diff options
Diffstat (limited to 'cpu')
119 files changed, 5049 insertions, 777 deletions
diff --git a/cpu/74xx_7xx/cpu.c b/cpu/74xx_7xx/cpu.c index 629ed66..706c880 100644 --- a/cpu/74xx_7xx/cpu.c +++ b/cpu/74xx_7xx/cpu.c @@ -49,6 +49,8 @@ #include "../board/MAI/AmigaOneG3SE/memio.h" #endif +DECLARE_GLOBAL_DATA_PTR; + cpu_t get_cpu_type(void) { @@ -111,8 +113,6 @@ get_cpu_type(void) #if !defined(CONFIG_BAB7xx) int checkcpu (void) { - DECLARE_GLOBAL_DATA_PTR; - uint type = get_cpu_type(); uint pvr = get_pvr(); ulong clock = gd->cpu_clk; @@ -258,8 +258,6 @@ do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) #ifdef CONFIG_AMIGAONEG3SE unsigned long get_tbclk(void) { - DECLARE_GLOBAL_DATA_PTR; - return (gd->bus_clk / 4); } #else /* ! CONFIG_AMIGAONEG3SE */ diff --git a/cpu/74xx_7xx/speed.c b/cpu/74xx_7xx/speed.c index f94ff78..2dc5107 100644 --- a/cpu/74xx_7xx/speed.c +++ b/cpu/74xx_7xx/speed.c @@ -29,6 +29,8 @@ #include "../board/MAI/AmigaOneG3SE/via686.h" #endif +DECLARE_GLOBAL_DATA_PTR; + static const int hid1_multipliers_x_10[] = { 25, /* 0000 - 2.5x */ 75, /* 0001 - 7.5x */ @@ -85,7 +87,6 @@ static const int hid1_fx_multipliers_x_10[] = { int get_clocks (void) { - DECLARE_GLOBAL_DATA_PTR; ulong clock = 0; /* calculate the clock frequency based upon the CPU type */ diff --git a/cpu/74xx_7xx/traps.c b/cpu/74xx_7xx/traps.c index ac5f8bf..50c5eeb 100644 --- a/cpu/74xx_7xx/traps.c +++ b/cpu/74xx_7xx/traps.c @@ -36,6 +36,10 @@ #include <command.h> #include <asm/processor.h> +#ifdef CONFIG_AMIGAONEG3SE +DECLARE_GLOBAL_DATA_PTR; +#endif + #if (CONFIG_COMMANDS & CFG_CMD_KGDB) int (*debugger_exception_handler)(struct pt_regs *) = 0; #endif @@ -58,9 +62,6 @@ extern unsigned long search_exception_table(unsigned long); void print_backtrace(unsigned long *sp) { -#ifdef CONFIG_AMIGAONEG3SE - DECLARE_GLOBAL_DATA_PTR; -#endif int cnt = 0; unsigned long i; diff --git a/cpu/arm1136/cpu.c b/cpu/arm1136/cpu.c index 85a4849..fa78eaa 100644 --- a/cpu/arm1136/cpu.c +++ b/cpu/arm1136/cpu.c @@ -37,6 +37,10 @@ #include <asm/arch/omap2420.h> #endif +#ifdef CONFIG_USE_IRQ +DECLARE_GLOBAL_DATA_PTR; +#endif + /* read co-processor 15, register #1 (control register) */ static unsigned long read_p15_c1 (void) { @@ -88,8 +92,6 @@ int cpu_init (void) * setup up stacks if necessary */ #ifdef CONFIG_USE_IRQ - DECLARE_GLOBAL_DATA_PTR; - IRQ_STACK_START = _armboot_start - CFG_MALLOC_LEN - CFG_GBL_DATA_SIZE - 4; FIQ_STACK_START = IRQ_STACK_START - CONFIG_STACKSIZE_IRQ; #endif diff --git a/cpu/arm720t/serial.c b/cpu/arm720t/serial.c index 0f99979..054bab9 100644 --- a/cpu/arm720t/serial.c +++ b/cpu/arm720t/serial.c @@ -34,10 +34,10 @@ #include <clps7111.h> +DECLARE_GLOBAL_DATA_PTR; + void serial_setbrg (void) { - DECLARE_GLOBAL_DATA_PTR; - unsigned int reg = 0; switch (gd->baudrate) { diff --git a/cpu/arm720t/serial_netarm.c b/cpu/arm720t/serial_netarm.c index 5ad98f0..bc6bf30 100644 --- a/cpu/arm720t/serial_netarm.c +++ b/cpu/arm720t/serial_netarm.c @@ -34,6 +34,8 @@ #include <asm/hardware.h> +DECLARE_GLOBAL_DATA_PTR; + #define PORTA (*(volatile unsigned int *)(NETARM_GEN_MODULE_BASE + NETARM_GEN_PORTA)) #if !defined(CONFIG_NETARM_NS7520) #define PORTB (*(volatile unsigned int *)(NETARM_GEN_MODULE_BASE + NETARM_GEN_PORTB)) @@ -67,9 +69,6 @@ extern void _netarm_led_FAIL1(void); */ void serial_setbrg (void) { - /* get the gd pointer */ - DECLARE_GLOBAL_DATA_PTR; - /* set 0 ... make sure pins are configured for serial */ #if !defined(CONFIG_NETARM_NS7520) PORTA = PORTB = diff --git a/cpu/arm920t/at91rm9200/i2c.c b/cpu/arm920t/at91rm9200/i2c.c index 2565998..826cea8 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/at91rm9200/serial.c b/cpu/arm920t/at91rm9200/serial.c index a281932..d563445 100644 --- a/cpu/arm920t/at91rm9200/serial.c +++ b/cpu/arm920t/at91rm9200/serial.c @@ -33,6 +33,8 @@ #include <asm/io.h> #include <asm/arch/hardware.h> +DECLARE_GLOBAL_DATA_PTR; + #if !defined(CONFIG_DBGU) && !defined(CONFIG_USART0) && !defined(CONFIG_USART1) #error must define one of CONFIG_DBGU or CONFIG_USART0 or CONFIG_USART1 #endif @@ -50,7 +52,6 @@ AT91PS_USART us = (AT91PS_USART) AT91C_BASE_US1; void serial_setbrg (void) { - DECLARE_GLOBAL_DATA_PTR; int baudrate; if ((baudrate = gd->baudrate) <= 0) diff --git a/cpu/arm920t/cpu.c b/cpu/arm920t/cpu.c index 2f7963d..f93bf57 100644 --- a/cpu/arm920t/cpu.c +++ b/cpu/arm920t/cpu.c @@ -33,6 +33,10 @@ #include <command.h> #include <arm920t.h> +#ifdef CONFIG_USE_IRQ +DECLARE_GLOBAL_DATA_PTR; +#endif + /* read co-processor 15, register #1 (control register) */ static unsigned long read_p15_c1 (void) { @@ -91,8 +95,6 @@ int cpu_init (void) * setup up stacks if necessary */ #ifdef CONFIG_USE_IRQ - DECLARE_GLOBAL_DATA_PTR; - IRQ_STACK_START = _armboot_start - CFG_MALLOC_LEN - CFG_GBL_DATA_SIZE - 4; FIQ_STACK_START = IRQ_STACK_START - CONFIG_STACKSIZE_IRQ; #endif diff --git a/cpu/arm920t/ks8695/serial.c b/cpu/arm920t/ks8695/serial.c index 0dd91e7..aacd1be 100644 --- a/cpu/arm920t/ks8695/serial.c +++ b/cpu/arm920t/ks8695/serial.c @@ -25,6 +25,8 @@ #error "Bad: you didn't configure serial ..." #endif +DECLARE_GLOBAL_DATA_PTR; + /* * Define the UART hardware register access structure. */ @@ -54,7 +56,6 @@ int serial_console = 1; void serial_setbrg(void) { - DECLARE_GLOBAL_DATA_PTR; volatile struct ks8695uart *uartp = KS8695_UART_ADDR; /* Set to global baud rate and 8 data bits, no parity, 1 stop bit*/ diff --git a/cpu/arm920t/s3c24x0/serial.c b/cpu/arm920t/s3c24x0/serial.c index 8327443..36851ad 100644 --- a/cpu/arm920t/s3c24x0/serial.c +++ b/cpu/arm920t/s3c24x0/serial.c @@ -27,6 +27,8 @@ #include <s3c2410.h> #endif +DECLARE_GLOBAL_DATA_PTR; + #ifdef CONFIG_SERIAL1 #define UART_NR S3C24X0_UART0 @@ -48,7 +50,6 @@ void serial_setbrg (void) { - DECLARE_GLOBAL_DATA_PTR; S3C24X0_UART * const uart = S3C24X0_GetBase_UART(UART_NR); int i; unsigned int reg = 0; diff --git a/cpu/arm920t/s3c24x0/usb_ohci.c b/cpu/arm920t/s3c24x0/usb_ohci.c index b4cc744..869ca79 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/arm920t/start.S b/cpu/arm920t/start.S index 4603cf5..346f0d0 100644 --- a/cpu/arm920t/start.S +++ b/cpu/arm920t/start.S @@ -237,6 +237,7 @@ _start_armboot: .word start_armboot */ +#ifndef CONFIG_SKIP_LOWLEVEL_INIT cpu_init_crit: /* * flush v4 I/D caches @@ -264,7 +265,7 @@ cpu_init_crit: bl lowlevel_init mov lr, ip mov pc, lr - +#endif /* CONFIG_SKIP_LOWLEVEL_INIT */ /* ************************************************************************* diff --git a/cpu/arm925t/cpu.c b/cpu/arm925t/cpu.c index c1c6b03..d85b7fa 100644 --- a/cpu/arm925t/cpu.c +++ b/cpu/arm925t/cpu.c @@ -33,6 +33,10 @@ #include <command.h> #include <arm925t.h> +#ifdef CONFIG_USE_IRQ +DECLARE_GLOBAL_DATA_PTR; +#endif + /* read co-processor 15, register #1 (control register) */ static unsigned long read_p15_c1 (void) { @@ -91,8 +95,6 @@ int cpu_init (void) * setup up stacks if necessary */ #ifdef CONFIG_USE_IRQ - DECLARE_GLOBAL_DATA_PTR; - IRQ_STACK_START = _armboot_start - CFG_MALLOC_LEN - CFG_GBL_DATA_SIZE - 4; FIQ_STACK_START = IRQ_STACK_START - CONFIG_STACKSIZE_IRQ; #endif diff --git a/cpu/arm926ejs/cpu.c b/cpu/arm926ejs/cpu.c index f57c5a5..722732e 100644 --- a/cpu/arm926ejs/cpu.c +++ b/cpu/arm926ejs/cpu.c @@ -33,6 +33,10 @@ #include <command.h> #include <arm926ejs.h> +#ifdef CONFIG_USE_IRQ +DECLARE_GLOBAL_DATA_PTR; +#endif + /* read co-processor 15, register #1 (control register) */ static unsigned long read_p15_c1 (void) { @@ -91,8 +95,6 @@ int cpu_init (void) * setup up stacks if necessary */ #ifdef CONFIG_USE_IRQ - DECLARE_GLOBAL_DATA_PTR; - IRQ_STACK_START = _armboot_start - CFG_MALLOC_LEN - CFG_GBL_DATA_SIZE - 4; FIQ_STACK_START = IRQ_STACK_START - CONFIG_STACKSIZE_IRQ; #endif diff --git a/cpu/arm926ejs/interrupts.c b/cpu/arm926ejs/interrupts.c index 0457bff..9cac969 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 0000000..f9d3378 --- /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 0000000..e898902 --- /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 0000000..a2a9133 --- /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 fc6b20b..725c663 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 0000000..f9d3378 --- /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 0000000..e898902 --- /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 0000000..32872d2 --- /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/arm946es/cpu.c b/cpu/arm946es/cpu.c index ba0a4e4..4c63a8d 100644 --- a/cpu/arm946es/cpu.c +++ b/cpu/arm946es/cpu.c @@ -33,6 +33,10 @@ #include <command.h> #include <arm946es.h> +#ifdef CONFIG_USE_IRQ +DECLARE_GLOBAL_DATA_PTR; +#endif + /* read co-processor 15, register #1 (control register) */ static unsigned long read_p15_c1 (void) { @@ -91,8 +95,6 @@ int cpu_init (void) * setup up stacks if necessary */ #ifdef CONFIG_USE_IRQ - DECLARE_GLOBAL_DATA_PTR; - IRQ_STACK_START = _armboot_start - CFG_MALLOC_LEN - CFG_GBL_DATA_SIZE - 4; FIQ_STACK_START = IRQ_STACK_START - CONFIG_STACKSIZE_IRQ; #endif diff --git a/cpu/arm_intcm/cpu.c b/cpu/arm_intcm/cpu.c index d03b09d..e2309f8 100644 --- a/cpu/arm_intcm/cpu.c +++ b/cpu/arm_intcm/cpu.c @@ -33,14 +33,16 @@ #include <common.h> #include <command.h> +#ifdef CONFIG_USE_IRQ +DECLARE_GLOBAL_DATA_PTR; +#endif + int cpu_init (void) { /* * setup up stacks if necessary */ #ifdef CONFIG_USE_IRQ - DECLARE_GLOBAL_DATA_PTR; - IRQ_STACK_START = _armboot_start - CFG_MALLOC_LEN - CFG_GBL_DATA_SIZE - 4; FIQ_STACK_START = IRQ_STACK_START - CONFIG_STACKSIZE_IRQ; #endif diff --git a/cpu/bf533/Makefile b/cpu/bf533/Makefile new file mode 100644 index 0000000..c63a8f6 --- /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 0000000..d430e6c --- /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 0000000..8fac402 --- /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 0000000..a9d529e --- /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 0000000..61be5bb --- /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 0000000..7a0b048 --- /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 0000000..78e2b96 --- /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 0000000..7ec3387 --- /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 0000000..9fbdefc --- /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 0000000..e780dc6 --- /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 0000000..df1a25e --- /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 0000000..859f4b2 --- /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 0000000..7b43ffd --- /dev/null +++ b/cpu/bf533/serial.c @@ -0,0 +1,195 @@ +/* + * 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" + +DECLARE_GLOBAL_DATA_PTR; + +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; + + 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 0000000..6d58575 --- /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 0000000..6f48124 --- /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 0000000..37470d5 --- /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/i386/sc520.c b/cpu/i386/sc520.c index 689e775..c83f0bb 100644 --- a/cpu/i386/sc520.c +++ b/cpu/i386/sc520.c @@ -36,6 +36,8 @@ #include <asm/pci.h> #include <asm/ic/sc520.h> +DECLARE_GLOBAL_DATA_PTR; + /* * utility functions for boards based on the AMD sc520 * @@ -93,8 +95,6 @@ u32 read_mmcr_long(u16 mmcr) void init_sc520(void) { - DECLARE_GLOBAL_DATA_PTR; - /* Set the UARTxCTL register at it's slower, * baud clock giving us a 1.8432 MHz reference */ @@ -139,7 +139,6 @@ void init_sc520(void) unsigned long init_sc520_dram(void) { - DECLARE_GLOBAL_DATA_PTR; bd_t *bd = gd->bd; u32 dram_present=0; diff --git a/cpu/i386/serial.c b/cpu/i386/serial.c index db13008..e7299a7 100644 --- a/cpu/i386/serial.c +++ b/cpu/i386/serial.c @@ -55,6 +55,8 @@ #include <malloc.h> #endif +DECLARE_GLOBAL_DATA_PTR; + #define UART_RBR 0x00 #define UART_THR 0x00 #define UART_IER 0x01 @@ -126,13 +128,9 @@ static int serial_div(int baudrate) int serial_init(void) { - DECLARE_GLOBAL_DATA_PTR; - volatile char val; - int bdiv = serial_div(gd->baudrate); - outb(0x80, UART0_BASE + UART_LCR); /* set DLAB bit */ outb(bdiv, UART0_BASE + UART_DLL); /* set baudrate divisor */ outb(bdiv >> 8, UART0_BASE + UART_DLM);/* set baudrate divisor */ @@ -150,8 +148,6 @@ int serial_init(void) void serial_setbrg(void) { - DECLARE_GLOBAL_DATA_PTR; - unsigned short bdiv; bdiv = serial_div(gd->baudrate); @@ -410,8 +406,6 @@ int serial_buffered_tstc(void) #if (CONFIG_KGDB_SER_INDEX & 2) void kgdb_serial_init(void) { - DECLARE_GLOBAL_DATA_PTR; - volatile char val; bdiv = serial_div (CONFIG_KGDB_BAUDRATE); diff --git a/cpu/ixp/cpu.c b/cpu/ixp/cpu.c index 9383473..2a2bd50 100644 --- a/cpu/ixp/cpu.c +++ b/cpu/ixp/cpu.c @@ -34,14 +34,16 @@ #include <command.h> #include <asm/arch/ixp425.h> +#ifdef CONFIG_USE_IRQ +DECLARE_GLOBAL_DATA_PTR; +#endif + int cpu_init (void) { /* * setup up stacks if necessary */ #ifdef CONFIG_USE_IRQ - DECLARE_GLOBAL_DATA_PTR; - IRQ_STACK_START = _armboot_start - CFG_MALLOC_LEN - CFG_GBL_DATA_SIZE - 4; FIQ_STACK_START = IRQ_STACK_START - CONFIG_STACKSIZE_IRQ; #endif diff --git a/cpu/ixp/serial.c b/cpu/ixp/serial.c index aea0cf8..2015958 100644 --- a/cpu/ixp/serial.c +++ b/cpu/ixp/serial.c @@ -31,10 +31,10 @@ #include <common.h> #include <asm/arch/ixp425.h> +DECLARE_GLOBAL_DATA_PTR; + void serial_setbrg (void) { - DECLARE_GLOBAL_DATA_PTR; - unsigned int quot = 0; int uart = CFG_IXP425_CONSOLE; diff --git a/cpu/lh7a40x/cpu.c b/cpu/lh7a40x/cpu.c index 718f253..578eb73 100644 --- a/cpu/lh7a40x/cpu.c +++ b/cpu/lh7a40x/cpu.c @@ -33,6 +33,10 @@ #include <command.h> #include <arm920t.h> +#ifdef CONFIG_USE_IRQ +DECLARE_GLOBAL_DATA_PTR; +#endif + /* read co-processor 15, register #1 (control register) */ static unsigned long read_p15_c1 (void) { @@ -90,8 +94,6 @@ int cpu_init (void) * setup up stacks if necessary */ #ifdef CONFIG_USE_IRQ - DECLARE_GLOBAL_DATA_PTR; - IRQ_STACK_START = _armboot_start - CFG_MALLOC_LEN - CFG_GBL_DATA_SIZE - 4; FIQ_STACK_START = IRQ_STACK_START - CONFIG_STACKSIZE_IRQ; #endif diff --git a/cpu/lh7a40x/serial.c b/cpu/lh7a40x/serial.c index ff5b2d8..2132c05 100644 --- a/cpu/lh7a40x/serial.c +++ b/cpu/lh7a40x/serial.c @@ -21,6 +21,8 @@ #include <common.h> #include <lh7a40x.h> +DECLARE_GLOBAL_DATA_PTR; + #if defined(CONFIG_CONSOLE_UART1) # define UART_CONSOLE 1 #elif defined(CONFIG_CONSOLE_UART2) @@ -33,7 +35,6 @@ void serial_setbrg (void) { - DECLARE_GLOBAL_DATA_PTR; lh7a40x_uart_t* uart = LH7A40X_UART_PTR(UART_CONSOLE); int i; unsigned int reg = 0; diff --git a/cpu/mcf52x2/serial.c b/cpu/mcf52x2/serial.c index 641f0d9..8fbfad4 100644 --- a/cpu/mcf52x2/serial.c +++ b/cpu/mcf52x2/serial.c @@ -42,6 +42,8 @@ #include <asm/m5249.h> #endif +DECLARE_GLOBAL_DATA_PTR; + #ifdef CONFIG_M5249 #define DoubleClock(a) ((double)(CFG_CLK/2) / 32.0 / (double)(a)) #else @@ -140,12 +142,10 @@ int rs_get_char(void) } void serial_setbrg(void) { - DECLARE_GLOBAL_DATA_PTR; rs_serial_setbaudrate(0,gd->bd->bi_baudrate); } int serial_init(void) { - DECLARE_GLOBAL_DATA_PTR; rs_serial_init(0,gd->baudrate); return 0; } diff --git a/cpu/mcf52x2/speed.c b/cpu/mcf52x2/speed.c index 519c992..ac860b2 100644 --- a/cpu/mcf52x2/speed.c +++ b/cpu/mcf52x2/speed.c @@ -24,13 +24,13 @@ #include <common.h> #include <asm/processor.h> +DECLARE_GLOBAL_DATA_PTR; + /* * get_clocks() fills in gd->cpu_clock and gd->bus_clk */ int get_clocks (void) { - DECLARE_GLOBAL_DATA_PTR; - gd->cpu_clk = CFG_CLK; #ifdef CONFIG_M5249 gd->bus_clk = gd->cpu_clk / 2; diff --git a/cpu/mips/au1x00_eth.c b/cpu/mips/au1x00_eth.c index 9ce9b35..078e832 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/mpc5xx/cpu.c b/cpu/mpc5xx/cpu.c index 0c22a31..4bef90c 100644 --- a/cpu/mpc5xx/cpu.c +++ b/cpu/mpc5xx/cpu.c @@ -34,6 +34,7 @@ #include <command.h> #include <mpc5xx.h> +DECLARE_GLOBAL_DATA_PTR; #if (defined(CONFIG_MPC555)) # define ID_STR "MPC555/556" @@ -62,8 +63,6 @@ static int check_cpu_version (long clock, uint pvr, uint immr) */ int checkcpu (void) { - DECLARE_GLOBAL_DATA_PTR; - ulong clock = gd->cpu_clk; uint immr = get_immr (0); /* Return full IMMR contents */ uint pvr = get_pvr (); /* Retrieve PVR register */ @@ -104,7 +103,6 @@ void reset_5xx_watchdog (volatile immap_t * immr) */ unsigned long get_tbclk (void) { - DECLARE_GLOBAL_DATA_PTR; volatile immap_t *immr = (volatile immap_t *) CFG_IMMR; ulong oscclk, factor; diff --git a/cpu/mpc5xx/serial.c b/cpu/mpc5xx/serial.c index 4868782..ac5556f 100644 --- a/cpu/mpc5xx/serial.c +++ b/cpu/mpc5xx/serial.c @@ -34,6 +34,7 @@ #include <command.h> #include <mpc5xx.h> +DECLARE_GLOBAL_DATA_PTR; /* * Local function prototypes @@ -128,7 +129,6 @@ int serial_tstc() void serial_setbrg (void) { - DECLARE_GLOBAL_DATA_PTR; volatile immap_t *immr = (immap_t *)CFG_IMMR; short scxbr; diff --git a/cpu/mpc5xx/speed.c b/cpu/mpc5xx/speed.c index f6097f5..6a1fa15 100644 --- a/cpu/mpc5xx/speed.c +++ b/cpu/mpc5xx/speed.c @@ -31,12 +31,13 @@ #include <mpc5xx.h> #include <asm/processor.h> +DECLARE_GLOBAL_DATA_PTR; + /* * Get cpu and bus clock */ int get_clocks (void) { - DECLARE_GLOBAL_DATA_PTR; volatile immap_t *immr = (immap_t *) CFG_IMMR; #ifndef CONFIG_5xx_GCLK_FREQ diff --git a/cpu/mpc5xxx/cpu.c b/cpu/mpc5xxx/cpu.c index 2d695d1..6b6f828 100644 --- a/cpu/mpc5xxx/cpu.c +++ b/cpu/mpc5xxx/cpu.c @@ -31,14 +31,14 @@ #include <mpc5xxx.h> #include <asm/processor.h> +DECLARE_GLOBAL_DATA_PTR; + int checkcpu (void) { - DECLARE_GLOBAL_DATA_PTR; - ulong clock = gd->cpu_clk; char buf[32]; #ifndef CONFIG_MGT5100 - uint svr; + uint svr, pvr; #endif puts ("CPU: "); @@ -47,7 +47,8 @@ int checkcpu (void) puts (CPU_ID_STR); printf (" (JTAG ID %08lx)", *(vu_long *)MPC5XXX_CDM_JTAGID); #else - svr = get_svr (); + svr = get_svr(); + pvr = get_pvr(); switch (SVR_VER (svr)) { case SVR_MPC5200: printf ("MPC5200"); @@ -57,11 +58,10 @@ int checkcpu (void) break; } - printf (" v%d.%d", SVR_MJREV (svr), SVR_MNREV (svr)); + printf (" v%d.%d, Core v%d.%d", SVR_MJREV (svr), SVR_MNREV (svr), + PVR_MAJ(pvr), PVR_MIN(pvr)); #endif - printf (" at %s MHz\n", strmhz (buf, clock)); - return 0; } @@ -94,8 +94,6 @@ do_reset (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) */ unsigned long get_tbclk (void) { - DECLARE_GLOBAL_DATA_PTR; - ulong tbclk; tbclk = (gd->bus_clk + 3L) / 4L; diff --git a/cpu/mpc5xxx/cpu_init.c b/cpu/mpc5xxx/cpu_init.c index 3df0050..b7e00b3 100644 --- a/cpu/mpc5xxx/cpu_init.c +++ b/cpu/mpc5xxx/cpu_init.c @@ -24,6 +24,8 @@ #include <common.h> #include <mpc5xxx.h> +DECLARE_GLOBAL_DATA_PTR; + /* * Breath some life into the CPU... * @@ -32,8 +34,6 @@ */ void cpu_init_f (void) { - DECLARE_GLOBAL_DATA_PTR; - unsigned long addecr = (1 << 25); /* Boot_CS */ #if defined(CFG_RAMBOOT) && defined(CONFIG_MGT5100) addecr |= (1 << 22); /* SDRAM enable */ @@ -152,6 +152,10 @@ void cpu_init_f (void) /* enable timebase */ *(vu_long *)(MPC5XXX_XLBARB + 0x40) |= (1 << 13); + /* Enable snooping for RAM */ + *(vu_long *)(MPC5XXX_XLBARB + 0x40) |= (1 << 15); + *(vu_long *)(MPC5XXX_XLBARB + 0x70) = CFG_SDRAM_BASE | 0x1d; + # if defined(CFG_IPBSPEED_133) /* Motorola reports IPB should better run at 133 MHz. */ *(vu_long *)MPC5XXX_ADDECR |= 1; diff --git a/cpu/mpc5xxx/fec.c b/cpu/mpc5xxx/fec.c index 86c8ce6..19737ce 100644 --- a/cpu/mpc5xxx/fec.c +++ b/cpu/mpc5xxx/fec.c @@ -14,6 +14,8 @@ #include "sdma.h" #include "fec.h" +DECLARE_GLOBAL_DATA_PTR; + /* #define DEBUG 0x28 */ #if (CONFIG_COMMANDS & CFG_CMD_NET) && defined(CONFIG_NET_MULTI) && \ @@ -242,7 +244,6 @@ static void mpc5xxx_fec_set_hwaddr(mpc5xxx_fec_priv *fec, char *mac) /********************************************************************/ static int mpc5xxx_fec_init(struct eth_device *dev, bd_t * bis) { - DECLARE_GLOBAL_DATA_PTR; mpc5xxx_fec_priv *fec = (mpc5xxx_fec_priv *)dev->priv; struct mpc5xxx_sdma *sdma = (struct mpc5xxx_sdma *)MPC5XXX_SDMA; @@ -393,7 +394,6 @@ static int mpc5xxx_fec_init(struct eth_device *dev, bd_t * bis) /********************************************************************/ static int mpc5xxx_fec_init_phy(struct eth_device *dev, bd_t * bis) { - DECLARE_GLOBAL_DATA_PTR; mpc5xxx_fec_priv *fec = (mpc5xxx_fec_priv *)dev->priv; const uint8 phyAddr = CONFIG_PHY_ADDR; /* Only one PHY */ @@ -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/mpc5xxx/i2c.c b/cpu/mpc5xxx/i2c.c index 044db46..0f02e78 100644 --- a/cpu/mpc5xxx/i2c.c +++ b/cpu/mpc5xxx/i2c.c @@ -23,6 +23,8 @@ #include <common.h> +DECLARE_GLOBAL_DATA_PTR; + #ifdef CONFIG_HARD_I2C #include <mpc5xxx.h> @@ -228,7 +230,6 @@ void i2c_init(int speed, int saddr) static int mpc_get_fdr(int speed) { - DECLARE_GLOBAL_DATA_PTR; static int fdr = -1; if (fdr == -1) { diff --git a/cpu/mpc5xxx/ide.c b/cpu/mpc5xxx/ide.c index 1af794c..29b99f6 100644 --- a/cpu/mpc5xxx/ide.c +++ b/cpu/mpc5xxx/ide.c @@ -27,6 +27,8 @@ #ifdef CFG_CMD_IDE #include <mpc5xxx.h> +DECLARE_GLOBAL_DATA_PTR; + #define CALC_TIMING(t) (t + period - 1) / period #ifdef CONFIG_IDE_RESET @@ -35,7 +37,6 @@ extern void init_ide_reset (void); int ide_preinit (void) { - DECLARE_GLOBAL_DATA_PTR; long period, t0, t1, t2_8, t2_16, t4, ta; vu_long reg; struct mpc5xxx_sdma *psdma = (struct mpc5xxx_sdma *) MPC5XXX_SDMA; diff --git a/cpu/mpc5xxx/pci_mpc5200.c b/cpu/mpc5xxx/pci_mpc5200.c index 1d90345..2f01d5c 100644 --- a/cpu/mpc5xxx/pci_mpc5200.c +++ b/cpu/mpc5xxx/pci_mpc5200.c @@ -135,10 +135,6 @@ void pci_mpc5xxx_init (struct pci_controller *hose) *(vu_long *)MPC5XXX_PCI_BAR1 = CONFIG_PCI_MEMORY_BUS | (1 << 3); *(vu_long *)MPC5XXX_PCI_TBATR1 = CONFIG_PCI_MEMORY_PHYS | 1; - /* Enable snooping for RAM */ - *(vu_long *)(MPC5XXX_XLBARB + 0x40) |= (1 << 15); - *(vu_long *)(MPC5XXX_XLBARB + 0x70) = CONFIG_PCI_MEMORY_PHYS | 0x1d; - /* Park XLB on PCI */ *(vu_long *)(MPC5XXX_XLBARB + 0x40) &= ~((7 << 8) | (3 << 5)); *(vu_long *)(MPC5XXX_XLBARB + 0x40) |= (3 << 8) | (3 << 5); diff --git a/cpu/mpc5xxx/serial.c b/cpu/mpc5xxx/serial.c index 91e1def..cacb9f0 100644 --- a/cpu/mpc5xxx/serial.c +++ b/cpu/mpc5xxx/serial.c @@ -33,6 +33,8 @@ #include <common.h> #include <mpc5xxx.h> +DECLARE_GLOBAL_DATA_PTR; + #if defined(CONFIG_PSC_CONSOLE) #if CONFIG_PSC_CONSOLE == 1 @@ -55,8 +57,6 @@ int serial_init (void) { - DECLARE_GLOBAL_DATA_PTR; - volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)PSC_BASE; unsigned long baseclk; int div; @@ -146,8 +146,6 @@ serial_tstc(void) void serial_setbrg(void) { - DECLARE_GLOBAL_DATA_PTR; - volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)PSC_BASE; unsigned long baseclk, div; diff --git a/cpu/mpc5xxx/speed.c b/cpu/mpc5xxx/speed.c index 4f4e814..7847adc 100644 --- a/cpu/mpc5xxx/speed.c +++ b/cpu/mpc5xxx/speed.c @@ -25,6 +25,8 @@ #include <mpc5xxx.h> #include <asm/processor.h> +DECLARE_GLOBAL_DATA_PTR; + /* ------------------------------------------------------------------------- */ /* Bus-to-Core Multipliers */ @@ -43,8 +45,6 @@ static int bus2core[] = { int get_clocks (void) { - DECLARE_GLOBAL_DATA_PTR; - ulong val, vco; #if !defined(CFG_MPC5XXX_CLKIN) @@ -81,8 +81,6 @@ int get_clocks (void) int prt_mpc5xxx_clks (void) { - DECLARE_GLOBAL_DATA_PTR; - printf(" Bus %ld MHz, IPB %ld MHz, PCI %ld MHz\n", gd->bus_clk / 1000000, gd->ipb_clk / 1000000, gd->pci_clk / 1000000); diff --git a/cpu/mpc8220/cpu.c b/cpu/mpc8220/cpu.c index 0cfe808..be274cd 100644 --- a/cpu/mpc8220/cpu.c +++ b/cpu/mpc8220/cpu.c @@ -31,10 +31,10 @@ #include <mpc8220.h> #include <asm/processor.h> +DECLARE_GLOBAL_DATA_PTR; + int checkcpu (void) { - DECLARE_GLOBAL_DATA_PTR; - ulong clock = gd->cpu_clk; char buf[32]; @@ -81,8 +81,6 @@ int do_reset (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) */ unsigned long get_tbclk (void) { - DECLARE_GLOBAL_DATA_PTR; - ulong tbclk; tbclk = (gd->bus_clk + 3L) / 4L; diff --git a/cpu/mpc8220/cpu_init.c b/cpu/mpc8220/cpu_init.c index 8c358a8..3cf5f66 100644 --- a/cpu/mpc8220/cpu_init.c +++ b/cpu/mpc8220/cpu_init.c @@ -24,6 +24,8 @@ #include <common.h> #include <mpc8220.h> +DECLARE_GLOBAL_DATA_PTR; + /* * Breath some life into the CPU... * @@ -32,8 +34,6 @@ */ void cpu_init_f (void) { - DECLARE_GLOBAL_DATA_PTR; - volatile flexbus8220_t *flexbus = (volatile flexbus8220_t *) MMAP_FB; volatile pcfg8220_t *portcfg = (volatile pcfg8220_t *) MMAP_PCFG; volatile xlbarb8220_t *xlbarb = (volatile xlbarb8220_t *) MMAP_XLBARB; diff --git a/cpu/mpc8220/dramSetup.c b/cpu/mpc8220/dramSetup.c index 1d0d384..08e3172 100644 --- a/cpu/mpc8220/dramSetup.c +++ b/cpu/mpc8220/dramSetup.c @@ -32,6 +32,8 @@ characteristics to initialize the dram on MPC8220 #include "i2cCore.h" #include "dramSetup.h" +DECLARE_GLOBAL_DATA_PTR; + #define SPD_SIZE CFG_SDRAM_SPD_SIZE #define DRAM_SPD (CFG_SDRAM_SPD_I2C_ADDR)<<1 /* on Board SPD eeprom */ #define TOTAL_BANK CFG_SDRAM_TOTAL_BANKS @@ -91,8 +93,6 @@ int spd_readbyte (volatile i2c8220_t * pi2c, u8 * readb, int *index) int readSpdData (u8 * spdData) { - DECLARE_GLOBAL_DATA_PTR; - volatile i2c8220_t *pi2cReg; volatile pcfg8220_t *pcfg; u8 slvAdr = DRAM_SPD; @@ -403,8 +403,6 @@ u8 checkMuxSetting (u8 rows, u8 columns) u32 dramSetup (void) { - DECLARE_GLOBAL_DATA_PTR; - draminfo_t DramInfo[TOTAL_BANK]; draminfo_t *pDramInfo; u32 size, temp, cfg_value, mode_value, refresh; diff --git a/cpu/mpc8220/i2c.c b/cpu/mpc8220/i2c.c index 62f7c0f..d67936d 100644 --- a/cpu/mpc8220/i2c.c +++ b/cpu/mpc8220/i2c.c @@ -23,6 +23,8 @@ #include <common.h> +DECLARE_GLOBAL_DATA_PTR; + #ifdef CONFIG_HARD_I2C #include <mpc8220.h> @@ -235,7 +237,6 @@ void i2c_init (int speed, int saddr) static int mpc_get_fdr (int speed) { - DECLARE_GLOBAL_DATA_PTR; static int fdr = -1; if (fdr == -1) { diff --git a/cpu/mpc8220/speed.c b/cpu/mpc8220/speed.c index 8346efe..200a762 100644 --- a/cpu/mpc8220/speed.c +++ b/cpu/mpc8220/speed.c @@ -25,6 +25,8 @@ #include <mpc8220.h> #include <asm/processor.h> +DECLARE_GLOBAL_DATA_PTR; + typedef struct pllmultiplier { u8 hid1; int multi; @@ -39,8 +41,6 @@ typedef struct pllmultiplier { int get_clocks (void) { - DECLARE_GLOBAL_DATA_PTR; - pllcfg_t bus2core[] = { {0x02, 2, 8}, /* 1 */ {0x01, 2, 4}, @@ -109,8 +109,6 @@ int get_clocks (void) int prt_mpc8220_clks (void) { - DECLARE_GLOBAL_DATA_PTR; - printf (" Bus %ld MHz, CPU %ld MHz, PCI %ld MHz, VCO %ld MHz\n", gd->bus_clk / 1000000, gd->cpu_clk / 1000000, gd->pci_clk / 1000000, gd->vco_clk / 1000000); diff --git a/cpu/mpc8220/uart.c b/cpu/mpc8220/uart.c index 5f54aac..0c4b536 100644 --- a/cpu/mpc8220/uart.c +++ b/cpu/mpc8220/uart.c @@ -30,12 +30,13 @@ #include <common.h> #include <mpc8220.h> +DECLARE_GLOBAL_DATA_PTR; + #define PSC_BASE MMAP_PSC1 #if defined(CONFIG_PSC_CONSOLE) int serial_init (void) { - DECLARE_GLOBAL_DATA_PTR; volatile psc8220_t *psc = (psc8220_t *) PSC_BASE; u32 counter; @@ -106,8 +107,6 @@ int serial_tstc (void) void serial_setbrg (void) { - DECLARE_GLOBAL_DATA_PTR; - volatile psc8220_t *psc = (psc8220_t *) PSC_BASE; u32 counter; diff --git a/cpu/mpc824x/cpu.c b/cpu/mpc824x/cpu.c index 312dfe2..0a45cc8 100644 --- a/cpu/mpc824x/cpu.c +++ b/cpu/mpc824x/cpu.c @@ -26,10 +26,10 @@ #include <common.h> #include <command.h> +DECLARE_GLOBAL_DATA_PTR; + int checkcpu (void) { - DECLARE_GLOBAL_DATA_PTR; - unsigned int pvr = get_pvr (); unsigned int version = pvr >> 16; unsigned char revision; diff --git a/cpu/mpc824x/speed.c b/cpu/mpc824x/speed.c index a37a087..fdcb972 100644 --- a/cpu/mpc824x/speed.c +++ b/cpu/mpc824x/speed.c @@ -29,6 +29,8 @@ #include <mpc824x.h> #include <asm/processor.h> +DECLARE_GLOBAL_DATA_PTR; + /* ------------------------------------------------------------------------- */ /* NOTE: This describes the proper use of this file. * @@ -107,8 +109,6 @@ short pllratio_to_factor[] = { /* compute the CPU and memory bus clock frequencies */ int get_clocks (void) { - DECLARE_GLOBAL_DATA_PTR; - uint hid1 = mfspr(HID1); hid1 = (hid1 >> (32-5)) & 0x1f; gd->cpu_clk = (pllratio_to_factor[hid1] * get_bus_freq(0) + 5) diff --git a/cpu/mpc8260/commproc.c b/cpu/mpc8260/commproc.c index e5c5fcf..8777e77 100644 --- a/cpu/mpc8260/commproc.c +++ b/cpu/mpc8260/commproc.c @@ -20,11 +20,11 @@ #include <common.h> #include <asm/cpm_8260.h> +DECLARE_GLOBAL_DATA_PTR; + void m8260_cpm_reset(void) { - DECLARE_GLOBAL_DATA_PTR; - volatile immap_t *immr = (immap_t *)CFG_IMMR; volatile ulong count; @@ -54,8 +54,6 @@ m8260_cpm_reset(void) uint m8260_cpm_dpalloc(uint size, uint align) { - DECLARE_GLOBAL_DATA_PTR; - volatile immap_t *immr = (immap_t *)CFG_IMMR; uint retloc; uint align_mask, off; @@ -112,8 +110,6 @@ m8260_cpm_hostalloc(uint size, uint align) void m8260_cpm_setbrg(uint brg, uint rate) { - DECLARE_GLOBAL_DATA_PTR; - volatile immap_t *immr = (immap_t *)CFG_IMMR; volatile uint *bp; uint cd = BRG_UART_CLK / rate; @@ -137,8 +133,6 @@ m8260_cpm_setbrg(uint brg, uint rate) void m8260_cpm_fastbrg(uint brg, uint rate, int div16) { - DECLARE_GLOBAL_DATA_PTR; - volatile immap_t *immr = (immap_t *)CFG_IMMR; volatile uint *bp; diff --git a/cpu/mpc8260/cpu.c b/cpu/mpc8260/cpu.c index 5d97933..4f23012 100644 --- a/cpu/mpc8260/cpu.c +++ b/cpu/mpc8260/cpu.c @@ -1,5 +1,5 @@ /* - * (C) Copyright 2000-2003 + * (C) Copyright 2000-2006 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. * * See file CREDITS for list of people who contributed to this @@ -47,10 +47,10 @@ #include <asm/processor.h> #include <asm/cpm_8260.h> +DECLARE_GLOBAL_DATA_PTR; + int checkcpu (void) { - DECLARE_GLOBAL_DATA_PTR; - volatile immap_t *immap = (immap_t *) CFG_IMMR; ulong clock = gd->cpu_clk; uint pvr = get_pvr (); @@ -264,8 +264,6 @@ do_reset (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) */ unsigned long get_tbclk (void) { - DECLARE_GLOBAL_DATA_PTR; - ulong tbclk; tbclk = (gd->bus_clk + 3L) / 4L; diff --git a/cpu/mpc8260/cpu_init.c b/cpu/mpc8260/cpu_init.c index babcce4..640026b 100644 --- a/cpu/mpc8260/cpu_init.c +++ b/cpu/mpc8260/cpu_init.c @@ -26,6 +26,8 @@ #include <asm/cpm_8260.h> #include <ioports.h> +DECLARE_GLOBAL_DATA_PTR; + static void config_8260_ioports (volatile immap_t * immr) { int portnum; @@ -97,7 +99,6 @@ static void config_8260_ioports (volatile immap_t * immr) */ void cpu_init_f (volatile immap_t * immr) { - DECLARE_GLOBAL_DATA_PTR; #if !defined(CONFIG_COGENT) /* done in start.S for the cogent */ uint sccr; #endif @@ -222,8 +223,6 @@ void cpu_init_f (volatile immap_t * immr) */ int cpu_init_r (void) { - DECLARE_GLOBAL_DATA_PTR; - volatile immap_t *immr = (immap_t *) gd->bd->bi_immr_base; immr->im_cpm.cp_rccr = CFG_RCCR; @@ -236,8 +235,6 @@ int cpu_init_r (void) */ int prt_8260_rsr (void) { - DECLARE_GLOBAL_DATA_PTR; - static struct { ulong mask; char *desc; diff --git a/cpu/mpc8260/ether_fcc.c b/cpu/mpc8260/ether_fcc.c index ed3515f..584c40f 100644 --- a/cpu/mpc8260/ether_fcc.c +++ b/cpu/mpc8260/ether_fcc.c @@ -51,6 +51,8 @@ #include <miiphy.h> #endif +DECLARE_GLOBAL_DATA_PTR; + #if defined(CONFIG_ETHER_ON_FCC) && (CONFIG_COMMANDS & CFG_CMD_NET) && \ defined(CONFIG_NET_MULTI) @@ -644,8 +646,6 @@ swap16 (unsigned short x) void eth_loopback_test (void) { - DECLARE_GLOBAL_DATA_PTR; - volatile immap_t *immr = (immap_t *)CFG_IMMR; volatile cpm8260_t *cp = &(immr->im_cpm); int c, nclosed; diff --git a/cpu/mpc8260/i2c.c b/cpu/mpc8260/i2c.c index ea97ab8..34bd389 100644 --- a/cpu/mpc8260/i2c.c +++ b/cpu/mpc8260/i2c.c @@ -34,6 +34,8 @@ /* define to enable debug messages */ #undef DEBUG_I2C +DECLARE_GLOBAL_DATA_PTR; + /* uSec to wait between polls of the i2c */ #define DELAY_US 100 /* uSec to wait for the CPM to start processing the buffer */ @@ -213,8 +215,6 @@ static int i2c_setrate(int hz, int speed) void i2c_init(int speed, int slaveadd) { - DECLARE_GLOBAL_DATA_PTR; - volatile immap_t *immap = (immap_t *)CFG_IMMR ; volatile cpm8260_t *cp = (cpm8260_t *)&immap->im_cpm; volatile i2c8260_t *i2c = (i2c8260_t *)&immap->im_i2c; diff --git a/cpu/mpc8260/interrupts.c b/cpu/mpc8260/interrupts.c index b2e4d83..56e9a72 100644 --- a/cpu/mpc8260/interrupts.c +++ b/cpu/mpc8260/interrupts.c @@ -29,6 +29,8 @@ #include <mpc8260_irq.h> #include <asm/processor.h> +DECLARE_GLOBAL_DATA_PTR; + /****************************************************************************/ struct irq_action { @@ -140,8 +142,6 @@ static int m8260_get_irq (struct pt_regs *regs) int interrupt_init_cpu (unsigned *decrementer_count) { - DECLARE_GLOBAL_DATA_PTR; - volatile immap_t *immr = (immap_t *) CFG_IMMR; *decrementer_count = (gd->bus_clk / 4) / CFG_HZ; diff --git a/cpu/mpc8260/pci.c b/cpu/mpc8260/pci.c index 44576de..ea5514f 100644 --- a/cpu/mpc8260/pci.c +++ b/cpu/mpc8260/pci.c @@ -33,6 +33,11 @@ #include <mpc8260.h> #include <asm/m8260_pci.h> #include <asm/io.h> + +#if defined CONFIG_MPC8266ADS || defined CONFIG_MPC8272 +DECLARE_GLOBAL_DATA_PTR; +#endif + /* * Local->PCI map (from CPU) controlled by * MPC826x master window @@ -234,9 +239,6 @@ static inline void pci_outl (u32 addr, u32 data) void pci_mpc8250_init (struct pci_controller *hose) { -#if defined CONFIG_MPC8266ADS || defined CONFIG_MPC8272 - DECLARE_GLOBAL_DATA_PTR; -#endif u16 tempShort; volatile immap_t *immap = (immap_t *) CFG_IMMR; diff --git a/cpu/mpc8260/serial_scc.c b/cpu/mpc8260/serial_scc.c index 32016f2..3a6eaf0 100644 --- a/cpu/mpc8260/serial_scc.c +++ b/cpu/mpc8260/serial_scc.c @@ -32,6 +32,8 @@ #include <mpc8260.h> #include <asm/cpm_8260.h> +DECLARE_GLOBAL_DATA_PTR; + #if defined(CONFIG_CONS_ON_SCC) #if CONFIG_CONS_INDEX == 1 /* Console on SCC1 */ @@ -181,8 +183,6 @@ int serial_init (void) void serial_setbrg (void) { - DECLARE_GLOBAL_DATA_PTR; - #if defined(CONFIG_CONS_USE_EXTC) m8260_cpm_extcbrg(SCC_INDEX, gd->baudrate, CONFIG_CONS_EXTC_RATE, CONFIG_CONS_EXTC_PINSEL); diff --git a/cpu/mpc8260/serial_smc.c b/cpu/mpc8260/serial_smc.c index b486f83..f3dffeb 100644 --- a/cpu/mpc8260/serial_smc.c +++ b/cpu/mpc8260/serial_smc.c @@ -34,6 +34,8 @@ #include <mpc8260.h> #include <asm/cpm_8260.h> +DECLARE_GLOBAL_DATA_PTR; + #if defined(CONFIG_CONS_ON_SMC) #if CONFIG_CONS_INDEX == 1 /* Console on SMC1 */ @@ -170,8 +172,6 @@ int serial_init (void) void serial_setbrg (void) { - DECLARE_GLOBAL_DATA_PTR; - #if defined(CONFIG_CONS_USE_EXTC) m8260_cpm_extcbrg(brg_map[SMC_INDEX], gd->baudrate, CONFIG_CONS_EXTC_RATE, CONFIG_CONS_EXTC_PINSEL); diff --git a/cpu/mpc8260/speed.c b/cpu/mpc8260/speed.c index a761a17..360404f 100644 --- a/cpu/mpc8260/speed.c +++ b/cpu/mpc8260/speed.c @@ -25,6 +25,8 @@ #include <mpc8260.h> #include <asm/processor.h> +DECLARE_GLOBAL_DATA_PTR; + /* ------------------------------------------------------------------------- */ /* Bus-to-Core Multiplier */ @@ -101,8 +103,6 @@ corecnf_t corecnf_tab[] = { int get_clocks (void) { - DECLARE_GLOBAL_DATA_PTR; - volatile immap_t *immap = (immap_t *) CFG_IMMR; ulong clkin; ulong sccr, dfbrg; @@ -159,11 +159,9 @@ int get_clocks (void) int prt_8260_clks (void) { - DECLARE_GLOBAL_DATA_PTR; - 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 +173,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 +203,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 +215,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 +236,3 @@ int prt_8260_clks (void) return (0); } - -/* ------------------------------------------------------------------------- */ diff --git a/cpu/mpc83xx/cpu.c b/cpu/mpc83xx/cpu.c index 8c9b515..20bba6c 100644 --- a/cpu/mpc83xx/cpu.c +++ b/cpu/mpc83xx/cpu.c @@ -35,12 +35,14 @@ #include <watchdog.h> #include <command.h> #include <mpc83xx.h> +#include <ft_build.h> #include <asm/processor.h> +DECLARE_GLOBAL_DATA_PTR; + int checkcpu(void) { - DECLARE_GLOBAL_DATA_PTR; ulong clock = gd->cpu_clk; u32 pvr = get_pvr(); char buf[32]; @@ -92,6 +94,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)); @@ -135,8 +139,6 @@ do_reset (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) unsigned long get_tbclk(void) { - DECLARE_GLOBAL_DATA_PTR; - ulong tbclk; tbclk = (gd->bus_clk + 3L) / 4L; @@ -151,3 +153,125 @@ void watchdog_reset (void) hang(); /* FIXME: implement watchdog_reset()? */ } #endif /* CONFIG_WATCHDOG */ + +#if defined(CONFIG_OF_FLAT_TREE) +void +ft_cpu_setup(void *blob, bd_t *bd) +{ + u32 *p; + int len; + ulong clock; + + clock = bd->bi_busfreq; + p = ft_get_prop(blob, "/cpus/" OF_CPU "/bus-frequency", &len); + if (p != NULL) + *p = cpu_to_be32(clock); + + p = ft_get_prop(blob, "/" OF_SOC "/bus-frequency", &len); + if (p != NULL) + *p = cpu_to_be32(clock); + + p = ft_get_prop(blob, "/" OF_SOC "/serial@4500/clock-frequency", &len); + if (p != NULL) + *p = cpu_to_be32(clock); + + p = ft_get_prop(blob, "/" OF_SOC "/serial@4600/clock-frequency", &len); + if (p != NULL) + *p = cpu_to_be32(clock); + +#ifdef CONFIG_MPC83XX_TSEC1 + p = ft_get_prop(blob, "/" OF_SOC "/ethernet@24000/address", &len); + memcpy(p, bd->bi_enetaddr, 6); +#endif + +#ifdef CONFIG_MPC83XX_TSEC2 + p = ft_get_prop(blob, "/" OF_SOC "/ethernet@25000/address", &len); + memcpy(p, bd->bi_enet1addr, 6); +#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/cpu_init.c b/cpu/mpc83xx/cpu_init.c index dcb3445..6ed0992 100644 --- a/cpu/mpc83xx/cpu_init.c +++ b/cpu/mpc83xx/cpu_init.c @@ -29,6 +29,8 @@ #include <mpc83xx.h> #include <ioports.h> +DECLARE_GLOBAL_DATA_PTR; + /* * Breathe some life into the CPU... * @@ -38,8 +40,6 @@ */ void cpu_init_f (volatile immap_t * im) { - DECLARE_GLOBAL_DATA_PTR; - /* Pointer is writable since we allocated a register for it */ gd = (gd_t *) (CFG_INIT_RAM_ADDR + CFG_GBL_DATA_OFFSET); @@ -63,8 +63,12 @@ void cpu_init_f (volatile immap_t * im) im->sysconf.spcr |= SPCR_TBEN; /* System General Purpose Register */ - im->sysconf.sicrh = SICRH_TSOBI1; - im->sysconf.sicrl = SICRL_LDP_A; +#ifdef CFG_SICRH + im->sysconf.sicrh = CFG_SICRH; +#endif +#ifdef CFG_SICRL + im->sysconf.sicrl = CFG_SICRL; +#endif /* * Memory Controller: @@ -87,69 +91,70 @@ void cpu_init_f (volatile immap_t * im) #error CFG_BR0_PRELIM, CFG_OR0_PRELIM, CFG_LBLAWBAR0_PRELIM & CFG_LBLAWAR0_PRELIM must be defined #endif -#if defined(CFG_BR1_PRELIM) \ - && defined(CFG_OR1_PRELIM) \ - && defined(CFG_LBLAWBAR1_PRELIM) \ - && defined(CFG_LBLAWAR1_PRELIM) +#if defined(CFG_BR1_PRELIM) && defined(CFG_OR1_PRELIM) im->lbus.bank[1].br = CFG_BR1_PRELIM; im->lbus.bank[1].or = CFG_OR1_PRELIM; +#endif +#if defined(CFG_LBLAWBAR1_PRELIM) && defined(CFG_LBLAWAR1_PRELIM) im->sysconf.lblaw[1].bar = CFG_LBLAWBAR1_PRELIM; im->sysconf.lblaw[1].ar = CFG_LBLAWAR1_PRELIM; #endif -#if defined(CFG_BR2_PRELIM) \ - && defined(CFG_OR2_PRELIM) \ - && defined(CFG_LBLAWBAR2_PRELIM) \ - && defined(CFG_LBLAWAR2_PRELIM) +#if defined(CFG_BR2_PRELIM) && defined(CFG_OR2_PRELIM) im->lbus.bank[2].br = CFG_BR2_PRELIM; im->lbus.bank[2].or = CFG_OR2_PRELIM; +#endif +#if defined(CFG_LBLAWBAR2_PRELIM) && defined(CFG_LBLAWAR2_PRELIM) im->sysconf.lblaw[2].bar = CFG_LBLAWBAR2_PRELIM; im->sysconf.lblaw[2].ar = CFG_LBLAWAR2_PRELIM; #endif -#if defined(CFG_BR3_PRELIM) \ - && defined(CFG_OR3_PRELIM) \ - && defined(CFG_LBLAWBAR3_PRELIM) \ - && defined(CFG_LBLAWAR3_PRELIM) +#if defined(CFG_BR3_PRELIM) && defined(CFG_OR3_PRELIM) im->lbus.bank[3].br = CFG_BR3_PRELIM; im->lbus.bank[3].or = CFG_OR3_PRELIM; +#endif +#if defined(CFG_LBLAWBAR3_PRELIM) && defined(CFG_LBLAWAR3_PRELIM) im->sysconf.lblaw[3].bar = CFG_LBLAWBAR3_PRELIM; im->sysconf.lblaw[3].ar = CFG_LBLAWAR3_PRELIM; #endif -#if defined(CFG_BR4_PRELIM) \ - && defined(CFG_OR4_PRELIM) \ - && defined(CFG_LBLAWBAR4_PRELIM) \ - && defined(CFG_LBLAWAR4_PRELIM) +#if defined(CFG_BR4_PRELIM) && defined(CFG_OR4_PRELIM) im->lbus.bank[4].br = CFG_BR4_PRELIM; im->lbus.bank[4].or = CFG_OR4_PRELIM; +#endif +#if defined(CFG_LBLAWBAR4_PRELIM) && defined(CFG_LBLAWAR4_PRELIM) im->sysconf.lblaw[4].bar = CFG_LBLAWBAR4_PRELIM; im->sysconf.lblaw[4].ar = CFG_LBLAWAR4_PRELIM; #endif -#if defined(CFG_BR5_PRELIM) \ - && defined(CFG_OR5_PRELIM) \ - && defined(CFG_LBLAWBAR5_PRELIM) \ - && defined(CFG_LBLAWAR5_PRELIM) +#if defined(CFG_BR5_PRELIM) && defined(CFG_OR5_PRELIM) im->lbus.bank[5].br = CFG_BR5_PRELIM; im->lbus.bank[5].or = CFG_OR5_PRELIM; +#endif +#if defined(CFG_LBLAWBAR5_PRELIM) && defined(CFG_LBLAWAR5_PRELIM) im->sysconf.lblaw[5].bar = CFG_LBLAWBAR5_PRELIM; im->sysconf.lblaw[5].ar = CFG_LBLAWAR5_PRELIM; #endif -#if defined(CFG_BR6_PRELIM) \ - && defined(CFG_OR6_PRELIM) \ - && defined(CFG_LBLAWBAR6_PRELIM) \ - && defined(CFG_LBLAWAR6_PRELIM) +#if defined(CFG_BR6_PRELIM) && defined(CFG_OR6_PRELIM) im->lbus.bank[6].br = CFG_BR6_PRELIM; im->lbus.bank[6].or = CFG_OR6_PRELIM; +#endif +#if defined(CFG_LBLAWBAR6_PRELIM) && defined(CFG_LBLAWAR6_PRELIM) im->sysconf.lblaw[6].bar = CFG_LBLAWBAR6_PRELIM; im->sysconf.lblaw[6].ar = CFG_LBLAWAR6_PRELIM; #endif -#if defined(CFG_BR7_PRELIM) \ - && defined(CFG_OR7_PRELIM) \ - && defined(CFG_LBLAWBAR7_PRELIM) \ - && defined(CFG_LBLAWAR7_PRELIM) +#if defined(CFG_BR7_PRELIM) && defined(CFG_OR7_PRELIM) im->lbus.bank[7].br = CFG_BR7_PRELIM; im->lbus.bank[7].or = CFG_OR7_PRELIM; +#endif +#if defined(CFG_LBLAWBAR7_PRELIM) && defined(CFG_LBLAWAR7_PRELIM) im->sysconf.lblaw[7].bar = CFG_LBLAWBAR7_PRELIM; im->sysconf.lblaw[7].ar = CFG_LBLAWAR7_PRELIM; #endif +#ifdef CFG_GPIO1_PRELIM + im->pgio[0].dir = CFG_GPIO1_DIR; + im->pgio[0].dat = CFG_GPIO1_DAT; +#endif +#ifdef CFG_GPIO2_PRELIM + im->pgio[1].dir = CFG_GPIO2_DIR; + im->pgio[1].dat = CFG_GPIO2_DAT; +#endif } diff --git a/cpu/mpc83xx/interrupts.c b/cpu/mpc83xx/interrupts.c index 53474f6..5a0babf 100644 --- a/cpu/mpc83xx/interrupts.c +++ b/cpu/mpc83xx/interrupts.c @@ -35,6 +35,8 @@ #include <mpc83xx.h> #include <asm/processor.h> +DECLARE_GLOBAL_DATA_PTR; + struct irq_action { interrupt_handler_t *handler; void *arg; @@ -43,6 +45,14 @@ struct irq_action { int interrupt_init_cpu (unsigned *decrementer_count) { + volatile immap_t *immr = (immap_t *) CFG_IMMRBAR; + + *decrementer_count = (gd->bus_clk / 4) / CFG_HZ; + + /* Enable e300 time base */ + + immr->sysconf.spcr |= 0x00400000; + return 0; } diff --git a/cpu/mpc83xx/spd_sdram.c b/cpu/mpc83xx/spd_sdram.c index 63dcd66..48624fe 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/speed.c b/cpu/mpc83xx/speed.c index 1368fc3..ad6b3f6 100644 --- a/cpu/mpc83xx/speed.c +++ b/cpu/mpc83xx/speed.c @@ -32,6 +32,8 @@ #include <mpc83xx.h> #include <asm/processor.h> +DECLARE_GLOBAL_DATA_PTR; + /* ----------------------------------------------------------------- */ typedef enum { @@ -92,7 +94,6 @@ corecnf_t corecnf_tab[] = { */ int get_clocks (void) { - DECLARE_GLOBAL_DATA_PTR; volatile immap_t *im = (immap_t *)CFG_IMMRBAR; u32 pci_sync_in; u8 spmf; @@ -342,14 +343,11 @@ int get_clocks (void) *********************************************/ ulong get_bus_freq (ulong dummy) { - DECLARE_GLOBAL_DATA_PTR; return gd->csb_clk; } int print_clock_conf (void) { - DECLARE_GLOBAL_DATA_PTR; - printf("Clock configuration:\n"); printf(" Coherent System Bus: %4d MHz\n",gd->csb_clk/1000000); printf(" Core: %4d MHz\n",gd->core_clk/1000000); diff --git a/cpu/mpc83xx/start.S b/cpu/mpc83xx/start.S index fb001a6..6e02cce 100644 --- a/cpu/mpc83xx/start.S +++ b/cpu/mpc83xx/start.S @@ -179,10 +179,47 @@ in_flash: #endif #endif /* CFG_RAMBOOT */ - bl setup_stack_in_data_cache_on_r1 + /* setup the bats */ + bl setup_bats + sync + + /* + * Cache must be enabled here for stack-in-cache trick. + * This means we need to enable the BATS. + * This means: + * 1) for the EVB, original gt regs need to be mapped + * 2) need to have an IBAT for the 0xf region, + * we are running there! + * Cache should be turned on after BATs, since by default + * everything is write-through. + * The init-mem BAT can be reused after reloc. The old + * gt-regs BAT can be reused after board_init_f calls + * board_early_init_f (EVB only). + */ + /* enable address translation */ + bl enable_addr_trans + sync + + /* enable and invalidate the data cache */ + bl dcache_enable + sync +#ifdef CFG_INIT_RAM_LOCK + bl lock_ram_in_cache + sync +#endif + + /* set up the stack pointer in our newly created + * cache-ram (r1) */ + lis r1, (CFG_INIT_RAM_ADDR + CFG_GBL_DATA_OFFSET)@h + ori r1, r1, (CFG_INIT_RAM_ADDR + CFG_GBL_DATA_OFFSET)@l + + li r0, 0 /* Make room for stack frame header and */ + stwu r0, -4(r1) /* clear final stack frame so that */ + stwu r0, -4(r1) /* stack backtraces terminate cleanly */ + /* let the C-code set up the rest */ - /* */ + /* */ /* Be careful to keep code relocatable & stack humble */ /*------------------------------------------------------*/ @@ -426,8 +463,14 @@ init_e300_core: /* time t 10 */ #else /* Disable Wathcdog */ /*-------------------*/ + lwz r4, SWCRR(r3) + /* Check to see if its enabled for disabling + once disabled by SW you can't re-enable */ + andi. r4, r4, 0x4 + beq 1f xor r4, r4, r4 stw r4, SWCRR(r3) +1: #endif /* CONFIG_WATCHDOG */ /* Initialize the Hardware Implementation-dependent Registers */ @@ -503,6 +546,221 @@ init_e300_core: /* time t 10 */ /*------------------------------*/ blr + .globl invalidate_bats +invalidate_bats: + /* invalidate BATs */ + mtspr IBAT0U, r0 + mtspr IBAT1U, r0 + mtspr IBAT2U, r0 + mtspr IBAT3U, r0 +#if (CFG_HID2 & HID2_HBE) + mtspr IBAT4U, r0 + mtspr IBAT5U, r0 + mtspr IBAT6U, r0 + mtspr IBAT7U, r0 +#endif + isync + mtspr DBAT0U, r0 + mtspr DBAT1U, r0 + mtspr DBAT2U, r0 + mtspr DBAT3U, r0 +#if (CFG_HID2 & HID2_HBE) + mtspr DBAT4U, r0 + mtspr DBAT5U, r0 + mtspr DBAT6U, r0 + mtspr DBAT7U, r0 +#endif + isync + sync + blr + + /* setup_bats - set them up to some initial state */ + .globl setup_bats +setup_bats: + addis r0, r0, 0x0000 + + /* IBAT 0 */ + addis r4, r0, CFG_IBAT0L@h + ori r4, r4, CFG_IBAT0L@l + addis r3, r0, CFG_IBAT0U@h + ori r3, r3, CFG_IBAT0U@l + mtspr IBAT0L, r4 + mtspr IBAT0U, r3 + isync + + /* DBAT 0 */ + addis r4, r0, CFG_DBAT0L@h + ori r4, r4, CFG_DBAT0L@l + addis r3, r0, CFG_DBAT0U@h + ori r3, r3, CFG_DBAT0U@l + mtspr DBAT0L, r4 + mtspr DBAT0U, r3 + isync + + /* IBAT 1 */ + addis r4, r0, CFG_IBAT1L@h + ori r4, r4, CFG_IBAT1L@l + addis r3, r0, CFG_IBAT1U@h + ori r3, r3, CFG_IBAT1U@l + mtspr IBAT1L, r4 + mtspr IBAT1U, r3 + isync + + /* DBAT 1 */ + addis r4, r0, CFG_DBAT1L@h + ori r4, r4, CFG_DBAT1L@l + addis r3, r0, CFG_DBAT1U@h + ori r3, r3, CFG_DBAT1U@l + mtspr DBAT1L, r4 + mtspr DBAT1U, r3 + isync + + /* IBAT 2 */ + addis r4, r0, CFG_IBAT2L@h + ori r4, r4, CFG_IBAT2L@l + addis r3, r0, CFG_IBAT2U@h + ori r3, r3, CFG_IBAT2U@l + mtspr IBAT2L, r4 + mtspr IBAT2U, r3 + isync + + /* DBAT 2 */ + addis r4, r0, CFG_DBAT2L@h + ori r4, r4, CFG_DBAT2L@l + addis r3, r0, CFG_DBAT2U@h + ori r3, r3, CFG_DBAT2U@l + mtspr DBAT2L, r4 + mtspr DBAT2U, r3 + isync + + /* IBAT 3 */ + addis r4, r0, CFG_IBAT3L@h + ori r4, r4, CFG_IBAT3L@l + addis r3, r0, CFG_IBAT3U@h + ori r3, r3, CFG_IBAT3U@l + mtspr IBAT3L, r4 + mtspr IBAT3U, r3 + isync + + /* DBAT 3 */ + addis r4, r0, CFG_DBAT3L@h + ori r4, r4, CFG_DBAT3L@l + addis r3, r0, CFG_DBAT3U@h + ori r3, r3, CFG_DBAT3U@l + mtspr DBAT3L, r4 + mtspr DBAT3U, r3 + isync + +#if (CFG_HID2 & HID2_HBE) + /* IBAT 4 */ + addis r4, r0, CFG_IBAT4L@h + ori r4, r4, CFG_IBAT4L@l + addis r3, r0, CFG_IBAT4U@h + ori r3, r3, CFG_IBAT4U@l + mtspr IBAT4L, r4 + mtspr IBAT4U, r3 + isync + + /* DBAT 4 */ + addis r4, r0, CFG_DBAT4L@h + ori r4, r4, CFG_DBAT4L@l + addis r3, r0, CFG_DBAT4U@h + ori r3, r3, CFG_DBAT4U@l + mtspr DBAT4L, r4 + mtspr DBAT4U, r3 + isync + + /* IBAT 5 */ + addis r4, r0, CFG_IBAT5L@h + ori r4, r4, CFG_IBAT5L@l + addis r3, r0, CFG_IBAT5U@h + ori r3, r3, CFG_IBAT5U@l + mtspr IBAT5L, r4 + mtspr IBAT5U, r3 + isync + + /* DBAT 5 */ + addis r4, r0, CFG_DBAT5L@h + ori r4, r4, CFG_DBAT5L@l + addis r3, r0, CFG_DBAT5U@h + ori r3, r3, CFG_DBAT5U@l + mtspr DBAT5L, r4 + mtspr DBAT5U, r3 + isync + + /* IBAT 6 */ + addis r4, r0, CFG_IBAT6L@h + ori r4, r4, CFG_IBAT6L@l + addis r3, r0, CFG_IBAT6U@h + ori r3, r3, CFG_IBAT6U@l + mtspr IBAT6L, r4 + mtspr IBAT6U, r3 + isync + + /* DBAT 6 */ + addis r4, r0, CFG_DBAT6L@h + ori r4, r4, CFG_DBAT6L@l + addis r3, r0, CFG_DBAT6U@h + ori r3, r3, CFG_DBAT6U@l + mtspr DBAT6L, r4 + mtspr DBAT6U, r3 + isync + + /* IBAT 7 */ + addis r4, r0, CFG_IBAT7L@h + ori r4, r4, CFG_IBAT7L@l + addis r3, r0, CFG_IBAT7U@h + ori r3, r3, CFG_IBAT7U@l + mtspr IBAT7L, r4 + mtspr IBAT7U, r3 + isync + + /* DBAT 7 */ + addis r4, r0, CFG_DBAT7L@h + ori r4, r4, CFG_DBAT7L@l + addis r3, r0, CFG_DBAT7U@h + ori r3, r3, CFG_DBAT7U@l + mtspr DBAT7L, r4 + mtspr DBAT7U, r3 + isync +#endif + + /* Invalidate TLBs. + * -> for (val = 0; val < 0x20000; val+=0x1000) + * -> tlbie(val); + */ + lis r3, 0 + lis r5, 2 + +1: + tlbie r3 + addi r3, r3, 0x1000 + cmp 0, 0, r3, r5 + blt 1b + + blr + + .globl enable_addr_trans +enable_addr_trans: + /* enable address translation */ + mfmsr r5 + ori r5, r5, (MSR_IR | MSR_DR) + mtmsr r5 + isync + blr + + .globl disable_addr_trans +disable_addr_trans: + /* disable address translation */ + mflr r4 + mfmsr r3 + andi. r0, r3, (MSR_IR | MSR_DR) + beqlr + andc r3, r3, r0 + mtspr SRR0, r4 + mtspr SRR1, r3 + rfi + /* Cache functions. * * Note: requires that all cache bits in @@ -538,32 +796,31 @@ 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 dcache_enable: mfspr r3, HID0 - ori r3, r3, HID0_ENABLE_DATA_CACHE - lis r4, 0 - ori r4, r4, HID0_LOCK_DATA_CACHE - andc r3, r3, r4 - ori r4, r3, HID0_LOCK_INSTRUCTION_CACHE - sync - mtspr HID0, r4 /* sets enable and invalidate, clears lock */ + li r5, HID0_DCFI|HID0_DLOCK + andc r3, r3, r5 + mtspr HID0, r3 /* no invalidate, unlock */ + ori r3, r3, HID0_DCE + ori r5, r3, HID0_DCFI + mtspr HID0, r5 /* enable + invalidate */ + mtspr HID0, r3 /* enable */ sync - mtspr HID0, r3 /* clears invalidate */ blr .globl dcache_disable dcache_disable: mfspr r3, HID0 lis r4, 0 - ori r4, r4, HID0_ENABLE_DATA_CACHE|HID0_LOCK_DATA_CACHE + ori r4, r4, HID0_DCE|HID0_DLOCK andc r3, r3, r4 - ori r4, r3, HID0_INVALIDATE_DATA_CACHE + ori r4, r3, HID0_DCI sync - mtspr HID0, r4 /* sets invalidate, clears enable and lock */ + mtspr HID0, r4 /* sets invalidate, clears enable and lock */ sync mtspr HID0, r3 /* clears invalidate */ blr @@ -571,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 @@ -579,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 + /*-------------------------------------------------------------------*/ /* @@ -668,46 +959,29 @@ relocate_code: * Now flush the cache: note that we must start from a cache aligned * address. Otherwise we might miss one cache line. */ -4: - bl un_setup_stack_in_data_cache - mr r7, r3 - mr r8, r4 - bl dcache_disable - mr r3, r7 - mr r4, r8 - - cmpwi r6,0 +4: cmpwi r6,0 add r5,r3,r5 - beq 7f /* Always flush prefetch queue in any case */ + beq 7f /* Always flush prefetch queue in any case */ subi r0,r6,1 andc r3,r3,r0 - mfspr r7,HID0 /* don't do dcbst if dcache is disabled*/ - rlwinm r7,r7,HID0_DCE_SHIFT,31,31 - cmpwi r7,0 - beq 9f mr r4,r3 5: dcbst 0,r4 add r4,r4,r6 cmplw r4,r5 blt 5b - sync /* Wait for all dcbst to complete on bus */ -9: mfspr r7,HID0 /* don't do icbi if icache is disabled */ - rlwinm r7,r7,HID0_DCE_SHIFT,31,31 - cmpwi r7,0 - beq 7f + sync /* Wait for all dcbst to complete on bus */ mr r4,r3 6: icbi 0,r4 add r4,r4,r6 cmplw r4,r5 blt 6b -7: sync /* Wait for all icbi to complete on bus */ +7: sync /* Wait for all icbi to complete on bus */ isync /* * We are done. Do not return, instead branch to second part of board * initialization, now running from RAM. */ - addi r0, r10, in_ram - _start + EXC_OFF_SYS_RESET mtlr r0 blr @@ -865,6 +1139,27 @@ trap_reloc: blr #ifdef CFG_INIT_RAM_LOCK +lock_ram_in_cache: + /* Allocate Initial RAM in data cache. + */ + lis r3, (CFG_INIT_RAM_ADDR & ~31)@h + ori r3, r3, (CFG_INIT_RAM_ADDR & ~31)@l + li r2, ((CFG_INIT_RAM_END & ~31) + \ + (CFG_INIT_RAM_ADDR & 31) + 31) / 32 + mtctr r2 +1: + dcbz r0, r3 + addi r3, r3, 32 + bdnz 1b + + /* Lock the data cache */ + mfspr r0, HID0 + ori r0, r0, 0x1000 + sync + mtspr HID0, r0 + sync + blr + .globl unlock_ram_in_cache unlock_ram_in_cache: /* invalidate the INIT_RAM section */ @@ -878,6 +1173,15 @@ unlock_ram_in_cache: bdnz 1b sync /* Wait for all icbi to complete on bus */ isync + + /* Unlock the data cache and invalidate it */ + mfspr r3, HID0 + li r5, HID0_DLOCK|HID0_DCFI + andc r3, r3, r5 /* no invalidate, unlock */ + ori r5, r3, HID0_DCFI /* invalidate, unlock */ + mtspr HID0, r5 /* invalidate, unlock */ + mtspr HID0, r3 /* no invalidate, unlock */ + sync blr #endif @@ -946,148 +1250,3 @@ remap_flash_by_law0: stw r4, LBLAWBAR1(r3) stw r4, LBLAWAR1(r3) /* Off LBIU LAW1 */ blr - -setup_stack_in_data_cache_on_r1: - lis r3, (CFG_IMMRBAR)@h - - /* setup D-BAT for the D-Cache (with out real memory backup) */ - - lis r4, (CFG_INIT_RAM_ADDR & 0xFFFE0000)@h - mtspr DBAT0U, r4 - ori r4, r4, 0x0002 - mtspr DBAT0L, r4 - isync - -#if 0 - /* Enable MMU */ - mfmsr r4 - ori r4, r4, (MSR_DR | MSR_IR)@l - mtmsr r4 -#endif - - /* Enable and invalidate data cache. */ - mfspr r4, HID0 - mr r5, r4 - ori r4, r4, HID0_DCE | HID0_DCI - ori r5, r5, HID0_DCE - sync - mtspr HID0, r4 - mtspr HID0, r5 - sync - - /* Allocate Initial RAM in data cache.*/ - li r0, 0 - lis r4, (CFG_INIT_RAM_ADDR)@h - ori r4, r4, (CFG_INIT_RAM_ADDR)@l - li r5, 128*8 /* 128*8*32=32Kb */ - mtctr r5 -1: - dcbz r0, r4 - addi r4, r4, 32 - bdnz 1b - isync - - /* Lock all the D-cache, basically leaving the reset of the program without dcache */ - mfspr r4, HID0 - ori r4, r4, (HID0_DLOCK)@l - sync - mtspr HID0 , r4 - - /* setup the stack pointer in r1 */ - lis r1, (CFG_INIT_RAM_ADDR + CFG_GBL_DATA_OFFSET)@h - ori r1, r1, (CFG_INIT_RAM_ADDR + CFG_GBL_DATA_OFFSET)@l - li r0, 0 /* Make room for stack frame header and */ - - stwu r0, -4(r1) /* clear final stack frame so that */ - stwu r0, -4(r1) /* stack backtraces terminate cleanly */ - - blr - -un_setup_stack_in_data_cache: - blr - mr r14, r4 - mr r15, r5 - - - lis r4, (CFG_INIT_RAM_ADDR & 0xFFFE0000)@h - mtspr DBAT0U, r4 - ori r4, r4, 0x0002 - mtspr DBAT0L, r4 - isync - - /* un lock all the D-cache */ - mfspr r4, HID0 - lis r5, (~(HID0_DLOCK))@h - ori r5, r5, (~(HID0_DLOCK))@l - and r4, r4, r5 - sync - mtspr HID0 , r4 - - /* Re - Allocate Initial RAM in data cache.*/ - li r0, 0 - lis r4, (CFG_INIT_RAM_ADDR)@h - ori r4, r4, (CFG_INIT_RAM_ADDR)@l - li r5, 128*8 /* 128*8*32=32Kb */ - mtctr r5 -1: - dcbz r0, r4 - addi r4, r4, 32 - bdnz 1b - isync - - mflr r16 - bl dcache_disable - mtlr r16 - - blr - -#if 0 -#define GREEN_LIGHT 0x2B0D4046 -#define RED_LIGHT 0x250D4046 -#define LIB_CNT 0x4FFF - -/* - * Lib Light - */ - - .globl liblight -liblight: - lis r3, CFG_IMMRBAR@h - ori r3, r3, CFG_IMMRBAR@l - li r4, 0x3002 - mtmsr r4 - xor r4, r4, r4 - mtspr HID0, r4 - mtspr HID2, r4 - lis r4, 0xF8000000@h - ori r4, r4, 0xF8000000@l - stw r4, LBLAWBAR1(r3) - lis r4, 0x8000000E@h - ori r4, r4, 0x8000000E@l - stw r4, LBLAWAR1(r3) - lis r4, 0xF8000801@h - ori r4, r4, 0xF8000801@l - stw r4, BR1(r3) - lis r4, 0xFFFFE8f0@h - ori r4, r4, 0xFFFFE8f0@l - stw r4, OR1(r3) - - lis r4, 0xF8000000@h - ori r4, r4, 0xF8000000@l - lis r5, GREEN_LIGHT@h - ori r5, r5, GREEN_LIGHT@l - lis r6, RED_LIGHT@h - ori r6, r6, RED_LIGHT@l - lis r7, LIB_CNT@h - ori r7, r7, LIB_CNT@l - -1: - stw r5, 0(r4) - mtctr r7 -2: bdnz 2b - stw r6, 0(r4) - mtctr r7 -3: bdnz 3b - b 1b - -#endif diff --git a/cpu/mpc83xx/traps.c b/cpu/mpc83xx/traps.c index c7a5638..44345af 100644 --- a/cpu/mpc83xx/traps.c +++ b/cpu/mpc83xx/traps.c @@ -40,6 +40,8 @@ #include <asm/processor.h> #include <asm/mpc8349_pci.h> +DECLARE_GLOBAL_DATA_PTR; + /* Returns 0 if exception not found and fixup otherwise. */ extern unsigned long search_exception_table(unsigned long); @@ -52,7 +54,6 @@ extern unsigned long search_exception_table(unsigned long); void print_backtrace(unsigned long *sp) { - DECLARE_GLOBAL_DATA_PTR; int cnt = 0; unsigned long i; diff --git a/cpu/mpc85xx/commproc.c b/cpu/mpc85xx/commproc.c index aa8a5a5..3504d50 100644 --- a/cpu/mpc85xx/commproc.c +++ b/cpu/mpc85xx/commproc.c @@ -24,6 +24,8 @@ #include <common.h> #include <asm/cpm_85xx.h> +DECLARE_GLOBAL_DATA_PTR; + #if defined(CONFIG_CPM2) /* * because we have stack and init data in dual port ram @@ -35,8 +37,6 @@ void m8560_cpm_reset(void) { - DECLARE_GLOBAL_DATA_PTR; - volatile immap_t *immr = (immap_t *)CFG_IMMR; volatile ulong count; @@ -64,8 +64,6 @@ m8560_cpm_reset(void) uint m8560_cpm_dpalloc(uint size, uint align) { - DECLARE_GLOBAL_DATA_PTR; - volatile immap_t *immr = (immap_t *)CFG_IMMR; uint retloc; uint align_mask, off; @@ -122,8 +120,6 @@ m8560_cpm_hostalloc(uint size, uint align) void m8560_cpm_setbrg(uint brg, uint rate) { - DECLARE_GLOBAL_DATA_PTR; - volatile immap_t *immr = (immap_t *)CFG_IMMR; volatile uint *bp; @@ -146,8 +142,6 @@ m8560_cpm_setbrg(uint brg, uint rate) void m8560_cpm_fastbrg(uint brg, uint rate, int div16) { - DECLARE_GLOBAL_DATA_PTR; - volatile immap_t *immr = (immap_t *)CFG_IMMR; volatile uint *bp; diff --git a/cpu/mpc85xx/cpu_init.c b/cpu/mpc85xx/cpu_init.c index efde9cc..c12b47b 100644 --- a/cpu/mpc85xx/cpu_init.c +++ b/cpu/mpc85xx/cpu_init.c @@ -30,6 +30,8 @@ #include <ioports.h> #include <asm/io.h> +DECLARE_GLOBAL_DATA_PTR; + #ifdef CONFIG_CPM2 static void config_8560_ioports (volatile immap_t * immr) { @@ -103,7 +105,6 @@ static void config_8560_ioports (volatile immap_t * immr) void cpu_init_f (void) { - DECLARE_GLOBAL_DATA_PTR; volatile immap_t *immap = (immap_t *)CFG_IMMR; volatile ccsr_lbc_t *memctl = &immap->im_lbc; extern void m8560_cpm_reset (void); diff --git a/cpu/mpc85xx/serial_scc.c b/cpu/mpc85xx/serial_scc.c index cf060d6..4e925f8 100644 --- a/cpu/mpc85xx/serial_scc.c +++ b/cpu/mpc85xx/serial_scc.c @@ -35,6 +35,8 @@ #include <common.h> #include <asm/cpm_85xx.h> +DECLARE_GLOBAL_DATA_PTR; + #if defined(CONFIG_CPM2) #if defined(CONFIG_CONS_ON_SCC) @@ -186,8 +188,6 @@ int serial_init (void) void serial_setbrg (void) { - DECLARE_GLOBAL_DATA_PTR; - #if defined(CONFIG_CONS_USE_EXTC) m8560_cpm_extcbrg(SCC_INDEX, gd->baudrate, CONFIG_CONS_EXTC_RATE, CONFIG_CONS_EXTC_PINSEL); diff --git a/cpu/mpc85xx/speed.c b/cpu/mpc85xx/speed.c index d736742..ca81ee7 100644 --- a/cpu/mpc85xx/speed.c +++ b/cpu/mpc85xx/speed.c @@ -29,6 +29,8 @@ #include <ppc_asm.tmpl> #include <asm/processor.h> +DECLARE_GLOBAL_DATA_PTR; + /* --------------------------------------------------------------- */ void get_sys_info (sys_info_t * sysInfo) @@ -80,7 +82,6 @@ void get_sys_info (sys_info_t * sysInfo) int get_clocks (void) { - DECLARE_GLOBAL_DATA_PTR; sys_info_t sys_info; #if defined(CONFIG_CPM2) volatile immap_t *immap = (immap_t *) CFG_IMMR; diff --git a/cpu/mpc85xx/start.S b/cpu/mpc85xx/start.S index 7ac6573..f96a4c3 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/mpc85xx/traps.c b/cpu/mpc85xx/traps.c index a87eed2..904f052 100644 --- a/cpu/mpc85xx/traps.c +++ b/cpu/mpc85xx/traps.c @@ -39,6 +39,8 @@ #include <command.h> #include <asm/processor.h> +DECLARE_GLOBAL_DATA_PTR; + #if (CONFIG_COMMANDS & CFG_CMD_KGDB) int (*debugger_exception_handler)(struct pt_regs *) = 0; #endif @@ -83,7 +85,6 @@ extern void do_bedbug_breakpoint(struct pt_regs *); void print_backtrace(unsigned long *sp) { - DECLARE_GLOBAL_DATA_PTR; int cnt = 0; unsigned long i; diff --git a/cpu/mpc8xx/commproc.c b/cpu/mpc8xx/commproc.c index 75740e0..07c763c 100644 --- a/cpu/mpc8xx/commproc.c +++ b/cpu/mpc8xx/commproc.c @@ -24,12 +24,12 @@ #include <common.h> #include <commproc.h> +DECLARE_GLOBAL_DATA_PTR; + #ifdef CFG_ALLOC_DPRAM int dpram_init (void) { - DECLARE_GLOBAL_DATA_PTR; - /* Reclaim the DP memory for our use. */ gd->dp_alloc_base = CPM_DATAONLY_BASE; gd->dp_alloc_top = CPM_DATAONLY_BASE + CPM_DATAONLY_SIZE; @@ -43,7 +43,6 @@ int dpram_init (void) */ uint dpram_alloc (uint size) { - DECLARE_GLOBAL_DATA_PTR; uint addr = gd->dp_alloc_base; if ((gd->dp_alloc_base + size) >= gd->dp_alloc_top) @@ -56,8 +55,6 @@ uint dpram_alloc (uint size) uint dpram_base (void) { - DECLARE_GLOBAL_DATA_PTR; - return gd->dp_alloc_base; } @@ -67,8 +64,6 @@ uint dpram_base (void) */ uint dpram_alloc_align (uint size, uint align) { - DECLARE_GLOBAL_DATA_PTR; - uint addr, mask = align - 1; addr = (gd->dp_alloc_base + mask) & ~mask; @@ -83,8 +78,6 @@ uint dpram_alloc_align (uint size, uint align) uint dpram_base_align (uint align) { - DECLARE_GLOBAL_DATA_PTR; - uint mask = align - 1; return (gd->dp_alloc_base + mask) & ~mask; diff --git a/cpu/mpc8xx/cpu.c b/cpu/mpc8xx/cpu.c index 4a32986..97112f0 100644 --- a/cpu/mpc8xx/cpu.c +++ b/cpu/mpc8xx/cpu.c @@ -39,6 +39,8 @@ #include <mpc8xx.h> #include <asm/cache.h> +DECLARE_GLOBAL_DATA_PTR; + static char *cpu_warning = "\n " \ "*** Warning: CPU Core has Silicon Bugs -- Check the Errata ***"; @@ -69,14 +71,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 +96,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) @@ -344,8 +351,6 @@ static int check_CPU (long clock, uint pvr, uint immr) int checkcpu (void) { - DECLARE_GLOBAL_DATA_PTR; - ulong clock = gd->cpu_clk; uint immr = get_immr (0); /* Return full IMMR contents */ uint pvr = get_pvr (); @@ -534,8 +539,6 @@ int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) */ unsigned long get_tbclk (void) { - DECLARE_GLOBAL_DATA_PTR; - uint immr = get_immr (0); /* Return full IMMR contents */ volatile immap_t *immap = (volatile immap_t *)(immr & 0xFFFF0000); ulong oscclk, factor, pll; diff --git a/cpu/mpc8xx/cpu_init.c b/cpu/mpc8xx/cpu_init.c index b2c59c6..1a7111f 100644 --- a/cpu/mpc8xx/cpu_init.c +++ b/cpu/mpc8xx/cpu_init.c @@ -27,6 +27,10 @@ #include <mpc8xx.h> #include <commproc.h> +#if defined(CFG_RTCSC) || defined(CFG_RMDS) +DECLARE_GLOBAL_DATA_PTR; +#endif + #if defined(CFG_I2C_UCODE_PATCH) || defined(CFG_SPI_UCODE_PATCH) void cpm_load_patch (volatile immap_t * immr); #endif @@ -259,8 +263,6 @@ void cpu_init_f (volatile immap_t * immr) int cpu_init_r (void) { #if defined(CFG_RTCSC) || defined(CFG_RMDS) - DECLARE_GLOBAL_DATA_PTR; - bd_t *bd = gd->bd; volatile immap_t *immr = (volatile immap_t *) (bd->bi_immr_base); #endif diff --git a/cpu/mpc8xx/fec.c b/cpu/mpc8xx/fec.c index d2f5d88..6006478 100644 --- a/cpu/mpc8xx/fec.c +++ b/cpu/mpc8xx/fec.c @@ -27,6 +27,8 @@ #include <net.h> #include <command.h> +DECLARE_GLOBAL_DATA_PTR; + #undef ET_DEBUG #if (CONFIG_COMMANDS & CFG_CMD_NET) && \ @@ -371,7 +373,6 @@ static inline void fec_half_duplex(struct eth_device *dev) static void fec_pin_init(int fecidx) { - DECLARE_GLOBAL_DATA_PTR; bd_t *bd = gd->bd; volatile immap_t *immr = (immap_t *) CFG_IMMR; volatile fec_t *fecp; diff --git a/cpu/mpc8xx/i2c.c b/cpu/mpc8xx/i2c.c index 682db53..6c59374 100644 --- a/cpu/mpc8xx/i2c.c +++ b/cpu/mpc8xx/i2c.c @@ -37,6 +37,8 @@ #include <watchdog.h> #endif +DECLARE_GLOBAL_DATA_PTR; + /* define to enable debug messages */ #undef DEBUG_I2C @@ -205,8 +207,6 @@ i2c_setrate (int hz, int speed) void i2c_init(int speed, int slaveaddr) { - DECLARE_GLOBAL_DATA_PTR; - volatile immap_t *immap = (immap_t *)CFG_IMMR ; volatile cpm8xx_t *cp = (cpm8xx_t *)&immap->im_cpm; volatile i2c8xx_t *i2c = (i2c8xx_t *)&immap->im_i2c; @@ -615,8 +615,6 @@ int i2c_probe(uchar chip) int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len) { - DECLARE_GLOBAL_DATA_PTR; - i2c_state_t state; uchar xaddr[4]; int rc; @@ -671,8 +669,6 @@ int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len) int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len) { - DECLARE_GLOBAL_DATA_PTR; - i2c_state_t state; uchar xaddr[4]; int rc; diff --git a/cpu/mpc8xx/serial.c b/cpu/mpc8xx/serial.c index fa0405f..26a82cc 100644 --- a/cpu/mpc8xx/serial.c +++ b/cpu/mpc8xx/serial.c @@ -27,6 +27,8 @@ #include <serial.h> #include <watchdog.h> +DECLARE_GLOBAL_DATA_PTR; + #if !defined(CONFIG_8xx_CONS_NONE) /* No Console at all */ #if defined(CONFIG_8xx_CONS_SMC1) /* Console on SMC1 */ @@ -65,7 +67,6 @@ static void serial_setdivisor(volatile cpm8xx_t *cp) { - DECLARE_GLOBAL_DATA_PTR; int divisor=(gd->cpu_clk + 8*gd->baudrate)/16/gd->baudrate; if(divisor/16>0x1000) { @@ -268,8 +269,6 @@ smc_putc(const char c) volatile cpm8xx_t *cpmp = &(im->im_cpm); #ifdef CONFIG_MODEM_SUPPORT - DECLARE_GLOBAL_DATA_PTR; - if (gd->be_quiet) return; #endif @@ -553,8 +552,6 @@ scc_putc(const char c) volatile cpm8xx_t *cpmp = &(im->im_cpm); #ifdef CONFIG_MODEM_SUPPORT - DECLARE_GLOBAL_DATA_PTR; - if (gd->be_quiet) return; #endif @@ -649,13 +646,11 @@ struct serial_device serial_scc_device = #ifdef CONFIG_MODEM_SUPPORT void disable_putc(void) { - DECLARE_GLOBAL_DATA_PTR; gd->be_quiet = 1; } void enable_putc(void) { - DECLARE_GLOBAL_DATA_PTR; gd->be_quiet = 0; } #endif diff --git a/cpu/mpc8xx/speed.c b/cpu/mpc8xx/speed.c index f038316..57f91c0 100644 --- a/cpu/mpc8xx/speed.c +++ b/cpu/mpc8xx/speed.c @@ -25,6 +25,8 @@ #include <mpc8xx.h> #include <asm/processor.h> +DECLARE_GLOBAL_DATA_PTR; + #if !defined(CONFIG_8xx_CPUCLK_DEFAULT) || defined(CFG_MEASURE_CPUCLK) || defined(DEBUG) #define PITC_SHIFT 16 @@ -181,8 +183,6 @@ unsigned long measure_gclk(void) */ int get_clocks (void) { - DECLARE_GLOBAL_DATA_PTR; - uint immr = get_immr (0); /* Return full IMMR contents */ volatile immap_t *immap = (immap_t *) (immr & 0xFFFF0000); uint sccr = immap->im_clkrst.car_sccr; @@ -238,8 +238,6 @@ static long init_pll_866 (long clk); */ int get_clocks_866 (void) { - DECLARE_GLOBAL_DATA_PTR; - volatile immap_t *immr = (immap_t *) CFG_IMMR; char tmp[64]; long cpuclk = 0; @@ -277,8 +275,6 @@ int get_clocks_866 (void) */ int sdram_adjust_866 (void) { - DECLARE_GLOBAL_DATA_PTR; - volatile immap_t *immr = (immap_t *) CFG_IMMR; long mamr; @@ -371,8 +367,6 @@ static long init_pll_866 (long clk) */ int adjust_sdram_tbs_8xx (void) { - DECLARE_GLOBAL_DATA_PTR; - volatile immap_t *immr = (immap_t *) CFG_IMMR; long mamr; long sccr; diff --git a/cpu/mpc8xx/video.c b/cpu/mpc8xx/video.c index ee60477..918de67 100644 --- a/cpu/mpc8xx/video.c +++ b/cpu/mpc8xx/video.c @@ -39,6 +39,8 @@ #ifdef CONFIG_VIDEO +DECLARE_GLOBAL_DATA_PTR; + /************************************************************************/ /* ** DEBUG SETTINGS */ /************************************************************************/ @@ -1164,7 +1166,6 @@ static void *video_logo (void) u16 *screen = video_fb_address, width = VIDEO_COLS; #ifdef VIDEO_INFO # ifndef CONFIG_FADS - DECLARE_GLOBAL_DATA_PTR; char temp[32]; # endif char info[80]; @@ -1282,8 +1283,6 @@ static int video_init (void *videobase) int drv_video_init (void) { - DECLARE_GLOBAL_DATA_PTR; - int error, devices = 1; device_t videodev; diff --git a/cpu/nios/serial.c b/cpu/nios/serial.c index 4bdda25..5ecdc6d 100644 --- a/cpu/nios/serial.c +++ b/cpu/nios/serial.c @@ -26,6 +26,8 @@ #include <watchdog.h> #include <nios-io.h> +DECLARE_GLOBAL_DATA_PTR; + /*------------------------------------------------------------------ * JTAG acts as the serial port *-----------------------------------------------------------------*/ @@ -83,7 +85,6 @@ int serial_init (void) { return (0);} void serial_setbrg (void) { - DECLARE_GLOBAL_DATA_PTR; unsigned div; div = (CONFIG_SYS_CLK_FREQ/gd->baudrate)-1; diff --git a/cpu/nios2/serial.c b/cpu/nios2/serial.c index 2d08c93..3d76603 100644 --- a/cpu/nios2/serial.c +++ b/cpu/nios2/serial.c @@ -27,6 +27,8 @@ #include <nios2.h> #include <nios2-io.h> +DECLARE_GLOBAL_DATA_PTR; + /*------------------------------------------------------------------ * JTAG acts as the serial port *-----------------------------------------------------------------*/ @@ -93,7 +95,6 @@ int serial_init (void) { return (0);} void serial_setbrg (void) { - DECLARE_GLOBAL_DATA_PTR; unsigned div; div = (CONFIG_SYS_CLK_FREQ/gd->baudrate)-1; diff --git a/cpu/ppc4xx/405gp_pci.c b/cpu/ppc4xx/405gp_pci.c index 64431ab..fad895b 100644 --- a/cpu/ppc4xx/405gp_pci.c +++ b/cpu/ppc4xx/405gp_pci.c @@ -77,10 +77,16 @@ #include <asm/processor.h> #include <pci.h> +DECLARE_GLOBAL_DATA_PTR; + #if defined(CONFIG_405GP) || defined(CONFIG_405EP) #ifdef CONFIG_PCI +#if defined(CONFIG_PMC405) +ushort pmc405_pci_subsys_deviceid(void); +#endif + /*#define DEBUG*/ /*-----------------------------------------------------------------------------+ @@ -88,21 +94,16 @@ *-----------------------------------------------------------------------------*/ void pci_405gp_init(struct pci_controller *hose) { - DECLARE_GLOBAL_DATA_PTR; - int i, reg_num = 0; bd_t *bd = gd->bd; unsigned short temp_short; unsigned long ptmpcila[2] = {CFG_PCI_PTM1PCI, CFG_PCI_PTM2PCI}; #if defined(CONFIG_CPCI405) || defined(CONFIG_PMC405) - unsigned long ptmla[2] = {bd->bi_memstart, bd->bi_flashstart}; - unsigned long ptmms[2] = {~(bd->bi_memsize - 1) | 1, ~(bd->bi_flashsize - 1) | 1}; char *ptmla_str, *ptmms_str; -#else +#endif unsigned long ptmla[2] = {CFG_PCI_PTM1LA, CFG_PCI_PTM2LA}; unsigned long ptmms[2] = {CFG_PCI_PTM1MS, CFG_PCI_PTM2MS}; -#endif #if defined(CONFIG_PIP405) || defined (CONFIG_MIP405) unsigned long pmmla[3] = {0x80000000, 0xA0000000, 0}; unsigned long pmmma[3] = {0xE0000001, 0xE0000001, 0}; @@ -372,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/cpu.c b/cpu/ppc4xx/cpu.c index a26533c..0cd72b0 100644 --- a/cpu/ppc4xx/cpu.c +++ b/cpu/ppc4xx/cpu.c @@ -37,6 +37,10 @@ #include <asm/cache.h> #include <ppc4xx.h> +#if !defined(CONFIG_405) +DECLARE_GLOBAL_DATA_PTR; +#endif + #if defined(CONFIG_440) #define FREQ_EBC (sys_info.freqEPB) @@ -116,7 +120,6 @@ static int do_chip_reset(unsigned long sys0, unsigned long sys1); int checkcpu (void) { #if !defined(CONFIG_405) /* not used on Xilinx 405 FPGA implementations */ - DECLARE_GLOBAL_DATA_PTR; uint pvr = get_pvr(); ulong clock = gd->cpu_clk; char buf[32]; diff --git a/cpu/ppc4xx/cpu_init.c b/cpu/ppc4xx/cpu_init.c index 79cfba3..1a139d7 100644 --- a/cpu/ppc4xx/cpu_init.c +++ b/cpu/ppc4xx/cpu_init.c @@ -27,6 +27,10 @@ #include <asm/processor.h> #include <ppc4xx.h> +#if defined(CONFIG_405GP) || defined(CONFIG_405EP) +DECLARE_GLOBAL_DATA_PTR; +#endif + #define mtebc(reg, data) mtdcr(ebccfga,reg);mtdcr(ebccfgd,data) @@ -209,8 +213,6 @@ cpu_init_f (void) int cpu_init_r (void) { #if defined(CONFIG_405GP) || defined(CONFIG_405EP) - DECLARE_GLOBAL_DATA_PTR; - bd_t *bd = gd->bd; unsigned long reg; #if defined(CONFIG_405GP) diff --git a/cpu/ppc4xx/i2c.c b/cpu/ppc4xx/i2c.c index be94b57..7db1cd8 100644 --- a/cpu/ppc4xx/i2c.c +++ b/cpu/ppc4xx/i2c.c @@ -16,6 +16,8 @@ #ifdef CONFIG_HARD_I2C +DECLARE_GLOBAL_DATA_PTR; + #define IIC_OK 0 #define IIC_NOK 1 #define IIC_NOK_LA 2 /* Lost arbitration */ @@ -350,7 +352,6 @@ int i2c_read (uchar chip, uint addr, int alen, uchar * buffer, int len) { uchar xaddr[4]; int ret; - DECLARE_GLOBAL_DATA_PTR; if ( alen > 4 ) { printf ("I2C read: addr len %d not supported\n", alen); diff --git a/cpu/ppc4xx/interrupts.c b/cpu/ppc4xx/interrupts.c index 1d8dc7c..3aae4ce 100644 --- a/cpu/ppc4xx/interrupts.c +++ b/cpu/ppc4xx/interrupts.c @@ -36,6 +36,8 @@ #include <commproc.h> #include "vecnum.h" +DECLARE_GLOBAL_DATA_PTR; + /****************************************************************************/ /* @@ -96,8 +98,6 @@ static __inline__ void set_evpr(unsigned long val) int interrupt_init_cpu (unsigned *decrementer_count) { - DECLARE_GLOBAL_DATA_PTR; - int vec; unsigned long val; diff --git a/cpu/ppc4xx/sdram.c b/cpu/ppc4xx/sdram.c index e9548cd..e31d59d 100644 --- a/cpu/ppc4xx/sdram.c +++ b/cpu/ppc4xx/sdram.c @@ -1,7 +1,10 @@ /* - * (C) Copyright 2005 + * (C) Copyright 2005-2006 * Stefan Roese, DENX Software Engineering, sr@denx.de. * + * (C) Copyright 2006 + * DAVE Srl <www.dave-tech.it> + * * (C) Copyright 2002-2004 * Stefan Roese, esd gmbh germany, stefan.roese@esd-electronics.com * @@ -15,7 +18,7 @@ * * 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 + * 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 @@ -27,63 +30,161 @@ #include <common.h> #include <ppc4xx.h> #include <asm/processor.h> +#include "sdram.h" #ifdef CONFIG_SDRAM_BANK0 -#define mtsdram0(reg, data) mtdcr(memcfga,reg);mtdcr(memcfgd,data) - - -struct sdram_conf_s { - unsigned long size; - unsigned long reg; -}; - -typedef struct sdram_conf_s sdram_conf_t; - #ifndef CFG_SDRAM_TABLE sdram_conf_t mb0cf[] = { - {(128 << 20), 0x000A4001}, /* (0-128MB) Address Mode 3, 13x10(4) */ - {(64 << 20), 0x00084001}, /* (0-64MB) Address Mode 3, 13x9(4) */ - {(32 << 20), 0x00062001}, /* (0-32MB) Address Mode 2, 12x9(4) */ - {(16 << 20), 0x00046001}, /* (0-16MB) Address Mode 4, 12x8(4) */ - {(4 << 20), 0x00008001}, /* (0-4MB) Address Mode 5, 11x8(2) */ + {(128 << 20), 13, 0x000A4001}, /* (0-128MB) Address Mode 3, 13x10(4) */ + {(64 << 20), 13, 0x00084001}, /* (0-64MB) Address Mode 3, 13x9(4) */ + {(32 << 20), 12, 0x00062001}, /* (0-32MB) Address Mode 2, 12x9(4) */ + {(16 << 20), 12, 0x00046001}, /* (0-16MB) Address Mode 4, 12x8(4) */ + {(4 << 20), 11, 0x00008001}, /* (0-4MB) Address Mode 5, 11x8(2) */ }; #else sdram_conf_t mb0cf[] = CFG_SDRAM_TABLE; #endif -#define N_MB0CF (sizeof(mb0cf) / sizeof(mb0cf[0])) +#define N_MB0CF (sizeof(mb0cf) / sizeof(mb0cf[0])) #ifndef CONFIG_440 -/* - * Autodetect onboard SDRAM on 405 platforms - */ -void sdram_init(void) +#ifdef CFG_SDRAM_CASL +static ulong ns2clks(ulong ns) { - ulong sdtr1; - ulong rtr; - int i; + ulong bus_period_x_10 = ONE_BILLION / (get_bus_freq(0) / 10); + return ((ns * 10) + bus_period_x_10) / bus_period_x_10; +} +#endif /* CFG_SDRAM_CASL */ + +static ulong compute_sdtr1(ulong speed) +{ +#ifdef CFG_SDRAM_CASL + ulong tmp; + ulong sdtr1 = 0; + + /* CASL */ + if (CFG_SDRAM_CASL < 2) + sdtr1 |= (1 << SDRAM0_TR_CASL); + else + if (CFG_SDRAM_CASL > 4) + sdtr1 |= (3 << SDRAM0_TR_CASL); + else + sdtr1 |= ((CFG_SDRAM_CASL-1) << SDRAM0_TR_CASL); + + /* PTA */ + tmp = ns2clks(CFG_SDRAM_PTA); + if ((tmp >= 2) && (tmp <= 4)) + sdtr1 |= ((tmp-1) << SDRAM0_TR_PTA); + else + sdtr1 |= ((4-1) << SDRAM0_TR_PTA); + + /* CTP */ + tmp = ns2clks(CFG_SDRAM_CTP); + if ((tmp >= 2) && (tmp <= 4)) + sdtr1 |= ((tmp-1) << SDRAM0_TR_CTP); + else + sdtr1 |= ((4-1) << SDRAM0_TR_CTP); + + /* LDF */ + tmp = ns2clks(CFG_SDRAM_LDF); + if ((tmp >= 2) && (tmp <= 4)) + sdtr1 |= ((tmp-1) << SDRAM0_TR_LDF); + else + sdtr1 |= ((2-1) << SDRAM0_TR_LDF); + + /* RFTA */ + tmp = ns2clks(CFG_SDRAM_RFTA); + if ((tmp >= 4) && (tmp <= 10)) + sdtr1 |= ((tmp-4) << SDRAM0_TR_RFTA); + else + sdtr1 |= ((10-4) << SDRAM0_TR_RFTA); + + /* RCD */ + tmp = ns2clks(CFG_SDRAM_RCD); + if ((tmp >= 2) && (tmp <= 4)) + sdtr1 |= ((tmp-1) << SDRAM0_TR_RCD); + else + sdtr1 |= ((4-1) << SDRAM0_TR_RCD); + + return sdtr1; +#else /* CFG_SDRAM_CASL */ /* - * Support for 100MHz and 133MHz SDRAM + * If no values are configured in the board config file + * use the default values, which seem to be ok for most + * boards. + * + * REMARK: + * For new board ports we strongly recommend to define the + * correct values for the used SDRAM chips in your board + * config file (see PPChameleonEVB.h) */ - if (get_bus_freq(0) > 100000000) { + if (speed > 100000000) { /* * 133 MHz SDRAM */ - sdtr1 = 0x01074015; - rtr = 0x07f00000; + return 0x01074015; } else { /* * default: 100 MHz SDRAM */ - sdtr1 = 0x0086400d; - rtr = 0x05f00000; + return 0x0086400d; } +#endif /* CFG_SDRAM_CASL */ +} + +/* refresh is expressed in ms */ +static ulong compute_rtr(ulong speed, ulong rows, ulong refresh) +{ +#ifdef CFG_SDRAM_CASL + ulong tmp; + + tmp = ((refresh*1000*1000) / (1 << rows)) * (speed / 1000); + tmp /= 1000000; + + return ((tmp & 0x00003FF8) << 16); +#else /* CFG_SDRAM_CASL */ + if (speed > 100000000) { + /* + * 133 MHz SDRAM + */ + return 0x07f00000; + } else { + /* + * default: 100 MHz SDRAM + */ + return 0x05f00000; + } +#endif /* CFG_SDRAM_CASL */ +} + +/* + * Autodetect onboard SDRAM on 405 platforms + */ +void sdram_init(void) +{ + ulong speed; + ulong sdtr1; + int i; + + /* + * Determine SDRAM speed + */ + speed = get_bus_freq(0); /* parameter not used on ppc4xx */ + + /* + * sdtr1 (register SDRAM0_TR) must take into account timings listed + * in SDRAM chip datasheet. rtr (register SDRAM0_RTR) must take into + * account actual SDRAM size. So we can set up sdtr1 according to what + * is specified in board configuration file while rtr dependds on SDRAM + * size we are assuming before detection. + */ + sdtr1 = compute_sdtr1(speed); for (i=0; i<N_MB0CF; i++) { /* @@ -96,7 +197,7 @@ void sdram_init(void) */ mtsdram0(mem_mb0cf, mb0cf[i].reg); mtsdram0(mem_sdtr1, sdtr1); - mtsdram0(mem_rtr, rtr); + mtsdram0(mem_rtr, compute_rtr(speed, mb0cf[i].rows, 64)); udelay(200); @@ -120,16 +221,135 @@ void sdram_init(void) #else /* CONFIG_440 */ +#define NUM_TRIES 64 +#define NUM_READS 10 + +static void sdram_tr1_set(int ram_address, int* tr1_value) +{ + int i; + int j, k; + volatile unsigned int* ram_pointer = (unsigned int *)ram_address; + int first_good = -1, last_bad = 0x1ff; + + unsigned long test[NUM_TRIES] = { + 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, + 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, + 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, + 0xAAAAAAAA, 0xAAAAAAAA, 0x55555555, 0x55555555, + 0xAAAAAAAA, 0xAAAAAAAA, 0x55555555, 0x55555555, + 0x55555555, 0x55555555, 0xAAAAAAAA, 0xAAAAAAAA, + 0x55555555, 0x55555555, 0xAAAAAAAA, 0xAAAAAAAA, + 0xA5A5A5A5, 0xA5A5A5A5, 0x5A5A5A5A, 0x5A5A5A5A, + 0xA5A5A5A5, 0xA5A5A5A5, 0x5A5A5A5A, 0x5A5A5A5A, + 0x5A5A5A5A, 0x5A5A5A5A, 0xA5A5A5A5, 0xA5A5A5A5, + 0x5A5A5A5A, 0x5A5A5A5A, 0xA5A5A5A5, 0xA5A5A5A5, + 0xAA55AA55, 0xAA55AA55, 0x55AA55AA, 0x55AA55AA, + 0xAA55AA55, 0xAA55AA55, 0x55AA55AA, 0x55AA55AA, + 0x55AA55AA, 0x55AA55AA, 0xAA55AA55, 0xAA55AA55, + 0x55AA55AA, 0x55AA55AA, 0xAA55AA55, 0xAA55AA55 }; + + /* go through all possible SDRAM0_TR1[RDCT] values */ + for (i=0; i<=0x1ff; i++) { + /* set the current value for TR1 */ + mtsdram(mem_tr1, (0x80800800 | i)); + + /* write values */ + for (j=0; j<NUM_TRIES; j++) { + ram_pointer[j] = test[j]; + + /* clear any cache at ram location */ + __asm__("dcbf 0,%0": :"r" (&ram_pointer[j])); + } + + /* read values back */ + for (j=0; j<NUM_TRIES; j++) { + for (k=0; k<NUM_READS; k++) { + /* clear any cache at ram location */ + __asm__("dcbf 0,%0": :"r" (&ram_pointer[j])); + + if (ram_pointer[j] != test[j]) + break; + } + + /* read error */ + if (k != NUM_READS) + break; + } + + /* we have a SDRAM0_TR1[RDCT] that is part of the window */ + if (j == NUM_TRIES) { + if (first_good == -1) + first_good = i; /* found beginning of window */ + } else { /* bad read */ + /* if we have not had a good read then don't care */ + if (first_good != -1) { + /* first failure after a good read */ + last_bad = i-1; + break; + } + } + } + + /* return the current value for TR1 */ + *tr1_value = (first_good + last_bad) / 2; +} + + +#ifdef CONFIG_SDRAM_ECC +static void ecc_init(ulong start, ulong size) +{ + ulong current_addr; /* current byte address */ + ulong end_addr; /* end of memory region */ + ulong addr_inc; /* address skip between writes */ + ulong cfg0_reg; /* for restoring ECC state */ + + /* + * TODO: Enable dcache before running this test (speedup) + */ + + mfsdram(mem_cfg0, cfg0_reg); + mtsdram(mem_cfg0, (cfg0_reg & ~SDRAM_CFG0_MEMCHK) | SDRAM_CFG0_MEMCHK_GEN); + + /* + * look at geometry of SDRAM (data width) to determine whether we + * can skip words when writing + */ + if ((cfg0_reg & SDRAM_CFG0_DRAMWDTH) == SDRAM_CFG0_DRAMWDTH_32) + addr_inc = 4; + else + addr_inc = 8; + + current_addr = start; + end_addr = start + size; + + while (current_addr < end_addr) { + *((ulong *)current_addr) = 0x00000000; + current_addr += addr_inc; + } + + /* + * TODO: Flush dcache and disable it again + */ + + /* + * Enable ecc checking and parity errors + */ + mtsdram(mem_cfg0, (cfg0_reg & ~SDRAM_CFG0_MEMCHK) | SDRAM_CFG0_MEMCHK_CHK); +} +#endif + /* * Autodetect onboard DDR SDRAM on 440 platforms * * NOTE: Some of the hardcoded values are hardware dependant, - * so this should be extended for other future boards - * using this routine! + * so this should be extended for other future boards + * using this routine! */ long int initdram(int board_type) { int i; + int tr1_bank1; for (i=0; i<N_MB0CF; i++) { /* @@ -140,11 +360,11 @@ long int initdram(int board_type) /* * Setup some default */ - mtsdram(mem_uabba, 0x00000000); /* ubba=0 (default) */ - mtsdram(mem_slio, 0x00000000); /* rdre=0 wrre=0 rarw=0 */ + mtsdram(mem_uabba, 0x00000000); /* ubba=0 (default) */ + mtsdram(mem_slio, 0x00000000); /* rdre=0 wrre=0 rarw=0 */ mtsdram(mem_devopt, 0x00000000); /* dll=0 ds=0 (normal) */ mtsdram(mem_wddctr, 0x00000000); /* wrcp=0 dcd=0 */ - mtsdram(mem_clktr, 0x40000000); /* clkp=1 (90 deg wr) dcdt=0 */ + mtsdram(mem_clktr, 0x40000000); /* clkp=1 (90 deg wr) dcdt=0 */ /* * Following for CAS Latency = 2.5 @ 133 MHz PLB @@ -159,11 +379,21 @@ long int initdram(int board_type) /* * Enable the controller, then wait for DCEN to complete */ - mtsdram(mem_cfg0, 0x86000000); /* DCEN=1, PMUD=1, 64-bit */ + mtsdram(mem_cfg0, 0x86000000); /* DCEN=1, PMUD=1, 64-bit */ udelay(10000); if (get_ram_size(0, mb0cf[i].size) == mb0cf[i].size) { /* + * Optimize TR1 to current hardware environment + */ + sdram_tr1_set(0x00000000, &tr1_bank1); + mtsdram(mem_tr1, (tr1_bank1 | 0x80800800)); + +#ifdef CONFIG_SDRAM_ECC + ecc_init(0, mb0cf[i].size); +#endif + + /* * OK, size detected -> all done */ return mb0cf[i].size; diff --git a/cpu/ppc4xx/sdram.h b/cpu/ppc4xx/sdram.h new file mode 100644 index 0000000..62b5442 --- /dev/null +++ b/cpu/ppc4xx/sdram.h @@ -0,0 +1,78 @@ +/* + * (C) Copyright 2006 + * Stefan Roese, DENX Software Engineering, sr@denx.de. + * + * (C) Copyright 2006 + * DAVE Srl <www.dave-tech.it> + * + * 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 _SDRAM_H_ +#define _SDRAM_H_ + +#include <config.h> + +#define mtsdram0(reg, data) mtdcr(memcfga,reg);mtdcr(memcfgd,data) + +#define ONE_BILLION 1000000000 + +struct sdram_conf_s { + unsigned long size; + int rows; + unsigned long reg; +}; + +typedef struct sdram_conf_s sdram_conf_t; + +/* Bitfields offsets */ +#define SDRAM0_TR_CASL (31 - 8) +#define SDRAM0_TR_PTA (31 - 13) +#define SDRAM0_TR_CTP (31 - 15) +#define SDRAM0_TR_LDF (31 - 17) +#define SDRAM0_TR_RFTA (31 - 29) +#define SDRAM0_TR_RCD (31 - 31) + +#ifdef CFG_SDRAM_CL +/* SDRAM timings [ns] according to AMCC/IBM names (see SDRAM_faq.doc) */ +#define CFG_SDRAM_CASL CFG_SDRAM_CL +#define CFG_SDRAM_PTA CFG_SDRAM_tRP +#define CFG_SDRAM_CTP (CFG_SDRAM_tRC - CFG_SDRAM_tRCD - CFG_SDRAM_tRP) +#define CFG_SDRAM_LDF 0 +#ifdef CFG_SDRAM_tRFC +#define CFG_SDRAM_RFTA CFG_SDRAM_tRFC +#else +#define CFG_SDRAM_RFTA CFG_SDRAM_tRC +#endif +#define CFG_SDRAM_RCD CFG_SDRAM_tRCD +#endif /* #ifdef CFG_SDRAM_CL */ + +/* + * Some defines for the 440 DDR controller + */ +#define SDRAM_CFG0_DC_EN 0x80000000 /* SDRAM Controller Enable */ +#define SDRAM_CFG0_MEMCHK 0x30000000 /* Memory data error checking mask*/ +#define SDRAM_CFG0_MEMCHK_NON 0x00000000 /* No ECC generation */ +#define SDRAM_CFG0_MEMCHK_GEN 0x20000000 /* ECC generation */ +#define SDRAM_CFG0_MEMCHK_CHK 0x30000000 /* ECC generation and checking */ +#define SDRAM_CFG0_DRAMWDTH 0x02000000 /* DRAM width mask */ +#define SDRAM_CFG0_DRAMWDTH_32 0x00000000 /* 32 bits */ +#define SDRAM_CFG0_DRAMWDTH_64 0x02000000 /* 64 bits */ + +#endif diff --git a/cpu/ppc4xx/serial.c b/cpu/ppc4xx/serial.c index e7f6bcb..83c9479 100644 --- a/cpu/ppc4xx/serial.c +++ b/cpu/ppc4xx/serial.c @@ -59,6 +59,8 @@ #include <malloc.h> #endif +DECLARE_GLOBAL_DATA_PTR; + /*****************************************************************************/ #ifdef CONFIG_IOP480 @@ -161,8 +163,6 @@ int serial_init (void) { - DECLARE_GLOBAL_DATA_PTR; - volatile char val; unsigned short br_reg; @@ -185,8 +185,6 @@ int serial_init (void) void serial_setbrg (void) { - DECLARE_GLOBAL_DATA_PTR; - unsigned short br_reg; br_reg = ((((CONFIG_CPUCLOCK * 1000000) / 16) / gd->baudrate) - 1); @@ -431,8 +429,6 @@ int serial_init_dev (unsigned long dev_base) int serial_init(void) #endif { - DECLARE_GLOBAL_DATA_PTR; - unsigned long reg; unsigned long udiv; unsigned short bdiv; @@ -520,8 +516,6 @@ int serial_init_dev (unsigned long dev_base) int serial_init (void) #endif { - DECLARE_GLOBAL_DATA_PTR; - unsigned long reg; unsigned long tmp; unsigned long clk; @@ -597,8 +591,6 @@ void serial_setbrg_dev (unsigned long dev_base) void serial_setbrg (void) #endif { - DECLARE_GLOBAL_DATA_PTR; - unsigned long tmp; unsigned long clk; unsigned long udiv; @@ -880,8 +872,6 @@ int serial_buffered_tstc (void) #if (CONFIG_KGDB_SER_INDEX & 2) void kgdb_serial_init (void) { - DECLARE_GLOBAL_DATA_PTR; - volatile char val; unsigned short br_reg; diff --git a/cpu/ppc4xx/speed.c b/cpu/ppc4xx/speed.c index 553c491..02b4383 100644 --- a/cpu/ppc4xx/speed.c +++ b/cpu/ppc4xx/speed.c @@ -26,7 +26,7 @@ #include <ppc4xx.h> #include <asm/processor.h> -/* ------------------------------------------------------------------------- */ +DECLARE_GLOBAL_DATA_PTR; #define ONE_BILLION 1000000000 @@ -522,8 +522,6 @@ ulong get_PCI_freq (void) int get_clocks (void) { #if defined(CONFIG_405GP) || defined(CONFIG_405CR) || defined(CONFIG_440) || defined(CONFIG_405) || defined(CONFIG_405EP) - DECLARE_GLOBAL_DATA_PTR; - sys_info_t sys_info; get_sys_info (&sys_info); @@ -533,8 +531,6 @@ int get_clocks (void) #endif /* defined(CONFIG_405GP) || defined(CONFIG_405CR) */ #ifdef CONFIG_IOP480 - DECLARE_GLOBAL_DATA_PTR; - gd->cpu_clk = 66000000; gd->bus_clk = 66000000; #endif diff --git a/cpu/ppc4xx/start.S b/cpu/ppc4xx/start.S index 48b430d..948de43 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 d1551dd..0ee8180 100644 --- a/cpu/pxa/cpu.c +++ b/cpu/pxa/cpu.c @@ -34,14 +34,16 @@ #include <command.h> #include <asm/arch/pxa-regs.h> +#ifdef CONFIG_USE_IRQ +DECLARE_GLOBAL_DATA_PTR; +#endif + int cpu_init (void) { /* * setup up stacks if necessary */ #ifdef CONFIG_USE_IRQ - DECLARE_GLOBAL_DATA_PTR; - IRQ_STACK_START = _armboot_start - CFG_MALLOC_LEN - CFG_GBL_DATA_SIZE - 4; FIQ_STACK_START = IRQ_STACK_START - CONFIG_STACKSIZE_IRQ; #endif @@ -143,6 +145,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 +163,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/i2c.c b/cpu/pxa/i2c.c index b6155b1..722d949 100644 --- a/cpu/pxa/i2c.c +++ b/cpu/pxa/i2c.c @@ -47,7 +47,13 @@ /*#define DEBUG_I2C 1 /###* activate local debugging output */ #define I2C_PXA_SLAVE_ADDR 0x1 /* slave pxa unit address */ -#define I2C_ICR_INIT (ICR_BEIE | ICR_IRFIE | ICR_ITEIE | ICR_GCD | ICR_SCLE) + +#if (CFG_I2C_SPEED == 400000) +#define I2C_ICR_INIT (ICR_FM | ICR_BEIE | ICR_IRFIE | ICR_ITEIE | ICR_GCD | ICR_SCLE) +#else +#define I2C_ICR_INIT (ICR_BEIE | ICR_IRFIE | ICR_ITEIE | ICR_GCD | ICR_SCLE) +#endif + #define I2C_ISR_INIT 0x7FF #ifdef DEBUG_I2C @@ -91,7 +97,11 @@ static void i2c_reset( void ) ICR |= ICR_UR; /* reset the unit */ udelay(100); ICR &= ~ICR_IUE; /* disable unit */ +#ifdef CONFIG_CPU_MONAHANS + CKENB |= (CKENB_4_I2C); /* | CKENB_1_PWM1 | CKENB_0_PWM0); */ +#else /* CONFIG_CPU_MONAHANS */ CKEN |= CKEN14_I2C; /* set the global I2C clock on */ +#endif ISAR = I2C_PXA_SLAVE_ADDR; /* set our slave address */ ICR = I2C_ICR_INIT; /* set control register values */ ISR = I2C_ISR_INIT; /* set clear interrupt bits */ @@ -104,9 +114,8 @@ static void i2c_reset( void ) * i2c_isr_set_cleared: - wait until certain bits of the I2C status register * are set and cleared * - * @return: 0 in case of success, 1 means timeout (no match within 10 ms). + * @return: 1 in case of success, 0 means timeout (no match within 10 ms). */ - static int i2c_isr_set_cleared( unsigned long set_mask, unsigned long cleared_mask ) { int timeout = 10000; @@ -360,9 +369,9 @@ int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len) msg.data = 0x00; if ((ret=i2c_transfer(&msg))) return -1; - *(buffer++) = msg.data; - + *buffer = msg.data; PRINTD(("i2c_read: reading byte (0x%08x)=0x%02x\n",(unsigned int)buffer,*buffer)); + buffer++; } diff --git a/cpu/pxa/serial.c b/cpu/pxa/serial.c index cedebfe..cb3a478 100644 --- a/cpu/pxa/serial.c +++ b/cpu/pxa/serial.c @@ -32,10 +32,10 @@ #include <watchdog.h> #include <asm/arch/pxa-regs.h> +DECLARE_GLOBAL_DATA_PTR; + void serial_setbrg (void) { - DECLARE_GLOBAL_DATA_PTR; - unsigned int quot = 0; if (gd->baudrate == 1200) @@ -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 a8cc080..ffaa30f 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,15 @@ OSTIMER_BASE: .word 0x40a00000 #define OWER 0x18 #define OIER 0x1C -/* Clock Manager Registers */ +/* Clock Manager Registers */ +#ifdef CONFIG_CPU_MONAHANS +# ifndef CFG_MONAHANS_RUN_MODE_OSC_RATIO +# error "You have to define CFG_MONAHANS_RUN_MODE_OSC_RATIO!!" +# endif +# ifndef CFG_MONAHANS_TURBO_RUN_MODE_RATIO +# define CFG_MONAHANS_TURBO_RUN_MODE_RATIO 0x1 +# endif +#else /* ! CONFIG_CPU_MONAHANS */ #ifdef CFG_CPUSPEED CC_BASE: .word 0x41300000 #define CCCR 0x00 @@ -188,26 +205,50 @@ cpuspeed: .word CFG_CPUSPEED #else #error "You have to define CFG_CPUSPEED!!" #endif +#endif /* CONFIG_CPU_MONAHANS */ - - /* 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] - -#if defined(CFG_CPUSPEED) +#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 /* set clock speed */ +#ifdef CONFIG_CPU_MONAHANS + ldr r0, =ACCR + ldr r1, =(((CFG_MONAHANS_TURBO_RUN_MODE_RATIO<<8) & ACCR_XN_MASK) | (CFG_MONAHANS_RUN_MODE_OSC_RATIO & ACCR_XL_MASK)) + str r1, [r0] +#else /* ! CONFIG_CPU_MONAHANS */ +#ifdef CFG_CPUSPEED ldr r0, CC_BASE ldr r1, cpuspeed str r1, [r0, #CCCR] @@ -215,7 +256,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 +270,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 +337,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 +464,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 +482,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] diff --git a/cpu/s3c44b0/serial.c b/cpu/s3c44b0/serial.c index 70b4ee8..95d0266 100644 --- a/cpu/s3c44b0/serial.c +++ b/cpu/s3c44b0/serial.c @@ -37,6 +37,8 @@ #include <common.h> #include <asm/hardware.h> +DECLARE_GLOBAL_DATA_PTR; + /* flush serial input queue. returns 0 on success or negative error * number otherwise */ @@ -68,8 +70,6 @@ static int serial_flush_output(void) void serial_setbrg (void) { - DECLARE_GLOBAL_DATA_PTR; - u32 divisor = 0; /* get correct divisor */ diff --git a/cpu/sa1100/cpu.c b/cpu/sa1100/cpu.c index 17e5b0d..f1bd644 100644 --- a/cpu/sa1100/cpu.c +++ b/cpu/sa1100/cpu.c @@ -33,14 +33,16 @@ #include <common.h> #include <command.h> +#ifdef CONFIG_USE_IRQ +DECLARE_GLOBAL_DATA_PTR; +#endif + int cpu_init (void) { /* * setup up stacks if necessary */ #ifdef CONFIG_USE_IRQ - DECLARE_GLOBAL_DATA_PTR; - IRQ_STACK_START = _armboot_start - CFG_MALLOC_LEN - CFG_GBL_DATA_SIZE - 4; FIQ_STACK_START = IRQ_STACK_START - CONFIG_STACKSIZE_IRQ; #endif diff --git a/cpu/sa1100/serial.c b/cpu/sa1100/serial.c index a598489..5d18875 100644 --- a/cpu/sa1100/serial.c +++ b/cpu/sa1100/serial.c @@ -31,10 +31,10 @@ #include <common.h> #include <SA-1100.h> +DECLARE_GLOBAL_DATA_PTR; + void serial_setbrg (void) { - DECLARE_GLOBAL_DATA_PTR; - unsigned int reg = 0; if (gd->baudrate == 1200) |