summaryrefslogtreecommitdiff
path: root/cpu
diff options
context:
space:
mode:
Diffstat (limited to 'cpu')
-rw-r--r--cpu/74xx_7xx/Makefile23
-rw-r--r--cpu/arm1136/Makefile20
-rw-r--r--cpu/arm720t/Makefile20
-rw-r--r--cpu/arm920t/Makefile20
-rw-r--r--cpu/arm920t/at91rm9200/Makefile21
-rw-r--r--cpu/arm920t/imx/Makefile19
-rw-r--r--cpu/arm920t/ks8695/Makefile21
-rw-r--r--cpu/arm920t/s3c24x0/Makefile19
-rw-r--r--cpu/arm925t/Makefile20
-rw-r--r--cpu/arm925t/omap925.c34
-rw-r--r--cpu/arm926ejs/Makefile20
-rw-r--r--cpu/arm926ejs/omap/Makefile22
-rw-r--r--cpu/arm926ejs/versatile/Makefile22
-rw-r--r--cpu/arm946es/Makefile20
-rw-r--r--cpu/arm_intcm/Makefile20
-rw-r--r--cpu/at32ap/Makefile50
-rw-r--r--cpu/at32ap/at32ap7000/Makefile43
-rw-r--r--cpu/at32ap/at32ap7000/devices.c448
-rw-r--r--cpu/at32ap/at32ap7000/hebi.c38
-rw-r--r--cpu/at32ap/cache.c97
-rw-r--r--cpu/at32ap/config.mk22
-rw-r--r--cpu/at32ap/cpu.c83
-rw-r--r--cpu/at32ap/device.c126
-rw-r--r--cpu/at32ap/entry.S65
-rw-r--r--cpu/at32ap/exception.c119
-rw-r--r--cpu/at32ap/hsdramc.c155
-rw-r--r--cpu/at32ap/hsdramc1.h143
-rw-r--r--cpu/at32ap/hsmc3.h126
-rw-r--r--cpu/at32ap/interrupts.c154
-rw-r--r--cpu/at32ap/pio.c94
-rw-r--r--cpu/at32ap/pio2.h44
-rw-r--r--cpu/at32ap/pm.c163
-rw-r--r--cpu/at32ap/sm.h204
-rw-r--r--cpu/at32ap/start.S113
-rw-r--r--cpu/bf533/Makefile20
-rw-r--r--cpu/i386/Makefile23
-rw-r--r--cpu/i386/sc520.c18
-rw-r--r--cpu/i386/sc520_asm.S52
-rw-r--r--cpu/ixp/Makefile20
-rw-r--r--cpu/ixp/npe/Makefile25
-rw-r--r--cpu/lh7a40x/Makefile20
-rw-r--r--cpu/mcf52x2/Makefile20
-rw-r--r--cpu/mcf52x2/fec.c1
-rw-r--r--cpu/mcf52x2/start.S2
-rw-r--r--cpu/microblaze/Makefile20
-rw-r--r--cpu/mips/Makefile22
-rw-r--r--cpu/mpc5xx/Makefile23
-rw-r--r--cpu/mpc5xxx/Makefile22
-rw-r--r--cpu/mpc5xxx/fec.c2
-rw-r--r--cpu/mpc5xxx/interrupts.c292
-rw-r--r--cpu/mpc5xxx/serial.c56
-rw-r--r--cpu/mpc8220/Makefile22
-rw-r--r--cpu/mpc8220/pci.c2
-rw-r--r--cpu/mpc824x/Makefile33
-rw-r--r--cpu/mpc824x/drivers/dma/Makefile83
-rw-r--r--cpu/mpc824x/drivers/dma/Makefile_pc89
-rw-r--r--cpu/mpc824x/drivers/dma/README100
-rw-r--r--cpu/mpc824x/drivers/dma/dma.h326
-rw-r--r--cpu/mpc824x/drivers/dma/dma1.c801
-rw-r--r--cpu/mpc824x/drivers/dma/dma2.S42
-rw-r--r--cpu/mpc824x/drivers/dma/dma_export.h100
-rw-r--r--cpu/mpc824x/drivers/dma_export.h100
-rw-r--r--cpu/mpc824x/drivers/i2o.h344
-rw-r--r--cpu/mpc824x/drivers/i2o/Makefile84
-rw-r--r--cpu/mpc824x/drivers/i2o/Makefile_pc90
-rw-r--r--cpu/mpc824x/drivers/i2o/i2o.h345
-rw-r--r--cpu/mpc824x/drivers/i2o/i2o1.c890
-rw-r--r--cpu/mpc824x/drivers/i2o/i2o2.S47
-rw-r--r--cpu/mpc8260/Makefile20
-rw-r--r--cpu/mpc83xx/Makefile32
-rw-r--r--cpu/mpc85xx/Makefile22
-rw-r--r--cpu/mpc85xx/cpu.c50
-rw-r--r--cpu/mpc85xx/cpu_init.c1
-rw-r--r--cpu/mpc85xx/i2c.c265
-rw-r--r--cpu/mpc85xx/pci.c190
-rw-r--r--cpu/mpc85xx/spd_sdram.c132
-rw-r--r--cpu/mpc86xx/Makefile51
-rw-r--r--cpu/mpc86xx/cache.S374
-rw-r--r--cpu/mpc86xx/config.mk26
-rw-r--r--cpu/mpc86xx/cpu.c308
-rw-r--r--cpu/mpc86xx/cpu_init.c117
-rw-r--r--cpu/mpc86xx/interrupts.c204
-rw-r--r--cpu/mpc86xx/pci.c146
-rw-r--r--cpu/mpc86xx/pcie_indirect.c199
-rw-r--r--cpu/mpc86xx/resetvec.S2
-rw-r--r--cpu/mpc86xx/spd_sdram.c1320
-rw-r--r--cpu/mpc86xx/speed.c127
-rw-r--r--cpu/mpc86xx/start.S1226
-rw-r--r--cpu/mpc86xx/traps.c226
-rw-r--r--cpu/mpc8xx/Makefile22
-rw-r--r--cpu/nios/Makefile24
-rw-r--r--cpu/nios2/Makefile24
-rw-r--r--cpu/ppc4xx/405gp_pci.c8
-rw-r--r--cpu/ppc4xx/440spe_pcie.c962
-rw-r--r--cpu/ppc4xx/440spe_pcie.h171
-rw-r--r--cpu/ppc4xx/4xx_enet.c184
-rw-r--r--cpu/ppc4xx/Makefile25
-rw-r--r--cpu/ppc4xx/cpu.c130
-rw-r--r--cpu/ppc4xx/cpu_init.c14
-rw-r--r--cpu/ppc4xx/interrupts.c57
-rw-r--r--cpu/ppc4xx/miiphy.c14
-rw-r--r--cpu/ppc4xx/ndfc.c193
-rw-r--r--cpu/ppc4xx/serial.c263
-rw-r--r--cpu/ppc4xx/speed.c3
-rw-r--r--cpu/ppc4xx/start.S173
-rw-r--r--cpu/ppc4xx/usb_ohci.c8
-rw-r--r--cpu/ppc4xx/usbdev.c20
-rw-r--r--cpu/ppc4xx/vecnum.h89
-rw-r--r--cpu/pxa/Makefile20
-rw-r--r--cpu/s3c44b0/Makefile20
-rw-r--r--cpu/sa1100/Makefile20
111 files changed, 9758 insertions, 4468 deletions
diff --git a/cpu/74xx_7xx/Makefile b/cpu/74xx_7xx/Makefile
index 0e10d3a..fe905f3 100644
--- a/cpu/74xx_7xx/Makefile
+++ b/cpu/74xx_7xx/Makefile
@@ -1,4 +1,7 @@
#
+# (C) Copyright 2006
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
# (C) Copyright 2001
# Josh Huber <huber@mclx.com>, Mission Critical Linux, Inc.
#
@@ -23,22 +26,26 @@
include $(TOPDIR)/config.mk
-LIB = lib$(CPU).a
+LIB = $(obj)lib$(CPU).a
START = start.o
-ASOBJS = cache.o kgdb.o io.o
-OBJS = traps.o cpu.o cpu_init.o speed.o interrupts.o
+SOBJS = cache.o kgdb.o io.o
+COBJS = traps.o cpu.o cpu_init.o speed.o interrupts.o
+
+SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
+START := $(addprefix $(obj),$(START))
-all: .depend $(START) $(ASOBJS) $(LIB)
+all: $(obj).depend $(START) $(LIB)
$(LIB): $(OBJS)
- $(AR) crv $@ $(ASOBJS) $(OBJS)
+ $(AR) $(ARFLAGS) $@ $(OBJS)
#########################################################################
-.depend: Makefile $(START:.o=.S) $(OBJS:.o=.c)
- $(CC) -M $(CFLAGS) $(START:.o=.S) $(ASOBJS:.o=.S) $(OBJS:.o=.c) > $@
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
-sinclude .depend
+sinclude $(obj).depend
#########################################################################
diff --git a/cpu/arm1136/Makefile b/cpu/arm1136/Makefile
index 203278e..d5ac7d3 100644
--- a/cpu/arm1136/Makefile
+++ b/cpu/arm1136/Makefile
@@ -1,5 +1,5 @@
#
-# (C) Copyright 2000-2003
+# (C) Copyright 2000-2006
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
#
# See file CREDITS for list of people who contributed to this
@@ -23,21 +23,25 @@
include $(TOPDIR)/config.mk
-LIB = lib$(CPU).a
+LIB = $(obj)lib$(CPU).a
START = start.o
-OBJS = interrupts.o cpu.o
+COBJS = interrupts.o cpu.o
-all: .depend $(START) $(LIB)
+SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(COBJS) $(SOBJS))
+START := $(addprefix $(obj),$(START))
+
+all: $(obj).depend $(START) $(LIB)
$(LIB): $(OBJS)
- $(AR) crv $@ $(OBJS)
+ $(AR) $(ARFLAGS) $@ $(OBJS)
#########################################################################
-.depend: Makefile $(START:.o=.S) $(OBJS:.o=.c)
- $(CC) -M $(CFLAGS) $(START:.o=.S) $(OBJS:.o=.c) > $@
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
-sinclude .depend
+sinclude $(obj).depend
#########################################################################
diff --git a/cpu/arm720t/Makefile b/cpu/arm720t/Makefile
index f273d92..c97f329 100644
--- a/cpu/arm720t/Makefile
+++ b/cpu/arm720t/Makefile
@@ -1,5 +1,5 @@
#
-# (C) Copyright 2000
+# (C) Copyright 2000-2006
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
#
# See file CREDITS for list of people who contributed to this
@@ -23,21 +23,25 @@
include $(TOPDIR)/config.mk
-LIB = lib$(CPU).a
+LIB = $(obj)lib$(CPU).a
START = start.o
-OBJS = serial.o serial_netarm.o interrupts.o cpu.o
+COBJS = serial.o serial_netarm.o interrupts.o cpu.o
-all: .depend $(START) $(LIB)
+SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(COBJS) $(SOBJS))
+START := $(addprefix $(obj),$(START))
+
+all: $(obj).depend $(START) $(LIB)
$(LIB): $(OBJS)
- $(AR) crv $@ $(OBJS)
+ $(AR) $(ARFLAGS) $@ $(OBJS)
#########################################################################
-.depend: Makefile $(START:.o=.S) $(OBJS:.o=.c)
- $(CC) -M $(CFLAGS) $(START:.o=.S) $(OBJS:.o=.c) > $@
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
-sinclude .depend
+sinclude $(obj).depend
#########################################################################
diff --git a/cpu/arm920t/Makefile b/cpu/arm920t/Makefile
index 8f256e9..e02bc6a 100644
--- a/cpu/arm920t/Makefile
+++ b/cpu/arm920t/Makefile
@@ -1,5 +1,5 @@
#
-# (C) Copyright 2000, 2001, 2002
+# (C) Copyright 2000-2006
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
#
# See file CREDITS for list of people who contributed to this
@@ -23,21 +23,25 @@
include $(TOPDIR)/config.mk
-LIB = lib$(CPU).a
+LIB = $(obj)lib$(CPU).a
START = start.o
-OBJS = cpu.o interrupts.o
+COBJS = cpu.o interrupts.o
-all: .depend $(START) $(LIB)
+SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(COBJS) $(SOBJS))
+START := $(addprefix $(obj),$(START))
+
+all: $(obj).depend $(START) $(LIB)
$(LIB): $(OBJS)
- $(AR) crv $@ $(OBJS)
+ $(AR) $(ARFLAGS) $@ $(OBJS)
#########################################################################
-.depend: Makefile $(START:.o=.S) $(OBJS:.o=.c)
- $(CC) -M $(CFLAGS) $(START:.o=.S) $(OBJS:.o=.c) > $@
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
-sinclude .depend
+sinclude $(obj).depend
#########################################################################
diff --git a/cpu/arm920t/at91rm9200/Makefile b/cpu/arm920t/at91rm9200/Makefile
index f9fccbc..eaabad2 100644
--- a/cpu/arm920t/at91rm9200/Makefile
+++ b/cpu/arm920t/at91rm9200/Makefile
@@ -1,5 +1,5 @@
#
-# (C) Copyright 2000-2005
+# (C) Copyright 2000-2006
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
#
# See file CREDITS for list of people who contributed to this
@@ -23,22 +23,25 @@
include $(TOPDIR)/config.mk
-LIB = lib$(SOC).a
+LIB = $(obj)lib$(SOC).a
-OBJS = bcm5221.o dm9161.o ether.o i2c.o interrupts.o \
+COBJS = bcm5221.o dm9161.o ether.o i2c.o interrupts.o \
lxt972.o serial.o usb.o
SOBJS = lowlevel_init.o
-all: .depend $(LIB)
+SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
-$(LIB): $(OBJS) $(SOBJS)
- $(AR) crv $@ $(OBJS) $(SOBJS)
+all: $(obj).depend $(LIB)
+
+$(LIB): $(OBJS)
+ $(AR) $(ARFLAGS) $@ $(OBJS)
#########################################################################
-.depend: Makefile $(SOBJS:.o=.S) $(OBJS:.o=.c)
- $(CC) -M $(CFLAGS) $(SOBJS:.o=.S) $(OBJS:.o=.c) > $@
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
-sinclude .depend
+sinclude $(obj).depend
#########################################################################
diff --git a/cpu/arm920t/imx/Makefile b/cpu/arm920t/imx/Makefile
index 8865f82..9207ec1 100644
--- a/cpu/arm920t/imx/Makefile
+++ b/cpu/arm920t/imx/Makefile
@@ -1,5 +1,5 @@
#
-# (C) Copyright 2000, 2001, 2002
+# (C) Copyright 2000-2006
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
#
# See file CREDITS for list of people who contributed to this
@@ -23,20 +23,23 @@
include $(TOPDIR)/config.mk
-LIB = lib$(SOC).a
+LIB = $(obj)lib$(SOC).a
-OBJS = generic.o interrupts.o serial.o speed.o
+COBJS = generic.o interrupts.o serial.o speed.o
-all: .depend $(LIB)
+SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
+
+all: $(obj).depend $(LIB)
$(LIB): $(OBJS)
- $(AR) crv $@ $(OBJS)
+ $(AR) $(ARFLAGS) $@ $(OBJS)
#########################################################################
-.depend: Makefile $(OBJS:.o=.c)
- $(CC) -M $(CFLAGS) $(OBJS:.o=.c) > $@
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
-sinclude .depend
+sinclude $(obj).depend
#########################################################################
diff --git a/cpu/arm920t/ks8695/Makefile b/cpu/arm920t/ks8695/Makefile
index ac49060..7db9473 100644
--- a/cpu/arm920t/ks8695/Makefile
+++ b/cpu/arm920t/ks8695/Makefile
@@ -1,5 +1,5 @@
#
-# (C) Copyright 2000-2005
+# (C) Copyright 2000-2006
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
#
# See file CREDITS for list of people who contributed to this
@@ -23,21 +23,24 @@
include $(TOPDIR)/config.mk
-LIB = lib$(SOC).a
+LIB = $(obj)lib$(SOC).a
-OBJS = interrupts.o serial.o
+COBJS = interrupts.o serial.o
SOBJS = lowlevel_init.o
-all: .depend $(LIB)
+SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
-$(LIB): $(OBJS) $(SOBJS)
- $(AR) crv $@ $(OBJS) $(SOBJS)
+all: $(obj).depend $(LIB)
+
+$(LIB): $(OBJS)
+ $(AR) $(ARFLAGS) $@ $(OBJS)
#########################################################################
-.depend: Makefile $(SOBJS:.o=.S) $(OBJS:.o=.c)
- $(CC) -M $(CFLAGS) $(SOBJS:.o=.S) $(OBJS:.o=.c) > $@
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
-sinclude .depend
+sinclude $(obj).depend
#########################################################################
diff --git a/cpu/arm920t/s3c24x0/Makefile b/cpu/arm920t/s3c24x0/Makefile
index f81f84d..0ff36c5 100644
--- a/cpu/arm920t/s3c24x0/Makefile
+++ b/cpu/arm920t/s3c24x0/Makefile
@@ -1,5 +1,5 @@
#
-# (C) Copyright 2000, 2001, 2002
+# (C) Copyright 2000-2006
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
#
# See file CREDITS for list of people who contributed to this
@@ -23,21 +23,24 @@
include $(TOPDIR)/config.mk
-LIB = lib$(SOC).a
+LIB = $(obj)lib$(SOC).a
-OBJS = i2c.o interrupts.o serial.o speed.o \
+COBJS = i2c.o interrupts.o serial.o speed.o \
usb.o
-all: .depend $(LIB)
+SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
+
+all: $(obj).depend $(LIB)
$(LIB): $(OBJS)
- $(AR) crv $@ $(OBJS)
+ $(AR) $(ARFLAGS) $@ $(OBJS)
#########################################################################
-.depend: Makefile $(OBJS:.o=.c)
- $(CC) -M $(CFLAGS) $(OBJS:.o=.c) > $@
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
-sinclude .depend
+sinclude $(obj).depend
#########################################################################
diff --git a/cpu/arm925t/Makefile b/cpu/arm925t/Makefile
index a1db818..0d4912c 100644
--- a/cpu/arm925t/Makefile
+++ b/cpu/arm925t/Makefile
@@ -1,5 +1,5 @@
#
-# (C) Copyright 2000-2003
+# (C) Copyright 2000-2006
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
#
# See file CREDITS for list of people who contributed to this
@@ -23,21 +23,25 @@
include $(TOPDIR)/config.mk
-LIB = lib$(CPU).a
+LIB = $(obj)lib$(CPU).a
START = start.o
-OBJS = interrupts.o cpu.o omap925.o
+COBJS = interrupts.o cpu.o omap925.o
-all: .depend $(START) $(LIB)
+SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
+START := $(addprefix $(obj),$(START))
+
+all: $(obj).depend $(START) $(LIB)
$(LIB): $(OBJS)
- $(AR) crv $@ $(OBJS)
+ $(AR) $(ARFLAGS) $@ $(OBJS)
#########################################################################
-.depend: Makefile $(START:.o=.S) $(OBJS:.o=.c)
- $(CC) -M $(CFLAGS) $(START:.o=.S) $(OBJS:.o=.c) > $@
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
-sinclude .depend
+sinclude $(obj).depend
#########################################################################
diff --git a/cpu/arm925t/omap925.c b/cpu/arm925t/omap925.c
index ae62656..65dab9f 100644
--- a/cpu/arm925t/omap925.c
+++ b/cpu/arm925t/omap925.c
@@ -25,40 +25,6 @@
#include <command.h>
#include <arm925t.h>
-ushort gpioreserved;
-
-void gpioreserve(ushort mask)
-{
- gpioreserved |= mask;
-}
-
-void gpiosetdir(ushort mask, ushort in)
-{
- *(ushort *)GPIO_DIR_CONTROL_REG = (*(ushort *)GPIO_DIR_CONTROL_REG & ~mask) | (in & mask);
-}
-
-
-void gpiosetout(ushort mask, ushort out)
-{
- ushort *r_ptr, r_val;
-
- r_ptr = (ushort *)GPIO_DATA_OUTPUT_REG; /* set pointer */
- r_val = *r_ptr & ~mask; /* get previous val, clear bits we want to change */
- r_val |= (out & mask); /* set specified bits in value + plus origional ones */
- *r_ptr = r_val; /* write it out */
-/*
- * gcc screwed this one up :(.
- *
- * *(ushort *)GPIO_DATA_OUTPUT_REG = (*(ushort *)GPIO_DATA_OUTPUT_REG & ~mask) | (out & mask);
- */
-
-}
-
-void gpioinit(void)
-{
-}
-
-
#define MIF_CONFIG_REG 0xFFFECC0C
#define FLASH_GLOBAL_CTRL_NWP 1
diff --git a/cpu/arm926ejs/Makefile b/cpu/arm926ejs/Makefile
index 060fd20..0facce4 100644
--- a/cpu/arm926ejs/Makefile
+++ b/cpu/arm926ejs/Makefile
@@ -1,5 +1,5 @@
#
-# (C) Copyright 2000-2003
+# (C) Copyright 2000-2006
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
#
# See file CREDITS for list of people who contributed to this
@@ -23,21 +23,25 @@
include $(TOPDIR)/config.mk
-LIB = lib$(CPU).a
+LIB = $(obj)lib$(CPU).a
START = start.o
-OBJS = interrupts.o cpu.o cpuinfo.o
+COBJS = interrupts.o cpu.o cpuinfo.o
-all: .depend $(START) $(LIB)
+SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(COBJS) $(SOBJS))
+START := $(addprefix $(obj),$(START))
+
+all: $(obj).depend $(START) $(LIB)
$(LIB): $(OBJS)
- $(AR) crv $@ $(OBJS)
+ $(AR) $(ARFLAGS) $@ $(OBJS)
#########################################################################
-.depend: Makefile $(START:.o=.S) $(OBJS:.o=.c)
- $(CC) -M $(CFLAGS) $(START:.o=.S) $(OBJS:.o=.c) > $@
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
-sinclude .depend
+sinclude $(obj).depend
#########################################################################
diff --git a/cpu/arm926ejs/omap/Makefile b/cpu/arm926ejs/omap/Makefile
index f9d3378..c335d5c 100644
--- a/cpu/arm926ejs/omap/Makefile
+++ b/cpu/arm926ejs/omap/Makefile
@@ -1,5 +1,5 @@
#
-# (C) Copyright 2000-2005
+# (C) Copyright 2000-2006
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
#
# See file CREDITS for list of people who contributed to this
@@ -23,21 +23,25 @@
include $(TOPDIR)/config.mk
-LIB = lib$(SOC).a
+LIB = $(obj)lib$(SOC).a
-OBJS = timer.o
+COBJS = timer.o
SOBJS = reset.o
-all: .depend $(LIB)
+SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(COBJS) $(SOBJS))
+START := $(addprefix $(obj),$(START))
-$(LIB): $(OBJS) $(SOBJS)
- $(AR) crv $@ $(OBJS) $(SOBJS)
+all: $(obj).depend $(LIB)
+
+$(LIB): $(OBJS)
+ $(AR) $(ARFLAGS) $@ $(OBJS)
#########################################################################
-.depend: Makefile $(OBJS:.o=.c)
- $(CC) -M $(CFLAGS) $(OBJS:.o=.c) > $@
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
-sinclude .depend
+sinclude $(obj).depend
#########################################################################
diff --git a/cpu/arm926ejs/versatile/Makefile b/cpu/arm926ejs/versatile/Makefile
index f9d3378..c335d5c 100644
--- a/cpu/arm926ejs/versatile/Makefile
+++ b/cpu/arm926ejs/versatile/Makefile
@@ -1,5 +1,5 @@
#
-# (C) Copyright 2000-2005
+# (C) Copyright 2000-2006
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
#
# See file CREDITS for list of people who contributed to this
@@ -23,21 +23,25 @@
include $(TOPDIR)/config.mk
-LIB = lib$(SOC).a
+LIB = $(obj)lib$(SOC).a
-OBJS = timer.o
+COBJS = timer.o
SOBJS = reset.o
-all: .depend $(LIB)
+SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(COBJS) $(SOBJS))
+START := $(addprefix $(obj),$(START))
-$(LIB): $(OBJS) $(SOBJS)
- $(AR) crv $@ $(OBJS) $(SOBJS)
+all: $(obj).depend $(LIB)
+
+$(LIB): $(OBJS)
+ $(AR) $(ARFLAGS) $@ $(OBJS)
#########################################################################
-.depend: Makefile $(OBJS:.o=.c)
- $(CC) -M $(CFLAGS) $(OBJS:.o=.c) > $@
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
-sinclude .depend
+sinclude $(obj).depend
#########################################################################
diff --git a/cpu/arm946es/Makefile b/cpu/arm946es/Makefile
index 203278e..d5ac7d3 100644
--- a/cpu/arm946es/Makefile
+++ b/cpu/arm946es/Makefile
@@ -1,5 +1,5 @@
#
-# (C) Copyright 2000-2003
+# (C) Copyright 2000-2006
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
#
# See file CREDITS for list of people who contributed to this
@@ -23,21 +23,25 @@
include $(TOPDIR)/config.mk
-LIB = lib$(CPU).a
+LIB = $(obj)lib$(CPU).a
START = start.o
-OBJS = interrupts.o cpu.o
+COBJS = interrupts.o cpu.o
-all: .depend $(START) $(LIB)
+SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(COBJS) $(SOBJS))
+START := $(addprefix $(obj),$(START))
+
+all: $(obj).depend $(START) $(LIB)
$(LIB): $(OBJS)
- $(AR) crv $@ $(OBJS)
+ $(AR) $(ARFLAGS) $@ $(OBJS)
#########################################################################
-.depend: Makefile $(START:.o=.S) $(OBJS:.o=.c)
- $(CC) -M $(CFLAGS) $(START:.o=.S) $(OBJS:.o=.c) > $@
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
-sinclude .depend
+sinclude $(obj).depend
#########################################################################
diff --git a/cpu/arm_intcm/Makefile b/cpu/arm_intcm/Makefile
index 203278e..d5ac7d3 100644
--- a/cpu/arm_intcm/Makefile
+++ b/cpu/arm_intcm/Makefile
@@ -1,5 +1,5 @@
#
-# (C) Copyright 2000-2003
+# (C) Copyright 2000-2006
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
#
# See file CREDITS for list of people who contributed to this
@@ -23,21 +23,25 @@
include $(TOPDIR)/config.mk
-LIB = lib$(CPU).a
+LIB = $(obj)lib$(CPU).a
START = start.o
-OBJS = interrupts.o cpu.o
+COBJS = interrupts.o cpu.o
-all: .depend $(START) $(LIB)
+SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(COBJS) $(SOBJS))
+START := $(addprefix $(obj),$(START))
+
+all: $(obj).depend $(START) $(LIB)
$(LIB): $(OBJS)
- $(AR) crv $@ $(OBJS)
+ $(AR) $(ARFLAGS) $@ $(OBJS)
#########################################################################
-.depend: Makefile $(START:.o=.S) $(OBJS:.o=.c)
- $(CC) -M $(CFLAGS) $(START:.o=.S) $(OBJS:.o=.c) > $@
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
-sinclude .depend
+sinclude $(obj).depend
#########################################################################
diff --git a/cpu/at32ap/Makefile b/cpu/at32ap/Makefile
new file mode 100644
index 0000000..f62ec8b
--- /dev/null
+++ b/cpu/at32ap/Makefile
@@ -0,0 +1,50 @@
+#
+# (C) Copyright 2000-2006
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# Copyright (C) 2005-2006 Atmel Corporation.
+#
+# 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$(CPU).a
+
+START := start.o
+SOBJS := entry.o
+COBJS := cpu.o hsdramc.o exception.o cache.o
+COBJS += interrupts.o device.o pm.o pio.o
+SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
+START := $(addprefix $(obj),$(START))
+
+all: $(obj).depend $(START) $(LIB)
+
+$(LIB): $(OBJS)
+ $(AR) $(ARFLAGS) $@ $^
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/cpu/at32ap/at32ap7000/Makefile b/cpu/at32ap/at32ap7000/Makefile
new file mode 100644
index 0000000..2ed74d2
--- /dev/null
+++ b/cpu/at32ap/at32ap7000/Makefile
@@ -0,0 +1,43 @@
+#
+# Copyright (C) 2005-2006 Atmel Corporation
+#
+# 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$(SOC).a
+
+COBJS := hebi.o devices.o
+SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
+
+all: $(obj).depend $(LIB)
+
+$(LIB): $(OBJS)
+ $(AR) $(ARFLAGS) $@ $^
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/cpu/at32ap/at32ap7000/devices.c b/cpu/at32ap/at32ap7000/devices.c
new file mode 100644
index 0000000..8b216e9
--- /dev/null
+++ b/cpu/at32ap/at32ap7000/devices.c
@@ -0,0 +1,448 @@
+/*
+ * Copyright (C) 2006 Atmel Corporation
+ *
+ * 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/arch/memory-map.h>
+#include <asm/arch/platform.h>
+
+#include "../sm.h"
+
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
+
+const struct clock_domain chip_clock[] = {
+ [CLOCK_CPU] = {
+ .reg = SM_PM_CPU_MASK,
+ .id = CLOCK_CPU,
+ .bridge = NO_DEVICE,
+ },
+ [CLOCK_HSB] = {
+ .reg = SM_PM_HSB_MASK,
+ .id = CLOCK_HSB,
+ .bridge = NO_DEVICE,
+ },
+ [CLOCK_PBA] = {
+ .reg = SM_PM_PBA_MASK,
+ .id = CLOCK_PBA,
+ .bridge = DEVICE_PBA_BRIDGE,
+ },
+ [CLOCK_PBB] = {
+ .reg = SM_PM_PBB_MASK,
+ .id = CLOCK_PBB,
+ .bridge = DEVICE_PBB_BRIDGE,
+ },
+};
+
+static const struct resource hebi_resource[] = {
+ {
+ .type = RESOURCE_CLOCK,
+ .u = {
+ .clock = { CLOCK_HSB, 0 },
+ },
+ }, {
+ .type = RESOURCE_CLOCK,
+ .u = {
+ .clock = { CLOCK_PBB, 13 },
+ },
+ }, {
+ .type = RESOURCE_CLOCK,
+ .u = {
+ .clock = { CLOCK_PBB, 14 },
+ },
+ }, {
+ .type = RESOURCE_GPIO,
+ .u = {
+ .gpio = { 27, DEVICE_PIOE, GPIO_FUNC_A, 0 },
+ },
+ },
+};
+static const struct resource pba_bridge_resource[] = {
+ {
+ .type = RESOURCE_CLOCK,
+ .u = {
+ .clock = { CLOCK_HSB, 1 },
+ }
+ }, {
+ .type = RESOURCE_CLOCK,
+ .u = {
+ /* HSB-HSB Bridge */
+ .clock = { CLOCK_HSB, 4 },
+ },
+ },
+};
+static const struct resource pbb_bridge_resource[] = {
+ {
+ .type = RESOURCE_CLOCK,
+ .u = {
+ .clock = { CLOCK_HSB, 2 },
+ },
+ },
+};
+static const struct resource hramc_resource[] = {
+ {
+ .type = RESOURCE_CLOCK,
+ .u = {
+ .clock = { CLOCK_HSB, 3 },
+ },
+ },
+};
+static const struct resource pioa_resource[] = {
+ {
+ .type = RESOURCE_CLOCK,
+ .u = {
+ .clock = { CLOCK_PBA, 10 },
+ },
+ },
+};
+static const struct resource piob_resource[] = {
+ {
+ .type = RESOURCE_CLOCK,
+ .u = {
+ .clock = { CLOCK_PBA, 11 },
+ },
+ },
+};
+static const struct resource pioc_resource[] = {
+ {
+ .type = RESOURCE_CLOCK,
+ .u = {
+ .clock = { CLOCK_PBA, 12 },
+ },
+ },
+};
+static const struct resource piod_resource[] = {
+ {
+ .type = RESOURCE_CLOCK,
+ .u = {
+ .clock = { CLOCK_PBA, 13 },
+ },
+ },
+};
+static const struct resource pioe_resource[] = {
+ {
+ .type = RESOURCE_CLOCK,
+ .u = {
+ .clock = { CLOCK_PBA, 14 },
+ },
+ },
+};
+static const struct resource sm_resource[] = {
+ {
+ .type = RESOURCE_CLOCK,
+ .u = {
+ .clock = { CLOCK_PBB, 0 },
+ },
+ },
+};
+static const struct resource intc_resource[] = {
+ {
+ .type = RESOURCE_CLOCK,
+ .u = {
+ .clock = { CLOCK_PBB, 1 },
+ },
+ },
+};
+static const struct resource hmatrix_resource[] = {
+ {
+ .type = RESOURCE_CLOCK,
+ .u = {
+ .clock = { CLOCK_PBB, 2 },
+ },
+ },
+};
+#if defined(CFG_HPDC)
+static const struct resource hpdc_resource[] = {
+ {
+ .type = RESOURCE_CLOCK,
+ .u = {
+ .clock = { CLOCK_PBA, 16 },
+ },
+ },
+};
+#endif
+#if defined(CFG_MACB0)
+static const struct resource macb0_resource[] = {
+ {
+ .type = RESOURCE_CLOCK,
+ .u = {
+ .clock = { CLOCK_HSB, 8 },
+ },
+ }, {
+ .type = RESOURCE_CLOCK,
+ .u = {
+ .clock = { CLOCK_PBB, 6 },
+ },
+ }, {
+ .type = RESOURCE_GPIO,
+ .u = {
+ .gpio = { 19, DEVICE_PIOC, GPIO_FUNC_A, 0 },
+ },
+ },
+};
+#endif
+#if defined(CFG_MACB1)
+static const struct resource macb1_resource[] = {
+ {
+ .type = RESOURCE_CLOCK,
+ .u = {
+ .clock = { CLOCK_HSB, 9 },
+ },
+ }, {
+ .type = RESOURCE_CLOCK,
+ .u = {
+ .clock = { CLOCK_PBB, 7 },
+ },
+ }, {
+ .type = RESOURCE_GPIO,
+ .u = {
+ .gpio = { 12, DEVICE_PIOC, GPIO_FUNC_B, 19 },
+ },
+ }, {
+ .type = RESOURCE_GPIO,
+ .u = {
+ .gpio = { 14, DEVICE_PIOD, GPIO_FUNC_B, 2 },
+ },
+ },
+};
+#endif
+#if defined(CFG_LCDC)
+static const struct resource lcdc_resource[] = {
+ {
+ .type = RESOURCE_CLOCK,
+ .u = {
+ .clock = { CLOCK_HSB, 7 },
+ },
+ },
+};
+#endif
+#if defined(CFG_USART0)
+static const struct resource usart0_resource[] = {
+ {
+ .type = RESOURCE_CLOCK,
+ .u = {
+ .clock = { CLOCK_PBA, 3 },
+ },
+ }, {
+ .type = RESOURCE_GPIO,
+ .u = {
+ .gpio = { 2, DEVICE_PIOA, GPIO_FUNC_B, 8 },
+ },
+ },
+};
+#endif
+#if defined(CFG_USART1)
+static const struct resource usart1_resource[] = {
+ {
+ .type = RESOURCE_CLOCK,
+ .u = {
+ .clock = { CLOCK_PBA, 4 },
+ },
+ }, {
+ .type = RESOURCE_GPIO,
+ .u = {
+ .gpio = { 2, DEVICE_PIOA, GPIO_FUNC_A, 17 },
+ },
+ },
+};
+#endif
+#if defined(CFG_USART2)
+static const struct resource usart2_resource[] = {
+ {
+ .type = RESOURCE_CLOCK,
+ .u = {
+ .clock = { CLOCK_PBA, 5 },
+ },
+ }, {
+ .type = RESOURCE_GPIO,
+ .u = {
+ .gpio = { 2, DEVICE_PIOB, GPIO_FUNC_B, 26 },
+ },
+ },
+};
+#endif
+#if defined(CFG_USART3)
+static const struct resource usart3_resource[] = {
+ {
+ .type = RESOURCE_CLOCK,
+ .u = {
+ .clock = { CLOCK_PBA, 6 },
+ },
+ }, {
+ .type = RESOURCE_GPIO,
+ .u = {
+ .gpio = { 2, DEVICE_PIOB, GPIO_FUNC_B, 17 },
+ },
+ },
+};
+#endif
+#if defined(CFG_MMCI)
+static const struct resource mmci_resource[] = {
+ {
+ .type = RESOURCE_CLOCK,
+ .u = {
+ .clock = { CLOCK_PBB, 9 },
+ },
+ }, {
+ .type = RESOURCE_GPIO,
+ .u = {
+ .gpio = { 6, DEVICE_PIOA, GPIO_FUNC_A, 10 },
+ },
+ },
+};
+#endif
+#if defined(CFG_DMAC)
+static const struct resource dmac_resource[] = {
+ {
+ .type = RESOURCE_CLOCK,
+ .u = {
+ .clock = { CLOCK_HSB, 10 },
+ },
+ },
+};
+#endif
+
+const struct device chip_device[] = {
+ [DEVICE_HEBI] = {
+ .regs = (void *)HSMC_BASE,
+ .nr_resources = ARRAY_SIZE(hebi_resource),
+ .resource = hebi_resource,
+ },
+ [DEVICE_PBA_BRIDGE] = {
+ .nr_resources = ARRAY_SIZE(pba_bridge_resource),
+ .resource = pba_bridge_resource,
+ },
+ [DEVICE_PBB_BRIDGE] = {
+ .nr_resources = ARRAY_SIZE(pbb_bridge_resource),
+ .resource = pbb_bridge_resource,
+ },
+ [DEVICE_HRAMC] = {
+ .nr_resources = ARRAY_SIZE(hramc_resource),
+ .resource = hramc_resource,
+ },
+ [DEVICE_PIOA] = {
+ .regs = (void *)PIOA_BASE,
+ .nr_resources = ARRAY_SIZE(pioa_resource),
+ .resource = pioa_resource,
+ },
+ [DEVICE_PIOB] = {
+ .regs = (void *)PIOB_BASE,
+ .nr_resources = ARRAY_SIZE(piob_resource),
+ .resource = piob_resource,
+ },
+ [DEVICE_PIOC] = {
+ .regs = (void *)PIOC_BASE,
+ .nr_resources = ARRAY_SIZE(pioc_resource),
+ .resource = pioc_resource,
+ },
+ [DEVICE_PIOD] = {
+ .regs = (void *)PIOD_BASE,
+ .nr_resources = ARRAY_SIZE(piod_resource),
+ .resource = piod_resource,
+ },
+ [DEVICE_PIOE] = {
+ .regs = (void *)PIOE_BASE,
+ .nr_resources = ARRAY_SIZE(pioe_resource),
+ .resource = pioe_resource,
+ },
+ [DEVICE_SM] = {
+ .regs = (void *)SM_BASE,
+ .nr_resources = ARRAY_SIZE(sm_resource),
+ .resource = sm_resource,
+ },
+ [DEVICE_INTC] = {
+ .regs = (void *)INTC_BASE,
+ .nr_resources = ARRAY_SIZE(intc_resource),
+ .resource = intc_resource,
+ },
+ [DEVICE_HMATRIX] = {
+ .regs = (void *)HMATRIX_BASE,
+ .nr_resources = ARRAY_SIZE(hmatrix_resource),
+ .resource = hmatrix_resource,
+ },
+#if defined(CFG_HPDC)
+ [DEVICE_HPDC] = {
+ .nr_resources = ARRAY_SIZE(hpdc_resource),
+ .resource = hpdc_resource,
+ },
+#endif
+#if defined(CFG_MACB0)
+ [DEVICE_MACB0] = {
+ .regs = (void *)MACB0_BASE,
+ .nr_resources = ARRAY_SIZE(macb0_resource),
+ .resource = macb0_resource,
+ },
+#endif
+#if defined(CFG_MACB1)
+ [DEVICE_MACB1] = {
+ .regs = (void *)MACB1_BASE,
+ .nr_resources = ARRAY_SIZE(macb1_resource),
+ .resource = macb1_resource,
+ },
+#endif
+#if defined(CFG_LCDC)
+ [DEVICE_LCDC] = {
+ .nr_resources = ARRAY_SIZE(lcdc_resource),
+ .resource = lcdc_resource,
+ },
+#endif
+#if defined(CFG_USART0)
+ [DEVICE_USART0] = {
+ .regs = (void *)USART0_BASE,
+ .nr_resources = ARRAY_SIZE(usart0_resource),
+ .resource = usart0_resource,
+ },
+#endif
+#if defined(CFG_USART1)
+ [DEVICE_USART1] = {
+ .regs = (void *)USART1_BASE,
+ .nr_resources = ARRAY_SIZE(usart1_resource),
+ .resource = usart1_resource,
+ },
+#endif
+#if defined(CFG_USART2)
+ [DEVICE_USART2] = {
+ .regs = (void *)USART2_BASE,
+ .nr_resources = ARRAY_SIZE(usart2_resource),
+ .resource = usart2_resource,
+ },
+#endif
+#if defined(CFG_USART3)
+ [DEVICE_USART3] = {
+ .regs = (void *)USART3_BASE,
+ .nr_resources = ARRAY_SIZE(usart3_resource),
+ .resource = usart3_resource,
+ },
+#endif
+#if defined(CFG_MMCI)
+ [DEVICE_MMCI] = {
+ .regs = (void *)MMCI_BASE,
+ .nr_resources = ARRAY_SIZE(mmci_resource),
+ .resource = mmci_resource,
+ },
+#endif
+#if defined(CFG_DMAC)
+ [DEVICE_DMAC] = {
+ .regs = (void *)DMAC_BASE,
+ .nr_resources = ARRAY_SIZE(dmac_resource),
+ .resource = dmac_resource,
+ },
+#endif
+};
diff --git a/cpu/at32ap/at32ap7000/hebi.c b/cpu/at32ap/at32ap7000/hebi.c
new file mode 100644
index 0000000..3b32adf
--- /dev/null
+++ b/cpu/at32ap/at32ap7000/hebi.c
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2006 Atmel Corporation
+ *
+ * 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>
+
+#include <asm/arch/hmatrix2.h>
+#include <asm/arch/memory-map.h>
+#include <asm/arch/platform.h>
+
+void cpu_enable_sdram(void)
+{
+ const struct device *hmatrix;
+
+ hmatrix = get_device(DEVICE_HMATRIX);
+
+ /* Set the SDRAM_ENABLE bit in the HEBI SFR */
+ hmatrix2_writel(hmatrix, SFR4, 1 << 1);
+}
diff --git a/cpu/at32ap/cache.c b/cpu/at32ap/cache.c
new file mode 100644
index 0000000..41fb5aa
--- /dev/null
+++ b/cpu/at32ap/cache.c
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2004-2006 Atmel Corporation
+ *
+ * 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/cacheflush.h>
+
+void dcache_clean_range(volatile void *start, size_t size)
+{
+ unsigned long v, begin, end, linesz;
+
+ linesz = CFG_DCACHE_LINESZ;
+
+ /* You asked for it, you got it */
+ begin = (unsigned long)start & ~(linesz - 1);
+ end = ((unsigned long)start + size + linesz - 1) & ~(linesz - 1);
+
+ for (v = begin; v < end; v += linesz)
+ dcache_clean_line((void *)v);
+
+ sync_write_buffer();
+}
+
+void dcache_invalidate_range(volatile void *start, size_t size)
+{
+ unsigned long v, begin, end, linesz;
+
+ linesz = CFG_DCACHE_LINESZ;
+
+ /* You asked for it, you got it */
+ begin = (unsigned long)start & ~(linesz - 1);
+ end = ((unsigned long)start + size + linesz - 1) & ~(linesz - 1);
+
+ for (v = begin; v < end; v += linesz)
+ dcache_invalidate_line((void *)v);
+}
+
+void dcache_flush_range(volatile void *start, size_t size)
+{
+ unsigned long v, begin, end, linesz;
+
+ linesz = CFG_DCACHE_LINESZ;
+
+ /* You asked for it, you got it */
+ begin = (unsigned long)start & ~(linesz - 1);
+ end = ((unsigned long)start + size + linesz - 1) & ~(linesz - 1);
+
+ for (v = begin; v < end; v += linesz)
+ dcache_flush_line((void *)v);
+
+ sync_write_buffer();
+}
+
+void icache_invalidate_range(volatile void *start, size_t size)
+{
+ unsigned long v, begin, end, linesz;
+
+ linesz = CFG_ICACHE_LINESZ;
+
+ /* You asked for it, you got it */
+ begin = (unsigned long)start & ~(linesz - 1);
+ end = ((unsigned long)start + size + linesz - 1) & ~(linesz - 1);
+
+ for (v = begin; v < end; v += linesz)
+ icache_invalidate_line((void *)v);
+}
+
+/*
+ * This is called after loading something into memory. We need to
+ * make sure that everything that was loaded is actually written to
+ * RAM, and that the icache will look for it. Cleaning the dcache and
+ * invalidating the icache will do the trick.
+ */
+void flush_cache (unsigned long start_addr, unsigned long size)
+{
+ dcache_clean_range((void *)start_addr, size);
+ icache_invalidate_range((void *)start_addr, size);
+}
diff --git a/cpu/at32ap/config.mk b/cpu/at32ap/config.mk
new file mode 100644
index 0000000..1c12169
--- /dev/null
+++ b/cpu/at32ap/config.mk
@@ -0,0 +1,22 @@
+#
+# Copyright (C) 2005-2006 Atmel Corporation
+#
+# 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
+#
+PLATFORM_RELFLAGS += -mcpu=ap7000
diff --git a/cpu/at32ap/cpu.c b/cpu/at32ap/cpu.c
new file mode 100644
index 0000000..37e3ea0
--- /dev/null
+++ b/cpu/at32ap/cpu.c
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2005-2006 Atmel Corporation
+ *
+ * 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 <asm/io.h>
+#include <asm/sections.h>
+#include <asm/sysreg.h>
+
+#include <asm/arch/memory-map.h>
+#include <asm/arch/platform.h>
+
+#include "hsmc3.h"
+
+DECLARE_GLOBAL_DATA_PTR;
+
+int cpu_init(void)
+{
+ const struct device *hebi;
+ extern void _evba(void);
+ char *p;
+
+ gd->cpu_hz = CFG_OSC0_HZ;
+
+ /* fff03400: 00010001 04030402 00050005 10011103 */
+ hebi = get_device(DEVICE_HEBI);
+ hsmc3_writel(hebi, MODE0, 0x00031103);
+ hsmc3_writel(hebi, CYCLE0, 0x000c000d);
+ hsmc3_writel(hebi, PULSE0, 0x0b0a0906);
+ hsmc3_writel(hebi, SETUP0, 0x00010002);
+
+ pm_init();
+
+ sysreg_write(EVBA, (unsigned long)&_evba);
+ asm volatile("csrf %0" : : "i"(SYSREG_EM_OFFSET));
+ gd->console_uart = get_device(CFG_CONSOLE_UART_DEV);
+
+ /* Lock everything that mess with the flash in the icache */
+ for (p = __flashprog_start; p <= (__flashprog_end + CFG_ICACHE_LINESZ);
+ p += CFG_ICACHE_LINESZ)
+ asm volatile("cache %0, 0x02" : "=m"(*p) :: "memory");
+
+ return 0;
+}
+
+void prepare_to_boot(void)
+{
+ /* Flush both caches and the write buffer */
+ asm volatile("cache %0[4], 010\n\t"
+ "cache %0[0], 000\n\t"
+ "sync 0" : : "r"(0) : "memory");
+}
+
+int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+ /* This will reset the CPU core, caches, MMU and all internal busses */
+ __builtin_mtdr(8, 1 << 13); /* set DC:DBE */
+ __builtin_mtdr(8, 1 << 30); /* set DC:RES */
+
+ /* Flush the pipeline before we declare it a failure */
+ asm volatile("sub pc, pc, -4");
+
+ return -1;
+}
diff --git a/cpu/at32ap/device.c b/cpu/at32ap/device.c
new file mode 100644
index 0000000..89914b6
--- /dev/null
+++ b/cpu/at32ap/device.c
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2006 Atmel Corporation
+ *
+ * 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/arch/platform.h>
+
+#include "sm.h"
+
+struct device_state {
+ int refcount;
+};
+
+static struct device_state device_state[NR_DEVICES];
+
+static int claim_resource(const struct resource *res)
+{
+ int ret = 0;
+
+ switch (res->type) {
+ case RESOURCE_GPIO:
+ ret = gpio_set_func(res->u.gpio.gpio_dev,
+ res->u.gpio.start,
+ res->u.gpio.nr_pins,
+ res->u.gpio.func);
+ break;
+ case RESOURCE_CLOCK:
+ ret = pm_enable_clock(res->u.clock.id, res->u.clock.index);
+ break;
+ }
+
+ return ret;
+}
+
+static void free_resource(const struct resource *res)
+{
+ switch (res->type) {
+ case RESOURCE_GPIO:
+ gpio_free(res->u.gpio.gpio_dev, res->u.gpio.start,
+ res->u.gpio.nr_pins);
+ break;
+ case RESOURCE_CLOCK:
+ pm_disable_clock(res->u.clock.id, res->u.clock.index);
+ break;
+ }
+}
+
+static int init_dev(const struct device *dev)
+{
+ unsigned int i;
+ int ret = 0;
+
+ for (i = 0; i < dev->nr_resources; i++) {
+ ret = claim_resource(&dev->resource[i]);
+ if (ret)
+ goto cleanup;
+ }
+
+ return 0;
+
+cleanup:
+ while (i--)
+ free_resource(&dev->resource[i]);
+
+ return ret;
+}
+
+const struct device *get_device(enum device_id devid)
+{
+ struct device_state *devstate;
+ const struct device *dev;
+ unsigned long flags;
+ int initialized = 0;
+ int ret = 0;
+
+ devstate = &device_state[devid];
+ dev = &chip_device[devid];
+
+ flags = disable_interrupts();
+ if (devstate->refcount++)
+ initialized = 1;
+ if (flags)
+ enable_interrupts();
+
+ if (!initialized)
+ ret = init_dev(dev);
+
+ return ret ? NULL : dev;
+}
+
+void put_device(const struct device *dev)
+{
+ struct device_state *devstate;
+ unsigned long devid, flags;
+
+ devid = (unsigned long)(dev - chip_device) / sizeof(struct device);
+ devstate = &device_state[devid];
+
+ flags = disable_interrupts();
+ devstate--;
+ if (!devstate) {
+ unsigned int i;
+ for (i = 0; i < dev->nr_resources; i++)
+ free_resource(&dev->resource[i]);
+ }
+ if (flags)
+ enable_interrupts();
+}
diff --git a/cpu/at32ap/entry.S b/cpu/at32ap/entry.S
new file mode 100644
index 0000000..b52d798
--- /dev/null
+++ b/cpu/at32ap/entry.S
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2004-2006 Atmel Corporation
+ *
+ * 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/sysreg.h>
+#include <asm/ptrace.h>
+
+ .section .text.exception,"ax"
+ .global _evba
+ .type _evba,@function
+ .align 10
+_evba:
+ .irp x,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16
+ .align 2
+ rjmp unknown_exception
+ .endr
+
+ .global timer_interrupt_handler
+ .type timer_interrupt_handler,@function
+ .align 2
+timer_interrupt_handler:
+ /*
+ * Increment timer_overflow and re-write COMPARE with 0xffffffff.
+ *
+ * We're running at interrupt level 3, so we don't need to save
+ * r8-r12 or lr to the stack.
+ */
+ mov r8, lo(timer_overflow)
+ orh r8, hi(timer_overflow)
+ ld.w r9, r8[0]
+ mov r10, -1
+ mtsr SYSREG_COMPARE, r10
+ sub r9, -1
+ st.w r8[0], r9
+ rete
+
+ .type unknown_exception, @function
+unknown_exception:
+ pushm r0-r12
+ sub r8, sp, REG_R12 - REG_R0 - 4
+ mov r9, lr
+ mfsr r10, SYSREG_RAR_EX
+ mfsr r11, SYSREG_RSR_EX
+ pushm r8-r11
+ mfsr r12, SYSREG_ECR
+ mov r11, sp
+ rcall do_unknown_exception
+1: rjmp 1b
diff --git a/cpu/at32ap/exception.c b/cpu/at32ap/exception.c
new file mode 100644
index 0000000..4123c44
--- /dev/null
+++ b/cpu/at32ap/exception.c
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2005-2006 Atmel Corporation
+ *
+ * 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/sysreg.h>
+#include <asm/ptrace.h>
+
+static const char * const cpu_modes[8] = {
+ "Application", "Supervisor", "Interrupt level 0", "Interrupt level 1",
+ "Interrupt level 2", "Interrupt level 3", "Exception", "NMI"
+};
+
+static void dump_mem(const char *str, unsigned long bottom, unsigned long top)
+{
+ unsigned long p;
+ int i;
+
+ printf("%s(0x%08lx to 0x%08lx)\n", str, bottom, top);
+
+ for (p = bottom & ~31; p < top; ) {
+ printf("%04lx: ", p & 0xffff);
+
+ for (i = 0; i < 8; i++, p += 4) {
+ unsigned int val;
+
+ if (p < bottom || p >= top)
+ printf(" ");
+ else {
+ val = *(unsigned long *)p;
+ printf("%08x ", val);
+ }
+ }
+ printf("\n");
+ }
+}
+
+void do_unknown_exception(unsigned int ecr, struct pt_regs *regs)
+{
+ unsigned int mode;
+
+ printf("\n *** Unhandled exception %u at PC=0x%08lx\n", ecr, regs->pc);
+
+ switch (ecr) {
+ case ECR_BUS_ERROR_WRITE:
+ case ECR_BUS_ERROR_READ:
+ printf("Bus error at address 0x%08lx\n",
+ sysreg_read(BEAR));
+ break;
+ case ECR_TLB_MULTIPLE:
+ case ECR_ADDR_ALIGN_X:
+ case ECR_PROTECTION_X:
+ case ECR_ADDR_ALIGN_R:
+ case ECR_ADDR_ALIGN_W:
+ case ECR_PROTECTION_R:
+ case ECR_PROTECTION_W:
+ case ECR_DTLB_MODIFIED:
+ case ECR_TLB_MISS_X:
+ case ECR_TLB_MISS_R:
+ case ECR_TLB_MISS_W:
+ printf("MMU exception at address 0x%08lx\n",
+ sysreg_read(TLBEAR));
+ break;
+ }
+
+ printf(" pc: %08lx lr: %08lx sp: %08lx r12: %08lx\n",
+ regs->pc, regs->lr, regs->sp, regs->r12);
+ printf(" r11: %08lx r10: %08lx r9: %08lx r8: %08lx\n",
+ regs->r11, regs->r10, regs->r9, regs->r8);
+ printf(" r7: %08lx r6: %08lx r5: %08lx r4: %08lx\n",
+ regs->r7, regs->r6, regs->r5, regs->r4);
+ printf(" r3: %08lx r2: %08lx r1: %08lx r0: %08lx\n",
+ regs->r3, regs->r2, regs->r1, regs->r0);
+ printf("Flags: %c%c%c%c%c\n",
+ regs->sr & SR_Q ? 'Q' : 'q',
+ regs->sr & SR_V ? 'V' : 'v',
+ regs->sr & SR_N ? 'N' : 'n',
+ regs->sr & SR_Z ? 'Z' : 'z',
+ regs->sr & SR_C ? 'C' : 'c');
+ printf("Mode bits: %c%c%c%c%c%c%c%c%c\n",
+ regs->sr & SR_H ? 'H' : 'h',
+ regs->sr & SR_R ? 'R' : 'r',
+ regs->sr & SR_J ? 'J' : 'j',
+ regs->sr & SR_EM ? 'E' : 'e',
+ regs->sr & SR_I3M ? '3' : '.',
+ regs->sr & SR_I2M ? '2' : '.',
+ regs->sr & SR_I1M ? '1' : '.',
+ regs->sr & SR_I0M ? '0' : '.',
+ regs->sr & SR_GM ? 'G' : 'g');
+ mode = (regs->sr >> SYSREG_M0_OFFSET) & 7;
+ printf("CPU Mode: %s\n", cpu_modes[mode]);
+
+ /* Avoid exception loops */
+ if (regs->sp >= CFG_INIT_SP_ADDR
+ || regs->sp < (CFG_INIT_SP_ADDR - CONFIG_STACKSIZE))
+ printf("\nStack pointer seems bogus, won't do stack dump\n");
+ else
+ dump_mem("\nStack: ", regs->sp, CFG_INIT_SP_ADDR);
+
+ panic("Unhandled exception\n");
+}
diff --git a/cpu/at32ap/hsdramc.c b/cpu/at32ap/hsdramc.c
new file mode 100644
index 0000000..f36da35
--- /dev/null
+++ b/cpu/at32ap/hsdramc.c
@@ -0,0 +1,155 @@
+/*
+ * Copyright (C) 2005-2006 Atmel Corporation
+ *
+ * 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 CFG_HSDRAMC
+#include <asm/io.h>
+#include <asm/sdram.h>
+
+#include <asm/arch/platform.h>
+
+#include "hsdramc1.h"
+
+struct hsdramc {
+ const struct device *hebi;
+ void *regs;
+};
+
+static struct hsdramc hsdramc;
+
+unsigned long sdram_init(const struct sdram_info *info)
+{
+ unsigned long *sdram = (unsigned long *)uncached(info->phys_addr);
+ unsigned long sdram_size;
+ unsigned long tmp;
+ unsigned long bus_hz;
+ unsigned int i;
+
+ hsdramc.hebi = get_device(DEVICE_HEBI);
+ if (!hsdramc.hebi)
+ return 0;
+
+ /* FIXME: Both of these lines are complete hacks */
+ hsdramc.regs = hsdramc.hebi->regs + 0x400;
+ bus_hz = pm_get_clock_freq(hsdramc.hebi->resource[0].u.clock.id);
+
+ cpu_enable_sdram();
+
+ tmp = (HSDRAMC1_BF(NC, info->col_bits - 8)
+ | HSDRAMC1_BF(NR, info->row_bits - 11)
+ | HSDRAMC1_BF(NB, info->bank_bits - 1)
+ | HSDRAMC1_BF(CAS, info->cas)
+ | HSDRAMC1_BF(TWR, info->twr)
+ | HSDRAMC1_BF(TRC, info->trc)
+ | HSDRAMC1_BF(TRP, info->trp)
+ | HSDRAMC1_BF(TRCD, info->trcd)
+ | HSDRAMC1_BF(TRAS, info->tras)
+ | HSDRAMC1_BF(TXSR, info->txsr));
+
+#ifdef CFG_SDRAM_16BIT
+ tmp |= HSDRAMC1_BIT(DBW);
+ sdram_size = 1 << (info->row_bits + info->col_bits
+ + info->bank_bits + 1);
+#else
+ sdram_size = 1 << (info->row_bits + info->col_bits
+ + info->bank_bits + 2);
+#endif
+
+ hsdramc1_writel(&hsdramc, CR, tmp);
+
+ /*
+ * Initialization sequence for SDRAM, from the data sheet:
+ *
+ * 1. A minimum pause of 200 us is provided to precede any
+ * signal toggle.
+ */
+ udelay(200);
+
+ /*
+ * 2. A Precharge All command is issued to the SDRAM
+ */
+ hsdramc1_writel(&hsdramc, MR, HSDRAMC1_MODE_BANKS_PRECHARGE);
+ hsdramc1_readl(&hsdramc, MR);
+ writel(0, sdram);
+
+ /*
+ * 3. Eight auto-refresh (CBR) cycles are provided
+ */
+ hsdramc1_writel(&hsdramc, MR, HSDRAMC1_MODE_AUTO_REFRESH);
+ hsdramc1_readl(&hsdramc, MR);
+ for (i = 0; i < 8; i++)
+ writel(0, sdram);
+
+ /*
+ * 4. A mode register set (MRS) cycle is issued to program
+ * SDRAM parameters, in particular CAS latency and burst
+ * length.
+ *
+ * CAS from info struct, burst length 1, serial burst type
+ */
+ hsdramc1_writel(&hsdramc, MR, HSDRAMC1_MODE_LOAD_MODE);
+ hsdramc1_readl(&hsdramc, MR);
+ writel(0, sdram + (info->cas << 4));
+
+ /*
+ * 5. A Normal Mode command is provided, 3 clocks after tMRD
+ * is met.
+ *
+ * From the timing diagram, it looks like tMRD is 3
+ * cycles...try a dummy read from the peripheral bus.
+ */
+ hsdramc1_readl(&hsdramc, MR);
+ hsdramc1_writel(&hsdramc, MR, HSDRAMC1_MODE_NORMAL);
+ hsdramc1_readl(&hsdramc, MR);
+ writel(0, sdram);
+
+ /*
+ * 6. Write refresh rate into SDRAMC refresh timer count
+ * register (refresh rate = timing between refresh cycles).
+ *
+ * 15.6 us is a typical value for a burst of length one
+ */
+ hsdramc1_writel(&hsdramc, TR, (156 * (bus_hz / 1000)) / 10000);
+
+ printf("SDRAM: %u MB at address 0x%08lx\n",
+ sdram_size >> 20, info->phys_addr);
+
+ printf("Testing SDRAM...");
+ for (i = 0; i < sdram_size / 4; i++)
+ sdram[i] = i;
+
+ for (i = 0; i < sdram_size / 4; i++) {
+ tmp = sdram[i];
+ if (tmp != i) {
+ printf("FAILED at address 0x%08lx\n",
+ info->phys_addr + i * 4);
+ printf("SDRAM: read 0x%lx, expected 0x%lx\n", tmp, i);
+ return 0;
+ }
+ }
+
+ puts("OK\n");
+
+ return sdram_size;
+}
+
+#endif /* CFG_HSDRAMC */
diff --git a/cpu/at32ap/hsdramc1.h b/cpu/at32ap/hsdramc1.h
new file mode 100644
index 0000000..ce229bc
--- /dev/null
+++ b/cpu/at32ap/hsdramc1.h
@@ -0,0 +1,143 @@
+/*
+ * Register definitions for SDRAM Controller
+ */
+#ifndef __ASM_AVR32_HSDRAMC1_H__
+#define __ASM_AVR32_HSDRAMC1_H__
+
+/* HSDRAMC1 register offsets */
+#define HSDRAMC1_MR 0x0000
+#define HSDRAMC1_TR 0x0004
+#define HSDRAMC1_CR 0x0008
+#define HSDRAMC1_HSR 0x000c
+#define HSDRAMC1_LPR 0x0010
+#define HSDRAMC1_IER 0x0014
+#define HSDRAMC1_IDR 0x0018
+#define HSDRAMC1_IMR 0x001c
+#define HSDRAMC1_ISR 0x0020
+#define HSDRAMC1_MDR 0x0024
+#define HSDRAMC1_VERSION 0x00fc
+
+/* Bitfields in MR */
+#define HSDRAMC1_MODE_OFFSET 0
+#define HSDRAMC1_MODE_SIZE 3
+
+/* Bitfields in TR */
+#define HSDRAMC1_COUNT_OFFSET 0
+#define HSDRAMC1_COUNT_SIZE 12
+
+/* Bitfields in CR */
+#define HSDRAMC1_NC_OFFSET 0
+#define HSDRAMC1_NC_SIZE 2
+#define HSDRAMC1_NR_OFFSET 2
+#define HSDRAMC1_NR_SIZE 2
+#define HSDRAMC1_NB_OFFSET 4
+#define HSDRAMC1_NB_SIZE 1
+#define HSDRAMC1_CAS_OFFSET 5
+#define HSDRAMC1_CAS_SIZE 2
+#define HSDRAMC1_DBW_OFFSET 7
+#define HSDRAMC1_DBW_SIZE 1
+#define HSDRAMC1_TWR_OFFSET 8
+#define HSDRAMC1_TWR_SIZE 4
+#define HSDRAMC1_TRC_OFFSET 12
+#define HSDRAMC1_TRC_SIZE 4
+#define HSDRAMC1_TRP_OFFSET 16
+#define HSDRAMC1_TRP_SIZE 4
+#define HSDRAMC1_TRCD_OFFSET 20
+#define HSDRAMC1_TRCD_SIZE 4
+#define HSDRAMC1_TRAS_OFFSET 24
+#define HSDRAMC1_TRAS_SIZE 4
+#define HSDRAMC1_TXSR_OFFSET 28
+#define HSDRAMC1_TXSR_SIZE 4
+
+/* Bitfields in HSR */
+#define HSDRAMC1_DA_OFFSET 0
+#define HSDRAMC1_DA_SIZE 1
+
+/* Bitfields in LPR */
+#define HSDRAMC1_LPCB_OFFSET 0
+#define HSDRAMC1_LPCB_SIZE 2
+#define HSDRAMC1_PASR_OFFSET 4
+#define HSDRAMC1_PASR_SIZE 3
+#define HSDRAMC1_TCSR_OFFSET 8
+#define HSDRAMC1_TCSR_SIZE 2
+#define HSDRAMC1_DS_OFFSET 10
+#define HSDRAMC1_DS_SIZE 2
+#define HSDRAMC1_TIMEOUT_OFFSET 12
+#define HSDRAMC1_TIMEOUT_SIZE 2
+
+/* Bitfields in IDR */
+#define HSDRAMC1_RES_OFFSET 0
+#define HSDRAMC1_RES_SIZE 1
+
+/* Bitfields in MDR */
+#define HSDRAMC1_MD_OFFSET 0
+#define HSDRAMC1_MD_SIZE 2
+
+/* Bitfields in VERSION */
+#define HSDRAMC1_VERSION_OFFSET 0
+#define HSDRAMC1_VERSION_SIZE 12
+#define HSDRAMC1_MFN_OFFSET 16
+#define HSDRAMC1_MFN_SIZE 3
+
+/* Constants for MODE */
+#define HSDRAMC1_MODE_NORMAL 0
+#define HSDRAMC1_MODE_NOP 1
+#define HSDRAMC1_MODE_BANKS_PRECHARGE 2
+#define HSDRAMC1_MODE_LOAD_MODE 3
+#define HSDRAMC1_MODE_AUTO_REFRESH 4
+#define HSDRAMC1_MODE_EXT_LOAD_MODE 5
+#define HSDRAMC1_MODE_POWER_DOWN 6
+
+/* Constants for NC */
+#define HSDRAMC1_NC_8_COLUMN_BITS 0
+#define HSDRAMC1_NC_9_COLUMN_BITS 1
+#define HSDRAMC1_NC_10_COLUMN_BITS 2
+#define HSDRAMC1_NC_11_COLUMN_BITS 3
+
+/* Constants for NR */
+#define HSDRAMC1_NR_11_ROW_BITS 0
+#define HSDRAMC1_NR_12_ROW_BITS 1
+#define HSDRAMC1_NR_13_ROW_BITS 2
+
+/* Constants for NB */
+#define HSDRAMC1_NB_TWO_BANKS 0
+#define HSDRAMC1_NB_FOUR_BANKS 1
+
+/* Constants for CAS */
+#define HSDRAMC1_CAS_ONE_CYCLE 1
+#define HSDRAMC1_CAS_TWO_CYCLES 2
+
+/* Constants for DBW */
+#define HSDRAMC1_DBW_32_BITS 0
+#define HSDRAMC1_DBW_16_BITS 1
+
+/* Constants for TIMEOUT */
+#define HSDRAMC1_TIMEOUT_AFTER_END 0
+#define HSDRAMC1_TIMEOUT_64_CYC_AFTER_END 1
+#define HSDRAMC1_TIMEOUT_128_CYC_AFTER_END 2
+
+/* Constants for MD */
+#define HSDRAMC1_MD_SDRAM 0
+#define HSDRAMC1_MD_LOW_POWER_SDRAM 1
+
+/* Bit manipulation macros */
+#define HSDRAMC1_BIT(name) \
+ (1 << HSDRAMC1_##name##_OFFSET)
+#define HSDRAMC1_BF(name,value) \
+ (((value) & ((1 << HSDRAMC1_##name##_SIZE) - 1)) \
+ << HSDRAMC1_##name##_OFFSET)
+#define HSDRAMC1_BFEXT(name,value) \
+ (((value) >> HSDRAMC1_##name##_OFFSET) \
+ & ((1 << HSDRAMC1_##name##_SIZE) - 1))
+#define HSDRAMC1_BFINS(name,value,old) \
+ (((old) & ~(((1 << HSDRAMC1_##name##_SIZE) - 1) \
+ << HSDRAMC1_##name##_OFFSET)) \
+ | HSDRAMC1_BF(name,value))
+
+/* Register access macros */
+#define hsdramc1_readl(port,reg) \
+ readl((port)->regs + HSDRAMC1_##reg)
+#define hsdramc1_writel(port,reg,value) \
+ writel((value), (port)->regs + HSDRAMC1_##reg)
+
+#endif /* __ASM_AVR32_HSDRAMC1_H__ */
diff --git a/cpu/at32ap/hsmc3.h b/cpu/at32ap/hsmc3.h
new file mode 100644
index 0000000..ec78cee
--- /dev/null
+++ b/cpu/at32ap/hsmc3.h
@@ -0,0 +1,126 @@
+/*
+ * Register definitions for Static Memory Controller
+ */
+#ifndef __CPU_AT32AP_HSMC3_H__
+#define __CPU_AT32AP_HSMC3_H__
+
+/* HSMC3 register offsets */
+#define HSMC3_SETUP0 0x0000
+#define HSMC3_PULSE0 0x0004
+#define HSMC3_CYCLE0 0x0008
+#define HSMC3_MODE0 0x000c
+#define HSMC3_SETUP1 0x0010
+#define HSMC3_PULSE1 0x0014
+#define HSMC3_CYCLE1 0x0018
+#define HSMC3_MODE1 0x001c
+#define HSMC3_SETUP2 0x0020
+#define HSMC3_PULSE2 0x0024
+#define HSMC3_CYCLE2 0x0028
+#define HSMC3_MODE2 0x002c
+#define HSMC3_SETUP3 0x0030
+#define HSMC3_PULSE3 0x0034
+#define HSMC3_CYCLE3 0x0038
+#define HSMC3_MODE3 0x003c
+#define HSMC3_SETUP4 0x0040
+#define HSMC3_PULSE4 0x0044
+#define HSMC3_CYCLE4 0x0048
+#define HSMC3_MODE4 0x004c
+#define HSMC3_SETUP5 0x0050
+#define HSMC3_PULSE5 0x0054
+#define HSMC3_CYCLE5 0x0058
+#define HSMC3_MODE5 0x005c
+
+/* Bitfields in SETUP0 */
+#define HSMC3_NWE_SETUP_OFFSET 0
+#define HSMC3_NWE_SETUP_SIZE 6
+#define HSMC3_NCS_WR_SETUP_OFFSET 8
+#define HSMC3_NCS_WR_SETUP_SIZE 6
+#define HSMC3_NRD_SETUP_OFFSET 16
+#define HSMC3_NRD_SETUP_SIZE 6
+#define HSMC3_NCS_RD_SETUP_OFFSET 24
+#define HSMC3_NCS_RD_SETUP_SIZE 6
+
+/* Bitfields in PULSE0 */
+#define HSMC3_NWE_PULSE_OFFSET 0
+#define HSMC3_NWE_PULSE_SIZE 7
+#define HSMC3_NCS_WR_PULSE_OFFSET 8
+#define HSMC3_NCS_WR_PULSE_SIZE 7
+#define HSMC3_NRD_PULSE_OFFSET 16
+#define HSMC3_NRD_PULSE_SIZE 7
+#define HSMC3_NCS_RD_PULSE_OFFSET 24
+#define HSMC3_NCS_RD_PULSE_SIZE 7
+
+/* Bitfields in CYCLE0 */
+#define HSMC3_NWE_CYCLE_OFFSET 0
+#define HSMC3_NWE_CYCLE_SIZE 9
+#define HSMC3_NRD_CYCLE_OFFSET 16
+#define HSMC3_NRD_CYCLE_SIZE 9
+
+/* Bitfields in MODE0 */
+#define HSMC3_READ_MODE_OFFSET 0
+#define HSMC3_READ_MODE_SIZE 1
+#define HSMC3_WRITE_MODE_OFFSET 1
+#define HSMC3_WRITE_MODE_SIZE 1
+#define HSMC3_EXNW_MODE_OFFSET 4
+#define HSMC3_EXNW_MODE_SIZE 2
+#define HSMC3_BAT_OFFSET 8
+#define HSMC3_BAT_SIZE 1
+#define HSMC3_DBW_OFFSET 12
+#define HSMC3_DBW_SIZE 2
+#define HSMC3_TDF_CYCLES_OFFSET 16
+#define HSMC3_TDF_CYCLES_SIZE 4
+#define HSMC3_TDF_MODE_OFFSET 20
+#define HSMC3_TDF_MODE_SIZE 1
+#define HSMC3_PMEN_OFFSET 24
+#define HSMC3_PMEN_SIZE 1
+#define HSMC3_PS_OFFSET 28
+#define HSMC3_PS_SIZE 2
+
+/* Bitfields in MODE1 */
+#define HSMC3_PD_OFFSET 28
+#define HSMC3_PD_SIZE 2
+
+/* Constants for READ_MODE */
+#define HSMC3_READ_MODE_NCS_CONTROLLED 0
+#define HSMC3_READ_MODE_NRD_CONTROLLED 1
+
+/* Constants for WRITE_MODE */
+#define HSMC3_WRITE_MODE_NCS_CONTROLLED 0
+#define HSMC3_WRITE_MODE_NWE_CONTROLLED 1
+
+/* Constants for EXNW_MODE */
+#define HSMC3_EXNW_MODE_DISABLED 0
+#define HSMC3_EXNW_MODE_RESERVED 1
+#define HSMC3_EXNW_MODE_FROZEN 2
+#define HSMC3_EXNW_MODE_READY 3
+
+/* Constants for BAT */
+#define HSMC3_BAT_BYTE_SELECT 0
+#define HSMC3_BAT_BYTE_WRITE 1
+
+/* Constants for DBW */
+#define HSMC3_DBW_8_BITS 0
+#define HSMC3_DBW_16_BITS 1
+#define HSMC3_DBW_32_BITS 2
+
+/* Bit manipulation macros */
+#define HSMC3_BIT(name) \
+ (1 << HSMC3_##name##_OFFSET)
+#define HSMC3_BF(name,value) \
+ (((value) & ((1 << HSMC3_##name##_SIZE) - 1)) \
+ << HSMC3_##name##_OFFSET)
+#define HSMC3_BFEXT(name,value) \
+ (((value) >> HSMC3_##name##_OFFSET) \
+ & ((1 << HSMC3_##name##_SIZE) - 1))
+#define HSMC3_BFINS(name,value,old)\
+ (((old) & ~(((1 << HSMC3_##name##_SIZE) - 1) \
+ << HSMC3_##name##_OFFSET)) \
+ | HSMC3_BF(name,value))
+
+/* Register access macros */
+#define hsmc3_readl(port,reg) \
+ readl((port)->regs + HSMC3_##reg)
+#define hsmc3_writel(port,reg,value) \
+ writel((value), (port)->regs + HSMC3_##reg)
+
+#endif /* __CPU_AT32AP_HSMC3_H__ */
diff --git a/cpu/at32ap/interrupts.c b/cpu/at32ap/interrupts.c
new file mode 100644
index 0000000..d720cfa
--- /dev/null
+++ b/cpu/at32ap/interrupts.c
@@ -0,0 +1,154 @@
+/*
+ * Copyright (C) 2004-2006 Atmel Corporation
+ *
+ * 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/div64.h>
+#include <asm/errno.h>
+#include <asm/io.h>
+#include <asm/processor.h>
+#include <asm/sysreg.h>
+
+#include <asm/arch/platform.h>
+
+#define HANDLER_MASK 0x00ffffff
+#define INTLEV_SHIFT 30
+#define INTLEV_MASK 0x00000003
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/* Incremented whenever COUNT reaches 0xffffffff by timer_interrupt_handler */
+volatile unsigned long timer_overflow;
+
+/*
+ * Instead of dividing by get_tbclk(), multiply by this constant and
+ * right-shift the result by 32 bits.
+ */
+static unsigned long tb_factor;
+
+static const struct device *intc_dev;
+
+unsigned long get_tbclk(void)
+{
+ return gd->cpu_hz;
+}
+
+unsigned long long get_ticks(void)
+{
+ unsigned long lo, hi_now, hi_prev;
+
+ do {
+ hi_prev = timer_overflow;
+ lo = sysreg_read(COUNT);
+ hi_now = timer_overflow;
+ } while (hi_prev != hi_now);
+
+ return ((unsigned long long)hi_now << 32) | lo;
+}
+
+void reset_timer(void)
+{
+ sysreg_write(COUNT, 0);
+ cpu_sync_pipeline(); /* process any pending interrupts */
+ timer_overflow = 0;
+}
+
+unsigned long get_timer(unsigned long base)
+{
+ u64 now = get_ticks();
+
+ now *= tb_factor;
+ return (unsigned long)(now >> 32) - base;
+}
+
+void set_timer(unsigned long t)
+{
+ unsigned long long ticks = t;
+ unsigned long lo, hi, hi_new;
+
+ ticks = (ticks * get_tbclk()) / CFG_HZ;
+ hi = ticks >> 32;
+ lo = ticks & 0xffffffffUL;
+
+ do {
+ timer_overflow = hi;
+ sysreg_write(COUNT, lo);
+ hi_new = timer_overflow;
+ } while (hi_new != hi);
+}
+
+/*
+ * For short delays only. It will overflow after a few seconds.
+ */
+void udelay(unsigned long usec)
+{
+ unsigned long now, end;
+
+ now = sysreg_read(COUNT);
+
+ end = ((usec * (get_tbclk() / 10000)) + 50) / 100;
+ end += now;
+
+ while (now > end)
+ now = sysreg_read(COUNT);
+
+ while (now < end)
+ now = sysreg_read(COUNT);
+}
+
+static int set_interrupt_handler(unsigned int nr, void (*handler)(void),
+ unsigned int priority)
+{
+ unsigned long intpr;
+ unsigned long handler_addr = (unsigned long)handler;
+
+ if ((handler_addr & HANDLER_MASK) != handler_addr
+ || (priority & INTLEV_MASK) != priority)
+ return -EINVAL;
+
+ intpr = (handler_addr & HANDLER_MASK);
+ intpr |= (priority & INTLEV_MASK) << INTLEV_SHIFT;
+ writel(intpr, intc_dev->regs + 4 * nr);
+
+ return 0;
+}
+
+void timer_init(void)
+{
+ extern void timer_interrupt_handler(void);
+ u64 tmp;
+
+ sysreg_write(COUNT, 0);
+
+ tmp = (u64)CFG_HZ << 32;
+ tmp += gd->cpu_hz / 2;
+ do_div(tmp, gd->cpu_hz);
+ tb_factor = (u32)tmp;
+
+ intc_dev = get_device(DEVICE_INTC);
+
+ if (!intc_dev
+ || set_interrupt_handler(0, &timer_interrupt_handler, 3))
+ return;
+
+ /* For all practical purposes, this gives us an overflow interrupt */
+ sysreg_write(COMPARE, 0xffffffff);
+}
diff --git a/cpu/at32ap/pio.c b/cpu/at32ap/pio.c
new file mode 100644
index 0000000..8b6c3a3
--- /dev/null
+++ b/cpu/at32ap/pio.c
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2006 Atmel Corporation
+ *
+ * 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/errno.h>
+#include <asm/io.h>
+#include <asm/arch/platform.h>
+
+#include "pio2.h"
+
+struct pio_state {
+ const struct device *dev;
+ u32 alloc_mask;
+};
+
+static struct pio_state pio_state[CFG_NR_PIOS];
+
+int gpio_set_func(enum device_id gpio_devid, unsigned int start,
+ unsigned int nr_pins, enum gpio_func func)
+{
+ const struct device *gpio;
+ struct pio_state *state;
+ u32 mask;
+
+ state = &pio_state[gpio_devid - DEVICE_PIOA];
+
+ gpio = get_device(gpio_devid);
+ if (!gpio)
+ return -EBUSY;
+
+ state->dev = gpio;
+ mask = ((1 << nr_pins) - 1) << start;
+
+ if (mask & state->alloc_mask) {
+ put_device(gpio);
+ return -EBUSY;
+ }
+ state->alloc_mask |= mask;
+
+ switch (func) {
+ case GPIO_FUNC_GPIO:
+ /* TODO */
+ return -EINVAL;
+ case GPIO_FUNC_A:
+ pio2_writel(gpio, ASR, mask);
+ pio2_writel(gpio, PDR, mask);
+ pio2_writel(gpio, PUDR, mask);
+ break;
+ case GPIO_FUNC_B:
+ pio2_writel(gpio, BSR, mask);
+ pio2_writel(gpio, PDR, mask);
+ pio2_writel(gpio, PUDR, mask);
+ break;
+ }
+
+ return 0;
+}
+
+void gpio_free(enum device_id gpio_devid, unsigned int start,
+ unsigned int nr_pins)
+{
+ const struct device *gpio;
+ struct pio_state *state;
+ u32 mask;
+
+ state = &pio_state[gpio_devid - DEVICE_PIOA];
+ gpio = state->dev;
+ mask = ((1 << nr_pins) - 1) << start;
+
+ pio2_writel(gpio, ODR, mask);
+ pio2_writel(gpio, PER, mask);
+
+ state->alloc_mask &= ~mask;
+ put_device(gpio);
+}
diff --git a/cpu/at32ap/pio2.h b/cpu/at32ap/pio2.h
new file mode 100644
index 0000000..6b79de3
--- /dev/null
+++ b/cpu/at32ap/pio2.h
@@ -0,0 +1,44 @@
+/*
+ * Register definitions for Parallel Input/Output Controller
+ */
+#ifndef __CPU_AT32AP_PIO2_H__
+#define __CPU_AT32AP_PIO2_H__
+
+/* PIO2 register offsets */
+#define PIO2_PER 0x0000
+#define PIO2_PDR 0x0004
+#define PIO2_PSR 0x0008
+#define PIO2_OER 0x0010
+#define PIO2_ODR 0x0014
+#define PIO2_OSR 0x0018
+#define PIO2_IFER 0x0020
+#define PIO2_IFDR 0x0024
+#define PIO2_ISFR 0x0028
+#define PIO2_SODR 0x0030
+#define PIO2_CODR 0x0034
+#define PIO2_ODSR 0x0038
+#define PIO2_PDSR 0x003c
+#define PIO2_IER 0x0040
+#define PIO2_IDR 0x0044
+#define PIO2_IMR 0x0048
+#define PIO2_ISR 0x004c
+#define PIO2_MDER 0x0050
+#define PIO2_MDDR 0x0054
+#define PIO2_MDSR 0x0058
+#define PIO2_PUDR 0x0060
+#define PIO2_PUER 0x0064
+#define PIO2_PUSR 0x0068
+#define PIO2_ASR 0x0070
+#define PIO2_BSR 0x0074
+#define PIO2_ABSR 0x0078
+#define PIO2_OWER 0x00a0
+#define PIO2_OWDR 0x00a4
+#define PIO2_OWSR 0x00a8
+
+/* Register access macros */
+#define pio2_readl(port,reg) \
+ readl((port)->regs + PIO2_##reg)
+#define pio2_writel(port,reg,value) \
+ writel((value), (port)->regs + PIO2_##reg)
+
+#endif /* __CPU_AT32AP_PIO2_H__ */
diff --git a/cpu/at32ap/pm.c b/cpu/at32ap/pm.c
new file mode 100644
index 0000000..01ac325
--- /dev/null
+++ b/cpu/at32ap/pm.c
@@ -0,0 +1,163 @@
+/*
+ * Copyright (C) 2006 Atmel Corporation
+ *
+ * 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 CFG_POWER_MANAGER
+#include <asm/errno.h>
+#include <asm/io.h>
+
+#include <asm/arch/memory-map.h>
+#include <asm/arch/platform.h>
+
+#include "sm.h"
+
+/* Sanity checks */
+#if (CFG_CLKDIV_CPU > CFG_CLKDIV_HSB) \
+ || (CFG_CLKDIV_HSB > CFG_CLKDIV_PBA) \
+ || (CFG_CLKDIV_HSB > CFG_CLKDIV_PBB)
+# error Constraint fCPU >= fHSB >= fPB{A,B} violated
+#endif
+#if defined(CONFIG_PLL) && ((CFG_PLL0_MUL < 1) || (CFG_PLL0_DIV < 1))
+# error Invalid PLL multiplier and/or divider
+#endif
+
+DECLARE_GLOBAL_DATA_PTR;
+
+struct clock_domain_state {
+ const struct device *bridge;
+ unsigned long freq;
+ u32 mask;
+};
+static struct clock_domain_state ckd_state[NR_CLOCK_DOMAINS];
+
+int pm_enable_clock(enum clock_domain_id id, unsigned int index)
+{
+ const struct clock_domain *ckd = &chip_clock[id];
+ struct clock_domain_state *state = &ckd_state[id];
+
+ if (ckd->bridge != NO_DEVICE) {
+ state->bridge = get_device(ckd->bridge);
+ if (!state->bridge)
+ return -EBUSY;
+ }
+
+ state->mask |= 1 << index;
+ if (gd->sm)
+ writel(state->mask, gd->sm->regs + ckd->reg);
+
+ return 0;
+}
+
+void pm_disable_clock(enum clock_domain_id id, unsigned int index)
+{
+ const struct clock_domain *ckd = &chip_clock[id];
+ struct clock_domain_state *state = &ckd_state[id];
+
+ state->mask &= ~(1 << index);
+ if (gd->sm)
+ writel(state->mask, gd->sm->regs + ckd->reg);
+
+ if (ckd->bridge)
+ put_device(state->bridge);
+}
+
+unsigned long pm_get_clock_freq(enum clock_domain_id domain)
+{
+ return ckd_state[domain].freq;
+}
+
+void pm_init(void)
+{
+ uint32_t cksel = 0;
+ unsigned long main_clock;
+
+ /* Make sure we don't disable any device we're already using */
+ get_device(DEVICE_HRAMC);
+ get_device(DEVICE_HEBI);
+
+ /* Enable the PICO as well */
+ ckd_state[CLOCK_CPU].mask |= 1;
+
+ gd->sm = get_device(DEVICE_SM);
+ if (!gd->sm)
+ panic("Unable to claim system manager device!\n");
+
+ /* Disable any devices that haven't been explicitly claimed */
+ sm_writel(gd->sm, PM_PBB_MASK, ckd_state[CLOCK_PBB].mask);
+ sm_writel(gd->sm, PM_PBA_MASK, ckd_state[CLOCK_PBA].mask);
+ sm_writel(gd->sm, PM_HSB_MASK, ckd_state[CLOCK_HSB].mask);
+ sm_writel(gd->sm, PM_CPU_MASK, ckd_state[CLOCK_CPU].mask);
+
+#ifdef CONFIG_PLL
+ /* Initialize the PLL */
+ main_clock = (CFG_OSC0_HZ / CFG_PLL0_DIV) * CFG_PLL0_MUL;
+
+ sm_writel(gd->sm, PM_PLL0, (SM_BF(PLLCOUNT, CFG_PLL0_SUPPRESS_CYCLES)
+ | SM_BF(PLLMUL, CFG_PLL0_MUL - 1)
+ | SM_BF(PLLDIV, CFG_PLL0_DIV - 1)
+ | SM_BF(PLLOPT, CFG_PLL0_OPT)
+ | SM_BF(PLLOSC, 0)
+ | SM_BIT(PLLEN)));
+
+ /* Wait for lock */
+ while (!(sm_readl(gd->sm, PM_ISR) & SM_BIT(LOCK0))) ;
+#else
+ main_clock = CFG_OSC0_HZ;
+#endif
+
+ /* Set up clocks for the CPU and all peripheral buses */
+ if (CFG_CLKDIV_CPU) {
+ cksel |= SM_BIT(CPUDIV) | SM_BF(CPUSEL, CFG_CLKDIV_CPU - 1);
+ ckd_state[CLOCK_CPU].freq = main_clock / (1 << CFG_CLKDIV_CPU);
+ } else {
+ ckd_state[CLOCK_CPU].freq = main_clock;
+ }
+ if (CFG_CLKDIV_HSB) {
+ cksel |= SM_BIT(HSBDIV) | SM_BF(HSBSEL, CFG_CLKDIV_HSB - 1);
+ ckd_state[CLOCK_HSB].freq = main_clock / (1 << CFG_CLKDIV_HSB);
+ } else {
+ ckd_state[CLOCK_HSB].freq = main_clock;
+ }
+ if (CFG_CLKDIV_PBA) {
+ cksel |= SM_BIT(PBADIV) | SM_BF(PBASEL, CFG_CLKDIV_PBA - 1);
+ ckd_state[CLOCK_PBA].freq = main_clock / (1 << CFG_CLKDIV_PBA);
+ } else {
+ ckd_state[CLOCK_PBA].freq = main_clock;
+ }
+ if (CFG_CLKDIV_PBB) {
+ cksel |= SM_BIT(PBBDIV) | SM_BF(PBBSEL, CFG_CLKDIV_PBB - 1);
+ ckd_state[CLOCK_PBB].freq = main_clock / (1 << CFG_CLKDIV_PBB);
+ } else {
+ ckd_state[CLOCK_PBB].freq = main_clock;
+ }
+ sm_writel(gd->sm, PM_CKSEL, cksel);
+
+ /* CFG_HZ currently depends on cpu_hz */
+ gd->cpu_hz = ckd_state[CLOCK_CPU].freq;
+
+#ifdef CONFIG_PLL
+ /* Use PLL0 as main clock */
+ sm_writel(gd->sm, PM_MCCTRL, SM_BIT(PLLSEL));
+#endif
+}
+
+#endif /* CFG_POWER_MANAGER */
diff --git a/cpu/at32ap/sm.h b/cpu/at32ap/sm.h
new file mode 100644
index 0000000..ce81ef0
--- /dev/null
+++ b/cpu/at32ap/sm.h
@@ -0,0 +1,204 @@
+/*
+ * Register definitions for System Manager
+ */
+#ifndef __CPU_AT32AP_SM_H__
+#define __CPU_AT32AP_SM_H__
+
+/* SM register offsets */
+#define SM_PM_MCCTRL 0x0000
+#define SM_PM_CKSEL 0x0004
+#define SM_PM_CPU_MASK 0x0008
+#define SM_PM_HSB_MASK 0x000c
+#define SM_PM_PBA_MASK 0x0010
+#define SM_PM_PBB_MASK 0x0014
+#define SM_PM_PLL0 0x0020
+#define SM_PM_PLL1 0x0024
+#define SM_PM_VCTRL 0x0030
+#define SM_PM_VMREF 0x0034
+#define SM_PM_VMV 0x0038
+#define SM_PM_IER 0x0040
+#define SM_PM_IDR 0x0044
+#define SM_PM_IMR 0x0048
+#define SM_PM_ISR 0x004c
+#define SM_PM_ICR 0x0050
+#define SM_PM_GCCTRL 0x0060
+#define SM_RTC_CTRL 0x0080
+#define SM_RTC_VAL 0x0084
+#define SM_RTC_TOP 0x0088
+#define SM_RTC_IER 0x0090
+#define SM_RTC_IDR 0x0094
+#define SM_RTC_IMR 0x0098
+#define SM_RTC_ISR 0x009c
+#define SM_RTC_ICR 0x00a0
+#define SM_WDT_CTRL 0x00b0
+#define SM_WDT_CLR 0x00b4
+#define SM_WDT_EXT 0x00b8
+#define SM_RC_RCAUSE 0x00c0
+#define SM_EIM_IER 0x0100
+#define SM_EIM_IDR 0x0104
+#define SM_EIM_IMR 0x0108
+#define SM_EIM_ISR 0x010c
+#define SM_EIM_ICR 0x0110
+#define SM_EIM_MODE 0x0114
+#define SM_EIM_EDGE 0x0118
+#define SM_EIM_LEVEL 0x011c
+#define SM_EIM_TEST 0x0120
+#define SM_EIM_NMIC 0x0124
+
+/* Bitfields in PM_CKSEL */
+#define SM_CPUSEL_OFFSET 0
+#define SM_CPUSEL_SIZE 3
+#define SM_CPUDIV_OFFSET 7
+#define SM_CPUDIV_SIZE 1
+#define SM_HSBSEL_OFFSET 8
+#define SM_HSBSEL_SIZE 3
+#define SM_HSBDIV_OFFSET 15
+#define SM_HSBDIV_SIZE 1
+#define SM_PBASEL_OFFSET 16
+#define SM_PBASEL_SIZE 3
+#define SM_PBADIV_OFFSET 23
+#define SM_PBADIV_SIZE 1
+#define SM_PBBSEL_OFFSET 24
+#define SM_PBBSEL_SIZE 3
+#define SM_PBBDIV_OFFSET 31
+#define SM_PBBDIV_SIZE 1
+
+/* Bitfields in PM_PLL0 */
+#define SM_PLLEN_OFFSET 0
+#define SM_PLLEN_SIZE 1
+#define SM_PLLOSC_OFFSET 1
+#define SM_PLLOSC_SIZE 1
+#define SM_PLLOPT_OFFSET 2
+#define SM_PLLOPT_SIZE 3
+#define SM_PLLDIV_OFFSET 8
+#define SM_PLLDIV_SIZE 8
+#define SM_PLLMUL_OFFSET 16
+#define SM_PLLMUL_SIZE 8
+#define SM_PLLCOUNT_OFFSET 24
+#define SM_PLLCOUNT_SIZE 6
+#define SM_PLLTEST_OFFSET 31
+#define SM_PLLTEST_SIZE 1
+
+/* Bitfields in PM_VCTRL */
+#define SM_VAUTO_OFFSET 0
+#define SM_VAUTO_SIZE 1
+#define SM_PM_VCTRL_VAL_OFFSET 8
+#define SM_PM_VCTRL_VAL_SIZE 7
+
+/* Bitfields in PM_VMREF */
+#define SM_REFSEL_OFFSET 0
+#define SM_REFSEL_SIZE 4
+
+/* Bitfields in PM_VMV */
+#define SM_PM_VMV_VAL_OFFSET 0
+#define SM_PM_VMV_VAL_SIZE 8
+
+/* Bitfields in PM_ICR */
+#define SM_LOCK0_OFFSET 0
+#define SM_LOCK0_SIZE 1
+#define SM_LOCK1_OFFSET 1
+#define SM_LOCK1_SIZE 1
+#define SM_WAKE_OFFSET 2
+#define SM_WAKE_SIZE 1
+#define SM_VOK_OFFSET 3
+#define SM_VOK_SIZE 1
+#define SM_VMRDY_OFFSET 4
+#define SM_VMRDY_SIZE 1
+#define SM_CKRDY_OFFSET 5
+#define SM_CKRDY_SIZE 1
+
+/* Bitfields in PM_GCCTRL */
+#define SM_OSCSEL_OFFSET 0
+#define SM_OSCSEL_SIZE 1
+#define SM_PLLSEL_OFFSET 1
+#define SM_PLLSEL_SIZE 1
+#define SM_CEN_OFFSET 2
+#define SM_CEN_SIZE 1
+#define SM_CPC_OFFSET 3
+#define SM_CPC_SIZE 1
+#define SM_DIVEN_OFFSET 4
+#define SM_DIVEN_SIZE 1
+#define SM_DIV_OFFSET 8
+#define SM_DIV_SIZE 8
+
+/* Bitfields in RTC_CTRL */
+#define SM_PCLR_OFFSET 1
+#define SM_PCLR_SIZE 1
+#define SM_TOPEN_OFFSET 2
+#define SM_TOPEN_SIZE 1
+#define SM_CLKEN_OFFSET 3
+#define SM_CLKEN_SIZE 1
+#define SM_PSEL_OFFSET 8
+#define SM_PSEL_SIZE 16
+
+/* Bitfields in RTC_VAL */
+#define SM_RTC_VAL_VAL_OFFSET 0
+#define SM_RTC_VAL_VAL_SIZE 31
+
+/* Bitfields in RTC_TOP */
+#define SM_RTC_TOP_VAL_OFFSET 0
+#define SM_RTC_TOP_VAL_SIZE 32
+
+/* Bitfields in RTC_ICR */
+#define SM_TOPI_OFFSET 0
+#define SM_TOPI_SIZE 1
+
+/* Bitfields in WDT_CTRL */
+#define SM_KEY_OFFSET 24
+#define SM_KEY_SIZE 8
+
+/* Bitfields in RC_RCAUSE */
+#define SM_POR_OFFSET 0
+#define SM_POR_SIZE 1
+#define SM_BOD_OFFSET 1
+#define SM_BOD_SIZE 1
+#define SM_EXT_OFFSET 2
+#define SM_EXT_SIZE 1
+#define SM_WDT_OFFSET 3
+#define SM_WDT_SIZE 1
+#define SM_NTAE_OFFSET 4
+#define SM_NTAE_SIZE 1
+#define SM_SERP_OFFSET 5
+#define SM_SERP_SIZE 1
+
+/* Bitfields in EIM_EDGE */
+#define SM_INT0_OFFSET 0
+#define SM_INT0_SIZE 1
+#define SM_INT1_OFFSET 1
+#define SM_INT1_SIZE 1
+#define SM_INT2_OFFSET 2
+#define SM_INT2_SIZE 1
+#define SM_INT3_OFFSET 3
+#define SM_INT3_SIZE 1
+
+/* Bitfields in EIM_LEVEL */
+
+/* Bitfields in EIM_TEST */
+#define SM_TESTEN_OFFSET 31
+#define SM_TESTEN_SIZE 1
+
+/* Bitfields in EIM_NMIC */
+#define SM_EN_OFFSET 0
+#define SM_EN_SIZE 1
+
+/* Bit manipulation macros */
+#define SM_BIT(name) \
+ (1 << SM_##name##_OFFSET)
+#define SM_BF(name,value) \
+ (((value) & ((1 << SM_##name##_SIZE) - 1)) \
+ << SM_##name##_OFFSET)
+#define SM_BFEXT(name,value) \
+ (((value) >> SM_##name##_OFFSET) \
+ & ((1 << SM_##name##_SIZE) - 1))
+#define SM_BFINS(name,value,old) \
+ (((old) & ~(((1 << SM_##name##_SIZE) - 1) \
+ << SM_##name##_OFFSET)) \
+ | SM_BF(name,value))
+
+/* Register access macros */
+#define sm_readl(port,reg) \
+ readl((port)->regs + SM_##reg)
+#define sm_writel(port,reg,value) \
+ writel((value), (port)->regs + SM_##reg)
+
+#endif /* __CPU_AT32AP_SM_H__ */
diff --git a/cpu/at32ap/start.S b/cpu/at32ap/start.S
new file mode 100644
index 0000000..79ee33b
--- /dev/null
+++ b/cpu/at32ap/start.S
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2005-2006 Atmel Corporation
+ *
+ * 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 <asm/sysreg.h>
+
+#ifndef PART_SPECIFIC_BOOTSTRAP
+# define PART_SPECIFIC_BOOTSTRAP
+#endif
+
+#define SYSREG_MMUCR_I_OFFSET 2
+#define SYSREG_MMUCR_S_OFFSET 4
+
+#define SR_INIT (SYSREG_BIT(GM) | SYSREG_BIT(EM) | SYSREG_BIT(M0))
+#define CPUCR_INIT (SYSREG_BIT(BI) | SYSREG_BIT(BE) \
+ | SYSREG_BIT(FE) | SYSREG_BIT(RE) \
+ | SYSREG_BIT(IBE) | SYSREG_BIT(IEE))
+
+ .text
+ .global _start
+_start:
+ PART_SPECIFIC_BOOTSTRAP
+
+ /* Reset the Status Register */
+ mov r0, lo(SR_INIT)
+ orh r0, hi(SR_INIT)
+ mtsr SYSREG_SR, r0
+
+ /* Reset CPUCR and invalidate the BTB */
+ mov r2, CPUCR_INIT
+ mtsr SYSREG_CPUCR, r2
+
+ /* Flush the caches */
+ mov r1, 0
+ cache r1[4], 8
+ cache r1[0], 0
+ sync 0
+
+ /* Reset the MMU to default settings */
+ mov r0, SYSREG_BIT(MMUCR_S) | SYSREG_BIT(MMUCR_I)
+ mtsr SYSREG_MMUCR, r0
+
+ /* Internal RAM should not need any initialization. We might
+ have to initialize external RAM here if the part doesn't
+ have internal RAM (or we may use the data cache) */
+
+ /* Jump to cacheable segment */
+ lddpc pc, 1f
+
+ .align 2
+1: .long 2f
+
+2: lddpc sp, sp_init
+
+ /*
+ * Relocate the data section and initialize .bss. Everything
+ * is guaranteed to be at least doubleword aligned by the
+ * linker script.
+ */
+ lddpc r12, .Ldata_vma
+ lddpc r11, .Ldata_lma
+ lddpc r10, .Ldata_end
+ sub r10, r12
+4: ld.d r8, r11++
+ sub r10, 8
+ st.d r12++, r8
+ brne 4b
+
+ mov r8, 0
+ mov r9, 0
+ lddpc r10, .Lbss_end
+ sub r10, r12
+4: sub r10, 8
+ st.d r12++, r8
+ brne 4b
+
+ /* Initialize the GOT pointer */
+ lddpc r6, got_init
+3: rsub r6, pc
+ ld.w pc, r6[start_u_boot@got]
+
+ .align 2
+ .type sp_init,@object
+sp_init:
+ .long CFG_INIT_SP_ADDR
+got_init:
+ .long 3b - _GLOBAL_OFFSET_TABLE_
+.Ldata_lma:
+ .long __data_lma
+.Ldata_vma:
+ .long _data
+.Ldata_end:
+ .long _edata
+.Lbss_end:
+ .long _end
diff --git a/cpu/bf533/Makefile b/cpu/bf533/Makefile
index c63a8f6..9f4a0d8 100644
--- a/cpu/bf533/Makefile
+++ b/cpu/bf533/Makefile
@@ -2,7 +2,7 @@
#
# Copyright (c) 2005 blackfin.uclinux.org
#
-# (C) Copyright 2000-2004
+# (C) Copyright 2000-2006
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
#
# See file CREDITS for list of people who contributed to this
@@ -26,21 +26,25 @@
include $(TOPDIR)/config.mk
-LIB = lib$(CPU).a
+LIB = $(obj)lib$(CPU).a
START = start.o start1.o interrupt.o cache.o cplbhdlr.o cplbmgr.o flush.o
-OBJS = cpu.o traps.o ints.o serial.o interrupts.o
+COBJS = cpu.o traps.o ints.o serial.o interrupts.o
-all: .depend $(START) $(LIB)
+SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
+START := $(addprefix $(obj),$(START))
+
+all: $(obj).depend $(START) $(LIB)
$(LIB): $(OBJS)
- $(AR) crv $@ $(OBJS)
+ $(AR) $(ARFLAGS) $@ $(OBJS)
#########################################################################
-.depend: Makefile $(START:.o=.S) $(OBJS:.o=.c)
- $(CC) -M $(CFLAGS) $(START:.o=.S) $(OBJS:.o=.c) > $@
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
-sinclude .depend
+sinclude $(obj).depend
#########################################################################
diff --git a/cpu/i386/Makefile b/cpu/i386/Makefile
index c44412a..50534b6 100644
--- a/cpu/i386/Makefile
+++ b/cpu/i386/Makefile
@@ -1,4 +1,7 @@
#
+# (C) Copyright 2006
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
# (C) Copyright 2002
# Daniel Engström, Omicron Ceti AB, daniel@omicron.se.
#
@@ -23,22 +26,26 @@
include $(TOPDIR)/config.mk
-LIB = lib$(CPU).a
+LIB = $(obj)lib$(CPU).a
START = start.o start16.o reset.o
COBJS = serial.o interrupts.o cpu.o timer.o sc520.o
-AOBJS = sc520_asm.o
+SOBJS = sc520_asm.o
+
+SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
+START := $(addprefix $(obj),$(START))
-all: .depend $(START) $(LIB)
+all: $(obj).depend $(START) $(LIB)
-$(LIB): $(COBJS) $(AOBJS)
- $(AR) crv $@ $(COBJS) $(AOBJS)
+$(LIB): $(OBJS)
+ $(AR) $(ARFLAGS) $@ $(OBJS)
#########################################################################
-.depend: Makefile $(START:.o=.S) $(COBJS:.o=.c) $(AOBJS:.o=.S)
- $(CC) -M $(CFLAGS) $(START:.o=.S) $(COBJS:.o=.c) $(AOBJS:.o=.S) > $@
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
-sinclude .depend
+sinclude $(obj).depend
#########################################################################
diff --git a/cpu/i386/sc520.c b/cpu/i386/sc520.c
index c83f0bb..d0a7341 100644
--- a/cpu/i386/sc520.c
+++ b/cpu/i386/sc520.c
@@ -31,7 +31,9 @@
#include <common.h>
#include <config.h>
#include <pci.h>
+#ifdef CONFIG_SC520_SSI
#include <ssi.h>
+#endif
#include <asm/io.h>
#include <asm/pci.h>
#include <asm/ic/sc520.h>
@@ -143,7 +145,15 @@ unsigned long init_sc520_dram(void)
u32 dram_present=0;
u32 dram_ctrl;
-
+#ifdef CFG_SDRAM_DRCTMCTL
+ /* these memory control registers are set up in the assember part,
+ * in sc520_asm.S, during 'mem_init'. If we muck with them here,
+ * after we are running a stack in RAM, we have troubles. Besides,
+ * these refresh and delay values are better ? simply specified
+ * outright in the include/configs/{cfg} file since the HW designer
+ * simply dictates it.
+ */
+#else
int val;
int cas_precharge_delay = CFG_SDRAM_PRECHARGE_DELAY;
@@ -162,6 +172,7 @@ unsigned long init_sc520_dram(void)
} else {
val = 3; /* 62.4us */
}
+
write_mmcr_byte(SC520_DRCCTL, (read_mmcr_byte(SC520_DRCCTL) & 0xcf) | (val<<4));
val = read_mmcr_byte(SC520_DRCTMCTL);
@@ -181,13 +192,12 @@ unsigned long init_sc520_dram(void)
val |= 1;
}
write_mmcr_byte(SC520_DRCTMCTL, val);
-
+#endif
/* We read-back the configuration of the dram
* controller that the assembly code wrote */
dram_ctrl = read_mmcr_long(SC520_DRCBENDADR);
-
bd->bi_dram[0].start = 0;
if (dram_ctrl & 0x80) {
/* bank 0 enabled */
@@ -274,7 +284,7 @@ int pci_sc520_set_irq(int pci_pin, int irq)
{
int i;
-# if 0
+# if 1
printf("set_irq(): map INT%c to IRQ%d\n", pci_pin + 'A', irq);
#endif
if (irq < 0 || irq > 15) {
diff --git a/cpu/i386/sc520_asm.S b/cpu/i386/sc520_asm.S
index 80464fa..8fc713d 100644
--- a/cpu/i386/sc520_asm.S
+++ b/cpu/i386/sc520_asm.S
@@ -113,6 +113,7 @@
.equ DRCCFG, 0x0fffef014 /* DRAM bank configuration register */
.equ DRCBENDADR, 0x0fffef018 /* DRAM bank ending address register */
.equ ECCCTL, 0x0fffef020 /* DRAM ECC control register */
+.equ ECCINT, 0x0fffefd18 /* DRAM ECC nmi-INT mapping */
.equ DBCTL, 0x0fffef040 /* DRAM buffer control register */
.equ CACHELINESZ, 0x00000010 /* size of our cache line (read buffer) */
@@ -459,6 +460,12 @@ emptybank:
incl %edi
loop cleanuplp
+#if defined CFG_SDRAM_DRCTMCTL
+ /* just have your hardware desinger _GIVE_ you what you need here! */
+ movl $DRCTMCTL, %edi
+ movb $CFG_SDRAM_DRCTMCTL,%al
+ movb (%edi), %al
+#else
#if defined(CFG_SDRAM_CAS_LATENCY_2T) || defined(CFG_SDRAM_CAS_LATENCY_3T)
/* set the CAS latency now since it is hard to do
* when we run from the RAM */
@@ -472,6 +479,7 @@ emptybank:
#endif
movb %al, (%edi)
#endif
+#endif
movl $DRCCTL, %edi /* DRAM Control register */
movb $0x3,%al /* Load mode register cmd */
movb %al, (%edi)
@@ -528,9 +536,49 @@ bank0: movl (%edi), %eax
shll $22, %eax
movl %eax, %ebx
-done: movl %ebx, %eax
+done:
+ movl %ebx, %eax
+
+#if CFG_SDRAM_ECC_ENABLE
+ /* A nominal memory test: just a byte at each address line */
+ movl %eax, %ecx
+ shrl $0x1, %ecx
+ movl $0x1, %edi
+memtest0:
+ movb $0xa5, (%edi)
+ cmpb $0xa5, (%edi)
+ jne out
+ shrl $1, %ecx
+ andl %ecx,%ecx
+ jz set_ecc
+ shll $1, %edi
+ jmp memtest0
+
+set_ecc:
+ /* clear all ram with a memset */
+ movl %eax, %ecx
+ xorl %esi, %esi
+ xorl %edi, %edi
+ xorl %eax, %eax
+ shrl $2, %ecx
+ cld
+ rep stosl
+ /* enable read, write buffers */
+ movb $0x11, %al
+ movl $DBCTL, %edi
+ movb %al, (%edi)
+ /* enable NMI mapping for ECC */
+ movl $ECCINT, %edi
+ mov $0x10, %al
+ movb %al, (%edi)
+ /* Turn on ECC */
+ movl $ECCCTL, %edi
+ mov $0x05, %al
+ movb %al, (%edi)
+#endif
+out:
+ movl %ebx, %eax
jmp *%ebp
-
#endif /* CONFIG_SC520 */
diff --git a/cpu/ixp/Makefile b/cpu/ixp/Makefile
index ba2e589..e1fb327 100644
--- a/cpu/ixp/Makefile
+++ b/cpu/ixp/Makefile
@@ -1,5 +1,5 @@
#
-# (C) Copyright 2000, 2002
+# (C) Copyright 2000-2006
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
#
# See file CREDITS for list of people who contributed to this
@@ -23,21 +23,25 @@
include $(TOPDIR)/config.mk
-LIB = lib$(CPU).a
+LIB = $(obj)lib$(CPU).a
START = start.o
-OBJS = serial.o interrupts.o cpu.o timer.o pci.o
+COBJS = serial.o interrupts.o cpu.o timer.o pci.o
-all: .depend $(START) $(LIB)
+SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
+START := $(addprefix $(obj),$(START))
+
+all: $(obj).depend $(START) $(LIB)
$(LIB): $(OBJS)
- $(AR) crv $@ $(OBJS)
+ $(AR) $(ARFLAGS) $@ $(OBJS)
#########################################################################
-.depend: Makefile $(START:.o=.S) $(OBJS:.o=.c)
- $(CC) -M $(CFLAGS) $(START:.o=.S) $(OBJS:.o=.c) > $@
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
-sinclude .depend
+sinclude $(obj).depend
#########################################################################
diff --git a/cpu/ixp/npe/Makefile b/cpu/ixp/npe/Makefile
index 937de9d..4de34fd 100644
--- a/cpu/ixp/npe/Makefile
+++ b/cpu/ixp/npe/Makefile
@@ -23,11 +23,13 @@
include $(TOPDIR)/config.mk
-LIB := libnpe.a
+LIB := $(obj)libnpe.a
-CFLAGS += -I$(TOPDIR)/cpu/ixp/npe/include -DCONFIG_IXP425_COMPONENT_ETHDB
+LOCAL_CFLAGS += -I$(TOPDIR)/cpu/ixp/npe/include -DCONFIG_IXP425_COMPONENT_ETHDB
+CFLAGS += $(LOCAL_CFLAGS)
+HOST_CFLAGS += $(LOCAL_CFLAGS)
-OBJS := npe.o \
+COBJS := npe.o \
miiphy.o \
IxOsalBufferMgt.o \
IxOsalIoMem.o \
@@ -78,14 +80,21 @@ OBJS := npe.o \
IxNpeMhSolicitedCbMgr.o \
IxNpeMhUnsolicitedCbMgr.o
+
+SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
+START := $(addprefix $(obj),$(START))
+
all: $(LIB)
-$(LIB): $(OBJS)
- $(AR) crv $@ $(OBJS)
+$(LIB): $(obj).depend $(OBJS)
+ $(AR) $(ARFLAGS) $@ $(OBJS)
#########################################################################
-.depend: Makefile $(OBJS:.o=.c)
- $(CC) -M $(CFLAGS) $(OBJS:.o=.c) > $@
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
-sinclude .depend
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/cpu/lh7a40x/Makefile b/cpu/lh7a40x/Makefile
index b45bd6a..bac2a64 100644
--- a/cpu/lh7a40x/Makefile
+++ b/cpu/lh7a40x/Makefile
@@ -1,5 +1,5 @@
#
-# (C) Copyright 2000, 2001, 2002
+# (C) Copyright 2000-2006
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
#
# See file CREDITS for list of people who contributed to this
@@ -23,21 +23,25 @@
include $(TOPDIR)/config.mk
-LIB = lib$(CPU).a
+LIB = $(obj)lib$(CPU).a
START = start.o
-OBJS = cpu.o speed.o interrupts.o serial.o
+COBJS = cpu.o speed.o interrupts.o serial.o
-all: .depend $(START) $(LIB)
+SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
+START := $(addprefix $(obj),$(START))
+
+all: $(obj).depend $(START) $(LIB)
$(LIB): $(OBJS)
- $(AR) crv $@ $(OBJS)
+ $(AR) $(ARFLAGS) $@ $(OBJS)
#########################################################################
-.depend: Makefile $(START:.o=.S) $(OBJS:.o=.c)
- $(CC) -M $(CFLAGS) $(START:.o=.S) $(OBJS:.o=.c) > $@
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
-sinclude .depend
+sinclude $(obj).depend
#########################################################################
diff --git a/cpu/mcf52x2/Makefile b/cpu/mcf52x2/Makefile
index 879deb7..70d57cf 100644
--- a/cpu/mcf52x2/Makefile
+++ b/cpu/mcf52x2/Makefile
@@ -1,5 +1,5 @@
#
-# (C) Copyright 2000-2004
+# (C) Copyright 2000-2006
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
#
# See file CREDITS for list of people who contributed to this
@@ -25,21 +25,25 @@ include $(TOPDIR)/config.mk
# CFLAGS += -DET_DEBUG
-LIB = lib$(CPU).a
+LIB = $(obj)lib$(CPU).a
START =
-OBJS = serial.o interrupts.o cpu.o speed.o cpu_init.o fec.o
+COBJS = serial.o interrupts.o cpu.o speed.o cpu_init.o fec.o
-all: .depend $(START) $(LIB)
+SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
+START := $(addprefix $(obj),$(START))
+
+all: $(obj).depend $(START) $(LIB)
$(LIB): $(OBJS)
- $(AR) crv $@ $(OBJS)
+ $(AR) $(ARFLAGS) $@ $(OBJS)
#########################################################################
-.depend: Makefile $(START:.o=.S) $(OBJS:.o=.c)
- $(CC) -M $(CFLAGS) $(START:.o=.S) $(OBJS:.o=.c) > $@
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
-sinclude .depend
+sinclude $(obj).depend
#########################################################################
diff --git a/cpu/mcf52x2/fec.c b/cpu/mcf52x2/fec.c
index 6db6214..b6540b5 100644
--- a/cpu/mcf52x2/fec.c
+++ b/cpu/mcf52x2/fec.c
@@ -267,6 +267,7 @@ int eth_init (bd_t * bd)
fecp->fec_hash_table_high = 0;
fecp->fec_hash_table_low = 0;
#endif
+#endif
/* Set maximum receive buffer size.
*/
diff --git a/cpu/mcf52x2/start.S b/cpu/mcf52x2/start.S
index 8a83ca5..f1f4077 100644
--- a/cpu/mcf52x2/start.S
+++ b/cpu/mcf52x2/start.S
@@ -140,6 +140,7 @@ _start:
move.l #(CFG_MBAR + 1), %d0 /* set IPSBAR address + valid flag */
move.l %d0, 0x40000000
+#if defined(CONFIG_M5282)
/* Initialize RAMBAR1: locate SRAM and validate it */
move.l #(CFG_INIT_RAM_ADDR + 0x21), %d0
movec %d0, %RAMBAR1
@@ -171,6 +172,7 @@ _after_flashbar_copy:
#endif /* (TEXT_BASE == CFG_INT_FLASH_BASE) */
#endif
+#endif
/* if we come from a pre-loader we have no exception table and
* therefore no VBR to set
*/
diff --git a/cpu/microblaze/Makefile b/cpu/microblaze/Makefile
index 610043e..fd54425 100644
--- a/cpu/microblaze/Makefile
+++ b/cpu/microblaze/Makefile
@@ -1,5 +1,5 @@
#
-# (C) Copyright 2000
+# (C) Copyright 2000-2006
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
#
# See file CREDITS for list of people who contributed to this
@@ -23,21 +23,25 @@
include $(TOPDIR)/config.mk
-LIB = lib$(CPU).a
+LIB = $(obj)lib$(CPU).a
START = start.o
-OBJS = cpu.o interrupts.o
+COBJS = cpu.o interrupts.o
-all: .depend $(START) $(LIB)
+SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
+START := $(addprefix $(obj),$(START))
+
+all: $(obj).depend $(START) $(LIB)
$(LIB): $(OBJS)
- $(AR) crv $@ $(OBJS)
+ $(AR) $(ARFLAGS) $@ $(OBJS)
#########################################################################
-.depend: Makefile $(START:.o=.S) $(OBJS:.o=.c) $(AOBJS:.o=.S)
- $(CC) -M $(CFLAGS) $(START:.o=.S) $(OBJS:.o=.c) $(AOBJS:.o=.S) > $@
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
-sinclude .depend
+sinclude $(obj).depend
#########################################################################
diff --git a/cpu/mips/Makefile b/cpu/mips/Makefile
index c8b30c7..92dcc16 100644
--- a/cpu/mips/Makefile
+++ b/cpu/mips/Makefile
@@ -1,5 +1,5 @@
#
-# (C) Copyright 2003
+# (C) Copyright 2003-2006
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
#
# See file CREDITS for list of people who contributed to this
@@ -23,23 +23,27 @@
include $(TOPDIR)/config.mk
-LIB = lib$(CPU).a
+LIB = $(obj)lib$(CPU).a
START = start.o
-OBJS = asc_serial.o au1x00_serial.o au1x00_eth.o au1x00_usb_ohci.o \
+COBJS = asc_serial.o au1x00_serial.o au1x00_eth.o au1x00_usb_ohci.o \
cpu.o interrupts.o incaip_clock.o
SOBJS = incaip_wdt.o cache.o
-all: .depend $(START) $(LIB)
+SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
+START := $(addprefix $(obj),$(START))
-$(LIB): $(OBJS) $(SOBJS)
- $(AR) crv $@ $(OBJS) $(SOBJS)
+all: $(obj).depend $(START) $(LIB)
+
+$(LIB): $(OBJS)
+ $(AR) $(ARFLAGS) $@ $(OBJS)
#########################################################################
-.depend: Makefile $(START:.o=.S) $(OBJS:.o=.c)
- $(CC) -M $(CFLAGS) $(START:.o=.S) $(OBJS:.o=.c) > $@
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
-sinclude .depend
+sinclude $(obj).depend
#########################################################################
diff --git a/cpu/mpc5xx/Makefile b/cpu/mpc5xx/Makefile
index b787b61..8aab018 100644
--- a/cpu/mpc5xx/Makefile
+++ b/cpu/mpc5xx/Makefile
@@ -1,4 +1,7 @@
#
+# (C) Copyright 2006
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
# (C) Copyright 2003
# Martin Winistoerfer, martinwinistoerfer@gmx.ch.
#
@@ -32,21 +35,25 @@
include $(TOPDIR)/config.mk
-LIB = lib$(CPU).a
+LIB = $(obj)lib$(CPU).a
+
+START = start.o
+COBJS = serial.o cpu.o cpu_init.o interrupts.o traps.o speed.o spi.o
-START = start.S
-OBJS = serial.o cpu.o cpu_init.o interrupts.o traps.o speed.o spi.o
+SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
+START := $(addprefix $(obj),$(START))
-all: .depend $(START) $(LIB)
+all: $(obj).depend $(START) $(LIB)
$(LIB): $(OBJS)
- $(AR) crv $@ $(OBJS)
+ $(AR) $(ARFLAGS) $@ $(OBJS)
#########################################################################
-.depend: Makefile $(START:.o=.S) $(OBJS:.o=.c)
- $(CC) -M $(CFLAGS) $(START:.o=.S) $(OBJS:.o=.c) > $@
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
-sinclude .depend
+sinclude $(obj).depend
#########################################################################
diff --git a/cpu/mpc5xxx/Makefile b/cpu/mpc5xxx/Makefile
index a97b625..235adb7 100644
--- a/cpu/mpc5xxx/Makefile
+++ b/cpu/mpc5xxx/Makefile
@@ -1,5 +1,5 @@
#
-# (C) Copyright 2003
+# (C) Copyright 2003-2006
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
#
# See file CREDITS for list of people who contributed to this
@@ -23,23 +23,27 @@
include $(TOPDIR)/config.mk
-LIB = lib$(CPU).a
+LIB = $(obj)lib$(CPU).a
START = start.o
-ASOBJS = io.o firmware_sc_task_bestcomm.impl.o firmware_sc_task.impl.o
-OBJS = i2c.o traps.o cpu.o cpu_init.o fec.o ide.o interrupts.o \
+SOBJS = io.o firmware_sc_task_bestcomm.impl.o firmware_sc_task.impl.o
+COBJS = i2c.o traps.o cpu.o cpu_init.o fec.o ide.o interrupts.o \
loadtask.o pci_mpc5200.o serial.o speed.o usb_ohci.o
-all: .depend $(START) $(ASOBJS) $(LIB)
+SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
+START := $(addprefix $(obj),$(START))
+
+all: $(obj).depend $(START) $(LIB)
$(LIB): $(OBJS)
- $(AR) crv $@ $(ASOBJS) $(OBJS)
+ $(AR) $(ARFLAGS) $@ $(OBJS)
#########################################################################
-.depend: Makefile $(START:.o=.S) $(OBJS:.o=.c)
- $(CC) -M $(CFLAGS) $(START:.o=.S) $(ASOBJS:.o=.S) $(OBJS:.o=.c) > $@
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
-sinclude .depend
+sinclude $(obj).depend
#########################################################################
diff --git a/cpu/mpc5xxx/fec.c b/cpu/mpc5xxx/fec.c
index 19737ce..37fe3e7 100644
--- a/cpu/mpc5xxx/fec.c
+++ b/cpu/mpc5xxx/fec.c
@@ -882,7 +882,7 @@ int mpc5xxx_fec_initialize(bd_t * bis)
defined(CONFIG_ICECUBE) || defined(CONFIG_INKA4X0) || \
defined(CONFIG_MCC200) || defined(CONFIG_O2DNT) || \
defined(CONFIG_PM520) || defined(CONFIG_TOP5200) || \
- defined(CONFIG_TQM5200)
+ defined(CONFIG_TQM5200) || defined(CONFIG_V38B)
# ifndef CONFIG_FEC_10MBIT
fec->xcv_type = MII100;
# else
diff --git a/cpu/mpc5xxx/interrupts.c b/cpu/mpc5xxx/interrupts.c
index 7bacecd..beeb222 100644
--- a/cpu/mpc5xxx/interrupts.c
+++ b/cpu/mpc5xxx/interrupts.c
@@ -1,4 +1,7 @@
/*
+ * (C) Copyright 2006
+ * Detlev Zundel, DENX Software Engineering, dzu@denx.de
+ *
* (C) Copyright -2003
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
@@ -24,18 +27,212 @@
* MA 02111-1307 USA
*/
-/*
- * interrupts.c - just enough support for the decrementer/timer
+/* this section was ripped out of arch/ppc/syslib/mpc52xx_pic.c in the
+ * Linux 2.6 source with the following copyright.
+ *
+ * Based on (well, mostly copied from) the code from the 2.4 kernel by
+ * Dale Farnsworth <dfarnsworth@mvista.com> and Kent Borg.
+ *
+ * Copyright (C) 2004 Sylvain Munaut <tnt@246tNt.com>
+ * Copyright (C) 2003 Montavista Software, Inc
*/
#include <common.h>
#include <asm/processor.h>
+#include <asm/io.h>
#include <command.h>
-int interrupt_init_cpu (ulong *decrementer_count)
+struct irq_action {
+ interrupt_handler_t *handler;
+ void *arg;
+ ulong count;
+};
+
+static struct irq_action irq_handlers[NR_IRQS];
+
+static struct mpc5xxx_intr *intr;
+static struct mpc5xxx_sdma *sdma;
+
+static void mpc5xxx_ic_disable(unsigned int irq)
+{
+ u32 val;
+
+ if (irq == MPC5XXX_IRQ0) {
+ val = in_be32(&intr->ctrl);
+ val &= ~(1 << 11);
+ out_be32(&intr->ctrl, val);
+ } else if (irq < MPC5XXX_IRQ1) {
+ BUG();
+ } else if (irq <= MPC5XXX_IRQ3) {
+ val = in_be32(&intr->ctrl);
+ val &= ~(1 << (10 - (irq - MPC5XXX_IRQ1)));
+ out_be32(&intr->ctrl, val);
+ } else if (irq < MPC5XXX_SDMA_IRQ_BASE) {
+ val = in_be32(&intr->main_mask);
+ val |= 1 << (16 - (irq - MPC5XXX_MAIN_IRQ_BASE));
+ out_be32(&intr->main_mask, val);
+ } else if (irq < MPC5XXX_PERP_IRQ_BASE) {
+ val = in_be32(&sdma->IntMask);
+ val |= 1 << (irq - MPC5XXX_SDMA_IRQ_BASE);
+ out_be32(&sdma->IntMask, val);
+ } else {
+ val = in_be32(&intr->per_mask);
+ val |= 1 << (31 - (irq - MPC5XXX_PERP_IRQ_BASE));
+ out_be32(&intr->per_mask, val);
+ }
+}
+
+static void mpc5xxx_ic_enable(unsigned int irq)
+{
+ u32 val;
+
+ if (irq == MPC5XXX_IRQ0) {
+ val = in_be32(&intr->ctrl);
+ val |= 1 << 11;
+ out_be32(&intr->ctrl, val);
+ } else if (irq < MPC5XXX_IRQ1) {
+ BUG();
+ } else if (irq <= MPC5XXX_IRQ3) {
+ val = in_be32(&intr->ctrl);
+ val |= 1 << (10 - (irq - MPC5XXX_IRQ1));
+ out_be32(&intr->ctrl, val);
+ } else if (irq < MPC5XXX_SDMA_IRQ_BASE) {
+ val = in_be32(&intr->main_mask);
+ val &= ~(1 << (16 - (irq - MPC5XXX_MAIN_IRQ_BASE)));
+ out_be32(&intr->main_mask, val);
+ } else if (irq < MPC5XXX_PERP_IRQ_BASE) {
+ val = in_be32(&sdma->IntMask);
+ val &= ~(1 << (irq - MPC5XXX_SDMA_IRQ_BASE));
+ out_be32(&sdma->IntMask, val);
+ } else {
+ val = in_be32(&intr->per_mask);
+ val &= ~(1 << (31 - (irq - MPC5XXX_PERP_IRQ_BASE)));
+ out_be32(&intr->per_mask, val);
+ }
+}
+
+static void mpc5xxx_ic_ack(unsigned int irq)
+{
+ u32 val;
+
+ /*
+ * Only some irqs are reset here, others in interrupting hardware.
+ */
+
+ switch (irq) {
+ case MPC5XXX_IRQ0:
+ val = in_be32(&intr->ctrl);
+ val |= 0x08000000;
+ out_be32(&intr->ctrl, val);
+ break;
+ case MPC5XXX_CCS_IRQ:
+ val = in_be32(&intr->enc_status);
+ val |= 0x00000400;
+ out_be32(&intr->enc_status, val);
+ break;
+ case MPC5XXX_IRQ1:
+ val = in_be32(&intr->ctrl);
+ val |= 0x04000000;
+ out_be32(&intr->ctrl, val);
+ break;
+ case MPC5XXX_IRQ2:
+ val = in_be32(&intr->ctrl);
+ val |= 0x02000000;
+ out_be32(&intr->ctrl, val);
+ break;
+ case MPC5XXX_IRQ3:
+ val = in_be32(&intr->ctrl);
+ val |= 0x01000000;
+ out_be32(&intr->ctrl, val);
+ break;
+ default:
+ if (irq >= MPC5XXX_SDMA_IRQ_BASE
+ && irq < (MPC5XXX_SDMA_IRQ_BASE + MPC5XXX_SDMA_IRQ_NUM)) {
+ out_be32(&sdma->IntPend,
+ 1 << (irq - MPC5XXX_SDMA_IRQ_BASE));
+ }
+ break;
+ }
+}
+
+static void mpc5xxx_ic_disable_and_ack(unsigned int irq)
+{
+ mpc5xxx_ic_disable(irq);
+ mpc5xxx_ic_ack(irq);
+}
+
+static void mpc5xxx_ic_end(unsigned int irq)
+{
+ mpc5xxx_ic_enable(irq);
+}
+
+void mpc5xxx_init_irq(void)
+{
+ u32 intr_ctrl;
+
+ /* Remap the necessary zones */
+ intr = (struct mpc5xxx_intr *)(MPC5XXX_ICTL);
+ sdma = (struct mpc5xxx_sdma *)(MPC5XXX_SDMA);
+
+ /* Disable all interrupt sources. */
+ out_be32(&sdma->IntPend, 0xffffffff); /* 1 means clear pending */
+ out_be32(&sdma->IntMask, 0xffffffff); /* 1 means disabled */
+ out_be32(&intr->per_mask, 0x7ffffc00); /* 1 means disabled */
+ out_be32(&intr->main_mask, 0x00010fff); /* 1 means disabled */
+ intr_ctrl = in_be32(&intr->ctrl);
+ intr_ctrl |= 0x0f000000 | /* clear IRQ 0-3 */
+ 0x00ff0000 | /* IRQ 0-3 level sensitive low active */
+ 0x00001000 | /* MEE master external enable */
+ 0x00000000 | /* 0 means disable IRQ 0-3 */
+ 0x00000001; /* CEb route critical normally */
+ out_be32(&intr->ctrl, intr_ctrl);
+
+ /* Zero a bunch of the priority settings. */
+ out_be32(&intr->per_pri1, 0);
+ out_be32(&intr->per_pri2, 0);
+ out_be32(&intr->per_pri3, 0);
+ out_be32(&intr->main_pri1, 0);
+ out_be32(&intr->main_pri2, 0);
+}
+
+int mpc5xxx_get_irq(struct pt_regs *regs)
+{
+ u32 status;
+ int irq = -1;
+
+ status = in_be32(&intr->enc_status);
+
+ if (status & 0x00000400) { /* critical */
+ irq = (status >> 8) & 0x3;
+ if (irq == 2) /* high priority peripheral */
+ goto peripheral;
+ irq += MPC5XXX_CRIT_IRQ_BASE;
+ } else if (status & 0x00200000) { /* main */
+ irq = (status >> 16) & 0x1f;
+ if (irq == 4) /* low priority peripheral */
+ goto peripheral;
+ irq += MPC5XXX_MAIN_IRQ_BASE;
+ } else if (status & 0x20000000) { /* peripheral */
+ peripheral:
+ irq = (status >> 24) & 0x1f;
+ if (irq == 0) { /* bestcomm */
+ status = in_be32(&sdma->IntPend);
+ irq = ffs(status) + MPC5XXX_SDMA_IRQ_BASE - 1;
+ } else
+ irq += MPC5XXX_PERP_IRQ_BASE;
+ }
+
+ return irq;
+}
+
+/****************************************************************************/
+
+int interrupt_init_cpu(ulong * decrementer_count)
{
*decrementer_count = get_tbclk() / CFG_HZ;
+ mpc5xxx_init_irq();
+
return (0);
}
@@ -44,14 +241,32 @@ int interrupt_init_cpu (ulong *decrementer_count)
/*
* Handle external interrupts
*/
-void
-external_interrupt(struct pt_regs *regs)
+void external_interrupt(struct pt_regs *regs)
{
- puts("external_interrupt (oops!)\n");
+ int irq, unmask = 1;
+
+ irq = mpc5xxx_get_irq(regs);
+
+ mpc5xxx_ic_disable_and_ack(irq);
+
+ enable_interrupts();
+
+ if (irq_handlers[irq].handler != NULL)
+ (*irq_handlers[irq].handler) (irq_handlers[irq].arg);
+ else {
+ printf("\nBogus External Interrupt IRQ %d\n", irq);
+ /*
+ * turn off the bogus interrupt, otherwise it
+ * might repeat forever
+ */
+ unmask = 0;
+ }
+
+ if (unmask)
+ mpc5xxx_ic_end(irq);
}
-void
-timer_interrupt_cpu (struct pt_regs *regs)
+void timer_interrupt_cpu(struct pt_regs *regs)
{
/* nothing to do here */
return;
@@ -63,22 +278,69 @@ timer_interrupt_cpu (struct pt_regs *regs)
* Install and free a interrupt handler.
*/
-void
-irq_install_handler(int vec, interrupt_handler_t *handler, void *arg)
+void irq_install_handler(int irq, interrupt_handler_t * handler, void *arg)
{
+ if (irq < 0 || irq >= NR_IRQS) {
+ printf("irq_install_handler: bad irq number %d\n", irq);
+ return;
+ }
+ if (irq_handlers[irq].handler != NULL)
+ printf("irq_install_handler: 0x%08lx replacing 0x%08lx\n",
+ (ulong) handler, (ulong) irq_handlers[irq].handler);
+
+ irq_handlers[irq].handler = handler;
+ irq_handlers[irq].arg = arg;
+
+ mpc5xxx_ic_enable(irq);
}
-void
-irq_free_handler(int vec)
+void irq_free_handler(int irq)
{
+ if (irq < 0 || irq >= NR_IRQS) {
+ printf("irq_free_handler: bad irq number %d\n", irq);
+ return;
+ }
+
+ mpc5xxx_ic_disable(irq);
+ irq_handlers[irq].handler = NULL;
+ irq_handlers[irq].arg = NULL;
}
/****************************************************************************/
-void
-do_irqinfo(cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[])
+#if (CONFIG_COMMANDS & CFG_CMD_IRQ)
+void do_irqinfo(cmd_tbl_t * cmdtp, bd_t * bd, int flag, int argc, char *argv[])
{
- puts("IRQ related functions are unimplemented currently.\n");
+ int irq, re_enable;
+ u32 intr_ctrl;
+ char *irq_config[] = { "level sensitive, active high",
+ "edge sensitive, rising active edge",
+ "edge sensitive, falling active edge",
+ "level sensitive, active low"
+ };
+
+ re_enable = disable_interrupts();
+
+ intr_ctrl = in_be32(&intr->ctrl);
+ printf("Interrupt configuration:\n");
+
+ for (irq = 0; irq <= 3; irq++) {
+ printf("IRQ%d: %s\n", irq,
+ irq_config[(intr_ctrl >> (22 - 2 * irq)) & 0x3]);
+ }
+
+ puts("\nInterrupt-Information:\n" "Nr Routine Arg Count\n");
+
+ for (irq = 0; irq < NR_IRQS; irq++)
+ if (irq_handlers[irq].handler != NULL)
+ printf("%02d %08lx %08lx %ld\n", irq,
+ (ulong) irq_handlers[irq].handler,
+ (ulong) irq_handlers[irq].arg,
+ irq_handlers[irq].count);
+
+ if (re_enable)
+ enable_interrupts();
}
+#endif
diff --git a/cpu/mpc5xxx/serial.c b/cpu/mpc5xxx/serial.c
index 6cb523d..430d63f 100644
--- a/cpu/mpc5xxx/serial.c
+++ b/cpu/mpc5xxx/serial.c
@@ -166,6 +166,25 @@ void serial_putc(const char c)
}
#if defined(CONFIG_SERIAL_MULTI)
+void serial_putc_raw_dev(unsigned long dev_base, const char c)
+#else
+void serial_putc_raw(const char c)
+#endif
+{
+#if defined(CONFIG_SERIAL_MULTI)
+ volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)dev_base;
+#else
+ volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)PSC_BASE;
+#endif
+ /* Wait for last character to go. */
+ while (!(psc->psc_status & PSC_SR_TXEMP))
+ ;
+
+ psc->psc_buffer_8 = c;
+}
+
+
+#if defined(CONFIG_SERIAL_MULTI)
void serial_puts_dev (unsigned long dev_base, const char *s)
#else
void serial_puts (const char *s)
@@ -240,6 +259,43 @@ void serial_setbrg(void)
}
#if defined(CONFIG_SERIAL_MULTI)
+void serial_setrts_dev (unsigned long dev_base, int s)
+#else
+void serial_setrts(int s)
+#endif
+{
+#if defined(CONFIG_SERIAL_MULTI)
+ volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)dev_base;
+#else
+ volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)PSC_BASE;
+#endif
+
+ if (s) {
+ /* Assert RTS (become LOW) */
+ psc->op1 = 0x1;
+ }
+ else {
+ /* Negate RTS (become HIGH) */
+ psc->op0 = 0x1;
+ }
+}
+
+#if defined(CONFIG_SERIAL_MULTI)
+int serial_getcts_dev (unsigned long dev_base)
+#else
+int serial_getcts(void)
+#endif
+{
+#if defined(CONFIG_SERIAL_MULTI)
+ volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)dev_base;
+#else
+ volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)PSC_BASE;
+#endif
+
+ return (psc->ip & 0x1) ? 0 : 1;
+}
+
+#if defined(CONFIG_SERIAL_MULTI)
int serial0_init(void)
{
return (serial_init_dev(PSC_BASE));
diff --git a/cpu/mpc8220/Makefile b/cpu/mpc8220/Makefile
index 7c9b6c9..b4fad28 100644
--- a/cpu/mpc8220/Makefile
+++ b/cpu/mpc8220/Makefile
@@ -1,5 +1,5 @@
#
-# (C) Copyright 2003
+# (C) Copyright 2003-2006
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
#
# See file CREDITS for list of people who contributed to this
@@ -23,24 +23,28 @@
include $(TOPDIR)/config.mk
-LIB = lib$(CPU).a
+LIB = $(obj)lib$(CPU).a
START = start.o
-ASOBJS = io.o fec_dma_tasks.o
-OBJS = cpu.o cpu_init.o dramSetup.o fec.o i2c.o \
+SOBJS = io.o fec_dma_tasks.o
+COBJS = cpu.o cpu_init.o dramSetup.o fec.o i2c.o \
interrupts.o loadtask.o speed.o \
traps.o uart.o pci.o
-all: .depend $(START) $(ASOBJS) $(LIB)
+SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
+START := $(addprefix $(obj),$(START))
+
+all: $(obj).depend $(START) $(LIB)
$(LIB): $(OBJS)
- $(AR) crv $@ $(ASOBJS) $(OBJS)
+ $(AR) $(ARFLAGS) $@ $(OBJS)
#########################################################################
-.depend: Makefile $(START:.o=.S) $(OBJS:.o=.c)
- $(CC) -M $(CFLAGS) $(START:.o=.S) $(ASOBJS:.o=.S) $(OBJS:.o=.c) > $@
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
-sinclude .depend
+sinclude $(obj).depend
#########################################################################
diff --git a/cpu/mpc8220/pci.c b/cpu/mpc8220/pci.c
index ca4a04d..4ef214e 100644
--- a/cpu/mpc8220/pci.c
+++ b/cpu/mpc8220/pci.c
@@ -170,7 +170,7 @@ pci_mpc8220_init(struct pci_controller *hose)
hose->region_count = 3;
hose->cfg_addr = &(xcpci->cfg_adr);
- hose->cfg_data = CONFIG_PCI_CFG_BUS;
+ hose->cfg_data = (volatile unsigned char *)CONFIG_PCI_CFG_BUS;
pci_set_ops(hose,
mpc8220_pci_read_config_byte,
diff --git a/cpu/mpc824x/Makefile b/cpu/mpc824x/Makefile
index df0d64e..f249dd7 100644
--- a/cpu/mpc824x/Makefile
+++ b/cpu/mpc824x/Makefile
@@ -1,5 +1,5 @@
#
-# (C) Copyright 2000
+# (C) Copyright 2000-2006
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
#
# See file CREDITS for list of people who contributed to this
@@ -22,26 +22,35 @@
#
include $(TOPDIR)/config.mk
+ifneq ($(OBJTREE),$(SRCTREE))
+$(shell mkdir -p $(obj)drivers/epic)
+$(shell mkdir -p $(obj)drivers/i2c)
+endif
-LIB = lib$(CPU).a
+LIB = $(obj)lib$(CPU).a
-START = start.S
-OBJS = traps.o cpu.o cpu_init.o interrupts.o speed.o \
- drivers/epic/epic1.o drivers/i2c/i2c.o pci.o bedbug_603e.o
+START = start.o
+COBJS = traps.o cpu.o cpu_init.o interrupts.o speed.o \
+ drivers/epic/epic1.o drivers/i2c/i2c.o pci.o
+COBJS_LN = bedbug_603e.o
-all: .depend $(START) $(LIB)
+SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c) $(addprefix $(obj),$(COBJS_LN:.o=.c))
+OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS) $(COBJS_LN))
+START := $(addprefix $(obj),$(START))
+
+all: $(obj).depend $(START) $(LIB)
$(LIB): $(OBJS)
- $(AR) crv $@ $(OBJS)
+ $(AR) $(ARFLAGS) $@ $(OBJS)
-bedbug_603e.c:
- ln -s ../mpc8260/bedbug_603e.c bedbug_603e.c
+$(obj)bedbug_603e.c:
+ ln -s $(src)../mpc8260/bedbug_603e.c $(obj)bedbug_603e.c
#########################################################################
-.depend: Makefile $(START:.o=.S) $(OBJS:.o=.c)
- $(CC) -M $(CFLAGS) $(START:.o=.S) $(OBJS:.o=.c) > $@
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
-sinclude .depend
+sinclude $(obj).depend
#########################################################################
diff --git a/cpu/mpc824x/drivers/dma/Makefile b/cpu/mpc824x/drivers/dma/Makefile
deleted file mode 100644
index 59e2fac..0000000
--- a/cpu/mpc824x/drivers/dma/Makefile
+++ /dev/null
@@ -1,83 +0,0 @@
-##########################################################################
-#
-# Copyright Motorola, Inc. 1997
-# ALL RIGHTS RESERVED
-#
-# You are hereby granted a copyright license to use, modify, and
-# distribute the SOFTWARE so long as this entire notice is retained
-# without alteration in any modified and/or redistributed versions,
-# and that such modified versions are clearly identified as such.
-# No licenses are granted by implication, estoppel or otherwise under
-# any patents or trademarks of Motorola, Inc.
-#
-# The SOFTWARE is provided on an "AS IS" basis and without warranty.
-# To the maximum extent permitted by applicable law, MOTOROLA DISCLAIMS
-# ALL WARRANTIES WHETHER EXPRESS OR IMPLIED, INCLUDING IMPLIED
-# WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR
-# PURPOSE AND ANY WARRANTY AGAINST INFRINGEMENT WITH
-# REGARD TO THE SOFTWARE (INCLUDING ANY MODIFIED VERSIONS
-# THEREOF) AND ANY ACCOMPANYING WRITTEN MATERIALS.
-#
-# To the maximum extent permitted by applicable law, IN NO EVENT SHALL
-# MOTOROLA BE LIABLE FOR ANY DAMAGES WHATSOEVER
-# (INCLUDING WITHOUT LIMITATION, DAMAGES FOR LOSS OF
-# BUSINESS PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS
-# INFORMATION, OR OTHER PECUNIARY LOSS) ARISING OF THE USE OR
-# INABILITY TO USE THE SOFTWARE.
-#
-############################################################################
-TARGET = libdma.a
-
-DEBUG = -DDMADBG
-LST = -Hanno -S
-OPTIM =
-CC = /risc/tools/pkgs/metaware/bin/hcppc
-CFLAGS = -Hnocopyr -c -Hsds -Hon=Char_default_unsigned -Hon=Char_is_rep -I../inc -I/risc/tools/pkgs/metaware/inc
-CCobj = $(CC) $(CFLAGS) $(DEBUG) $(OPTIM)
-PREP = $(CC) $(CFLAGS) -P
-
-# Assembler used to build the .s files (for the board version)
-
-ASOPT = -big_si -c
-ASDEBUG = -l -fm
-AS = /risc/tools/pkgs/metaware/bin/asppc
-
-# Linker to bring .o files together into an executable.
-
-LKOPT = -Bbase=0 -q -r -Qn
-LKCMD =
-LINK = /risc/tools/pkgs/metaware/bin/ldppc $(LKCMD) $(LKOPT)
-
-# DOS Utilities
-
-DEL = rm
-COPY = cp
-LIST = ls
-
-OBJECTS = dma1.o dma2.o
-
-all: $(TARGET)
-
-$(TARGET): $(OBJECTS)
- $(LINK) $(OBJECTS) -o $@
-
-objects: dma1.o
-
-clean:
- $(DEL) -f *.o *.i *.map *.lst $(TARGET) $(OBJECTS)
-
-.s.o:
- $(DEL) -f $*.i
- $(PREP) -Hasmcpp $<
- $(AS) $(ASOPT) $*.i
-# $(AS) $(ASOPT) $(ASDEBUG) $*.i > $*.lst
-
-.c.o:
- $(CCobj) $<
-
-.c.s:
- $(CCobj) $(LST) $<
-
-dma1.o: dma_export.h dma.h dma1.c
-
-dma2.o: dma.h dma2.s
diff --git a/cpu/mpc824x/drivers/dma/Makefile_pc b/cpu/mpc824x/drivers/dma/Makefile_pc
deleted file mode 100644
index 8df2a3c..0000000
--- a/cpu/mpc824x/drivers/dma/Makefile_pc
+++ /dev/null
@@ -1,89 +0,0 @@
-##########################################################################
-#
-# makefile_pc for use with mksnt tools drivers/dma
-#
-# Copyright Motorola, Inc. 1997
-# ALL RIGHTS RESERVED
-#
-# You are hereby granted a copyright license to use, modify, and
-# distribute the SOFTWARE so long as this entire notice is retained
-# without alteration in any modified and/or redistributed versions,
-# and that such modified versions are clearly identified as such.
-# No licenses are granted by implication, estoppel or otherwise under
-# any patents or trademarks of Motorola, Inc.
-#
-# The SOFTWARE is provided on an "AS IS" basis and without warranty.
-# To the maximum extent permitted by applicable law, MOTOROLA DISCLAIMS
-# ALL WARRANTIES WHETHER EXPRESS OR IMPLIED, INCLUDING IMPLIED
-# WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR
-# PURPOSE AND ANY WARRANTY AGAINST INFRINGEMENT WITH
-# REGARD TO THE SOFTWARE (INCLUDING ANY MODIFIED VERSIONS
-# THEREOF) AND ANY ACCOMPANYING WRITTEN MATERIALS.
-#
-# To the maximum extent permitted by applicable law, IN NO EVENT SHALL
-# MOTOROLA BE LIABLE FOR ANY DAMAGES WHATSOEVER
-# (INCLUDING WITHOUT LIMITATION, DAMAGES FOR LOSS OF
-# BUSINESS PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS
-# INFORMATION, OR OTHER PECUNIARY LOSS) ARISING OF THE USE OR
-# INABILITY TO USE THE SOFTWARE.
-#
-############################################################################
-TARGET = libdma.a
-
-DEBUG = -DDMADBG
-LST = -Hanno -S
-OPTIM =
-CC = m:/old_tools/tools/hcppc/bin/hcppc
-CFLAGS = -Hnocopyr -c -Hsds -Hon=Char_default_unsigned -Hon=Char_is_rep -I../inc -I/risc/tools/pkgs/metaware/inc
-CCobj = $(CC) $(CFLAGS) $(DEBUG) $(OPTIM)
-PREP = $(CC) $(CFLAGS) -P
-
-# Assembler used to build the .s files (for the board version)
-
-ASOPT = -big_si -c
-ASDEBUG = -l -fm
-AS = m:/old_tools/tools/hcppc/bin/asppc
-
-# Linker to bring .o files together into an executable.
-
-LKOPT = -Bbase=0 -q -r -Qn
-LKCMD =
-LINK = m:/old_tools/tools/hcppc/bin/ldppc $(LKCMD) $(LKOPT)
-
-# DOS Utilities
-
-DEL = rm
-COPY = cp
-LIST = ls
-
-OBJECTS = dma1.o dma2.o
-
-all: $(TARGET)
-
-$(TARGET): $(OBJECTS)
- $(LINK) $(OBJECTS) -o $@
-
-objects: dma1.o
-
-clean:
- $(DEL) -f *.o *.i *.map *.lst $(TARGET) $(OBJECTS)
-
-.s.o:
- $(DEL) -f $*.i
- $(PREP) -Hasmcpp $<
- $(AS) $(ASOPT) $*.i
-# $(AS) $(ASOPT) $(ASDEBUG) $*.i > $*.lst
-
-.c.o:
- $(CCobj) $<
-
-.c.s:
- $(CCobj) $(LST) $<
-
-dma1.o: dma_export.h dma.h dma1.c
- $(CCobj) $<
-
-dma2.o: dma.h dma2.s
- $(DEL) -f $*.i
- $(PREP) -Hasmcpp $<
- $(AS) $(ASOPT) $*.i
diff --git a/cpu/mpc824x/drivers/dma/README b/cpu/mpc824x/drivers/dma/README
deleted file mode 100644
index 06f4bc0..0000000
--- a/cpu/mpc824x/drivers/dma/README
+++ /dev/null
@@ -1,100 +0,0 @@
-CONTENT:
-
- dma.h
- dma1.c
- dma2.s
-
-WHAT ARE THESE FILES:
-
-These files contain MPC8240 (Kahlua) DMA controller
-driver routines. The driver routines are not
-written for any specific operating system.
-They serves the purpose of code sample, and
-jump-start for using the MPC8240 DMA controller.
-
-For the reason of correctness of C language
-syntax, these files are compiled by Metaware
-C compiler and assembler.
-
-ENDIAN NOTATION:
-
-The algorithm is designed for big-endian mode,
-software is responsible for byte swapping.
-
-USAGE:
-
-1. The host system that is running on MPC8240
- or using MPC8240 as I/O device shall link
- the files listed here. The memory location
- of driver routines shall take into account of
- that driver routines need to run in supervisor
- mode and they process DMA controller interrupt.
-
-2. The host system is responsible for configuring
- the MPC8240 including Embedded Utilities Memory
- Block. Since the DMA controller on MPC8240 can
- be accessed by either local 603e core or the host
- that MPC8240 serves as I/O processor through host
- PCI configuration, it is important that the local
- processor uses EUMBBAR to access its local DMA
- controller while the PCI master uses I/O
- processor's PCSRBAR to access the DMA controller
- on I/O device.
-
- To qualify whether is EUMBBAR or PCSRBAR, one
- additional parameter is requied from the host
- system, LOCAL or REMOTE so that the base value
- can be correctly interpreted.
-
-3. If the host system is also using the EPIC unit
- on MPC8240, the system can register the
- DMA_ISR with the EPIC including other
- desired resources.
-
- If the host system does not using the EPIC unit
- on MPC8240, DMA_ISR function can be called for
- each desired time interval.
-
- In both cases, the host system is free to
- provide its own interrupt service routine.
-
-4. To start a direct mode DMA transaction,
- use DMA_Bld_Curr with the start parameter
- set to 1.
-
- To start a chaining mode DMA transaction,
- the application shall build descriptors
- in memory first, next, use DMA_Bld_Desp
- with the start parameter set to 1.
-
-5. DMA_Start function clears, then sets the CS
- bit of DMA mode register.
-
- DMA_Halt function clears the CS bit of DMA
- mode register.
-
- These functions can be used to start and
- halt the DMA transaction.
-
- If the chaining descriptors has been
- modified since the last time a DMA
- transaction started, use DMA_Chn_Cnt
- function to let DMA controller process
- the modified descriptor chain without
- stopping or disturbing the current DMA
- transaction.
-
- It is the host system's responsibility of
- setting up the correct DMA transfer mode
- and pass the correct memory address parameters.
-
-6. It is the host system's responsibility of
- queueing the DMA I/O request. The host
- system can call the DMA_ISR with its own
- desired interrupt service subroutines to
- handle each individual interrupt and queued
- DMA I/O requests.
-
-7. The DMA driver routines contains a set
- of utilities, Set and Get, for host system
- to query and modify the desired DMA registers.
diff --git a/cpu/mpc824x/drivers/dma/dma.h b/cpu/mpc824x/drivers/dma/dma.h
deleted file mode 100644
index a21be74..0000000
--- a/cpu/mpc824x/drivers/dma/dma.h
+++ /dev/null
@@ -1,326 +0,0 @@
-#ifndef DMA_H
-#define DMA_H
-/*******************************************************
- *
- * copyright @ Motorola 1999
- *
- *******************************************************/
-#define NUM_DMA_REG 7
-#define DMA_MR_REG 0
-#define DMA_SR_REG 1
-#define DMA_CDAR_REG 2
-#define DMA_SAR_REG 3
-#define DMA_DAR_REG 4
-#define DMA_BCR_REG 5
-#define DMA_NDAR_REG 6
-
-typedef enum _dmastatus
-{
- DMASUCCESS = 0x1000,
- DMALMERROR,
- DMAPERROR,
- DMACHNBUSY,
- DMAEOSINT,
- DMAEOCAINT,
- DMAINVALID,
- DMANOEVENT,
-} DMAStatus;
-
-typedef enum _location
-{
- LOCAL = 0, /* local processor accesses on board DMA,
- local processor's eumbbar is required */
- REMOTE = 1, /* PCI master accesses DMA on I/O board,
- I/O processor's pcsrbar is required */
-} LOCATION;
-
-typedef enum dma_mr_bit
-{
- IRQS = 0x00080000,
- PDE = 0x00040000,
- DAHTS = 0x00030000,
- SAHTS = 0x0000c000,
- DAHE = 0x00002000,
- SAHE = 0x00001000,
- PRC = 0x00000c00,
- EIE = 0x00000080,
- EOTIE = 0x00000040,
- DL = 0x00000008,
- CTM = 0x00000004,
- CC = 0x00000002,
- CS = 0x00000001,
-} DMA_MR_BIT;
-
-typedef enum dma_sr_bit
-{
- LME = 0x00000080,
- PE = 0x00000010,
- CB = 0x00000004,
- EOSI = 0x00000002,
- EOCAI = 0x00000001,
-} DMA_SR_BIT;
-
-/* structure for DMA Mode Register */
-typedef struct _dma_mr
-{
- unsigned int reserved0 : 12;
- unsigned int irqs : 1;
- unsigned int pde : 1;
- unsigned int dahts : 2;
- unsigned int sahts : 2;
- unsigned int dahe : 1;
- unsigned int sahe : 1;
- unsigned int prc : 2;
- unsigned int reserved1 : 1;
- unsigned int eie : 1;
- unsigned int eotie : 1;
- unsigned int reserved2 : 3;
- unsigned int dl : 1;
- unsigned int ctm : 1;
- /* if chaining mode is enabled, any time, user can modify the
- * descriptor and does not need to halt the current DMA transaction.
- * Set CC bit, enable DMA to process the modified descriptors
- * Hardware will clear this bit each time, DMA starts.
- */
- unsigned int cc : 1;
- /* cs bit has dua role, halt the current DMA transaction and
- * (re)start DMA transaction. In chaining mode, if the descriptor
- * needs modification, cs bit shall be used not the cc bit.
- * Hardware will not set/clear this bit each time DMA transaction
- * stops or starts. Software shall do it.
- *
- * cs bit shall not be used to halt chaining DMA transaction for
- * modifying the descriptor. That is the role of CC bit.
- */
- unsigned int cs : 1;
-} DMA_MR;
-
-/* structure for DMA Status register */
-typedef struct _dma_sr
-{
- unsigned int reserved0 : 24;
- unsigned int lme : 1;
- unsigned int reserved1 : 2;
- unsigned int pe : 1;
- unsigned int reserved2 : 1;
- unsigned int cb : 1;
- unsigned int eosi : 1;
- unsigned int eocai : 1;
-} DMA_SR;
-
-/* structure for DMA current descriptor address register */
-typedef struct _dma_cdar
-{
- unsigned int cda : 27;
- unsigned int snen : 1;
- unsigned int eosie : 1;
- unsigned int ctt : 2;
- unsigned int eotd : 1;
-} DMA_CDAR;
-
-/* structure for DMA byte count register */
-typedef struct _dma_bcr
-{
- unsigned int reserved : 6;
- unsigned int bcr : 26;
-} DMA_BCR;
-
-/* structure for DMA Next Descriptor Address register */
-typedef struct _dma_ndar
-{
- unsigned int nda : 27;
- unsigned int ndsnen : 1;
- unsigned int ndeosie: 1;
- unsigned int ndctt : 2;
- unsigned int eotd : 1;
-} DMA_NDAR;
-
-/* structure for DMA current transaction info */
-typedef struct _dma_curr
-{
- unsigned int src_addr;
- unsigned int dest_addr;
- unsigned int byte_cnt;
-} DMA_CURR;
-
-/************************* Kernel API********************
- * Kernel APIs are used to interface with O.S. kernel.
- * They are the functions required by O.S. kernel to
- * provide I/O service.
- ********************************************************/
-
-/**************DMA Device Control Functions ********/
-
-/**
- * Note:
- *
- * In all following functions, the host (KAHLUA) processor has a
- * choice of accessing on board local DMA (LOCAL),
- * or DMA on a distributed KAHLUA (REMOTE). In either case,
- * the caller shall pass the configured embedded utility memory
- * block base address relative to the DMA. If LOCAL DMA is used,
- * this parameter shall be EUMBBAR, if REMOTE is used, the
- * parameter shall be the corresponding PCSRBAR.
- **/
-
-/**************************************************************
- * function: DMA_Get_Stat
- *
- * description: return the content of status register of
- * the given DMA channel
- * if error, return DMAINVALID. Otherwise return
- * DMASUCCESS.
- *
- **************************************************************/
-static DMAStatus DMA_Get_Stat( LOCATION, unsigned int eumbbar, unsigned int channel, DMA_SR * );
-
-/**************************************************************
- * function: DMA_Get_Mode
- *
- * description: return the content of mode register of the
- * given DMA channel
- * if error, return DMAINVALID. Otherwise return DMASUCCESS.
- *
- **************************************************************/
-static DMAStatus DMA_Get_Mode( LOCATION, unsigned int eumbbar, unsigned int channel, DMA_MR * );
-
-/**************************************************************
- * function: DMA_Set_Mode
- *
- * description: Set a new mode to a given DMA channel
- * return DMASUCCESS if success, otherwise return DMACHNINVALID
- *
- * note: It is not a good idea of changing the DMA mode during
- * the middle of a transaction.
- **************************************************************/
-static DMAStatus DMA_Set_Mode( LOCATION, unsigned int eumbbar, unsigned int channel, DMA_MR mode );
-
-/*************************************************************
- * function: DMA_ISR
- *
- * description: DMA interrupt service routine
- * return DMAStatus based on the status
- *
- *************************************************************/
-static DMAStatus DMA_ISR( unsigned int eumbbar,
- unsigned int channel,
- DMAStatus (*lme_func)( unsigned int, unsigned int, DMAStatus ),
- DMAStatus (*pe_func) ( unsigned int, unsigned int, DMAStatus ),
- DMAStatus (*eosi_func)( unsigned int, unsigned int, DMAStatus ),
- DMAStatus (*eocai_func)(unsigned int, unsigned int, DMAStatus ));
-
-static DMAStatus dma_error_func( unsigned int, unsigned int, DMAStatus );
-
-/********************* DMA I/O function ********************/
-
-/************************************************************
- * function: DMA_Start
- *
- * description: start a given DMA channel transaction
- * return DMASUCCESS if success, otherwise return DMACHNINVALID
- *
- * note: this function will clear DMA_MR(CC) first, then
- * set DMA_MR(CC).
- ***********************************************************/
-static DMAStatus DMA_Start( LOCATION, unsigned int eumbbar,unsigned int channel );
-
-/***********************************************************
- * function: DMA_Halt
- *
- * description: halt the current dma transaction on the specified
- * channel.
- * return DMASUCCESS if success, otherwise return DMACHNINVALID
- *
- * note: if the specified DMA channel is idle, nothing happens
- *************************************************************/
-static DMAStatus DMA_Halt( LOCATION, unsigned int eumbbar,unsigned int channel );
-
-/*************************************************************
- * function: DMA_Chn_Cnt
- *
- * description: set the DMA_MR(CC) bit for a given channel
- * that is in chaining mode.
- * return DMASUCCESS if successfule, otherwise return DMACHNINVALID
- *
- * note: if the given channel is not in chaining mode, nothing
- * happen.
- *
- *************************************************************/
-static DMAStatus DMA_Chn_Cnt( LOCATION, unsigned int eumbbar,unsigned int channel );
-
-/*********************** App. API ***************************
- * App. API are the APIs Kernel provides for the application
- * level program
- ************************************************************/
-/**************************************************************
- * function: DMA_Bld_Curr
- *
- * description: set current src, dest, byte count registers
- * according to the desp for a given channel
- *
- * if the given channel is busy, no change made,
- * return DMACHNBUSY.
- *
- * otherwise return DMASUCCESS.
- *
- * note:
- **************************************************************/
-static DMAStatus DMA_Bld_Curr( LOCATION,
- unsigned int eumbbar,
- unsigned int channel,
- DMA_CURR desp );
-
-/**************************************************************
- * function: DMA_Poke_Curr
- *
- * description: poke the current src, dest, byte count registers
- * for a given channel.
- *
- * return DMASUCCESS if no error otherwise return DMACHNERROR
- *
- * note: Due to the undeterministic parallelism, in chaining
- * mode, the value returned by this function shall
- * be taken as reference when the query is made rather
- * than the absolute snapshot when the value is returned.
- **************************************************************/
-static DMAStatus DMA_Poke_Curr( LOCATION,
- unsigned int eumbbar,
- unsigned int channel,
- DMA_CURR* desp );
-
-/**************************************************************
- * function: DMA_Bld_Desp
- *
- * description: set current descriptor address register
- * according to the desp for a given channel
- *
- * if the given channel is busy return DMACHNBUSY
- * and no change made, otherwise return DMASUCCESS.
- *
- * note:
- **************************************************************/
-static DMAStatus DMA_Bld_Desp( LOCATION host,
- unsigned int eumbbar,
- unsigned int channel,
- DMA_CDAR desp );
-
-/**************************************************************
- * function: DMA_Poke_Desp
- *
- * description: poke the current descriptor address register
- * for a given channel
- *
- * return DMASUCCESS if no error otherwise return
- * DMAINVALID
- *
- * note: Due to the undeterministic parallellism of DMA operation,
- * the value returned by this function shall be taken as
- * the most recently used descriptor when the last time
- * DMA starts a chaining mode operation.
- **************************************************************/
-static DMAStatus DMA_Poke_Desp( LOCATION,
- unsigned int eumbbar,
- unsigned int channel,
- DMA_CDAR *desp );
-
-#endif
diff --git a/cpu/mpc824x/drivers/dma/dma1.c b/cpu/mpc824x/drivers/dma/dma1.c
deleted file mode 100644
index 9c85267..0000000
--- a/cpu/mpc824x/drivers/dma/dma1.c
+++ /dev/null
@@ -1,801 +0,0 @@
-/************************************************************
- *
- * copyright @ Motorola, 1999
- *
- * App. API
- *
- * App. API are the APIs Kernel provides for the application
- * level program
- *
- ************************************************************/
-#include "dma_export.h"
-#include "dma.h"
-
-/* Define a macro to use an optional application-layer print function, if
- * one was passed to the library during initialization. If there was no
- * function pointer passed, this protects against referencing a NULL pointer.
- * Also define The global variable that holds the passed pointer.
- */
-#define PRINT if ( app_print ) app_print
-static int (*app_print)(char *,...);
-
-/* Set by call to get_eumbbar during DMA_Initialize.
- * This could be globally available to the library, but there is
- * an advantage to passing it as a parameter: it is already in a register
- * and doesn't have to be loaded from memory. Also, that is the way the
- * library was already implemented and I don't want to change it without
- * a more detailed analysis.
- * It is being set as a global variable during initialization to hide it from
- * the DINK application layer, because it is Kahlua-specific. I think that
- * get_eumbbar, load_runtime_reg, and store_runtime_reg should be defined in
- * a Kahlua-specific library dealing with the embedded utilities memory block.
- * Right now, get_eumbbar is defined in dink32/kahlua.s. The other two are
- * defined in dink32/drivers/i2c/i2c2.s, drivers/dma/dma2.s, etc.
- */
-static unsigned int Global_eumbbar = 0;
-extern unsigned int get_eumbbar();
-
-
-extern unsigned int load_runtime_reg( unsigned int eumbbar, unsigned int reg );
-#pragma Alias( load_runtime_reg, "load_runtime_reg" );
-
-extern void store_runtime_reg( unsigned int eumbbar, unsigned int reg, unsigned int val );
-#pragma Alias( store_runtime_reg, "store_runtime_reg" );
-
-unsigned int dma_reg_tb[][14] = {
- /* local DMA registers */
- {
- /* DMA_0_MR */ 0x00001100,
- /* DMA_0_SR */ 0x00001104,
- /* DMA_0_CDAR */ 0x00001108,
- /* DMA_0_SAR */ 0x00001110,
- /* DMA_0_DAR */ 0x00001118,
- /* DMA_0_BCR */ 0x00001120,
- /* DMA_0_NDAR */ 0x00001124,
- /* DMA_1_MR */ 0x00001200,
- /* DMA_1_SR */ 0x00001204,
- /* DMA_1_CDAR */ 0x00001208,
- /* DMA_1_SAR */ 0x00001210,
- /* DMA_1_DAR */ 0x00001218,
- /* DMA_1_BCR */ 0x00001220,
- /* DMA_1_NDAR */ 0x00001224,
- },
- /* remote DMA registers */
- {
- /* DMA_0_MR */ 0x00000100,
- /* DMA_0_SR */ 0x00000104,
- /* DMA_0_CDAR */ 0x00000108,
- /* DMA_0_SAR */ 0x00000110,
- /* DMA_0_DAR */ 0x00000118,
- /* DMA_0_BCR */ 0x00000120,
- /* DMA_0_NDAR */ 0x00000124,
- /* DMA_1_MR */ 0x00000200,
- /* DMA_1_SR */ 0x00000204,
- /* DMA_1_CDAR */ 0x00000208,
- /* DMA_1_SAR */ 0x00000210,
- /* DMA_1_DAR */ 0x00000218,
- /* DMA_1_BCR */ 0x00000220,
- /* DMA_1_NDAR */ 0x00000224,
- },
-};
-
-/* API functions */
-
-/* Initialize DMA unit with the following:
- * optional pointer to application layer print function
- *
- * These parameters may be added:
- * ???
- * Interrupt enables, modes, etc. are set for each transfer.
- *
- * This function must be called before DMA unit can be used.
- */
-extern
-DMA_Status DMA_Initialize( int (*p)(char *,...))
-{
- DMAStatus status;
- /* establish the pointer, if there is one, to the application's "printf" */
- app_print = p;
-
- /* If this is the first call, get the embedded utilities memory block
- * base address. I'm not sure what to do about error handling here:
- * if a non-zero value is returned, accept it.
- */
- if ( Global_eumbbar == 0)
- Global_eumbbar = get_eumbbar();
- if ( Global_eumbbar == 0)
- {
- PRINT( "DMA_Initialize: can't find EUMBBAR\n" );
- return DMA_ERROR;
- }
-
- return DMA_SUCCESS;
-}
-
-
-/* Perform the DMA transfer, only direct mode is currently implemented.
- * At this point, I think it would be better to define a different
- * function for chaining mode.
- * Also, I'm not sure if it is appropriate to have the "generic" API
- * accept snoop and int_steer parameters. The DINK user interface allows
- * them, so for now I'll leave them.
- *
- * int_steer controls DMA interrupt steering to PCI or local processor
- * type is the type of transfer: M2M, M2P, P2M, P2P
- * source is the source address of the data
- * dest is the destination address of the data
- * len is the length of data to transfer
- * channel is the DMA channel to use for the transfer
- * snoop is the snoop enable control
- */
-extern DMA_Status DMA_direct_transfer( DMA_INTERRUPT_STEER int_steer,
- DMA_TRANSFER_TYPE type,
- unsigned int source,
- unsigned int dest,
- unsigned int len,
- DMA_CHANNEL channel,
- DMA_SNOOP_MODE snoop)
-{
- DMA_MR md;
- DMA_CDAR cdar;
- /* it's inappropriate for curr to be a struct, but I'll leave it */
- DMA_CURR curr;
-
- DMAStatus stat;
-
- /* The rest of this code was moved from device.c test_dma to here.
- * It needs to be cleaned up and validated, but at least it is removed
- * from the application and API. Most of the mode is left hard coded.
- * This should be changed after the final API is defined and the user
- * application has a way to control the transfer.
- *
- */
-
- if ( DMA_Get_Mode( LOCAL, Global_eumbbar, channel, &md ) != DMASUCCESS )
- {
- return DMA_ERROR;
- }
-
- md.irqs = int_steer;
- md.pde = 0;
- md.dahts = 3; /* 8 - byte */
- md.sahts = 3; /* 8 - byte */
- md.dahe = 0;
- md.sahe = 0;
- md.prc = 0;
- /* if steering interrupts to local processor, use polling mode */
- if ( int_steer == DMA_INT_STEER_PCI )
- {
- md.eie = 1;
- md.eotie = 1;
- } else {
- md.eie = 0;
- md.eotie = 0;
- }
- md.dl = 0;
- md.ctm = 1; /* direct mode */
- md.cc = 0;
-
- /* validate the length range */
- if (len > 0x3ffffff )
- {
- PRINT( "dev DMA: length of transfer too large: %d\n", len );
- return DMA_ERROR;
- }
-
- /* inappropriate to use a struct, but leave as is for now */
- curr.src_addr = source;
- curr.dest_addr = dest;
- curr.byte_cnt = len;
-
- (void)DMA_Poke_Desp( LOCAL, Global_eumbbar, channel, &cdar );
- cdar.snen = snoop;
- cdar.ctt = type;
-
- if ( ( stat = DMA_Bld_Desp( LOCAL, Global_eumbbar, channel, cdar ))
- != DMASUCCESS ||
- ( stat = DMA_Bld_Curr( LOCAL, Global_eumbbar, channel, curr ))
- != DMASUCCESS ||
- ( stat = DMA_Set_Mode( LOCAL, Global_eumbbar, channel, md ))
- != DMASUCCESS ||
- ( stat = DMA_Start( LOCAL, Global_eumbbar, channel ))
- != DMASUCCESS )
- {
- if ( stat == DMACHNBUSY )
- {
- PRINT( "dev DMA: channel %d busy.\n", channel );
- }
- else
- {
- PRINT( "dev DMA: invalid channel request.\n", channel );
- }
-
- return DMA_ERROR;
- }
-
-/* Since we are interested at the DMA performace right now,
- we are going to do as less as possible to burden the
- 603e core.
-
- if you have epic enabled or don't care the return from
- DMA operation, you can just return SUCCESS.
-
- if you don't have epic enabled and care the DMA result,
- you can use the polling method below.
-
- Note: I'll attempt to activate the code for handling polling.
- */
-
-#if 0
- /* if steering interrupt to local processor, let it handle results */
- if ( int_steer == DMA_INT_STEER_LOCAL )
- {
- return DMA_SUCCESS;
- }
-
- /* polling since interrupt goes to PCI */
- do
- {
- stat = DMA_ISR( Global_eumbbar, channel, dma_error_func,
- dma_error_func, dma_error_func, dma_error_func );
- }
- while ( stat == DMANOEVENT );
-#endif
-
- return DMA_SUCCESS;
-}
-
-/* DMA library internal functions */
-
-/**
- * Note:
- *
- * In all following functions, the host (KAHLUA) processor has a
- * choice of accessing on board local DMA (LOCAL),
- * or DMA on a distributed KAHLUA (REMOTE). In either case,
- * the caller shall pass the configured embedded utility memory
- * block base address relative to the DMA. If LOCAL DMA is used,
- * this parameter shall be EUMBBAR, if REMOTE is used, the
- * parameter shall be the corresponding PCSRBAR.
- **/
-
-/**************************************************************
- * function: DMA_Get_Stat
- *
- * description: return the content of status register of
- * the given DMA channel
- *
- * if error, reserved0 field all 1s.
- **************************************************************/
-static
-DMAStatus DMA_Get_Stat( LOCATION host, unsigned int eumbbar, unsigned int channel, DMA_SR *stat )
-{
- unsigned int tmp;
-
- if ( channel != 0 && channel != 1 || stat == 0 )
- {
- return DMAINVALID;
- }
-
- tmp = load_runtime_reg( eumbbar, dma_reg_tb[host][channel*NUM_DMA_REG+DMA_SR_REG] );
-#ifdef DMADBG0
- PRINT( "%s(%d): %s DMA %d (0x%08x) stat = 0x%08x\n", __FILE__, __LINE__,
- ( host == LOCAL ? "local" : "remote" ), channel, dma_reg_tb[host][channel*NUM_DMA_REG+DMA_SR_REG], tmp );
-#endif
-
- stat->reserved0 = ( tmp & 0xffffff00 ) >> 8;
- stat->lme = ( tmp & 0x00000080 ) >> 7;
- stat->reserved1 = ( tmp & 0x00000060 ) >> 5;
- stat->pe = ( tmp & 0x00000010 ) >> 4;
- stat->reserved2 = ( tmp & 0x00000008 ) >> 3;
- stat->cb = ( tmp & 0x00000004 ) >> 2;
- stat->eosi = ( tmp & 0x00000002 ) >> 1;
- stat->eocai = ( tmp & 0x00000001 );
-
- return DMASUCCESS;
-}
-
-/**************************************************************
- * function: DMA_Get_Mode
- *
- * description: return the content of mode register of the
- * given DMA channel
- *
- * if error, return DMAINVALID, otherwise return
- * DMASUCCESS
- **************************************************************/
-static
-DMAStatus DMA_Get_Mode( LOCATION host, unsigned eumbbar, unsigned int channel, DMA_MR *mode )
-{
- unsigned int tmp;
- if ( channel != 0 && channel != 1 || mode == 0 )
- {
- return DMAINVALID;
- }
-
- tmp = load_runtime_reg( eumbbar, dma_reg_tb[host][channel*NUM_DMA_REG+DMA_MR_REG] );
-
-#ifdef DMADBG0
- PRINT( "%s(%d): %s DMA %d (0x%08x) mode = 0x%08x\n", __FILE__, __LINE__,
- ( host == LOCAL ? "local" : "remote" ), channel, dma_reg_tb[host][channel*NUM_DMA_REG+DMA_MR_REG], tmp );
-#endif
-
- mode->reserved0 = (tmp & 0xfff00000) >> 20;
- mode->irqs = (tmp & 0x00080000) >> 19;
- mode->pde = (tmp & 0x00040000) >> 18;
- mode->dahts = (tmp & 0x00030000) >> 16;
- mode->sahts = (tmp & 0x0000c000) >> 14;
- mode->dahe = (tmp & 0x00002000) >> 13;
- mode->sahe = (tmp & 0x00001000) >> 12;
- mode->prc = (tmp & 0x00000c00) >> 10;
- mode->reserved1 = (tmp & 0x00000200) >> 9;
- mode->eie = (tmp & 0x00000100) >> 8;
- mode->eotie = (tmp & 0x00000080) >> 7;
- mode->reserved2 = (tmp & 0x00000070) >> 4;
- mode->dl = (tmp & 0x00000008) >> 3;
- mode->ctm = (tmp & 0x00000004) >> 2;
- mode->cc = (tmp & 0x00000002) >> 1;
- mode->cs = (tmp & 0x00000001);
-
- return DMASUCCESS;
-}
-
-/**************************************************************
- * function: DMA_Set_Mode
- *
- * description: Set a new mode to a given DMA channel
- *
- * note: It is not a good idea of changing the DMA mode during
- * the middle of a transaction.
- **************************************************************/
-static
-DMAStatus DMA_Set_Mode( LOCATION host, unsigned eumbbar, unsigned int channel, DMA_MR mode )
-{
- unsigned int tmp;
- if ( channel != 0 && channel != 1 )
- {
- return DMAINVALID;
- }
-
- tmp = ( mode.reserved0 & 0xfff ) << 20;
- tmp |= ( ( mode.irqs & 0x1 ) << 19);
- tmp |= ( ( mode.pde & 0x1 ) << 18 );
- tmp |= ( ( mode.dahts & 0x3 ) << 16 );
- tmp |= ( ( mode.sahts & 0x3 ) << 14 );
- tmp |= ( ( mode.dahe & 0x1 ) << 13 );
- tmp |= ( ( mode.sahe & 0x1 ) << 12 );
- tmp |= ( ( mode.prc & 0x3 ) << 10 );
- tmp |= ( ( mode.reserved1 & 0x1 ) << 9 );
- tmp |= ( ( mode.eie & 0x1 ) << 8 );
- tmp |= ( ( mode.eotie & 0x1 ) << 7 );
- tmp |= ( ( mode.reserved2 & 0x7 ) << 4 );
- tmp |= ( ( mode.dl & 0x1 ) << 3 );
- tmp |= ( ( mode.ctm & 0x1 ) << 2 );
- tmp |= ( ( mode.cc & 0x1 ) << 1 ) ;
- tmp |= ( mode.cs & 0x1 );
-
- store_runtime_reg( eumbbar, dma_reg_tb[host][channel*NUM_DMA_REG + DMA_MR_REG], tmp );
- return DMASUCCESS;
-}
-
-/************************************************************
- * function: DMA_Start
- *
- * description: start a given DMA channel transaction
- * return DMASUCCESS if success otherwise return
- * DMAStatus value
- *
- * note: this function will clear DMA_MR(CC) first, then
- * set DMA_MR(CC).
- ***********************************************************/
-static
-DMAStatus DMA_Start( LOCATION host, unsigned int eumbbar, unsigned int channel )
-{
- DMA_SR stat;
- unsigned int mode;
-
- if ( channel != 0 && channel != 1 )
- {
- return DMAINVALID;
- }
-
- if ( DMA_Get_Stat( host, eumbbar, channel, &stat ) != DMASUCCESS )
- {
- return DMAINVALID;
- }
-
- if ( stat.cb == 1 )
- {
- /* DMA is not free */
- return DMACHNBUSY;
- }
-
- mode = load_runtime_reg( eumbbar, dma_reg_tb[host][channel*NUM_DMA_REG + DMA_MR_REG] );
- /* clear DMA_MR(CS) */
- mode &= 0xfffffffe;
- store_runtime_reg( eumbbar, dma_reg_tb[host][channel*NUM_DMA_REG + DMA_MR_REG], mode );
-
- /* set DMA_MR(CS) */
- mode |= CS;
- store_runtime_reg( eumbbar, dma_reg_tb[host][channel*NUM_DMA_REG + DMA_MR_REG], mode );
- return DMASUCCESS;
-}
-
-/***********************************************************
- * function: DMA_Halt
- *
- * description: halt the current dma transaction on the specified
- * channel.
- * return DMASUCCESS if success otherwise return DMAINVALID
- *
- * note: if the specified DMA channel is idle, nothing happens
- *************************************************************/
-static
-DMAStatus DMA_Halt( LOCATION host, unsigned int eumbbar, unsigned int channel )
-{
- unsigned int mode;
- if ( channel != 0 && channel != 1 )
- {
- return DMAINVALID;
- }
-
- mode = load_runtime_reg( eumbbar, dma_reg_tb[host][channel*NUM_DMA_REG + DMA_MR_REG]);
-
- /* clear DMA_MR(CS) */
- mode &= 0xfffffffe;
- store_runtime_reg(eumbbar, dma_reg_tb[host][channel*NUM_DMA_REG + DMA_MR_REG], mode );
- return DMASUCCESS;
-}
-
-/*************************************************************
- * function: DMA_Chn_Cnt
- *
- * description: set the DMA_MR(CC) bit for a given channel
- * that is in chaining mode.
- * return DMASUCCESS if successfule, otherwise return
- * DMAINVALID.
- *
- * note: if the given channel is not in chaining mode, nothing
- * happen.
- *
- *************************************************************/
-static
-DMAStatus DMA_Chn_Cnt( LOCATION host, unsigned int eumbbar, unsigned int channel )
-{
- DMA_MR mode;
- if ( channel != 0 && channel != 1 )
- {
- return DMAINVALID;
- }
-
- if ( DMA_Get_Mode( host, eumbbar, channel, &mode ) != DMASUCCESS )
- {
- return DMAINVALID;
- }
-
- if ( mode.ctm == 0 )
- {
- /* either illegal mode or not chaining mode */
- return DMAINVALID;
- }
-
- mode.cc = 1;
- return DMA_Set_Mode( host, eumbbar, channel, mode );
-}
-
-/**************************************************************
- * function: DMA_Bld_Desp
- *
- * description: set current descriptor address register
- * according to the desp for a given channel
- *
- * if the given channel is busy return DMACHNBUSY
- * and no change made, otherwise return DMASUCCESS.
- *
- * note:
- **************************************************************/
-static
-DMAStatus DMA_Bld_Desp( LOCATION host,
- unsigned int eumbbar,
- unsigned int channel,
- DMA_CDAR desp )
-{
- DMA_SR status;
- unsigned int temp;
-
- if ( channel != 0 && channel != 1 )
- {
- /* channel number out of range */
- return DMAINVALID;
- }
-
- if ( DMA_Get_Stat( host, eumbbar, channel, &status ) != DMASUCCESS )
- {
- return DMAINVALID;
- }
-
- if ( status.cb == 1 )
- {
- /* channel busy */
- return DMACHNBUSY;
- }
-
- temp = ( desp.cda & 0x7ffffff ) << 5;
- temp |= (( desp.snen & 0x1 ) << 4 );
- temp |= (( desp.eosie & 0x1 ) << 3 );
- temp |= (( desp.ctt & 0x3 ) << 1 );
- temp |= ( desp.eotd & 0x1 );
-
- store_runtime_reg( eumbbar, dma_reg_tb[host][channel*NUM_DMA_REG+DMA_CDAR_REG], temp );
-
-#ifdef DMADBG0
- PRINT( "%s(%d): %s DMA %d (0x%08x) cdar := 0x%08x\n", __FILE__, __LINE__,
- ( host == LOCAL ? "local" : "remote" ), channel, dma_reg_tb[host][channel*NUM_DMA_REG+DMA_CDAR_REG], temp );
-#endif
-
- return DMASUCCESS;
-}
-
-/**************************************************************
- * function: DMA_Poke_Desp
- *
- * description: poke the current descriptor address register
- * for a given channel
- *
- * return DMASUCCESS if no error
- *
- * note: Due to the undeterministic parallellism of DMA operation,
- * the value returned by this function shall be taken as
- * the most recently used descriptor when the last time
- * DMA starts a chaining mode operation.
- **************************************************************/
-static
-DMAStatus DMA_Poke_Desp( LOCATION host,
- unsigned int eumbbar,
- unsigned int channel,
- DMA_CDAR *desp )
-{
- unsigned int cdar;
- if ( channel != 0 && channel != 1 || desp == 0 )
- {
- return DMAINVALID;
- }
-
- cdar = load_runtime_reg( eumbbar, dma_reg_tb[host][channel*NUM_DMA_REG+DMA_CDAR_REG] );
-
-#ifdef DMADBG0
- PRINT( "%s(%d): %s DMA %d (0x%08x) cdar : 0x%08x\n", __FILE__, __LINE__,
- ( host == LOCAL ? "local" : "remote" ), channel, dma_reg_tb[host][channel*NUM_DMA_REG+DMA_CDAR_REG], cdar );
-#endif
-
-
- desp->cda = ( cdar & 0xffffffe0 ) >> 5;
- desp->snen = ( cdar & 0x00000010 ) >> 4;
- desp->eosie = ( cdar & 0x00000008 ) >> 3;
- desp->ctt = ( cdar & 0x00000006 ) >> 1;
- desp->eotd = ( cdar & 0x00000001 );
-
- return DMASUCCESS;
-}
-
-/**************************************************************
- * function: DMA_Bld_Curr
- *
- * description: set current src, dest, byte count registers
- * according to the desp for a given channel
- * return DMASUCCESS if no error.
- *
- * note:
- **************************************************************/
-static
-DMAStatus DMA_Bld_Curr( LOCATION host,
- unsigned int eumbbar,
- unsigned int channel,
- DMA_CURR desp )
-{
- DMA_SR status;
- if ( channel != 0 && channel != 1 )
- {
- /* channel number out of range */
- return DMAINVALID;
- }
-
- if ( DMA_Get_Stat( host, eumbbar, channel, &status ) != DMASUCCESS )
- {
- return DMAINVALID;
- }
-
- if ( status.cb == 1 )
- {
- /* channel busy */
- return DMACHNBUSY;
- }
-
- desp.byte_cnt &= 0x03ffffff; /* upper 6-bits are 0s */
-
- store_runtime_reg( eumbbar, dma_reg_tb[host][channel*NUM_DMA_REG+DMA_SAR_REG], desp.src_addr );
-#ifdef DMADBG0
- PRINT( "%s(%d): %s DMA %d (0x%08x) src := 0x%08x\n", __FILE__, __LINE__,
- ( host == LOCAL ? "local" : "remote" ), channel, dma_reg_tb[host][channel*NUM_DMA_REG+DMA_CDAR_REG], desp.src_addr );
-#endif
-
- store_runtime_reg( eumbbar, dma_reg_tb[host][channel*NUM_DMA_REG+DMA_DAR_REG], desp.dest_addr );
-#ifdef DMADBG0
- PRINT( "%s(%d): %s DMA %d (0x%08x) dest := 0x%08x\n", __FILE__, __LINE__,
- ( host == LOCAL ? "local" : "remote" ), channel, dma_reg_tb[host][channel*NUM_DMA_REG+DMA_CDAR_REG], desp.dest_addr );
-#endif
-
- store_runtime_reg( eumbbar, dma_reg_tb[host][channel*NUM_DMA_REG+DMA_BCR_REG], desp.byte_cnt );
-#ifdef DMADBG0
- PRINT( "%s(%d): %s DMA %d (0x%08x) count := 0x%08x\n", __FILE__, __LINE__,
- ( host == LOCAL ? "local" : "remote" ), channel, dma_reg_tb[host][channel*NUM_DMA_REG+DMA_CDAR_REG], desp.byte_cnt );
-#endif
-
-
- return DMASUCCESS;
-
-}
-
-/**************************************************************
- * function: DMA_Poke_Curr
- *
- * description: poke the current src, dest, byte count registers
- * for a given channel.
- *
- * return DMASUCCESS if no error
- *
- * note: Due to the undeterministic parallelism, in chaining
- * mode, the value returned by this function shall
- * be taken as reference when the query is made rather
- * than the absolute snapshot when the value is returned.
- **************************************************************/
-static
-DMAStatus DMA_Poke_Curr( LOCATION host,
- unsigned int eumbbar,
- unsigned int channel,
- DMA_CURR* desp )
-{
- if ( channel != 0 && channel != 1 || desp == 0 )
- {
- return DMAINVALID;
- }
-
- desp->src_addr = load_runtime_reg( eumbbar, dma_reg_tb[host][channel*NUM_DMA_REG+DMA_SAR_REG] );
-#ifdef DMADBG0
- PRINT( "%s(%d): %s DMA %d (0x%08x) src : 0x%08x\n", __FILE__, __LINE__,
- ( host == LOCAL ? "local" : "remote" ), channel, dma_reg_tb[host][channel*NUM_DMA_REG+DMA_CDAR_REG], desp->src_addr );
-#endif
-
- desp->dest_addr = load_runtime_reg( eumbbar, dma_reg_tb[host][channel*NUM_DMA_REG+DMA_DAR_REG] );
-#ifdef DMADBG0
- PRINT( "%s(%d): %s DMA %d (0x%08x) dest : 0x%08x\n", __FILE__, __LINE__,
- ( host == LOCAL ? "local" : "remote" ), channel, dma_reg_tb[host][channel*NUM_DMA_REG+DMA_CDAR_REG], desp->dest_addr );
-#endif
-
- desp->byte_cnt = load_runtime_reg( eumbbar, dma_reg_tb[host][channel*NUM_DMA_REG+DMA_BCR_REG] );
-#ifdef DMADBG0
- PRINT( "%s(%d): %s DMA %d (0x%08x) count : 0x%08x\n", __FILE__, __LINE__,
- ( host == LOCAL ? "local" : "remote" ), channel, dma_reg_tb[host][channel*NUM_DMA_REG+DMA_CDAR_REG], desp->byte_cnt );
-#endif
-
-
- return DMASUCCESS;
-}
-
-/*****************************************************************
- * function: dma_error_func
- *
- * description: display the error information
- *
- * note: This seems like a highly convoluted way to handle messages,
- * but I'll leave it as it was in device.c when I moved it into the
- * DMA library source.
- ****************************************************************/
-static
-DMAStatus dma_error_func( unsigned int eumbbar, unsigned int chn, DMAStatus err)
-{
- unsigned char *msg[] =
- {
- "Local Memory Error",
- "PCI Error",
- "Channel Busy",
- "End-of-Segment Interrupt",
- "End-of-Chain/Direct Interrupt",
- };
-
- if ( err >= DMALMERROR && err <= DMAEOCAINT )
- {
- PRINT( "DMA Status: channel %d %s\n", chn, msg[err-DMASUCCESS-1] );
- }
-
- return err;
-
-}
-
-/*************************************************************
- * function: DMA_ISR
- *
- * description: DMA interrupt service routine
- * return DMAStatus value based on
- * the status
- *
- *************************************************************/
-static
-DMAStatus DMA_ISR( unsigned int eumbbar,
- unsigned int channel,
- DMAStatus (*lme_func)( unsigned int, unsigned int, DMAStatus ),
- DMAStatus (*pe_func) ( unsigned int, unsigned int, DMAStatus ),
- DMAStatus (*eosi_func)( unsigned int, unsigned int, DMAStatus ),
- DMAStatus (*eocai_func)(unsigned int, unsigned int, DMAStatus ))
-{
-
- DMA_SR stat;
- DMAStatus rval = DMANOEVENT;
- unsigned int temp;
-
- if ( channel != 0 && channel != 1 )
- {
- return DMAINVALID;
- }
-
- if ( DMA_Get_Stat( LOCAL, eumbbar, channel, &stat ) != DMASUCCESS )
- {
- return DMAINVALID;
- }
-
- if ( stat.lme == 1 )
- {
- /* local memory error */
- rval = DMALMERROR;
- if ( lme_func != 0 )
- {
- rval = (*lme_func)(eumbbar, channel, DMALMERROR );
- }
-
- }
- else if ( stat.pe == 1 )
- {
- /* PCI error */
- rval = DMAPERROR;
- if ( pe_func != 0 )
- {
- rval = (*pe_func)(eumbbar, channel, DMAPERROR );
- }
-
- }
- else if ( stat.eosi == 1 )
- {
- /* end-of-segment interrupt */
- rval = DMAEOSINT;
- if ( eosi_func != 0 )
- {
- rval = (*eosi_func)(eumbbar, channel, DMAEOSINT );
- }
- }
- else
- {
- /* End-of-chain/direct interrupt */
- rval = DMAEOCAINT;
- if ( eocai_func != 0 )
- {
- rval = (*eocai_func)(eumbbar, channel, DMAEOCAINT );
- }
- }
-
- temp = ( stat.reserved0 & 0xffffff ) << 8;
- temp |= ( ( stat.lme & 0x1 ) << 7 ); /* write one to clear */
- temp |= ( ( stat.reserved1 & 0x3 ) << 5 );
- temp |= ( ( stat.pe & 0x1 ) << 4 ); /* write one to clear */
- temp |= ( ( stat.reserved2 & 0x1 ) << 3 );
- temp |= ( ( stat.cb & 0x1 ) << 2 ); /* write one to clear */
- temp |= ( ( stat.eosi & 0x1 ) << 1 ); /* write one to clear */
- temp |= ( stat.eocai & 0x1 ); /* write one to clear */
-
- store_runtime_reg( eumbbar, dma_reg_tb[LOCAL][channel*NUM_DMA_REG + DMA_SR_REG], temp );
-
-#ifdef DMADBG0
- PRINT( "%s(%d): DMA channel %d SR := 0x%08x\n", __FILE__, __LINE__, channel, temp );
-#endif
-
- return rval;
-}
diff --git a/cpu/mpc824x/drivers/dma/dma2.S b/cpu/mpc824x/drivers/dma/dma2.S
deleted file mode 100644
index ccbc226..0000000
--- a/cpu/mpc824x/drivers/dma/dma2.S
+++ /dev/null
@@ -1,42 +0,0 @@
-/**************************************
- *
- * copyright @ Motorola, 1999
- *
- **************************************/
-
-/**********************************************************
- * function: load_runtime_reg
- *
- * input: r3 - value of eumbbar
- * r4 - register offset in embedded utility space
- *
- * output: r3 - register content
- **********************************************************/
- .text
- .align 2
- .global load_runtime_reg
-
-load_runtime_reg:
-
- lwbrx r3,r4,r3
- sync
-
- bclr 20, 0
-
-/****************************************************************
- * function: store_runtime_reg
- *
- * input: r3 - value of eumbbar
- * r4 - register offset in embedded utility space
- * r5 - new value to be stored
- *
- ****************************************************************/
- .text
- .align 2
- .global store_runtime_reg
-store_runtime_reg:
-
- stwbrx r5, r4, r3
- sync
-
- bclr 20,0
diff --git a/cpu/mpc824x/drivers/dma/dma_export.h b/cpu/mpc824x/drivers/dma/dma_export.h
deleted file mode 100644
index 471e488..0000000
--- a/cpu/mpc824x/drivers/dma/dma_export.h
+++ /dev/null
@@ -1,100 +0,0 @@
-#ifndef DMA_EXPORT_H
-#define DMA_EXPORT_H
-
-/****************************************************
- * $Id:
- *
- * Copyright Motorola 1999
- *
- * $Log:
- *
- ****************************************************/
-
-/* These are the defined return values for the DMA_* functions.
- * Any non-zero value indicates failure. Failure modes can be added for
- * more detailed error reporting.
- */
-typedef enum _dma_status
-{
- DMA_SUCCESS = 0,
- DMA_ERROR,
-} DMA_Status;
-
-/* These are the defined channel transfer types. */
-typedef enum _dma_transfer_types
-{
- DMA_M2M = 0, /* local memory to local memory */
- DMA_M2P = 1, /* local memory to PCI */
- DMA_P2M = 2, /* PCI to local memory */
- DMA_P2P = 3, /* PCI to PCI */
-} DMA_TRANSFER_TYPE;
-
-typedef enum _dma_interrupt_steer
-{
- DMA_INT_STEER_LOCAL = 0, /* steer DMA int to local processor */
- DMA_INT_STEER_PCI = 1, /* steer DMA int to PCI bus through INTA_ */
-} DMA_INTERRUPT_STEER;
-
-typedef enum _dma_channel
-{
- DMA_CHN_0 = 0, /* kahlua has two dma channels: 0 and 1 */
- DMA_CHN_1 = 1,
-} DMA_CHANNEL;
-
-typedef enum _dma_snoop_mode
-{
- DMA_SNOOP_DISABLE = 0,
- DMA_SNOOP_ENABLE = 1,
-} DMA_SNOOP_MODE;
-
-/******************** App. API ********************
- * The application API is for user level application
- * to use the functionality provided by DMA driver.
- * This is a "generic" DMA interface, it should contain
- * nothing specific to the Kahlua implementation.
- * Only the generic functions are exported by the library.
- *
- * Note: Its App.s responsibility to swap the data
- * byte. In our API, we currently transfer whatever
- * we are given - Big/Little Endian. This could
- * become part of the DMA config, though.
- **************************************************/
-
-
-/* Initialize DMA unit with the following:
- * optional pointer to application layer print function
- *
- * These parameters may be added:
- * ???
- * Interrupt enables, modes, etc. are set for each transfer.
- *
- * This function must be called before DMA unit can be used.
- */
-extern DMA_Status DMA_Initialize(
- int (*app_print_function)(char *,...)); /* pointer to optional "printf"
- * provided by application
- */
-
-/* Perform the DMA transfer, only direct mode is currently implemented.
- * At this point, I think it would be better to define a different
- * function for chaining mode.
- * Also, I'm not sure if it is appropriate to have the "generic" API
- * accept snoop and int_steer parameters. The DINK user interface allows
- * them, so for now I'll leave them.
- *
- * int_steer controls DMA interrupt steering to PCI or local processor
- * type is the type of transfer: M2M, M2P, P2M, P2P
- * source is the source address of the data
- * dest is the destination address of the data
- * len is the length of data to transfer
- * channel is the DMA channel to use for the transfer
- * snoop is the snoop enable control
- */
-extern DMA_Status DMA_direct_transfer( DMA_INTERRUPT_STEER int_steer,
- DMA_TRANSFER_TYPE type,
- unsigned int source,
- unsigned int dest,
- unsigned int len,
- DMA_CHANNEL channel,
- DMA_SNOOP_MODE snoop);
-#endif
diff --git a/cpu/mpc824x/drivers/dma_export.h b/cpu/mpc824x/drivers/dma_export.h
deleted file mode 100644
index 471e488..0000000
--- a/cpu/mpc824x/drivers/dma_export.h
+++ /dev/null
@@ -1,100 +0,0 @@
-#ifndef DMA_EXPORT_H
-#define DMA_EXPORT_H
-
-/****************************************************
- * $Id:
- *
- * Copyright Motorola 1999
- *
- * $Log:
- *
- ****************************************************/
-
-/* These are the defined return values for the DMA_* functions.
- * Any non-zero value indicates failure. Failure modes can be added for
- * more detailed error reporting.
- */
-typedef enum _dma_status
-{
- DMA_SUCCESS = 0,
- DMA_ERROR,
-} DMA_Status;
-
-/* These are the defined channel transfer types. */
-typedef enum _dma_transfer_types
-{
- DMA_M2M = 0, /* local memory to local memory */
- DMA_M2P = 1, /* local memory to PCI */
- DMA_P2M = 2, /* PCI to local memory */
- DMA_P2P = 3, /* PCI to PCI */
-} DMA_TRANSFER_TYPE;
-
-typedef enum _dma_interrupt_steer
-{
- DMA_INT_STEER_LOCAL = 0, /* steer DMA int to local processor */
- DMA_INT_STEER_PCI = 1, /* steer DMA int to PCI bus through INTA_ */
-} DMA_INTERRUPT_STEER;
-
-typedef enum _dma_channel
-{
- DMA_CHN_0 = 0, /* kahlua has two dma channels: 0 and 1 */
- DMA_CHN_1 = 1,
-} DMA_CHANNEL;
-
-typedef enum _dma_snoop_mode
-{
- DMA_SNOOP_DISABLE = 0,
- DMA_SNOOP_ENABLE = 1,
-} DMA_SNOOP_MODE;
-
-/******************** App. API ********************
- * The application API is for user level application
- * to use the functionality provided by DMA driver.
- * This is a "generic" DMA interface, it should contain
- * nothing specific to the Kahlua implementation.
- * Only the generic functions are exported by the library.
- *
- * Note: Its App.s responsibility to swap the data
- * byte. In our API, we currently transfer whatever
- * we are given - Big/Little Endian. This could
- * become part of the DMA config, though.
- **************************************************/
-
-
-/* Initialize DMA unit with the following:
- * optional pointer to application layer print function
- *
- * These parameters may be added:
- * ???
- * Interrupt enables, modes, etc. are set for each transfer.
- *
- * This function must be called before DMA unit can be used.
- */
-extern DMA_Status DMA_Initialize(
- int (*app_print_function)(char *,...)); /* pointer to optional "printf"
- * provided by application
- */
-
-/* Perform the DMA transfer, only direct mode is currently implemented.
- * At this point, I think it would be better to define a different
- * function for chaining mode.
- * Also, I'm not sure if it is appropriate to have the "generic" API
- * accept snoop and int_steer parameters. The DINK user interface allows
- * them, so for now I'll leave them.
- *
- * int_steer controls DMA interrupt steering to PCI or local processor
- * type is the type of transfer: M2M, M2P, P2M, P2P
- * source is the source address of the data
- * dest is the destination address of the data
- * len is the length of data to transfer
- * channel is the DMA channel to use for the transfer
- * snoop is the snoop enable control
- */
-extern DMA_Status DMA_direct_transfer( DMA_INTERRUPT_STEER int_steer,
- DMA_TRANSFER_TYPE type,
- unsigned int source,
- unsigned int dest,
- unsigned int len,
- DMA_CHANNEL channel,
- DMA_SNOOP_MODE snoop);
-#endif
diff --git a/cpu/mpc824x/drivers/i2o.h b/cpu/mpc824x/drivers/i2o.h
deleted file mode 100644
index c47253d..0000000
--- a/cpu/mpc824x/drivers/i2o.h
+++ /dev/null
@@ -1,344 +0,0 @@
-#ifndef I2O_H
-#define I2O_H
-/*********************************************************
- *
- * copyright @ Motorola, 1999
- *********************************************************/
-
-#define I2O_REG_OFFSET 0x0004
-
-#define PCI_CFG_CLA 0x0B
-#define PCI_CFG_SCL 0x0A
-#define PCI_CFG_PIC 0x09
-
-#define I2O_IMR0 0x0050
-#define I2O_IMR1 0x0054
-#define I2O_OMR0 0x0058
-#define I2O_OMR1 0x005C
-
-#define I2O_ODBR 0x0060
-#define I2O_IDBR 0x0068
-
-#define I2O_OMISR 0x0030
-#define I2O_OMIMR 0x0034
-#define I2O_IMISR 0x0100
-#define I2O_IMIMR 0x0104
-
-/* accessable to PCI master but local processor */
-#define I2O_IFQPR 0x0040
-#define I2O_OFQPR 0x0044
-
-/* accessable to local processor */
-#define I2O_IFHPR 0x0120
-#define I2O_IFTPR 0x0128
-#define I2O_IPHPR 0x0130
-#define I2O_IPTPR 0x0138
-#define I2O_OFHPR 0x0140
-#define I2O_OFTPR 0x0148
-#define I2O_OPHPR 0x0150
-#define I2O_OPTPR 0x0158
-#define I2O_MUCR 0x0164
-#define I2O_QBAR 0x0170
-
-#define I2O_NUM_MSG 2
-
-typedef enum _i2o_status
-{
- I2OSUCCESS = 0,
- I2OINVALID,
- I2OMSGINVALID,
- I2ODBINVALID,
- I2OQUEINVALID,
- I2OQUEEMPTY,
- I2OQUEFULL,
- I2ONOEVENT,
-} I2OSTATUS;
-
-typedef enum _queue_size
-{
- QSIZE_4K = 0x02,
- QSIZE_8K = 0x04,
- QSIZE_16K = 0x08,
- QSIZE_32K = 0x10,
- QSIZe_64K = 0x20,
-} QUEUE_SIZE;
-
-typedef enum _location
-{
- LOCAL = 0, /* used by local processor to access its own on board device,
- local processor's eumbbar is required */
- REMOTE, /* used by PCI master to access the devices on its PCI device,
- device's pcsrbar is required */
-} LOCATION;
-
-/* door bell */
-typedef enum _i2o_in_db
-{
- IN_DB = 1,
- MC, /* machine check */
-} I2O_IN_DB;
-
-/* I2O PCI configuration identification */
-typedef struct _i2o_iop
-{
- unsigned int base_class : 8;
- unsigned int sub_class : 8;
- unsigned int prg_code : 8;
-} I2OIOP;
-
-/* I2O Outbound Message Interrupt Status Register */
-typedef struct _i2o_om_stat
-{
- unsigned int rsvd0 : 26;
- unsigned int opqi : 1;
- unsigned int rsvd1 : 1;
- unsigned int odi : 1;
- unsigned int rsvd2 : 1;
- unsigned int om1i : 1;
- unsigned int om0i : 1;
-} I2OOMSTAT;
-
-/* I2O inbound Message Interrupt Status Register */
-typedef struct _i2o_im_stat
-{
- unsigned int rsvd0 : 23;
- unsigned int ofoi : 1;
- unsigned int ipoi : 1;
- unsigned int rsvd1 : 1;
- unsigned int ipqi : 1;
- unsigned int mci : 1;
- unsigned int idi : 1;
- unsigned int rsvd2 : 1;
- unsigned int im1i : 1;
- unsigned int im0i : 1;
-} I2OIMSTAT;
-
-/**
- Enable the interrupt associated with in/out bound msg
-
- Inbound message interrupt generated by PCI master and serviced by local processor
- local processor needs to enable its inbound interrupts it wants to handle (LOCAL)
-
- Outbound message interrupt generated by local processor and serviced by PCI master
- PCI master needs to enable the devices' outbound interrupts it wants to handle (REMOTE)
- **/
-extern I2OSTATUS I2OMsgEnable( LOCATION, /* REMOTE/LOCAL */
- unsigned int base, /* pcsrbar/eumbbar */
- unsigned char n ); /* b'1' - msg 0
- * b'10'- msg 1
- * b'11'- both
- */
-
-/**
- Disable the interrupt associated with in/out bound msg
-
- local processor needs to disable its inbound interrupts it is not interested (LOCAL)
-
- PCI master needs to disable outbound interrupts of devices it is not interested (REMOTE)
- **/
-extern I2OSTATUS I2OMsgDisable( LOCATION, /* REMOTE/LOCAL */
- unsigned int base, /* pcsrbar/eumbbar */
- unsigned char n ); /* b'1' - msg 0
- * b'10'- msg 1
- * b'11'- both
- */
-
-/**
- Read the msg register either from local inbound msg 0/1,
- or an outbound msg 0/1 of devices.
-
- If it is not local, pcsrbar must be passed to the function.
- Otherwise eumbbar is passed.
-
- If it is remote, outbound msg of the device is read.
- Otherwise local inbound msg is read.
- **/
-extern I2OSTATUS I2OMsgGet ( LOCATION, /* REMOTE/LOCAL */
- unsigned int base, /*pcsrbar/eumbbar */
- unsigned int n, /* 0 or 1 */
- unsigned int *msg );
-
-/**
- Write to nth Msg register either on local outbound msg 0/1,
- or aninbound msg 0/1 of devices
-
- If it is not local, pcsrbar must be passed to the function.
- Otherwise eumbbar is passed.
-
- If it is remote, inbound msg on the device is written.
- Otherwise local outbound msg is written.
- **/
-extern I2OSTATUS I2OMsgPost( LOCATION, /* REMOTE/LOCAL */
- unsigned int base, /*pcsrbar/eumbbar */
- unsigned int n, /* 0 or 1 */
- unsigned int msg );
-
-/**
- Enable the In/Out DoorBell Interrupt
-
- InDoorBell interrupt is generated by PCI master and serviced by local processor
- local processor needs to enable its inbound doorbell interrupts it wants to handle
-
- OutDoorbell interrupt is generated by local processor and serviced by PCI master
- PCI master needs to enable outbound doorbell interrupts of the devices it wants to handle
- **/
-extern I2OSTATUS I2ODBEnable( LOCATION, /* REMOTE/LOCAL */
- unsigned int base, /* pcsrbar/eumbbar */
- unsigned int in_db );/* when LOCAL, I2O_IN_DB, MC, I2O_IN_DB|MC */
-
-/**
- Disable the In/Out DoorBell Interrupt
-
- local processor needs to disable its inbound doorbell interrupts it is not interested
-
- PCI master needs to disable outbound doorbell interrupts of devices it is not interested
-
- **/
-extern I2OSTATUS I2ODBDisable( LOCATION, /* REMOTE/LOCAL */
- unsigned int base, /* pcsrbar/eumbbar */
- unsigned int in_db ); /* when LOCAL, I2O_IN_DB, MC, I2O_IN_DB|MC */
-
-/**
- Read a local indoorbell register, or an outdoorbell of devices.
- Reading a doorbell register, the register will be cleared.
-
- If it is not local, pcsrbar must be passed to the function.
- Otherwise eumbbar is passed.
-
- If it is remote, outdoorbell register on the device is read.
- Otherwise local in doorbell is read
- **/
-extern unsigned int I2ODBGet( LOCATION, /* REMOTE/LOCAL */
- unsigned int base); /* pcsrbar/eumbbar */
-
-/**
- Write to a local outdoorbell register, or an indoorbell register of devices.
-
- If it is not local, pcsrbar must be passed to the function.
- Otherwise eumbbar is passed.
-
- If it is remote, in doorbell register on the device is written.
- Otherwise local out doorbell is written
- **/
-extern void I2ODBPost( LOCATION, /* REMOTE/LOCAL */
- unsigned int base, /* pcsrbar/eumbbar */
- unsigned int msg ); /* in / out */
-
-/**
- Read the outbound msg unit interrupt status of devices. Reading an interrupt status register,
- the register will be cleared.
-
- The outbound interrupt status is AND with the outbound
- interrupt mask. The result is returned.
-
- PCI master must pass the pcsrbar to the function.
- **/
-extern I2OSTATUS I2OOutMsgStatGet( unsigned int pcsrbar, I2OOMSTAT * );
-
-/**
- Read the inbound msg unit interrupt status. Reading an interrupt status register,
- the register will be cleared.
-
- The inbound interrupt status is AND with the inbound
- interrupt mask. The result is returned.
-
- Local process must pass its eumbbar to the function.
-**/
-extern I2OSTATUS I2OInMsgStatGet( unsigned int eumbbar, I2OIMSTAT * );
-
-/**
- Configure the I2O FIFO, including QBAR, IFHPR/IFTPR,IPHPR/IPTPR,OFHPR/OFTPR, OPHPR/OPTPR,
- MUCR.
- **/
-extern I2OSTATUS I2OFIFOInit( unsigned int eumbbar,
- QUEUE_SIZE,
- unsigned int qba);/* queue base address that must be aligned at 1M */
-/**
- Enable the circular queue
- **/
-extern I2OSTATUS I2OFIFOEnable( unsigned int eumbbar );
-
-/**
- Disable the circular queue
- **/
-extern void I2OFIFODisable( unsigned int eumbbar );
-
-/**
- Enable the circular queue interrupt
- PCI master enables outbound FIFO interrupt of device
- Device enables its inbound FIFO interrupt
- **/
-extern void I2OFIFOIntEnable( LOCATION, unsigned int base );
-
-/**
- Disable the circular queue interrupt
- PCI master disables outbound FIFO interrupt of device
- Device disables its inbound FIFO interrupt
- **/
-extern void I2OFIFOIntDisable( LOCATION, unsigned int base );
-
-/**
- Enable the circular queue overflow interrupt
- **/
-extern void I2OFIFOOverflowIntEnable( unsigned int eumbbar );
-
-/**
- Disable the circular queue overflow interrupt
- **/
-extern void I2OFIFOOverflowIntDisable( unsigned int eumbbar );
-
-/**
- Allocate a free msg frame from free FIFO.
-
- PCI Master allocates a free msg frame through inbound queue port of device(IFQPR)
- while local processor allocates a free msg frame from outbound free queue(OFTPR)
-
- Unless both free queues are initialized, allocating a free MF will return 0xffffffff
- **/
-extern I2OSTATUS I2OFIFOAlloc( LOCATION,
- unsigned int base,
- void **pMsg);
-/**
- Free a used msg frame back to free queue
- PCI Master frees a MFA through outbound queue port of device(OFQPR)
- while local processor frees a MFA into its inbound free queue(IFHPR)
-
- Used msg frame does not need to be recycled in the order they
- read
-
- This function has to be called by PCI master to initialize Inbound free queue
- and by device to initialize Outbound free queue before I2OFIFOAlloc can be used.
- **/
-extern I2OSTATUS I2OFIFOFree( LOCATION,
- unsigned int base,
- void *pMsg );
-
-/**
- Post a msg into FIFO
- PCI Master posts a msg through inbound queue port of device(IFQPR)
- while local processor post a msg into its outbound post queue(OPHPR)
-
- The total number of msg must be less than the max size of the queue
- Otherwise queue overflow interrupt will assert.
- **/
-extern I2OSTATUS I2OFIFOPost( LOCATION,
- unsigned int base,
- void *pMsg );
-
-/**
- Read a msg from FIFO
- PCI Master reads a msg through outbound queue port of device(OFQPR)
- while local processor reads a msg from its inbound post queue(IPTPR)
- **/
-extern I2OSTATUS I2OFIFOGet( LOCATION,
- unsigned int base,
- void **pMsg );
-
-/**
- Get the I2O PCI configuration identification register
- **/
-extern I2OSTATUS I2OPCIConfigGet( LOCATION,
- unsigned int base,
- I2OIOP *);
-
-#endif
diff --git a/cpu/mpc824x/drivers/i2o/Makefile b/cpu/mpc824x/drivers/i2o/Makefile
deleted file mode 100644
index 3f5ca26..0000000
--- a/cpu/mpc824x/drivers/i2o/Makefile
+++ /dev/null
@@ -1,84 +0,0 @@
-##########################################################################
-#
-# Copyright Motorola, Inc. 1997
-# ALL RIGHTS RESERVED
-#
-# You are hereby granted a copyright license to use, modify, and
-# distribute the SOFTWARE so long as this entire notice is retained
-# without alteration in any modified and/or redistributed versions,
-# and that such modified versions are clearly identified as such.
-# No licenses are granted by implication, estoppel or otherwise under
-# any patents or trademarks of Motorola, Inc.
-#
-# The SOFTWARE is provided on an "AS IS" basis and without warranty.
-# To the maximum extent permitted by applicable law, MOTOROLA DISCLAIMS
-# ALL WARRANTIES WHETHER EXPRESS OR IMPLIED, INCLUDING IMPLIED
-# WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR
-# PURPOSE AND ANY WARRANTY AGAINST INFRINGEMENT WITH
-# REGARD TO THE SOFTWARE (INCLUDING ANY MODIFIED VERSIONS
-# THEREOF) AND ANY ACCOMPANYING WRITTEN MATERIALS.
-#
-# To the maximum extent permitted by applicable law, IN NO EVENT SHALL
-# MOTOROLA BE LIABLE FOR ANY DAMAGES WHATSOEVER
-# (INCLUDING WITHOUT LIMITATION, DAMAGES FOR LOSS OF
-# BUSINESS PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS
-# INFORMATION, OR OTHER PECUNIARY LOSS) ARISING OF THE USE OR
-# INABILITY TO USE THE SOFTWARE.
-#
-############################################################################
-TARGET = libi2o.a
-
-#DEBUG = -g
-DEBUG =
-LST = -Hanno -S
-OPTIM =
-CC = /risc/tools/pkgs/metaware/bin/hcppc
-CFLAGS = -Hnocopyr -c -Hsds -Hon=Char_default_unsigned -Hon=Char_is_rep -I../inc -I/risc/tools/pkgs/metaware/inc
-CCobj = $(CC) $(CFLAGS) $(DEBUG) $(OPTIM)
-PREP = $(CC) $(CFLAGS) -P
-
-# Assembler used to build the .s files (for the board version)
-
-ASOPT = -big_si -c
-ASDEBUG = -l -fm
-AS = /risc/tools/pkgs/metaware/bin/asppc
-
-# Linker to bring .o files together into an executable.
-
-LKOPT = -Bbase=0 -Qn -q -r
-LKCMD =
-LINK = /risc/tools/pkgs/metaware/bin/ldppc $(LKCMD) $(LKOPT)
-
-# DOS Utilities
-
-DEL = rm
-COPY = cp
-LIST = ls
-
-OBJECTS = i2o1.o i2o2.o
-
-all: $(TARGET)
-
-$(TARGET): $(OBJECTS)
- $(LINK) $(OBJECTS) -o $@
-
-objects: i2o1.o
-
-clean:
- $(DEL) -f *.o *.i *.map *.lst $(TARGET) $(OBJECTS)
-
-.s.o:
- $(DEL) -f $*.i
- $(PREP) -Hasmcpp $<
- $(AS) $(ASOPT) $*.i
-# $(AS) $(ASOPT) $(ASDEBUG) $*.i > $*.lst
-
-.c.o:
- $(CCobj) $<
-
-.c.s:
- $(CCobj) $(LST) $<
-
-i2o1.o: i2o.h i2o1.c
-
-i2o2.o: i2o.h i2o2.s
diff --git a/cpu/mpc824x/drivers/i2o/Makefile_pc b/cpu/mpc824x/drivers/i2o/Makefile_pc
deleted file mode 100644
index 6867f58..0000000
--- a/cpu/mpc824x/drivers/i2o/Makefile_pc
+++ /dev/null
@@ -1,90 +0,0 @@
-##########################################################################
-#
-# makefile_pc for use with PC mksnt tools dink32/drivers/i2o
-#
-# Copyright Motorola, Inc. 1997
-# ALL RIGHTS RESERVED
-#
-# You are hereby granted a copyright license to use, modify, and
-# distribute the SOFTWARE so long as this entire notice is retained
-# without alteration in any modified and/or redistributed versions,
-# and that such modified versions are clearly identified as such.
-# No licenses are granted by implication, estoppel or otherwise under
-# any patents or trademarks of Motorola, Inc.
-#
-# The SOFTWARE is provided on an "AS IS" basis and without warranty.
-# To the maximum extent permitted by applicable law, MOTOROLA DISCLAIMS
-# ALL WARRANTIES WHETHER EXPRESS OR IMPLIED, INCLUDING IMPLIED
-# WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR
-# PURPOSE AND ANY WARRANTY AGAINST INFRINGEMENT WITH
-# REGARD TO THE SOFTWARE (INCLUDING ANY MODIFIED VERSIONS
-# THEREOF) AND ANY ACCOMPANYING WRITTEN MATERIALS.
-#
-# To the maximum extent permitted by applicable law, IN NO EVENT SHALL
-# MOTOROLA BE LIABLE FOR ANY DAMAGES WHATSOEVER
-# (INCLUDING WITHOUT LIMITATION, DAMAGES FOR LOSS OF
-# BUSINESS PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS
-# INFORMATION, OR OTHER PECUNIARY LOSS) ARISING OF THE USE OR
-# INABILITY TO USE THE SOFTWARE.
-#
-############################################################################
-TARGET = libi2o.a
-
-#DEBUG = -g
-DEBUG =
-LST = -Hanno -S
-OPTIM =
-CC = m:/old_tools/tools/hcppc/bin/hcppc
-CFLAGS = -Hnocopyr -c -Hsds -Hon=Char_default_unsigned -Hon=Char_is_rep -I../inc -I/risc/tools/pkgs/metaware/inc
-CCobj = $(CC) $(CFLAGS) $(DEBUG) $(OPTIM)
-PREP = $(CC) $(CFLAGS) -P
-
-# Assembler used to build the .s files (for the board version)
-
-ASOPT = -big_si -c
-ASDEBUG = -l -fm
-AS = m:/old_tools/tools/hcppc/bin/asppc
-
-# Linker to bring .o files together into an executable.
-
-LKOPT = -Bbase=0 -Qn -q -r
-LKCMD =
-LINK = m:/old_tools/tools/hcppc/bin/ldppc $(LKCMD) $(LKOPT)
-
-# DOS Utilities
-
-DEL = rm
-COPY = cp
-LIST = ls
-
-OBJECTS = i2o1.o i2o2.o
-
-all: $(TARGET)
-
-$(TARGET): $(OBJECTS)
- $(LINK) $(OBJECTS) -o $@
-
-objects: i2o1.o
-
-clean:
- $(DEL) -f *.o *.i *.map *.lst $(TARGET) $(OBJECTS)
-
-.s.o:
- $(DEL) -f $*.i
- $(PREP) -Hasmcpp $<
- $(AS) $(ASOPT) $*.i
-# $(AS) $(ASOPT) $(ASDEBUG) $*.i > $*.lst
-
-.c.o:
- $(CCobj) $<
-
-.c.s:
- $(CCobj) $(LST) $<
-
-i2o1.o: i2o.h i2o1.c
- $(CCobj) $<
-
-i2o2.o: i2o.h i2o2.s
- $(DEL) -f $*.i
- $(PREP) -Hasmcpp $<
- $(AS) $(ASOPT) $*.i
diff --git a/cpu/mpc824x/drivers/i2o/i2o.h b/cpu/mpc824x/drivers/i2o/i2o.h
deleted file mode 100644
index 71572b2..0000000
--- a/cpu/mpc824x/drivers/i2o/i2o.h
+++ /dev/null
@@ -1,345 +0,0 @@
-#ifndef I2O_H
-#define I2O_H
-/*********************************************************
- *
- * copyright @ Motorola, 1999
- *
- *********************************************************/
-
-#define I2O_REG_OFFSET 0x0004
-
-#define PCI_CFG_CLA 0x0B
-#define PCI_CFG_SCL 0x0A
-#define PCI_CFG_PIC 0x09
-
-#define I2O_IMR0 0x0050
-#define I2O_IMR1 0x0054
-#define I2O_OMR0 0x0058
-#define I2O_OMR1 0x005C
-
-#define I2O_ODBR 0x0060
-#define I2O_IDBR 0x0068
-
-#define I2O_OMISR 0x0030
-#define I2O_OMIMR 0x0034
-#define I2O_IMISR 0x0100
-#define I2O_IMIMR 0x0104
-
-/* accessable to PCI master but local processor */
-#define I2O_IFQPR 0x0040
-#define I2O_OFQPR 0x0044
-
-/* accessable to local processor */
-#define I2O_IFHPR 0x0120
-#define I2O_IFTPR 0x0128
-#define I2O_IPHPR 0x0130
-#define I2O_IPTPR 0x0138
-#define I2O_OFHPR 0x0140
-#define I2O_OFTPR 0x0148
-#define I2O_OPHPR 0x0150
-#define I2O_OPTPR 0x0158
-#define I2O_MUCR 0x0164
-#define I2O_QBAR 0x0170
-
-#define I2O_NUM_MSG 2
-
-typedef enum _i2o_status
-{
- I2OSUCCESS = 0,
- I2OINVALID,
- I2OMSGINVALID,
- I2ODBINVALID,
- I2OQUEINVALID,
- I2OQUEEMPTY,
- I2OQUEFULL,
- I2ONOEVENT,
-} I2OSTATUS;
-
-typedef enum _queue_size
-{
- QSIZE_4K = 0x02,
- QSIZE_8K = 0x04,
- QSIZE_16K = 0x08,
- QSIZE_32K = 0x10,
- QSIZe_64K = 0x20,
-} QUEUE_SIZE;
-
-typedef enum _location
-{
- LOCAL = 0, /* used by local processor to access its own on board device,
- local processor's eumbbar is required */
- REMOTE, /* used by PCI master to access the devices on its PCI device,
- device's pcsrbar is required */
-} LOCATION;
-
-/* door bell */
-typedef enum _i2o_in_db
-{
- IN_DB = 1,
- MC, /* machine check */
-} I2O_IN_DB;
-
-/* I2O PCI configuration identification */
-typedef struct _i2o_iop
-{
- unsigned int base_class : 8;
- unsigned int sub_class : 8;
- unsigned int prg_code : 8;
-} I2OIOP;
-
-/* I2O Outbound Message Interrupt Status Register */
-typedef struct _i2o_om_stat
-{
- unsigned int rsvd0 : 26;
- unsigned int opqi : 1;
- unsigned int rsvd1 : 1;
- unsigned int odi : 1;
- unsigned int rsvd2 : 1;
- unsigned int om1i : 1;
- unsigned int om0i : 1;
-} I2OOMSTAT;
-
-/* I2O inbound Message Interrupt Status Register */
-typedef struct _i2o_im_stat
-{
- unsigned int rsvd0 : 23;
- unsigned int ofoi : 1;
- unsigned int ipoi : 1;
- unsigned int rsvd1 : 1;
- unsigned int ipqi : 1;
- unsigned int mci : 1;
- unsigned int idi : 1;
- unsigned int rsvd2 : 1;
- unsigned int im1i : 1;
- unsigned int im0i : 1;
-} I2OIMSTAT;
-
-/**
- Enable the interrupt associated with in/out bound msg
-
- Inbound message interrupt generated by PCI master and serviced by local processor
- local processor needs to enable its inbound interrupts it wants to handle (LOCAL)
-
- Outbound message interrupt generated by local processor and serviced by PCI master
- PCI master needs to enable the devices' outbound interrupts it wants to handle (REMOTE)
- **/
-extern I2OSTATUS I2OMsgEnable( LOCATION, /* REMOTE/LOCAL */
- unsigned int base, /* pcsrbar/eumbbar */
- unsigned char n ); /* b'1' - msg 0
- * b'10'- msg 1
- * b'11'- both
- */
-
-/**
- Disable the interrupt associated with in/out bound msg
-
- local processor needs to disable its inbound interrupts it is not interested (LOCAL)
-
- PCI master needs to disable outbound interrupts of devices it is not interested (REMOTE)
- **/
-extern I2OSTATUS I2OMsgDisable( LOCATION, /* REMOTE/LOCAL */
- unsigned int base, /* pcsrbar/eumbbar */
- unsigned char n ); /* b'1' - msg 0
- * b'10'- msg 1
- * b'11'- both
- */
-
-/**
- Read the msg register either from local inbound msg 0/1,
- or an outbound msg 0/1 of devices.
-
- If it is not local, pcsrbar must be passed to the function.
- Otherwise eumbbar is passed.
-
- If it is remote, outbound msg of the device is read.
- Otherwise local inbound msg is read.
- **/
-extern I2OSTATUS I2OMsgGet ( LOCATION, /* REMOTE/LOCAL */
- unsigned int base, /*pcsrbar/eumbbar */
- unsigned int n, /* 0 or 1 */
- unsigned int *msg );
-
-/**
- Write to nth Msg register either on local outbound msg 0/1,
- or aninbound msg 0/1 of devices
-
- If it is not local, pcsrbar must be passed to the function.
- Otherwise eumbbar is passed.
-
- If it is remote, inbound msg on the device is written.
- Otherwise local outbound msg is written.
- **/
-extern I2OSTATUS I2OMsgPost( LOCATION, /* REMOTE/LOCAL */
- unsigned int base, /*pcsrbar/eumbbar */
- unsigned int n, /* 0 or 1 */
- unsigned int msg );
-
-/**
- Enable the In/Out DoorBell Interrupt
-
- InDoorBell interrupt is generated by PCI master and serviced by local processor
- local processor needs to enable its inbound doorbell interrupts it wants to handle
-
- OutDoorbell interrupt is generated by local processor and serviced by PCI master
- PCI master needs to enable outbound doorbell interrupts of the devices it wants to handle
- **/
-extern I2OSTATUS I2ODBEnable( LOCATION, /* REMOTE/LOCAL */
- unsigned int base, /* pcsrbar/eumbbar */
- unsigned int in_db );/* when LOCAL, I2O_IN_DB, MC, I2O_IN_DB|MC */
-
-/**
- Disable the In/Out DoorBell Interrupt
-
- local processor needs to disable its inbound doorbell interrupts it is not interested
-
- PCI master needs to disable outbound doorbell interrupts of devices it is not interested
-
- **/
-extern I2OSTATUS I2ODBDisable( LOCATION, /* REMOTE/LOCAL */
- unsigned int base, /* pcsrbar/eumbbar */
- unsigned int in_db ); /* when LOCAL, I2O_IN_DB, MC, I2O_IN_DB|MC */
-
-/**
- Read a local indoorbell register, or an outdoorbell of devices.
- Reading a doorbell register, the register will be cleared.
-
- If it is not local, pcsrbar must be passed to the function.
- Otherwise eumbbar is passed.
-
- If it is remote, outdoorbell register on the device is read.
- Otherwise local in doorbell is read
- **/
-extern unsigned int I2ODBGet( LOCATION, /* REMOTE/LOCAL */
- unsigned int base); /* pcsrbar/eumbbar */
-
-/**
- Write to a local outdoorbell register, or an indoorbell register of devices.
-
- If it is not local, pcsrbar must be passed to the function.
- Otherwise eumbbar is passed.
-
- If it is remote, in doorbell register on the device is written.
- Otherwise local out doorbell is written
- **/
-extern void I2ODBPost( LOCATION, /* REMOTE/LOCAL */
- unsigned int base, /* pcsrbar/eumbbar */
- unsigned int msg ); /* in / out */
-
-/**
- Read the outbound msg unit interrupt status of devices. Reading an interrupt status register,
- the register will be cleared.
-
- The outbound interrupt status is AND with the outbound
- interrupt mask. The result is returned.
-
- PCI master must pass the pcsrbar to the function.
- **/
-extern I2OSTATUS I2OOutMsgStatGet( unsigned int pcsrbar, I2OOMSTAT * );
-
-/**
- Read the inbound msg unit interrupt status. Reading an interrupt status register,
- the register will be cleared.
-
- The inbound interrupt status is AND with the inbound
- interrupt mask. The result is returned.
-
- Local process must pass its eumbbar to the function.
-**/
-extern I2OSTATUS I2OInMsgStatGet( unsigned int eumbbar, I2OIMSTAT * );
-
-/**
- Configure the I2O FIFO, including QBAR, IFHPR/IFTPR,IPHPR/IPTPR,OFHPR/OFTPR, OPHPR/OPTPR,
- MUCR.
- **/
-extern I2OSTATUS I2OFIFOInit( unsigned int eumbbar,
- QUEUE_SIZE,
- unsigned int qba);/* queue base address that must be aligned at 1M */
-/**
- Enable the circular queue
- **/
-extern I2OSTATUS I2OFIFOEnable( unsigned int eumbbar );
-
-/**
- Disable the circular queue
- **/
-extern void I2OFIFODisable( unsigned int eumbbar );
-
-/**
- Enable the circular queue interrupt
- PCI master enables outbound FIFO interrupt of device
- Device enables its inbound FIFO interrupt
- **/
-extern void I2OFIFOIntEnable( LOCATION, unsigned int base );
-
-/**
- Disable the circular queue interrupt
- PCI master disables outbound FIFO interrupt of device
- Device disables its inbound FIFO interrupt
- **/
-extern void I2OFIFOIntDisable( LOCATION, unsigned int base );
-
-/**
- Enable the circular queue overflow interrupt
- **/
-extern void I2OFIFOOverflowIntEnable( unsigned int eumbbar );
-
-/**
- Disable the circular queue overflow interrupt
- **/
-extern void I2OFIFOOverflowIntDisable( unsigned int eumbbar );
-
-/**
- Allocate a free msg frame from free FIFO.
-
- PCI Master allocates a free msg frame through inbound queue port of device(IFQPR)
- while local processor allocates a free msg frame from outbound free queue(OFTPR)
-
- Unless both free queues are initialized, allocating a free MF will return 0xffffffff
- **/
-extern I2OSTATUS I2OFIFOAlloc( LOCATION,
- unsigned int base,
- void **pMsg);
-/**
- Free a used msg frame back to free queue
- PCI Master frees a MFA through outbound queue port of device(OFQPR)
- while local processor frees a MFA into its inbound free queue(IFHPR)
-
- Used msg frame does not need to be recycled in the order they
- read
-
- This function has to be called by PCI master to initialize Inbound free queue
- and by device to initialize Outbound free queue before I2OFIFOAlloc can be used.
- **/
-extern I2OSTATUS I2OFIFOFree( LOCATION,
- unsigned int base,
- void *pMsg );
-
-/**
- Post a msg into FIFO
- PCI Master posts a msg through inbound queue port of device(IFQPR)
- while local processor post a msg into its outbound post queue(OPHPR)
-
- The total number of msg must be less than the max size of the queue
- Otherwise queue overflow interrupt will assert.
- **/
-extern I2OSTATUS I2OFIFOPost( LOCATION,
- unsigned int base,
- void *pMsg );
-
-/**
- Read a msg from FIFO
- PCI Master reads a msg through outbound queue port of device(OFQPR)
- while local processor reads a msg from its inbound post queue(IPTPR)
- **/
-extern I2OSTATUS I2OFIFOGet( LOCATION,
- unsigned int base,
- void **pMsg );
-
-/**
- Get the I2O PCI configuration identification register
- **/
-extern I2OSTATUS I2OPCIConfigGet( LOCATION,
- unsigned int base,
- I2OIOP *);
-
-#endif
diff --git a/cpu/mpc824x/drivers/i2o/i2o1.c b/cpu/mpc824x/drivers/i2o/i2o1.c
deleted file mode 100644
index f058151..0000000
--- a/cpu/mpc824x/drivers/i2o/i2o1.c
+++ /dev/null
@@ -1,890 +0,0 @@
-/*********************************************************
- * $Id
- *
- * copyright @ Motorola, 1999
- *********************************************************/
-#include "i2o.h"
-
-extern unsigned int load_runtime_reg( unsigned int eumbbar, unsigned int reg );
-#pragma Alias( load_runtime_reg, "load_runtime_reg" );
-
-extern void store_runtime_reg( unsigned int eumbbar, unsigned int reg, unsigned int val );
-#pragma Alias( store_runtime_reg, "store_runtime_reg" );
-
-typedef struct _fifo_stat
-{
- QUEUE_SIZE qsz;
- unsigned int qba;
-} FIFOSTAT;
-
-FIFOSTAT fifo_stat = { QSIZE_4K, 0xffffffff };
-
-/**********************************************************************************
- * function: I2OMsgEnable
- *
- * description: Enable the interrupt associated with in/out bound msg
- * return I2OSUCCESS if no error, otherwise return I2OMSGINVALID.
- *
- * All previously enabled interrupts are preserved.
- * note:
- * Inbound message interrupt generated by PCI master and serviced by local processor
- * Outbound message interrupt generated by local processor and serviced by PCI master
- *
- * local processor needs to enable its inbound interrupts it wants to handle(LOCAL)
- * PCI master needs to enable the outbound interrupts of devices it wants to handle(REMOTE)
- ************************************************************************************/
-I2OSTATUS I2OMsgEnable ( LOCATION loc, /* REMOTE/LOCAL */
- unsigned int base, /* pcsrbar/eumbbar */
- unsigned char n ) /* b'1' - msg 0
- * b'10'- msg 1
- * b'11'- both
- */
-{
- unsigned int reg, val;
- if ( ( n & 0x3 ) == 0 )
- {
- /* neither msg 0, nor msg 1 */
- return I2OMSGINVALID;
- }
-
- n = (~n) & 0x3;
- /* LOCATION - REMOTE : enable outbound message of device, pcsrbar as base
- * LOCAL : enable local inbound message, eumbbar as base
- */
- reg = ( loc == REMOTE ? I2O_OMIMR : I2O_IMIMR );
- val = load_runtime_reg( base, reg );
-
- val &= 0xfffffffc; /* masked out the msg interrupt bits */
- val |= n; /* LSB are the one we want */
- store_runtime_reg( base, reg, val );
-
- return I2OSUCCESS;
-}
-
-/*********************************************************************************
- * function: I2OMsgDisable
- *
- * description: Disable the interrupt associated with in/out bound msg
- * Other previously enabled interrupts are preserved.
- * return I2OSUCCESS if no error otherwise return I2OMSGINVALID
- *
- * note:
- * local processor needs to disable its inbound interrupts it is not interested(LOCAL)
- * PCI master needs to disable outbound interrupts of devices it is not interested(REMOTE)
- *********************************************************************************/
-I2OSTATUS I2OMsgDisable( LOCATION loc, /* REMOTE/LOCAL */
- unsigned int base, /* pcsrbar/eumbbar */
- unsigned char n ) /* b'1' - msg 0
- * b'10'- msg 1
- * b'11'- both
- */
-{
- unsigned int reg, val;
-
- if ( ( n & 0x3 ) == 0 )
- {
- /* neither msg 0, nor msg 1 */
- return I2OMSGINVALID;
- }
-
- /* LOCATION - REMOTE : disable outbound message interrupt of device, pcsrbar as base
- * LOCAL : disable local inbound message interrupt, eumbbar as base
- */
- reg = ( loc == REMOTE ? I2O_OMIMR : I2O_IMIMR );
- val = load_runtime_reg( base, reg );
-
- val &= 0xfffffffc; /* masked out the msg interrupt bits */
- val |= ( n & 0x3 );
- store_runtime_reg( base, reg, val );
-
- return I2OSUCCESS;
-
-}
-
-/**************************************************************************
- * function: I2OMsgGet
- *
- * description: Local processor reads the nth Msg register from its inbound msg,
- * or a PCI Master reads nth outbound msg from device
- *
- * return I2OSUCCESS if no error, otherwise return I2OMSGINVALID.
- *
- * note:
- * If it is not local, pcsrbar must be passed to the function. Otherwise eumbbar is passed.
- * If it is remote, outbound msg on the device is read; otherwise local inbound msg is read
- *************************************************************************/
-I2OSTATUS I2OMsgGet ( LOCATION loc, /* REMOTE/LOCAL */
- unsigned int base, /*pcsrbar/eumbbar */
- unsigned int n, /* 0 or 1 */
- unsigned int *msg )
-{
- if ( n >= I2O_NUM_MSG || msg == 0 )
- {
- return I2OMSGINVALID;
- }
-
- if ( loc == REMOTE )
- {
- /* read the outbound msg of the device, pcsrbar as base */
- *msg = load_runtime_reg( base, I2O_OMR0+n*I2O_REG_OFFSET );
- }
- else
- {
- /* read the inbound msg sent by PCI master, eumbbar as base */
- *msg = load_runtime_reg( base, I2O_IMR0+n*I2O_REG_OFFSET );
- }
-
- return I2OSUCCESS;
-}
-
-/***************************************************************
- * function: I2OMsgPost
- *
- * description: Kahlua writes to its nth outbound msg register
- * PCI master writes to nth inbound msg register of device
- *
- * return I2OSUCCESS if no error, otherwise return I2OMSGINVALID.
- *
- * note:
- * If it is not local, pcsrbar must be passed to the function. Otherwise eumbbar is passed.
- *
- * If it is remote, inbound msg on the device is written; otherwise local outbound msg is written
- ***************************************************************/
-I2OSTATUS I2OMsgPost( LOCATION loc, /* REMOTE/LOCAL */
- unsigned int base, /*pcsrbar/eumbbar */
- unsigned int n, /* 0 or 1 */
- unsigned int msg )
-{
- if ( n >= I2O_NUM_MSG )
- {
- return I2OMSGINVALID;
- }
-
- if ( loc == REMOTE )
- {
- /* write to the inbound msg register of the device, pcsrbar as base */
- store_runtime_reg( base, I2O_IMR0+n*I2O_REG_OFFSET, msg );
- }
- else
- {
- /* write to the outbound msg register for PCI master to read, eumbbar as base */
- store_runtime_reg( base, I2O_OMR0+n*I2O_REG_OFFSET, msg );
- }
-
- return I2OSUCCESS;
-}
-
-/***********************************************************************
- * function: I2ODBEnable
- *
- * description: Local processor enables it's inbound doorbell interrupt
- * PCI master enables outbound doorbell interrupt of devices
- * Other previously enabled interrupts are preserved.
- * Return I2OSUCCESS if no error otherwise return I2ODBINVALID
- *
- * note:
- * In DoorBell interrupt is generated by PCI master and serviced by local processor
- * Out Doorbell interrupt is generated by local processor and serviced by PCI master
- *
- * Out Doorbell interrupt is generated by local processor and serviced by PCI master
- * PCI master needs to enable the outbound doorbell interrupts of device it wants to handle
- **********************************************************************/
-I2OSTATUS I2ODBEnable( LOCATION loc, /* REMOTE/LOCAL */
- unsigned int base, /* pcsrbar/eumbbar */
- unsigned int in_db ) /* when LOCAL, I2O_IN_DB, MC, I2O_IN_DB|MC */
-{
-
- /* LOCATION - REMOTE : PCI master initializes outbound doorbell message of device
- * LOCAL : Kahlua initializes its inbound doorbell message
- */
- unsigned int val;
-
- if ( loc == LOCAL && ( in_db & 0x3 ) == 0 )
- {
- return I2ODBINVALID;
- }
-
- if ( loc == REMOTE )
- {
- /* pcsrbar is base */
- val = load_runtime_reg( base, I2O_OMIMR );
- val &= 0xfffffff7;
- store_runtime_reg( base, I2O_OMIMR , val );
- }
- else
- {
- /* eumbbar is base */
- val = load_runtime_reg( base, I2O_IMIMR);
- in_db = ( (~in_db) & 0x3 ) << 3;
- val = ( val & 0xffffffe7) | in_db;
- store_runtime_reg( base, I2O_IMIMR, val );
- }
-
- return I2OSUCCESS;
-}
-
-/**********************************************************************************
- * function: I2ODBDisable
- *
- * description: local processor disables its inbound DoorBell Interrupt
- * PCI master disables outbound DoorBell interrupt of device
- * Other previously enabled interrupts are preserved.
- * return I2OSUCCESS if no error.Otherwise return I2ODBINVALID
- *
- * note:
- * local processor needs to disable its inbound doorbell interrupts it is not interested
- *
- * PCI master needs to disable outbound doorbell interrupts of device it is not interested
- ************************************************************************************/
-I2OSTATUS I2ODBDisable( LOCATION loc, /* REMOTE/LOCAL */
- unsigned int base, /* pcsrbar/eumbbar */
- unsigned int in_db ) /* when LOCAL, I2O_IN_DB, MC, I2O_IN_DB|MC */
-{
- /* LOCATION - REMOTE : handle device's out bound message initialization
- * LOCAL : handle local in bound message initialization
- */
- unsigned int val;
-
- if ( loc == LOCAL && ( in_db & 0x3 ) == 0 )
- {
- return I2ODBINVALID;
- }
-
- if ( loc == REMOTE )
- {
- /* pcsrbar is the base */
- val = load_runtime_reg( base, I2O_OMIMR );
- val |= 0x8;
- store_runtime_reg( base, I2O_OMIMR, val );
- }
- else
- {
- val = load_runtime_reg( base, I2O_IMIMR);
- in_db = ( in_db & 0x3 ) << 3;
- val |= in_db;
- store_runtime_reg( base, I2O_IMIMR, val );
- }
-
- return I2OSUCCESS;
-}
-
-/**********************************************************************************
- * function: I2ODBGet
- *
- * description: Local processor reads its in doorbell register,
- * PCI master reads the outdoorbell register of device.
- * After a doorbell register is read, the whole register will be cleared.
- * Otherwise, HW keeps generating interrupt.
- *
- * note:
- * If it is not local, pcsrbar must be passed to the function.
- * Otherwise eumbbar is passed.
- *
- * If it is remote, out doorbell register on the device is read.
- * Otherwise local in doorbell is read
- *
- * If the register is not cleared by write to it, any remaining bit of b'1's
- * will cause interrupt pending.
- *********************************************************************************/
-unsigned int I2ODBGet( LOCATION loc, /* REMOTE/LOCAL */
- unsigned int base) /* pcsrbar/eumbbar */
-{
- unsigned int msg, val;
-
- if ( loc == REMOTE )
- {
- /* read outbound doorbell register of device, pcsrbar is the base */
- val = load_runtime_reg( base, I2O_ODBR );
- msg = val & 0xe0000000;
- store_runtime_reg( base, I2O_ODBR, val ); /* clear the register */
- }
- else
- {
- /* read the inbound doorbell register, eumbbar is the base */
- val = load_runtime_reg( base, I2O_IDBR );
- store_runtime_reg( base, I2O_IDBR, val ); /* clear the register */
- msg = val;
- }
-
- return msg;
-}
-
-/**********************************************************************
- * function: I2ODBPost
- *
- * description: local processor writes to a outbound doorbell register,
- * PCI master writes to the inbound doorbell register of device
- *
- * note:
- * If it is not local, pcsrbar must be passed to the function.
- * Otherwise eumbbar is passed.
- *
- * If it is remote, in doorbell register on the device is written.
- * Otherwise local out doorbell is written
- *********************************************************************/
-void I2ODBPost( LOCATION loc, /* REMOTE/LOCAL */
- unsigned int base, /* pcsrbar/eumbbar */
- unsigned int msg ) /* in / out */
-{
- if ( loc == REMOTE )
- {
- /* write to inbound doorbell register of device, pcsrbar is the base */
- store_runtime_reg( base, I2O_IDBR, msg );
- }
- else
- {
- /* write to local outbound doorbell register, eumbbar is the base */
- store_runtime_reg( base, I2O_ODBR, msg & 0x1fffffff );
- }
-
-}
-
-/********************************************************************
- * function: I2OOutMsgStatGet
- *
- * description: PCI master reads device's outbound msg unit interrupt status.
- * Reading an interrupt status register,
- * the register will be cleared.
- *
- * The value of the status register is AND with the outbound
- * interrupt mask and result is returned.
- *
- * note:
- * pcsrbar must be passed to the function.
- ********************************************************************/
-I2OSTATUS I2OOutMsgStatGet( unsigned int pcsrbar, I2OOMSTAT *val )
-{
- unsigned int stat;
- unsigned int mask;
-
- if ( val == 0 )
- {
- return I2OINVALID;
- }
-
- /* read device's outbound status */
- stat = load_runtime_reg( pcsrbar, I2O_OMISR );
- mask = load_runtime_reg( pcsrbar, I2O_OMIMR );
- store_runtime_reg( pcsrbar, I2O_OMISR, stat & 0xffffffd7);
-
- stat &= mask;
- val->rsvd0 = ( stat & 0xffffffc0 ) >> 6;
- val->opqi = ( stat & 0x00000020 ) >> 5;
- val->rsvd1 = ( stat & 0x00000010 ) >> 4;
- val->odi = ( stat & 0x00000008 ) >> 3;
- val->rsvd2 = ( stat & 0x00000004 ) >> 2;
- val->om1i = ( stat & 0x00000002 ) >> 1;
- val->om0i = ( stat & 0x00000001 );
-
- return I2OSUCCESS;
-}
-
-/********************************************************************
- * function: I2OInMsgStatGet
- *
- * description: Local processor reads its inbound msg unit interrupt status.
- * Reading an interrupt status register,
- * the register will be cleared.
- *
- * The inbound msg interrupt status is AND with the inbound
- * msg interrupt mask and result is returned.
- *
- * note:
- * eumbbar must be passed to the function.
- ********************************************************************/
-I2OSTATUS I2OInMsgStatGet(unsigned int eumbbar, I2OIMSTAT *val)
-{
- unsigned int stat;
- unsigned int mask;
-
- if ( val == 0 )
- {
- return I2OINVALID;
- }
-
- /* read device's outbound status */
- stat = load_runtime_reg( eumbbar, I2O_OMISR );
- mask = load_runtime_reg( eumbbar, I2O_OMIMR );
- store_runtime_reg( eumbbar, I2O_OMISR, stat & 0xffffffe7 );
-
- stat &= mask;
- val->rsvd0 = ( stat & 0xfffffe00 ) >> 9;
- val->ofoi = ( stat & 0x00000100 ) >> 8;
- val->ipoi = ( stat & 0x00000080 ) >> 7;
- val->rsvd1 = ( stat & 0x00000040 ) >> 6;
- val->ipqi = ( stat & 0x00000020 ) >> 5;
- val->mci = ( stat & 0x00000010 ) >> 4;
- val->idi = ( stat & 0x00000008 ) >> 3;
- val->rsvd2 = ( stat & 0x00000004 ) >> 2;
- val->im1i = ( stat & 0x00000002 ) >> 1;
- val->im0i = ( stat & 0x00000001 );
-
- return I2OSUCCESS;
-
-}
-
-/***********************************************************
- * function: I2OFIFOInit
- *
- * description: Configure the I2O FIFO, including QBAR,
- * IFHPR/IFTPR, IPHPR/IPTPR, OFHPR/OFTPR,
- * OPHPR/OPTPR, MUCR.
- *
- * return I2OSUCCESS if no error,
- * otherwise return I2OQUEINVALID
- *
- * note: It is NOT this driver's responsibility of initializing
- * MFA blocks, i.e., FIFO queue itself. The MFA blocks
- * must be initialized before I2O unit can be used.
- ***********************************************************/
-I2OSTATUS I2OFIFOInit( unsigned int eumbbar,
- QUEUE_SIZE sz, /* value of CQS of MUCR */
- unsigned int qba) /* queue base address that must be aligned at 1M */
-{
-
- if ( ( qba & 0xfffff ) != 0 )
- {
- /* QBA must be aligned at 1Mbyte boundary */
- return I2OQUEINVALID;
- }
-
- store_runtime_reg( eumbbar, I2O_QBAR, qba );
- store_runtime_reg( eumbbar, I2O_MUCR, (unsigned int)sz );
- store_runtime_reg( eumbbar, I2O_IFHPR, qba );
- store_runtime_reg( eumbbar, I2O_IFTPR, qba );
- store_runtime_reg( eumbbar, I2O_IPHPR, qba + 1 * ( sz << 11 ));
- store_runtime_reg( eumbbar, I2O_IPTPR, qba + 1 * ( sz << 11 ));
- store_runtime_reg( eumbbar, I2O_OFHPR, qba + 2 * ( sz << 11 ));
- store_runtime_reg( eumbbar, I2O_OFTPR, qba + 2 * ( sz << 11 ));
- store_runtime_reg( eumbbar, I2O_OPHPR, qba + 3 * ( sz << 11 ));
- store_runtime_reg( eumbbar, I2O_OPTPR, qba + 3 * ( sz << 11 ));
-
- fifo_stat.qsz = sz;
- fifo_stat.qba = qba;
-
- return I2OSUCCESS;
-}
-
-/**************************************************
- * function: I2OFIFOEnable
- *
- * description: Enable the circular queue
- * return I2OSUCCESS if no error.
- * Otherwise I2OQUEINVALID is returned.
- *
- * note:
- *************************************************/
-I2OSTATUS I2OFIFOEnable( unsigned int eumbbar )
-{
- unsigned int val;
-
- if ( fifo_stat.qba == 0xfffffff )
- {
- return I2OQUEINVALID;
- }
-
- val = load_runtime_reg( eumbbar, I2O_MUCR );
- store_runtime_reg( eumbbar, I2O_MUCR, val | 0x1 );
-
- return I2OSUCCESS;
-}
-
-/**************************************************
- * function: I2OFIFODisable
- *
- * description: Disable the circular queue
- *
- * note:
- *************************************************/
-void I2OFIFODisable( unsigned int eumbbar )
-{
- if ( fifo_stat.qba == 0xffffffff )
- {
- /* not enabled */
- return;
- }
-
- unsigned int val = load_runtime_reg( eumbbar, I2O_MUCR );
- store_runtime_reg( eumbbar, I2O_MUCR, val & 0xfffffffe );
-}
-
-/****************************************************
- * function: I2OFIFOAlloc
- *
- * description: Allocate a free MFA from free FIFO.
- * return I2OSUCCESS if no error.
- * return I2OQUEEMPTY if no more free MFA.
- * return I2OINVALID on other errors.
- *
- * A free MFA must be allocated before a
- * message can be posted.
- *
- * note:
- * PCI Master allocates a free MFA from inbound queue of device
- * (pcsrbar is the base,) through the inbound queue port of device
- * while local processor allocates a free MFA from its outbound
- * queue (eumbbar is the base.)
- *
- ****************************************************/
-I2OSTATUS I2OFIFOAlloc( LOCATION loc,
- unsigned int base,
- void **pMsg )
-{
- I2OSTATUS stat = I2OSUCCESS;
- void *pHdr, *pTil;
-
- if ( pMsg == 0 || *pMsg == 0 || fifo_stat.qba == 0xffffffff )
- {
- /* not configured */
- return I2OQUEINVALID;
- }
-
- if ( loc == REMOTE )
- {
- /* pcsrbar is the base and read the inbound free tail ptr */
- pTil = (void *)load_runtime_reg( base, I2O_IFQPR );
- if ( ( (unsigned int)pTil & 0xFFFFFFF ) == 0xFFFFFFFF )
- {
- stat = I2OQUEEMPTY;
- }
- else
- {
- *pMsg = pTil;
- }
- }
- else
- {
- /* eumbbar is the base and read the outbound free tail ptr */
- pHdr = (void *)load_runtime_reg( base, I2O_OFHPR ); /* queue head */
- pTil = (void *)load_runtime_reg( base, I2O_OFTPR ); /* queue tail */
-
- /* check underflow */
- if ( pHdr == pTil )
- {
- /* hdr and til point to the same fifo item, no free MFA */
- stat = I2OQUEEMPTY;
- }
- else
- {
- /* update OFTPR */
- *pMsg = (void *)(*(unsigned char *)pTil);
- pTil = (void *)((unsigned int)pTil + 4);
- if ( (unsigned int)pTil == fifo_stat.qba + ( 4 * ( fifo_stat.qsz << 11 ) ) )
- {
- /* reach the upper limit */
- pTil = (void *)(fifo_stat.qba + ( 3 * (fifo_stat.qsz << 11) ));
- }
- store_runtime_reg( base, I2O_OFTPR, (unsigned int)pTil );
- }
- }
-
- return stat;
-}
-
-/******************************************************
- * function: I2OFIFOFree
- *
- * description: Free a used MFA back to free queue after
- * use.
- * return I2OSUCCESS if no error.
- * return I2OQUEFULL if inbound free queue
- * overflow
- *
- * note: PCI Master frees a MFA into device's outbound queue
- * (OFQPR) while local processor frees a MFA into its
- * inbound queue (IFHPR).
- *****************************************************/
-I2OSTATUS I2OFIFOFree( LOCATION loc,
- unsigned int base,
- void *pMsg )
-{
- void **pHdr, **pTil;
- I2OSTATUS stat = I2OSUCCESS;
-
- if ( fifo_stat.qba == 0xffffffff || pMsg == 0 )
- {
- return I2OQUEINVALID;
- }
-
- if ( loc == REMOTE )
- {
- /* pcsrbar is the base */
- store_runtime_reg( base, I2O_OFQPR, (unsigned int)pMsg );
- }
- else
- {
- /* eumbbar is the base */
- pHdr = (void **)load_runtime_reg( base, I2O_IFHPR );
- pTil = (void **)load_runtime_reg( base, I2O_IFTPR );
-
- /* store MFA */
- *pHdr = pMsg;
-
- /* update IFHPR */
- pHdr += 4;
-
- if ( (unsigned int)pHdr == fifo_stat.qba + ( fifo_stat.qsz << 11 ) )
- {
- /* reach the upper limit */
- pHdr = (void **)fifo_stat.qba;
- }
-
- /* check inbound free queue overflow */
- if ( pHdr != pTil )
- {
- store_runtime_reg( base, I2O_OPHPR, (unsigned int)pHdr);
- }
- else
- {
- stat = I2OQUEFULL;
- }
-
- }
-
- return stat;
-
-}
-
-/*********************************************
- * function: I2OFIFOPost
- *
- * description: Post a msg into FIFO post queue
- * the value of msg must be the one
- * returned by I2OFIFOAlloc
- *
- * note: PCI Master posts a msg into device's inbound queue
- * (IFQPR) while local processor post a msg into device's
- * outbound queue (OPHPR)
- *********************************************/
-I2OSTATUS I2OFIFOPost( LOCATION loc,
- unsigned int base,
- void *pMsg )
-{
- void **pHdr, **pTil;
- I2OSTATUS stat = I2OSUCCESS;
-
- if ( fifo_stat.qba == 0xffffffff || pMsg == 0 )
- {
- return I2OQUEINVALID;
- }
-
- if ( loc == REMOTE )
- {
- /* pcsrbar is the base */
- store_runtime_reg( base, I2O_IFQPR, (unsigned int)pMsg );
- }
- else
- {
- /* eumbbar is the base */
- pHdr = (void **)load_runtime_reg( base, I2O_OPHPR );
- pTil = (void **)load_runtime_reg( base, I2O_OPTPR );
-
- /* store MFA */
- *pHdr = pMsg;
-
- /* update IFHPR */
- pHdr += 4;
-
- if ( (unsigned int)pHdr == fifo_stat.qba + 3 * ( fifo_stat.qsz << 11 ) )
- {
- /* reach the upper limit */
- pHdr = (void **)(fifo_stat.qba + 2 * ( fifo_stat.qsz << 11 ) );
- }
-
- /* check post queue overflow */
- if ( pHdr != pTil )
- {
- store_runtime_reg( base, I2O_OPHPR, (unsigned int)pHdr);
- }
- else
- {
- stat = I2OQUEFULL;
- }
- }
-
- return stat;
-}
-
-/************************************************
- * function: I2OFIFOGet
- *
- * description: Read a msg from FIFO
- * This function should be called
- * only when there is a corresponding
- * msg interrupt.
- *
- * note: PCI Master reads a msg from device's outbound queue
- * (OFQPR) while local processor reads a msg from device's
- * inbound queue (IPTPR)
- ************************************************/
-I2OSTATUS I2OFIFOGet( LOCATION loc,
- unsigned int base,
- void **pMsg )
-{
- I2OSTATUS stat = I2OSUCCESS;
- void *pHdr, *pTil;
-
- if ( pMsg == 0 || *pMsg == 0 || fifo_stat.qba == 0xffffffff )
- {
- /* not configured */
- return I2OQUEINVALID;
- }
-
- if ( loc == REMOTE )
- {
- /* pcsrbar is the base */
- pTil = (void *)load_runtime_reg( base, I2O_OFQPR );
- if ( ( (unsigned int)pTil & 0xFFFFFFF ) == 0xFFFFFFFF )
- {
- stat = I2OQUEEMPTY;
- }
- else
- {
- *pMsg = pTil;
- }
- }
- else
- {
- /* eumbbar is the base and read the outbound free tail ptr */
- pHdr = (void *)load_runtime_reg( base, I2O_IPHPR ); /* queue head */
- pTil = (void *)load_runtime_reg( base, I2O_IPTPR ); /* queue tail */
-
- /* check underflow */
- if ( pHdr == pTil )
- {
- /* no free MFA */
- stat = I2OQUEEMPTY;
- }
- else
- {
- /* update OFTPR */
- *pMsg = (void *)(*(unsigned char *)pTil);
- pTil = (void *)((unsigned int)pTil + 4);
- if ( (unsigned int)pTil == fifo_stat.qba + 2 * ( fifo_stat.qsz << 11 ) )
- {
- /* reach the upper limit */
- pTil = (void *)(fifo_stat.qba + 1 * (fifo_stat.qsz << 11) );
- }
-
- store_runtime_reg( base, I2O_IPTPR, (unsigned int)pTil );
- }
- }
-
- return stat;
-}
-
-/********************************************************
- * function: I2OIOP
- *
- * description: Get the I2O PCI configuration identification
- * register.
- *
- * note: PCI master should pass pcsrbar while local processor
- * should pass eumbbar.
- *********************************************************/
-I2OSTATUS I2OPCIConfigGet( LOCATION loc,
- unsigned int base,
- I2OIOP * val)
-{
- unsigned int tmp;
- if ( val == 0 )
- {
- return I2OINVALID;
- }
- tmp = load_runtime_reg( base, PCI_CFG_CLA );
- val->base_class = ( tmp & 0xFF) << 16;
- tmp = load_runtime_reg( base, PCI_CFG_SCL );
- val->sub_class= ( (tmp & 0xFF) << 8 );
- tmp = load_runtime_reg( base, PCI_CFG_PIC );
- val->prg_code = (tmp & 0xFF);
- return I2OSUCCESS;
-}
-
-/*********************************************************
- * function: I2OFIFOIntEnable
- *
- * description: Enable the circular post queue interrupt
- *
- * note:
- * PCI master enables outbound FIFO interrupt of device
- * pscrbar is the base
- * Device enables its inbound FIFO interrupt
- * eumbbar is the base
- *******************************************************/
-void I2OFIFOIntEnable( LOCATION loc, unsigned int base )
-{
- unsigned int reg, val;
-
- /* LOCATION - REMOTE : enable outbound message of device, pcsrbar as base
- * LOCAL : enable local inbound message, eumbbar as base
- */
- reg = ( loc == REMOTE ? I2O_OMIMR : I2O_IMIMR );
- val = load_runtime_reg( base, reg );
-
- val &= 0xffffffdf; /* clear the msg interrupt bits */
- store_runtime_reg( base, reg, val );
-
-}
-
-/****************************************************
- * function: I2OFIFOIntDisable
- *
- * description: Disable the circular post queue interrupt
- *
- * note:
- * PCI master disables outbound FIFO interrupt of device
- * (pscrbar is the base)
- * Device disables its inbound FIFO interrupt
- * (eumbbar is the base)
- *****************************************************/
-void I2OFIFOIntDisable( LOCATION loc, unsigned int base )
-{
-
- /* LOCATION - REMOTE : disable outbound message interrupt of device, pcsrbar as base
- * LOCAL : disable local inbound message interrupt, eumbbar as base
- */
- unsigned int reg = ( loc == REMOTE ? I2O_OMIMR : I2O_IMIMR );
- unsigned int val = load_runtime_reg( base, reg );
-
- val |= 0x00000020; /* masked out the msg interrupt bits */
- store_runtime_reg( base, reg, val );
-
-}
-
-/*********************************************************
- * function: I2OFIFOOverflowIntEnable
- *
- * description: Enable the circular queue overflow interrupt
- *
- * note:
- * Device enables its inbound FIFO post overflow interrupt
- * and outbound free overflow interrupt.
- * eumbbar is the base
- *******************************************************/
-void I2OFIFOOverflowIntEnable( unsigned int eumbbar )
-{
- unsigned int val = load_runtime_reg( eumbbar, I2O_IMIMR );
-
- val &= 0xfffffe7f; /* clear the two overflow interrupt bits */
- store_runtime_reg( eumbbar, I2O_IMIMR, val );
-
-}
-
-/****************************************************
- * function: I2OFIFOOverflowIntDisable
- *
- * description: Disable the circular queue overflow interrupt
- *
- * note:
- * Device disables its inbound post FIFO overflow interrupt
- * and outbound free FIFO overflow interrupt
- * (eumbbar is the base)
- *****************************************************/
-void I2OFIFOOverflowIntDisable( unsigned int eumbbar )
-{
-
- unsigned int val = load_runtime_reg( eumbbar, I2O_IMIMR );
-
- val |= 0x00000180; /* masked out the msg overflow interrupt bits */
- store_runtime_reg( eumbbar, I2O_IMIMR, val );
-}
diff --git a/cpu/mpc824x/drivers/i2o/i2o2.S b/cpu/mpc824x/drivers/i2o/i2o2.S
deleted file mode 100644
index 990f9ef..0000000
--- a/cpu/mpc824x/drivers/i2o/i2o2.S
+++ /dev/null
@@ -1,47 +0,0 @@
-/**************************************
- *
- * copyright @ Motorola, 1999
- *
- **************************************/
-
-/**********************************************************
- * function: load_runtime_reg
- *
- * input: r3 - value of eumbbar
- * r4 - register offset in embedded utility space
- *
- * output: r3 - register content
- **********************************************************/
- .text
- .align 2
- .global load_runtime_reg
-
-load_runtime_reg:
-
- xor r5,r5,r5
- or r5,r5,r3 /* save eumbbar */
-
- lwbrx r3,r4,r5
- sync
-
- bclr 20, 0
-
-/****************************************************************
- * function: store_runtime_reg
- *
- * input: r3 - value of eumbbar
- * r4 - register offset in embedded utility space
- * r5 - new value to be stored
- *
- ****************************************************************/
- .text
- .align 2
- .global store_runtime_reg
-store_runtime_reg:
-
- xor r0,r0,r0
-
- stwbrx r5, r4, r3
- sync
-
- bclr 20,0
diff --git a/cpu/mpc8260/Makefile b/cpu/mpc8260/Makefile
index b4c269f..80d7852 100644
--- a/cpu/mpc8260/Makefile
+++ b/cpu/mpc8260/Makefile
@@ -1,5 +1,5 @@
#
-# (C) Copyright 2000
+# (C) Copyright 2000-2006
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
#
# See file CREDITS for list of people who contributed to this
@@ -23,23 +23,27 @@
include $(TOPDIR)/config.mk
-LIB = lib$(CPU).a
+LIB = $(obj)lib$(CPU).a
START = start.o kgdb.o
-OBJS = traps.o serial_smc.o serial_scc.o cpu.o cpu_init.o speed.o \
+COBJS = traps.o serial_smc.o serial_scc.o cpu.o cpu_init.o speed.o \
interrupts.o ether_scc.o ether_fcc.o i2c.o commproc.o \
bedbug_603e.o pci.o spi.o
-all: .depend $(START) $(LIB)
+SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
+START := $(addprefix $(obj),$(START))
+
+all: $(obj).depend $(START) $(LIB)
$(LIB): $(OBJS)
- $(AR) crv $@ $(OBJS) kgdb.o
+ $(AR) $(ARFLAGS) $@ $(OBJS) $(obj)kgdb.o
#########################################################################
-.depend: Makefile $(START:.o=.S) $(OBJS:.o=.c)
- $(CC) -M $(CFLAGS) $(START:.o=.S) $(OBJS:.o=.c) > $@
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
-sinclude .depend
+sinclude $(obj).depend
#########################################################################
diff --git a/cpu/mpc83xx/Makefile b/cpu/mpc83xx/Makefile
index 60df4cd..b2a6b3e 100644
--- a/cpu/mpc83xx/Makefile
+++ b/cpu/mpc83xx/Makefile
@@ -1,4 +1,7 @@
#
+# (C) Copyright 2006
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
# Copyright 2004 Freescale Semiconductor, Inc.
#
# See file CREDITS for list of people who contributed to this
@@ -22,31 +25,26 @@
include $(TOPDIR)/config.mk
-LIB = lib$(CPU).a
-
-START = start.o \
- resetvec.o
+LIB = $(obj)lib$(CPU).a
-COBJS = traps.o \
- cpu.o \
- cpu_init.o \
- speed.o \
- interrupts.o \
- i2c.o \
- spd_sdram.o
+START = start.o resetvec.o
+COBJS = traps.o cpu.o cpu_init.o speed.o interrupts.o \
+ i2c.o spd_sdram.o
-OBJS = $(COBJS)
+SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
+START := $(addprefix $(obj),$(START))
-all: .depend $(START) $(LIB)
+all: $(obj).depend $(START) $(LIB)
$(LIB): $(OBJS)
- $(AR) crv $@ $(OBJS)
+ $(AR) $(ARFLAGS) $@ $(OBJS)
#########################################################################
-.depend: Makefile $(START:.o=.S) $(AOBJS:.o=.S) $(COBJS:.o=.c)
- $(CC) -M $(CFLAGS) $(START:.o=.S) $(COBJS:.o=.c) > $@
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
-sinclude .depend
+sinclude $(obj).depend
#########################################################################
diff --git a/cpu/mpc85xx/Makefile b/cpu/mpc85xx/Makefile
index 5298dc1..ff67dcd 100644
--- a/cpu/mpc85xx/Makefile
+++ b/cpu/mpc85xx/Makefile
@@ -1,4 +1,7 @@
#
+# (C) Copyright 2006
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
# (C) Copyright 2002,2003 Motorola Inc.
# Xianghua Xiao,X.Xiao@motorola.com
#
@@ -23,23 +26,26 @@
include $(TOPDIR)/config.mk
-LIB = lib$(CPU).a
+LIB = $(obj)lib$(CPU).a
START = start.o resetvec.o
COBJS = traps.o cpu.o cpu_init.o speed.o interrupts.o \
- pci.o serial_scc.o commproc.o ether_fcc.o i2c.o spd_sdram.o
-OBJS = $(COBJS)
+ pci.o serial_scc.o commproc.o ether_fcc.o spd_sdram.o
+
+SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
+START := $(addprefix $(obj),$(START))
-all: .depend $(START) $(LIB)
+all: $(obj).depend $(START) $(LIB)
$(LIB): $(OBJS)
- $(AR) crv $@ $(OBJS)
+ $(AR) $(ARFLAGS) $@ $(OBJS)
#########################################################################
-.depend: Makefile $(START:.o=.S) $(AOBJS:.o=.S) $(COBJS:.o=.c)
- $(CC) -M $(CFLAGS) $(START:.o=.S) $(AOBJS:.o=.S) $(COBJS:.o=.c) > $@
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
-sinclude .depend
+sinclude $(obj).depend
#########################################################################
diff --git a/cpu/mpc85xx/cpu.c b/cpu/mpc85xx/cpu.c
index f7fe22e..0507c47 100644
--- a/cpu/mpc85xx/cpu.c
+++ b/cpu/mpc85xx/cpu.c
@@ -30,7 +30,10 @@
#include <command.h>
#include <asm/cache.h>
-/* ------------------------------------------------------------------------- */
+#if defined(CONFIG_OF_FLAT_TREE)
+#include <ft_build.h>
+#endif
+
int checkcpu (void)
{
@@ -227,3 +230,48 @@ int dma_xfer(void *dest, uint count, void *src) {
return dma_check();
}
#endif
+
+
+#ifdef CONFIG_OF_FLAT_TREE
+void
+ft_cpu_setup(void *blob, bd_t *bd)
+{
+ u32 *p;
+ ulong clock;
+ int len;
+
+ clock = bd->bi_busfreq;
+ p = ft_get_prop(blob, "/cpus/" OF_CPU "/bus-frequency", &len);
+ if (p != NULL)
+ *p = cpu_to_be32(clock);
+
+ p = ft_get_prop(blob, "/" OF_SOC "/serial@4500/clock-frequency", &len);
+ if (p != NULL)
+ *p = cpu_to_be32(clock);
+
+ p = ft_get_prop(blob, "/" OF_SOC "/serial@4600/clock-frequency", &len);
+ if (p != NULL)
+ *p = cpu_to_be32(clock);
+
+#if defined(CONFIG_MPC85XX_TSEC1)
+ p = ft_get_prop(blob, "/" OF_SOC "/ethernet@24000/mac-address", &len);
+ memcpy(p, bd->bi_enetaddr, 6);
+#endif
+
+#if defined(CONFIG_HAS_ETH1)
+ p = ft_get_prop(blob, "/" OF_SOC "/ethernet@25000/mac-address", &len);
+ memcpy(p, bd->bi_enet1addr, 6);
+#endif
+
+#if defined(CONFIG_HAS_ETH2)
+ p = ft_get_prop(blob, "/" OF_SOC "/ethernet@26000/mac-address", &len);
+ memcpy(p, bd->bi_enet2addr, 6);
+#endif
+
+#if defined(CONFIG_HAS_ETH3)
+ p = ft_get_prop(blob, "/" OF_SOC "/ethernet@27000/mac-address", &len);
+ memcpy(p, bd->bi_enet3addr, 6);
+#endif
+
+}
+#endif
diff --git a/cpu/mpc85xx/cpu_init.c b/cpu/mpc85xx/cpu_init.c
index c12b47b..9f4d36c 100644
--- a/cpu/mpc85xx/cpu_init.c
+++ b/cpu/mpc85xx/cpu_init.c
@@ -32,6 +32,7 @@
DECLARE_GLOBAL_DATA_PTR;
+
#ifdef CONFIG_CPM2
static void config_8560_ioports (volatile immap_t * immr)
{
diff --git a/cpu/mpc85xx/i2c.c b/cpu/mpc85xx/i2c.c
deleted file mode 100644
index 32dcf5d..0000000
--- a/cpu/mpc85xx/i2c.c
+++ /dev/null
@@ -1,265 +0,0 @@
-/*
- * (C) Copyright 2003,Motorola Inc.
- * Xianghua Xiao <x.xiao@motorola.com>
- * Adapted for Motorola 85xx chip.
- *
- * (C) Copyright 2003
- * Gleb Natapov <gnatapov@mrv.com>
- * Some bits are taken from linux driver writen by adrian@humboldt.co.uk
- *
- * Hardware I2C driver for MPC107 PCI bridge.
- *
- * 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 <asm/io.h>
-
-#ifdef CONFIG_HARD_I2C
-#include <i2c.h>
-
-#define TIMEOUT (CFG_HZ/4)
-
-#define I2C_Addr ((u8 *)(CFG_CCSRBAR + 0x3000))
-
-#define I2CADR &I2C_Addr[0]
-#define I2CFDR &I2C_Addr[4]
-#define I2CCCR &I2C_Addr[8]
-#define I2CCSR &I2C_Addr[12]
-#define I2CCDR &I2C_Addr[16]
-#define I2CDFSRR &I2C_Addr[20]
-
-#define I2C_READ 1
-#define I2C_WRITE 0
-
-void
-i2c_init(int speed, int slaveadd)
-{
- /* stop I2C controller */
- writeb(0x0, I2CCCR);
-
- /* set clock */
- writeb(0x3f, I2CFDR);
-
- /* set default filter */
- writeb(0x10,I2CDFSRR);
-
- /* write slave address */
- writeb(slaveadd, I2CADR);
-
- /* clear status register */
- writeb(0x0, I2CCSR);
-
- /* start I2C controller */
- writeb(MPC85xx_I2CCR_MEN, I2CCCR);
-}
-
-static __inline__ int
-i2c_wait4bus (void)
-{
- ulong timeval = get_timer (0);
-
- while (readb(I2CCSR) & MPC85xx_I2CSR_MBB) {
- if (get_timer (timeval) > TIMEOUT) {
- return -1;
- }
- }
-
- return 0;
-}
-
-static __inline__ int
-i2c_wait (int write)
-{
- u32 csr;
- ulong timeval = get_timer (0);
-
- do {
- csr = readb(I2CCSR);
-
- if (!(csr & MPC85xx_I2CSR_MIF))
- continue;
-
- writeb(0x0, I2CCSR);
-
- if (csr & MPC85xx_I2CSR_MAL) {
- debug("i2c_wait: MAL\n");
- return -1;
- }
-
- if (!(csr & MPC85xx_I2CSR_MCF)) {
- debug("i2c_wait: unfinished\n");
- return -1;
- }
-
- if (write == I2C_WRITE && (csr & MPC85xx_I2CSR_RXAK)) {
- debug("i2c_wait: No RXACK\n");
- return -1;
- }
-
- return 0;
- } while (get_timer (timeval) < TIMEOUT);
-
- debug("i2c_wait: timed out\n");
- return -1;
-}
-
-static __inline__ int
-i2c_write_addr (u8 dev, u8 dir, int rsta)
-{
- writeb(MPC85xx_I2CCR_MEN | MPC85xx_I2CCR_MSTA | MPC85xx_I2CCR_MTX |
- (rsta?MPC85xx_I2CCR_RSTA:0),
- I2CCCR);
-
- writeb((dev << 1) | dir, I2CCDR);
-
- if (i2c_wait (I2C_WRITE) < 0)
- return 0;
-
- return 1;
-}
-
-static __inline__ int
-__i2c_write (u8 *data, int length)
-{
- int i;
-
- writeb(MPC85xx_I2CCR_MEN | MPC85xx_I2CCR_MSTA | MPC85xx_I2CCR_MTX,
- I2CCCR);
-
- for (i=0; i < length; i++) {
- writeb(data[i], I2CCDR);
-
- if (i2c_wait (I2C_WRITE) < 0)
- break;
- }
-
- return i;
-}
-
-static __inline__ int
-__i2c_read (u8 *data, int length)
-{
- int i;
-
- writeb(MPC85xx_I2CCR_MEN | MPC85xx_I2CCR_MSTA |
- ((length == 1) ? MPC85xx_I2CCR_TXAK : 0),
- I2CCCR);
-
- /* dummy read */
- readb(I2CCDR);
-
- for (i=0; i < length; i++) {
- if (i2c_wait (I2C_READ) < 0)
- break;
-
- /* Generate ack on last next to last byte */
- if (i == length - 2)
- writeb(MPC85xx_I2CCR_MEN | MPC85xx_I2CCR_MSTA |
- MPC85xx_I2CCR_TXAK,
- I2CCCR);
-
- /* Generate stop on last byte */
- if (i == length - 1)
- writeb(MPC85xx_I2CCR_MEN | MPC85xx_I2CCR_TXAK, I2CCCR);
-
- data[i] = readb(I2CCDR);
- }
-
- return i;
-}
-
-int
-i2c_read (u8 dev, uint addr, int alen, u8 *data, int length)
-{
- int i = 0;
- u8 *a = (u8*)&addr;
-
- if (i2c_wait4bus () < 0)
- goto exit;
-
- if (i2c_write_addr (dev, I2C_WRITE, 0) == 0)
- goto exit;
-
- if (__i2c_write (&a[4 - alen], alen) != alen)
- goto exit;
-
- if (i2c_write_addr (dev, I2C_READ, 1) == 0)
- goto exit;
-
- i = __i2c_read (data, length);
-
- exit:
- writeb(MPC85xx_I2CCR_MEN, I2CCCR);
-
- return !(i == length);
-}
-
-int
-i2c_write (u8 dev, uint addr, int alen, u8 *data, int length)
-{
- int i = 0;
- u8 *a = (u8*)&addr;
-
- if (i2c_wait4bus () < 0)
- goto exit;
-
- if (i2c_write_addr (dev, I2C_WRITE, 0) == 0)
- goto exit;
-
- if (__i2c_write (&a[4 - alen], alen) != alen)
- goto exit;
-
- i = __i2c_write (data, length);
-
- exit:
- writeb(MPC85xx_I2CCR_MEN, I2CCCR);
-
- return !(i == length);
-}
-
-int i2c_probe (uchar chip)
-{
- int tmp;
-
- /*
- * Try to read the first location of the chip. The underlying
- * driver doesn't appear to support sending just the chip address
- * and looking for an <ACK> back.
- */
- udelay(10000);
- return i2c_read (chip, 0, 1, (uchar *)&tmp, 1);
-}
-
-uchar i2c_reg_read (uchar i2c_addr, uchar reg)
-{
- uchar buf[1];
-
- i2c_read (i2c_addr, reg, 1, buf, 1);
-
- return (buf[0]);
-}
-
-void i2c_reg_write (uchar i2c_addr, uchar reg, uchar val)
-{
- i2c_write (i2c_addr, reg, 1, &val, 1);
-}
-
-#endif /* CONFIG_HARD_I2C */
diff --git a/cpu/mpc85xx/pci.c b/cpu/mpc85xx/pci.c
index a94493e..84f839a 100644
--- a/cpu/mpc85xx/pci.c
+++ b/cpu/mpc85xx/pci.c
@@ -29,69 +29,101 @@
#include <asm/cpm_85xx.h>
#include <pci.h>
+#if defined(CONFIG_OF_FLAT_TREE)
+#include <ft_build.h>
+#endif
#if defined(CONFIG_PCI)
+static struct pci_controller *pci_hose;
+
void
-pci_mpc85xx_init(struct pci_controller *hose)
+pci_mpc85xx_init(struct pci_controller *board_hose)
{
+ u16 reg16;
+ u32 dev;
+
volatile immap_t *immap = (immap_t *)CFG_CCSRBAR;
volatile ccsr_pcix_t *pcix = &immap->im_pcix;
+#ifdef CONFIG_MPC85XX_PCI2
+ volatile ccsr_pcix_t *pcix2 = &immap->im_pcix2;
+#endif
+ volatile ccsr_gur_t *gur = &immap->im_gur;
+ struct pci_controller * hose;
- u16 reg16;
+ pci_hose = board_hose;
+
+ hose = &pci_hose[0];
hose->first_busno = 0;
hose->last_busno = 0xff;
- pci_set_region(hose->regions + 0,
- CFG_PCI1_MEM_BASE,
- CFG_PCI1_MEM_PHYS,
- CFG_PCI1_MEM_SIZE,
- PCI_REGION_MEM);
-
- pci_set_region(hose->regions + 1,
- CFG_PCI1_IO_BASE,
- CFG_PCI1_IO_PHYS,
- CFG_PCI1_IO_SIZE,
- PCI_REGION_IO);
-
- hose->region_count = 2;
-
pci_setup_indirect(hose,
(CFG_IMMR+0x8000),
(CFG_IMMR+0x8004));
+ /*
+ * Hose scan.
+ */
+ 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);
+
+ if (!(gur->pordevsr & PORDEVSR_PCI)) {
+ /* PCI-X init */
+ if (CONFIG_SYS_CLK_FREQ < 66000000)
+ printf("PCI-X will only work at 66 MHz\n");
+
+ reg16 = PCI_X_CMD_MAX_SPLIT | PCI_X_CMD_MAX_READ
+ | PCI_X_CMD_ERO | PCI_X_CMD_DPERR_E;
+ pci_hose_write_config_word(hose, dev, PCIX_COMMAND, reg16);
+ }
+
pcix->potar1 = (CFG_PCI1_MEM_BASE >> 12) & 0x000fffff;
pcix->potear1 = 0x00000000;
- pcix->powbar1 = (CFG_PCI1_MEM_BASE >> 12) & 0x000fffff;
+ pcix->powbar1 = (CFG_PCI1_MEM_PHYS >> 12) & 0x000fffff;
pcix->powbear1 = 0x00000000;
- pcix->powar1 = 0x8004401c; /* 512M MEM space */
+ pcix->powar1 = (POWAR_EN | POWAR_MEM_READ |
+ POWAR_MEM_WRITE | POWAR_MEM_512M);
- pcix->potar2 = 0x00000000;
+ pcix->potar2 = (CFG_PCI1_IO_BASE >> 12) & 0x000fffff;
pcix->potear2 = 0x00000000;
- pcix->powbar2 = (CFG_PCI1_IO_BASE >> 12) & 0x000fffff;
+ pcix->powbar2 = (CFG_PCI1_IO_PHYS >> 12) & 0x000fffff;
pcix->powbear2 = 0x00000000;
- pcix->powar2 = 0x80088017; /* 16M IO space */
+ pcix->powar2 = (POWAR_EN | POWAR_IO_READ |
+ POWAR_IO_WRITE | POWAR_IO_1M);
pcix->pitar1 = 0x00000000;
pcix->piwbar1 = 0x00000000;
- pcix->piwar1 = 0xa0f5501e; /* Enable, Prefetch, Local Mem,
- * Snoop R/W, 2G */
+ pcix->piwar1 = (PIWAR_EN | PIWAR_PF | PIWAR_LOCAL |
+ PIWAR_READ_SNOOP | PIWAR_WRITE_SNOOP | PIWAR_MEM_2G);
- /*
- * Hose scan.
- */
- pci_register_hose(hose);
+ pcix->powar3 = 0;
+ pcix->powar4 = 0;
+ pcix->piwar2 = 0;
+ pcix->piwar3 = 0;
- pci_read_config_word (PCI_BDF(0,0,0), PCI_COMMAND, &reg16);
- reg16 |= PCI_COMMAND_SERR | PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
- pci_write_config_word(PCI_BDF(0,0,0), PCI_COMMAND, reg16);
+ pci_set_region(hose->regions + 0,
+ CFG_PCI1_MEM_BASE,
+ CFG_PCI1_MEM_PHYS,
+ CFG_PCI1_MEM_SIZE,
+ PCI_REGION_MEM);
- /*
- * Clear non-reserved bits in status register.
- */
- pci_write_config_word(PCI_BDF(0,0,0), PCI_STATUS, 0xffff);
- pci_write_config_byte(PCI_BDF(0,0,0), PCI_LATENCY_TIMER,0x80);
+ pci_set_region(hose->regions + 1,
+ CFG_PCI1_IO_BASE,
+ CFG_PCI1_IO_PHYS,
+ CFG_PCI1_IO_SIZE,
+ PCI_REGION_IO);
+
+ hose->region_count = 2;
+
+ pci_register_hose(hose);
#if defined(CONFIG_MPC8555CDS) || defined(CONFIG_MPC8541CDS)
/*
@@ -117,6 +149,94 @@ pci_mpc85xx_init(struct pci_controller *hose)
#endif
hose->last_busno = pci_hose_scan(hose);
+
+#ifdef CONFIG_MPC85XX_PCI2
+ hose = &pci_hose[1];
+
+ hose->first_busno = pci_hose[0].last_busno + 1;
+ hose->last_busno = 0xff;
+
+ pci_setup_indirect(hose,
+ (CFG_IMMR+0x9000),
+ (CFG_IMMR+0x9004));
+
+ 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);
+
+ pcix2->potar1 = (CFG_PCI2_MEM_BASE >> 12) & 0x000fffff;
+ pcix2->potear1 = 0x00000000;
+ pcix2->powbar1 = (CFG_PCI2_MEM_PHYS >> 12) & 0x000fffff;
+ pcix2->powbear1 = 0x00000000;
+ pcix2->powar1 = (POWAR_EN | POWAR_MEM_READ |
+ POWAR_MEM_WRITE | POWAR_MEM_512M);
+
+ pcix2->potar2 = (CFG_PCI2_IO_BASE >> 12) & 0x000fffff;
+ pcix2->potear2 = 0x00000000;
+ pcix2->powbar2 = (CFG_PCI2_IO_PHYS >> 12) & 0x000fffff;
+ pcix2->powbear2 = 0x00000000;
+ pcix2->powar2 = (POWAR_EN | POWAR_IO_READ |
+ POWAR_IO_WRITE | POWAR_IO_1M);
+
+ pcix2->pitar1 = 0x00000000;
+ pcix2->piwbar1 = 0x00000000;
+ pcix2->piwar1 = (PIWAR_EN | PIWAR_PF | PIWAR_LOCAL |
+ PIWAR_READ_SNOOP | PIWAR_WRITE_SNOOP | PIWAR_MEM_2G);
+
+ pcix2->powar3 = 0;
+ pcix2->powar4 = 0;
+ pcix2->piwar2 = 0;
+ pcix2->piwar3 = 0;
+
+ pci_set_region(hose->regions + 0,
+ CFG_PCI2_MEM_BASE,
+ CFG_PCI2_MEM_PHYS,
+ CFG_PCI2_MEM_SIZE,
+ PCI_REGION_MEM);
+
+ pci_set_region(hose->regions + 1,
+ CFG_PCI2_IO_BASE,
+ CFG_PCI2_IO_PHYS,
+ CFG_PCI2_IO_SIZE,
+ PCI_REGION_IO);
+
+ hose->region_count = 2;
+
+ /*
+ * Hose scan.
+ */
+ pci_register_hose(hose);
+
+ 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@8000/bus-range", &len);
+ if (p != NULL) {
+ p[0] = pci_hose[0].first_busno;
+ p[1] = pci_hose[0].last_busno;
+ }
+
+#ifdef CONFIG_MPC85XX_PCI2
+ p = (u32 *)ft_get_prop(blob, "/" OF_SOC "/pci@9000/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/cpu/mpc85xx/spd_sdram.c b/cpu/mpc85xx/spd_sdram.c
index af99282..6da5367 100644
--- a/cpu/mpc85xx/spd_sdram.c
+++ b/cpu/mpc85xx/spd_sdram.c
@@ -131,8 +131,8 @@ convert_bcd_tenths_to_cycle_time_ps(unsigned int spd_val)
800,
900,
250,
- 330, /* FIXME: Is 333 better/valid? */
- 660, /* FIXME: Is 667 better/valid? */
+ 330,
+ 660,
750,
0, /* undefined */
0 /* undefined */
@@ -146,6 +146,28 @@ convert_bcd_tenths_to_cycle_time_ps(unsigned int spd_val)
}
+/*
+ * Determine Refresh Rate. Ignore self refresh bit on DDR I.
+ * Table from SPD Spec, Byte 12, converted to picoseconds and
+ * filled in with "default" normal values.
+ */
+unsigned int determine_refresh_rate(unsigned int spd_refresh)
+{
+ unsigned int refresh_time_ns[8] = {
+ 15625000, /* 0 Normal 1.00x */
+ 3900000, /* 1 Reduced .25x */
+ 7800000, /* 2 Extended .50x */
+ 31300000, /* 3 Extended 2.00x */
+ 62500000, /* 4 Extended 4.00x */
+ 125000000, /* 5 Extended 8.00x */
+ 15625000, /* 6 Normal 1.00x filler */
+ 15625000, /* 7 Normal 1.00x filler */
+ };
+
+ return picos_to_clk(refresh_time_ns[spd_refresh & 0x7]);
+}
+
+
long int
spd_sdram(void)
{
@@ -157,6 +179,10 @@ spd_sdram(void)
unsigned int rank_density;
unsigned int odt_rd_cfg, odt_wr_cfg;
unsigned int odt_cfg, mode_odt_enable;
+ unsigned int refresh_clk;
+#ifdef MPC85xx_DDR_SDRAM_CLK_CNTL
+ unsigned char clk_adjust;
+#endif
unsigned int dqs_cfg;
unsigned char twr_clk, twtr_clk, twr_auto_clk;
unsigned int tCKmin_ps, tCKmax_ps;
@@ -740,38 +766,21 @@ spd_sdram(void)
ddr->sdram_mode_2 = 0;
debug("DDR: sdram_mode_2 = 0x%08x\n", ddr->sdram_mode_2);
-
/*
- * Determine Refresh Rate. Ignore self refresh bit on DDR I.
- * Table from SPD Spec, Byte 12, converted to picoseconds and
- * filled in with "default" normal values.
+ * Determine Refresh Rate.
*/
- {
- unsigned int refresh_clk;
- unsigned int refresh_time_ns[8] = {
- 15625000, /* 0 Normal 1.00x */
- 3900000, /* 1 Reduced .25x */
- 7800000, /* 2 Extended .50x */
- 31300000, /* 3 Extended 2.00x */
- 62500000, /* 4 Extended 4.00x */
- 125000000, /* 5 Extended 8.00x */
- 15625000, /* 6 Normal 1.00x filler */
- 15625000, /* 7 Normal 1.00x filler */
- };
-
- refresh_clk = picos_to_clk(refresh_time_ns[spd.refresh & 0x7]);
+ refresh_clk = determine_refresh_rate(spd.refresh & 0x7);
- /*
- * Set BSTOPRE to 0x100 for page mode
- * If auto-charge is used, set BSTOPRE = 0
- */
- ddr->sdram_interval =
- (0
- | (refresh_clk & 0x3fff) << 16
- | 0x100
- );
- debug("DDR: sdram_interval = 0x%08x\n", ddr->sdram_interval);
- }
+ /*
+ * Set BSTOPRE to 0x100 for page mode
+ * If auto-charge is used, set BSTOPRE = 0
+ */
+ ddr->sdram_interval =
+ (0
+ | (refresh_clk & 0x3fff) << 16
+ | 0x100
+ );
+ debug("DDR: sdram_interval = 0x%08x\n", ddr->sdram_interval);
/*
* Is this an ECC DDR chip?
@@ -835,28 +844,23 @@ spd_sdram(void)
#ifdef MPC85xx_DDR_SDRAM_CLK_CNTL
- {
- unsigned char clk_adjust;
-
- /*
- * Setup the clock control.
- * SDRAM_CLK_CNTL[0] = Source synchronous enable == 1
- * SDRAM_CLK_CNTL[5-7] = Clock Adjust
- * 0110 3/4 cycle late
- * 0111 7/8 cycle late
- */
- if (spd.mem_type == SPD_MEMTYPE_DDR) {
- clk_adjust = 0x6;
- } else {
- clk_adjust = 0x7;
- }
+ /*
+ * Setup the clock control.
+ * SDRAM_CLK_CNTL[0] = Source synchronous enable == 1
+ * SDRAM_CLK_CNTL[5-7] = Clock Adjust
+ * 0110 3/4 cycle late
+ * 0111 7/8 cycle late
+ */
+ if (spd.mem_type == SPD_MEMTYPE_DDR)
+ clk_adjust = 0x6;
+ else
+ clk_adjust = 0x7;
- ddr->sdram_clk_cntl = (0
+ ddr->sdram_clk_cntl = (0
| 0x80000000
| (clk_adjust << 23)
);
- debug("DDR: sdram_clk_cntl = 0x%08x\n", ddr->sdram_clk_cntl);
- }
+ debug("DDR: sdram_clk_cntl = 0x%08x\n", ddr->sdram_clk_cntl);
#endif
/*
@@ -1081,26 +1085,16 @@ ddr_enable_ecc(unsigned int dram_size)
}
}
- /* 8K */
- dma_xfer((uint *)0x2000, 0x2000, (uint *)0);
- /* 16K */
- dma_xfer((uint *)0x4000, 0x4000, (uint *)0);
- /* 32K */
- dma_xfer((uint *)0x8000, 0x8000, (uint *)0);
- /* 64K */
- dma_xfer((uint *)0x10000, 0x10000, (uint *)0);
- /* 128k */
- dma_xfer((uint *)0x20000, 0x20000, (uint *)0);
- /* 256k */
- dma_xfer((uint *)0x40000, 0x40000, (uint *)0);
- /* 512k */
- dma_xfer((uint *)0x80000, 0x80000, (uint *)0);
- /* 1M */
- dma_xfer((uint *)0x100000, 0x100000, (uint *)0);
- /* 2M */
- dma_xfer((uint *)0x200000, 0x200000, (uint *)0);
- /* 4M */
- dma_xfer((uint *)0x400000, 0x400000, (uint *)0);
+ dma_xfer((uint *)0x002000, 0x002000, (uint *)0); /* 8K */
+ dma_xfer((uint *)0x004000, 0x004000, (uint *)0); /* 16K */
+ dma_xfer((uint *)0x008000, 0x008000, (uint *)0); /* 32K */
+ dma_xfer((uint *)0x010000, 0x010000, (uint *)0); /* 64K */
+ dma_xfer((uint *)0x020000, 0x020000, (uint *)0); /* 128k */
+ dma_xfer((uint *)0x040000, 0x040000, (uint *)0); /* 256k */
+ dma_xfer((uint *)0x080000, 0x080000, (uint *)0); /* 512k */
+ dma_xfer((uint *)0x100000, 0x100000, (uint *)0); /* 1M */
+ dma_xfer((uint *)0x200000, 0x200000, (uint *)0); /* 2M */
+ dma_xfer((uint *)0x400000, 0x400000, (uint *)0); /* 4M */
for (i = 1; i < dram_size / 0x800000; i++) {
dma_xfer((uint *)(0x800000*i), 0x800000, (uint *)0);
diff --git a/cpu/mpc86xx/Makefile b/cpu/mpc86xx/Makefile
new file mode 100644
index 0000000..fffcfd2
--- /dev/null
+++ b/cpu/mpc86xx/Makefile
@@ -0,0 +1,51 @@
+#
+# (C) Copyright 2002,2003 Motorola Inc.
+# Xianghua Xiao,X.Xiao@motorola.com
+#
+# (C) Copyright 2004 Freescale Semiconductor. (MC86xx Port)
+# Jeff Brown
+# 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$(CPU).a
+
+START = start.o #resetvec.o
+SOBJS = cache.o
+COBJS = traps.o cpu.o cpu_init.o speed.o interrupts.o \
+ pci.o pcie_indirect.o spd_sdram.o
+
+SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
+START := $(addprefix $(obj),$(START))
+
+all: $(obj).depend $(START) $(LIB)
+
+$(LIB): $(OBJS)
+ $(AR) $(ARFLAGS) $@ $(ASOBJS) $(OBJS)
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/cpu/mpc86xx/cache.S b/cpu/mpc86xx/cache.S
new file mode 100644
index 0000000..f316b3e
--- /dev/null
+++ b/cpu/mpc86xx/cache.S
@@ -0,0 +1,374 @@
+#include <config.h>
+#include <mpc86xx.h>
+#include <version.h>
+
+#include <ppc_asm.tmpl>
+#include <ppc_defs.h>
+
+#include <asm/cache.h>
+#include <asm/mmu.h>
+
+#ifndef CACHE_LINE_SIZE
+# define CACHE_LINE_SIZE L1_CACHE_BYTES
+#endif
+
+#if CACHE_LINE_SIZE == 128
+#define LG_CACHE_LINE_SIZE 7
+#elif CACHE_LINE_SIZE == 32
+#define LG_CACHE_LINE_SIZE 5
+#elif CACHE_LINE_SIZE == 16
+#define LG_CACHE_LINE_SIZE 4
+#elif CACHE_LINE_SIZE == 8
+#define LG_CACHE_LINE_SIZE 3
+#else
+# error "Invalid cache line size!"
+#endif
+
+/*
+ * Most of this code is taken from 74xx_7xx/cache.S
+ * and then cleaned up a bit
+ */
+
+/*
+ * Invalidate L1 instruction cache.
+ */
+_GLOBAL(invalidate_l1_instruction_cache)
+ /* use invalidate-all bit in HID0 */
+ mfspr r3,HID0
+ ori r3,r3,HID0_ICFI
+ mtspr HID0,r3
+ isync
+ blr
+
+/*
+ * Invalidate L1 data cache.
+ */
+_GLOBAL(invalidate_l1_data_cache)
+ mfspr r3,HID0
+ ori r3,r3,HID0_DCFI
+ mtspr HID0,r3
+ isync
+ blr
+
+/*
+ * Flush data cache.
+ */
+_GLOBAL(flush_data_cache)
+ lis r3,0
+ lis r5,CACHE_LINE_SIZE
+flush:
+ cmp 0,1,r3,r5
+ bge done
+ lwz r5,0(r3)
+ lis r5,CACHE_LINE_SIZE
+ addi r3,r3,0x4
+ b flush
+done:
+ blr
+/*
+ * Write any modified data cache blocks out to memory
+ * and invalidate the corresponding instruction cache blocks.
+ * This is a no-op on the 601.
+ *
+ * flush_icache_range(unsigned long start, unsigned long stop)
+ */
+_GLOBAL(flush_icache_range)
+ li r5,CACHE_LINE_SIZE-1
+ andc r3,r3,r5
+ subf r4,r3,r4
+ add r4,r4,r5
+ srwi. r4,r4,LG_CACHE_LINE_SIZE
+ beqlr
+ mtctr r4
+ mr r6,r3
+1: dcbst 0,r3
+ addi r3,r3,CACHE_LINE_SIZE
+ bdnz 1b
+ sync /* wait for dcbst's to get to ram */
+ mtctr r4
+2: icbi 0,r6
+ addi r6,r6,CACHE_LINE_SIZE
+ bdnz 2b
+ sync /* additional sync needed on g4 */
+ isync
+ blr
+/*
+ * Write any modified data cache blocks out to memory.
+ * Does not invalidate the corresponding cache lines (especially for
+ * any corresponding instruction cache).
+ *
+ * clean_dcache_range(unsigned long start, unsigned long stop)
+ */
+_GLOBAL(clean_dcache_range)
+ li r5,CACHE_LINE_SIZE-1
+ andc r3,r3,r5 /* align r3 down to cache line */
+ subf r4,r3,r4 /* r4 = offset of stop from start of cache line */
+ add r4,r4,r5 /* r4 += cache_line_size-1 */
+ srwi. r4,r4,LG_CACHE_LINE_SIZE /* r4 = number of cache lines to flush */
+ beqlr /* if r4 == 0 return */
+ mtctr r4 /* ctr = r4 */
+
+ sync
+1: dcbst 0,r3
+ addi r3,r3,CACHE_LINE_SIZE
+ bdnz 1b
+ sync /* wait for dcbst's to get to ram */
+ blr
+
+/*
+ * Write any modified data cache blocks out to memory
+ * and invalidate the corresponding instruction cache blocks.
+ *
+ * flush_dcache_range(unsigned long start, unsigned long stop)
+ */
+_GLOBAL(flush_dcache_range)
+ li r5,CACHE_LINE_SIZE-1
+ andc r3,r3,r5
+ subf r4,r3,r4
+ add r4,r4,r5
+ srwi. r4,r4,LG_CACHE_LINE_SIZE
+ beqlr
+ mtctr r4
+
+ sync
+1: dcbf 0,r3
+ addi r3,r3,CACHE_LINE_SIZE
+ bdnz 1b
+ sync /* wait for dcbf's to get to ram */
+ blr
+
+/*
+ * Like above, but invalidate the D-cache. This is used by the 8xx
+ * to invalidate the cache so the PPC core doesn't get stale data
+ * from the CPM (no cache snooping here :-).
+ *
+ * invalidate_dcache_range(unsigned long start, unsigned long stop)
+ */
+_GLOBAL(invalidate_dcache_range)
+ li r5,CACHE_LINE_SIZE-1
+ andc r3,r3,r5
+ subf r4,r3,r4
+ add r4,r4,r5
+ srwi. r4,r4,LG_CACHE_LINE_SIZE
+ beqlr
+ mtctr r4
+
+ sync
+1: dcbi 0,r3
+ addi r3,r3,CACHE_LINE_SIZE
+ bdnz 1b
+ sync /* wait for dcbi's to get to ram */
+ blr
+
+/*
+ * Flush a particular page from the data cache to RAM.
+ * Note: this is necessary because the instruction cache does *not*
+ * snoop from the data cache.
+ *
+ * void __flush_page_to_ram(void *page)
+ */
+_GLOBAL(__flush_page_to_ram)
+ rlwinm r3,r3,0,0,19 /* Get page base address */
+ li r4,4096/CACHE_LINE_SIZE /* Number of lines in a page */
+ mtctr r4
+ mr r6,r3
+0: dcbst 0,r3 /* Write line to ram */
+ addi r3,r3,CACHE_LINE_SIZE
+ bdnz 0b
+ sync
+ mtctr r4
+1: icbi 0,r6
+ addi r6,r6,CACHE_LINE_SIZE
+ bdnz 1b
+ sync
+ isync
+ blr
+
+/*
+ * Flush a particular page from the instruction cache.
+ * Note: this is necessary because the instruction cache does *not*
+ * snoop from the data cache.
+ *
+ * void __flush_icache_page(void *page)
+ */
+_GLOBAL(__flush_icache_page)
+ li r4,4096/CACHE_LINE_SIZE /* Number of lines in a page */
+ mtctr r4
+1: icbi 0,r3
+ addi r3,r3,CACHE_LINE_SIZE
+ bdnz 1b
+ sync
+ isync
+ blr
+
+/*
+ * Clear a page using the dcbz instruction, which doesn't cause any
+ * memory traffic (except to write out any cache lines which get
+ * displaced). This only works on cacheable memory.
+ */
+_GLOBAL(clear_page)
+ li r0,4096/CACHE_LINE_SIZE
+ mtctr r0
+1: dcbz 0,r3
+ addi r3,r3,CACHE_LINE_SIZE
+ bdnz 1b
+ blr
+
+/*
+ * Enable L1 Instruction cache
+ */
+_GLOBAL(icache_enable)
+ mfspr r3, HID0
+ li r5, HID0_ICFI|HID0_ILOCK
+ andc r3, r3, r5
+ ori r3, r3, HID0_ICE
+ ori r5, r3, HID0_ICFI
+ mtspr HID0, r5
+ mtspr HID0, r3
+ isync
+ blr
+
+/*
+ * Disable L1 Instruction cache
+ */
+_GLOBAL(icache_disable)
+ mfspr r3, HID0
+ li r5, 0
+ ori r5, r5, HID0_ICE
+ andc r3, r3, r5
+ mtspr HID0, r3
+ isync
+ blr
+
+/*
+ * Is instruction cache enabled?
+ */
+_GLOBAL(icache_status)
+ mfspr r3, HID0
+ andi. r3, r3, HID0_ICE
+ blr
+
+
+_GLOBAL(l1dcache_enable)
+ mfspr r3, HID0
+ li r5, HID0_DCFI|HID0_DLOCK
+ andc r3, r3, r5
+ mtspr HID0, r3 /* no invalidate, unlock */
+ ori r3, r3, HID0_DCE
+ ori r5, r3, HID0_DCFI
+ mtspr HID0, r5 /* enable + invalidate */
+ mtspr HID0, r3 /* enable */
+ sync
+ blr
+
+/*
+ * Enable data cache(s) - L1 and optionally L2
+ * Calls l2cache_enable. LR saved in r5
+ */
+_GLOBAL(dcache_enable)
+ mfspr r3, HID0
+ li r5, HID0_DCFI|HID0_DLOCK
+ andc r3, r3, r5
+ mtspr HID0, r3 /* no invalidate, unlock */
+ ori r3, r3, HID0_DCE
+ ori r5, r3, HID0_DCFI
+ mtspr HID0, r5 /* enable + invalidate */
+ mtspr HID0, r3 /* enable */
+ sync
+#ifdef CFG_L2
+ mflr r5
+ bl l2cache_enable /* uses r3 and r4 */
+ sync
+ mtlr r5
+#endif
+ blr
+
+
+/*
+ * Disable data cache(s) - L1 and optionally L2
+ * Calls flush_data_cache and l2cache_disable_no_flush.
+ * LR saved in r4
+ */
+_GLOBAL(dcache_disable)
+ mflr r4 /* save link register */
+ bl flush_data_cache /* uses r3 and r5 */
+ sync
+ mfspr r3, HID0
+ li r5, HID0_DCFI|HID0_DLOCK
+ andc r3, r3, r5
+ mtspr HID0, r3 /* no invalidate, unlock */
+ li r5, HID0_DCE|HID0_DCFI
+ andc r3, r3, r5 /* no enable, no invalidate */
+ mtspr HID0, r3
+ sync
+#ifdef CFG_L2
+ bl l2cache_disable_no_flush /* uses r3 */
+#endif
+ mtlr r4 /* restore link register */
+ blr
+
+/*
+ * Is data cache enabled?
+ */
+_GLOBAL(dcache_status)
+ mfspr r3, HID0
+ andi. r3, r3, HID0_DCE
+ blr
+
+/*
+ * Invalidate L2 cache using L2I, assume L2 is enabled
+ */
+_GLOBAL(l2cache_invalidate)
+ mfspr r3, l2cr
+ rlwinm. r3, r3, 0, 0, 0
+ beq 1f
+
+ mfspr r3, l2cr
+ rlwinm r3, r3, 0, 1, 31
+
+#ifdef CONFIG_ALTIVEC
+ dssall
+#endif
+ sync
+ mtspr l2cr, r3
+ sync
+1: mfspr r3, l2cr
+ oris r3, r3, L2CR_L2I@h
+ mtspr l2cr, r3
+
+invl2:
+ mfspr r3, l2cr
+ andi. r3, r3, L2CR_L2I@h
+ bne invl2
+ blr
+
+/*
+ * Enable L2 cache
+ * Calls l2cache_invalidate. LR is saved in r4
+ */
+_GLOBAL(l2cache_enable)
+ mflr r4 /* save link register */
+ bl l2cache_invalidate /* uses r3 */
+ sync
+ lis r3, L2_ENABLE@h
+ ori r3, r3, L2_ENABLE@l
+ mtspr l2cr, r3
+ isync
+ mtlr r4 /* restore link register */
+ blr
+
+/*
+ * Disable L2 cache
+ * Calls flush_data_cache. LR is saved in r4
+ */
+_GLOBAL(l2cache_disable)
+ mflr r4 /* save link register */
+ bl flush_data_cache /* uses r3 and r5 */
+ sync
+ mtlr r4 /* restore link register */
+l2cache_disable_no_flush: /* provide way to disable L2 w/o flushing */
+ lis r3, L2_INIT@h
+ ori r3, r3, L2_INIT@l
+ mtspr l2cr, r3
+ isync
+ blr
diff --git a/cpu/mpc86xx/config.mk b/cpu/mpc86xx/config.mk
new file mode 100644
index 0000000..3c54f4a
--- /dev/null
+++ b/cpu/mpc86xx/config.mk
@@ -0,0 +1,26 @@
+#
+# (C) Copyright 2004 Freescale Semiconductor.
+# Jeff Brown
+#
+# 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
+#
+
+PLATFORM_RELFLAGS += -fPIC -ffixed-r14 -meabi
+
+PLATFORM_CPPFLAGS += -DCONFIG_MPC86xx -ffixed-r2 -ffixed-r29 -mstring
diff --git a/cpu/mpc86xx/cpu.c b/cpu/mpc86xx/cpu.c
new file mode 100644
index 0000000..551b243
--- /dev/null
+++ b/cpu/mpc86xx/cpu.c
@@ -0,0 +1,308 @@
+/*
+ * Copyright 2006 Freescale Semiconductor
+ * Jeff Brown
+ * Srikanth Srinivasan (srikanth.srinivasan@freescale.com)
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <watchdog.h>
+#include <command.h>
+#include <asm/cache.h>
+#include <mpc86xx.h>
+
+#if defined(CONFIG_OF_FLAT_TREE)
+#include <ft_build.h>
+#endif
+
+#ifdef CONFIG_MPC8641HPCN
+extern void mpc8641_reset_board(cmd_tbl_t *cmdtp, int flag,
+ int argc, char *argv[]);
+#endif
+
+
+int
+checkcpu(void)
+{
+ sys_info_t sysinfo;
+ uint pvr, svr;
+ uint ver;
+ uint major, minor;
+ uint lcrr; /* local bus clock ratio register */
+ uint clkdiv; /* clock divider portion of lcrr */
+
+ puts("Freescale PowerPC\n");
+
+ pvr = get_pvr();
+ ver = PVR_VER(pvr);
+ major = PVR_MAJ(pvr);
+ minor = PVR_MIN(pvr);
+
+ puts("CPU:\n");
+ puts(" Core: ");
+
+ switch (ver) {
+ case PVR_VER(PVR_86xx):
+ puts("E600");
+ break;
+ default:
+ puts("Unknown");
+ break;
+ }
+ printf(", Version: %d.%d, (0x%08x)\n", major, minor, pvr);
+
+ svr = get_svr();
+ ver = SVR_VER(svr);
+ major = SVR_MAJ(svr);
+ minor = SVR_MIN(svr);
+
+ puts(" System: ");
+ switch (ver) {
+ case SVR_8641:
+ if (SVR_SUBVER(svr) == 1) {
+ puts("8641D");
+ } else {
+ puts("8641");
+ }
+ break;
+ default:
+ puts("Unknown");
+ break;
+ }
+ printf(", Version: %d.%d, (0x%08x)\n", major, minor, svr);
+
+ get_sys_info(&sysinfo);
+
+ puts(" Clocks: ");
+ printf("CPU:%4lu MHz, ", sysinfo.freqProcessor / 1000000);
+ printf("MPX:%4lu MHz, ", sysinfo.freqSystemBus / 1000000);
+ printf("DDR:%4lu MHz, ", sysinfo.freqSystemBus / 2000000);
+
+#if defined(CFG_LBC_LCRR)
+ lcrr = CFG_LBC_LCRR;
+#else
+ {
+ volatile immap_t *immap = (immap_t *) CFG_IMMR;
+ volatile ccsr_lbc_t *lbc = &immap->im_lbc;
+
+ lcrr = lbc->lcrr;
+ }
+#endif
+ clkdiv = lcrr & 0x0f;
+ if (clkdiv == 2 || clkdiv == 4 || clkdiv == 8) {
+ printf("LBC:%4lu MHz\n",
+ sysinfo.freqSystemBus / 1000000 / clkdiv);
+ } else {
+ printf(" LBC: unknown (lcrr: 0x%08x)\n", lcrr);
+ }
+
+ puts(" L2: ");
+ if (get_l2cr() & 0x80000000)
+ puts("Enabled\n");
+ else
+ puts("Disabled\n");
+
+ return 0;
+}
+
+
+static inline void
+soft_restart(unsigned long addr)
+{
+#ifndef CONFIG_MPC8641HPCN
+
+ /*
+ * SRR0 has system reset vector, SRR1 has default MSR value
+ * rfi restores MSR from SRR1 and sets the PC to the SRR0 value
+ */
+
+ __asm__ __volatile__ ("mtspr 26, %0" :: "r" (addr));
+ __asm__ __volatile__ ("li 4, (1 << 6)" ::: "r4");
+ __asm__ __volatile__ ("mtspr 27, 4");
+ __asm__ __volatile__ ("rfi");
+
+#else /* CONFIG_MPC8641HPCN */
+
+ out8(PIXIS_BASE + PIXIS_RST, 0);
+
+#endif /* !CONFIG_MPC8641HPCN */
+
+ while (1) ; /* not reached */
+}
+
+
+/*
+ * No generic way to do board reset. Simply call soft_reset.
+ */
+void
+do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+#ifndef CONFIG_MPC8641HPCN
+
+#ifdef CFG_RESET_ADDRESS
+ ulong addr = CFG_RESET_ADDRESS;
+#else
+ /*
+ * note: when CFG_MONITOR_BASE points to a RAM address,
+ * CFG_MONITOR_BASE - sizeof (ulong) is usually a valid
+ * address. Better pick an address known to be invalid on your
+ * system and assign it to CFG_RESET_ADDRESS.
+ */
+ ulong addr = CFG_MONITOR_BASE - sizeof(ulong);
+#endif
+
+ /* flush and disable I/D cache */
+ __asm__ __volatile__ ("mfspr 3, 1008" ::: "r3");
+ __asm__ __volatile__ ("ori 5, 5, 0xcc00" ::: "r5");
+ __asm__ __volatile__ ("ori 4, 3, 0xc00" ::: "r4");
+ __asm__ __volatile__ ("andc 5, 3, 5" ::: "r5");
+ __asm__ __volatile__ ("sync");
+ __asm__ __volatile__ ("mtspr 1008, 4");
+ __asm__ __volatile__ ("isync");
+ __asm__ __volatile__ ("sync");
+ __asm__ __volatile__ ("mtspr 1008, 5");
+ __asm__ __volatile__ ("isync");
+ __asm__ __volatile__ ("sync");
+
+ soft_restart(addr);
+
+#else /* CONFIG_MPC8641HPCN */
+
+ mpc8641_reset_board(cmdtp, flag, argc, argv);
+
+#endif /* !CONFIG_MPC8641HPCN */
+
+ while (1) ; /* not reached */
+}
+
+
+/*
+ * Get timebase clock frequency
+ */
+unsigned long
+get_tbclk(void)
+{
+ sys_info_t sys_info;
+
+ get_sys_info(&sys_info);
+ return (sys_info.freqSystemBus + 3L) / 4L;
+}
+
+
+#if defined(CONFIG_WATCHDOG)
+void
+watchdog_reset(void)
+{
+}
+#endif /* CONFIG_WATCHDOG */
+
+
+#if defined(CONFIG_DDR_ECC)
+void
+dma_init(void)
+{
+ volatile immap_t *immap = (immap_t *) CFG_IMMR;
+ volatile ccsr_dma_t *dma = &immap->im_dma;
+
+ dma->satr0 = 0x00040000;
+ dma->datr0 = 0x00040000;
+ asm("sync; isync");
+}
+
+uint
+dma_check(void)
+{
+ volatile immap_t *immap = (immap_t *) CFG_IMMR;
+ volatile ccsr_dma_t *dma = &immap->im_dma;
+ volatile uint status = dma->sr0;
+
+ /* While the channel is busy, spin */
+ while ((status & 4) == 4) {
+ status = dma->sr0;
+ }
+
+ if (status != 0) {
+ printf("DMA Error: status = %x\n", status);
+ }
+ return status;
+}
+
+int
+dma_xfer(void *dest, uint count, void *src)
+{
+ volatile immap_t *immap = (immap_t *) CFG_IMMR;
+ volatile ccsr_dma_t *dma = &immap->im_dma;
+
+ dma->dar0 = (uint) dest;
+ dma->sar0 = (uint) src;
+ dma->bcr0 = count;
+ dma->mr0 = 0xf000004;
+ asm("sync;isync");
+ dma->mr0 = 0xf000005;
+ asm("sync;isync");
+ return dma_check();
+}
+
+#endif /* CONFIG_DDR_ECC */
+
+
+#ifdef CONFIG_OF_FLAT_TREE
+void
+ft_cpu_setup(void *blob, bd_t *bd)
+{
+ u32 *p;
+ ulong clock;
+ int len;
+
+ clock = bd->bi_busfreq;
+ p = ft_get_prop(blob, "/cpus/" OF_CPU "/bus-frequency", &len);
+ if (p != NULL)
+ *p = cpu_to_be32(clock);
+
+ p = ft_get_prop(blob, "/" OF_SOC "/serial@4500/clock-frequency", &len);
+ if (p != NULL)
+ *p = cpu_to_be32(clock);
+
+ p = ft_get_prop(blob, "/" OF_SOC "/serial@4600/clock-frequency", &len);
+ if (p != NULL)
+ *p = cpu_to_be32(clock);
+
+#if defined(CONFIG_MPC86XX_TSEC1)
+ p = ft_get_prop(blob, "/" OF_SOC "/ethernet@24000/mac-address", &len);
+ memcpy(p, bd->bi_enetaddr, 6);
+#endif
+
+#if defined(CONFIG_MPC86XX_TSEC2)
+ p = ft_get_prop(blob, "/" OF_SOC "/ethernet@25000/mac-address", &len);
+ memcpy(p, bd->bi_enet1addr, 6);
+#endif
+
+#if defined(CONFIG_MPC86XX_TSEC3)
+ p = ft_get_prop(blob, "/" OF_SOC "/ethernet@26000/mac-address", &len);
+ memcpy(p, bd->bi_enet2addr, 6);
+#endif
+
+#if defined(CONFIG_MPC86XX_TSEC4)
+ p = ft_get_prop(blob, "/" OF_SOC "/ethernet@27000/mac-address", &len);
+ memcpy(p, bd->bi_enet3addr, 6);
+#endif
+
+}
+#endif
diff --git a/cpu/mpc86xx/cpu_init.c b/cpu/mpc86xx/cpu_init.c
new file mode 100644
index 0000000..4673d05
--- /dev/null
+++ b/cpu/mpc86xx/cpu_init.c
@@ -0,0 +1,117 @@
+/*
+ * Copyright 2004 Freescale Semiconductor.
+ * Jeff Brown
+ * Srikanth Srinivasan (srikanth.srinivasan@freescale.com)
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/*
+ * cpu_init.c - low level cpu init
+ */
+
+#include <common.h>
+#include <mpc86xx.h>
+
+/*
+ * Breathe some life into the CPU...
+ *
+ * Set up the memory map
+ * initialize a bunch of registers
+ */
+
+void cpu_init_f(void)
+{
+ DECLARE_GLOBAL_DATA_PTR;
+ volatile immap_t *immap = (immap_t *)CFG_IMMR;
+ volatile ccsr_lbc_t *memctl = &immap->im_lbc;
+
+ /* Pointer is writable since we allocated a register for it */
+ gd = (gd_t *) (CFG_INIT_RAM_ADDR + CFG_GBL_DATA_OFFSET);
+
+ /* Clear initial global data */
+ memset ((void *) gd, 0, sizeof (gd_t));
+
+ /* Map banks 0 and 1 to the FLASH banks 0 and 1 at preliminary
+ * addresses - these have to be modified later when FLASH size
+ * has been determined
+ */
+
+#if defined(CFG_OR0_REMAP)
+ memctl->or0 = CFG_OR0_REMAP;
+#endif
+#if defined(CFG_OR1_REMAP)
+ memctl->or1 = CFG_OR1_REMAP;
+#endif
+
+ /* now restrict to preliminary range */
+#if defined(CFG_BR0_PRELIM) && defined(CFG_OR0_PRELIM)
+ memctl->br0 = CFG_BR0_PRELIM;
+ memctl->or0 = CFG_OR0_PRELIM;
+#endif
+
+#if defined(CFG_BR1_PRELIM) && defined(CFG_OR1_PRELIM)
+ memctl->or1 = CFG_OR1_PRELIM;
+ memctl->br1 = CFG_BR1_PRELIM;
+#endif
+
+#if defined(CFG_BR2_PRELIM) && defined(CFG_OR2_PRELIM)
+ memctl->or2 = CFG_OR2_PRELIM;
+ memctl->br2 = CFG_BR2_PRELIM;
+#endif
+
+#if defined(CFG_BR3_PRELIM) && defined(CFG_OR3_PRELIM)
+ memctl->or3 = CFG_OR3_PRELIM;
+ memctl->br3 = CFG_BR3_PRELIM;
+#endif
+
+#if defined(CFG_BR4_PRELIM) && defined(CFG_OR4_PRELIM)
+ memctl->or4 = CFG_OR4_PRELIM;
+ memctl->br4 = CFG_BR4_PRELIM;
+#endif
+
+#if defined(CFG_BR5_PRELIM) && defined(CFG_OR5_PRELIM)
+ memctl->or5 = CFG_OR5_PRELIM;
+ memctl->br5 = CFG_BR5_PRELIM;
+#endif
+
+#if defined(CFG_BR6_PRELIM) && defined(CFG_OR6_PRELIM)
+ memctl->or6 = CFG_OR6_PRELIM;
+ memctl->br6 = CFG_BR6_PRELIM;
+#endif
+
+#if defined(CFG_BR7_PRELIM) && defined(CFG_OR7_PRELIM)
+ memctl->or7 = CFG_OR7_PRELIM;
+ memctl->br7 = CFG_BR7_PRELIM;
+#endif
+
+ /* enable the timebase bit in HID0 */
+ set_hid0(get_hid0() | 0x4000000);
+
+ /* enable SYNCBE | ABE bits in HID1 */
+ set_hid1(get_hid1() | 0x00000C00);
+}
+
+/*
+ * initialize higher level parts of CPU like timers
+ */
+int cpu_init_r(void)
+{
+ return 0;
+}
diff --git a/cpu/mpc86xx/interrupts.c b/cpu/mpc86xx/interrupts.c
new file mode 100644
index 0000000..1df6cdc
--- /dev/null
+++ b/cpu/mpc86xx/interrupts.c
@@ -0,0 +1,204 @@
+/*
+ * (C) Copyright 2000-2002
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * (C) Copyright 2002 (440 port)
+ * Scott McNutt, Artesyn Communication Producs, smcnutt@artsyncp.com
+ *
+ * (C) Copyright 2003 Motorola Inc. (MPC85xx port)
+ * Xianghua Xiao (X.Xiao@motorola.com)
+ *
+ * (C) Copyright 2004 Freescale Semiconductor. (MPC86xx Port)
+ * Jeff Brown
+ * Srikanth Srinivasan (srikanth.srinivasan@freescale.com)
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <mpc86xx.h>
+#include <command.h>
+#include <asm/processor.h>
+#include <ppc_asm.tmpl>
+
+unsigned long decrementer_count; /* count value for 1e6/HZ microseconds */
+unsigned long timestamp;
+
+
+static __inline__ unsigned long get_msr(void)
+{
+ unsigned long msr;
+
+ asm volatile ("mfmsr %0":"=r" (msr):);
+
+ return msr;
+}
+
+static __inline__ void set_msr(unsigned long msr)
+{
+ asm volatile ("mtmsr %0"::"r" (msr));
+}
+
+static __inline__ unsigned long get_dec(void)
+{
+ unsigned long val;
+
+ asm volatile ("mfdec %0":"=r" (val):);
+
+ return val;
+}
+
+static __inline__ void set_dec(unsigned long val)
+{
+ if (val)
+ asm volatile ("mtdec %0"::"r" (val));
+}
+
+/* interrupt is not supported yet */
+int interrupt_init_cpu(unsigned *decrementer_count)
+{
+ return 0;
+}
+
+int interrupt_init(void)
+{
+ int ret;
+
+ /* call cpu specific function from $(CPU)/interrupts.c */
+ ret = interrupt_init_cpu(&decrementer_count);
+
+ if (ret)
+ return ret;
+
+ decrementer_count = get_tbclk() / CFG_HZ;
+ debug("interrupt init: tbclk() = %d MHz, decrementer_count = %d\n",
+ (get_tbclk() / 1000000),
+ decrementer_count);
+
+ set_dec(decrementer_count);
+
+ set_msr(get_msr() | MSR_EE);
+
+ debug("MSR = 0x%08lx, Decrementer reg = 0x%08lx\n",
+ get_msr(),
+ get_dec());
+
+ return 0;
+}
+
+void enable_interrupts(void)
+{
+ set_msr(get_msr() | MSR_EE);
+}
+
+/* returns flag if MSR_EE was set before */
+int disable_interrupts(void)
+{
+ ulong msr = get_msr();
+
+ set_msr(msr & ~MSR_EE);
+ return (msr & MSR_EE) != 0;
+}
+
+void increment_timestamp(void)
+{
+ timestamp++;
+}
+
+/*
+ * timer_interrupt - gets called when the decrementer overflows,
+ * with interrupts disabled.
+ * Trivial implementation - no need to be really accurate.
+ */
+void timer_interrupt_cpu(struct pt_regs *regs)
+{
+ /* nothing to do here */
+}
+
+void timer_interrupt(struct pt_regs *regs)
+{
+ /* call cpu specific function from $(CPU)/interrupts.c */
+ timer_interrupt_cpu(regs);
+
+ timestamp++;
+
+ ppcDcbf(&timestamp);
+
+ /* Restore Decrementer Count */
+ set_dec(decrementer_count);
+
+#if defined(CONFIG_WATCHDOG) || defined (CONFIG_HW_WATCHDOG)
+ if ((timestamp % (CFG_WATCHDOG_FREQ)) == 0)
+ WATCHDOG_RESET();
+#endif /* CONFIG_WATCHDOG || CONFIG_HW_WATCHDOG */
+
+#ifdef CONFIG_STATUS_LED
+ status_led_tick(timestamp);
+#endif /* CONFIG_STATUS_LED */
+
+#ifdef CONFIG_SHOW_ACTIVITY
+ board_show_activity(timestamp);
+#endif /* CONFIG_SHOW_ACTIVITY */
+
+}
+
+void reset_timer(void)
+{
+ timestamp = 0;
+}
+
+ulong get_timer(ulong base)
+{
+ return timestamp - base;
+}
+
+void set_timer(ulong t)
+{
+ timestamp = t;
+}
+
+/*
+ * Install and free a interrupt handler. Not implemented yet.
+ */
+
+void irq_install_handler(int vec, interrupt_handler_t *handler, void *arg)
+{
+}
+
+void irq_free_handler(int vec)
+{
+}
+
+/*
+ * irqinfo - print information about PCI devices,not implemented.
+ */
+int do_irqinfo(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+ printf("\nInterrupt-unsupported:\n");
+
+ return 0;
+}
+
+/*
+ * Handle external interrupts
+ */
+void external_interrupt(struct pt_regs *regs)
+{
+ puts("external_interrupt (oops!)\n");
+}
diff --git a/cpu/mpc86xx/pci.c b/cpu/mpc86xx/pci.c
new file mode 100644
index 0000000..b86548d
--- /dev/null
+++ b/cpu/mpc86xx/pci.c
@@ -0,0 +1,146 @@
+/*
+ * Copyright (C) Freescale Semiconductor,Inc.
+ * 2005, 2006. All rights reserved.
+ *
+ * Ed Swarthout (ed.swarthout@freescale.com)
+ * Jason Jin (Jason.jin@freescale.com)
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/*
+ * PCIE Configuration space access support for PCIE Bridge
+ */
+#include <common.h>
+#include <pci.h>
+
+#if defined(CONFIG_PCI)
+void
+pci_mpc86xx_init(struct pci_controller *hose)
+{
+ volatile immap_t *immap = (immap_t *) CFG_CCSRBAR;
+ volatile ccsr_pex_t *pcie1 = &immap->im_pex1;
+ u16 temp16;
+ u32 temp32;
+
+ volatile ccsr_gur_t *gur = &immap->im_gur;
+ uint host1_agent = (gur->porbmsr & MPC86xx_PORBMSR_HA) >> 17;
+ uint pcie1_host = (host1_agent == 2) || (host1_agent == 3);
+ uint pcie1_agent = (host1_agent == 0) || (host1_agent == 1);
+ uint devdisr = gur->devdisr;
+ uint io_sel = (gur->pordevsr & MPC86xx_PORDEVSR_IO_SEL) >> 16;
+
+ if ((io_sel == 2 || io_sel == 3 || io_sel == 5 || io_sel == 6 ||
+ io_sel == 7 || io_sel == 0xf)
+ && !(devdisr & MPC86xx_DEVDISR_PCIEX1)) {
+ printf("PCI-EXPRESS 1: Configured as %s \n",
+ pcie1_agent ? "Agent" : "Host");
+ if (pcie1_agent)
+ return; /*Don't scan bus when configured as agent */
+ printf(" Scanning PCIE bus");
+ debug("0x%08x=0x%08x ",
+ &pcie1->pme_msg_det,
+ pcie1->pme_msg_det);
+ if (pcie1->pme_msg_det) {
+ pcie1->pme_msg_det = 0xffffffff;
+ debug(" with errors. Clearing. Now 0x%08x",
+ pcie1->pme_msg_det);
+ }
+ debug("\n");
+ } else {
+ printf("PCI-EXPRESS 1 disabled!\n");
+ return;
+ }
+
+ /*
+ * Set first_bus=0 only skipped B0:D0:F0 which is
+ * a reserved device in M1575, but make it easy for
+ * most of the scan process.
+ */
+ hose->first_busno = 0x00;
+ hose->last_busno = 0xfe;
+
+ pcie_setup_indirect(hose, (CFG_IMMR + 0x8000), (CFG_IMMR + 0x8004));
+
+ pci_hose_read_config_word(hose,
+ PCI_BDF(0, 0, 0), PCI_COMMAND, &temp16);
+ temp16 |= PCI_COMMAND_SERR | PCI_COMMAND_MASTER |
+ PCI_COMMAND_MEMORY | PCI_COMMAND_IO;
+ pci_hose_write_config_word(hose,
+ PCI_BDF(0, 0, 0), PCI_COMMAND, temp16);
+
+ pci_hose_write_config_word(hose, PCI_BDF(0, 0, 0), PCI_STATUS, 0xffff);
+ pci_hose_write_config_byte(hose,
+ PCI_BDF(0, 0, 0), PCI_LATENCY_TIMER, 0x80);
+
+ pci_hose_read_config_dword(hose, PCI_BDF(0, 0, 0), PCI_PRIMARY_BUS,
+ &temp32);
+ temp32 = (temp32 & 0xff000000) | (0xff) | (0x0 << 8) | (0xfe << 16);
+ pci_hose_write_config_dword(hose, PCI_BDF(0, 0, 0), PCI_PRIMARY_BUS,
+ temp32);
+
+ pcie1->powar1 = 0;
+ pcie1->powar2 = 0;
+ pcie1->piwar1 = 0;
+ pcie1->piwar1 = 0;
+
+ pcie1->powbar1 = (CFG_PCI1_MEM_BASE >> 12) & 0x000fffff;
+ pcie1->powar1 = 0x8004401c; /* 512M MEM space */
+ pcie1->potar1 = (CFG_PCI1_MEM_BASE >> 12) & 0x000fffff;
+ pcie1->potear1 = 0x00000000;
+
+ pcie1->powbar2 = (CFG_PCI1_IO_BASE >> 12) & 0x000fffff;
+ pcie1->powar2 = 0x80088017; /* 16M IO space */
+ pcie1->potar2 = 0x00000000;
+ pcie1->potear2 = 0x00000000;
+
+ pcie1->pitar1 = 0x00000000;
+ pcie1->piwbar1 = 0x00000000;
+ /* Enable, Prefetch, Local Mem, * Snoop R/W, 2G */
+ pcie1->piwar1 = 0xa0f5501e;
+
+ pci_set_region(hose->regions + 0,
+ CFG_PCI_MEMORY_BUS,
+ CFG_PCI_MEMORY_PHYS,
+ CFG_PCI_MEMORY_SIZE,
+ PCI_REGION_MEM | PCI_REGION_MEMORY);
+
+ pci_set_region(hose->regions + 1,
+ CFG_PCI1_MEM_BASE,
+ CFG_PCI1_MEM_PHYS,
+ CFG_PCI1_MEM_SIZE,
+ PCI_REGION_MEM);
+
+ pci_set_region(hose->regions + 2,
+ CFG_PCI1_IO_BASE,
+ CFG_PCI1_IO_PHYS,
+ CFG_PCI1_IO_SIZE,
+ PCI_REGION_IO);
+
+ hose->region_count = 3;
+
+ pci_register_hose(hose);
+
+ hose->last_busno = pci_hose_scan(hose);
+ debug("pcie_mpc86xx_init: last_busno %x\n", hose->last_busno);
+ debug("pcie_mpc86xx init: current_busno %x\n ", hose->current_busno);
+
+ printf("....PCIE1 scan & enumeration done\n");
+}
+#endif /* CONFIG_PCI */
diff --git a/cpu/mpc86xx/pcie_indirect.c b/cpu/mpc86xx/pcie_indirect.c
new file mode 100644
index 0000000..b00ad76
--- /dev/null
+++ b/cpu/mpc86xx/pcie_indirect.c
@@ -0,0 +1,199 @@
+/*
+ * Support for indirect PCI bridges.
+ *
+ * Copyright (c) Freescale Semiconductor, Inc.
+ * 2006. All rights reserved.
+ *
+ * Jason Jin <Jason.jin@freescale.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ * partly derived from
+ * arch/powerpc/platforms/86xx/mpc86xx_pcie.c
+ */
+
+#include <common.h>
+
+#ifdef CONFIG_PCI
+
+#include <asm/processor.h>
+#include <asm/io.h>
+#include <pci.h>
+
+#define PCI_CFG_OUT out_be32
+#define PEX_FIX out_be32(hose->cfg_addr+0x4, 0x0400ffff)
+
+static int
+indirect_read_config_pcie(struct pci_controller *hose,
+ pci_dev_t dev,
+ int offset,
+ int len,
+ u32 *val)
+{
+ int bus = PCI_BUS(dev);
+
+ volatile unsigned char *cfg_data;
+ u32 temp;
+
+ PEX_FIX;
+ if (bus == 0xff) {
+ PCI_CFG_OUT(hose->cfg_addr,
+ dev | (offset & 0xfc) | 0x80000001);
+ } else {
+ PCI_CFG_OUT(hose->cfg_addr,
+ dev | (offset & 0xfc) | 0x80000000);
+ }
+ /*
+ * Note: the caller has already checked that offset is
+ * suitably aligned and that len is 1, 2 or 4.
+ */
+ /* ERRATA PCI-Ex 12 - Configuration Address/Data Alignment */
+ cfg_data = hose->cfg_data;
+ PEX_FIX;
+ temp = in_le32((u32 *) cfg_data);
+ switch (len) {
+ case 1:
+ *val = (temp >> (((offset & 3)) * 8)) & 0xff;
+ break;
+ case 2:
+ *val = (temp >> (((offset & 3)) * 8)) & 0xffff;
+ break;
+ default:
+ *val = temp;
+ break;
+ }
+
+ return 0;
+}
+
+static int
+indirect_write_config_pcie(struct pci_controller *hose,
+ pci_dev_t dev,
+ int offset,
+ int len,
+ u32 val)
+{
+ int bus = PCI_BUS(dev);
+ volatile unsigned char *cfg_data;
+ u32 temp;
+
+ PEX_FIX;
+ if (bus == 0xff) {
+ PCI_CFG_OUT(hose->cfg_addr,
+ dev | (offset & 0xfc) | 0x80000001);
+ } else {
+ PCI_CFG_OUT(hose->cfg_addr,
+ dev | (offset & 0xfc) | 0x80000000);
+ }
+
+ /*
+ * Note: the caller has already checked that offset is
+ * suitably aligned and that len is 1, 2 or 4.
+ */
+ /* ERRATA PCI-Ex 12 - Configuration Address/Data Alignment */
+ cfg_data = hose->cfg_data;
+ switch (len) {
+ case 1:
+ PEX_FIX;
+ temp = in_le32((u32 *) cfg_data);
+ temp = (temp & ~(0xff << ((offset & 3) * 8))) |
+ (val << ((offset & 3) * 8));
+ PEX_FIX;
+ out_le32((u32 *) cfg_data, temp);
+ break;
+ case 2:
+ PEX_FIX;
+ temp = in_le32((u32 *) cfg_data);
+ temp = (temp & ~(0xffff << ((offset & 3) * 8)));
+ temp |= (val << ((offset & 3) * 8));
+ PEX_FIX;
+ out_le32((u32 *) cfg_data, temp);
+ break;
+ default:
+ PEX_FIX;
+ out_le32((u32 *) cfg_data, val);
+ break;
+ }
+ PEX_FIX;
+ return 0;
+}
+
+static int
+indirect_read_config_byte_pcie(struct pci_controller *hose,
+ pci_dev_t dev,
+ int offset,
+ u8 *val)
+{
+ u32 val32;
+ indirect_read_config_pcie(hose, dev, offset, 1, &val32);
+ *val = (u8) val32;
+ return 0;
+}
+
+static int
+indirect_read_config_word_pcie(struct pci_controller *hose,
+ pci_dev_t dev,
+ int offset,
+ u16 *val)
+{
+ u32 val32;
+ indirect_read_config_pcie(hose, dev, offset, 2, &val32);
+ *val = (u16) val32;
+ return 0;
+}
+
+static int
+indirect_read_config_dword_pcie(struct pci_controller *hose,
+ pci_dev_t dev,
+ int offset,
+ u32 *val)
+{
+ return indirect_read_config_pcie(hose, dev, offset, 4, val);
+}
+
+static int
+indirect_write_config_byte_pcie(struct pci_controller *hose,
+ pci_dev_t dev,
+ int offset,
+ u8 val)
+{
+ return indirect_write_config_pcie(hose, dev, offset, 1, (u32) val);
+}
+
+static int
+indirect_write_config_word_pcie(struct pci_controller *hose,
+ pci_dev_t dev,
+ int offset,
+ unsigned short val)
+{
+ return indirect_write_config_pcie(hose, dev, offset, 2, (u32) val);
+}
+
+static int
+indirect_write_config_dword_pcie(struct pci_controller *hose,
+ pci_dev_t dev,
+ int offset,
+ u32 val)
+{
+ return indirect_write_config_pcie(hose, dev, offset, 4, val);
+}
+
+void
+pcie_setup_indirect(struct pci_controller *hose, u32 cfg_addr, u32 cfg_data)
+{
+ pci_set_ops(hose,
+ indirect_read_config_byte_pcie,
+ indirect_read_config_word_pcie,
+ indirect_read_config_dword_pcie,
+ indirect_write_config_byte_pcie,
+ indirect_write_config_word_pcie,
+ indirect_write_config_dword_pcie);
+
+ hose->cfg_addr = (unsigned int *)cfg_addr;
+ hose->cfg_data = (unsigned char *)cfg_data;
+}
+
+#endif /* CONFIG_PCI */
diff --git a/cpu/mpc86xx/resetvec.S b/cpu/mpc86xx/resetvec.S
new file mode 100644
index 0000000..9a552f6
--- /dev/null
+++ b/cpu/mpc86xx/resetvec.S
@@ -0,0 +1,2 @@
+ .section .resetvec,"ax"
+ b _start
diff --git a/cpu/mpc86xx/spd_sdram.c b/cpu/mpc86xx/spd_sdram.c
new file mode 100644
index 0000000..b18e822
--- /dev/null
+++ b/cpu/mpc86xx/spd_sdram.c
@@ -0,0 +1,1320 @@
+/*
+ * Copyright 2004 Freescale Semiconductor.
+ * (C) Copyright 2003 Motorola Inc.
+ * Xianghua Xiao (X.Xiao@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 <asm/processor.h>
+#include <i2c.h>
+#include <spd.h>
+#include <asm/mmu.h>
+
+
+#if defined(CONFIG_DDR_ECC) && !defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER)
+extern void dma_init(void);
+extern uint dma_check(void);
+extern int dma_xfer(void *dest, uint count, void *src);
+#endif
+
+#ifdef CONFIG_SPD_EEPROM
+
+#ifndef CFG_READ_SPD
+#define CFG_READ_SPD i2c_read
+#endif
+
+/*
+ * Only one of the following three should be 1; others should be 0
+ * By default the cache line interleaving is selected if
+ * the CONFIG_DDR_INTERLEAVE flag is defined
+ */
+#define CFG_PAGE_INTERLEAVING 0
+#define CFG_BANK_INTERLEAVING 0
+#define CFG_SUPER_BANK_INTERLEAVING 0
+
+/*
+ * Convert picoseconds into clock cycles (rounding up if needed).
+ */
+
+int
+picos_to_clk(int picos)
+{
+ int clks;
+
+ clks = picos / (2000000000 / (get_bus_freq(0) / 1000));
+ if (picos % (2000000000 / (get_bus_freq(0) / 1000)) != 0) {
+ clks++;
+ }
+
+ return clks;
+}
+
+
+/*
+ * Calculate the Density of each Physical Rank.
+ * Returned size is in bytes.
+ *
+ * Study these table from Byte 31 of JEDEC SPD Spec.
+ *
+ * DDR I DDR II
+ * Bit Size Size
+ * --- ----- ------
+ * 7 high 512MB 512MB
+ * 6 256MB 256MB
+ * 5 128MB 128MB
+ * 4 64MB 16GB
+ * 3 32MB 8GB
+ * 2 16MB 4GB
+ * 1 2GB 2GB
+ * 0 low 1GB 1GB
+ *
+ * Reorder Table to be linear by stripping the bottom
+ * 2 or 5 bits off and shifting them up to the top.
+ */
+
+unsigned int
+compute_banksize(unsigned int mem_type, unsigned char row_dens)
+{
+ unsigned int bsize;
+
+ if (mem_type == SPD_MEMTYPE_DDR) {
+ /* Bottom 2 bits up to the top. */
+ bsize = ((row_dens >> 2) | ((row_dens & 3) << 6)) << 24;
+ debug("DDR: DDR I rank density = 0x%08x\n", bsize);
+ } else {
+ /* Bottom 5 bits up to the top. */
+ bsize = ((row_dens >> 5) | ((row_dens & 31) << 3)) << 27;
+ debug("DDR: DDR II rank density = 0x%08x\n", bsize);
+ }
+ return bsize;
+}
+
+
+/*
+ * Convert a two-nibble BCD value into a cycle time.
+ * While the spec calls for nano-seconds, picos are returned.
+ *
+ * This implements the tables for bytes 9, 23 and 25 for both
+ * DDR I and II. No allowance for distinguishing the invalid
+ * fields absent for DDR I yet present in DDR II is made.
+ * (That is, cycle times of .25, .33, .66 and .75 ns are
+ * allowed for both DDR II and I.)
+ */
+
+unsigned int
+convert_bcd_tenths_to_cycle_time_ps(unsigned int spd_val)
+{
+ /*
+ * Table look up the lower nibble, allow DDR I & II.
+ */
+ unsigned int tenths_ps[16] = {
+ 0,
+ 100,
+ 200,
+ 300,
+ 400,
+ 500,
+ 600,
+ 700,
+ 800,
+ 900,
+ 250,
+ 330,
+ 660,
+ 750,
+ 0, /* undefined */
+ 0 /* undefined */
+ };
+
+ unsigned int whole_ns = (spd_val & 0xF0) >> 4;
+ unsigned int tenth_ns = spd_val & 0x0F;
+ unsigned int ps = whole_ns * 1000 + tenths_ps[tenth_ns];
+
+ return ps;
+}
+
+
+/*
+ * Determine Refresh Rate. Ignore self refresh bit on DDR I.
+ * Table from SPD Spec, Byte 12, converted to picoseconds and
+ * filled in with "default" normal values.
+ */
+unsigned int determine_refresh_rate(unsigned int spd_refresh)
+{
+ unsigned int refresh_time_ns[8] = {
+ 15625000, /* 0 Normal 1.00x */
+ 3900000, /* 1 Reduced .25x */
+ 7800000, /* 2 Extended .50x */
+ 31300000, /* 3 Extended 2.00x */
+ 62500000, /* 4 Extended 4.00x */
+ 125000000, /* 5 Extended 8.00x */
+ 15625000, /* 6 Normal 1.00x filler */
+ 15625000, /* 7 Normal 1.00x filler */
+ };
+
+ return picos_to_clk(refresh_time_ns[spd_refresh & 0x7]);
+}
+
+
+long int
+spd_init(unsigned char i2c_address, unsigned int ddr_num,
+ unsigned int dimm_num, unsigned int start_addr)
+{
+ volatile immap_t *immap = (immap_t *)CFG_IMMR;
+ volatile ccsr_ddr_t *ddr;
+ volatile ccsr_gur_t *gur = &immap->im_gur;
+ spd_eeprom_t spd;
+ unsigned int n_ranks;
+ unsigned int rank_density;
+ unsigned int odt_rd_cfg, odt_wr_cfg;
+ unsigned int odt_cfg, mode_odt_enable;
+ unsigned int refresh_clk;
+#ifdef MPC86xx_DDR_SDRAM_CLK_CNTL
+ unsigned char clk_adjust;
+#endif
+ unsigned int dqs_cfg;
+ unsigned char twr_clk, twtr_clk, twr_auto_clk;
+ unsigned int tCKmin_ps, tCKmax_ps;
+ unsigned int max_data_rate;
+ unsigned int busfreq;
+ unsigned int memsize;
+ unsigned char caslat, caslat_ctrl;
+ unsigned int trfc, trfc_clk, trfc_low, trfc_high;
+ unsigned int trcd_clk;
+ unsigned int trtp_clk;
+ unsigned char cke_min_clk;
+ unsigned char add_lat;
+ unsigned char wr_lat;
+ unsigned char wr_data_delay;
+ unsigned char four_act;
+ unsigned char cpo;
+ unsigned char burst_len;
+ unsigned int mode_caslat;
+ unsigned char d_init;
+ unsigned int tCycle_ps, modfreq;
+
+ if (ddr_num == 1)
+ ddr = &immap->im_ddr1;
+ else
+ ddr = &immap->im_ddr2;
+
+ /*
+ * Read SPD information.
+ */
+ debug("Performing SPD read at I2C address 0x%02lx\n",i2c_address);
+ memset((void *)&spd, 0, sizeof(spd));
+ CFG_READ_SPD(i2c_address, 0, 1, (uchar *) &spd, sizeof(spd));
+
+ /*
+ * Check for supported memory module types.
+ */
+ if (spd.mem_type != SPD_MEMTYPE_DDR &&
+ spd.mem_type != SPD_MEMTYPE_DDR2) {
+ debug("Warning: Unable to locate DDR I or DDR II module for DIMM %d of DDR controller %d.\n"
+ " Fundamental memory type is 0x%0x\n",
+ dimm_num,
+ ddr_num,
+ spd.mem_type);
+ return 0;
+ }
+
+ debug("\nFound memory of type 0x%02lx ", spd.mem_type);
+ if (spd.mem_type == SPD_MEMTYPE_DDR)
+ debug("DDR I\n");
+ else
+ debug("DDR II\n");
+
+ /*
+ * These test gloss over DDR I and II differences in interpretation
+ * of bytes 3 and 4, but irrelevantly. Multiple asymmetric banks
+ * are not supported on DDR I; and not encoded on DDR II.
+ *
+ * Also note that the 8548 controller can support:
+ * 12 <= nrow <= 16
+ * and
+ * 8 <= ncol <= 11 (still, for DDR)
+ * 6 <= ncol <= 9 (for FCRAM)
+ */
+ if (spd.nrow_addr < 12 || spd.nrow_addr > 14) {
+ printf("DDR: Unsupported number of Row Addr lines: %d.\n",
+ spd.nrow_addr);
+ return 0;
+ }
+ if (spd.ncol_addr < 8 || spd.ncol_addr > 11) {
+ printf("DDR: Unsupported number of Column Addr lines: %d.\n",
+ spd.ncol_addr);
+ return 0;
+ }
+
+ /*
+ * Determine the number of physical banks controlled by
+ * different Chip Select signals. This is not quite the
+ * same as the number of DIMM modules on the board. Feh.
+ */
+ if (spd.mem_type == SPD_MEMTYPE_DDR) {
+ n_ranks = spd.nrows;
+ } else {
+ n_ranks = (spd.nrows & 0x7) + 1;
+ }
+
+ debug("DDR: number of ranks = %d\n", n_ranks);
+
+ if (n_ranks > 2) {
+ printf("DDR: Only 2 chip selects are supported: %d\n",
+ n_ranks);
+ return 0;
+ }
+
+ /*
+ * Adjust DDR II IO voltage biasing. It just makes it work.
+ */
+ if (spd.mem_type == SPD_MEMTYPE_DDR2) {
+ gur->ddrioovcr = (0
+ | 0x80000000 /* Enable */
+ | 0x10000000 /* VSEL to 1.8V */
+ );
+ }
+
+ /*
+ * Determine the size of each Rank in bytes.
+ */
+ rank_density = compute_banksize(spd.mem_type, spd.row_dens);
+
+ debug("Start address for this controller is 0x%08lx\n", start_addr);
+
+ /*
+ * ODT configuration recommendation from DDR Controller Chapter.
+ */
+ odt_rd_cfg = 0; /* Never assert ODT */
+ odt_wr_cfg = 0; /* Never assert ODT */
+ if (spd.mem_type == SPD_MEMTYPE_DDR2) {
+ odt_wr_cfg = 1; /* Assert ODT on writes to CS0 */
+ }
+
+#ifdef CONFIG_DDR_INTERLEAVE
+
+ if (dimm_num != 1) {
+ printf("For interleaving memory on HPCN, need to use DIMM 1 for DDR Controller %d !\n", ddr_num);
+ return 0;
+ } else {
+ /*
+ * Since interleaved memory only uses CS0, the
+ * memory sticks have to be identical in size and quantity
+ * of ranks. That essentially gives double the size on
+ * one rank, i.e on CS0 for both controllers put together.
+ * Confirm this???
+ */
+ rank_density *= 2;
+
+ /*
+ * Eg: Bounds: 0x0000_0000 to 0x0f000_0000 first 256 Meg
+ */
+ start_addr = 0;
+ ddr->cs0_bnds = (start_addr >> 8)
+ | (((start_addr + rank_density - 1) >> 24));
+ /*
+ * Default interleaving mode to cache-line interleaving.
+ */
+ ddr->cs0_config = ( 1 << 31
+#if (CFG_PAGE_INTERLEAVING == 1)
+ | (PAGE_INTERLEAVING)
+#elif (CFG_BANK_INTERLEAVING == 1)
+ | (BANK_INTERLEAVING)
+#elif (CFG_SUPER_BANK_INTERLEAVING == 1)
+ | (SUPER_BANK_INTERLEAVING)
+#else
+ | (CACHE_LINE_INTERLEAVING)
+#endif
+ | (odt_rd_cfg << 20)
+ | (odt_wr_cfg << 16)
+ | (spd.nrow_addr - 12) << 8
+ | (spd.ncol_addr - 8) );
+
+ debug("DDR: cs0_bnds = 0x%08x\n", ddr->cs0_bnds);
+ debug("DDR: cs0_config = 0x%08x\n", ddr->cs0_config);
+
+ /*
+ * Adjustment for dual rank memory to get correct memory
+ * size (return value of this function).
+ */
+ if (n_ranks == 2) {
+ n_ranks = 1;
+ rank_density /= 2;
+ } else {
+ rank_density /= 2;
+ }
+ }
+#else /* CONFIG_DDR_INTERLEAVE */
+
+ if (dimm_num == 1) {
+ /*
+ * Eg: Bounds: 0x0000_0000 to 0x0f000_0000 first 256 Meg
+ */
+ ddr->cs0_bnds = (start_addr >> 8)
+ | (((start_addr + rank_density - 1) >> 24));
+
+ ddr->cs0_config = ( 1 << 31
+ | (odt_rd_cfg << 20)
+ | (odt_wr_cfg << 16)
+ | (spd.nrow_addr - 12) << 8
+ | (spd.ncol_addr - 8) );
+
+ debug("DDR: cs0_bnds = 0x%08x\n", ddr->cs0_bnds);
+ debug("DDR: cs0_config = 0x%08x\n", ddr->cs0_config);
+
+ if (n_ranks == 2) {
+ /*
+ * Eg: Bounds: 0x1000_0000 to 0x1f00_0000,
+ * second 256 Meg
+ */
+ ddr->cs1_bnds = (((start_addr + rank_density) >> 8)
+ | (( start_addr + 2*rank_density - 1)
+ >> 24));
+ ddr->cs1_config = ( 1<<31
+ | (odt_rd_cfg << 20)
+ | (odt_wr_cfg << 16)
+ | (spd.nrow_addr - 12) << 8
+ | (spd.ncol_addr - 8) );
+ debug("DDR: cs1_bnds = 0x%08x\n", ddr->cs1_bnds);
+ debug("DDR: cs1_config = 0x%08x\n", ddr->cs1_config);
+ }
+
+ } else {
+ /*
+ * This is the 2nd DIMM slot for this controller
+ */
+ /*
+ * Eg: Bounds: 0x0000_0000 to 0x0f000_0000 first 256 Meg
+ */
+ ddr->cs2_bnds = (start_addr >> 8)
+ | (((start_addr + rank_density - 1) >> 24));
+
+ ddr->cs2_config = ( 1 << 31
+ | (odt_rd_cfg << 20)
+ | (odt_wr_cfg << 16)
+ | (spd.nrow_addr - 12) << 8
+ | (spd.ncol_addr - 8) );
+
+ debug("DDR: cs2_bnds = 0x%08x\n", ddr->cs2_bnds);
+ debug("DDR: cs2_config = 0x%08x\n", ddr->cs2_config);
+
+ if (n_ranks == 2) {
+ /*
+ * Eg: Bounds: 0x1000_0000 to 0x1f00_0000,
+ * second 256 Meg
+ */
+ ddr->cs3_bnds = (((start_addr + rank_density) >> 8)
+ | (( start_addr + 2*rank_density - 1)
+ >> 24));
+ ddr->cs3_config = ( 1<<31
+ | (odt_rd_cfg << 20)
+ | (odt_wr_cfg << 16)
+ | (spd.nrow_addr - 12) << 8
+ | (spd.ncol_addr - 8) );
+ debug("DDR: cs3_bnds = 0x%08x\n", ddr->cs3_bnds);
+ debug("DDR: cs3_config = 0x%08x\n", ddr->cs3_config);
+ }
+ }
+#endif /* CONFIG_DDR_INTERLEAVE */
+
+ /*
+ * Find the largest CAS by locating the highest 1 bit
+ * in the spd.cas_lat field. Translate it to a DDR
+ * controller field value:
+ *
+ * CAS Lat DDR I DDR II Ctrl
+ * Clocks SPD Bit SPD Bit Value
+ * ------- ------- ------- -----
+ * 1.0 0 0001
+ * 1.5 1 0010
+ * 2.0 2 2 0011
+ * 2.5 3 0100
+ * 3.0 4 3 0101
+ * 3.5 5 0110
+ * 4.0 4 0111
+ * 4.5 1000
+ * 5.0 5 1001
+ */
+ caslat = __ilog2(spd.cas_lat);
+ if ((spd.mem_type == SPD_MEMTYPE_DDR)
+ && (caslat > 5)) {
+ printf("DDR I: Invalid SPD CAS Latency: 0x%x.\n", spd.cas_lat);
+ return 0;
+
+ } else if (spd.mem_type == SPD_MEMTYPE_DDR2
+ && (caslat < 2 || caslat > 5)) {
+ printf("DDR II: Invalid SPD CAS Latency: 0x%x.\n",
+ spd.cas_lat);
+ return 0;
+ }
+ debug("DDR: caslat SPD bit is %d\n", caslat);
+
+ /*
+ * Calculate the Maximum Data Rate based on the Minimum Cycle time.
+ * The SPD clk_cycle field (tCKmin) is measured in tenths of
+ * nanoseconds and represented as BCD.
+ */
+ tCKmin_ps = convert_bcd_tenths_to_cycle_time_ps(spd.clk_cycle);
+ debug("DDR: tCKmin = %d ps\n", tCKmin_ps);
+
+ /*
+ * Double-data rate, scaled 1000 to picoseconds, and back down to MHz.
+ */
+ max_data_rate = 2 * 1000 * 1000 / tCKmin_ps;
+ debug("DDR: Module max data rate = %d Mhz\n", max_data_rate);
+
+
+ /*
+ * Adjust the CAS Latency to allow for bus speeds that
+ * are slower than the DDR module.
+ */
+ busfreq = get_bus_freq(0) / 1000000; /* MHz */
+ tCycle_ps = convert_bcd_tenths_to_cycle_time_ps(spd.clk_cycle3);
+ modfreq = 2 * 1000 * 1000 / tCycle_ps;
+
+ if ((spd.mem_type == SPD_MEMTYPE_DDR2) && (busfreq < 266)) {
+ printf("DDR: platform frequency too low for correct DDR2 controller operation\n");
+ return 0;
+ } else if (busfreq < 90) {
+ printf("DDR: platform frequency too low for correct DDR1 operation\n");
+ return 0;
+ }
+
+ if ((busfreq <= modfreq) && (spd.cas_lat & (1 << (caslat - 2)))) {
+ caslat -= 2;
+ } else {
+ tCycle_ps = convert_bcd_tenths_to_cycle_time_ps(spd.clk_cycle2);
+ modfreq = 2 * 1000 * 1000 / tCycle_ps;
+ if ((busfreq <= modfreq) && (spd.cas_lat & (1 << (caslat - 1))))
+ caslat -= 1;
+ else if (busfreq > max_data_rate) {
+ printf("DDR: Bus freq %d MHz is not fit for DDR rate %d MHz\n",
+ busfreq, max_data_rate);
+ return 0;
+ }
+ }
+
+ /*
+ * Empirically set ~MCAS-to-preamble override for DDR 2.
+ * Your milage will vary.
+ */
+ cpo = 0;
+ if (spd.mem_type == SPD_MEMTYPE_DDR2) {
+ if (busfreq <= 333) {
+ cpo = 0x7;
+ } else if (busfreq <= 400) {
+ cpo = 0x9;
+ } else {
+ cpo = 0xa;
+ }
+ }
+
+ /*
+ * Convert caslat clocks to DDR controller value.
+ * Force caslat_ctrl to be DDR Controller field-sized.
+ */
+ if (spd.mem_type == SPD_MEMTYPE_DDR) {
+ caslat_ctrl = (caslat + 1) & 0x07;
+ } else {
+ caslat_ctrl = (2 * caslat - 1) & 0x0f;
+ }
+
+ debug("DDR: caslat SPD bit is %d, controller field is 0x%x\n",
+ caslat, caslat_ctrl);
+
+ /*
+ * Timing Config 0.
+ * Avoid writing for DDR I. The new PQ38 DDR controller
+ * dreams up non-zero default values to be backwards compatible.
+ */
+ if (spd.mem_type == SPD_MEMTYPE_DDR2) {
+ unsigned char taxpd_clk = 8; /* By the book. */
+ unsigned char tmrd_clk = 2; /* By the book. */
+ unsigned char act_pd_exit = 2; /* Empirical? */
+ unsigned char pre_pd_exit = 6; /* Empirical? */
+
+ ddr->timing_cfg_0 = (0
+ | ((act_pd_exit & 0x7) << 20) /* ACT_PD_EXIT */
+ | ((pre_pd_exit & 0x7) << 16) /* PRE_PD_EXIT */
+ | ((taxpd_clk & 0xf) << 8) /* ODT_PD_EXIT */
+ | ((tmrd_clk & 0xf) << 0) /* MRS_CYC */
+ );
+ debug("DDR: timing_cfg_0 = 0x%08x\n", ddr->timing_cfg_0);
+
+ }
+
+
+ /*
+ * Some Timing Config 1 values now.
+ * Sneak Extended Refresh Recovery in here too.
+ */
+
+ /*
+ * For DDR I, WRREC(Twr) and WRTORD(Twtr) are not in SPD,
+ * use conservative value.
+ * For DDR II, they are bytes 36 and 37, in quarter nanos.
+ */
+
+ if (spd.mem_type == SPD_MEMTYPE_DDR) {
+ twr_clk = 3; /* Clocks */
+ twtr_clk = 1; /* Clocks */
+ } else {
+ twr_clk = picos_to_clk(spd.twr * 250);
+ twtr_clk = picos_to_clk(spd.twtr * 250);
+ }
+
+ /*
+ * Calculate Trfc, in picos.
+ * DDR I: Byte 42 straight up in ns.
+ * DDR II: Byte 40 and 42 swizzled some, in ns.
+ */
+ if (spd.mem_type == SPD_MEMTYPE_DDR) {
+ trfc = spd.trfc * 1000; /* up to ps */
+ } else {
+ unsigned int byte40_table_ps[8] = {
+ 0,
+ 250,
+ 330,
+ 500,
+ 660,
+ 750,
+ 0,
+ 0
+ };
+
+ trfc = (((spd.trctrfc_ext & 0x1) * 256) + spd.trfc) * 1000
+ + byte40_table_ps[(spd.trctrfc_ext >> 1) & 0x7];
+ }
+ trfc_clk = picos_to_clk(trfc);
+
+ /*
+ * Trcd, Byte 29, from quarter nanos to ps and clocks.
+ */
+ trcd_clk = picos_to_clk(spd.trcd * 250) & 0x7;
+
+ /*
+ * Convert trfc_clk to DDR controller fields. DDR I should
+ * fit in the REFREC field (16-19) of TIMING_CFG_1, but the
+ * 8548 controller has an extended REFREC field of three bits.
+ * The controller automatically adds 8 clocks to this value,
+ * so preadjust it down 8 first before splitting it up.
+ */
+ trfc_low = (trfc_clk - 8) & 0xf;
+ trfc_high = ((trfc_clk - 8) >> 4) & 0x3;
+
+ /*
+ * Sneak in some Extended Refresh Recovery.
+ */
+ ddr->ext_refrec = (trfc_high << 16);
+ debug("DDR: ext_refrec = 0x%08x\n", ddr->ext_refrec);
+
+ ddr->timing_cfg_1 =
+ (0
+ | ((picos_to_clk(spd.trp * 250) & 0x07) << 28) /* PRETOACT */
+ | ((picos_to_clk(spd.tras * 1000) & 0x0f ) << 24) /* ACTTOPRE */
+ | (trcd_clk << 20) /* ACTTORW */
+ | (caslat_ctrl << 16) /* CASLAT */
+ | (trfc_low << 12) /* REFEC */
+ | ((twr_clk & 0x07) << 8) /* WRRREC */
+ | ((picos_to_clk(spd.trrd * 250) & 0x07) << 4) /* ACTTOACT */
+ | ((twtr_clk & 0x07) << 0) /* WRTORD */
+ );
+
+ debug("DDR: timing_cfg_1 = 0x%08x\n", ddr->timing_cfg_1);
+
+
+ /*
+ * Timing_Config_2
+ * Was: 0x00000800;
+ */
+
+ /*
+ * Additive Latency
+ * For DDR I, 0.
+ * For DDR II, with ODT enabled, use "a value" less than ACTTORW,
+ * which comes from Trcd, and also note that:
+ * add_lat + caslat must be >= 4
+ */
+ add_lat = 0;
+ if (spd.mem_type == SPD_MEMTYPE_DDR2
+ && (odt_wr_cfg || odt_rd_cfg)
+ && (caslat < 4)) {
+ add_lat = 4 - caslat;
+ if (add_lat >= trcd_clk) {
+ add_lat = trcd_clk - 1;
+ }
+ }
+
+ /*
+ * Write Data Delay
+ * Historically 0x2 == 4/8 clock delay.
+ * Empirically, 0x3 == 6/8 clock delay is suggested for DDR I 266.
+ */
+ wr_data_delay = 3;
+
+ /*
+ * Write Latency
+ * Read to Precharge
+ * Minimum CKE Pulse Width.
+ * Four Activate Window
+ */
+ if (spd.mem_type == SPD_MEMTYPE_DDR) {
+ /*
+ * This is a lie. It should really be 1, but if it is
+ * set to 1, bits overlap into the old controller's
+ * otherwise unused ACSM field. If we leave it 0, then
+ * the HW will magically treat it as 1 for DDR 1. Oh Yea.
+ */
+ wr_lat = 0;
+
+ trtp_clk = 2; /* By the book. */
+ cke_min_clk = 1; /* By the book. */
+ four_act = 1; /* By the book. */
+
+ } else {
+ wr_lat = caslat - 1;
+
+ /* Convert SPD value from quarter nanos to picos. */
+ trtp_clk = picos_to_clk(spd.trtp * 250);
+
+ cke_min_clk = 3; /* By the book. */
+ four_act = picos_to_clk(37500); /* By the book. 1k pages? */
+ }
+
+ ddr->timing_cfg_2 = (0
+ | ((add_lat & 0x7) << 28) /* ADD_LAT */
+ | ((cpo & 0x1f) << 23) /* CPO */
+ | ((wr_lat & 0x7) << 19) /* WR_LAT */
+ | ((trtp_clk & 0x7) << 13) /* RD_TO_PRE */
+ | ((wr_data_delay & 0x7) << 10) /* WR_DATA_DELAY */
+ | ((cke_min_clk & 0x7) << 6) /* CKE_PLS */
+ | ((four_act & 0x1f) << 0) /* FOUR_ACT */
+ );
+
+ debug("DDR: timing_cfg_2 = 0x%08x\n", ddr->timing_cfg_2);
+
+
+ /*
+ * Determine the Mode Register Set.
+ *
+ * This is nominally part specific, but it appears to be
+ * consistent for all DDR I devices, and for all DDR II devices.
+ *
+ * caslat must be programmed
+ * burst length is always 4
+ * burst type is sequential
+ *
+ * For DDR I:
+ * operating mode is "normal"
+ *
+ * For DDR II:
+ * other stuff
+ */
+
+ mode_caslat = 0;
+
+ /*
+ * Table lookup from DDR I or II Device Operation Specs.
+ */
+ if (spd.mem_type == SPD_MEMTYPE_DDR) {
+ if (1 <= caslat && caslat <= 4) {
+ unsigned char mode_caslat_table[4] = {
+ 0x5, /* 1.5 clocks */
+ 0x2, /* 2.0 clocks */
+ 0x6, /* 2.5 clocks */
+ 0x3 /* 3.0 clocks */
+ };
+ mode_caslat = mode_caslat_table[caslat - 1];
+ } else {
+ puts("DDR I: Only CAS Latencies of 1.5, 2.0, "
+ "2.5 and 3.0 clocks are supported.\n");
+ return 0;
+ }
+
+ } else {
+ if (2 <= caslat && caslat <= 5) {
+ mode_caslat = caslat;
+ } else {
+ puts("DDR II: Only CAS Latencies of 2.0, 3.0, "
+ "4.0 and 5.0 clocks are supported.\n");
+ return 0;
+ }
+ }
+
+ /*
+ * Encoded Burst Length of 4.
+ */
+ burst_len = 2; /* Fiat. */
+
+ if (spd.mem_type == SPD_MEMTYPE_DDR) {
+ twr_auto_clk = 0; /* Historical */
+ } else {
+ /*
+ * Determine tCK max in picos. Grab tWR and convert to picos.
+ * Auto-precharge write recovery is:
+ * WR = roundup(tWR_ns/tCKmax_ns).
+ *
+ * Ponder: Is twr_auto_clk different than twr_clk?
+ */
+ tCKmax_ps = convert_bcd_tenths_to_cycle_time_ps(spd.tckmax);
+ twr_auto_clk = (spd.twr * 250 + tCKmax_ps - 1) / tCKmax_ps;
+ }
+
+ /*
+ * Mode Reg in bits 16 ~ 31,
+ * Extended Mode Reg 1 in bits 0 ~ 15.
+ */
+ mode_odt_enable = 0x0; /* Default disabled */
+ if (odt_wr_cfg || odt_rd_cfg) {
+ /*
+ * Bits 6 and 2 in Extended MRS(1)
+ * Bit 2 == 0x04 == 75 Ohm, with 2 DIMM modules.
+ * Bit 6 == 0x40 == 150 Ohm, with 1 DIMM module.
+ */
+ mode_odt_enable = 0x40; /* 150 Ohm */
+ }
+
+ ddr->sdram_mode_1 =
+ (0
+ | (add_lat << (16 + 3)) /* Additive Latency in EMRS1 */
+ | (mode_odt_enable << 16) /* ODT Enable in EMRS1 */
+ | (twr_auto_clk << 9) /* Write Recovery Autopre */
+ | (mode_caslat << 4) /* caslat */
+ | (burst_len << 0) /* Burst length */
+ );
+
+ debug("DDR: sdram_mode = 0x%08x\n", ddr->sdram_mode_1);
+
+ /*
+ * Clear EMRS2 and EMRS3.
+ */
+ ddr->sdram_mode_2 = 0;
+ debug("DDR: sdram_mode_2 = 0x%08x\n", ddr->sdram_mode_2);
+
+ /*
+ * Determine Refresh Rate.
+ */
+ refresh_clk = determine_refresh_rate(spd.refresh & 0x7);
+
+ /*
+ * Set BSTOPRE to 0x100 for page mode
+ * If auto-charge is used, set BSTOPRE = 0
+ */
+ ddr->sdram_interval =
+ (0
+ | (refresh_clk & 0x3fff) << 16
+ | 0x100
+ );
+ debug("DDR: sdram_interval = 0x%08x\n", ddr->sdram_interval);
+
+
+ /*
+ * Is this an ECC DDR chip?
+ * But don't mess with it if the DDR controller will init mem.
+ */
+#if defined(CONFIG_DDR_ECC) && !defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER)
+ if (spd.config == 0x02) {
+ ddr->err_disable = 0x0000000d;
+ ddr->err_sbe = 0x00ff0000;
+ }
+ debug("DDR: err_disable = 0x%08x\n", ddr->err_disable);
+ debug("DDR: err_sbe = 0x%08x\n", ddr->err_sbe);
+#endif
+
+ asm volatile("sync;isync");
+ udelay(500);
+
+ /*
+ * SDRAM Cfg 2
+ */
+
+ /*
+ * When ODT is enabled, Chap 9 suggests asserting ODT to
+ * internal IOs only during reads.
+ */
+ odt_cfg = 0;
+ if (odt_rd_cfg | odt_wr_cfg) {
+ odt_cfg = 0x2; /* ODT to IOs during reads */
+ }
+
+ /*
+ * Try to use differential DQS with DDR II.
+ */
+ if (spd.mem_type == SPD_MEMTYPE_DDR) {
+ dqs_cfg = 0; /* No Differential DQS for DDR I */
+ } else {
+ dqs_cfg = 0x1; /* Differential DQS for DDR II */
+ }
+
+#if defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER)
+ /*
+ * Use the DDR controller to auto initialize memory.
+ */
+ d_init = 1;
+ ddr->sdram_data_init = CONFIG_MEM_INIT_VALUE;
+ debug("DDR: ddr_data_init = 0x%08x\n", ddr->sdram_data_init);
+#else
+ /*
+ * Memory will be initialized via DMA, or not at all.
+ */
+ d_init = 0;
+#endif
+
+ ddr->sdram_cfg_2 = (0
+ | (dqs_cfg << 26) /* Differential DQS */
+ | (odt_cfg << 21) /* ODT */
+ | (d_init << 4) /* D_INIT auto init DDR */
+ );
+
+ debug("DDR: sdram_cfg_2 = 0x%08x\n", ddr->sdram_cfg_2);
+
+
+#ifdef MPC86xx_DDR_SDRAM_CLK_CNTL
+ /*
+ * Setup the clock control.
+ * SDRAM_CLK_CNTL[0] = Source synchronous enable == 1
+ * SDRAM_CLK_CNTL[5-7] = Clock Adjust
+ * 0110 3/4 cycle late
+ * 0111 7/8 cycle late
+ */
+ if (spd.mem_type == SPD_MEMTYPE_DDR)
+ clk_adjust = 0x6;
+ else
+ clk_adjust = 0x7;
+
+ ddr->sdram_clk_cntl = (0
+ | 0x80000000
+ | (clk_adjust << 23)
+ );
+ debug("DDR: sdram_clk_cntl = 0x%08x\n", ddr->sdram_clk_cntl);
+#endif
+
+ /*
+ * Figure out memory size in Megabytes.
+ */
+ debug("# ranks = %d, rank_density = 0x%08lx\n", n_ranks, rank_density);
+ memsize = n_ranks * rank_density / 0x100000;
+ return memsize;
+}
+
+
+unsigned int enable_ddr(unsigned int ddr_num)
+{
+ volatile immap_t *immap = (immap_t *)CFG_IMMR;
+ spd_eeprom_t spd1,spd2;
+ volatile ccsr_ddr_t *ddr;
+ unsigned sdram_cfg_1;
+ unsigned char sdram_type, mem_type, config, mod_attr;
+ unsigned char d_init;
+ unsigned int no_dimm1=0, no_dimm2=0;
+
+ /* Set up pointer to enable the current ddr controller */
+ if (ddr_num == 1)
+ ddr = &immap->im_ddr1;
+ else
+ ddr = &immap->im_ddr2;
+
+ /*
+ * Read both dimm slots and decide whether
+ * or not to enable this controller.
+ */
+ memset((void *)&spd1,0,sizeof(spd1));
+ memset((void *)&spd2,0,sizeof(spd2));
+
+ if (ddr_num == 1) {
+ CFG_READ_SPD(SPD_EEPROM_ADDRESS1,
+ 0, 1, (uchar *) &spd1, sizeof(spd1));
+ CFG_READ_SPD(SPD_EEPROM_ADDRESS2,
+ 0, 1, (uchar *) &spd2, sizeof(spd2));
+ } else {
+ CFG_READ_SPD(SPD_EEPROM_ADDRESS3,
+ 0, 1, (uchar *) &spd1, sizeof(spd1));
+ CFG_READ_SPD(SPD_EEPROM_ADDRESS4,
+ 0, 1, (uchar *) &spd2, sizeof(spd2));
+ }
+
+ /*
+ * Check for supported memory module types.
+ */
+ if (spd1.mem_type != SPD_MEMTYPE_DDR
+ && spd1.mem_type != SPD_MEMTYPE_DDR2) {
+ no_dimm1 = 1;
+ } else {
+ debug("\nFound memory of type 0x%02lx ",spd1.mem_type );
+ if (spd1.mem_type == SPD_MEMTYPE_DDR)
+ debug("DDR I\n");
+ else
+ debug("DDR II\n");
+ }
+
+ if (spd2.mem_type != SPD_MEMTYPE_DDR &&
+ spd2.mem_type != SPD_MEMTYPE_DDR2) {
+ no_dimm2 = 1;
+ } else {
+ debug("\nFound memory of type 0x%02lx ",spd2.mem_type );
+ if (spd2.mem_type == SPD_MEMTYPE_DDR)
+ debug("DDR I\n");
+ else
+ debug("DDR II\n");
+ }
+
+#ifdef CONFIG_DDR_INTERLEAVE
+ if (no_dimm1) {
+ printf("For interleaved operation memory modules need to be present in CS0 DIMM slots of both DDR controllers!\n");
+ return 0;
+ }
+#endif
+
+ /*
+ * Memory is not present in DIMM1 and DIMM2 - so do not enable DDRn
+ */
+ if (no_dimm1 && no_dimm2) {
+ printf("No memory modules found for DDR controller %d!!\n", ddr_num);
+ return 0;
+ } else {
+ mem_type = no_dimm2 ? spd1.mem_type : spd2.mem_type;
+
+ /*
+ * Figure out the settings for the sdram_cfg register.
+ * Build up the entire register in 'sdram_cfg' before
+ * writing since the write into the register will
+ * actually enable the memory controller; all settings
+ * must be done before enabling.
+ *
+ * sdram_cfg[0] = 1 (ddr sdram logic enable)
+ * sdram_cfg[1] = 1 (self-refresh-enable)
+ * sdram_cfg[5:7] = (SDRAM type = DDR SDRAM)
+ * 010 DDR 1 SDRAM
+ * 011 DDR 2 SDRAM
+ */
+ sdram_type = (mem_type == SPD_MEMTYPE_DDR) ? 2 : 3;
+ sdram_cfg_1 = (0
+ | (1 << 31) /* Enable */
+ | (1 << 30) /* Self refresh */
+ | (sdram_type << 24) /* SDRAM type */
+ );
+
+ /*
+ * sdram_cfg[3] = RD_EN - registered DIMM enable
+ * A value of 0x26 indicates micron registered
+ * DIMMS (micron.com)
+ */
+ mod_attr = no_dimm2 ? spd1.mod_attr : spd2.mod_attr;
+ if (mem_type == SPD_MEMTYPE_DDR && mod_attr == 0x26) {
+ sdram_cfg_1 |= 0x10000000; /* RD_EN */
+ }
+
+#if defined(CONFIG_DDR_ECC)
+
+ config = no_dimm2 ? spd1.config : spd2.config;
+
+ /*
+ * If the user wanted ECC (enabled via sdram_cfg[2])
+ */
+ if (config == 0x02) {
+ ddr->err_disable = 0x00000000;
+ asm volatile("sync;isync;");
+ ddr->err_sbe = 0x00ff0000;
+ ddr->err_int_en = 0x0000000d;
+ sdram_cfg_1 |= 0x20000000; /* ECC_EN */
+ }
+#endif
+
+ /*
+ * Set 1T or 2T timing based on 1 or 2 modules
+ */
+ {
+ if (!(no_dimm1 || no_dimm2)) {
+ /*
+ * 2T timing,because both DIMMS are present.
+ * Enable 2T timing by setting sdram_cfg[16].
+ */
+ sdram_cfg_1 |= 0x8000; /* 2T_EN */
+ }
+ }
+
+ /*
+ * 200 painful micro-seconds must elapse between
+ * the DDR clock setup and the DDR config enable.
+ */
+ udelay(200);
+
+ /*
+ * Go!
+ */
+ ddr->sdram_cfg_1 = sdram_cfg_1;
+
+ asm volatile("sync;isync");
+ udelay(500);
+
+ debug("DDR: sdram_cfg = 0x%08x\n", ddr->sdram_cfg_1);
+
+
+#if defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER)
+ d_init = 1;
+ debug("DDR: memory initializing\n");
+
+ /*
+ * Poll until memory is initialized.
+ * 512 Meg at 400 might hit this 200 times or so.
+ */
+ while ((ddr->sdram_cfg_2 & (d_init << 4)) != 0) {
+ udelay(1000);
+ }
+ debug("DDR: memory initialized\n\n");
+#endif
+
+ debug("Enabled DDR Controller %d\n", ddr_num);
+ return 1;
+ }
+}
+
+
+long int
+spd_sdram(void)
+{
+ int memsize_ddr1_dimm1 = 0;
+ int memsize_ddr1_dimm2 = 0;
+ int memsize_ddr2_dimm1 = 0;
+ int memsize_ddr2_dimm2 = 0;
+ int memsize_total = 0;
+ int memsize_ddr1 = 0;
+ int memsize_ddr2 = 0;
+ unsigned int ddr1_enabled = 0;
+ unsigned int ddr2_enabled = 0;
+ unsigned int law_size_ddr1;
+ unsigned int law_size_ddr2;
+ volatile immap_t *immap = (immap_t *)CFG_IMMR;
+ volatile ccsr_local_mcm_t *mcm = &immap->im_local_mcm;
+
+#ifdef CONFIG_DDR_INTERLEAVE
+ unsigned int law_size_interleaved;
+ volatile ccsr_ddr_t *ddr1 = &immap->im_ddr1;
+ volatile ccsr_ddr_t *ddr2 = &immap->im_ddr2;
+
+ memsize_ddr1_dimm1 = spd_init(SPD_EEPROM_ADDRESS1,
+ 1, 1,
+ (unsigned int)memsize_total * 1024*1024);
+ memsize_total += memsize_ddr1_dimm1;
+
+ memsize_ddr2_dimm1 = spd_init(SPD_EEPROM_ADDRESS3,
+ 2, 1,
+ (unsigned int)memsize_total * 1024*1024);
+ memsize_total += memsize_ddr2_dimm1;
+
+ if (memsize_ddr1_dimm1 != memsize_ddr2_dimm1) {
+ if (memsize_ddr1_dimm1 < memsize_ddr2_dimm1)
+ memsize_total -= memsize_ddr1_dimm1;
+ else
+ memsize_total -= memsize_ddr2_dimm1;
+ debug("Total memory available for interleaving 0x%08lx\n",
+ memsize_total * 1024 * 1024);
+ debug("Adjusting CS0_BNDS to account for unequal DIMM sizes in interleaved memory\n");
+ ddr1->cs0_bnds = ((memsize_total * 1024 * 1024) - 1) >> 24;
+ ddr2->cs0_bnds = ((memsize_total * 1024 * 1024) - 1) >> 24;
+ debug("DDR1: cs0_bnds = 0x%08x\n", ddr1->cs0_bnds);
+ debug("DDR2: cs0_bnds = 0x%08x\n", ddr2->cs0_bnds);
+ }
+
+ ddr1_enabled = enable_ddr(1);
+ ddr2_enabled = enable_ddr(2);
+
+ /*
+ * Both controllers need to be enabled for interleaving.
+ */
+ if (ddr1_enabled && ddr2_enabled) {
+ law_size_interleaved = 19 + __ilog2(memsize_total);
+
+ /*
+ * Set up LAWBAR for DDR 1 space.
+ */
+ mcm->lawbar1 = ((CFG_DDR_SDRAM_BASE >> 12) & 0xfffff);
+ mcm->lawar1 = (LAWAR_EN
+ | LAWAR_TRGT_IF_DDR_INTERLEAVED
+ | (LAWAR_SIZE & law_size_interleaved));
+ debug("DDR: LAWBAR1=0x%08x\n", mcm->lawbar1);
+ debug("DDR: LAWAR1=0x%08x\n", mcm->lawar1);
+ debug("Interleaved memory size is 0x%08lx\n", memsize_total);
+
+#ifdef CONFIG_DDR_INTERLEAVE
+#if (CFG_PAGE_INTERLEAVING == 1)
+ printf("Page ");
+#elif (CFG_BANK_INTERLEAVING == 1)
+ printf("Bank ");
+#elif (CFG_SUPER_BANK_INTERLEAVING == 1)
+ printf("Super-bank ");
+#else
+ printf("Cache-line ");
+#endif
+#endif
+ printf("Interleaved");
+ return memsize_total * 1024 * 1024;
+ } else {
+ printf("Interleaved memory not enabled - check CS0 DIMM slots for both controllers.\n");
+ return 0;
+ }
+
+#else
+ /*
+ * Call spd_sdram() routine to init ddr1 - pass I2c address,
+ * controller number, dimm number, and starting address.
+ */
+ memsize_ddr1_dimm1 = spd_init(SPD_EEPROM_ADDRESS1,
+ 1, 1,
+ (unsigned int)memsize_total * 1024*1024);
+ memsize_total += memsize_ddr1_dimm1;
+
+ memsize_ddr1_dimm2 = spd_init(SPD_EEPROM_ADDRESS2,
+ 1, 2,
+ (unsigned int)memsize_total * 1024*1024);
+ memsize_total += memsize_ddr1_dimm2;
+
+ /*
+ * Enable the DDR controller - pass ddr controller number.
+ */
+ ddr1_enabled = enable_ddr(1);
+
+ /* Keep track of memory to be addressed by DDR1 */
+ memsize_ddr1 = memsize_ddr1_dimm1 + memsize_ddr1_dimm2;
+
+ /*
+ * First supported LAW size is 16M, at LAWAR_SIZE_16M == 23. Fnord.
+ */
+ if (ddr1_enabled) {
+ law_size_ddr1 = 19 + __ilog2(memsize_ddr1);
+
+ /*
+ * Set up LAWBAR for DDR 1 space.
+ */
+ mcm->lawbar1 = ((CFG_DDR_SDRAM_BASE >> 12) & 0xfffff);
+ mcm->lawar1 = (LAWAR_EN
+ | LAWAR_TRGT_IF_DDR1
+ | (LAWAR_SIZE & law_size_ddr1));
+ debug("DDR: LAWBAR1=0x%08x\n", mcm->lawbar1);
+ debug("DDR: LAWAR1=0x%08x\n", mcm->lawar1);
+ }
+
+#if (CONFIG_NUM_DDR_CONTROLLERS > 1)
+ memsize_ddr2_dimm1 = spd_init(SPD_EEPROM_ADDRESS3,
+ 2, 1,
+ (unsigned int)memsize_total * 1024*1024);
+ memsize_total += memsize_ddr2_dimm1;
+
+ memsize_ddr2_dimm2 = spd_init(SPD_EEPROM_ADDRESS4,
+ 2, 2,
+ (unsigned int)memsize_total * 1024*1024);
+ memsize_total += memsize_ddr2_dimm2;
+
+ ddr2_enabled = enable_ddr(2);
+
+ /* Keep track of memory to be addressed by DDR2 */
+ memsize_ddr2 = memsize_ddr2_dimm1 + memsize_ddr2_dimm2;
+
+ if (ddr2_enabled) {
+ law_size_ddr2 = 19 + __ilog2(memsize_ddr2);
+
+ /*
+ * Set up LAWBAR for DDR 2 space.
+ */
+ if (ddr1_enabled)
+ mcm->lawbar8 = (((memsize_ddr1 * 1024 * 1024) >> 12)
+ & 0xfffff);
+ else
+ mcm->lawbar8 = ((CFG_DDR_SDRAM_BASE >> 12) & 0xfffff);
+
+ mcm->lawar8 = (LAWAR_EN
+ | LAWAR_TRGT_IF_DDR2
+ | (LAWAR_SIZE & law_size_ddr2));
+ debug("\nDDR: LAWBAR8=0x%08x\n", mcm->lawbar8);
+ debug("DDR: LAWAR8=0x%08x\n", mcm->lawar8);
+ }
+#endif /* CONFIG_NUM_DDR_CONTROLLERS > 1 */
+
+ debug("\nMemory sizes are DDR1 = 0x%08lx, DDR2 = 0x%08lx\n",
+ memsize_ddr1, memsize_ddr2);
+
+ /*
+ * If neither DDR controller is enabled return 0.
+ */
+ if (!ddr1_enabled && !ddr2_enabled)
+ return 0;
+
+ printf("Non-interleaved");
+ return memsize_total * 1024 * 1024;
+
+#endif /* CONFIG_DDR_INTERLEAVE */
+}
+
+
+#endif /* CONFIG_SPD_EEPROM */
+
+
+#if defined(CONFIG_DDR_ECC) && !defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER)
+
+/*
+ * Initialize all of memory for ECC, then enable errors.
+ */
+
+void
+ddr_enable_ecc(unsigned int dram_size)
+{
+ uint *p = 0;
+ uint i = 0;
+ volatile immap_t *immap = (immap_t *)CFG_IMMR;
+ volatile ccsr_ddr_t *ddr1= &immap->im_ddr1;
+
+ dma_init();
+
+ for (*p = 0; p < (uint *)(8 * 1024); p++) {
+ if (((unsigned int)p & 0x1f) == 0) {
+ ppcDcbz((unsigned long) p);
+ }
+ *p = (unsigned int)CONFIG_MEM_INIT_VALUE;
+ if (((unsigned int)p & 0x1c) == 0x1c) {
+ ppcDcbf((unsigned long) p);
+ }
+ }
+
+ dma_xfer((uint *)0x002000, 0x002000, (uint *)0); /* 8K */
+ dma_xfer((uint *)0x004000, 0x004000, (uint *)0); /* 16K */
+ dma_xfer((uint *)0x008000, 0x008000, (uint *)0); /* 32K */
+ dma_xfer((uint *)0x010000, 0x010000, (uint *)0); /* 64K */
+ dma_xfer((uint *)0x020000, 0x020000, (uint *)0); /* 128k */
+ dma_xfer((uint *)0x040000, 0x040000, (uint *)0); /* 256k */
+ dma_xfer((uint *)0x080000, 0x080000, (uint *)0); /* 512k */
+ dma_xfer((uint *)0x100000, 0x100000, (uint *)0); /* 1M */
+ dma_xfer((uint *)0x200000, 0x200000, (uint *)0); /* 2M */
+ dma_xfer((uint *)0x400000, 0x400000, (uint *)0); /* 4M */
+
+ for (i = 1; i < dram_size / 0x800000; i++) {
+ dma_xfer((uint *)(0x800000*i), 0x800000, (uint *)0);
+ }
+
+ /*
+ * Enable errors for ECC.
+ */
+ debug("DMA DDR: err_disable = 0x%08x\n", ddr1->err_disable);
+ ddr1->err_disable = 0x00000000;
+ asm volatile("sync;isync");
+ debug("DMA DDR: err_disable = 0x%08x\n", ddr1->err_disable);
+}
+
+#endif /* CONFIG_DDR_ECC && ! CONFIG_ECC_INIT_VIA_DDRCONTROLLER */
diff --git a/cpu/mpc86xx/speed.c b/cpu/mpc86xx/speed.c
new file mode 100644
index 0000000..312ca12
--- /dev/null
+++ b/cpu/mpc86xx/speed.c
@@ -0,0 +1,127 @@
+/*
+ * Copyright 2004 Freescale Semiconductor.
+ * Jeff Brown
+ * Srikanth Srinivasan (srikanth.srinivasan@freescale.com)
+ *
+ * (C) Copyright 2000-2002
+ * 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 <mpc86xx.h>
+#include <asm/processor.h>
+
+
+void get_sys_info(sys_info_t *sysInfo)
+{
+ volatile immap_t *immap = (immap_t *) CFG_IMMR;
+ volatile ccsr_gur_t *gur = &immap->im_gur;
+ uint plat_ratio, e600_ratio;
+
+ plat_ratio = (gur->porpllsr) & 0x0000003e;
+ plat_ratio >>= 1;
+
+ switch (plat_ratio) {
+ case 0x0:
+ sysInfo->freqSystemBus = 16 * CONFIG_SYS_CLK_FREQ;
+ break;
+ case 0x02:
+ case 0x03:
+ case 0x04:
+ case 0x05:
+ case 0x06:
+ case 0x08:
+ case 0x09:
+ case 0x0a:
+ case 0x0c:
+ case 0x10:
+ sysInfo->freqSystemBus = plat_ratio * CONFIG_SYS_CLK_FREQ;
+ break;
+ default:
+ sysInfo->freqSystemBus = 0;
+ break;
+ }
+
+ e600_ratio = (gur->porpllsr) & 0x003f0000;
+ e600_ratio >>= 16;
+
+ switch (e600_ratio) {
+ case 0x10:
+ sysInfo->freqProcessor = 2 * sysInfo->freqSystemBus;
+ break;
+ case 0x19:
+ sysInfo->freqProcessor = 5 * sysInfo->freqSystemBus / 2;
+ break;
+ case 0x20:
+ sysInfo->freqProcessor = 3 * sysInfo->freqSystemBus;
+ break;
+ case 0x39:
+ sysInfo->freqProcessor = 7 * sysInfo->freqSystemBus / 2;
+ break;
+ case 0x28:
+ sysInfo->freqProcessor = 4 * sysInfo->freqSystemBus;
+ break;
+ case 0x1d:
+ sysInfo->freqProcessor = 9 * sysInfo->freqSystemBus / 2;
+ break;
+ default:
+ sysInfo->freqProcessor = e600_ratio + sysInfo->freqSystemBus;
+ break;
+ }
+}
+
+
+/*
+ * Measure CPU clock speed (core clock GCLK1, GCLK2)
+ * (Approx. GCLK frequency in Hz)
+ */
+
+int get_clocks(void)
+{
+ DECLARE_GLOBAL_DATA_PTR;
+ sys_info_t sys_info;
+
+ get_sys_info(&sys_info);
+ gd->cpu_clk = sys_info.freqProcessor;
+ gd->bus_clk = sys_info.freqSystemBus;
+
+ if (gd->cpu_clk != 0)
+ return 0;
+ else
+ return 1;
+}
+
+
+/*
+ * get_bus_freq
+ * Return system bus freq in Hz
+ */
+
+ulong get_bus_freq(ulong dummy)
+{
+ ulong val;
+ sys_info_t sys_info;
+
+ get_sys_info(&sys_info);
+ val = sys_info.freqSystemBus;
+
+ return val;
+}
diff --git a/cpu/mpc86xx/start.S b/cpu/mpc86xx/start.S
new file mode 100644
index 0000000..7406fe2
--- /dev/null
+++ b/cpu/mpc86xx/start.S
@@ -0,0 +1,1226 @@
+/*
+ * Copyright 2004 Freescale Semiconductor.
+ * Srikanth Srinivasan <srikanth.srinivaan@freescale.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/* U-Boot - Startup Code for 86xx PowerPC based Embedded Boards
+ *
+ *
+ * The processor starts at 0xfff00100 and the code is executed
+ * from flash. The code is organized to be at an other address
+ * in memory, but as long we don't jump around before relocating.
+ * board_init lies at a quite high address and when the cpu has
+ * jumped there, everything is ok.
+ */
+#include <config.h>
+#include <mpc86xx.h>
+#include <version.h>
+
+#include <ppc_asm.tmpl>
+#include <ppc_defs.h>
+
+#include <asm/cache.h>
+#include <asm/mmu.h>
+
+#ifndef CONFIG_IDENT_STRING
+#define CONFIG_IDENT_STRING ""
+#endif
+
+/* We don't want the MMU yet.
+*/
+#undef MSR_KERNEL
+/* Machine Check and Recoverable Interr. */
+#define MSR_KERNEL ( MSR_ME | MSR_RI )
+
+/*
+ * Set up GOT: Global Offset Table
+ *
+ * Use r14 to access the GOT
+ */
+ START_GOT
+ GOT_ENTRY(_GOT2_TABLE_)
+ GOT_ENTRY(_FIXUP_TABLE_)
+
+ GOT_ENTRY(_start)
+ GOT_ENTRY(_start_of_vectors)
+ GOT_ENTRY(_end_of_vectors)
+ GOT_ENTRY(transfer_to_handler)
+
+ GOT_ENTRY(__init_end)
+ GOT_ENTRY(_end)
+ GOT_ENTRY(__bss_start)
+ END_GOT
+
+/*
+ * r3 - 1st arg to board_init(): IMMP pointer
+ * r4 - 2nd arg to board_init(): boot flag
+ */
+ .text
+ .long 0x27051956 /* U-Boot Magic Number */
+ .globl version_string
+version_string:
+ .ascii U_BOOT_VERSION
+ .ascii " (", __DATE__, " - ", __TIME__, ")"
+ .ascii CONFIG_IDENT_STRING, "\0"
+
+ . = EXC_OFF_SYS_RESET
+ .globl _start
+_start:
+ li r21, BOOTFLAG_COLD /* Normal Power-On: Boot from FLASH */
+ b boot_cold
+ sync
+
+ . = EXC_OFF_SYS_RESET + 0x10
+
+ .globl _start_warm
+_start_warm:
+ li r21, BOOTFLAG_WARM /* Software reboot */
+ b boot_warm
+ sync
+
+ /* the boot code is located below the exception table */
+
+ .globl _start_of_vectors
+_start_of_vectors:
+
+/* Machine check */
+ STD_EXCEPTION(0x200, MachineCheck, MachineCheckException)
+
+/* Data Storage exception. */
+ STD_EXCEPTION(0x300, DataStorage, UnknownException)
+
+/* Instruction Storage exception. */
+ STD_EXCEPTION(0x400, InstStorage, UnknownException)
+
+/* External Interrupt exception. */
+ STD_EXCEPTION(0x500, ExtInterrupt, external_interrupt)
+
+/* Alignment exception. */
+ . = 0x600
+Alignment:
+ EXCEPTION_PROLOG
+ mfspr r4,DAR
+ stw r4,_DAR(r21)
+ mfspr r5,DSISR
+ stw r5,_DSISR(r21)
+ addi r3,r1,STACK_FRAME_OVERHEAD
+ li r20,MSR_KERNEL
+ rlwimi r20,r23,0,16,16 /* copy EE bit from saved MSR */
+ lwz r6,GOT(transfer_to_handler)
+ mtlr r6
+ blrl
+.L_Alignment:
+ .long AlignmentException - _start + EXC_OFF_SYS_RESET
+ .long int_return - _start + EXC_OFF_SYS_RESET
+
+/* Program check exception */
+ . = 0x700
+ProgramCheck:
+ EXCEPTION_PROLOG
+ addi r3,r1,STACK_FRAME_OVERHEAD
+ li r20,MSR_KERNEL
+ rlwimi r20,r23,0,16,16 /* copy EE bit from saved MSR */
+ lwz r6,GOT(transfer_to_handler)
+ mtlr r6
+ blrl
+.L_ProgramCheck:
+ .long ProgramCheckException - _start + EXC_OFF_SYS_RESET
+ .long int_return - _start + EXC_OFF_SYS_RESET
+
+ STD_EXCEPTION(0x800, FPUnavailable, UnknownException)
+
+ /* I guess we could implement decrementer, and may have
+ * to someday for timekeeping.
+ */
+ STD_EXCEPTION(0x900, Decrementer, timer_interrupt)
+ STD_EXCEPTION(0xa00, Trap_0a, UnknownException)
+ STD_EXCEPTION(0xb00, Trap_0b, UnknownException)
+ STD_EXCEPTION(0xc00, SystemCall, UnknownException)
+ STD_EXCEPTION(0xd00, SingleStep, UnknownException)
+ STD_EXCEPTION(0xe00, Trap_0e, UnknownException)
+ STD_EXCEPTION(0xf00, Trap_0f, UnknownException)
+ STD_EXCEPTION(0x1000, SoftEmu, SoftEmuException)
+ STD_EXCEPTION(0x1100, InstructionTLBMiss, UnknownException)
+ STD_EXCEPTION(0x1200, DataTLBMiss, UnknownException)
+ STD_EXCEPTION(0x1300, InstructionTLBError, UnknownException)
+ STD_EXCEPTION(0x1400, DataTLBError, UnknownException)
+ STD_EXCEPTION(0x1500, Reserved5, UnknownException)
+ STD_EXCEPTION(0x1600, Reserved6, UnknownException)
+ STD_EXCEPTION(0x1700, Reserved7, UnknownException)
+ STD_EXCEPTION(0x1800, Reserved8, UnknownException)
+ STD_EXCEPTION(0x1900, Reserved9, UnknownException)
+ STD_EXCEPTION(0x1a00, ReservedA, UnknownException)
+ STD_EXCEPTION(0x1b00, ReservedB, UnknownException)
+ STD_EXCEPTION(0x1c00, DataBreakpoint, UnknownException)
+ STD_EXCEPTION(0x1d00, InstructionBreakpoint, UnknownException)
+ STD_EXCEPTION(0x1e00, PeripheralBreakpoint, UnknownException)
+ STD_EXCEPTION(0x1f00, DevPortBreakpoint, UnknownException)
+
+ .globl _end_of_vectors
+_end_of_vectors:
+
+ . = 0x2000
+
+boot_cold:
+boot_warm:
+
+ /* if this is a multi-core system we need to check which cpu
+ * this is, if it is not cpu 0 send the cpu to the linux reset
+ * vector */
+#if (CONFIG_NUM_CPUS > 1)
+ mfspr r0, MSSCR0
+ andi. r0, r0, 0x0020
+ rlwinm r0,r0,27,31,31
+ mtspr PIR, r0
+ beq 1f
+
+ bl secondary_cpu_setup
+#endif
+
+ /* disable everything */
+1: li r0, 0
+ mtspr HID0, r0
+ sync
+ mtmsr 0
+ bl invalidate_bats
+ sync
+
+#ifdef CFG_L2
+ /* init the L2 cache */
+ addis r3, r0, L2_INIT@h
+ ori r3, r3, L2_INIT@l
+ mtspr l2cr, r3
+ /* invalidate the L2 cache */
+ bl l2cache_invalidate
+ sync
+#endif
+
+ /*
+ * Calculate absolute address in FLASH and jump there
+ *------------------------------------------------------*/
+ lis r3, CFG_MONITOR_BASE@h
+ ori r3, r3, CFG_MONITOR_BASE@l
+ addi r3, r3, in_flash - _start + EXC_OFF_SYS_RESET
+ mtlr r3
+ blr
+
+in_flash:
+ /* let the C-code set up the rest */
+ /* */
+ /* Be careful to keep code relocatable ! */
+ /*------------------------------------------------------*/
+ /* perform low-level init */
+
+ /* enable extended addressing */
+ bl enable_ext_addr
+
+ /* setup the bats */
+ bl setup_bats
+ sync
+
+#if (CFG_CCSRBAR_DEFAULT != CFG_CCSRBAR)
+ /* setup ccsrbar */
+ bl setup_ccsrbar
+#endif
+
+ /* Fix for SMP linux - Changing arbitration to round-robin */
+ lis r3, CFG_CCSRBAR@h
+ ori r3, r3, 0x1000
+ xor r4, r4, r4
+ li r4, 0x1000
+ stw r4, 0(r3)
+
+ /* setup the law entries */
+ bl law_entry
+ sync
+
+ /* Don't use this feature due to bug in 8641D PD4 */
+ /* Disable ERD_DIS */
+ lis r3, CFG_CCSRBAR@h
+ ori r3, r3, 0x1008
+ lwz r4, 0(r3)
+ oris r4, r4, 0x4000
+ stw r4, 0(r3)
+ sync
+
+#if (EMULATOR_RUN == 1)
+ /* On the emulator we want to adjust these ASAP */
+ /* otherwise things are sloooow */
+ /* Setup OR0 (LALE FIX)*/
+ lis r3, CFG_CCSRBAR@h
+ ori r3, r3, 0x5004
+ li r4, 0x0FF3
+ stw r4, 0(r3)
+ sync
+
+ /* Setup LCRR */
+ lis r3, CFG_CCSRBAR@h
+ ori r3, r3, 0x50D4
+ lis r4, 0x8000
+ ori r4, r4, 0x0002
+ stw r4, 0(r3)
+ sync
+#endif
+#if 1
+ /* make sure timer enabled in guts register too */
+ lis r3, CFG_CCSRBAR@h
+ oris r3,r3, 0xE
+ ori r3,r3,0x0070
+ lwz r4, 0(r3)
+ lis r5,0xFFFC
+ ori r5,r5,0x5FFF
+ and r4,r4,r5
+ stw r4,0(r3)
+#endif
+ /*
+ * Cache must be enabled here for stack-in-cache trick.
+ * This means we need to enable the BATS.
+ * Cache should be turned on after BATs, since by default
+ * everything is write-through.
+ */
+
+ /* enable address translation */
+ bl enable_addr_trans
+ sync
+
+ /* enable and invalidate the data cache */
+/* bl l1dcache_enable */
+ bl dcache_enable
+ sync
+
+#if 1
+ bl icache_enable
+#endif
+
+#ifdef CFG_INIT_RAM_LOCK
+ bl lock_ram_in_cache
+ sync
+#endif
+
+ /* set up the stack pointer in our newly created
+ * cache-ram (r1) */
+ lis r1, (CFG_INIT_RAM_ADDR + CFG_GBL_DATA_OFFSET)@h
+ ori r1, r1, (CFG_INIT_RAM_ADDR + CFG_GBL_DATA_OFFSET)@l
+
+ li r0, 0 /* Make room for stack frame header and */
+ stwu r0, -4(r1) /* clear final stack frame so that */
+ stwu r0, -4(r1) /* stack backtraces terminate cleanly */
+
+ GET_GOT /* initialize GOT access */
+
+ /* run low-level CPU init code (from Flash) */
+ bl cpu_init_f
+ sync
+
+#ifdef RUN_DIAG
+
+ /* Sri: Code to run the diagnostic automatically */
+
+ /* Load PX_AUX register address in r4 */
+ lis r4, 0xf810
+ ori r4, r4, 0x6
+ /* Load contents of PX_AUX in r3 bits 24 to 31*/
+ lbz r3, 0(r4)
+
+ /* Mask and obtain the bit in r3 */
+ rlwinm. r3, r3, 0, 24, 24
+ /* If not zero, jump and continue with u-boot */
+ bne diag_done
+
+ /* Load back contents of PX_AUX in r3 bits 24 to 31 */
+ lbz r3, 0(r4)
+ /* Set the MSB of the register value */
+ ori r3, r3, 0x80
+ /* Write value in r3 back to PX_AUX */
+ stb r3, 0(r4)
+
+ /* Get the address to jump to in r3*/
+ lis r3, CFG_DIAG_ADDR@h
+ ori r3, r3, CFG_DIAG_ADDR@l
+
+ /* Load the LR with the branch address */
+ mtlr r3
+
+ /* Branch to diagnostic */
+ blr
+
+diag_done:
+#endif
+
+/* bl l2cache_enable */
+ mr r3, r21
+
+ /* r3: BOOTFLAG */
+ /* run 1st part of board init code (from Flash) */
+ bl board_init_f
+ sync
+
+ /* NOTREACHED */
+
+ .globl invalidate_bats
+invalidate_bats:
+
+ /* invalidate BATs */
+ mtspr IBAT0U, r0
+ mtspr IBAT1U, r0
+ mtspr IBAT2U, r0
+ mtspr IBAT3U, r0
+ mtspr IBAT4U, r0
+ mtspr IBAT5U, r0
+ mtspr IBAT6U, r0
+ mtspr IBAT7U, r0
+
+ isync
+ mtspr DBAT0U, r0
+ mtspr DBAT1U, r0
+ mtspr DBAT2U, r0
+ mtspr DBAT3U, r0
+ mtspr DBAT4U, r0
+ mtspr DBAT5U, r0
+ mtspr DBAT6U, r0
+ mtspr DBAT7U, r0
+
+ isync
+ sync
+ blr
+
+
+ /* setup_bats - set them up to some initial state */
+ .globl setup_bats
+setup_bats:
+
+ addis r0, r0, 0x0000
+
+ /* IBAT 0 */
+ addis r4, r0, CFG_IBAT0L@h
+ ori r4, r4, CFG_IBAT0L@l
+ addis r3, r0, CFG_IBAT0U@h
+ ori r3, r3, CFG_IBAT0U@l
+ mtspr IBAT0L, r4
+ mtspr IBAT0U, r3
+ isync
+
+ /* DBAT 0 */
+ addis r4, r0, CFG_DBAT0L@h
+ ori r4, r4, CFG_DBAT0L@l
+ addis r3, r0, CFG_DBAT0U@h
+ ori r3, r3, CFG_DBAT0U@l
+ mtspr DBAT0L, r4
+ mtspr DBAT0U, r3
+ isync
+
+ /* IBAT 1 */
+ addis r4, r0, CFG_IBAT1L@h
+ ori r4, r4, CFG_IBAT1L@l
+ addis r3, r0, CFG_IBAT1U@h
+ ori r3, r3, CFG_IBAT1U@l
+ mtspr IBAT1L, r4
+ mtspr IBAT1U, r3
+ isync
+
+ /* DBAT 1 */
+ addis r4, r0, CFG_DBAT1L@h
+ ori r4, r4, CFG_DBAT1L@l
+ addis r3, r0, CFG_DBAT1U@h
+ ori r3, r3, CFG_DBAT1U@l
+ mtspr DBAT1L, r4
+ mtspr DBAT1U, r3
+ isync
+
+ /* IBAT 2 */
+ addis r4, r0, CFG_IBAT2L@h
+ ori r4, r4, CFG_IBAT2L@l
+ addis r3, r0, CFG_IBAT2U@h
+ ori r3, r3, CFG_IBAT2U@l
+ mtspr IBAT2L, r4
+ mtspr IBAT2U, r3
+ isync
+
+ /* DBAT 2 */
+ addis r4, r0, CFG_DBAT2L@h
+ ori r4, r4, CFG_DBAT2L@l
+ addis r3, r0, CFG_DBAT2U@h
+ ori r3, r3, CFG_DBAT2U@l
+ mtspr DBAT2L, r4
+ mtspr DBAT2U, r3
+ isync
+
+ /* IBAT 3 */
+ addis r4, r0, CFG_IBAT3L@h
+ ori r4, r4, CFG_IBAT3L@l
+ addis r3, r0, CFG_IBAT3U@h
+ ori r3, r3, CFG_IBAT3U@l
+ mtspr IBAT3L, r4
+ mtspr IBAT3U, r3
+ isync
+
+ /* DBAT 3 */
+ addis r4, r0, CFG_DBAT3L@h
+ ori r4, r4, CFG_DBAT3L@l
+ addis r3, r0, CFG_DBAT3U@h
+ ori r3, r3, CFG_DBAT3U@l
+ mtspr DBAT3L, r4
+ mtspr DBAT3U, r3
+ isync
+
+ /* IBAT 4 */
+ addis r4, r0, CFG_IBAT4L@h
+ ori r4, r4, CFG_IBAT4L@l
+ addis r3, r0, CFG_IBAT4U@h
+ ori r3, r3, CFG_IBAT4U@l
+ mtspr IBAT4L, r4
+ mtspr IBAT4U, r3
+ isync
+
+ /* DBAT 4 */
+ addis r4, r0, CFG_DBAT4L@h
+ ori r4, r4, CFG_DBAT4L@l
+ addis r3, r0, CFG_DBAT4U@h
+ ori r3, r3, CFG_DBAT4U@l
+ mtspr DBAT4L, r4
+ mtspr DBAT4U, r3
+ isync
+
+ /* IBAT 5 */
+ addis r4, r0, CFG_IBAT5L@h
+ ori r4, r4, CFG_IBAT5L@l
+ addis r3, r0, CFG_IBAT5U@h
+ ori r3, r3, CFG_IBAT5U@l
+ mtspr IBAT5L, r4
+ mtspr IBAT5U, r3
+ isync
+
+ /* DBAT 5 */
+ addis r4, r0, CFG_DBAT5L@h
+ ori r4, r4, CFG_DBAT5L@l
+ addis r3, r0, CFG_DBAT5U@h
+ ori r3, r3, CFG_DBAT5U@l
+ mtspr DBAT5L, r4
+ mtspr DBAT5U, r3
+ isync
+
+ /* IBAT 6 */
+ addis r4, r0, CFG_IBAT6L@h
+ ori r4, r4, CFG_IBAT6L@l
+ addis r3, r0, CFG_IBAT6U@h
+ ori r3, r3, CFG_IBAT6U@l
+ mtspr IBAT6L, r4
+ mtspr IBAT6U, r3
+ isync
+
+ /* DBAT 6 */
+ addis r4, r0, CFG_DBAT6L@h
+ ori r4, r4, CFG_DBAT6L@l
+ addis r3, r0, CFG_DBAT6U@h
+ ori r3, r3, CFG_DBAT6U@l
+ mtspr DBAT6L, r4
+ mtspr DBAT6U, r3
+ isync
+
+ /* IBAT 7 */
+ addis r4, r0, CFG_IBAT7L@h
+ ori r4, r4, CFG_IBAT7L@l
+ addis r3, r0, CFG_IBAT7U@h
+ ori r3, r3, CFG_IBAT7U@l
+ mtspr IBAT7L, r4
+ mtspr IBAT7U, r3
+ isync
+
+ /* DBAT 7 */
+ addis r4, r0, CFG_DBAT7L@h
+ ori r4, r4, CFG_DBAT7L@l
+ addis r3, r0, CFG_DBAT7U@h
+ ori r3, r3, CFG_DBAT7U@l
+ mtspr DBAT7L, r4
+ mtspr DBAT7U, r3
+ isync
+
+1:
+ addis r3, 0, 0x0000
+ addis r5, 0, 0x4 /* upper bound of 0x00040000 for 7400/750 */
+ isync
+
+tlblp:
+ tlbie r3
+ sync
+ addi r3, r3, 0x1000
+ cmp 0, 0, r3, r5
+ blt tlblp
+
+ blr
+
+ .globl enable_addr_trans
+enable_addr_trans:
+ /* enable address translation */
+ mfmsr r5
+ ori r5, r5, (MSR_IR | MSR_DR)
+ mtmsr r5
+ isync
+ blr
+
+ .globl disable_addr_trans
+disable_addr_trans:
+ /* disable address translation */
+ mflr r4
+ mfmsr r3
+ andi. r0, r3, (MSR_IR | MSR_DR)
+ beqlr
+ andc r3, r3, r0
+ mtspr SRR0, r4
+ mtspr SRR1, r3
+ rfi
+
+/*
+ * This code finishes saving the registers to the exception frame
+ * and jumps to the appropriate handler for the exception.
+ * Register r21 is pointer into trap frame, r1 has new stack pointer.
+ */
+ .globl transfer_to_handler
+transfer_to_handler:
+ stw r22,_NIP(r21)
+ lis r22,MSR_POW@h
+ andc r23,r23,r22
+ stw r23,_MSR(r21)
+ SAVE_GPR(7, r21)
+ SAVE_4GPRS(8, r21)
+ SAVE_8GPRS(12, r21)
+ SAVE_8GPRS(24, r21)
+ mflr r23
+ andi. r24,r23,0x3f00 /* get vector offset */
+ stw r24,TRAP(r21)
+ li r22,0
+ stw r22,RESULT(r21)
+ mtspr SPRG2,r22 /* r1 is now kernel sp */
+ lwz r24,0(r23) /* virtual address of handler */
+ lwz r23,4(r23) /* where to go when done */
+ mtspr SRR0,r24
+ mtspr SRR1,r20
+ mtlr r23
+ SYNC
+ rfi /* jump to handler, enable MMU */
+
+int_return:
+ mfmsr r28 /* Disable interrupts */
+ li r4,0
+ ori r4,r4,MSR_EE
+ andc r28,r28,r4
+ SYNC /* Some chip revs need this... */
+ mtmsr r28
+ SYNC
+ lwz r2,_CTR(r1)
+ lwz r0,_LINK(r1)
+ mtctr r2
+ mtlr r0
+ lwz r2,_XER(r1)
+ lwz r0,_CCR(r1)
+ mtspr XER,r2
+ mtcrf 0xFF,r0
+ REST_10GPRS(3, r1)
+ REST_10GPRS(13, r1)
+ REST_8GPRS(23, r1)
+ REST_GPR(31, r1)
+ lwz r2,_NIP(r1) /* Restore environment */
+ lwz r0,_MSR(r1)
+ mtspr SRR0,r2
+ mtspr SRR1,r0
+ lwz r0,GPR0(r1)
+ lwz r2,GPR2(r1)
+ lwz r1,GPR1(r1)
+ SYNC
+ rfi
+
+ .globl dc_read
+dc_read:
+ blr
+
+ .globl get_pvr
+get_pvr:
+ mfspr r3, PVR
+ blr
+
+ .globl get_svr
+get_svr:
+ mfspr r3, SVR
+ blr
+
+
+/*
+ * Function: in8
+ * Description: Input 8 bits
+ */
+ .globl in8
+in8:
+ lbz r3,0x0000(r3)
+ blr
+
+/*
+ * Function: out8
+ * Description: Output 8 bits
+ */
+ .globl out8
+out8:
+ stb r4,0x0000(r3)
+ blr
+
+/*
+ * Function: out16
+ * Description: Output 16 bits
+ */
+ .globl out16
+out16:
+ sth r4,0x0000(r3)
+ blr
+
+/*
+ * Function: out16r
+ * Description: Byte reverse and output 16 bits
+ */
+ .globl out16r
+out16r:
+ sthbrx r4,r0,r3
+ blr
+
+/*
+ * Function: out32
+ * Description: Output 32 bits
+ */
+ .globl out32
+out32:
+ stw r4,0x0000(r3)
+ blr
+
+/*
+ * Function: out32r
+ * Description: Byte reverse and output 32 bits
+ */
+ .globl out32r
+out32r:
+ stwbrx r4,r0,r3
+ blr
+
+/*
+ * Function: in16
+ * Description: Input 16 bits
+ */
+ .globl in16
+in16:
+ lhz r3,0x0000(r3)
+ blr
+
+/*
+ * Function: in16r
+ * Description: Input 16 bits and byte reverse
+ */
+ .globl in16r
+in16r:
+ lhbrx r3,r0,r3
+ blr
+
+/*
+ * Function: in32
+ * Description: Input 32 bits
+ */
+ .globl in32
+in32:
+ lwz 3,0x0000(3)
+ blr
+
+/*
+ * Function: in32r
+ * Description: Input 32 bits and byte reverse
+ */
+ .globl in32r
+in32r:
+ lwbrx r3,r0,r3
+ blr
+
+/*
+ * Function: ppcDcbf
+ * Description: Data Cache block flush
+ * Input: r3 = effective address
+ * Output: none.
+ */
+ .globl ppcDcbf
+ppcDcbf:
+ dcbf r0,r3
+ blr
+
+/*
+ * Function: ppcDcbi
+ * Description: Data Cache block Invalidate
+ * Input: r3 = effective address
+ * Output: none.
+ */
+ .globl ppcDcbi
+ppcDcbi:
+ dcbi r0,r3
+ blr
+
+/*
+ * Function: ppcDcbz
+ * Description: Data Cache block zero.
+ * Input: r3 = effective address
+ * Output: none.
+ */
+ .globl ppcDcbz
+ppcDcbz:
+ dcbz r0,r3
+ blr
+
+/*
+ * Function: ppcSync
+ * Description: Processor Synchronize
+ * Input: none.
+ * Output: none.
+ */
+ .globl ppcSync
+ppcSync:
+ sync
+ blr
+
+/*
+ * void relocate_code (addr_sp, gd, addr_moni)
+ *
+ * This "function" does not return, instead it continues in RAM
+ * after relocating the monitor code.
+ *
+ * r3 = dest
+ * r4 = src
+ * r5 = length in bytes
+ * r6 = cachelinesize
+ */
+ .globl relocate_code
+relocate_code:
+
+ mr r1, r3 /* Set new stack pointer */
+ mr r9, r4 /* Save copy of Global Data pointer */
+ mr r29, r9 /* Save for DECLARE_GLOBAL_DATA_PTR */
+ mr r10, r5 /* Save copy of Destination Address */
+
+ mr r3, r5 /* Destination Address */
+ lis r4, CFG_MONITOR_BASE@h /* Source Address */
+ ori r4, r4, CFG_MONITOR_BASE@l
+ lwz r5, GOT(__init_end)
+ sub r5, r5, r4
+ li r6, CFG_CACHELINE_SIZE /* Cache Line Size */
+
+ /*
+ * Fix GOT pointer:
+ *
+ * New GOT-PTR = (old GOT-PTR - CFG_MONITOR_BASE) + Destination Address
+ *
+ * Offset:
+ */
+ sub r15, r10, r4
+
+ /* First our own GOT */
+ add r14, r14, r15
+ /* then the one used by the C code */
+ add r30, r30, r15
+
+ /*
+ * Now relocate code
+ */
+#ifdef CONFIG_ECC
+ bl board_relocate_rom
+ sync
+ mr r3, r10 /* Destination Address */
+ lis r4, CFG_MONITOR_BASE@h /* Source Address */
+ ori r4, r4, CFG_MONITOR_BASE@l
+ lwz r5, GOT(__init_end)
+ sub r5, r5, r4
+ li r6, CFG_CACHELINE_SIZE /* Cache Line Size */
+#else
+ cmplw cr1,r3,r4
+ addi r0,r5,3
+ srwi. r0,r0,2
+ beq cr1,4f /* In place copy is not necessary */
+ beq 7f /* Protect against 0 count */
+ mtctr r0
+ bge cr1,2f
+
+ la r8,-4(r4)
+ la r7,-4(r3)
+1: lwzu r0,4(r8)
+ stwu r0,4(r7)
+ bdnz 1b
+ b 4f
+
+2: slwi r0,r0,2
+ add r8,r4,r0
+ add r7,r3,r0
+3: lwzu r0,-4(r8)
+ stwu r0,-4(r7)
+ bdnz 3b
+#endif
+/*
+ * Now flush the cache: note that we must start from a cache aligned
+ * address. Otherwise we might miss one cache line.
+ */
+4: cmpwi r6,0
+ add r5,r3,r5
+ beq 7f /* Always flush prefetch queue in any case */
+ subi r0,r6,1
+ andc r3,r3,r0
+ mr r4,r3
+5: dcbst 0,r4
+ add r4,r4,r6
+ cmplw r4,r5
+ blt 5b
+ sync /* Wait for all dcbst to complete on bus */
+ mr r4,r3
+6: icbi 0,r4
+ add r4,r4,r6
+ cmplw r4,r5
+ blt 6b
+7: sync /* Wait for all icbi to complete on bus */
+ isync
+
+/*
+ * We are done. Do not return, instead branch to second part of board
+ * initialization, now running from RAM.
+ */
+ addi r0, r10, in_ram - _start + EXC_OFF_SYS_RESET
+ mtlr r0
+ blr
+
+in_ram:
+#ifdef CONFIG_ECC
+ bl board_init_ecc
+#endif
+ /*
+ * Relocation Function, r14 point to got2+0x8000
+ *
+ * Adjust got2 pointers, no need to check for 0, this code
+ * already puts a few entries in the table.
+ */
+ li r0,__got2_entries@sectoff@l
+ la r3,GOT(_GOT2_TABLE_)
+ lwz r11,GOT(_GOT2_TABLE_)
+ mtctr r0
+ sub r11,r3,r11
+ addi r3,r3,-4
+1: lwzu r0,4(r3)
+ add r0,r0,r11
+ stw r0,0(r3)
+ bdnz 1b
+
+ /*
+ * Now adjust the fixups and the pointers to the fixups
+ * in case we need to move ourselves again.
+ */
+2: li r0,__fixup_entries@sectoff@l
+ lwz r3,GOT(_FIXUP_TABLE_)
+ cmpwi r0,0
+ mtctr r0
+ addi r3,r3,-4
+ beq 4f
+3: lwzu r4,4(r3)
+ lwzux r0,r4,r11
+ add r0,r0,r11
+ stw r10,0(r3)
+ stw r0,0(r4)
+ bdnz 3b
+4:
+/* clear_bss: */
+ /*
+ * Now clear BSS segment
+ */
+ lwz r3,GOT(__bss_start)
+ lwz r4,GOT(_end)
+
+ cmplw 0, r3, r4
+ beq 6f
+
+ li r0, 0
+5:
+ stw r0, 0(r3)
+ addi r3, r3, 4
+ cmplw 0, r3, r4
+ bne 5b
+6:
+ mr r3, r9 /* Init Date pointer */
+ mr r4, r10 /* Destination Address */
+ bl board_init_r
+
+ /* not reached - end relocate_code */
+/*-----------------------------------------------------------------------*/
+
+ /*
+ * Copy exception vector code to low memory
+ *
+ * r3: dest_addr
+ * r7: source address, r8: end address, r9: target address
+ */
+ .globl trap_init
+trap_init:
+ lwz r7, GOT(_start)
+ lwz r8, GOT(_end_of_vectors)
+
+ li r9, 0x100 /* reset vector always at 0x100 */
+
+ cmplw 0, r7, r8
+ bgelr /* return if r7>=r8 - just in case */
+
+ mflr r4 /* save link register */
+1:
+ lwz r0, 0(r7)
+ stw r0, 0(r9)
+ addi r7, r7, 4
+ addi r9, r9, 4
+ cmplw 0, r7, r8
+ bne 1b
+
+ /*
+ * relocate `hdlr' and `int_return' entries
+ */
+ li r7, .L_MachineCheck - _start + EXC_OFF_SYS_RESET
+ li r8, Alignment - _start + EXC_OFF_SYS_RESET
+2:
+ bl trap_reloc
+ addi r7, r7, 0x100 /* next exception vector */
+ cmplw 0, r7, r8
+ blt 2b
+
+ li r7, .L_Alignment - _start + EXC_OFF_SYS_RESET
+ bl trap_reloc
+
+ li r7, .L_ProgramCheck - _start + EXC_OFF_SYS_RESET
+ bl trap_reloc
+
+ li r7, .L_FPUnavailable - _start + EXC_OFF_SYS_RESET
+ li r8, SystemCall - _start + EXC_OFF_SYS_RESET
+3:
+ bl trap_reloc
+ addi r7, r7, 0x100 /* next exception vector */
+ cmplw 0, r7, r8
+ blt 3b
+
+ li r7, .L_SingleStep - _start + EXC_OFF_SYS_RESET
+ li r8, _end_of_vectors - _start + EXC_OFF_SYS_RESET
+4:
+ bl trap_reloc
+ addi r7, r7, 0x100 /* next exception vector */
+ cmplw 0, r7, r8
+ blt 4b
+
+ /* enable execptions from RAM vectors */
+ mfmsr r7
+ li r8,MSR_IP
+ andc r7,r7,r8
+ mtmsr r7
+
+ mtlr r4 /* restore link register */
+ blr
+
+ /*
+ * Function: relocate entries for one exception vector
+ */
+trap_reloc:
+ lwz r0, 0(r7) /* hdlr ... */
+ add r0, r0, r3 /* ... += dest_addr */
+ stw r0, 0(r7)
+
+ lwz r0, 4(r7) /* int_return ... */
+ add r0, r0, r3 /* ... += dest_addr */
+ stw r0, 4(r7)
+
+ sync
+ isync
+
+ blr
+
+.globl enable_ext_addr
+enable_ext_addr:
+ mfspr r0, HID0
+ lis r0, (HID0_HIGH_BAT_EN | HID0_XBSEN | HID0_XAEN)@h
+ ori r0, r0, (HID0_HIGH_BAT_EN | HID0_XBSEN | HID0_XAEN)@l
+ mtspr HID0, r0
+ sync
+ isync
+ blr
+
+#if (CFG_CCSRBAR_DEFAULT != CFG_CCSRBAR)
+.globl setup_ccsrbar
+setup_ccsrbar:
+ /* Special sequence needed to update CCSRBAR itself */
+ lis r4, CFG_CCSRBAR_DEFAULT@h
+ ori r4, r4, CFG_CCSRBAR_DEFAULT@l
+
+ lis r5, CFG_CCSRBAR@h
+ ori r5, r5, CFG_CCSRBAR@l
+ srwi r6,r5,12
+ stw r6, 0(r4)
+ isync
+
+ lis r5, 0xffff
+ ori r5,r5,0xf000
+ lwz r5, 0(r5)
+ isync
+
+ lis r3, CFG_CCSRBAR@h
+ lwz r5, CFG_CCSRBAR@l(r3)
+ isync
+
+ blr
+#endif
+
+#ifdef CFG_INIT_RAM_LOCK
+lock_ram_in_cache:
+ /* Allocate Initial RAM in data cache.
+ */
+ lis r3, (CFG_INIT_RAM_ADDR & ~31)@h
+ ori r3, r3, (CFG_INIT_RAM_ADDR & ~31)@l
+ li r2, ((CFG_INIT_RAM_END & ~31) + \
+ (CFG_INIT_RAM_ADDR & 31) + 31) / 32
+ mtctr r2
+1:
+ dcbz r0, r3
+ addi r3, r3, 32
+ bdnz 1b
+#if 1
+/* Lock the data cache */
+ mfspr r0, HID0
+ ori r0, r0, 0x1000
+ sync
+ mtspr HID0, r0
+ sync
+ blr
+#endif
+#if 0
+ /* Lock the first way of the data cache */
+ mfspr r0, LDSTCR
+ ori r0, r0, 0x0080
+#if defined(CONFIG_ALTIVEC)
+ dssall
+#endif
+ sync
+ mtspr LDSTCR, r0
+ sync
+ isync
+ blr
+#endif
+
+.globl unlock_ram_in_cache
+unlock_ram_in_cache:
+ /* invalidate the INIT_RAM section */
+ lis r3, (CFG_INIT_RAM_ADDR & ~31)@h
+ ori r3, r3, (CFG_INIT_RAM_ADDR & ~31)@l
+ li r2, ((CFG_INIT_RAM_END & ~31) + \
+ (CFG_INIT_RAM_ADDR & 31) + 31) / 32
+ mtctr r2
+1: icbi r0, r3
+ addi r3, r3, 32
+ bdnz 1b
+ sync /* Wait for all icbi to complete on bus */
+ isync
+#if 1
+/* Unlock the data cache and invalidate it */
+ mfspr r0, HID0
+ li r3,0x1000
+ andc r0,r0,r3
+ li r3,0x0400
+ or r0,r0,r3
+ sync
+ mtspr HID0, r0
+ sync
+ blr
+#endif
+#if 0
+ /* Unlock the first way of the data cache */
+ mfspr r0, LDSTCR
+ li r3,0x0080
+ andc r0,r0,r3
+#ifdef CONFIG_ALTIVEC
+ dssall
+#endif
+ sync
+ mtspr LDSTCR, r0
+ sync
+ isync
+ li r3,0x0400
+ or r0,r0,r3
+ sync
+ mtspr HID0, r0
+ sync
+ blr
+#endif
+#endif
+
+/* If this is a multi-cpu system then we need to handle the
+ * 2nd cpu. The assumption is that the 2nd cpu is being
+ * held in boot holdoff mode until the 1st cpu unlocks it
+ * from Linux. We'll do some basic cpu init and then pass
+ * it to the Linux Reset Vector.
+ * Sri: Much of this initialization is not required. Linux
+ * rewrites the bats, and the sprs and also enables the L1 cache.
+ */
+#if (CONFIG_NUM_CPUS > 1)
+.globl secondary_cpu_setup
+secondary_cpu_setup:
+ /* Do only core setup on all cores except cpu0 */
+ bl invalidate_bats
+ sync
+ bl enable_ext_addr
+
+#ifdef CFG_L2
+ /* init the L2 cache */
+ addis r3, r0, L2_INIT@h
+ ori r3, r3, L2_INIT@l
+ sync
+ mtspr l2cr, r3
+#ifdef CONFIG_ALTIVEC
+ dssall
+#endif
+ /* invalidate the L2 cache */
+ bl l2cache_invalidate
+ sync
+#endif
+
+ /* enable and invalidate the data cache */
+ bl dcache_enable
+ sync
+
+ /* enable and invalidate the instruction cache*/
+ bl icache_enable
+ sync
+
+ /* TBEN in HID0 */
+ mfspr r4, HID0
+ oris r4, r4, 0x0400
+ mtspr HID0, r4
+ sync
+ isync
+
+ /*SYNCBE|ABE in HID1*/
+ mfspr r4, HID1
+ ori r4, r4, 0x0C00
+ mtspr HID1, r4
+ sync
+ isync
+
+ lis r3, CONFIG_LINUX_RESET_VEC@h
+ ori r3, r3, CONFIG_LINUX_RESET_VEC@l
+ mtlr r3
+ blr
+
+ /* Never Returns, Running in Linux Now */
+#endif
diff --git a/cpu/mpc86xx/traps.c b/cpu/mpc86xx/traps.c
new file mode 100644
index 0000000..8ea14e5
--- /dev/null
+++ b/cpu/mpc86xx/traps.c
@@ -0,0 +1,226 @@
+/*
+ * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
+ *
+ * Modified by Cort Dougan (cort@cs.nmt.edu)
+ * and Paul Mackerras (paulus@cs.anu.edu.au)
+ *
+ * (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
+ */
+
+/*
+ * This file handles the architecture-dependent parts of hardware exceptions
+ */
+
+#include <common.h>
+#include <command.h>
+#include <asm/processor.h>
+
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+int (*debugger_exception_handler)(struct pt_regs *) = 0;
+#endif
+
+/* Returns 0 if exception not found and fixup otherwise. */
+extern unsigned long search_exception_table(unsigned long);
+
+#define END_OF_MEM (gd->bd->bi_memstart + gd->bd->bi_memsize)
+
+/*
+ * Trap & Exception support
+ */
+
+void
+print_backtrace(unsigned long *sp)
+{
+ DECLARE_GLOBAL_DATA_PTR;
+
+ int cnt = 0;
+ unsigned long i;
+
+ printf("Call backtrace: ");
+ while (sp) {
+ if ((uint) sp > END_OF_MEM)
+ break;
+
+ i = sp[1];
+ if (cnt++ % 7 == 0)
+ printf("\n");
+ printf("%08lX ", i);
+ if (cnt > 32)
+ break;
+ sp = (unsigned long *)*sp;
+ }
+ printf("\n");
+}
+
+void
+show_regs(struct pt_regs *regs)
+{
+ int i;
+
+ printf("NIP: %08lX XER: %08lX LR: %08lX REGS:"
+ " %p TRAP: %04lx DAR: %08lX\n",
+ regs->nip, regs->xer, regs->link, regs, regs->trap, regs->dar);
+ printf("MSR: %08lx EE: %01x PR: %01x FP:"
+ " %01x ME: %01x IR/DR: %01x%01x\n",
+ regs->msr, regs->msr & MSR_EE ? 1 : 0,
+ regs->msr & MSR_PR ? 1 : 0, regs->msr & MSR_FP ? 1 : 0,
+ regs->msr & MSR_ME ? 1 : 0, regs->msr & MSR_IR ? 1 : 0,
+ regs->msr & MSR_DR ? 1 : 0);
+
+ printf("\n");
+ for (i = 0; i < 32; i++) {
+ if ((i % 8) == 0) {
+ printf("GPR%02d: ", i);
+ }
+
+ printf("%08lX ", regs->gpr[i]);
+ if ((i % 8) == 7) {
+ printf("\n");
+ }
+ }
+}
+
+
+void
+_exception(int signr, struct pt_regs *regs)
+{
+ show_regs(regs);
+ print_backtrace((unsigned long *)regs->gpr[1]);
+ panic("Exception in kernel pc %lx signal %d", regs->nip, signr);
+}
+
+void
+MachineCheckException(struct pt_regs *regs)
+{
+ unsigned long fixup;
+
+ /* Probing PCI using config cycles cause this exception
+ * when a device is not present. Catch it and return to
+ * the PCI exception handler.
+ */
+ if ((fixup = search_exception_table(regs->nip)) != 0) {
+ regs->nip = fixup;
+ return;
+ }
+
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+ if (debugger_exception_handler && (*debugger_exception_handler) (regs))
+ return;
+#endif
+
+ printf("Machine check in kernel mode.\n");
+ printf("Caused by (from msr): ");
+ printf("regs %p ", regs);
+ switch (regs->msr & 0x000F0000) {
+ case (0x80000000 >> 12):
+ printf("Machine check signal - probably due to mm fault\n"
+ "with mmu off\n");
+ break;
+ case (0x80000000 >> 13):
+ printf("Transfer error ack signal\n");
+ break;
+ case (0x80000000 >> 14):
+ printf("Data parity signal\n");
+ break;
+ case (0x80000000 >> 15):
+ printf("Address parity signal\n");
+ break;
+ default:
+ printf("Unknown values in msr\n");
+ }
+ show_regs(regs);
+ print_backtrace((unsigned long *)regs->gpr[1]);
+ panic("machine check");
+}
+
+void
+AlignmentException(struct pt_regs *regs)
+{
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+ if (debugger_exception_handler && (*debugger_exception_handler) (regs))
+ return;
+#endif
+ show_regs(regs);
+ print_backtrace((unsigned long *)regs->gpr[1]);
+ panic("Alignment Exception");
+}
+
+void
+ProgramCheckException(struct pt_regs *regs)
+{
+ unsigned char *p = regs ? (unsigned char *)(regs->nip) : NULL;
+ int i, j;
+
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+ if (debugger_exception_handler && (*debugger_exception_handler) (regs))
+ return;
+#endif
+ show_regs(regs);
+
+ p = (unsigned char *)((unsigned long)p & 0xFFFFFFE0);
+ p -= 32;
+ for (i = 0; i < 256; i += 16) {
+ printf("%08x: ", (unsigned int)p + i);
+ for (j = 0; j < 16; j++) {
+ printf("%02x ", p[i + j]);
+ }
+ printf("\n");
+ }
+
+ print_backtrace((unsigned long *)regs->gpr[1]);
+ panic("Program Check Exception");
+}
+
+void
+SoftEmuException(struct pt_regs *regs)
+{
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+ if (debugger_exception_handler && (*debugger_exception_handler) (regs))
+ return;
+#endif
+ show_regs(regs);
+ print_backtrace((unsigned long *)regs->gpr[1]);
+ panic("Software Emulation Exception");
+}
+
+void
+UnknownException(struct pt_regs *regs)
+{
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+ if (debugger_exception_handler && (*debugger_exception_handler) (regs))
+ return;
+#endif
+ printf("Bad trap at PC: %lx, SR: %lx, vector=%lx\n",
+ regs->nip, regs->msr, regs->trap);
+ _exception(0, regs);
+}
+
+/*
+ * Probe an address by reading.
+ * If not present, return -1,
+ * otherwise return 0.
+ */
+int
+addr_probe(uint *addr)
+{
+ return 0;
+}
diff --git a/cpu/mpc8xx/Makefile b/cpu/mpc8xx/Makefile
index de75fad..223b30c 100644
--- a/cpu/mpc8xx/Makefile
+++ b/cpu/mpc8xx/Makefile
@@ -1,5 +1,5 @@
#
-# (C) Copyright 2000
+# (C) Copyright 2000-2006
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
#
# See file CREDITS for list of people who contributed to this
@@ -25,25 +25,29 @@ include $(TOPDIR)/config.mk
# CFLAGS += -DET_DEBUG
-LIB = lib$(CPU).a
+LIB = $(obj)lib$(CPU).a
START = start.o kgdb.o
-OBJS = bedbug_860.o commproc.o cpu.o cpu_init.o \
+COBJS = bedbug_860.o commproc.o cpu.o cpu_init.o \
fec.o i2c.o interrupts.o lcd.o scc.o \
serial.o speed.o spi.o \
traps.o upatch.o video.o
SOBJS = plprcr_write.o
-all: .depend $(START) $(LIB)
+SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
+START := $(addprefix $(obj),$(START))
-$(LIB): $(OBJS) $(SOBJS)
- $(AR) crv $@ $(OBJS) $(SOBJS) kgdb.o
+all: $(obj).depend $(START) $(LIB)
+
+$(LIB): $(OBJS)
+ $(AR) $(ARFLAGS) $@ $(OBJS) $(obj)kgdb.o
#########################################################################
-.depend: Makefile $(START:.o=.S) $(OBJS:.o=.c) $(SOBJS:.o=.S)
- $(CC) -M $(CFLAGS) $(START:.o=.S) $(OBJS:.o=.c) $(SOBJS:.o=.S) > $@
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
-sinclude .depend
+sinclude $(obj).depend
#########################################################################
diff --git a/cpu/nios/Makefile b/cpu/nios/Makefile
index 7855325..ad17456 100644
--- a/cpu/nios/Makefile
+++ b/cpu/nios/Makefile
@@ -1,5 +1,5 @@
#
-# (C) Copyright 2000
+# (C) Copyright 2000-2006
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
#
# See file CREDITS for list of people who contributed to this
@@ -23,22 +23,26 @@
include $(TOPDIR)/config.mk
-LIB = lib$(CPU).a
+LIB = $(obj)lib$(CPU).a
START = start.o
-AOBJS = traps.o
-OBJS = cpu.o interrupts.o serial.o asmi.o spi.o
+SOBJS = traps.o
+COBJS = cpu.o interrupts.o serial.o asmi.o spi.o
-all: .depend $(START) $(LIB)
+SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
+START := $(addprefix $(obj),$(START))
-$(LIB): $(OBJS) $(AOBJS)
- $(AR) crv $@ $(OBJS) $(AOBJS)
+all: $(obj).depend $(START) $(LIB)
+
+$(LIB): $(OBJS)
+ $(AR) $(ARFLAGS) $@ $(OBJS)
#########################################################################
-.depend: Makefile $(START:.o=.S) $(OBJS:.o=.c) $(AOBJS:.o=.S)
- $(CC) -M $(CFLAGS) $(START:.o=.S) $(OBJS:.o=.c) $(AOBJS:.o=.S) > $@
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
-sinclude .depend
+sinclude $(obj).depend
#########################################################################
diff --git a/cpu/nios2/Makefile b/cpu/nios2/Makefile
index 11fda50..75f30b4 100644
--- a/cpu/nios2/Makefile
+++ b/cpu/nios2/Makefile
@@ -1,5 +1,5 @@
#
-# (C) Copyright 2000
+# (C) Copyright 2000-2006
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
#
# See file CREDITS for list of people who contributed to this
@@ -23,22 +23,26 @@
include $(TOPDIR)/config.mk
-LIB = lib$(CPU).a
+LIB = $(obj)lib$(CPU).a
START = start.o
-AOBJS = exceptions.o
-OBJS = cpu.o interrupts.o serial.o sysid.o traps.o epcs.o
+SOBJS = exceptions.o
+COBJS = cpu.o interrupts.o serial.o sysid.o traps.o epcs.o
-all: .depend $(START) $(LIB)
+SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
+START := $(addprefix $(obj),$(START))
-$(LIB): $(OBJS) $(AOBJS)
- $(AR) crv $@ $(OBJS) $(AOBJS)
+all: $(obj).depend $(START) $(LIB)
+
+$(LIB): $(OBJS)
+ $(AR) $(ARFLAGS) $@ $(OBJS)
#########################################################################
-.depend: Makefile $(START:.o=.S) $(OBJS:.o=.c) $(AOBJS:.o=.S)
- $(CC) -M $(CFLAGS) $(START:.o=.S) $(OBJS:.o=.c) $(AOBJS:.o=.S) > $@
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
-sinclude .depend
+sinclude $(obj).depend
#########################################################################
diff --git a/cpu/ppc4xx/405gp_pci.c b/cpu/ppc4xx/405gp_pci.c
index cf5eccb..03128d3 100644
--- a/cpu/ppc4xx/405gp_pci.c
+++ b/cpu/ppc4xx/405gp_pci.c
@@ -315,7 +315,6 @@ void pci_405gp_init(struct pci_controller *hose)
#ifdef CONFIG_PCI_SCAN_SHOW
printf("PCI: Bus Dev VenId DevId Class Int\n");
#endif
-
hose->last_busno = pci_hose_scan(hose);
}
#endif /* CONFIG_PCI_PNP */
@@ -556,17 +555,20 @@ void pci_440_init (struct pci_controller *hose)
#ifdef CONFIG_PCI_SCAN_SHOW
printf("PCI: Bus Dev VenId DevId Class Int\n");
#endif
-#if !defined(CONFIG_440EP) && !defined(CONFIG_440GR)
+#if !defined(CONFIG_440EP) && !defined(CONFIG_440GR) && \
+ !defined(CONFIG_440EPX) && !defined(CONFIG_440GRX)
out16r( PCIX0_CMD, in16r( PCIX0_CMD ) | PCI_COMMAND_MASTER);
#endif
hose->last_busno = pci_hose_scan(hose);
}
}
-
void pci_init_board(void)
{
pci_440_init (&ppc440_hose);
+#if defined(CONFIG_440SPE)
+ pcie_setup_hoses();
+#endif
}
#endif /* CONFIG_440 & CONFIG_PCI */
diff --git a/cpu/ppc4xx/440spe_pcie.c b/cpu/ppc4xx/440spe_pcie.c
new file mode 100644
index 0000000..6130cd2
--- /dev/null
+++ b/cpu/ppc4xx/440spe_pcie.c
@@ -0,0 +1,962 @@
+/*
+ * (C) Copyright 2006
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * Copyright (c) 2005 Cisco Systems. All rights reserved.
+ * Roland Dreier <rolandd@cisco.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.
+ *
+ */
+
+#include <asm/processor.h>
+#include <asm-ppc/io.h>
+#include <ppc4xx.h>
+#include <common.h>
+#include <pci.h>
+
+#include "440spe_pcie.h"
+
+#if defined(CONFIG_440SPE)
+#if defined(CONFIG_PCI)
+
+enum {
+ PTYPE_ENDPOINT = 0x0,
+ PTYPE_LEGACY_ENDPOINT = 0x1,
+ PTYPE_ROOT_PORT = 0x4,
+
+ LNKW_X1 = 0x1,
+ LNKW_X4 = 0x4,
+ LNKW_X8 = 0x8
+};
+
+static int pcie_read_config(struct pci_controller *hose, unsigned int devfn,
+ int offset, int len, u32 *val) {
+
+ *val = 0;
+ /*
+ * 440SPE implements only one function per port
+ */
+ if (!((PCI_FUNC(devfn) == 0) && (PCI_DEV(devfn) == 1)))
+ return 0;
+
+ devfn = PCI_BDF(0,0,0);
+ offset += devfn << 4;
+
+ switch (len) {
+ case 1:
+ *val = in_8(hose->cfg_data + offset);
+ break;
+ case 2:
+ *val = in_le16((u16 *)(hose->cfg_data + offset));
+ break;
+ default:
+ *val = in_le32((u32 *)(hose->cfg_data + offset));
+ break;
+ }
+ return 0;
+}
+
+static int pcie_write_config(struct pci_controller *hose, unsigned int devfn,
+ int offset, int len, u32 val) {
+
+ /*
+ * 440SPE implements only one function per port
+ */
+ if (!((PCI_FUNC(devfn) == 0) && (PCI_DEV(devfn) == 1)))
+ return 0;
+
+ devfn = PCI_BDF(0,0,0);
+ offset += devfn << 4;
+
+ switch (len) {
+ case 1:
+ out_8(hose->cfg_data + offset, val);
+ break;
+ case 2:
+ out_le16((u16 *)(hose->cfg_data + offset), val);
+ break;
+ default:
+ out_le32((u32 *)(hose->cfg_data + offset), val);
+ break;
+ }
+ return 0;
+}
+
+int pcie_read_config_byte(struct pci_controller *hose,pci_dev_t dev,int offset,u8 *val)
+{
+ u32 v;
+ int rv;
+
+ rv = pcie_read_config(hose, dev, offset, 1, &v);
+ *val = (u8)v;
+ return rv;
+}
+
+int pcie_read_config_word(struct pci_controller *hose,pci_dev_t dev,int offset,u16 *val)
+{
+ u32 v;
+ int rv;
+
+ rv = pcie_read_config(hose, dev, offset, 2, &v);
+ *val = (u16)v;
+ return rv;
+}
+
+int pcie_read_config_dword(struct pci_controller *hose,pci_dev_t dev,int offset,u32 *val)
+{
+ u32 v;
+ int rv;
+
+ rv = pcie_read_config(hose, dev, offset, 3, &v);
+ *val = (u32)v;
+ return rv;
+}
+
+int pcie_write_config_byte(struct pci_controller *hose,pci_dev_t dev,int offset,u8 val)
+{
+ return pcie_write_config(hose,(u32)dev,offset,1,val);
+}
+
+int pcie_write_config_word(struct pci_controller *hose,pci_dev_t dev,int offset,u16 val)
+{
+ return pcie_write_config(hose,(u32)dev,offset,2,(u32 )val);
+}
+
+int pcie_write_config_dword(struct pci_controller *hose,pci_dev_t dev,int offset,u32 val)
+{
+ return pcie_write_config(hose,(u32)dev,offset,3,(u32 )val);
+}
+
+static void ppc440spe_setup_utl(u32 port) {
+
+ volatile void *utl_base = NULL;
+
+ /*
+ * Map UTL registers
+ */
+ switch (port) {
+ case 0:
+ mtdcr(DCRN_PEGPL_REGBAH(PCIE0), 0x0000000c);
+ mtdcr(DCRN_PEGPL_REGBAL(PCIE0), 0x20000000);
+ mtdcr(DCRN_PEGPL_REGMSK(PCIE0), 0x00007001);
+ mtdcr(DCRN_PEGPL_SPECIAL(PCIE0), 0x68782800);
+ break;
+
+ case 1:
+ mtdcr(DCRN_PEGPL_REGBAH(PCIE1), 0x0000000c);
+ mtdcr(DCRN_PEGPL_REGBAL(PCIE1), 0x20001000);
+ mtdcr(DCRN_PEGPL_REGMSK(PCIE1), 0x00007001);
+ mtdcr(DCRN_PEGPL_SPECIAL(PCIE1), 0x68782800);
+ break;
+
+ case 2:
+ mtdcr(DCRN_PEGPL_REGBAH(PCIE2), 0x0000000c);
+ mtdcr(DCRN_PEGPL_REGBAL(PCIE2), 0x20002000);
+ mtdcr(DCRN_PEGPL_REGMSK(PCIE2), 0x00007001);
+ mtdcr(DCRN_PEGPL_SPECIAL(PCIE2), 0x68782800);
+ break;
+ }
+ utl_base = (unsigned int *)(CFG_PCIE_BASE + 0x1000 * port);
+
+ /*
+ * Set buffer allocations and then assert VRB and TXE.
+ */
+ out_be32(utl_base + PEUTL_OUTTR, 0x08000000);
+ out_be32(utl_base + PEUTL_INTR, 0x02000000);
+ out_be32(utl_base + PEUTL_OPDBSZ, 0x10000000);
+ out_be32(utl_base + PEUTL_PBBSZ, 0x53000000);
+ out_be32(utl_base + PEUTL_IPHBSZ, 0x08000000);
+ out_be32(utl_base + PEUTL_IPDBSZ, 0x10000000);
+ out_be32(utl_base + PEUTL_RCIRQEN, 0x00f00000);
+ out_be32(utl_base + PEUTL_PCTL, 0x80800066);
+}
+
+static int check_error(void)
+{
+ u32 valPE0, valPE1, valPE2;
+ int err = 0;
+
+ /* SDR0_PEGPLLLCT1 reset */
+ if (!(valPE0 = SDR_READ(PESDR0_PLLLCT1) & 0x01000000)) {
+ printf("PCIE: SDR0_PEGPLLLCT1 reset error 0x%x\n", valPE0);
+ }
+
+ valPE0 = SDR_READ(PESDR0_RCSSET);
+ valPE1 = SDR_READ(PESDR1_RCSSET);
+ valPE2 = SDR_READ(PESDR2_RCSSET);
+
+ /* SDR0_PExRCSSET rstgu */
+ if (!(valPE0 & 0x01000000) ||
+ !(valPE1 & 0x01000000) ||
+ !(valPE2 & 0x01000000)) {
+ printf("PCIE: SDR0_PExRCSSET rstgu error\n");
+ err = -1;
+ }
+
+ /* SDR0_PExRCSSET rstdl */
+ if (!(valPE0 & 0x00010000) ||
+ !(valPE1 & 0x00010000) ||
+ !(valPE2 & 0x00010000)) {
+ printf("PCIE: SDR0_PExRCSSET rstdl error\n");
+ err = -1;
+ }
+
+ /* SDR0_PExRCSSET rstpyn */
+ if ((valPE0 & 0x00001000) ||
+ (valPE1 & 0x00001000) ||
+ (valPE2 & 0x00001000)) {
+ printf("PCIE: SDR0_PExRCSSET rstpyn error\n");
+ err = -1;
+ }
+
+ /* SDR0_PExRCSSET hldplb */
+ if ((valPE0 & 0x10000000) ||
+ (valPE1 & 0x10000000) ||
+ (valPE2 & 0x10000000)) {
+ printf("PCIE: SDR0_PExRCSSET hldplb error\n");
+ err = -1;
+ }
+
+ /* SDR0_PExRCSSET rdy */
+ if ((valPE0 & 0x00100000) ||
+ (valPE1 & 0x00100000) ||
+ (valPE2 & 0x00100000)) {
+ printf("PCIE: SDR0_PExRCSSET rdy error\n");
+ err = -1;
+ }
+
+ /* SDR0_PExRCSSET shutdown */
+ if ((valPE0 & 0x00000100) ||
+ (valPE1 & 0x00000100) ||
+ (valPE2 & 0x00000100)) {
+ printf("PCIE: SDR0_PExRCSSET shutdown error\n");
+ err = -1;
+ }
+ return err;
+}
+
+/*
+ * Initialize PCI Express core
+ */
+int ppc440spe_init_pcie(void)
+{
+ int time_out = 20;
+
+ /* Set PLL clock receiver to LVPECL */
+ SDR_WRITE(PESDR0_PLLLCT1, SDR_READ(PESDR0_PLLLCT1) | 1 << 28);
+
+ if (check_error())
+ return -1;
+
+ if (!(SDR_READ(PESDR0_PLLLCT2) & 0x10000))
+ {
+ printf("PCIE: PESDR_PLLCT2 resistance calibration failed (0x%08x)\n",
+ SDR_READ(PESDR0_PLLLCT2));
+ return -1;
+ }
+ /* De-assert reset of PCIe PLL, wait for lock */
+ SDR_WRITE(PESDR0_PLLLCT1, SDR_READ(PESDR0_PLLLCT1) & ~(1 << 24));
+ udelay(3);
+
+ while (time_out) {
+ if (!(SDR_READ(PESDR0_PLLLCT3) & 0x10000000)) {
+ time_out--;
+ udelay(1);
+ } else
+ break;
+ }
+ if (!time_out) {
+ printf("PCIE: VCO output not locked\n");
+ return -1;
+ }
+ return 0;
+}
+
+/*
+ * Yucca board as End point and root point setup
+ * and
+ * testing inbound and out bound windows
+ *
+ * YUCCA board can be plugged into another yucca board or you can get PCI-E
+ * cable which can be used to setup loop back from one port to another port.
+ * Please rememeber that unless there is a endpoint plugged in to root port it
+ * will not initialize. It is the same in case of endpoint , unless there is
+ * root port attached it will not initialize.
+ *
+ * In this release of software all the PCI-E ports are configured as either
+ * endpoint or rootpoint.In future we will have support for selective ports
+ * setup as endpoint and root point in single board.
+ *
+ * Once your board came up as root point , you can verify by reading
+ * /proc/bus/pci/devices. Where you can see the configuration registers
+ * of end point device attached to the port.
+ *
+ * Enpoint cofiguration can be verified by connecting Yucca board to any
+ * host or another yucca board. Then try to scan the device. In case of
+ * linux use "lspci" or appripriate os command.
+ *
+ * How do I verify the inbound and out bound windows ?(yucca to yucca)
+ * in this configuration inbound and outbound windows are setup to access
+ * sram memroy area. SRAM is at 0x4 0000 0000 , on PLB bus. This address
+ * is mapped at 0x90000000. From u-boot prompt write data 0xb000 0000,
+ * This is waere your POM(PLB out bound memory window) mapped. then
+ * read the data from other yucca board's u-boot prompt at address
+ * 0x9000 0000(SRAM). Data should match.
+ * In case of inbound , write data to u-boot command prompt at 0xb000 0000
+ * which is mapped to 0x4 0000 0000. Now on rootpoint yucca u-boot prompt check
+ * data at 0x9000 0000(SRAM).Data should match.
+ */
+int ppc440spe_init_pcie_rootport(int port)
+{
+ static int core_init;
+ volatile u32 val = 0;
+ int attempts;
+
+ if (!core_init) {
+ ++core_init;
+ if (ppc440spe_init_pcie())
+ return -1;
+ }
+
+ /*
+ * Initialize various parts of the PCI Express core for our port:
+ *
+ * - Set as a root port and enable max width
+ * (PXIE0 -> X8, PCIE1 and PCIE2 -> X4).
+ * - Set up UTL configuration.
+ * - Increase SERDES drive strength to levels suggested by AMCC.
+ * - De-assert RSTPYN, RSTDL and RSTGU.
+ *
+ * NOTICE for revB chip: PESDRn_UTLSET2 is not set - we leave it with
+ * default setting 0x11310000. The register has new fields,
+ * PESDRn_UTLSET2[LKINE] in particular: clearing it leads to PCIE core
+ * hang.
+ */
+ switch (port) {
+ case 0:
+ SDR_WRITE(PESDR0_DLPSET, 1 << 24 | PTYPE_ROOT_PORT << 20 | LNKW_X8 << 12);
+
+ SDR_WRITE(PESDR0_UTLSET1, 0x21222222);
+ if (!ppc440spe_revB())
+ SDR_WRITE(PESDR0_UTLSET2, 0x11000000);
+ SDR_WRITE(PESDR0_HSSL0SET1, 0x35000000);
+ SDR_WRITE(PESDR0_HSSL1SET1, 0x35000000);
+ SDR_WRITE(PESDR0_HSSL2SET1, 0x35000000);
+ SDR_WRITE(PESDR0_HSSL3SET1, 0x35000000);
+ SDR_WRITE(PESDR0_HSSL4SET1, 0x35000000);
+ SDR_WRITE(PESDR0_HSSL5SET1, 0x35000000);
+ SDR_WRITE(PESDR0_HSSL6SET1, 0x35000000);
+ SDR_WRITE(PESDR0_HSSL7SET1, 0x35000000);
+ SDR_WRITE(PESDR0_RCSSET,
+ (SDR_READ(PESDR0_RCSSET) & ~(1 << 24 | 1 << 16)) | 1 << 12);
+ break;
+
+ case 1:
+ SDR_WRITE(PESDR1_DLPSET, 1 << 24 | PTYPE_ROOT_PORT << 20 | LNKW_X4 << 12);
+ SDR_WRITE(PESDR1_UTLSET1, 0x21222222);
+ if (!ppc440spe_revB())
+ SDR_WRITE(PESDR1_UTLSET2, 0x11000000);
+ SDR_WRITE(PESDR1_HSSL0SET1, 0x35000000);
+ SDR_WRITE(PESDR1_HSSL1SET1, 0x35000000);
+ SDR_WRITE(PESDR1_HSSL2SET1, 0x35000000);
+ SDR_WRITE(PESDR1_HSSL3SET1, 0x35000000);
+ SDR_WRITE(PESDR1_RCSSET,
+ (SDR_READ(PESDR1_RCSSET) & ~(1 << 24 | 1 << 16)) | 1 << 12);
+ break;
+
+ case 2:
+ SDR_WRITE(PESDR2_DLPSET, 1 << 24 | PTYPE_ROOT_PORT << 20 | LNKW_X4 << 12);
+ SDR_WRITE(PESDR2_UTLSET1, 0x21222222);
+ if (!ppc440spe_revB())
+ SDR_WRITE(PESDR2_UTLSET2, 0x11000000);
+ SDR_WRITE(PESDR2_HSSL0SET1, 0x35000000);
+ SDR_WRITE(PESDR2_HSSL1SET1, 0x35000000);
+ SDR_WRITE(PESDR2_HSSL2SET1, 0x35000000);
+ SDR_WRITE(PESDR2_HSSL3SET1, 0x35000000);
+ SDR_WRITE(PESDR2_RCSSET,
+ (SDR_READ(PESDR2_RCSSET) & ~(1 << 24 | 1 << 16)) | 1 << 12);
+ break;
+ }
+ /*
+ * Notice: the following delay has critical impact on device
+ * initialization - if too short (<50ms) the link doesn't get up.
+ */
+ mdelay(100);
+
+ switch (port) {
+ case 0:
+ val = SDR_READ(PESDR0_RCSSTS);
+ break;
+ case 1:
+ val = SDR_READ(PESDR1_RCSSTS);
+ break;
+ case 2:
+ val = SDR_READ(PESDR2_RCSSTS);
+ break;
+ }
+
+ if (val & (1 << 20)) {
+ printf("PCIE%d: PGRST failed %08x\n", port, val);
+ return -1;
+ }
+
+ /*
+ * Verify link is up
+ */
+ val = 0;
+ switch (port) {
+ case 0:
+ val = SDR_READ(PESDR0_LOOP);
+ break;
+ case 1:
+ val = SDR_READ(PESDR1_LOOP);
+ break;
+ case 2:
+ val = SDR_READ(PESDR2_LOOP);
+ break;
+ }
+ if (!(val & 0x00001000)) {
+ printf("PCIE%d: link is not up.\n", port);
+ return -1;
+ }
+
+ /*
+ * Setup UTL registers - but only on revA!
+ * We use default settings for revB chip.
+ */
+ if (!ppc440spe_revB())
+ ppc440spe_setup_utl(port);
+
+ /*
+ * We map PCI Express configuration access into the 512MB regions
+ *
+ * NOTICE: revB is very strict about PLB real addressess 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.
+ *
+ * For revA:
+ * PCIE0: 0xc_4000_0000
+ * PCIE1: 0xc_8000_0000
+ * PCIE2: 0xc_c000_0000
+ *
+ * For revB:
+ * PCIE0: 0xd_0000_0000
+ * PCIE1: 0xd_2000_0000
+ * PCIE2: 0xd_4000_0000
+ */
+
+ switch (port) {
+ case 0:
+ if (ppc440spe_revB()) {
+ mtdcr(DCRN_PEGPL_CFGBAH(PCIE0), 0x0000000d);
+ mtdcr(DCRN_PEGPL_CFGBAL(PCIE0), 0x00000000);
+ } else {
+ /* revA */
+ mtdcr(DCRN_PEGPL_CFGBAH(PCIE0), 0x0000000c);
+ mtdcr(DCRN_PEGPL_CFGBAL(PCIE0), 0x40000000);
+ }
+ mtdcr(DCRN_PEGPL_CFGMSK(PCIE0), 0xe0000001); /* 512MB region, valid */
+ break;
+
+ case 1:
+ if (ppc440spe_revB()) {
+ mtdcr(DCRN_PEGPL_CFGBAH(PCIE1), 0x0000000d);
+ mtdcr(DCRN_PEGPL_CFGBAL(PCIE1), 0x20000000);
+ } else {
+ mtdcr(DCRN_PEGPL_CFGBAH(PCIE1), 0x0000000c);
+ mtdcr(DCRN_PEGPL_CFGBAL(PCIE1), 0x80000000);
+ }
+ mtdcr(DCRN_PEGPL_CFGMSK(PCIE1), 0xe0000001); /* 512MB region, valid */
+ break;
+
+ case 2:
+ if (ppc440spe_revB()) {
+ mtdcr(DCRN_PEGPL_CFGBAH(PCIE2), 0x0000000d);
+ mtdcr(DCRN_PEGPL_CFGBAL(PCIE2), 0x40000000);
+ } else {
+ mtdcr(DCRN_PEGPL_CFGBAH(PCIE2), 0x0000000c);
+ mtdcr(DCRN_PEGPL_CFGBAL(PCIE2), 0xc0000000);
+ }
+ mtdcr(DCRN_PEGPL_CFGMSK(PCIE2), 0xe0000001); /* 512MB region, valid */
+ break;
+ }
+
+ /*
+ * Check for VC0 active and assert RDY.
+ */
+ attempts = 10;
+ switch (port) {
+ case 0:
+ while(!(SDR_READ(PESDR0_RCSSTS) & (1 << 16))) {
+ if (!(attempts--)) {
+ printf("PCIE0: VC0 not active\n");
+ return -1;
+ }
+ mdelay(1000);
+ }
+ SDR_WRITE(PESDR0_RCSSET, SDR_READ(PESDR0_RCSSET) | 1 << 20);
+ break;
+ case 1:
+ while(!(SDR_READ(PESDR1_RCSSTS) & (1 << 16))) {
+ if (!(attempts--)) {
+ printf("PCIE1: VC0 not active\n");
+ return -1;
+ }
+ mdelay(1000);
+ }
+
+ SDR_WRITE(PESDR1_RCSSET, SDR_READ(PESDR1_RCSSET) | 1 << 20);
+ break;
+ case 2:
+ while(!(SDR_READ(PESDR2_RCSSTS) & (1 << 16))) {
+ if (!(attempts--)) {
+ printf("PCIE2: VC0 not active\n");
+ return -1;
+ }
+ mdelay(1000);
+ }
+
+ SDR_WRITE(PESDR2_RCSSET, SDR_READ(PESDR2_RCSSET) | 1 << 20);
+ break;
+ }
+ mdelay(100);
+
+ return 0;
+}
+
+int ppc440spe_init_pcie_endport(int port)
+{
+ static int core_init;
+ volatile u32 val = 0;
+ int attempts;
+
+ if (!core_init) {
+ ++core_init;
+ if (ppc440spe_init_pcie())
+ return -1;
+ }
+
+ /*
+ * Initialize various parts of the PCI Express core for our port:
+ *
+ * - Set as a end port and enable max width
+ * (PXIE0 -> X8, PCIE1 and PCIE2 -> X4).
+ * - Set up UTL configuration.
+ * - Increase SERDES drive strength to levels suggested by AMCC.
+ * - De-assert RSTPYN, RSTDL and RSTGU.
+ *
+ * NOTICE for revB chip: PESDRn_UTLSET2 is not set - we leave it with
+ * default setting 0x11310000. The register has new fields,
+ * PESDRn_UTLSET2[LKINE] in particular: clearing it leads to PCIE core
+ * hang.
+ */
+ switch (port) {
+ case 0:
+ SDR_WRITE(PESDR0_DLPSET, 1 << 24 | PTYPE_LEGACY_ENDPOINT << 20 | LNKW_X8 << 12);
+
+ SDR_WRITE(PESDR0_UTLSET1, 0x20222222);
+ if (!ppc440spe_revB())
+ SDR_WRITE(PESDR0_UTLSET2, 0x11000000);
+ SDR_WRITE(PESDR0_HSSL0SET1, 0x35000000);
+ SDR_WRITE(PESDR0_HSSL1SET1, 0x35000000);
+ SDR_WRITE(PESDR0_HSSL2SET1, 0x35000000);
+ SDR_WRITE(PESDR0_HSSL3SET1, 0x35000000);
+ SDR_WRITE(PESDR0_HSSL4SET1, 0x35000000);
+ SDR_WRITE(PESDR0_HSSL5SET1, 0x35000000);
+ SDR_WRITE(PESDR0_HSSL6SET1, 0x35000000);
+ SDR_WRITE(PESDR0_HSSL7SET1, 0x35000000);
+ SDR_WRITE(PESDR0_RCSSET,
+ (SDR_READ(PESDR0_RCSSET) & ~(1 << 24 | 1 << 16)) | 1 << 12);
+ break;
+
+ case 1:
+ SDR_WRITE(PESDR1_DLPSET, 1 << 24 | PTYPE_LEGACY_ENDPOINT << 20 | LNKW_X4 << 12);
+ SDR_WRITE(PESDR1_UTLSET1, 0x20222222);
+ if (!ppc440spe_revB())
+ SDR_WRITE(PESDR1_UTLSET2, 0x11000000);
+ SDR_WRITE(PESDR1_HSSL0SET1, 0x35000000);
+ SDR_WRITE(PESDR1_HSSL1SET1, 0x35000000);
+ SDR_WRITE(PESDR1_HSSL2SET1, 0x35000000);
+ SDR_WRITE(PESDR1_HSSL3SET1, 0x35000000);
+ SDR_WRITE(PESDR1_RCSSET,
+ (SDR_READ(PESDR1_RCSSET) & ~(1 << 24 | 1 << 16)) | 1 << 12);
+ break;
+
+ case 2:
+ SDR_WRITE(PESDR2_DLPSET, 1 << 24 | PTYPE_LEGACY_ENDPOINT << 20 | LNKW_X4 << 12);
+ SDR_WRITE(PESDR2_UTLSET1, 0x20222222);
+ if (!ppc440spe_revB())
+ SDR_WRITE(PESDR2_UTLSET2, 0x11000000);
+ SDR_WRITE(PESDR2_HSSL0SET1, 0x35000000);
+ SDR_WRITE(PESDR2_HSSL1SET1, 0x35000000);
+ SDR_WRITE(PESDR2_HSSL2SET1, 0x35000000);
+ SDR_WRITE(PESDR2_HSSL3SET1, 0x35000000);
+ SDR_WRITE(PESDR2_RCSSET,
+ (SDR_READ(PESDR2_RCSSET) & ~(1 << 24 | 1 << 16)) | 1 << 12);
+ break;
+ }
+ /*
+ * Notice: the following delay has critical impact on device
+ * initialization - if too short (<50ms) the link doesn't get up.
+ */
+ mdelay(100);
+
+ switch (port) {
+ case 0: val = SDR_READ(PESDR0_RCSSTS); break;
+ case 1: val = SDR_READ(PESDR1_RCSSTS); break;
+ case 2: val = SDR_READ(PESDR2_RCSSTS); break;
+ }
+
+ if (val & (1 << 20)) {
+ printf("PCIE%d: PGRST failed %08x\n", port, val);
+ return -1;
+ }
+
+ /*
+ * Verify link is up
+ */
+ val = 0;
+ switch (port)
+ {
+ case 0:
+ val = SDR_READ(PESDR0_LOOP);
+ break;
+ case 1:
+ val = SDR_READ(PESDR1_LOOP);
+ break;
+ case 2:
+ val = SDR_READ(PESDR2_LOOP);
+ break;
+ }
+ if (!(val & 0x00001000)) {
+ printf("PCIE%d: link is not up.\n", port);
+ return -1;
+ }
+
+ /*
+ * Setup UTL registers - but only on revA!
+ * We use default settings for revB chip.
+ */
+ if (!ppc440spe_revB())
+ ppc440spe_setup_utl(port);
+
+ /*
+ * We map PCI Express configuration access into the 512MB regions
+ *
+ * NOTICE: revB is very strict about PLB real addressess 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.
+ *
+ * For revA:
+ * PCIE0: 0xc_4000_0000
+ * PCIE1: 0xc_8000_0000
+ * PCIE2: 0xc_c000_0000
+ *
+ * For revB:
+ * PCIE0: 0xd_0000_0000
+ * PCIE1: 0xd_2000_0000
+ * PCIE2: 0xd_4000_0000
+ */
+ switch (port) {
+ case 0:
+ if (ppc440spe_revB()) {
+ mtdcr(DCRN_PEGPL_CFGBAH(PCIE0), 0x0000000d);
+ mtdcr(DCRN_PEGPL_CFGBAL(PCIE0), 0x00000000);
+ } else {
+ /* revA */
+ mtdcr(DCRN_PEGPL_CFGBAH(PCIE0), 0x0000000c);
+ mtdcr(DCRN_PEGPL_CFGBAL(PCIE0), 0x40000000);
+ }
+ mtdcr(DCRN_PEGPL_CFGMSK(PCIE0), 0xe0000001); /* 512MB region, valid */
+ break;
+
+ case 1:
+ if (ppc440spe_revB()) {
+ mtdcr(DCRN_PEGPL_CFGBAH(PCIE1), 0x0000000d);
+ mtdcr(DCRN_PEGPL_CFGBAL(PCIE1), 0x20000000);
+ } else {
+ mtdcr(DCRN_PEGPL_CFGBAH(PCIE1), 0x0000000c);
+ mtdcr(DCRN_PEGPL_CFGBAL(PCIE1), 0x80000000);
+ }
+ mtdcr(DCRN_PEGPL_CFGMSK(PCIE1), 0xe0000001); /* 512MB region, valid */
+ break;
+
+ case 2:
+ if (ppc440spe_revB()) {
+ mtdcr(DCRN_PEGPL_CFGBAH(PCIE2), 0x0000000d);
+ mtdcr(DCRN_PEGPL_CFGBAL(PCIE2), 0x40000000);
+ } else {
+ mtdcr(DCRN_PEGPL_CFGBAH(PCIE2), 0x0000000c);
+ mtdcr(DCRN_PEGPL_CFGBAL(PCIE2), 0xc0000000);
+ }
+ mtdcr(DCRN_PEGPL_CFGMSK(PCIE2), 0xe0000001); /* 512MB region, valid */
+ break;
+ }
+
+ /*
+ * Check for VC0 active and assert RDY.
+ */
+ attempts = 10;
+ switch (port) {
+ case 0:
+ while(!(SDR_READ(PESDR0_RCSSTS) & (1 << 16))) {
+ if (!(attempts--)) {
+ printf("PCIE0: VC0 not active\n");
+ return -1;
+ }
+ mdelay(1000);
+ }
+ SDR_WRITE(PESDR0_RCSSET, SDR_READ(PESDR0_RCSSET) | 1 << 20);
+ break;
+ case 1:
+ while(!(SDR_READ(PESDR1_RCSSTS) & (1 << 16))) {
+ if (!(attempts--)) {
+ printf("PCIE1: VC0 not active\n");
+ return -1;
+ }
+ mdelay(1000);
+ }
+
+ SDR_WRITE(PESDR1_RCSSET, SDR_READ(PESDR1_RCSSET) | 1 << 20);
+ break;
+ case 2:
+ while(!(SDR_READ(PESDR2_RCSSTS) & (1 << 16))) {
+ if (!(attempts--)) {
+ printf("PCIE2: VC0 not active\n");
+ return -1;
+ }
+ mdelay(1000);
+ }
+
+ SDR_WRITE(PESDR2_RCSSET, SDR_READ(PESDR2_RCSSET) | 1 << 20);
+ break;
+ }
+ mdelay(100);
+
+ return 0;
+}
+
+void ppc440spe_setup_pcie_rootpoint(struct pci_controller *hose, int port)
+{
+ volatile void *mbase = NULL;
+ volatile void *rmbase = NULL;
+
+ pci_set_ops(hose,
+ pcie_read_config_byte,
+ pcie_read_config_word,
+ pcie_read_config_dword,
+ pcie_write_config_byte,
+ pcie_write_config_word,
+ pcie_write_config_dword);
+
+ switch (port) {
+ case 0:
+ mbase = (u32 *)CFG_PCIE0_XCFGBASE;
+ rmbase = (u32 *)CFG_PCIE0_CFGBASE;
+ hose->cfg_data = (u8 *)CFG_PCIE0_CFGBASE;
+ break;
+ case 1:
+ mbase = (u32 *)CFG_PCIE1_XCFGBASE;
+ rmbase = (u32 *)CFG_PCIE1_CFGBASE;
+ hose->cfg_data = (u8 *)CFG_PCIE1_CFGBASE;
+ break;
+ case 2:
+ mbase = (u32 *)CFG_PCIE2_XCFGBASE;
+ rmbase = (u32 *)CFG_PCIE2_CFGBASE;
+ hose->cfg_data = (u8 *)CFG_PCIE2_CFGBASE;
+ break;
+ }
+
+ /*
+ * Set bus numbers on our root port
+ */
+ out_8((u8 *)mbase + PCI_PRIMARY_BUS, 0);
+ out_8((u8 *)mbase + PCI_SECONDARY_BUS, 1);
+ out_8((u8 *)mbase + PCI_SUBORDINATE_BUS, 1);
+
+ /*
+ * Set up outbound translation to hose->mem_space from PLB
+ * addresses at an offset of 0xd_0000_0000. We set the low
+ * bits of the mask to 11 to turn off splitting into 8
+ * subregions and to enable the outbound translation.
+ */
+ out_le32(mbase + PECFG_POM0LAH, 0x00000000);
+ out_le32(mbase + PECFG_POM0LAL, 0x00000000);
+
+ switch (port) {
+ case 0:
+ mtdcr(DCRN_PEGPL_OMR1BAH(PCIE0), 0x0000000d);
+ mtdcr(DCRN_PEGPL_OMR1BAL(PCIE0), CFG_PCIE_MEMBASE +
+ port * CFG_PCIE_MEMSIZE);
+ mtdcr(DCRN_PEGPL_OMR1MSKH(PCIE0), 0x7fffffff);
+ mtdcr(DCRN_PEGPL_OMR1MSKL(PCIE0),
+ ~(CFG_PCIE_MEMSIZE - 1) | 3);
+ break;
+ case 1:
+ mtdcr(DCRN_PEGPL_OMR1BAH(PCIE1), 0x0000000d);
+ mtdcr(DCRN_PEGPL_OMR1BAL(PCIE1), (CFG_PCIE_MEMBASE +
+ port * CFG_PCIE_MEMSIZE));
+ mtdcr(DCRN_PEGPL_OMR1MSKH(PCIE1), 0x7fffffff);
+ mtdcr(DCRN_PEGPL_OMR1MSKL(PCIE1),
+ ~(CFG_PCIE_MEMSIZE - 1) | 3);
+ break;
+ case 2:
+ mtdcr(DCRN_PEGPL_OMR1BAH(PCIE2), 0x0000000d);
+ mtdcr(DCRN_PEGPL_OMR1BAL(PCIE2), (CFG_PCIE_MEMBASE +
+ port * CFG_PCIE_MEMSIZE));
+ mtdcr(DCRN_PEGPL_OMR1MSKH(PCIE2), 0x7fffffff);
+ mtdcr(DCRN_PEGPL_OMR1MSKL(PCIE2),
+ ~(CFG_PCIE_MEMSIZE - 1) | 3);
+ break;
+ }
+
+ /* Set up 16GB inbound memory window at 0 */
+ out_le32(mbase + PCI_BASE_ADDRESS_0, 0);
+ out_le32(mbase + PCI_BASE_ADDRESS_1, 0);
+ out_le32(mbase + PECFG_BAR0HMPA, 0x7fffffc);
+ out_le32(mbase + PECFG_BAR0LMPA, 0);
+
+ out_le32(mbase + PECFG_PIM01SAH, 0xffff0000);
+ out_le32(mbase + PECFG_PIM01SAL, 0x00000000);
+ out_le32(mbase + PECFG_PIM0LAL, 0);
+ out_le32(mbase + PECFG_PIM0LAH, 0);
+ out_le32(mbase + PECFG_PIM1LAL, 0x00000000);
+ out_le32(mbase + PECFG_PIM1LAH, 0x00000004);
+ out_le32(mbase + PECFG_PIMEN, 0x1);
+
+ /* Enable I/O, Mem, and Busmaster cycles */
+ out_le16((u16 *)(mbase + PCI_COMMAND),
+ in_le16((u16 *)(mbase + PCI_COMMAND)) |
+ PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
+ printf("PCIE:%d successfully set as rootpoint\n",port);
+}
+
+int ppc440spe_setup_pcie_endpoint(struct pci_controller *hose, int port)
+{
+ volatile void *mbase = NULL;
+ int attempts = 0;
+
+ pci_set_ops(hose,
+ pcie_read_config_byte,
+ pcie_read_config_word,
+ pcie_read_config_dword,
+ pcie_write_config_byte,
+ pcie_write_config_word,
+ pcie_write_config_dword);
+
+ switch (port) {
+ case 0:
+ mbase = (u32 *)CFG_PCIE0_XCFGBASE;
+ hose->cfg_data = (u8 *)CFG_PCIE0_CFGBASE;
+ break;
+ case 1:
+ mbase = (u32 *)CFG_PCIE1_XCFGBASE;
+ hose->cfg_data = (u8 *)CFG_PCIE1_CFGBASE;
+ break;
+ case 2:
+ mbase = (u32 *)CFG_PCIE2_XCFGBASE;
+ hose->cfg_data = (u8 *)CFG_PCIE2_CFGBASE;
+ break;
+ }
+
+ /*
+ * Set up outbound translation to hose->mem_space from PLB
+ * addresses at an offset of 0xd_0000_0000. We set the low
+ * bits of the mask to 11 to turn off splitting into 8
+ * subregions and to enable the outbound translation.
+ */
+ out_le32(mbase + PECFG_POM0LAH, 0x00001ff8);
+ out_le32(mbase + PECFG_POM0LAL, 0x00001000);
+
+ switch (port) {
+ case 0:
+ mtdcr(DCRN_PEGPL_OMR1BAH(PCIE0), 0x0000000d);
+ mtdcr(DCRN_PEGPL_OMR1BAL(PCIE0), CFG_PCIE_MEMBASE +
+ port * CFG_PCIE_MEMSIZE);
+ mtdcr(DCRN_PEGPL_OMR1MSKH(PCIE0), 0x7fffffff);
+ mtdcr(DCRN_PEGPL_OMR1MSKL(PCIE0),
+ ~(CFG_PCIE_MEMSIZE - 1) | 3);
+ break;
+ case 1:
+ mtdcr(DCRN_PEGPL_OMR1BAH(PCIE1), 0x0000000d);
+ mtdcr(DCRN_PEGPL_OMR1BAL(PCIE1), (CFG_PCIE_MEMBASE +
+ port * CFG_PCIE_MEMSIZE));
+ mtdcr(DCRN_PEGPL_OMR1MSKH(PCIE1), 0x7fffffff);
+ mtdcr(DCRN_PEGPL_OMR1MSKL(PCIE1),
+ ~(CFG_PCIE_MEMSIZE - 1) | 3);
+ break;
+ case 2:
+ mtdcr(DCRN_PEGPL_OMR1BAH(PCIE2), 0x0000000d);
+ mtdcr(DCRN_PEGPL_OMR1BAL(PCIE2), (CFG_PCIE_MEMBASE +
+ port * CFG_PCIE_MEMSIZE));
+ mtdcr(DCRN_PEGPL_OMR1MSKH(PCIE2), 0x7fffffff);
+ mtdcr(DCRN_PEGPL_OMR1MSKL(PCIE2),
+ ~(CFG_PCIE_MEMSIZE - 1) | 3);
+ break;
+ }
+
+ /* Set up 16GB inbound memory window at 0 */
+ out_le32(mbase + PCI_BASE_ADDRESS_0, 0);
+ out_le32(mbase + PCI_BASE_ADDRESS_1, 0);
+ out_le32(mbase + PECFG_BAR0HMPA, 0x7fffffc);
+ out_le32(mbase + PECFG_BAR0LMPA, 0);
+ out_le32(mbase + PECFG_PIM0LAL, 0x00000000);
+ out_le32(mbase + PECFG_PIM0LAH, 0x00000004); /* pointing to SRAM */
+ out_le32(mbase + PECFG_PIMEN, 0x1);
+
+ /* Enable I/O, Mem, and Busmaster cycles */
+ out_le16((u16 *)(mbase + PCI_COMMAND),
+ in_le16((u16 *)(mbase + PCI_COMMAND)) |
+ PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
+ out_le16(mbase + 0x200,0xcaad); /* Setting vendor ID */
+ out_le16(mbase + 0x202,0xfeed); /* Setting device ID */
+ attempts = 10;
+ switch (port) {
+ case 0:
+ while (!(SDR_READ(PESDR0_RCSSTS) & (1 << 8))) {
+ if (!(attempts--)) {
+ printf("PCIE0: BMEN is not active\n");
+ return -1;
+ }
+ mdelay(1000);
+ }
+ break;
+ case 1:
+ while (!(SDR_READ(PESDR1_RCSSTS) & (1 << 8))) {
+ if (!(attempts--)) {
+ printf("PCIE1: BMEN is not active\n");
+ return -1;
+ }
+ mdelay(1000);
+ }
+ break;
+ case 2:
+ while (!(SDR_READ(PESDR2_RCSSTS) & (1 << 8))) {
+ if (!(attempts--)) {
+ printf("PCIE2: BMEN is not active\n");
+ return -1;
+ }
+ mdelay(1000);
+ }
+ break;
+ }
+ printf("PCIE:%d successfully set as endpoint\n",port);
+
+ return 0;
+}
+#endif /* CONFIG_PCI */
+#endif /* CONFIG_440SPE */
diff --git a/cpu/ppc4xx/440spe_pcie.h b/cpu/ppc4xx/440spe_pcie.h
new file mode 100644
index 0000000..2becc77
--- /dev/null
+++ b/cpu/ppc4xx/440spe_pcie.h
@@ -0,0 +1,171 @@
+/*
+ * Copyright (c) 2005 Cisco Systems. All rights reserved.
+ * Roland Dreier <rolandd@cisco.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.
+ */
+
+#include <ppc4xx.h>
+#ifndef __440SPE_PCIE_H
+#define __440SPE_PCIE_H
+
+#define mdelay(n) ({unsigned long __ms=(n); while (__ms--) udelay(1000);})
+
+#define DCRN_SDR0_CFGADDR 0x00e
+#define DCRN_SDR0_CFGDATA 0x00f
+
+#define DCRN_PCIE0_BASE 0x100
+#define DCRN_PCIE1_BASE 0x120
+#define DCRN_PCIE2_BASE 0x140
+#define PCIE0 DCRN_PCIE0_BASE
+#define PCIE1 DCRN_PCIE1_BASE
+#define PCIE2 DCRN_PCIE2_BASE
+
+#define DCRN_PEGPL_CFGBAH(base) (base + 0x00)
+#define DCRN_PEGPL_CFGBAL(base) (base + 0x01)
+#define DCRN_PEGPL_CFGMSK(base) (base + 0x02)
+#define DCRN_PEGPL_MSGBAH(base) (base + 0x03)
+#define DCRN_PEGPL_MSGBAL(base) (base + 0x04)
+#define DCRN_PEGPL_MSGMSK(base) (base + 0x05)
+#define DCRN_PEGPL_OMR1BAH(base) (base + 0x06)
+#define DCRN_PEGPL_OMR1BAL(base) (base + 0x07)
+#define DCRN_PEGPL_OMR1MSKH(base) (base + 0x08)
+#define DCRN_PEGPL_OMR1MSKL(base) (base + 0x09)
+#define DCRN_PEGPL_REGBAH(base) (base + 0x12)
+#define DCRN_PEGPL_REGBAL(base) (base + 0x13)
+#define DCRN_PEGPL_REGMSK(base) (base + 0x14)
+#define DCRN_PEGPL_SPECIAL(base) (base + 0x15)
+
+/*
+ * System DCRs (SDRs)
+ */
+#define PESDR0_PLLLCT1 0x03a0
+#define PESDR0_PLLLCT2 0x03a1
+#define PESDR0_PLLLCT3 0x03a2
+
+#define PESDR0_UTLSET1 0x0300
+#define PESDR0_UTLSET2 0x0301
+#define PESDR0_DLPSET 0x0302
+#define PESDR0_LOOP 0x0303
+#define PESDR0_RCSSET 0x0304
+#define PESDR0_RCSSTS 0x0305
+#define PESDR0_HSSL0SET1 0x0306
+#define PESDR0_HSSL0SET2 0x0307
+#define PESDR0_HSSL0STS 0x0308
+#define PESDR0_HSSL1SET1 0x0309
+#define PESDR0_HSSL1SET2 0x030a
+#define PESDR0_HSSL1STS 0x030b
+#define PESDR0_HSSL2SET1 0x030c
+#define PESDR0_HSSL2SET2 0x030d
+#define PESDR0_HSSL2STS 0x030e
+#define PESDR0_HSSL3SET1 0x030f
+#define PESDR0_HSSL3SET2 0x0310
+#define PESDR0_HSSL3STS 0x0311
+#define PESDR0_HSSL4SET1 0x0312
+#define PESDR0_HSSL4SET2 0x0313
+#define PESDR0_HSSL4STS 0x0314
+#define PESDR0_HSSL5SET1 0x0315
+#define PESDR0_HSSL5SET2 0x0316
+#define PESDR0_HSSL5STS 0x0317
+#define PESDR0_HSSL6SET1 0x0318
+#define PESDR0_HSSL6SET2 0x0319
+#define PESDR0_HSSL6STS 0x031a
+#define PESDR0_HSSL7SET1 0x031b
+#define PESDR0_HSSL7SET2 0x031c
+#define PESDR0_HSSL7STS 0x031d
+#define PESDR0_HSSCTLSET 0x031e
+#define PESDR0_LANE_ABCD 0x031f
+#define PESDR0_LANE_EFGH 0x0320
+
+#define PESDR1_UTLSET1 0x0340
+#define PESDR1_UTLSET2 0x0341
+#define PESDR1_DLPSET 0x0342
+#define PESDR1_LOOP 0x0343
+#define PESDR1_RCSSET 0x0344
+#define PESDR1_RCSSTS 0x0345
+#define PESDR1_HSSL0SET1 0x0346
+#define PESDR1_HSSL0SET2 0x0347
+#define PESDR1_HSSL0STS 0x0348
+#define PESDR1_HSSL1SET1 0x0349
+#define PESDR1_HSSL1SET2 0x034a
+#define PESDR1_HSSL1STS 0x034b
+#define PESDR1_HSSL2SET1 0x034c
+#define PESDR1_HSSL2SET2 0x034d
+#define PESDR1_HSSL2STS 0x034e
+#define PESDR1_HSSL3SET1 0x034f
+#define PESDR1_HSSL3SET2 0x0350
+#define PESDR1_HSSL3STS 0x0351
+#define PESDR1_HSSCTLSET 0x0352
+#define PESDR1_LANE_ABCD 0x0353
+
+#define PESDR2_UTLSET1 0x0370
+#define PESDR2_UTLSET2 0x0371
+#define PESDR2_DLPSET 0x0372
+#define PESDR2_LOOP 0x0373
+#define PESDR2_RCSSET 0x0374
+#define PESDR2_RCSSTS 0x0375
+#define PESDR2_HSSL0SET1 0x0376
+#define PESDR2_HSSL0SET2 0x0377
+#define PESDR2_HSSL0STS 0x0378
+#define PESDR2_HSSL1SET1 0x0379
+#define PESDR2_HSSL1SET2 0x037a
+#define PESDR2_HSSL1STS 0x037b
+#define PESDR2_HSSL2SET1 0x037c
+#define PESDR2_HSSL2SET2 0x037d
+#define PESDR2_HSSL2STS 0x037e
+#define PESDR2_HSSL3SET1 0x037f
+#define PESDR2_HSSL3SET2 0x0380
+#define PESDR2_HSSL3STS 0x0381
+#define PESDR2_HSSCTLSET 0x0382
+#define PESDR2_LANE_ABCD 0x0383
+
+/*
+ * UTL register offsets
+ */
+#define PEUTL_PBBSZ 0x20
+#define PEUTL_OPDBSZ 0x68
+#define PEUTL_IPHBSZ 0x70
+#define PEUTL_IPDBSZ 0x78
+#define PEUTL_OUTTR 0x90
+#define PEUTL_INTR 0x98
+#define PEUTL_PCTL 0xa0
+#define PEUTL_RCIRQEN 0xb8
+
+/*
+ * Config space register offsets
+ */
+#define PECFG_BAR0LMPA 0x210
+#define PECFG_BAR0HMPA 0x214
+#define PECFG_BAR1MPA 0x218
+#define PECFG_BAR2MPA 0x220
+
+#define PECFG_PIMEN 0x33c
+#define PECFG_PIM0LAL 0x340
+#define PECFG_PIM0LAH 0x344
+#define PECFG_PIM1LAL 0x348
+#define PECFG_PIM1LAH 0x34c
+#define PECFG_PIM01SAL 0x350
+#define PECFG_PIM01SAH 0x354
+
+#define PECFG_POM0LAL 0x380
+#define PECFG_POM0LAH 0x384
+
+#define SDR_READ(offset) ({\
+ mtdcr(DCRN_SDR0_CFGADDR, offset); \
+ mfdcr(DCRN_SDR0_CFGDATA);})
+
+#define SDR_WRITE(offset, data) ({\
+ mtdcr(DCRN_SDR0_CFGADDR, offset); \
+ mtdcr(DCRN_SDR0_CFGDATA,data);})
+
+int ppc440spe_init_pcie(void);
+int ppc440spe_init_pcie_rootport(int port);
+void yucca_setup_pcie_fpga_rootpoint(int port);
+void ppc440spe_setup_pcie_rootpoint(struct pci_controller *hose, int port);
+int ppc440spe_setup_pcie_endpoint(struct pci_controller *hose, int port);
+int yucca_pcie_card_present(int port);
+int pcie_hose_scan(struct pci_controller *hose, int bus);
+#endif /* __440SPE_PCIE_H */
diff --git a/cpu/ppc4xx/4xx_enet.c b/cpu/ppc4xx/4xx_enet.c
index fab65af..81d49ff 100644
--- a/cpu/ppc4xx/4xx_enet.c
+++ b/cpu/ppc4xx/4xx_enet.c
@@ -130,7 +130,17 @@
#define BI_PHYMODE_NONE 0
#define BI_PHYMODE_ZMII 1
#define BI_PHYMODE_RGMII 2
+#define BI_PHYMODE_GMII 3
+#define BI_PHYMODE_RTBI 4
+#define BI_PHYMODE_TBI 5
+#if defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
+#define BI_PHYMODE_SMII 6
+#define BI_PHYMODE_MII 7
+#endif
+#if defined(CONFIG_440SPE) || defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
+#define SDR0_MFR_ETH_CLK_SEL_V(n) ((0x01<<27) / (n+1))
+#endif
/*-----------------------------------------------------------------------------+
* Global variables. TX and RX descriptors and buffers.
@@ -181,7 +191,7 @@ static void ppc_4xx_eth_halt (struct eth_device *dev)
{
EMAC_4XX_HW_PST hw_p = dev->priv;
uint32_t failsafe = 10000;
-#if defined(CONFIG_440SPE)
+#if defined(CONFIG_440SPE) || defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
unsigned long mfr;
#endif
@@ -205,19 +215,19 @@ static void ppc_4xx_eth_halt (struct eth_device *dev)
}
/* EMAC RESET */
-#if defined(CONFIG_440SPE)
+#if defined(CONFIG_440SPE) || defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
/* provide clocks for EMAC internal loopback */
mfsdr (sdr_mfr, mfr);
- mfr |= 0x08000000;
+ mfr |= SDR0_MFR_ETH_CLK_SEL_V(hw_p->devnum);
mtsdr(sdr_mfr, mfr);
#endif
out32 (EMAC_M0 + hw_p->hw_addr, EMAC_M0_SRST);
-#if defined(CONFIG_440SPE)
+#if defined(CONFIG_440SPE) || defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
/* remove clocks for EMAC internal loopback */
mfsdr (sdr_mfr, mfr);
- mfr &= ~0x08000000;
+ mfr &= ~SDR0_MFR_ETH_CLK_SEL_V(hw_p->devnum);
mtsdr(sdr_mfr, mfr);
#endif
@@ -317,10 +327,50 @@ int ppc_4xx_eth_setup_bridge(int devnum, bd_t * bis)
out32 (RGMII_FER, rmiifer);
return ((int)pfc1);
-
}
#endif /* CONFIG_440_GX */
+#if defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
+int ppc_4xx_eth_setup_bridge(int devnum, bd_t * bis)
+{
+ unsigned long zmiifer=0x0;
+
+ /*
+ * Right now only 2*RGMII is supported. Please extend when needed.
+ * sr - 2006-08-29
+ */
+ switch (1) {
+ case 0:
+ /* 1 x GMII port */
+ out32 (ZMII_FER, 0x00);
+ out32 (RGMII_FER, 0x00000037);
+ bis->bi_phymode[0] = BI_PHYMODE_GMII;
+ bis->bi_phymode[1] = BI_PHYMODE_NONE;
+ break;
+ case 1:
+ /* 2 x RGMII ports */
+ out32 (ZMII_FER, 0x00);
+ out32 (RGMII_FER, 0x00000055);
+ bis->bi_phymode[0] = BI_PHYMODE_RGMII;
+ bis->bi_phymode[1] = BI_PHYMODE_RGMII;
+ break;
+ case 2:
+ /* 2 x SMII ports */
+
+ break;
+ default:
+ break;
+ }
+
+ /* Ensure we setup mdio for this devnum and ONLY this devnum */
+ zmiifer = in32 (ZMII_FER);
+ zmiifer |= (ZMII_FER_MDI) << ZMII_FER_V(devnum);
+ out32 (ZMII_FER, zmiifer);
+
+ return ((int)0x0);
+}
+#endif /* CONFIG_440EPX */
+
static int ppc_4xx_eth_init (struct eth_device *dev, bd_t * bis)
{
int i, j;
@@ -332,13 +382,16 @@ static int ppc_4xx_eth_init (struct eth_device *dev, bd_t * bis)
unsigned mode_reg;
unsigned short devnum;
unsigned short reg_short;
-#if defined(CONFIG_440GX) || defined(CONFIG_440SP) || defined(CONFIG_440SPE)
+#if defined(CONFIG_440GX) || \
+ defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \
+ defined(CONFIG_440SP) || defined(CONFIG_440SPE)
sys_info_t sysinfo;
-#if defined(CONFIG_440GX) || defined(CONFIG_440SPE)
+#if defined(CONFIG_440GX) || defined(CONFIG_440SPE) || \
+ defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
int ethgroup = -1;
#endif
#endif
-#if defined(CONFIG_440SPE)
+#if defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || defined(CONFIG_440SPE)
unsigned long mfr;
#endif
@@ -352,7 +405,9 @@ static int ppc_4xx_eth_init (struct eth_device *dev, bd_t * bis)
return -1;
}
-#if defined(CONFIG_440GX) || defined(CONFIG_440SP) || defined(CONFIG_440SPE)
+#if defined(CONFIG_440GX) || \
+ defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \
+ defined(CONFIG_440SP) || defined(CONFIG_440SPE)
/* Need to get the OPB frequency so we can access the PHY */
get_sys_info (&sysinfo);
#endif
@@ -407,7 +462,7 @@ static int ppc_4xx_eth_init (struct eth_device *dev, bd_t * bis)
#if defined(CONFIG_440EP) || defined(CONFIG_440GR)
out32 (ZMII_FER, (ZMII_FER_RMII | ZMII_FER_MDI) << ZMII_FER_V (devnum));
-#elif defined(CONFIG_440GX)
+#elif defined(CONFIG_440GX) || defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
ethgroup = ppc_4xx_eth_setup_bridge(devnum, bis);
#elif defined(CONFIG_440GP)
/* set RMII mode */
@@ -429,10 +484,10 @@ static int ppc_4xx_eth_init (struct eth_device *dev, bd_t * bis)
__asm__ volatile ("eieio");
/* reset emac so we have access to the phy */
-#if defined(CONFIG_440SPE)
+#if defined(CONFIG_440SPE) || defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
/* provide clocks for EMAC internal loopback */
mfsdr (sdr_mfr, mfr);
- mfr |= 0x08000000;
+ mfr |= SDR0_MFR_ETH_CLK_SEL_V(devnum);
mtsdr(sdr_mfr, mfr);
#endif
@@ -444,15 +499,19 @@ static int ppc_4xx_eth_init (struct eth_device *dev, bd_t * bis)
udelay (1000);
failsafe--;
}
+ if (failsafe <= 0)
+ printf("\nProblem resetting EMAC!\n");
-#if defined(CONFIG_440SPE)
+#if defined(CONFIG_440SPE) || defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
/* remove clocks for EMAC internal loopback */
mfsdr (sdr_mfr, mfr);
- mfr &= ~0x08000000;
+ mfr &= ~SDR0_MFR_ETH_CLK_SEL_V(devnum);
mtsdr(sdr_mfr, mfr);
#endif
-#if defined(CONFIG_440GX) || defined(CONFIG_440SP) || defined(CONFIG_440SPE)
+#if defined(CONFIG_440GX) || \
+ defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \
+ defined(CONFIG_440SP) || defined(CONFIG_440SPE)
/* Whack the M1 register */
mode_reg = 0x0;
mode_reg &= ~0x00000038;
@@ -502,15 +561,39 @@ static int ppc_4xx_eth_init (struct eth_device *dev, bd_t * bis)
* otherwise, just check the speeds & feeds
*/
if (hw_p->first_init == 0) {
+#if defined(CONFIG_88E1111_CLK_DELAY)
+ /*
+ * On some boards (e.g. ALPR) the Marvell 88E1111 PHY needs
+ * the "RGMII transmit timing control" and "RGMII receive
+ * timing control" bits set, so that Gbit communication works
+ * without problems.
+ * Also set the "Transmitter disable" to 1 to enable the
+ * transmitter.
+ * After setting these bits a soft-reset must occur for this
+ * change to become active.
+ */
+ miiphy_read (dev->name, reg, 0x14, &reg_short);
+ reg_short |= (1 << 7) | (1 << 1) | (1 << 0);
+ miiphy_write (dev->name, reg, 0x14, reg_short);
+#endif
+#if defined(CONFIG_M88E1111_PHY) /* test-only: merge with CONFIG_88E1111_CLK_DELAY !!! */
+ miiphy_write (dev->name, reg, 0x14, 0x0ce3);
+ miiphy_write (dev->name, reg, 0x18, 0x4101);
+ miiphy_write (dev->name, reg, 0x09, 0x0e00);
+ miiphy_write (dev->name, reg, 0x04, 0x01e1);
+#endif
miiphy_reset (dev->name, reg);
-#if defined(CONFIG_440GX) || defined(CONFIG_440SP) || defined(CONFIG_440SPE)
+#if defined(CONFIG_440GX) || \
+ defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \
+ defined(CONFIG_440SP) || defined(CONFIG_440SPE)
+
#if defined(CONFIG_CIS8201_PHY)
/*
* Cicada 8201 PHY needs to have an extended register whacked
* for RGMII mode.
*/
- if ( ((devnum == 2) || (devnum ==3)) && (4 == ethgroup) ) {
+ if (((devnum == 2) || (devnum == 3)) && (4 == ethgroup)) {
#if defined(CONFIG_CIS8201_SHORT_ETCH)
miiphy_write (dev->name, reg, 23, 0x1300);
#else
@@ -580,7 +663,8 @@ static int ppc_4xx_eth_init (struct eth_device *dev, bd_t * bis)
(int) speed, (duplex == HALF) ? "HALF" : "FULL");
}
-#if defined(CONFIG_440) && !defined(CONFIG_440SP) && !defined(CONFIG_440SPE)
+#if defined(CONFIG_440) && !defined(CONFIG_440SP) && !defined(CONFIG_440SPE) && \
+ !defined(CONFIG_440EPX) && !defined(CONFIG_440GRX)
#if defined(CONFIG_440EP) || defined(CONFIG_440GR)
mfsdr(sdr_mfr, reg);
if (speed == 100) {
@@ -603,15 +687,34 @@ static int ppc_4xx_eth_init (struct eth_device *dev, bd_t * bis)
reg = (RGMII_SSR_SP_1000MBPS << RGMII_SSR_V (devnum));
else if (speed == 100)
reg = (RGMII_SSR_SP_100MBPS << RGMII_SSR_V (devnum));
- else
+ else if (speed == 10)
reg = (RGMII_SSR_SP_10MBPS << RGMII_SSR_V (devnum));
-
+ else {
+ printf("Error in RGMII Speed\n");
+ return -1;
+ }
out32 (RGMII_SSR, reg);
}
#endif /* defined(CONFIG_440) && !defined(CONFIG_440SP) */
+#if defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
+ if (speed == 1000)
+ reg = (RGMII_SSR_SP_1000MBPS << RGMII_SSR_V (devnum));
+ else if (speed == 100)
+ reg = (RGMII_SSR_SP_100MBPS << RGMII_SSR_V (devnum));
+ else if (speed == 10)
+ reg = (RGMII_SSR_SP_10MBPS << RGMII_SSR_V (devnum));
+ else {
+ printf("Error in RGMII Speed\n");
+ return -1;
+ }
+ out32 (RGMII_SSR, reg);
+#endif
+
/* set the Mal configuration reg */
-#if defined(CONFIG_440GX) || defined(CONFIG_440SP) || defined(CONFIG_440SPE)
+#if defined(CONFIG_440GX) || \
+ defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \
+ defined(CONFIG_440SP) || defined(CONFIG_440SPE)
mtdcr (malmcr, MAL_CR_PLBB | MAL_CR_OPBBL | MAL_CR_LEA |
MAL_CR_PLBLT_DEFAULT | MAL_CR_EOPIE | 0x00330000);
#else
@@ -795,8 +898,10 @@ static int ppc_4xx_eth_init (struct eth_device *dev, bd_t * bis)
/* set speed */
if (speed == _1000BASET) {
-#if defined(CONFIG_440SP) || defined(CONFIG_440SPE)
+#if defined(CONFIG_440SP) || defined(CONFIG_440SPE) || \
+ defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
unsigned long pfc1;
+
mfsdr (sdr_pfc1, pfc1);
pfc1 |= SDR0_PFC1_EM_1000;
mtsdr (sdr_pfc1, pfc1);
@@ -942,6 +1047,14 @@ static int ppc_4xx_eth_send (struct eth_device *dev, volatile void *ptr,
#define UIC0SR uic0sr
#endif
+#if defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
+#define UICMSR_ETHX uic0msr
+#define UICSR_ETHX uic0sr
+#else
+#define UICMSR_ETHX uic1msr
+#define UICSR_ETHX uic1sr
+#endif
+
int enetInt (struct eth_device *dev)
{
int serviced;
@@ -950,6 +1063,7 @@ int enetInt (struct eth_device *dev)
unsigned long emac_isr = 0;
unsigned long mal_rx_eob;
unsigned long my_uic0msr, my_uic1msr;
+ unsigned long my_uicmsr_ethx;
#if defined(CONFIG_440GX)
unsigned long my_uic2msr;
@@ -977,8 +1091,11 @@ int enetInt (struct eth_device *dev)
#if defined(CONFIG_440GX)
my_uic2msr = mfdcr (uic2msr);
#endif
+ my_uicmsr_ethx = mfdcr (UICMSR_ETHX);
+
if (!(my_uic0msr & (UIC_MRE | UIC_MTE))
- && !(my_uic1msr & (UIC_ETH0 | UIC_ETH1 | UIC_MS | UIC_MTDE | UIC_MRDE))) {
+ && !(my_uic1msr & (UIC_MS | UIC_MTDE | UIC_MRDE))
+ && !(my_uicmsr_ethx & (UIC_ETH0 | UIC_ETH1))) {
/* not for us */
return (rc);
}
@@ -997,8 +1114,7 @@ int enetInt (struct eth_device *dev)
mal_isr = mfdcr (malesr);
/* look for mal error */
if (my_uic1msr & (UIC_MS | UIC_MTDE | UIC_MRDE)) {
- mal_err (dev, mal_isr, my_uic0msr,
- MAL_UIC_DEF, MAL_UIC_ERR);
+ mal_err (dev, mal_isr, my_uic1msr, MAL_UIC_DEF, MAL_UIC_ERR);
serviced = 1;
rc = 0;
}
@@ -1006,7 +1122,7 @@ int enetInt (struct eth_device *dev)
/* port by port dispatch of emac interrupts */
if (hw_p->devnum == 0) {
- if (UIC_ETH0 & my_uic1msr) { /* look for EMAC errors */
+ if (UIC_ETH0 & my_uicmsr_ethx) { /* look for EMAC errors */
emac_isr = in32 (EMAC_ISR + hw_p->hw_addr);
if ((hw_p->emac_ier & emac_isr) != 0) {
emac_err (dev, emac_isr);
@@ -1017,14 +1133,15 @@ int enetInt (struct eth_device *dev)
if ((hw_p->emac_ier & emac_isr)
|| (my_uic1msr & (UIC_MS | UIC_MTDE | UIC_MRDE))) {
mtdcr (UIC0SR, UIC_MRE | UIC_MTE); /* Clear */
- mtdcr (uic1sr, UIC_ETH0 | UIC_MS | UIC_MTDE | UIC_MRDE); /* Clear */
+ mtdcr (uic1sr, UIC_MS | UIC_MTDE | UIC_MRDE); /* Clear */
+ mtdcr (UICSR_ETHX, UIC_ETH0); /* Clear */
return (rc); /* we had errors so get out */
}
}
#if !defined(CONFIG_440SP)
if (hw_p->devnum == 1) {
- if (UIC_ETH1 & my_uic1msr) { /* look for EMAC errors */
+ if (UIC_ETH1 & my_uicmsr_ethx) { /* look for EMAC errors */
emac_isr = in32 (EMAC_ISR + hw_p->hw_addr);
if ((hw_p->emac_ier & emac_isr) != 0) {
emac_err (dev, emac_isr);
@@ -1035,7 +1152,8 @@ int enetInt (struct eth_device *dev)
if ((hw_p->emac_ier & emac_isr)
|| (my_uic1msr & (UIC_MS | UIC_MTDE | UIC_MRDE))) {
mtdcr (UIC0SR, UIC_MRE | UIC_MTE); /* Clear */
- mtdcr (uic1sr, UIC_ETH1 | UIC_MS | UIC_MTDE | UIC_MRDE); /* Clear */
+ mtdcr (uic1sr, UIC_MS | UIC_MTDE | UIC_MRDE); /* Clear */
+ mtdcr (UICSR_ETHX, UIC_ETH1); /* Clear */
return (rc); /* we had errors so get out */
}
}
@@ -1102,10 +1220,10 @@ int enetInt (struct eth_device *dev)
mtdcr (uic1sr, UIC_MS | UIC_MTDE | UIC_MRDE); /* Clear */
switch (hw_p->devnum) {
case 0:
- mtdcr (uic1sr, UIC_ETH0);
+ mtdcr (UICSR_ETHX, UIC_ETH0);
break;
case 1:
- mtdcr (uic1sr, UIC_ETH1);
+ mtdcr (UICSR_ETHX, UIC_ETH1);
break;
#if defined (CONFIG_440GX)
case 2:
@@ -1512,7 +1630,7 @@ int ppc_4xx_eth_initialize (bd_t * bis)
if (0 == virgin) {
/* set the MAL IER ??? names may change with new spec ??? */
-#if defined(CONFIG_440SPE)
+#if defined(CONFIG_440SPE) || defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
mal_ier =
MAL_IER_PT | MAL_IER_PRE | MAL_IER_PWE |
MAL_IER_DE | MAL_IER_OTE | MAL_IER_OE | MAL_IER_PE ;
diff --git a/cpu/ppc4xx/Makefile b/cpu/ppc4xx/Makefile
index c563457..baecf70 100644
--- a/cpu/ppc4xx/Makefile
+++ b/cpu/ppc4xx/Makefile
@@ -1,5 +1,5 @@
#
-# (C) Copyright 2000
+# (C) Copyright 2000-2006
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
#
# See file CREDITS for list of people who contributed to this
@@ -23,28 +23,31 @@
include $(TOPDIR)/config.mk
-LIB = lib$(CPU).a
+LIB = $(obj)lib$(CPU).a
START = start.o resetvec.o kgdb.o
-AOBJS = dcr.o
+SOBJS = dcr.o
COBJS = 405gp_pci.o 4xx_enet.o \
bedbug_405.o commproc.o \
cpu.o cpu_init.o i2c.o interrupts.o \
- miiphy.o sdram.o serial.o \
- spd_sdram.o speed.o traps.o usb_ohci.o usbdev.o
+ miiphy.o ndfc.o sdram.o serial.o \
+ spd_sdram.o speed.o traps.o usb_ohci.o usbdev.o \
+ 440spe_pcie.o
-OBJS = $(AOBJS) $(COBJS)
+SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
+START := $(addprefix $(obj),$(START))
-all: .depend $(START) $(LIB)
+all: $(obj).depend $(START) $(LIB)
$(LIB): $(OBJS)
- $(AR) crv $@ $(OBJS)
+ $(AR) $(ARFLAGS) $@ $(OBJS)
#########################################################################
-.depend: Makefile $(START:.o=.S) $(AOBJS:.o=.S) $(COBJS:.o=.c)
- $(CC) -M $(CFLAGS) $(START:.o=.S) $(AOBJS:.o=.S) $(COBJS:.o=.c) > $@
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
-sinclude .depend
+sinclude $(obj).depend
#########################################################################
diff --git a/cpu/ppc4xx/cpu.c b/cpu/ppc4xx/cpu.c
index 71303bc..f4a7208 100644
--- a/cpu/ppc4xx/cpu.c
+++ b/cpu/ppc4xx/cpu.c
@@ -41,14 +41,15 @@
DECLARE_GLOBAL_DATA_PTR;
#endif
-
#if defined(CONFIG_440)
#define FREQ_EBC (sys_info.freqEPB)
#else
#define FREQ_EBC (sys_info.freqPLB / sys_info.pllExtBusDiv)
#endif
-#if defined(CONFIG_405GP) || defined(CONFIG_440EP) || defined(CONFIG_440GR)
+#if defined(CONFIG_405GP) || \
+ defined(CONFIG_440EP) || defined(CONFIG_440GR) || \
+ defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
#define PCI_ASYNC
@@ -58,7 +59,8 @@ int pci_async_enabled(void)
return (mfdcr(strap) & PSR_PCI_ASYNC_EN);
#endif
-#if defined(CONFIG_440EP) || defined(CONFIG_440GR)
+#if defined(CONFIG_440EP) || defined(CONFIG_440GR) || \
+ defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
unsigned long val;
mfsdr(sdr_sdstp1, val);
@@ -82,9 +84,10 @@ int pci_arbiter_enabled(void)
return (mfdcr(cpc0_strp1) & CPC0_STRP1_PAE_MASK);
#endif
-#if defined(CONFIG_440GX) || defined(CONFIG_440EP) || \
- defined(CONFIG_440GR) || defined(CONFIG_440SP) || \
- defined(CONFIG_440SPE)
+#if defined(CONFIG_440GX) || \
+ defined(CONFIG_440EP) || defined(CONFIG_440GR) || \
+ defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \
+ defined(CONFIG_440SP) || defined(CONFIG_440SPE)
unsigned long val;
mfsdr(sdr_sdstp1, val);
@@ -93,8 +96,10 @@ int pci_arbiter_enabled(void)
}
#endif
-#if defined(CONFIG_405EP) || defined(CONFIG_440EP) || defined(CONFIG_440GR) || \
- defined(CONFIG_440GX) || defined(CONFIG_440SP) || defined(CONFIG_440SPE)
+#if defined(CONFIG_405EP) || defined(CONFIG_440GX) || \
+ defined(CONFIG_440EP) || defined(CONFIG_440GR) || \
+ defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \
+ defined(CONFIG_440SP) || defined(CONFIG_440SPE)
#define I2C_BOOTROM
@@ -102,17 +107,75 @@ int i2c_bootrom_enabled(void)
{
#if defined(CONFIG_405EP)
return (mfdcr(cpc0_boot) & CPC0_BOOT_SEP);
-#endif
-
-#if defined(CONFIG_440GX) || defined(CONFIG_440EP) || \
- defined(CONFIG_440GR) || defined(CONFIG_440SP) || \
- defined(CONFIG_440SPE)
+#else
unsigned long val;
mfsdr(sdr_sdcs, val);
return (val & SDR0_SDCS_SDD);
#endif
}
+
+#if defined(CONFIG_440GX)
+#define SDR0_PINSTP_SHIFT 29
+static char *bootstrap_str[] = {
+ "EBC (16 bits)",
+ "EBC (8 bits)",
+ "EBC (32 bits)",
+ "EBC (8 bits)",
+ "PCI",
+ "I2C (Addr 0x54)",
+ "Reserved",
+ "I2C (Addr 0x50)",
+};
+#endif
+
+#if defined(CONFIG_440SP) || defined(CONFIG_440SPE)
+#define SDR0_PINSTP_SHIFT 30
+static char *bootstrap_str[] = {
+ "EBC (8 bits)",
+ "PCI",
+ "I2C (Addr 0x54)",
+ "I2C (Addr 0x50)",
+};
+#endif
+
+#if defined(CONFIG_440EP) || defined(CONFIG_440GR)
+#define SDR0_PINSTP_SHIFT 29
+static char *bootstrap_str[] = {
+ "EBC (8 bits)",
+ "PCI",
+ "NAND (8 bits)",
+ "EBC (16 bits)",
+ "EBC (16 bits)",
+ "I2C (Addr 0x54)",
+ "PCI",
+ "I2C (Addr 0x52)",
+};
+#endif
+
+#if defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
+#define SDR0_PINSTP_SHIFT 29
+static char *bootstrap_str[] = {
+ "EBC (8 bits)",
+ "EBC (16 bits)",
+ "EBC (16 bits)",
+ "NAND (8 bits)",
+ "PCI",
+ "I2C (Addr 0x54)",
+ "PCI",
+ "I2C (Addr 0x52)",
+};
+#endif
+
+#if defined(SDR0_PINSTP_SHIFT)
+static int bootstrap_option(void)
+{
+ unsigned long val;
+
+ mfsdr(sdr_pinstp, val);
+ return ((val & 0xe0000000) >> SDR0_PINSTP_SHIFT);
+}
+#endif /* SDR0_PINSTP_SHIFT */
#endif
@@ -129,6 +192,7 @@ int checkcpu (void)
char buf[32];
#if !defined(CONFIG_IOP480)
+ char addstr[64] = "";
sys_info_t sys_info;
puts ("CPU: ");
@@ -244,6 +308,26 @@ int checkcpu (void)
#endif /* CONFIG_440GR */
#endif /* CONFIG_440 */
+ case PVR_440EPX1_RA:
+ puts("EPx Rev. A");
+ strcpy(addstr, "Security/Kasumi support");
+ break;
+
+ case PVR_440EPX2_RA:
+ puts("EPx Rev. A");
+ strcpy(addstr, "No Security/Kasumi support");
+ break;
+
+ case PVR_440GRX1_RA:
+ puts("GRx Rev. A");
+ strcpy(addstr, "Security/Kasumi support");
+ break;
+
+ case PVR_440GRX2_RA:
+ puts("GRx Rev. A");
+ strcpy(addstr, "No Security/Kasumi support");
+ break;
+
case PVR_440SP_RA:
puts("SP Rev. A");
break;
@@ -270,9 +354,16 @@ int checkcpu (void)
sys_info.freqPLB / sys_info.pllOpbDiv / 1000000,
FREQ_EBC / 1000000);
+ if (addstr[0] != 0)
+ printf(" %s\n", addstr);
+
#if defined(I2C_BOOTROM)
printf (" I2C boot EEPROM %sabled\n", i2c_bootrom_enabled() ? "en" : "dis");
-#endif
+#if defined(SDR0_PINSTP_SHIFT)
+ printf (" Bootstrap Option %c - ", (char)bootstrap_option() + 'A');
+ printf ("Boot ROM Location %s\n", bootstrap_str[bootstrap_option()]);
+#endif /* SDR0_PINSTP_SHIFT */
+#endif /* I2C_BOOTROM */
#if defined(CONFIG_PCI)
printf (" Internal PCI arbiter %sabled", pci_arbiter_enabled() ? "en" : "dis");
@@ -315,6 +406,17 @@ int checkcpu (void)
return 0;
}
+#if defined (CONFIG_440SPE)
+int ppc440spe_revB() {
+ unsigned int pvr;
+
+ pvr = get_pvr();
+ if (pvr == PVR_440SPe_RB)
+ return 1;
+ else
+ return 0;
+}
+#endif
/* ------------------------------------------------------------------------- */
diff --git a/cpu/ppc4xx/cpu_init.c b/cpu/ppc4xx/cpu_init.c
index b27567f..def46f1 100644
--- a/cpu/ppc4xx/cpu_init.c
+++ b/cpu/ppc4xx/cpu_init.c
@@ -226,13 +226,19 @@ cpu_init_f (void)
/*
* GPIO0 setup (select GPIO or alternate function)
*/
- out32(GPIO0_OSRH, CFG_GPIO0_OSRH); /* output select */
+#if defined(CFG_GPIO0_OR)
+ out32(GPIO0_OR, CFG_GPIO0_OR); /* set initial state of output pins */
+#endif
+#if defined(CFG_GPIO0_ODR)
+ out32(GPIO0_ODR, CFG_GPIO0_ODR); /* open-drain select */
+#endif
+ out32(GPIO0_OSRH, CFG_GPIO0_OSRH); /* output select */
out32(GPIO0_OSRL, CFG_GPIO0_OSRL);
- out32(GPIO0_ISR1H, CFG_GPIO0_ISR1H); /* input select */
+ out32(GPIO0_ISR1H, CFG_GPIO0_ISR1H); /* input select */
out32(GPIO0_ISR1L, CFG_GPIO0_ISR1L);
- out32(GPIO0_TSRH, CFG_GPIO0_TSRH); /* three-state select */
+ out32(GPIO0_TSRH, CFG_GPIO0_TSRH); /* three-state select */
out32(GPIO0_TSRL, CFG_GPIO0_TSRL);
- out32(GPIO0_TCR, CFG_GPIO0_TCR); /* enable output driver for outputs */
+ out32(GPIO0_TCR, CFG_GPIO0_TCR); /* enable output driver for outputs */
/*
* Set EMAC noise filter bits
diff --git a/cpu/ppc4xx/interrupts.c b/cpu/ppc4xx/interrupts.c
index 886f405..c5a9f02 100644
--- a/cpu/ppc4xx/interrupts.c
+++ b/cpu/ppc4xx/interrupts.c
@@ -57,12 +57,13 @@ static struct irq_action irq_vecs1[32]; /* For UIC1 */
void uic1_interrupt( void * parms); /* UIC1 handler */
-#if defined(CONFIG_440GX) || defined(CONFIG_440SPE)
+#if defined(CONFIG_440GX) || defined(CONFIG_440SPE) || \
+ defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
static struct irq_action irq_vecs2[32]; /* For UIC2 */
void uic2_interrupt( void * parms); /* UIC2 handler */
#endif /* CONFIG_440GX CONFIG_440SPE */
-#if defined(CONFIG_440SPE)
+#if defined(CONFIG_440SPE) || defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
static struct irq_action irq_vecs3[32]; /* For UIC3 */
void uic3_interrupt( void * parms); /* UIC3 handler */
#endif /* CONFIG_440SPE */
@@ -119,12 +120,13 @@ int interrupt_init_cpu (unsigned *decrementer_count)
irq_vecs1[vec].handler = NULL;
irq_vecs1[vec].arg = NULL;
irq_vecs1[vec].count = 0;
-#if defined(CONFIG_440GX) || defined(CONFIG_440SPE)
+#if defined(CONFIG_440GX) || defined(CONFIG_440SPE) || \
+ defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
irq_vecs2[vec].handler = NULL;
irq_vecs2[vec].arg = NULL;
irq_vecs2[vec].count = 0;
#endif /* CONFIG_440GX */
-#if defined(CONFIG_440SPE)
+#if defined(CONFIG_440SPE) || defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
irq_vecs3[vec].handler = NULL;
irq_vecs3[vec].arg = NULL;
irq_vecs3[vec].count = 0;
@@ -230,6 +232,32 @@ void external_interrupt(struct pt_regs *regs)
} /* external_interrupt CONFIG_440GX */
+#elif defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
+void external_interrupt(struct pt_regs *regs)
+{
+ ulong uic_msr;
+
+ /*
+ * Read masked interrupt status register to determine interrupt source
+ */
+ /* 440 SPe uses base uic register */
+ uic_msr = mfdcr(uic0msr);
+
+ if ( (UICB0_UIC1CI & uic_msr) || (UICB0_UIC1NCI & uic_msr) )
+ uic1_interrupt(0);
+
+ if ( (UICB0_UIC2CI & uic_msr) || (UICB0_UIC2NCI & uic_msr) )
+ uic2_interrupt(0);
+
+ if (uic_msr & ~(UICB0_ALL))
+ uic0_interrupt(0);
+
+ mtdcr(uic0sr, uic_msr);
+
+ return;
+
+} /* external_interrupt CONFIG_440EPX & CONFIG_440GRX */
+
#elif defined(CONFIG_440SPE)
void external_interrupt(struct pt_regs *regs)
{
@@ -303,7 +331,8 @@ void external_interrupt(struct pt_regs *regs)
}
#endif
-#if defined(CONFIG_440GX) || defined(CONFIG_440SPE)
+#if defined(CONFIG_440GX) || defined(CONFIG_440SPE) || \
+ defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
/* Handler for UIC0 interrupt */
void uic0_interrupt( void * parms)
{
@@ -394,7 +423,8 @@ void uic1_interrupt( void * parms)
}
#endif /* defined(CONFIG_440) */
-#if defined(CONFIG_440GX) || defined(CONFIG_440SPE)
+#if defined(CONFIG_440GX) || defined(CONFIG_440SPE) || \
+ defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
/* Handler for UIC2 interrupt */
void uic2_interrupt( void * parms)
{
@@ -496,7 +526,8 @@ void irq_install_handler (int vec, interrupt_handler_t * handler, void *arg)
int i = vec;
#if defined(CONFIG_440)
-#if defined(CONFIG_440GX) || defined(CONFIG_440SPE)
+#if defined(CONFIG_440GX) || defined(CONFIG_440SPE) || \
+ defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
if ((vec > 31) && (vec < 64)) {
i = vec - 32;
irqa = irq_vecs1;
@@ -523,7 +554,8 @@ void irq_install_handler (int vec, interrupt_handler_t * handler, void *arg)
irqa[i].arg = arg;
#if defined(CONFIG_440)
-#if defined(CONFIG_440GX) || defined(CONFIG_440SPE)
+#if defined(CONFIG_440GX) || defined(CONFIG_440SPE) || \
+ defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
if ((vec > 31) && (vec < 64))
mtdcr (uic1er, mfdcr (uic1er) | (0x80000000 >> i));
else if (vec > 63)
@@ -546,7 +578,8 @@ void irq_free_handler (int vec)
int i = vec;
#if defined(CONFIG_440)
-#if defined(CONFIG_440GX) || defined(CONFIG_440SPE)
+#if defined(CONFIG_440GX) || defined(CONFIG_440SPE) || \
+ defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
if ((vec > 31) && (vec < 64)) {
irqa = irq_vecs1;
i = vec - 32;
@@ -567,7 +600,8 @@ void irq_free_handler (int vec)
#endif
#if defined(CONFIG_440)
-#if defined(CONFIG_440GX) || defined(CONFIG_440SPE)
+#if defined(CONFIG_440GX) || defined(CONFIG_440SPE) || \
+ defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
if ((vec > 31) && (vec < 64))
mtdcr (uic1er, mfdcr (uic1er) & ~(0x80000000 >> i));
else if (vec > 63)
@@ -635,7 +669,8 @@ do_irqinfo(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
printf("\n");
#endif
-#if defined(CONFIG_440GX) || defined(CONFIG_440SPE)
+#if defined(CONFIG_440GX) || defined(CONFIG_440SPE) || \
+ defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
printf ("\nUIC 2\n");
printf ("Nr Routine Arg Count\n");
diff --git a/cpu/ppc4xx/miiphy.c b/cpu/ppc4xx/miiphy.c
index aa580ed..6b98025 100644
--- a/cpu/ppc4xx/miiphy.c
+++ b/cpu/ppc4xx/miiphy.c
@@ -173,7 +173,8 @@ int emac4xx_miiphy_read (char *devname, unsigned char addr,
}
sta_reg = reg; /* reg address */
/* set clock (50Mhz) and read flags */
-#if defined(CONFIG_440GX) || defined(CONFIG_440SPE)
+#if defined(CONFIG_440GX) || defined(CONFIG_440SPE) || \
+ defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
#if defined(CONFIG_IBM_EMAC4_V4) /* EMAC4 V4 changed bit setting */
sta_reg = (sta_reg & ~EMAC_STACR_OP_MASK) | EMAC_STACR_READ;
#else
@@ -183,7 +184,9 @@ int emac4xx_miiphy_read (char *devname, unsigned char addr,
sta_reg = (sta_reg | EMAC_STACR_READ) & ~EMAC_STACR_CLK_100MHZ;
#endif
-#if defined(CONFIG_PHY_CLK_FREQ) && !defined(CONFIG_440GX) && !defined(CONFIG__440SP) && !defined(CONFIG__440SPE)
+#if defined(CONFIG_PHY_CLK_FREQ) && !defined(CONFIG_440GX) && \
+ !defined(CONFIG_440SP) && !defined(CONFIG_440SPE) && \
+ !defined(CONFIG_440EPX) && !defined(CONFIG_440GRX)
sta_reg = sta_reg | CONFIG_PHY_CLK_FREQ;
#endif
sta_reg = sta_reg | (addr << 5); /* Phy address */
@@ -244,7 +247,8 @@ int emac4xx_miiphy_write (char *devname, unsigned char addr,
sta_reg = 0;
sta_reg = reg; /* reg address */
/* set clock (50Mhz) and read flags */
-#if defined(CONFIG_440GX) || defined(CONFIG_440SPE)
+#if defined(CONFIG_440GX) || defined(CONFIG_440SPE) || \
+ defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
#if defined(CONFIG_IBM_EMAC4_V4) /* EMAC4 V4 changed bit setting */
sta_reg = (sta_reg & ~EMAC_STACR_OP_MASK) | EMAC_STACR_WRITE;
#else
@@ -254,7 +258,9 @@ int emac4xx_miiphy_write (char *devname, unsigned char addr,
sta_reg = (sta_reg | EMAC_STACR_WRITE) & ~EMAC_STACR_CLK_100MHZ;
#endif
-#if defined(CONFIG_PHY_CLK_FREQ) && !defined(CONFIG_440GX) && !defined(CONFIG__440SP) && !defined(CONFIG__440SPE)
+#if defined(CONFIG_PHY_CLK_FREQ) && !defined(CONFIG_440GX) && \
+ !defined(CONFIG_440SP) && !defined(CONFIG_440SPE) && \
+ !defined(CONFIG_440EPX) && !defined(CONFIG_440GRX)
sta_reg = sta_reg | CONFIG_PHY_CLK_FREQ; /* Set clock frequency (PLB freq. dependend) */
#endif
sta_reg = sta_reg | ((unsigned long) addr << 5);/* Phy address */
diff --git a/cpu/ppc4xx/ndfc.c b/cpu/ppc4xx/ndfc.c
new file mode 100644
index 0000000..3521731
--- /dev/null
+++ b/cpu/ppc4xx/ndfc.c
@@ -0,0 +1,193 @@
+/*
+ * Overview:
+ * Platform independend driver for NDFC (NanD Flash Controller)
+ * integrated into EP440 cores
+ *
+ * (C) Copyright 2006
+ * Stefan Roese, DENX Software Engineering, sr@denx.de.
+ *
+ * Based on original work by
+ * Thomas Gleixner
+ * Copyright 2006 IBM
+ *
+ * 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) && !defined(CFG_NAND_LEGACY) && \
+ (defined(CONFIG_440EP) || defined(CONFIG_440GR) || \
+ defined(CONFIG_440EPX) || defined(CONFIG_440GRX))
+
+#include <nand.h>
+#include <linux/mtd/ndfc.h>
+#include <asm/processor.h>
+#include <ppc440.h>
+
+static u8 hwctl = 0;
+
+static void ndfc_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 ndfc_write_byte(struct mtd_info *mtdinfo, u_char byte)
+{
+ struct nand_chip *this = mtdinfo->priv;
+ ulong base = (ulong) this->IO_ADDR_W & 0xfffffffc;
+
+ if (hwctl & 0x1)
+ out8(base + NDFC_CMD, byte);
+ else if (hwctl & 0x2)
+ out8(base + NDFC_ALE, byte);
+ else
+ out8(base + NDFC_DATA, byte);
+}
+
+static u_char ndfc_read_byte(struct mtd_info *mtdinfo)
+{
+ struct nand_chip *this = mtdinfo->priv;
+ ulong base = (ulong) this->IO_ADDR_W & 0xfffffffc;
+
+ return (in8(base + NDFC_DATA));
+}
+
+static int ndfc_dev_ready(struct mtd_info *mtdinfo)
+{
+ struct nand_chip *this = mtdinfo->priv;
+ ulong base = (ulong) this->IO_ADDR_W & 0xfffffffc;
+
+ while (!(in32(base + NDFC_STAT) & NDFC_STAT_IS_READY))
+ ;
+
+ return 1;
+}
+
+#ifndef CONFIG_NAND_SPL
+/*
+ * Don't use these speedup functions in NAND boot image, since the image
+ * has to fit into 4kByte.
+ */
+
+/*
+ * Speedups for buffer read/write/verify
+ *
+ * NDFC allows 32bit read/write of data. So we can speed up the buffer
+ * functions. No further checking, as nand_base will always read/write
+ * page aligned.
+ */
+static void ndfc_read_buf(struct mtd_info *mtdinfo, uint8_t *buf, int len)
+{
+ struct nand_chip *this = mtdinfo->priv;
+ ulong base = (ulong) this->IO_ADDR_W & 0xfffffffc;
+ uint32_t *p = (uint32_t *) buf;
+
+ for (;len > 0; len -= 4)
+ *p++ = in32(base + NDFC_DATA);
+}
+
+static void ndfc_write_buf(struct mtd_info *mtdinfo, const uint8_t *buf, int len)
+{
+ struct nand_chip *this = mtdinfo->priv;
+ ulong base = (ulong) this->IO_ADDR_W & 0xfffffffc;
+ uint32_t *p = (uint32_t *) buf;
+
+ for (; len > 0; len -= 4)
+ out32(base + NDFC_DATA, *p++);
+}
+
+static int ndfc_verify_buf(struct mtd_info *mtdinfo, const uint8_t *buf, int len)
+{
+ struct nand_chip *this = mtdinfo->priv;
+ ulong base = (ulong) this->IO_ADDR_W & 0xfffffffc;
+ uint32_t *p = (uint32_t *) buf;
+
+ for (; len > 0; len -= 4)
+ if (*p++ != in32(base + NDFC_DATA))
+ return -1;
+
+ return 0;
+}
+#endif /* #ifndef CONFIG_NAND_SPL */
+
+void board_nand_select_device(struct nand_chip *nand, int chip)
+{
+ /*
+ * Don't use "chip" to address the NAND device,
+ * generate the cs from the address where it is encoded.
+ */
+ int cs = (ulong)nand->IO_ADDR_W & 0x00000003;
+ ulong base = (ulong)nand->IO_ADDR_W & 0xfffffffc;
+
+ /* Set NandFlash Core Configuration Register */
+ /* 1col x 2 rows */
+ out32(base + NDFC_CCR, 0x00000000 | (cs << 24));
+}
+
+void board_nand_init(struct nand_chip *nand)
+{
+ int cs = (ulong)nand->IO_ADDR_W & 0x00000003;
+ ulong base = (ulong)nand->IO_ADDR_W & 0xfffffffc;
+
+ nand->eccmode = NAND_ECC_SOFT;
+
+ nand->hwcontrol = ndfc_hwcontrol;
+ nand->read_byte = ndfc_read_byte;
+ nand->write_byte = ndfc_write_byte;
+ nand->dev_ready = ndfc_dev_ready;
+
+#ifndef CONFIG_NAND_SPL
+ nand->write_buf = ndfc_write_buf;
+ nand->read_buf = ndfc_read_buf;
+ nand->verify_buf = ndfc_verify_buf;
+#else
+ /*
+ * Setup EBC (CS0 only right now)
+ */
+ mtdcr(ebccfga, xbcfg);
+ mtdcr(ebccfgd, 0xb8400000);
+
+ mtebc(pb0cr, CFG_EBC_PB0CR);
+ mtebc(pb0ap, CFG_EBC_PB0AP);
+#endif
+
+ /*
+ * Select required NAND chip in NDFC
+ */
+ board_nand_select_device(nand, cs);
+ out32(base + NDFC_BCFG0 + (cs << 2), 0x80002222);
+}
+
+#endif
diff --git a/cpu/ppc4xx/serial.c b/cpu/ppc4xx/serial.c
index ad3ca6e..fab0d95 100644
--- a/cpu/ppc4xx/serial.c
+++ b/cpu/ppc4xx/serial.c
@@ -264,10 +264,12 @@ int serial_tstc ()
#endif /* CONFIG_IOP480 */
/*****************************************************************************/
-#if defined(CONFIG_405GP) || defined(CONFIG_405CR) || defined(CONFIG_440) || defined(CONFIG_405EP)
+#if defined(CONFIG_405GP) || defined(CONFIG_405CR) || defined(CONFIG_405EP) || \
+ defined(CONFIG_440)
#if defined(CONFIG_440)
-#if defined(CONFIG_440EP) || defined(CONFIG_440GR)
+#if defined(CONFIG_440EP) || defined(CONFIG_440GR) || \
+ defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
#define UART0_BASE CFG_PERIPHERAL_BASE + 0x00000300
#define UART1_BASE CFG_PERIPHERAL_BASE + 0x00000400
#else
@@ -279,15 +281,34 @@ int serial_tstc ()
#define UART2_BASE CFG_PERIPHERAL_BASE + 0x00000600
#endif
-#if defined(CONFIG_440GX) || defined(CONFIG_440EP) || defined(CONFIG_440GR) || defined(CONFIG_440SP) || defined(CONFIG_440SPE)
-#define CR0_MASK 0xdfffffff
-#define CR0_EXTCLK_ENA 0x00800000
-#define CR0_UDIV_POS 0
-#else
+#if defined(CONFIG_440GP)
#define CR0_MASK 0x3fff0000
#define CR0_EXTCLK_ENA 0x00600000
#define CR0_UDIV_POS 16
-#endif /* CONFIG_440GX */
+#define UDIV_SUBTRACT 1
+#define UART0_SDR cntrl0
+#define MFREG(a, d) d = mfdcr(a)
+#define MTREG(a, d) mtdcr(a, d)
+#else /* #if defined(CONFIG_440GP) */
+/* all other 440 PPC's access clock divider via sdr register */
+#define CR0_MASK 0xdfffffff
+#define CR0_EXTCLK_ENA 0x00800000
+#define CR0_UDIV_POS 0
+#define UDIV_SUBTRACT 0
+#define UART0_SDR sdr_uart0
+#define UART1_SDR sdr_uart1
+#if defined(CONFIG_440EP) || defined(CONFIG_440EPx) || \
+ defined(CONFIG_440GR) || defined(CONFIG_440GRx) || \
+ defined(CONFIG_440SP) || defined(CONFIG_440SPe)
+#define UART2_SDR sdr_uart2
+#endif
+#if defined(CONFIG_440EP) || defined(CONFIG_440EPx) || \
+ defined(CONFIG_440GR) || defined(CONFIG_440GRx)
+#define UART3_SDR sdr_uart3
+#endif
+#define MFREG(a, d) mfsdr(a, d)
+#define MTREG(a, d) mtsdr(a, d)
+#endif /* #if defined(CONFIG_440GP) */
#elif defined(CONFIG_405EP)
#define UART0_BASE 0xef600300
#define UART1_BASE 0xef600400
@@ -309,21 +330,15 @@ int serial_tstc ()
#if defined(CONFIG_UART1_CONSOLE)
#define ACTING_UART0_BASE UART1_BASE
#define ACTING_UART1_BASE UART0_BASE
-#if defined(CONFIG_440GX) || defined(CONFIG_440EP) || \
- defined(CONFIG_440GR) || defined(CONFIG_440SP) || \
- defined(CONFIG_440SPE)
-#define UART0_SDR sdr_uart1
-#define UART1_SDR sdr_uart0
-#endif /* CONFIG_440GX */
#else
#define ACTING_UART0_BASE UART0_BASE
#define ACTING_UART1_BASE UART1_BASE
-#if defined(CONFIG_440GX) || defined(CONFIG_440EP) || \
- defined(CONFIG_440GR) || defined(CONFIG_440SP) || \
- defined(CONFIG_440SPE)
-#define UART0_SDR sdr_uart0
-#define UART1_SDR sdr_uart1
-#endif /* CONFIG_440GX */
+#endif
+
+#if defined(CONFIG_SERIAL_MULTI)
+#define UART_BASE dev_base
+#else
+#define UART_BASE ACTING_UART0_BASE
#endif
#if defined(CONFIG_405EP) && defined(CFG_EXT_SERIAL_CLOCK)
@@ -419,7 +434,7 @@ static void serial_divs (int baudrate, unsigned long *pudiv,
*pbdiv = div/udiv;
}
-#endif /* defined(CONFIG_440) && !defined(CFG_EXT_SERIAL_CLK */
+#endif /* defined(CONFIG_440) && !defined(CFG_EXT_SERIAL_CLK) */
/*
* Minimal serial functions needed to use one of the SMC ports
@@ -441,23 +456,9 @@ int serial_init(void)
unsigned long tmp;
#endif
-#if defined(CONFIG_440GX) || defined(CONFIG_440SP) || \
- defined(CONFIG_440SPE)
-#if defined(CONFIG_SERIAL_MULTI)
- if (UART0_BASE == dev_base) {
- mfsdr(UART0_SDR,reg);
- reg &= ~CR0_MASK;
- } else {
- mfsdr(UART1_SDR,reg);
- reg &= ~CR0_MASK;
- }
-#else
- mfsdr(UART0_SDR,reg);
+ MFREG(UART0_SDR, reg);
reg &= ~CR0_MASK;
-#endif
-#else
- reg = mfdcr(cntrl0) & ~CR0_MASK;
-#endif /* CONFIG_440GX */
+
#ifdef CFG_EXT_SERIAL_CLOCK
reg |= CR0_EXTCLK_ENA;
udiv = 1;
@@ -471,47 +472,34 @@ int serial_init(void)
serial_divs (gd->baudrate, &udiv, &bdiv);
#endif
-#if defined(CONFIG_440GX) || defined(CONFIG_440EP) || \
- defined(CONFIG_440GR) || defined(CONFIG_440SP) || \
- defined(CONFIG_440SPE)
- reg |= udiv << CR0_UDIV_POS; /* set the UART divisor */
-#if defined(CONFIG_SERIAL_MULTI)
- if (UART0_BASE == dev_base) {
- mtsdr (UART0_SDR,reg);
- } else {
- mtsdr (UART1_SDR,reg);
- }
-#else
- mtsdr (UART0_SDR,reg);
+ reg |= (udiv - UDIV_SUBTRACT) << CR0_UDIV_POS; /* set the UART divisor */
+
+ /*
+ * Configure input clock to baudrate generator for all
+ * available serial ports here
+ */
+ MTREG(UART0_SDR, reg);
+#if defined(UART1_SDR)
+ MTREG(UART1_SDR, reg);
#endif
-#else
- reg |= (udiv - 1) << CR0_UDIV_POS; /* set the UART divisor */
- mtdcr (cntrl0, reg);
+#if defined(UART2_SDR)
+ MTREG(UART2_SDR, reg);
#endif
-
-#if defined(CONFIG_SERIAL_MULTI)
- out8 (dev_base + UART_LCR, 0x80); /* set DLAB bit */
- out8 (dev_base + UART_DLL, bdiv); /* set baudrate divisor */
- out8 (dev_base + UART_DLM, bdiv >> 8);/* set baudrate divisor */
- out8 (dev_base + UART_LCR, 0x03); /* clear DLAB; set 8 bits, no parity */
- out8 (dev_base + UART_FCR, 0x00); /* disable FIFO */
- out8 (dev_base + UART_MCR, 0x00); /* no modem control DTR RTS */
- val = in8 (dev_base + UART_LSR); /* clear line status */
- val = in8 (dev_base + UART_RBR); /* read receive buffer */
- out8 (dev_base + UART_SCR, 0x00); /* set scratchpad */
- out8 (dev_base + UART_IER, 0x00); /* set interrupt enable reg */
-#else
- out8 (ACTING_UART0_BASE + UART_LCR, 0x80); /* set DLAB bit */
- out8 (ACTING_UART0_BASE + UART_DLL, bdiv); /* set baudrate divisor */
- out8 (ACTING_UART0_BASE + UART_DLM, bdiv >> 8);/* set baudrate divisor */
- out8 (ACTING_UART0_BASE + UART_LCR, 0x03); /* clear DLAB; set 8 bits, no parity */
- out8 (ACTING_UART0_BASE + UART_FCR, 0x00); /* disable FIFO */
- out8 (ACTING_UART0_BASE + UART_MCR, 0x00); /* no modem control DTR RTS */
- val = in8 (ACTING_UART0_BASE + UART_LSR); /* clear line status */
- val = in8 (ACTING_UART0_BASE + UART_RBR); /* read receive buffer */
- out8 (ACTING_UART0_BASE + UART_SCR, 0x00); /* set scratchpad */
- out8 (ACTING_UART0_BASE + UART_IER, 0x00); /* set interrupt enable reg */
+#if defined(UART3_SDR)
+ MTREG(UART3_SDR, reg);
#endif
+
+ out8(UART_BASE + UART_LCR, 0x80); /* set DLAB bit */
+ out8(UART_BASE + UART_DLL, bdiv); /* set baudrate divisor */
+ out8(UART_BASE + UART_DLM, bdiv >> 8); /* set baudrate divisor */
+ out8(UART_BASE + UART_LCR, 0x03); /* clear DLAB; set 8 bits, no parity */
+ out8(UART_BASE + UART_FCR, 0x00); /* disable FIFO */
+ out8(UART_BASE + UART_MCR, 0x00); /* no modem control DTR RTS */
+ val = in8(UART_BASE + UART_LSR); /* clear line status */
+ val = in8(UART_BASE + UART_RBR); /* read receive buffer */
+ out8(UART_BASE + UART_SCR, 0x00); /* set scratchpad */
+ out8(UART_BASE + UART_IER, 0x00); /* set interrupt enable reg */
+
return (0);
}
@@ -564,29 +552,17 @@ int serial_init (void)
tmp = gd->baudrate * udiv * 16;
bdiv = (clk + tmp / 2) / tmp;
-#if defined(CONFIG_SERIAL_MULTI)
- out8 (dev_base + UART_LCR, 0x80); /* set DLAB bit */
- out8 (dev_base + UART_DLL, bdiv); /* set baudrate divisor */
- out8 (dev_base + UART_DLM, bdiv >> 8);/* set baudrate divisor */
- out8 (dev_base + UART_LCR, 0x03); /* clear DLAB; set 8 bits, no parity */
- out8 (dev_base + UART_FCR, 0x00); /* disable FIFO */
- out8 (dev_base + UART_MCR, 0x00); /* no modem control DTR RTS */
- val = in8 (dev_base + UART_LSR); /* clear line status */
- val = in8 (dev_base + UART_RBR); /* read receive buffer */
- out8 (dev_base + UART_SCR, 0x00); /* set scratchpad */
- out8 (dev_base + UART_IER, 0x00); /* set interrupt enable reg */
-#else
- out8 (ACTING_UART0_BASE + UART_LCR, 0x80); /* set DLAB bit */
- out8 (ACTING_UART0_BASE + UART_DLL, bdiv); /* set baudrate divisor */
- out8 (ACTING_UART0_BASE + UART_DLM, bdiv >> 8);/* set baudrate divisor */
- out8 (ACTING_UART0_BASE + UART_LCR, 0x03); /* clear DLAB; set 8 bits, no parity */
- out8 (ACTING_UART0_BASE + UART_FCR, 0x00); /* disable FIFO */
- out8 (ACTING_UART0_BASE + UART_MCR, 0x00); /* no modem control DTR RTS */
- val = in8 (ACTING_UART0_BASE + UART_LSR); /* clear line status */
- val = in8 (ACTING_UART0_BASE + UART_RBR); /* read receive buffer */
- out8 (ACTING_UART0_BASE + UART_SCR, 0x00); /* set scratchpad */
- out8 (ACTING_UART0_BASE + UART_IER, 0x00); /* set interrupt enable reg */
-#endif
+ out8(UART_BASE + UART_LCR, 0x80); /* set DLAB bit */
+ out8(UART_BASE + UART_DLL, bdiv); /* set baudrate divisor */
+ out8(UART_BASE + UART_DLM, bdiv >> 8); /* set baudrate divisor */
+ out8(UART_BASE + UART_LCR, 0x03); /* clear DLAB; set 8 bits, no parity */
+ out8(UART_BASE + UART_FCR, 0x00); /* disable FIFO */
+ out8(UART_BASE + UART_MCR, 0x00); /* no modem control DTR RTS */
+ val = in8(UART_BASE + UART_LSR); /* clear line status */
+ val = in8(UART_BASE + UART_RBR); /* read receive buffer */
+ out8(UART_BASE + UART_SCR, 0x00); /* set scratchpad */
+ out8(UART_BASE + UART_IER, 0x00); /* set interrupt enable reg */
+
return (0);
}
@@ -598,55 +574,10 @@ void serial_setbrg_dev (unsigned long dev_base)
void serial_setbrg (void)
#endif
{
- unsigned long tmp;
- unsigned long clk;
- unsigned long udiv;
- unsigned short bdiv;
-
-#ifdef CFG_EXT_SERIAL_CLOCK
- clk = CFG_EXT_SERIAL_CLOCK;
-#else
- clk = gd->cpu_clk;
-#endif
-
-#ifdef CONFIG_405EP
- udiv = ((mfdcr (cpc0_ucr) & UCR0_MASK) >> UCR0_UDIV_POS);
-#else
- udiv = ((mfdcr (cntrl0) & 0x3e) >> 1) + 1;
-#endif /* CONFIG_405EP */
-
-#if !defined(CFG_EXT_SERIAL_CLOCK) && \
- ( defined(CONFIG_440GX) || defined(CONFIG_440EP) || \
- defined(CONFIG_440GR) || defined(CONFIG_440SP) || \
- defined(CONFIG_440SPE) )
- serial_divs (gd->baudrate, &udiv, &bdiv);
- tmp = udiv << CR0_UDIV_POS; /* set the UART divisor */
-#if defined(CONFIG_SERIAL_MULTI)
- if (UART0_BASE == dev_base) {
- mtsdr (UART0_SDR, tmp);
- } else {
- mtsdr (UART1_SDR, tmp);
- }
-#else
- mtsdr (UART0_SDR, tmp);
-#endif
-
-#else
-
- tmp = gd->baudrate * udiv * 16;
- bdiv = (clk + tmp / 2) / tmp;
-#endif /* !defined(CFG_EXT_SERIAL_CLOCK) && (...) */
-
#if defined(CONFIG_SERIAL_MULTI)
- out8 (dev_base + UART_LCR, 0x80); /* set DLAB bit */
- out8 (dev_base + UART_DLL, bdiv); /* set baudrate divisor */
- out8 (dev_base + UART_DLM, bdiv >> 8);/* set baudrate divisor */
- out8 (dev_base + UART_LCR, 0x03); /* clear DLAB; set 8 bits, no parity */
+ serial_init_dev(dev_base);
#else
- out8 (ACTING_UART0_BASE + UART_LCR, 0x80); /* set DLAB bit */
- out8 (ACTING_UART0_BASE + UART_DLL, bdiv); /* set baudrate divisor */
- out8 (ACTING_UART0_BASE + UART_DLM, bdiv >> 8);/* set baudrate divisor */
- out8 (ACTING_UART0_BASE + UART_LCR, 0x03); /* clear DLAB; set 8 bits, no parity */
+ serial_init();
#endif
}
@@ -667,19 +598,11 @@ void serial_putc (const char c)
/* check THRE bit, wait for transmiter available */
for (i = 1; i < 3500; i++) {
-#if defined(CONFIG_SERIAL_MULTI)
- if ((in8 (dev_base + UART_LSR) & 0x20) == 0x20)
-#else
- if ((in8 (ACTING_UART0_BASE + UART_LSR) & 0x20) == 0x20)
-#endif
+ if ((in8 (UART_BASE + UART_LSR) & 0x20) == 0x20)
break;
udelay (100);
}
-#if defined(CONFIG_SERIAL_MULTI)
- out8 (dev_base + UART_THR, c); /* put character out */
-#else
- out8 (ACTING_UART0_BASE + UART_THR, c); /* put character out */
-#endif
+ out8 (UART_BASE + UART_THR, c); /* put character out */
}
#if defined(CONFIG_SERIAL_MULTI)
@@ -709,11 +632,7 @@ int serial_getc (void)
#if defined(CONFIG_HW_WATCHDOG)
WATCHDOG_RESET (); /* Reset HW Watchdog, if needed */
#endif /* CONFIG_HW_WATCHDOG */
-#if defined(CONFIG_SERIAL_MULTI)
- status = in8 (dev_base + UART_LSR);
-#else
- status = in8 (ACTING_UART0_BASE + UART_LSR);
-#endif
+ status = in8 (UART_BASE + UART_LSR);
if ((status & asyncLSRDataReady1) != 0x0) {
break;
}
@@ -721,22 +640,14 @@ int serial_getc (void)
asyncLSROverrunError1 |
asyncLSRParityError1 |
asyncLSRBreakInterrupt1 )) != 0) {
-#if defined(CONFIG_SERIAL_MULTI)
- out8 (dev_base + UART_LSR,
-#else
- out8 (ACTING_UART0_BASE + UART_LSR,
-#endif
+ out8 (UART_BASE + UART_LSR,
asyncLSRFramingError1 |
asyncLSROverrunError1 |
asyncLSRParityError1 |
asyncLSRBreakInterrupt1);
}
}
-#if defined(CONFIG_SERIAL_MULTI)
- return (0x000000ff & (int) in8 (dev_base));
-#else
- return (0x000000ff & (int) in8 (ACTING_UART0_BASE));
-#endif
+ return (0x000000ff & (int) in8 (UART_BASE));
}
#if defined(CONFIG_SERIAL_MULTI)
@@ -747,11 +658,7 @@ int serial_tstc (void)
{
unsigned char status;
-#if defined(CONFIG_SERIAL_MULTI)
- status = in8 (dev_base + UART_LSR);
-#else
- status = in8 (ACTING_UART0_BASE + UART_LSR);
-#endif
+ status = in8 (UART_BASE + UART_LSR);
if ((status & asyncLSRDataReady1) != 0x0) {
return (1);
}
@@ -759,11 +666,7 @@ int serial_tstc (void)
asyncLSROverrunError1 |
asyncLSRParityError1 |
asyncLSRBreakInterrupt1 )) != 0) {
-#if defined(CONFIG_SERIAL_MULTI)
- out8 (dev_base + UART_LSR,
-#else
- out8 (ACTING_UART0_BASE + UART_LSR,
-#endif
+ out8 (UART_BASE + UART_LSR,
asyncLSRFramingError1 |
asyncLSROverrunError1 |
asyncLSRParityError1 |
diff --git a/cpu/ppc4xx/speed.c b/cpu/ppc4xx/speed.c
index e552c03..2d16a83 100644
--- a/cpu/ppc4xx/speed.c
+++ b/cpu/ppc4xx/speed.c
@@ -199,7 +199,8 @@ ulong get_PCI_freq (void)
#elif defined(CONFIG_440)
-#if defined(CONFIG_440EP) || defined(CONFIG_440GR)
+#if defined(CONFIG_440EP) || defined(CONFIG_440GR) || \
+ defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
void get_sys_info (sys_info_t *sysInfo)
{
unsigned long temp;
diff --git a/cpu/ppc4xx/start.S b/cpu/ppc4xx/start.S
index 699fa7f..8e000d3 100644
--- a/cpu/ppc4xx/start.S
+++ b/cpu/ppc4xx/start.S
@@ -117,12 +117,16 @@
.extern ext_bus_cntlr_init
.extern sdram_init
+#ifdef CONFIG_NAND_U_BOOT
+ .extern reconfig_tlb0
+#endif
/*
* Set up GOT: Global Offset Table
*
* Use r14 to access the GOT
*/
+#if !defined(CONFIG_NAND_SPL)
START_GOT
GOT_ENTRY(_GOT2_TABLE_)
GOT_ENTRY(_FIXUP_TABLE_)
@@ -136,6 +140,18 @@
GOT_ENTRY(_end)
GOT_ENTRY(__bss_start)
END_GOT
+#endif /* CONFIG_NAND_SPL */
+
+#if defined(CONFIG_NAND_U_BOOT) && !defined(CONFIG_NAND_SPL)
+ /*
+ * NAND U-Boot image is started from offset 0
+ */
+ .text
+ bl reconfig_tlb0
+ GET_GOT
+ bl cpu_init_f /* run low-level CPU init code (from Flash) */
+ bl board_init_f
+#endif
/*
* 440 Startup -- on reset only the top 4k of the effective
@@ -150,11 +166,21 @@
*/
#if defined(CONFIG_440)
+#if !defined(CONFIG_NAND_SPL)
.section .bootpg,"ax"
+#endif
.globl _start_440
/**************************************************************************/
_start_440:
+ /*--------------------------------------------------------------------+
+ | 440EPX BUP Change - Hardware team request
+ +--------------------------------------------------------------------*/
+#if defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
+ sync
+ nop
+ nop
+#endif
/*----------------------------------------------------------------+
| Core bug fix. Clear the esr
+-----------------------------------------------------------------*/
@@ -171,15 +197,31 @@ _start_440:
mtspr srr1,r0
mtspr csrr0,r0
mtspr csrr1,r0
-#if defined(CONFIG_440GX) || defined(CONFIG_440SP) || defined(CONFIG_440SPE) /* NOTE: 440GX adds machine check status regs */
+ /* NOTE: 440GX adds machine check status regs */
+#if defined(CONFIG_440) && !defined(CONFIG_440GP)
mtspr mcsrr0,r0
mtspr mcsrr1,r0
- mfspr r1, mcsr
+ mfspr r1,mcsr
mtspr mcsr,r1
#endif
+
+ /*----------------------------------------------------------------*/
+ /* CCR0 init */
+ /*----------------------------------------------------------------*/
+ /* Disable store gathering & broadcast, guarantee inst/data
+ * cache block touch, force load/store alignment
+ * (see errata 1.12: 440_33)
+ */
+ lis r1,0x0030 /* store gathering & broadcast disable */
+ ori r1,r1,0x6000 /* cache touch */
+ mtspr ccr0,r1
+
/*----------------------------------------------------------------*/
/* Initialize debug */
/*----------------------------------------------------------------*/
+ mfspr r1,dbcr0
+ andis. r1, r1, 0x8000 /* test DBCR0[EDM] bit */
+ bne skip_debug_init /* if set, don't clear debug register */
mtspr dbcr0,r0
mtspr dbcr1,r0
mtspr dbcr2,r0
@@ -193,17 +235,7 @@ _start_440:
mfspr r1,dbsr
mtspr dbsr,r1 /* Clear all valid bits */
-
- /*----------------------------------------------------------------*/
- /* CCR0 init */
- /*----------------------------------------------------------------*/
- /* Disable store gathering & broadcast, guarantee inst/data
- * cache block touch, force load/store alignment
- * (see errata 1.12: 440_33)
- */
- lis r1,0x0030 /* store gathering & broadcast disable */
- ori r1,r1,0x6000 /* cache touch */
- mtspr ccr0,r1
+skip_debug_init:
#if defined (CONFIG_440SPE)
/*----------------------------------------------------------------+
@@ -315,7 +347,23 @@ rsttlb: tlbwe r0,r1,0x0000 /* Invalidate all entries (V=0)*/
/*----------------------------------------------------------------*/
/* TLB entry setup -- step thru tlbtab */
/*----------------------------------------------------------------*/
+#if defined(CONFIG_440SPE)
+ /*----------------------------------------------------------------*/
+ /* We have different TLB tables for revA and rev B of 440SPe */
+ /*----------------------------------------------------------------*/
+ mfspr r1, PVR
+ lis r0,0x5342
+ ori r0,r0,0x1891
+ cmpw r7,r1,r0
+ bne r7,..revA
+ bl tlbtabB
+ b ..goon
+..revA:
+ bl tlbtabA
+..goon:
+#else
bl tlbtab /* Get tlbtab pointer */
+#endif
mr r5,r0
li r1,0x003f /* 64 TLB entries max */
mtctr r1
@@ -336,7 +384,53 @@ rsttlb: tlbwe r0,r1,0x0000 /* Invalidate all entries (V=0)*/
/*----------------------------------------------------------------*/
/* Continue from 'normal' start */
/*----------------------------------------------------------------*/
-2: bl 3f
+2:
+
+#if defined(CONFIG_NAND_SPL)
+ /*
+ * Enable internal SRAM
+ */
+ lis r2,0x7fff
+ ori r2,r2,0xffff
+ mfdcr r1,isram0_dpc
+ and r1,r1,r2 /* Disable parity check */
+ mtdcr isram0_dpc,r1
+ mfdcr r1,isram0_pmeg
+ and r1,r1,r2 /* Disable pwr mgmt */
+ mtdcr isram0_pmeg,r1
+
+ /*
+ * Copy SPL from cache into internal SRAM
+ */
+ li r4,(CFG_NAND_BOOT_SPL_SIZE >> 2) - 1
+ mtctr r4
+ lis r2,CFG_NAND_BOOT_SPL_SRC@h
+ ori r2,r2,CFG_NAND_BOOT_SPL_SRC@l
+ lis r3,CFG_NAND_BOOT_SPL_DST@h
+ ori r3,r3,CFG_NAND_BOOT_SPL_DST@l
+spl_loop:
+ lwzu r4,4(r2)
+ stwu r4,4(r3)
+ bdnz spl_loop
+
+ /*
+ * Jump to code in RAM
+ */
+ bl 00f
+00: mflr r10
+ lis r3,(CFG_NAND_BOOT_SPL_SRC - CFG_NAND_BOOT_SPL_DST)@h
+ ori r3,r3,(CFG_NAND_BOOT_SPL_SRC - CFG_NAND_BOOT_SPL_DST)@l
+ sub r10,r10,r3
+ addi r10,r10,28
+ mtlr r10
+ blr
+
+start_ram:
+ sync
+ isync
+#endif
+
+ bl 3f
b _start
3: li r0,0
@@ -350,6 +444,7 @@ rsttlb: tlbwe r0,r1,0x0000 /* Invalidate all entries (V=0)*/
* r3 - 1st arg to board_init(): IMMP pointer
* r4 - 2nd arg to board_init(): boot flag
*/
+#ifndef CONFIG_NAND_SPL
.text
.long 0x27051956 /* U-Boot Magic Number */
.globl version_string
@@ -363,6 +458,7 @@ version_string:
* location (0x100) is where the CriticalInput Execption should be.
*/
. = EXC_OFF_SYS_RESET
+#endif
.globl _start
_start:
@@ -401,7 +497,8 @@ _start:
/* Setup the internal SRAM */
/*----------------------------------------------------------------*/
li r0,0
-#if defined(CONFIG_440EP) || defined(CONFIG_440GR)
+
+#ifdef CFG_INIT_RAM_DCACHE
/* Clear Dcache to use as RAM */
addis r3,r0,CFG_INIT_RAM_ADDR@h
ori r3,r3,CFG_INIT_RAM_ADDR@l
@@ -417,19 +514,22 @@ _start:
dcbz r0,r3
addi r3,r3,32
bdnz ..d_ag
-#else
-#if defined (CONFIG_440GX) || defined(CONFIG_440SP) || defined(CONFIG_440SPE)
+#endif /* CFG_INIT_RAM_DCACHE */
+
+ /* 440EP & 440GR are only 440er PPC's without internal SRAM */
+#if !defined(CONFIG_440EP) && !defined(CONFIG_440GR)
+ /* not all PPC's have internal SRAM usable as L2-cache */
+#if defined(CONFIG_440GX) || defined(CONFIG_440SP) || defined(CONFIG_440SPE)
mtdcr l2_cache_cfg,r0 /* Ensure L2 Cache is off */
#endif
- mtdcr isram0_sb1cr,r0 /* Disable bank 1 */
- li r2,0x7fff
+ lis r2,0x7fff
ori r2,r2,0xffff
mfdcr r1,isram0_dpc
and r1,r1,r2 /* Disable parity check */
mtdcr isram0_dpc,r1
mfdcr r1,isram0_pmeg
- andis. r1,r1,r2 /* Disable pwr mgmt */
+ and r1,r1,r2 /* Disable pwr mgmt */
mtdcr isram0_pmeg,r1
lis r1,0x8000 /* BAS = 8000_0000 */
@@ -458,11 +558,12 @@ _start:
lis r1, 0x0003
ori r1,r1, 0x0984 /* fourth 64k */
mtdcr isram0_sb3cr,r1
-#else
+#elif defined(CONFIG_440GP)
ori r1,r1,0x0380 /* 8k rw */
mtdcr isram0_sb0cr,r1
+ mtdcr isram0_sb1cr,r0 /* Disable bank 1 */
#endif
-#endif
+#endif /* #if !defined(CONFIG_440EP) && !defined(CONFIG_440GR) */
/*----------------------------------------------------------------*/
/* Setup the stack in internal SRAM */
@@ -479,10 +580,14 @@ _start:
stwu r1,-8(r1) /* Save back chain and move SP */
stw r0,+12(r1) /* Save return addr (underflow vect) */
+#ifdef CONFIG_NAND_SPL
+ bl nand_boot /* will not return */
+#else
GET_GOT
bl cpu_init_f /* run low-level CPU init code (from Flash) */
bl board_init_f
+#endif
#endif /* CONFIG_440 */
@@ -792,6 +897,7 @@ _start:
/*----------------------------------------------------------------------- */
+#ifndef CONFIG_NAND_SPL
/*****************************************************************************/
.globl _start_of_vectors
_start_of_vectors:
@@ -997,6 +1103,7 @@ crit_return:
lwz r1,GPR1(r1)
SYNC
rfci
+#endif /* CONFIG_NAND_SPL */
/* Cache functions.
*/
@@ -1238,6 +1345,7 @@ ppcSync:
/*------------------------------------------------------------------------------*/
+#ifndef CONFIG_NAND_SPL
/*
* void relocate_code (addr_sp, gd, addr_moni)
*
@@ -1251,7 +1359,9 @@ ppcSync:
*/
.globl relocate_code
relocate_code:
-#if defined(CONFIG_440EP) || defined(CONFIG_440GR) || defined(CONFIG_440SPE)
+#if defined(CONFIG_440EP) || defined(CONFIG_440GR) || \
+ defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \
+ defined(CONFIG_440SPE)
/*
* On some 440er platforms the cache is enabled in the first TLB (Boot-CS)
* to speed up the boot process. Now this cache needs to be disabled.
@@ -1466,22 +1576,22 @@ trap_init:
cmplw 0, r7, r8
blt 4b
-#if !defined(CONFIG_440GX) && !defined(CONFIG_440SPE)
+#if !defined(CONFIG_440)
addi r7,r0,0x1000 /* set ME bit (Machine Exceptions) */
oris r7,r7,0x0002 /* set CE bit (Critical Exceptions) */
mtmsr r7 /* change MSR */
#else
- bl __440gx_msr_set
- b __440gx_msr_continue
+ bl __440_msr_set
+ b __440_msr_continue
-__440gx_msr_set:
+__440_msr_set:
addi r7,r0,0x1000 /* set ME bit (Machine Exceptions) */
oris r7,r7,0x0002 /* set CE bit (Critical Exceptions) */
mtspr srr1,r7
mflr r7
mtspr srr0,r7
rfi
-__440gx_msr_continue:
+__440_msr_continue:
#endif
mtlr r4 /* restore link register */
@@ -1500,6 +1610,7 @@ trap_reloc:
stw r0, 4(r7)
blr
+#endif /* CONFIG_NAND_SPL */
/**************************************************************************/
@@ -1587,7 +1698,8 @@ ppc405ep_init:
mtdcr ebccfgd,r3
#endif
- addi r3,0,CPC0_PCI_HOST_CFG_EN
+#ifndef CFG_CPC0_PCI
+ li r3,CPC0_PCI_HOST_CFG_EN
#ifdef CONFIG_BUBINGA
/*
!-----------------------------------------------------------------------
@@ -1602,6 +1714,9 @@ ppc405ep_init:
beq ..pci_cfg_set /* if not set, then bypass reg write*/
#endif
ori r3,r3,CPC0_PCI_ARBIT_EN
+#else /* CFG_CPC0_PCI */
+ li r3,CFG_CPC0_PCI
+#endif /* CFG_CPC0_PCI */
..pci_cfg_set:
mtdcr CPC0_PCI, r3 /* Enable internal arbiter*/
diff --git a/cpu/ppc4xx/usb_ohci.c b/cpu/ppc4xx/usb_ohci.c
index bb57658..ab852c5 100644
--- a/cpu/ppc4xx/usb_ohci.c
+++ b/cpu/ppc4xx/usb_ohci.c
@@ -76,7 +76,7 @@
#define m16_swap(x) swap_16(x)
#define m32_swap(x) swap_32(x)
-#ifdef CONFIG_440EP
+#if defined(CONFIG_440EP) || defined(CONFIG_440EPX)
#define ohci_cpu_to_le16(x) (x)
#define ohci_cpu_to_le32(x) (x)
#else
@@ -1599,7 +1599,11 @@ int usb_lowlevel_init(void)
gohci.disabled = 1;
gohci.sleeping = 0;
gohci.irq = -1;
- gohci.regs = (struct ohci_regs *)(CFG_PERIPHERAL_BASE | 0x1000);
+#if defined(CONFIG_440EP)
+ gohci.regs = (struct ohci_regs *)(CFG_PERIPHERAL_BASE | 0x1000);
+#elif defined(CONFIG_440EPX)
+ gohci.regs = (struct ohci_regs *)(CFG_USB_HOST);
+#endif
gohci.flags = 0;
gohci.slot_name = "ppc440";
diff --git a/cpu/ppc4xx/usbdev.c b/cpu/ppc4xx/usbdev.c
index 8262c54..6140d2a 100644
--- a/cpu/ppc4xx/usbdev.c
+++ b/cpu/ppc4xx/usbdev.c
@@ -3,7 +3,7 @@
#include <common.h>
#include <asm/processor.h>
-#ifdef CONFIG_440EP
+#if (defined(CONFIG_440EP) || defined(CONFIG_440EPX)) && (CONFIG_COMMANDS & CFG_CMD_USB)
#include <usb.h>
#include "usbdev.h"
@@ -186,6 +186,21 @@ int usbInt(void)
return 0;
}
+#if defined(CONFIG_440EPX)
+void usb_dev_init()
+{
+ printf("USB 2.0 Device init\n");
+
+ /*usb dev init */
+ *(unsigned char *)USB2D0_POWER_8 = 0xa1; /* 2.0 */
+
+ /*enable interrupts */
+ *(unsigned char *)USB2D0_INTRUSBE_8 = 0x0f;
+
+ irq_install_handler(VECNUM_HSB2D, (interrupt_handler_t *) usbInt,
+ NULL);
+}
+#else
void usb_dev_init()
{
#ifdef USB_2_0_DEVICE
@@ -210,5 +225,6 @@ void usb_dev_init()
irq_install_handler(VECNUM_USBDEV, (interrupt_handler_t *) usbInt,
NULL);
}
+#endif
-#endif /*CONFIG_440EP */
+#endif /* CONFIG_440EP || CONFIG_440EPX */
diff --git a/cpu/ppc4xx/vecnum.h b/cpu/ppc4xx/vecnum.h
index 93cef02..685d48b 100644
--- a/cpu/ppc4xx/vecnum.h
+++ b/cpu/ppc4xx/vecnum.h
@@ -31,7 +31,94 @@
#ifndef _VECNUMS_H_
#define _VECNUMS_H_
-#if defined(CONFIG_440SPE)
+#if defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
+
+/* UIC 0 */
+#define VECNUM_U0 0 /* UART 0 */
+#define VECNUM_U1 1 /* UART 1 */
+#define VECNUM_IIC0 2 /* IIC */
+#define VECNUM_KRD 3 /* Kasumi Ready for data */
+#define VECNUM_KDA 4 /* Kasumi Data Available */
+#define VECNUM_PCRW 5 /* PCI command register write */
+#define VECNUM_PPM 6 /* PCI power management */
+#define VECNUM_IIC1 7 /* IIC */
+#define VECNUM_SPI 8 /* SPI */
+#define VECNUM_EPCISER 9 /* External PCI SERR */
+#define VECNUM_MTE 10 /* MAL TXEOB */
+#define VECNUM_MRE 11 /* MAL RXEOB */
+#define VECNUM_D0 12 /* DMA channel 0 */
+#define VECNUM_D1 13 /* DMA channel 1 */
+#define VECNUM_D2 14 /* DMA channel 2 */
+#define VECNUM_D3 15 /* DMA channel 3 */
+#define VECNUM_UD0 16 /* UDMA irq 0 */
+#define VECNUM_UD1 17 /* UDMA irq 1 */
+#define VECNUM_UD2 18 /* UDMA irq 2 */
+#define VECNUM_UD3 19 /* UDMA irq 3 */
+#define VECNUM_HSB2D 20 /* USB2.0 Device */
+#define VECNUM_USBDEV 20 /* USB 1.1/USB 2.0 Device */
+#define VECNUM_OHCI1 21 /* USB2.0 Host OHCI irq 1 */
+#define VECNUM_OHCI2 22 /* USB2.0 Host OHCI irq 2 */
+#define VECNUM_EIP94 23 /* Security EIP94 */
+#define VECNUM_ETH0 24 /* Emac 0 */
+#define VECNUM_ETH1 25 /* Emac 1 */
+#define VECNUM_EHCI 26 /* USB2.0 Host EHCI */
+#define VECNUM_EIR4 27 /* External interrupt 4 */
+#define VECNUM_UIC2NC 28 /* UIC2 non-critical interrupt */
+#define VECNUM_UIC2C 29 /* UIC2 critical interrupt */
+#define VECNUM_UIC1NC 30 /* UIC1 non-critical interrupt */
+#define VECNUM_UIC1C 31 /* UIC1 critical interrupt */
+
+/* UIC 1 */
+#define VECNUM_MS (32 + 0) /* MAL SERR */
+#define VECNUM_MTDE (32 + 1) /* MAL TXDE */
+#define VECNUM_MRDE (32 + 2) /* MAL RXDE */
+#define VECNUM_U2 (32 + 3) /* UART 2 */
+#define VECNUM_U3 (32 + 4) /* UART 3 */
+#define VECNUM_EBCO (32 + 5) /* EBCO interrupt status */
+#define VECNUM_NDFC (32 + 6) /* NDFC */
+#define VECNUM_KSLE (32 + 7) /* KASUMI slave error */
+#define VECNUM_CT5 (32 + 8) /* GPT compare timer 5 */
+#define VECNUM_CT6 (32 + 9) /* GPT compare timer 6 */
+#define VECNUM_PLB34I0 (32 + 10) /* PLB3X4X MIRQ0 */
+#define VECNUM_PLB34I1 (32 + 11) /* PLB3X4X MIRQ1 */
+#define VECNUM_PLB34I2 (32 + 12) /* PLB3X4X MIRQ2 */
+#define VECNUM_PLB34I3 (32 + 13) /* PLB3X4X MIRQ3 */
+#define VECNUM_PLB34I4 (32 + 14) /* PLB3X4X MIRQ4 */
+#define VECNUM_PLB34I5 (32 + 15) /* PLB3X4X MIRQ5 */
+#define VECNUM_CT0 (32 + 16) /* GPT compare timer 0 */
+#define VECNUM_CT1 (32 + 17) /* GPT compare timer 1 */
+#define VECNUM_EIR7 (32 + 18) /* External interrupt 7 */
+#define VECNUM_EIR8 (32 + 19) /* External interrupt 8 */
+#define VECNUM_EIR9 (32 + 20) /* External interrupt 9 */
+#define VECNUM_CT2 (32 + 21) /* GPT compare timer 2 */
+#define VECNUM_CT3 (32 + 22) /* GPT compare timer 3 */
+#define VECNUM_CT4 (32 + 23) /* GPT compare timer 4 */
+#define VECNUM_SRE (32 + 24) /* Serial ROM error */
+#define VECNUM_GPTDC (32 + 25) /* GPT decrementer pulse */
+#define VECNUM_RSVD0 (32 + 26) /* Reserved */
+#define VECNUM_EPCIPER (32 + 27) /* External PCI PERR */
+#define VECNUM_EIR0 (32 + 28) /* External interrupt 0 */
+#define VECNUM_EWU0 (32 + 29) /* Ethernet 0 wakeup */
+#define VECNUM_EIR1 (32 + 30) /* External interrupt 1 */
+#define VECNUM_EWU1 (32 + 31) /* Ethernet 1 wakeup */
+
+#define VECNUM_TXDE VECNUM_MTDE
+#define VECNUM_RXDE VECNUM_MRDE
+
+/* UIC 2 */
+#define VECNUM_EIR5 (62 + 0) /* External interrupt 5 */
+#define VECNUM_EIR6 (62 + 1) /* External interrupt 6 */
+#define VECNUM_OPB (62 + 2) /* OPB to PLB bridge int stat */
+#define VECNUM_EIR2 (62 + 3) /* External interrupt 2 */
+#define VECNUM_EIR3 (62 + 4) /* External interrupt 3 */
+#define VECNUM_DDR2 (62 + 5) /* DDR2 sdram */
+#define VECNUM_MCTX0 (62 + 6) /* MAl intp coalescence TX0 */
+#define VECNUM_MCTX1 (62 + 7) /* MAl intp coalescence TX1 */
+#define VECNUM_MCTR0 (62 + 8) /* MAl intp coalescence TR0 */
+#define VECNUM_MCTR1 (62 + 9) /* MAl intp coalescence TR1 */
+
+#elif defined(CONFIG_440SPE)
+
/* UIC 0 */
#define VECNUM_U0 0 /* UART0 */
#define VECNUM_U1 1 /* UART1 */
diff --git a/cpu/pxa/Makefile b/cpu/pxa/Makefile
index bd476f1..8b4367e 100644
--- a/cpu/pxa/Makefile
+++ b/cpu/pxa/Makefile
@@ -1,5 +1,5 @@
#
-# (C) Copyright 2000, 2002
+# (C) Copyright 2000-2006
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
#
# See file CREDITS for list of people who contributed to this
@@ -23,21 +23,25 @@
include $(TOPDIR)/config.mk
-LIB = lib$(CPU).a
+LIB = $(obj)lib$(CPU).a
START = start.o
-OBJS = serial.o interrupts.o cpu.o i2c.o pxafb.o mmc.o usb.o
+COBJS = serial.o interrupts.o cpu.o i2c.o pxafb.o mmc.o usb.o
-all: .depend $(START) $(LIB)
+SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
+START := $(addprefix $(obj),$(START))
+
+all: $(obj).depend $(START) $(LIB)
$(LIB): $(OBJS)
- $(AR) crv $@ $(OBJS)
+ $(AR) $(ARFLAGS) $@ $(OBJS)
#########################################################################
-.depend: Makefile $(START:.o=.S) $(OBJS:.o=.c)
- $(CC) -M $(CFLAGS) $(START:.o=.S) $(OBJS:.o=.c) > $@
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
-sinclude .depend
+sinclude $(obj).depend
#########################################################################
diff --git a/cpu/s3c44b0/Makefile b/cpu/s3c44b0/Makefile
index d43c73e..790faeb 100644
--- a/cpu/s3c44b0/Makefile
+++ b/cpu/s3c44b0/Makefile
@@ -1,5 +1,5 @@
#
-# (C) Copyright 2000-2004
+# (C) Copyright 2000-2006
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
#
# See file CREDITS for list of people who contributed to this
@@ -23,21 +23,25 @@
include $(TOPDIR)/config.mk
-LIB = lib$(CPU).a
+LIB = $(obj)lib$(CPU).a
START = start.o
-OBJS = serial.o interrupts.o cpu.o
+COBJS = serial.o interrupts.o cpu.o
-all: .depend $(START) $(LIB)
+SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
+START := $(addprefix $(obj),$(START))
+
+all: $(obj).depend $(START) $(LIB)
$(LIB): $(OBJS)
- $(AR) crv $@ $(OBJS)
+ $(AR) $(ARFLAGS) $@ $(OBJS)
#########################################################################
-.depend: Makefile $(START:.o=.S) $(OBJS:.o=.c)
- $(CC) -M $(CFLAGS) $(START:.o=.S) $(OBJS:.o=.c) > $@
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
-sinclude .depend
+sinclude $(obj).depend
#########################################################################
diff --git a/cpu/sa1100/Makefile b/cpu/sa1100/Makefile
index 8c950da..790faeb 100644
--- a/cpu/sa1100/Makefile
+++ b/cpu/sa1100/Makefile
@@ -1,5 +1,5 @@
#
-# (C) Copyright 2000
+# (C) Copyright 2000-2006
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
#
# See file CREDITS for list of people who contributed to this
@@ -23,21 +23,25 @@
include $(TOPDIR)/config.mk
-LIB = lib$(CPU).a
+LIB = $(obj)lib$(CPU).a
START = start.o
-OBJS = serial.o interrupts.o cpu.o
+COBJS = serial.o interrupts.o cpu.o
-all: .depend $(START) $(LIB)
+SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
+START := $(addprefix $(obj),$(START))
+
+all: $(obj).depend $(START) $(LIB)
$(LIB): $(OBJS)
- $(AR) crv $@ $(OBJS)
+ $(AR) $(ARFLAGS) $@ $(OBJS)
#########################################################################
-.depend: Makefile $(START:.o=.S) $(OBJS:.o=.c)
- $(CC) -M $(CFLAGS) $(START:.o=.S) $(OBJS:.o=.c) > $@
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
-sinclude .depend
+sinclude $(obj).depend
#########################################################################