summaryrefslogtreecommitdiff
path: root/arch/arm/mach-nomadik
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-nomadik')
-rw-r--r--arch/arm/mach-nomadik/Kconfig16
-rw-r--r--arch/arm/mach-nomadik/Makefile9
-rw-r--r--arch/arm/mach-nomadik/gpio.c83
-rw-r--r--arch/arm/mach-nomadik/include/mach/gpio.h26
-rw-r--r--arch/arm/mach-nomadik/include/mach/mtu.h50
-rw-r--r--arch/arm/mach-nomadik/reset.S14
-rw-r--r--arch/arm/mach-nomadik/timer.c71
7 files changed, 269 insertions, 0 deletions
diff --git a/arch/arm/mach-nomadik/Kconfig b/arch/arm/mach-nomadik/Kconfig
new file mode 100644
index 0000000..265f336
--- /dev/null
+++ b/arch/arm/mach-nomadik/Kconfig
@@ -0,0 +1,16 @@
+if ARCH_NOMADIK
+
+choice
+ prompt "Nomadik board select"
+
+config NOMADIK_NHK8815
+ bool "ST 8815 Nomadik Hardware Kit"
+
+endchoice
+
+config SYS_SOC
+ default "nomadik"
+
+source "board/st/nhk8815/Kconfig"
+
+endif
diff --git a/arch/arm/mach-nomadik/Makefile b/arch/arm/mach-nomadik/Makefile
new file mode 100644
index 0000000..cdf1345
--- /dev/null
+++ b/arch/arm/mach-nomadik/Makefile
@@ -0,0 +1,9 @@
+#
+# (C) Copyright 2000-2006
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# SPDX-License-Identifier: GPL-2.0+
+#
+
+obj-y = timer.o gpio.o
+obj-y += reset.o
diff --git a/arch/arm/mach-nomadik/gpio.c b/arch/arm/mach-nomadik/gpio.c
new file mode 100644
index 0000000..eff5b2b
--- /dev/null
+++ b/arch/arm/mach-nomadik/gpio.c
@@ -0,0 +1,83 @@
+/*
+ * (C) Copyright 2009 Alessandro Rubini
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/gpio.h>
+
+static unsigned long gpio_base[4] = {
+ NOMADIK_GPIO0_BASE,
+ NOMADIK_GPIO1_BASE,
+ NOMADIK_GPIO2_BASE,
+ NOMADIK_GPIO3_BASE
+};
+
+enum gpio_registers {
+ GPIO_DAT = 0x00, /* data register */
+ GPIO_DATS = 0x04, /* data set */
+ GPIO_DATC = 0x08, /* data clear */
+ GPIO_PDIS = 0x0c, /* pull disable */
+ GPIO_DIR = 0x10, /* direction */
+ GPIO_DIRS = 0x14, /* direction set */
+ GPIO_DIRC = 0x18, /* direction clear */
+ GPIO_AFSLA = 0x20, /* alternate function select A */
+ GPIO_AFSLB = 0x24, /* alternate function select B */
+};
+
+static inline unsigned long gpio_to_base(int gpio)
+{
+ return gpio_base[gpio / 32];
+}
+
+static inline u32 gpio_to_bit(int gpio)
+{
+ return 1 << (gpio & 0x1f);
+}
+
+void nmk_gpio_af(int gpio, int alternate_function)
+{
+ unsigned long base = gpio_to_base(gpio);
+ u32 bit = gpio_to_bit(gpio);
+ u32 afunc, bfunc;
+
+ /* alternate function is 0..3, with one bit per register */
+ afunc = readl(base + GPIO_AFSLA) & ~bit;
+ bfunc = readl(base + GPIO_AFSLB) & ~bit;
+ if (alternate_function & 1) afunc |= bit;
+ if (alternate_function & 2) bfunc |= bit;
+ writel(afunc, base + GPIO_AFSLA);
+ writel(bfunc, base + GPIO_AFSLB);
+}
+
+void nmk_gpio_dir(int gpio, int dir)
+{
+ unsigned long base = gpio_to_base(gpio);
+ u32 bit = gpio_to_bit(gpio);
+
+ if (dir)
+ writel(bit, base + GPIO_DIRS);
+ else
+ writel(bit, base + GPIO_DIRC);
+}
+
+void nmk_gpio_set(int gpio, int val)
+{
+ unsigned long base = gpio_to_base(gpio);
+ u32 bit = gpio_to_bit(gpio);
+
+ if (val)
+ writel(bit, base + GPIO_DATS);
+ else
+ writel(bit, base + GPIO_DATC);
+}
+
+int nmk_gpio_get(int gpio)
+{
+ unsigned long base = gpio_to_base(gpio);
+ u32 bit = gpio_to_bit(gpio);
+
+ return readl(base + GPIO_DAT) & bit;
+}
diff --git a/arch/arm/mach-nomadik/include/mach/gpio.h b/arch/arm/mach-nomadik/include/mach/gpio.h
new file mode 100644
index 0000000..311758a
--- /dev/null
+++ b/arch/arm/mach-nomadik/include/mach/gpio.h
@@ -0,0 +1,26 @@
+/*
+ * (C) Copyright 2009 Alessandro Rubini
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+#ifndef __NMK_GPIO_H__
+#define __NMK_GPIO_H__
+
+/*
+ * These functions are called from the soft-i2c driver, but
+ * are also used by board files to set output bits.
+ */
+
+enum nmk_af { /* alternate function settings */
+ GPIO_GPIO = 0,
+ GPIO_ALT_A,
+ GPIO_ALT_B,
+ GPIO_ALT_C
+};
+
+extern void nmk_gpio_af(int gpio, int alternate_function);
+extern void nmk_gpio_dir(int gpio, int dir);
+extern void nmk_gpio_set(int gpio, int val);
+extern int nmk_gpio_get(int gpio);
+
+#endif /* __NMK_GPIO_H__ */
diff --git a/arch/arm/mach-nomadik/include/mach/mtu.h b/arch/arm/mach-nomadik/include/mach/mtu.h
new file mode 100644
index 0000000..f89f242
--- /dev/null
+++ b/arch/arm/mach-nomadik/include/mach/mtu.h
@@ -0,0 +1,50 @@
+/*
+ * (C) Copyright 2009 Alessandro Rubini
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef __ASM_ARCH_MTU_H
+#define __ASM_ARCH_MTU_H
+
+/*
+ * The MTU device hosts four different counters, with 4 set of
+ * registers. These are register names.
+ */
+
+#define MTU_IMSC 0x00 /* Interrupt mask set/clear */
+#define MTU_RIS 0x04 /* Raw interrupt status */
+#define MTU_MIS 0x08 /* Masked interrupt status */
+#define MTU_ICR 0x0C /* Interrupt clear register */
+
+/* per-timer registers take 0..3 as argument */
+#define MTU_LR(x) (0x10 + 0x10 * (x) + 0x00) /* Load value */
+#define MTU_VAL(x) (0x10 + 0x10 * (x) + 0x04) /* Current value */
+#define MTU_CR(x) (0x10 + 0x10 * (x) + 0x08) /* Control reg */
+#define MTU_BGLR(x) (0x10 + 0x10 * (x) + 0x0c) /* At next overflow */
+
+/* bits for the control register */
+#define MTU_CRn_ENA 0x80
+#define MTU_CRn_PERIODIC 0x40 /* if 0 = free-running */
+#define MTU_CRn_PRESCALE_MASK 0x0c
+#define MTU_CRn_PRESCALE_1 0x00
+#define MTU_CRn_PRESCALE_16 0x04
+#define MTU_CRn_PRESCALE_256 0x08
+#define MTU_CRn_32BITS 0x02
+#define MTU_CRn_ONESHOT 0x01 /* if 0 = wraps reloading from BGLR*/
+
+/* Other registers are usual amba/primecell registers, currently not used */
+#define MTU_ITCR 0xff0
+#define MTU_ITOP 0xff4
+
+#define MTU_PERIPH_ID0 0xfe0
+#define MTU_PERIPH_ID1 0xfe4
+#define MTU_PERIPH_ID2 0xfe8
+#define MTU_PERIPH_ID3 0xfeC
+
+#define MTU_PCELL0 0xff0
+#define MTU_PCELL1 0xff4
+#define MTU_PCELL2 0xff8
+#define MTU_PCELL3 0xffC
+
+#endif /* __ASM_ARCH_MTU_H */
diff --git a/arch/arm/mach-nomadik/reset.S b/arch/arm/mach-nomadik/reset.S
new file mode 100644
index 0000000..ec95472
--- /dev/null
+++ b/arch/arm/mach-nomadik/reset.S
@@ -0,0 +1,14 @@
+#include <config.h>
+/*
+ * Processor reset for Nomadik
+ */
+
+ .align 5
+.globl reset_cpu
+reset_cpu:
+ ldr r0, =NOMADIK_SRC_BASE /* System and Reset Controller */
+ ldr r1, =0x1
+ str r1, [r0, #0x18]
+
+_loop_forever:
+ b _loop_forever
diff --git a/arch/arm/mach-nomadik/timer.c b/arch/arm/mach-nomadik/timer.c
new file mode 100644
index 0000000..775d0b7
--- /dev/null
+++ b/arch/arm/mach-nomadik/timer.c
@@ -0,0 +1,71 @@
+/*
+ * (C) Copyright 2009 Alessandro Rubini
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/mtu.h>
+
+/*
+ * The timer is a decrementer, we'll left it free running at 2.4MHz.
+ * We have 2.4 ticks per microsecond and an overflow in almost 30min
+ */
+#define TIMER_CLOCK (24 * 100 * 1000)
+#define COUNT_TO_USEC(x) ((x) * 5 / 12) /* overflows at 6min */
+#define USEC_TO_COUNT(x) ((x) * 12 / 5) /* overflows at 6min */
+#define TICKS_PER_HZ (TIMER_CLOCK / CONFIG_SYS_HZ)
+#define TICKS_TO_HZ(x) ((x) / TICKS_PER_HZ)
+
+/* macro to read the decrementing 32 bit timer as an increasing count */
+#define READ_TIMER() (0 - readl(CONFIG_SYS_TIMERBASE + MTU_VAL(0)))
+
+/* Configure a free-running, auto-wrap counter with no prescaler */
+int timer_init(void)
+{
+ ulong val;
+
+ writel(MTU_CRn_ENA | MTU_CRn_PRESCALE_1 | MTU_CRn_32BITS,
+ CONFIG_SYS_TIMERBASE + MTU_CR(0));
+
+ /* Reset the timer */
+ writel(0, CONFIG_SYS_TIMERBASE + MTU_LR(0));
+ /*
+ * The load-register isn't really immediate: it changes on clock
+ * edges, so we must wait for our newly-written value to appear.
+ * Since we might miss reading 0, wait for any change in value.
+ */
+ val = READ_TIMER();
+ while (READ_TIMER() == val)
+ ;
+
+ return 0;
+}
+
+/* Return how many HZ passed since "base" */
+ulong get_timer(ulong base)
+{
+ return TICKS_TO_HZ(READ_TIMER()) - base;
+}
+
+/* Delay x useconds */
+void __udelay(unsigned long usec)
+{
+ ulong ini, end;
+
+ ini = READ_TIMER();
+ end = ini + USEC_TO_COUNT(usec);
+ while ((signed)(end - READ_TIMER()) > 0)
+ ;
+}
+
+unsigned long long get_ticks(void)
+{
+ return get_timer(0);
+}
+
+ulong get_tbclk(void)
+{
+ return CONFIG_SYS_HZ;
+}