[U-Boot] [PATCH v2 8/9] AVR32: CPU support for AT32UC3A0xxx CPUs

Gunnar Rangoy
2009-01-23T11:56:33Z

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 at 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@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
+ * @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, at 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, at 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", at progbits
+ .global relocate_code
+ .type relocate_code, at 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 */
--
1.6.0.4