ARM: 5786/1: Introduce plat-nomadik, MTU code re-organization
authorSrinidhi Kasagar <srinidhi.kasagar@stericsson.com>
Thu, 12 Nov 2009 05:20:54 +0000 (06:20 +0100)
committerRussell King <rmk+kernel@arm.linux.org.uk>
Sat, 28 Nov 2009 10:22:51 +0000 (10:22 +0000)
Introduce the plat-nomadik folder for ST-Ericsson
machines including the existing nomadik 8815 architecture.
This also moves the existing MTU (MultiTimerUnit)
of nomadik 8815 to the proposed plat-nomadik and adds
HAS_MTU. The patch has been re-based to 2.6.32-rc6

Signed-off-by: srinidhi kasagar <srinidhi.kasagar@stericsson.com>
Acked-by: Alessandro Rubini <rubini@unipv.it>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
12 files changed:
arch/arm/Kconfig
arch/arm/Makefile
arch/arm/mach-nomadik/Kconfig
arch/arm/mach-nomadik/Makefile
arch/arm/mach-nomadik/board-nhk8815.c
arch/arm/mach-nomadik/include/mach/mtu.h [deleted file]
arch/arm/mach-nomadik/include/mach/setup.h
arch/arm/mach-nomadik/timer.c [deleted file]
arch/arm/plat-nomadik/Kconfig [new file with mode: 0644]
arch/arm/plat-nomadik/Makefile [new file with mode: 0644]
arch/arm/plat-nomadik/include/plat/mtu.h [new file with mode: 0644]
arch/arm/plat-nomadik/timer.c [new file with mode: 0644]

index 1c4119c600407447cd67ce074eb7a84265ce2bc9..76cd466ad48ca878549d61bc5f564bdb3ec18a83 100644 (file)
@@ -787,6 +787,7 @@ source "arch/arm/mach-at91/Kconfig"
 source "arch/arm/plat-mxc/Kconfig"
 
 source "arch/arm/mach-nomadik/Kconfig"
+source "arch/arm/plat-nomadik/Kconfig"
 
 source "arch/arm/mach-netx/Kconfig"
 
index a73caaf667633c286e8812da535aa43203170134..1bee36fa5fb16318a286514dd2255e0413c6eccc 100644 (file)
@@ -176,6 +176,7 @@ machine-$(CONFIG_ARCH_MXC91231)             := mxc91231
 plat-$(CONFIG_ARCH_MXC)                := mxc
 plat-$(CONFIG_ARCH_OMAP)       := omap
 plat-$(CONFIG_PLAT_IOP)                := iop
+plat-$(CONFIG_PLAT_NOMADIK)    := nomadik
 plat-$(CONFIG_PLAT_ORION)      := orion
 plat-$(CONFIG_PLAT_PXA)                := pxa
 plat-$(CONFIG_PLAT_S3C24XX)    := s3c24xx s3c
index 2a02b49c40f05efad4210c6a8b6c050db0ffb074..3c5e0f522e9ce507f6ceb95fcd605ef3bd734334 100644 (file)
@@ -5,13 +5,13 @@ menu "Nomadik boards"
 config MACH_NOMADIK_8815NHK
        bool "ST 8815 Nomadik Hardware Kit (evaluation board)"
        select NOMADIK_8815
+       select HAS_MTU
 
 endmenu
 
 config NOMADIK_8815
        bool
 
-
 config I2C_BITBANG_8815NHK
        tristate "Driver for bit-bang busses found on the 8815 NHK"
        depends on I2C && MACH_NOMADIK_8815NHK
index 412040982a402ed18450b69328ed0e5e9a562a4f..36f67fb207d21ab0635623ceeb5ff5bdd1dad21b 100644 (file)
@@ -7,7 +7,7 @@
 
 # Object file lists.
 
-obj-y                  += clock.o timer.o gpio.o
+obj-y                  += clock.o gpio.o
 
 # Cpu revision
 obj-$(CONFIG_NOMADIK_8815) += cpu-8815.o
index 6bfd537d5afbeba3f4518c5381f3711cac5d9311..116394484e7184d343fdfd18868bfc65ba4c613f 100644 (file)
 #include <asm/mach/arch.h>
 #include <asm/mach/irq.h>
 #include <asm/mach/flash.h>
+
+#include <plat/mtu.h>
+
 #include <mach/setup.h>
 #include <mach/nand.h>
 #include <mach/fsmc.h>
 #include "clock.h"
 
+/* Initial value for SRC control register: all timers use MXTAL/8 source */
+#define SRC_CR_INIT_MASK       0x00007fff
+#define SRC_CR_INIT_VAL                0x2aaa8000
+
 /* These adresses span 16MB, so use three individual pages */
 static struct resource nhk8815_nand_resources[] = {
        {
@@ -239,6 +246,26 @@ static struct platform_device *nhk8815_platform_devices[] __initdata = {
        /* will add more devices */
 };
 
+static void __init nomadik_timer_init(void)
+{
+       u32 src_cr;
+
+       /* Configure timer sources in "system reset controller" ctrl reg */
+       src_cr = readl(io_p2v(NOMADIK_SRC_BASE));
+       src_cr &= SRC_CR_INIT_MASK;
+       src_cr |= SRC_CR_INIT_VAL;
+       writel(src_cr, io_p2v(NOMADIK_SRC_BASE));
+
+       /* Save global pointer to mtu, used by platform timer code */
+       mtu_base = io_p2v(NOMADIK_MTU0_BASE);
+
+       nmdk_timer_init();
+}
+
+static struct sys_timer nomadik_timer = {
+       .init   = nomadik_timer_init,
+};
+
 static void __init nhk8815_platform_init(void)
 {
        int i;
diff --git a/arch/arm/mach-nomadik/include/mach/mtu.h b/arch/arm/mach-nomadik/include/mach/mtu.h
deleted file mode 100644 (file)
index 76da7f0..0000000
+++ /dev/null
@@ -1,45 +0,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 */
-
index a4e468cf63da39efe89d21595159c6bbd0c038db..b7897edf1f3577cac64769b6a31f8d869dd6bcaf 100644 (file)
@@ -15,7 +15,7 @@
 extern void cpu8815_map_io(void);
 extern void cpu8815_platform_init(void);
 extern void cpu8815_init_irq(void);
-extern struct sys_timer nomadik_timer;
+extern void nmdk_timer_init(void);
 
 #endif /* NOMADIK_8815 */
 
diff --git a/arch/arm/mach-nomadik/timer.c b/arch/arm/mach-nomadik/timer.c
deleted file mode 100644 (file)
index d1738e7..0000000
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- *  linux/arch/arm/mach-nomadik/timer.c
- *
- * Copyright (C) 2008 STMicroelectronics
- * Copyright (C) 2009 Alessandro Rubini, somewhat based on at91sam926x
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2, as
- * published by the Free Software Foundation.
- */
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/io.h>
-#include <linux/clockchips.h>
-#include <linux/jiffies.h>
-#include <asm/mach/time.h>
-#include <mach/mtu.h>
-
-#define TIMER_CTRL     0x80    /* No divisor */
-#define TIMER_PERIODIC 0x40
-#define TIMER_SZ32BIT  0x02
-
-/* Initial value for SRC control register: all timers use MXTAL/8 source */
-#define SRC_CR_INIT_MASK       0x00007fff
-#define SRC_CR_INIT_VAL                0x2aaa8000
-
-static u32     nmdk_count;             /* accumulated count */
-static u32     nmdk_cycle;             /* write-once */
-static __iomem void *mtu_base;
-
-/*
- * clocksource: the MTU device is a decrementing counters, so we negate
- * the value being read.
- */
-static cycle_t nmdk_read_timer(struct clocksource *cs)
-{
-       u32 count = readl(mtu_base + MTU_VAL(0));
-       return nmdk_count + nmdk_cycle - count;
-
-}
-
-static struct clocksource nmdk_clksrc = {
-       .name           = "mtu_0",
-       .rating         = 120,
-       .read           = nmdk_read_timer,
-       .shift          = 20,
-       .flags          = CLOCK_SOURCE_IS_CONTINUOUS,
-};
-
-/*
- * Clockevent device: currently only periodic mode is supported
- */
-static void nmdk_clkevt_mode(enum clock_event_mode mode,
-                            struct clock_event_device *dev)
-{
-       unsigned long flags;
-
-       switch (mode) {
-       case CLOCK_EVT_MODE_PERIODIC:
-               /* enable interrupts -- and count current value? */
-               raw_local_irq_save(flags);
-               writel(readl(mtu_base + MTU_IMSC) | 1, mtu_base + MTU_IMSC);
-               raw_local_irq_restore(flags);
-               break;
-       case CLOCK_EVT_MODE_ONESHOT:
-               BUG(); /* Not supported, yet */
-               /* FALLTHROUGH */
-       case CLOCK_EVT_MODE_SHUTDOWN:
-       case CLOCK_EVT_MODE_UNUSED:
-               /* disable irq */
-               raw_local_irq_save(flags);
-               writel(readl(mtu_base + MTU_IMSC) & ~1, mtu_base + MTU_IMSC);
-               raw_local_irq_restore(flags);
-               break;
-       case CLOCK_EVT_MODE_RESUME:
-               break;
-       }
-}
-
-static struct clock_event_device nmdk_clkevt = {
-       .name           = "mtu_0",
-       .features       = CLOCK_EVT_FEAT_PERIODIC,
-       .shift          = 32,
-       .rating         = 100,
-       .set_mode       = nmdk_clkevt_mode,
-};
-
-/*
- * IRQ Handler for the timer 0 of the MTU block. The irq is not shared
- * as we are the only users of mtu0 by now.
- */
-static irqreturn_t nmdk_timer_interrupt(int irq, void *dev_id)
-{
-       /* ack: "interrupt clear register" */
-       writel( 1 << 0, mtu_base + MTU_ICR);
-
-       /* we can't count lost ticks, unfortunately */
-       nmdk_count += nmdk_cycle;
-       nmdk_clkevt.event_handler(&nmdk_clkevt);
-
-       return IRQ_HANDLED;
-}
-
-/*
- * Set up timer interrupt, and return the current time in seconds.
- */
-static struct irqaction nmdk_timer_irq = {
-       .name           = "Nomadik Timer Tick",
-       .flags          = IRQF_DISABLED | IRQF_TIMER,
-       .handler        = nmdk_timer_interrupt,
-};
-
-static void nmdk_timer_reset(void)
-{
-       u32 cr;
-
-       writel(0, mtu_base + MTU_CR(0)); /* off */
-
-       /* configure load and background-load, and fire it up */
-       writel(nmdk_cycle, mtu_base + MTU_LR(0));
-       writel(nmdk_cycle, mtu_base + MTU_BGLR(0));
-       cr = MTU_CRn_PERIODIC | MTU_CRn_PRESCALE_1 | MTU_CRn_32BITS;
-       writel(cr, mtu_base + MTU_CR(0));
-       writel(cr | MTU_CRn_ENA, mtu_base + MTU_CR(0));
-}
-
-static void __init nmdk_timer_init(void)
-{
-       u32 src_cr;
-       unsigned long rate;
-       int bits;
-
-       rate = CLOCK_TICK_RATE; /* 2.4MHz */
-       nmdk_cycle = (rate + HZ/2) / HZ;
-
-       /* Configure timer sources in "system reset controller" ctrl reg */
-       src_cr = readl(io_p2v(NOMADIK_SRC_BASE));
-       src_cr &= SRC_CR_INIT_MASK;
-       src_cr |= SRC_CR_INIT_VAL;
-       writel(src_cr, io_p2v(NOMADIK_SRC_BASE));
-
-       /* Save global pointer to mtu, used by functions above */
-       mtu_base = io_p2v(NOMADIK_MTU0_BASE);
-
-       /* Init the timer and register clocksource */
-       nmdk_timer_reset();
-
-       nmdk_clksrc.mult = clocksource_hz2mult(rate, nmdk_clksrc.shift);
-       bits =  8*sizeof(nmdk_count);
-       nmdk_clksrc.mask = CLOCKSOURCE_MASK(bits);
-
-       clocksource_register(&nmdk_clksrc);
-
-       /* Register irq and clockevents */
-       setup_irq(IRQ_MTU0, &nmdk_timer_irq);
-       nmdk_clkevt.mult = div_sc(rate, NSEC_PER_SEC, nmdk_clkevt.shift);
-       nmdk_clkevt.cpumask = cpumask_of(0);
-       clockevents_register_device(&nmdk_clkevt);
-}
-
-struct sys_timer nomadik_timer = {
-       .init           = nmdk_timer_init,
-};
diff --git a/arch/arm/plat-nomadik/Kconfig b/arch/arm/plat-nomadik/Kconfig
new file mode 100644 (file)
index 0000000..e27ee31
--- /dev/null
@@ -0,0 +1,22 @@
+# We keep common IP's here for Nomadik and other similar
+# familiy of processors from ST-Ericsson. At the moment we have
+# just MTU, others to follow soon.
+
+config PLAT_NOMADIK
+       bool
+       depends on ARCH_NOMADIK
+       default y
+       help
+         Common platform code for Nomadik and other ST-Ericsson
+         platforms.
+
+if PLAT_NOMADIK
+
+config HAS_MTU
+       bool
+       help
+         Support for Multi Timer Unit. MTU provides access
+         to multiple interrupt generating programmable
+         32-bit free running decrementing counters.
+
+endif
diff --git a/arch/arm/plat-nomadik/Makefile b/arch/arm/plat-nomadik/Makefile
new file mode 100644 (file)
index 0000000..37c7cdd
--- /dev/null
@@ -0,0 +1,5 @@
+# arch/arm/plat-nomadik/Makefile
+# Copyright 2009 ST-Ericsson
+# Licensed under GPLv2
+
+obj-$(CONFIG_HAS_MTU)  += timer.o
diff --git a/arch/arm/plat-nomadik/include/plat/mtu.h b/arch/arm/plat-nomadik/include/plat/mtu.h
new file mode 100644 (file)
index 0000000..42c9072
--- /dev/null
@@ -0,0 +1,48 @@
+#ifndef __PLAT_MTU_H
+#define __PLAT_MTU_H
+
+/* should be set by the platform code */
+extern void __iomem *mtu_base;
+
+/*
+ * 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 /* __PLAT_MTU_H */
+
diff --git a/arch/arm/plat-nomadik/timer.c b/arch/arm/plat-nomadik/timer.c
new file mode 100644 (file)
index 0000000..62f18ad
--- /dev/null
@@ -0,0 +1,147 @@
+/*
+ *  linux/arch/arm/mach-nomadik/timer.c
+ *
+ * Copyright (C) 2008 STMicroelectronics
+ * Copyright (C) 2009 Alessandro Rubini, somewhat based on at91sam926x
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2, as
+ * published by the Free Software Foundation.
+ */
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <linux/clockchips.h>
+#include <linux/jiffies.h>
+#include <asm/mach/time.h>
+
+#include <plat/mtu.h>
+
+static u32     nmdk_count;             /* accumulated count */
+static u32     nmdk_cycle;             /* write-once */
+
+/* setup by the platform code */
+void __iomem *mtu_base;
+
+/*
+ * clocksource: the MTU device is a decrementing counters, so we negate
+ * the value being read.
+ */
+static cycle_t nmdk_read_timer(struct clocksource *cs)
+{
+       u32 count = readl(mtu_base + MTU_VAL(0));
+       return nmdk_count + nmdk_cycle - count;
+
+}
+
+static struct clocksource nmdk_clksrc = {
+       .name           = "mtu_0",
+       .rating         = 120,
+       .read           = nmdk_read_timer,
+       .shift          = 20,
+       .flags          = CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+/*
+ * Clockevent device: currently only periodic mode is supported
+ */
+static void nmdk_clkevt_mode(enum clock_event_mode mode,
+                            struct clock_event_device *dev)
+{
+       unsigned long flags;
+
+       switch (mode) {
+       case CLOCK_EVT_MODE_PERIODIC:
+               /* enable interrupts -- and count current value? */
+               raw_local_irq_save(flags);
+               writel(readl(mtu_base + MTU_IMSC) | 1, mtu_base + MTU_IMSC);
+               raw_local_irq_restore(flags);
+               break;
+       case CLOCK_EVT_MODE_ONESHOT:
+               BUG(); /* Not supported, yet */
+               /* FALLTHROUGH */
+       case CLOCK_EVT_MODE_SHUTDOWN:
+       case CLOCK_EVT_MODE_UNUSED:
+               /* disable irq */
+               raw_local_irq_save(flags);
+               writel(readl(mtu_base + MTU_IMSC) & ~1, mtu_base + MTU_IMSC);
+               raw_local_irq_restore(flags);
+               break;
+       case CLOCK_EVT_MODE_RESUME:
+               break;
+       }
+}
+
+static struct clock_event_device nmdk_clkevt = {
+       .name           = "mtu_0",
+       .features       = CLOCK_EVT_FEAT_PERIODIC,
+       .shift          = 32,
+       .rating         = 100,
+       .set_mode       = nmdk_clkevt_mode,
+};
+
+/*
+ * IRQ Handler for the timer 0 of the MTU block. The irq is not shared
+ * as we are the only users of mtu0 by now.
+ */
+static irqreturn_t nmdk_timer_interrupt(int irq, void *dev_id)
+{
+       /* ack: "interrupt clear register" */
+       writel(1 << 0, mtu_base + MTU_ICR);
+
+       /* we can't count lost ticks, unfortunately */
+       nmdk_count += nmdk_cycle;
+       nmdk_clkevt.event_handler(&nmdk_clkevt);
+
+       return IRQ_HANDLED;
+}
+
+/*
+ * Set up timer interrupt, and return the current time in seconds.
+ */
+static struct irqaction nmdk_timer_irq = {
+       .name           = "Nomadik Timer Tick",
+       .flags          = IRQF_DISABLED | IRQF_TIMER,
+       .handler        = nmdk_timer_interrupt,
+};
+
+static void nmdk_timer_reset(void)
+{
+       u32 cr;
+
+       writel(0, mtu_base + MTU_CR(0)); /* off */
+
+       /* configure load and background-load, and fire it up */
+       writel(nmdk_cycle, mtu_base + MTU_LR(0));
+       writel(nmdk_cycle, mtu_base + MTU_BGLR(0));
+       cr = MTU_CRn_PERIODIC | MTU_CRn_PRESCALE_1 | MTU_CRn_32BITS;
+       writel(cr, mtu_base + MTU_CR(0));
+       writel(cr | MTU_CRn_ENA, mtu_base + MTU_CR(0));
+}
+
+void __init nmdk_timer_init(void)
+{
+       unsigned long rate;
+       int bits;
+
+       rate = CLOCK_TICK_RATE; /* 2.4MHz */
+       nmdk_cycle = (rate + HZ/2) / HZ;
+
+       /* Init the timer and register clocksource */
+       nmdk_timer_reset();
+
+       nmdk_clksrc.mult = clocksource_hz2mult(rate, nmdk_clksrc.shift);
+       bits =  8*sizeof(nmdk_count);
+       nmdk_clksrc.mask = CLOCKSOURCE_MASK(bits);
+
+       if (clocksource_register(&nmdk_clksrc))
+               printk(KERN_ERR "timer: failed to initialize clock "
+                       "source %s\n", nmdk_clksrc.name);
+
+       /* Register irq and clockevents */
+       setup_irq(IRQ_MTU0, &nmdk_timer_irq);
+       nmdk_clkevt.mult = div_sc(rate, NSEC_PER_SEC, nmdk_clkevt.shift);
+       nmdk_clkevt.cpumask = cpumask_of(0);
+       clockevents_register_device(&nmdk_clkevt);
+}