diff options
Diffstat (limited to 'arch/m68k/cpu')
46 files changed, 7401 insertions, 0 deletions
diff --git a/arch/m68k/cpu/mcf5227x/Makefile b/arch/m68k/cpu/mcf5227x/Makefile new file mode 100644 index 0000000000..d0e9b4550f --- /dev/null +++ b/arch/m68k/cpu/mcf5227x/Makefile @@ -0,0 +1,48 @@ +# +# (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 + +# CFLAGS += -DET_DEBUG + +LIB = lib$(CPU).a + +START = start.o +COBJS = cpu.o speed.o cpu_init.o interrupts.o + +SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) +START := $(addprefix $(obj),$(START)) + +all: $(obj).depend $(START) $(LIB) + +$(LIB): $(OBJS) + $(AR) $(ARFLAGS) $@ $(OBJS) + +######################################################################### + +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/arch/m68k/cpu/mcf5227x/config.mk b/arch/m68k/cpu/mcf5227x/config.mk new file mode 100644 index 0000000000..8eab49dff9 --- /dev/null +++ b/arch/m68k/cpu/mcf5227x/config.mk @@ -0,0 +1,31 @@ +# +# (C) Copyright 2003 Josef Baumgartner <josef.baumgartner@telex.de> +# +# (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-d7 -msep-data +ifneq ($(findstring 4.1,$(shell $(CC) --version)),4.1) +PLATFORM_CPPFLAGS += -mcpu=52277 -fPIC +else +PLATFORM_CPPFLAGS += -m5307 -fPIC +endif diff --git a/arch/m68k/cpu/mcf5227x/cpu.c b/arch/m68k/cpu/mcf5227x/cpu.c new file mode 100644 index 0000000000..d9f5f43c3c --- /dev/null +++ b/arch/m68k/cpu/mcf5227x/cpu.c @@ -0,0 +1,77 @@ +/* + * + * (C) Copyright 2000-2003 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * Copyright (C) 2004-2007 Freescale Semiconductor, Inc. + * TsiChung Liew (Tsi-Chung.Liew@freescale.com) + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <watchdog.h> +#include <command.h> + +#include <asm/immap.h> + +DECLARE_GLOBAL_DATA_PTR; + +int do_reset(cmd_tbl_t * cmdtp, bd_t * bd, int flag, int argc, char *argv[]) +{ + volatile rcm_t *rcm = (rcm_t *) (MMAP_RCM); + udelay(1000); + rcm->rcr |= RCM_RCR_SOFTRST; + + /* we don't return! */ + return 0; +}; + +int checkcpu(void) +{ + volatile ccm_t *ccm = (ccm_t *) MMAP_CCM; + u16 msk; + u16 id = 0; + u8 ver; + + puts("CPU: "); + msk = (ccm->cir >> 6); + ver = (ccm->cir & 0x003f); + switch (msk) { + case 0x6c: + id = 52277; + break; + } + + if (id) { + char buf1[32], buf2[32], buf3[32]; + + printf("Freescale MCF%d (Mask:%01x Version:%x)\n", id, msk, + ver); + printf(" CPU CLK %s MHz BUS CLK %s MHz FLB CLK %s MHz\n", + strmhz(buf1, gd->cpu_clk), + strmhz(buf2, gd->bus_clk), + strmhz(buf3, gd->flb_clk)); + printf(" INP CLK %s MHz VCO CLK %s MHz\n", + strmhz(buf1, gd->inp_clk), + strmhz(buf2, gd->vco_clk)); + } + + return 0; +} diff --git a/arch/m68k/cpu/mcf5227x/cpu_init.c b/arch/m68k/cpu/mcf5227x/cpu_init.c new file mode 100644 index 0000000000..beb78f5839 --- /dev/null +++ b/arch/m68k/cpu/mcf5227x/cpu_init.c @@ -0,0 +1,206 @@ +/* + * + * (C) Copyright 2000-2003 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * (C) Copyright 2004-2007 Freescale Semiconductor, Inc. + * TsiChung Liew (Tsi-Chung.Liew@freescale.com) + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <watchdog.h> + +#include <asm/immap.h> +#include <asm/rtc.h> + +/* + * Breath some life into the CPU... + * + * Set up the memory map, + * initialize a bunch of registers, + * initialize the UPM's + */ +void cpu_init_f(void) +{ + volatile scm1_t *scm1 = (scm1_t *) MMAP_SCM1; + volatile gpio_t *gpio = (gpio_t *) MMAP_GPIO; + volatile fbcs_t *fbcs = (fbcs_t *) MMAP_FBCS; + volatile pll_t *pll = (volatile pll_t *)MMAP_PLL; + +#if !defined(CONFIG_CF_SBF) + /* Workaround, must place before fbcs */ + pll->psr = 0x12; + + scm1->mpr = 0x77777777; + scm1->pacra = 0; + scm1->pacrb = 0; + scm1->pacrc = 0; + scm1->pacrd = 0; + scm1->pacre = 0; + scm1->pacrf = 0; + scm1->pacrg = 0; + scm1->pacri = 0; + +#if (defined(CONFIG_SYS_CS0_BASE) && defined(CONFIG_SYS_CS0_MASK) \ + && defined(CONFIG_SYS_CS0_CTRL)) + fbcs->csar0 = CONFIG_SYS_CS0_BASE; + fbcs->cscr0 = CONFIG_SYS_CS0_CTRL; + fbcs->csmr0 = CONFIG_SYS_CS0_MASK; +#endif +#endif /* CONFIG_CF_SBF */ + +#if (defined(CONFIG_SYS_CS1_BASE) && defined(CONFIG_SYS_CS1_MASK) \ + && defined(CONFIG_SYS_CS1_CTRL)) + fbcs->csar1 = CONFIG_SYS_CS1_BASE; + fbcs->cscr1 = CONFIG_SYS_CS1_CTRL; + fbcs->csmr1 = CONFIG_SYS_CS1_MASK; +#endif + +#if (defined(CONFIG_SYS_CS2_BASE) && defined(CONFIG_SYS_CS2_MASK) \ + && defined(CONFIG_SYS_CS2_CTRL)) + fbcs->csar2 = CONFIG_SYS_CS2_BASE; + fbcs->cscr2 = CONFIG_SYS_CS2_CTRL; + fbcs->csmr2 = CONFIG_SYS_CS2_MASK; +#endif + +#if (defined(CONFIG_SYS_CS3_BASE) && defined(CONFIG_SYS_CS3_MASK) \ + && defined(CONFIG_SYS_CS3_CTRL)) + fbcs->csar3 = CONFIG_SYS_CS3_BASE; + fbcs->cscr3 = CONFIG_SYS_CS3_CTRL; + fbcs->csmr3 = CONFIG_SYS_CS3_MASK; +#endif + +#if (defined(CONFIG_SYS_CS4_BASE) && defined(CONFIG_SYS_CS4_MASK) \ + && defined(CONFIG_SYS_CS4_CTRL)) + fbcs->csar4 = CONFIG_SYS_CS4_BASE; + fbcs->cscr4 = CONFIG_SYS_CS4_CTRL; + fbcs->csmr4 = CONFIG_SYS_CS4_MASK; +#endif + +#if (defined(CONFIG_SYS_CS5_BASE) && defined(CONFIG_SYS_CS5_MASK) \ + && defined(CONFIG_SYS_CS5_CTRL)) + fbcs->csar5 = CONFIG_SYS_CS5_BASE; + fbcs->cscr5 = CONFIG_SYS_CS5_CTRL; + fbcs->csmr5 = CONFIG_SYS_CS5_MASK; +#endif + +#ifdef CONFIG_FSL_I2C + gpio->par_i2c = GPIO_PAR_I2C_SCL_SCL | GPIO_PAR_I2C_SDA_SDA; +#endif + + icache_enable(); +} + +/* + * initialize higher level parts of CPU like timers + */ +int cpu_init_r(void) +{ +#ifdef CONFIG_MCFRTC + volatile rtc_t *rtc = (volatile rtc_t *)(CONFIG_SYS_MCFRTC_BASE); + volatile rtcex_t *rtcex = (volatile rtcex_t *)&rtc->extended; + + rtcex->gocu = (CONFIG_SYS_RTC_OSCILLATOR >> 16) & 0xFFFF; + rtcex->gocl = CONFIG_SYS_RTC_OSCILLATOR & 0xFFFF; +#endif + + return (0); +} + +void uart_port_conf(int port) +{ + volatile gpio_t *gpio = (gpio_t *) MMAP_GPIO; + + /* Setup Ports: */ + switch (port) { + case 0: + gpio->par_uart &= + (GPIO_PAR_UART_U0TXD_UNMASK & GPIO_PAR_UART_U0RXD_UNMASK); + gpio->par_uart |= + (GPIO_PAR_UART_U0TXD_U0TXD | GPIO_PAR_UART_U0RXD_U0RXD); + break; + case 1: + gpio->par_uart &= + (GPIO_PAR_UART_U1TXD_UNMASK & GPIO_PAR_UART_U1RXD_UNMASK); + gpio->par_uart |= + (GPIO_PAR_UART_U1TXD_U1TXD | GPIO_PAR_UART_U1RXD_U1RXD); + break; + case 2: + gpio->par_dspi &= + (GPIO_PAR_DSPI_SIN_UNMASK & GPIO_PAR_DSPI_SOUT_UNMASK); + gpio->par_dspi = + (GPIO_PAR_DSPI_SIN_U2RXD | GPIO_PAR_DSPI_SOUT_U2TXD); + break; + } +} + +#ifdef CONFIG_CF_DSPI +void cfspi_port_conf(void) +{ + volatile gpio_t *gpio = (gpio_t *) MMAP_GPIO; + + gpio->par_dspi = + GPIO_PAR_DSPI_SIN_SIN | GPIO_PAR_DSPI_SOUT_SOUT | + GPIO_PAR_DSPI_SCK_SCK; +} + +int cfspi_claim_bus(uint bus, uint cs) +{ + volatile dspi_t *dspi = (dspi_t *) MMAP_DSPI; + volatile gpio_t *gpio = (gpio_t *) MMAP_GPIO; + + if ((dspi->sr & DSPI_SR_TXRXS) != DSPI_SR_TXRXS) + return -1; + + /* Clear FIFO and resume transfer */ + dspi->mcr &= ~(DSPI_MCR_CTXF | DSPI_MCR_CRXF); + + switch (cs) { + case 0: + gpio->par_dspi &= ~GPIO_PAR_DSPI_PCS0_UNMASK; + gpio->par_dspi |= GPIO_PAR_DSPI_PCS0_PCS0; + break; + case 2: + gpio->par_timer &= GPIO_PAR_TIMER_T2IN_UNMASK; + gpio->par_timer |= GPIO_PAR_TIMER_T2IN_DSPIPCS2; + break; + } + + return 0; +} + +void cfspi_release_bus(uint bus, uint cs) +{ + volatile dspi_t *dspi = (dspi_t *) MMAP_DSPI; + volatile gpio_t *gpio = (gpio_t *) MMAP_GPIO; + + dspi->mcr &= ~(DSPI_MCR_CTXF | DSPI_MCR_CRXF); /* Clear FIFO */ + + switch (cs) { + case 0: + gpio->par_dspi &= ~GPIO_PAR_DSPI_PCS0_PCS0; + break; + case 2: + gpio->par_timer &= GPIO_PAR_TIMER_T2IN_UNMASK; + break; + } +} +#endif diff --git a/arch/m68k/cpu/mcf5227x/interrupts.c b/arch/m68k/cpu/mcf5227x/interrupts.c new file mode 100644 index 0000000000..85828a67b5 --- /dev/null +++ b/arch/m68k/cpu/mcf5227x/interrupts.c @@ -0,0 +1,52 @@ +/* + * + * (C) Copyright 2000-2004 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * Copyright (C) 2004-2007 Freescale Semiconductor, Inc. + * TsiChung Liew (Tsi-Chung.Liew@freescale.com) + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +/* CPU specific interrupt routine */ +#include <common.h> +#include <asm/immap.h> + +int interrupt_init(void) +{ + volatile int0_t *intp = (int0_t *) (CONFIG_SYS_INTR_BASE); + + /* Make sure all interrupts are disabled */ + intp->imrh0 |= 0xFFFFFFFF; + intp->imrl0 |= 0xFFFFFFFF; + + enable_interrupts(); + return 0; +} + +#if defined(CONFIG_MCFTMR) +void dtimer_intr_setup(void) +{ + volatile int0_t *intp = (int0_t *) (CONFIG_SYS_INTR_BASE); + + intp->icr0[CONFIG_SYS_TMRINTR_NO] = CONFIG_SYS_TMRINTR_PRI; + intp->imrh0 &= ~CONFIG_SYS_TMRINTR_MASK; +} +#endif diff --git a/arch/m68k/cpu/mcf5227x/speed.c b/arch/m68k/cpu/mcf5227x/speed.c new file mode 100644 index 0000000000..7e385d3998 --- /dev/null +++ b/arch/m68k/cpu/mcf5227x/speed.c @@ -0,0 +1,140 @@ +/* + * + * Copyright (C) 2004-2007 Freescale Semiconductor, Inc. + * TsiChung Liew (Tsi-Chung.Liew@freescale.com) + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <asm/processor.h> + +#include <asm/immap.h> + +DECLARE_GLOBAL_DATA_PTR; + +/* + * Low Power Divider specifications + */ +#define CLOCK_LPD_MIN (1 << 0) /* Divider (decoded) */ +#define CLOCK_LPD_MAX (1 << 15) /* Divider (decoded) */ + +#define CLOCK_PLL_FVCO_MAX 540000000 +#define CLOCK_PLL_FVCO_MIN 300000000 + +#define CLOCK_PLL_FSYS_MAX 266666666 +#define CLOCK_PLL_FSYS_MIN 100000000 +#define MHZ 1000000 + +void clock_enter_limp(int lpdiv) +{ + volatile ccm_t *ccm = (volatile ccm_t *)MMAP_CCM; + int i, j; + + /* Check bounds of divider */ + if (lpdiv < CLOCK_LPD_MIN) + lpdiv = CLOCK_LPD_MIN; + if (lpdiv > CLOCK_LPD_MAX) + lpdiv = CLOCK_LPD_MAX; + + /* Round divider down to nearest power of two */ + for (i = 0, j = lpdiv; j != 1; j >>= 1, i++) ; + + /* Apply the divider to the system clock */ + ccm->cdr = (ccm->cdr & 0xF0FF) | CCM_CDR_LPDIV(i); + + /* Enable Limp Mode */ + ccm->misccr |= CCM_MISCCR_LIMP; +} + +/* + * brief Exit Limp mode + * warning The PLL should be set and locked prior to exiting Limp mode + */ +void clock_exit_limp(void) +{ + volatile ccm_t *ccm = (volatile ccm_t *)MMAP_CCM; + volatile pll_t *pll = (volatile pll_t *)MMAP_PLL; + + /* Exit Limp mode */ + ccm->misccr &= ~CCM_MISCCR_LIMP; + + /* Wait for the PLL to lock */ + while (!(pll->psr & PLL_PSR_LOCK)) ; +} + +/* + * get_clocks() fills in gd->cpu_clock and gd->bus_clk + */ +int get_clocks(void) +{ + + volatile ccm_t *ccm = (volatile ccm_t *)MMAP_CCM; + volatile pll_t *pll = (volatile pll_t *)MMAP_PLL; + int vco, temp, pcrvalue, pfdr; + u8 bootmode; + + pcrvalue = pll->pcr & 0xFF0F0FFF; + pfdr = pcrvalue >> 24; + + if (pfdr == 0x1E) + bootmode = 0; /* Normal Mode */ + +#ifdef CONFIG_CF_SBF + bootmode = 3; /* Serial Mode */ +#endif + + if (bootmode == 0) { + /* Normal mode */ + vco = ((pll->pcr & 0xFF000000) >> 24) * CONFIG_SYS_INPUT_CLKSRC; + if ((vco < CLOCK_PLL_FVCO_MIN) || (vco > CLOCK_PLL_FVCO_MAX)) { + /* Default value */ + pcrvalue = (pll->pcr & 0x00FFFFFF); + pcrvalue |= 0x1E << 24; + pll->pcr = pcrvalue; + vco = + ((pll->pcr & 0xFF000000) >> 24) * + CONFIG_SYS_INPUT_CLKSRC; + } + gd->vco_clk = vco; /* Vco clock */ + } else if (bootmode == 3) { + /* serial mode */ + vco = ((pll->pcr & 0xFF000000) >> 24) * CONFIG_SYS_INPUT_CLKSRC; + gd->vco_clk = vco; /* Vco clock */ + } + + if ((ccm->ccr & CCM_MISCCR_LIMP) == CCM_MISCCR_LIMP) { + /* Limp mode */ + } else { + gd->inp_clk = CONFIG_SYS_INPUT_CLKSRC; /* Input clock */ + + temp = (pll->pcr & PLL_PCR_OUTDIV1_MASK) + 1; + gd->cpu_clk = vco / temp; /* cpu clock */ + + temp = ((pll->pcr & PLL_PCR_OUTDIV2_MASK) >> 4) + 1; + gd->flb_clk = vco / temp; /* flexbus clock */ + gd->bus_clk = gd->flb_clk; + } + +#ifdef CONFIG_FSL_I2C + gd->i2c1_clk = gd->bus_clk; +#endif + + return (0); +} diff --git a/arch/m68k/cpu/mcf5227x/start.S b/arch/m68k/cpu/mcf5227x/start.S new file mode 100644 index 0000000000..30428f15d8 --- /dev/null +++ b/arch/m68k/cpu/mcf5227x/start.S @@ -0,0 +1,513 @@ +/* + * Copyright (C) 2003 Josef Baumgartner <josef.baumgartner@telex.de> + * Based on code from Bernhard Kuhn <bkuhn@metrowerks.com> + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <config.h> +#include <timestamp.h> +#include "version.h" +#include <asm/cache.h> + +#ifndef CONFIG_IDENT_STRING +#define CONFIG_IDENT_STRING "" +#endif + +#define _START _start +#define _FAULT _fault + +#define SAVE_ALL \ + move.w #0x2700,%sr; /* disable intrs */ \ + subl #60,%sp; /* space for 15 regs */ \ + moveml %d0-%d7/%a0-%a6,%sp@; + +#define RESTORE_ALL \ + moveml %sp@,%d0-%d7/%a0-%a6; \ + addl #60,%sp; /* space for 15 regs */ \ + rte; + +#if defined(CONFIG_CF_SBF) +#define ASM_DRAMINIT (asm_dram_init - TEXT_BASE + CONFIG_SYS_INIT_RAM_ADDR) +#define ASM_SBF_IMG_HDR (asm_sbf_img_hdr - TEXT_BASE + CONFIG_SYS_INIT_RAM_ADDR) +#endif + +.text +/* + * Vector table. This is used for initial platform startup. + * These vectors are to catch any un-intended traps. + */ +_vectors: + +#if defined(CONFIG_CF_SBF) +INITSP: .long 0 /* Initial SP */ +INITPC: .long ASM_DRAMINIT /* Initial PC */ +#else +INITSP: .long 0 /* Initial SP */ +INITPC: .long _START /* Initial PC */ +#endif + +vector02: .long _FAULT /* Access Error */ +vector03: .long _FAULT /* Address Error */ +vector04: .long _FAULT /* Illegal Instruction */ +vector05: .long _FAULT /* Reserved */ +vector06: .long _FAULT /* Reserved */ +vector07: .long _FAULT /* Reserved */ +vector08: .long _FAULT /* Privilege Violation */ +vector09: .long _FAULT /* Trace */ +vector0A: .long _FAULT /* Unimplemented A-Line */ +vector0B: .long _FAULT /* Unimplemented F-Line */ +vector0C: .long _FAULT /* Debug Interrupt */ +vector0D: .long _FAULT /* Reserved */ +vector0E: .long _FAULT /* Format Error */ +vector0F: .long _FAULT /* Unitialized Int. */ + +/* Reserved */ +vector10_17: +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT + +vector18: .long _FAULT /* Spurious Interrupt */ +vector19: .long _FAULT /* Autovector Level 1 */ +vector1A: .long _FAULT /* Autovector Level 2 */ +vector1B: .long _FAULT /* Autovector Level 3 */ +vector1C: .long _FAULT /* Autovector Level 4 */ +vector1D: .long _FAULT /* Autovector Level 5 */ +vector1E: .long _FAULT /* Autovector Level 6 */ +vector1F: .long _FAULT /* Autovector Level 7 */ + +#if !defined(CONFIG_CF_SBF) +/* TRAP #0 - #15 */ +vector20_2F: +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT + +/* Reserved */ +vector30_3F: +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT + +vector64_127: +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT + +vector128_191: +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT + +vector192_255: +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +#endif + +#if defined(CONFIG_CF_SBF) + /* Image header: chksum 4 bytes, len 4 bytes, img dest 4 bytes */ +asm_sbf_img_hdr: + .long 0x00000000 /* checksum, not yet implemented */ + .long 0x00020000 /* image length */ + .long TEXT_BASE /* image to be relocated at */ + +asm_dram_init: + move.l #(CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_RAM_CTRL), %d0 + movec %d0, %RAMBAR1 /* init Rambar */ + move.l #(CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_SP_OFFSET), %sp + clr.l %sp@- + + /* Must disable global address */ + move.l #0xFC008000, %a1 + move.l #(CONFIG_SYS_CS0_BASE), (%a1) + move.l #0xFC008008, %a1 + move.l #(CONFIG_SYS_CS0_CTRL), (%a1) + move.l #0xFC008004, %a1 + move.l #(CONFIG_SYS_CS0_MASK), (%a1) + + /* + * Dram Initialization + * a1, a2, and d0 + */ + /* mscr sdram */ + move.l #0xFC0A4074, %a1 + move.b #(CONFIG_SYS_SDRAM_DRV_STRENGTH), (%a1) + nop + + /* SDRAM Chip 0 and 1 */ + move.l #0xFC0B8110, %a1 + move.l #0xFC0B8114, %a2 + + /* calculate the size */ + move.l #0x13, %d1 + move.l #(CONFIG_SYS_SDRAM_SIZE), %d2 +#ifdef CONFIG_SYS_SDRAM_BASE1 + lsr.l #1, %d2 +#endif + +dramsz_loop: + lsr.l #1, %d2 + add.l #1, %d1 + cmp.l #1, %d2 + bne dramsz_loop + + /* SDRAM Chip 0 and 1 */ + move.l #(CONFIG_SYS_SDRAM_BASE), (%a1) + or.l %d1, (%a1) +#ifdef CONFIG_SYS_SDRAM_BASE1 + move.l #(CONFIG_SYS_SDRAM_BASE1), (%a2) + or.l %d1, (%a2) +#endif + nop + + /* dram cfg1 and cfg2 */ + move.l #0xFC0B8008, %a1 + move.l #(CONFIG_SYS_SDRAM_CFG1), (%a1) + nop + move.l #0xFC0B800C, %a2 + move.l #(CONFIG_SYS_SDRAM_CFG2), (%a2) + nop + + move.l #0xFC0B8000, %a1 /* Mode */ + move.l #0xFC0B8004, %a2 /* Ctrl */ + + /* Issue PALL */ + move.l #(CONFIG_SYS_SDRAM_CTRL + 2), (%a2) + nop + + /* Issue LEMR */ + move.l #(CONFIG_SYS_SDRAM_MODE), (%a1) + nop + move.l #(CONFIG_SYS_SDRAM_EMOD), (%a1) + nop + + move.l #1000, %d0 +wait1000: + nop + subq.l #1, %d0 + bne wait1000 + + /* Issue PALL */ + move.l #(CONFIG_SYS_SDRAM_CTRL + 2), (%a2) + nop + + /* Perform two refresh cycles */ + move.l #(CONFIG_SYS_SDRAM_CTRL + 4), %d0 + nop + move.l %d0, (%a2) + move.l %d0, (%a2) + nop + + move.l #(CONFIG_SYS_SDRAM_CTRL), %d0 + and.l #0x7FFFFFFF, %d0 + or.l #0x10000c00, %d0 + move.l %d0, (%a2) + nop + + /* + * DSPI Initialization + * a0 - general, sram - 0x80008000 - 32, see M52277EVB.h + * a1 - dspi status + * a2 - dtfr + * a3 - drfr + * a4 - Dst addr + */ + + /* Enable pins for DSPI mode - chip-selects are enabled later */ + move.l #0xFC0A4036, %a0 + move.b #0x3F, %d0 + move.b %d0, (%a0) + + /* DSPI CS */ +#ifdef CONFIG_SYS_DSPI_CS0 + move.b (%a0), %d0 + or.l #0xC0, %d0 + move.b %d0, (%a0) +#endif +#ifdef CONFIG_SYS_DSPI_CS2 + move.l #0xFC0A4037, %a0 + move.b (%a0), %d0 + or.l #0x10, %d0 + move.b %d0, (%a0) +#endif + nop + + /* Configure DSPI module */ + move.l #0xFC05C000, %a0 + move.l #0x80FF0C00, (%a0) /* Master, clear TX/RX FIFO */ + + move.l #0xFC05C00C, %a0 + move.l #0x3E000011, (%a0) + + move.l #0xFC05C034, %a2 /* dtfr */ + move.l #0xFC05C03B, %a3 /* drfr */ + + move.l #(ASM_SBF_IMG_HDR + 4), %a1 + move.l (%a1)+, %d5 + move.l (%a1), %a4 + + move.l #(CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_SBFHDR_DATA_OFFSET), %a0 + move.l #(CONFIG_SYS_SBFHDR_SIZE), %d4 + + move.l #0xFC05C02C, %a1 /* dspi status */ + + /* Issue commands and address */ + move.l #0x8004000B, %d2 /* Fast Read Cmd */ + jsr asm_dspi_wr_status + jsr asm_dspi_rd_status + + move.l #0x80040000, %d2 /* Address byte 2 */ + jsr asm_dspi_wr_status + jsr asm_dspi_rd_status + + move.l #0x80040000, %d2 /* Address byte 1 */ + jsr asm_dspi_wr_status + jsr asm_dspi_rd_status + + move.l #0x80040000, %d2 /* Address byte 0 */ + jsr asm_dspi_wr_status + jsr asm_dspi_rd_status + + move.l #0x80040000, %d2 /* Dummy Wr and Rd */ + jsr asm_dspi_wr_status + jsr asm_dspi_rd_status + + /* Transfer serial boot header to sram */ +asm_dspi_rd_loop1: + move.l #0x80040000, %d2 + jsr asm_dspi_wr_status + jsr asm_dspi_rd_status + + move.b %d1, (%a0) /* read, copy to dst */ + + add.l #1, %a0 /* inc dst by 1 */ + sub.l #1, %d4 /* dec cnt by 1 */ + bne asm_dspi_rd_loop1 + + /* Transfer u-boot from serial flash to memory */ +asm_dspi_rd_loop2: + move.l #0x80040000, %d2 + jsr asm_dspi_wr_status + jsr asm_dspi_rd_status + + move.b %d1, (%a4) /* read, copy to dst */ + + add.l #1, %a4 /* inc dst by 1 */ + sub.l #1, %d5 /* dec cnt by 1 */ + bne asm_dspi_rd_loop2 + + move.l #0x00040000, %d2 /* Terminate */ + jsr asm_dspi_wr_status + jsr asm_dspi_rd_status + + /* jump to memory and execute */ + move.l #(TEXT_BASE + 0x400), %a0 + move.l %a0, (%a1) + jmp (%a0) + +asm_dspi_wr_status: + move.l (%a1), %d0 /* status */ + and.l #0x0000F000, %d0 + cmp.l #0x00003000, %d0 + bgt asm_dspi_wr_status + + move.l %d2, (%a2) + rts + +asm_dspi_rd_status: + move.l (%a1), %d0 /* status */ + and.l #0x000000F0, %d0 + lsr.l #4, %d0 + cmp.l #0, %d0 + beq asm_dspi_rd_status + + move.b (%a3), %d1 + rts +#endif /* CONFIG_CF_SBF */ + + .text + . = 0x400 + .globl _start +_start: + nop + nop + move.w #0x2700,%sr /* Mask off Interrupt */ + + /* Set vector base register at the beginning of the Flash */ +#if defined(CONFIG_CF_SBF) + move.l #TEXT_BASE, %d0 + movec %d0, %VBR +#else + move.l #CONFIG_SYS_FLASH_BASE, %d0 + movec %d0, %VBR + + move.l #(CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_RAM_CTRL), %d0 + movec %d0, %RAMBAR1 +#endif + + /* invalidate and disable cache */ + move.l #CF_CACR_CINV, %d0 /* Invalidate cache cmd */ + movec %d0, %CACR /* Invalidate cache */ + move.l #0, %d0 + movec %d0, %ACR0 + movec %d0, %ACR1 + + /* initialize general use internal ram */ + move.l #0, %d0 + move.l #(ICACHE_STATUS), %a1 /* icache */ + move.l #(DCACHE_STATUS), %a2 /* icache */ + move.l %d0, (%a1) + move.l %d0, (%a2) + + /* set stackpointer to end of internal ram to get some stackspace for + the first c-code */ + move.l #(CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_SP_OFFSET), %sp + clr.l %sp@- + + move.l #__got_start, %a5 /* put relocation table address to a5 */ + + bsr cpu_init_f /* run low-level CPU init code (from flash) */ + bsr board_init_f /* run low-level board init code (from flash) */ + + /* board_init_f() does not return */ + +/*------------------------------------------------------------------------------*/ + +/* + * void relocate_code (addr_sp, gd, addr_moni) + * + * This "function" does not return, instead it continues in RAM + * after relocating the monitor code. + * + * r3 = dest + * r4 = src + * r5 = length in bytes + * r6 = cachelinesize + */ + .globl relocate_code +relocate_code: + link.w %a6,#0 + move.l 8(%a6), %sp /* set new stack pointer */ + + move.l 12(%a6), %d0 /* Save copy of Global Data pointer */ + move.l 16(%a6), %a0 /* Save copy of Destination Address */ + + move.l #CONFIG_SYS_MONITOR_BASE, %a1 + move.l #__init_end, %a2 + move.l %a0, %a3 + + /* copy the code to RAM */ +1: + move.l (%a1)+, (%a3)+ + cmp.l %a1,%a2 + bgt.s 1b + +/* + * We are done. Do not return, instead branch to second part of board + * initialization, now running from RAM. + */ + move.l %a0, %a1 + add.l #(in_ram - CONFIG_SYS_MONITOR_BASE), %a1 + jmp (%a1) + +in_ram: + +clear_bss: + /* + * Now clear BSS segment + */ + move.l %a0, %a1 + add.l #(_sbss - CONFIG_SYS_MONITOR_BASE),%a1 + move.l %a0, %d1 + add.l #(_ebss - CONFIG_SYS_MONITOR_BASE),%d1 +6: + clr.l (%a1)+ + cmp.l %a1,%d1 + bgt.s 6b + + /* + * fix got table in RAM + */ + move.l %a0, %a1 + add.l #(__got_start - CONFIG_SYS_MONITOR_BASE),%a1 + move.l %a1,%a5 /* * fix got pointer register a5 */ + + move.l %a0, %a2 + add.l #(__got_end - CONFIG_SYS_MONITOR_BASE),%a2 + +7: + move.l (%a1),%d1 + sub.l #_start,%d1 + add.l %a0,%d1 + move.l %d1,(%a1)+ + cmp.l %a2, %a1 + bne 7b + + /* calculate relative jump to board_init_r in ram */ + move.l %a0, %a1 + add.l #(board_init_r - CONFIG_SYS_MONITOR_BASE), %a1 + + /* set parameters for board_init_r */ + move.l %a0,-(%sp) /* dest_addr */ + move.l %d0,-(%sp) /* gd */ + jsr (%a1) + +/*------------------------------------------------------------------------------*/ +/* exception code */ + .globl _fault +_fault: + jmp _fault + .globl _exc_handler + +_exc_handler: + SAVE_ALL + movel %sp,%sp@- + bsr exc_handler + addql #4,%sp + RESTORE_ALL + + .globl _int_handler +_int_handler: + SAVE_ALL + movel %sp,%sp@- + bsr int_handler + addql #4,%sp + RESTORE_ALL + +/*------------------------------------------------------------------------------*/ + + .globl version_string +version_string: + .ascii U_BOOT_VERSION + .ascii " (", U_BOOT_DATE, " - ", U_BOOT_TIME, ")" + .ascii CONFIG_IDENT_STRING, "\0" + .align 4 diff --git a/arch/m68k/cpu/mcf523x/Makefile b/arch/m68k/cpu/mcf523x/Makefile new file mode 100644 index 0000000000..d0e9b4550f --- /dev/null +++ b/arch/m68k/cpu/mcf523x/Makefile @@ -0,0 +1,48 @@ +# +# (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 + +# CFLAGS += -DET_DEBUG + +LIB = lib$(CPU).a + +START = start.o +COBJS = cpu.o speed.o cpu_init.o interrupts.o + +SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) +START := $(addprefix $(obj),$(START)) + +all: $(obj).depend $(START) $(LIB) + +$(LIB): $(OBJS) + $(AR) $(ARFLAGS) $@ $(OBJS) + +######################################################################### + +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/arch/m68k/cpu/mcf523x/config.mk b/arch/m68k/cpu/mcf523x/config.mk new file mode 100644 index 0000000000..fc7945451f --- /dev/null +++ b/arch/m68k/cpu/mcf523x/config.mk @@ -0,0 +1,31 @@ +# +# (C) Copyright 2003 Josef Baumgartner <josef.baumgartner@telex.de> +# +# (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-d7 -msep-data +ifneq ($(findstring 4.1,$(shell $(CC) --version)),4.1) +PLATFORM_CPPFLAGS += -mcpu=5235 -fPIC +else +PLATFORM_CPPFLAGS += -m5307 -fPIC +endif diff --git a/arch/m68k/cpu/mcf523x/cpu.c b/arch/m68k/cpu/mcf523x/cpu.c new file mode 100644 index 0000000000..a1a51336c2 --- /dev/null +++ b/arch/m68k/cpu/mcf523x/cpu.c @@ -0,0 +1,124 @@ +/* + * + * (C) Copyright 2000-2003 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * Copyright (C) 2004-2007 Freescale Semiconductor, Inc. + * TsiChung Liew (Tsi-Chung.Liew@freescale.com) + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <watchdog.h> +#include <command.h> +#include <netdev.h> + +#include <asm/immap.h> + +DECLARE_GLOBAL_DATA_PTR; + +int do_reset(cmd_tbl_t * cmdtp, bd_t * bd, int flag, int argc, char *argv[]) +{ + volatile ccm_t *ccm = (ccm_t *) MMAP_CCM; + + ccm->rcr = CCM_RCR_SOFTRST; + /* we don't return! */ + return 0; +}; + +int checkcpu(void) +{ + volatile ccm_t *ccm = (ccm_t *) MMAP_CCM; + u16 msk; + u16 id = 0; + u8 ver; + + puts("CPU: "); + msk = (ccm->cir >> 6); + ver = (ccm->cir & 0x003f); + switch (msk) { + case 0x31: + id = 5235; + break; + } + + if (id) { + char buf1[32], buf2[32]; + + printf("Freescale MCF%d (Mask:%01x Version:%x)\n", id, msk, + ver); + printf(" CPU CLK %s MHz BUS CLK %s MHz\n", + strmhz(buf1, gd->cpu_clk), + strmhz(buf2, gd->bus_clk)); + } + + return 0; +}; + +#if defined(CONFIG_WATCHDOG) +/* Called by macro WATCHDOG_RESET */ +void watchdog_reset(void) +{ + volatile wdog_t *wdp = (wdog_t *) (MMAP_WDOG); + + wdp->sr = 0x5555; /* Count register */ + asm("nop"); + wdp->sr = 0xAAAA; /* Count register */ +} + +int watchdog_disable(void) +{ + volatile wdog_t *wdp = (wdog_t *) (MMAP_WDOG); + + /* UserManual, once the wdog is disabled, wdog cannot be re-enabled */ + wdp->cr |= WTM_WCR_HALTED; /* halted watchdog timer */ + + puts("WATCHDOG:disabled\n"); + return (0); +} + +int watchdog_init(void) +{ + volatile wdog_t *wdp = (wdog_t *) (MMAP_WDOG); + u32 wdog_module = 0; + + /* set timeout and enable watchdog */ + wdog_module = ((CONFIG_SYS_CLK / CONFIG_SYS_HZ) * CONFIG_WATCHDOG_TIMEOUT); + wdog_module |= (wdog_module / 8192); + wdp->mr = wdog_module; + + wdp->cr = WTM_WCR_EN; + puts("WATCHDOG:enabled\n"); + + return (0); +} +#endif /* CONFIG_WATCHDOG */ + +#if defined(CONFIG_MCFFEC) +/* Default initializations for MCFFEC controllers. To override, + * create a board-specific function called: + * int board_eth_init(bd_t *bis) + */ + +int cpu_eth_init(bd_t *bis) +{ + return mcffec_initialize(bis); +} +#endif diff --git a/arch/m68k/cpu/mcf523x/cpu_init.c b/arch/m68k/cpu/mcf523x/cpu_init.c new file mode 100644 index 0000000000..0f299f0c3c --- /dev/null +++ b/arch/m68k/cpu/mcf523x/cpu_init.c @@ -0,0 +1,179 @@ +/* + * + * (C) Copyright 2000-2003 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * (C) Copyright 2007 Freescale Semiconductor, Inc. + * TsiChung Liew (Tsi-Chung.Liew@freescale.com) + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <watchdog.h> +#include <asm/immap.h> + +#if defined(CONFIG_CMD_NET) +#include <config.h> +#include <net.h> +#include <asm/fec.h> +#endif + +/* + * Breath some life into the CPU... + * + * Set up the memory map, + * initialize a bunch of registers, + * initialize the UPM's + */ +void cpu_init_f(void) +{ + volatile gpio_t *gpio = (gpio_t *) MMAP_GPIO; + volatile fbcs_t *fbcs = (fbcs_t *) MMAP_FBCS; + volatile wdog_t *wdog = (wdog_t *) MMAP_WDOG; + volatile scm_t *scm = (scm_t *) MMAP_SCM; + + /* watchdog is enabled by default - disable the watchdog */ +#ifndef CONFIG_WATCHDOG + wdog->cr = 0; +#endif + + scm->rambar = (CONFIG_SYS_INIT_RAM_ADDR | SCM_RAMBAR_BDE); + + /* Port configuration */ + gpio->par_cs = 0; + +#if (defined(CONFIG_SYS_CS0_BASE) && defined(CONFIG_SYS_CS0_MASK) && defined(CONFIG_SYS_CS0_CTRL)) + fbcs->csar0 = CONFIG_SYS_CS0_BASE; + fbcs->cscr0 = CONFIG_SYS_CS0_CTRL; + fbcs->csmr0 = CONFIG_SYS_CS0_MASK; +#endif + +#if (defined(CONFIG_SYS_CS1_BASE) && defined(CONFIG_SYS_CS1_MASK) && defined(CONFIG_SYS_CS1_CTRL)) + gpio->par_cs |= GPIO_PAR_CS_CS1; + fbcs->csar1 = CONFIG_SYS_CS1_BASE; + fbcs->cscr1 = CONFIG_SYS_CS1_CTRL; + fbcs->csmr1 = CONFIG_SYS_CS1_MASK; +#endif + +#if (defined(CONFIG_SYS_CS2_BASE) && defined(CONFIG_SYS_CS2_MASK) && defined(CONFIG_SYS_CS2_CTRL)) + gpio->par_cs |= GPIO_PAR_CS_CS2; + fbcs->csar2 = CONFIG_SYS_CS2_BASE; + fbcs->cscr2 = CONFIG_SYS_CS2_CTRL; + fbcs->csmr2 = CONFIG_SYS_CS2_MASK; +#endif + +#if (defined(CONFIG_SYS_CS3_BASE) && defined(CONFIG_SYS_CS3_MASK) && defined(CONFIG_SYS_CS3_CTRL)) + gpio->par_cs |= GPIO_PAR_CS_CS3; + fbcs->csar3 = CONFIG_SYS_CS3_BASE; + fbcs->cscr3 = CONFIG_SYS_CS3_CTRL; + fbcs->csmr3 = CONFIG_SYS_CS3_MASK; +#endif + +#if (defined(CONFIG_SYS_CS4_BASE) && defined(CONFIG_SYS_CS4_MASK) && defined(CONFIG_SYS_CS4_CTRL)) + gpio->par_cs |= GPIO_PAR_CS_CS4; + fbcs->csar4 = CONFIG_SYS_CS4_BASE; + fbcs->cscr4 = CONFIG_SYS_CS4_CTRL; + fbcs->csmr4 = CONFIG_SYS_CS4_MASK; +#endif + +#if (defined(CONFIG_SYS_CS5_BASE) && defined(CONFIG_SYS_CS5_MASK) && defined(CONFIG_SYS_CS5_CTRL)) + gpio->par_cs |= GPIO_PAR_CS_CS5; + fbcs->csar5 = CONFIG_SYS_CS5_BASE; + fbcs->cscr5 = CONFIG_SYS_CS5_CTRL; + fbcs->csmr5 = CONFIG_SYS_CS5_MASK; +#endif + +#if (defined(CONFIG_SYS_CS6_BASE) && defined(CONFIG_SYS_CS6_MASK) && defined(CONFIG_SYS_CS6_CTRL)) + gpio->par_cs |= GPIO_PAR_CS_CS6; + fbcs->csar6 = CONFIG_SYS_CS6_BASE; + fbcs->cscr6 = CONFIG_SYS_CS6_CTRL; + fbcs->csmr6 = CONFIG_SYS_CS6_MASK; +#endif + +#if (defined(CONFIG_SYS_CS7_BASE) && defined(CONFIG_SYS_CS7_MASK) && defined(CONFIG_SYS_CS7_CTRL)) + gpio->par_cs |= GPIO_PAR_CS_CS7; + fbcs->csar7 = CONFIG_SYS_CS7_BASE; + fbcs->cscr7 = CONFIG_SYS_CS7_CTRL; + fbcs->csmr7 = CONFIG_SYS_CS7_MASK; +#endif + +#ifdef CONFIG_FSL_I2C + CONFIG_SYS_I2C_PINMUX_REG &= CONFIG_SYS_I2C_PINMUX_CLR; + CONFIG_SYS_I2C_PINMUX_REG |= CONFIG_SYS_I2C_PINMUX_SET; +#endif + + icache_enable(); +} + +/* + * initialize higher level parts of CPU like timers + */ +int cpu_init_r(void) +{ + return (0); +} + +void uart_port_conf(int port) +{ + volatile gpio_t *gpio = (gpio_t *) MMAP_GPIO; + + /* Setup Ports: */ + switch (port) { + case 0: + gpio->par_uart &= ~(GPIO_PAR_UART_U0RXD | GPIO_PAR_UART_U0TXD); + gpio->par_uart |= (GPIO_PAR_UART_U0RXD | GPIO_PAR_UART_U0TXD); + break; + case 1: + gpio->par_uart &= + ~(GPIO_PAR_UART_U1RXD_MASK | GPIO_PAR_UART_U1TXD_MASK); + gpio->par_uart |= + (GPIO_PAR_UART_U1RXD_U1RXD | GPIO_PAR_UART_U1TXD_U1TXD); + break; + case 2: +#ifdef CONFIG_SYS_UART2_PRI_GPIO + gpio->par_uart &= ~(GPIO_PAR_UART_U2RXD | GPIO_PAR_UART_U2TXD); + gpio->par_uart |= (GPIO_PAR_UART_U2RXD | GPIO_PAR_UART_U2TXD); +#elif defined(CONFIG_SYS_UART2_ALT1_GPIO) + gpio->feci2c &= + ~(GPIO_PAR_FECI2C_EMDC_MASK | GPIO_PAR_FECI2C_EMDIO_MASK); + gpio->feci2c |= + (GPIO_PAR_FECI2C_EMDC_U2TXD | GPIO_PAR_FECI2C_EMDIO_U2RXD); +#endif + break; + } +} + +#if defined(CONFIG_CMD_NET) +int fecpin_setclear(struct eth_device *dev, int setclear) +{ + volatile gpio_t *gpio = (gpio_t *) MMAP_GPIO; + + if (setclear) { + gpio->par_feci2c |= + (GPIO_PAR_FECI2C_EMDC_FECEMDC | + GPIO_PAR_FECI2C_EMDIO_FECEMDIO); + } else { + gpio->par_feci2c &= + ~(GPIO_PAR_FECI2C_EMDC_MASK | GPIO_PAR_FECI2C_EMDIO_MASK); + } + + return 0; +} +#endif diff --git a/arch/m68k/cpu/mcf523x/interrupts.c b/arch/m68k/cpu/mcf523x/interrupts.c new file mode 100644 index 0000000000..db5ccdf6d3 --- /dev/null +++ b/arch/m68k/cpu/mcf523x/interrupts.c @@ -0,0 +1,49 @@ +/* + * + * Copyright (C) 2004-2007 Freescale Semiconductor, Inc. + * TsiChung Liew (Tsi-Chung.Liew@freescale.com) + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +/* CPU specific interrupt routine */ +#include <common.h> +#include <asm/immap.h> + +int interrupt_init(void) +{ + volatile int0_t *intp = (int0_t *) (CONFIG_SYS_INTR_BASE); + + /* Make sure all interrupts are disabled */ + intp->imrl0 |= 0x1; + + enable_interrupts(); + return 0; +} + +#if defined(CONFIG_MCFTMR) +void dtimer_intr_setup(void) +{ + volatile int0_t *intp = (int0_t *) (CONFIG_SYS_INTR_BASE); + + intp->icr0[CONFIG_SYS_TMRINTR_NO] = CONFIG_SYS_TMRINTR_PRI; + intp->imrl0 &= ~INTC_IPRL_INT0; + intp->imrl0 &= ~CONFIG_SYS_TMRINTR_MASK; +} +#endif diff --git a/arch/m68k/cpu/mcf523x/speed.c b/arch/m68k/cpu/mcf523x/speed.c new file mode 100644 index 0000000000..6096ba4144 --- /dev/null +++ b/arch/m68k/cpu/mcf523x/speed.c @@ -0,0 +1,53 @@ +/* + * + * (C) Copyright 2000-2003 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * Copyright (C) 2004-2007 Freescale Semiconductor, Inc. + * TsiChung Liew (Tsi-Chung.Liew@freescale.com) + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <asm/processor.h> + +#include <asm/immap.h> + +DECLARE_GLOBAL_DATA_PTR; +/* + * get_clocks() fills in gd->cpu_clock and gd->bus_clk + */ +int get_clocks(void) +{ + volatile pll_t *pll = (volatile pll_t *)(MMAP_PLL); + + pll->syncr = PLL_SYNCR_MFD(1); + + while (!(pll->synsr & PLL_SYNSR_LOCK)); + + gd->bus_clk = CONFIG_SYS_CLK; + gd->cpu_clk = (gd->bus_clk * 2); + +#ifdef CONFIG_FSL_I2C + gd->i2c1_clk = gd->bus_clk; +#endif + + return (0); +} diff --git a/arch/m68k/cpu/mcf523x/start.S b/arch/m68k/cpu/mcf523x/start.S new file mode 100644 index 0000000000..20b50e7579 --- /dev/null +++ b/arch/m68k/cpu/mcf523x/start.S @@ -0,0 +1,275 @@ +/* + * Copyright (C) 2003 Josef Baumgartner <josef.baumgartner@telex.de> + * Based on code from Bernhard Kuhn <bkuhn@metrowerks.com> + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <config.h> +#include <timestamp.h> +#include "version.h" +#include <asm/cache.h> + +#ifndef CONFIG_IDENT_STRING +#define CONFIG_IDENT_STRING "" +#endif + +#define _START _start +#define _FAULT _fault + +#define SAVE_ALL \ + move.w #0x2700,%sr; /* disable intrs */ \ + subl #60,%sp; /* space for 15 regs */ \ + moveml %d0-%d7/%a0-%a6,%sp@; + +#define RESTORE_ALL \ + moveml %sp@,%d0-%d7/%a0-%a6; \ + addl #60,%sp; /* space for 15 regs */ \ + rte; + +.text +/* + * Vector table. This is used for initial platform startup. + * These vectors are to catch any un-intended traps. + */ +_vectors: + +INITSP: .long 0x00000000 /* Initial SP */ +INITPC: .long _START /* Initial PC */ +vector02: .long _FAULT /* Access Error */ +vector03: .long _FAULT /* Address Error */ +vector04: .long _FAULT /* Illegal Instruction */ +vector05: .long _FAULT /* Reserved */ +vector06: .long _FAULT /* Reserved */ +vector07: .long _FAULT /* Reserved */ +vector08: .long _FAULT /* Privilege Violation */ +vector09: .long _FAULT /* Trace */ +vector0A: .long _FAULT /* Unimplemented A-Line */ +vector0B: .long _FAULT /* Unimplemented F-Line */ +vector0C: .long _FAULT /* Debug Interrupt */ +vector0D: .long _FAULT /* Reserved */ +vector0E: .long _FAULT /* Format Error */ +vector0F: .long _FAULT /* Unitialized Int. */ + +/* Reserved */ +vector10_17: +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT + +vector18: .long _FAULT /* Spurious Interrupt */ +vector19: .long _FAULT /* Autovector Level 1 */ +vector1A: .long _FAULT /* Autovector Level 2 */ +vector1B: .long _FAULT /* Autovector Level 3 */ +vector1C: .long _FAULT /* Autovector Level 4 */ +vector1D: .long _FAULT /* Autovector Level 5 */ +vector1E: .long _FAULT /* Autovector Level 6 */ +vector1F: .long _FAULT /* Autovector Level 7 */ + +/* TRAP #0 - #15 */ +vector20_2F: +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT + +/* Reserved */ +vector30_3F: +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT + +vector64_127: +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT + +vector128_191: +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT + +vector192_255: +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT + + .text + + .globl _start +_start: + nop + nop + move.w #0x2700,%sr /* Mask off Interrupt */ + + /* Set vector base register at the beginning of the Flash */ + move.l #CONFIG_SYS_FLASH_BASE, %d0 + movec %d0, %VBR + + move.l #(CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_RAM_CTRL), %d0 + movec %d0, %RAMBAR1 + + /* invalidate and disable cache */ + move.l #CF_CACR_CINV, %d0 /* Invalidate cache cmd */ + movec %d0, %CACR /* Invalidate cache */ + nop + move.l #0, %d0 + movec %d0, %ACR0 + movec %d0, %ACR1 + + /* initialize general use internal ram */ + move.l #0, %d0 + move.l #(ICACHE_STATUS), %a1 /* icache */ + move.l #(DCACHE_STATUS), %a2 /* icache */ + move.l %d0, (%a1) + move.l %d0, (%a2) + + /* set stackpointer to end of internal ram to get some stackspace for the + first c-code */ + move.l #(CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_SP_OFFSET), %sp + clr.l %sp@- + + move.l #__got_start, %a5 /* put relocation table address to a5 */ + + bsr cpu_init_f /* run low-level CPU init code (from flash) */ + bsr board_init_f /* run low-level board init code (from flash) */ + + /* board_init_f() does not return */ + +/*------------------------------------------------------------------------------*/ + +/* + * void relocate_code (addr_sp, gd, addr_moni) + * + * This "function" does not return, instead it continues in RAM + * after relocating the monitor code. + * + * r3 = dest + * r4 = src + * r5 = length in bytes + * r6 = cachelinesize + */ + .globl relocate_code +relocate_code: + link.w %a6,#0 + move.l 8(%a6), %sp /* set new stack pointer */ + + move.l 12(%a6), %d0 /* Save copy of Global Data pointer */ + move.l 16(%a6), %a0 /* Save copy of Destination Address */ + + move.l #CONFIG_SYS_MONITOR_BASE, %a1 + move.l #__init_end, %a2 + move.l %a0, %a3 + + /* copy the code to RAM */ +1: + move.l (%a1)+, (%a3)+ + cmp.l %a1,%a2 + bgt.s 1b + +/* + * We are done. Do not return, instead branch to second part of board + * initialization, now running from RAM. + */ + move.l %a0, %a1 + add.l #(in_ram - CONFIG_SYS_MONITOR_BASE), %a1 + jmp (%a1) + +in_ram: + +clear_bss: + /* + * Now clear BSS segment + */ + move.l %a0, %a1 + add.l #(_sbss - CONFIG_SYS_MONITOR_BASE),%a1 + move.l %a0, %d1 + add.l #(_ebss - CONFIG_SYS_MONITOR_BASE),%d1 +6: + clr.l (%a1)+ + cmp.l %a1,%d1 + bgt.s 6b + + /* + * fix got table in RAM + */ + move.l %a0, %a1 + add.l #(__got_start - CONFIG_SYS_MONITOR_BASE),%a1 + move.l %a1,%a5 /* * fix got pointer register a5 */ + + move.l %a0, %a2 + add.l #(__got_end - CONFIG_SYS_MONITOR_BASE),%a2 + +7: + move.l (%a1),%d1 + sub.l #_start,%d1 + add.l %a0,%d1 + move.l %d1,(%a1)+ + cmp.l %a2, %a1 + bne 7b + + /* calculate relative jump to board_init_r in ram */ + move.l %a0, %a1 + add.l #(board_init_r - CONFIG_SYS_MONITOR_BASE), %a1 + + /* set parameters for board_init_r */ + move.l %a0,-(%sp) /* dest_addr */ + move.l %d0,-(%sp) /* gd */ + jsr (%a1) + +/*------------------------------------------------------------------------------*/ +/* exception code */ + .globl _fault +_fault: + jmp _fault + .globl _exc_handler + +_exc_handler: + SAVE_ALL + movel %sp,%sp@- + bsr exc_handler + addql #4,%sp + RESTORE_ALL + + .globl _int_handler +_int_handler: + SAVE_ALL + movel %sp,%sp@- + bsr int_handler + addql #4,%sp + RESTORE_ALL + +/*------------------------------------------------------------------------------*/ + + .globl version_string +version_string: + .ascii U_BOOT_VERSION + .ascii " (", U_BOOT_DATE, " - ", U_BOOT_TIME, ")" + .ascii CONFIG_IDENT_STRING, "\0" + .align 4 diff --git a/arch/m68k/cpu/mcf52x2/Makefile b/arch/m68k/cpu/mcf52x2/Makefile new file mode 100644 index 0000000000..937cdd0584 --- /dev/null +++ b/arch/m68k/cpu/mcf52x2/Makefile @@ -0,0 +1,49 @@ +# +# (C) Copyright 2000-2006 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +include $(TOPDIR)/config.mk + +# CFLAGS += -DET_DEBUG + +LIB = $(obj)lib$(CPU).a + +START = start.o +COBJS = interrupts.o cpu.o speed.o cpu_init.o + +SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) +START := $(addprefix $(obj),$(START)) + +all: $(obj).depend $(START) $(LIB) + +$(LIB): $(OBJS) + $(AR) $(ARFLAGS) $@ $(OBJS) + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/arch/m68k/cpu/mcf52x2/config.mk b/arch/m68k/cpu/mcf52x2/config.mk new file mode 100644 index 0000000000..52751be3e4 --- /dev/null +++ b/arch/m68k/cpu/mcf52x2/config.mk @@ -0,0 +1,64 @@ +# +# (C) Copyright 2003 Josef Baumgartner <josef.baumgartner@telex.de> +# +# (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-d7 -msep-data + +cfg=$(shell grep configs $(OBJTREE)/include/config.h | sed 's/.*<\(configs.*\)>/\1/') +is5208:=$(shell grep CONFIG_M5208 $(TOPDIR)/include/$(cfg)) +is5249:=$(shell grep CONFIG_M5249 $(TOPDIR)/include/$(cfg)) +is5253:=$(shell grep CONFIG_M5253 $(TOPDIR)/include/$(cfg)) +is5271:=$(shell grep CONFIG_M5271 $(TOPDIR)/include/$(cfg)) +is5272:=$(shell grep CONFIG_M5272 $(TOPDIR)/include/$(cfg)) +is5275:=$(shell grep CONFIG_M5275 $(TOPDIR)/include/$(cfg)) +is5282:=$(shell grep CONFIG_M5282 $(TOPDIR)/include/$(cfg)) + + +ifneq ($(findstring 4.1,$(shell $(CC) --version)),4.1) + +ifneq (,$(findstring CONFIG_M5208,$(is5208))) +PLATFORM_CPPFLAGS += -mcpu=5208 +endif +ifneq (,$(findstring CONFIG_M5249,$(is5249))) +PLATFORM_CPPFLAGS += -mcpu=5249 +endif +ifneq (,$(findstring CONFIG_M5253,$(is5253))) +PLATFORM_CPPFLAGS += -mcpu=5253 +endif +ifneq (,$(findstring CONFIG_M5271,$(is5271))) +PLATFORM_CPPFLAGS += -mcpu=5271 +endif +ifneq (,$(findstring CONFIG_M5272,$(is5272))) +PLATFORM_CPPFLAGS += -mcpu=5272 +endif +ifneq (,$(findstring CONFIG_M5275,$(is5275))) +PLATFORM_CPPFLAGS += -mcpu=5275 +endif +ifneq (,$(findstring CONFIG_M5282,$(is5282))) +PLATFORM_CPPFLAGS += -mcpu=5282 +endif + +else +PLATFORM_CPPFLAGS += -m5307 +endif diff --git a/arch/m68k/cpu/mcf52x2/cpu.c b/arch/m68k/cpu/mcf52x2/cpu.c new file mode 100644 index 0000000000..c4c5d50604 --- /dev/null +++ b/arch/m68k/cpu/mcf52x2/cpu.c @@ -0,0 +1,408 @@ +/* + * (C) Copyright 2003 + * Josef Baumgartner <josef.baumgartner@telex.de> + * + * MCF5282 additionals + * (C) Copyright 2005 + * BuS Elektronik GmbH & Co. KG <esw@bus-elektronik.de> + * + * MCF5275 additions + * Copyright (C) 2008 Arthur Shipkowski (art@videon-central.com) + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <watchdog.h> +#include <command.h> +#include <asm/immap.h> +#include <netdev.h> +#include "cpu.h" + +DECLARE_GLOBAL_DATA_PTR; + +#ifdef CONFIG_M5208 +int do_reset(cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) +{ + volatile rcm_t *rcm = (rcm_t *)(MMAP_RCM); + + udelay(1000); + + rcm->rcr = RCM_RCR_SOFTRST; + + /* we don't return! */ + return 0; +}; + +int checkcpu(void) +{ + char buf1[32], buf2[32]; + + printf("CPU: Freescale Coldfire MCF5208\n" + " CPU CLK %s MHz BUS CLK %s MHz\n", + strmhz(buf1, gd->cpu_clk), + strmhz(buf2, gd->bus_clk)); + return 0; +}; + +#if defined(CONFIG_WATCHDOG) +/* Called by macro WATCHDOG_RESET */ +void watchdog_reset(void) +{ + volatile wdog_t *wdt = (volatile wdog_t *)(MMAP_WDOG); + wdt->sr = 0x5555; + wdt->sr = 0xAAAA; +} + +int watchdog_disable(void) +{ + volatile wdog_t *wdt = (volatile wdog_t *)(MMAP_WDOG); + + wdt->sr = 0x5555; /* reset watchdog counteDECLARE_GLOBAL_DATA_PTR; +r */ + wdt->sr = 0xAAAA; + wdt->cr = 0; /* disable watchdog timer */ + + puts("WATCHDOG:disabled\n"); + return (0); +} + +int watchdog_init(void) +{ + volatile wdog_t *wdt = (volatile wdog_t *)(MMAP_WDOG); + + wdt->cr = 0; /* disable watchdog */ + + /* set timeout and enable watchdog */ + wdt->mr = + ((CONFIG_WATCHDOG_TIMEOUT * CONFIG_SYS_HZ) / (32768 * 1000)) - 1; + wdt->sr = 0x5555; /* reset watchdog counter */ + wdt->sr = 0xAAAA; + + puts("WATCHDOG:enabled\n"); + return (0); +} +#endif /* #ifdef CONFIG_WATCHDOG */ +#endif /* #ifdef CONFIG_M5208 */ + +#ifdef CONFIG_M5271 +/* + * Both MCF5270 and MCF5271 are members of the MPC5271 family. Try to + * determine which one we are running on, based on the Chip Identification + * Register (CIR). + */ +int checkcpu(void) +{ + char buf[32]; + unsigned short cir; /* Chip Identification Register */ + unsigned short pin; /* Part identification number */ + unsigned char prn; /* Part revision number */ + char *cpu_model; + + cir = mbar_readShort(MCF_CCM_CIR); + pin = cir >> MCF_CCM_CIR_PIN_LEN; + prn = cir & MCF_CCM_CIR_PRN_MASK; + + switch (pin) { + case MCF_CCM_CIR_PIN_MCF5270: + cpu_model = "5270"; + break; + case MCF_CCM_CIR_PIN_MCF5271: + cpu_model = "5271"; + break; + default: + cpu_model = NULL; + break; + } + + if (cpu_model) + printf("CPU: Freescale ColdFire MCF%s rev. %hu, at %s MHz\n", + cpu_model, prn, strmhz(buf, CONFIG_SYS_CLK)); + else + printf("CPU: Unknown - Freescale ColdFire MCF5271 family" + " (PIN: 0x%x) rev. %hu, at %s MHz\n", + pin, prn, strmhz(buf, CONFIG_SYS_CLK)); + + return 0; +} + +int do_reset(cmd_tbl_t * cmdtp, bd_t * bd, int flag, int argc, char *argv[]) +{ + /* Call the board specific reset actions first. */ + if(board_reset) { + board_reset(); + } + + mbar_writeByte(MCF_RCM_RCR, + MCF_RCM_RCR_SOFTRST | MCF_RCM_RCR_FRCRSTOUT); + return 0; +}; + +#if defined(CONFIG_WATCHDOG) +void watchdog_reset(void) +{ + mbar_writeShort(MCF_WTM_WSR, 0x5555); + mbar_writeShort(MCF_WTM_WSR, 0xAAAA); +} + +int watchdog_disable(void) +{ + mbar_writeShort(MCF_WTM_WCR, 0); + return (0); +} + +int watchdog_init(void) +{ + mbar_writeShort(MCF_WTM_WCR, MCF_WTM_WCR_EN); + return (0); +} +#endif /* #ifdef CONFIG_WATCHDOG */ + +#endif + +#ifdef CONFIG_M5272 +int do_reset(cmd_tbl_t * cmdtp, bd_t * bd, int flag, int argc, char *argv[]) +{ + volatile wdog_t *wdp = (wdog_t *) (MMAP_WDOG); + + wdp->wdog_wrrr = 0; + udelay(1000); + + /* enable watchdog, set timeout to 0 and wait */ + wdp->wdog_wrrr = 1; + while (1) ; + + /* we don't return! */ + return 0; +}; + +int checkcpu(void) +{ + volatile sysctrl_t *sysctrl = (sysctrl_t *) (MMAP_CFG); + uchar msk; + char *suf; + + puts("CPU: "); + msk = (sysctrl->sc_dir > 28) & 0xf; + switch (msk) { + case 0x2: + suf = "1K75N"; + break; + case 0x4: + suf = "3K75N"; + break; + default: + suf = NULL; + printf("Freescale MCF5272 (Mask:%01x)\n", msk); + break; + } + + if (suf) + printf("Freescale MCF5272 %s\n", suf); + return 0; +}; + +#if defined(CONFIG_WATCHDOG) +/* Called by macro WATCHDOG_RESET */ +void watchdog_reset(void) +{ + volatile wdog_t *wdt = (volatile wdog_t *)(MMAP_WDOG); + wdt->wdog_wcr = 0; +} + +int watchdog_disable(void) +{ + volatile wdog_t *wdt = (volatile wdog_t *)(MMAP_WDOG); + + wdt->wdog_wcr = 0; /* reset watchdog counter */ + wdt->wdog_wirr = 0; /* disable watchdog interrupt */ + wdt->wdog_wrrr = 0; /* disable watchdog timer */ + + puts("WATCHDOG:disabled\n"); + return (0); +} + +int watchdog_init(void) +{ + volatile wdog_t *wdt = (volatile wdog_t *)(MMAP_WDOG); + + wdt->wdog_wirr = 0; /* disable watchdog interrupt */ + + /* set timeout and enable watchdog */ + wdt->wdog_wrrr = + ((CONFIG_WATCHDOG_TIMEOUT * CONFIG_SYS_HZ) / (32768 * 1000)) - 1; + wdt->wdog_wcr = 0; /* reset watchdog counter */ + + puts("WATCHDOG:enabled\n"); + return (0); +} +#endif /* #ifdef CONFIG_WATCHDOG */ + +#endif /* #ifdef CONFIG_M5272 */ + +#ifdef CONFIG_M5275 +int do_reset(cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) +{ + volatile rcm_t *rcm = (rcm_t *)(MMAP_RCM); + + udelay(1000); + + rcm->rcr = RCM_RCR_SOFTRST; + + /* we don't return! */ + return 0; +}; + +int checkcpu(void) +{ + char buf[32]; + + printf("CPU: Freescale Coldfire MCF5275 at %s MHz\n", + strmhz(buf, CONFIG_SYS_CLK)); + return 0; +}; + + +#if defined(CONFIG_WATCHDOG) +/* Called by macro WATCHDOG_RESET */ +void watchdog_reset(void) +{ + volatile wdog_t *wdt = (volatile wdog_t *)(MMAP_WDOG); + wdt->wsr = 0x5555; + wdt->wsr = 0xAAAA; +} + +int watchdog_disable(void) +{ + volatile wdog_t *wdt = (volatile wdog_t *)(MMAP_WDOG); + + wdt->wsr = 0x5555; /* reset watchdog counter */ + wdt->wsr = 0xAAAA; + wdt->wcr = 0; /* disable watchdog timer */ + + puts("WATCHDOG:disabled\n"); + return (0); +} + +int watchdog_init(void) +{ + volatile wdog_t *wdt = (volatile wdog_t *)(MMAP_WDOG); + + wdt->wcr = 0; /* disable watchdog */ + + /* set timeout and enable watchdog */ + wdt->wmr = + ((CONFIG_WATCHDOG_TIMEOUT * CONFIG_SYS_HZ) / (32768 * 1000)) - 1; + wdt->wsr = 0x5555; /* reset watchdog counter */ + wdt->wsr = 0xAAAA; + + puts("WATCHDOG:enabled\n"); + return (0); +} +#endif /* #ifdef CONFIG_WATCHDOG */ + +#endif /* #ifdef CONFIG_M5275 */ + +#ifdef CONFIG_M5282 +int checkcpu(void) +{ + unsigned char resetsource = MCFRESET_RSR; + + printf("CPU: Freescale Coldfire MCF5282 (PIN: %2.2x REV: %2.2x)\n", + MCFCCM_CIR >> 8, MCFCCM_CIR & MCFCCM_CIR_PRN_MASK); + printf("Reset:%s%s%s%s%s%s%s\n", + (resetsource & MCFRESET_RSR_LOL) ? " Loss of Lock" : "", + (resetsource & MCFRESET_RSR_LOC) ? " Loss of Clock" : "", + (resetsource & MCFRESET_RSR_EXT) ? " External" : "", + (resetsource & MCFRESET_RSR_POR) ? " Power On" : "", + (resetsource & MCFRESET_RSR_WDR) ? " Watchdog" : "", + (resetsource & MCFRESET_RSR_SOFT) ? " Software" : "", + (resetsource & MCFRESET_RSR_LVD) ? " Low Voltage" : ""); + return 0; +} + +int do_reset(cmd_tbl_t * cmdtp, bd_t * bd, int flag, int argc, char *argv[]) +{ + MCFRESET_RCR = MCFRESET_RCR_SOFTRST; + return 0; +}; +#endif + +#ifdef CONFIG_M5249 +int checkcpu(void) +{ + char buf[32]; + + printf("CPU: Freescale Coldfire MCF5249 at %s MHz\n", + strmhz(buf, CONFIG_SYS_CLK)); + return 0; +} + +int do_reset(cmd_tbl_t * cmdtp, bd_t * bd, int flag, int argc, char *argv[]) +{ + /* enable watchdog, set timeout to 0 and wait */ + mbar_writeByte(MCFSIM_SYPCR, 0xc0); + while (1) ; + + /* we don't return! */ + return 0; +}; +#endif + +#ifdef CONFIG_M5253 +int checkcpu(void) +{ + char buf[32]; + + unsigned char resetsource = mbar_readLong(SIM_RSR); + printf("CPU: Freescale Coldfire MCF5253 at %s MHz\n", + strmhz(buf, CONFIG_SYS_CLK)); + + if ((resetsource & SIM_RSR_HRST) || (resetsource & SIM_RSR_SWTR)) { + printf("Reset:%s%s\n", + (resetsource & SIM_RSR_HRST) ? " Hardware/ System Reset" + : "", + (resetsource & SIM_RSR_SWTR) ? " Software Watchdog" : + ""); + } + return 0; +} + +int do_reset(cmd_tbl_t * cmdtp, bd_t * bd, int flag, int argc, char *argv[]) +{ + /* enable watchdog, set timeout to 0 and wait */ + mbar_writeByte(SIM_SYPCR, 0xc0); + while (1) ; + + /* we don't return! */ + return 0; +}; +#endif + +#if defined(CONFIG_MCFFEC) +/* Default initializations for MCFFEC controllers. To override, + * create a board-specific function called: + * int board_eth_init(bd_t *bis) + */ + +int cpu_eth_init(bd_t *bis) +{ + return mcffec_initialize(bis); +} +#endif diff --git a/arch/m68k/cpu/mcf52x2/cpu.h b/arch/m68k/cpu/mcf52x2/cpu.h new file mode 100644 index 0000000000..c1227eb1ce --- /dev/null +++ b/arch/m68k/cpu/mcf52x2/cpu.h @@ -0,0 +1,33 @@ +/* + * cpu.h + * + * Copyright (c) 2009 Freescale Semiconductor, Inc. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * 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., 51 Franklin St, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#ifndef _CPU_H_ +#define _CPU_H_ + +#include <command.h> + +/* Use this to create board specific reset functions */ +void board_reset(void) __attribute__((__weak__)); + +#endif /* _CPU_H_ */ diff --git a/arch/m68k/cpu/mcf52x2/cpu_init.c b/arch/m68k/cpu/mcf52x2/cpu_init.c new file mode 100644 index 0000000000..170bbfc356 --- /dev/null +++ b/arch/m68k/cpu/mcf52x2/cpu_init.c @@ -0,0 +1,747 @@ +/* + * (C) Copyright 2003 + * Josef Baumgartner <josef.baumgartner@telex.de> + * + * MCF5282 additionals + * (C) Copyright 2005 + * BuS Elektronik GmbH & Co. KG <esw@bus-elektronik.de> + * (c) Copyright 2010 + * Arcturus Networks Inc. <www.arcturusnetworks.com> + * + * Copyright (C) 2004-2007 Freescale Semiconductor, Inc. + * TsiChung Liew (Tsi-Chung.Liew@freescale.com) + * Hayden Fraser (Hayden.Fraser@freescale.com) + * + * MCF5275 additions + * Copyright (C) 2008 Arthur Shipkowski (art@videon-central.com) + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <watchdog.h> +#include <asm/immap.h> + +#if defined(CONFIG_CMD_NET) +#include <config.h> +#include <net.h> +#include <asm/fec.h> +#endif + +#ifndef CONFIG_M5272 +/* Only 5272 Flexbus chipselect is different from the rest */ +void init_fbcs(void) +{ + volatile fbcs_t *fbcs = (fbcs_t *) (MMAP_FBCS); + +#if (defined(CONFIG_SYS_CS0_BASE) && defined(CONFIG_SYS_CS0_MASK) \ + && defined(CONFIG_SYS_CS0_CTRL)) + fbcs->csar0 = CONFIG_SYS_CS0_BASE; + fbcs->cscr0 = CONFIG_SYS_CS0_CTRL; + fbcs->csmr0 = CONFIG_SYS_CS0_MASK; +#else +#warning "Chip Select 0 are not initialized/used" +#endif +#if (defined(CONFIG_SYS_CS1_BASE) && defined(CONFIG_SYS_CS1_MASK) \ + && defined(CONFIG_SYS_CS1_CTRL)) + fbcs->csar1 = CONFIG_SYS_CS1_BASE; + fbcs->cscr1 = CONFIG_SYS_CS1_CTRL; + fbcs->csmr1 = CONFIG_SYS_CS1_MASK; +#endif +#if (defined(CONFIG_SYS_CS2_BASE) && defined(CONFIG_SYS_CS2_MASK) \ + && defined(CONFIG_SYS_CS2_CTRL)) + fbcs->csar2 = CONFIG_SYS_CS2_BASE; + fbcs->cscr2 = CONFIG_SYS_CS2_CTRL; + fbcs->csmr2 = CONFIG_SYS_CS2_MASK; +#endif +#if (defined(CONFIG_SYS_CS3_BASE) && defined(CONFIG_SYS_CS3_MASK) \ + && defined(CONFIG_SYS_CS3_CTRL)) + fbcs->csar3 = CONFIG_SYS_CS3_BASE; + fbcs->cscr3 = CONFIG_SYS_CS3_CTRL; + fbcs->csmr3 = CONFIG_SYS_CS3_MASK; +#endif +#if (defined(CONFIG_SYS_CS4_BASE) && defined(CONFIG_SYS_CS4_MASK) \ + && defined(CONFIG_SYS_CS4_CTRL)) + fbcs->csar4 = CONFIG_SYS_CS4_BASE; + fbcs->cscr4 = CONFIG_SYS_CS4_CTRL; + fbcs->csmr4 = CONFIG_SYS_CS4_MASK; +#endif +#if (defined(CONFIG_SYS_CS5_BASE) && defined(CONFIG_SYS_CS5_MASK) \ + && defined(CONFIG_SYS_CS5_CTRL)) + fbcs->csar5 = CONFIG_SYS_CS5_BASE; + fbcs->cscr5 = CONFIG_SYS_CS5_CTRL; + fbcs->csmr5 = CONFIG_SYS_CS5_MASK; +#endif +#if (defined(CONFIG_SYS_CS6_BASE) && defined(CONFIG_SYS_CS6_MASK) \ + && defined(CONFIG_SYS_CS6_CTRL)) + fbcs->csar6 = CONFIG_SYS_CS6_BASE; + fbcs->cscr6 = CONFIG_SYS_CS6_CTRL; + fbcs->csmr6 = CONFIG_SYS_CS6_MASK; +#endif +#if (defined(CONFIG_SYS_CS7_BASE) && defined(CONFIG_SYS_CS7_MASK) \ + && defined(CONFIG_SYS_CS7_CTRL)) + fbcs->csar7 = CONFIG_SYS_CS7_BASE; + fbcs->cscr7 = CONFIG_SYS_CS7_CTRL; + fbcs->csmr7 = CONFIG_SYS_CS7_MASK; +#endif +} +#endif + +#if defined(CONFIG_M5208) +void cpu_init_f(void) +{ + volatile scm1_t *scm1 = (scm1_t *) MMAP_SCM1; + +#ifndef CONFIG_WATCHDOG + volatile wdog_t *wdg = (wdog_t *) MMAP_WDOG; + + /* Disable the watchdog if we aren't using it */ + wdg->cr = 0; +#endif + + scm1->mpr = 0x77777777; + scm1->pacra = 0; + scm1->pacrb = 0; + scm1->pacrc = 0; + scm1->pacrd = 0; + scm1->pacre = 0; + scm1->pacrf = 0; + + /* FlexBus Chipselect */ + init_fbcs(); + + icache_enable(); +} + +/* initialize higher level parts of CPU like timers */ +int cpu_init_r(void) +{ + return (0); +} + +void uart_port_conf(int port) +{ + volatile gpio_t *gpio = (gpio_t *) MMAP_GPIO; + + /* Setup Ports: */ + switch (port) { + case 0: + gpio->par_uart &= GPIO_PAR_UART0_UNMASK; + gpio->par_uart |= (GPIO_PAR_UART_U0TXD | GPIO_PAR_UART_U0RXD); + break; + case 1: + gpio->par_uart &= GPIO_PAR_UART0_UNMASK; + gpio->par_uart |= (GPIO_PAR_UART_U1TXD | GPIO_PAR_UART_U1RXD); + break; + case 2: +#ifdef CONFIG_SYS_UART2_PRI_GPIO + gpio->par_timer &= + (GPIO_PAR_TMR_TIN0_UNMASK | GPIO_PAR_TMR_TIN1_UNMASK); + gpio->par_timer |= + (GPIO_PAR_TMR_TIN0_U2TXD | GPIO_PAR_TMR_TIN1_U2RXD); +#endif +#ifdef CONFIG_SYS_UART2_ALT1_GPIO + gpio->par_feci2c &= + (GPIO_PAR_FECI2C_MDC_UNMASK | GPIO_PAR_FECI2C_MDIO_UNMASK); + gpio->par_feci2c |= + (GPIO_PAR_FECI2C_MDC_U2TXD | GPIO_PAR_FECI2C_MDIO_U2RXD); +#endif +#ifdef CONFIG_SYS_UART2_ALT1_GPIO + gpio->par_feci2c &= + (GPIO_PAR_FECI2C_SDA_UNMASK | GPIO_PAR_FECI2C_SCL_UNMASK); + gpio->par_feci2c |= + (GPIO_PAR_FECI2C_SDA_U2TXD | GPIO_PAR_FECI2C_SCL_U2RXD); +#endif + break; + } +} + +#if defined(CONFIG_CMD_NET) +int fecpin_setclear(struct eth_device *dev, int setclear) +{ + volatile gpio_t *gpio = (gpio_t *) MMAP_GPIO; + + if (setclear) { + gpio->par_fec |= + GPIO_PAR_FEC_7W_FEC | GPIO_PAR_FEC_MII_FEC; + gpio->par_feci2c |= + GPIO_PAR_FECI2C_MDC_MDC | GPIO_PAR_FECI2C_MDIO_MDIO; + } else { + gpio->par_fec &= + (GPIO_PAR_FEC_7W_UNMASK & GPIO_PAR_FEC_MII_UNMASK); + gpio->par_feci2c &= GPIO_PAR_FECI2C_RMII_UNMASK; + } + return 0; +} +#endif /* CONFIG_CMD_NET */ +#endif /* CONFIG_M5208 */ + +#if defined(CONFIG_M5253) +/* + * Breath some life into the CPU... + * + * Set up the memory map, + * initialize a bunch of registers, + * initialize the UPM's + */ +void cpu_init_f(void) +{ + mbar_writeByte(MCFSIM_MPARK, 0x40); /* 5249 Internal Core takes priority over DMA */ + mbar_writeByte(MCFSIM_SYPCR, 0x00); + mbar_writeByte(MCFSIM_SWIVR, 0x0f); + mbar_writeByte(MCFSIM_SWSR, 0x00); + mbar_writeByte(MCFSIM_SWDICR, 0x00); + mbar_writeByte(MCFSIM_TIMER1ICR, 0x00); + mbar_writeByte(MCFSIM_TIMER2ICR, 0x88); + mbar_writeByte(MCFSIM_I2CICR, 0x00); + mbar_writeByte(MCFSIM_UART1ICR, 0x00); + mbar_writeByte(MCFSIM_UART2ICR, 0x00); + mbar_writeByte(MCFSIM_ICR6, 0x00); + mbar_writeByte(MCFSIM_ICR7, 0x00); + mbar_writeByte(MCFSIM_ICR8, 0x00); + mbar_writeByte(MCFSIM_ICR9, 0x00); + mbar_writeByte(MCFSIM_QSPIICR, 0x00); + + mbar2_writeLong(MCFSIM_GPIO_INT_EN, 0x00000080); + mbar2_writeByte(MCFSIM_INTBASE, 0x40); /* Base interrupts at 64 */ + mbar2_writeByte(MCFSIM_SPURVEC, 0x00); + + /*mbar2_writeLong(MCFSIM_IDECONFIG1, 0x00000020); */ /* Enable a 1 cycle pre-drive cycle on CS1 */ + + /* FlexBus Chipselect */ + init_fbcs(); + +#ifdef CONFIG_FSL_I2C + CONFIG_SYS_I2C_PINMUX_REG = + CONFIG_SYS_I2C_PINMUX_REG & CONFIG_SYS_I2C_PINMUX_CLR; + CONFIG_SYS_I2C_PINMUX_REG |= CONFIG_SYS_I2C_PINMUX_SET; +#ifdef CONFIG_SYS_I2C2_OFFSET + CONFIG_SYS_I2C2_PINMUX_REG &= CONFIG_SYS_I2C2_PINMUX_CLR; + CONFIG_SYS_I2C2_PINMUX_REG |= CONFIG_SYS_I2C2_PINMUX_SET; +#endif +#endif + + /* enable instruction cache now */ + icache_enable(); +} + +/*initialize higher level parts of CPU like timers */ +int cpu_init_r(void) +{ + return (0); +} + +void uart_port_conf(int port) +{ + volatile u32 *par = (u32 *) MMAP_PAR; + + /* Setup Ports: */ + switch (port) { + case 1: + *par &= 0xFFE7FFFF; + *par |= 0x00180000; + break; + case 2: + *par &= 0xFFFFFFFC; + *par &= 0x00000003; + break; + } +} +#endif /* #if defined(CONFIG_M5253) */ + +#if defined(CONFIG_M5271) +void cpu_init_f(void) +{ +#ifndef CONFIG_WATCHDOG + /* Disable the watchdog if we aren't using it */ + mbar_writeShort(MCF_WTM_WCR, 0); +#endif + + /* FlexBus Chipselect */ + init_fbcs(); + +#ifdef CONFIG_SYS_MCF_SYNCR + /* Set clockspeed according to board header file */ + mbar_writeLong(MCF_FMPLL_SYNCR, CONFIG_SYS_MCF_SYNCR); +#else + /* Set clockspeed to 100MHz */ + mbar_writeLong(MCF_FMPLL_SYNCR, + MCF_FMPLL_SYNCR_MFD(0) | MCF_FMPLL_SYNCR_RFD(0)); +#endif + while (!mbar_readByte(MCF_FMPLL_SYNSR) & MCF_FMPLL_SYNSR_LOCK) ; +} + +/* + * initialize higher level parts of CPU like timers + */ +int cpu_init_r(void) +{ + return (0); +} + +void uart_port_conf(int port) +{ + u16 temp; + + /* Setup Ports: */ + switch (port) { + case 0: + temp = mbar_readShort(MCF_GPIO_PAR_UART) & 0xFFF3; + temp |= (MCF_GPIO_PAR_UART_U0TXD | MCF_GPIO_PAR_UART_U0RXD); + mbar_writeShort(MCF_GPIO_PAR_UART, temp); + break; + case 1: + temp = mbar_readShort(MCF_GPIO_PAR_UART) & 0xF0FF; + temp |= (MCF_GPIO_PAR_UART_U1RXD_UART1 | MCF_GPIO_PAR_UART_U1TXD_UART1); + mbar_writeShort(MCF_GPIO_PAR_UART, temp); + break; + case 2: + temp = mbar_readShort(MCF_GPIO_PAR_UART) & 0xCFFF; + temp |= (0x3000); + mbar_writeShort(MCF_GPIO_PAR_UART, temp); + break; + } +} + +#if defined(CONFIG_CMD_NET) +int fecpin_setclear(struct eth_device *dev, int setclear) +{ + if (setclear) { + /* Enable Ethernet pins */ + mbar_writeByte(MCF_GPIO_PAR_FECI2C, + (mbar_readByte(MCF_GPIO_PAR_FECI2C) | 0xF0)); + } else { + } + + return 0; +} +#endif /* CONFIG_CMD_NET */ +#endif + +#if defined(CONFIG_M5272) +/* + * Breath some life into the CPU... + * + * Set up the memory map, + * initialize a bunch of registers, + * initialize the UPM's + */ +void cpu_init_f(void) +{ + /* if we come from RAM we assume the CPU is + * already initialized. + */ +#ifndef CONFIG_MONITOR_IS_IN_RAM + volatile sysctrl_t *sysctrl = (sysctrl_t *) (CONFIG_SYS_MBAR); + volatile gpio_t *gpio = (gpio_t *) (MMAP_GPIO); + volatile csctrl_t *csctrl = (csctrl_t *) (MMAP_FBCS); + + sysctrl->sc_scr = CONFIG_SYS_SCR; + sysctrl->sc_spr = CONFIG_SYS_SPR; + + /* Setup Ports: */ + gpio->gpio_pacnt = CONFIG_SYS_PACNT; + gpio->gpio_paddr = CONFIG_SYS_PADDR; + gpio->gpio_padat = CONFIG_SYS_PADAT; + gpio->gpio_pbcnt = CONFIG_SYS_PBCNT; + gpio->gpio_pbddr = CONFIG_SYS_PBDDR; + gpio->gpio_pbdat = CONFIG_SYS_PBDAT; + gpio->gpio_pdcnt = CONFIG_SYS_PDCNT; + + /* Memory Controller: */ + csctrl->cs_br0 = CONFIG_SYS_BR0_PRELIM; + csctrl->cs_or0 = CONFIG_SYS_OR0_PRELIM; + +#if (defined(CONFIG_SYS_OR1_PRELIM) && defined(CONFIG_SYS_BR1_PRELIM)) + csctrl->cs_br1 = CONFIG_SYS_BR1_PRELIM; + csctrl->cs_or1 = CONFIG_SYS_OR1_PRELIM; +#endif + +#if defined(CONFIG_SYS_OR2_PRELIM) && defined(CONFIG_SYS_BR2_PRELIM) + csctrl->cs_br2 = CONFIG_SYS_BR2_PRELIM; + csctrl->cs_or2 = CONFIG_SYS_OR2_PRELIM; +#endif + +#if defined(CONFIG_SYS_OR3_PRELIM) && defined(CONFIG_SYS_BR3_PRELIM) + csctrl->cs_br3 = CONFIG_SYS_BR3_PRELIM; + csctrl->cs_or3 = CONFIG_SYS_OR3_PRELIM; +#endif + +#if defined(CONFIG_SYS_OR4_PRELIM) && defined(CONFIG_SYS_BR4_PRELIM) + csctrl->cs_br4 = CONFIG_SYS_BR4_PRELIM; + csctrl->cs_or4 = CONFIG_SYS_OR4_PRELIM; +#endif + +#if defined(CONFIG_SYS_OR5_PRELIM) && defined(CONFIG_SYS_BR5_PRELIM) + csctrl->cs_br5 = CONFIG_SYS_BR5_PRELIM; + csctrl->cs_or5 = CONFIG_SYS_OR5_PRELIM; +#endif + +#if defined(CONFIG_SYS_OR6_PRELIM) && defined(CONFIG_SYS_BR6_PRELIM) + csctrl->cs_br6 = CONFIG_SYS_BR6_PRELIM; + csctrl->cs_or6 = CONFIG_SYS_OR6_PRELIM; +#endif + +#if defined(CONFIG_SYS_OR7_PRELIM) && defined(CONFIG_SYS_BR7_PRELIM) + csctrl->cs_br7 = CONFIG_SYS_BR7_PRELIM; + csctrl->cs_or7 = CONFIG_SYS_OR7_PRELIM; +#endif + +#endif /* #ifndef CONFIG_MONITOR_IS_IN_RAM */ + + /* enable instruction cache now */ + icache_enable(); + +} + +/* + * initialize higher level parts of CPU like timers + */ +int cpu_init_r(void) +{ + return (0); +} + +void uart_port_conf(int port) +{ + volatile gpio_t *gpio = (gpio_t *) MMAP_GPIO; + + /* Setup Ports: */ + switch (port) { + case 0: + gpio->gpio_pbcnt &= ~(GPIO_PBCNT_PB0MSK | GPIO_PBCNT_PB1MSK); + gpio->gpio_pbcnt |= (GPIO_PBCNT_URT0_TXD | GPIO_PBCNT_URT0_RXD); + break; + case 1: + gpio->gpio_pdcnt &= ~(GPIO_PDCNT_PD1MSK | GPIO_PDCNT_PD4MSK); + gpio->gpio_pdcnt |= (GPIO_PDCNT_URT1_RXD | GPIO_PDCNT_URT1_TXD); + break; + } +} + +#if defined(CONFIG_CMD_NET) +int fecpin_setclear(struct eth_device *dev, int setclear) +{ + volatile gpio_t *gpio = (gpio_t *) MMAP_GPIO; + + if (setclear) { + gpio->gpio_pbcnt |= GPIO_PBCNT_E_MDC | GPIO_PBCNT_E_RXER | + GPIO_PBCNT_E_RXD1 | GPIO_PBCNT_E_RXD2 | + GPIO_PBCNT_E_RXD3 | GPIO_PBCNT_E_TXD1 | + GPIO_PBCNT_E_TXD2 | GPIO_PBCNT_E_TXD3; + } else { + } + return 0; +} +#endif /* CONFIG_CMD_NET */ +#endif /* #if defined(CONFIG_M5272) */ + +#if defined(CONFIG_M5275) + +/* + * Breathe some life into the CPU... + * + * Set up the memory map, + * initialize a bunch of registers, + * initialize the UPM's + */ +void cpu_init_f(void) +{ + /* + * if we come from RAM we assume the CPU is + * already initialized. + */ + +#ifndef CONFIG_MONITOR_IS_IN_RAM + volatile wdog_t *wdog_reg = (wdog_t *) (MMAP_WDOG); + volatile gpio_t *gpio_reg = (gpio_t *) (MMAP_GPIO); + + /* Kill watchdog so we can initialize the PLL */ + wdog_reg->wcr = 0; + + /* FlexBus Chipselect */ + init_fbcs(); +#endif /* #ifndef CONFIG_MONITOR_IS_IN_RAM */ + +#ifdef CONFIG_FSL_I2C + CONFIG_SYS_I2C_PINMUX_REG &= CONFIG_SYS_I2C_PINMUX_CLR; + CONFIG_SYS_I2C_PINMUX_REG |= CONFIG_SYS_I2C_PINMUX_SET; +#endif + + /* enable instruction cache now */ + icache_enable(); +} + +/* + * initialize higher level parts of CPU like timers + */ +int cpu_init_r(void) +{ + return (0); +} + +void uart_port_conf(int port) +{ + volatile gpio_t *gpio = (gpio_t *) MMAP_GPIO; + + /* Setup Ports: */ + switch (port) { + case 0: + gpio->par_uart &= ~UART0_ENABLE_MASK; + gpio->par_uart |= UART0_ENABLE_MASK; + break; + case 1: + gpio->par_uart &= ~UART1_ENABLE_MASK; + gpio->par_uart |= UART1_ENABLE_MASK; + break; + case 2: + gpio->par_uart &= ~UART2_ENABLE_MASK; + gpio->par_uart |= UART2_ENABLE_MASK; + break; + } +} + +#if defined(CONFIG_CMD_NET) +int fecpin_setclear(struct eth_device *dev, int setclear) +{ + struct fec_info_s *info = (struct fec_info_s *) dev->priv; + volatile gpio_t *gpio = (gpio_t *)MMAP_GPIO; + + if (setclear) { + /* Enable Ethernet pins */ + if (info->iobase == CONFIG_SYS_FEC0_IOBASE) { + gpio->par_feci2c |= 0x0F00; + gpio->par_fec0hl |= 0xC0; + } else { + gpio->par_feci2c |= 0x00A0; + gpio->par_fec1hl |= 0xC0; + } + } else { + if (info->iobase == CONFIG_SYS_FEC0_IOBASE) { + gpio->par_feci2c &= ~0x0F00; + gpio->par_fec0hl &= ~0xC0; + } else { + gpio->par_feci2c &= ~0x00A0; + gpio->par_fec1hl &= ~0xC0; + } + } + + return 0; +} +#endif /* CONFIG_CMD_NET */ +#endif /* #if defined(CONFIG_M5275) */ + +#if defined(CONFIG_M5282) +/* + * Breath some life into the CPU... + * + * Set up the memory map, + * initialize a bunch of registers, + * initialize the UPM's + */ +void cpu_init_f(void) +{ +#ifndef CONFIG_WATCHDOG + /* disable watchdog if we aren't using it */ + MCFWTM_WCR = 0; +#endif + +#ifndef CONFIG_MONITOR_IS_IN_RAM + /* Set speed /PLL */ + MCFCLOCK_SYNCR = + MCFCLOCK_SYNCR_MFD(CONFIG_SYS_MFD) | + MCFCLOCK_SYNCR_RFD(CONFIG_SYS_RFD); + while (!(MCFCLOCK_SYNSR & MCFCLOCK_SYNSR_LOCK)) ; + + MCFGPIO_PBCDPAR = 0xc0; + + /* Set up the GPIO ports */ +#ifdef CONFIG_SYS_PEPAR + MCFGPIO_PEPAR = CONFIG_SYS_PEPAR; +#endif +#ifdef CONFIG_SYS_PFPAR + MCFGPIO_PFPAR = CONFIG_SYS_PFPAR; +#endif +#ifdef CONFIG_SYS_PJPAR + MCFGPIO_PJPAR = CONFIG_SYS_PJPAR; +#endif +#ifdef CONFIG_SYS_PSDPAR + MCFGPIO_PSDPAR = CONFIG_SYS_PSDPAR; +#endif +#ifdef CONFIG_SYS_PASPAR + MCFGPIO_PASPAR = CONFIG_SYS_PASPAR; +#endif +#ifdef CONFIG_SYS_PEHLPAR + MCFGPIO_PEHLPAR = CONFIG_SYS_PEHLPAR; +#endif +#ifdef CONFIG_SYS_PQSPAR + MCFGPIO_PQSPAR = CONFIG_SYS_PQSPAR; +#endif +#ifdef CONFIG_SYS_PTCPAR + MCFGPIO_PTCPAR = CONFIG_SYS_PTCPAR; +#endif +#if defined(CONFIG_SYS_PORTTC) + MCFGPIO_PORTTC = CONFIG_SYS_PORTTC; +#endif +#if defined(CONFIG_SYS_DDRTC) + MCFGPIO_DDRTC = CONFIG_SYS_DDRTC; +#endif +#ifdef CONFIG_SYS_PTDPAR + MCFGPIO_PTDPAR = CONFIG_SYS_PTDPAR; +#endif +#ifdef CONFIG_SYS_PUAPAR + MCFGPIO_PUAPAR = CONFIG_SYS_PUAPAR; +#endif + +#if defined(CONFIG_SYS_DDRD) + MCFGPIO_DDRD = CONFIG_SYS_DDRD; +#endif +#ifdef CONFIG_SYS_DDRUA + MCFGPIO_DDRUA = CONFIG_SYS_DDRUA; +#endif + + /* FlexBus Chipselect */ + init_fbcs(); + +#endif /* CONFIG_MONITOR_IS_IN_RAM */ + + /* defer enabling cache until boot (see do_go) */ + /* icache_enable(); */ +} + +/* + * initialize higher level parts of CPU like timers + */ +int cpu_init_r(void) +{ + return (0); +} + +void uart_port_conf(int port) +{ + /* Setup Ports: */ + switch (port) { + case 0: + MCFGPIO_PUAPAR &= 0xFc; + MCFGPIO_PUAPAR |= 0x03; + break; + case 1: + MCFGPIO_PUAPAR &= 0xF3; + MCFGPIO_PUAPAR |= 0x0C; + break; + case 2: + MCFGPIO_PASPAR &= 0xFF0F; + MCFGPIO_PASPAR |= 0x00A0; + break; + } +} + +#if defined(CONFIG_CMD_NET) +int fecpin_setclear(struct eth_device *dev, int setclear) +{ + if (setclear) { + MCFGPIO_PASPAR |= 0x0F00; + MCFGPIO_PEHLPAR = CONFIG_SYS_PEHLPAR; + } else { + MCFGPIO_PASPAR &= 0xF0FF; + MCFGPIO_PEHLPAR &= ~CONFIG_SYS_PEHLPAR; + } + return 0; +} +#endif /* CONFIG_CMD_NET */ +#endif + +#if defined(CONFIG_M5249) +/* + * Breath some life into the CPU... + * + * Set up the memory map, + * initialize a bunch of registers, + * initialize the UPM's + */ +void cpu_init_f(void) +{ + /* + * NOTE: by setting the GPIO_FUNCTION registers, we ensure that the UART pins + * (UART0: gpio 30,27, UART1: gpio 31, 28) will be used as UART pins + * which is their primary function. + * ~Jeremy + */ + mbar2_writeLong(MCFSIM_GPIO_FUNC, CONFIG_SYS_GPIO_FUNC); + mbar2_writeLong(MCFSIM_GPIO1_FUNC, CONFIG_SYS_GPIO1_FUNC); + mbar2_writeLong(MCFSIM_GPIO_EN, CONFIG_SYS_GPIO_EN); + mbar2_writeLong(MCFSIM_GPIO1_EN, CONFIG_SYS_GPIO1_EN); + mbar2_writeLong(MCFSIM_GPIO_OUT, CONFIG_SYS_GPIO_OUT); + mbar2_writeLong(MCFSIM_GPIO1_OUT, CONFIG_SYS_GPIO1_OUT); + + /* + * dBug Compliance: + * You can verify these values by using dBug's 'ird' + * (Internal Register Display) command + * ~Jeremy + * + */ + mbar_writeByte(MCFSIM_MPARK, 0x30); /* 5249 Internal Core takes priority over DMA */ + mbar_writeByte(MCFSIM_SYPCR, 0x00); + mbar_writeByte(MCFSIM_SWIVR, 0x0f); + mbar_writeByte(MCFSIM_SWSR, 0x00); + mbar_writeLong(MCFSIM_IMR, 0xfffffbff); + mbar_writeByte(MCFSIM_SWDICR, 0x00); + mbar_writeByte(MCFSIM_TIMER1ICR, 0x00); + mbar_writeByte(MCFSIM_TIMER2ICR, 0x88); + mbar_writeByte(MCFSIM_I2CICR, 0x00); + mbar_writeByte(MCFSIM_UART1ICR, 0x00); + mbar_writeByte(MCFSIM_UART2ICR, 0x00); + mbar_writeByte(MCFSIM_ICR6, 0x00); + mbar_writeByte(MCFSIM_ICR7, 0x00); + mbar_writeByte(MCFSIM_ICR8, 0x00); + mbar_writeByte(MCFSIM_ICR9, 0x00); + mbar_writeByte(MCFSIM_QSPIICR, 0x00); + + mbar2_writeLong(MCFSIM_GPIO_INT_EN, 0x00000080); + mbar2_writeByte(MCFSIM_INTBASE, 0x40); /* Base interrupts at 64 */ + mbar2_writeByte(MCFSIM_SPURVEC, 0x00); + mbar2_writeLong(MCFSIM_IDECONFIG1, 0x00000020); /* Enable a 1 cycle pre-drive cycle on CS1 */ + + /* Setup interrupt priorities for gpio7 */ + /* mbar2_writeLong(MCFSIM_INTLEV5, 0x70000000); */ + + /* IDE Config registers */ + mbar2_writeLong(MCFSIM_IDECONFIG1, 0x00000020); + mbar2_writeLong(MCFSIM_IDECONFIG2, 0x00000000); + + /* FlexBus Chipselect */ + init_fbcs(); + + /* enable instruction cache now */ + icache_enable(); +} + +/* + * initialize higher level parts of CPU like timers + */ +int cpu_init_r(void) +{ + return (0); +} + +void uart_port_conf(int port) +{ +} +#endif /* #if defined(CONFIG_M5249) */ diff --git a/arch/m68k/cpu/mcf52x2/interrupts.c b/arch/m68k/cpu/mcf52x2/interrupts.c new file mode 100644 index 0000000000..dff8c6aa88 --- /dev/null +++ b/arch/m68k/cpu/mcf52x2/interrupts.c @@ -0,0 +1,107 @@ +/* + * (C) Copyright 2000-2004 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * Copyright (C) 2004-2007 Freescale Semiconductor, Inc. + * TsiChung Liew (Tsi-Chung.Liew@freescale.com) + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <watchdog.h> +#include <asm/processor.h> +#include <asm/immap.h> + +#ifdef CONFIG_M5272 +int interrupt_init(void) +{ + volatile intctrl_t *intp = (intctrl_t *) (MMAP_INTC); + + /* disable all external interrupts */ + intp->int_icr1 = 0x88888888; + intp->int_icr2 = 0x88888888; + intp->int_icr3 = 0x88888888; + intp->int_icr4 = 0x88888888; + intp->int_pitr = 0x00000000; + /* initialize vector register */ + intp->int_pivr = 0x40; + + enable_interrupts(); + + return 0; +} + +#if defined(CONFIG_MCFTMR) +void dtimer_intr_setup(void) +{ + volatile intctrl_t *intp = (intctrl_t *) (CONFIG_SYS_INTR_BASE); + + intp->int_icr1 &= ~INT_ICR1_TMR3MASK; + intp->int_icr1 |= CONFIG_SYS_TMRINTR_PRI; +} +#endif /* CONFIG_MCFTMR */ +#endif /* CONFIG_M5272 */ + +#if defined(CONFIG_M5208) || defined(CONFIG_M5282) || \ + defined(CONFIG_M5271) || defined(CONFIG_M5275) +int interrupt_init(void) +{ + volatile int0_t *intp = (int0_t *) (CONFIG_SYS_INTR_BASE); + + /* Make sure all interrupts are disabled */ +#if defined(CONFIG_M5208) + intp->imrl0 = 0xFFFFFFFF; + intp->imrh0 = 0xFFFFFFFF; +#else + intp->imrl0 |= 0x1; +#endif + + enable_interrupts(); + return 0; +} + +#if defined(CONFIG_MCFTMR) +void dtimer_intr_setup(void) +{ + volatile int0_t *intp = (int0_t *) (CONFIG_SYS_INTR_BASE); + + intp->icr0[CONFIG_SYS_TMRINTR_NO] = CONFIG_SYS_TMRINTR_PRI; + intp->imrl0 &= 0xFFFFFFFE; + intp->imrl0 &= ~CONFIG_SYS_TMRINTR_MASK; +} +#endif /* CONFIG_MCFTMR */ +#endif /* CONFIG_M5282 | CONFIG_M5271 | CONFIG_M5275 */ + +#if defined(CONFIG_M5249) || defined(CONFIG_M5253) +int interrupt_init(void) +{ + enable_interrupts(); + + return 0; +} + +#if defined(CONFIG_MCFTMR) +void dtimer_intr_setup(void) +{ + mbar_writeLong(MCFSIM_IMR, mbar_readLong(MCFSIM_IMR) & ~0x00000400); + mbar_writeByte(MCFSIM_TIMER2ICR, CONFIG_SYS_TMRINTR_PRI); +} +#endif /* CONFIG_MCFTMR */ +#endif /* CONFIG_M5249 || CONFIG_M5253 */ diff --git a/arch/m68k/cpu/mcf52x2/speed.c b/arch/m68k/cpu/mcf52x2/speed.c new file mode 100644 index 0000000000..b485e1cccc --- /dev/null +++ b/arch/m68k/cpu/mcf52x2/speed.c @@ -0,0 +1,100 @@ +/* + * (C) Copyright 2003 + * Josef Baumgartner <josef.baumgartner@telex.de> + * + * Copyright (C) 2004-2007 Freescale Semiconductor, Inc. + * Hayden Fraser (Hayden.Fraser@freescale.com) + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <asm/processor.h> +#include <asm/immap.h> + +DECLARE_GLOBAL_DATA_PTR; + +/* get_clocks() fills in gd->cpu_clock and gd->bus_clk */ +int get_clocks (void) +{ +#if defined(CONFIG_M5208) + volatile pll_t *pll = (pll_t *) MMAP_PLL; + + pll->odr = CONFIG_SYS_PLL_ODR; + pll->fdr = CONFIG_SYS_PLL_FDR; +#endif + +#if defined(CONFIG_M5249) || defined(CONFIG_M5253) + volatile unsigned long cpll = mbar2_readLong(MCFSIM_PLLCR); + unsigned long pllcr; + +#ifndef CONFIG_SYS_PLL_BYPASS + +#ifdef CONFIG_M5249 + /* Setup the PLL to run at the specified speed */ +#ifdef CONFIG_SYS_FAST_CLK + pllcr = 0x925a3100; /* ~140MHz clock (PLL bypass = 0) */ +#else + pllcr = 0x135a4140; /* ~72MHz clock (PLL bypass = 0) */ +#endif +#endif /* CONFIG_M5249 */ + +#ifdef CONFIG_M5253 + pllcr = CONFIG_SYS_PLLCR; +#endif /* CONFIG_M5253 */ + + cpll = cpll & 0xfffffffe; /* Set PLL bypass mode = 0 (PSTCLK = crystal) */ + mbar2_writeLong(MCFSIM_PLLCR, cpll); /* Set the PLL to bypass mode (PSTCLK = crystal) */ + mbar2_writeLong(MCFSIM_PLLCR, pllcr); /* set the clock speed */ + pllcr ^= 0x00000001; /* Set pll bypass to 1 */ + mbar2_writeLong(MCFSIM_PLLCR, pllcr); /* Start locking (pll bypass = 1) */ + udelay(0x20); /* Wait for a lock ... */ +#endif /* #ifndef CONFIG_SYS_PLL_BYPASS */ + +#endif /* CONFIG_M5249 || CONFIG_M5253 */ + +#if defined(CONFIG_M5275) + volatile pll_t *pll = (volatile pll_t *)(MMAP_PLL); + + /* Setup PLL */ + pll->syncr = 0x01080000; + while (!(pll->synsr & FMPLL_SYNSR_LOCK)) + ; + pll->syncr = 0x01000000; + while (!(pll->synsr & FMPLL_SYNSR_LOCK)) + ; +#endif + + gd->cpu_clk = CONFIG_SYS_CLK; +#if defined(CONFIG_M5208) || defined(CONFIG_M5249) || defined(CONFIG_M5253) || \ + defined(CONFIG_M5271) || defined(CONFIG_M5275) + gd->bus_clk = gd->cpu_clk / 2; +#else + gd->bus_clk = gd->cpu_clk; +#endif + +#ifdef CONFIG_FSL_I2C + gd->i2c1_clk = gd->bus_clk; +#ifdef CONFIG_SYS_I2C2_OFFSET + gd->i2c2_clk = gd->bus_clk; +#endif +#endif + + return (0); +} diff --git a/arch/m68k/cpu/mcf52x2/start.S b/arch/m68k/cpu/mcf52x2/start.S new file mode 100644 index 0000000000..9ef206aa0f --- /dev/null +++ b/arch/m68k/cpu/mcf52x2/start.S @@ -0,0 +1,335 @@ +/* + * Copyright (C) 2003 Josef Baumgartner <josef.baumgartner@telex.de> + * Based on code from Bernhard Kuhn <bkuhn@metrowerks.com> + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <config.h> +#include <timestamp.h> +#include "version.h" +#include <asm/cache.h> + +#ifndef CONFIG_IDENT_STRING +#define CONFIG_IDENT_STRING "" +#endif + +#define _START _start +#define _FAULT _fault + + +#define SAVE_ALL \ + move.w #0x2700,%sr; /* disable intrs */ \ + subl #60,%sp; /* space for 15 regs */ \ + moveml %d0-%d7/%a0-%a6,%sp@; \ + +#define RESTORE_ALL \ + moveml %sp@,%d0-%d7/%a0-%a6; \ + addl #60,%sp; /* space for 15 regs */ \ + rte + +/* If we come from a pre-loader we don't need an initial exception + * table. + */ +#if !defined(CONFIG_MONITOR_IS_IN_RAM) + +.text +/* + * Vector table. This is used for initial platform startup. + * These vectors are to catch any un-intended traps. + */ +_vectors: + +.long 0x00000000 /* Flash offset is 0 until we setup CS0 */ +#if defined(CONFIG_M5282) && (TEXT_BASE == CONFIG_SYS_INT_FLASH_BASE) +.long _start - TEXT_BASE +#else +.long _START +#endif + +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT + +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT + +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT + +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT + +#endif + + .text + + +#if defined(CONFIG_SYS_INT_FLASH_BASE) && \ + (defined(CONFIG_M5282) || defined(CONFIG_M5281)) + #if (TEXT_BASE == CONFIG_SYS_INT_FLASH_BASE) + .long 0x55AA55AA,0xAA55AA55 /* CFM Backdoorkey */ + .long 0xFFFFFFFF /* all sectors protected */ + .long 0x00000000 /* supervisor/User restriction */ + .long 0x00000000 /* programm/data space restriction */ + .long 0x00000000 /* Flash security */ + #endif +#endif + .globl _start +_start: + nop + nop + move.w #0x2700,%sr + +#if defined(CONFIG_M5208) + /* Initialize RAMBAR: locate SRAM and validate it */ + move.l #(CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_RAM_CTRL), %d0 + movec %d0, %RAMBAR1 +#endif + +#if defined(CONFIG_M5272) || defined(CONFIG_M5249) || defined(CONFIG_M5253) + move.l #(CONFIG_SYS_MBAR + 1), %d0 /* set MBAR address + valid flag */ + move.c %d0, %MBAR + + /*** The 5249 has MBAR2 as well ***/ +#ifdef CONFIG_SYS_MBAR2 + move.l #(CONFIG_SYS_MBAR2 + 1), %d0 /* Get MBAR2 address */ + movec %d0, #0xc0e /* Set MBAR2 */ +#endif + + move.l #(CONFIG_SYS_INIT_RAM_ADDR + 1), %d0 + movec %d0, %RAMBAR0 +#endif /* CONFIG_M5272 || CONFIG_M5249 || CONFIG_M5253 */ + +#if defined(CONFIG_M5282) || defined(CONFIG_M5271) + /* Initialize IPSBAR */ + move.l #(CONFIG_SYS_MBAR + 1), %d0 /* set IPSBAR address + valid flag */ + move.l %d0, 0x40000000 + + /* Initialize RAMBAR1: locate SRAM and validate it */ + move.l #(CONFIG_SYS_INIT_RAM_ADDR + 0x21), %d0 + movec %d0, %RAMBAR1 + +#if defined(CONFIG_M5282) +#if (TEXT_BASE == CONFIG_SYS_INT_FLASH_BASE) + /* Setup code in SRAM to initialize FLASHBAR, if start from internal Flash */ + + move.l #(_flashbar_setup-CONFIG_SYS_INT_FLASH_BASE), %a0 + move.l #(_flashbar_setup_end-CONFIG_SYS_INT_FLASH_BASE), %a1 + move.l #(CONFIG_SYS_INIT_RAM_ADDR), %a2 +_copy_flash: + move.l (%a0)+, (%a2)+ + cmp.l %a0, %a1 + bgt.s _copy_flash + jmp CONFIG_SYS_INIT_RAM_ADDR + +_flashbar_setup: + /* Initialize FLASHBAR: locate internal Flash and validate it */ + move.l #(CONFIG_SYS_INT_FLASH_BASE + CONFIG_SYS_INT_FLASH_ENABLE), %d0 + movec %d0, %FLASHBAR + jmp _after_flashbar_copy.L /* Force jump to absolute address */ +_flashbar_setup_end: + nop +_after_flashbar_copy: +#else + /* Setup code to initialize FLASHBAR, if start from external Memory */ + move.l #(CONFIG_SYS_INT_FLASH_BASE + CONFIG_SYS_INT_FLASH_ENABLE), %d0 + movec %d0, %FLASHBAR +#endif /* (TEXT_BASE == CONFIG_SYS_INT_FLASH_BASE) */ + +#endif +#endif + /* if we come from a pre-loader we have no exception table and + * therefore no VBR to set + */ +#if !defined(CONFIG_MONITOR_IS_IN_RAM) +#if defined(CONFIG_M5282) && (TEXT_BASE == CONFIG_SYS_INT_FLASH_BASE) + move.l #CONFIG_SYS_INT_FLASH_BASE, %d0 +#else + move.l #CONFIG_SYS_FLASH_BASE, %d0 +#endif + movec %d0, %VBR +#endif + +#ifdef CONFIG_M5275 + /* Initialize IPSBAR */ + move.l #(CONFIG_SYS_MBAR + 1), %d0 /* set IPSBAR address + valid flag */ + move.l %d0, 0x40000000 +/* movec %d0, %MBAR */ + + /* Initialize RAMBAR: locate SRAM and validate it */ + move.l #(CONFIG_SYS_INIT_RAM_ADDR + 0x21), %d0 + movec %d0, %RAMBAR1 +#endif + + /* initialize general use internal ram */ + move.l #0, %d0 + move.l #(ICACHE_STATUS), %a1 /* icache */ + move.l #(DCACHE_STATUS), %a2 /* icache */ + move.l %d0, (%a1) + move.l %d0, (%a2) + + /* set stackpointer to end of internal ram to get some stackspace for the first c-code */ + move.l #(CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_SP_OFFSET), %sp + clr.l %sp@- + + move.l #__got_start, %a5 /* put relocation table address to a5 */ + + bsr cpu_init_f /* run low-level CPU init code (from flash) */ + bsr board_init_f /* run low-level board init code (from flash) */ + + /* board_init_f() does not return */ + +/*------------------------------------------------------------------------------*/ + +/* + * void relocate_code (addr_sp, gd, addr_moni) + * + * This "function" does not return, instead it continues in RAM + * after relocating the monitor code. + * + * r3 = dest + * r4 = src + * r5 = length in bytes + * r6 = cachelinesize + */ + .globl relocate_code +relocate_code: + link.w %a6,#0 + move.l 8(%a6), %sp /* set new stack pointer */ + + move.l 12(%a6), %d0 /* Save copy of Global Data pointer */ + move.l 16(%a6), %a0 /* Save copy of Destination Address */ + + move.l #CONFIG_SYS_MONITOR_BASE, %a1 + move.l #__init_end, %a2 + move.l %a0, %a3 + /* copy the code to RAM */ +1: + move.l (%a1)+, (%a3)+ + cmp.l %a1,%a2 + bgt.s 1b + +/* + * We are done. Do not return, instead branch to second part of board + * initialization, now running from RAM. + */ + move.l %a0, %a1 + add.l #(in_ram - CONFIG_SYS_MONITOR_BASE), %a1 + jmp (%a1) + +in_ram: + +clear_bss: + /* + * Now clear BSS segment + */ + move.l %a0, %a1 + add.l #(_sbss - CONFIG_SYS_MONITOR_BASE),%a1 + move.l %a0, %d1 + add.l #(_ebss - CONFIG_SYS_MONITOR_BASE),%d1 +6: + clr.l (%a1)+ + cmp.l %a1,%d1 + bgt.s 6b + + /* + * fix got table in RAM + */ + move.l %a0, %a1 + add.l #(__got_start - CONFIG_SYS_MONITOR_BASE),%a1 + move.l %a1,%a5 /* * fix got pointer register a5 */ + + move.l %a0, %a2 + add.l #(__got_end - CONFIG_SYS_MONITOR_BASE),%a2 + +7: + move.l (%a1),%d1 + sub.l #_start,%d1 + add.l %a0,%d1 + move.l %d1,(%a1)+ + cmp.l %a2, %a1 + bne 7b + + /* calculate relative jump to board_init_r in ram */ + move.l %a0, %a1 + add.l #(board_init_r - CONFIG_SYS_MONITOR_BASE), %a1 + + /* set parameters for board_init_r */ + move.l %a0,-(%sp) /* dest_addr */ + move.l %d0,-(%sp) /* gd */ +#if defined(DEBUG) && (TEXT_BASE != CONFIG_SYS_INT_FLASH_BASE) && \ + defined(CONFIG_SYS_HALT_BEFOR_RAM_JUMP) + halt +#endif + jsr (%a1) + +/*------------------------------------------------------------------------------*/ +/* exception code */ + .globl _fault +_fault: + jmp _fault + + .globl _exc_handler +_exc_handler: + SAVE_ALL + movel %sp,%sp@- + bsr exc_handler + addql #4,%sp + RESTORE_ALL + + .globl _int_handler +_int_handler: + SAVE_ALL + movel %sp,%sp@- + bsr int_handler + addql #4,%sp + RESTORE_ALL + +/*------------------------------------------------------------------------------*/ + + .globl version_string +version_string: + .ascii U_BOOT_VERSION + .ascii " (", U_BOOT_DATE, " - ", U_BOOT_TIME, ")" + .ascii CONFIG_IDENT_STRING, "\0" + .align 4 diff --git a/arch/m68k/cpu/mcf532x/Makefile b/arch/m68k/cpu/mcf532x/Makefile new file mode 100644 index 0000000000..6790d90f27 --- /dev/null +++ b/arch/m68k/cpu/mcf532x/Makefile @@ -0,0 +1,48 @@ +# +# (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 + +# CFLAGS += -DET_DEBUG + +LIB = lib$(CPU).a + +START = +COBJS = cpu.o speed.o cpu_init.o interrupts.o + +SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) +START := $(addprefix $(obj),$(START)) + +all: $(obj).depend $(START) $(LIB) + +$(LIB): $(OBJS) + $(AR) $(ARFLAGS) $@ $(OBJS) + +######################################################################### + +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/arch/m68k/cpu/mcf532x/config.mk b/arch/m68k/cpu/mcf532x/config.mk new file mode 100644 index 0000000000..b783444ae8 --- /dev/null +++ b/arch/m68k/cpu/mcf532x/config.mk @@ -0,0 +1,43 @@ +# +# (C) Copyright 2003 Josef Baumgartner <josef.baumgartner@telex.de> +# +# (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-d7 -msep-data + +cfg=$(shell grep configs $(OBJTREE)/include/config.h | sed 's/.*<\(configs.*\)>/\1/') +is5301x:=$(shell grep CONFIG_MCF5301x $(TOPDIR)/include/$(cfg)) +is532x:=$(shell grep CONFIG_MCF532x $(TOPDIR)/include/$(cfg)) + +ifneq ($(findstring 4.1,$(shell $(CC) --version)),4.1) + +ifneq (,$(findstring CONFIG_MCF5301x,$(is5301x))) +PLATFORM_CPPFLAGS += -mcpu=53015 -fPIC +endif +ifneq (,$(findstring CONFIG_MCF532x,$(is532x))) +PLATFORM_CPPFLAGS += -mcpu=5329 -fPIC +endif + +else +PLATFORM_CPPFLAGS += -m5307 -fPIC +endif diff --git a/arch/m68k/cpu/mcf532x/cpu.c b/arch/m68k/cpu/mcf532x/cpu.c new file mode 100644 index 0000000000..331cc15da4 --- /dev/null +++ b/arch/m68k/cpu/mcf532x/cpu.c @@ -0,0 +1,165 @@ +/* + * + * (C) Copyright 2000-2003 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * Copyright (C) 2004-2008 Freescale Semiconductor, Inc. + * TsiChung Liew (Tsi-Chung.Liew@freescale.com) + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <watchdog.h> +#include <command.h> +#include <netdev.h> + +#include <asm/immap.h> + +DECLARE_GLOBAL_DATA_PTR; + +int do_reset(cmd_tbl_t * cmdtp, bd_t * bd, int flag, int argc, char *argv[]) +{ + volatile rcm_t *rcm = (rcm_t *) (MMAP_RCM); + + udelay(1000); + rcm->rcr |= RCM_RCR_SOFTRST; + + /* we don't return! */ + return 0; +}; + +int checkcpu(void) +{ + volatile ccm_t *ccm = (ccm_t *) MMAP_CCM; + u16 msk; + u16 id = 0; + u8 ver; + + puts("CPU: "); + msk = (ccm->cir >> 6); + ver = (ccm->cir & 0x003f); + switch (msk) { +#ifdef CONFIG_MCF5301x + case 0x78: + id = 53010; + break; + case 0x77: + id = 53012; + break; + case 0x76: + id = 53015; + break; + case 0x74: + id = 53011; + break; + case 0x73: + id = 53013; + break; +#endif +#ifdef CONFIG_MCF532x + case 0x54: + id = 5329; + break; + case 0x59: + id = 5328; + break; + case 0x61: + id = 5327; + break; + case 0x65: + id = 5373; + break; + case 0x68: + id = 53721; + break; + case 0x69: + id = 5372; + break; + case 0x6B: + id = 5372; + break; +#endif + } + + if (id) { + char buf1[32], buf2[32]; + + printf("Freescale MCF%d (Mask:%01x Version:%x)\n", id, msk, + ver); + printf(" CPU CLK %s MHz BUS CLK %s MHz\n", + strmhz(buf1, gd->cpu_clk), + strmhz(buf2, gd->bus_clk)); + } + + return 0; +}; + +#if defined(CONFIG_WATCHDOG) +/* Called by macro WATCHDOG_RESET */ +void watchdog_reset(void) +{ + volatile wdog_t *wdp = (wdog_t *) (MMAP_WDOG); + + wdp->sr = 0x5555; /* Count register */ + wdp->sr = 0xAAAA; /* Count register */ +} + +int watchdog_disable(void) +{ + volatile wdog_t *wdp = (wdog_t *) (MMAP_WDOG); + + /* UserManual, once the wdog is disabled, wdog cannot be re-enabled */ + wdp->cr |= WTM_WCR_HALTED; /* halted watchdog timer */ + + puts("WATCHDOG:disabled\n"); + return (0); +} + +int watchdog_init(void) +{ + volatile wdog_t *wdp = (wdog_t *) (MMAP_WDOG); + u32 wdog_module = 0; + + /* set timeout and enable watchdog */ + wdog_module = ((CONFIG_SYS_CLK / 1000) * CONFIG_WATCHDOG_TIMEOUT); +#ifdef CONFIG_M5329 + wdp->mr = (wdog_module / 8192); +#else + wdp->mr = (wdog_module / 4096); +#endif + + wdp->cr = WTM_WCR_EN; + puts("WATCHDOG:enabled\n"); + + return (0); +} +#endif /* CONFIG_WATCHDOG */ + +#if defined(CONFIG_MCFFEC) +/* Default initializations for MCFFEC controllers. To override, + * create a board-specific function called: + * int board_eth_init(bd_t *bis) + */ + +int cpu_eth_init(bd_t *bis) +{ + return mcffec_initialize(bis); +} +#endif diff --git a/arch/m68k/cpu/mcf532x/cpu_init.c b/arch/m68k/cpu/mcf532x/cpu_init.c new file mode 100644 index 0000000000..6f551b60c9 --- /dev/null +++ b/arch/m68k/cpu/mcf532x/cpu_init.c @@ -0,0 +1,350 @@ +/* + * + * (C) Copyright 2000-2003 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * (C) Copyright 2004-2008 Freescale Semiconductor, Inc. + * TsiChung Liew (Tsi-Chung.Liew@freescale.com) + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <watchdog.h> +#include <asm/immap.h> + +#if defined(CONFIG_CMD_NET) +#include <config.h> +#include <net.h> +#include <asm/fec.h> +#endif + +#ifdef CONFIG_MCF5301x +void cpu_init_f(void) +{ + volatile scm1_t *scm1 = (scm1_t *) MMAP_SCM1; + volatile gpio_t *gpio = (gpio_t *) MMAP_GPIO; + volatile fbcs_t *fbcs = (fbcs_t *) MMAP_FBCS; + + /* watchdog is enabled by default - disable the watchdog */ +#ifndef CONFIG_WATCHDOG + /*wdog->cr = 0; */ +#endif + + scm1->mpr = 0x77777777; + scm1->pacra = 0; + scm1->pacrb = 0; + scm1->pacrc = 0; + scm1->pacrd = 0; + scm1->pacre = 0; + scm1->pacrf = 0; + scm1->pacrg = 0; + +#if (defined(CONFIG_SYS_CS0_BASE) && defined(CONFIG_SYS_CS0_MASK) \ + && defined(CONFIG_SYS_CS0_CTRL)) + gpio->par_cs |= GPIO_PAR_CS0_CS0; + fbcs->csar0 = CONFIG_SYS_CS0_BASE; + fbcs->cscr0 = CONFIG_SYS_CS0_CTRL; + fbcs->csmr0 = CONFIG_SYS_CS0_MASK; +#endif + +#if (defined(CONFIG_SYS_CS1_BASE) && defined(CONFIG_SYS_CS1_MASK) \ + && defined(CONFIG_SYS_CS1_CTRL)) + gpio->par_cs |= GPIO_PAR_CS1_CS1; + fbcs->csar1 = CONFIG_SYS_CS1_BASE; + fbcs->cscr1 = CONFIG_SYS_CS1_CTRL; + fbcs->csmr1 = CONFIG_SYS_CS1_MASK; +#endif + +#if (defined(CONFIG_SYS_CS2_BASE) && defined(CONFIG_SYS_CS2_MASK) \ + && defined(CONFIG_SYS_CS2_CTRL)) + fbcs->csar2 = CONFIG_SYS_CS2_BASE; + fbcs->cscr2 = CONFIG_SYS_CS2_CTRL; + fbcs->csmr2 = CONFIG_SYS_CS2_MASK; +#endif + +#if (defined(CONFIG_SYS_CS3_BASE) && defined(CONFIG_SYS_CS3_MASK) \ + && defined(CONFIG_SYS_CS3_CTRL)) + fbcs->csar3 = CONFIG_SYS_CS3_BASE; + fbcs->cscr3 = CONFIG_SYS_CS3_CTRL; + fbcs->csmr3 = CONFIG_SYS_CS3_MASK; +#endif + +#if (defined(CONFIG_SYS_CS4_BASE) && defined(CONFIG_SYS_CS4_MASK) \ + && defined(CONFIG_SYS_CS4_CTRL)) + gpio->par_cs |= GPIO_PAR_CS4; + fbcs->csar4 = CONFIG_SYS_CS4_BASE; + fbcs->cscr4 = CONFIG_SYS_CS4_CTRL; + fbcs->csmr4 = CONFIG_SYS_CS4_MASK; +#endif + +#if (defined(CONFIG_SYS_CS5_BASE) && defined(CONFIG_SYS_CS5_MASK) \ + && defined(CONFIG_SYS_CS5_CTRL)) + gpio->par_cs |= GPIO_PAR_CS5; + fbcs->csar5 = CONFIG_SYS_CS5_BASE; + fbcs->cscr5 = CONFIG_SYS_CS5_CTRL; + fbcs->csmr5 = CONFIG_SYS_CS5_MASK; +#endif + +#ifdef CONFIG_FSL_I2C + gpio->par_feci2c = GPIO_PAR_FECI2C_SDA_SDA | GPIO_PAR_FECI2C_SCL_SCL; +#endif + + icache_enable(); +} + +/* initialize higher level parts of CPU like timers */ +int cpu_init_r(void) +{ +#ifdef CONFIG_MCFFEC + volatile ccm_t *ccm = (ccm_t *) MMAP_CCM; +#endif +#ifdef CONFIG_MCFRTC + volatile rtc_t *rtc = (rtc_t *) (CONFIG_SYS_MCFRTC_BASE); + volatile rtcex_t *rtcex = (rtcex_t *) & rtc->extended; + + rtcex->gocu = CONFIG_SYS_RTC_CNT; + rtcex->gocl = CONFIG_SYS_RTC_SETUP; + +#endif +#ifdef CONFIG_MCFFEC + if (CONFIG_SYS_FEC0_MIIBASE != CONFIG_SYS_FEC1_MIIBASE) + ccm->misccr |= CCM_MISCCR_FECM; + else + ccm->misccr &= ~CCM_MISCCR_FECM; +#endif + + return (0); +} + +void uart_port_conf(int port) +{ + volatile gpio_t *gpio = (gpio_t *) MMAP_GPIO; + + /* Setup Ports: */ + switch (port) { + case 0: + gpio->par_uart &= ~(GPIO_PAR_UART_U0TXD | GPIO_PAR_UART_U0RXD); + gpio->par_uart |= (GPIO_PAR_UART_U0TXD | GPIO_PAR_UART_U0RXD); + break; + case 1: +#ifdef CONFIG_SYS_UART1_ALT1_GPIO + gpio->par_simp1h &= + ~(GPIO_PAR_SIMP1H_DATA1_UNMASK | + GPIO_PAR_SIMP1H_VEN1_UNMASK); + gpio->par_simp1h |= + (GPIO_PAR_SIMP1H_DATA1_U1TXD | GPIO_PAR_SIMP1H_VEN1_U1RXD); +#elif defined(CONFIG_SYS_UART1_ALT2_GPIO) + gpio->par_ssih &= + ~(GPIO_PAR_SSIH_RXD_UNMASK | GPIO_PAR_SSIH_TXD_UNMASK); + gpio->par_ssih |= + (GPIO_PAR_SSIH_RXD_U1RXD | GPIO_PAR_SSIH_TXD_U1TXD); +#endif + break; + case 2: +#ifdef CONFIG_SYS_UART2_PRI_GPIO + gpio->par_uart |= (GPIO_PAR_UART_U2TXD | GPIO_PAR_UART_U2RXD); +#elif defined(CONFIG_SYS_UART2_ALT1_GPIO) + gpio->par_dspih &= + ~(GPIO_PAR_DSPIH_SIN_UNMASK | GPIO_PAR_DSPIH_SOUT_UNMASK); + gpio->par_dspih |= + (GPIO_PAR_DSPIH_SIN_U2RXD | GPIO_PAR_DSPIH_SOUT_U2TXD); +#elif defined(CONFIG_SYS_UART2_ALT2_GPIO) + gpio->par_feci2c &= + ~(GPIO_PAR_FECI2C_SDA_UNMASK | GPIO_PAR_FECI2C_SCL_UNMASK); + gpio->par_feci2c |= + (GPIO_PAR_FECI2C_SDA_U2TXD | GPIO_PAR_FECI2C_SCL_U2RXD); +#endif + break; + } +} + +#if defined(CONFIG_CMD_NET) +int fecpin_setclear(struct eth_device *dev, int setclear) +{ + volatile gpio_t *gpio = (gpio_t *) MMAP_GPIO; + struct fec_info_s *info = (struct fec_info_s *)dev->priv; + + if (setclear) { + if (info->iobase == CONFIG_SYS_FEC0_IOBASE) { + gpio->par_fec |= + GPIO_PAR_FEC0_7W_FEC | GPIO_PAR_FEC0_RMII_FEC; + gpio->par_feci2c |= + GPIO_PAR_FECI2C_MDC0 | GPIO_PAR_FECI2C_MDIO0; + } else { + gpio->par_fec |= + GPIO_PAR_FEC1_7W_FEC | GPIO_PAR_FEC1_RMII_FEC; + gpio->par_feci2c |= + GPIO_PAR_FECI2C_MDC1 | GPIO_PAR_FECI2C_MDIO1; + } + } else { + if (info->iobase == CONFIG_SYS_FEC0_IOBASE) { + gpio->par_fec &= + ~(GPIO_PAR_FEC0_7W_FEC | GPIO_PAR_FEC0_RMII_FEC); + gpio->par_feci2c &= GPIO_PAR_FECI2C_RMII0_UNMASK; + } else { + gpio->par_fec &= + ~(GPIO_PAR_FEC1_7W_FEC | GPIO_PAR_FEC1_RMII_FEC); + gpio->par_feci2c &= GPIO_PAR_FECI2C_RMII1_UNMASK; + } + } + return 0; +} +#endif /* CONFIG_CMD_NET */ +#endif /* CONFIG_MCF5301x */ + +#ifdef CONFIG_MCF532x +void cpu_init_f(void) +{ + volatile scm1_t *scm1 = (scm1_t *) MMAP_SCM1; + volatile scm2_t *scm2 = (scm2_t *) MMAP_SCM2; + volatile gpio_t *gpio = (gpio_t *) MMAP_GPIO; + volatile fbcs_t *fbcs = (fbcs_t *) MMAP_FBCS; + volatile wdog_t *wdog = (wdog_t *) MMAP_WDOG; + + /* watchdog is enabled by default - disable the watchdog */ +#ifndef CONFIG_WATCHDOG + wdog->cr = 0; +#endif + + scm1->mpr0 = 0x77777777; + scm2->pacra = 0; + scm2->pacrb = 0; + scm2->pacrc = 0; + scm2->pacrd = 0; + scm2->pacre = 0; + scm2->pacrf = 0; + scm2->pacrg = 0; + scm1->pacrh = 0; + + /* Port configuration */ + gpio->par_cs = 0; + +#if (defined(CONFIG_SYS_CS0_BASE) && defined(CONFIG_SYS_CS0_MASK) \ + && defined(CONFIG_SYS_CS0_CTRL)) + fbcs->csar0 = CONFIG_SYS_CS0_BASE; + fbcs->cscr0 = CONFIG_SYS_CS0_CTRL; + fbcs->csmr0 = CONFIG_SYS_CS0_MASK; +#endif + +#if (defined(CONFIG_SYS_CS1_BASE) && defined(CONFIG_SYS_CS1_MASK) \ + && defined(CONFIG_SYS_CS1_CTRL)) + /* Latch chipselect */ + gpio->par_cs |= GPIO_PAR_CS1; + fbcs->csar1 = CONFIG_SYS_CS1_BASE; + fbcs->cscr1 = CONFIG_SYS_CS1_CTRL; + fbcs->csmr1 = CONFIG_SYS_CS1_MASK; +#endif + +#if (defined(CONFIG_SYS_CS2_BASE) && defined(CONFIG_SYS_CS2_MASK) \ + && defined(CONFIG_SYS_CS2_CTRL)) + gpio->par_cs |= GPIO_PAR_CS2; + fbcs->csar2 = CONFIG_SYS_CS2_BASE; + fbcs->cscr2 = CONFIG_SYS_CS2_CTRL; + fbcs->csmr2 = CONFIG_SYS_CS2_MASK; +#endif + +#if (defined(CONFIG_SYS_CS3_BASE) && defined(CONFIG_SYS_CS3_MASK) \ + && defined(CONFIG_SYS_CS3_CTRL)) + gpio->par_cs |= GPIO_PAR_CS3; + fbcs->csar3 = CONFIG_SYS_CS3_BASE; + fbcs->cscr3 = CONFIG_SYS_CS3_CTRL; + fbcs->csmr3 = CONFIG_SYS_CS3_MASK; +#endif + +#if (defined(CONFIG_SYS_CS4_BASE) && defined(CONFIG_SYS_CS4_MASK) \ + && defined(CONFIG_SYS_CS4_CTRL)) + gpio->par_cs |= GPIO_PAR_CS4; + fbcs->csar4 = CONFIG_SYS_CS4_BASE; + fbcs->cscr4 = CONFIG_SYS_CS4_CTRL; + fbcs->csmr4 = CONFIG_SYS_CS4_MASK; +#endif + +#if (defined(CONFIG_SYS_CS5_BASE) && defined(CONFIG_SYS_CS5_MASK) \ + && defined(CONFIG_SYS_CS5_CTRL)) + gpio->par_cs |= GPIO_PAR_CS5; + fbcs->csar5 = CONFIG_SYS_CS5_BASE; + fbcs->cscr5 = CONFIG_SYS_CS5_CTRL; + fbcs->csmr5 = CONFIG_SYS_CS5_MASK; +#endif + +#ifdef CONFIG_FSL_I2C + gpio->par_feci2c = GPIO_PAR_FECI2C_SCL_SCL | GPIO_PAR_FECI2C_SDA_SDA; +#endif + + icache_enable(); +} + +/* + * initialize higher level parts of CPU like timers + */ +int cpu_init_r(void) +{ + return (0); +} + +void uart_port_conf(int port) +{ + volatile gpio_t *gpio = (gpio_t *) MMAP_GPIO; + + /* Setup Ports: */ + switch (port) { + case 0: + gpio->par_uart &= ~(GPIO_PAR_UART_TXD0 | GPIO_PAR_UART_RXD0); + gpio->par_uart |= (GPIO_PAR_UART_TXD0 | GPIO_PAR_UART_RXD0); + break; + case 1: + gpio->par_uart &= + ~(GPIO_PAR_UART_TXD1(3) | GPIO_PAR_UART_RXD1(3)); + gpio->par_uart |= + (GPIO_PAR_UART_TXD1(3) | GPIO_PAR_UART_RXD1(3)); + break; + case 2: +#ifdef CONFIG_SYS_UART2_ALT1_GPIO + gpio->par_timer &= 0x0F; + gpio->par_timer |= (GPIO_PAR_TIN3_URXD2 | GPIO_PAR_TIN2_UTXD2); +#elif defined(CONFIG_SYS_UART2_ALT2_GPIO) + gpio->par_feci2c &= 0xFF00; + gpio->par_feci2c |= (GPIO_PAR_FECI2C_SCL_UTXD2 | GPIO_PAR_FECI2C_SDA_URXD2); +#elif defined(CONFIG_SYS_UART2_ALT3_GPIO) + gpio->par_ssi &= 0xF0FF; + gpio->par_ssi |= (GPIO_PAR_SSI_RXD(2) | GPIO_PAR_SSI_TXD(2)); +#endif + break; + } +} + +#if defined(CONFIG_CMD_NET) +int fecpin_setclear(struct eth_device *dev, int setclear) +{ + volatile gpio_t *gpio = (gpio_t *) MMAP_GPIO; + + if (setclear) { + gpio->par_fec |= GPIO_PAR_FEC_7W_FEC | GPIO_PAR_FEC_MII_FEC; + gpio->par_feci2c |= + GPIO_PAR_FECI2C_MDC_EMDC | GPIO_PAR_FECI2C_MDIO_EMDIO; + } else { + gpio->par_fec &= ~(GPIO_PAR_FEC_7W_FEC | GPIO_PAR_FEC_MII_FEC); + gpio->par_feci2c &= + ~(GPIO_PAR_FECI2C_MDC_EMDC | GPIO_PAR_FECI2C_MDIO_EMDIO); + } + return 0; +} +#endif +#endif /* CONFIG_MCF532x */ diff --git a/arch/m68k/cpu/mcf532x/interrupts.c b/arch/m68k/cpu/mcf532x/interrupts.c new file mode 100644 index 0000000000..d6c8205454 --- /dev/null +++ b/arch/m68k/cpu/mcf532x/interrupts.c @@ -0,0 +1,49 @@ +/* + * + * Copyright (C) 2004-2007 Freescale Semiconductor, Inc. + * TsiChung Liew (Tsi-Chung.Liew@freescale.com) + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +/* CPU specific interrupt routine */ +#include <common.h> +#include <asm/immap.h> + +int interrupt_init(void) +{ + volatile int0_t *intp = (int0_t *) (CONFIG_SYS_INTR_BASE); + + /* Make sure all interrupts are disabled */ + intp->imrh0 |= 0xFFFFFFFF; + intp->imrl0 |= 0xFFFFFFFF; + + enable_interrupts(); + return 0; +} + +#if defined(CONFIG_MCFTMR) +void dtimer_intr_setup(void) +{ + volatile int0_t *intp = (int0_t *) (CONFIG_SYS_INTR_BASE); + + intp->icr0[CONFIG_SYS_TMRINTR_NO] = CONFIG_SYS_TMRINTR_PRI; + intp->imrh0 &= ~CONFIG_SYS_TMRINTR_MASK; +} +#endif diff --git a/arch/m68k/cpu/mcf532x/speed.c b/arch/m68k/cpu/mcf532x/speed.c new file mode 100644 index 0000000000..5a29e2567a --- /dev/null +++ b/arch/m68k/cpu/mcf532x/speed.c @@ -0,0 +1,275 @@ +/* + * + * (C) Copyright 2000-2003 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * Copyright (C) 2004-2008 Freescale Semiconductor, Inc. + * TsiChung Liew (Tsi-Chung.Liew@freescale.com) + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <asm/processor.h> + +#include <asm/immap.h> + +DECLARE_GLOBAL_DATA_PTR; + +/* PLL min/max specifications */ +#define MAX_FVCO 500000 /* KHz */ +#define MAX_FSYS 80000 /* KHz */ +#define MIN_FSYS 58333 /* KHz */ + +#ifdef CONFIG_MCF5301x +#define FREF 20000 /* KHz */ +#define MAX_MFD 63 /* Multiplier */ +#define MIN_MFD 0 /* Multiplier */ +#define USBDIV 8 + +/* Low Power Divider specifications */ +#define MIN_LPD (0) /* Divider (not encoded) */ +#define MAX_LPD (15) /* Divider (not encoded) */ +#define DEFAULT_LPD (0) /* Divider (not encoded) */ +#endif + +#ifdef CONFIG_MCF532x +#define FREF 16000 /* KHz */ +#define MAX_MFD 135 /* Multiplier */ +#define MIN_MFD 88 /* Multiplier */ + +/* Low Power Divider specifications */ +#define MIN_LPD (1 << 0) /* Divider (not encoded) */ +#define MAX_LPD (1 << 15) /* Divider (not encoded) */ +#define DEFAULT_LPD (1 << 1) /* Divider (not encoded) */ +#endif + +#define BUSDIV 6 /* Divider */ + +/* Get the value of the current system clock */ +int get_sys_clock(void) +{ + volatile ccm_t *ccm = (volatile ccm_t *)(MMAP_CCM); + volatile pll_t *pll = (volatile pll_t *)(MMAP_PLL); + int divider; + + /* Test to see if device is in LIMP mode */ + if (ccm->misccr & CCM_MISCCR_LIMP) { + divider = ccm->cdr & CCM_CDR_LPDIV(0xF); +#ifdef CONFIG_MCF5301x + return (FREF / (3 * (1 << divider))); +#endif +#ifdef CONFIG_MCF532x + return (FREF / (2 << divider)); +#endif + } else { +#ifdef CONFIG_MCF5301x + u32 pfdr = (pll->pcr & 0x3F) + 1; + u32 refdiv = (1 << ((pll->pcr & PLL_PCR_REFDIV(7)) >> 8)); + u32 busdiv = ((pll->pdr & 0x00F0) >> 4) + 1; + + return (((FREF * pfdr) / refdiv) / busdiv); +#endif +#ifdef CONFIG_MCF532x + return ((FREF * pll->pfdr) / (BUSDIV * 4)); +#endif + } +} + +/* + * Initialize the Low Power Divider circuit + * + * Parameters: + * div Desired system frequency divider + * + * Return Value: + * The resulting output system frequency + */ +int clock_limp(int div) +{ + volatile ccm_t *ccm = (volatile ccm_t *)(MMAP_CCM); + u32 temp; + + /* Check bounds of divider */ + if (div < MIN_LPD) + div = MIN_LPD; + if (div > MAX_LPD) + div = MAX_LPD; + + /* Save of the current value of the SSIDIV so we don't overwrite the value */ + temp = (ccm->cdr & CCM_CDR_SSIDIV(0xFF)); + + /* Apply the divider to the system clock */ + ccm->cdr = (CCM_CDR_LPDIV(div) | CCM_CDR_SSIDIV(temp)); + + ccm->misccr |= CCM_MISCCR_LIMP; + + return (FREF / (3 * (1 << div))); +} + +/* Exit low power LIMP mode */ +int clock_exit_limp(void) +{ + volatile ccm_t *ccm = (volatile ccm_t *)(MMAP_CCM); + int fout; + + /* Exit LIMP mode */ + ccm->misccr &= (~CCM_MISCCR_LIMP); + + /* Wait for PLL to lock */ + while (!(ccm->misccr & CCM_MISCCR_PLL_LOCK)) ; + + fout = get_sys_clock(); + + return fout; +} + +/* Initialize the PLL + * + * Parameters: + * fref PLL reference clock frequency in KHz + * fsys Desired PLL output frequency in KHz + * flags Operating parameters + * + * Return Value: + * The resulting output system frequency + */ +int clock_pll(int fsys, int flags) +{ +#ifdef CONFIG_MCF532x + volatile u32 *sdram_workaround = (volatile u32 *)(MMAP_SDRAM + 0x80); +#endif + volatile sdram_t *sdram = (volatile sdram_t *)(MMAP_SDRAM); + volatile pll_t *pll = (volatile pll_t *)(MMAP_PLL); + int fref, temp, fout, mfd; + u32 i; + + fref = FREF; + + if (fsys == 0) { + /* Return current PLL output */ +#ifdef CONFIG_MCF5301x + u32 busdiv = ((pll->pdr >> 4) & 0x0F) + 1; + mfd = (pll->pcr & 0x3F) + 1; + + return (fref * mfd) / busdiv; +#endif +#ifdef CONFIG_MCF532x + mfd = pll->pfdr; + + return (fref * mfd / (BUSDIV * 4)); +#endif + } + + /* Check bounds of requested system clock */ + if (fsys > MAX_FSYS) + fsys = MAX_FSYS; + + if (fsys < MIN_FSYS) + fsys = MIN_FSYS; + + /* + * Multiplying by 100 when calculating the temp value, + * and then dividing by 100 to calculate the mfd allows + * for exact values without needing to include floating + * point libraries. + */ + temp = (100 * fsys) / fref; +#ifdef CONFIG_MCF5301x + mfd = (BUSDIV * temp) / 100; + + /* Determine the output frequency for selected values */ + fout = ((fref * mfd) / BUSDIV); +#endif +#ifdef CONFIG_MCF532x + mfd = (4 * BUSDIV * temp) / 100; + + /* Determine the output frequency for selected values */ + fout = ((fref * mfd) / (BUSDIV * 4)); +#endif + +/* must not tamper with SDRAMC if running from SDRAM */ +#if !defined(CONFIG_MONITOR_IS_IN_RAM) + /* + * Check to see if the SDRAM has already been initialized. + * If it has then the SDRAM needs to be put into self refresh + * mode before reprogramming the PLL. + */ + if (sdram->ctrl & SDRAMC_SDCR_REF) + sdram->ctrl &= ~SDRAMC_SDCR_CKE; + + /* + * Initialize the PLL to generate the new system clock frequency. + * The device must be put into LIMP mode to reprogram the PLL. + */ + + /* Enter LIMP mode */ + clock_limp(DEFAULT_LPD); + +#ifdef CONFIG_MCF5301x + pll->pdr = + PLL_PDR_OUTDIV1((BUSDIV / 3) - 1) | + PLL_PDR_OUTDIV2(BUSDIV - 1) | + PLL_PDR_OUTDIV3((BUSDIV / 2) - 1) | + PLL_PDR_OUTDIV4(USBDIV - 1); + + pll->pcr &= PLL_PCR_FBDIV_UNMASK; + pll->pcr |= PLL_PCR_FBDIV(mfd - 1); +#endif +#ifdef CONFIG_MCF532x + /* Reprogram PLL for desired fsys */ + pll->podr = (PLL_PODR_CPUDIV(BUSDIV / 3) | PLL_PODR_BUSDIV(BUSDIV)); + + pll->pfdr = mfd; +#endif + + /* Exit LIMP mode */ + clock_exit_limp(); + + /* Return the SDRAM to normal operation if it is in use. */ + if (sdram->ctrl & SDRAMC_SDCR_REF) + sdram->ctrl |= SDRAMC_SDCR_CKE; + +#ifdef CONFIG_MCF532x + /* + * software workaround for SDRAM opeartion after exiting LIMP + * mode errata + */ + *sdram_workaround = CONFIG_SYS_SDRAM_BASE; +#endif + + /* wait for DQS logic to relock */ + for (i = 0; i < 0x200; i++) ; +#endif /* !defined(CONFIG_MONITOR_IS_IN_RAM) */ + + return fout; +} + +/* get_clocks() fills in gd->cpu_clock and gd->bus_clk */ +int get_clocks(void) +{ + gd->bus_clk = clock_pll(CONFIG_SYS_CLK / 1000, 0) * 1000; + gd->cpu_clk = (gd->bus_clk * 3); + +#ifdef CONFIG_FSL_I2C + gd->i2c1_clk = gd->bus_clk; +#endif + + return (0); +} diff --git a/arch/m68k/cpu/mcf532x/start.S b/arch/m68k/cpu/mcf532x/start.S new file mode 100644 index 0000000000..a80b0a9946 --- /dev/null +++ b/arch/m68k/cpu/mcf532x/start.S @@ -0,0 +1,288 @@ +/* + * Copyright (C) 2003 Josef Baumgartner <josef.baumgartner@telex.de> + * Based on code from Bernhard Kuhn <bkuhn@metrowerks.com> + * + * (C) Copyright 2004-2008 Freescale Semiconductor, Inc. + * TsiChung Liew (Tsi-Chung.Liew@freescale.com) + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <config.h> +#include <timestamp.h> +#include "version.h" +#include <asm/cache.h> + +#ifndef CONFIG_IDENT_STRING +#define CONFIG_IDENT_STRING "" +#endif + +#define _START _start +#define _FAULT _fault + +#define SAVE_ALL \ + move.w #0x2700,%sr; /* disable intrs */ \ + subl #60,%sp; /* space for 15 regs */ \ + moveml %d0-%d7/%a0-%a6,%sp@; + +#define RESTORE_ALL \ + moveml %sp@,%d0-%d7/%a0-%a6; \ + addl #60,%sp; /* space for 15 regs */ \ + rte; + +#if !defined(CONFIG_MONITOR_IS_IN_RAM) +.text +/* + * Vector table. This is used for initial platform startup. + * These vectors are to catch any un-intended traps. + */ +_vectors: + +INITSP: .long 0x00000000 /* Initial SP */ +INITPC: .long _START /* Initial PC */ +vector02: .long _FAULT /* Access Error */ +vector03: .long _FAULT /* Address Error */ +vector04: .long _FAULT /* Illegal Instruction */ +vector05: .long _FAULT /* Reserved */ +vector06: .long _FAULT /* Reserved */ +vector07: .long _FAULT /* Reserved */ +vector08: .long _FAULT /* Privilege Violation */ +vector09: .long _FAULT /* Trace */ +vector0A: .long _FAULT /* Unimplemented A-Line */ +vector0B: .long _FAULT /* Unimplemented F-Line */ +vector0C: .long _FAULT /* Debug Interrupt */ +vector0D: .long _FAULT /* Reserved */ +vector0E: .long _FAULT /* Format Error */ +vector0F: .long _FAULT /* Unitialized Int. */ + +/* Reserved */ +vector10_17: +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT + +vector18: .long _FAULT /* Spurious Interrupt */ +vector19: .long _FAULT /* Autovector Level 1 */ +vector1A: .long _FAULT /* Autovector Level 2 */ +vector1B: .long _FAULT /* Autovector Level 3 */ +vector1C: .long _FAULT /* Autovector Level 4 */ +vector1D: .long _FAULT /* Autovector Level 5 */ +vector1E: .long _FAULT /* Autovector Level 6 */ +vector1F: .long _FAULT /* Autovector Level 7 */ + +/* TRAP #0 - #15 */ +vector20_2F: +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT + +/* Reserved */ +vector30_3F: +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT + +vector64_127: +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT + +vector128_191: +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT + +vector192_255: +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +#endif /* !defined(CONFIG_MONITOR_IS_IN_RAM) */ + + .text + + .globl _start +_start: + nop + nop + move.w #0x2700,%sr /* Mask off Interrupt */ + +#if !defined(CONFIG_MONITOR_IS_IN_RAM) + /* Set vector base register at the beginning of the Flash */ + move.l #CONFIG_SYS_FLASH_BASE, %d0 + movec %d0, %VBR +#endif + + move.l #(CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_RAM_CTRL), %d0 + movec %d0, %RAMBAR1 + + /* invalidate and disable cache */ + move.l #CF_CACR_CINVA, %d0 /* Invalidate cache cmd */ + movec %d0, %CACR /* Invalidate cache */ + move.l #0, %d0 + movec %d0, %ACR0 + movec %d0, %ACR1 + +#ifdef CONFIG_MCF5301x + move.l #(0xFC0a0010), %a0 + move.w (%a0), %d0 + and.l %d0, 0xEFFF + + move.w %d0, (%a0) +#endif + + /* initialize general use internal ram */ + move.l #0, %d0 + move.l #(ICACHE_STATUS), %a1 /* icache */ + move.l #(DCACHE_STATUS), %a2 /* icache */ + move.l %d0, (%a1) + move.l %d0, (%a2) + + /* set stackpointer to end of internal ram to get some stackspace for the + first c-code */ + move.l #(CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_SP_OFFSET), %sp + clr.l %sp@- + + move.l #__got_start, %a5 /* put relocation table address to a5 */ + + bsr cpu_init_f /* run low-level CPU init code (from flash) */ + bsr board_init_f /* run low-level board init code (from flash) */ + + /* board_init_f() does not return */ + +/*------------------------------------------------------------------------------*/ + +/* + * void relocate_code (addr_sp, gd, addr_moni) + * + * This "function" does not return, instead it continues in RAM + * after relocating the monitor code. + * + * r3 = dest + * r4 = src + * r5 = length in bytes + * r6 = cachelinesize + */ + .globl relocate_code +relocate_code: + link.w %a6,#0 + move.l 8(%a6), %sp /* set new stack pointer */ + + move.l 12(%a6), %d0 /* Save copy of Global Data pointer */ + move.l 16(%a6), %a0 /* Save copy of Destination Address */ + + move.l #CONFIG_SYS_MONITOR_BASE, %a1 + move.l #__init_end, %a2 + move.l %a0, %a3 + + /* copy the code to RAM */ +1: + move.l (%a1)+, (%a3)+ + cmp.l %a1,%a2 + bgt.s 1b + +/* + * We are done. Do not return, instead branch to second part of board + * initialization, now running from RAM. + */ + move.l %a0, %a1 + add.l #(in_ram - CONFIG_SYS_MONITOR_BASE), %a1 + jmp (%a1) + +in_ram: + +clear_bss: + /* + * Now clear BSS segment + */ + move.l %a0, %a1 + add.l #(_sbss - CONFIG_SYS_MONITOR_BASE),%a1 + move.l %a0, %d1 + add.l #(_ebss - CONFIG_SYS_MONITOR_BASE),%d1 +6: + clr.l (%a1)+ + cmp.l %a1,%d1 + bgt.s 6b + + /* + * fix got table in RAM + */ + move.l %a0, %a1 + add.l #(__got_start - CONFIG_SYS_MONITOR_BASE),%a1 + move.l %a1,%a5 /* * fix got pointer register a5 */ + + move.l %a0, %a2 + add.l #(__got_end - CONFIG_SYS_MONITOR_BASE),%a2 + +7: + move.l (%a1),%d1 + sub.l #_start,%d1 + add.l %a0,%d1 + move.l %d1,(%a1)+ + cmp.l %a2, %a1 + bne 7b + + /* calculate relative jump to board_init_r in ram */ + move.l %a0, %a1 + add.l #(board_init_r - CONFIG_SYS_MONITOR_BASE), %a1 + + /* set parameters for board_init_r */ + move.l %a0,-(%sp) /* dest_addr */ + move.l %d0,-(%sp) /* gd */ + jsr (%a1) + +/*------------------------------------------------------------------------------*/ +/* exception code */ + .globl _fault +_fault: + jmp _fault + .globl _exc_handler + +_exc_handler: + SAVE_ALL + movel %sp,%sp@- + bsr exc_handler + addql #4,%sp + RESTORE_ALL + + .globl _int_handler +_int_handler: + SAVE_ALL + movel %sp,%sp@- + bsr int_handler + addql #4,%sp + RESTORE_ALL + +/*------------------------------------------------------------------------------*/ + .globl version_string +version_string: + .ascii U_BOOT_VERSION + .ascii " (", U_BOOT_DATE, " - ", U_BOOT_TIME, ")" + .ascii CONFIG_IDENT_STRING, "\0" + .align 4 diff --git a/arch/m68k/cpu/mcf5445x/Makefile b/arch/m68k/cpu/mcf5445x/Makefile new file mode 100644 index 0000000000..26ec29895e --- /dev/null +++ b/arch/m68k/cpu/mcf5445x/Makefile @@ -0,0 +1,48 @@ +# +# (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 + +# CFLAGS += -DET_DEBUG + +LIB = lib$(CPU).a + +START = start.o +COBJS = cpu.o speed.o cpu_init.o interrupts.o pci.o + +SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) +START := $(addprefix $(obj),$(START)) + +all: $(obj).depend $(START) $(LIB) + +$(LIB): $(OBJS) + $(AR) $(ARFLAGS) $@ $(OBJS) + +######################################################################### + +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/arch/m68k/cpu/mcf5445x/config.mk b/arch/m68k/cpu/mcf5445x/config.mk new file mode 100644 index 0000000000..b0b49f7b26 --- /dev/null +++ b/arch/m68k/cpu/mcf5445x/config.mk @@ -0,0 +1,37 @@ +# +# (C) Copyright 2003 Josef Baumgartner <josef.baumgartner@telex.de> +# +# (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-d7 -msep-data +ifneq ($(findstring 4.1,$(shell $(CC) --version)),4.1) +PLATFORM_CPPFLAGS += -mcpu=54455 -fPIC +else +PLATFORM_CPPFLAGS += -m5407 -fPIC +endif + +ifneq (,$(findstring -linux-,$(shell $(CC) --version))) +ifneq (,$(findstring GOT,$(shell $(LD) --help))) +PLATFORM_LDFLAGS += --got=single +endif +endif diff --git a/arch/m68k/cpu/mcf5445x/cpu.c b/arch/m68k/cpu/mcf5445x/cpu.c new file mode 100644 index 0000000000..6238bc020f --- /dev/null +++ b/arch/m68k/cpu/mcf5445x/cpu.c @@ -0,0 +1,112 @@ +/* + * + * (C) Copyright 2000-2003 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * Copyright (C) 2004-2007 Freescale Semiconductor, Inc. + * TsiChung Liew (Tsi-Chung.Liew@freescale.com) + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <watchdog.h> +#include <command.h> +#include <netdev.h> + +#include <asm/immap.h> + +DECLARE_GLOBAL_DATA_PTR; + +int do_reset(cmd_tbl_t * cmdtp, bd_t * bd, int flag, int argc, char *argv[]) +{ + volatile rcm_t *rcm = (rcm_t *) (MMAP_RCM); + udelay(1000); + rcm->rcr |= RCM_RCR_SOFTRST; + + /* we don't return! */ + return 0; +}; + +int checkcpu(void) +{ + volatile ccm_t *ccm = (ccm_t *) MMAP_CCM; + u16 msk; + u16 id = 0; + u8 ver; + + puts("CPU: "); + msk = (ccm->cir >> 6); + ver = (ccm->cir & 0x003f); + switch (msk) { + case 0x48: + id = 54455; + break; + case 0x49: + id = 54454; + break; + case 0x4a: + id = 54453; + break; + case 0x4b: + id = 54452; + break; + case 0x4d: + id = 54451; + break; + case 0x4f: + id = 54450; + break; + } + + if (id) { + char buf1[32], buf2[32], buf3[32]; + + printf("Freescale MCF%d (Mask:%01x Version:%x)\n", id, msk, + ver); + printf(" CPU CLK %s MHz BUS CLK %s MHz FLB CLK %s MHz\n", + strmhz(buf1, gd->cpu_clk), + strmhz(buf2, gd->bus_clk), + strmhz(buf3, gd->flb_clk)); +#ifdef CONFIG_PCI + printf(" PCI CLK %s MHz INP CLK %s MHz VCO CLK %s MHz\n", + strmhz(buf1, gd->pci_clk), + strmhz(buf2, gd->inp_clk), + strmhz(buf3, gd->vco_clk)); +#else + printf(" INP CLK %s MHz VCO CLK %s MHz\n", + strmhz(buf1, gd->inp_clk), + strmhz(buf2, gd->vco_clk)); +#endif + } + + return 0; +} + +#if defined(CONFIG_MCFFEC) +/* Default initializations for MCFFEC controllers. To override, + * create a board-specific function called: + * int board_eth_init(bd_t *bis) + */ + +int cpu_eth_init(bd_t *bis) +{ + return mcffec_initialize(bis); +} +#endif diff --git a/arch/m68k/cpu/mcf5445x/cpu_init.c b/arch/m68k/cpu/mcf5445x/cpu_init.c new file mode 100644 index 0000000000..8d51d35d68 --- /dev/null +++ b/arch/m68k/cpu/mcf5445x/cpu_init.c @@ -0,0 +1,272 @@ +/* + * + * (C) Copyright 2000-2003 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * (C) Copyright 2004-2007 Freescale Semiconductor, Inc. + * TsiChung Liew (Tsi-Chung.Liew@freescale.com) + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <watchdog.h> +#include <asm/immap.h> +#include <asm/processor.h> +#include <asm/rtc.h> + +#if defined(CONFIG_CMD_NET) +#include <config.h> +#include <net.h> +#include <asm/fec.h> +#endif + +/* + * Breath some life into the CPU... + * + * Set up the memory map, + * initialize a bunch of registers, + * initialize the UPM's + */ +void cpu_init_f(void) +{ + volatile scm1_t *scm1 = (scm1_t *) MMAP_SCM1; + volatile gpio_t *gpio = (gpio_t *) MMAP_GPIO; + volatile fbcs_t *fbcs = (fbcs_t *) MMAP_FBCS; + + scm1->mpr = 0x77777777; + scm1->pacra = 0; + scm1->pacrb = 0; + scm1->pacrc = 0; + scm1->pacrd = 0; + scm1->pacre = 0; + scm1->pacrf = 0; + scm1->pacrg = 0; + + /* FlexBus */ + gpio->par_be = + GPIO_PAR_BE_BE3_BE3 | GPIO_PAR_BE_BE2_BE2 | GPIO_PAR_BE_BE1_BE1 | + GPIO_PAR_BE_BE0_BE0; + gpio->par_fbctl = + GPIO_PAR_FBCTL_OE | GPIO_PAR_FBCTL_TA_TA | GPIO_PAR_FBCTL_RW_RW | + GPIO_PAR_FBCTL_TS_TS; + +#if !defined(CONFIG_CF_SBF) +#if (defined(CONFIG_SYS_CS0_BASE) && defined(CONFIG_SYS_CS0_MASK) && defined(CONFIG_SYS_CS0_CTRL)) + fbcs->csar0 = CONFIG_SYS_CS0_BASE; + fbcs->cscr0 = CONFIG_SYS_CS0_CTRL; + fbcs->csmr0 = CONFIG_SYS_CS0_MASK; +#endif +#endif + +#if (defined(CONFIG_SYS_CS1_BASE) && defined(CONFIG_SYS_CS1_MASK) && defined(CONFIG_SYS_CS1_CTRL)) + /* Latch chipselect */ + fbcs->csar1 = CONFIG_SYS_CS1_BASE; + fbcs->cscr1 = CONFIG_SYS_CS1_CTRL; + fbcs->csmr1 = CONFIG_SYS_CS1_MASK; +#endif + +#if (defined(CONFIG_SYS_CS2_BASE) && defined(CONFIG_SYS_CS2_MASK) && defined(CONFIG_SYS_CS2_CTRL)) + fbcs->csar2 = CONFIG_SYS_CS2_BASE; + fbcs->cscr2 = CONFIG_SYS_CS2_CTRL; + fbcs->csmr2 = CONFIG_SYS_CS2_MASK; +#endif + +#if (defined(CONFIG_SYS_CS3_BASE) && defined(CONFIG_SYS_CS3_MASK) && defined(CONFIG_SYS_CS3_CTRL)) + fbcs->csar3 = CONFIG_SYS_CS3_BASE; + fbcs->cscr3 = CONFIG_SYS_CS3_CTRL; + fbcs->csmr3 = CONFIG_SYS_CS3_MASK; +#endif + +#if (defined(CONFIG_SYS_CS4_BASE) && defined(CONFIG_SYS_CS4_MASK) && defined(CONFIG_SYS_CS4_CTRL)) + fbcs->csar4 = CONFIG_SYS_CS4_BASE; + fbcs->cscr4 = CONFIG_SYS_CS4_CTRL; + fbcs->csmr4 = CONFIG_SYS_CS4_MASK; +#endif + +#if (defined(CONFIG_SYS_CS5_BASE) && defined(CONFIG_SYS_CS5_MASK) && defined(CONFIG_SYS_CS5_CTRL)) + fbcs->csar5 = CONFIG_SYS_CS5_BASE; + fbcs->cscr5 = CONFIG_SYS_CS5_CTRL; + fbcs->csmr5 = CONFIG_SYS_CS5_MASK; +#endif + + /* + * now the flash base address is no longer at 0 (Newer ColdFire family + * boot at address 0 instead of 0xFFnn_nnnn). The vector table must + * also move to the new location. + */ + if (CONFIG_SYS_CS0_BASE != 0) + setvbr(CONFIG_SYS_CS0_BASE); + +#ifdef CONFIG_FSL_I2C + gpio->par_feci2c = GPIO_PAR_FECI2C_SCL_SCL | GPIO_PAR_FECI2C_SDA_SDA; +#endif + + icache_enable(); +} + +/* + * initialize higher level parts of CPU like timers + */ +int cpu_init_r(void) +{ +#ifdef CONFIG_MCFRTC + volatile rtc_t *rtc = (volatile rtc_t *)(CONFIG_SYS_MCFRTC_BASE); + volatile rtcex_t *rtcex = (volatile rtcex_t *)&rtc->extended; + + rtcex->gocu = (CONFIG_SYS_RTC_OSCILLATOR >> 16) & 0xFFFF; + rtcex->gocl = CONFIG_SYS_RTC_OSCILLATOR & 0xFFFF; +#endif + + return (0); +} + +void uart_port_conf(int port) +{ + volatile gpio_t *gpio = (gpio_t *) MMAP_GPIO; + + /* Setup Ports: */ + switch (port) { + case 0: + gpio->par_uart &= + ~(GPIO_PAR_UART_U0TXD_U0TXD | GPIO_PAR_UART_U0RXD_U0RXD); + gpio->par_uart |= + (GPIO_PAR_UART_U0TXD_U0TXD | GPIO_PAR_UART_U0RXD_U0RXD); + break; + case 1: +#ifdef CONFIG_SYS_UART1_PRI_GPIO + gpio->par_uart &= + ~(GPIO_PAR_UART_U1TXD_U1TXD | GPIO_PAR_UART_U1RXD_U1RXD); + gpio->par_uart |= + (GPIO_PAR_UART_U1TXD_U1TXD | GPIO_PAR_UART_U1RXD_U1RXD); +#elif defined(CONFIG_SYS_UART1_ALT1_GPIO) + gpio->par_ssi &= + (GPIO_PAR_SSI_SRXD_UNMASK | GPIO_PAR_SSI_STXD_UNMASK); + gpio->par_ssi |= + (GPIO_PAR_SSI_SRXD_U1RXD | GPIO_PAR_SSI_STXD_U1TXD); +#endif + break; + case 2: +#if defined(CONFIG_SYS_UART2_ALT1_GPIO) + gpio->par_timer &= + (GPIO_PAR_TIMER_T3IN_UNMASK | GPIO_PAR_TIMER_T2IN_UNMASK); + gpio->par_timer |= + (GPIO_PAR_TIMER_T3IN_U2RXD | GPIO_PAR_TIMER_T2IN_U2TXD); +#elif defined(CONFIG_SYS_UART2_ALT2_GPIO) + gpio->par_timer &= + (GPIO_PAR_FECI2C_SCL_UNMASK | GPIO_PAR_FECI2C_SDA_UNMASK); + gpio->par_timer |= + (GPIO_PAR_FECI2C_SCL_U2TXD | GPIO_PAR_FECI2C_SDA_U2RXD); +#endif + break; + } +} + +#if defined(CONFIG_CMD_NET) +int fecpin_setclear(struct eth_device *dev, int setclear) +{ + volatile gpio_t *gpio = (gpio_t *) MMAP_GPIO; + struct fec_info_s *info = (struct fec_info_s *)dev->priv; + + if (setclear) { + gpio->par_feci2c |= + (GPIO_PAR_FECI2C_MDC0_MDC0 | GPIO_PAR_FECI2C_MDIO0_MDIO0); + + if (info->iobase == CONFIG_SYS_FEC0_IOBASE) + gpio->par_fec |= GPIO_PAR_FEC_FEC0_RMII_GPIO; + else + gpio->par_fec |= GPIO_PAR_FEC_FEC1_RMII_ATA; + } else { + gpio->par_feci2c &= + ~(GPIO_PAR_FECI2C_MDC0_MDC0 | GPIO_PAR_FECI2C_MDIO0_MDIO0); + + if (info->iobase == CONFIG_SYS_FEC0_IOBASE) + gpio->par_fec &= GPIO_PAR_FEC_FEC0_UNMASK; + else + gpio->par_fec &= GPIO_PAR_FEC_FEC1_UNMASK; + } + return 0; +} +#endif + +#ifdef CONFIG_CF_DSPI +void cfspi_port_conf(void) +{ + volatile gpio_t *gpio = (gpio_t *) MMAP_GPIO; + + gpio->par_dspi = GPIO_PAR_DSPI_SIN_SIN | GPIO_PAR_DSPI_SOUT_SOUT | + GPIO_PAR_DSPI_SCK_SCK; +} + +int cfspi_claim_bus(uint bus, uint cs) +{ + volatile dspi_t *dspi = (dspi_t *) MMAP_DSPI; + volatile gpio_t *gpio = (gpio_t *) MMAP_GPIO; + + if ((dspi->sr & DSPI_SR_TXRXS) != DSPI_SR_TXRXS) + return -1; + + /* Clear FIFO and resume transfer */ + dspi->mcr &= ~(DSPI_MCR_CTXF | DSPI_MCR_CRXF); + + switch (cs) { + case 0: + gpio->par_dspi &= ~GPIO_PAR_DSPI_PCS0_PCS0; + gpio->par_dspi |= GPIO_PAR_DSPI_PCS0_PCS0; + break; + case 1: + gpio->par_dspi &= ~GPIO_PAR_DSPI_PCS1_PCS1; + gpio->par_dspi |= GPIO_PAR_DSPI_PCS1_PCS1; + break; + case 2: + gpio->par_dspi &= ~GPIO_PAR_DSPI_PCS2_PCS2; + gpio->par_dspi |= GPIO_PAR_DSPI_PCS2_PCS2; + break; + case 5: + gpio->par_dspi &= ~GPIO_PAR_DSPI_PCS5_PCS5; + gpio->par_dspi |= GPIO_PAR_DSPI_PCS5_PCS5; + break; + } + + return 0; +} + +void cfspi_release_bus(uint bus, uint cs) +{ + volatile dspi_t *dspi = (dspi_t *) MMAP_DSPI; + volatile gpio_t *gpio = (gpio_t *) MMAP_GPIO; + + dspi->mcr &= ~(DSPI_MCR_CTXF | DSPI_MCR_CRXF); /* Clear FIFO */ + + switch (cs) { + case 0: + gpio->par_dspi &= ~GPIO_PAR_DSPI_PCS0_PCS0; + break; + case 1: + gpio->par_dspi &= ~GPIO_PAR_DSPI_PCS1_PCS1; + break; + case 2: + gpio->par_dspi &= ~GPIO_PAR_DSPI_PCS2_PCS2; + break; + case 5: + gpio->par_dspi &= ~GPIO_PAR_DSPI_PCS5_PCS5; + break; + } +} +#endif diff --git a/arch/m68k/cpu/mcf5445x/interrupts.c b/arch/m68k/cpu/mcf5445x/interrupts.c new file mode 100644 index 0000000000..85828a67b5 --- /dev/null +++ b/arch/m68k/cpu/mcf5445x/interrupts.c @@ -0,0 +1,52 @@ +/* + * + * (C) Copyright 2000-2004 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * Copyright (C) 2004-2007 Freescale Semiconductor, Inc. + * TsiChung Liew (Tsi-Chung.Liew@freescale.com) + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +/* CPU specific interrupt routine */ +#include <common.h> +#include <asm/immap.h> + +int interrupt_init(void) +{ + volatile int0_t *intp = (int0_t *) (CONFIG_SYS_INTR_BASE); + + /* Make sure all interrupts are disabled */ + intp->imrh0 |= 0xFFFFFFFF; + intp->imrl0 |= 0xFFFFFFFF; + + enable_interrupts(); + return 0; +} + +#if defined(CONFIG_MCFTMR) +void dtimer_intr_setup(void) +{ + volatile int0_t *intp = (int0_t *) (CONFIG_SYS_INTR_BASE); + + intp->icr0[CONFIG_SYS_TMRINTR_NO] = CONFIG_SYS_TMRINTR_PRI; + intp->imrh0 &= ~CONFIG_SYS_TMRINTR_MASK; +} +#endif diff --git a/arch/m68k/cpu/mcf5445x/pci.c b/arch/m68k/cpu/mcf5445x/pci.c new file mode 100644 index 0000000000..7f9784c3cb --- /dev/null +++ b/arch/m68k/cpu/mcf5445x/pci.c @@ -0,0 +1,164 @@ +/* + * Copyright (C) 2004-2007 Freescale Semiconductor, Inc. + * TsiChung Liew (Tsi-Chung.Liew@freescale.com) + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +/* + * PCI Configuration space access support + */ +#include <common.h> +#include <pci.h> +#include <asm/io.h> +#include <asm/immap.h> + +#if defined(CONFIG_PCI) +/* System RAM mapped over PCI */ +#define CONFIG_SYS_PCI_SYS_MEM_BUS CONFIG_SYS_SDRAM_BASE +#define CONFIG_SYS_PCI_SYS_MEM_PHYS CONFIG_SYS_SDRAM_BASE +#define CONFIG_SYS_PCI_SYS_MEM_SIZE (1024 * 1024 * 1024) + +#define cfg_read(val, addr, type, op) *val = op((type)(addr)); +#define cfg_write(val, addr, type, op) op((type *)(addr), (val)); + +#define PCI_OP(rw, size, type, op, mask) \ +int pci_##rw##_cfg_##size(struct pci_controller *hose, \ + pci_dev_t dev, int offset, type val) \ +{ \ + u32 addr = 0; \ + u16 cfg_type = 0; \ + addr = ((offset & 0xfc) | cfg_type | (dev) | 0x80000000); \ + out_be32(hose->cfg_addr, addr); \ + cfg_##rw(val, hose->cfg_data + (offset & mask), type, op); \ + out_be32(hose->cfg_addr, addr & 0x7fffffff); \ + return 0; \ +} + +PCI_OP(read, byte, u8 *, in_8, 3) +PCI_OP(read, word, u16 *, in_le16, 2) +PCI_OP(read, dword, u32 *, in_le32, 0) +PCI_OP(write, byte, u8, out_8, 3) +PCI_OP(write, word, u16, out_le16, 2) +PCI_OP(write, dword, u32, out_le32, 0) + +void pci_mcf5445x_init(struct pci_controller *hose) +{ + volatile pci_t *pci = (volatile pci_t *)MMAP_PCI; + volatile pciarb_t *pciarb = (volatile pciarb_t *)MMAP_PCIARB; + volatile gpio_t *gpio = (gpio_t *) MMAP_GPIO; + u32 barEn = 0; + + pciarb->acr = 0x001F001F; + + /* Set PCIGNT1, PCIREQ1, PCIREQ0/PCIGNTIN, PCIGNT0/PCIREQOUT, + PCIREQ2, PCIGNT2 */ + gpio->par_pci = + GPIO_PAR_PCI_GNT3_GNT3 | GPIO_PAR_PCI_GNT2 | GPIO_PAR_PCI_GNT1 | + GPIO_PAR_PCI_GNT0 | GPIO_PAR_PCI_REQ3_REQ3 | GPIO_PAR_PCI_REQ2 | + GPIO_PAR_PCI_REQ1 | GPIO_PAR_PCI_REQ0; + + /* Assert reset bit */ + pci->gscr |= PCI_GSCR_PR; + + pci->tcr1 |= PCI_TCR1_P; + + /* Initiator windows */ + pci->iw0btar = CONFIG_SYS_PCI_MEM_PHYS | (CONFIG_SYS_PCI_MEM_PHYS >> 16); + pci->iw1btar = CONFIG_SYS_PCI_IO_PHYS | (CONFIG_SYS_PCI_IO_PHYS >> 16); + pci->iw2btar = CONFIG_SYS_PCI_CFG_PHYS | (CONFIG_SYS_PCI_CFG_PHYS >> 16); + + pci->iwcr = + PCI_IWCR_W0C_EN | PCI_IWCR_W1C_EN | PCI_IWCR_W1C_IO | + PCI_IWCR_W2C_EN | PCI_IWCR_W2C_IO; + + pci->icr = 0; + + /* Enable bus master and mem access */ + pci->scr = PCI_SCR_B | PCI_SCR_M; + + /* Cache line size and master latency */ + pci->cr1 = PCI_CR1_CLS(8) | PCI_CR1_LTMR(0xF8); + pci->cr2 = 0; + +#ifdef CONFIG_SYS_PCI_BAR0 + pci->bar0 = PCI_BAR_BAR0(CONFIG_SYS_PCI_BAR0); + pci->tbatr0 = CONFIG_SYS_PCI_TBATR0 | PCI_TBATR_EN; + barEn |= PCI_TCR2_B0E; +#endif +#ifdef CONFIG_SYS_PCI_BAR1 + pci->bar1 = PCI_BAR_BAR1(CONFIG_SYS_PCI_BAR1); + pci->tbatr1 = CONFIG_SYS_PCI_TBATR1 | PCI_TBATR_EN; + barEn |= PCI_TCR2_B1E; +#endif +#ifdef CONFIG_SYS_PCI_BAR2 + pci->bar2 = PCI_BAR_BAR2(CONFIG_SYS_PCI_BAR2); + pci->tbatr2 = CONFIG_SYS_PCI_TBATR2 | PCI_TBATR_EN; + barEn |= PCI_TCR2_B2E; +#endif +#ifdef CONFIG_SYS_PCI_BAR3 + pci->bar3 = PCI_BAR_BAR3(CONFIG_SYS_PCI_BAR3); + pci->tbatr3 = CONFIG_SYS_PCI_TBATR3 | PCI_TBATR_EN; + barEn |= PCI_TCR2_B3E; +#endif +#ifdef CONFIG_SYS_PCI_BAR4 + pci->bar4 = PCI_BAR_BAR4(CONFIG_SYS_PCI_BAR4); + pci->tbatr4 = CONFIG_SYS_PCI_TBATR4 | PCI_TBATR_EN; + barEn |= PCI_TCR2_B4E; +#endif +#ifdef CONFIG_SYS_PCI_BAR5 + pci->bar5 = PCI_BAR_BAR5(CONFIG_SYS_PCI_BAR5); + pci->tbatr5 = CONFIG_SYS_PCI_TBATR5 | PCI_TBATR_EN; + barEn |= PCI_TCR2_B5E; +#endif + + pci->tcr2 = barEn; + + /* Deassert reset bit */ + pci->gscr &= ~PCI_GSCR_PR; + udelay(1000); + + /* Enable PCI bus master support */ + hose->first_busno = 0; + hose->last_busno = 0xff; + + pci_set_region(hose->regions + 0, CONFIG_SYS_PCI_MEM_BUS, CONFIG_SYS_PCI_MEM_PHYS, + CONFIG_SYS_PCI_MEM_SIZE, PCI_REGION_MEM); + + pci_set_region(hose->regions + 1, CONFIG_SYS_PCI_IO_BUS, CONFIG_SYS_PCI_IO_PHYS, + CONFIG_SYS_PCI_IO_SIZE, PCI_REGION_IO); + + pci_set_region(hose->regions + 2, CONFIG_SYS_PCI_SYS_MEM_BUS, + CONFIG_SYS_PCI_SYS_MEM_PHYS, CONFIG_SYS_PCI_SYS_MEM_SIZE, + PCI_REGION_MEM | PCI_REGION_SYS_MEMORY); + + hose->region_count = 3; + + hose->cfg_addr = &(pci->car); + hose->cfg_data = (volatile unsigned char *)CONFIG_SYS_PCI_CFG_BUS; + + pci_set_ops(hose, pci_read_cfg_byte, pci_read_cfg_word, + pci_read_cfg_dword, pci_write_cfg_byte, pci_write_cfg_word, + pci_write_cfg_dword); + + /* Hose scan */ + pci_register_hose(hose); + hose->last_busno = pci_hose_scan(hose); +} +#endif /* CONFIG_PCI */ diff --git a/arch/m68k/cpu/mcf5445x/speed.c b/arch/m68k/cpu/mcf5445x/speed.c new file mode 100644 index 0000000000..9c0c07733b --- /dev/null +++ b/arch/m68k/cpu/mcf5445x/speed.c @@ -0,0 +1,217 @@ +/* + * + * Copyright (C) 2004-2007 Freescale Semiconductor, Inc. + * TsiChung Liew (Tsi-Chung.Liew@freescale.com) + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <asm/processor.h> + +#include <asm/immap.h> + +DECLARE_GLOBAL_DATA_PTR; + +/* + * Low Power Divider specifications + */ +#define CLOCK_LPD_MIN (1 << 0) /* Divider (decoded) */ +#define CLOCK_LPD_MAX (1 << 15) /* Divider (decoded) */ + +#define CLOCK_PLL_FVCO_MAX 540000000 +#define CLOCK_PLL_FVCO_MIN 300000000 + +#define CLOCK_PLL_FSYS_MAX 266666666 +#define CLOCK_PLL_FSYS_MIN 100000000 +#define MHZ 1000000 + +void clock_enter_limp(int lpdiv) +{ + volatile ccm_t *ccm = (volatile ccm_t *)MMAP_CCM; + int i, j; + + /* Check bounds of divider */ + if (lpdiv < CLOCK_LPD_MIN) + lpdiv = CLOCK_LPD_MIN; + if (lpdiv > CLOCK_LPD_MAX) + lpdiv = CLOCK_LPD_MAX; + + /* Round divider down to nearest power of two */ + for (i = 0, j = lpdiv; j != 1; j >>= 1, i++) ; + + /* Apply the divider to the system clock */ + ccm->cdr = (ccm->cdr & 0xF0FF) | CCM_CDR_LPDIV(i); + + /* Enable Limp Mode */ + ccm->misccr |= CCM_MISCCR_LIMP; +} + +/* + * brief Exit Limp mode + * warning The PLL should be set and locked prior to exiting Limp mode + */ +void clock_exit_limp(void) +{ + volatile ccm_t *ccm = (volatile ccm_t *)MMAP_CCM; + volatile pll_t *pll = (volatile pll_t *)MMAP_PLL; + + /* Exit Limp mode */ + ccm->misccr &= ~CCM_MISCCR_LIMP; + + /* Wait for the PLL to lock */ + while (!(pll->psr & PLL_PSR_LOCK)) ; +} + +/* + * get_clocks() fills in gd->cpu_clock and gd->bus_clk + */ +int get_clocks(void) +{ + + volatile ccm_t *ccm = (volatile ccm_t *)MMAP_CCM; + volatile pll_t *pll = (volatile pll_t *)MMAP_PLL; + int pllmult_nopci[] = { 20, 10, 24, 18, 12, 6, 16, 8 }; + int pllmult_pci[] = { 12, 6, 16, 8 }; + int vco = 0, bPci, temp, fbtemp, pcrvalue; + int *pPllmult = NULL; + u16 fbpll_mask; + +#ifdef CONFIG_M54455EVB + volatile u8 *cpld = (volatile u8 *)(CONFIG_SYS_CS2_BASE + 3); +#endif + u8 bootmode; + + /* To determine PCI is present or not */ + if (((ccm->ccr & CCM_CCR_360_FBCONFIG_MASK) == 0x00e0) || + ((ccm->ccr & CCM_CCR_360_FBCONFIG_MASK) == 0x0060)) { + pPllmult = &pllmult_pci[0]; + fbpll_mask = 3; /* 11b */ + bPci = 1; + } else { + pPllmult = &pllmult_nopci[0]; + fbpll_mask = 7; /* 111b */ +#ifdef CONFIG_PCI + gd->pci_clk = 0; +#endif + bPci = 0; + } + +#ifdef CONFIG_M54455EVB + bootmode = (*cpld & 0x03); + + if (bootmode != 3) { + /* Temporary read from CCR- fixed fb issue, must be the same clock + as pci or input clock, causing cpld/fpga read inconsistancy */ + fbtemp = pPllmult[ccm->ccr & fbpll_mask]; + + /* Break down into small pieces, code still in flex bus */ + pcrvalue = pll->pcr & 0xFFFFF0FF; + temp = fbtemp - 1; + pcrvalue |= PLL_PCR_OUTDIV3(temp); + + pll->pcr = pcrvalue; + } +#endif +#ifdef CONFIG_M54451EVB + /* No external logic to read the bootmode, hard coded from built */ +#ifdef CONFIG_CF_SBF + bootmode = 3; +#else + bootmode = 2; + + /* default value is 16 mul, set to 20 mul */ + pcrvalue = (pll->pcr & 0x00FFFFFF) | 0x14000000; + pll->pcr = pcrvalue; + while ((pll->psr & PLL_PSR_LOCK) != PLL_PSR_LOCK); +#endif +#endif + + if (bootmode == 0) { + /* RCON mode */ + vco = pPllmult[ccm->rcon & fbpll_mask] * CONFIG_SYS_INPUT_CLKSRC; + + if ((vco < CLOCK_PLL_FVCO_MIN) || (vco > CLOCK_PLL_FVCO_MAX)) { + /* invaild range, re-set in PCR */ + int temp = ((pll->pcr & PLL_PCR_OUTDIV2_MASK) >> 4) + 1; + int i, j, bus; + + j = (pll->pcr & 0xFF000000) >> 24; + for (i = j; i < 0xFF; i++) { + vco = i * CONFIG_SYS_INPUT_CLKSRC; + if (vco >= CLOCK_PLL_FVCO_MIN) { + bus = vco / temp; + if (bus <= CLOCK_PLL_FSYS_MIN - MHZ) + continue; + else + break; + } + } + pcrvalue = pll->pcr & 0x00FF00FF; + fbtemp = ((i - 1) << 8) | ((i - 1) << 12); + pcrvalue |= ((i << 24) | fbtemp); + + pll->pcr = pcrvalue; + } + gd->vco_clk = vco; /* Vco clock */ + } else if (bootmode == 2) { + /* Normal mode */ + vco = ((pll->pcr & 0xFF000000) >> 24) * CONFIG_SYS_INPUT_CLKSRC; + if ((vco < CLOCK_PLL_FVCO_MIN) || (vco > CLOCK_PLL_FVCO_MAX)) { + /* Default value */ + pcrvalue = (pll->pcr & 0x00FFFFFF); + pcrvalue |= pPllmult[ccm->ccr & fbpll_mask] << 24; + pll->pcr = pcrvalue; + vco = ((pll->pcr & 0xFF000000) >> 24) * CONFIG_SYS_INPUT_CLKSRC; + } + gd->vco_clk = vco; /* Vco clock */ + } else if (bootmode == 3) { + /* serial mode */ + vco = ((pll->pcr & 0xFF000000) >> 24) * CONFIG_SYS_INPUT_CLKSRC; + gd->vco_clk = vco; /* Vco clock */ + } + + if ((ccm->ccr & CCM_MISCCR_LIMP) == CCM_MISCCR_LIMP) { + /* Limp mode */ + } else { + gd->inp_clk = CONFIG_SYS_INPUT_CLKSRC; /* Input clock */ + + temp = (pll->pcr & PLL_PCR_OUTDIV1_MASK) + 1; + gd->cpu_clk = vco / temp; /* cpu clock */ + + temp = ((pll->pcr & PLL_PCR_OUTDIV2_MASK) >> 4) + 1; + gd->bus_clk = vco / temp; /* bus clock */ + + temp = ((pll->pcr & PLL_PCR_OUTDIV3_MASK) >> 8) + 1; + gd->flb_clk = vco / temp; /* FlexBus clock */ + +#ifdef CONFIG_PCI + if (bPci) { + temp = ((pll->pcr & PLL_PCR_OUTDIV4_MASK) >> 12) + 1; + gd->pci_clk = vco / temp; /* PCI clock */ + } +#endif + } + +#ifdef CONFIG_FSL_I2C + gd->i2c1_clk = gd->bus_clk; +#endif + + return (0); +} diff --git a/arch/m68k/cpu/mcf5445x/start.S b/arch/m68k/cpu/mcf5445x/start.S new file mode 100644 index 0000000000..738e4a7110 --- /dev/null +++ b/arch/m68k/cpu/mcf5445x/start.S @@ -0,0 +1,545 @@ +/* + * Copyright (C) 2003 Josef Baumgartner <josef.baumgartner@telex.de> + * Based on code from Bernhard Kuhn <bkuhn@metrowerks.com> + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <config.h> +#include <timestamp.h> +#include "version.h" +#include <asm/cache.h> + +#ifndef CONFIG_IDENT_STRING +#define CONFIG_IDENT_STRING "" +#endif + +#define _START _start +#define _FAULT _fault + +#define SAVE_ALL \ + move.w #0x2700,%sr; /* disable intrs */ \ + subl #60,%sp; /* space for 15 regs */ \ + moveml %d0-%d7/%a0-%a6,%sp@; + +#define RESTORE_ALL \ + moveml %sp@,%d0-%d7/%a0-%a6; \ + addl #60,%sp; /* space for 15 regs */ \ + rte; + +#if defined(CONFIG_CF_SBF) +#define ASM_DRAMINIT (asm_dram_init - TEXT_BASE + CONFIG_SYS_INIT_RAM_ADDR) +#define ASM_SBF_IMG_HDR (asm_sbf_img_hdr - TEXT_BASE + CONFIG_SYS_INIT_RAM_ADDR) +#endif + +.text + +/* + * Vector table. This is used for initial platform startup. + * These vectors are to catch any un-intended traps. + */ +_vectors: +#if defined(CONFIG_CF_SBF) + +INITSP: .long 0 /* Initial SP */ +INITPC: .long ASM_DRAMINIT /* Initial PC */ + +#else + +INITSP: .long 0 /* Initial SP */ +INITPC: .long _START /* Initial PC */ + +#endif + +vector02: .long _FAULT /* Access Error */ +vector03: .long _FAULT /* Address Error */ +vector04: .long _FAULT /* Illegal Instruction */ +vector05: .long _FAULT /* Reserved */ +vector06: .long _FAULT /* Reserved */ +vector07: .long _FAULT /* Reserved */ +vector08: .long _FAULT /* Privilege Violation */ +vector09: .long _FAULT /* Trace */ +vector0A: .long _FAULT /* Unimplemented A-Line */ +vector0B: .long _FAULT /* Unimplemented F-Line */ +vector0C: .long _FAULT /* Debug Interrupt */ +vector0D: .long _FAULT /* Reserved */ +vector0E: .long _FAULT /* Format Error */ +vector0F: .long _FAULT /* Unitialized Int. */ + +/* Reserved */ +vector10_17: +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT + +vector18: .long _FAULT /* Spurious Interrupt */ +vector19: .long _FAULT /* Autovector Level 1 */ +vector1A: .long _FAULT /* Autovector Level 2 */ +vector1B: .long _FAULT /* Autovector Level 3 */ +vector1C: .long _FAULT /* Autovector Level 4 */ +vector1D: .long _FAULT /* Autovector Level 5 */ +vector1E: .long _FAULT /* Autovector Level 6 */ +vector1F: .long _FAULT /* Autovector Level 7 */ + +#if !defined(CONFIG_CF_SBF) + +/* TRAP #0 - #15 */ +vector20_2F: +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT + +/* Reserved */ +vector30_3F: +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT + +vector64_127: +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT + +vector128_191: +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT + +vector192_255: +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +#endif + +#if defined(CONFIG_CF_SBF) + /* Image header: chksum 4 bytes, len 4 bytes, img dest 4 bytes */ +asm_sbf_img_hdr: + .long 0x00000000 /* checksum, not yet implemented */ + .long 0x00030000 /* image length */ + .long TEXT_BASE /* image to be relocated at */ + +asm_dram_init: + move.w #0x2700,%sr /* Mask off Interrupt */ + + move.l #CONFIG_SYS_INIT_RAM_ADDR, %d0 + movec %d0, %VBR + + move.l #(CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_RAM_CTRL), %d0 + movec %d0, %RAMBAR1 + + /* initialize general use internal ram */ + move.l #0, %d0 + move.l #(ICACHE_STATUS), %a1 /* icache */ + move.l #(DCACHE_STATUS), %a2 /* dcache */ + move.l %d0, (%a1) + move.l %d0, (%a2) + + /* invalidate and disable cache */ + move.l #(CONFIG_SYS_ICACHE_INV + CONFIG_SYS_DCACHE_INV), %d0 + movec %d0, %CACR /* Invalidate cache */ + move.l #0, %d0 + movec %d0, %ACR0 + movec %d0, %ACR1 + movec %d0, %ACR2 + movec %d0, %ACR3 + + move.l #(CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_SP_OFFSET), %sp + clr.l %sp@- + + /* Must disable global address */ + move.l #0xFC008000, %a1 + move.l #(CONFIG_SYS_CS0_BASE), (%a1) + move.l #0xFC008008, %a1 + move.l #(CONFIG_SYS_CS0_CTRL), (%a1) + move.l #0xFC008004, %a1 + move.l #(CONFIG_SYS_CS0_MASK), (%a1) + + /* Dram Initialization a1, a2, and d0 */ + /* mscr sdram */ + move.l #0xFC0A4074, %a1 + move.b #(CONFIG_SYS_SDRAM_DRV_STRENGTH), (%a1) + nop + + /* SDRAM Chip 0 and 1 */ + move.l #0xFC0B8110, %a1 + move.l #0xFC0B8114, %a2 + + /* calculate the size */ + move.l #0x13, %d1 + move.l #(CONFIG_SYS_SDRAM_SIZE), %d2 +#ifdef CONFIG_SYS_SDRAM_BASE1 + lsr.l #1, %d2 +#endif + +dramsz_loop: + lsr.l #1, %d2 + add.l #1, %d1 + cmp.l #1, %d2 + bne dramsz_loop + + /* SDRAM Chip 0 and 1 */ + move.l #(CONFIG_SYS_SDRAM_BASE), (%a1) + or.l %d1, (%a1) +#ifdef CONFIG_SYS_SDRAM_BASE1 + move.l #(CONFIG_SYS_SDRAM_BASE1), (%a2) + or.l %d1, (%a2) +#endif + nop + + /* dram cfg1 and cfg2 */ + move.l #0xFC0B8008, %a1 + move.l #(CONFIG_SYS_SDRAM_CFG1), (%a1) + nop + move.l #0xFC0B800C, %a2 + move.l #(CONFIG_SYS_SDRAM_CFG2), (%a2) + nop + + move.l #0xFC0B8000, %a1 /* Mode */ + move.l #0xFC0B8004, %a2 /* Ctrl */ + + /* Issue PALL */ + move.l #(CONFIG_SYS_SDRAM_CTRL + 2), (%a2) + nop + +#ifdef CONFIG_M54455EVB + /* Issue LEMR */ + move.l #(CONFIG_SYS_SDRAM_EMOD + 0x408), (%a1) + nop + move.l #(CONFIG_SYS_SDRAM_MODE + 0x300), (%a1) + nop +#endif + + move.l #1000, %d1 + jsr asm_delay + + /* Issue PALL */ + move.l #(CONFIG_SYS_SDRAM_CTRL + 2), (%a2) + nop + + /* Perform two refresh cycles */ + move.l #(CONFIG_SYS_SDRAM_CTRL + 4), %d0 + nop + move.l %d0, (%a2) + move.l %d0, (%a2) + nop + +#ifdef CONFIG_M54455EVB + move.l #(CONFIG_SYS_SDRAM_MODE + 0x200), (%a1) + nop +#elif defined(CONFIG_M54451EVB) + /* Issue LEMR */ + move.l #(CONFIG_SYS_SDRAM_MODE), (%a1) + nop + move.l #(CONFIG_SYS_SDRAM_EMOD), (%a1) +#endif + + move.l #500, %d1 + jsr asm_delay + + move.l #(CONFIG_SYS_SDRAM_CTRL), %d1 + and.l #0x7FFFFFFF, %d1 +#ifdef CONFIG_M54455EVB + or.l #0x10000C00, %d1 +#elif defined(CONFIG_M54451EVB) + or.l #0x10000C00, %d1 +#endif + move.l %d1, (%a2) + nop + + move.l #2000, %d1 + jsr asm_delay + + /* + * DSPI Initialization + * a0 - general, sram - 0x80008000 - 32, see M54455EVB.h + * a1 - dspi status + * a2 - dtfr + * a3 - drfr + * a4 - Dst addr + */ + /* Enable pins for DSPI mode - chip-selects are enabled later */ +asm_dspi_init: + move.l #0xFC0A4063, %a0 + move.b #0x7F, (%a0) + + /* Configure DSPI module */ + move.l #0xFC05C000, %a0 + move.l #0x80FF0C00, (%a0) /* Master, clear TX/RX FIFO */ + + move.l #0xFC05C00C, %a0 + move.l #0x3E000011, (%a0) + + move.l #0xFC05C034, %a2 /* dtfr */ + move.l #0xFC05C03B, %a3 /* drfr */ + + move.l #(ASM_SBF_IMG_HDR + 4), %a1 + move.l (%a1)+, %d5 + move.l (%a1), %a4 + + move.l #(CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_SBFHDR_DATA_OFFSET), %a0 + move.l #(CONFIG_SYS_SBFHDR_SIZE), %d4 + + move.l #0xFC05C02C, %a1 /* dspi status */ + + /* Issue commands and address */ + move.l #0x8002000B, %d2 /* Fast Read Cmd */ + jsr asm_dspi_wr_status + jsr asm_dspi_rd_status + + move.l #0x80020000, %d2 /* Address byte 2 */ + jsr asm_dspi_wr_status + jsr asm_dspi_rd_status + + move.l #0x80020000, %d2 /* Address byte 1 */ + jsr asm_dspi_wr_status + jsr asm_dspi_rd_status + + move.l #0x80020000, %d2 /* Address byte 0 */ + jsr asm_dspi_wr_status + jsr asm_dspi_rd_status + + move.l #0x80020000, %d2 /* Dummy Wr and Rd */ + jsr asm_dspi_wr_status + jsr asm_dspi_rd_status + + /* Transfer serial boot header to sram */ +asm_dspi_rd_loop1: + move.l #0x80020000, %d2 + jsr asm_dspi_wr_status + jsr asm_dspi_rd_status + + move.b %d1, (%a0) /* read, copy to dst */ + + add.l #1, %a0 /* inc dst by 1 */ + sub.l #1, %d4 /* dec cnt by 1 */ + bne asm_dspi_rd_loop1 + + /* Transfer u-boot from serial flash to memory */ +asm_dspi_rd_loop2: + move.l #0x80020000, %d2 + jsr asm_dspi_wr_status + jsr asm_dspi_rd_status + + move.b %d1, (%a4) /* read, copy to dst */ + + add.l #1, %a4 /* inc dst by 1 */ + sub.l #1, %d5 /* dec cnt by 1 */ + bne asm_dspi_rd_loop2 + + move.l #0x00020000, %d2 /* Terminate */ + jsr asm_dspi_wr_status + jsr asm_dspi_rd_status + + /* jump to memory and execute */ + move.l #(TEXT_BASE + 0x400), %a0 + jmp (%a0) + +asm_dspi_wr_status: + move.l (%a1), %d0 /* status */ + and.l #0x0000F000, %d0 + cmp.l #0x00003000, %d0 + bgt asm_dspi_wr_status + + move.l %d2, (%a2) + rts + +asm_dspi_rd_status: + move.l (%a1), %d0 /* status */ + and.l #0x000000F0, %d0 + lsr.l #4, %d0 + cmp.l #0, %d0 + beq asm_dspi_rd_status + + move.b (%a3), %d1 + rts + +asm_delay: + nop + subq.l #1, %d1 + bne asm_delay + rts +#endif /* CONFIG_CF_SBF */ + + .text + . = 0x400 + .globl _start +_start: +#if !defined(CONFIG_CF_SBF) + nop + nop + move.w #0x2700,%sr /* Mask off Interrupt */ + + /* Set vector base register at the beginning of the Flash */ + move.l #CONFIG_SYS_FLASH_BASE, %d0 + movec %d0, %VBR + + move.l #(CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_RAM_CTRL), %d0 + movec %d0, %RAMBAR1 + + /* initialize general use internal ram */ + move.l #0, %d0 + move.l #(ICACHE_STATUS), %a1 /* icache */ + move.l #(DCACHE_STATUS), %a2 /* dcache */ + move.l %d0, (%a1) + move.l %d0, (%a2) + + /* invalidate and disable cache */ + move.l #(CONFIG_SYS_ICACHE_INV + CONFIG_SYS_DCACHE_INV), %d0 + movec %d0, %CACR /* Invalidate cache */ + move.l #0, %d0 + movec %d0, %ACR0 + movec %d0, %ACR1 + movec %d0, %ACR2 + movec %d0, %ACR3 + + /* set stackpointer to end of internal ram to get some stackspace for + the first c-code */ + move.l #(CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_SP_OFFSET), %sp + clr.l %sp@- +#endif + + move.l #__got_start, %a5 /* put relocation table address to a5 */ + + bsr cpu_init_f /* run low-level CPU init code (from flash) */ + bsr board_init_f /* run low-level board init code (from flash) */ + + /* board_init_f() does not return */ + +/*------------------------------------------------------------------------------*/ + +/* + * void relocate_code (addr_sp, gd, addr_moni) + * + * This "function" does not return, instead it continues in RAM + * after relocating the monitor code. + * + * r3 = dest + * r4 = src + * r5 = length in bytes + * r6 = cachelinesize + */ + .globl relocate_code +relocate_code: + link.w %a6,#0 + move.l 8(%a6), %sp /* set new stack pointer */ + + move.l 12(%a6), %d0 /* Save copy of Global Data pointer */ + move.l 16(%a6), %a0 /* Save copy of Destination Address */ + + move.l #CONFIG_SYS_MONITOR_BASE, %a1 + move.l #__init_end, %a2 + move.l %a0, %a3 + + /* copy the code to RAM */ +1: + move.l (%a1)+, (%a3)+ + cmp.l %a1,%a2 + bgt.s 1b + +/* + * We are done. Do not return, instead branch to second part of board + * initialization, now running from RAM. + */ + move.l %a0, %a1 + add.l #(in_ram - CONFIG_SYS_MONITOR_BASE), %a1 + jmp (%a1) + +in_ram: + +clear_bss: + /* + * Now clear BSS segment + */ + move.l %a0, %a1 + add.l #(_sbss - CONFIG_SYS_MONITOR_BASE),%a1 + move.l %a0, %d1 + add.l #(_ebss - CONFIG_SYS_MONITOR_BASE),%d1 +6: + clr.l (%a1)+ + cmp.l %a1,%d1 + bgt.s 6b + + /* + * fix got table in RAM + */ + move.l %a0, %a1 + add.l #(__got_start - CONFIG_SYS_MONITOR_BASE),%a1 + move.l %a1,%a5 /* * fix got pointer register a5 */ + + move.l %a0, %a2 + add.l #(__got_end - CONFIG_SYS_MONITOR_BASE),%a2 + +7: + move.l (%a1),%d1 + sub.l #_start,%d1 + add.l %a0,%d1 + move.l %d1,(%a1)+ + cmp.l %a2, %a1 + bne 7b + + /* calculate relative jump to board_init_r in ram */ + move.l %a0, %a1 + add.l #(board_init_r - CONFIG_SYS_MONITOR_BASE), %a1 + + /* set parameters for board_init_r */ + move.l %a0,-(%sp) /* dest_addr */ + move.l %d0,-(%sp) /* gd */ + jsr (%a1) + +/*------------------------------------------------------------------------------*/ +/* exception code */ + .globl _fault +_fault: + bra _fault + .globl _exc_handler + +_exc_handler: + SAVE_ALL + movel %sp,%sp@- + bsr exc_handler + addql #4,%sp + RESTORE_ALL + + .globl _int_handler +_int_handler: + SAVE_ALL + movel %sp,%sp@- + bsr int_handler + addql #4,%sp + RESTORE_ALL + +/*------------------------------------------------------------------------------*/ + + .globl version_string +version_string: + .ascii U_BOOT_VERSION + .ascii " (", U_BOOT_DATE, " - ", U_BOOT_TIME, ")" + .ascii CONFIG_IDENT_STRING, "\0" + .align 4 diff --git a/arch/m68k/cpu/mcf547x_8x/Makefile b/arch/m68k/cpu/mcf547x_8x/Makefile new file mode 100644 index 0000000000..e12bef12c9 --- /dev/null +++ b/arch/m68k/cpu/mcf547x_8x/Makefile @@ -0,0 +1,48 @@ +# +# (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 + +# CFLAGS += -DET_DEBUG + +LIB = lib$(CPU).a + +START = +COBJS = cpu.o speed.o cpu_init.o pci.o interrupts.o slicetimer.o + +SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) +START := $(addprefix $(obj),$(START)) + +all: $(obj).depend $(START) $(LIB) + +$(LIB): $(OBJS) + $(AR) $(ARFLAGS) $@ $(OBJS) + +######################################################################### + +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/arch/m68k/cpu/mcf547x_8x/config.mk b/arch/m68k/cpu/mcf547x_8x/config.mk new file mode 100644 index 0000000000..83102abbbb --- /dev/null +++ b/arch/m68k/cpu/mcf547x_8x/config.mk @@ -0,0 +1,37 @@ +# +# (C) Copyright 2003 Josef Baumgartner <josef.baumgartner@telex.de> +# +# (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-d7 -msep-data +ifneq ($(findstring 4.1,$(shell $(CC) --version)),4.1) +PLATFORM_CPPFLAGS += -mcpu=5485 -fPIC +else +PLATFORM_CPPFLAGS += -m5407 -fPIC +endif + +ifneq (,$(findstring -linux-,$(shell $(CC) --version))) +ifneq (,$(findstring GOT,$(shell $(LD) --help))) +PLATFORM_LDFLAGS += --got=single +endif +endif diff --git a/arch/m68k/cpu/mcf547x_8x/cpu.c b/arch/m68k/cpu/mcf547x_8x/cpu.c new file mode 100644 index 0000000000..3912a74d5f --- /dev/null +++ b/arch/m68k/cpu/mcf547x_8x/cpu.c @@ -0,0 +1,164 @@ +/* + * + * (C) Copyright 2000-2003 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * Copyright (C) 2004-2007 Freescale Semiconductor, Inc. + * TsiChung Liew (Tsi-Chung.Liew@freescale.com) + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <watchdog.h> +#include <command.h> +#include <netdev.h> + +#include <asm/immap.h> + +DECLARE_GLOBAL_DATA_PTR; + +int do_reset(cmd_tbl_t * cmdtp, bd_t * bd, int flag, int argc, char *argv[]) +{ + volatile gptmr_t *gptmr = (gptmr_t *) (MMAP_GPTMR); + + gptmr->pre = 10; + gptmr->cnt = 1; + + /* enable watchdog, set timeout to 0 and wait */ + gptmr->mode = GPT_TMS_SGPIO; + gptmr->ctrl = GPT_CTRL_WDEN | GPT_CTRL_CE; + + /* we don't return! */ + return 1; +}; + +int checkcpu(void) +{ + volatile siu_t *siu = (siu_t *) MMAP_SIU; + u16 id = 0; + + puts("CPU: "); + + switch ((siu->jtagid & 0x000FF000) >> 12) { + case 0x0C: + id = 5485; + break; + case 0x0D: + id = 5484; + break; + case 0x0E: + id = 5483; + break; + case 0x0F: + id = 5482; + break; + case 0x10: + id = 5481; + break; + case 0x11: + id = 5480; + break; + case 0x12: + id = 5475; + break; + case 0x13: + id = 5474; + break; + case 0x14: + id = 5473; + break; + case 0x15: + id = 5472; + break; + case 0x16: + id = 5471; + break; + case 0x17: + id = 5470; + break; + } + + if (id) { + char buf1[32], buf2[32]; + + printf("Freescale MCF%d\n", id); + printf(" CPU CLK %s MHz BUS CLK %s MHz\n", + strmhz(buf1, gd->cpu_clk), + strmhz(buf2, gd->bus_clk)); + } + + return 0; +}; + +#if defined(CONFIG_HW_WATCHDOG) +/* Called by macro WATCHDOG_RESET */ +void hw_watchdog_reset(void) +{ + volatile gptmr_t *gptmr = (gptmr_t *) (MMAP_GPTMR); + + gptmr->ocpw = 0xa5; +} + +int watchdog_disable(void) +{ + volatile gptmr_t *gptmr = (gptmr_t *) (MMAP_GPTMR); + + /* UserManual, once the wdog is disabled, wdog cannot be re-enabled */ + gptmr->mode = 0; + gptmr->ctrl = 0; + + puts("WATCHDOG:disabled\n"); + + return (0); +} + +int watchdog_init(void) +{ + + volatile gptmr_t *gptmr = (gptmr_t *) (MMAP_GPTMR); + + gptmr->pre = CONFIG_WATCHDOG_TIMEOUT; + gptmr->cnt = CONFIG_SYS_TIMER_PRESCALER * 1000; + + gptmr->mode = GPT_TMS_SGPIO; + gptmr->ctrl = GPT_CTRL_CE | GPT_CTRL_WDEN; + puts("WATCHDOG:enabled\n"); + + return (0); +} +#endif /* CONFIG_HW_WATCHDOG */ + +#if defined(CONFIG_FSLDMAFEC) || defined(CONFIG_MCFFEC) +/* Default initializations for MCFFEC controllers. To override, + * create a board-specific function called: + * int board_eth_init(bd_t *bis) + */ + +int cpu_eth_init(bd_t *bis) +{ +#if defined(CONFIG_FSLDMAFEC) + mcdmafec_initialize(bis); +#endif +#if defined(CONFIG_MCFFEC) + mcffec_initialize(bis); +#endif + return 0; +} +#endif diff --git a/arch/m68k/cpu/mcf547x_8x/cpu_init.c b/arch/m68k/cpu/mcf547x_8x/cpu_init.c new file mode 100644 index 0000000000..60c91267a7 --- /dev/null +++ b/arch/m68k/cpu/mcf547x_8x/cpu_init.c @@ -0,0 +1,159 @@ +/* + * + * (C) Copyright 2000-2003 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * (C) Copyright 2007 Freescale Semiconductor, Inc. + * TsiChung Liew (Tsi-Chung.Liew@freescale.com) + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <MCD_dma.h> +#include <asm/immap.h> + +#if defined(CONFIG_CMD_NET) +#include <config.h> +#include <net.h> +#include <asm/fsl_mcdmafec.h> +#endif + +/* + * Breath some life into the CPU... + * + * Set up the memory map, + * initialize a bunch of registers, + * initialize the UPM's + */ +void cpu_init_f(void) +{ + volatile gpio_t *gpio = (gpio_t *) MMAP_GPIO; + volatile fbcs_t *fbcs = (fbcs_t *) MMAP_FBCS; + volatile xlbarb_t *xlbarb = (volatile xlbarb_t *) MMAP_XARB; + + xlbarb->adrto = 0x2000; + xlbarb->datto = 0x2500; + xlbarb->busto = 0x3000; + + xlbarb->cfg = XARB_CFG_AT | XARB_CFG_DT; + + /* Master Priority Enable */ + xlbarb->prien = 0xff; + xlbarb->pri = 0; + +#if (defined(CONFIG_SYS_CS0_BASE) && defined(CONFIG_SYS_CS0_MASK) && defined(CONFIG_SYS_CS0_CTRL)) + fbcs->csar0 = CONFIG_SYS_CS0_BASE; + fbcs->cscr0 = CONFIG_SYS_CS0_CTRL; + fbcs->csmr0 = CONFIG_SYS_CS0_MASK; +#endif + +#if (defined(CONFIG_SYS_CS1_BASE) && defined(CONFIG_SYS_CS1_MASK) && defined(CONFIG_SYS_CS1_CTRL)) + fbcs->csar1 = CONFIG_SYS_CS1_BASE; + fbcs->cscr1 = CONFIG_SYS_CS1_CTRL; + fbcs->csmr1 = CONFIG_SYS_CS1_MASK; +#endif + +#if (defined(CONFIG_SYS_CS2_BASE) && defined(CONFIG_SYS_CS2_MASK) && defined(CONFIG_SYS_CS2_CTRL)) + fbcs->csar2 = CONFIG_SYS_CS2_BASE; + fbcs->cscr2 = CONFIG_SYS_CS2_CTRL; + fbcs->csmr2 = CONFIG_SYS_CS2_MASK; +#endif + +#if (defined(CONFIG_SYS_CS3_BASE) && defined(CONFIG_SYS_CS3_MASK) && defined(CONFIG_SYS_CS3_CTRL)) + fbcs->csar3 = CONFIG_SYS_CS3_BASE; + fbcs->cscr3 = CONFIG_SYS_CS3_CTRL; + fbcs->csmr3 = CONFIG_SYS_CS3_MASK; +#endif + +#if (defined(CONFIG_SYS_CS4_BASE) && defined(CONFIG_SYS_CS4_MASK) && defined(CONFIG_SYS_CS4_CTRL)) + fbcs->csar4 = CONFIG_SYS_CS4_BASE; + fbcs->cscr4 = CONFIG_SYS_CS4_CTRL; + fbcs->csmr4 = CONFIG_SYS_CS4_MASK; +#endif + +#if (defined(CONFIG_SYS_CS5_BASE) && defined(CONFIG_SYS_CS5_MASK) && defined(CONFIG_SYS_CS5_CTRL)) + fbcs->csar5 = CONFIG_SYS_CS5_BASE; + fbcs->cscr5 = CONFIG_SYS_CS5_CTRL; + fbcs->csmr5 = CONFIG_SYS_CS5_MASK; +#endif + +#ifdef CONFIG_FSL_I2C + gpio->par_feci2cirq = GPIO_PAR_FECI2CIRQ_SCL | GPIO_PAR_FECI2CIRQ_SDA; +#endif + + icache_enable(); +} + +/* + * initialize higher level parts of CPU like timers + */ +int cpu_init_r(void) +{ +#if defined(CONFIG_CMD_NET) && defined(CONFIG_FSLDMAFEC) + MCD_initDma((dmaRegs *) (MMAP_MCDMA), (void *)(MMAP_SRAM + 512), + MCD_RELOC_TASKS); +#endif + return (0); +} + +void uart_port_conf(int port) +{ + volatile gpio_t *gpio = (gpio_t *) MMAP_GPIO; + volatile u8 *pscsicr = (u8 *) (CONFIG_SYS_UART_BASE + 0x40); + + /* Setup Ports: */ + switch (port) { + case 0: + gpio->par_psc0 = (GPIO_PAR_PSC0_TXD0 | GPIO_PAR_PSC0_RXD0); + break; + case 1: + gpio->par_psc1 = (GPIO_PAR_PSC1_TXD1 | GPIO_PAR_PSC1_RXD1); + break; + case 2: + gpio->par_psc2 = (GPIO_PAR_PSC2_TXD2 | GPIO_PAR_PSC2_RXD2); + break; + case 3: + gpio->par_psc3 = (GPIO_PAR_PSC3_TXD3 | GPIO_PAR_PSC3_RXD3); + break; + } + + *pscsicr &= 0xF8; +} + +#if defined(CONFIG_CMD_NET) +int fecpin_setclear(struct eth_device *dev, int setclear) +{ + volatile gpio_t *gpio = (gpio_t *) MMAP_GPIO; + struct fec_info_dma *info = (struct fec_info_dma *)dev->priv; + + if (setclear) { + if (info->iobase == CONFIG_SYS_FEC0_IOBASE) + gpio->par_feci2cirq |= 0xF000; + else + gpio->par_feci2cirq |= 0x0FC0; + } else { + if (info->iobase == CONFIG_SYS_FEC0_IOBASE) + gpio->par_feci2cirq &= 0x0FFF; + else + gpio->par_feci2cirq &= 0xF03F; + } + return 0; +} +#endif diff --git a/arch/m68k/cpu/mcf547x_8x/interrupts.c b/arch/m68k/cpu/mcf547x_8x/interrupts.c new file mode 100644 index 0000000000..76be876aa0 --- /dev/null +++ b/arch/m68k/cpu/mcf547x_8x/interrupts.c @@ -0,0 +1,50 @@ +/* + * + * Copyright (C) 2004-2007 Freescale Semiconductor, Inc. + * TsiChung Liew (Tsi-Chung.Liew@freescale.com) + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +/* CPU specific interrupt routine */ +#include <common.h> +#include <asm/immap.h> + +int interrupt_init(void) +{ + volatile int0_t *intp = (int0_t *) (CONFIG_SYS_INTR_BASE); + + /* Make sure all interrupts are disabled */ + intp->imrh0 |= 0xFFFFFFFF; + intp->imrl0 |= 0xFFFFFFFF; + + enable_interrupts(); + + return 0; +} + +#if defined(CONFIG_SLTTMR) +void dtimer_intr_setup(void) +{ + volatile int0_t *intp = (int0_t *) (CONFIG_SYS_INTR_BASE); + + intp->icr0[CONFIG_SYS_TMRINTR_NO] = CONFIG_SYS_TMRINTR_PRI; + intp->imrh0 &= ~CONFIG_SYS_TMRINTR_MASK; +} +#endif diff --git a/arch/m68k/cpu/mcf547x_8x/pci.c b/arch/m68k/cpu/mcf547x_8x/pci.c new file mode 100644 index 0000000000..f867dc1279 --- /dev/null +++ b/arch/m68k/cpu/mcf547x_8x/pci.c @@ -0,0 +1,167 @@ +/* + * Copyright (C) 2004-2007 Freescale Semiconductor, Inc. + * TsiChung Liew (Tsi-Chung.Liew@freescale.com) + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +/* + * PCI Configuration space access support + */ +#include <common.h> +#include <pci.h> +#include <asm/io.h> +#include <asm/immap.h> + +#if defined(CONFIG_PCI) +/* System RAM mapped over PCI */ +#define CONFIG_SYS_PCI_SYS_MEM_BUS CONFIG_SYS_SDRAM_BASE +#define CONFIG_SYS_PCI_SYS_MEM_PHYS CONFIG_SYS_SDRAM_BASE +#define CONFIG_SYS_PCI_SYS_MEM_SIZE (1024 * 1024 * 1024) + +#define cfg_read(val, addr, type, op) *val = op((type)(addr)); +#define cfg_write(val, addr, type, op) op((type *)(addr), (val)); + +#define PCI_OP(rw, size, type, op, mask) \ +int pci_##rw##_cfg_##size(struct pci_controller *hose, \ + pci_dev_t dev, int offset, type val) \ +{ \ + u32 addr = 0; \ + u16 cfg_type = 0; \ + addr = ((offset & 0xfc) | cfg_type | (dev) | 0x80000000); \ + out_be32(hose->cfg_addr, addr); \ + cfg_##rw(val, hose->cfg_data + (offset & mask), type, op); \ + __asm__ __volatile__("nop"); \ + __asm__ __volatile__("nop"); \ + out_be32(hose->cfg_addr, addr & 0x7fffffff); \ + return 0; \ +} + +PCI_OP(read, byte, u8 *, in_8, 3) +PCI_OP(read, word, u16 *, in_le16, 2) +PCI_OP(write, byte, u8, out_8, 3) +PCI_OP(write, word, u16, out_le16, 2) +PCI_OP(write, dword, u32, out_le32, 0) + +int pci_read_cfg_dword(struct pci_controller *hose, pci_dev_t dev, + int offset, u32 * val) +{ + u32 addr; + u32 tmpv; + u32 mask = 2; /* word access */ + /* Read lower 16 bits */ + addr = ((offset & 0xfc) | (dev) | 0x80000000); + out_be32(hose->cfg_addr, addr); + *val = (u32) in_le16((u16 *) (hose->cfg_data + (offset & mask))); + __asm__ __volatile__("nop"); + out_be32(hose->cfg_addr, addr & 0x7fffffff); + + /* Read upper 16 bits */ + offset += 2; + addr = ((offset & 0xfc) | 1 | (dev) | 0x80000000); + out_be32(hose->cfg_addr, addr); + tmpv = (u32) in_le16((u16 *) (hose->cfg_data + (offset & mask))); + __asm__ __volatile__("nop"); + out_be32(hose->cfg_addr, addr & 0x7fffffff); + + /* combine results into dword value */ + *val = (tmpv << 16) | *val; + + return 0; +} + +void pci_mcf547x_8x_init(struct pci_controller *hose) +{ + volatile pci_t *pci = (volatile pci_t *) MMAP_PCI; + volatile gpio_t *gpio = (gpio_t *) MMAP_GPIO; + + /* Port configuration */ + gpio->par_pcibg = + GPIO_PAR_PCIBG_PCIBG0(3) | GPIO_PAR_PCIBG_PCIBG1(3) | + GPIO_PAR_PCIBG_PCIBG2(3) | GPIO_PAR_PCIBG_PCIBG3(3) | + GPIO_PAR_PCIBG_PCIBG4(3); + gpio->par_pcibr = + GPIO_PAR_PCIBR_PCIBR0(3) | GPIO_PAR_PCIBR_PCIBR1(3) | + GPIO_PAR_PCIBR_PCIBR2(3) | GPIO_PAR_PCIBR_PCIBR3(3) | + GPIO_PAR_PCIBR_PCIBR4(3); + + /* Assert reset bit */ + pci->gscr |= PCI_GSCR_PR; + + pci->tcr1 = PCI_TCR1_P; + + /* Initiator windows */ + pci->iw0btar = CONFIG_SYS_PCI_MEM_PHYS | (CONFIG_SYS_PCI_MEM_PHYS >> 16); + pci->iw1btar = CONFIG_SYS_PCI_IO_PHYS | (CONFIG_SYS_PCI_IO_PHYS >> 16); + pci->iw2btar = CONFIG_SYS_PCI_CFG_PHYS | (CONFIG_SYS_PCI_CFG_PHYS >> 16); + + pci->iwcr = + PCI_IWCR_W0C_EN | PCI_IWCR_W1C_EN | PCI_IWCR_W1C_IO | + PCI_IWCR_W2C_EN | PCI_IWCR_W2C_IO; + + pci->icr = 0; + + /* Enable bus master and mem access */ + pci->scr = PCI_SCR_B | PCI_SCR_M; + + /* Cache line size and master latency */ + pci->cr1 = PCI_CR1_CLS(8) | PCI_CR1_LTMR(0xF8); + pci->cr2 = 0; + +#ifdef CONFIG_SYS_PCI_BAR0 + pci->bar0 = PCI_BAR_BAR0(CONFIG_SYS_PCI_BAR0); + pci->tbatr0a = CONFIG_SYS_PCI_TBATR0 | PCI_TBATR_EN; +#endif +#ifdef CONFIG_SYS_PCI_BAR1 + pci->bar1 = PCI_BAR_BAR1(CONFIG_SYS_PCI_BAR1); + pci->tbatr1a = CONFIG_SYS_PCI_TBATR1 | PCI_TBATR_EN; +#endif + + /* Deassert reset bit */ + pci->gscr &= ~PCI_GSCR_PR; + udelay(1000); + + /* Enable PCI bus master support */ + hose->first_busno = 0; + hose->last_busno = 0xff; + + pci_set_region(hose->regions + 0, CONFIG_SYS_PCI_MEM_BUS, CONFIG_SYS_PCI_MEM_PHYS, + CONFIG_SYS_PCI_MEM_SIZE, PCI_REGION_MEM); + + pci_set_region(hose->regions + 1, CONFIG_SYS_PCI_IO_BUS, CONFIG_SYS_PCI_IO_PHYS, + CONFIG_SYS_PCI_IO_SIZE, PCI_REGION_IO); + + pci_set_region(hose->regions + 2, CONFIG_SYS_PCI_SYS_MEM_BUS, + CONFIG_SYS_PCI_SYS_MEM_PHYS, CONFIG_SYS_PCI_SYS_MEM_SIZE, + PCI_REGION_MEM | PCI_REGION_SYS_MEMORY); + + hose->region_count = 3; + + hose->cfg_addr = &(pci->car); + hose->cfg_data = (volatile unsigned char *)CONFIG_SYS_PCI_CFG_BUS; + + pci_set_ops(hose, pci_read_cfg_byte, pci_read_cfg_word, + pci_read_cfg_dword, pci_write_cfg_byte, pci_write_cfg_word, + pci_write_cfg_dword); + + /* Hose scan */ + pci_register_hose(hose); + hose->last_busno = pci_hose_scan(hose); +} +#endif /* CONFIG_PCI */ diff --git a/arch/m68k/cpu/mcf547x_8x/slicetimer.c b/arch/m68k/cpu/mcf547x_8x/slicetimer.c new file mode 100644 index 0000000000..8dc010a352 --- /dev/null +++ b/arch/m68k/cpu/mcf547x_8x/slicetimer.c @@ -0,0 +1,112 @@ +/* + * (C) Copyright 2007 Freescale Semiconductor, Inc. + * TsiChung Liew (Tsi-Chung.Liew@freescale.com) + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> + +#include <asm/timer.h> +#include <asm/immap.h> + +DECLARE_GLOBAL_DATA_PTR; + +static ulong timestamp; + +#if defined(CONFIG_SLTTMR) +#ifndef CONFIG_SYS_UDELAY_BASE +# error "uDelay base not defined!" +#endif + +#if !defined(CONFIG_SYS_TMR_BASE) || !defined(CONFIG_SYS_INTR_BASE) || !defined(CONFIG_SYS_TMRINTR_NO) || !defined(CONFIG_SYS_TMRINTR_MASK) +# error "TMR_BASE, INTR_BASE, TMRINTR_NO or TMRINTR_MASk not defined!" +#endif +extern void dtimer_intr_setup(void); + +void __udelay(unsigned long usec) +{ + volatile slt_t *timerp = (slt_t *) (CONFIG_SYS_UDELAY_BASE); + u32 now, freq; + + /* 1 us period */ + freq = CONFIG_SYS_TIMER_PRESCALER; + + timerp->cr = 0; /* Disable */ + timerp->tcnt = usec * freq; + timerp->cr = SLT_CR_TEN; + + now = timerp->cnt; + while (now != 0) + now = timerp->cnt; + + timerp->sr |= SLT_SR_ST; + timerp->cr = 0; +} + +void dtimer_interrupt(void *not_used) +{ + volatile slt_t *timerp = (slt_t *) (CONFIG_SYS_TMR_BASE); + + /* check for timer interrupt asserted */ + if ((CONFIG_SYS_TMRPND_REG & CONFIG_SYS_TMRINTR_MASK) == CONFIG_SYS_TMRINTR_PEND) { + timerp->sr |= SLT_SR_ST; + timestamp++; + return; + } +} + +void timer_init(void) +{ + volatile slt_t *timerp = (slt_t *) (CONFIG_SYS_TMR_BASE); + + timestamp = 0; + + timerp->cr = 0; /* disable timer */ + timerp->tcnt = 0; + timerp->sr = SLT_SR_BE | SLT_SR_ST; /* clear status */ + + /* initialize and enable timer interrupt */ + irq_install_handler(CONFIG_SYS_TMRINTR_NO, dtimer_interrupt, 0); + + /* Interrupt every ms */ + timerp->tcnt = 1000 * CONFIG_SYS_TIMER_PRESCALER; + + dtimer_intr_setup(); + + /* set a period of 1us, set timer mode to restart and + enable timer and interrupt */ + timerp->cr = SLT_CR_RUN | SLT_CR_IEN | SLT_CR_TEN; +} + +void reset_timer(void) +{ + timestamp = 0; +} + +ulong get_timer(ulong base) +{ + return (timestamp - base); +} + +void set_timer(ulong t) +{ + timestamp = t; +} +#endif /* CONFIG_SLTTMR */ diff --git a/arch/m68k/cpu/mcf547x_8x/speed.c b/arch/m68k/cpu/mcf547x_8x/speed.c new file mode 100644 index 0000000000..2cee4887ac --- /dev/null +++ b/arch/m68k/cpu/mcf547x_8x/speed.c @@ -0,0 +1,48 @@ +/* + * + * (C) Copyright 2000-2003 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * Copyright (C) 2004-2007 Freescale Semiconductor, Inc. + * TsiChung Liew (Tsi-Chung.Liew@freescale.com) + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <asm/processor.h> + +#include <asm/immap.h> + +/* + * get_clocks() fills in gd->cpu_clock and gd->bus_clk + */ +int get_clocks(void) +{ + DECLARE_GLOBAL_DATA_PTR; + + gd->bus_clk = CONFIG_SYS_CLK; + gd->cpu_clk = (gd->bus_clk * 2); + +#ifdef CONFIG_FSL_I2C + gd->i2c1_clk = gd->bus_clk; +#endif + + return (0); +} diff --git a/arch/m68k/cpu/mcf547x_8x/start.S b/arch/m68k/cpu/mcf547x_8x/start.S new file mode 100644 index 0000000000..84118629e2 --- /dev/null +++ b/arch/m68k/cpu/mcf547x_8x/start.S @@ -0,0 +1,282 @@ +/* + * Copyright (C) 2003 Josef Baumgartner <josef.baumgartner@telex.de> + * Based on code from Bernhard Kuhn <bkuhn@metrowerks.com> + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <config.h> +#include <timestamp.h> +#include "version.h" +#include <asm/cache.h> + +#ifndef CONFIG_IDENT_STRING +#define CONFIG_IDENT_STRING "" +#endif + +#define _START _start +#define _FAULT _fault + +#define SAVE_ALL \ + move.w #0x2700,%sr; /* disable intrs */ \ + subl #60,%sp; /* space for 15 regs */ \ + moveml %d0-%d7/%a0-%a6,%sp@; + +#define RESTORE_ALL \ + moveml %sp@,%d0-%d7/%a0-%a6; \ + addl #60,%sp; /* space for 15 regs */ \ + rte; + +.text +/* + * Vector table. This is used for initial platform startup. + * These vectors are to catch any un-intended traps. + */ +_vectors: + +INITSP: .long 0x00000000 /* Initial SP */ +INITPC: .long _START /* Initial PC */ +vector02: .long _FAULT /* Access Error */ +vector03: .long _FAULT /* Address Error */ +vector04: .long _FAULT /* Illegal Instruction */ +vector05: .long _FAULT /* Reserved */ +vector06: .long _FAULT /* Reserved */ +vector07: .long _FAULT /* Reserved */ +vector08: .long _FAULT /* Privilege Violation */ +vector09: .long _FAULT /* Trace */ +vector0A: .long _FAULT /* Unimplemented A-Line */ +vector0B: .long _FAULT /* Unimplemented F-Line */ +vector0C: .long _FAULT /* Debug Interrupt */ +vector0D: .long _FAULT /* Reserved */ +vector0E: .long _FAULT /* Format Error */ +vector0F: .long _FAULT /* Unitialized Int. */ + +/* Reserved */ +vector10_17: +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT + +vector18: .long _FAULT /* Spurious Interrupt */ +vector19: .long _FAULT /* Autovector Level 1 */ +vector1A: .long _FAULT /* Autovector Level 2 */ +vector1B: .long _FAULT /* Autovector Level 3 */ +vector1C: .long _FAULT /* Autovector Level 4 */ +vector1D: .long _FAULT /* Autovector Level 5 */ +vector1E: .long _FAULT /* Autovector Level 6 */ +vector1F: .long _FAULT /* Autovector Level 7 */ + +/* TRAP #0 - #15 */ +vector20_2F: +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT + +/* Reserved */ +vector30_3F: +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT + +vector64_127: +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT + +vector128_191: +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT + +vector192_255: +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT +.long _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT, _FAULT + + .text + + .globl _start +_start: + nop + nop + move.w #0x2700,%sr /* Mask off Interrupt */ + + /* Set vector base register at the beginning of the Flash */ + move.l #CONFIG_SYS_FLASH_BASE, %d0 + movec %d0, %VBR + + move.l #(CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_RAM_CTRL), %d0 + movec %d0, %RAMBAR0 + + move.l #(CONFIG_SYS_INIT_RAM1_ADDR + CONFIG_SYS_INIT_RAM1_CTRL), %d0 + movec %d0, %RAMBAR1 + + move.l #CONFIG_SYS_MBAR, %d0 /* set MBAR address */ + move.c %d0, %MBAR + + /* invalidate and disable cache */ + move.l #0x01040100, %d0 /* Invalidate cache cmd */ + movec %d0, %CACR /* Invalidate cache */ + move.l #0, %d0 + movec %d0, %ACR0 + movec %d0, %ACR1 + movec %d0, %ACR2 + movec %d0, %ACR3 + + /* initialize general use internal ram */ + move.l #0, %d0 + move.l #(ICACHE_STATUS), %a1 /* icache */ + move.l #(DCACHE_STATUS), %a2 /* icache */ + move.l %d0, (%a1) + move.l %d0, (%a2) + + /* set stackpointer to end of internal ram to get some stackspace for the + first c-code */ + move.l #(CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_SP_OFFSET), %sp + clr.l %sp@- + + move.l #__got_start, %a5 /* put relocation table address to a5 */ + + bsr cpu_init_f /* run low-level CPU init code (from flash) */ + bsr board_init_f /* run low-level board init code (from flash) */ + + /* board_init_f() does not return */ + +/*------------------------------------------------------------------------------*/ + +/* + * void relocate_code (addr_sp, gd, addr_moni) + * + * This "function" does not return, instead it continues in RAM + * after relocating the monitor code. + * + * r3 = dest + * r4 = src + * r5 = length in bytes + * r6 = cachelinesize + */ + .globl relocate_code +relocate_code: + link.w %a6,#0 + move.l 8(%a6), %sp /* set new stack pointer */ + + move.l 12(%a6), %d0 /* Save copy of Global Data pointer */ + move.l 16(%a6), %a0 /* Save copy of Destination Address */ + + move.l #CONFIG_SYS_MONITOR_BASE, %a1 + move.l #__init_end, %a2 + move.l %a0, %a3 + + /* copy the code to RAM */ +1: + move.l (%a1)+, (%a3)+ + cmp.l %a1,%a2 + bgt.s 1b + +/* + * We are done. Do not return, instead branch to second part of board + * initialization, now running from RAM. + */ + move.l %a0, %a1 + add.l #(in_ram - CONFIG_SYS_MONITOR_BASE), %a1 + jmp (%a1) + +in_ram: + +clear_bss: + /* + * Now clear BSS segment + */ + move.l %a0, %a1 + add.l #(_sbss - CONFIG_SYS_MONITOR_BASE),%a1 + move.l %a0, %d1 + add.l #(_ebss - CONFIG_SYS_MONITOR_BASE),%d1 +6: + clr.l (%a1)+ + cmp.l %a1,%d1 + bgt.s 6b + + /* + * fix got table in RAM + */ + move.l %a0, %a1 + add.l #(__got_start - CONFIG_SYS_MONITOR_BASE),%a1 + move.l %a1,%a5 /* * fix got pointer register a5 */ + + move.l %a0, %a2 + add.l #(__got_end - CONFIG_SYS_MONITOR_BASE),%a2 + +7: + move.l (%a1),%d1 + sub.l #_start,%d1 + add.l %a0,%d1 + move.l %d1,(%a1)+ + cmp.l %a2, %a1 + bne 7b + + /* calculate relative jump to board_init_r in ram */ + move.l %a0, %a1 + add.l #(board_init_r - CONFIG_SYS_MONITOR_BASE), %a1 + + /* set parameters for board_init_r */ + move.l %a0,-(%sp) /* dest_addr */ + move.l %d0,-(%sp) /* gd */ + jsr (%a1) + +/*------------------------------------------------------------------------------*/ +/* exception code */ + .globl _fault +_fault: + bra _fault + .globl _exc_handler + +_exc_handler: + SAVE_ALL + movel %sp,%sp@- + bsr exc_handler + addql #4,%sp + RESTORE_ALL + + .globl _int_handler +_int_handler: + SAVE_ALL + movel %sp,%sp@- + bsr int_handler + addql #4,%sp + RESTORE_ALL + +/*------------------------------------------------------------------------------*/ + + .globl version_string +version_string: + .ascii U_BOOT_VERSION + .ascii " (", U_BOOT_DATE, " - ", U_BOOT_TIME, ")" + .ascii CONFIG_IDENT_STRING, "\0" + .align 4 |