Merge branch 'devel-stable' into devel
[linux-3.10.git] / arch / arm / mach-versatile / core.c
index 3b1a4ee..3dff864 100644 (file)
 #include <linux/amba/clcd.h>
 #include <linux/amba/pl061.h>
 #include <linux/amba/mmci.h>
-#include <linux/clocksource.h>
-#include <linux/clockchips.h>
-#include <linux/cnt32_to_63.h>
 #include <linux/io.h>
 #include <linux/gfp.h>
 
 #include <asm/clkdev.h>
 #include <asm/system.h>
-#include <mach/hardware.h>
 #include <asm/irq.h>
 #include <asm/leds.h>
 #include <asm/hardware/arm_timer.h>
-#include <asm/hardware/icst307.h>
+#include <asm/hardware/icst.h>
 #include <asm/hardware/vic.h>
 #include <asm/mach-types.h>
 
 #include <asm/mach/irq.h>
 #include <asm/mach/time.h>
 #include <asm/mach/map.h>
+#include <mach/clkdev.h>
+#include <mach/hardware.h>
+#include <mach/platform.h>
+#include <plat/timer-sp.h>
 
 #include "core.h"
-#include "clock.h"
 
 /*
  * All IO addresses are mapped onto VA 0xFFFx.xxxx, where x.xxxx
@@ -59,7 +58,6 @@
  *
  * Setup a VA for the Versatile Vectored Interrupt Controller.
  */
-#define __io_address(n)                __io(IO_ADDRESS(n))
 #define VA_VIC_BASE            __io_address(VERSATILE_VIC_BASE)
 #define VA_SIC_BASE            __io_address(VERSATILE_SIC_BASE)
 
@@ -229,27 +227,6 @@ void __init versatile_map_io(void)
        iotable_init(versatile_io_desc, ARRAY_SIZE(versatile_io_desc));
 }
 
-#define VERSATILE_REFCOUNTER   (__io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_24MHz_OFFSET)
-
-/*
- * This is the Versatile sched_clock implementation.  This has
- * a resolution of 41.7ns, and a maximum value of about 35583 days.
- *
- * The return value is guaranteed to be monotonic in that range as
- * long as there is always less than 89 seconds between successive
- * calls to this function.
- */
-unsigned long long sched_clock(void)
-{
-       unsigned long long v = cnt32_to_63(readl(VERSATILE_REFCOUNTER));
-
-       /* the <<1 gets rid of the cnt_32_to_63 top bit saving on a bic insn */
-       v *= 125<<1;
-       do_div(v, 3<<1);
-
-       return v;
-}
-
 
 #define VERSATILE_FLASHCTRL    (__io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_FLASH_OFFSET)
 
@@ -380,33 +357,40 @@ static struct mmci_platform_data mmc0_plat_data = {
 /*
  * Clock handling
  */
-static const struct icst307_params versatile_oscvco_params = {
-       .ref            = 24000,
-       .vco_max        = 200000,
+static const struct icst_params versatile_oscvco_params = {
+       .ref            = 24000000,
+       .vco_max        = ICST307_VCO_MAX,
+       .vco_min        = ICST307_VCO_MIN,
        .vd_min         = 4 + 8,
        .vd_max         = 511 + 8,
        .rd_min         = 1 + 2,
        .rd_max         = 127 + 2,
+       .s2div          = icst307_s2div,
+       .idx2s          = icst307_idx2s,
 };
 
-static void versatile_oscvco_set(struct clk *clk, struct icst307_vco vco)
+static void versatile_oscvco_set(struct clk *clk, struct icst_vco vco)
 {
-       void __iomem *sys = __io_address(VERSATILE_SYS_BASE);
-       void __iomem *sys_lock = sys + VERSATILE_SYS_LOCK_OFFSET;
+       void __iomem *sys_lock = __io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_LOCK_OFFSET;
        u32 val;
 
-       val = readl(sys + clk->oscoff) & ~0x7ffff;
+       val = readl(clk->vcoreg) & ~0x7ffff;
        val |= vco.v | (vco.r << 9) | (vco.s << 16);
 
        writel(0xa05f, sys_lock);
-       writel(val, sys + clk->oscoff);
+       writel(val, clk->vcoreg);
        writel(0, sys_lock);
 }
 
+static const struct clk_ops osc4_clk_ops = {
+       .round  = icst_clk_round,
+       .set    = icst_clk_set,
+       .setvco = versatile_oscvco_set,
+};
+
 static struct clk osc4_clk = {
+       .ops    = &osc4_clk_ops,
        .params = &versatile_oscvco_params,
-       .oscoff = VERSATILE_SYS_OSCCLCD_OFFSET,
-       .setvco = versatile_oscvco_set,
 };
 
 /*
@@ -852,6 +836,8 @@ void __init versatile_init(void)
 {
        int i;
 
+       osc4_clk.vcoreg = __io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_OSCCLCD_OFFSET;
+
        clkdev_add_table(lookups, ARRAY_SIZE(lookups));
 
        platform_device_register(&versatile_flash_device);
@@ -875,120 +861,6 @@ void __init versatile_init(void)
 #define TIMER1_VA_BASE         (__io_address(VERSATILE_TIMER0_1_BASE) + 0x20)
 #define TIMER2_VA_BASE          __io_address(VERSATILE_TIMER2_3_BASE)
 #define TIMER3_VA_BASE         (__io_address(VERSATILE_TIMER2_3_BASE) + 0x20)
-#define VA_IC_BASE              __io_address(VERSATILE_VIC_BASE) 
-
-/*
- * How long is the timer interval?
- */
-#define TIMER_INTERVAL (TICKS_PER_uSEC * mSEC_10)
-#if TIMER_INTERVAL >= 0x100000
-#define TIMER_RELOAD   (TIMER_INTERVAL >> 8)
-#define TIMER_DIVISOR  (TIMER_CTRL_DIV256)
-#define TICKS2USECS(x) (256 * (x) / TICKS_PER_uSEC)
-#elif TIMER_INTERVAL >= 0x10000
-#define TIMER_RELOAD   (TIMER_INTERVAL >> 4)           /* Divide by 16 */
-#define TIMER_DIVISOR  (TIMER_CTRL_DIV16)
-#define TICKS2USECS(x) (16 * (x) / TICKS_PER_uSEC)
-#else
-#define TIMER_RELOAD   (TIMER_INTERVAL)
-#define TIMER_DIVISOR  (TIMER_CTRL_DIV1)
-#define TICKS2USECS(x) ((x) / TICKS_PER_uSEC)
-#endif
-
-static void timer_set_mode(enum clock_event_mode mode,
-                          struct clock_event_device *clk)
-{
-       unsigned long ctrl;
-
-       switch(mode) {
-       case CLOCK_EVT_MODE_PERIODIC:
-               writel(TIMER_RELOAD, TIMER0_VA_BASE + TIMER_LOAD);
-
-               ctrl = TIMER_CTRL_PERIODIC;
-               ctrl |= TIMER_CTRL_32BIT | TIMER_CTRL_IE | TIMER_CTRL_ENABLE;
-               break;
-       case CLOCK_EVT_MODE_ONESHOT:
-               /* period set, and timer enabled in 'next_event' hook */
-               ctrl = TIMER_CTRL_ONESHOT;
-               ctrl |= TIMER_CTRL_32BIT | TIMER_CTRL_IE;
-               break;
-       case CLOCK_EVT_MODE_UNUSED:
-       case CLOCK_EVT_MODE_SHUTDOWN:
-       default:
-               ctrl = 0;
-       }
-
-       writel(ctrl, TIMER0_VA_BASE + TIMER_CTRL);
-}
-
-static int timer_set_next_event(unsigned long evt,
-                               struct clock_event_device *unused)
-{
-       unsigned long ctrl = readl(TIMER0_VA_BASE + TIMER_CTRL);
-
-       writel(evt, TIMER0_VA_BASE + TIMER_LOAD);
-       writel(ctrl | TIMER_CTRL_ENABLE, TIMER0_VA_BASE + TIMER_CTRL);
-
-       return 0;
-}
-
-static struct clock_event_device timer0_clockevent =    {
-       .name           = "timer0",
-       .shift          = 32,
-       .features       = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
-       .set_mode       = timer_set_mode,
-       .set_next_event = timer_set_next_event,
-};
-
-/*
- * IRQ handler for the timer
- */
-static irqreturn_t versatile_timer_interrupt(int irq, void *dev_id)
-{
-       struct clock_event_device *evt = &timer0_clockevent;
-
-       writel(1, TIMER0_VA_BASE + TIMER_INTCLR);
-
-       evt->event_handler(evt);
-
-       return IRQ_HANDLED;
-}
-
-static struct irqaction versatile_timer_irq = {
-       .name           = "Versatile Timer Tick",
-       .flags          = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
-       .handler        = versatile_timer_interrupt,
-};
-
-static cycle_t versatile_get_cycles(struct clocksource *cs)
-{
-       return ~readl(TIMER3_VA_BASE + TIMER_VALUE);
-}
-
-static struct clocksource clocksource_versatile = {
-       .name           = "timer3",
-       .rating         = 200,
-       .read           = versatile_get_cycles,
-       .mask           = CLOCKSOURCE_MASK(32),
-       .shift          = 20,
-       .flags          = CLOCK_SOURCE_IS_CONTINUOUS,
-};
-
-static int __init versatile_clocksource_init(void)
-{
-       /* setup timer3 as free-running clocksource */
-       writel(0, TIMER3_VA_BASE + TIMER_CTRL);
-       writel(0xffffffff, TIMER3_VA_BASE + TIMER_LOAD);
-       writel(0xffffffff, TIMER3_VA_BASE + TIMER_VALUE);
-       writel(TIMER_CTRL_32BIT | TIMER_CTRL_ENABLE | TIMER_CTRL_PERIODIC,
-              TIMER3_VA_BASE + TIMER_CTRL);
-
-       clocksource_versatile.mult =
-               clocksource_khz2mult(1000, clocksource_versatile.shift);
-       clocksource_register(&clocksource_versatile);
-
-       return 0;
-}
 
 /*
  * Set up timer interrupt, and return the current time in seconds.
@@ -1017,22 +889,8 @@ static void __init versatile_timer_init(void)
        writel(0, TIMER2_VA_BASE + TIMER_CTRL);
        writel(0, TIMER3_VA_BASE + TIMER_CTRL);
 
-       /* 
-        * Make irqs happen for the system timer
-        */
-       setup_irq(IRQ_TIMERINT0_1, &versatile_timer_irq);
-
-       versatile_clocksource_init();
-
-       timer0_clockevent.mult =
-               div_sc(1000000, NSEC_PER_SEC, timer0_clockevent.shift);
-       timer0_clockevent.max_delta_ns =
-               clockevent_delta2ns(0xffffffff, &timer0_clockevent);
-       timer0_clockevent.min_delta_ns =
-               clockevent_delta2ns(0xf, &timer0_clockevent);
-
-       timer0_clockevent.cpumask = cpumask_of(0);
-       clockevents_register_device(&timer0_clockevent);
+       sp804_clocksource_init(TIMER3_VA_BASE);
+       sp804_clockevents_init(TIMER0_VA_BASE, IRQ_TIMERINT0_1);
 }
 
 struct sys_timer versatile_timer = {