Merge branches 'at91', 'ep93xx', 'kexec', 'iop', 'lmb', 'nomadik', 'nuc', 'pl', ...
[platform/adaptation/renesas_rcar/renesas_kernel.git] / arch / arm / mach-versatile / core.c
index 3b1a4ee..e38acb0 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/amba/pl022.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 +59,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 +228,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)
 
@@ -377,36 +355,58 @@ static struct mmci_platform_data mmc0_plat_data = {
        .gpio_cd        = -1,
 };
 
+static struct resource char_lcd_resources[] = {
+       {
+               .start = VERSATILE_CHAR_LCD_BASE,
+               .end   = (VERSATILE_CHAR_LCD_BASE + SZ_4K - 1),
+               .flags = IORESOURCE_MEM,
+       },
+};
+
+static struct platform_device char_lcd_device = {
+       .name           =       "arm-charlcd",
+       .id             =       -1,
+       .num_resources  =       ARRAY_SIZE(char_lcd_resources),
+       .resource       =       char_lcd_resources,
+};
+
 /*
  * 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,
 };
 
 /*
@@ -416,8 +416,13 @@ static struct clk ref24_clk = {
        .rate   = 24000000,
 };
 
+static struct clk dummy_apb_pclk;
+
 static struct clk_lookup lookups[] = {
-       {       /* UART0 */
+       {       /* AMBA bus clock */
+               .con_id         = "apb_pclk",
+               .clk            = &dummy_apb_pclk,
+       }, {    /* UART0 */
                .dev_id         = "dev:f1",
                .clk            = &ref24_clk,
        }, {    /* UART1 */
@@ -441,6 +446,9 @@ static struct clk_lookup lookups[] = {
        }, {    /* MMC1 */
                .dev_id         = "fpga:0b",
                .clk            = &ref24_clk,
+       }, {    /* SSP */
+               .dev_id         = "dev:f4",
+               .clk            = &ref24_clk,
        }, {    /* CLCD */
                .dev_id         = "dev:20",
                .clk            = &osc4_clk,
@@ -719,6 +727,12 @@ static struct pl061_platform_data gpio1_plat_data = {
        .irq_base       = IRQ_GPIO1_START,
 };
 
+static struct pl022_ssp_controller ssp0_plat_data = {
+       .bus_id = 0,
+       .enable_dma = 0,
+       .num_chipselect = 1,
+};
+
 #define AACI_IRQ       { IRQ_AACI, NO_IRQ }
 #define AACI_DMA       { 0x80, 0x81 }
 #define MMCI0_IRQ      { IRQ_MMCI0A,IRQ_SIC_MMCI0B }
@@ -788,7 +802,7 @@ AMBA_DEVICE(sci0,  "dev:f0",  SCI,      NULL);
 AMBA_DEVICE(uart0, "dev:f1",  UART0,    NULL);
 AMBA_DEVICE(uart1, "dev:f2",  UART1,    NULL);
 AMBA_DEVICE(uart2, "dev:f3",  UART2,    NULL);
-AMBA_DEVICE(ssp0,  "dev:f4",  SSP,      NULL);
+AMBA_DEVICE(ssp0,  "dev:f4",  SSP,      &ssp0_plat_data);
 
 static struct amba_device *amba_devs[] __initdata = {
        &dmac_device,
@@ -852,11 +866,14 @@ 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);
        platform_device_register(&versatile_i2c_device);
        platform_device_register(&smc91x_device);
+       platform_device_register(&char_lcd_device);
 
        for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
                struct amba_device *d = amba_devs[i];
@@ -875,120 +892,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 +920,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 = {