summaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-at91
diff options
context:
space:
mode:
authorJean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>2009-10-04 01:20:18 +0200
committerJean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>2009-10-20 15:02:36 +0200
commit81362c2b2a81d63f93e9534aa624c7f265c55947 (patch)
tree23b3def1f64276305469b9e2a4a86dc25895e651 /arch/arm/mach-at91
parent35144c0b867d03a09118f02f1e9e43111e6f544a (diff)
downloadbarebox-81362c2b2a81d63f93e9534aa624c7f265c55947.tar.gz
barebox-81362c2b2a81d63f93e9534aa624c7f265c55947.tar.xz
at91sam9: move to at91
this will allow to add at91rm9200 with the same api as done in the kernel Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
Diffstat (limited to 'arch/arm/mach-at91')
-rw-r--r--arch/arm/mach-at91/Makefile3
-rw-r--r--arch/arm/mach-at91/at91sam9260.c26
-rw-r--r--arch/arm/mach-at91/at91sam9263.c26
-rw-r--r--arch/arm/mach-at91/clocksource.c77
-rw-r--r--arch/arm/mach-at91/gpio.c192
5 files changed, 324 insertions, 0 deletions
diff --git a/arch/arm/mach-at91/Makefile b/arch/arm/mach-at91/Makefile
new file mode 100644
index 0000000000..5d57900c33
--- /dev/null
+++ b/arch/arm/mach-at91/Makefile
@@ -0,0 +1,3 @@
+obj-y += clocksource.o gpio.o
+obj-$(CONFIG_ARCH_AT91SAM9260) += at91sam9260.o
+obj-$(CONFIG_ARCH_AT91SAM9263) += at91sam9263.o
diff --git a/arch/arm/mach-at91/at91sam9260.c b/arch/arm/mach-at91/at91sam9260.c
new file mode 100644
index 0000000000..04e954b039
--- /dev/null
+++ b/arch/arm/mach-at91/at91sam9260.c
@@ -0,0 +1,26 @@
+#include <common.h>
+#include <gpio.h>
+#include <init.h>
+#include <asm/hardware.h>
+
+static struct at91_gpio_bank at91sam9260_gpio[] = {
+ {
+ .id = AT91C_ID_PIOA,
+ .regbase = (void __iomem *)AT91C_BASE_PIOA,
+ }, {
+ .id = AT91C_ID_PIOB,
+ .regbase = (void __iomem *)AT91C_BASE_PIOB,
+ }, {
+ .id = AT91C_ID_PIOC,
+ .regbase = (void __iomem *)AT91C_BASE_PIOC,
+ }
+};
+
+static int at91sam9260_initialize(void)
+{
+ /* Register GPIO subsystem */
+ at91_gpio_init(at91sam9260_gpio, 3);
+ return 0;
+}
+
+core_initcall(at91sam9260_initialize);
diff --git a/arch/arm/mach-at91/at91sam9263.c b/arch/arm/mach-at91/at91sam9263.c
new file mode 100644
index 0000000000..8688b979eb
--- /dev/null
+++ b/arch/arm/mach-at91/at91sam9263.c
@@ -0,0 +1,26 @@
+#include <common.h>
+#include <gpio.h>
+#include <init.h>
+#include <asm/hardware.h>
+
+static struct at91_gpio_bank at91sam9263_gpio[] = {
+ {
+ .id = AT91C_ID_PIOA,
+ .regbase = (void __iomem *)AT91C_BASE_PIOA,
+ }, {
+ .id = AT91C_ID_PIOB,
+ .regbase = (void __iomem *)AT91C_BASE_PIOB,
+ }, {
+ .id = AT91C_ID_PIOCDE,
+ .regbase = (void __iomem *)AT91C_BASE_PIOC,
+ }
+};
+
+static int at91sam9263_initialize(void)
+{
+ /* Register GPIO subsystem */
+ at91_gpio_init(at91sam9263_gpio, 3);
+ return 0;
+}
+
+core_initcall(at91sam9263_initialize);
diff --git a/arch/arm/mach-at91/clocksource.c b/arch/arm/mach-at91/clocksource.c
new file mode 100644
index 0000000000..86a51d584e
--- /dev/null
+++ b/arch/arm/mach-at91/clocksource.c
@@ -0,0 +1,77 @@
+/*
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Marius Groeger <mgroeger@sysgo.de>
+ *
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Alex Zuepke <azu@sysgo.de>
+ *
+ * (C) Copyright 2002
+ * Gary Jennejohn, DENX Software Engineering, <gj@denx.de>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <init.h>
+#include <clock.h>
+#include <asm/hardware.h>
+#include <asm/io.h>
+
+uint64_t at91sam9_clocksource_read(void)
+{
+ return readl(AT91C_PITC_PIIR);
+}
+
+static struct clocksource cs = {
+ .read = at91sam9_clocksource_read,
+ .mask = 0xffffffff,
+ .shift = 10,
+};
+
+static int clocksource_init (void)
+{
+ /*
+ * Enable PITC Clock
+ * The clock is already enabled for system controller in boot
+ */
+ writel(1 << AT91C_ID_SYS, AT91C_PMC_PCER);
+
+ /* Enable PITC */
+ writel(0xfffff | AT91C_PITC_PITEN, AT91C_PITC_PIMR);
+
+ cs.mult = clocksource_hz2mult(1000000 * 6, cs.shift);
+
+ init_clock(&cs);
+
+ return 0;
+}
+
+core_initcall(clocksource_init);
+
+/*
+ * Reset the cpu by setting up the watchdog timer and let it time out
+ */
+void reset_cpu (ulong ignored)
+{
+ writel((0xa5 << 24) | AT91C_RSTC_PROCRST | AT91C_RSTC_PERRST,
+ AT91C_RSTC_RCR);
+}
+EXPORT_SYMBOL(reset_cpu);
diff --git a/arch/arm/mach-at91/gpio.c b/arch/arm/mach-at91/gpio.c
new file mode 100644
index 0000000000..09894b7fd0
--- /dev/null
+++ b/arch/arm/mach-at91/gpio.c
@@ -0,0 +1,192 @@
+/*
+ *
+ * (c) 2008 Sascha Hauer, Pengutronix <s.hauer@pengutronix.de>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <errno.h>
+#include <asm/io.h>
+#include <gpio.h>
+
+#define OFS_PIO_PER 0x00 /* Enable Register */
+#define OFS_PIO_PDR 0x04 /* Disable Register */
+#define OFS_PIO_PSR 0x08 /* Status Register */
+#define OFS_PIO_OER 0x10 /* Output Enable Register */
+#define OFS_PIO_ODR 0x14 /* Output Disable Register */
+#define OFS_PIO_OSR 0x18 /* Output Status Register */
+#define OFS_PIO_IFER 0x20 /* Glitch Input Filter Enable */
+#define OFS_PIO_IFDR 0x24 /* Glitch Input Filter Disable */
+#define OFS_PIO_IFSR 0x28 /* Glitch Input Filter Status */
+#define OFS_PIO_SODR 0x30 /* Set Output Data Register */
+#define OFS_PIO_CODR 0x34 /* Clear Output Data Register */
+#define OFS_PIO_ODSR 0x38 /* Output Data Status Register */
+#define OFS_PIO_PDSR 0x3c /* Pin Data Status Register */
+#define OFS_PIO_IER 0x40 /* Interrupt Enable Register */
+#define OFS_PIO_IDR 0x44 /* Interrupt Disable Register */
+#define OFS_PIO_IMR 0x48 /* Interrupt Mask Register */
+#define OFS_PIO_ISR 0x4c /* Interrupt Status Register */
+#define OFS_PIO_MDER 0x50 /* Multi-driver Enable Register */
+#define OFS_PIO_MDDR 0x54 /* Multi-driver Disable Register */
+#define OFS_PIO_MDSR 0x58 /* Multi-driver Status Register */
+#define OFS_PIO_PUDR 0x60 /* Pull-up Disable Register */
+#define OFS_PIO_PUER 0x64 /* Pull-up Enable Register */
+#define OFS_PIO_PUSR 0x68 /* Pull-up Status Register */
+#define OFS_PIO_ASR 0x70 /* Peripheral A Select Register */
+#define OFS_PIO_BSR 0x74 /* Peripheral B Select Register */
+#define OFS_PIO_ABSR 0x78 /* AB Status Register */
+#define OFS_PIO_OWER 0xa0 /* Output Write Enable Register */
+#define OFS_PIO_OWDR 0xa4 /* Output Write Disable Register */
+#define OFS_PIO_OWSR 0xa8 /* Output Write Status Register */
+
+static int gpio_banks;
+static struct at91_gpio_bank *gpio;
+
+static inline void __iomem *pin_to_controller(unsigned pin)
+{
+ pin /= 32;
+ if (likely(pin < gpio_banks))
+ return gpio[pin].regbase;
+
+ return NULL;
+}
+
+static inline unsigned pin_to_mask(unsigned pin)
+{
+ return 1 << (pin % 32);
+}
+
+/*
+ * mux the pin to the gpio controller (instead of "A" or "B" peripheral), and
+ * configure it for an input.
+ */
+int at91_set_gpio_input(unsigned pin, int use_pullup)
+{
+ void __iomem *pio = pin_to_controller(pin);
+ unsigned mask = pin_to_mask(pin);
+
+ if (!pio)
+ return -EINVAL;
+
+ writel(mask, pio + OFS_PIO_IDR);
+ writel(mask, pio + (use_pullup ? OFS_PIO_PUER : OFS_PIO_PUDR));
+ writel(mask, pio + OFS_PIO_ODR);
+ writel(mask, pio + OFS_PIO_PER);
+ return 0;
+}
+EXPORT_SYMBOL(at91_set_gpio_input);
+
+/*
+ * mux the pin to the gpio controller (instead of "A" or "B" peripheral),
+ * and configure it for an output.
+ */
+int at91_set_gpio_output(unsigned pin, int value)
+{
+ void __iomem *pio = pin_to_controller(pin);
+ unsigned mask = pin_to_mask(pin);
+
+ if (!pio)
+ return -EINVAL;
+
+ writel(mask, pio + OFS_PIO_IDR);
+ writel(mask, pio + OFS_PIO_PUDR);
+ writel(mask, pio + (value ? OFS_PIO_SODR : OFS_PIO_CODR));
+ writel(mask, pio + OFS_PIO_OER);
+ writel(mask, pio + OFS_PIO_PER);
+ return 0;
+}
+EXPORT_SYMBOL(at91_set_gpio_output);
+
+int gpio_direction_input(unsigned pin)
+{
+ void __iomem *pio = pin_to_controller(pin);
+ unsigned mask = pin_to_mask(pin);
+
+ if (!pio || !(readl(pio + OFS_PIO_PSR) & mask))
+ return -EINVAL;
+ writel(mask, pio + OFS_PIO_ODR);
+ return 0;
+}
+EXPORT_SYMBOL(gpio_direction_input);
+
+int gpio_direction_output(unsigned pin, int value)
+{
+ void __iomem *pio = pin_to_controller(pin);
+ unsigned mask = pin_to_mask(pin);
+
+ if (!pio || !(readl(pio + OFS_PIO_PSR) & mask))
+ return -EINVAL;
+ writel(mask, pio + (value ? OFS_PIO_SODR : OFS_PIO_CODR));
+ writel(mask, pio + OFS_PIO_OER);
+ return 0;
+}
+EXPORT_SYMBOL(gpio_direction_output);
+
+/*--------------------------------------------------------------------------*/
+
+/*
+ * assuming the pin is muxed as a gpio output, set its value.
+ */
+void gpio_set_value(unsigned pin, int value)
+{
+ void __iomem *pio = pin_to_controller(pin);
+ unsigned mask = pin_to_mask(pin);
+
+ if (!pio)
+ return;
+ writel(mask, pio + (value ? OFS_PIO_SODR : OFS_PIO_CODR));
+}
+EXPORT_SYMBOL(gpio_set_value);
+
+
+/*
+ * read the pin's value (works even if it's not muxed as a gpio).
+ */
+int gpio_get_value(unsigned pin)
+{
+ void __iomem *pio = pin_to_controller(pin);
+ unsigned mask = pin_to_mask(pin);
+ u32 pdsr;
+
+ if (!pio)
+ return -EINVAL;
+ pdsr = readl(pio + OFS_PIO_PDSR);
+ return (pdsr & mask) != 0;
+}
+EXPORT_SYMBOL(gpio_get_value);
+
+int at91_gpio_init(struct at91_gpio_bank *data, int nr_banks)
+{
+ unsigned i;
+ struct at91_gpio_bank *last;
+
+ gpio = data;
+ gpio_banks = nr_banks;
+
+ for (i = 0, last = NULL; i < nr_banks; i++, last = data, data++) {
+ data->chipbase = i * 32;
+
+ /* AT91SAM9263_ID_PIOCDE groups PIOC, PIOD, PIOE */
+ if (last && last->id == data->id)
+ last->next = data;
+ }
+
+ return 0;
+}