summaryrefslogtreecommitdiff
path: root/cpu/at32ap
diff options
context:
space:
mode:
authorHaavard Skinnemoen <hskinnemoen@atmel.com>2006-11-19 18:06:53 +0100
committerHaavard Skinnemoen <hskinnemoen@atmel.com>2007-04-14 15:20:27 +0200
commitdf548d3c3e2bbc40258713167859ffc2ce99a900 (patch)
tree63759a73724848ba192874aa552861e03faf1058 /cpu/at32ap
parent03d1e1365796cd15d1726e8a51fd8b5be50b2fe9 (diff)
AVR32: Resource management rewrite
Rewrite the resource management code (i.e. I/O memory, clock gating, gpio) so it doesn't depend on any global state. This is necessary because this code is heavily used before relocation to RAM, so we can't write to any global variables. As an added bonus, this makes u-boot's memory footprint a bit smaller, although some functionality has been left out; all clocks are enabled all the time, and there's no checking for gpio line conflicts. Signed-off-by: Haavard Skinnemoen <hskinnemoen@atmel.com>
Diffstat (limited to 'cpu/at32ap')
-rw-r--r--cpu/at32ap/Makefile2
-rw-r--r--cpu/at32ap/at32ap7000/Makefile2
-rw-r--r--cpu/at32ap/at32ap7000/devices.c448
-rw-r--r--cpu/at32ap/at32ap7000/gpio.c77
-rw-r--r--cpu/at32ap/at32ap7000/hebi.c38
-rw-r--r--cpu/at32ap/cpu.c64
-rw-r--r--cpu/at32ap/device.c126
-rw-r--r--cpu/at32ap/hsdramc.c43
-rw-r--r--cpu/at32ap/hsdramc1.h8
-rw-r--r--cpu/at32ap/hsmc3.h8
-rw-r--r--cpu/at32ap/interrupts.c11
-rw-r--r--cpu/at32ap/pio.c90
-rw-r--r--cpu/at32ap/pio2.h8
-rw-r--r--cpu/at32ap/pm.c127
-rw-r--r--cpu/at32ap/sm.h8
15 files changed, 198 insertions, 862 deletions
diff --git a/cpu/at32ap/Makefile b/cpu/at32ap/Makefile
index f62ec8bc9b2..3f1bb07b3e2 100644
--- a/cpu/at32ap/Makefile
+++ b/cpu/at32ap/Makefile
@@ -30,7 +30,7 @@ LIB := $(obj)lib$(CPU).a
START := start.o
SOBJS := entry.o
COBJS := cpu.o hsdramc.o exception.o cache.o
-COBJS += interrupts.o device.o pm.o pio.o
+COBJS += interrupts.o pio.o
SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
START := $(addprefix $(obj),$(START))
diff --git a/cpu/at32ap/at32ap7000/Makefile b/cpu/at32ap/at32ap7000/Makefile
index 2ed74d2508c..d2767121184 100644
--- a/cpu/at32ap/at32ap7000/Makefile
+++ b/cpu/at32ap/at32ap7000/Makefile
@@ -24,7 +24,7 @@ include $(TOPDIR)/config.mk
LIB := $(obj)lib$(SOC).a
-COBJS := hebi.o devices.o
+COBJS := gpio.o
SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
diff --git a/cpu/at32ap/at32ap7000/devices.c b/cpu/at32ap/at32ap7000/devices.c
deleted file mode 100644
index 8b216e906a2..00000000000
--- a/cpu/at32ap/at32ap7000/devices.c
+++ /dev/null
@@ -1,448 +0,0 @@
-/*
- * 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
- */
-#include <common.h>
-
-#include <asm/arch/memory-map.h>
-#include <asm/arch/platform.h>
-
-#include "../sm.h"
-
-#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
-
-const struct clock_domain chip_clock[] = {
- [CLOCK_CPU] = {
- .reg = SM_PM_CPU_MASK,
- .id = CLOCK_CPU,
- .bridge = NO_DEVICE,
- },
- [CLOCK_HSB] = {
- .reg = SM_PM_HSB_MASK,
- .id = CLOCK_HSB,
- .bridge = NO_DEVICE,
- },
- [CLOCK_PBA] = {
- .reg = SM_PM_PBA_MASK,
- .id = CLOCK_PBA,
- .bridge = DEVICE_PBA_BRIDGE,
- },
- [CLOCK_PBB] = {
- .reg = SM_PM_PBB_MASK,
- .id = CLOCK_PBB,
- .bridge = DEVICE_PBB_BRIDGE,
- },
-};
-
-static const struct resource hebi_resource[] = {
- {
- .type = RESOURCE_CLOCK,
- .u = {
- .clock = { CLOCK_HSB, 0 },
- },
- }, {
- .type = RESOURCE_CLOCK,
- .u = {
- .clock = { CLOCK_PBB, 13 },
- },
- }, {
- .type = RESOURCE_CLOCK,
- .u = {
- .clock = { CLOCK_PBB, 14 },
- },
- }, {
- .type = RESOURCE_GPIO,
- .u = {
- .gpio = { 27, DEVICE_PIOE, GPIO_FUNC_A, 0 },
- },
- },
-};
-static const struct resource pba_bridge_resource[] = {
- {
- .type = RESOURCE_CLOCK,
- .u = {
- .clock = { CLOCK_HSB, 1 },
- }
- }, {
- .type = RESOURCE_CLOCK,
- .u = {
- /* HSB-HSB Bridge */
- .clock = { CLOCK_HSB, 4 },
- },
- },
-};
-static const struct resource pbb_bridge_resource[] = {
- {
- .type = RESOURCE_CLOCK,
- .u = {
- .clock = { CLOCK_HSB, 2 },
- },
- },
-};
-static const struct resource hramc_resource[] = {
- {
- .type = RESOURCE_CLOCK,
- .u = {
- .clock = { CLOCK_HSB, 3 },
- },
- },
-};
-static const struct resource pioa_resource[] = {
- {
- .type = RESOURCE_CLOCK,
- .u = {
- .clock = { CLOCK_PBA, 10 },
- },
- },
-};
-static const struct resource piob_resource[] = {
- {
- .type = RESOURCE_CLOCK,
- .u = {
- .clock = { CLOCK_PBA, 11 },
- },
- },
-};
-static const struct resource pioc_resource[] = {
- {
- .type = RESOURCE_CLOCK,
- .u = {
- .clock = { CLOCK_PBA, 12 },
- },
- },
-};
-static const struct resource piod_resource[] = {
- {
- .type = RESOURCE_CLOCK,
- .u = {
- .clock = { CLOCK_PBA, 13 },
- },
- },
-};
-static const struct resource pioe_resource[] = {
- {
- .type = RESOURCE_CLOCK,
- .u = {
- .clock = { CLOCK_PBA, 14 },
- },
- },
-};
-static const struct resource sm_resource[] = {
- {
- .type = RESOURCE_CLOCK,
- .u = {
- .clock = { CLOCK_PBB, 0 },
- },
- },
-};
-static const struct resource intc_resource[] = {
- {
- .type = RESOURCE_CLOCK,
- .u = {
- .clock = { CLOCK_PBB, 1 },
- },
- },
-};
-static const struct resource hmatrix_resource[] = {
- {
- .type = RESOURCE_CLOCK,
- .u = {
- .clock = { CLOCK_PBB, 2 },
- },
- },
-};
-#if defined(CFG_HPDC)
-static const struct resource hpdc_resource[] = {
- {
- .type = RESOURCE_CLOCK,
- .u = {
- .clock = { CLOCK_PBA, 16 },
- },
- },
-};
-#endif
-#if defined(CFG_MACB0)
-static const struct resource macb0_resource[] = {
- {
- .type = RESOURCE_CLOCK,
- .u = {
- .clock = { CLOCK_HSB, 8 },
- },
- }, {
- .type = RESOURCE_CLOCK,
- .u = {
- .clock = { CLOCK_PBB, 6 },
- },
- }, {
- .type = RESOURCE_GPIO,
- .u = {
- .gpio = { 19, DEVICE_PIOC, GPIO_FUNC_A, 0 },
- },
- },
-};
-#endif
-#if defined(CFG_MACB1)
-static const struct resource macb1_resource[] = {
- {
- .type = RESOURCE_CLOCK,
- .u = {
- .clock = { CLOCK_HSB, 9 },
- },
- }, {
- .type = RESOURCE_CLOCK,
- .u = {
- .clock = { CLOCK_PBB, 7 },
- },
- }, {
- .type = RESOURCE_GPIO,
- .u = {
- .gpio = { 12, DEVICE_PIOC, GPIO_FUNC_B, 19 },
- },
- }, {
- .type = RESOURCE_GPIO,
- .u = {
- .gpio = { 14, DEVICE_PIOD, GPIO_FUNC_B, 2 },
- },
- },
-};
-#endif
-#if defined(CFG_LCDC)
-static const struct resource lcdc_resource[] = {
- {
- .type = RESOURCE_CLOCK,
- .u = {
- .clock = { CLOCK_HSB, 7 },
- },
- },
-};
-#endif
-#if defined(CFG_USART0)
-static const struct resource usart0_resource[] = {
- {
- .type = RESOURCE_CLOCK,
- .u = {
- .clock = { CLOCK_PBA, 3 },
- },
- }, {
- .type = RESOURCE_GPIO,
- .u = {
- .gpio = { 2, DEVICE_PIOA, GPIO_FUNC_B, 8 },
- },
- },
-};
-#endif
-#if defined(CFG_USART1)
-static const struct resource usart1_resource[] = {
- {
- .type = RESOURCE_CLOCK,
- .u = {
- .clock = { CLOCK_PBA, 4 },
- },
- }, {
- .type = RESOURCE_GPIO,
- .u = {
- .gpio = { 2, DEVICE_PIOA, GPIO_FUNC_A, 17 },
- },
- },
-};
-#endif
-#if defined(CFG_USART2)
-static const struct resource usart2_resource[] = {
- {
- .type = RESOURCE_CLOCK,
- .u = {
- .clock = { CLOCK_PBA, 5 },
- },
- }, {
- .type = RESOURCE_GPIO,
- .u = {
- .gpio = { 2, DEVICE_PIOB, GPIO_FUNC_B, 26 },
- },
- },
-};
-#endif
-#if defined(CFG_USART3)
-static const struct resource usart3_resource[] = {
- {
- .type = RESOURCE_CLOCK,
- .u = {
- .clock = { CLOCK_PBA, 6 },
- },
- }, {
- .type = RESOURCE_GPIO,
- .u = {
- .gpio = { 2, DEVICE_PIOB, GPIO_FUNC_B, 17 },
- },
- },
-};
-#endif
-#if defined(CFG_MMCI)
-static const struct resource mmci_resource[] = {
- {
- .type = RESOURCE_CLOCK,
- .u = {
- .clock = { CLOCK_PBB, 9 },
- },
- }, {
- .type = RESOURCE_GPIO,
- .u = {
- .gpio = { 6, DEVICE_PIOA, GPIO_FUNC_A, 10 },
- },
- },
-};
-#endif
-#if defined(CFG_DMAC)
-static const struct resource dmac_resource[] = {
- {
- .type = RESOURCE_CLOCK,
- .u = {
- .clock = { CLOCK_HSB, 10 },
- },
- },
-};
-#endif
-
-const struct device chip_device[] = {
- [DEVICE_HEBI] = {
- .regs = (void *)HSMC_BASE,
- .nr_resources = ARRAY_SIZE(hebi_resource),
- .resource = hebi_resource,
- },
- [DEVICE_PBA_BRIDGE] = {
- .nr_resources = ARRAY_SIZE(pba_bridge_resource),
- .resource = pba_bridge_resource,
- },
- [DEVICE_PBB_BRIDGE] = {
- .nr_resources = ARRAY_SIZE(pbb_bridge_resource),
- .resource = pbb_bridge_resource,
- },
- [DEVICE_HRAMC] = {
- .nr_resources = ARRAY_SIZE(hramc_resource),
- .resource = hramc_resource,
- },
- [DEVICE_PIOA] = {
- .regs = (void *)PIOA_BASE,
- .nr_resources = ARRAY_SIZE(pioa_resource),
- .resource = pioa_resource,
- },
- [DEVICE_PIOB] = {
- .regs = (void *)PIOB_BASE,
- .nr_resources = ARRAY_SIZE(piob_resource),
- .resource = piob_resource,
- },
- [DEVICE_PIOC] = {
- .regs = (void *)PIOC_BASE,
- .nr_resources = ARRAY_SIZE(pioc_resource),
- .resource = pioc_resource,
- },
- [DEVICE_PIOD] = {
- .regs = (void *)PIOD_BASE,
- .nr_resources = ARRAY_SIZE(piod_resource),
- .resource = piod_resource,
- },
- [DEVICE_PIOE] = {
- .regs = (void *)PIOE_BASE,
- .nr_resources = ARRAY_SIZE(pioe_resource),
- .resource = pioe_resource,
- },
- [DEVICE_SM] = {
- .regs = (void *)SM_BASE,
- .nr_resources = ARRAY_SIZE(sm_resource),
- .resource = sm_resource,
- },
- [DEVICE_INTC] = {
- .regs = (void *)INTC_BASE,
- .nr_resources = ARRAY_SIZE(intc_resource),
- .resource = intc_resource,
- },
- [DEVICE_HMATRIX] = {
- .regs = (void *)HMATRIX_BASE,
- .nr_resources = ARRAY_SIZE(hmatrix_resource),
- .resource = hmatrix_resource,
- },
-#if defined(CFG_HPDC)
- [DEVICE_HPDC] = {
- .nr_resources = ARRAY_SIZE(hpdc_resource),
- .resource = hpdc_resource,
- },
-#endif
-#if defined(CFG_MACB0)
- [DEVICE_MACB0] = {
- .regs = (void *)MACB0_BASE,
- .nr_resources = ARRAY_SIZE(macb0_resource),
- .resource = macb0_resource,
- },
-#endif
-#if defined(CFG_MACB1)
- [DEVICE_MACB1] = {
- .regs = (void *)MACB1_BASE,
- .nr_resources = ARRAY_SIZE(macb1_resource),
- .resource = macb1_resource,
- },
-#endif
-#if defined(CFG_LCDC)
- [DEVICE_LCDC] = {
- .nr_resources = ARRAY_SIZE(lcdc_resource),
- .resource = lcdc_resource,
- },
-#endif
-#if defined(CFG_USART0)
- [DEVICE_USART0] = {
- .regs = (void *)USART0_BASE,
- .nr_resources = ARRAY_SIZE(usart0_resource),
- .resource = usart0_resource,
- },
-#endif
-#if defined(CFG_USART1)
- [DEVICE_USART1] = {
- .regs = (void *)USART1_BASE,
- .nr_resources = ARRAY_SIZE(usart1_resource),
- .resource = usart1_resource,
- },
-#endif
-#if defined(CFG_USART2)
- [DEVICE_USART2] = {
- .regs = (void *)USART2_BASE,
- .nr_resources = ARRAY_SIZE(usart2_resource),
- .resource = usart2_resource,
- },
-#endif
-#if defined(CFG_USART3)
- [DEVICE_USART3] = {
- .regs = (void *)USART3_BASE,
- .nr_resources = ARRAY_SIZE(usart3_resource),
- .resource = usart3_resource,
- },
-#endif
-#if defined(CFG_MMCI)
- [DEVICE_MMCI] = {
- .regs = (void *)MMCI_BASE,
- .nr_resources = ARRAY_SIZE(mmci_resource),
- .resource = mmci_resource,
- },
-#endif
-#if defined(CFG_DMAC)
- [DEVICE_DMAC] = {
- .regs = (void *)DMAC_BASE,
- .nr_resources = ARRAY_SIZE(dmac_resource),
- .resource = dmac_resource,
- },
-#endif
-};
diff --git a/cpu/at32ap/at32ap7000/gpio.c b/cpu/at32ap/at32ap7000/gpio.c
new file mode 100644
index 00000000000..a5d3ea65d96
--- /dev/null
+++ b/cpu/at32ap/at32ap7000/gpio.c
@@ -0,0 +1,77 @@
+/*
+ * 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
+ */
+#include <common.h>
+
+#include <asm/arch/gpio.h>
+
+/*
+ * Lots of small functions here. We depend on --gc-sections getting
+ * rid of the ones we don't need.
+ */
+void gpio_enable_ebi(void)
+{
+#ifdef CFG_HSDRAMC
+#ifndef CFG_SDRAM_16BIT
+ gpio_select_periph_A(GPIO_PIN_PE0, 0);
+ gpio_select_periph_A(GPIO_PIN_PE1, 0);
+ gpio_select_periph_A(GPIO_PIN_PE2, 0);
+ gpio_select_periph_A(GPIO_PIN_PE3, 0);
+ gpio_select_periph_A(GPIO_PIN_PE4, 0);
+ gpio_select_periph_A(GPIO_PIN_PE5, 0);
+ gpio_select_periph_A(GPIO_PIN_PE6, 0);
+ gpio_select_periph_A(GPIO_PIN_PE7, 0);
+ gpio_select_periph_A(GPIO_PIN_PE8, 0);
+ gpio_select_periph_A(GPIO_PIN_PE9, 0);
+ gpio_select_periph_A(GPIO_PIN_PE10, 0);
+ gpio_select_periph_A(GPIO_PIN_PE11, 0);
+ gpio_select_periph_A(GPIO_PIN_PE12, 0);
+ gpio_select_periph_A(GPIO_PIN_PE13, 0);
+ gpio_select_periph_A(GPIO_PIN_PE14, 0);
+ gpio_select_periph_A(GPIO_PIN_PE15, 0);
+#endif
+ gpio_select_periph_A(GPIO_PIN_PE26, 0);
+#endif
+}
+
+void gpio_enable_usart0(void)
+{
+ gpio_select_periph_B(GPIO_PIN_PA8, 0);
+ gpio_select_periph_B(GPIO_PIN_PA9, 0);
+}
+
+void gpio_enable_usart1(void)
+{
+ gpio_select_periph_A(GPIO_PIN_PA17, 0);
+ gpio_select_periph_A(GPIO_PIN_PA18, 0);
+}
+
+void gpio_enable_usart2(void)
+{
+ gpio_select_periph_B(GPIO_PIN_PB26, 0);
+ gpio_select_periph_B(GPIO_PIN_PB27, 0);
+}
+
+void gpio_enable_usart3(void)
+{
+ gpio_select_periph_B(GPIO_PIN_PB18, 0);
+ gpio_select_periph_B(GPIO_PIN_PB19, 0);
+}
diff --git a/cpu/at32ap/at32ap7000/hebi.c b/cpu/at32ap/at32ap7000/hebi.c
deleted file mode 100644
index 3b32adf1ea9..00000000000
--- a/cpu/at32ap/at32ap7000/hebi.c
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * 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
- */
-#include <common.h>
-
-#include <asm/io.h>
-
-#include <asm/arch/hmatrix2.h>
-#include <asm/arch/memory-map.h>
-#include <asm/arch/platform.h>
-
-void cpu_enable_sdram(void)
-{
- const struct device *hmatrix;
-
- hmatrix = get_device(DEVICE_HMATRIX);
-
- /* Set the SDRAM_ENABLE bit in the HEBI SFR */
- hmatrix2_writel(hmatrix, SFR4, 1 << 1);
-}
diff --git a/cpu/at32ap/cpu.c b/cpu/at32ap/cpu.c
index 37e3ea040be..311466b7814 100644
--- a/cpu/at32ap/cpu.c
+++ b/cpu/at32ap/cpu.c
@@ -26,33 +26,79 @@
#include <asm/sections.h>
#include <asm/sysreg.h>
+#include <asm/arch/clk.h>
#include <asm/arch/memory-map.h>
-#include <asm/arch/platform.h>
#include "hsmc3.h"
+#include "sm.h"
+
+/* Sanity checks */
+#if (CFG_CLKDIV_CPU > CFG_CLKDIV_HSB) \
+ || (CFG_CLKDIV_HSB > CFG_CLKDIV_PBA) \
+ || (CFG_CLKDIV_HSB > CFG_CLKDIV_PBB)
+# error Constraint fCPU >= fHSB >= fPB{A,B} violated
+#endif
+#if defined(CONFIG_PLL) && ((CFG_PLL0_MUL < 1) || (CFG_PLL0_DIV < 1))
+# error Invalid PLL multiplier and/or divider
+#endif
DECLARE_GLOBAL_DATA_PTR;
+static void pm_init(void)
+{
+ uint32_t cksel;
+
+#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 - 1)
+ | SM_BF(PLLOPT, CFG_PLL0_OPT)
+ | SM_BF(PLLOSC, 0)
+ | SM_BIT(PLLEN)));
+
+ /* Wait for lock */
+ while (!(sm_readl(PM_ISR) & SM_BIT(LOCK0))) ;
+#endif
+
+ /* 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_HSB)
+ cksel |= SM_BIT(HSBDIV) | SM_BF(HSBSEL, CFG_CLKDIV_HSB - 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);
+
+ gd->cpu_hz = get_cpu_clk_rate();
+
+#ifdef CONFIG_PLL
+ /* Use PLL0 as main clock */
+ sm_writel(PM_MCCTRL, SM_BIT(PLLSEL));
+#endif
+}
+
int cpu_init(void)
{
- const struct device *hebi;
extern void _evba(void);
char *p;
gd->cpu_hz = CFG_OSC0_HZ;
- /* fff03400: 00010001 04030402 00050005 10011103 */
- hebi = get_device(DEVICE_HEBI);
- hsmc3_writel(hebi, MODE0, 0x00031103);
- hsmc3_writel(hebi, CYCLE0, 0x000c000d);
- hsmc3_writel(hebi, PULSE0, 0x0b0a0906);
- hsmc3_writel(hebi, SETUP0, 0x00010002);
+ /* TODO: Move somewhere else, but needs to be run before we
+ * increase the clock frequency. */
+ hsmc3_writel(MODE0, 0x00031103);
+ hsmc3_writel(CYCLE0, 0x000c000d);
+ hsmc3_writel(PULSE0, 0x0b0a0906);
+ hsmc3_writel(SETUP0, 0x00010002);
pm_init();
sysreg_write(EVBA, (unsigned long)&_evba);
asm volatile("csrf %0" : : "i"(SYSREG_EM_OFFSET));
- gd->console_uart = get_device(CFG_CONSOLE_UART_DEV);
/* Lock everything that mess with the flash in the icache */
for (p = __flashprog_start; p <= (__flashprog_end + CFG_ICACHE_LINESZ);
diff --git a/cpu/at32ap/device.c b/cpu/at32ap/device.c
deleted file mode 100644
index 89914b6b56b..00000000000
--- a/cpu/at32ap/device.c
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * 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
- */
-#include <common.h>
-
-#include <asm/arch/platform.h>
-
-#include "sm.h"
-
-struct device_state {
- int refcount;
-};
-
-static struct device_state device_state[NR_DEVICES];
-
-static int claim_resource(const struct resource *res)
-{
- int ret = 0;
-
- switch (res->type) {
- case RESOURCE_GPIO:
- ret = gpio_set_func(res->u.gpio.gpio_dev,
- res->u.gpio.start,
- res->u.gpio.nr_pins,
- res->u.gpio.func);
- break;
- case RESOURCE_CLOCK:
- ret = pm_enable_clock(res->u.clock.id, res->u.clock.index);
- break;
- }
-
- return ret;
-}
-
-static void free_resource(const struct resource *res)
-{
- switch (res->type) {
- case RESOURCE_GPIO:
- gpio_free(res->u.gpio.gpio_dev, res->u.gpio.start,
- res->u.gpio.nr_pins);
- break;
- case RESOURCE_CLOCK:
- pm_disable_clock(res->u.clock.id, res->u.clock.index);
- break;
- }
-}
-
-static int init_dev(const struct device *dev)
-{
- unsigned int i;
- int ret = 0;
-
- for (i = 0; i < dev->nr_resources; i++) {
- ret = claim_resource(&dev->resource[i]);
- if (ret)
- goto cleanup;
- }
-
- return 0;
-
-cleanup:
- while (i--)
- free_resource(&dev->resource[i]);
-
- return ret;
-}
-
-const struct device *get_device(enum device_id devid)
-{
- struct device_state *devstate;
- const struct device *dev;
- unsigned long flags;
- int initialized = 0;
- int ret = 0;
-
- devstate = &device_state[devid];
- dev = &chip_device[devid];
-
- flags = disable_interrupts();
- if (devstate->refcount++)
- initialized = 1;
- if (flags)
- enable_interrupts();
-
- if (!initialized)
- ret = init_dev(dev);
-
- return ret ? NULL : dev;
-}
-
-void put_device(const struct device *dev)
-{
- struct device_state *devstate;
- unsigned long devid, flags;
-
- devid = (unsigned long)(dev - chip_device) / sizeof(struct device);
- devstate = &device_state[devid];
-
- flags = disable_interrupts();
- devstate--;
- if (!devstate) {
- unsigned int i;
- for (i = 0; i < dev->nr_resources; i++)
- free_resource(&dev->resource[i]);
- }
- if (flags)
- enable_interrupts();
-}
diff --git a/cpu/at32ap/hsdramc.c b/cpu/at32ap/hsdramc.c
index f36da354528..a936e03166c 100644
--- a/cpu/at32ap/hsdramc.c
+++ b/cpu/at32ap/hsdramc.c
@@ -25,17 +25,11 @@
#include <asm/io.h>
#include <asm/sdram.h>
-#include <asm/arch/platform.h>
+#include <asm/arch/clk.h>
+#include <asm/arch/memory-map.h>
#include "hsdramc1.h"
-struct hsdramc {
- const struct device *hebi;
- void *regs;
-};
-
-static struct hsdramc hsdramc;
-
unsigned long sdram_init(const struct sdram_info *info)
{
unsigned long *sdram = (unsigned long *)uncached(info->phys_addr);
@@ -44,16 +38,6 @@ unsigned long sdram_init(const struct sdram_info *info)
unsigned long bus_hz;
unsigned int i;
- hsdramc.hebi = get_device(DEVICE_HEBI);
- if (!hsdramc.hebi)
- return 0;
-
- /* FIXME: Both of these lines are complete hacks */
- hsdramc.regs = hsdramc.hebi->regs + 0x400;
- bus_hz = pm_get_clock_freq(hsdramc.hebi->resource[0].u.clock.id);
-
- cpu_enable_sdram();
-
tmp = (HSDRAMC1_BF(NC, info->col_bits - 8)
| HSDRAMC1_BF(NR, info->row_bits - 11)
| HSDRAMC1_BF(NB, info->bank_bits - 1)
@@ -74,7 +58,7 @@ unsigned long sdram_init(const struct sdram_info *info)
+ info->bank_bits + 2);
#endif
- hsdramc1_writel(&hsdramc, CR, tmp);
+ hsdramc1_writel(CR, tmp);
/*
* Initialization sequence for SDRAM, from the data sheet:
@@ -87,15 +71,15 @@ unsigned long sdram_init(const struct sdram_info *info)
/*
* 2. A Precharge All command is issued to the SDRAM
*/
- hsdramc1_writel(&hsdramc, MR, HSDRAMC1_MODE_BANKS_PRECHARGE);
- hsdramc1_readl(&hsdramc, MR);
+ hsdramc1_writel(MR, HSDRAMC1_MODE_BANKS_PRECHARGE);
+ hsdramc1_readl(MR);
writel(0, sdram);
/*
* 3. Eight auto-refresh (CBR) cycles are provided
*/
- hsdramc1_writel(&hsdramc, MR, HSDRAMC1_MODE_AUTO_REFRESH);
- hsdramc1_readl(&hsdramc, MR);
+ hsdramc1_writel(MR, HSDRAMC1_MODE_AUTO_REFRESH);
+ hsdramc1_readl(MR);
for (i = 0; i < 8; i++)
writel(0, sdram);
@@ -106,8 +90,8 @@ unsigned long sdram_init(const struct sdram_info *info)
*
* CAS from info struct, burst length 1, serial burst type
*/
- hsdramc1_writel(&hsdramc, MR, HSDRAMC1_MODE_LOAD_MODE);
- hsdramc1_readl(&hsdramc, MR);
+ hsdramc1_writel(MR, HSDRAMC1_MODE_LOAD_MODE);
+ hsdramc1_readl(MR);
writel(0, sdram + (info->cas << 4));
/*
@@ -117,9 +101,9 @@ unsigned long sdram_init(const struct sdram_info *info)
* From the timing diagram, it looks like tMRD is 3
* cycles...try a dummy read from the peripheral bus.
*/
- hsdramc1_readl(&hsdramc, MR);
- hsdramc1_writel(&hsdramc, MR, HSDRAMC1_MODE_NORMAL);
- hsdramc1_readl(&hsdramc, MR);
+ hsdramc1_readl(MR);
+ hsdramc1_writel(MR, HSDRAMC1_MODE_NORMAL);
+ hsdramc1_readl(MR);
writel(0, sdram);
/*
@@ -128,7 +112,8 @@ unsigned long sdram_init(const struct sdram_info *info)
*
* 15.6 us is a typical value for a burst of length one
*/
- hsdramc1_writel(&hsdramc, TR, (156 * (bus_hz / 1000)) / 10000);
+ bus_hz = get_sdram_clk_rate();
+ hsdramc1_writel(TR, (156 * (bus_hz / 1000)) / 10000);
printf("SDRAM: %u MB at address 0x%08lx\n",
sdram_size >> 20, info->phys_addr);
diff --git a/cpu/at32ap/hsdramc1.h b/cpu/at32ap/hsdramc1.h
index ce229bca1fb..305d2cb5d39 100644
--- a/cpu/at32ap/hsdramc1.h
+++ b/cpu/at32ap/hsdramc1.h
@@ -135,9 +135,9 @@
| HSDRAMC1_BF(name,value))
/* Register access macros */
-#define hsdramc1_readl(port,reg) \
- readl((port)->regs + HSDRAMC1_##reg)
-#define hsdramc1_writel(port,reg,value) \
- writel((value), (port)->regs + HSDRAMC1_##reg)
+#define hsdramc1_readl(reg) \
+ readl((void *)HSDRAMC_BASE + HSDRAMC1_##reg)
+#define hsdramc1_writel(reg,value) \
+ writel((value), (void *)HSDRAMC_BASE + HSDRAMC1_##reg)
#endif /* __ASM_AVR32_HSDRAMC1_H__ */
diff --git a/cpu/at32ap/hsmc3.h b/cpu/at32ap/hsmc3.h
index ec78cee7147..ca533b922ed 100644
--- a/cpu/at32ap/hsmc3.h
+++ b/cpu/at32ap/hsmc3.h
@@ -118,9 +118,9 @@
| HSMC3_BF(name,value))
/* Register access macros */
-#define hsmc3_readl(port,reg) \
- readl((port)->regs + HSMC3_##reg)
-#define hsmc3_writel(port,reg,value) \
- writel((value), (port)->regs + HSMC3_##reg)
+#define hsmc3_readl(reg) \
+ readl((void *)HSMC_BASE + HSMC3_##reg)
+#define hsmc3_writel(reg,value) \
+ writel((value), (void *)HSMC_BASE + HSMC3_##reg)
#endif /* __CPU_AT32AP_HSMC3_H__ */
diff --git a/cpu/at32ap/interrupts.c b/cpu/at32ap/interrupts.c
index d720cfa942b..85420a4248a 100644
--- a/cpu/at32ap/interrupts.c
+++ b/cpu/at32ap/interrupts.c
@@ -27,7 +27,7 @@
#include <asm/processor.h>
#include <asm/sysreg.h>
-#include <asm/arch/platform.h>
+#include <asm/arch/memory-map.h>
#define HANDLER_MASK 0x00ffffff
#define INTLEV_SHIFT 30
@@ -44,8 +44,6 @@ volatile unsigned long timer_overflow;
*/
static unsigned long tb_factor;
-static const struct device *intc_dev;
-
unsigned long get_tbclk(void)
{
return gd->cpu_hz;
@@ -126,7 +124,7 @@ static int set_interrupt_handler(unsigned int nr, void (*handler)(void),
intpr = (handler_addr & HANDLER_MASK);
intpr |= (priority & INTLEV_MASK) << INTLEV_SHIFT;
- writel(intpr, intc_dev->regs + 4 * nr);
+ writel(intpr, (void *)INTC_BASE + 4 * nr);
return 0;
}
@@ -143,10 +141,7 @@ void timer_init(void)
do_div(tmp, gd->cpu_hz);
tb_factor = (u32)tmp;
- intc_dev = get_device(DEVICE_INTC);
-
- if (!intc_dev
- || set_interrupt_handler(0, &timer_interrupt_handler, 3))
+ if (set_interrupt_handler(0, &timer_interrupt_handler, 3))
return;
/* For all practical purposes, this gives us an overflow interrupt */
diff --git a/cpu/at32ap/pio.c b/cpu/at32ap/pio.c
index 8b6c3a35df5..9ba0b8ea8b2 100644
--- a/cpu/at32ap/pio.c
+++ b/cpu/at32ap/pio.c
@@ -21,74 +21,40 @@
*/
#include <common.h>
-#include <asm/errno.h>
#include <asm/io.h>
-#include <asm/arch/platform.h>
+#include <asm/arch/gpio.h>
+#include <asm/arch/memory-map.h>
#include "pio2.h"
-struct pio_state {
- const struct device *dev;
- u32 alloc_mask;
-};
-
-static struct pio_state pio_state[CFG_NR_PIOS];
-
-int gpio_set_func(enum device_id gpio_devid, unsigned int start,
- unsigned int nr_pins, enum gpio_func func)
+void gpio_select_periph_A(unsigned int pin, int use_pullup)
{
- const struct device *gpio;
- struct pio_state *state;
- u32 mask;
-
- state = &pio_state[gpio_devid - DEVICE_PIOA];
-
- gpio = get_device(gpio_devid);
- if (!gpio)
- return -EBUSY;
-
- state->dev = gpio;
- mask = ((1 << nr_pins) - 1) << start;
-
- if (mask & state->alloc_mask) {
- put_device(gpio);
- return -EBUSY;
- }
- state->alloc_mask |= mask;
-
- switch (func) {
- case GPIO_FUNC_GPIO:
- /* TODO */
- return -EINVAL;
- case GPIO_FUNC_A:
- pio2_writel(gpio, ASR, mask);
- pio2_writel(gpio, PDR, mask);
- pio2_writel(gpio, PUDR, mask);
- break;
- case GPIO_FUNC_B:
- pio2_writel(gpio, BSR, mask);
- pio2_writel(gpio, PDR, mask);
- pio2_writel(gpio, PUDR, mask);
- break;
- }
-
- return 0;
+ void *base = gpio_pin_to_addr(pin);
+ uint32_t mask = 1 << (pin & 0x1f);
+
+ if (!base)
+ panic("Invalid GPIO pin %u\n", pin);
+
+ pio2_writel(base, ASR, mask);
+ pio2_writel(base, PDR, mask);
+ if (use_pullup)
+ pio2_writel(base, PUER, mask);
+ else
+ pio2_writel(base, PUDR, mask);
}
-void gpio_free(enum device_id gpio_devid, unsigned int start,
- unsigned int nr_pins)
+void gpio_select_periph_B(unsigned int pin, int use_pullup)
{
- const struct device *gpio;
- struct pio_state *state;
- u32 mask;
-
- state = &pio_state[gpio_devid - DEVICE_PIOA];
- gpio = state->dev;
- mask = ((1 << nr_pins) - 1) << start;
-
- pio2_writel(gpio, ODR, mask);
- pio2_writel(gpio, PER, mask);
-
- state->alloc_mask &= ~mask;
- put_device(gpio);
+ void *base = gpio_pin_to_addr(pin);
+ uint32_t mask = 1 << (pin & 0x1f);
+
+ if (!base)
+ panic("Invalid GPIO pin %u\n", pin);
+
+ pio2_writel(base, BSR, mask);
+ pio2_writel(base, PDR, mask);
+ if (use_pullup)
+ pio2_writel(base, PUER, mask);
+ else
+ pio2_writel(base, PUDR, mask);
}
diff --git a/cpu/at32ap/pio2.h b/cpu/at32ap/pio2.h
index 6b79de3c72b..9719ea8c433 100644
--- a/cpu/at32ap/pio2.h
+++ b/cpu/at32ap/pio2.h
@@ -36,9 +36,9 @@
#define PIO2_OWSR 0x00a8
/* Register access macros */
-#define pio2_readl(port,reg) \
- readl((port)->regs + PIO2_##reg)
-#define pio2_writel(port,reg,value) \
- writel((value), (port)->regs + PIO2_##reg)
+#define pio2_readl(base,reg) \
+ readl((void *)base + PIO2_##reg)
+#define pio2_writel(base,reg,value) \
+ writel((value), (void *)base + PIO2_##reg)
#endif /* __CPU_AT32AP_PIO2_H__ */
diff --git a/cpu/at32ap/pm.c b/cpu/at32ap/pm.c
index 01ac325ee8f..c78d547f85e 100644
--- a/cpu/at32ap/pm.c
+++ b/cpu/at32ap/pm.c
@@ -26,138 +26,17 @@
#include <asm/io.h>
#include <asm/arch/memory-map.h>
-#include <asm/arch/platform.h>
#include "sm.h"
-/* Sanity checks */
-#if (CFG_CLKDIV_CPU > CFG_CLKDIV_HSB) \
- || (CFG_CLKDIV_HSB > CFG_CLKDIV_PBA) \
- || (CFG_CLKDIV_HSB > CFG_CLKDIV_PBB)
-# error Constraint fCPU >= fHSB >= fPB{A,B} violated
-#endif
-#if defined(CONFIG_PLL) && ((CFG_PLL0_MUL < 1) || (CFG_PLL0_DIV < 1))
-# error Invalid PLL multiplier and/or divider
-#endif
-
-DECLARE_GLOBAL_DATA_PTR;
-
-struct clock_domain_state {
- const struct device *bridge;
- unsigned long freq;
- u32 mask;
-};
-static struct clock_domain_state ckd_state[NR_CLOCK_DOMAINS];
-
-int pm_enable_clock(enum clock_domain_id id, unsigned int index)
-{
- const struct clock_domain *ckd = &chip_clock[id];
- struct clock_domain_state *state = &ckd_state[id];
-
- if (ckd->bridge != NO_DEVICE) {
- state->bridge = get_device(ckd->bridge);
- if (!state->bridge)
- return -EBUSY;
- }
-
- state->mask |= 1 << index;
- if (gd->sm)
- writel(state->mask, gd->sm->regs + ckd->reg);
-
- return 0;
-}
-
-void pm_disable_clock(enum clock_domain_id id, unsigned int index)
-{
- const struct clock_domain *ckd = &chip_clock[id];
- struct clock_domain_state *state = &ckd_state[id];
-
- state->mask &= ~(1 << index);
- if (gd->sm)
- writel(state->mask, gd->sm->regs + ckd->reg);
-
- if (ckd->bridge)
- put_device(state->bridge);
-}
-
-unsigned long pm_get_clock_freq(enum clock_domain_id domain)
-{
- return ckd_state[domain].freq;
-}
-
-void pm_init(void)
-{
- uint32_t cksel = 0;
- unsigned long main_clock;
-
- /* Make sure we don't disable any device we're already using */
- get_device(DEVICE_HRAMC);
- get_device(DEVICE_HEBI);
-
- /* Enable the PICO as well */
- ckd_state[CLOCK_CPU].mask |= 1;
-
- gd->sm = get_device(DEVICE_SM);
- if (!gd->sm)
- panic("Unable to claim system manager device!\n");
-
- /* Disable any devices that haven't been explicitly claimed */
- sm_writel(gd->sm, PM_PBB_MASK, ckd_state[CLOCK_PBB].mask);
- sm_writel(gd->sm, PM_PBA_MASK, ckd_state[CLOCK_PBA].mask);
- sm_writel(gd->sm, PM_HSB_MASK, ckd_state[CLOCK_HSB].mask);
- sm_writel(gd->sm, PM_CPU_MASK, ckd_state[CLOCK_CPU].mask);
#ifdef CONFIG_PLL
- /* Initialize the PLL */
- main_clock = (CFG_OSC0_HZ / CFG_PLL0_DIV) * CFG_PLL0_MUL;
-
- sm_writel(gd->sm, PM_PLL0, (SM_BF(PLLCOUNT, CFG_PLL0_SUPPRESS_CYCLES)
- | SM_BF(PLLMUL, CFG_PLL0_MUL - 1)
- | SM_BF(PLLDIV, CFG_PLL0_DIV - 1)
- | SM_BF(PLLOPT, CFG_PLL0_OPT)
- | SM_BF(PLLOSC, 0)
- | SM_BIT(PLLEN)));
-
- /* Wait for lock */
- while (!(sm_readl(gd->sm, PM_ISR) & SM_BIT(LOCK0))) ;
+#define MAIN_CLK_RATE ((CFG_OSC0_HZ / CFG_PLL0_DIV) * CFG_PLL0_MUL)
#else
- main_clock = CFG_OSC0_HZ;
+#define MAIN_CLK_RATE (CFG_OSC0_HZ)
#endif
- /* Set up clocks for the CPU and all peripheral buses */
- if (CFG_CLKDIV_CPU) {
- cksel |= SM_BIT(CPUDIV) | SM_BF(CPUSEL, CFG_CLKDIV_CPU - 1);
- ckd_state[CLOCK_CPU].freq = main_clock / (1 << CFG_CLKDIV_CPU);
- } else {
- ckd_state[CLOCK_CPU].freq = main_clock;
- }
- if (CFG_CLKDIV_HSB) {
- cksel |= SM_BIT(HSBDIV) | SM_BF(HSBSEL, CFG_CLKDIV_HSB - 1);
- ckd_state[CLOCK_HSB].freq = main_clock / (1 << CFG_CLKDIV_HSB);
- } else {
- ckd_state[CLOCK_HSB].freq = main_clock;
- }
- if (CFG_CLKDIV_PBA) {
- cksel |= SM_BIT(PBADIV) | SM_BF(PBASEL, CFG_CLKDIV_PBA - 1);
- ckd_state[CLOCK_PBA].freq = main_clock / (1 << CFG_CLKDIV_PBA);
- } else {
- ckd_state[CLOCK_PBA].freq = main_clock;
- }
- if (CFG_CLKDIV_PBB) {
- cksel |= SM_BIT(PBBDIV) | SM_BF(PBBSEL, CFG_CLKDIV_PBB - 1);
- ckd_state[CLOCK_PBB].freq = main_clock / (1 << CFG_CLKDIV_PBB);
- } else {
- ckd_state[CLOCK_PBB].freq = main_clock;
- }
- sm_writel(gd->sm, PM_CKSEL, cksel);
-
- /* CFG_HZ currently depends on cpu_hz */
- gd->cpu_hz = ckd_state[CLOCK_CPU].freq;
+DECLARE_GLOBAL_DATA_PTR;
-#ifdef CONFIG_PLL
- /* Use PLL0 as main clock */
- sm_writel(gd->sm, PM_MCCTRL, SM_BIT(PLLSEL));
-#endif
-}
#endif /* CFG_POWER_MANAGER */
diff --git a/cpu/at32ap/sm.h b/cpu/at32ap/sm.h
index ce81ef0a463..6492c8e81d2 100644
--- a/cpu/at32ap/sm.h
+++ b/cpu/at32ap/sm.h
@@ -196,9 +196,9 @@
| SM_BF(name,value))
/* Register access macros */
-#define sm_readl(port,reg) \
- readl((port)->regs + SM_##reg)
-#define sm_writel(port,reg,value) \
- writel((value), (port)->regs + SM_##reg)
+#define sm_readl(reg) \
+ readl((void *)SM_BASE + SM_##reg)
+#define sm_writel(reg,value) \
+ writel((value), (void *)SM_BASE + SM_##reg)
#endif /* __CPU_AT32AP_SM_H__ */