summaryrefslogtreecommitdiffstats
path: root/cpu
diff options
context:
space:
mode:
authorKumar Gala <galak@kernel.crashing.org>2006-03-20 10:42:05 -0600
committerKumar Gala <galak@kernel.crashing.org>2006-03-20 10:42:05 -0600
commitf8edca2e9a128f526b1fe6f997f7adb852cf5b3c (patch)
tree92deb9ddf1153c64ff1ced9392816e60b4ecaa03 /cpu
parent79582020313e6d992a3bac71cf3a9b337f9ac7f7 (diff)
parent7b4fd36b0322ec98836a8459d9be80e2777fdc05 (diff)
downloadu-boot-f8edca2e9a128f526b1fe6f997f7adb852cf5b3c.tar.gz
u-boot-f8edca2e9a128f526b1fe6f997f7adb852cf5b3c.tar.xz
u-boot-f8edca2e9a128f526b1fe6f997f7adb852cf5b3c.zip
Merge branch 'origin'
Conflicts: CHANGELOG
Diffstat (limited to 'cpu')
-rw-r--r--cpu/arm920t/at91rm9200/i2c.c4
-rw-r--r--cpu/arm920t/s3c24x0/usb_ohci.c3
-rw-r--r--cpu/arm926ejs/interrupts.c148
-rw-r--r--cpu/arm926ejs/omap/Makefile43
-rw-r--r--cpu/arm926ejs/omap/reset.S45
-rw-r--r--cpu/arm926ejs/omap/timer.c177
-rw-r--r--cpu/arm926ejs/start.S22
-rw-r--r--cpu/arm926ejs/versatile/Makefile43
-rw-r--r--cpu/arm926ejs/versatile/reset.S45
-rw-r--r--cpu/arm926ejs/versatile/timer.c175
-rw-r--r--cpu/bf533/Makefile46
-rw-r--r--cpu/bf533/bf533_serial.h78
-rw-r--r--cpu/bf533/cache.S125
-rw-r--r--cpu/bf533/config.mk27
-rw-r--r--cpu/bf533/cplbhdlr.S193
-rw-r--r--cpu/bf533/cplbmgr.S601
-rw-r--r--cpu/bf533/cpu.c189
-rw-r--r--cpu/bf533/cpu.h65
-rw-r--r--cpu/bf533/flush.S402
-rw-r--r--cpu/bf533/interrupt.S391
-rw-r--r--cpu/bf533/interrupts.c165
-rw-r--r--cpu/bf533/ints.c107
-rw-r--r--cpu/bf533/serial.c194
-rw-r--r--cpu/bf533/start.S435
-rw-r--r--cpu/bf533/start1.S38
-rw-r--r--cpu/bf533/traps.c73
-rw-r--r--cpu/mips/au1x00_eth.c8
-rw-r--r--cpu/mpc5xxx/fec.c3
-rw-r--r--cpu/mpc8260/speed.c27
-rw-r--r--cpu/mpc83xx/cpu.c87
-rw-r--r--cpu/mpc83xx/spd_sdram.c189
-rw-r--r--cpu/mpc83xx/start.S38
-rw-r--r--cpu/mpc85xx/start.S4
-rw-r--r--cpu/mpc8xx/cpu.c11
-rw-r--r--cpu/ppc4xx/405gp_pci.c2
-rw-r--r--cpu/ppc4xx/start.S41
-rw-r--r--cpu/pxa/cpu.c2
-rw-r--r--cpu/pxa/serial.c12
-rw-r--r--cpu/pxa/start.S106
39 files changed, 4082 insertions, 282 deletions
diff --git a/cpu/arm920t/at91rm9200/i2c.c b/cpu/arm920t/at91rm9200/i2c.c
index 2565998e48..826cea8e26 100644
--- a/cpu/arm920t/at91rm9200/i2c.c
+++ b/cpu/arm920t/at91rm9200/i2c.c
@@ -111,7 +111,7 @@ at91_xfer(unsigned char chip, unsigned int addr, int alen,
int
i2c_probe(unsigned char chip)
{
- char buffer[1];
+ unsigned char buffer[1];
return at91_xfer(chip, 0, 0, buffer, 1, 1);
}
@@ -191,7 +191,7 @@ i2c_init(int speed, int slaveaddr)
uchar i2c_reg_read(uchar i2c_addr, uchar reg)
{
- char buf;
+ unsigned char buf;
i2c_read(i2c_addr, reg, 1, &buf, 1);
diff --git a/cpu/arm920t/s3c24x0/usb_ohci.c b/cpu/arm920t/s3c24x0/usb_ohci.c
index b4cc74476b..869ca79d03 100644
--- a/cpu/arm920t/s3c24x0/usb_ohci.c
+++ b/cpu/arm920t/s3c24x0/usb_ohci.c
@@ -1647,7 +1647,8 @@ int usb_lowlevel_init(void)
}
/* FIXME this is a second HC reset; why?? */
- writel (gohci.hc_control = OHCI_USB_RESET, &gohci.regs->control);
+ gohci.hc_control = OHCI_USB_RESET;
+ writel (gohci.hc_control, &gohci.regs->control);
wait_ms (10);
if (hc_start (&gohci) < 0) {
diff --git a/cpu/arm926ejs/interrupts.c b/cpu/arm926ejs/interrupts.c
index 0457bff964..9cac969f64 100644
--- a/cpu/arm926ejs/interrupts.c
+++ b/cpu/arm926ejs/interrupts.c
@@ -39,16 +39,6 @@
#include <arm926ejs.h>
#include <asm/proc-armv/ptrace.h>
-#define TIMER_LOAD_VAL 0xffffffff
-
-/* macro to read the 32 bit timer */
-#ifdef CONFIG_OMAP
-#define READ_TIMER (*(volatile ulong *)(CFG_TIMERBASE+8))
-#endif
-#ifdef CONFIG_VERSATILE
-#define READ_TIMER (*(volatile ulong *)(CFG_TIMERBASE+4))
-#endif
-
#ifdef CONFIG_USE_IRQ
/* enable IRQ interrupts */
void enable_interrupts (void)
@@ -188,146 +178,14 @@ void do_irq (struct pt_regs *pt_regs)
#else
-static ulong timestamp;
-static ulong lastdec;
-
/* nothing really to do with interrupts, just starts up a counter. */
int interrupt_init (void)
{
-#ifdef CONFIG_OMAP
- int32_t val;
-
- /* Start the decrementer ticking down from 0xffffffff */
- *((int32_t *) (CFG_TIMERBASE + LOAD_TIM)) = TIMER_LOAD_VAL;
- val = MPUTIM_ST | MPUTIM_AR | MPUTIM_CLOCK_ENABLE | (CFG_PVT << MPUTIM_PTV_BIT);
- *((int32_t *) (CFG_TIMERBASE + CNTL_TIMER)) = val;
-#endif /* CONFIG_OMAP */
-
-#ifdef CONFIG_VERSATILE
- *(volatile ulong *)(CFG_TIMERBASE + 0) = CFG_TIMER_RELOAD; /* TimerLoad */
- *(volatile ulong *)(CFG_TIMERBASE + 4) = CFG_TIMER_RELOAD; /* TimerValue */
- *(volatile ulong *)(CFG_TIMERBASE + 8) = 0x8C;
-#endif /* CONFIG_VERSATILE */
-
- /* init the timestamp and lastdec value */
- reset_timer_masked();
-
- return (0);
-}
-
-/*
- * timer without interrupts
- */
-
-void reset_timer (void)
-{
- reset_timer_masked ();
-}
+ extern void timer_init(void);
-ulong get_timer (ulong base)
-{
- return get_timer_masked () - base;
-}
+ timer_init();
-void set_timer (ulong t)
-{
- timestamp = t;
-}
-
-/* delay x useconds AND perserve advance timstamp value */
-void udelay (unsigned long usec)
-{
- ulong tmo, tmp;
-
- if(usec >= 1000){ /* if "big" number, spread normalization to seconds */
- tmo = usec / 1000; /* start to normalize for usec to ticks per sec */
- tmo *= CFG_HZ; /* find number of "ticks" to wait to achieve target */
- tmo /= 1000; /* finish normalize. */
- }else{ /* else small number, don't kill it prior to HZ multiply */
- tmo = usec * CFG_HZ;
- tmo /= (1000*1000);
- }
-
- tmp = get_timer (0); /* get current timestamp */
- if( (tmo + tmp + 1) < tmp ) /* if setting this fordward will roll time stamp */
- reset_timer_masked (); /* reset "advancing" timestamp to 0, set lastdec value */
- else
- tmo += tmp; /* else, set advancing stamp wake up time */
-
- while (get_timer_masked () < tmo)/* loop till event */
- /*NOP*/;
-}
-
-void reset_timer_masked (void)
-{
- /* reset time */
- lastdec = READ_TIMER; /* capure current decrementer value time */
- timestamp = 0; /* start "advancing" time stamp from 0 */
-}
-
-ulong get_timer_masked (void)
-{
- ulong now = READ_TIMER; /* current tick value */
-
- if (lastdec >= now) { /* normal mode (non roll) */
- /* normal mode */
- timestamp += lastdec - now; /* move stamp fordward with absoulte diff ticks */
- } else { /* we have overflow of the count down timer */
- /* nts = ts + ld + (TLV - now)
- * ts=old stamp, ld=time that passed before passing through -1
- * (TLV-now) amount of time after passing though -1
- * nts = new "advancing time stamp"...it could also roll and cause problems.
- */
- timestamp += lastdec + TIMER_LOAD_VAL - now;
- }
- lastdec = now;
-
- return timestamp;
-}
-
-/* waits specified delay value and resets timestamp */
-void udelay_masked (unsigned long usec)
-{
- ulong tmo;
- ulong endtime;
- signed long diff;
-
- if (usec >= 1000) { /* if "big" number, spread normalization to seconds */
- tmo = usec / 1000; /* start to normalize for usec to ticks per sec */
- tmo *= CFG_HZ; /* find number of "ticks" to wait to achieve target */
- tmo /= 1000; /* finish normalize. */
- } else { /* else small number, don't kill it prior to HZ multiply */
- tmo = usec * CFG_HZ;
- tmo /= (1000*1000);
- }
-
- endtime = get_timer_masked () + tmo;
-
- do {
- ulong now = get_timer_masked ();
- diff = endtime - now;
- } while (diff >= 0);
-}
-
-/*
- * This function is derived from PowerPC code (read timebase as long long).
- * On ARM it just returns the timer value.
- */
-unsigned long long get_ticks(void)
-{
- return get_timer(0);
-}
-
-/*
- * This function is derived from PowerPC code (timebase clock frequency).
- * On ARM it returns the number of timer ticks per second.
- */
-ulong get_tbclk (void)
-{
- ulong tbclk;
-
- tbclk = CFG_HZ;
- return tbclk;
+ return 0;
}
#endif /* CONFIG_INTEGRATOR */
diff --git a/cpu/arm926ejs/omap/Makefile b/cpu/arm926ejs/omap/Makefile
new file mode 100644
index 0000000000..f9d3378197
--- /dev/null
+++ b/cpu/arm926ejs/omap/Makefile
@@ -0,0 +1,43 @@
+#
+# (C) Copyright 2000-2005
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+include $(TOPDIR)/config.mk
+
+LIB = lib$(SOC).a
+
+OBJS = timer.o
+SOBJS = reset.o
+
+all: .depend $(LIB)
+
+$(LIB): $(OBJS) $(SOBJS)
+ $(AR) crv $@ $(OBJS) $(SOBJS)
+
+#########################################################################
+
+.depend: Makefile $(OBJS:.o=.c)
+ $(CC) -M $(CFLAGS) $(OBJS:.o=.c) > $@
+
+sinclude .depend
+
+#########################################################################
diff --git a/cpu/arm926ejs/omap/reset.S b/cpu/arm926ejs/omap/reset.S
new file mode 100644
index 0000000000..e8989028e2
--- /dev/null
+++ b/cpu/arm926ejs/omap/reset.S
@@ -0,0 +1,45 @@
+/*
+ * armboot - Startup Code for ARM926EJS CPU-core
+ *
+ * Copyright (c) 2003 Texas Instruments
+ *
+ * ----- Adapted for OMAP1610 OMAP730 from ARM925t code ------
+ *
+ * Copyright (c) 2001 Marius Gröger <mag@sysgo.de>
+ * Copyright (c) 2002 Alex Züpke <azu@sysgo.de>
+ * Copyright (c) 2002 Gary Jennejohn <gj@denx.de>
+ * Copyright (c) 2003 Richard Woodruff <r-woodruff2@ti.com>
+ * Copyright (c) 2003 Kshitij <kshitij@ti.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
+ */
+
+ .align 5
+.globl reset_cpu
+reset_cpu:
+ ldr r1, rstctl1 /* get clkm1 reset ctl */
+ mov r3, #0x0
+ strh r3, [r1] /* clear it */
+ mov r3, #0x8
+ strh r3, [r1] /* force dsp+arm reset */
+_loop_forever:
+ b _loop_forever
+
+rstctl1:
+ .word 0xfffece10
diff --git a/cpu/arm926ejs/omap/timer.c b/cpu/arm926ejs/omap/timer.c
new file mode 100644
index 0000000000..a2a9133ee0
--- /dev/null
+++ b/cpu/arm926ejs/omap/timer.c
@@ -0,0 +1,177 @@
+/*
+ * (C) Copyright 2003
+ * Texas Instruments <www.ti.com>
+ *
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Marius Groeger <mgroeger@sysgo.de>
+ *
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Alex Zuepke <azu@sysgo.de>
+ *
+ * (C) Copyright 2002-2004
+ * Gary Jennejohn, DENX Software Engineering, <gj@denx.de>
+ *
+ * (C) Copyright 2004
+ * Philippe Robin, ARM Ltd. <philippe.robin@arm.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 <arm926ejs.h>
+
+#define TIMER_LOAD_VAL 0xffffffff
+
+/* macro to read the 32 bit timer */
+#define READ_TIMER (*(volatile ulong *)(CFG_TIMERBASE+8))
+
+static ulong timestamp;
+static ulong lastdec;
+
+int timer_init (void)
+{
+ int32_t val;
+
+ /* Start the decrementer ticking down from 0xffffffff */
+ *((int32_t *) (CFG_TIMERBASE + LOAD_TIM)) = TIMER_LOAD_VAL;
+ val = MPUTIM_ST | MPUTIM_AR | MPUTIM_CLOCK_ENABLE | (CFG_PVT << MPUTIM_PTV_BIT);
+ *((int32_t *) (CFG_TIMERBASE + CNTL_TIMER)) = val;
+
+ /* init the timestamp and lastdec value */
+ reset_timer_masked();
+
+ return 0;
+}
+
+/*
+ * timer without interrupts
+ */
+
+void reset_timer (void)
+{
+ reset_timer_masked ();
+}
+
+ulong get_timer (ulong base)
+{
+ return get_timer_masked () - base;
+}
+
+void set_timer (ulong t)
+{
+ timestamp = t;
+}
+
+/* delay x useconds AND perserve advance timstamp value */
+void udelay (unsigned long usec)
+{
+ ulong tmo, tmp;
+
+ if(usec >= 1000){ /* if "big" number, spread normalization to seconds */
+ tmo = usec / 1000; /* start to normalize for usec to ticks per sec */
+ tmo *= CFG_HZ; /* find number of "ticks" to wait to achieve target */
+ tmo /= 1000; /* finish normalize. */
+ }else{ /* else small number, don't kill it prior to HZ multiply */
+ tmo = usec * CFG_HZ;
+ tmo /= (1000*1000);
+ }
+
+ tmp = get_timer (0); /* get current timestamp */
+ if( (tmo + tmp + 1) < tmp ) /* if setting this fordward will roll time stamp */
+ reset_timer_masked (); /* reset "advancing" timestamp to 0, set lastdec value */
+ else
+ tmo += tmp; /* else, set advancing stamp wake up time */
+
+ while (get_timer_masked () < tmo)/* loop till event */
+ /*NOP*/;
+}
+
+void reset_timer_masked (void)
+{
+ /* reset time */
+ lastdec = READ_TIMER; /* capure current decrementer value time */
+ timestamp = 0; /* start "advancing" time stamp from 0 */
+}
+
+ulong get_timer_masked (void)
+{
+ ulong now = READ_TIMER; /* current tick value */
+
+ if (lastdec >= now) { /* normal mode (non roll) */
+ /* normal mode */
+ timestamp += lastdec - now; /* move stamp fordward with absoulte diff ticks */
+ } else { /* we have overflow of the count down timer */
+ /* nts = ts + ld + (TLV - now)
+ * ts=old stamp, ld=time that passed before passing through -1
+ * (TLV-now) amount of time after passing though -1
+ * nts = new "advancing time stamp"...it could also roll and cause problems.
+ */
+ timestamp += lastdec + TIMER_LOAD_VAL - now;
+ }
+ lastdec = now;
+
+ return timestamp;
+}
+
+/* waits specified delay value and resets timestamp */
+void udelay_masked (unsigned long usec)
+{
+ ulong tmo;
+ ulong endtime;
+ signed long diff;
+
+ if (usec >= 1000) { /* if "big" number, spread normalization to seconds */
+ tmo = usec / 1000; /* start to normalize for usec to ticks per sec */
+ tmo *= CFG_HZ; /* find number of "ticks" to wait to achieve target */
+ tmo /= 1000; /* finish normalize. */
+ } else { /* else small number, don't kill it prior to HZ multiply */
+ tmo = usec * CFG_HZ;
+ tmo /= (1000*1000);
+ }
+
+ endtime = get_timer_masked () + tmo;
+
+ do {
+ ulong now = get_timer_masked ();
+ diff = endtime - now;
+ } while (diff >= 0);
+}
+
+/*
+ * This function is derived from PowerPC code (read timebase as long long).
+ * On ARM it just returns the timer value.
+ */
+unsigned long long get_ticks(void)
+{
+ return get_timer(0);
+}
+
+/*
+ * This function is derived from PowerPC code (timebase clock frequency).
+ * On ARM it returns the number of timer ticks per second.
+ */
+ulong get_tbclk (void)
+{
+ ulong tbclk;
+
+ tbclk = CFG_HZ;
+ return tbclk;
+}
diff --git a/cpu/arm926ejs/start.S b/cpu/arm926ejs/start.S
index fc6b20b21e..725c6639a1 100644
--- a/cpu/arm926ejs/start.S
+++ b/cpu/arm926ejs/start.S
@@ -392,25 +392,3 @@ fiq:
bl do_fiq
#endif
-
-# ifdef CONFIG_INTEGRATOR
-
- /* Satisfied by Integrator routine (AP or CP) */
-
-#else
-
- .align 5
-.globl reset_cpu
-reset_cpu:
- ldr r1, rstctl1 /* get clkm1 reset ctl */
- mov r3, #0x0
- strh r3, [r1] /* clear it */
- mov r3, #0x8
- strh r3, [r1] /* force dsp+arm reset */
-_loop_forever:
- b _loop_forever
-
-rstctl1:
- .word 0xfffece10
-
-#endif /* #ifdef CONFIG_INTEGRATOR */
diff --git a/cpu/arm926ejs/versatile/Makefile b/cpu/arm926ejs/versatile/Makefile
new file mode 100644
index 0000000000..f9d3378197
--- /dev/null
+++ b/cpu/arm926ejs/versatile/Makefile
@@ -0,0 +1,43 @@
+#
+# (C) Copyright 2000-2005
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+include $(TOPDIR)/config.mk
+
+LIB = lib$(SOC).a
+
+OBJS = timer.o
+SOBJS = reset.o
+
+all: .depend $(LIB)
+
+$(LIB): $(OBJS) $(SOBJS)
+ $(AR) crv $@ $(OBJS) $(SOBJS)
+
+#########################################################################
+
+.depend: Makefile $(OBJS:.o=.c)
+ $(CC) -M $(CFLAGS) $(OBJS:.o=.c) > $@
+
+sinclude .depend
+
+#########################################################################
diff --git a/cpu/arm926ejs/versatile/reset.S b/cpu/arm926ejs/versatile/reset.S
new file mode 100644
index 0000000000..e8989028e2
--- /dev/null
+++ b/cpu/arm926ejs/versatile/reset.S
@@ -0,0 +1,45 @@
+/*
+ * armboot - Startup Code for ARM926EJS CPU-core
+ *
+ * Copyright (c) 2003 Texas Instruments
+ *
+ * ----- Adapted for OMAP1610 OMAP730 from ARM925t code ------
+ *
+ * Copyright (c) 2001 Marius Gröger <mag@sysgo.de>
+ * Copyright (c) 2002 Alex Züpke <azu@sysgo.de>
+ * Copyright (c) 2002 Gary Jennejohn <gj@denx.de>
+ * Copyright (c) 2003 Richard Woodruff <r-woodruff2@ti.com>
+ * Copyright (c) 2003 Kshitij <kshitij@ti.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
+ */
+
+ .align 5
+.globl reset_cpu
+reset_cpu:
+ ldr r1, rstctl1 /* get clkm1 reset ctl */
+ mov r3, #0x0
+ strh r3, [r1] /* clear it */
+ mov r3, #0x8
+ strh r3, [r1] /* force dsp+arm reset */
+_loop_forever:
+ b _loop_forever
+
+rstctl1:
+ .word 0xfffece10
diff --git a/cpu/arm926ejs/versatile/timer.c b/cpu/arm926ejs/versatile/timer.c
new file mode 100644
index 0000000000..32872d2b66
--- /dev/null
+++ b/cpu/arm926ejs/versatile/timer.c
@@ -0,0 +1,175 @@
+/*
+ * (C) Copyright 2003
+ * Texas Instruments <www.ti.com>
+ *
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Marius Groeger <mgroeger@sysgo.de>
+ *
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Alex Zuepke <azu@sysgo.de>
+ *
+ * (C) Copyright 2002-2004
+ * Gary Jennejohn, DENX Software Engineering, <gj@denx.de>
+ *
+ * (C) Copyright 2004
+ * Philippe Robin, ARM Ltd. <philippe.robin@arm.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 <arm926ejs.h>
+
+#define TIMER_LOAD_VAL 0xffffffff
+
+/* macro to read the 32 bit timer */
+#define READ_TIMER (*(volatile ulong *)(CFG_TIMERBASE+4))
+
+static ulong timestamp;
+static ulong lastdec;
+
+/* nothing really to do with interrupts, just starts up a counter. */
+int timer_init (void)
+{
+ *(volatile ulong *)(CFG_TIMERBASE + 0) = CFG_TIMER_RELOAD; /* TimerLoad */
+ *(volatile ulong *)(CFG_TIMERBASE + 4) = CFG_TIMER_RELOAD; /* TimerValue */
+ *(volatile ulong *)(CFG_TIMERBASE + 8) = 0x8C;
+
+ /* init the timestamp and lastdec value */
+ reset_timer_masked();
+
+ return 0;
+}
+
+/*
+ * timer without interrupts
+ */
+
+void reset_timer (void)
+{
+ reset_timer_masked ();
+}
+
+ulong get_timer (ulong base)
+{
+ return get_timer_masked () - base;
+}
+
+void set_timer (ulong t)
+{
+ timestamp = t;
+}
+
+/* delay x useconds AND perserve advance timstamp value */
+void udelay (unsigned long usec)
+{
+ ulong tmo, tmp;
+
+ if(usec >= 1000){ /* if "big" number, spread normalization to seconds */
+ tmo = usec / 1000; /* start to normalize for usec to ticks per sec */
+ tmo *= CFG_HZ; /* find number of "ticks" to wait to achieve target */
+ tmo /= 1000; /* finish normalize. */
+ }else{ /* else small number, don't kill it prior to HZ multiply */
+ tmo = usec * CFG_HZ;
+ tmo /= (1000*1000);
+ }
+
+ tmp = get_timer (0); /* get current timestamp */
+ if( (tmo + tmp + 1) < tmp ) /* if setting this fordward will roll time stamp */
+ reset_timer_masked (); /* reset "advancing" timestamp to 0, set lastdec value */
+ else
+ tmo += tmp; /* else, set advancing stamp wake up time */
+
+ while (get_timer_masked () < tmo)/* loop till event */
+ /*NOP*/;
+}
+
+void reset_timer_masked (void)
+{
+ /* reset time */
+ lastdec = READ_TIMER; /* capure current decrementer value time */
+ timestamp = 0; /* start "advancing" time stamp from 0 */
+}
+
+ulong get_timer_masked (void)
+{
+ ulong now = READ_TIMER; /* current tick value */
+
+ if (lastdec >= now) { /* normal mode (non roll) */
+ /* normal mode */
+ timestamp += lastdec - now; /* move stamp fordward with absoulte diff ticks */
+ } else { /* we have overflow of the count down timer */
+ /* nts = ts + ld + (TLV - now)
+ * ts=old stamp, ld=time that passed before passing through -1
+ * (TLV-now) amount of time after passing though -1
+ * nts = new "advancing time stamp"...it could also roll and cause problems.
+ */
+ timestamp += lastdec + TIMER_LOAD_VAL - now;
+ }
+ lastdec = now;
+
+ return timestamp;
+}
+
+/* waits specified delay value and resets timestamp */
+void udelay_masked (unsigned long usec)
+{
+ ulong tmo;
+ ulong endtime;
+ signed long diff;
+
+ if (usec >= 1000) { /* if "big" number, spread normalization to seconds */
+ tmo = usec / 1000; /* start to normalize for usec to ticks per sec */
+ tmo *= CFG_HZ; /* find number of "ticks" to wait to achieve target */
+ tmo /= 1000; /* finish normalize. */
+ } else { /* else small number, don't kill it prior to HZ multiply */
+ tmo = usec * CFG_HZ;
+ tmo /= (1000*1000);
+ }
+
+ endtime = get_timer_masked () + tmo;
+
+ do {
+ ulong now = get_timer_masked ();
+ diff = endtime - now;
+ } while (diff >= 0);
+}
+
+/*
+ * This function is derived from PowerPC code (read timebase as long long).
+ * On ARM it just returns the timer value.
+ */
+unsigned long long get_ticks(void)
+{
+ return get_timer(0);
+}
+
+/*
+ * This function is derived from PowerPC code (timebase clock frequency).
+ * On ARM it returns the number of timer ticks per second.
+ */
+ulong get_tbclk (void)
+{
+ ulong tbclk;
+
+ tbclk = CFG_HZ;
+ return tbclk;
+}
diff --git a/cpu/bf533/Makefile b/cpu/bf533/Makefile
new file mode 100644
index 0000000000..c63a8f6d01
--- /dev/null
+++ b/cpu/bf533/Makefile
@@ -0,0 +1,46 @@
+# U-boot - Makefile
+#
+# Copyright (c) 2005 blackfin.uclinux.org
+#
+# (C) Copyright 2000-2004
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+include $(TOPDIR)/config.mk
+
+LIB = 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
+
+all: .depend $(START) $(LIB)
+
+$(LIB): $(OBJS)
+ $(AR) crv $@ $(OBJS)
+
+#########################################################################
+
+.depend: Makefile $(START:.o=.S) $(OBJS:.o=.c)
+ $(CC) -M $(CFLAGS) $(START:.o=.S) $(OBJS:.o=.c) > $@
+
+sinclude .depend
+
+#########################################################################
diff --git a/cpu/bf533/bf533_serial.h b/cpu/bf533/bf533_serial.h
new file mode 100644
index 0000000000..d430e6cabd
--- /dev/null
+++ b/cpu/bf533/bf533_serial.h
@@ -0,0 +1,78 @@
+/*
+ * U-boot - bf533_serial.h Serial Driver defines
+ *
+ * Copyright (c) 2005 blackfin.uclinux.org
+ *
+ * This file is based on
+ * bf533_serial.h: Definitions for the BlackFin BF533 DSP serial driver.
+ * Copyright (C) 2003 Bas Vermeulen <bas@buyways.nl>
+ * BuyWays B.V. (www.buyways.nl)
+ *
+ * Based heavily on:
+ * blkfinserial.h: Definitions for the BlackFin DSP serial driver.
+ *
+ * Copyright (C) 2001 Tony Z. Kou tonyko@arcturusnetworks.com
+ * Copyright (C) 2001 Arcturus Networks Inc. <www.arcturusnetworks.com>
+ *
+ * Based on code from 68328serial.c which was:
+ * Copyright (C) 1995 David S. Miller <davem@caip.rutgers.edu>
+ * Copyright (C) 1998 Kenneth Albanowski <kjahds@kjahds.com>
+ * Copyright (C) 1998, 1999 D. Jeff Dionne <jeff@uclinux.org>
+ * Copyright (C) 1999 Vladimir Gurevich <vgurevic@cisco.com>
+ *
+ * (C) Copyright 2000-2004
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef _Bf533_SERIAL_H
+#define _Bf533_SERIAL_H
+
+#include <linux/config.h>
+#include <asm/blackfin.h>
+
+#define SYNC_ALL __asm__ __volatile__ ("ssync;\n")
+#define ACCESS_LATCH *pUART_LCR |= UART_LCR_DLAB;
+#define ACCESS_PORT_IER *pUART_LCR &= (~UART_LCR_DLAB);
+
+void serial_setbrg(void);
+static void local_put_char(char ch);
+void calc_baud(void);
+void serial_setbrg(void);
+int serial_init(void);
+void serial_putc(const char c);
+int serial_tstc(void);
+int serial_getc(void);
+void serial_puts(const char *s);
+static void local_put_char(char ch);
+
+extern int get_clock(void);
+int baud_table[5] = {9600, 19200, 38400, 57600, 115200};
+
+struct {
+ unsigned char dl_high;
+ unsigned char dl_low;
+} hw_baud_table[5];
+
+#ifdef CONFIG_STAMP
+extern unsigned long pll_div_fact;
+#endif
+
+#endif
diff --git a/cpu/bf533/cache.S b/cpu/bf533/cache.S
new file mode 100644
index 0000000000..8fac402740
--- /dev/null
+++ b/cpu/bf533/cache.S
@@ -0,0 +1,125 @@
+
+
+#define ASSEMBLY
+#include <asm/linkage.h>
+#include <asm/cpu/def_LPBlackfin.h>
+
+.text
+.align 2
+ENTRY(blackfin_icache_flush_range)
+ R2 = -32;
+ R2 = R0 & R2;
+ P0 = R2;
+ P1 = R1;
+ CSYNC;
+1:
+ IFLUSH[P0++];
+ CC = P0 < P1(iu);
+ IF CC JUMP 1b(bp);
+ IFLUSH[P0];
+ SSYNC;
+ RTS;
+
+ENTRY(blackfin_dcache_flush_range)
+ R2 = -32;
+ R2 = R0 & R2;
+ P0 = R2;
+ P1 = R1;
+ CSYNC;
+1:
+ FLUSH[P0++];
+ CC = P0 < P1(iu);
+ IF CC JUMP 1b(bp);
+ FLUSH[P0];
+ SSYNC;
+ RTS;
+
+ENTRY(_icache_invalidate)
+ENTRY(invalidate_entire_icache)
+ [--SP] = ( R7:5);
+
+ P0.L = (IMEM_CONTROL & 0xFFFF);
+ P0.H = (IMEM_CONTROL >> 16);
+ R7 = [P0];
+
+ /* Clear the IMC bit , All valid bits in the instruction
+ * cache are set to the invalid state
+ */
+ BITCLR(R7,IMC_P);
+ CLI R6;
+ SSYNC; /* SSYNC required before invalidating cache. */
+ .align 8;
+ [P0] = R7;
+ SSYNC;
+ STI R6;
+
+ /* Configures the instruction cache agian */
+ R6 = (IMC | ENICPLB);
+ R7 = R7 | R6;
+
+ CLI R6;
+ SSYNC; /* SSYNC required before writing to IMEM_CONTROL. */
+ .align 8;
+ [P0] = R7;
+ SSYNC;
+ STI R6;
+
+ ( R7:5) = [SP++];
+ RTS;
+
+/* Invalidate the Entire Data cache by
+ * clearing DMC[1:0] bits
+ */
+ENTRY(invalidate_entire_dcache)
+ENTRY(_dcache_invalidate)
+ [--SP] = ( R7:6);
+
+ P0.L = (DMEM_CONTROL & 0xFFFF);
+ P0.H = (DMEM_CONTROL >> 16);
+ R7 = [P0];
+
+ /* Clear the DMC[1:0] bits, All valid bits in the data
+ * cache are set to the invalid state
+ */
+ BITCLR(R7,DMC0_P);
+ BITCLR(R7,DMC1_P);
+ CLI R6;
+ SSYNC; /* SSYNC required before writing to DMEM_CONTROL. */
+ .align 8;
+ [P0] = R7;
+ SSYNC;
+ STI R6;
+
+ /* Configures the data cache again */
+
+ R6 = (ACACHE_BCACHE | ENDCPLB | PORT_PREF0);
+ R7 = R7 | R6;
+
+ CLI R6;
+ SSYNC; /* SSYNC required before writing to DMEM_CONTROL. */
+ .align 8;
+ [P0] = R7;
+ SSYNC;
+ STI R6;
+
+ ( R7:6) = [SP++];
+ RTS;
+
+ENTRY(blackfin_dcache_invalidate_range)
+ R2 = -32;
+ R2 = R0 & R2;
+ P0 = R2;
+ P1 = R1;
+ CSYNC;
+1:
+ FLUSHINV[P0++];
+ CC = P0 < P1 (iu);
+ IF CC JUMP 1b (bp);
+
+ /* If the data crosses a cache line, then we'll be pointing to
+ ** the last cache line, but won't have flushed/invalidated it yet, so do
+ ** one more.
+ */
+ FLUSHINV[P0];
+ SSYNC;
+ RTS;
diff --git a/cpu/bf533/config.mk b/cpu/bf533/config.mk
new file mode 100644
index 0000000000..a9d529ecd8
--- /dev/null
+++ b/cpu/bf533/config.mk
@@ -0,0 +1,27 @@
+# U-boot - config.mk
+#
+# Copyright (c) 2005 blackfin.uclinux.org
+#
+# (C) Copyright 2000-2004
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+PLATFORM_RELFLAGS += -ffixed-P5
diff --git a/cpu/bf533/cplbhdlr.S b/cpu/bf533/cplbhdlr.S
new file mode 100644
index 0000000000..61be5bb90c
--- /dev/null
+++ b/cpu/bf533/cplbhdlr.S
@@ -0,0 +1,193 @@
+/* Copyright (C) 2003 Analog Devices, Inc. All Rights Reserved.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.
+ *
+ * Blackfin BF533/2.6 support : LG Soft India
+ */
+
+
+/* Include an exception handler to invoke the CPLB manager
+ */
+
+#include <asm-blackfin/linkage.h>
+#include <asm/cplb.h>
+#include <asm/entry.h>
+
+
+.text
+
+.globl _cplb_hdr;
+.type _cplb_hdr, STT_FUNC;
+.extern _cplb_mgr;
+.type _cplb_mgr, STT_FUNC;
+.extern __unknown_exception_occurred;
+.type __unknown_exception_occurred, STT_FUNC;
+.extern __cplb_miss_all_locked;
+.type __cplb_miss_all_locked, STT_FUNC;
+.extern __cplb_miss_without_replacement;
+.type __cplb_miss_without_replacement, STT_FUNC;
+.extern __cplb_protection_violation;
+.type __cplb_protection_violation, STT_FUNC;
+.extern panic_pv;
+
+.align 2;
+
+ENTRY(_cplb_hdr)
+ SSYNC;
+ [--SP] = ( R7:0, P5:0 );
+ [--SP] = ASTAT;
+ [--SP] = SEQSTAT;
+ [--SP] = I0;
+ [--SP] = I1;
+ [--SP] = I2;
+ [--SP] = I3;
+ [--SP] = LT0;
+ [--SP] = LB0;
+ [--SP] = LC0;
+ [--SP] = LT1;
+ [--SP] = LB1;
+ [--SP] = LC1;
+ R2 = SEQSTAT;
+
+ /*Mask the contents of SEQSTAT and leave only EXCAUSE in R2*/
+ R2 <<= 26;
+ R2 >>= 26;
+
+ R1 = 0x23; /* Data access CPLB protection violation */
+ CC = R2 == R1;
+ IF !CC JUMP not_data_write;
+ R0 = 2; /* is a write to data space*/
+ JUMP is_icplb_miss;
+
+not_data_write:
+ R1 = 0x2C; /* CPLB miss on an instruction fetch */
+ CC = R2 == R1;
+ R0 = 0; /* is_data_miss == False*/
+ IF CC JUMP is_icplb_miss;
+
+ R1 = 0x26;
+ CC = R2 == R1;
+ IF !CC JUMP unknown;
+
+ R0 = 1; /* is_data_miss == True*/
+
+is_icplb_miss:
+
+#if ( defined (CONFIG_BLKFIN_CACHE) || defined (CONFIG_BLKFIN_DCACHE))
+#if ( defined (CONFIG_BLKFIN_CACHE) && !defined (CONFIG_BLKFIN_DCACHE))
+ R1 = CPLB_ENABLE_ICACHE;
+#endif
+#if ( !defined (CONFIG_BLKFIN_CACHE) && defined (CONFIG_BLKFIN_DCACHE))
+ R1 = CPLB_ENABLE_DCACHE;
+#endif
+#if ( defined (CONFIG_BLKFIN_CACHE) && defined (CONFIG_BLKFIN_DCACHE))
+ R1 = CPLB_ENABLE_DCACHE | CPLB_ENABLE_ICACHE;
+#endif
+#else
+ R1 = 0;
+#endif
+
+ [--SP] = RETS;
+ CALL _cplb_mgr;
+ RETS = [SP++];
+ CC = R0 == 0;
+ IF !CC JUMP not_replaced;
+ LC1 = [SP++];
+ LB1 = [SP++];
+ LT1 = [SP++];
+ LC0 = [SP++];
+ LB0 = [SP++];
+ LT0 = [SP++];
+ I3 = [SP++];
+ I2 = [SP++];
+ I1 = [SP++];
+ I0 = [SP++];
+ SEQSTAT = [SP++];
+ ASTAT = [SP++];
+ ( R7:0, P5:0 ) = [SP++];
+ RTS;
+
+unknown:
+ [--SP] = RETS;
+ CALL __unknown_exception_occurred;
+ RETS = [SP++];
+ JUMP unknown;
+not_replaced:
+ CC = R0 == CPLB_NO_UNLOCKED;
+ IF !CC JUMP next_check;
+ [--SP] = RETS;
+ CALL __cplb_miss_all_locked;
+ RETS = [SP++];
+next_check:
+ CC = R0 == CPLB_NO_ADDR_MATCH;
+ IF !CC JUMP next_check2;
+ [--SP] = RETS;
+ CALL __cplb_miss_without_replacement;
+ RETS = [SP++];
+ JUMP not_replaced;
+next_check2:
+ CC = R0 == CPLB_PROT_VIOL;
+ IF !CC JUMP strange_return_from_cplb_mgr;
+ [--SP] = RETS;
+ CALL __cplb_protection_violation;
+ RETS = [SP++];
+ JUMP not_replaced;
+strange_return_from_cplb_mgr:
+ IDLE;
+ CSYNC;
+ JUMP strange_return_from_cplb_mgr;
+
+/************************************
+ * Diagnostic exception handlers
+ */
+
+__cplb_miss_all_locked:
+ sp += -12;
+ R0 = CPLB_NO_UNLOCKED;
+ call panic_bfin;
+ SP += 12;
+ RTS;
+
+ __cplb_miss_without_replacement:
+ sp += -12;
+ R0 = CPLB_NO_ADDR_MATCH;
+ call panic_bfin;
+ SP += 12;
+ RTS;
+
+__cplb_protection_violation:
+ sp += -12;
+ R0 = CPLB_PROT_VIOL;
+ call panic_bfin;
+ SP += 12;
+ RTS;
+
+__unknown_exception_occurred:
+
+ /* This function is invoked by the default exception
+ * handler, if it does not recognise the kind of
+ * exception that has occurred. In other words, the
+ * default handler only handles some of the system's
+ * exception types, and it does not expect any others
+ * to occur. If your application is going to be using
+ * other kinds of exceptions, you must replace the
+ * default handler with your own, that handles all the
+ * exceptions you will use.
+ *
+ * Since there's nothing we can do, we just loop here
+ * at what we hope is a suitably informative label.
+ */
+
+ IDLE;
+do_not_know_what_to_do:
+ CSYNC;
+ JUMP __unknown_exception_occurred;
+
+ RTS;
+.__unknown_exception_occurred.end:
+.global __unknown_exception_occurred;
+.type __unknown_exception_occurred, STT_FUNC;
+
+panic_bfin:
+ RTS;
diff --git a/cpu/bf533/cplbmgr.S b/cpu/bf533/cplbmgr.S
new file mode 100644
index 0000000000..7a0b048629
--- /dev/null
+++ b/cpu/bf533/cplbmgr.S
@@ -0,0 +1,601 @@
+/*This file is subject to the terms and conditions of the GNU General Public
+ * License.
+ *
+ * Blackfin BF533/2.6 support : LG Soft India
+ * Modification: Dec 07 2004
+ * 1. Correction in icheck_lock. Valid lock entries were
+ * geting victimized, for instruction cplb replacement.
+ * 2. Setup loop's are modified as now toolchain support's P Indexed
+ * addressing
+ * :LG Soft India
+ *
+ */
+
+/* Usage: int _cplb_mgr(is_data_miss,int enable_cache)
+ * is_data_miss==2 => Mark as Dirty, write to the clean data page
+ * is_data_miss==1 => Replace a data CPLB.
+ * is_data_miss==0 => Replace an instruction CPLB.
+ *
+ * Returns:
+ * CPLB_RELOADED => Successfully updated CPLB table.
+ * CPLB_NO_UNLOCKED => All CPLBs are locked, so cannot be evicted.This indicates
+ * that the CPLBs in the configuration tablei are badly
+ * configured, as this should never occur.
+ * CPLB_NO_ADDR_MATCH => The address being accessed, that triggered the exception,
+ * is not covered by any of the CPLBs in the configuration
+ * table. The application isi presumably misbehaving.
+ * CPLB_PROT_VIOL => The address being accessed, that triggered thei exception,
+ * was not a first-write to a clean Write Back Data page,
+ * and so presumably is a genuine violation of the page's
+ * protection attributes. The application is misbehaving.
+ */
+#define ASSEMBLY
+
+#include <asm-blackfin/linkage.h>
+#include <asm-blackfin/blackfin.h>
+#include <asm-blackfin/cplbtab.h>
+#include <asm-blackfin/cplb.h>
+
+.text
+
+.align 2;
+ENTRY(_cplb_mgr)
+
+ [--SP]=( R7:0,P5:0 );
+
+ CC = R0 == 2;
+ IF CC JUMP dcplb_write;
+
+ CC = R0 == 0;
+ IF !CC JUMP dcplb_miss_compare;
+
+ /* ICPLB Miss Exception. We need to choose one of the
+ * currently-installed CPLBs, and replace it with one
+ * from the configuration table.
+ */
+
+ P4.L = (ICPLB_FAULT_ADDR & 0xFFFF);
+ P4.H = (ICPLB_FAULT_ADDR >> 16);
+
+ P1 = 16;
+ P5.L = page_size_table;
+ P5.H = page_size_table;
+
+ P0.L = (ICPLB_DATA0 & 0xFFFF);
+ P0.H = (ICPLB_DATA0 >> 16);
+ R4 = [P4]; /* Get faulting address*/
+ R6 = 64; /* Advance past the fault address, which*/
+ R6 = R6 + R4; /* we'll use if we find a match*/
+ R3 = ((16 << 8) | 2); /* Extract mask, bits 16 and 17.*/
+
+ R5 = 0;
+isearch:
+
+ R1 = [P0-0x100]; /* Address for this CPLB */
+
+ R0 = [P0++]; /* Info for this CPLB*/
+ CC = BITTST(R0,0); /* Is the CPLB valid?*/
+ IF !CC JUMP nomatch; /* Skip it, if not.*/
+ CC = R4 < R1(IU); /* If fault address less than page start*/
+ IF CC JUMP nomatch; /* then skip this one.*/
+ R2 = EXTRACT(R0,R3.L) (Z); /* Get page size*/
+ P1 = R2;
+ P1 = P5 + (P1<<2); /* index into page-size table*/
+ R2 = [P1]; /* Get the page size*/
+ R1 = R1 + R2; /* and add to page start, to get page end*/
+ CC = R4 < R1(IU); /* and see whether fault addr is in page.*/
+ IF !CC R4 = R6; /* If so, advance the address and finish loop.*/
+ IF !CC JUMP isearch_done;
+nomatch:
+ /* Go around again*/
+ R5 += 1;
+ CC = BITTST(R5, 4); /* i.e CC = R5 >= 16*/
+ IF !CC JUMP isearch;
+
+isearch_done:
+ I0 = R4; /* Fault address we'll search for*/
+
+ /* set up pointers */
+ P0.L = (ICPLB_DATA0 & 0xFFFF);
+ P0.H = (ICPLB_DATA0 >> 16);
+
+ /* The replacement procedure for ICPLBs */
+
+ P4.L = (IMEM_CONTROL & 0xFFFF);
+ P4.H = (IMEM_CONTROL >> 16);
+
+ /* disable cplbs */
+ R5 = [P4]; /* Control Register*/
+ BITCLR(R5,ENICPLB_P);
+ CLI R1;
+ SSYNC; /* SSYNC required before writing to IMEM_CONTROL. */
+ .align 8;
+ [P4] = R5;
+ SSYNC;
+ STI R1;
+
+ R1 = -1; /* end point comparison */
+ R3 = 16; /* counter */
+
+ /* Search through CPLBs for first non-locked entry */
+ /* Overwrite it by moving everyone else up by 1 */
+icheck_lock:
+ R0 = [P0++];
+ R3 = R3 + R1;
+ CC = R3 == R1;
+ IF CC JUMP all_locked;
+ CC = BITTST(R0, 0); /* an invalid entry is good */
+ IF !CC JUMP ifound_victim;
+ CC = BITTST(R0,1); /* but a locked entry isn't */
+ IF CC JUMP icheck_lock;
+
+ifound_victim:
+#ifdef CONFIG_CPLB_INFO
+ R7 = [P0 - 0x104];
+ P2.L = ipdt_table;
+ P2.H = ipdt_table;
+ P3.L = ipdt_swapcount_table;
+ P3.H = ipdt_swapcount_table;
+ P3 += -4;
+icount:
+ R2 = [P2]; /* address from config table */
+ P2 += 8;
+ P3 += 8;
+ CC = R2==-1;
+ IF CC JUMP icount_done;
+ CC = R7==R2;
+ IF !CC JUMP icount;
+ R7 = [P3];
+ R7 += 1;
+ [P3] = R7;
+ CSYNC;
+icount_done:
+#endif
+ LC0=R3;
+ LSETUP(is_move,ie_move) LC0;
+is_move:
+ R0 = [P0];
+ [P0 - 4] = R0;
+ R0 = [P0 - 0x100];
+ [P0-0x104] = R0;
+ie_move:P0+=4;
+
+ /* We've made space in the ICPLB table, so that ICPLB15
+ * is now free to be overwritten. Next, we have to determine
+ * which CPLB we need to install, from the configuration
+ * table. This is a matter of getting the start-of-page
+ * addresses and page-lengths from the config table, and
+ * determining whether the fault address falls within that
+ * range.
+ */
+
+ P2.L = ipdt_table;
+ P2.H = ipdt_table;
+#ifdef CONFIG_CPLB_INFO
+ P3.L = ipdt_swapcount_table;
+ P3.H = ipdt_swapcount_table;
+ P3 += -8;
+#endif
+ P0.L = page_size_table;
+ P0.H = page_size_table;
+
+ /* Retrieve our fault address (which may have been advanced
+ * because the faulting instruction crossed a page boundary).
+ */
+
+ R0 = I0;
+
+ /* An extraction pattern, to get the page-size bits from
+ * the CPLB data entry. Bits 16-17, so two bits at posn 16.
+ */
+
+ R1 = ((16<<8)|2);
+inext: R4 = [P2++]; /* address from config table */
+ R2 = [P2++]; /* data from config table */
+#ifdef CONFIG_CPLB_INFO
+ P3 += 8;
+#endif
+
+ CC = R4 == -1; /* End of config table*/
+ IF CC JUMP no_page_in_table;
+
+ /* See if failed address > start address */
+ CC = R4 <= R0(IU);
+ IF !CC JUMP inext;
+
+ /* extract page size (17:16)*/
+ R3 = EXTRACT(R2, R1.L) (Z);
+
+ /* add page size to addr to get range */
+
+ P5 = R3;
+ P5 = P0 + (P5 << 2); /* scaled, for int access*/
+ R3 = [P5];
+ R3 = R3 + R4;
+
+ /* See if failed address < (start address + page size) */
+ CC = R0 < R3(IU);
+ IF !CC JUMP inext;
+
+ /* We've found a CPLB in the config table that covers
+ * the faulting address, so install this CPLB into the
+ * last entry of the table.
+ */
+
+ P1.L = (ICPLB_DATA15 & 0xFFFF); /*ICPLB_DATA15*/
+ P1.H = (ICPLB_DATA15 >> 16);
+ [P1] = R2;
+ [P1-0x100] = R4;
+#ifdef CONFIG_CPLB_INFO
+ R3 = [P3];
+ R3 += 1;
+ [P3] = R3;
+#endif
+
+ /* P4 points to IMEM_CONTROL, and R5 contains its old
+ * value, after we disabled ICPLBS. Re-enable them.
+ */
+
+ BITSET(R5,ENICPLB_P);
+ CLI R2;
+ SSYNC; /* SSYNC required before writing to IMEM_CONTROL. */
+ .align 8;
+ [P4] = R5;
+ SSYNC;
+ STI R2;
+
+ ( R7:0,P5:0 ) = [SP++];
+ R0 = CPLB_RELOADED;
+ RTS;
+
+/* FAILED CASES*/
+no_page_in_table:
+ ( R7:0,P5:0 ) = [SP++];
+ R0 = CPLB_NO_ADDR_MATCH;
+ RTS;
+all_locked:
+ ( R7:0,P5:0 ) = [SP++];
+ R0 = CPLB_NO_UNLOCKED;
+ RTS;
+prot_violation:
+ ( R7:0,P5:0 ) = [SP++];
+ R0 = CPLB_PROT_VIOL;
+ RTS;
+
+dcplb_write:
+
+ /* if a DCPLB is marked as write-back (CPLB_WT==0), and
+ * it is clean (CPLB_DIRTY==0), then a write to the
+ * CPLB's page triggers a protection violation. We have to
+ * mark the CPLB as dirty, to indicate that there are
+ * pending writes associated with the CPLB.
+ */
+
+ P4.L = (DCPLB_STATUS & 0xFFFF);
+ P4.H = (DCPLB_STATUS >> 16);
+ P3.L = (DCPLB_DATA0 & 0xFFFF);
+ P3.H = (DCPLB_DATA0 >> 16);
+ R5 = [P4];
+
+ /* A protection violation can be caused by more than just writes
+ * to a clean WB page, so we have to ensure that:
+ * - It's a write
+ * - to a clean WB page
+ * - and is allowed in the mode the access occurred.
+ */
+
+ CC = BITTST(R5, 16); /* ensure it was a write*/
+ IF !CC JUMP prot_violation;
+
+ /* to check the rest, we have to retrieve the DCPLB.*/
+
+ /* The low half of DCPLB_STATUS is a bit mask*/
+
+ R2 = R5.L (Z); /* indicating which CPLB triggered the event.*/
+ R3 = 30; /* so we can use this to determine the offset*/
+ R2.L = SIGNBITS R2;
+ R2 = R2.L (Z); /* into the DCPLB table.*/
+ R3 = R3 - R2;
+ P4 = R3;
+ P3 = P3 + (P4<<2);
+ R3 = [P3]; /* Retrieve the CPLB*/
+
+ /* Now we can check whether it's a clean WB page*/
+
+ CC = BITTST(R3, 14); /* 0==WB, 1==WT*/
+ IF CC JUMP prot_violation;
+ CC = BITTST(R3, 7); /* 0 == clean, 1 == dirty*/
+ IF CC JUMP prot_violation;
+
+ /* Check whether the write is allowed in the mode that was active.*/
+
+ R2 = 1<<3; /* checking write in user mode*/
+ CC = BITTST(R5, 17); /* 0==was user, 1==was super*/
+ R5 = CC;
+ R2 <<= R5; /* if was super, check write in super mode*/
+ R2 = R3 & R2;
+ CC = R2 == 0;
+ IF CC JUMP prot_violation;
+
+ /* It's a genuine write-to-clean-page.*/
+
+ BITSET(R3, 7); /* mark as dirty*/
+ [P3] = R3; /* and write back.*/
+ CSYNC;
+ ( R7:0,P5:0 ) = [SP++];
+ R0 = CPLB_RELOADED;
+ RTS;
+
+dcplb_miss_compare:
+
+ /* Data CPLB Miss event. We need to choose a CPLB to
+ * evict, and then locate a new CPLB to install from the
+ * config table, that covers the faulting address.
+ */
+
+ P1.L = (DCPLB_DATA15 & 0xFFFF);
+ P1.H = (DCPLB_DATA15 >> 16);
+
+ P4.L = (DCPLB_FAULT_ADDR & 0xFFFF);
+ P4.H = (DCPLB_FAULT_ADDR >> 16);
+ R4 = [P4];
+ I0 = R4;
+
+ /* The replacement procedure for DCPLBs*/
+
+ R6 = R1; /* Save for later*/
+
+ /* Turn off CPLBs while we work.*/
+ P4.L = (DMEM_CONTROL & 0xFFFF);
+ P4.H = (DMEM_CONTROL >> 16);
+ R5 = [P4];
+ BITCLR(R5,ENDCPLB_P);
+ CLI R0;
+ SSYNC; /* SSYNC required before writing to DMEM_CONTROL. */
+ .align 8;
+ [P4] = R5;
+ SSYNC;
+ STI R0;
+
+ /* Start looking for a CPLB to evict. Our order of preference
+ * is: invalid CPLBs, clean CPLBs, dirty CPLBs. Locked CPLBs
+ * are no good.
+ */
+
+ I1.L = (DCPLB_DATA0 & 0xFFFF);
+ I1.H = (DCPLB_DATA0 >> 16);
+ P1 = 3;
+ P2 = 16;
+ I2.L = dcplb_preference;
+ I2.H = dcplb_preference;
+ LSETUP(sdsearch1, edsearch1) LC0 = P1;
+sdsearch1:
+ R0 = [I2++]; /* Get the bits we're interested in*/
+ P0 = I1; /* Go back to start of table*/
+ LSETUP (sdsearch2, edsearch2) LC1 = P2;
+sdsearch2:
+ R1 = [P0++]; /* Fetch each installed CPLB in turn*/
+ R2 = R1 & R0; /* and test for interesting bits.*/
+ CC = R2 == 0; /* If none are set, it'll do.*/
+ IF !CC JUMP skip_stack_check;
+
+ R2 = [P0 - 0x104]; /* R2 - PageStart */
+ P3.L = page_size_table; /* retrive end address */
+ P3.H = page_size_table; /* retrive end address */
+ R3 = 0x2; /* 0th - position, 2 bits -length */
+ nop; /*Anamoly 05000209*/
+ R7 = EXTRACT(R1,R3.l);
+ R7 = R7 << 2; /* Page size index offset */
+ P5 = R7;
+ P3 = P3 + P5;
+ R7 = [P3]; /* page size in 1K bytes */
+
+ R7 = R7 << 0xA; /* in bytes * 1024*/
+ R7 = R2 + R7; /* R7 - PageEnd */
+ R4 = SP; /* Test SP is in range */
+
+ CC = R7 < R4; /* if PageEnd < SP */
+ IF CC JUMP dfound_victim;
+ R3 = 0x284; /* stack length from start of trap till the point */
+ /* 20 stack locations for future modifications */
+ R4 = R4 + R3;
+ CC = R4 < R2; /* if SP + stacklen < PageStart */
+ IF CC JUMP dfound_victim;
+skip_stack_check:
+
+edsearch2: NOP;
+edsearch1: NOP;
+
+ /* If we got here, we didn't find a DCPLB we considered
+ * replacable, which means all of them were locked.
+ */
+
+ JUMP all_locked;
+dfound_victim:
+
+#ifdef CONFIG_CPLB_INFO
+ R1 = [P0 - 0x104];
+ P2.L = dpdt_table;
+ P2.H = dpdt_table;
+ P3.L = dpdt_swapcount_table;
+ P3.H = dpdt_swapcount_table;
+ P3 += -4;
+dicount:
+ R2 = [P2];
+ P2 += 8;
+ P3 += 8;
+ CC = R2==-1;
+ IF CC JUMP dicount_done;
+ CC = R1==R2;
+ IF !CC JUMP dicount;
+ R1 = [P3];
+ R1 += 1;
+ [P3] = R1;
+ CSYNC;
+dicount_done:
+#endif
+
+ /* Clean down the hardware loops*/
+ R2 = 0;
+ LC1 = R2;
+ LC0 = R2;
+
+ /* There's a suitable victim in [P0-4] (because we've
+ * advanced already). If it's a valid dirty write-back
+ * CPLB, we need to flush the pending writes first.
+ */
+
+ CC = BITTST(R1, 0); /* Is it valid?*/
+ IF !CC JUMP Ddoverwrite;/* nope.*/
+ CC = BITTST(R1, 7); /* Is it dirty?*/
+ IF !CC JUMP Ddoverwrite (BP); /* Nope.*/
+ CC = BITTST(R1, 14); /* Is it Write-Through?*/
+ IF CC JUMP Ddoverwrite; /* Yep*/
+
+ /* This is a dirty page, so we need to flush all writes
+ * that are pending on the page.
+ */
+
+ /* Retrieve the page start address*/
+ R0 = [P0 - 0x104];
+ [--sp] = rets;
+ CALL dcplb_flush; /* R0==CPLB addr, R1==CPLB data*/
+ rets = [sp++];
+Ddoverwrite:
+
+ /* [P0-4] is a suitable victim CPLB, so we want to
+ * overwrite it by moving all the following CPLBs
+ * one space closer to the start.
+ */
+
+ R1.L = ((DCPLB_DATA15+4) & 0xFFFF); /*DCPLB_DATA15+4*/
+ R1.H = ((DCPLB_DATA15+4) >> 16);
+ R0 = P0;
+
+ /* If the victim happens to be in DCPLB15,
+ * we don't need to move anything.
+ */
+
+ CC = R1 == R0;
+ IF CC JUMP de_moved;
+ R1 = R1 - R0;
+ R1 >>= 2;
+ P1 = R1;
+ LSETUP(ds_move, de_move) LC0=P1;
+ds_move:
+ R0 = [P0++]; /* move data */
+ [P0 - 8] = R0;
+ R0 = [P0-0x104] /* move address */
+de_move: [P0-0x108] = R0;
+
+ /* We've now made space in DCPLB15 for the new CPLB to be
+ * installed. The next stage is to locate a CPLB in the
+ * config table that covers the faulting address.
+ */
+
+de_moved:NOP;
+ R0 = I0; /* Our faulting address */
+
+ P2.L = dpdt_table;
+ P2.H = dpdt_table;
+#ifdef CONFIG_CPLB_INFO
+ P3.L = dpdt_swapcount_table;
+ P3.H = dpdt_swapcount_table;
+ P3 += -8;
+#endif
+
+ P1.L = page_size_table;
+ P1.H = page_size_table;
+
+ /* An extraction pattern, to retrieve bits 17:16.*/
+
+ R1 = (16<<8)|2;
+dnext: R4 = [P2++]; /* address */
+ R2 = [P2++]; /* data */
+#ifdef CONFIG_CPLB_INFO
+ P3 += 8;
+#endif
+
+ CC = R4 == -1;
+ IF CC JUMP no_page_in_table;
+
+ /* See if failed address > start address */
+ CC = R4 <= R0(IU);
+ IF !CC JUMP dnext;
+
+ /* extract page size (17:16)*/
+ R3 = EXTRACT(R2, R1.L) (Z);
+
+ /* add page size to addr to get range */
+
+ P5 = R3;
+ P5 = P1 + (P5 << 2);
+ R3 = [P5];
+ R3 = R3 + R4;
+
+ /* See if failed address < (start address + page size) */
+ CC = R0 < R3(IU);
+ IF !CC JUMP dnext;
+
+ /* We've found the CPLB that should be installed, so
+ * write it into CPLB15, masking off any caching bits
+ * if necessary.
+ */
+
+ P1.L = (DCPLB_DATA15 & 0xFFFF);
+ P1.H = (DCPLB_DATA15 >> 16);
+
+ /* If the DCPLB has cache bits set, but caching hasn't
+ * been enabled, then we want to mask off the cache-in-L1
+ * bit before installing. Moreover, if caching is off, we
+ * also want to ensure that the DCPLB has WT mode set, rather
+ * than WB, since WB pages still trigger first-write exceptions
+ * even when not caching is off, and the page isn't marked as
+ * cachable. Finally, we could mark the page as clean, not dirty,
+ * but we choose to leave that decision to the user; if the user
+ * chooses to have a CPLB pre-defined as dirty, then they always
+ * pay the cost of flushing during eviction, but don't pay the
+ * cost of first-write exceptions to mark the page as dirty.
+ */
+
+#ifdef CONFIG_BLKFIN_WT
+ BITSET(R6, 14); /* Set WT*/
+#endif
+
+ [P1] = R2;
+ [P1-0x100] = R4;
+#ifdef CONFIG_CPLB_INFO
+ R3 = [P3];
+ R3 += 1;
+ [P3] = R3;
+#endif
+
+ /* We've installed the CPLB, so re-enable CPLBs. P4
+ * points to DMEM_CONTROL, and R5 is the value we
+ * last wrote to it, when we were disabling CPLBs.
+ */
+
+ BITSET(R5,ENDCPLB_P);
+ CLI R2;
+ .align 8;
+ [P4] = R5;
+ SSYNC;
+ STI R2;
+
+ ( R7:0,P5:0 ) = [SP++];
+ R0 = CPLB_RELOADED;
+ RTS;
+
+.data
+.align 4;
+page_size_table:
+.byte4 0x00000400; /* 1K */
+.byte4 0x00001000; /* 4K */
+.byte4 0x00100000; /* 1M */
+.byte4 0x00400000; /* 4M */
+
+.align 4;
+dcplb_preference:
+.byte4 0x00000001; /* valid bit */
+.byte4 0x00000082; /* dirty+lock bits */
+.byte4 0x00000002; /* lock bit */
diff --git a/cpu/bf533/cpu.c b/cpu/bf533/cpu.c
new file mode 100644
index 0000000000..78e2b966bb
--- /dev/null
+++ b/cpu/bf533/cpu.c
@@ -0,0 +1,189 @@
+/*
+ * U-boot - cpu.c CPU specific functions
+ *
+ * Copyright (c) 2005 blackfin.uclinux.org
+ *
+ * (C) Copyright 2000-2004
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <asm/blackfin.h>
+#include <command.h>
+#include <asm/entry.h>
+
+#define SSYNC() asm("ssync;")
+#define CACHE_ON 1
+#define CACHE_OFF 0
+
+/* Data Attibutes*/
+
+#define SDRAM_IGENERIC (PAGE_SIZE_4MB | CPLB_L1_CHBL | CPLB_USER_RD | CPLB_VALID)
+#define SDRAM_IKERNEL (PAGE_SIZE_4MB | CPLB_L1_CHBL | CPLB_USER_RD | CPLB_VALID | CPLB_LOCK)
+#define L1_IMEMORY (PAGE_SIZE_1MB | CPLB_L1_CHBL | CPLB_USER_RD | CPLB_VALID | CPLB_LOCK)
+#define SDRAM_INON_CHBL (PAGE_SIZE_4MB | CPLB_USER_RD | CPLB_VALID)
+
+#define ANOMALY_05000158 0x200
+#define SDRAM_DGENERIC (PAGE_SIZE_4MB | CPLB_L1_CHBL | CPLB_WT | CPLB_L1_AOW | CPLB_SUPV_WR | CPLB_USER_RD | CPLB_USER_WR | CPLB_VALID | ANOMALY_05000158)
+#define SDRAM_DNON_CHBL (PAGE_SIZE_4MB | CPLB_WT | CPLB_L1_AOW | CPLB_SUPV_WR | CPLB_USER_WR | CPLB_USER_RD | CPLB_VALID | ANOMALY_05000158)
+#define SDRAM_DKERNEL (PAGE_SIZE_4MB | CPLB_L1_CHBL | CPLB_WT | CPLB_L1_AOW | CPLB_USER_RD | CPLB_SUPV_WR | CPLB_USER_WR | CPLB_VALID | CPLB_LOCK | ANOMALY_05000158)
+#define L1_DMEMORY (PAGE_SIZE_4KB | CPLB_L1_CHBL | CPLB_L1_AOW | CPLB_WT | CPLB_SUPV_WR | CPLB_USER_WR | CPLB_VALID | ANOMALY_05000158)
+#define SDRAM_EBIU (PAGE_SIZE_4MB | CPLB_WT | CPLB_L1_AOW | CPLB_USER_RD | CPLB_USER_WR | CPLB_SUPV_WR | CPLB_VALID | ANOMALY_05000158)
+
+static unsigned int icplb_table[16][2]={
+ {0xFFA00000, L1_IMEMORY},
+ {0x00000000, SDRAM_IKERNEL}, /*SDRAM_Page1*/
+ {0x00400000, SDRAM_IKERNEL}, /*SDRAM_Page1*/
+ {0x07C00000, SDRAM_IKERNEL}, /*SDRAM_Page14*/
+ {0x00800000, SDRAM_IGENERIC}, /*SDRAM_Page2*/
+ {0x00C00000, SDRAM_IGENERIC}, /*SDRAM_Page2*/
+ {0x01000000, SDRAM_IGENERIC}, /*SDRAM_Page4*/
+ {0x01400000, SDRAM_IGENERIC}, /*SDRAM_Page5*/
+ {0x01800000, SDRAM_IGENERIC}, /*SDRAM_Page6*/
+ {0x01C00000, SDRAM_IGENERIC}, /*SDRAM_Page7*/
+ {0x02000000, SDRAM_IGENERIC}, /*SDRAM_Page8*/
+ {0x02400000, SDRAM_IGENERIC}, /*SDRAM_Page9*/
+ {0x02800000, SDRAM_IGENERIC}, /*SDRAM_Page10*/
+ {0x02C00000, SDRAM_IGENERIC}, /*SDRAM_Page11*/
+ {0x03000000, SDRAM_IGENERIC}, /*SDRAM_Page12*/
+ {0x03400000, SDRAM_IGENERIC}, /*SDRAM_Page13*/
+};
+
+static unsigned int dcplb_table[16][2]={
+ {0xFFA00000,L1_DMEMORY},
+ {0x00000000,SDRAM_DKERNEL}, /*SDRAM_Page1*/
+ {0x00400000,SDRAM_DKERNEL}, /*SDRAM_Page1*/
+ {0x07C00000,SDRAM_DKERNEL}, /*SDRAM_Page15*/
+ {0x00800000,SDRAM_DGENERIC}, /*SDRAM_Page2*/
+ {0x00C00000,SDRAM_DGENERIC}, /*SDRAM_Page3*/
+ {0x01000000,SDRAM_DGENERIC}, /*SDRAM_Page4*/
+ {0x01400000,SDRAM_DGENERIC}, /*SDRAM_Page5*/
+ {0x01800000,SDRAM_DGENERIC}, /*SDRAM_Page6*/
+ {0x01C00000,SDRAM_DGENERIC}, /*SDRAM_Page7*/
+ {0x02000000,SDRAM_DGENERIC}, /*SDRAM_Page8*/
+ {0x02400000,SDRAM_DGENERIC}, /*SDRAM_Page9*/
+ {0x02800000,SDRAM_DGENERIC}, /*SDRAM_Page10*/
+ {0x02C00000,SDRAM_DGENERIC}, /*SDRAM_Page11*/
+ {0x03000000,SDRAM_DGENERIC}, /*SDRAM_Page12*/
+ {0x20000000,SDRAM_EBIU}, /*For Network */
+};
+
+int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+ __asm__ __volatile__
+ ("cli r3;"
+ "P0 = %0;"
+ "JUMP (P0);"
+ :
+ : "r" (L1_ISRAM)
+ );
+
+ return 0;
+}
+
+/* These functions are just used to satisfy the linker */
+int cpu_init(void)
+{
+ return 0;
+}
+
+int cleanup_before_linux(void)
+{
+ return 0;
+}
+
+void icache_enable(void)
+{
+ unsigned int *I0,*I1;
+ int i;
+
+ I0 = (unsigned int *)ICPLB_ADDR0;
+ I1 = (unsigned int *)ICPLB_DATA0;
+
+ for(i=0;i<16;i++){
+ *I0++ = icplb_table[i][0];
+ *I1++ = icplb_table[i][1];
+ }
+ cli();
+ SSYNC();
+ *(unsigned int *)IMEM_CONTROL = IMC | ENICPLB;
+ SSYNC();
+ sti();
+}
+
+void icache_disable(void)
+{
+ cli();
+ SSYNC();
+ *(unsigned int *)IMEM_CONTROL &= ~(IMC | ENICPLB);
+ SSYNC();
+ sti();
+}
+
+int icache_status(void)
+{
+ unsigned int value;
+ value = *(unsigned int *)IMEM_CONTROL;
+
+ if( value & (IMC|ENICPLB) )
+ return CACHE_ON;
+ else
+ return CACHE_OFF;
+}
+
+void dcache_enable(void)
+{
+ unsigned int *I0,*I1;
+ unsigned int temp;
+ int i;
+ I0 = (unsigned int *)DCPLB_ADDR0;
+ I1 = (unsigned int *)DCPLB_DATA0;
+
+ for(i=0;i<16;i++){
+ *I0++ = dcplb_table[i][0];
+ *I1++ = dcplb_table[i][1];
+ }
+ cli();
+ temp = *(unsigned int *)DMEM_CONTROL;
+ SSYNC();
+ *(unsigned int *)DMEM_CONTROL = ACACHE_BCACHE |ENDCPLB |PORT_PREF0|temp;
+ SSYNC();
+ sti();
+}
+
+void dcache_disable(void)
+{
+ cli();
+ SSYNC();
+ *(unsigned int *)DMEM_CONTROL &= ~(ACACHE_BCACHE |ENDCPLB |PORT_PREF0);
+ SSYNC();
+ sti();
+}
+
+int dcache_status(void)
+{
+ unsigned int value;
+ value = *(unsigned int *)DMEM_CONTROL;
+ if( value & (ENDCPLB))
+ return CACHE_ON;
+ else
+ return CACHE_OFF;
+}
diff --git a/cpu/bf533/cpu.h b/cpu/bf533/cpu.h
new file mode 100644
index 0000000000..7ec33878ea
--- /dev/null
+++ b/cpu/bf533/cpu.h
@@ -0,0 +1,65 @@
+/*
+ * U-boot - cpu.h
+ *
+ * Copyright (c) 2005 blackfin.uclinux.org
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef _CPU_H_
+#define _CPU_H_
+
+#include <command.h>
+
+#define INTERNAL_IRQS (32)
+#define NUM_IRQ_NODES 16
+#define DEF_INTERRUPT_FLAGS 1
+#define MAX_TIM_LOAD 0xFFFFFFFF
+
+void blackfin_irq_panic(int reason, struct pt_regs * reg);
+extern void dump(struct pt_regs * regs);
+void display_excp(void);
+asmlinkage void evt_nmi(void);
+asmlinkage void evt_exception(void);
+asmlinkage void trap(void);
+asmlinkage void evt_ivhw(void);
+asmlinkage void evt_rst(void);
+asmlinkage void evt_timer(void);
+asmlinkage void evt_evt7(void);
+asmlinkage void evt_evt8(void);
+asmlinkage void evt_evt9(void);
+asmlinkage void evt_evt10(void);
+asmlinkage void evt_evt11(void);
+asmlinkage void evt_evt12(void);
+asmlinkage void evt_evt13(void);
+asmlinkage void evt_soft_int1(void);
+asmlinkage void evt_system_call(void);
+void blackfin_irq_panic(int reason, struct pt_regs * regs);
+void blackfin_free_irq(unsigned int irq, void *dev_id);
+void call_isr(int irq, struct pt_regs * fp);
+void blackfin_do_irq(int vec, struct pt_regs *fp);
+void blackfin_init_IRQ(void);
+void blackfin_enable_irq(unsigned int irq);
+void blackfin_disable_irq(unsigned int irq);
+extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
+int blackfin_request_irq(unsigned int irq,
+ void (*handler)(int, void *, struct pt_regs *),
+ unsigned long flags,const char *devname,void *dev_id);
+void timer_init(void);
+#endif
diff --git a/cpu/bf533/flush.S b/cpu/bf533/flush.S
new file mode 100644
index 0000000000..9fbdefc9db
--- /dev/null
+++ b/cpu/bf533/flush.S
@@ -0,0 +1,402 @@
+/* Copyright (C) 2003 Analog Devices, Inc. All Rights Reserved.
+ * Copyright (C) 2004 LG SOft India. All Rights Reserved.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.
+ *
+ * Blackfin BF533/2.6 support : LG Soft India
+ */
+#define ASSEMBLY
+
+#include <asm/linkage.h>
+#include <asm/cplb.h>
+#include <asm/blackfin.h>
+
+.text
+
+/* This is an external function being called by the user
+ * application through __flush_cache_all. Currently this function
+ * serves the purpose of flushing all the pending writes in
+ * in the instruction cache.
+ */
+
+ENTRY(flush_instruction_cache)
+ [--SP] = ( R7:6, P5:4 );
+ LINK 12;
+ SP += -12;
+ P5.H = (ICPLB_ADDR0 >> 16);
+ P5.L = (ICPLB_ADDR0 & 0xFFFF);
+ P4.H = (ICPLB_DATA0 >> 16);
+ P4.L = (ICPLB_DATA0 & 0xFFFF);
+ R7 = CPLB_VALID | CPLB_L1_CHBL;
+ R6 = 16;
+inext: R0 = [P5++];
+ R1 = [P4++];
+ [--SP] = RETS;
+ CALL icplb_flush; /* R0 = page, R1 = data*/
+ RETS = [SP++];
+iskip: R6 += -1;
+ CC = R6;
+ IF CC JUMP inext;
+ SSYNC;
+ SP += 12;
+ UNLINK;
+ ( R7:6, P5:4 ) = [SP++];
+ RTS;
+
+/* This is an internal function to flush all pending
+ * writes in the cache associated with a particular ICPLB.
+ *
+ * R0 - page's start address
+ * R1 - CPLB's data field.
+ */
+
+.align 2
+ENTRY(icplb_flush)
+ [--SP] = ( R7:0, P5:0 );
+ [--SP] = LC0;
+ [--SP] = LT0;
+ [--SP] = LB0;
+ [--SP] = LC1;
+ [--SP] = LT1;
+ [--SP] = LB1;
+
+ /* If it's a 1K or 4K page, then it's quickest to
+ * just systematically flush all the addresses in
+ * the page, regardless of whether they're in the
+ * cache, or dirty. If it's a 1M or 4M page, there
+ * are too many addresses, and we have to search the
+ * cache for lines corresponding to the page.
+ */
+
+ CC = BITTST(R1, 17); /* 1MB or 4MB */
+ IF !CC JUMP iflush_whole_page;
+
+ /* We're only interested in the page's size, so extract
+ * this from the CPLB (bits 17:16), and scale to give an
+ * offset into the page_size and page_prefix tables.
+ */
+
+ R1 <<= 14;
+ R1 >>= 30;
+ R1 <<= 2;
+
+ /* We can also determine the sub-bank used, because this is
+ * taken from bits 13:12 of the address.
+ */
+
+ R3 = ((12<<8)|2); /* Extraction pattern */
+ nop; /*Anamoly 05000209*/
+ R4 = EXTRACT(R0, R3.L) (Z); /* Extract bits*/
+ R3.H = R4.L << 0 ; /* Save in extraction pattern for later deposit.*/
+
+
+ /* So:
+ * R0 = Page start
+ * R1 = Page length (actually, offset into size/prefix tables)
+ * R3 = sub-bank deposit values
+ *
+ * The cache has 2 Ways, and 64 sets, so we iterate through
+ * the sets, accessing the tag for each Way, for our Bank and
+ * sub-bank, looking for dirty, valid tags that match our
+ * address prefix.
+ */
+
+ P5.L = (ITEST_COMMAND & 0xFFFF);
+ P5.H = (ITEST_COMMAND >> 16);
+ P4.L = (ITEST_DATA0 & 0xFFFF);
+ P4.H = (ITEST_DATA0 >> 16);
+
+ P0.L = page_prefix_table;
+ P0.H = page_prefix_table;
+ P1 = R1;
+ R5 = 0; /* Set counter*/
+ P0 = P1 + P0;
+ R4 = [P0]; /* This is the address prefix*/
+
+ /* We're reading (bit 1==0) the tag (bit 2==0), and we
+ * don't care about which double-word, since we're only
+ * fetching tags, so we only have to set Set, Bank,
+ * Sub-bank and Way.
+ */
+
+ P2 = 4;
+ LSETUP (ifs1, ife1) LC1 = P2;
+ifs1: P0 = 32; /* iterate over all sets*/
+ LSETUP (ifs0, ife0) LC0 = P0;
+ifs0: R6 = R5 << 5; /* Combine set*/
+ R6.H = R3.H << 0 ; /* and sub-bank*/
+ [P5] = R6; /* Issue Command*/
+ SSYNC; /* CSYNC will not work here :(*/
+ R7 = [P4]; /* and read Tag.*/
+ CC = BITTST(R7, 0); /* Check if valid*/
+ IF !CC JUMP ifskip; /* and skip if not.*/
+
+ /* Compare against the page address. First, plant bits 13:12
+ * into the tag, since those aren't part of the returned data.
+ */
+
+ R7 = DEPOSIT(R7, R3); /* set 13:12*/
+ R1 = R7 & R4; /* Mask off lower bits*/
+ CC = R1 == R0; /* Compare against page start.*/
+ IF !CC JUMP ifskip; /* Skip it if it doesn't match.*/
+
+ /* Tag address matches against page, so this is an entry
+ * we must flush.
+ */
+
+ R7 >>= 10; /* Mask off the non-address bits*/
+ R7 <<= 10;
+ P3 = R7;
+ IFLUSH [P3]; /* And flush the entry*/
+ifskip:
+ife0: R5 += 1; /* Advance to next Set*/
+ife1: NOP;
+
+ifinished:
+ SSYNC; /* Ensure the data gets out to mem.*/
+
+ /*Finished. Restore context.*/
+ LB1 = [SP++];
+ LT1 = [SP++];
+ LC1 = [SP++];
+ LB0 = [SP++];
+ LT0 = [SP++];
+ LC0 = [SP++];
+ ( R7:0, P5:0 ) = [SP++];
+ RTS;
+
+iflush_whole_page:
+ /* It's a 1K or 4K page, so quicker to just flush the
+ * entire page.
+ */
+
+ P1 = 32; /* For 1K pages*/
+ P2 = P1 << 2; /* For 4K pages*/
+ P0 = R0; /* Start of page*/
+ CC = BITTST(R1, 16); /* Whether 1K or 4K*/
+ IF CC P1 = P2;
+ P1 += -1; /* Unroll one iteration*/
+ SSYNC;
+ IFLUSH [P0++]; /* because CSYNC can't end loops.*/
+ LSETUP (isall, ieall) LC0 = P1;
+isall:IFLUSH [P0++];
+ieall: NOP;
+ SSYNC;
+ JUMP ifinished;
+
+/* This is an external function being called by the user
+ * application through __flush_cache_all. Currently this function
+ * serves the purpose of flushing all the pending writes in
+ * in the data cache.
+ */
+
+ENTRY(flush_data_cache)
+ [--SP] = ( R7:6, P5:4 );
+ LINK 12;
+ SP += -12;
+ P5.H = (DCPLB_ADDR0 >> 16);
+ P5.L = (DCPLB_ADDR0 & 0xFFFF);
+ P4.H = (DCPLB_DATA0 >> 16);
+ P4.L = (DCPLB_DATA0 & 0xFFFF);
+ R7 = CPLB_VALID | CPLB_L1_CHBL | CPLB_DIRTY (Z);
+ R6 = 16;
+next: R0 = [P5++];
+ R1 = [P4++];
+ CC = BITTST(R1, 14); /* Is it write-through?*/
+ IF CC JUMP skip; /* If so, ignore it.*/
+ R2 = R1 & R7; /* Is it a dirty, cached page?*/
+ CC = R2;
+ IF !CC JUMP skip; /* If not, ignore it.*/
+ [--SP] = RETS;
+ CALL dcplb_flush; /* R0 = page, R1 = data*/
+ RETS = [SP++];
+skip: R6 += -1;
+ CC = R6;
+ IF CC JUMP next;
+ SSYNC;
+ SP += 12;
+ UNLINK;
+ ( R7:6, P5:4 ) = [SP++];
+ RTS;
+
+/* This is an internal function to flush all pending
+ * writes in the cache associated with a particular DCPLB.
+ *
+ * R0 - page's start address
+ * R1 - CPLB's data field.
+ */
+
+.align 2
+ENTRY(dcplb_flush)
+ [--SP] = ( R7:0, P5:0 );
+ [--SP] = LC0;
+ [--SP] = LT0;
+ [--SP] = LB0;
+ [--SP] = LC1;
+ [--SP] = LT1;
+ [--SP] = LB1;
+
+ /* If it's a 1K or 4K page, then it's quickest to
+ * just systematically flush all the addresses in
+ * the page, regardless of whether they're in the
+ * cache, or dirty. If it's a 1M or 4M page, there
+ * are too many addresses, and we have to search the
+ * cache for lines corresponding to the page.
+ */
+
+ CC = BITTST(R1, 17); /* 1MB or 4MB */
+ IF !CC JUMP dflush_whole_page;
+
+ /* We're only interested in the page's size, so extract
+ * this from the CPLB (bits 17:16), and scale to give an
+ * offset into the page_size and page_prefix tables.
+ */
+
+ R1 <<= 14;
+ R1 >>= 30;
+ R1 <<= 2;
+
+ /* The page could be mapped into Bank A or Bank B, depending
+ * on (a) whether both banks are configured as cache, and
+ * (b) on whether address bit A[x] is set. x is determined
+ * by DCBS in DMEM_CONTROL
+ */
+
+ R2 = 0; /* Default to Bank A (Bank B would be 1)*/
+
+ P0.L = (DMEM_CONTROL & 0xFFFF);
+ P0.H = (DMEM_CONTROL >> 16);
+
+ R3 = [P0]; /* If Bank B is not enabled as cache*/
+ CC = BITTST(R3, 2); /* then Bank A is our only option.*/
+ IF CC JUMP bank_chosen;
+
+ R4 = 1<<14; /* If DCBS==0, use A[14].*/
+ R5 = R4 << 7; /* If DCBS==1, use A[23];*/
+ CC = BITTST(R3, 4);
+ IF CC R4 = R5; /* R4 now has either bit 14 or bit 23 set.*/
+ R5 = R0 & R4; /* Use it to test the Page address*/
+ CC = R5; /* and if that bit is set, we use Bank B,*/
+ R2 = CC; /* else we use Bank A.*/
+ R2 <<= 23; /* The Bank selection's at posn 23.*/
+
+bank_chosen:
+
+ /* We can also determine the sub-bank used, because this is
+ * taken from bits 13:12 of the address.
+ */
+
+ R3 = ((12<<8)|2); /* Extraction pattern */
+ nop; /*Anamoly 05000209*/
+ R4 = EXTRACT(R0, R3.L) (Z); /* Extract bits*/
+ R3.H = R4.L << 0 ; /* Save in extraction pattern for later deposit.*/
+
+ /* So:
+ * R0 = Page start
+ * R1 = Page length (actually, offset into size/prefix tables)
+ * R2 = Bank select mask
+ * R3 = sub-bank deposit values
+ *
+ * The cache has 2 Ways, and 64 sets, so we iterate through
+ * the sets, accessing the tag for each Way, for our Bank and
+ * sub-bank, looking for dirty, valid tags that match our
+ * address prefix.
+ */
+
+ P5.L = (DTEST_COMMAND & 0xFFFF);
+ P5.H = (DTEST_COMMAND >> 16);
+ P4.L = (DTEST_DATA0 & 0xFFFF);
+ P4.H = (DTEST_DATA0 >> 16);
+
+ P0.L = page_prefix_table;
+ P0.H = page_prefix_table;
+ P1 = R1;
+ R5 = 0; /* Set counter*/
+ P0 = P1 + P0;
+ R4 = [P0]; /* This is the address prefix*/
+
+
+ /* We're reading (bit 1==0) the tag (bit 2==0), and we
+ * don't care about which double-word, since we're only
+ * fetching tags, so we only have to set Set, Bank,
+ * Sub-bank and Way.
+ */
+
+ P2 = 2;
+ LSETUP (fs1, fe1) LC1 = P2;
+fs1: P0 = 64; /* iterate over all sets*/
+ LSETUP (fs0, fe0) LC0 = P0;
+fs0: R6 = R5 << 5; /* Combine set*/
+ R6.H = R3.H << 0 ; /* and sub-bank*/
+ R6 = R6 | R2; /* and Bank. Leave Way==0 at first.*/
+ BITSET(R6,14);
+ [P5] = R6; /* Issue Command*/
+ SSYNC;
+ R7 = [P4]; /* and read Tag.*/
+ CC = BITTST(R7, 0); /* Check if valid*/
+ IF !CC JUMP fskip; /* and skip if not.*/
+ CC = BITTST(R7, 1); /* Check if dirty*/
+ IF !CC JUMP fskip; /* and skip if not.*/
+
+ /* Compare against the page address. First, plant bits 13:12
+ * into the tag, since those aren't part of the returned data.
+ */
+
+ R7 = DEPOSIT(R7, R3); /* set 13:12*/
+ R1 = R7 & R4; /* Mask off lower bits*/
+ CC = R1 == R0; /* Compare against page start.*/
+ IF !CC JUMP fskip; /* Skip it if it doesn't match.*/
+
+ /* Tag address matches against page, so this is an entry
+ * we must flush.
+ */
+
+ R7 >>= 10; /* Mask off the non-address bits*/
+ R7 <<= 10;
+ P3 = R7;
+ SSYNC;
+ FLUSHINV [P3]; /* And flush the entry*/
+fskip:
+fe0: R5 += 1; /* Advance to next Set*/
+fe1: BITSET(R2, 26); /* Go to next Way.*/
+
+dfinished:
+ SSYNC; /* Ensure the data gets out to mem.*/
+
+ /*Finished. Restore context.*/
+ LB1 = [SP++];
+ LT1 = [SP++];
+ LC1 = [SP++];
+ LB0 = [SP++];
+ LT0 = [SP++];
+ LC0 = [SP++];
+ ( R7:0, P5:0 ) = [SP++];
+ RTS;
+
+dflush_whole_page:
+
+ /* It's a 1K or 4K page, so quicker to just flush the
+ * entire page.
+ */
+
+ P1 = 32; /* For 1K pages*/
+ P2 = P1 << 2; /* For 4K pages*/
+ P0 = R0; /* Start of page*/
+ CC = BITTST(R1, 16); /* Whether 1K or 4K*/
+ IF CC P1 = P2;
+ P1 += -1; /* Unroll one iteration*/
+ SSYNC;
+ FLUSHINV [P0++]; /* because CSYNC can't end loops.*/
+ LSETUP (eall, eall) LC0 = P1;
+eall: FLUSHINV [P0++];
+ SSYNC;
+ JUMP dfinished;
+
+.align 4;
+page_prefix_table:
+.byte4 0xFFFFFC00; /* 1K */
+.byte4 0xFFFFF000; /* 4K */
+.byte4 0xFFF00000; /* 1M */
+.byte4 0xFFC00000; /* 4M */
+.page_prefix_table.end:
diff --git a/cpu/bf533/interrupt.S b/cpu/bf533/interrupt.S
new file mode 100644
index 0000000000..e780dc6d6b
--- /dev/null
+++ b/cpu/bf533/interrupt.S
@@ -0,0 +1,391 @@
+/*
+ * U-boot - interrupt.S Processing of interrupts and exception handling
+ *
+ * Copyright (c) 2005 blackfin.uclinux.org
+ *
+ * (C) Copyright 2000-2004
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * This file is based on interrupt.S
+ *
+ * Copyright (C) 2003 Metrowerks, Inc. <mwaddel@metrowerks.com>
+ * Copyright (C) 2002 Arcturus Networks Ltd. Ted Ma <mated@sympatico.ca>
+ * Copyright (C) 1998 D. Jeff Dionne <jeff@ryeham.ee.ryerson.ca>,
+ * Kenneth Albanowski <kjahds@kjahds.com>,
+ * The Silver Hammer Group, Ltd.
+ *
+ * (c) 1995, Dionne & Associates
+ * (c) 1995, DKG Display Tech.
+ *
+ * This file is also based on exception.asm
+ * (C) Copyright 2001-2005 - Analog Devices, Inc. All rights reserved.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#define ASSEMBLY
+
+#include <asm/hw_irq.h>
+#include <asm/entry.h>
+#include <asm/blackfin_defs.h>
+#include <asm/cpu/bf533_irq.h>
+
+.global blackfin_irq_panic;
+
+.text
+.align 2
+
+#ifndef CONFIG_KGDB
+.global evt_emulation
+evt_emulation:
+ SAVE_CONTEXT
+ r0 = IRQ_EMU;
+ r1 = seqstat;
+ sp += -12;
+ call blackfin_irq_panic;
+ sp += 12;
+ rte;
+#endif
+
+.global evt_nmi
+evt_nmi:
+ SAVE_CONTEXT
+ r0 = IRQ_NMI;
+ r1 = RETN;
+ sp += -12;
+ call blackfin_irq_panic;
+ sp += 12;
+
+_evt_nmi_exit:
+ rtn;
+
+.global trap
+trap:
+ [--sp] = r0;
+ [--sp] = r1;
+ [--sp] = p0;
+ [--sp] = p1;
+ [--sp] = astat;
+ r0 = seqstat;
+ R0 <<= 26;
+ R0 >>= 26;
+ p0 = r0;
+ p1.l = EVTABLE;
+ p1.h = EVTABLE;
+ p0 = p1 + (p0 << 1);
+ r1 = W[p0] (Z);
+ p1 = r1;
+ jump (pc + p1);
+
+.global _EVENT1
+_EVENT1:
+ RAISE 14;
+ JUMP.S _EXIT;
+
+.global _EVENT2
+_EVENT2:
+ RAISE 14;
+ JUMP.S _EXIT;
+
+.global _EVENT3
+_EVENT3:
+ RAISE 14;
+ JUMP.S _EXIT;
+
+.global _EVENT4
+_EVENT4:
+ RAISE 14;
+ JUMP.S _EXIT;
+
+.global _EVENT5
+_EVENT5:
+ RAISE 14;
+ JUMP.S _EXIT;
+
+.global _EVENT6
+_EVENT6:
+ RAISE 14;
+ JUMP.S _EXIT;
+
+.global _EVENT7
+_EVENT7:
+ RAISE 15;
+ JUMP.S _EXIT;
+
+.global _EVENT8
+_EVENT8:
+ RAISE 14;
+ JUMP.S _EXIT;
+
+.global _EVENT9
+_EVENT9:
+ RAISE 14;
+ JUMP.S _EXIT;
+
+.global _EVENT10
+_EVENT10:
+ RAISE 14;
+ JUMP.S _EXIT;
+
+.global _EVENT11
+_EVENT11:
+ RAISE 14;
+ JUMP.S _EXIT;
+
+.global _EVENT12
+_EVENT12:
+ RAISE 14;
+ JUMP.S _EXIT;
+
+.global _EVENT13
+_EVENT13:
+ RAISE 14;
+ JUMP.S _EXIT;
+
+.global _EVENT14
+_EVENT14:
+/* RAISE 14; */
+ CALL _cplb_hdr;
+ JUMP.S _EXIT;
+
+.global _EVENT19
+_EVENT19:
+ RAISE 14;
+ JUMP.S _EXIT;
+
+.global _EVENT20
+_EVENT20:
+ RAISE 14;
+ JUMP.S _EXIT;
+
+.global _EVENT21
+_EVENT21:
+ RAISE 14;
+ JUMP.S _EXIT;
+
+.global _EXIT
+_EXIT:
+ ASTAT = [sp++];
+ p1 = [sp++];
+ p0 = [sp++];
+ r1 = [sp++];
+ r0 = [sp++];
+ RTX;
+
+EVTABLE:
+ .byte2 0x0000;
+ .byte2 0x0000;
+ .byte2 0x0000;
+ .byte2 0x0000;
+ .byte2 0x0000;
+ .byte2 0x0000;
+ .byte2 0x0000;
+ .byte2 0x0000;
+ .byte2 0x0000;
+ .byte2 0x0000;
+ .byte2 0x0000;
+ .byte2 0x0000;
+ .byte2 0x0000;
+ .byte2 0x0000;
+ .byte2 0x0000;
+ .byte2 0x0000;
+ .byte2 0x003E;
+ .byte2 0x0042;
+ .byte4 0x0000;
+ .byte4 0x0000;
+ .byte4 0x0000;
+ .byte4 0x0000;
+ .byte4 0x0000;
+ .byte4 0x0000;
+ .byte4 0x0000;
+ .byte2 0x0000;
+ .byte2 0x001E;
+ .byte2 0x0022;
+ .byte2 0x0032;
+ .byte2 0x002e;
+ .byte2 0x0002;
+ .byte2 0x0036;
+ .byte2 0x002A;
+ .byte2 0x001A;
+ .byte2 0x0016;
+ .byte2 0x000A;
+ .byte2 0x000E;
+ .byte2 0x0012;
+ .byte2 0x0006;
+ .byte2 0x0026;
+
+.global evt_rst
+evt_rst:
+ SAVE_CONTEXT
+ r0 = IRQ_RST;
+ r1 = RETN;
+ sp += -12;
+ call do_reset;
+ sp += 12;
+
+_evt_rst_exit:
+ rtn;
+
+irq_panic:
+ r0 = IRQ_EVX;
+ r1 = sp;
+ sp += -12;
+ call blackfin_irq_panic;
+ sp += 12;
+
+.global evt_ivhw
+evt_ivhw:
+ SAVE_CONTEXT
+ RAISE 14;
+
+_evt_ivhw_exit:
+ rti;
+
+.global evt_timer
+evt_timer:
+ SAVE_CONTEXT
+ r0 = IRQ_CORETMR;
+ sp += -12;
+ /* Polling method used now. */
+ /* call timer_int; */
+ sp += 12;
+ RESTORE_CONTEXT
+ rti;
+ nop;
+
+.global evt_evt7
+evt_evt7:
+ SAVE_CONTEXT
+ r0 = 7;
+ sp += -12;
+ call process_int;
+ sp += 12;
+
+evt_evt7_exit:
+ RESTORE_CONTEXT
+ rti;
+
+.global evt_evt8
+evt_evt8:
+ SAVE_CONTEXT
+ r0 = 8;
+ sp += -12;
+ call process_int;
+ sp += 12;
+
+evt_evt8_exit:
+ RESTORE_CONTEXT
+ rti;
+
+.global evt_evt9
+evt_evt9:
+ SAVE_CONTEXT
+ r0 = 9;
+ sp += -12;
+ call process_int;
+ sp += 12;
+
+evt_evt9_exit:
+ RESTORE_CONTEXT
+ rti;
+
+.global evt_evt10
+evt_evt10:
+ SAVE_CONTEXT
+ r0 = 10;
+ sp += -12;
+ call process_int;
+ sp += 12;
+
+evt_evt10_exit:
+ RESTORE_CONTEXT
+ rti;
+
+.global evt_evt11
+evt_evt11:
+ SAVE_CONTEXT
+ r0 = 11;
+ sp += -12;
+ call process_int;
+ sp += 12;
+
+evt_evt11_exit:
+ RESTORE_CONTEXT
+ rti;
+
+.global evt_evt12
+evt_evt12:
+ SAVE_CONTEXT
+ r0 = 12;
+ sp += -12;
+ call process_int;
+ sp += 12;
+evt_evt12_exit:
+ RESTORE_CONTEXT
+ rti;
+
+.global evt_evt13
+evt_evt13:
+ SAVE_CONTEXT
+ r0 = 13;
+ sp += -12;
+ call process_int;
+ sp += 12;
+
+evt_evt13_exit:
+ RESTORE_CONTEXT
+ rti;
+
+.global evt_system_call
+evt_system_call:
+ [--sp] = r0;
+ [--SP] = RETI;
+ r0 = [sp++];
+ r0 += 2;
+ [--sp] = r0;
+ RETI = [SP++];
+ r0 = [SP++];
+ SAVE_CONTEXT
+ sp += -12;
+ call display_excp;
+ sp += 12;
+ RESTORE_CONTEXT
+ RTI;
+
+evt_system_call_exit:
+ rti;
+
+.global evt_soft_int1
+evt_soft_int1:
+ [--sp] = r0;
+ [--SP] = RETI;
+ r0 = [sp++];
+ r0 += 2;
+ [--sp] = r0;
+ RETI = [SP++];
+ r0 = [SP++];
+ SAVE_CONTEXT
+ sp += -12;
+ call display_excp;
+ sp += 12;
+ RESTORE_CONTEXT
+ RTI;
+
+evt_soft_int1_exit:
+ rti;
diff --git a/cpu/bf533/interrupts.c b/cpu/bf533/interrupts.c
new file mode 100644
index 0000000000..df1a25ec75
--- /dev/null
+++ b/cpu/bf533/interrupts.c
@@ -0,0 +1,165 @@
+/*
+ * U-boot - interrupts.c Interrupt related routines
+ *
+ * Copyright (c) 2005 blackfin.uclinux.org
+ *
+ * This file is based on interrupts.c
+ * Copyright 1996 Roman Zippel
+ * Copyright 1999 D. Jeff Dionne <jeff@uclinux.org>
+ * Copyright 2000-2001 Lineo, Inc. D. Jefff Dionne <jeff@lineo.ca>
+ * Copyright 2002 Arcturus Networks Inc. MaTed <mated@sympatico.ca>
+ * Copyright 2003 Metrowerks/Motorola
+ * Copyright 2003 Bas Vermeulen <bas@buyways.nl>,
+ * BuyWays B.V. (www.buyways.nl)
+ *
+ * (C) Copyright 2000-2004
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <asm/machdep.h>
+#include <asm/irq.h>
+#include <asm/cpu/defBF533.h>
+#include "cpu.h"
+
+static ulong timestamp;
+static ulong last_time;
+static int int_flag;
+
+int irq_flags; /* needed by asm-blackfin/system.h */
+
+/* Functions just to satisfy the linker */
+
+/*
+ * This function is derived from PowerPC code (read timebase as long long).
+ * On BF533 it just returns the timer value.
+ */
+unsigned long long get_ticks(void)
+{
+ return get_timer(0);
+}
+
+/*
+ * This function is derived from PowerPC code (timebase clock frequency).
+ * On BF533 it returns the number of timer ticks per second.
+ */
+ulong get_tbclk (void)
+{
+ ulong tbclk;
+
+ tbclk = CFG_HZ;
+ return tbclk;
+}
+
+void enable_interrupts(void)
+{
+ restore_flags(int_flag);
+}
+
+int disable_interrupts(void)
+{
+ save_and_cli(int_flag);
+ return 1;
+}
+
+int interrupt_init(void)
+{
+ return (0);
+}
+
+void udelay(unsigned long usec)
+{
+ unsigned long delay, start, stop;
+ unsigned long cclk;
+ cclk = (CONFIG_CCLK_HZ);
+
+ while ( usec > 1 ) {
+ /*
+ * how many clock ticks to delay?
+ * - request(in useconds) * clock_ticks(Hz) / useconds/second
+ */
+ if (usec < 1000) {
+ delay = (usec * (cclk/244)) >> 12 ;
+ usec = 0;
+ } else {
+ delay = (1000 * (cclk/244)) >> 12 ;
+ usec -= 1000;
+ }
+
+ asm volatile (" %0 = CYCLES;": "=g"(start));
+ do {
+ asm volatile (" %0 = CYCLES; ": "=g"(stop));
+ } while (stop - start < delay);
+ }
+
+ return;
+}
+
+void timer_init(void)
+{
+ *pTCNTL = 0x1;
+ *pTSCALE = 0x0;
+ *pTCOUNT = MAX_TIM_LOAD;
+ *pTPERIOD = MAX_TIM_LOAD;
+ *pTCNTL = 0x7;
+ asm("CSYNC;");
+
+ timestamp = 0;
+ last_time = 0;
+}
+
+/* Any network command or flash
+ * command is started get_timer shall
+ * be called before TCOUNT gets reset,
+ * to implement the accurate timeouts.
+ *
+ * How ever milliconds doesn't return
+ * the number that has been elapsed from
+ * the last reset.
+ *
+ * As get_timer is used in the u-boot
+ * only for timeouts this should be
+ * sufficient
+ */
+ulong get_timer(ulong base)
+{
+ ulong milisec;
+
+ /* Number of clocks elapsed */
+ ulong clocks = (MAX_TIM_LOAD - (*pTCOUNT));
+
+ /* Find if the TCOUNT is reset
+ timestamp gives the number of times
+ TCOUNT got reset */
+ if(clocks < last_time)
+ timestamp++;
+ last_time = clocks;
+
+ /* Get the number of milliseconds */
+ milisec = clocks/(CONFIG_CCLK_HZ / 1000);
+
+ /* Find the number of millisonds
+ that got elapsed before this TCOUNT
+ cycle */
+ milisec += timestamp * (MAX_TIM_LOAD/(CONFIG_CCLK_HZ / 1000));
+
+ return (milisec - base);
+}
diff --git a/cpu/bf533/ints.c b/cpu/bf533/ints.c
new file mode 100644
index 0000000000..859f4b2f09
--- /dev/null
+++ b/cpu/bf533/ints.c
@@ -0,0 +1,107 @@
+/*
+ * U-boot - ints.c Interrupt related routines
+ *
+ * Copyright (c) 2005 blackfin.uclinux.org
+ *
+ * This file is based on ints.c
+ *
+ * Apr18 2003, Changed by HuTao to support interrupt cascading for Blackfin
+ * drivers
+ *
+ * Copyright 1996 Roman Zippel
+ * Copyright 1999 D. Jeff Dionne <jeff@uclinux.org>
+ * Copyright 2000-2001 Lineo, Inc. D. Jefff Dionne <jeff@lineo.ca>
+ * Copyright 2002 Arcturus Networks Inc. MaTed <mated@sympatico.ca>
+ * Copyright 2003 Metrowerks/Motorola
+ *
+ * (C) Copyright 2000-2004
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <linux/stddef.h>
+#include <asm/system.h>
+#include <asm/irq.h>
+#include <asm/traps.h>
+#include <asm/io.h>
+#include <asm/errno.h>
+#include <asm/machdep.h>
+#include <asm/setup.h>
+#include <asm/blackfin.h>
+#include "cpu.h"
+
+void blackfin_irq_panic(int reason, struct pt_regs *regs)
+{
+ printf("\n\nException: IRQ 0x%x entered\n", reason);
+ printf("code=[0x%x], ", (unsigned int) (regs->seqstat & 0x3f));
+ printf("stack frame=0x%x, ", (unsigned int) regs);
+ printf("bad PC=0x%04x\n", (unsigned int) regs->pc);
+ dump(regs);
+ printf("Unhandled IRQ or exceptions!\n");
+ printf("Please reset the board \n");
+}
+
+void blackfin_init_IRQ(void)
+{
+ *(unsigned volatile long *) (SIC_IMASK) = SIC_UNMASK_ALL;
+ cli();
+#ifndef CONFIG_KGDB
+ *(unsigned volatile long *) (EVT_EMULATION_ADDR) = 0x0;
+#endif
+ *(unsigned volatile long *) (EVT_NMI_ADDR) =
+ (unsigned volatile long) evt_nmi;
+ *(unsigned volatile long *) (EVT_EXCEPTION_ADDR) =
+ (unsigned volatile long) trap;
+ *(unsigned volatile long *) (EVT_HARDWARE_ERROR_ADDR) =
+ (unsigned volatile long) evt_ivhw;
+ *(unsigned volatile long *) (EVT_RESET_ADDR) =
+ (unsigned volatile long) evt_rst;
+ *(unsigned volatile long *) (EVT_TIMER_ADDR) =
+ (unsigned volatile long) evt_timer;
+ *(unsigned volatile long *) (EVT_IVG7_ADDR) =
+ (unsigned volatile long) evt_evt7;
+ *(unsigned volatile long *) (EVT_IVG8_ADDR) =
+ (unsigned volatile long) evt_evt8;
+ *(unsigned volatile long *) (EVT_IVG9_ADDR) =
+ (unsigned volatile long) evt_evt9;
+ *(unsigned volatile long *) (EVT_IVG10_ADDR) =
+ (unsigned volatile long) evt_evt10;
+ *(unsigned volatile long *) (EVT_IVG11_ADDR) =
+ (unsigned volatile long) evt_evt11;
+ *(unsigned volatile long *) (EVT_IVG12_ADDR) =
+ (unsigned volatile long) evt_evt12;
+ *(unsigned volatile long *) (EVT_IVG13_ADDR) =
+ (unsigned volatile long) evt_evt13;
+ *(unsigned volatile long *) (EVT_IVG14_ADDR) =
+ (unsigned volatile long) evt_system_call;
+ *(unsigned volatile long *) (EVT_IVG15_ADDR) =
+ (unsigned volatile long) evt_soft_int1;
+ *(volatile unsigned long *) ILAT = 0;
+ asm("csync;");
+ sti();
+ *(volatile unsigned long *) IMASK = 0xffbf;
+ asm("csync;");
+}
+
+void display_excp(void)
+{
+ printf("Exception!\n");
+}
diff --git a/cpu/bf533/serial.c b/cpu/bf533/serial.c
new file mode 100644
index 0000000000..84ae9d9cde
--- /dev/null
+++ b/cpu/bf533/serial.c
@@ -0,0 +1,194 @@
+/*
+ * U-boot - serial.c Serial driver for BF533
+ *
+ * Copyright (c) 2005 blackfin.uclinux.org
+ *
+ * This file is based on
+ * bf533_serial.c: Serial driver for BlackFin BF533 DSP internal UART.
+ * Copyright (c) 2003 Bas Vermeulen <bas@buyways.nl>,
+ * BuyWays B.V. (www.buyways.nl)
+ *
+ * Based heavily on blkfinserial.c
+ * blkfinserial.c: Serial driver for BlackFin DSP internal USRTs.
+ * Copyright(c) 2003 Metrowerks <mwaddel@metrowerks.com>
+ * Copyright(c) 2001 Tony Z. Kou <tonyko@arcturusnetworks.com>
+ * Copyright(c) 2001-2002 Arcturus Networks Inc. <www.arcturusnetworks.com>
+ *
+ * Based on code from 68328 version serial driver imlpementation which was:
+ * Copyright (C) 1995 David S. Miller <davem@caip.rutgers.edu>
+ * Copyright (C) 1998 Kenneth Albanowski <kjahds@kjahds.com>
+ * Copyright (C) 1998, 1999 D. Jeff Dionne <jeff@uclinux.org>
+ * Copyright (C) 1999 Vladimir Gurevich <vgurevic@cisco.com>
+ *
+ * (C) Copyright 2000-2004
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <asm/irq.h>
+#include <asm/system.h>
+#include <asm/segment.h>
+#include <asm/bitops.h>
+#include <asm/delay.h>
+#include <asm/uaccess.h>
+#include "bf533_serial.h"
+
+unsigned long pll_div_fact;
+
+void calc_baud(void)
+{
+ unsigned char i;
+ int temp;
+
+ for(i = 0; i < sizeof(baud_table)/sizeof(int); i++) {
+ temp = CONFIG_SCLK_HZ/(baud_table[i]*8);
+ if ( temp && 0x1 == 1 ) {
+ temp++;
+ }
+ temp = temp/2;
+ hw_baud_table[i].dl_high = (temp >> 8)& 0xFF;
+ hw_baud_table[i].dl_low = (temp) & 0xFF;
+ }
+}
+
+void serial_setbrg(void)
+{
+ int i;
+ DECLARE_GLOBAL_DATA_PTR;
+
+ calc_baud();
+
+ for (i = 0; i < sizeof(baud_table) / sizeof(int); i++) {
+ if (gd->baudrate == baud_table[i])
+ break;
+ }
+
+ /* Enable UART */
+ *pUART_GCTL |= UART_GCTL_UCEN;
+ asm("ssync;");
+
+ /* Set DLAB in LCR to Access DLL and DLH */
+ ACCESS_LATCH;
+ asm("ssync;");
+
+ *pUART_DLL = hw_baud_table[i].dl_low;
+ asm("ssync;");
+ *pUART_DLH = hw_baud_table[i].dl_high;
+ asm("ssync;");
+
+ /* Clear DLAB in LCR to Access THR RBR IER */
+ ACCESS_PORT_IER;
+ asm("ssync;");
+
+ /* Enable ERBFI and ELSI interrupts
+ * to poll SIC_ISR register*/
+ *pUART_IER = UART_IER_ELSI | UART_IER_ERBFI | UART_IER_ETBEI;
+ asm("ssync;");
+
+ /* Set LCR to Word Lengh 8-bit word select */
+ *pUART_LCR = UART_LCR_WLS8;
+ asm("ssync;");
+
+ return;
+}
+
+int serial_init(void)
+{
+ serial_setbrg();
+ return (0);
+}
+
+void serial_putc(const char c)
+{
+ if ((*pUART_LSR) & UART_LSR_TEMT)
+ {
+ if (c == '\n')
+ serial_putc('\r');
+
+ local_put_char(c);
+ }
+
+ while (!((*pUART_LSR) & UART_LSR_TEMT))
+ SYNC_ALL;
+
+ return;
+}
+
+int serial_tstc(void)
+{
+ if (*pUART_LSR & UART_LSR_DR)
+ return 1;
+ else
+ return 0;
+}
+
+int serial_getc(void)
+{
+ unsigned short uart_lsr_val, uart_rbr_val;
+ unsigned long isr_val;
+ int ret;
+
+ /* Poll for RX Interrupt */
+ while (!((isr_val = *(volatile unsigned long *)SIC_ISR) & IRQ_UART_RX_BIT));
+ asm("csync;");
+
+ uart_lsr_val = *pUART_LSR; /* Clear status bit */
+ uart_rbr_val = *pUART_RBR; /* getc() */
+
+ if (isr_val & IRQ_UART_ERROR_BIT) {
+ ret = -1;
+ }
+ else
+ {
+ ret = uart_rbr_val & 0xff;
+ }
+
+ return ret;
+}
+
+void serial_puts(const char *s)
+{
+ while (*s) {
+ serial_putc(*s++);
+ }
+}
+
+static void local_put_char(char ch)
+{
+ int flags = 0;
+ unsigned long isr_val;
+
+ save_and_cli(flags);
+
+ /* Poll for TX Interruput */
+ while (!((isr_val = *pSIC_ISR) & IRQ_UART_TX_BIT));
+ asm("csync;");
+
+ *pUART_THR = ch; /* putc() */
+
+ if (isr_val & IRQ_UART_ERROR_BIT) {
+ printf("?");
+ }
+
+ restore_flags(flags);
+
+ return ;
+}
diff --git a/cpu/bf533/start.S b/cpu/bf533/start.S
new file mode 100644
index 0000000000..6d585751ab
--- /dev/null
+++ b/cpu/bf533/start.S
@@ -0,0 +1,435 @@
+/*
+ * U-boot - start.S Startup file of u-boot for BF533
+ *
+ * Copyright (c) 2005 blackfin.uclinux.org
+ *
+ * This file is based on head.S
+ * Copyright (c) 2003 Metrowerks/Motorola
+ * Copyright (C) 1998 D. Jeff Dionne <jeff@ryeham.ee.ryerson.ca>,
+ * Kenneth Albanowski <kjahds@kjahds.com>,
+ * The Silver Hammer Group, Ltd.
+ * (c) 1995, Dionne & Associates
+ * (c) 1995, DKG Display Tech.
+ *
+ * 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
+ */
+
+/*
+ * Note: A change in this file subsequently requires a change in
+ * board/$(board_name)/config.mk for a valid u-boot.bin
+ */
+
+#define ASSEMBLY
+
+#include <linux/config.h>
+#include <asm/blackfin.h>
+#include <config.h>
+#include <asm/mem_init.h>
+
+#if (CONFIG_CCLK_DIV == 1)
+#define CONFIG_CCLK_ACT_DIV CCLK_DIV1
+#endif
+#if (CONFIG_CCLK_DIV == 2)
+#define CONFIG_CCLK_ACT_DIV CCLK_DIV2
+#endif
+#if (CONFIG_CCLK_DIV == 4)
+#define CONFIG_CCLK_ACT_DIV CCLK_DIV4
+#endif
+#if (CONFIG_CCLK_DIV == 8)
+#define CONFIG_CCLK_ACT_DIV CCLK_DIV8
+#endif
+#ifndef CONFIG_CCLK_ACT_DIV
+#define CONFIG_CCLK_ACT_DIV CONFIG_CCLK_DIV_not_defined_properly
+#endif
+
+.global _stext;
+.global __bss_start;
+.global start;
+.global _start;
+.global _rambase;
+.global _ramstart;
+.global _ramend;
+.global _bf533_data_dest;
+.global _bf533_data_size;
+.global edata;
+.global _initialize;
+.global _exit;
+.global flashdataend;
+
+.text
+_start:
+start:
+_stext:
+
+ R0 = 0x30;
+ SYSCFG = R0;
+ SSYNC;
+
+ /* As per HW reference manual DAG registers,
+ * DATA and Address resgister shall be zero'd
+ * in initialization, after a reset state
+ */
+ r1 = 0; /* Data registers zero'd */
+ r2 = 0;
+ r3 = 0;
+ r4 = 0;
+ r5 = 0;
+ r6 = 0;
+ r7 = 0;
+
+ p0 = 0; /* Address registers zero'd */
+ p1 = 0;
+ p2 = 0;
+ p3 = 0;
+ p4 = 0;
+ p5 = 0;
+
+ i0 = 0; /* DAG Registers zero'd */
+ i1 = 0;
+ i2 = 0;
+ i3 = 0;
+ m0 = 0;
+ m1 = 0;
+ m3 = 0;
+ m3 = 0;
+ l0 = 0;
+ l1 = 0;
+ l2 = 0;
+ l3 = 0;
+ b0 = 0;
+ b1 = 0;
+ b2 = 0;
+ b3 = 0;
+
+ /* Set loop counters to zero, to make sure that
+ * hw loops are disabled.
+ */
+ lc0 = 0;
+ lc1 = 0;
+
+ SSYNC;
+
+ /* Check soft reset status */
+ p0.h = SWRST >> 16;
+ p0.l = SWRST & 0xFFFF;
+ r0.l = w[p0];
+
+ cc = bittst(r0, 15);
+ if !cc jump no_soft_reset;
+
+ /* Clear Soft reset */
+ r0 = 0x0000;
+ w[p0] = r0;
+ ssync;
+
+no_soft_reset:
+ nop;
+
+ /* Clear EVT registers */
+ p0.h = (EVT_EMULATION_ADDR >> 16);
+ p0.l = (EVT_EMULATION_ADDR & 0xFFFF);
+ p0 += 8;
+ p1 = 14;
+ r1 = 0;
+ LSETUP(4,4) lc0 = p1;
+ [ p0 ++ ] = r1;
+
+ /*
+ * Set PLL_CTL
+ * - [14:09] = MSEL[5:0] : CLKIN / VCO multiplication factors
+ * - [8] = BYPASS : BYPASS the PLL, run CLKIN into CCLK/SCLK
+ * - [7] = output delay (add 200ps of delay to mem signals)
+ * - [6] = input delay (add 200ps of input delay to mem signals)
+ * - [5] = PDWN : 1=All Clocks off
+ * - [3] = STOPCK : 1=Core Clock off
+ * - [1] = PLL_OFF : 1=Disable Power to PLL
+ * - [0] = DF : 1=Pass CLKIN/2 to PLL / 0=Pass CLKIN to PLL
+ * all other bits set to zero
+ */
+
+ r0 = CONFIG_VCO_MULT; /* Load the VCO multiplier */
+ r0 = r0 << 9; /* Shift it over */
+ r1 = CONFIG_CLKIN_HALF; /* Do we need to divide CLKIN by 2? */
+ r0 = r1 | r0;
+ r1 = CONFIG_PLL_BYPASS; /* Bypass the PLL? */
+ r1 = r1 << 8; /* Shift it over */
+ r0 = r1 | r0; /* add them all together */
+
+ p0.h = (PLL_CTL >> 16);
+ p0.l = (PLL_CTL & 0xFFFF); /* Load the address */
+ cli r2; /* Disable interrupts */
+ w[p0] = r0; /* Set the value */
+ idle; /* Wait for the PLL to stablize */
+ sti r2; /* Enable interrupts */
+ ssync;
+
+ /*
+ * Turn on the CYCLES COUNTER
+ */
+ r2 = SYSCFG;
+ BITSET (r2,1);
+ SYSCFG = r2;
+
+ /* Configure SCLK & CCLK Dividers */
+ r0 = CONFIG_CCLK_ACT_DIV | CONFIG_SCLK_DIV;
+ p0.h = (PLL_DIV >> 16);
+ p0.l = (PLL_DIV & 0xFFFF);
+ w[p0] = r0;
+ ssync;
+
+wait_for_pll_stab:
+ p0.h = (PLL_STAT >> 16);
+ p0.l = (PLL_STAT & 0xFFFF);
+ r0.l = w[p0];
+ cc = bittst(r0,5);
+ if !cc jump wait_for_pll_stab;
+
+ /* Configure SDRAM if SDRAM is already not enabled */
+ p0.l = (EBIU_SDSTAT & 0xFFFF);
+ p0.h = (EBIU_SDSTAT >> 16);
+ r0.l = w[p0];
+ cc = bittst(r0, 3);
+ if !cc jump skip_sdram_enable;
+
+ /* SDRAM initialization */
+ p0.l = (EBIU_SDGCTL & 0xFFFF);
+ p0.h = (EBIU_SDGCTL >> 16); /* SDRAM Memory Global Control Register */
+ r0.h = (mem_SDGCTL >> 16);
+ r0.l = (mem_SDGCTL & 0xFFFF);
+ [p0] = r0;
+ ssync;
+
+ p0.l = (EBIU_SDBCTL & 0xFFFF);
+ p0.h = (EBIU_SDBCTL >> 16); /* SDRAM Memory Bank Control Register */
+ r0 = mem_SDBCTL;
+ w[p0] = r0.l;
+ ssync;
+
+ p0.l = (EBIU_SDRRC & 0xFFFF);
+ p0.h = (EBIU_SDRRC >> 16); /* SDRAM Refresh Rate Control Register */
+ r0 = mem_SDRRC;
+ w[p0] = r0.l;
+ ssync;
+
+skip_sdram_enable:
+ nop;
+
+#ifndef CFG_NO_FLASH
+ /* relocate into to RAM */
+ p1.l = (CFG_FLASH_BASE & 0xffff);
+ p1.h = (CFG_FLASH_BASE >> 16);
+ p2.l = (CFG_MONITOR_BASE & 0xffff);
+ p2.h = (CFG_MONITOR_BASE >> 16);
+ r0.l = (CFG_MONITOR_LEN & 0xffff);
+ r0.h = (CFG_MONITOR_LEN >> 16);
+loop1:
+ r1 = [p1];
+ [p2] = r1;
+ p3=0x4;
+ p1=p1+p3;
+ p2=p2+p3;
+ r2=0x4;
+ r0=r0-r2;
+ cc=r0==0x0;
+ if !cc jump loop1;
+#endif
+ /*
+ * configure STACK
+ */
+ r0.h = (CONFIG_STACKBASE >> 16);
+ r0.l = (CONFIG_STACKBASE & 0xFFFF);
+ sp = r0;
+ fp = sp;
+
+ /*
+ * This next section keeps the processor in supervisor mode
+ * during kernel boot. Switches to user mode at end of boot.
+ * See page 3-9 of Hardware Reference manual for documentation.
+ */
+
+ /* To keep ourselves in the supervisor mode */
+ p0.l = (EVT_IVG15_ADDR & 0xFFFF);
+ p0.h = (EVT_IVG15_ADDR >> 16);
+
+ p1.l = _real_start;
+ p1.h = _real_start;
+ [p0] = p1;
+
+ p0.l = (IMASK & 0xFFFF);
+ p0.h = (IMASK >> 16);
+ r0 = IVG15_POS;
+ [p0] = r0;
+ raise 15;
+ p0.l = WAIT_HERE;
+ p0.h = WAIT_HERE;
+ reti = p0;
+ rti;
+
+WAIT_HERE:
+ jump WAIT_HERE;
+
+.global _real_start;
+_real_start:
+ [ -- sp ] = reti;
+
+#ifdef CONFIG_EZKIT533
+ p0.l = (WDOG_CTL & 0xFFFF);
+ p0.h = (WDOG_CTL >> 16);
+ r0 = WATCHDOG_DISABLE(z);
+ w[p0] = r0;
+#endif
+
+ /* Code for initializing Async mem banks */
+ p2.h = (EBIU_AMBCTL1 >> 16);
+ p2.l = (EBIU_AMBCTL1 & 0xFFFF);
+ r0.h = (AMBCTL1VAL >> 16);
+ r0.l = (AMBCTL1VAL & 0xFFFF);
+ [p2] = r0;
+ ssync;
+
+ p2.h = (EBIU_AMBCTL0 >> 16);
+ p2.l = (EBIU_AMBCTL0 & 0xFFFF);
+ r0.h = (AMBCTL0VAL >> 16);
+ r0.l = (AMBCTL0VAL & 0xFFFF);
+ [p2] = r0;
+ ssync;
+
+ p2.h = (EBIU_AMGCTL >> 16);
+ p2.l = (EBIU_AMGCTL & 0xffff);
+ r0 = AMGCTLVAL;
+ w[p2] = r0;
+ ssync;
+
+ /* DMA reset code to Hi of L1 SRAM */
+copy:
+ P1.H = hi(SYSMMR_BASE); /* P1 Points to the beginning of SYSTEM MMR Space */
+ P1.L = lo(SYSMMR_BASE);
+
+ R0.H = reset_start; /* Source Address (high) */
+ R0.L = reset_start; /* Source Address (low) */
+ R1.H = reset_end;
+ R1.L = reset_end;
+ R2 = R1 - R0; /* Count */
+ R1.H = hi(L1_ISRAM); /* Destination Address (high) */
+ R1.L = lo(L1_ISRAM); /* Destination Address (low) */
+ R3.L = DMAEN; /* Source DMAConfig Value (8-bit words) */
+ R4.L = (DI_EN | WNR | DMAEN); /* Destination DMAConfig Value (8-bit words) */
+
+DMA:
+ R6 = 0x1 (Z);
+ W[P1+OFFSET_(MDMA_S0_X_MODIFY)] = R6; /* Source Modify = 1 */
+ W[P1+OFFSET_(MDMA_D0_X_MODIFY)] = R6; /* Destination Modify = 1 */
+
+ [P1+OFFSET_(MDMA_S0_START_ADDR)] = R0; /* Set Source Base Address */
+ W[P1+OFFSET_(MDMA_S0_X_COUNT)] = R2; /* Set Source Count */
+ /* Set Source DMAConfig = DMA Enable,
+ Memory Read, 8-Bit Transfers, 1-D DMA, Flow - Stop */
+ W[P1+OFFSET_(MDMA_S0_CONFIG)] = R3;
+
+ [P1+OFFSET_(MDMA_D0_START_ADDR)] = R1; /* Set Destination Base Address */
+ W[P1+OFFSET_(MDMA_D0_X_COUNT)] = R2; /* Set Destination Count */
+ /* Set Destination DMAConfig = DMA Enable,
+ Memory Write, 8-Bit Transfers, 1-D DMA, Flow - Stop, IOC */
+ W[P1+OFFSET_(MDMA_D0_CONFIG)] = R4;
+
+ IDLE; /* Wait for DMA to Complete */
+
+ R0 = 0x1;
+ W[P1+OFFSET_(MDMA_D0_IRQ_STATUS)] = R0; /* Write 1 to clear DMA interrupt */
+
+ /* DMA reset code to DATA BANK A which uses this port
+ * to avoid following problem
+ * " Data from a Data Cache fill can be corrupoted after or during
+ * instruction DMA if certain core stalls exist"
+ */
+
+copy_as_data:
+ R0.H = reset_start; /* Source Address (high) */
+ R0.L = reset_start; /* Source Address (low) */
+ R1.H = reset_end;
+ R1.L = reset_end;
+ R2 = R1 - R0; /* Count */
+ R1.H = hi(DATA_BANKA_SRAM); /* Destination Address (high) */
+ R1.L = lo(DATA_BANKA_SRAM); /* Destination Address (low) */
+ R3.L = DMAEN; /* Source DMAConfig Value (8-bit words) */
+ R4.L = (DI_EN | WNR | DMAEN); /* Destination DMAConfig Value (8-bit words) */
+
+DMA_DATA:
+ R6 = 0x1 (Z);
+ W[P1+OFFSET_(MDMA_S0_X_MODIFY)] = R6; /* Source Modify = 1 */
+ W[P1+OFFSET_(MDMA_D0_X_MODIFY)] = R6; /* Destination Modify = 1 */
+
+ [P1+OFFSET_(MDMA_S0_START_ADDR)] = R0; /* Set Source Base Address */
+ W[P1+OFFSET_(MDMA_S0_X_COUNT)] = R2; /* Set Source Count */
+ /* Set Source DMAConfig = DMA Enable,
+ Memory Read, 8-Bit Transfers, 1-D DMA, Flow - Stop */
+ W[P1+OFFSET_(MDMA_S0_CONFIG)] = R3;
+
+ [P1+OFFSET_(MDMA_D0_START_ADDR)] = R1; /* Set Destination Base Address */
+ W[P1+OFFSET_(MDMA_D0_X_COUNT)] = R2; /* Set Destination Count */
+ /* Set Destination DMAConfig = DMA Enable,
+ Memory Write, 8-Bit Transfers, 1-D DMA, Flow - Stop, IOC */
+ W[P1+OFFSET_(MDMA_D0_CONFIG)] = R4;
+
+ IDLE; /* Wait for DMA to Complete */
+
+ R0 = 0x1;
+ W[P1+OFFSET_(MDMA_D0_IRQ_STATUS)] = R0; /* Write 1 to clear DMA interrupt */
+
+copy_end: nop;
+
+ /* Initialize BSS Section with 0 s */
+ p1.l = __bss_start;
+ p1.h = __bss_start;
+ p2.l = _end;
+ p2.h = _end;
+ r1 = p1;
+ r2 = p2;
+ r3 = r2 - r1;
+ r3 = r3 >> 2;
+ p3 = r3;
+ lsetup (_clear_bss, _clear_bss_end ) lc1 = p3;
+ CC = p2<=p1;
+ if CC jump _clear_bss_skip;
+ r0 = 0;
+_clear_bss:
+_clear_bss_end:
+ [p1++] = r0;
+_clear_bss_skip:
+
+ p0.l = _start1;
+ p0.h = _start1;
+ jump (p0);
+
+reset_start:
+ p0.h = WDOG_CNT >> 16;
+ p0.l = WDOG_CNT & 0xffff;
+ r0 = 0x0010;
+ w[p0] = r0;
+ p0.h = WDOG_CTL >> 16;
+ p0.l = WDOG_CTL & 0xffff;
+ r0 = 0x0000;
+ w[p0] = r0;
+reset_wait:
+ jump reset_wait;
+
+reset_end: nop;
+
+_exit:
+ jump.s _exit;
diff --git a/cpu/bf533/start1.S b/cpu/bf533/start1.S
new file mode 100644
index 0000000000..6f48124055
--- /dev/null
+++ b/cpu/bf533/start1.S
@@ -0,0 +1,38 @@
+/*
+ * U-boot - start1.S Code running out of RAM after relocation
+ *
+ * Copyright (c) 2005 blackfin.uclinux.org
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#define ASSEMBLY
+#include <linux/config.h>
+#include <asm/blackfin.h>
+#include <config.h>
+
+.global start1;
+.global _start1;
+
+.text
+_start1:
+start1:
+ sp += -12;
+ call board_init_f;
+ sp += 12;
diff --git a/cpu/bf533/traps.c b/cpu/bf533/traps.c
new file mode 100644
index 0000000000..37470d583e
--- /dev/null
+++ b/cpu/bf533/traps.c
@@ -0,0 +1,73 @@
+/*
+ * U-boot - traps.c Routines related to interrupts and exceptions
+ *
+ * Copyright (c) 2005 blackfin.uclinux.org
+ *
+ * This file is based on
+ * No original Copyright holder listed,
+ * Probabily original (C) Roman Zippel (assigned DJD, 1999)
+ *
+ * Copyright 2003 Metrowerks - for Blackfin
+ * Copyright 2000-2001 Lineo, Inc. D. Jeff Dionne <jeff@lineo.ca>
+ * Copyright 1999-2000 D. Jeff Dionne, <jeff@uclinux.org>
+ *
+ * (C) Copyright 2000-2004
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <linux/types.h>
+#include <asm/errno.h>
+#include <asm/irq.h>
+#include <asm/system.h>
+#include <asm/traps.h>
+#include <asm/page.h>
+#include <asm/machdep.h>
+#include "cpu.h"
+
+void init_IRQ(void)
+{
+ blackfin_init_IRQ();
+ return;
+}
+
+void process_int(unsigned long vec, struct pt_regs *fp)
+{
+ return;
+}
+
+void dump(struct pt_regs *fp)
+{
+ printf("PC: %08lx\n", fp->pc);
+ printf("SEQSTAT: %08lx SP: %08lx\n", (long) fp->seqstat,
+ (long) fp);
+ printf("R0: %08lx R1: %08lx R2: %08lx R3: %08lx\n",
+ fp->r0, fp->r1, fp->r2, fp->r3);
+ printf("R4: %08lx R5: %08lx R6: %08lx R7: %08lx\n",
+ fp->r4, fp->r5, fp->r6, fp->r7);
+ printf("P0: %08lx P1: %08lx P2: %08lx P3: %08lx\n",
+ fp->p0, fp->p1, fp->p2, fp->p3);
+ printf("P4: %08lx P5: %08lx FP: %08lx\n", fp->p4, fp->p5,
+ fp->fp);
+ printf("A0.w: %08lx A0.x: %08lx A1.w: %08lx A1.x: %08lx\n",
+ fp->a0w, fp->a0x, fp->a1w, fp->a1x);
+ printf("\n");
+}
diff --git a/cpu/mips/au1x00_eth.c b/cpu/mips/au1x00_eth.c
index 9ce9b35397..078e8328b6 100644
--- a/cpu/mips/au1x00_eth.c
+++ b/cpu/mips/au1x00_eth.c
@@ -224,10 +224,14 @@ static void au1x00_halt(struct eth_device* dev){
int au1x00_enet_initialize(bd_t *bis){
struct eth_device* dev;
- dev = (struct eth_device*) malloc(sizeof *dev);
+ if ((dev = (struct eth_device*)malloc(sizeof *dev)) == NULL) {
+ puts ("malloc failed\n");
+ return 0;
+ }
+
memset(dev, 0, sizeof *dev);
- sprintf(dev->name, "Au1X00 ETHERNET");
+ sprintf(dev->name, "Au1X00 ethernet");
dev->iobase = 0;
dev->priv = 0;
dev->init = au1x00_init;
diff --git a/cpu/mpc5xxx/fec.c b/cpu/mpc5xxx/fec.c
index 86c8ce6879..2e8e54958f 100644
--- a/cpu/mpc5xxx/fec.c
+++ b/cpu/mpc5xxx/fec.c
@@ -880,8 +880,9 @@ int mpc5xxx_fec_initialize(bd_t * bis)
fec->rbdBase = (FEC_RBD *)(FEC_BD_BASE + FEC_TBD_NUM * sizeof(FEC_TBD));
#if defined(CONFIG_CANMB) || defined(CONFIG_HMI1001) || \
defined(CONFIG_ICECUBE) || defined(CONFIG_INKA4X0) || \
+ defined(CONFIG_MCC200) || defined(CONFIG_O2DNT) || \
defined(CONFIG_PM520) || defined(CONFIG_TOP5200) || \
- defined(CONFIG_TQM5200) || defined(CONFIG_O2DNT)
+ defined(CONFIG_TQM5200)
# ifndef CONFIG_FEC_10MBIT
fec->xcv_type = MII100;
# else
diff --git a/cpu/mpc8260/speed.c b/cpu/mpc8260/speed.c
index a761a178bc..99afe7609f 100644
--- a/cpu/mpc8260/speed.c
+++ b/cpu/mpc8260/speed.c
@@ -163,7 +163,7 @@ int prt_8260_clks (void)
volatile immap_t *immap = (immap_t *) CFG_IMMR;
ulong sccr, dfbrg;
- ulong scmr, corecnf, busdf, cpmdf, plldf, pllmf;
+ ulong scmr, corecnf, busdf, cpmdf, plldf, pllmf, pcidf;
corecnf_t *cp;
sccr = immap->im_clkrst.car_sccr;
@@ -175,6 +175,7 @@ int prt_8260_clks (void)
cpmdf = (scmr & SCMR_CPMDF_MSK) >> SCMR_CPMDF_SHIFT;
plldf = (scmr & SCMR_PLLDF) ? 1 : 0;
pllmf = (scmr & SCMR_PLLMF_MSK) >> SCMR_PLLMF_SHIFT;
+ pcidf = (sccr & SCCR_PCIDF_MSK) >> SCCR_PCIDF_SHIFT;
cp = &corecnf_tab[corecnf];
@@ -204,8 +205,9 @@ int prt_8260_clks (void)
cp->vco_div, cp->freq_60x, cp->freq_core);
printf (" - dfbrg %ld, corecnf 0x%02lx, busdf %ld, cpmdf %ld, "
- "plldf %ld, pllmf %ld\n", dfbrg, corecnf, busdf, cpmdf, plldf,
- pllmf);
+ "plldf %ld, pllmf %ld, pcidf %ld\n",
+ dfbrg, corecnf, busdf, cpmdf,
+ plldf, pllmf, pcidf);
printf (" - vco_out %10ld, scc_clk %10ld, brg_clk %10ld\n",
gd->vco_out, gd->scc_clk, gd->brg_clk);
@@ -215,9 +217,20 @@ int prt_8260_clks (void)
if (sccr & SCCR_PCI_MODE) {
uint pci_div;
-
- pci_div = ( (sccr & SCCR_PCI_MODCK) ? 2 : 1) *
- ( ( (sccr & SCCR_PCIDF_MSK) >> SCCR_PCIDF_SHIFT) + 1);
+ uint pcidf = (sccr & SCCR_PCIDF_MSK) >> SCCR_PCIDF_SHIFT;
+
+ if (sccr & SCCR_PCI_MODCK) {
+ pci_div = 2;
+ if (pcidf == 9) {
+ pci_div *= 5;
+ } else if (pcidf == 0xB) {
+ pci_div *= 6;
+ } else {
+ pci_div *= (pcidf + 1);
+ }
+ } else {
+ pci_div = pcidf + 1;
+ }
printf (" - pci_clk %10ld\n", (gd->cpm_clk * 2) / pci_div);
}
@@ -225,5 +238,3 @@ int prt_8260_clks (void)
return (0);
}
-
-/* ------------------------------------------------------------------------- */
diff --git a/cpu/mpc83xx/cpu.c b/cpu/mpc83xx/cpu.c
index e49e4fe0ee..f24d3a4b1c 100644
--- a/cpu/mpc83xx/cpu.c
+++ b/cpu/mpc83xx/cpu.c
@@ -93,6 +93,8 @@ do_reset (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
/* enable Reset Control Reg */
immap->reset.rpr = 0x52535445;
+ __asm__ __volatile__ ("sync");
+ __asm__ __volatile__ ("isync");
/* confirm Reset Control Reg is enabled */
while(!((immap->reset.rcer) & RCER_CRE));
@@ -189,3 +191,88 @@ ft_cpu_setup(void *blob, bd_t *bd)
#endif
}
#endif
+
+#if defined(CONFIG_DDR_ECC)
+void dma_init(void)
+{
+ volatile immap_t *immap = (immap_t *)CFG_IMMRBAR;
+ volatile dma8349_t *dma = &immap->dma;
+ volatile u32 status = swab32(dma->dmasr0);
+ volatile u32 dmamr0 = swab32(dma->dmamr0);
+
+ debug("DMA-init\n");
+
+ /* initialize DMASARn, DMADAR and DMAABCRn */
+ dma->dmadar0 = (u32)0;
+ dma->dmasar0 = (u32)0;
+ dma->dmabcr0 = 0;
+
+ __asm__ __volatile__ ("sync");
+ __asm__ __volatile__ ("isync");
+
+ /* clear CS bit */
+ dmamr0 &= ~DMA_CHANNEL_START;
+ dma->dmamr0 = swab32(dmamr0);
+ __asm__ __volatile__ ("sync");
+ __asm__ __volatile__ ("isync");
+
+ /* while the channel is busy, spin */
+ while(status & DMA_CHANNEL_BUSY) {
+ status = swab32(dma->dmasr0);
+ }
+
+ debug("DMA-init end\n");
+}
+
+uint dma_check(void)
+{
+ volatile immap_t *immap = (immap_t *)CFG_IMMRBAR;
+ volatile dma8349_t *dma = &immap->dma;
+ volatile u32 status = swab32(dma->dmasr0);
+ volatile u32 byte_count = swab32(dma->dmabcr0);
+
+ /* while the channel is busy, spin */
+ while (status & DMA_CHANNEL_BUSY) {
+ status = swab32(dma->dmasr0);
+ }
+
+ if (status & DMA_CHANNEL_TRANSFER_ERROR) {
+ printf ("DMA Error: status = %x @ %d\n", status, byte_count);
+ }
+
+ return status;
+}
+
+int dma_xfer(void *dest, u32 count, void *src)
+{
+ volatile immap_t *immap = (immap_t *)CFG_IMMRBAR;
+ volatile dma8349_t *dma = &immap->dma;
+ volatile u32 dmamr0;
+
+ /* initialize DMASARn, DMADAR and DMAABCRn */
+ dma->dmadar0 = swab32((u32)dest);
+ dma->dmasar0 = swab32((u32)src);
+ dma->dmabcr0 = swab32(count);
+
+ __asm__ __volatile__ ("sync");
+ __asm__ __volatile__ ("isync");
+
+ /* init direct transfer, clear CS bit */
+ dmamr0 = (DMA_CHANNEL_TRANSFER_MODE_DIRECT |
+ DMA_CHANNEL_SOURCE_ADDRESS_HOLD_8B |
+ DMA_CHANNEL_SOURCE_ADRESSS_HOLD_EN);
+
+ dma->dmamr0 = swab32(dmamr0);
+
+ __asm__ __volatile__ ("sync");
+ __asm__ __volatile__ ("isync");
+
+ /* set CS to start DMA transfer */
+ dmamr0 |= DMA_CHANNEL_START;
+ dma->dmamr0 = swab32(dmamr0);
+ __asm__ __volatile__ ("sync");
+ __asm__ __volatile__ ("isync");
+
+ return ((int)dma_check());
+}
+#endif /*CONFIG_DDR_ECC*/
diff --git a/cpu/mpc83xx/spd_sdram.c b/cpu/mpc83xx/spd_sdram.c
index 63dcd664be..b4012a8ddf 100644
--- a/cpu/mpc83xx/spd_sdram.c
+++ b/cpu/mpc83xx/spd_sdram.c
@@ -1,4 +1,7 @@
/*
+ * (C) Copyright 2006
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
* Copyright 2004 Freescale Semiconductor.
* (C) Copyright 2003 Motorola Inc.
* Xianghua Xiao (X.Xiao@motorola.com)
@@ -63,13 +66,42 @@ picos_to_clk(int picos)
return clks;
}
-unsigned int
-banksize(unsigned char row_dens)
+unsigned int banksize(unsigned char row_dens)
{
return ((row_dens >> 2) | ((row_dens & 3) << 6)) << 24;
}
-long int spd_sdram(int(read_spd)(uint addr))
+int read_spd(uint addr)
+{
+ return ((int) addr);
+}
+
+#undef SPD_DEBUG
+#ifdef SPD_DEBUG
+static void spd_debug(spd_eeprom_t *spd)
+{
+ printf ("\nDIMM type: %-18.18s\n", spd->mpart);
+ printf ("SPD size: %d\n", spd->info_size);
+ printf ("EEPROM size: %d\n", 1 << spd->chip_size);
+ printf ("Memory type: %d\n", spd->mem_type);
+ printf ("Row addr: %d\n", spd->nrow_addr);
+ printf ("Column addr: %d\n", spd->ncol_addr);
+ printf ("# of rows: %d\n", spd->nrows);
+ printf ("Row density: %d\n", spd->row_dens);
+ printf ("# of banks: %d\n", spd->nbanks);
+ printf ("Data width: %d\n",
+ 256 * spd->dataw_msb + spd->dataw_lsb);
+ printf ("Chip width: %d\n", spd->primw);
+ printf ("Refresh rate: %02X\n", spd->refresh);
+ printf ("CAS latencies: %02X\n", spd->cas_lat);
+ printf ("Write latencies: %02X\n", spd->write_lat);
+ printf ("tRP: %d\n", spd->trp);
+ printf ("tRCD: %d\n", spd->trcd);
+ printf ("\n");
+}
+#endif /* SPD_DEBUG */
+
+long int spd_sdram()
{
volatile immap_t *immap = (immap_t *)CFG_IMMRBAR;
volatile ddr8349_t *ddr = &immap->ddr;
@@ -81,10 +113,10 @@ long int spd_sdram(int(read_spd)(uint addr))
unsigned char caslat;
unsigned int trfc, trfc_clk, trfc_low;
-#warning Current spd_sdram does not fit its usage... adjust implementation or API...
-
CFG_READ_SPD(SPD_EEPROM_ADDRESS, 0, 1, (uchar *) & spd, sizeof (spd));
-
+#ifdef SPD_DEBUG
+ spd_debug(&spd);
+#endif
if (spd.nrows > 2) {
puts("DDR:Only two chip selects are supported on ADS.\n");
return 0;
@@ -219,25 +251,31 @@ long int spd_sdram(int(read_spd)(uint addr))
* Only DDR I is supported
* DDR I and II have different mode-register-set definition
*/
-
- /* burst length is always 4 */
switch(caslat) {
case 2:
- ddr->sdram_mode = 0x52; /* 1.5 */
+ tmp = 0x50; /* 1.5 */
break;
case 3:
- ddr->sdram_mode = 0x22; /* 2.0 */
+ tmp = 0x20; /* 2.0 */
break;
case 4:
- ddr->sdram_mode = 0x62; /* 2.5 */
+ tmp = 0x60; /* 2.5 */
break;
case 5:
- ddr->sdram_mode = 0x32; /* 3.0 */
+ tmp = 0x30; /* 3.0 */
break;
default:
puts("DDR:only CAS Latency 1.5, 2.0, 2.5, 3.0 is supported.\n");
return 0;
}
+#if defined (CONFIG_DDR_32BIT)
+ /* set burst length to 8 for 32-bit data path */
+ tmp |= 0x03;
+#else
+ /* set burst length to 4 - default for 64-bit data path */
+ tmp |= 0x02;
+#endif
+ ddr->sdram_mode = tmp;
debug("DDR:sdram_mode=0x%08x\n", ddr->sdram_mode);
switch(spd.refresh) {
@@ -282,8 +320,13 @@ long int spd_sdram(int(read_spd)(uint addr))
*/
#if defined(CONFIG_DDR_ECC)
if (spd.config == 0x02) {
- ddr->err_disable = 0x0000000d;
- ddr->err_sbe = 0x00ff0000;
+ /* disable error detection */
+ ddr->err_disable = ~ECC_ERROR_ENABLE;
+
+ /* set single bit error threshold to maximum value,
+ * reset counter to zero */
+ ddr->err_sbe = (255 << ECC_ERROR_MAN_SBET_SHIFT) |
+ (0 << ECC_ERROR_MAN_SBEC_SHIFT);
}
debug("DDR:err_disable=0x%08x\n", ddr->err_disable);
debug("DDR:err_sbe=0x%08x\n", ddr->err_sbe);
@@ -297,7 +340,8 @@ long int spd_sdram(int(read_spd)(uint addr))
* CLK_ADJST = 2-MCK/MCK_B, is lauched 1/2 of one SDRAM
* clock cycle after address/command
*/
- ddr->sdram_clk_cntl = 0x82000000;
+ /*ddr->sdram_clk_cntl = 0x82000000;*/
+ ddr->sdram_clk_cntl = (DDR_SDRAM_CLK_CNTL_SS_EN|DDR_SDRAM_CLK_CNTL_CLK_ADJUST_05);
/*
* Figure out the settings for the sdram_cfg register. Build up
@@ -311,6 +355,10 @@ long int spd_sdram(int(read_spd)(uint addr))
*/
tmp = 0xc2000000;
+#if defined (CONFIG_DDR_32BIT)
+ /* in 32-Bit mode burst len is 8 beats */
+ tmp |= (SDRAM_CFG_32_BE | SDRAM_CFG_8_BE);
+#endif
/*
* sdram_cfg[3] = RD_EN - registered DIMM enable
* A value of 0x26 indicates micron registered DIMMS (micron.com)
@@ -324,7 +372,7 @@ long int spd_sdram(int(read_spd)(uint addr))
* If the user wanted ECC (enabled via sdram_cfg[2])
*/
if (spd.config == 0x02) {
- tmp |= 0x20000000;
+ tmp |= SDRAM_CFG_ECC_EN;
}
#endif
@@ -340,37 +388,94 @@ long int spd_sdram(int(read_spd)(uint addr))
udelay(500);
debug("DDR:sdram_cfg=0x%08x\n", ddr->sdram_cfg);
-
- return memsize;/*in MBytes*/
+ return memsize; /*in MBytes*/
}
#endif /* CONFIG_SPD_EEPROM */
#if defined(CONFIG_DDR_ECC)
/*
- * Initialize all of memory for ECC, then enable errors.
+ * Use timebase counter, get_timer() is not availabe
+ * at this point of initialization yet.
*/
+static __inline__ unsigned long get_tbms (void)
+{
+ unsigned long tbl;
+ unsigned long tbu1, tbu2;
+ unsigned long ms;
+ unsigned long long tmp;
+
+ ulong tbclk = get_tbclk();
+
+ /* get the timebase ticks */
+ do {
+ asm volatile ("mftbu %0":"=r" (tbu1):);
+ asm volatile ("mftb %0":"=r" (tbl):);
+ asm volatile ("mftbu %0":"=r" (tbu2):);
+ } while (tbu1 != tbu2);
+
+ /* convert ticks to ms */
+ tmp = (unsigned long long)(tbu1);
+ tmp = (tmp << 32);
+ tmp += (unsigned long long)(tbl);
+ ms = tmp/(tbclk/1000);
+
+ return ms;
+}
-void
-ddr_enable_ecc(unsigned int dram_size)
+/*
+ * Initialize all of memory for ECC, then enable errors.
+ */
+//#define CONFIG_DDR_ECC_INIT_VIA_DMA
+void ddr_enable_ecc(unsigned int dram_size)
{
-#ifndef FIXME
- uint *p = 0;
- uint i = 0;
+ uint *p;
volatile immap_t *immap = (immap_t *)CFG_IMMRBAR;
- volatile ccsr_ddr_t *ddr= &immap->im_ddr;
+ volatile ddr8349_t *ddr = &immap->ddr;
+ unsigned long t_start, t_end;
+#if defined(CONFIG_DDR_ECC_INIT_VIA_DMA)
+ uint i;
+#endif
+
+ debug("Initialize a Cachline in DRAM\n");
+ icache_enable();
+#if defined(CONFIG_DDR_ECC_INIT_VIA_DMA)
+ /* Initialise DMA for direct Transfers */
dma_init();
+#endif
+
+ t_start = get_tbms();
- for (*p = 0; p < (uint *)(8 * 1024); p++) {
+#if !defined(CONFIG_DDR_ECC_INIT_VIA_DMA)
+ debug("DDR init: Cache flush method\n");
+ for (p = 0; p < (uint *)(dram_size); p++) {
if (((unsigned int)p & 0x1f) == 0) {
ppcDcbz((unsigned long) p);
}
+
+ /* write pattern to cache and flush */
*p = (unsigned int)0xdeadbeef;
+
if (((unsigned int)p & 0x1c) == 0x1c) {
ppcDcbf((unsigned long) p);
}
}
+#else
+ printf("DDR init: DMA method\n");
+ for (p = 0; p < (uint *)(8 * 1024); p++) {
+ /* zero one data cache line */
+ if (((unsigned int)p & 0x1f) == 0) {
+ ppcDcbz((unsigned long)p);
+ }
+
+ /* write pattern to it and flush */
+ *p = (unsigned int)0xdeadbeef;
+
+ if (((unsigned int)p & 0x1c) == 0x1c) {
+ ppcDcbf((unsigned long)p);
+ }
+ }
/* 8K */
dma_xfer((uint *)0x2000, 0x2000, (uint *)0);
@@ -396,13 +501,31 @@ ddr_enable_ecc(unsigned int dram_size)
for (i = 1; i < dram_size / 0x800000; i++) {
dma_xfer((uint *)(0x800000*i), 0x800000, (uint *)0);
}
-
- /*
- * Enable errors for ECC.
- */
- ddr->err_disable = 0x00000000;
- asm("sync;isync");
#endif
-}
+ t_end = get_tbms();
+ icache_disable();
+
+ debug("\nREADY!!\n");
+ debug("ddr init duration: %ld ms\n", t_end - t_start);
+
+ /* Clear All ECC Errors */
+ if ((ddr->err_detect & ECC_ERROR_DETECT_MME) == ECC_ERROR_DETECT_MME)
+ ddr->err_detect |= ECC_ERROR_DETECT_MME;
+ if ((ddr->err_detect & ECC_ERROR_DETECT_MBE) == ECC_ERROR_DETECT_MBE)
+ ddr->err_detect |= ECC_ERROR_DETECT_MBE;
+ if ((ddr->err_detect & ECC_ERROR_DETECT_SBE) == ECC_ERROR_DETECT_SBE)
+ ddr->err_detect |= ECC_ERROR_DETECT_SBE;
+ if ((ddr->err_detect & ECC_ERROR_DETECT_MSE) == ECC_ERROR_DETECT_MSE)
+ ddr->err_detect |= ECC_ERROR_DETECT_MSE;
+
+ /* Disable ECC-Interrupts */
+ ddr->err_int_en &= ECC_ERR_INT_DISABLE;
+
+ /* Enable errors for ECC */
+ ddr->err_disable &= ECC_ERROR_ENABLE;
+
+ __asm__ __volatile__ ("sync");
+ __asm__ __volatile__ ("isync");
+}
#endif /* CONFIG_DDR_ECC */
diff --git a/cpu/mpc83xx/start.S b/cpu/mpc83xx/start.S
index 46c748f790..6e02cce799 100644
--- a/cpu/mpc83xx/start.S
+++ b/cpu/mpc83xx/start.S
@@ -796,7 +796,7 @@ icache_disable:
.globl icache_status
icache_status:
mfspr r3, HID0
- rlwinm r3, r3, HID0_ICE_SHIFT, 31, 31
+ rlwinm r3, r3, (31 - HID0_ICE_SHIFT + 1), 31, 31
blr
.globl dcache_enable
@@ -828,7 +828,7 @@ dcache_disable:
.globl dcache_status
dcache_status:
mfspr r3, HID0
- rlwinm r3, r3, HID0_DCE_SHIFT, 31, 31
+ rlwinm r3, r3, (31 - HID0_DCE_SHIFT + 1), 31, 31
blr
.globl get_pvr
@@ -836,6 +836,40 @@ get_pvr:
mfspr r3, PVR
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
+
/*-------------------------------------------------------------------*/
/*
diff --git a/cpu/mpc85xx/start.S b/cpu/mpc85xx/start.S
index 7ac65736bc..f96a4c3f8b 100644
--- a/cpu/mpc85xx/start.S
+++ b/cpu/mpc85xx/start.S
@@ -715,7 +715,7 @@ icache_disable:
.globl icache_status
icache_status:
mfspr r3,L1CSR1
- srwi r3, r3, 31 /* >>31 => select bit 0 */
+ andi. r3,r3,1
blr
.globl dcache_enable
@@ -748,7 +748,7 @@ dcache_disable:
.globl dcache_status
dcache_status:
mfspr r3,L1CSR0
- srwi r3, r3, 31 /* >>31 => select bit 0 */
+ andi. r3,r3,1
blr
.globl get_pir
diff --git a/cpu/mpc8xx/cpu.c b/cpu/mpc8xx/cpu.c
index 4a32986a2e..c4a0cba13a 100644
--- a/cpu/mpc8xx/cpu.c
+++ b/cpu/mpc8xx/cpu.c
@@ -69,14 +69,15 @@ static int check_CPU (long clock, uint pvr, uint immr)
k = (immr << 16) | *((ushort *) & immap->im_cpm.cp_dparam[0xB0]);
m = 0;
+ suf = "";
/*
* Some boards use sockets so different CPUs can be used.
* We have to check chip version in run time.
*/
switch (k) {
- case 0x00020001: pre = 'P'; suf = ""; break;
- case 0x00030001: suf = ""; break;
+ case 0x00020001: pre = 'P'; break;
+ case 0x00030001: break;
case 0x00120003: suf = "A"; break;
case 0x00130003: suf = "A3"; break;
@@ -93,7 +94,11 @@ static int check_CPU (long clock, uint pvr, uint immr)
/* this value is not documented anywhere */
case 0x40000000: pre = 'P'; suf = "D"; m = 1; break;
/* MPC866P/MPC866T/MPC859T/MPC859DSL/MPC852T */
- case 0x08000003: pre = 'M'; suf = ""; m = 1;
+ case 0x08010004: /* Rev. A.0 */
+ suf = "A";
+ /* fall through */
+ case 0x08000003: /* Rev. 0.3 */
+ pre = 'M'; m = 1;
if (id_str == NULL)
id_str =
# if defined(CONFIG_MPC852T)
diff --git a/cpu/ppc4xx/405gp_pci.c b/cpu/ppc4xx/405gp_pci.c
index f6b29e9d6e..947b85e28a 100644
--- a/cpu/ppc4xx/405gp_pci.c
+++ b/cpu/ppc4xx/405gp_pci.c
@@ -373,7 +373,7 @@ void pci_405gp_setup_vga(struct pci_controller *hose, pci_dev_t dev,
{
unsigned int cmdstat = 0;
- pciauto_setup_device(hose, dev, 6, hose->pci_mem, hose->pci_io);
+ pciauto_setup_device(hose, dev, 6, hose->pci_mem, hose->pci_prefetch, hose->pci_io);
/* always enable io space on vga boards */
pci_hose_read_config_dword(hose, dev, PCI_COMMAND, &cmdstat);
diff --git a/cpu/ppc4xx/start.S b/cpu/ppc4xx/start.S
index 48b430d14d..948de43d14 100644
--- a/cpu/ppc4xx/start.S
+++ b/cpu/ppc4xx/start.S
@@ -340,23 +340,6 @@ _start:
mtspr tcr,r0 /* disable all */
mtspr esr,r0 /* clear exception syndrome register */
mtxer r0 /* clear integer exception register */
-#if !defined(CONFIG_440GX)
- lis r1,0x0002 /* set CE bit (Critical Exceptions) */
- ori r1,r1,0x1000 /* set ME bit (Machine Exceptions) */
- mtmsr r1 /* change MSR */
-#elif !defined(CONFIG_440EP) && !defined(CONFIG_440GR)
- bl __440gx_msr_set
- b __440gx_msr_continue
-
-__440gx_msr_set:
- lis r1, 0x0002 /* set CE bit (Critical Exceptions) */
- ori r1,r1,0x1000 /* set ME bit (Machine Exceptions) */
- mtspr srr1,r1
- mflr r1
- mtspr srr0,r1
- rfi
-__440gx_msr_continue:
-#endif
/*----------------------------------------------------------------*/
/* Debug setup -- some (not very good) ice's need an event*/
@@ -458,9 +441,6 @@ __440gx_msr_continue:
mtspr esr,r0 /* clear Exception Syndrome Reg */
mttcr r0 /* timer control register */
mtexier r0 /* disable all interrupts */
- addi r4,r0,0x1000 /* set ME bit (Machine Exceptions) */
- oris r4,r4,0x2 /* set CE bit (Critical Exceptions) */
- mtmsr r4 /* change MSR */
addis r4,r0,0xFFFF /* set r4 to 0xFFFFFFFF (status in the */
ori r4,r4,0xFFFF /* dbsr is cleared by setting bits to 1) */
mtdbsr r4 /* clear/reset the dbsr */
@@ -571,9 +551,6 @@ __440gx_msr_continue:
mttcr r4 /* clear Timer Control Reg */
mtxer r4 /* clear Fixed-Point Exception Reg */
mtevpr r4 /* clear Exception Vector Prefix Reg */
- addi r4,r0,0x1000 /* set ME bit (Machine Exceptions) */
- oris r4,r4,0x0002 /* set CE bit (Critical Exceptions) */
- mtmsr r4 /* change MSR */
addi r4,r0,(0xFFFF-0x10000) /* set r4 to 0xFFFFFFFF (status in the */
/* dbsr is cleared by setting bits to 1) */
mtdbsr r4 /* clear/reset the dbsr */
@@ -1428,6 +1405,24 @@ trap_init:
cmplw 0, r7, r8
blt 4b
+#if !defined(CONFIG_440_GX)
+ 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
+
+__440gx_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:
+#endif
+
mtlr r4 /* restore link register */
blr
diff --git a/cpu/pxa/cpu.c b/cpu/pxa/cpu.c
index d1551ddc38..b33d674110 100644
--- a/cpu/pxa/cpu.c
+++ b/cpu/pxa/cpu.c
@@ -143,6 +143,7 @@ int dcache_status (void)
return 0; /* always off */
}
+#ifndef CONFIG_CPU_MONAHANS
void set_GPIO_mode(int gpio_mode)
{
int gpio = gpio_mode & GPIO_MD_MASK_NR;
@@ -160,3 +161,4 @@ void set_GPIO_mode(int gpio_mode)
gafr = GAFR(gpio) & ~(0x3 << (((gpio) & 0xf)*2));
GAFR(gpio) = gafr | (fn << (((gpio) & 0xf)*2));
}
+#endif /* CONFIG_CPU_MONAHANS */
diff --git a/cpu/pxa/serial.c b/cpu/pxa/serial.c
index cedebfe496..9bf2a7cf4f 100644
--- a/cpu/pxa/serial.c
+++ b/cpu/pxa/serial.c
@@ -54,7 +54,11 @@ void serial_setbrg (void)
hang ();
#ifdef CONFIG_FFUART
+#ifdef CONFIG_CPU_MONAHANS
+ CKENA |= CKENA_22_FFUART;
+#else
CKEN |= CKEN6_FFUART;
+#endif /* CONFIG_CPU_MONAHANS */
FFIER = 0; /* Disable for now */
FFFCR = 0; /* No fifos enabled */
@@ -68,7 +72,11 @@ void serial_setbrg (void)
FFIER = IER_UUE; /* Enable FFUART */
#elif defined(CONFIG_BTUART)
+#ifdef CONFIG_CPU_MONAHANS
+ CKENA |= CKENA_21_BTUART;
+#else
CKEN |= CKEN7_BTUART;
+#endif /* CONFIG_CPU_MONAHANS */
BTIER = 0;
BTFCR = 0;
@@ -82,7 +90,11 @@ void serial_setbrg (void)
BTIER = IER_UUE; /* Enable BFUART */
#elif defined(CONFIG_STUART)
+#ifdef CONFIG_CPU_MONAHANS
+ CKENA |= CKENA_23_STUART;
+#else
CKEN |= CKEN5_STUART;
+#endif /* CONFIG_CPU_MONAHANS */
STIER = 0;
STFCR = 0;
diff --git a/cpu/pxa/start.S b/cpu/pxa/start.S
index a8cc0800b0..9541c9b2b9 100644
--- a/cpu/pxa/start.S
+++ b/cpu/pxa/start.S
@@ -6,8 +6,8 @@
* Copyright (C) 2000 Wolfgang Denk <wd@denx.de>
* Copyright (C) 2001 Alex Zuepke <azu@sysgo.de>
* Copyright (C) 2002 Kyle Harris <kharris@nexus-tech.net>
- * Copyright (C) 2003 Robert Schwebel <r.schwebel@pengutronix.de>
- * Copyright (C) 2003 Kai-Uwe Bloem <kai-uwe.bloem@auerswald.de>
+ * Copyright (C) 2003 Robert Schwebel <r.schwebel@pengutronix.de>
+ * Copyright (C) 2003 Kai-Uwe Bloem <kai-uwe.bloem@auerswald.de>
*
* See file CREDITS for list of people who contributed to this
* project.
@@ -30,6 +30,7 @@
#include <config.h>
#include <version.h>
+#include <asm/arch/pxa-regs.h>
.globl _start
_start: b reset
@@ -116,13 +117,13 @@ reset:
relocate: /* relocate U-Boot to RAM */
adr r0, _start /* r0 <- current position of code */
ldr r1, _TEXT_BASE /* test if we run from flash or RAM */
- cmp r0, r1 /* don't reloc during debug */
- beq stack_setup
+ cmp r0, r1 /* don't reloc during debug */
+ beq stack_setup
ldr r2, _armboot_start
ldr r3, _bss_start
- sub r2, r3, r2 /* r2 <- size of armboot */
- add r2, r0, r2 /* r2 <- source end address */
+ sub r2, r3, r2 /* r2 <- size of armboot */
+ add r2, r0, r2 /* r2 <- source end address */
copy_loop:
ldmia r0!, {r3-r10} /* copy from source address [r0] */
@@ -134,19 +135,19 @@ copy_loop:
/* Set up the stack */
stack_setup:
ldr r0, _TEXT_BASE /* upper 128 KiB: relocated uboot */
- sub r0, r0, #CFG_MALLOC_LEN /* malloc area */
- sub r0, r0, #CFG_GBL_DATA_SIZE /* bdinfo */
+ sub r0, r0, #CFG_MALLOC_LEN /* malloc area */
+ sub r0, r0, #CFG_GBL_DATA_SIZE /* bdinfo */
#ifdef CONFIG_USE_IRQ
sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)
#endif
sub sp, r0, #12 /* leave 3 words for abort-stack */
clear_bss:
- ldr r0, _bss_start /* find start of bss segment */
- ldr r1, _bss_end /* stop here */
- mov r2, #0x00000000 /* clear */
+ ldr r0, _bss_start /* find start of bss segment */
+ ldr r1, _bss_end /* stop here */
+ mov r2, #0x00000000 /* clear */
-clbss_l:str r2, [r0] /* clear loop... */
+clbss_l:str r2, [r0] /* clear loop... */
add r0, r0, #4
cmp r0, r1
ble clbss_l
@@ -164,8 +165,16 @@ _start_armboot: .word start_armboot
/* - setup memory timing */
/* */
/****************************************************************************/
+/* mk@tbd: Fix this! */
+#ifdef CONFIG_CPU_MONAHANS
+#undef ICMR
+#undef OSMR3
+#undef OSCR
+#undef OWER
+#undef OIER
+#endif
-/* Interrupt-Controller base address */
+/* Interrupt-Controller base address */
IC_BASE: .word 0x40d00000
#define ICMR 0x04
@@ -180,7 +189,7 @@ OSTIMER_BASE: .word 0x40a00000
#define OWER 0x18
#define OIER 0x1C
-/* Clock Manager Registers */
+/* Clock Manager Registers */
#ifdef CFG_CPUSPEED
CC_BASE: .word 0x41300000
#define CCCR 0x00
@@ -189,25 +198,44 @@ cpuspeed: .word CFG_CPUSPEED
#error "You have to define CFG_CPUSPEED!!"
#endif
-
- /* RS: ??? */
- .macro CPWAIT
- mrc p15,0,r0,c2,c0,0
- mov r0,r0
+ /* takes care the CP15 update has taken place */
+ .macro CPWAIT reg
+ mrc p15,0,\reg,c2,c0,0
+ mov \reg,\reg
sub pc,pc,#4
.endm
-
cpu_init_crit:
/* mask all IRQs */
+#ifndef CONFIG_CPU_MONAHANS
ldr r0, IC_BASE
mov r1, #0x00
str r1, [r0, #ICMR]
+#else
+ /* Step 1 - Enable CP6 permission */
+ mrc p15, 0, r1, c15, c1, 0 @ read CPAR
+ orr r1, r1, #0x40
+ mcr p15, 0, r1, c15, c1, 0
+ CPWAIT r1
+
+ /* Step 2 - Mask ICMR & ICMR2 */
+ mov r1, #0
+ mcr p6, 0, r1, c1, c0, 0 @ ICMR
+ mcr p6, 0, r1, c7, c0, 0 @ ICMR2
+
+ /* turn off all clocks but the ones we will definitly require */
+ ldr r1, =CKENA
+ ldr r2, =(CKENA_22_FFUART | CKENA_10_SRAM | CKENA_9_SMC | CKENA_8_DMC)
+ str r2, [r1]
+ ldr r1, =CKENB
+ ldr r2, =(CKENB_6_IRQ)
+ str r2, [r1]
+#endif
-#if defined(CFG_CPUSPEED)
-
- /* set clock speed */
+#ifndef CONFIG_CPU_MONAHANS
+#ifdef CFG_CPUSPEED
+ /* set clock speed tbd@mk: required for monahans? */
ldr r0, CC_BASE
ldr r1, cpuspeed
str r1, [r0, #CCCR]
@@ -215,7 +243,9 @@ cpu_init_crit:
mcr p14, 0, r0, c6, c0, 0
setspeed_done:
-#endif
+
+#endif /* CFG_CPUSPEED */
+#endif /* CONFIG_CPU_MONAHANS */
/*
* before relocating, we have to setup RAM timing
@@ -227,19 +257,21 @@ setspeed_done:
mov lr, ip
/* Memory interfaces are working. Disable MMU and enable I-cache. */
+ /* mk: hmm, this is not in the monahans docs, leave it now but
+ * check here if it doesn't work :-) */
ldr r0, =0x2001 /* enable access to all coproc. */
mcr p15, 0, r0, c15, c1, 0
- CPWAIT
+ CPWAIT r0
mcr p15, 0, r0, c7, c10, 4 /* drain the write & fill buffers */
- CPWAIT
+ CPWAIT r0
mcr p15, 0, r0, c7, c7, 0 /* flush Icache, Dcache and BTB */
- CPWAIT
+ CPWAIT r0
mcr p15, 0, r0, c8, c7, 0 /* flush instuction and data TLBs */
- CPWAIT
+ CPWAIT r0
/* Enable the Icache */
/*
@@ -292,7 +324,7 @@ setspeed_done:
ldr r2, _armboot_start
sub r2, r2, #(CONFIG_STACKSIZE+CFG_MALLOC_LEN)
- sub r2, r2, #(CFG_GBL_DATA_SIZE+8) @ set base 2 words into abort stack
+ sub r2, r2, #(CFG_GBL_DATA_SIZE+8) @ set base 2 words into abort stack
ldmia r2, {r2 - r4} /* get pc, cpsr, old_r0 */
add r0, sp, #S_FRAME_SIZE /* restore sp_SVC */
@@ -419,17 +451,17 @@ fiq:
#endif
/****************************************************************************/
-/* */
+/* */
/* Reset function: the PXA250 doesn't have a reset function, so we have to */
-/* perform a watchdog timeout for a soft reset. */
-/* */
+/* perform a watchdog timeout for a soft reset. */
+/* */
/****************************************************************************/
.align 5
.globl reset_cpu
- /* FIXME: this code is PXA250 specific. How is this handled on */
- /* other XScale processors? */
+ /* FIXME: this code is PXA250 specific. How is this handled on */
+ /* other XScale processors? */
reset_cpu:
@@ -437,13 +469,13 @@ reset_cpu:
ldr r0, OSTIMER_BASE
ldr r1, [r0, #OWER]
- orr r1, r1, #0x0001 /* bit0: WME */
+ orr r1, r1, #0x0001 /* bit0: WME */
str r1, [r0, #OWER]
/* OS timer does only wrap every 1165 seconds, so we have to set */
- /* the match register as well. */
+ /* the match register as well. */
- ldr r1, [r0, #OSCR] /* read OS timer */
+ ldr r1, [r0, #OSCR] /* read OS timer */
add r1, r1, #0x800 /* let OSMR3 match after */
add r1, r1, #0x800 /* 4096*(1/3.6864MHz)=1ms */
str r1, [r0, #OSMR3]