Merge branch 'devel' of master.kernel.org:/home/rmk/linux-2.6-arm
[pandora-kernel.git] / arch / arm / mach-msm / timer.c
index ae85aa9..56f920c 100644 (file)
 
 #include <asm/mach/time.h>
 #include <mach/msm_iomap.h>
-
-#ifndef MSM_DGT_BASE
-#define MSM_DGT_BASE (MSM_GPT_BASE + 0x10)
-#endif
+#include <mach/cpu.h>
 
 #define TIMER_MATCH_VAL         0x0000
 #define TIMER_COUNT_VAL         0x0004
@@ -52,18 +49,14 @@ enum timer_location {
        GLOBAL_TIMER = 1,
 };
 
-#ifdef MSM_TMR0_BASE
-#define MSM_TMR_GLOBAL         (MSM_TMR0_BASE - MSM_TMR_BASE)
-#else
-#define MSM_TMR_GLOBAL         0
-#endif
-
 #define MSM_GLOBAL_TIMER MSM_CLOCK_DGT
 
+/* TODO: Remove these ifdefs */
 #if defined(CONFIG_ARCH_QSD8X50)
 #define DGT_HZ (19200000 / 4) /* 19.2 MHz / 4 by default */
 #define MSM_DGT_SHIFT (0)
-#elif defined(CONFIG_ARCH_MSM7X30) || defined(CONFIG_ARCH_MSM8X60)
+#elif defined(CONFIG_ARCH_MSM7X30) || defined(CONFIG_ARCH_MSM8X60) || \
+                                     defined(CONFIG_ARCH_MSM8960)
 #define DGT_HZ (24576000 / 4) /* 24.576 MHz (LPXO) / 4 by default */
 #define MSM_DGT_SHIFT (0)
 #else
@@ -177,11 +170,7 @@ static struct msm_clock msm_clocks[] = {
                        .dev_id  = &msm_clocks[0].clockevent,
                        .irq     = INT_GP_TIMER_EXP
                },
-               .regbase = MSM_GPT_BASE,
                .freq = GPT_HZ,
-               .local_counter = MSM_GPT_BASE + TIMER_COUNT_VAL,
-               .global_counter = MSM_GPT_BASE + TIMER_COUNT_VAL +
-                       MSM_TMR_GLOBAL,
        },
        [MSM_CLOCK_DGT] = {
                .clockevent = {
@@ -206,12 +195,8 @@ static struct msm_clock msm_clocks[] = {
                        .dev_id  = &msm_clocks[1].clockevent,
                        .irq     = INT_DEBUG_TIMER_EXP
                },
-               .regbase = MSM_DGT_BASE,
                .freq = DGT_HZ >> MSM_DGT_SHIFT,
                .shift = MSM_DGT_SHIFT,
-               .local_counter = MSM_DGT_BASE + TIMER_COUNT_VAL,
-               .global_counter = MSM_DGT_BASE + TIMER_COUNT_VAL +
-                       MSM_TMR_GLOBAL,
        }
 };
 
@@ -219,6 +204,25 @@ static void __init msm_timer_init(void)
 {
        int i;
        int res;
+       int global_offset = 0;
+
+       if (cpu_is_msm7x01()) {
+               msm_clocks[MSM_CLOCK_GPT].regbase = MSM_CSR_BASE;
+               msm_clocks[MSM_CLOCK_DGT].regbase = MSM_CSR_BASE + 0x10;
+       } else if (cpu_is_msm7x30()) {
+               msm_clocks[MSM_CLOCK_GPT].regbase = MSM_CSR_BASE + 0x04;
+               msm_clocks[MSM_CLOCK_DGT].regbase = MSM_CSR_BASE + 0x24;
+       } else if (cpu_is_qsd8x50()) {
+               msm_clocks[MSM_CLOCK_GPT].regbase = MSM_CSR_BASE;
+               msm_clocks[MSM_CLOCK_DGT].regbase = MSM_CSR_BASE + 0x10;
+       } else if (cpu_is_msm8x60() || cpu_is_msm8960()) {
+               msm_clocks[MSM_CLOCK_GPT].regbase = MSM_TMR_BASE + 0x04;
+               msm_clocks[MSM_CLOCK_DGT].regbase = MSM_TMR_BASE + 0x24;
+
+               /* Use CPU0's timer as the global timer. */
+               global_offset = MSM_TMR0_BASE - MSM_TMR_BASE;
+       } else
+               BUG();
 
 #ifdef CONFIG_ARCH_MSM_SCORPIONMP
        writel(DGT_CLK_CTL_DIV_4, MSM_TMR_BASE + DGT_CLK_CTL);
@@ -228,6 +232,10 @@ static void __init msm_timer_init(void)
                struct msm_clock *clock = &msm_clocks[i];
                struct clock_event_device *ce = &clock->clockevent;
                struct clocksource *cs = &clock->clocksource;
+
+               clock->local_counter = clock->regbase + TIMER_COUNT_VAL;
+               clock->global_counter = clock->local_counter + global_offset;
+
                writel(0, clock->regbase + TIMER_ENABLE);
                writel(0, clock->regbase + TIMER_CLEAR);
                writel(~0, clock->regbase + TIMER_MATCH_VAL);