summaryrefslogtreecommitdiff
path: root/board
diff options
context:
space:
mode:
Diffstat (limited to 'board')
-rw-r--r--board/BuS/EB+MCF-EV123/EB+MCF-EV123.c10
-rw-r--r--board/BuS/EB+MCF-EV123/VCxK.c2
-rw-r--r--board/BuS/EB+MCF-EV123/VCxK.h16
-rw-r--r--board/BuS/EB+MCF-EV123/cfm_flash.c2
-rw-r--r--board/BuS/EB+MCF-EV123/flash.c2
-rw-r--r--board/BuS/EB+MCF-EV123/u-boot.lds8
-rw-r--r--board/LEOX/elpt860/u-boot.lds8
-rw-r--r--board/LEOX/elpt860/u-boot.lds.debug8
-rw-r--r--board/MAI/AmigaOneG3SE/Makefile2
-rw-r--r--board/MAI/AmigaOneG3SE/articiaS_pci.c10
-rw-r--r--board/MAI/AmigaOneG3SE/enet.c148
-rw-r--r--board/amcc/acadia/Makefile47
-rw-r--r--board/amcc/acadia/acadia.c152
-rw-r--r--board/amcc/acadia/config.mk41
-rw-r--r--board/amcc/acadia/cpr.c195
-rw-r--r--board/amcc/acadia/flash.c1108
-rw-r--r--board/amcc/acadia/memory.c552
-rw-r--r--board/amcc/acadia/u-boot.lds150
-rw-r--r--board/amcc/ebony/init.S77
-rw-r--r--board/amcc/katmai/Makefile51
-rw-r--r--board/amcc/katmai/cmd_katmai.c267
-rw-r--r--board/amcc/katmai/config.mk38
-rw-r--r--board/amcc/katmai/init.S118
-rw-r--r--board/amcc/katmai/katmai.c529
-rw-r--r--board/amcc/katmai/u-boot.lds141
-rw-r--r--board/amcc/luan/init.S170
-rw-r--r--board/amcc/luan/luan.c99
-rw-r--r--board/amcc/luan/u-boot.lds13
-rw-r--r--board/amcc/ocotea/init.S82
-rw-r--r--board/amcc/sequoia/init.S2
-rw-r--r--board/amcc/sequoia/sdram.c383
-rw-r--r--board/amcc/sequoia/sdram.h505
-rw-r--r--board/amcc/sequoia/sequoia.c40
-rw-r--r--board/amcc/taishan/Makefile (renamed from board/amcc/yellowstone/Makefile)4
-rw-r--r--board/amcc/taishan/config.mk44
-rw-r--r--board/amcc/taishan/init.S97
-rw-r--r--board/amcc/taishan/lcd.c380
-rw-r--r--board/amcc/taishan/showinfo.c236
-rw-r--r--board/amcc/taishan/taishan.c331
-rw-r--r--board/amcc/taishan/u-boot.lds (renamed from board/amcc/yellowstone/u-boot.lds)4
-rw-r--r--board/amcc/taishan/update.c78
-rw-r--r--board/amcc/yellowstone/init.S112
-rw-r--r--board/amcc/yellowstone/yellowstone.c554
-rw-r--r--board/amcc/yosemite/yosemite.c39
-rw-r--r--board/amcc/yucca/init.S83
-rw-r--r--board/amcc/yucca/yucca.c316
-rw-r--r--board/bf533-ezkit/Makefile (renamed from board/stamp/Makefile)41
-rw-r--r--board/bf533-ezkit/bf533-ezkit.c (renamed from board/ezkit533/ezkit533.c)24
-rw-r--r--board/bf533-ezkit/config.mk25
-rw-r--r--board/bf533-ezkit/flash-defines.h (renamed from board/ezkit533/flash-defines.h)6
-rw-r--r--board/bf533-ezkit/flash.c (renamed from board/ezkit533/flash.c)148
-rw-r--r--board/bf533-ezkit/psd4256.h (renamed from board/ezkit533/psd4256.h)22
-rw-r--r--board/bf533-ezkit/u-boot.lds.S (renamed from board/ezkit533/u-boot.lds)16
-rw-r--r--board/bf533-stamp/Makefile58
-rw-r--r--board/bf533-stamp/bf533-stamp.c (renamed from board/stamp/stamp.c)136
-rw-r--r--board/bf533-stamp/bf533-stamp.h (renamed from board/stamp/stamp.h)1
-rw-r--r--board/bf533-stamp/config.mk25
-rw-r--r--board/bf533-stamp/spi.c473
-rw-r--r--board/bf533-stamp/u-boot.lds.S (renamed from board/stamp/u-boot.lds)17
-rw-r--r--board/bf537-stamp/Makefile58
-rw-r--r--board/bf537-stamp/bf537-stamp.c437
-rw-r--r--board/bf537-stamp/cmd_bf537led.c201
-rw-r--r--board/bf537-stamp/config.mk25
-rw-r--r--board/bf537-stamp/ether_bf537.c545
-rw-r--r--board/bf537-stamp/ether_bf537.h110
-rw-r--r--board/bf537-stamp/flash-defines.h123
-rw-r--r--board/bf537-stamp/flash.c403
-rw-r--r--board/bf537-stamp/nand.c106
-rw-r--r--board/bf537-stamp/post-memory.c322
-rw-r--r--board/bf537-stamp/stm_m25p64.c515
-rw-r--r--board/bf537-stamp/u-boot.lds.S190
-rw-r--r--board/bf561-ezkit/Makefile58
-rw-r--r--board/bf561-ezkit/bf561-ezkit.c73
-rw-r--r--board/bf561-ezkit/config.mk25
-rw-r--r--board/bf561-ezkit/u-boot.lds.S153
-rw-r--r--board/cray/L1/L1.c2
-rw-r--r--board/dave/PPChameleonEVB/nand.c3
-rw-r--r--board/delta/nand.c3
-rw-r--r--board/emk/top5200/top5200.c2
-rw-r--r--board/esd/common/auto_update.c3
-rw-r--r--board/esd/cpci5200/cpci5200.c3
-rw-r--r--board/esd/cpci750/cpci750.c38
-rw-r--r--board/esd/cpci750/sdram_init.c41
-rw-r--r--board/esd/du405/du405.c2
-rw-r--r--board/esd/mecp5200/Makefile51
-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.lds122
-rw-r--r--board/esd/pf5200/pf5200.c3
-rw-r--r--board/esd/plu405/plu405.c17
-rw-r--r--board/hmi1001/hmi1001.c18
-rw-r--r--board/icecube/icecube.c14
-rw-r--r--board/idmr/Makefile (renamed from board/ezkit533/Makefile)6
-rw-r--r--board/idmr/config.mk25
-rw-r--r--board/idmr/flash.c356
-rw-r--r--board/idmr/idmr.c169
-rw-r--r--board/idmr/u-boot.lds145
-rw-r--r--board/jupiter/Makefile51
-rw-r--r--board/jupiter/config.mk41
-rw-r--r--board/jupiter/jupiter.c317
-rw-r--r--board/jupiter/u-boot.lds125
-rw-r--r--board/lpc2292sodimm/Makefile58
-rw-r--r--board/lpc2292sodimm/config.mk30
-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
-rw-r--r--board/mcc200/Makefile2
-rw-r--r--board/mcc200/auto_update.c522
-rw-r--r--board/mcc200/lcd.c31
-rw-r--r--board/mcc200/mcc200.c8
-rw-r--r--board/motionpro/Makefile50
-rw-r--r--board/motionpro/config.mk30
-rw-r--r--board/motionpro/motionpro.c172
-rw-r--r--board/motionpro/u-boot.lds123
-rw-r--r--board/mpc832xemds/Makefile50
-rw-r--r--board/mpc832xemds/config.mk (renamed from board/stamp/config.mk)9
-rw-r--r--board/mpc832xemds/mpc832xemds.c176
-rw-r--r--board/mpc832xemds/pci.c316
-rw-r--r--board/mpc832xemds/u-boot.lds123
-rw-r--r--board/mpc8349emds/Makefile2
-rw-r--r--board/mpc8349emds/mpc8349emds.c57
-rw-r--r--board/mpc8349emds/pci.c53
-rw-r--r--board/mpc8349itx/Makefile48
-rw-r--r--board/mpc8349itx/config.mk37
-rw-r--r--board/mpc8349itx/mpc8349itx.c407
-rw-r--r--board/mpc8349itx/pci.c357
-rw-r--r--board/mpc8349itx/u-boot.lds120
-rw-r--r--board/mpc8360emds/Makefile50
-rw-r--r--board/mpc8360emds/config.mk (renamed from board/ezkit533/config.mk)9
-rw-r--r--board/mpc8360emds/mpc8360emds.c679
-rw-r--r--board/mpc8360emds/pci.c316
-rw-r--r--board/mpc8360emds/u-boot.lds123
-rw-r--r--board/mpl/common/memtst.c2
-rw-r--r--board/mpl/mip405/mip405.c5
-rw-r--r--board/nc650/nand.c3
-rw-r--r--board/netstar/nand.c3
-rw-r--r--board/prodrive/alpr/Makefile51
-rw-r--r--board/prodrive/alpr/alpr.c317
-rw-r--r--board/prodrive/alpr/config.mk (renamed from board/amcc/yellowstone/config.mk)10
-rw-r--r--board/prodrive/alpr/fpga.c257
-rw-r--r--board/prodrive/alpr/init.S103
-rw-r--r--board/prodrive/alpr/nand.c175
-rw-r--r--board/prodrive/alpr/u-boot.lds157
-rw-r--r--board/prodrive/common/flash.c4
-rw-r--r--board/prodrive/p3mx/64460.h52
-rw-r--r--board/prodrive/p3mx/Makefile55
-rw-r--r--board/prodrive/p3mx/config.mk28
-rw-r--r--board/prodrive/p3mx/eth.h43
-rw-r--r--board/prodrive/p3mx/misc.S245
-rw-r--r--board/prodrive/p3mx/mpsc.c1013
-rw-r--r--board/prodrive/p3mx/mpsc.h156
-rw-r--r--board/prodrive/p3mx/mv_eth.c3344
-rw-r--r--board/prodrive/p3mx/mv_eth.h840
-rw-r--r--board/prodrive/p3mx/mv_regs.h1125
-rw-r--r--board/prodrive/p3mx/p3mx.c864
-rw-r--r--board/prodrive/p3mx/p3mx.h33
-rw-r--r--board/prodrive/p3mx/pci.c1025
-rw-r--r--board/prodrive/p3mx/ppc_error_no.h164
-rw-r--r--board/prodrive/p3mx/sdram_init.c434
-rw-r--r--board/prodrive/p3mx/serial.c107
-rw-r--r--board/prodrive/p3mx/serial.h89
-rw-r--r--board/prodrive/p3mx/u-boot.lds138
-rw-r--r--board/prodrive/pdnb3/flash.c4
-rw-r--r--board/prodrive/pdnb3/nand.c3
-rw-r--r--board/sandburst/common/ppc440gx_i2c.c7
-rw-r--r--board/sandburst/common/ppc440gx_i2c.h6
-rw-r--r--board/sbc8349/Makefile49
-rw-r--r--board/sbc8349/config.mk27
-rw-r--r--board/sbc8349/pci.c348
-rw-r--r--board/sbc8349/sbc8349.c585
-rw-r--r--board/sbc8349/u-boot.lds125
-rw-r--r--board/sc3/Makefile51
-rw-r--r--board/sc3/config.mk24
-rw-r--r--board/sc3/init.S382
-rw-r--r--board/sc3/sc3.c781
-rw-r--r--board/sc3/sc3.h117
-rw-r--r--board/sc3/sc3nand.c94
-rw-r--r--board/sc3/u-boot.lds150
-rw-r--r--board/spc1920/Makefile2
-rw-r--r--board/spc1920/hpi.c603
-rw-r--r--board/spc1920/hpi.h28
-rw-r--r--board/spc1920/pld.h2
-rw-r--r--board/spc1920/spc1920.c38
-rw-r--r--board/tqm5200/cam5200_flash.c4
-rw-r--r--board/tqm8272/Makefile40
-rw-r--r--board/tqm8272/config.mk34
-rw-r--r--board/tqm8272/tqm8272.c1234
-rw-r--r--board/tqm8272/u-boot.lds126
-rw-r--r--board/tqm834x/pci.c18
-rw-r--r--board/tqm834x/tqm834x.c8
-rw-r--r--board/trab/auto_update.c1
-rw-r--r--board/uc101/Makefile50
-rw-r--r--board/uc101/config.mk41
-rw-r--r--board/uc101/u-boot.lds136
-rw-r--r--board/uc101/uc101.c371
-rw-r--r--board/v38b/v38b.c21
-rw-r--r--board/xilinx/ml300/Makefile2
-rw-r--r--board/xilinx/ml300/ml300.c2
-rw-r--r--board/xilinx/ml300/serial.c3
-rw-r--r--board/xilinx/xilinx_enet/emac_adapter.c2
-rw-r--r--board/xilinx/xilinx_enet/xemac.h2
-rw-r--r--board/xilinx/xilinx_enet/xemac_g.c2
-rw-r--r--board/xilinx/xilinx_iic/iic_adapter.c2
-rw-r--r--board/zylonite/nand.c3
213 files changed, 34036 insertions, 1891 deletions
diff --git a/board/BuS/EB+MCF-EV123/EB+MCF-EV123.c b/board/BuS/EB+MCF-EV123/EB+MCF-EV123.c
index f18313d5161..dcfd83ed279 100644
--- a/board/BuS/EB+MCF-EV123/EB+MCF-EV123.c
+++ b/board/BuS/EB+MCF-EV123/EB+MCF-EV123.c
@@ -50,13 +50,13 @@ long int initdram (int board_type)
MCFSDRAMC_DACR0 = MCFSDRAMC_DACR_BASE(CFG_SDRAM_BASE0)
| MCFSDRAMC_DACR_CASL(1)
- | MCFSDRAMC_DACR_CBM(3)
+ | MCFSDRAMC_DACR_CBM(3)
| MCFSDRAMC_DACR_PS_16);
MCFSDRAMC_DMR0 = MCFSDRAMC_DMR_BAM_16M
| MCFSDRAMC_DMR_V;
- MCFSDRAMC_DACR0 |= MCFSDRAMC_DACR_IP;
+ MCFSDRAMC_DACR0 |= MCFSDRAMC_DACR_IP;
*(unsigned short *)(CFG_SDRAM_BASE0) = 0xA5A5;
MCFSDRAMC_DACR0 |= MCFSDRAMC_DACR_RE;
@@ -70,10 +70,10 @@ long int initdram (int board_type)
#ifdef CFG_SDRAM_BASE1
MCFSDRAMC_DACR1 = MCFSDRAMC_DACR_BASE(CFG_SDRAM_BASE1)
| MCFSDRAMC_DACR_CASL(1)
- | MCFSDRAMC_DACR_CBM(3)
+ | MCFSDRAMC_DACR_CBM(3)
| MCFSDRAMC_DACR_PS_16;
- MCFSDRAMC_DMR1 = MCFSDRAMC_DMR_BAM_16M
+ MCFSDRAMC_DMR1 = MCFSDRAMC_DMR_BAM_16M
| MCFSDRAMC_DMR_V;
MCFSDRAMC_DACR1 |= MCFSDRAMC_DACR_IP;
@@ -82,7 +82,7 @@ long int initdram (int board_type)
MCFSDRAMC_DACR1 |= MCFSDRAMC_DACR_RE;
for (i=0; i < 2000; i++)
asm(" nop");
- MCFSDRAMC_DACR1 |= MCFSDRAMC_DACR_IMRS;
+ MCFSDRAMC_DACR1 |= MCFSDRAMC_DACR_IMRS;
*(unsigned int *)(CFG_SDRAM_BASE1 + 0x220) = 0xA5A5;
size += CFG_SDRAM_SIZE1 * 1024 * 1024;
#endif
diff --git a/board/BuS/EB+MCF-EV123/VCxK.c b/board/BuS/EB+MCF-EV123/VCxK.c
index 493881791b9..4b46b7c9a59 100644
--- a/board/BuS/EB+MCF-EV123/VCxK.c
+++ b/board/BuS/EB+MCF-EV123/VCxK.c
@@ -66,7 +66,7 @@ int init_vcxk(void)
return 1;
}
-void vcxk_loadimage(ulong source)
+void vcxk_loadimage(ulong source)
{
int cnt;
vcxk_acknowledge_wait();
diff --git a/board/BuS/EB+MCF-EV123/VCxK.h b/board/BuS/EB+MCF-EV123/VCxK.h
index 74467ba98a7..f591e5c52f3 100644
--- a/board/BuS/EB+MCF-EV123/VCxK.h
+++ b/board/BuS/EB+MCF-EV123/VCxK.h
@@ -25,24 +25,24 @@
#define __VCXK_H_
extern int init_vcxk(void);
-void vcxk_loadimage(ulong source);
+void vcxk_loadimage(ulong source);
#define VIDEO_ACKNOWLEDGE_PORT MCFGPTB_GPTPORT
-#define VIDEO_ACKNOWLEDGE_DDR MCFGPTB_GPTDDR
+#define VIDEO_ACKNOWLEDGE_DDR MCFGPTB_GPTDDR
#define VIDEO_ACKNOWLEDGE_PIN 0x0001
-#define VIDEO_ENABLE_PORT MCFGPTB_GPTPORT
-#define VIDEO_ENABLE_DDR MCFGPTB_GPTDDR
+#define VIDEO_ENABLE_PORT MCFGPTB_GPTPORT
+#define VIDEO_ENABLE_DDR MCFGPTB_GPTDDR
#define VIDEO_ENABLE_PIN 0x0002
-#define VIDEO_REQUEST_PORT MCFGPTB_GPTPORT
-#define VIDEO_REQUEST_DDR MCFGPTB_GPTDDR
+#define VIDEO_REQUEST_PORT MCFGPTB_GPTPORT
+#define VIDEO_REQUEST_DDR MCFGPTB_GPTDDR
#define VIDEO_REQUEST_PIN 0x0004
#define VIDEO_Invert_CFG MCFGPIO_PEPAR
#define VIDEO_Invert_IO MCFGPIO_PEPAR_PEPA2
-#define VIDEO_INVERT_PORT MCFGPIO_PORTE
-#define VIDEO_INVERT_DDR MCFGPIO_DDRE
+#define VIDEO_INVERT_PORT MCFGPIO_PORTE
+#define VIDEO_INVERT_DDR MCFGPIO_DDRE
#define VIDEO_INVERT_PIN MCFGPIO_PORT2
#endif
diff --git a/board/BuS/EB+MCF-EV123/cfm_flash.c b/board/BuS/EB+MCF-EV123/cfm_flash.c
index 6ecf0d1f543..b3263841022 100644
--- a/board/BuS/EB+MCF-EV123/cfm_flash.c
+++ b/board/BuS/EB+MCF-EV123/cfm_flash.c
@@ -60,7 +60,7 @@ void cfm_flash_init (flash_info_t * info)
MCFCFM_MCR = 0;
MCFCFM_CLKD = CFM_CLK;
debug ("CFM Clock divider: %ld (%d Hz @ %ld Hz)\n",CFM_CLK,\
- CFG_CLK / (2* ((CFM_CLK & 0x3F)+1) * (1+((CFM_CLK & 0x40)>>6)*7)),\
+ CFG_CLK / (2* ((CFM_CLK & 0x3F)+1) * (1+((CFM_CLK & 0x40)>>6)*7)),\
CFG_CLK);
MCFCFM_SACC = 0;
MCFCFM_DACC = 0;
diff --git a/board/BuS/EB+MCF-EV123/flash.c b/board/BuS/EB+MCF-EV123/flash.c
index ba76bef12e4..5e2647ddadf 100644
--- a/board/BuS/EB+MCF-EV123/flash.c
+++ b/board/BuS/EB+MCF-EV123/flash.c
@@ -256,7 +256,7 @@ int flash_erase (flash_info_t * info, int s_first, int s_last)
enable_interrupts ();
if (cflag)
- icache_enable ();
+ icache_enable ();
return rc;
}
diff --git a/board/BuS/EB+MCF-EV123/u-boot.lds b/board/BuS/EB+MCF-EV123/u-boot.lds
index d790018d2dd..ac532451c97 100644
--- a/board/BuS/EB+MCF-EV123/u-boot.lds
+++ b/board/BuS/EB+MCF-EV123/u-boot.lds
@@ -34,11 +34,11 @@ SECTIONS
.dynsym : { *(.dynsym) }
.dynstr : { *(.dynstr) }
.rel.text : { *(.rel.text) }
- .rela.text : { *(.rela.text) }
+ .rela.text : { *(.rela.text) }
.rel.data : { *(.rel.data) }
- .rela.data : { *(.rela.data) }
- .rel.rodata : { *(.rel.rodata) }
- .rela.rodata : { *(.rela.rodata) }
+ .rela.data : { *(.rela.data) }
+ .rel.rodata : { *(.rel.rodata) }
+ .rela.rodata : { *(.rela.rodata) }
.rel.got : { *(.rel.got) }
.rela.got : { *(.rela.got) }
.rel.ctors : { *(.rel.ctors) }
diff --git a/board/LEOX/elpt860/u-boot.lds b/board/LEOX/elpt860/u-boot.lds
index b09fc3390a2..214752d9c0d 100644
--- a/board/LEOX/elpt860/u-boot.lds
+++ b/board/LEOX/elpt860/u-boot.lds
@@ -43,11 +43,11 @@ SECTIONS
.dynsym : { *(.dynsym) }
.dynstr : { *(.dynstr) }
.rel.text : { *(.rel.text) }
- .rela.text : { *(.rela.text) }
+ .rela.text : { *(.rela.text) }
.rel.data : { *(.rel.data) }
- .rela.data : { *(.rela.data) }
- .rel.rodata : { *(.rel.rodata) }
- .rela.rodata : { *(.rela.rodata) }
+ .rela.data : { *(.rela.data) }
+ .rel.rodata : { *(.rel.rodata) }
+ .rela.rodata : { *(.rela.rodata) }
.rel.got : { *(.rel.got) }
.rela.got : { *(.rela.got) }
.rel.ctors : { *(.rel.ctors) }
diff --git a/board/LEOX/elpt860/u-boot.lds.debug b/board/LEOX/elpt860/u-boot.lds.debug
index 6f5af91fd18..17f99eb840b 100644
--- a/board/LEOX/elpt860/u-boot.lds.debug
+++ b/board/LEOX/elpt860/u-boot.lds.debug
@@ -43,11 +43,11 @@ SECTIONS
.dynsym : { *(.dynsym) }
.dynstr : { *(.dynstr) }
.rel.text : { *(.rel.text) }
- .rela.text : { *(.rela.text) }
+ .rela.text : { *(.rela.text) }
.rel.data : { *(.rel.data) }
- .rela.data : { *(.rela.data) }
- .rel.rodata : { *(.rel.rodata) }
- .rela.rodata : { *(.rela.rodata) }
+ .rela.data : { *(.rela.data) }
+ .rel.rodata : { *(.rel.rodata) }
+ .rela.rodata : { *(.rela.rodata) }
.rel.got : { *(.rel.got) }
.rela.got : { *(.rela.got) }
.rel.ctors : { *(.rel.ctors) }
diff --git a/board/MAI/AmigaOneG3SE/Makefile b/board/MAI/AmigaOneG3SE/Makefile
index cb6ea26298d..fa28d3b495a 100644
--- a/board/MAI/AmigaOneG3SE/Makefile
+++ b/board/MAI/AmigaOneG3SE/Makefile
@@ -30,7 +30,7 @@ endif
LIB = $(obj)lib$(BOARD).a
COBJS = $(BOARD).o articiaS.o flash.o serial.o smbus.o articiaS_pci.o \
- via686.o i8259.o ../bios_emulator/x86interface.o \
+ via686.o i8259.o ../bios_emulator/x86interface.o \
../bios_emulator/bios.o ../bios_emulator/glue.o \
interrupts.o ps2kbd.o video.o usb_uhci.o enet.o \
../menu/cmd_menu.o cmd_boota.o nvram.o
diff --git a/board/MAI/AmigaOneG3SE/articiaS_pci.c b/board/MAI/AmigaOneG3SE/articiaS_pci.c
index 480dae5b968..45b8195012f 100644
--- a/board/MAI/AmigaOneG3SE/articiaS_pci.c
+++ b/board/MAI/AmigaOneG3SE/articiaS_pci.c
@@ -368,11 +368,11 @@ void articiaS_pci_init (void)
if (articiaS_init_vga() == -1)
{
/* If the VGA didn't init and we have stdout set to VGA, reset to serial */
-/* s = getenv("stdout"); */
-/* if (s && strcmp(s, "vga") == 0) */
-/* { */
-/* setenv("stdout", "serial"); */
-/* } */
+/* s = getenv("stdout"); */
+/* if (s && strcmp(s, "vga") == 0) */
+/* { */
+/* setenv("stdout", "serial"); */
+/* } */
}
}
pci_write_config_byte(PCI_BDF(0,1,0), PCI_INTERRUPT_LINE, 0xFF);
diff --git a/board/MAI/AmigaOneG3SE/enet.c b/board/MAI/AmigaOneG3SE/enet.c
index d4be889ea83..ad2bcdeffea 100644
--- a/board/MAI/AmigaOneG3SE/enet.c
+++ b/board/MAI/AmigaOneG3SE/enet.c
@@ -41,57 +41,57 @@
/* 3Com Commands, top 5 bits are command and bottom 11 bits are parameters */
-#define TotalReset (0<<11)
-#define SelectWindow (1<<11)
-#define StartCoax (2<<11)
-#define RxDisable (3<<11)
-#define RxEnable (4<<11)
-#define RxReset (5<<11)
-#define UpStall (6<<11)
-#define UpUnstall (6<<11)+1
-#define DownStall (6<<11)+2
-#define DownUnstall (6<<11)+3
-#define RxDiscard (8<<11)
-#define TxEnable (9<<11)
-#define TxDisable (10<<11)
-#define TxReset (11<<11)
-#define FakeIntr (12<<11)
-#define AckIntr (13<<11)
-#define SetIntrEnb (14<<11)
-#define SetStatusEnb (15<<11)
-#define SetRxFilter (16<<11)
-#define SetRxThreshold (17<<11)
-#define SetTxThreshold (18<<11)
-#define SetTxStart (19<<11)
-#define StartDMAUp (20<<11)
-#define StartDMADown (20<<11)+1
+#define TotalReset (0<<11)
+#define SelectWindow (1<<11)
+#define StartCoax (2<<11)
+#define RxDisable (3<<11)
+#define RxEnable (4<<11)
+#define RxReset (5<<11)
+#define UpStall (6<<11)
+#define UpUnstall (6<<11)+1
+#define DownStall (6<<11)+2
+#define DownUnstall (6<<11)+3
+#define RxDiscard (8<<11)
+#define TxEnable (9<<11)
+#define TxDisable (10<<11)
+#define TxReset (11<<11)
+#define FakeIntr (12<<11)
+#define AckIntr (13<<11)
+#define SetIntrEnb (14<<11)
+#define SetStatusEnb (15<<11)
+#define SetRxFilter (16<<11)
+#define SetRxThreshold (17<<11)
+#define SetTxThreshold (18<<11)
+#define SetTxStart (19<<11)
+#define StartDMAUp (20<<11)
+#define StartDMADown (20<<11)+1
#define StatsEnable (21<<11)
#define StatsDisable (22<<11)
-#define StopCoax (23<<11)
-#define SetFilterBit (25<<11)
+#define StopCoax (23<<11)
+#define SetFilterBit (25<<11)
/* The SetRxFilter command accepts the following classes */
-#define RxStation 1
+#define RxStation 1
#define RxMulticast 2
#define RxBroadcast 4
-#define RxProm 8
+#define RxProm 8
/* 3Com status word defnitions */
-#define IntLatch 0x0001
-#define HostError 0x0002
-#define TxComplete 0x0004
-#define TxAvailable 0x0008
-#define RxComplete 0x0010
-#define RxEarly 0x0020
-#define IntReq 0x0040
-#define StatsFull 0x0080
-#define DMADone (1<<8)
-#define DownComplete (1<<9)
-#define UpComplete (1<<10)
-#define DMAInProgress (1<<11) /* DMA controller is still busy.*/
-#define CmdInProgress (1<<12) /* EL3_CMD is still busy.*/
+#define IntLatch 0x0001
+#define HostError 0x0002
+#define TxComplete 0x0004
+#define TxAvailable 0x0008
+#define RxComplete 0x0010
+#define RxEarly 0x0020
+#define IntReq 0x0040
+#define StatsFull 0x0080
+#define DMADone (1<<8)
+#define DownComplete (1<<9)
+#define UpComplete (1<<10)
+#define DMAInProgress (1<<11) /* DMA controller is still busy.*/
+#define CmdInProgress (1<<12) /* EL3_CMD is still busy.*/
/* Polling Registers */
@@ -100,17 +100,17 @@
/* Register window 0 offets */
-#define Wn0EepromCmd 10 /* Window 0: EEPROM command register. */
-#define Wn0EepromData 12 /* Window 0: EEPROM results register. */
+#define Wn0EepromCmd 10 /* Window 0: EEPROM command register. */
+#define Wn0EepromData 12 /* Window 0: EEPROM results register. */
#define IntrStatus 0x0E /* Valid in all windows. */
/* Register window 0 EEPROM bits */
-#define EEPROM_Read 0x80
-#define EEPROM_WRITE 0x40
-#define EEPROM_ERASE 0xC0
-#define EEPROM_EWENB 0x30 /* Enable erasing/writing for 10 msec. */
-#define EEPROM_EWDIS 0x00 /* Disable EWENB before 10 msec timeout. */
+#define EEPROM_Read 0x80
+#define EEPROM_WRITE 0x40
+#define EEPROM_ERASE 0xC0
+#define EEPROM_EWENB 0x30 /* Enable erasing/writing for 10 msec. */
+#define EEPROM_EWDIS 0x00 /* Disable EWENB before 10 msec timeout. */
/* EEPROM locations. */
@@ -129,13 +129,13 @@
/* Register window 1 offsets, the window used in normal operation */
-#define TX_FIFO 0x10
-#define RX_FIFO 0x10
-#define RxErrors 0x14
-#define RxStatus 0x18
+#define TX_FIFO 0x10
+#define RX_FIFOa 0x10
+#define RxErrors 0x14
+#define RxStatus 0x18
#define Timer 0x1A
-#define TxStatus 0x1B
-#define TxFree 0x1C /* Remaining free bytes in Tx buffer. */
+#define TxStatus 0x1B
+#define TxFree 0x1C /* Remaining free bytes in Tx buffer. */
/* Register Window 2 */
@@ -147,47 +147,47 @@
#define Wn3_MAC_Ctrl 6
#define Wn3_Options 8
-#define BFEXT(value, offset, bitcount) \
+#define BFEXT(value, offset, bitcount) \
((((unsigned long)(value)) >> (offset)) & ((1 << (bitcount)) - 1))
#define BFINS(lhs, rhs, offset, bitcount) \
- (((lhs) & ~((((1 << (bitcount)) - 1)) << (offset))) | \
+ (((lhs) & ~((((1 << (bitcount)) - 1)) << (offset))) | \
(((rhs) & ((1 << (bitcount)) - 1)) << (offset)))
#define RAM_SIZE(v) BFEXT(v, 0, 3)
-#define RAM_WIDTH(v) BFEXT(v, 3, 1)
-#define RAM_SPEED(v) BFEXT(v, 4, 2)
+#define RAM_WIDTH(v) BFEXT(v, 3, 1)
+#define RAM_SPEED(v) BFEXT(v, 4, 2)
#define ROM_SIZE(v) BFEXT(v, 6, 2)
-#define RAM_SPLIT(v) BFEXT(v, 16, 2)
+#define RAM_SPLIT(v) BFEXT(v, 16, 2)
#define XCVR(v) BFEXT(v, 20, 4)
-#define AUTOSELECT(v) BFEXT(v, 24, 1)
+#define AUTOSELECT(v) BFEXT(v, 24, 1)
/* Register Window 4: Xcvr/media bits */
-#define Wn4_FIFODiag 4
-#define Wn4_NetDiag 6
+#define Wn4_FIFODiag 4
+#define Wn4_NetDiag 6
#define Wn4_PhysicalMgmt 8
-#define Wn4_Media 10
+#define Wn4_Media 10
-#define Media_SQE 0x0008 /* Enable SQE error counting for AUI. */
-#define Media_10TP 0x00C0 /* Enable link beat and jabber for 10baseT. */
-#define Media_Lnk 0x0080 /* Enable just link beat for 100TX/100FX. */
-#define Media_LnkBeat 0x0800
+#define Media_SQE 0x0008 /* Enable SQE error counting for AUI. */
+#define Media_10TP 0x00C0 /* Enable link beat and jabber for 10baseT. */
+#define Media_Lnk 0x0080 /* Enable just link beat for 100TX/100FX. */
+#define Media_LnkBeat 0x0800
/* Register Window 7: Bus Master control */
-#define Wn7_MasterAddr 0
-#define Wn7_MasterLen 6
-#define Wn7_MasterStatus 12
+#define Wn7_MasterAddr 0
+#define Wn7_MasterLen 6
+#define Wn7_MasterStatus 12
/* Boomerang bus master control registers. */
-#define PktStatus 0x20
+#define PktStatus 0x20
#define DownListPtr 0x24
-#define FragAddr 0x28
-#define FragLen 0x2c
+#define FragAddr 0x28
+#define FragLen 0x2c
#define TxFreeThreshold 0x2f
-#define UpPktStatus 0x30
+#define UpPktStatus 0x30
#define UpListPtr 0x38
/* The Rx and Tx descriptor lists. */
diff --git a/board/amcc/acadia/Makefile b/board/amcc/acadia/Makefile
new file mode 100644
index 00000000000..183f694c7b8
--- /dev/null
+++ b/board/amcc/acadia/Makefile
@@ -0,0 +1,47 @@
+#
+# (C) Copyright 2007
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+include $(TOPDIR)/config.mk
+
+LIB = lib$(BOARD).a
+
+OBJS = $(BOARD).o cpr.o memory.o
+SOBJS =
+
+$(LIB): $(OBJS) $(SOBJS)
+ $(AR) crv $@ $(OBJS) $(SOBJS)
+
+clean:
+ rm -f $(SOBJS) $(OBJS)
+
+distclean: clean
+ rm -f $(LIB) core *.bak .depend
+
+#########################################################################
+
+.depend: Makefile $(SOBJS:.o=.S) $(OBJS:.o=.c)
+ $(CC) -M $(CFLAGS) $(SOBJS:.o=.S) $(OBJS:.o=.c) > $@
+
+sinclude .depend
+
+#########################################################################
diff --git a/board/amcc/acadia/acadia.c b/board/amcc/acadia/acadia.c
new file mode 100644
index 00000000000..c8aaad2d785
--- /dev/null
+++ b/board/amcc/acadia/acadia.c
@@ -0,0 +1,152 @@
+/*
+ * (C) Copyright 2007
+ * Stefan Roese, DENX Software Engineering, sr@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <asm/processor.h>
+
+extern void board_pll_init_f(void);
+
+/* Some specific Acadia Defines */
+#define CPLD_BASE 0x80000000
+
+void liveoak_gpio_init(void)
+{
+ /*
+ * GPIO0 setup (select GPIO or alternate function)
+ */
+ out32(GPIO0_OSRL, CFG_GPIO0_OSRL);
+ out32(GPIO0_OSRH, CFG_GPIO0_OSRH); /* output select */
+ out32(GPIO0_ISR1L, CFG_GPIO0_ISR1L);
+ out32(GPIO0_ISR1H, CFG_GPIO0_ISR1H); /* input select */
+ out32(GPIO0_TSRL, CFG_GPIO0_TSRL);
+ out32(GPIO0_TSRH, CFG_GPIO0_TSRH); /* three-state select */
+ out32(GPIO0_TCR, CFG_GPIO0_TCR); /* enable output driver for outputs */
+
+ /*
+ * Ultra (405EZ) was nice enough to add another GPIO controller
+ */
+ out32(GPIO1_OSRH, CFG_GPIO1_OSRH); /* output select */
+ out32(GPIO1_OSRL, CFG_GPIO1_OSRL);
+ out32(GPIO1_ISR1H, CFG_GPIO1_ISR1H); /* input select */
+ out32(GPIO1_ISR1L, CFG_GPIO1_ISR1L);
+ out32(GPIO1_TSRH, CFG_GPIO1_TSRH); /* three-state select */
+ out32(GPIO1_TSRL, CFG_GPIO1_TSRL);
+ out32(GPIO1_TCR, CFG_GPIO1_TCR); /* enable output driver for outputs */
+}
+
+#if 0 /* test-only: not called at all??? */
+void ext_bus_cntlr_init(void)
+{
+#if (defined(EBC_PB4AP) && defined(EBC_PB4CR) && !(CFG_INIT_DCACHE_CS == 4))
+ mtebc(pb4ap, EBC_PB4AP);
+ mtebc(pb4cr, EBC_PB4CR);
+#endif
+}
+#endif
+
+int board_early_init_f(void)
+{
+ unsigned int reg;
+
+#if 0 /* test-only */
+ /*
+ * If CRAM memory and SPI/NAND boot, and if the CRAM memory is
+ * already initialized by the pre-loader then we can't reinitialize
+ * CPR registers, GPIO registers and EBC registers as this will
+ * have the effect of un-initializing CRAM.
+ */
+ spr_reg = (volatile unsigned long) mfspr(SPRG7);
+ if (spr_reg != LOAK_CRAM) { /* != CRAM */
+ board_pll_init_f();
+ liveoak_gpio_init();
+ ext_bus_cntlr_init();
+
+ mtebc(pb1ap, CFG_EBC_PB1AP);
+ mtebc(pb1cr, CFG_EBC_PB1CR);
+
+ mtebc(pb2ap, CFG_EBC_PB2AP);
+ mtebc(pb2cr, CFG_EBC_PB2CR);
+ }
+#else
+ board_pll_init_f();
+ liveoak_gpio_init();
+/* ext_bus_cntlr_init(); */
+#endif
+
+#if 0 /* test-only (orig) */
+ /*
+ * If we boot from NAND Flash, we are running in
+ * RAM, so disable the EBC_CS0 so that it goes back
+ * to the NOR Flash. It will be enabled later
+ * for the NAND Flash on EBC_CS1
+ */
+ mfsdr(sdrultra0, reg);
+ mtsdr(sdrultra0, reg & ~SDR_ULTRA0_CSNSEL0);
+#endif
+#if 0 /* test-only */
+ /* configure for NAND */
+ mfsdr(sdrultra0, reg);
+ reg &= ~SDR_ULTRA0_CSN_MASK;
+ reg |= SDR_ULTRA0_CSNSEL0 >> CFG_NAND_CS;
+ mtsdr(sdrultra0, reg & ~SDR_ULTRA0_CSNSEL0);
+#endif
+
+ /* USB Host core needs this bit set */
+ mfsdr(sdrultra1, reg);
+ mtsdr(sdrultra1, reg | SDR_ULTRA1_LEDNENABLE);
+
+ mtdcr(uicsr, 0xFFFFFFFF); /* clear all ints */
+ mtdcr(uicer, 0x00000000); /* disable all ints */
+ mtdcr(uiccr, 0x00000010);
+ mtdcr(uicpr, 0xFE7FFFF0); /* set int polarities */
+ mtdcr(uictr, 0x00000010); /* set int trigger levels */
+ mtdcr(uicsr, 0xFFFFFFFF); /* clear all ints */
+
+ return 0;
+}
+
+int misc_init_f(void)
+{
+ /* Set EPLD to take PHY out of reset */
+ out8(CPLD_BASE + 0x05, 0x00);
+ udelay(100000);
+
+ return 0;
+}
+
+/*
+ * Check Board Identity:
+ */
+int checkboard(void)
+{
+ char *s = getenv("serial#");
+
+ printf("Board: Acadia - AMCC PPC405EZ Evaluation Board");
+ if (s != NULL) {
+ puts(", serial# ");
+ puts(s);
+ }
+ putc('\n');
+
+ return (0);
+}
diff --git a/board/amcc/acadia/config.mk b/board/amcc/acadia/config.mk
new file mode 100644
index 00000000000..ce213746589
--- /dev/null
+++ b/board/amcc/acadia/config.mk
@@ -0,0 +1,41 @@
+#
+# (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
+#
+
+sinclude $(TOPDIR)/board/amcc/liveoak/config.tmp
+
+ifndef TEXT_BASE
+TEXT_BASE = 0xFFFC0000
+endif
+
+ifeq ($(CONFIG_NAND_U_BOOT),y)
+LDSCRIPT = $(TOPDIR)/board/$(BOARDDIR)/u-boot-nand.lds
+endif
+
+ifeq ($(CONFIG_SPI_U_BOOT),y)
+LDSCRIPT = $(TOPDIR)/board/$(BOARDDIR)/u-boot-spi.lds
+PAD_TO = 0x00840000
+endif
+
+ifeq ($(debug),1)
+PLATFORM_CPPFLAGS += -DDEBUG
+endif
diff --git a/board/amcc/acadia/cpr.c b/board/amcc/acadia/cpr.c
new file mode 100644
index 00000000000..23b9e1242bc
--- /dev/null
+++ b/board/amcc/acadia/cpr.c
@@ -0,0 +1,195 @@
+/*
+ * (C) Copyright 2007
+ * Stefan Roese, DENX Software Engineering, sr@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <asm/processor.h>
+#include <ppc405.h>
+
+/* test-only: move into cpu directory!!! */
+
+#if defined(PLLMR0_200_133_66)
+void board_pll_init_f(void)
+{
+ /*
+ * set PLL clocks based on input sysclk is 33M
+ *
+ * ----------------------------------
+ * | CLK | FREQ (MHz) | DIV RATIO |
+ * ----------------------------------
+ * | CPU | 200.0 | 4 (0x02)|
+ * | PLB | 133.3 | 6 (0x06)|
+ * | OPB | 66.6 | 12 (0x0C)|
+ * | EBC | 66.6 | 12 (0x0C)|
+ * | SPI | 66.6 | 12 (0x0C)|
+ * | UART0 | 10.0 | 40 (0x28)|
+ * | UART1 | 10.0 | 40 (0x28)|
+ * | DAC | 2.0 | 200 (0xC8)|
+ * | ADC | 2.0 | 200 (0xC8)|
+ * | PWM | 100.0 | 4 (0x04)|
+ * | EMAC | 25.0 | 16 (0x10)|
+ * -----------------------------------
+ */
+
+ /* Initialize PLL */
+ mtcpr(cprpllc, 0x0000033c);
+ mtcpr(cprplld, 0x0c010200);
+ mtcpr(cprprimad, 0x04060c0c);
+ mtcpr(cprperd0, 0x000c0000); /* SPI clk div. eq. OPB clk div. */
+ mtcpr(cprclkupd, 0x40000000);
+}
+
+#elif defined(PLLMR0_266_160_80)
+
+void board_pll_init_f(void)
+{
+ /*
+ * set PLL clocks based on input sysclk is 33M
+ *
+ * ----------------------------------
+ * | CLK | FREQ (MHz) | DIV RATIO |
+ * ----------------------------------
+ * | CPU | 266.64 | 3 |
+ * | PLB | 159.98 | 5 (0x05)|
+ * | OPB | 79.99 | 10 (0x0A)|
+ * | EBC | 79.99 | 10 (0x0A)|
+ * | SPI | 79.99 | 10 (0x0A)|
+ * | UART0 | 28.57 | 7 (0x07)|
+ * | UART1 | 28.57 | 7 (0x07)|
+ * | DAC | 28.57 | 7 (0xA7)|
+ * | ADC | 4 | 50 (0x32)|
+ * | PWM | 28.57 | 7 (0x07)|
+ * | EMAC | 4 | 50 (0x32)|
+ * -----------------------------------
+ */
+
+ /* Initialize PLL */
+ mtcpr(cprpllc, 0x20000238);
+ mtcpr(cprplld, 0x03010400);
+ mtcpr(cprprimad, 0x03050a0a);
+ mtcpr(cprperc0, 0x00000000);
+ mtcpr(cprperd0, 0x070a0707); /* SPI clk div. eq. OPB clk div. */
+ mtcpr(cprperd1, 0x07323200);
+ mtcpr(cprclkupd, 0x40000000);
+}
+
+#elif defined(PLLMR0_333_166_83)
+
+void board_pll_init_f(void)
+{
+ /*
+ * set PLL clocks based on input sysclk is 33M
+ *
+ * ----------------------------------
+ * | CLK | FREQ (MHz) | DIV RATIO |
+ * ----------------------------------
+ * | CPU | 333.33 | 2 |
+ * | PLB | 166.66 | 4 (0x04)|
+ * | OPB | 83.33 | 8 (0x08)|
+ * | EBC | 83.33 | 8 (0x08)|
+ * | SPI | 83.33 | 8 (0x08)|
+ * | UART0 | 16.66 | 5 (0x05)|
+ * | UART1 | 16.66 | 5 (0x05)|
+ * | DAC | ???? | 166 (0xA6)|
+ * | ADC | ???? | 166 (0xA6)|
+ * | PWM | 41.66 | 3 (0x03)|
+ * | EMAC | ???? | 3 (0x03)|
+ * -----------------------------------
+ */
+
+ /* Initialize PLL */
+ mtcpr(cprpllc, 0x0000033C);
+ mtcpr(cprplld, 0x0a010000);
+ mtcpr(cprprimad, 0x02040808);
+ mtcpr(cprperd0, 0x02080505); /* SPI clk div. eq. OPB clk div. */
+ mtcpr(cprperd1, 0xA6A60300);
+ mtcpr(cprclkupd, 0x40000000);
+}
+
+#elif defined(PLLMR0_100_100_12)
+
+void board_pll_init_f(void)
+{
+ /*
+ * set PLL clocks based on input sysclk is 33M
+ *
+ * ----------------------
+ * | CLK | FREQ (MHz) |
+ * ----------------------
+ * | CPU | 100.00 |
+ * | PLB | 100.00 |
+ * | OPB | 12.00 |
+ * | EBC | 49.00 |
+ * ----------------------
+ */
+
+ /* Initialize PLL */
+ mtcpr(cprpllc, 0x000003BC);
+ mtcpr(cprplld, 0x06060600);
+ mtcpr(cprprimad, 0x02020004);
+ mtcpr(cprperd0, 0x04002828); /* SPI clk div. eq. OPB clk div. */
+ mtcpr(cprperd1, 0xC8C81600);
+ mtcpr(cprclkupd, 0x40000000);
+}
+#endif /* CPU_<speed>_405EZ */
+
+#if defined(CONFIG_NAND_SPL) || defined(CONFIG_SPI_SPL)
+/*
+ * Get timebase clock frequency
+ */
+unsigned long get_tbclk (void)
+{
+ unsigned long cpr_plld;
+ unsigned long cpr_primad;
+ unsigned long primad_cpudv;
+ unsigned long pllFbkDiv;
+ unsigned long freqProcessor;
+
+ /*
+ * Read PLL Mode registers
+ */
+ mfcpr(cprplld, cpr_plld);
+
+ /*
+ * Read CPR_PRIMAD register
+ */
+ mfcpr(cprprimad, cpr_primad);
+
+ /*
+ * Determine CPU clock frequency
+ */
+ primad_cpudv = ((cpr_primad & PRIMAD_CPUDV_MASK) >> 24);
+ if (primad_cpudv == 0)
+ primad_cpudv = 16;
+
+ /*
+ * Determine FBK_DIV.
+ */
+ pllFbkDiv = ((cpr_plld & PLLD_FBDV_MASK) >> 24);
+ if (pllFbkDiv == 0)
+ pllFbkDiv = 256;
+
+ freqProcessor = (CONFIG_SYS_CLK_FREQ * pllFbkDiv) / primad_cpudv;
+
+ return (freqProcessor);
+}
+#endif /* defined(CONFIG_NAND_SPL) || defined(CONFIG_SPI_SPL) */
diff --git a/board/amcc/acadia/flash.c b/board/amcc/acadia/flash.c
new file mode 100644
index 00000000000..0626aba9d57
--- /dev/null
+++ b/board/amcc/acadia/flash.c
@@ -0,0 +1,1108 @@
+/*
+ * (C) Copyright 2004-2005
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * (C) Copyright 2002 Jun Gu <jung@artesyncp.com>
+ * Add support for Am29F016D and dynamic switch setting.
+ *
+ * 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
+ */
+
+/*
+ * Modified 4/5/2001
+ * Wait for completion of each sector erase command issued
+ * 4/5/2001
+ * Chris Hallinan - DS4.COM, Inc. - clh@net1plus.com
+ */
+
+#include <common.h>
+#include <ppc4xx.h>
+#include <asm/processor.h>
+
+#ifdef DEBUG
+#define DEBUGF(x...) printf(x)
+#else
+#define DEBUGF(x...)
+#endif /* DEBUG */
+
+flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */
+
+/*
+ * Mark big flash bank (16 bit instead of 8 bit access) in address with bit 0
+ */
+static unsigned long flash_addr_table[][CFG_MAX_FLASH_BANKS] = {
+ {0xffc00001}, /* 0:boot from big flash */
+};
+
+/*
+ * include common flash code (for amcc boards)
+ */
+/*-----------------------------------------------------------------------
+ * Functions
+ */
+static int write_word(flash_info_t * info, ulong dest, ulong data);
+#ifdef CFG_FLASH_2ND_16BIT_DEV
+static int write_word_1(flash_info_t * info, ulong dest, ulong data);
+static int write_word_2(flash_info_t * info, ulong dest, ulong data);
+static int flash_erase_1(flash_info_t * info, int s_first, int s_last);
+static int flash_erase_2(flash_info_t * info, int s_first, int s_last);
+static ulong flash_get_size_1(vu_long * addr, flash_info_t * info);
+static ulong flash_get_size_2(vu_long * addr, flash_info_t * info);
+#endif
+
+void flash_print_info(flash_info_t * info)
+{
+ int i;
+ int k;
+ int size;
+ int erased;
+ volatile unsigned long *flash;
+
+ if (info->flash_id == FLASH_UNKNOWN) {
+ printf("missing or unknown FLASH type\n");
+ return;
+ }
+
+ switch (info->flash_id & FLASH_VENDMASK) {
+ case FLASH_MAN_AMD:
+ printf("AMD ");
+ break;
+ case FLASH_MAN_STM:
+ printf("STM ");
+ break;
+ case FLASH_MAN_FUJ:
+ printf("FUJITSU ");
+ break;
+ case FLASH_MAN_SST:
+ printf("SST ");
+ break;
+ case FLASH_MAN_MX:
+ printf("MIXC ");
+ break;
+ default:
+ printf("Unknown Vendor ");
+ break;
+ }
+
+ switch (info->flash_id & FLASH_TYPEMASK) {
+ case FLASH_AM040:
+ printf("AM29F040 (512 Kbit, uniform sector size)\n");
+ break;
+ case FLASH_AM400B:
+ printf("AM29LV400B (4 Mbit, bottom boot sect)\n");
+ break;
+ case FLASH_AM400T:
+ printf("AM29LV400T (4 Mbit, top boot sector)\n");
+ break;
+ case FLASH_AM800B:
+ printf("AM29LV800B (8 Mbit, bottom boot sect)\n");
+ break;
+ case FLASH_AM800T:
+ printf("AM29LV800T (8 Mbit, top boot sector)\n");
+ break;
+ case FLASH_AMD016:
+ printf("AM29F016D (16 Mbit, uniform sector size)\n");
+ break;
+ case FLASH_AM160B:
+ printf("AM29LV160B (16 Mbit, bottom boot sect)\n");
+ break;
+ case FLASH_AM160T:
+ printf("AM29LV160T (16 Mbit, top boot sector)\n");
+ break;
+ case FLASH_AM320B:
+ printf("AM29LV320B (32 Mbit, bottom boot sect)\n");
+ break;
+ case FLASH_AM320T:
+ printf("AM29LV320T (32 Mbit, top boot sector)\n");
+ break;
+ case FLASH_AM033C:
+ printf("AM29LV033C (32 Mbit, top boot sector)\n");
+ break;
+ case FLASH_SST800A:
+ printf("SST39LF/VF800 (8 Mbit, uniform sector size)\n");
+ break;
+ case FLASH_SST160A:
+ printf("SST39LF/VF160 (16 Mbit, uniform sector size)\n");
+ break;
+ case FLASH_STMW320DT:
+ printf ("M29W320DT (32 M, top sector)\n");
+ break;
+ case FLASH_MXLV320T:
+ printf ("MXLV320T (32 Mbit, top sector)\n");
+ break;
+ default:
+ printf("Unknown Chip Type\n");
+ 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) {
+ /*
+ * Check if whole sector is erased
+ */
+ if (i != (info->sector_count - 1))
+ size = info->start[i + 1] - info->start[i];
+ else
+ size = info->start[0] + info->size - info->start[i];
+ erased = 1;
+ flash = (volatile unsigned long *)info->start[i];
+ size = size >> 2; /* divide by 4 for longword access */
+ for (k = 0; k < size; k++) {
+ if (*flash++ != 0xffffffff) {
+ erased = 0;
+ break;
+ }
+ }
+
+ if ((i % 5) == 0)
+ printf("\n ");
+ printf(" %08lX%s%s",
+ info->start[i],
+ erased ? " E" : " ", info->protect[i] ? "RO " : " ");
+ }
+ printf("\n");
+ return;
+}
+
+/*
+ * The following code cannot be run from FLASH!
+ */
+#ifdef CFG_FLASH_2ND_16BIT_DEV
+static ulong flash_get_size(vu_long * addr, flash_info_t * info)
+{
+ /* bit 0 used for big flash marking */
+ if ((ulong)addr & 0x1) {
+ return flash_get_size_2((vu_long *)((ulong)addr & 0xfffffffe), info);
+ } else {
+ return flash_get_size_1(addr, info);
+ }
+}
+
+static ulong flash_get_size_1(vu_long * addr, flash_info_t * info)
+#else
+static ulong flash_get_size(vu_long * addr, flash_info_t * info)
+#endif
+{
+ short i;
+ CFG_FLASH_WORD_SIZE value;
+ ulong base = (ulong) addr;
+ volatile CFG_FLASH_WORD_SIZE *addr2 = (CFG_FLASH_WORD_SIZE *) addr;
+
+ DEBUGF("FLASH ADDR: %08x\n", (unsigned)addr);
+
+ /* Write auto select command: read Manufacturer ID */
+ addr2[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE) 0x00AA00AA;
+ addr2[CFG_FLASH_ADDR1] = (CFG_FLASH_WORD_SIZE) 0x00550055;
+ addr2[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE) 0x00900090;
+ udelay(1000);
+
+ value = addr2[0];
+ DEBUGF("FLASH MANUFACT: %x\n", value);
+
+ switch (value) {
+ case (CFG_FLASH_WORD_SIZE) AMD_MANUFACT:
+ info->flash_id = FLASH_MAN_AMD;
+ break;
+ case (CFG_FLASH_WORD_SIZE) FUJ_MANUFACT:
+ info->flash_id = FLASH_MAN_FUJ;
+ break;
+ case (CFG_FLASH_WORD_SIZE) SST_MANUFACT:
+ info->flash_id = FLASH_MAN_SST;
+ break;
+ case (CFG_FLASH_WORD_SIZE) STM_MANUFACT:
+ info->flash_id = FLASH_MAN_STM;
+ break;
+ default:
+ info->flash_id = FLASH_UNKNOWN;
+ info->sector_count = 0;
+ info->size = 0;
+ return (0); /* no or unknown flash */
+ }
+
+ value = addr2[1]; /* device ID */
+ DEBUGF("\nFLASH DEVICEID: %x\n", value);
+
+ switch (value) {
+ case (CFG_FLASH_WORD_SIZE) AMD_ID_LV040B:
+ info->flash_id += FLASH_AM040;
+ info->sector_count = 8;
+ info->size = 0x0080000; /* => 512 ko */
+ break;
+
+ case (CFG_FLASH_WORD_SIZE) AMD_ID_F040B:
+ info->flash_id += FLASH_AM040;
+ info->sector_count = 8;
+ info->size = 0x0080000; /* => 512 ko */
+ break;
+
+ case (CFG_FLASH_WORD_SIZE) STM_ID_M29W040B:
+ info->flash_id += FLASH_AM040;
+ info->sector_count = 8;
+ info->size = 0x0080000; /* => 512 ko */
+ break;
+
+ case (CFG_FLASH_WORD_SIZE) AMD_ID_F016D:
+ info->flash_id += FLASH_AMD016;
+ info->sector_count = 32;
+ info->size = 0x00200000;
+ break; /* => 2 MB */
+
+ case (CFG_FLASH_WORD_SIZE) AMD_ID_LV033C:
+ info->flash_id += FLASH_AMDLV033C;
+ info->sector_count = 64;
+ info->size = 0x00400000;
+ break; /* => 4 MB */
+
+ case (CFG_FLASH_WORD_SIZE) AMD_ID_LV400T:
+ info->flash_id += FLASH_AM400T;
+ info->sector_count = 11;
+ info->size = 0x00080000;
+ break; /* => 0.5 MB */
+
+ case (CFG_FLASH_WORD_SIZE) AMD_ID_LV400B:
+ info->flash_id += FLASH_AM400B;
+ info->sector_count = 11;
+ info->size = 0x00080000;
+ break; /* => 0.5 MB */
+
+ case (CFG_FLASH_WORD_SIZE) AMD_ID_LV800T:
+ info->flash_id += FLASH_AM800T;
+ info->sector_count = 19;
+ info->size = 0x00100000;
+ break; /* => 1 MB */
+
+ case (CFG_FLASH_WORD_SIZE) AMD_ID_LV800B:
+ info->flash_id += FLASH_AM800B;
+ info->sector_count = 19;
+ info->size = 0x00100000;
+ break; /* => 1 MB */
+
+ case (CFG_FLASH_WORD_SIZE) AMD_ID_LV160T:
+ info->flash_id += FLASH_AM160T;
+ info->sector_count = 35;
+ info->size = 0x00200000;
+ break; /* => 2 MB */
+
+ case (CFG_FLASH_WORD_SIZE) AMD_ID_LV160B:
+ info->flash_id += FLASH_AM160B;
+ info->sector_count = 35;
+ info->size = 0x00200000;
+ break; /* => 2 MB */
+
+ default:
+ info->flash_id = FLASH_UNKNOWN;
+ return (0); /* => no or unknown flash */
+ }
+
+ /* set up sector start address table */
+ if (((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_SST) ||
+ ((info->flash_id & FLASH_TYPEMASK) == FLASH_AM040) ||
+ ((info->flash_id & FLASH_TYPEMASK) == FLASH_AMD016)) {
+ for (i = 0; i < info->sector_count; i++)
+ info->start[i] = base + (i * 0x00010000);
+ } else {
+ if (info->flash_id & FLASH_BTYPE) {
+ /* set sector offsets for bottom boot block type */
+ info->start[0] = base + 0x00000000;
+ info->start[1] = base + 0x00004000;
+ info->start[2] = base + 0x00006000;
+ info->start[3] = base + 0x00008000;
+ for (i = 4; i < info->sector_count; i++) {
+ info->start[i] =
+ base + (i * 0x00010000) - 0x00030000;
+ }
+ } else {
+ /* set sector offsets for top boot block type */
+ i = info->sector_count - 1;
+ info->start[i--] = base + info->size - 0x00004000;
+ info->start[i--] = base + info->size - 0x00006000;
+ info->start[i--] = base + info->size - 0x00008000;
+ for (; i >= 0; i--) {
+ info->start[i] = base + i * 0x00010000;
+ }
+ }
+ }
+
+ /* check for protected sectors */
+ for (i = 0; i < info->sector_count; i++) {
+ /* read sector protection at sector address, (A7 .. A0) = 0x02 */
+ /* D0 = 1 if protected */
+ addr2 = (volatile CFG_FLASH_WORD_SIZE *)(info->start[i]);
+
+ /* For AMD29033C flash we need to resend the command of *
+ * reading flash protection for upper 8 Mb of flash */
+ if (i == 32) {
+ addr2[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE) 0xAAAAAAAA;
+ addr2[CFG_FLASH_ADDR1] = (CFG_FLASH_WORD_SIZE) 0x55555555;
+ addr2[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE) 0x90909090;
+ }
+
+ if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_SST)
+ info->protect[i] = 0;
+ else
+ info->protect[i] = addr2[2] & 1;
+ }
+
+ /* issue bank reset to return to read mode */
+ addr2[0] = (CFG_FLASH_WORD_SIZE) 0x00F000F0;
+
+ return (info->size);
+}
+
+static int wait_for_DQ7_1(flash_info_t * info, int sect)
+{
+ ulong start, now, last;
+ volatile CFG_FLASH_WORD_SIZE *addr =
+ (CFG_FLASH_WORD_SIZE *) (info->start[sect]);
+
+ start = get_timer(0);
+ last = start;
+ while ((addr[0] & (CFG_FLASH_WORD_SIZE) 0x00800080) !=
+ (CFG_FLASH_WORD_SIZE) 0x00800080) {
+ if ((now = get_timer(start)) > CFG_FLASH_ERASE_TOUT) {
+ printf("Timeout\n");
+ return -1;
+ }
+ /* show that we're waiting */
+ if ((now - last) > 1000) { /* every second */
+ putc('.');
+ last = now;
+ }
+ }
+ return 0;
+}
+
+#ifdef CFG_FLASH_2ND_16BIT_DEV
+int flash_erase(flash_info_t * info, int s_first, int s_last)
+{
+ if (((info->flash_id & FLASH_TYPEMASK) == FLASH_AM320B) ||
+ ((info->flash_id & FLASH_TYPEMASK) == FLASH_AM320T) ||
+ ((info->flash_id & FLASH_TYPEMASK) == FLASH_STMW320DT) ||
+ ((info->flash_id & FLASH_TYPEMASK) == FLASH_MXLV320T)) {
+ return flash_erase_2(info, s_first, s_last);
+ } else {
+ return flash_erase_1(info, s_first, s_last);
+ }
+}
+
+static int flash_erase_1(flash_info_t * info, int s_first, int s_last)
+#else
+int flash_erase(flash_info_t * info, int s_first, int s_last)
+#endif
+{
+ volatile CFG_FLASH_WORD_SIZE *addr = (CFG_FLASH_WORD_SIZE *) (info->start[0]);
+ volatile CFG_FLASH_WORD_SIZE *addr2;
+ int flag, prot, sect, l_sect;
+ int i;
+
+ if ((s_first < 0) || (s_first > s_last)) {
+ if (info->flash_id == FLASH_UNKNOWN) {
+ printf("- missing\n");
+ } else {
+ printf("- no sectors to erase\n");
+ }
+ return 1;
+ }
+
+ if (info->flash_id == FLASH_UNKNOWN) {
+ printf("Can't erase unknown flash type - aborted\n");
+ return 1;
+ }
+
+ prot = 0;
+ for (sect = s_first; sect <= s_last; ++sect) {
+ if (info->protect[sect]) {
+ prot++;
+ }
+ }
+
+ if (prot) {
+ printf("- Warning: %d protected sectors will not be erased!\n",
+ prot);
+ } else {
+ printf("\n");
+ }
+
+ l_sect = -1;
+
+ /* Disable interrupts which might cause a timeout here */
+ flag = disable_interrupts();
+
+ /* Start erase on unprotected sectors */
+ for (sect = s_first; sect <= s_last; sect++) {
+ if (info->protect[sect] == 0) { /* not protected */
+ addr2 = (CFG_FLASH_WORD_SIZE *) (info->start[sect]);
+
+ if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_SST) {
+ addr[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE) 0x00AA00AA;
+ addr[CFG_FLASH_ADDR1] = (CFG_FLASH_WORD_SIZE) 0x00550055;
+ addr[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE) 0x00800080;
+ addr[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE) 0x00AA00AA;
+ addr[CFG_FLASH_ADDR1] = (CFG_FLASH_WORD_SIZE) 0x00550055;
+ addr2[0] = (CFG_FLASH_WORD_SIZE) 0x00500050; /* block erase */
+ for (i = 0; i < 50; i++)
+ udelay(1000); /* wait 1 ms */
+ } else {
+ addr[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE) 0x00AA00AA;
+ addr[CFG_FLASH_ADDR1] = (CFG_FLASH_WORD_SIZE) 0x00550055;
+ addr[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE) 0x00800080;
+ addr[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE) 0x00AA00AA;
+ addr[CFG_FLASH_ADDR1] = (CFG_FLASH_WORD_SIZE) 0x00550055;
+ addr2[0] = (CFG_FLASH_WORD_SIZE) 0x00300030; /* sector erase */
+ }
+ l_sect = sect;
+ /*
+ * Wait for each sector to complete, it's more
+ * reliable. According to AMD Spec, you must
+ * issue all erase commands within a specified
+ * timeout. This has been seen to fail, especially
+ * if printf()s are included (for debug)!!
+ */
+ wait_for_DQ7_1(info, sect);
+ }
+ }
+
+ /* re-enable interrupts if necessary */
+ if (flag)
+ enable_interrupts();
+
+ /* wait at least 80us - let's wait 1 ms */
+ udelay(1000);
+
+ /* reset to read mode */
+ addr = (CFG_FLASH_WORD_SIZE *) info->start[0];
+ addr[0] = (CFG_FLASH_WORD_SIZE) 0x00F000F0; /* reset bank */
+
+ printf(" done\n");
+ return 0;
+}
+
+/*-----------------------------------------------------------------------
+ * Copy memory to flash, returns:
+ * 0 - OK
+ * 1 - write timeout
+ * 2 - Flash not erased
+ */
+int write_buff(flash_info_t * info, uchar * src, ulong addr, ulong cnt)
+{
+ ulong cp, wp, data;
+ int i, l, rc;
+
+ wp = (addr & ~3); /* get lower word aligned address */
+
+ /*
+ * handle unaligned start bytes
+ */
+ if ((l = addr - wp) != 0) {
+ data = 0;
+ for (i = 0, cp = wp; i < l; ++i, ++cp) {
+ data = (data << 8) | (*(uchar *) cp);
+ }
+ for (; i < 4 && cnt > 0; ++i) {
+ data = (data << 8) | *src++;
+ --cnt;
+ ++cp;
+ }
+ for (; cnt == 0 && i < 4; ++i, ++cp) {
+ data = (data << 8) | (*(uchar *) cp);
+ }
+
+ if ((rc = write_word(info, wp, data)) != 0) {
+ return (rc);
+ }
+ wp += 4;
+ }
+
+ /*
+ * handle word aligned part
+ */
+ while (cnt >= 4) {
+ data = 0;
+ for (i = 0; i < 4; ++i) {
+ data = (data << 8) | *src++;
+ }
+ if ((rc = write_word(info, wp, data)) != 0) {
+ return (rc);
+ }
+ wp += 4;
+ cnt -= 4;
+ }
+
+ if (cnt == 0) {
+ return (0);
+ }
+
+ /*
+ * handle unaligned tail bytes
+ */
+ data = 0;
+ for (i = 0, cp = wp; i < 4 && cnt > 0; ++i, ++cp) {
+ data = (data << 8) | *src++;
+ --cnt;
+ }
+ for (; i < 4; ++i, ++cp) {
+ data = (data << 8) | (*(uchar *) cp);
+ }
+
+ return (write_word(info, wp, data));
+}
+
+/*-----------------------------------------------------------------------
+ * Copy memory to flash, returns:
+ * 0 - OK
+ * 1 - write timeout
+ * 2 - Flash not erased
+ */
+#ifdef CFG_FLASH_2ND_16BIT_DEV
+static int write_word(flash_info_t * info, ulong dest, ulong data)
+{
+ if (((info->flash_id & FLASH_TYPEMASK) == FLASH_AM320B) ||
+ ((info->flash_id & FLASH_TYPEMASK) == FLASH_AM320T) ||
+ ((info->flash_id & FLASH_TYPEMASK) == FLASH_STMW320DT) ||
+ ((info->flash_id & FLASH_TYPEMASK) == FLASH_MXLV320T)) {
+ return write_word_2(info, dest, data);
+ } else {
+ return write_word_1(info, dest, data);
+ }
+}
+
+static int write_word_1(flash_info_t * info, ulong dest, ulong data)
+#else
+static int write_word(flash_info_t * info, ulong dest, ulong data)
+#endif
+{
+ volatile CFG_FLASH_WORD_SIZE *addr2 = (CFG_FLASH_WORD_SIZE *) (info->start[0]);
+ volatile CFG_FLASH_WORD_SIZE *dest2 = (CFG_FLASH_WORD_SIZE *) dest;
+ volatile CFG_FLASH_WORD_SIZE *data2 = (CFG_FLASH_WORD_SIZE *) & data;
+ ulong start;
+ int i;
+
+ /* Check if Flash is (sufficiently) erased */
+ if ((*((vu_long *)dest) & data) != data) {
+ return (2);
+ }
+
+ for (i = 0; i < 4 / sizeof(CFG_FLASH_WORD_SIZE); i++) {
+ int flag;
+
+ /* Disable interrupts which might cause a timeout here */
+ flag = disable_interrupts();
+
+ addr2[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE) 0x00AA00AA;
+ addr2[CFG_FLASH_ADDR1] = (CFG_FLASH_WORD_SIZE) 0x00550055;
+ addr2[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE) 0x00A000A0;
+
+ dest2[i] = data2[i];
+
+ /* re-enable interrupts if necessary */
+ if (flag)
+ enable_interrupts();
+
+ /* data polling for D7 */
+ start = get_timer(0);
+ while ((dest2[i] & (CFG_FLASH_WORD_SIZE) 0x00800080) !=
+ (data2[i] & (CFG_FLASH_WORD_SIZE) 0x00800080)) {
+
+ if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {
+ return (1);
+ }
+ }
+ }
+
+ return (0);
+}
+
+#ifdef CFG_FLASH_2ND_16BIT_DEV
+
+#undef CFG_FLASH_WORD_SIZE
+#define CFG_FLASH_WORD_SIZE unsigned short
+
+/*
+ * The following code cannot be run from FLASH!
+ */
+static ulong flash_get_size_2(vu_long * addr, flash_info_t * info)
+{
+ short i;
+ int n;
+ CFG_FLASH_WORD_SIZE value;
+ ulong base = (ulong) addr;
+ volatile CFG_FLASH_WORD_SIZE *addr2 = (CFG_FLASH_WORD_SIZE *) addr;
+
+ DEBUGF("FLASH ADDR: %08x\n", (unsigned)addr);
+
+ /* issue bank reset to return to read mode */
+ addr2[0] = (CFG_FLASH_WORD_SIZE) 0x00F000F0;
+ /* Write auto select command: read Manufacturer ID */
+ addr2[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE) 0x00AA00AA;
+ addr2[CFG_FLASH_ADDR1] = (CFG_FLASH_WORD_SIZE) 0x00550055;
+ addr2[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE) 0x00900090;
+ udelay(1000);
+
+ value = addr2[0];
+ DEBUGF("FLASH MANUFACT: %x\n", value);
+
+#if 0 /* TODO: remove ifdef when Flash responds correctly */
+ switch (value) {
+ case (CFG_FLASH_WORD_SIZE) AMD_MANUFACT:
+ info->flash_id = FLASH_MAN_AMD;
+ break;
+ case (CFG_FLASH_WORD_SIZE) FUJ_MANUFACT:
+ info->flash_id = FLASH_MAN_FUJ;
+ break;
+ case (CFG_FLASH_WORD_SIZE) SST_MANUFACT:
+ info->flash_id = FLASH_MAN_SST;
+ break;
+ case (CFG_FLASH_WORD_SIZE) STM_MANUFACT:
+ info->flash_id = FLASH_MAN_STM;
+ break;
+ case (CFG_FLASH_WORD_SIZE) MX_MANUFACT:
+ info->flash_id = FLASH_MAN_MX;
+ break;
+ default:
+ info->flash_id = FLASH_UNKNOWN;
+ info->sector_count = 0;
+ info->size = 0;
+ return (0); /* no or unknown flash */
+ }
+#endif /* TODO: remove ifdef when Flash responds correctly */
+
+ /*
+ * TODO: Start
+ * uncomment block above when Flash responds correctly.
+ * also remove the lines below:
+ */
+ info->flash_id = FLASH_MAN_AMD;
+ DEBUGF("FLASH MANUFACT: FLASH_MAN_AMD\n");
+ /* TODO: End */
+
+ value = addr2[1]; /* device ID */
+
+ DEBUGF("\nFLASH DEVICEID: %x\n", value);
+
+#if 0 /* TODO: remove ifdef when Flash responds correctly */
+ switch (value) {
+
+ case (CFG_FLASH_WORD_SIZE)AMD_ID_LV320T:
+ info->flash_id += FLASH_AM320T;
+ info->sector_count = 71;
+ info->size = 0x00400000; break; /* => 4 MB */
+
+ case (CFG_FLASH_WORD_SIZE)AMD_ID_LV320B:
+ info->flash_id += FLASH_AM320B;
+ info->sector_count = 71;
+ info->size = 0x00400000; break; /* => 4 MB */
+
+ case (CFG_FLASH_WORD_SIZE)STM_ID_29W320DT:
+ info->flash_id += FLASH_STMW320DT;
+ info->sector_count = 67;
+ info->size = 0x00400000; break; /* => 4 MB */
+
+ case (CFG_FLASH_WORD_SIZE)MX_ID_LV320T:
+ info->flash_id += FLASH_MXLV320T;
+ info->sector_count = 71;
+ info->size = 0x00400000; break; /* => 4 MB */
+
+ default:
+ info->flash_id = FLASH_UNKNOWN;
+ return (0); /* => no or unknown flash */
+ }
+#endif /* TODO: remove ifdef when Flash responds correctly */
+
+ /*
+ * TODO: Start
+ * uncomment block above when Flash responds correctly.
+ * also remove the lines below:
+ */
+ DEBUGF("\nFLASH DEVICEID: FLASH_AM320T\n");
+ info->flash_id += FLASH_AM320T;
+ info->sector_count = 71;
+ info->size = 0x00400000; /* => 4 MB */
+ /* TODO: End */
+
+ /* set up sector start address table */
+ if (((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_SST) ||
+ ((info->flash_id & FLASH_TYPEMASK) == FLASH_AM040) ||
+ ((info->flash_id & FLASH_TYPEMASK) == FLASH_AMD016)) {
+ for (i = 0; i < info->sector_count; i++)
+ info->start[i] = base + (i * 0x00010000);
+ } else if ((info->flash_id & FLASH_TYPEMASK) == FLASH_STMW320DT) {
+ /* set sector offsets for top boot block type */
+ base += info->size;
+ i = info->sector_count;
+ /* 1 x 16k boot sector */
+ base -= 16 << 10;
+ --i;
+ info->start[i] = base;
+ /* 2 x 8k boot sectors */
+ for (n=0; n<2; ++n) {
+ base -= 8 << 10;
+ --i;
+ info->start[i] = base;
+ }
+ /* 1 x 32k boot sector */
+ base -= 32 << 10;
+ --i;
+ info->start[i] = base;
+
+ while (i > 0) { /* 64k regular sectors */
+ base -= 64 << 10;
+ --i;
+ info->start[i] = base;
+ }
+ } else if ( ((info->flash_id & FLASH_TYPEMASK) == FLASH_MXLV320T) ||
+ ((info->flash_id & FLASH_TYPEMASK) == FLASH_AM320T) ) {
+ i = info->sector_count - 1;
+ info->start[i--] = base + info->size - 0x00002000;
+ info->start[i--] = base + info->size - 0x00004000;
+ info->start[i--] = base + info->size - 0x00006000;
+ info->start[i--] = base + info->size - 0x00008000;
+ info->start[i--] = base + info->size - 0x0000a000;
+ info->start[i--] = base + info->size - 0x0000c000;
+ info->start[i--] = base + info->size - 0x0000e000;
+ info->start[i--] = base + info->size - 0x00010000;
+ for (; i >= 0; i--) {
+ info->start[i] = base + i * 0x00010000;
+ }
+ }
+ else {
+ if (info->flash_id & FLASH_BTYPE){
+ /* set sector offsets for bottom boot block type */
+ info->start[0] = base + 0x00000000;
+ info->start[1] = base + 0x00004000;
+ info->start[2] = base + 0x00006000;
+ info->start[3] = base + 0x00008000;
+ for (i = 4; i < info->sector_count; i++) {
+ info->start[i] =
+ base + (i * 0x00010000) - 0x00030000;
+ }
+ } else {
+ /* set sector offsets for top boot block type */
+ i = info->sector_count - 1;
+ info->start[i--] = base + info->size - 0x00004000;
+ info->start[i--] = base + info->size - 0x00006000;
+ info->start[i--] = base + info->size - 0x00008000;
+ for (; i >= 0; i--) {
+ info->start[i] = base + i * 0x00010000;
+ }
+ }
+ }
+
+ /* check for protected sectors */
+ for (i = 0; i < info->sector_count; i++) {
+ /* read sector protection at sector address,(A7 .. A0) = 0x02 */
+ /* D0 = 1 if protected */
+ addr2 = (volatile CFG_FLASH_WORD_SIZE *)(info->start[i]);
+
+ /* For AMD29033C flash we need to resend the command of *
+ * reading flash protection for upper 8 Mb of flash */
+ if (i == 32) {
+ addr2[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE) 0xAAAAAAAA;
+ addr2[CFG_FLASH_ADDR1] = (CFG_FLASH_WORD_SIZE) 0x55555555;
+ addr2[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE) 0x90909090;
+ }
+
+ if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_SST)
+ info->protect[i] = 0;
+ else
+ info->protect[i] = addr2[2] & 1;
+ }
+
+ /* issue bank reset to return to read mode */
+ addr2[0] = (CFG_FLASH_WORD_SIZE) 0x00F000F0;
+
+ return (info->size);
+}
+
+/*
+ * TODO: FIX: this wait loop sometimes fails: DQ7 indicates the erase command
+ * never was accepted (i.e. didn't start) - why????
+ */
+static int wait_for_DQ7_2(flash_info_t * info, int sect)
+{
+ ulong start, now, last, counter = 0;
+ volatile CFG_FLASH_WORD_SIZE *addr =
+ (CFG_FLASH_WORD_SIZE *) (info->start[sect]);
+
+ start = get_timer(0);
+ DEBUGF("DQ7_2: start = 0x%08lx\n", start);
+ last = start;
+ while ((addr[0] & (CFG_FLASH_WORD_SIZE) 0x00800080) !=
+ (CFG_FLASH_WORD_SIZE) 0x00800080) {
+ DEBUGF("DQ7_2: start = 0x%08lx, now = 0x%08lx\n", start, now);
+ if ((now = get_timer(start)) > CFG_FLASH_ERASE_TOUT) {
+ printf("Timeout\n");
+ return -1;
+ }
+ /* show that we're waiting */
+ if ((now - last) > 1000) { /* every second */
+ putc('.');
+ last = now;
+ }
+ udelay(1000000); /* 1 sec */
+ putc('.');
+ counter++;
+ if (counter > 5) {
+ return -1;
+ }
+ DEBUGF("DQ7_2: now = 0x%08lx, last = 0x%08lx\n", now, last);
+ }
+ return 0;
+}
+
+static void wr_flash_cmd(ulong sector, ushort addr, CFG_FLASH_WORD_SIZE value)
+{
+ int fw_size;
+
+ fw_size = sizeof(value);
+ switch (fw_size)
+ {
+ case 1:
+ out8((ulong)(sector + addr), value);
+ break;
+ case 2:
+ out16((ulong)(sector + (addr << 1)), value);
+ break;
+ default:
+ printf("flash_erase: error incorrect chip programing size.\n");
+ }
+ return;
+}
+
+static int flash_erase_2(flash_info_t * info, int s_first, int s_last)
+{
+ volatile CFG_FLASH_WORD_SIZE *addr = (CFG_FLASH_WORD_SIZE *) (info->start[0]);
+ volatile CFG_FLASH_WORD_SIZE *addr2;
+ int flag, prot, sect, l_sect, count = 0;
+ int i;
+
+ if ((s_first < 0) || (s_first > s_last)) {
+ if (info->flash_id == FLASH_UNKNOWN) {
+ printf("- missing\n");
+ } else {
+ printf("- no sectors to erase\n");
+ }
+ return 1;
+ }
+
+ if (info->flash_id == FLASH_UNKNOWN) {
+ printf("Can't erase unknown flash type - aborted\n");
+ return 1;
+ }
+
+ prot = 0;
+ for (sect = s_first; sect <= s_last; ++sect) {
+ if (info->protect[sect]) {
+ prot++;
+ }
+ }
+
+ if (prot) {
+ printf("- Warning: %d protected sectors will not be erased!\n",
+ prot);
+ } else {
+ printf("\n");
+ }
+
+ l_sect = -1;
+
+ /* Disable interrupts which might cause a timeout here */
+ flag = disable_interrupts();
+
+ /* Start erase on unprotected sectors */
+ for (sect = s_first, count = 0; sect <= s_last; sect++) {
+ if (info->protect[sect] == 0) { /* not protected */
+ addr2 = (CFG_FLASH_WORD_SIZE *) (info->start[sect]);
+
+ if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_SST) {
+ addr[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE) 0x00AA00AA;
+ addr[CFG_FLASH_ADDR1] = (CFG_FLASH_WORD_SIZE) 0x00550055;
+ addr[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE) 0x00800080;
+ addr[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE) 0x00AA00AA;
+ addr[CFG_FLASH_ADDR1] = (CFG_FLASH_WORD_SIZE) 0x00550055;
+ addr2[0] = (CFG_FLASH_WORD_SIZE) 0x00500050; /* block erase */
+ for (i = 0; i < 50; i++)
+ udelay(1000); /* wait 1 ms */
+ } else {
+ /*
+ * TODO: fix code
+ */
+ wr_flash_cmd((ulong)addr, 0, (CFG_FLASH_WORD_SIZE) 0x00F000F0);
+ wr_flash_cmd((ulong)addr, CFG_FLASH_ADDR0, (CFG_FLASH_WORD_SIZE) 0x00AA00AA);
+ wr_flash_cmd((ulong)addr, CFG_FLASH_ADDR1, (CFG_FLASH_WORD_SIZE) 0x00550055);
+ wr_flash_cmd((ulong)addr, CFG_FLASH_ADDR0, (CFG_FLASH_WORD_SIZE) 0x00800080);
+ wr_flash_cmd((ulong)addr, CFG_FLASH_ADDR0, (CFG_FLASH_WORD_SIZE) 0x00AA00AA);
+ wr_flash_cmd((ulong)addr, CFG_FLASH_ADDR1, (CFG_FLASH_WORD_SIZE) 0x00550055);
+ wr_flash_cmd((ulong)addr2, 0, (CFG_FLASH_WORD_SIZE) 0x00300030);
+ udelay(2000000); /* 2 sec */
+ wr_flash_cmd((ulong)addr, 0, (CFG_FLASH_WORD_SIZE) 0x00F000F0);
+
+#if 0
+ addr[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE) 0x00AA00AA;
+ addr[CFG_FLASH_ADDR1] = (CFG_FLASH_WORD_SIZE) 0x00550055;
+ addr[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE) 0x00800080;
+ addr[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE) 0x00AA00AA;
+ addr[CFG_FLASH_ADDR1] = (CFG_FLASH_WORD_SIZE) 0x00550055;
+ addr2[0] = (CFG_FLASH_WORD_SIZE) 0x00300030; /* sector erase */
+#endif
+ }
+ l_sect = sect;
+ printf("..");
+ printf("..");
+ /*
+ * Wait for each sector to complete, it's more
+ * reliable. According to AMD Spec, you must
+ * issue all erase commands within a specified
+ * timeout. This has been seen to fail, especially
+ * if printf()s are included (for debug)!!
+ */
+ wait_for_DQ7_2(info, sect);
+ count++;
+ }
+ }
+
+ /* re-enable interrupts if necessary */
+ if (flag)
+ enable_interrupts();
+
+ /* wait at least 80us - let's wait 1 ms */
+ udelay(1000);
+
+ /* reset to read mode */
+ addr = (CFG_FLASH_WORD_SIZE *) info->start[0];
+ addr[0] = (CFG_FLASH_WORD_SIZE) 0x00F000F0; /* reset bank */
+
+ printf(" done\n");
+
+ if (count > 0) {
+ return 0;
+ } else {
+ return 1;
+ }
+}
+
+static int write_word_2(flash_info_t * info, ulong dest, ulong data)
+{
+ volatile CFG_FLASH_WORD_SIZE *addr2 = (CFG_FLASH_WORD_SIZE *) (info->start[0]);
+ volatile CFG_FLASH_WORD_SIZE *dest2 = (CFG_FLASH_WORD_SIZE *) dest;
+ volatile CFG_FLASH_WORD_SIZE *data2 = (CFG_FLASH_WORD_SIZE *) & data;
+ ulong start;
+ int i;
+
+ /* Check if Flash is (sufficiently) erased */
+ if ((*((vu_long *)dest) & data) != data) {
+ return (2);
+ }
+
+ for (i = 0; i < 4 / sizeof(CFG_FLASH_WORD_SIZE); i++) {
+ int flag;
+
+ /* Disable interrupts which might cause a timeout here */
+ flag = disable_interrupts();
+
+ addr2[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE) 0x00AA00AA;
+ addr2[CFG_FLASH_ADDR1] = (CFG_FLASH_WORD_SIZE) 0x00550055;
+ addr2[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE) 0x00A000A0;
+
+ dest2[i] = data2[i];
+
+ /* re-enable interrupts if necessary */
+ if (flag)
+ enable_interrupts();
+
+ /* data polling for D7 */
+ start = get_timer(0);
+ while ((dest2[i] & (CFG_FLASH_WORD_SIZE) 0x00800080) !=
+ (data2[i] & (CFG_FLASH_WORD_SIZE) 0x00800080)) {
+
+ if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {
+ return (1);
+ }
+ }
+ }
+
+ return (0);
+}
+#endif /* CFG_FLASH_2ND_16BIT_DEV */
+
+/*-----------------------------------------------------------------------
+ * Functions
+ */
+static ulong flash_get_size(vu_long * addr, flash_info_t * info);
+static int write_word(flash_info_t * info, ulong dest, ulong data);
+
+/*-----------------------------------------------------------------------
+ */
+
+unsigned long flash_init(void)
+{
+ unsigned long total_b = 0;
+ unsigned long size_b[CFG_MAX_FLASH_BANKS];
+ unsigned short index = 0;
+ int i;
+
+ index = 0;
+
+ DEBUGF("\n");
+ DEBUGF("FLASH: Index: %d\n", index);
+
+ /* Init: no FLASHes known */
+ for (i = 0; i < CFG_MAX_FLASH_BANKS; ++i) {
+ flash_info[i].flash_id = FLASH_UNKNOWN;
+ flash_info[i].sector_count = -1;
+ flash_info[i].size = 0;
+
+ /* check whether the address is 0 */
+ if (flash_addr_table[index][i] == 0) {
+ continue;
+ }
+
+ /* call flash_get_size() to initialize sector address */
+ size_b[i] = flash_get_size((vu_long *) flash_addr_table[index][i],
+ &flash_info[i]);
+ flash_info[i].size = size_b[i];
+ if (flash_info[i].flash_id == FLASH_UNKNOWN) {
+ printf("## Unknown FLASH on Bank %d - Size = 0x%08lx = %ld MB\n",
+ i, size_b[i], size_b[i] << 20);
+ flash_info[i].sector_count = -1;
+ flash_info[i].size = 0;
+ }
+
+ /* Monitor protection ON by default */
+ (void)flash_protect(FLAG_PROTECT_SET, CFG_MONITOR_BASE,
+ CFG_MONITOR_BASE + CFG_MONITOR_LEN - 1,
+ &flash_info[i]);
+#if defined(CFG_ENV_IS_IN_FLASH)
+ (void)flash_protect(FLAG_PROTECT_SET, CFG_ENV_ADDR,
+ CFG_ENV_ADDR + CFG_ENV_SECT_SIZE - 1,
+ &flash_info[i]);
+#if defined(CFG_ENV_IS_IN_FLASH) && defined(CFG_ENV_ADDR_REDUND)
+ (void)flash_protect(FLAG_PROTECT_SET, CFG_ENV_ADDR_REDUND,
+ CFG_ENV_ADDR_REDUND + CFG_ENV_SECT_SIZE - 1,
+ &flash_info[i]);
+#endif
+#endif
+
+ total_b += flash_info[i].size;
+ }
+
+ return total_b;
+}
diff --git a/board/amcc/acadia/memory.c b/board/amcc/acadia/memory.c
new file mode 100644
index 00000000000..a1b015519a7
--- /dev/null
+++ b/board/amcc/acadia/memory.c
@@ -0,0 +1,552 @@
+/*
+ * (C) Copyright 2007
+ * Stefan Roese, DENX Software Engineering, sr@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <asm/processor.h>
+
+#define CRAM_BANK0_BASE 0x0
+#define CRAM_DIDR 0x00100000
+#define MICRON_MT45W8MW16BGX_CRAM_ID 0x1b431b43
+#define MICRON_MT45W8MW16BGX_CRAM_ID2 0x13431343
+#define MICRON_DIDR_VENDOR_ID 0x00030003 /* 00011b */
+#define CRAM_DIDR_VENDOR_ID_MASK 0x001f001f /* DIDR[4:0] */
+#define CRAM_DEVID_NOT_SUPPORTED 0x00000000
+
+#define PSRAM_PASS 0x50415353 /* "PASS" */
+#define PSRAM_FAIL 0x4641494C /* "FAIL" */
+
+static u32 is_cram_inited(void);
+static u32 is_cram(void);
+static long int cram_init(u32);
+static void cram_bcr_write(u32);
+void udelay (unsigned long);
+
+void sdram_init(void)
+{
+ volatile unsigned long spr_reg;
+
+ /*
+ * If CRAM not initialized or CRAM looks initialized because this
+ * is after a warm reboot then set SPRG7 to indicate CRAM needs
+ * initialization. Note that CRAM is initialized by the SPI and
+ * NAND preloader.
+ */
+ spr_reg = (volatile unsigned long) mfspr(SPRG6);
+ if ((is_cram_inited() != 1) || (spr_reg != LOAK_SPL)) {
+ mtspr(SPRG7, LOAK_NONE); /* "NONE" */
+ }
+#if 1
+ /*
+ * When running the NAND SPL, the normal EBC configuration is not
+ * done, so We need to enable EPLD access on EBC_CS_2 and the memory
+ * on EBC_CS_3
+ */
+
+ /* Enable CPLD - Needed for PSRAM Access */
+
+
+ /* Init SDRAM by setting EBC Bank 3 for PSRAM */
+ mtebc(pb1ap, CFG_EBC_PB1AP);
+ mtebc(pb1cr, CFG_EBC_PB1CR);
+
+ mtebc(pb2ap, CFG_EBC_PB2AP);
+ mtebc(pb2cr, CFG_EBC_PB2CR);
+
+ /* pre-boot loader code: we are in OCM */
+ mtspr(SPRG6, LOAK_SPL); /* "SPL " */
+ mtspr(SPRG7, LOAK_OCM); /* "OCM " */
+#endif
+ return;
+}
+
+static void cram_bcr_write(u32 wr_val)
+{
+ u32 tmp_reg;
+ u32 val;
+ volatile u32 gpio_reg;
+
+ /* # Program CRAM write */
+
+ /*
+ * set CRAM_CRE = 0x1
+ * set wr_val = wr_val << 2
+ */
+ gpio_reg = in32(GPIO1_OR);
+ out32(GPIO1_OR, gpio_reg | 0x00000400);
+ wr_val = wr_val << 2;
+ /* wr_val = 0x1c048; */
+
+ /*
+ * # stop PLL clock before programming CRAM
+ * set EPLD0_MUX_CTL.OESPR3 = 1
+ * delay 2
+ */
+
+ /*
+ * # CS1
+ * read 0x00200000
+ * #shift 2 bit left before write
+ * set val = wr_val + 0x00200000
+ * write dmem val 0
+ * read 0x00200000 val
+ * print val/8x
+ */
+ tmp_reg = in32(0x00200000);
+ val = wr_val + 0x00200000;
+ /* val = 0x0021c048; */
+ out32(val, 0x0000);
+ udelay(100000);
+ val = in32(0x00200000);
+
+ debug("CRAM VAL: %x for CS1 ", val);
+
+ /*
+ * # CS2
+ * read 0x02200000
+ * #shift 2 bit left before write
+ * set val = wr_val + 0x02200000
+ * write dmem val 0
+ * read 0x02200000 val
+ * print val/8x
+ */
+ tmp_reg = in32(0x02200000);
+ val = wr_val + 0x02200000;
+ /* val = 0x0221c048; */
+ out32(val, 0x0000);
+ udelay(100000);
+ val = in32(0x02200000);
+
+ debug("CRAM VAL: %x for CS2 ", val);
+
+ /*
+ * # Start PLL clock before programming CRAM
+ * set EPLD0_MUX_CTL.OESPR3 = 0
+ */
+
+ /*
+ * set CRAMCR = 0x1
+ */
+ gpio_reg = in32(GPIO1_OR);
+ out32(GPIO1_OR, gpio_reg | 0x00000400);
+
+ /*
+ * # read CRAM config BCR ( bit19:18 = 10b )
+ * #read 0x00200000
+ * # 1001_1001_0001_1111 ( 991f ) =>
+ * #10_0110_0100_0111_1100 => 2647c => 0022647c
+ * #0011_0010_0011_1110 (323e)
+ * #
+ */
+
+ /*
+ * set EPLD0_MUX_CTL.CRAMCR = 0x0
+ */
+ gpio_reg = in32(GPIO1_OR);
+ out32(GPIO1_OR, gpio_reg & 0xFFFFFBFF);
+ return;
+}
+
+static u32 is_cram_inited()
+{
+ volatile unsigned long spr_reg;
+
+ /*
+ * If CRAM is initialized already, then don't reinitialize it again.
+ * In the case of NAND boot and SPI boot, CRAM will already be
+ * initialized by the pre-loader
+ */
+ spr_reg = (volatile unsigned long) mfspr(SPRG7);
+ if (spr_reg == LOAK_CRAM) {
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+/******
+ * return 0 if not CRAM
+ * return 1 if CRAM and it's already inited by preloader
+ * else return cram_id (CRAM Device Identification Register)
+ ******/
+static u32 is_cram(void)
+{
+ u32 gpio_TCR, gpio_OSRL, gpio_OR, gpio_ISR1L;
+ volatile u32 gpio_reg;
+ volatile u32 cram_id = 0;
+
+ if (is_cram_inited() == 1) {
+ /* this is CRAM and it is already inited (by preloader) */
+ cram_id = 1;
+ } else {
+ /*
+ * # CRAM CLOCK
+ * set GPIO0_TCR.G8 = 1
+ * set GPIO0_OSRL.G8 = 0
+ * set GPIO0_OR.G8 = 0
+ */
+ gpio_reg = in32(GPIO0_TCR);
+ gpio_TCR = gpio_reg;
+ out32(GPIO0_TCR, gpio_reg | 0x00800000);
+ gpio_reg = in32(GPIO0_OSRL);
+ gpio_OSRL = gpio_reg;
+ out32(GPIO0_OSRL, gpio_reg & 0xffffbfff);
+ gpio_reg = in32(GPIO0_OR);
+ gpio_OR = gpio_reg;
+ out32(GPIO0_OR, gpio_reg & 0xff7fffff);
+
+ /*
+ * # CRAM Addreaa Valid
+ * set GPIO0_TCR.G10 = 1
+ * set GPIO0_OSRL.G10 = 0
+ * set GPIO0_OR.G10 = 0
+ */
+ gpio_reg = in32(GPIO0_TCR);
+ out32(GPIO0_TCR, gpio_reg | 0x00200000);
+ gpio_reg = in32(GPIO0_OSRL);
+ out32(GPIO0_OSRL, gpio_reg & 0xfffffbff);
+ gpio_reg = in32(GPIO0_OR);
+ out32(GPIO0_OR, gpio_reg & 0xffdfffff);
+
+ /*
+ * # config input (EBC_WAIT)
+ * set GPIO0_ISR1L.G9 = 1
+ * set GPIO0_TCR.G9 = 0
+ */
+ gpio_reg = in32(GPIO0_ISR1L);
+ gpio_ISR1L = gpio_reg;
+ out32(GPIO0_ISR1L, gpio_reg | 0x00001000);
+ gpio_reg = in32(GPIO0_TCR);
+ out32(GPIO0_TCR, gpio_reg & 0xffbfffff);
+
+ /*
+ * Enable CRE to read Registers
+ * set GPIO0_TCR.21 = 1
+ * set GPIO1_OR.21 = 1
+ */
+ gpio_reg = in32(GPIO1_TCR);
+ out32(GPIO1_TCR, gpio_reg | 0x00000400);
+
+ gpio_reg = in32(GPIO1_OR);
+ out32(GPIO1_OR, gpio_reg | 0x00000400);
+
+ /* Read Version ID */
+ cram_id = (volatile u32) in32(CRAM_BANK0_BASE+CRAM_DIDR);
+ udelay(100000);
+
+ asm volatile(" sync");
+ asm volatile(" eieio");
+
+ debug("Cram ID: %X ", cram_id);
+
+ switch (cram_id) {
+ case MICRON_MT45W8MW16BGX_CRAM_ID:
+ case MICRON_MT45W8MW16BGX_CRAM_ID2:
+ /* supported CRAM vendor/part */
+ break;
+ case CRAM_DEVID_NOT_SUPPORTED:
+ default:
+ /* check for DIDR Vendor ID of Micron */
+ if ((cram_id & CRAM_DIDR_VENDOR_ID_MASK) ==
+ MICRON_DIDR_VENDOR_ID)
+ {
+ /* supported CRAM vendor */
+ break;
+ }
+ /* this is not CRAM or not supported CRAM vendor/part */
+ cram_id = 0;
+ /*
+ * reset the GPIO registers to the values that were
+ * there before this routine
+ */
+ out32(GPIO0_TCR, gpio_TCR);
+ out32(GPIO0_OSRL, gpio_OSRL);
+ out32(GPIO0_OR, gpio_OR);
+ out32(GPIO0_ISR1L, gpio_ISR1L);
+ break;
+ }
+ }
+
+ return cram_id;
+}
+
+static long int cram_init(u32 already_inited)
+{
+ volatile u32 tmp_reg;
+ u32 cram_wr_val;
+
+ if (already_inited == 0) return 0;
+
+ /*
+ * If CRAM is initialized already, then don't reinitialize it again.
+ * In the case of NAND boot and SPI boot, CRAM will already be
+ * initialized by the pre-loader
+ */
+ if (already_inited != 1) {
+ /*
+ * #o CRAM Card
+ * # - CRAMCRE @reg16 = 1; for CRAM to use
+ * # - CRAMCRE @reg16 = 0; for CRAM to program
+ *
+ * # enable CRAM SEL, move from setEPLD.cmd
+ * set EPLD0_MUX_CTL.OECRAM = 0
+ * set EPLD0_MUX_CTL.CRAMCR = 1
+ * set EPLD0_ETHRSTBOOT.SLCRAM = 0
+ * #end
+ */
+
+ /*
+ * #1. EBC need to program READY, CLK, ADV for ASync mode
+ * # config output
+ */
+
+ /*
+ * # CRAM CLOCK
+ * set GPIO0_TCR.G8 = 1
+ * set GPIO0_OSRL.G8 = 0
+ * set GPIO0_OR.G8 = 0
+ */
+ tmp_reg = in32(GPIO0_TCR);
+ out32(GPIO0_TCR, tmp_reg | 0x00800000);
+ tmp_reg = in32(GPIO0_OSRL);
+ out32(GPIO0_OSRL, tmp_reg & 0xffffbfff);
+ tmp_reg = in32(GPIO0_OR);
+ out32(GPIO0_OR, tmp_reg & 0xff7fffff);
+
+ /*
+ * # CRAM Addreaa Valid
+ * set GPIO0_TCR.G10 = 1
+ * set GPIO0_OSRL.G10 = 0
+ * set GPIO0_OR.G10 = 0
+ */
+ tmp_reg = in32(GPIO0_TCR);
+ out32(GPIO0_TCR, tmp_reg | 0x00200000);
+ tmp_reg = in32(GPIO0_OSRL);
+ out32(GPIO0_OSRL, tmp_reg & 0xfffffbff);
+ tmp_reg = in32(GPIO0_OR);
+ out32(GPIO0_OR, tmp_reg & 0xffdfffff);
+
+ /*
+ * # config input (EBC_WAIT)
+ * set GPIO0_ISR1L.G9 = 1
+ * set GPIO0_TCR.G9 = 0
+ */
+ tmp_reg = in32(GPIO0_ISR1L);
+ out32(GPIO0_ISR1L, tmp_reg | 0x00001000);
+ tmp_reg = in32(GPIO0_TCR);
+ out32(GPIO0_TCR, tmp_reg & 0xffbfffff);
+
+ /*
+ * # config CS4 from GPIO
+ * set GPIO0_TCR.G0 = 1
+ * set GPIO0_OSRL.G0 = 1
+ */
+ tmp_reg = in32(GPIO0_TCR);
+ out32(GPIO0_TCR, tmp_reg | 0x80000000);
+ tmp_reg = in32(GPIO0_OSRL);
+ out32(GPIO0_OSRL, tmp_reg | 0x40000000);
+
+ /*
+ * #2. EBC in Async mode
+ * # set EBC0_PB1AP = 0x078f0ec0
+ * set EBC0_PB1AP = 0x078f1ec0
+ * set EBC0_PB2AP = 0x078f1ec0
+ */
+ mtebc(pb1ap, 0x078F1EC0);
+ mtebc(pb2ap, 0x078F1EC0);
+
+ /*
+ * #set EBC0_PB1CR = 0x000bc000
+ * #enable CS2 for CRAM
+ * set EBC0_PB2CR = 0x020bc000
+ */
+ mtebc(pb1cr, 0x000BC000);
+ mtebc(pb2cr, 0x020BC000);
+
+ /*
+ * #3. set CRAM in Sync mode
+ * #exec cm_bcr_write.cmd { 0x701f }
+ * #3. set CRAM in Sync mode (full drv strength)
+ * exec cm_bcr_write.cmd { 0x701F }
+ */
+ cram_wr_val = 0x7012; /* CRAM burst setting */
+ cram_bcr_write(cram_wr_val);
+
+ /*
+ * #4. EBC in Sync mode
+ * #set EBC0_PB1AP = 0x9f800fc0
+ * #set EBC0_PB1AP = 0x900001c0
+ * set EBC0_PB2AP = 0x9C0201c0
+ * set EBC0_PB2AP = 0x9C0201c0
+ */
+ mtebc(pb1ap, 0x9C0201C0);
+ mtebc(pb2ap, 0x9C0201C0);
+
+ /*
+ * #5. EBC need to program READY, CLK, ADV for Sync mode
+ * # config output
+ * set GPIO0_TCR.G8 = 1
+ * set GPIO0_OSRL.G8 = 1
+ * set GPIO0_TCR.G10 = 1
+ * set GPIO0_OSRL.G10 = 1
+ */
+ tmp_reg = in32(GPIO0_TCR);
+ out32(GPIO0_TCR, tmp_reg | 0x00800000);
+ tmp_reg = in32(GPIO0_OSRL);
+ out32(GPIO0_OSRL, tmp_reg | 0x00004000);
+ tmp_reg = in32(GPIO0_TCR);
+ out32(GPIO0_TCR, tmp_reg | 0x00200000);
+ tmp_reg = in32(GPIO0_OSRL);
+ out32(GPIO0_OSRL, tmp_reg | 0x00000400);
+
+ /*
+ * # config input
+ * set GPIO0_ISR1L.G9 = 1
+ * set GPIO0_TCR.G9 = 0
+ */
+ tmp_reg = in32(GPIO0_ISR1L);
+ out32(GPIO0_ISR1L, tmp_reg | 0x00001000);
+ tmp_reg = in32(GPIO0_TCR);
+ out32(GPIO0_TCR, tmp_reg & 0xffbfffff);
+
+ /*
+ * # config EBC to use RDY
+ * set SDR0_ULTRA0.EBCREN = 1
+ */
+ mfsdr(sdrultra0, tmp_reg);
+ mtsdr(sdrultra0, tmp_reg | 0x04000000);
+
+ /*
+ * set EPLD0_MUX_CTL.OESPR3 = 0
+ */
+ mtspr(SPRG7, LOAK_CRAM); /* "CRAM" */
+ } /* if (already_inited != 1) */
+
+ return (64 * 1024 * 1024);
+}
+
+/******
+ * return 0 if not PSRAM
+ * return 1 if is PSRAM
+ ******/
+static int is_psram(u32 addr)
+{
+ u32 test_pattern = 0xdeadbeef;
+ volatile u32 readback;
+
+ if (addr == CFG_SDRAM_BASE) {
+ /* This is to temp enable OE for PSRAM */
+ out16(EPLD_BASE+EPLD_MUXOE, 0x7f0f);
+ udelay(10000);
+ }
+
+ out32(addr, test_pattern);
+ asm volatile(" sync");
+ asm volatile(" eieio");
+
+ readback = (volatile u32) in32(addr);
+ asm volatile(" sync");
+ asm volatile(" eieio");
+ if (readback == test_pattern) {
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+static long int psram_init(void)
+{
+ u32 readback;
+ long psramsize = 0;
+ int i;
+
+ /* This is to temp enable OE for PSRAM */
+ out16(EPLD_BASE+EPLD_MUXOE, 0x7f0f);
+ udelay(10000);
+
+ /*
+ * PSRAM bank 1: read then write to address 0x00000000
+ */
+ for (i = 0; i < 100; i++) {
+ if (is_psram(CFG_SDRAM_BASE + (i*256)) == 1) {
+ readback = PSRAM_PASS;
+ } else {
+ readback = PSRAM_FAIL;
+ break;
+ }
+ }
+ if (readback == PSRAM_PASS) {
+ debug("psram_init(bank0): pass\n");
+ psramsize = (16 * 1024 * 1024);
+ } else {
+ debug("psram_init(bank0): fail\n");
+ return 0;
+ }
+
+#if 0
+ /*
+ * PSRAM bank 1: read then write to address 0x01000000
+ */
+ for (i = 0; i < 100; i++) {
+ if (is_psram((1 << 24) + (i*256)) == 1) {
+ readback = PSRAM_PASS;
+ } else {
+ readback = PSRAM_FAIL;
+ break;
+ }
+ }
+ if (readback == PSRAM_PASS) {
+ debug("psram_init(bank1): pass\n");
+ psramsize = psramsize + (16 * 1024 * 1024);
+ }
+#endif
+
+ mtspr(SPRG7, LOAK_PSRAM); /* "PSRA" - PSRAM */
+
+ return psramsize;
+}
+
+long int initdram(int board_type)
+{
+ long int sram_size;
+ u32 cram_inited;
+
+ /* Determine Attached Memory Expansion Card*/
+ cram_inited = is_cram();
+ if (cram_inited != 0) { /* CRAM */
+ debug("CRAM Expansion Card attached\n");
+ sram_size = cram_init(cram_inited);
+ } else if (is_psram(CFG_SDRAM_BASE+4) == 1) { /* PSRAM */
+ debug("PSRAM Expansion Card attached\n");
+ sram_size = psram_init();
+ } else { /* no SRAM */
+ debug("No Memory Card Attached!!\n");
+ sram_size = 0;
+ }
+
+ return sram_size;
+}
+
+int testdram(void)
+{
+ return (0);
+}
diff --git a/board/amcc/acadia/u-boot.lds b/board/amcc/acadia/u-boot.lds
new file mode 100644
index 00000000000..be030923b8e
--- /dev/null
+++ b/board/amcc/acadia/u-boot.lds
@@ -0,0 +1,150 @@
+/*
+ * (C) Copyright 2000
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+OUTPUT_ARCH(powerpc)
+SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/local/powerpc-any-elf/lib);
+/* Do we need any of these for elf?
+ __DYNAMIC = 0; */
+SECTIONS
+{
+ .resetvec 0xFFFFFFFC :
+ {
+ *(.resetvec)
+ } = 0xffff
+
+ /* Read-only sections, merged into text segment: */
+ . = + SIZEOF_HEADERS;
+ .interp : { *(.interp) }
+ .hash : { *(.hash) }
+ .dynsym : { *(.dynsym) }
+ .dynstr : { *(.dynstr) }
+ .rel.text : { *(.rel.text) }
+ .rela.text : { *(.rela.text) }
+ .rel.data : { *(.rel.data) }
+ .rela.data : { *(.rela.data) }
+ .rel.rodata : { *(.rel.rodata) }
+ .rela.rodata : { *(.rela.rodata) }
+ .rel.got : { *(.rel.got) }
+ .rela.got : { *(.rela.got) }
+ .rel.ctors : { *(.rel.ctors) }
+ .rela.ctors : { *(.rela.ctors) }
+ .rel.dtors : { *(.rel.dtors) }
+ .rela.dtors : { *(.rela.dtors) }
+ .rel.bss : { *(.rel.bss) }
+ .rela.bss : { *(.rela.bss) }
+ .rel.plt : { *(.rel.plt) }
+ .rela.plt : { *(.rela.plt) }
+ .init : { *(.init) }
+ .plt : { *(.plt) }
+ .text :
+ {
+ /* WARNING - the following is hand-optimized to fit within */
+ /* the sector layout of our flash chips! XXX FIXME XXX */
+
+ cpu/ppc4xx/start.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)*/
+
+ *(.text)
+ *(.fixup)
+ *(.got1)
+ }
+ _etext = .;
+ PROVIDE (etext = .);
+ .rodata :
+ {
+ *(.rodata)
+ *(.rodata1)
+ *(.rodata.str1.4)
+ *(.eh_frame)
+ }
+ .fini : { *(.fini) } =0
+ .ctors : { *(.ctors) }
+ .dtors : { *(.dtors) }
+
+ /* Read-write section, merged into data segment: */
+ . = (. + 0x00FF) & 0xFFFFFF00;
+ _erotext = .;
+ PROVIDE (erotext = .);
+ .reloc :
+ {
+ *(.got)
+ _GOT2_TABLE_ = .;
+ *(.got2)
+ _FIXUP_TABLE_ = .;
+ *(.fixup)
+ }
+ __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2;
+ __fixup_entries = (. - _FIXUP_TABLE_)>>2;
+
+ .data :
+ {
+ *(.data)
+ *(.data1)
+ *(.sdata)
+ *(.sdata2)
+ *(.dynamic)
+ CONSTRUCTORS
+ }
+ _edata = .;
+ PROVIDE (edata = .);
+
+ . = .;
+ __u_boot_cmd_start = .;
+ .u_boot_cmd : { *(.u_boot_cmd) }
+ __u_boot_cmd_end = .;
+
+ . = .;
+ __start___ex_table = .;
+ __ex_table : { *(__ex_table) }
+ __stop___ex_table = .;
+
+ . = ALIGN(256);
+ __init_begin = .;
+ .text.init : { *(.text.init) }
+ .data.init : { *(.data.init) }
+ . = ALIGN(256);
+ __init_end = .;
+
+ __bss_start = .;
+ .bss :
+ {
+ *(.sbss) *(.scommon)
+ *(.dynbss)
+ *(.bss)
+ *(COMMON)
+ }
+ _end = . ;
+ PROVIDE (end = .);
+}
diff --git a/board/amcc/ebony/init.S b/board/amcc/ebony/init.S
index cc8f8b444e0..c86076e8069 100644
--- a/board/amcc/ebony/init.S
+++ b/board/amcc/ebony/init.S
@@ -22,53 +22,7 @@
#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_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)
-
+#include <asm-ppc/mmu.h>
/**************************************************************************
* TLB TABLE
@@ -81,16 +35,23 @@
*
*************************************************************************/
- .section .bootpg,"ax"
- .globl tlbtab
+ .section .bootpg,"ax"
+ .globl tlbtab
tlbtab:
- tlbtab_start
- tlbentry( 0xf0000000, SZ_256M, 0xf0000000, 1, AC_R|AC_W|AC_X|SA_G|SA_I)
- tlbentry( CFG_PERIPHERAL_BASE, SZ_256M, 0x40000000, 1, AC_R|AC_W|SA_G|SA_I)
- tlbentry( CFG_ISRAM_BASE, SZ_4K, 0x80000000, 0, AC_R|AC_W|AC_X )
- tlbentry( CFG_ISRAM_BASE + 0x1000, SZ_4K, 0x80001000, 0, AC_R|AC_W|AC_X )
- tlbentry( CFG_SDRAM_BASE, SZ_256M, 0x00000000, 0, AC_R|AC_W|AC_X|SA_G|SA_I )
- tlbentry( CFG_PCI_BASE, SZ_256M, 0x00000000, 2, AC_R|AC_W|SA_G|SA_I )
- tlbentry( CFG_PCI_MEMBASE, SZ_256M, 0x00000000, 3, AC_R|AC_W|SA_G|SA_I )
- tlbtab_end
+ tlbtab_start
+
+ tlbentry(0xf0000000, SZ_256M, 0xf0000000, 1, AC_R|AC_W|AC_X|SA_G|SA_I)
+
+ /*
+ * TLB entries for SDRAM are not needed on this platform.
+ * They are dynamically generated in the SPD DDR(2) detection
+ * routine.
+ */
+
+ tlbentry(CFG_PERIPHERAL_BASE, SZ_256M, 0x40000000, 1, AC_R|AC_W|SA_G|SA_I)
+ tlbentry(CFG_ISRAM_BASE, SZ_4K, 0x80000000, 0, AC_R|AC_W|AC_X)
+ tlbentry(CFG_ISRAM_BASE + 0x1000, SZ_4K, 0x80001000, 0, AC_R|AC_W|AC_X)
+ tlbentry(CFG_PCI_BASE, SZ_256M, 0x00000000, 2, AC_R|AC_W|SA_G|SA_I)
+ tlbentry(CFG_PCI_MEMBASE, SZ_256M, 0x00000000, 3, AC_R|AC_W|SA_G|SA_I)
+ tlbtab_end
diff --git a/board/amcc/katmai/Makefile b/board/amcc/katmai/Makefile
new file mode 100644
index 00000000000..d06a402d175
--- /dev/null
+++ b/board/amcc/katmai/Makefile
@@ -0,0 +1,51 @@
+#
+# (C) Copyright 2007
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+include $(TOPDIR)/config.mk
+
+LIB = $(obj)lib$(BOARD).a
+
+COBJS = $(BOARD).o cmd_katmai.o
+SOBJS = init.o
+
+SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(COBJS))
+SOBJS := $(addprefix $(obj),$(SOBJS))
+
+$(LIB): $(obj).depend $(OBJS) $(SOBJS)
+ $(AR) $(ARFLAGS) $@ $(OBJS)
+
+clean:
+ rm -f $(SOBJS) $(OBJS)
+
+distclean: clean
+ rm -f $(LIB) core *.bak .depend *~
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/board/amcc/katmai/cmd_katmai.c b/board/amcc/katmai/cmd_katmai.c
new file mode 100644
index 00000000000..684f6a58637
--- /dev/null
+++ b/board/amcc/katmai/cmd_katmai.c
@@ -0,0 +1,267 @@
+/*
+ * (C) Copyright 2007
+ * Stefan Roese, DENX Software Engineering, sr@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ */
+
+#include <common.h>
+#include <command.h>
+#include <i2c.h>
+#include <asm/byteorder.h>
+
+static int do_bootstrap(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+ uchar chip;
+ ulong data;
+ int nbytes;
+ extern char console_buffer[];
+
+ char sysClock[4];
+ char cpuClock[4];
+ char plbClock[4];
+ char pcixClock[4];
+
+ if (argc < 3) {
+ printf ("Usage:\n%s\n", cmdtp->usage);
+ return 1;
+ }
+
+ if (strcmp(argv[2], "prom0") == 0)
+ chip = IIC0_BOOTPROM_ADDR;
+ else
+ chip = IIC0_ALT_BOOTPROM_ADDR;
+
+ do {
+ printf("enter sys clock frequency 33 or 66 Mhz or quit to abort\n");
+ nbytes = readline (" ? ");
+
+ if (strcmp(console_buffer, "quit") == 0)
+ return 0;
+
+ if ((strcmp(console_buffer, "33") != 0) &
+ (strcmp(console_buffer, "66") != 0))
+ nbytes=0;
+
+ strcpy(sysClock, console_buffer);
+
+ } while (nbytes == 0);
+
+ do {
+ if (strcmp(sysClock, "66") == 0) {
+ printf("enter cpu clock frequency 400, 533 Mhz or quit to abort\n");
+ } else {
+#ifdef CONFIG_STRESS
+ printf("enter cpu clock frequency 400, 500, 533, 667 Mhz or quit to abort\n");
+#else
+ printf("enter cpu clock frequency 400, 500, 533 Mhz or quit to abort\n");
+#endif
+ }
+ nbytes = readline (" ? ");
+
+ if (strcmp(console_buffer, "quit") == 0)
+ return 0;
+
+ if (strcmp(sysClock, "66") == 0) {
+ if ((strcmp(console_buffer, "400") != 0) &
+ (strcmp(console_buffer, "533") != 0)
+#ifdef CONFIG_STRESS
+ & (strcmp(console_buffer, "667") != 0)
+#endif
+ ) {
+ nbytes = 0;
+ }
+ } else {
+ if ((strcmp(console_buffer, "400") != 0) &
+ (strcmp(console_buffer, "500") != 0) &
+ (strcmp(console_buffer, "533") != 0)
+#ifdef CONFIG_STRESS
+ & (strcmp(console_buffer, "667") != 0)
+#endif
+ ) {
+ nbytes = 0;
+ }
+ }
+
+ strcpy(cpuClock, console_buffer);
+
+ } while (nbytes == 0);
+
+ if (strcmp(cpuClock, "500") == 0)
+ strcpy(plbClock, "166");
+ else if (strcmp(cpuClock, "533") == 0)
+ strcpy(plbClock, "133");
+ else {
+ do {
+ if (strcmp(cpuClock, "400") == 0)
+ printf("enter plb clock frequency 100, 133 Mhz or quit to abort\n");
+
+#ifdef CONFIG_STRESS
+ if (strcmp(cpuClock, "667") == 0)
+ printf("enter plb clock frequency 133, 166 Mhz or quit to abort\n");
+
+#endif
+ nbytes = readline (" ? ");
+
+ if (strcmp(console_buffer, "quit") == 0)
+ return 0;
+
+ if (strcmp(cpuClock, "400") == 0) {
+ if ((strcmp(console_buffer, "100") != 0) &
+ (strcmp(console_buffer, "133") != 0))
+ nbytes = 0;
+ }
+#ifdef CONFIG_STRESS
+ if (strcmp(cpuClock, "667") == 0) {
+ if ((strcmp(console_buffer, "133") != 0) &
+ (strcmp(console_buffer, "166") != 0))
+ nbytes = 0;
+ }
+#endif
+ strcpy(plbClock, console_buffer);
+
+ } while (nbytes == 0);
+ }
+
+ do {
+ printf("enter Pci-X clock frequency 33, 66, 100 or 133 Mhz or quit to abort\n");
+ nbytes = readline (" ? ");
+
+ if (strcmp(console_buffer, "quit") == 0)
+ return 0;
+
+ if ((strcmp(console_buffer, "33") != 0) &
+ (strcmp(console_buffer, "66") != 0) &
+ (strcmp(console_buffer, "100") != 0) &
+ (strcmp(console_buffer, "133") != 0)) {
+ nbytes = 0;
+ }
+ strcpy(pcixClock, console_buffer);
+
+ } while (nbytes == 0);
+
+ printf("\nsys clk = %sMhz\n", sysClock);
+ printf("cpu clk = %sMhz\n", cpuClock);
+ printf("plb clk = %sMhz\n", plbClock);
+ printf("Pci-X clk = %sMhz\n", pcixClock);
+
+ do {
+ printf("\npress [y] to write I2C bootstrap \n");
+ printf("or [n] to abort. \n");
+ printf("Don't forget to set board switches \n");
+ printf("according to your choice before re-starting \n");
+ printf("(refer to 440spe_uboot_kit_um_1_01.pdf) \n");
+
+ nbytes = readline (" ? ");
+ if (strcmp(console_buffer, "n") == 0)
+ return 0;
+
+ } while (nbytes == 0);
+
+ if (strcmp(sysClock, "33") == 0) {
+ if ((strcmp(cpuClock, "400") == 0) &
+ (strcmp(plbClock, "100") == 0))
+ data = 0x8678c206;
+
+ if ((strcmp(cpuClock, "400") == 0) &
+ (strcmp(plbClock, "133") == 0))
+ data = 0x8678c2c6;
+
+ if ((strcmp(cpuClock, "500") == 0))
+ data = 0x8778f2c6;
+
+ if ((strcmp(cpuClock, "533") == 0))
+ data = 0x87790252;
+
+#ifdef CONFIG_STRESS
+ if ((strcmp(cpuClock, "667") == 0) &
+ (strcmp(plbClock, "133") == 0))
+ data = 0x87794256;
+
+ if ((strcmp(cpuClock, "667") == 0) &
+ (strcmp(plbClock, "166") == 0))
+ data = 0x87794206;
+
+#endif
+ }
+ if (strcmp(sysClock, "66") == 0) {
+ if ((strcmp(cpuClock, "400") == 0) &
+ (strcmp(plbClock, "100") == 0))
+ data = 0x84706206;
+
+ if ((strcmp(cpuClock, "400") == 0) &
+ (strcmp(plbClock, "133") == 0))
+ data = 0x847062c6;
+
+ if ((strcmp(cpuClock, "533") == 0))
+ data = 0x85708206;
+
+#ifdef CONFIG_STRESS
+ if ((strcmp(cpuClock, "667") == 0) &
+ (strcmp(plbClock, "133") == 0))
+ data = 0x8570a256;
+
+ if ((strcmp(cpuClock, "667") == 0) &
+ (strcmp(plbClock, "166") == 0))
+ data = 0x8570a206;
+
+#endif
+ }
+
+#ifdef DEBUG
+ printf(" pin strap0 to write in i2c = %x\n", data);
+#endif /* DEBUG */
+
+ if (i2c_write(chip, 0, 1, (uchar *)&data, 4) != 0)
+ printf("Error writing strap0 in %s\n", argv[2]);
+
+ if (strcmp(pcixClock, "33") == 0)
+ data = 0x00000701;
+
+ if (strcmp(pcixClock, "66") == 0)
+ data = 0x00000601;
+
+ if (strcmp(pcixClock, "100") == 0)
+ data = 0x00000501;
+
+ if (strcmp(pcixClock, "133") == 0)
+ data = 0x00000401;
+
+ if (strcmp(plbClock, "166") == 0)
+ data |= 0x05950000;
+ else
+ data |= 0x05A50000;
+
+#ifdef DEBUG
+ printf(" pin strap1 to write in i2c = %x\n", data);
+#endif /* DEBUG */
+
+ udelay(1000);
+ if (i2c_write(chip, 4, 1, (uchar *)&data, 4) != 0)
+ printf("Error writing strap1 in %s\n", argv[2]);
+
+ return 0;
+}
+
+U_BOOT_CMD(
+ bootstrap, 3, 1, do_bootstrap,
+ "bootstrap - program the serial device strap\n",
+ "wrclk [prom0|prom1] - program the serial device strap\n"
+ );
diff --git a/board/amcc/katmai/config.mk b/board/amcc/katmai/config.mk
new file mode 100644
index 00000000000..115c1aed053
--- /dev/null
+++ b/board/amcc/katmai/config.mk
@@ -0,0 +1,38 @@
+#
+# (C) Copyright 2006
+# 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
+#
+
+#
+# AMCC 440SPe Evaluation (Katmai) board
+#
+
+TEXT_BASE = 0xfffc0000
+
+PLATFORM_CPPFLAGS += -DCONFIG_440=1
+
+ifeq ($(debug),1)
+PLATFORM_CPPFLAGS += -DDEBUG
+endif
+
+ifeq ($(dbcr),1)
+PLATFORM_CPPFLAGS += -DCFG_INIT_DBCR=0x8cff0000
+endif
diff --git a/board/amcc/katmai/init.S b/board/amcc/katmai/init.S
new file mode 100644
index 00000000000..6b024eec40c
--- /dev/null
+++ b/board/amcc/katmai/init.S
@@ -0,0 +1,118 @@
+/*
+ * (C) Copyright 2007
+ * Stefan Roese, DENX Software Engineering, sr@denx.de.
+ *
+ * Copyright (C) 2002 Scott McNutt <smcnutt@artesyncp.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <ppc_asm.tmpl>
+#include <config.h>
+#include <asm-ppc/mmu.h>
+
+/**************************************************************************
+ * 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"
+
+/**************************************************************************
+ * TLB table for revA
+ *************************************************************************/
+ .globl tlbtabA
+tlbtabA:
+ 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(0xff000000, SZ_16M, 0xff000000, 4, AC_R|AC_W|AC_X|SA_G)
+
+ /*
+ * TLB entries for SDRAM are not needed on this platform.
+ * They are dynamically generated in the SPD DDR(2) detection
+ * routine.
+ */
+
+ tlbentry(CFG_ISRAM_BASE, SZ_256K, 0x00000000, 4, AC_R|AC_W|AC_X|SA_I)
+ tlbentry(CFG_PERIPHERAL_BASE, SZ_4K, 0xF0000000, 4, AC_R|AC_W|SA_G|SA_I)
+
+ tlbentry(CFG_PCI_BASE, SZ_256M, 0x00000000, 0xC, AC_R|AC_W|SA_G|SA_I)
+ tlbentry(CFG_PCI_MEMBASE, SZ_256M, 0x10000000, 0xC, AC_R|AC_W|SA_G|SA_I)
+ tlbentry(CFG_PCIE_MEMBASE, SZ_256M, 0xB0000000, 0xD, AC_R|AC_W|SA_G|SA_I)
+ tlbentry(CFG_PCIE_BASE, SZ_16K, 0x20000000, 0xC, AC_R|AC_W|SA_G|SA_I)
+
+ tlbentry(CFG_PCIE0_CFGBASE, SZ_1K, 0x40000000, 0xC, AC_R|AC_W|SA_G|SA_I)
+ tlbentry(CFG_PCIE1_CFGBASE, SZ_1K, 0x80000000, 0xC, AC_R|AC_W|SA_G|SA_I)
+ tlbentry(CFG_PCIE2_CFGBASE, SZ_1K, 0xC0000000, 0xC, AC_R|AC_W|SA_G|SA_I)
+ tlbentry(CFG_PCIE0_XCFGBASE, SZ_1K, 0x50000000, 0xC, AC_R|AC_W|SA_G|SA_I)
+ tlbentry(CFG_PCIE1_XCFGBASE, SZ_1K, 0x90000000, 0xC, AC_R|AC_W|SA_G|SA_I)
+ tlbentry(CFG_PCIE2_XCFGBASE, SZ_1K, 0xD0000000, 0xC, AC_R|AC_W|SA_G|SA_I)
+ tlbtab_end
+
+/**************************************************************************
+ * TLB table for revB
+ *
+ * Notice: revB of the 440SPe chip is very strict about PLB real addresses
+ * and ranges to be mapped for config space: it seems to only work with
+ * d_nnnn_nnnn range (hangs the core upon config transaction attempts when
+ * set otherwise) while revA uses c_nnnn_nnnn.
+ *************************************************************************/
+ .globl tlbtabB
+tlbtabB:
+ 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(0xff000000, SZ_16M, 0xff000000, 4, AC_R|AC_W|AC_X|SA_G)
+
+ /*
+ * TLB entries for SDRAM are not needed on this platform.
+ * They are dynamically generated in the SPD DDR(2) detection
+ * routine.
+ */
+
+ tlbentry(CFG_ISRAM_BASE, SZ_256K, 0x00000000, 4, AC_R|AC_W|AC_X|SA_I)
+
+ tlbentry(CFG_PERIPHERAL_BASE, SZ_4K, 0xF0000000, 4, AC_R|AC_W|SA_G|SA_I)
+
+ tlbentry(CFG_ACE_BASE, SZ_1K, 0xE0000000, 4,AC_R|AC_W|SA_G|SA_I)
+
+ tlbentry(CFG_PCI_BASE, SZ_256M, 0x00000000, 0xC, AC_R|AC_W|SA_G|SA_I)
+ tlbentry(CFG_PCI_MEMBASE, SZ_256M, 0x10000000, 0xC, AC_R|AC_W|SA_G|SA_I)
+ tlbentry(CFG_PCIE_MEMBASE, SZ_256M, 0xB0000000, 0xD, AC_R|AC_W|SA_G|SA_I)
+
+ tlbentry(CFG_PCIE0_CFGBASE, SZ_1K, 0x00100000, 0xD, AC_R|AC_W|SA_G|SA_I)
+ tlbentry(CFG_PCIE1_CFGBASE, SZ_1K, 0x20100000, 0xD, AC_R|AC_W|SA_G|SA_I)
+ tlbentry(CFG_PCIE2_CFGBASE, SZ_1K, 0x40100000, 0xD, AC_R|AC_W|SA_G|SA_I)
+ tlbentry(CFG_PCIE0_XCFGBASE, SZ_1K, 0x10000000, 0xD, AC_R|AC_W|SA_G|SA_I)
+ tlbentry(CFG_PCIE1_XCFGBASE, SZ_1K, 0x30000000, 0xD, AC_R|AC_W|SA_G|SA_I)
+ tlbentry(CFG_PCIE2_XCFGBASE, SZ_1K, 0x50000000, 0xD, AC_R|AC_W|SA_G|SA_I)
+ tlbtab_end
diff --git a/board/amcc/katmai/katmai.c b/board/amcc/katmai/katmai.c
new file mode 100644
index 00000000000..fbf1a98ab3d
--- /dev/null
+++ b/board/amcc/katmai/katmai.c
@@ -0,0 +1,529 @@
+/*
+ * (C) Copyright 2007
+ * Stefan Roese, DENX Software Engineering, sr@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ */
+
+#include <common.h>
+#include <ppc4xx.h>
+#include <asm/processor.h>
+#include <i2c.h>
+#include <asm-ppc/io.h>
+
+#include "../cpu/ppc4xx/440spe_pcie.h"
+
+#undef PCIE_ENDPOINT
+/* #define PCIE_ENDPOINT 1 */
+
+int ppc440spe_init_pcie_rootport(int port);
+void ppc440spe_setup_pcie(struct pci_controller *hose, int port);
+
+int board_early_init_f (void)
+{
+ unsigned long mfr;
+
+ /*----------------------------------------------------------------------+
+ * Interrupt controller setup for the Katmai 440SPe Evaluation board.
+ *-----------------------------------------------------------------------+
+ *-----------------------------------------------------------------------+
+ * Interrupt | Source | Pol. | Sensi.| Crit. |
+ *-----------+-----------------------------------+-------+-------+-------+
+ * IRQ 00 | UART0 | High | Level | Non |
+ * IRQ 01 | UART1 | High | Level | Non |
+ * IRQ 02 | IIC0 | High | Level | Non |
+ * IRQ 03 | IIC1 | High | Level | Non |
+ * IRQ 04 | PCI0X0 MSG IN | High | Level | Non |
+ * IRQ 05 | PCI0X0 CMD Write | High | Level | Non |
+ * IRQ 06 | PCI0X0 Power Mgt | High | Level | Non |
+ * IRQ 07 | PCI0X0 VPD Access | Rising| Edge | Non |
+ * IRQ 08 | PCI0X0 MSI level 0 | High | Lvl/ed| Non |
+ * IRQ 09 | External IRQ 15 - (PCI-Express) | pgm H | Pgm | Non |
+ * IRQ 10 | UIC2 Non-critical Int. | NA | NA | Non |
+ * IRQ 11 | UIC2 Critical Interrupt | NA | NA | Crit |
+ * IRQ 12 | PCI Express MSI Level 0 | Rising| Edge | Non |
+ * IRQ 13 | PCI Express MSI Level 1 | Rising| Edge | Non |
+ * IRQ 14 | PCI Express MSI Level 2 | Rising| Edge | Non |
+ * IRQ 15 | PCI Express MSI Level 3 | Rising| Edge | Non |
+ * IRQ 16 | UIC3 Non-critical Int. | NA | NA | Non |
+ * IRQ 17 | UIC3 Critical Interrupt | NA | NA | Crit |
+ * IRQ 18 | External IRQ 14 - (PCI-Express) | Pgm | Pgm | Non |
+ * IRQ 19 | DMA Channel 0 FIFO Full | High | Level | Non |
+ * IRQ 20 | DMA Channel 0 Stat FIFO | High | Level | Non |
+ * IRQ 21 | DMA Channel 1 FIFO Full | High | Level | Non |
+ * IRQ 22 | DMA Channel 1 Stat FIFO | High | Level | Non |
+ * IRQ 23 | I2O Inbound Doorbell | High | Level | Non |
+ * IRQ 24 | Inbound Post List FIFO Not Empt | High | Level | Non |
+ * IRQ 25 | I2O Region 0 LL PLB Write | High | Level | Non |
+ * IRQ 26 | I2O Region 1 LL PLB Write | High | Level | Non |
+ * IRQ 27 | I2O Region 0 HB PLB Write | High | Level | Non |
+ * IRQ 28 | I2O Region 1 HB PLB Write | High | Level | Non |
+ * IRQ 29 | GPT Down Count Timer | Rising| Edge | Non |
+ * IRQ 30 | UIC1 Non-critical Int. | NA | NA | Non |
+ * IRQ 31 | UIC1 Critical Interrupt | NA | NA | Crit. |
+ *------------------------------------------------------------------------
+ * IRQ 32 | Ext. IRQ 13 - (PCI-Express) |pgm (H)|pgm/Lvl| Non |
+ * IRQ 33 | MAL Serr | High | Level | Non |
+ * IRQ 34 | MAL Txde | High | Level | Non |
+ * IRQ 35 | MAL Rxde | High | Level | Non |
+ * IRQ 36 | DMC CE or DMC UE | High | Level | Non |
+ * IRQ 37 | EBC or UART2 | High |Lvl Edg| Non |
+ * IRQ 38 | MAL TX EOB | High | Level | Non |
+ * IRQ 39 | MAL RX EOB | High | Level | Non |
+ * IRQ 40 | PCIX0 MSI Level 1 | High |Lvl Edg| Non |
+ * IRQ 41 | PCIX0 MSI level 2 | High |Lvl Edg| Non |
+ * IRQ 42 | PCIX0 MSI level 3 | High |Lvl Edg| Non |
+ * IRQ 43 | L2 Cache | Risin | Edge | Non |
+ * IRQ 44 | GPT Compare Timer 0 | Risin | Edge | Non |
+ * IRQ 45 | GPT Compare Timer 1 | Risin | Edge | Non |
+ * IRQ 46 | GPT Compare Timer 2 | Risin | Edge | Non |
+ * IRQ 47 | GPT Compare Timer 3 | Risin | Edge | Non |
+ * IRQ 48 | GPT Compare Timer 4 | Risin | Edge | Non |
+ * IRQ 49 | Ext. IRQ 12 - PCI-X |pgm/Fal|pgm/Lvl| Non |
+ * IRQ 50 | Ext. IRQ 11 - |pgm (H)|pgm/Lvl| Non |
+ * IRQ 51 | Ext. IRQ 10 - |pgm (H)|pgm/Lvl| Non |
+ * IRQ 52 | Ext. IRQ 9 |pgm (H)|pgm/Lvl| Non |
+ * IRQ 53 | Ext. IRQ 8 |pgm (H)|pgm/Lvl| Non |
+ * IRQ 54 | DMA Error | High | Level | Non |
+ * IRQ 55 | DMA I2O Error | High | Level | Non |
+ * IRQ 56 | Serial ROM | High | Level | Non |
+ * IRQ 57 | PCIX0 Error | High | Edge | Non |
+ * IRQ 58 | Ext. IRQ 7- |pgm (H)|pgm/Lvl| Non |
+ * IRQ 59 | Ext. IRQ 6- |pgm (H)|pgm/Lvl| Non |
+ * IRQ 60 | EMAC0 Interrupt | High | Level | Non |
+ * IRQ 61 | EMAC0 Wake-up | High | Level | Non |
+ * IRQ 62 | Reserved | High | Level | Non |
+ * IRQ 63 | XOR | High | Level | Non |
+ *-----------------------------------------------------------------------
+ * IRQ 64 | PE0 AL | High | Level | Non |
+ * IRQ 65 | PE0 VPD Access | Risin | Edge | Non |
+ * IRQ 66 | PE0 Hot Reset Request | Risin | Edge | Non |
+ * IRQ 67 | PE0 Hot Reset Request | Falli | Edge | Non |
+ * IRQ 68 | PE0 TCR | High | Level | Non |
+ * IRQ 69 | PE0 BusMaster VCO | Falli | Edge | Non |
+ * IRQ 70 | PE0 DCR Error | High | Level | Non |
+ * IRQ 71 | Reserved | N/A | N/A | Non |
+ * IRQ 72 | PE1 AL | High | Level | Non |
+ * IRQ 73 | PE1 VPD Access | Risin | Edge | Non |
+ * IRQ 74 | PE1 Hot Reset Request | Risin | Edge | Non |
+ * IRQ 75 | PE1 Hot Reset Request | Falli | Edge | Non |
+ * IRQ 76 | PE1 TCR | High | Level | Non |
+ * IRQ 77 | PE1 BusMaster VCO | Falli | Edge | Non |
+ * IRQ 78 | PE1 DCR Error | High | Level | Non |
+ * IRQ 79 | Reserved | N/A | N/A | Non |
+ * IRQ 80 | PE2 AL | High | Level | Non |
+ * IRQ 81 | PE2 VPD Access | Risin | Edge | Non |
+ * IRQ 82 | PE2 Hot Reset Request | Risin | Edge | Non |
+ * IRQ 83 | PE2 Hot Reset Request | Falli | Edge | Non |
+ * IRQ 84 | PE2 TCR | High | Level | Non |
+ * IRQ 85 | PE2 BusMaster VCO | Falli | Edge | Non |
+ * IRQ 86 | PE2 DCR Error | High | Level | Non |
+ * IRQ 87 | Reserved | N/A | N/A | Non |
+ * IRQ 88 | External IRQ(5) | Progr | Progr | Non |
+ * IRQ 89 | External IRQ 4 - Ethernet | Progr | Progr | Non |
+ * IRQ 90 | External IRQ 3 - PCI-X | Progr | Progr | Non |
+ * IRQ 91 | External IRQ 2 - PCI-X | Progr | Progr | Non |
+ * IRQ 92 | External IRQ 1 - PCI-X | Progr | Progr | Non |
+ * IRQ 93 | External IRQ 0 - PCI-X | Progr | Progr | Non |
+ * IRQ 94 | Reserved | N/A | N/A | Non |
+ * IRQ 95 | Reserved | N/A | N/A | Non |
+ *-----------------------------------------------------------------------
+ * IRQ 96 | PE0 INTA | High | Level | Non |
+ * IRQ 97 | PE0 INTB | High | Level | Non |
+ * IRQ 98 | PE0 INTC | High | Level | Non |
+ * IRQ 99 | PE0 INTD | High | Level | Non |
+ * IRQ 100 | PE1 INTA | High | Level | Non |
+ * IRQ 101 | PE1 INTB | High | Level | Non |
+ * IRQ 102 | PE1 INTC | High | Level | Non |
+ * IRQ 103 | PE1 INTD | High | Level | Non |
+ * IRQ 104 | PE2 INTA | High | Level | Non |
+ * IRQ 105 | PE2 INTB | High | Level | Non |
+ * IRQ 106 | PE2 INTC | High | Level | Non |
+ * IRQ 107 | PE2 INTD | Risin | Edge | Non |
+ * IRQ 108 | PCI Express MSI Level 4 | Risin | Edge | Non |
+ * IRQ 109 | PCI Express MSI Level 5 | Risin | Edge | Non |
+ * IRQ 110 | PCI Express MSI Level 6 | Risin | Edge | Non |
+ * IRQ 111 | PCI Express MSI Level 7 | Risin | Edge | Non |
+ * IRQ 116 | PCI Express MSI Level 12 | Risin | Edge | Non |
+ * IRQ 112 | PCI Express MSI Level 8 | Risin | Edge | Non |
+ * IRQ 113 | PCI Express MSI Level 9 | Risin | Edge | Non |
+ * IRQ 114 | PCI Express MSI Level 10 | Risin | Edge | Non |
+ * IRQ 115 | PCI Express MSI Level 11 | Risin | Edge | Non |
+ * IRQ 117 | PCI Express MSI Level 13 | Risin | Edge | Non |
+ * IRQ 118 | PCI Express MSI Level 14 | Risin | Edge | Non |
+ * IRQ 119 | PCI Express MSI Level 15 | Risin | Edge | Non |
+ * IRQ 120 | PCI Express MSI Level 16 | Risin | Edge | Non |
+ * IRQ 121 | PCI Express MSI Level 17 | Risin | Edge | Non |
+ * IRQ 122 | PCI Express MSI Level 18 | Risin | Edge | Non |
+ * IRQ 123 | PCI Express MSI Level 19 | Risin | Edge | Non |
+ * IRQ 124 | PCI Express MSI Level 20 | Risin | Edge | Non |
+ * IRQ 125 | PCI Express MSI Level 21 | Risin | Edge | Non |
+ * IRQ 126 | PCI Express MSI Level 22 | Risin | Edge | Non |
+ * IRQ 127 | PCI Express MSI Level 23 | Risin | Edge | Non |
+ *-----------+-----------------------------------+-------+-------+-------+ */
+ /*-------------------------------------------------------------------------+
+ * Put UICs in PowerPC440SPemode.
+ * Initialise UIC registers. Clear all interrupts. Disable all interrupts.
+ * Set critical interrupt values. Set interrupt polarities. Set interrupt
+ * trigger levels. Make bit 0 High priority. Clear all interrupts again.
+ *------------------------------------------------------------------------*/
+ mtdcr (uic3sr, 0xffffffff); /* Clear all interrupts */
+ mtdcr (uic3er, 0x00000000); /* disable all interrupts */
+ mtdcr (uic3cr, 0x00000000); /* Set Critical / Non Critical interrupts: */
+ mtdcr (uic3pr, 0xffffffff); /* Set Interrupt Polarities*/
+ mtdcr (uic3tr, 0x001fffff); /* Set Interrupt Trigger Levels */
+ mtdcr (uic3vr, 0x00000001); /* Set Vect base=0,INT31 Highest priority */
+ mtdcr (uic3sr, 0x00000000); /* clear all interrupts*/
+ mtdcr (uic3sr, 0xffffffff); /* clear all interrupts*/
+
+
+ mtdcr (uic2sr, 0xffffffff); /* Clear all interrupts */
+ mtdcr (uic2er, 0x00000000); /* disable all interrupts*/
+ mtdcr (uic2cr, 0x00000000); /* Set Critical / Non Critical interrupts*/
+ mtdcr (uic2pr, 0xebebebff); /* Set Interrupt Polarities*/
+ mtdcr (uic2tr, 0x74747400); /* Set Interrupt Trigger Levels */
+ mtdcr (uic2vr, 0x00000001); /* Set Vect base=0,INT31 Highest priority */
+ mtdcr (uic2sr, 0x00000000); /* clear all interrupts */
+ mtdcr (uic2sr, 0xffffffff); /* clear all interrupts */
+
+ mtdcr (uic1sr, 0xffffffff); /* Clear all interrupts*/
+ mtdcr (uic1er, 0x00000000); /* disable all interrupts*/
+ mtdcr (uic1cr, 0x00000000); /* Set Critical / Non Critical interrupts*/
+ mtdcr (uic1pr, 0xffffffff); /* Set Interrupt Polarities */
+ mtdcr (uic1tr, 0x001f8040); /* Set Interrupt Trigger Levels*/
+ mtdcr (uic1vr, 0x00000001); /* Set Vect base=0,INT31 Highest priority */
+ mtdcr (uic1sr, 0x00000000); /* clear all interrupts*/
+ mtdcr (uic1sr, 0xffffffff); /* clear all interrupts*/
+
+ mtdcr (uic0sr, 0xffffffff); /* Clear all interrupts */
+ mtdcr (uic0er, 0x00000000); /* disable all interrupts excepted cascade to be checked */
+ mtdcr (uic0cr, 0x00104001); /* Set Critical / Non Critical interrupts*/
+ mtdcr (uic0pr, 0xffffffff); /* Set Interrupt Polarities*/
+ mtdcr (uic0tr, 0x010f0004); /* Set Interrupt Trigger Levels */
+ mtdcr (uic0vr, 0x00000001); /* Set Vect base=0,INT31 Highest priority */
+ mtdcr (uic0sr, 0x00000000); /* clear all interrupts*/
+ mtdcr (uic0sr, 0xffffffff); /* clear all interrupts*/
+
+/* SDR0_MFR should be part of Ethernet init */
+ mfsdr (sdr_mfr, mfr);
+ mfr &= ~SDR0_MFR_ECS_MASK;
+/* mtsdr(sdr_mfr, mfr); */
+
+ mtsdr(SDR0_PFC0, CFG_PFC0);
+
+ out32(GPIO0_OR, CFG_GPIO_OR);
+ out32(GPIO0_ODR, CFG_GPIO_ODR);
+ out32(GPIO0_TCR, CFG_GPIO_TCR);
+
+ return 0;
+}
+
+int checkboard (void)
+{
+ char *s = getenv("serial#");
+
+ printf("Board: Katmai - AMCC 440SPe Evaluation Board");
+ if (s != NULL) {
+ puts(", serial# ");
+ puts(s);
+ }
+ putc('\n');
+
+ return 0;
+}
+
+#if defined(CFG_DRAM_TEST)
+int testdram (void)
+{
+ uint *pstart = (uint *) 0x00000000;
+ uint *pend = (uint *) 0x08000000;
+ uint *p;
+
+ for (p = pstart; p < pend; p++)
+ *p = 0xaaaaaaaa;
+
+ for (p = pstart; p < pend; p++) {
+ if (*p != 0xaaaaaaaa) {
+ printf ("SDRAM test fails at: %08x\n", (uint) p);
+ return 1;
+ }
+ }
+
+ for (p = pstart; p < pend; p++)
+ *p = 0x55555555;
+
+ for (p = pstart; p < pend; p++) {
+ if (*p != 0x55555555) {
+ printf ("SDRAM test fails at: %08x\n", (uint) p);
+ return 1;
+ }
+ }
+ 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 strap;
+
+ /*-------------------------------------------------------------------+
+ * The katmai board is always configured as the host & requires the
+ * PCI arbiter to be enabled.
+ *-------------------------------------------------------------------*/
+ mfsdr(sdr_sdstp1, strap);
+ if( (strap & SDR0_SDSTP1_PAE_MASK) == 0 ) {
+ printf("PCI: SDR0_STRP1[%08lX] - PCI Arbiter disabled.\n",strap);
+ return 0;
+ }
+
+ return 1;
+}
+#endif /* defined(CONFIG_PCI) && defined(CFG_PCI_PRE_INIT) */
+
+/*************************************************************************
+ * pci_target_init
+ *
+ * The bootstrap configuration provides default settings for the pci
+ * inbound map (PIM). But the bootstrap config choices are limited and
+ * may not be sufficient for a given board.
+ *
+ ************************************************************************/
+#if defined(CONFIG_PCI) && defined(CFG_PCI_TARGET_INIT)
+void pci_target_init(struct pci_controller * hose )
+{
+ DECLARE_GLOBAL_DATA_PTR;
+
+ /*-------------------------------------------------------------------+
+ * Disable everything
+ *-------------------------------------------------------------------*/
+ out32r( PCIX0_PIM0SA, 0 ); /* disable */
+ out32r( PCIX0_PIM1SA, 0 ); /* disable */
+ out32r( PCIX0_PIM2SA, 0 ); /* disable */
+ out32r( PCIX0_EROMBA, 0 ); /* disable expansion rom */
+
+ /*-------------------------------------------------------------------+
+ * Map all of SDRAM to PCI address 0x0000_0000. Note that the 440
+ * strapping options to not support sizes such as 128/256 MB.
+ *-------------------------------------------------------------------*/
+ out32r( PCIX0_PIM0LAL, CFG_SDRAM_BASE );
+ out32r( PCIX0_PIM0LAH, 0 );
+ out32r( PCIX0_PIM0SA, ~(gd->ram_size - 1) | 1 );
+ out32r( PCIX0_BAR0, 0 );
+
+ /*-------------------------------------------------------------------+
+ * Program the board's subsystem id/vendor id
+ *-------------------------------------------------------------------*/
+ out16r( PCIX0_SBSYSVID, CFG_PCI_SUBSYS_VENDORID );
+ out16r( PCIX0_SBSYSID, CFG_PCI_SUBSYS_DEVICEID );
+
+ out16r( PCIX0_CMD, in16r(PCIX0_CMD) | PCI_COMMAND_MEMORY );
+}
+#endif /* defined(CONFIG_PCI) && defined(CFG_PCI_TARGET_INIT) */
+
+#if defined(CONFIG_PCI)
+/*************************************************************************
+ * 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.
+ *
+ *
+ ************************************************************************/
+int is_pci_host(struct pci_controller *hose)
+{
+ /* The katmai board is always configured as host. */
+ return 1;
+}
+
+int katmai_pcie_card_present(int port)
+{
+ u32 val;
+
+ val = in32(GPIO0_IR);
+ switch (port) {
+ case 0:
+ return !(val & GPIO_VAL(CFG_GPIO_PCIE_PRESENT0));
+ case 1:
+ return !(val & GPIO_VAL(CFG_GPIO_PCIE_PRESENT1));
+ case 2:
+ return !(val & GPIO_VAL(CFG_GPIO_PCIE_PRESENT2));
+ default:
+ return 0;
+ }
+}
+
+static struct pci_controller pcie_hose[3] = {{0},{0},{0}};
+
+void pcie_setup_hoses(void)
+{
+ struct pci_controller *hose;
+ int i, bus;
+
+ /*
+ * assume we're called after the PCIX hose is initialized, which takes
+ * bus ID 0 and therefore start numbering PCIe's from 1.
+ */
+ bus = 1;
+ for (i = 0; i <= 2; i++) {
+ /* Check for katmai card presence */
+ if (!katmai_pcie_card_present(i))
+ continue;
+
+#ifdef PCIE_ENDPOINT
+ if (ppc440spe_init_pcie_endport(i)) {
+#else
+ if (ppc440spe_init_pcie_rootport(i)) {
+#endif
+ printf("PCIE%d: initialization failed\n", i);
+ continue;
+ }
+
+ hose = &pcie_hose[i];
+ hose->first_busno = bus;
+ hose->last_busno = bus;
+ bus++;
+
+ /* setup mem resource */
+ pci_set_region(hose->regions + 0,
+ CFG_PCIE_MEMBASE + i * CFG_PCIE_MEMSIZE,
+ CFG_PCIE_MEMBASE + i * CFG_PCIE_MEMSIZE,
+ CFG_PCIE_MEMSIZE,
+ PCI_REGION_MEM
+ );
+ hose->region_count = 1;
+ pci_register_hose(hose);
+
+#ifdef PCIE_ENDPOINT
+ ppc440spe_setup_pcie_endpoint(hose, i);
+ /*
+ * Reson for no scanning is endpoint can not generate
+ * upstream configuration accesses.
+ */
+#else
+ ppc440spe_setup_pcie_rootpoint(hose, i);
+ /*
+ * Config access can only go down stream
+ */
+ hose->last_busno = pci_hose_scan(hose);
+#endif
+ }
+}
+#endif /* defined(CONFIG_PCI) */
+
+int misc_init_f (void)
+{
+ uint reg;
+#if defined(CONFIG_STRESS)
+ uint i ;
+ uint disp;
+#endif
+
+ /* minimal init for PCIe */
+#if 0 /* test-only: test endpoint at some time, for now rootpoint only */
+ /* pci express 0 Endpoint Mode */
+ mfsdr(SDR0_PE0DLPSET, reg);
+ reg &= (~0x00400000);
+ mtsdr(SDR0_PE0DLPSET, reg);
+#else
+ /* pci express 0 Rootpoint Mode */
+ mfsdr(SDR0_PE0DLPSET, reg);
+ reg |= 0x00400000;
+ mtsdr(SDR0_PE0DLPSET, reg);
+#endif
+ /* pci express 1 Rootpoint Mode */
+ mfsdr(SDR0_PE1DLPSET, reg);
+ reg |= 0x00400000;
+ mtsdr(SDR0_PE1DLPSET, reg);
+ /* pci express 2 Rootpoint Mode */
+ mfsdr(SDR0_PE2DLPSET, reg);
+ reg |= 0x00400000;
+ mtsdr(SDR0_PE2DLPSET, reg);
+
+#if defined(CONFIG_STRESS)
+ /*
+ * All this setting done by linux only needed by stress an charac. test
+ * procedure
+ * PCIe 1 Rootpoint PCIe2 Endpoint
+ * PCIe 0 FIR Pre-emphasis Filter Coefficients & Transmit Driver Power Level
+ */
+ for (i=0,disp=0; i<8; i++,disp+=3) {
+ mfsdr(SDR0_PE0HSSSET1L0+disp, reg);
+ reg |= 0x33000000;
+ mtsdr(SDR0_PE0HSSSET1L0+disp, reg);
+ }
+
+ /*PCIe 1 FIR Pre-emphasis Filter Coefficients & Transmit Driver Power Level */
+ for (i=0,disp=0; i<4; i++,disp+=3) {
+ mfsdr(SDR0_PE1HSSSET1L0+disp, reg);
+ reg |= 0x33000000;
+ mtsdr(SDR0_PE1HSSSET1L0+disp, reg);
+ }
+
+ /*PCIE 2 FIR Pre-emphasis Filter Coefficients & Transmit Driver Power Level */
+ for (i=0,disp=0; i<4; i++,disp+=3) {
+ mfsdr(SDR0_PE2HSSSET1L0+disp, reg);
+ reg |= 0x33000000;
+ mtsdr(SDR0_PE2HSSSET1L0+disp, reg);
+ }
+
+ reg = 0x21242222;
+ mtsdr(SDR0_PE2UTLSET1, reg);
+ reg = 0x11000000;
+ mtsdr(SDR0_PE2UTLSET2, reg);
+ /* pci express 1 Endpoint Mode */
+ reg = 0x00004000;
+ mtsdr(SDR0_PE2DLPSET, reg);
+
+ mtsdr(SDR0_UART1, 0x2080005a); /* patch for TG */
+#endif
+
+ return 0;
+}
+
+#ifdef CONFIG_POST
+/*
+ * Returns 1 if keys pressed to start the power-on long-running tests
+ * Called from board_init_f().
+ */
+int post_hotkeys_pressed(void)
+{
+ return (ctrlc());
+}
+#endif
diff --git a/board/amcc/katmai/u-boot.lds b/board/amcc/katmai/u-boot.lds
new file mode 100644
index 00000000000..bf8fc5d3dab
--- /dev/null
+++ b/board/amcc/katmai/u-boot.lds
@@ -0,0 +1,141 @@
+/*
+ * (C) Copyright 2004
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+OUTPUT_ARCH(powerpc)
+SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/local/powerpc-any-elf/lib);
+/* Do we need any of these for elf?
+ __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) }
+ .hash : { *(.hash) }
+ .dynsym : { *(.dynsym) }
+ .dynstr : { *(.dynstr) }
+ .rel.text : { *(.rel.text) }
+ .rela.text : { *(.rela.text) }
+ .rel.data : { *(.rel.data) }
+ .rela.data : { *(.rela.data) }
+ .rel.rodata : { *(.rel.rodata) }
+ .rela.rodata : { *(.rela.rodata) }
+ .rel.got : { *(.rel.got) }
+ .rela.got : { *(.rela.got) }
+ .rel.ctors : { *(.rel.ctors) }
+ .rela.ctors : { *(.rela.ctors) }
+ .rel.dtors : { *(.rel.dtors) }
+ .rela.dtors : { *(.rela.dtors) }
+ .rel.bss : { *(.rel.bss) }
+ .rela.bss : { *(.rela.bss) }
+ .rel.plt : { *(.rel.plt) }
+ .rela.plt : { *(.rela.plt) }
+ .init : { *(.init) }
+ .plt : { *(.plt) }
+ .text :
+ {
+ cpu/ppc4xx/start.o (.text)
+ board/amcc/katmai/init.o (.text)
+
+ *(.text)
+ *(.fixup)
+ *(.got1)
+ }
+ _etext = .;
+ PROVIDE (etext = .);
+ .rodata :
+ {
+ *(.rodata)
+ *(.rodata1)
+ *(.rodata.str1.4)
+ *(.eh_frame)
+ }
+ .fini : { *(.fini) } =0
+ .ctors : { *(.ctors) }
+ .dtors : { *(.dtors) }
+
+ /* Read-write section, merged into data segment: */
+ . = (. + 0x00FF) & 0xFFFFFF00;
+ _erotext = .;
+ PROVIDE (erotext = .);
+ .reloc :
+ {
+ *(.got)
+ _GOT2_TABLE_ = .;
+ *(.got2)
+ _FIXUP_TABLE_ = .;
+ *(.fixup)
+ }
+ __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2;
+ __fixup_entries = (. - _FIXUP_TABLE_)>>2;
+
+ .data :
+ {
+ *(.data)
+ *(.data1)
+ *(.sdata)
+ *(.sdata2)
+ *(.dynamic)
+ CONSTRUCTORS
+ }
+ _edata = .;
+ PROVIDE (edata = .);
+
+ . = .;
+ __u_boot_cmd_start = .;
+ .u_boot_cmd : { *(.u_boot_cmd) }
+ __u_boot_cmd_end = .;
+
+
+ . = .;
+ __start___ex_table = .;
+ __ex_table : { *(__ex_table) }
+ __stop___ex_table = .;
+
+ . = ALIGN(256);
+ __init_begin = .;
+ .text.init : { *(.text.init) }
+ .data.init : { *(.data.init) }
+ . = ALIGN(256);
+ __init_end = .;
+
+ __bss_start = .;
+ .bss :
+ {
+ *(.sbss) *(.scommon)
+ *(.dynbss)
+ *(.bss)
+ *(COMMON)
+ }
+ _end = . ;
+ PROVIDE (end = .);
+}
diff --git a/board/amcc/luan/init.S b/board/amcc/luan/init.S
index 7830ebdfa6d..d5ee117dfac 100644
--- a/board/amcc/luan/init.S
+++ b/board/amcc/luan/init.S
@@ -1,73 +1,31 @@
/*
-*
-* 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
-*/
+ * (C) Copyright 2007
+ * Stefan Roese, DENX Software Engineering, sr@denx.de.
+ *
+ * Copyright (C) 2002 Scott McNutt <smcnutt@artesyncp.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
#include <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_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)
-
+#include <asm-ppc/mmu.h>
/**************************************************************************
* TLB TABLE
@@ -80,53 +38,37 @@
*
*************************************************************************/
- .section .bootpg,"ax"
- .globl tlbtab
+ .section .bootpg,"ax"
+ .globl tlbtab
tlbtab:
- tlbtab_start
-
-#if (CFG_LARGE_FLASH == 0xffc00000) /* if booting from large flash */
- /* large flash */
- tlbentry( 0xffc00000, SZ_1M, 0xffc00000, 1, AC_R|AC_W|AC_X|SA_G|SA_I|SA_W )
- tlbentry( 0xffd00000, SZ_1M, 0xffd00000, 1, AC_R|AC_W|AC_X|SA_G|SA_I|SA_W )
- tlbentry( 0xffe00000, SZ_1M, 0xffe00000, 1, AC_R|AC_W|AC_X|SA_G|SA_I|SA_W )
- tlbentry( 0xfff00000, SZ_1M, 0xfff00000, 1, AC_R|AC_W|AC_X|SA_G|SA_I|SA_W )
-
- tlbentry( 0xff800000, SZ_1M, 0xff800000, 1, AC_R|AC_W|AC_X|SA_G/*|SA_I*/ )
- tlbentry( 0xff900000, SZ_1M, 0xff900000, 1, AC_R|AC_W|AC_X|SA_G|SA_I|SA_W )
-#else /* else booting from small flash */
- tlbentry( 0xffe00000, SZ_1M, 0xffe00000, 1, AC_R|AC_W|AC_X|SA_G/*|SA_I*/ )
- tlbentry( 0xfff00000, SZ_1M, 0xfff00000, 1, AC_R|AC_W|AC_X|SA_G/*|SA_I*/ )
-
- tlbentry( 0xff800000, SZ_1M, 0xff800000, 1, AC_R|AC_W|AC_X|SA_G/*|SA_I*/ )
- tlbentry( 0xff900000, SZ_1M, 0xff900000, 1, AC_R|AC_W|AC_X|SA_G/*|SA_I*/ )
- tlbentry( 0xffa00000, SZ_1M, 0xffa00000, 1, AC_R|AC_W|AC_X|SA_G/*|SA_I*/ )
- tlbentry( 0xffb00000, SZ_1M, 0xffb00000, 1, AC_R|AC_W|AC_X|SA_G/*|SA_I*/ )
-#endif
-
- tlbentry( CFG_EPLD_BASE, SZ_256K, 0xff000000, 1, AC_R|AC_W|SA_G|SA_I )
-
-#if (CFG_SRAM_BASE != 0) /* if SRAM up high and SDRAM at zero */
- tlbentry( 0x00000000, SZ_256M, 0x00000000, 0, AC_R|AC_W|AC_X|SA_G|SA_I )
- tlbentry( 0x10000000, SZ_256M, 0x10000000, 0, AC_R|AC_W|AC_X|SA_G|SA_I )
-#elif (CFG_SMALL_FLASH == 0xff900000) /* else SRAM at 0 */
- tlbentry( 0x00000000, SZ_1M, 0xff800000, 1, AC_R|AC_W|AC_X|SA_G/*|SA_I*/ )
-#elif (CFG_SMALL_FLASH == 0xfff00000)
- tlbentry( 0x00000000, SZ_1M, 0xffe00000, 1, AC_R|AC_W|AC_X|SA_G/*|SA_I*/ )
-#else
- #error DONT KNOW SRAM LOCATION
-#endif
-
- /* internal ram (l2 cache) */
- tlbentry( CFG_ISRAM_BASE, SZ_256K, 0x80000000, 0, AC_R|AC_W|AC_X|SA_I )
-
- /* peripherals at f0000000 */
- tlbentry( CFG_PERIPHERAL_BASE, SZ_4K, CFG_PERIPHERAL_BASE, 1, AC_R|AC_W|SA_G|SA_I )
-
- /* PCI */
-#if (CONFIG_COMMANDS & CFG_CMD_PCI)
- tlbentry( CFG_PCI_BASE, SZ_256M, 0x00000000, 9, AC_R|AC_W|SA_G|SA_I )
- tlbentry( CFG_PCI_MEMBASE, SZ_256M, 0x10000000, 9, AC_R|AC_W|SA_G|SA_I )
-#endif
- tlbtab_end
+ 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(0xfff00000, SZ_1M, 0xfff00000, 1, AC_R|AC_W|AC_X|SA_G)
+
+ tlbentry(0xffc00000, SZ_1M, 0xffc00000, 1, AC_R|AC_W|AC_X|SA_G|SA_I)
+ tlbentry(0xffd00000, SZ_1M, 0xffd00000, 1, AC_R|AC_W|AC_X|SA_G|SA_I)
+ tlbentry(0xffe00000, SZ_1M, 0xffe00000, 1, AC_R|AC_W|AC_X|SA_G|SA_I)
+ tlbentry(0xff900000, SZ_1M, 0xff900000, 1, AC_R|AC_W|AC_X|SA_G|SA_I)
+ tlbentry(CFG_EPLD_BASE, SZ_256K, 0xff000000, 1, AC_R|AC_W|SA_G|SA_I)
+
+ /*
+ * TLB entries for SDRAM are not needed on this platform.
+ * They are dynamically generated in the SPD DDR(2) detection
+ * routine.
+ */
+
+ /* internal ram (l2 cache) */
+ tlbentry(CFG_ISRAM_BASE, SZ_256K, 0x80000000, 0, AC_R|AC_W|AC_X|SA_I)
+
+ /* peripherals at f0000000 */
+ tlbentry(CFG_PERIPHERAL_BASE, SZ_4K, CFG_PERIPHERAL_BASE, 1, AC_R|AC_W|SA_G|SA_I)
+
+ /* PCI */
+ tlbentry(CFG_PCI_BASE, SZ_256M, 0x00000000, 9, AC_R|AC_W|SA_G|SA_I)
+ tlbentry(CFG_PCI_MEMBASE, SZ_256M, 0x10000000, 9, AC_R|AC_W|SA_G|SA_I)
+ tlbtab_end
diff --git a/board/amcc/luan/luan.c b/board/amcc/luan/luan.c
index 06a57f6c4aa..778aafc7660 100644
--- a/board/amcc/luan/luan.c
+++ b/board/amcc/luan/luan.c
@@ -106,105 +106,6 @@ int checkboard(void)
/*************************************************************************
- * long int fixed_sdram()
- *
- ************************************************************************/
-static long int fixed_sdram(void)
-{ /* DDR2 init from BDI2000 script */
- mtdcr( 0x10, 0x00000021 ); /* MCIF0_MCOPT2 - zero DCEN bit */
- mtdcr( 0x11, 0x84000000 );
- mtdcr( 0x10, 0x00000020 ); /* MCIF0_MCOPT1 - no ECC, 64 bits, 4 banks, DDR2 */
- mtdcr( 0x11, 0x2D122000 );
- mtdcr( 0x10, 0x00000026 ); /* MCIF0_CODT - die termination on */
- mtdcr( 0x11, 0x00800026 );
- mtdcr( 0x10, 0x00000081 ); /* MCIF0_WRDTR - Write DQS Adv 90 + Fractional DQS Delay */
- mtdcr( 0x11, 0x82000800 );
- mtdcr( 0x10, 0x00000080 ); /* MCIF0_CLKTR - advance addr clock by 180 deg */
- mtdcr( 0x11, 0x80000000 );
- mtdcr( 0x10, 0x00000040 ); /* MCIF0_MB0CF - turn on CS0, N x 10 coll */
- mtdcr( 0x11, 0x00000201 );
- mtdcr( 0x10, 0x00000044 ); /* MCIF0_MB1CF - turn on CS0, N x 10 coll */
- mtdcr( 0x11, 0x00000201 );
- mtdcr( 0x10, 0x00000030 ); /* MCIF0_RTR - refresh every 7.8125uS */
- mtdcr( 0x11, 0x08200000 );
- mtdcr( 0x10, 0x00000085 ); /* MCIF0_SDTR1 - timing register 1 */
- mtdcr( 0x11, 0x80201000 );
- mtdcr( 0x10, 0x00000086 ); /* MCIF0_SDTR2 - timing register 2 */
- mtdcr( 0x11, 0x42103242 );
- mtdcr( 0x10, 0x00000087 ); /* MCIF0_SDTR3 - timing register 3 */
- mtdcr( 0x11, 0x0C100D14 );
- mtdcr( 0x10, 0x00000088 ); /* MCIF0_MMODE - CAS is 4 cycles */
- mtdcr( 0x11, 0x00000642 );
- mtdcr( 0x10, 0x00000089 ); /* MCIF0_MEMODE - diff DQS disabled */
- mtdcr( 0x11, 0x00000400 ); /* ODT term disabled */
-
- mtdcr( 0x10, 0x00000050 ); /* MCIF0_INITPLR0 - NOP */
- mtdcr( 0x11, 0x81b80000 );
- mtdcr( 0x10, 0x00000051 ); /* MCIF0_INITPLR1 - PRE */
- mtdcr( 0x11, 0x82100400 );
- mtdcr( 0x10, 0x00000052 ); /* MCIF0_INITPLR2 - EMR2 */
- mtdcr( 0x11, 0x80820000 );
- mtdcr( 0x10, 0x00000053 ); /* MCIF0_INITPLR3 - EMR3 */
- mtdcr( 0x11, 0x80830000 );
- mtdcr( 0x10, 0x00000054 ); /* MCIF0_INITPLR4 - EMR DLL ENABLE */
- mtdcr( 0x11, 0x80810000 );
- mtdcr( 0x10, 0x00000055 ); /* MCIF0_INITPLR5 - MR DLL RESET */
- mtdcr( 0x11, 0x80800542 );
- mtdcr( 0x10, 0x00000056 ); /* MCIF0_INITPLR6 - PRE */
- mtdcr( 0x11, 0x82100400 );
- mtdcr( 0x10, 0x00000057 ); /* MCIF0_INITPLR7 - refresh */
- mtdcr( 0x11, 0x99080000 );
- mtdcr( 0x10, 0x00000058 ); /* MCIF0_INITPLR8 */
- mtdcr( 0x11, 0x99080000 );
- mtdcr( 0x10, 0x00000059 ); /* MCIF0_INITPLR9 */
- mtdcr( 0x11, 0x99080000 );
- mtdcr( 0x10, 0x0000005A ); /* MCIF0_INITPLR10 */
- mtdcr( 0x11, 0x99080000 );
- mtdcr( 0x10, 0x0000005B ); /* MCIF0_INITPLR11 - MR */
- mtdcr( 0x11, 0x80800442 );
- mtdcr( 0x10, 0x0000005C ); /* MCIF0_INITPLR12 - EMR OCD Default */
- mtdcr( 0x11, 0x80810380 );
- mtdcr( 0x10, 0x0000005D ); /* MCIF0_INITPLR13 - EMR OCD exit */
- mtdcr( 0x11, 0x80810000 );
- udelay( 10*1000 );
-
- mtdcr( 0x10, 0x00000021 ); /* MCIF0_MCOPT2 - execute preloaded init */
- mtdcr( 0x11, 0x28000000 ); /* set DC_EN */
- udelay( 100*1000 );
-
- mtdcr( 0x40, 0x0000F800 ); /* MQ0_B0BAS: base addr 00000000 / 256MB */
- mtdcr( 0x41, 0x1000F800 ); /* MQ0_B1BAS: base addr 10000000 / 256MB */
-
- mtdcr( 0x10, 0x00000078 ); /* MCIF0_RDCC - auto set read stage */
- mtdcr( 0x11, 0x00000000 );
- mtdcr( 0x10, 0x00000070 ); /* MCIF0_RQDC - read DQS delay control */
- mtdcr( 0x11, 0x8000003A ); /* enabled, frac DQS delay */
- mtdcr( 0x10, 0x00000074 ); /* MCIF0_RFDC - two clock feedback delay */
- mtdcr( 0x11, 0x00000200 );
-
- return 512 << 20;
-}
-
-
-/*************************************************************************
- * long int initdram
- *
- ************************************************************************/
-long int initdram( int board_type )
-{
- long dram_size = 0;
-
-#if defined(CONFIG_SPD_EEPROM)
- dram_size = spd_sdram (0);
-#else
- dram_size = fixed_sdram ();
-#endif
-
- return dram_size;
-}
-
-
-/*************************************************************************
* int testdram()
*
************************************************************************/
diff --git a/board/amcc/luan/u-boot.lds b/board/amcc/luan/u-boot.lds
index d122f499f1b..72ce6855d75 100644
--- a/board/amcc/luan/u-boot.lds
+++ b/board/amcc/luan/u-boot.lds
@@ -68,19 +68,6 @@ SECTIONS
cpu/ppc4xx/start.o (.text)
board/amcc/luan/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)*/
*(.text)
*(.fixup)
diff --git a/board/amcc/ocotea/init.S b/board/amcc/ocotea/init.S
index 7e0b1324929..d211c710b23 100644
--- a/board/amcc/ocotea/init.S
+++ b/board/amcc/ocotea/init.S
@@ -22,55 +22,7 @@
#include <ppc_asm.tmpl>
#include <config.h>
-
-/* General */
-#define TLB_VALID 0x00000200
-#define _256M 0x10000000
-
-/* 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)
-
+#include <asm-ppc/mmu.h>
/**************************************************************************
* TLB TABLE
@@ -83,19 +35,23 @@
*
*************************************************************************/
- .section .bootpg,"ax"
- .globl tlbtab
+ .section .bootpg,"ax"
+ .globl tlbtab
tlbtab:
- tlbtab_start
- tlbentry( 0xf0000000, SZ_256M, 0xf0000000, 1, AC_R|AC_W|AC_X|SA_G|SA_I )
- tlbentry( CFG_PERIPHERAL_BASE, SZ_256M, 0x40000000, 1, AC_R|AC_W|SA_G|SA_I )
- tlbentry( CFG_ISRAM_BASE, SZ_4K, 0x80000000, 0, AC_R|AC_W|AC_X )
- tlbentry( CFG_ISRAM_BASE + 0x1000, SZ_4K, 0x80001000, 0, AC_R|AC_W|AC_X )
- tlbentry( CFG_SDRAM_BASE, SZ_256M, 0x00000000, 0, AC_R|AC_W|AC_X|SA_G|SA_I )
- tlbentry( CFG_SDRAM_BASE + 0x10000000, SZ_256M, 0x10000000, 0, AC_R|AC_W|AC_X|SA_G|SA_I )
- tlbentry( CFG_SDRAM_BASE + 0x20000000, SZ_256M, 0x20000000, 0, AC_R|AC_W|AC_X|SA_G|SA_I )
- tlbentry( CFG_SDRAM_BASE + 0x30000000, SZ_256M, 0x30000000, 0, AC_R|AC_W|AC_X|SA_G|SA_I )
- tlbentry( CFG_PCI_BASE, SZ_256M, 0x00000000, 2, AC_R|AC_W|SA_G|SA_I )
- tlbentry( CFG_PCI_MEMBASE, SZ_256M, 0x00000000, 3, AC_R|AC_W|SA_G|SA_I )
- tlbtab_end
+ tlbtab_start
+
+ tlbentry(0xf0000000, SZ_256M, 0xf0000000, 1, AC_R|AC_W|AC_X|SA_G|SA_I)
+
+ /*
+ * TLB entries for SDRAM are not needed on this platform.
+ * They are dynamically generated in the SPD DDR(2) detection
+ * routine.
+ */
+
+ tlbentry(CFG_PERIPHERAL_BASE, SZ_256M, 0x40000000, 1, AC_R|AC_W|SA_G|SA_I)
+ tlbentry(CFG_ISRAM_BASE, SZ_4K, 0x80000000, 0, AC_R|AC_W|AC_X)
+ tlbentry(CFG_ISRAM_BASE + 0x1000, SZ_4K, 0x80001000, 0, AC_R|AC_W|AC_X)
+ tlbentry(CFG_PCI_BASE, SZ_256M, 0x00000000, 2, AC_R|AC_W|SA_G|SA_I)
+ tlbentry(CFG_PCI_MEMBASE, SZ_256M, 0x00000000, 3, AC_R|AC_W|SA_G|SA_I)
+ tlbtab_end
diff --git a/board/amcc/sequoia/init.S b/board/amcc/sequoia/init.S
index 3d4ac8543d5..45bcd4bef75 100644
--- a/board/amcc/sequoia/init.S
+++ b/board/amcc/sequoia/init.S
@@ -90,7 +90,7 @@ tlbtab:
/*
* 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
- */
+ */
#ifndef CONFIG_NAND_SPL
tlbentry( CFG_BOOT_BASE_ADDR, SZ_256M, CFG_BOOT_BASE_ADDR, 1, AC_R|AC_W|AC_X|SA_G )
#else
diff --git a/board/amcc/sequoia/sdram.c b/board/amcc/sequoia/sdram.c
index 53f728def9d..f8b837ed286 100644
--- a/board/amcc/sequoia/sdram.c
+++ b/board/amcc/sequoia/sdram.c
@@ -1,5 +1,12 @@
/*
* (C) Copyright 2006
+ * Sylvie Gohl, AMCC/IBM, gohl.sylvie@fr.ibm.com
+ * Jacqueline Pira-Ferriol, AMCC/IBM, jpira-ferriol@fr.ibm.com
+ * Thierry Roman, AMCC/IBM, thierry_roman@fr.ibm.com
+ * Alain Saurel, AMCC/IBM, alain.saurel@fr.ibm.com
+ * Robert Snyder, AMCC/IBM, rob.snyder@fr.ibm.com
+ *
+ * (C) Copyright 2006-2007
* Stefan Roese, DENX Software Engineering, sr@denx.de.
*
* This program is free software; you can redistribute it and/or
@@ -18,10 +25,352 @@
* MA 02111-1307 USA
*/
+/* define DEBUG for debug output */
+#undef DEBUG
+
#include <common.h>
#include <asm/processor.h>
+#include <asm/io.h>
#include <ppc440.h>
+#include "sdram.h"
+
+#if !defined(CONFIG_NAND_U_BOOT) || defined(CONFIG_NAND_SPL) || \
+ defined(CONFIG_DDR_DATA_EYE)
+/*-----------------------------------------------------------------------------+
+ * wait_for_dlllock.
+ +----------------------------------------------------------------------------*/
+static int wait_for_dlllock(void)
+{
+ unsigned long val;
+ int wait = 0;
+
+ /* -----------------------------------------------------------+
+ * Wait for the DCC master delay line to finish calibration
+ * ----------------------------------------------------------*/
+ mtdcr(ddrcfga, DDR0_17);
+ val = DDR0_17_DLLLOCKREG_UNLOCKED;
+
+ while (wait != 0xffff) {
+ val = mfdcr(ddrcfgd);
+ if ((val & DDR0_17_DLLLOCKREG_MASK) == DDR0_17_DLLLOCKREG_LOCKED)
+ /* dlllockreg bit on */
+ return 0;
+ else
+ wait++;
+ }
+ debug("0x%04x: DDR0_17 Value (dlllockreg bit): 0x%08x\n", wait, val);
+ debug("Waiting for dlllockreg bit to raise\n");
+
+ return -1;
+}
+#endif
+
+#if defined(CONFIG_DDR_DATA_EYE)
+/*-----------------------------------------------------------------------------+
+ * wait_for_dram_init_complete.
+ +----------------------------------------------------------------------------*/
+int wait_for_dram_init_complete(void)
+{
+ unsigned long val;
+ int wait = 0;
+
+ /* --------------------------------------------------------------+
+ * Wait for 'DRAM initialization complete' bit in status register
+ * -------------------------------------------------------------*/
+ mtdcr(ddrcfga, DDR0_00);
+
+ while (wait != 0xffff) {
+ val = mfdcr(ddrcfgd);
+ if ((val & DDR0_00_INT_STATUS_BIT6) == DDR0_00_INT_STATUS_BIT6)
+ /* 'DRAM initialization complete' bit */
+ return 0;
+ else
+ wait++;
+ }
+
+ debug("DRAM initialization complete bit in status register did not rise\n");
+
+ return -1;
+}
+
+#define NUM_TRIES 64
+#define NUM_READS 10
+
+/*-----------------------------------------------------------------------------+
+ * denali_core_search_data_eye.
+ +----------------------------------------------------------------------------*/
+void denali_core_search_data_eye(unsigned long memory_size)
+{
+ int k, j;
+ u32 val;
+ u32 wr_dqs_shift, dqs_out_shift, dll_dqs_delay_X;
+ u32 max_passing_cases = 0, wr_dqs_shift_with_max_passing_cases = 0;
+ u32 passing_cases = 0, dll_dqs_delay_X_sw_val = 0;
+ u32 dll_dqs_delay_X_start_window = 0, dll_dqs_delay_X_end_window = 0;
+ volatile u32 *ram_pointer;
+ u32 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 };
+
+ ram_pointer = (volatile u32 *)(CFG_SDRAM_BASE);
+
+ for (wr_dqs_shift = 64; wr_dqs_shift < 96; wr_dqs_shift++) {
+ /*for (wr_dqs_shift=1; wr_dqs_shift<96; wr_dqs_shift++) {*/
+
+ /* -----------------------------------------------------------+
+ * De-assert 'start' parameter.
+ * ----------------------------------------------------------*/
+ mtdcr(ddrcfga, DDR0_02);
+ val = (mfdcr(ddrcfgd) & ~DDR0_02_START_MASK) | DDR0_02_START_OFF;
+ mtdcr(ddrcfgd, val);
+
+ /* -----------------------------------------------------------+
+ * Set 'wr_dqs_shift'
+ * ----------------------------------------------------------*/
+ mtdcr(ddrcfga, DDR0_09);
+ val = (mfdcr(ddrcfgd) & ~DDR0_09_WR_DQS_SHIFT_MASK)
+ | DDR0_09_WR_DQS_SHIFT_ENCODE(wr_dqs_shift);
+ mtdcr(ddrcfgd, val);
+
+ /* -----------------------------------------------------------+
+ * Set 'dqs_out_shift' = wr_dqs_shift + 32
+ * ----------------------------------------------------------*/
+ dqs_out_shift = wr_dqs_shift + 32;
+ mtdcr(ddrcfga, DDR0_22);
+ val = (mfdcr(ddrcfgd) & ~DDR0_22_DQS_OUT_SHIFT_MASK)
+ | DDR0_22_DQS_OUT_SHIFT_ENCODE(dqs_out_shift);
+ mtdcr(ddrcfgd, val);
+
+ passing_cases = 0;
+
+ for (dll_dqs_delay_X = 1; dll_dqs_delay_X < 64; dll_dqs_delay_X++) {
+ /*for (dll_dqs_delay_X=1; dll_dqs_delay_X<128; dll_dqs_delay_X++) {*/
+ /* -----------------------------------------------------------+
+ * Set 'dll_dqs_delay_X'.
+ * ----------------------------------------------------------*/
+ /* dll_dqs_delay_0 */
+ mtdcr(ddrcfga, DDR0_17);
+ val = (mfdcr(ddrcfgd) & ~DDR0_17_DLL_DQS_DELAY_0_MASK)
+ | DDR0_17_DLL_DQS_DELAY_0_ENCODE(dll_dqs_delay_X);
+ mtdcr(ddrcfgd, val);
+ /* dll_dqs_delay_1 to dll_dqs_delay_4 */
+ mtdcr(ddrcfga, DDR0_18);
+ val = (mfdcr(ddrcfgd) & ~DDR0_18_DLL_DQS_DELAY_X_MASK)
+ | DDR0_18_DLL_DQS_DELAY_4_ENCODE(dll_dqs_delay_X)
+ | DDR0_18_DLL_DQS_DELAY_3_ENCODE(dll_dqs_delay_X)
+ | DDR0_18_DLL_DQS_DELAY_2_ENCODE(dll_dqs_delay_X)
+ | DDR0_18_DLL_DQS_DELAY_1_ENCODE(dll_dqs_delay_X);
+ mtdcr(ddrcfgd, val);
+ /* dll_dqs_delay_5 to dll_dqs_delay_8 */
+ mtdcr(ddrcfga, DDR0_19);
+ val = (mfdcr(ddrcfgd) & ~DDR0_19_DLL_DQS_DELAY_X_MASK)
+ | DDR0_19_DLL_DQS_DELAY_8_ENCODE(dll_dqs_delay_X)
+ | DDR0_19_DLL_DQS_DELAY_7_ENCODE(dll_dqs_delay_X)
+ | DDR0_19_DLL_DQS_DELAY_6_ENCODE(dll_dqs_delay_X)
+ | DDR0_19_DLL_DQS_DELAY_5_ENCODE(dll_dqs_delay_X);
+ mtdcr(ddrcfgd, val);
+
+ ppcMsync();
+ ppcMbar();
+
+ /* -----------------------------------------------------------+
+ * Assert 'start' parameter.
+ * ----------------------------------------------------------*/
+ mtdcr(ddrcfga, DDR0_02);
+ val = (mfdcr(ddrcfgd) & ~DDR0_02_START_MASK) | DDR0_02_START_ON;
+ mtdcr(ddrcfgd, val);
+
+ ppcMsync();
+ ppcMbar();
+
+ /* -----------------------------------------------------------+
+ * Wait for the DCC master delay line to finish calibration
+ * ----------------------------------------------------------*/
+ if (wait_for_dlllock() != 0) {
+ printf("dlllock did not occur !!!\n");
+ printf("denali_core_search_data_eye!!!\n");
+ printf("wr_dqs_shift = %d - dll_dqs_delay_X = %d\n",
+ wr_dqs_shift, dll_dqs_delay_X);
+ hang();
+ }
+ ppcMsync();
+ ppcMbar();
+
+ if (wait_for_dram_init_complete() != 0) {
+ printf("dram init complete did not occur !!!\n");
+ printf("denali_core_search_data_eye!!!\n");
+ printf("wr_dqs_shift = %d - dll_dqs_delay_X = %d\n",
+ wr_dqs_shift, dll_dqs_delay_X);
+ hang();
+ }
+ udelay(100); /* wait 100us to ensure init is really completed !!! */
+
+ /* 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;
+ }
+
+ /* See if the dll_dqs_delay_X value passed.*/
+ if (j < NUM_TRIES) {
+ /* Failed */
+ passing_cases = 0;
+ /* break; */
+ } else {
+ /* Passed */
+ if (passing_cases == 0)
+ dll_dqs_delay_X_sw_val = dll_dqs_delay_X;
+ passing_cases++;
+ if (passing_cases >= max_passing_cases) {
+ max_passing_cases = passing_cases;
+ wr_dqs_shift_with_max_passing_cases = wr_dqs_shift;
+ dll_dqs_delay_X_start_window = dll_dqs_delay_X_sw_val;
+ dll_dqs_delay_X_end_window = dll_dqs_delay_X;
+ }
+ }
+
+ /* -----------------------------------------------------------+
+ * De-assert 'start' parameter.
+ * ----------------------------------------------------------*/
+ mtdcr(ddrcfga, DDR0_02);
+ val = (mfdcr(ddrcfgd) & ~DDR0_02_START_MASK) | DDR0_02_START_OFF;
+ mtdcr(ddrcfgd, val);
+
+ } /* for (dll_dqs_delay_X=0; dll_dqs_delay_X<128; dll_dqs_delay_X++) */
+
+ } /* for (wr_dqs_shift=0; wr_dqs_shift<96; wr_dqs_shift++) */
+
+ /* -----------------------------------------------------------+
+ * Largest passing window is now detected.
+ * ----------------------------------------------------------*/
+
+ /* Compute dll_dqs_delay_X value */
+ dll_dqs_delay_X = (dll_dqs_delay_X_end_window + dll_dqs_delay_X_start_window) / 2;
+ wr_dqs_shift = wr_dqs_shift_with_max_passing_cases;
+
+ debug("DQS calibration - Window detected:\n");
+ debug("max_passing_cases = %d\n", max_passing_cases);
+ debug("wr_dqs_shift = %d\n", wr_dqs_shift);
+ debug("dll_dqs_delay_X = %d\n", dll_dqs_delay_X);
+ debug("dll_dqs_delay_X window = %d - %d\n",
+ dll_dqs_delay_X_start_window, dll_dqs_delay_X_end_window);
+
+ /* -----------------------------------------------------------+
+ * De-assert 'start' parameter.
+ * ----------------------------------------------------------*/
+ mtdcr(ddrcfga, DDR0_02);
+ val = (mfdcr(ddrcfgd) & ~DDR0_02_START_MASK) | DDR0_02_START_OFF;
+ mtdcr(ddrcfgd, val);
+
+ /* -----------------------------------------------------------+
+ * Set 'wr_dqs_shift'
+ * ----------------------------------------------------------*/
+ mtdcr(ddrcfga, DDR0_09);
+ val = (mfdcr(ddrcfgd) & ~DDR0_09_WR_DQS_SHIFT_MASK)
+ | DDR0_09_WR_DQS_SHIFT_ENCODE(wr_dqs_shift);
+ mtdcr(ddrcfgd, val);
+ debug("DDR0_09=0x%08lx\n", val);
+
+ /* -----------------------------------------------------------+
+ * Set 'dqs_out_shift' = wr_dqs_shift + 32
+ * ----------------------------------------------------------*/
+ dqs_out_shift = wr_dqs_shift + 32;
+ mtdcr(ddrcfga, DDR0_22);
+ val = (mfdcr(ddrcfgd) & ~DDR0_22_DQS_OUT_SHIFT_MASK)
+ | DDR0_22_DQS_OUT_SHIFT_ENCODE(dqs_out_shift);
+ mtdcr(ddrcfgd, val);
+ debug("DDR0_22=0x%08lx\n", val);
+
+ /* -----------------------------------------------------------+
+ * Set 'dll_dqs_delay_X'.
+ * ----------------------------------------------------------*/
+ /* dll_dqs_delay_0 */
+ mtdcr(ddrcfga, DDR0_17);
+ val = (mfdcr(ddrcfgd) & ~DDR0_17_DLL_DQS_DELAY_0_MASK)
+ | DDR0_17_DLL_DQS_DELAY_0_ENCODE(dll_dqs_delay_X);
+ mtdcr(ddrcfgd, val);
+ debug("DDR0_17=0x%08lx\n", val);
+
+ /* dll_dqs_delay_1 to dll_dqs_delay_4 */
+ mtdcr(ddrcfga, DDR0_18);
+ val = (mfdcr(ddrcfgd) & ~DDR0_18_DLL_DQS_DELAY_X_MASK)
+ | DDR0_18_DLL_DQS_DELAY_4_ENCODE(dll_dqs_delay_X)
+ | DDR0_18_DLL_DQS_DELAY_3_ENCODE(dll_dqs_delay_X)
+ | DDR0_18_DLL_DQS_DELAY_2_ENCODE(dll_dqs_delay_X)
+ | DDR0_18_DLL_DQS_DELAY_1_ENCODE(dll_dqs_delay_X);
+ mtdcr(ddrcfgd, val);
+ debug("DDR0_18=0x%08lx\n", val);
+
+ /* dll_dqs_delay_5 to dll_dqs_delay_8 */
+ mtdcr(ddrcfga, DDR0_19);
+ val = (mfdcr(ddrcfgd) & ~DDR0_19_DLL_DQS_DELAY_X_MASK)
+ | DDR0_19_DLL_DQS_DELAY_8_ENCODE(dll_dqs_delay_X)
+ | DDR0_19_DLL_DQS_DELAY_7_ENCODE(dll_dqs_delay_X)
+ | DDR0_19_DLL_DQS_DELAY_6_ENCODE(dll_dqs_delay_X)
+ | DDR0_19_DLL_DQS_DELAY_5_ENCODE(dll_dqs_delay_X);
+ mtdcr(ddrcfgd, val);
+ debug("DDR0_19=0x%08lx\n", val);
+
+ /* -----------------------------------------------------------+
+ * Assert 'start' parameter.
+ * ----------------------------------------------------------*/
+ mtdcr(ddrcfga, DDR0_02);
+ val = (mfdcr(ddrcfgd) & ~DDR0_02_START_MASK) | DDR0_02_START_ON;
+ mtdcr(ddrcfgd, val);
+
+ ppcMsync();
+ ppcMbar();
+
+ /* -----------------------------------------------------------+
+ * Wait for the DCC master delay line to finish calibration
+ * ----------------------------------------------------------*/
+ if (wait_for_dlllock() != 0) {
+ printf("dlllock did not occur !!!\n");
+ hang();
+ }
+ ppcMsync();
+ ppcMbar();
+
+ if (wait_for_dram_init_complete() != 0) {
+ printf("dram init complete did not occur !!!\n");
+ hang();
+ }
+ udelay(100); /* wait 100us to ensure init is really completed !!! */
+}
+#endif /* CONFIG_DDR_DATA_EYE */
+
/*************************************************************************
*
* initdram -- 440EPx's DDR controller is a DENALI Core
@@ -30,18 +379,18 @@
long int initdram (int board_type)
{
#if !defined(CONFIG_NAND_U_BOOT) || defined(CONFIG_NAND_SPL)
- volatile ulong val;
+ ulong speed = get_bus_freq(0);
mtsdram(DDR0_02, 0x00000000);
mtsdram(DDR0_00, 0x0000190A);
mtsdram(DDR0_01, 0x01000000);
mtsdram(DDR0_03, 0x02030602);
- mtsdram(DDR0_04, 0x13030300);
- mtsdram(DDR0_05, 0x0202050E);
- mtsdram(DDR0_06, 0x0104C823);
+ mtsdram(DDR0_04, 0x0A020200);
+ mtsdram(DDR0_05, 0x02020308);
+ mtsdram(DDR0_06, 0x0102C812);
mtsdram(DDR0_07, 0x000D0100);
- mtsdram(DDR0_08, 0x02360001);
+ mtsdram(DDR0_08, 0x02430001);
mtsdram(DDR0_09, 0x00011D5F);
mtsdram(DDR0_10, 0x00000300);
mtsdram(DDR0_11, 0x0027C800);
@@ -55,23 +404,27 @@ long int initdram (int board_type)
mtsdram(DDR0_22, 0x00267F0B);
mtsdram(DDR0_23, 0x00000000);
mtsdram(DDR0_24, 0x01010002);
- mtsdram(DDR0_26, 0x5B260181);
+ if (speed > 133333333)
+ mtsdram(DDR0_26, 0x5B26050C);
+ else
+ mtsdram(DDR0_26, 0x5B260408);
mtsdram(DDR0_27, 0x0000682B);
mtsdram(DDR0_28, 0x00000000);
mtsdram(DDR0_31, 0x00000000);
mtsdram(DDR0_42, 0x01000006);
- mtsdram(DDR0_43, 0x050A0200);
- mtsdram(DDR0_44, 0x00000005);
+ mtsdram(DDR0_43, 0x030A0200);
+ mtsdram(DDR0_44, 0x00000003);
mtsdram(DDR0_02, 0x00000001);
- /*
- * Wait for DCC master delay line to finish calibration
- */
- mfsdram(DDR0_17, val);
- while (((val >> 8) & 0x000007f) == 0) {
- mfsdram(DDR0_17, val);
- }
+ wait_for_dlllock();
#endif /* #ifndef CONFIG_NAND_U_BOOT */
+#ifdef CONFIG_DDR_DATA_EYE
+ /* -----------------------------------------------------------+
+ * Perform data eye search if requested.
+ * ----------------------------------------------------------*/
+ denali_core_search_data_eye(CFG_MBYTES_SDRAM << 20);
+#endif
+
return (CFG_MBYTES_SDRAM << 20);
}
diff --git a/board/amcc/sequoia/sdram.h b/board/amcc/sequoia/sdram.h
new file mode 100644
index 00000000000..7f847aa2ad9
--- /dev/null
+++ b/board/amcc/sequoia/sdram.h
@@ -0,0 +1,505 @@
+/*
+ * (C) Copyright 2006
+ * Sylvie Gohl, AMCC/IBM, gohl.sylvie@fr.ibm.com
+ * Jacqueline Pira-Ferriol, AMCC/IBM, jpira-ferriol@fr.ibm.com
+ * Thierry Roman, AMCC/IBM, thierry_roman@fr.ibm.com
+ * Alain Saurel, AMCC/IBM, alain.saurel@fr.ibm.com
+ * Robert Snyder, AMCC/IBM, rob.snyder@fr.ibm.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 _SPD_SDRAM_DENALI_H_
+#define _SPD_SDRAM_DENALI_H_
+
+#define ppcMsync sync
+#define ppcMbar eieio
+
+/* General definitions */
+#define MAX_SPD_BYTE 128 /* highest SPD byte # to read */
+#define DENALI_REG_NUMBER 45 /* 45 Regs in PPC440EPx Denali Core */
+#define SUPPORTED_DIMMS_NB 7 /* Number of supported DIMM modules types */
+#define SDRAM_NONE 0 /* No DIMM detected in Slot */
+#define MAXRANKS 2 /* 2 ranks maximum */
+
+/* Supported PLB Frequencies */
+#define PLB_FREQ_133MHZ 133333333
+#define PLB_FREQ_152MHZ 152000000
+#define PLB_FREQ_160MHZ 160000000
+#define PLB_FREQ_166MHZ 166666666
+
+/* Denali Core Registers */
+#define SDRAM_DCR_BASE 0x10
+
+#define DDR_DCR_BASE 0x10
+#define ddrcfga (DDR_DCR_BASE+0x0) /* DDR configuration address reg */
+#define ddrcfgd (DDR_DCR_BASE+0x1) /* DDR configuration data reg */
+
+/*-----------------------------------------------------------------------------+
+ | Values for ddrcfga register - indirect addressing of these regs
+ +-----------------------------------------------------------------------------*/
+
+#define DDR0_00 0x00
+#define DDR0_00_INT_ACK_MASK 0x7F000000 /* Write only */
+#define DDR0_00_INT_ACK_ALL 0x7F000000
+#define DDR0_00_INT_ACK_ENCODE(n) ((((unsigned long)(n))&0x7F)<<24)
+#define DDR0_00_INT_ACK_DECODE(n) ((((unsigned long)(n))>>24)&0x7F)
+/* Status */
+#define DDR0_00_INT_STATUS_MASK 0x00FF0000 /* Read only */
+/* Bit0. A single access outside the defined PHYSICAL memory space detected. */
+#define DDR0_00_INT_STATUS_BIT0 0x00010000
+/* Bit1. Multiple accesses outside the defined PHYSICAL memory space detected. */
+#define DDR0_00_INT_STATUS_BIT1 0x00020000
+/* Bit2. Single correctable ECC event detected */
+#define DDR0_00_INT_STATUS_BIT2 0x00040000
+/* Bit3. Multiple correctable ECC events detected. */
+#define DDR0_00_INT_STATUS_BIT3 0x00080000
+/* Bit4. Single uncorrectable ECC event detected. */
+#define DDR0_00_INT_STATUS_BIT4 0x00100000
+/* Bit5. Multiple uncorrectable ECC events detected. */
+#define DDR0_00_INT_STATUS_BIT5 0x00200000
+/* Bit6. DRAM initialization complete. */
+#define DDR0_00_INT_STATUS_BIT6 0x00400000
+/* Bit7. Logical OR of all lower bits. */
+#define DDR0_00_INT_STATUS_BIT7 0x00800000
+
+#define DDR0_00_INT_STATUS_ENCODE(n) ((((unsigned long)(n))&0xFF)<<16)
+#define DDR0_00_INT_STATUS_DECODE(n) ((((unsigned long)(n))>>16)&0xFF)
+#define DDR0_00_DLL_INCREMENT_MASK 0x00007F00
+#define DDR0_00_DLL_INCREMENT_ENCODE(n) ((((unsigned long)(n))&0x7F)<<8)
+#define DDR0_00_DLL_INCREMENT_DECODE(n) ((((unsigned long)(n))>>8)&0x7F)
+#define DDR0_00_DLL_START_POINT_MASK 0x0000007F
+#define DDR0_00_DLL_START_POINT_ENCODE(n) ((((unsigned long)(n))&0x7F)<<0)
+#define DDR0_00_DLL_START_POINT_DECODE(n) ((((unsigned long)(n))>>0)&0x7F)
+
+
+#define DDR0_01 0x01
+#define DDR0_01_PLB0_DB_CS_LOWER_MASK 0x1F000000
+#define DDR0_01_PLB0_DB_CS_LOWER_ENCODE(n) ((((unsigned long)(n))&0x1F)<<24)
+#define DDR0_01_PLB0_DB_CS_LOWER_DECODE(n) ((((unsigned long)(n))>>24)&0x1F)
+#define DDR0_01_PLB0_DB_CS_UPPER_MASK 0x001F0000
+#define DDR0_01_PLB0_DB_CS_UPPER_ENCODE(n) ((((unsigned long)(n))&0x1F)<<16)
+#define DDR0_01_PLB0_DB_CS_UPPER_DECODE(n) ((((unsigned long)(n))>>16)&0x1F)
+#define DDR0_01_OUT_OF_RANGE_TYPE_MASK 0x00000700 /* Read only */
+#define DDR0_01_OUT_OF_RANGE_TYPE_ENCODE(n) ((((unsigned long)(n))&0x7)<<8)
+#define DDR0_01_OUT_OF_RANGE_TYPE_DECODE(n) ((((unsigned long)(n))>>8)&0x7)
+#define DDR0_01_INT_MASK_MASK 0x000000FF
+#define DDR0_01_INT_MASK_ENCODE(n) ((((unsigned long)(n))&0xFF)<<0)
+#define DDR0_01_INT_MASK_DECODE(n) ((((unsigned long)(n))>>0)&0xFF)
+#define DDR0_01_INT_MASK_ALL_ON 0x000000FF
+#define DDR0_01_INT_MASK_ALL_OFF 0x00000000
+
+#define DDR0_02 0x02
+#define DDR0_02_MAX_CS_REG_MASK 0x02000000 /* Read only */
+#define DDR0_02_MAX_CS_REG_ENCODE(n) ((((unsigned long)(n))&0x2)<<24)
+#define DDR0_02_MAX_CS_REG_DECODE(n) ((((unsigned long)(n))>>24)&0x2)
+#define DDR0_02_MAX_COL_REG_MASK 0x000F0000 /* Read only */
+#define DDR0_02_MAX_COL_REG_ENCODE(n) ((((unsigned long)(n))&0xF)<<16)
+#define DDR0_02_MAX_COL_REG_DECODE(n) ((((unsigned long)(n))>>16)&0xF)
+#define DDR0_02_MAX_ROW_REG_MASK 0x00000F00 /* Read only */
+#define DDR0_02_MAX_ROW_REG_ENCODE(n) ((((unsigned long)(n))&0xF)<<8)
+#define DDR0_02_MAX_ROW_REG_DECODE(n) ((((unsigned long)(n))>>8)&0xF)
+#define DDR0_02_START_MASK 0x00000001
+#define DDR0_02_START_ENCODE(n) ((((unsigned long)(n))&0x1)<<0)
+#define DDR0_02_START_DECODE(n) ((((unsigned long)(n))>>0)&0x1)
+#define DDR0_02_START_OFF 0x00000000
+#define DDR0_02_START_ON 0x00000001
+
+#define DDR0_03 0x03
+#define DDR0_03_BSTLEN_MASK 0x07000000
+#define DDR0_03_BSTLEN_ENCODE(n) ((((unsigned long)(n))&0x7)<<24)
+#define DDR0_03_BSTLEN_DECODE(n) ((((unsigned long)(n))>>24)&0x7)
+#define DDR0_03_CASLAT_MASK 0x00070000
+#define DDR0_03_CASLAT_ENCODE(n) ((((unsigned long)(n))&0x7)<<16)
+#define DDR0_03_CASLAT_DECODE(n) ((((unsigned long)(n))>>16)&0x7)
+#define DDR0_03_CASLAT_LIN_MASK 0x00000F00
+#define DDR0_03_CASLAT_LIN_ENCODE(n) ((((unsigned long)(n))&0xF)<<8)
+#define DDR0_03_CASLAT_LIN_DECODE(n) ((((unsigned long)(n))>>8)&0xF)
+#define DDR0_03_INITAREF_MASK 0x0000000F
+#define DDR0_03_INITAREF_ENCODE(n) ((((unsigned long)(n))&0xF)<<0)
+#define DDR0_03_INITAREF_DECODE(n) ((((unsigned long)(n))>>0)&0xF)
+
+#define DDR0_04 0x04
+#define DDR0_04_TRC_MASK 0x1F000000
+#define DDR0_04_TRC_ENCODE(n) ((((unsigned long)(n))&0x1F)<<24)
+#define DDR0_04_TRC_DECODE(n) ((((unsigned long)(n))>>24)&0x1F)
+#define DDR0_04_TRRD_MASK 0x00070000
+#define DDR0_04_TRRD_ENCODE(n) ((((unsigned long)(n))&0x7)<<16)
+#define DDR0_04_TRRD_DECODE(n) ((((unsigned long)(n))>>16)&0x7)
+#define DDR0_04_TRTP_MASK 0x00000700
+#define DDR0_04_TRTP_ENCODE(n) ((((unsigned long)(n))&0x7)<<8)
+#define DDR0_04_TRTP_DECODE(n) ((((unsigned long)(n))>>8)&0x7)
+
+#define DDR0_05 0x05
+#define DDR0_05_TMRD_MASK 0x1F000000
+#define DDR0_05_TMRD_ENCODE(n) ((((unsigned long)(n))&0x1F)<<24)
+#define DDR0_05_TMRD_DECODE(n) ((((unsigned long)(n))>>24)&0x1F)
+#define DDR0_05_TEMRS_MASK 0x00070000
+#define DDR0_05_TEMRS_ENCODE(n) ((((unsigned long)(n))&0x7)<<16)
+#define DDR0_05_TEMRS_DECODE(n) ((((unsigned long)(n))>>16)&0x7)
+#define DDR0_05_TRP_MASK 0x00000F00
+#define DDR0_05_TRP_ENCODE(n) ((((unsigned long)(n))&0xF)<<8)
+#define DDR0_05_TRP_DECODE(n) ((((unsigned long)(n))>>8)&0xF)
+#define DDR0_05_TRAS_MIN_MASK 0x000000FF
+#define DDR0_05_TRAS_MIN_ENCODE(n) ((((unsigned long)(n))&0xFF)<<0)
+#define DDR0_05_TRAS_MIN_DECODE(n) ((((unsigned long)(n))>>0)&0xFF)
+
+#define DDR0_06 0x06
+#define DDR0_06_WRITEINTERP_MASK 0x01000000
+#define DDR0_06_WRITEINTERP_ENCODE(n) ((((unsigned long)(n))&0x1)<<24)
+#define DDR0_06_WRITEINTERP_DECODE(n) ((((unsigned long)(n))>>24)&0x1)
+#define DDR0_06_TWTR_MASK 0x00070000
+#define DDR0_06_TWTR_ENCODE(n) ((((unsigned long)(n))&0x7)<<16)
+#define DDR0_06_TWTR_DECODE(n) ((((unsigned long)(n))>>16)&0x7)
+#define DDR0_06_TDLL_MASK 0x0000FF00
+#define DDR0_06_TDLL_ENCODE(n) ((((unsigned long)(n))&0xFF)<<8)
+#define DDR0_06_TDLL_DECODE(n) ((((unsigned long)(n))>>8)&0xFF)
+#define DDR0_06_TRFC_MASK 0x0000007F
+#define DDR0_06_TRFC_ENCODE(n) ((((unsigned long)(n))&0x7F)<<0)
+#define DDR0_06_TRFC_DECODE(n) ((((unsigned long)(n))>>0)&0x7F)
+
+#define DDR0_07 0x07
+#define DDR0_07_NO_CMD_INIT_MASK 0x01000000
+#define DDR0_07_NO_CMD_INIT_ENCODE(n) ((((unsigned long)(n))&0x1)<<24)
+#define DDR0_07_NO_CMD_INIT_DECODE(n) ((((unsigned long)(n))>>24)&0x1)
+#define DDR0_07_TFAW_MASK 0x001F0000
+#define DDR0_07_TFAW_ENCODE(n) ((((unsigned long)(n))&0x1F)<<16)
+#define DDR0_07_TFAW_DECODE(n) ((((unsigned long)(n))>>16)&0x1F)
+#define DDR0_07_AUTO_REFRESH_MODE_MASK 0x00000100
+#define DDR0_07_AUTO_REFRESH_MODE_ENCODE(n) ((((unsigned long)(n))&0x1)<<8)
+#define DDR0_07_AUTO_REFRESH_MODE_DECODE(n) ((((unsigned long)(n))>>8)&0x1)
+#define DDR0_07_AREFRESH_MASK 0x00000001
+#define DDR0_07_AREFRESH_ENCODE(n) ((((unsigned long)(n))&0x1)<<0)
+#define DDR0_07_AREFRESH_DECODE(n) ((((unsigned long)(n))>>0)&0x1)
+
+#define DDR0_08 0x08
+#define DDR0_08_WRLAT_MASK 0x07000000
+#define DDR0_08_WRLAT_ENCODE(n) ((((unsigned long)(n))&0x7)<<24)
+#define DDR0_08_WRLAT_DECODE(n) ((((unsigned long)(n))>>24)&0x7)
+#define DDR0_08_TCPD_MASK 0x00FF0000
+#define DDR0_08_TCPD_ENCODE(n) ((((unsigned long)(n))&0xFF)<<16)
+#define DDR0_08_TCPD_DECODE(n) ((((unsigned long)(n))>>16)&0xFF)
+#define DDR0_08_DQS_N_EN_MASK 0x00000100
+#define DDR0_08_DQS_N_EN_ENCODE(n) ((((unsigned long)(n))&0x1)<<8)
+#define DDR0_08_DQS_N_EN_DECODE(n) ((((unsigned long)(n))>>8)&0x1)
+#define DDR0_08_DDRII_SDRAM_MODE_MASK 0x00000001
+#define DDR0_08_DDRII_ENCODE(n) ((((unsigned long)(n))&0x1)<<0)
+#define DDR0_08_DDRII_DECODE(n) ((((unsigned long)(n))>>0)&0x1)
+
+#define DDR0_09 0x09
+#define DDR0_09_OCD_ADJUST_PDN_CS_0_MASK 0x1F000000
+#define DDR0_09_OCD_ADJUST_PDN_CS_0_ENCODE(n) ((((unsigned long)(n))&0x1F)<<24)
+#define DDR0_09_OCD_ADJUST_PDN_CS_0_DECODE(n) ((((unsigned long)(n))>>24)&0x1F)
+#define DDR0_09_RTT_0_MASK 0x00030000
+#define DDR0_09_RTT_0_ENCODE(n) ((((unsigned long)(n))&0x3)<<16)
+#define DDR0_09_RTT_0_DECODE(n) ((((unsigned long)(n))>>16)&0x3)
+#define DDR0_09_WR_DQS_SHIFT_BYPASS_MASK 0x00007F00
+#define DDR0_09_WR_DQS_SHIFT_BYPASS_ENCODE(n) ((((unsigned long)(n))&0x7F)<<8)
+#define DDR0_09_WR_DQS_SHIFT_BYPASS_DECODE(n) ((((unsigned long)(n))>>8)&0x7F)
+#define DDR0_09_WR_DQS_SHIFT_MASK 0x0000007F
+#define DDR0_09_WR_DQS_SHIFT_ENCODE(n) ((((unsigned long)(n))&0x7F)<<0)
+#define DDR0_09_WR_DQS_SHIFT_DECODE(n) ((((unsigned long)(n))>>0)&0x7F)
+
+#define DDR0_10 0x0A
+#define DDR0_10_WRITE_MODEREG_MASK 0x00010000 /* Write only */
+#define DDR0_10_WRITE_MODEREG_ENCODE(n) ((((unsigned long)(n))&0x1)<<16)
+#define DDR0_10_WRITE_MODEREG_DECODE(n) ((((unsigned long)(n))>>16)&0x1)
+#define DDR0_10_CS_MAP_MASK 0x00000300
+#define DDR0_10_CS_MAP_NO_MEM 0x00000000
+#define DDR0_10_CS_MAP_RANK0_INSTALLED 0x00000100
+#define DDR0_10_CS_MAP_RANK1_INSTALLED 0x00000200
+#define DDR0_10_CS_MAP_ENCODE(n) ((((unsigned long)(n))&0x3)<<8)
+#define DDR0_10_CS_MAP_DECODE(n) ((((unsigned long)(n))>>8)&0x3)
+#define DDR0_10_OCD_ADJUST_PUP_CS_0_MASK 0x0000001F
+#define DDR0_10_OCD_ADJUST_PUP_CS_0_ENCODE(n) ((((unsigned long)(n))&0x1F)<<0)
+#define DDR0_10_OCD_ADJUST_PUP_CS_0_DECODE(n) ((((unsigned long)(n))>>0)&0x1F)
+
+#define DDR0_11 0x0B
+#define DDR0_11_SREFRESH_MASK 0x01000000
+#define DDR0_11_SREFRESH_ENCODE(n) ((((unsigned long)(n))&0x1)<<24)
+#define DDR0_11_SREFRESH_DECODE(n) ((((unsigned long)(n))>>24)&0x1F)
+#define DDR0_11_TXSNR_MASK 0x00FF0000
+#define DDR0_11_TXSNR_ENCODE(n) ((((unsigned long)(n))&0xFF)<<16)
+#define DDR0_11_TXSNR_DECODE(n) ((((unsigned long)(n))>>16)&0xFF)
+#define DDR0_11_TXSR_MASK 0x0000FF00
+#define DDR0_11_TXSR_ENCODE(n) ((((unsigned long)(n))&0xFF)<<8)
+#define DDR0_11_TXSR_DECODE(n) ((((unsigned long)(n))>>8)&0xFF)
+
+#define DDR0_12 0x0C
+#define DDR0_12_TCKE_MASK 0x0000007
+#define DDR0_12_TCKE_ENCODE(n) ((((unsigned long)(n))&0x7)<<0)
+#define DDR0_12_TCKE_DECODE(n) ((((unsigned long)(n))>>0)&0x7)
+
+#define DDR0_13 0x0D
+
+#define DDR0_14 0x0E
+#define DDR0_14_DLL_BYPASS_MODE_MASK 0x01000000
+#define DDR0_14_DLL_BYPASS_MODE_ENCODE(n) ((((unsigned long)(n))&0x1)<<24)
+#define DDR0_14_DLL_BYPASS_MODE_DECODE(n) ((((unsigned long)(n))>>24)&0x1)
+#define DDR0_14_REDUC_MASK 0x00010000
+#define DDR0_14_REDUC_64BITS 0x00000000
+#define DDR0_14_REDUC_32BITS 0x00010000
+#define DDR0_14_REDUC_ENCODE(n) ((((unsigned long)(n))&0x1)<<16)
+#define DDR0_14_REDUC_DECODE(n) ((((unsigned long)(n))>>16)&0x1)
+#define DDR0_14_REG_DIMM_ENABLE_MASK 0x00000100
+#define DDR0_14_REG_DIMM_ENABLE_ENCODE(n) ((((unsigned long)(n))&0x1)<<8)
+#define DDR0_14_REG_DIMM_ENABLE_DECODE(n) ((((unsigned long)(n))>>8)&0x1)
+
+#define DDR0_15 0x0F
+
+#define DDR0_16 0x10
+
+#define DDR0_17 0x11
+#define DDR0_17_DLL_DQS_DELAY_0_MASK 0x7F000000
+#define DDR0_17_DLL_DQS_DELAY_0_ENCODE(n) ((((unsigned long)(n))&0x7F)<<24)
+#define DDR0_17_DLL_DQS_DELAY_0_DECODE(n) ((((unsigned long)(n))>>24)&0x7F)
+#define DDR0_17_DLLLOCKREG_MASK 0x00010000 /* Read only */
+#define DDR0_17_DLLLOCKREG_LOCKED 0x00010000
+#define DDR0_17_DLLLOCKREG_UNLOCKED 0x00000000
+#define DDR0_17_DLLLOCKREG_ENCODE(n) ((((unsigned long)(n))&0x1)<<16)
+#define DDR0_17_DLLLOCKREG_DECODE(n) ((((unsigned long)(n))>>16)&0x1)
+#define DDR0_17_DLL_LOCK_MASK 0x00007F00 /* Read only */
+#define DDR0_17_DLL_LOCK_ENCODE(n) ((((unsigned long)(n))&0x7F)<<8)
+#define DDR0_17_DLL_LOCK_DECODE(n) ((((unsigned long)(n))>>8)&0x7F)
+
+#define DDR0_18 0x12
+#define DDR0_18_DLL_DQS_DELAY_X_MASK 0x7F7F7F7F
+#define DDR0_18_DLL_DQS_DELAY_4_MASK 0x7F000000
+#define DDR0_18_DLL_DQS_DELAY_4_ENCODE(n) ((((unsigned long)(n))&0x7F)<<24)
+#define DDR0_18_DLL_DQS_DELAY_4_DECODE(n) ((((unsigned long)(n))>>24)&0x7F)
+#define DDR0_18_DLL_DQS_DELAY_3_MASK 0x007F0000
+#define DDR0_18_DLL_DQS_DELAY_3_ENCODE(n) ((((unsigned long)(n))&0x7F)<<16)
+#define DDR0_18_DLL_DQS_DELAY_3_DECODE(n) ((((unsigned long)(n))>>16)&0x7F)
+#define DDR0_18_DLL_DQS_DELAY_2_MASK 0x00007F00
+#define DDR0_18_DLL_DQS_DELAY_2_ENCODE(n) ((((unsigned long)(n))&0x7F)<<8)
+#define DDR0_18_DLL_DQS_DELAY_2_DECODE(n) ((((unsigned long)(n))>>8)&0x7F)
+#define DDR0_18_DLL_DQS_DELAY_1_MASK 0x0000007F
+#define DDR0_18_DLL_DQS_DELAY_1_ENCODE(n) ((((unsigned long)(n))&0x7F)<<0)
+#define DDR0_18_DLL_DQS_DELAY_1_DECODE(n) ((((unsigned long)(n))>>0)&0x7F)
+
+#define DDR0_19 0x13
+#define DDR0_19_DLL_DQS_DELAY_X_MASK 0x7F7F7F7F
+#define DDR0_19_DLL_DQS_DELAY_8_MASK 0x7F000000
+#define DDR0_19_DLL_DQS_DELAY_8_ENCODE(n) ((((unsigned long)(n))&0x7F)<<24)
+#define DDR0_19_DLL_DQS_DELAY_8_DECODE(n) ((((unsigned long)(n))>>24)&0x7F)
+#define DDR0_19_DLL_DQS_DELAY_7_MASK 0x007F0000
+#define DDR0_19_DLL_DQS_DELAY_7_ENCODE(n) ((((unsigned long)(n))&0x7F)<<16)
+#define DDR0_19_DLL_DQS_DELAY_7_DECODE(n) ((((unsigned long)(n))>>16)&0x7F)
+#define DDR0_19_DLL_DQS_DELAY_6_MASK 0x00007F00
+#define DDR0_19_DLL_DQS_DELAY_6_ENCODE(n) ((((unsigned long)(n))&0x7F)<<8)
+#define DDR0_19_DLL_DQS_DELAY_6_DECODE(n) ((((unsigned long)(n))>>8)&0x7F)
+#define DDR0_19_DLL_DQS_DELAY_5_MASK 0x0000007F
+#define DDR0_19_DLL_DQS_DELAY_5_ENCODE(n) ((((unsigned long)(n))&0x7F)<<0)
+#define DDR0_19_DLL_DQS_DELAY_5_DECODE(n) ((((unsigned long)(n))>>0)&0x7F)
+
+#define DDR0_20 0x14
+#define DDR0_20_DLL_DQS_BYPASS_3_MASK 0x7F000000
+#define DDR0_20_DLL_DQS_BYPASS_3_ENCODE(n) ((((unsigned long)(n))&0x7F)<<24)
+#define DDR0_20_DLL_DQS_BYPASS_3_DECODE(n) ((((unsigned long)(n))>>24)&0x7F)
+#define DDR0_20_DLL_DQS_BYPASS_2_MASK 0x007F0000
+#define DDR0_20_DLL_DQS_BYPASS_2_ENCODE(n) ((((unsigned long)(n))&0x7F)<<16)
+#define DDR0_20_DLL_DQS_BYPASS_2_DECODE(n) ((((unsigned long)(n))>>16)&0x7F)
+#define DDR0_20_DLL_DQS_BYPASS_1_MASK 0x00007F00
+#define DDR0_20_DLL_DQS_BYPASS_1_ENCODE(n) ((((unsigned long)(n))&0x7F)<<8)
+#define DDR0_20_DLL_DQS_BYPASS_1_DECODE(n) ((((unsigned long)(n))>>8)&0x7F)
+#define DDR0_20_DLL_DQS_BYPASS_0_MASK 0x0000007F
+#define DDR0_20_DLL_DQS_BYPASS_0_ENCODE(n) ((((unsigned long)(n))&0x7F)<<0)
+#define DDR0_20_DLL_DQS_BYPASS_0_DECODE(n) ((((unsigned long)(n))>>0)&0x7F)
+
+#define DDR0_21 0x15
+#define DDR0_21_DLL_DQS_BYPASS_7_MASK 0x7F000000
+#define DDR0_21_DLL_DQS_BYPASS_7_ENCODE(n) ((((unsigned long)(n))&0x7F)<<24)
+#define DDR0_21_DLL_DQS_BYPASS_7_DECODE(n) ((((unsigned long)(n))>>24)&0x7F)
+#define DDR0_21_DLL_DQS_BYPASS_6_MASK 0x007F0000
+#define DDR0_21_DLL_DQS_BYPASS_6_ENCODE(n) ((((unsigned long)(n))&0x7F)<<16)
+#define DDR0_21_DLL_DQS_BYPASS_6_DECODE(n) ((((unsigned long)(n))>>16)&0x7F)
+#define DDR0_21_DLL_DQS_BYPASS_5_MASK 0x00007F00
+#define DDR0_21_DLL_DQS_BYPASS_5_ENCODE(n) ((((unsigned long)(n))&0x7F)<<8)
+#define DDR0_21_DLL_DQS_BYPASS_5_DECODE(n) ((((unsigned long)(n))>>8)&0x7F)
+#define DDR0_21_DLL_DQS_BYPASS_4_MASK 0x0000007F
+#define DDR0_21_DLL_DQS_BYPASS_4_ENCODE(n) ((((unsigned long)(n))&0x7F)<<0)
+#define DDR0_21_DLL_DQS_BYPASS_4_DECODE(n) ((((unsigned long)(n))>>0)&0x7F)
+
+#define DDR0_22 0x16
+/* ECC */
+#define DDR0_22_CTRL_RAW_MASK 0x03000000
+#define DDR0_22_CTRL_RAW_ECC_DISABLE 0x00000000 /* ECC not being used */
+#define DDR0_22_CTRL_RAW_ECC_CHECK_ONLY 0x01000000 /* ECC checking is on, but no attempts to correct*/
+#define DDR0_22_CTRL_RAW_NO_ECC_RAM 0x02000000 /* No ECC RAM storage available */
+#define DDR0_22_CTRL_RAW_ECC_ENABLE 0x03000000 /* ECC checking and correcting on */
+#define DDR0_22_CTRL_RAW_ENCODE(n) ((((unsigned long)(n))&0x3)<<24)
+#define DDR0_22_CTRL_RAW_DECODE(n) ((((unsigned long)(n))>>24)&0x3)
+
+#define DDR0_22_DQS_OUT_SHIFT_BYPASS_MASK 0x007F0000
+#define DDR0_22_DQS_OUT_SHIFT_BYPASS_ENCODE(n) ((((unsigned long)(n))&0x7F)<<16)
+#define DDR0_22_DQS_OUT_SHIFT_BYPASS_DECODE(n) ((((unsigned long)(n))>>16)&0x7F)
+#define DDR0_22_DQS_OUT_SHIFT_MASK 0x00007F00
+#define DDR0_22_DQS_OUT_SHIFT_ENCODE(n) ((((unsigned long)(n))&0x7F)<<8)
+#define DDR0_22_DQS_OUT_SHIFT_DECODE(n) ((((unsigned long)(n))>>8)&0x7F)
+#define DDR0_22_DLL_DQS_BYPASS_8_MASK 0x0000007F
+#define DDR0_22_DLL_DQS_BYPASS_8_ENCODE(n) ((((unsigned long)(n))&0x7F)<<0)
+#define DDR0_22_DLL_DQS_BYPASS_8_DECODE(n) ((((unsigned long)(n))>>0)&0x7F)
+
+
+#define DDR0_23 0x17
+#define DDR0_23_ODT_RD_MAP_CS0_MASK 0x03000000
+#define DDR0_23_ODT_RD_MAP_CS0_ENCODE(n) ((((unsigned long)(n))&0x3)<<24)
+#define DDR0_23_ODT_RD_MAP_CS0_DECODE(n) ((((unsigned long)(n))>>24)&0x3)
+#define DDR0_23_ECC_C_SYND_MASK 0x00FF0000 /* Read only */
+#define DDR0_23_ECC_C_SYND_ENCODE(n) ((((unsigned long)(n))&0xFF)<<16)
+#define DDR0_23_ECC_C_SYND_DECODE(n) ((((unsigned long)(n))>>16)&0xFF)
+#define DDR0_23_ECC_U_SYND_MASK 0x0000FF00 /* Read only */
+#define DDR0_23_ECC_U_SYND_ENCODE(n) ((((unsigned long)(n))&0xFF)<<8)
+#define DDR0_23_ECC_U_SYND_DECODE(n) ((((unsigned long)(n))>>8)&0xFF)
+#define DDR0_23_FWC_MASK 0x00000001 /* Write only */
+#define DDR0_23_FWC_ENCODE(n) ((((unsigned long)(n))&0x1)<<0)
+#define DDR0_23_FWC_DECODE(n) ((((unsigned long)(n))>>0)&0x1)
+
+#define DDR0_24 0x18
+#define DDR0_24_RTT_PAD_TERMINATION_MASK 0x03000000
+#define DDR0_24_RTT_PAD_TERMINATION_ENCODE(n) ((((unsigned long)(n))&0x3)<<24)
+#define DDR0_24_RTT_PAD_TERMINATION_DECODE(n) ((((unsigned long)(n))>>24)&0x3)
+#define DDR0_24_ODT_WR_MAP_CS1_MASK 0x00030000
+#define DDR0_24_ODT_WR_MAP_CS1_ENCODE(n) ((((unsigned long)(n))&0x3)<<16)
+#define DDR0_24_ODT_WR_MAP_CS1_DECODE(n) ((((unsigned long)(n))>>16)&0x3)
+#define DDR0_24_ODT_RD_MAP_CS1_MASK 0x00000300
+#define DDR0_24_ODT_RD_MAP_CS1_ENCODE(n) ((((unsigned long)(n))&0x3)<<8)
+#define DDR0_24_ODT_RD_MAP_CS1_DECODE(n) ((((unsigned long)(n))>>8)&0x3)
+#define DDR0_24_ODT_WR_MAP_CS0_MASK 0x00000003
+#define DDR0_24_ODT_WR_MAP_CS0_ENCODE(n) ((((unsigned long)(n))&0x3)<<0)
+#define DDR0_24_ODT_WR_MAP_CS0_DECODE(n) ((((unsigned long)(n))>>0)&0x3)
+
+#define DDR0_25 0x19
+#define DDR0_25_VERSION_MASK 0xFFFF0000 /* Read only */
+#define DDR0_25_VERSION_ENCODE(n) ((((unsigned long)(n))&0xFFFF)<<16)
+#define DDR0_25_VERSION_DECODE(n) ((((unsigned long)(n))>>16)&0xFFFF)
+#define DDR0_25_OUT_OF_RANGE_LENGTH_MASK 0x000003FF /* Read only */
+#define DDR0_25_OUT_OF_RANGE_LENGTH_ENCODE(n) ((((unsigned long)(n))&0x3FF)<<0)
+#define DDR0_25_OUT_OF_RANGE_LENGTH_DECODE(n) ((((unsigned long)(n))>>0)&0x3FF)
+
+#define DDR0_26 0x1A
+#define DDR0_26_TRAS_MAX_MASK 0xFFFF0000
+#define DDR0_26_TRAS_MAX_ENCODE(n) ((((unsigned long)(n))&0xFFFF)<<16)
+#define DDR0_26_TRAS_MAX_DECODE(n) ((((unsigned long)(n))>>16)&0xFFFF)
+#define DDR0_26_TREF_MASK 0x00003FFF
+#define DDR0_26_TREF_ENCODE(n) ((((unsigned long)(n))&0x3FF)<<0)
+#define DDR0_26_TREF_DECODE(n) ((((unsigned long)(n))>>0)&0x3FF)
+
+#define DDR0_27 0x1B
+#define DDR0_27_EMRS_DATA_MASK 0x3FFF0000
+#define DDR0_27_EMRS_DATA_ENCODE(n) ((((unsigned long)(n))&0x3FFF)<<16)
+#define DDR0_27_EMRS_DATA_DECODE(n) ((((unsigned long)(n))>>16)&0x3FFF)
+#define DDR0_27_TINIT_MASK 0x0000FFFF
+#define DDR0_27_TINIT_ENCODE(n) ((((unsigned long)(n))&0xFFFF)<<0)
+#define DDR0_27_TINIT_DECODE(n) ((((unsigned long)(n))>>0)&0xFFFF)
+
+#define DDR0_28 0x1C
+#define DDR0_28_EMRS3_DATA_MASK 0x3FFF0000
+#define DDR0_28_EMRS3_DATA_ENCODE(n) ((((unsigned long)(n))&0x3FFF)<<16)
+#define DDR0_28_EMRS3_DATA_DECODE(n) ((((unsigned long)(n))>>16)&0x3FFF)
+#define DDR0_28_EMRS2_DATA_MASK 0x00003FFF
+#define DDR0_28_EMRS2_DATA_ENCODE(n) ((((unsigned long)(n))&0x3FFF)<<0)
+#define DDR0_28_EMRS2_DATA_DECODE(n) ((((unsigned long)(n))>>0)&0x3FFF)
+
+#define DDR0_29 0x1D
+
+#define DDR0_30 0x1E
+
+#define DDR0_31 0x1F
+#define DDR0_31_XOR_CHECK_BITS_MASK 0x0000FFFF
+#define DDR0_31_XOR_CHECK_BITS_ENCODE(n) ((((unsigned long)(n))&0xFFFF)<<0)
+#define DDR0_31_XOR_CHECK_BITS_DECODE(n) ((((unsigned long)(n))>>0)&0xFFFF)
+
+#define DDR0_32 0x20
+#define DDR0_32_OUT_OF_RANGE_ADDR_MASK 0xFFFFFFFF /* Read only */
+#define DDR0_32_OUT_OF_RANGE_ADDR_ENCODE(n) ((((unsigned long)(n))&0xFFFFFFFF)<<0)
+#define DDR0_32_OUT_OF_RANGE_ADDR_DECODE(n) ((((unsigned long)(n))>>0)&0xFFFFFFFF)
+
+#define DDR0_33 0x21
+#define DDR0_33_OUT_OF_RANGE_ADDR_MASK 0x00000001 /* Read only */
+#define DDR0_33_OUT_OF_RANGE_ADDR_ENCODE(n) ((((unsigned long)(n))&0x1)<<0)
+#define DDR0_33_OUT_OF_RANGE_ADDR_DECODE(n) ((((unsigned long)(n))>>0)&0x1)
+
+#define DDR0_34 0x22
+#define DDR0_34_ECC_U_ADDR_MASK 0xFFFFFFFF /* Read only */
+#define DDR0_34_ECC_U_ADDR_ENCODE(n) ((((unsigned long)(n))&0xFFFFFFFF)<<0)
+#define DDR0_34_ECC_U_ADDR_DECODE(n) ((((unsigned long)(n))>>0)&0xFFFFFFFF)
+
+#define DDR0_35 0x23
+#define DDR0_35_ECC_U_ADDR_MASK 0x00000001 /* Read only */
+#define DDR0_35_ECC_U_ADDR_ENCODE(n) ((((unsigned long)(n))&0x1)<<0)
+#define DDR0_35_ECC_U_ADDR_DECODE(n) ((((unsigned long)(n))>>0)&0x1)
+
+#define DDR0_36 0x24
+#define DDR0_36_ECC_U_DATA_MASK 0xFFFFFFFF /* Read only */
+#define DDR0_36_ECC_U_DATA_ENCODE(n) ((((unsigned long)(n))&0xFFFFFFFF)<<0)
+#define DDR0_36_ECC_U_DATA_DECODE(n) ((((unsigned long)(n))>>0)&0xFFFFFFFF)
+
+#define DDR0_37 0x25
+#define DDR0_37_ECC_U_DATA_MASK 0xFFFFFFFF /* Read only */
+#define DDR0_37_ECC_U_DATA_ENCODE(n) ((((unsigned long)(n))&0xFFFFFFFF)<<0)
+#define DDR0_37_ECC_U_DATA_DECODE(n) ((((unsigned long)(n))>>0)&0xFFFFFFFF)
+
+#define DDR0_38 0x26
+#define DDR0_38_ECC_C_ADDR_MASK 0xFFFFFFFF /* Read only */
+#define DDR0_38_ECC_C_ADDR_ENCODE(n) ((((unsigned long)(n))&0xFFFFFFFF)<<0)
+#define DDR0_38_ECC_C_ADDR_DECODE(n) ((((unsigned long)(n))>>0)&0xFFFFFFFF)
+
+#define DDR0_39 0x27
+#define DDR0_39_ECC_C_ADDR_MASK 0x00000001 /* Read only */
+#define DDR0_39_ECC_C_ADDR_ENCODE(n) ((((unsigned long)(n))&0x1)<<0)
+#define DDR0_39_ECC_C_ADDR_DECODE(n) ((((unsigned long)(n))>>0)&0x1)
+
+#define DDR0_40 0x28
+#define DDR0_40_ECC_C_DATA_MASK 0xFFFFFFFF /* Read only */
+#define DDR0_40_ECC_C_DATA_ENCODE(n) ((((unsigned long)(n))&0xFFFFFFFF)<<0)
+#define DDR0_40_ECC_C_DATA_DECODE(n) ((((unsigned long)(n))>>0)&0xFFFFFFFF)
+
+#define DDR0_41 0x29
+#define DDR0_41_ECC_C_DATA_MASK 0xFFFFFFFF /* Read only */
+#define DDR0_41_ECC_C_DATA_ENCODE(n) ((((unsigned long)(n))&0xFFFFFFFF)<<0)
+#define DDR0_41_ECC_C_DATA_DECODE(n) ((((unsigned long)(n))>>0)&0xFFFFFFFF)
+
+#define DDR0_42 0x2A
+#define DDR0_42_ADDR_PINS_MASK 0x07000000
+#define DDR0_42_ADDR_PINS_ENCODE(n) ((((unsigned long)(n))&0x7)<<24)
+#define DDR0_42_ADDR_PINS_DECODE(n) ((((unsigned long)(n))>>24)&0x7)
+#define DDR0_42_CASLAT_LIN_GATE_MASK 0x0000000F
+#define DDR0_42_CASLAT_LIN_GATE_ENCODE(n) ((((unsigned long)(n))&0xF)<<0)
+#define DDR0_42_CASLAT_LIN_GATE_DECODE(n) ((((unsigned long)(n))>>0)&0xF)
+
+#define DDR0_43 0x2B
+#define DDR0_43_TWR_MASK 0x07000000
+#define DDR0_43_TWR_ENCODE(n) ((((unsigned long)(n))&0x7)<<24)
+#define DDR0_43_TWR_DECODE(n) ((((unsigned long)(n))>>24)&0x7)
+#define DDR0_43_APREBIT_MASK 0x000F0000
+#define DDR0_43_APREBIT_ENCODE(n) ((((unsigned long)(n))&0xF)<<16)
+#define DDR0_43_APREBIT_DECODE(n) ((((unsigned long)(n))>>16)&0xF)
+#define DDR0_43_COLUMN_SIZE_MASK 0x00000700
+#define DDR0_43_COLUMN_SIZE_ENCODE(n) ((((unsigned long)(n))&0x7)<<8)
+#define DDR0_43_COLUMN_SIZE_DECODE(n) ((((unsigned long)(n))>>8)&0x7)
+#define DDR0_43_EIGHT_BANK_MODE_MASK 0x00000001
+#define DDR0_43_EIGHT_BANK_MODE_8_BANKS 0x00000001
+#define DDR0_43_EIGHT_BANK_MODE_4_BANKS 0x00000000
+#define DDR0_43_EIGHT_BANK_MODE_ENCODE(n) ((((unsigned long)(n))&0x1)<<0)
+#define DDR0_43_EIGHT_BANK_MODE_DECODE(n) ((((unsigned long)(n))>>0)&0x1)
+
+#define DDR0_44 0x2C
+#define DDR0_44_TRCD_MASK 0x000000FF
+#define DDR0_44_TRCD_ENCODE(n) ((((unsigned long)(n))&0xFF)<<0)
+#define DDR0_44_TRCD_DECODE(n) ((((unsigned long)(n))>>0)&0xFF)
+
+#endif /* _SPD_SDRAM_DENALI_H_ */
diff --git a/board/amcc/sequoia/sequoia.c b/board/amcc/sequoia/sequoia.c
index ccf6f0c8039..daaffe06d35 100644
--- a/board/amcc/sequoia/sequoia.c
+++ b/board/amcc/sequoia/sequoia.c
@@ -31,11 +31,13 @@ DECLARE_GLOBAL_DATA_PTR;
extern flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */
+ulong flash_get_size (ulong base, int banknum);
+
int board_early_init_f(void)
{
- unsigned long sdr0_cust0;
- unsigned long sdr0_pfc1, sdr0_pfc2;
- register uint reg;
+ u32 sdr0_cust0;
+ u32 sdr0_pfc1, sdr0_pfc2;
+ u32 reg;
mtdcr(ebccfga, xbcfg);
mtdcr(ebccfgd, 0xb8400000);
@@ -140,6 +142,7 @@ int misc_init_r(void)
{
uint pbcr;
int size_val = 0;
+ u32 reg;
#ifdef CONFIG_440EPX
unsigned long usb2d0cr = 0;
unsigned long usb2phy0cr, usb2h0cr = 0;
@@ -152,6 +155,11 @@ int misc_init_r(void)
*/
/* Re-do sizing to get full correct info */
+
+ /* adjust flash start and offset */
+ gd->bd->bi_flashstart = 0 - gd->bd->bi_flashsize;
+ gd->bd->bi_flashoffset = 0;
+
#if defined(CONFIG_NAND_U_BOOT) || defined(CONFIG_NAND_SPL)
mtdcr(ebccfga, pb3cr);
#else
@@ -192,9 +200,10 @@ int misc_init_r(void)
#endif
mtdcr(ebccfgd, pbcr);
- /* adjust flash start and offset */
- gd->bd->bi_flashstart = 0 - gd->bd->bi_flashsize;
- gd->bd->bi_flashoffset = 0;
+ /*
+ * Re-check to get correct base address
+ */
+ flash_get_size(gd->bd->bi_flashstart, 0);
#ifdef CFG_ENV_IS_IN_FLASH
/* Monitor protection ON by default */
@@ -327,18 +336,37 @@ int misc_init_r(void)
}
#endif /* CONFIG_440EPX */
+ mfsdr(SDR0_SRST1, reg); /* enable security/kasumi engines */
+ reg &= ~(SDR0_SRST1_CRYP0 | SDR0_SRST1_KASU0);
+ mtsdr(SDR0_SRST1, reg);
+
+ /*
+ * Clear PLB4A0_ACR[WRP]
+ * This fix will make the MAL burst disabling patch for the Linux
+ * EMAC driver obsolete.
+ */
+ reg = mfdcr(plb4_acr) & ~PLB4_ACR_WRP;
+ mtdcr(plb4_acr, reg);
+
return 0;
}
int checkboard(void)
{
char *s = getenv("serial#");
+ u8 rev;
+ u8 val;
#ifdef CONFIG_440EPX
printf("Board: Sequoia - AMCC PPC440EPx Evaluation Board");
#else
printf("Board: Rainier - AMCC PPC440GRx Evaluation Board");
#endif
+
+ 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);
diff --git a/board/amcc/yellowstone/Makefile b/board/amcc/taishan/Makefile
index 261e5d49cca..462af001b48 100644
--- a/board/amcc/yellowstone/Makefile
+++ b/board/amcc/taishan/Makefile
@@ -1,5 +1,5 @@
#
-# (C) Copyright 2002-2006
+# (C) Copyright 2007
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
#
# See file CREDITS for list of people who contributed to this
@@ -25,7 +25,7 @@ include $(TOPDIR)/config.mk
LIB = $(obj)lib$(BOARD).a
-COBJS = $(BOARD).o
+COBJS = $(BOARD).o lcd.o update.o showinfo.o
SOBJS = init.o
SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
diff --git a/board/amcc/taishan/config.mk b/board/amcc/taishan/config.mk
new file mode 100644
index 00000000000..4eefff21dd7
--- /dev/null
+++ b/board/amcc/taishan/config.mk
@@ -0,0 +1,44 @@
+#
+# (C) Copyright 2004
+# 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
+#
+
+#
+# AMCC 440GX Reference Platform (Taishan) board
+#
+
+#TEXT_BASE = 0xFFFE0000
+
+ifeq ($(ramsym),1)
+TEXT_BASE = 0x07FD0000
+else
+TEXT_BASE = 0xFFFC0000
+endif
+
+PLATFORM_CPPFLAGS += -DCONFIG_440=1
+
+ifeq ($(debug),1)
+PLATFORM_CPPFLAGS += -DDEBUG
+endif
+
+ifeq ($(dbcr),1)
+PLATFORM_CPPFLAGS += -DCFG_INIT_DBCR=0x8cff0000
+endif
diff --git a/board/amcc/taishan/init.S b/board/amcc/taishan/init.S
new file mode 100644
index 00000000000..8db043ba181
--- /dev/null
+++ b/board/amcc/taishan/init.S
@@ -0,0 +1,97 @@
+/*
+ * (C) Copyright 2007
+ * Stefan Roese, DENX Software Engineering, sr@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <ppc_asm.tmpl>
+#include <config.h>
+
+/* General */
+#define TLB_VALID 0x00000200
+#define _256M 0x10000000
+
+/* 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
+ tlbentry( 0xf0000000, SZ_256M, 0xf0000000, 1, AC_R|AC_W|AC_X|SA_G|SA_I)
+ tlbentry( CFG_PERIPHERAL_BASE, SZ_256M, 0x40000000, 1, AC_R|AC_W|SA_G|SA_I)
+ tlbentry( CFG_ISRAM_BASE, SZ_256K, 0x80000000, 0, AC_R|AC_W|AC_X )
+ tlbentry( CFG_SDRAM_BASE, SZ_256M, 0x00000000, 0, AC_R|AC_W|AC_X|SA_G|SA_I )
+ tlbentry( CFG_PCI_BASE, SZ_256M, 0x00000000, 2, AC_R|AC_W|SA_G|SA_I )
+ tlbentry( CFG_PCI_MEMBASE, SZ_256M, 0x00000000, 3, AC_R|AC_W|SA_G|SA_I )
+ tlbtab_end
diff --git a/board/amcc/taishan/lcd.c b/board/amcc/taishan/lcd.c
new file mode 100644
index 00000000000..8d2dce35ca4
--- /dev/null
+++ b/board/amcc/taishan/lcd.c
@@ -0,0 +1,380 @@
+/*
+ * (C) Copyright 2007
+ * Stefan Roese, DENX Software Engineering, sr@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <config.h>
+#include <common.h>
+#include <command.h>
+#include <i2c.h>
+#include <miiphy.h>
+
+#ifdef CONFIG_TAISHAN
+
+#define LCD_DELAY_NORMAL_US 100
+#define LCD_DELAY_NORMAL_MS 2
+#define LCD_CMD_ADDR ((volatile char *)(CFG_EBC2_LCM_BASE))
+#define LCD_DATA_ADDR ((volatile char *)(CFG_EBC2_LCM_BASE+1))
+#define LCD_BLK_CTRL ((volatile char *)(CFG_EBC1_FPGA_BASE+0x2))
+
+#define mdelay(t) ({unsigned long msec=(t); while (msec--) { udelay(1000);}})
+
+static int g_lcd_init_b = 0;
+static char *amcc_logo = " AMCC TAISHAN 440GX EvalBoard";
+static char addr_flag = 0x80;
+
+static void lcd_bl_ctrl(char val)
+{
+ char cpld_val;
+
+ cpld_val = *LCD_BLK_CTRL;
+ *LCD_BLK_CTRL = val | cpld_val;
+}
+
+static void lcd_putc(char val)
+{
+ int i = 100;
+ char addr;
+
+ while (i--) {
+ if ((*LCD_CMD_ADDR & 0x80) != 0x80) { /*BF = 1 ? */
+ udelay(LCD_DELAY_NORMAL_US);
+ break;
+ }
+ udelay(LCD_DELAY_NORMAL_US);
+ }
+
+ if (*LCD_CMD_ADDR & 0x80) {
+ printf("LCD is busy\n");
+ return;
+ }
+
+ addr = *LCD_CMD_ADDR;
+ udelay(LCD_DELAY_NORMAL_US);
+ if ((addr != 0) && (addr % 0x10 == 0)) {
+ addr_flag ^= 0x40;
+ *LCD_CMD_ADDR = addr_flag;
+ }
+
+ udelay(LCD_DELAY_NORMAL_US);
+ *LCD_DATA_ADDR = val;
+ udelay(LCD_DELAY_NORMAL_US);
+}
+
+static void lcd_puts(char *s)
+{
+ char *p = s;
+ int i = 100;
+
+ while (i--) {
+ if ((*LCD_CMD_ADDR & 0x80) != 0x80) { /*BF = 1 ? */
+ udelay(LCD_DELAY_NORMAL_US);
+ break;
+ }
+ udelay(LCD_DELAY_NORMAL_US);
+ }
+
+ if (*LCD_CMD_ADDR & 0x80) {
+ printf("LCD is busy\n");
+ return;
+ }
+
+ while (*p)
+ lcd_putc(*p++);
+}
+
+static void lcd_put_logo(void)
+{
+ int i = 100;
+ char *p = amcc_logo;
+
+ while (i--) {
+ if ((*LCD_CMD_ADDR & 0x80) != 0x80) { /*BF = 1 ? */
+ udelay(LCD_DELAY_NORMAL_US);
+ break;
+ }
+ udelay(LCD_DELAY_NORMAL_US);
+ }
+
+ if (*LCD_CMD_ADDR & 0x80) {
+ printf("LCD is busy\n");
+ return;
+ }
+
+ *LCD_CMD_ADDR = 0x80;
+ while (*p)
+ lcd_putc(*p++);
+}
+
+int lcd_init(void)
+{
+ if (g_lcd_init_b == 0) {
+ puts("LCD: ");
+ mdelay(100); /* Waiting for the LCD initialize */
+
+ *LCD_CMD_ADDR = 0x38; /*set function:8-bit,2-line,5x7 font type */
+ udelay(LCD_DELAY_NORMAL_US);
+
+ *LCD_CMD_ADDR = 0x0f; /*set display on,cursor on,blink on */
+ udelay(LCD_DELAY_NORMAL_US);
+
+ *LCD_CMD_ADDR = 0x01; /*display clear */
+ mdelay(LCD_DELAY_NORMAL_MS);
+
+ *LCD_CMD_ADDR = 0x06; /*set entry */
+ udelay(LCD_DELAY_NORMAL_US);
+
+ lcd_bl_ctrl(0x02);
+ lcd_put_logo();
+
+ puts(" ready\n");
+ g_lcd_init_b = 1;
+ }
+
+ return 0;
+}
+
+static int do_lcd_test(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
+{
+ lcd_init();
+ return 0;
+}
+
+static int do_lcd_clear(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
+{
+ *LCD_CMD_ADDR = 0x01;
+ mdelay(LCD_DELAY_NORMAL_MS);
+ return 0;
+}
+static int do_lcd_puts(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
+{
+ if (argc < 2) {
+ printf("%s", cmdtp->usage);
+ return 1;
+ }
+ lcd_puts(argv[1]);
+ return 0;
+}
+static int do_lcd_putc(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
+{
+ if (argc < 2) {
+ printf("%s", cmdtp->usage);
+ return 1;
+ }
+ lcd_putc((char)argv[1][0]);
+ return 0;
+}
+static int do_lcd_cur(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
+{
+ ulong count;
+ ulong dir;
+ char cur_addr;
+
+ if (argc < 3) {
+ printf("%s", cmdtp->usage);
+ return 1;
+ }
+
+ count = simple_strtoul(argv[1], NULL, 16);
+ if (count > 31) {
+ printf("unable to shift > 0x20\n");
+ count = 0;
+ }
+
+ dir = simple_strtoul(argv[2], NULL, 16);
+ cur_addr = *LCD_CMD_ADDR;
+ udelay(LCD_DELAY_NORMAL_US);
+ if (dir == 0x0) {
+ if (addr_flag == 0x80) {
+ if (count >= (cur_addr & 0xf)) {
+ *LCD_CMD_ADDR = 0x80;
+ udelay(LCD_DELAY_NORMAL_US);
+ count = 0;
+ }
+ } else {
+ if (count >= ((cur_addr & 0x0f) + 0x0f)) {
+ *LCD_CMD_ADDR = 0x80;
+ addr_flag = 0x80;
+ udelay(LCD_DELAY_NORMAL_US);
+ count = 0x0;
+ } else if (count >= (cur_addr & 0xf)) {
+ count -= cur_addr & 0xf;
+ *LCD_CMD_ADDR = 0x80 | 0xf;
+ addr_flag = 0x80;
+ udelay(LCD_DELAY_NORMAL_US);
+ }
+ }
+ } else {
+ if (addr_flag == 0x80) {
+ if (count >= (0x1f - (cur_addr & 0xf))) {
+ count = 0x0;
+ addr_flag = 0xc0;
+ *LCD_CMD_ADDR = 0xc0 | 0xf;
+ udelay(LCD_DELAY_NORMAL_US);
+ } else if ((count + (cur_addr & 0xf)) >= 0x0f) {
+ count = count + (cur_addr & 0xf) - 0x0f;
+ addr_flag = 0xc0;
+ *LCD_CMD_ADDR = 0xc0;
+ udelay(LCD_DELAY_NORMAL_US);
+ }
+ } else if ((count + (cur_addr & 0xf)) >= 0x0f) {
+ count = 0x0;
+ *LCD_CMD_ADDR = 0xc0 | 0xf;
+ udelay(LCD_DELAY_NORMAL_US);
+ }
+ }
+
+ while (count--) {
+ if (dir == 0) {
+ *LCD_CMD_ADDR = 0x10;
+ } else {
+ *LCD_CMD_ADDR = 0x14;
+ }
+ udelay(LCD_DELAY_NORMAL_US);
+ }
+
+ return 0;
+}
+
+U_BOOT_CMD(lcd_test, 1, 1, do_lcd_test, "lcd_test - lcd test display\n", NULL);
+U_BOOT_CMD(lcd_cls, 1, 1, do_lcd_clear, "lcd_cls - lcd clear display\n", NULL);
+U_BOOT_CMD(lcd_puts, 2, 1, do_lcd_puts,
+ "lcd_puts - display string on lcd\n",
+ "<string> - <string> to be displayed\n");
+U_BOOT_CMD(lcd_putc, 2, 1, do_lcd_putc,
+ "lcd_putc - display char on lcd\n",
+ "<char> - <char> to be displayed\n");
+U_BOOT_CMD(lcd_cur, 3, 1, do_lcd_cur,
+ "lcd_cur - shift cursor on lcd\n",
+ "<count> <dir>- shift cursor on lcd <count> times, direction is <dir> \n"
+ " <count> - 0~31\n" " <dir> - 0,backward; 1, forward\n");
+
+#if 0 /* test-only */
+void set_phy_loopback_mode(void)
+{
+ char devemac2[32];
+ char devemac3[32];
+
+ sprintf(devemac2, "%s2", CONFIG_EMAC_DEV_NAME);
+ sprintf(devemac3, "%s3", CONFIG_EMAC_DEV_NAME);
+
+#if 0
+ unsigned short reg_short;
+
+ miiphy_read(devemac2, 0x1, 1, &reg_short);
+ if (reg_short & 0x04) {
+ /*
+ * printf("EMAC2 link up,do nothing\n");
+ */
+ } else {
+ udelay(1000);
+ miiphy_write(devemac2, 0x1, 0, 0x6000);
+ udelay(1000);
+ miiphy_read(devemac2, 0x1, 0, &reg_short);
+ if (reg_short != 0x6000) {
+ printf
+ ("\nEMAC2 error set LOOPBACK mode error,reg2[0]=%x\n",
+ reg_short);
+ }
+ }
+
+ miiphy_read(devemac3, 0x3, 1, &reg_short);
+ if (reg_short & 0x04) {
+ /*
+ * printf("EMAC3 link up,do nothing\n");
+ */
+ } else {
+ udelay(1000);
+ miiphy_write(devemac3, 0x3, 0, 0x6000);
+ udelay(1000);
+ miiphy_read(devemac3, 0x3, 0, &reg_short);
+ if (reg_short != 0x6000) {
+ printf
+ ("\nEMAC3 error set LOOPBACK mode error,reg2[0]=%x\n",
+ reg_short);
+ }
+ }
+#else
+ /* Set PHY as LOOPBACK MODE, for Linux emac initializing */
+ miiphy_write(devemac2, CONFIG_PHY2_ADDR, 0, 0x6000);
+ udelay(1000);
+ miiphy_write(devemac3, CONFIG_PHY3_ADDR, 0, 0x6000);
+ udelay(1000);
+#endif /* 0 */
+}
+
+void set_phy_normal_mode(void)
+{
+ char devemac2[32];
+ char devemac3[32];
+ unsigned short reg_short;
+
+ sprintf(devemac2, "%s2", CONFIG_EMAC_DEV_NAME);
+ sprintf(devemac3, "%s3", CONFIG_EMAC_DEV_NAME);
+
+ /* Set phy of EMAC2 */
+ miiphy_read(devemac2, CONFIG_PHY2_ADDR, 0x16, &reg_short);
+ reg_short &= ~(0x7);
+ reg_short |= 0x6; /* RGMII DLL Delay */
+ miiphy_write(devemac2, CONFIG_PHY2_ADDR, 0x16, reg_short);
+
+ miiphy_read(devemac2, CONFIG_PHY2_ADDR, 0x17, &reg_short);
+ reg_short &= ~(0x40);
+ miiphy_write(devemac2, CONFIG_PHY2_ADDR, 0x17, reg_short);
+
+ miiphy_write(devemac2, CONFIG_PHY2_ADDR, 0x1c, 0x74f0);
+
+ /* Set phy of EMAC3 */
+ miiphy_read(devemac3, CONFIG_PHY3_ADDR, 0x16, &reg_short);
+ reg_short &= ~(0x7);
+ reg_short |= 0x6; /* RGMII DLL Delay */
+ miiphy_write(devemac3, CONFIG_PHY3_ADDR, 0x16, reg_short);
+
+ miiphy_read(devemac3, CONFIG_PHY3_ADDR, 0x17, &reg_short);
+ reg_short &= ~(0x40);
+ miiphy_write(devemac3, CONFIG_PHY3_ADDR, 0x17, reg_short);
+
+ miiphy_write(devemac3, CONFIG_PHY3_ADDR, 0x1c, 0x74f0);
+}
+#endif /* 0 - test only */
+
+static int do_led_test_off(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
+{
+ volatile unsigned int *GpioOr =
+ (volatile unsigned int *)(CFG_PERIPHERAL_BASE + 0x700);
+ *GpioOr |= 0x00300000;
+ return 0;
+}
+
+static int do_led_test_on(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
+{
+ volatile unsigned int *GpioOr =
+ (volatile unsigned int *)(CFG_PERIPHERAL_BASE + 0x700);
+ *GpioOr &= ~0x00300000;
+ return 0;
+}
+
+U_BOOT_CMD(ledon, 1, 1, do_led_test_on,
+ "ledon - led test light on\n", NULL);
+
+U_BOOT_CMD(ledoff, 1, 1, do_led_test_off,
+ "ledoff - led test light off\n", NULL);
+#endif
diff --git a/board/amcc/taishan/showinfo.c b/board/amcc/taishan/showinfo.c
new file mode 100644
index 00000000000..57b9d1c4218
--- /dev/null
+++ b/board/amcc/taishan/showinfo.c
@@ -0,0 +1,236 @@
+/*
+ * (C) Copyright 2007
+ * Stefan Roese, DENX Software Engineering, sr@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <config.h>
+#include <common.h>
+#include <command.h>
+#include <asm/processor.h>
+#include <pci.h>
+
+void show_reset_reg(void)
+{
+ unsigned long reg;
+
+ /* read clock regsiter */
+ printf("===== Display reset and initialize register Start =========\n");
+ mfclk(clk_pllc,reg);
+ printf("cpr_pllc = %#010x\n",reg);
+
+ mfclk(clk_plld,reg);
+ printf("cpr_plld = %#010x\n",reg);
+
+ mfclk(clk_primad,reg);
+ printf("cpr_primad = %#010x\n",reg);
+
+ mfclk(clk_primbd,reg);
+ printf("cpr_primbd = %#010x\n",reg);
+
+ mfclk(clk_opbd,reg);
+ printf("cpr_opbd = %#010x\n",reg);
+
+ mfclk(clk_perd,reg);
+ printf("cpr_perd = %#010x\n",reg);
+
+ mfclk(clk_mald,reg);
+ printf("cpr_mald = %#010x\n",reg);
+
+ /* read sdr register */
+ mfsdr(sdr_ebc,reg);
+ printf("sdr_ebc = %#010x\n",reg);
+
+ mfsdr(sdr_cp440,reg);
+ printf("sdr_cp440 = %#010x\n",reg);
+
+ mfsdr(sdr_xcr,reg);
+ printf("sdr_xcr = %#010x\n",reg);
+
+ mfsdr(sdr_xpllc,reg);
+ printf("sdr_xpllc = %#010x\n",reg);
+
+ mfsdr(sdr_xplld,reg);
+ printf("sdr_xplld = %#010x\n",reg);
+
+ mfsdr(sdr_pfc0,reg);
+ printf("sdr_pfc0 = %#010x\n",reg);
+
+ mfsdr(sdr_pfc1,reg);
+ printf("sdr_pfc1 = %#010x\n",reg);
+
+ mfsdr(sdr_cust0,reg);
+ printf("sdr_cust0 = %#010x\n",reg);
+
+ mfsdr(sdr_cust1,reg);
+ printf("sdr_cust1 = %#010x\n",reg);
+
+ mfsdr(sdr_uart0,reg);
+ printf("sdr_uart0 = %#010x\n",reg);
+
+ mfsdr(sdr_uart1,reg);
+ printf("sdr_uart1 = %#010x\n",reg);
+
+ printf("===== Display reset and initialize register End =========\n");
+}
+
+void show_xbridge_info(void)
+{
+ unsigned long reg;
+
+ printf("PCI-X chip control registers\n");
+ mfsdr(sdr_xcr, reg);
+ printf("sdr_xcr = %#010x\n", reg);
+
+ mfsdr(sdr_xpllc, reg);
+ printf("sdr_xpllc = %#010x\n", reg);
+
+ mfsdr(sdr_xplld, reg);
+ printf("sdr_xplld = %#010x\n", reg);
+
+ printf("PCI-X Bridge Configure registers\n");
+ printf("PCIX0_VENDID = %#06x\n", in16r(PCIX0_VENDID));
+ printf("PCIX0_DEVID = %#06x\n", in16r(PCIX0_DEVID));
+ printf("PCIX0_CMD = %#06x\n", in16r(PCIX0_CMD));
+ printf("PCIX0_STATUS = %#06x\n", in16r(PCIX0_STATUS));
+ printf("PCIX0_REVID = %#04x\n", in8(PCIX0_REVID));
+ printf("PCIX0_CACHELS = %#04x\n", in8(PCIX0_CACHELS));
+ printf("PCIX0_LATTIM = %#04x\n", in8(PCIX0_LATTIM));
+ printf("PCIX0_HDTYPE = %#04x\n", in8(PCIX0_HDTYPE));
+ printf("PCIX0_BIST = %#04x\n", in8(PCIX0_BIST));
+
+ printf("PCIX0_BAR0 = %#010x\n", in32r(PCIX0_BAR0));
+ printf("PCIX0_BAR1 = %#010x\n", in32r(PCIX0_BAR1));
+ printf("PCIX0_BAR2 = %#010x\n", in32r(PCIX0_BAR2));
+ printf("PCIX0_BAR3 = %#010x\n", in32r(PCIX0_BAR3));
+ printf("PCIX0_BAR4 = %#010x\n", in32r(PCIX0_BAR4));
+ printf("PCIX0_BAR5 = %#010x\n", in32r(PCIX0_BAR5));
+
+ printf("PCIX0_CISPTR = %#010x\n", in32r(PCIX0_CISPTR));
+ printf("PCIX0_SBSSYSVID = %#010x\n", in16r(PCIX0_SBSYSVID));
+ printf("PCIX0_SBSSYSID = %#010x\n", in16r(PCIX0_SBSYSID));
+ printf("PCIX0_EROMBA = %#010x\n", in32r(PCIX0_EROMBA));
+ printf("PCIX0_CAP = %#04x\n", in8(PCIX0_CAP));
+ printf("PCIX0_INTLN = %#04x\n", in8(PCIX0_INTLN));
+ printf("PCIX0_INTPN = %#04x\n", in8(PCIX0_INTPN));
+ printf("PCIX0_MINGNT = %#04x\n", in8(PCIX0_MINGNT));
+ printf("PCIX0_MAXLTNCY = %#04x\n", in8(PCIX0_MAXLTNCY));
+
+ printf("PCIX0_BRDGOPT1 = %#010x\n", in32r(PCIX0_BRDGOPT1));
+ printf("PCIX0_BRDGOPT2 = %#010x\n", in32r(PCIX0_BRDGOPT2));
+
+ printf("PCIX0_POM0LAL = %#010x\n", in32r(PCIX0_POM0LAL));
+ printf("PCIX0_POM0LAH = %#010x\n", in32r(PCIX0_POM0LAH));
+ printf("PCIX0_POM0SA = %#010x\n", in32r(PCIX0_POM0SA));
+ printf("PCIX0_POM0PCILAL = %#010x\n", in32r(PCIX0_POM0PCIAL));
+ printf("PCIX0_POM0PCILAH = %#010x\n", in32r(PCIX0_POM0PCIAH));
+ printf("PCIX0_POM1LAL = %#010x\n", in32r(PCIX0_POM1LAL));
+ printf("PCIX0_POM1LAH = %#010x\n", in32r(PCIX0_POM1LAH));
+ printf("PCIX0_POM1SA = %#010x\n", in32r(PCIX0_POM1SA));
+ printf("PCIX0_POM1PCILAL = %#010x\n", in32r(PCIX0_POM1PCIAL));
+ printf("PCIX0_POM1PCILAH = %#010x\n", in32r(PCIX0_POM1PCIAH));
+ printf("PCIX0_POM2SA = %#010x\n", in32r(PCIX0_POM2SA));
+
+ printf("PCIX0_PIM0SA = %#010x\n", in32r(PCIX0_PIM0SA));
+ printf("PCIX0_PIM0LAL = %#010x\n", in32r(PCIX0_PIM0LAL));
+ printf("PCIX0_PIM0LAH = %#010x\n", in32r(PCIX0_PIM0LAH));
+ printf("PCIX0_PIM1SA = %#010x\n", in32r(PCIX0_PIM1SA));
+ printf("PCIX0_PIM1LAL = %#010x\n", in32r(PCIX0_PIM1LAL));
+ printf("PCIX0_PIM1LAH = %#010x\n", in32r(PCIX0_PIM1LAH));
+ printf("PCIX0_PIM2SA = %#010x\n", in32r(PCIX0_PIM1SA));
+ printf("PCIX0_PIM2LAL = %#010x\n", in32r(PCIX0_PIM1LAL));
+ printf("PCIX0_PIM2LAH = %#010x\n", in32r(PCIX0_PIM1LAH));
+
+ printf("PCIX0_XSTS = %#010x\n", in32r(PCIX0_STS));
+}
+
+int do_show_xbridge_info(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
+{
+ show_xbridge_info();
+ return 0;
+}
+
+U_BOOT_CMD(xbriinfo, 1, 1, do_show_xbridge_info,
+ "xbriinfo - Show PCIX bridge info\n", NULL);
+
+#define TAISHAN_PCI_DEV_ID0 0x800
+#define TAISHAN_PCI_DEV_ID1 0x1000
+
+void show_pcix_device_info(void)
+{
+ int ii;
+ int dev;
+ u8 capp;
+ u8 xcapid;
+ u16 status;
+ u16 xcommand;
+ u32 xstatus;
+
+ for (ii = 0; ii < 2; ii++) {
+ if (ii == 0)
+ dev = TAISHAN_PCI_DEV_ID0;
+ else
+ dev = TAISHAN_PCI_DEV_ID1;
+
+ pci_read_config_word(dev, PCI_STATUS, &status);
+ if (status & PCI_STATUS_CAP_LIST) {
+ pci_read_config_byte(dev, PCI_CAPABILITY_LIST, &capp);
+
+ pci_read_config_byte(dev, (int)(capp), &xcapid);
+ if (xcapid == 0x07) {
+ pci_read_config_word(dev, (int)(capp + 2),
+ &xcommand);
+ pci_read_config_dword(dev, (int)(capp + 4),
+ &xstatus);
+ printf("BUS0 dev%d Xcommand=%#06x,Xstatus=%#010x\n",
+ (ii + 1), xcommand, xstatus);
+ } else {
+ printf("BUS0 dev%d PCI-X CAP ID error,"
+ "CAP=%#04x,XCAPID=%#04x\n",
+ (ii + 1), capp, xcapid);
+ }
+ } else {
+ printf("BUS0 dev%d not found PCI_STATUS_CAP_LIST supporting\n",
+ ii + 1);
+ }
+ }
+
+}
+
+int do_show_pcix_device_info(cmd_tbl_t * cmdtp, int flag, int argc,
+ char *argv[])
+{
+ show_pcix_device_info();
+ return 0;
+}
+
+U_BOOT_CMD(xdevinfo, 1, 1, do_show_pcix_device_info,
+ "xdevinfo - Show PCIX Device info\n", NULL);
+
+extern void show_reset_reg(void);
+
+int do_show_reset_reg_info(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
+{
+ show_reset_reg();
+ return 0;
+}
+
+U_BOOT_CMD(resetinfo, 1, 1, do_show_reset_reg_info,
+ "resetinfo - Show Reset REG info\n", NULL);
diff --git a/board/amcc/taishan/taishan.c b/board/amcc/taishan/taishan.c
new file mode 100644
index 00000000000..1a2e53b1abc
--- /dev/null
+++ b/board/amcc/taishan/taishan.c
@@ -0,0 +1,331 @@
+/*
+ * Copyright (C) 2004 PaulReynolds@lhsolutions.com
+ *
+ * (C) Copyright 2007
+ * Stefan Roese, DENX Software Engineering, sr@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <asm/processor.h>
+#include <spd_sdram.h>
+#include <ppc4xx_enet.h>
+
+#ifdef CFG_INIT_SHOW_RESET_REG
+void show_reset_reg(void);
+#endif
+
+int lcd_init(void);
+
+int board_early_init_f (void)
+{
+ unsigned long reg;
+ volatile unsigned int *GpioOdr;
+ volatile unsigned int *GpioTcr;
+ volatile unsigned int *GpioOr;
+
+ /*-------------------------------------------------------------------------+
+ | Initialize EBC CONFIG
+ +-------------------------------------------------------------------------*/
+ mtebc(xbcfg, EBC_CFG_LE_UNLOCK |
+ EBC_CFG_PTD_ENABLE | EBC_CFG_RTC_64PERCLK |
+ EBC_CFG_ATC_PREVIOUS | EBC_CFG_DTC_PREVIOUS |
+ EBC_CFG_CTC_PREVIOUS | EBC_CFG_EMC_DEFAULT |
+ EBC_CFG_PME_DISABLE | EBC_CFG_PR_32);
+
+ /*-------------------------------------------------------------------------+
+ | 64MB FLASH. Initialize bank 0 with default values.
+ +-------------------------------------------------------------------------*/
+ mtebc(pb0ap, EBC_BXAP_BME_DISABLED|EBC_BXAP_TWT_ENCODE(15) |
+ EBC_BXAP_BCE_DISABLE |
+ EBC_BXAP_CSN_ENCODE(1) | EBC_BXAP_OEN_ENCODE(1) |
+ EBC_BXAP_WBN_ENCODE(1) | EBC_BXAP_WBF_ENCODE(1) |
+ EBC_BXAP_TH_ENCODE(3) | EBC_BXAP_RE_DISABLED |
+ EBC_BXAP_BEM_WRITEONLY |
+ EBC_BXAP_PEN_DISABLED);
+ mtebc(pb0cr, EBC_BXCR_BAS_ENCODE(CFG_FLASH_BASE) |
+ EBC_BXCR_BS_64MB | EBC_BXCR_BU_RW|EBC_BXCR_BW_32BIT);
+
+ /*-------------------------------------------------------------------------+
+ | FPGA. Initialize bank 1 with default values.
+ +-------------------------------------------------------------------------*/
+ mtebc(pb1ap, EBC_BXAP_BME_DISABLED|EBC_BXAP_TWT_ENCODE(5) |
+ EBC_BXAP_BCE_DISABLE |
+ EBC_BXAP_CSN_ENCODE(1) | EBC_BXAP_OEN_ENCODE(1) |
+ EBC_BXAP_WBN_ENCODE(1) | EBC_BXAP_WBF_ENCODE(1) |
+ EBC_BXAP_TH_ENCODE(3) | EBC_BXAP_RE_DISABLED |
+ EBC_BXAP_BEM_WRITEONLY |
+ EBC_BXAP_PEN_DISABLED);
+ mtebc(pb1cr, EBC_BXCR_BAS_ENCODE(0x41000000) |
+ EBC_BXCR_BS_1MB | EBC_BXCR_BU_RW | EBC_BXCR_BW_8BIT);
+
+ /*-------------------------------------------------------------------------+
+ | LCM. Initialize bank 2 with default values.
+ +-------------------------------------------------------------------------*/
+ mtebc(pb2ap, EBC_BXAP_BME_DISABLED | EBC_BXAP_TWT_ENCODE(64) |
+ EBC_BXAP_BCE_DISABLE |
+ EBC_BXAP_CSN_ENCODE(3) | EBC_BXAP_OEN_ENCODE(3) |
+ EBC_BXAP_WBN_ENCODE(3) | EBC_BXAP_WBF_ENCODE(3) |
+ EBC_BXAP_TH_ENCODE(7) | EBC_BXAP_RE_DISABLED |
+ EBC_BXAP_BEM_WRITEONLY |
+ EBC_BXAP_PEN_DISABLED);
+ mtebc(pb2cr, EBC_BXCR_BAS_ENCODE(0x42000000) |
+ EBC_BXCR_BS_1MB | EBC_BXCR_BU_RW|EBC_BXCR_BW_8BIT);
+
+ /*-------------------------------------------------------------------------+
+ | TMP. Initialize bank 3 with default values.
+ +-------------------------------------------------------------------------*/
+ mtebc(pb3ap, EBC_BXAP_BME_DISABLED | EBC_BXAP_TWT_ENCODE(128) |
+ EBC_BXAP_BCE_DISABLE |
+ EBC_BXAP_CSN_ENCODE(3) | EBC_BXAP_OEN_ENCODE(3) |
+ EBC_BXAP_WBN_ENCODE(3) | EBC_BXAP_WBF_ENCODE(3) |
+ EBC_BXAP_TH_ENCODE(7) | EBC_BXAP_RE_DISABLED |
+ EBC_BXAP_BEM_WRITEONLY |
+ EBC_BXAP_PEN_DISABLED);
+ mtebc(pb3cr, EBC_BXCR_BAS_ENCODE(0x48000000) |
+ EBC_BXCR_BS_64MB | EBC_BXCR_BU_RW | EBC_BXCR_BW_32BIT);
+
+ /*-------------------------------------------------------------------------+
+ | Connector 4~7. Initialize bank 3~ 7 with default values.
+ +-------------------------------------------------------------------------*/
+ mtebc(pb4ap,0);
+ mtebc(pb4cr,0);
+ mtebc(pb5ap,0);
+ mtebc(pb5cr,0);
+ mtebc(pb6ap,0);
+ mtebc(pb6cr,0);
+ mtebc(pb7ap,0);
+ mtebc(pb7cr,0);
+
+ /*--------------------------------------------------------------------
+ * Setup the interrupt controller polarities, triggers, etc.
+ *-------------------------------------------------------------------*/
+ mtdcr (uic0sr, 0xffffffff); /* clear all */
+ mtdcr (uic0er, 0x00000000); /* disable all */
+ mtdcr (uic0cr, 0x00000009); /* SMI & 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 */
+
+ mtdcr (uic2sr, 0xffffffff); /* clear all */
+ mtdcr (uic2er, 0x00000000); /* disable all */
+ mtdcr (uic2cr, 0x00000000); /* all non-critical */
+ mtdcr (uic2pr, 0xffffffff); /* per ref-board manual */
+ mtdcr (uic2tr, 0x00ff8c0f); /* per ref-board manual */
+ mtdcr (uic2vr, 0x00000001); /* int31 highest, base=0x000 */
+ mtdcr (uic2sr, 0xffffffff); /* clear all */
+
+ mtdcr (uicb0sr, 0xfc000000); /* clear all */
+ mtdcr (uicb0er, 0x00000000); /* disable all */
+ mtdcr (uicb0cr, 0x00000000); /* all non-critical */
+ mtdcr (uicb0pr, 0xfc000000); /* */
+ mtdcr (uicb0tr, 0x00000000); /* */
+ mtdcr (uicb0vr, 0x00000001); /* */
+
+ /* Enable two GPIO 10~11 and TraceA signal */
+ mfsdr(sdr_pfc0,reg);
+ reg |= 0x00300000;
+ mtsdr(sdr_pfc0,reg);
+
+ mfsdr(sdr_pfc1,reg);
+ reg |= 0x00100000;
+ mtsdr(sdr_pfc1,reg);
+
+ /* Set GPIO 10 and 11 as output */
+ GpioOdr = (volatile unsigned int*)(CFG_PERIPHERAL_BASE+0x718);
+ GpioTcr = (volatile unsigned int*)(CFG_PERIPHERAL_BASE+0x704);
+ GpioOr = (volatile unsigned int*)(CFG_PERIPHERAL_BASE+0x700);
+
+ *GpioOdr &= ~(0x00300000);
+ *GpioTcr |= 0x00300000;
+ *GpioOr |= 0x00300000;
+
+ return 0;
+}
+
+int misc_init_r(void)
+{
+ lcd_init();
+
+ return 0;
+}
+
+int checkboard (void)
+{
+ char *s = getenv ("serial#");
+
+ printf ("Board: Taishan - AMCC PPC440GX Evaluation Board");
+ if (s != NULL) {
+ puts (", serial# ");
+ puts (s);
+ }
+ putc ('\n');
+
+#ifdef CFG_INIT_SHOW_RESET_REG
+ show_reset_reg();
+#endif
+
+ return (0);
+}
+
+#if defined(CFG_DRAM_TEST)
+int testdram (void)
+{
+ uint *pstart = (uint *) 0x04000000;
+ uint *pend = (uint *) 0x0fc00000;
+ uint *p;
+
+ for (p = pstart; p < pend; p++)
+ *p = 0xaaaaaaaa;
+
+ for (p = pstart; p < pend; p++) {
+ if (*p != 0xaaaaaaaa) {
+ printf ("SDRAM test fails at: %08x\n", (uint) p);
+ return 1;
+ }
+ }
+
+ for (p = pstart; p < pend; p++)
+ *p = 0x55555555;
+
+ for (p = pstart; p < pend; p++) {
+ if (*p != 0x55555555) {
+ printf ("SDRAM test fails at: %08x\n", (uint) p);
+ return 1;
+ }
+ }
+ 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 strap;
+
+ /*--------------------------------------------------------------------------+
+ * The ocotea board is always configured as the host & requires the
+ * PCI arbiter to be enabled.
+ *--------------------------------------------------------------------------*/
+ mfsdr(sdr_sdstp1, strap);
+ if( (strap & SDR0_SDSTP1_PAE_MASK) == 0 ){
+ printf("PCI: SDR0_STRP1[%08lX] - PCI Arbiter disabled.\n",strap);
+ return 0;
+ }
+
+ return 1;
+}
+#endif /* defined(CONFIG_PCI) && defined(CFG_PCI_PRE_INIT) */
+
+/*************************************************************************
+ * pci_target_init
+ *
+ * The bootstrap configuration provides default settings for the pci
+ * inbound map (PIM). But the bootstrap config choices are limited and
+ * may not be sufficient for a given board.
+ *
+ ************************************************************************/
+#if defined(CONFIG_PCI) && defined(CFG_PCI_TARGET_INIT)
+void pci_target_init(struct pci_controller * hose )
+{
+ DECLARE_GLOBAL_DATA_PTR;
+
+ /*--------------------------------------------------------------------------+
+ * Disable everything
+ *--------------------------------------------------------------------------*/
+ out32r( PCIX0_PIM0SA, 0 ); /* disable */
+ out32r( PCIX0_PIM1SA, 0 ); /* disable */
+ out32r( PCIX0_PIM2SA, 0 ); /* disable */
+ out32r( PCIX0_EROMBA, 0 ); /* disable expansion rom */
+
+ /*--------------------------------------------------------------------------+
+ * Map all of SDRAM to PCI address 0x0000_0000. Note that the 440 strapping
+ * options to not support sizes such as 128/256 MB.
+ *--------------------------------------------------------------------------*/
+ out32r( PCIX0_PIM0LAL, CFG_SDRAM_BASE );
+ out32r( PCIX0_PIM0LAH, 0 );
+ out32r( PCIX0_PIM0SA, ~(gd->ram_size - 1) | 1 );
+
+ out32r( PCIX0_BAR0, 0 );
+
+ /*--------------------------------------------------------------------------+
+ * Program the board's subsystem id/vendor id
+ *--------------------------------------------------------------------------*/
+ out16r( PCIX0_SBSYSVID, CFG_PCI_SUBSYS_VENDORID );
+ out16r( PCIX0_SBSYSID, CFG_PCI_SUBSYS_DEVICEID );
+
+ out16r( PCIX0_CMD, in16r(PCIX0_CMD) | PCI_COMMAND_MEMORY );
+}
+#endif /* defined(CONFIG_PCI) && defined(CFG_PCI_TARGET_INIT) */
+
+/*************************************************************************
+ * is_pci_host
+ *
+ * This routine is called to determine if a pci scan should be
+ * performed. With various hardware environments (especially cPCI and
+ * PPMC) it's insufficient to depend on the state of the arbiter enable
+ * bit in the strap register, or generic host/adapter assumptions.
+ *
+ * Rather than hard-code a bad assumption in the general 440 code, the
+ * 440 pci code requires the board to decide at runtime.
+ *
+ * Return 0 for adapter mode, non-zero for host (monarch) mode.
+ *
+ *
+ ************************************************************************/
+#if defined(CONFIG_PCI)
+int is_pci_host(struct pci_controller *hose)
+{
+ /* The ocotea board is always configured as host. */
+ return(1);
+}
+#endif /* defined(CONFIG_PCI) */
+
+#ifdef CONFIG_POST
+/*
+ * Returns 1 if keys pressed to start the power-on long-running tests
+ * Called from board_init_f().
+ */
+int post_hotkeys_pressed(void)
+{
+ return (ctrlc());
+}
+#endif
diff --git a/board/amcc/yellowstone/u-boot.lds b/board/amcc/taishan/u-boot.lds
index a0ba44de889..664716ed441 100644
--- a/board/amcc/yellowstone/u-boot.lds
+++ b/board/amcc/taishan/u-boot.lds
@@ -1,5 +1,5 @@
/*
- * (C) Copyright 2002
+ * (C) Copyright 2004
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
* See file CREDITS for list of people who contributed to this
@@ -67,7 +67,7 @@ SECTIONS
/* the sector layout of our flash chips! XXX FIXME XXX */
cpu/ppc4xx/start.o (.text)
- board/amcc/yellowstone/init.o (.text)
+ board/amcc/taishan/init.o (.text)
cpu/ppc4xx/kgdb.o (.text)
cpu/ppc4xx/traps.o (.text)
cpu/ppc4xx/interrupts.o (.text)
diff --git a/board/amcc/taishan/update.c b/board/amcc/taishan/update.c
new file mode 100644
index 00000000000..ed2c196dcf5
--- /dev/null
+++ b/board/amcc/taishan/update.c
@@ -0,0 +1,78 @@
+/*
+ * (C) Copyright 2007
+ * Stefan Roese, DENX Software Engineering, sr@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <config.h>
+#include <common.h>
+#include <command.h>
+#include <asm/processor.h>
+#include <i2c.h>
+
+#if defined(CONFIG_TAISHAN)
+
+const uchar bootstrap_buf[16] = {
+ 0x86,
+ 0x78,
+ 0xc1,
+ 0xa6,
+ 0x09,
+ 0x67,
+ 0x04,
+ 0x63,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00
+};
+
+static int update_boot_eeprom(void)
+{
+ ulong len = 0x10;
+ uchar chip = CFG_BOOTSTRAP_IIC_ADDR;
+ uchar *pbuf = (uchar *)bootstrap_buf;
+ int ii, jj;
+
+ for (ii = 0; ii < len; ii++) {
+ if (i2c_write(chip, ii, 1, &pbuf[ii], 1) != 0) {
+ printf("i2c_write failed\n");
+ return -1;
+ }
+
+ /* wait 10ms */
+ for (jj = 0; jj < 10; jj++)
+ udelay(1000);
+ }
+ return 0;
+}
+
+int do_update_boot_eeprom(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
+{
+ return update_boot_eeprom();
+}
+
+U_BOOT_CMD(update_boot_eeprom, 1, 1, do_update_boot_eeprom,
+ "update_boot_eeprom - update bootstrap eeprom content\n", NULL);
+#endif
diff --git a/board/amcc/yellowstone/init.S b/board/amcc/yellowstone/init.S
deleted file mode 100644
index 425ad0868f8..00000000000
--- 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 92dc9d4c028..00000000000
--- a/board/amcc/yellowstone/yellowstone.c
+++ /dev/null
@@ -1,554 +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 */
-
- mtebc(pb0ap, 0x03017300); /* FLASH/SRAM */
- mtebc(pb0cr, 0xfc0da000); /* BAS=0xfc0 64MB r/w 16-bit */
-
- mtebc(pb1ap, 0x00000000);
- mtebc(pb1cr, 0x00000000);
-
- mtebc(pb2ap, 0x04814500);
- /*CPLD*/ mtebc(pb2cr, 0x80018000); /*BAS=0x800 1MB r/w 8-bit */
-
- mtebc(pb3ap, 0x00000000);
- mtebc(pb3cr, 0x00000000);
-
- mtebc(pb4ap, 0x00000000);
- mtebc(pb4cr, 0x00000000);
-
- mtebc(pb5ap, 0x00000000);
- mtebc(pb5cr, 0x00000000);
-
- /*--------------------------------------------------------------------
- * 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#");
-
- printf("Board: Yellowstone - AMCC PPC440GR Evaluation Board");
- 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
diff --git a/board/amcc/yosemite/yosemite.c b/board/amcc/yosemite/yosemite.c
index 7f2e718203b..c2e12ba12ea 100644
--- a/board/amcc/yosemite/yosemite.c
+++ b/board/amcc/yosemite/yosemite.c
@@ -39,24 +39,6 @@ int board_early_init_f(void)
reg = mfdcr(ebccfgd);
mtdcr(ebccfgd, reg | 0x04000000); /* Set ATC */
- mtebc(pb0ap, 0x03017300); /* FLASH/SRAM */
- mtebc(pb0cr, 0xfc0da000); /* BAS=0xfc0 64MB r/w 16-bit */
-
- mtebc(pb1ap, 0x00000000);
- mtebc(pb1cr, 0x00000000);
-
- mtebc(pb2ap, 0x04814500);
- /*CPLD*/ mtebc(pb2cr, 0x80018000); /*BAS=0x800 1MB r/w 8-bit */
-
- mtebc(pb3ap, 0x00000000);
- mtebc(pb3cr, 0x00000000);
-
- mtebc(pb4ap, 0x00000000);
- mtebc(pb4cr, 0x00000000);
-
- mtebc(pb5ap, 0x00000000);
- mtebc(pb5cr, 0x00000000);
-
/*--------------------------------------------------------------------
* Setup the GPIO pins
*-------------------------------------------------------------------*/
@@ -83,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.
@@ -123,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;
@@ -186,8 +172,19 @@ int misc_init_r (void)
int checkboard(void)
{
char *s = getenv("serial#");
+ 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;
+ printf(", Rev. %X, PCI=%d MHz", rev, val ? 66 : 33);
+
if (s != NULL) {
puts(", serial# ");
puts(s);
@@ -548,3 +545,9 @@ 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/yucca/init.S b/board/amcc/yucca/init.S
index c9eca686b25..c92dcf7a514 100644
--- a/board/amcc/yucca/init.S
+++ b/board/amcc/yucca/init.S
@@ -1,4 +1,7 @@
/*
+ * (C) Copyright 2007
+ * Stefan Roese, DENX Software Engineering, sr@denx.de.
+ *
* Copyright (C) 2002 Scott McNutt <smcnutt@artesyncp.com>
*
* See file CREDITS for list of people who contributed to this
@@ -19,56 +22,10 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
-/* port to AMCC 440SPE evaluatioon board - SG April 12,2005 */
#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_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)
+#include <asm-ppc/mmu.h>
/**************************************************************************
* TLB TABLE
@@ -89,12 +46,18 @@
.globl tlbtabA
tlbtabA:
tlbtab_start
- tlbentry(0xfff00000, SZ_16M, 0xfff00000, 4, AC_R|AC_W|AC_X|SA_G)
- tlbentry(CFG_SDRAM_BASE, SZ_256M, 0x00000000, 0, AC_R|AC_W|AC_X|SA_G|SA_I)
- tlbentry(CFG_SDRAM_BASE + 0x10000000, SZ_256M, 0x10000000, 0, AC_R|AC_W|AC_X|SA_G|SA_I)
- tlbentry(CFG_SDRAM_BASE + 0x20000000, SZ_256M, 0x20000000, 0, AC_R|AC_W|AC_X|SA_G|SA_I)
- tlbentry(CFG_SDRAM_BASE + 0x30000000, SZ_256M, 0x30000000, 0, AC_R|AC_W|AC_X|SA_G|SA_I)
+ /*
+ * 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(0xff000000, SZ_16M, 0xff000000, 4, AC_R|AC_W|AC_X|SA_G)
+
+ /*
+ * TLB entries for SDRAM are not needed on this platform.
+ * They are dynamically generated in the SPD DDR(2) detection
+ * routine.
+ */
tlbentry(CFG_ISRAM_BASE, SZ_256K, 0x00000000, 4, AC_R|AC_W|AC_X|SA_I)
tlbentry(CFG_FPGA_BASE, SZ_1K, 0xE2000000, 4,AC_R|AC_W|SA_I)
@@ -126,12 +89,18 @@ tlbtabA:
.globl tlbtabB
tlbtabB:
tlbtab_start
- tlbentry(0xfff00000, SZ_16M, 0xfff00000, 4, AC_R|AC_W|AC_X|SA_G)
- tlbentry(CFG_SDRAM_BASE, SZ_256M, 0x00000000, 0, AC_R|AC_W|AC_X|SA_G|SA_I)
- tlbentry(CFG_SDRAM_BASE + 0x10000000, SZ_256M, 0x10000000, 0, AC_R|AC_W|AC_X|SA_G|SA_I)
- tlbentry(CFG_SDRAM_BASE + 0x20000000, SZ_256M, 0x20000000, 0, AC_R|AC_W|AC_X|SA_G|SA_I)
- tlbentry(CFG_SDRAM_BASE + 0x30000000, SZ_256M, 0x30000000, 0, AC_R|AC_W|AC_X|SA_G|SA_I)
+ /*
+ * 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(0xff000000, SZ_16M, 0xff000000, 4, AC_R|AC_W|AC_X|SA_G)
+
+ /*
+ * TLB entries for SDRAM are not needed on this platform.
+ * They are dynamically generated in the SPD DDR(2) detection
+ * routine.
+ */
tlbentry(CFG_ISRAM_BASE, SZ_256K, 0x00000000, 4, AC_R|AC_W|AC_X|SA_I)
tlbentry(CFG_FPGA_BASE, SZ_1K, 0xE2000000, 4,AC_R|AC_W|SA_I)
diff --git a/board/amcc/yucca/yucca.c b/board/amcc/yucca/yucca.c
index e9b34dd249a..90eaab1c80b 100644
--- a/board/amcc/yucca/yucca.c
+++ b/board/amcc/yucca/yucca.c
@@ -44,8 +44,6 @@ int compare_to_true(char *str );
char *remove_l_w_space(char *in_str );
char *remove_t_w_space(char *in_str );
int get_console_port(void);
-unsigned long ppcMfcpr(unsigned long cpr_reg);
-unsigned long ppcMfsdr(unsigned long sdr_reg);
int ppc440spe_init_pcie_rootport(int port);
void ppc440spe_setup_pcie(struct pci_controller *hose, int port);
@@ -221,7 +219,7 @@ int board_early_init_f (void)
|
+-------------------------------------------------------------------*/
/* Read Pin Strap Register in PPC440SP */
- sdr0_pinstp = ppcMfsdr(SDR0_PINSTP);
+ mfsdr(SDR0_PINSTP, sdr0_pinstp);
bootstrap_settings = sdr0_pinstp & SDR0_PINSTP_BOOTSTRAP_MASK;
switch (bootstrap_settings) {
@@ -246,7 +244,7 @@ int board_early_init_f (void)
* Boot Settings in IIC EEprom address 0x50 or 0x54
* Read Serial Device Strap Register1 in PPC440SPe
*/
- sdr0_sdstp1 = ppcMfsdr(SDR0_SDSTP1);
+ mfsdr(SDR0_SDSTP1, sdr0_sdstp1);
boot_selection = sdr0_sdstp1 & SDR0_SDSTP1_ERPN_MASK;
ebc_data_width = sdr0_sdstp1 & SDR0_SDSTP1_EBCW_MASK;
@@ -564,277 +562,6 @@ int checkboard (void)
return 0;
}
-static long int yucca_probe_for_dimms(void)
-{
- int dimm_installed[MAXDIMMS];
- int dimm_num, result;
- int dimms_found = 0;
- uchar dimm_addr = IIC0_DIMM0_ADDR;
- uchar dimm_spd_data[MAX_SPD_BYTES];
-
- for (dimm_num = 0; dimm_num < MAXDIMMS; dimm_num++) {
- /* check if there is a chip at the dimm address */
- switch (dimm_num) {
- case 0:
- dimm_addr = IIC0_DIMM0_ADDR;
- break;
- case 1:
- dimm_addr = IIC0_DIMM1_ADDR;
- break;
- }
-
- result = i2c_probe(dimm_addr);
-
- memset(dimm_spd_data, 0, MAX_SPD_BYTES * sizeof(char));
- if (result == 0) {
- /* read first byte of SPD data, if there is any data */
- result = i2c_read(dimm_addr, 0, 1, dimm_spd_data, 1);
-
- if (result == 0) {
- result = dimm_spd_data[0];
- result = result > MAX_SPD_BYTES ?
- MAX_SPD_BYTES : result;
- result = i2c_read(dimm_addr, 0, 1,
- dimm_spd_data, result);
- }
- }
-
- if ((result == 0) &&
- (dimm_spd_data[64] == MICRON_SPD_JEDEC_ID)) {
- dimm_installed[dimm_num] = TRUE;
- dimms_found++;
- debug("DIMM slot %d: DDR2 SDRAM detected\n", dimm_num);
- } else {
- dimm_installed[dimm_num] = FALSE;
- debug("DIMM slot %d: Not populated or cannot sucessfully probe the DIMM\n", dimm_num);
- }
- }
-
- if (dimms_found == 0) {
- printf("ERROR - No memory installed. Install a DDR-SDRAM DIMM.\n\n");
- hang();
- }
-
- if (dimm_installed[0] != TRUE) {
- printf("\nERROR - DIMM slot 0 must be populated before DIMM slot 1.\n");
- printf(" Unsupported configuration. Move DIMM module from DIMM slot 1 to slot 0.\n\n");
- hang();
- }
-
- return dimms_found;
-}
-
-/*************************************************************************
- * init SDRAM controller with fixed value
- * the initialization values are for 2x MICRON DDR2
- * PN: MT18HTF6472DY-53EB2
- * 512MB, DDR2, 533, CL4, ECC, REG
- ************************************************************************/
-static long int fixed_sdram(void)
-{
- long int yucca_dimms = 0;
-
- yucca_dimms = yucca_probe_for_dimms();
-
- /* SDRAM0_MCOPT2 (0X21) Clear DCEN BIT */
- mtdcr( 0x10, 0x00000021 );
- mtdcr( 0x11, 0x84000000 );
-
- /* SDRAM0_MCOPT1 (0X20) ECC OFF / 64 bits / 4 banks / DDR2 */
- mtdcr( 0x10, 0x00000020 );
- mtdcr( 0x11, 0x2D122000 );
-
- /* SET MCIF0_CODT Die Termination On */
- mtdcr( 0x10, 0x00000026 );
- if (yucca_dimms == 2)
- mtdcr( 0x11, 0x2A800021 );
- else if (yucca_dimms == 1)
- mtdcr( 0x11, 0x02800021 );
-
- /* On-Die Termination for Bank 0 */
- mtdcr( 0x10, 0x00000022 );
- if (yucca_dimms == 2)
- mtdcr( 0x11, 0x18000000 );
- else if (yucca_dimms == 1)
- mtdcr( 0x11, 0x06000000 );
-
- /* On-Die Termination for Bank 1 */
- mtdcr( 0x10, 0x00000023 );
- if (yucca_dimms == 2)
- mtdcr( 0x11, 0x18000000 );
- else if (yucca_dimms == 1)
- mtdcr( 0x11, 0x01800000 );
-
- /* On-Die Termination for Bank 2 */
- mtdcr( 0x10, 0x00000024 );
- if (yucca_dimms == 2)
- mtdcr( 0x11, 0x01800000 );
- else if (yucca_dimms == 1)
- mtdcr( 0x11, 0x00000000 );
-
- /* On-Die Termination for Bank 3 */
- mtdcr( 0x10, 0x00000025 );
- if (yucca_dimms == 2)
- mtdcr( 0x11, 0x01800000 );
- else if (yucca_dimms == 1)
- mtdcr( 0x11, 0x00000000 );
-
- /* Refresh Time register (0x30) Refresh every 7.8125uS */
- mtdcr( 0x10, 0x00000030 );
- mtdcr( 0x11, 0x08200000 );
-
- /* SET MCIF0_MMODE CL 4 */
- mtdcr( 0x10, 0x00000088 );
- mtdcr( 0x11, 0x00000642 );
-
- /* MCIF0_MEMODE */
- mtdcr( 0x10, 0x00000089 );
- mtdcr( 0x11, 0x00000004 );
-
- /*SET MCIF0_MB0CF */
- mtdcr( 0x10, 0x00000040 );
- mtdcr( 0x11, 0x00000201 );
-
- /* SET MCIF0_MB1CF */
- mtdcr( 0x10, 0x00000044 );
- mtdcr( 0x11, 0x00000201 );
-
- /* SET MCIF0_MB2CF */
- mtdcr( 0x10, 0x00000048 );
- if (yucca_dimms == 2)
- mtdcr( 0x11, 0x00000201 );
- else if (yucca_dimms == 1)
- mtdcr( 0x11, 0x00000000 );
-
- /* SET MCIF0_MB3CF */
- mtdcr( 0x10, 0x0000004c );
- if (yucca_dimms == 2)
- mtdcr( 0x11, 0x00000201 );
- else if (yucca_dimms == 1)
- mtdcr( 0x11, 0x00000000 );
-
- /* SET MCIF0_INITPLR0 # NOP */
- mtdcr( 0x10, 0x00000050 );
- mtdcr( 0x11, 0xB5380000 );
-
- /* SET MCIF0_INITPLR1 # PRE */
- mtdcr( 0x10, 0x00000051 );
- mtdcr( 0x11, 0x82100400 );
-
- /* SET MCIF0_INITPLR2 # EMR2 */
- mtdcr( 0x10, 0x00000052 );
- mtdcr( 0x11, 0x80820000 );
-
- /* SET MCIF0_INITPLR3 # EMR3 */
- mtdcr( 0x10, 0x00000053 );
- mtdcr( 0x11, 0x80830000 );
-
- /* SET MCIF0_INITPLR4 # EMR DLL ENABLE */
- mtdcr( 0x10, 0x00000054 );
- mtdcr( 0x11, 0x80810000 );
-
- /* SET MCIF0_INITPLR5 # MR DLL RESET */
- mtdcr( 0x10, 0x00000055 );
- mtdcr( 0x11, 0x80800542 );
-
- /* SET MCIF0_INITPLR6 # PRE */
- mtdcr( 0x10, 0x00000056 );
- mtdcr( 0x11, 0x82100400 );
-
- /* SET MCIF0_INITPLR7 # Refresh */
- mtdcr( 0x10, 0x00000057 );
- mtdcr( 0x11, 0x8A080000 );
-
- /* SET MCIF0_INITPLR8 # Refresh */
- mtdcr( 0x10, 0x00000058 );
- mtdcr( 0x11, 0x8A080000 );
-
- /* SET MCIF0_INITPLR9 # Refresh */
- mtdcr( 0x10, 0x00000059 );
- mtdcr( 0x11, 0x8A080000 );
-
- /* SET MCIF0_INITPLR10 # Refresh */
- mtdcr( 0x10, 0x0000005A );
- mtdcr( 0x11, 0x8A080000 );
-
- /* SET MCIF0_INITPLR11 # MR */
- mtdcr( 0x10, 0x0000005B );
- mtdcr( 0x11, 0x80800442 );
-
- /* SET MCIF0_INITPLR12 # EMR OCD Default*/
- mtdcr( 0x10, 0x0000005C );
- mtdcr( 0x11, 0x80810380 );
-
- /* SET MCIF0_INITPLR13 # EMR OCD Exit */
- mtdcr( 0x10, 0x0000005D );
- mtdcr( 0x11, 0x80810000 );
-
- /* 0x80: Adv Addr clock by 180 deg */
- mtdcr( 0x10, 0x00000080 );
- mtdcr( 0x11, 0x80000000 );
-
- /* 0x21: Exit self refresh, set DC_EN */
- mtdcr( 0x10, 0x00000021 );
- mtdcr( 0x11, 0x28000000 );
-
- /* 0x81: Write DQS Adv 90 + Fractional DQS Delay */
- mtdcr( 0x10, 0x00000081 );
- mtdcr( 0x11, 0x80000800 );
-
- /* MCIF0_SDTR1 */
- mtdcr( 0x10, 0x00000085 );
- mtdcr( 0x11, 0x80201000 );
-
- /* MCIF0_SDTR2 */
- mtdcr( 0x10, 0x00000086 );
- mtdcr( 0x11, 0x42103242 );
-
- /* MCIF0_SDTR3 */
- mtdcr( 0x10, 0x00000087 );
- mtdcr( 0x11, 0x0C100D14 );
-
- /* SET MQ0_B0BAS base addr 00000000 / 256MB */
- mtdcr( 0x40, 0x0000F800 );
-
- /* SET MQ0_B1BAS base addr 10000000 / 256MB */
- mtdcr( 0x41, 0x0400F800 );
-
- /* SET MQ0_B2BAS base addr 20000000 / 256MB */
- if (yucca_dimms == 2)
- mtdcr( 0x42, 0x0800F800 );
- else if (yucca_dimms == 1)
- mtdcr( 0x42, 0x00000000 );
-
- /* SET MQ0_B3BAS base addr 30000000 / 256MB */
- if (yucca_dimms == 2)
- mtdcr( 0x43, 0x0C00F800 );
- else if (yucca_dimms == 1)
- mtdcr( 0x43, 0x00000000 );
-
- /* SDRAM_RQDC */
- mtdcr( 0x10, 0x00000070 );
- mtdcr( 0x11, 0x8000003F );
-
- /* SDRAM_RDCC */
- mtdcr( 0x10, 0x00000078 );
- mtdcr( 0x11, 0x80000000 );
-
- /* SDRAM_RFDC */
- mtdcr( 0x10, 0x00000074 );
- mtdcr( 0x11, 0x00000220 );
-
- return (yucca_dimms * 512) << 20;
-}
-
-long int initdram (int board_type)
-{
- long dram_size = 0;
-
- dram_size = fixed_sdram();
-
- return dram_size;
-}
-
#if defined(CFG_DRAM_TEST)
int testdram (void)
{
@@ -1267,42 +994,3 @@ int onboard_pci_arbiter_selected(int core_pci)
#endif
return (BOARD_OPTION_NOT_SELECTED);
}
-
-/*---------------------------------------------------------------------------+
- | ppcMfcpr.
- +---------------------------------------------------------------------------*/
-unsigned long ppcMfcpr(unsigned long cpr_reg)
-{
- unsigned long msr;
- unsigned long cpr_cfgaddr_temp;
- unsigned long cpr_value;
-
- msr = (mfmsr () & ~(MSR_EE));
- cpr_cfgaddr_temp = mfdcr(CPR0_CFGADDR);
- mtdcr(CPR0_CFGADDR, cpr_reg);
- cpr_value = mfdcr(CPR0_CFGDATA);
- mtdcr(CPR0_CFGADDR, cpr_cfgaddr_temp);
- mtmsr(msr);
-
- return (cpr_value);
-}
-
-/*----------------------------------------------------------------------------+
-| Indirect Access of the System DCR's (SDR)
-| ppcMfsdr
-+----------------------------------------------------------------------------*/
-unsigned long ppcMfsdr(unsigned long sdr_reg)
-{
- unsigned long msr;
- unsigned long sdr_cfgaddr_temp;
- unsigned long sdr_value;
-
- msr = (mfmsr () & ~(MSR_EE));
- sdr_cfgaddr_temp = mfdcr(SDR0_CFGADDR);
- mtdcr(SDR0_CFGADDR, sdr_reg);
- sdr_value = mfdcr(SDR0_CFGDATA);
- mtdcr(SDR0_CFGADDR, sdr_cfgaddr_temp);
- mtmsr(msr);
-
- return (sdr_value);
-}
diff --git a/board/stamp/Makefile b/board/bf533-ezkit/Makefile
index ee52007b791..4fe7d785f36 100644
--- a/board/stamp/Makefile
+++ b/board/bf533-ezkit/Makefile
@@ -1,7 +1,7 @@
#
# U-boot - Makefile
#
-# Copyright (c) 2005 blackfin.uclinux.org
+# Copyright (c) 2007 Analog Device Inc.
#
# (C) Copyright 2000-2006
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
@@ -25,41 +25,28 @@
# MA 02111-1307 USA
#
-#
-# (C) Copyright 2001-2006
-# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
-#
-# See file CREDITS for list of people who contributed to this
-# project.
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License as
-# published by the Free Software Foundation; either version 2 of
-# the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
-# MA 02111-1307 USA
-#
-
include $(TOPDIR)/config.mk
LIB = $(obj)lib$(BOARD).a
-COBJS = $(BOARD).o stamp.o
+COBJS := $(BOARD).o flash.o
SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
OBJS := $(addprefix $(obj),$(COBJS))
SOBJS := $(addprefix $(obj),$(SOBJS))
-$(LIB): $(obj).depend $(OBJS)
- $(AR) $(ARFLAGS) $@ $(OBJS)
+$(LIB): $(obj).depend $(OBJS) $(SOBJS) u-boot.lds
+ $(AR) $(ARFLAGS) $@ $(OBJS) $(SOBJS)
+
+u-boot.lds: u-boot.lds.S
+ $(CPP) $(CPPFLAGS) -P -Ubfin $^ > $@.tmp
+ mv -f $@.tmp $@
+
+clean:
+ rm -f $(SOBJS) $(OBJS)
+
+distclean: clean
+ rm -f $(LIB) core *.bak .depend
#########################################################################
diff --git a/board/ezkit533/ezkit533.c b/board/bf533-ezkit/bf533-ezkit.c
index 8d6c8de70b0..feaeb006970 100644
--- a/board/ezkit533/ezkit533.c
+++ b/board/bf533-ezkit/bf533-ezkit.c
@@ -30,24 +30,28 @@
#include "psd4256.h"
#endif
-DECLARE_GLOBAL_DATA_PTR;
-
int checkboard(void)
{
+#if (BFIN_CPU == ADSP_BF531)
+ printf("CPU: ADSP BF531 Rev.: 0.%d\n", *pCHIPID >> 28);
+#elif (BFIN_CPU == ADSP_BF532)
+ printf("CPU: ADSP BF532 Rev.: 0.%d\n", *pCHIPID >> 28);
+#else
printf("CPU: ADSP BF533 Rev.: 0.%d\n", *pCHIPID >> 28);
+#endif
printf("Board: ADI BF533 EZ-Kit Lite board\n");
printf(" Support: http://blackfin.uclinux.org/\n");
- printf(" Richard Klingler <richard@uclinux.net>\n");
return 0;
}
long int initdram(int board_type)
{
+ DECLARE_GLOBAL_DATA_PTR;
#ifdef DEBUG
int brate;
char *tmp = getenv("baudrate");
brate = simple_strtoul(tmp, NULL, 16);
- printf("Serial Port initialized with Baud rate = %x\n",brate);
+ printf("Serial Port initialized with Baud rate = %x\n", brate);
printf("SDRAM attributes:\n");
printf("tRCD %d SCLK Cycles,tRP %d SCLK Cycles,tRAS %d SCLK Cycles"
"tWR %d SCLK Cycles,CAS Latency %d SCLK cycles \n",
@@ -64,9 +68,13 @@ long int initdram(int board_type)
/* miscellaneous platform dependent initialisations */
int misc_init_r(void)
{
- /* Set direction bits for Video en/decoder reset as output */
- *(volatile unsigned char *)(CFG_FLASH1_BASE + PSD_PORTA_DIR) = PSDA_VDEC_RST | PSDA_VENC_RST;
- /* Deactivate Video en/decoder reset lines */
- *(volatile unsigned char *)(CFG_FLASH1_BASE + PSD_PORTA_DOUT) = PSDA_VDEC_RST | PSDA_VENC_RST;
+ /* Set direction bits for Video en/decoder reset as output */
+ *(volatile unsigned char *)(CFG_FLASH1_BASE + PSD_PORTA_DIR) =
+ PSDA_VDEC_RST | PSDA_VENC_RST;
+ /* Deactivate Video en/decoder reset lines */
+ *(volatile unsigned char *)(CFG_FLASH1_BASE + PSD_PORTA_DOUT) =
+ PSDA_VDEC_RST | PSDA_VENC_RST;
+
+ return 0;
}
#endif
diff --git a/board/bf533-ezkit/config.mk b/board/bf533-ezkit/config.mk
new file mode 100644
index 00000000000..f39be5fcb04
--- /dev/null
+++ b/board/bf533-ezkit/config.mk
@@ -0,0 +1,25 @@
+#
+# (C) Copyright 2001
+# 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
+#
+# TEXT_BASE should be defined as the MAX_SDRAM Address - 256k bytes
+# 256k is defined as CFG_MONITOR_LEN in ./include/configs/<board>.h
+TEXT_BASE = 0x01FC0000
diff --git a/board/ezkit533/flash-defines.h b/board/bf533-ezkit/flash-defines.h
index 8f9dff5de81..e211918bc20 100644
--- a/board/ezkit533/flash-defines.h
+++ b/board/bf533-ezkit/flash-defines.h
@@ -52,17 +52,13 @@
#define CFG_FLASH0_BASE 0x20000000
#define RESET_VAL 0xF0
-
-asm("#define FLASH_START_L 0x0000");
-asm("#define FLASH_START_H 0x2000");
-
flash_info_t flash_info[CFG_MAX_FLASH_BANKS];
int get_codes(void);
int poll_toggle_bit(long lOffset);
void reset_flash(void);
int erase_flash(void);
-int erase_block_flash(int,unsigned long);
+int erase_block_flash(int, unsigned long);
void unlock_flash(long lOffset);
int write_data(long lStart, long lCount, long lStride, int *pnData);
int FillData(long lStart, long lCount, long lStride, int *pnData);
diff --git a/board/ezkit533/flash.c b/board/bf533-ezkit/flash.c
index b0a0796b864..067a2609065 100644
--- a/board/ezkit533/flash.c
+++ b/board/bf533-ezkit/flash.c
@@ -26,6 +26,7 @@
* MA 02111-1307 USA
*/
+#include <asm/io.h>
#include "flash-defines.h"
void flash_reset(void)
@@ -33,14 +34,13 @@ void flash_reset(void)
reset_flash();
}
-unsigned long flash_get_size(ulong baseaddr, flash_info_t * info,
- int bank_flag)
+unsigned long flash_get_size(ulong baseaddr, flash_info_t * info, int bank_flag)
{
int id = 0, i = 0;
static int FlagDev = 1;
id = get_codes();
- if(FlagDev) {
+ if (FlagDev) {
#ifdef DEBUG
printf("Device ID of the Flash is %x\n", id);
#endif
@@ -100,10 +100,11 @@ unsigned long flash_init(void)
if (flash_info[0].flash_id == FLASH_UNKNOWN || size_b0 == 0) {
printf("## Unknown FLASH on Bank 0 - Size = 0x%08lx = %ld MB\n",
- size_b0, size_b0 >> 20);
+ size_b0, size_b0 >> 20);
}
- (void)flash_protect(FLAG_PROTECT_SET,CFG_FLASH0_BASE,(flash_info[0].start[2] - 1),&flash_info[0]);
+ (void)flash_protect(FLAG_PROTECT_SET, CFG_FLASH0_BASE,
+ (flash_info[0].start[2] - 1), &flash_info[0]);
return (size_b0 + size_b1 + size_b2);
}
@@ -122,15 +123,14 @@ void flash_print_info(flash_info_t * info)
printf("ST Microelectronics ");
break;
default:
- printf("Unknown Vendor ");
+ printf("Unknown Vendor: (0x%08X) ", info->flash_id);
break;
}
for (i = 0; i < info->sector_count; ++i) {
if ((i % 5) == 0)
printf("\n ");
printf(" %08lX%s",
- info->start[i],
- info->protect[i] ? " (RO)" : " ");
+ info->start[i], info->protect[i] ? " (RO)" : " ");
}
printf("\n");
return;
@@ -138,8 +138,8 @@ void flash_print_info(flash_info_t * info)
int flash_erase(flash_info_t * info, int s_first, int s_last)
{
- int cnt = 0,i;
- int prot,sect;
+ int cnt = 0, i;
+ int prot, sect;
prot = 0;
for (sect = s_first; sect <= s_last; ++sect) {
@@ -148,15 +148,16 @@ int flash_erase(flash_info_t * info, int s_first, int s_last)
}
if (prot)
- printf ("- Warning: %d protected sectors will not be erased!\n", prot);
+ printf("- Warning: %d protected sectors will not be erased!\n",
+ prot);
else
- printf ("\n");
+ printf("\n");
cnt = s_last - s_first + 1;
if (cnt == FLASH_TOT_SECT) {
printf("Erasing flash, Please Wait \n");
- if(erase_flash() < 0) {
+ if (erase_flash() < 0) {
printf("Erasing flash failed \n");
return FLASH_FAIL;
}
@@ -164,7 +165,7 @@ int flash_erase(flash_info_t * info, int s_first, int s_last)
printf("Erasing Flash locations, Please Wait\n");
for (i = s_first; i <= s_last; i++) {
if (info->protect[i] == 0) { /* not protected */
- if(erase_block_flash(i, info->start[i]) < 0) {
+ if (erase_block_flash(i, info->start[i]) < 0) {
printf("Error Sector erasing \n");
return FLASH_FAIL;
}
@@ -178,13 +179,12 @@ int write_buff(flash_info_t * info, uchar * src, ulong addr, ulong cnt)
{
int ret;
- ret = write_data(addr, cnt, 1, (int *) src);
- if(ret == FLASH_FAIL)
+ ret = write_data(addr, cnt, 1, (int *)src);
+ if (ret == FLASH_FAIL)
return ERR_NOT_ERASED;
return FLASH_SUCCESS;
}
-
int write_data(long lStart, long lCount, long lStride, int *pnData)
{
long i = 0;
@@ -198,20 +198,23 @@ int write_data(long lStart, long lCount, long lStride, int *pnData)
for (i = 0; (i < lCount / 4) && (i < BUFFER_SIZE); i++) {
for (iShift = 0, j = 0; (j < iNumWords);
- j++, ulOffset += (lStride * 2)) {
+ j++, ulOffset += (lStride * 2)) {
if ((ulOffset >= INVALIDLOCNSTART)
- && (ulOffset < INVALIDLOCNEND)) {
- printf("Invalid locations, Try writing to another location \n");
+ && (ulOffset < INVALIDLOCNEND)) {
+ printf
+ ("Invalid locations, Try writing to another location \n");
return FLASH_FAIL;
}
get_sector_number(ulOffset, &nSector);
- read_flash(ulOffset,&d);
- if(d != 0xffff) {
- printf("Flash not erased at offset 0x%x Please erase to reprogram \n",ulOffset);
+ read_flash(ulOffset, &d);
+ if (d != 0xffff) {
+ printf
+ ("Flash not erased at offset 0x%x Please erase to reprogram \n",
+ ulOffset);
return FLASH_FAIL;
}
unlock_flash(ulOffset);
- if(write_flash(ulOffset, (pnData[i] >> iShift)) < 0) {
+ if (write_flash(ulOffset, (pnData[i] >> iShift)) < 0) {
printf("Error programming the flash \n");
return FLASH_FAIL;
}
@@ -220,17 +223,18 @@ int write_data(long lStart, long lCount, long lStride, int *pnData)
}
if (nLeftover > 0) {
if ((ulOffset >= INVALIDLOCNSTART)
- && (ulOffset < INVALIDLOCNEND))
- return FLASH_FAIL;
+ && (ulOffset < INVALIDLOCNEND))
+ return FLASH_FAIL;
get_sector_number(ulOffset, &nSector);
- read_flash(ulOffset,&d);
- if(d != 0xffff) {
- printf("Flash already programmed. Please erase to reprogram \n");
- printf("uloffset = 0x%x \t d = 0x%x\n",ulOffset,d);
+ read_flash(ulOffset, &d);
+ if (d != 0xffff) {
+ printf
+ ("Flash already programmed. Please erase to reprogram \n");
+ printf("uloffset = 0x%x \t d = 0x%x\n", ulOffset, d);
return FLASH_FAIL;
}
unlock_flash(ulOffset);
- if(write_flash(ulOffset, pnData[i]) < 0) {
+ if (write_flash(ulOffset, pnData[i]) < 0) {
printf("Error programming the flash \n");
return FLASH_FAIL;
}
@@ -252,8 +256,8 @@ int read_data(long ulStart, long lCount, long lStride, int *pnData)
for (i = 0; (i < lCount / 4) && (i < BUFFER_SIZE); i++) {
for (iShift = 0, j = 0; j < iNumWords; j += 2) {
if ((ulOffset >= INVALIDLOCNSTART)
- && (ulOffset < INVALIDLOCNEND))
- return FLASH_FAIL;
+ && (ulOffset < INVALIDLOCNEND))
+ return FLASH_FAIL;
get_sector_number(ulOffset, &nSector);
read_flash(ulOffset, &nLow);
@@ -265,8 +269,8 @@ int read_data(long ulStart, long lCount, long lStride, int *pnData)
}
if (nLeftover > 0) {
if ((ulOffset >= INVALIDLOCNSTART)
- && (ulOffset < INVALIDLOCNEND))
- return FLASH_FAIL;
+ && (ulOffset < INVALIDLOCNEND))
+ return FLASH_FAIL;
get_sector_number(ulOffset, &nSector);
read_flash(ulOffset, &pnData[i]);
@@ -279,10 +283,10 @@ int write_flash(long nOffset, int nValue)
long addr;
addr = (CFG_FLASH_BASE + nOffset);
- asm("ssync;");
- *(unsigned volatile short *) addr = nValue;
- asm("ssync;");
- if(poll_toggle_bit(nOffset) < 0)
+ sync();
+ *(unsigned volatile short *)addr = nValue;
+ sync();
+ if (poll_toggle_bit(nOffset) < 0)
return FLASH_FAIL;
return FLASH_SUCCESS;
}
@@ -294,29 +298,30 @@ int read_flash(long nOffset, int *pnValue)
if (nOffset != 0x2)
reset_flash();
- asm("ssync;");
- nValue = *(volatile unsigned short *) addr;
- asm("ssync;");
+ sync();
+ nValue = *(volatile unsigned short *)addr;
+ sync();
*pnValue = nValue;
return TRUE;
}
int poll_toggle_bit(long lOffset)
{
- unsigned int u1,u2;
+ unsigned int u1, u2;
unsigned long timeout = 0xFFFFFFFF;
- volatile unsigned long *FB = (volatile unsigned long *)(0x20000000 + lOffset);
- while(1) {
- if(timeout < 0)
+ volatile unsigned long *FB =
+ (volatile unsigned long *)(0x20000000 + lOffset);
+ while (1) {
+ if (timeout < 0)
break;
u1 = *(volatile unsigned short *)FB;
u2 = *(volatile unsigned short *)FB;
- if((u1 & 0x0040) == (u2 & 0x0040))
+ if ((u1 & 0x0040) == (u2 & 0x0040))
return FLASH_SUCCESS;
- if((u2 & 0x0020) == 0x0000)
+ if ((u2 & 0x0020) == 0x0000)
continue;
u1 = *(volatile unsigned short *)FB;
- if((u2 & 0x0040) == (u1 & 0x0040))
+ if ((u2 & 0x0040) == (u1 & 0x0040))
return FLASH_SUCCESS;
else {
reset_flash();
@@ -325,7 +330,8 @@ int poll_toggle_bit(long lOffset)
timeout--;
}
printf("Time out occured \n");
- if(timeout <0) return FLASH_FAIL;
+ if (timeout < 0)
+ return FLASH_FAIL;
}
void reset_flash(void)
@@ -344,7 +350,7 @@ int erase_flash(void)
write_flash(WRITESEQ5, WRITEDATA5);
write_flash(WRITESEQ6, WRITEDATA6);
- if(poll_toggle_bit(0x0000) < 0)
+ if (poll_toggle_bit(0x0000) < 0)
return FLASH_FAIL;
write_flash(SecFlashAOff + WRITESEQ1, WRITEDATA1);
@@ -354,7 +360,7 @@ int erase_flash(void)
write_flash(SecFlashAOff + WRITESEQ5, WRITEDATA5);
write_flash(SecFlashAOff + WRITESEQ6, WRITEDATA6);
- if(poll_toggle_bit(SecFlashASec1Off) < 0)
+ if (poll_toggle_bit(SecFlashASec1Off) < 0)
return FLASH_FAIL;
write_flash(PriFlashBOff + WRITESEQ1, WRITEDATA1);
@@ -364,7 +370,7 @@ int erase_flash(void)
write_flash(PriFlashBOff + WRITESEQ5, WRITEDATA5);
write_flash(PriFlashBOff + WRITESEQ6, WRITEDATA6);
- if(poll_toggle_bit(PriFlashBOff) <0)
+ if (poll_toggle_bit(PriFlashBOff) < 0)
return FLASH_FAIL;
write_flash(SecFlashBOff + WRITESEQ1, WRITEDATA1);
@@ -374,7 +380,7 @@ int erase_flash(void)
write_flash(SecFlashBOff + WRITESEQ5, WRITEDATA5);
write_flash(SecFlashBOff + WRITESEQ6, WRITEDATA6);
- if(poll_toggle_bit(SecFlashBOff) < 0)
+ if (poll_toggle_bit(SecFlashBOff) < 0)
return FLASH_FAIL;
return FLASH_SUCCESS;
@@ -397,7 +403,7 @@ int erase_block_flash(int nBlock, unsigned long address)
write_flash(ulSectorOff, BlockEraseVal);
- if(poll_toggle_bit(ulSectorOff) < 0)
+ if (poll_toggle_bit(ulSectorOff) < 0)
return FLASH_FAIL;
return FLASH_SUCCESS;
@@ -435,34 +441,34 @@ void get_sector_number(long ulOffset, int *pnSector)
if (ulOffset >= SecFlashAOff) {
if ((ulOffset < SecFlashASec1Off)
- && (ulOffset < SecFlashASec2Off)) {
- nSector = SECT32;
+ && (ulOffset < SecFlashASec2Off)) {
+ nSector = SECT32;
} else if ((ulOffset >= SecFlashASec2Off)
- && (ulOffset < SecFlashASec3Off)) {
- nSector = SECT33;
+ && (ulOffset < SecFlashASec3Off)) {
+ nSector = SECT33;
} else if ((ulOffset >= SecFlashASec3Off)
- && (ulOffset < SecFlashASec4Off)) {
- nSector = SECT34;
+ && (ulOffset < SecFlashASec4Off)) {
+ nSector = SECT34;
} else if ((ulOffset >= SecFlashASec4Off)
- && (ulOffset < SecFlashAEndOff)) {
- nSector = SECT35;
+ && (ulOffset < SecFlashAEndOff)) {
+ nSector = SECT35;
}
} else if (ulOffset >= SecFlashBOff) {
if ((ulOffset < SecFlashBSec1Off)
- && (ulOffset < SecFlashBSec2Off)) {
- nSector = SECT36;
+ && (ulOffset < SecFlashBSec2Off)) {
+ nSector = SECT36;
}
if ((ulOffset < SecFlashBSec2Off)
- && (ulOffset < SecFlashBSec3Off)) {
- nSector = SECT37;
+ && (ulOffset < SecFlashBSec3Off)) {
+ nSector = SECT37;
}
if ((ulOffset < SecFlashBSec3Off)
- && (ulOffset < SecFlashBSec4Off)) {
- nSector = SECT38;
+ && (ulOffset < SecFlashBSec4Off)) {
+ nSector = SECT38;
}
if ((ulOffset < SecFlashBSec4Off)
- && (ulOffset < SecFlashBEndOff)) {
- nSector = SECT39;
+ && (ulOffset < SecFlashBEndOff)) {
+ nSector = SECT39;
}
} else if ((ulOffset >= PriFlashAOff) && (ulOffset < SecFlashAOff)) {
nSector = ulOffset & 0xffff0000;
diff --git a/board/ezkit533/psd4256.h b/board/bf533-ezkit/psd4256.h
index 01f656601b7..97765165f88 100644
--- a/board/ezkit533/psd4256.h
+++ b/board/bf533-ezkit/psd4256.h
@@ -49,19 +49,19 @@
* Flash A Port A Bit definitions
*/
-#define PSDA_PPICLK1 0x20 /* PPI Clock select bit 1 */
-#define PSDA_PPICLK0 0x10 /* PPI Clock select bit 0 */
-#define PSDA_VDEC_RST 0x08 /* Video decoder reset, 0 = RESET */
-#define PSDA_VENC_RST 0x04 /* Video encoder reset, 0 = RESET */
-#define PSDA_CODEC_RST 0x01 /* Codec reset, 0 = RESET */
+#define PSDA_PPICLK1 0x20 /* PPI Clock select bit 1 */
+#define PSDA_PPICLK0 0x10 /* PPI Clock select bit 0 */
+#define PSDA_VDEC_RST 0x08 /* Video decoder reset, 0 = RESET */
+#define PSDA_VENC_RST 0x04 /* Video encoder reset, 0 = RESET */
+#define PSDA_CODEC_RST 0x01 /* Codec reset, 0 = RESET */
/*
* Flash A Port B Bit definitions
*/
-#define PSDA_LED9 0x20 /* LED 9, 1 = LED ON */
-#define PSDA_LED8 0x10 /* LED 8, 1 = LED ON */
-#define PSDA_LED7 0x08 /* LED 7, 1 = LED ON */
-#define PSDA_LED6 0x04 /* LED 6, 1 = LED ON */
-#define PSDA_LED5 0x02 /* LED 5, 1 = LED ON */
-#define PSDA_LED4 0x01 /* LED 4, 1 = LED ON */
+#define PSDA_LED9 0x20 /* LED 9, 1 = LED ON */
+#define PSDA_LED8 0x10 /* LED 8, 1 = LED ON */
+#define PSDA_LED7 0x08 /* LED 7, 1 = LED ON */
+#define PSDA_LED6 0x04 /* LED 6, 1 = LED ON */
+#define PSDA_LED5 0x02 /* LED 5, 1 = LED ON */
+#define PSDA_LED4 0x01 /* LED 4, 1 = LED ON */
diff --git a/board/ezkit533/u-boot.lds b/board/bf533-ezkit/u-boot.lds.S
index 10203ff89be..9742e0297c0 100644
--- a/board/ezkit533/u-boot.lds
+++ b/board/bf533-ezkit/u-boot.lds.S
@@ -1,7 +1,7 @@
/*
- * U-boot - u-boot.lds
+ * U-boot - u-boot.lds.S
*
- * Copyright (c) 2005 blackfin.uclinux.org
+ * Copyright (c) 2005-2007 Analog Device Inc.
*
* (C) Copyright 2000-2004
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
@@ -25,6 +25,8 @@
* MA 02111-1307 USA
*/
+#include <config.h>
+
OUTPUT_ARCH(bfin)
SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib);
/* Do we need any of these for elf?
@@ -55,6 +57,7 @@ SECTIONS
.rela.plt : { *(.rela.plt) }
.init : { *(.init) }
.plt : { *(.plt) }
+ . = CFG_MONITOR_BASE;
.text :
{
/* WARNING - the following is hand-optimized to fit within */
@@ -68,10 +71,11 @@ SECTIONS
cpu/bf533/interrupt.o (.text)
cpu/bf533/serial.o (.text)
common/dlmalloc.o (.text)
- lib_generic/vsprintf.o (.text)
+/* lib_blackfin/bf533_string.o (.text) */
+/* lib_generic/vsprintf.o (.text) */
lib_generic/crc32.o (.text)
lib_generic/zlib.o (.text)
- board/ezkit533/ezkit533.o (.text)
+ board/bf533-ezkit/bf533-ezkit.o (.text)
. = DEFINED(env_offset) ? env_offset : .;
common/environment.o (.text)
@@ -119,9 +123,9 @@ SECTIONS
_edata = .;
PROVIDE (edata = .);
- __u_boot_cmd_start = .;
+ ___u_boot_cmd_start = .;
.u_boot_cmd : { *(.u_boot_cmd) }
- __u_boot_cmd_end = .;
+ ___u_boot_cmd_end = .;
__start___ex_table = .;
diff --git a/board/bf533-stamp/Makefile b/board/bf533-stamp/Makefile
new file mode 100644
index 00000000000..8223d591ce4
--- /dev/null
+++ b/board/bf533-stamp/Makefile
@@ -0,0 +1,58 @@
+#
+# U-boot - Makefile
+#
+# Copyright (c) 2007 Analog Device Inc.
+#
+# (C) Copyright 2000-2006
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+include $(TOPDIR)/config.mk
+
+LIB = $(obj)lib$(BOARD).a
+
+COBJS := $(BOARD).o spi.o
+
+SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(COBJS))
+SOBJS := $(addprefix $(obj),$(SOBJS))
+
+$(LIB): $(obj).depend $(OBJS) $(SOBJS) u-boot.lds
+ $(AR) $(ARFLAGS) $@ $(OBJS) $(SOBJS)
+
+u-boot.lds: u-boot.lds.S
+ $(CPP) $(CPPFLAGS) -P -Ubfin $^ > $@.tmp
+ mv -f $@.tmp $@
+
+clean:
+ rm -f $(SOBJS) $(OBJS)
+
+distclean: clean
+ rm -f $(LIB) core *.bak .depend
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/board/stamp/stamp.c b/board/bf533-stamp/bf533-stamp.c
index 7e3af20eab2..2f6e75187b1 100644
--- a/board/stamp/stamp.c
+++ b/board/bf533-stamp/bf533-stamp.c
@@ -27,9 +27,8 @@
#include <common.h>
#include <asm/mem_init.h>
-#include "stamp.h"
-
-DECLARE_GLOBAL_DATA_PTR;
+#include <asm/io.h>
+#include "bf533-stamp.h"
#define STATUS_LED_OFF 0
#define STATUS_LED_ON 1
@@ -40,42 +39,45 @@ DECLARE_GLOBAL_DATA_PTR;
# define SHOW_BOOT_PROGRESS(arg)
#endif
-int checkboard (void)
+int checkboard(void)
{
- printf ("CPU: ADSP BF533 Rev.: 0.%d\n", *pCHIPID >> 28);
- printf ("Board: ADI BF533 Stamp board\n");
- printf (" Support: http://blackfin.uclinux.org/\n");
- printf (" Richard Klingler <richard@uclinux.net>\n");
+#if (BFIN_CPU == ADSP_BF531)
+ printf("CPU: ADSP BF531 Rev.: 0.%d\n", *pCHIPID >> 28);
+#elif (BFIN_CPU == ADSP_BF532)
+ printf("CPU: ADSP BF532 Rev.: 0.%d\n", *pCHIPID >> 28);
+#else
+ printf("CPU: ADSP BF533 Rev.: 0.%d\n", *pCHIPID >> 28);
+#endif
+ printf("Board: ADI BF533 Stamp board\n");
+ printf(" Support: http://blackfin.uclinux.org/\n");
return 0;
}
-long int initdram (int board_type)
+long int initdram(int board_type)
{
+ DECLARE_GLOBAL_DATA_PTR;
#ifdef DEBUG
- printf ("SDRAM attributes:\n");
- printf (" tRCD:%d Cycles; tRP:%d Cycles; tRAS:%d Cycles; tWR:%d Cycles; "
- "CAS Latency:%d cycles\n",
- (SDRAM_tRCD >> 15),
- (SDRAM_tRP >> 11),
- (SDRAM_tRAS >> 6),
- (SDRAM_tWR >> 19),
- (SDRAM_CL >> 2));
- printf ("SDRAM Begin: 0x%x\n", CFG_SDRAM_BASE);
- printf ("Bank size = %d MB\n", 128);
+ printf("SDRAM attributes:\n");
+ printf
+ (" tRCD:%d Cycles; tRP:%d Cycles; tRAS:%d Cycles; tWR:%d Cycles; "
+ "CAS Latency:%d cycles\n", (SDRAM_tRCD >> 15), (SDRAM_tRP >> 11),
+ (SDRAM_tRAS >> 6), (SDRAM_tWR >> 19), (SDRAM_CL >> 2));
+ printf("SDRAM Begin: 0x%x\n", CFG_SDRAM_BASE);
+ printf("Bank size = %d MB\n", 128);
#endif
gd->bd->bi_memstart = CFG_SDRAM_BASE;
gd->bd->bi_memsize = CFG_MAX_RAM_SIZE;
return (gd->bd->bi_memsize);
}
-void swap_to (int device_id)
+void swap_to(int device_id)
{
if (device_id == ETHERNET) {
*pFIO_DIR = PF0;
- asm ("ssync;");
+ sync();
*pFIO_FLAG_S = PF0;
- asm ("ssync;");
+ sync();
} else if (device_id == FLASH) {
*pFIO_DIR = (PF4 | PF3 | PF2 | PF1 | PF0);
*pFIO_FLAG_S = (PF4 | PF3 | PF2);
@@ -85,9 +87,9 @@ void swap_to (int device_id)
*pFIO_EDGE = (PF8 | PF7 | PF6 | PF5);
*pFIO_INEN = (PF8 | PF7 | PF6 | PF5);
*pFIO_FLAG_D = (PF4 | PF3 | PF2);
- asm ("ssync;");
+ sync();
} else {
- printf ("Unknown bank to switch\n");
+ printf("Unknown bank to switch\n");
}
return;
@@ -95,7 +97,7 @@ void swap_to (int device_id)
#if defined(CONFIG_MISC_INIT_R)
/* miscellaneous platform dependent initialisations */
-int misc_init_r (void)
+int misc_init_r(void)
{
int i;
int cf_stat = 0;
@@ -104,7 +106,7 @@ int misc_init_r (void)
*pFIO_EDGE = FIO_EDGE_CF_BITS;
*pFIO_POLAR = FIO_POLAR_CF_BITS;
for (i = 0; i < 0x300; i++)
- asm ("nop;");
+ asm("nop;");
if ((*pFIO_FLAG_S) & CF_STAT_BITS) {
cf_stat = 0;
@@ -115,37 +117,36 @@ int misc_init_r (void)
*pFIO_EDGE = FIO_EDGE_BITS;
*pFIO_POLAR = FIO_POLAR_BITS;
-
if (cf_stat) {
- printf ("Booting from COMPACT flash\n");
+ printf("Booting from COMPACT flash\n");
/* Set cycle time for CF */
- *(volatile unsigned long *) ambctl1 = CF_AMBCTL1VAL;
+ *(volatile unsigned long *)ambctl1 = CF_AMBCTL1VAL;
for (i = 0; i < 0x1000; i++)
- asm ("nop;");
+ asm("nop;");
for (i = 0; i < 0x1000; i++)
- asm ("nop;");
+ asm("nop;");
for (i = 0; i < 0x1000; i++)
- asm ("nop;");
+ asm("nop;");
- serial_setbrg ();
- ide_init ();
+ serial_setbrg();
+ ide_init();
- setenv ("bootargs", "");
- setenv ("bootcmd",
- "fatload ide 0:1 0x1000000 uImage-stamp;bootm 0x1000000;bootm 0x20100000");
+ setenv("bootargs", "");
+ setenv("bootcmd",
+ "fatload ide 0:1 0x1000000 uImage-stamp;bootm 0x1000000;bootm 0x20100000");
} else {
- printf ("Booting from FLASH\n");
+ printf("Booting from FLASH\n");
}
- return 1;
+ return 0;
}
#endif
#ifdef CONFIG_STAMP_CF
-void cf_outb (unsigned char val, volatile unsigned char *addr)
+void cf_outb(unsigned char val, volatile unsigned char *addr)
{
/*
* Set PF1 PF0 respectively to 0 1 to divert address
@@ -153,70 +154,70 @@ void cf_outb (unsigned char val, volatile unsigned char *addr)
*/
*pFIO_FLAG_S = CF_PF0;
*pFIO_FLAG_C = CF_PF1;
- asm ("ssync;");
+ sync();
*(addr) = val;
- asm ("ssync;");
+ sync();
/* Setback PF1 PF0 to 0 0 to address external
* memory banks */
- *(volatile unsigned short *) pFIO_FLAG_C = CF_PF1_PF0;
- asm ("ssync;");
+ *(volatile unsigned short *)pFIO_FLAG_C = CF_PF1_PF0;
+ sync();
}
-unsigned char cf_inb (volatile unsigned char *addr)
+unsigned char cf_inb(volatile unsigned char *addr)
{
volatile unsigned char c;
*pFIO_FLAG_S = CF_PF0;
*pFIO_FLAG_C = CF_PF1;
- asm ("ssync;");
+ sync();
c = *(addr);
- asm ("ssync;");
+ sync();
*pFIO_FLAG_C = CF_PF1_PF0;
- asm ("ssync;");
+ sync();
return c;
}
-void cf_insw (unsigned short *sect_buf, unsigned short *addr, int words)
+void cf_insw(unsigned short *sect_buf, unsigned short *addr, int words)
{
int i;
*pFIO_FLAG_S = CF_PF0;
*pFIO_FLAG_C = CF_PF1;
- asm ("ssync;");
+ sync();
for (i = 0; i < words; i++) {
*(sect_buf + i) = *(addr);
- asm ("ssync;");
+ sync();
}
*pFIO_FLAG_C = CF_PF1_PF0;
- asm ("ssync;");
+ sync();
}
-void cf_outsw (unsigned short *addr, unsigned short *sect_buf, int words)
+void cf_outsw(unsigned short *addr, unsigned short *sect_buf, int words)
{
int i;
*pFIO_FLAG_S = CF_PF0;
*pFIO_FLAG_C = CF_PF1;
- asm ("ssync;");
+ sync();
for (i = 0; i < words; i++) {
*(addr) = *(sect_buf + i);
- asm ("ssync;");
+ sync();
}
*pFIO_FLAG_C = CF_PF1_PF0;
- asm ("ssync;");
+ sync();
}
#endif
-void stamp_led_set (int LED1, int LED2, int LED3)
+void stamp_led_set(int LED1, int LED2, int LED3)
{
*pFIO_INEN &= ~(PF2 | PF3 | PF4);
*pFIO_DIR |= (PF2 | PF3 | PF4);
@@ -233,31 +234,31 @@ void stamp_led_set (int LED1, int LED2, int LED3)
*pFIO_FLAG_S = PF4;
else
*pFIO_FLAG_C = PF4;
- asm ("ssync;");
+ sync();
}
-void show_boot_progress (int status)
+void show_boot_progress(int status)
{
switch (status) {
case 1:
- stamp_led_set (STATUS_LED_OFF, STATUS_LED_OFF, STATUS_LED_ON);
+ stamp_led_set(STATUS_LED_OFF, STATUS_LED_OFF, STATUS_LED_ON);
break;
case 2:
- stamp_led_set (STATUS_LED_OFF, STATUS_LED_ON, STATUS_LED_OFF);
+ stamp_led_set(STATUS_LED_OFF, STATUS_LED_ON, STATUS_LED_OFF);
break;
case 3:
- stamp_led_set (STATUS_LED_OFF, STATUS_LED_ON, STATUS_LED_ON);
+ stamp_led_set(STATUS_LED_OFF, STATUS_LED_ON, STATUS_LED_ON);
break;
case 4:
- stamp_led_set (STATUS_LED_ON, STATUS_LED_OFF, STATUS_LED_OFF);
+ stamp_led_set(STATUS_LED_ON, STATUS_LED_OFF, STATUS_LED_OFF);
break;
case 5:
case 6:
- stamp_led_set (STATUS_LED_ON, STATUS_LED_OFF, STATUS_LED_ON);
+ stamp_led_set(STATUS_LED_ON, STATUS_LED_OFF, STATUS_LED_ON);
break;
case 7:
case 8:
- stamp_led_set (STATUS_LED_ON, STATUS_LED_ON, STATUS_LED_OFF);
+ stamp_led_set(STATUS_LED_ON, STATUS_LED_ON, STATUS_LED_OFF);
break;
case 9:
case 10:
@@ -266,11 +267,10 @@ void show_boot_progress (int status)
case 13:
case 14:
case 15:
- stamp_led_set (STATUS_LED_OFF, STATUS_LED_OFF,
- STATUS_LED_OFF);
+ stamp_led_set(STATUS_LED_OFF, STATUS_LED_OFF, STATUS_LED_OFF);
break;
default:
- stamp_led_set (STATUS_LED_ON, STATUS_LED_ON, STATUS_LED_ON);
+ stamp_led_set(STATUS_LED_ON, STATUS_LED_ON, STATUS_LED_ON);
break;
}
}
diff --git a/board/stamp/stamp.h b/board/bf533-stamp/bf533-stamp.h
index 7bc33b41476..b2b51aa2ba2 100644
--- a/board/stamp/stamp.h
+++ b/board/bf533-stamp/bf533-stamp.h
@@ -36,7 +36,6 @@ extern volatile unsigned long *amgctl;
extern unsigned long pll_div_fact;
extern void serial_setbrg(void);
-extern void pll_set(int vco, int crystal_frq, int pll_div);
/* Definitions used in Compact Flash Boot support */
#define FIO_EDGE_CF_BITS 0x0000
diff --git a/board/bf533-stamp/config.mk b/board/bf533-stamp/config.mk
new file mode 100644
index 00000000000..113438b4ff6
--- /dev/null
+++ b/board/bf533-stamp/config.mk
@@ -0,0 +1,25 @@
+#
+# (C) Copyright 2001
+# 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
+#
+# TEXT_BASE should be defined as the MAX_SDRAM Address - 256k bytes
+# 256k is defined as CFG_MONITOR_LEN in ./include/configs/<board>.h
+TEXT_BASE = 0x07FC0000
diff --git a/board/bf533-stamp/spi.c b/board/bf533-stamp/spi.c
new file mode 100644
index 00000000000..d30750faa3b
--- /dev/null
+++ b/board/bf533-stamp/spi.c
@@ -0,0 +1,473 @@
+/****************************************************************************
+ * SPI flash driver for M25P64
+ ****************************************************************************/
+#include <common.h>
+#include <linux/ctype.h>
+#include <asm/io.h>
+
+#if defined(CONFIG_SPI)
+
+ /*Application definitions */
+
+#define NUM_SECTORS 128 /* number of sectors */
+#define SECTOR_SIZE 0x10000
+#define NOP_NUM 1000
+
+#define COMMON_SPI_SETTINGS (SPE|MSTR|CPHA|CPOL) /*Settings to the SPI_CTL */
+#define TIMOD01 (0x01) /*stes the SPI to work with core instructions */
+
+ /*Flash commands */
+#define SPI_WREN (0x06) /*Set Write Enable Latch */
+#define SPI_WRDI (0x04) /*Reset Write Enable Latch */
+#define SPI_RDSR (0x05) /*Read Status Register */
+#define SPI_WRSR (0x01) /*Write Status Register */
+#define SPI_READ (0x03) /*Read data from memory */
+#define SPI_PP (0x02) /*Program Data into memory */
+#define SPI_SE (0xD8) /*Erase one sector in memory */
+#define SPI_BE (0xC7) /*Erase all memory */
+#define WIP (0x1) /*Check the write in progress bit of the SPI status register */
+#define WEL (0x2) /*Check the write enable bit of the SPI status register */
+
+#define TIMEOUT 350000000
+
+typedef enum {
+ NO_ERR,
+ POLL_TIMEOUT,
+ INVALID_SECTOR,
+ INVALID_BLOCK,
+} ERROR_CODE;
+
+void spi_init_f(void);
+void spi_init_r(void);
+ssize_t spi_read(uchar *, int, uchar *, int);
+ssize_t spi_write(uchar *, int, uchar *, int);
+
+char ReadStatusRegister(void);
+void Wait_For_SPIF(void);
+void SetupSPI(const int spi_setting);
+void SPI_OFF(void);
+void SendSingleCommand(const int iCommand);
+
+ERROR_CODE GetSectorNumber(unsigned long ulOffset, int *pnSector);
+ERROR_CODE EraseBlock(int nBlock);
+ERROR_CODE ReadData(unsigned long ulStart, long lCount, int *pnData);
+ERROR_CODE WriteData(unsigned long ulStart, long lCount, int *pnData);
+ERROR_CODE Wait_For_Status(char Statusbit);
+ERROR_CODE Wait_For_WEL(void);
+
+/* -------------------
+ * Variables
+ * ------------------- */
+
+/* **************************************************************************
+ *
+ * Function: spi_init_f
+ *
+ * Description: Init SPI-Controller (ROM part)
+ *
+ * return: ---
+ *
+ * *********************************************************************** */
+void spi_init_f(void)
+{
+}
+
+/* **************************************************************************
+ *
+ * Function: spi_init_r
+ *
+ * Description: Init SPI-Controller (RAM part) -
+ * The malloc engine is ready and we can move our buffers to
+ * normal RAM
+ *
+ * return: ---
+ *
+ * *********************************************************************** */
+void spi_init_r(void)
+{
+ return;
+}
+
+/****************************************************************************
+ * Function: spi_write
+ **************************************************************************** */
+ssize_t spi_write(uchar * addr, int alen, uchar * buffer, int len)
+{
+ unsigned long offset;
+ int start_block, end_block;
+ int start_byte, end_byte;
+ ERROR_CODE result = NO_ERR;
+ uchar temp[SECTOR_SIZE];
+ int i, num;
+
+ offset = addr[0] << 16 | addr[1] << 8 | addr[2];
+ /* Get the start block number */
+ result = GetSectorNumber(offset, &start_block);
+ if (result == INVALID_SECTOR) {
+ printf("Invalid sector! ");
+ return 0;
+ }
+ /* Get the end block number */
+ result = GetSectorNumber(offset + len - 1, &end_block);
+ if (result == INVALID_SECTOR) {
+ printf("Invalid sector! ");
+ return 0;
+ }
+
+ for (num = start_block; num <= end_block; num++) {
+ ReadData(num * SECTOR_SIZE, SECTOR_SIZE, (int *)temp);
+ start_byte = num * SECTOR_SIZE;
+ end_byte = (num + 1) * SECTOR_SIZE - 1;
+ if (start_byte < offset)
+ start_byte = offset;
+ if (end_byte > (offset + len))
+ end_byte = (offset + len - 1);
+ for (i = start_byte; i <= end_byte; i++)
+ temp[i - num * SECTOR_SIZE] = buffer[i - offset];
+ EraseBlock(num);
+ result = WriteData(num * SECTOR_SIZE, SECTOR_SIZE, (int *)temp);
+ if (result != NO_ERR)
+ return 0;
+ printf(".");
+ }
+ return len;
+}
+
+/****************************************************************************
+ * Function: spi_read
+ **************************************************************************** */
+ssize_t spi_read(uchar * addr, int alen, uchar * buffer, int len)
+{
+ unsigned long offset;
+ offset = addr[0] << 16 | addr[1] << 8 | addr[2];
+ ReadData(offset, len, (int *)buffer);
+ return len;
+}
+
+void SendSingleCommand(const int iCommand)
+{
+ unsigned short dummy;
+
+ /*turns on the SPI in single write mode */
+ SetupSPI((COMMON_SPI_SETTINGS | TIMOD01));
+
+ /*sends the actual command to the SPI TX register */
+ *pSPI_TDBR = iCommand;
+ sync();
+
+ /*The SPI status register will be polled to check the SPIF bit */
+ Wait_For_SPIF();
+
+ dummy = *pSPI_RDBR;
+
+ /*The SPI will be turned off */
+ SPI_OFF();
+
+}
+
+void SetupSPI(const int spi_setting)
+{
+
+ if (icache_status() || dcache_status())
+ udelay(CONFIG_CCLK_HZ / 50000000);
+ /*sets up the PF2 to be the slave select of the SPI */
+ *pSPI_FLG = 0xFB04;
+ *pSPI_BAUD = CONFIG_SPI_BAUD;
+ *pSPI_CTL = spi_setting;
+ sync();
+}
+
+void SPI_OFF(void)
+{
+
+ *pSPI_CTL = 0x0400; /* disable SPI */
+ *pSPI_FLG = 0;
+ *pSPI_BAUD = 0;
+ sync();
+ udelay(CONFIG_CCLK_HZ / 50000000);
+
+}
+
+void Wait_For_SPIF(void)
+{
+ unsigned short dummyread;
+ while ((*pSPI_STAT & TXS)) ;
+ while (!(*pSPI_STAT & SPIF)) ;
+ while (!(*pSPI_STAT & RXS)) ;
+ dummyread = *pSPI_RDBR; /* Read dummy to empty the receive register */
+
+}
+
+ERROR_CODE Wait_For_WEL(void)
+{
+ int i;
+ char status_register = 0;
+ ERROR_CODE ErrorCode = NO_ERR; /* tells us if there was an error erasing flash */
+
+ for (i = 0; i < TIMEOUT; i++) {
+ status_register = ReadStatusRegister();
+ if ((status_register & WEL)) {
+ ErrorCode = NO_ERR; /* tells us if there was an error erasing flash */
+ break;
+ }
+ ErrorCode = POLL_TIMEOUT; /* Time out error */
+ };
+
+ return ErrorCode;
+}
+
+ERROR_CODE Wait_For_Status(char Statusbit)
+{
+ int i;
+ char status_register = 0xFF;
+ ERROR_CODE ErrorCode = NO_ERR; /* tells us if there was an error erasing flash */
+
+ for (i = 0; i < TIMEOUT; i++) {
+ status_register = ReadStatusRegister();
+ if (!(status_register & Statusbit)) {
+ ErrorCode = NO_ERR; /* tells us if there was an error erasing flash */
+ break;
+ }
+ ErrorCode = POLL_TIMEOUT; /* Time out error */
+ };
+
+ return ErrorCode;
+}
+
+char ReadStatusRegister(void)
+{
+ char status_register = 0;
+
+ SetupSPI((COMMON_SPI_SETTINGS | TIMOD01)); /* Turn on the SPI */
+
+ *pSPI_TDBR = SPI_RDSR; /* send instruction to read status register */
+ sync();
+ Wait_For_SPIF(); /*wait until the instruction has been sent */
+ *pSPI_TDBR = 0; /*send dummy to receive the status register */
+ sync();
+ Wait_For_SPIF(); /*wait until the data has been sent */
+ status_register = *pSPI_RDBR; /*read the status register */
+
+ SPI_OFF(); /* Turn off the SPI */
+
+ return status_register;
+}
+
+ERROR_CODE GetSectorNumber(unsigned long ulOffset, int *pnSector)
+{
+ int nSector = 0;
+ ERROR_CODE ErrorCode = NO_ERR;
+
+ if (ulOffset > (NUM_SECTORS * 0x10000 - 1)) {
+ ErrorCode = INVALID_SECTOR;
+ return ErrorCode;
+ }
+
+ nSector = (int)ulOffset / 0x10000;
+ *pnSector = nSector;
+
+ /* ok */
+ return ErrorCode;
+}
+
+ERROR_CODE EraseBlock(int nBlock)
+{
+ unsigned long ulSectorOff = 0x0, ShiftValue;
+ ERROR_CODE ErrorCode = NO_ERR;
+
+ /* if the block is invalid just return */
+ if ((nBlock < 0) || (nBlock > NUM_SECTORS)) {
+ ErrorCode = INVALID_BLOCK; /* tells us if there was an error erasing flash */
+ return ErrorCode;
+ }
+ /* figure out the offset of the block in flash */
+ if ((nBlock >= 0) && (nBlock < NUM_SECTORS)) {
+ ulSectorOff = (nBlock * SECTOR_SIZE);
+
+ } else {
+ ErrorCode = INVALID_BLOCK; /* tells us if there was an error erasing flash */
+ return ErrorCode;
+ }
+
+ /* A write enable instruction must previously have been executed */
+ SendSingleCommand(SPI_WREN);
+
+ /*The status register will be polled to check the write enable latch "WREN" */
+ ErrorCode = Wait_For_WEL();
+
+ if (POLL_TIMEOUT == ErrorCode) {
+ printf("SPI Erase block error\n");
+ return ErrorCode;
+ } else
+ /*Turn on the SPI to send single commands */
+ SetupSPI((COMMON_SPI_SETTINGS | TIMOD01));
+
+ /* Send the erase block command to the flash followed by the 24 address */
+ /* to point to the start of a sector. */
+ *pSPI_TDBR = SPI_SE;
+ sync();
+ Wait_For_SPIF();
+ ShiftValue = (ulSectorOff >> 16); /* Send the highest byte of the 24 bit address at first */
+ *pSPI_TDBR = ShiftValue;
+ sync();
+ Wait_For_SPIF(); /* Wait until the instruction has been sent */
+ ShiftValue = (ulSectorOff >> 8); /* Send the middle byte of the 24 bit address at second */
+ *pSPI_TDBR = ShiftValue;
+ sync();
+ Wait_For_SPIF(); /* Wait until the instruction has been sent */
+ *pSPI_TDBR = ulSectorOff; /* Send the lowest byte of the 24 bit address finally */
+ sync();
+ Wait_For_SPIF(); /* Wait until the instruction has been sent */
+
+ /*Turns off the SPI */
+ SPI_OFF();
+
+ /* Poll the status register to check the Write in Progress bit */
+ /* Sector erase takes time */
+ ErrorCode = Wait_For_Status(WIP);
+
+ /* block erase should be complete */
+ return ErrorCode;
+}
+
+/*****************************************************************************
+* ERROR_CODE ReadData()
+*
+* Read a value from flash for verify purpose
+*
+* Inputs: unsigned long ulStart - holds the SPI start address
+* int pnData - pointer to store value read from flash
+* long lCount - number of elements to read
+***************************************************************************** */
+ERROR_CODE ReadData(unsigned long ulStart, long lCount, int *pnData)
+{
+ unsigned long ShiftValue;
+ char *cnData;
+ int i;
+
+ cnData = (char *)pnData; /* Pointer cast to be able to increment byte wise */
+
+ /* Start SPI interface */
+ SetupSPI((COMMON_SPI_SETTINGS | TIMOD01));
+
+ *pSPI_TDBR = SPI_READ; /* Send the read command to SPI device */
+ sync();
+ Wait_For_SPIF(); /* Wait until the instruction has been sent */
+ ShiftValue = (ulStart >> 16); /* Send the highest byte of the 24 bit address at first */
+ *pSPI_TDBR = ShiftValue; /* Send the byte to the SPI device */
+ sync();
+ Wait_For_SPIF(); /* Wait until the instruction has been sent */
+ ShiftValue = (ulStart >> 8); /* Send the middle byte of the 24 bit address at second */
+ *pSPI_TDBR = ShiftValue; /* Send the byte to the SPI device */
+ sync();
+ Wait_For_SPIF(); /* Wait until the instruction has been sent */
+ *pSPI_TDBR = ulStart; /* Send the lowest byte of the 24 bit address finally */
+ sync();
+ Wait_For_SPIF(); /* Wait until the instruction has been sent */
+
+ /* After the SPI device address has been placed on the MOSI pin the data can be */
+ /* received on the MISO pin. */
+ for (i = 0; i < lCount; i++) {
+ *pSPI_TDBR = 0; /*send dummy */
+ sync();
+ while (!(*pSPI_STAT & RXS)) ;
+ *cnData++ = *pSPI_RDBR; /*read */
+
+ if ((i >= SECTOR_SIZE) && (i % SECTOR_SIZE == 0))
+ printf(".");
+ }
+
+ SPI_OFF(); /* Turn off the SPI */
+
+ return NO_ERR;
+}
+
+ERROR_CODE WriteFlash(unsigned long ulStartAddr, long lTransferCount,
+ int *iDataSource, long *lWriteCount)
+{
+
+ unsigned long ulWAddr;
+ long lWTransferCount = 0;
+ int i;
+ char iData;
+ char *temp = (char *)iDataSource;
+ ERROR_CODE ErrorCode = NO_ERR; /* tells us if there was an error erasing flash */
+
+ /* First, a Write Enable Command must be sent to the SPI. */
+ SendSingleCommand(SPI_WREN);
+
+ /* Second, the SPI Status Register will be tested whether the */
+ /* Write Enable Bit has been set. */
+ ErrorCode = Wait_For_WEL();
+ if (POLL_TIMEOUT == ErrorCode) {
+ printf("SPI Write Time Out\n");
+ return ErrorCode;
+ } else
+ /* Third, the 24 bit address will be shifted out the SPI MOSI bytewise. */
+ SetupSPI((COMMON_SPI_SETTINGS | TIMOD01)); /* Turns the SPI on */
+ *pSPI_TDBR = SPI_PP;
+ sync();
+ Wait_For_SPIF(); /*wait until the instruction has been sent */
+ ulWAddr = (ulStartAddr >> 16);
+ *pSPI_TDBR = ulWAddr;
+ sync();
+ Wait_For_SPIF(); /*wait until the instruction has been sent */
+ ulWAddr = (ulStartAddr >> 8);
+ *pSPI_TDBR = ulWAddr;
+ sync();
+ Wait_For_SPIF(); /*wait until the instruction has been sent */
+ ulWAddr = ulStartAddr;
+ *pSPI_TDBR = ulWAddr;
+ sync();
+ Wait_For_SPIF(); /*wait until the instruction has been sent */
+ /* Fourth, maximum number of 256 bytes will be taken from the Buffer */
+ /* and sent to the SPI device. */
+ for (i = 0; (i < lTransferCount) && (i < 256); i++, lWTransferCount++) {
+ iData = *temp;
+ *pSPI_TDBR = iData;
+ sync();
+ Wait_For_SPIF(); /*wait until the instruction has been sent */
+ temp++;
+ }
+
+ SPI_OFF(); /* Turns the SPI off */
+
+ /* Sixth, the SPI Write in Progress Bit must be toggled to ensure the */
+ /* programming is done before start of next transfer. */
+ ErrorCode = Wait_For_Status(WIP);
+
+ if (POLL_TIMEOUT == ErrorCode) {
+ printf("SPI Program Time out!\n");
+ return ErrorCode;
+ } else
+
+ *lWriteCount = lWTransferCount;
+
+ return ErrorCode;
+}
+
+ERROR_CODE WriteData(unsigned long ulStart, long lCount, int *pnData)
+{
+
+ unsigned long ulWStart = ulStart;
+ long lWCount = lCount, lWriteCount;
+ long *pnWriteCount = &lWriteCount;
+
+ ERROR_CODE ErrorCode = NO_ERR;
+
+ while (lWCount != 0) {
+ ErrorCode = WriteFlash(ulWStart, lWCount, pnData, pnWriteCount);
+
+ /* After each function call of WriteFlash the counter must be adjusted */
+ lWCount -= *pnWriteCount;
+
+ /* Also, both address pointers must be recalculated. */
+ ulWStart += *pnWriteCount;
+ pnData += *pnWriteCount / 4;
+ }
+
+ /* return the appropriate error code */
+ return ErrorCode;
+}
+
+#endif /* CONFIG_SPI */
diff --git a/board/stamp/u-boot.lds b/board/bf533-stamp/u-boot.lds.S
index 9a22e507817..03ef72b6090 100644
--- a/board/stamp/u-boot.lds
+++ b/board/bf533-stamp/u-boot.lds.S
@@ -1,7 +1,7 @@
/*
- * U-boot - u-boot.lds
+ * U-boot - u-boot.lds.S
*
- * Copyright (c) 2005 blackfin.uclinux.org
+ * Copyright (c) 2005-2007 Analog Device Inc.
*
* (C) Copyright 2000-2004
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
@@ -25,6 +25,8 @@
* MA 02111-1307 USA
*/
+#include <config.h>
+
OUTPUT_ARCH(bfin)
SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib);
/* Do we need any of these for elf?
@@ -55,6 +57,7 @@ SECTIONS
.rela.plt : { *(.rela.plt) }
.init : { *(.init) }
.plt : { *(.plt) }
+ . = CFG_MONITOR_BASE;
.text :
{
/* WARNING - the following is hand-optimized to fit within */
@@ -68,9 +71,11 @@ SECTIONS
cpu/bf533/interrupt.o (.text)
cpu/bf533/serial.o (.text)
common/dlmalloc.o (.text)
- lib_generic/vsprintf.o (.text)
+/* lib_blackfin/bf533_string.o (.text) */
+/* lib_generic/vsprintf.o (.text) */
lib_generic/crc32.o (.text)
- lib_generic/zlib.o (.text)
+/* lib_generic/zlib.o (.text) */
+/* board/stamp/stamp.o (.text) */
. = DEFINED(env_offset) ? env_offset : .;
common/environment.o (.text)
@@ -118,9 +123,9 @@ SECTIONS
_edata = .;
PROVIDE (edata = .);
- __u_boot_cmd_start = .;
+ ___u_boot_cmd_start = .;
.u_boot_cmd : { *(.u_boot_cmd) }
- __u_boot_cmd_end = .;
+ ___u_boot_cmd_end = .;
__start___ex_table = .;
diff --git a/board/bf537-stamp/Makefile b/board/bf537-stamp/Makefile
new file mode 100644
index 00000000000..e4888441a97
--- /dev/null
+++ b/board/bf537-stamp/Makefile
@@ -0,0 +1,58 @@
+#
+# U-boot - Makefile
+#
+# Copyright (c) 2005-2007 Analog Device Inc.
+#
+# (C) Copyright 2000-2006
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+include $(TOPDIR)/config.mk
+
+LIB = $(obj)lib$(BOARD).a
+
+COBJS := $(BOARD).o flash.o ether_bf537.o post-memory.o stm_m25p64.o cmd_bf537led.o nand.o
+
+SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(COBJS))
+SOBJS := $(addprefix $(obj),$(SOBJS))
+
+$(LIB): $(obj).depend $(OBJS) $(SOBJS) u-boot.lds
+ $(AR) $(ARFLAGS) $@ $(OBJS) $(SOBJS)
+
+u-boot.lds: u-boot.lds.S
+ $(CPP) $(CPPFLAGS) -P -Ubfin $^ > $@.tmp
+ mv -f $@.tmp $@
+
+clean:
+ rm -f $(SOBJS) $(OBJS)
+
+distclean: clean
+ rm -f $(LIB) core *.bak .depend
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/board/bf537-stamp/bf537-stamp.c b/board/bf537-stamp/bf537-stamp.c
new file mode 100644
index 00000000000..cc4e9985fec
--- /dev/null
+++ b/board/bf537-stamp/bf537-stamp.c
@@ -0,0 +1,437 @@
+/*
+ * U-boot - BF537.c
+ *
+ * Copyright (c) 2005 blackfin.uclinux.org
+ *
+ * (C) Copyright 2000-2004
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <config.h>
+#include <command.h>
+#include <asm/blackfin.h>
+#include <asm/io.h>
+#include "ether_bf537.h"
+
+#define POST_WORD_ADDR 0xFF903FFC
+
+/*
+ * the bootldr command loads an address, checks to see if there
+ * is a Boot stream that the on-chip BOOTROM can understand,
+ * and loads it via the BOOTROM Callback. It is possible
+ * to also add booting from SPI, or TWI, but this function does
+ * not currently support that.
+ */
+int do_bootldr(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
+{
+ ulong addr, entry;
+ ulong *data;
+
+ /* Get the address */
+ if (argc < 2) {
+ addr = load_addr;
+ } else {
+ addr = simple_strtoul(argv[1], NULL, 16);
+ }
+
+ /* Check if it is a LDR file */
+ data = (ulong *) addr;
+ if (*data == 0xFF800060 || *data == 0xFF800040 || *data == 0xFF800020) {
+ /* We want to boot from FLASH or SDRAM */
+ entry = _BOOTROM_BOOT_DXE_FLASH;
+ printf("## Booting ldr image at 0x%08lx ...\n", addr);
+ if (icache_status())
+ icache_disable();
+ if (dcache_status())
+ dcache_disable();
+
+ __asm__("R7=%[a];\n" "P0=%[b];\n" "JUMP (P0);\n":
+ :[a] "d"(addr),[b] "a"(entry)
+ :"R7", "P0");
+
+ } else {
+ printf("## No ldr image at address 0x%08lx\n", addr);
+ }
+
+ return 0;
+}
+
+U_BOOT_CMD(bootldr, 2, 0, do_bootldr,
+ "bootldr - boot ldr image from memory\n",
+ "[addr]\n - boot ldr image stored in memory\n");
+
+int checkboard(void)
+{
+#if (BFIN_CPU == ADSP_BF534)
+ printf("CPU: ADSP BF534 Rev.: 0.%d\n", *pCHIPID >> 28);
+#elif (BFIN_CPU == ADSP_BF536)
+ printf("CPU: ADSP BF536 Rev.: 0.%d\n", *pCHIPID >> 28);
+#else
+ printf("CPU: ADSP BF537 Rev.: 0.%d\n", *pCHIPID >> 28);
+#endif
+ printf("Board: ADI BF537 stamp board\n");
+ printf(" Support: http://blackfin.uclinux.org/\n");
+ return 0;
+}
+
+#if defined(CONFIG_BFIN_IDE)
+
+void cf_outb(unsigned char val, volatile unsigned char *addr)
+{
+ *(addr) = val;
+ sync();
+}
+
+unsigned char cf_inb(volatile unsigned char *addr)
+{
+ volatile unsigned char c;
+
+ c = *(addr);
+ sync();
+
+ return c;
+}
+
+void cf_insw(unsigned short *sect_buf, unsigned short *addr, int words)
+{
+ int i;
+
+ for (i = 0; i < words; i++)
+ *(sect_buf + i) = *(addr);
+ sync();
+}
+
+void cf_outsw(unsigned short *addr, unsigned short *sect_buf, int words)
+{
+ int i;
+
+ for (i = 0; i < words; i++)
+ *(addr) = *(sect_buf + i);
+ sync();
+}
+#endif /* CONFIG_BFIN_IDE */
+
+long int initdram(int board_type)
+{
+ DECLARE_GLOBAL_DATA_PTR;
+#ifdef DEBUG
+ int brate;
+ char *tmp = getenv("baudrate");
+ brate = simple_strtoul(tmp, NULL, 16);
+ printf("Serial Port initialized with Baud rate = %x\n", brate);
+ printf("SDRAM attributes:\n");
+ printf("tRCD %d SCLK Cycles,tRP %d SCLK Cycles,tRAS %d SCLK Cycles"
+ "tWR %d SCLK Cycles,CAS Latency %d SCLK cycles \n",
+ 3, 3, 6, 2, 3);
+ printf("SDRAM Begin: 0x%x\n", CFG_SDRAM_BASE);
+ printf("Bank size = %d MB\n", CFG_MAX_RAM_SIZE >> 20);
+#endif
+ gd->bd->bi_memstart = CFG_SDRAM_BASE;
+ gd->bd->bi_memsize = CFG_MAX_RAM_SIZE;
+ return CFG_MAX_RAM_SIZE;
+}
+
+#if defined(CONFIG_MISC_INIT_R)
+/* miscellaneous platform dependent initialisations */
+int misc_init_r(void)
+{
+#if (BFIN_BOOT_MODE == BF537_BYPASS_BOOT)
+ char nid[32];
+ unsigned char *pMACaddr = (unsigned char *)0x203F0000;
+ u8 SrcAddr[6] = { 0x02, 0x80, 0xAD, 0x20, 0x31, 0xB8 };
+
+#if (CONFIG_COMMANDS & CFG_CMD_NET)
+ /* The 0xFF check here is to make sure we don't use the address
+ * in flash if it's simply been erased (aka all 0xFF values) */
+ if (getenv("ethaddr") == NULL && is_valid_ether_addr(pMACaddr)) {
+ sprintf(nid, "%02x:%02x:%02x:%02x:%02x:%02x",
+ pMACaddr[0], pMACaddr[1],
+ pMACaddr[2], pMACaddr[3], pMACaddr[4], pMACaddr[5]);
+ setenv("ethaddr", nid);
+ }
+ if (getenv("ethaddr")) {
+ SetupMacAddr(SrcAddr);
+ }
+#endif /* CONFIG_COMMANDS & CFG_CMD_NET */
+#endif /* BFIN_BOOT_MODE == BF537_BYPASS_BOOT */
+
+#if defined(CONFIG_BFIN_IDE)
+#if defined(CONFIG_BFIN_TRUE_IDE)
+ /* Enable ATASEL when in True IDE mode */
+ printf("Using CF True IDE Mode\n");
+ cf_outb(0, (unsigned char *)CONFIG_CF_ATASEL_ENA);
+ udelay(1000);
+#elif defined(CONFIG_BFIN_CF_IDE)
+ /* Disable ATASEL when we're in Common Memory Mode */
+ printf("Using CF Common Memory Mode\n");
+ cf_outb(0, (unsigned char *)CONFIG_CF_ATASEL_DIS);
+ udelay(1000);
+#elif defined(CONFIG_BFIN_HDD_IDE)
+ printf("Using HDD IDE Mode\n");
+#endif
+ ide_init();
+#endif /* CONFIG_BFIN_IDE */
+ return 0;
+}
+#endif /* CONFIG_MISC_INIT_R */
+
+#ifdef CONFIG_POST
+#if (BFIN_BOOT_MODE != BF537_BYPASS_BOOT)
+/* Using sw10-PF5 as the hotkey */
+int post_hotkeys_pressed(void)
+{
+ return 0;
+}
+#else
+/* Using sw10-PF5 as the hotkey */
+int post_hotkeys_pressed(void)
+{
+ int delay = 3;
+ int i;
+ unsigned short value;
+
+ *pPORTF_FER &= ~PF5;
+ *pPORTFIO_DIR &= ~PF5;
+ *pPORTFIO_INEN |= PF5;
+
+ printf("########Press SW10 to enter Memory POST########: %2d ", delay);
+ while (delay--) {
+ for (i = 0; i < 100; i++) {
+ value = *pPORTFIO & PF5;
+ if (value != 0) {
+ break;
+ }
+ udelay(10000);
+ }
+ printf("\b\b\b%2d ", delay);
+ }
+ printf("\b\b\b 0");
+ printf("\n");
+ if (value == 0)
+ return 0;
+ else {
+ printf("Hotkey has been pressed, Enter POST . . . . . .\n");
+ return 1;
+ }
+}
+#endif
+#endif
+
+#if defined(CONFIG_POST) || defined(CONFIG_LOGBUFFER)
+void post_word_store(ulong a)
+{
+ volatile ulong *save_addr = (volatile ulong *)POST_WORD_ADDR;
+ *save_addr = a;
+}
+
+ulong post_word_load(void)
+{
+ volatile ulong *save_addr = (volatile ulong *)POST_WORD_ADDR;
+ return *save_addr;
+}
+#endif
+
+#ifdef CONFIG_POST
+int uart_post_test(int flags)
+{
+ return 0;
+}
+
+#define BLOCK_SIZE 0x10000
+#define VERIFY_ADDR 0x2000000
+extern int erase_block_flash(int);
+extern int write_data(long lStart, long lCount, uchar * pnData);
+int flash_post_test(int flags)
+{
+ unsigned short *pbuf, *temp;
+ int offset, n, i;
+ int value = 0;
+ int result = 0;
+ printf("\n");
+ pbuf = (unsigned short *)VERIFY_ADDR;
+ temp = pbuf;
+ for (n = FLASH_START_POST_BLOCK; n < FLASH_END_POST_BLOCK; n++) {
+ offset = (n - 7) * BLOCK_SIZE;
+ printf("--------Erase block:%2d..", n);
+ erase_block_flash(n);
+ printf("OK\r");
+ printf("--------Program block:%2d...", n);
+ write_data(CFG_FLASH_BASE + offset, BLOCK_SIZE, pbuf);
+ printf("OK\r");
+ printf("--------Verify block:%2d...", n);
+ for (i = 0; i < BLOCK_SIZE; i += 2) {
+ if (*(unsigned short *)(CFG_FLASH_BASE + offset + i) !=
+ *temp++) {
+ value = 1;
+ result = 1;
+ }
+ }
+ if (value)
+ printf("failed\n");
+ else
+ printf("OK %3d%%\r",
+ (int)(
+ (n + 1 -
+ FLASH_START_POST_BLOCK) *
+ 100 / (FLASH_END_POST_BLOCK -
+ FLASH_START_POST_BLOCK)));
+
+ temp = pbuf;
+ value = 0;
+ }
+ printf("\n");
+ if (result)
+ return -1;
+ else
+ return 0;
+}
+
+/****************************************************
+ * LED1 ---- PF6 LED2 ---- PF7 *
+ * LED3 ---- PF8 LED4 ---- PF9 *
+ * LED5 ---- PF10 LED6 ---- PF11 *
+ ****************************************************/
+int led_post_test(int flags)
+{
+ *pPORTF_FER &= ~(PF6 | PF7 | PF8 | PF9 | PF10 | PF11);
+ *pPORTFIO_DIR |= PF6 | PF7 | PF8 | PF9 | PF10 | PF11;
+ *pPORTFIO_INEN &= ~(PF6 | PF7 | PF8 | PF9 | PF10 | PF11);
+ *pPORTFIO &= ~(PF6 | PF7 | PF8 | PF9 | PF10 | PF11);
+ udelay(1000000);
+ printf("LED1 on");
+ *pPORTFIO |= PF6;
+ udelay(1000000);
+ printf("\b\b\b\b\b\b\b");
+ printf("LED2 on");
+ *pPORTFIO |= PF7;
+ udelay(1000000);
+ printf("\b\b\b\b\b\b\b");
+ printf("LED3 on");
+ *pPORTFIO |= PF8;
+ udelay(1000000);
+ printf("\b\b\b\b\b\b\b");
+ printf("LED4 on");
+ *pPORTFIO |= PF9;
+ udelay(1000000);
+ printf("\b\b\b\b\b\b\b");
+ printf("LED5 on");
+ *pPORTFIO |= PF10;
+ udelay(1000000);
+ printf("\b\b\b\b\b\b\b");
+ printf("lED6 on");
+ *pPORTFIO |= PF11;
+ printf("\b\b\b\b\b\b\b ");
+ return 0;
+}
+
+/************************************************
+ * SW10 ---- PF5 SW11 ---- PF4 *
+ * SW12 ---- PF3 SW13 ---- PF2 *
+ ************************************************/
+int button_post_test(int flags)
+{
+ int i, delay = 5;
+ unsigned short value = 0;
+ int result = 0;
+
+ *pPORTF_FER &= ~(PF5 | PF4 | PF3 | PF2);
+ *pPORTFIO_DIR &= ~(PF5 | PF4 | PF3 | PF2);
+ *pPORTFIO_INEN |= (PF5 | PF4 | PF3 | PF2);
+
+ printf("\n--------Press SW10: %2d ", delay);
+ while (delay--) {
+ for (i = 0; i < 100; i++) {
+ value = *pPORTFIO & PF5;
+ if (value != 0) {
+ break;
+ }
+ udelay(10000);
+ }
+ printf("\b\b\b%2d ", delay);
+ }
+ if (value != 0)
+ printf("\b\bOK");
+ else {
+ result = -1;
+ printf("\b\bfailed");
+ }
+
+ delay = 5;
+ printf("\n--------Press SW11: %2d ", delay);
+ while (delay--) {
+ for (i = 0; i < 100; i++) {
+ value = *pPORTFIO & PF4;
+ if (value != 0) {
+ break;
+ }
+ udelay(10000);
+ }
+ printf("\b\b\b%2d ", delay);
+ }
+ if (value != 0)
+ printf("\b\bOK");
+ else {
+ result = -1;
+ printf("\b\bfailed");
+ }
+
+ delay = 5;
+ printf("\n--------Press SW12: %2d ", delay);
+ while (delay--) {
+ for (i = 0; i < 100; i++) {
+ value = *pPORTFIO & PF3;
+ if (value != 0) {
+ break;
+ }
+ udelay(10000);
+ }
+ printf("\b\b\b%2d ", delay);
+ }
+ if (value != 0)
+ printf("\b\bOK");
+ else {
+ result = -1;
+ printf("\b\bfailed");
+ }
+
+ delay = 5;
+ printf("\n--------Press SW13: %2d ", delay);
+ while (delay--) {
+ for (i = 0; i < 100; i++) {
+ value = *pPORTFIO & PF2;
+ if (value != 0) {
+ break;
+ }
+ udelay(10000);
+ }
+ printf("\b\b\b%2d ", delay);
+ }
+ if (value != 0)
+ printf("\b\bOK");
+ else {
+ result = -1;
+ printf("\b\bfailed");
+ }
+ printf("\n");
+ return result;
+}
+#endif
diff --git a/board/bf537-stamp/cmd_bf537led.c b/board/bf537-stamp/cmd_bf537led.c
new file mode 100644
index 00000000000..fa650f26fe4
--- /dev/null
+++ b/board/bf537-stamp/cmd_bf537led.c
@@ -0,0 +1,201 @@
+/*
+ * U-boot - cmd_bf537led.c
+ *
+ * Copyright (C) 2006 Aaron Gage, Ocean Optics Inc.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+#include <common.h>
+#include <config.h>
+#include <command.h>
+#include <asm/blackfin.h>
+#include <asm-blackfin/string.h>
+#ifdef CONFIG_BF537_STAMP_LEDCMD
+
+/* Define the command usage in a reusable way */
+#define USAGE_LONG \
+ "led <number> <action>\n" \
+ " <number> - Index (0-5) of LED to change, or \"all\"\n" \
+ " <action> - Must be one of:\n" \
+ " on off toggle\n"
+
+/* Number of LEDs supported by the board */
+#define NUMBER_LEDS 6
+/* The BF537 stamp has 6 LEDs. This mask indicates that all should be lit. */
+#define LED_ALL_MASK 0x003F
+
+void show_cmd_usage(void);
+void set_led_state(int index, int state);
+void configure_GPIO_to_output(int index);
+
+/* Map of LEDs according to their GPIO ports. This can be rearranged or
+ * otherwise changed to account for different GPIO configurations.
+ */
+int led_ports[] = { PF6, PF7, PF8, PF9, PF10, PF11 };
+
+#define ACTION_TOGGLE -1
+#define ACTION_OFF 0
+#define ACTION_ON 1
+
+#define LED_STATE_OFF 0
+#define LED_STATE_ON 1
+
+/* This is a trivial atoi implementation since we don't have one available */
+int atoi(char *string)
+{
+ int length;
+ int retval = 0;
+ int i;
+ int sign = 1;
+
+ length = strlen(string);
+ for (i = 0; i < length; i++) {
+ if (0 == i && string[0] == '-') {
+ sign = -1;
+ continue;
+ }
+ if (string[i] > '9' || string[i] < '0') {
+ break;
+ }
+ retval *= 10;
+ retval += string[i] - '0';
+ }
+ retval *= sign;
+ return retval;
+}
+
+int do_bf537led(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
+{
+ int led_mask = 0;
+ int led_current_state = 0;
+ int action = ACTION_OFF;
+ int temp;
+
+ if (3 != argc) {
+ /* Not enough arguments, so just show usage information */
+ show_cmd_usage();
+ return 1;
+ }
+
+ if (strcmp(argv[1], "all") == 0) {
+ led_mask = LED_ALL_MASK;
+ } else {
+ temp = atoi(argv[1]);
+ if (temp < 0 || temp >= NUMBER_LEDS) {
+ printf("Invalid LED number [%s]\n", argv[1]);
+ show_cmd_usage();
+ return 2;
+ }
+ led_mask |= (1 << temp);
+ }
+
+ if (strcmp(argv[2], "off") == 0) {
+ action = ACTION_OFF;
+ } else if (strcmp(argv[2], "on") == 0) {
+ action = ACTION_ON;
+ } else if (strcmp(argv[2], "toggle") == 0) {
+ action = ACTION_TOGGLE;
+ } else {
+ printf("Invalid action [%s]\n", argv[2]);
+ show_cmd_usage();
+ return 3;
+ }
+
+ for (temp = 0; temp < NUMBER_LEDS; temp++) {
+ if ((led_mask & (1 << temp)) > 0) {
+ /*
+ * It is possible that the user has wired one of PF6-PF11 to
+ * something other than an LED, so this will only change a pin
+ * to output if the user has indicated a state change. This may
+ * happen a lot, but this way is safer than just setting all pins
+ * to output.
+ */
+ configure_GPIO_to_output(temp);
+
+ led_current_state =
+ ((*pPORTFIO & led_ports[temp]) >
+ 0) ? LED_STATE_ON : LED_STATE_OFF;
+ /*
+ printf("LED state for index %d (%x) is %d\n", temp, led_ports[temp],
+ led_current_state);
+ printf("*pPORTFIO is %x\n", *pPORTFIO);
+ */
+ if (ACTION_ON == action
+ || (ACTION_TOGGLE == action
+ && 0 == led_current_state)) {
+ printf("Turning LED %d on\n", temp);
+ set_led_state(temp, LED_STATE_ON);
+ } else {
+ printf("Turning LED %d off\n", temp);
+ set_led_state(temp, LED_STATE_OFF);
+ }
+ }
+ }
+
+ return 0;
+}
+
+/*
+ * The GPIO pins that go to the LEDs on the BF537 stamp must be configured
+ * as output. This function simply configures them that way. This could
+ * be done to all of the GPIO lines at once, but if a user is using a
+ * custom board, this will try to be nice and only change the GPIO lines
+ * that the user specifically names.
+ */
+void configure_GPIO_to_output(int index)
+{
+ int port;
+
+ port = led_ports[index];
+
+ /* Clear the Port F Function Enable Register */
+ *pPORTF_FER &= ~port;
+ /* Set the Port F I/O direction register */
+ *pPORTFIO_DIR |= port;
+ /* Clear the Port F I/O Input Enable Register */
+ *pPORTFIO_INEN &= ~port;
+}
+
+/* Enforce the given state on the GPIO line for the indicated LED */
+void set_led_state(int index, int state)
+{
+ int port;
+
+ port = led_ports[index];
+
+ if (LED_STATE_OFF == state) {
+ /* Clear the bit to turn off the LED */
+ *pPORTFIO &= ~port;
+ } else {
+ /* Set the bit to turn on the LED */
+ *pPORTFIO |= port;
+ }
+}
+
+/* Display usage information */
+void show_cmd_usage()
+{
+ printf("Usage:\n%s", USAGE_LONG);
+}
+
+/* Register information for u-boot to find this command */
+U_BOOT_CMD(led, 3, 1, do_bf537led,
+ "led- Control BF537 stamp LEDs\n", USAGE_LONG);
+
+#endif
diff --git a/board/bf537-stamp/config.mk b/board/bf537-stamp/config.mk
new file mode 100644
index 00000000000..a623c3df0c6
--- /dev/null
+++ b/board/bf537-stamp/config.mk
@@ -0,0 +1,25 @@
+#
+# (C) Copyright 2001
+# 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
+#
+# TEXT_BASE should be defined as the MAX_SDRAM Address - 256k bytes
+# 256k is defined as CFG_MONITOR_LEN in ./include/configs/<board>.h
+TEXT_BASE = 0x03FC0000
diff --git a/board/bf537-stamp/ether_bf537.c b/board/bf537-stamp/ether_bf537.c
new file mode 100644
index 00000000000..f00837aad2c
--- /dev/null
+++ b/board/bf537-stamp/ether_bf537.c
@@ -0,0 +1,545 @@
+/*
+ * ADI Blackfin 537 MAC Ethernet
+ *
+ * Copyright (c) 2005 Analog Device, Inc.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <config.h>
+#include <asm/blackfin.h>
+#include <net.h>
+#include <command.h>
+#include <malloc.h>
+#include "ether_bf537.h"
+
+#ifdef CONFIG_POST
+#include <post.h>
+#endif
+
+#undef DEBUG_ETHERNET
+
+#ifdef DEBUG_ETHERNET
+#define DEBUGF(fmt,args...) printf(fmt,##args)
+#else
+#define DEBUGF(fmt,args...)
+#endif
+
+#if (CONFIG_COMMANDS & CFG_CMD_NET)
+
+#define RXBUF_BASE_ADDR 0xFF900000
+#define TXBUF_BASE_ADDR 0xFF800000
+#define TX_BUF_CNT 1
+
+#define TOUT_LOOP 1000000
+
+ADI_ETHER_BUFFER *txbuf[TX_BUF_CNT];
+ADI_ETHER_BUFFER *rxbuf[PKTBUFSRX];
+static u16 txIdx; /* index of the current RX buffer */
+static u16 rxIdx; /* index of the current TX buffer */
+
+u8 SrcAddr[6];
+u16 PHYregs[NO_PHY_REGS]; /* u16 PHYADDR; */
+
+/* DMAx_CONFIG values at DMA Restart */
+const ADI_DMA_CONFIG_REG rxdmacfg = { 1, 1, 2, 0, 0, 0, 0, 5, 7 };
+
+#if 0
+ rxdmacfg.b_DMA_EN = 1; /* enabled */
+ rxdmacfg.b_WNR = 1; /* write to memory */
+ rxdmacfg.b_WDSIZE = 2; /* wordsize is 32 bits */
+ rxdmacfg.b_DMA2D = 0; /* N/A */
+ rxdmacfg.b_RESTART= 0; /* N/A */
+ rxdmacfg.b_DI_SEL = 0; /* N/A */
+ rxdmacfg.b_DI_EN = 0; /* no interrupt */
+ rxdmacfg.b_NDSIZE = 5; /* 5 half words is desc size. */
+ rxdmacfg.b_FLOW = 7; /* large desc flow */
+#endif
+
+const ADI_DMA_CONFIG_REG txdmacfg = { 1, 0, 2, 0, 0, 0, 0, 5, 7 };
+
+#if 0
+ txdmacfg.b_DMA_EN = 1; /* enabled */
+ txdmacfg.b_WNR = 0; /* read from memory */
+ txdmacfg.b_WDSIZE = 2; /* wordsize is 32 bits */
+ txdmacfg.b_DMA2D = 0; /* N/A */
+ txdmacfg.b_RESTART= 0; /* N/A */
+ txdmacfg.b_DI_SEL = 0; /* N/A */
+ txdmacfg.b_DI_EN = 0; /* no interrupt */
+ txdmacfg.b_NDSIZE = 5; /* 5 half words is desc size. */
+ txdmacfg.b_FLOW = 7; /* large desc flow */
+#endif
+
+ADI_ETHER_BUFFER *SetupRxBuffer(int no);
+ADI_ETHER_BUFFER *SetupTxBuffer(int no);
+
+static int bfin_EMAC_init(struct eth_device *dev, bd_t * bd);
+static void bfin_EMAC_halt(struct eth_device *dev);
+static int bfin_EMAC_send(struct eth_device *dev, volatile void *packet,
+ int length);
+static int bfin_EMAC_recv(struct eth_device *dev);
+
+int bfin_EMAC_initialize(bd_t * bis)
+{
+ struct eth_device *dev;
+ dev = (struct eth_device *)malloc(sizeof(*dev));
+ if (dev == NULL)
+ hang();
+
+ memset(dev, 0, sizeof(*dev));
+ sprintf(dev->name, "BF537 ETHERNET");
+
+ dev->iobase = 0;
+ dev->priv = 0;
+ dev->init = bfin_EMAC_init;
+ dev->halt = bfin_EMAC_halt;
+ dev->send = bfin_EMAC_send;
+ dev->recv = bfin_EMAC_recv;
+
+ eth_register(dev);
+
+ return 1;
+}
+
+static int bfin_EMAC_send(struct eth_device *dev, volatile void *packet,
+ int length)
+{
+ int i;
+ int result = 0;
+ unsigned int *buf;
+ buf = (unsigned int *)packet;
+
+ if (length <= 0) {
+ printf("Ethernet: bad packet size: %d\n", length);
+ goto out;
+ }
+
+ if ((*pDMA2_IRQ_STATUS & DMA_ERR) != 0) {
+ printf("Ethernet: tx DMA error\n");
+ goto out;
+ }
+
+ for (i = 0; (*pDMA2_IRQ_STATUS & DMA_RUN) != 0; i++) {
+ if (i > TOUT_LOOP) {
+ puts("Ethernet: tx time out\n");
+ goto out;
+ }
+ }
+ txbuf[txIdx]->FrmData->NoBytes = length;
+ memcpy(txbuf[txIdx]->FrmData->Dest, (void *)packet, length);
+ txbuf[txIdx]->Dma[0].START_ADDR = (u32) txbuf[txIdx]->FrmData;
+ *pDMA2_NEXT_DESC_PTR = &txbuf[txIdx]->Dma[0];
+ *pDMA2_CONFIG = *(u16 *) (void *)(&txdmacfg);
+ *pEMAC_OPMODE |= TE;
+
+ for (i = 0; (txbuf[txIdx]->StatusWord & TX_COMP) == 0; i++) {
+ if (i > TOUT_LOOP) {
+ puts("Ethernet: tx error\n");
+ goto out;
+ }
+ }
+ result = txbuf[txIdx]->StatusWord;
+ txbuf[txIdx]->StatusWord = 0;
+ if ((txIdx + 1) >= TX_BUF_CNT)
+ txIdx = 0;
+ else
+ txIdx++;
+ out:
+ DEBUGF("BFIN EMAC send: length = %d\n", length);
+ return result;
+}
+
+static int bfin_EMAC_recv(struct eth_device *dev)
+{
+ int length = 0;
+
+ for (;;) {
+ if ((rxbuf[rxIdx]->StatusWord & RX_COMP) == 0) {
+ length = -1;
+ break;
+ }
+ if ((rxbuf[rxIdx]->StatusWord & RX_DMAO) != 0) {
+ printf("Ethernet: rx dma overrun\n");
+ break;
+ }
+ if ((rxbuf[rxIdx]->StatusWord & RX_OK) == 0) {
+ printf("Ethernet: rx error\n");
+ break;
+ }
+ length = rxbuf[rxIdx]->StatusWord & 0x000007FF;
+ if (length <= 4) {
+ printf("Ethernet: bad frame\n");
+ break;
+ }
+ NetRxPackets[rxIdx] =
+ (volatile uchar *)(rxbuf[rxIdx]->FrmData->Dest);
+ NetReceive(NetRxPackets[rxIdx], length - 4);
+ *pDMA1_IRQ_STATUS |= DMA_DONE | DMA_ERR;
+ rxbuf[rxIdx]->StatusWord = 0x00000000;
+ if ((rxIdx + 1) >= PKTBUFSRX)
+ rxIdx = 0;
+ else
+ rxIdx++;
+ }
+
+ return length;
+}
+
+/**************************************************************
+ *
+ * Ethernet Initialization Routine
+ *
+ *************************************************************/
+
+static int bfin_EMAC_init(struct eth_device *dev, bd_t * bd)
+{
+ u32 opmode;
+ int dat;
+ int i;
+ DEBUGF("Eth_init: ......\n");
+
+ txIdx = 0;
+ rxIdx = 0;
+
+/* Initialize System Register */
+ if (SetupSystemRegs(&dat) < 0)
+ return -1;
+
+/* Initialize EMAC address */
+ SetupMacAddr(SrcAddr);
+
+/* Initialize TX and RX buffer */
+ for (i = 0; i < PKTBUFSRX; i++) {
+ rxbuf[i] = SetupRxBuffer(i);
+ if (i > 0) {
+ rxbuf[i - 1]->Dma[1].NEXT_DESC_PTR =
+ &(rxbuf[i]->Dma[0]);
+ if (i == (PKTBUFSRX - 1))
+ rxbuf[i]->Dma[1].NEXT_DESC_PTR =
+ &(rxbuf[0]->Dma[0]);
+ }
+ }
+ for (i = 0; i < TX_BUF_CNT; i++) {
+ txbuf[i] = SetupTxBuffer(i);
+ if (i > 0) {
+ txbuf[i - 1]->Dma[1].NEXT_DESC_PTR =
+ &(txbuf[i]->Dma[0]);
+ if (i == (TX_BUF_CNT - 1))
+ txbuf[i]->Dma[1].NEXT_DESC_PTR =
+ &(txbuf[0]->Dma[0]);
+ }
+ }
+
+ /* Set RX DMA */
+ *pDMA1_NEXT_DESC_PTR = &rxbuf[0]->Dma[0];
+ *pDMA1_CONFIG = *((u16 *) (void *)&rxbuf[0]->Dma[0].CONFIG);
+
+ /* Wait MII done */
+ PollMdcDone();
+
+ /* We enable only RX here */
+ /* ASTP : Enable Automatic Pad Stripping
+ PR : Promiscuous Mode for test
+ PSF : Receive frames with total length less than 64 bytes.
+ FDMODE : Full Duplex Mode
+ LB : Internal Loopback for test
+ RE : Receiver Enable */
+ if (dat == FDMODE)
+ opmode = ASTP | FDMODE | PSF;
+ else
+ opmode = ASTP | PSF;
+ opmode |= RE;
+#ifdef CONFIG_BFIN_MAC_RMII
+ opmode |= TE | RMII;
+#endif
+ /* Turn on the EMAC */
+ *pEMAC_OPMODE = opmode;
+ return 0;
+}
+
+static void bfin_EMAC_halt(struct eth_device *dev)
+{
+ DEBUGF("Eth_halt: ......\n");
+ /* Turn off the EMAC */
+ *pEMAC_OPMODE = 0x00000000;
+ /* Turn off the EMAC RX DMA */
+ *pDMA1_CONFIG = 0x0000;
+ *pDMA2_CONFIG = 0x0000;
+
+}
+
+void SetupMacAddr(u8 * MACaddr)
+{
+ char *tmp, *end;
+ int i;
+ /* this depends on a little-endian machine */
+ tmp = getenv("ethaddr");
+ if (tmp) {
+ for (i = 0; i < 6; i++) {
+ MACaddr[i] = tmp ? simple_strtoul(tmp, &end, 16) : 0;
+ if (tmp)
+ tmp = (*end) ? end + 1 : end;
+ }
+
+#ifndef CONFIG_NETCONSOLE
+ printf("Using MAC Address %02X:%02X:%02X:%02X:%02X:%02X\n",
+ MACaddr[0], MACaddr[1],
+ MACaddr[2], MACaddr[3], MACaddr[4], MACaddr[5]);
+#endif
+ *pEMAC_ADDRLO = MACaddr[0] | MACaddr[1] << 8 |
+ MACaddr[2] << 16 | MACaddr[3] << 24;
+ *pEMAC_ADDRHI = MACaddr[4] | MACaddr[5] << 8;
+ }
+}
+
+void PollMdcDone(void)
+{
+ /* poll the STABUSY bit */
+ while (*pEMAC_STAADD & STABUSY) ;
+}
+
+void WrPHYReg(u16 PHYAddr, u16 RegAddr, u16 Data)
+{
+ PollMdcDone();
+
+ *pEMAC_STADAT = Data;
+
+ *pEMAC_STAADD = SET_PHYAD(PHYAddr) | SET_REGAD(RegAddr) |
+ STAOP | STAIE | STABUSY;
+}
+
+/*********************************************************************************
+ * Read an off-chip register in a PHY through the MDC/MDIO port *
+ *********************************************************************************/
+u16 RdPHYReg(u16 PHYAddr, u16 RegAddr)
+{
+ u16 Data;
+
+ PollMdcDone();
+
+ *pEMAC_STAADD = SET_PHYAD(PHYAddr) | SET_REGAD(RegAddr) |
+ STAIE | STABUSY;
+
+ PollMdcDone();
+
+ Data = (u16) * pEMAC_STADAT;
+
+ PHYregs[RegAddr] = Data; /* save shadow copy */
+
+ return Data;
+}
+
+void SoftResetPHY(void)
+{
+ u16 phydat;
+ /* set the reset bit */
+ WrPHYReg(PHYADDR, PHY_MODECTL, PHY_RESET);
+ /* and clear it again */
+ WrPHYReg(PHYADDR, PHY_MODECTL, 0x0000);
+ do {
+ /* poll until reset is complete */
+ phydat = RdPHYReg(PHYADDR, PHY_MODECTL);
+ } while ((phydat & PHY_RESET) != 0);
+}
+
+int SetupSystemRegs(int *opmode)
+{
+ u16 sysctl, phydat;
+ int count = 0;
+ /* Enable PHY output */
+ *pVR_CTL |= PHYCLKOE;
+ /* MDC = 2.5 MHz */
+ sysctl = SET_MDCDIV(24);
+ /* Odd word alignment for Receive Frame DMA word */
+ /* Configure checksum support and rcve frame word alignment */
+ sysctl |= RXDWA | RXCKS;
+ *pEMAC_SYSCTL = sysctl;
+ /* auto negotiation on */
+ /* full duplex */
+ /* 100 Mbps */
+ phydat = PHY_ANEG_EN | PHY_DUPLEX | PHY_SPD_SET;
+ WrPHYReg(PHYADDR, PHY_MODECTL, phydat);
+ do {
+ udelay(1000);
+ phydat = RdPHYReg(PHYADDR, PHY_MODESTAT);
+ if (count > 3000) {
+ printf
+ ("Link is down, please check your network connection\n");
+ return -1;
+ }
+ count++;
+ } while (!(phydat & 0x0004));
+
+ phydat = RdPHYReg(PHYADDR, PHY_ANLPAR);
+
+ if ((phydat & 0x0100) || (phydat & 0x0040))
+ *opmode = FDMODE;
+ else
+ *opmode = 0;
+
+ *pEMAC_MMC_CTL = RSTC | CROLL;
+
+ /* Initialize the TX DMA channel registers */
+ *pDMA2_X_COUNT = 0;
+ *pDMA2_X_MODIFY = 4;
+ *pDMA2_Y_COUNT = 0;
+ *pDMA2_Y_MODIFY = 0;
+
+ /* Initialize the RX DMA channel registers */
+ *pDMA1_X_COUNT = 0;
+ *pDMA1_X_MODIFY = 4;
+ *pDMA1_Y_COUNT = 0;
+ *pDMA1_Y_MODIFY = 0;
+ return 0;
+}
+
+ADI_ETHER_BUFFER *SetupRxBuffer(int no)
+{
+ ADI_ETHER_FRAME_BUFFER *frmbuf;
+ ADI_ETHER_BUFFER *buf;
+ int nobytes_buffer = sizeof(ADI_ETHER_BUFFER[2]) / 2; /* ensure a multi. of 4 */
+ int total_size = nobytes_buffer + RECV_BUFSIZE;
+
+ buf = (ADI_ETHER_BUFFER *) (RXBUF_BASE_ADDR + no * total_size);
+ frmbuf =
+ (ADI_ETHER_FRAME_BUFFER *) (RXBUF_BASE_ADDR + no * total_size +
+ nobytes_buffer);
+
+ memset(buf, 0x00, nobytes_buffer);
+ buf->FrmData = frmbuf;
+ memset(frmbuf, 0xfe, RECV_BUFSIZE);
+
+ /* set up first desc to point to receive frame buffer */
+ buf->Dma[0].NEXT_DESC_PTR = &(buf->Dma[1]);
+ buf->Dma[0].START_ADDR = (u32) buf->FrmData;
+ buf->Dma[0].CONFIG.b_DMA_EN = 1; /* enabled */
+ buf->Dma[0].CONFIG.b_WNR = 1; /* Write to memory */
+ buf->Dma[0].CONFIG.b_WDSIZE = 2; /* wordsize is 32 bits */
+ buf->Dma[0].CONFIG.b_NDSIZE = 5; /* 5 half words is desc size. */
+ buf->Dma[0].CONFIG.b_FLOW = 7; /* large desc flow */
+
+ /* set up second desc to point to status word */
+ buf->Dma[1].NEXT_DESC_PTR = &(buf->Dma[0]);
+ buf->Dma[1].START_ADDR = (u32) & buf->IPHdrChksum;
+ buf->Dma[1].CONFIG.b_DMA_EN = 1; /* enabled */
+ buf->Dma[1].CONFIG.b_WNR = 1; /* Write to memory */
+ buf->Dma[1].CONFIG.b_WDSIZE = 2; /* wordsize is 32 bits */
+ buf->Dma[1].CONFIG.b_DI_EN = 1; /* enable interrupt */
+ buf->Dma[1].CONFIG.b_NDSIZE = 5; /* must be 0 when FLOW is 0 */
+ buf->Dma[1].CONFIG.b_FLOW = 7; /* stop */
+
+ return buf;
+}
+
+ADI_ETHER_BUFFER *SetupTxBuffer(int no)
+{
+ ADI_ETHER_FRAME_BUFFER *frmbuf;
+ ADI_ETHER_BUFFER *buf;
+ int nobytes_buffer = sizeof(ADI_ETHER_BUFFER[2]) / 2; /* ensure a multi. of 4 */
+ int total_size = nobytes_buffer + RECV_BUFSIZE;
+
+ buf = (ADI_ETHER_BUFFER *) (TXBUF_BASE_ADDR + no * total_size);
+ frmbuf =
+ (ADI_ETHER_FRAME_BUFFER *) (TXBUF_BASE_ADDR + no * total_size +
+ nobytes_buffer);
+
+ memset(buf, 0x00, nobytes_buffer);
+ buf->FrmData = frmbuf;
+ memset(frmbuf, 0x00, RECV_BUFSIZE);
+
+ /* set up first desc to point to receive frame buffer */
+ buf->Dma[0].NEXT_DESC_PTR = &(buf->Dma[1]);
+ buf->Dma[0].START_ADDR = (u32) buf->FrmData;
+ buf->Dma[0].CONFIG.b_DMA_EN = 1; /* enabled */
+ buf->Dma[0].CONFIG.b_WNR = 0; /* Read to memory */
+ buf->Dma[0].CONFIG.b_WDSIZE = 2; /* wordsize is 32 bits */
+ buf->Dma[0].CONFIG.b_NDSIZE = 5; /* 5 half words is desc size. */
+ buf->Dma[0].CONFIG.b_FLOW = 7; /* large desc flow */
+
+ /* set up second desc to point to status word */
+ buf->Dma[1].NEXT_DESC_PTR = &(buf->Dma[0]);
+ buf->Dma[1].START_ADDR = (u32) & buf->StatusWord;
+ buf->Dma[1].CONFIG.b_DMA_EN = 1; /* enabled */
+ buf->Dma[1].CONFIG.b_WNR = 1; /* Write to memory */
+ buf->Dma[1].CONFIG.b_WDSIZE = 2; /* wordsize is 32 bits */
+ buf->Dma[1].CONFIG.b_DI_EN = 1; /* enable interrupt */
+ buf->Dma[1].CONFIG.b_NDSIZE = 0; /* must be 0 when FLOW is 0 */
+ buf->Dma[1].CONFIG.b_FLOW = 0; /* stop */
+
+ return buf;
+}
+
+#if defined(CONFIG_POST) && defined(CFG_POST_ETHER)
+int ether_post_test(int flags)
+{
+ uchar buf[64];
+ int i, value = 0;
+ int length;
+
+ printf("\n--------");
+ bfin_EMAC_init(NULL, NULL);
+ /* construct the package */
+ buf[0] = buf[6] = (unsigned char)(*pEMAC_ADDRLO & 0xFF);
+ buf[1] = buf[7] = (unsigned char)((*pEMAC_ADDRLO & 0xFF00) >> 8);
+ buf[2] = buf[8] = (unsigned char)((*pEMAC_ADDRLO & 0xFF0000) >> 16);
+ buf[3] = buf[9] = (unsigned char)((*pEMAC_ADDRLO & 0xFF000000) >> 24);
+ buf[4] = buf[10] = (unsigned char)(*pEMAC_ADDRHI & 0xFF);
+ buf[5] = buf[11] = (unsigned char)((*pEMAC_ADDRHI & 0xFF00) >> 8);
+ buf[12] = 0x08; /* Type: ARP */
+ buf[13] = 0x06;
+ buf[14] = 0x00; /* Hardware type: Ethernet */
+ buf[15] = 0x01;
+ buf[16] = 0x08; /* Protocal type: IP */
+ buf[17] = 0x00;
+ buf[18] = 0x06; /* Hardware size */
+ buf[19] = 0x04; /* Protocol size */
+ buf[20] = 0x00; /* Opcode: request */
+ buf[21] = 0x01;
+
+ for (i = 0; i < 42; i++)
+ buf[i + 22] = i;
+ printf("--------Send 64 bytes......\n");
+ bfin_EMAC_send(NULL, (volatile void *)buf, 64);
+ for (i = 0; i < 100; i++) {
+ udelay(10000);
+ if ((rxbuf[rxIdx]->StatusWord & RX_COMP) != 0) {
+ value = 1;
+ break;
+ }
+ }
+ if (value == 0) {
+ printf("--------EMAC can't receive any data\n");
+ eth_halt();
+ return -1;
+ }
+ length = rxbuf[rxIdx]->StatusWord & 0x000007FF - 4;
+ for (i = 0; i < length; i++) {
+ if (rxbuf[rxIdx]->FrmData->Dest[i] != buf[i]) {
+ printf("--------EMAC receive error data!\n");
+ eth_halt();
+ return -1;
+ }
+ }
+ printf("--------receive %d bytes, matched\n", length);
+ bfin_EMAC_halt(NULL);
+ return 0;
+}
+#endif
+#endif /* CFG_CMD_NET */
diff --git a/board/bf537-stamp/ether_bf537.h b/board/bf537-stamp/ether_bf537.h
new file mode 100644
index 00000000000..64240ba01b5
--- /dev/null
+++ b/board/bf537-stamp/ether_bf537.h
@@ -0,0 +1,110 @@
+#define PHYADDR 0x01
+#define NO_PHY_REGS 0x20
+
+#define DEFAULT_PHY_PHYID1 0x0007
+#define DEFAULT_PHY_PHYID2 0xC0A3
+#define PHY_MODECTL 0x00
+#define PHY_MODESTAT 0x01
+#define PHY_PHYID1 0x02
+#define PHY_PHYID2 0x03
+#define PHY_ANAR 0x04
+#define PHY_ANLPAR 0x05
+#define PHY_ANER 0x06
+
+#define PHY_RESET 0x8000
+#define PHY_ANEG_EN 0x1000
+#define PHY_DUPLEX 0x0100
+#define PHY_SPD_SET 0x2000
+
+#define RECV_BUFSIZE (0x614)
+
+typedef volatile u32 reg32;
+typedef volatile u16 reg16;
+
+typedef struct ADI_DMA_CONFIG_REG {
+ u16 b_DMA_EN:1; /* 0 Enabled */
+ u16 b_WNR:1; /* 1 Direction */
+ u16 b_WDSIZE:2; /* 2:3 Transfer word size */
+ u16 b_DMA2D:1; /* 4 DMA mode */
+ u16 b_RESTART:1; /* 5 Retain FIFO */
+ u16 b_DI_SEL:1; /* 6 Data interrupt timing select */
+ u16 b_DI_EN:1; /* 7 Data interrupt enabled */
+ u16 b_NDSIZE:4; /* 8:11 Flex descriptor size */
+ u16 b_FLOW:3; /* 12:14Flow */
+} ADI_DMA_CONFIG_REG;
+
+typedef struct adi_ether_frame_buffer {
+ u16 NoBytes; /* the no. of following bytes */
+ u8 Dest[6]; /* destination MAC address */
+ u8 Srce[6]; /* source MAC address */
+ u16 LTfield; /* length/type field */
+ u8 Data[0]; /* payload bytes */
+} ADI_ETHER_FRAME_BUFFER;
+/* 16 bytes/struct */
+
+typedef struct dma_descriptor {
+ struct dma_descriptor *NEXT_DESC_PTR;
+ u32 START_ADDR;
+ ADI_DMA_CONFIG_REG CONFIG;
+} DMA_DESCRIPTOR;
+/* 10 bytes/struct in 12 bytes */
+
+typedef struct adi_ether_buffer {
+ DMA_DESCRIPTOR Dma[2]; /* first for the frame, second for the status */
+ ADI_ETHER_FRAME_BUFFER *FrmData;/* pointer to data */
+ struct adi_ether_buffer *pNext; /* next buffer */
+ struct adi_ether_buffer *pPrev; /* prev buffer */
+ u16 IPHdrChksum; /* the IP header checksum */
+ u16 IPPayloadChksum; /* the IP header and payload checksum */
+ volatile u32 StatusWord; /* the frame status word */
+} ADI_ETHER_BUFFER;
+/* 40 bytes/struct in 44 bytes */
+
+void SetupMacAddr(u8 * MACaddr);
+
+void PollMdcDone(void);
+void WrPHYReg(u16 PHYAddr, u16 RegAddr, u16 Data);
+u16 RdPHYReg(u16 PHYAddr, u16 RegAddr);
+void SoftResetPHY(void);
+void DumpPHYRegs(void);
+
+int SetupSystemRegs(int *opmode);
+
+/**
+ * is_zero_ether_addr - Determine if give Ethernet address is all zeros.
+ * @addr: Pointer to a six-byte array containing the Ethernet address
+ *
+ * Return true if the address is all zeroes.
+ */
+static inline int is_zero_ether_addr(const u8 * addr)
+{
+ return !(addr[0] | addr[1] | addr[2] | addr[3] | addr[4] | addr[5]);
+}
+
+/**
+ * is_multicast_ether_addr - Determine if the Ethernet address is a multicast.
+ * @addr: Pointer to a six-byte array containing the Ethernet address
+ *
+ * Return true if the address is a multicast address.
+ * By definition the broadcast address is also a multicast address.
+ */
+static inline int is_multicast_ether_addr(const u8 * addr)
+{
+ return (0x01 & addr[0]);
+}
+
+/**
+ * is_valid_ether_addr - Determine if the given Ethernet address is valid
+ * @addr: Pointer to a six-byte array containing the Ethernet address
+ *
+ * Check that the Ethernet address (MAC) is not 00:00:00:00:00:00, is not
+ * a multicast address, and is not FF:FF:FF:FF:FF:FF.
+ *
+ * Return true if the address is valid.
+ */
+static inline int is_valid_ether_addr(const u8 * addr)
+{
+ /* FF:FF:FF:FF:FF:FF is a multicast address so we don't need to
+ * explicitly check for it here. */
+ return !is_multicast_ether_addr(addr) && !is_zero_ether_addr(addr);
+}
diff --git a/board/bf537-stamp/flash-defines.h b/board/bf537-stamp/flash-defines.h
new file mode 100644
index 00000000000..f19e171d04f
--- /dev/null
+++ b/board/bf537-stamp/flash-defines.h
@@ -0,0 +1,123 @@
+/*
+ * U-boot - flash-defines.h
+ *
+ * Copyright (c) 2005 blackfin.uclinux.org
+ *
+ * (C) Copyright 2000-2004
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef __FLASHDEFINES_H__
+#define __FLASHDEFINES_H__
+
+#include <common.h>
+
+#define V_ULONG(a) (*(volatile unsigned long *)( a ))
+#define V_BYTE(a) (*(volatile unsigned char *)( a ))
+#define TRUE 0x1
+#define FALSE 0x0
+#define BUFFER_SIZE 0x80000
+#define NO_COMMAND 0
+#define GET_CODES 1
+#define RESET 2
+#define WRITE 3
+#define FILL 4
+#define ERASE_ALL 5
+#define ERASE_SECT 6
+#define READ 7
+#define GET_SECTNUM 8
+#define FLASH_START_L 0x0000
+#define FLASH_START_H 0x2000
+#define FLASH_MAN_ST 2
+#define RESET_VAL 0xF0
+
+flash_info_t flash_info[CFG_MAX_FLASH_BANKS];
+
+int get_codes(void);
+int poll_toggle_bit(long lOffset);
+void reset_flash(void);
+int erase_flash(void);
+int erase_block_flash(int);
+void unlock_flash(long lOffset);
+int write_data(long lStart, long lCount, uchar * pnData);
+int read_flash(long nOffset, int *pnValue);
+int write_flash(long nOffset, int nValue);
+void get_sector_number(long lOffset, int *pnSector);
+int GetSectorProtectionStatus(flash_info_t * info, int nSector);
+int GetOffset(int nBlock);
+int AFP_NumSectors = 71;
+long AFP_SectorSize2 = 0x10000;
+int AFP_SectorSize1 = 0x2000;
+
+#define NUM_SECTORS 71
+
+#define WRITESEQ1 0x0AAA
+#define WRITESEQ2 0x0554
+#define WRITESEQ3 0x0AAA
+#define WRITESEQ4 0x0AAA
+#define WRITESEQ5 0x0554
+#define WRITESEQ6 0x0AAA
+#define WRITEDATA1 0xaa
+#define WRITEDATA2 0x55
+#define WRITEDATA3 0x80
+#define WRITEDATA4 0xaa
+#define WRITEDATA5 0x55
+#define WRITEDATA6 0x10
+#define PriFlashABegin 0
+#define SecFlashABegin 8
+#define SecFlashBBegin 36
+#define PriFlashAOff 0x0
+#define PriFlashBOff 0x100000
+#define SecFlashAOff 0x10000
+#define SecFlashBOff 0x280000
+#define INVALIDLOCNSTART 0x20270000
+#define INVALIDLOCNEND 0x20280000
+#define BlockEraseVal 0x30
+#define UNLOCKDATA1 0xaa
+#define UNLOCKDATA2 0x55
+#define UNLOCKDATA3 0xa0
+#define GETCODEDATA1 0xaa
+#define GETCODEDATA2 0x55
+#define GETCODEDATA3 0x90
+#define SecFlashASec1Off 0x200000
+#define SecFlashASec2Off 0x204000
+#define SecFlashASec3Off 0x206000
+#define SecFlashASec4Off 0x208000
+#define SecFlashAEndOff 0x210000
+#define SecFlashBSec1Off 0x280000
+#define SecFlashBSec2Off 0x284000
+#define SecFlashBSec3Off 0x286000
+#define SecFlashBSec4Off 0x288000
+#define SecFlashBEndOff 0x290000
+
+#define SECT32 32
+#define SECT33 33
+#define SECT34 34
+#define SECT35 35
+#define SECT36 36
+#define SECT37 37
+#define SECT38 38
+#define SECT39 39
+
+#define FLASH_SUCCESS 0
+#define FLASH_FAIL -1
+
+#endif
diff --git a/board/bf537-stamp/flash.c b/board/bf537-stamp/flash.c
new file mode 100644
index 00000000000..42dcf062b1a
--- /dev/null
+++ b/board/bf537-stamp/flash.c
@@ -0,0 +1,403 @@
+/*
+ * U-boot - flash.c Flash driver for PSD4256GV
+ *
+ * Copyright (c) 2005 blackfin.uclinux.org
+ * This file is based on BF533EzFlash.c originally written by Analog Devices, Inc.
+ *
+ * (C) Copyright 2000-2004
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <malloc.h>
+#include <config.h>
+#include <asm/io.h>
+#include "flash-defines.h"
+
+void flash_reset(void)
+{
+ reset_flash();
+}
+
+unsigned long flash_get_size(ulong baseaddr, flash_info_t * info, int bank_flag)
+{
+ int id = 0, i = 0;
+ static int FlagDev = 1;
+
+ id = get_codes();
+ if (FlagDev) {
+ FlagDev = 0;
+ }
+ info->flash_id = id;
+ switch (bank_flag) {
+ case 0:
+ for (i = PriFlashABegin; i < SecFlashABegin; i++)
+ info->start[i] = (baseaddr + (i * AFP_SectorSize1));
+ for (i = SecFlashABegin; i < NUM_SECTORS; i++)
+ info->start[i] =
+ (baseaddr + SecFlashAOff +
+ ((i - SecFlashABegin) * AFP_SectorSize2));
+ info->size = 0x400000;
+ info->sector_count = NUM_SECTORS;
+ break;
+ case 1:
+ info->start[0] = baseaddr + SecFlashASec1Off;
+ info->start[1] = baseaddr + SecFlashASec2Off;
+ info->start[2] = baseaddr + SecFlashASec3Off;
+ info->start[3] = baseaddr + SecFlashASec4Off;
+ info->size = 0x10000;
+ info->sector_count = 4;
+ break;
+ case 2:
+ info->start[0] = baseaddr + SecFlashBSec1Off;
+ info->start[1] = baseaddr + SecFlashBSec2Off;
+ info->start[2] = baseaddr + SecFlashBSec3Off;
+ info->start[3] = baseaddr + SecFlashBSec4Off;
+ info->size = 0x10000;
+ info->sector_count = 4;
+ break;
+ }
+ return (info->size);
+}
+
+unsigned long flash_init(void)
+{
+ unsigned long size_b;
+ int i;
+
+ size_b = 0;
+ for (i = 0; i < CFG_MAX_FLASH_BANKS; ++i) {
+ flash_info[i].flash_id = FLASH_UNKNOWN;
+ }
+
+ size_b = flash_get_size(CFG_FLASH_BASE, &flash_info[0], 0);
+
+ if (flash_info[0].flash_id == FLASH_UNKNOWN || size_b == 0) {
+ printf("## Unknown FLASH on Bank 0 - Size = 0x%08lx = %ld MB\n",
+ size_b, size_b >> 20);
+ }
+
+ /* flash_protect (int flag, ulong from, ulong to, flash_info_t *info) */
+ (void)flash_protect(FLAG_PROTECT_SET, CFG_FLASH_BASE,
+ (flash_info[0].start[2] - 1), &flash_info[0]);
+#if (BFIN_BOOT_MODE == BF537_BYPASS_BOOT)
+ (void)flash_protect(FLAG_PROTECT_SET, 0x203F0000, 0x203FFFFF,
+ &flash_info[0]);
+#endif
+
+ return (size_b);
+}
+
+void flash_print_info(flash_info_t * info)
+{
+ int i;
+
+ if (info->flash_id == FLASH_UNKNOWN) {
+ printf("missing or unknown FLASH type\n");
+ return;
+ }
+
+ switch (info->flash_id) {
+ case (STM_ID_29W320EB & 0xFFFF):
+ case (STM_ID_29W320DB & 0xFFFF):
+ printf("ST Microelectronics ");
+ break;
+ default:
+ printf("Unknown Vendor: (0x%08X) ", info->flash_id);
+ break;
+ }
+ for (i = 0; i < info->sector_count; ++i) {
+ if ((i % 5) == 0)
+ printf("\n ");
+ printf(" %08lX%s",
+ info->start[i], info->protect[i] ? " (RO)" : " ");
+ }
+ printf("\n");
+ return;
+}
+
+int flash_erase(flash_info_t * info, int s_first, int s_last)
+{
+ int cnt = 0, i;
+ int prot, sect;
+
+ prot = 0;
+ for (sect = s_first; sect <= s_last; ++sect) {
+ if (info->protect[sect])
+ prot++;
+ }
+ if (prot)
+ printf("- Warning: %d protected sectors will not be erased!\n",
+ prot);
+ else
+ printf("\n");
+
+ cnt = s_last - s_first + 1;
+
+#if (BFIN_BOOT_MODE == BF537_BYPASS_BOOT)
+ printf("Erasing Flash locations, Please Wait\n");
+ for (i = s_first; i <= s_last; i++) {
+ if (info->protect[i] == 0) { /* not protected */
+ if (erase_block_flash(i) < 0) {
+ printf("Error Sector erasing \n");
+ return FLASH_FAIL;
+ }
+ }
+ }
+#elif (BFIN_BOOT_MODE == BF537_SPI_MASTER_BOOT)
+ if (cnt == FLASH_TOT_SECT) {
+ printf("Erasing flash, Please Wait \n");
+ if (erase_flash() < 0) {
+ printf("Erasing flash failed \n");
+ return FLASH_FAIL;
+ }
+ } else {
+ printf("Erasing Flash locations, Please Wait\n");
+ for (i = s_first; i <= s_last; i++) {
+ if (info->protect[i] == 0) { /* not protected */
+ if (erase_block_flash(i) < 0) {
+ printf("Error Sector erasing \n");
+ return FLASH_FAIL;
+ }
+ }
+ }
+ }
+#endif
+ printf("\n");
+ return FLASH_SUCCESS;
+}
+
+int write_buff(flash_info_t * info, uchar * src, ulong addr, ulong cnt)
+{
+ int d;
+ if (addr % 2) {
+ read_flash(addr - 1 - CFG_FLASH_BASE, &d);
+ d = (int)((d & 0x00FF) | (*src++ << 8));
+ write_data(addr - 1, 2, (uchar *) & d);
+ write_data(addr + 1, cnt - 1, src);
+ } else
+ write_data(addr, cnt, src);
+ return FLASH_SUCCESS;
+}
+
+int write_data(long lStart, long lCount, uchar * pnData)
+{
+ long i = 0;
+ unsigned long ulOffset = lStart - CFG_FLASH_BASE;
+ int d;
+ int nSector = 0;
+ int flag = 0;
+
+ if (lCount % 2) {
+ flag = 1;
+ lCount = lCount - 1;
+ }
+
+ for (i = 0; i < lCount - 1; i += 2, ulOffset += 2) {
+ get_sector_number(ulOffset, &nSector);
+ read_flash(ulOffset, &d);
+ if (d != 0xffff) {
+ printf
+ ("Flash not erased at offset 0x%x Please erase to reprogram \n",
+ ulOffset);
+ return FLASH_FAIL;
+ }
+ unlock_flash(ulOffset);
+ d = (int)(pnData[i] | pnData[i + 1] << 8);
+ write_flash(ulOffset, d);
+ if (poll_toggle_bit(ulOffset) < 0) {
+ printf("Error programming the flash \n");
+ return FLASH_FAIL;
+ }
+ if ((i > 0) && (!(i % AFP_SectorSize2)))
+ printf(".");
+ }
+ if (flag) {
+ get_sector_number(ulOffset, &nSector);
+ read_flash(ulOffset, &d);
+ if (d != 0xffff) {
+ printf
+ ("Flash not erased at offset 0x%x Please erase to reprogram \n",
+ ulOffset);
+ return FLASH_FAIL;
+ }
+ unlock_flash(ulOffset);
+ d = (int)(pnData[i] | (d & 0xFF00));
+ write_flash(ulOffset, d);
+ if (poll_toggle_bit(ulOffset) < 0) {
+ printf("Error programming the flash \n");
+ return FLASH_FAIL;
+ }
+ }
+ return FLASH_SUCCESS;
+}
+
+int write_flash(long nOffset, int nValue)
+{
+ long addr;
+
+ addr = (CFG_FLASH_BASE + nOffset);
+ *(unsigned volatile short *)addr = nValue;
+ sync();
+#if (BFIN_BOOT_MODE == BF537_SPI_MASTER_BOOT)
+ if (icache_status())
+ udelay(CONFIG_CCLK_HZ / 1000000);
+#endif
+ return FLASH_SUCCESS;
+}
+
+int read_flash(long nOffset, int *pnValue)
+{
+ unsigned short *pFlashAddr =
+ (unsigned short *)(CFG_FLASH_BASE + nOffset);
+
+ *pnValue = *pFlashAddr;
+
+ return TRUE;
+}
+
+int poll_toggle_bit(long lOffset)
+{
+ unsigned int u1, u2;
+ volatile unsigned long *FB =
+ (volatile unsigned long *)(CFG_FLASH_BASE + lOffset);
+ while (1) {
+ u1 = *(volatile unsigned short *)FB;
+ u2 = *(volatile unsigned short *)FB;
+ u1 ^= u2;
+ if (!(u1 & 0x0040))
+ break;
+ if (!(u2 & 0x0020))
+ continue;
+ else {
+ u1 = *(volatile unsigned short *)FB;
+ u2 = *(volatile unsigned short *)FB;
+ u1 ^= u2;
+ if (!(u1 & 0x0040))
+ break;
+ else {
+ reset_flash();
+ return FLASH_FAIL;
+ }
+ }
+ }
+ return FLASH_SUCCESS;
+}
+
+void reset_flash(void)
+{
+ write_flash(WRITESEQ1, RESET_VAL);
+ /* Wait for 10 micro seconds */
+ udelay(10);
+}
+
+int erase_flash(void)
+{
+ write_flash(WRITESEQ1, WRITEDATA1);
+ write_flash(WRITESEQ2, WRITEDATA2);
+ write_flash(WRITESEQ3, WRITEDATA3);
+ write_flash(WRITESEQ4, WRITEDATA4);
+ write_flash(WRITESEQ5, WRITEDATA5);
+ write_flash(WRITESEQ6, WRITEDATA6);
+
+ if (poll_toggle_bit(0x0000) < 0)
+ return FLASH_FAIL;
+
+ return FLASH_SUCCESS;
+}
+
+int erase_block_flash(int nBlock)
+{
+ long ulSectorOff = 0x0;
+
+ if ((nBlock < 0) || (nBlock > AFP_NumSectors))
+ return FALSE;
+
+ /* figure out the offset of the block in flash */
+ if ((nBlock >= 0) && (nBlock < SecFlashABegin))
+ ulSectorOff = nBlock * AFP_SectorSize1;
+
+ else if ((nBlock >= SecFlashABegin) && (nBlock < NUM_SECTORS))
+ ulSectorOff =
+ SecFlashAOff + (nBlock - SecFlashABegin) * AFP_SectorSize2;
+ /* no such sector */
+ else
+ return FLASH_FAIL;
+
+ write_flash((WRITESEQ1 | ulSectorOff), WRITEDATA1);
+ write_flash((WRITESEQ2 | ulSectorOff), WRITEDATA2);
+ write_flash((WRITESEQ3 | ulSectorOff), WRITEDATA3);
+ write_flash((WRITESEQ4 | ulSectorOff), WRITEDATA4);
+ write_flash((WRITESEQ5 | ulSectorOff), WRITEDATA5);
+
+ write_flash(ulSectorOff, BlockEraseVal);
+
+ if (poll_toggle_bit(ulSectorOff) < 0)
+ return FLASH_FAIL;
+ printf(".");
+
+ return FLASH_SUCCESS;
+}
+
+void unlock_flash(long ulOffset)
+{
+ unsigned long ulOffsetAddr = ulOffset;
+ ulOffsetAddr &= 0xFFFF0000;
+
+ write_flash((WRITESEQ1 | ulOffsetAddr), UNLOCKDATA1);
+ write_flash((WRITESEQ2 | ulOffsetAddr), UNLOCKDATA2);
+ write_flash((WRITESEQ3 | ulOffsetAddr), UNLOCKDATA3);
+}
+
+int get_codes()
+{
+ int dev_id = 0;
+
+ write_flash(WRITESEQ1, GETCODEDATA1);
+ write_flash(WRITESEQ2, GETCODEDATA2);
+ write_flash(WRITESEQ3, GETCODEDATA3);
+
+ read_flash(0x0402, &dev_id);
+ dev_id &= 0x0000FFFF;
+
+ reset_flash();
+
+ return dev_id;
+}
+
+void get_sector_number(long ulOffset, int *pnSector)
+{
+ int nSector = 0;
+ long lMainEnd = 0x400000;
+ long lBootEnd = 0x10000;
+
+ /* sector numbers for the FLASH A boot sectors */
+ if (ulOffset < lBootEnd) {
+ nSector = (int)ulOffset / AFP_SectorSize1;
+ }
+ /* sector numbers for the FLASH B boot sectors */
+ else if ((ulOffset >= lBootEnd) && (ulOffset < lMainEnd)) {
+ nSector = ((ulOffset / (AFP_SectorSize2)) + 7);
+ }
+ /* if it is a valid sector, set it */
+ if ((nSector >= 0) && (nSector < AFP_NumSectors))
+ *pnSector = nSector;
+
+}
diff --git a/board/bf537-stamp/nand.c b/board/bf537-stamp/nand.c
new file mode 100644
index 00000000000..4d6e7760d52
--- /dev/null
+++ b/board/bf537-stamp/nand.c
@@ -0,0 +1,106 @@
+/*
+ * (C) Copyright 2006 Aubrey.Li, aubrey.li@analog.com
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <asm/io.h>
+
+#if (CONFIG_COMMANDS & CFG_CMD_NAND)
+
+#include <nand.h>
+
+#define CONCAT(a,b,c,d) a ## b ## c ## d
+#define PORT(a,b) CONCAT(pPORT,a,b,)
+
+#ifndef CONFIG_NAND_GPIO_PORT
+#define CONFIG_NAND_GPIO_PORT F
+#endif
+
+/*
+ * hardware specific access to control-lines
+ */
+static void bfin_hwcontrol(struct mtd_info *mtd, int cmd)
+{
+ register struct nand_chip *this = mtd->priv;
+
+ switch (cmd) {
+
+ case NAND_CTL_SETCLE:
+ this->IO_ADDR_W = CFG_NAND_BASE + BFIN_NAND_CLE;
+ break;
+ case NAND_CTL_CLRCLE:
+ this->IO_ADDR_W = CFG_NAND_BASE;
+ break;
+
+ case NAND_CTL_SETALE:
+ this->IO_ADDR_W = CFG_NAND_BASE + BFIN_NAND_ALE;
+ break;
+ case NAND_CTL_CLRALE:
+ this->IO_ADDR_W = CFG_NAND_BASE;
+ break;
+ case NAND_CTL_SETNCE:
+ case NAND_CTL_CLRNCE:
+ break;
+ }
+
+ this->IO_ADDR_R = this->IO_ADDR_W;
+
+ /* Drain the writebuffer */
+ sync();
+}
+
+int bfin_device_ready(struct mtd_info *mtd)
+{
+ int ret = (*PORT(CONFIG_NAND_GPIO_PORT, IO) & BFIN_NAND_READY) ? 1 : 0;
+ sync();
+ return ret;
+}
+
+/*
+ * Board-specific NAND initialization. The following members of the
+ * argument are board-specific (per include/linux/mtd/nand.h):
+ * - IO_ADDR_R?: address to read the 8 I/O lines of the flash device
+ * - IO_ADDR_W?: address to write the 8 I/O lines of the flash device
+ * - hwcontrol: hardwarespecific function for accesing control-lines
+ * - dev_ready: hardwarespecific function for accesing device ready/busy line
+ * - enable_hwecc?: function to enable (reset) hardware ecc generator. Must
+ * only be provided if a hardware ECC is available
+ * - eccmode: mode of ecc, see defines
+ * - chip_delay: chip dependent delay for transfering data from array to
+ * read regs (tR)
+ * - options: various chip options. They can partly be set to inform
+ * nand_scan about special functionality. See the defines for further
+ * explanation
+ * Members with a "?" were not set in the merged testing-NAND branch,
+ * so they are not set here either.
+ */
+void board_nand_init(struct nand_chip *nand)
+{
+ *PORT(CONFIG_NAND_GPIO_PORT, _FER) &= ~BFIN_NAND_READY;
+ *PORT(CONFIG_NAND_GPIO_PORT, IO_DIR) &= ~BFIN_NAND_READY;
+ *PORT(CONFIG_NAND_GPIO_PORT, IO_INEN) |= BFIN_NAND_READY;
+
+ nand->hwcontrol = bfin_hwcontrol;
+ nand->eccmode = NAND_ECC_SOFT;
+ nand->dev_ready = bfin_device_ready;
+ nand->chip_delay = 30;
+}
+#endif /* (CONFIG_COMMANDS & CFG_CMD_NAND) */
diff --git a/board/bf537-stamp/post-memory.c b/board/bf537-stamp/post-memory.c
new file mode 100644
index 00000000000..60393505a28
--- /dev/null
+++ b/board/bf537-stamp/post-memory.c
@@ -0,0 +1,322 @@
+#include <common.h>
+#include <asm/io.h>
+
+#ifdef CONFIG_POST
+
+#include <post.h>
+#include <watchdog.h>
+
+#if CONFIG_POST & CFG_POST_MEMORY
+#define CLKIN 25000000
+#define PATTERN1 0x5A5A5A5A
+#define PATTERN2 0xAAAAAAAA
+
+#define CCLK_NUM 4
+#define SCLK_NUM 3
+
+void post_out_buff(char *buff);
+int post_key_pressed(void);
+void post_init_pll(int mult, int div);
+int post_init_sdram(int sclk);
+void post_init_uart(int sclk);
+
+const int pll[CCLK_NUM][SCLK_NUM][2] = {
+ {{20, 4}, {20, 5}, {20, 10}}, /* CCLK = 500M */
+ {{16, 4}, {16, 5}, {16, 8}}, /* CCLK = 400M */
+ {{8, 2}, {8, 4}, {8, 5}}, /* CCLK = 200M */
+ {{4, 1}, {4, 2}, {4, 4}} /* CCLK = 100M */
+};
+const char *const log[CCLK_NUM][SCLK_NUM] = {
+ {"CCLK-500Mhz SCLK-125Mhz: Writing...\0",
+ "CCLK-500Mhz SCLK-100Mhz: Writing...\0",
+ "CCLK-500Mhz SCLK- 50Mhz: Writing...\0",},
+ {"CCLK-400Mhz SCLK-100Mhz: Writing...\0",
+ "CCLK-400Mhz SCLK- 80Mhz: Writing...\0",
+ "CCLK-400Mhz SCLK- 50Mhz: Writing...\0",},
+ {"CCLK-200Mhz SCLK-100Mhz: Writing...\0",
+ "CCLK-200Mhz SCLK- 50Mhz: Writing...\0",
+ "CCLK-200Mhz SCLK- 40Mhz: Writing...\0",},
+ {"CCLK-100Mhz SCLK-100Mhz: Writing...\0",
+ "CCLK-100Mhz SCLK- 50Mhz: Writing...\0",
+ "CCLK-100Mhz SCLK- 25Mhz: Writing...\0",},
+};
+
+int memory_post_test(int flags)
+{
+ int addr;
+ int m, n;
+ int sclk, sclk_temp;
+ int ret = 1;
+
+ sclk_temp = CLKIN / 1000000;
+ sclk_temp = sclk_temp * CONFIG_VCO_MULT;
+ for (sclk = 0; sclk_temp > 0; sclk++)
+ sclk_temp -= CONFIG_SCLK_DIV;
+ sclk = sclk * 1000000;
+ post_init_uart(sclk);
+ if (post_key_pressed() == 0)
+ return 0;
+
+ for (m = 0; m < CCLK_NUM; m++) {
+ for (n = 0; n < SCLK_NUM; n++) {
+ /* Calculate the sclk */
+ sclk_temp = CLKIN / 1000000;
+ sclk_temp = sclk_temp * pll[m][n][0];
+ for (sclk = 0; sclk_temp > 0; sclk++)
+ sclk_temp -= pll[m][n][1];
+ sclk = sclk * 1000000;
+
+ post_init_pll(pll[m][n][0], pll[m][n][1]);
+ post_init_sdram(sclk);
+ post_init_uart(sclk);
+ post_out_buff("\n\r\0");
+ post_out_buff(log[m][n]);
+ for (addr = 0x0; addr < CFG_MAX_RAM_SIZE; addr += 4)
+ *(unsigned long *)addr = PATTERN1;
+ post_out_buff("Reading...\0");
+ for (addr = 0x0; addr < CFG_MAX_RAM_SIZE; addr += 4) {
+ if ((*(unsigned long *)addr) != PATTERN1) {
+ post_out_buff("Error\n\r\0");
+ ret = 0;
+ }
+ }
+ post_out_buff("OK\n\r\0");
+ }
+ }
+ if (ret)
+ post_out_buff("memory POST passed\n\r\0");
+ else
+ post_out_buff("memory POST failed\n\r\0");
+
+ post_out_buff("\n\r\n\r\0");
+ return 1;
+}
+
+void post_init_uart(int sclk)
+{
+ int divisor;
+
+ for (divisor = 0; sclk > 0; divisor++)
+ sclk -= 57600 * 16;
+
+ *pPORTF_FER = 0x000F;
+ *pPORTH_FER = 0xFFFF;
+
+ *pUART_GCTL = 0x00;
+ *pUART_LCR = 0x83;
+ sync();
+ *pUART_DLL = (divisor & 0xFF);
+ sync();
+ *pUART_DLH = ((divisor >> 8) & 0xFF);
+ sync();
+ *pUART_LCR = 0x03;
+ sync();
+ *pUART_GCTL = 0x01;
+ sync();
+}
+
+void post_out_buff(char *buff)
+{
+
+ int i = 0;
+ for (i = 0; i < 0x80000; i++) ;
+ i = 0;
+ while ((buff[i] != '\0') && (i != 100)) {
+ while (!(*pUART_LSR & 0x20)) ;
+ *pUART_THR = buff[i];
+ sync();
+ i++;
+ }
+ for (i = 0; i < 0x80000; i++) ;
+}
+
+/* Using sw10-PF5 as the hotkey */
+#define KEY_LOOP 0x80000
+#define KEY_DELAY 0x80
+int post_key_pressed(void)
+{
+ int i, n;
+ unsigned short value;
+
+ *pPORTF_FER &= ~PF5;
+ *pPORTFIO_DIR &= ~PF5;
+ *pPORTFIO_INEN |= PF5;
+ sync();
+
+ post_out_buff("########Press SW10 to enter Memory POST########: 3\0");
+ for (i = 0; i < KEY_LOOP; i++) {
+ value = *pPORTFIO & PF5;
+ if (*pUART0_RBR == 0x0D) {
+ value = 0;
+ goto key_pressed;
+ }
+ if (value != 0) {
+ goto key_pressed;
+ }
+ for (n = 0; n < KEY_DELAY; n++)
+ asm("nop");
+ }
+ post_out_buff("\b2\0");
+
+ for (i = 0; i < KEY_LOOP; i++) {
+ value = *pPORTFIO & PF5;
+ if (*pUART0_RBR == 0x0D) {
+ value = 0;
+ goto key_pressed;
+ }
+ if (value != 0) {
+ goto key_pressed;
+ }
+ for (n = 0; n < KEY_DELAY; n++)
+ asm("nop");
+ }
+ post_out_buff("\b1\0");
+
+ for (i = 0; i < KEY_LOOP; i++) {
+ value = *pPORTFIO & PF5;
+ if (*pUART0_RBR == 0x0D) {
+ value = 0;
+ goto key_pressed;
+ }
+ if (value != 0) {
+ goto key_pressed;
+ }
+ for (n = 0; n < KEY_DELAY; n++)
+ asm("nop");
+ }
+ key_pressed:
+ post_out_buff("\b0");
+ post_out_buff("\n\r\0");
+ if (value == 0)
+ return 0;
+ post_out_buff("Hotkey has been pressed, Enter POST . . . . . .\n\r\0");
+ return 1;
+}
+
+void post_init_pll(int mult, int div)
+{
+
+ *pSIC_IWR = 0x01;
+ *pPLL_CTL = (mult << 9);
+ *pPLL_DIV = div;
+ asm("CLI R2;");
+ asm("IDLE;");
+ asm("STI R2;");
+ while (!(*pPLL_STAT & 0x20)) ;
+}
+
+int post_init_sdram(int sclk)
+{
+ int SDRAM_tRP, SDRAM_tRP_num, SDRAM_tRAS, SDRAM_tRAS_num, SDRAM_tRCD,
+ SDRAM_tWR;
+ int SDRAM_Tref, SDRAM_NRA, SDRAM_CL, SDRAM_SIZE, SDRAM_WIDTH,
+ mem_SDGCTL, mem_SDBCTL, mem_SDRRC;
+
+ if ((sclk > 119402985)) {
+ SDRAM_tRP = TRP_2;
+ SDRAM_tRP_num = 2;
+ SDRAM_tRAS = TRAS_7;
+ SDRAM_tRAS_num = 7;
+ SDRAM_tRCD = TRCD_2;
+ SDRAM_tWR = TWR_2;
+ } else if ((sclk > 104477612) && (sclk <= 119402985)) {
+ SDRAM_tRP = TRP_2;
+ SDRAM_tRP_num = 2;
+ SDRAM_tRAS = TRAS_6;
+ SDRAM_tRAS_num = 6;
+ SDRAM_tRCD = TRCD_2;
+ SDRAM_tWR = TWR_2;
+ } else if ((sclk > 89552239) && (sclk <= 104477612)) {
+ SDRAM_tRP = TRP_2;
+ SDRAM_tRP_num = 2;
+ SDRAM_tRAS = TRAS_5;
+ SDRAM_tRAS_num = 5;
+ SDRAM_tRCD = TRCD_2;
+ SDRAM_tWR = TWR_2;
+ } else if ((sclk > 74626866) && (sclk <= 89552239)) {
+ SDRAM_tRP = TRP_2;
+ SDRAM_tRP_num = 2;
+ SDRAM_tRAS = TRAS_4;
+ SDRAM_tRAS_num = 4;
+ SDRAM_tRCD = TRCD_2;
+ SDRAM_tWR = TWR_2;
+ } else if ((sclk > 66666667) && (sclk <= 74626866)) {
+ SDRAM_tRP = TRP_2;
+ SDRAM_tRP_num = 2;
+ SDRAM_tRAS = TRAS_3;
+ SDRAM_tRAS_num = 3;
+ SDRAM_tRCD = TRCD_2;
+ SDRAM_tWR = TWR_2;
+ } else if ((sclk > 59701493) && (sclk <= 66666667)) {
+ SDRAM_tRP = TRP_1;
+ SDRAM_tRP_num = 1;
+ SDRAM_tRAS = TRAS_4;
+ SDRAM_tRAS_num = 4;
+ SDRAM_tRCD = TRCD_1;
+ SDRAM_tWR = TWR_2;
+ } else if ((sclk > 44776119) && (sclk <= 59701493)) {
+ SDRAM_tRP = TRP_1;
+ SDRAM_tRP_num = 1;
+ SDRAM_tRAS = TRAS_3;
+ SDRAM_tRAS_num = 3;
+ SDRAM_tRCD = TRCD_1;
+ SDRAM_tWR = TWR_2;
+ } else if ((sclk > 29850746) && (sclk <= 44776119)) {
+ SDRAM_tRP = TRP_1;
+ SDRAM_tRP_num = 1;
+ SDRAM_tRAS = TRAS_2;
+ SDRAM_tRAS_num = 2;
+ SDRAM_tRCD = TRCD_1;
+ SDRAM_tWR = TWR_2;
+ } else if (sclk <= 29850746) {
+ SDRAM_tRP = TRP_1;
+ SDRAM_tRP_num = 1;
+ SDRAM_tRAS = TRAS_1;
+ SDRAM_tRAS_num = 1;
+ SDRAM_tRCD = TRCD_1;
+ SDRAM_tWR = TWR_2;
+ } else {
+ SDRAM_tRP = TRP_1;
+ SDRAM_tRP_num = 1;
+ SDRAM_tRAS = TRAS_1;
+ SDRAM_tRAS_num = 1;
+ SDRAM_tRCD = TRCD_1;
+ SDRAM_tWR = TWR_2;
+ }
+ /*SDRAM INFORMATION: */
+ SDRAM_Tref = 64; /* Refresh period in milliseconds */
+ SDRAM_NRA = 4096; /* Number of row addresses in SDRAM */
+ SDRAM_CL = CL_3; /* 2 */
+
+ SDRAM_SIZE = EBSZ_64;
+ SDRAM_WIDTH = EBCAW_10;
+
+ mem_SDBCTL = SDRAM_WIDTH | SDRAM_SIZE | EBE;
+
+ /* Equation from section 17 (p17-46) of BF533 HRM */
+ mem_SDRRC =
+ (((CONFIG_SCLK_HZ / 1000) * SDRAM_Tref) / SDRAM_NRA) -
+ (SDRAM_tRAS_num + SDRAM_tRP_num);
+
+ /* Enable SCLK Out */
+ mem_SDGCTL =
+ (SCTLE | SDRAM_CL | SDRAM_tRAS | SDRAM_tRP | SDRAM_tRCD | SDRAM_tWR
+ | PSS);
+
+ sync();
+
+ *pEBIU_SDGCTL |= 0x1000000;
+ /* Set the SDRAM Refresh Rate control register based on SSCLK value */
+ *pEBIU_SDRRC = mem_SDRRC;
+
+ /* SDRAM Memory Bank Control Register */
+ *pEBIU_SDBCTL = mem_SDBCTL;
+
+ /* SDRAM Memory Global Control Register */
+ *pEBIU_SDGCTL = mem_SDGCTL;
+ sync();
+ return mem_SDRRC;
+}
+
+#endif /* CONFIG_POST & CFG_POST_MEMORY */
+#endif /* CONFIG_POST */
diff --git a/board/bf537-stamp/stm_m25p64.c b/board/bf537-stamp/stm_m25p64.c
new file mode 100644
index 00000000000..7077e85f412
--- /dev/null
+++ b/board/bf537-stamp/stm_m25p64.c
@@ -0,0 +1,515 @@
+/****************************************************************************
+ * SPI flash driver for M25P64
+ ****************************************************************************/
+#include <common.h>
+#include <linux/ctype.h>
+#include <asm/io.h>
+
+#if defined(CONFIG_SPI)
+
+/* Application definitions */
+
+#define NUM_SECTORS 128 /* number of sectors */
+#define SECTOR_SIZE 0x10000
+#define NOP_NUM 1000
+
+#define COMMON_SPI_SETTINGS (SPE|MSTR|CPHA|CPOL) /* Settings to the SPI_CTL */
+#define TIMOD01 (0x01) /* stes the SPI to work with core instructions */
+
+/* Flash commands */
+#define SPI_WREN (0x06) /*Set Write Enable Latch */
+#define SPI_WRDI (0x04) /*Reset Write Enable Latch */
+#define SPI_RDSR (0x05) /*Read Status Register */
+#define SPI_WRSR (0x01) /*Write Status Register */
+#define SPI_READ (0x03) /*Read data from memory */
+#define SPI_FAST_READ (0x0B) /*Read data from memory */
+#define SPI_PP (0x02) /*Program Data into memory */
+#define SPI_SE (0xD8) /*Erase one sector in memory */
+#define SPI_BE (0xC7) /*Erase all memory */
+#define WIP (0x1) /*Check the write in progress bit of the SPI status register */
+#define WEL (0x2) /*Check the write enable bit of the SPI status register */
+
+#define TIMEOUT 350000000
+
+typedef enum {
+ NO_ERR,
+ POLL_TIMEOUT,
+ INVALID_SECTOR,
+ INVALID_BLOCK,
+} ERROR_CODE;
+
+void spi_init_f(void);
+void spi_init_r(void);
+ssize_t spi_read(uchar *, int, uchar *, int);
+ssize_t spi_write(uchar *, int, uchar *, int);
+
+char ReadStatusRegister(void);
+void Wait_For_SPIF(void);
+void SetupSPI(const int spi_setting);
+void SPI_OFF(void);
+void SendSingleCommand(const int iCommand);
+
+ERROR_CODE GetSectorNumber(unsigned long ulOffset, int *pnSector);
+ERROR_CODE EraseBlock(int nBlock);
+ERROR_CODE ReadData(unsigned long ulStart, long lCount, int *pnData);
+ERROR_CODE WriteData(unsigned long ulStart, long lCount, int *pnData);
+ERROR_CODE Wait_For_Status(char Statusbit);
+ERROR_CODE Wait_For_WEL(void);
+
+/*
+ * Function: spi_init_f
+ * Description: Init SPI-Controller (ROM part)
+ * return: ---
+ */
+void spi_init_f(void)
+{
+}
+
+/*
+ * Function: spi_init_r
+ * Description: Init SPI-Controller (RAM part) -
+ * The malloc engine is ready and we can move our buffers to
+ * normal RAM
+ * return: ---
+ */
+void spi_init_r(void)
+{
+ return;
+}
+
+/*
+ * Function: spi_write
+ */
+ssize_t spi_write(uchar * addr, int alen, uchar * buffer, int len)
+{
+ unsigned long offset;
+ int start_block, end_block;
+ int start_byte, end_byte;
+ ERROR_CODE result = NO_ERR;
+ uchar temp[SECTOR_SIZE];
+ int i, num;
+
+ offset = addr[0] << 16 | addr[1] << 8 | addr[2];
+ /* Get the start block number */
+ result = GetSectorNumber(offset, &start_block);
+ if (result == INVALID_SECTOR) {
+ printf("Invalid sector! ");
+ return 0;
+ }
+ /* Get the end block number */
+ result = GetSectorNumber(offset + len - 1, &end_block);
+ if (result == INVALID_SECTOR) {
+ printf("Invalid sector! ");
+ return 0;
+ }
+
+ for (num = start_block; num <= end_block; num++) {
+ ReadData(num * SECTOR_SIZE, SECTOR_SIZE, (int *)temp);
+ start_byte = num * SECTOR_SIZE;
+ end_byte = (num + 1) * SECTOR_SIZE - 1;
+ if (start_byte < offset)
+ start_byte = offset;
+ if (end_byte > (offset + len))
+ end_byte = (offset + len - 1);
+ for (i = start_byte; i <= end_byte; i++)
+ temp[i - num * SECTOR_SIZE] = buffer[i - offset];
+ EraseBlock(num);
+ result = WriteData(num * SECTOR_SIZE, SECTOR_SIZE, (int *)temp);
+ if (result != NO_ERR)
+ return 0;
+ printf(".");
+ }
+ return len;
+}
+
+/*
+ * Function: spi_read
+ */
+ssize_t spi_read(uchar * addr, int alen, uchar * buffer, int len)
+{
+ unsigned long offset;
+ offset = addr[0] << 16 | addr[1] << 8 | addr[2];
+ ReadData(offset, len, (int *)buffer);
+ return len;
+}
+
+void SendSingleCommand(const int iCommand)
+{
+ unsigned short dummy;
+
+ /* turns on the SPI in single write mode */
+ SetupSPI((COMMON_SPI_SETTINGS | TIMOD01));
+
+ /* sends the actual command to the SPI TX register */
+ *pSPI_TDBR = iCommand;
+ sync();
+
+ /* The SPI status register will be polled to check the SPIF bit */
+ Wait_For_SPIF();
+
+ dummy = *pSPI_RDBR;
+
+ /* The SPI will be turned off */
+ SPI_OFF();
+
+}
+
+void SetupSPI(const int spi_setting)
+{
+
+ if (icache_status() || dcache_status())
+ udelay(CONFIG_CCLK_HZ / 50000000);
+ /*sets up the PF10 to be the slave select of the SPI */
+ *pPORTF_FER |= (PF10 | PF11 | PF12 | PF13);
+ *pSPI_FLG = 0xFF02;
+ *pSPI_BAUD = CONFIG_SPI_BAUD;
+ *pSPI_CTL = spi_setting;
+ sync();
+
+ *pSPI_FLG = 0xFD02;
+ sync();
+}
+
+void SPI_OFF(void)
+{
+
+ *pSPI_CTL = 0x0400; /* disable SPI */
+ *pSPI_FLG = 0;
+ *pSPI_BAUD = 0;
+ sync();
+ udelay(CONFIG_CCLK_HZ / 50000000);
+
+}
+
+void Wait_For_SPIF(void)
+{
+ unsigned short dummyread;
+ while ((*pSPI_STAT & TXS)) ;
+ while (!(*pSPI_STAT & SPIF)) ;
+ while (!(*pSPI_STAT & RXS)) ;
+ /* Read dummy to empty the receive register */
+ dummyread = *pSPI_RDBR;
+}
+
+ERROR_CODE Wait_For_WEL(void)
+{
+ int i;
+ char status_register = 0;
+ ERROR_CODE ErrorCode = NO_ERR;
+
+ for (i = 0; i < TIMEOUT; i++) {
+ status_register = ReadStatusRegister();
+ if ((status_register & WEL)) {
+ ErrorCode = NO_ERR;
+ break;
+ }
+ ErrorCode = POLL_TIMEOUT; /* Time out error */
+ };
+
+ return ErrorCode;
+}
+
+ERROR_CODE Wait_For_Status(char Statusbit)
+{
+ int i;
+ char status_register = 0xFF;
+ ERROR_CODE ErrorCode = NO_ERR;
+
+ for (i = 0; i < TIMEOUT; i++) {
+ status_register = ReadStatusRegister();
+ if (!(status_register & Statusbit)) {
+ ErrorCode = NO_ERR;
+ break;
+ }
+ ErrorCode = POLL_TIMEOUT; /* Time out error */
+ };
+
+ return ErrorCode;
+}
+
+char ReadStatusRegister(void)
+{
+ char status_register = 0;
+
+ SetupSPI((COMMON_SPI_SETTINGS | TIMOD01)); /* Turn on the SPI */
+
+ *pSPI_TDBR = SPI_RDSR; /* send instruction to read status register */
+ sync();
+ Wait_For_SPIF(); /*wait until the instruction has been sent */
+ *pSPI_TDBR = 0; /*send dummy to receive the status register */
+ sync();
+ Wait_For_SPIF(); /*wait until the data has been sent */
+ status_register = *pSPI_RDBR; /*read the status register */
+
+ SPI_OFF(); /* Turn off the SPI */
+
+ return status_register;
+}
+
+ERROR_CODE GetSectorNumber(unsigned long ulOffset, int *pnSector)
+{
+ int nSector = 0;
+ ERROR_CODE ErrorCode = NO_ERR;
+
+ if (ulOffset > (NUM_SECTORS * 0x10000 - 1)) {
+ ErrorCode = INVALID_SECTOR;
+ return ErrorCode;
+ }
+
+ nSector = (int)ulOffset / 0x10000;
+ *pnSector = nSector;
+
+ return ErrorCode;
+}
+
+ERROR_CODE EraseBlock(int nBlock)
+{
+ unsigned long ulSectorOff = 0x0, ShiftValue;
+ ERROR_CODE ErrorCode = NO_ERR;
+
+ /* if the block is invalid just return */
+ if ((nBlock < 0) || (nBlock > NUM_SECTORS)) {
+ ErrorCode = INVALID_BLOCK;
+ return ErrorCode;
+ }
+ /* figure out the offset of the block in flash */
+ if ((nBlock >= 0) && (nBlock < NUM_SECTORS)) {
+ ulSectorOff = (nBlock * SECTOR_SIZE);
+
+ } else {
+ ErrorCode = INVALID_BLOCK;
+ return ErrorCode;
+ }
+
+ /* A write enable instruction must previously have been executed */
+ SendSingleCommand(SPI_WREN);
+
+ /* The status register will be polled to check the write enable latch "WREN" */
+ ErrorCode = Wait_For_WEL();
+
+ if (POLL_TIMEOUT == ErrorCode) {
+ printf("SPI Erase block error\n");
+ return ErrorCode;
+ } else
+
+ /* Turn on the SPI to send single commands */
+ SetupSPI((COMMON_SPI_SETTINGS | TIMOD01));
+
+ /*
+ * Send the erase block command to the flash followed by the 24 address
+ * to point to the start of a sector
+ */
+ *pSPI_TDBR = SPI_SE;
+ sync();
+ Wait_For_SPIF();
+ /* Send the highest byte of the 24 bit address at first */
+ ShiftValue = (ulSectorOff >> 16);
+ *pSPI_TDBR = ShiftValue;
+ sync();
+ /* Wait until the instruction has been sent */
+ Wait_For_SPIF();
+ /* Send the middle byte of the 24 bit address at second */
+ ShiftValue = (ulSectorOff >> 8);
+ *pSPI_TDBR = ShiftValue;
+ sync();
+ /* Wait until the instruction has been sent */
+ Wait_For_SPIF();
+ /* Send the lowest byte of the 24 bit address finally */
+ *pSPI_TDBR = ulSectorOff;
+ sync();
+ /* Wait until the instruction has been sent */
+ Wait_For_SPIF();
+
+ /* Turns off the SPI */
+ SPI_OFF();
+
+ /* Poll the status register to check the Write in Progress bit */
+ /* Sector erase takes time */
+ ErrorCode = Wait_For_Status(WIP);
+
+ /* block erase should be complete */
+ return ErrorCode;
+}
+
+/*
+ * ERROR_CODE ReadData()
+ * Read a value from flash for verify purpose
+ * Inputs: unsigned long ulStart - holds the SPI start address
+ * int pnData - pointer to store value read from flash
+ * long lCount - number of elements to read
+ */
+ERROR_CODE ReadData(unsigned long ulStart, long lCount, int *pnData)
+{
+ unsigned long ShiftValue;
+ char *cnData;
+ int i;
+
+ /* Pointer cast to be able to increment byte wise */
+
+ cnData = (char *)pnData;
+ /* Start SPI interface */
+ SetupSPI((COMMON_SPI_SETTINGS | TIMOD01));
+
+#ifdef CONFIG_SPI_FLASH_FAST_READ
+ /* Send the read command to SPI device */
+ *pSPI_TDBR = SPI_FAST_READ;
+#else
+ /* Send the read command to SPI device */
+ *pSPI_TDBR = SPI_READ;
+#endif
+ sync();
+ /* Wait until the instruction has been sent */
+ Wait_For_SPIF();
+ /* Send the highest byte of the 24 bit address at first */
+ ShiftValue = (ulStart >> 16);
+ /* Send the byte to the SPI device */
+ *pSPI_TDBR = ShiftValue;
+ sync();
+ /* Wait until the instruction has been sent */
+ Wait_For_SPIF();
+ /* Send the middle byte of the 24 bit address at second */
+ ShiftValue = (ulStart >> 8);
+ /* Send the byte to the SPI device */
+ *pSPI_TDBR = ShiftValue;
+ sync();
+ /* Wait until the instruction has been sent */
+ Wait_For_SPIF();
+ /* Send the lowest byte of the 24 bit address finally */
+ *pSPI_TDBR = ulStart;
+ sync();
+ /* Wait until the instruction has been sent */
+ Wait_For_SPIF();
+
+#ifdef CONFIG_SPI_FLASH_FAST_READ
+ /* Send dummy for FAST_READ */
+ *pSPI_TDBR = 0;
+ sync();
+ /* Wait until the instruction has been sent */
+ Wait_For_SPIF();
+#endif
+
+ /* After the SPI device address has been placed on the MOSI pin the data can be */
+ /* received on the MISO pin. */
+ for (i = 0; i < lCount; i++) {
+ *pSPI_TDBR = 0;
+ sync();
+ while (!(*pSPI_STAT & RXS)) ;
+ *cnData++ = *pSPI_RDBR;
+
+ if ((i >= SECTOR_SIZE) && (i % SECTOR_SIZE == 0))
+ printf(".");
+ }
+
+ /* Turn off the SPI */
+ SPI_OFF();
+
+ return NO_ERR;
+}
+
+ERROR_CODE WriteFlash(unsigned long ulStartAddr, long lTransferCount,
+ int *iDataSource, long *lWriteCount)
+{
+
+ unsigned long ulWAddr;
+ long lWTransferCount = 0;
+ int i;
+ char iData;
+ char *temp = (char *)iDataSource;
+ ERROR_CODE ErrorCode = NO_ERR;
+
+ /* First, a Write Enable Command must be sent to the SPI. */
+ SendSingleCommand(SPI_WREN);
+
+ /*
+ * Second, the SPI Status Register will be tested whether the
+ * Write Enable Bit has been set
+ */
+ ErrorCode = Wait_For_WEL();
+ if (POLL_TIMEOUT == ErrorCode) {
+ printf("SPI Write Time Out\n");
+ return ErrorCode;
+ } else
+ /* Third, the 24 bit address will be shifted out
+ * the SPI MOSI bytewise.
+ * Turns the SPI on
+ */
+ SetupSPI((COMMON_SPI_SETTINGS | TIMOD01));
+ *pSPI_TDBR = SPI_PP;
+ sync();
+ /*wait until the instruction has been sent */
+ Wait_For_SPIF();
+ ulWAddr = (ulStartAddr >> 16);
+ *pSPI_TDBR = ulWAddr;
+ sync();
+ /*wait until the instruction has been sent */
+ Wait_For_SPIF();
+ ulWAddr = (ulStartAddr >> 8);
+ *pSPI_TDBR = ulWAddr;
+ sync();
+ /*wait until the instruction has been sent */
+ Wait_For_SPIF();
+ ulWAddr = ulStartAddr;
+ *pSPI_TDBR = ulWAddr;
+ sync();
+ /*wait until the instruction has been sent */
+ Wait_For_SPIF();
+ /*
+ * Fourth, maximum number of 256 bytes will be taken from the Buffer
+ * and sent to the SPI device.
+ */
+ for (i = 0; (i < lTransferCount) && (i < 256); i++, lWTransferCount++) {
+ iData = *temp;
+ *pSPI_TDBR = iData;
+ sync();
+ /*wait until the instruction has been sent */
+ Wait_For_SPIF();
+ temp++;
+ }
+
+ /* Turns the SPI off */
+ SPI_OFF();
+
+ /*
+ * Sixth, the SPI Write in Progress Bit must be toggled to ensure the
+ * programming is done before start of next transfer
+ */
+ ErrorCode = Wait_For_Status(WIP);
+
+ if (POLL_TIMEOUT == ErrorCode) {
+ printf("SPI Program Time out!\n");
+ return ErrorCode;
+ } else
+
+ *lWriteCount = lWTransferCount;
+
+ return ErrorCode;
+}
+
+ERROR_CODE WriteData(unsigned long ulStart, long lCount, int *pnData)
+{
+
+ unsigned long ulWStart = ulStart;
+ long lWCount = lCount, lWriteCount;
+ long *pnWriteCount = &lWriteCount;
+
+ ERROR_CODE ErrorCode = NO_ERR;
+
+ while (lWCount != 0) {
+ ErrorCode = WriteFlash(ulWStart, lWCount, pnData, pnWriteCount);
+
+ /*
+ * After each function call of WriteFlash the counter
+ * must be adjusted
+ */
+ lWCount -= *pnWriteCount;
+
+ /* Also, both address pointers must be recalculated. */
+ ulWStart += *pnWriteCount;
+ pnData += *pnWriteCount / 4;
+ }
+
+ /* return the appropriate error code */
+ return ErrorCode;
+}
+
+#endif /* CONFIG_SPI */
diff --git a/board/bf537-stamp/u-boot.lds.S b/board/bf537-stamp/u-boot.lds.S
new file mode 100644
index 00000000000..3fb2d0cc60b
--- /dev/null
+++ b/board/bf537-stamp/u-boot.lds.S
@@ -0,0 +1,190 @@
+/*
+ * U-boot - u-boot.lds.S
+ *
+ * Copyright (c) 2005-2007 Analog Device Inc.
+ *
+ * (C) Copyright 2000-2004
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <config.h>
+
+OUTPUT_ARCH(bfin)
+SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib);
+/* Do we need any of these for elf?
+ __DYNAMIC = 0; */
+MEMORY
+ {
+ ram : ORIGIN = (CFG_MONITOR_BASE), LENGTH = (256 * 1024)
+ l1_code : ORIGIN = 0xFFA00000, LENGTH = 0xC000
+ l1_data : ORIGIN = 0xFF900000, LENGTH = 0x4000
+ }
+
+SECTIONS
+{
+ /* Read-only sections, merged into text segment: */
+ . = + SIZEOF_HEADERS; /*0x1000;*/
+ .interp : { *(.interp) }
+ .hash : { *(.hash) }
+ .dynsym : { *(.dynsym) }
+ .dynstr : { *(.dynstr) }
+ .rel.text : { *(.rel.text) }
+ .rela.text : { *(.rela.text) }
+ .rel.data : { *(.rel.data) }
+ .rela.data : { *(.rela.data) }
+ .rel.rodata : { *(.rel.rodata) }
+ .rela.rodata : { *(.rela.rodata) }
+ .rel.got : { *(.rel.got) }
+ .rela.got : { *(.rela.got) }
+ .rel.ctors : { *(.rel.ctors) }
+ .rela.ctors : { *(.rela.ctors) }
+ .rel.dtors : { *(.rel.dtors) }
+ .rela.dtors : { *(.rela.dtors) }
+ .rel.bss : { *(.rel.bss) }
+ .rela.bss : { *(.rela.bss) }
+ .rel.plt : { *(.rel.plt) }
+ .rela.plt : { *(.rela.plt) }
+ .init : { *(.init) }
+ .plt : { *(.plt) }
+ . = CFG_MONITOR_BASE;
+ .text :
+ {
+ /* WARNING - the following is hand-optimized to fit within */
+ /* the sector before the environment sector. If it throws */
+ /* an error during compilation remove an object here to get */
+ /* it linked after the configuration sector. */
+
+ cpu/bf537/start.o (.text)
+ cpu/bf537/start1.o (.text)
+ cpu/bf537/traps.o (.text)
+ cpu/bf537/interrupt.o (.text)
+ cpu/bf537/serial.o (.text)
+ common/dlmalloc.o (.text)
+/* lib_blackfin/bf533_string.o (.text) */
+/* lib_generic/vsprintf.o (.text) */
+ lib_generic/crc32.o (.text)
+/* lib_generic/zlib.o (.text) */
+/* board/bf537-stamp/bf537-stamp.o (.text) */
+
+ . = DEFINED(env_offset) ? env_offset : .;
+ common/environment.o (.text)
+
+ *(EXCLUDE_FILE (board/bf537-stamp/post-memory.o) .text)
+ *(.fixup)
+ *(.got1)
+ } > ram
+ _etext = .;
+ PROVIDE (etext = .);
+ .text_l1 :
+ {
+ . = ALIGN(4) ;
+ _text_l1 = .;
+ PROVIDE (text_l1 = .);
+ board/bf537-stamp/post-memory.o (.text)
+ . = ALIGN(4) ;
+ _etext_l1 = .;
+ PROVIDE (etext_l1 = .);
+ } > l1_code AT > ram
+
+ .rodata :
+ {
+ . = ALIGN(4);
+ *(EXCLUDE_FILE (board/bf537-stamp/post-memory.o) .rodata)
+ *(EXCLUDE_FILE (board/bf537-stamp/post-memory.o) .rodata1)
+ *(EXCLUDE_FILE (board/bf537-stamp/post-memory.o) .rodata.str1.4)
+ *(.eh_frame)
+ . = ALIGN(4);
+ } > ram
+
+ . = ALIGN(4);
+ _erodata = .;
+ PROVIDE (erodata = .);
+ .rodata_l1 :
+ {
+ . = ALIGN(4) ;
+ _rodata_l1 = .;
+ PROVIDE (rodata_l1 = .);
+ board/bf537-stamp/post-memory.o (.rodata)
+ board/bf537-stamp/post-memory.o (.rodata1)
+ board/bf537-stamp/post-memory.o (.rodata.str1.4)
+ . = ALIGN(4) ;
+ _erodata_l1 = .;
+ PROVIDE(erodata_l1 = .);
+ } > l1_data AT > ram
+
+ .fini : { *(.fini) } =0
+ .ctors : { *(.ctors) }
+ .dtors : { *(.dtors) }
+
+ /* Read-write section, merged into data segment: */
+ . = (. + 0x00FF) & 0xFFFFFF00;
+ _erotext = .;
+ PROVIDE (erotext = .);
+ .reloc :
+ {
+ *(.got)
+ _GOT2_TABLE_ = .;
+ *(.got2)
+ _FIXUP_TABLE_ = .;
+ *(.fixup)
+ }
+ __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2;
+ __fixup_entries = (. - _FIXUP_TABLE_)>>2;
+
+ .data :
+ {
+ *(.data)
+ *(.data1)
+ *(.sdata)
+ *(.sdata2)
+ *(.dynamic)
+ CONSTRUCTORS
+ } > ram
+ _edata = .;
+ PROVIDE (edata = .);
+
+ ___u_boot_cmd_start = .;
+ .u_boot_cmd : { *(.u_boot_cmd) } > ram
+ ___u_boot_cmd_end = .;
+
+
+ __start___ex_table = .;
+ __ex_table : { *(__ex_table) }
+ __stop___ex_table = .;
+
+ . = ALIGN(256);
+ __init_begin = .;
+ .text.init : { *(.text.init) }
+ .data.init : { *(.data.init) }
+ . = ALIGN(256);
+ __init_end = .;
+
+ .bss :
+ {
+ __bss_start = .;
+ *(.sbss) *(.scommon)
+ *(.dynbss)
+ *(.bss)
+ *(COMMON)
+ } > ram
+ _end = . ;
+ PROVIDE (end = .);
+}
diff --git a/board/bf561-ezkit/Makefile b/board/bf561-ezkit/Makefile
new file mode 100644
index 00000000000..a3c2e5bae70
--- /dev/null
+++ b/board/bf561-ezkit/Makefile
@@ -0,0 +1,58 @@
+#
+# U-boot - Makefile
+#
+# Copyright (c) 2005-2007 Analog Device Inc.
+#
+# (C) Copyright 2000-2006
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+include $(TOPDIR)/config.mk
+
+LIB = $(obj)lib$(BOARD).a
+
+COBJS := $(BOARD).o
+
+SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(COBJS))
+SOBJS := $(addprefix $(obj),$(SOBJS))
+
+$(LIB): $(obj).depend $(OBJS) $(SOBJS) u-boot.lds
+ $(AR) $(ARFLAGS) $@ $(OBJS) $(SOBJS)
+
+u-boot.lds: u-boot.lds.S
+ $(CPP) $(CPPFLAGS) -P -Ubfin $^ > $@.tmp
+ mv -f $@.tmp $@
+
+clean:
+ rm -f $(SOBJS) $(OBJS)
+
+distclean: clean
+ rm -f $(LIB) core *.bak .depend
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/board/bf561-ezkit/bf561-ezkit.c b/board/bf561-ezkit/bf561-ezkit.c
new file mode 100644
index 00000000000..71281c0139c
--- /dev/null
+++ b/board/bf561-ezkit/bf561-ezkit.c
@@ -0,0 +1,73 @@
+/*
+ * U-boot - ezkit561.c
+ *
+ * Copyright (c) 2005 Bas Vermeulen <bas@buyways.nl>
+ * Copyright (c) 2005 blackfin.uclinux.org
+ *
+ * (C) Copyright 2000-2004
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <asm/io.h>
+
+int checkboard(void)
+{
+ printf("CPU: ADSP BF561\n");
+ printf("Board: ADI BF561 EZ-Kit Lite board\n");
+ printf(" Support: http://blackfin.uclinux.org/\n");
+ return 0;
+}
+
+long int initdram(int board_type)
+{
+ DECLARE_GLOBAL_DATA_PTR;
+#ifdef DEBUG
+ int brate;
+ char *tmp = getenv("baudrate");
+ brate = simple_strtoul(tmp, NULL, 16);
+ printf("Serial Port initialized with Baud rate = %x\n", brate);
+ printf("SDRAM attributes:\n");
+ printf("tRCD %d SCLK Cycles,tRP %d SCLK Cycles,tRAS %d SCLK Cycles"
+ "tWR %d SCLK Cycles,CAS Latency %d SCLK cycles \n",
+ 3, 3, 6, 2, 3);
+ printf("SDRAM Begin: 0x%x\n", CFG_SDRAM_BASE);
+ printf("Bank size = %d MB\n", CFG_MAX_RAM_SIZE >> 20);
+#endif
+ gd->bd->bi_memstart = CFG_SDRAM_BASE;
+ gd->bd->bi_memsize = CFG_MAX_RAM_SIZE;
+ return CFG_MAX_RAM_SIZE;
+}
+
+#if defined(CONFIG_MISC_INIT_R)
+/* miscellaneous platform dependent initialisations */
+int misc_init_r(void)
+{
+ /* Keep PF12 low to be able to drive the USB-LAN Extender */
+ *pFIO0_DIR = 0x0000;
+ *pFIO0_FLAG_C = 0x1000; /* Clear PF12 */
+ sync();
+ *pFIO0_POLAR = 0x0000;
+ sync();
+
+ return 0;
+}
+#endif
diff --git a/board/bf561-ezkit/config.mk b/board/bf561-ezkit/config.mk
new file mode 100644
index 00000000000..a623c3df0c6
--- /dev/null
+++ b/board/bf561-ezkit/config.mk
@@ -0,0 +1,25 @@
+#
+# (C) Copyright 2001
+# 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
+#
+# TEXT_BASE should be defined as the MAX_SDRAM Address - 256k bytes
+# 256k is defined as CFG_MONITOR_LEN in ./include/configs/<board>.h
+TEXT_BASE = 0x03FC0000
diff --git a/board/bf561-ezkit/u-boot.lds.S b/board/bf561-ezkit/u-boot.lds.S
new file mode 100644
index 00000000000..84df5fc8052
--- /dev/null
+++ b/board/bf561-ezkit/u-boot.lds.S
@@ -0,0 +1,153 @@
+/*
+ * U-boot - u-boot.lds.S
+ *
+ * Copyright (c) 2005-2007 Analog Device Inc.
+ *
+ * (C) Copyright 2000-2004
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <config.h>
+
+OUTPUT_ARCH(bfin)
+OUTPUT_ARCH(bfin)
+SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib);
+/* Do we need any of these for elf?
+ __DYNAMIC = 0; */
+SECTIONS
+{
+ /* Read-only sections, merged into text segment: */
+ . = + SIZEOF_HEADERS;
+ .interp : { *(.interp) }
+ .hash : { *(.hash) }
+ .dynsym : { *(.dynsym) }
+ .dynstr : { *(.dynstr) }
+ .rel.text : { *(.rel.text) }
+ .rela.text : { *(.rela.text) }
+ .rel.data : { *(.rel.data) }
+ .rela.data : { *(.rela.data) }
+ .rel.rodata : { *(.rel.rodata) }
+ .rela.rodata : { *(.rela.rodata) }
+ .rel.got : { *(.rel.got) }
+ .rela.got : { *(.rela.got) }
+ .rel.ctors : { *(.rel.ctors) }
+ .rela.ctors : { *(.rela.ctors) }
+ .rel.dtors : { *(.rel.dtors) }
+ .rela.dtors : { *(.rela.dtors) }
+ .rel.bss : { *(.rel.bss) }
+ .rela.bss : { *(.rela.bss) }
+ .rel.plt : { *(.rel.plt) }
+ .rela.plt : { *(.rela.plt) }
+ .init : { *(.init) }
+ .plt : { *(.plt) }
+ . = CFG_MONITOR_BASE;
+ .text :
+ {
+ /* WARNING - the following is hand-optimized to fit within */
+ /* the sector before the environment sector. If it throws */
+ /* an error during compilation remove an object here to get */
+ /* it linked after the configuration sector. */
+
+ cpu/bf561/start.o (.text)
+ cpu/bf561/start1.o (.text)
+ cpu/bf561/traps.o (.text)
+ cpu/bf561/interrupt.o (.text)
+ cpu/bf561/serial.o (.text)
+ common/dlmalloc.o (.text)
+/* lib_blackfin/bf533_string.o (.text) */
+/* lib_generic/vsprintf.o (.text) */
+ lib_generic/crc32.o (.text)
+ lib_generic/zlib.o (.text)
+ board/bf561-ezkit/bf561-ezkit.o (.text)
+
+ . = DEFINED(env_offset) ? env_offset : .;
+ common/environment.o (.text)
+
+ *(.text)
+ *(.fixup)
+ *(.got1)
+ }
+ _etext = .;
+ PROVIDE (etext = .);
+ .rodata :
+ {
+ *(.rodata)
+ *(.rodata1)
+ *(.rodata.str1.4)
+ }
+ .fini : { *(.fini) } =0
+ .ctors : { *(.ctors) }
+ .dtors : { *(.dtors) }
+
+ /* Read-write section, merged into data segment: */
+ . = (. + 0x00FF) & 0xFFFFFF00;
+ _erotext = .;
+ PROVIDE (erotext = .);
+ .reloc :
+ {
+ *(.got)
+ _GOT2_TABLE_ = .;
+ *(.got2)
+ _FIXUP_TABLE_ = .;
+ *(.fixup)
+ }
+ __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2;
+ __fixup_entries = (. - _FIXUP_TABLE_)>>2;
+
+ .data :
+ {
+ *(.data)
+ *(.data1)
+ *(.sdata)
+ *(.sdata2)
+ *(.dynamic)
+ CONSTRUCTORS
+ }
+ _edata = .;
+ PROVIDE (edata = .);
+
+ ___u_boot_cmd_start = .;
+ .u_boot_cmd : { *(.u_boot_cmd) }
+ ___u_boot_cmd_end = .;
+
+
+ __start___ex_table = .;
+ __ex_table : { *(__ex_table) }
+ __stop___ex_table = .;
+
+ . = ALIGN(256);
+ __init_begin = .;
+ .text.init : { *(.text.init) }
+ .data.init : { *(.data.init) }
+ . = ALIGN(256);
+ __init_end = .;
+
+ __bss_start = .;
+ .bss :
+ {
+ *(.sbss) *(.scommon)
+ *(.dynbss)
+ *(.bss)
+ *(COMMON)
+ }
+ _end = . ;
+ PROVIDE (end = .);
+}
diff --git a/board/cray/L1/L1.c b/board/cray/L1/L1.c
index a7114eb074e..a0fac7fe5ab 100644
--- a/board/cray/L1/L1.c
+++ b/board/cray/L1/L1.c
@@ -23,7 +23,7 @@
#include <common.h>
#include <asm/processor.h>
-#include <405gp_i2c.h>
+#include <4xx_i2c.h>
#include <command.h>
#include <rtc.h>
#include <post.h>
diff --git a/board/dave/PPChameleonEVB/nand.c b/board/dave/PPChameleonEVB/nand.c
index 40a827c3e2c..f5c3dd9edc7 100644
--- a/board/dave/PPChameleonEVB/nand.c
+++ b/board/dave/PPChameleonEVB/nand.c
@@ -105,7 +105,7 @@ static int ppchameleonevb_device_ready(struct mtd_info *mtdinfo)
* Members with a "?" were not set in the merged testing-NAND branch,
* so they are not set here either.
*/
-void board_nand_init(struct nand_chip *nand)
+int board_nand_init(struct nand_chip *nand)
{
nand->hwcontrol = ppchameleonevb_hwcontrol;
@@ -113,5 +113,6 @@ void board_nand_init(struct nand_chip *nand)
nand->eccmode = NAND_ECC_SOFT;
nand->chip_delay = NAND_BIG_DELAY_US;
nand->options = NAND_SAMSUNG_LP_OPTIONS;
+ return 0;
}
#endif /* (CONFIG_COMMANDS & CFG_CMD_NAND) */
diff --git a/board/delta/nand.c b/board/delta/nand.c
index fe648fc1ff8..d170938c020 100644
--- a/board/delta/nand.c
+++ b/board/delta/nand.c
@@ -448,7 +448,7 @@ static void dfc_gpio_init(void)
* Members with a "?" were not set in the merged testing-NAND branch,
* so they are not set here either.
*/
-void board_nand_init(struct nand_chip *nand)
+int board_nand_init(struct nand_chip *nand)
{
unsigned long tCH, tCS, tWH, tWP, tRH, tRP, tRP_high, tR, tWHR, tAR;
@@ -576,6 +576,7 @@ void board_nand_init(struct nand_chip *nand)
nand->cmdfunc = dfc_cmdfunc;
nand->autooob = &delta_oob;
nand->badblock_pattern = &delta_bbt_descr;
+ return 0;
}
#else
diff --git a/board/emk/top5200/top5200.c b/board/emk/top5200/top5200.c
index 12acc57171b..d741e6b5cef 100644
--- a/board/emk/top5200/top5200.c
+++ b/board/emk/top5200/top5200.c
@@ -190,7 +190,7 @@ void init_ide_reset (void)
{
debug ("init_ide_reset\n");
- /* Configure PSC1_4 as GPIO output for ATA reset */
+ /* 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;
}
diff --git a/board/esd/common/auto_update.c b/board/esd/common/auto_update.c
index 5cd342332f5..001fd68da42 100644
--- a/board/esd/common/auto_update.c
+++ b/board/esd/common/auto_update.c
@@ -33,6 +33,7 @@
#include <asm/byteorder.h>
#include <linux/mtd/nand_legacy.h>
#include <fat.h>
+#include <part.h>
#include "auto_update.h"
@@ -71,8 +72,6 @@ extern int transfer_pic(unsigned char, unsigned char *, int, int);
extern int flash_sect_erase(ulong, ulong);
extern int flash_sect_protect (int, ulong, ulong);
extern int flash_write (char *, ulong, ulong);
-/* change char* to void* to shutup the compiler */
-extern block_dev_desc_t *get_dev (char*, int);
#if (CONFIG_COMMANDS & CFG_CMD_NAND) && defined(CFG_NAND_LEGACY)
/* references to names in cmd_nand.c */
diff --git a/board/esd/cpci5200/cpci5200.c b/board/esd/cpci5200/cpci5200.c
index f14331bebc4..a925b84fd9e 100644
--- a/board/esd/cpci5200/cpci5200.c
+++ b/board/esd/cpci5200/cpci5200.c
@@ -191,8 +191,7 @@ static struct pci_controller hose;
extern void pci_mpc5xxx_init(struct pci_controller *);
-void pci_init_board(void
- ) {
+void pci_init_board(void) {
pci_mpc5xxx_init(&hose);
}
#endif
diff --git a/board/esd/cpci750/cpci750.c b/board/esd/cpci750/cpci750.c
index dbed5971738..17e35689410 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"
@@ -365,12 +366,12 @@ int misc_init_r ()
dcache_lock ();
#endif
if (flash_info[3].size < CFG_FLASH_INCREMENT) {
- unsigned int flash_offset;
+ unsigned int flash_offset;
unsigned int l;
flash_offset = CFG_FLASH_INCREMENT - flash_info[3].size;
for (l = 0; l < CFG_MAX_FLASH_SECT; l++) {
- if (flash_info[3].start[l] != 0) {
+ if (flash_info[3].start[l] != 0) {
flash_info[3].start[l] += flash_offset;
}
}
@@ -502,7 +503,7 @@ static void move64 (unsigned long long *src, unsigned long long *dest)
{
asm ("lfd 0, 0(3)\n\t" /* fpr0 = *scr */
"stfd 0, 0(4)" /* *dest = fpr0 */
- : : : "fr0"); /* Clobbers fr0 */
+ : : : "fr0"); /* Clobbers fr0 */
return;
}
@@ -580,9 +581,9 @@ int mem_test_data (void)
move64 (&(pattern[i]), pmem);
move64 (pmem, &temp64);
- /* hi = (temp64>>32) & 0xffffffff; */
- /* lo = temp64 & 0xffffffff; */
- /* printf("\ntemp64 = 0x%08x%08x", hi, lo); */
+ /* hi = (temp64>>32) & 0xffffffff; */
+ /* lo = temp64 & 0xffffffff; */
+ /* printf("\ntemp64 = 0x%08x%08x", hi, lo); */
hi = (pattern[i] >> 32) & 0xffffffff;
lo = pattern[i] & 0xffffffff;
@@ -855,11 +856,11 @@ int testdram (void)
}
#endif /* CFG_DRAM_TEST */
-/* ronen - the below functions are used by the bootm function */
+/* ronen - the below functions are used by the bootm function */
/* - we map the base register to fbe00000 (same mapping as in the LSP) */
/* - we turn off the RX gig dmas - to prevent the dma from overunning */
-/* the kernel data areas. */
-/* - we diable and invalidate the icache and dcache. */
+/* the kernel data areas. */
+/* - we diable and invalidate the icache and dcache. */
void my_remap_gt_regs_bootm (u32 cur_loc, u32 new_loc)
{
u32 temp;
@@ -899,3 +900,22 @@ 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 6bdfc1d1cc0..c094755351c 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/esd/du405/du405.c b/board/esd/du405/du405.c
index a019ce42150..69432138d31 100644
--- a/board/esd/du405/du405.c
+++ b/board/esd/du405/du405.c
@@ -25,7 +25,7 @@
#include "du405.h"
#include <asm/processor.h>
#include <ppc4xx.h>
-#include <405gp_i2c.h>
+#include <4xx_i2c.h>
#include <command.h>
DECLARE_GLOBAL_DATA_PTR;
diff --git a/board/esd/mecp5200/Makefile b/board/esd/mecp5200/Makefile
new file mode 100644
index 00000000000..45efdb0dec4
--- /dev/null
+++ b/board/esd/mecp5200/Makefile
@@ -0,0 +1,51 @@
+
+#
+# (C) Copyright 2003-2006
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+include $(TOPDIR)/config.mk
+
+LIB = $(obj)lib$(BOARD).a
+
+COBJS = $(BOARD).o
+
+SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(COBJS))
+SOBJS := $(addprefix $(obj),$(SOBJS))
+
+$(LIB): $(obj).depend $(OBJS)
+ $(AR) $(ARFLAGS) $@ $(OBJS)
+
+clean:
+ rm -f $(SOBJS) $(OBJS)
+
+distclean: clean
+ rm -f $(LIB) core *.bak .depend
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/board/esd/mecp5200/config.mk b/board/esd/mecp5200/config.mk
new file mode 100644
index 00000000000..07b5de1881c
--- /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 00000000000..c4b91e950bc
--- /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 00000000000..22d0a554442
--- /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/esd/mecp5200/u-boot.lds b/board/esd/mecp5200/u-boot.lds
new file mode 100644
index 00000000000..d999dd16ad9
--- /dev/null
+++ b/board/esd/mecp5200/u-boot.lds
@@ -0,0 +1,122 @@
+/*
+ * (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
+ */
+
+OUTPUT_ARCH(powerpc)
+SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/local/powerpc-any-elf/lib);
+/* Do we need any of these for elf?
+ __DYNAMIC = 0; */
+SECTIONS
+{
+ /* Read-only sections, merged into text segment: */
+ . = + SIZEOF_HEADERS;
+ .interp : { *(.interp) }
+ .hash : { *(.hash) }
+ .dynsym : { *(.dynsym) }
+ .dynstr : { *(.dynstr) }
+ .rel.text : { *(.rel.text) }
+ .rela.text : { *(.rela.text) }
+ .rel.data : { *(.rel.data) }
+ .rela.data : { *(.rela.data) }
+ .rel.rodata : { *(.rel.rodata) }
+ .rela.rodata : { *(.rela.rodata) }
+ .rel.got : { *(.rel.got) }
+ .rela.got : { *(.rela.got) }
+ .rel.ctors : { *(.rel.ctors) }
+ .rela.ctors : { *(.rela.ctors) }
+ .rel.dtors : { *(.rel.dtors) }
+ .rela.dtors : { *(.rela.dtors) }
+ .rel.bss : { *(.rel.bss) }
+ .rela.bss : { *(.rela.bss) }
+ .rel.plt : { *(.rel.plt) }
+ .rela.plt : { *(.rela.plt) }
+ .init : { *(.init) }
+ .plt : { *(.plt) }
+ .text :
+ {
+ cpu/mpc5xxx/start.o (.text)
+ *(.text)
+ *(.fixup)
+ *(.got1)
+ . = ALIGN(16);
+ *(.rodata)
+ *(.rodata1)
+ *(.rodata.str1.4)
+ }
+ .fini : { *(.fini) } =0
+ .ctors : { *(.ctors) }
+ .dtors : { *(.dtors) }
+
+ /* Read-write section, merged into data segment: */
+ . = (. + 0x0FFF) & 0xFFFFF000;
+ _erotext = .;
+ PROVIDE (erotext = .);
+ .reloc :
+ {
+ *(.got)
+ _GOT2_TABLE_ = .;
+ *(.got2)
+ _FIXUP_TABLE_ = .;
+ *(.fixup)
+ }
+ __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >> 2;
+ __fixup_entries = (. - _FIXUP_TABLE_) >> 2;
+
+ .data :
+ {
+ *(.data)
+ *(.data1)
+ *(.sdata)
+ *(.sdata2)
+ *(.dynamic)
+ CONSTRUCTORS
+ }
+ _edata = .;
+ PROVIDE (edata = .);
+
+ __u_boot_cmd_start = .;
+ .u_boot_cmd : { *(.u_boot_cmd) }
+ __u_boot_cmd_end = .;
+
+
+ __start___ex_table = .;
+ __ex_table : { *(__ex_table) }
+ __stop___ex_table = .;
+
+ . = ALIGN(4096);
+ __init_begin = .;
+ .text.init : { *(.text.init) }
+ .data.init : { *(.data.init) }
+ . = ALIGN(4096);
+ __init_end = .;
+
+ __bss_start = .;
+ .bss :
+ {
+ *(.sbss) *(.scommon)
+ *(.dynbss)
+ *(.bss)
+ *(COMMON)
+ }
+ _end = . ;
+ PROVIDE (end = .);
+}
diff --git a/board/esd/pf5200/pf5200.c b/board/esd/pf5200/pf5200.c
index 1f30d454fff..77e164bd18d 100644
--- a/board/esd/pf5200/pf5200.c
+++ b/board/esd/pf5200/pf5200.c
@@ -191,8 +191,7 @@ static struct pci_controller hose;
extern void pci_mpc5xxx_init(struct pci_controller *);
-void pci_init_board(void
- ) {
+void pci_init_board(void) {
pci_mpc5xxx_init(&hose);
}
#endif
diff --git a/board/esd/plu405/plu405.c b/board/esd/plu405/plu405.c
index 37b92fb65a8..59171f8f4c5 100644
--- a/board/esd/plu405/plu405.c
+++ b/board/esd/plu405/plu405.c
@@ -215,12 +215,6 @@ int checkboard (void)
}
putc ('\n');
-
- /*
- * Disable sleep mode in LXT971
- */
- lxt971_no_sleep();
-
return 0;
}
@@ -292,3 +286,14 @@ void board_auto_update_show(int au_active)
}
}
#endif
+
+void reset_phy(void)
+{
+#ifdef CONFIG_LXT971_NO_SLEEP
+
+ /*
+ * Disable sleep mode in LXT971
+ */
+ lxt971_no_sleep();
+#endif
+}
diff --git a/board/hmi1001/hmi1001.c b/board/hmi1001/hmi1001.c
index 237e8631657..9fa0e747b92 100644
--- a/board/hmi1001/hmi1001.c
+++ b/board/hmi1001/hmi1001.c
@@ -103,9 +103,9 @@ long int initdram (int board_type)
/* find RAM size using SDRAM CS0 only */
sdram_start(0);
- test1 = get_ram_size((ulong *)CFG_SDRAM_BASE, 0x20000000);
+ test1 = get_ram_size((long *)CFG_SDRAM_BASE, 0x20000000);
sdram_start(1);
- test2 = get_ram_size((ulong *)CFG_SDRAM_BASE, 0x20000000);
+ test2 = get_ram_size((long *)CFG_SDRAM_BASE, 0x20000000);
if (test1 > test2) {
sdram_start(0);
dramsize = test1;
@@ -179,7 +179,7 @@ struct kbd_data_t* get_keys (struct kbd_data_t *kbd_data)
return kbd_data;
}
-static int compare_magic (const struct kbd_data_t *kbd_data, uchar *str)
+static int compare_magic (const struct kbd_data_t *kbd_data, char *str)
{
char s1 = str[0];
char s2;
@@ -222,11 +222,11 @@ static int compare_magic (const struct kbd_data_t *kbd_data, uchar *str)
return 0;
}
-static uchar *key_match (const struct kbd_data_t *kbd_data)
+static char *key_match (const struct kbd_data_t *kbd_data)
{
- uchar magic[sizeof (kbd_magic_prefix) + 1];
- uchar *suffix;
- uchar *kbd_magic_keys;
+ char magic[sizeof (kbd_magic_prefix) + 1];
+ char *suffix;
+ char *kbd_magic_keys;
/*
* The following string defines the characters that can be appended
@@ -247,7 +247,7 @@ static uchar *key_match (const struct kbd_data_t *kbd_data)
sprintf (magic, "%s%c", kbd_magic_prefix, *suffix);
if (compare_magic(kbd_data, getenv(magic)) == 0) {
- uchar cmd_name[sizeof (kbd_command_prefix) + 1];
+ char cmd_name[sizeof (kbd_command_prefix) + 1];
char *cmd;
sprintf (cmd_name, "%s%c", kbd_command_prefix, *suffix);
@@ -267,7 +267,7 @@ int misc_init_r (void)
#ifdef CONFIG_PREBOOT
struct kbd_data_t kbd_data;
/* Decode keys */
- uchar *str = strdup (key_match (get_keys (&kbd_data)));
+ char *str = strdup (key_match (get_keys (&kbd_data)));
/* Set or delete definition */
setenv ("preboot", str);
free (str);
diff --git a/board/icecube/icecube.c b/board/icecube/icecube.c
index f958b32dbd8..700c9d9323f 100644
--- a/board/icecube/icecube.c
+++ b/board/icecube/icecube.c
@@ -29,6 +29,10 @@
#include <pci.h>
#include <asm/processor.h>
+#if defined(CONFIG_OF_FLAT_TREE)
+#include <ft_build.h>
+#endif
+
#if defined(CONFIG_LITE5200B)
#include "mt46v32m16.h"
#else
@@ -312,7 +316,7 @@ void init_ide_reset (void)
{
debug ("init_ide_reset\n");
- /* Configure PSC1_4 as GPIO output for ATA reset */
+ /* 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;
/* Deassert reset */
@@ -332,3 +336,11 @@ void ide_set_reset (int idereset)
}
}
#endif /* defined (CFG_CMD_IDE) && defined (CONFIG_IDE_RESET) */
+
+#if defined(CONFIG_OF_FLAT_TREE) && defined(CONFIG_OF_BOARD_SETUP)
+void
+ft_board_setup(void *blob, bd_t *bd)
+{
+ ft_cpu_setup(blob, bd);
+}
+#endif
diff --git a/board/ezkit533/Makefile b/board/idmr/Makefile
index 4f3c22321a8..cf07cf40fdb 100644
--- a/board/ezkit533/Makefile
+++ b/board/idmr/Makefile
@@ -1,8 +1,4 @@
#
-# U-boot - Makefile
-#
-# Copyright (c) 2005 blackfin.uclinux.org
-#
# (C) Copyright 2000-2006
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
#
@@ -29,7 +25,7 @@ include $(TOPDIR)/config.mk
LIB = $(obj)lib$(BOARD).a
-COBJS = $(BOARD).o flash.o ezkit533.o
+COBJS = $(BOARD).o flash.o
SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
OBJS := $(addprefix $(obj),$(COBJS))
diff --git a/board/idmr/config.mk b/board/idmr/config.mk
new file mode 100644
index 00000000000..f7c2258a85b
--- /dev/null
+++ b/board/idmr/config.mk
@@ -0,0 +1,25 @@
+#
+# (C) Copyright 2000-2006
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+# Coldfire contribution by Bernhard Kuhn <bkuhn@metrowerks.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
+#
+
+TEXT_BASE = 0xff800000
diff --git a/board/idmr/flash.c b/board/idmr/flash.c
new file mode 100644
index 00000000000..33512b8946d
--- /dev/null
+++ b/board/idmr/flash.c
@@ -0,0 +1,356 @@
+/*
+ * (C) Copyright 2000-2006
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+
+#define PHYS_FLASH_1 CFG_FLASH_BASE
+#define FLASH_BANK_SIZE 0x800000
+#define EN29LV640 0x227e227e
+
+flash_info_t flash_info[CFG_MAX_FLASH_BANKS];
+
+void flash_print_info (flash_info_t * info)
+{
+ int i;
+
+ switch (info->flash_id & FLASH_VENDMASK) {
+ case (AMD_MANUFACT & FLASH_VENDMASK):
+ printf ("AMD: ");
+ break;
+ default:
+ printf ("Unknown Vendor ");
+ break;
+ }
+
+ switch (info->flash_id & FLASH_TYPEMASK) {
+ case (EN29LV640 & FLASH_TYPEMASK):
+ printf ("EN29LV640 (16Mbit)\n");
+ break;
+ default:
+ printf ("Unknown Chip Type\n");
+ goto Done;
+ break;
+ }
+
+ printf (" Size: %ld MB in %d Sectors\n",
+ info->size >> 20, info->sector_count);
+
+ printf (" Sector Start Addresses:");
+ for (i = 0; i < info->sector_count; i++) {
+ if ((i % 5) == 0) {
+ printf ("\n ");
+ }
+ printf (" %08lX%s", info->start[i],
+ info->protect[i] ? " (RO)" : " ");
+ }
+ printf ("\n");
+
+ Done:
+ return;
+}
+
+
+unsigned long flash_init (void)
+{
+ int i, j;
+ ulong size = 0;
+
+ for (i = 0; i < CFG_MAX_FLASH_BANKS; i++) {
+ ulong flashbase = 0;
+
+ flash_info[i].flash_id =
+ (AMD_MANUFACT & FLASH_VENDMASK) |
+ (EN29LV640 & FLASH_TYPEMASK);
+ flash_info[i].size = FLASH_BANK_SIZE;
+ flash_info[i].sector_count = CFG_MAX_FLASH_SECT;
+ memset (flash_info[i].protect, 0, CFG_MAX_FLASH_SECT);
+ if (i == 0)
+ flashbase = PHYS_FLASH_1;
+ else
+ panic ("configured to many flash banks!\n");
+
+ for (j = 0; j < flash_info[i].sector_count; j++) {
+ flash_info[i].start[j] = flashbase + 0x10000 * j;
+ }
+ size += flash_info[i].size;
+ }
+
+ flash_protect (FLAG_PROTECT_SET,
+ CFG_FLASH_BASE,
+ CFG_FLASH_BASE + 0x2ffff, &flash_info[0]);
+
+ return size;
+}
+
+
+#define CMD_READ_ARRAY 0x00F0
+#define CMD_UNLOCK1 0x00AA
+#define CMD_UNLOCK2 0x0055
+#define CMD_ERASE_SETUP 0x0080
+#define CMD_ERASE_CONFIRM 0x0030
+#define CMD_PROGRAM 0x00A0
+#define CMD_UNLOCK_BYPASS 0x0020
+
+#define MEM_FLASH_ADDR1 (*(volatile u16 *)(CFG_FLASH_BASE + (0x00000555<<1)))
+#define MEM_FLASH_ADDR2 (*(volatile u16 *)(CFG_FLASH_BASE + (0x000002AA<<1)))
+
+#define BIT_ERASE_DONE 0x0080
+#define BIT_RDY_MASK 0x0080
+#define BIT_PROGRAM_ERROR 0x0020
+#define BIT_TIMEOUT 0x80000000 /* our flag */
+
+#define READY 1
+#define ERR 2
+#define TMO 4
+
+
+int flash_erase (flash_info_t * info, int s_first, int s_last)
+{
+ ulong result;
+ int iflag, prot, sect;
+ int rc = ERR_OK;
+ int chip1;
+
+ /* first look for protection bits */
+
+ if (info->flash_id == FLASH_UNKNOWN)
+ return ERR_UNKNOWN_FLASH_TYPE;
+
+ if ((s_first < 0) || (s_first > s_last)) {
+ return ERR_INVAL;
+ }
+
+ if ((info->flash_id & FLASH_VENDMASK) !=
+ (AMD_MANUFACT & FLASH_VENDMASK)) {
+ return ERR_UNKNOWN_FLASH_VENDOR;
+ }
+
+ prot = 0;
+ for (sect = s_first; sect <= s_last; ++sect) {
+ if (info->protect[sect]) {
+ prot++;
+ }
+ }
+ if (prot)
+ return ERR_PROTECTED;
+
+ /*
+ * Disable interrupts which might cause a timeout
+ * here. Remember that our exception vectors are
+ * at address 0 in the flash, and we don't want a
+ * (ticker) exception to happen while the flash
+ * chip is in programming mode.
+ */
+ iflag = disable_interrupts ();
+
+ printf ("\n");
+
+ /* Start erase on unprotected sectors */
+ for (sect = s_first; sect <= s_last && !ctrlc (); sect++) {
+ printf ("Erasing sector %2d ... ", sect);
+
+ /* arm simple, non interrupt dependent timer */
+ set_timer (0);
+
+ if (info->protect[sect] == 0) { /* not protected */
+ volatile u16 *addr =
+ (volatile u16 *) (info->start[sect]);
+
+ MEM_FLASH_ADDR1 = CMD_UNLOCK1;
+ MEM_FLASH_ADDR2 = CMD_UNLOCK2;
+ MEM_FLASH_ADDR1 = CMD_ERASE_SETUP;
+
+ MEM_FLASH_ADDR1 = CMD_UNLOCK1;
+ MEM_FLASH_ADDR2 = CMD_UNLOCK2;
+ *addr = CMD_ERASE_CONFIRM;
+
+ /* wait until flash is ready */
+ chip1 = 0;
+
+ do {
+ result = *addr;
+
+ /* check timeout */
+ if (get_timer (0) > CFG_FLASH_ERASE_TOUT * CFG_HZ / 1000) {
+ MEM_FLASH_ADDR1 = CMD_READ_ARRAY;
+ chip1 = TMO;
+ break;
+ }
+
+ if (!chip1
+ && (result & 0xFFFF) & BIT_ERASE_DONE)
+ chip1 = READY;
+
+ } while (!chip1);
+
+ MEM_FLASH_ADDR1 = CMD_READ_ARRAY;
+
+ if (chip1 == ERR) {
+ rc = ERR_PROG_ERROR;
+ goto outahere;
+ }
+ if (chip1 == TMO) {
+ rc = ERR_TIMOUT;
+ goto outahere;
+ }
+
+ printf ("ok.\n");
+ } else { /* it was protected */
+
+ printf ("protected!\n");
+ }
+ }
+
+ if (ctrlc ())
+ printf ("User Interrupt!\n");
+
+ outahere:
+ /* allow flash to settle - wait 10 ms */
+ printf("Waiting 10 ms...");
+ udelay (10000);
+
+/* for (i = 0; i < 10 * 1000 * 1000; ++i)
+ asm(" nop");
+*/
+
+ printf("done\n");
+ if (iflag)
+ enable_interrupts ();
+
+
+ return rc;
+}
+
+static int write_word (flash_info_t * info, ulong dest, ulong data)
+{
+ volatile u16 *addr = (volatile u16 *) dest;
+ ulong result;
+ int rc = ERR_OK;
+ int iflag;
+ int chip1;
+
+ /*
+ * Check if Flash is (sufficiently) erased
+ */
+ result = *addr;
+ if ((result & data) != data)
+ return ERR_NOT_ERASED;
+
+
+ /*
+ * Disable interrupts which might cause a timeout
+ * here. Remember that our exception vectors are
+ * at address 0 in the flash, and we don't want a
+ * (ticker) exception to happen while the flash
+ * chip is in programming mode.
+ */
+ iflag = disable_interrupts ();
+
+ MEM_FLASH_ADDR1 = CMD_UNLOCK1;
+ MEM_FLASH_ADDR2 = CMD_UNLOCK2;
+ MEM_FLASH_ADDR1 = CMD_PROGRAM;
+ *addr = data;
+
+ /* arm simple, non interrupt dependent timer */
+ set_timer (0);
+
+ /* wait until flash is ready */
+ chip1 = 0;
+ do {
+ result = *addr;
+
+ /* check timeout */
+ if (get_timer (0) > CFG_FLASH_ERASE_TOUT * CFG_HZ / 1000) {
+ chip1 = ERR | TMO;
+ break;
+ }
+ if (!chip1 && ((result & 0x80) == (data & 0x80)))
+ chip1 = READY;
+
+ } while (!chip1);
+
+ *addr = CMD_READ_ARRAY;
+
+ if (chip1 == ERR || *addr != data)
+ rc = ERR_PROG_ERROR;
+
+ if (iflag)
+ enable_interrupts ();
+
+ return rc;
+}
+
+
+int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt)
+{
+ ulong wp, data;
+ int rc;
+
+ if (addr & 1) {
+ printf ("unaligned destination not supported\n");
+ return ERR_ALIGN;
+ }
+
+#if 0
+ if (cnt & 1) {
+ printf ("odd transfer sizes not supported\n");
+ return ERR_ALIGN;
+ }
+#endif
+
+ wp = addr;
+
+ if (addr & 1) {
+ data = (*((volatile u8 *) addr) << 8) | *((volatile u8 *)
+ src);
+ if ((rc = write_word (info, wp - 1, data)) != 0) {
+ return (rc);
+ }
+ src += 1;
+ wp += 1;
+ cnt -= 1;
+ }
+
+ while (cnt >= 2) {
+ data = *((volatile u16 *) src);
+ if ((rc = write_word (info, wp, data)) != 0) {
+ return (rc);
+ }
+ src += 2;
+ wp += 2;
+ cnt -= 2;
+ }
+
+ if (cnt == 1) {
+ data = (*((volatile u8 *) src) << 8) |
+ *((volatile u8 *) (wp + 1));
+ if ((rc = write_word (info, wp, data)) != 0) {
+ return (rc);
+ }
+ src += 1;
+ wp += 1;
+ cnt -= 1;
+ }
+
+ return ERR_OK;
+}
diff --git a/board/idmr/idmr.c b/board/idmr/idmr.c
new file mode 100644
index 00000000000..58cdba1e136
--- /dev/null
+++ b/board/idmr/idmr.c
@@ -0,0 +1,169 @@
+/*
+ * (C) Copyright 2000-2006
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <asm/m5271.h>
+#include <asm/immap_5271.h>
+
+int checkboard (void) {
+ puts ("Board: iDMR\n");
+ return 0;
+};
+
+long int initdram (int board_type) {
+ int i;
+
+ /*
+ * After reset, CS0 is configured to cover entire address space. We
+ * need to configure it to its proper values, so that writes to
+ * CFG_SDRAM_BASE and vicinity during SDRAM controller setup below do
+ * now fall under CS0 (see 16.3.1 of the MCF5271 Reference Manual).
+ */
+
+ /* Flash chipselect, CS0 */
+ /* ;CSAR0: Flash at 0xFF800000 */
+ mbar_writeShort(0x0080, 0xFF80);
+
+ /* CSCR0: Flash 6 waits, 16bit */
+ mbar_writeShort(0x008A, 0x1980);
+
+ /* CSMR0: Flash 8MB, R/W, valid */
+ mbar_writeLong(0x0084, 0x007F0001);
+
+
+ /*
+ * SDRAM configuration proper
+ */
+
+ /*
+ * Address/Data Pin Assignment Reg.: enable address lines 23-21; do
+ * not enable data pins D[15:0], as we have 16 bit port to SDRAM
+ */
+ mbar_writeByte(MCF_GPIO_PAR_AD,
+ MCF_GPIO_AD_ADDR23 |
+ MCF_GPIO_AD_ADDR22 |
+ MCF_GPIO_AD_ADDR21);
+
+ /* No need to configure BS pins - reset values are OK */
+
+ /* Chip Select Pin Assignment Reg.: set CS[1-7] to GPIO */
+ mbar_writeByte(MCF_GPIO_PAR_CS, 0x00);
+
+ /* SDRAM Control Pin Assignment Reg. */
+ mbar_writeByte(MCF_GPIO_PAR_SDRAM,
+ MCF_GPIO_SDRAM_CSSDCS_00 | /* no matter: PAR_CS=0 */
+ MCF_GPIO_SDRAM_SDWE |
+ MCF_GPIO_SDRAM_SCAS |
+ MCF_GPIO_SDRAM_SRAS |
+ MCF_GPIO_SDRAM_SCKE |
+ MCF_GPIO_SDRAM_SDCS_01);
+
+ /*
+ * Wait 100us. We run the bus at 50Mhz, one cycle is 20ns. So 5
+ * iterations will do, but we do 10 just to be safe.
+ */
+ for (i = 0; i < 10; ++i)
+ asm(" nop");
+
+
+ /* 1. Initialize DRAM Control Register: DCR */
+ mbar_writeShort(MCF_SDRAMC_DCR,
+ MCF_SDRAMC_DCR_RTIM(0x10) | /* 65ns */
+ MCF_SDRAMC_DCR_RC(0x60)); /* 1562 cycles */
+
+
+ /*
+ * 2. Initialize DACR0
+ *
+ * CL: 11 (CL=3: 0x03, 0x02; CL=2: 0x1)
+ * CBM: cmd at A20, bank select bits 21 and up
+ * PS: 16 bit
+ */
+ mbar_writeLong(MCF_SDRAMC_DACR0,
+ MCF_SDRAMC_DACRn_BA(CFG_SDRAM_BASE>>18) |
+ MCF_SDRAMC_DACRn_BA(0x00) |
+ MCF_SDRAMC_DACRn_CASL(0x03) |
+ MCF_SDRAMC_DACRn_CBM(0x03) |
+ MCF_SDRAMC_DACRn_PS(0x03));
+
+ /* Initialize DMR0 */
+ mbar_writeLong(MCF_SDRAMC_DMR0,
+ MCF_SDRAMC_DMRn_BAM_16M |
+ MCF_SDRAMC_DMRn_V);
+
+
+ /* 3. Set IP bit in DACR to initiate PALL command */
+ mbar_writeLong(MCF_SDRAMC_DACR0,
+ mbar_readLong(MCF_SDRAMC_DACR0) |
+ MCF_SDRAMC_DACRn_IP);
+
+ /* Write to this block to initiate precharge */
+ *(volatile u16 *)(CFG_SDRAM_BASE) = 0xa5a5;
+
+ /*
+ * Wait at least 20ns to allow banks to precharge (t_RP = 20ns). We
+ * wait a wee longer, just to be safe.
+ */
+ for (i = 0; i < 5; ++i)
+ asm(" nop");
+
+
+ /* 4. Set RE bit in DACR */
+ mbar_writeLong(MCF_SDRAMC_DACR0,
+ mbar_readLong(MCF_SDRAMC_DACR0) |
+ MCF_SDRAMC_DACRn_RE);
+
+ /*
+ * Wait for at least 8 auto refresh cycles to occur, i.e. at least
+ * 781 bus cycles.
+ */
+ for (i = 0; i < 1000; ++i)
+ asm(" nop");
+
+ /* Finish the configuration by issuing the MRS */
+ mbar_writeLong(MCF_SDRAMC_DACR0,
+ mbar_readLong(MCF_SDRAMC_DACR0) |
+ MCF_SDRAMC_DACRn_MRS);
+
+ /*
+ * Write to the SDRAM Mode Register A0-A11 = 0x400
+ *
+ * Write Burst Mode = Programmed Burst Length
+ * Op Mode = Standard Op
+ * CAS Latency = 3
+ * Burst Type = Sequential
+ * Burst Length = 1
+ */
+ *(volatile u32 *)(CFG_SDRAM_BASE + 0x1800) = 0xa5a5a5a5;
+
+ return CFG_SDRAM_SIZE * 1024 * 1024;
+};
+
+
+int testdram (void) {
+
+ /* TODO: XXX XXX XXX */
+ printf ("DRAM test not implemented!\n");
+
+ return (0);
+}
diff --git a/board/idmr/u-boot.lds b/board/idmr/u-boot.lds
new file mode 100644
index 00000000000..69f31793adf
--- /dev/null
+++ b/board/idmr/u-boot.lds
@@ -0,0 +1,145 @@
+/*
+ * (C) Copyright 2000
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+OUTPUT_ARCH(m68k)
+SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib);
+/* Do we need any of these for elf?
+ __DYNAMIC = 0; */
+GROUP(libgcc.a)
+SECTIONS
+{
+ /* Read-only sections, merged into text segment: */
+ . = + SIZEOF_HEADERS;
+ .interp : { *(.interp) }
+ .hash : { *(.hash) }
+ .dynsym : { *(.dynsym) }
+ .dynstr : { *(.dynstr) }
+ .rel.text : { *(.rel.text) }
+ .rela.text : { *(.rela.text) }
+ .rel.data : { *(.rel.data) }
+ .rela.data : { *(.rela.data) }
+ .rel.rodata : { *(.rel.rodata) }
+ .rela.rodata : { *(.rela.rodata) }
+ .rel.got : { *(.rel.got) }
+ .rela.got : { *(.rela.got) }
+ .rel.ctors : { *(.rel.ctors) }
+ .rela.ctors : { *(.rela.ctors) }
+ .rel.dtors : { *(.rel.dtors) }
+ .rela.dtors : { *(.rela.dtors) }
+ .rel.bss : { *(.rel.bss) }
+ .rela.bss : { *(.rela.bss) }
+ .rel.plt : { *(.rel.plt) }
+ .rela.plt : { *(.rela.plt) }
+ .init : { *(.init) }
+ .plt : { *(.plt) }
+ .text :
+ {
+ /* WARNING - the following is hand-optimized to fit within */
+ /* the sector layout of our flash chips! XXX FIXME XXX */
+
+ cpu/mcf52x2/start.o (.text)
+ lib_m68k/traps.o (.text)
+ cpu/mcf52x2/interrupts.o (.text)
+ common/dlmalloc.o (.text)
+ lib_generic/zlib.o (.text)
+
+ . = DEFINED(env_offset) ? env_offset : .;
+ common/environment.o (.ppcenv)
+
+ *(.text)
+ *(.fixup)
+ *(.got1)
+ }
+ _etext = .;
+ PROVIDE (etext = .);
+ .rodata :
+ {
+ *(.rodata)
+ *(.rodata1)
+ }
+ .fini : { *(.fini) } =0
+ .ctors : { *(.ctors) }
+ .dtors : { *(.dtors) }
+
+ /* Read-write section, merged into data segment: */
+ . = (. + 0x00FF) & 0xFFFFFF00;
+ _erotext = .;
+ PROVIDE (erotext = .);
+
+ .reloc :
+ {
+ __got_start = .;
+ *(.got)
+ __got_end = .;
+ _GOT2_TABLE_ = .;
+ *(.got2)
+ _FIXUP_TABLE_ = .;
+ *(.fixup)
+ }
+ __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2;
+ __fixup_entries = (. - _FIXUP_TABLE_)>>2;
+
+ .data :
+ {
+ *(.data)
+ *(.data1)
+ *(.sdata)
+ *(.sdata2)
+ *(.dynamic)
+ CONSTRUCTORS
+ }
+ _edata = .;
+ PROVIDE (edata = .);
+
+ . = .;
+ __u_boot_cmd_start = .;
+ .u_boot_cmd : { *(.u_boot_cmd) }
+ __u_boot_cmd_end = .;
+
+
+ . = .;
+ __start___ex_table = .;
+ __ex_table : { *(__ex_table) }
+ __stop___ex_table = .;
+
+ . = ALIGN(256);
+ __init_begin = .;
+ .text.init : { *(.text.init) }
+ .data.init : { *(.data.init) }
+ . = ALIGN(256);
+ __init_end = .;
+
+ __bss_start = .;
+ .bss :
+ {
+ _sbss = .;
+ *(.sbss) *(.scommon)
+ *(.dynbss)
+ *(.bss)
+ *(COMMON)
+ . = ALIGN(4);
+ _ebss = .;
+ }
+ _end = . ;
+ PROVIDE (end = .);
+}
diff --git a/board/jupiter/Makefile b/board/jupiter/Makefile
new file mode 100644
index 00000000000..aed3af000f1
--- /dev/null
+++ b/board/jupiter/Makefile
@@ -0,0 +1,51 @@
+
+#
+# (C) Copyright 2003-2006
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+include $(TOPDIR)/config.mk
+
+LIB = $(obj)lib$(BOARD).a
+
+COBJS := $(BOARD).o
+
+SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(COBJS))
+SOBJS := $(addprefix $(obj),$(SOBJS))
+
+$(LIB): $(obj).depend $(OBJS)
+ $(AR) $(ARFLAGS) $@ $(OBJS)
+
+clean:
+ rm -f $(SOBJS) $(OBJS)
+
+distclean: clean
+ rm -f $(LIB) core *.bak .depend
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/board/jupiter/config.mk b/board/jupiter/config.mk
new file mode 100644
index 00000000000..5f4da96da5f
--- /dev/null
+++ b/board/jupiter/config.mk
@@ -0,0 +1,41 @@
+#
+# (C) Copyright 2007
+# Heiko Schocher, DENX Software Engineering, hs@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
+#
+
+#
+# Jupiter board:
+#
+# Valid values for TEXT_BASE are:
+#
+# 0xFFF00000 boot high (standard configuration)
+# 0x00100000 boot from RAM (for testing only)
+#
+
+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
+#PLATFORM_CPPFLAGS += -DTEXT_BASE=$(TEXT_BASE) -DDEBUG -I$(TOPDIR)/board
diff --git a/board/jupiter/jupiter.c b/board/jupiter/jupiter.c
new file mode 100644
index 00000000000..04fda4a69f1
--- /dev/null
+++ b/board/jupiter/jupiter.c
@@ -0,0 +1,317 @@
+/*
+ * (C) Copyright 2007
+ * Heiko Schocher, DENX Software Engineering, hs@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
+ */
+
+#include <common.h>
+#include <mpc5xxx.h>
+#include <pci.h>
+#include <asm/processor.h>
+
+#if defined(CONFIG_OF_FLAT_TREE)
+#include <ft_build.h>
+#endif
+
+
+#define SDRAM_DDR 0
+#if 1
+/* Settings Icecube */
+#define SDRAM_MODE 0x00CD0000
+#define SDRAM_CONTROL 0x504F0000
+#define SDRAM_CONFIG1 0xD2322800
+#define SDRAM_CONFIG2 0x8AD70000
+#else
+/*Settings Jupiter UB 1.0.0 */
+#define SDRAM_MODE 0x008D0000
+#define SDRAM_CONTROL 0xD04F0000
+#define SDRAM_CONFIG1 0xf7277f00
+#define SDRAM_CONFIG2 0x88b70004
+#endif
+
+#ifndef CFG_RAMBOOT
+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");
+
+#if SDRAM_DDR
+ /* 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");
+#endif
+
+ /* 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");
+}
+#endif
+
+/*
+ * 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 dramsize2 = 0;
+ uint svr, pvr;
+
+#ifndef CFG_RAMBOOT
+ 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");
+
+#if SDRAM_DDR
+ /* set tap delay */
+ *(vu_long *)MPC5XXX_CDM_PORCFG = SDRAM_TAPDELAY;
+ __asm__ volatile ("sync");
+#endif
+
+ /* find RAM size using SDRAM CS0 only */
+ sdram_start(0);
+ test1 = get_ram_size((long *)CFG_SDRAM_BASE, 0x80000000);
+ sdram_start(1);
+ test2 = get_ram_size((long *)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;
+ } else {
+ *(vu_long *)MPC5XXX_SDRAM_CS0CFG = 0; /* disabled */
+ }
+
+ /* let SDRAM CS1 start right after CS0 */
+ *(vu_long *)MPC5XXX_SDRAM_CS1CFG = dramsize + 0x0000001e;/* 2G */
+
+ /* find RAM size using SDRAM CS1 only */
+ if (!dramsize)
+ sdram_start(0);
+ test2 = test1 = get_ram_size((long *)(CFG_SDRAM_BASE + dramsize), 0x80000000);
+ if (!dramsize) {
+ sdram_start(1);
+ test2 = get_ram_size((long *)(CFG_SDRAM_BASE + dramsize), 0x80000000);
+ }
+ if (test1 > test2) {
+ sdram_start(0);
+ dramsize2 = test1;
+ } else {
+ dramsize2 = test2;
+ }
+
+ /* memory smaller than 1MB is impossible */
+ if (dramsize2 < (1 << 20)) {
+ dramsize2 = 0;
+ }
+
+ /* set SDRAM CS1 size according to the amount of RAM found */
+ if (dramsize2 > 0) {
+ *(vu_long *)MPC5XXX_SDRAM_CS1CFG = dramsize
+ | (0x13 + __builtin_ffs(dramsize2 >> 20) - 1);
+ } else {
+ *(vu_long *)MPC5XXX_SDRAM_CS1CFG = dramsize; /* disabled */
+ }
+
+#else /* CFG_RAMBOOT */
+
+ /* retrieve size of memory connected to SDRAM CS0 */
+ dramsize = *(vu_long *)MPC5XXX_SDRAM_CS0CFG & 0xFF;
+ if (dramsize >= 0x13) {
+ dramsize = (1 << (dramsize - 0x13)) << 20;
+ } else {
+ dramsize = 0;
+ }
+
+ /* retrieve size of memory connected to SDRAM CS1 */
+ dramsize2 = *(vu_long *)MPC5XXX_SDRAM_CS1CFG & 0xFF;
+ if (dramsize2 >= 0x13) {
+ dramsize2 = (1 << (dramsize2 - 0x13)) << 20;
+ } else {
+ dramsize2 = 0;
+ }
+
+#endif /* CFG_RAMBOOT */
+
+ /*
+ * On MPC5200B we need to set the special configuration delay in the
+ * DDR controller. Please refer to Freescale's AN3221 "MPC5200B SDRAM
+ * Initialization and Configuration", 3.3.1 SDelay--MBAR + 0x0190:
+ *
+ * "The SDelay should be written to a value of 0x00000004. It is
+ * required to account for changes caused by normal wafer processing
+ * parameters."
+ */
+ svr = get_svr();
+ pvr = get_pvr();
+ if ((SVR_MJREV(svr) >= 2) &&
+ (PVR_MAJ(pvr) == 1) && (PVR_MIN(pvr) == 4)) {
+
+ *(vu_long *)MPC5XXX_SDRAM_SDELAY = 0x04;
+ __asm__ volatile ("sync");
+ }
+
+ return dramsize + dramsize2;
+}
+
+int checkboard (void)
+{
+ puts ("Board: Sauter (Jupiter)\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.
+ */
+#if defined(CONFIG_MGT5100)
+ *(vu_long *)MPC5XXX_ADDECR &= ~(1 << 25); /* disable CS_BOOT */
+ *(vu_long *)MPC5XXX_ADDECR |= (1 << 16); /* enable CS0 */
+#endif
+ *(vu_long *)MPC5XXX_BOOTCS_CFG &= ~0x1; /* clear RO */
+}
+
+int board_early_init_r (void)
+{
+ flash_preinit ();
+ return 0;
+}
+
+void flash_afterinit(ulong size)
+{
+ if (size == 0x1000000) { /* 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);
+ }
+#if defined(CONFIG_MPC5200)
+ *(vu_long *)MPC5XXX_ADDECR &= ~(1 << 25); /* disable CS_BOOT */
+ *(vu_long *)MPC5XXX_ADDECR |= (1 << 16); /* enable CS0 */
+#endif
+}
+
+int update_flash_size (int flash_size)
+{
+ flash_afterinit (flash_size);
+ return 0;
+}
+
+int board_early_init_f (void)
+{
+ *(vu_long *)MPC5XXX_BOOTCS_CFG &= ~0x1; /* clear RO */
+ return 0;
+}
+
+#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)
+
+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;
+ /* Deassert reset */
+ *(vu_long *) MPC5XXX_WU_GPIO_DATA_O |= 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;
+ /* Make a delay. MPC5200 spec says 25 usec min */
+ udelay(500000);
+ } else {
+ *(vu_long *) MPC5XXX_WU_GPIO_DATA_O |= GPIO_PSC1_4;
+ }
+}
+#endif /* defined (CFG_CMD_IDE) && defined (CONFIG_IDE_RESET) */
+
+#if defined(CONFIG_OF_FLAT_TREE) && defined(CONFIG_OF_BOARD_SETUP)
+void
+ft_board_setup(void *blob, bd_t *bd)
+{
+ ft_cpu_setup(blob, bd);
+}
+#endif
diff --git a/board/jupiter/u-boot.lds b/board/jupiter/u-boot.lds
new file mode 100644
index 00000000000..f23432ecfa8
--- /dev/null
+++ b/board/jupiter/u-boot.lds
@@ -0,0 +1,125 @@
+/*
+ * (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
+ */
+
+OUTPUT_ARCH(powerpc)
+SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/local/powerpc-any-elf/lib);
+/* Do we need any of these for elf?
+ __DYNAMIC = 0; */
+SECTIONS
+{
+ /* Read-only sections, merged into text segment: */
+ . = + SIZEOF_HEADERS;
+ .interp : { *(.interp) }
+ .hash : { *(.hash) }
+ .dynsym : { *(.dynsym) }
+ .dynstr : { *(.dynstr) }
+ .rel.text : { *(.rel.text) }
+ .rela.text : { *(.rela.text) }
+ .rel.data : { *(.rel.data) }
+ .rela.data : { *(.rela.data) }
+ .rel.rodata : { *(.rel.rodata) }
+ .rela.rodata : { *(.rela.rodata) }
+ .rel.got : { *(.rel.got) }
+ .rela.got : { *(.rela.got) }
+ .rel.ctors : { *(.rel.ctors) }
+ .rela.ctors : { *(.rela.ctors) }
+ .rel.dtors : { *(.rel.dtors) }
+ .rela.dtors : { *(.rela.dtors) }
+ .rel.bss : { *(.rel.bss) }
+ .rela.bss : { *(.rela.bss) }
+ .rel.plt : { *(.rel.plt) }
+ .rela.plt : { *(.rela.plt) }
+ .init : { *(.init) }
+ .plt : { *(.plt) }
+ .text :
+ {
+ cpu/mpc5xxx/start.o (.text)
+ *(.text)
+ *(.fixup)
+ *(.got1)
+ . = ALIGN(16);
+ *(.rodata)
+ *(.rodata1)
+ *(.rodata.str1.4)
+ *(.eh_frame)
+ }
+ .fini : { *(.fini) } =0
+ .ctors : { *(.ctors) }
+ .dtors : { *(.dtors) }
+
+ /* Read-write section, merged into data segment: */
+ . = (. + 0x0FFF) & 0xFFFFF000;
+ _erotext = .;
+ PROVIDE (erotext = .);
+ .reloc :
+ {
+ *(.got)
+ _GOT2_TABLE_ = .;
+ *(.got2)
+ _FIXUP_TABLE_ = .;
+ *(.fixup)
+ }
+ __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >> 2;
+ __fixup_entries = (. - _FIXUP_TABLE_) >> 2;
+
+ .data :
+ {
+ *(.data)
+ *(.data1)
+ *(.sdata)
+ *(.sdata2)
+ *(.dynamic)
+ CONSTRUCTORS
+ }
+ _edata = .;
+ PROVIDE (edata = .);
+
+ . = .;
+ __u_boot_cmd_start = .;
+ .u_boot_cmd : { *(.u_boot_cmd) }
+ __u_boot_cmd_end = .;
+
+
+ . = .;
+ __start___ex_table = .;
+ __ex_table : { *(__ex_table) }
+ __stop___ex_table = .;
+
+ . = ALIGN(4096);
+ __init_begin = .;
+ .text.init : { *(.text.init) }
+ .data.init : { *(.data.init) }
+ . = ALIGN(4096);
+ __init_end = .;
+
+ __bss_start = .;
+ .bss :
+ {
+ *(.sbss) *(.scommon)
+ *(.dynbss)
+ *(.bss)
+ *(COMMON)
+ }
+ _end = . ;
+ PROVIDE (end = .);
+}
diff --git a/board/lpc2292sodimm/Makefile b/board/lpc2292sodimm/Makefile
new file mode 100644
index 00000000000..5a30198e21a
--- /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/lpc2292sodimm/config.mk b/board/lpc2292sodimm/config.mk
new file mode 100644
index 00000000000..b28f418df7b
--- /dev/null
+++ b/board/lpc2292sodimm/config.mk
@@ -0,0 +1,30 @@
+#
+# (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
+# 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
+#
+
+#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 00000000000..249ab043934
--- /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 00000000000..55aaabfe6f6
--- /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 00000000000..c31d5190bd7
--- /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 00000000000..a0e9747a9b1
--- /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 00000000000..d212c63328b
--- /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 = PHYS_SDRAM_1 + 0x100;
+
+ 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 00000000000..1c0922f2405
--- /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 00000000000..31f2a7988da
--- /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 00000000000..3687dbf6969
--- /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 00000000000..4ba1468f39e
--- /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 00000000000..6ae66e8ba74
--- /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 00000000000..64d946c4392
--- /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 = .;
+}
diff --git a/board/mcc200/Makefile b/board/mcc200/Makefile
index 75808cbb5ad..5869119697e 100644
--- a/board/mcc200/Makefile
+++ b/board/mcc200/Makefile
@@ -25,7 +25,7 @@ include $(TOPDIR)/config.mk
LIB = $(obj)lib$(BOARD).a
-COBJS := $(BOARD).o lcd.o
+COBJS := $(BOARD).o lcd.o auto_update.o
SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
OBJS := $(addprefix $(obj),$(COBJS))
diff --git a/board/mcc200/auto_update.c b/board/mcc200/auto_update.c
new file mode 100644
index 00000000000..90d03ec47a8
--- /dev/null
+++ b/board/mcc200/auto_update.c
@@ -0,0 +1,522 @@
+/*
+ * (C) Copyright 2006
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+#include <common.h>
+#include <command.h>
+#include <malloc.h>
+#include <image.h>
+#include <asm/byteorder.h>
+#include <usb.h>
+#include <part.h>
+
+#ifdef CFG_HUSH_PARSER
+#include <hush.h>
+#endif
+
+
+#ifdef CONFIG_AUTO_UPDATE
+
+#ifndef CONFIG_USB_OHCI
+#error "must define CONFIG_USB_OHCI"
+#endif
+
+#ifndef CONFIG_USB_STORAGE
+#error "must define CONFIG_USB_STORAGE"
+#endif
+
+#ifndef CFG_HUSH_PARSER
+#error "must define CFG_HUSH_PARSER"
+#endif
+
+#if !(CONFIG_COMMANDS & CFG_CMD_FAT)
+#error "must define CFG_CMD_FAT"
+#endif
+
+#undef AU_DEBUG
+
+#undef debug
+#ifdef AU_DEBUG
+#define debug(fmt,args...) printf (fmt ,##args)
+#else
+#define debug(fmt,args...)
+#endif /* AU_DEBUG */
+
+/* possible names of files on the USB stick. */
+#define AU_FIRMWARE "u-boot.img"
+#define AU_KERNEL "kernel.img"
+#define AU_ROOTFS "rootfs.img"
+
+struct flash_layout {
+ long start;
+ long end;
+};
+
+/* layout of the FLASH. ST = start address, ND = end address. */
+#define AU_FL_FIRMWARE_ST 0xfC000000
+#define AU_FL_FIRMWARE_ND 0xfC03FFFF
+#define AU_FL_KERNEL_ST 0xfC0C0000
+#define AU_FL_KERNEL_ND 0xfC1BFFFF
+#define AU_FL_ROOTFS_ST 0xFC1C0000
+#define AU_FL_ROOTFS_ND 0xFCFBFFFF
+
+static int au_usb_stor_curr_dev; /* current device */
+
+/* index of each file in the following arrays */
+#define IDX_FIRMWARE 0
+#define IDX_KERNEL 1
+#define IDX_ROOTFS 2
+
+/* max. number of files which could interest us */
+#define AU_MAXFILES 3
+
+/* pointers to file names */
+char *aufile[AU_MAXFILES] = {
+ AU_FIRMWARE,
+ AU_KERNEL,
+ AU_ROOTFS
+};
+
+/* sizes of flash areas for each file */
+long ausize[AU_MAXFILES] = {
+ (AU_FL_FIRMWARE_ND + 1) - AU_FL_FIRMWARE_ST,
+ (AU_FL_KERNEL_ND + 1) - AU_FL_KERNEL_ST,
+ (AU_FL_ROOTFS_ND + 1) - AU_FL_ROOTFS_ST,
+};
+
+/* array of flash areas start and end addresses */
+struct flash_layout aufl_layout[AU_MAXFILES] = {
+ { AU_FL_FIRMWARE_ST, AU_FL_FIRMWARE_ND, },
+ { AU_FL_KERNEL_ST, AU_FL_KERNEL_ND, },
+ { AU_FL_ROOTFS_ST, AU_FL_ROOTFS_ND, },
+};
+
+ulong totsize;
+
+/* where to load files into memory */
+#define LOAD_ADDR ((unsigned char *)0x00200000)
+
+/* the root file system is the largest image */
+#define MAX_LOADSZ ausize[IDX_ROOTFS]
+
+/*i2c address of the keypad status*/
+#define I2C_PSOC_KEYPAD_ADDR 0x53
+
+/* keypad mask */
+#define KEYPAD_ROW 2
+#define KEYPAD_COL 2
+#define KEYPAD_MASK_LO ((1<<(KEYPAD_COL-1+(KEYPAD_ROW*3-3)))&0xFF)
+#define KEYPAD_MASK_HI ((1<<(KEYPAD_COL-1+(KEYPAD_ROW*3-3)))>>8)
+
+/* externals */
+extern int fat_register_device(block_dev_desc_t *, int);
+extern int file_fat_detectfs(void);
+extern long file_fat_read(const char *, void *, unsigned long);
+extern int i2c_read (unsigned char, unsigned int, int , unsigned char* , int);
+extern int flash_sect_erase(ulong, ulong);
+extern int flash_sect_protect (int, ulong, ulong);
+extern int flash_write (char *, ulong, ulong);
+extern int u_boot_hush_start(void);
+#ifdef CONFIG_PROGRESSBAR
+extern void show_progress(int, int);
+extern void lcd_puts (char *);
+extern void lcd_enable(void);
+#endif
+
+int au_check_cksum_valid(int idx, long nbytes)
+{
+ image_header_t *hdr;
+ unsigned long checksum;
+
+ hdr = (image_header_t *)LOAD_ADDR;
+
+ if (nbytes != (sizeof(*hdr) + ntohl(hdr->ih_size))) {
+ printf ("Image %s bad total SIZE\n", aufile[idx]);
+ return -1;
+ }
+ /* check the data CRC */
+ checksum = ntohl(hdr->ih_dcrc);
+
+ if (crc32 (0, (uchar *)(LOAD_ADDR + sizeof(*hdr)), ntohl(hdr->ih_size)) != checksum) {
+ printf ("Image %s bad data checksum\n", aufile[idx]);
+ return -1;
+ }
+ return 0;
+}
+
+int au_check_header_valid(int idx, long nbytes)
+{
+ image_header_t *hdr;
+ unsigned long checksum, fsize;
+
+ hdr = (image_header_t *)LOAD_ADDR;
+ /* check the easy ones first */
+#undef CHECK_VALID_DEBUG
+#ifdef CHECK_VALID_DEBUG
+ printf("magic %#x %#x ", ntohl(hdr->ih_magic), IH_MAGIC);
+ printf("arch %#x %#x ", hdr->ih_arch, IH_CPU_ARM);
+ printf("size %#x %#lx ", ntohl(hdr->ih_size), nbytes);
+ printf("type %#x %#x ", hdr->ih_type, IH_TYPE_KERNEL);
+#endif
+ if (nbytes < sizeof(*hdr)) {
+ printf ("Image %s bad header SIZE\n", aufile[idx]);
+ ausize[idx] = 0;
+ return -1;
+ }
+ if (ntohl(hdr->ih_magic) != IH_MAGIC || hdr->ih_arch != IH_CPU_PPC) {
+ printf ("Image %s bad MAGIC or ARCH\n", aufile[idx]);
+ ausize[idx] = 0;
+ return -1;
+ }
+ /* check the hdr CRC */
+ checksum = ntohl(hdr->ih_hcrc);
+ hdr->ih_hcrc = 0;
+
+ if (crc32 (0, (uchar *)hdr, sizeof(*hdr)) != checksum) {
+ printf ("Image %s bad header checksum\n", aufile[idx]);
+ ausize[idx] = 0;
+ return -1;
+ }
+ hdr->ih_hcrc = htonl(checksum);
+ /* check the type - could do this all in one gigantic if() */
+ if ((idx == IDX_FIRMWARE) && (hdr->ih_type != IH_TYPE_FIRMWARE)) {
+ printf ("Image %s wrong type\n", aufile[idx]);
+ ausize[idx] = 0;
+ return -1;
+ }
+ if ((idx == IDX_KERNEL) && (hdr->ih_type != IH_TYPE_KERNEL)) {
+ printf ("Image %s wrong type\n", aufile[idx]);
+ ausize[idx] = 0;
+ return -1;
+ }
+ if ((idx == IDX_ROOTFS) &&
+ ( (hdr->ih_type != IH_TYPE_RAMDISK) && (hdr->ih_type != IH_TYPE_FILESYSTEM) )
+ ) {
+ printf ("Image %s wrong type\n", aufile[idx]);
+ ausize[idx] = 0;
+ return -1;
+ }
+ /* recycle checksum */
+ checksum = ntohl(hdr->ih_size);
+
+ fsize = checksum + sizeof(*hdr);
+ /* for kernel and ramdisk the image header must also fit into flash */
+ if (idx == IDX_KERNEL || hdr->ih_type == IH_TYPE_RAMDISK)
+ checksum += sizeof(*hdr);
+
+ /* check the size does not exceed space in flash. HUSH scripts */
+ if ((ausize[idx] != 0) && (ausize[idx] < checksum)) {
+ printf ("Image %s is bigger than FLASH\n", aufile[idx]);
+ ausize[idx] = 0;
+ return -1;
+ }
+ /* Update with the real filesize */
+ ausize[idx] = fsize;
+
+ return checksum; /* return size to be written to flash */
+}
+
+int au_do_update(int idx, long sz)
+{
+ image_header_t *hdr;
+ char *addr;
+ long start, end;
+ int off, rc;
+ uint nbytes;
+
+ hdr = (image_header_t *)LOAD_ADDR;
+
+ /* execute a script */
+ if (hdr->ih_type == IH_TYPE_SCRIPT) {
+ addr = (char *)((char *)hdr + sizeof(*hdr));
+ /* stick a NULL at the end of the script, otherwise */
+ /* parse_string_outer() runs off the end. */
+ addr[ntohl(hdr->ih_size)] = 0;
+ addr += 8;
+ parse_string_outer(addr, FLAG_PARSE_SEMICOLON);
+ return 0;
+ }
+
+ start = aufl_layout[idx].start;
+ end = aufl_layout[idx].end;
+
+ /* unprotect the address range */
+ /* this assumes that ONLY the firmware is protected! */
+ if (idx == IDX_FIRMWARE) {
+#undef AU_UPDATE_TEST
+#ifdef AU_UPDATE_TEST
+ /* erase it where Linux goes */
+ start = aufl_layout[1].start;
+ end = aufl_layout[1].end;
+#endif
+ flash_sect_protect(0, start, end);
+ }
+
+ /*
+ * erase the address range.
+ */
+ debug ("flash_sect_erase(%lx, %lx);\n", start, end);
+ flash_sect_erase(start, end);
+ wait_ms(100);
+#ifdef CONFIG_PROGRESSBAR
+ show_progress(end - start, totsize);
+#endif
+
+ /* strip the header - except for the kernel and ramdisk */
+ if (hdr->ih_type == IH_TYPE_KERNEL || hdr->ih_type == IH_TYPE_RAMDISK) {
+ addr = (char *)hdr;
+ off = sizeof(*hdr);
+ nbytes = sizeof(*hdr) + ntohl(hdr->ih_size);
+ } else {
+ addr = (char *)((char *)hdr + sizeof(*hdr));
+#ifdef AU_UPDATE_TEST
+ /* copy it to where Linux goes */
+ if (idx == IDX_FIRMWARE)
+ start = aufl_layout[1].start;
+#endif
+ off = 0;
+ nbytes = ntohl(hdr->ih_size);
+ }
+
+ /* copy the data from RAM to FLASH */
+ debug ("flash_write(%p, %lx %x)\n", addr, start, nbytes);
+ rc = flash_write(addr, start, nbytes);
+ if (rc != 0) {
+ printf("Flashing failed due to error %d\n", rc);
+ return -1;
+ }
+
+#ifdef CONFIG_PROGRESSBAR
+ show_progress(nbytes, totsize);
+#endif
+
+ /* check the data CRC of the copy */
+ if (crc32 (0, (uchar *)(start + off), ntohl(hdr->ih_size)) != ntohl(hdr->ih_dcrc)) {
+ printf ("Image %s Bad Data Checksum after COPY\n", aufile[idx]);
+ return -1;
+ }
+
+ /* protect the address range */
+ /* this assumes that ONLY the firmware is protected! */
+ if (idx == IDX_FIRMWARE)
+ flash_sect_protect(1, start, end);
+ return 0;
+}
+
+/*
+ * this is called from board_init() after the hardware has been set up
+ * and is usable. That seems like a good time to do this.
+ * Right now the return value is ignored.
+ */
+int do_auto_update(void)
+{
+ block_dev_desc_t *stor_dev;
+ long sz;
+ int i, res = 0, bitmap_first, cnt, old_ctrlc, got_ctrlc;
+ char *env;
+ long start, end;
+ uchar keypad_status1[2] = {0,0}, keypad_status2[2] = {0,0};
+
+ /*
+ * Read keypad status
+ */
+ i2c_read(I2C_PSOC_KEYPAD_ADDR, 0, 0, keypad_status1, 2);
+ wait_ms(500);
+ i2c_read(I2C_PSOC_KEYPAD_ADDR, 0, 0, keypad_status2, 2);
+
+ /*
+ * Check keypad
+ */
+ if ( !(keypad_status1[1] & KEYPAD_MASK_LO) ||
+ (keypad_status1[1] != keypad_status2[1])) {
+ return 0;
+ }
+
+ au_usb_stor_curr_dev = -1;
+ /* start USB */
+ if (usb_stop() < 0) {
+ debug ("usb_stop failed\n");
+ return -1;
+ }
+ if (usb_init() < 0) {
+ debug ("usb_init failed\n");
+ return -1;
+ }
+ /*
+ * check whether a storage device is attached (assume that it's
+ * a USB memory stick, since nothing else should be attached).
+ */
+ au_usb_stor_curr_dev = usb_stor_scan(0);
+ if (au_usb_stor_curr_dev == -1) {
+ debug ("No device found. Not initialized?\n");
+ return -1;
+ }
+ /* check whether it has a partition table */
+ stor_dev = get_dev("usb", 0);
+ if (stor_dev == NULL) {
+ debug ("uknown device type\n");
+ return -1;
+ }
+ if (fat_register_device(stor_dev, 1) != 0) {
+ debug ("Unable to use USB %d:%d for fatls\n",
+ au_usb_stor_curr_dev, 1);
+ return -1;
+ }
+ if (file_fat_detectfs() != 0) {
+ debug ("file_fat_detectfs failed\n");
+ }
+
+ /*
+ * now check whether start and end are defined using environment
+ * variables.
+ */
+ start = -1;
+ end = 0;
+ env = getenv("firmware_st");
+ if (env != NULL)
+ start = simple_strtoul(env, NULL, 16);
+ env = getenv("firmware_nd");
+ if (env != NULL)
+ end = simple_strtoul(env, NULL, 16);
+ if (start >= 0 && end && end > start) {
+ ausize[IDX_FIRMWARE] = (end + 1) - start;
+ aufl_layout[IDX_FIRMWARE].start = start;
+ aufl_layout[IDX_FIRMWARE].end = end;
+ }
+ start = -1;
+ end = 0;
+ env = getenv("kernel_st");
+ if (env != NULL)
+ start = simple_strtoul(env, NULL, 16);
+ env = getenv("kernel_nd");
+ if (env != NULL)
+ end = simple_strtoul(env, NULL, 16);
+ if (start >= 0 && end && end > start) {
+ ausize[IDX_KERNEL] = (end + 1) - start;
+ aufl_layout[IDX_KERNEL].start = start;
+ aufl_layout[IDX_KERNEL].end = end;
+ }
+ start = -1;
+ end = 0;
+ env = getenv("rootfs_st");
+ if (env != NULL)
+ start = simple_strtoul(env, NULL, 16);
+ env = getenv("rootfs_nd");
+ if (env != NULL)
+ end = simple_strtoul(env, NULL, 16);
+ if (start >= 0 && end && end > start) {
+ ausize[IDX_ROOTFS] = (end + 1) - start;
+ aufl_layout[IDX_ROOTFS].start = start;
+ aufl_layout[IDX_ROOTFS].end = end;
+ }
+
+ /* make certain that HUSH is runnable */
+ u_boot_hush_start();
+ /* make sure that we see CTRL-C and save the old state */
+ old_ctrlc = disable_ctrlc(0);
+
+ bitmap_first = 0;
+
+ /* validate the images first */
+ for (i = 0; i < AU_MAXFILES; i++) {
+ ulong imsize;
+ /* just read the header */
+ sz = file_fat_read(aufile[i], LOAD_ADDR, sizeof(image_header_t));
+ debug ("read %s sz %ld hdr %d\n",
+ aufile[i], sz, sizeof(image_header_t));
+ if (sz <= 0 || sz < sizeof(image_header_t)) {
+ debug ("%s not found\n", aufile[i]);
+ ausize[i] = 0;
+ continue;
+ }
+ /* au_check_header_valid() updates ausize[] */
+ if ((imsize = au_check_header_valid(i, sz)) < 0) {
+ debug ("%s header not valid\n", aufile[i]);
+ continue;
+ }
+ /* totsize accounts for image size and flash erase size */
+ totsize += (imsize + (aufl_layout[i].end - aufl_layout[i].start));
+ }
+
+#ifdef CONFIG_PROGRESSBAR
+ if (totsize) {
+ lcd_puts(" Update in progress\n");
+ lcd_enable();
+ }
+#endif
+
+ /* just loop thru all the possible files */
+ for (i = 0; i < AU_MAXFILES && totsize; i++) {
+ if (!ausize[i]) {
+ continue;
+ }
+ sz = file_fat_read(aufile[i], LOAD_ADDR, ausize[i]);
+
+ debug ("read %s sz %ld hdr %d\n",
+ aufile[i], sz, sizeof(image_header_t));
+
+ if (sz != ausize[i]) {
+ printf ("%s: size %d read %d?\n", aufile[i], ausize[i], sz);
+ continue;
+ }
+
+ if (sz <= 0 || sz <= sizeof(image_header_t)) {
+ debug ("%s not found\n", aufile[i]);
+ continue;
+ }
+ if (au_check_cksum_valid(i, sz) < 0) {
+ debug ("%s checksum not valid\n", aufile[i]);
+ continue;
+ }
+ /* this is really not a good idea, but it's what the */
+ /* customer wants. */
+ cnt = 0;
+ got_ctrlc = 0;
+ do {
+ res = au_do_update(i, sz);
+ /* let the user break out of the loop */
+ if (ctrlc() || had_ctrlc()) {
+ clear_ctrlc();
+ if (res < 0)
+ got_ctrlc = 1;
+ break;
+ }
+ cnt++;
+#ifdef AU_TEST_ONLY
+ } while (res < 0 && cnt < (AU_MAXFILES + 1));
+ if (cnt < (AU_MAXFILES + 1))
+#else
+ } while (res < 0);
+#endif
+ }
+ usb_stop();
+ /* restore the old state */
+ disable_ctrlc(old_ctrlc);
+#ifdef CONFIG_PROGRESSBAR
+ if (totsize) {
+ if (!res) {
+ lcd_puts("\n Update completed\n");
+ } else {
+ lcd_puts("\n Update error\n");
+ }
+ lcd_enable();
+ }
+#endif
+ return 0;
+}
+#endif /* CONFIG_AUTO_UPDATE */
diff --git a/board/mcc200/lcd.c b/board/mcc200/lcd.c
index b2625160a5e..98b86d1834f 100644
--- a/board/mcc200/lcd.c
+++ b/board/mcc200/lcd.c
@@ -24,13 +24,13 @@
#ifdef CONFIG_LCD
-#define SWAPPED_LCD
+#undef SWAPPED_LCD /* For the previous h/w version */
/*
* The name of the device used for communication
* with the PSoC.
*/
#define PSOC_PSC MPC5XXX_PSC2
-#define PSOC_BAUD 500000UL
+#define PSOC_BAUD 230400UL
#define RTS_ASSERT 1
#define RTS_NEGATE 0
@@ -181,10 +181,35 @@ void lcd_enable (void)
udelay (PSOC_WAIT_TIME);
}
if (!retries) {
- printf ("%s Error: PSoC doesn't respond on "
+ printf ("%s Warning: PSoC doesn't respond on "
"RTS NEGATE\n", __FUNCTION__);
}
return;
}
+#ifdef CONFIG_PROGRESSBAR
+
+#define FONT_WIDTH 8 /* the same as VIDEO_FONT_WIDTH in video_font.h */
+void show_progress (int size, int tot)
+{
+ int cnt;
+ int i;
+ static int rc = 0;
+
+ rc += size;
+
+ cnt = ((LCD_WIDTH/FONT_WIDTH) * rc) / tot;
+
+ rc -= (cnt * tot) / (LCD_WIDTH/FONT_WIDTH);
+
+ for (i = 0; i < cnt; i++) {
+ lcd_putc(0xdc);
+ }
+
+ if (cnt) {
+ lcd_enable(); /* MCC200-specific - send the framebuffer to PSoC */
+ }
+}
+
+#endif
#endif /* CONFIG_LCD */
diff --git a/board/mcc200/mcc200.c b/board/mcc200/mcc200.c
index 5d74bdeb42e..af047e2a077 100644
--- a/board/mcc200/mcc200.c
+++ b/board/mcc200/mcc200.c
@@ -44,6 +44,7 @@ DECLARE_GLOBAL_DATA_PTR;
extern flash_info_t flash_info[]; /* FLASH chips info */
+extern int do_auto_update(void);
ulong flash_get_size (ulong base, int banknum);
#ifndef CFG_RAMBOOT
@@ -91,8 +92,8 @@ static void sdram_start (int hi_addr)
/*
* 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.
+ * 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)
@@ -289,6 +290,9 @@ int misc_init_r (void)
flash_info[0].sector_count = snum;
}
+#ifdef CONFIG_AUTO_UPDATE
+ do_auto_update();
+#endif
return (0);
}
diff --git a/board/motionpro/Makefile b/board/motionpro/Makefile
new file mode 100644
index 00000000000..698ead195cb
--- /dev/null
+++ b/board/motionpro/Makefile
@@ -0,0 +1,50 @@
+#
+# (C) Copyright 2003-2007
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+include $(TOPDIR)/config.mk
+
+LIB = $(obj)lib$(BOARD).a
+
+COBJS := $(BOARD).o
+
+SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(COBJS))
+SOBJS := $(addprefix $(obj),$(SOBJS))
+
+$(LIB): $(obj).depend $(OBJS)
+ $(AR) $(ARFLAGS) $@ $(OBJS)
+
+clean:
+ rm -f $(SOBJS) $(OBJS)
+
+distclean: clean
+ rm -f $(LIB) core *.bak .depend
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/board/motionpro/config.mk b/board/motionpro/config.mk
new file mode 100644
index 00000000000..e7934d29c15
--- /dev/null
+++ b/board/motionpro/config.mk
@@ -0,0 +1,30 @@
+#
+# (C) Copyright 2006-2007
+# 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
+#
+
+#
+# Promess Motion-PRO
+#
+
+TEXT_BASE = 0xfff00000
+
+PLATFORM_CPPFLAGS += -DTEXT_BASE=$(TEXT_BASE) -I$(TOPDIR)/board
diff --git a/board/motionpro/motionpro.c b/board/motionpro/motionpro.c
new file mode 100644
index 00000000000..d60d23332b1
--- /dev/null
+++ b/board/motionpro/motionpro.c
@@ -0,0 +1,172 @@
+/*
+ * (C) Copyright 2003-2007
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * modified for Promess PRO - by Andy Joseph, andy@promessdev.com
+ * modified for Promess PRO-Motion - by Robert McCullough, rob@promessdev.com
+ * modified by Chris M. Tumas 6/20/06 Change CAS latency to 2 from 3
+ * Also changed the refresh for 100Mhz operation
+ *
+ * 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 <mpc5xxx.h>
+
+
+/* Kollmorgen DPR initialization data */
+struct init_elem {
+ unsigned long addr;
+ unsigned len;
+ char *data;
+ } init_seq[] = {
+ {0x500003F2, 2, "\x86\x00"}, /* HW parameter */
+ {0x500003F0, 2, "\x00\x00"},
+ {0x500003EC, 4, "\x00\x80\xc1\x52"}, /* Magic word */
+ };
+
+/*
+ * Initialize Kollmorgen DPR
+ */
+static void kollmorgen_init(void)
+{
+ unsigned i, j;
+ vu_char *p;
+
+ for (i = 0; i < sizeof(init_seq) / sizeof(struct init_elem); ++i) {
+ p = (vu_char *)init_seq[i].addr;
+ for (j = 0; j < init_seq[i].len; ++j)
+ *(p + j) = *(init_seq[i].data + j);
+ }
+
+ printf("DPR: Kollmorgen DPR initialized\n");
+}
+
+
+/*
+ * Early board initalization.
+ */
+int board_early_init_r(void)
+{
+ /* Now, when we are in RAM, disable Boot Chipselect and enable CS0 */
+ *(vu_long *)MPC5XXX_ADDECR &= ~(1 << 25);
+ *(vu_long *)MPC5XXX_ADDECR |= (1 << 16);
+
+ /* Initialize Kollmorgen DPR */
+ kollmorgen_init();
+
+ return 0;
+}
+
+
+#ifndef CFG_RAMBOOT
+/*
+ * Helper function to initialize SDRAM controller.
+ */
+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;
+
+ /* precharge all banks */
+ *(vu_long *)MPC5XXX_SDRAM_CTRL = SDRAM_CONTROL | 0x80000002 |
+ hi_addr_bit;
+
+ /* auto refresh */
+ *(vu_long *)MPC5XXX_SDRAM_CTRL = SDRAM_CONTROL | 0x80000004 |
+ hi_addr_bit;
+
+ /* auto refresh, second time */
+ *(vu_long *)MPC5XXX_SDRAM_CTRL = SDRAM_CONTROL | 0x80000004 |
+ hi_addr_bit;
+
+ /* set mode register */
+ *(vu_long *)MPC5XXX_SDRAM_MODE = SDRAM_MODE;
+
+ /* normal operation */
+ *(vu_long *)MPC5XXX_SDRAM_CTRL = SDRAM_CONTROL | hi_addr_bit;
+}
+#endif /* !CFG_RAMBOOT */
+
+
+/*
+ * Initalize SDRAM - configure SDRAM controller, detect memory size.
+ */
+long int initdram (int board_type)
+{
+ ulong dramsize = 0;
+#ifndef CFG_RAMBOOT
+ ulong test1, test2;
+
+ /* configure SDRAM start/end for detection */
+ *(vu_long *)MPC5XXX_SDRAM_CS0CFG = 0x0000001e; /* 2G at 0x0 */
+ *(vu_long *)MPC5XXX_SDRAM_CS1CFG = 0x80000000; /* disabled */
+
+ /* setup config registers */
+ *(vu_long *)MPC5XXX_SDRAM_CONFIG1 = SDRAM_CONFIG1;
+ *(vu_long *)MPC5XXX_SDRAM_CONFIG2 = SDRAM_CONFIG2;
+
+ sdram_start(0);
+ test1 = get_ram_size((long *)CFG_SDRAM_BASE, 0x80000000);
+ sdram_start(1);
+ test2 = get_ram_size((long *)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;
+ } else {
+ *(vu_long *)MPC5XXX_SDRAM_CS0CFG = 0; /* disabled */
+ }
+
+ /* let SDRAM CS1 start right after CS0 and disable it */
+ *(vu_long *) MPC5XXX_SDRAM_CS1CFG = dramsize;
+
+#else /* !CFG_RAMBOOT */
+ /* retrieve size of memory connected to SDRAM CS0 */
+ dramsize = *(vu_long *)MPC5XXX_SDRAM_CS0CFG & 0xFF;
+ if (dramsize >= 0x13)
+ dramsize = (1 << (dramsize - 0x13)) << 20;
+ else
+ dramsize = 0;
+#endif /* CFG_RAMBOOT */
+
+ /* return total ram size */
+ return dramsize;
+}
+
+
+int checkboard (void)
+{
+ puts("Board: Promess Motion-PRO board\n");
+ return 0;
+}
diff --git a/board/motionpro/u-boot.lds b/board/motionpro/u-boot.lds
new file mode 100644
index 00000000000..8fa9c0f7ed5
--- /dev/null
+++ b/board/motionpro/u-boot.lds
@@ -0,0 +1,123 @@
+/*
+ * (C) Copyright 2003-2007
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+OUTPUT_ARCH(powerpc)
+SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/local/powerpc-any-elf/lib);
+SECTIONS
+{
+ /* Read-only sections, merged into text segment: */
+ . = + SIZEOF_HEADERS;
+ .interp : { *(.interp) }
+ .hash : { *(.hash) }
+ .dynsym : { *(.dynsym) }
+ .dynstr : { *(.dynstr) }
+ .rel.text : { *(.rel.text) }
+ .rela.text : { *(.rela.text) }
+ .rel.data : { *(.rel.data) }
+ .rela.data : { *(.rela.data) }
+ .rel.rodata : { *(.rel.rodata) }
+ .rela.rodata : { *(.rela.rodata) }
+ .rel.got : { *(.rel.got) }
+ .rela.got : { *(.rela.got) }
+ .rel.ctors : { *(.rel.ctors) }
+ .rela.ctors : { *(.rela.ctors) }
+ .rel.dtors : { *(.rel.dtors) }
+ .rela.dtors : { *(.rela.dtors) }
+ .rel.bss : { *(.rel.bss) }
+ .rela.bss : { *(.rela.bss) }
+ .rel.plt : { *(.rel.plt) }
+ .rela.plt : { *(.rela.plt) }
+ .init : { *(.init) }
+ .plt : { *(.plt) }
+ .text :
+ {
+ cpu/mpc5xxx/start.o (.text)
+ *(.text)
+ *(.fixup)
+ *(.got1)
+ . = ALIGN(16);
+ *(.rodata)
+ *(.rodata1)
+ *(.rodata.str1.4)
+ *(.eh_frame)
+ }
+ .fini : { *(.fini) } =0
+ .ctors : { *(.ctors) }
+ .dtors : { *(.dtors) }
+
+ /* Read-write section, merged into data segment: */
+ . = (. + 0x0FFF) & 0xFFFFF000;
+ _erotext = .;
+ PROVIDE (erotext = .);
+ .reloc :
+ {
+ *(.got)
+ _GOT2_TABLE_ = .;
+ *(.got2)
+ _FIXUP_TABLE_ = .;
+ *(.fixup)
+ }
+ __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >> 2;
+ __fixup_entries = (. - _FIXUP_TABLE_) >> 2;
+
+ .data :
+ {
+ *(.data)
+ *(.data1)
+ *(.sdata)
+ *(.sdata2)
+ *(.dynamic)
+ CONSTRUCTORS
+ }
+ _edata = .;
+ PROVIDE (edata = .);
+
+ . = .;
+ __u_boot_cmd_start = .;
+ .u_boot_cmd : { *(.u_boot_cmd) }
+ __u_boot_cmd_end = .;
+
+
+ . = .;
+ __start___ex_table = .;
+ __ex_table : { *(__ex_table) }
+ __stop___ex_table = .;
+
+ . = ALIGN(4096);
+ __init_begin = .;
+ .text.init : { *(.text.init) }
+ .data.init : { *(.data.init) }
+ . = ALIGN(4096);
+ __init_end = .;
+
+ __bss_start = .;
+ .bss :
+ {
+ *(.sbss) *(.scommon)
+ *(.dynbss)
+ *(.bss)
+ *(COMMON)
+ }
+ _end = . ;
+ PROVIDE (end = .);
+}
diff --git a/board/mpc832xemds/Makefile b/board/mpc832xemds/Makefile
new file mode 100644
index 00000000000..5ec7a871d4d
--- /dev/null
+++ b/board/mpc832xemds/Makefile
@@ -0,0 +1,50 @@
+#
+# (C) Copyright 2006
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+include $(TOPDIR)/config.mk
+
+LIB = $(obj)lib$(BOARD).a
+
+COBJS := $(BOARD).o pci.o
+
+SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(COBJS))
+SOBJS := $(addprefix $(obj),$(SOBJS))
+
+$(LIB): $(obj).depend $(OBJS)
+ $(AR) $(ARFLAGS) $@ $(OBJS)
+
+clean:
+ rm -f $(SOBJS) $(OBJS)
+
+distclean: clean
+ rm -f $(LIB) core *.bak .depend
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/board/stamp/config.mk b/board/mpc832xemds/config.mk
index 0d0073032da..6c3eca75341 100644
--- a/board/stamp/config.mk
+++ b/board/mpc832xemds/config.mk
@@ -1,5 +1,5 @@
#
-# (C) Copyright 2001
+# (C) Copyright 2006
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
#
# See file CREDITS for list of people who contributed to this
@@ -21,5 +21,8 @@
# MA 02111-1307 USA
#
-TEXT_BASE = 0x07FC0000
-PLATFORM_CPPFLAGS += -I$(TOPDIR)
+#
+# MPC832XEMDS
+#
+
+TEXT_BASE = 0xFE000000
diff --git a/board/mpc832xemds/mpc832xemds.c b/board/mpc832xemds/mpc832xemds.c
new file mode 100644
index 00000000000..772da678f00
--- /dev/null
+++ b/board/mpc832xemds/mpc832xemds.c
@@ -0,0 +1,176 @@
+/*
+ * Copyright (C) 2006 Freescale Semiconductor, Inc.
+ *
+ * Dave Liu <daveliu@freescale.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ */
+
+#include <common.h>
+#include <ioports.h>
+#include <mpc83xx.h>
+#include <i2c.h>
+#include <spd.h>
+#include <miiphy.h>
+#include <command.h>
+#if defined(CONFIG_PCI)
+#include <pci.h>
+#endif
+#if defined(CONFIG_SPD_EEPROM)
+#include <spd_sdram.h>
+#else
+#include <asm/mmu.h>
+#endif
+#if defined(CONFIG_OF_FLAT_TREE)
+#include <ft_build.h>
+#endif
+
+const qe_iop_conf_t qe_iop_conf_tab[] = {
+ /* ETH3 */
+ {1, 0, 1, 0, 1}, /* TxD0 */
+ {1, 1, 1, 0, 1}, /* TxD1 */
+ {1, 2, 1, 0, 1}, /* TxD2 */
+ {1, 3, 1, 0, 1}, /* TxD3 */
+ {1, 9, 1, 0, 1}, /* TxER */
+ {1, 12, 1, 0, 1}, /* TxEN */
+ {3, 24, 2, 0, 1}, /* TxCLK->CLK10 */
+
+ {1, 4, 2, 0, 1}, /* RxD0 */
+ {1, 5, 2, 0, 1}, /* RxD1 */
+ {1, 6, 2, 0, 1}, /* RxD2 */
+ {1, 7, 2, 0, 1}, /* RxD3 */
+ {1, 8, 2, 0, 1}, /* RxER */
+ {1, 10, 2, 0, 1}, /* RxDV */
+ {0, 13, 2, 0, 1}, /* RxCLK->CLK9 */
+ {1, 11, 2, 0, 1}, /* COL */
+ {1, 13, 2, 0, 1}, /* CRS */
+
+ /* ETH4 */
+ {1, 18, 1, 0, 1}, /* TxD0 */
+ {1, 19, 1, 0, 1}, /* TxD1 */
+ {1, 20, 1, 0, 1}, /* TxD2 */
+ {1, 21, 1, 0, 1}, /* TxD3 */
+ {1, 27, 1, 0, 1}, /* TxER */
+ {1, 30, 1, 0, 1}, /* TxEN */
+ {3, 6, 2, 0, 1}, /* TxCLK->CLK8 */
+
+ {1, 22, 2, 0, 1}, /* RxD0 */
+ {1, 23, 2, 0, 1}, /* RxD1 */
+ {1, 24, 2, 0, 1}, /* RxD2 */
+ {1, 25, 2, 0, 1}, /* RxD3 */
+ {1, 26, 1, 0, 1}, /* RxER */
+ {1, 28, 2, 0, 1}, /* Rx_DV */
+ {3, 31, 2, 0, 1}, /* RxCLK->CLK7 */
+ {1, 29, 2, 0, 1}, /* COL */
+ {1, 31, 2, 0, 1}, /* CRS */
+
+ {3, 4, 3, 0, 2}, /* MDIO */
+ {3, 5, 1, 0, 2}, /* MDC */
+
+ {0, 0, 0, 0, QE_IOP_TAB_END}, /* END of table */
+};
+
+int board_early_init_f(void)
+{
+ volatile u8 *bcsr = (volatile u8 *)CFG_BCSR;
+
+ /* Enable flash write */
+ bcsr[9] &= ~0x08;
+
+ return 0;
+}
+
+int fixed_sdram(void);
+
+long int initdram(int board_type)
+{
+ volatile immap_t *im = (immap_t *) CFG_IMMR;
+ u32 msize = 0;
+
+ if ((im->sysconf.immrbar & IMMRBAR_BASE_ADDR) != (u32) im)
+ return -1;
+
+ /* DDR SDRAM - Main SODIMM */
+ im->sysconf.ddrlaw[0].bar = CFG_DDR_BASE & LAWBAR_BAR;
+
+ msize = fixed_sdram();
+
+ puts("\n DDR RAM: ");
+
+ /* return total bus SDRAM size(bytes) -- DDR */
+ return (msize * 1024 * 1024);
+}
+
+/*************************************************************************
+ * fixed sdram init -- doesn't use serial presence detect.
+ ************************************************************************/
+int fixed_sdram(void)
+{
+ volatile immap_t *im = (immap_t *) CFG_IMMR;
+ u32 msize = 0;
+ u32 ddr_size;
+ u32 ddr_size_log2;
+
+ msize = CFG_DDR_SIZE;
+ for (ddr_size = msize << 20, ddr_size_log2 = 0;
+ (ddr_size > 1); ddr_size = ddr_size >> 1, ddr_size_log2++) {
+ if (ddr_size & 1) {
+ return -1;
+ }
+ }
+ im->sysconf.ddrlaw[0].ar =
+ LAWAR_EN | ((ddr_size_log2 - 1) & LAWAR_SIZE);
+#if (CFG_DDR_SIZE != 128)
+#warning Currenly any ddr size other than 128 is not supported
+#endif
+ im->ddr.sdram_clk_cntl = CFG_DDR_CLK_CNTL;
+ im->ddr.csbnds[0].csbnds = CFG_DDR_CS0_BNDS;
+ im->ddr.cs_config[0] = CFG_DDR_CS0_CONFIG;
+ im->ddr.timing_cfg_0 = CFG_DDR_TIMING_0;
+ im->ddr.timing_cfg_1 = CFG_DDR_TIMING_1;
+ im->ddr.timing_cfg_2 = CFG_DDR_TIMING_2;
+ im->ddr.timing_cfg_3 = CFG_DDR_TIMING_3;
+ im->ddr.sdram_cfg = CFG_DDR_SDRAM_CFG;
+ im->ddr.sdram_cfg2 = CFG_DDR_SDRAM_CFG2;
+ im->ddr.sdram_mode = CFG_DDR_MODE;
+ im->ddr.sdram_mode2 = CFG_DDR_MODE2;
+ im->ddr.sdram_interval = CFG_DDR_INTERVAL;
+ __asm__ __volatile__ ("sync");
+ udelay(200);
+
+ im->ddr.sdram_cfg |= SDRAM_CFG_MEM_EN;
+ __asm__ __volatile__ ("sync");
+ return msize;
+}
+
+int checkboard(void)
+{
+ puts("Board: Freescale MPC832XEMDS\n");
+ return 0;
+}
+
+#if defined(CONFIG_OF_FLAT_TREE) && defined(CONFIG_OF_BOARD_SETUP)
+void
+ft_board_setup(void *blob, bd_t *bd)
+{
+ u32 *p;
+ int len;
+
+#ifdef CONFIG_PCI
+ ft_pci_setup(blob, bd);
+#endif
+ ft_cpu_setup(blob, bd);
+
+ p = ft_get_prop(blob, "/memory/reg", &len);
+ if (p != NULL) {
+ *p++ = cpu_to_be32(bd->bi_memstart);
+ *p = cpu_to_be32(bd->bi_memsize);
+ }
+}
+#endif
diff --git a/board/mpc832xemds/pci.c b/board/mpc832xemds/pci.c
new file mode 100644
index 00000000000..d0a407ae8aa
--- /dev/null
+++ b/board/mpc832xemds/pci.c
@@ -0,0 +1,316 @@
+/*
+ * Copyright (C) 2006 Freescale Semiconductor, Inc.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ */
+
+/*
+ * PCI Configuration space access support for MPC83xx PCI Bridge
+ */
+#include <asm/mmu.h>
+#include <asm/io.h>
+#include <common.h>
+#include <pci.h>
+#include <i2c.h>
+#if defined(CONFIG_OF_FLAT_TREE)
+#include <ft_build.h>
+#endif
+
+#include <asm/fsl_i2c.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#if defined(CONFIG_PCI)
+#define PCI_FUNCTION_CONFIG 0x44
+#define PCI_FUNCTION_CFG_LOCK 0x20
+
+/*
+ * Initialize PCI Devices, report devices found
+ */
+#ifndef CONFIG_PCI_PNP
+static struct pci_config_table pci_mpc83xxemds_config_table[] = {
+ {
+ PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
+ pci_cfgfunc_config_device,
+ {PCI_ENET0_IOADDR,
+ PCI_ENET0_MEMADDR,
+ PCI_COMMON_MEMORY | PCI_COMMAND_MASTER}
+ },
+ {}
+}
+#endif
+static struct pci_controller hose[] = {
+ {
+#ifndef CONFIG_PCI_PNP
+ config_table:pci_mpc83xxemds_config_table,
+#endif
+ },
+};
+
+/**********************************************************************
+ * pci_init_board()
+ *********************************************************************/
+void pci_init_board(void)
+#ifdef CONFIG_PCISLAVE
+{
+ u16 reg16;
+ volatile immap_t *immr;
+ volatile law83xx_t *pci_law;
+ volatile pot83xx_t *pci_pot;
+ volatile pcictrl83xx_t *pci_ctrl;
+ volatile pciconf83xx_t *pci_conf;
+
+ immr = (immap_t *) CFG_IMMR;
+ pci_law = immr->sysconf.pcilaw;
+ pci_pot = immr->ios.pot;
+ pci_ctrl = immr->pci_ctrl;
+ pci_conf = immr->pci_conf;
+ /*
+ * Configure PCI Inbound Translation Windows
+ */
+ pci_ctrl[0].pitar0 = 0x0;
+ pci_ctrl[0].pibar0 = 0x0;
+ pci_ctrl[0].piwar0 = PIWAR_EN | PIWAR_RTT_SNOOP |
+ PIWAR_WTT_SNOOP | PIWAR_IWS_4K;
+
+ pci_ctrl[0].pitar1 = 0x0;
+ pci_ctrl[0].pibar1 = 0x0;
+ pci_ctrl[0].piebar1 = 0x0;
+ pci_ctrl[0].piwar1 &= ~PIWAR_EN;
+
+ pci_ctrl[0].pitar2 = 0x0;
+ pci_ctrl[0].pibar2 = 0x0;
+ pci_ctrl[0].piebar2 = 0x0;
+ pci_ctrl[0].piwar2 &= ~PIWAR_EN;
+
+ hose[0].first_busno = 0;
+ hose[0].last_busno = 0xff;
+ pci_setup_indirect(&hose[0],
+ (CFG_IMMR + 0x8300), (CFG_IMMR + 0x8304));
+ reg16 = 0xff;
+
+ pci_hose_read_config_word(&hose[0], PCI_BDF(0, 0, 0),
+ PCI_COMMAND, &reg16);
+ reg16 |= PCI_COMMAND_SERR | PCI_COMMAND_MEMORY;
+ pci_hose_write_config_word(&hose[0], PCI_BDF(0, 0, 0),
+ PCI_COMMAND, reg16);
+
+ /*
+ * Clear non-reserved bits in status register.
+ */
+ pci_hose_write_config_word(&hose[0], PCI_BDF(0, 0, 0),
+ PCI_STATUS, 0xffff);
+ pci_hose_write_config_byte(&hose[0], PCI_BDF(0, 0, 0),
+ PCI_LATENCY_TIMER, 0x80);
+
+ /*
+ * Unlock configuration lock in PCI function configuration register.
+ */
+ pci_hose_read_config_word(&hose[0], PCI_BDF(0, 0, 0),
+ PCI_FUNCTION_CONFIG, &reg16);
+ reg16 &= ~(PCI_FUNCTION_CFG_LOCK);
+ pci_hose_write_config_word(&hose[0], PCI_BDF(0, 0, 0),
+ PCI_FUNCTION_CONFIG, reg16);
+
+ printf("Enabled PCI 32bit Agent Mode\n");
+}
+#else
+{
+ volatile immap_t *immr;
+ volatile clk83xx_t *clk;
+ volatile law83xx_t *pci_law;
+ volatile pot83xx_t *pci_pot;
+ volatile pcictrl83xx_t *pci_ctrl;
+ volatile pciconf83xx_t *pci_conf;
+
+ u8 val8, orig_i2c_bus;
+ u16 reg16;
+ u32 val32;
+ u32 dev;
+
+ immr = (immap_t *) CFG_IMMR;
+ clk = (clk83xx_t *) & immr->clk;
+ pci_law = immr->sysconf.pcilaw;
+ pci_pot = immr->ios.pot;
+ pci_ctrl = immr->pci_ctrl;
+ pci_conf = immr->pci_conf;
+ /*
+ * Configure PCI controller and PCI_CLK_OUTPUT both in 66M mode
+ */
+ val32 = clk->occr;
+ udelay(2000);
+#if defined(PCI_66M)
+ clk->occr = OCCR_PCICOE0 | OCCR_PCICOE1 | OCCR_PCICOE2;
+ printf("PCI clock is 66MHz\n");
+#elif defined(PCI_33M)
+ clk->occr = OCCR_PCICOE0 | OCCR_PCICOE1 | OCCR_PCICOE2 |
+ OCCR_PCICD0 | OCCR_PCICD1 | OCCR_PCICD2 | OCCR_PCICR;
+ printf("PCI clock is 33MHz\n");
+#else
+ clk->occr = OCCR_PCICOE0 | OCCR_PCICOE1 | OCCR_PCICOE2;
+ printf("PCI clock is 66MHz\n");
+#endif
+ udelay(2000);
+
+ /*
+ * Configure PCI Local Access Windows
+ */
+ pci_law[0].bar = CFG_PCI_MEM_PHYS & LAWBAR_BAR;
+ pci_law[0].ar = LAWAR_EN | LAWAR_SIZE_512M;
+
+ pci_law[1].bar = CFG_PCI_IO_PHYS & LAWBAR_BAR;
+ pci_law[1].ar = LAWAR_EN | LAWAR_SIZE_1M;
+
+ /*
+ * Configure PCI Outbound Translation Windows
+ */
+
+ /* PCI mem space - prefetch */
+ pci_pot[0].potar = (CFG_PCI_MEM_BASE >> 12) & POTAR_TA_MASK;
+ pci_pot[0].pobar = (CFG_PCI_MEM_PHYS >> 12) & POBAR_BA_MASK;
+ pci_pot[0].pocmr =
+ POCMR_EN | POCMR_SE | (POCMR_CM_256M & POCMR_CM_MASK);
+
+ /* PCI mmio - non-prefetch mem space */
+ pci_pot[1].potar = (CFG_PCI_MMIO_BASE >> 12) & POTAR_TA_MASK;
+ pci_pot[1].pobar = (CFG_PCI_MMIO_PHYS >> 12) & POBAR_BA_MASK;
+ pci_pot[1].pocmr = POCMR_EN | (POCMR_CM_256M & POCMR_CM_MASK);
+
+ /* PCI IO space */
+ pci_pot[2].potar = (CFG_PCI_IO_BASE >> 12) & POTAR_TA_MASK;
+ pci_pot[2].pobar = (CFG_PCI_IO_PHYS >> 12) & POBAR_BA_MASK;
+ pci_pot[2].pocmr = POCMR_EN | POCMR_IO | (POCMR_CM_1M & POCMR_CM_MASK);
+
+ /*
+ * Configure PCI Inbound Translation Windows
+ */
+ pci_ctrl[0].pitar1 = (CFG_PCI_SLV_MEM_LOCAL >> 12) & PITAR_TA_MASK;
+ pci_ctrl[0].pibar1 = (CFG_PCI_SLV_MEM_BUS >> 12) & PIBAR_MASK;
+ pci_ctrl[0].piebar1 = 0x0;
+ pci_ctrl[0].piwar1 =
+ PIWAR_EN | PIWAR_PF | PIWAR_RTT_SNOOP | PIWAR_WTT_SNOOP |
+ PIWAR_IWS_2G;
+
+ /*
+ * Assign PIB PMC slot to desired PCI bus
+ */
+
+ /* Switch temporarily to I2C bus #2 */
+ orig_i2c_bus = i2c_get_bus_num();
+ i2c_set_bus_num(1);
+
+ val8 = 0;
+ i2c_write(0x23, 0x6, 1, &val8, 1);
+ i2c_write(0x23, 0x7, 1, &val8, 1);
+ val8 = 0xff;
+ i2c_write(0x23, 0x2, 1, &val8, 1);
+ i2c_write(0x23, 0x3, 1, &val8, 1);
+
+ val8 = 0;
+ i2c_write(0x26, 0x6, 1, &val8, 1);
+ val8 = 0x34;
+ i2c_write(0x26, 0x7, 1, &val8, 1);
+
+ val8 = 0xf9; /* PMC2, PMC3 slot to PCI bus */
+ i2c_write(0x26, 0x2, 1, &val8, 1);
+ val8 = 0xff;
+ i2c_write(0x26, 0x3, 1, &val8, 1);
+
+ val8 = 0;
+ i2c_write(0x27, 0x6, 1, &val8, 1);
+ i2c_write(0x27, 0x7, 1, &val8, 1);
+ val8 = 0xff;
+ i2c_write(0x27, 0x2, 1, &val8, 1);
+ val8 = 0xef;
+ i2c_write(0x27, 0x3, 1, &val8, 1);
+ asm("eieio");
+
+ /* Reset to original I2C bus */
+ i2c_set_bus_num(orig_i2c_bus);
+
+ /*
+ * Release PCI RST Output signal
+ */
+ udelay(2000);
+ pci_ctrl[0].gcr = 1;
+ udelay(2000);
+
+ hose[0].first_busno = 0;
+ hose[0].last_busno = 0xff;
+
+ /* PCI memory prefetch space */
+ pci_set_region(hose[0].regions + 0,
+ CFG_PCI_MEM_BASE,
+ CFG_PCI_MEM_PHYS,
+ CFG_PCI_MEM_SIZE, PCI_REGION_MEM | PCI_REGION_PREFETCH);
+
+ /* PCI memory space */
+ pci_set_region(hose[0].regions + 1,
+ CFG_PCI_MMIO_BASE,
+ CFG_PCI_MMIO_PHYS, CFG_PCI_MMIO_SIZE, PCI_REGION_MEM);
+
+ /* PCI IO space */
+ pci_set_region(hose[0].regions + 2,
+ CFG_PCI_IO_BASE,
+ CFG_PCI_IO_PHYS, CFG_PCI_IO_SIZE, PCI_REGION_IO);
+
+ /* System memory space */
+ pci_set_region(hose[0].regions + 3,
+ CFG_PCI_SLV_MEM_LOCAL,
+ CFG_PCI_SLV_MEM_BUS,
+ CFG_PCI_SLV_MEM_SIZE,
+ PCI_REGION_MEM | PCI_REGION_MEMORY);
+
+ hose[0].region_count = 4;
+
+ pci_setup_indirect(&hose[0],
+ (CFG_IMMR + 0x8300), (CFG_IMMR + 0x8304));
+
+ pci_register_hose(hose);
+
+ /*
+ * Write command register
+ */
+ reg16 = 0xff;
+ dev = PCI_BDF(0, 0, 0);
+ pci_hose_read_config_word(&hose[0], dev, PCI_COMMAND, &reg16);
+ reg16 |= PCI_COMMAND_SERR | PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
+ pci_hose_write_config_word(&hose[0], dev, PCI_COMMAND, reg16);
+
+ /*
+ * Clear non-reserved bits in status register.
+ */
+ pci_hose_write_config_word(&hose[0], dev, PCI_STATUS, 0xffff);
+ pci_hose_write_config_byte(&hose[0], dev, PCI_LATENCY_TIMER, 0x80);
+ pci_hose_write_config_byte(&hose[0], dev, PCI_CACHE_LINE_SIZE, 0x08);
+
+ printf("PCI 32bit bus on PMC2 & PMC3\n");
+
+ /*
+ * Hose scan.
+ */
+ hose->last_busno = pci_hose_scan(hose);
+}
+#endif /* CONFIG_PCISLAVE */
+
+#ifdef CONFIG_OF_FLAT_TREE
+void
+ft_pci_setup(void *blob, bd_t *bd)
+{
+ u32 *p;
+ int len;
+
+ p = (u32 *)ft_get_prop(blob, "/" OF_SOC "/pci@8500/bus-range", &len);
+ if (p != NULL) {
+ p[0] = hose[0].first_busno;
+ p[1] = hose[0].last_busno;
+ }
+}
+#endif /* CONFIG_OF_FLAT_TREE */
+#endif /* CONFIG_PCI */
diff --git a/board/mpc832xemds/u-boot.lds b/board/mpc832xemds/u-boot.lds
new file mode 100644
index 00000000000..937c87a27cd
--- /dev/null
+++ b/board/mpc832xemds/u-boot.lds
@@ -0,0 +1,123 @@
+/*
+ * (C) Copyright 2006
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+OUTPUT_ARCH(powerpc)
+SECTIONS
+{
+ /* Read-only sections, merged into text segment: */
+ . = + SIZEOF_HEADERS;
+ .interp : { *(.interp) }
+ .hash : { *(.hash) }
+ .dynsym : { *(.dynsym) }
+ .dynstr : { *(.dynstr) }
+ .rel.text : { *(.rel.text) }
+ .rela.text : { *(.rela.text) }
+ .rel.data : { *(.rel.data) }
+ .rela.data : { *(.rela.data) }
+ .rel.rodata : { *(.rel.rodata) }
+ .rela.rodata : { *(.rela.rodata) }
+ .rel.got : { *(.rel.got) }
+ .rela.got : { *(.rela.got) }
+ .rel.ctors : { *(.rel.ctors) }
+ .rela.ctors : { *(.rela.ctors) }
+ .rel.dtors : { *(.rel.dtors) }
+ .rela.dtors : { *(.rela.dtors) }
+ .rel.bss : { *(.rel.bss) }
+ .rela.bss : { *(.rela.bss) }
+ .rel.plt : { *(.rel.plt) }
+ .rela.plt : { *(.rela.plt) }
+ .init : { *(.init) }
+ .plt : { *(.plt) }
+ .text :
+ {
+ cpu/mpc83xx/start.o (.text)
+ *(.text)
+ *(.fixup)
+ *(.got1)
+ . = ALIGN(16);
+ *(.rodata)
+ *(.rodata1)
+ *(.rodata.str1.4)
+ *(.eh_frame)
+ }
+ .fini : { *(.fini) } =0
+ .ctors : { *(.ctors) }
+ .dtors : { *(.dtors) }
+
+ /* Read-write section, merged into data segment: */
+ . = (. + 0x0FFF) & 0xFFFFF000;
+ _erotext = .;
+ PROVIDE (erotext = .);
+ .reloc :
+ {
+ *(.got)
+ _GOT2_TABLE_ = .;
+ *(.got2)
+ _FIXUP_TABLE_ = .;
+ *(.fixup)
+ }
+ __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >> 2;
+ __fixup_entries = (. - _FIXUP_TABLE_) >> 2;
+
+ .data :
+ {
+ *(.data)
+ *(.data1)
+ *(.sdata)
+ *(.sdata2)
+ *(.dynamic)
+ CONSTRUCTORS
+ }
+ _edata = .;
+ PROVIDE (edata = .);
+
+ . = .;
+ __u_boot_cmd_start = .;
+ .u_boot_cmd : { *(.u_boot_cmd) }
+ __u_boot_cmd_end = .;
+
+
+ . = .;
+ __start___ex_table = .;
+ __ex_table : { *(__ex_table) }
+ __stop___ex_table = .;
+
+ . = ALIGN(4096);
+ __init_begin = .;
+ .text.init : { *(.text.init) }
+ .data.init : { *(.data.init) }
+ . = ALIGN(4096);
+ __init_end = .;
+
+ __bss_start = .;
+ .bss :
+ {
+ *(.sbss) *(.scommon)
+ *(.dynbss)
+ *(.bss)
+ *(COMMON)
+ }
+ _end = . ;
+ PROVIDE (end = .);
+}
+ENTRY(_start)
diff --git a/board/mpc8349emds/Makefile b/board/mpc8349emds/Makefile
index acc954488f5..5ec7a871d4d 100644
--- a/board/mpc8349emds/Makefile
+++ b/board/mpc8349emds/Makefile
@@ -25,7 +25,7 @@ include $(TOPDIR)/config.mk
LIB = $(obj)lib$(BOARD).a
-COBJS := $(BOARD).o
+COBJS := $(BOARD).o pci.o
SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
OBJS := $(addprefix $(obj),$(COBJS))
diff --git a/board/mpc8349emds/mpc8349emds.c b/board/mpc8349emds/mpc8349emds.c
index b5ccb536048..071591ed835 100644
--- a/board/mpc8349emds/mpc8349emds.c
+++ b/board/mpc8349emds/mpc8349emds.c
@@ -33,6 +33,10 @@
#if defined(CONFIG_SPD_EEPROM)
#include <spd_sdram.h>
#endif
+#if defined(CONFIG_OF_FLAT_TREE)
+#include <ft_build.h>
+#endif
+
int fixed_sdram(void);
void sdram_init(void);
@@ -59,7 +63,7 @@ int board_early_init_f (void)
long int initdram (int board_type)
{
- volatile immap_t *im = (immap_t *)CFG_IMMRBAR;
+ volatile immap_t *im = (immap_t *)CFG_IMMR;
u32 msize = 0;
if ((im->sysconf.immrbar & IMMRBAR_BASE_ADDR) != (u32)im)
@@ -96,7 +100,7 @@ long int initdram (int board_type)
************************************************************************/
int fixed_sdram(void)
{
- volatile immap_t *im = (immap_t *)CFG_IMMRBAR;
+ volatile immap_t *im = (immap_t *)CFG_IMMR;
u32 msize = 0;
u32 ddr_size;
u32 ddr_size_log2;
@@ -115,6 +119,20 @@ int fixed_sdram(void)
#if (CFG_DDR_SIZE != 256)
#warning Currenly any ddr size other than 256 is not supported
#endif
+#ifdef CONFIG_DDR_II
+ im->ddr.csbnds[2].csbnds = CFG_DDR_CS2_BNDS;
+ im->ddr.cs_config[2] = CFG_DDR_CS2_CONFIG;
+ im->ddr.timing_cfg_0 = CFG_DDR_TIMING_0;
+ im->ddr.timing_cfg_1 = CFG_DDR_TIMING_1;
+ im->ddr.timing_cfg_2 = CFG_DDR_TIMING_2;
+ im->ddr.timing_cfg_3 = CFG_DDR_TIMING_3;
+ im->ddr.sdram_cfg = CFG_DDR_SDRAM_CFG;
+ im->ddr.sdram_cfg2 = CFG_DDR_SDRAM_CFG2;
+ im->ddr.sdram_mode = CFG_DDR_MODE;
+ im->ddr.sdram_mode2 = CFG_DDR_MODE2;
+ im->ddr.sdram_interval = CFG_DDR_INTERVAL;
+ im->ddr.sdram_clk_cntl = CFG_DDR_CLK_CNTL;
+#else
im->ddr.csbnds[2].csbnds = 0x0000000f;
im->ddr.cs_config[2] = CFG_DDR_CONFIG;
@@ -139,6 +157,7 @@ int fixed_sdram(void)
im->ddr.sdram_mode = CFG_DDR_MODE;
im->ddr.sdram_interval = CFG_DDR_INTERVAL;
+#endif
udelay(200);
/* enable DDR controller */
@@ -167,8 +186,8 @@ int checkboard (void)
void sdram_init(void)
{
- volatile immap_t *immap = (immap_t *)CFG_IMMRBAR;
- volatile lbus8349_t *lbc= &immap->lbus;
+ volatile immap_t *immap = (immap_t *)CFG_IMMR;
+ volatile lbus83xx_t *lbc= &immap->lbus;
uint *sdram_addr = (uint *)CFG_LBC_SDRAM_BASE;
puts("\n SDRAM on Local Bus: ");
@@ -235,7 +254,7 @@ void sdram_init(void)
#else
void sdram_init(void)
{
- put("SDRAM on Local Bus is NOT available!\n");
+ puts(" SDRAM on Local Bus is NOT available!\n");
}
#endif
@@ -245,8 +264,8 @@ void sdram_init(void)
*/
void ecc_print_status(void)
{
- volatile immap_t *immap = (immap_t *)CFG_IMMRBAR;
- volatile ddr8349_t *ddr = &immap->ddr;
+ volatile immap_t *immap = (immap_t *)CFG_IMMR;
+ volatile ddr83xx_t *ddr = &immap->ddr;
printf("\nECC mode: %s\n\n", (ddr->sdram_cfg & SDRAM_CFG_ECC_EN) ? "ON" : "OFF");
@@ -320,8 +339,8 @@ void ecc_print_status(void)
int do_ecc ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
- volatile immap_t *immap = (immap_t *)CFG_IMMRBAR;
- volatile ddr8349_t *ddr = &immap->ddr;
+ volatile immap_t *immap = (immap_t *)CFG_IMMR;
+ volatile ddr83xx_t *ddr = &immap->ddr;
volatile u32 val;
u64 *addr, count, val64;
register u64 *i;
@@ -564,3 +583,23 @@ U_BOOT_CMD(
" - re-inits memory"
);
#endif /* if defined(CONFIG_DDR_ECC) && defined(CONFIG_DDR_ECC_CMD) */
+
+#if defined(CONFIG_OF_FLAT_TREE) && defined(CONFIG_OF_BOARD_SETUP)
+void
+ft_board_setup(void *blob, bd_t *bd)
+{
+ u32 *p;
+ int len;
+
+#ifdef CONFIG_PCI
+ ft_pci_setup(blob, bd);
+#endif
+ ft_cpu_setup(blob, bd);
+
+ p = ft_get_prop(blob, "/memory/reg", &len);
+ if (p != NULL) {
+ *p++ = cpu_to_be32(bd->bi_memstart);
+ *p = cpu_to_be32(bd->bi_memsize);
+ }
+}
+#endif
diff --git a/board/mpc8349emds/pci.c b/board/mpc8349emds/pci.c
index 63e44055780..d6a12b82a49 100644
--- a/board/mpc8349emds/pci.c
+++ b/board/mpc8349emds/pci.c
@@ -68,12 +68,13 @@ static struct pci_controller pci_hose[] = {
void
pib_init(void)
{
- u8 val8;
+ u8 val8, orig_i2c_bus;
/*
* Assign PIB PMC slot to desired PCI bus
*/
- mpc8349_i2c = (i2c_t*)(CFG_IMMRBAR + CFG_I2C2_OFFSET);
- i2c_init(CFG_I2C_SPEED, CFG_I2C_SLAVE);
+ /* Switch temporarily to I2C bus #2 */
+ orig_i2c_bus = i2c_get_bus_num();
+ i2c_set_bus_num(1);
val8 = 0;
i2c_write(0x23, 0x6, 1, &val8, 1);
@@ -118,6 +119,8 @@ pib_init(void)
printf("PCI1: 32-bit on PMC1, PMC2\n");
printf("PCI2: 32-bit on PMC3\n");
#endif
+ /* Reset to original I2C bus */
+ i2c_set_bus_num(orig_i2c_bus);
}
/**************************************************************************
@@ -130,18 +133,18 @@ void
pci_init_board(void)
{
volatile immap_t * immr;
- volatile clk8349_t * clk;
- volatile law8349_t * pci_law;
- volatile pot8349_t * pci_pot;
- volatile pcictrl8349_t * pci_ctrl;
- volatile pciconf8349_t * pci_conf;
+ volatile clk83xx_t * clk;
+ volatile law83xx_t * pci_law;
+ volatile pot83xx_t * pci_pot;
+ volatile pcictrl83xx_t * pci_ctrl;
+ volatile pciconf83xx_t * pci_conf;
u16 reg16;
u32 reg32;
u32 dev;
struct pci_controller * hose;
- immr = (immap_t *)CFG_IMMRBAR;
- clk = (clk8349_t *)&immr->clk;
+ immr = (immap_t *)CFG_IMMR;
+ clk = (clk83xx_t *)&immr->clk;
pci_law = immr->sysconf.pcilaw;
pci_pot = immr->ios.pot;
pci_ctrl = immr->pci_ctrl;
@@ -254,8 +257,8 @@ pci_init_board(void)
hose->region_count = 4;
pci_setup_indirect(hose,
- (CFG_IMMRBAR+0x8300),
- (CFG_IMMRBAR+0x8304));
+ (CFG_IMMR+0x8300),
+ (CFG_IMMR+0x8304));
pci_register_hose(hose);
@@ -350,8 +353,8 @@ pci_init_board(void)
hose->region_count = 4;
pci_setup_indirect(hose,
- (CFG_IMMRBAR+0x8380),
- (CFG_IMMRBAR+0x8384));
+ (CFG_IMMR+0x8380),
+ (CFG_IMMR+0x8384));
pci_register_hose(hose);
@@ -379,4 +382,26 @@ pci_init_board(void)
}
+#ifdef CONFIG_OF_FLAT_TREE
+void
+ft_pci_setup(void *blob, bd_t *bd)
+{
+ u32 *p;
+ int len;
+
+ p = (u32 *)ft_get_prop(blob, "/" OF_SOC "/pci@8500/bus-range", &len);
+ if (p != NULL) {
+ p[0] = pci_hose[0].first_busno;
+ p[1] = pci_hose[0].last_busno;
+ }
+
+#ifdef CONFIG_MPC83XX_PCI2
+ p = (u32 *)ft_get_prop(blob, "/" OF_SOC "/pci@8600/bus-range", &len);
+ if (p != NULL) {
+ p[0] = pci_hose[1].first_busno;
+ p[1] = pci_hose[1].last_busno;
+ }
+#endif
+}
+#endif /* CONFIG_OF_FLAT_TREE */
#endif /* CONFIG_PCI */
diff --git a/board/mpc8349itx/Makefile b/board/mpc8349itx/Makefile
new file mode 100644
index 00000000000..31bcdb8642a
--- /dev/null
+++ b/board/mpc8349itx/Makefile
@@ -0,0 +1,48 @@
+#
+# Copyright (C) Freescale Semiconductor, Inc. 2006. All rights reserved.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+include $(TOPDIR)/config.mk
+
+LIB = $(obj)lib$(BOARD).a
+
+COBJS := $(BOARD).o pci.o
+
+SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(COBJS))
+SOBJS := $(addprefix $(obj),$(SOBJS))
+
+$(LIB): $(obj).depend $(OBJS)
+ $(AR) crv $@ $(OBJS)
+
+clean:
+ rm -f $(SOBJS) $(OBJS)
+
+distclean: clean
+ rm -f $(LIB) core *.bak .depend
+
+#########################################################################
+
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/board/mpc8349itx/config.mk b/board/mpc8349itx/config.mk
new file mode 100644
index 00000000000..1901fdc2cef
--- /dev/null
+++ b/board/mpc8349itx/config.mk
@@ -0,0 +1,37 @@
+#
+# Copyright (C) Freescale Semiconductor, Inc. 2006. All rights reserved.
+#
+# 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
+#
+
+#
+# MPC8349E-mITX and MPC8349E-mITX-GP
+#
+
+sinclude $(OBJTREE)/board/$(BOARDDIR)/config.tmp
+
+ifndef TEXT_BASE
+TEXT_BASE = 0xFEF00000
+endif
+
+ifneq ($(OBJTREE),$(SRCTREE))
+# We are building u-boot in a separate directory, use generated
+# .lds script from OBJTREE directory.
+LDSCRIPT := $(OBJTREE)/board/$(BOARDDIR)/u-boot.lds
+endif
diff --git a/board/mpc8349itx/mpc8349itx.c b/board/mpc8349itx/mpc8349itx.c
new file mode 100644
index 00000000000..2b3ded17629
--- /dev/null
+++ b/board/mpc8349itx/mpc8349itx.c
@@ -0,0 +1,407 @@
+/*
+ * Copyright (C) Freescale Semiconductor, Inc. 2006. All rights reserved.
+ *
+ * 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 <ioports.h>
+#include <mpc83xx.h>
+#include <i2c.h>
+#include <spd.h>
+#include <miiphy.h>
+
+#ifdef CONFIG_PCI
+#include <asm/mpc8349_pci.h>
+#include <pci.h>
+#endif
+
+#ifdef CONFIG_SPD_EEPROM
+#include <spd_sdram.h>
+#else
+#include <asm/mmu.h>
+#endif
+#if defined(CONFIG_OF_FLAT_TREE)
+#include <ft_build.h>
+#endif
+
+#ifndef CONFIG_SPD_EEPROM
+/*************************************************************************
+ * fixed sdram init -- doesn't use serial presence detect.
+ ************************************************************************/
+int fixed_sdram(void)
+{
+ volatile immap_t *im = (immap_t *) CFG_IMMR;
+ u32 ddr_size; /* The size of RAM, in bytes */
+ u32 ddr_size_log2 = 0;
+
+ for (ddr_size = CFG_DDR_SIZE * 0x100000; ddr_size > 1; ddr_size >>= 1) {
+ if (ddr_size & 1) {
+ return -1;
+ }
+ ddr_size_log2++;
+ }
+
+ im->sysconf.ddrlaw[0].ar =
+ LAWAR_EN | ((ddr_size_log2 - 1) & LAWAR_SIZE);
+ im->sysconf.ddrlaw[0].bar = (CFG_DDR_SDRAM_BASE >> 12) & 0xfffff;
+
+ /* Only one CS0 for DDR */
+ im->ddr.csbnds[0].csbnds = 0x0000000f;
+ im->ddr.cs_config[0] = CFG_DDR_CONFIG;
+
+ debug("cs0_bnds = 0x%08x\n", im->ddr.csbnds[0].csbnds);
+ debug("cs0_config = 0x%08x\n", im->ddr.cs_config[0]);
+
+ debug("DDR:bar=0x%08x\n", im->sysconf.ddrlaw[0].bar);
+ debug("DDR:ar=0x%08x\n", im->sysconf.ddrlaw[0].ar);
+
+ im->ddr.timing_cfg_1 = CFG_DDR_TIMING_1;
+ im->ddr.timing_cfg_2 = CFG_DDR_TIMING_2;/* Was "2 << TIMING_CFG2_WR_DATA_DELAY_SHIFT" */
+ im->ddr.sdram_cfg = SDRAM_CFG_SREN | SDRAM_CFG_SDRAM_TYPE_DDR;
+ im->ddr.sdram_mode =
+ (0x0000 << SDRAM_MODE_ESD_SHIFT) | (0x0032 << SDRAM_MODE_SD_SHIFT);
+ im->ddr.sdram_interval =
+ (0x0410 << SDRAM_INTERVAL_REFINT_SHIFT) | (0x0100 <<
+ SDRAM_INTERVAL_BSTOPRE_SHIFT);
+ im->ddr.sdram_clk_cntl =
+ DDR_SDRAM_CLK_CNTL_SS_EN | DDR_SDRAM_CLK_CNTL_CLK_ADJUST_05;
+
+ udelay(200);
+
+ im->ddr.sdram_cfg |= SDRAM_CFG_MEM_EN;
+
+ debug("DDR:timing_cfg_1=0x%08x\n", im->ddr.timing_cfg_1);
+ debug("DDR:timing_cfg_2=0x%08x\n", im->ddr.timing_cfg_2);
+ debug("DDR:sdram_mode=0x%08x\n", im->ddr.sdram_mode);
+ debug("DDR:sdram_interval=0x%08x\n", im->ddr.sdram_interval);
+ debug("DDR:sdram_cfg=0x%08x\n", im->ddr.sdram_cfg);
+
+ return CFG_DDR_SIZE;
+}
+#endif
+
+#ifdef CONFIG_PCI
+/*
+ * Initialize PCI Devices, report devices found
+ */
+#ifndef CONFIG_PCI_PNP
+static struct pci_config_table pci_mpc83xxmitx_config_table[] = {
+ {
+ PCI_ANY_ID,
+ PCI_ANY_ID,
+ PCI_ANY_ID,
+ PCI_ANY_ID,
+ 0x0f,
+ PCI_ANY_ID,
+ pci_cfgfunc_config_device,
+ {
+ PCI_ENET0_IOADDR,
+ PCI_ENET0_MEMADDR,
+ PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER}
+ },
+ {}
+}
+#endif
+
+volatile static struct pci_controller hose[] = {
+ {
+#ifndef CONFIG_PCI_PNP
+ config_table:pci_mpc83xxmitx_config_table,
+#endif
+ },
+ {
+#ifndef CONFIG_PCI_PNP
+ config_table:pci_mpc83xxmitx_config_table,
+#endif
+ }
+};
+#endif /* CONFIG_PCI */
+
+long int initdram(int board_type)
+{
+ volatile immap_t *im = (immap_t *) CFG_IMMR;
+ u32 msize = 0;
+#ifdef CONFIG_DDR_ECC
+ volatile ddr83xx_t *ddr = &im->ddr;
+#endif
+
+ if ((im->sysconf.immrbar & IMMRBAR_BASE_ADDR) != (u32) im)
+ return -1;
+
+ /* DDR SDRAM - Main SODIMM */
+ im->sysconf.ddrlaw[0].bar = CFG_DDR_BASE & LAWBAR_BAR;
+#ifdef CONFIG_SPD_EEPROM
+ msize = spd_sdram();
+#else
+ msize = fixed_sdram();
+#endif
+
+#ifdef CONFIG_DDR_ECC
+ if (ddr->sdram_cfg & SDRAM_CFG_ECC_EN)
+ /* Unlike every other board, on the 83xx spd_sdram() returns
+ megabytes instead of just bytes. That's why we need to
+ multiple by 1MB when calling ddr_enable_ecc(). */
+ ddr_enable_ecc(msize * 1048576);
+#endif
+
+ puts(" DDR RAM: ");
+ /* return total bus RAM size(bytes) */
+ return msize * 1024 * 1024;
+}
+
+int checkboard(void)
+{
+#ifdef CONFIG_MPC8349ITX
+ puts("Board: Freescale MPC8349E-mITX\n");
+#else
+ puts("Board: Freescale MPC8349E-mITX-GP\n");
+#endif
+
+ return 0;
+}
+
+/*
+ * Implement a work-around for a hardware problem with compact
+ * flash.
+ *
+ * Program the UPM if compact flash is enabled.
+ */
+int misc_init_f(void)
+{
+#ifdef CONFIG_VSC7385
+ volatile u32 *vsc7385_cpuctrl;
+
+ /* 0x1c0c0 is the VSC7385 CPU Control (CPUCTRL) Register. The power up
+ default of VSC7385 L1_IRQ and L2_IRQ requests are active high. That
+ means it is 0 when the IRQ is not active. This makes the wire-AND
+ logic always assert IRQ7 to CPU even if there is no request from the
+ switch. Since the compact flash and the switch share the same IRQ,
+ the Linux kernel will think that the compact flash is requesting irq
+ and get stuck when it tries to clear the IRQ. Thus we need to set
+ the L2_IRQ0 and L2_IRQ1 to active low.
+
+ The following code sets the L1_IRQ and L2_IRQ polarity to active low.
+ Without this code, compact flash will not work in Linux because
+ unlike U-Boot, Linux uses the IRQ, so this code is necessary if we
+ don't enable compact flash for U-Boot.
+ */
+
+ vsc7385_cpuctrl = (volatile u32 *)(CFG_VSC7385_BASE + 0x1c0c0);
+ *vsc7385_cpuctrl |= 0x0c;
+#endif
+
+#ifdef CONFIG_COMPACT_FLASH
+ /* UPM Table Configuration Code */
+ static uint UPMATable[] = {
+ 0xcffffc00, 0x0fffff00, 0x0fafff00, 0x0fafff00,
+ 0x0faffd00, 0x0faffc04, 0x0ffffc00, 0x3ffffc01,
+ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
+ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
+ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfff7fc00,
+ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01,
+ 0xcffffc00, 0x0fffff00, 0x0ff3ff00, 0x0ff3ff00,
+ 0x0ff3fe00, 0x0ffffc00, 0x3ffffc05, 0xfffffc00,
+ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
+ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
+ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
+ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01,
+ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
+ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
+ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01,
+ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01
+ };
+ volatile immap_t *immap = (immap_t *) CFG_IMMR;
+ volatile lbus83xx_t *lbus = &immap->lbus;
+
+ lbus->bank[3].br = CFG_BR3_PRELIM;
+ lbus->bank[3].or = CFG_OR3_PRELIM;
+
+ /* Program the MAMR. RFEN=0, OP=00, UWPL=1, AM=000, DS=01, G0CL=000,
+ GPL4=0, RLF=0001, WLF=0001, TLF=0001, MAD=000000
+ */
+ lbus->mamr = 0x08404440;
+
+ upmconfig(0, UPMATable, sizeof(UPMATable) / sizeof(UPMATable[0]));
+
+ puts("UPMA: Configured for compact flash\n");
+#endif
+
+ return 0;
+}
+
+/*
+ * Make sure the EEPROM has the HRCW correctly programmed.
+ * Make sure the RTC is correctly programmed.
+ *
+ * The MPC8349E-mITX can be configured to load the HRCW from
+ * EEPROM instead of flash. This is controlled via jumpers
+ * LGPL0, 1, and 3. Normally, these jumpers are set to 000 (all
+ * jumpered), but if they're set to 001 or 010, then the HRCW is
+ * read from the "I2C EEPROM".
+ *
+ * This function makes sure that the I2C EEPROM is programmed
+ * correctly.
+ */
+int misc_init_r(void)
+{
+ int rc = 0;
+
+#ifdef CONFIG_HARD_I2C
+
+ unsigned int orig_bus = i2c_get_bus_num();
+ u8 i2c_data;
+
+#ifdef CFG_I2C_RTC_ADDR
+ u8 ds1339_data[17];
+#endif
+
+#ifdef CFG_I2C_EEPROM_ADDR
+ static u8 eeprom_data[] = /* HRCW data */
+ {
+ 0xAA, 0x55, 0xAA, /* Preamble */
+ 0x7C, /* ACS=0, BYTE_EN=1111, CONT=1 */
+ 0x02, 0x40, /* RCWL ADDR=0x0_0900 */
+ (CFG_HRCW_LOW >> 24) & 0xFF,
+ (CFG_HRCW_LOW >> 16) & 0xFF,
+ (CFG_HRCW_LOW >> 8) & 0xFF,
+ CFG_HRCW_LOW & 0xFF,
+ 0x7C, /* ACS=0, BYTE_EN=1111, CONT=1 */
+ 0x02, 0x41, /* RCWH ADDR=0x0_0904 */
+ (CFG_HRCW_HIGH >> 24) & 0xFF,
+ (CFG_HRCW_HIGH >> 16) & 0xFF,
+ (CFG_HRCW_HIGH >> 8) & 0xFF,
+ CFG_HRCW_HIGH & 0xFF
+ };
+
+ u8 data[sizeof(eeprom_data)];
+#endif
+
+ printf("Board revision: ");
+ i2c_set_bus_num(1);
+ if (i2c_read(CFG_I2C_8574A_ADDR2, 0, 0, &i2c_data, sizeof(i2c_data)) == 0)
+ printf("%u.%u (PCF8475A)\n", (i2c_data & 0x02) >> 1, i2c_data & 0x01);
+ else if (i2c_read(CFG_I2C_8574_ADDR2, 0, 0, &i2c_data, sizeof(i2c_data)) == 0)
+ printf("%u.%u (PCF8475)\n", (i2c_data & 0x02) >> 1, i2c_data & 0x01);
+ else {
+ printf("Unknown\n");
+ rc = 1;
+ }
+
+#ifdef CFG_I2C_EEPROM_ADDR
+ i2c_set_bus_num(0);
+
+ if (i2c_read(CFG_I2C_EEPROM_ADDR, 0, 2, data, sizeof(data)) == 0) {
+ if (memcmp(data, eeprom_data, sizeof(data)) != 0) {
+ if (i2c_write
+ (CFG_I2C_EEPROM_ADDR, 0, 2, eeprom_data,
+ sizeof(eeprom_data)) != 0) {
+ puts("Failure writing the HRCW to EEPROM via I2C.\n");
+ rc = 1;
+ }
+ }
+ } else {
+ puts("Failure reading the HRCW from EEPROM via I2C.\n");
+ rc = 1;
+ }
+#endif
+
+#ifdef CFG_I2C_RTC_ADDR
+ i2c_set_bus_num(1);
+
+ if (i2c_read(CFG_I2C_RTC_ADDR, 0, 1, ds1339_data, sizeof(ds1339_data))
+ == 0) {
+
+ /* Work-around for MPC8349E-mITX bug #13601.
+ If the RTC does not contain valid register values, the DS1339
+ Linux driver will not work.
+ */
+
+ /* Make sure status register bits 6-2 are zero */
+ ds1339_data[0x0f] &= ~0x7c;
+
+ /* Check for a valid day register value */
+ ds1339_data[0x03] &= ~0xf8;
+ if (ds1339_data[0x03] == 0) {
+ ds1339_data[0x03] = 1;
+ }
+
+ /* Check for a valid date register value */
+ ds1339_data[0x04] &= ~0xc0;
+ if ((ds1339_data[0x04] == 0) ||
+ ((ds1339_data[0x04] & 0x0f) > 9) ||
+ (ds1339_data[0x04] >= 0x32)) {
+ ds1339_data[0x04] = 1;
+ }
+
+ /* Check for a valid month register value */
+ ds1339_data[0x05] &= ~0x60;
+
+ if ((ds1339_data[0x05] == 0) ||
+ ((ds1339_data[0x05] & 0x0f) > 9) ||
+ ((ds1339_data[0x05] >= 0x13)
+ && (ds1339_data[0x05] <= 0x19))) {
+ ds1339_data[0x05] = 1;
+ }
+
+ /* Enable Oscillator and rate select */
+ ds1339_data[0x0e] = 0x1c;
+
+ /* Work-around for MPC8349E-mITX bug #13330.
+ Ensure that the RTC control register contains the value 0x1c.
+ This affects SATA performance.
+ */
+
+ if (i2c_write
+ (CFG_I2C_RTC_ADDR, 0, 1, ds1339_data,
+ sizeof(ds1339_data))) {
+ puts("Failure writing to the RTC via I2C.\n");
+ rc = 1;
+ }
+ } else {
+ puts("Failure reading from the RTC via I2C.\n");
+ rc = 1;
+ }
+#endif
+
+ i2c_set_bus_num(orig_bus);
+#endif
+
+ return rc;
+}
+
+#if defined(CONFIG_OF_FLAT_TREE) && defined(CONFIG_OF_BOARD_SETUP)
+void
+ft_board_setup(void *blob, bd_t *bd)
+{
+ u32 *p;
+ int len;
+
+#ifdef CONFIG_PCI
+ ft_pci_setup(blob, bd);
+#endif
+ ft_cpu_setup(blob, bd);
+
+ p = ft_get_prop(blob, "/memory/reg", &len);
+ if (p != NULL) {
+ *p++ = cpu_to_be32(bd->bi_memstart);
+ *p = cpu_to_be32(bd->bi_memsize);
+ }
+}
+#endif
diff --git a/board/mpc8349itx/pci.c b/board/mpc8349itx/pci.c
new file mode 100644
index 00000000000..e81ad273568
--- /dev/null
+++ b/board/mpc8349itx/pci.c
@@ -0,0 +1,357 @@
+/*
+ * Copyright (C) Freescale Semiconductor, Inc. 2006. All rights reserved.
+ *
+ * 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>
+
+#ifdef CONFIG_PCI
+
+#include <asm/mmu.h>
+#include <asm/global_data.h>
+#include <pci.h>
+#include <asm/mpc8349_pci.h>
+#include <i2c.h>
+#if defined(CONFIG_OF_FLAT_TREE)
+#include <ft_build.h>
+#endif
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/* System RAM mapped to PCI space */
+#define CONFIG_PCI_SYS_MEM_BUS CFG_SDRAM_BASE
+#define CONFIG_PCI_SYS_MEM_PHYS CFG_SDRAM_BASE
+
+#ifndef CONFIG_PCI_PNP
+static struct pci_config_table pci_mpc8349itx_config_table[] = {
+ {
+ PCI_ANY_ID,
+ PCI_ANY_ID,
+ PCI_ANY_ID,
+ PCI_ANY_ID,
+ PCI_IDSEL_NUMBER,
+ PCI_ANY_ID,
+ pci_cfgfunc_config_device,
+ {
+ PCI_ENET0_IOADDR,
+ PCI_ENET0_MEMADDR,
+ PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER}
+ },
+ {}
+};
+#endif
+
+static struct pci_controller pci_hose[] = {
+ {
+#ifndef CONFIG_PCI_PNP
+ config_table:pci_mpc8349itx_config_table,
+#endif
+ },
+ {
+#ifndef CONFIG_PCI_PNP
+ config_table:pci_mpc8349itx_config_table,
+#endif
+ }
+};
+
+/**************************************************************************
+ * pci_init_board()
+ *
+ * NOTICE: PCI2 is not currently supported
+ *
+ */
+void pci_init_board(void)
+{
+ volatile immap_t *immr;
+ volatile clk83xx_t *clk;
+ volatile law83xx_t *pci_law;
+ volatile pot83xx_t *pci_pot;
+ volatile pcictrl83xx_t *pci_ctrl;
+ volatile pciconf83xx_t *pci_conf;
+ u8 reg8;
+ u16 reg16;
+ u32 reg32;
+ u32 dev;
+ struct pci_controller *hose;
+
+ immr = (immap_t *) CFG_IMMR;
+ clk = (clk83xx_t *) & immr->clk;
+ pci_law = immr->sysconf.pcilaw;
+ pci_pot = immr->ios.pot;
+ pci_ctrl = immr->pci_ctrl;
+ pci_conf = immr->pci_conf;
+
+ hose = &pci_hose[0];
+
+ /*
+ * Configure PCI controller and PCI_CLK_OUTPUT both in 66M mode
+ */
+
+ reg32 = clk->occr;
+ udelay(2000);
+
+#ifdef CONFIG_HARD_I2C
+ i2c_set_bus_num(1);
+ /* Read the PCI_M66EN jumper setting */
+ if ((i2c_read(CFG_I2C_8574_ADDR2, 0, 0, &reg8, sizeof(reg8)) == 0) ||
+ (i2c_read(CFG_I2C_8574A_ADDR2, 0, 0, &reg8, sizeof(reg8)) == 0)) {
+ if (reg8 & I2C_8574_PCI66)
+ clk->occr = 0xff000000; /* 66 MHz PCI */
+ else
+ clk->occr = 0xff600001; /* 33 MHz PCI */
+ } else {
+ clk->occr = 0xff600001; /* 33 MHz PCI */
+ }
+#else
+ clk->occr = 0xff000000; /* 66 MHz PCI */
+#endif
+
+ udelay(2000);
+
+ /*
+ * Release PCI RST Output signal
+ */
+ pci_ctrl[0].gcr = 0;
+ udelay(2000);
+ pci_ctrl[0].gcr = 1;
+
+#ifdef CONFIG_MPC83XX_PCI2
+ pci_ctrl[1].gcr = 0;
+ udelay(2000);
+ pci_ctrl[1].gcr = 1;
+#endif
+
+ /* We need to wait at least a 1sec based on PCI specs */
+ {
+ int i;
+
+ for (i = 0; i < 1000; i++)
+ udelay(1000);
+ }
+
+ /*
+ * Configure PCI Local Access Windows
+ */
+ pci_law[0].bar = CFG_PCI1_MEM_PHYS & LAWBAR_BAR;
+ pci_law[0].ar = LAWAR_EN | LAWAR_SIZE_1G;
+
+ pci_law[1].bar = CFG_PCI1_IO_PHYS & LAWBAR_BAR;
+ pci_law[1].ar = LAWAR_EN | LAWAR_SIZE_32M;
+
+ /*
+ * Configure PCI Outbound Translation Windows
+ */
+
+ /* PCI1 mem space - prefetch */
+ pci_pot[0].potar = (CFG_PCI1_MEM_BASE >> 12) & POTAR_TA_MASK;
+ pci_pot[0].pobar = (CFG_PCI1_MEM_PHYS >> 12) & POBAR_BA_MASK;
+ pci_pot[0].pocmr = POCMR_EN | POCMR_PREFETCH_EN | POCMR_CM_256M;
+
+ /* PCI1 IO space */
+ pci_pot[1].potar = (CFG_PCI1_IO_BASE >> 12) & POTAR_TA_MASK;
+ pci_pot[1].pobar = (CFG_PCI1_IO_PHYS >> 12) & POBAR_BA_MASK;
+ pci_pot[1].pocmr = POCMR_EN | POCMR_IO | POCMR_CM_16M;
+
+ /* PCI1 mmio - non-prefetch mem space */
+ pci_pot[2].potar = (CFG_PCI1_MMIO_BASE >> 12) & POTAR_TA_MASK;
+ pci_pot[2].pobar = (CFG_PCI1_MMIO_PHYS >> 12) & POBAR_BA_MASK;
+ pci_pot[2].pocmr = POCMR_EN | POCMR_CM_256M;
+
+ /*
+ * Configure PCI Inbound Translation Windows
+ */
+
+ /* we need RAM mapped to PCI space for the devices to
+ * access main memory */
+ pci_ctrl[0].pitar1 = 0x0;
+ pci_ctrl[0].pibar1 = 0x0;
+ pci_ctrl[0].piebar1 = 0x0;
+ pci_ctrl[0].piwar1 = PIWAR_EN | PIWAR_PF | PIWAR_RTT_SNOOP |
+ PIWAR_WTT_SNOOP | (__ilog2(gd->ram_size) - 1);
+
+ hose->first_busno = 0;
+ hose->last_busno = 0xff;
+
+ /* PCI memory prefetch space */
+ pci_set_region(hose->regions + 0,
+ CFG_PCI1_MEM_BASE,
+ CFG_PCI1_MEM_PHYS,
+ CFG_PCI1_MEM_SIZE, PCI_REGION_MEM | PCI_REGION_PREFETCH);
+
+ /* PCI memory space */
+ pci_set_region(hose->regions + 1,
+ CFG_PCI1_MMIO_BASE,
+ CFG_PCI1_MMIO_PHYS, CFG_PCI1_MMIO_SIZE, PCI_REGION_MEM);
+
+ /* PCI IO space */
+ pci_set_region(hose->regions + 2,
+ CFG_PCI1_IO_BASE,
+ CFG_PCI1_IO_PHYS, CFG_PCI1_IO_SIZE, PCI_REGION_IO);
+
+ /* System memory space */
+ pci_set_region(hose->regions + 3,
+ CONFIG_PCI_SYS_MEM_BUS,
+ CONFIG_PCI_SYS_MEM_PHYS,
+ gd->ram_size, PCI_REGION_MEM | PCI_REGION_MEMORY);
+
+ hose->region_count = 4;
+
+ pci_setup_indirect(hose,
+ (CFG_IMMR + 0x8300), (CFG_IMMR + 0x8304));
+
+ pci_register_hose(hose);
+
+ /*
+ * Write to Command register
+ */
+ reg16 = 0xff;
+ dev = PCI_BDF(hose->first_busno, 0, 0);
+ pci_hose_read_config_word(hose, dev, PCI_COMMAND, &reg16);
+ reg16 |= PCI_COMMAND_SERR | PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
+ pci_hose_write_config_word(hose, dev, PCI_COMMAND, reg16);
+
+ /*
+ * Clear non-reserved bits in status register.
+ */
+ pci_hose_write_config_word(hose, dev, PCI_STATUS, 0xffff);
+ pci_hose_write_config_byte(hose, dev, PCI_LATENCY_TIMER, 0x80);
+ pci_hose_write_config_byte(hose, dev, PCI_CACHE_LINE_SIZE, 0x08);
+
+#ifdef CONFIG_PCI_SCAN_SHOW
+ printf("PCI: Bus Dev VenId DevId Class Int\n");
+#endif
+ /*
+ * Hose scan.
+ */
+ hose->last_busno = pci_hose_scan(hose);
+
+#ifdef CONFIG_MPC83XX_PCI2
+ hose = &pci_hose[1];
+
+ /*
+ * Configure PCI Outbound Translation Windows
+ */
+
+ /* PCI2 mem space - prefetch */
+ pci_pot[3].potar = (CFG_PCI2_MEM_BASE >> 12) & POTAR_TA_MASK;
+ pci_pot[3].pobar = (CFG_PCI2_MEM_PHYS >> 12) & POBAR_BA_MASK;
+ pci_pot[3].pocmr = POCMR_EN | POCMR_PCI2 | POCMR_PREFETCH_EN | POCMR_CM_256M;
+
+ /* PCI2 IO space */
+ pci_pot[4].potar = (CFG_PCI2_IO_BASE >> 12) & POTAR_TA_MASK;
+ pci_pot[4].pobar = (CFG_PCI2_IO_PHYS >> 12) & POBAR_BA_MASK;
+ pci_pot[4].pocmr = POCMR_EN | POCMR_PCI2 | POCMR_IO | POCMR_CM_16M;
+
+ /* PCI2 mmio - non-prefetch mem space */
+ pci_pot[5].potar = (CFG_PCI2_MMIO_BASE >> 12) & POTAR_TA_MASK;
+ pci_pot[5].pobar = (CFG_PCI2_MMIO_PHYS >> 12) & POBAR_BA_MASK;
+ pci_pot[5].pocmr = POCMR_EN | POCMR_PCI2 | POCMR_CM_256M;
+
+ /*
+ * Configure PCI Inbound Translation Windows
+ */
+
+ /* we need RAM mapped to PCI space for the devices to
+ * access main memory */
+ pci_ctrl[1].pitar1 = 0x0;
+ pci_ctrl[1].pibar1 = 0x0;
+ pci_ctrl[1].piebar1 = 0x0;
+ pci_ctrl[1].piwar1 =
+ PIWAR_EN | PIWAR_PF | PIWAR_RTT_SNOOP | PIWAR_WTT_SNOOP |
+ (__ilog2(gd->ram_size) - 1);
+
+ hose->first_busno = pci_hose[0].last_busno + 1;
+ hose->last_busno = 0xff;
+
+ /* PCI memory prefetch space */
+ pci_set_region(hose->regions + 0,
+ CFG_PCI2_MEM_BASE,
+ CFG_PCI2_MEM_PHYS,
+ CFG_PCI2_MEM_SIZE, PCI_REGION_MEM | PCI_REGION_PREFETCH);
+
+ /* PCI memory space */
+ pci_set_region(hose->regions + 1,
+ CFG_PCI2_MMIO_BASE,
+ CFG_PCI2_MMIO_PHYS, CFG_PCI2_MMIO_SIZE, PCI_REGION_MEM);
+
+ /* PCI IO space */
+ pci_set_region(hose->regions + 2,
+ CFG_PCI2_IO_BASE,
+ CFG_PCI2_IO_PHYS, CFG_PCI2_IO_SIZE, PCI_REGION_IO);
+
+ /* System memory space */
+ pci_set_region(hose->regions + 3,
+ CONFIG_PCI_SYS_MEM_BUS,
+ CONFIG_PCI_SYS_MEM_PHYS,
+ gd->ram_size, PCI_REGION_MEM | PCI_REGION_MEMORY);
+
+ hose->region_count = 4;
+
+ pci_setup_indirect(hose,
+ (CFG_IMMR + 0x8380), (CFG_IMMR + 0x8384));
+
+ pci_register_hose(hose);
+
+ /*
+ * Write to Command register
+ */
+ reg16 = 0xff;
+ dev = PCI_BDF(hose->first_busno, 0, 0);
+ pci_hose_read_config_word(hose, dev, PCI_COMMAND, &reg16);
+ reg16 |= PCI_COMMAND_SERR | PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
+ pci_hose_write_config_word(hose, dev, PCI_COMMAND, reg16);
+
+ /*
+ * Clear non-reserved bits in status register.
+ */
+ pci_hose_write_config_word(hose, dev, PCI_STATUS, 0xffff);
+ pci_hose_write_config_byte(hose, dev, PCI_LATENCY_TIMER, 0x80);
+ pci_hose_write_config_byte(hose, dev, PCI_CACHE_LINE_SIZE, 0x08);
+
+ /*
+ * Hose scan.
+ */
+ hose->last_busno = pci_hose_scan(hose);
+#endif
+}
+
+#endif /* CONFIG_PCI */
+#ifdef CONFIG_OF_FLAT_TREE
+void
+ft_pci_setup(void *blob, bd_t *bd)
+{
+ u32 *p;
+ int len;
+
+ p = (u32 *)ft_get_prop(blob, "/" OF_SOC "/pci@8500/bus-range", &len);
+ if (p != NULL) {
+ p[0] = pci_hose[0].first_busno;
+ p[1] = pci_hose[0].last_busno;
+ }
+
+#ifdef CONFIG_MPC83XX_PCI2
+ p = (u32 *)ft_get_prop(blob, "/" OF_SOC "/pci@8600/bus-range", &len);
+ if (p != NULL) {
+ p[0] = pci_hose[1].first_busno;
+ p[1] = pci_hose[1].last_busno;
+ }
+#endif
+}
+#endif /* CONFIG_OF_FLAT_TREE */
diff --git a/board/mpc8349itx/u-boot.lds b/board/mpc8349itx/u-boot.lds
new file mode 100644
index 00000000000..f044c0f00e1
--- /dev/null
+++ b/board/mpc8349itx/u-boot.lds
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) Freescale Semiconductor, Inc. 2006. All rights reserved.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+OUTPUT_ARCH(powerpc)
+SECTIONS
+{
+ /* Read-only sections, merged into text segment: */
+ . = + SIZEOF_HEADERS;
+ .interp : { *(.interp) }
+ .hash : { *(.hash) }
+ .dynsym : { *(.dynsym) }
+ .dynstr : { *(.dynstr) }
+ .rel.text : { *(.rel.text) }
+ .rela.text : { *(.rela.text) }
+ .rel.data : { *(.rel.data) }
+ .rela.data : { *(.rela.data) }
+ .rel.rodata : { *(.rel.rodata) }
+ .rela.rodata : { *(.rela.rodata) }
+ .rel.got : { *(.rel.got) }
+ .rela.got : { *(.rela.got) }
+ .rel.ctors : { *(.rel.ctors) }
+ .rela.ctors : { *(.rela.ctors) }
+ .rel.dtors : { *(.rel.dtors) }
+ .rela.dtors : { *(.rela.dtors) }
+ .rel.bss : { *(.rel.bss) }
+ .rela.bss : { *(.rela.bss) }
+ .rel.plt : { *(.rel.plt) }
+ .rela.plt : { *(.rela.plt) }
+ .init : { *(.init) }
+ .plt : { *(.plt) }
+ .text :
+ {
+ cpu/mpc83xx/start.o (.text)
+ *(.text)
+ *(.fixup)
+ *(.got1)
+ . = ALIGN(16);
+ *(.rodata)
+ *(.rodata1)
+ *(.rodata.str1.4)
+ }
+ .fini : { *(.fini) } =0
+ .ctors : { *(.ctors) }
+ .dtors : { *(.dtors) }
+
+ /* Read-write section, merged into data segment: */
+ . = (. + 0x0FFF) & 0xFFFFF000;
+ _erotext = .;
+ PROVIDE (erotext = .);
+ .reloc :
+ {
+ *(.got)
+ _GOT2_TABLE_ = .;
+ *(.got2)
+ _FIXUP_TABLE_ = .;
+ *(.fixup)
+ }
+ __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >> 2;
+ __fixup_entries = (. - _FIXUP_TABLE_) >> 2;
+
+ .data :
+ {
+ *(.data)
+ *(.data1)
+ *(.sdata)
+ *(.sdata2)
+ *(.dynamic)
+ CONSTRUCTORS
+ }
+ _edata = .;
+ PROVIDE (edata = .);
+
+ . = .;
+ __u_boot_cmd_start = .;
+ .u_boot_cmd : { *(.u_boot_cmd) }
+ __u_boot_cmd_end = .;
+
+ . = .;
+ __start___ex_table = .;
+ __ex_table : { *(__ex_table) }
+ __stop___ex_table = .;
+
+ . = ALIGN(4096);
+ __init_begin = .;
+ .text.init : { *(.text.init) }
+ .data.init : { *(.data.init) }
+ . = ALIGN(4096);
+ __init_end = .;
+
+ __bss_start = .;
+ .bss :
+ {
+ *(.sbss) *(.scommon)
+ *(.dynbss)
+ *(.bss)
+ *(COMMON)
+ }
+ _end = . ;
+ PROVIDE (end = .);
+}
+ENTRY(_start)
diff --git a/board/mpc8360emds/Makefile b/board/mpc8360emds/Makefile
new file mode 100644
index 00000000000..5ec7a871d4d
--- /dev/null
+++ b/board/mpc8360emds/Makefile
@@ -0,0 +1,50 @@
+#
+# (C) Copyright 2006
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+include $(TOPDIR)/config.mk
+
+LIB = $(obj)lib$(BOARD).a
+
+COBJS := $(BOARD).o pci.o
+
+SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(COBJS))
+SOBJS := $(addprefix $(obj),$(SOBJS))
+
+$(LIB): $(obj).depend $(OBJS)
+ $(AR) $(ARFLAGS) $@ $(OBJS)
+
+clean:
+ rm -f $(SOBJS) $(OBJS)
+
+distclean: clean
+ rm -f $(LIB) core *.bak .depend
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/board/ezkit533/config.mk b/board/mpc8360emds/config.mk
index 36c9f997dde..9ace8860cfd 100644
--- a/board/ezkit533/config.mk
+++ b/board/mpc8360emds/config.mk
@@ -1,5 +1,5 @@
#
-# (C) Copyright 2001
+# (C) Copyright 2006
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
#
# See file CREDITS for list of people who contributed to this
@@ -21,5 +21,8 @@
# MA 02111-1307 USA
#
-TEXT_BASE = 0x01FC0000
-PLATFORM_CPPFLAGS += -I$(TOPDIR)
+#
+# MPC8360EMDS
+#
+
+TEXT_BASE = 0xFE000000
diff --git a/board/mpc8360emds/mpc8360emds.c b/board/mpc8360emds/mpc8360emds.c
new file mode 100644
index 00000000000..535884cb509
--- /dev/null
+++ b/board/mpc8360emds/mpc8360emds.c
@@ -0,0 +1,679 @@
+/*
+ * Copyright (C) 2006 Freescale Semiconductor, Inc.
+ *
+ * Dave Liu <daveliu@freescale.com>
+ * based on board/mpc8349emds/mpc8349emds.c
+ *
+ * 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.
+ */
+
+#include <common.h>
+#include <ioports.h>
+#include <mpc83xx.h>
+#include <i2c.h>
+#include <spd.h>
+#include <miiphy.h>
+#include <command.h>
+#if defined(CONFIG_PCI)
+#include <pci.h>
+#endif
+#if defined(CONFIG_SPD_EEPROM)
+#include <spd_sdram.h>
+#else
+#include <asm/mmu.h>
+#endif
+#if defined(CONFIG_OF_FLAT_TREE)
+#include <ft_build.h>
+#endif
+
+const qe_iop_conf_t qe_iop_conf_tab[] = {
+ /* GETH1 */
+ {0, 3, 1, 0, 1}, /* TxD0 */
+ {0, 4, 1, 0, 1}, /* TxD1 */
+ {0, 5, 1, 0, 1}, /* TxD2 */
+ {0, 6, 1, 0, 1}, /* TxD3 */
+ {1, 6, 1, 0, 3}, /* TxD4 */
+ {1, 7, 1, 0, 1}, /* TxD5 */
+ {1, 9, 1, 0, 2}, /* TxD6 */
+ {1, 10, 1, 0, 2}, /* TxD7 */
+ {0, 9, 2, 0, 1}, /* RxD0 */
+ {0, 10, 2, 0, 1}, /* RxD1 */
+ {0, 11, 2, 0, 1}, /* RxD2 */
+ {0, 12, 2, 0, 1}, /* RxD3 */
+ {0, 13, 2, 0, 1}, /* RxD4 */
+ {1, 1, 2, 0, 2}, /* RxD5 */
+ {1, 0, 2, 0, 2}, /* RxD6 */
+ {1, 4, 2, 0, 2}, /* RxD7 */
+ {0, 7, 1, 0, 1}, /* TX_EN */
+ {0, 8, 1, 0, 1}, /* TX_ER */
+ {0, 15, 2, 0, 1}, /* RX_DV */
+ {0, 16, 2, 0, 1}, /* RX_ER */
+ {0, 0, 2, 0, 1}, /* RX_CLK */
+ {2, 9, 1, 0, 3}, /* GTX_CLK - CLK10 */
+ {2, 8, 2, 0, 1}, /* GTX125 - CLK9 */
+ /* GETH2 */
+ {0, 17, 1, 0, 1}, /* TxD0 */
+ {0, 18, 1, 0, 1}, /* TxD1 */
+ {0, 19, 1, 0, 1}, /* TxD2 */
+ {0, 20, 1, 0, 1}, /* TxD3 */
+ {1, 2, 1, 0, 1}, /* TxD4 */
+ {1, 3, 1, 0, 2}, /* TxD5 */
+ {1, 5, 1, 0, 3}, /* TxD6 */
+ {1, 8, 1, 0, 3}, /* TxD7 */
+ {0, 23, 2, 0, 1}, /* RxD0 */
+ {0, 24, 2, 0, 1}, /* RxD1 */
+ {0, 25, 2, 0, 1}, /* RxD2 */
+ {0, 26, 2, 0, 1}, /* RxD3 */
+ {0, 27, 2, 0, 1}, /* RxD4 */
+ {1, 12, 2, 0, 2}, /* RxD5 */
+ {1, 13, 2, 0, 3}, /* RxD6 */
+ {1, 11, 2, 0, 2}, /* RxD7 */
+ {0, 21, 1, 0, 1}, /* TX_EN */
+ {0, 22, 1, 0, 1}, /* TX_ER */
+ {0, 29, 2, 0, 1}, /* RX_DV */
+ {0, 30, 2, 0, 1}, /* RX_ER */
+ {0, 31, 2, 0, 1}, /* RX_CLK */
+ {2, 2, 1, 0, 2}, /* GTX_CLK = CLK10 */
+ {2, 3, 2, 0, 1}, /* GTX125 - CLK4 */
+
+ {0, 1, 3, 0, 2}, /* MDIO */
+ {0, 2, 1, 0, 1}, /* MDC */
+
+ {0, 0, 0, 0, QE_IOP_TAB_END}, /* END of table */
+};
+
+int board_early_init_f(void)
+{
+
+ u8 *bcsr = (u8 *)CFG_BCSR;
+ const immap_t *immr = (immap_t *)CFG_IMMR;
+
+ /* Enable flash write */
+ bcsr[0xa] &= ~0x04;
+
+ /* Disable G1TXCLK, G2TXCLK h/w buffers (rev.2 h/w bug workaround) */
+ if (immr->sysconf.spridr == SPR_8360_REV20 ||
+ immr->sysconf.spridr == SPR_8360E_REV20)
+ bcsr[0xe] = 0x30;
+
+ return 0;
+}
+
+#if defined(CONFIG_DDR_ECC) && !defined(CONFIG_ECC_INIT_VIA_DDRC)
+extern void ddr_enable_ecc(unsigned int dram_size);
+#endif
+int fixed_sdram(void);
+void sdram_init(void);
+
+long int initdram(int board_type)
+{
+ volatile immap_t *im = (immap_t *) CFG_IMMR;
+ u32 msize = 0;
+
+ if ((im->sysconf.immrbar & IMMRBAR_BASE_ADDR) != (u32) im)
+ return -1;
+
+ /* DDR SDRAM - Main SODIMM */
+ im->sysconf.ddrlaw[0].bar = CFG_DDR_BASE & LAWBAR_BAR;
+#if defined(CONFIG_SPD_EEPROM)
+ msize = spd_sdram();
+#else
+ msize = fixed_sdram();
+#endif
+
+#if defined(CONFIG_DDR_ECC) && !defined(CONFIG_ECC_INIT_VIA_DDRC)
+ /*
+ * Initialize DDR ECC byte
+ */
+ ddr_enable_ecc(msize * 1024 * 1024);
+#endif
+ /*
+ * Initialize SDRAM if it is on local bus.
+ */
+ sdram_init();
+ puts(" DDR RAM: ");
+ /* return total bus SDRAM size(bytes) -- DDR */
+ return (msize * 1024 * 1024);
+}
+
+#if !defined(CONFIG_SPD_EEPROM)
+/*************************************************************************
+ * fixed sdram init -- doesn't use serial presence detect.
+ ************************************************************************/
+int fixed_sdram(void)
+{
+ volatile immap_t *im = (immap_t *) CFG_IMMR;
+ u32 msize = 0;
+ u32 ddr_size;
+ u32 ddr_size_log2;
+
+ msize = CFG_DDR_SIZE;
+ for (ddr_size = msize << 20, ddr_size_log2 = 0;
+ (ddr_size > 1); ddr_size = ddr_size >> 1, ddr_size_log2++) {
+ if (ddr_size & 1) {
+ return -1;
+ }
+ }
+ im->sysconf.ddrlaw[0].ar =
+ LAWAR_EN | ((ddr_size_log2 - 1) & LAWAR_SIZE);
+#if (CFG_DDR_SIZE != 256)
+#warning Currenly any ddr size other than 256 is not supported
+#endif
+#ifdef CONFIG_DDR_II
+ im->ddr.csbnds[0].csbnds = CFG_DDR_CS0_BNDS;
+ im->ddr.cs_config[0] = CFG_DDR_CS0_CONFIG;
+ im->ddr.timing_cfg_0 = CFG_DDR_TIMING_0;
+ im->ddr.timing_cfg_1 = CFG_DDR_TIMING_1;
+ im->ddr.timing_cfg_2 = CFG_DDR_TIMING_2;
+ im->ddr.timing_cfg_3 = CFG_DDR_TIMING_3;
+ im->ddr.sdram_cfg = CFG_DDR_SDRAM_CFG;
+ im->ddr.sdram_cfg2 = CFG_DDR_SDRAM_CFG2;
+ im->ddr.sdram_mode = CFG_DDR_MODE;
+ im->ddr.sdram_mode2 = CFG_DDR_MODE2;
+ im->ddr.sdram_interval = CFG_DDR_INTERVAL;
+ im->ddr.sdram_clk_cntl = CFG_DDR_CLK_CNTL;
+#else
+ im->ddr.csbnds[0].csbnds = 0x00000007;
+ im->ddr.csbnds[1].csbnds = 0x0008000f;
+
+ im->ddr.cs_config[0] = CFG_DDR_CONFIG;
+ im->ddr.cs_config[1] = CFG_DDR_CONFIG;
+
+ im->ddr.timing_cfg_1 = CFG_DDR_TIMING_1;
+ im->ddr.timing_cfg_2 = CFG_DDR_TIMING_2;
+ im->ddr.sdram_cfg = CFG_DDR_CONTROL;
+
+ im->ddr.sdram_mode = CFG_DDR_MODE;
+ im->ddr.sdram_interval = CFG_DDR_INTERVAL;
+#endif
+ udelay(200);
+ im->ddr.sdram_cfg |= SDRAM_CFG_MEM_EN;
+
+ return msize;
+}
+#endif /*!CFG_SPD_EEPROM */
+
+int checkboard(void)
+{
+ puts("Board: Freescale MPC8360EMDS\n");
+ return 0;
+}
+
+/*
+ * if MPC8360EMDS is soldered with SDRAM
+ */
+#if defined(CFG_BR2_PRELIM) \
+ && defined(CFG_OR2_PRELIM) \
+ && defined(CFG_LBLAWBAR2_PRELIM) \
+ && defined(CFG_LBLAWAR2_PRELIM)
+/*
+ * Initialize SDRAM memory on the Local Bus.
+ */
+
+void sdram_init(void)
+{
+ volatile immap_t *immap = (immap_t *) CFG_IMMR;
+ volatile lbus83xx_t *lbc = &immap->lbus;
+ uint *sdram_addr = (uint *) CFG_LBC_SDRAM_BASE;
+
+ puts("\n SDRAM on Local Bus: ");
+ print_size(CFG_LBC_SDRAM_SIZE * 1024 * 1024, "\n");
+ /*
+ * Setup SDRAM Base and Option Registers, already done in cpu_init.c
+ */
+ /*setup mtrpt, lsrt and lbcr for LB bus */
+ lbc->lbcr = CFG_LBC_LBCR;
+ lbc->mrtpr = CFG_LBC_MRTPR;
+ lbc->lsrt = CFG_LBC_LSRT;
+ asm("sync");
+
+ /*
+ * Configure the SDRAM controller Machine Mode Register.
+ */
+ lbc->lsdmr = CFG_LBC_LSDMR_5; /* Normal Operation */
+ lbc->lsdmr = CFG_LBC_LSDMR_1; /* Precharge All Banks */
+ asm("sync");
+ *sdram_addr = 0xff;
+ udelay(100);
+
+ /*
+ * We need do 8 times auto refresh operation.
+ */
+ lbc->lsdmr = CFG_LBC_LSDMR_2;
+ asm("sync");
+ *sdram_addr = 0xff; /* 1 times */
+ udelay(100);
+ *sdram_addr = 0xff; /* 2 times */
+ udelay(100);
+ *sdram_addr = 0xff; /* 3 times */
+ udelay(100);
+ *sdram_addr = 0xff; /* 4 times */
+ udelay(100);
+ *sdram_addr = 0xff; /* 5 times */
+ udelay(100);
+ *sdram_addr = 0xff; /* 6 times */
+ udelay(100);
+ *sdram_addr = 0xff; /* 7 times */
+ udelay(100);
+ *sdram_addr = 0xff; /* 8 times */
+ udelay(100);
+
+ /* Mode register write operation */
+ lbc->lsdmr = CFG_LBC_LSDMR_4;
+ asm("sync");
+ *(sdram_addr + 0xcc) = 0xff;
+ udelay(100);
+
+ /* Normal operation */
+ lbc->lsdmr = CFG_LBC_LSDMR_5 | 0x40000000;
+ asm("sync");
+ *sdram_addr = 0xff;
+ udelay(100);
+}
+#else
+void sdram_init(void)
+{
+ puts("SDRAM on Local Bus is NOT available!\n");
+}
+#endif
+
+#if defined(CONFIG_DDR_ECC) && defined(CONFIG_DDR_ECC_CMD)
+/*
+ * ECC user commands
+ */
+void ecc_print_status(void)
+{
+ volatile immap_t *immap = (immap_t *) CFG_IMMR;
+ volatile ddr83xx_t *ddr = &immap->ddr;
+
+ printf("\nECC mode: %s\n\n",
+ (ddr->sdram_cfg & SDRAM_CFG_ECC_EN) ? "ON" : "OFF");
+
+ /* Interrupts */
+ printf("Memory Error Interrupt Enable:\n");
+ printf(" Multiple-Bit Error Interrupt Enable: %d\n",
+ (ddr->err_int_en & ECC_ERR_INT_EN_MBEE) ? 1 : 0);
+ printf(" Single-Bit Error Interrupt Enable: %d\n",
+ (ddr->err_int_en & ECC_ERR_INT_EN_SBEE) ? 1 : 0);
+ printf(" Memory Select Error Interrupt Enable: %d\n\n",
+ (ddr->err_int_en & ECC_ERR_INT_EN_MSEE) ? 1 : 0);
+
+ /* Error disable */
+ printf("Memory Error Disable:\n");
+ printf(" Multiple-Bit Error Disable: %d\n",
+ (ddr->err_disable & ECC_ERROR_DISABLE_MBED) ? 1 : 0);
+ printf(" Sinle-Bit Error Disable: %d\n",
+ (ddr->err_disable & ECC_ERROR_DISABLE_SBED) ? 1 : 0);
+ printf(" Memory Select Error Disable: %d\n\n",
+ (ddr->err_disable & ECC_ERROR_DISABLE_MSED) ? 1 : 0);
+
+ /* Error injection */
+ printf("Memory Data Path Error Injection Mask High/Low: %08lx %08lx\n",
+ ddr->data_err_inject_hi, ddr->data_err_inject_lo);
+
+ printf("Memory Data Path Error Injection Mask ECC:\n");
+ printf(" ECC Mirror Byte: %d\n",
+ (ddr->ecc_err_inject & ECC_ERR_INJECT_EMB) ? 1 : 0);
+ printf(" ECC Injection Enable: %d\n",
+ (ddr->ecc_err_inject & ECC_ERR_INJECT_EIEN) ? 1 : 0);
+ printf(" ECC Error Injection Mask: 0x%02x\n\n",
+ ddr->ecc_err_inject & ECC_ERR_INJECT_EEIM);
+
+ /* SBE counter/threshold */
+ printf("Memory Single-Bit Error Management (0..255):\n");
+ printf(" Single-Bit Error Threshold: %d\n",
+ (ddr->err_sbe & ECC_ERROR_MAN_SBET) >> ECC_ERROR_MAN_SBET_SHIFT);
+ printf(" Single-Bit Error Counter: %d\n\n",
+ (ddr->err_sbe & ECC_ERROR_MAN_SBEC) >> ECC_ERROR_MAN_SBEC_SHIFT);
+
+ /* Error detect */
+ printf("Memory Error Detect:\n");
+ printf(" Multiple Memory Errors: %d\n",
+ (ddr->err_detect & ECC_ERROR_DETECT_MME) ? 1 : 0);
+ printf(" Multiple-Bit Error: %d\n",
+ (ddr->err_detect & ECC_ERROR_DETECT_MBE) ? 1 : 0);
+ printf(" Single-Bit Error: %d\n",
+ (ddr->err_detect & ECC_ERROR_DETECT_SBE) ? 1 : 0);
+ printf(" Memory Select Error: %d\n\n",
+ (ddr->err_detect & ECC_ERROR_DETECT_MSE) ? 1 : 0);
+
+ /* Capture data */
+ printf("Memory Error Address Capture: 0x%08lx\n", ddr->capture_address);
+ printf("Memory Data Path Read Capture High/Low: %08lx %08lx\n",
+ ddr->capture_data_hi, ddr->capture_data_lo);
+ printf("Memory Data Path Read Capture ECC: 0x%02x\n\n",
+ ddr->capture_ecc & CAPTURE_ECC_ECE);
+
+ printf("Memory Error Attributes Capture:\n");
+ printf(" Data Beat Number: %d\n",
+ (ddr->capture_attributes & ECC_CAPT_ATTR_BNUM) >>
+ ECC_CAPT_ATTR_BNUM_SHIFT);
+ printf(" Transaction Size: %d\n",
+ (ddr->capture_attributes & ECC_CAPT_ATTR_TSIZ) >>
+ ECC_CAPT_ATTR_TSIZ_SHIFT);
+ printf(" Transaction Source: %d\n",
+ (ddr->capture_attributes & ECC_CAPT_ATTR_TSRC) >>
+ ECC_CAPT_ATTR_TSRC_SHIFT);
+ printf(" Transaction Type: %d\n",
+ (ddr->capture_attributes & ECC_CAPT_ATTR_TTYP) >>
+ ECC_CAPT_ATTR_TTYP_SHIFT);
+ printf(" Error Information Valid: %d\n\n",
+ ddr->capture_attributes & ECC_CAPT_ATTR_VLD);
+}
+
+int do_ecc(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
+{
+ volatile immap_t *immap = (immap_t *) CFG_IMMR;
+ volatile ddr83xx_t *ddr = &immap->ddr;
+ volatile u32 val;
+ u64 *addr;
+ u32 count;
+ register u64 *i;
+ u32 ret[2];
+ u32 pattern[2];
+ u32 writeback[2];
+
+ /* The pattern is written into memory to generate error */
+ pattern[0] = 0xfedcba98UL;
+ pattern[1] = 0x76543210UL;
+
+ /* After injecting error, re-initialize the memory with the value */
+ writeback[0] = 0x01234567UL;
+ writeback[1] = 0x89abcdefUL;
+
+ if (argc > 4) {
+ printf("Usage:\n%s\n", cmdtp->usage);
+ return 1;
+ }
+
+ if (argc == 2) {
+ if (strcmp(argv[1], "status") == 0) {
+ ecc_print_status();
+ return 0;
+ } else if (strcmp(argv[1], "captureclear") == 0) {
+ ddr->capture_address = 0;
+ ddr->capture_data_hi = 0;
+ ddr->capture_data_lo = 0;
+ ddr->capture_ecc = 0;
+ ddr->capture_attributes = 0;
+ return 0;
+ }
+ }
+ if (argc == 3) {
+ if (strcmp(argv[1], "sbecnt") == 0) {
+ val = simple_strtoul(argv[2], NULL, 10);
+ if (val > 255) {
+ printf("Incorrect Counter value, "
+ "should be 0..255\n");
+ return 1;
+ }
+
+ val = (val << ECC_ERROR_MAN_SBEC_SHIFT);
+ val |= (ddr->err_sbe & ECC_ERROR_MAN_SBET);
+
+ ddr->err_sbe = val;
+ return 0;
+ } else if (strcmp(argv[1], "sbethr") == 0) {
+ val = simple_strtoul(argv[2], NULL, 10);
+ if (val > 255) {
+ printf("Incorrect Counter value, "
+ "should be 0..255\n");
+ return 1;
+ }
+
+ val = (val << ECC_ERROR_MAN_SBET_SHIFT);
+ val |= (ddr->err_sbe & ECC_ERROR_MAN_SBEC);
+
+ ddr->err_sbe = val;
+ return 0;
+ } else if (strcmp(argv[1], "errdisable") == 0) {
+ val = ddr->err_disable;
+
+ if (strcmp(argv[2], "+sbe") == 0) {
+ val |= ECC_ERROR_DISABLE_SBED;
+ } else if (strcmp(argv[2], "+mbe") == 0) {
+ val |= ECC_ERROR_DISABLE_MBED;
+ } else if (strcmp(argv[2], "+mse") == 0) {
+ val |= ECC_ERROR_DISABLE_MSED;
+ } else if (strcmp(argv[2], "+all") == 0) {
+ val |= (ECC_ERROR_DISABLE_SBED |
+ ECC_ERROR_DISABLE_MBED |
+ ECC_ERROR_DISABLE_MSED);
+ } else if (strcmp(argv[2], "-sbe") == 0) {
+ val &= ~ECC_ERROR_DISABLE_SBED;
+ } else if (strcmp(argv[2], "-mbe") == 0) {
+ val &= ~ECC_ERROR_DISABLE_MBED;
+ } else if (strcmp(argv[2], "-mse") == 0) {
+ val &= ~ECC_ERROR_DISABLE_MSED;
+ } else if (strcmp(argv[2], "-all") == 0) {
+ val &= ~(ECC_ERROR_DISABLE_SBED |
+ ECC_ERROR_DISABLE_MBED |
+ ECC_ERROR_DISABLE_MSED);
+ } else {
+ printf("Incorrect err_disable field\n");
+ return 1;
+ }
+
+ ddr->err_disable = val;
+ __asm__ __volatile__("sync");
+ __asm__ __volatile__("isync");
+ return 0;
+ } else if (strcmp(argv[1], "errdetectclr") == 0) {
+ val = ddr->err_detect;
+
+ if (strcmp(argv[2], "mme") == 0) {
+ val |= ECC_ERROR_DETECT_MME;
+ } else if (strcmp(argv[2], "sbe") == 0) {
+ val |= ECC_ERROR_DETECT_SBE;
+ } else if (strcmp(argv[2], "mbe") == 0) {
+ val |= ECC_ERROR_DETECT_MBE;
+ } else if (strcmp(argv[2], "mse") == 0) {
+ val |= ECC_ERROR_DETECT_MSE;
+ } else if (strcmp(argv[2], "all") == 0) {
+ val |= (ECC_ERROR_DETECT_MME |
+ ECC_ERROR_DETECT_MBE |
+ ECC_ERROR_DETECT_SBE |
+ ECC_ERROR_DETECT_MSE);
+ } else {
+ printf("Incorrect err_detect field\n");
+ return 1;
+ }
+
+ ddr->err_detect = val;
+ return 0;
+ } else if (strcmp(argv[1], "injectdatahi") == 0) {
+ val = simple_strtoul(argv[2], NULL, 16);
+
+ ddr->data_err_inject_hi = val;
+ return 0;
+ } else if (strcmp(argv[1], "injectdatalo") == 0) {
+ val = simple_strtoul(argv[2], NULL, 16);
+
+ ddr->data_err_inject_lo = val;
+ return 0;
+ } else if (strcmp(argv[1], "injectecc") == 0) {
+ val = simple_strtoul(argv[2], NULL, 16);
+ if (val > 0xff) {
+ printf("Incorrect ECC inject mask, "
+ "should be 0x00..0xff\n");
+ return 1;
+ }
+ val |= (ddr->ecc_err_inject & ~ECC_ERR_INJECT_EEIM);
+
+ ddr->ecc_err_inject = val;
+ return 0;
+ } else if (strcmp(argv[1], "inject") == 0) {
+ val = ddr->ecc_err_inject;
+
+ if (strcmp(argv[2], "en") == 0)
+ val |= ECC_ERR_INJECT_EIEN;
+ else if (strcmp(argv[2], "dis") == 0)
+ val &= ~ECC_ERR_INJECT_EIEN;
+ else
+ printf("Incorrect command\n");
+
+ ddr->ecc_err_inject = val;
+ __asm__ __volatile__("sync");
+ __asm__ __volatile__("isync");
+ return 0;
+ } else if (strcmp(argv[1], "mirror") == 0) {
+ val = ddr->ecc_err_inject;
+
+ if (strcmp(argv[2], "en") == 0)
+ val |= ECC_ERR_INJECT_EMB;
+ else if (strcmp(argv[2], "dis") == 0)
+ val &= ~ECC_ERR_INJECT_EMB;
+ else
+ printf("Incorrect command\n");
+
+ ddr->ecc_err_inject = val;
+ return 0;
+ }
+ }
+ if (argc == 4) {
+ if (strcmp(argv[1], "testdw") == 0) {
+ addr = (u64 *) simple_strtoul(argv[2], NULL, 16);
+ count = simple_strtoul(argv[3], NULL, 16);
+
+ if ((u32) addr % 8) {
+ printf("Address not alligned on "
+ "double word boundary\n");
+ return 1;
+ }
+ disable_interrupts();
+
+ for (i = addr; i < addr + count; i++) {
+
+ /* enable injects */
+ ddr->ecc_err_inject |= ECC_ERR_INJECT_EIEN;
+ __asm__ __volatile__("sync");
+ __asm__ __volatile__("isync");
+
+ /* write memory location injecting errors */
+ ppcDWstore((u32 *) i, pattern);
+ __asm__ __volatile__("sync");
+
+ /* disable injects */
+ ddr->ecc_err_inject &= ~ECC_ERR_INJECT_EIEN;
+ __asm__ __volatile__("sync");
+ __asm__ __volatile__("isync");
+
+ /* read data, this generates ECC error */
+ ppcDWload((u32 *) i, ret);
+ __asm__ __volatile__("sync");
+
+ /* re-initialize memory, double word write the location again,
+ * generates new ECC code this time */
+ ppcDWstore((u32 *) i, writeback);
+ __asm__ __volatile__("sync");
+ }
+ enable_interrupts();
+ return 0;
+ }
+ if (strcmp(argv[1], "testword") == 0) {
+ addr = (u64 *) simple_strtoul(argv[2], NULL, 16);
+ count = simple_strtoul(argv[3], NULL, 16);
+
+ if ((u32) addr % 8) {
+ printf("Address not alligned on "
+ "double word boundary\n");
+ return 1;
+ }
+ disable_interrupts();
+
+ for (i = addr; i < addr + count; i++) {
+
+ /* enable injects */
+ ddr->ecc_err_inject |= ECC_ERR_INJECT_EIEN;
+ __asm__ __volatile__("sync");
+ __asm__ __volatile__("isync");
+
+ /* write memory location injecting errors */
+ *(u32 *) i = 0xfedcba98UL;
+ __asm__ __volatile__("sync");
+
+ /* sub double word write,
+ * bus will read-modify-write,
+ * generates ECC error */
+ *((u32 *) i + 1) = 0x76543210UL;
+ __asm__ __volatile__("sync");
+
+ /* disable injects */
+ ddr->ecc_err_inject &= ~ECC_ERR_INJECT_EIEN;
+ __asm__ __volatile__("sync");
+ __asm__ __volatile__("isync");
+
+ /* re-initialize memory,
+ * double word write the location again,
+ * generates new ECC code this time */
+ ppcDWstore((u32 *) i, writeback);
+ __asm__ __volatile__("sync");
+ }
+ enable_interrupts();
+ return 0;
+ }
+ }
+ printf("Usage:\n%s\n", cmdtp->usage);
+ return 1;
+}
+
+U_BOOT_CMD(ecc, 4, 0, do_ecc,
+ "ecc - support for DDR ECC features\n",
+ "status - print out status info\n"
+ "ecc captureclear - clear capture regs data\n"
+ "ecc sbecnt <val> - set Single-Bit Error counter\n"
+ "ecc sbethr <val> - set Single-Bit Threshold\n"
+ "ecc errdisable <flag> - clear/set disable Memory Error Disable, flag:\n"
+ " [-|+]sbe - Single-Bit Error\n"
+ " [-|+]mbe - Multiple-Bit Error\n"
+ " [-|+]mse - Memory Select Error\n"
+ " [-|+]all - all errors\n"
+ "ecc errdetectclr <flag> - clear Memory Error Detect, flag:\n"
+ " mme - Multiple Memory Errors\n"
+ " sbe - Single-Bit Error\n"
+ " mbe - Multiple-Bit Error\n"
+ " mse - Memory Select Error\n"
+ " all - all errors\n"
+ "ecc injectdatahi <hi> - set Memory Data Path Error Injection Mask High\n"
+ "ecc injectdatalo <lo> - set Memory Data Path Error Injection Mask Low\n"
+ "ecc injectecc <ecc> - set ECC Error Injection Mask\n"
+ "ecc inject <en|dis> - enable/disable error injection\n"
+ "ecc mirror <en|dis> - enable/disable mirror byte\n"
+ "ecc testdw <addr> <cnt> - test mem region with double word access:\n"
+ " - enables injects\n"
+ " - writes pattern injecting errors with double word access\n"
+ " - disables injects\n"
+ " - reads pattern back with double word access, generates error\n"
+ " - re-inits memory\n"
+ "ecc testword <addr> <cnt> - test mem region with word access:\n"
+ " - enables injects\n"
+ " - writes pattern injecting errors with word access\n"
+ " - writes pattern with word access, generates error\n"
+ " - disables injects\n" " - re-inits memory");
+#endif /* if defined(CONFIG_DDR_ECC) && defined(CONFIG_DDR_ECC_CMD) */
+
+#if defined(CONFIG_OF_FLAT_TREE) && defined(CONFIG_OF_BOARD_SETUP)
+void
+ft_board_setup(void *blob, bd_t *bd)
+{
+ u32 *p;
+ int len;
+
+#ifdef CONFIG_PCI
+ ft_pci_setup(blob, bd);
+#endif
+ ft_cpu_setup(blob, bd);
+
+ p = ft_get_prop(blob, "/memory/reg", &len);
+ if (p != NULL) {
+ *p++ = cpu_to_be32(bd->bi_memstart);
+ *p = cpu_to_be32(bd->bi_memsize);
+ }
+}
+#endif
diff --git a/board/mpc8360emds/pci.c b/board/mpc8360emds/pci.c
new file mode 100644
index 00000000000..67cd70981ca
--- /dev/null
+++ b/board/mpc8360emds/pci.c
@@ -0,0 +1,316 @@
+/*
+ * Copyright (C) 2006 Freescale Semiconductor, Inc.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ */
+
+/*
+ * PCI Configuration space access support for MPC83xx PCI Bridge
+ */
+#include <asm/mmu.h>
+#include <asm/io.h>
+#include <common.h>
+#include <pci.h>
+#include <i2c.h>
+#if defined(CONFIG_OF_FLAT_TREE)
+#include <ft_build.h>
+#endif
+
+#include <asm/fsl_i2c.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#if defined(CONFIG_PCI)
+#define PCI_FUNCTION_CONFIG 0x44
+#define PCI_FUNCTION_CFG_LOCK 0x20
+
+/*
+ * Initialize PCI Devices, report devices found
+ */
+#ifndef CONFIG_PCI_PNP
+static struct pci_config_table pci_mpc83xxemds_config_table[] = {
+ {
+ PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
+ pci_cfgfunc_config_device,
+ {PCI_ENET0_IOADDR,
+ PCI_ENET0_MEMADDR,
+ PCI_COMMON_MEMORY | PCI_COMMAND_MASTER}
+ },
+ {}
+}
+#endif
+static struct pci_controller hose[] = {
+ {
+#ifndef CONFIG_PCI_PNP
+ config_table:pci_mpc83xxemds_config_table,
+#endif
+ },
+};
+
+/**********************************************************************
+ * pci_init_board()
+ *********************************************************************/
+void pci_init_board(void)
+#ifdef CONFIG_PCISLAVE
+{
+ u16 reg16;
+ volatile immap_t *immr;
+ volatile law83xx_t *pci_law;
+ volatile pot83xx_t *pci_pot;
+ volatile pcictrl83xx_t *pci_ctrl;
+ volatile pciconf83xx_t *pci_conf;
+
+ immr = (immap_t *) CFG_IMMR;
+ pci_law = immr->sysconf.pcilaw;
+ pci_pot = immr->ios.pot;
+ pci_ctrl = immr->pci_ctrl;
+ pci_conf = immr->pci_conf;
+ /*
+ * Configure PCI Inbound Translation Windows
+ */
+ pci_ctrl[0].pitar0 = 0x0;
+ pci_ctrl[0].pibar0 = 0x0;
+ pci_ctrl[0].piwar0 = PIWAR_EN | PIWAR_RTT_SNOOP |
+ PIWAR_WTT_SNOOP | PIWAR_IWS_4K;
+
+ pci_ctrl[0].pitar1 = 0x0;
+ pci_ctrl[0].pibar1 = 0x0;
+ pci_ctrl[0].piebar1 = 0x0;
+ pci_ctrl[0].piwar1 &= ~PIWAR_EN;
+
+ pci_ctrl[0].pitar2 = 0x0;
+ pci_ctrl[0].pibar2 = 0x0;
+ pci_ctrl[0].piebar2 = 0x0;
+ pci_ctrl[0].piwar2 &= ~PIWAR_EN;
+
+ hose[0].first_busno = 0;
+ hose[0].last_busno = 0xff;
+ pci_setup_indirect(&hose[0],
+ (CFG_IMMR + 0x8300), (CFG_IMMR + 0x8304));
+ reg16 = 0xff;
+
+ pci_hose_read_config_word(&hose[0], PCI_BDF(0, 0, 0),
+ PCI_COMMAND, &reg16);
+ reg16 |= PCI_COMMAND_SERR | PCI_COMMAND_MEMORY;
+ pci_hose_write_config_word(&hose[0], PCI_BDF(0, 0, 0),
+ PCI_COMMAND, reg16);
+
+ /*
+ * Clear non-reserved bits in status register.
+ */
+ pci_hose_write_config_word(&hose[0], PCI_BDF(0, 0, 0),
+ PCI_STATUS, 0xffff);
+ pci_hose_write_config_byte(&hose[0], PCI_BDF(0, 0, 0),
+ PCI_LATENCY_TIMER, 0x80);
+
+ /*
+ * Unlock configuration lock in PCI function configuration register.
+ */
+ pci_hose_read_config_word(&hose[0], PCI_BDF(0, 0, 0),
+ PCI_FUNCTION_CONFIG, &reg16);
+ reg16 &= ~(PCI_FUNCTION_CFG_LOCK);
+ pci_hose_write_config_word(&hose[0], PCI_BDF(0, 0, 0),
+ PCI_FUNCTION_CONFIG, reg16);
+
+ printf("Enabled PCI 32bit Agent Mode\n");
+}
+#else
+{
+ volatile immap_t *immr;
+ volatile clk83xx_t *clk;
+ volatile law83xx_t *pci_law;
+ volatile pot83xx_t *pci_pot;
+ volatile pcictrl83xx_t *pci_ctrl;
+ volatile pciconf83xx_t *pci_conf;
+
+ u8 val8, orig_i2c_bus;
+ u16 reg16;
+ u32 val32;
+ u32 dev;
+
+ immr = (immap_t *) CFG_IMMR;
+ clk = (clk83xx_t *) & immr->clk;
+ pci_law = immr->sysconf.pcilaw;
+ pci_pot = immr->ios.pot;
+ pci_ctrl = immr->pci_ctrl;
+ pci_conf = immr->pci_conf;
+ /*
+ * Configure PCI controller and PCI_CLK_OUTPUT both in 66M mode
+ */
+ val32 = clk->occr;
+ udelay(2000);
+#if defined(PCI_66M)
+ clk->occr = OCCR_PCICOE0 | OCCR_PCICOE1 | OCCR_PCICOE2;
+ printf("PCI clock is 66MHz\n");
+#elif defined(PCI_33M)
+ clk->occr = OCCR_PCICOE0 | OCCR_PCICOE1 | OCCR_PCICOE2 |
+ OCCR_PCICD0 | OCCR_PCICD1 | OCCR_PCICD2 | OCCR_PCICR;
+ printf("PCI clock is 33MHz\n");
+#else
+ clk->occr = OCCR_PCICOE0 | OCCR_PCICOE1 | OCCR_PCICOE2;
+ printf("PCI clock is 66MHz\n");
+#endif
+ udelay(2000);
+
+ /*
+ * Configure PCI Local Access Windows
+ */
+ pci_law[0].bar = CFG_PCI_MEM_PHYS & LAWBAR_BAR;
+ pci_law[0].ar = LAWAR_EN | LAWAR_SIZE_512M;
+
+ pci_law[1].bar = CFG_PCI_IO_PHYS & LAWBAR_BAR;
+ pci_law[1].ar = LAWAR_EN | LAWAR_SIZE_1M;
+
+ /*
+ * Configure PCI Outbound Translation Windows
+ */
+
+ /* PCI mem space - prefetch */
+ pci_pot[0].potar = (CFG_PCI_MEM_BASE >> 12) & POTAR_TA_MASK;
+ pci_pot[0].pobar = (CFG_PCI_MEM_PHYS >> 12) & POBAR_BA_MASK;
+ pci_pot[0].pocmr =
+ POCMR_EN | POCMR_SE | (POCMR_CM_256M & POCMR_CM_MASK);
+
+ /* PCI mmio - non-prefetch mem space */
+ pci_pot[1].potar = (CFG_PCI_MMIO_BASE >> 12) & POTAR_TA_MASK;
+ pci_pot[1].pobar = (CFG_PCI_MMIO_PHYS >> 12) & POBAR_BA_MASK;
+ pci_pot[1].pocmr = POCMR_EN | (POCMR_CM_256M & POCMR_CM_MASK);
+
+ /* PCI IO space */
+ pci_pot[2].potar = (CFG_PCI_IO_BASE >> 12) & POTAR_TA_MASK;
+ pci_pot[2].pobar = (CFG_PCI_IO_PHYS >> 12) & POBAR_BA_MASK;
+ pci_pot[2].pocmr = POCMR_EN | POCMR_IO | (POCMR_CM_1M & POCMR_CM_MASK);
+
+ /*
+ * Configure PCI Inbound Translation Windows
+ */
+ pci_ctrl[0].pitar1 = (CFG_PCI_SLV_MEM_LOCAL >> 12) & PITAR_TA_MASK;
+ pci_ctrl[0].pibar1 = (CFG_PCI_SLV_MEM_BUS >> 12) & PIBAR_MASK;
+ pci_ctrl[0].piebar1 = 0x0;
+ pci_ctrl[0].piwar1 =
+ PIWAR_EN | PIWAR_PF | PIWAR_RTT_SNOOP | PIWAR_WTT_SNOOP |
+ PIWAR_IWS_2G;
+
+ /*
+ * Assign PIB PMC slot to desired PCI bus
+ */
+
+ /* Switch temporarily to I2C bus #2 */
+ orig_i2c_bus = i2c_get_bus_num();
+ i2c_set_bus_num(1);
+
+ val8 = 0;
+ i2c_write(0x23, 0x6, 1, &val8, 1);
+ i2c_write(0x23, 0x7, 1, &val8, 1);
+ val8 = 0xff;
+ i2c_write(0x23, 0x2, 1, &val8, 1);
+ i2c_write(0x23, 0x3, 1, &val8, 1);
+
+ val8 = 0;
+ i2c_write(0x26, 0x6, 1, &val8, 1);
+ val8 = 0x34;
+ i2c_write(0x26, 0x7, 1, &val8, 1);
+
+ val8 = 0xf3; /*PMC1, PMC2, PMC3 slot to PCI bus */
+ i2c_write(0x26, 0x2, 1, &val8, 1);
+ val8 = 0xff;
+ i2c_write(0x26, 0x3, 1, &val8, 1);
+
+ val8 = 0;
+ i2c_write(0x27, 0x6, 1, &val8, 1);
+ i2c_write(0x27, 0x7, 1, &val8, 1);
+ val8 = 0xff;
+ i2c_write(0x27, 0x2, 1, &val8, 1);
+ val8 = 0xef;
+ i2c_write(0x27, 0x3, 1, &val8, 1);
+ asm("eieio");
+
+ /* Reset to original I2C bus */
+ i2c_set_bus_num(orig_i2c_bus);
+
+ /*
+ * Release PCI RST Output signal
+ */
+ udelay(2000);
+ pci_ctrl[0].gcr = 1;
+ udelay(2000);
+
+ hose[0].first_busno = 0;
+ hose[0].last_busno = 0xff;
+
+ /* PCI memory prefetch space */
+ pci_set_region(hose[0].regions + 0,
+ CFG_PCI_MEM_BASE,
+ CFG_PCI_MEM_PHYS,
+ CFG_PCI_MEM_SIZE, PCI_REGION_MEM | PCI_REGION_PREFETCH);
+
+ /* PCI memory space */
+ pci_set_region(hose[0].regions + 1,
+ CFG_PCI_MMIO_BASE,
+ CFG_PCI_MMIO_PHYS, CFG_PCI_MMIO_SIZE, PCI_REGION_MEM);
+
+ /* PCI IO space */
+ pci_set_region(hose[0].regions + 2,
+ CFG_PCI_IO_BASE,
+ CFG_PCI_IO_PHYS, CFG_PCI_IO_SIZE, PCI_REGION_IO);
+
+ /* System memory space */
+ pci_set_region(hose[0].regions + 3,
+ CFG_PCI_SLV_MEM_LOCAL,
+ CFG_PCI_SLV_MEM_BUS,
+ CFG_PCI_SLV_MEM_SIZE,
+ PCI_REGION_MEM | PCI_REGION_MEMORY);
+
+ hose[0].region_count = 4;
+
+ pci_setup_indirect(&hose[0],
+ (CFG_IMMR + 0x8300), (CFG_IMMR + 0x8304));
+
+ pci_register_hose(hose);
+
+ /*
+ * Write command register
+ */
+ reg16 = 0xff;
+ dev = PCI_BDF(0, 0, 0);
+ pci_hose_read_config_word(&hose[0], dev, PCI_COMMAND, &reg16);
+ reg16 |= PCI_COMMAND_SERR | PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
+ pci_hose_write_config_word(&hose[0], dev, PCI_COMMAND, reg16);
+
+ /*
+ * Clear non-reserved bits in status register.
+ */
+ pci_hose_write_config_word(&hose[0], dev, PCI_STATUS, 0xffff);
+ pci_hose_write_config_byte(&hose[0], dev, PCI_LATENCY_TIMER, 0x80);
+ pci_hose_write_config_byte(&hose[0], dev, PCI_CACHE_LINE_SIZE, 0x08);
+
+ printf("PCI 32bit bus on PMC1 & PMC2 & PMC3\n");
+
+ /*
+ * Hose scan.
+ */
+ hose->last_busno = pci_hose_scan(hose);
+}
+#endif /* CONFIG_PCISLAVE */
+
+#ifdef CONFIG_OF_FLAT_TREE
+void
+ft_pci_setup(void *blob, bd_t *bd)
+{
+ u32 *p;
+ int len;
+
+ p = (u32 *)ft_get_prop(blob, "/" OF_SOC "/pci@8500/bus-range", &len);
+ if (p != NULL) {
+ p[0] = hose[0].first_busno;
+ p[1] = hose[0].last_busno;
+ }
+}
+#endif /* CONFIG_OF_FLAT_TREE */
+#endif /* CONFIG_PCI */
diff --git a/board/mpc8360emds/u-boot.lds b/board/mpc8360emds/u-boot.lds
new file mode 100644
index 00000000000..937c87a27cd
--- /dev/null
+++ b/board/mpc8360emds/u-boot.lds
@@ -0,0 +1,123 @@
+/*
+ * (C) Copyright 2006
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+OUTPUT_ARCH(powerpc)
+SECTIONS
+{
+ /* Read-only sections, merged into text segment: */
+ . = + SIZEOF_HEADERS;
+ .interp : { *(.interp) }
+ .hash : { *(.hash) }
+ .dynsym : { *(.dynsym) }
+ .dynstr : { *(.dynstr) }
+ .rel.text : { *(.rel.text) }
+ .rela.text : { *(.rela.text) }
+ .rel.data : { *(.rel.data) }
+ .rela.data : { *(.rela.data) }
+ .rel.rodata : { *(.rel.rodata) }
+ .rela.rodata : { *(.rela.rodata) }
+ .rel.got : { *(.rel.got) }
+ .rela.got : { *(.rela.got) }
+ .rel.ctors : { *(.rel.ctors) }
+ .rela.ctors : { *(.rela.ctors) }
+ .rel.dtors : { *(.rel.dtors) }
+ .rela.dtors : { *(.rela.dtors) }
+ .rel.bss : { *(.rel.bss) }
+ .rela.bss : { *(.rela.bss) }
+ .rel.plt : { *(.rel.plt) }
+ .rela.plt : { *(.rela.plt) }
+ .init : { *(.init) }
+ .plt : { *(.plt) }
+ .text :
+ {
+ cpu/mpc83xx/start.o (.text)
+ *(.text)
+ *(.fixup)
+ *(.got1)
+ . = ALIGN(16);
+ *(.rodata)
+ *(.rodata1)
+ *(.rodata.str1.4)
+ *(.eh_frame)
+ }
+ .fini : { *(.fini) } =0
+ .ctors : { *(.ctors) }
+ .dtors : { *(.dtors) }
+
+ /* Read-write section, merged into data segment: */
+ . = (. + 0x0FFF) & 0xFFFFF000;
+ _erotext = .;
+ PROVIDE (erotext = .);
+ .reloc :
+ {
+ *(.got)
+ _GOT2_TABLE_ = .;
+ *(.got2)
+ _FIXUP_TABLE_ = .;
+ *(.fixup)
+ }
+ __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >> 2;
+ __fixup_entries = (. - _FIXUP_TABLE_) >> 2;
+
+ .data :
+ {
+ *(.data)
+ *(.data1)
+ *(.sdata)
+ *(.sdata2)
+ *(.dynamic)
+ CONSTRUCTORS
+ }
+ _edata = .;
+ PROVIDE (edata = .);
+
+ . = .;
+ __u_boot_cmd_start = .;
+ .u_boot_cmd : { *(.u_boot_cmd) }
+ __u_boot_cmd_end = .;
+
+
+ . = .;
+ __start___ex_table = .;
+ __ex_table : { *(__ex_table) }
+ __stop___ex_table = .;
+
+ . = ALIGN(4096);
+ __init_begin = .;
+ .text.init : { *(.text.init) }
+ .data.init : { *(.data.init) }
+ . = ALIGN(4096);
+ __init_end = .;
+
+ __bss_start = .;
+ .bss :
+ {
+ *(.sbss) *(.scommon)
+ *(.dynbss)
+ *(.bss)
+ *(COMMON)
+ }
+ _end = . ;
+ PROVIDE (end = .);
+}
+ENTRY(_start)
diff --git a/board/mpl/common/memtst.c b/board/mpl/common/memtst.c
index ff1190ab212..1d28513d87e 100644
--- a/board/mpl/common/memtst.c
+++ b/board/mpl/common/memtst.c
@@ -48,7 +48,7 @@ int testdram (void)
#include <common.h>
#include <asm/processor.h>
-#include <405gp_i2c.h>
+#include <4xx_i2c.h>
DECLARE_GLOBAL_DATA_PTR;
diff --git a/board/mpl/mip405/mip405.c b/board/mpl/mip405/mip405.c
index 34f328999d1..4b1c1c06694 100644
--- a/board/mpl/mip405/mip405.c
+++ b/board/mpl/mip405/mip405.c
@@ -65,7 +65,7 @@
#include <common.h>
#include "mip405.h"
#include <asm/processor.h>
-#include <405gp_i2c.h>
+#include <4xx_i2c.h>
#include <miiphy.h>
#include "../common/common_util.h"
#include <i2c.h>
@@ -73,9 +73,6 @@
DECLARE_GLOBAL_DATA_PTR;
-extern block_dev_desc_t * scsi_get_dev(int dev);
-extern block_dev_desc_t * ide_get_dev(int dev);
-
#undef SDRAM_DEBUG
#define ENABLE_ECC /* for ecc boards */
#define FALSE 0
diff --git a/board/nc650/nand.c b/board/nc650/nand.c
index de54386ddd5..6bb7c314375 100644
--- a/board/nc650/nand.c
+++ b/board/nc650/nand.c
@@ -106,12 +106,13 @@ static void nc650_hwcontrol(struct mtd_info *mtd, int cmd)
* Members with a "?" were not set in the merged testing-NAND branch,
* so they are not set here either.
*/
-void board_nand_init(struct nand_chip *nand)
+int board_nand_init(struct nand_chip *nand)
{
nand->hwcontrol = nc650_hwcontrol;
nand->eccmode = NAND_ECC_SOFT;
nand->chip_delay = 12;
/* nand->options = NAND_SAMSUNG_LP_OPTIONS;*/
+ return 0;
}
#endif /* (CONFIG_COMMANDS & CFG_CMD_NAND) */
diff --git a/board/netstar/nand.c b/board/netstar/nand.c
index f470c1a01e0..78523654eb9 100644
--- a/board/netstar/nand.c
+++ b/board/netstar/nand.c
@@ -55,12 +55,13 @@ static int netstar_nand_ready(struct mtd_info *mtd)
}
***/
-void board_nand_init(struct nand_chip *nand)
+int board_nand_init(struct nand_chip *nand)
{
nand->options = NAND_SAMSUNG_LP_OPTIONS;
nand->eccmode = NAND_ECC_SOFT;
nand->hwcontrol = netstar_nand_hwcontrol;
/* nand->dev_ready = netstar_nand_ready; */
nand->chip_delay = 18;
+ return 0;
}
#endif
diff --git a/board/prodrive/alpr/Makefile b/board/prodrive/alpr/Makefile
new file mode 100644
index 00000000000..00dc180bbd3
--- /dev/null
+++ b/board/prodrive/alpr/Makefile
@@ -0,0 +1,51 @@
+#
+# (C) Copyright 2006
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+include $(TOPDIR)/config.mk
+
+LIB = $(obj)lib$(BOARD).a
+
+COBJS = $(BOARD).o fpga.o nand.o
+SOBJS = init.o
+
+SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(COBJS))
+SOBJS := $(addprefix $(obj),$(SOBJS))
+
+$(LIB): $(OBJS) $(SOBJS)
+ $(AR) $(ARFLAGS) $@ $(OBJS)
+
+clean:
+ rm -f $(SOBJS) $(OBJS)
+
+distclean: clean
+ rm -f $(LIB) core *.bak .depend *~
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/board/prodrive/alpr/alpr.c b/board/prodrive/alpr/alpr.c
new file mode 100644
index 00000000000..5abc87dde64
--- /dev/null
+++ b/board/prodrive/alpr/alpr.c
@@ -0,0 +1,317 @@
+/*
+ * (C) Copyright 2006
+ * Stefan Roese, DENX Software Engineering, sr@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+
+#include <common.h>
+#include <asm/processor.h>
+#include <spd_sdram.h>
+#include <ppc4xx_enet.h>
+#include <miiphy.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+extern int alpr_fpga_init(void);
+
+int board_early_init_f (void)
+{
+ /*-------------------------------------------------------------------------
+ * Initialize EBC CONFIG
+ *-------------------------------------------------------------------------*/
+ mtebc(xbcfg, EBC_CFG_LE_UNLOCK |
+ EBC_CFG_PTD_DISABLE | EBC_CFG_RTC_64PERCLK |
+ EBC_CFG_ATC_PREVIOUS | EBC_CFG_DTC_PREVIOUS |
+ EBC_CFG_CTC_PREVIOUS | EBC_CFG_EMC_NONDEFAULT |
+ EBC_CFG_PME_DISABLE | EBC_CFG_PR_32);
+
+ /*--------------------------------------------------------------------
+ * Setup the interrupt controller polarities, triggers, etc.
+ *-------------------------------------------------------------------*/
+ mtdcr (uic0sr, 0xffffffff); /* clear all */
+ mtdcr (uic0er, 0x00000000); /* disable all */
+ mtdcr (uic0cr, 0x00000009); /* SMI & UIC1 crit are critical */
+ mtdcr (uic0pr, 0xfffffe03); /* per manual */
+ mtdcr (uic0tr, 0x01c00000); /* per 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 */
+
+ mtdcr (uic2sr, 0xffffffff); /* clear all */
+ mtdcr (uic2er, 0x00000000); /* disable all */
+ mtdcr (uic2cr, 0x00000000); /* all non-critical */
+ mtdcr (uic2pr, 0xffffffff); /* per ref-board manual */
+ mtdcr (uic2tr, 0x00ff8c0f); /* per ref-board manual */
+ mtdcr (uic2vr, 0x00000001); /* int31 highest, base=0x000 */
+ mtdcr (uic2sr, 0xffffffff); /* clear all */
+
+ mtdcr (uicb0sr, 0xfc000000); /* clear all */
+ mtdcr (uicb0er, 0x00000000); /* disable all */
+ mtdcr (uicb0cr, 0x00000000); /* all non-critical */
+ mtdcr (uicb0pr, 0xfc000000); /* */
+ mtdcr (uicb0tr, 0x00000000); /* */
+ mtdcr (uicb0vr, 0x00000001); /* */
+
+ /* Setup shutdown/SSD empty interrupt as inputs */
+ out32(GPIO0_TCR, in32(GPIO0_TCR) & ~(CFG_GPIO_SHUTDOWN | CFG_GPIO_SSD_EMPTY));
+ out32(GPIO0_ODR, in32(GPIO0_ODR) & ~(CFG_GPIO_SHUTDOWN | CFG_GPIO_SSD_EMPTY));
+
+ /* Setup GPIO/IRQ multiplexing */
+ mtsdr(sdr_pfc0, 0x01a33e00);
+
+ return 0;
+}
+
+int last_stage_init(void)
+{
+ unsigned short reg;
+
+ /*
+ * Configure LED's of both Marvell 88E1111 PHY's
+ *
+ * This has to be done after the 4xx ethernet driver is loaded,
+ * so "last_stage_init()" is the right place.
+ */
+ miiphy_read("ppc_4xx_eth2", CONFIG_PHY2_ADDR, 0x18, &reg);
+ reg |= 0x0001;
+ miiphy_write("ppc_4xx_eth2", CONFIG_PHY2_ADDR, 0x18, reg);
+ miiphy_read("ppc_4xx_eth3", CONFIG_PHY3_ADDR, 0x18, &reg);
+ reg |= 0x0001;
+ miiphy_write("ppc_4xx_eth3", CONFIG_PHY3_ADDR, 0x18, reg);
+
+ return 0;
+}
+
+static int board_rev(void)
+{
+ /* Setup as input */
+ out32(GPIO0_TCR, in32(GPIO0_TCR) & ~(CFG_GPIO_REV0 | CFG_GPIO_REV1));
+ out32(GPIO0_ODR, in32(GPIO0_ODR) & ~(CFG_GPIO_REV0 | CFG_GPIO_REV1));
+
+ return (in32(GPIO0_IR) >> 16) & 0x3;
+}
+
+int checkboard (void)
+{
+ char *s = getenv ("serial#");
+
+ printf ("Board: ALPR");
+ if (s != NULL) {
+ puts (", serial# ");
+ puts (s);
+ }
+ printf(" (Rev. %d)\n", board_rev());
+
+ return (0);
+}
+
+#if defined(CFG_DRAM_TEST)
+int testdram (void)
+{
+ uint *pstart = (uint *) 0x00000000;
+ uint *pend = (uint *) 0x08000000;
+ uint *p;
+
+ for (p = pstart; p < pend; p++)
+ *p = 0xaaaaaaaa;
+
+ for (p = pstart; p < pend; p++) {
+ if (*p != 0xaaaaaaaa) {
+ printf ("SDRAM test fails at: %08x\n", (uint) p);
+ return 1;
+ }
+ }
+
+ for (p = pstart; p < pend; p++)
+ *p = 0x55555555;
+
+ for (p = pstart; p < pend; p++) {
+ if (*p != 0x55555555) {
+ printf ("SDRAM test fails at: %08x\n", (uint) p);
+ return 1;
+ }
+ }
+ 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 strap;
+
+ /*--------------------------------------------------------------------------+
+ * The ocotea board is always configured as the host & requires the
+ * PCI arbiter to be enabled.
+ *--------------------------------------------------------------------------*/
+ mfsdr(sdr_sdstp1, strap);
+ if( (strap & SDR0_SDSTP1_PAE_MASK) == 0 ){
+ printf("PCI: SDR0_STRP1[%08lX] - PCI Arbiter disabled.\n",strap);
+ return 0;
+ }
+
+ /* FPGA Init */
+ alpr_fpga_init ();
+
+ 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 )
+{
+ /*--------------------------------------------------------------------------+
+ * Disable everything
+ *--------------------------------------------------------------------------*/
+ out32r( PCIX0_PIM0SA, 0 ); /* disable */
+ out32r( PCIX0_PIM1SA, 0 ); /* disable */
+ out32r( PCIX0_PIM2SA, 0 ); /* disable */
+ out32r( PCIX0_EROMBA, 0 ); /* disable expansion rom */
+
+ /*--------------------------------------------------------------------------+
+ * Map all of SDRAM to PCI address 0x0000_0000. Note that the 440 strapping
+ * options to not support sizes such as 128/256 MB.
+ *--------------------------------------------------------------------------*/
+ out32r( PCIX0_PIM0LAL, CFG_SDRAM_BASE );
+ out32r( PCIX0_PIM0LAH, 0 );
+ out32r( PCIX0_PIM0SA, ~(gd->ram_size - 1) | 1 );
+
+ out32r( PCIX0_BAR0, 0 );
+
+ /*--------------------------------------------------------------------------+
+ * Program the board's subsystem id/vendor id
+ *--------------------------------------------------------------------------*/
+ out16r( PCIX0_SBSYSVID, CFG_PCI_SUBSYS_VENDORID );
+ out16r( PCIX0_SBSYSID, CFG_PCI_SUBSYS_DEVICEID );
+
+ out16r( PCIX0_CMD, in16r(PCIX0_CMD) | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
+}
+#endif /* defined(CONFIG_PCI) && defined(CFG_PCI_TARGET_INIT) */
+
+/*************************************************************************
+ * is_pci_host
+ *
+ * This routine is called to determine if a pci scan should be
+ * performed. With various hardware environments (especially cPCI and
+ * PPMC) it's insufficient to depend on the state of the arbiter enable
+ * bit in the strap register, or generic host/adapter assumptions.
+ *
+ * Rather than hard-code a bad assumption in the general 440 code, the
+ * 440 pci code requires the board to decide at runtime.
+ *
+ * Return 0 for adapter mode, non-zero for host (monarch) mode.
+ *
+ *
+ ************************************************************************/
+#if defined(CONFIG_PCI)
+
+static void wait_for_pci_ready(void)
+{
+ /*
+ * Configure EREADY as input
+ */
+ out32(GPIO0_TCR, in32(GPIO0_TCR) & ~CFG_GPIO_EREADY);
+ udelay(1000);
+
+ for (;;) {
+ if (in32(GPIO0_IR) & CFG_GPIO_EREADY)
+ return;
+ }
+
+}
+
+int is_pci_host(struct pci_controller *hose)
+{
+ wait_for_pci_ready();
+ return 1; /* return 1 for host controller */
+}
+#endif /* defined(CONFIG_PCI) */
+
+/*************************************************************************
+ * pci_master_init
+ *
+ ************************************************************************/
+#if defined(CONFIG_PCI) && defined(CFG_PCI_MASTER_INIT)
+void pci_master_init(struct pci_controller *hose)
+{
+ /*--------------------------------------------------------------------------+
+ | PowerPC440 PCI Master configuration.
+ | Map PLB/processor addresses to PCI memory space.
+ | PLB address 0xA0000000-0xCFFFFFFF ==> PCI address 0x80000000-0xCFFFFFFF
+ | Use byte reversed out routines to handle endianess.
+ | Make this region non-prefetchable.
+ +--------------------------------------------------------------------------*/
+ out32r( PCIX0_POM0SA, 0 ); /* disable */
+ out32r( PCIX0_POM1SA, 0 ); /* disable */
+ out32r( PCIX0_POM2SA, 0 ); /* disable */
+
+ out32r(PCIX0_POM0LAL, CFG_PCI_MEMBASE); /* PMM0 Local Address */
+ out32r(PCIX0_POM0LAH, 0x00000003); /* PMM0 Local Address */
+ out32r(PCIX0_POM0PCIAL, CFG_PCI_MEMBASE); /* PMM0 PCI Low Address */
+ out32r(PCIX0_POM0PCIAH, 0x00000000); /* PMM0 PCI High Address */
+ out32r(PCIX0_POM0SA, ~(0x10000000 - 1) | 1); /* 256MB + enable region */
+
+ out32r(PCIX0_POM1LAL, CFG_PCI_MEMBASE2); /* PMM0 Local Address */
+ out32r(PCIX0_POM1LAH, 0x00000003); /* PMM0 Local Address */
+ out32r(PCIX0_POM1PCIAL, CFG_PCI_MEMBASE2); /* PMM0 PCI Low Address */
+ out32r(PCIX0_POM1PCIAH, 0x00000000); /* PMM0 PCI High Address */
+ out32r(PCIX0_POM1SA, ~(0x10000000 - 1) | 1); /* 256MB + enable region */
+}
+#endif /* defined(CONFIG_PCI) && defined(CFG_PCI_MASTER_INIT) */
+
+#ifdef CONFIG_POST
+/*
+ * Returns 1 if keys pressed to start the power-on long-running tests
+ * Called from board_init_f().
+ */
+int post_hotkeys_pressed(void)
+{
+
+ return (ctrlc());
+}
+#endif
diff --git a/board/amcc/yellowstone/config.mk b/board/prodrive/alpr/config.mk
index 4ab0ea0084f..9e1833591a2 100644
--- a/board/amcc/yellowstone/config.mk
+++ b/board/prodrive/alpr/config.mk
@@ -1,5 +1,5 @@
#
-# (C) Copyright 2002
+# (C) Copyright 2004
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
#
# See file CREDITS for list of people who contributed to this
@@ -22,15 +22,15 @@
#
#
-# esd ADCIOP boards
+# AMCC 440GX Reference Platform (Ocotea) board
#
-#TEXT_BASE = 0x00001000
+#TEXT_BASE = 0xFFFE0000
ifeq ($(ramsym),1)
-TEXT_BASE = 0xFBD00000
+TEXT_BASE = 0x07FD0000
else
-TEXT_BASE = 0xFFF80000
+TEXT_BASE = 0xFFFC0000
endif
PLATFORM_CPPFLAGS += -DCONFIG_440=1
diff --git a/board/prodrive/alpr/fpga.c b/board/prodrive/alpr/fpga.c
new file mode 100644
index 00000000000..e94360f814d
--- /dev/null
+++ b/board/prodrive/alpr/fpga.c
@@ -0,0 +1,257 @@
+/*
+ * (C) Copyright 2006
+ * Heiko Schocher, DENX Software Engineering, hs@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
+ *
+ */
+
+/*
+ * Altera FPGA configuration support for the ALPR computer from prodrive
+ */
+
+#include <common.h>
+#include <altera.h>
+#include <ACEX1K.h>
+#include <command.h>
+#include <asm-ppc/processor.h>
+#include <ppc440.h>
+#include "fpga.h"
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#if defined(CONFIG_FPGA)
+
+#ifdef FPGA_DEBUG
+#define PRINTF(fmt,args...) printf (fmt ,##args)
+#else
+#define PRINTF(fmt,args...)
+#endif
+
+static unsigned long regval;
+
+#define SET_GPIO_REG_0(reg, bit) { \
+ regval = in32(reg); \
+ regval &= ~(0x80000000 >> bit); \
+ out32(reg, regval); \
+ }
+
+#define SET_GPIO_REG_1(reg, bit) { \
+ regval = in32(reg); \
+ regval |= (0x80000000 >> bit); \
+ out32(reg, regval); \
+ }
+
+#define SET_GPIO_0(bit) SET_GPIO_REG_0(GPIO0_OR, bit)
+#define SET_GPIO_1(bit) SET_GPIO_REG_1(GPIO0_OR, bit)
+
+#define FPGA_PRG (0x80000000 >> CFG_GPIO_PROG_EN)
+#define FPGA_CONFIG (0x80000000 >> CFG_GPIO_CONFIG)
+#define FPGA_DATA (0x80000000 >> CFG_GPIO_DATA)
+#define FPGA_CLK (0x80000000 >> CFG_GPIO_CLK)
+#define OLD_VAL (FPGA_PRG | FPGA_CONFIG)
+
+#define SET_FPGA(data) out32(GPIO0_OR, data)
+
+#define FPGA_WRITE_1 { \
+ SET_FPGA(OLD_VAL | 0 | FPGA_DATA); /* set data to 1 */ \
+ SET_FPGA(OLD_VAL | FPGA_CLK | FPGA_DATA);} /* set data to 1 */
+
+#define FPGA_WRITE_0 { \
+ SET_FPGA(OLD_VAL | 0 | 0 ); /* set data to 0 */ \
+ SET_FPGA(OLD_VAL | FPGA_CLK | 0 );} /* set data to 1 */
+
+/* Plattforminitializations */
+/* Here we have to set the FPGA Chain */
+/* PROGRAM_PROG_EN = HIGH */
+/* PROGRAM_SEL_DPR = LOW */
+int fpga_pre_fn (int cookie)
+{
+ unsigned long reg;
+
+ reg = in32(GPIO0_IR);
+ /* Enable the FPGA Chain */
+ SET_GPIO_REG_1(GPIO0_TCR, CFG_GPIO_PROG_EN);
+ SET_GPIO_REG_0(GPIO0_ODR, CFG_GPIO_PROG_EN);
+ SET_GPIO_1(CFG_GPIO_PROG_EN);
+ SET_GPIO_REG_1(GPIO0_TCR, CFG_GPIO_SEL_DPR);
+ SET_GPIO_REG_0(GPIO0_ODR, CFG_GPIO_SEL_DPR);
+ SET_GPIO_0((CFG_GPIO_SEL_DPR));
+
+ /* initialize the GPIO Pins */
+ /* output */
+ SET_GPIO_0(CFG_GPIO_CLK);
+ SET_GPIO_REG_1(GPIO0_TCR, CFG_GPIO_CLK);
+ SET_GPIO_REG_0(GPIO0_ODR, CFG_GPIO_CLK);
+
+ /* output */
+ SET_GPIO_0(CFG_GPIO_DATA);
+ SET_GPIO_REG_1(GPIO0_TCR, CFG_GPIO_DATA);
+ SET_GPIO_REG_0(GPIO0_ODR, CFG_GPIO_DATA);
+
+ /* First we set STATUS to 0 then as an input */
+ SET_GPIO_REG_1(GPIO0_TCR, CFG_GPIO_STATUS);
+ SET_GPIO_REG_0(GPIO0_ODR, CFG_GPIO_STATUS);
+ SET_GPIO_0(CFG_GPIO_STATUS);
+ SET_GPIO_REG_0(GPIO0_TCR, CFG_GPIO_STATUS);
+ SET_GPIO_REG_0(GPIO0_ODR, CFG_GPIO_STATUS);
+
+ /* output */
+ SET_GPIO_REG_1(GPIO0_TCR, CFG_GPIO_CONFIG);
+ SET_GPIO_REG_0(GPIO0_ODR, CFG_GPIO_CONFIG);
+ SET_GPIO_0(CFG_GPIO_CONFIG);
+
+ /* input */
+ SET_GPIO_0(CFG_GPIO_CON_DON);
+ SET_GPIO_REG_0(GPIO0_TCR, CFG_GPIO_CON_DON);
+ SET_GPIO_REG_0(GPIO0_ODR, CFG_GPIO_CON_DON);
+
+ /* CONFIG = 0 STATUS = 0 -> FPGA in reset state */
+ SET_GPIO_0(CFG_GPIO_CONFIG);
+ return FPGA_SUCCESS;
+}
+
+/* Set the state of CONFIG Pin */
+int fpga_config_fn (int assert_config, int flush, int cookie)
+{
+ if (assert_config) {
+ SET_GPIO_1(CFG_GPIO_CONFIG);
+ } else {
+ SET_GPIO_0(CFG_GPIO_CONFIG);
+ }
+ return FPGA_SUCCESS;
+}
+
+/* Returns the state of STATUS Pin */
+int fpga_status_fn (int cookie)
+{
+ unsigned long reg;
+
+ reg = in32(GPIO0_IR);
+ if (reg &= (0x80000000 >> CFG_GPIO_STATUS)) {
+ PRINTF("STATUS = HIGH\n");
+ return FPGA_FAIL;
+ }
+ PRINTF("STATUS = LOW\n");
+ return FPGA_SUCCESS;
+}
+
+/* Returns the state of CONF_DONE Pin */
+int fpga_done_fn (int cookie)
+{
+ unsigned long reg;
+ reg = in32(GPIO0_IR);
+ if (reg &= (0x80000000 >> CFG_GPIO_CON_DON)) {
+ PRINTF("CONF_DON = HIGH\n");
+ return FPGA_FAIL;
+ }
+ PRINTF("CONF_DON = LOW\n");
+ return FPGA_SUCCESS;
+}
+
+/* writes the complete buffer to the FPGA
+ writing the complete buffer in one function is much faster,
+ then calling it for every bit */
+int fpga_write_fn (void *buf, size_t len, int flush, int cookie)
+{
+ size_t bytecount = 0;
+ unsigned char *data = (unsigned char *) buf;
+ unsigned char val=0;
+ int i;
+ int len_40 = len / 40;
+
+ while (bytecount < len) {
+ val = data[bytecount++];
+ i = 8;
+ do {
+ if (val & 0x01) {
+ FPGA_WRITE_1;
+ } else {
+ FPGA_WRITE_0;
+ }
+ val >>= 1;
+ i --;
+ } while (i > 0);
+
+#ifdef CFG_FPGA_PROG_FEEDBACK
+ if (bytecount % len_40 == 0) {
+ putc ('.'); /* let them know we are alive */
+#ifdef CFG_FPGA_CHECK_CTRLC
+ if (ctrlc ())
+ return FPGA_FAIL;
+#endif
+ }
+#endif
+ }
+ return FPGA_SUCCESS;
+}
+
+/* called, when programming is aborted */
+int fpga_abort_fn (int cookie)
+{
+ SET_GPIO_1((CFG_GPIO_SEL_DPR));
+ return FPGA_SUCCESS;
+}
+
+/* called, when programming was succesful */
+int fpga_post_fn (int cookie)
+{
+ return fpga_abort_fn (cookie);
+}
+
+/* Note that these are pointers to code that is in Flash. They will be
+ * relocated at runtime.
+ */
+Altera_CYC2_Passive_Serial_fns fpga_fns = {
+ fpga_pre_fn,
+ fpga_config_fn,
+ fpga_status_fn,
+ fpga_done_fn,
+ fpga_write_fn,
+ fpga_abort_fn,
+ fpga_post_fn
+};
+
+Altera_desc fpga[CONFIG_FPGA_COUNT] = {
+ {Altera_CYC2,
+ passive_serial,
+ Altera_EP2C35_SIZE,
+ (void *) &fpga_fns,
+ NULL,
+ 0}
+};
+
+/*
+ * Initialize the fpga. Return 1 on success, 0 on failure.
+ */
+int alpr_fpga_init (void)
+{
+ int i;
+
+ PRINTF ("%s:%d: Initialize FPGA interface (relocation offset = 0x%.8lx)\n", __FUNCTION__, __LINE__, gd->reloc_off);
+ fpga_init (gd->reloc_off);
+
+ for (i = 0; i < CONFIG_FPGA_COUNT; i++) {
+ PRINTF ("%s:%d: Adding fpga %d\n", __FUNCTION__, __LINE__, i);
+ fpga_add (fpga_altera, &fpga[i]);
+ }
+ return 1;
+}
+
+#endif
diff --git a/board/prodrive/alpr/init.S b/board/prodrive/alpr/init.S
new file mode 100644
index 00000000000..135674c26a7
--- /dev/null
+++ b/board/prodrive/alpr/init.S
@@ -0,0 +1,103 @@
+/*
+ * (C) Copyright 2006
+ * Stefan Roese, DENX Software Engineering, sr@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <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_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
+ tlbentry( 0xff000000, SZ_16M, 0xff000000, 1, AC_R|AC_W|AC_X|SA_G|SA_I )
+ tlbentry( CFG_PERIPHERAL_BASE, SZ_256M, 0x40000000, 1, AC_R|AC_W|SA_G|SA_I )
+ tlbentry( CFG_ISRAM_BASE, SZ_4K, 0x80000000, 0, AC_R|AC_W|AC_X )
+ tlbentry( CFG_ISRAM_BASE + 0x1000, SZ_4K, 0x80001000, 0, AC_R|AC_W|AC_X )
+ tlbentry( CFG_SDRAM_BASE, SZ_256M, 0x00000000, 0, AC_R|AC_W|AC_X|SA_G|SA_I )
+ tlbentry( CFG_PCI_BASE, SZ_256M, 0x00000000, 2, AC_R|AC_W|SA_G|SA_I )
+
+ /* PCI */
+ tlbentry( CFG_PCI_MEMBASE, SZ_256M, CFG_PCI_MEMBASE, 3, AC_R|AC_W|SA_G|SA_I )
+ tlbentry( CFG_PCI_MEMBASE1, SZ_256M, CFG_PCI_MEMBASE1, 3, AC_R|AC_W|SA_G|SA_I )
+ tlbentry( CFG_PCI_MEMBASE2, SZ_256M, CFG_PCI_MEMBASE2, 3, AC_R|AC_W|SA_G|SA_I )
+
+ /* NAND */
+ tlbentry( CFG_NAND_BASE, SZ_4K, CFG_NAND_BASE, 1, AC_R|AC_W|AC_X|SA_G|SA_I )
+ tlbtab_end
diff --git a/board/prodrive/alpr/nand.c b/board/prodrive/alpr/nand.c
new file mode 100644
index 00000000000..d66b08847a5
--- /dev/null
+++ b/board/prodrive/alpr/nand.c
@@ -0,0 +1,175 @@
+/*
+ * (C) Copyright 2006
+ * Heiko Schocher, DENX Software Engineering, hs@denx.de
+ *
+ * (C) Copyright 2006
+ * Stefan Roese, DENX Software Engineering, sr@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+
+#if (CONFIG_COMMANDS & CFG_CMD_NAND)
+
+#include <asm/processor.h>
+#include <nand.h>
+
+struct alpr_ndfc_regs {
+ u8 cmd[4];
+ u8 addr_wait;
+ u8 term;
+ u8 dummy;
+ u8 dummy2;
+ u8 data;
+};
+
+static u8 hwctl;
+static struct alpr_ndfc_regs *alpr_ndfc = NULL;
+
+#define readb(addr) (u8)(*(volatile u8 *)(addr))
+#define writeb(d,addr) *(volatile u8 *)(addr) = ((u8)(d))
+
+/*
+ * The ALPR has a NAND Flash Controller (NDFC) that handles all accesses to
+ * the NAND devices. The NDFC has command, address and data registers that
+ * when accessed will set up the NAND flash pins appropriately. We'll use the
+ * hwcontrol function to save the configuration in a global variable.
+ * We can then use this information in the read and write functions to
+ * determine which NDFC register to access.
+ *
+ * There are 2 NAND devices on the board, a Hynix HY27US08561A (1 GByte).
+ */
+static void alpr_nand_hwcontrol(struct mtd_info *mtd, int cmd)
+{
+ switch (cmd) {
+ case NAND_CTL_SETCLE:
+ hwctl |= 0x1;
+ break;
+ case NAND_CTL_CLRCLE:
+ hwctl &= ~0x1;
+ break;
+ case NAND_CTL_SETALE:
+ hwctl |= 0x2;
+ break;
+ case NAND_CTL_CLRALE:
+ hwctl &= ~0x2;
+ break;
+ case NAND_CTL_SETNCE:
+ break;
+ case NAND_CTL_CLRNCE:
+ writeb(0x00, &(alpr_ndfc->term));
+ break;
+ }
+}
+
+static void alpr_nand_write_byte(struct mtd_info *mtd, u_char byte)
+{
+ struct nand_chip *nand = mtd->priv;
+
+ if (hwctl & 0x1)
+ /*
+ * IO_ADDR_W used as CMD[i] reg to support multiple NAND
+ * chips.
+ */
+ writeb(byte, nand->IO_ADDR_W);
+ else if (hwctl & 0x2) {
+ writeb(byte, &(alpr_ndfc->addr_wait));
+ } else
+ writeb(byte, &(alpr_ndfc->data));
+}
+
+static u_char alpr_nand_read_byte(struct mtd_info *mtd)
+{
+ return readb(&(alpr_ndfc->data));
+}
+
+static void alpr_nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len)
+{
+ struct nand_chip *nand = mtd->priv;
+ int i;
+
+ for (i = 0; i < len; i++) {
+ if (hwctl & 0x1)
+ /*
+ * IO_ADDR_W used as CMD[i] reg to support multiple NAND
+ * chips.
+ */
+ writeb(buf[i], nand->IO_ADDR_W);
+ else if (hwctl & 0x2)
+ writeb(buf[i], &(alpr_ndfc->addr_wait));
+ else
+ writeb(buf[i], &(alpr_ndfc->data));
+ }
+}
+
+static void alpr_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len)
+{
+ int i;
+
+ for (i = 0; i < len; i++) {
+ buf[i] = readb(&(alpr_ndfc->data));
+ }
+}
+
+static int alpr_nand_verify_buf(struct mtd_info *mtd, const u_char *buf, int len)
+{
+ int i;
+
+ for (i = 0; i < len; i++)
+ if (buf[i] != readb(&(alpr_ndfc->data)))
+ return i;
+
+ return 0;
+}
+
+static int alpr_nand_dev_ready(struct mtd_info *mtd)
+{
+ volatile u_char val;
+
+ /*
+ * Blocking read to wait for NAND to be ready
+ */
+ val = readb(&(alpr_ndfc->addr_wait));
+
+ /*
+ * Return always true
+ */
+ return 1;
+}
+
+int board_nand_init(struct nand_chip *nand)
+{
+ alpr_ndfc = (struct alpr_ndfc_regs *)CFG_NAND_BASE;
+
+ nand->eccmode = NAND_ECC_SOFT;
+
+ /* Reference hardware control function */
+ nand->hwcontrol = alpr_nand_hwcontrol;
+ /* Set command delay time */
+ nand->write_byte = alpr_nand_write_byte;
+ nand->read_byte = alpr_nand_read_byte;
+ nand->write_buf = alpr_nand_write_buf;
+ nand->read_buf = alpr_nand_read_buf;
+ nand->verify_buf = alpr_nand_verify_buf;
+ nand->dev_ready = alpr_nand_dev_ready;
+
+ return 0;
+}
+#endif
diff --git a/board/prodrive/alpr/u-boot.lds b/board/prodrive/alpr/u-boot.lds
new file mode 100644
index 00000000000..4f04089c945
--- /dev/null
+++ b/board/prodrive/alpr/u-boot.lds
@@ -0,0 +1,157 @@
+/*
+ * (C) Copyright 2004
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+OUTPUT_ARCH(powerpc)
+SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/local/powerpc-any-elf/lib);
+/* Do we need any of these for elf?
+ __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) }
+ .hash : { *(.hash) }
+ .dynsym : { *(.dynsym) }
+ .dynstr : { *(.dynstr) }
+ .rel.text : { *(.rel.text) }
+ .rela.text : { *(.rela.text) }
+ .rel.data : { *(.rel.data) }
+ .rela.data : { *(.rela.data) }
+ .rel.rodata : { *(.rel.rodata) }
+ .rela.rodata : { *(.rela.rodata) }
+ .rel.got : { *(.rel.got) }
+ .rela.got : { *(.rela.got) }
+ .rel.ctors : { *(.rel.ctors) }
+ .rela.ctors : { *(.rela.ctors) }
+ .rel.dtors : { *(.rel.dtors) }
+ .rela.dtors : { *(.rela.dtors) }
+ .rel.bss : { *(.rel.bss) }
+ .rela.bss : { *(.rela.bss) }
+ .rel.plt : { *(.rel.plt) }
+ .rela.plt : { *(.rela.plt) }
+ .init : { *(.init) }
+ .plt : { *(.plt) }
+ .text :
+ {
+ /* 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/prodrive/alpr/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)*/
+
+ *(.text)
+ *(.fixup)
+ *(.got1)
+ }
+ _etext = .;
+ PROVIDE (etext = .);
+ .rodata :
+ {
+ *(.rodata)
+ *(.rodata1)
+ *(.rodata.str1.4)
+ *(.eh_frame)
+ }
+ .fini : { *(.fini) } =0
+ .ctors : { *(.ctors) }
+ .dtors : { *(.dtors) }
+
+ /* Read-write section, merged into data segment: */
+ . = (. + 0x00FF) & 0xFFFFFF00;
+ _erotext = .;
+ PROVIDE (erotext = .);
+ .reloc :
+ {
+ *(.got)
+ _GOT2_TABLE_ = .;
+ *(.got2)
+ _FIXUP_TABLE_ = .;
+ *(.fixup)
+ }
+ __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2;
+ __fixup_entries = (. - _FIXUP_TABLE_)>>2;
+
+ .data :
+ {
+ *(.data)
+ *(.data1)
+ *(.sdata)
+ *(.sdata2)
+ *(.dynamic)
+ CONSTRUCTORS
+ }
+ _edata = .;
+ PROVIDE (edata = .);
+
+ . = .;
+ __u_boot_cmd_start = .;
+ .u_boot_cmd : { *(.u_boot_cmd) }
+ __u_boot_cmd_end = .;
+
+
+ . = .;
+ __start___ex_table = .;
+ __ex_table : { *(__ex_table) }
+ __stop___ex_table = .;
+
+ . = ALIGN(256);
+ __init_begin = .;
+ .text.init : { *(.text.init) }
+ .data.init : { *(.data.init) }
+ . = ALIGN(256);
+ __init_end = .;
+
+ __bss_start = .;
+ .bss :
+ {
+ *(.sbss) *(.scommon)
+ *(.dynbss)
+ *(.bss)
+ *(COMMON)
+ }
+ _end = . ;
+ PROVIDE (end = .);
+}
diff --git a/board/prodrive/common/flash.c b/board/prodrive/common/flash.c
index 8630cc16642..363631fd84f 100644
--- a/board/prodrive/common/flash.c
+++ b/board/prodrive/common/flash.c
@@ -48,6 +48,7 @@ void flash_print_info(flash_info_t *info)
case FLASH_MAN_AMD: printf ("AMD "); break;
case FLASH_MAN_FUJ: printf ("FUJITSU "); break;
case FLASH_MAN_SST: printf ("SST "); break;
+ case FLASH_MAN_STM: printf ("ST "); break;
case FLASH_MAN_EXCEL: printf ("Excel Semiconductor "); break;
default: printf ("Unknown Vendor "); break;
}
@@ -156,6 +157,9 @@ static ulong flash_get_size(vu_long *addr, flash_info_t *info)
case (CFG_FLASH_WORD_SIZE)SST_MANUFACT:
info->flash_id = FLASH_MAN_SST;
break;
+ case (CFG_FLASH_WORD_SIZE)STM_MANUFACT:
+ info->flash_id = FLASH_MAN_STM;
+ break;
case (CFG_FLASH_WORD_SIZE)EXCEL_MANUFACT:
info->flash_id = FLASH_MAN_EXCEL;
break;
diff --git a/board/prodrive/p3mx/64460.h b/board/prodrive/p3mx/64460.h
new file mode 100644
index 00000000000..8bb0ebfd219
--- /dev/null
+++ b/board/prodrive/p3mx/64460.h
@@ -0,0 +1,52 @@
+/*
+ * (C) Copyright 2003
+ * Ingo Assmus <ingo.assmus@keymile.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
+ */
+
+/*
+ * main board support/init for the Galileo Eval board DB64460.
+ */
+
+#ifndef __64460_H__
+#define __64460_H__
+
+/* CPU Configuration bits */
+#define CPU_CONF_ADDR_MISS_EN (1 << 8)
+#define CPU_CONF_SINGLE_CPU (1 << 11)
+#define CPU_CONF_ENDIANESS (1 << 12)
+#define CPU_CONF_PIPELINE (1 << 13)
+#define CPU_CONF_STOP_RETRY (1 << 17)
+#define CPU_CONF_MULTI_DECODE (1 << 18)
+#define CPU_CONF_DP_VALID (1 << 19)
+#define CPU_CONF_PERR_PROP (1 << 22)
+#define CPU_CONF_AACK_DELAY_2 (1 << 25)
+#define CPU_CONF_AP_VALID (1 << 26)
+#define CPU_CONF_REMAP_WR_DIS (1 << 27)
+
+/* CPU Master Control bits */
+#define CPU_MAST_CTL_ARB_EN (1 << 8)
+#define CPU_MAST_CTL_MASK_BR_1 (1 << 9)
+#define CPU_MAST_CTL_M_WR_TRIG (1 << 10)
+#define CPU_MAST_CTL_M_RD_TRIG (1 << 11)
+#define CPU_MAST_CTL_CLEAN_BLK (1 << 12)
+#define CPU_MAST_CTL_FLUSH_BLK (1 << 13)
+
+#endif /* __64460_H__ */
diff --git a/board/prodrive/p3mx/Makefile b/board/prodrive/p3mx/Makefile
new file mode 100644
index 00000000000..bf74a5a83b0
--- /dev/null
+++ b/board/prodrive/p3mx/Makefile
@@ -0,0 +1,55 @@
+#
+# (C) Copyright 2002-2006
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+include $(TOPDIR)/config.mk
+ifneq ($(OBJTREE),$(SRCTREE))
+$(shell mkdir -p $(obj)../../Marvell/common)
+endif
+
+LIB = $(obj)lib$(BOARD).a
+
+SOBJS = misc.o
+COBJS = $(BOARD).o mpsc.o mv_eth.o pci.o sdram_init.o serial.o \
+ ../../Marvell/common/i2c.o ../../Marvell/common/memory.o
+
+SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(COBJS))
+SOBJS := $(addprefix $(obj),$(SOBJS))
+
+$(LIB): $(obj).depend $(OBJS) $(SOBJS)
+ $(AR) $(ARFLAGS) $@ $(OBJS) $(SOBJS)
+
+clean:
+ rm -f $(SOBJS) $(OBJS)
+
+distclean: clean
+ rm -f $(LIB) core *.bak .depend *~
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/board/prodrive/p3mx/config.mk b/board/prodrive/p3mx/config.mk
new file mode 100644
index 00000000000..35bf1c1554e
--- /dev/null
+++ b/board/prodrive/p3mx/config.mk
@@ -0,0 +1,28 @@
+#
+# (C) Copyright 2002-2006
+# 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
+#
+
+#
+# p3mx boards (P3M750 & P3M7448)
+#
+
+TEXT_BASE = 0xfff00000
diff --git a/board/prodrive/p3mx/eth.h b/board/prodrive/p3mx/eth.h
new file mode 100644
index 00000000000..aab32d2a5af
--- /dev/null
+++ b/board/prodrive/p3mx/eth.h
@@ -0,0 +1,43 @@
+/*
+ * (C) Copyright 2001
+ * Josh Huber <huber@mclx.com>, Mission Critical Linux, Inc.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/*
+ * eth.h - header file for the polled mode GT ethernet driver
+ */
+
+#ifndef __EVB64360_ETH_H__
+#define __EVB64360_ETH_H__
+
+#include <asm/types.h>
+#include <asm/io.h>
+#include <asm/byteorder.h>
+#include <common.h>
+
+
+int db64360_eth0_poll(void);
+int db64360_eth0_transmit(unsigned int s, volatile char *p);
+void db64360_eth0_disable(void);
+bool network_start(bd_t *bis);
+
+
+#endif /* __EVB64360_ETH_H__ */
diff --git a/board/prodrive/p3mx/misc.S b/board/prodrive/p3mx/misc.S
new file mode 100644
index 00000000000..160b1d31f76
--- /dev/null
+++ b/board/prodrive/p3mx/misc.S
@@ -0,0 +1,245 @@
+#include <config.h>
+#include <74xx_7xx.h>
+#include "version.h"
+
+#include <ppc_asm.tmpl>
+#include <ppc_defs.h>
+
+#include <asm/cache.h>
+#include <asm/mmu.h>
+
+#include "../../Marvell/include/mv_gen_reg.h"
+
+#ifdef CONFIG_ECC
+ /* Galileo specific asm code for initializing ECC */
+ .globl board_relocate_rom
+board_relocate_rom:
+ mflr r7
+ /* update the location of the GT registers */
+ lis r11, CFG_GT_REGS@h
+ /* if we're using ECC, we must use the DMA engine to copy ourselves */
+ bl start_idma_transfer_0
+ bl wait_for_idma_0
+ bl stop_idma_engine_0
+
+ mtlr r7
+ blr
+
+ .globl board_init_ecc
+board_init_ecc:
+ mflr r7
+ /* NOTE: r10 still contains the location we've been relocated to
+ * which happens to be TOP_OF_RAM - CFG_MONITOR_LEN */
+
+ /* now that we're running from ram, init the rest of main memory
+ * for ECC use */
+ lis r8, CFG_MONITOR_LEN@h
+ ori r8, r8, CFG_MONITOR_LEN@l
+
+ divw r3, r10, r8
+
+ /* set up the counter, and init the starting address */
+ mtctr r3
+ li r12, 0
+
+ /* bytes per transfer */
+ mr r5, r8
+about_to_init_ecc:
+1: mr r3, r12
+ mr r4, r12
+ bl start_idma_transfer_0
+ bl wait_for_idma_0
+ bl stop_idma_engine_0
+ add r12, r12, r8
+ bdnz 1b
+
+ mtlr r7
+ blr
+
+ /* r3: dest addr
+ * r4: source addr
+ * r5: byte count
+ * r11: gt regbase
+ * trashes: r6, r5
+ */
+start_idma_transfer_0:
+ /* set the byte count, including the OWN bit */
+ mr r6, r11
+ ori r6, r6, CHANNEL0_DMA_BYTE_COUNT
+ stwbrx r5, 0, (r6)
+
+ /* set the source address */
+ mr r6, r11
+ ori r6, r6, CHANNEL0_DMA_SOURCE_ADDRESS
+ stwbrx r4, 0, (r6)
+
+ /* set the dest address */
+ mr r6, r11
+ ori r6, r6, CHANNEL0_DMA_DESTINATION_ADDRESS
+ stwbrx r3, 0, (r6)
+
+ /* set the next record pointer */
+ li r5, 0
+ mr r6, r11
+ ori r6, r6, CHANNEL0NEXT_RECORD_POINTER
+ stwbrx r5, 0, (r6)
+
+ /* set the low control register */
+ /* bit 9 is NON chained mode, bit 31 is new style descriptors.
+ bit 12 is channel enable */
+ ori r5, r5, (1 << 12) | (1 << 12) | (1 << 11)
+ /* 15 shifted by 16 (oris) == bit 31 */
+ oris r5, r5, (1 << 15)
+ mr r6, r11
+ ori r6, r6, CHANNEL0CONTROL
+ stwbrx r5, 0, (r6)
+
+ blr
+
+ /* this waits for the bytecount to return to zero, indicating
+ * that the trasfer is complete */
+wait_for_idma_0:
+ mr r5, r11
+ lis r6, 0xff
+ ori r6, r6, 0xffff
+ ori r5, r5, CHANNEL0_DMA_BYTE_COUNT
+1: lwbrx r4, 0, (r5)
+ and. r4, r4, r6
+ bne 1b
+
+ blr
+
+ /* this turns off channel 0 of the idma engine */
+stop_idma_engine_0:
+ /* shut off the DMA engine */
+ li r5, 0
+ mr r6, r11
+ ori r6, r6, CHANNEL0CONTROL
+ stwbrx r5, 0, (r6)
+
+ blr
+#endif
+
+#ifdef CFG_BOARD_ASM_INIT
+ /* NOTE: trashes r3-r7 */
+ .globl board_asm_init
+board_asm_init:
+ /* just move the GT registers to where they belong */
+ lis r3, CFG_DFL_GT_REGS@h
+ ori r3, r3, CFG_DFL_GT_REGS@l
+ lis r4, CFG_GT_REGS@h
+ ori r4, r4, CFG_GT_REGS@l
+ li r5, INTERNAL_SPACE_DECODE
+
+ /* test to see if we've already moved */
+ lwbrx r6, r5, r4
+ andi. r6, r6, 0xffff
+ /* check loading of R7 is: 0x0F80 should: 0xf800: DONE */
+/* rlwinm r7, r4, 8, 16, 31
+ rlwinm r7, r4, 12, 16, 31 */ /* original */
+ rlwinm r7, r4, 16, 16, 31
+ /* -----------------------------------------------------*/
+ cmp cr0, r7, r6
+ beqlr
+
+ /* nope, have to move the registers */
+ lwbrx r6, r5, r3
+ andis. r6, r6, 0xffff
+ or r6, r6, r7
+ stwbrx r6, r5, r3
+
+ /* now, poll for the change */
+1: lwbrx r7, r5, r4
+ cmp cr0, r7, r6
+ bne 1b
+
+ lis r3, CFG_INT_SRAM_BASE@h
+ ori r3, r3, CFG_INT_SRAM_BASE@l
+ rlwinm r3, r3, 16, 16, 31
+ lis r4, CFG_GT_REGS@h
+ ori r4, r4, CFG_GT_REGS@l
+ li r5, INTEGRATED_SRAM_BASE_ADDR
+ stwbrx r3, r5, r4
+
+2: lwbrx r6, r5, r4
+ cmp cr0, r3, r6
+ bne 2b
+
+ /* done! */
+ blr
+#endif
+
+/* For use of the debug LEDs */
+ .global led_on0_relocated
+led_on0_relocated:
+ xor r21, r21, r21
+ xor r18, r18, r18
+ lis r18, 0xFC80
+ ori r18, r18, 0x8000
+/* stw r21, 0x0(r18) */
+ sync
+ blr
+
+ .global led_off0_relocated
+led_off0_relocated:
+ xor r21, r21, r21
+ xor r18, r18, r18
+ lis r18, 0xFC81
+ ori r18, r18, 0x4000
+/* stw r21, 0x0(r18) */
+ sync
+ blr
+
+ .global led_on0
+led_on0:
+ xor r18, r18, r18
+ lis r18, 0x1c80
+ ori r18, r18, 0x8000
+/* stw r18, 0x0(r18) */
+ sync
+ blr
+
+ .global led_off0
+led_off0:
+ xor r18, r18, r18
+ lis r18, 0x1c81
+ ori r18, r18, 0x4000
+/* stw r18, 0x0(r18) */
+ sync
+ blr
+
+ .global led_on1
+led_on1:
+ xor r18, r18, r18
+ lis r18, 0x1c80
+ ori r18, r18, 0xc000
+/* stw r18, 0x0(r18) */
+ sync
+ blr
+
+ .global led_off1
+led_off1:
+ xor r18, r18, r18
+ lis r18, 0x1c81
+ ori r18, r18, 0x8000
+/* stw r18, 0x0(r18) */
+ sync
+ blr
+
+ .global led_on2
+led_on2:
+ xor r18, r18, r18
+ lis r18, 0x1c81
+ ori r18, r18, 0x0000
+/* stw r18, 0x0(r18) */
+ sync
+ blr
+
+ .global led_off2
+led_off2:
+ xor r18, r18, r18
+ lis r18, 0x1c81
+ ori r18, r18, 0xc000
+/* stw r18, 0x0(r18) */
+ sync
+ blr
diff --git a/board/prodrive/p3mx/mpsc.c b/board/prodrive/p3mx/mpsc.c
new file mode 100644
index 00000000000..da95cfa777f
--- /dev/null
+++ b/board/prodrive/p3mx/mpsc.c
@@ -0,0 +1,1013 @@
+/*
+ * (C) Copyright 2001
+ * John Clemens <clemens@mclx.com>, Mission Critical Linux, Inc.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/*************************************************************************
+ * changes for Marvell DB64460 eval board 2003 by Ingo Assmus <ingo.assmus@keymile.com>
+ *
+ ************************************************************************/
+
+/*
+ * mpsc.c - driver for console over the MPSC.
+ */
+
+
+#include <common.h>
+#include <config.h>
+#include <asm/cache.h>
+
+#include <malloc.h>
+#include "mpsc.h"
+
+#include "mv_regs.h"
+
+#include "../../Marvell/include/memory.h"
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/* Define this if you wish to use the MPSC as a register based UART.
+ * This will force the serial port to not use the SDMA engine at all.
+ */
+#undef CONFIG_MPSC_DEBUG_PORT
+
+
+int (*mpsc_putchar) (char ch) = mpsc_putchar_early;
+char (*mpsc_getchar) (void) = mpsc_getchar_debug;
+int (*mpsc_test_char) (void) = mpsc_test_char_debug;
+
+
+static volatile unsigned int *rx_desc_base = NULL;
+static unsigned int rx_desc_index = 0;
+static volatile unsigned int *tx_desc_base = NULL;
+static unsigned int tx_desc_index = 0;
+
+/* local function declarations */
+static int galmpsc_connect (int channel, int connect);
+static int galmpsc_route_rx_clock (int channel, int brg);
+static int galmpsc_route_tx_clock (int channel, int brg);
+static int galmpsc_write_config_regs (int mpsc, int mode);
+static int galmpsc_config_channel_regs (int mpsc);
+static int galmpsc_set_char_length (int mpsc, int value);
+static int galmpsc_set_stop_bit_length (int mpsc, int value);
+static int galmpsc_set_parity (int mpsc, int value);
+static int galmpsc_enter_hunt (int mpsc);
+static int galmpsc_set_brkcnt (int mpsc, int value);
+static int galmpsc_set_tcschar (int mpsc, int value);
+static int galmpsc_set_snoop (int mpsc, int value);
+static int galmpsc_shutdown (int mpsc);
+
+static int galsdma_set_RFT (int channel);
+static int galsdma_set_SFM (int channel);
+static int galsdma_set_rxle (int channel);
+static int galsdma_set_txle (int channel);
+static int galsdma_set_burstsize (int channel, unsigned int value);
+static int galsdma_set_RC (int channel, unsigned int value);
+
+static int galbrg_set_CDV (int channel, int value);
+static int galbrg_enable (int channel);
+static int galbrg_disable (int channel);
+static int galbrg_set_clksrc (int channel, int value);
+static int galbrg_set_CUV (int channel, int value);
+
+static void galsdma_enable_rx (void);
+static int galsdma_set_mem_space (unsigned int memSpace,
+ unsigned int memSpaceTarget,
+ unsigned int memSpaceAttr,
+ unsigned int baseAddress,
+ unsigned int size);
+
+
+#define SOFTWARE_CACHE_MANAGEMENT
+
+#ifdef SOFTWARE_CACHE_MANAGEMENT
+#define FLUSH_DCACHE(a,b) if(dcache_status()){clean_dcache_range((u32)(a),(u32)(b));}
+#define FLUSH_AND_INVALIDATE_DCACHE(a,b) if(dcache_status()){flush_dcache_range((u32)(a),(u32)(b));}
+#define INVALIDATE_DCACHE(a,b) if(dcache_status()){invalidate_dcache_range((u32)(a),(u32)(b));}
+#else
+#define FLUSH_DCACHE(a,b)
+#define FLUSH_AND_INVALIDATE_DCACHE(a,b)
+#define INVALIDATE_DCACHE(a,b)
+#endif
+
+#ifdef CONFIG_MPSC_DEBUG_PORT
+static void mpsc_debug_init (void)
+{
+
+ volatile unsigned int temp;
+
+ /* Clear the CFR (CHR4) */
+ /* Write random 'Z' bit (bit 29) of CHR4 to enable debug uart *UNDOCUMENTED FEATURE* */
+ temp = GTREGREAD (GALMPSC_CHANNELREG_4 + (CHANNEL * GALMPSC_REG_GAP));
+ temp &= 0xffffff00;
+ temp |= BIT29;
+ GT_REG_WRITE (GALMPSC_CHANNELREG_4 + (CHANNEL * GALMPSC_REG_GAP),
+ temp);
+
+ /* Set the Valid bit 'V' (bit 12) and int generation bit 'INT' (bit 15) */
+ temp = GTREGREAD (GALMPSC_CHANNELREG_5 + (CHANNEL * GALMPSC_REG_GAP));
+ temp |= (BIT12 | BIT15);
+ GT_REG_WRITE (GALMPSC_CHANNELREG_5 + (CHANNEL * GALMPSC_REG_GAP),
+ temp);
+
+ /* Set int mask */
+ temp = GTREGREAD (GALMPSC_0_INT_MASK);
+ temp |= BIT6;
+ GT_REG_WRITE (GALMPSC_0_INT_MASK, temp);
+}
+#endif
+
+char mpsc_getchar_debug (void)
+{
+ volatile int temp;
+ volatile unsigned int cause;
+
+ cause = GTREGREAD (GALMPSC_0_INT_CAUSE);
+ while ((cause & BIT6) == 0) {
+ cause = GTREGREAD (GALMPSC_0_INT_CAUSE);
+ }
+
+ temp = GTREGREAD (GALMPSC_CHANNELREG_10 +
+ (CHANNEL * GALMPSC_REG_GAP));
+ /* By writing 1's to the set bits, the register is cleared */
+ GT_REG_WRITE (GALMPSC_CHANNELREG_10 + (CHANNEL * GALMPSC_REG_GAP),
+ temp);
+ GT_REG_WRITE (GALMPSC_0_INT_CAUSE, cause & ~BIT6);
+ return (temp >> 16) & 0xff;
+}
+
+/* special function for running out of flash. doesn't modify any
+ * global variables [josh] */
+int mpsc_putchar_early (char ch)
+{
+ int mpsc = CHANNEL;
+ int temp =
+ GTREGREAD (GALMPSC_CHANNELREG_2 + (mpsc * GALMPSC_REG_GAP));
+ galmpsc_set_tcschar (mpsc, ch);
+ GT_REG_WRITE (GALMPSC_CHANNELREG_2 + (mpsc * GALMPSC_REG_GAP),
+ temp | 0x200);
+
+#define MAGIC_FACTOR (10*1000000)
+
+ udelay (MAGIC_FACTOR / gd->baudrate);
+ return 0;
+}
+
+/* This is used after relocation, see serial.c and mpsc_init2 */
+static int mpsc_putchar_sdma (char ch)
+{
+ volatile unsigned int *p;
+ unsigned int temp;
+
+
+ /* align the descriptor */
+ p = tx_desc_base;
+ memset ((void *) p, 0, 8 * sizeof (unsigned int));
+
+ /* fill one 64 bit buffer */
+ /* word swap, pad with 0 */
+ p[4] = 0; /* x */
+ p[5] = (unsigned int) ch; /* x */
+
+ /* CHANGED completely according to GT64260A dox - NTL */
+ p[0] = 0x00010001; /* 0 */
+ p[1] = DESC_OWNER_BIT | DESC_FIRST | DESC_LAST; /* 4 */
+ p[2] = 0; /* 8 */
+ p[3] = (unsigned int) &p[4]; /* c */
+
+#if 0
+ p[9] = DESC_FIRST | DESC_LAST;
+ p[10] = (unsigned int) &p[0];
+ p[11] = (unsigned int) &p[12];
+#endif
+
+ FLUSH_DCACHE (&p[0], &p[8]);
+
+ GT_REG_WRITE (GALSDMA_0_CUR_TX_PTR + (CHANNEL * GALSDMA_REG_DIFF),
+ (unsigned int) &p[0]);
+ GT_REG_WRITE (GALSDMA_0_FIR_TX_PTR + (CHANNEL * GALSDMA_REG_DIFF),
+ (unsigned int) &p[0]);
+
+ temp = GTREGREAD (GALSDMA_0_COM_REG + (CHANNEL * GALSDMA_REG_DIFF));
+ temp |= (TX_DEMAND | TX_STOP);
+ GT_REG_WRITE (GALSDMA_0_COM_REG + (CHANNEL * GALSDMA_REG_DIFF), temp);
+
+ INVALIDATE_DCACHE (&p[1], &p[2]);
+
+ while (p[1] & DESC_OWNER_BIT) {
+ udelay (100);
+ INVALIDATE_DCACHE (&p[1], &p[2]);
+ }
+ return 0;
+}
+
+char mpsc_getchar_sdma (void)
+{
+ static unsigned int done = 0;
+ volatile char ch;
+ unsigned int len = 0, idx = 0, temp;
+
+ volatile unsigned int *p;
+
+
+ do {
+ p = &rx_desc_base[rx_desc_index * 8];
+
+ INVALIDATE_DCACHE (&p[0], &p[1]);
+ /* Wait for character */
+ while (p[1] & DESC_OWNER_BIT) {
+ udelay (100);
+ INVALIDATE_DCACHE (&p[0], &p[1]);
+ }
+
+ /* Handle error case */
+ if (p[1] & (1 << 15)) {
+ printf ("oops, error: %08x\n", p[1]);
+
+ temp = GTREGREAD (GALMPSC_CHANNELREG_2 +
+ (CHANNEL * GALMPSC_REG_GAP));
+ temp |= (1 << 23);
+ GT_REG_WRITE (GALMPSC_CHANNELREG_2 +
+ (CHANNEL * GALMPSC_REG_GAP), temp);
+
+ /* Can't poll on abort bit, so we just wait. */
+ udelay (100);
+
+ galsdma_enable_rx ();
+ }
+
+ /* Number of bytes left in this descriptor */
+ len = p[0] & 0xffff;
+
+ if (len) {
+ /* Where to look */
+ idx = 5;
+ if (done > 3)
+ idx = 4;
+ if (done > 7)
+ idx = 7;
+ if (done > 11)
+ idx = 6;
+
+ INVALIDATE_DCACHE (&p[idx], &p[idx + 1]);
+ ch = p[idx] & 0xff;
+ done++;
+ }
+
+ if (done < len) {
+ /* this descriptor has more bytes still
+ * shift down the char we just read, and leave the
+ * buffer in place for the next time around
+ */
+ p[idx] = p[idx] >> 8;
+ FLUSH_DCACHE (&p[idx], &p[idx + 1]);
+ }
+
+ if (done == len) {
+ /* nothing left in this descriptor.
+ * go to next one
+ */
+ p[1] = DESC_OWNER_BIT | DESC_FIRST | DESC_LAST;
+ p[0] = 0x00100000;
+ FLUSH_DCACHE (&p[0], &p[1]);
+ /* Next descriptor */
+ rx_desc_index = (rx_desc_index + 1) % RX_DESC;
+ done = 0;
+ }
+ } while (len == 0); /* galileo bug.. len might be zero */
+
+ return ch;
+}
+
+
+int mpsc_test_char_debug (void)
+{
+ if ((GTREGREAD (GALMPSC_0_INT_CAUSE) & BIT6) == 0)
+ return 0;
+ else {
+ return 1;
+ }
+}
+
+
+int mpsc_test_char_sdma (void)
+{
+ volatile unsigned int *p = &rx_desc_base[rx_desc_index * 8];
+
+ INVALIDATE_DCACHE (&p[1], &p[2]);
+
+ if (p[1] & DESC_OWNER_BIT)
+ return 0;
+ else
+ return 1;
+}
+
+int mpsc_init (int baud)
+{
+ /* BRG CONFIG */
+ galbrg_set_baudrate (CHANNEL, baud);
+ galbrg_set_clksrc (CHANNEL, 8); /* set source=Tclk */
+ galbrg_set_CUV (CHANNEL, 0); /* set up CountUpValue */
+ galbrg_enable (CHANNEL); /* Enable BRG */
+
+ /* Set up clock routing */
+ galmpsc_connect (CHANNEL, GALMPSC_CONNECT); /* connect it */
+
+ galmpsc_route_rx_clock (CHANNEL, CHANNEL); /* chosse BRG0 for Rx */
+ galmpsc_route_tx_clock (CHANNEL, CHANNEL); /* chose BRG0 for Tx */
+
+ /* reset MPSC state */
+ galmpsc_shutdown (CHANNEL);
+
+ /* SDMA CONFIG */
+ galsdma_set_burstsize (CHANNEL, L1_CACHE_BYTES / 8); /* in 64 bit words (8 bytes) */
+ galsdma_set_txle (CHANNEL);
+ galsdma_set_rxle (CHANNEL);
+ galsdma_set_RC (CHANNEL, 0xf);
+ galsdma_set_SFM (CHANNEL);
+ galsdma_set_RFT (CHANNEL);
+
+ /* MPSC CONFIG */
+ galmpsc_write_config_regs (CHANNEL, GALMPSC_UART);
+ galmpsc_config_channel_regs (CHANNEL);
+ galmpsc_set_char_length (CHANNEL, GALMPSC_CHAR_LENGTH_8); /* 8 */
+ galmpsc_set_parity (CHANNEL, GALMPSC_PARITY_NONE); /* N */
+ galmpsc_set_stop_bit_length (CHANNEL, GALMPSC_STOP_BITS_1); /* 1 */
+
+#ifdef CONFIG_MPSC_DEBUG_PORT
+ mpsc_debug_init ();
+#endif
+
+ /* COMM_MPSC CONFIG */
+#ifdef SOFTWARE_CACHE_MANAGEMENT
+ galmpsc_set_snoop (CHANNEL, 0); /* disable snoop */
+#else
+ galmpsc_set_snoop (CHANNEL, 1); /* enable snoop */
+#endif
+
+ return 0;
+}
+
+
+void mpsc_sdma_init (void)
+{
+ /* Setup SDMA channel0 SDMA_CONFIG_REG*/
+ GT_REG_WRITE (SDMA_CONFIG_REG (0), 0x000020ff);
+
+ /* Enable MPSC-Window0 for DRAM Bank 0 */
+ if (galsdma_set_mem_space (MV64460_CUNIT_BASE_ADDR_WIN_0_BIT,
+ MV64460_SDMA_DRAM_CS_0_TARGET,
+ 0,
+ memoryGetBankBaseAddress(0),
+ memoryGetBankSize(0)) != true)
+ printf ("%s: SDMA_Window0 memory setup failed !!! \n",
+ __FUNCTION__);
+
+
+ /* Enable MPSC-Window1 for DRAM Bank 1 */
+ if (galsdma_set_mem_space (MV64460_CUNIT_BASE_ADDR_WIN_1_BIT,
+ MV64460_SDMA_DRAM_CS_1_TARGET,
+ 0,
+ memoryGetBankBaseAddress(1),
+ memoryGetBankSize(1)) != true)
+ printf ("%s: SDMA_Window1 memory setup failed !!! \n",
+ __FUNCTION__);
+
+
+ /* Disable MPSC-Window2 */
+ if (galsdma_set_mem_space (MV64460_CUNIT_BASE_ADDR_WIN_2_BIT,
+ MV64460_SDMA_DRAM_CS_2_TARGET,
+ 0,
+ memoryGetBankBaseAddress(2),
+ memoryGetBankSize(2)) != true)
+ printf ("%s: SDMA_Window2 memory setup failed !!! \n",
+ __FUNCTION__);
+
+
+ /* Disable MPSC-Window3 */
+ if (galsdma_set_mem_space (MV64460_CUNIT_BASE_ADDR_WIN_3_BIT,
+ MV64460_SDMA_DRAM_CS_3_TARGET,
+ 0,
+ memoryGetBankBaseAddress(3),
+ memoryGetBankSize(3)) != true)
+ printf ("%s: SDMA_Window3 memory setup failed !!! \n",
+ __FUNCTION__);
+
+ /* Setup MPSC0 access mode Window0 full access */
+ GT_SET_REG_BITS (MPSC0_ACCESS_PROTECTION_REG,
+ (MV64460_SDMA_WIN_ACCESS_FULL <<
+ (MV64460_CUNIT_BASE_ADDR_WIN_0_BIT * 2)));
+
+ /* Setup MPSC1 access mode Window1 full access */
+ GT_SET_REG_BITS (MPSC1_ACCESS_PROTECTION_REG,
+ (MV64460_SDMA_WIN_ACCESS_FULL <<
+ (MV64460_CUNIT_BASE_ADDR_WIN_0_BIT * 2)));
+
+ /* Setup MPSC internal address space base address */
+ GT_REG_WRITE (CUNIT_INTERNAL_SPACE_BASE_ADDR_REG, CFG_GT_REGS);
+
+ /* no high address remap*/
+ GT_REG_WRITE (CUNIT_HIGH_ADDR_REMAP_REG0, 0x00);
+ GT_REG_WRITE (CUNIT_HIGH_ADDR_REMAP_REG1, 0x00);
+
+ /* clear interrupt cause register for MPSC (fault register)*/
+ GT_REG_WRITE (CUNIT_INTERRUPT_CAUSE_REG, 0x00);
+}
+
+
+void mpsc_init2 (void)
+{
+ int i;
+
+#ifndef CONFIG_MPSC_DEBUG_PORT
+ mpsc_putchar = mpsc_putchar_sdma;
+ mpsc_getchar = mpsc_getchar_sdma;
+ mpsc_test_char = mpsc_test_char_sdma;
+#endif
+ /* RX descriptors */
+ rx_desc_base = (unsigned int *) malloc (((RX_DESC + 1) * 8) *
+ sizeof (unsigned int));
+
+ /* align descriptors */
+ rx_desc_base = (unsigned int *)
+ (((unsigned int) rx_desc_base + 32) & 0xFFFFFFF0);
+
+ rx_desc_index = 0;
+
+ memset ((void *) rx_desc_base, 0,
+ (RX_DESC * 8) * sizeof (unsigned int));
+
+ for (i = 0; i < RX_DESC; i++) {
+ rx_desc_base[i * 8 + 3] = (unsigned int) &rx_desc_base[i * 8 + 4]; /* Buffer */
+ rx_desc_base[i * 8 + 2] = (unsigned int) &rx_desc_base[(i + 1) * 8]; /* Next descriptor */
+ rx_desc_base[i * 8 + 1] = DESC_OWNER_BIT | DESC_FIRST | DESC_LAST; /* Command & control */
+ rx_desc_base[i * 8] = 0x00100000;
+ }
+ rx_desc_base[(i - 1) * 8 + 2] = (unsigned int) &rx_desc_base[0];
+
+ FLUSH_DCACHE (&rx_desc_base[0], &rx_desc_base[RX_DESC * 8]);
+ GT_REG_WRITE (GALSDMA_0_CUR_RX_PTR + (CHANNEL * GALSDMA_REG_DIFF),
+ (unsigned int) &rx_desc_base[0]);
+
+ /* TX descriptors */
+ tx_desc_base = (unsigned int *) malloc (((TX_DESC + 1) * 8) *
+ sizeof (unsigned int));
+
+ /* align descriptors */
+ tx_desc_base = (unsigned int *)
+ (((unsigned int) tx_desc_base + 32) & 0xFFFFFFF0);
+
+ tx_desc_index = -1;
+
+ memset ((void *) tx_desc_base, 0,
+ (TX_DESC * 8) * sizeof (unsigned int));
+
+ for (i = 0; i < TX_DESC; i++) {
+ tx_desc_base[i * 8 + 5] = (unsigned int) 0x23232323;
+ tx_desc_base[i * 8 + 4] = (unsigned int) 0x23232323;
+ tx_desc_base[i * 8 + 3] =
+ (unsigned int) &tx_desc_base[i * 8 + 4];
+ tx_desc_base[i * 8 + 2] =
+ (unsigned int) &tx_desc_base[(i + 1) * 8];
+ tx_desc_base[i * 8 + 1] =
+ DESC_OWNER_BIT | DESC_FIRST | DESC_LAST;
+
+ /* set sbytecnt and shadow byte cnt to 1 */
+ tx_desc_base[i * 8] = 0x00010001;
+ }
+ tx_desc_base[(i - 1) * 8 + 2] = (unsigned int) &tx_desc_base[0];
+
+ FLUSH_DCACHE (&tx_desc_base[0], &tx_desc_base[TX_DESC * 8]);
+
+ udelay (100);
+
+ galsdma_enable_rx ();
+
+ return;
+}
+
+int galbrg_set_baudrate (int channel, int rate)
+{
+ int clock;
+
+ galbrg_disable (channel); /*ok */
+
+#ifdef ZUMA_NTL
+ /* from tclk */
+ clock = (CFG_TCLK / (16 * rate)) - 1;
+#else
+ clock = (CFG_TCLK / (16 * rate)) - 1;
+#endif
+
+ galbrg_set_CDV (channel, clock); /* set timer Reg. for BRG */
+
+ galbrg_enable (channel);
+
+ gd->baudrate = rate;
+
+ return 0;
+}
+
+/* ------------------------------------------------------------------ */
+
+/* Below are all the private functions that no one else needs */
+
+static int galbrg_set_CDV (int channel, int value)
+{
+ unsigned int temp;
+
+ temp = GTREGREAD (GALBRG_0_CONFREG + (channel * GALBRG_REG_GAP));
+ temp &= 0xFFFF0000;
+ temp |= (value & 0x0000FFFF);
+ GT_REG_WRITE (GALBRG_0_CONFREG + (channel * GALBRG_REG_GAP), temp);
+
+ return 0;
+}
+
+static int galbrg_enable (int channel)
+{
+ unsigned int temp;
+
+ temp = GTREGREAD (GALBRG_0_CONFREG + (channel * GALBRG_REG_GAP));
+ temp |= 0x00010000;
+ GT_REG_WRITE (GALBRG_0_CONFREG + (channel * GALBRG_REG_GAP), temp);
+
+ return 0;
+}
+
+static int galbrg_disable (int channel)
+{
+ unsigned int temp;
+
+ temp = GTREGREAD (GALBRG_0_CONFREG + (channel * GALBRG_REG_GAP));
+ temp &= 0xFFFEFFFF;
+ GT_REG_WRITE (GALBRG_0_CONFREG + (channel * GALBRG_REG_GAP), temp);
+
+ return 0;
+}
+
+static int galbrg_set_clksrc (int channel, int value)
+{
+ unsigned int temp;
+
+ temp = GTREGREAD (GALBRG_0_CONFREG + (channel * GALBRG_REG_GAP));
+ temp &= 0xFFC3FFFF; /* Bit 18 - 21 (MV 64260 18-22) */
+ temp |= (value << 18);
+ GT_REG_WRITE (GALBRG_0_CONFREG + (channel * GALBRG_REG_GAP), temp);
+ return 0;
+}
+
+static int galbrg_set_CUV (int channel, int value)
+{
+ /* set CountUpValue */
+ GT_REG_WRITE (GALBRG_0_BTREG + (channel * GALBRG_REG_GAP), value);
+
+ return 0;
+}
+
+#if 0
+static int galbrg_reset (int channel)
+{
+ unsigned int temp;
+
+ temp = GTREGREAD (GALBRG_0_CONFREG + (channel * GALBRG_REG_GAP));
+ temp |= 0x20000;
+ GT_REG_WRITE (GALBRG_0_CONFREG + (channel * GALBRG_REG_GAP), temp);
+
+ return 0;
+}
+#endif
+
+static int galsdma_set_RFT (int channel)
+{
+ unsigned int temp;
+
+ temp = GTREGREAD (GALSDMA_0_CONF_REG + (channel * GALSDMA_REG_DIFF));
+ temp |= 0x00000001;
+ GT_REG_WRITE (GALSDMA_0_CONF_REG + (channel * GALSDMA_REG_DIFF),
+ temp);
+
+ return 0;
+}
+
+static int galsdma_set_SFM (int channel)
+{
+ unsigned int temp;
+
+ temp = GTREGREAD (GALSDMA_0_CONF_REG + (channel * GALSDMA_REG_DIFF));
+ temp |= 0x00000002;
+ GT_REG_WRITE (GALSDMA_0_CONF_REG + (channel * GALSDMA_REG_DIFF),
+ temp);
+
+ return 0;
+}
+
+static int galsdma_set_rxle (int channel)
+{
+ unsigned int temp;
+
+ temp = GTREGREAD (GALSDMA_0_CONF_REG + (channel * GALSDMA_REG_DIFF));
+ temp |= 0x00000040;
+ GT_REG_WRITE (GALSDMA_0_CONF_REG + (channel * GALSDMA_REG_DIFF),
+ temp);
+
+ return 0;
+}
+
+static int galsdma_set_txle (int channel)
+{
+ unsigned int temp;
+
+ temp = GTREGREAD (GALSDMA_0_CONF_REG + (channel * GALSDMA_REG_DIFF));
+ temp |= 0x00000080;
+ GT_REG_WRITE (GALSDMA_0_CONF_REG + (channel * GALSDMA_REG_DIFF),
+ temp);
+
+ return 0;
+}
+
+static int galsdma_set_RC (int channel, unsigned int value)
+{
+ unsigned int temp;
+
+ temp = GTREGREAD (GALSDMA_0_CONF_REG + (channel * GALSDMA_REG_DIFF));
+ temp &= ~0x0000003c;
+ temp |= (value << 2);
+ GT_REG_WRITE (GALSDMA_0_CONF_REG + (channel * GALSDMA_REG_DIFF),
+ temp);
+
+ return 0;
+}
+
+static int galsdma_set_burstsize (int channel, unsigned int value)
+{
+ unsigned int temp;
+
+ temp = GTREGREAD (GALSDMA_0_CONF_REG + (channel * GALSDMA_REG_DIFF));
+ temp &= 0xFFFFCFFF;
+ switch (value) {
+ case 8:
+ GT_REG_WRITE (GALSDMA_0_CONF_REG +
+ (channel * GALSDMA_REG_DIFF),
+ (temp | (0x3 << 12)));
+ break;
+
+ case 4:
+ GT_REG_WRITE (GALSDMA_0_CONF_REG +
+ (channel * GALSDMA_REG_DIFF),
+ (temp | (0x2 << 12)));
+ break;
+
+ case 2:
+ GT_REG_WRITE (GALSDMA_0_CONF_REG +
+ (channel * GALSDMA_REG_DIFF),
+ (temp | (0x1 << 12)));
+ break;
+
+ case 1:
+ GT_REG_WRITE (GALSDMA_0_CONF_REG +
+ (channel * GALSDMA_REG_DIFF),
+ (temp | (0x0 << 12)));
+ break;
+
+ default:
+ return -1;
+ break;
+ }
+
+ return 0;
+}
+
+static int galmpsc_connect (int channel, int connect)
+{
+ unsigned int temp;
+
+ temp = GTREGREAD (GALMPSC_ROUTING_REGISTER);
+
+ if ((channel == 0) && connect)
+ temp &= ~0x00000007;
+ else if ((channel == 1) && connect)
+ temp &= ~(0x00000007 << 6);
+ else if ((channel == 0) && !connect)
+ temp |= 0x00000007;
+ else
+ temp |= (0x00000007 << 6);
+
+ /* Just in case... */
+ temp &= 0x3fffffff;
+
+ GT_REG_WRITE (GALMPSC_ROUTING_REGISTER, temp);
+
+ return 0;
+}
+
+static int galmpsc_route_rx_clock (int channel, int brg)
+{
+ unsigned int temp;
+
+ temp = GTREGREAD (GALMPSC_RxC_ROUTE);
+
+ if (channel == 0) {
+ temp &= ~0x0000000F;
+ temp |= brg;
+ } else {
+ temp &= ~0x00000F00;
+ temp |= (brg << 8);
+ }
+
+ GT_REG_WRITE (GALMPSC_RxC_ROUTE, temp);
+
+ return 0;
+}
+
+static int galmpsc_route_tx_clock (int channel, int brg)
+{
+ unsigned int temp;
+
+ temp = GTREGREAD (GALMPSC_TxC_ROUTE);
+
+ if (channel == 0) {
+ temp &= ~0x0000000F;
+ temp |= brg;
+ } else {
+ temp &= ~0x00000F00;
+ temp |= (brg << 8);
+ }
+
+ GT_REG_WRITE (GALMPSC_TxC_ROUTE, temp);
+
+ return 0;
+}
+
+static int galmpsc_write_config_regs (int mpsc, int mode)
+{
+ if (mode == GALMPSC_UART) {
+ /* Main config reg Low (Null modem, Enable Tx/Rx, UART mode) */
+ GT_REG_WRITE (GALMPSC_MCONF_LOW + (mpsc * GALMPSC_REG_GAP),
+ 0x000004c4);
+
+ /* Main config reg High (32x Rx/Tx clock mode, width=8bits */
+ GT_REG_WRITE (GALMPSC_MCONF_HIGH + (mpsc * GALMPSC_REG_GAP),
+ 0x024003f8);
+ /* 22 2222 1111 */
+ /* 54 3210 9876 */
+ /* 0000 0010 0000 0000 */
+ /* 1 */
+ /* 098 7654 3210 */
+ /* 0000 0011 1111 1000 */
+ } else
+ return -1;
+
+ return 0;
+}
+
+static int galmpsc_config_channel_regs (int mpsc)
+{
+ GT_REG_WRITE (GALMPSC_CHANNELREG_1 + (mpsc * GALMPSC_REG_GAP), 0);
+ GT_REG_WRITE (GALMPSC_CHANNELREG_2 + (mpsc * GALMPSC_REG_GAP), 0);
+ GT_REG_WRITE (GALMPSC_CHANNELREG_3 + (mpsc * GALMPSC_REG_GAP), 1);
+ GT_REG_WRITE (GALMPSC_CHANNELREG_4 + (mpsc * GALMPSC_REG_GAP), 0);
+ GT_REG_WRITE (GALMPSC_CHANNELREG_5 + (mpsc * GALMPSC_REG_GAP), 0);
+ GT_REG_WRITE (GALMPSC_CHANNELREG_6 + (mpsc * GALMPSC_REG_GAP), 0);
+ GT_REG_WRITE (GALMPSC_CHANNELREG_7 + (mpsc * GALMPSC_REG_GAP), 0);
+ GT_REG_WRITE (GALMPSC_CHANNELREG_8 + (mpsc * GALMPSC_REG_GAP), 0);
+ GT_REG_WRITE (GALMPSC_CHANNELREG_9 + (mpsc * GALMPSC_REG_GAP), 0);
+ GT_REG_WRITE (GALMPSC_CHANNELREG_10 + (mpsc * GALMPSC_REG_GAP), 0);
+
+ galmpsc_set_brkcnt (mpsc, 0x3);
+ galmpsc_set_tcschar (mpsc, 0xab);
+
+ return 0;
+}
+
+static int galmpsc_set_brkcnt (int mpsc, int value)
+{
+ unsigned int temp;
+
+ temp = GTREGREAD (GALMPSC_CHANNELREG_1 + (mpsc * GALMPSC_REG_GAP));
+ temp &= 0x0000FFFF;
+ temp |= (value << 16);
+ GT_REG_WRITE (GALMPSC_CHANNELREG_1 + (mpsc * GALMPSC_REG_GAP), temp);
+
+ return 0;
+}
+
+static int galmpsc_set_tcschar (int mpsc, int value)
+{
+ unsigned int temp;
+
+ temp = GTREGREAD (GALMPSC_CHANNELREG_1 + (mpsc * GALMPSC_REG_GAP));
+ temp &= 0xFFFF0000;
+ temp |= value;
+ GT_REG_WRITE (GALMPSC_CHANNELREG_1 + (mpsc * GALMPSC_REG_GAP), temp);
+
+ return 0;
+}
+
+static int galmpsc_set_char_length (int mpsc, int value)
+{
+ unsigned int temp;
+
+ temp = GTREGREAD (GALMPSC_PROTOCONF_REG + (mpsc * GALMPSC_REG_GAP));
+ temp &= 0xFFFFCFFF;
+ temp |= (value << 12);
+ GT_REG_WRITE (GALMPSC_PROTOCONF_REG + (mpsc * GALMPSC_REG_GAP), temp);
+
+ return 0;
+}
+
+static int galmpsc_set_stop_bit_length (int mpsc, int value)
+{
+ unsigned int temp;
+
+ temp = GTREGREAD (GALMPSC_PROTOCONF_REG + (mpsc * GALMPSC_REG_GAP));
+ temp &= 0xFFFFBFFF;
+ temp |= (value << 14);
+ GT_REG_WRITE (GALMPSC_PROTOCONF_REG + (mpsc * GALMPSC_REG_GAP), temp);
+
+ return 0;
+}
+
+static int galmpsc_set_parity (int mpsc, int value)
+{
+ unsigned int temp;
+
+ temp = GTREGREAD (GALMPSC_CHANNELREG_2 + (mpsc * GALMPSC_REG_GAP));
+ if (value != -1) {
+ temp &= 0xFFF3FFF3;
+ temp |= ((value << 18) | (value << 2));
+ temp |= ((value << 17) | (value << 1));
+ } else {
+ temp &= 0xFFF1FFF1;
+ }
+
+ GT_REG_WRITE (GALMPSC_CHANNELREG_2 + (mpsc * GALMPSC_REG_GAP), temp);
+
+ return 0;
+}
+
+static int galmpsc_enter_hunt (int mpsc)
+{
+ int temp;
+
+ temp = GTREGREAD (GALMPSC_CHANNELREG_2 + (mpsc * GALMPSC_REG_GAP));
+ temp |= 0x80000000;
+ GT_REG_WRITE (GALMPSC_CHANNELREG_2 + (mpsc * GALMPSC_REG_GAP), temp);
+
+ while (GTREGREAD (GALMPSC_CHANNELREG_2 + (mpsc * GALMPSC_REG_GAP)) &
+ MPSC_ENTER_HUNT) {
+ udelay (1);
+ }
+ return 0;
+}
+
+
+static int galmpsc_shutdown (int mpsc)
+{
+ unsigned int temp;
+
+ /* cause RX abort (clears RX) */
+ temp = GTREGREAD (GALMPSC_CHANNELREG_2 + (mpsc * GALMPSC_REG_GAP));
+ temp |= MPSC_RX_ABORT | MPSC_TX_ABORT;
+ temp &= ~MPSC_ENTER_HUNT;
+ GT_REG_WRITE (GALMPSC_CHANNELREG_2 + (mpsc * GALMPSC_REG_GAP), temp);
+
+ GT_REG_WRITE (GALSDMA_0_COM_REG, 0);
+ GT_REG_WRITE (GALSDMA_0_COM_REG, SDMA_TX_ABORT | SDMA_RX_ABORT);
+
+ /* shut down the MPSC */
+ GT_REG_WRITE (GALMPSC_MCONF_LOW, 0);
+ GT_REG_WRITE (GALMPSC_MCONF_HIGH, 0);
+ GT_REG_WRITE (GALMPSC_PROTOCONF_REG + (mpsc * GALMPSC_REG_GAP), 0);
+
+ udelay (100);
+
+ /* shut down the sdma engines. */
+ /* reset config to default */
+ GT_REG_WRITE (GALSDMA_0_CONF_REG, 0x000000fc);
+
+ udelay (100);
+
+ /* clear the SDMA current and first TX and RX pointers */
+ GT_REG_WRITE (GALSDMA_0_CUR_RX_PTR, 0);
+ GT_REG_WRITE (GALSDMA_0_CUR_TX_PTR, 0);
+ GT_REG_WRITE (GALSDMA_0_FIR_TX_PTR, 0);
+
+ udelay (100);
+
+ return 0;
+}
+
+static void galsdma_enable_rx (void)
+{
+ int temp;
+
+ /* Enable RX processing */
+ temp = GTREGREAD (GALSDMA_0_COM_REG + (CHANNEL * GALSDMA_REG_DIFF));
+ temp |= RX_ENABLE;
+ GT_REG_WRITE (GALSDMA_0_COM_REG + (CHANNEL * GALSDMA_REG_DIFF), temp);
+
+ galmpsc_enter_hunt (CHANNEL);
+}
+
+static int galmpsc_set_snoop (int mpsc, int value)
+{
+ int reg =
+ mpsc ? MPSC_1_ADDRESS_CONTROL_LOW :
+ MPSC_0_ADDRESS_CONTROL_LOW;
+ int temp = GTREGREAD (reg);
+
+ if (value)
+ temp |= (1 << 6) | (1 << 14) | (1 << 22) | (1 << 30);
+ else
+ temp &= ~((1 << 6) | (1 << 14) | (1 << 22) | (1 << 30));
+ GT_REG_WRITE (reg, temp);
+ return 0;
+}
+
+/*******************************************************************************
+* galsdma_set_mem_space - Set MV64460 IDMA memory decoding map.
+*
+* DESCRIPTION:
+* the MV64460 SDMA has its own address decoding map that is de-coupled
+* from the CPU interface address decoding windows. The SDMA channels
+* share four address windows. Each region can be individually configured
+* by this function by associating it to a target interface and setting
+* base and size values.
+*
+* NOTE!!!
+* The size must be in 64Kbyte granularity.
+* The base address must be aligned to the size.
+* The size must be a series of 1s followed by a series of zeros
+*
+* OUTPUT:
+* None.
+*
+* RETURN:
+* True for success, false otherwise.
+*
+*******************************************************************************/
+
+static int galsdma_set_mem_space (unsigned int memSpace,
+ unsigned int memSpaceTarget,
+ unsigned int memSpaceAttr,
+ unsigned int baseAddress, unsigned int size)
+{
+ unsigned int temp;
+
+ if (size == 0) {
+ GT_RESET_REG_BITS (MV64460_CUNIT_BASE_ADDR_ENABLE_REG,
+ 1 << memSpace);
+ return true;
+ }
+
+ /* The base address must be aligned to the size. */
+ if (baseAddress % size != 0) {
+ return false;
+ }
+ if (size < 0x10000) {
+ return false;
+ }
+
+ /* Align size and base to 64K */
+ baseAddress &= 0xffff0000;
+ size &= 0xffff0000;
+ temp = size >> 16;
+
+ /* Checking that the size is a sequence of '1' followed by a
+ sequence of '0' starting from LSB to MSB. */
+ while ((temp > 0) && (temp & 0x1)) {
+ temp = temp >> 1;
+ }
+
+ if (temp != 0) {
+ GT_REG_WRITE (MV64460_CUNIT_BASE_ADDR_REG0 + memSpace * 8,
+ (baseAddress | memSpaceTarget | memSpaceAttr));
+ GT_REG_WRITE ((MV64460_CUNIT_SIZE0 + memSpace * 8),
+ (size - 1) & 0xffff0000);
+ GT_RESET_REG_BITS (MV64460_CUNIT_BASE_ADDR_ENABLE_REG,
+ 1 << memSpace);
+ } else {
+ /* An invalid size was specified */
+ return false;
+ }
+ return true;
+}
diff --git a/board/prodrive/p3mx/mpsc.h b/board/prodrive/p3mx/mpsc.h
new file mode 100644
index 00000000000..a03d1cc0f84
--- /dev/null
+++ b/board/prodrive/p3mx/mpsc.h
@@ -0,0 +1,156 @@
+/*
+ * (C) Copyright 2001
+ * John Clemens <clemens@mclx.com>, Mission Critical Linux, Inc.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/*************************************************************************
+ * changes for Marvell DB64360 eval board 2003 by Ingo Assmus <ingo.assmus@keymile.com>
+ *
+ ************************************************************************/
+
+
+/*
+ * mpsc.h - header file for MPSC in uart mode (console driver)
+ */
+
+#ifndef __MPSC_H__
+#define __MPSC_H__
+
+/* include actual Galileo defines */
+#include "../../Marvell/include/mv_gen_reg.h"
+
+/* driver related defines */
+
+int mpsc_init(int baud);
+void mpsc_sdma_init(void);
+void mpsc_init2(void);
+int galbrg_set_baudrate(int channel, int rate);
+
+int mpsc_putchar_early(char ch);
+char mpsc_getchar_debug(void);
+int mpsc_test_char_debug(void);
+
+int mpsc_test_char_sdma(void);
+
+extern int (*mpsc_putchar)(char ch);
+extern char (*mpsc_getchar)(void);
+extern int (*mpsc_test_char)(void);
+
+#define CHANNEL CONFIG_MPSC_PORT
+
+#define TX_DESC 5
+#define RX_DESC 20
+
+#define DESC_FIRST 0x00010000
+#define DESC_LAST 0x00020000
+#define DESC_OWNER_BIT 0x80000000
+
+#define TX_DEMAND 0x00800000
+#define TX_STOP 0x00010000
+#define RX_ENABLE 0x00000080
+
+#define SDMA_RX_ABORT (1 << 15)
+#define SDMA_TX_ABORT (1 << 31)
+#define MPSC_TX_ABORT (1 << 7)
+#define MPSC_RX_ABORT (1 << 23)
+#define MPSC_ENTER_HUNT (1 << 31)
+
+/* MPSC defines */
+
+#define GALMPSC_CONNECT 0x1
+#define GALMPSC_DISCONNECT 0x0
+
+#define GALMPSC_UART 0x1
+
+#define GALMPSC_STOP_BITS_1 0x0
+#define GALMPSC_STOP_BITS_2 0x1
+#define GALMPSC_CHAR_LENGTH_8 0x3
+#define GALMPSC_CHAR_LENGTH_7 0x2
+
+#define GALMPSC_PARITY_ODD 0x0
+#define GALMPSC_PARITY_EVEN 0x2
+#define GALMPSC_PARITY_MARK 0x3
+#define GALMPSC_PARITY_SPACE 0x1
+#define GALMPSC_PARITY_NONE -1
+
+#define GALMPSC_SERIAL_MULTIPLEX SERIAL_PORT_MULTIPLEX /* 0xf010 */
+#define GALMPSC_ROUTING_REGISTER MAIN_ROUTING_REGISTER /* 0xb400 */
+#define GALMPSC_RxC_ROUTE RECEIVE_CLOCK_ROUTING_REGISTER /* 0xb404 */
+#define GALMPSC_TxC_ROUTE TRANSMIT_CLOCK_ROUTING_REGISTER /* 0xb408 */
+#define GALMPSC_MCONF_LOW MPSC0_MAIN_CONFIGURATION_LOW /* 0x8000 */
+#define GALMPSC_MCONF_HIGH MPSC0_MAIN_CONFIGURATION_HIGH /* 0x8004 */
+#define GALMPSC_PROTOCONF_REG MPSC0_PROTOCOL_CONFIGURATION /* 0x8008 */
+
+#define GALMPSC_REG_GAP 0x1000
+
+#define GALMPSC_MCONF_CHREG_BASE CHANNEL0_REGISTER1 /* 0x800c */
+#define GALMPSC_CHANNELREG_1 CHANNEL0_REGISTER1 /* 0x800c */
+#define GALMPSC_CHANNELREG_2 CHANNEL0_REGISTER2 /* 0x8010 */
+#define GALMPSC_CHANNELREG_3 CHANNEL0_REGISTER3 /* 0x8014 */
+#define GALMPSC_CHANNELREG_4 CHANNEL0_REGISTER4 /* 0x8018 */
+#define GALMPSC_CHANNELREG_5 CHANNEL0_REGISTER5 /* 0x801c */
+#define GALMPSC_CHANNELREG_6 CHANNEL0_REGISTER6 /* 0x8020 */
+#define GALMPSC_CHANNELREG_7 CHANNEL0_REGISTER7 /* 0x8024 */
+#define GALMPSC_CHANNELREG_8 CHANNEL0_REGISTER8 /* 0x8028 */
+#define GALMPSC_CHANNELREG_9 CHANNEL0_REGISTER9 /* 0x802c */
+#define GALMPSC_CHANNELREG_10 CHANNEL0_REGISTER10 /* 0x8030 */
+#define GALMPSC_CHANNELREG_11 CHANNEL0_REGISTER11 /* 0x8034 */
+
+#define GALSDMA_COMMAND_FIRST (1 << 16)
+#define GALSDMA_COMMAND_LAST (1 << 17)
+#define GALSDMA_COMMAND_ENABLEINT (1 << 23)
+#define GALSDMA_COMMAND_AUTO (1 << 30)
+#define GALSDMA_COMMAND_OWNER (1 << 31)
+
+#define GALSDMA_RX 0
+#define GALSDMA_TX 1
+
+/* CHANNEL2 should be CHANNEL1, according to documentation,
+ * but to work with the current GTREGS file...
+ */
+#define GALSDMA_0_CONF_REG CHANNEL0_CONFIGURATION_REGISTER /* 0x4000 */
+#define GALSDMA_1_CONF_REG CHANNEL2_CONFIGURATION_REGISTER /* 0x6000 */
+#define GALSDMA_0_COM_REG CHANNEL0_COMMAND_REGISTER /* 0x4008 */
+#define GALSDMA_1_COM_REG CHANNEL2_COMMAND_REGISTER /* 0x6008 */
+#define GALSDMA_0_CUR_RX_PTR CHANNEL0_CURRENT_RX_DESCRIPTOR_POINTER /* 0x4810 */
+#define GALSDMA_0_CUR_TX_PTR CHANNEL0_CURRENT_TX_DESCRIPTOR_POINTER /* 0x4c10 */
+#define GALSDMA_0_FIR_TX_PTR CHANNEL0_FIRST_TX_DESCRIPTOR_POINTER /* 0x4c14 */
+#define GALSDMA_1_CUR_RX_PTR CHANNEL2_CURRENT_RX_DESCRIPTOR_POINTER /* 0x6810 */
+#define GALSDMA_1_CUR_TX_PTR CHANNEL2_CURRENT_TX_DESCRIPTOR_POINTER /* 0x6c10 */
+#define GALSDMA_1_FIR_TX_PTR CHANNEL2_FIRST_TX_DESCRIPTOR_POINTER /* 0x6c14 */
+#define GALSDMA_REG_DIFF 0x2000
+
+/* WRONG in gt64260R.h */
+#define GALSDMA_INT_CAUSE 0xb800 /* SDMA_CAUSE */
+#define GALSDMA_INT_MASK 0xb880 /* SDMA_MASK */
+#define GALMPSC_0_INT_CAUSE 0xb804
+#define GALMPSC_0_INT_MASK 0xb884
+
+#define GALSDMA_MODE_UART 0
+#define GALSDMA_MODE_BISYNC 1
+#define GALSDMA_MODE_HDLC 2
+#define GALSDMA_MODE_TRANSPARENT 3
+
+#define GALBRG_0_CONFREG BRG0_CONFIGURATION_REGISTER /* 0xb200 */
+#define GALBRG_REG_GAP 0x0008
+#define GALBRG_0_BTREG BRG0_BAUDE_TUNING_REGISTER /* 0xb204 */
+
+#endif /* __MPSC_H__ */
diff --git a/board/prodrive/p3mx/mv_eth.c b/board/prodrive/p3mx/mv_eth.c
new file mode 100644
index 00000000000..8203b3cbf18
--- /dev/null
+++ b/board/prodrive/p3mx/mv_eth.c
@@ -0,0 +1,3344 @@
+/*
+ * (C) Copyright 2003
+ * Ingo Assmus <ingo.assmus@keymile.com>
+ *
+ * based on - Driver for MV64460X ethernet ports
+ * Copyright (C) 2002 rabeeh@galileo.co.il
+ *
+ * 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
+ 3 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
+ */
+
+/*
+ * mv_eth.c - header file for the polled mode GT ethernet driver
+ */
+#include <common.h>
+#include <net.h>
+#include <malloc.h>
+#include <miiphy.h>
+
+#include "mv_eth.h"
+
+/* enable Debug outputs */
+
+#undef DEBUG_MV_ETH
+
+#ifdef DEBUG_MV_ETH
+#define DEBUG
+#define DP(x) x
+#else
+#define DP(x)
+#endif
+
+/* PHY DFCDL Registers */
+#define ETH_PHY_DFCDL_CONFIG0_REG 0x2100
+#define ETH_PHY_DFCDL_CONFIG1_REG 0x2104
+#define ETH_PHY_DFCDL_ADDR_REG 0x2110
+#define ETH_PHY_DFCDL_DATA0_REG 0x2114
+
+#define PHY_AUTONEGOTIATE_TIMEOUT 4000 /* 4000 ms autonegotiate timeout */
+#define PHY_UPDATE_TIMEOUT 10000
+
+#undef MV64460_CHECKSUM_OFFLOAD
+/*************************************************************************
+* The first part is the high level driver of the gigE ethernet ports. *
+*************************************************************************/
+
+/* Definition for configuring driver */
+/* #define UPDATE_STATS_BY_SOFTWARE */
+#undef MV64460_RX_QUEUE_FILL_ON_TASK
+
+/* Constants */
+#define MAGIC_ETH_RUNNING 8031971
+#define MV64460_INTERNAL_SRAM_SIZE _256K
+#define EXTRA_BYTES 32
+#define WRAP ETH_HLEN + 2 + 4 + 16
+#define BUFFER_MTU dev->mtu + WRAP
+#define INT_CAUSE_UNMASK_ALL 0x0007ffff
+#define INT_CAUSE_UNMASK_ALL_EXT 0x0011ffff
+#ifdef MV64460_RX_FILL_ON_TASK
+#define INT_CAUSE_MASK_ALL 0x00000000
+#define INT_CAUSE_CHECK_BITS INT_CAUSE_UNMASK_ALL
+#define INT_CAUSE_CHECK_BITS_EXT INT_CAUSE_UNMASK_ALL_EXT
+#endif
+
+/* Read/Write to/from MV64460 internal registers */
+#define MV_REG_READ(offset) my_le32_to_cpu(* (volatile unsigned int *) (INTERNAL_REG_BASE_ADDR + offset))
+#define MV_REG_WRITE(offset,data) *(volatile unsigned int *) (INTERNAL_REG_BASE_ADDR + offset) = my_cpu_to_le32 (data)
+#define MV_SET_REG_BITS(regOffset,bits) ((*((volatile unsigned int*)((INTERNAL_REG_BASE_ADDR) + (regOffset)))) |= ((unsigned int)my_cpu_to_le32(bits)))
+#define MV_RESET_REG_BITS(regOffset,bits) ((*((volatile unsigned int*)((INTERNAL_REG_BASE_ADDR) + (regOffset)))) &= ~((unsigned int)my_cpu_to_le32(bits)))
+
+#define my_cpu_to_le32(x) my_le32_to_cpu((x))
+
+/* Static function declarations */
+static int mv64460_eth_real_open (struct eth_device *eth);
+static int mv64460_eth_real_stop (struct eth_device *eth);
+static struct net_device_stats *mv64460_eth_get_stats (struct eth_device
+ *dev);
+static void eth_port_init_mac_tables (ETH_PORT eth_port_num);
+static void mv64460_eth_update_stat (struct eth_device *dev);
+bool db64460_eth_start (struct eth_device *eth);
+unsigned int eth_read_mib_counter (ETH_PORT eth_port_num,
+ unsigned int mib_offset);
+int mv64460_eth_receive (struct eth_device *dev);
+
+int mv64460_eth_xmit (struct eth_device *, volatile void *packet, int length);
+
+int mv_miiphy_read(char *devname, unsigned char phy_addr,
+ unsigned char phy_reg, unsigned short *value);
+int mv_miiphy_write(char *devname, unsigned char phy_addr,
+ unsigned char phy_reg, unsigned short value);
+
+int phy_setup_aneg (char *devname, unsigned char addr);
+
+#ifndef UPDATE_STATS_BY_SOFTWARE
+static void mv64460_eth_print_stat (struct eth_device *dev);
+#endif
+/* Processes a received packet */
+extern void NetReceive (volatile uchar *, int);
+
+extern unsigned int INTERNAL_REG_BASE_ADDR;
+
+unsigned long my_le32_to_cpu (unsigned long x)
+{
+ return (((x & 0x000000ffU) << 24) |
+ ((x & 0x0000ff00U) << 8) |
+ ((x & 0x00ff0000U) >> 8) | ((x & 0xff000000U) >> 24));
+}
+
+/*************************************************
+ *Helper functions - used inside the driver only *
+ *************************************************/
+#ifdef DEBUG_MV_ETH
+void print_globals (struct eth_device *dev)
+{
+ printf ("Ethernet PRINT_Globals-Debug function\n");
+ printf ("Base Address for ETH_PORT_INFO: %08x\n",
+ (unsigned int) dev->priv);
+ printf ("Base Address for mv64460_eth_priv: %08x\n",
+ (unsigned int) &(((ETH_PORT_INFO *) dev->priv)->
+ port_private));
+
+ printf ("GT Internal Base Address: %08x\n",
+ INTERNAL_REG_BASE_ADDR);
+ printf ("Base Address for TX-DESCs: %08x Number of allocated Buffers %d\n",
+ (unsigned int) ((ETH_PORT_INFO *) dev->priv)->p_tx_desc_area_base[0], MV64460_TX_QUEUE_SIZE);
+ printf ("Base Address for RX-DESCs: %08x Number of allocated Buffers %d\n",
+ (unsigned int) ((ETH_PORT_INFO *) dev->priv)->p_rx_desc_area_base[0], MV64460_RX_QUEUE_SIZE);
+ printf ("Base Address for RX-Buffer: %08x allocated Bytes %d\n",
+ (unsigned int) ((ETH_PORT_INFO *) dev->priv)->
+ p_rx_buffer_base[0],
+ (MV64460_RX_QUEUE_SIZE * MV64460_RX_BUFFER_SIZE) + 32);
+ printf ("Base Address for TX-Buffer: %08x allocated Bytes %d\n",
+ (unsigned int) ((ETH_PORT_INFO *) dev->priv)->
+ p_tx_buffer_base[0],
+ (MV64460_TX_QUEUE_SIZE * MV64460_TX_BUFFER_SIZE) + 32);
+}
+#endif
+
+/**********************************************************************
+ * mv64460_eth_print_phy_status
+ *
+ * Prints gigabit ethenret phy status
+ *
+ * Input : pointer to ethernet interface network device structure
+ * Output : N/A
+ **********************************************************************/
+void mv64460_eth_print_phy_status (struct eth_device *dev)
+{
+ struct mv64460_eth_priv *port_private;
+ unsigned int port_num;
+ ETH_PORT_INFO *ethernet_private = (ETH_PORT_INFO *) dev->priv;
+ unsigned int port_status, phy_reg_data;
+
+ port_private =
+ (struct mv64460_eth_priv *) ethernet_private->port_private;
+ port_num = port_private->port_num;
+
+ /* Check Link status on phy */
+ eth_port_read_smi_reg (port_num, 1, &phy_reg_data);
+ if (!(phy_reg_data & 0x20)) {
+ printf ("Ethernet port changed link status to DOWN\n");
+ } else {
+ port_status =
+ MV_REG_READ (MV64460_ETH_PORT_STATUS_REG (port_num));
+ printf ("Ethernet status port %d: Link up", port_num);
+ printf (", %s",
+ (port_status & BIT2) ? "Full Duplex" : "Half Duplex");
+ if (port_status & BIT4)
+ printf (", Speed 1 Gbps");
+ else
+ printf (", %s",
+ (port_status & BIT5) ? "Speed 100 Mbps" :
+ "Speed 10 Mbps");
+ printf ("\n");
+ }
+}
+
+/**********************************************************************
+ * u-boot entry functions for mv64460_eth
+ *
+ **********************************************************************/
+int db64460_eth_probe (struct eth_device *dev)
+{
+ return ((int) db64460_eth_start (dev));
+}
+
+int db64460_eth_poll (struct eth_device *dev)
+{
+ return mv64460_eth_receive (dev);
+}
+
+int db64460_eth_transmit (struct eth_device *dev, volatile void *packet,
+ int length)
+{
+ mv64460_eth_xmit (dev, packet, length);
+ return 0;
+}
+
+void db64460_eth_disable (struct eth_device *dev)
+{
+ mv64460_eth_stop (dev);
+}
+
+#define DFCDL(write,read) ((write << 6) | read)
+unsigned int ethDfcdls[] = {
+ DFCDL(0,0), DFCDL(1,1), DFCDL(2,2), DFCDL(3,3),
+ DFCDL(4,4), DFCDL(5,5), DFCDL(6,6), DFCDL(7,7),
+ DFCDL(8,8), DFCDL(9,9), DFCDL(10,10), DFCDL(11,11),
+ DFCDL(12,12), DFCDL(13,13), DFCDL(14,14), DFCDL(15,15),
+ DFCDL(16,16), DFCDL(17,17), DFCDL(18,18), DFCDL(19,19),
+ DFCDL(20,20), DFCDL(21,21), DFCDL(22,22), DFCDL(23,23),
+ DFCDL(24,24), DFCDL(25,25), DFCDL(26,26), DFCDL(27,27),
+ DFCDL(28,28), DFCDL(29,29), DFCDL(30,30), DFCDL(31,31),
+ DFCDL(32,32), DFCDL(33,33), DFCDL(34,34), DFCDL(35,35),
+ DFCDL(36,36), DFCDL(37,37), DFCDL(38,38), DFCDL(39,39),
+ DFCDL(40,40), DFCDL(41,41), DFCDL(42,42), DFCDL(43,43),
+ DFCDL(44,44), DFCDL(45,45), DFCDL(46,46), DFCDL(47,47),
+ DFCDL(48,48), DFCDL(49,49), DFCDL(50,50), DFCDL(51,51),
+ DFCDL(52,52), DFCDL(53,53), DFCDL(54,54), DFCDL(55,55),
+ DFCDL(56,56), DFCDL(57,57), DFCDL(58,58), DFCDL(59,59),
+ DFCDL(60,60), DFCDL(61,61), DFCDL(62,62), DFCDL(63,63),
+};
+
+void mv_eth_phy_init (void)
+{
+ int i;
+
+ MV_REG_WRITE (ETH_PHY_DFCDL_ADDR_REG, 0);
+
+ for (i = 0; i < 64; i++) {
+ MV_REG_WRITE (ETH_PHY_DFCDL_DATA0_REG, ethDfcdls[i]);
+ }
+
+ MV_REG_WRITE (ETH_PHY_DFCDL_CONFIG0_REG, 0x300000);
+}
+
+void mv6446x_eth_initialize (bd_t * bis)
+{
+ struct eth_device *dev;
+ ETH_PORT_INFO *ethernet_private;
+ struct mv64460_eth_priv *port_private;
+ int devnum, x, temp;
+ char *s, *e, buf[64];
+
+ /* P3M750 only
+ * Set RGMII clock drives strength
+ */
+ temp = MV_REG_READ(0x20A0);
+ temp |= 0x04000080;
+ MV_REG_WRITE(0x20A0, temp);
+
+ mv_eth_phy_init();
+
+ for (devnum = 0; devnum < MV_ETH_DEVS; devnum++) {
+ dev = calloc (sizeof (*dev), 1);
+ if (!dev) {
+ printf ("%s: mv_enet%d allocation failure, %s\n",
+ __FUNCTION__, devnum, "eth_device structure");
+ return;
+ }
+
+ /* must be less than NAMESIZE (16) */
+ sprintf (dev->name, "mv_enet%d", devnum);
+
+#ifdef DEBUG
+ printf ("Initializing %s\n", dev->name);
+#endif
+
+ /* Extract the MAC address from the environment */
+ switch (devnum) {
+ case 0:
+ s = "ethaddr";
+ break;
+ case 1:
+ s = "eth1addr";
+ break;
+ case 2:
+ s = "eth2addr";
+ break;
+ default: /* this should never happen */
+ printf ("%s: Invalid device number %d\n",
+ __FUNCTION__, devnum);
+ return;
+ }
+
+ temp = getenv_r (s, buf, sizeof (buf));
+ s = (temp > 0) ? buf : NULL;
+
+#ifdef DEBUG
+ printf ("Setting MAC %d to %s\n", devnum, s);
+#endif
+ for (x = 0; x < 6; ++x) {
+ dev->enetaddr[x] = s ? simple_strtoul (s, &e, 16) : 0;
+ if (s)
+ s = (*e) ? e + 1 : e;
+ }
+ /* ronen - set the MAC addr in the HW */
+ eth_port_uc_addr_set (devnum, dev->enetaddr, 0);
+
+ dev->init = (void *) db64460_eth_probe;
+ dev->halt = (void *) ethernet_phy_reset;
+ dev->send = (void *) db64460_eth_transmit;
+ dev->recv = (void *) db64460_eth_poll;
+
+ ethernet_private = calloc (sizeof (*ethernet_private), 1);
+ dev->priv = (void *)ethernet_private;
+ if (!ethernet_private) {
+ printf ("%s: %s allocation failure, %s\n",
+ __FUNCTION__, dev->name,
+ "Private Device Structure");
+ free (dev);
+ return;
+ }
+ /* start with an zeroed ETH_PORT_INFO */
+ memset (ethernet_private, 0, sizeof (ETH_PORT_INFO));
+ memcpy (ethernet_private->port_mac_addr, dev->enetaddr, 6);
+
+ /* set pointer to memory for stats data structure etc... */
+ port_private = calloc (sizeof (*ethernet_private), 1);
+ ethernet_private->port_private = (void *)port_private;
+ if (!port_private) {
+ printf ("%s: %s allocation failure, %s\n",
+ __FUNCTION__, dev->name,
+ "Port Private Device Structure");
+
+ free (ethernet_private);
+ free (dev);
+ return;
+ }
+
+ port_private->stats =
+ calloc (sizeof (struct net_device_stats), 1);
+ if (!port_private->stats) {
+ printf ("%s: %s allocation failure, %s\n",
+ __FUNCTION__, dev->name,
+ "Net stat Structure");
+
+ free (port_private);
+ free (ethernet_private);
+ free (dev);
+ return;
+ }
+ memset (ethernet_private->port_private, 0,
+ sizeof (struct mv64460_eth_priv));
+ switch (devnum) {
+ case 0:
+ ethernet_private->port_num = ETH_0;
+ break;
+ case 1:
+ ethernet_private->port_num = ETH_1;
+ break;
+ case 2:
+ ethernet_private->port_num = ETH_2;
+ break;
+ default:
+ printf ("Invalid device number %d\n", devnum);
+ break;
+ };
+
+ port_private->port_num = devnum;
+ /*
+ * Read MIB counter on the GT in order to reset them,
+ * then zero all the stats fields in memory
+ */
+ mv64460_eth_update_stat (dev);
+ memset (port_private->stats, 0,
+ sizeof (struct net_device_stats));
+ /* Extract the MAC address from the environment */
+ switch (devnum) {
+ case 0:
+ s = "ethaddr";
+ break;
+ case 1:
+ s = "eth1addr";
+ break;
+ case 2:
+ s = "eth2addr";
+ break;
+ default: /* this should never happen */
+ printf ("%s: Invalid device number %d\n",
+ __FUNCTION__, devnum);
+ return;
+ }
+
+ temp = getenv_r (s, buf, sizeof (buf));
+ s = (temp > 0) ? buf : NULL;
+
+#ifdef DEBUG
+ printf ("Setting MAC %d to %s\n", devnum, s);
+#endif
+ for (x = 0; x < 6; ++x) {
+ dev->enetaddr[x] = s ? simple_strtoul (s, &e, 16) : 0;
+ if (s)
+ s = (*e) ? e + 1 : e;
+ }
+
+ DP (printf ("Allocating descriptor and buffer rings\n"));
+
+ ethernet_private->p_rx_desc_area_base[0] =
+ (ETH_RX_DESC *) memalign (16,
+ RX_DESC_ALIGNED_SIZE *
+ MV64460_RX_QUEUE_SIZE + 1);
+ ethernet_private->p_tx_desc_area_base[0] =
+ (ETH_TX_DESC *) memalign (16,
+ TX_DESC_ALIGNED_SIZE *
+ MV64460_TX_QUEUE_SIZE + 1);
+
+ ethernet_private->p_rx_buffer_base[0] =
+ (char *) memalign (16,
+ MV64460_RX_QUEUE_SIZE *
+ MV64460_TX_BUFFER_SIZE + 1);
+ ethernet_private->p_tx_buffer_base[0] =
+ (char *) memalign (16,
+ MV64460_RX_QUEUE_SIZE *
+ MV64460_TX_BUFFER_SIZE + 1);
+
+#ifdef DEBUG_MV_ETH
+ /* DEBUG OUTPUT prints adresses of globals */
+ print_globals (dev);
+#endif
+ eth_register (dev);
+
+ miiphy_register(dev->name, mv_miiphy_read, mv_miiphy_write);
+ }
+ DP (printf ("%s: exit\n", __FUNCTION__));
+
+}
+
+/**********************************************************************
+ * mv64460_eth_open
+ *
+ * This function is called when openning the network device. The function
+ * should initialize all the hardware, initialize cyclic Rx/Tx
+ * descriptors chain and buffers and allocate an IRQ to the network
+ * device.
+ *
+ * Input : a pointer to the network device structure
+ * / / ronen - changed the output to match net/eth.c needs
+ * Output : nonzero of success , zero if fails.
+ * under construction
+ **********************************************************************/
+
+int mv64460_eth_open (struct eth_device *dev)
+{
+ return (mv64460_eth_real_open (dev));
+}
+
+/* Helper function for mv64460_eth_open */
+static int mv64460_eth_real_open (struct eth_device *dev)
+{
+
+ unsigned int queue;
+ ETH_PORT_INFO *ethernet_private;
+ struct mv64460_eth_priv *port_private;
+ unsigned int port_num;
+ u32 port_status;
+ ushort reg_short;
+ int speed;
+ int duplex;
+ int i;
+ int reg;
+
+ ethernet_private = (ETH_PORT_INFO *) dev->priv;
+ /* ronen - when we update the MAC env params we only update dev->enetaddr
+ see ./net/eth.c eth_set_enetaddr() */
+ memcpy (ethernet_private->port_mac_addr, dev->enetaddr, 6);
+
+ port_private = (struct mv64460_eth_priv *) ethernet_private->port_private;
+ port_num = port_private->port_num;
+
+ /* Stop RX Queues */
+ MV_REG_WRITE (MV64460_ETH_RECEIVE_QUEUE_COMMAND_REG (port_num), 0x0000ff00);
+
+ /* Clear the ethernet port interrupts */
+ MV_REG_WRITE (MV64460_ETH_INTERRUPT_CAUSE_REG (port_num), 0);
+ MV_REG_WRITE (MV64460_ETH_INTERRUPT_CAUSE_EXTEND_REG (port_num), 0);
+
+ /* Unmask RX buffer and TX end interrupt */
+ MV_REG_WRITE (MV64460_ETH_INTERRUPT_MASK_REG (port_num),
+ INT_CAUSE_UNMASK_ALL);
+
+ /* Unmask phy and link status changes interrupts */
+ MV_REG_WRITE (MV64460_ETH_INTERRUPT_EXTEND_MASK_REG (port_num),
+ INT_CAUSE_UNMASK_ALL_EXT);
+
+ /* Set phy address of the port */
+ ethernet_private->port_phy_addr = 0x1 + (port_num << 1);
+ reg = ethernet_private->port_phy_addr;
+
+ /* Activate the DMA channels etc */
+ eth_port_init (ethernet_private);
+
+ /* "Allocate" setup TX rings */
+
+ for (queue = 0; queue < MV64460_TX_QUEUE_NUM; queue++) {
+ unsigned int size;
+
+ port_private->tx_ring_size[queue] = MV64460_TX_QUEUE_SIZE;
+ size = (port_private->tx_ring_size[queue] * TX_DESC_ALIGNED_SIZE); /*size = no of DESCs times DESC-size */
+ ethernet_private->tx_desc_area_size[queue] = size;
+
+ /* first clear desc area completely */
+ memset ((void *) ethernet_private->p_tx_desc_area_base[queue],
+ 0, ethernet_private->tx_desc_area_size[queue]);
+
+ /* initialize tx desc ring with low level driver */
+ if (ether_init_tx_desc_ring
+ (ethernet_private, ETH_Q0,
+ port_private->tx_ring_size[queue],
+ MV64460_TX_BUFFER_SIZE /* Each Buffer is 1600 Byte */ ,
+ (unsigned int) ethernet_private->
+ p_tx_desc_area_base[queue],
+ (unsigned int) ethernet_private->
+ p_tx_buffer_base[queue]) == false)
+ printf ("### Error initializing TX Ring\n");
+ }
+
+ /* "Allocate" setup RX rings */
+ for (queue = 0; queue < MV64460_RX_QUEUE_NUM; queue++) {
+ unsigned int size;
+
+ /* Meantime RX Ring are fixed - but must be configurable by user */
+ port_private->rx_ring_size[queue] = MV64460_RX_QUEUE_SIZE;
+ size = (port_private->rx_ring_size[queue] *
+ RX_DESC_ALIGNED_SIZE);
+ ethernet_private->rx_desc_area_size[queue] = size;
+
+ /* first clear desc area completely */
+ memset ((void *) ethernet_private->p_rx_desc_area_base[queue],
+ 0, ethernet_private->rx_desc_area_size[queue]);
+ if ((ether_init_rx_desc_ring
+ (ethernet_private, ETH_Q0,
+ port_private->rx_ring_size[queue],
+ MV64460_RX_BUFFER_SIZE /* Each Buffer is 1600 Byte */ ,
+ (unsigned int) ethernet_private->
+ p_rx_desc_area_base[queue],
+ (unsigned int) ethernet_private->
+ p_rx_buffer_base[queue])) == false)
+ printf ("### Error initializing RX Ring\n");
+ }
+
+ eth_port_start (ethernet_private);
+
+ /* Set maximum receive buffer to 9700 bytes */
+ MV_REG_WRITE (MV64460_ETH_PORT_SERIAL_CONTROL_REG (port_num),
+ (0x5 << 17) |
+ (MV_REG_READ
+ (MV64460_ETH_PORT_SERIAL_CONTROL_REG (port_num))
+ & 0xfff1ffff));
+
+ /*
+ * Set ethernet MTU for leaky bucket mechanism to 0 - this will
+ * disable the leaky bucket mechanism .
+ */
+
+ MV_REG_WRITE (MV64460_ETH_MAXIMUM_TRANSMIT_UNIT (port_num), 0);
+ port_status = MV_REG_READ (MV64460_ETH_PORT_STATUS_REG (port_num));
+
+#if defined(CONFIG_PHY_RESET)
+ /*
+ * Reset the phy, only if its the first time through
+ * otherwise, just check the speeds & feeds
+ */
+ if (port_private->first_init == 0) {
+ port_private->first_init = 1;
+ ethernet_phy_reset (port_num);
+
+ /* Start/Restart autonegotiation */
+ phy_setup_aneg (dev->name, reg);
+ udelay (1000);
+ }
+#endif /* defined(CONFIG_PHY_RESET) */
+
+ miiphy_read (dev->name, reg, PHY_BMSR, &reg_short);
+
+ /*
+ * Wait if PHY is capable of autonegotiation and autonegotiation is not complete
+ */
+ if ((reg_short & PHY_BMSR_AUTN_ABLE)
+ && !(reg_short & PHY_BMSR_AUTN_COMP)) {
+ puts ("Waiting for PHY auto negotiation to complete");
+ i = 0;
+ while (!(reg_short & PHY_BMSR_AUTN_COMP)) {
+ /*
+ * Timeout reached ?
+ */
+ if (i > PHY_AUTONEGOTIATE_TIMEOUT) {
+ puts (" TIMEOUT !\n");
+ break;
+ }
+
+ if ((i++ % 1000) == 0) {
+ putc ('.');
+ }
+ udelay (1000); /* 1 ms */
+ miiphy_read (dev->name, reg, PHY_BMSR, &reg_short);
+
+ }
+ puts (" done\n");
+ udelay (500000); /* another 500 ms (results in faster booting) */
+ }
+
+ speed = miiphy_speed (dev->name, reg);
+ duplex = miiphy_duplex (dev->name, reg);
+
+ printf ("ENET Speed is %d Mbps - %s duplex connection\n",
+ (int) speed, (duplex == HALF) ? "HALF" : "FULL");
+
+ port_private->eth_running = MAGIC_ETH_RUNNING;
+ return 1;
+}
+
+static int mv64460_eth_free_tx_rings (struct eth_device *dev)
+{
+ unsigned int queue;
+ ETH_PORT_INFO *ethernet_private;
+ struct mv64460_eth_priv *port_private;
+ unsigned int port_num;
+ volatile ETH_TX_DESC *p_tx_curr_desc;
+
+ ethernet_private = (ETH_PORT_INFO *) dev->priv;
+ port_private =
+ (struct mv64460_eth_priv *) ethernet_private->port_private;
+ port_num = port_private->port_num;
+
+ /* Stop Tx Queues */
+ MV_REG_WRITE (MV64460_ETH_TRANSMIT_QUEUE_COMMAND_REG (port_num),
+ 0x0000ff00);
+
+ /* Free TX rings */
+ DP (printf ("Clearing previously allocated TX queues... "));
+ for (queue = 0; queue < MV64460_TX_QUEUE_NUM; queue++) {
+ /* Free on TX rings */
+ for (p_tx_curr_desc =
+ ethernet_private->p_tx_desc_area_base[queue];
+ ((unsigned int) p_tx_curr_desc <= (unsigned int)
+ ethernet_private->p_tx_desc_area_base[queue] +
+ ethernet_private->tx_desc_area_size[queue]);
+ p_tx_curr_desc =
+ (ETH_TX_DESC *) ((unsigned int) p_tx_curr_desc +
+ TX_DESC_ALIGNED_SIZE)) {
+ /* this is inside for loop */
+ if (p_tx_curr_desc->return_info != 0) {
+ p_tx_curr_desc->return_info = 0;
+ DP (printf ("freed\n"));
+ }
+ }
+ DP (printf ("Done\n"));
+ }
+ return 0;
+}
+
+static int mv64460_eth_free_rx_rings (struct eth_device *dev)
+{
+ unsigned int queue;
+ ETH_PORT_INFO *ethernet_private;
+ struct mv64460_eth_priv *port_private;
+ unsigned int port_num;
+ volatile ETH_RX_DESC *p_rx_curr_desc;
+
+ ethernet_private = (ETH_PORT_INFO *) dev->priv;
+ port_private =
+ (struct mv64460_eth_priv *) ethernet_private->port_private;
+ port_num = port_private->port_num;
+
+ /* Stop RX Queues */
+ MV_REG_WRITE (MV64460_ETH_RECEIVE_QUEUE_COMMAND_REG (port_num),
+ 0x0000ff00);
+
+ /* Free RX rings */
+ DP (printf ("Clearing previously allocated RX queues... "));
+ for (queue = 0; queue < MV64460_RX_QUEUE_NUM; queue++) {
+ /* Free preallocated skb's on RX rings */
+ for (p_rx_curr_desc =
+ ethernet_private->p_rx_desc_area_base[queue];
+ (((unsigned int) p_rx_curr_desc <
+ ((unsigned int) ethernet_private->
+ p_rx_desc_area_base[queue] +
+ ethernet_private->rx_desc_area_size[queue])));
+ p_rx_curr_desc =
+ (ETH_RX_DESC *) ((unsigned int) p_rx_curr_desc +
+ RX_DESC_ALIGNED_SIZE)) {
+ if (p_rx_curr_desc->return_info != 0) {
+ p_rx_curr_desc->return_info = 0;
+ DP (printf ("freed\n"));
+ }
+ }
+ DP (printf ("Done\n"));
+ }
+ return 0;
+}
+
+/**********************************************************************
+ * mv64460_eth_stop
+ *
+ * This function is used when closing the network device.
+ * It updates the hardware,
+ * release all memory that holds buffers and descriptors and release the IRQ.
+ * Input : a pointer to the device structure
+ * Output : zero if success , nonzero if fails
+ *********************************************************************/
+
+int mv64460_eth_stop (struct eth_device *dev)
+{
+ ETH_PORT_INFO *ethernet_private;
+ struct mv64460_eth_priv *port_private;
+ unsigned int port_num;
+
+ ethernet_private = (ETH_PORT_INFO *) dev->priv;
+ port_private =
+ (struct mv64460_eth_priv *) ethernet_private->port_private;
+ port_num = port_private->port_num;
+
+ /* Disable all gigE address decoder */
+ MV_REG_WRITE (MV64460_ETH_BASE_ADDR_ENABLE_REG, 0x3f);
+ DP (printf ("%s Ethernet stop called ... \n", __FUNCTION__));
+ mv64460_eth_real_stop (dev);
+
+ return 0;
+};
+
+/* Helper function for mv64460_eth_stop */
+
+static int mv64460_eth_real_stop (struct eth_device *dev)
+{
+ ETH_PORT_INFO *ethernet_private;
+ struct mv64460_eth_priv *port_private;
+ unsigned int port_num;
+
+ ethernet_private = (ETH_PORT_INFO *) dev->priv;
+ port_private =
+ (struct mv64460_eth_priv *) ethernet_private->port_private;
+ port_num = port_private->port_num;
+
+ mv64460_eth_free_tx_rings (dev);
+ mv64460_eth_free_rx_rings (dev);
+
+ eth_port_reset (ethernet_private->port_num);
+ /* Disable ethernet port interrupts */
+ MV_REG_WRITE (MV64460_ETH_INTERRUPT_CAUSE_REG (port_num), 0);
+ MV_REG_WRITE (MV64460_ETH_INTERRUPT_CAUSE_EXTEND_REG (port_num), 0);
+ /* Mask RX buffer and TX end interrupt */
+ MV_REG_WRITE (MV64460_ETH_INTERRUPT_MASK_REG (port_num), 0);
+ /* Mask phy and link status changes interrupts */
+ MV_REG_WRITE (MV64460_ETH_INTERRUPT_EXTEND_MASK_REG (port_num), 0);
+ MV_RESET_REG_BITS (MV64460_CPU_INTERRUPT0_MASK_HIGH,
+ BIT0 << port_num);
+ /* Print Network statistics */
+#ifndef UPDATE_STATS_BY_SOFTWARE
+ /*
+ * Print statistics (only if ethernet is running),
+ * then zero all the stats fields in memory
+ */
+ if (port_private->eth_running == MAGIC_ETH_RUNNING) {
+ port_private->eth_running = 0;
+ mv64460_eth_print_stat (dev);
+ }
+ memset (port_private->stats, 0, sizeof (struct net_device_stats));
+#endif
+ DP (printf ("\nEthernet stopped ... \n"));
+ return 0;
+}
+
+/**********************************************************************
+ * mv64460_eth_start_xmit
+ *
+ * This function is queues a packet in the Tx descriptor for
+ * required port.
+ *
+ * Input : skb - a pointer to socket buffer
+ * dev - a pointer to the required port
+ *
+ * Output : zero upon success
+ **********************************************************************/
+
+int mv64460_eth_xmit (struct eth_device *dev, volatile void *dataPtr,
+ int dataSize)
+{
+ ETH_PORT_INFO *ethernet_private;
+ struct mv64460_eth_priv *port_private;
+ unsigned int port_num;
+ PKT_INFO pkt_info;
+ ETH_FUNC_RET_STATUS status;
+ struct net_device_stats *stats;
+ ETH_FUNC_RET_STATUS release_result;
+
+ ethernet_private = (ETH_PORT_INFO *) dev->priv;
+ port_private =
+ (struct mv64460_eth_priv *) ethernet_private->port_private;
+ port_num = port_private->port_num;
+
+ stats = port_private->stats;
+
+ /* Update packet info data structure */
+ pkt_info.cmd_sts = ETH_TX_FIRST_DESC | ETH_TX_LAST_DESC; /* DMA owned, first last */
+ pkt_info.byte_cnt = dataSize;
+ pkt_info.buf_ptr = (unsigned int) dataPtr;
+ pkt_info.return_info = 0;
+
+ status = eth_port_send (ethernet_private, ETH_Q0, &pkt_info);
+ if ((status == ETH_ERROR) || (status == ETH_QUEUE_FULL)) {
+ printf ("Error on transmitting packet ..");
+ if (status == ETH_QUEUE_FULL)
+ printf ("ETH Queue is full. \n");
+ if (status == ETH_QUEUE_LAST_RESOURCE)
+ printf ("ETH Queue: using last available resource. \n");
+ return 1;
+ }
+
+ /* Update statistics and start of transmittion time */
+ stats->tx_bytes += dataSize;
+ stats->tx_packets++;
+
+ /* Check if packet(s) is(are) transmitted correctly (release everything) */
+ do {
+ release_result =
+ eth_tx_return_desc (ethernet_private, ETH_Q0,
+ &pkt_info);
+ switch (release_result) {
+ case ETH_OK:
+ DP (printf ("descriptor released\n"));
+ if (pkt_info.cmd_sts & BIT0) {
+ printf ("Error in TX\n");
+ stats->tx_errors++;
+ }
+ break;
+ case ETH_RETRY:
+ DP (printf ("transmission still in process\n"));
+ break;
+
+ case ETH_ERROR:
+ printf ("routine can not access Tx desc ring\n");
+ break;
+
+ case ETH_END_OF_JOB:
+ DP (printf ("the routine has nothing to release\n"));
+ break;
+ default: /* should not happen */
+ break;
+ }
+ } while (release_result == ETH_OK);
+
+ return 0; /* success */
+}
+
+/**********************************************************************
+ * mv64460_eth_receive
+ *
+ * This function is forward packets that are received from the port's
+ * queues toward kernel core or FastRoute them to another interface.
+ *
+ * Input : dev - a pointer to the required interface
+ * max - maximum number to receive (0 means unlimted)
+ *
+ * Output : number of served packets
+ **********************************************************************/
+
+int mv64460_eth_receive (struct eth_device *dev)
+{
+ ETH_PORT_INFO *ethernet_private;
+ struct mv64460_eth_priv *port_private;
+ unsigned int port_num;
+ PKT_INFO pkt_info;
+ struct net_device_stats *stats;
+
+ ethernet_private = (ETH_PORT_INFO *) dev->priv;
+ port_private = (struct mv64460_eth_priv *) ethernet_private->port_private;
+ port_num = port_private->port_num;
+ stats = port_private->stats;
+
+ while ((eth_port_receive (ethernet_private, ETH_Q0, &pkt_info) == ETH_OK)) {
+#ifdef DEBUG_MV_ETH
+ if (pkt_info.byte_cnt != 0) {
+ printf ("%s: Received %d byte Packet @ 0x%x\n",
+ __FUNCTION__, pkt_info.byte_cnt,
+ pkt_info.buf_ptr);
+ if(pkt_info.buf_ptr != 0){
+ for(i=0; i < pkt_info.byte_cnt; i++){
+ if((i % 4) == 0){
+ printf("\n0x");
+ }
+ printf("%02x", ((char*)pkt_info.buf_ptr)[i]);
+ }
+ printf("\n");
+ }
+ }
+#endif
+ /* Update statistics. Note byte count includes 4 byte CRC count */
+ stats->rx_packets++;
+ stats->rx_bytes += pkt_info.byte_cnt;
+
+ /*
+ * In case received a packet without first / last bits on OR the error
+ * summary bit is on, the packets needs to be dropeed.
+ */
+ if (((pkt_info.
+ cmd_sts & (ETH_RX_FIRST_DESC | ETH_RX_LAST_DESC)) !=
+ (ETH_RX_FIRST_DESC | ETH_RX_LAST_DESC))
+ || (pkt_info.cmd_sts & ETH_ERROR_SUMMARY)) {
+ stats->rx_dropped++;
+
+ printf ("Received packet spread on multiple descriptors\n");
+
+ /* Is this caused by an error ? */
+ if (pkt_info.cmd_sts & ETH_ERROR_SUMMARY) {
+ stats->rx_errors++;
+ }
+
+ /* free these descriptors again without forwarding them to the higher layers */
+ pkt_info.buf_ptr &= ~0x7; /* realign buffer again */
+ pkt_info.byte_cnt = 0x0000; /* Reset Byte count */
+
+ if (eth_rx_return_buff
+ (ethernet_private, ETH_Q0, &pkt_info) != ETH_OK) {
+ printf ("Error while returning the RX Desc to Ring\n");
+ } else {
+ DP (printf ("RX Desc returned to Ring\n"));
+ }
+ /* /free these descriptors again */
+ } else {
+
+/* !!! call higher layer processing */
+#ifdef DEBUG_MV_ETH
+ printf ("\nNow send it to upper layer protocols (NetReceive) ...\n");
+#endif
+ /* let the upper layer handle the packet */
+ NetReceive ((uchar *) pkt_info.buf_ptr,
+ (int) pkt_info.byte_cnt);
+
+/* **************************************************************** */
+/* free descriptor */
+ pkt_info.buf_ptr &= ~0x7; /* realign buffer again */
+ pkt_info.byte_cnt = 0x0000; /* Reset Byte count */
+ DP (printf ("RX: pkt_info.buf_ptr = %x\n", pkt_info.buf_ptr));
+ if (eth_rx_return_buff
+ (ethernet_private, ETH_Q0, &pkt_info) != ETH_OK) {
+ printf ("Error while returning the RX Desc to Ring\n");
+ } else {
+ DP (printf ("RX: Desc returned to Ring\n"));
+ }
+
+/* **************************************************************** */
+
+ }
+ }
+ mv64460_eth_get_stats (dev); /* update statistics */
+ return 1;
+}
+
+/**********************************************************************
+ * mv64460_eth_get_stats
+ *
+ * Returns a pointer to the interface statistics.
+ *
+ * Input : dev - a pointer to the required interface
+ *
+ * Output : a pointer to the interface's statistics
+ **********************************************************************/
+
+static struct net_device_stats *mv64460_eth_get_stats (struct eth_device *dev)
+{
+ ETH_PORT_INFO *ethernet_private;
+ struct mv64460_eth_priv *port_private;
+ unsigned int port_num;
+
+ ethernet_private = (ETH_PORT_INFO *) dev->priv;
+ port_private =
+ (struct mv64460_eth_priv *) ethernet_private->port_private;
+ port_num = port_private->port_num;
+
+ mv64460_eth_update_stat (dev);
+
+ return port_private->stats;
+}
+
+/**********************************************************************
+ * mv64460_eth_update_stat
+ *
+ * Update the statistics structure in the private data structure
+ *
+ * Input : pointer to ethernet interface network device structure
+ * Output : N/A
+ **********************************************************************/
+
+static void mv64460_eth_update_stat (struct eth_device *dev)
+{
+ ETH_PORT_INFO *ethernet_private;
+ struct mv64460_eth_priv *port_private;
+ struct net_device_stats *stats;
+ unsigned int port_num;
+ volatile unsigned int dummy;
+
+ ethernet_private = (ETH_PORT_INFO *) dev->priv;
+ port_private =
+ (struct mv64460_eth_priv *) ethernet_private->port_private;
+ port_num = port_private->port_num;
+ stats = port_private->stats;
+
+ /* These are false updates */
+ stats->rx_packets += (unsigned long)
+ eth_read_mib_counter (ethernet_private->port_num,
+ ETH_MIB_GOOD_FRAMES_RECEIVED);
+ stats->tx_packets += (unsigned long)
+ eth_read_mib_counter (ethernet_private->port_num,
+ ETH_MIB_GOOD_FRAMES_SENT);
+ stats->rx_bytes += (unsigned long)
+ eth_read_mib_counter (ethernet_private->port_num,
+ ETH_MIB_GOOD_OCTETS_RECEIVED_LOW);
+ /*
+ * Ideally this should be as follows -
+ *
+ * stats->rx_bytes += stats->rx_bytes +
+ * ((unsigned long) ethReadMibCounter (ethernet_private->port_num ,
+ * ETH_MIB_GOOD_OCTETS_RECEIVED_HIGH) << 32);
+ *
+ * But the unsigned long in PowerPC and MIPS are 32bit. So the next read
+ * is just a dummy read for proper work of the GigE port
+ */
+ dummy = eth_read_mib_counter (ethernet_private->port_num,
+ ETH_MIB_GOOD_OCTETS_RECEIVED_HIGH);
+ stats->tx_bytes += (unsigned long)
+ eth_read_mib_counter (ethernet_private->port_num,
+ ETH_MIB_GOOD_OCTETS_SENT_LOW);
+ dummy = eth_read_mib_counter (ethernet_private->port_num,
+ ETH_MIB_GOOD_OCTETS_SENT_HIGH);
+ stats->rx_errors += (unsigned long)
+ eth_read_mib_counter (ethernet_private->port_num,
+ ETH_MIB_MAC_RECEIVE_ERROR);
+
+ /* Rx dropped is for received packet with CRC error */
+ stats->rx_dropped +=
+ (unsigned long) eth_read_mib_counter (ethernet_private->
+ port_num,
+ ETH_MIB_BAD_CRC_EVENT);
+ stats->multicast += (unsigned long)
+ eth_read_mib_counter (ethernet_private->port_num,
+ ETH_MIB_MULTICAST_FRAMES_RECEIVED);
+ stats->collisions +=
+ (unsigned long) eth_read_mib_counter (ethernet_private->
+ port_num,
+ ETH_MIB_COLLISION) +
+ (unsigned long) eth_read_mib_counter (ethernet_private->
+ port_num,
+ ETH_MIB_LATE_COLLISION);
+ /* detailed rx errors */
+ stats->rx_length_errors +=
+ (unsigned long) eth_read_mib_counter (ethernet_private->
+ port_num,
+ ETH_MIB_UNDERSIZE_RECEIVED)
+ +
+ (unsigned long) eth_read_mib_counter (ethernet_private->
+ port_num,
+ ETH_MIB_OVERSIZE_RECEIVED);
+ /* detailed tx errors */
+}
+
+#ifndef UPDATE_STATS_BY_SOFTWARE
+/**********************************************************************
+ * mv64460_eth_print_stat
+ *
+ * Update the statistics structure in the private data structure
+ *
+ * Input : pointer to ethernet interface network device structure
+ * Output : N/A
+ **********************************************************************/
+
+static void mv64460_eth_print_stat (struct eth_device *dev)
+{
+ ETH_PORT_INFO *ethernet_private;
+ struct mv64460_eth_priv *port_private;
+ struct net_device_stats *stats;
+ unsigned int port_num;
+
+ ethernet_private = (ETH_PORT_INFO *) dev->priv;
+ port_private =
+ (struct mv64460_eth_priv *) ethernet_private->port_private;
+ port_num = port_private->port_num;
+ stats = port_private->stats;
+
+ /* These are false updates */
+ printf ("\n### Network statistics: ###\n");
+ printf ("--------------------------\n");
+ printf (" Packets received: %ld\n", stats->rx_packets);
+ printf (" Packets send: %ld\n", stats->tx_packets);
+ printf (" Received bytes: %ld\n", stats->rx_bytes);
+ printf (" Send bytes: %ld\n", stats->tx_bytes);
+ if (stats->rx_errors != 0)
+ printf (" Rx Errors: %ld\n",
+ stats->rx_errors);
+ if (stats->rx_dropped != 0)
+ printf (" Rx dropped (CRC Errors): %ld\n",
+ stats->rx_dropped);
+ if (stats->multicast != 0)
+ printf (" Rx mulicast frames: %ld\n",
+ stats->multicast);
+ if (stats->collisions != 0)
+ printf (" No. of collisions: %ld\n",
+ stats->collisions);
+ if (stats->rx_length_errors != 0)
+ printf (" Rx length errors: %ld\n",
+ stats->rx_length_errors);
+}
+#endif
+
+/**************************************************************************
+ *network_start - Network Kick Off Routine UBoot
+ *Inputs :
+ *Outputs :
+ **************************************************************************/
+
+bool db64460_eth_start (struct eth_device *dev)
+{
+ return (mv64460_eth_open (dev)); /* calls real open */
+}
+
+/*************************************************************************
+**************************************************************************
+**************************************************************************
+* The second part is the low level driver of the gigE ethernet ports. *
+**************************************************************************
+**************************************************************************
+*************************************************************************/
+/*
+ * based on Linux code
+ * arch/ppc/galileo/EVB64460/mv64460_eth.c - Driver for MV64460X ethernet ports
+ * Copyright (C) 2002 rabeeh@galileo.co.il
+
+ * 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.
+ *
+ */
+
+/********************************************************************************
+ * Marvell's Gigabit Ethernet controller low level driver
+ *
+ * DESCRIPTION:
+ * This file introduce low level API to Marvell's Gigabit Ethernet
+ * controller. This Gigabit Ethernet Controller driver API controls
+ * 1) Operations (i.e. port init, start, reset etc').
+ * 2) Data flow (i.e. port send, receive etc').
+ * Each Gigabit Ethernet port is controlled via ETH_PORT_INFO
+ * struct.
+ * This struct includes user configuration information as well as
+ * driver internal data needed for its operations.
+ *
+ * Supported Features:
+ * - This low level driver is OS independent. Allocating memory for
+ * the descriptor rings and buffers are not within the scope of
+ * this driver.
+ * - The user is free from Rx/Tx queue managing.
+ * - This low level driver introduce functionality API that enable
+ * the to operate Marvell's Gigabit Ethernet Controller in a
+ * convenient way.
+ * - Simple Gigabit Ethernet port operation API.
+ * - Simple Gigabit Ethernet port data flow API.
+ * - Data flow and operation API support per queue functionality.
+ * - Support cached descriptors for better performance.
+ * - Enable access to all four DRAM banks and internal SRAM memory
+ * spaces.
+ * - PHY access and control API.
+ * - Port control register configuration API.
+ * - Full control over Unicast and Multicast MAC configurations.
+ *
+ * Operation flow:
+ *
+ * Initialization phase
+ * This phase complete the initialization of the ETH_PORT_INFO
+ * struct.
+ * User information regarding port configuration has to be set
+ * prior to calling the port initialization routine. For example,
+ * the user has to assign the port_phy_addr field which is board
+ * depended parameter.
+ * In this phase any port Tx/Rx activity is halted, MIB counters
+ * are cleared, PHY address is set according to user parameter and
+ * access to DRAM and internal SRAM memory spaces.
+ *
+ * Driver ring initialization
+ * Allocating memory for the descriptor rings and buffers is not
+ * within the scope of this driver. Thus, the user is required to
+ * allocate memory for the descriptors ring and buffers. Those
+ * memory parameters are used by the Rx and Tx ring initialization
+ * routines in order to curve the descriptor linked list in a form
+ * of a ring.
+ * Note: Pay special attention to alignment issues when using
+ * cached descriptors/buffers. In this phase the driver store
+ * information in the ETH_PORT_INFO struct regarding each queue
+ * ring.
+ *
+ * Driver start
+ * This phase prepares the Ethernet port for Rx and Tx activity.
+ * It uses the information stored in the ETH_PORT_INFO struct to
+ * initialize the various port registers.
+ *
+ * Data flow:
+ * All packet references to/from the driver are done using PKT_INFO
+ * struct.
+ * This struct is a unified struct used with Rx and Tx operations.
+ * This way the user is not required to be familiar with neither
+ * Tx nor Rx descriptors structures.
+ * The driver's descriptors rings are management by indexes.
+ * Those indexes controls the ring resources and used to indicate
+ * a SW resource error:
+ * 'current'
+ * This index points to the current available resource for use. For
+ * example in Rx process this index will point to the descriptor
+ * that will be passed to the user upon calling the receive routine.
+ * In Tx process, this index will point to the descriptor
+ * that will be assigned with the user packet info and transmitted.
+ * 'used'
+ * This index points to the descriptor that need to restore its
+ * resources. For example in Rx process, using the Rx buffer return
+ * API will attach the buffer returned in packet info to the
+ * descriptor pointed by 'used'. In Tx process, using the Tx
+ * descriptor return will merely return the user packet info with
+ * the command status of the transmitted buffer pointed by the
+ * 'used' index. Nevertheless, it is essential to use this routine
+ * to update the 'used' index.
+ * 'first'
+ * This index supports Tx Scatter-Gather. It points to the first
+ * descriptor of a packet assembled of multiple buffers. For example
+ * when in middle of Such packet we have a Tx resource error the
+ * 'curr' index get the value of 'first' to indicate that the ring
+ * returned to its state before trying to transmit this packet.
+ *
+ * Receive operation:
+ * The eth_port_receive API set the packet information struct,
+ * passed by the caller, with received information from the
+ * 'current' SDMA descriptor.
+ * It is the user responsibility to return this resource back
+ * to the Rx descriptor ring to enable the reuse of this source.
+ * Return Rx resource is done using the eth_rx_return_buff API.
+ *
+ * Transmit operation:
+ * The eth_port_send API supports Scatter-Gather which enables to
+ * send a packet spanned over multiple buffers. This means that
+ * for each packet info structure given by the user and put into
+ * the Tx descriptors ring, will be transmitted only if the 'LAST'
+ * bit will be set in the packet info command status field. This
+ * API also consider restriction regarding buffer alignments and
+ * sizes.
+ * The user must return a Tx resource after ensuring the buffer
+ * has been transmitted to enable the Tx ring indexes to update.
+ *
+ * BOARD LAYOUT
+ * This device is on-board. No jumper diagram is necessary.
+ *
+ * EXTERNAL INTERFACE
+ *
+ * Prior to calling the initialization routine eth_port_init() the user
+ * must set the following fields under ETH_PORT_INFO struct:
+ * port_num User Ethernet port number.
+ * port_phy_addr User PHY address of Ethernet port.
+ * port_mac_addr[6] User defined port MAC address.
+ * port_config User port configuration value.
+ * port_config_extend User port config extend value.
+ * port_sdma_config User port SDMA config value.
+ * port_serial_control User port serial control value.
+ * *port_virt_to_phys () User function to cast virtual addr to CPU bus addr.
+ * *port_private User scratch pad for user specific data structures.
+ *
+ * This driver introduce a set of default values:
+ * PORT_CONFIG_VALUE Default port configuration value
+ * PORT_CONFIG_EXTEND_VALUE Default port extend configuration value
+ * PORT_SDMA_CONFIG_VALUE Default sdma control value
+ * PORT_SERIAL_CONTROL_VALUE Default port serial control value
+ *
+ * This driver data flow is done using the PKT_INFO struct which is
+ * a unified struct for Rx and Tx operations:
+ * byte_cnt Tx/Rx descriptor buffer byte count.
+ * l4i_chk CPU provided TCP Checksum. For Tx operation only.
+ * cmd_sts Tx/Rx descriptor command status.
+ * buf_ptr Tx/Rx descriptor buffer pointer.
+ * return_info Tx/Rx user resource return information.
+ *
+ *
+ * EXTERNAL SUPPORT REQUIREMENTS
+ *
+ * This driver requires the following external support:
+ *
+ * D_CACHE_FLUSH_LINE (address, address offset)
+ *
+ * This macro applies assembly code to flush and invalidate cache
+ * line.
+ * address - address base.
+ * address offset - address offset
+ *
+ *
+ * CPU_PIPE_FLUSH
+ *
+ * This macro applies assembly code to flush the CPU pipeline.
+ *
+ *******************************************************************************/
+/* includes */
+
+/* defines */
+/* SDMA command macros */
+#define ETH_ENABLE_TX_QUEUE(tx_queue, eth_port) \
+ MV_REG_WRITE(MV64460_ETH_TRANSMIT_QUEUE_COMMAND_REG(eth_port), (1 << tx_queue))
+
+#define ETH_DISABLE_TX_QUEUE(tx_queue, eth_port) \
+ MV_REG_WRITE(MV64460_ETH_TRANSMIT_QUEUE_COMMAND_REG(eth_port),\
+ (1 << (8 + tx_queue)))
+
+#define ETH_ENABLE_RX_QUEUE(rx_queue, eth_port) \
+MV_REG_WRITE(MV64460_ETH_RECEIVE_QUEUE_COMMAND_REG(eth_port), (1 << rx_queue))
+
+#define ETH_DISABLE_RX_QUEUE(rx_queue, eth_port) \
+MV_REG_WRITE(MV64460_ETH_RECEIVE_QUEUE_COMMAND_REG(eth_port), (1 << (8 + rx_queue)))
+
+#define CURR_RFD_GET(p_curr_desc, queue) \
+ ((p_curr_desc) = p_eth_port_ctrl->p_rx_curr_desc_q[queue])
+
+#define CURR_RFD_SET(p_curr_desc, queue) \
+ (p_eth_port_ctrl->p_rx_curr_desc_q[queue] = (p_curr_desc))
+
+#define USED_RFD_GET(p_used_desc, queue) \
+ ((p_used_desc) = p_eth_port_ctrl->p_rx_used_desc_q[queue])
+
+#define USED_RFD_SET(p_used_desc, queue)\
+(p_eth_port_ctrl->p_rx_used_desc_q[queue] = (p_used_desc))
+
+
+#define CURR_TFD_GET(p_curr_desc, queue) \
+ ((p_curr_desc) = p_eth_port_ctrl->p_tx_curr_desc_q[queue])
+
+#define CURR_TFD_SET(p_curr_desc, queue) \
+ (p_eth_port_ctrl->p_tx_curr_desc_q[queue] = (p_curr_desc))
+
+#define USED_TFD_GET(p_used_desc, queue) \
+ ((p_used_desc) = p_eth_port_ctrl->p_tx_used_desc_q[queue])
+
+#define USED_TFD_SET(p_used_desc, queue) \
+ (p_eth_port_ctrl->p_tx_used_desc_q[queue] = (p_used_desc))
+
+#define FIRST_TFD_GET(p_first_desc, queue) \
+ ((p_first_desc) = p_eth_port_ctrl->p_tx_first_desc_q[queue])
+
+#define FIRST_TFD_SET(p_first_desc, queue) \
+ (p_eth_port_ctrl->p_tx_first_desc_q[queue] = (p_first_desc))
+
+
+/* Macros that save access to desc in order to find next desc pointer */
+#define RX_NEXT_DESC_PTR(p_rx_desc, queue) (ETH_RX_DESC*)(((((unsigned int)p_rx_desc - (unsigned int)p_eth_port_ctrl->p_rx_desc_area_base[queue]) + RX_DESC_ALIGNED_SIZE) % p_eth_port_ctrl->rx_desc_area_size[queue]) + (unsigned int)p_eth_port_ctrl->p_rx_desc_area_base[queue])
+
+#define TX_NEXT_DESC_PTR(p_tx_desc, queue) (ETH_TX_DESC*)(((((unsigned int)p_tx_desc - (unsigned int)p_eth_port_ctrl->p_tx_desc_area_base[queue]) + TX_DESC_ALIGNED_SIZE) % p_eth_port_ctrl->tx_desc_area_size[queue]) + (unsigned int)p_eth_port_ctrl->p_tx_desc_area_base[queue])
+
+#define LINK_UP_TIMEOUT 100000
+#define PHY_BUSY_TIMEOUT 10000000
+
+/* locals */
+
+/* PHY routines */
+static void ethernet_phy_set (ETH_PORT eth_port_num, int phy_addr);
+static int ethernet_phy_get (ETH_PORT eth_port_num);
+
+/* Ethernet Port routines */
+static void eth_set_access_control (ETH_PORT eth_port_num,
+ ETH_WIN_PARAM * param);
+static bool eth_port_uc_addr (ETH_PORT eth_port_num, unsigned char uc_nibble,
+ ETH_QUEUE queue, int option);
+#if 0 /* FIXME */
+static bool eth_port_smc_addr (ETH_PORT eth_port_num,
+ unsigned char mc_byte,
+ ETH_QUEUE queue, int option);
+static bool eth_port_omc_addr (ETH_PORT eth_port_num,
+ unsigned char crc8,
+ ETH_QUEUE queue, int option);
+#endif
+
+static void eth_b_copy (unsigned int src_addr, unsigned int dst_addr,
+ int byte_count);
+
+void eth_dbg (ETH_PORT_INFO * p_eth_port_ctrl);
+
+
+typedef enum _memory_bank { BANK0, BANK1, BANK2, BANK3 } MEMORY_BANK;
+u32 mv_get_dram_bank_base_addr (MEMORY_BANK bank)
+{
+ u32 result = 0;
+ u32 enable = MV_REG_READ (MV64460_BASE_ADDR_ENABLE);
+
+ if (enable & (1 << bank))
+ return 0;
+ if (bank == BANK0)
+ result = MV_REG_READ (MV64460_CS_0_BASE_ADDR);
+ if (bank == BANK1)
+ result = MV_REG_READ (MV64460_CS_1_BASE_ADDR);
+ if (bank == BANK2)
+ result = MV_REG_READ (MV64460_CS_2_BASE_ADDR);
+ if (bank == BANK3)
+ result = MV_REG_READ (MV64460_CS_3_BASE_ADDR);
+ result &= 0x0000ffff;
+ result = result << 16;
+ return result;
+}
+
+u32 mv_get_dram_bank_size (MEMORY_BANK bank)
+{
+ u32 result = 0;
+ u32 enable = MV_REG_READ (MV64460_BASE_ADDR_ENABLE);
+
+ if (enable & (1 << bank))
+ return 0;
+ if (bank == BANK0)
+ result = MV_REG_READ (MV64460_CS_0_SIZE);
+ if (bank == BANK1)
+ result = MV_REG_READ (MV64460_CS_1_SIZE);
+ if (bank == BANK2)
+ result = MV_REG_READ (MV64460_CS_2_SIZE);
+ if (bank == BANK3)
+ result = MV_REG_READ (MV64460_CS_3_SIZE);
+ result += 1;
+ result &= 0x0000ffff;
+ result = result << 16;
+ return result;
+}
+
+u32 mv_get_internal_sram_base (void)
+{
+ u32 result;
+
+ result = MV_REG_READ (MV64460_INTEGRATED_SRAM_BASE_ADDR);
+ result &= 0x0000ffff;
+ result = result << 16;
+ return result;
+}
+
+/*******************************************************************************
+* eth_port_init - Initialize the Ethernet port driver
+*
+* DESCRIPTION:
+* This function prepares the ethernet port to start its activity:
+* 1) Completes the ethernet port driver struct initialization toward port
+* start routine.
+* 2) Resets the device to a quiescent state in case of warm reboot.
+* 3) Enable SDMA access to all four DRAM banks as well as internal SRAM.
+* 4) Clean MAC tables. The reset status of those tables is unknown.
+* 5) Set PHY address.
+* Note: Call this routine prior to eth_port_start routine and after setting
+* user values in the user fields of Ethernet port control struct (i.e.
+* port_phy_addr).
+*
+* INPUT:
+* ETH_PORT_INFO *p_eth_port_ctrl Ethernet port control struct
+*
+* OUTPUT:
+* See description.
+*
+* RETURN:
+* None.
+*
+*******************************************************************************/
+static void eth_port_init (ETH_PORT_INFO * p_eth_port_ctrl)
+{
+ int queue;
+ ETH_WIN_PARAM win_param;
+
+ p_eth_port_ctrl->port_config = PORT_CONFIG_VALUE;
+ p_eth_port_ctrl->port_config_extend = PORT_CONFIG_EXTEND_VALUE;
+ p_eth_port_ctrl->port_sdma_config = PORT_SDMA_CONFIG_VALUE;
+ p_eth_port_ctrl->port_serial_control = PORT_SERIAL_CONTROL_VALUE;
+
+ p_eth_port_ctrl->port_rx_queue_command = 0;
+ p_eth_port_ctrl->port_tx_queue_command = 0;
+
+ /* Zero out SW structs */
+ for (queue = 0; queue < MAX_RX_QUEUE_NUM; queue++) {
+ CURR_RFD_SET ((ETH_RX_DESC *) 0x00000000, queue);
+ USED_RFD_SET ((ETH_RX_DESC *) 0x00000000, queue);
+ p_eth_port_ctrl->rx_resource_err[queue] = false;
+ }
+
+ for (queue = 0; queue < MAX_TX_QUEUE_NUM; queue++) {
+ CURR_TFD_SET ((ETH_TX_DESC *) 0x00000000, queue);
+ USED_TFD_SET ((ETH_TX_DESC *) 0x00000000, queue);
+ FIRST_TFD_SET ((ETH_TX_DESC *) 0x00000000, queue);
+ p_eth_port_ctrl->tx_resource_err[queue] = false;
+ }
+
+ eth_port_reset (p_eth_port_ctrl->port_num);
+
+ /* Set access parameters for DRAM bank 0 */
+ win_param.win = ETH_WIN0; /* Use Ethernet window 0 */
+ win_param.target = ETH_TARGET_DRAM; /* Window target - DDR */
+ win_param.attributes = EBAR_ATTR_DRAM_CS0; /* Enable DRAM bank */
+#ifndef CONFIG_NOT_COHERENT_CACHE
+ win_param.attributes |= EBAR_ATTR_DRAM_CACHE_COHERENCY_WB;
+#endif
+ win_param.high_addr = 0;
+ /* Get bank base */
+ win_param.base_addr = mv_get_dram_bank_base_addr (BANK0);
+ win_param.size = mv_get_dram_bank_size (BANK0); /* Get bank size */
+ if (win_param.size == 0)
+ win_param.enable = 0;
+ else
+ win_param.enable = 1; /* Enable the access */
+ win_param.access_ctrl = EWIN_ACCESS_FULL; /* Enable full access */
+
+ /* Set the access control for address window (EPAPR) READ & WRITE */
+ eth_set_access_control (p_eth_port_ctrl->port_num, &win_param);
+
+ /* Set access parameters for DRAM bank 1 */
+ win_param.win = ETH_WIN1; /* Use Ethernet window 1 */
+ win_param.target = ETH_TARGET_DRAM; /* Window target - DDR */
+ win_param.attributes = EBAR_ATTR_DRAM_CS1; /* Enable DRAM bank */
+#ifndef CONFIG_NOT_COHERENT_CACHE
+ win_param.attributes |= EBAR_ATTR_DRAM_CACHE_COHERENCY_WB;
+#endif
+ win_param.high_addr = 0;
+ /* Get bank base */
+ win_param.base_addr = mv_get_dram_bank_base_addr (BANK1);
+ win_param.size = mv_get_dram_bank_size (BANK1); /* Get bank size */
+ if (win_param.size == 0)
+ win_param.enable = 0;
+ else
+ win_param.enable = 1; /* Enable the access */
+ win_param.access_ctrl = EWIN_ACCESS_FULL; /* Enable full access */
+
+ /* Set the access control for address window (EPAPR) READ & WRITE */
+ eth_set_access_control (p_eth_port_ctrl->port_num, &win_param);
+
+ /* Set access parameters for DRAM bank 2 */
+ win_param.win = ETH_WIN2; /* Use Ethernet window 2 */
+ win_param.target = ETH_TARGET_DRAM; /* Window target - DDR */
+ win_param.attributes = EBAR_ATTR_DRAM_CS2; /* Enable DRAM bank */
+#ifndef CONFIG_NOT_COHERENT_CACHE
+ win_param.attributes |= EBAR_ATTR_DRAM_CACHE_COHERENCY_WB;
+#endif
+ win_param.high_addr = 0;
+ /* Get bank base */
+ win_param.base_addr = mv_get_dram_bank_base_addr (BANK2);
+ win_param.size = mv_get_dram_bank_size (BANK2); /* Get bank size */
+ if (win_param.size == 0)
+ win_param.enable = 0;
+ else
+ win_param.enable = 1; /* Enable the access */
+ win_param.access_ctrl = EWIN_ACCESS_FULL; /* Enable full access */
+
+ /* Set the access control for address window (EPAPR) READ & WRITE */
+ eth_set_access_control (p_eth_port_ctrl->port_num, &win_param);
+
+ /* Set access parameters for DRAM bank 3 */
+ win_param.win = ETH_WIN3; /* Use Ethernet window 3 */
+ win_param.target = ETH_TARGET_DRAM; /* Window target - DDR */
+ win_param.attributes = EBAR_ATTR_DRAM_CS3; /* Enable DRAM bank */
+#ifndef CONFIG_NOT_COHERENT_CACHE
+ win_param.attributes |= EBAR_ATTR_DRAM_CACHE_COHERENCY_WB;
+#endif
+ win_param.high_addr = 0;
+ /* Get bank base */
+ win_param.base_addr = mv_get_dram_bank_base_addr (BANK3);
+ win_param.size = mv_get_dram_bank_size (BANK3); /* Get bank size */
+ if (win_param.size == 0)
+ win_param.enable = 0;
+ else
+ win_param.enable = 1; /* Enable the access */
+ win_param.access_ctrl = EWIN_ACCESS_FULL; /* Enable full access */
+
+ /* Set the access control for address window (EPAPR) READ & WRITE */
+ eth_set_access_control (p_eth_port_ctrl->port_num, &win_param);
+
+ /* Set access parameters for Internal SRAM */
+ win_param.win = ETH_WIN4; /* Use Ethernet window 0 */
+ win_param.target = EBAR_TARGET_CBS; /* Target - Internal SRAM */
+ win_param.attributes = EBAR_ATTR_CBS_SRAM | EBAR_ATTR_CBS_SRAM_BLOCK0;
+ win_param.high_addr = 0;
+ win_param.base_addr = mv_get_internal_sram_base (); /* Get base addr */
+ win_param.size = MV64460_INTERNAL_SRAM_SIZE; /* Get bank size */
+ win_param.enable = 1; /* Enable the access */
+ win_param.access_ctrl = EWIN_ACCESS_FULL; /* Enable full access */
+
+ /* Set the access control for address window (EPAPR) READ & WRITE */
+ eth_set_access_control (p_eth_port_ctrl->port_num, &win_param);
+
+ eth_port_init_mac_tables (p_eth_port_ctrl->port_num);
+
+ ethernet_phy_set (p_eth_port_ctrl->port_num,
+ p_eth_port_ctrl->port_phy_addr);
+
+ return;
+
+}
+
+/*******************************************************************************
+* eth_port_start - Start the Ethernet port activity.
+*
+* DESCRIPTION:
+* This routine prepares the Ethernet port for Rx and Tx activity:
+* 1. Initialize Tx and Rx Current Descriptor Pointer for each queue that
+* has been initialized a descriptor's ring (using ether_init_tx_desc_ring
+* for Tx and ether_init_rx_desc_ring for Rx)
+* 2. Initialize and enable the Ethernet configuration port by writing to
+* the port's configuration and command registers.
+* 3. Initialize and enable the SDMA by writing to the SDMA's
+* configuration and command registers.
+* After completing these steps, the ethernet port SDMA can starts to
+* perform Rx and Tx activities.
+*
+* Note: Each Rx and Tx queue descriptor's list must be initialized prior
+* to calling this function (use ether_init_tx_desc_ring for Tx queues and
+* ether_init_rx_desc_ring for Rx queues).
+*
+* INPUT:
+* ETH_PORT_INFO *p_eth_port_ctrl Ethernet port control struct
+*
+* OUTPUT:
+* Ethernet port is ready to receive and transmit.
+*
+* RETURN:
+* false if the port PHY is not up.
+* true otherwise.
+*
+*******************************************************************************/
+static bool eth_port_start (ETH_PORT_INFO * p_eth_port_ctrl)
+{
+ int queue;
+ volatile ETH_TX_DESC *p_tx_curr_desc;
+ volatile ETH_RX_DESC *p_rx_curr_desc;
+ unsigned int phy_reg_data;
+ ETH_PORT eth_port_num = p_eth_port_ctrl->port_num;
+
+ /* Assignment of Tx CTRP of given queue */
+ for (queue = 0; queue < MAX_TX_QUEUE_NUM; queue++) {
+ CURR_TFD_GET (p_tx_curr_desc, queue);
+ MV_REG_WRITE ((MV64460_ETH_TX_CURRENT_QUEUE_DESC_PTR_0
+ (eth_port_num)
+ + (4 * queue)),
+ ((unsigned int) p_tx_curr_desc));
+
+ }
+
+ /* Assignment of Rx CRDP of given queue */
+ for (queue = 0; queue < MAX_RX_QUEUE_NUM; queue++) {
+ CURR_RFD_GET (p_rx_curr_desc, queue);
+ MV_REG_WRITE ((MV64460_ETH_RX_CURRENT_QUEUE_DESC_PTR_0
+ (eth_port_num)
+ + (4 * queue)),
+ ((unsigned int) p_rx_curr_desc));
+
+ if (p_rx_curr_desc != NULL)
+ /* Add the assigned Ethernet address to the port's address table */
+ eth_port_uc_addr_set (p_eth_port_ctrl->port_num,
+ p_eth_port_ctrl->port_mac_addr,
+ queue);
+ }
+
+ /* Assign port configuration and command. */
+ MV_REG_WRITE (MV64460_ETH_PORT_CONFIG_REG (eth_port_num),
+ p_eth_port_ctrl->port_config);
+
+ MV_REG_WRITE (MV64460_ETH_PORT_CONFIG_EXTEND_REG (eth_port_num),
+ p_eth_port_ctrl->port_config_extend);
+
+ MV_REG_WRITE (MV64460_ETH_PORT_SERIAL_CONTROL_REG (eth_port_num),
+ p_eth_port_ctrl->port_serial_control);
+
+ MV_SET_REG_BITS (MV64460_ETH_PORT_SERIAL_CONTROL_REG (eth_port_num),
+ ETH_SERIAL_PORT_ENABLE);
+
+ /* Assign port SDMA configuration */
+ MV_REG_WRITE (MV64460_ETH_SDMA_CONFIG_REG (eth_port_num),
+ p_eth_port_ctrl->port_sdma_config);
+
+ MV_REG_WRITE (MV64460_ETH_TX_QUEUE_0_TOKEN_BUCKET_COUNT
+ (eth_port_num), 0x3fffffff);
+ MV_REG_WRITE (MV64460_ETH_TX_QUEUE_0_TOKEN_BUCKET_CONFIG
+ (eth_port_num), 0x03fffcff);
+ /* Turn off the port/queue bandwidth limitation */
+ MV_REG_WRITE (MV64460_ETH_MAXIMUM_TRANSMIT_UNIT (eth_port_num), 0x0);
+
+ /* Enable port Rx. */
+ MV_REG_WRITE (MV64460_ETH_RECEIVE_QUEUE_COMMAND_REG (eth_port_num),
+ p_eth_port_ctrl->port_rx_queue_command);
+
+ /* Check if link is up */
+ eth_port_read_smi_reg (eth_port_num, 1, &phy_reg_data);
+
+ if (!(phy_reg_data & 0x20))
+ return false;
+
+ return true;
+}
+
+/*******************************************************************************
+* eth_port_uc_addr_set - This function Set the port Unicast address.
+*
+* DESCRIPTION:
+* This function Set the port Ethernet MAC address.
+*
+* INPUT:
+* ETH_PORT eth_port_num Port number.
+* char * p_addr Address to be set
+* ETH_QUEUE queue Rx queue number for this MAC address.
+*
+* OUTPUT:
+* Set MAC address low and high registers. also calls eth_port_uc_addr()
+* To set the unicast table with the proper information.
+*
+* RETURN:
+* N/A.
+*
+*******************************************************************************/
+static void eth_port_uc_addr_set (ETH_PORT eth_port_num,
+ unsigned char *p_addr, ETH_QUEUE queue)
+{
+ unsigned int mac_h;
+ unsigned int mac_l;
+
+ mac_l = (p_addr[4] << 8) | (p_addr[5]);
+ mac_h = (p_addr[0] << 24) | (p_addr[1] << 16) |
+ (p_addr[2] << 8) | (p_addr[3] << 0);
+
+ MV_REG_WRITE (MV64460_ETH_MAC_ADDR_LOW (eth_port_num), mac_l);
+ MV_REG_WRITE (MV64460_ETH_MAC_ADDR_HIGH (eth_port_num), mac_h);
+
+ /* Accept frames of this address */
+ eth_port_uc_addr (eth_port_num, p_addr[5], queue, ACCEPT_MAC_ADDR);
+
+ return;
+}
+
+/*******************************************************************************
+* eth_port_uc_addr - This function Set the port unicast address table
+*
+* DESCRIPTION:
+* This function locates the proper entry in the Unicast table for the
+* specified MAC nibble and sets its properties according to function
+* parameters.
+*
+* INPUT:
+* ETH_PORT eth_port_num Port number.
+* unsigned char uc_nibble Unicast MAC Address last nibble.
+* ETH_QUEUE queue Rx queue number for this MAC address.
+* int option 0 = Add, 1 = remove address.
+*
+* OUTPUT:
+* This function add/removes MAC addresses from the port unicast address
+* table.
+*
+* RETURN:
+* true is output succeeded.
+* false if option parameter is invalid.
+*
+*******************************************************************************/
+static bool eth_port_uc_addr (ETH_PORT eth_port_num,
+ unsigned char uc_nibble,
+ ETH_QUEUE queue, int option)
+{
+ unsigned int unicast_reg;
+ unsigned int tbl_offset;
+ unsigned int reg_offset;
+
+ /* Locate the Unicast table entry */
+ uc_nibble = (0xf & uc_nibble);
+ tbl_offset = (uc_nibble / 4) * 4; /* Register offset from unicast table base */
+ reg_offset = uc_nibble % 4; /* Entry offset within the above register */
+
+ switch (option) {
+ case REJECT_MAC_ADDR:
+ /* Clear accepts frame bit at specified unicast DA table entry */
+ unicast_reg =
+ MV_REG_READ ((MV64460_ETH_DA_FILTER_UNICAST_TABLE_BASE
+ (eth_port_num)
+ + tbl_offset));
+
+ unicast_reg &= (0x0E << (8 * reg_offset));
+
+ MV_REG_WRITE ((MV64460_ETH_DA_FILTER_UNICAST_TABLE_BASE
+ (eth_port_num)
+ + tbl_offset), unicast_reg);
+ break;
+
+ case ACCEPT_MAC_ADDR:
+ /* Set accepts frame bit at unicast DA filter table entry */
+ unicast_reg =
+ MV_REG_READ ((MV64460_ETH_DA_FILTER_UNICAST_TABLE_BASE
+ (eth_port_num)
+ + tbl_offset));
+
+ unicast_reg |= ((0x01 | queue) << (8 * reg_offset));
+
+ MV_REG_WRITE ((MV64460_ETH_DA_FILTER_UNICAST_TABLE_BASE
+ (eth_port_num)
+ + tbl_offset), unicast_reg);
+
+ break;
+
+ default:
+ return false;
+ }
+ return true;
+}
+
+#if 0 /* FIXME */
+/*******************************************************************************
+* eth_port_mc_addr - Multicast address settings.
+*
+* DESCRIPTION:
+* This API controls the MV device MAC multicast support.
+* The MV device supports multicast using two tables:
+* 1) Special Multicast Table for MAC addresses of the form
+* 0x01-00-5E-00-00-XX (where XX is between 0x00 and 0x_fF).
+* The MAC DA[7:0] bits are used as a pointer to the Special Multicast
+* Table entries in the DA-Filter table.
+* In this case, the function calls eth_port_smc_addr() routine to set the
+* Special Multicast Table.
+* 2) Other Multicast Table for multicast of another type. A CRC-8bit
+* is used as an index to the Other Multicast Table entries in the
+* DA-Filter table.
+* In this case, the function calculates the CRC-8bit value and calls
+* eth_port_omc_addr() routine to set the Other Multicast Table.
+* INPUT:
+* ETH_PORT eth_port_num Port number.
+* unsigned char *p_addr Unicast MAC Address.
+* ETH_QUEUE queue Rx queue number for this MAC address.
+* int option 0 = Add, 1 = remove address.
+*
+* OUTPUT:
+* See description.
+*
+* RETURN:
+* true is output succeeded.
+* false if add_address_table_entry( ) failed.
+*
+*******************************************************************************/
+static void eth_port_mc_addr (ETH_PORT eth_port_num,
+ unsigned char *p_addr,
+ ETH_QUEUE queue, int option)
+{
+ unsigned int mac_h;
+ unsigned int mac_l;
+ unsigned char crc_result = 0;
+ int mac_array[48];
+ int crc[8];
+ int i;
+
+ if ((p_addr[0] == 0x01) &&
+ (p_addr[1] == 0x00) &&
+ (p_addr[2] == 0x5E) && (p_addr[3] == 0x00) && (p_addr[4] == 0x00)) {
+
+ eth_port_smc_addr (eth_port_num, p_addr[5], queue, option);
+ } else {
+ /* Calculate CRC-8 out of the given address */
+ mac_h = (p_addr[0] << 8) | (p_addr[1]);
+ mac_l = (p_addr[2] << 24) | (p_addr[3] << 16) |
+ (p_addr[4] << 8) | (p_addr[5] << 0);
+
+ for (i = 0; i < 32; i++)
+ mac_array[i] = (mac_l >> i) & 0x1;
+ for (i = 32; i < 48; i++)
+ mac_array[i] = (mac_h >> (i - 32)) & 0x1;
+
+ crc[0] = mac_array[45] ^ mac_array[43] ^ mac_array[40] ^
+ mac_array[39] ^ mac_array[35] ^ mac_array[34] ^
+ mac_array[31] ^ mac_array[30] ^ mac_array[28] ^
+ mac_array[23] ^ mac_array[21] ^ mac_array[19] ^
+ mac_array[18] ^ mac_array[16] ^ mac_array[14] ^
+ mac_array[12] ^ mac_array[8] ^ mac_array[7] ^
+ mac_array[6] ^ mac_array[0];
+
+ crc[1] = mac_array[46] ^ mac_array[45] ^ mac_array[44] ^
+ mac_array[43] ^ mac_array[41] ^ mac_array[39] ^
+ mac_array[36] ^ mac_array[34] ^ mac_array[32] ^
+ mac_array[30] ^ mac_array[29] ^ mac_array[28] ^
+ mac_array[24] ^ mac_array[23] ^ mac_array[22] ^
+ mac_array[21] ^ mac_array[20] ^ mac_array[18] ^
+ mac_array[17] ^ mac_array[16] ^ mac_array[15] ^
+ mac_array[14] ^ mac_array[13] ^ mac_array[12] ^
+ mac_array[9] ^ mac_array[6] ^ mac_array[1] ^
+ mac_array[0];
+
+ crc[2] = mac_array[47] ^ mac_array[46] ^ mac_array[44] ^
+ mac_array[43] ^ mac_array[42] ^ mac_array[39] ^
+ mac_array[37] ^ mac_array[34] ^ mac_array[33] ^
+ mac_array[29] ^ mac_array[28] ^ mac_array[25] ^
+ mac_array[24] ^ mac_array[22] ^ mac_array[17] ^
+ mac_array[15] ^ mac_array[13] ^ mac_array[12] ^
+ mac_array[10] ^ mac_array[8] ^ mac_array[6] ^
+ mac_array[2] ^ mac_array[1] ^ mac_array[0];
+
+ crc[3] = mac_array[47] ^ mac_array[45] ^ mac_array[44] ^
+ mac_array[43] ^ mac_array[40] ^ mac_array[38] ^
+ mac_array[35] ^ mac_array[34] ^ mac_array[30] ^
+ mac_array[29] ^ mac_array[26] ^ mac_array[25] ^
+ mac_array[23] ^ mac_array[18] ^ mac_array[16] ^
+ mac_array[14] ^ mac_array[13] ^ mac_array[11] ^
+ mac_array[9] ^ mac_array[7] ^ mac_array[3] ^
+ mac_array[2] ^ mac_array[1];
+
+ crc[4] = mac_array[46] ^ mac_array[45] ^ mac_array[44] ^
+ mac_array[41] ^ mac_array[39] ^ mac_array[36] ^
+ mac_array[35] ^ mac_array[31] ^ mac_array[30] ^
+ mac_array[27] ^ mac_array[26] ^ mac_array[24] ^
+ mac_array[19] ^ mac_array[17] ^ mac_array[15] ^
+ mac_array[14] ^ mac_array[12] ^ mac_array[10] ^
+ mac_array[8] ^ mac_array[4] ^ mac_array[3] ^
+ mac_array[2];
+
+ crc[5] = mac_array[47] ^ mac_array[46] ^ mac_array[45] ^
+ mac_array[42] ^ mac_array[40] ^ mac_array[37] ^
+ mac_array[36] ^ mac_array[32] ^ mac_array[31] ^
+ mac_array[28] ^ mac_array[27] ^ mac_array[25] ^
+ mac_array[20] ^ mac_array[18] ^ mac_array[16] ^
+ mac_array[15] ^ mac_array[13] ^ mac_array[11] ^
+ mac_array[9] ^ mac_array[5] ^ mac_array[4] ^
+ mac_array[3];
+
+ crc[6] = mac_array[47] ^ mac_array[46] ^ mac_array[43] ^
+ mac_array[41] ^ mac_array[38] ^ mac_array[37] ^
+ mac_array[33] ^ mac_array[32] ^ mac_array[29] ^
+ mac_array[28] ^ mac_array[26] ^ mac_array[21] ^
+ mac_array[19] ^ mac_array[17] ^ mac_array[16] ^
+ mac_array[14] ^ mac_array[12] ^ mac_array[10] ^
+ mac_array[6] ^ mac_array[5] ^ mac_array[4];
+
+ crc[7] = mac_array[47] ^ mac_array[44] ^ mac_array[42] ^
+ mac_array[39] ^ mac_array[38] ^ mac_array[34] ^
+ mac_array[33] ^ mac_array[30] ^ mac_array[29] ^
+ mac_array[27] ^ mac_array[22] ^ mac_array[20] ^
+ mac_array[18] ^ mac_array[17] ^ mac_array[15] ^
+ mac_array[13] ^ mac_array[11] ^ mac_array[7] ^
+ mac_array[6] ^ mac_array[5];
+
+ for (i = 0; i < 8; i++)
+ crc_result = crc_result | (crc[i] << i);
+
+ eth_port_omc_addr (eth_port_num, crc_result, queue, option);
+ }
+ return;
+}
+
+/*******************************************************************************
+* eth_port_smc_addr - Special Multicast address settings.
+*
+* DESCRIPTION:
+* This routine controls the MV device special MAC multicast support.
+* The Special Multicast Table for MAC addresses supports MAC of the form
+* 0x01-00-5E-00-00-XX (where XX is between 0x00 and 0x_fF).
+* The MAC DA[7:0] bits are used as a pointer to the Special Multicast
+* Table entries in the DA-Filter table.
+* This function set the Special Multicast Table appropriate entry
+* according to the argument given.
+*
+* INPUT:
+* ETH_PORT eth_port_num Port number.
+* unsigned char mc_byte Multicast addr last byte (MAC DA[7:0] bits).
+* ETH_QUEUE queue Rx queue number for this MAC address.
+* int option 0 = Add, 1 = remove address.
+*
+* OUTPUT:
+* See description.
+*
+* RETURN:
+* true is output succeeded.
+* false if option parameter is invalid.
+*
+*******************************************************************************/
+static bool eth_port_smc_addr (ETH_PORT eth_port_num,
+ unsigned char mc_byte,
+ ETH_QUEUE queue, int option)
+{
+ unsigned int smc_table_reg;
+ unsigned int tbl_offset;
+ unsigned int reg_offset;
+
+ /* Locate the SMC table entry */
+ tbl_offset = (mc_byte / 4) * 4; /* Register offset from SMC table base */
+ reg_offset = mc_byte % 4; /* Entry offset within the above register */
+ queue &= 0x7;
+
+ switch (option) {
+ case REJECT_MAC_ADDR:
+ /* Clear accepts frame bit at specified Special DA table entry */
+ smc_table_reg =
+ MV_REG_READ ((MV64460_ETH_DA_FILTER_SPECIAL_MULTICAST_TABLE_BASE (eth_port_num) + tbl_offset));
+ smc_table_reg &= (0x0E << (8 * reg_offset));
+
+ MV_REG_WRITE ((MV64460_ETH_DA_FILTER_SPECIAL_MULTICAST_TABLE_BASE (eth_port_num) + tbl_offset), smc_table_reg);
+ break;
+
+ case ACCEPT_MAC_ADDR:
+ /* Set accepts frame bit at specified Special DA table entry */
+ smc_table_reg =
+ MV_REG_READ ((MV64460_ETH_DA_FILTER_SPECIAL_MULTICAST_TABLE_BASE (eth_port_num) + tbl_offset));
+ smc_table_reg |= ((0x01 | queue) << (8 * reg_offset));
+
+ MV_REG_WRITE ((MV64460_ETH_DA_FILTER_SPECIAL_MULTICAST_TABLE_BASE (eth_port_num) + tbl_offset), smc_table_reg);
+ break;
+
+ default:
+ return false;
+ }
+ return true;
+}
+
+/*******************************************************************************
+* eth_port_omc_addr - Multicast address settings.
+*
+* DESCRIPTION:
+* This routine controls the MV device Other MAC multicast support.
+* The Other Multicast Table is used for multicast of another type.
+* A CRC-8bit is used as an index to the Other Multicast Table entries
+* in the DA-Filter table.
+* The function gets the CRC-8bit value from the calling routine and
+* set the Other Multicast Table appropriate entry according to the
+* CRC-8 argument given.
+*
+* INPUT:
+* ETH_PORT eth_port_num Port number.
+* unsigned char crc8 A CRC-8bit (Polynomial: x^8+x^2+x^1+1).
+* ETH_QUEUE queue Rx queue number for this MAC address.
+* int option 0 = Add, 1 = remove address.
+*
+* OUTPUT:
+* See description.
+*
+* RETURN:
+* true is output succeeded.
+* false if option parameter is invalid.
+*
+*******************************************************************************/
+static bool eth_port_omc_addr (ETH_PORT eth_port_num,
+ unsigned char crc8,
+ ETH_QUEUE queue, int option)
+{
+ unsigned int omc_table_reg;
+ unsigned int tbl_offset;
+ unsigned int reg_offset;
+
+ /* Locate the OMC table entry */
+ tbl_offset = (crc8 / 4) * 4; /* Register offset from OMC table base */
+ reg_offset = crc8 % 4; /* Entry offset within the above register */
+ queue &= 0x7;
+
+ switch (option) {
+ case REJECT_MAC_ADDR:
+ /* Clear accepts frame bit at specified Other DA table entry */
+ omc_table_reg =
+ MV_REG_READ ((MV64460_ETH_DA_FILTER_OTHER_MULTICAST_TABLE_BASE (eth_port_num) + tbl_offset));
+ omc_table_reg &= (0x0E << (8 * reg_offset));
+
+ MV_REG_WRITE ((MV64460_ETH_DA_FILTER_OTHER_MULTICAST_TABLE_BASE (eth_port_num) + tbl_offset), omc_table_reg);
+ break;
+
+ case ACCEPT_MAC_ADDR:
+ /* Set accepts frame bit at specified Other DA table entry */
+ omc_table_reg =
+ MV_REG_READ ((MV64460_ETH_DA_FILTER_OTHER_MULTICAST_TABLE_BASE (eth_port_num) + tbl_offset));
+ omc_table_reg |= ((0x01 | queue) << (8 * reg_offset));
+
+ MV_REG_WRITE ((MV64460_ETH_DA_FILTER_OTHER_MULTICAST_TABLE_BASE (eth_port_num) + tbl_offset), omc_table_reg);
+ break;
+
+ default:
+ return false;
+ }
+ return true;
+}
+#endif
+
+/*******************************************************************************
+* eth_port_init_mac_tables - Clear all entrance in the UC, SMC and OMC tables
+*
+* DESCRIPTION:
+* Go through all the DA filter tables (Unicast, Special Multicast & Other
+* Multicast) and set each entry to 0.
+*
+* INPUT:
+* ETH_PORT eth_port_num Ethernet Port number. See ETH_PORT enum.
+*
+* OUTPUT:
+* Multicast and Unicast packets are rejected.
+*
+* RETURN:
+* None.
+*
+*******************************************************************************/
+static void eth_port_init_mac_tables (ETH_PORT eth_port_num)
+{
+ int table_index;
+
+ /* Clear DA filter unicast table (Ex_dFUT) */
+ for (table_index = 0; table_index <= 0xC; table_index += 4)
+ MV_REG_WRITE ((MV64460_ETH_DA_FILTER_UNICAST_TABLE_BASE
+ (eth_port_num) + table_index), 0);
+
+ for (table_index = 0; table_index <= 0xFC; table_index += 4) {
+ /* Clear DA filter special multicast table (Ex_dFSMT) */
+ MV_REG_WRITE ((MV64460_ETH_DA_FILTER_SPECIAL_MULTICAST_TABLE_BASE (eth_port_num) + table_index), 0);
+ /* Clear DA filter other multicast table (Ex_dFOMT) */
+ MV_REG_WRITE ((MV64460_ETH_DA_FILTER_OTHER_MULTICAST_TABLE_BASE (eth_port_num) + table_index), 0);
+ }
+}
+
+/*******************************************************************************
+* eth_clear_mib_counters - Clear all MIB counters
+*
+* DESCRIPTION:
+* This function clears all MIB counters of a specific ethernet port.
+* A read from the MIB counter will reset the counter.
+*
+* INPUT:
+* ETH_PORT eth_port_num Ethernet Port number. See ETH_PORT enum.
+*
+* OUTPUT:
+* After reading all MIB counters, the counters resets.
+*
+* RETURN:
+* MIB counter value.
+*
+*******************************************************************************/
+static void eth_clear_mib_counters (ETH_PORT eth_port_num)
+{
+ int i;
+ unsigned int dummy;
+
+ /* Perform dummy reads from MIB counters */
+ for (i = ETH_MIB_GOOD_OCTETS_RECEIVED_LOW; i < ETH_MIB_LATE_COLLISION;
+ i += 4)
+ dummy = MV_REG_READ ((MV64460_ETH_MIB_COUNTERS_BASE
+ (eth_port_num) + i));
+
+ return;
+}
+
+/*******************************************************************************
+* eth_read_mib_counter - Read a MIB counter
+*
+* DESCRIPTION:
+* This function reads a MIB counter of a specific ethernet port.
+* NOTE - If read from ETH_MIB_GOOD_OCTETS_RECEIVED_LOW, then the
+* following read must be from ETH_MIB_GOOD_OCTETS_RECEIVED_HIGH
+* register. The same applies for ETH_MIB_GOOD_OCTETS_SENT_LOW and
+* ETH_MIB_GOOD_OCTETS_SENT_HIGH
+*
+* INPUT:
+* ETH_PORT eth_port_num Ethernet Port number. See ETH_PORT enum.
+* unsigned int mib_offset MIB counter offset (use ETH_MIB_... macros).
+*
+* OUTPUT:
+* After reading the MIB counter, the counter resets.
+*
+* RETURN:
+* MIB counter value.
+*
+*******************************************************************************/
+unsigned int eth_read_mib_counter (ETH_PORT eth_port_num,
+ unsigned int mib_offset)
+{
+ return (MV_REG_READ (MV64460_ETH_MIB_COUNTERS_BASE (eth_port_num)
+ + mib_offset));
+}
+
+/*******************************************************************************
+* ethernet_phy_set - Set the ethernet port PHY address.
+*
+* DESCRIPTION:
+* This routine set the ethernet port PHY address according to given
+* parameter.
+*
+* INPUT:
+* ETH_PORT eth_port_num Ethernet Port number. See ETH_PORT enum.
+*
+* OUTPUT:
+* Set PHY Address Register with given PHY address parameter.
+*
+* RETURN:
+* None.
+*
+*******************************************************************************/
+static void ethernet_phy_set (ETH_PORT eth_port_num, int phy_addr)
+{
+ unsigned int reg_data;
+
+ reg_data = MV_REG_READ (MV64460_ETH_PHY_ADDR_REG);
+
+ reg_data &= ~(0x1F << (5 * eth_port_num));
+ reg_data |= (phy_addr << (5 * eth_port_num));
+
+ MV_REG_WRITE (MV64460_ETH_PHY_ADDR_REG, reg_data);
+
+ return;
+}
+
+/*******************************************************************************
+ * ethernet_phy_get - Get the ethernet port PHY address.
+ *
+ * DESCRIPTION:
+ * This routine returns the given ethernet port PHY address.
+ *
+ * INPUT:
+ * ETH_PORT eth_port_num Ethernet Port number. See ETH_PORT enum.
+ *
+ * OUTPUT:
+ * None.
+ *
+ * RETURN:
+ * PHY address.
+ *
+ *******************************************************************************/
+static int ethernet_phy_get (ETH_PORT eth_port_num)
+{
+ unsigned int reg_data;
+
+ reg_data = MV_REG_READ (MV64460_ETH_PHY_ADDR_REG);
+
+ return ((reg_data >> (5 * eth_port_num)) & 0x1f);
+}
+
+/***********************************************************/
+/* (Re)start autonegotiation */
+/***********************************************************/
+int phy_setup_aneg (char *devname, unsigned char addr)
+{
+ unsigned short ctl, adv;
+
+ /* Setup standard advertise */
+ miiphy_read (devname, addr, PHY_ANAR, &adv);
+ adv |= (PHY_ANLPAR_ACK | PHY_ANLPAR_RF | PHY_ANLPAR_T4 |
+ PHY_ANLPAR_TXFD | PHY_ANLPAR_TX | PHY_ANLPAR_10FD |
+ PHY_ANLPAR_10);
+ miiphy_write (devname, addr, PHY_ANAR, adv);
+
+ miiphy_read (devname, addr, PHY_1000BTCR, &adv);
+ adv |= (0x0300);
+ miiphy_write (devname, addr, PHY_1000BTCR, adv);
+
+ /* Start/Restart aneg */
+ miiphy_read (devname, addr, PHY_BMCR, &ctl);
+ ctl |= (PHY_BMCR_AUTON | PHY_BMCR_RST_NEG);
+ miiphy_write (devname, addr, PHY_BMCR, ctl);
+
+ return 0;
+}
+
+/*******************************************************************************
+ * ethernet_phy_reset - Reset Ethernet port PHY.
+ *
+ * DESCRIPTION:
+ * This routine utilize the SMI interface to reset the ethernet port PHY.
+ * The routine waits until the link is up again or link up is timeout.
+ *
+ * INPUT:
+ * ETH_PORT eth_port_num Ethernet Port number. See ETH_PORT enum.
+ *
+ * OUTPUT:
+ * The ethernet port PHY renew its link.
+ *
+ * RETURN:
+ * None.
+ *
+ *******************************************************************************/
+static bool ethernet_phy_reset (ETH_PORT eth_port_num)
+{
+ unsigned int time_out = 50;
+ unsigned int phy_reg_data;
+
+ eth_port_read_smi_reg (eth_port_num, 20, &phy_reg_data);
+ phy_reg_data |= 0x0083; /* Set bit 7 to 1 for different RGMII timing */
+ eth_port_write_smi_reg (eth_port_num, 20, phy_reg_data);
+
+ /* Reset the PHY */
+ eth_port_read_smi_reg (eth_port_num, 0, &phy_reg_data);
+ phy_reg_data |= 0x8000; /* Set bit 15 to reset the PHY */
+ eth_port_write_smi_reg (eth_port_num, 0, phy_reg_data);
+
+ /* Poll on the PHY LINK */
+ do {
+ eth_port_read_smi_reg (eth_port_num, 1, &phy_reg_data);
+
+ if (time_out-- == 0)
+ return false;
+ }
+ while (!(phy_reg_data & 0x20));
+
+ return true;
+}
+
+/*******************************************************************************
+ * eth_port_reset - Reset Ethernet port
+ *
+ * DESCRIPTION:
+ * This routine resets the chip by aborting any SDMA engine activity and
+ * clearing the MIB counters. The Receiver and the Transmit unit are in
+ * idle state after this command is performed and the port is disabled.
+ *
+ * INPUT:
+ * ETH_PORT eth_port_num Ethernet Port number. See ETH_PORT enum.
+ *
+ * OUTPUT:
+ * Channel activity is halted.
+ *
+ * RETURN:
+ * None.
+ *
+ *******************************************************************************/
+static void eth_port_reset (ETH_PORT eth_port_num)
+{
+ unsigned int reg_data;
+
+ /* Stop Tx port activity. Check port Tx activity. */
+ reg_data =
+ MV_REG_READ (MV64460_ETH_TRANSMIT_QUEUE_COMMAND_REG
+ (eth_port_num));
+
+ if (reg_data & 0xFF) {
+ /* Issue stop command for active channels only */
+ MV_REG_WRITE (MV64460_ETH_TRANSMIT_QUEUE_COMMAND_REG
+ (eth_port_num), (reg_data << 8));
+
+ /* Wait for all Tx activity to terminate. */
+ do {
+ /* Check port cause register that all Tx queues are stopped */
+ reg_data =
+ MV_REG_READ
+ (MV64460_ETH_TRANSMIT_QUEUE_COMMAND_REG
+ (eth_port_num));
+ }
+ while (reg_data & 0xFF);
+ }
+
+ /* Stop Rx port activity. Check port Rx activity. */
+ reg_data =
+ MV_REG_READ (MV64460_ETH_RECEIVE_QUEUE_COMMAND_REG
+ (eth_port_num));
+
+ if (reg_data & 0xFF) {
+ /* Issue stop command for active channels only */
+ MV_REG_WRITE (MV64460_ETH_RECEIVE_QUEUE_COMMAND_REG
+ (eth_port_num), (reg_data << 8));
+
+ /* Wait for all Rx activity to terminate. */
+ do {
+ /* Check port cause register that all Rx queues are stopped */
+ reg_data =
+ MV_REG_READ
+ (MV64460_ETH_RECEIVE_QUEUE_COMMAND_REG
+ (eth_port_num));
+ }
+ while (reg_data & 0xFF);
+ }
+
+ /* Clear all MIB counters */
+ eth_clear_mib_counters (eth_port_num);
+
+ /* Reset the Enable bit in the Configuration Register */
+ reg_data =
+ MV_REG_READ (MV64460_ETH_PORT_SERIAL_CONTROL_REG
+ (eth_port_num));
+ reg_data &= ~ETH_SERIAL_PORT_ENABLE;
+ MV_REG_WRITE (MV64460_ETH_PORT_SERIAL_CONTROL_REG (eth_port_num),
+ reg_data);
+
+ return;
+}
+
+#if 0 /* Not needed here */
+/*******************************************************************************
+ * ethernet_set_config_reg - Set specified bits in configuration register.
+ *
+ * DESCRIPTION:
+ * This function sets specified bits in the given ethernet
+ * configuration register.
+ *
+ * INPUT:
+ * ETH_PORT eth_port_num Ethernet Port number. See ETH_PORT enum.
+ * unsigned int value 32 bit value.
+ *
+ * OUTPUT:
+ * The set bits in the value parameter are set in the configuration
+ * register.
+ *
+ * RETURN:
+ * None.
+ *
+ *******************************************************************************/
+static void ethernet_set_config_reg (ETH_PORT eth_port_num,
+ unsigned int value)
+{
+ unsigned int eth_config_reg;
+
+ eth_config_reg =
+ MV_REG_READ (MV64460_ETH_PORT_CONFIG_REG (eth_port_num));
+ eth_config_reg |= value;
+ MV_REG_WRITE (MV64460_ETH_PORT_CONFIG_REG (eth_port_num),
+ eth_config_reg);
+
+ return;
+}
+#endif
+
+#if 0 /* FIXME */
+/*******************************************************************************
+ * ethernet_reset_config_reg - Reset specified bits in configuration register.
+ *
+ * DESCRIPTION:
+ * This function resets specified bits in the given Ethernet
+ * configuration register.
+ *
+ * INPUT:
+ * ETH_PORT eth_port_num Ethernet Port number. See ETH_PORT enum.
+ * unsigned int value 32 bit value.
+ *
+ * OUTPUT:
+ * The set bits in the value parameter are reset in the configuration
+ * register.
+ *
+ * RETURN:
+ * None.
+ *
+ *******************************************************************************/
+static void ethernet_reset_config_reg (ETH_PORT eth_port_num,
+ unsigned int value)
+{
+ unsigned int eth_config_reg;
+
+ eth_config_reg = MV_REG_READ (MV64460_ETH_PORT_CONFIG_EXTEND_REG
+ (eth_port_num));
+ eth_config_reg &= ~value;
+ MV_REG_WRITE (MV64460_ETH_PORT_CONFIG_EXTEND_REG (eth_port_num),
+ eth_config_reg);
+
+ return;
+}
+#endif
+
+#if 0 /* Not needed here */
+/*******************************************************************************
+ * ethernet_get_config_reg - Get the port configuration register
+ *
+ * DESCRIPTION:
+ * This function returns the configuration register value of the given
+ * ethernet port.
+ *
+ * INPUT:
+ * ETH_PORT eth_port_num Ethernet Port number. See ETH_PORT enum.
+ *
+ * OUTPUT:
+ * None.
+ *
+ * RETURN:
+ * Port configuration register value.
+ *
+ *******************************************************************************/
+static unsigned int ethernet_get_config_reg (ETH_PORT eth_port_num)
+{
+ unsigned int eth_config_reg;
+
+ eth_config_reg = MV_REG_READ (MV64460_ETH_PORT_CONFIG_EXTEND_REG
+ (eth_port_num));
+ return eth_config_reg;
+}
+
+#endif
+
+/*******************************************************************************
+ * eth_port_read_smi_reg - Read PHY registers
+ *
+ * DESCRIPTION:
+ * This routine utilize the SMI interface to interact with the PHY in
+ * order to perform PHY register read.
+ *
+ * INPUT:
+ * ETH_PORT eth_port_num Ethernet Port number. See ETH_PORT enum.
+ * unsigned int phy_reg PHY register address offset.
+ * unsigned int *value Register value buffer.
+ *
+ * OUTPUT:
+ * Write the value of a specified PHY register into given buffer.
+ *
+ * RETURN:
+ * false if the PHY is busy or read data is not in valid state.
+ * true otherwise.
+ *
+ *******************************************************************************/
+static bool eth_port_read_smi_reg (ETH_PORT eth_port_num,
+ unsigned int phy_reg, unsigned int *value)
+{
+ unsigned int reg_value;
+ unsigned int time_out = PHY_BUSY_TIMEOUT;
+ int phy_addr;
+
+ phy_addr = ethernet_phy_get (eth_port_num);
+
+ /* first check that it is not busy */
+ do {
+ reg_value = MV_REG_READ (MV64460_ETH_SMI_REG);
+ if (time_out-- == 0) {
+ return false;
+ }
+ }
+ while (reg_value & ETH_SMI_BUSY);
+
+ /* not busy */
+
+ MV_REG_WRITE (MV64460_ETH_SMI_REG,
+ (phy_addr << 16) | (phy_reg << 21) |
+ ETH_SMI_OPCODE_READ);
+
+ time_out = PHY_BUSY_TIMEOUT; /* initialize the time out var again */
+
+ do {
+ reg_value = MV_REG_READ (MV64460_ETH_SMI_REG);
+ if (time_out-- == 0) {
+ return false;
+ }
+ }
+ while ((reg_value & ETH_SMI_READ_VALID) != ETH_SMI_READ_VALID); /* Bit set equ operation done */
+
+ /* Wait for the data to update in the SMI register */
+#define PHY_UPDATE_TIMEOUT 10000
+ for (time_out = 0; time_out < PHY_UPDATE_TIMEOUT; time_out++);
+
+ reg_value = MV_REG_READ (MV64460_ETH_SMI_REG);
+
+ *value = reg_value & 0xffff;
+
+ return true;
+}
+
+int mv_miiphy_read(char *devname, unsigned char phy_addr,
+ unsigned char phy_reg, unsigned short *value)
+{
+ unsigned int reg_value;
+ unsigned int time_out = PHY_BUSY_TIMEOUT;
+
+ /* first check that it is not busy */
+ do {
+ reg_value = MV_REG_READ (MV64460_ETH_SMI_REG);
+ if (time_out-- == 0) {
+ return false;
+ }
+ }
+ while (reg_value & ETH_SMI_BUSY);
+
+ /* not busy */
+ MV_REG_WRITE (MV64460_ETH_SMI_REG,
+ (phy_addr << 16) | (phy_reg << 21) |
+ ETH_SMI_OPCODE_READ);
+
+ time_out = PHY_BUSY_TIMEOUT; /* initialize the time out var again */
+
+ do {
+ reg_value = MV_REG_READ (MV64460_ETH_SMI_REG);
+ if (time_out-- == 0) {
+ return false;
+ }
+ }
+ while ((reg_value & ETH_SMI_READ_VALID) != ETH_SMI_READ_VALID); /* Bit set equ operation done */
+
+ /* Wait for the data to update in the SMI register */
+ for (time_out = 0; time_out < PHY_UPDATE_TIMEOUT; time_out++);
+
+ reg_value = MV_REG_READ (MV64460_ETH_SMI_REG);
+
+ *value = reg_value & 0xffff;
+
+ return 0;
+}
+
+/*******************************************************************************
+ * eth_port_write_smi_reg - Write to PHY registers
+ *
+ * DESCRIPTION:
+ * This routine utilize the SMI interface to interact with the PHY in
+ * order to perform writes to PHY registers.
+ *
+ * INPUT:
+ * ETH_PORT eth_port_num Ethernet Port number. See ETH_PORT enum.
+ * unsigned int phy_reg PHY register address offset.
+ * unsigned int value Register value.
+ *
+ * OUTPUT:
+ * Write the given value to the specified PHY register.
+ *
+ * RETURN:
+ * false if the PHY is busy.
+ * true otherwise.
+ *
+ *******************************************************************************/
+static bool eth_port_write_smi_reg (ETH_PORT eth_port_num,
+ unsigned int phy_reg, unsigned int value)
+{
+ unsigned int reg_value;
+ unsigned int time_out = PHY_BUSY_TIMEOUT;
+ int phy_addr;
+
+ phy_addr = ethernet_phy_get (eth_port_num);
+
+ /* first check that it is not busy */
+ do {
+ reg_value = MV_REG_READ (MV64460_ETH_SMI_REG);
+ if (time_out-- == 0) {
+ return false;
+ }
+ }
+ while (reg_value & ETH_SMI_BUSY);
+
+ /* not busy */
+ MV_REG_WRITE (MV64460_ETH_SMI_REG,
+ (phy_addr << 16) | (phy_reg << 21) |
+ ETH_SMI_OPCODE_WRITE | (value & 0xffff));
+ return true;
+}
+
+int mv_miiphy_write(char *devname, unsigned char phy_addr,
+ unsigned char phy_reg, unsigned short value)
+{
+ unsigned int reg_value;
+ unsigned int time_out = PHY_BUSY_TIMEOUT;
+
+ /* first check that it is not busy */
+ do {
+ reg_value = MV_REG_READ (MV64460_ETH_SMI_REG);
+ if (time_out-- == 0) {
+ return false;
+ }
+ }
+ while (reg_value & ETH_SMI_BUSY);
+
+ /* not busy */
+ MV_REG_WRITE (MV64460_ETH_SMI_REG,
+ (phy_addr << 16) | (phy_reg << 21) |
+ ETH_SMI_OPCODE_WRITE | (value & 0xffff));
+ return 0;
+}
+
+/*******************************************************************************
+ * eth_set_access_control - Config address decode parameters for Ethernet unit
+ *
+ * DESCRIPTION:
+ * This function configures the address decode parameters for the Gigabit
+ * Ethernet Controller according the given parameters struct.
+ *
+ * INPUT:
+ * ETH_PORT eth_port_num Ethernet Port number. See ETH_PORT enum.
+ * ETH_WIN_PARAM *param Address decode parameter struct.
+ *
+ * OUTPUT:
+ * An access window is opened using the given access parameters.
+ *
+ * RETURN:
+ * None.
+ *
+ *******************************************************************************/
+static void eth_set_access_control (ETH_PORT eth_port_num,
+ ETH_WIN_PARAM * param)
+{
+ unsigned int access_prot_reg;
+
+ /* Set access control register */
+ access_prot_reg = MV_REG_READ (MV64460_ETH_ACCESS_PROTECTION_REG
+ (eth_port_num));
+ access_prot_reg &= (~(3 << (param->win * 2))); /* clear window permission */
+ access_prot_reg |= (param->access_ctrl << (param->win * 2));
+ MV_REG_WRITE (MV64460_ETH_ACCESS_PROTECTION_REG (eth_port_num),
+ access_prot_reg);
+
+ /* Set window Size reg (SR) */
+ MV_REG_WRITE ((MV64460_ETH_SIZE_REG_0 +
+ (ETH_SIZE_REG_GAP * param->win)),
+ (((param->size / 0x10000) - 1) << 16));
+
+ /* Set window Base address reg (BA) */
+ MV_REG_WRITE ((MV64460_ETH_BAR_0 + (ETH_BAR_GAP * param->win)),
+ (param->target | param->attributes | param->base_addr));
+ /* High address remap reg (HARR) */
+ if (param->win < 4)
+ MV_REG_WRITE ((MV64460_ETH_HIGH_ADDR_REMAP_REG_0 +
+ (ETH_HIGH_ADDR_REMAP_REG_GAP * param->win)),
+ param->high_addr);
+
+ /* Base address enable reg (BARER) */
+ if (param->enable == 1)
+ MV_RESET_REG_BITS (MV64460_ETH_BASE_ADDR_ENABLE_REG,
+ (1 << param->win));
+ else
+ MV_SET_REG_BITS (MV64460_ETH_BASE_ADDR_ENABLE_REG,
+ (1 << param->win));
+}
+
+/*******************************************************************************
+ * ether_init_rx_desc_ring - Curve a Rx chain desc list and buffer in memory.
+ *
+ * DESCRIPTION:
+ * This function prepares a Rx chained list of descriptors and packet
+ * buffers in a form of a ring. The routine must be called after port
+ * initialization routine and before port start routine.
+ * The Ethernet SDMA engine uses CPU bus addresses to access the various
+ * devices in the system (i.e. DRAM). This function uses the ethernet
+ * struct 'virtual to physical' routine (set by the user) to set the ring
+ * with physical addresses.
+ *
+ * INPUT:
+ * ETH_PORT_INFO *p_eth_port_ctrl Ethernet Port Control srtuct.
+ * ETH_QUEUE rx_queue Number of Rx queue.
+ * int rx_desc_num Number of Rx descriptors
+ * int rx_buff_size Size of Rx buffer
+ * unsigned int rx_desc_base_addr Rx descriptors memory area base addr.
+ * unsigned int rx_buff_base_addr Rx buffer memory area base addr.
+ *
+ * OUTPUT:
+ * The routine updates the Ethernet port control struct with information
+ * regarding the Rx descriptors and buffers.
+ *
+ * RETURN:
+ * false if the given descriptors memory area is not aligned according to
+ * Ethernet SDMA specifications.
+ * true otherwise.
+ *
+ *******************************************************************************/
+static bool ether_init_rx_desc_ring (ETH_PORT_INFO * p_eth_port_ctrl,
+ ETH_QUEUE rx_queue,
+ int rx_desc_num,
+ int rx_buff_size,
+ unsigned int rx_desc_base_addr,
+ unsigned int rx_buff_base_addr)
+{
+ ETH_RX_DESC *p_rx_desc;
+ ETH_RX_DESC *p_rx_prev_desc; /* pointer to link with the last descriptor */
+ unsigned int buffer_addr;
+ int ix; /* a counter */
+
+ p_rx_desc = (ETH_RX_DESC *) rx_desc_base_addr;
+ p_rx_prev_desc = p_rx_desc;
+ buffer_addr = rx_buff_base_addr;
+
+ /* Rx desc Must be 4LW aligned (i.e. Descriptor_Address[3:0]=0000). */
+ if (rx_buff_base_addr & 0xF)
+ return false;
+
+ /* Rx buffers are limited to 64K bytes and Minimum size is 8 bytes */
+ if ((rx_buff_size < 8) || (rx_buff_size > RX_BUFFER_MAX_SIZE))
+ return false;
+
+ /* Rx buffers must be 64-bit aligned. */
+ if ((rx_buff_base_addr + rx_buff_size) & 0x7)
+ return false;
+
+ /* initialize the Rx descriptors ring */
+ for (ix = 0; ix < rx_desc_num; ix++) {
+ p_rx_desc->buf_size = rx_buff_size;
+ p_rx_desc->byte_cnt = 0x0000;
+ p_rx_desc->cmd_sts =
+ ETH_BUFFER_OWNED_BY_DMA | ETH_RX_ENABLE_INTERRUPT;
+ p_rx_desc->next_desc_ptr =
+ ((unsigned int) p_rx_desc) + RX_DESC_ALIGNED_SIZE;
+ p_rx_desc->buf_ptr = buffer_addr;
+ p_rx_desc->return_info = 0x00000000;
+ D_CACHE_FLUSH_LINE (p_rx_desc, 0);
+ buffer_addr += rx_buff_size;
+ p_rx_prev_desc = p_rx_desc;
+ p_rx_desc = (ETH_RX_DESC *)
+ ((unsigned int) p_rx_desc + RX_DESC_ALIGNED_SIZE);
+ }
+
+ /* Closing Rx descriptors ring */
+ p_rx_prev_desc->next_desc_ptr = (rx_desc_base_addr);
+ D_CACHE_FLUSH_LINE (p_rx_prev_desc, 0);
+
+ /* Save Rx desc pointer to driver struct. */
+ CURR_RFD_SET ((ETH_RX_DESC *) rx_desc_base_addr, rx_queue);
+ USED_RFD_SET ((ETH_RX_DESC *) rx_desc_base_addr, rx_queue);
+
+ p_eth_port_ctrl->p_rx_desc_area_base[rx_queue] =
+ (ETH_RX_DESC *) rx_desc_base_addr;
+ p_eth_port_ctrl->rx_desc_area_size[rx_queue] =
+ rx_desc_num * RX_DESC_ALIGNED_SIZE;
+
+ p_eth_port_ctrl->port_rx_queue_command |= (1 << rx_queue);
+
+ return true;
+}
+
+/*******************************************************************************
+ * ether_init_tx_desc_ring - Curve a Tx chain desc list and buffer in memory.
+ *
+ * DESCRIPTION:
+ * This function prepares a Tx chained list of descriptors and packet
+ * buffers in a form of a ring. The routine must be called after port
+ * initialization routine and before port start routine.
+ * The Ethernet SDMA engine uses CPU bus addresses to access the various
+ * devices in the system (i.e. DRAM). This function uses the ethernet
+ * struct 'virtual to physical' routine (set by the user) to set the ring
+ * with physical addresses.
+ *
+ * INPUT:
+ * ETH_PORT_INFO *p_eth_port_ctrl Ethernet Port Control srtuct.
+ * ETH_QUEUE tx_queue Number of Tx queue.
+ * int tx_desc_num Number of Tx descriptors
+ * int tx_buff_size Size of Tx buffer
+ * unsigned int tx_desc_base_addr Tx descriptors memory area base addr.
+ * unsigned int tx_buff_base_addr Tx buffer memory area base addr.
+ *
+ * OUTPUT:
+ * The routine updates the Ethernet port control struct with information
+ * regarding the Tx descriptors and buffers.
+ *
+ * RETURN:
+ * false if the given descriptors memory area is not aligned according to
+ * Ethernet SDMA specifications.
+ * true otherwise.
+ *
+ *******************************************************************************/
+static bool ether_init_tx_desc_ring (ETH_PORT_INFO * p_eth_port_ctrl,
+ ETH_QUEUE tx_queue,
+ int tx_desc_num,
+ int tx_buff_size,
+ unsigned int tx_desc_base_addr,
+ unsigned int tx_buff_base_addr)
+{
+
+ ETH_TX_DESC *p_tx_desc;
+ ETH_TX_DESC *p_tx_prev_desc;
+ unsigned int buffer_addr;
+ int ix; /* a counter */
+
+ /* save the first desc pointer to link with the last descriptor */
+ p_tx_desc = (ETH_TX_DESC *) tx_desc_base_addr;
+ p_tx_prev_desc = p_tx_desc;
+ buffer_addr = tx_buff_base_addr;
+
+ /* Tx desc Must be 4LW aligned (i.e. Descriptor_Address[3:0]=0000). */
+ if (tx_buff_base_addr & 0xF)
+ return false;
+
+ /* Tx buffers are limited to 64K bytes and Minimum size is 8 bytes */
+ if ((tx_buff_size > TX_BUFFER_MAX_SIZE)
+ || (tx_buff_size < TX_BUFFER_MIN_SIZE))
+ return false;
+
+ /* Initialize the Tx descriptors ring */
+ for (ix = 0; ix < tx_desc_num; ix++) {
+ p_tx_desc->byte_cnt = 0x0000;
+ p_tx_desc->l4i_chk = 0x0000;
+ p_tx_desc->cmd_sts = 0x00000000;
+ p_tx_desc->next_desc_ptr =
+ ((unsigned int) p_tx_desc) + TX_DESC_ALIGNED_SIZE;
+
+ p_tx_desc->buf_ptr = buffer_addr;
+ p_tx_desc->return_info = 0x00000000;
+ D_CACHE_FLUSH_LINE (p_tx_desc, 0);
+ buffer_addr += tx_buff_size;
+ p_tx_prev_desc = p_tx_desc;
+ p_tx_desc = (ETH_TX_DESC *)
+ ((unsigned int) p_tx_desc + TX_DESC_ALIGNED_SIZE);
+
+ }
+ /* Closing Tx descriptors ring */
+ p_tx_prev_desc->next_desc_ptr = tx_desc_base_addr;
+ D_CACHE_FLUSH_LINE (p_tx_prev_desc, 0);
+ /* Set Tx desc pointer in driver struct. */
+ CURR_TFD_SET ((ETH_TX_DESC *) tx_desc_base_addr, tx_queue);
+ USED_TFD_SET ((ETH_TX_DESC *) tx_desc_base_addr, tx_queue);
+
+ /* Init Tx ring base and size parameters */
+ p_eth_port_ctrl->p_tx_desc_area_base[tx_queue] =
+ (ETH_TX_DESC *) tx_desc_base_addr;
+ p_eth_port_ctrl->tx_desc_area_size[tx_queue] =
+ (tx_desc_num * TX_DESC_ALIGNED_SIZE);
+
+ /* Add the queue to the list of Tx queues of this port */
+ p_eth_port_ctrl->port_tx_queue_command |= (1 << tx_queue);
+
+ return true;
+}
+
+/*******************************************************************************
+ * eth_port_send - Send an Ethernet packet
+ *
+ * DESCRIPTION:
+ * This routine send a given packet described by p_pktinfo parameter. It
+ * supports transmitting of a packet spaned over multiple buffers. The
+ * routine updates 'curr' and 'first' indexes according to the packet
+ * segment passed to the routine. In case the packet segment is first,
+ * the 'first' index is update. In any case, the 'curr' index is updated.
+ * If the routine get into Tx resource error it assigns 'curr' index as
+ * 'first'. This way the function can abort Tx process of multiple
+ * descriptors per packet.
+ *
+ * INPUT:
+ * ETH_PORT_INFO *p_eth_port_ctrl Ethernet Port Control srtuct.
+ * ETH_QUEUE tx_queue Number of Tx queue.
+ * PKT_INFO *p_pkt_info User packet buffer.
+ *
+ * OUTPUT:
+ * Tx ring 'curr' and 'first' indexes are updated.
+ *
+ * RETURN:
+ * ETH_QUEUE_FULL in case of Tx resource error.
+ * ETH_ERROR in case the routine can not access Tx desc ring.
+ * ETH_QUEUE_LAST_RESOURCE if the routine uses the last Tx resource.
+ * ETH_OK otherwise.
+ *
+ *******************************************************************************/
+static ETH_FUNC_RET_STATUS eth_port_send (ETH_PORT_INFO * p_eth_port_ctrl,
+ ETH_QUEUE tx_queue,
+ PKT_INFO * p_pkt_info)
+{
+ volatile ETH_TX_DESC *p_tx_desc_first;
+ volatile ETH_TX_DESC *p_tx_desc_curr;
+ volatile ETH_TX_DESC *p_tx_next_desc_curr;
+ volatile ETH_TX_DESC *p_tx_desc_used;
+ unsigned int command_status;
+
+ /* Do not process Tx ring in case of Tx ring resource error */
+ if (p_eth_port_ctrl->tx_resource_err[tx_queue] == true)
+ return ETH_QUEUE_FULL;
+
+ /* Get the Tx Desc ring indexes */
+ CURR_TFD_GET (p_tx_desc_curr, tx_queue);
+ USED_TFD_GET (p_tx_desc_used, tx_queue);
+
+ if (p_tx_desc_curr == NULL)
+ return ETH_ERROR;
+
+ /* The following parameters are used to save readings from memory */
+ p_tx_next_desc_curr = TX_NEXT_DESC_PTR (p_tx_desc_curr, tx_queue);
+ command_status = p_pkt_info->cmd_sts | ETH_ZERO_PADDING | ETH_GEN_CRC;
+
+ if (command_status & (ETH_TX_FIRST_DESC)) {
+ /* Update first desc */
+ FIRST_TFD_SET (p_tx_desc_curr, tx_queue);
+ p_tx_desc_first = p_tx_desc_curr;
+ } else {
+ FIRST_TFD_GET (p_tx_desc_first, tx_queue);
+ command_status |= ETH_BUFFER_OWNED_BY_DMA;
+ }
+
+ /* Buffers with a payload smaller than 8 bytes must be aligned to 64-bit */
+ /* boundary. We use the memory allocated for Tx descriptor. This memory */
+ /* located in TX_BUF_OFFSET_IN_DESC offset within the Tx descriptor. */
+ if (p_pkt_info->byte_cnt <= 8) {
+ printf ("You have failed in the < 8 bytes errata - fixme\n"); /* RABEEH - TBD */
+ return ETH_ERROR;
+
+ p_tx_desc_curr->buf_ptr =
+ (unsigned int) p_tx_desc_curr + TX_BUF_OFFSET_IN_DESC;
+ eth_b_copy (p_pkt_info->buf_ptr, p_tx_desc_curr->buf_ptr,
+ p_pkt_info->byte_cnt);
+ } else
+ p_tx_desc_curr->buf_ptr = p_pkt_info->buf_ptr;
+
+ p_tx_desc_curr->byte_cnt = p_pkt_info->byte_cnt;
+ p_tx_desc_curr->return_info = p_pkt_info->return_info;
+
+ if (p_pkt_info->cmd_sts & (ETH_TX_LAST_DESC)) {
+ /* Set last desc with DMA ownership and interrupt enable. */
+ p_tx_desc_curr->cmd_sts = command_status |
+ ETH_BUFFER_OWNED_BY_DMA | ETH_TX_ENABLE_INTERRUPT;
+
+ if (p_tx_desc_curr != p_tx_desc_first)
+ p_tx_desc_first->cmd_sts |= ETH_BUFFER_OWNED_BY_DMA;
+
+ /* Flush CPU pipe */
+
+ D_CACHE_FLUSH_LINE ((unsigned int) p_tx_desc_curr, 0);
+ D_CACHE_FLUSH_LINE ((unsigned int) p_tx_desc_first, 0);
+ CPU_PIPE_FLUSH;
+
+ /* Apply send command */
+ ETH_ENABLE_TX_QUEUE (tx_queue, p_eth_port_ctrl->port_num);
+
+ /* Finish Tx packet. Update first desc in case of Tx resource error */
+ p_tx_desc_first = p_tx_next_desc_curr;
+ FIRST_TFD_SET (p_tx_desc_first, tx_queue);
+
+ } else {
+ p_tx_desc_curr->cmd_sts = command_status;
+ D_CACHE_FLUSH_LINE ((unsigned int) p_tx_desc_curr, 0);
+ }
+
+ /* Check for ring index overlap in the Tx desc ring */
+ if (p_tx_next_desc_curr == p_tx_desc_used) {
+ /* Update the current descriptor */
+ CURR_TFD_SET (p_tx_desc_first, tx_queue);
+
+ p_eth_port_ctrl->tx_resource_err[tx_queue] = true;
+ return ETH_QUEUE_LAST_RESOURCE;
+ } else {
+ /* Update the current descriptor */
+ CURR_TFD_SET (p_tx_next_desc_curr, tx_queue);
+ return ETH_OK;
+ }
+}
+
+/*******************************************************************************
+ * eth_tx_return_desc - Free all used Tx descriptors
+ *
+ * DESCRIPTION:
+ * This routine returns the transmitted packet information to the caller.
+ * It uses the 'first' index to support Tx desc return in case a transmit
+ * of a packet spanned over multiple buffer still in process.
+ * In case the Tx queue was in "resource error" condition, where there are
+ * no available Tx resources, the function resets the resource error flag.
+ *
+ * INPUT:
+ * ETH_PORT_INFO *p_eth_port_ctrl Ethernet Port Control srtuct.
+ * ETH_QUEUE tx_queue Number of Tx queue.
+ * PKT_INFO *p_pkt_info User packet buffer.
+ *
+ * OUTPUT:
+ * Tx ring 'first' and 'used' indexes are updated.
+ *
+ * RETURN:
+ * ETH_ERROR in case the routine can not access Tx desc ring.
+ * ETH_RETRY in case there is transmission in process.
+ * ETH_END_OF_JOB if the routine has nothing to release.
+ * ETH_OK otherwise.
+ *
+ *******************************************************************************/
+static ETH_FUNC_RET_STATUS eth_tx_return_desc (ETH_PORT_INFO *
+ p_eth_port_ctrl,
+ ETH_QUEUE tx_queue,
+ PKT_INFO * p_pkt_info)
+{
+ volatile ETH_TX_DESC *p_tx_desc_used = NULL;
+ volatile ETH_TX_DESC *p_tx_desc_first = NULL;
+ unsigned int command_status;
+
+ /* Get the Tx Desc ring indexes */
+ USED_TFD_GET (p_tx_desc_used, tx_queue);
+ FIRST_TFD_GET (p_tx_desc_first, tx_queue);
+
+ /* Sanity check */
+ if (p_tx_desc_used == NULL)
+ return ETH_ERROR;
+
+ command_status = p_tx_desc_used->cmd_sts;
+
+ /* Still transmitting... */
+ if (command_status & (ETH_BUFFER_OWNED_BY_DMA)) {
+ D_CACHE_FLUSH_LINE ((unsigned int) p_tx_desc_used, 0);
+ return ETH_RETRY;
+ }
+
+ /* Stop release. About to overlap the current available Tx descriptor */
+ if ((p_tx_desc_used == p_tx_desc_first) &&
+ (p_eth_port_ctrl->tx_resource_err[tx_queue] == false)) {
+ D_CACHE_FLUSH_LINE ((unsigned int) p_tx_desc_used, 0);
+ return ETH_END_OF_JOB;
+ }
+
+ /* Pass the packet information to the caller */
+ p_pkt_info->cmd_sts = command_status;
+ p_pkt_info->return_info = p_tx_desc_used->return_info;
+ p_tx_desc_used->return_info = 0;
+
+ /* Update the next descriptor to release. */
+ USED_TFD_SET (TX_NEXT_DESC_PTR (p_tx_desc_used, tx_queue), tx_queue);
+
+ /* Any Tx return cancels the Tx resource error status */
+ if (p_eth_port_ctrl->tx_resource_err[tx_queue] == true)
+ p_eth_port_ctrl->tx_resource_err[tx_queue] = false;
+
+ D_CACHE_FLUSH_LINE ((unsigned int) p_tx_desc_used, 0);
+
+ return ETH_OK;
+
+}
+
+/*******************************************************************************
+ * eth_port_receive - Get received information from Rx ring.
+ *
+ * DESCRIPTION:
+ * This routine returns the received data to the caller. There is no
+ * data copying during routine operation. All information is returned
+ * using pointer to packet information struct passed from the caller.
+ * If the routine exhausts Rx ring resources then the resource error flag
+ * is set.
+ *
+ * INPUT:
+ * ETH_PORT_INFO *p_eth_port_ctrl Ethernet Port Control srtuct.
+ * ETH_QUEUE rx_queue Number of Rx queue.
+ * PKT_INFO *p_pkt_info User packet buffer.
+ *
+ * OUTPUT:
+ * Rx ring current and used indexes are updated.
+ *
+ * RETURN:
+ * ETH_ERROR in case the routine can not access Rx desc ring.
+ * ETH_QUEUE_FULL if Rx ring resources are exhausted.
+ * ETH_END_OF_JOB if there is no received data.
+ * ETH_OK otherwise.
+ *
+ *******************************************************************************/
+static ETH_FUNC_RET_STATUS eth_port_receive (ETH_PORT_INFO * p_eth_port_ctrl,
+ ETH_QUEUE rx_queue,
+ PKT_INFO * p_pkt_info)
+{
+ volatile ETH_RX_DESC *p_rx_curr_desc;
+ volatile ETH_RX_DESC *p_rx_next_curr_desc;
+ volatile ETH_RX_DESC *p_rx_used_desc;
+ unsigned int command_status;
+
+ /* Do not process Rx ring in case of Rx ring resource error */
+ if (p_eth_port_ctrl->rx_resource_err[rx_queue] == true) {
+ printf ("\nRx Queue is full ...\n");
+ return ETH_QUEUE_FULL;
+ }
+
+ /* Get the Rx Desc ring 'curr and 'used' indexes */
+ CURR_RFD_GET (p_rx_curr_desc, rx_queue);
+ USED_RFD_GET (p_rx_used_desc, rx_queue);
+
+ /* Sanity check */
+ if (p_rx_curr_desc == NULL)
+ return ETH_ERROR;
+
+ /* The following parameters are used to save readings from memory */
+ p_rx_next_curr_desc = RX_NEXT_DESC_PTR (p_rx_curr_desc, rx_queue);
+ command_status = p_rx_curr_desc->cmd_sts;
+
+ /* Nothing to receive... */
+ if (command_status & (ETH_BUFFER_OWNED_BY_DMA)) {
+/* DP(printf("Rx: command_status: %08x\n", command_status)); */
+ D_CACHE_FLUSH_LINE ((unsigned int) p_rx_curr_desc, 0);
+/* DP(printf("\nETH_END_OF_JOB ...\n"));*/
+ return ETH_END_OF_JOB;
+ }
+
+ p_pkt_info->byte_cnt = (p_rx_curr_desc->byte_cnt) - RX_BUF_OFFSET;
+ p_pkt_info->cmd_sts = command_status;
+ p_pkt_info->buf_ptr = (p_rx_curr_desc->buf_ptr) + RX_BUF_OFFSET;
+ p_pkt_info->return_info = p_rx_curr_desc->return_info;
+ p_pkt_info->l4i_chk = p_rx_curr_desc->buf_size; /* IP fragment indicator */
+
+ /* Clean the return info field to indicate that the packet has been */
+ /* moved to the upper layers */
+ p_rx_curr_desc->return_info = 0;
+
+ /* Update 'curr' in data structure */
+ CURR_RFD_SET (p_rx_next_curr_desc, rx_queue);
+
+ /* Rx descriptors resource exhausted. Set the Rx ring resource error flag */
+ if (p_rx_next_curr_desc == p_rx_used_desc)
+ p_eth_port_ctrl->rx_resource_err[rx_queue] = true;
+
+ D_CACHE_FLUSH_LINE ((unsigned int) p_rx_curr_desc, 0);
+ CPU_PIPE_FLUSH;
+
+ return ETH_OK;
+}
+
+/*******************************************************************************
+ * eth_rx_return_buff - Returns a Rx buffer back to the Rx ring.
+ *
+ * DESCRIPTION:
+ * This routine returns a Rx buffer back to the Rx ring. It retrieves the
+ * next 'used' descriptor and attached the returned buffer to it.
+ * In case the Rx ring was in "resource error" condition, where there are
+ * no available Rx resources, the function resets the resource error flag.
+ *
+ * INPUT:
+ * ETH_PORT_INFO *p_eth_port_ctrl Ethernet Port Control srtuct.
+ * ETH_QUEUE rx_queue Number of Rx queue.
+ * PKT_INFO *p_pkt_info Information on the returned buffer.
+ *
+ * OUTPUT:
+ * New available Rx resource in Rx descriptor ring.
+ *
+ * RETURN:
+ * ETH_ERROR in case the routine can not access Rx desc ring.
+ * ETH_OK otherwise.
+ *
+ *******************************************************************************/
+static ETH_FUNC_RET_STATUS eth_rx_return_buff (ETH_PORT_INFO *
+ p_eth_port_ctrl,
+ ETH_QUEUE rx_queue,
+ PKT_INFO * p_pkt_info)
+{
+ volatile ETH_RX_DESC *p_used_rx_desc; /* Where to return Rx resource */
+
+ /* Get 'used' Rx descriptor */
+ USED_RFD_GET (p_used_rx_desc, rx_queue);
+
+ /* Sanity check */
+ if (p_used_rx_desc == NULL)
+ return ETH_ERROR;
+
+ p_used_rx_desc->buf_ptr = p_pkt_info->buf_ptr;
+ p_used_rx_desc->return_info = p_pkt_info->return_info;
+ p_used_rx_desc->byte_cnt = p_pkt_info->byte_cnt;
+ p_used_rx_desc->buf_size = MV64460_RX_BUFFER_SIZE; /* Reset Buffer size */
+
+ /* Flush the write pipe */
+ CPU_PIPE_FLUSH;
+
+ /* Return the descriptor to DMA ownership */
+ p_used_rx_desc->cmd_sts =
+ ETH_BUFFER_OWNED_BY_DMA | ETH_RX_ENABLE_INTERRUPT;
+
+ /* Flush descriptor and CPU pipe */
+ D_CACHE_FLUSH_LINE ((unsigned int) p_used_rx_desc, 0);
+ CPU_PIPE_FLUSH;
+
+ /* Move the used descriptor pointer to the next descriptor */
+ USED_RFD_SET (RX_NEXT_DESC_PTR (p_used_rx_desc, rx_queue), rx_queue);
+
+ /* Any Rx return cancels the Rx resource error status */
+ if (p_eth_port_ctrl->rx_resource_err[rx_queue] == true)
+ p_eth_port_ctrl->rx_resource_err[rx_queue] = false;
+
+ return ETH_OK;
+}
+
+/*******************************************************************************
+ * eth_port_set_rx_coal - Sets coalescing interrupt mechanism on RX path
+ *
+ * DESCRIPTION:
+ * This routine sets the RX coalescing interrupt mechanism parameter.
+ * This parameter is a timeout counter, that counts in 64 t_clk
+ * chunks ; that when timeout event occurs a maskable interrupt
+ * occurs.
+ * The parameter is calculated using the tClk of the MV-643xx chip
+ * , and the required delay of the interrupt in usec.
+ *
+ * INPUT:
+ * ETH_PORT eth_port_num Ethernet port number
+ * unsigned int t_clk t_clk of the MV-643xx chip in HZ units
+ * unsigned int delay Delay in usec
+ *
+ * OUTPUT:
+ * Interrupt coalescing mechanism value is set in MV-643xx chip.
+ *
+ * RETURN:
+ * The interrupt coalescing value set in the gigE port.
+ *
+ *******************************************************************************/
+#if 0 /* FIXME */
+static unsigned int eth_port_set_rx_coal (ETH_PORT eth_port_num,
+ unsigned int t_clk,
+ unsigned int delay)
+{
+ unsigned int coal;
+
+ coal = ((t_clk / 1000000) * delay) / 64;
+ /* Set RX Coalescing mechanism */
+ MV_REG_WRITE (MV64460_ETH_SDMA_CONFIG_REG (eth_port_num),
+ ((coal & 0x3fff) << 8) |
+ (MV_REG_READ
+ (MV64460_ETH_SDMA_CONFIG_REG (eth_port_num))
+ & 0xffc000ff));
+ return coal;
+}
+
+#endif
+/*******************************************************************************
+ * eth_port_set_tx_coal - Sets coalescing interrupt mechanism on TX path
+ *
+ * DESCRIPTION:
+ * This routine sets the TX coalescing interrupt mechanism parameter.
+ * This parameter is a timeout counter, that counts in 64 t_clk
+ * chunks ; that when timeout event occurs a maskable interrupt
+ * occurs.
+ * The parameter is calculated using the t_cLK frequency of the
+ * MV-643xx chip and the required delay in the interrupt in uSec
+ *
+ * INPUT:
+ * ETH_PORT eth_port_num Ethernet port number
+ * unsigned int t_clk t_clk of the MV-643xx chip in HZ units
+ * unsigned int delay Delay in uSeconds
+ *
+ * OUTPUT:
+ * Interrupt coalescing mechanism value is set in MV-643xx chip.
+ *
+ * RETURN:
+ * The interrupt coalescing value set in the gigE port.
+ *
+ *******************************************************************************/
+#if 0 /* FIXME */
+static unsigned int eth_port_set_tx_coal (ETH_PORT eth_port_num,
+ unsigned int t_clk,
+ unsigned int delay)
+{
+ unsigned int coal;
+
+ coal = ((t_clk / 1000000) * delay) / 64;
+ /* Set TX Coalescing mechanism */
+ MV_REG_WRITE (MV64460_ETH_TX_FIFO_URGENT_THRESHOLD_REG (eth_port_num),
+ coal << 4);
+ return coal;
+}
+#endif
+
+/*******************************************************************************
+ * eth_b_copy - Copy bytes from source to destination
+ *
+ * DESCRIPTION:
+ * This function supports the eight bytes limitation on Tx buffer size.
+ * The routine will zero eight bytes starting from the destination address
+ * followed by copying bytes from the source address to the destination.
+ *
+ * INPUT:
+ * unsigned int src_addr 32 bit source address.
+ * unsigned int dst_addr 32 bit destination address.
+ * int byte_count Number of bytes to copy.
+ *
+ * OUTPUT:
+ * See description.
+ *
+ * RETURN:
+ * None.
+ *
+ *******************************************************************************/
+static void eth_b_copy (unsigned int src_addr, unsigned int dst_addr,
+ int byte_count)
+{
+ /* Zero the dst_addr area */
+ *(unsigned int *) dst_addr = 0x0;
+
+ while (byte_count != 0) {
+ *(char *) dst_addr = *(char *) src_addr;
+ dst_addr++;
+ src_addr++;
+ byte_count--;
+ }
+}
diff --git a/board/prodrive/p3mx/mv_eth.h b/board/prodrive/p3mx/mv_eth.h
new file mode 100644
index 00000000000..334b049ec55
--- /dev/null
+++ b/board/prodrive/p3mx/mv_eth.h
@@ -0,0 +1,840 @@
+/*
+ * (C) Copyright 2003
+ * Ingo Assmus <ingo.assmus@keymile.com>
+ *
+ * based on - Driver for MV64460X ethernet ports
+ * Copyright (C) 2002 rabeeh@galileo.co.il
+ *
+ * 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
+ */
+
+/*
+ * mv_eth.h - header file for the polled mode GT ethernet driver
+ */
+
+#ifndef __DB64460_ETH_H__
+#define __DB64460_ETH_H__
+
+#include <asm/types.h>
+#include <asm/io.h>
+#include <asm/byteorder.h>
+#include <common.h>
+#include <net.h>
+#include "mv_regs.h"
+#include "ppc_error_no.h"
+#include "../../Marvell/include/core.h"
+
+/*************************************************************************
+**************************************************************************
+**************************************************************************
+* The first part is the high level driver of the gigE ethernet ports. *
+**************************************************************************
+**************************************************************************
+*************************************************************************/
+#ifndef TRUE
+#define TRUE 1
+#endif
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+/* In case not using SG on Tx, define MAX_SKB_FRAGS as 0 */
+#ifndef MAX_SKB_FRAGS
+#define MAX_SKB_FRAGS 0
+#endif
+
+/* Port attributes */
+/*#define MAX_RX_QUEUE_NUM 8*/
+/*#define MAX_TX_QUEUE_NUM 8*/
+#define MAX_RX_QUEUE_NUM 1
+#define MAX_TX_QUEUE_NUM 1
+
+
+/* Use one TX queue and one RX queue */
+#define MV64460_TX_QUEUE_NUM 1
+#define MV64460_RX_QUEUE_NUM 1
+
+/*
+ * Number of RX / TX descriptors on RX / TX rings.
+ * Note that allocating RX descriptors is done by allocating the RX
+ * ring AND a preallocated RX buffers (skb's) for each descriptor.
+ * The TX descriptors only allocates the TX descriptors ring,
+ * with no pre allocated TX buffers (skb's are allocated by higher layers.
+ */
+
+/* Default TX ring size is 10 descriptors */
+#ifdef CONFIG_MV64460_ETH_TXQUEUE_SIZE
+#define MV64460_TX_QUEUE_SIZE CONFIG_MV64460_ETH_TXQUEUE_SIZE
+#else
+#define MV64460_TX_QUEUE_SIZE 4
+#endif
+
+/* Default RX ring size is 4 descriptors */
+#ifdef CONFIG_MV64460_ETH_RXQUEUE_SIZE
+#define MV64460_RX_QUEUE_SIZE CONFIG_MV64460_ETH_RXQUEUE_SIZE
+#else
+#define MV64460_RX_QUEUE_SIZE 4
+#endif
+
+#ifdef CONFIG_RX_BUFFER_SIZE
+#define MV64460_RX_BUFFER_SIZE CONFIG_RX_BUFFER_SIZE
+#else
+#define MV64460_RX_BUFFER_SIZE 1600
+#endif
+
+#ifdef CONFIG_TX_BUFFER_SIZE
+#define MV64460_TX_BUFFER_SIZE CONFIG_TX_BUFFER_SIZE
+#else
+#define MV64460_TX_BUFFER_SIZE 1600
+#endif
+
+/*
+ * Network device statistics. Akin to the 2.0 ether stats but
+ * with byte counters.
+ */
+
+struct net_device_stats
+{
+ unsigned long rx_packets; /* total packets received */
+ unsigned long tx_packets; /* total packets transmitted */
+ unsigned long rx_bytes; /* total bytes received */
+ unsigned long tx_bytes; /* total bytes transmitted */
+ unsigned long rx_errors; /* bad packets received */
+ unsigned long tx_errors; /* packet transmit problems */
+ unsigned long rx_dropped; /* no space in linux buffers */
+ unsigned long tx_dropped; /* no space available in linux */
+ unsigned long multicast; /* multicast packets received */
+ unsigned long collisions;
+
+ /* detailed rx_errors: */
+ unsigned long rx_length_errors;
+ unsigned long rx_over_errors; /* receiver ring buff overflow */
+ unsigned long rx_crc_errors; /* recved pkt with crc error */
+ unsigned long rx_frame_errors; /* recv'd frame alignment error */
+ unsigned long rx_fifo_errors; /* recv'r fifo overrun */
+ unsigned long rx_missed_errors; /* receiver missed packet */
+
+ /* detailed tx_errors */
+ unsigned long tx_aborted_errors;
+ unsigned long tx_carrier_errors;
+ unsigned long tx_fifo_errors;
+ unsigned long tx_heartbeat_errors;
+ unsigned long tx_window_errors;
+
+ /* for cslip etc */
+ unsigned long rx_compressed;
+ unsigned long tx_compressed;
+};
+
+
+/* Private data structure used for ethernet device */
+struct mv64460_eth_priv {
+ unsigned int port_num;
+ struct net_device_stats *stats;
+
+ /* to buffer area aligned */
+ char * p_eth_tx_buffer[MV64460_TX_QUEUE_SIZE+1]; /*pointers to alligned tx buffs in memory space */
+ char * p_eth_rx_buffer[MV64460_RX_QUEUE_SIZE+1]; /*pointers to allinged rx buffs in memory space */
+
+ /* Size of Tx Ring per queue */
+ unsigned int tx_ring_size [MAX_TX_QUEUE_NUM];
+
+ /* Size of Rx Ring per queue */
+ unsigned int rx_ring_size [MAX_RX_QUEUE_NUM];
+
+ /* Magic Number for Ethernet running */
+ unsigned int eth_running;
+
+ int first_init;
+};
+
+int mv64460_eth_init (struct eth_device *dev);
+int mv64460_eth_stop (struct eth_device *dev);
+int mv64460_eth_start_xmit (struct eth_device*, volatile void* packet, int length);
+/* return db64460_eth0_poll(); */
+
+int mv64460_eth_open (struct eth_device *dev);
+
+
+/*************************************************************************
+**************************************************************************
+**************************************************************************
+* The second part is the low level driver of the gigE ethernet ports. *
+**************************************************************************
+**************************************************************************
+*************************************************************************/
+
+
+/********************************************************************************
+ * Header File for : MV-643xx network interface header
+ *
+ * DESCRIPTION:
+ * This header file contains macros typedefs and function declaration for
+ * the Marvell Gig Bit Ethernet Controller.
+ *
+ * DEPENDENCIES:
+ * None.
+ *
+ *******************************************************************************/
+
+
+#ifdef CONFIG_SPECIAL_CONSISTENT_MEMORY
+#ifdef CONFIG_MV64460_SRAM_CACHEABLE
+/* In case SRAM is cacheable but not cache coherent */
+#define D_CACHE_FLUSH_LINE(addr, offset) \
+{ \
+ __asm__ __volatile__ ("dcbf %0,%1" : : "r" (addr), "r" (offset)); \
+}
+#else
+/* In case SRAM is cache coherent or non-cacheable */
+#define D_CACHE_FLUSH_LINE(addr, offset) ;
+#endif
+#else
+#ifdef CONFIG_NOT_COHERENT_CACHE
+/* In case of descriptors on DDR but not cache coherent */
+#define D_CACHE_FLUSH_LINE(addr, offset) \
+{ \
+ __asm__ __volatile__ ("dcbf %0,%1" : : "r" (addr), "r" (offset)); \
+}
+#else
+/* In case of descriptors on DDR and cache coherent */
+#define D_CACHE_FLUSH_LINE(addr, offset) ;
+#endif /* CONFIG_NOT_COHERENT_CACHE */
+#endif /* CONFIG_SPECIAL_CONSISTENT_MEMORY */
+
+
+#define CPU_PIPE_FLUSH \
+{ \
+ __asm__ __volatile__ ("eieio"); \
+}
+
+
+/* defines */
+
+/* Default port configuration value */
+#define PORT_CONFIG_VALUE \
+ ETH_UNICAST_NORMAL_MODE | \
+ ETH_DEFAULT_RX_QUEUE_0 | \
+ ETH_DEFAULT_RX_ARP_QUEUE_0 | \
+ ETH_RECEIVE_BC_IF_NOT_IP_OR_ARP | \
+ ETH_RECEIVE_BC_IF_IP | \
+ ETH_RECEIVE_BC_IF_ARP | \
+ ETH_CAPTURE_TCP_FRAMES_DIS | \
+ ETH_CAPTURE_UDP_FRAMES_DIS | \
+ ETH_DEFAULT_RX_TCP_QUEUE_0 | \
+ ETH_DEFAULT_RX_UDP_QUEUE_0 | \
+ ETH_DEFAULT_RX_BPDU_QUEUE_0
+
+/* Default port extend configuration value */
+#define PORT_CONFIG_EXTEND_VALUE \
+ ETH_SPAN_BPDU_PACKETS_AS_NORMAL | \
+ ETH_PARTITION_DISABLE
+
+
+/* Default sdma control value */
+#ifdef CONFIG_NOT_COHERENT_CACHE
+#define PORT_SDMA_CONFIG_VALUE \
+ ETH_RX_BURST_SIZE_16_64BIT | \
+ GT_ETH_IPG_INT_RX(0) | \
+ ETH_TX_BURST_SIZE_16_64BIT;
+#else
+#define PORT_SDMA_CONFIG_VALUE \
+ ETH_RX_BURST_SIZE_4_64BIT | \
+ GT_ETH_IPG_INT_RX(0) | \
+ ETH_TX_BURST_SIZE_4_64BIT;
+#endif
+
+#define GT_ETH_IPG_INT_RX(value) \
+ ((value & 0x3fff) << 8)
+
+/* Default port serial control value */
+#define PORT_SERIAL_CONTROL_VALUE \
+ ETH_FORCE_LINK_PASS | \
+ ETH_ENABLE_AUTO_NEG_FOR_DUPLX | \
+ ETH_DISABLE_AUTO_NEG_FOR_FLOW_CTRL | \
+ ETH_ADV_SYMMETRIC_FLOW_CTRL | \
+ ETH_FORCE_FC_MODE_NO_PAUSE_DIS_TX | \
+ ETH_FORCE_BP_MODE_NO_JAM | \
+ BIT9 | \
+ ETH_DO_NOT_FORCE_LINK_FAIL | \
+ ETH_RETRANSMIT_16_ETTEMPTS | \
+ ETH_ENABLE_AUTO_NEG_SPEED_GMII | \
+ ETH_DTE_ADV_0 | \
+ ETH_DISABLE_AUTO_NEG_BYPASS | \
+ ETH_AUTO_NEG_NO_CHANGE | \
+ ETH_MAX_RX_PACKET_1552BYTE | \
+ ETH_CLR_EXT_LOOPBACK | \
+ ETH_SET_FULL_DUPLEX_MODE | \
+ ETH_ENABLE_FLOW_CTRL_TX_RX_IN_FULL_DUPLEX;
+
+#define RX_BUFFER_MAX_SIZE 0xFFFF
+#define TX_BUFFER_MAX_SIZE 0xFFFF /* Buffer are limited to 64k */
+
+#define RX_BUFFER_MIN_SIZE 0x8
+#define TX_BUFFER_MIN_SIZE 0x8
+
+/* Tx WRR confoguration macros */
+#define PORT_MAX_TRAN_UNIT 0x24 /* MTU register (default) 9KByte */
+#define PORT_MAX_TOKEN_BUCKET_SIZE 0x_fFFF /* PMTBS register (default) */
+#define PORT_TOKEN_RATE 1023 /* PTTBRC register (default) */
+
+/* MAC accepet/reject macros */
+#define ACCEPT_MAC_ADDR 0
+#define REJECT_MAC_ADDR 1
+
+/* Size of a Tx/Rx descriptor used in chain list data structure */
+#define RX_DESC_ALIGNED_SIZE 0x20
+#define TX_DESC_ALIGNED_SIZE 0x20
+
+/* An offest in Tx descriptors to store data for buffers less than 8 Bytes */
+#define TX_BUF_OFFSET_IN_DESC 0x18
+/* Buffer offset from buffer pointer */
+#define RX_BUF_OFFSET 0x2
+
+/* Gap define */
+#define ETH_BAR_GAP 0x8
+#define ETH_SIZE_REG_GAP 0x8
+#define ETH_HIGH_ADDR_REMAP_REG_GAP 0x4
+#define ETH_PORT_ACCESS_CTRL_GAP 0x4
+
+/* Gigabit Ethernet Unit Global Registers */
+
+/* MIB Counters register definitions */
+#define ETH_MIB_GOOD_OCTETS_RECEIVED_LOW 0x0
+#define ETH_MIB_GOOD_OCTETS_RECEIVED_HIGH 0x4
+#define ETH_MIB_BAD_OCTETS_RECEIVED 0x8
+#define ETH_MIB_INTERNAL_MAC_TRANSMIT_ERR 0xc
+#define ETH_MIB_GOOD_FRAMES_RECEIVED 0x10
+#define ETH_MIB_BAD_FRAMES_RECEIVED 0x14
+#define ETH_MIB_BROADCAST_FRAMES_RECEIVED 0x18
+#define ETH_MIB_MULTICAST_FRAMES_RECEIVED 0x1c
+#define ETH_MIB_FRAMES_64_OCTETS 0x20
+#define ETH_MIB_FRAMES_65_TO_127_OCTETS 0x24
+#define ETH_MIB_FRAMES_128_TO_255_OCTETS 0x28
+#define ETH_MIB_FRAMES_256_TO_511_OCTETS 0x2c
+#define ETH_MIB_FRAMES_512_TO_1023_OCTETS 0x30
+#define ETH_MIB_FRAMES_1024_TO_MAX_OCTETS 0x34
+#define ETH_MIB_GOOD_OCTETS_SENT_LOW 0x38
+#define ETH_MIB_GOOD_OCTETS_SENT_HIGH 0x3c
+#define ETH_MIB_GOOD_FRAMES_SENT 0x40
+#define ETH_MIB_EXCESSIVE_COLLISION 0x44
+#define ETH_MIB_MULTICAST_FRAMES_SENT 0x48
+#define ETH_MIB_BROADCAST_FRAMES_SENT 0x4c
+#define ETH_MIB_UNREC_MAC_CONTROL_RECEIVED 0x50
+#define ETH_MIB_FC_SENT 0x54
+#define ETH_MIB_GOOD_FC_RECEIVED 0x58
+#define ETH_MIB_BAD_FC_RECEIVED 0x5c
+#define ETH_MIB_UNDERSIZE_RECEIVED 0x60
+#define ETH_MIB_FRAGMENTS_RECEIVED 0x64
+#define ETH_MIB_OVERSIZE_RECEIVED 0x68
+#define ETH_MIB_JABBER_RECEIVED 0x6c
+#define ETH_MIB_MAC_RECEIVE_ERROR 0x70
+#define ETH_MIB_BAD_CRC_EVENT 0x74
+#define ETH_MIB_COLLISION 0x78
+#define ETH_MIB_LATE_COLLISION 0x7c
+
+/* Port serial status reg (PSR) */
+#define ETH_INTERFACE_GMII_MII 0
+#define ETH_INTERFACE_PCM BIT0
+#define ETH_LINK_IS_DOWN 0
+#define ETH_LINK_IS_UP BIT1
+#define ETH_PORT_AT_HALF_DUPLEX 0
+#define ETH_PORT_AT_FULL_DUPLEX BIT2
+#define ETH_RX_FLOW_CTRL_DISABLED 0
+#define ETH_RX_FLOW_CTRL_ENBALED BIT3
+#define ETH_GMII_SPEED_100_10 0
+#define ETH_GMII_SPEED_1000 BIT4
+#define ETH_MII_SPEED_10 0
+#define ETH_MII_SPEED_100 BIT5
+#define ETH_NO_TX 0
+#define ETH_TX_IN_PROGRESS BIT7
+#define ETH_BYPASS_NO_ACTIVE 0
+#define ETH_BYPASS_ACTIVE BIT8
+#define ETH_PORT_NOT_AT_PARTITION_STATE 0
+#define ETH_PORT_AT_PARTITION_STATE BIT9
+#define ETH_PORT_TX_FIFO_NOT_EMPTY 0
+#define ETH_PORT_TX_FIFO_EMPTY BIT10
+
+
+/* These macros describes the Port configuration reg (Px_cR) bits */
+#define ETH_UNICAST_NORMAL_MODE 0
+#define ETH_UNICAST_PROMISCUOUS_MODE BIT0
+#define ETH_DEFAULT_RX_QUEUE_0 0
+#define ETH_DEFAULT_RX_QUEUE_1 BIT1
+#define ETH_DEFAULT_RX_QUEUE_2 BIT2
+#define ETH_DEFAULT_RX_QUEUE_3 (BIT2 | BIT1)
+#define ETH_DEFAULT_RX_QUEUE_4 BIT3
+#define ETH_DEFAULT_RX_QUEUE_5 (BIT3 | BIT1)
+#define ETH_DEFAULT_RX_QUEUE_6 (BIT3 | BIT2)
+#define ETH_DEFAULT_RX_QUEUE_7 (BIT3 | BIT2 | BIT1)
+#define ETH_DEFAULT_RX_ARP_QUEUE_0 0
+#define ETH_DEFAULT_RX_ARP_QUEUE_1 BIT4
+#define ETH_DEFAULT_RX_ARP_QUEUE_2 BIT5
+#define ETH_DEFAULT_RX_ARP_QUEUE_3 (BIT5 | BIT4)
+#define ETH_DEFAULT_RX_ARP_QUEUE_4 BIT6
+#define ETH_DEFAULT_RX_ARP_QUEUE_5 (BIT6 | BIT4)
+#define ETH_DEFAULT_RX_ARP_QUEUE_6 (BIT6 | BIT5)
+#define ETH_DEFAULT_RX_ARP_QUEUE_7 (BIT6 | BIT5 | BIT4)
+#define ETH_RECEIVE_BC_IF_NOT_IP_OR_ARP 0
+#define ETH_REJECT_BC_IF_NOT_IP_OR_ARP BIT7
+#define ETH_RECEIVE_BC_IF_IP 0
+#define ETH_REJECT_BC_IF_IP BIT8
+#define ETH_RECEIVE_BC_IF_ARP 0
+#define ETH_REJECT_BC_IF_ARP BIT9
+#define ETH_TX_AM_NO_UPDATE_ERROR_SUMMARY BIT12
+#define ETH_CAPTURE_TCP_FRAMES_DIS 0
+#define ETH_CAPTURE_TCP_FRAMES_EN BIT14
+#define ETH_CAPTURE_UDP_FRAMES_DIS 0
+#define ETH_CAPTURE_UDP_FRAMES_EN BIT15
+#define ETH_DEFAULT_RX_TCP_QUEUE_0 0
+#define ETH_DEFAULT_RX_TCP_QUEUE_1 BIT16
+#define ETH_DEFAULT_RX_TCP_QUEUE_2 BIT17
+#define ETH_DEFAULT_RX_TCP_QUEUE_3 (BIT17 | BIT16)
+#define ETH_DEFAULT_RX_TCP_QUEUE_4 BIT18
+#define ETH_DEFAULT_RX_TCP_QUEUE_5 (BIT18 | BIT16)
+#define ETH_DEFAULT_RX_TCP_QUEUE_6 (BIT18 | BIT17)
+#define ETH_DEFAULT_RX_TCP_QUEUE_7 (BIT18 | BIT17 | BIT16)
+#define ETH_DEFAULT_RX_UDP_QUEUE_0 0
+#define ETH_DEFAULT_RX_UDP_QUEUE_1 BIT19
+#define ETH_DEFAULT_RX_UDP_QUEUE_2 BIT20
+#define ETH_DEFAULT_RX_UDP_QUEUE_3 (BIT20 | BIT19)
+#define ETH_DEFAULT_RX_UDP_QUEUE_4 (BIT21
+#define ETH_DEFAULT_RX_UDP_QUEUE_5 (BIT21 | BIT19)
+#define ETH_DEFAULT_RX_UDP_QUEUE_6 (BIT21 | BIT20)
+#define ETH_DEFAULT_RX_UDP_QUEUE_7 (BIT21 | BIT20 | BIT19)
+#define ETH_DEFAULT_RX_BPDU_QUEUE_0 0
+#define ETH_DEFAULT_RX_BPDU_QUEUE_1 BIT22
+#define ETH_DEFAULT_RX_BPDU_QUEUE_2 BIT23
+#define ETH_DEFAULT_RX_BPDU_QUEUE_3 (BIT23 | BIT22)
+#define ETH_DEFAULT_RX_BPDU_QUEUE_4 BIT24
+#define ETH_DEFAULT_RX_BPDU_QUEUE_5 (BIT24 | BIT22)
+#define ETH_DEFAULT_RX_BPDU_QUEUE_6 (BIT24 | BIT23)
+#define ETH_DEFAULT_RX_BPDU_QUEUE_7 (BIT24 | BIT23 | BIT22)
+
+
+/* These macros describes the Port configuration extend reg (Px_cXR) bits*/
+#define ETH_CLASSIFY_EN BIT0
+#define ETH_SPAN_BPDU_PACKETS_AS_NORMAL 0
+#define ETH_SPAN_BPDU_PACKETS_TO_RX_QUEUE_7 BIT1
+#define ETH_PARTITION_DISABLE 0
+#define ETH_PARTITION_ENABLE BIT2
+
+
+/* Tx/Rx queue command reg (RQCR/TQCR)*/
+#define ETH_QUEUE_0_ENABLE BIT0
+#define ETH_QUEUE_1_ENABLE BIT1
+#define ETH_QUEUE_2_ENABLE BIT2
+#define ETH_QUEUE_3_ENABLE BIT3
+#define ETH_QUEUE_4_ENABLE BIT4
+#define ETH_QUEUE_5_ENABLE BIT5
+#define ETH_QUEUE_6_ENABLE BIT6
+#define ETH_QUEUE_7_ENABLE BIT7
+#define ETH_QUEUE_0_DISABLE BIT8
+#define ETH_QUEUE_1_DISABLE BIT9
+#define ETH_QUEUE_2_DISABLE BIT10
+#define ETH_QUEUE_3_DISABLE BIT11
+#define ETH_QUEUE_4_DISABLE BIT12
+#define ETH_QUEUE_5_DISABLE BIT13
+#define ETH_QUEUE_6_DISABLE BIT14
+#define ETH_QUEUE_7_DISABLE BIT15
+
+/* These macros describes the Port Sdma configuration reg (SDCR) bits */
+#define ETH_RIFB BIT0
+#define ETH_RX_BURST_SIZE_1_64BIT 0
+#define ETH_RX_BURST_SIZE_2_64BIT BIT1
+#define ETH_RX_BURST_SIZE_4_64BIT BIT2
+#define ETH_RX_BURST_SIZE_8_64BIT (BIT2 | BIT1)
+#define ETH_RX_BURST_SIZE_16_64BIT BIT3
+#define ETH_BLM_RX_NO_SWAP BIT4
+#define ETH_BLM_RX_BYTE_SWAP 0
+#define ETH_BLM_TX_NO_SWAP BIT5
+#define ETH_BLM_TX_BYTE_SWAP 0
+#define ETH_DESCRIPTORS_BYTE_SWAP BIT6
+#define ETH_DESCRIPTORS_NO_SWAP 0
+#define ETH_TX_BURST_SIZE_1_64BIT 0
+#define ETH_TX_BURST_SIZE_2_64BIT BIT22
+#define ETH_TX_BURST_SIZE_4_64BIT BIT23
+#define ETH_TX_BURST_SIZE_8_64BIT (BIT23 | BIT22)
+#define ETH_TX_BURST_SIZE_16_64BIT BIT24
+
+/* These macros describes the Port serial control reg (PSCR) bits */
+#define ETH_SERIAL_PORT_DISABLE 0
+#define ETH_SERIAL_PORT_ENABLE BIT0
+#define ETH_FORCE_LINK_PASS BIT1
+#define ETH_DO_NOT_FORCE_LINK_PASS 0
+#define ETH_ENABLE_AUTO_NEG_FOR_DUPLX 0
+#define ETH_DISABLE_AUTO_NEG_FOR_DUPLX BIT2
+#define ETH_ENABLE_AUTO_NEG_FOR_FLOW_CTRL 0
+#define ETH_DISABLE_AUTO_NEG_FOR_FLOW_CTRL BIT3
+#define ETH_ADV_NO_FLOW_CTRL 0
+#define ETH_ADV_SYMMETRIC_FLOW_CTRL BIT4
+#define ETH_FORCE_FC_MODE_NO_PAUSE_DIS_TX 0
+#define ETH_FORCE_FC_MODE_TX_PAUSE_DIS BIT5
+#define ETH_FORCE_BP_MODE_NO_JAM 0
+#define ETH_FORCE_BP_MODE_JAM_TX BIT7
+#define ETH_FORCE_BP_MODE_JAM_TX_ON_RX_ERR BIT8
+#define ETH_FORCE_LINK_FAIL 0
+#define ETH_DO_NOT_FORCE_LINK_FAIL BIT10
+#define ETH_RETRANSMIT_16_ETTEMPTS 0
+#define ETH_RETRANSMIT_FOREVER BIT11
+#define ETH_DISABLE_AUTO_NEG_SPEED_GMII BIT13
+#define ETH_ENABLE_AUTO_NEG_SPEED_GMII 0
+#define ETH_DTE_ADV_0 0
+#define ETH_DTE_ADV_1 BIT14
+#define ETH_DISABLE_AUTO_NEG_BYPASS 0
+#define ETH_ENABLE_AUTO_NEG_BYPASS BIT15
+#define ETH_AUTO_NEG_NO_CHANGE 0
+#define ETH_RESTART_AUTO_NEG BIT16
+#define ETH_MAX_RX_PACKET_1518BYTE 0
+#define ETH_MAX_RX_PACKET_1522BYTE BIT17
+#define ETH_MAX_RX_PACKET_1552BYTE BIT18
+#define ETH_MAX_RX_PACKET_9022BYTE (BIT18 | BIT17)
+#define ETH_MAX_RX_PACKET_9192BYTE BIT19
+#define ETH_MAX_RX_PACKET_9700BYTE (BIT19 | BIT17)
+#define ETH_SET_EXT_LOOPBACK BIT20
+#define ETH_CLR_EXT_LOOPBACK 0
+#define ETH_SET_FULL_DUPLEX_MODE BIT21
+#define ETH_SET_HALF_DUPLEX_MODE 0
+#define ETH_ENABLE_FLOW_CTRL_TX_RX_IN_FULL_DUPLEX BIT22
+#define ETH_DISABLE_FLOW_CTRL_TX_RX_IN_FULL_DUPLEX 0
+#define ETH_SET_GMII_SPEED_TO_10_100 0
+#define ETH_SET_GMII_SPEED_TO_1000 BIT23
+#define ETH_SET_MII_SPEED_TO_10 0
+#define ETH_SET_MII_SPEED_TO_100 BIT24
+
+
+/* SMI reg */
+#define ETH_SMI_BUSY BIT28 /* 0 - Write, 1 - Read */
+#define ETH_SMI_READ_VALID BIT27 /* 0 - Write, 1 - Read */
+#define ETH_SMI_OPCODE_WRITE 0 /* Completion of Read operation */
+#define ETH_SMI_OPCODE_READ BIT26 /* Operation is in progress */
+
+/* SDMA command status fields macros */
+
+/* Tx & Rx descriptors status */
+#define ETH_ERROR_SUMMARY (BIT0)
+
+/* Tx & Rx descriptors command */
+#define ETH_BUFFER_OWNED_BY_DMA (BIT31)
+
+/* Tx descriptors status */
+#define ETH_LC_ERROR (0 )
+#define ETH_UR_ERROR (BIT1 )
+#define ETH_RL_ERROR (BIT2 )
+#define ETH_LLC_SNAP_FORMAT (BIT9 )
+
+/* Rx descriptors status */
+#define ETH_CRC_ERROR (0 )
+#define ETH_OVERRUN_ERROR (BIT1 )
+#define ETH_MAX_FRAME_LENGTH_ERROR (BIT2 )
+#define ETH_RESOURCE_ERROR ((BIT2 | BIT1))
+#define ETH_VLAN_TAGGED (BIT19)
+#define ETH_BPDU_FRAME (BIT20)
+#define ETH_TCP_FRAME_OVER_IP_V_4 (0 )
+#define ETH_UDP_FRAME_OVER_IP_V_4 (BIT21)
+#define ETH_OTHER_FRAME_TYPE (BIT22)
+#define ETH_LAYER_2_IS_ETH_V_2 (BIT23)
+#define ETH_FRAME_TYPE_IP_V_4 (BIT24)
+#define ETH_FRAME_HEADER_OK (BIT25)
+#define ETH_RX_LAST_DESC (BIT26)
+#define ETH_RX_FIRST_DESC (BIT27)
+#define ETH_UNKNOWN_DESTINATION_ADDR (BIT28)
+#define ETH_RX_ENABLE_INTERRUPT (BIT29)
+#define ETH_LAYER_4_CHECKSUM_OK (BIT30)
+
+/* Rx descriptors byte count */
+#define ETH_FRAME_FRAGMENTED (BIT2)
+
+/* Tx descriptors command */
+#define ETH_LAYER_4_CHECKSUM_FIRST_DESC (BIT10)
+#define ETH_FRAME_SET_TO_VLAN (BIT15)
+#define ETH_TCP_FRAME (0 )
+#define ETH_UDP_FRAME (BIT16)
+#define ETH_GEN_TCP_UDP_CHECKSUM (BIT17)
+#define ETH_GEN_IP_V_4_CHECKSUM (BIT18)
+#define ETH_ZERO_PADDING (BIT19)
+#define ETH_TX_LAST_DESC (BIT20)
+#define ETH_TX_FIRST_DESC (BIT21)
+#define ETH_GEN_CRC (BIT22)
+#define ETH_TX_ENABLE_INTERRUPT (BIT23)
+#define ETH_AUTO_MODE (BIT30)
+
+/* Address decode parameters */
+/* Ethernet Base Address Register bits */
+#define EBAR_TARGET_DRAM 0x00000000
+#define EBAR_TARGET_DEVICE 0x00000001
+#define EBAR_TARGET_CBS 0x00000002
+#define EBAR_TARGET_PCI0 0x00000003
+#define EBAR_TARGET_PCI1 0x00000004
+#define EBAR_TARGET_CUNIT 0x00000005
+#define EBAR_TARGET_AUNIT 0x00000006
+#define EBAR_TARGET_GUNIT 0x00000007
+
+/* Window attributes */
+#define EBAR_ATTR_DRAM_CS0 0x00000E00
+#define EBAR_ATTR_DRAM_CS1 0x00000D00
+#define EBAR_ATTR_DRAM_CS2 0x00000B00
+#define EBAR_ATTR_DRAM_CS3 0x00000700
+
+/* DRAM Target interface */
+#define EBAR_ATTR_DRAM_NO_CACHE_COHERENCY 0x00000000
+#define EBAR_ATTR_DRAM_CACHE_COHERENCY_WT 0x00001000
+#define EBAR_ATTR_DRAM_CACHE_COHERENCY_WB 0x00002000
+
+/* Device Bus Target interface */
+#define EBAR_ATTR_DEVICE_DEVCS0 0x00001E00
+#define EBAR_ATTR_DEVICE_DEVCS1 0x00001D00
+#define EBAR_ATTR_DEVICE_DEVCS2 0x00001B00
+#define EBAR_ATTR_DEVICE_DEVCS3 0x00001700
+#define EBAR_ATTR_DEVICE_BOOTCS3 0x00000F00
+
+/* PCI Target interface */
+#define EBAR_ATTR_PCI_BYTE_SWAP 0x00000000
+#define EBAR_ATTR_PCI_NO_SWAP 0x00000100
+#define EBAR_ATTR_PCI_BYTE_WORD_SWAP 0x00000200
+#define EBAR_ATTR_PCI_WORD_SWAP 0x00000300
+#define EBAR_ATTR_PCI_NO_SNOOP_NOT_ASSERT 0x00000000
+#define EBAR_ATTR_PCI_NO_SNOOP_ASSERT 0x00000400
+#define EBAR_ATTR_PCI_IO_SPACE 0x00000000
+#define EBAR_ATTR_PCI_MEMORY_SPACE 0x00000800
+#define EBAR_ATTR_PCI_REQ64_FORCE 0x00000000
+#define EBAR_ATTR_PCI_REQ64_SIZE 0x00001000
+
+/* CPU 60x bus or internal SRAM interface */
+#define EBAR_ATTR_CBS_SRAM_BLOCK0 0x00000000
+#define EBAR_ATTR_CBS_SRAM_BLOCK1 0x00000100
+#define EBAR_ATTR_CBS_SRAM 0x00000000
+#define EBAR_ATTR_CBS_CPU_BUS 0x00000800
+
+/* Window access control */
+#define EWIN_ACCESS_NOT_ALLOWED 0
+#define EWIN_ACCESS_READ_ONLY BIT0
+#define EWIN_ACCESS_FULL (BIT1 | BIT0)
+#define EWIN0_ACCESS_MASK 0x0003
+#define EWIN1_ACCESS_MASK 0x000C
+#define EWIN2_ACCESS_MASK 0x0030
+#define EWIN3_ACCESS_MASK 0x00C0
+
+/* typedefs */
+
+typedef enum _eth_port
+{
+ ETH_0 = 0,
+ ETH_1 = 1,
+ ETH_2 = 2
+}ETH_PORT;
+
+typedef enum _eth_func_ret_status
+{
+ ETH_OK, /* Returned as expected. */
+ ETH_ERROR, /* Fundamental error. */
+ ETH_RETRY, /* Could not process request. Try later. */
+ ETH_END_OF_JOB, /* Ring has nothing to process. */
+ ETH_QUEUE_FULL, /* Ring resource error. */
+ ETH_QUEUE_LAST_RESOURCE /* Ring resources about to exhaust. */
+}ETH_FUNC_RET_STATUS;
+
+typedef enum _eth_queue
+{
+ ETH_Q0 = 0,
+ ETH_Q1 = 1,
+ ETH_Q2 = 2,
+ ETH_Q3 = 3,
+ ETH_Q4 = 4,
+ ETH_Q5 = 5,
+ ETH_Q6 = 6,
+ ETH_Q7 = 7
+} ETH_QUEUE;
+
+typedef enum _addr_win
+{
+ ETH_WIN0,
+ ETH_WIN1,
+ ETH_WIN2,
+ ETH_WIN3,
+ ETH_WIN4,
+ ETH_WIN5
+} ETH_ADDR_WIN;
+
+typedef enum _eth_target
+{
+ ETH_TARGET_DRAM ,
+ ETH_TARGET_DEVICE,
+ ETH_TARGET_CBS ,
+ ETH_TARGET_PCI0 ,
+ ETH_TARGET_PCI1
+}ETH_TARGET;
+
+typedef struct _eth_rx_desc
+{
+ unsigned short byte_cnt ; /* Descriptor buffer byte count */
+ unsigned short buf_size ; /* Buffer size */
+ unsigned int cmd_sts ; /* Descriptor command status */
+ unsigned int next_desc_ptr; /* Next descriptor pointer */
+ unsigned int buf_ptr ; /* Descriptor buffer pointer */
+ unsigned int return_info ; /* User resource return information */
+} ETH_RX_DESC;
+
+
+typedef struct _eth_tx_desc
+{
+ unsigned short byte_cnt ; /* Descriptor buffer byte count */
+ unsigned short l4i_chk ; /* CPU provided TCP Checksum */
+ unsigned int cmd_sts ; /* Descriptor command status */
+ unsigned int next_desc_ptr; /* Next descriptor pointer */
+ unsigned int buf_ptr ; /* Descriptor buffer pointer */
+ unsigned int return_info ; /* User resource return information */
+} ETH_TX_DESC;
+
+/* Unified struct for Rx and Tx operations. The user is not required to */
+/* be familier with neither Tx nor Rx descriptors. */
+typedef struct _pkt_info
+{
+ unsigned short byte_cnt ; /* Descriptor buffer byte count */
+ unsigned short l4i_chk ; /* Tx CPU provided TCP Checksum */
+ unsigned int cmd_sts ; /* Descriptor command status */
+ unsigned int buf_ptr ; /* Descriptor buffer pointer */
+ unsigned int return_info ; /* User resource return information */
+} PKT_INFO;
+
+
+typedef struct _eth_win_param
+{
+ ETH_ADDR_WIN win; /* Window number. See ETH_ADDR_WIN enum */
+ ETH_TARGET target; /* System targets. See ETH_TARGET enum */
+ unsigned short attributes; /* BAR attributes. See above macros. */
+ unsigned int base_addr; /* Window base address in unsigned int form */
+ unsigned int high_addr; /* Window high address in unsigned int form */
+ unsigned int size; /* Size in MBytes. Must be % 64Kbyte. */
+ bool enable; /* Enable/disable access to the window. */
+ unsigned short access_ctrl; /* Access ctrl register. see above macros */
+} ETH_WIN_PARAM;
+
+
+/* Ethernet port specific infomation */
+
+typedef struct _eth_port_ctrl
+{
+ ETH_PORT port_num; /* User Ethernet port number */
+ int port_phy_addr; /* User phy address of Ethrnet port */
+ unsigned char port_mac_addr[6]; /* User defined port MAC address. */
+ unsigned int port_config; /* User port configuration value */
+ unsigned int port_config_extend; /* User port config extend value */
+ unsigned int port_sdma_config; /* User port SDMA config value */
+ unsigned int port_serial_control; /* User port serial control value */
+ unsigned int port_tx_queue_command; /* Port active Tx queues summary */
+ unsigned int port_rx_queue_command; /* Port active Rx queues summary */
+
+ /* User function to cast virtual address to CPU bus address */
+ unsigned int (*port_virt_to_phys)(unsigned int addr);
+ /* User scratch pad for user specific data structures */
+ void *port_private;
+
+ bool rx_resource_err[MAX_RX_QUEUE_NUM]; /* Rx ring resource error flag */
+ bool tx_resource_err[MAX_TX_QUEUE_NUM]; /* Tx ring resource error flag */
+
+ /* Tx/Rx rings managment indexes fields. For driver use */
+
+ /* Next available Rx resource */
+ volatile ETH_RX_DESC *p_rx_curr_desc_q[MAX_RX_QUEUE_NUM];
+ /* Returning Rx resource */
+ volatile ETH_RX_DESC *p_rx_used_desc_q[MAX_RX_QUEUE_NUM];
+
+ /* Next available Tx resource */
+ volatile ETH_TX_DESC *p_tx_curr_desc_q[MAX_TX_QUEUE_NUM];
+ /* Returning Tx resource */
+ volatile ETH_TX_DESC *p_tx_used_desc_q[MAX_TX_QUEUE_NUM];
+ /* An extra Tx index to support transmit of multiple buffers per packet */
+ volatile ETH_TX_DESC *p_tx_first_desc_q[MAX_TX_QUEUE_NUM];
+
+ /* Tx/Rx rings size and base variables fields. For driver use */
+
+ volatile ETH_RX_DESC *p_rx_desc_area_base[MAX_RX_QUEUE_NUM];
+ unsigned int rx_desc_area_size[MAX_RX_QUEUE_NUM];
+ char *p_rx_buffer_base[MAX_RX_QUEUE_NUM];
+
+ volatile ETH_TX_DESC *p_tx_desc_area_base[MAX_TX_QUEUE_NUM];
+ unsigned int tx_desc_area_size[MAX_TX_QUEUE_NUM];
+ char *p_tx_buffer_base[MAX_TX_QUEUE_NUM];
+
+} ETH_PORT_INFO;
+
+
+/* ethernet.h API list */
+
+/* Port operation control routines */
+static void eth_port_init (ETH_PORT_INFO *p_eth_port_ctrl);
+static void eth_port_reset(ETH_PORT eth_port_num);
+static bool eth_port_start(ETH_PORT_INFO *p_eth_port_ctrl);
+
+
+/* Port MAC address routines */
+static void eth_port_uc_addr_set (ETH_PORT eth_port_num,
+ unsigned char *p_addr,
+ ETH_QUEUE queue);
+#if 0 /* FIXME */
+static void eth_port_mc_addr (ETH_PORT eth_port_num,
+ unsigned char *p_addr,
+ ETH_QUEUE queue,
+ int option);
+#endif
+
+/* PHY and MIB routines */
+static bool ethernet_phy_reset(ETH_PORT eth_port_num);
+
+static bool eth_port_write_smi_reg(ETH_PORT eth_port_num,
+ unsigned int phy_reg,
+ unsigned int value);
+
+static bool eth_port_read_smi_reg(ETH_PORT eth_port_num,
+ unsigned int phy_reg,
+ unsigned int* value);
+
+static void eth_clear_mib_counters(ETH_PORT eth_port_num);
+
+/* Port data flow control routines */
+static ETH_FUNC_RET_STATUS eth_port_send (ETH_PORT_INFO *p_eth_port_ctrl,
+ ETH_QUEUE tx_queue,
+ PKT_INFO *p_pkt_info);
+static ETH_FUNC_RET_STATUS eth_tx_return_desc(ETH_PORT_INFO *p_eth_port_ctrl,
+ ETH_QUEUE tx_queue,
+ PKT_INFO *p_pkt_info);
+static ETH_FUNC_RET_STATUS eth_port_receive (ETH_PORT_INFO *p_eth_port_ctrl,
+ ETH_QUEUE rx_queue,
+ PKT_INFO *p_pkt_info);
+static ETH_FUNC_RET_STATUS eth_rx_return_buff(ETH_PORT_INFO *p_eth_port_ctrl,
+ ETH_QUEUE rx_queue,
+ PKT_INFO *p_pkt_info);
+
+
+static bool ether_init_tx_desc_ring(ETH_PORT_INFO *p_eth_port_ctrl,
+ ETH_QUEUE tx_queue,
+ int tx_desc_num,
+ int tx_buff_size,
+ unsigned int tx_desc_base_addr,
+ unsigned int tx_buff_base_addr);
+
+static bool ether_init_rx_desc_ring(ETH_PORT_INFO *p_eth_port_ctrl,
+ ETH_QUEUE rx_queue,
+ int rx_desc_num,
+ int rx_buff_size,
+ unsigned int rx_desc_base_addr,
+ unsigned int rx_buff_base_addr);
+
+#endif /* MV64460_ETH_ */
diff --git a/board/prodrive/p3mx/mv_regs.h b/board/prodrive/p3mx/mv_regs.h
new file mode 100644
index 00000000000..068590f9d3f
--- /dev/null
+++ b/board/prodrive/p3mx/mv_regs.h
@@ -0,0 +1,1125 @@
+/*
+ * (C) Copyright 2003
+ * Ingo Assmus <ingo.assmus@keymile.com>
+ *
+ * based on - Driver for MV64460X ethernet ports
+ * Copyright (C) 2002 rabeeh@galileo.co.il
+ *
+ * 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
+ */
+
+/********************************************************************************
+* gt64460r.h - GT-64460 Internal registers definition file.
+*
+* DESCRIPTION:
+* None.
+*
+* DEPENDENCIES:
+* None.
+*
+*******************************************************************************/
+
+#ifndef __INCmv_regsh
+#define __INCmv_regsh
+
+#define MV64460
+
+/* Supported by the Atlantis */
+#define MV64460_INCLUDE_PCI_1
+#define MV64460_INCLUDE_PCI_0_ARBITER
+#define MV64460_INCLUDE_PCI_1_ARBITER
+#define MV64460_INCLUDE_SNOOP_SUPPORT
+#define MV64460_INCLUDE_P2P
+#define MV64460_INCLUDE_ETH_PORT_2
+#define MV64460_INCLUDE_CPU_MAPPING
+#define MV64460_INCLUDE_MPSC
+
+/* Not supported features */
+#undef INCLUDE_CNTMR_4_7
+#undef INCLUDE_DMA_4_7
+
+/****************************************/
+/* Processor Address Space */
+/****************************************/
+
+/* DDR SDRAM BAR and size registers */
+
+#define MV64460_CS_0_BASE_ADDR 0x008
+#define MV64460_CS_0_SIZE 0x010
+#define MV64460_CS_1_BASE_ADDR 0x208
+#define MV64460_CS_1_SIZE 0x210
+#define MV64460_CS_2_BASE_ADDR 0x018
+#define MV64460_CS_2_SIZE 0x020
+#define MV64460_CS_3_BASE_ADDR 0x218
+#define MV64460_CS_3_SIZE 0x220
+
+/* Devices BAR and size registers */
+
+#define MV64460_DEV_CS0_BASE_ADDR 0x028
+#define MV64460_DEV_CS0_SIZE 0x030
+#define MV64460_DEV_CS1_BASE_ADDR 0x228
+#define MV64460_DEV_CS1_SIZE 0x230
+#define MV64460_DEV_CS2_BASE_ADDR 0x248
+#define MV64460_DEV_CS2_SIZE 0x250
+#define MV64460_DEV_CS3_BASE_ADDR 0x038
+#define MV64460_DEV_CS3_SIZE 0x040
+#define MV64460_BOOTCS_BASE_ADDR 0x238
+#define MV64460_BOOTCS_SIZE 0x240
+
+/* PCI 0 BAR and size registers */
+
+#define MV64460_PCI_0_IO_BASE_ADDR 0x048
+#define MV64460_PCI_0_IO_SIZE 0x050
+#define MV64460_PCI_0_MEMORY0_BASE_ADDR 0x058
+#define MV64460_PCI_0_MEMORY0_SIZE 0x060
+#define MV64460_PCI_0_MEMORY1_BASE_ADDR 0x080
+#define MV64460_PCI_0_MEMORY1_SIZE 0x088
+#define MV64460_PCI_0_MEMORY2_BASE_ADDR 0x258
+#define MV64460_PCI_0_MEMORY2_SIZE 0x260
+#define MV64460_PCI_0_MEMORY3_BASE_ADDR 0x280
+#define MV64460_PCI_0_MEMORY3_SIZE 0x288
+
+/* PCI 1 BAR and size registers */
+#define MV64460_PCI_1_IO_BASE_ADDR 0x090
+#define MV64460_PCI_1_IO_SIZE 0x098
+#define MV64460_PCI_1_MEMORY0_BASE_ADDR 0x0a0
+#define MV64460_PCI_1_MEMORY0_SIZE 0x0a8
+#define MV64460_PCI_1_MEMORY1_BASE_ADDR 0x0b0
+#define MV64460_PCI_1_MEMORY1_SIZE 0x0b8
+#define MV64460_PCI_1_MEMORY2_BASE_ADDR 0x2a0
+#define MV64460_PCI_1_MEMORY2_SIZE 0x2a8
+#define MV64460_PCI_1_MEMORY3_BASE_ADDR 0x2b0
+#define MV64460_PCI_1_MEMORY3_SIZE 0x2b8
+
+/* SRAM base address */
+#define MV64460_INTEGRATED_SRAM_BASE_ADDR 0x268
+
+/* internal registers space base address */
+#define MV64460_INTERNAL_SPACE_BASE_ADDR 0x068
+
+/* Enables the CS , DEV_CS , PCI 0 and PCI 1
+ windows above */
+#define MV64460_BASE_ADDR_ENABLE 0x278
+
+/****************************************/
+/* PCI remap registers */
+/****************************************/
+ /* PCI 0 */
+#define MV64460_PCI_0_IO_ADDR_REMAP 0x0f0
+#define MV64460_PCI_0_MEMORY0_LOW_ADDR_REMAP 0x0f8
+#define MV64460_PCI_0_MEMORY0_HIGH_ADDR_REMAP 0x320
+#define MV64460_PCI_0_MEMORY1_LOW_ADDR_REMAP 0x100
+#define MV64460_PCI_0_MEMORY1_HIGH_ADDR_REMAP 0x328
+#define MV64460_PCI_0_MEMORY2_LOW_ADDR_REMAP 0x2f8
+#define MV64460_PCI_0_MEMORY2_HIGH_ADDR_REMAP 0x330
+#define MV64460_PCI_0_MEMORY3_LOW_ADDR_REMAP 0x300
+#define MV64460_PCI_0_MEMORY3_HIGH_ADDR_REMAP 0x338
+ /* PCI 1 */
+#define MV64460_PCI_1_IO_ADDR_REMAP 0x108
+#define MV64460_PCI_1_MEMORY0_LOW_ADDR_REMAP 0x110
+#define MV64460_PCI_1_MEMORY0_HIGH_ADDR_REMAP 0x340
+#define MV64460_PCI_1_MEMORY1_LOW_ADDR_REMAP 0x118
+#define MV64460_PCI_1_MEMORY1_HIGH_ADDR_REMAP 0x348
+#define MV64460_PCI_1_MEMORY2_LOW_ADDR_REMAP 0x310
+#define MV64460_PCI_1_MEMORY2_HIGH_ADDR_REMAP 0x350
+#define MV64460_PCI_1_MEMORY3_LOW_ADDR_REMAP 0x318
+#define MV64460_PCI_1_MEMORY3_HIGH_ADDR_REMAP 0x358
+
+#define MV64460_CPU_PCI_0_HEADERS_RETARGET_CONTROL 0x3b0
+#define MV64460_CPU_PCI_0_HEADERS_RETARGET_BASE 0x3b8
+#define MV64460_CPU_PCI_1_HEADERS_RETARGET_CONTROL 0x3c0
+#define MV64460_CPU_PCI_1_HEADERS_RETARGET_BASE 0x3c8
+#define MV64460_CPU_GE_HEADERS_RETARGET_CONTROL 0x3d0
+#define MV64460_CPU_GE_HEADERS_RETARGET_BASE 0x3d8
+#define MV64460_CPU_IDMA_HEADERS_RETARGET_CONTROL 0x3e0
+#define MV64460_CPU_IDMA_HEADERS_RETARGET_BASE 0x3e8
+
+/****************************************/
+/* CPU Control Registers */
+/****************************************/
+
+#define MV64460_CPU_CONFIG 0x000
+#define MV64460_CPU_MODE 0x120
+#define MV64460_CPU_MASTER_CONTROL 0x160
+#define MV64460_CPU_CROSS_BAR_CONTROL_LOW 0x150
+#define MV64460_CPU_CROSS_BAR_CONTROL_HIGH 0x158
+#define MV64460_CPU_CROSS_BAR_TIMEOUT 0x168
+
+/****************************************/
+/* SMP RegisterS */
+/****************************************/
+
+#define MV64460_SMP_WHO_AM_I 0x200
+#define MV64460_SMP_CPU0_DOORBELL 0x214
+#define MV64460_SMP_CPU0_DOORBELL_CLEAR 0x21C
+#define MV64460_SMP_CPU1_DOORBELL 0x224
+#define MV64460_SMP_CPU1_DOORBELL_CLEAR 0x22C
+#define MV64460_SMP_CPU0_DOORBELL_MASK 0x234
+#define MV64460_SMP_CPU1_DOORBELL_MASK 0x23C
+#define MV64460_SMP_SEMAPHOR0 0x244
+#define MV64460_SMP_SEMAPHOR1 0x24c
+#define MV64460_SMP_SEMAPHOR2 0x254
+#define MV64460_SMP_SEMAPHOR3 0x25c
+#define MV64460_SMP_SEMAPHOR4 0x264
+#define MV64460_SMP_SEMAPHOR5 0x26c
+#define MV64460_SMP_SEMAPHOR6 0x274
+#define MV64460_SMP_SEMAPHOR7 0x27c
+
+/****************************************/
+/* CPU Sync Barrier Register */
+/****************************************/
+
+#define MV64460_CPU_0_SYNC_BARRIER_TRIGGER 0x0c0
+#define MV64460_CPU_0_SYNC_BARRIER_VIRTUAL 0x0c8
+#define MV64460_CPU_1_SYNC_BARRIER_TRIGGER 0x0d0
+#define MV64460_CPU_1_SYNC_BARRIER_VIRTUAL 0x0d8
+
+/****************************************/
+/* CPU Access Protect */
+/****************************************/
+
+#define MV64460_CPU_PROTECT_WINDOW_0_BASE_ADDR 0x180
+#define MV64460_CPU_PROTECT_WINDOW_0_SIZE 0x188
+#define MV64460_CPU_PROTECT_WINDOW_1_BASE_ADDR 0x190
+#define MV64460_CPU_PROTECT_WINDOW_1_SIZE 0x198
+#define MV64460_CPU_PROTECT_WINDOW_2_BASE_ADDR 0x1a0
+#define MV64460_CPU_PROTECT_WINDOW_2_SIZE 0x1a8
+#define MV64460_CPU_PROTECT_WINDOW_3_BASE_ADDR 0x1b0
+#define MV64460_CPU_PROTECT_WINDOW_3_SIZE 0x1b8
+
+
+/****************************************/
+/* CPU Error Report */
+/****************************************/
+
+#define MV64460_CPU_ERROR_ADDR_LOW 0x070
+#define MV64460_CPU_ERROR_ADDR_HIGH 0x078
+#define MV64460_CPU_ERROR_DATA_LOW 0x128
+#define MV64460_CPU_ERROR_DATA_HIGH 0x130
+#define MV64460_CPU_ERROR_PARITY 0x138
+#define MV64460_CPU_ERROR_CAUSE 0x140
+#define MV64460_CPU_ERROR_MASK 0x148
+
+/****************************************/
+/* CPU Interface Debug Registers */
+/****************************************/
+
+#define MV64460_PUNIT_SLAVE_DEBUG_LOW 0x360
+#define MV64460_PUNIT_SLAVE_DEBUG_HIGH 0x368
+#define MV64460_PUNIT_MASTER_DEBUG_LOW 0x370
+#define MV64460_PUNIT_MASTER_DEBUG_HIGH 0x378
+#define MV64460_PUNIT_MMASK 0x3e4
+
+/****************************************/
+/* Integrated SRAM Registers */
+/****************************************/
+
+#define MV64460_SRAM_CONFIG 0x380
+#define MV64460_SRAM_TEST_MODE 0X3F4
+#define MV64460_SRAM_ERROR_CAUSE 0x388
+#define MV64460_SRAM_ERROR_ADDR 0x390
+#define MV64460_SRAM_ERROR_ADDR_HIGH 0X3F8
+#define MV64460_SRAM_ERROR_DATA_LOW 0x398
+#define MV64460_SRAM_ERROR_DATA_HIGH 0x3a0
+#define MV64460_SRAM_ERROR_DATA_PARITY 0x3a8
+
+/****************************************/
+/* SDRAM Configuration */
+/****************************************/
+
+#define MV64460_SDRAM_CONFIG 0x1400
+#define MV64460_D_UNIT_CONTROL_LOW 0x1404
+#define MV64460_D_UNIT_CONTROL_HIGH 0x1424
+#define MV64460_D_UNIT_MMASK 0x14B0
+#define MV64460_SDRAM_TIMING_CONTROL_LOW 0x1408
+#define MV64460_SDRAM_TIMING_CONTROL_HIGH 0x140c
+#define MV64460_SDRAM_ADDR_CONTROL 0x1410
+#define MV64460_SDRAM_OPEN_PAGES_CONTROL 0x1414
+#define MV64460_SDRAM_OPERATION 0x1418
+#define MV64460_SDRAM_MODE 0x141c
+#define MV64460_EXTENDED_DRAM_MODE 0x1420
+#define MV64460_SDRAM_CROSS_BAR_CONTROL_LOW 0x1430
+#define MV64460_SDRAM_CROSS_BAR_CONTROL_HIGH 0x1434
+#define MV64460_SDRAM_CROSS_BAR_TIMEOUT 0x1438
+#define MV64460_SDRAM_ADDR_CTRL_PADS_CALIBRATION 0x14c0
+#define MV64460_SDRAM_DATA_PADS_CALIBRATION 0x14c4
+
+/****************************************/
+/* SDRAM Error Report */
+/****************************************/
+
+#define MV64460_SDRAM_ERROR_DATA_LOW 0x1444
+#define MV64460_SDRAM_ERROR_DATA_HIGH 0x1440
+#define MV64460_SDRAM_ERROR_ADDR 0x1450
+#define MV64460_SDRAM_RECEIVED_ECC 0x1448
+#define MV64460_SDRAM_CALCULATED_ECC 0x144c
+#define MV64460_SDRAM_ECC_CONTROL 0x1454
+#define MV64460_SDRAM_ECC_ERROR_COUNTER 0x1458
+
+/******************************************/
+/* Controlled Delay Line (CDL) Registers */
+/******************************************/
+
+#define MV64460_DFCDL_CONFIG0 0x1480
+#define MV64460_DFCDL_CONFIG1 0x1484
+#define MV64460_DLL_WRITE 0x1488
+#define MV64460_DLL_READ 0x148c
+#define MV64460_SRAM_ADDR 0x1490
+#define MV64460_SRAM_DATA0 0x1494
+#define MV64460_SRAM_DATA1 0x1498
+#define MV64460_SRAM_DATA2 0x149c
+#define MV64460_DFCL_PROBE 0x14a0
+
+/******************************************/
+/* Debug Registers */
+/******************************************/
+
+#define MV64460_DUNIT_DEBUG_LOW 0x1460
+#define MV64460_DUNIT_DEBUG_HIGH 0x1464
+#define MV64460_DUNIT_MMASK 0X1b40
+
+/****************************************/
+/* Device Parameters */
+/****************************************/
+
+#define MV64460_DEVICE_BANK0_PARAMETERS 0x45c
+#define MV64460_DEVICE_BANK1_PARAMETERS 0x460
+#define MV64460_DEVICE_BANK2_PARAMETERS 0x464
+#define MV64460_DEVICE_BANK3_PARAMETERS 0x468
+#define MV64460_DEVICE_BOOT_BANK_PARAMETERS 0x46c
+#define MV64460_DEVICE_INTERFACE_CONTROL 0x4c0
+#define MV64460_DEVICE_INTERFACE_CROSS_BAR_CONTROL_LOW 0x4c8
+#define MV64460_DEVICE_INTERFACE_CROSS_BAR_CONTROL_HIGH 0x4cc
+#define MV64460_DEVICE_INTERFACE_CROSS_BAR_TIMEOUT 0x4c4
+
+/****************************************/
+/* Device interrupt registers */
+/****************************************/
+
+#define MV64460_DEVICE_INTERRUPT_CAUSE 0x4d0
+#define MV64460_DEVICE_INTERRUPT_MASK 0x4d4
+#define MV64460_DEVICE_ERROR_ADDR 0x4d8
+#define MV64460_DEVICE_ERROR_DATA 0x4dc
+#define MV64460_DEVICE_ERROR_PARITY 0x4e0
+
+/****************************************/
+/* Device debug registers */
+/****************************************/
+
+#define MV64460_DEVICE_DEBUG_LOW 0x4e4
+#define MV64460_DEVICE_DEBUG_HIGH 0x4e8
+#define MV64460_RUNIT_MMASK 0x4f0
+
+/****************************************/
+/* PCI Slave Address Decoding registers */
+/****************************************/
+
+#define MV64460_PCI_0_CS_0_BANK_SIZE 0xc08
+#define MV64460_PCI_1_CS_0_BANK_SIZE 0xc88
+#define MV64460_PCI_0_CS_1_BANK_SIZE 0xd08
+#define MV64460_PCI_1_CS_1_BANK_SIZE 0xd88
+#define MV64460_PCI_0_CS_2_BANK_SIZE 0xc0c
+#define MV64460_PCI_1_CS_2_BANK_SIZE 0xc8c
+#define MV64460_PCI_0_CS_3_BANK_SIZE 0xd0c
+#define MV64460_PCI_1_CS_3_BANK_SIZE 0xd8c
+#define MV64460_PCI_0_DEVCS_0_BANK_SIZE 0xc10
+#define MV64460_PCI_1_DEVCS_0_BANK_SIZE 0xc90
+#define MV64460_PCI_0_DEVCS_1_BANK_SIZE 0xd10
+#define MV64460_PCI_1_DEVCS_1_BANK_SIZE 0xd90
+#define MV64460_PCI_0_DEVCS_2_BANK_SIZE 0xd18
+#define MV64460_PCI_1_DEVCS_2_BANK_SIZE 0xd98
+#define MV64460_PCI_0_DEVCS_3_BANK_SIZE 0xc14
+#define MV64460_PCI_1_DEVCS_3_BANK_SIZE 0xc94
+#define MV64460_PCI_0_DEVCS_BOOT_BANK_SIZE 0xd14
+#define MV64460_PCI_1_DEVCS_BOOT_BANK_SIZE 0xd94
+#define MV64460_PCI_0_P2P_MEM0_BAR_SIZE 0xd1c
+#define MV64460_PCI_1_P2P_MEM0_BAR_SIZE 0xd9c
+#define MV64460_PCI_0_P2P_MEM1_BAR_SIZE 0xd20
+#define MV64460_PCI_1_P2P_MEM1_BAR_SIZE 0xda0
+#define MV64460_PCI_0_P2P_I_O_BAR_SIZE 0xd24
+#define MV64460_PCI_1_P2P_I_O_BAR_SIZE 0xda4
+#define MV64460_PCI_0_CPU_BAR_SIZE 0xd28
+#define MV64460_PCI_1_CPU_BAR_SIZE 0xda8
+#define MV64460_PCI_0_INTERNAL_SRAM_BAR_SIZE 0xe00
+#define MV64460_PCI_1_INTERNAL_SRAM_BAR_SIZE 0xe80
+#define MV64460_PCI_0_EXPANSION_ROM_BAR_SIZE 0xd2c
+#define MV64460_PCI_1_EXPANSION_ROM_BAR_SIZE 0xd9c
+#define MV64460_PCI_0_BASE_ADDR_REG_ENABLE 0xc3c
+#define MV64460_PCI_1_BASE_ADDR_REG_ENABLE 0xcbc
+#define MV64460_PCI_0_CS_0_BASE_ADDR_REMAP 0xc48
+#define MV64460_PCI_1_CS_0_BASE_ADDR_REMAP 0xcc8
+#define MV64460_PCI_0_CS_1_BASE_ADDR_REMAP 0xd48
+#define MV64460_PCI_1_CS_1_BASE_ADDR_REMAP 0xdc8
+#define MV64460_PCI_0_CS_2_BASE_ADDR_REMAP 0xc4c
+#define MV64460_PCI_1_CS_2_BASE_ADDR_REMAP 0xccc
+#define MV64460_PCI_0_CS_3_BASE_ADDR_REMAP 0xd4c
+#define MV64460_PCI_1_CS_3_BASE_ADDR_REMAP 0xdcc
+#define MV64460_PCI_0_CS_0_BASE_HIGH_ADDR_REMAP 0xF04
+#define MV64460_PCI_1_CS_0_BASE_HIGH_ADDR_REMAP 0xF84
+#define MV64460_PCI_0_CS_1_BASE_HIGH_ADDR_REMAP 0xF08
+#define MV64460_PCI_1_CS_1_BASE_HIGH_ADDR_REMAP 0xF88
+#define MV64460_PCI_0_CS_2_BASE_HIGH_ADDR_REMAP 0xF0C
+#define MV64460_PCI_1_CS_2_BASE_HIGH_ADDR_REMAP 0xF8C
+#define MV64460_PCI_0_CS_3_BASE_HIGH_ADDR_REMAP 0xF10
+#define MV64460_PCI_1_CS_3_BASE_HIGH_ADDR_REMAP 0xF90
+#define MV64460_PCI_0_DEVCS_0_BASE_ADDR_REMAP 0xc50
+#define MV64460_PCI_1_DEVCS_0_BASE_ADDR_REMAP 0xcd0
+#define MV64460_PCI_0_DEVCS_1_BASE_ADDR_REMAP 0xd50
+#define MV64460_PCI_1_DEVCS_1_BASE_ADDR_REMAP 0xdd0
+#define MV64460_PCI_0_DEVCS_2_BASE_ADDR_REMAP 0xd58
+#define MV64460_PCI_1_DEVCS_2_BASE_ADDR_REMAP 0xdd8
+#define MV64460_PCI_0_DEVCS_3_BASE_ADDR_REMAP 0xc54
+#define MV64460_PCI_1_DEVCS_3_BASE_ADDR_REMAP 0xcd4
+#define MV64460_PCI_0_DEVCS_BOOTCS_BASE_ADDR_REMAP 0xd54
+#define MV64460_PCI_1_DEVCS_BOOTCS_BASE_ADDR_REMAP 0xdd4
+#define MV64460_PCI_0_P2P_MEM0_BASE_ADDR_REMAP_LOW 0xd5c
+#define MV64460_PCI_1_P2P_MEM0_BASE_ADDR_REMAP_LOW 0xddc
+#define MV64460_PCI_0_P2P_MEM0_BASE_ADDR_REMAP_HIGH 0xd60
+#define MV64460_PCI_1_P2P_MEM0_BASE_ADDR_REMAP_HIGH 0xde0
+#define MV64460_PCI_0_P2P_MEM1_BASE_ADDR_REMAP_LOW 0xd64
+#define MV64460_PCI_1_P2P_MEM1_BASE_ADDR_REMAP_LOW 0xde4
+#define MV64460_PCI_0_P2P_MEM1_BASE_ADDR_REMAP_HIGH 0xd68
+#define MV64460_PCI_1_P2P_MEM1_BASE_ADDR_REMAP_HIGH 0xde8
+#define MV64460_PCI_0_P2P_I_O_BASE_ADDR_REMAP 0xd6c
+#define MV64460_PCI_1_P2P_I_O_BASE_ADDR_REMAP 0xdec
+#define MV64460_PCI_0_CPU_BASE_ADDR_REMAP_LOW 0xd70
+#define MV64460_PCI_1_CPU_BASE_ADDR_REMAP_LOW 0xdf0
+#define MV64460_PCI_0_CPU_BASE_ADDR_REMAP_HIGH 0xd74
+#define MV64460_PCI_1_CPU_BASE_ADDR_REMAP_HIGH 0xdf4
+#define MV64460_PCI_0_INTEGRATED_SRAM_BASE_ADDR_REMAP 0xf00
+#define MV64460_PCI_1_INTEGRATED_SRAM_BASE_ADDR_REMAP 0xf80
+#define MV64460_PCI_0_EXPANSION_ROM_BASE_ADDR_REMAP 0xf38
+#define MV64460_PCI_1_EXPANSION_ROM_BASE_ADDR_REMAP 0xfb8
+#define MV64460_PCI_0_ADDR_DECODE_CONTROL 0xd3c
+#define MV64460_PCI_1_ADDR_DECODE_CONTROL 0xdbc
+#define MV64460_PCI_0_HEADERS_RETARGET_CONTROL 0xF40
+#define MV64460_PCI_1_HEADERS_RETARGET_CONTROL 0xFc0
+#define MV64460_PCI_0_HEADERS_RETARGET_BASE 0xF44
+#define MV64460_PCI_1_HEADERS_RETARGET_BASE 0xFc4
+#define MV64460_PCI_0_HEADERS_RETARGET_HIGH 0xF48
+#define MV64460_PCI_1_HEADERS_RETARGET_HIGH 0xFc8
+
+/***********************************/
+/* PCI Control Register Map */
+/***********************************/
+
+#define MV64460_PCI_0_DLL_STATUS_AND_COMMAND 0x1d20
+#define MV64460_PCI_1_DLL_STATUS_AND_COMMAND 0x1da0
+#define MV64460_PCI_0_MPP_PADS_DRIVE_CONTROL 0x1d1C
+#define MV64460_PCI_1_MPP_PADS_DRIVE_CONTROL 0x1d9C
+#define MV64460_PCI_0_COMMAND 0xc00
+#define MV64460_PCI_1_COMMAND 0xc80
+#define MV64460_PCI_0_MODE 0xd00
+#define MV64460_PCI_1_MODE 0xd80
+#define MV64460_PCI_0_RETRY 0xc04
+#define MV64460_PCI_1_RETRY 0xc84
+#define MV64460_PCI_0_READ_BUFFER_DISCARD_TIMER 0xd04
+#define MV64460_PCI_1_READ_BUFFER_DISCARD_TIMER 0xd84
+#define MV64460_PCI_0_MSI_TRIGGER_TIMER 0xc38
+#define MV64460_PCI_1_MSI_TRIGGER_TIMER 0xcb8
+#define MV64460_PCI_0_ARBITER_CONTROL 0x1d00
+#define MV64460_PCI_1_ARBITER_CONTROL 0x1d80
+#define MV64460_PCI_0_CROSS_BAR_CONTROL_LOW 0x1d08
+#define MV64460_PCI_1_CROSS_BAR_CONTROL_LOW 0x1d88
+#define MV64460_PCI_0_CROSS_BAR_CONTROL_HIGH 0x1d0c
+#define MV64460_PCI_1_CROSS_BAR_CONTROL_HIGH 0x1d8c
+#define MV64460_PCI_0_CROSS_BAR_TIMEOUT 0x1d04
+#define MV64460_PCI_1_CROSS_BAR_TIMEOUT 0x1d84
+#define MV64460_PCI_0_SYNC_BARRIER_TRIGGER_REG 0x1D18
+#define MV64460_PCI_1_SYNC_BARRIER_TRIGGER_REG 0x1D98
+#define MV64460_PCI_0_SYNC_BARRIER_VIRTUAL_REG 0x1d10
+#define MV64460_PCI_1_SYNC_BARRIER_VIRTUAL_REG 0x1d90
+#define MV64460_PCI_0_P2P_CONFIG 0x1d14
+#define MV64460_PCI_1_P2P_CONFIG 0x1d94
+
+#define MV64460_PCI_0_ACCESS_CONTROL_BASE_0_LOW 0x1e00
+#define MV64460_PCI_0_ACCESS_CONTROL_BASE_0_HIGH 0x1e04
+#define MV64460_PCI_0_ACCESS_CONTROL_SIZE_0 0x1e08
+#define MV64460_PCI_0_ACCESS_CONTROL_BASE_1_LOW 0x1e10
+#define MV64460_PCI_0_ACCESS_CONTROL_BASE_1_HIGH 0x1e14
+#define MV64460_PCI_0_ACCESS_CONTROL_SIZE_1 0x1e18
+#define MV64460_PCI_0_ACCESS_CONTROL_BASE_2_LOW 0x1e20
+#define MV64460_PCI_0_ACCESS_CONTROL_BASE_2_HIGH 0x1e24
+#define MV64460_PCI_0_ACCESS_CONTROL_SIZE_2 0x1e28
+#define MV64460_PCI_0_ACCESS_CONTROL_BASE_3_LOW 0x1e30
+#define MV64460_PCI_0_ACCESS_CONTROL_BASE_3_HIGH 0x1e34
+#define MV64460_PCI_0_ACCESS_CONTROL_SIZE_3 0x1e38
+#define MV64460_PCI_0_ACCESS_CONTROL_BASE_4_LOW 0x1e40
+#define MV64460_PCI_0_ACCESS_CONTROL_BASE_4_HIGH 0x1e44
+#define MV64460_PCI_0_ACCESS_CONTROL_SIZE_4 0x1e48
+#define MV64460_PCI_0_ACCESS_CONTROL_BASE_5_LOW 0x1e50
+#define MV64460_PCI_0_ACCESS_CONTROL_BASE_5_HIGH 0x1e54
+#define MV64460_PCI_0_ACCESS_CONTROL_SIZE_5 0x1e58
+
+#define MV64460_PCI_1_ACCESS_CONTROL_BASE_0_LOW 0x1e80
+#define MV64460_PCI_1_ACCESS_CONTROL_BASE_0_HIGH 0x1e84
+#define MV64460_PCI_1_ACCESS_CONTROL_SIZE_0 0x1e88
+#define MV64460_PCI_1_ACCESS_CONTROL_BASE_1_LOW 0x1e90
+#define MV64460_PCI_1_ACCESS_CONTROL_BASE_1_HIGH 0x1e94
+#define MV64460_PCI_1_ACCESS_CONTROL_SIZE_1 0x1e98
+#define MV64460_PCI_1_ACCESS_CONTROL_BASE_2_LOW 0x1ea0
+#define MV64460_PCI_1_ACCESS_CONTROL_BASE_2_HIGH 0x1ea4
+#define MV64460_PCI_1_ACCESS_CONTROL_SIZE_2 0x1ea8
+#define MV64460_PCI_1_ACCESS_CONTROL_BASE_3_LOW 0x1eb0
+#define MV64460_PCI_1_ACCESS_CONTROL_BASE_3_HIGH 0x1eb4
+#define MV64460_PCI_1_ACCESS_CONTROL_SIZE_3 0x1eb8
+#define MV64460_PCI_1_ACCESS_CONTROL_BASE_4_LOW 0x1ec0
+#define MV64460_PCI_1_ACCESS_CONTROL_BASE_4_HIGH 0x1ec4
+#define MV64460_PCI_1_ACCESS_CONTROL_SIZE_4 0x1ec8
+#define MV64460_PCI_1_ACCESS_CONTROL_BASE_5_LOW 0x1ed0
+#define MV64460_PCI_1_ACCESS_CONTROL_BASE_5_HIGH 0x1ed4
+#define MV64460_PCI_1_ACCESS_CONTROL_SIZE_5 0x1ed8
+
+/****************************************/
+/* PCI Configuration Access Registers */
+/****************************************/
+
+#define MV64460_PCI_0_CONFIG_ADDR 0xcf8
+#define MV64460_PCI_0_CONFIG_DATA_VIRTUAL_REG 0xcfc
+#define MV64460_PCI_1_CONFIG_ADDR 0xc78
+#define MV64460_PCI_1_CONFIG_DATA_VIRTUAL_REG 0xc7c
+#define MV64460_PCI_0_INTERRUPT_ACKNOWLEDGE_VIRTUAL_REG 0xc34
+#define MV64460_PCI_1_INTERRUPT_ACKNOWLEDGE_VIRTUAL_REG 0xcb4
+
+/****************************************/
+/* PCI Error Report Registers */
+/****************************************/
+
+#define MV64460_PCI_0_SERR_MASK 0xc28
+#define MV64460_PCI_1_SERR_MASK 0xca8
+#define MV64460_PCI_0_ERROR_ADDR_LOW 0x1d40
+#define MV64460_PCI_1_ERROR_ADDR_LOW 0x1dc0
+#define MV64460_PCI_0_ERROR_ADDR_HIGH 0x1d44
+#define MV64460_PCI_1_ERROR_ADDR_HIGH 0x1dc4
+#define MV64460_PCI_0_ERROR_ATTRIBUTE 0x1d48
+#define MV64460_PCI_1_ERROR_ATTRIBUTE 0x1dc8
+#define MV64460_PCI_0_ERROR_COMMAND 0x1d50
+#define MV64460_PCI_1_ERROR_COMMAND 0x1dd0
+#define MV64460_PCI_0_ERROR_CAUSE 0x1d58
+#define MV64460_PCI_1_ERROR_CAUSE 0x1dd8
+#define MV64460_PCI_0_ERROR_MASK 0x1d5c
+#define MV64460_PCI_1_ERROR_MASK 0x1ddc
+
+/****************************************/
+/* PCI Debug Registers */
+/****************************************/
+
+#define MV64460_PCI_0_MMASK 0X1D24
+#define MV64460_PCI_1_MMASK 0X1DA4
+
+/*********************************************/
+/* PCI Configuration, Function 0, Registers */
+/*********************************************/
+
+#define MV64460_PCI_DEVICE_AND_VENDOR_ID 0x000
+#define MV64460_PCI_STATUS_AND_COMMAND 0x004
+#define MV64460_PCI_CLASS_CODE_AND_REVISION_ID 0x008
+#define MV64460_PCI_BIST_HEADER_TYPE_LATENCY_TIMER_CACHE_LINE 0x00C
+
+#define MV64460_PCI_SCS_0_BASE_ADDR_LOW 0x010
+#define MV64460_PCI_SCS_0_BASE_ADDR_HIGH 0x014
+#define MV64460_PCI_SCS_1_BASE_ADDR_LOW 0x018
+#define MV64460_PCI_SCS_1_BASE_ADDR_HIGH 0x01C
+#define MV64460_PCI_INTERNAL_REG_MEM_MAPPED_BASE_ADDR_LOW 0x020
+#define MV64460_PCI_INTERNAL_REG_MEM_MAPPED_BASE_ADDR_HIGH 0x024
+#define MV64460_PCI_SUBSYSTEM_ID_AND_SUBSYSTEM_VENDOR_ID 0x02c
+#define MV64460_PCI_EXPANSION_ROM_BASE_ADDR_REG 0x030
+#define MV64460_PCI_CAPABILTY_LIST_POINTER 0x034
+#define MV64460_PCI_INTERRUPT_PIN_AND_LINE 0x03C
+ /* capability list */
+#define MV64460_PCI_POWER_MANAGEMENT_CAPABILITY 0x040
+#define MV64460_PCI_POWER_MANAGEMENT_STATUS_AND_CONTROL 0x044
+#define MV64460_PCI_VPD_ADDR 0x048
+#define MV64460_PCI_VPD_DATA 0x04c
+#define MV64460_PCI_MSI_MESSAGE_CONTROL 0x050
+#define MV64460_PCI_MSI_MESSAGE_ADDR 0x054
+#define MV64460_PCI_MSI_MESSAGE_UPPER_ADDR 0x058
+#define MV64460_PCI_MSI_MESSAGE_DATA 0x05c
+#define MV64460_PCI_X_COMMAND 0x060
+#define MV64460_PCI_X_STATUS 0x064
+#define MV64460_PCI_COMPACT_PCI_HOT_SWAP 0x068
+
+/***********************************************/
+/* PCI Configuration, Function 1, Registers */
+/***********************************************/
+
+#define MV64460_PCI_SCS_2_BASE_ADDR_LOW 0x110
+#define MV64460_PCI_SCS_2_BASE_ADDR_HIGH 0x114
+#define MV64460_PCI_SCS_3_BASE_ADDR_LOW 0x118
+#define MV64460_PCI_SCS_3_BASE_ADDR_HIGH 0x11c
+#define MV64460_PCI_INTERNAL_SRAM_BASE_ADDR_LOW 0x120
+#define MV64460_PCI_INTERNAL_SRAM_BASE_ADDR_HIGH 0x124
+
+/***********************************************/
+/* PCI Configuration, Function 2, Registers */
+/***********************************************/
+
+#define MV64460_PCI_DEVCS_0_BASE_ADDR_LOW 0x210
+#define MV64460_PCI_DEVCS_0_BASE_ADDR_HIGH 0x214
+#define MV64460_PCI_DEVCS_1_BASE_ADDR_LOW 0x218
+#define MV64460_PCI_DEVCS_1_BASE_ADDR_HIGH 0x21c
+#define MV64460_PCI_DEVCS_2_BASE_ADDR_LOW 0x220
+#define MV64460_PCI_DEVCS_2_BASE_ADDR_HIGH 0x224
+
+/***********************************************/
+/* PCI Configuration, Function 3, Registers */
+/***********************************************/
+
+#define MV64460_PCI_DEVCS_3_BASE_ADDR_LOW 0x310
+#define MV64460_PCI_DEVCS_3_BASE_ADDR_HIGH 0x314
+#define MV64460_PCI_BOOT_CS_BASE_ADDR_LOW 0x318
+#define MV64460_PCI_BOOT_CS_BASE_ADDR_HIGH 0x31c
+#define MV64460_PCI_CPU_BASE_ADDR_LOW 0x220
+#define MV64460_PCI_CPU_BASE_ADDR_HIGH 0x224
+
+/***********************************************/
+/* PCI Configuration, Function 4, Registers */
+/***********************************************/
+
+#define MV64460_PCI_P2P_MEM0_BASE_ADDR_LOW 0x410
+#define MV64460_PCI_P2P_MEM0_BASE_ADDR_HIGH 0x414
+#define MV64460_PCI_P2P_MEM1_BASE_ADDR_LOW 0x418
+#define MV64460_PCI_P2P_MEM1_BASE_ADDR_HIGH 0x41c
+#define MV64460_PCI_P2P_I_O_BASE_ADDR 0x420
+#define MV64460_PCI_INTERNAL_REGS_I_O_MAPPED_BASE_ADDR 0x424
+
+/****************************************/
+/* Messaging Unit Registers (I20) */
+/****************************************/
+
+#define MV64460_I2O_INBOUND_MESSAGE_REG0_PCI_0_SIDE 0x010
+#define MV64460_I2O_INBOUND_MESSAGE_REG1_PCI_0_SIDE 0x014
+#define MV64460_I2O_OUTBOUND_MESSAGE_REG0_PCI_0_SIDE 0x018
+#define MV64460_I2O_OUTBOUND_MESSAGE_REG1_PCI_0_SIDE 0x01C
+#define MV64460_I2O_INBOUND_DOORBELL_REG_PCI_0_SIDE 0x020
+#define MV64460_I2O_INBOUND_INTERRUPT_CAUSE_REG_PCI_0_SIDE 0x024
+#define MV64460_I2O_INBOUND_INTERRUPT_MASK_REG_PCI_0_SIDE 0x028
+#define MV64460_I2O_OUTBOUND_DOORBELL_REG_PCI_0_SIDE 0x02C
+#define MV64460_I2O_OUTBOUND_INTERRUPT_CAUSE_REG_PCI_0_SIDE 0x030
+#define MV64460_I2O_OUTBOUND_INTERRUPT_MASK_REG_PCI_0_SIDE 0x034
+#define MV64460_I2O_INBOUND_QUEUE_PORT_VIRTUAL_REG_PCI_0_SIDE 0x040
+#define MV64460_I2O_OUTBOUND_QUEUE_PORT_VIRTUAL_REG_PCI_0_SIDE 0x044
+#define MV64460_I2O_QUEUE_CONTROL_REG_PCI_0_SIDE 0x050
+#define MV64460_I2O_QUEUE_BASE_ADDR_REG_PCI_0_SIDE 0x054
+#define MV64460_I2O_INBOUND_FREE_HEAD_POINTER_REG_PCI_0_SIDE 0x060
+#define MV64460_I2O_INBOUND_FREE_TAIL_POINTER_REG_PCI_0_SIDE 0x064
+#define MV64460_I2O_INBOUND_POST_HEAD_POINTER_REG_PCI_0_SIDE 0x068
+#define MV64460_I2O_INBOUND_POST_TAIL_POINTER_REG_PCI_0_SIDE 0x06C
+#define MV64460_I2O_OUTBOUND_FREE_HEAD_POINTER_REG_PCI_0_SIDE 0x070
+#define MV64460_I2O_OUTBOUND_FREE_TAIL_POINTER_REG_PCI_0_SIDE 0x074
+#define MV64460_I2O_OUTBOUND_POST_HEAD_POINTER_REG_PCI_0_SIDE 0x0F8
+#define MV64460_I2O_OUTBOUND_POST_TAIL_POINTER_REG_PCI_0_SIDE 0x0FC
+
+#define MV64460_I2O_INBOUND_MESSAGE_REG0_PCI_1_SIDE 0x090
+#define MV64460_I2O_INBOUND_MESSAGE_REG1_PCI_1_SIDE 0x094
+#define MV64460_I2O_OUTBOUND_MESSAGE_REG0_PCI_1_SIDE 0x098
+#define MV64460_I2O_OUTBOUND_MESSAGE_REG1_PCI_1_SIDE 0x09C
+#define MV64460_I2O_INBOUND_DOORBELL_REG_PCI_1_SIDE 0x0A0
+#define MV64460_I2O_INBOUND_INTERRUPT_CAUSE_REG_PCI_1_SIDE 0x0A4
+#define MV64460_I2O_INBOUND_INTERRUPT_MASK_REG_PCI_1_SIDE 0x0A8
+#define MV64460_I2O_OUTBOUND_DOORBELL_REG_PCI_1_SIDE 0x0AC
+#define MV64460_I2O_OUTBOUND_INTERRUPT_CAUSE_REG_PCI_1_SIDE 0x0B0
+#define MV64460_I2O_OUTBOUND_INTERRUPT_MASK_REG_PCI_1_SIDE 0x0B4
+#define MV64460_I2O_INBOUND_QUEUE_PORT_VIRTUAL_REG_PCI_1_SIDE 0x0C0
+#define MV64460_I2O_OUTBOUND_QUEUE_PORT_VIRTUAL_REG_PCI_1_SIDE 0x0C4
+#define MV64460_I2O_QUEUE_CONTROL_REG_PCI_1_SIDE 0x0D0
+#define MV64460_I2O_QUEUE_BASE_ADDR_REG_PCI_1_SIDE 0x0D4
+#define MV64460_I2O_INBOUND_FREE_HEAD_POINTER_REG_PCI_1_SIDE 0x0E0
+#define MV64460_I2O_INBOUND_FREE_TAIL_POINTER_REG_PCI_1_SIDE 0x0E4
+#define MV64460_I2O_INBOUND_POST_HEAD_POINTER_REG_PCI_1_SIDE 0x0E8
+#define MV64460_I2O_INBOUND_POST_TAIL_POINTER_REG_PCI_1_SIDE 0x0EC
+#define MV64460_I2O_OUTBOUND_FREE_HEAD_POINTER_REG_PCI_1_SIDE 0x0F0
+#define MV64460_I2O_OUTBOUND_FREE_TAIL_POINTER_REG_PCI_1_SIDE 0x0F4
+#define MV64460_I2O_OUTBOUND_POST_HEAD_POINTER_REG_PCI_1_SIDE 0x078
+#define MV64460_I2O_OUTBOUND_POST_TAIL_POINTER_REG_PCI_1_SIDE 0x07C
+
+#define MV64460_I2O_INBOUND_MESSAGE_REG0_CPU0_SIDE 0x1C10
+#define MV64460_I2O_INBOUND_MESSAGE_REG1_CPU0_SIDE 0x1C14
+#define MV64460_I2O_OUTBOUND_MESSAGE_REG0_CPU0_SIDE 0x1C18
+#define MV64460_I2O_OUTBOUND_MESSAGE_REG1_CPU0_SIDE 0x1C1C
+#define MV64460_I2O_INBOUND_DOORBELL_REG_CPU0_SIDE 0x1C20
+#define MV64460_I2O_INBOUND_INTERRUPT_CAUSE_REG_CPU0_SIDE 0x1C24
+#define MV64460_I2O_INBOUND_INTERRUPT_MASK_REG_CPU0_SIDE 0x1C28
+#define MV64460_I2O_OUTBOUND_DOORBELL_REG_CPU0_SIDE 0x1C2C
+#define MV64460_I2O_OUTBOUND_INTERRUPT_CAUSE_REG_CPU0_SIDE 0x1C30
+#define MV64460_I2O_OUTBOUND_INTERRUPT_MASK_REG_CPU0_SIDE 0x1C34
+#define MV64460_I2O_INBOUND_QUEUE_PORT_VIRTUAL_REG_CPU0_SIDE 0x1C40
+#define MV64460_I2O_OUTBOUND_QUEUE_PORT_VIRTUAL_REG_CPU0_SIDE 0x1C44
+#define MV64460_I2O_QUEUE_CONTROL_REG_CPU0_SIDE 0x1C50
+#define MV64460_I2O_QUEUE_BASE_ADDR_REG_CPU0_SIDE 0x1C54
+#define MV64460_I2O_INBOUND_FREE_HEAD_POINTER_REG_CPU0_SIDE 0x1C60
+#define MV64460_I2O_INBOUND_FREE_TAIL_POINTER_REG_CPU0_SIDE 0x1C64
+#define MV64460_I2O_INBOUND_POST_HEAD_POINTER_REG_CPU0_SIDE 0x1C68
+#define MV64460_I2O_INBOUND_POST_TAIL_POINTER_REG_CPU0_SIDE 0x1C6C
+#define MV64460_I2O_OUTBOUND_FREE_HEAD_POINTER_REG_CPU0_SIDE 0x1C70
+#define MV64460_I2O_OUTBOUND_FREE_TAIL_POINTER_REG_CPU0_SIDE 0x1C74
+#define MV64460_I2O_OUTBOUND_POST_HEAD_POINTER_REG_CPU0_SIDE 0x1CF8
+#define MV64460_I2O_OUTBOUND_POST_TAIL_POINTER_REG_CPU0_SIDE 0x1CFC
+#define MV64460_I2O_INBOUND_MESSAGE_REG0_CPU1_SIDE 0x1C90
+#define MV64460_I2O_INBOUND_MESSAGE_REG1_CPU1_SIDE 0x1C94
+#define MV64460_I2O_OUTBOUND_MESSAGE_REG0_CPU1_SIDE 0x1C98
+#define MV64460_I2O_OUTBOUND_MESSAGE_REG1_CPU1_SIDE 0x1C9C
+#define MV64460_I2O_INBOUND_DOORBELL_REG_CPU1_SIDE 0x1CA0
+#define MV64460_I2O_INBOUND_INTERRUPT_CAUSE_REG_CPU1_SIDE 0x1CA4
+#define MV64460_I2O_INBOUND_INTERRUPT_MASK_REG_CPU1_SIDE 0x1CA8
+#define MV64460_I2O_OUTBOUND_DOORBELL_REG_CPU1_SIDE 0x1CAC
+#define MV64460_I2O_OUTBOUND_INTERRUPT_CAUSE_REG_CPU1_SIDE 0x1CB0
+#define MV64460_I2O_OUTBOUND_INTERRUPT_MASK_REG_CPU1_SIDE 0x1CB4
+#define MV64460_I2O_INBOUND_QUEUE_PORT_VIRTUAL_REG_CPU1_SIDE 0x1CC0
+#define MV64460_I2O_OUTBOUND_QUEUE_PORT_VIRTUAL_REG_CPU1_SIDE 0x1CC4
+#define MV64460_I2O_QUEUE_CONTROL_REG_CPU1_SIDE 0x1CD0
+#define MV64460_I2O_QUEUE_BASE_ADDR_REG_CPU1_SIDE 0x1CD4
+#define MV64460_I2O_INBOUND_FREE_HEAD_POINTER_REG_CPU1_SIDE 0x1CE0
+#define MV64460_I2O_INBOUND_FREE_TAIL_POINTER_REG_CPU1_SIDE 0x1CE4
+#define MV64460_I2O_INBOUND_POST_HEAD_POINTER_REG_CPU1_SIDE 0x1CE8
+#define MV64460_I2O_INBOUND_POST_TAIL_POINTER_REG_CPU1_SIDE 0x1CEC
+#define MV64460_I2O_OUTBOUND_FREE_HEAD_POINTER_REG_CPU1_SIDE 0x1CF0
+#define MV64460_I2O_OUTBOUND_FREE_TAIL_POINTER_REG_CPU1_SIDE 0x1CF4
+#define MV64460_I2O_OUTBOUND_POST_HEAD_POINTER_REG_CPU1_SIDE 0x1C78
+#define MV64460_I2O_OUTBOUND_POST_TAIL_POINTER_REG_CPU1_SIDE 0x1C7C
+
+/****************************************/
+/* Ethernet Unit Registers */
+/****************************************/
+
+#define MV64460_ETH_PHY_ADDR_REG 0x2000
+#define MV64460_ETH_SMI_REG 0x2004
+#define MV64460_ETH_UNIT_DEFAULT_ADDR_REG 0x2008
+#define MV64460_ETH_UNIT_DEFAULTID_REG 0x200c
+#define MV64460_ETH_UNIT_INTERRUPT_CAUSE_REG 0x2080
+#define MV64460_ETH_UNIT_INTERRUPT_MASK_REG 0x2084
+#define MV64460_ETH_UNIT_INTERNAL_USE_REG 0x24fc
+#define MV64460_ETH_UNIT_ERROR_ADDR_REG 0x2094
+#define MV64460_ETH_BAR_0 0x2200
+#define MV64460_ETH_BAR_1 0x2208
+#define MV64460_ETH_BAR_2 0x2210
+#define MV64460_ETH_BAR_3 0x2218
+#define MV64460_ETH_BAR_4 0x2220
+#define MV64460_ETH_BAR_5 0x2228
+#define MV64460_ETH_SIZE_REG_0 0x2204
+#define MV64460_ETH_SIZE_REG_1 0x220c
+#define MV64460_ETH_SIZE_REG_2 0x2214
+#define MV64460_ETH_SIZE_REG_3 0x221c
+#define MV64460_ETH_SIZE_REG_4 0x2224
+#define MV64460_ETH_SIZE_REG_5 0x222c
+#define MV64460_ETH_HEADERS_RETARGET_BASE_REG 0x2230
+#define MV64460_ETH_HEADERS_RETARGET_CONTROL_REG 0x2234
+#define MV64460_ETH_HIGH_ADDR_REMAP_REG_0 0x2280
+#define MV64460_ETH_HIGH_ADDR_REMAP_REG_1 0x2284
+#define MV64460_ETH_HIGH_ADDR_REMAP_REG_2 0x2288
+#define MV64460_ETH_HIGH_ADDR_REMAP_REG_3 0x228c
+#define MV64460_ETH_BASE_ADDR_ENABLE_REG 0x2290
+#define MV64460_ETH_ACCESS_PROTECTION_REG(port) (0x2294 + (port<<2))
+#define MV64460_ETH_MIB_COUNTERS_BASE(port) (0x3000 + (port<<7))
+#define MV64460_ETH_PORT_CONFIG_REG(port) (0x2400 + (port<<10))
+#define MV64460_ETH_PORT_CONFIG_EXTEND_REG(port) (0x2404 + (port<<10))
+#define MV64460_ETH_MII_SERIAL_PARAMETRS_REG(port) (0x2408 + (port<<10))
+#define MV64460_ETH_GMII_SERIAL_PARAMETRS_REG(port) (0x240c + (port<<10))
+#define MV64460_ETH_VLAN_ETHERTYPE_REG(port) (0x2410 + (port<<10))
+#define MV64460_ETH_MAC_ADDR_LOW(port) (0x2414 + (port<<10))
+#define MV64460_ETH_MAC_ADDR_HIGH(port) (0x2418 + (port<<10))
+#define MV64460_ETH_SDMA_CONFIG_REG(port) (0x241c + (port<<10))
+#define MV64460_ETH_DSCP_0(port) (0x2420 + (port<<10))
+#define MV64460_ETH_DSCP_1(port) (0x2424 + (port<<10))
+#define MV64460_ETH_DSCP_2(port) (0x2428 + (port<<10))
+#define MV64460_ETH_DSCP_3(port) (0x242c + (port<<10))
+#define MV64460_ETH_DSCP_4(port) (0x2430 + (port<<10))
+#define MV64460_ETH_DSCP_5(port) (0x2434 + (port<<10))
+#define MV64460_ETH_DSCP_6(port) (0x2438 + (port<<10))
+#define MV64460_ETH_PORT_SERIAL_CONTROL_REG(port) (0x243c + (port<<10))
+#define MV64460_ETH_VLAN_PRIORITY_TAG_TO_PRIORITY(port) (0x2440 + (port<<10))
+#define MV64460_ETH_PORT_STATUS_REG(port) (0x2444 + (port<<10))
+#define MV64460_ETH_TRANSMIT_QUEUE_COMMAND_REG(port) (0x2448 + (port<<10))
+#define MV64460_ETH_TX_QUEUE_FIXED_PRIORITY(port) (0x244c + (port<<10))
+#define MV64460_ETH_PORT_TX_TOKEN_BUCKET_RATE_CONFIG(port) (0x2450 + (port<<10))
+#define MV64460_ETH_MAXIMUM_TRANSMIT_UNIT(port) (0x2458 + (port<<10))
+#define MV64460_ETH_PORT_MAXIMUM_TOKEN_BUCKET_SIZE(port) (0x245c + (port<<10))
+#define MV64460_ETH_INTERRUPT_CAUSE_REG(port) (0x2460 + (port<<10))
+#define MV64460_ETH_INTERRUPT_CAUSE_EXTEND_REG(port) (0x2464 + (port<<10))
+#define MV64460_ETH_INTERRUPT_MASK_REG(port) (0x2468 + (port<<10))
+#define MV64460_ETH_INTERRUPT_EXTEND_MASK_REG(port) (0x246c + (port<<10))
+#define MV64460_ETH_RX_FIFO_URGENT_THRESHOLD_REG(port) (0x2470 + (port<<10))
+#define MV64460_ETH_TX_FIFO_URGENT_THRESHOLD_REG(port) (0x2474 + (port<<10))
+#define MV64460_ETH_RX_MINIMAL_FRAME_SIZE_REG(port) (0x247c + (port<<10))
+#define MV64460_ETH_RX_DISCARDED_FRAMES_COUNTER(port) (0x2484 + (port<<10)
+#define MV64460_ETH_PORT_DEBUG_0_REG(port) (0x248c + (port<<10))
+#define MV64460_ETH_PORT_DEBUG_1_REG(port) (0x2490 + (port<<10))
+#define MV64460_ETH_PORT_INTERNAL_ADDR_ERROR_REG(port) (0x2494 + (port<<10))
+#define MV64460_ETH_INTERNAL_USE_REG(port) (0x24fc + (port<<10))
+#define MV64460_ETH_RECEIVE_QUEUE_COMMAND_REG(port) (0x2680 + (port<<10))
+#define MV64460_ETH_CURRENT_SERVED_TX_DESC_PTR(port) (0x2684 + (port<<10))
+#define MV64460_ETH_RX_CURRENT_QUEUE_DESC_PTR_0(port) (0x260c + (port<<10))
+#define MV64460_ETH_RX_CURRENT_QUEUE_DESC_PTR_1(port) (0x261c + (port<<10))
+#define MV64460_ETH_RX_CURRENT_QUEUE_DESC_PTR_2(port) (0x262c + (port<<10))
+#define MV64460_ETH_RX_CURRENT_QUEUE_DESC_PTR_3(port) (0x263c + (port<<10))
+#define MV64460_ETH_RX_CURRENT_QUEUE_DESC_PTR_4(port) (0x264c + (port<<10))
+#define MV64460_ETH_RX_CURRENT_QUEUE_DESC_PTR_5(port) (0x265c + (port<<10))
+#define MV64460_ETH_RX_CURRENT_QUEUE_DESC_PTR_6(port) (0x266c + (port<<10))
+#define MV64460_ETH_RX_CURRENT_QUEUE_DESC_PTR_7(port) (0x267c + (port<<10))
+#define MV64460_ETH_TX_CURRENT_QUEUE_DESC_PTR_0(port) (0x26c0 + (port<<10))
+#define MV64460_ETH_TX_CURRENT_QUEUE_DESC_PTR_1(port) (0x26c4 + (port<<10))
+#define MV64460_ETH_TX_CURRENT_QUEUE_DESC_PTR_2(port) (0x26c8 + (port<<10))
+#define MV64460_ETH_TX_CURRENT_QUEUE_DESC_PTR_3(port) (0x26cc + (port<<10))
+#define MV64460_ETH_TX_CURRENT_QUEUE_DESC_PTR_4(port) (0x26d0 + (port<<10))
+#define MV64460_ETH_TX_CURRENT_QUEUE_DESC_PTR_5(port) (0x26d4 + (port<<10))
+#define MV64460_ETH_TX_CURRENT_QUEUE_DESC_PTR_6(port) (0x26d8 + (port<<10))
+#define MV64460_ETH_TX_CURRENT_QUEUE_DESC_PTR_7(port) (0x26dc + (port<<10))
+#define MV64460_ETH_TX_QUEUE_0_TOKEN_BUCKET_COUNT(port) (0x2700 + (port<<10))
+#define MV64460_ETH_TX_QUEUE_1_TOKEN_BUCKET_COUNT(port) (0x2710 + (port<<10))
+#define MV64460_ETH_TX_QUEUE_2_TOKEN_BUCKET_COUNT(port) (0x2720 + (port<<10))
+#define MV64460_ETH_TX_QUEUE_3_TOKEN_BUCKET_COUNT(port) (0x2730 + (port<<10))
+#define MV64460_ETH_TX_QUEUE_4_TOKEN_BUCKET_COUNT(port) (0x2740 + (port<<10))
+#define MV64460_ETH_TX_QUEUE_5_TOKEN_BUCKET_COUNT(port) (0x2750 + (port<<10))
+#define MV64460_ETH_TX_QUEUE_6_TOKEN_BUCKET_COUNT(port) (0x2760 + (port<<10))
+#define MV64460_ETH_TX_QUEUE_7_TOKEN_BUCKET_COUNT(port) (0x2770 + (port<<10))
+#define MV64460_ETH_TX_QUEUE_0_TOKEN_BUCKET_CONFIG(port) (0x2704 + (port<<10))
+#define MV64460_ETH_TX_QUEUE_1_TOKEN_BUCKET_CONFIG(port) (0x2714 + (port<<10))
+#define MV64460_ETH_TX_QUEUE_2_TOKEN_BUCKET_CONFIG(port) (0x2724 + (port<<10))
+#define MV64460_ETH_TX_QUEUE_3_TOKEN_BUCKET_CONFIG(port) (0x2734 + (port<<10))
+#define MV64460_ETH_TX_QUEUE_4_TOKEN_BUCKET_CONFIG(port) (0x2744 + (port<<10))
+#define MV64460_ETH_TX_QUEUE_5_TOKEN_BUCKET_CONFIG(port) (0x2754 + (port<<10))
+#define MV64460_ETH_TX_QUEUE_6_TOKEN_BUCKET_CONFIG(port) (0x2764 + (port<<10))
+#define MV64460_ETH_TX_QUEUE_7_TOKEN_BUCKET_CONFIG(port) (0x2774 + (port<<10))
+#define MV64460_ETH_TX_QUEUE_0_ARBITER_CONFIG(port) (0x2708 + (port<<10))
+#define MV64460_ETH_TX_QUEUE_1_ARBITER_CONFIG(port) (0x2718 + (port<<10))
+#define MV64460_ETH_TX_QUEUE_2_ARBITER_CONFIG(port) (0x2728 + (port<<10))
+#define MV64460_ETH_TX_QUEUE_3_ARBITER_CONFIG(port) (0x2738 + (port<<10))
+#define MV64460_ETH_TX_QUEUE_4_ARBITER_CONFIG(port) (0x2748 + (port<<10))
+#define MV64460_ETH_TX_QUEUE_5_ARBITER_CONFIG(port) (0x2758 + (port<<10))
+#define MV64460_ETH_TX_QUEUE_6_ARBITER_CONFIG(port) (0x2768 + (port<<10))
+#define MV64460_ETH_TX_QUEUE_7_ARBITER_CONFIG(port) (0x2778 + (port<<10))
+#define MV64460_ETH_PORT_TX_TOKEN_BUCKET_COUNT(port) (0x2780 + (port<<10))
+#define MV64460_ETH_DA_FILTER_SPECIAL_MULTICAST_TABLE_BASE(port) (0x3400 + (port<<10))
+#define MV64460_ETH_DA_FILTER_OTHER_MULTICAST_TABLE_BASE(port) (0x3500 + (port<<10))
+#define MV64460_ETH_DA_FILTER_UNICAST_TABLE_BASE(port) (0x3600 + (port<<10))
+
+/*******************************************/
+/* CUNIT Registers */
+/*******************************************/
+
+ /* Address Decoding Register Map */
+
+#define MV64460_CUNIT_BASE_ADDR_REG0 0xf200
+#define MV64460_CUNIT_BASE_ADDR_REG1 0xf208
+#define MV64460_CUNIT_BASE_ADDR_REG2 0xf210
+#define MV64460_CUNIT_BASE_ADDR_REG3 0xf218
+#define MV64460_CUNIT_SIZE0 0xf204
+#define MV64460_CUNIT_SIZE1 0xf20c
+#define MV64460_CUNIT_SIZE2 0xf214
+#define MV64460_CUNIT_SIZE3 0xf21c
+#define MV64460_CUNIT_HIGH_ADDR_REMAP_REG0 0xf240
+#define MV64460_CUNIT_HIGH_ADDR_REMAP_REG1 0xf244
+#define MV64460_CUNIT_BASE_ADDR_ENABLE_REG 0xf250
+#define MV64460_MPSC0_ACCESS_PROTECTION_REG 0xf254
+#define MV64460_MPSC1_ACCESS_PROTECTION_REG 0xf258
+#define MV64460_CUNIT_INTERNAL_SPACE_BASE_ADDR_REG 0xf25C
+
+ /* Error Report Registers */
+
+#define MV64460_CUNIT_INTERRUPT_CAUSE_REG 0xf310
+#define MV64460_CUNIT_INTERRUPT_MASK_REG 0xf314
+#define MV64460_CUNIT_ERROR_ADDR 0xf318
+
+ /* Cunit Control Registers */
+
+#define MV64460_CUNIT_ARBITER_CONTROL_REG 0xf300
+#define MV64460_CUNIT_CONFIG_REG 0xb40c
+#define MV64460_CUNIT_CRROSBAR_TIMEOUT_REG 0xf304
+
+ /* Cunit Debug Registers */
+
+#define MV64460_CUNIT_DEBUG_LOW 0xf340
+#define MV64460_CUNIT_DEBUG_HIGH 0xf344
+#define MV64460_CUNIT_MMASK 0xf380
+
+ /* Cunit Base Address Enable Window Bits*/
+#define MV64460_CUNIT_BASE_ADDR_WIN_0_BIT 0x0
+#define MV64460_CUNIT_BASE_ADDR_WIN_1_BIT 0x1
+#define MV64460_CUNIT_BASE_ADDR_WIN_2_BIT 0x2
+#define MV64460_CUNIT_BASE_ADDR_WIN_3_BIT 0x3
+
+ /* MPSCs Clocks Routing Registers */
+
+#define MV64460_MPSC_ROUTING_REG 0xb400
+#define MV64460_MPSC_RX_CLOCK_ROUTING_REG 0xb404
+#define MV64460_MPSC_TX_CLOCK_ROUTING_REG 0xb408
+
+ /* MPSCs Interrupts Registers */
+
+#define MV64460_MPSC_CAUSE_REG(port) (0xb804 + (port<<3))
+#define MV64460_MPSC_MASK_REG(port) (0xb884 + (port<<3))
+
+#define MV64460_MPSC_MAIN_CONFIG_LOW(port) (0x8000 + (port<<12))
+#define MV64460_MPSC_MAIN_CONFIG_HIGH(port) (0x8004 + (port<<12))
+#define MV64460_MPSC_PROTOCOL_CONFIG(port) (0x8008 + (port<<12))
+#define MV64460_MPSC_CHANNEL_REG1(port) (0x800c + (port<<12))
+#define MV64460_MPSC_CHANNEL_REG2(port) (0x8010 + (port<<12))
+#define MV64460_MPSC_CHANNEL_REG3(port) (0x8014 + (port<<12))
+#define MV64460_MPSC_CHANNEL_REG4(port) (0x8018 + (port<<12))
+#define MV64460_MPSC_CHANNEL_REG5(port) (0x801c + (port<<12))
+#define MV64460_MPSC_CHANNEL_REG6(port) (0x8020 + (port<<12))
+#define MV64460_MPSC_CHANNEL_REG7(port) (0x8024 + (port<<12))
+#define MV64460_MPSC_CHANNEL_REG8(port) (0x8028 + (port<<12))
+#define MV64460_MPSC_CHANNEL_REG9(port) (0x802c + (port<<12))
+#define MV64460_MPSC_CHANNEL_REG10(port) (0x8030 + (port<<12))
+
+ /* MPSC0 Registers */
+
+
+/***************************************/
+/* SDMA Registers */
+/***************************************/
+
+#define MV64460_SDMA_CONFIG_REG(channel) (0x4000 + (channel<<13))
+#define MV64460_SDMA_COMMAND_REG(channel) (0x4008 + (channel<<13))
+#define MV64460_SDMA_CURRENT_RX_DESCRIPTOR_POINTER(channel) (0x4810 + (channel<<13))
+#define MV64460_SDMA_CURRENT_TX_DESCRIPTOR_POINTER(channel) (0x4c10 + (channel<<13))
+#define MV64460_SDMA_FIRST_TX_DESCRIPTOR_POINTER(channel) (0x4c14 + (channel<<13))
+
+#define MV64460_SDMA_CAUSE_REG 0xb800
+#define MV64460_SDMA_MASK_REG 0xb880
+
+
+/****************************************/
+/* SDMA Address Space Targets */
+/****************************************/
+
+#define MV64460_SDMA_DRAM_CS_0_TARGET 0x0e00
+#define MV64460_SDMA_DRAM_CS_1_TARGET 0x0d00
+#define MV64460_SDMA_DRAM_CS_2_TARGET 0x0b00
+#define MV64460_SDMA_DRAM_CS_3_TARGET 0x0700
+
+#define MV64460_SDMA_DEV_CS_0_TARGET 0x1e01
+#define MV64460_SDMA_DEV_CS_1_TARGET 0x1d01
+#define MV64460_SDMA_DEV_CS_2_TARGET 0x1b01
+#define MV64460_SDMA_DEV_CS_3_TARGET 0x1701
+
+#define MV64460_SDMA_BOOT_CS_TARGET 0x0f00
+
+#define MV64460_SDMA_SRAM_TARGET 0x0003
+#define MV64460_SDMA_60X_BUS_TARGET 0x4003
+
+#define MV64460_PCI_0_TARGET 0x0003
+#define MV64460_PCI_1_TARGET 0x0004
+
+
+/* Devices BAR and size registers */
+
+#define MV64460_DEV_CS0_BASE_ADDR 0x028
+#define MV64460_DEV_CS0_SIZE 0x030
+#define MV64460_DEV_CS1_BASE_ADDR 0x228
+#define MV64460_DEV_CS1_SIZE 0x230
+#define MV64460_DEV_CS2_BASE_ADDR 0x248
+#define MV64460_DEV_CS2_SIZE 0x250
+#define MV64460_DEV_CS3_BASE_ADDR 0x038
+#define MV64460_DEV_CS3_SIZE 0x040
+#define MV64460_BOOTCS_BASE_ADDR 0x238
+#define MV64460_BOOTCS_SIZE 0x240
+
+/* SDMA Window access protection */
+#define MV64460_SDMA_WIN_ACCESS_NOT_ALLOWED 0
+#define MV64460_SDMA_WIN_ACCESS_READ_ONLY 1
+#define MV64460_SDMA_WIN_ACCESS_FULL 2
+
+/* BRG Interrupts */
+
+#define MV64460_BRG_CONFIG_REG(brg) (0xb200 + (brg<<3))
+#define MV64460_BRG_BAUDE_TUNING_REG(brg) (0xb204 + (brg<<3))
+#define MV64460_BRG_CAUSE_REG 0xb834
+#define MV64460_BRG_MASK_REG 0xb8b4
+
+/****************************************/
+/* DMA Channel Control */
+/****************************************/
+
+#define MV64460_DMA_CHANNEL0_CONTROL 0x840
+#define MV64460_DMA_CHANNEL0_CONTROL_HIGH 0x880
+#define MV64460_DMA_CHANNEL1_CONTROL 0x844
+#define MV64460_DMA_CHANNEL1_CONTROL_HIGH 0x884
+#define MV64460_DMA_CHANNEL2_CONTROL 0x848
+#define MV64460_DMA_CHANNEL2_CONTROL_HIGH 0x888
+#define MV64460_DMA_CHANNEL3_CONTROL 0x84C
+#define MV64460_DMA_CHANNEL3_CONTROL_HIGH 0x88C
+
+
+/****************************************/
+/* IDMA Registers */
+/****************************************/
+
+#define MV64460_DMA_CHANNEL0_BYTE_COUNT 0x800
+#define MV64460_DMA_CHANNEL1_BYTE_COUNT 0x804
+#define MV64460_DMA_CHANNEL2_BYTE_COUNT 0x808
+#define MV64460_DMA_CHANNEL3_BYTE_COUNT 0x80C
+#define MV64460_DMA_CHANNEL0_SOURCE_ADDR 0x810
+#define MV64460_DMA_CHANNEL1_SOURCE_ADDR 0x814
+#define MV64460_DMA_CHANNEL2_SOURCE_ADDR 0x818
+#define MV64460_DMA_CHANNEL3_SOURCE_ADDR 0x81c
+#define MV64460_DMA_CHANNEL0_DESTINATION_ADDR 0x820
+#define MV64460_DMA_CHANNEL1_DESTINATION_ADDR 0x824
+#define MV64460_DMA_CHANNEL2_DESTINATION_ADDR 0x828
+#define MV64460_DMA_CHANNEL3_DESTINATION_ADDR 0x82C
+#define MV64460_DMA_CHANNEL0_NEXT_DESCRIPTOR_POINTER 0x830
+#define MV64460_DMA_CHANNEL1_NEXT_DESCRIPTOR_POINTER 0x834
+#define MV64460_DMA_CHANNEL2_NEXT_DESCRIPTOR_POINTER 0x838
+#define MV64460_DMA_CHANNEL3_NEXT_DESCRIPTOR_POINTER 0x83C
+#define MV64460_DMA_CHANNEL0_CURRENT_DESCRIPTOR_POINTER 0x870
+#define MV64460_DMA_CHANNEL1_CURRENT_DESCRIPTOR_POINTER 0x874
+#define MV64460_DMA_CHANNEL2_CURRENT_DESCRIPTOR_POINTER 0x878
+#define MV64460_DMA_CHANNEL3_CURRENT_DESCRIPTOR_POINTER 0x87C
+
+ /* IDMA Address Decoding Base Address Registers */
+
+#define MV64460_DMA_BASE_ADDR_REG0 0xa00
+#define MV64460_DMA_BASE_ADDR_REG1 0xa08
+#define MV64460_DMA_BASE_ADDR_REG2 0xa10
+#define MV64460_DMA_BASE_ADDR_REG3 0xa18
+#define MV64460_DMA_BASE_ADDR_REG4 0xa20
+#define MV64460_DMA_BASE_ADDR_REG5 0xa28
+#define MV64460_DMA_BASE_ADDR_REG6 0xa30
+#define MV64460_DMA_BASE_ADDR_REG7 0xa38
+
+ /* IDMA Address Decoding Size Address Register */
+
+#define MV64460_DMA_SIZE_REG0 0xa04
+#define MV64460_DMA_SIZE_REG1 0xa0c
+#define MV64460_DMA_SIZE_REG2 0xa14
+#define MV64460_DMA_SIZE_REG3 0xa1c
+#define MV64460_DMA_SIZE_REG4 0xa24
+#define MV64460_DMA_SIZE_REG5 0xa2c
+#define MV64460_DMA_SIZE_REG6 0xa34
+#define MV64460_DMA_SIZE_REG7 0xa3C
+
+ /* IDMA Address Decoding High Address Remap and Access
+ Protection Registers */
+
+#define MV64460_DMA_HIGH_ADDR_REMAP_REG0 0xa60
+#define MV64460_DMA_HIGH_ADDR_REMAP_REG1 0xa64
+#define MV64460_DMA_HIGH_ADDR_REMAP_REG2 0xa68
+#define MV64460_DMA_HIGH_ADDR_REMAP_REG3 0xa6C
+#define MV64460_DMA_BASE_ADDR_ENABLE_REG 0xa80
+#define MV64460_DMA_CHANNEL0_ACCESS_PROTECTION_REG 0xa70
+#define MV64460_DMA_CHANNEL1_ACCESS_PROTECTION_REG 0xa74
+#define MV64460_DMA_CHANNEL2_ACCESS_PROTECTION_REG 0xa78
+#define MV64460_DMA_CHANNEL3_ACCESS_PROTECTION_REG 0xa7c
+#define MV64460_DMA_ARBITER_CONTROL 0x860
+#define MV64460_DMA_CROSS_BAR_TIMEOUT 0x8d0
+
+ /* IDMA Headers Retarget Registers */
+
+#define MV64460_DMA_HEADERS_RETARGET_CONTROL 0xa84
+#define MV64460_DMA_HEADERS_RETARGET_BASE 0xa88
+
+ /* IDMA Interrupt Register */
+
+#define MV64460_DMA_INTERRUPT_CAUSE_REG 0x8c0
+#define MV64460_DMA_INTERRUPT_CAUSE_MASK 0x8c4
+#define MV64460_DMA_ERROR_ADDR 0x8c8
+#define MV64460_DMA_ERROR_SELECT 0x8cc
+
+ /* IDMA Debug Register ( for internal use ) */
+
+#define MV64460_DMA_DEBUG_LOW 0x8e0
+#define MV64460_DMA_DEBUG_HIGH 0x8e4
+#define MV64460_DMA_SPARE 0xA8C
+
+/****************************************/
+/* Timer_Counter */
+/****************************************/
+
+#define MV64460_TIMER_COUNTER0 0x850
+#define MV64460_TIMER_COUNTER1 0x854
+#define MV64460_TIMER_COUNTER2 0x858
+#define MV64460_TIMER_COUNTER3 0x85C
+#define MV64460_TIMER_COUNTER_0_3_CONTROL 0x864
+#define MV64460_TIMER_COUNTER_0_3_INTERRUPT_CAUSE 0x868
+#define MV64460_TIMER_COUNTER_0_3_INTERRUPT_MASK 0x86c
+
+/****************************************/
+/* Watchdog registers */
+/****************************************/
+
+#define MV64460_WATCHDOG_CONFIG_REG 0xb410
+#define MV64460_WATCHDOG_VALUE_REG 0xb414
+
+/****************************************/
+/* I2C Registers */
+/****************************************/
+
+#define MV64460_I2C_SLAVE_ADDR 0xc000
+#define MV64460_I2C_EXTENDED_SLAVE_ADDR 0xc010
+#define MV64460_I2C_DATA 0xc004
+#define MV64460_I2C_CONTROL 0xc008
+#define MV64460_I2C_STATUS_BAUDE_RATE 0xc00C
+#define MV64460_I2C_SOFT_RESET 0xc01c
+
+/****************************************/
+/* GPP Interface Registers */
+/****************************************/
+
+#define MV64460_GPP_IO_CONTROL 0xf100
+#define MV64460_GPP_LEVEL_CONTROL 0xf110
+#define MV64460_GPP_VALUE 0xf104
+#define MV64460_GPP_INTERRUPT_CAUSE 0xf108
+#define MV64460_GPP_INTERRUPT_MASK0 0xf10c
+#define MV64460_GPP_INTERRUPT_MASK1 0xf114
+#define MV64460_GPP_VALUE_SET 0xf118
+#define MV64460_GPP_VALUE_CLEAR 0xf11c
+
+/****************************************/
+/* Interrupt Controller Registers */
+/****************************************/
+
+/****************************************/
+/* Interrupts */
+/****************************************/
+
+#define MV64460_MAIN_INTERRUPT_CAUSE_LOW 0x004
+#define MV64460_MAIN_INTERRUPT_CAUSE_HIGH 0x00c
+#define MV64460_CPU_INTERRUPT0_MASK_LOW 0x014
+#define MV64460_CPU_INTERRUPT0_MASK_HIGH 0x01c
+#define MV64460_CPU_INTERRUPT0_SELECT_CAUSE 0x024
+#define MV64460_CPU_INTERRUPT1_MASK_LOW 0x034
+#define MV64460_CPU_INTERRUPT1_MASK_HIGH 0x03c
+#define MV64460_CPU_INTERRUPT1_SELECT_CAUSE 0x044
+#define MV64460_INTERRUPT0_MASK_0_LOW 0x054
+#define MV64460_INTERRUPT0_MASK_0_HIGH 0x05c
+#define MV64460_INTERRUPT0_SELECT_CAUSE 0x064
+#define MV64460_INTERRUPT1_MASK_0_LOW 0x074
+#define MV64460_INTERRUPT1_MASK_0_HIGH 0x07c
+#define MV64460_INTERRUPT1_SELECT_CAUSE 0x084
+
+/****************************************/
+/* MPP Interface Registers */
+/****************************************/
+
+#define MV64460_MPP_CONTROL0 0xf000
+#define MV64460_MPP_CONTROL1 0xf004
+#define MV64460_MPP_CONTROL2 0xf008
+#define MV64460_MPP_CONTROL3 0xf00c
+
+/****************************************/
+/* Serial Initialization registers */
+/****************************************/
+
+#define MV64460_SERIAL_INIT_LAST_DATA 0xf324
+#define MV64460_SERIAL_INIT_CONTROL 0xf328
+#define MV64460_SERIAL_INIT_STATUS 0xf32c
+
+
+#endif /* __INCgt64460rh */
diff --git a/board/prodrive/p3mx/p3mx.c b/board/prodrive/p3mx/p3mx.c
new file mode 100644
index 00000000000..d54ddaffc1e
--- /dev/null
+++ b/board/prodrive/p3mx/p3mx.c
@@ -0,0 +1,864 @@
+/*
+ * (C) Copyright 2006
+ * Stefan Roese, DENX Software Engineering, sr@denx.de.
+ *
+ * Based on original work by
+ * Roel Loeffen, (C) Copyright 2006 Prodrive B.V.
+ * Josh Huber, (C) Copyright 2001 Mission Critical Linux, Inc.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ * modifications for the DB64360 eval board based by Ingo.Assmus@keymile.com
+ * modifications for the cpci750 by reinhard.arlt@esd-electronics.com
+ * modifications for the P3M750 by roel.loeffen@prodrive.nl
+ */
+
+/*
+ * p3m750.c - main board support/init for the Prodrive p3m750/p3m7448.
+ */
+
+#include <common.h>
+#include <74xx_7xx.h>
+#include "../../Marvell/include/memory.h"
+#include "../../Marvell/include/pci.h"
+#include "../../Marvell/include/mv_gen_reg.h"
+#include <net.h>
+#include <i2c.h>
+
+#include "eth.h"
+#include "mpsc.h"
+#include "64460.h"
+#include "mv_regs.h"
+#include "p3mx.h"
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#undef DEBUG
+/*#define DEBUG */
+
+#ifdef CONFIG_PCI
+#define MAP_PCI
+#endif /* of CONFIG_PCI */
+
+#ifdef DEBUG
+#define DP(x) x
+#else
+#define DP(x)
+#endif
+
+extern void flush_data_cache (void);
+extern void invalidate_l1_instruction_cache (void);
+extern flash_info_t flash_info[];
+
+/* ------------------------------------------------------------------------- */
+
+/* this is the current GT register space location */
+/* it starts at CFG_DFL_GT_REGS but moves later to CFG_GT_REGS */
+
+/* Unfortunately, we cant change it while we are in flash, so we initialize it
+ * to the "final" value. This means that any debug_led calls before
+ * board_early_init_f wont work right (like in cpu_init_f).
+ * See also my_remap_gt_regs below. (NTL)
+ */
+
+void board_prebootm_init (void);
+unsigned int INTERNAL_REG_BASE_ADDR = CFG_GT_REGS;
+int display_mem_map (void);
+void set_led(int);
+
+/* ------------------------------------------------------------------------- */
+
+/*
+ * This is a version of the GT register space remapping function that
+ * doesn't touch globals (meaning, it's ok to run from flash.)
+ *
+ * Unfortunately, this has the side effect that a writable
+ * INTERNAL_REG_BASE_ADDR is impossible. Oh well.
+ */
+
+void my_remap_gt_regs (u32 cur_loc, u32 new_loc)
+{
+ u32 temp;
+
+ /* check and see if it's already moved */
+ temp = in_le32 ((u32 *) (new_loc + INTERNAL_SPACE_DECODE));
+ if ((temp & 0xffff) == new_loc >> 16)
+ return;
+
+ temp = (in_le32 ((u32 *) (cur_loc + INTERNAL_SPACE_DECODE)) &
+ 0xffff0000) | (new_loc >> 16);
+
+ out_le32 ((u32 *) (cur_loc + INTERNAL_SPACE_DECODE), temp);
+
+ while (GTREGREAD (INTERNAL_SPACE_DECODE) != temp);
+}
+
+#ifdef CONFIG_PCI
+
+static void gt_pci_config (void)
+{
+ unsigned int stat;
+ unsigned int val = 0x00fff864; /* DINK32: BusNum 23:16, DevNum 15:11, */
+ /* FuncNum 10:8, RegNum 7:2 */
+
+ /*
+ * In PCIX mode devices provide their own bus and device numbers.
+ * We query the Discovery II's
+ * config registers by writing ones to the bus and device.
+ * We then update the Virtual register with the correct value for the
+ * bus and device.
+ */
+ if ((GTREGREAD (PCI_0_MODE) & (BIT4 | BIT5)) != 0) { /* if PCI-X */
+ GT_REG_WRITE (PCI_0_CONFIG_ADDR, BIT31 | val);
+
+ GT_REG_READ (PCI_0_CONFIG_DATA_VIRTUAL_REG, &stat);
+
+ GT_REG_WRITE (PCI_0_CONFIG_ADDR, BIT31 | val);
+ GT_REG_WRITE (PCI_0_CONFIG_DATA_VIRTUAL_REG,
+ (stat & 0xffff0000) | CFG_PCI_IDSEL);
+
+ }
+ if ((GTREGREAD (PCI_1_MODE) & (BIT4 | BIT5)) != 0) { /* if PCI-X */
+ GT_REG_WRITE (PCI_1_CONFIG_ADDR, BIT31 | val);
+ GT_REG_READ (PCI_1_CONFIG_DATA_VIRTUAL_REG, &stat);
+
+ GT_REG_WRITE (PCI_1_CONFIG_ADDR, BIT31 | val);
+ GT_REG_WRITE (PCI_1_CONFIG_DATA_VIRTUAL_REG,
+ (stat & 0xffff0000) | CFG_PCI_IDSEL);
+ }
+
+ /* Enable master */
+ PCI_MASTER_ENABLE (0, SELF);
+ PCI_MASTER_ENABLE (1, SELF);
+
+ /* Enable PCI0/1 Mem0 and IO 0 disable all others */
+ GT_REG_READ (BASE_ADDR_ENABLE, &stat);
+ stat |= (1 << 11) | (1 << 12) | (1 << 13) | (1 << 16) | (1 << 17) |
+ (1 << 18);
+ stat &= ~((1 << 9) | (1 << 10) | (1 << 14) | (1 << 15));
+ GT_REG_WRITE (BASE_ADDR_ENABLE, stat);
+
+ /* ronen:
+ * add write to pci remap registers for 64460.
+ * in 64360 when writing to pci base go and overide remap automaticaly,
+ * in 64460 it doesn't
+ */
+ GT_REG_WRITE (PCI_0_IO_BASE_ADDR, CFG_PCI0_IO_SPACE >> 16);
+ GT_REG_WRITE (PCI_0I_O_ADDRESS_REMAP, CFG_PCI0_IO_SPACE_PCI >> 16);
+ GT_REG_WRITE (PCI_0_IO_SIZE, (CFG_PCI0_IO_SIZE - 1) >> 16);
+
+ GT_REG_WRITE (PCI_0_MEMORY0_BASE_ADDR, CFG_PCI0_MEM_BASE >> 16);
+ GT_REG_WRITE (PCI_0MEMORY0_ADDRESS_REMAP, CFG_PCI0_MEM_BASE >> 16);
+ GT_REG_WRITE (PCI_0_MEMORY0_SIZE, (CFG_PCI0_MEM_SIZE - 1) >> 16);
+
+ GT_REG_WRITE (PCI_1_IO_BASE_ADDR, CFG_PCI1_IO_SPACE >> 16);
+ GT_REG_WRITE (PCI_1I_O_ADDRESS_REMAP, CFG_PCI1_IO_SPACE_PCI >> 16);
+ GT_REG_WRITE (PCI_1_IO_SIZE, (CFG_PCI1_IO_SIZE - 1) >> 16);
+
+ GT_REG_WRITE (PCI_1_MEMORY0_BASE_ADDR, CFG_PCI1_MEM_BASE >> 16);
+ GT_REG_WRITE (PCI_1MEMORY0_ADDRESS_REMAP, CFG_PCI1_MEM_BASE >> 16);
+ GT_REG_WRITE (PCI_1_MEMORY0_SIZE, (CFG_PCI1_MEM_SIZE - 1) >> 16);
+
+ /* PCI interface settings */
+ /* Timeout set to retry forever */
+ GT_REG_WRITE (PCI_0TIMEOUT_RETRY, 0x0);
+ GT_REG_WRITE (PCI_1TIMEOUT_RETRY, 0x0);
+
+ /* ronen - enable only CS0 and Internal reg!! */
+ GT_REG_WRITE (PCI_0BASE_ADDRESS_REGISTERS_ENABLE, 0xfffffdfe);
+ GT_REG_WRITE (PCI_1BASE_ADDRESS_REGISTERS_ENABLE, 0xfffffdfe);
+
+ /* ronen:
+ * update the pci internal registers base address.
+ */
+#ifdef MAP_PCI
+ for (stat = 0; stat <= PCI_HOST1; stat++)
+ pciWriteConfigReg (stat,
+ PCI_INTERNAL_REGISTERS_MEMORY_MAPPED_BASE_ADDRESS,
+ SELF, CFG_GT_REGS);
+#endif
+
+}
+#endif
+
+/* Setup CPU interface paramaters */
+static void gt_cpu_config (void)
+{
+ cpu_t cpu = get_cpu_type ();
+ ulong tmp;
+
+ /* cpu configuration register */
+ tmp = GTREGREAD (CPU_CONFIGURATION);
+ /* set the SINGLE_CPU bit see MV64460 */
+#ifndef CFG_GT_DUAL_CPU /* SINGLE_CPU seems to cause JTAG problems */
+ tmp |= CPU_CONF_SINGLE_CPU;
+#endif
+ tmp &= ~CPU_CONF_AACK_DELAY_2;
+ tmp |= CPU_CONF_DP_VALID;
+ tmp |= CPU_CONF_AP_VALID;
+ tmp |= CPU_CONF_PIPELINE;
+ GT_REG_WRITE (CPU_CONFIGURATION, tmp); /* Marvell (VXWorks) writes 0x20220FF */
+
+ /* CPU master control register */
+ tmp = GTREGREAD (CPU_MASTER_CONTROL);
+ tmp |= CPU_MAST_CTL_ARB_EN;
+
+ if ((cpu == CPU_7400) ||
+ (cpu == CPU_7410) || (cpu == CPU_7455) || (cpu == CPU_7450)) {
+
+ tmp |= CPU_MAST_CTL_CLEAN_BLK;
+ tmp |= CPU_MAST_CTL_FLUSH_BLK;
+
+ } else {
+ /* cleanblock must be cleared for CPUs
+ * that do not support this command (603e, 750)
+ * see Res#1 */
+ tmp &= ~CPU_MAST_CTL_CLEAN_BLK;
+ tmp &= ~CPU_MAST_CTL_FLUSH_BLK;
+ }
+ GT_REG_WRITE (CPU_MASTER_CONTROL, tmp);
+}
+
+/*
+ * board_early_init_f.
+ *
+ * set up gal. device mappings, etc.
+ */
+int board_early_init_f (void)
+{
+ /* set up the GT the way the kernel wants it
+ * the call to move the GT register space will obviously
+ * fail if it has already been done, but we're going to assume
+ * that if it's not at the power-on location, it's where we put
+ * it last time. (huber)
+ */
+ my_remap_gt_regs (CFG_DFL_GT_REGS, CFG_GT_REGS);
+
+#ifdef CONFIG_PCI
+ gt_pci_config ();
+#endif
+ /* mask all external interrupt sources */
+ GT_REG_WRITE (CPU_INTERRUPT_MASK_REGISTER_LOW, 0);
+ GT_REG_WRITE (CPU_INTERRUPT_MASK_REGISTER_HIGH, 0);
+ /* new in >MV6436x */
+ GT_REG_WRITE (CPU_INTERRUPT_1_MASK_REGISTER_LOW, 0);
+ GT_REG_WRITE (CPU_INTERRUPT_1_MASK_REGISTER_HIGH, 0);
+ /* --------------------- */
+ GT_REG_WRITE (PCI_0INTERRUPT_CAUSE_MASK_REGISTER_LOW, 0);
+ GT_REG_WRITE (PCI_0INTERRUPT_CAUSE_MASK_REGISTER_HIGH, 0);
+ GT_REG_WRITE (PCI_1INTERRUPT_CAUSE_MASK_REGISTER_LOW, 0);
+ GT_REG_WRITE (PCI_1INTERRUPT_CAUSE_MASK_REGISTER_HIGH, 0);
+
+ /* Device and Boot bus settings
+ */
+ memoryMapDeviceSpace(DEVICE0, 0, 0);
+ GT_REG_WRITE(DEVICE_BANK0PARAMETERS, 0);
+ memoryMapDeviceSpace(DEVICE1, 0, 0);
+ GT_REG_WRITE(DEVICE_BANK1PARAMETERS, 0);
+ memoryMapDeviceSpace(DEVICE2, 0, 0);
+ GT_REG_WRITE(DEVICE_BANK2PARAMETERS, 0);
+ memoryMapDeviceSpace(DEVICE3, 0, 0);
+ GT_REG_WRITE(DEVICE_BANK3PARAMETERS, 0);
+
+ GT_REG_WRITE(DEVICE_BOOT_BANK_PARAMETERS, CFG_BOOT_PAR);
+
+ gt_cpu_config();
+
+ /* MPP setup */
+ GT_REG_WRITE (MPP_CONTROL0, CFG_MPP_CONTROL_0);
+ GT_REG_WRITE (MPP_CONTROL1, CFG_MPP_CONTROL_1);
+ GT_REG_WRITE (MPP_CONTROL2, CFG_MPP_CONTROL_2);
+ GT_REG_WRITE (MPP_CONTROL3, CFG_MPP_CONTROL_3);
+
+ GT_REG_WRITE (GPP_LEVEL_CONTROL, CFG_GPP_LEVEL_CONTROL);
+
+ set_led(LED_RED);
+
+ return 0;
+}
+
+/* various things to do after relocation */
+
+int misc_init_r ()
+{
+ u8 val;
+
+ icache_enable ();
+#ifdef CFG_L2
+ l2cache_enable ();
+#endif
+#ifdef CONFIG_MPSC
+ mpsc_sdma_init ();
+ mpsc_init2 ();
+#endif
+
+ /*
+ * Enable trickle changing in RTC upon powerup
+ * No diode, 250 ohm series resistor
+ */
+ val = 0xa5;
+ i2c_write(CFG_I2C_RTC_ADDR, 8, 1, &val, 1);
+
+ return 0;
+}
+
+int board_early_init_r(void)
+{
+ /* now relocate the debug serial driver */
+ mpsc_putchar += gd->reloc_off;
+ mpsc_getchar += gd->reloc_off;
+ mpsc_test_char += gd->reloc_off;
+
+ return 0;
+}
+
+void after_reloc (ulong dest_addr, gd_t * gd)
+{
+ memoryMapDeviceSpace (BOOT_DEVICE, CFG_BOOT_SPACE, CFG_BOOT_SIZE);
+
+/* display_mem_map(); */
+
+ /* now, jump to the main U-Boot board init code */
+ set_led(LED_GREEN);
+ board_init_r (gd, dest_addr);
+ /* NOTREACHED */
+}
+
+/*
+ * Check Board Identity:
+ * right now, assume borad type. (there is just one...after all)
+ */
+
+int checkboard (void)
+{
+ char *s = getenv("serial#");
+
+ printf("Board: %s", CFG_BOARD_NAME);
+
+ if (s != NULL) {
+ puts(", serial# ");
+ puts(s);
+ }
+ putc('\n');
+
+ return (0);
+}
+
+void set_led(int col)
+{
+ int tmp;
+ int on_pin;
+ int off_pin;
+
+ /* Program Mpp[22] as Gpp[22]
+ * Program Mpp[23] as Gpp[23]
+ */
+ tmp = GTREGREAD(MPP_CONTROL2);
+ tmp &= 0x00ffffff;
+ GT_REG_WRITE(MPP_CONTROL2,tmp);
+
+ /* Program Gpp[22] and Gpp[23] as output
+ */
+ tmp = GTREGREAD(GPP_IO_CONTROL);
+ tmp |= 0x00C00000;
+ GT_REG_WRITE(GPP_IO_CONTROL, tmp);
+
+ /* Program Gpp[22] and Gpp[23] as active high
+ */
+ tmp = GTREGREAD(GPP_LEVEL_CONTROL);
+ tmp &= 0xff3fffff;
+ GT_REG_WRITE(GPP_LEVEL_CONTROL, tmp);
+
+ switch(col) {
+ default:
+ case LED_OFF :
+ on_pin = 0;
+ off_pin = ((1 << 23) | (1 << 22));
+ break;
+ case LED_RED :
+ on_pin = (1 << 23);
+ off_pin = (1 << 22);
+ break;
+ case LED_GREEN :
+ on_pin = (1 << 22);
+ off_pin = (1 << 23);
+ break;
+ case LED_ORANGE :
+ on_pin = ((1 << 23) | (1 << 22));
+ off_pin = 0;
+ break;
+ }
+
+ /* Set output Gpp[22] and Gpp[23]
+ */
+ tmp = GTREGREAD(GPP_VALUE);
+ tmp |= on_pin;
+ tmp &= ~off_pin;
+ GT_REG_WRITE(GPP_VALUE, tmp);
+}
+
+int display_mem_map (void)
+{
+ int i;
+ unsigned int base, size, width;
+#ifdef CONFIG_PCI
+ int j;
+#endif
+
+ /* SDRAM */
+ printf ("SD (DDR) RAM\n");
+ for (i = 0; i <= BANK3; i++) {
+ base = memoryGetBankBaseAddress (i);
+ size = memoryGetBankSize (i);
+ if (size != 0)
+ printf ("BANK%d: base - 0x%08x\tsize - %dM bytes\n",
+ i, base, size >> 20);
+ }
+#ifdef CONFIG_PCI
+ /* CPU's PCI windows */
+ for (i = 0; i <= PCI_HOST1; i++) {
+ printf ("\nCPU's PCI %d windows\n", i);
+ base = pciGetSpaceBase (i, PCI_IO);
+ size = pciGetSpaceSize (i, PCI_IO);
+ printf (" IO: base - 0x%08x\tsize - %dM bytes\n", base,
+ size >> 20);
+ /* ronen currently only first PCI MEM is used 3 */
+ for (j = 0; j <= PCI_REGION0; j++) {
+ base = pciGetSpaceBase (i, j);
+ size = pciGetSpaceSize (i, j);
+ printf ("MEMORY %d: base - 0x%08x\tsize - %dM bytes\n",
+ j, base, size >> 20);
+ }
+ }
+#endif /* of CONFIG_PCI */
+
+ /* Bootrom */
+ base = memoryGetDeviceBaseAddress (BOOT_DEVICE); /* Boot */
+ size = memoryGetDeviceSize (BOOT_DEVICE);
+ width = memoryGetDeviceWidth (BOOT_DEVICE) * 8;
+ printf (" BOOT: base - 0x%08x size - %dM bytes\twidth - %d bits\t- FLASH\n",
+ base, size >> 20, width);
+
+ return (0);
+}
+
+/* DRAM check routines copied from gw8260 */
+
+#if defined (CFG_DRAM_TEST)
+
+/*********************************************************************/
+/* NAME: move64() - moves a double word (64-bit) */
+/* */
+/* DESCRIPTION: */
+/* this function performs a double word move from the data at */
+/* the source pointer to the location at the destination pointer. */
+/* */
+/* INPUTS: */
+/* unsigned long long *src - pointer to data to move */
+/* */
+/* OUTPUTS: */
+/* unsigned long long *dest - pointer to locate to move data */
+/* */
+/* RETURNS: */
+/* None */
+/* */
+/* RESTRICTIONS/LIMITATIONS: */
+/* May cloober fr0. */
+/* */
+/*********************************************************************/
+static void move64 (unsigned long long *src, unsigned long long *dest)
+{
+ asm ("lfd 0, 0(3)\n\t" /* fpr0 = *scr */
+ "stfd 0, 0(4)" /* *dest = fpr0 */
+ : : : "fr0"); /* Clobbers fr0 */
+ return;
+}
+
+
+#if defined (CFG_DRAM_TEST_DATA)
+
+unsigned long long pattern[] = {
+ 0xaaaaaaaaaaaaaaaaULL,
+ 0xccccccccccccccccULL,
+ 0xf0f0f0f0f0f0f0f0ULL,
+ 0xff00ff00ff00ff00ULL,
+ 0xffff0000ffff0000ULL,
+ 0xffffffff00000000ULL,
+ 0x00000000ffffffffULL,
+ 0x0000ffff0000ffffULL,
+ 0x00ff00ff00ff00ffULL,
+ 0x0f0f0f0f0f0f0f0fULL,
+ 0x3333333333333333ULL,
+ 0x5555555555555555ULL
+};
+
+/*********************************************************************/
+/* NAME: mem_test_data() - test data lines for shorts and opens */
+/* */
+/* DESCRIPTION: */
+/* Tests data lines for shorts and opens by forcing adjacent data */
+/* to opposite states. Because the data lines could be routed in */
+/* an arbitrary manner the must ensure test patterns ensure that */
+/* every case is tested. By using the following series of binary */
+/* patterns every combination of adjacent bits is test regardless */
+/* of routing. */
+/* */
+/* ...101010101010101010101010 */
+/* ...110011001100110011001100 */
+/* ...111100001111000011110000 */
+/* ...111111110000000011111111 */
+/* */
+/* Carrying this out, gives us six hex patterns as follows: */
+/* */
+/* 0xaaaaaaaaaaaaaaaa */
+/* 0xcccccccccccccccc */
+/* 0xf0f0f0f0f0f0f0f0 */
+/* 0xff00ff00ff00ff00 */
+/* 0xffff0000ffff0000 */
+/* 0xffffffff00000000 */
+/* */
+/* The number test patterns will always be given by: */
+/* */
+/* log(base 2)(number data bits) = log2 (64) = 6 */
+/* */
+/* To test for short and opens to other signals on our boards. we */
+/* simply */
+/* test with the 1's complemnt of the paterns as well. */
+/* */
+/* OUTPUTS: */
+/* Displays failing test pattern */
+/* */
+/* RETURNS: */
+/* 0 - Passed test */
+/* 1 - Failed test */
+/* */
+/* RESTRICTIONS/LIMITATIONS: */
+/* Assumes only one one SDRAM bank */
+/* */
+/*********************************************************************/
+int mem_test_data (void)
+{
+ unsigned long long *pmem = (unsigned long long *) CFG_MEMTEST_START;
+ unsigned long long temp64 = 0;
+ int num_patterns = sizeof (pattern) / sizeof (pattern[0]);
+ int i;
+ unsigned int hi, lo;
+
+ for (i = 0; i < num_patterns; i++) {
+ move64 (&(pattern[i]), pmem);
+ move64 (pmem, &temp64);
+
+ /* hi = (temp64>>32) & 0xffffffff; */
+ /* lo = temp64 & 0xffffffff; */
+ /* printf("\ntemp64 = 0x%08x%08x", hi, lo); */
+
+ hi = (pattern[i] >> 32) & 0xffffffff;
+ lo = pattern[i] & 0xffffffff;
+ /* printf("\npattern[%d] = 0x%08x%08x", i, hi, lo); */
+
+ if (temp64 != pattern[i]) {
+ printf ("\n Data Test Failed, pattern 0x%08x%08x",
+ hi, lo);
+ return 1;
+ }
+ }
+
+ return 0;
+}
+#endif /* CFG_DRAM_TEST_DATA */
+
+#if defined (CFG_DRAM_TEST_ADDRESS)
+/*********************************************************************/
+/* NAME: mem_test_address() - test address lines */
+/* */
+/* DESCRIPTION: */
+/* This function performs a test to verify that each word im */
+/* memory is uniquly addressable. The test sequence is as follows: */
+/* */
+/* 1) write the address of each word to each word. */
+/* 2) verify that each location equals its address */
+/* */
+/* OUTPUTS: */
+/* Displays failing test pattern and address */
+/* */
+/* RETURNS: */
+/* 0 - Passed test */
+/* 1 - Failed test */
+/* */
+/* RESTRICTIONS/LIMITATIONS: */
+/* */
+/* */
+/*********************************************************************/
+int mem_test_address (void)
+{
+ volatile unsigned int *pmem =
+ (volatile unsigned int *) CFG_MEMTEST_START;
+ const unsigned int size = (CFG_MEMTEST_END - CFG_MEMTEST_START) / 4;
+ unsigned int i;
+
+ /* write address to each location */
+ for (i = 0; i < size; i++)
+ pmem[i] = i;
+
+ /* verify each loaction */
+ for (i = 0; i < size; i++) {
+ if (pmem[i] != i) {
+ printf ("\n Address Test Failed at 0x%x", i);
+ return 1;
+ }
+ }
+ return 0;
+}
+#endif /* CFG_DRAM_TEST_ADDRESS */
+
+#if defined (CFG_DRAM_TEST_WALK)
+/*********************************************************************/
+/* NAME: mem_march() - memory march */
+/* */
+/* DESCRIPTION: */
+/* Marches up through memory. At each location verifies rmask if */
+/* read = 1. At each location write wmask if write = 1. Displays */
+/* failing address and pattern. */
+/* */
+/* INPUTS: */
+/* volatile unsigned long long * base - start address of test */
+/* unsigned int size - number of dwords(64-bit) to test */
+/* unsigned long long rmask - read verify mask */
+/* unsigned long long wmask - wrtie verify mask */
+/* short read - verifies rmask if read = 1 */
+/* short write - writes wmask if write = 1 */
+/* */
+/* OUTPUTS: */
+/* Displays failing test pattern and address */
+/* */
+/* RETURNS: */
+/* 0 - Passed test */
+/* 1 - Failed test */
+/* */
+/* RESTRICTIONS/LIMITATIONS: */
+/* */
+/* */
+/*********************************************************************/
+int mem_march (volatile unsigned long long *base,
+ unsigned int size,
+ unsigned long long rmask,
+ unsigned long long wmask, short read, short write)
+{
+ unsigned int i;
+ unsigned long long temp = 0;
+ unsigned int hitemp, lotemp, himask, lomask;
+
+ for (i = 0; i < size; i++) {
+ if (read != 0) {
+ /* temp = base[i]; */
+ move64 ((unsigned long long *) &(base[i]), &temp);
+ if (rmask != temp) {
+ hitemp = (temp >> 32) & 0xffffffff;
+ lotemp = temp & 0xffffffff;
+ himask = (rmask >> 32) & 0xffffffff;
+ lomask = rmask & 0xffffffff;
+
+ printf ("\n Walking one's test failed: address = 0x%08x," "\n\texpected 0x%08x%08x, found 0x%08x%08x", i << 3, himask, lomask, hitemp, lotemp);
+ return 1;
+ }
+ }
+ if (write != 0) {
+ /* base[i] = wmask; */
+ move64 (&wmask, (unsigned long long *) &(base[i]));
+ }
+ }
+ return 0;
+}
+#endif /* CFG_DRAM_TEST_WALK */
+
+/*********************************************************************/
+/* NAME: mem_test_walk() - a simple walking ones test */
+/* */
+/* DESCRIPTION: */
+/* Performs a walking ones through entire physical memory. The */
+/* test uses as series of memory marches, mem_march(), to verify */
+/* and write the test patterns to memory. The test sequence is as */
+/* follows: */
+/* 1) march writing 0000...0001 */
+/* 2) march verifying 0000...0001 , writing 0000...0010 */
+/* 3) repeat step 2 shifting masks left 1 bit each time unitl */
+/* the write mask equals 1000...0000 */
+/* 4) march verifying 1000...0000 */
+/* The test fails if any of the memory marches return a failure. */
+/* */
+/* OUTPUTS: */
+/* Displays which pass on the memory test is executing */
+/* */
+/* RETURNS: */
+/* 0 - Passed test */
+/* 1 - Failed test */
+/* */
+/* RESTRICTIONS/LIMITATIONS: */
+/* */
+/* */
+/*********************************************************************/
+int mem_test_walk (void)
+{
+ unsigned long long mask;
+ volatile unsigned long long *pmem =
+ (volatile unsigned long long *) CFG_MEMTEST_START;
+ const unsigned long size = (CFG_MEMTEST_END - CFG_MEMTEST_START) / 8;
+
+ unsigned int i;
+
+ mask = 0x01;
+
+ printf ("Initial Pass");
+ mem_march (pmem, size, 0x0, 0x1, 0, 1);
+
+ printf ("\b\b\b\b\b\b\b\b\b\b\b\b");
+ printf (" ");
+ printf (" ");
+ printf ("\b\b\b\b\b\b\b\b\b\b\b\b");
+
+ for (i = 0; i < 63; i++) {
+ printf ("Pass %2d", i + 2);
+ if (mem_march (pmem, size, mask, mask << 1, 1, 1) != 0) {
+ /*printf("mask: 0x%x, pass: %d, ", mask, i); */
+ return 1;
+ }
+ mask = mask << 1;
+ printf ("\b\b\b\b\b\b\b");
+ }
+
+ printf ("Last Pass");
+ if (mem_march (pmem, size, 0, mask, 0, 1) != 0) {
+ /* printf("mask: 0x%x", mask); */
+ return 1;
+ }
+ printf ("\b\b\b\b\b\b\b\b\b");
+ printf (" ");
+ printf ("\b\b\b\b\b\b\b\b\b");
+
+ return 0;
+}
+
+/*********************************************************************/
+/* NAME: testdram() - calls any enabled memory tests */
+/* */
+/* DESCRIPTION: */
+/* Runs memory tests if the environment test variables are set to */
+/* 'y'. */
+/* */
+/* INPUTS: */
+/* testdramdata - If set to 'y', data test is run. */
+/* testdramaddress - If set to 'y', address test is run. */
+/* testdramwalk - If set to 'y', walking ones test is run */
+/* */
+/* OUTPUTS: */
+/* None */
+/* */
+/* RETURNS: */
+/* 0 - Passed test */
+/* 1 - Failed test */
+/* */
+/* RESTRICTIONS/LIMITATIONS: */
+/* */
+/* */
+/*********************************************************************/
+int testdram (void)
+{
+ char *s;
+ int rundata = 0;
+ int runaddress = 0;
+ int runwalk = 0;
+
+#ifdef CFG_DRAM_TEST_DATA
+ s = getenv ("testdramdata");
+ rundata = (s && (*s == 'y')) ? 1 : 0;
+#endif
+#ifdef CFG_DRAM_TEST_ADDRESS
+ s = getenv ("testdramaddress");
+ runaddress = (s && (*s == 'y')) ? 1 : 0;
+#endif
+#ifdef CFG_DRAM_TEST_WALK
+ s = getenv ("testdramwalk");
+ runwalk = (s && (*s == 'y')) ? 1 : 0;
+#endif
+
+ if ((rundata == 1) || (runaddress == 1) || (runwalk == 1))
+ printf ("Testing RAM from 0x%08x to 0x%08x ... "
+ "(don't panic... that will take a moment !!!!)\n",
+ CFG_MEMTEST_START, CFG_MEMTEST_END);
+#ifdef CFG_DRAM_TEST_DATA
+ if (rundata == 1) {
+ printf ("Test DATA ... ");
+ if (mem_test_data () == 1) {
+ printf ("failed \n");
+ return 1;
+ } else
+ printf ("ok \n");
+ }
+#endif
+#ifdef CFG_DRAM_TEST_ADDRESS
+ if (runaddress == 1) {
+ printf ("Test ADDRESS ... ");
+ if (mem_test_address () == 1) {
+ printf ("failed \n");
+ return 1;
+ } else
+ printf ("ok \n");
+ }
+#endif
+#ifdef CFG_DRAM_TEST_WALK
+ if (runwalk == 1) {
+ printf ("Test WALKING ONEs ... ");
+ if (mem_test_walk () == 1) {
+ printf ("failed \n");
+ return 1;
+ } else
+ printf ("ok \n");
+ }
+#endif
+ if ((rundata == 1) || (runaddress == 1) || (runwalk == 1))
+ printf ("passed\n");
+ return 0;
+
+}
+#endif /* CFG_DRAM_TEST */
+
+/* ronen - the below functions are used by the bootm function */
+/* - we map the base register to fbe00000 (same mapping as in the LSP) */
+/* - we turn off the RX gig dmas - to prevent the dma from overunning */
+/* the kernel data areas. */
+/* - we diable and invalidate the icache and dcache. */
+void my_remap_gt_regs_bootm (u32 cur_loc, u32 new_loc)
+{
+ u32 temp;
+
+ temp = in_le32 ((u32 *) (new_loc + INTERNAL_SPACE_DECODE));
+ if ((temp & 0xffff) == new_loc >> 16)
+ return;
+
+ temp = (in_le32 ((u32 *) (cur_loc + INTERNAL_SPACE_DECODE)) &
+ 0xffff0000) | (new_loc >> 16);
+
+ out_le32 ((u32 *) (cur_loc + INTERNAL_SPACE_DECODE), temp);
+
+ while ((WORD_SWAP (*((volatile unsigned int *) (NONE_CACHEABLE |
+ new_loc |
+ (INTERNAL_SPACE_DECODE)))))
+ != temp);
+
+}
diff --git a/board/prodrive/p3mx/p3mx.h b/board/prodrive/p3mx/p3mx.h
new file mode 100644
index 00000000000..1caae6b9c15
--- /dev/null
+++ b/board/prodrive/p3mx/p3mx.h
@@ -0,0 +1,33 @@
+/*
+ * (C) Copyright 2005
+ *
+ * Roel Loeffen, (C) Copyright 2006 Prodrive B.V. roel.loeffen@prodrive.nl
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef __P3MX_H__
+#define __P3MX_H__
+
+#define LED_OFF 1
+#define LED_GREEN 2
+#define LED_RED 3
+#define LED_ORANGE 4
+
+#endif /* __P3MX_H__ */
diff --git a/board/prodrive/p3mx/pci.c b/board/prodrive/p3mx/pci.c
new file mode 100644
index 00000000000..137739bede6
--- /dev/null
+++ b/board/prodrive/p3mx/pci.c
@@ -0,0 +1,1025 @@
+/*
+ * (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
+ *
+ */
+/* PCI.c - PCI functions */
+
+
+#include <common.h>
+#ifdef CONFIG_PCI
+#include <pci.h>
+
+#ifdef CONFIG_PCI_PNP
+void pciauto_config_init(struct pci_controller *hose);
+int pciauto_region_allocate(struct pci_region* res, unsigned int size, unsigned int *bar);
+#endif
+
+#include "../../Marvell/include/pci.h"
+
+#undef DEBUG
+#undef IDE_SET_NATIVE_MODE
+static unsigned int local_buses[] = { 0, 0 };
+
+static const unsigned char pci_irq_swizzle[2][PCI_MAX_DEVICES] = {
+ {0, 0, 0, 0, 0, 0, 0, 27, 27, [9 ... PCI_MAX_DEVICES - 1] = 0 },
+ {0, 0, 0, 0, 0, 0, 0, 29, 29, [9 ... PCI_MAX_DEVICES - 1] = 0 },
+};
+
+#ifdef CONFIG_USE_CPCIDVI
+typedef struct {
+ unsigned int base;
+ unsigned int init;
+} GT_CPCIDVI_ROM_T;
+
+static GT_CPCIDVI_ROM_T gt_cpcidvi_rom = {0, 0};
+#endif
+
+#ifdef DEBUG
+static const unsigned int pci_bus_list[] = { PCI_0_MODE, PCI_1_MODE };
+static void gt_pci_bus_mode_display (PCI_HOST host)
+{
+ unsigned int mode;
+
+
+ mode = (GTREGREAD (pci_bus_list[host]) & (BIT4 | BIT5)) >> 4;
+ switch (mode) {
+ case 0:
+ printf ("PCI %d bus mode: Conventional PCI\n", host);
+ break;
+ case 1:
+ printf ("PCI %d bus mode: 66 Mhz PCIX\n", host);
+ break;
+ case 2:
+ printf ("PCI %d bus mode: 100 Mhz PCIX\n", host);
+ break;
+ case 3:
+ printf ("PCI %d bus mode: 133 Mhz PCIX\n", host);
+ break;
+ default:
+ printf ("Unknown BUS %d\n", mode);
+ }
+}
+#endif
+
+static const unsigned int pci_p2p_configuration_reg[] = {
+ PCI_0P2P_CONFIGURATION, PCI_1P2P_CONFIGURATION
+};
+
+static const unsigned int pci_configuration_address[] = {
+ PCI_0CONFIGURATION_ADDRESS, PCI_1CONFIGURATION_ADDRESS
+};
+
+static const unsigned int pci_configuration_data[] = {
+ PCI_0CONFIGURATION_DATA_VIRTUAL_REGISTER,
+ PCI_1CONFIGURATION_DATA_VIRTUAL_REGISTER
+};
+
+static const unsigned int pci_error_cause_reg[] = {
+ PCI_0ERROR_CAUSE, PCI_1ERROR_CAUSE
+};
+
+static const unsigned int pci_arbiter_control[] = {
+ PCI_0ARBITER_CONTROL, PCI_1ARBITER_CONTROL
+};
+
+static const unsigned int pci_address_space_en[] = {
+ PCI_0_BASE_ADDR_REG_ENABLE, PCI_1_BASE_ADDR_REG_ENABLE
+};
+
+static const unsigned int pci_snoop_control_base_0_low[] = {
+ PCI_0SNOOP_CONTROL_BASE_0_LOW, PCI_1SNOOP_CONTROL_BASE_0_LOW
+};
+static const unsigned int pci_snoop_control_top_0[] = {
+ PCI_0SNOOP_CONTROL_TOP_0, PCI_1SNOOP_CONTROL_TOP_0
+};
+
+static const unsigned int pci_access_control_base_0_low[] = {
+ PCI_0ACCESS_CONTROL_BASE_0_LOW, PCI_1ACCESS_CONTROL_BASE_0_LOW
+};
+static const unsigned int pci_access_control_top_0[] = {
+ PCI_0ACCESS_CONTROL_TOP_0, PCI_1ACCESS_CONTROL_TOP_0
+};
+
+static const unsigned int pci_scs_bank_size[2][4] = {
+ {PCI_0SCS_0_BANK_SIZE, PCI_0SCS_1_BANK_SIZE,
+ PCI_0SCS_2_BANK_SIZE, PCI_0SCS_3_BANK_SIZE},
+ {PCI_1SCS_0_BANK_SIZE, PCI_1SCS_1_BANK_SIZE,
+ PCI_1SCS_2_BANK_SIZE, PCI_1SCS_3_BANK_SIZE}
+};
+
+static const unsigned int pci_p2p_configuration[] = {
+ PCI_0P2P_CONFIGURATION, PCI_1P2P_CONFIGURATION
+};
+
+
+/********************************************************************
+* pciWriteConfigReg - Write to a PCI configuration register
+* - Make sure the GT is configured as a master before writing
+* to another device on the PCI.
+* - The function takes care of Big/Little endian conversion.
+*
+*
+* Inputs: unsigned int regOffset: The register offset as it apears in the GT spec
+* (or any other PCI device spec)
+* pciDevNum: The device number needs to be addressed.
+*
+* Configuration Address 0xCF8:
+*
+* 31 30 24 23 16 15 11 10 8 7 2 0 <=bit Number
+* |congif|Reserved| Bus |Device|Function|Register|00|
+* |Enable| |Number|Number| Number | Number | | <=field Name
+*
+*********************************************************************/
+void pciWriteConfigReg (PCI_HOST host, unsigned int regOffset,
+ unsigned int pciDevNum, unsigned int data)
+{
+ volatile unsigned int DataForAddrReg;
+ unsigned int functionNum;
+ unsigned int busNum = 0;
+ unsigned int addr;
+
+ if (pciDevNum > 32) /* illegal device Number */
+ return;
+ if (pciDevNum == SELF) { /* configure our configuration space. */
+ pciDevNum =
+ (GTREGREAD (pci_p2p_configuration_reg[host]) >> 24) &
+ 0x1f;
+ busNum = GTREGREAD (pci_p2p_configuration_reg[host]) &
+ 0xff0000;
+ }
+ functionNum = regOffset & 0x00000700;
+ pciDevNum = pciDevNum << 11;
+ regOffset = regOffset & 0xfc;
+ DataForAddrReg =
+ (regOffset | pciDevNum | functionNum | busNum) | BIT31;
+ GT_REG_WRITE (pci_configuration_address[host], DataForAddrReg);
+ GT_REG_READ (pci_configuration_address[host], &addr);
+ if (addr != DataForAddrReg)
+ return;
+ GT_REG_WRITE (pci_configuration_data[host], data);
+}
+
+/********************************************************************
+* pciReadConfigReg - Read from a PCI0 configuration register
+* - Make sure the GT is configured as a master before reading
+* from another device on the PCI.
+* - The function takes care of Big/Little endian conversion.
+* INPUTS: regOffset: The register offset as it apears in the GT spec (or PCI
+* spec)
+* pciDevNum: The device number needs to be addressed.
+* RETURNS: data , if the data == 0xffffffff check the master abort bit in the
+* cause register to make sure the data is valid
+*
+* Configuration Address 0xCF8:
+*
+* 31 30 24 23 16 15 11 10 8 7 2 0 <=bit Number
+* |congif|Reserved| Bus |Device|Function|Register|00|
+* |Enable| |Number|Number| Number | Number | | <=field Name
+*
+*********************************************************************/
+unsigned int pciReadConfigReg (PCI_HOST host, unsigned int regOffset,
+ unsigned int pciDevNum)
+{
+ volatile unsigned int DataForAddrReg;
+ unsigned int data;
+ unsigned int functionNum;
+ unsigned int busNum = 0;
+
+ if (pciDevNum > 32) /* illegal device Number */
+ return 0xffffffff;
+ if (pciDevNum == SELF) { /* configure our configuration space. */
+ pciDevNum =
+ (GTREGREAD (pci_p2p_configuration_reg[host]) >> 24) &
+ 0x1f;
+ busNum = GTREGREAD (pci_p2p_configuration_reg[host]) &
+ 0xff0000;
+ }
+ functionNum = regOffset & 0x00000700;
+ pciDevNum = pciDevNum << 11;
+ regOffset = regOffset & 0xfc;
+ DataForAddrReg =
+ (regOffset | pciDevNum | functionNum | busNum) | BIT31;
+ GT_REG_WRITE (pci_configuration_address[host], DataForAddrReg);
+ GT_REG_READ (pci_configuration_address[host], &data);
+ if (data != DataForAddrReg)
+ return 0xffffffff;
+ GT_REG_READ (pci_configuration_data[host], &data);
+ return data;
+}
+
+/********************************************************************
+* pciOverBridgeWriteConfigReg - Write to a PCI configuration register where
+* the agent is placed on another Bus. For more
+* information read P2P in the PCI spec.
+*
+* Inputs: unsigned int regOffset - The register offset as it apears in the
+* GT spec (or any other PCI device spec).
+* unsigned int pciDevNum - The device number needs to be addressed.
+* unsigned int busNum - On which bus does the Target agent connect
+* to.
+* unsigned int data - data to be written.
+*
+* Configuration Address 0xCF8:
+*
+* 31 30 24 23 16 15 11 10 8 7 2 0 <=bit Number
+* |congif|Reserved| Bus |Device|Function|Register|01|
+* |Enable| |Number|Number| Number | Number | | <=field Name
+*
+* The configuration Address is configure as type-I (bits[1:0] = '01') due to
+* PCI spec referring to P2P.
+*
+*********************************************************************/
+void pciOverBridgeWriteConfigReg (PCI_HOST host,
+ unsigned int regOffset,
+ unsigned int pciDevNum,
+ unsigned int busNum, unsigned int data)
+{
+ unsigned int DataForReg;
+ unsigned int functionNum;
+
+ functionNum = regOffset & 0x00000700;
+ pciDevNum = pciDevNum << 11;
+ regOffset = regOffset & 0xff;
+ busNum = busNum << 16;
+ if (pciDevNum == SELF) { /* This board */
+ DataForReg = (regOffset | pciDevNum | functionNum) | BIT0;
+ } else {
+ DataForReg = (regOffset | pciDevNum | functionNum | busNum) |
+ BIT31 | BIT0;
+ }
+ GT_REG_WRITE (pci_configuration_address[host], DataForReg);
+ GT_REG_WRITE (pci_configuration_data[host], data);
+}
+
+
+/********************************************************************
+* pciOverBridgeReadConfigReg - Read from a PCIn configuration register where
+* the agent target locate on another PCI bus.
+* - Make sure the GT is configured as a master
+* before reading from another device on the PCI.
+* - The function takes care of Big/Little endian
+* conversion.
+* INPUTS: regOffset: The register offset as it apears in the GT spec (or PCI
+* spec). (configuration register offset.)
+* pciDevNum: The device number needs to be addressed.
+* busNum: the Bus number where the agent is place.
+* RETURNS: data , if the data == 0xffffffff check the master abort bit in the
+* cause register to make sure the data is valid
+*
+* Configuration Address 0xCF8:
+*
+* 31 30 24 23 16 15 11 10 8 7 2 0 <=bit Number
+* |congif|Reserved| Bus |Device|Function|Register|01|
+* |Enable| |Number|Number| Number | Number | | <=field Name
+*
+*********************************************************************/
+unsigned int pciOverBridgeReadConfigReg (PCI_HOST host,
+ unsigned int regOffset,
+ unsigned int pciDevNum,
+ unsigned int busNum)
+{
+ unsigned int DataForReg;
+ unsigned int data;
+ unsigned int functionNum;
+
+ functionNum = regOffset & 0x00000700;
+ pciDevNum = pciDevNum << 11;
+ regOffset = regOffset & 0xff;
+ busNum = busNum << 16;
+ if (pciDevNum == SELF) { /* This board */
+ DataForReg = (regOffset | pciDevNum | functionNum) | BIT31;
+ } else { /* agent on another bus */
+
+ DataForReg = (regOffset | pciDevNum | functionNum | busNum) |
+ BIT0 | BIT31;
+ }
+ GT_REG_WRITE (pci_configuration_address[host], DataForReg);
+ GT_REG_READ (pci_configuration_data[host], &data);
+ return data;
+}
+
+
+/********************************************************************
+* pciGetRegOffset - Gets the register offset for this region config.
+*
+* INPUT: Bus, Region - The bus and region we ask for its base address.
+* OUTPUT: N/A
+* RETURNS: PCI register base address
+*********************************************************************/
+static unsigned int pciGetRegOffset (PCI_HOST host, PCI_REGION region)
+{
+ switch (host) {
+ case PCI_HOST0:
+ switch (region) {
+ case PCI_IO:
+ return PCI_0I_O_LOW_DECODE_ADDRESS;
+ case PCI_REGION0:
+ return PCI_0MEMORY0_LOW_DECODE_ADDRESS;
+ case PCI_REGION1:
+ return PCI_0MEMORY1_LOW_DECODE_ADDRESS;
+ case PCI_REGION2:
+ return PCI_0MEMORY2_LOW_DECODE_ADDRESS;
+ case PCI_REGION3:
+ return PCI_0MEMORY3_LOW_DECODE_ADDRESS;
+ }
+ case PCI_HOST1:
+ switch (region) {
+ case PCI_IO:
+ return PCI_1I_O_LOW_DECODE_ADDRESS;
+ case PCI_REGION0:
+ return PCI_1MEMORY0_LOW_DECODE_ADDRESS;
+ case PCI_REGION1:
+ return PCI_1MEMORY1_LOW_DECODE_ADDRESS;
+ case PCI_REGION2:
+ return PCI_1MEMORY2_LOW_DECODE_ADDRESS;
+ case PCI_REGION3:
+ return PCI_1MEMORY3_LOW_DECODE_ADDRESS;
+ }
+ }
+ return PCI_0MEMORY0_LOW_DECODE_ADDRESS;
+}
+
+static unsigned int pciGetRemapOffset (PCI_HOST host, PCI_REGION region)
+{
+ switch (host) {
+ case PCI_HOST0:
+ switch (region) {
+ case PCI_IO:
+ return PCI_0I_O_ADDRESS_REMAP;
+ case PCI_REGION0:
+ return PCI_0MEMORY0_ADDRESS_REMAP;
+ case PCI_REGION1:
+ return PCI_0MEMORY1_ADDRESS_REMAP;
+ case PCI_REGION2:
+ return PCI_0MEMORY2_ADDRESS_REMAP;
+ case PCI_REGION3:
+ return PCI_0MEMORY3_ADDRESS_REMAP;
+ }
+ case PCI_HOST1:
+ switch (region) {
+ case PCI_IO:
+ return PCI_1I_O_ADDRESS_REMAP;
+ case PCI_REGION0:
+ return PCI_1MEMORY0_ADDRESS_REMAP;
+ case PCI_REGION1:
+ return PCI_1MEMORY1_ADDRESS_REMAP;
+ case PCI_REGION2:
+ return PCI_1MEMORY2_ADDRESS_REMAP;
+ case PCI_REGION3:
+ return PCI_1MEMORY3_ADDRESS_REMAP;
+ }
+ }
+ return PCI_0MEMORY0_ADDRESS_REMAP;
+}
+
+/********************************************************************
+* pciGetBaseAddress - Gets the base address of a PCI.
+* - If the PCI size is 0 then this base address has no meaning!!!
+*
+*
+* INPUT: Bus, Region - The bus and region we ask for its base address.
+* OUTPUT: N/A
+* RETURNS: PCI base address.
+*********************************************************************/
+unsigned int pciGetBaseAddress (PCI_HOST host, PCI_REGION region)
+{
+ unsigned int regBase;
+ unsigned int regEnd;
+ unsigned int regOffset = pciGetRegOffset (host, region);
+
+ GT_REG_READ (regOffset, &regBase);
+ GT_REG_READ (regOffset + 8, &regEnd);
+
+ if (regEnd <= regBase)
+ return 0xffffffff; /* ERROR !!! */
+
+ regBase = regBase << 16;
+ return regBase;
+}
+
+bool pciMapSpace (PCI_HOST host, PCI_REGION region, unsigned int remapBase,
+ unsigned int bankBase, unsigned int bankLength)
+{
+ unsigned int low = 0xfff;
+ unsigned int high = 0x0;
+ unsigned int regOffset = pciGetRegOffset (host, region);
+ unsigned int remapOffset = pciGetRemapOffset (host, region);
+
+ if (bankLength != 0) {
+ low = (bankBase >> 16) & 0xffff;
+ high = ((bankBase + bankLength) >> 16) - 1;
+ }
+
+ GT_REG_WRITE (regOffset, low | (1 << 24)); /* no swapping */
+ GT_REG_WRITE (regOffset + 8, high);
+
+ if (bankLength != 0) { /* must do AFTER writing maps */
+ GT_REG_WRITE (remapOffset, remapBase >> 16); /* sorry, 32 bits only.
+ dont support upper 32
+ in this driver */
+ }
+ return true;
+}
+
+unsigned int pciGetSpaceBase (PCI_HOST host, PCI_REGION region)
+{
+ unsigned int low;
+ unsigned int regOffset = pciGetRegOffset (host, region);
+
+ GT_REG_READ (regOffset, &low);
+ return (low & 0xffff) << 16;
+}
+
+unsigned int pciGetSpaceSize (PCI_HOST host, PCI_REGION region)
+{
+ unsigned int low, high;
+ unsigned int regOffset = pciGetRegOffset (host, region);
+
+ GT_REG_READ (regOffset, &low);
+ GT_REG_READ (regOffset + 8, &high);
+ return ((high & 0xffff) + 1) << 16;
+}
+
+
+/* ronen - 7/Dec/03*/
+/********************************************************************
+* gtPciDisable/EnableInternalBAR - This function enable/disable PCI BARS.
+* Inputs: one of the PCI BAR
+*********************************************************************/
+void gtPciEnableInternalBAR (PCI_HOST host, PCI_INTERNAL_BAR pciBAR)
+{
+ RESET_REG_BITS (pci_address_space_en[host], BIT0 << pciBAR);
+}
+
+void gtPciDisableInternalBAR (PCI_HOST host, PCI_INTERNAL_BAR pciBAR)
+{
+ SET_REG_BITS (pci_address_space_en[host], BIT0 << pciBAR);
+}
+
+/********************************************************************
+* pciMapMemoryBank - Maps PCI_host memory bank "bank" for the slave.
+*
+* Inputs: base and size of PCI SCS
+*********************************************************************/
+void pciMapMemoryBank (PCI_HOST host, MEMORY_BANK bank,
+ unsigned int pciDramBase, unsigned int pciDramSize)
+{
+ /*ronen different function for 3rd bank. */
+ unsigned int offset = (bank < 2) ? bank * 8 : 0x100 + (bank - 2) * 8;
+
+ pciDramBase = pciDramBase & 0xfffff000;
+ pciDramBase = pciDramBase | (pciReadConfigReg (host,
+ PCI_SCS_0_BASE_ADDRESS
+ + offset,
+ SELF) & 0x00000fff);
+ pciWriteConfigReg (host, PCI_SCS_0_BASE_ADDRESS + offset, SELF,
+ pciDramBase);
+ if (pciDramSize == 0)
+ pciDramSize++;
+ GT_REG_WRITE (pci_scs_bank_size[host][bank], pciDramSize - 1);
+ gtPciEnableInternalBAR (host, bank);
+}
+
+/********************************************************************
+* pciSetRegionFeatures - This function modifys one of the 8 regions with
+* feature bits given as an input.
+* - Be advised to check the spec before modifying them.
+* Inputs: PCI_PROTECT_REGION region - one of the eight regions.
+* unsigned int features - See file: pci.h there are defintion for those
+* region features.
+* unsigned int baseAddress - The region base Address.
+* unsigned int topAddress - The region top Address.
+* Returns: false if one of the parameters is erroneous true otherwise.
+*********************************************************************/
+bool pciSetRegionFeatures (PCI_HOST host, PCI_ACCESS_REGIONS region,
+ unsigned int features, unsigned int baseAddress,
+ unsigned int regionLength)
+{
+ unsigned int accessLow;
+ unsigned int accessHigh;
+ unsigned int accessTop = baseAddress + regionLength;
+
+ if (regionLength == 0) { /* close the region. */
+ pciDisableAccessRegion (host, region);
+ return true;
+ }
+ /* base Address is store is bits [11:0] */
+ accessLow = (baseAddress & 0xfff00000) >> 20;
+ /* All the features are update according to the defines in pci.h (to be on
+ the safe side we disable bits: [11:0] */
+ accessLow = accessLow | (features & 0xfffff000);
+ /* write to the Low Access Region register */
+ GT_REG_WRITE (pci_access_control_base_0_low[host] + 0x10 * region,
+ accessLow);
+
+ accessHigh = (accessTop & 0xfff00000) >> 20;
+
+ /* write to the High Access Region register */
+ GT_REG_WRITE (pci_access_control_top_0[host] + 0x10 * region,
+ accessHigh - 1);
+ return true;
+}
+
+/********************************************************************
+* pciDisableAccessRegion - Disable The given Region by writing MAX size
+* to its low Address and MIN size to its high Address.
+*
+* Inputs: PCI_ACCESS_REGIONS region - The region we to be Disabled.
+* Returns: N/A.
+*********************************************************************/
+void pciDisableAccessRegion (PCI_HOST host, PCI_ACCESS_REGIONS region)
+{
+ /* writing back the registers default values. */
+ GT_REG_WRITE (pci_access_control_base_0_low[host] + 0x10 * region,
+ 0x01001fff);
+ GT_REG_WRITE (pci_access_control_top_0[host] + 0x10 * region, 0);
+}
+
+/********************************************************************
+* pciArbiterEnable - Enables PCI-0`s Arbitration mechanism.
+*
+* Inputs: N/A
+* Returns: true.
+*********************************************************************/
+bool pciArbiterEnable (PCI_HOST host)
+{
+ unsigned int regData;
+
+ GT_REG_READ (pci_arbiter_control[host], &regData);
+ GT_REG_WRITE (pci_arbiter_control[host], regData | BIT31);
+ return true;
+}
+
+/********************************************************************
+* pciArbiterDisable - Disable PCI-0`s Arbitration mechanism.
+*
+* Inputs: N/A
+* Returns: true
+*********************************************************************/
+bool pciArbiterDisable (PCI_HOST host)
+{
+ unsigned int regData;
+
+ GT_REG_READ (pci_arbiter_control[host], &regData);
+ GT_REG_WRITE (pci_arbiter_control[host], regData & 0x7fffffff);
+ return true;
+}
+
+/********************************************************************
+* pciSetArbiterAgentsPriority - Priority setup for the PCI agents (Hi or Low)
+*
+* Inputs: PCI_AGENT_PRIO internalAgent - priotity for internal agent.
+* PCI_AGENT_PRIO externalAgent0 - priotity for external#0 agent.
+* PCI_AGENT_PRIO externalAgent1 - priotity for external#1 agent.
+* PCI_AGENT_PRIO externalAgent2 - priotity for external#2 agent.
+* PCI_AGENT_PRIO externalAgent3 - priotity for external#3 agent.
+* PCI_AGENT_PRIO externalAgent4 - priotity for external#4 agent.
+* PCI_AGENT_PRIO externalAgent5 - priotity for external#5 agent.
+* Returns: true
+*********************************************************************/
+bool pciSetArbiterAgentsPriority (PCI_HOST host, PCI_AGENT_PRIO internalAgent,
+ PCI_AGENT_PRIO externalAgent0,
+ PCI_AGENT_PRIO externalAgent1,
+ PCI_AGENT_PRIO externalAgent2,
+ PCI_AGENT_PRIO externalAgent3,
+ PCI_AGENT_PRIO externalAgent4,
+ PCI_AGENT_PRIO externalAgent5)
+{
+ unsigned int regData;
+ unsigned int writeData;
+
+ GT_REG_READ (pci_arbiter_control[host], &regData);
+ writeData = (internalAgent << 7) + (externalAgent0 << 8) +
+ (externalAgent1 << 9) + (externalAgent2 << 10) +
+ (externalAgent3 << 11) + (externalAgent4 << 12) +
+ (externalAgent5 << 13);
+ regData = (regData & 0xffffc07f) | writeData;
+ GT_REG_WRITE (pci_arbiter_control[host], regData & regData);
+ return true;
+}
+
+/********************************************************************
+* pciParkingDisable - Park on last option disable, with this function you can
+* disable the park on last mechanism for each agent.
+* disabling this option for all agents results parking
+* on the internal master.
+*
+* Inputs: PCI_AGENT_PARK internalAgent - parking Disable for internal agent.
+* PCI_AGENT_PARK externalAgent0 - parking Disable for external#0 agent.
+* PCI_AGENT_PARK externalAgent1 - parking Disable for external#1 agent.
+* PCI_AGENT_PARK externalAgent2 - parking Disable for external#2 agent.
+* PCI_AGENT_PARK externalAgent3 - parking Disable for external#3 agent.
+* PCI_AGENT_PARK externalAgent4 - parking Disable for external#4 agent.
+* PCI_AGENT_PARK externalAgent5 - parking Disable for external#5 agent.
+* Returns: true
+*********************************************************************/
+bool pciParkingDisable (PCI_HOST host, PCI_AGENT_PARK internalAgent,
+ PCI_AGENT_PARK externalAgent0,
+ PCI_AGENT_PARK externalAgent1,
+ PCI_AGENT_PARK externalAgent2,
+ PCI_AGENT_PARK externalAgent3,
+ PCI_AGENT_PARK externalAgent4,
+ PCI_AGENT_PARK externalAgent5)
+{
+ unsigned int regData;
+ unsigned int writeData;
+
+ GT_REG_READ (pci_arbiter_control[host], &regData);
+ writeData = (internalAgent << 14) + (externalAgent0 << 15) +
+ (externalAgent1 << 16) + (externalAgent2 << 17) +
+ (externalAgent3 << 18) + (externalAgent4 << 19) +
+ (externalAgent5 << 20);
+ regData = (regData & ~(0x7f << 14)) | writeData;
+ GT_REG_WRITE (pci_arbiter_control[host], regData);
+ return true;
+}
+
+/********************************************************************
+* pciEnableBrokenAgentDetection - A master is said to be broken if it fails to
+* respond to grant assertion within a window specified in
+* the input value: 'brokenValue'.
+*
+* Inputs: unsigned char brokenValue - A value which limits the Master to hold the
+* grant without asserting frame.
+* Returns: Error for illegal broken value otherwise true.
+*********************************************************************/
+bool pciEnableBrokenAgentDetection (PCI_HOST host, unsigned char brokenValue)
+{
+ unsigned int data;
+ unsigned int regData;
+
+ if (brokenValue > 0xf)
+ return false; /* brokenValue must be 4 bit */
+ data = brokenValue << 3;
+ GT_REG_READ (pci_arbiter_control[host], &regData);
+ regData = (regData & 0xffffff87) | data;
+ GT_REG_WRITE (pci_arbiter_control[host], regData | BIT1);
+ return true;
+}
+
+/********************************************************************
+* pciDisableBrokenAgentDetection - This function disable the Broken agent
+* Detection mechanism.
+* NOTE: This operation may cause a dead lock on the
+* pci0 arbitration.
+*
+* Inputs: N/A
+* Returns: true.
+*********************************************************************/
+bool pciDisableBrokenAgentDetection (PCI_HOST host)
+{
+ unsigned int regData;
+
+ GT_REG_READ (pci_arbiter_control[host], &regData);
+ regData = regData & 0xfffffffd;
+ GT_REG_WRITE (pci_arbiter_control[host], regData);
+ return true;
+}
+
+/********************************************************************
+* pciP2PConfig - This function set the PCI_n P2P configurate.
+* For more information on the P2P read PCI spec.
+*
+* Inputs: unsigned int SecondBusLow - Secondery PCI interface Bus Range Lower
+* Boundry.
+* unsigned int SecondBusHigh - Secondry PCI interface Bus Range upper
+* Boundry.
+* unsigned int busNum - The CPI bus number to which the PCI interface
+* is connected.
+* unsigned int devNum - The PCI interface's device number.
+*
+* Returns: true.
+*********************************************************************/
+bool pciP2PConfig (PCI_HOST host, unsigned int SecondBusLow,
+ unsigned int SecondBusHigh,
+ unsigned int busNum, unsigned int devNum)
+{
+ unsigned int regData;
+
+ regData = (SecondBusLow & 0xff) | ((SecondBusHigh & 0xff) << 8) |
+ ((busNum & 0xff) << 16) | ((devNum & 0x1f) << 24);
+ GT_REG_WRITE (pci_p2p_configuration[host], regData);
+ return true;
+}
+
+/********************************************************************
+* pciSetRegionSnoopMode - This function modifys one of the 4 regions which
+* supports Cache Coherency in the PCI_n interface.
+* Inputs: region - One of the four regions.
+* snoopType - There is four optional Types:
+* 1. No Snoop.
+* 2. Snoop to WT region.
+* 3. Snoop to WB region.
+* 4. Snoop & Invalidate to WB region.
+* baseAddress - Base Address of this region.
+* regionLength - Region length.
+* Returns: false if one of the parameters is wrong otherwise return true.
+*********************************************************************/
+bool pciSetRegionSnoopMode (PCI_HOST host, PCI_SNOOP_REGION region,
+ PCI_SNOOP_TYPE snoopType,
+ unsigned int baseAddress,
+ unsigned int regionLength)
+{
+ unsigned int snoopXbaseAddress;
+ unsigned int snoopXtopAddress;
+ unsigned int data;
+ unsigned int snoopHigh = baseAddress + regionLength;
+
+ if ((region > PCI_SNOOP_REGION3) || (snoopType > PCI_SNOOP_WB))
+ return false;
+ snoopXbaseAddress =
+ pci_snoop_control_base_0_low[host] + 0x10 * region;
+ snoopXtopAddress = pci_snoop_control_top_0[host] + 0x10 * region;
+ if (regionLength == 0) { /* closing the region */
+ GT_REG_WRITE (snoopXbaseAddress, 0x0000ffff);
+ GT_REG_WRITE (snoopXtopAddress, 0);
+ return true;
+ }
+ baseAddress = baseAddress & 0xfff00000; /* Granularity of 1MByte */
+ data = (baseAddress >> 20) | snoopType << 12;
+ GT_REG_WRITE (snoopXbaseAddress, data);
+ snoopHigh = (snoopHigh & 0xfff00000) >> 20;
+ GT_REG_WRITE (snoopXtopAddress, snoopHigh - 1);
+ return true;
+}
+
+static int gt_read_config_dword (struct pci_controller *hose,
+ pci_dev_t dev, int offset, u32 * value)
+{
+ int bus = PCI_BUS (dev);
+
+ if ((bus == local_buses[0]) || (bus == local_buses[1])) {
+ *value = pciReadConfigReg ((PCI_HOST) hose->cfg_addr, offset,
+ PCI_DEV (dev));
+ } else {
+ *value = pciOverBridgeReadConfigReg ((PCI_HOST) hose->
+ cfg_addr, offset,
+ PCI_DEV (dev), bus);
+ }
+
+ return 0;
+}
+
+static int gt_write_config_dword (struct pci_controller *hose,
+ pci_dev_t dev, int offset, u32 value)
+{
+ int bus = PCI_BUS (dev);
+
+ if ((bus == local_buses[0]) || (bus == local_buses[1])) {
+ pciWriteConfigReg ((PCI_HOST) hose->cfg_addr, offset,
+ PCI_DEV (dev), value);
+ } else {
+ pciOverBridgeWriteConfigReg ((PCI_HOST) hose->cfg_addr,
+ offset, PCI_DEV (dev), bus,
+ value);
+ }
+ return 0;
+}
+
+
+static void gt_setup_ide (struct pci_controller *hose,
+ pci_dev_t dev, struct pci_config_table *entry)
+{
+ static const int ide_bar[] = { 8, 4, 8, 4, 0, 0 };
+ u32 bar_response, bar_value;
+ int bar;
+
+ for (bar = 0; bar < 6; bar++) {
+ /*ronen different function for 3rd bank. */
+ unsigned int offset =
+ (bar < 2) ? bar * 8 : 0x100 + (bar - 2) * 8;
+
+ pci_hose_write_config_dword (hose, dev, PCI_BASE_ADDRESS_0 + offset,
+ 0x0);
+ pci_hose_read_config_dword (hose, dev, PCI_BASE_ADDRESS_0 + offset,
+ &bar_response);
+
+ pciauto_region_allocate (bar_response &
+ PCI_BASE_ADDRESS_SPACE_IO ? hose->
+ pci_io : hose->pci_mem, ide_bar[bar],
+ &bar_value);
+
+ pci_hose_write_config_dword (hose, dev, PCI_BASE_ADDRESS_0 + bar * 4,
+ bar_value);
+ }
+}
+
+#ifdef CONFIG_USE_CPCIDVI
+static void gt_setup_cpcidvi (struct pci_controller *hose,
+ pci_dev_t dev, struct pci_config_table *entry)
+{
+ u32 bar_value, pci_response;
+
+ pci_hose_read_config_dword (hose, dev, PCI_COMMAND, &pci_response);
+ pci_hose_write_config_dword (hose, dev, PCI_BASE_ADDRESS_0, 0xffffffff);
+ pci_hose_read_config_dword (hose, dev, PCI_BASE_ADDRESS_0, &pci_response);
+ pciauto_region_allocate (hose->pci_mem, 0x01000000, &bar_value);
+ pci_hose_write_config_dword (hose, dev, PCI_BASE_ADDRESS_0, (bar_value & 0xffffff00));
+ pci_hose_write_config_dword (hose, dev, PCI_ROM_ADDRESS, 0x0);
+ pciauto_region_allocate (hose->pci_mem, 0x40000, &bar_value);
+ pci_hose_write_config_dword (hose, dev, PCI_ROM_ADDRESS, (bar_value & 0xffffff00) | 0x01);
+ gt_cpcidvi_rom.base = bar_value & 0xffffff00;
+ gt_cpcidvi_rom.init = 1;
+}
+
+unsigned char gt_cpcidvi_in8(unsigned int offset)
+{
+ unsigned char data;
+
+ if (gt_cpcidvi_rom.init == 0) {
+ return(0);
+ }
+ data = in8((offset & 0x04) + 0x3f000 + gt_cpcidvi_rom.base);
+ return(data);
+}
+
+void gt_cpcidvi_out8(unsigned int offset, unsigned char data)
+{
+ unsigned int off;
+
+ if (gt_cpcidvi_rom.init == 0) {
+ return;
+ }
+ off = data;
+ off = ((off << 3) & 0x7f8) + (offset & 0x4) + 0x3e000 + gt_cpcidvi_rom.base;
+ in8(off);
+ return;
+}
+#endif
+
+/* TODO BJW: Change this for DB64360. This was pulled from the EV64260 */
+/* and is curently not called *. */
+#if 0
+static void gt_fixup_irq (struct pci_controller *hose, pci_dev_t dev)
+{
+ unsigned char pin, irq;
+
+ pci_read_config_byte (dev, PCI_INTERRUPT_PIN, &pin);
+
+ if (pin == 1) { /* only allow INT A */
+ irq = pci_irq_swizzle[(PCI_HOST) hose->
+ cfg_addr][PCI_DEV (dev)];
+ if (irq)
+ pci_write_config_byte (dev, PCI_INTERRUPT_LINE, irq);
+ }
+}
+#endif
+
+struct pci_config_table gt_config_table[] = {
+#ifdef CONFIG_USE_CPCIDVI
+ {PCI_VENDOR_ID_CT, PCI_DEVICE_ID_CT_69030, PCI_CLASS_DISPLAY_VGA,
+ PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, gt_setup_cpcidvi},
+#endif
+ {PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_STORAGE_IDE,
+ PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, gt_setup_ide},
+ {}
+};
+
+struct pci_controller pci0_hose = {
+/* fixup_irq: gt_fixup_irq, */
+ config_table:gt_config_table,
+};
+
+struct pci_controller pci1_hose = {
+/* fixup_irq: gt_fixup_irq, */
+ config_table:gt_config_table,
+};
+
+void pci_init_board (void)
+{
+ unsigned int command;
+#ifdef CONFIG_PCI_PNP
+ unsigned int bar;
+#endif
+#ifdef DEBUG
+ gt_pci_bus_mode_display (PCI_HOST0);
+#endif
+#ifdef CONFIG_USE_CPCIDVI
+ gt_cpcidvi_rom.init = 0;
+ gt_cpcidvi_rom.base = 0;
+#endif
+
+ pci0_hose.config_table = gt_config_table;
+ pci1_hose.config_table = gt_config_table;
+
+#ifdef CONFIG_USE_CPCIDVI
+ gt_config_table[0].config_device = gt_setup_cpcidvi;
+#endif
+ gt_config_table[1].config_device = gt_setup_ide;
+
+ pci0_hose.first_busno = 0;
+ pci0_hose.last_busno = 0xff;
+ local_buses[0] = pci0_hose.first_busno;
+
+ /* PCI memory space */
+ pci_set_region (pci0_hose.regions + 0,
+ CFG_PCI0_0_MEM_SPACE,
+ CFG_PCI0_0_MEM_SPACE,
+ CFG_PCI0_MEM_SIZE, PCI_REGION_MEM);
+
+ /* PCI I/O space */
+ pci_set_region (pci0_hose.regions + 1,
+ CFG_PCI0_IO_SPACE_PCI,
+ CFG_PCI0_IO_SPACE, CFG_PCI0_IO_SIZE, PCI_REGION_IO);
+
+ pci_set_ops (&pci0_hose,
+ pci_hose_read_config_byte_via_dword,
+ pci_hose_read_config_word_via_dword,
+ gt_read_config_dword,
+ pci_hose_write_config_byte_via_dword,
+ pci_hose_write_config_word_via_dword,
+ gt_write_config_dword);
+ pci0_hose.region_count = 2;
+
+ pci0_hose.cfg_addr = (unsigned int *) PCI_HOST0;
+
+ pci_register_hose (&pci0_hose);
+ pciArbiterDisable(PCI_HOST0); /* on PMC modules no arbiter is used */
+ pciParkingDisable (PCI_HOST0, 1, 1, 1, 1, 1, 1, 1);
+ command = pciReadConfigReg (PCI_HOST0, PCI_COMMAND, SELF);
+ command |= PCI_COMMAND_MASTER;
+ pciWriteConfigReg (PCI_HOST0, PCI_COMMAND, SELF, command);
+ command = pciReadConfigReg (PCI_HOST0, PCI_COMMAND, SELF);
+ command |= PCI_COMMAND_MEMORY;
+ pciWriteConfigReg (PCI_HOST0, PCI_COMMAND, SELF, command);
+
+#ifdef CONFIG_PCI_PNP
+ pciauto_config_init(&pci0_hose);
+ pciauto_region_allocate(pci0_hose.pci_io, 0x400, &bar);
+#endif
+#ifdef CONFIG_PCI_SCAN_SHOW
+ printf("PCI: Bus Dev VenId DevId Class Int\n");
+#endif
+ pci0_hose.last_busno = pci_hose_scan_bus (&pci0_hose, pci0_hose.first_busno);
+
+#ifdef DEBUG
+ gt_pci_bus_mode_display (PCI_HOST1);
+#endif
+ pci1_hose.first_busno = pci0_hose.last_busno + 1;
+ pci1_hose.last_busno = 0xff;
+ pci1_hose.current_busno = pci1_hose.first_busno;
+ local_buses[1] = pci1_hose.first_busno;
+
+ /* PCI memory space */
+ pci_set_region (pci1_hose.regions + 0,
+ CFG_PCI1_0_MEM_SPACE,
+ CFG_PCI1_0_MEM_SPACE,
+ CFG_PCI1_MEM_SIZE, PCI_REGION_MEM);
+
+ /* PCI I/O space */
+ pci_set_region (pci1_hose.regions + 1,
+ CFG_PCI1_IO_SPACE_PCI,
+ CFG_PCI1_IO_SPACE, CFG_PCI1_IO_SIZE, PCI_REGION_IO);
+
+ pci_set_ops (&pci1_hose,
+ pci_hose_read_config_byte_via_dword,
+ pci_hose_read_config_word_via_dword,
+ gt_read_config_dword,
+ pci_hose_write_config_byte_via_dword,
+ pci_hose_write_config_word_via_dword,
+ gt_write_config_dword);
+
+ pci1_hose.region_count = 2;
+
+ pci1_hose.cfg_addr = (unsigned int *) PCI_HOST1;
+
+ pci_register_hose (&pci1_hose);
+
+ pciArbiterEnable (PCI_HOST1);
+ pciParkingDisable (PCI_HOST1, 1, 1, 1, 1, 1, 1, 1);
+
+ command = pciReadConfigReg (PCI_HOST1, PCI_COMMAND, SELF);
+ command |= PCI_COMMAND_MASTER;
+ pciWriteConfigReg (PCI_HOST1, PCI_COMMAND, SELF, command);
+
+#ifdef CONFIG_PCI_PNP
+ pciauto_config_init(&pci1_hose);
+ pciauto_region_allocate(pci1_hose.pci_io, 0x400, &bar);
+#endif
+ pci1_hose.last_busno = pci_hose_scan_bus (&pci1_hose, pci1_hose.first_busno);
+
+ command = pciReadConfigReg (PCI_HOST1, PCI_COMMAND, SELF);
+ command |= PCI_COMMAND_MEMORY;
+ pciWriteConfigReg (PCI_HOST1, PCI_COMMAND, SELF, command);
+
+}
+#endif /* of CONFIG_PCI */
diff --git a/board/prodrive/p3mx/ppc_error_no.h b/board/prodrive/p3mx/ppc_error_no.h
new file mode 100644
index 00000000000..53687c86bb7
--- /dev/null
+++ b/board/prodrive/p3mx/ppc_error_no.h
@@ -0,0 +1,164 @@
+/*
+ * (C) Copyright 2003
+ * Ingo Assmus <ingo.assmus@keymile.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
+ */
+
+/*
+ * BK Id: SCCS/s.errno.h 1.9 06/05/01 21:45:21 paulus
+ */
+#ifndef _MV_PPC_ERRNO_H
+#define _MV_PPC_ERRNO_H
+
+#define EPERM 1 /* Operation not permitted */
+#define ENOENT 2 /* No such file or directory */
+#define ESRCH 3 /* No such process */
+#define EINTR 4 /* Interrupted system call */
+#define EIO 5 /* I/O error */
+#define ENXIO 6 /* No such device or address */
+#define E2BIG 7 /* Arg list too long */
+#define ENOEXEC 8 /* Exec format error */
+#define EBADF 9 /* Bad file number */
+#define ECHILD 10 /* No child processes */
+#define EAGAIN 11 /* Try again */
+#define ENOMEM 12 /* Out of memory */
+#define EACCES 13 /* Permission denied */
+#define EFAULT 14 /* Bad address */
+#define ENOTBLK 15 /* Block device required */
+#define EBUSY 16 /* Device or resource busy */
+#define EEXIST 17 /* File exists */
+#define EXDEV 18 /* Cross-device link */
+#define ENODEV 19 /* No such device */
+#define ENOTDIR 20 /* Not a directory */
+#define EISDIR 21 /* Is a directory */
+#define EINVAL 22 /* Invalid argument */
+#define ENFILE 23 /* File table overflow */
+#define EMFILE 24 /* Too many open files */
+#define ENOTTY 25 /* Not a typewriter */
+#define ETXTBSY 26 /* Text file busy */
+#define EFBIG 27 /* File too large */
+#define ENOSPC 28 /* No space left on device */
+#define ESPIPE 29 /* Illegal seek */
+#define EROFS 30 /* Read-only file system */
+#define EMLINK 31 /* Too many links */
+#define EPIPE 32 /* Broken pipe */
+#define EDOM 33 /* Math argument out of domain of func */
+#define ERANGE 34 /* Math result not representable */
+#define EDEADLK 35 /* Resource deadlock would occur */
+#define ENAMETOOLONG 36 /* File name too long */
+#define ENOLCK 37 /* No record locks available */
+#define ENOSYS 38 /* Function not implemented */
+#define ENOTEMPTY 39 /* Directory not empty */
+#define ELOOP 40 /* Too many symbolic links encountered */
+#define EWOULDBLOCK EAGAIN /* Operation would block */
+#define ENOMSG 42 /* No message of desired type */
+#define EIDRM 43 /* Identifier removed */
+#define ECHRNG 44 /* Channel number out of range */
+#define EL2NSYNC 45 /* Level 2 not synchronized */
+#define EL3HLT 46 /* Level 3 halted */
+#define EL3RST 47 /* Level 3 reset */
+#define ELNRNG 48 /* Link number out of range */
+#define EUNATCH 49 /* Protocol driver not attached */
+#define ENOCSI 50 /* No CSI structure available */
+#define EL2HLT 51 /* Level 2 halted */
+#define EBADE 52 /* Invalid exchange */
+#define EBADR 53 /* Invalid request descriptor */
+#define EXFULL 54 /* Exchange full */
+#define ENOANO 55 /* No anode */
+#define EBADRQC 56 /* Invalid request code */
+#define EBADSLT 57 /* Invalid slot */
+#define EDEADLOCK 58 /* File locking deadlock error */
+#define EBFONT 59 /* Bad font file format */
+#define ENOSTR 60 /* Device not a stream */
+#define ENODATA 61 /* No data available */
+#define ETIME 62 /* Timer expired */
+#define ENOSR 63 /* Out of streams resources */
+#define ENONET 64 /* Machine is not on the network */
+#define ENOPKG 65 /* Package not installed */
+#define EREMOTE 66 /* Object is remote */
+#define ENOLINK 67 /* Link has been severed */
+#define EADV 68 /* Advertise error */
+#define ESRMNT 69 /* Srmount error */
+#define ECOMM 70 /* Communication error on send */
+#define EPROTO 71 /* Protocol error */
+#define EMULTIHOP 72 /* Multihop attempted */
+#define EDOTDOT 73 /* RFS specific error */
+#define EBADMSG 74 /* Not a data message */
+#define EOVERFLOW 75 /* Value too large for defined data type */
+#define ENOTUNIQ 76 /* Name not unique on network */
+#define EBADFD 77 /* File descriptor in bad state */
+#define EREMCHG 78 /* Remote address changed */
+#define ELIBACC 79 /* Can not access a needed shared library */
+#define ELIBBAD 80 /* Accessing a corrupted shared library */
+#define ELIBSCN 81 /* .lib section in a.out corrupted */
+#define ELIBMAX 82 /* Attempting to link in too many shared libraries */
+#define ELIBEXEC 83 /* Cannot exec a shared library directly */
+#define EILSEQ 84 /* Illegal byte sequence */
+#define ERESTART 85 /* Interrupted system call should be restarted */
+#define ESTRPIPE 86 /* Streams pipe error */
+#define EUSERS 87 /* Too many users */
+#define ENOTSOCK 88 /* Socket operation on non-socket */
+#define EDESTADDRREQ 89 /* Destination address required */
+#define EMSGSIZE 90 /* Message too long */
+#define EPROTOTYPE 91 /* Protocol wrong type for socket */
+#define ENOPROTOOPT 92 /* Protocol not available */
+#define EPROTONOSUPPORT 93 /* Protocol not supported */
+#define ESOCKTNOSUPPORT 94 /* Socket type not supported */
+#define EOPNOTSUPP 95 /* Operation not supported on transport endpoint */
+#define EPFNOSUPPORT 96 /* Protocol family not supported */
+#define EAFNOSUPPORT 97 /* Address family not supported by protocol */
+#define EADDRINUSE 98 /* Address already in use */
+#define EADDRNOTAVAIL 99 /* Cannot assign requested address */
+#define ENETDOWN 100 /* Network is down */
+#define ENETUNREACH 101 /* Network is unreachable */
+#define ENETRESET 102 /* Network dropped connection because of reset */
+#define ECONNABORTED 103 /* Software caused connection abort */
+#define ECONNRESET 104 /* Connection reset by peer */
+#define ENOBUFS 105 /* No buffer space available */
+#define EISCONN 106 /* Transport endpoint is already connected */
+#define ENOTCONN 107 /* Transport endpoint is not connected */
+#define ESHUTDOWN 108 /* Cannot send after transport endpoint shutdown */
+#define ETOOMANYREFS 109 /* Too many references: cannot splice */
+#define ETIMEDOUT 110 /* Connection timed out */
+#define ECONNREFUSED 111 /* Connection refused */
+#define EHOSTDOWN 112 /* Host is down */
+#define EHOSTUNREACH 113 /* No route to host */
+#define EALREADY 114 /* Operation already in progress */
+#define EINPROGRESS 115 /* Operation now in progress */
+#define ESTALE 116 /* Stale NFS file handle */
+#define EUCLEAN 117 /* Structure needs cleaning */
+#define ENOTNAM 118 /* Not a XENIX named type file */
+#define ENAVAIL 119 /* No XENIX semaphores available */
+#define EISNAM 120 /* Is a named type file */
+#define EREMOTEIO 121 /* Remote I/O error */
+#define EDQUOT 122 /* Quota exceeded */
+
+#define ENOMEDIUM 123 /* No medium found */
+#define EMEDIUMTYPE 124 /* Wrong medium type */
+
+/* Should never be seen by user programs */
+#define ERESTARTSYS 512
+#define ERESTARTNOINTR 513
+#define ERESTARTNOHAND 514 /* restart if no handler.. */
+#define ENOIOCTLCMD 515 /* No ioctl command */
+
+#define _LAST_ERRNO 515
+
+#endif
diff --git a/board/prodrive/p3mx/sdram_init.c b/board/prodrive/p3mx/sdram_init.c
new file mode 100644
index 00000000000..0464860424e
--- /dev/null
+++ b/board/prodrive/p3mx/sdram_init.c
@@ -0,0 +1,434 @@
+/*
+ * (C) Copyright 2001
+ * Josh Huber <huber@mclx.com>, Mission Critical Linux, Inc.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/*************************************************************************
+ * adaption for the Marvell DB64460 Board
+ * Ingo Assmus (ingo.assmus@keymile.com)
+ *************************************************************************/
+
+/* sdram_init.c - automatic memory sizing */
+
+#include <common.h>
+#include <74xx_7xx.h>
+#include "../../Marvell/include/memory.h"
+#include "../../Marvell/include/pci.h"
+#include "../../Marvell/include/mv_gen_reg.h"
+#include <net.h>
+
+#include "eth.h"
+#include "mpsc.h"
+#include "../../Marvell/common/i2c.h"
+#include "64460.h"
+#include "mv_regs.h"
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#undef DEBUG
+#define MAP_PCI
+
+#ifdef DEBUG
+#define DP(x) x
+#else
+#define DP(x)
+#endif
+
+int set_dfcdlInit (void); /* setup delay line of Mv64460 */
+int mvDmaIsChannelActive (int);
+int mvDmaSetMemorySpace (ulong, ulong, ulong, ulong, ulong);
+int mvDmaTransfer (int, ulong, ulong, ulong, ulong);
+
+#define D_CACHE_FLUSH_LINE(addr, offset) \
+ { \
+ __asm__ __volatile__ ("dcbf %0,%1" : : "r" (addr), "r" (offset)); \
+ }
+
+int memory_map_bank (unsigned int bankNo,
+ unsigned int bankBase, unsigned int bankLength)
+{
+#if defined (MAP_PCI) && defined (CONFIG_PCI)
+ PCI_HOST host;
+#endif
+
+#ifdef DEBUG
+ if (bankLength > 0) {
+ printf ("mapping bank %d at %08x - %08x\n",
+ bankNo, bankBase, bankBase + bankLength - 1);
+ } else {
+ printf ("unmapping bank %d\n", bankNo);
+ }
+#endif
+
+ memoryMapBank (bankNo, bankBase, bankLength);
+
+#if defined (MAP_PCI) && defined (CONFIG_PCI)
+ for (host = PCI_HOST0; host <= PCI_HOST1; host++) {
+ const int features =
+ PREFETCH_ENABLE |
+ DELAYED_READ_ENABLE |
+ AGGRESSIVE_PREFETCH |
+ READ_LINE_AGGRESSIVE_PREFETCH |
+ READ_MULTI_AGGRESSIVE_PREFETCH |
+ MAX_BURST_4 | PCI_NO_SWAP;
+
+ pciMapMemoryBank (host, bankNo, bankBase, bankLength);
+
+ pciSetRegionSnoopMode (host, bankNo, PCI_SNOOP_WB, bankBase,
+ bankLength);
+
+ pciSetRegionFeatures (host, bankNo, features, bankBase,
+ bankLength);
+ }
+#endif
+
+ return 0;
+}
+
+/*
+ * Check memory range for valid RAM. A simple memory test determines
+ * the actually available RAM size between addresses `base' and
+ * `base + maxsize'. Some (not all) hardware errors are detected:
+ * - short between address lines
+ * - short between data lines
+ */
+long int dram_size (long int *base, long int maxsize)
+{
+ volatile long int *addr, *b = base;
+ long int cnt, val, save1, save2;
+
+#define STARTVAL (1<<20) /* start test at 1M */
+ for (cnt = STARTVAL / sizeof (long); cnt < maxsize / sizeof (long);
+ cnt <<= 1) {
+ addr = base + cnt; /* pointer arith! */
+
+ save1 = *addr; /* save contents of addr */
+ save2 = *b; /* save contents of base */
+
+ *addr = cnt; /* write cnt to addr */
+ *b = 0; /* put null at base */
+
+ /* check at base address */
+ if ((*b) != 0) {
+ *addr = save1; /* restore *addr */
+ *b = save2; /* restore *b */
+ return (0);
+ }
+ val = *addr; /* read *addr */
+ val = *addr; /* read *addr */
+
+ *addr = save1;
+ *b = save2;
+
+ if (val != cnt) {
+ DP (printf
+ ("Found %08x at Address %08x (failure)\n",
+ (unsigned int) val, (unsigned int) addr));
+ /* fix boundary condition.. STARTVAL means zero */
+ if (cnt == STARTVAL / sizeof (long))
+ cnt = 0;
+ return (cnt * sizeof (long));
+ }
+ }
+
+ return maxsize;
+}
+
+#define SDRAM_NORMAL 0x0
+#define SDRAM_PRECHARGE_ALL 0x1
+#define SDRAM_REFRESH_ALL 0x2
+#define SDRAM_MODE_REG_SETUP 0x3
+#define SDRAM_XTEN_MODE_REG_SETUP 0x4
+#define SDRAM_NOP 0x5
+#define SDRAM_SELF_REFRESH 0x7
+
+long int initdram (int board_type)
+{
+ int tmp;
+ int start;
+ ulong size;
+ ulong memSpaceAttr;
+ ulong dest;
+
+ /* first disable all banks */
+ memory_map_bank(0, 0, 0);
+ memory_map_bank(1, 0, 0);
+ memory_map_bank(2, 0, 0);
+ memory_map_bank(3, 0, 0);
+
+ /* calibrate delay lines */
+ set_dfcdlInit();
+
+ GT_REG_WRITE(MV64460_SDRAM_OPERATION, SDRAM_NOP); /* 0x1418 */
+ do {
+ tmp = GTREGREAD(MV64460_SDRAM_OPERATION);
+ } while(tmp != 0x0);
+
+ /* SDRAM controller configuration */
+#ifdef CONFIG_MV64460_ECC
+ GT_REG_WRITE(MV64460_SDRAM_CONFIG, 0x58201400); /* 0x1400 */
+#else
+ GT_REG_WRITE(MV64460_SDRAM_CONFIG, 0x58200400); /* 0x1400 */
+#endif
+ GT_REG_WRITE(MV64460_D_UNIT_CONTROL_LOW, 0xC3000540); /* 0x1404 */
+ GT_REG_WRITE(MV64460_D_UNIT_CONTROL_HIGH, 0x0300F777); /* 0x1424 */
+ GT_REG_WRITE(MV64460_SDRAM_TIMING_CONTROL_LOW, 0x01712220); /* 0x1408 */
+ GT_REG_WRITE(MV64460_SDRAM_TIMING_CONTROL_HIGH, 0x0000005D); /* 0x140C */
+ GT_REG_WRITE(MV64460_SDRAM_ADDR_CONTROL, 0x00000012); /* 0x1410 */
+ GT_REG_WRITE(MV64460_SDRAM_OPEN_PAGES_CONTROL, 0x00000001); /* 0x1414 */
+
+ /* SDRAM drive strength */
+ GT_REG_WRITE(MV64460_SDRAM_ADDR_CTRL_PADS_CALIBRATION, 0x80000000); /* 0x14C0 */
+ GT_REG_WRITE(MV64460_SDRAM_ADDR_CTRL_PADS_CALIBRATION, 0x80000008); /* 0x14C0 */
+ GT_REG_WRITE(MV64460_SDRAM_DATA_PADS_CALIBRATION, 0x80000000); /* 0x14C4 */
+ GT_REG_WRITE(MV64460_SDRAM_DATA_PADS_CALIBRATION, 0x80000008); /* 0x14C4 */
+
+ /* setup SDRAM device registers */
+
+ /* precharge all */
+ GT_REG_WRITE(MV64460_SDRAM_OPERATION, SDRAM_PRECHARGE_ALL); /* 0x1418 */
+ do {
+ tmp = GTREGREAD(MV64460_SDRAM_OPERATION);
+ } while(tmp != 0x0);
+
+ /* enable DLL */
+ GT_REG_WRITE(MV64460_EXTENDED_DRAM_MODE, 0x00000000); /* 0x1420 */
+ GT_REG_WRITE(MV64460_SDRAM_OPERATION, SDRAM_XTEN_MODE_REG_SETUP); /* 0x1418 */
+ do {
+ tmp = GTREGREAD(MV64460_SDRAM_OPERATION);
+ } while(tmp != 0x0);
+
+ /* reset DLL */
+ GT_REG_WRITE(MV64460_SDRAM_MODE, 0x00000132); /* 0x141C */
+ GT_REG_WRITE(MV64460_SDRAM_OPERATION, SDRAM_MODE_REG_SETUP); /* 0x1418 */
+ do {
+ tmp = GTREGREAD(MV64460_SDRAM_OPERATION);
+ } while(tmp != 0x0);
+
+ /* precharge all */
+ GT_REG_WRITE(MV64460_SDRAM_OPERATION, SDRAM_PRECHARGE_ALL); /* 0x1418 */
+ do {
+ tmp = GTREGREAD(MV64460_SDRAM_OPERATION);
+ } while(tmp != 0x0);
+
+ /* wait for 2 auto refresh commands */
+ udelay(20);
+
+ /* un-reset DLL */
+ GT_REG_WRITE(MV64460_SDRAM_MODE, 0x00000032); /* 0x141C */
+ GT_REG_WRITE(MV64460_SDRAM_OPERATION, SDRAM_MODE_REG_SETUP); /* 0x1418 */
+ do {
+ tmp = GTREGREAD(MV64460_SDRAM_OPERATION);
+ } while(tmp != 0x0);
+
+ /* wait 200 cycles */
+ udelay(2); /* FIXME make this dynamic for the system clock */
+
+ /* SDRAM init done */
+ memory_map_bank(0, CFG_SDRAM_BASE, (256 << 20));
+#ifdef CFG_SDRAM1_BASE
+ memory_map_bank(1, CFG_SDRAM1_BASE, (256 << 20));
+#endif
+
+ /* DUNIT_MMASK: enable SnoopHitEn bit to avoid errata CPU-#4
+ */
+ tmp = GTREGREAD(MV64460_D_UNIT_MMASK); /* 0x14B0 */
+ GT_REG_WRITE(MV64460_D_UNIT_MMASK, tmp | 0x2);
+
+ start = (0 << 20);
+#ifdef CONFIG_P3M750
+ size = (512 << 20);
+#elif defined (CONFIG_P3M7448)
+ size = (128 << 20);
+#endif
+
+#ifdef CONFIG_MV64460_ECC
+ memSpaceAttr = ((~(BIT0 << 0)) & 0xf) << 8;
+ mvDmaSetMemorySpace (0, 0, memSpaceAttr, start, size);
+ for (dest = start; dest < start + size; dest += _8M) {
+ mvDmaTransfer (0, start, dest, _8M,
+ BIT8 /*DMA_DTL_128BYTES */ |
+ BIT3 /*DMA_HOLD_SOURCE_ADDR */ |
+ BIT11 /*DMA_BLOCK_TRANSFER_MODE */ );
+ while (mvDmaIsChannelActive (0));
+ }
+#endif
+
+ return (size);
+}
+
+void board_add_ram_info(int use_default)
+{
+ u32 val;
+
+ puts(" (CL=");
+ switch ((GTREGREAD(MV64460_SDRAM_MODE) >> 4) & 0x7) {
+ case 0x2:
+ puts("2");
+ break;
+ case 0x3:
+ puts("3");
+ break;
+ case 0x5:
+ puts("1.5");
+ break;
+ case 0x6:
+ puts("2.5");
+ break;
+ }
+
+ val = GTREGREAD(MV64460_SDRAM_CONFIG);
+
+ puts(", ECC ");
+ if (val & 0x00001000)
+ puts("enabled)");
+ else
+ puts("not enabled)");
+}
+
+/*
+ * mvDmaIsChannelActive - Check if IDMA channel is active
+ *
+ * channel = IDMA channel number from 0 to 7
+ */
+int mvDmaIsChannelActive (int channel)
+{
+ ulong data;
+
+ data = GTREGREAD (MV64460_DMA_CHANNEL0_CONTROL + 4 * channel);
+ if (data & BIT14) /* activity status */
+ return 1;
+
+ return 0;
+}
+
+/*
+ * mvDmaSetMemorySpace - Set a DMA memory window for the DMA's address decoding
+ * map.
+ *
+ * memSpace = IDMA memory window number from 0 to 7
+ * trg_if = Target interface:
+ * 0x0 DRAM
+ * 0x1 Device Bus
+ * 0x2 Integrated SDRAM (or CPU bus 60x only)
+ * 0x3 PCI0
+ * 0x4 PCI1
+ * attr = IDMA attributes (see MV datasheet)
+ * base_addr = Sets up memory window for transfers
+ *
+ */
+int mvDmaSetMemorySpace (ulong memSpace,
+ ulong trg_if,
+ ulong attr, ulong base_addr, ulong size)
+{
+ ulong temp;
+
+ /* The base address must be aligned to the size. */
+ if (base_addr % size != 0)
+ return 0;
+
+ if (size >= 0x10000) { /* 64K */
+ size &= 0xffff0000;
+ base_addr = (base_addr & 0xffff0000);
+ /* Set the new attributes */
+ GT_REG_WRITE (MV64460_DMA_BASE_ADDR_REG0 + memSpace * 8,
+ (base_addr | trg_if | attr));
+ GT_REG_WRITE ((MV64460_DMA_SIZE_REG0 + memSpace * 8),
+ (size - 1) & 0xffff0000);
+ temp = GTREGREAD (MV64460_DMA_BASE_ADDR_ENABLE_REG);
+ GT_REG_WRITE (DMA_BASE_ADDR_ENABLE_REG,
+ (temp & ~(BIT0 << memSpace)));
+ return 1;
+ }
+
+ return 0;
+}
+
+/*
+ * mvDmaTransfer - Transfer data from src_addr to dst_addr on one of the 4
+ * DMA channels.
+ *
+ * channel = IDMA channel number from 0 to 3
+ * destAddr = Destination address
+ * sourceAddr = Source address
+ * size = Size in bytes
+ * command = See MV datasheet
+ *
+ */
+int mvDmaTransfer (int channel, ulong sourceAddr,
+ ulong destAddr, ulong size, ulong command)
+{
+ ulong engOffReg = 0; /* Engine Offset Register */
+
+ if (size > 0xffff)
+ command = command | BIT31; /* DMA_16M_DESCRIPTOR_MODE */
+ command = command | ((command >> 6) & 0x7);
+ engOffReg = channel * 4;
+ GT_REG_WRITE (MV64460_DMA_CHANNEL0_BYTE_COUNT + engOffReg, size);
+ GT_REG_WRITE (MV64460_DMA_CHANNEL0_SOURCE_ADDR + engOffReg, sourceAddr);
+ GT_REG_WRITE (MV64460_DMA_CHANNEL0_DESTINATION_ADDR + engOffReg, destAddr);
+ command = command |
+ BIT12 | /* DMA_CHANNEL_ENABLE */
+ BIT9; /* DMA_NON_CHAIN_MODE */
+ /* Activate DMA channel By writting to mvDmaControlRegister */
+ GT_REG_WRITE (MV64460_DMA_CHANNEL0_CONTROL + engOffReg, command);
+ return 1;
+}
+
+/****************************************************************************************
+ * SDRAM INIT *
+ * This procedure detect all Sdram types: 64, 128, 256, 512 Mbit, 1Gbit and 2Gb *
+ * This procedure fits only the Atlantis *
+ * *
+ ***************************************************************************************/
+
+/****************************************************************************************
+ * DFCDL initialize MV643xx Design Considerations *
+ * *
+ ***************************************************************************************/
+int set_dfcdlInit (void)
+{
+ int i;
+
+ /* Values from MV64460 User Manual */
+ unsigned int dfcdl_tbl[] = { 0x00000000, 0x00000001, 0x00000042, 0x00000083,
+ 0x000000c4, 0x00000105, 0x00000146, 0x00000187,
+ 0x000001c8, 0x00000209, 0x0000024a, 0x0000028b,
+ 0x000002cc, 0x0000030d, 0x0000034e, 0x0000038f,
+ 0x000003d0, 0x00000411, 0x00000452, 0x00000493,
+ 0x000004d4, 0x00000515, 0x00000556, 0x00000597,
+ 0x000005d8, 0x00000619, 0x0000065a, 0x0000069b,
+ 0x000006dc, 0x0000071d, 0x0000075e, 0x0000079f,
+ 0x000007e0, 0x00000821, 0x00000862, 0x000008a3,
+ 0x000008e4, 0x00000925, 0x00000966, 0x000009a7,
+ 0x000009e8, 0x00000a29, 0x00000a6a, 0x00000aab,
+ 0x00000aec, 0x00000b2d, 0x00000b6e, 0x00000baf,
+ 0x00000bf0, 0x00000c31, 0x00000c72, 0x00000cb3,
+ 0x00000cf4, 0x00000d35, 0x00000d76, 0x00000db7,
+ 0x00000df8, 0x00000e39, 0x00000e7a, 0x00000ebb,
+ 0x00000efc, 0x00000f3d, 0x00000f7e, 0x00000fbf };
+
+ for (i = 0; i < 64; i++)
+ GT_REG_WRITE (SRAM_DATA0, dfcdl_tbl[i]);
+ GT_REG_WRITE (DFCDL_CONFIG0, 0x00300000); /* enable dynamic delay line updating */
+
+ return (0);
+}
diff --git a/board/prodrive/p3mx/serial.c b/board/prodrive/p3mx/serial.c
new file mode 100644
index 00000000000..ba32ac12ace
--- /dev/null
+++ b/board/prodrive/p3mx/serial.c
@@ -0,0 +1,107 @@
+/*
+ * (C) Copyright 2001
+ * Josh Huber <huber@mclx.com>, Mission Critical Linux, Inc.
+ *
+ * modified for marvell db64360 eval board by
+ * Ingo Assmus <ingo.assmus@keymile.com>
+ *
+ * modified for cpci750 board by
+ * Reinhard Arlt <reinhard.arlt@esd-electronics.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
+ */
+
+/*
+ * serial.c - serial support for esd cpci750 board
+ */
+
+/* supports the MPSC */
+
+#include <common.h>
+#include <command.h>
+#include "../../Marvell/include/memory.h"
+#include "serial.h"
+
+#include "mpsc.h"
+
+DECLARE_GLOBAL_DATA_PTR;
+
+int serial_init (void)
+{
+ mpsc_init (gd->baudrate);
+
+ return (0);
+}
+
+void serial_putc (const char c)
+{
+ if (c == '\n')
+ mpsc_putchar ('\r');
+
+ mpsc_putchar (c);
+}
+
+int serial_getc (void)
+{
+ return mpsc_getchar ();
+}
+
+int serial_tstc (void)
+{
+ return mpsc_test_char ();
+}
+
+void serial_setbrg (void)
+{
+ galbrg_set_baudrate (CONFIG_MPSC_PORT, gd->baudrate);
+}
+
+
+void serial_puts (const char *s)
+{
+ while (*s) {
+ serial_putc (*s++);
+ }
+}
+
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+void kgdb_serial_init (void)
+{
+}
+
+void putDebugChar (int c)
+{
+ serial_putc (c);
+}
+
+void putDebugStr (const char *str)
+{
+ serial_puts (str);
+}
+
+int getDebugChar (void)
+{
+ return serial_getc ();
+}
+
+void kgdb_interruptible (int yes)
+{
+ return;
+}
+#endif /* CFG_CMD_KGDB */
diff --git a/board/prodrive/p3mx/serial.h b/board/prodrive/p3mx/serial.h
new file mode 100644
index 00000000000..c7fc8c162d8
--- /dev/null
+++ b/board/prodrive/p3mx/serial.h
@@ -0,0 +1,89 @@
+/*
+ * (C) Copyright 2001
+ * Josh Huber <huber@mclx.com>, Mission Critical Linux, Inc.
+ *
+ * modified for marvell db64360 eval board by
+ * Ingo Assmus <ingo.assmus@keymile.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
+ */
+
+/* serial.h - mostly useful for DUART serial_init in serial.c */
+
+#ifndef __SERIAL_H__
+#define __SERIAL_H__
+
+#if 0
+
+#define B230400 1
+#define B115200 2
+#define B57600 4
+#define B38400 82
+#define B19200 163
+#define B9600 24
+#define B4800 651
+#define B2400 1302
+#define B1200 2604
+#define B600 5208
+#define B300 10417
+#define B150 20833
+#define B110 28409
+#define BDEFAULT B115200
+
+ /* this stuff is important to initialize
+ the DUART channels */
+
+#define Scale 0x01L /* distance between port addresses */
+#define COM1 0x000003f8 /* Keyboard */
+#define COM2 0x000002f8 /* Host */
+
+
+/* Port Definitions relative to base COM port addresses */
+#define DataIn (0x00*Scale) /* data input port */
+#define DataOut (0x00*Scale) /* data output port */
+#define BaudLsb (0x00*Scale) /* baud rate divisor least significant byte */
+#define BaudMsb (0x01*Scale) /* baud rate divisor most significant byte */
+#define Ier (0x01*Scale) /* interrupt enable register */
+#define Iir (0x02*Scale) /* interrupt identification register */
+#define Lcr (0x03*Scale) /* line control register */
+#define Mcr (0x04*Scale) /* modem control register */
+#define Lsr (0x05*Scale) /* line status register */
+#define Msr (0x06*Scale) /* modem status register */
+
+/* Bit Definitions for above ports */
+#define LcrDlab 0x80 /* b7: enable baud rate divisor registers */
+#define LcrDflt 0x03 /* b6-0: no parity, 1 stop, 8 data */
+
+#define McrRts 0x02 /* b1: request to send (I am ready to xmit) */
+#define McrDtr 0x01 /* b0: data terminal ready (I am alive ready to rcv) */
+#define McrDflt (McrRts|McrDtr)
+
+#define LsrTxD 0x6000 /* b5: transmit holding register empty (i.e. xmit OK!)*/
+ /* b6: transmitter empty */
+#define LsrRxD 0x0100 /* b0: received data ready (i.e. got a byte!) */
+
+#define MsrRi 0x0040 /* b6: ring indicator (other guy is ready to rcv) */
+#define MsrDsr 0x0020 /* b5: data set ready (other guy is alive ready to rcv */
+#define MsrCts 0x0010 /* b4: clear to send (other guy is ready to rcv) */
+
+#define IerRda 0xf /* b0: Enable received data available interrupt */
+
+#endif
+
+#endif /* __SERIAL_H__ */
diff --git a/board/prodrive/p3mx/u-boot.lds b/board/prodrive/p3mx/u-boot.lds
new file mode 100644
index 00000000000..d89eb6cff20
--- /dev/null
+++ b/board/prodrive/p3mx/u-boot.lds
@@ -0,0 +1,138 @@
+/*
+ * (C) Copyright 2001
+ * Josh Huber <huber@mclx.com>, Mission Critical Linux, Inc.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/*
+ * u-boot.lds - linker script for U-Boot on the Galileo Eval Board.
+ */
+
+OUTPUT_ARCH(powerpc)
+SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/local/powerpc-any-elf/lib);
+/* Do we need any of these for elf?
+ __DYNAMIC = 0; */
+SECTIONS
+{
+ /* Read-only sections, merged into text segment: */
+ . = + SIZEOF_HEADERS;
+ .interp : { *(.interp) }
+ .hash : { *(.hash) }
+ .dynsym : { *(.dynsym) }
+ .dynstr : { *(.dynstr) }
+ .rel.text : { *(.rel.text) }
+ .rela.text : { *(.rela.text) }
+ .rel.data : { *(.rel.data) }
+ .rela.data : { *(.rela.data) }
+ .rel.rodata : { *(.rel.rodata) }
+ .rela.rodata : { *(.rela.rodata) }
+ .rel.got : { *(.rel.got) }
+ .rela.got : { *(.rela.got) }
+ .rel.ctors : { *(.rel.ctors) }
+ .rela.ctors : { *(.rela.ctors) }
+ .rel.dtors : { *(.rel.dtors) }
+ .rela.dtors : { *(.rela.dtors) }
+ .rel.bss : { *(.rel.bss) }
+ .rela.bss : { *(.rela.bss) }
+ .rel.plt : { *(.rel.plt) }
+ .rela.plt : { *(.rela.plt) }
+ .init : { *(.init) }
+ .plt : { *(.plt) }
+ .text :
+ {
+ cpu/74xx_7xx/start.o (.text)
+
+/* store the environment in a seperate sector in the boot flash */
+/* . = env_offset; */
+/* common/environment.o(.text) */
+
+ *(.text)
+ *(.fixup)
+ *(.got1)
+ }
+ _etext = .;
+ PROVIDE (etext = .);
+ .rodata :
+ {
+ *(.rodata)
+ *(.rodata1)
+ *(.rodata.str1.4)
+ *(.eh_frame)
+ }
+ .fini : { *(.fini) } =0
+ .ctors : { *(.ctors) }
+ .dtors : { *(.dtors) }
+
+ /* Read-write section, merged into data segment: */
+ . = (. + 0x00FF) & 0xFFFFFF00;
+ _erotext = .;
+ PROVIDE (erotext = .);
+ .reloc :
+ {
+ *(.got)
+ _GOT2_TABLE_ = .;
+ *(.got2)
+ _FIXUP_TABLE_ = .;
+ *(.fixup)
+ }
+ __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2;
+ __fixup_entries = (. - _FIXUP_TABLE_)>>2;
+
+ .data :
+ {
+ *(.data)
+ *(.data1)
+ *(.sdata)
+ *(.sdata2)
+ *(.dynamic)
+ CONSTRUCTORS
+ }
+ _edata = .;
+ PROVIDE (edata = .);
+
+ . = .;
+ __u_boot_cmd_start = .;
+ .u_boot_cmd : { *(.u_boot_cmd) }
+ __u_boot_cmd_end = .;
+
+
+ . = .;
+ __start___ex_table = .;
+ __ex_table : { *(__ex_table) }
+ __stop___ex_table = .;
+
+ . = ALIGN(256);
+ __init_begin = .;
+ .text.init : { *(.text.init) }
+ .data.init : { *(.data.init) }
+ . = ALIGN(256);
+ __init_end = .;
+
+ __bss_start = .;
+ .bss :
+ {
+ *(.sbss) *(.scommon)
+ *(.dynbss)
+ *(.bss)
+ *(COMMON)
+ }
+ _end = . ;
+ PROVIDE (end = .);
+}
diff --git a/board/prodrive/pdnb3/flash.c b/board/prodrive/pdnb3/flash.c
index d0e5fe703b9..518ea9c0314 100644
--- a/board/prodrive/pdnb3/flash.c
+++ b/board/prodrive/pdnb3/flash.c
@@ -24,6 +24,8 @@
#include <common.h>
#include <asm/arch/ixp425.h>
+#if !defined(CFG_FLASH_CFI_DRIVER)
+
/*
* include common flash code (for esd boards)
*/
@@ -83,3 +85,5 @@ unsigned long flash_init(void)
return size;
}
+
+#endif /* CFG_FLASH_CFI_DRIVER */
diff --git a/board/prodrive/pdnb3/nand.c b/board/prodrive/pdnb3/nand.c
index 1931d64de0c..92f9c019023 100644
--- a/board/prodrive/pdnb3/nand.c
+++ b/board/prodrive/pdnb3/nand.c
@@ -148,7 +148,7 @@ static int pdnb3_nand_dev_ready(struct mtd_info *mtd)
return 1;
}
-void board_nand_init(struct nand_chip *nand)
+int board_nand_init(struct nand_chip *nand)
{
pdnb3_ndfc = (struct pdnb3_ndfc_regs *)CFG_NAND_BASE;
@@ -167,5 +167,6 @@ void board_nand_init(struct nand_chip *nand)
nand->read_buf = pdnb3_nand_read_buf;
nand->verify_buf = pdnb3_nand_verify_buf;
nand->dev_ready = pdnb3_nand_dev_ready;
+ return 0;
}
#endif
diff --git a/board/sandburst/common/ppc440gx_i2c.c b/board/sandburst/common/ppc440gx_i2c.c
index 859dd7afe56..1e3dffb1ee1 100644
--- a/board/sandburst/common/ppc440gx_i2c.c
+++ b/board/sandburst/common/ppc440gx_i2c.c
@@ -27,13 +27,8 @@
*/
#include <common.h>
#include <ppc4xx.h>
-#if defined(CONFIG_440)
-# include <440_i2c.h>
-#else
-# include <405gp_i2c.h>
-#endif
+#include <4xx_i2c.h>
#include <i2c.h>
-#include <440_i2c.h>
#include <command.h>
#include "ppc440gx_i2c.h"
diff --git a/board/sandburst/common/ppc440gx_i2c.h b/board/sandburst/common/ppc440gx_i2c.h
index cd4fc86661f..10000f5ba9b 100644
--- a/board/sandburst/common/ppc440gx_i2c.h
+++ b/board/sandburst/common/ppc440gx_i2c.h
@@ -27,11 +27,7 @@
*/
#include <common.h>
#include <ppc4xx.h>
-#if defined(CONFIG_440)
-# include <440_i2c.h>
-#else
-# include <405gp_i2c.h>
-#endif
+#include <4xx_i2c.h>
#include <i2c.h>
#ifdef CONFIG_HARD_I2C
diff --git a/board/sbc8349/Makefile b/board/sbc8349/Makefile
new file mode 100644
index 00000000000..02cf569b5b8
--- /dev/null
+++ b/board/sbc8349/Makefile
@@ -0,0 +1,49 @@
+#
+# Copyright (c) 2006 Wind River Systems, Inc.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+include $(TOPDIR)/config.mk
+
+LIB = $(obj)lib$(BOARD).a
+
+COBJS := $(BOARD).o pci.o
+
+SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(COBJS))
+SOBJS := $(addprefix $(obj),$(SOBJS))
+
+$(LIB): $(obj).depend $(OBJS)
+ $(AR) $(ARFLAGS) $@ $(OBJS)
+
+clean:
+ rm -f $(SOBJS) $(OBJS)
+
+distclean: clean
+ rm -f $(LIB) core *.bak .depend
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/board/sbc8349/config.mk b/board/sbc8349/config.mk
new file mode 100644
index 00000000000..05fa5a07d57
--- /dev/null
+++ b/board/sbc8349/config.mk
@@ -0,0 +1,27 @@
+#
+# Copyright (c) 2006 Wind River Systems, Inc.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+#
+# SBC8349E
+#
+
+TEXT_BASE = 0xFFF00000
diff --git a/board/sbc8349/pci.c b/board/sbc8349/pci.c
new file mode 100644
index 00000000000..eadf230983d
--- /dev/null
+++ b/board/sbc8349/pci.c
@@ -0,0 +1,348 @@
+/*
+ * pci.c -- WindRiver SBC8349 PCI board support.
+ * Copyright (c) 2006 Wind River Systems, Inc.
+ *
+ * Based on MPC8349 PCI support but w/o PIB related code.
+ *
+ * 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 <asm/mmu.h>
+#include <common.h>
+#include <asm/global_data.h>
+#include <pci.h>
+#include <asm/mpc8349_pci.h>
+#include <i2c.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#ifdef CONFIG_PCI
+
+/* System RAM mapped to PCI space */
+#define CONFIG_PCI_SYS_MEM_BUS CFG_SDRAM_BASE
+#define CONFIG_PCI_SYS_MEM_PHYS CFG_SDRAM_BASE
+
+#ifndef CONFIG_PCI_PNP
+static struct pci_config_table pci_mpc8349emds_config_table[] = {
+ {PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
+ PCI_IDSEL_NUMBER, PCI_ANY_ID,
+ pci_cfgfunc_config_device, {PCI_ENET0_IOADDR,
+ PCI_ENET0_MEMADDR,
+ PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER
+ }
+ },
+ {}
+};
+#endif
+
+static struct pci_controller pci_hose[] = {
+ {
+#ifndef CONFIG_PCI_PNP
+ config_table:pci_mpc8349emds_config_table,
+#endif
+ },
+ {
+#ifndef CONFIG_PCI_PNP
+ config_table:pci_mpc8349emds_config_table,
+#endif
+ }
+};
+
+/**************************************************************************
+ * pci_init_board()
+ *
+ * NOTICE: PCI2 is not supported. There is only one
+ * physical PCI slot on the board.
+ *
+ */
+void
+pci_init_board(void)
+{
+ volatile immap_t * immr;
+ volatile clk83xx_t * clk;
+ volatile law83xx_t * pci_law;
+ volatile pot83xx_t * pci_pot;
+ volatile pcictrl83xx_t * pci_ctrl;
+ volatile pciconf83xx_t * pci_conf;
+ u16 reg16;
+ u32 reg32;
+ u32 dev;
+ struct pci_controller * hose;
+
+ immr = (immap_t *)CFG_IMMR;
+ clk = (clk83xx_t *)&immr->clk;
+ pci_law = immr->sysconf.pcilaw;
+ pci_pot = immr->ios.pot;
+ pci_ctrl = immr->pci_ctrl;
+ pci_conf = immr->pci_conf;
+
+ hose = &pci_hose[0];
+
+ /*
+ * Configure PCI controller and PCI_CLK_OUTPUT both in 66M mode
+ */
+
+ reg32 = clk->occr;
+ udelay(2000);
+ clk->occr = 0xff000000;
+ udelay(2000);
+
+ /*
+ * Release PCI RST Output signal
+ */
+ pci_ctrl[0].gcr = 0;
+ udelay(2000);
+ pci_ctrl[0].gcr = 1;
+
+#ifdef CONFIG_MPC83XX_PCI2
+ pci_ctrl[1].gcr = 0;
+ udelay(2000);
+ pci_ctrl[1].gcr = 1;
+#endif
+
+ /* We need to wait at least a 1sec based on PCI specs */
+ {
+ int i;
+
+ for (i = 0; i < 1000; ++i)
+ udelay (1000);
+ }
+
+ /*
+ * Configure PCI Local Access Windows
+ */
+ pci_law[0].bar = CFG_PCI1_MEM_PHYS & LAWBAR_BAR;
+ pci_law[0].ar = LAWAR_EN | LAWAR_SIZE_1G;
+
+ pci_law[1].bar = CFG_PCI1_IO_PHYS & LAWBAR_BAR;
+ pci_law[1].ar = LAWAR_EN | LAWAR_SIZE_4M;
+
+ /*
+ * Configure PCI Outbound Translation Windows
+ */
+
+ /* PCI1 mem space - prefetch */
+ pci_pot[0].potar = (CFG_PCI1_MEM_BASE >> 12) & POTAR_TA_MASK;
+ pci_pot[0].pobar = (CFG_PCI1_MEM_PHYS >> 12) & POBAR_BA_MASK;
+ pci_pot[0].pocmr = POCMR_EN | POCMR_PREFETCH_EN | (POCMR_CM_256M & POCMR_CM_MASK);
+
+ /* PCI1 IO space */
+ pci_pot[1].potar = (CFG_PCI1_IO_BASE >> 12) & POTAR_TA_MASK;
+ pci_pot[1].pobar = (CFG_PCI1_IO_PHYS >> 12) & POBAR_BA_MASK;
+ pci_pot[1].pocmr = POCMR_EN | POCMR_IO | (POCMR_CM_1M & POCMR_CM_MASK);
+
+ /* PCI1 mmio - non-prefetch mem space */
+ pci_pot[2].potar = (CFG_PCI1_MMIO_BASE >> 12) & POTAR_TA_MASK;
+ pci_pot[2].pobar = (CFG_PCI1_MMIO_PHYS >> 12) & POBAR_BA_MASK;
+ pci_pot[2].pocmr = POCMR_EN | (POCMR_CM_256M & POCMR_CM_MASK);
+
+ /*
+ * Configure PCI Inbound Translation Windows
+ */
+
+ /* we need RAM mapped to PCI space for the devices to
+ * access main memory */
+ pci_ctrl[0].pitar1 = 0x0;
+ pci_ctrl[0].pibar1 = 0x0;
+ pci_ctrl[0].piebar1 = 0x0;
+ pci_ctrl[0].piwar1 = PIWAR_EN | PIWAR_PF | PIWAR_RTT_SNOOP | PIWAR_WTT_SNOOP | (__ilog2(gd->ram_size) - 1);
+
+ hose->first_busno = 0;
+ hose->last_busno = 0xff;
+
+ /* PCI memory prefetch space */
+ pci_set_region(hose->regions + 0,
+ CFG_PCI1_MEM_BASE,
+ CFG_PCI1_MEM_PHYS,
+ CFG_PCI1_MEM_SIZE,
+ PCI_REGION_MEM|PCI_REGION_PREFETCH);
+
+ /* PCI memory space */
+ pci_set_region(hose->regions + 1,
+ CFG_PCI1_MMIO_BASE,
+ CFG_PCI1_MMIO_PHYS,
+ CFG_PCI1_MMIO_SIZE,
+ PCI_REGION_MEM);
+
+ /* PCI IO space */
+ pci_set_region(hose->regions + 2,
+ CFG_PCI1_IO_BASE,
+ CFG_PCI1_IO_PHYS,
+ CFG_PCI1_IO_SIZE,
+ PCI_REGION_IO);
+
+ /* System memory space */
+ pci_set_region(hose->regions + 3,
+ CONFIG_PCI_SYS_MEM_BUS,
+ CONFIG_PCI_SYS_MEM_PHYS,
+ gd->ram_size,
+ PCI_REGION_MEM | PCI_REGION_MEMORY);
+
+ hose->region_count = 4;
+
+ pci_setup_indirect(hose,
+ (CFG_IMMR+0x8300),
+ (CFG_IMMR+0x8304));
+
+ pci_register_hose(hose);
+
+ /*
+ * Write to Command register
+ */
+ reg16 = 0xff;
+ dev = PCI_BDF(hose->first_busno, 0, 0);
+ pci_hose_read_config_word (hose, dev, PCI_COMMAND, &reg16);
+ reg16 |= PCI_COMMAND_SERR | PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
+ pci_hose_write_config_word(hose, dev, PCI_COMMAND, reg16);
+
+ /*
+ * Clear non-reserved bits in status register.
+ */
+ pci_hose_write_config_word(hose, dev, PCI_STATUS, 0xffff);
+ pci_hose_write_config_byte(hose, dev, PCI_LATENCY_TIMER, 0x80);
+ pci_hose_write_config_byte(hose, dev, PCI_CACHE_LINE_SIZE, 0x08);
+
+#ifdef CONFIG_PCI_SCAN_SHOW
+ printf("PCI: Bus Dev VenId DevId Class Int\n");
+#endif
+ /*
+ * Hose scan.
+ */
+ hose->last_busno = pci_hose_scan(hose);
+
+#ifdef CONFIG_MPC83XX_PCI2
+ hose = &pci_hose[1];
+
+ /*
+ * Configure PCI Outbound Translation Windows
+ */
+
+ /* PCI2 mem space - prefetch */
+ pci_pot[3].potar = (CFG_PCI2_MEM_BASE >> 12) & POTAR_TA_MASK;
+ pci_pot[3].pobar = (CFG_PCI2_MEM_PHYS >> 12) & POBAR_BA_MASK;
+ pci_pot[3].pocmr = POCMR_EN | POCMR_PCI2 | POCMR_PREFETCH_EN | (POCMR_CM_256M & POCMR_CM_MASK);
+
+ /* PCI2 IO space */
+ pci_pot[4].potar = (CFG_PCI2_IO_BASE >> 12) & POTAR_TA_MASK;
+ pci_pot[4].pobar = (CFG_PCI2_IO_PHYS >> 12) & POBAR_BA_MASK;
+ pci_pot[4].pocmr = POCMR_EN | POCMR_PCI2 | POCMR_IO | (POCMR_CM_1M & POCMR_CM_MASK);
+
+ /* PCI2 mmio - non-prefetch mem space */
+ pci_pot[5].potar = (CFG_PCI2_MMIO_BASE >> 12) & POTAR_TA_MASK;
+ pci_pot[5].pobar = (CFG_PCI2_MMIO_PHYS >> 12) & POBAR_BA_MASK;
+ pci_pot[5].pocmr = POCMR_EN | POCMR_PCI2 | (POCMR_CM_256M & POCMR_CM_MASK);
+
+ /*
+ * Configure PCI Inbound Translation Windows
+ */
+
+ /* we need RAM mapped to PCI space for the devices to
+ * access main memory */
+ pci_ctrl[1].pitar1 = 0x0;
+ pci_ctrl[1].pibar1 = 0x0;
+ pci_ctrl[1].piebar1 = 0x0;
+ pci_ctrl[1].piwar1 = PIWAR_EN | PIWAR_PF | PIWAR_RTT_SNOOP | PIWAR_WTT_SNOOP | (__ilog2(gd->ram_size) - 1);
+
+ hose->first_busno = pci_hose[0].last_busno + 1;
+ hose->last_busno = 0xff;
+
+ /* PCI memory prefetch space */
+ pci_set_region(hose->regions + 0,
+ CFG_PCI2_MEM_BASE,
+ CFG_PCI2_MEM_PHYS,
+ CFG_PCI2_MEM_SIZE,
+ PCI_REGION_MEM|PCI_REGION_PREFETCH);
+
+ /* PCI memory space */
+ pci_set_region(hose->regions + 1,
+ CFG_PCI2_MMIO_BASE,
+ CFG_PCI2_MMIO_PHYS,
+ CFG_PCI2_MMIO_SIZE,
+ PCI_REGION_MEM);
+
+ /* PCI IO space */
+ pci_set_region(hose->regions + 2,
+ CFG_PCI2_IO_BASE,
+ CFG_PCI2_IO_PHYS,
+ CFG_PCI2_IO_SIZE,
+ PCI_REGION_IO);
+
+ /* System memory space */
+ pci_set_region(hose->regions + 3,
+ CONFIG_PCI_SYS_MEM_BUS,
+ CONFIG_PCI_SYS_MEM_PHYS,
+ gd->ram_size,
+ PCI_REGION_MEM | PCI_REGION_MEMORY);
+
+ hose->region_count = 4;
+
+ pci_setup_indirect(hose,
+ (CFG_IMMR+0x8380),
+ (CFG_IMMR+0x8384));
+
+ pci_register_hose(hose);
+
+ /*
+ * Write to Command register
+ */
+ reg16 = 0xff;
+ dev = PCI_BDF(hose->first_busno, 0, 0);
+ pci_hose_read_config_word (hose, dev, PCI_COMMAND, &reg16);
+ reg16 |= PCI_COMMAND_SERR | PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
+ pci_hose_write_config_word(hose, dev, PCI_COMMAND, reg16);
+
+ /*
+ * Clear non-reserved bits in status register.
+ */
+ pci_hose_write_config_word(hose, dev, PCI_STATUS, 0xffff);
+ pci_hose_write_config_byte(hose, dev, PCI_LATENCY_TIMER, 0x80);
+ pci_hose_write_config_byte(hose, dev, PCI_CACHE_LINE_SIZE, 0x08);
+
+ /*
+ * Hose scan.
+ */
+ hose->last_busno = pci_hose_scan(hose);
+#endif
+
+}
+
+#ifdef CONFIG_OF_FLAT_TREE
+void
+ft_pci_setup(void *blob, bd_t *bd)
+{
+ u32 *p;
+ int len;
+
+ p = (u32 *)ft_get_prop(blob, "/" OF_SOC "/pci@8500/bus-range", &len);
+ if (p != NULL) {
+ p[0] = pci_hose[0].first_busno;
+ p[1] = pci_hose[0].last_busno;
+ }
+
+#ifdef CONFIG_MPC83XX_PCI2
+ p = (u32 *)ft_get_prop(blob, "/" OF_SOC "/pci@8600/bus-range", &len);
+ if (p != NULL) {
+ p[0] = pci_hose[1].first_busno;
+ p[1] = pci_hose[1].last_busno;
+ }
+#endif
+}
+#endif /* CONFIG_OF_FLAT_TREE */
+#endif /* CONFIG_PCI */
diff --git a/board/sbc8349/sbc8349.c b/board/sbc8349/sbc8349.c
new file mode 100644
index 00000000000..4cd447e097f
--- /dev/null
+++ b/board/sbc8349/sbc8349.c
@@ -0,0 +1,585 @@
+/*
+ * sbc8349.c -- WindRiver SBC8349 board support.
+ * Copyright (c) 2006-2007 Wind River Systems, Inc.
+ *
+ * Paul Gortmaker <paul.gortmaker@windriver.com>
+ * Based on board/mpc8349emds/mpc8349emds.c (and previous 834x releases.)
+ *
+ * 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 <ioports.h>
+#include <mpc83xx.h>
+#include <asm/mpc8349_pci.h>
+#include <i2c.h>
+#include <spd.h>
+#include <miiphy.h>
+#include <command.h>
+#if defined(CONFIG_SPD_EEPROM)
+#include <spd_sdram.h>
+#endif
+#if defined(CONFIG_OF_FLAT_TREE)
+#include <ft_build.h>
+#endif
+
+int fixed_sdram(void);
+void sdram_init(void);
+
+#if defined(CONFIG_DDR_ECC) && defined(CONFIG_MPC83XX)
+void ddr_enable_ecc(unsigned int dram_size);
+#endif
+
+#ifdef CONFIG_BOARD_EARLY_INIT_F
+int board_early_init_f (void)
+{
+ return 0;
+}
+#endif
+
+#define ns2clk(ns) (ns / (1000000000 / CONFIG_8349_CLKIN) + 1)
+
+long int initdram (int board_type)
+{
+ volatile immap_t *im = (immap_t *)CFG_IMMR;
+ u32 msize = 0;
+
+ if ((im->sysconf.immrbar & IMMRBAR_BASE_ADDR) != (u32)im)
+ return -1;
+
+ puts("Initializing\n");
+
+ /* DDR SDRAM - Main SODIMM */
+ im->sysconf.ddrlaw[0].bar = CFG_DDR_BASE & LAWBAR_BAR;
+#if defined(CONFIG_SPD_EEPROM)
+ msize = spd_sdram();
+#else
+ msize = fixed_sdram();
+#endif
+ /*
+ * Initialize SDRAM if it is on local bus.
+ */
+ sdram_init();
+
+#if defined(CONFIG_DDR_ECC) && !defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER)
+ /*
+ * Initialize and enable DDR ECC.
+ */
+ ddr_enable_ecc(msize * 1024 * 1024);
+#endif
+ puts(" DDR RAM: ");
+ /* return total bus SDRAM size(bytes) -- DDR */
+ return (msize * 1024 * 1024);
+}
+
+#if !defined(CONFIG_SPD_EEPROM)
+/*************************************************************************
+ * fixed sdram init -- doesn't use serial presence detect.
+ ************************************************************************/
+int fixed_sdram(void)
+{
+ volatile immap_t *im = (immap_t *)CFG_IMMR;
+ u32 msize = 0;
+ u32 ddr_size;
+ u32 ddr_size_log2;
+
+ msize = CFG_DDR_SIZE;
+ for (ddr_size = msize << 20, ddr_size_log2 = 0;
+ (ddr_size > 1);
+ ddr_size = ddr_size>>1, ddr_size_log2++) {
+ if (ddr_size & 1) {
+ return -1;
+ }
+ }
+ im->sysconf.ddrlaw[0].bar = ((CFG_DDR_SDRAM_BASE>>12) & 0xfffff);
+ im->sysconf.ddrlaw[0].ar = LAWAR_EN | ((ddr_size_log2 - 1) & LAWAR_SIZE);
+
+#if (CFG_DDR_SIZE != 256)
+#warning Currently any ddr size other than 256 is not supported
+#endif
+ im->ddr.csbnds[2].csbnds = 0x0000000f;
+ im->ddr.cs_config[2] = CFG_DDR_CONFIG;
+
+ /* currently we use only one CS, so disable the other banks */
+ im->ddr.cs_config[0] = 0;
+ im->ddr.cs_config[1] = 0;
+ im->ddr.cs_config[3] = 0;
+
+ im->ddr.timing_cfg_1 = CFG_DDR_TIMING_1;
+ im->ddr.timing_cfg_2 = CFG_DDR_TIMING_2;
+
+ im->ddr.sdram_cfg =
+ SDRAM_CFG_SREN
+#if defined(CONFIG_DDR_2T_TIMING)
+ | SDRAM_CFG_2T_EN
+#endif
+ | 2 << SDRAM_CFG_SDRAM_TYPE_SHIFT;
+#if defined (CONFIG_DDR_32BIT)
+ /* for 32-bit mode burst length is 8 */
+ im->ddr.sdram_cfg |= (SDRAM_CFG_32_BE | SDRAM_CFG_8_BE);
+#endif
+ im->ddr.sdram_mode = CFG_DDR_MODE;
+
+ im->ddr.sdram_interval = CFG_DDR_INTERVAL;
+ udelay(200);
+
+ /* enable DDR controller */
+ im->ddr.sdram_cfg |= SDRAM_CFG_MEM_EN;
+ return msize;
+}
+#endif/*!CFG_SPD_EEPROM*/
+
+
+int checkboard (void)
+{
+ puts("Board: Wind River SBC834x\n");
+ return 0;
+}
+
+/*
+ * if board is fitted with SDRAM
+ */
+#if defined(CFG_BR2_PRELIM) \
+ && defined(CFG_OR2_PRELIM) \
+ && defined(CFG_LBLAWBAR2_PRELIM) \
+ && defined(CFG_LBLAWAR2_PRELIM)
+/*
+ * Initialize SDRAM memory on the Local Bus.
+ */
+
+void sdram_init(void)
+{
+ volatile immap_t *immap = (immap_t *)CFG_IMMR;
+ volatile lbus83xx_t *lbc= &immap->lbus;
+ uint *sdram_addr = (uint *)CFG_LBC_SDRAM_BASE;
+
+ puts("\n SDRAM on Local Bus: ");
+ print_size (CFG_LBC_SDRAM_SIZE * 1024 * 1024, "\n");
+
+ /*
+ * Setup SDRAM Base and Option Registers, already done in cpu_init.c
+ */
+
+ /* setup mtrpt, lsrt and lbcr for LB bus */
+ lbc->lbcr = CFG_LBC_LBCR;
+ lbc->mrtpr = CFG_LBC_MRTPR;
+ lbc->lsrt = CFG_LBC_LSRT;
+ asm("sync");
+
+ /*
+ * Configure the SDRAM controller Machine Mode Register.
+ */
+ lbc->lsdmr = CFG_LBC_LSDMR_5; /* 0x40636733; normal operation */
+
+ lbc->lsdmr = CFG_LBC_LSDMR_1; /* 0x68636733; precharge all the banks */
+ asm("sync");
+ *sdram_addr = 0xff;
+ udelay(100);
+
+ lbc->lsdmr = CFG_LBC_LSDMR_2; /* 0x48636733; auto refresh */
+ asm("sync");
+ /*1 times*/
+ *sdram_addr = 0xff;
+ udelay(100);
+ /*2 times*/
+ *sdram_addr = 0xff;
+ udelay(100);
+ /*3 times*/
+ *sdram_addr = 0xff;
+ udelay(100);
+ /*4 times*/
+ *sdram_addr = 0xff;
+ udelay(100);
+ /*5 times*/
+ *sdram_addr = 0xff;
+ udelay(100);
+ /*6 times*/
+ *sdram_addr = 0xff;
+ udelay(100);
+ /*7 times*/
+ *sdram_addr = 0xff;
+ udelay(100);
+ /*8 times*/
+ *sdram_addr = 0xff;
+ udelay(100);
+
+ /* 0x58636733; mode register write operation */
+ lbc->lsdmr = CFG_LBC_LSDMR_4;
+ asm("sync");
+ *sdram_addr = 0xff;
+ udelay(100);
+
+ lbc->lsdmr = CFG_LBC_LSDMR_5; /* 0x40636733; normal operation */
+ asm("sync");
+ *sdram_addr = 0xff;
+ udelay(100);
+}
+#else
+void sdram_init(void)
+{
+ puts(" SDRAM on Local Bus: Disabled in config\n");
+}
+#endif
+
+#if defined(CONFIG_DDR_ECC) && defined(CONFIG_DDR_ECC_CMD)
+/*
+ * ECC user commands
+ */
+void ecc_print_status(void)
+{
+ volatile immap_t *immap = (immap_t *)CFG_IMMR;
+ volatile ddr83xx_t *ddr = &immap->ddr;
+
+ printf("\nECC mode: %s\n\n", (ddr->sdram_cfg & SDRAM_CFG_ECC_EN) ? "ON" : "OFF");
+
+ /* Interrupts */
+ printf("Memory Error Interrupt Enable:\n");
+ printf(" Multiple-Bit Error Interrupt Enable: %d\n",
+ (ddr->err_int_en & ECC_ERR_INT_EN_MBEE) ? 1 : 0);
+ printf(" Single-Bit Error Interrupt Enable: %d\n",
+ (ddr->err_int_en & ECC_ERR_INT_EN_SBEE) ? 1 : 0);
+ printf(" Memory Select Error Interrupt Enable: %d\n\n",
+ (ddr->err_int_en & ECC_ERR_INT_EN_MSEE) ? 1 : 0);
+
+ /* Error disable */
+ printf("Memory Error Disable:\n");
+ printf(" Multiple-Bit Error Disable: %d\n",
+ (ddr->err_disable & ECC_ERROR_DISABLE_MBED) ? 1 : 0);
+ printf(" Sinle-Bit Error Disable: %d\n",
+ (ddr->err_disable & ECC_ERROR_DISABLE_SBED) ? 1 : 0);
+ printf(" Memory Select Error Disable: %d\n\n",
+ (ddr->err_disable & ECC_ERROR_DISABLE_MSED) ? 1 : 0);
+
+ /* Error injection */
+ printf("Memory Data Path Error Injection Mask High/Low: %08lx %08lx\n",
+ ddr->data_err_inject_hi, ddr->data_err_inject_lo);
+
+ printf("Memory Data Path Error Injection Mask ECC:\n");
+ printf(" ECC Mirror Byte: %d\n",
+ (ddr->ecc_err_inject & ECC_ERR_INJECT_EMB) ? 1 : 0);
+ printf(" ECC Injection Enable: %d\n",
+ (ddr->ecc_err_inject & ECC_ERR_INJECT_EIEN) ? 1 : 0);
+ printf(" ECC Error Injection Mask: 0x%02x\n\n",
+ ddr->ecc_err_inject & ECC_ERR_INJECT_EEIM);
+
+ /* SBE counter/threshold */
+ printf("Memory Single-Bit Error Management (0..255):\n");
+ printf(" Single-Bit Error Threshold: %d\n",
+ (ddr->err_sbe & ECC_ERROR_MAN_SBET) >> ECC_ERROR_MAN_SBET_SHIFT);
+ printf(" Single-Bit Error Counter: %d\n\n",
+ (ddr->err_sbe & ECC_ERROR_MAN_SBEC) >> ECC_ERROR_MAN_SBEC_SHIFT);
+
+ /* Error detect */
+ printf("Memory Error Detect:\n");
+ printf(" Multiple Memory Errors: %d\n",
+ (ddr->err_detect & ECC_ERROR_DETECT_MME) ? 1 : 0);
+ printf(" Multiple-Bit Error: %d\n",
+ (ddr->err_detect & ECC_ERROR_DETECT_MBE) ? 1 : 0);
+ printf(" Single-Bit Error: %d\n",
+ (ddr->err_detect & ECC_ERROR_DETECT_SBE) ? 1 : 0);
+ printf(" Memory Select Error: %d\n\n",
+ (ddr->err_detect & ECC_ERROR_DETECT_MSE) ? 1 : 0);
+
+ /* Capture data */
+ printf("Memory Error Address Capture: 0x%08lx\n", ddr->capture_address);
+ printf("Memory Data Path Read Capture High/Low: %08lx %08lx\n",
+ ddr->capture_data_hi, ddr->capture_data_lo);
+ printf("Memory Data Path Read Capture ECC: 0x%02x\n\n",
+ ddr->capture_ecc & CAPTURE_ECC_ECE);
+
+ printf("Memory Error Attributes Capture:\n");
+ printf(" Data Beat Number: %d\n",
+ (ddr->capture_attributes & ECC_CAPT_ATTR_BNUM) >> ECC_CAPT_ATTR_BNUM_SHIFT);
+ printf(" Transaction Size: %d\n",
+ (ddr->capture_attributes & ECC_CAPT_ATTR_TSIZ) >> ECC_CAPT_ATTR_TSIZ_SHIFT);
+ printf(" Transaction Source: %d\n",
+ (ddr->capture_attributes & ECC_CAPT_ATTR_TSRC) >> ECC_CAPT_ATTR_TSRC_SHIFT);
+ printf(" Transaction Type: %d\n",
+ (ddr->capture_attributes & ECC_CAPT_ATTR_TTYP) >> ECC_CAPT_ATTR_TTYP_SHIFT);
+ printf(" Error Information Valid: %d\n\n",
+ ddr->capture_attributes & ECC_CAPT_ATTR_VLD);
+}
+
+int do_ecc ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+ volatile immap_t *immap = (immap_t *)CFG_IMMR;
+ volatile ddr83xx_t *ddr = &immap->ddr;
+ volatile u32 val;
+ u64 *addr, count, val64;
+ register u64 *i;
+
+ if (argc > 4) {
+ printf ("Usage:\n%s\n", cmdtp->usage);
+ return 1;
+ }
+
+ if (argc == 2) {
+ if (strcmp(argv[1], "status") == 0) {
+ ecc_print_status();
+ return 0;
+ } else if (strcmp(argv[1], "captureclear") == 0) {
+ ddr->capture_address = 0;
+ ddr->capture_data_hi = 0;
+ ddr->capture_data_lo = 0;
+ ddr->capture_ecc = 0;
+ ddr->capture_attributes = 0;
+ return 0;
+ }
+ }
+
+ if (argc == 3) {
+ if (strcmp(argv[1], "sbecnt") == 0) {
+ val = simple_strtoul(argv[2], NULL, 10);
+ if (val > 255) {
+ printf("Incorrect Counter value, should be 0..255\n");
+ return 1;
+ }
+
+ val = (val << ECC_ERROR_MAN_SBEC_SHIFT);
+ val |= (ddr->err_sbe & ECC_ERROR_MAN_SBET);
+
+ ddr->err_sbe = val;
+ return 0;
+ } else if (strcmp(argv[1], "sbethr") == 0) {
+ val = simple_strtoul(argv[2], NULL, 10);
+ if (val > 255) {
+ printf("Incorrect Counter value, should be 0..255\n");
+ return 1;
+ }
+
+ val = (val << ECC_ERROR_MAN_SBET_SHIFT);
+ val |= (ddr->err_sbe & ECC_ERROR_MAN_SBEC);
+
+ ddr->err_sbe = val;
+ return 0;
+ } else if (strcmp(argv[1], "errdisable") == 0) {
+ val = ddr->err_disable;
+
+ if (strcmp(argv[2], "+sbe") == 0) {
+ val |= ECC_ERROR_DISABLE_SBED;
+ } else if (strcmp(argv[2], "+mbe") == 0) {
+ val |= ECC_ERROR_DISABLE_MBED;
+ } else if (strcmp(argv[2], "+mse") == 0) {
+ val |= ECC_ERROR_DISABLE_MSED;
+ } else if (strcmp(argv[2], "+all") == 0) {
+ val |= (ECC_ERROR_DISABLE_SBED |
+ ECC_ERROR_DISABLE_MBED |
+ ECC_ERROR_DISABLE_MSED);
+ } else if (strcmp(argv[2], "-sbe") == 0) {
+ val &= ~ECC_ERROR_DISABLE_SBED;
+ } else if (strcmp(argv[2], "-mbe") == 0) {
+ val &= ~ECC_ERROR_DISABLE_MBED;
+ } else if (strcmp(argv[2], "-mse") == 0) {
+ val &= ~ECC_ERROR_DISABLE_MSED;
+ } else if (strcmp(argv[2], "-all") == 0) {
+ val &= ~(ECC_ERROR_DISABLE_SBED |
+ ECC_ERROR_DISABLE_MBED |
+ ECC_ERROR_DISABLE_MSED);
+ } else {
+ printf("Incorrect err_disable field\n");
+ return 1;
+ }
+
+ ddr->err_disable = val;
+ __asm__ __volatile__ ("sync");
+ __asm__ __volatile__ ("isync");
+ return 0;
+ } else if (strcmp(argv[1], "errdetectclr") == 0) {
+ val = ddr->err_detect;
+
+ if (strcmp(argv[2], "mme") == 0) {
+ val |= ECC_ERROR_DETECT_MME;
+ } else if (strcmp(argv[2], "sbe") == 0) {
+ val |= ECC_ERROR_DETECT_SBE;
+ } else if (strcmp(argv[2], "mbe") == 0) {
+ val |= ECC_ERROR_DETECT_MBE;
+ } else if (strcmp(argv[2], "mse") == 0) {
+ val |= ECC_ERROR_DETECT_MSE;
+ } else if (strcmp(argv[2], "all") == 0) {
+ val |= (ECC_ERROR_DETECT_MME |
+ ECC_ERROR_DETECT_MBE |
+ ECC_ERROR_DETECT_SBE |
+ ECC_ERROR_DETECT_MSE);
+ } else {
+ printf("Incorrect err_detect field\n");
+ return 1;
+ }
+
+ ddr->err_detect = val;
+ return 0;
+ } else if (strcmp(argv[1], "injectdatahi") == 0) {
+ val = simple_strtoul(argv[2], NULL, 16);
+
+ ddr->data_err_inject_hi = val;
+ return 0;
+ } else if (strcmp(argv[1], "injectdatalo") == 0) {
+ val = simple_strtoul(argv[2], NULL, 16);
+
+ ddr->data_err_inject_lo = val;
+ return 0;
+ } else if (strcmp(argv[1], "injectecc") == 0) {
+ val = simple_strtoul(argv[2], NULL, 16);
+ if (val > 0xff) {
+ printf("Incorrect ECC inject mask, should be 0x00..0xff\n");
+ return 1;
+ }
+ val |= (ddr->ecc_err_inject & ~ECC_ERR_INJECT_EEIM);
+
+ ddr->ecc_err_inject = val;
+ return 0;
+ } else if (strcmp(argv[1], "inject") == 0) {
+ val = ddr->ecc_err_inject;
+
+ if (strcmp(argv[2], "en") == 0)
+ val |= ECC_ERR_INJECT_EIEN;
+ else if (strcmp(argv[2], "dis") == 0)
+ val &= ~ECC_ERR_INJECT_EIEN;
+ else
+ printf("Incorrect command\n");
+
+ ddr->ecc_err_inject = val;
+ __asm__ __volatile__ ("sync");
+ __asm__ __volatile__ ("isync");
+ return 0;
+ } else if (strcmp(argv[1], "mirror") == 0) {
+ val = ddr->ecc_err_inject;
+
+ if (strcmp(argv[2], "en") == 0)
+ val |= ECC_ERR_INJECT_EMB;
+ else if (strcmp(argv[2], "dis") == 0)
+ val &= ~ECC_ERR_INJECT_EMB;
+ else
+ printf("Incorrect command\n");
+
+ ddr->ecc_err_inject = val;
+ return 0;
+ }
+ }
+
+ if (argc == 4) {
+ if (strcmp(argv[1], "test") == 0) {
+ addr = (u64 *)simple_strtoul(argv[2], NULL, 16);
+ count = simple_strtoul(argv[3], NULL, 16);
+
+ if ((u32)addr % 8) {
+ printf("Address not alligned on double word boundary\n");
+ return 1;
+ }
+
+ disable_interrupts();
+ icache_disable();
+
+ for (i = addr; i < addr + count; i++) {
+ /* enable injects */
+ ddr->ecc_err_inject |= ECC_ERR_INJECT_EIEN;
+ __asm__ __volatile__ ("sync");
+ __asm__ __volatile__ ("isync");
+
+ /* write memory location injecting errors */
+ *i = 0x1122334455667788ULL;
+ __asm__ __volatile__ ("sync");
+
+ /* disable injects */
+ ddr->ecc_err_inject &= ~ECC_ERR_INJECT_EIEN;
+ __asm__ __volatile__ ("sync");
+ __asm__ __volatile__ ("isync");
+
+ /* read data, this generates ECC error */
+ val64 = *i;
+ __asm__ __volatile__ ("sync");
+
+ /* disable errors for ECC */
+ ddr->err_disable |= ~ECC_ERROR_ENABLE;
+ __asm__ __volatile__ ("sync");
+ __asm__ __volatile__ ("isync");
+
+ /* re-initialize memory, write the location again
+ * NOT injecting errors this time */
+ *i = 0xcafecafecafecafeULL;
+ __asm__ __volatile__ ("sync");
+
+ /* enable errors for ECC */
+ ddr->err_disable &= ECC_ERROR_ENABLE;
+ __asm__ __volatile__ ("sync");
+ __asm__ __volatile__ ("isync");
+ }
+
+ icache_enable();
+ enable_interrupts();
+
+ return 0;
+ }
+ }
+
+ printf ("Usage:\n%s\n", cmdtp->usage);
+ return 1;
+}
+
+U_BOOT_CMD(
+ ecc, 4, 0, do_ecc,
+ "ecc - support for DDR ECC features\n",
+ "status - print out status info\n"
+ "ecc captureclear - clear capture regs data\n"
+ "ecc sbecnt <val> - set Single-Bit Error counter\n"
+ "ecc sbethr <val> - set Single-Bit Threshold\n"
+ "ecc errdisable <flag> - clear/set disable Memory Error Disable, flag:\n"
+ " [-|+]sbe - Single-Bit Error\n"
+ " [-|+]mbe - Multiple-Bit Error\n"
+ " [-|+]mse - Memory Select Error\n"
+ " [-|+]all - all errors\n"
+ "ecc errdetectclr <flag> - clear Memory Error Detect, flag:\n"
+ " mme - Multiple Memory Errors\n"
+ " sbe - Single-Bit Error\n"
+ " mbe - Multiple-Bit Error\n"
+ " mse - Memory Select Error\n"
+ " all - all errors\n"
+ "ecc injectdatahi <hi> - set Memory Data Path Error Injection Mask High\n"
+ "ecc injectdatalo <lo> - set Memory Data Path Error Injection Mask Low\n"
+ "ecc injectecc <ecc> - set ECC Error Injection Mask\n"
+ "ecc inject <en|dis> - enable/disable error injection\n"
+ "ecc mirror <en|dis> - enable/disable mirror byte\n"
+ "ecc test <addr> <cnt> - test mem region:\n"
+ " - enables injects\n"
+ " - writes pattern injecting errors\n"
+ " - disables injects\n"
+ " - reads pattern back, generates error\n"
+ " - re-inits memory"
+);
+#endif /* if defined(CONFIG_DDR_ECC) && defined(CONFIG_DDR_ECC_CMD) */
+
+#if defined(CONFIG_OF_FLAT_TREE) && defined(CONFIG_OF_BOARD_SETUP)
+void
+ft_board_setup(void *blob, bd_t *bd)
+{
+ u32 *p;
+ int len;
+
+#ifdef CONFIG_PCI
+ ft_pci_setup(blob, bd);
+#endif
+ ft_cpu_setup(blob, bd);
+
+ p = ft_get_prop(blob, "/memory/reg", &len);
+ if (p != NULL) {
+ *p++ = cpu_to_be32(bd->bi_memstart);
+ *p = cpu_to_be32(bd->bi_memsize);
+ }
+}
+#endif
diff --git a/board/sbc8349/u-boot.lds b/board/sbc8349/u-boot.lds
new file mode 100644
index 00000000000..e32c0754cf6
--- /dev/null
+++ b/board/sbc8349/u-boot.lds
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 2006 Wind River Systems, Inc.
+ * u-boot.lds for WindRiver SBC8349.
+ *
+ * Based on the MPC8349 u-boot.lds
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+OUTPUT_ARCH(powerpc)
+SECTIONS
+{
+ /* Read-only sections, merged into text segment: */
+ . = + SIZEOF_HEADERS;
+ .interp : { *(.interp) }
+ .hash : { *(.hash) }
+ .dynsym : { *(.dynsym) }
+ .dynstr : { *(.dynstr) }
+ .rel.text : { *(.rel.text) }
+ .rela.text : { *(.rela.text) }
+ .rel.data : { *(.rel.data) }
+ .rela.data : { *(.rela.data) }
+ .rel.rodata : { *(.rel.rodata) }
+ .rela.rodata : { *(.rela.rodata) }
+ .rel.got : { *(.rel.got) }
+ .rela.got : { *(.rela.got) }
+ .rel.ctors : { *(.rel.ctors) }
+ .rela.ctors : { *(.rela.ctors) }
+ .rel.dtors : { *(.rel.dtors) }
+ .rela.dtors : { *(.rela.dtors) }
+ .rel.bss : { *(.rel.bss) }
+ .rela.bss : { *(.rela.bss) }
+ .rel.plt : { *(.rel.plt) }
+ .rela.plt : { *(.rela.plt) }
+ .init : { *(.init) }
+ .plt : { *(.plt) }
+ .text :
+ {
+ cpu/mpc83xx/start.o (.text)
+ *(.text)
+ *(.fixup)
+ *(.got1)
+ . = ALIGN(16);
+ *(.rodata)
+ *(.rodata1)
+ *(.rodata.str1.4)
+ *(.eh_frame)
+ }
+ .fini : { *(.fini) } =0
+ .ctors : { *(.ctors) }
+ .dtors : { *(.dtors) }
+
+ /* Read-write section, merged into data segment: */
+ . = (. + 0x0FFF) & 0xFFFFF000;
+ _erotext = .;
+ PROVIDE (erotext = .);
+ .reloc :
+ {
+ *(.got)
+ _GOT2_TABLE_ = .;
+ *(.got2)
+ _FIXUP_TABLE_ = .;
+ *(.fixup)
+ }
+ __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >> 2;
+ __fixup_entries = (. - _FIXUP_TABLE_) >> 2;
+
+ .data :
+ {
+ *(.data)
+ *(.data1)
+ *(.sdata)
+ *(.sdata2)
+ *(.dynamic)
+ CONSTRUCTORS
+ }
+ _edata = .;
+ PROVIDE (edata = .);
+
+ . = .;
+ __u_boot_cmd_start = .;
+ .u_boot_cmd : { *(.u_boot_cmd) }
+ __u_boot_cmd_end = .;
+
+
+ . = .;
+ __start___ex_table = .;
+ __ex_table : { *(__ex_table) }
+ __stop___ex_table = .;
+
+ . = ALIGN(4096);
+ __init_begin = .;
+ .text.init : { *(.text.init) }
+ .data.init : { *(.data.init) }
+ . = ALIGN(4096);
+ __init_end = .;
+
+ __bss_start = .;
+ .bss :
+ {
+ *(.sbss) *(.scommon)
+ *(.dynbss)
+ *(.bss)
+ *(COMMON)
+ }
+ _end = . ;
+ PROVIDE (end = .);
+}
+ENTRY(_start)
diff --git a/board/sc3/Makefile b/board/sc3/Makefile
new file mode 100644
index 00000000000..4cc2b4171ca
--- /dev/null
+++ b/board/sc3/Makefile
@@ -0,0 +1,51 @@
+#
+# (C) Copyright 2000
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+include $(TOPDIR)/config.mk
+
+LIB = $(obj)lib$(BOARD).a
+
+COBJS = $(BOARD).o sc3nand.o
+SOBJS = init.o
+
+SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(COBJS))
+SOBJS := $(addprefix $(obj),$(SOBJS))
+
+$(LIB): $(OBJS) $(SOBJS)
+ $(AR) $(ARFLAGS) $@ $(OBJS) $(SOBJS)
+
+clean:
+ rm -f $(SOBJS) $(OBJS)
+
+distclean: clean
+ rm -f $(LIB) core *.bak .depend
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/board/sc3/config.mk b/board/sc3/config.mk
new file mode 100644
index 00000000000..1bdf5e4fcf3
--- /dev/null
+++ b/board/sc3/config.mk
@@ -0,0 +1,24 @@
+#
+# (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
+#
+
+TEXT_BASE = 0xFFFC0000
diff --git a/board/sc3/init.S b/board/sc3/init.S
new file mode 100644
index 00000000000..e7b3c839492
--- /dev/null
+++ b/board/sc3/init.S
@@ -0,0 +1,382 @@
+/*------------------------------------------------------------------------------+
+ *
+ * This souce code has been made available to you by EuroDesign
+ * (www.eurodsn.de). It's based on the original IBM source code, so
+ * this follows:
+ *
+ * This source code has been made available to you by IBM on an AS-IS
+ * basis. Anyone receiving this source is licensed under IBM
+ * copyrights to use it in any way he or she deems fit, including
+ * copying it, modifying it, compiling it, and redistributing it either
+ * with or without modifications. No license under IBM patents or
+ * patent applications is to be implied by the copyright license.
+ *
+ * Any user of this software should understand that IBM cannot provide
+ * technical support for this software and will not be responsible for
+ * any consequences resulting from the use of this software.
+ *
+ * Any person who transfers this source code or any derivative work
+ * must include the IBM copyright notice, this paragraph, and the
+ * preceding two paragraphs in the transferred software.
+ *
+ * COPYRIGHT I B M CORPORATION 1995
+ * LICENSED MATERIAL - PROGRAM PROPERTY OF I B M
+ *------------------------------------------------------------------------------- */
+
+#include <config.h>
+#include <ppc4xx.h>
+
+#define _LINUX_CONFIG_H 1 /* avoid reading Linux autoconf.h file */
+
+#include <ppc_asm.tmpl>
+#include <ppc_defs.h>
+
+#include <asm/cache.h>
+#include <asm/mmu.h>
+
+/**
+ * ext_bus_cntlr_init - Initializes the External Bus Controller for the external peripherals
+ *
+ * IMPORTANT: For pass1 this code must run from cache since you can not
+ * reliably change a peripheral banks timing register (pbxap) while running
+ * code from that bank. For ex., since we are running from ROM on bank 0, we
+ * can NOT execute the code that modifies bank 0 timings from ROM, so
+ * we run it from cache.
+ *
+ * Bank 0 - Boot-Flash
+ * Bank 1 - NAND-Flash
+ * Bank 2 - ISA bus
+ * Bank 3 - Second Flash
+ * Bank 4 - USB controller
+ */
+ .globl ext_bus_cntlr_init
+ext_bus_cntlr_init:
+/*
+ * We need the current boot up configuration to set correct
+ * timings into internal flash and external flash
+ */
+ mfdcr r24,strap /* xxxx xxxx xxxx xxx? ?xxx xxxx xxxx xxxx
+ 0 0 -> 8 bit external ROM
+ 0 1 -> 16 bit internal ROM */
+ addi r4,0,2
+ srw r24,r24,r4 /* shift right r24 two positions */
+ andi. r24,r24,0x06000
+/*
+ * All calculations are based on 33MHz EBC clock.
+ *
+ * First, create a "very slow" timing (~250ns) with burst mode enabled
+ * This is need for the external flash access
+ */
+ lis r25,0x0800
+ ori r25,r25,0x0280 /* 0000 1000 0xxx 0000 0000 0010 100x xxxx = 0x03800280
+/*
+ * Second, create a fast timing:
+ * 90ns first cycle - 3 clock access
+ * and 90ns burst cycle, plus 1 clock after the last access
+ * This is used for the internal access
+ */
+ lis r26,0x8900
+ ori r26,r26,0x0280 /* 1000 1001 0xxx 0000 0000 0010 100x xxxx
+/*
+ * We can't change settings on CS# if we currently use them.
+ * -> load a few instructions into cache and run this code from cache
+ */
+ mflr r4 /* save link register */
+ bl ..getAddr
+..getAddr:
+ mflr r3 /* get address of ..getAddr */
+ mtlr r4 /* restore link register */
+ addi r4,0,14 /* set ctr to 10; used to prefetch */
+ mtctr r4 /* 10 cache lines to fit this function
+ in cache (gives us 8x10=80 instructions) */
+..ebcloop:
+ icbt r0,r3 /* prefetch cache line for addr in r3 */
+ addi r3,r3,32 /* move to next cache line */
+ bdnz ..ebcloop /* continue for 10 cache lines */
+/*
+ * Delay to ensure all accesses to ROM are complete before changing
+ * bank 0 timings. 200usec should be enough.
+ * 200,000,000 (cycles/sec) X .000200 (sec) = 0x9C40 cycles
+ */
+ lis r3,0x0
+ ori r3,r3,0xA000 /* ensure 200usec have passed since reset */
+ mtctr r3
+..spinlp:
+ bdnz ..spinlp /* spin loop */
+
+/*-----------------------------------------------------------------------
+ * Memory Bank 0 (BOOT-ROM) initialization
+ * 0xFFEF00000....0xFFFFFFF
+ * We only have to change the timing. Mapping is ok by boot-strapping
+ *----------------------------------------------------------------------- */
+
+ li r4,pb0ap /* PB0AP=Peripheral Bank 0 Access Parameters */
+ mtdcr ebccfga,r4
+
+ mr r4,r26 /* assume internal fast flash is boot flash */
+ cmpwi r24,0x2000 /* assumption true? ... */
+ beq 1f /* ...yes! */
+ mr r4,r25 /* ...no, use the slow variant */
+ mr r25,r26 /* use this for the other flash */
+1:
+ mtdcr ebccfgd,r4 /* change timing now */
+
+ li r4,pb0cr /* PB0CR=Peripheral Bank 0 Control Register */
+ mtdcr ebccfga,r4
+ mfdcr r4,ebccfgd
+ lis r3,0x0001
+ ori r3,r3,0x8000 /* allow reads and writes */
+ or r4,r4,r3
+ mtdcr ebccfgd,r4
+
+/*-----------------------------------------------------------------------
+ * Memory Bank 3 (Second-Flash) initialization
+ * 0xF0000000...0xF01FFFFF -> 2MB
+ *----------------------------------------------------------------------- */
+
+ li r4,pb3ap /* Peripheral Bank 1 Access Parameter */
+ mtdcr ebccfga,r4
+ mtdcr ebccfgd,r2 /* change timing */
+
+ li r4,pb3cr /* Peripheral Bank 1 Configuration Registers */
+ mtdcr ebccfga,r4
+
+ lis r4,0xF003
+ ori r4,r4,0x8000
+/*
+ * Consider boot configuration
+ */
+ xori r24,r24,0x2000 /* invert current bus width */
+ or r4,r4,r24
+ mtdcr ebccfgd,r4
+
+/*-----------------------------------------------------------------------
+ * Memory Bank 1 (NAND-Flash) initialization
+ * 0x77D00000...0x77DFFFFF -> 1MB
+ * - the write/read pulse to the NAND can be as short as 25ns, bus the cycle time is always 50ns
+ * - the setup time is 0ns
+ * - the hold time is 15ns
+ * ->
+ * - TWT = 0
+ * - CSN = 0
+ * - OEN = 0
+ * - WBN = 0
+ * - WBF = 0
+ * - TH = 1
+ * ----> 2 clocks per cycle = 60ns cycle (30ns active, 30ns hold)
+ *----------------------------------------------------------------------- */
+
+ li r4,pb1ap /* Peripheral Bank 1 Access Parameter */
+ mtdcr ebccfga,r4
+
+ lis r4,0x0000
+ ori r4,r4,0x0200
+ mtdcr ebccfgd,r4
+
+ li r4,pb1cr /* Peripheral Bank 1 Configuration Registers */
+ mtdcr ebccfga,r4
+
+ lis r4,0x77D1
+ ori r4,r4,0x8000
+ mtdcr ebccfgd,r4
+
+
+/* USB init (without acceleration) */
+#ifndef CONFIG_ISP1161_PRESENT
+ li r4,pb4ap /* PB4AP=Peripheral Bank 4 Access Parameters */
+ mtdcr ebccfga,r4
+ lis r4,0x0180
+ ori r4,r4,0x5940
+ mtdcr ebccfgd,r4
+#endif
+
+/*-----------------------------------------------------------------------
+ * Memory Bank 2 (ISA Access) initialization (plus memory bank 6 and 7)
+ * 0x78000000...0x7BFFFFFF -> 64 MB
+ * Wir arbeiten bei 33 MHz -> 30ns
+ *-----------------------------------------------------------------------
+
+ A7 (ppc notation) or A24 (standard notation) decides about
+ the type of access:
+ A7/A24=0 -> memory cycle
+ A7/ /A24=1 -> I/O cycle
+*/
+ li r4,pb2ap /* PB2AP=Peripheral Bank 2 Access Parameters */
+ mtdcr ebccfga,r4
+/*
+ We emulate an ISA access
+
+ 1. Address active
+ 2. wait 0 EBC clocks -> CSN=0
+ 3. set CS#
+ 4. wait 0 EBC clock -> OEN/WBN=0
+ 5. set OE#/WE#
+ 6. wait 4 clocks (ca. 90ns) and for Ready signal
+ 7. hold for 4 clocks -> TH=4
+*/
+
+#if 1
+/* faster access to isa-bus */
+ lis r4,0x0180
+ ori r4,r4,0x5940
+#else
+ lis r4,0x0100
+ ori r4,r4,0x0340
+#endif
+ mtdcr ebccfgd,r4
+
+#ifdef IDE_USES_ISA_EMULATION
+ li r25,pb5ap /* PB5AP=Peripheral Bank 5 Access Parameters */
+ mtdcr ebccfga,r25
+ mtdcr ebccfgd,r4
+#endif
+
+ li r25,pb6ap /* PB6AP=Peripheral Bank 6 Access Parameters */
+ mtdcr ebccfga,r25
+ mtdcr ebccfgd,r4
+ li r25,pb7ap /* PB7AP=Peripheral Bank 7 Access Parameters */
+ mtdcr ebccfga,r25
+ mtdcr ebccfgd,r4
+
+ li r25,pb2cr /* PB2CR=Peripheral Bank 2 Configuration Register */
+ mtdcr ebccfga,r25
+
+ lis r4,0x780B
+ ori r4,r4,0xA000
+ mtdcr ebccfgd,r4
+/*
+ * the other areas are only 1MiB in size
+ */
+ lis r4,0x7401
+ ori r4,r4,0xA000
+
+ li r25,pb6cr /* PB6CR=Peripheral Bank 6 Configuration Register */
+ mtdcr ebccfga,r25
+ lis r4,0x7401
+ ori r4,r4,0xA000
+ mtdcr ebccfgd,r4
+
+ li r25,pb7cr /* PB7CR=Peripheral Bank 7 Configuration Register */
+ mtdcr ebccfga,r25
+ lis r4,0x7411
+ ori r4,r4,0xA000
+ mtdcr ebccfgd,r4
+
+#ifndef CONFIG_ISP1161_PRESENT
+ li r25,pb4cr /* PB4CR=Peripheral Bank 4 Configuration Register */
+ mtdcr ebccfga,r25
+ lis r4,0x7421
+ ori r4,r4,0xA000
+ mtdcr ebccfgd,r4
+#endif
+#ifdef IDE_USES_ISA_EMULATION
+ li r25,pb5cr /* PB5CR=Peripheral Bank 5 Configuration Register */
+ mtdcr ebccfga,r25
+ lis r4,0x0000
+ ori r4,r4,0x0000
+ mtdcr ebccfgd,r4
+#endif
+
+/*-----------------------------------------------------------------------
+ * Memory bank 4: USB controller Philips ISP6111
+ * 0x77C00000 ... 0x77CFFFFF
+ *
+ * The chip is connected to:
+ * - CPU CS#4
+ * - CPU IRQ#2
+ * - CPU DMA 3
+ *
+ * Timing:
+ * - command to first data: 300ns. Software must ensure this timing!
+ * - Write pulse: 26ns
+ * - Read pulse: 33ns
+ * - read cycle time: 150ns
+ * - write cycle time: 140ns
+ *
+ * Note: All calculations are based on 33MHz EBC clock. One '#' or '_' is 30ns
+ *
+ * |- 300ns --|
+ * |---- 420ns ---|---- 420ns ---| cycle
+ * CS ############:###____#######:###____#######
+ * OE ############:####___#######:####___#######
+ * WE ############:####__########:####__########
+ *
+ * ----> 2 clocks RD/WR pulses: 60ns
+ * ----> CSN: 3 clock, 90ns
+ * ----> OEN: 1 clocks (read cycle)
+ * ----> WBN: 1 clocks (write cycle)
+ * ----> WBE: 2 clocks
+ * ----> TH: 7 clock, 210ns
+ * ----> TWT: 7 clocks
+ *----------------------------------------------------------------------- */
+
+#ifdef CONFIG_ISP1161_PRESENT
+
+ li r4,pb4ap /* PB4AP=Peripheral Bank 4 Access Parameters */
+ mtdcr ebccfga,r4
+
+ lis r4,0x030D
+ ori r4,r4,0x5E80
+ mtdcr ebccfgd,r4
+
+ li r4,pb4cr /* PB2CR=Peripheral Bank 4 Configuration Register */
+ mtdcr ebccfga,r4
+
+ lis r4,0x77C1
+ ori r4,r4,0xA000
+ mtdcr ebccfgd,r4
+
+#endif
+
+#ifndef IDE_USES_ISA_EMULATION
+
+/*-----------------------------------------------------------------------
+ * Memory Bank 5 used for IDE access
+ *
+ * Timings for IDE Interface
+ *
+ * SETUP / LENGTH / HOLD - cycles valid for 33.3 MHz clk -> 30ns cycle time
+ * 70 165 30 PIO-Mode 0, [ns]
+ * 3 6 1 [Cycles] ----> AP=0x040C0200
+ * 50 125 20 PIO-Mode 1, [ns]
+ * 2 5 1 [Cycles] ----> AP=0x03080200
+ * 30 100 15 PIO-Mode 2, [ns]
+ * 1 4 1 [Cycles] ----> AP=0x02040200
+ * 30 80 10 PIO-Mode 3, [ns]
+ * 1 3 1 [Cycles] ----> AP=0x01840200
+ * 25 70 10 PIO-Mode 4, [ns]
+ * 1 3 1 [Cycles] ----> AP=0x01840200
+ *
+ *----------------------------------------------------------------------- */
+
+ li r4,pb5ap
+ mtdcr ebccfga,r4
+ lis r4,0x040C
+ ori r4,r4,0x0200
+ mtdcr ebccfgd,r4
+
+ li r4,pb5cr /* PB2CR=Peripheral Bank 2 Configuration Register */
+ mtdcr ebccfga,r4
+
+ lis r4,0x7A01
+ ori r4,r4,0xA000
+ mtdcr ebccfgd,r4
+#endif
+/*
+ * External Peripheral Control Register
+ */
+ li r4,epcr
+ mtdcr ebccfga,r4
+
+ lis r4,0xB84E
+ ori r4,r4,0xF000
+ mtdcr ebccfgd,r4
+/*
+ * drive POST code
+ */
+ lis r4,0x7900
+ ori r4,r4,0x0080
+ li r3,0x0001
+ stb r3,0(r4) /* 01 -> external bus controller is initialized */
+ nop /* pass2 DCR errata #8 */
+ blr
diff --git a/board/sc3/sc3.c b/board/sc3/sc3.c
new file mode 100644
index 00000000000..363a77d8a4e
--- /dev/null
+++ b/board/sc3/sc3.c
@@ -0,0 +1,781 @@
+/*
+ * (C) Copyright 2007
+ * Heiko Schocher, DENX Software Engineering, <hs@denx.de>.
+ *
+ * (C) Copyright 2003
+ * Juergen Beisert, EuroDesign embedded technologies, info@eurodsn.de
+ * Derived from walnut.c
+ *
+ * (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
+ *
+ * $Log:$
+ */
+
+#include <common.h>
+#include <asm/processor.h>
+#include <asm/io.h>
+#include "sc3.h"
+#include <pci.h>
+#include <i2c.h>
+#include <malloc.h>
+
+#undef writel
+#undef writeb
+#define writeb(b,addr) ((*(volatile u8 *) (addr)) = (b))
+#define writel(b,addr) ((*(volatile u32 *) (addr)) = (b))
+
+/* write only register to configure things in our CPLD */
+#define CPLD_CONTROL_1 0x79000102
+#define CPLD_VERSION 0x79000103
+
+#define IS_CAMERON ((*(unsigned char *)(CPLD_VERSION)== 0x32) ? 1 : 0)
+
+static struct pci_controller hose={0,};
+
+/************************************************************
+ * Standard definition
+ ************************************************************/
+
+/* CPC0_CR0 Function ISA bus
+ - GPIO0
+ - GPIO1 -> Output: NAND-Command Latch Enable
+ - GPIO2 -> Output: NAND Address Latch Enable
+ - GPIO3 -> IRQ input ISA-IRQ #5 (through CPLD)
+ - GPIO4 -> Output: NAND-Chip Enable
+ - GPIO5 -> IRQ input ISA-IRQ#7 (through CPLD)
+ - GPIO6 -> IRQ input ISA-IRQ#9 (through CPLD)
+ - GPIO7 -> IRQ input ISA-IRQ#10 (through CPLD)
+ - GPIO8 -> IRQ input ISA-IRQ#11 (through CPLD)
+ - GPIO9 -> IRQ input ISA-IRQ#12 (through CPLD)
+ - GPIO10/CS1# -> CS1# NAND ISA-CS#0
+ - GPIO11/CS2# -> CS2# ISA emulation ISA-CS#1
+ - GPIO12/CS3# -> CS3# 2nd Flash-Bank ISA-CS#2 or ISA-CS#7
+ - GPIO13/CS4# -> CS4# USB HC or ISA emulation ISA-CS#3
+ - GPIO14/CS5# -> CS5# Boosted IDE access ISA-CS#4
+ - GPIO15/CS6# -> CS6# ISA emulation ISA-CS#5
+ - GPIO16/CS7# -> CS7# ISA emulation ISA-CS#6
+ - GPIO17/IRQ0 -> GPIO, in, NAND-Ready/Busy# line ISA-IRQ#3
+ - GPIO18/IRQ1 -> IRQ input ISA-IRQ#14
+ - GPIO19/IRQ2 -> IRQ input or USB ISA-IRQ#4
+ - GPIO20/IRQ3 -> IRQ input PCI-IRQ#D
+ - GPIO21/IRQ4 -> IRQ input PCI-IRQ#C
+ - GPIO22/IRQ5 -> IRQ input PCI-IRQ#B
+ - GPIO23/IRQ6 -> IRQ input PCI-IRQ#A
+ - GPIO24 -> if GPIO output: 0=JTAG CPLD activ, 1=JTAG CPLD inactiv
+*/
+/*
+| CPLD register: io-space at offset 0x102 (write only)
+| 0
+| 1
+| 2 0=CS#4 USB CS#, 1=ISA or GP bus
+| 3
+| 4
+| 5
+| 6 1=enable faster IDE access
+| 7
+*/
+#define USB_CHIP_ENABLE 0x04
+#define IDE_BOOSTING 0x40
+
+/* --------------- USB stuff ------------------------------------- */
+#ifdef CONFIG_ISP1161_PRESENT
+/**
+ * initUsbHost- Initialize the Philips isp1161 HC part if present
+ * @cpldConfig: Pointer to value in write only CPLD register
+ *
+ * Initialize the USB host controller if present and fills the
+ * scratch register to inform the driver about used resources
+ */
+
+static void initUsbHost (unsigned char *cpldConfig)
+{
+ int i;
+ unsigned long usbBase;
+ /*
+ * Read back where init.S has located the USB chip
+ */
+ mtdcr (0x012, 0x04);
+ usbBase = mfdcr (0x013);
+ if (!(usbBase & 0x18000)) /* enabled? */
+ return;
+ usbBase &= 0xFFF00000;
+
+ /*
+ * to test for the USB controller enable using of CS#4 and DMA 3 for USB access
+ */
+ writeb (*cpldConfig | USB_CHIP_ENABLE,CPLD_CONTROL_1);
+
+ /*
+ * first check: is the controller assembled?
+ */
+ hcWriteWord (usbBase, 0x5555, HcScratch);
+ if (hcReadWord (usbBase, HcScratch) == 0x5555) {
+ hcWriteWord (usbBase, 0xAAAA, HcScratch);
+ if (hcReadWord (usbBase, HcScratch) == 0xAAAA) {
+ if ((hcReadWord (usbBase, HcChipID) & 0xFF00) != 0x6100)
+ return; /* this is not our controller */
+ /*
+ * try a software reset. This needs up to 10 seconds (see datasheet)
+ */
+ hcWriteDWord (usbBase, 0x00000001, HcCommandStatus);
+ for (i = 1000; i > 0; i--) { /* loop up to 10 seconds */
+ udelay (10);
+ if (!(hcReadDWord (usbBase, HcCommandStatus) & 0x01))
+ break;
+ }
+
+ if (!i)
+ return; /* the controller doesn't responding. Broken? */
+ /*
+ * OK. USB controller is ready. Initialize it in such way the later driver
+ * can us it (without any knowing about specific implementation)
+ */
+ hcWriteDWord (usbBase, 0x00000000, HcControl);
+ /*
+ * disable all interrupt sources. Because we
+ * don't know where we come from (hard reset, cold start, soft reset...)
+ */
+ hcWriteDWord (usbBase, 0x8000007D, HcInterruptDisable);
+ /*
+ * our current setup hardware configuration
+ * - every port power supply can switched indepently
+ * - every port can signal overcurrent
+ * - every port is "outside" and the devices are removeable
+ */
+ hcWriteDWord (usbBase, 0x32000902, HcRhDescriptorA);
+ hcWriteDWord (usbBase, 0x00060000, HcRhDescriptorB);
+ /*
+ * don't forget to switch off power supply of each port
+ * The later running driver can reenable them to find and use
+ * the (maybe) connected devices.
+ *
+ */
+ hcWriteDWord (usbBase, 0x00000200, HcRhPortStatus1);
+ hcWriteDWord (usbBase, 0x00000200, HcRhPortStatus2);
+ hcWriteWord (usbBase, 0x0428, HcHardwareConfiguration);
+ hcWriteWord (usbBase, 0x0040, HcDMAConfiguration);
+ hcWriteWord (usbBase, 0x0000, HcuPInterruptEnable);
+ hcWriteWord (usbBase, 0xA000 | (0x03 << 8) | 27, HcScratch);
+ /*
+ * controller is present and usable
+ */
+ *cpldConfig |= USB_CHIP_ENABLE;
+ }
+ }
+}
+#endif
+
+#if defined(CONFIG_START_IDE)
+int board_start_ide(void)
+{
+ if (IS_CAMERON) {
+ puts ("no IDE on cameron board.\n");
+ return 0;
+ }
+ return 1;
+}
+#endif
+
+static int sc3_cameron_init (void)
+{
+ /* Set up the Memory Controller for the CAMERON version */
+ mtebc (pb4ap, 0x01805940);
+ mtebc (pb4cr, 0x7401a000);
+ mtebc (pb5ap, 0x01805940);
+ mtebc (pb5cr, 0x7401a000);
+ mtebc (pb6ap, 0x0);
+ mtebc (pb6cr, 0x0);
+ mtebc (pb7ap, 0x0);
+ mtebc (pb7cr, 0x0);
+ return 0;
+}
+
+void sc3_read_eeprom (void)
+{
+ uchar i2c_buffer[18];
+
+ i2c_read (0x50, 0x03, 1, i2c_buffer, 9);
+ i2c_buffer[9] = 0;
+ setenv ("serial#", (char *)i2c_buffer);
+
+ /* read mac-address from eeprom */
+ i2c_read (0x50, 0x11, 1, i2c_buffer, 15);
+ i2c_buffer[17] = 0;
+ i2c_buffer[16] = i2c_buffer[14];
+ i2c_buffer[15] = i2c_buffer[13];
+ i2c_buffer[14] = ':';
+ i2c_buffer[13] = i2c_buffer[12];
+ i2c_buffer[12] = i2c_buffer[11];
+ i2c_buffer[11] = ':';
+ i2c_buffer[8] = ':';
+ i2c_buffer[5] = ':';
+ i2c_buffer[2] = ':';
+ setenv ("ethaddr", (char *)i2c_buffer);
+}
+
+int board_early_init_f (void)
+{
+ /* write only register to configure things in our CPLD */
+ unsigned char cpldConfig_1=0x00;
+
+/*-------------------------------------------------------------------------+
+| Interrupt controller setup for the SolidCard III CPU card (plus Evaluation board).
+|
+| Note: IRQ 0 UART 0, active high; level sensitive
+| IRQ 1 UART 1, active high; level sensitive
+| IRQ 2 IIC, active high; level sensitive
+| IRQ 3 Ext. master, rising edge, edge sensitive
+| IRQ 4 PCI, active high; level sensitive
+| IRQ 5 DMA Channel 0, active high; level sensitive
+| IRQ 6 DMA Channel 1, active high; level sensitive
+| IRQ 7 DMA Channel 2, active high; level sensitive
+| IRQ 8 DMA Channel 3, active high; level sensitive
+| IRQ 9 Ethernet Wakeup, active high; level sensitive
+| IRQ 10 MAL System Error (SERR), active high; level sensitive
+| IRQ 11 MAL Tx End of Buffer, active high; level sensitive
+| IRQ 12 MAL Rx End of Buffer, active high; level sensitive
+| IRQ 13 MAL Tx Descriptor Error, active high; level sensitive
+| IRQ 14 MAL Rx Descriptor Error, active high; level sensitive
+| IRQ 15 Ethernet, active high; level sensitive
+| IRQ 16 External PCI SERR, active high; level sensitive
+| IRQ 17 ECC Correctable Error, active high; level sensitive
+| IRQ 18 PCI Power Management, active high; level sensitive
+|
+| IRQ 19 (EXT IRQ7 405GPr only)
+| IRQ 20 (EXT IRQ8 405GPr only)
+| IRQ 21 (EXT IRQ9 405GPr only)
+| IRQ 22 (EXT IRQ10 405GPr only)
+| IRQ 23 (EXT IRQ11 405GPr only)
+| IRQ 24 (EXT IRQ12 405GPr only)
+|
+| IRQ 25 (EXT IRQ 0) NAND-Flash R/B# (raising edge means flash is ready)
+| IRQ 26 (EXT IRQ 1) IDE0 interrupt (x86 = IRQ14). Active high (edge sensitive)
+| IRQ 27 (EXT IRQ 2) USB controller
+| IRQ 28 (EXT IRQ 3) INT D, VGA; active low; level sensitive
+| IRQ 29 (EXT IRQ 4) INT C, Ethernet; active low; level sensitive
+| IRQ 30 (EXT IRQ 5) INT B, PC104+ SLOT; active low; level sensitive
+| IRQ 31 (EXT IRQ 6) INT A, PC104+ SLOT; active low; level sensitive
+|
+| Direct Memory Access Controller Signal Polarities
+| DRQ0 active high (like ISA)
+| ACK0 active low (like ISA)
+| EOT0 active high (like ISA)
+| DRQ1 active high (like ISA)
+| ACK1 active low (like ISA)
+| EOT1 active high (like ISA)
+| DRQ2 active high (like ISA)
+| ACK2 active low (like ISA)
+| EOT2 active high (like ISA)
+| DRQ3 active high (like ISA)
+| ACK3 active low (like ISA)
+| EOT3 active high (like ISA)
+|
++-------------------------------------------------------------------------*/
+
+ writeb (cpldConfig_1, CPLD_CONTROL_1); /* disable everything in CPLD */
+
+ mtdcr (uicsr, 0xFFFFFFFF); /* clear all ints */
+ mtdcr (uicer, 0x00000000); /* disable all ints */
+ mtdcr (uiccr, 0x00000000); /* set all to be non-critical */
+
+ if (IS_CAMERON) {
+ sc3_cameron_init();
+ mtdcr (0x0B6, 0x18000000);
+ mtdcr (uicpr, 0xFFFFFFF0);
+ mtdcr (uictr, 0x10001030);
+ } else {
+ mtdcr (0x0B6, 0x0000000);
+ mtdcr (uicpr, 0xFFFFFFE0);
+ mtdcr (uictr, 0x10000020);
+ }
+ mtdcr (uicvcr, 0x00000001); /* set vect base=0,INT0 highest priority */
+ mtdcr (uicsr, 0xFFFFFFFF); /* clear all ints */
+
+ /* setup other implementation specific details */
+ mtdcr (ecr, 0x60606000);
+
+ mtdcr (cntrl1, 0x000042C0);
+
+ if (IS_CAMERON) {
+ mtdcr (cntrl0, 0x01380000);
+ /* Setup the GPIOs */
+ writel (0x08008000, 0xEF600700); /* Output states */
+ writel (0x00000000, 0xEF600718); /* Open Drain control */
+ writel (0x68098000, 0xEF600704); /* Output control */
+ } else {
+ mtdcr (cntrl0,0x00080000);
+ /* Setup the GPIOs */
+ writel (0x08000000, 0xEF600700); /* Output states */
+ writel (0x14000000, 0xEF600718); /* Open Drain control */
+ writel (0x7C000000, 0xEF600704); /* Output control */
+ }
+
+ /* Code decompression disabled */
+ mtdcr (kiar, kconf);
+ mtdcr (kidr, 0x2B);
+
+ /* CPC0_ER: enable sleep mode of (currently) unused components */
+ /* CPC0_FR: force unused components into sleep mode */
+ mtdcr (cpmer, 0x3F800000);
+ mtdcr (cpmfr, 0x14000000);
+
+ /* set PLB priority */
+ mtdcr (0x87, 0x08000000);
+
+ /* --------------- DMA stuff ------------------------------------- */
+ mtdcr (0x126, 0x49200000);
+
+#ifndef IDE_USES_ISA_EMULATION
+ cpldConfig_1 |= IDE_BOOSTING; /* enable faster IDE */
+ /* cpldConfig |= 0x01; */ /* enable 8.33MHz output, if *not* present on your baseboard */
+ writeb (cpldConfig_1, CPLD_CONTROL_1);
+#endif
+
+#ifdef CONFIG_ISP1161_PRESENT
+ initUsbHost (&cpldConfig_1);
+ writeb (cpldConfig_1, CPLD_CONTROL_1);
+#endif
+ /* FIXME: for what must we do this */
+ *(unsigned long *)0x79000080 = 0x0001;
+ return(0);
+}
+
+int misc_init_r (void)
+{
+ char *s1;
+ int i, xilinx_val;
+ volatile char *xilinx_adr;
+ xilinx_adr = (char *)0x79000102;
+
+ *xilinx_adr = 0x00;
+
+/* customer settings ***************************************** */
+/*
+ s1 = getenv ("function");
+ if (s1) {
+ if (!strcmp (s1, "Rosho")) {
+ printf ("function 'Rosho' activated\n");
+ *xilinx_adr = 0x40;
+ }
+ else {
+ printf (">>>>>>>>>> function %s not recognized\n",s1);
+ }
+ }
+*/
+
+/* individual settings ***************************************** */
+ if ((s1 = getenv ("xilinx"))) {
+ i=0;
+ xilinx_val = 0;
+ while (i < 3 && s1[i]) {
+ if (s1[i] >= '0' && s1[i] <= '9')
+ xilinx_val = (xilinx_val << 4) + s1[i] - '0';
+ else
+ if (s1[i] >= 'A' && s1[i] <= 'F')
+ xilinx_val = (xilinx_val << 4) + s1[i] - 'A' + 10;
+ else
+ if (s1[i] >= 'a' && s1[i] <= 'f')
+ xilinx_val = (xilinx_val << 4) + s1[i] - 'a' + 10;
+ else {
+ xilinx_val = -1;
+ break;
+ }
+ i++;
+ }
+ if (xilinx_val >= 0 && xilinx_val <=255 && i < 3) {
+ printf ("Xilinx: set to %s\n", s1);
+ *xilinx_adr = (unsigned char) xilinx_val;
+ } else
+ printf ("Xilinx: rejected value %s\n", s1);
+ }
+ return 0;
+}
+
+/* -------------------------------------------------------------------------
+ * printCSConfig
+ *
+ * Print some informations about chips select configurations
+ * Only used while debugging.
+ *
+ * Params:
+ * - No. of CS pin
+ * - AP of this CS
+ * - CR of this CS
+ *
+ * Returns
+ * nothing
+ ------------------------------------------------------------------------- */
+
+#ifdef SC3_DEBUGOUT
+static void printCSConfig(int reg,unsigned long ap,unsigned long cr)
+{
+ const char *bsize[4] = {"8","16","32","?"};
+ const unsigned char banks[8] = {1, 2, 4, 8, 16, 32, 64, 128};
+ const char *bankaccess[4] = {"disabled", "RO", "WO", "RW"};
+
+#define CYCLE 30 /* time of one clock (based on 33MHz) */
+
+ printf("\nCS#%d",reg);
+ if (!(cr & 0x00018000))
+ puts(" unused");
+ else {
+ if (((cr&0xFFF00000U) & ((banks[(cr & 0x000E0000) >> 17]-1) << 20)))
+ puts(" Address is not multiple of bank size!");
+
+ printf("\n -%s bit device",
+ bsize[(cr & 0x00006000) >> 13]);
+ printf(" at 0x%08lX", cr & 0xFFF00000U);
+ printf(" size: %u MB", banks[(cr & 0x000E0000) >> 17]);
+ printf(" rights: %s", bankaccess[(cr & 0x00018000) >> 15]);
+ if (ap & 0x80000000) {
+ printf("\n -Burst device (%luns/%luns)",
+ (((ap & 0x7C000000) >> 26) + 1) * CYCLE,
+ (((ap & 0x03800000) >> 23) + 1) * CYCLE);
+ } else {
+ printf("\n -Non burst device, active cycle %luns",
+ (((ap & 0x7F800000) >> 23) + 1) * CYCLE);
+ printf("\n -Address setup %luns",
+ ((ap & 0xC0000) >> 18) * CYCLE);
+ printf("\n -CS active to RD %luns/WR %luns",
+ ((ap & 0x30000) >> 16) * CYCLE,
+ ((ap & 0xC000) >> 14) * CYCLE);
+ printf("\n -WR to CS inactive %luns",
+ ((ap & 0x3000) >> 12) * CYCLE);
+ printf("\n -Hold after access %luns",
+ ((ap & 0xE00) >> 9) * CYCLE);
+ printf("\n -Ready is %sabled",
+ ap & 0x100 ? "en" : "dis");
+ }
+ }
+}
+#endif
+
+#ifdef SC3_DEBUGOUT
+
+static unsigned int ap[] = {pb0ap, pb1ap, pb2ap, pb3ap, pb4ap,
+ pb5ap, pb6ap, pb7ap};
+static unsigned int cr[] = {pb0cr, pb1cr, pb2cr, pb3cr, pb4cr,
+ pb5cr, pb6cr, pb7cr};
+
+static int show_reg (int nr)
+{
+ unsigned long ul1, ul2;
+
+ mtdcr (ebccfga, ap[nr]);
+ ul1 = mfdcr (ebccfgd);
+ mtdcr (ebccfga, cr[nr]);
+ ul2 = mfdcr(ebccfgd);
+ printCSConfig(nr, ul1, ul2);
+ return 0;
+}
+#endif
+
+int checkboard (void)
+{
+#ifdef SC3_DEBUGOUT
+ unsigned long ul1;
+ int i;
+
+ for (i = 0; i < 8; i++) {
+ show_reg (i);
+ }
+
+ mtdcr (ebccfga, epcr);
+ ul1 = mfdcr (ebccfgd);
+
+ puts ("\nGeneral configuration:\n");
+
+ if (ul1 & 0x80000000)
+ printf(" -External Bus is always driven\n");
+
+ if (ul1 & 0x400000)
+ printf(" -CS signals are always driven\n");
+
+ if (ul1 & 0x20000)
+ printf(" -PowerDown after %lu clocks\n",
+ (ul1 & 0x1F000) >> 7);
+
+ switch (ul1 & 0xC0000)
+ {
+ case 0xC0000:
+ printf(" -No external master present\n");
+ break;
+ case 0x00000:
+ printf(" -8 bit external master present\n");
+ break;
+ case 0x40000:
+ printf(" -16 bit external master present\n");
+ break;
+ case 0x80000:
+ printf(" -32 bit external master present\n");
+ break;
+ }
+
+ switch (ul1 & 0x300000)
+ {
+ case 0x300000:
+ printf(" -Prefetch: Illegal setting!\n");
+ break;
+ case 0x000000:
+ printf(" -1 doubleword prefetch\n");
+ break;
+ case 0x100000:
+ printf(" -2 doublewords prefetch\n");
+ break;
+ case 0x200000:
+ printf(" -4 doublewords prefetch\n");
+ break;
+ }
+ putc ('\n');
+#endif
+ printf("Board: SolidCard III %s %s version.\n",
+ (IS_CAMERON ? "Cameron" : "Eurodesign"), CONFIG_SC3_VERSION);
+ return 0;
+}
+
+static int printSDRAMConfig(char reg, unsigned long cr)
+{
+ const int bisize[8]={4, 8, 16, 32, 64, 128, 256, 0};
+#ifdef SC3_DEBUGOUT
+ const char *basize[8]=
+ {"4", "8", "16", "32", "64", "128", "256", "Reserved"};
+
+ printf("SDRAM bank %d",reg);
+
+ if (!(cr & 0x01))
+ puts(" disabled\n");
+ else {
+ printf(" at 0x%08lX, size %s MB",cr & 0xFFC00000,basize[(cr&0xE0000)>>17]);
+ printf(" mode %lu\n",((cr & 0xE000)>>13)+1);
+ }
+#endif
+
+ if (cr & 0x01)
+ return(bisize[(cr & 0xE0000) >> 17]);
+
+ return 0;
+}
+
+#ifdef SC3_DEBUGOUT
+static unsigned int mbcf[] = {mem_mb0cf, mem_mb1cf, mem_mb2cf, mem_mb3cf};
+#endif
+
+long int initdram (int board_type)
+{
+ unsigned int mems=0;
+ unsigned long ul1;
+
+#ifdef SC3_DEBUGOUT
+ unsigned long ul2;
+ int i;
+
+ puts("\nSDRAM configuration:\n");
+
+ mtdcr (memcfga, mem_mcopt1);
+ ul1 = mfdcr(memcfgd);
+
+ if (!(ul1 & 0x80000000)) {
+ puts(" Controller disabled\n");
+ return 0;
+ }
+ for (i = 0; i < 4; i++) {
+ mtdcr (memcfga, mbcf[i]);
+ ul1 = mfdcr (memcfgd);
+ mems += printSDRAMConfig (i, ul1);
+ }
+
+ mtdcr (memcfga, mem_sdtr1);
+ ul1 = mfdcr(memcfgd);
+
+ printf ("Timing:\n -CAS latency %lu\n", ((ul1 & 0x1800000) >> 23)+1);
+ printf (" -Precharge %lu (PTA) \n", ((ul1 & 0xC0000) >> 18) + 1);
+ printf (" -R/W to Precharge %lu (CTP)\n", ((ul1 & 0x30000) >> 16) + 1);
+ printf (" -Leadoff %lu\n", ((ul1 & 0xC000) >> 14) + 1);
+ printf (" -CAS to RAS %lu\n", ((ul1 & 0x1C) >> 2) + 4);
+ printf (" -RAS to CAS %lu\n", ((ul1 & 0x3) + 1));
+ puts ("Misc:\n");
+ mtdcr (memcfga, mem_rtr);
+ ul1 = mfdcr(memcfgd);
+ printf (" -Refresh rate: %luns\n", (ul1 >> 16) * 7);
+
+ mtdcr(memcfga,mem_pmit);
+ ul2=mfdcr(memcfgd);
+
+ mtdcr(memcfga,mem_mcopt1);
+ ul1=mfdcr(memcfgd);
+
+ if (ul1 & 0x20000000)
+ printf(" -Power Down after: %luns\n",
+ ((ul2 & 0xFFC00000) >> 22) * 7);
+ else
+ puts(" -Power Down disabled\n");
+
+ if (ul1 & 0x40000000)
+ printf(" -Self refresh feature active\n");
+ else
+ puts(" -Self refresh disabled\n");
+
+ if (ul1 & 0x10000000)
+ puts(" -ECC enabled\n");
+ else
+ puts(" -ECC disabled\n");
+
+ if (ul1 & 0x8000000)
+ puts(" -Using registered SDRAM\n");
+
+ if (!(ul1 & 0x6000000))
+ puts(" -Using 32 bit data width\n");
+ else
+ puts(" -Illegal data width!\n");
+
+ if (ul1 & 0x400000)
+ puts(" -ECC drivers inactive\n");
+ else
+ puts(" -ECC drivers active\n");
+
+ if (ul1 & 0x200000)
+ puts(" -Memory lines always active outputs\n");
+ else
+ puts(" -Memory lines only at write cycles active outputs\n");
+
+ mtdcr (memcfga, mem_status);
+ ul1 = mfdcr (memcfgd);
+ if (ul1 & 0x80000000)
+ puts(" -SDRAM Controller ready\n");
+ else
+ puts(" -SDRAM Controller not ready\n");
+
+ if (ul1 & 0x4000000)
+ puts(" -SDRAM in self refresh mode!\n");
+
+ return (mems * 1024 * 1024);
+#else
+ mtdcr (memcfga, mem_mb0cf);
+ ul1 = mfdcr (memcfgd);
+ mems = printSDRAMConfig (0, ul1);
+
+ mtdcr (memcfga, mem_mb1cf);
+ ul1 = mfdcr (memcfgd);
+ mems += printSDRAMConfig (1, ul1);
+
+ mtdcr (memcfga, mem_mb2cf);
+ ul1 = mfdcr(memcfgd);
+ mems += printSDRAMConfig (2, ul1);
+
+ mtdcr (memcfga, mem_mb3cf);
+ ul1 = mfdcr(memcfgd);
+ mems += printSDRAMConfig (3, ul1);
+
+ return (mems * 1024 * 1024);
+#endif
+}
+
+static void pci_solidcard3_fixup_irq (struct pci_controller *hose, pci_dev_t dev)
+{
+/*-------------------------------------------------------------------------+
+ | ,-. ,-. ,-. ,-. ,-.
+ | INTD# ----|B|-----|P|-. ,-|P|-. ,-| |-. ,-|G|
+ | |R| |C| \ / |C| \ / |E| \ / |r|
+ | INTC# ----|I|-----|1|-. `/---|1|-. `/---|t|-. `/---|a|
+ | |D| |0| \/ |0| \/ |h| \/ |f|
+ | INTB# ----|G|-----|4|-./`----|4|-./`----|e|-./`----|i|
+ | |E| |+| /\ |+| /\ |r| /\ |k|
+ | INTA# ----| |-----| |- `----| |- `----| |- `----| |
+ | `-' `-' `-' `-' `-'
+ | Slot 0 10 11 12 13
+ | REQ# 0 1 2 *
+ | GNT# 0 1 2 *
+ +-------------------------------------------------------------------------*/
+ unsigned char int_line = 0xff;
+
+ switch (PCI_DEV(dev)) {
+ case 10:
+ int_line = 31; /* INT A */
+ POST_OUT(0x42);
+ break;
+
+ case 11:
+ int_line = 30; /* INT B */
+ POST_OUT(0x43);
+ break;
+
+ case 12:
+ int_line = 29; /* INT C */
+ POST_OUT(0x44);
+ break;
+
+ case 13:
+ int_line = 28; /* INT D */
+ POST_OUT(0x45);
+ break;
+ }
+ pci_hose_write_config_byte(hose, dev, PCI_INTERRUPT_LINE, int_line);
+}
+
+extern void pci_405gp_init(struct pci_controller *hose);
+extern void pci_405gp_fixup_irq(struct pci_controller *hose, pci_dev_t dev);
+extern void pci_405gp_setup_bridge(struct pci_controller *hose, pci_dev_t dev,struct pci_config_table *entry);
+/*
+ * The following table is used when there is a special need to setup a PCI device.
+ * For every PCI device found in this table is called the given init function with given
+ * parameters. So never let all IDs at PCI_ANY_ID. In this case any found device gets the same
+ * parameters!
+ *
+*/
+static struct pci_config_table pci_solidcard3_config_table[] =
+{
+/* Host to PCI Bridge device (405GP) */
+ {
+ vendor: 0x1014,
+ device: 0x0156,
+ class: PCI_CLASS_BRIDGE_HOST,
+ bus: 0,
+ dev: 0,
+ func: 0,
+ config_device: pci_405gp_setup_bridge
+ },
+ { }
+};
+
+/*-------------------------------------------------------------------------+
+ | pci_init_board (Called from pci_init() in drivers/pci.c)
+ |
+ | Init the PCI part of the SolidCard III
+ |
+ | Params:
+ * - Pointer to current PCI hose
+ * - Current Device
+ *
+ * Returns
+ * nothing
+ +-------------------------------------------------------------------------*/
+
+void pci_init_board(void)
+{
+ POST_OUT(0x41);
+/*
+ * we want the ptrs to RAM not flash (ie don't use init list)
+ */
+ hose.fixup_irq = pci_solidcard3_fixup_irq;
+ hose.config_table = pci_solidcard3_config_table;
+ pci_405gp_init(&hose);
+}
diff --git a/board/sc3/sc3.h b/board/sc3/sc3.h
new file mode 100644
index 00000000000..cf920f9f511
--- /dev/null
+++ b/board/sc3/sc3.h
@@ -0,0 +1,117 @@
+/*
+ * (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
+ */
+
+/**
+ * hcWriteWord - write a 16 bit value into the USB controller
+ * @base: base address to access the chip registers
+ * @value: 16 bit value to write into register @offset
+ * @offset: register to write the @value into
+ *
+ */
+static void inline hcWriteWord (unsigned long base, unsigned int value,
+ unsigned int offset)
+{
+ out_le16 ((volatile u16*)(base + 2), offset | 0x80);
+ out_le16 ((volatile u16*)base, value);
+}
+
+/**
+ * hcWriteDWord - write a 32 bit value into the USB controller
+ * @base: base address to access the chip registers
+ * @value: 32 bit value to write into register @offset
+ * @offset: register to write the @value into
+ *
+ */
+
+static void inline hcWriteDWord (unsigned long base, unsigned long value,
+ unsigned int offset)
+{
+ out_le16 ((volatile u16*)(base + 2), offset | 0x80);
+ out_le16 ((volatile u16*)base, value);
+ out_le16 ((volatile u16*)base, value >> 16);
+}
+
+/**
+ * hcReadWord - read a 16 bit value from the USB controller
+ * @base: base address to access the chip registers
+ * @offset: register to read from
+ *
+ * Returns the readed register value
+ */
+
+static unsigned int inline hcReadWord (unsigned long base, unsigned int offset)
+{
+ out_le16 ((volatile u16*)(base + 2), offset);
+ return (in_le16 ((volatile u16*)base));
+}
+
+/**
+ * hcReadDWord - read a 32 bit value from the USB controller
+ * @base: base address to access the chip registers
+ * @offset: register to read from
+ *
+ * Returns the readed register value
+ */
+
+static unsigned long inline hcReadDWord (unsigned long base, unsigned int offset)
+{
+ unsigned long val, val16;
+
+ out_le16 ((volatile u16*)(base + 2), offset);
+ val = in_le16((volatile u16*)base);
+ val16 = in_le16((volatile u16*)base);
+ return (val | (val16 << 16));
+}
+
+/* control and status registers isp1161 */
+#define HcRevision 0x00
+#define HcControl 0x01
+#define HcCommandStatus 0x02
+#define HcInterruptStatus 0x03
+#define HcInterruptEnable 0x04
+#define HcInterruptDisable 0x05
+#define HcFmInterval 0x0D
+#define HcFmRemaining 0x0E
+#define HcFmNumber 0x0F
+#define HcLSThreshold 0x11
+#define HcRhDescriptorA 0x12
+#define HcRhDescriptorB 0x13
+#define HcRhStatus 0x14
+#define HcRhPortStatus1 0x15
+#define HcRhPortStatus2 0x16
+
+#define HcHardwareConfiguration 0x20
+#define HcDMAConfiguration 0x21
+#define HcTransferCounter 0x22
+#define HcuPInterrupt 0x24
+#define HcuPInterruptEnable 0x25
+#define HcChipID 0x27
+#define HcScratch 0x28
+#define HcSoftwareReset 0x29
+#define HcITLBufferLength 0x2A
+#define HcATLBufferLength 0x2B
+#define HcBufferStatus 0x2C
+#define HcReadBackITL0Length 0x2D
+#define HcReadBackITL1Length 0x2E
+#define HcITLBufferPort 0x40
+#define HcATLBufferPort 0x41
diff --git a/board/sc3/sc3nand.c b/board/sc3/sc3nand.c
new file mode 100644
index 00000000000..7daa877cddc
--- /dev/null
+++ b/board/sc3/sc3nand.c
@@ -0,0 +1,94 @@
+/*
+ * (C) Copyright 2007
+ * Heiko Schocher, DENX Software Engineering, hs@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+
+#if (CONFIG_COMMANDS & CFG_CMD_NAND)
+
+#include <nand.h>
+#include <asm/processor.h>
+
+#define readb(addr) *(volatile u_char *)(addr)
+#define readl(addr) *(volatile u_long *)(addr)
+#define writeb(d,addr) *(volatile u_char *)(addr) = (d)
+
+#define SC3_NAND_ALE 29 /* GPIO PIN 3 */
+#define SC3_NAND_CLE 30 /* GPIO PIN 2 */
+#define SC3_NAND_CE 27 /* GPIO PIN 5 */
+
+static void *sc3_io_base;
+static void *sc3_control_base = (void *)0xEF600700;
+
+static void sc3_nand_hwcontrol(struct mtd_info *mtd, int cmd)
+{
+ switch (cmd) {
+ case NAND_CTL_SETCLE:
+ set_bit (SC3_NAND_CLE, sc3_control_base);
+ break;
+ case NAND_CTL_CLRCLE:
+ clear_bit (SC3_NAND_CLE, sc3_control_base);
+ break;
+
+ case NAND_CTL_SETALE:
+ set_bit (SC3_NAND_ALE, sc3_control_base);
+ break;
+ case NAND_CTL_CLRALE:
+ clear_bit (SC3_NAND_ALE, sc3_control_base);
+ break;
+
+ case NAND_CTL_SETNCE:
+ set_bit (SC3_NAND_CE, sc3_control_base);
+ break;
+ case NAND_CTL_CLRNCE:
+ clear_bit (SC3_NAND_CE, sc3_control_base);
+ break;
+ }
+}
+
+static int sc3_nand_dev_ready(struct mtd_info *mtd)
+{
+ if (!(readl(sc3_control_base + 0x1C) & 0x4000))
+ return 0;
+ return 1;
+}
+
+static void sc3_select_chip(struct mtd_info *mtd, int chip)
+{
+ clear_bit (SC3_NAND_CE, sc3_control_base);
+}
+
+int board_nand_init(struct nand_chip *nand)
+{
+ nand->eccmode = NAND_ECC_SOFT;
+
+ sc3_io_base = (void *) CFG_NAND_BASE;
+ /* Set address of NAND IO lines (Using Linear Data Access Region) */
+ nand->IO_ADDR_R = (void __iomem *) sc3_io_base;
+ nand->IO_ADDR_W = (void __iomem *) sc3_io_base;
+ /* Reference hardware control function */
+ nand->hwcontrol = sc3_nand_hwcontrol;
+ nand->dev_ready = sc3_nand_dev_ready;
+ nand->select_chip = sc3_select_chip;
+ return 0;
+}
+#endif
diff --git a/board/sc3/u-boot.lds b/board/sc3/u-boot.lds
new file mode 100644
index 00000000000..dc255d283ec
--- /dev/null
+++ b/board/sc3/u-boot.lds
@@ -0,0 +1,150 @@
+/*
+ * (C) Copyright 2000
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+OUTPUT_ARCH(powerpc)
+SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/local/powerpc-any-elf/lib);
+/* Do we need any of these for elf?
+ __DYNAMIC = 0; */
+SECTIONS
+{
+ .resetvec 0xFFFFFFFC :
+ {
+ *(.resetvec)
+ } = 0xffff
+
+ /* Read-only sections, merged into text segment: */
+ . = + SIZEOF_HEADERS;
+ .interp : { *(.interp) }
+ .hash : { *(.hash) }
+ .dynsym : { *(.dynsym) }
+ .dynstr : { *(.dynstr) }
+ .rel.text : { *(.rel.text) }
+ .rela.text : { *(.rela.text) }
+ .rel.data : { *(.rel.data) }
+ .rela.data : { *(.rela.data) }
+ .rel.rodata : { *(.rel.rodata) }
+ .rela.rodata : { *(.rela.rodata) }
+ .rel.got : { *(.rel.got) }
+ .rela.got : { *(.rela.got) }
+ .rel.ctors : { *(.rel.ctors) }
+ .rela.ctors : { *(.rela.ctors) }
+ .rel.dtors : { *(.rel.dtors) }
+ .rela.dtors : { *(.rela.dtors) }
+ .rel.bss : { *(.rel.bss) }
+ .rela.bss : { *(.rela.bss) }
+ .rel.plt : { *(.rel.plt) }
+ .rela.plt : { *(.rela.plt) }
+ .init : { *(.init) }
+ .plt : { *(.plt) }
+ .text :
+ {
+ /* 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/sc3/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)*/
+
+ *(.text)
+ *(.fixup)
+ *(.got1)
+ }
+ _etext = .;
+ PROVIDE (etext = .);
+ .rodata :
+ {
+ *(.rodata)
+ *(.rodata1)
+ *(.rodata.str1.4)
+ *(.eh_frame)
+ }
+ .fini : { *(.fini) } =0
+ .ctors : { *(.ctors) }
+ .dtors : { *(.dtors) }
+
+ /* Read-write section, merged into data segment: */
+ . = (. + 0x00FF) & 0xFFFFFF00;
+ _erotext = .;
+ PROVIDE (erotext = .);
+ .reloc :
+ {
+ *(.got)
+ _GOT2_TABLE_ = .;
+ *(.got2)
+ _FIXUP_TABLE_ = .;
+ *(.fixup)
+ }
+ __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2;
+ __fixup_entries = (. - _FIXUP_TABLE_)>>2;
+
+ .data :
+ {
+ *(.data)
+ *(.data1)
+ *(.sdata)
+ *(.sdata2)
+ *(.dynamic)
+ CONSTRUCTORS
+ }
+ _edata = .;
+ PROVIDE (edata = .);
+
+ . = .;
+ __u_boot_cmd_start = .;
+ .u_boot_cmd : { *(.u_boot_cmd) }
+ __u_boot_cmd_end = .;
+
+ __start___ex_table = .;
+ __ex_table : { *(__ex_table) }
+ __stop___ex_table = .;
+
+ . = ALIGN(256);
+ __init_begin = .;
+ .text.init : { *(.text.init) }
+ .data.init : { *(.data.init) }
+ . = ALIGN(256);
+ __init_end = .;
+
+ __bss_start = .;
+ .bss :
+ {
+ *(.sbss) *(.scommon)
+ *(.dynbss)
+ *(.bss)
+ *(COMMON)
+ }
+ _end = . ;
+ PROVIDE (end = .);
+}
diff --git a/board/spc1920/Makefile b/board/spc1920/Makefile
index 424ab1cf9e3..0c48c3aeecc 100644
--- a/board/spc1920/Makefile
+++ b/board/spc1920/Makefile
@@ -25,7 +25,7 @@ include $(TOPDIR)/config.mk
LIB = $(obj)lib$(BOARD).a
-COBJS = $(BOARD).o
+COBJS = $(BOARD).o hpi.o
SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
OBJS := $(addprefix $(obj),$(COBJS))
diff --git a/board/spc1920/hpi.c b/board/spc1920/hpi.c
new file mode 100644
index 00000000000..3c36f7911bc
--- /dev/null
+++ b/board/spc1920/hpi.c
@@ -0,0 +1,603 @@
+/*
+ * (C) Copyright 2006
+ * Markus Klotzbuecher, DENX Software Engineering, mk@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
+ */
+
+/*
+ * Host Port Interface (HPI)
+ */
+
+/* debug levels:
+ * 0 : errors
+ * 1 : usefull info
+ * 2 : lots of info
+ * 3 : noisy
+ */
+
+#define DEBUG 0
+
+#include <config.h>
+#include <common.h>
+#include <mpc8xx.h>
+
+#include "pld.h"
+#include "hpi.h"
+
+#define _NOT_USED_ 0xFFFFFFFF
+
+/* original table:
+ * - inserted loops to achieve long CS low and high Periods (~217ns)
+ * - move cs high 2/4 to the right
+ */
+const uint dsp_table_slow[] =
+{
+ /* single read (offset 0x00 in upm ram) */
+ 0x8fffdc04, 0x0fffdc84, 0x0fffdc84, 0x0fffdc00,
+ 0x3fffdc04, 0xffffdc84, 0xffffdc84, 0xffffdc05,
+
+ /* burst read (offset 0x08 in upm ram) */
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+
+ /* single write (offset 0x18 in upm ram) */
+ 0x8fffd004, 0x0fffd084, 0x0fffd084, 0x3fffd000,
+ 0xffffd084, 0xffffd084, 0xffffd005, _NOT_USED_,
+
+ /* burst write (offset 0x20 in upm ram) */
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ /* refresh (offset 0x30 in upm ram) */
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ /* exception (offset 0x3C in upm ram) */
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+};
+
+/* dsp hpi upm ram table
+ * works fine for noninc access, failes on incremental.
+ * - removed first word
+ */
+const uint dsp_table_fast[] =
+{
+ /* single read (offset 0x00 in upm ram) */
+ 0x8fffdc04, 0x0fffdc04, 0x0fffdc00, 0x3fffdc04,
+ 0xffffdc05, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+
+ /* burst read (offset 0x08 in upm ram) */
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+
+ /* single write (offset 0x18 in upm ram) */
+ 0x8fffd004, 0x0fffd004, 0x3fffd000, 0xffffd005,
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+
+ /* burst write (offset 0x20 in upm ram) */
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ /* refresh (offset 0x30 in upm ram) */
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ /* exception (offset 0x3C in upm ram) */
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+};
+
+
+#ifdef CONFIG_SPC1920_HPI_TEST
+#undef HPI_TEST_OSZI
+
+#define HPI_TEST_CHUNKSIZE 0x1000
+#define HPI_TEST_PATTERN 0x00000000
+#define HPI_TEST_START 0x0
+#define HPI_TEST_END 0x30000
+
+#define TINY_AUTOINC_DATA_SIZE 16 /* 32bit words */
+#define TINY_AUTOINC_BASE_ADDR 0x0
+
+static int hpi_activate(void);
+static void hpi_inactivate(void);
+static void dsp_reset(void);
+
+static int hpi_write_inc(u32 addr, u32 *data, u32 count);
+static int hpi_read_inc(u32 addr, u32 *buf, u32 count);
+static int hpi_write_noinc(u32 addr, u32 data);
+static u32 hpi_read_noinc(u32 addr);
+
+int hpi_test(void);
+static int hpi_write_addr_test(u32 addr);
+static int hpi_read_write_test(u32 addr, u32 data);
+static int hpi_tiny_autoinc_test(void);
+#endif /* CONFIG_SPC1920_HPI_TEST */
+
+
+/* init the host port interface on UPMA */
+int hpi_init(void)
+{
+ volatile immap_t *immr = (immap_t *) CFG_IMMR;
+ volatile memctl8xx_t *memctl = &immr->im_memctl;
+ volatile spc1920_pld_t *pld = (spc1920_pld_t *) CFG_SPC1920_PLD_BASE;
+
+ upmconfig(UPMA, (uint *)dsp_table_slow, sizeof(dsp_table_slow)/sizeof(uint));
+ udelay(100);
+
+ memctl->memc_mamr = CFG_MAMR;
+ memctl->memc_or3 = CFG_OR3;
+ memctl->memc_br3 = CFG_BR3;
+
+ /* reset dsp */
+ dsp_reset();
+
+ /* activate hpi switch*/
+ pld->dsp_hpi_on = 0x1;
+
+ udelay(100);
+
+ return 0;
+}
+
+#ifdef CONFIG_SPC1920_HPI_TEST
+/* activate the Host Port interface */
+static int hpi_activate(void)
+{
+ volatile spc1920_pld_t *pld = (spc1920_pld_t *) CFG_SPC1920_PLD_BASE;
+
+ /* turn on hpi */
+ pld->dsp_hpi_on = 0x1;
+
+ udelay(5);
+
+ /* turn on the power EN_DSP_POWER high*/
+ /* currently always on TBD */
+
+ /* setup hpi control register */
+ HPI_HPIC_1 = (u16) 0x0008;
+ HPI_HPIC_2 = (u16) 0x0008;
+
+ udelay(100);
+
+ return 0;
+}
+
+/* turn off the host port interface */
+static void hpi_inactivate(void)
+{
+ volatile spc1920_pld_t *pld = (spc1920_pld_t *) CFG_SPC1920_PLD_BASE;
+
+ /* deactivate hpi */
+ pld->dsp_hpi_on = 0x0;
+
+ /* reset the dsp */
+ /* pld->dsp_reset = 0x0; */
+
+ /* turn off the power EN_DSP_POWER# high*/
+ /* currently always on TBD */
+
+}
+
+/* reset the DSP */
+static void dsp_reset(void)
+{
+ volatile spc1920_pld_t *pld = (spc1920_pld_t *) CFG_SPC1920_PLD_BASE;
+ pld->dsp_reset = 0x1;
+ pld->dsp_hpi_on = 0x0;
+
+ udelay(300000);
+
+ pld->dsp_reset = 0x0;
+ pld->dsp_hpi_on = 0x1;
+}
+
+
+/* write using autoinc (count is number of 32bit words) */
+static int hpi_write_inc(u32 addr, u32 *data, u32 count)
+{
+ int i;
+ u16 addr1, addr2;
+
+ addr1 = (u16) ((addr >> 16) & 0xffff); /* First HW is most significant */
+ addr2 = (u16) (addr & 0xffff);
+
+ /* write address */
+ HPI_HPIA_1 = addr1;
+ HPI_HPIA_2 = addr2;
+
+ debugX(4, "writing from data=0x%x to 0x%x\n", data, (data+count));
+
+ for(i=0; i<count; i++) {
+ HPI_HPID_INC_1 = (u16) ((data[i] >> 16) & 0xffff);
+ HPI_HPID_INC_2 = (u16) (data[i] & 0xffff);
+ debugX(4, "hpi_write_inc: data1=0x%x, data2=0x%x\n",
+ (u16) ((data[i] >> 16) & 0xffff),
+ (u16) (data[i] & 0xffff));
+ }
+#if 0
+ while(data_ptr < (u16*) (data + count)) {
+ HPI_HPID_INC_1 = *(data_ptr++);
+ HPI_HPID_INC_2 = *(data_ptr++);
+ }
+#endif
+
+ /* return number of bytes written */
+ return count;
+}
+
+/*
+ * read using autoinc (count is number of 32bit words)
+ */
+static int hpi_read_inc(u32 addr, u32 *buf, u32 count)
+{
+ int i;
+ u16 addr1, addr2, data1, data2;
+
+ addr1 = (u16) ((addr >> 16) & 0xffff); /* First HW is most significant */
+ addr2 = (u16) (addr & 0xffff);
+
+ /* write address */
+ HPI_HPIA_1 = addr1;
+ HPI_HPIA_2 = addr2;
+
+ for(i=0; i<count; i++) {
+ data1 = HPI_HPID_INC_1;
+ data2 = HPI_HPID_INC_2;
+ debugX(4, "hpi_read_inc: data1=0x%x, data2=0x%x\n", data1, data2);
+ buf[i] = (((u32) data1) << 16) | (data2 & 0xffff);
+ }
+
+#if 0
+ while(buf_ptr < (u16*) (buf + count)) {
+ *(buf_ptr++) = HPI_HPID_INC_1;
+ *(buf_ptr++) = HPI_HPID_INC_2;
+ }
+#endif
+
+ /* return number of bytes read */
+ return count;
+}
+
+
+/* write to non- auto inc regs */
+static int hpi_write_noinc(u32 addr, u32 data)
+{
+
+ u16 addr1, addr2, data1, data2;
+
+ addr1 = (u16) ((addr >> 16) & 0xffff); /* First HW is most significant */
+ addr2 = (u16) (addr & 0xffff);
+
+ /* printf("hpi_write_noinc: addr1=0x%x, addr2=0x%x\n", addr1, addr2); */
+
+ HPI_HPIA_1 = addr1;
+ HPI_HPIA_2 = addr2;
+
+ data1 = (u16) ((data >> 16) & 0xffff);
+ data2 = (u16) (data & 0xffff);
+
+ /* printf("hpi_write_noinc: data1=0x%x, data2=0x%x\n", data1, data2); */
+
+ HPI_HPID_NOINC_1 = data1;
+ HPI_HPID_NOINC_2 = data2;
+
+ return 0;
+}
+
+/* read from non- auto inc regs */
+static u32 hpi_read_noinc(u32 addr)
+{
+ u16 addr1, addr2, data1, data2;
+ u32 ret;
+
+ addr1 = (u16) ((addr >> 16) & 0xffff); /* First HW is most significant */
+ addr2 = (u16) (addr & 0xffff);
+
+ HPI_HPIA_1 = addr1;
+ HPI_HPIA_2 = addr2;
+
+ /* printf("hpi_read_noinc: addr1=0x%x, addr2=0x%x\n", addr1, addr2); */
+
+ data1 = HPI_HPID_NOINC_1;
+ data2 = HPI_HPID_NOINC_2;
+
+ /* printf("hpi_read_noinc: data1=0x%x, data2=0x%x\n", data1, data2); */
+
+ ret = (((u32) data1) << 16) | (data2 & 0xffff);
+ return ret;
+
+}
+
+/*
+ * Host Port Interface Tests
+ */
+
+#ifndef HPI_TEST_OSZI
+/* main test function */
+int hpi_test(void)
+{
+ int err = 0;
+ u32 i, ii, pattern, tmp;
+
+ pattern = HPI_TEST_PATTERN;
+
+ u32 test_data[HPI_TEST_CHUNKSIZE];
+ u32 read_data[HPI_TEST_CHUNKSIZE];
+
+ debugX(2, "hpi_test: activating hpi...");
+ hpi_activate();
+ debugX(2, "OK.\n");
+
+#if 0
+ /* Dump the first 1024 bytes
+ *
+ */
+ for(i=0; i<1024; i+=4) {
+ if(i%16==0)
+ printf("\n0x%08x: ", i);
+ printf("0x%08x ", hpi_read_noinc(i));
+ }
+#endif
+
+ /* HPIA read-write test
+ *
+ */
+ debugX(1, "hpi_test: starting HPIA read-write tests...\n");
+ err |= hpi_write_addr_test(0xdeadc0de);
+ err |= hpi_write_addr_test(0xbeefd00d);
+ err |= hpi_write_addr_test(0xabcd1234);
+ err |= hpi_write_addr_test(0xaaaaaaaa);
+ if(err) {
+ debugX(1, "hpi_test: HPIA read-write tests: *** FAILED ***\n");
+ return -1;
+ }
+ debugX(1, "hpi_test: HPIA read-write tests: OK\n");
+
+
+ /* read write test using nonincremental data regs
+ *
+ */
+ debugX(1, "hpi_test: starting nonincremental tests...\n");
+ for(i=HPI_TEST_START; i<HPI_TEST_END; i+=4) {
+ err |= hpi_read_write_test(i, pattern);
+
+ /* stolen from cmd_mem.c */
+ if(pattern & 0x80000000) {
+ pattern = -pattern; /* complement & increment */
+ } else {
+ pattern = ~pattern;
+ }
+ err |= hpi_read_write_test(i, pattern);
+
+ if(err) {
+ debugX(1, "hpi_test: nonincremental tests *** FAILED ***\n");
+ return -1;
+ }
+ }
+ debugX(1, "hpi_test: nonincremental test OK\n");
+
+ /* read write a chunk of data using nonincremental data regs
+ *
+ */
+ debugX(1, "hpi_test: starting nonincremental chunk tests...\n");
+ pattern = HPI_TEST_PATTERN;
+ for(i=HPI_TEST_START; i<HPI_TEST_END; i+=4) {
+ hpi_write_noinc(i, pattern);
+
+ /* stolen from cmd_mem.c */
+ if(pattern & 0x80000000) {
+ pattern = -pattern; /* complement & increment */
+ } else {
+ pattern = ~pattern;
+ }
+ }
+ pattern = HPI_TEST_PATTERN;
+ for(i=HPI_TEST_START; i<HPI_TEST_END; i+=4) {
+ tmp = hpi_read_noinc(i);
+
+ if(tmp != pattern) {
+ debugX(1, "hpi_test: noninc chunk test *** FAILED *** @ 0x%x, written=0x%x, read=0x%x\n", i, pattern, tmp);
+ err = -1;
+ }
+ /* stolen from cmd_mem.c */
+ if(pattern & 0x80000000) {
+ pattern = -pattern; /* complement & increment */
+ } else {
+ pattern = ~pattern;
+ }
+ }
+ if(err)
+ return -1;
+ debugX(1, "hpi_test: nonincremental chunk test OK\n");
+
+
+#ifdef DO_TINY_TEST
+ /* small verbose test using autoinc and nonautoinc to compare
+ *
+ */
+ debugX(1, "hpi_test: tiny_autoinc_test...\n");
+ hpi_tiny_autoinc_test();
+ debugX(1, "hpi_test: tiny_autoinc_test done\n");
+#endif /* DO_TINY_TEST */
+
+
+ /* $%& write a chunk of data using the autoincremental regs
+ *
+ */
+ debugX(1, "hpi_test: starting autoinc test %d chunks with 0x%x bytes...\n",
+ ((HPI_TEST_END - HPI_TEST_START) / HPI_TEST_CHUNKSIZE),
+ HPI_TEST_CHUNKSIZE);
+
+ for(i=HPI_TEST_START;
+ i < ((HPI_TEST_END - HPI_TEST_START) / HPI_TEST_CHUNKSIZE);
+ i++) {
+ /* generate the pattern data */
+ debugX(3, "generating pattern data: ");
+ for(ii = 0; ii < HPI_TEST_CHUNKSIZE; ii++) {
+ debugX(3, "0x%x ", pattern);
+
+ test_data[ii] = pattern;
+ read_data[ii] = 0x0; /* zero to be sure */
+
+ /* stolen from cmd_mem.c */
+ if(pattern & 0x80000000) {
+ pattern = -pattern; /* complement & increment */
+ } else {
+ pattern = ~pattern;
+ }
+ }
+ debugX(3, "done\n");
+
+ debugX(2, "Writing autoinc data @ 0x%x\n", i);
+ hpi_write_inc(i, test_data, HPI_TEST_CHUNKSIZE);
+
+ debugX(2, "Reading autoinc data @ 0x%x\n", i);
+ hpi_read_inc(i, read_data, HPI_TEST_CHUNKSIZE);
+
+ /* compare */
+ for(ii = 0; ii < HPI_TEST_CHUNKSIZE; ii++) {
+ debugX(3, "hpi_test_autoinc: @ 0x%x, written=0x%x, read=0x%x", i+ii, test_data[ii], read_data[ii]);
+ if(read_data[ii] != test_data[ii]) {
+ debugX(0, "hpi_test: autoinc test @ 0x%x, written=0x%x, read=0x%x *** FAILED ***\n", i+ii, test_data[ii], read_data[ii]);
+ return -1;
+ }
+ }
+ }
+ debugX(1, "hpi_test: autoinc test OK\n");
+
+ return 0;
+}
+#else /* HPI_TEST_OSZI */
+int hpi_test(void)
+{
+ int i;
+ u32 read_data[TINY_AUTOINC_DATA_SIZE];
+
+ unsigned int dummy_data[TINY_AUTOINC_DATA_SIZE] = {
+ 0x11112222, 0x33334444, 0x55556666, 0x77778888,
+ 0x9999aaaa, 0xbbbbcccc, 0xddddeeee, 0xffff1111,
+ 0x00010002, 0x00030004, 0x00050006, 0x00070008,
+ 0x0009000a, 0x000b000c, 0x000d000e, 0x000f0001
+ };
+
+ debugX(0, "hpi_test: activating hpi...");
+ hpi_activate();
+ debugX(0, "OK.\n");
+
+ while(1) {
+ led9(1);
+ debugX(0, " writing to autoinc...\n");
+ hpi_write_inc(TINY_AUTOINC_BASE_ADDR,
+ dummy_data, TINY_AUTOINC_DATA_SIZE);
+
+ debugX(0, " reading from autoinc...\n");
+ hpi_read_inc(TINY_AUTOINC_BASE_ADDR,
+ read_data, TINY_AUTOINC_DATA_SIZE);
+
+ for(i=0; i < (TINY_AUTOINC_DATA_SIZE); i++) {
+ debugX(0, " written=0x%x, read(inc)=0x%x\n",
+ dummy_data[i], read_data[i]);
+ }
+ led9(0);
+ udelay(2000000);
+ }
+ return 0;
+}
+#endif
+
+/* test if Host Port Address Register can be written correctly */
+static int hpi_write_addr_test(u32 addr)
+{
+ u32 read_back;
+ /* write address */
+ HPI_HPIA_1 = ((u16) (addr >> 16)); /* First HW is most significant */
+ HPI_HPIA_2 = ((u16) addr);
+
+ read_back = (((u32) HPI_HPIA_1)<<16) | ((u32) HPI_HPIA_2);
+
+ if(read_back == addr) {
+ debugX(2, " hpi_write_addr_test OK: written=0x%x, read=0x%x\n",
+ addr, read_back);
+ return 0;
+ } else {
+ debugX(0, " hpi_write_addr_test *** FAILED ***: written=0x%x, read=0x%x\n",
+ addr, read_back);
+ return -1;
+ }
+
+ return 0;
+}
+
+/* test if a simple read/write sequence succeeds */
+static int hpi_read_write_test(u32 addr, u32 data)
+{
+ u32 read_back;
+
+ hpi_write_noinc(addr, data);
+ read_back = hpi_read_noinc(addr);
+
+ if(read_back == data) {
+ debugX(2, " hpi_read_write_test: OK, addr=0x%x written=0x%x, read=0x%x\n", addr, data, read_back);
+ return 0;
+ } else {
+ debugX(0, " hpi_read_write_test: *** FAILED ***, addr=0x%x written=0x%x, read=0x%x\n", addr, data, read_back);
+ return -1;
+ }
+
+ return 0;
+}
+
+static int hpi_tiny_autoinc_test(void)
+{
+ int i;
+ u32 read_data[TINY_AUTOINC_DATA_SIZE];
+ u32 read_data_noinc[TINY_AUTOINC_DATA_SIZE];
+
+ unsigned int dummy_data[TINY_AUTOINC_DATA_SIZE] = {
+ 0x11112222, 0x33334444, 0x55556666, 0x77778888,
+ 0x9999aaaa, 0xbbbbcccc, 0xddddeeee, 0xffff1111,
+ 0x00010002, 0x00030004, 0x00050006, 0x00070008,
+ 0x0009000a, 0x000b000c, 0x000d000e, 0x000f0001
+ };
+
+ printf(" writing to autoinc...\n");
+ hpi_write_inc(TINY_AUTOINC_BASE_ADDR, dummy_data, TINY_AUTOINC_DATA_SIZE);
+
+ printf(" reading from autoinc...\n");
+ hpi_read_inc(TINY_AUTOINC_BASE_ADDR, read_data, TINY_AUTOINC_DATA_SIZE);
+
+ printf(" reading from noinc for comparison...\n");
+ for(i=0; i < (TINY_AUTOINC_DATA_SIZE); i++)
+ read_data_noinc[i] = hpi_read_noinc(TINY_AUTOINC_BASE_ADDR+i*4);
+
+ for(i=0; i < (TINY_AUTOINC_DATA_SIZE); i++) {
+ printf(" written=0x%x, read(inc)=0x%x, read(noinc)=0x%x\n",
+ dummy_data[i], read_data[i], read_data_noinc[i]);
+ }
+ return 0;
+}
+
+#endif /* CONFIG_SPC1920_HPI_TEST */
diff --git a/board/spc1920/hpi.h b/board/spc1920/hpi.h
new file mode 100644
index 00000000000..45038730841
--- /dev/null
+++ b/board/spc1920/hpi.h
@@ -0,0 +1,28 @@
+/*
+ * (C) Copyright 2006
+ * Markus Klotzbuecher, DENX Software Engineering, mk@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
+ */
+
+int hpi_init(void);
+
+#ifdef CONFIG_SPC1920_HPI_TEST
+int hpi_test(void);
+#endif
diff --git a/board/spc1920/pld.h b/board/spc1920/pld.h
index 3254f820c1e..5beb71b5cca 100644
--- a/board/spc1920/pld.h
+++ b/board/spc1920/pld.h
@@ -5,8 +5,8 @@ typedef struct spc1920_pld {
uchar com1_en;
uchar dsp_reset;
uchar dsp_hpi_on;
+ uchar superv_mode;
uchar codec_dsp_power_en;
- uchar clk2_en;
uchar clk3_select;
uchar clk4_select;
} spc1920_pld_t;
diff --git a/board/spc1920/spc1920.c b/board/spc1920/spc1920.c
index 028f4c635de..1f5dcb5d3e0 100644
--- a/board/spc1920/spc1920.c
+++ b/board/spc1920/spc1920.c
@@ -27,9 +27,9 @@
#include <common.h>
#include <mpc8xx.h>
#include "pld.h"
+#include "hpi.h"
#define _NOT_USED_ 0xFFFFFFFF
-/* #define debug(fmt,args...) printf (fmt ,##args) */
static long int dram_size (long int, long int *, long int);
@@ -172,10 +172,12 @@ long int initdram (int board_type)
memctl->memc_br1 = (CFG_SDRAM_BASE & BR_BA_MSK) | BR_MS_UPMB | BR_V;
udelay (1000);
+ /* initalize the DSP Host Port Interface */
+ hpi_init();
- /* PLD Setup */
- memctl->memc_or5 = CFG_OR5_PRELIM;
- memctl->memc_br5 = CFG_BR5_PRELIM;
+ /* FRAM Setup */
+ memctl->memc_or4 = CFG_OR4;
+ memctl->memc_br4 = CFG_BR4;
udelay(1000);
return (size_b0);
@@ -207,13 +209,31 @@ int board_early_init_f(void)
{
volatile immap_t *immap = (immap_t *) CFG_IMMR;
+ /* Set Go/NoGo led (PA15) to color red */
+ immap->im_ioport.iop_papar &= ~0x1;
+ immap->im_ioport.iop_paodr &= ~0x1;
+ immap->im_ioport.iop_padir |= 0x1;
+ immap->im_ioport.iop_padat |= 0x1;
+#if 0
/* Turn on LED PD9 */
immap->im_ioport.iop_pdpar &= ~(0x0040);
immap->im_ioport.iop_pddir |= 0x0040;
immap->im_ioport.iop_pddat |= 0x0040;
+#endif
+
+ /*
+ * Enable console on SMC1. This requires turning on
+ * the com2_en signal and SMC1_DISABLE
+ */
+
+ /* SMC1_DISABLE: PB17 */
+ immap->im_cpm.cp_pbodr &= ~0x4000;
+ immap->im_cpm.cp_pbpar &= ~0x4000;
+ immap->im_cpm.cp_pbdir |= 0x4000;
+ immap->im_cpm.cp_pbdat &= ~0x4000;
- /* Enable PD10 (COM2_EN) */
+ /* COM2_EN: PD10 */
immap->im_ioport.iop_pdpar &= ~0x0020;
immap->im_ioport.iop_pddir &= ~0x4000;
immap->im_ioport.iop_pddir |= 0x0020;
@@ -228,6 +248,14 @@ int board_early_init_f(void)
return 0;
}
+int last_stage_init(void)
+{
+#ifdef CONFIG_SPC1920_HPI_TEST
+ printf("CMB1920 Host Port Interface Test: %s\n",
+ hpi_test() ? "Failed!" : "OK");
+#endif
+ return 0;
+}
int checkboard (void)
{
diff --git a/board/tqm5200/cam5200_flash.c b/board/tqm5200/cam5200_flash.c
index 8c3f62e398c..b3f095d807f 100644
--- a/board/tqm5200/cam5200_flash.c
+++ b/board/tqm5200/cam5200_flash.c
@@ -25,7 +25,7 @@
#include <mpc5xxx.h>
#include <asm/processor.h>
-#ifdef CONFIG_CAM5200
+#if defined(CONFIG_CAM5200) && defined(CONFIG_CAM5200_NIOSFLASH)
#if 0
#define DEBUGF(x...) printf(x)
@@ -783,4 +783,4 @@ unsigned long flash_init(void)
return total_b;
}
-#endif /* ifdef CONFIG_CAM5200 */
+#endif /* if defined(CONFIG_CAM5200) && defined(CONFIG_CAM5200_NIOSFLASH) */
diff --git a/board/tqm8272/Makefile b/board/tqm8272/Makefile
new file mode 100644
index 00000000000..3dbf913d2eb
--- /dev/null
+++ b/board/tqm8272/Makefile
@@ -0,0 +1,40 @@
+#
+# (C) Copyright 2001
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+include $(TOPDIR)/config.mk
+
+LIB = lib$(BOARD).a
+
+OBJS = $(BOARD).o ../tqm8xx/load_sernum_ethaddr.o
+
+$(LIB): .depend $(OBJS)
+ $(AR) crv $@ $(OBJS)
+
+#########################################################################
+
+.depend: Makefile $(SOBJS:.o=.S) $(OBJS:.o=.c)
+ $(CC) -M $(CFLAGS) $(SOBJS:.o=.S) $(OBJS:.o=.c) > $@
+
+sinclude .depend
+
+#########################################################################
diff --git a/board/tqm8272/config.mk b/board/tqm8272/config.mk
new file mode 100644
index 00000000000..af7a81e3358
--- /dev/null
+++ b/board/tqm8272/config.mk
@@ -0,0 +1,34 @@
+#
+# (C) Copyright 2006
+# 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
+#
+
+#
+# TQM8272 boards
+#
+
+# This should be equal to the CFG_FLASH_BASE define in config_TQM8260.h
+# for the "final" configuration, with U-Boot in flash, or the address
+# in RAM where U-Boot is loaded at for debugging.
+#
+TEXT_BASE = 0x40000000
+
+PLATFORM_CPPFLAGS += -DTEXT_BASE=$(TEXT_BASE) -I$(TOPDIR)
diff --git a/board/tqm8272/tqm8272.c b/board/tqm8272/tqm8272.c
new file mode 100644
index 00000000000..70d1bb889f7
--- /dev/null
+++ b/board/tqm8272/tqm8272.c
@@ -0,0 +1,1234 @@
+/*
+ * (C) Copyright 2006
+ * Heiko Schocher, DENX Software Engineering, hs@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <ioports.h>
+#include <mpc8260.h>
+
+#include <command.h>
+#ifdef CONFIG_PCI
+#include <pci.h>
+#include <asm/m8260_pci.h>
+#endif
+#if CONFIG_OF_FLAT_TREE
+#include <ft_build.h>
+#include <image.h>
+#endif
+
+#if 0
+#define deb_printf(fmt,arg...) \
+ printf ("TQM8272 %s %s: " fmt,__FILE__, __FUNCTION__, ##arg)
+#else
+#define deb_printf(fmt,arg...) \
+ do { } while (0)
+#endif
+
+#if defined(CONFIG_BOARD_GET_CPU_CLK_F)
+unsigned long board_get_cpu_clk_f (void);
+#endif
+
+/*
+ * I/O Port configuration table
+ *
+ * if conf is 1, then that port pin will be configured at boot time
+ * according to the five values podr/pdir/ppar/psor/pdat for that entry
+ */
+
+const iop_conf_t iop_conf_tab[4][32] = {
+
+ /* Port A configuration */
+ { /* conf ppar psor pdir podr pdat */
+ /* PA31 */ { 0, 0, 0, 1, 0, 0 }, /* FCC1 *ATMTXEN */
+ /* PA30 */ { 0, 0, 0, 1, 0, 0 }, /* FCC1 ATMTCA */
+ /* PA29 */ { 0, 0, 0, 1, 0, 0 }, /* FCC1 ATMTSOC */
+ /* PA28 */ { 0, 0, 0, 1, 0, 0 }, /* FCC1 *ATMRXEN */
+ /* PA27 */ { 0, 0, 0, 1, 0, 0 }, /* FCC1 ATMRSOC */
+ /* PA26 */ { 0, 0, 0, 1, 0, 0 }, /* FCC1 ATMRCA */
+ /* PA25 */ { 0, 0, 0, 1, 0, 0 }, /* FCC1 ATMTXD[0] */
+ /* PA24 */ { 0, 0, 0, 1, 0, 0 }, /* FCC1 ATMTXD[1] */
+ /* PA23 */ { 0, 0, 0, 1, 0, 0 }, /* FCC1 ATMTXD[2] */
+ /* PA22 */ { 0, 0, 0, 1, 0, 0 }, /* FCC1 ATMTXD[3] */
+ /* PA21 */ { 0, 0, 0, 1, 0, 0 }, /* FCC1 ATMTXD[4] */
+ /* PA20 */ { 0, 0, 0, 1, 0, 0 }, /* FCC1 ATMTXD[5] */
+ /* PA19 */ { 0, 0, 0, 1, 0, 0 }, /* FCC1 ATMTXD[6] */
+ /* PA18 */ { 0, 0, 0, 1, 0, 0 }, /* FCC1 ATMTXD[7] */
+ /* PA17 */ { 0, 0, 0, 1, 0, 0 }, /* FCC1 ATMRXD[7] */
+ /* PA16 */ { 0, 0, 0, 1, 0, 0 }, /* FCC1 ATMRXD[6] */
+ /* PA15 */ { 0, 0, 0, 1, 0, 0 }, /* FCC1 ATMRXD[5] */
+ /* PA14 */ { 0, 0, 0, 1, 0, 0 }, /* FCC1 ATMRXD[4] */
+ /* PA13 */ { 0, 0, 0, 1, 0, 0 }, /* FCC1 ATMRXD[3] */
+ /* PA12 */ { 0, 0, 0, 1, 0, 0 }, /* FCC1 ATMRXD[2] */
+ /* PA11 */ { 0, 0, 0, 1, 0, 0 }, /* FCC1 ATMRXD[1] */
+ /* PA10 */ { 0, 0, 0, 1, 0, 0 }, /* FCC1 ATMRXD[0] */
+ /* PA9 */ { 1, 1, 0, 1, 0, 0 }, /* SMC2 TXD */
+ /* PA8 */ { 1, 1, 0, 0, 0, 0 }, /* SMC2 RXD */
+ /* PA7 */ { 0, 0, 0, 1, 0, 0 }, /* PA7 */
+ /* PA6 */ { 0, 0, 0, 1, 0, 0 }, /* PA6 */
+ /* PA5 */ { 0, 0, 0, 1, 0, 0 }, /* PA5 */
+ /* PA4 */ { 0, 0, 0, 1, 0, 0 }, /* PA4 */
+ /* PA3 */ { 0, 0, 0, 1, 0, 0 }, /* PA3 */
+ /* PA2 */ { 0, 0, 0, 1, 0, 0 }, /* PA2 */
+ /* PA1 */ { 0, 0, 0, 1, 0, 0 }, /* PA1 */
+ /* PA0 */ { 0, 0, 0, 1, 0, 0 } /* PA0 */
+ },
+
+ /* Port B configuration */
+ { /* conf ppar psor pdir podr pdat */
+ /* PB31 */ { 1, 1, 0, 1, 0, 0 }, /* FCC2 MII TX_ER */
+ /* PB30 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII RX_DV */
+ /* PB29 */ { 1, 1, 1, 1, 0, 0 }, /* FCC2 MII TX_EN */
+ /* PB28 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII RX_ER */
+ /* PB27 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII COL */
+ /* PB26 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII CRS */
+ /* PB25 */ { 1, 1, 0, 1, 0, 0 }, /* FCC2 MII TxD[3] */
+ /* PB24 */ { 1, 1, 0, 1, 0, 0 }, /* FCC2 MII TxD[2] */
+ /* PB23 */ { 1, 1, 0, 1, 0, 0 }, /* FCC2 MII TxD[1] */
+ /* PB22 */ { 1, 1, 0, 1, 0, 0 }, /* FCC2 MII TxD[0] */
+ /* PB21 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII RxD[0] */
+ /* PB20 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII RxD[1] */
+ /* PB19 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII RxD[2] */
+ /* PB18 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII RxD[3] */
+ /* PB17 */ { 0, 0, 0, 0, 0, 0 }, /* PB17 */
+ /* PB16 */ { 0, 0, 0, 0, 0, 0 }, /* PB16 */
+ /* PB15 */ { 0, 0, 0, 0, 0, 0 }, /* PB15 */
+ /* PB14 */ { 0, 0, 0, 0, 0, 0 }, /* PB14 */
+ /* PB13 */ { 0, 0, 0, 0, 0, 0 }, /* PB13 */
+ /* PB12 */ { 0, 0, 0, 0, 0, 0 }, /* PB12 */
+ /* PB11 */ { 0, 0, 0, 0, 0, 0 }, /* PB11 */
+ /* PB10 */ { 0, 0, 0, 0, 0, 0 }, /* PB10 */
+ /* PB9 */ { 0, 0, 0, 0, 0, 0 }, /* PB9 */
+ /* PB8 */ { 0, 0, 0, 0, 0, 0 }, /* PB8 */
+ /* PB7 */ { 0, 0, 0, 0, 0, 0 }, /* PB7 */
+ /* PB6 */ { 0, 0, 0, 0, 0, 0 }, /* PB6 */
+ /* PB5 */ { 0, 0, 0, 0, 0, 0 }, /* PB5 */
+ /* PB4 */ { 0, 0, 0, 0, 0, 0 }, /* PB4 */
+ /* PB3 */ { 0, 0, 0, 0, 0, 0 }, /* pin doesn't exist */
+ /* PB2 */ { 0, 0, 0, 0, 0, 0 }, /* pin doesn't exist */
+ /* PB1 */ { 0, 0, 0, 0, 0, 0 }, /* pin doesn't exist */
+ /* PB0 */ { 0, 0, 0, 0, 0, 0 } /* pin doesn't exist */
+ },
+
+ /* Port C */
+ { /* conf ppar psor pdir podr pdat */
+ /* PC31 */ { 0, 0, 0, 1, 0, 0 }, /* PC31 */
+ /* PC30 */ { 0, 0, 0, 0, 0, 0 }, /* PC30 */
+ /* PC29 */ { 1, 1, 1, 0, 0, 0 }, /* SCC1 EN *CLSN */
+ /* PC28 */ { 0, 0, 0, 1, 0, 0 }, /* PC28 */
+ /* PC27 */ { 0, 0, 0, 1, 0, 0 }, /* PC27 */
+ /* PC26 */ { 0, 0, 0, 1, 0, 0 }, /* PC26 */
+ /* PC25 */ { 0, 0, 0, 1, 0, 0 }, /* PC25 */
+ /* PC24 */ { 0, 0, 0, 1, 0, 0 }, /* PC24 */
+ /* PC23 */ { 0, 1, 0, 1, 0, 0 }, /* ATMTFCLK */
+ /* PC22 */ { 0, 1, 0, 0, 0, 0 }, /* ATMRFCLK */
+ /* PC21 */ { 1, 1, 0, 0, 0, 0 }, /* SCC1 EN RXCLK */
+ /* PC20 */ { 1, 1, 0, 0, 0, 0 }, /* SCC1 EN TXCLK */
+ /* PC19 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII RX_CLK */
+ /* PC18 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII TX_CLK */
+ /* PC17 */ { 1, 0, 0, 1, 0, 0 }, /* PC17 MDC */
+ /* PC16 */ { 1, 0, 0, 0, 0, 0 }, /* PC16 MDIO*/
+ /* PC15 */ { 0, 0, 0, 1, 0, 0 }, /* PC15 */
+ /* PC14 */ { 1, 1, 0, 0, 0, 0 }, /* SCC1 EN *CD */
+ /* PC13 */ { 0, 0, 0, 1, 0, 0 }, /* PC13 */
+ /* PC12 */ { 0, 0, 0, 1, 0, 0 }, /* PC12 */
+ /* PC11 */ { 0, 0, 0, 1, 0, 0 }, /* PC11 */
+ /* PC10 */ { 0, 0, 0, 1, 0, 0 }, /* PC10 */
+ /* PC9 */ { 0, 0, 0, 1, 0, 0 }, /* PC9 */
+ /* PC8 */ { 0, 0, 0, 1, 0, 0 }, /* PC8 */
+ /* PC7 */ { 0, 0, 0, 1, 0, 0 }, /* PC7 */
+ /* PC6 */ { 0, 0, 0, 1, 0, 0 }, /* PC6 */
+ /* PC5 */ { 1, 1, 0, 1, 0, 0 }, /* PC5 SMC1 TXD */
+ /* PC4 */ { 1, 1, 0, 0, 0, 0 }, /* PC4 SMC1 RXD */
+ /* PC3 */ { 0, 0, 0, 1, 0, 0 }, /* PC3 */
+ /* PC2 */ { 0, 0, 0, 1, 0, 1 }, /* ENET FDE */
+ /* PC1 */ { 0, 0, 0, 1, 0, 0 }, /* ENET DSQE */
+ /* PC0 */ { 0, 0, 0, 1, 0, 0 }, /* ENET LBK */
+ },
+
+ /* Port D */
+ { /* conf ppar psor pdir podr pdat */
+ /* PD31 */ { 1, 1, 0, 0, 0, 0 }, /* SCC1 EN RxD */
+ /* PD30 */ { 1, 1, 1, 1, 0, 0 }, /* SCC1 EN TxD */
+ /* PD29 */ { 1, 1, 0, 1, 0, 0 }, /* SCC1 EN TENA */
+ /* PD28 */ { 0, 0, 0, 1, 0, 0 }, /* PD28 */
+ /* PD27 */ { 0, 0, 0, 1, 0, 0 }, /* PD27 */
+ /* PD26 */ { 0, 0, 0, 1, 0, 0 }, /* PD26 */
+ /* PD25 */ { 0, 0, 0, 1, 0, 0 }, /* PD25 */
+ /* PD24 */ { 0, 0, 0, 1, 0, 0 }, /* PD24 */
+ /* PD23 */ { 0, 0, 0, 1, 0, 0 }, /* PD23 */
+ /* PD22 */ { 0, 0, 0, 1, 0, 0 }, /* PD22 */
+ /* PD21 */ { 0, 0, 0, 1, 0, 0 }, /* PD21 */
+ /* PD20 */ { 0, 0, 0, 1, 0, 0 }, /* PD20 */
+ /* PD19 */ { 0, 0, 0, 1, 0, 0 }, /* PD19 */
+ /* PD18 */ { 0, 0, 0, 1, 0, 0 }, /* PD19 */
+ /* PD17 */ { 0, 1, 0, 0, 0, 0 }, /* FCC1 ATMRXPRTY */
+ /* PD16 */ { 0, 1, 0, 1, 0, 0 }, /* FCC1 ATMTXPRTY */
+#if defined(CONFIG_SOFT_I2C)
+ /* PD15 */ { 1, 0, 0, 1, 1, 1 }, /* I2C SDA */
+ /* PD14 */ { 1, 0, 0, 1, 1, 1 }, /* I2C SCL */
+#else
+#if defined(CONFIG_HARD_I2C)
+ /* PD15 */ { 1, 1, 1, 0, 1, 0 }, /* I2C SDA */
+ /* PD14 */ { 1, 1, 1, 0, 1, 0 }, /* I2C SCL */
+#else /* normal I/O port pins */
+ /* PD15 */ { 0, 1, 1, 0, 1, 0 }, /* I2C SDA */
+ /* PD14 */ { 0, 1, 1, 0, 1, 0 }, /* I2C SCL */
+#endif
+#endif
+ /* PD13 */ { 0, 0, 0, 0, 0, 0 }, /* PD13 */
+ /* PD12 */ { 0, 0, 0, 0, 0, 0 }, /* PD12 */
+ /* PD11 */ { 0, 0, 0, 0, 0, 0 }, /* PD11 */
+ /* PD10 */ { 0, 0, 0, 0, 0, 0 }, /* PD10 */
+ /* PD9 */ { 1, 1, 0, 1, 0, 0 }, /* SMC1 TXD */
+ /* PD8 */ { 1, 1, 0, 0, 0, 0 }, /* SMC1 RXD */
+ /* PD7 */ { 0, 0, 0, 1, 0, 1 }, /* PD7 */
+ /* PD6 */ { 0, 0, 0, 1, 0, 1 }, /* PD6 */
+ /* PD5 */ { 0, 0, 0, 1, 0, 0 }, /* PD5 */
+ /* PD4 */ { 0, 0, 0, 1, 0, 1 }, /* PD4 */
+ /* PD3 */ { 0, 0, 0, 0, 0, 0 }, /* pin doesn't exist */
+ /* PD2 */ { 0, 0, 0, 0, 0, 0 }, /* pin doesn't exist */
+ /* PD1 */ { 0, 0, 0, 0, 0, 0 }, /* pin doesn't exist */
+ /* PD0 */ { 0, 0, 0, 0, 0, 0 } /* pin doesn't exist */
+ }
+};
+
+#define _NOT_USED_ 0xFFFFFFFF
+
+/* UPM pattern for bus clock = 66.7 MHz */
+static const uint upmTable67[] =
+{
+ /* Offset UPM Read Single RAM array entry -> NAND Read Data */
+ /* 0x00 */ 0x0fa3f100, 0x0fa3b000, 0x0fa33100, 0x0fa33000,
+ /* 0x04 */ 0x0fa33000, 0x0fa33004, 0xfffffc01, 0xfffffc00,
+
+ /* UPM Read Burst RAM array entry -> unused */
+ /* 0x08 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
+ /* 0x0C */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
+
+ /* UPM Read Burst RAM array entry -> unused */
+ /* 0x10 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
+ /* 0x14 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
+
+ /* UPM Write Single RAM array entry -> NAND Write Data, ADDR and CMD */
+ /* 0x18 */ 0x00a3fc00, 0x00a3fc00, 0x00a3fc00, 0x00a3fc00,
+ /* 0x1C */ 0x0fa3fc00, 0x0fa3fc04, 0xfffffc01, 0xfffffc00,
+
+ /* UPM Write Burst RAM array entry -> unused */
+ /* 0x20 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
+ /* 0x24 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
+ /* 0x28 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
+ /* 0x2C */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01,
+
+ /* UPM Refresh Timer RAM array entry -> unused */
+ /* 0x30 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
+ /* 0x34 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
+ /* 0x38 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01,
+
+ /* UPM Exception RAM array entry -> unsused */
+ /* 0x3C */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01,
+};
+
+/* UPM pattern for bus clock = 100 MHz */
+static const uint upmTable100[] =
+{
+ /* Offset UPM Read Single RAM array entry -> NAND Read Data */
+ /* 0x00 */ 0x0fa3f200, 0x0fa3b000, 0x0fa33300, 0x0fa33000,
+ /* 0x04 */ 0x0fa33000, 0x0fa33004, 0xfffffc01, 0xfffffc00,
+
+ /* UPM Read Burst RAM array entry -> unused */
+ /* 0x08 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
+ /* 0x0C */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
+
+ /* UPM Read Burst RAM array entry -> unused */
+ /* 0x10 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
+ /* 0x14 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
+
+ /* UPM Write Single RAM array entry -> NAND Write Data, ADDR and CMD */
+ /* 0x18 */ 0x00a3ff00, 0x00a3fc00, 0x00a3fc00, 0x0fa3fc00,
+ /* 0x1C */ 0x0fa3fc00, 0x0fa3fc04, 0xfffffc01, 0xfffffc00,
+
+ /* UPM Write Burst RAM array entry -> unused */
+ /* 0x20 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
+ /* 0x24 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
+ /* 0x28 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
+ /* 0x2C */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01,
+
+ /* UPM Refresh Timer RAM array entry -> unused */
+ /* 0x30 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
+ /* 0x34 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
+ /* 0x38 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01,
+
+ /* UPM Exception RAM array entry -> unsused */
+ /* 0x3C */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01,
+};
+
+/* UPM pattern for bus clock = 133.3 MHz */
+static const uint upmTable133[] =
+{
+ /* Offset UPM Read Single RAM array entry -> NAND Read Data */
+ /* 0x00 */ 0x0fa3f300, 0x0fa3b000, 0x0fa33300, 0x0fa33000,
+ /* 0x04 */ 0x0fa33200, 0x0fa33004, 0xfffffc01, 0xfffffc00,
+
+ /* UPM Read Burst RAM array entry -> unused */
+ /* 0x08 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
+ /* 0x0C */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
+
+ /* UPM Read Burst RAM array entry -> unused */
+ /* 0x10 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
+ /* 0x14 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
+
+ /* UPM Write Single RAM array entry -> NAND Write Data, ADDR and CMD */
+ /* 0x18 */ 0x00a3ff00, 0x00a3fc00, 0x00a3fd00, 0x0fa3fc00,
+ /* 0x1C */ 0x0fa3fd00, 0x0fa3fc04, 0xfffffc01, 0xfffffc00,
+
+ /* UPM Write Burst RAM array entry -> unused */
+ /* 0x20 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
+ /* 0x24 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
+ /* 0x28 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
+ /* 0x2C */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01,
+
+ /* UPM Refresh Timer RAM array entry -> unused */
+ /* 0x30 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
+ /* 0x34 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
+ /* 0x38 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01,
+
+ /* UPM Exception RAM array entry -> unsused */
+ /* 0x3C */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01,
+};
+
+static int chipsel = 0;
+
+/* UPM pattern for slow init */
+static const uint upmTableSlow[] =
+{
+ /* Offset UPM Read Single RAM array entry */
+ /* 0x00 */ 0xffffee00, 0x00ffcc80, 0x00ffcf00, 0x00ffdc00,
+ /* 0x04 */ 0x00ffce80, 0x00ffcc00, 0x00ffee00, 0x3fffcc07,
+
+ /* UPM Read Burst RAM array entry -> unused */
+ /* 0x08 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
+ /* 0x0C */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
+
+ /* UPM Read Burst RAM array entry -> unused */
+ /* 0x10 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
+ /* 0x14 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
+
+ /* UPM Write Single RAM array entry */
+ /* 0x18 */ 0xffffee00, 0x00ffec80, 0x00ffef00, 0x00fffc80,
+ /* 0x1C */ 0x00fffe00, 0x00ffec00, 0x0fffef00, 0x3fffec05,
+
+ /* UPM Write Burst RAM array entry -> unused */
+ /* 0x20 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
+ /* 0x24 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
+ /* 0x28 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
+ /* 0x2C */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01,
+
+ /* UPM Refresh Timer RAM array entry -> unused */
+ /* 0x30 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
+ /* 0x34 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
+ /* 0x38 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01,
+
+ /* UPM Exception RAM array entry -> unused */
+ /* 0x3C */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01,
+};
+
+/* UPM pattern for fast init */
+static const uint upmTableFast[] =
+{
+ /* Offset UPM Read Single RAM array entry */
+ /* 0x00 */ 0xffffee00, 0x00ffcc80, 0x00ffcd80, 0x00ffdc00,
+ /* 0x04 */ 0x00ffdc00, 0x00ffcf00, 0x00ffec00, 0x3fffcc07,
+
+ /* UPM Read Burst RAM array entry -> unused */
+ /* 0x08 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
+ /* 0x0C */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
+
+ /* UPM Read Burst RAM array entry -> unused */
+ /* 0x10 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
+ /* 0x14 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
+
+ /* UPM Write Single RAM array entry */
+ /* 0x18 */ 0xffffee00, 0x00ffec80, 0x00ffee80, 0x00fffc00,
+ /* 0x1C */ 0x00fffc00, 0x00ffec00, 0x0fffef00, 0x3fffec05,
+
+ /* UPM Write Burst RAM array entry -> unused */
+ /* 0x20 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
+ /* 0x24 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
+ /* 0x28 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
+ /* 0x2C */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01,
+
+ /* UPM Refresh Timer RAM array entry -> unused */
+ /* 0x30 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
+ /* 0x34 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
+ /* 0x38 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01,
+
+ /* UPM Exception RAM array entry -> unused */
+ /* 0x3C */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01,
+};
+
+
+/* ------------------------------------------------------------------------- */
+
+/* Check Board Identity:
+ */
+int checkboard (void)
+{
+ char *p = (char *) HWIB_INFO_START_ADDR;
+
+ puts ("Board: ");
+ if (*((unsigned long *)p) == (unsigned long)CFG_HWINFO_MAGIC) {
+ puts (p);
+ } else {
+ puts ("No HWIB assuming TQM8272");
+ }
+ putc ('\n');
+
+ return 0;
+}
+
+/* ------------------------------------------------------------------------- */
+#if defined(CONFIG_BOARD_GET_CPU_CLK_F)
+static int get_cas_latency (void)
+{
+ /* get it from the option -ts in CIB */
+ /* default is 3 */
+ int ret = 3;
+ int pos = 0;
+ char *p = (char *) CIB_INFO_START_ADDR;
+
+ while ((*p != '\0') && (pos < CIB_INFO_LEN)) {
+ if (*p < ' ' || *p > '~') { /* ASCII strings! */
+ return ret;
+ }
+ if (*p == '-') {
+ if ((p[1] == 't') && (p[2] == 's')) {
+ return (p[4] - '0');
+ }
+ }
+ p++;
+ pos++;
+ }
+ return ret;
+}
+#endif
+
+static ulong set_sdram_timing (volatile uint *sdmr_ptr, ulong sdmr, int col)
+{
+#if defined(CONFIG_BOARD_GET_CPU_CLK_F)
+ int clk = board_get_cpu_clk_f ();
+ volatile immap_t *immr = (immap_t *)CFG_IMMR;
+ int busmode = (immr->im_siu_conf.sc_bcr & BCR_EBM ? 1 : 0);
+ int cas;
+
+ sdmr = sdmr & ~(PSDMR_RFRC_MSK | PSDMR_PRETOACT_MSK | PSDMR_WRC_MSK | \
+ PSDMR_BUFCMD);
+ if (busmode) {
+ switch (clk) {
+ case 66666666:
+ sdmr |= (PSDMR_RFRC_66MHZ_60X | \
+ PSDMR_PRETOACT_66MHZ_60X | \
+ PSDMR_WRC_66MHZ_60X | \
+ PSDMR_BUFCMD_66MHZ_60X);
+ break;
+ case 100000000:
+ sdmr |= (PSDMR_RFRC_100MHZ_60X | \
+ PSDMR_PRETOACT_100MHZ_60X | \
+ PSDMR_WRC_100MHZ_60X | \
+ PSDMR_BUFCMD_100MHZ_60X);
+ break;
+
+ }
+ } else {
+ switch (clk) {
+ case 66666666:
+ sdmr |= (PSDMR_RFRC_66MHZ_SINGLE | \
+ PSDMR_PRETOACT_66MHZ_SINGLE | \
+ PSDMR_WRC_66MHZ_SINGLE | \
+ PSDMR_BUFCMD_66MHZ_SINGLE);
+ break;
+ case 100000000:
+ sdmr |= (PSDMR_RFRC_100MHZ_SINGLE | \
+ PSDMR_PRETOACT_100MHZ_SINGLE | \
+ PSDMR_WRC_100MHZ_SINGLE | \
+ PSDMR_BUFCMD_100MHZ_SINGLE);
+ break;
+ case 133333333:
+ sdmr |= (PSDMR_RFRC_133MHZ_SINGLE | \
+ PSDMR_PRETOACT_133MHZ_SINGLE | \
+ PSDMR_WRC_133MHZ_SINGLE | \
+ PSDMR_BUFCMD_133MHZ_SINGLE);
+ break;
+ }
+ }
+ cas = get_cas_latency();
+ sdmr &=~ (PSDMR_CL_MSK | PSDMR_LDOTOPRE_MSK);
+ sdmr |= cas;
+ sdmr |= ((cas - 1) << 6);
+ return sdmr;
+#else
+ return sdmr;
+#endif
+}
+
+/* Try SDRAM initialization with P/LSDMR=sdmr and ORx=orx
+ *
+ * This routine performs standard 8260 initialization sequence
+ * and calculates the available memory size. It may be called
+ * several times to try different SDRAM configurations on both
+ * 60x and local buses.
+ */
+static long int try_init (volatile memctl8260_t * memctl, ulong sdmr,
+ ulong orx, volatile uchar * base, int col)
+{
+ volatile uchar c = 0xff;
+ volatile uint *sdmr_ptr;
+ volatile uint *orx_ptr;
+ ulong maxsize, size;
+ int i;
+
+ /* We must be able to test a location outsize the maximum legal size
+ * to find out THAT we are outside; but this address still has to be
+ * mapped by the controller. That means, that the initial mapping has
+ * to be (at least) twice as large as the maximum expected size.
+ */
+ maxsize = (1 + (~orx | 0x7fff)) / 2;
+
+ /* Since CFG_SDRAM_BASE is always 0 (??), we assume that
+ * we are configuring CS1 if base != 0
+ */
+ sdmr_ptr = base ? &memctl->memc_lsdmr : &memctl->memc_psdmr;
+ orx_ptr = base ? &memctl->memc_or2 : &memctl->memc_or1;
+
+ *orx_ptr = orx;
+ sdmr = set_sdram_timing (sdmr_ptr, sdmr, col);
+ /*
+ * Quote from 8260 UM (10.4.2 SDRAM Power-On Initialization, 10-35):
+ *
+ * "At system reset, initialization software must set up the
+ * programmable parameters in the memory controller banks registers
+ * (ORx, BRx, P/LSDMR). After all memory parameters are configured,
+ * system software should execute the following initialization sequence
+ * for each SDRAM device.
+ *
+ * 1. Issue a PRECHARGE-ALL-BANKS command
+ * 2. Issue eight CBR REFRESH commands
+ * 3. Issue a MODE-SET command to initialize the mode register
+ *
+ * The initial commands are executed by setting P/LSDMR[OP] and
+ * accessing the SDRAM with a single-byte transaction."
+ *
+ * The appropriate BRx/ORx registers have already been set when we
+ * get here. The SDRAM can be accessed at the address CFG_SDRAM_BASE.
+ */
+
+ *sdmr_ptr = sdmr | PSDMR_OP_PREA;
+ *base = c;
+
+ *sdmr_ptr = sdmr | PSDMR_OP_CBRR;
+ for (i = 0; i < 8; i++)
+ *base = c;
+
+ *sdmr_ptr = sdmr | PSDMR_OP_MRW;
+ *(base + CFG_MRS_OFFS) = c; /* setting MR on address lines */
+
+ *sdmr_ptr = sdmr | PSDMR_OP_NORM | PSDMR_RFEN;
+ *base = c;
+
+ size = get_ram_size((long *)base, maxsize);
+ *orx_ptr = orx | ~(size - 1);
+
+ return (size);
+}
+
+long int initdram (int board_type)
+{
+ volatile immap_t *immap = (immap_t *) CFG_IMMR;
+ volatile memctl8260_t *memctl = &immap->im_memctl;
+
+#ifndef CFG_RAMBOOT
+ long size8, size9;
+#endif
+ long psize, lsize;
+
+ psize = 16 * 1024 * 1024;
+ lsize = 0;
+
+ memctl->memc_psrt = CFG_PSRT;
+ memctl->memc_mptpr = CFG_MPTPR;
+
+#ifndef CFG_RAMBOOT
+ /* 60x SDRAM setup:
+ */
+ size8 = try_init (memctl, CFG_PSDMR_8COL, CFG_OR1_8COL,
+ (uchar *) CFG_SDRAM_BASE, 8);
+ size9 = try_init (memctl, CFG_PSDMR_9COL, CFG_OR1_9COL,
+ (uchar *) CFG_SDRAM_BASE, 9);
+
+ if (size8 < size9) {
+ psize = size9;
+ printf ("(60x:9COL - %ld MB, ", psize >> 20);
+ } else {
+ psize = try_init (memctl, CFG_PSDMR_8COL, CFG_OR1_8COL,
+ (uchar *) CFG_SDRAM_BASE, 8);
+ printf ("(60x:8COL - %ld MB, ", psize >> 20);
+ }
+
+#endif /* CFG_RAMBOOT */
+
+ icache_enable ();
+
+ return (psize);
+}
+
+
+static inline int scanChar (char *p, int len, unsigned long *number)
+{
+ int akt = 0;
+
+ *number = 0;
+ while (akt < len) {
+ if ((*p >= '0') && (*p <= '9')) {
+ *number *= 10;
+ *number += *p - '0';
+ p += 1;
+ } else {
+ if (*p == '-') return akt;
+ return -1;
+ }
+ akt ++;
+ }
+ return akt;
+}
+
+typedef struct{
+ int Bus;
+ int flash;
+ int flash_nr;
+ int ram;
+ int ram_cs;
+ int nand;
+ int nand_cs;
+ int eeprom;
+ int can;
+ unsigned long cpunr;
+ unsigned long option;
+ int SecEng;
+ int cpucl;
+ int cpmcl;
+ int buscl;
+ int busclk_real_ok;
+ int busclk_real;
+ unsigned char OK;
+ unsigned char ethaddr[20];
+} HWIB_INFO;
+
+HWIB_INFO hwinf = {0, 0, 1, 0, 1, 0, 0, 0, 0, 8272, 0 ,0,
+ 0, 0, 0, 0, 0, 0};
+
+static int dump_hwib(void)
+{
+ HWIB_INFO *hw = &hwinf;
+ volatile immap_t *immr = (immap_t *)CFG_IMMR;
+ char *s = getenv("serial#");
+
+ if (hw->OK) {
+ printf ("HWIB on %x\n", HWIB_INFO_START_ADDR);
+ printf ("serial : %s\n", s);
+ printf ("ethaddr: %s\n", hw->ethaddr);
+ printf ("FLASH : %x nr:%d\n", hw->flash, hw->flash_nr);
+ printf ("RAM : %x cs:%d\n", hw->ram, hw->ram_cs);
+ printf ("CPU : %d\n", hw->cpunr);
+ printf ("CAN : %d\n", hw->can);
+ if (hw->eeprom) printf ("EEprom : %x\n", hw->eeprom);
+ else printf ("No EEprom\n");
+ if (hw->nand) {
+ printf ("NAND : %x\n", hw->nand);
+ printf ("NAND CS: %d\n", hw->nand_cs);
+ } else { printf ("No NAND\n");}
+ printf ("Bus %s mode.\n", (hw->Bus ? "60x" : "Single PQII"));
+ printf (" real : %s\n", (immr->im_siu_conf.sc_bcr & BCR_EBM ? \
+ "60x" : "Single PQII"));
+ printf ("Option : %x\n", hw->option);
+ printf ("%s Security Engine\n", (hw->SecEng ? "with" : "no"));
+ printf ("CPM Clk: %d\n", hw->cpmcl);
+ printf ("CPU Clk: %d\n", hw->cpucl);
+ printf ("Bus Clk: %d\n", hw->buscl);
+ if (hw->busclk_real_ok) {
+ printf (" real Clk: %d\n", hw->busclk_real);
+ }
+ printf ("CAS : %d\n", get_cas_latency());
+ } else {
+ printf("HWIB @%x not OK\n", HWIB_INFO_START_ADDR);
+ }
+ return 0;
+}
+
+static inline int search_real_busclk (int *clk)
+{
+ int part = 0, pos = 0;
+ char *p = (char *) CIB_INFO_START_ADDR;
+ int ok = 0;
+
+ while ((*p != '\0') && (pos < CIB_INFO_LEN)) {
+ if (*p < ' ' || *p > '~') { /* ASCII strings! */
+ return 0;
+ }
+ switch (part) {
+ default:
+ if (*p == '-') {
+ ++part;
+ }
+ break;
+ case 3:
+ if (*p == '-') {
+ ++part;
+ break;
+ }
+ if (*p == 'b') {
+ ok = 1;
+ p++;
+ break;
+ }
+ if (ok) {
+ switch (*p) {
+ case '6':
+ *clk = 66666666;
+ return 1;
+ break;
+ case '1':
+ if (p[1] == '3') {
+ *clk = 133333333;
+ } else {
+ *clk = 100000000;
+ }
+ return 1;
+ break;
+ }
+ }
+ break;
+ }
+ p++;
+ }
+ return 0;
+}
+
+int analyse_hwib (void)
+{
+ char *p = (char *) HWIB_INFO_START_ADDR;
+ int anz;
+ int part = 1, i = 0, pos = 0;
+ HWIB_INFO *hw = &hwinf;
+
+ deb_printf(" %s pointer: %p\n", __FUNCTION__, p);
+ /* Head = TQM */
+ if (*((unsigned long *)p) != (unsigned long)CFG_HWINFO_MAGIC) {
+ deb_printf("No HWIB\n");
+ return -1;
+ }
+ p += 3;
+ if (scanChar (p, 4, &hw->cpunr) < 0) {
+ deb_printf("No CPU\n");
+ return -2;
+ }
+ p +=4;
+
+ hw->flash = 0x200000 << (*p - 'A');
+ p++;
+ hw->flash_nr = *p - '0';
+ p++;
+
+ hw->ram = 0x2000000 << (*p - 'A');
+ p++;
+ if (*p == '2') {
+ hw->ram_cs = 2;
+ p++;
+ }
+
+ if (*p == 'A') hw->can = 1;
+ if (*p == 'B') hw->can = 2;
+ p +=1;
+ p +=1; /* connector */
+ if (*p != '0') {
+ hw->eeprom = 0x1000 << (*p - 'A');
+ }
+ p++;
+
+ if ((*p < '0') || (*p > '9')) {
+ /* NAND before z-option */
+ hw->nand = 0x8000000 << (*p - 'A');
+ p++;
+ hw->nand_cs = *p - '0';
+ p += 2;
+ }
+ /* z-option */
+ anz = scanChar (p, 4, &hw->option);
+ if (anz < 0) {
+ deb_printf("No option\n");
+ return -3;
+ }
+ if (hw->option & 0x8) hw->Bus = 1;
+ p += anz;
+ if (*p != '-') {
+ deb_printf("No -\n");
+ return -4;
+ }
+ p++;
+ /* C option */
+ if (*p == 'E') {
+ hw->SecEng = 1;
+ p++;
+ }
+ switch (*p) {
+ case 'M': hw->cpucl = 266666666;
+ break;
+ case 'P': hw->cpucl = 300000000;
+ break;
+ case 'T': hw->cpucl = 400000000;
+ break;
+ default:
+ deb_printf("No CPU Clk: %c\n", *p);
+ return -5;
+ break;
+ }
+ p++;
+ switch (*p) {
+ case 'I': hw->cpmcl = 200000000;
+ break;
+ case 'M': hw->cpmcl = 300000000;
+ break;
+ default:
+ deb_printf("No CPM Clk\n");
+ return -6;
+ break;
+ }
+ p++;
+ switch (*p) {
+ case 'B': hw->buscl = 66666666;
+ break;
+ case 'E': hw->buscl = 100000000;
+ break;
+ case 'F': hw->buscl = 133333333;
+ break;
+ default:
+ deb_printf("No BUS Clk\n");
+ return -7;
+ break;
+ }
+ p++;
+
+ hw->OK = 1;
+ /* search MAC Address */
+ while ((*p != '\0') && (pos < CFG_HWINFO_SIZE)) {
+ if (*p < ' ' || *p > '~') { /* ASCII strings! */
+ return 0;
+ }
+ switch (part) {
+ default:
+ if (*p == ' ') {
+ ++part;
+ i = 0;
+ }
+ break;
+ case 3: /* Copy MAC address */
+ if (*p == ' ') {
+ ++part;
+ i = 0;
+ break;
+ }
+ hw->ethaddr[i++] = *p;
+ if ((i % 3) == 2)
+ hw->ethaddr[i++] = ':';
+ break;
+
+ }
+ p++;
+ }
+
+ hw->busclk_real_ok = search_real_busclk (&hw->busclk_real);
+ return 0;
+}
+
+#if defined(CONFIG_GET_CPU_STR_F)
+/* !! This routine runs from Flash */
+char get_cpu_str_f (char *buf)
+{
+ char *p = (char *) HWIB_INFO_START_ADDR;
+ int i = 0;
+
+ buf[i++] = 'M';
+ buf[i++] = 'P';
+ buf[i++] = 'C';
+ if (*((unsigned long *)p) == (unsigned long)CFG_HWINFO_MAGIC) {
+ buf[i++] = *&p[3];
+ buf[i++] = *&p[4];
+ buf[i++] = *&p[5];
+ buf[i++] = *&p[6];
+ } else {
+ buf[i++] = '8';
+ buf[i++] = '2';
+ buf[i++] = '7';
+ buf[i++] = 'x';
+ }
+ buf[i++] = 0;
+ return 0;
+}
+#endif
+
+#if defined(CONFIG_BOARD_GET_CPU_CLK_F)
+/* !! This routine runs from Flash */
+unsigned long board_get_cpu_clk_f (void)
+{
+ char *p = (char *) HWIB_INFO_START_ADDR;
+ int i = 0;
+
+ if (*((unsigned long *)p) == (unsigned long)CFG_HWINFO_MAGIC) {
+ if (search_real_busclk (&i))
+ return i;
+ }
+ return CONFIG_8260_CLKIN;
+}
+#endif
+
+#if CONFIG_BOARD_EARLY_INIT_R
+
+static int can_test (unsigned long off)
+{
+ volatile unsigned char *base = (unsigned char *) (CFG_CAN_BASE + off);
+
+ *(base + 0x17) = 'T';
+ *(base + 0x18) = 'Q';
+ *(base + 0x19) = 'M';
+ if ((*(base + 0x17) != 'T') ||
+ (*(base + 0x18) != 'Q') ||
+ (*(base + 0x19) != 'M')) {
+ return 0;
+ }
+ return 1;
+}
+
+static int can_config_one (unsigned long off)
+{
+ volatile unsigned char *ctrl = (unsigned char *) (CFG_CAN_BASE + off);
+ volatile unsigned char *cpu_if = (unsigned char *) (CFG_CAN_BASE + off + 0x02);
+ volatile unsigned char *clkout = (unsigned char *) (CFG_CAN_BASE + off + 0x1f);
+ unsigned char temp;
+
+ *cpu_if = 0x45;
+ temp = *ctrl;
+ temp |= 0x40;
+ *ctrl = temp;
+ *clkout = 0x20;
+ temp = *ctrl;
+ temp &= ~0x40;
+ *ctrl = temp;
+ return 0;
+}
+
+static int can_config (void)
+{
+ int ret = 0;
+ can_config_one (0);
+ if (hwinf.can == 2) {
+ can_config_one (0x100);
+ }
+ /* make Test if they really there */
+ ret += can_test (0);
+ ret += can_test (0x100);
+ return ret;
+}
+
+static int init_can (void)
+{
+ volatile immap_t * immr = (immap_t *)CFG_IMMR;
+ volatile memctl8260_t *memctl = &immr->im_memctl;
+ int count = 0;
+
+ if ((hwinf.OK) && (hwinf.can)) {
+ memctl->memc_or4 = CFG_CAN_OR;
+ memctl->memc_br4 = CFG_CAN_BR;
+ /* upm Init */
+ upmconfig (UPMC, (uint *) upmTableFast,
+ sizeof (upmTableFast) / sizeof (uint));
+ memctl->memc_mcmr = (MxMR_DSx_3_CYCL |
+ MxMR_GPL_x4DIS |
+ MxMR_RLFx_2X |
+ MxMR_WLFx_2X |
+ MxMR_OP_NORM);
+ /* can configure */
+ count = can_config ();
+ printf ("CAN: %d @ %x\n", count, CFG_CAN_BASE);
+ if (hwinf.can != count) printf("!!! difference to HWIB\n");
+ } else {
+ printf ("CAN: No\n");
+ }
+ return 0;
+}
+
+int board_early_init_r(void)
+{
+ analyse_hwib ();
+ init_can ();
+ return 0;
+}
+#endif
+
+int do_hwib_dump (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
+{
+ dump_hwib ();
+ return 0;
+}
+
+U_BOOT_CMD(
+ hwib, 1, 1, do_hwib_dump,
+ "hwib - dump HWIB'\n",
+ "\n"
+);
+
+#ifdef CFG_UPDATE_FLASH_SIZE
+static int get_flash_timing (void)
+{
+ /* get it from the option -tf in CIB */
+ /* default is 0x00000c84 */
+ int ret = 0x00000c84;
+ int pos = 0;
+ int nr = 0;
+ char *p = (char *) CIB_INFO_START_ADDR;
+
+ while ((*p != '\0') && (pos < CIB_INFO_LEN)) {
+ if (*p < ' ' || *p > '~') { /* ASCII strings! */
+ return ret;
+ }
+ if (*p == '-') {
+ if ((p[1] == 't') && (p[2] == 'f')) {
+ p += 6;
+ ret = 0;
+ while (nr < 8) {
+ if ((*p >= '0') && (*p <= '9')) {
+ ret *= 0x10;
+ ret += *p - '0';
+ p += 1;
+ nr ++;
+ } else if ((*p >= 'A') && (*p <= 'F')) {
+ ret *= 10;
+ ret += *p - '7';
+ p += 1;
+ nr ++;
+ } else {
+ if (nr < 8) return 0x00000c84;
+ return ret;
+ }
+ }
+ }
+ }
+ p++;
+ pos++;
+ }
+ return ret;
+}
+
+/* Update the Flash_Size and the Flash Timing */
+int update_flash_size (int flash_size)
+{
+ volatile immap_t * immr = (immap_t *)CFG_IMMR;
+ volatile memctl8260_t *memctl = &immr->im_memctl;
+ unsigned long reg;
+ unsigned long tim;
+
+ /* I must use reg, otherwise the board hang */
+ reg = memctl->memc_or0;
+ reg &= ~ORxU_AM_MSK;
+ reg |= MEG_TO_AM(flash_size >> 20);
+ tim = get_flash_timing ();
+ reg &= ~0xfff;
+ reg |= (tim & 0xfff);
+ memctl->memc_or0 = reg;
+ return 0;
+}
+#endif
+
+#if (CONFIG_COMMANDS & CFG_CMD_NAND)
+
+#include <nand.h>
+#include <linux/mtd/mtd.h>
+
+static u8 hwctl = 0;
+
+static void upmnand_hwcontrol(struct mtd_info *mtdinfo, int cmd)
+{
+ switch (cmd) {
+ case NAND_CTL_SETCLE:
+ hwctl |= 0x1;
+ break;
+ case NAND_CTL_CLRCLE:
+ hwctl &= ~0x1;
+ break;
+
+ case NAND_CTL_SETALE:
+ hwctl |= 0x2;
+ break;
+
+ case NAND_CTL_CLRALE:
+ hwctl &= ~0x2;
+ break;
+ }
+}
+
+static void upmnand_write_byte(struct mtd_info *mtdinfo, u_char byte)
+{
+ struct nand_chip *this = mtdinfo->priv;
+ ulong base = (ulong) (this->IO_ADDR_W + chipsel * CFG_NAND_CS_DIST);
+
+ if (hwctl & 0x1) {
+ WRITE_NAND_UPM(byte, base, CFG_NAND_UPM_WRITE_CMD_OFS);
+ } else if (hwctl & 0x2) {
+ WRITE_NAND_UPM(byte, base, CFG_NAND_UPM_WRITE_ADDR_OFS);
+ } else {
+ WRITE_NAND(byte, base);
+ }
+}
+
+static u_char upmnand_read_byte(struct mtd_info *mtdinfo)
+{
+ struct nand_chip *this = mtdinfo->priv;
+ ulong base = (ulong) (this->IO_ADDR_W + chipsel * CFG_NAND_CS_DIST);
+
+ return READ_NAND(base);
+}
+
+static int tqm8272_dev_ready(struct mtd_info *mtdinfo)
+{
+ /* constant delay (see also tR in the datasheet) */
+ udelay(12); \
+ return 1;
+}
+
+#ifndef CONFIG_NAND_SPL
+static void tqm8272_read_buf(struct mtd_info *mtdinfo, uint8_t *buf, int len)
+{
+ struct nand_chip *this = mtdinfo->priv;
+ unsigned char *base = (unsigned char *) (this->IO_ADDR_W + chipsel * CFG_NAND_CS_DIST);
+ int i;
+
+ for (i = 0; i< len; i++)
+ buf[i] = *base;
+}
+
+static void tqm8272_write_buf(struct mtd_info *mtdinfo, const uint8_t *buf, int len)
+{
+ struct nand_chip *this = mtdinfo->priv;
+ unsigned char *base = (unsigned char *) (this->IO_ADDR_W + chipsel * CFG_NAND_CS_DIST);
+ int i;
+
+ for (i = 0; i< len; i++)
+ *base = buf[i];
+}
+
+static int tqm8272_verify_buf(struct mtd_info *mtdinfo, const uint8_t *buf, int len)
+{
+ struct nand_chip *this = mtdinfo->priv;
+ unsigned char *base = (unsigned char *) (this->IO_ADDR_W + chipsel * CFG_NAND_CS_DIST);
+ int i;
+
+ for (i = 0; i < len; i++)
+ if (buf[i] != *base)
+ return -1;
+ return 0;
+}
+#endif /* #ifndef CONFIG_NAND_SPL */
+
+void board_nand_select_device(struct nand_chip *nand, int chip)
+{
+ chipsel = chip;
+}
+
+int board_nand_init(struct nand_chip *nand)
+{
+ static int UpmInit = 0;
+ volatile immap_t * immr = (immap_t *)CFG_IMMR;
+ volatile memctl8260_t *memctl = &immr->im_memctl;
+
+ if (hwinf.nand == 0) return -1;
+
+ /* Setup the UPM */
+ if (UpmInit == 0) {
+ switch (hwinf.busclk_real) {
+ case 100000000:
+ upmconfig (UPMB, (uint *) upmTable100,
+ sizeof (upmTable100) / sizeof (uint));
+ break;
+ case 133333333:
+ upmconfig (UPMB, (uint *) upmTable133,
+ sizeof (upmTable133) / sizeof (uint));
+ break;
+ default:
+ upmconfig (UPMB, (uint *) upmTable67,
+ sizeof (upmTable67) / sizeof (uint));
+ break;
+ }
+ UpmInit = 1;
+ }
+
+ /* Setup the memctrl */
+ memctl->memc_or3 = CFG_NAND_OR;
+ memctl->memc_br3 = CFG_NAND_BR;
+ memctl->memc_mbmr = (MxMR_OP_NORM);
+
+ nand->eccmode = NAND_ECC_SOFT;
+
+ nand->hwcontrol = upmnand_hwcontrol;
+ nand->read_byte = upmnand_read_byte;
+ nand->write_byte = upmnand_write_byte;
+ nand->dev_ready = tqm8272_dev_ready;
+
+#ifndef CONFIG_NAND_SPL
+ nand->write_buf = tqm8272_write_buf;
+ nand->read_buf = tqm8272_read_buf;
+ nand->verify_buf = tqm8272_verify_buf;
+#endif
+
+ /*
+ * Select required NAND chip
+ */
+ board_nand_select_device(nand, 0);
+ return 0;
+}
+
+#endif /* CFG_CMD_NAND */
+
+#ifdef CONFIG_PCI
+struct pci_controller hose;
+
+int board_early_init_f (void)
+{
+ volatile immap_t *immap = (immap_t *) CFG_IMMR;
+
+ immap->im_clkrst.car_sccr |= M826X_SCCR_PCI_MODE_EN;
+ return 0;
+}
+
+extern void pci_mpc8250_init(struct pci_controller *);
+
+void pci_init_board(void)
+{
+ pci_mpc8250_init(&hose);
+}
+#endif
diff --git a/board/tqm8272/u-boot.lds b/board/tqm8272/u-boot.lds
new file mode 100644
index 00000000000..05f29c6ed08
--- /dev/null
+++ b/board/tqm8272/u-boot.lds
@@ -0,0 +1,126 @@
+/*
+ * (C) Copyright 2001
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+OUTPUT_ARCH(powerpc)
+SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/local/powerpc-any-elf/lib);
+/* Do we need any of these for elf?
+ __DYNAMIC = 0; */
+SECTIONS
+{
+ /* Read-only sections, merged into text segment: */
+ . = + SIZEOF_HEADERS;
+ .interp : { *(.interp) }
+ .hash : { *(.hash) }
+ .dynsym : { *(.dynsym) }
+ .dynstr : { *(.dynstr) }
+ .rel.text : { *(.rel.text) }
+ .rela.text : { *(.rela.text) }
+ .rel.data : { *(.rel.data) }
+ .rela.data : { *(.rela.data) }
+ .rel.rodata : { *(.rel.rodata) }
+ .rela.rodata : { *(.rela.rodata) }
+ .rel.got : { *(.rel.got) }
+ .rela.got : { *(.rela.got) }
+ .rel.ctors : { *(.rel.ctors) }
+ .rela.ctors : { *(.rela.ctors) }
+ .rel.dtors : { *(.rel.dtors) }
+ .rela.dtors : { *(.rela.dtors) }
+ .rel.bss : { *(.rel.bss) }
+ .rela.bss : { *(.rela.bss) }
+ .rel.plt : { *(.rel.plt) }
+ .rela.plt : { *(.rela.plt) }
+ .init : { *(.init) }
+ .plt : { *(.plt) }
+ .text :
+ {
+ cpu/mpc8260/start.o (.text)
+ *(.text)
+ common/environment.o(.text)
+ *(.fixup)
+ *(.got1)
+ . = ALIGN(16);
+ *(.rodata)
+ *(.rodata1)
+ *(.rodata.str1.4)
+ *(.eh_frame)
+ }
+ .fini : { *(.fini) } =0
+ .ctors : { *(.ctors) }
+ .dtors : { *(.dtors) }
+
+ /* Read-write section, merged into data segment: */
+ . = (. + 0x0FFF) & 0xFFFFF000;
+ _erotext = .;
+ PROVIDE (erotext = .);
+ .reloc :
+ {
+ *(.got)
+ _GOT2_TABLE_ = .;
+ *(.got2)
+ _FIXUP_TABLE_ = .;
+ *(.fixup)
+ }
+ __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >> 2;
+ __fixup_entries = (. - _FIXUP_TABLE_) >> 2;
+
+ .data :
+ {
+ *(.data)
+ *(.data1)
+ *(.sdata)
+ *(.sdata2)
+ *(.dynamic)
+ CONSTRUCTORS
+ }
+ _edata = .;
+ PROVIDE (edata = .);
+
+ . = .;
+ __u_boot_cmd_start = .;
+ .u_boot_cmd : { *(.u_boot_cmd) }
+ __u_boot_cmd_end = .;
+
+
+ . = .;
+ __start___ex_table = .;
+ __ex_table : { *(__ex_table) }
+ __stop___ex_table = .;
+
+ . = ALIGN(4096);
+ __init_begin = .;
+ .text.init : { *(.text.init) }
+ .data.init : { *(.data.init) }
+ . = ALIGN(4096);
+ __init_end = .;
+
+ __bss_start = .;
+ .bss :
+ {
+ *(.sbss) *(.scommon)
+ *(.dynbss)
+ *(.bss)
+ *(COMMON)
+ }
+ _end = . ;
+ PROVIDE (end = .);
+}
diff --git a/board/tqm834x/pci.c b/board/tqm834x/pci.c
index 5a23e6c55e9..d896f17aad0 100644
--- a/board/tqm834x/pci.c
+++ b/board/tqm834x/pci.c
@@ -69,17 +69,17 @@ void
pci_init_board(void)
{
volatile immap_t * immr;
- volatile clk8349_t * clk;
- volatile law8349_t * pci_law;
- volatile pot8349_t * pci_pot;
- volatile pcictrl8349_t * pci_ctrl;
- volatile pciconf8349_t * pci_conf;
+ volatile clk83xx_t * clk;
+ volatile law83xx_t * pci_law;
+ volatile pot83xx_t * pci_pot;
+ volatile pcictrl83xx_t * pci_ctrl;
+ volatile pciconf83xx_t * pci_conf;
u16 reg16;
u32 reg32;
struct pci_controller * hose;
- immr = (immap_t *)CFG_IMMRBAR;
- clk = (clk8349_t *)&immr->clk;
+ immr = (immap_t *)CFG_IMMR;
+ clk = (clk83xx_t *)&immr->clk;
pci_law = immr->sysconf.pcilaw;
pci_pot = immr->ios.pot;
pci_ctrl = immr->pci_ctrl;
@@ -186,8 +186,8 @@ pci_init_board(void)
hose->region_count = 3;
pci_setup_indirect(hose,
- (CFG_IMMRBAR+0x8300),
- (CFG_IMMRBAR+0x8304));
+ (CFG_IMMR+0x8300),
+ (CFG_IMMR+0x8304));
pci_register_hose(hose);
diff --git a/board/tqm834x/tqm834x.c b/board/tqm834x/tqm834x.c
index 41b34cc6fa4..9c35e22c8e1 100644
--- a/board/tqm834x/tqm834x.c
+++ b/board/tqm834x/tqm834x.c
@@ -69,7 +69,7 @@ static void set_cs_config(short cs, long config);
static void set_ddr_config(void);
/* Local variable */
-static volatile immap_t *im = (immap_t *)CFG_IMMRBAR;
+static volatile immap_t *im = (immap_t *)CFG_IMMR;
/**************************************************************************
* Board initialzation after relocation to RAM. Used to detect the number
@@ -147,15 +147,15 @@ int checkboard (void)
volatile immap_t * immr;
u32 w, f;
- immr = (immap_t *)CFG_IMMRBAR;
- if (!(immr->reset.rcwh & RCWH_PCIHOST)) {
+ immr = (immap_t *)CFG_IMMR;
+ if (!(immr->reset.rcwh & HRCWH_PCI_HOST)) {
printf("PCI: NOT in host mode..?!\n");
return 0;
}
/* get bus width */
w = 32;
- if (immr->reset.rcwh & RCWH_PCI64)
+ if (immr->reset.rcwh & HRCWH_64_BIT_PCI)
w = 64;
/* get clock */
diff --git a/board/trab/auto_update.c b/board/trab/auto_update.c
index 7684499c246..6f903d2b037 100644
--- a/board/trab/auto_update.c
+++ b/board/trab/auto_update.c
@@ -203,7 +203,6 @@ extern int flash_write (char *, ulong, ulong);
/* change char* to void* to shutup the compiler */
extern int i2c_write_multiple (uchar, uint, int, void *, int);
extern int i2c_read_multiple (uchar, uint, int, void *, int);
-extern block_dev_desc_t *get_dev (char*, int);
extern int u_boot_hush_start(void);
int
diff --git a/board/uc101/Makefile b/board/uc101/Makefile
new file mode 100644
index 00000000000..ddfd2ef8afe
--- /dev/null
+++ b/board/uc101/Makefile
@@ -0,0 +1,50 @@
+#
+# (C) Copyright 2003-2006
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+include $(TOPDIR)/config.mk
+
+LIB = $(obj)lib$(BOARD).a
+
+COBJS := $(BOARD).o
+
+SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(COBJS))
+SOBJS := $(addprefix $(obj),$(SOBJS))
+
+$(LIB): $(obj).depend $(OBJS)
+ $(AR) $(ARFLAGS) $@ $(OBJS)
+
+clean:
+ rm -f $(SOBJS) $(OBJS)
+
+distclean: clean
+ rm -f $(LIB) core *.bak .depend
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/board/uc101/config.mk b/board/uc101/config.mk
new file mode 100644
index 00000000000..51e8e84c5c3
--- /dev/null
+++ b/board/uc101/config.mk
@@ -0,0 +1,41 @@
+#
+# (C) Copyright 2004
+# 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
+#
+
+#
+# INKA 4X0 board:
+#
+# Valid values for TEXT_BASE are:
+#
+# 0xFFE00000 boot high
+#
+# 0x00100000 boot from RAM (for testing only)
+#
+
+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/uc101/u-boot.lds b/board/uc101/u-boot.lds
new file mode 100644
index 00000000000..123a14c5aa0
--- /dev/null
+++ b/board/uc101/u-boot.lds
@@ -0,0 +1,136 @@
+/*
+ * (C) Copyright 2003-2004
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+OUTPUT_ARCH(powerpc)
+SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/local/powerpc-any-elf/lib);
+/* Do we need any of these for elf?
+ __DYNAMIC = 0; */
+SECTIONS
+{
+ /* Read-only sections, merged into text segment: */
+ . = + SIZEOF_HEADERS;
+ .interp : { *(.interp) }
+ .hash : { *(.hash) }
+ .dynsym : { *(.dynsym) }
+ .dynstr : { *(.dynstr) }
+ .rel.text : { *(.rel.text) }
+ .rela.text : { *(.rela.text) }
+ .rel.data : { *(.rel.data) }
+ .rela.data : { *(.rela.data) }
+ .rel.rodata : { *(.rel.rodata) }
+ .rela.rodata : { *(.rela.rodata) }
+ .rel.got : { *(.rel.got) }
+ .rela.got : { *(.rela.got) }
+ .rel.ctors : { *(.rel.ctors) }
+ .rela.ctors : { *(.rela.ctors) }
+ .rel.dtors : { *(.rel.dtors) }
+ .rela.dtors : { *(.rela.dtors) }
+ .rel.bss : { *(.rel.bss) }
+ .rela.bss : { *(.rela.bss) }
+ .rel.plt : { *(.rel.plt) }
+ .rela.plt : { *(.rela.plt) }
+ .init : { *(.init) }
+ .plt : { *(.plt) }
+ .text :
+ {
+ /* WARNING - the following is hand-optimized to fit within */
+ /* the sector layout of our flash chips! XXX FIXME XXX */
+
+ cpu/mpc5xxx/start.o (.text)
+ cpu/mpc5xxx/traps.o (.text)
+ lib_generic/crc32.o (.text)
+ lib_ppc/cache.o (.text)
+ lib_ppc/time.o (.text)
+
+ . = DEFINED(env_offset) ? env_offset : .;
+ common/environment.o (.ppcenv)
+
+ *(.text)
+ *(.fixup)
+ *(.got1)
+ . = ALIGN(16);
+ *(.rodata)
+ *(.rodata1)
+ *(.rodata.str1.4)
+ *(.eh_frame)
+ }
+ .fini : { *(.fini) } =0
+ .ctors : { *(.ctors) }
+ .dtors : { *(.dtors) }
+
+ /* Read-write section, merged into data segment: */
+ . = (. + 0x0FFF) & 0xFFFFF000;
+ _erotext = .;
+ PROVIDE (erotext = .);
+ .reloc :
+ {
+ *(.got)
+ _GOT2_TABLE_ = .;
+ *(.got2)
+ _FIXUP_TABLE_ = .;
+ *(.fixup)
+ }
+ __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >> 2;
+ __fixup_entries = (. - _FIXUP_TABLE_) >> 2;
+
+ .data :
+ {
+ *(.data)
+ *(.data1)
+ *(.sdata)
+ *(.sdata2)
+ *(.dynamic)
+ CONSTRUCTORS
+ }
+ _edata = .;
+ PROVIDE (edata = .);
+
+ . = .;
+ __u_boot_cmd_start = .;
+ .u_boot_cmd : { *(.u_boot_cmd) }
+ __u_boot_cmd_end = .;
+
+
+ . = .;
+ __start___ex_table = .;
+ __ex_table : { *(__ex_table) }
+ __stop___ex_table = .;
+
+ . = ALIGN(4096);
+ __init_begin = .;
+ .text.init : { *(.text.init) }
+ .data.init : { *(.data.init) }
+ . = ALIGN(4096);
+ __init_end = .;
+
+ __bss_start = .;
+ .bss :
+ {
+ *(.sbss) *(.scommon)
+ *(.dynbss)
+ *(.bss)
+ *(COMMON)
+ }
+ _end = . ;
+ PROVIDE (end = .);
+}
diff --git a/board/uc101/uc101.c b/board/uc101/uc101.c
new file mode 100644
index 00000000000..7a6b3be72e6
--- /dev/null
+++ b/board/uc101/uc101.c
@@ -0,0 +1,371 @@
+/*
+ * (C) Copyright 2006
+ * Heiko Schocher, DENX Software Engineering, hs@denx.de.
+ *
+ * (C) Copyright 2003-2004
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * (C) Copyright 2004
+ * Mark Jonas, Freescale Semiconductor, mark.jonas@motorola.com.
+ *
+ * (C) Copyright 2004
+ * Martin Krause, TQ-Systems GmbH, martin.krause@tqs.de
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <mpc5xxx.h>
+#include <pci.h>
+#include <malloc.h>
+
+/* some SIMPLE GPIO Pins */
+#define GPIO_USB_8 (31-12)
+#define GPIO_USB_7 (31-13)
+#define GPIO_USB_6 (31-14)
+#define GPIO_USB_0 (31-15)
+#define GPIO_PSC3_7 (31-18)
+#define GPIO_PSC3_6 (31-19)
+#define GPIO_PSC3_1 (31-22)
+#define GPIO_PSC3_0 (31-23)
+
+/* some simple Interrupt GPIO Pins */
+#define GPIO_PSC3_8 2
+#define GPIO_USB1_9 3
+
+#define GPT_OUT_0 0x00000027
+#define GPT_OUT_1 0x00000037
+#define GPT_DISABLE 0x00000000 /* GPT pin disabled */
+
+#define GP_SIMP_ENABLE_O(n, v) {pgpio->simple_dvo |= (v << n); \
+ pgpio->simple_ddr |= (1 << n); \
+ pgpio->simple_gpioe |= (1 << n); \
+ }
+
+#define GP_SIMP_ENABLE_I(n) { pgpio->simple_ddr |= ~(1 << n); \
+ pgpio->simple_gpioe |= (1 << n); \
+ }
+
+#define GP_SIMP_SET_O(n, v) (pgpio->simple_dvo = v ? \
+ (pgpio->simple_dvo | (1 << n)) : \
+ (pgpio->simple_dvo & ~(1 << n)) )
+
+#define GP_SIMP_GET_O(n) ((pgpio->simple_dvo >> n) & 1)
+#define GP_SIMP_GET_I(n) ((pgpio->simple_ival >> n) & 1)
+
+#define GP_SINT_SET_O(n, v) (pgpio->sint_dvo = v ? \
+ (pgpio->sint_dvo | (1 << n)) : \
+ (pgpio->sint_dvo & ~(1 << n)) )
+
+#define GP_SINT_ENABLE_O(n, v) {pgpio->sint_ode &= ~(1 << n); \
+ pgpio->sint_ddr |= (1 << n); \
+ GP_SINT_SET_O(n, v); \
+ pgpio->sint_gpioe |= (1 << n); \
+ }
+
+#define GP_SINT_ENABLE_I(n) { pgpio->sint_ddr |= ~(1 << n); \
+ pgpio->sint_gpioe |= (1 << n); \
+ }
+
+#define GP_SINT_GET_O(n) ((pgpio->sint_ival >> n) & 1)
+#define GP_SINT_GET_I(n) ((pgpio-ntt_ival >> n) & 1)
+
+#define GP_TIMER_ENABLE_O(n, v) ( \
+ ((volatile struct mpc5xxx_gpt *)(MPC5XXX_GPT + n))->emsr = v ? \
+ GPT_OUT_1 : \
+ GPT_OUT_0 )
+
+#define GP_TIMER_SET_O(n, v) GP_TIMER_ENABLE_O(n, v)
+
+#define GP_TIMER_GET_O(n, v) ( \
+ (((volatile struct mpc5xxx_gpt *)(MPC5XXX_GPT + n))->emsr & 0x10) >> 4)
+
+#define GP_TIMER_GET_I(n, v) ( \
+ (((volatile struct mpc5xxx_gpt *)(MPC5XXX_GPT + n))->sr & 0x100) >> 8)
+
+#ifndef CFG_RAMBOOT
+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");
+
+#if SDRAM_DDR
+ /* 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");
+#endif
+
+ /* 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");
+}
+#endif
+
+/*
+ * 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;
+#ifndef CFG_RAMBOOT
+ ulong test1, test2;
+
+ /* setup SDRAM chip selects */
+ *(vu_long *)MPC5XXX_SDRAM_CS0CFG = 0x0000001c; /* 512MB at 0x0 */
+ *(vu_long *)MPC5XXX_SDRAM_CS1CFG = 0x40000000; /* disabled */
+ __asm__ volatile ("sync");
+
+ /* setup config registers */
+ *(vu_long *)MPC5XXX_SDRAM_CONFIG1 = SDRAM_CONFIG1;
+ *(vu_long *)MPC5XXX_SDRAM_CONFIG2 = SDRAM_CONFIG2;
+ __asm__ volatile ("sync");
+
+#if SDRAM_DDR
+ /* set tap delay */
+ *(vu_long *)MPC5XXX_CDM_PORCFG = SDRAM_TAPDELAY;
+ __asm__ volatile ("sync");
+#endif
+
+ /* find RAM size using SDRAM CS0 only */
+ sdram_start(0);
+ test1 = get_ram_size((long *)CFG_SDRAM_BASE, 0x20000000);
+ sdram_start(1);
+ test2 = get_ram_size((long *)CFG_SDRAM_BASE, 0x20000000);
+ 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;
+ } else {
+ *(vu_long *)MPC5XXX_SDRAM_CS0CFG = 0; /* disabled */
+ }
+
+ *(vu_long *)MPC5XXX_SDRAM_CS1CFG = dramsize; /* disabled */
+#else /* CFG_RAMBOOT */
+
+ /* retrieve size of memory connected to SDRAM CS0 */
+ dramsize = *(vu_long *)MPC5XXX_SDRAM_CS0CFG & 0xFF;
+ if (dramsize >= 0x13) {
+ dramsize = (1 << (dramsize - 0x13)) << 20;
+ } else {
+ dramsize = 0;
+ }
+
+ /* retrieve size of memory connected to SDRAM CS1 */
+ dramsize2 = *(vu_long *)MPC5XXX_SDRAM_CS1CFG & 0xFF;
+ if (dramsize2 >= 0x13) {
+ dramsize2 = (1 << (dramsize2 - 0x13)) << 20;
+ } else {
+ dramsize2 = 0;
+ }
+
+#endif /* CFG_RAMBOOT */
+
+/* return dramsize + dramsize2; */
+ return dramsize;
+}
+
+int checkboard (void)
+{
+ puts ("Board: MAN UC101\n");
+ return 0;
+}
+
+static void init_ports (void)
+{
+ volatile struct mpc5xxx_gpio *pgpio =
+ (struct mpc5xxx_gpio *)MPC5XXX_GPIO;
+
+ GP_SIMP_ENABLE_I(GPIO_USB_8); /* HEX Bit 3 */
+ GP_SIMP_ENABLE_I(GPIO_USB_7); /* HEX Bit 2 */
+ GP_SIMP_ENABLE_I(GPIO_USB_6); /* HEX Bit 1 */
+ GP_SIMP_ENABLE_I(GPIO_USB_0); /* HEX Bit 0 */
+ GP_SIMP_ENABLE_I(GPIO_PSC3_0); /* Switch Menue A */
+ GP_SIMP_ENABLE_I(GPIO_PSC3_1); /* Switch Menue B */
+ GP_SIMP_ENABLE_I(GPIO_PSC3_6); /* Switch Cold_Warm */
+ GP_SIMP_ENABLE_I(GPIO_PSC3_7); /* Switch Restart */
+ GP_SINT_ENABLE_O(GPIO_PSC3_8, 0); /* LED H2 */
+ GP_SINT_ENABLE_O(GPIO_USB1_9, 0); /* LED H3 */
+ GP_TIMER_ENABLE_O(4, 0); /* LED H4 */
+ GP_TIMER_ENABLE_O(5, 0); /* LED H5 */
+ GP_TIMER_ENABLE_O(3, 0); /* LED HB */
+ GP_TIMER_ENABLE_O(1, 0); /* RES_COLDSTART */
+}
+
+#ifdef CONFIG_PREBOOT
+
+static uchar kbd_magic_prefix[] = "key_magic";
+static uchar kbd_command_prefix[] = "key_cmd";
+
+struct kbd_data_t {
+ char s1;
+};
+
+struct kbd_data_t* get_keys (struct kbd_data_t *kbd_data)
+{
+ volatile struct mpc5xxx_gpio *pgpio =
+ (struct mpc5xxx_gpio *)MPC5XXX_GPIO;
+
+ kbd_data->s1 = GP_SIMP_GET_I(GPIO_USB_8) << 3 | \
+ GP_SIMP_GET_I(GPIO_USB_7) << 2 | \
+ GP_SIMP_GET_I(GPIO_USB_6) << 1 | \
+ GP_SIMP_GET_I(GPIO_USB_0) << 0;
+ return kbd_data;
+}
+
+static int compare_magic (const struct kbd_data_t *kbd_data, char *str)
+{
+ char s1 = str[0];
+
+ if (s1 >= '0' && s1 <= '9')
+ s1 -= '0';
+ else if (s1 >= 'a' && s1 <= 'f')
+ s1 = s1 - 'a' + 10;
+ else if (s1 >= 'A' && s1 <= 'F')
+ s1 = s1 - 'A' + 10;
+ else
+ return -1;
+
+ if (s1 != kbd_data->s1) return -1;
+ return 0;
+}
+
+static char *key_match (const struct kbd_data_t *kbd_data)
+{
+ char magic[sizeof (kbd_magic_prefix) + 1];
+ char *suffix;
+ char *kbd_magic_keys;
+
+ /*
+ * The following string defines the characters that can be appended
+ * to "key_magic" to form the names of environment variables that
+ * hold "magic" key codes, i. e. such key codes that can cause
+ * pre-boot actions. If the string is empty (""), then only
+ * "key_magic" is checked (old behaviour); the string "125" causes
+ * checks for "key_magic1", "key_magic2" and "key_magic5", etc.
+ */
+ if ((kbd_magic_keys = getenv ("magic_keys")) == NULL)
+ kbd_magic_keys = "";
+
+ /* loop over all magic keys;
+ * use '\0' suffix in case of empty string
+ */
+ for (suffix = kbd_magic_keys; *suffix ||
+ suffix == kbd_magic_keys; ++suffix) {
+ sprintf (magic, "%s%c", kbd_magic_prefix, *suffix);
+
+ if (compare_magic(kbd_data, getenv(magic)) == 0) {
+ char cmd_name[sizeof (kbd_command_prefix) + 1];
+ char *cmd;
+
+ sprintf (cmd_name, "%s%c", kbd_command_prefix, *suffix);
+ cmd = getenv (cmd_name);
+
+ return (cmd);
+ }
+ }
+
+ return (NULL);
+}
+
+#endif /* CONFIG_PREBOOT */
+
+int misc_init_r (void)
+{
+ /* Init the I/O ports */
+ init_ports ();
+
+#ifdef CONFIG_PREBOOT
+ struct kbd_data_t kbd_data;
+ /* Decode keys */
+ char *str = strdup (key_match (get_keys (&kbd_data)));
+ /* Set or delete definition */
+ setenv ("preboot", str);
+ free (str);
+#endif /* CONFIG_PREBOOT */
+ return 0;
+}
+
+int board_early_init_r (void)
+{
+ *(vu_long *)MPC5XXX_BOOTCS_CFG &= ~0x1; /* clear RO */
+ *(vu_long *)MPC5XXX_BOOTCS_START =
+ *(vu_long *)MPC5XXX_CS0_START = START_REG(CFG_FLASH_BASE);
+ *(vu_long *)MPC5XXX_BOOTCS_STOP =
+ *(vu_long *)MPC5XXX_CS0_STOP = STOP_REG(CFG_FLASH_BASE, CFG_FLASH_SIZE);
+ /* Interbus enable it here ?? */
+ *(vu_long *)MPC5XXX_GPT6_ENABLE = GPT_OUT_1;
+ return 0;
+}
+#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(CONFIG_HW_WATCHDOG)
+void hw_watchdog_reset(void)
+{
+ /* Trigger HW Watchdog with TIMER_0 */
+ *(vu_long *)MPC5XXX_GPT0_ENABLE = GPT_OUT_1;
+ *(vu_long *)MPC5XXX_GPT0_ENABLE = GPT_OUT_0;
+}
+#endif
diff --git a/board/v38b/v38b.c b/board/v38b/v38b.c
index dede9968801..ace4aa2caed 100644
--- a/board/v38b/v38b.c
+++ b/board/v38b/v38b.c
@@ -191,16 +191,8 @@ int checkboard (void)
return 0;
}
-
-int board_early_init_r(void)
+int board_early_init_f(void)
{
- /*
- * Now, when we are in RAM, enable flash write access for the
- * detection process. Note that CS_BOOT cannot be cleared when
- * executing in flash.
- */
- *(vu_long *) MPC5XXX_BOOTCS_CFG &= ~0x1; /* clear RO */
-
#ifdef CONFIG_HW_WATCHDOG
/*
* Enable and configure the direction (output) of PSC3_9 - watchdog
@@ -210,6 +202,17 @@ int board_early_init_r(void)
*(vu_long *) MPC5XXX_WU_GPIO_ENABLE |= GPIO_PSC3_9;
*(vu_long *) MPC5XXX_WU_GPIO_DIR |= GPIO_PSC3_9;
#endif /* CONFIG_HW_WATCHDOG */
+ return 0;
+}
+
+int board_early_init_r(void)
+{
+ /*
+ * Now, when we are in RAM, enable flash write access for the
+ * detection process. Note that CS_BOOT cannot be cleared when
+ * executing in flash.
+ */
+ *(vu_long *) MPC5XXX_BOOTCS_CFG &= ~0x1; /* clear RO */
/*
* Enable GPIO_WKUP_7 to "read the status of the actual power
diff --git a/board/xilinx/ml300/Makefile b/board/xilinx/ml300/Makefile
index 02c22fbef1f..05ad23524f1 100644
--- a/board/xilinx/ml300/Makefile
+++ b/board/xilinx/ml300/Makefile
@@ -28,7 +28,7 @@ $(shell mkdir -p $(obj)../xilinx_enet)
$(shell mkdir -p $(obj)../xilinx_iic)
endif
-INCS := -I../ml300 -I../common -I../xilinx_enet -I../xilinx_iic
+INCS := -I../common -I../xilinx_enet -I../xilinx_iic
CFLAGS += $(INCS)
HOST_CFLAGS += $(INCS)
diff --git a/board/xilinx/ml300/ml300.c b/board/xilinx/ml300/ml300.c
index dad562f1c77..60f0bc24e78 100644
--- a/board/xilinx/ml300/ml300.c
+++ b/board/xilinx/ml300/ml300.c
@@ -38,9 +38,9 @@
*
*/
+#include <config.h>
#include <common.h>
#include <asm/processor.h>
-#include "xparameters.h"
#ifdef CFG_ENV_IS_IN_EEPROM
extern void convert_env(void);
diff --git a/board/xilinx/ml300/serial.c b/board/xilinx/ml300/serial.c
index c204b88e415..9b03f89eff4 100644
--- a/board/xilinx/ml300/serial.c
+++ b/board/xilinx/ml300/serial.c
@@ -40,8 +40,7 @@
#include <asm/processor.h>
#include <common.h>
#include <command.h>
-#include <configs/ml300.h>
-#include "xparameters.h"
+#include <config.h>
DECLARE_GLOBAL_DATA_PTR;
diff --git a/board/xilinx/xilinx_enet/emac_adapter.c b/board/xilinx/xilinx_enet/emac_adapter.c
index b30e8976692..f159cb6e392 100644
--- a/board/xilinx/xilinx_enet/emac_adapter.c
+++ b/board/xilinx/xilinx_enet/emac_adapter.c
@@ -37,9 +37,9 @@
*
******************************************************************************/
+#include <config.h>
#include <common.h>
#include <net.h>
-#include "xparameters.h"
#include "xemac.h"
#if defined(XPAR_EMAC_0_DEVICE_ID)
diff --git a/board/xilinx/xilinx_enet/xemac.h b/board/xilinx/xilinx_enet/xemac.h
index ed704bf29b3..584cb7ac51e 100644
--- a/board/xilinx/xilinx_enet/xemac.h
+++ b/board/xilinx/xilinx_enet/xemac.h
@@ -257,9 +257,9 @@
/***************************** Include Files *********************************/
+#include <config.h>
#include "xbasic_types.h"
#include "xstatus.h"
-#include "xparameters.h"
#include "xpacket_fifo_v1_00_b.h" /* Uses v1.00b of Packet Fifo */
#include "xdma_channel.h"
diff --git a/board/xilinx/xilinx_enet/xemac_g.c b/board/xilinx/xilinx_enet/xemac_g.c
index 9340f911f86..d9851574f73 100644
--- a/board/xilinx/xilinx_enet/xemac_g.c
+++ b/board/xilinx/xilinx_enet/xemac_g.c
@@ -43,7 +43,7 @@
*
*******************************************************************/
-#include "xparameters.h"
+#include <config.h>
#include "xemac.h"
/*
diff --git a/board/xilinx/xilinx_iic/iic_adapter.c b/board/xilinx/xilinx_iic/iic_adapter.c
index 163fe1511db..37dce039164 100644
--- a/board/xilinx/xilinx_iic/iic_adapter.c
+++ b/board/xilinx/xilinx_iic/iic_adapter.c
@@ -37,10 +37,10 @@
*
******************************************************************************/
+#include <config.h>
#include <common.h>
#include <environment.h>
#include <net.h>
-#include "xparameters.h"
#ifdef CFG_ENV_IS_IN_EEPROM
#include <i2c.h>
diff --git a/board/zylonite/nand.c b/board/zylonite/nand.c
index 5d2cd6585f6..a41714351f0 100644
--- a/board/zylonite/nand.c
+++ b/board/zylonite/nand.c
@@ -448,7 +448,7 @@ static void dfc_gpio_init(void)
* Members with a "?" were not set in the merged testing-NAND branch,
* so they are not set here either.
*/
-void board_nand_init(struct nand_chip *nand)
+int board_nand_init(struct nand_chip *nand)
{
unsigned long tCH, tCS, tWH, tWP, tRH, tRP, tRP_high, tR, tWHR, tAR;
@@ -576,6 +576,7 @@ void board_nand_init(struct nand_chip *nand)
nand->cmdfunc = dfc_cmdfunc;
nand->autooob = &delta_oob;
nand->badblock_pattern = &delta_bbt_descr;
+ return 0;
}
#else