
This patch adds support for the AT32UC3A0xxx chips.
Signed-off-by: Gunnar Rangoy gunnar@rangoy.com Signed-off-by: Paul Driveklepp pauldriveklepp@gmail.com Signed-off-by: Olav Morken olavmrk@gmail.com --- cpu/at32uc/Makefile | 57 +++++ cpu/at32uc/at32uc3a0xxx/Makefile | 43 ++++ cpu/at32uc/at32uc3a0xxx/clk.c | 88 +++++++ cpu/at32uc/at32uc3a0xxx/portmux.c | 154 ++++++++++++ cpu/at32uc/at32uc3a0xxx/sm.h | 247 +++++++++++++++++++ cpu/at32uc/cache.c | 34 +++ cpu/at32uc/config.mk | 22 ++ cpu/at32uc/cpu.c | 79 ++++++ cpu/at32uc/exception.c | 121 ++++++++++ cpu/at32uc/flashc.c | 144 +++++++++++ cpu/at32uc/flashc.h | 84 +++++++ cpu/at32uc/interrupts.c | 150 ++++++++++++ cpu/at32uc/portmux-gpio.c | 78 ++++++ cpu/at32uc/sdramc.c | 120 ++++++++++ cpu/at32uc/sdramc.h | 137 +++++++++++ cpu/at32uc/smc.c | 61 +++++ cpu/at32uc/smc.h | 105 ++++++++ cpu/at32uc/start.S | 252 ++++++++++++++++++++ include/asm-avr32/arch-at32uc3a0xxx/addrspace.h | 63 +++++ include/asm-avr32/arch-at32uc3a0xxx/cacheflush.h | 41 ++++ .../asm-avr32/arch-at32uc3a0xxx/chip-features.h | 30 +++ include/asm-avr32/arch-at32uc3a0xxx/clk.h | 85 +++++++ include/asm-avr32/arch-at32uc3a0xxx/gpio-impl.h | 62 +++++ include/asm-avr32/arch-at32uc3a0xxx/gpio.h | 44 ++++ include/asm-avr32/arch-at32uc3a0xxx/hmatrix.h | 47 ++++ include/asm-avr32/arch-at32uc3a0xxx/memory-map.h | 75 ++++++ include/asm-avr32/arch-at32uc3a0xxx/portmux.h | 80 ++++++ include/asm-avr32/sram.h | 34 +++ 28 files changed, 2537 insertions(+), 0 deletions(-) create mode 100644 cpu/at32uc/Makefile create mode 100644 cpu/at32uc/at32uc3a0xxx/Makefile create mode 100644 cpu/at32uc/at32uc3a0xxx/clk.c create mode 100644 cpu/at32uc/at32uc3a0xxx/portmux.c create mode 100644 cpu/at32uc/at32uc3a0xxx/sm.h create mode 100644 cpu/at32uc/cache.c create mode 100644 cpu/at32uc/config.mk create mode 100644 cpu/at32uc/cpu.c create mode 100644 cpu/at32uc/exception.c create mode 100644 cpu/at32uc/flashc.c create mode 100644 cpu/at32uc/flashc.h create mode 100644 cpu/at32uc/interrupts.c create mode 100644 cpu/at32uc/portmux-gpio.c create mode 100644 cpu/at32uc/sdramc.c create mode 100644 cpu/at32uc/sdramc.h create mode 100644 cpu/at32uc/smc.c create mode 100644 cpu/at32uc/smc.h create mode 100644 cpu/at32uc/start.S create mode 100644 include/asm-avr32/arch-at32uc3a0xxx/addrspace.h create mode 100644 include/asm-avr32/arch-at32uc3a0xxx/cacheflush.h create mode 100644 include/asm-avr32/arch-at32uc3a0xxx/chip-features.h create mode 100644 include/asm-avr32/arch-at32uc3a0xxx/clk.h create mode 100644 include/asm-avr32/arch-at32uc3a0xxx/gpio-impl.h create mode 100644 include/asm-avr32/arch-at32uc3a0xxx/gpio.h create mode 100644 include/asm-avr32/arch-at32uc3a0xxx/hmatrix.h create mode 100644 include/asm-avr32/arch-at32uc3a0xxx/memory-map.h create mode 100644 include/asm-avr32/arch-at32uc3a0xxx/portmux.h create mode 100644 include/asm-avr32/sram.h
diff --git a/cpu/at32uc/Makefile b/cpu/at32uc/Makefile new file mode 100644 index 0000000..6714d14 --- /dev/null +++ b/cpu/at32uc/Makefile @@ -0,0 +1,57 @@ +# +# (C) Copyright 2000-2006 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# Copyright (C) 2005-2006 Atmel Corporation. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +include $(TOPDIR)/config.mk + +LIB := $(obj)lib$(CPU).a + +START-y += start.o + +COBJS-y += cpu.o +COBJS-y += sdramc.o +COBJS-y += exception.o +COBJS-y += cache.o +COBJS-y += interrupts.o +COBJS-$(CONFIG_PORTMUX_GPIO) += portmux-gpio.o +COBJS-y += flashc.o +COBJS-y += smc.o + +SRCS := $(START-y:.o=.S) $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c) +OBJS := $(addprefix $(obj),$(SOBJS-y) $(COBJS-y)) +START := $(addprefix $(obj),$(START-y)) + +all: $(obj).depend $(START) $(LIB) + +$(LIB): $(OBJS) + $(AR) $(ARFLAGS) $@ $^ + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/cpu/at32uc/at32uc3a0xxx/Makefile b/cpu/at32uc/at32uc3a0xxx/Makefile new file mode 100644 index 0000000..4942e56 --- /dev/null +++ b/cpu/at32uc/at32uc3a0xxx/Makefile @@ -0,0 +1,43 @@ +# +# Copyright (C) 2005-2006 Atmel Corporation +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +include $(TOPDIR)/config.mk + +LIB := $(obj)lib$(SOC).a + +COBJS := clk.o portmux.o +SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) + +all: $(obj).depend $(LIB) + +$(LIB): $(OBJS) + $(AR) $(ARFLAGS) $@ $^ + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/cpu/at32uc/at32uc3a0xxx/clk.c b/cpu/at32uc/at32uc3a0xxx/clk.c new file mode 100644 index 0000000..7d4f813 --- /dev/null +++ b/cpu/at32uc/at32uc3a0xxx/clk.c @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2005-2008 Atmel Corporation + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ +#include <common.h> + +#include <asm/io.h> + +#include <asm/arch/clk.h> +#include <asm/arch/memory-map.h> + +#include "sm.h" + +void clk_init(void) +{ + uint32_t cksel; + + /* in case of soft resets, disable watchdog */ + sm_writel(WDT_CTRL, SM_BF(KEY, 0x55)); + sm_writel(WDT_CTRL, SM_BF(KEY, 0xaa)); + + /* osc0 is 12mhz (Mode 7)*/ + sm_writel(PM_OSCCTRL0, (SM_BF(MODE, 7)|SM_BF(STARTUP, 1))); + + /* enable osc0 */ + sm_writel(PM_MCCTRL, SM_BIT(OSC0EN)); + + /* wait for osc0 */ + while (!(sm_readl(PM_POSCSR) & SM_BIT(OSC0RDY))) + ; + + /* run from osc0 */ + sm_writel(PM_MCCTRL, SM_BF(MCSEL, 1) | SM_BIT(OSC0EN)); + +#ifdef CONFIG_PLL + /* Initialize the PLL */ + sm_writel(PM_PLL0, (SM_BF(PLLCOUNT, CFG_PLL0_SUPPRESS_CYCLES) + | SM_BF(PLLMUL, CFG_PLL0_MUL - 1) + | SM_BF(PLLDIV, CFG_PLL0_DIV) + | SM_BF(PLLOPT, CFG_PLL0_OPT) + | SM_BF(PLLOSC, 0) + | SM_BIT(PLLEN) + | SM_BIT(ERRATA))); + + /* Wait for lock */ + while (!(sm_readl(PM_POSCSR) & SM_BIT(LOCK0))) + ; +#endif + + /* We cannot write the CKSEL register before the ready-signal is set. */ + while (!(sm_readl(PM_POSCSR) & SM_BIT(CKRDY))) + ; + + /* Set up clocks for the CPU and all peripheral buses */ + cksel = 0; + if (CFG_CLKDIV_CPU) + cksel |= SM_BIT(CPUDIV) | SM_BF(CPUSEL, CFG_CLKDIV_CPU - 1); + if (CFG_CLKDIV_PBA) + cksel |= SM_BIT(PBADIV) | SM_BF(PBASEL, CFG_CLKDIV_PBA - 1); + if (CFG_CLKDIV_PBB) + cksel |= SM_BIT(PBBDIV) | SM_BF(PBBSEL, CFG_CLKDIV_PBB - 1); + + + sm_writel(PM_CKSEL, cksel); + +#ifdef CONFIG_PLL + /* Use PLL0 as main clock */ + sm_writel(PM_MCCTRL, SM_BF(MCSEL, 2) | SM_BIT(OSC0EN)); +#endif + +} diff --git a/cpu/at32uc/at32uc3a0xxx/portmux.c b/cpu/at32uc/at32uc3a0xxx/portmux.c new file mode 100644 index 0000000..a796f22 --- /dev/null +++ b/cpu/at32uc/at32uc3a0xxx/portmux.c @@ -0,0 +1,154 @@ +/* + * Copyright (C) 2006, 2008 Atmel Corporation + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ +#include <common.h> + +#include <asm/io.h> + +#include <asm/arch/chip-features.h> +#include <asm/arch/memory-map.h> +#include <asm/arch/portmux.h> + +/* + * Lots of small functions here. We depend on --gc-sections getting + * rid of the ones we don't need. + */ +void portmux_enable_ebi(unsigned int bus_width, unsigned int addr_width, + unsigned long flags, unsigned long drive_strength) +{ + /* + * GPIO pins to be set to enable all EBI pins + * + * PIN 14-17 function C port0 mask 00 03 C0 00 + * PIN 25-28 function C port0 mask 1E 00 00 00 + * PIN 36 function C port1 mask 00 00 00 10 + * PIN 42-46 function C port1 mask 00 00 7C 00 + * PIN 48-49 function C port1 mask 00 03 00 00 + * PIN 61-63 function C port1 mask E0 00 00 00 + * PIN 70-95 function A port2 mask FF FF FF C0 + * PIN 96-109 function A port3 mask 00 00 3F FF + */ + + portmux_select_peripheral(PORTMUX_PORT(0), + 0x0003C000 | + 0x1E000000, PORTMUX_FUNC_C, 0); + portmux_select_peripheral(PORTMUX_PORT(1), + 0x00000010 | + 0x00007C00 | + 0x00030000 | + 0xE0000000, PORTMUX_FUNC_C, 0); + portmux_select_peripheral(PORTMUX_PORT(2), + 0xFFFFFFC0, PORTMUX_FUNC_A, 0); + portmux_select_peripheral(PORTMUX_PORT(3), + 0x00003FFF, PORTMUX_FUNC_A, 0); +} + +#ifdef AT32UC3A0xxx_CHIP_HAS_MACB +void portmux_enable_macb(unsigned long flags, unsigned long drive_strength) +{ + unsigned long portb_mask; + + portb_mask = (1 << 2) /* TXD0 */ + | (1 << 3) /* TXD1 */ + | (1 << 1) /* TXEN */ + | (1 << 0) /* TXCK */ + | (1 << 5) /* RXD0 */ + | (1 << 6) /* RXD1 */ + | (1 << 7) /* RXER */ + | (1 << 15) /* RXDV */ + | (1 << 8) /* MDC */ + | (1 << 9); /* MDIO */ + + if (flags & PORTMUX_MACB_MII) + portb_mask |= (1 << 16) /* COL */ + | (1 << 4) /* CRS */ + | (1 << 12) /* TXER */ + | (1 << 10) /* TXD2 */ + | (1 << 11) /* TXD3 */ + | (1 << 13) /* RXD2 */ + | (1 << 14) /* RXD3 */ + | (1 << 17); /* RXCK */ + + if (flags & PORTMUX_MACB_SPEED) + portb_mask |= (1 << 18);/* SPD */ + + /* REVISIT: Some pins are probably pure outputs */ + portmux_select_peripheral(PORTMUX_PORT_B, portb_mask, + PORTMUX_FUNC_A, PORTMUX_BUSKEEPER); +} + +#endif + + +#ifdef AT32UC3A0xxx_CHIP_HAS_SPI +void portmux_enable_spi0(unsigned long cs_mask, unsigned long drive_strength) +{ + unsigned long pin_mask; + + /* MOSI and SCK */ + portmux_select_peripheral(PORTMUX_PORT_A, (1 << 12) | (1 << 13), + PORTMUX_FUNC_A, 0); + /* MISO may float */ + portmux_select_peripheral(PORTMUX_PORT_A, 1 << 11, + PORTMUX_FUNC_A, PORTMUX_BUSKEEPER); + + /* Set up NPCSx as GPIO outputs, initially high */ + pin_mask = 0; + if (cs_mask & (1 << 0)) + pin_mask |= 1 << 10; + if (cs_mask & (1 << 1)) + pin_mask |= 1 << 8; + if (cs_mask & (1 << 2)) + pin_mask |= 1 << 9; + if (cs_mask & (1 << 3)) + pin_mask |= 1 << 7; + + portmux_select_gpio(PORTMUX_PORT_A, pin_mask, + PORTMUX_DIR_OUTPUT | PORTMUX_INIT_HIGH); +} + +void portmux_enable_spi1(unsigned long cs_mask, unsigned long drive_strength) +{ + unsigned long pin_mask; + + /* MOSI and SCK */ + portmux_select_peripheral(PORTMUX_PORT_B, (1 << 16) | (1 << 15), + PORTMUX_FUNC_B, 0); + /* MISO may float */ + portmux_select_peripheral(PORTMUX_PORT_B, 1 << 17, + PORTMUX_FUNC_B, PORTMUX_BUSKEEPER); + + /* Set up NPCSx as GPIO outputs, initially high */ + pin_mask = 0; + if (cs_mask & (1 << 0)) + pin_mask |= 1 << 14; + if (cs_mask & (1 << 1)) + pin_mask |= 1 << 18; + if (cs_mask & (1 << 2)) + pin_mask |= 1 << 19; + if (cs_mask & (1 << 3)) + pin_mask |= 1 << 20; + + portmux_select_gpio(PORTMUX_PORT_A, pin_mask, + PORTMUX_DIR_OUTPUT | PORTMUX_INIT_HIGH); +} +#endif + diff --git a/cpu/at32uc/at32uc3a0xxx/sm.h b/cpu/at32uc/at32uc3a0xxx/sm.h new file mode 100644 index 0000000..17bff39 --- /dev/null +++ b/cpu/at32uc/at32uc3a0xxx/sm.h @@ -0,0 +1,247 @@ +/* + * Register definitions for System Manager + */ +#ifndef __CPU_AT32UC_SM_H__ +#define __CPU_AT32UC_SM_H__ + +/* SM register offsets */ +/* PM starts at 0xFFFF0C00 */ +#define SM_PM_REGS_OFFSET 0x0c00 +#define SM_PM_MCCTRL (SM_PM_REGS_OFFSET + 0x0000) +#define SM_PM_CKSEL (SM_PM_REGS_OFFSET + 0x0004) +#define SM_PM_CPU_MASK (SM_PM_REGS_OFFSET + 0x0008) +#define SM_PM_HSB_MASK (SM_PM_REGS_OFFSET + 0x000c) +#define SM_PM_PBA_MASK (SM_PM_REGS_OFFSET + 0x0010) +#define SM_PM_PBB_MASK (SM_PM_REGS_OFFSET + 0x0014) +#define SM_PM_PLL0 (SM_PM_REGS_OFFSET + 0x0020) +#define SM_PM_PLL1 (SM_PM_REGS_OFFSET + 0x0024) +#define SM_PM_OSCCTRL0 (SM_PM_REGS_OFFSET + 0x0028) +#define SM_PM_OSCCTRL1 (SM_PM_REGS_OFFSET + 0x002c) +#define SM_PM_OSCCTRL32 (SM_PM_REGS_OFFSET + 0x0030) +#define SM_PM_IER (SM_PM_REGS_OFFSET + 0x0040) +#define SM_PM_IDR (SM_PM_REGS_OFFSET + 0x0044) +#define SM_PM_IMR (SM_PM_REGS_OFFSET + 0x0048) +#define SM_PM_ISR (SM_PM_REGS_OFFSET + 0x004c) +#define SM_PM_ICR (SM_PM_REGS_OFFSET + 0x0050) +#define SM_PM_POSCSR (SM_PM_REGS_OFFSET + 0x0054) +#define SM_PM_GCCTRL (SM_PM_REGS_OFFSET + 0x0060) +#define SM_PM_RCCR (SM_PM_REGS_OFFSET + 0x00c0) +#define SM_PM_BGCR (SM_PM_REGS_OFFSET + 0x00c4) +#define SM_PM_VREGCR (SM_PM_REGS_OFFSET + 0x00c8) +#define SM_PM_BOD (SM_PM_REGS_OFFSET + 0x00d0) +#define SM_PM_RCAUSE (SM_PM_REGS_OFFSET + 0x0140) +/* RTC starts at 0xFFFF0D00 */ +#define SM_RTC_REGS_OFFSET 0x0d00 +#define SM_RTC_CTRL (SM_RTC_REGS_OFFSET + 0x0000) +#define SM_RTC_VAL (SM_RTC_REGS_OFFSET + 0x0004) +#define SM_RTC_TOP (SM_RTC_REGS_OFFSET + 0x0008) +#define SM_RTC_IER (SM_RTC_REGS_OFFSET + 0x0010) +#define SM_RTC_IDR (SM_RTC_REGS_OFFSET + 0x0014) +#define SM_RTC_IMR (SM_RTC_REGS_OFFSET + 0x0018) +#define SM_RTC_ISR (SM_RTC_REGS_OFFSET + 0x001c) +#define SM_RTC_ICR (SM_RTC_REGS_OFFSET + 0x0020) +/* WDT starts at 0xFFFF0D30 */ +#define SM_WDT_REGS_OFFSET 0x0d30 +#define SM_WDT_CTRL (SM_WDT_REGS_OFFSET + 0x0000) +#define SM_WDT_CLR (SM_WDT_REGS_OFFSET + 0x0004) +/* EIC starts at offset 0xFFFF0D80 */ +/* TODO: change EIM to EIC */ +#define SM_EIC_REGS_OFFSET 0x0d80 +#define SM_EIC_IER (SM_EIC_REGS_OFFSET + 0x0000) +#define SM_EIC_IDR (SM_EIC_REGS_OFFSET + 0x0004) +#define SM_EIC_IMR (SM_EIC_REGS_OFFSET + 0x0008) +#define SM_EIC_ISR (SM_EIC_REGS_OFFSET + 0x000c) +#define SM_EIC_ICR (SM_EIC_REGS_OFFSET + 0x0010) +#define SM_EIC_MODE (SM_EIC_REGS_OFFSET + 0x0014) +#define SM_EIC_EDGE (SM_EIC_REGS_OFFSET + 0x0018) +#define SM_EIC_LEVEL (SM_EIC_REGS_OFFSET + 0x001c) +#define SM_EIC_FILTER (SM_EIC_REGS_OFFSET + 0x0020) +#define SM_EIC_TEST (SM_EIC_REGS_OFFSET + 0x0024) +#define SM_EIC_ASYNC (SM_EIC_REGS_OFFSET + 0x0028) +#define SM_EIC_SCAN (SM_EIC_REGS_OFFSET + 0x002c) +#define SM_EIC_EN (SM_EIC_REGS_OFFSET + 0x0030) +#define SM_EIC_DIS (SM_EIC_REGS_OFFSET + 0x0034) +#define SM_EIC_CTRL (SM_EIC_REGS_OFFSET + 0x0038) + +/* Bitfields used in many registers */ +#define SM_EN_OFFSET 0 +#define SM_EN_SIZE 1 + +/* Bitfields in PM_MCCTRL */ +#define SM_MCSEL_OFFSET 0 +#define SM_MCSEL_SIZE 2 +#define SM_OSC0EN_OFFSET 2 +#define SM_OSC0EN_SIZE 1 +#define SM_OSC1EN_OFFSET 3 +#define SM_OSC1EN_SIZE 1 + +/* Bitfields in PM_CKSEL */ +#define SM_CPUSEL_OFFSET 0 +#define SM_CPUSEL_SIZE 3 +#define SM_CPUDIV_OFFSET 7 +#define SM_CPUDIV_SIZE 1 +#define SM_HSBSEL_OFFSET 8 +#define SM_HSBSEL_SIZE 3 +#define SM_HSBDIV_OFFSET 15 +#define SM_HSBDIV_SIZE 1 +#define SM_PBASEL_OFFSET 16 +#define SM_PBASEL_SIZE 3 +#define SM_PBADIV_OFFSET 23 +#define SM_PBADIV_SIZE 1 +#define SM_PBBSEL_OFFSET 24 +#define SM_PBBSEL_SIZE 3 +#define SM_PBBDIV_OFFSET 31 +#define SM_PBBDIV_SIZE 1 + +/* Bitfields in PM_PLL0 */ +#define SM_PLLEN_OFFSET 0 +#define SM_PLLEN_SIZE 1 +#define SM_PLLOSC_OFFSET 1 +#define SM_PLLOSC_SIZE 1 +#define SM_PLLOPT_OFFSET 2 +#define SM_PLLOPT_SIZE 3 +#define SM_ERRATA_OFFSET 7 +#define SM_ERRATA_SIZE 1 +#define SM_PLLDIV_OFFSET 8 +#define SM_PLLDIV_SIZE 4 +#define SM_PLLMUL_OFFSET 16 +#define SM_PLLMUL_SIZE 4 +#define SM_PLLCOUNT_OFFSET 24 +#define SM_PLLCOUNT_SIZE 6 + +/* Bitfields in PM_OSCCTRL0,1 */ +#define SM_MODE_OFFSET 0 +#define SM_MODE_SIZE 3 +#define SM_STARTUP_OFFSET 8 +#define SM_STARTUP_SIZE 3 + + +/* Bitfields in PM_IER/IDR/IMR/ISR/ICR, POSCSR */ +#define SM_LOCK0_OFFSET 0 +#define SM_LOCK0_SIZE 1 +#define SM_LOCK1_OFFSET 1 +#define SM_LOCK1_SIZE 1 +#define SM_CKRDY_OFFSET 5 +#define SM_CKRDY_SIZE 1 +#define SM_MSKRDY_OFFSET 6 +#define SM_MSKRDY_SIZE 1 +#define SM_OSC0RDY_OFFSET 7 +#define SM_OSC0RDY_SIZE 1 +#define SM_OSC1RDY_OFFSET 8 +#define SM_OSC1RDY_SIZE 1 +#define SM_OSC32RDY_OFFSET 9 +#define SM_OSC32RDY_SIZE 1 +#define SM_BODDET_OFFSET 16 +#define SM_BODDET_SIZE 1 + +/* Bitfields in PM_GCCTRL*/ +#define SM_OSCSEL_OFFSET 0 +#define SM_OSCSEL_SIZE 1 +#define SM_PLLSEL_OFFSET 1 +#define SM_PLLSEL_SIZE 1 +#define SM_CEN_OFFSET 2 +#define SM_CEN_SIZE 1 +#define SM_DIVEN_OFFSET 4 +#define SM_DIVEN_SIZE 1 +#define SM_DIV_OFFSET 8 +#define SM_DIV_SIZE 8 + +/* Bitfields in PM_RCAUSE */ +#define SM_POR_OFFSET 0 +#define SM_POR_SIZE 1 +#define SM_BOD_OFFSET 1 +#define SM_BOD_SIZE 1 +#define SM_EXT_OFFSET 2 +#define SM_EXT_SIZE 1 +#define SM_WDT_OFFSET 3 +#define SM_WDT_SIZE 1 +#define SM_JTAG_OFFSET 4 +#define SM_JTAG_SIZE 1 +#define SM_CPUERR_OFFSET 7 +#define SM_CPUERR_SIZE 1 +#define SM_OCDRST_OFFSET 8 +#define SM_OCDRST_SIZE 1 +#define SM_JTAGHARD_OFFSET 9 +#define SM_JTAGHARD_SIZE 1 + + +/* Bitfields in RTC_CTRL */ +#define SM_PCLR_OFFSET 1 +#define SM_PCLR_SIZE 1 +#define SM_WAKE_EN_OFFSET 2 +#define SM_WAKE_EN_SIZE 1 +#define SM_CLK32_OFFSET 3 +#define SM_CLK32_SIZE 1 +#define SM_BUSY_OFFSET 4 +#define SM_BUSY_SIZE 1 +#define SM_RTC_CTRL_PSEL_OFFSET 8 +#define SM_RTC_CTRL_PSEL_SIZE 4 +#define SM_CLKEN_OFFSET 16 +#define SM_CLKEN_SIZE 1 + +/* Bitfields in RTC_VAL */ +#define SM_RTC_VAL_VAL_OFFSET 0 +#define SM_RTC_VAL_VAL_SIZE 32 + +/* Bitfields in RTC_TOP */ +#define SM_RTC_TOP_VAL_OFFSET 0 +#define SM_RTC_TOP_VAL_SIZE 32 + +/* Bitfields in RTC_ICR */ +#define SM_TOPI_OFFSET 0 +#define SM_TOPI_SIZE 1 + + +/* Bitfields in WDT_CTRL */ +#define SM_WDT_CTRL_PSEL_OFFSET 8 +#define SM_WDT_CTRL_PSEL_SIZE 5 +#define SM_KEY_OFFSET 24 +#define SM_KEY_SIZE 8 + + +/* Bitfields in EIC IER/IDR/IMR/ISR/ICR and MODE/EDGE/LEVEL/FILTER/ASYNC */ +#define SM_INT0_OFFSET 0 +#define SM_INT0_SIZE 1 +#define SM_INT1_OFFSET 1 +#define SM_INT1_SIZE 1 +#define SM_INT2_OFFSET 2 +#define SM_INT2_SIZE 1 +#define SM_INT3_OFFSET 3 +#define SM_INT3_SIZE 1 +#define SM_INT4_OFFSET 4 +#define SM_INT4_SIZE 1 +#define SM_INT5_OFFSET 5 +#define SM_INT5_SIZE 1 +#define SM_INT6_OFFSET 6 +#define SM_INT6_SIZE 1 +#define SM_INT7_OFFSET 7 +#define SM_INT7_SIZE 1 +#define SM_NMI_OFFSET 8 +#define SM_NMI_SIZE 1 + +/* Bitfields in EIM_TEST */ +#define SM_TESTEN_OFFSET 31 +#define SM_TESTEN_SIZE 1 + + +/* Bit manipulation macros */ +#define SM_BIT(name) \ + (1 << SM_##name##_OFFSET) +#define SM_BF(name,value) \ + (((value) & ((1 << SM_##name##_SIZE) - 1)) \ + << SM_##name##_OFFSET) +#define SM_BFEXT(name,value) \ + (((value) >> SM_##name##_OFFSET) \ + & ((1 << SM_##name##_SIZE) - 1)) +#define SM_BFINS(name,value,old) \ + (((old) & ~(((1 << SM_##name##_SIZE) - 1) \ + << SM_##name##_OFFSET)) \ + | SM_BF(name,value)) + +/* Register access macros */ +#define sm_readl(reg) \ + readl((void *)SM_BASE + SM_##reg) +#define sm_writel(reg,value) \ + writel((value), (void *)SM_BASE + SM_##reg) + +#endif /* __CPU_AT32UC_SM_H__ */ diff --git a/cpu/at32uc/cache.c b/cpu/at32uc/cache.c new file mode 100644 index 0000000..d624e6f --- /dev/null +++ b/cpu/at32uc/cache.c @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2004-2006 Atmel Corporation + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> + +/* + * This is called after loading something into memory. We need to + * make sure that everything that was loaded is actually written to + * RAM, and that the icache will look for it. Cleaning the dcache and + * invalidating the icache will do the trick. + */ +void flush_cache(unsigned long start_addr, unsigned long size) +{ + /* No cache to clean in the at32uc3. */ +} diff --git a/cpu/at32uc/config.mk b/cpu/at32uc/config.mk new file mode 100644 index 0000000..1a6eaa8 --- /dev/null +++ b/cpu/at32uc/config.mk @@ -0,0 +1,22 @@ +# +# Copyright (C) 2005-2006 Atmel Corporation +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# +PLATFORM_RELFLAGS += -mcpu=uc3a0512es diff --git a/cpu/at32uc/cpu.c b/cpu/at32uc/cpu.c new file mode 100644 index 0000000..d145e1d --- /dev/null +++ b/cpu/at32uc/cpu.c @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2005-2006 Atmel Corporation + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ +#include <common.h> +#include <command.h> + +#include <asm/io.h> +#include <asm/sections.h> +#include <asm/sysreg.h> + +#include <asm/arch/clk.h> +#include <asm/arch/memory-map.h> + +/* Sanity checks */ +#if ((CFG_CLKDIV_CPU > CFG_CLKDIV_PBA) \ + || (CFG_CLKDIV_CPU > CFG_CLKDIV_PBB)) +# error Constraint fCPU >= fPB{A,B} violated +#endif +#if defined(CONFIG_PLL) && ((CFG_PLL0_MUL < 1) || (CFG_PLL0_DIV < 0)) +# error Invalid PLL multiplier and/or divider +#endif + +DECLARE_GLOBAL_DATA_PTR; + +int cpu_init(void) +{ + extern void _evba(void); + + gd->cpu_hz = CFG_OSC0_HZ; + + clk_init(); + + /* Update the CPU speed according to the PLL configuration */ + gd->cpu_hz = get_cpu_clk_rate(); + + /* Set up the exception handler table and enable exceptions */ + sysreg_write(EVBA, (unsigned long)&_evba); + asm volatile("csrf %0" : : "i"(SYSREG_EM_OFFSET)); + + if (gclk_init) + gclk_init(); + + return 0; +} + +void prepare_to_boot(void) +{ + /* No caches to flush on this cpu. */ +} + +int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +{ + /* This will reset the CPU core, caches, MMU and all internal busses */ + __builtin_mtdr(8, 1 << 13); /* set DC:DBE */ + __builtin_mtdr(8, 1 << 30); /* set DC:RES */ + + /* Flush the pipeline before we declare it a failure */ + asm volatile("sub pc, pc, -4"); + + return -1; +} diff --git a/cpu/at32uc/exception.c b/cpu/at32uc/exception.c new file mode 100644 index 0000000..dc9c300 --- /dev/null +++ b/cpu/at32uc/exception.c @@ -0,0 +1,121 @@ +/* + * Copyright (C) 2005-2006 Atmel Corporation + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ +#include <common.h> + +#include <asm/sysreg.h> +#include <asm/ptrace.h> + +DECLARE_GLOBAL_DATA_PTR; + +static const char * const cpu_modes[8] = { + "Application", "Supervisor", "Interrupt level 0", "Interrupt level 1", + "Interrupt level 2", "Interrupt level 3", "Exception", "NMI" +}; + +static void dump_mem(const char *str, unsigned long bottom, unsigned long top) +{ + unsigned long p; + int i; + + printf("%s(0x%08lx to 0x%08lx)\n", str, bottom, top); + + for (p = bottom & ~31; p < top; ) { + printf("%04lx: ", p & 0xffff); + + for (i = 0; i < 8; i++, p += 4) { + unsigned int val; + + if (p < bottom || p >= top) + printf(" "); + else { + val = *(unsigned long *)p; + printf("%08x ", val); + } + } + printf("\n"); + } +} + +void do_unknown_exception(unsigned int ecr, struct pt_regs *regs) +{ + unsigned int mode; + + printf("\n *** Unhandled exception %u at PC=0x%08lx\n", ecr, regs->pc); + + switch (ecr) { + case ECR_BUS_ERROR_WRITE: + case ECR_BUS_ERROR_READ: + printf("Bus error at address 0x%08lx\n", + sysreg_read(BEAR)); + break; + case ECR_TLB_MULTIPLE: + case ECR_ADDR_ALIGN_X: + case ECR_PROTECTION_X: + case ECR_ADDR_ALIGN_R: + case ECR_ADDR_ALIGN_W: + case ECR_PROTECTION_R: + case ECR_PROTECTION_W: + case ECR_DTLB_MODIFIED: + case ECR_TLB_MISS_X: + case ECR_TLB_MISS_R: + case ECR_TLB_MISS_W: + printf("MMU exception at address 0x%08lx\n", + sysreg_read(TLBEAR)); + break; + } + + printf(" pc: %08lx lr: %08lx sp: %08lx r12: %08lx\n", + regs->pc, regs->lr, regs->sp, regs->r12); + printf(" r11: %08lx r10: %08lx r9: %08lx r8: %08lx\n", + regs->r11, regs->r10, regs->r9, regs->r8); + printf(" r7: %08lx r6: %08lx r5: %08lx r4: %08lx\n", + regs->r7, regs->r6, regs->r5, regs->r4); + printf(" r3: %08lx r2: %08lx r1: %08lx r0: %08lx\n", + regs->r3, regs->r2, regs->r1, regs->r0); + printf("Flags: %c%c%c%c%c\n", + regs->sr & SR_Q ? 'Q' : 'q', + regs->sr & SR_V ? 'V' : 'v', + regs->sr & SR_N ? 'N' : 'n', + regs->sr & SR_Z ? 'Z' : 'z', + regs->sr & SR_C ? 'C' : 'c'); + printf("Mode bits: %c%c%c%c%c%c%c%c%c\n", + regs->sr & SR_H ? 'H' : 'h', + regs->sr & SR_R ? 'R' : 'r', + regs->sr & SR_J ? 'J' : 'j', + regs->sr & SR_EM ? 'E' : 'e', + regs->sr & SR_I3M ? '3' : '.', + regs->sr & SR_I2M ? '2' : '.', + regs->sr & SR_I1M ? '1' : '.', + regs->sr & SR_I0M ? '0' : '.', + regs->sr & SR_GM ? 'G' : 'g'); + mode = (regs->sr >> SYSREG_M0_OFFSET) & 7; + printf("CPU Mode: %s\n", cpu_modes[mode]); + + /* Avoid exception loops */ + if (regs->sp < (gd->stack_end - CONFIG_STACKSIZE) + || regs->sp >= gd->stack_end) + printf("\nStack pointer seems bogus, won't do stack dump\n"); + else + dump_mem("\nStack: ", regs->sp, gd->stack_end); + + panic("Unhandled exception\n"); +} diff --git a/cpu/at32uc/flashc.c b/cpu/at32uc/flashc.c new file mode 100644 index 0000000..2244b2e --- /dev/null +++ b/cpu/at32uc/flashc.c @@ -0,0 +1,144 @@ +/* + * Copyright (C) 2005-2006 Atmel Corporation + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ +#include <common.h> + +#include <asm/io.h> +#include <asm/arch/memory-map.h> +#include "flashc.h" + +DECLARE_GLOBAL_DATA_PTR; + +/* Flash sizes in KB as returned by FSZ bitfield in FSR */ +const unsigned long flash_sizes[8] = { + 32, + 64, + 128, + 256, + 384, + 512, + 768, + 1024 +}; + +flash_info_t flash_info[1]; + +unsigned long flash_init(void) +{ + unsigned long fsz; + unsigned long size; + unsigned int i; + + fsz = FLASHC_BFEXT(FSZ, flashc_readl(FSR)); + + size = flash_sizes[fsz] * 1024; + + flash_info[0].size = size; + + /* Currently, all interflash have pages which are 128 words. */ + flash_info[0].sector_count = size / (128*4); + + for (i = 0; i < flash_info[0].sector_count; i++) { + flash_info[0].start[i] = i*128*4 + CFG_FLASH_BASE; + } + + return size; +} + +void flash_print_info(flash_info_t *info) +{ + printf("Flash: Vendor ID: 0x%02lx, Product ID: 0x%02lx\n", + info->flash_id >> 16, info->flash_id & 0xffff); + printf("Size: %ld kB in %d sectors\n", + info->size >> 10, info->sector_count); +} + +static void flash_wait_ready(void) +{ + while (!flashc_readl(FSR) & FLASHC_BIT(FRDY)) + ; +} + +int flash_erase(flash_info_t *info, int s_first, int s_last) +{ + int page; + + for (page = s_first; page < s_last; page++) { + flash_wait_ready(); + flashc_writel(FCMD, + FLASHC_BF(CMD, FLASHC_EP) | + FLASHC_BF(PAGEN, page) | + FLASHC_BF(KEY, 0xa5)); + } + return ERR_OK; +} + +static void write_flash_page(unsigned int pagen, const u32 *data) +{ + unsigned int i; + u32 *dst; + + dst = (u32 *) CFG_FLASH_BASE; + + /* clear page buffer */ + flash_wait_ready(); + flashc_writel(FCMD, + FLASHC_BF(CMD, FLASHC_CPB) | + FLASHC_BF(KEY, 0xa5)); + + /* fill page buffer*/ + flash_wait_ready(); + for (i = 0; i < 128; i++) { + dst[i] = data[i]; + } + + /* issue write command */ + flashc_writel(FCMD, + FLASHC_BF(CMD, FLASHC_WP) | + FLASHC_BF(PAGEN, pagen) | + FLASHC_BF(KEY, 0xa5)); +} + +int write_buff(flash_info_t *info, uchar *src, ulong addr, ulong count) +{ + unsigned int i; + + if (addr % (4*128)) { + printf("flash: write_buff(): ERROR, addr(0x%08lx) not " + "on page boundary", addr); + return ERR_ALIGN; + } + if (count % (4*128)) { + printf("flash: write_buff(): ERROR, count(0x%lu) not " + "a multiple of pagesize", count); + return ERR_ALIGN; + } + + for (i = 0; i < count; i += 128*4) { + unsigned int pagen; + pagen = (addr-CFG_FLASH_BASE+i) / (128*4); + write_flash_page(pagen, (u32 *) (src+i)); + } + + + return ERR_OK; +} + diff --git a/cpu/at32uc/flashc.h b/cpu/at32uc/flashc.h new file mode 100644 index 0000000..3e97781 --- /dev/null +++ b/cpu/at32uc/flashc.h @@ -0,0 +1,84 @@ +/* + * Register definitions for flash controller + */ +#ifndef __ASM_AVR32_FLASHC_H__ +#define __ASM_AVR32_FLASHC_H__ + +/* FLASHC register offsets */ +#define FLASHC_FCR 0x0000 +#define FLASHC_FCMD 0x0004 +#define FLASHC_FSR 0x0008 +#define FLASHC_FGPFRHI 0x000c +#define FLASHC_FGPFRLO 0x0010 + +/* Bitfields in FCR and FSR */ +#define FLASHC_FRDY_OFFSET 0 +#define FLASHC_FRDY_SIZE 1 +#define FLASHC_LOCKE_OFFSET 2 +#define FLASHC_LOCKE_SIZE 1 +#define FLASHC_PROGE_OFFSET 3 +#define FLASHC_PROGE_SIZE 1 + +/* Bitfields in FCR */ +#define FLASHC_FWS_OFFSET 6 +#define FLASHC_FWS_SIZE 1 +#define FLASHC_SASD_OFFSET 8 +#define FLASHC_SASD_SIZE 1 + +/* Bitfields in FCMD */ +#define FLASHC_CMD_OFFSET 0 +#define FLASHC_CMD_SIZE 6 +#define FLASHC_PAGEN_OFFSET 8 +#define FLASHC_PAGEN_SIZE 16 +#define FLASHC_KEY_OFFSET 24 +#define FLASHC_KEY_SIZE 8 + +/* Bitfields in FSR */ +#define FLASHC_SECURITY_OFFSET 4 +#define FLASHC_SECURITY_SIZE 1 +#define FLASHC_QPRR_OFFSET 5 +#define FLASHC_QPRR_SIZE 1 +#define FLASHC_FSZ_OFFSET 13 +#define FLASHC_FSZ_SIZE 3 +#define FLASHC_LOCK_OFFSET 16 +#define FLASHC_LOCK_SIZE 16 + +#define FLASHC_NOP 0 /*No operation*/ +#define FLASHC_WP 1 /*Write Page*/ +#define FLASHC_EP 2 /*Erase Page*/ +#define FLASHC_CPB 3 /*Clear Page Buffer*/ +#define FLASHC_LP 4 /*Lock region containing given Page*/ +#define FLASHC_UP 5 /*Unlock region containing given Page*/ +#define FLASHC_EA 6 /*Erase All*/ +#define FLASHC_WGPB 7 /*Write General-Purpose Fuse Bit*/ +#define FLASHC_EGPB 8 /*Erase General-Purpose Fuse Bit*/ +#define FLASHC_SSB 9 /*Set Security Bit*/ +#define FLASHC_PGPFB 10 /*Program GP Fuse Byte*/ +#define FLASHC_EAGPF 11 /*Erase All GPFuses*/ +#define FLASHC_QPR 12 /*Quick Page Read*/ +#define FLASHC_WUP 13 /*Write User Page*/ +#define FLASHC_EUP 14 /*Erase User Page*/ +#define FLASHC_QPRUP 15 /*Quick Page Read User Page*/ + + +/* Bit manipulation macros */ +#define FLASHC_BIT(name) \ + (1 << FLASHC_##name##_OFFSET) +#define FLASHC_BF(name,value) \ + (((value) & ((1 << FLASHC_##name##_SIZE) - 1)) \ + << FLASHC_##name##_OFFSET) +#define FLASHC_BFEXT(name,value) \ + (((value) >> FLASHC_##name##_OFFSET) \ + & ((1 << FLASHC_##name##_SIZE) - 1)) +#define FLASHC_BFINS(name,value,old) \ + (((old) & ~(((1 << FLASHC_##name##_SIZE) - 1) \ + << FLASHC_##name##_OFFSET)) \ + | FLASHC_BF(name,value)) + +/* Register access macros */ +#define flashc_readl(reg) \ + readl((void *)FLASHC_BASE + FLASHC_##reg) +#define flashc_writel(reg,value) \ + writel((value), (void *)FLASHC_BASE + FLASHC_##reg) + +#endif /* __ASM_AVR32_FLASHC_H__ */ diff --git a/cpu/at32uc/interrupts.c b/cpu/at32uc/interrupts.c new file mode 100644 index 0000000..160838e --- /dev/null +++ b/cpu/at32uc/interrupts.c @@ -0,0 +1,150 @@ +/* + * Copyright (C) 2004-2006 Atmel Corporation + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ +#include <common.h> +#include <div64.h> + +#include <asm/errno.h> +#include <asm/io.h> +#include <asm/processor.h> +#include <asm/sysreg.h> + +#include <asm/arch/memory-map.h> + +#define HANDLER_MASK 0x00ffffff +#define INTLEV_SHIFT 30 +#define INTLEV_MASK 0x00000003 + +DECLARE_GLOBAL_DATA_PTR; + +/* Incremented whenever COUNT reaches 0xffffffff by timer_interrupt_handler */ +volatile unsigned long timer_overflow; + +/* + * Instead of dividing by get_tbclk(), multiply by this constant and + * right-shift the result by 32 bits. + */ +static unsigned long tb_factor; + +unsigned long get_tbclk(void) +{ + return gd->cpu_hz; +} + +unsigned long long get_ticks(void) +{ + unsigned long lo, hi_now, hi_prev; + + do { + hi_prev = timer_overflow; + lo = sysreg_read(COUNT); + hi_now = timer_overflow; + } while (hi_prev != hi_now); + + return ((unsigned long long)hi_now << 32) | lo; +} + +void reset_timer(void) +{ + sysreg_write(COUNT, 0); + cpu_sync_pipeline(); /* process any pending interrupts */ + timer_overflow = 0; +} + +unsigned long get_timer(unsigned long base) +{ + u64 now = get_ticks(); + + now *= tb_factor; + return (unsigned long)(now >> 32) - base; +} + +void set_timer(unsigned long t) +{ + unsigned long long ticks = t; + unsigned long lo, hi, hi_new; + + ticks = (ticks * get_tbclk()) / CFG_HZ; + hi = ticks >> 32; + lo = ticks & 0xffffffffUL; + + do { + timer_overflow = hi; + sysreg_write(COUNT, lo); + hi_new = timer_overflow; + } while (hi_new != hi); +} + +/* + * For short delays only. It will overflow after a few seconds. + */ +void udelay(unsigned long usec) +{ + unsigned long cycles; + unsigned long base; + unsigned long now; + + base = sysreg_read(COUNT); + cycles = ((usec * (get_tbclk() / 10000)) + 50) / 100; + + do { + now = sysreg_read(COUNT); + } while ((now - base) < cycles); +} + +static int set_interrupt_handler(unsigned int nr, void (*handler)(void), + unsigned int priority) +{ + extern void _evba(void); + unsigned long intpr; + unsigned long handler_addr = (unsigned long)handler; + + handler_addr -= (unsigned long)&_evba; + + if ((handler_addr & HANDLER_MASK) != handler_addr + || (priority & INTLEV_MASK) != priority) + return -EINVAL; + + intpr = (handler_addr & HANDLER_MASK); + intpr |= (priority & INTLEV_MASK) << INTLEV_SHIFT; + writel(intpr, (void *)INTC_BASE + 4 * nr); + + return 0; +} + +void timer_init(void) +{ + extern void timer_interrupt_handler(void); + u64 tmp; + + sysreg_write(COUNT, 0); + + tmp = (u64)CFG_HZ << 32; + tmp += gd->cpu_hz / 2; + do_div(tmp, gd->cpu_hz); + tb_factor = (u32)tmp; + + if (set_interrupt_handler(0, &timer_interrupt_handler, 3)) + return; + + /* For all practical purposes, this gives us an overflow interrupt */ + sysreg_write(COMPARE, 0xffffffff); +} diff --git a/cpu/at32uc/portmux-gpio.c b/cpu/at32uc/portmux-gpio.c new file mode 100644 index 0000000..0b8bae9 --- /dev/null +++ b/cpu/at32uc/portmux-gpio.c @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2008 Atmel Corporation + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ +#include <common.h> + +#include <asm/io.h> +#include <asm/arch/memory-map.h> +#include <asm/arch-common/portmux-gpio.h> + + +void portmux_select_peripheral(void *port, unsigned long pin_mask, + enum portmux_function func, unsigned long flags) +{ + if (flags & PORTMUX_PULL_UP) + gpio_writel(port, PUERS, pin_mask); + else + gpio_writel(port, PUERC, pin_mask); + + /* Select function */ + if (func & PORTMUX_FUNC_B) + gpio_writel(port, PMR0S, pin_mask); + else + gpio_writel(port, PMR0C, pin_mask); + if (func & PORTMUX_FUNC_C) + gpio_writel(port, PMR1S, pin_mask); + else + gpio_writel(port, PMR1C, pin_mask); + + /* Disable GPIO (i.e. enable peripheral) */ + gpio_writel(port, GPERC, pin_mask); +} + +void portmux_select_gpio(void *port, unsigned long pin_mask, + unsigned long flags) +{ + if (flags & PORTMUX_PULL_UP) + gpio_writel(port, PUERS, pin_mask); + else + gpio_writel(port, PUERC, pin_mask); + + /* Enable open-drain mode if requested */ + if (flags & PORTMUX_OPEN_DRAIN) + gpio_writel(port, ODMERS, pin_mask); + else + gpio_writel(port, ODMERC, pin_mask); + + /* Select direction and initial pin state */ + if (flags & PORTMUX_DIR_OUTPUT) { + if (flags & PORTMUX_INIT_HIGH) + gpio_writel(port, OVRS, pin_mask); + else + gpio_writel(port, OVRC, pin_mask); + gpio_writel(port, ODERS, pin_mask); + } else { + gpio_writel(port, ODERC, pin_mask); + } + + /* Enable GPIO */ + gpio_writel(port, GPERS, pin_mask); +} diff --git a/cpu/at32uc/sdramc.c b/cpu/at32uc/sdramc.c new file mode 100644 index 0000000..2ed0066 --- /dev/null +++ b/cpu/at32uc/sdramc.c @@ -0,0 +1,120 @@ +/* + * Copyright (C) 2005-2006 Atmel Corporation + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ +#include <common.h> + +#ifdef CFG_SDRAMC +#include <asm/io.h> +#include <asm/sdram.h> + +#include <asm/arch/clk.h> +#include <asm/arch/memory-map.h> + +#include "sdramc.h" + +unsigned long sdram_init(void *sdram_base, const struct sdram_config *config) +{ + unsigned long sdram_size; + uint32_t cfgreg; + unsigned int i; + + cfgreg = (SDRAMC_BF(NC, config->col_bits - 8) + | SDRAMC_BF(NR, config->row_bits - 11) + | SDRAMC_BF(NB, config->bank_bits - 1) + | SDRAMC_BF(CAS, config->cas) + | SDRAMC_BF(TWR, config->twr) + | SDRAMC_BF(TRC, config->trc) + | SDRAMC_BF(TRP, config->trp) + | SDRAMC_BF(TRCD, config->trcd) + | SDRAMC_BF(TRAS, config->tras) + | SDRAMC_BF(TXSR, config->txsr)); + + if (config->data_bits == SDRAM_DATA_16BIT) + cfgreg |= SDRAMC_BIT(DBW); + + sdramc_writel(CR, cfgreg); + + /* Send a NOP to turn on the clock (necessary on some chips) */ + sdramc_writel(MR, SDRAMC_MODE_NOP); + sdramc_readl(MR); + writel(0, sdram_base); + + /* + * Initialization sequence for SDRAM, from the data sheet: + * + * 1. A minimum pause of 200 us is provided to precede any + * signal toggle. + */ + udelay(200); + + /* + * 2. A Precharge All command is issued to the SDRAM + */ + sdramc_writel(MR, SDRAMC_MODE_BANKS_PRECHARGE); + sdramc_readl(MR); + writel(0, sdram_base); + + /* + * 3. Eight auto-refresh (CBR) cycles are provided + */ + sdramc_writel(MR, SDRAMC_MODE_AUTO_REFRESH); + sdramc_readl(MR); + for (i = 0; i < 8; i++) + writel(0, sdram_base); + + /* + * 4. A mode register set (MRS) cycle is issued to program + * SDRAM parameters, in particular CAS latency and burst + * length. + * + * The address will be chosen by the SDRAMC automatically; we + * just have to make sure BA[1:0] are set to 0. + */ + sdramc_writel(MR, SDRAMC_MODE_LOAD_MODE); + sdramc_readl(MR); + writel(0, sdram_base); + + /* + * 5. The application must go into Normal Mode, setting Mode + * to 0 in the Mode Register and performing a write access + * at any location in the SDRAM. + */ + sdramc_writel(MR, SDRAMC_MODE_NORMAL); + sdramc_readl(MR); + writel(0, sdram_base); + + /* + * 6. Write refresh rate into SDRAMC refresh timer count + * register (refresh rate = timing between refresh cycles). + */ + sdramc_writel(TR, config->refresh_period); + + if (config->data_bits == SDRAM_DATA_16BIT) + sdram_size = 1 << (config->row_bits + config->col_bits + + config->bank_bits + 1); + else + sdram_size = 1 << (config->row_bits + config->col_bits + + config->bank_bits + 2); + + return sdram_size; +} + +#endif /* CFG_SDRAMC */ diff --git a/cpu/at32uc/sdramc.h b/cpu/at32uc/sdramc.h new file mode 100644 index 0000000..8154415 --- /dev/null +++ b/cpu/at32uc/sdramc.h @@ -0,0 +1,137 @@ +/* + * Register definitions for SDRAM Controller + */ +#ifndef __ASM_AVR32_SDRAMC_H__ +#define __ASM_AVR32_SDRAMC_H__ + +/* SDRAMC register offsets */ +#define SDRAMC_MR 0x0000 +#define SDRAMC_TR 0x0004 +#define SDRAMC_CR 0x0008 +#define SDRAMC_HSR 0x000c +#define SDRAMC_LPR 0x0010 +#define SDRAMC_IER 0x0014 +#define SDRAMC_IDR 0x0018 +#define SDRAMC_IMR 0x001c +#define SDRAMC_ISR 0x0020 +#define SDRAMC_MDR 0x0024 + +/* Bitfields in MR */ +#define SDRAMC_MODE_OFFSET 0 +#define SDRAMC_MODE_SIZE 3 + +/* Bitfields in TR */ +#define SDRAMC_COUNT_OFFSET 0 +#define SDRAMC_COUNT_SIZE 12 + +/* Bitfields in CR */ +#define SDRAMC_NC_OFFSET 0 +#define SDRAMC_NC_SIZE 2 +#define SDRAMC_NR_OFFSET 2 +#define SDRAMC_NR_SIZE 2 +#define SDRAMC_NB_OFFSET 4 +#define SDRAMC_NB_SIZE 1 +#define SDRAMC_CAS_OFFSET 5 +#define SDRAMC_CAS_SIZE 2 +#define SDRAMC_DBW_OFFSET 7 +#define SDRAMC_DBW_SIZE 1 +#define SDRAMC_TWR_OFFSET 8 +#define SDRAMC_TWR_SIZE 4 +#define SDRAMC_TRC_OFFSET 12 +#define SDRAMC_TRC_SIZE 4 +#define SDRAMC_TRP_OFFSET 16 +#define SDRAMC_TRP_SIZE 4 +#define SDRAMC_TRCD_OFFSET 20 +#define SDRAMC_TRCD_SIZE 4 +#define SDRAMC_TRAS_OFFSET 24 +#define SDRAMC_TRAS_SIZE 4 +#define SDRAMC_TXSR_OFFSET 28 +#define SDRAMC_TXSR_SIZE 4 + +/* Bitfields in HSR */ +#define SDRAMC_DA_OFFSET 0 +#define SDRAMC_DA_SIZE 1 + +/* Bitfields in LPR */ +#define SDRAMC_LPCB_OFFSET 0 +#define SDRAMC_LPCB_SIZE 2 +#define SDRAMC_PASR_OFFSET 4 +#define SDRAMC_PASR_SIZE 3 +#define SDRAMC_TCSR_OFFSET 8 +#define SDRAMC_TCSR_SIZE 2 +#define SDRAMC_DS_OFFSET 10 +#define SDRAMC_DS_SIZE 2 +#define SDRAMC_TIMEOUT_OFFSET 12 +#define SDRAMC_TIMEOUT_SIZE 2 + +/* Bitfields in IDR */ +#define SDRAMC_RES_OFFSET 0 +#define SDRAMC_RES_SIZE 1 + +/* Bitfields in MDR */ +#define SDRAMC_MD_OFFSET 0 +#define SDRAMC_MD_SIZE 2 + +/* Constants for MODE */ +#define SDRAMC_MODE_NORMAL 0 +#define SDRAMC_MODE_NOP 1 +#define SDRAMC_MODE_BANKS_PRECHARGE 2 +#define SDRAMC_MODE_LOAD_MODE 3 +#define SDRAMC_MODE_AUTO_REFRESH 4 +#define SDRAMC_MODE_EXT_LOAD_MODE 5 +#define SDRAMC_MODE_POWER_DOWN 6 + +/* Constants for NC */ +#define SDRAMC_NC_8_COLUMN_BITS 0 +#define SDRAMC_NC_9_COLUMN_BITS 1 +#define SDRAMC_NC_10_COLUMN_BITS 2 +#define SDRAMC_NC_11_COLUMN_BITS 3 + +/* Constants for NR */ +#define SDRAMC_NR_11_ROW_BITS 0 +#define SDRAMC_NR_12_ROW_BITS 1 +#define SDRAMC_NR_13_ROW_BITS 2 + +/* Constants for NB */ +#define SDRAMC_NB_TWO_BANKS 0 +#define SDRAMC_NB_FOUR_BANKS 1 + +/* Constants for CAS */ +#define SDRAMC_CAS_ONE_CYCLE 1 +#define SDRAMC_CAS_TWO_CYCLES 2 +#define SDRAMC_CAS_THREE_CYCLES 3 + +/* Constants for DBW */ +#define SDRAMC_DBW_32_BITS 0 +#define SDRAMC_DBW_16_BITS 1 + +/* Constants for TIMEOUT */ +#define SDRAMC_TIMEOUT_AFTER_END 0 +#define SDRAMC_TIMEOUT_64_CYC_AFTER_END 1 +#define SDRAMC_TIMEOUT_128_CYC_AFTER_END 2 + +/* Constants for MD */ +#define SDRAMC_MD_SDRAM 0 +#define SDRAMC_MD_LOW_POWER_SDRAM 1 + +/* Bit manipulation macros */ +#define SDRAMC_BIT(name) \ + (1 << SDRAMC_##name##_OFFSET) +#define SDRAMC_BF(name,value) \ + (((value) & ((1 << SDRAMC_##name##_SIZE) - 1)) \ + << SDRAMC_##name##_OFFSET) +#define SDRAMC_BFEXT(name,value) \ + (((value) >> SDRAMC_##name##_OFFSET) \ + & ((1 << SDRAMC_##name##_SIZE) - 1)) +#define SDRAMC_BFINS(name,value,old) \ + (((old) & ~(((1 << SDRAMC_##name##_SIZE) - 1) \ + << SDRAMC_##name##_OFFSET)) \ + | SDRAMC_BF(name,value)) + +/* Register access macros */ +#define sdramc_readl(reg) \ + readl((void *)SDRAMC_BASE + SDRAMC_##reg) +#define sdramc_writel(reg,value) \ + writel((value), (void *)SDRAMC_BASE + SDRAMC_##reg) + +#endif /* __ASM_AVR32_SDRAMC_H__ */ diff --git a/cpu/at32uc/smc.c b/cpu/at32uc/smc.c new file mode 100644 index 0000000..74c2947 --- /dev/null +++ b/cpu/at32uc/smc.c @@ -0,0 +1,61 @@ +#include <common.h> +#include <asm/sram.h> +#include "smc.h" + +unsigned long sram_init(const struct sram_config *config) +{ + u32 cfgreg; + u32 dbw; + u32 sram_size; + + cfgreg = SMC_BF(NWE_SETUP, config->nwe_setup) + |SMC_BF(NRD_SETUP, config->nrd_setup) + |SMC_BF(NCS_WR_SETUP, config->ncs_wr_setup) + |SMC_BF(NCS_RD_SETUP, config->ncs_rd_setup); + smc_writel(config->chip_select, SETUP, cfgreg); + + cfgreg = SMC_BF(NWE_PULSE, config->nwe_pulse) + |SMC_BF(NRD_PULSE, config->nrd_pulse) + |SMC_BF(NCS_WR_PULSE, config->ncs_wr_pulse) + |SMC_BF(NCS_RD_PULSE, config->ncs_rd_pulse); + smc_writel(config->chip_select, PULSE, cfgreg); + + cfgreg = SMC_BF(NWE_CYCLE, config->nwe_cycle) + |SMC_BF(NRD_CYCLE, config->nrd_cycle); + smc_writel(config->chip_select, CYCLE, cfgreg); + + switch (config->data_bits) { + case 8: + dbw = 0; + break; + case 16: + dbw = 1; + break; + case 32: + dbw = 2; + break; + default: + panic("Invalid number of databits for SRAM"); + + } + cfgreg = SMC_BF(READ_MODE, config->read_mode) + |SMC_BF(WRITE_MODE, config->write_mode) + |SMC_BF(EXNW_MODE, config->exnw_mode) + |SMC_BF(BAT, config->bat) + |SMC_BF(DBW, dbw) + |SMC_BF(TDF_CYCLES, config->tdf_cycles) + |SMC_BF(TDF_MODE, config->tdf_mode) + |SMC_BF(PMEN, config->pmen) + |SMC_BF(PS, config->ps); + + + + + smc_writel(config->chip_select, MODE, cfgreg); + sram_size = (1<<config->address_bits) * (config->data_bits/8); + + + return sram_size; +} + + diff --git a/cpu/at32uc/smc.h b/cpu/at32uc/smc.h new file mode 100644 index 0000000..ae765ec --- /dev/null +++ b/cpu/at32uc/smc.h @@ -0,0 +1,105 @@ +/* + * Register definitions for Static Memory Controller + */ +#ifndef __CPU_AT32UC3_SMC_H__ +#define __CPU_AT32UC3_SMC_H__ + +#include <asm/arch/memory-map.h> +#include <asm/io.h> + +/* SMC register offsets */ +#define SMC_SETUP(x) (0x0000+(x)*0x10) +#define SMC_PULSE(x) (0x0004+(x)*0x10) +#define SMC_CYCLE(x) (0x0008+(x)*0x10) +#define SMC_MODE(x) (0x000c+(x)*0x10) + +/* Bitfields in SETUP0..3 */ +#define SMC_NWE_SETUP_OFFSET 0 +#define SMC_NWE_SETUP_SIZE 6 +#define SMC_NCS_WR_SETUP_OFFSET 8 +#define SMC_NCS_WR_SETUP_SIZE 6 +#define SMC_NRD_SETUP_OFFSET 16 +#define SMC_NRD_SETUP_SIZE 6 +#define SMC_NCS_RD_SETUP_OFFSET 24 +#define SMC_NCS_RD_SETUP_SIZE 6 + +/* Bitfields in PULSE0..3 */ +#define SMC_NWE_PULSE_OFFSET 0 +#define SMC_NWE_PULSE_SIZE 7 +#define SMC_NCS_WR_PULSE_OFFSET 8 +#define SMC_NCS_WR_PULSE_SIZE 7 +#define SMC_NRD_PULSE_OFFSET 16 +#define SMC_NRD_PULSE_SIZE 7 +#define SMC_NCS_RD_PULSE_OFFSET 24 +#define SMC_NCS_RD_PULSE_SIZE 7 + +/* Bitfields in CYCLE0..3 */ +#define SMC_NWE_CYCLE_OFFSET 0 +#define SMC_NWE_CYCLE_SIZE 9 +#define SMC_NRD_CYCLE_OFFSET 16 +#define SMC_NRD_CYCLE_SIZE 9 + +/* Bitfields in MODE0..3 */ +#define SMC_READ_MODE_OFFSET 0 +#define SMC_READ_MODE_SIZE 1 +#define SMC_WRITE_MODE_OFFSET 1 +#define SMC_WRITE_MODE_SIZE 1 +#define SMC_EXNW_MODE_OFFSET 4 +#define SMC_EXNW_MODE_SIZE 2 +#define SMC_BAT_OFFSET 8 +#define SMC_BAT_SIZE 1 +#define SMC_DBW_OFFSET 12 +#define SMC_DBW_SIZE 2 +#define SMC_TDF_CYCLES_OFFSET 16 +#define SMC_TDF_CYCLES_SIZE 4 +#define SMC_TDF_MODE_OFFSET 20 +#define SMC_TDF_MODE_SIZE 1 +#define SMC_PMEN_OFFSET 24 +#define SMC_PMEN_SIZE 1 +#define SMC_PS_OFFSET 28 +#define SMC_PS_SIZE 2 + +/* Constants for READ_MODE */ +#define SMC_READ_MODE_NCS_CONTROLLED 0 +#define SMC_READ_MODE_NRD_CONTROLLED 1 + +/* Constants for WRITE_MODE */ +#define SMC_WRITE_MODE_NCS_CONTROLLED 0 +#define SMC_WRITE_MODE_NWE_CONTROLLED 1 + +/* Constants for EXNW_MODE */ +#define SMC_EXNW_MODE_DISABLED 0 +#define SMC_EXNW_MODE_RESERVED 1 +#define SMC_EXNW_MODE_FROZEN 2 +#define SMC_EXNW_MODE_READY 3 + +/* Constants for BAT */ +#define SMC_BAT_BYTE_SELECT 0 +#define SMC_BAT_BYTE_WRITE 1 + +/* Constants for DBW */ +#define SMC_DBW_8_BITS 0 +#define SMC_DBW_16_BITS 1 +#define SMC_DBW_32_BITS 2 + +/* Bit manipulation macros */ +#define SMC_BIT(name) \ + (1 << SMC_##name##_OFFSET) +#define SMC_BF(name,value) \ + (((value) & ((1 << SMC_##name##_SIZE) - 1)) \ + << SMC_##name##_OFFSET) +#define SMC_BFEXT(name,value) \ + (((value) >> SMC_##name##_OFFSET) \ + & ((1 << SMC_##name##_SIZE) - 1)) +#define SMC_BFINS(name,value,old)\ + (((old) & ~(((1 << SMC_##name##_SIZE) - 1) \ + << SMC_##name##_OFFSET)) \ + | SMC_BF(name,value)) + +/* Register access macros */ +#define smc_readl(cs,reg) \ + readl((void *)SMC_BASE + SMC_##reg(cs)) +#define smc_writel(cs,reg,value) \ + writel((value), (void *)SMC_BASE + SMC_##reg(cs)) + +#endif /* __CPU_AT32UC3_SMC_H__ */ diff --git a/cpu/at32uc/start.S b/cpu/at32uc/start.S new file mode 100644 index 0000000..a8798af --- /dev/null +++ b/cpu/at32uc/start.S @@ -0,0 +1,252 @@ +/* + * Copyright (C) 2005-2008 Atmel Corporation + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ +#include <config.h> +#include <asm/ptrace.h> +#include <asm/sysreg.h> + + +#define SR_INIT (SYSREG_BIT(GM) | SYSREG_BIT(EM) | SYSREG_BIT(M0)) +#define CPUCR_INIT (SYSREG_BIT(BI) | SYSREG_BIT(BE) \ + | SYSREG_BIT(FE) | SYSREG_BIT(RE) \ + | SYSREG_BIT(IBE) | SYSREG_BIT(IEE)) + + /* + * To save some space, we use the same entry point for + * exceptions and reset. This avoids lots of alignment padding + * since the reset vector is always suitably aligned. + */ + .section .exception.text, "ax", @progbits + .global _start + .global _evba + .type _start, @function + .type _evba, @function +_start: + .size _start, 0 +_evba: + .org 0x00 + rjmp unknown_exception /* Unrecoverable exception */ + .org 0x04 + rjmp unknown_exception /* TLB multiple hit */ + .org 0x08 + rjmp unknown_exception /* Bus error data fetch */ + .org 0x0c + rjmp unknown_exception /* Bus error instruction fetch */ + .org 0x10 + rjmp unknown_exception /* NMI */ + .org 0x14 + rjmp unknown_exception /* Instruction address */ + .org 0x18 + rjmp unknown_exception /* ITLB protection */ + .org 0x1c + rjmp unknown_exception /* Breakpoint */ + .org 0x20 + rjmp unknown_exception /* Illegal opcode */ + .org 0x24 + rjmp unknown_exception /* Unimplemented instruction */ + .org 0x28 + rjmp unknown_exception /* Privilege violation */ + .org 0x2c + rjmp unknown_exception /* Floating-point */ + .org 0x30 + rjmp unknown_exception /* Coprocessor absent */ + .org 0x34 + rjmp unknown_exception /* Data Address (read) */ + .org 0x38 + rjmp unknown_exception /* Data Address (write) */ + .org 0x3c + rjmp unknown_exception /* DTLB Protection (read) */ + .org 0x40 + rjmp unknown_exception /* DTLB Protection (write) */ + .org 0x44 + rjmp unknown_exception /* DTLB Modified */ + + .org 0x50 + rjmp unknown_exception /* ITLB Miss */ + .org 0x60 + rjmp unknown_exception /* DTLB Miss (read) */ + .org 0x70 + rjmp unknown_exception /* DTLB Miss (write) */ + + .size _evba, . - _evba + + .align 2 + .type unknown_exception, @function +unknown_exception: + /* Figure out whether we're handling an exception (Exception + * mode) or just booting (Supervisor mode). */ + csrfcz SYSREG_M1_OFFSET + brcc at32uc_cpu_bootstrap + + /* This is an exception. Complain. */ + pushm r0-r12 + sub r8, sp, REG_R12 - REG_R0 - 4*3 + mov r9, lr + ld.w r10, r8[-4] + ld.w r11, r8[-8] + pushm r8-r11 + mfsr r12, SYSREG_ECR + mov r11, sp + rcall do_unknown_exception +1: rjmp 1b + + /* The COUNT/COMPARE timer interrupt handler */ + .global timer_interrupt_handler + .type timer_interrupt_handler,@function + .align 2 +timer_interrupt_handler: + /* + * Increment timer_overflow and re-write COMPARE with 0xffffffff. + * + * We're running at interrupt level 3, so we don't need to save + * r8-r12 or lr to the stack. + */ + lda.w r8, timer_overflow + ld.w r9, r8[0] + mov r10, -1 + mtsr SYSREG_COMPARE, r10 + sub r9, -1 + st.w r8[0], r9 + rete + + /* + * CPU bootstrap after reset is handled here. SoC code may + * override this in case they need to initialize oscillators, + * etc. + */ + .section .text.at32uc_cpu_bootstrap, "ax", @progbits + .global at32uc_cpu_bootstrap + .weak at32uc_cpu_bootstrap + .type at32uc_cpu_bootstrap, @function + .align 2 +at32uc_cpu_bootstrap: + /* Reset the Status Register */ + mov r0, lo(SR_INIT) + orh r0, hi(SR_INIT) + mtsr SYSREG_SR, r0 + /* ERRATA: two NOPs required after mtsr which may mask interrupts. */ + nop + nop + + /* Reset CPUCR and invalidate the BTB */ + mov r2, CPUCR_INIT + mtsr SYSREG_CPUCR, r2 + + /* Internal RAM should not need any initialization. We might + have to initialize external RAM here if the part doesn't + have internal RAM (or we may use the data cache) */ + + + lddpc sp, sp_init + + /* Initialize the GOT pointer */ + lddpc r6, got_init +3: rsub r6, pc + + /* Let's go */ + rjmp board_init_f + + .align 2 + .type sp_init,@object +sp_init: + .long CFG_INIT_SP_ADDR +got_init: + .long 3b - _GLOBAL_OFFSET_TABLE_ + + /* + * void relocate_code(new_sp, new_gd, monitor_addr) + * + * Relocate the u-boot image into RAM and continue from there. + * Does not return. + */ + .section .text.relocate_code,"ax",@progbits + .global relocate_code + .type relocate_code,@function +relocate_code: + mov sp, r12 /* use new stack */ + mov r12, r11 /* save new_gd */ + mov r11, r10 /* save destination address */ + + /* copy .text section */ + lda.w r8, _text + lda.w r9, _etext + sub lr, r10, r8 /* relocation offset */ + +1: ldm r8++, r0-r3 + stm r10, r0-r3 + sub r10, -16 + ldm r8++, r0-r3 + stm r10, r0-r3 + sub r10, -16 + cp.w r8, r9 + brlt 1b + + /* copy data sections */ + lda.w r9, _edata +1: ld.d r0, r8++ + st.d r10++, r0 + cp.w r8, r9 + brlt 1b + + /* zero out .bss */ + mov r0, 0 + mov r1, 0 + lda.w r9, _end + sub r9, r8 +1: st.d r10++, r0 + sub r9, 8 + brgt 1b + + /* jump to RAM */ + sub r0, pc, . - in_ram + add pc, r0, lr + + .align 2 +in_ram: + /* find the new GOT and relocate it */ + lddpc r6, got_init_reloc +3: rsub r6, pc + mov r8, r6 + lda.w r9, _egot + lda.w r10, _got + sub r9, r10 + +1: ld.w r0, r8[0] + add r0, lr + st.w r8, r0 + + sub r8, -4 + sub r9, 4 + brgt 1b + + /* Move the exception handlers */ + mfsr r2, SYSREG_EVBA + add r2, lr + mtsr SYSREG_EVBA, r2 + + /* Do the rest of the initialization sequence */ + call board_init_r + + .align 2 +got_init_reloc: + .long 3b - _GLOBAL_OFFSET_TABLE_ + + .size relocate_code, . - relocate_code diff --git a/include/asm-avr32/arch-at32uc3a0xxx/addrspace.h b/include/asm-avr32/arch-at32uc3a0xxx/addrspace.h new file mode 100644 index 0000000..0b8b3df --- /dev/null +++ b/include/asm-avr32/arch-at32uc3a0xxx/addrspace.h @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2006 Atmel Corporation + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ +#ifndef __ASM_AVR32_ADDRSPACE_H +#define __ASM_AVR32_ADDRSPACE_H + +#include <asm/types.h> + +/* Returns the physical address of an address */ +#define PHYSADDR(a) ((unsigned long)(a)) + +/* virt_to_phys will only work when address is in P1 or P2 */ +static __inline__ unsigned long virt_to_phys(volatile void *address) +{ + return PHYSADDR(address); +} + +static __inline__ void *phys_to_virt(unsigned long address) +{ + return (void *)address; +} + +#define cached(addr) ((void *)(addr)) +#define uncached(addr) ((void *)(addr)) + +/* + * Given a physical address and a length, return a virtual address + * that can be used to access the memory range with the caching + * properties specified by "flags". + * + * This implementation works for memory below 512MiB (flash, etc.) as + * well as above 3.5GiB (internal peripherals.) + */ +#define MAP_NOCACHE (0) +#define MAP_WRCOMBINE (1 << 7) +#define MAP_WRBACK (MAP_WRCOMBINE | (1 << 9)) +#define MAP_WRTHROUGH (MAP_WRBACK | (1 << 0)) + +static inline void * +map_physmem(phys_addr_t paddr, unsigned long len, unsigned long flags) +{ + return (void *)paddr; +} + +#endif /* __ASM_AVR32_ADDRSPACE_H */ diff --git a/include/asm-avr32/arch-at32uc3a0xxx/cacheflush.h b/include/asm-avr32/arch-at32uc3a0xxx/cacheflush.h new file mode 100644 index 0000000..3dc1068 --- /dev/null +++ b/include/asm-avr32/arch-at32uc3a0xxx/cacheflush.h @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2006 Atmel Corporation + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ +#ifndef __ASM_AVR32_CACHEFLUSH_H +#define __ASM_AVR32_CACHEFLUSH_H + +/* No cache in the UC3. */ +#define dcache_invalidate_line(vaddr) +#define dcache_clean_line(vaddr) +#define dcache_flush_line(vaddr) +#define icache_invalidate_line(vaddr) +#define dcache_invalidate_range(start, len) +#define dcache_clean_range(start, len) +#define dcache_flush_range(start, len) +#define icache_invalidate_range(start, len) +#define dcache_flush_unlocked() + +/* + * Make sure any pending writes are completed before continuing. + */ +#define sync_write_buffer() asm volatile("sync 0" : : : "memory") + +#endif /* __ASM_AVR32_CACHEFLUSH_H */ diff --git a/include/asm-avr32/arch-at32uc3a0xxx/chip-features.h b/include/asm-avr32/arch-at32uc3a0xxx/chip-features.h new file mode 100644 index 0000000..25ae8d7 --- /dev/null +++ b/include/asm-avr32/arch-at32uc3a0xxx/chip-features.h @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2007 Atmel Corporation + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ +#ifndef __ASM_AVR32_ARCH_CHIP_FEATURES_H__ +#define __ASM_AVR32_ARCH_CHIP_FEATURES_H__ + +/* All the UC3A0xxx chips have these. */ +#define AT32UC3A0xxx_CHIP_HAS_USART +#define AT32UC3A0xxx_CHIP_HAS_SPI +#define AT32UC3A0xxx_CHIP_HAS_MACB + +#endif /* __ASM_AVR32_ARCH_CHIP_FEATURES_H__ */ diff --git a/include/asm-avr32/arch-at32uc3a0xxx/clk.h b/include/asm-avr32/arch-at32uc3a0xxx/clk.h new file mode 100644 index 0000000..eb94eaa --- /dev/null +++ b/include/asm-avr32/arch-at32uc3a0xxx/clk.h @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2006 Atmel Corporation + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ +#ifndef __ASM_AVR32_ARCH_CLK_H__ +#define __ASM_AVR32_ARCH_CLK_H__ + +#include <asm/arch/chip-features.h> + +#ifdef CONFIG_PLL +#define MAIN_CLK_RATE (((CFG_OSC0_HZ / CFG_PLL0_DIV) * CFG_PLL0_MUL) / \ + ((CFG_PLL0_OPT & 0x2) ? 2 : 1)) +#else +#define MAIN_CLK_RATE (CFG_OSC0_HZ) +#endif + +static inline unsigned long get_cpu_clk_rate(void) +{ + return MAIN_CLK_RATE >> CFG_CLKDIV_CPU; +} +static inline unsigned long get_hsb_clk_rate(void) +{ + return MAIN_CLK_RATE >> CFG_CLKDIV_CPU; +} +static inline unsigned long get_pba_clk_rate(void) +{ + return MAIN_CLK_RATE >> CFG_CLKDIV_PBA; +} +static inline unsigned long get_pbb_clk_rate(void) +{ + return MAIN_CLK_RATE >> CFG_CLKDIV_PBB; +} + +/* Accessors for specific devices. More will be added as needed. */ +static inline unsigned long get_sdram_clk_rate(void) +{ + return get_hsb_clk_rate(); +} +#ifdef AT32UC3A0xxx_CHIP_HAS_USART +static inline unsigned long get_usart_clk_rate(unsigned int dev_id) +{ + return get_pba_clk_rate(); +} +#endif +#ifdef AT32UC3A0xxx_CHIP_HAS_MACB +static inline unsigned long get_macb_pclk_rate(unsigned int dev_id) +{ + return get_pbb_clk_rate(); +} +static inline unsigned long get_macb_hclk_rate(unsigned int dev_id) +{ + return get_hsb_clk_rate(); +} +#endif +#ifdef AT32UC3A0xxx_CHIP_HAS_SPI +static inline unsigned long get_spi_clk_rate(unsigned int dev_id) +{ + return get_pba_clk_rate(); +} +#endif + +extern void clk_init(void); +extern void gclk_init(void) __attribute__((weak)); + +/* Board code may need the SDRAM base clock as a compile-time constant */ +#define SDRAMC_BUS_HZ (MAIN_CLK_RATE >> CFG_CLKDIV_CPU) + +#endif /* __ASM_AVR32_ARCH_CLK_H__ */ diff --git a/include/asm-avr32/arch-at32uc3a0xxx/gpio-impl.h b/include/asm-avr32/arch-at32uc3a0xxx/gpio-impl.h new file mode 100644 index 0000000..636bd19 --- /dev/null +++ b/include/asm-avr32/arch-at32uc3a0xxx/gpio-impl.h @@ -0,0 +1,62 @@ +#ifndef __ASM_AVR32_ARCH_GPIO_IMPL_H__ +#define __ASM_AVR32_ARCH_GPIO_IMPL_H__ + +/* Register offsets */ +struct gpio_regs { + u32 GPER; + u32 GPERS; + u32 GPERC; + u32 GPERT; + u32 PMR0; + u32 PMR0S; + u32 PMR0C; + u32 PMR0T; + u32 PMR1; + u32 PMR1S; + u32 PMR1C; + u32 PMR1T; + u32 __reserved0[4]; + u32 ODER; + u32 ODERS; + u32 ODERC; + u32 ODERT; + u32 OVR; + u32 OVRS; + u32 OVRC; + u32 OVRT; + u32 PVR; + u32 __reserved_PVRS; + u32 __reserved_PVRC; + u32 __reserved_PVRT; + u32 PUER; + u32 PUERS; + u32 PUERC; + u32 PUERT; + u32 ODMER; + u32 ODMERS; + u32 ODMERC; + u32 ODMERT; + u32 IER; + u32 IERS; + u32 IERC; + u32 IERT; + u32 IMR0; + u32 IMR0S; + u32 IMR0C; + u32 IMR0T; + u32 IMR1; + u32 IMR1S; + u32 IMR1C; + u32 IMR1T; + u32 GFER; + u32 GFERS; + u32 GFERC; + u32 GFERT; + u32 IFR; + u32 __reserved_IFRS; + u32 IFRC; + u32 __reserved_IFRT; + u32 __reserved1[8]; +}; + +#endif /* __ASM_AVR32_ARCH_GPIO_IMPL_H__ */ diff --git a/include/asm-avr32/arch-at32uc3a0xxx/gpio.h b/include/asm-avr32/arch-at32uc3a0xxx/gpio.h new file mode 100644 index 0000000..165ee5d --- /dev/null +++ b/include/asm-avr32/arch-at32uc3a0xxx/gpio.h @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2006, 2008 Atmel Corporation + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ +#ifndef __ASM_AVR32_ARCH_GPIO_H__ +#define __ASM_AVR32_ARCH_GPIO_H__ + +#include <asm/arch/chip-features.h> +#include <asm/arch/memory-map.h> + +#define NR_GPIO_CONTROLLERS 4 + +static inline void *pio_pin_to_port(unsigned int pin) +{ + unsigned port_no; + + port_no = pin / 32; + if (port_no >= (NR_GPIO_CONTROLLERS - 1)) { + return NULL; + } + + return GPIO_PORT(port_no); +} + +#include <asm/arch-common/portmux-pio.h> + +#endif /* __ASM_AVR32_ARCH_GPIO_H__ */ diff --git a/include/asm-avr32/arch-at32uc3a0xxx/hmatrix.h b/include/asm-avr32/arch-at32uc3a0xxx/hmatrix.h new file mode 100644 index 0000000..907912f --- /dev/null +++ b/include/asm-avr32/arch-at32uc3a0xxx/hmatrix.h @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2008 Atmel Corporation + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ +#ifndef __ASM_AVR32_ARCH_HMATRIX_H__ +#define __ASM_AVR32_ARCH_HMATRIX_H__ + +#include <asm/hmatrix-common.h> + +/* Bitfields in SFR5 (EBI) */ +#define HMATRIX_EBI_SDRAM_ENABLE_OFFSET 1 +#define HMATRIX_EBI_SDRAM_ENABLE_SIZE 1 + +/* HSB masters */ +#define HMATRIX_MASTER_CPU_DATA 0 +#define HMATRIX_MASTER_CPU_INSTRUCTIONS 1 +#define HMATRIX_MASTER_CPU_SAB 2 +#define HMATRIX_MASTER_PDCA 3 +#define HMATRIX_MASTER_MACB_DMA 4 +#define HMATRIX_MASTER_USBB_DMA 5 + +/* HSB slaves */ +#define HMATRIX_SLAVE_INT_FLASH 0 +#define HMATRIX_SLAVE_HSB_PB_BR0 1 +#define HMATRIX_SLAVE_HSB_PB_BR1 2 +#define HMATRIX_SLAVE_INT_SRAM 3 +#define HMATRIX_SLAVE_USBB_DPRAM 4 +#define HMATRIX_SLAVE_EBI 5 + +#endif /* __ASM_AVR32_ARCH_HMATRIX_H__ */ diff --git a/include/asm-avr32/arch-at32uc3a0xxx/memory-map.h b/include/asm-avr32/arch-at32uc3a0xxx/memory-map.h new file mode 100644 index 0000000..3beaad9 --- /dev/null +++ b/include/asm-avr32/arch-at32uc3a0xxx/memory-map.h @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2005-2006 Atmel Corporation + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ +#ifndef __AT32UC3A0512_MEMORY_MAP_H__ +#define __AT32UC3A0512_MEMORY_MAP_H__ + +/* Internal and external memories */ +#define EBI_SRAM_CS0_BASE 0xc0000000 +#define EBI_SRAM_CS0_SIZE 0x01000000 +#define EBI_SRAM_CS2_BASE 0xc8000000 +#define EBI_SRAM_CS2_SIZE 0x01000000 +#define EBI_SRAM_CS3_BASE 0xcc000000 +#define EBI_SRAM_CS3_SIZE 0x01000000 +#define EBI_SRAM_CS1_BASE 0xd0000000 +#define EBI_SRAM_CS1_SIZE 0x08000000 + +#define EBI_SDRAM_BASE EBI_SRAM_CS1_BASE +#define EBI_SDRAM_SIZE EBI_SRAM_CS1_SIZE + +#define INTERNAL_SRAM_BASE 0x00000000 +#define INTERNAL_SRAM_SIZE 0x00010000 + +/* Devices on HSB bus */ +#define USBB_SLAVE_BASE 0xE0000000 + +/* Devices on Peripheral Bus B (PBB) */ +#define USBB_CONFIG_BASE 0xFFFE0000 +#define HMATRIX_BASE 0xFFFE1000 +#define FLASHC_BASE 0xFFFE1400 +#define MACB_BASE 0xFFFE1800 +#define SMC_BASE 0xFFFE1C00 +#define SDRAMC_BASE 0xFFFE2000 + +/* Devices on Peripheral Bus A (PBA) */ +#define SM_BASE 0xFFFF0000 +#define PCDA_BASE 0xFFFF0000 +#define INTC_BASE 0xFFFF0800 +#define PM_BASE 0xFFFF0C00 +#define RTC_BASE 0xFFFF0D00 +#define WDT_BASE 0xFFFF0D30 +#define EIC_BASE 0xFFFF0D80 +#define GPIO_BASE 0xFFFF1000 +#define USART0_BASE 0xFFFF1400 +#define USART1_BASE 0xFFFF1800 +#define USART2_BASE 0xFFFF1C00 +#define USART3_BASE 0xFFFF2000 +#define SPI0_BASE 0xFFFF2400 +#define SPI1_BASE 0xFFFF2800 +#define TWI_BASE 0xFFFF2C00 +#define PWM_BASE 0xFFFF3000 +#define SSC_BASE 0xFFFF3400 +#define TC_BASE 0xFFFF3800 +#define ADC_BASE 0xFFFF3C00 + +#define GPIO_PORT(x) ((void *) (GPIO_BASE + (x) * 0x0100)) + +#endif /* __AT32UC3A0512_MEMORY_MAP_H__ */ diff --git a/include/asm-avr32/arch-at32uc3a0xxx/portmux.h b/include/asm-avr32/arch-at32uc3a0xxx/portmux.h new file mode 100644 index 0000000..c9b17a8 --- /dev/null +++ b/include/asm-avr32/arch-at32uc3a0xxx/portmux.h @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2006, 2008 Atmel Corporation + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ +#ifndef __ASM_AVR32_ARCH_PORTMUX_H__ +#define __ASM_AVR32_ARCH_PORTMUX_H__ + +#include <asm/arch-common/portmux-gpio.h> +#include <asm/arch/memory-map.h> + +#define PORTMUX_PORT(x) ((void *) (GPIO_BASE + (x) * 0x0100)) +#define PORTMUX_PORT_A PORTMUX_PORT(0) +#define PORTMUX_PORT_B PORTMUX_PORT(1) +#define PORTMUX_PORT_C PORTMUX_PORT(2) + +void portmux_enable_ebi(unsigned int bus_width, unsigned int addr_width, + unsigned long flags, unsigned long drive_strength); + +#define PORTMUX_EBI_CS(x) (1 << (x)) +#define PORTMUX_EBI_NAND (1 << 6) +#define PORTMUX_EBI_CF(x) (1 << ((x) + 7)) +#define PORTMUX_EBI_NWAIT (1 << 9) + +#ifdef AT32UC3A0xxx_CHIP_HAS_USART +static inline void portmux_enable_usart0(unsigned long drive_strength) +{ + portmux_select_peripheral(PORTMUX_PORT_A, (1 << 0) | (1 << 1), + PORTMUX_FUNC_A, 0); +} + +static inline void portmux_enable_usart1(unsigned long drive_strength) +{ + portmux_select_peripheral(PORTMUX_PORT_A, (1 << 5) | (1 << 6), + PORTMUX_FUNC_A, 0); +} + +static inline void portmux_enable_usart2(unsigned long drive_strength) +{ + portmux_select_peripheral(PORTMUX_PORT_B, (1 << 29) | (1 << 30), + PORTMUX_FUNC_A, 0); +} + +static inline void portmux_enable_usart3(unsigned long drive_strength) +{ + portmux_select_peripheral(PORTMUX_PORT_B, (1 << 10) | (1 << 11), + PORTMUX_FUNC_B, 0); +} +#endif +#ifdef AT32UC3A0xxx_CHIP_HAS_MACB +void portmux_enable_macb(unsigned long flags, unsigned long drive_strength); + +#define PORTMUX_MACB_RMII (0) +#define PORTMUX_MACB_MII (1 << 0) +#define PORTMUX_MACB_SPEED (1 << 1) + +#endif +#ifdef AT32UC3A0xxx_CHIP_HAS_SPI +void portmux_enable_spi0(unsigned long cs_mask, unsigned long drive_strength); +void portmux_enable_spi1(unsigned long cs_mask, unsigned long drive_strength); +#endif + +#endif /* __ASM_AVR32_ARCH_PORTMUX_H__ */ + diff --git a/include/asm-avr32/sram.h b/include/asm-avr32/sram.h new file mode 100644 index 0000000..3306d0b --- /dev/null +++ b/include/asm-avr32/sram.h @@ -0,0 +1,34 @@ +#ifndef __ASM_AVR32_SRAM_H +#define __ASM_AVR32_SRAM_H +#include <asm/types.h> + +struct sram_config { + /* Number of data bits. */ + u8 data_bits; + + /* Chip select */ + u8 chip_select; + + /* Number of address bits */ + u8 address_bits; + + /* nwe/nrd waveforms */ + u8 nwe_setup, nwe_pulse, nwe_hold; + u8 nrd_setup, nrd_pulse, nrd_hold; + + /* ncs waveforms */ + u8 ncs_wr_setup, ncs_wr_pulse, ncs_wr_hold; + u8 ncs_rd_setup, ncs_rd_pulse, ncs_rd_hold; + + /* Cycle length */ + u16 nwe_cycle, nrd_cycle; + + /* mode */ + u8 read_mode, write_mode, exnw_mode; + u8 bat, dbw, tdf_cycles, tdf_mode, pmen, ps; +}; + + +unsigned long sram_init(const struct sram_config *config); + +#endif /* __ASM_AVR32_SRAM_H */