From 570c0186aecab1b747b2d44d0e1d3c1ac4cb27f5 Mon Sep 17 00:00:00 2001 From: TsiChungLiew Date: Tue, 15 Jan 2008 13:37:34 -0600 Subject: [PATCH] ColdFire: Add MCF547x_8x cpu arch Signed-off-by: TsiChungLiew Signed-off by: John Rigby --- cpu/mcf547x_8x/Makefile | 48 +++++ cpu/mcf547x_8x/config.mk | 31 ++++ cpu/mcf547x_8x/cpu.c | 143 ++++++++++++++ cpu/mcf547x_8x/cpu_init.c | 132 +++++++++++++ cpu/mcf547x_8x/interrupts.c | 50 +++++ cpu/mcf547x_8x/pci.c | 167 +++++++++++++++++ cpu/mcf547x_8x/slicetimer.c | 112 +++++++++++ cpu/mcf547x_8x/speed.c | 43 +++++ cpu/mcf547x_8x/start.S | 361 ++++++++++++++++++++++++++++++++++++ 9 files changed, 1087 insertions(+) create mode 100644 cpu/mcf547x_8x/Makefile create mode 100644 cpu/mcf547x_8x/config.mk create mode 100644 cpu/mcf547x_8x/cpu.c create mode 100644 cpu/mcf547x_8x/cpu_init.c create mode 100644 cpu/mcf547x_8x/interrupts.c create mode 100644 cpu/mcf547x_8x/pci.c create mode 100644 cpu/mcf547x_8x/slicetimer.c create mode 100644 cpu/mcf547x_8x/speed.c create mode 100644 cpu/mcf547x_8x/start.S diff --git a/cpu/mcf547x_8x/Makefile b/cpu/mcf547x_8x/Makefile new file mode 100644 index 0000000000..e12bef12c9 --- /dev/null +++ b/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/cpu/mcf547x_8x/config.mk b/cpu/mcf547x_8x/config.mk new file mode 100644 index 0000000000..e5f4385dd3 --- /dev/null +++ b/cpu/mcf547x_8x/config.mk @@ -0,0 +1,31 @@ +# +# (C) Copyright 2003 Josef Baumgartner +# +# (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 +ifeq ($(findstring 4.2,$(shell $(CC) --version)),4.2) +PLATFORM_CPPFLAGS += -mcpu=5485 -fPIC +else +PLATFORM_CPPFLAGS += -m5407 -fPIC +endif diff --git a/cpu/mcf547x_8x/cpu.c b/cpu/mcf547x_8x/cpu.c new file mode 100644 index 0000000000..528bca6bf9 --- /dev/null +++ b/cpu/mcf547x_8x/cpu.c @@ -0,0 +1,143 @@ +/* + * + * (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 +#include +#include + +#include + +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) { + printf("Freescale MCF%d\n", id); + printf(" CPU CLK %d Mhz BUS CLK %d Mhz\n", + (int)(gd->cpu_clk / 1000000), + (int)(gd->bus_clk / 1000000)); + } + + 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 = CFG_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 */ diff --git a/cpu/mcf547x_8x/cpu_init.c b/cpu/mcf547x_8x/cpu_init.c new file mode 100644 index 0000000000..11154c63a8 --- /dev/null +++ b/cpu/mcf547x_8x/cpu_init.c @@ -0,0 +1,132 @@ +/* + * + * (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 +#include +#include + +/* + * 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 = 0x2000; + xlbarb->busto = 0x3000; + + xlbarb->cfg = XARB_SR_AT | XARB_SR_DT; + + /* Master Priority Enable */ + xlbarb->pri = 0; + xlbarb->prien = 0xff; + +#if (defined(CFG_CS0_BASE) && defined(CFG_CS0_MASK) && defined(CFG_CS0_CTRL)) + fbcs->csar0 = CFG_CS0_BASE; + fbcs->cscr0 = CFG_CS0_CTRL; + fbcs->csmr0 = CFG_CS0_MASK; +#endif + +#if (defined(CFG_CS1_BASE) && defined(CFG_CS1_MASK) && defined(CFG_CS1_CTRL)) + fbcs->csar1 = CFG_CS1_BASE; + fbcs->cscr1 = CFG_CS1_CTRL; + fbcs->csmr1 = CFG_CS1_MASK; +#endif + +#if (defined(CFG_CS2_BASE) && defined(CFG_CS2_MASK) && defined(CFG_CS2_CTRL)) + fbcs->csar2 = CFG_CS2_BASE; + fbcs->cscr2 = CFG_CS2_CTRL; + fbcs->csmr2 = CFG_CS2_MASK; +#endif + +#if (defined(CFG_CS3_BASE) && defined(CFG_CS3_MASK) && defined(CFG_CS3_CTRL)) + fbcs->csar3 = CFG_CS3_BASE; + fbcs->cscr3 = CFG_CS3_CTRL; + fbcs->csmr3 = CFG_CS3_MASK; +#endif + +#if (defined(CFG_CS4_BASE) && defined(CFG_CS4_MASK) && defined(CFG_CS4_CTRL)) + fbcs->csar4 = CFG_CS4_BASE; + fbcs->cscr4 = CFG_CS4_CTRL; + fbcs->csmr4 = CFG_CS4_MASK; +#endif + +#if (defined(CFG_CS5_BASE) && defined(CFG_CS5_MASK) && defined(CFG_CS5_CTRL)) + fbcs->csar5 = CFG_CS5_BASE; + fbcs->cscr5 = CFG_CS5_CTRL; + fbcs->csmr5 = CFG_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(void) +{ + volatile gpio_t *gpio = (gpio_t *) MMAP_GPIO; + volatile u8 *pscsicr = (u8 *) (CFG_UART_BASE + 0x40); + + /* Setup Ports: */ + switch (CFG_UART_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; +} diff --git a/cpu/mcf547x_8x/interrupts.c b/cpu/mcf547x_8x/interrupts.c new file mode 100644 index 0000000000..d684ffe9d0 --- /dev/null +++ b/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 +#include + +int interrupt_init(void) +{ + volatile int0_t *intp = (int0_t *) (CFG_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 *) (CFG_INTR_BASE); + + intp->icr0[CFG_TMRINTR_NO] = CFG_TMRINTR_PRI; + intp->imrh0 &= ~CFG_TMRINTR_MASK; +} +#endif diff --git a/cpu/mcf547x_8x/pci.c b/cpu/mcf547x_8x/pci.c new file mode 100644 index 0000000000..70378b09ec --- /dev/null +++ b/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 +#include +#include +#include + +#if defined(CONFIG_PCI) +/* System RAM mapped over PCI */ +#define CFG_PCI_SYS_MEM_BUS CFG_SDRAM_BASE +#define CFG_PCI_SYS_MEM_PHYS CFG_SDRAM_BASE +#define CFG_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 = CFG_PCI_MEM_PHYS | (CFG_PCI_MEM_PHYS >> 16); + pci->iw1btar = CFG_PCI_IO_PHYS | (CFG_PCI_IO_PHYS >> 16); + pci->iw2btar = CFG_PCI_CFG_PHYS | (CFG_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 CFG_PCI_BAR0 + pci->bar0 = PCI_BAR_BAR0(CFG_PCI_BAR0); + pci->tbatr0a = CFG_PCI_TBATR0 | PCI_TBATR_EN; +#endif +#ifdef CFG_PCI_BAR1 + pci->bar1 = PCI_BAR_BAR1(CFG_PCI_BAR1); + pci->tbatr1a = CFG_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, CFG_PCI_MEM_BUS, CFG_PCI_MEM_PHYS, + CFG_PCI_MEM_SIZE, PCI_REGION_MEM); + + pci_set_region(hose->regions + 1, CFG_PCI_IO_BUS, CFG_PCI_IO_PHYS, + CFG_PCI_IO_SIZE, PCI_REGION_IO); + + pci_set_region(hose->regions + 2, CFG_PCI_SYS_MEM_BUS, + CFG_PCI_SYS_MEM_PHYS, CFG_PCI_SYS_MEM_SIZE, + PCI_REGION_MEM | PCI_REGION_MEMORY); + + hose->region_count = 3; + + hose->cfg_addr = &(pci->car); + hose->cfg_data = (volatile unsigned char *)CFG_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/cpu/mcf547x_8x/slicetimer.c b/cpu/mcf547x_8x/slicetimer.c new file mode 100644 index 0000000000..494f98f669 --- /dev/null +++ b/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 + +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +static ulong timestamp; + +#if defined(CONFIG_SLTTMR) +#ifndef CFG_UDELAY_BASE +# error "uDelay base not defined!" +#endif + +#if !defined(CFG_TMR_BASE) || !defined(CFG_INTR_BASE) || !defined(CFG_TMRINTR_NO) || !defined(CFG_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 *) (CFG_UDELAY_BASE); + u32 now, freq; + + /* 1 us period */ + freq = CFG_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 *) (CFG_TMR_BASE); + + /* check for timer interrupt asserted */ + if ((CFG_TMRPND_REG & CFG_TMRINTR_MASK) == CFG_TMRINTR_PEND) { + timerp->sr |= SLT_SR_ST; + timestamp++; + return; + } +} + +void timer_init(void) +{ + volatile slt_t *timerp = (slt_t *) (CFG_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(CFG_TMRINTR_NO, dtimer_interrupt, 0); + + /* Interrupt every ms */ + timerp->tcnt = 1000 * CFG_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/cpu/mcf547x_8x/speed.c b/cpu/mcf547x_8x/speed.c new file mode 100644 index 0000000000..389e7c99f5 --- /dev/null +++ b/cpu/mcf547x_8x/speed.c @@ -0,0 +1,43 @@ +/* + * + * (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 +#include + +#include + +/* + * get_clocks() fills in gd->cpu_clock and gd->bus_clk + */ +int get_clocks(void) +{ + DECLARE_GLOBAL_DATA_PTR; + + gd->bus_clk = CFG_CLK; + gd->cpu_clk = (gd->bus_clk * 2); + return (0); +} diff --git a/cpu/mcf547x_8x/start.S b/cpu/mcf547x_8x/start.S new file mode 100644 index 0000000000..442665f250 --- /dev/null +++ b/cpu/mcf547x_8x/start.S @@ -0,0 +1,361 @@ +/* + * Copyright (C) 2003 Josef Baumgartner + * Based on code from Bernhard Kuhn + * + * 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 +#include "version.h" + +#ifndef CONFIG_IDENT_STRING +#define CONFIG_IDENT_STRING "" +#endif + +/* last three long word reserved for cache status */ +#define ICACHE_STATUS (CFG_INIT_RAM_ADDR+CFG_INIT_RAM_END- 4) +#define DCACHE_STATUS (CFG_INIT_RAM_ADDR+CFG_INIT_RAM_END- 8) +#define CACR_STATUS (CFG_INIT_RAM_ADDR+CFG_INIT_RAM_END-12) + +#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 #CFG_FLASH_BASE, %d0 + movec %d0, %VBR + + move.l #(CFG_INIT_RAM_ADDR + CFG_INIT_RAM_CTRL), %d0 + movec %d0, %RAMBAR0 + + move.l #(CFG_INIT_RAM1_ADDR + CFG_INIT_RAM1_CTRL), %d0 + movec %d0, %RAMBAR1 + + move.l #CFG_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 #(CACR_STATUS), %a3 /* CACR */ + move.l %d0, (%a1) + move.l %d0, (%a2) + move.l %d0, (%a3) + + /* set stackpointer to end of internal ram to get some stackspace for the + first c-code */ + move.l #(CFG_INIT_RAM_ADDR + CFG_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 #CFG_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 - CFG_MONITOR_BASE), %a1 + jmp (%a1) + +in_ram: + +clear_bss: + /* + * Now clear BSS segment + */ + move.l %a0, %a1 + add.l #(_sbss - CFG_MONITOR_BASE),%a1 + move.l %a0, %d1 + add.l #(_ebss - CFG_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 - CFG_MONITOR_BASE),%a1 + move.l %a1,%a5 /* * fix got pointer register a5 */ + + move.l %a0, %a2 + add.l #(__got_end - CFG_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 - CFG_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 + +/*------------------------------------------------------------------------------*/ +/* cache functions */ + .globl icache_enable +icache_enable: + move.l #(CFG_SDRAM_BASE + 0x1c000), %d0 + movec %d0, %ACR2 /* Enable cache */ + + move.l #0x020C8100, %d0 /* Setup cache mask */ + movec %d0, %CACR /* Enable cache */ + nop + + move.l #(ICACHE_STATUS), %a1 + moveq #1, %d0 + move.l %d0, (%a1) + rts + + .globl icache_disable +icache_disable: + move.l #0x000C8100, %d0 /* Setup cache mask */ + movec %d0, %CACR /* Disable cache */ + clr.l %d0 /* Setup cache mask */ + movec %d0, %ACR2 + movec %d0, %ACR3 + + move.l #(ICACHE_STATUS), %a1 + moveq #0, %d0 + move.l %d0, (%a1) + rts + + .globl icache_invalid +icache_invalid: + move.l #0x000C8100, %d0 /* Setup cache mask */ + movec %d0, %CACR /* Enable cache */ + rts + + .globl icache_status +icache_status: + move.l #(ICACHE_STATUS), %a1 + move.l (%a1), %d0 + rts + + .globl dcache_enable +dcache_enable: + bsr icache_disable + + move.l #(CFG_SDRAM_BASE + 0xc000), %d0 + movec %d0, %ACR0 /* Enable cache */ + + move.l #0xA30C8100, %d0 /* Invalidate cache cmd */ + movec %d0, %CACR /* Invalidate cache */ + + move.l #(DCACHE_STATUS), %a1 + moveq #1, %d0 + move.l %d0, (%a1) + rts + + .globl dcache_disable +dcache_disable: + move.l #0xA30C8100, %d0 /* Setup cache mask */ + movec %d0, %CACR /* Disable cache */ + clr.l %d0 /* Setup cache mask */ + movec %d0, %ACR0 + movec %d0, %ACR1 + + move.l #(DCACHE_STATUS), %a1 + moveq #0, %d0 + move.l %d0, (%a1) + rts + + .globl dcache_status +dcache_status: + move.l #(DCACHE_STATUS), %a1 + move.l (%a1), %d0 + rts + +/*------------------------------------------------------------------------------*/ + + .globl version_string +version_string: + .ascii U_BOOT_VERSION + .ascii " (", __DATE__, " - ", __TIME__, ")" + .ascii CONFIG_IDENT_STRING, "\0" -- 2.39.5