aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-msm/timer.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-msm/timer.c')
-rw-r--r--arch/arm/mach-msm/timer.c46
1 files changed, 27 insertions, 19 deletions
diff --git a/arch/arm/mach-msm/timer.c b/arch/arm/mach-msm/timer.c
index c105d28b53e3..e7f8e5a4d48f 100644
--- a/arch/arm/mach-msm/timer.c
+++ b/arch/arm/mach-msm/timer.c
@@ -24,10 +24,7 @@
24 24
25#include <asm/mach/time.h> 25#include <asm/mach/time.h>
26#include <mach/msm_iomap.h> 26#include <mach/msm_iomap.h>
27 27#include <mach/cpu.h>
28#ifndef MSM_DGT_BASE
29#define MSM_DGT_BASE (MSM_GPT_BASE + 0x10)
30#endif
31 28
32#define TIMER_MATCH_VAL 0x0000 29#define TIMER_MATCH_VAL 0x0000
33#define TIMER_COUNT_VAL 0x0004 30#define TIMER_COUNT_VAL 0x0004
@@ -52,18 +49,14 @@ enum timer_location {
52 GLOBAL_TIMER = 1, 49 GLOBAL_TIMER = 1,
53}; 50};
54 51
55#ifdef MSM_TMR0_BASE
56#define MSM_TMR_GLOBAL (MSM_TMR0_BASE - MSM_TMR_BASE)
57#else
58#define MSM_TMR_GLOBAL 0
59#endif
60
61#define MSM_GLOBAL_TIMER MSM_CLOCK_DGT 52#define MSM_GLOBAL_TIMER MSM_CLOCK_DGT
62 53
54/* TODO: Remove these ifdefs */
63#if defined(CONFIG_ARCH_QSD8X50) 55#if defined(CONFIG_ARCH_QSD8X50)
64#define DGT_HZ (19200000 / 4) /* 19.2 MHz / 4 by default */ 56#define DGT_HZ (19200000 / 4) /* 19.2 MHz / 4 by default */
65#define MSM_DGT_SHIFT (0) 57#define MSM_DGT_SHIFT (0)
66#elif defined(CONFIG_ARCH_MSM7X30) || defined(CONFIG_ARCH_MSM8X60) 58#elif defined(CONFIG_ARCH_MSM7X30) || defined(CONFIG_ARCH_MSM8X60) || \
59 defined(CONFIG_ARCH_MSM8960)
67#define DGT_HZ (24576000 / 4) /* 24.576 MHz (LPXO) / 4 by default */ 60#define DGT_HZ (24576000 / 4) /* 24.576 MHz (LPXO) / 4 by default */
68#define MSM_DGT_SHIFT (0) 61#define MSM_DGT_SHIFT (0)
69#else 62#else
@@ -177,11 +170,7 @@ static struct msm_clock msm_clocks[] = {
177 .dev_id = &msm_clocks[0].clockevent, 170 .dev_id = &msm_clocks[0].clockevent,
178 .irq = INT_GP_TIMER_EXP 171 .irq = INT_GP_TIMER_EXP
179 }, 172 },
180 .regbase = MSM_GPT_BASE,
181 .freq = GPT_HZ, 173 .freq = GPT_HZ,
182 .local_counter = MSM_GPT_BASE + TIMER_COUNT_VAL,
183 .global_counter = MSM_GPT_BASE + TIMER_COUNT_VAL +
184 MSM_TMR_GLOBAL,
185 }, 174 },
186 [MSM_CLOCK_DGT] = { 175 [MSM_CLOCK_DGT] = {
187 .clockevent = { 176 .clockevent = {
@@ -206,12 +195,8 @@ static struct msm_clock msm_clocks[] = {
206 .dev_id = &msm_clocks[1].clockevent, 195 .dev_id = &msm_clocks[1].clockevent,
207 .irq = INT_DEBUG_TIMER_EXP 196 .irq = INT_DEBUG_TIMER_EXP
208 }, 197 },
209 .regbase = MSM_DGT_BASE,
210 .freq = DGT_HZ >> MSM_DGT_SHIFT, 198 .freq = DGT_HZ >> MSM_DGT_SHIFT,
211 .shift = MSM_DGT_SHIFT, 199 .shift = MSM_DGT_SHIFT,
212 .local_counter = MSM_DGT_BASE + TIMER_COUNT_VAL,
213 .global_counter = MSM_DGT_BASE + TIMER_COUNT_VAL +
214 MSM_TMR_GLOBAL,
215 } 200 }
216}; 201};
217 202
@@ -219,6 +204,25 @@ static void __init msm_timer_init(void)
219{ 204{
220 int i; 205 int i;
221 int res; 206 int res;
207 int global_offset = 0;
208
209 if (cpu_is_msm7x01()) {
210 msm_clocks[MSM_CLOCK_GPT].regbase = MSM_CSR_BASE;
211 msm_clocks[MSM_CLOCK_DGT].regbase = MSM_CSR_BASE + 0x10;
212 } else if (cpu_is_msm7x30()) {
213 msm_clocks[MSM_CLOCK_GPT].regbase = MSM_CSR_BASE + 0x04;
214 msm_clocks[MSM_CLOCK_DGT].regbase = MSM_CSR_BASE + 0x24;
215 } else if (cpu_is_qsd8x50()) {
216 msm_clocks[MSM_CLOCK_GPT].regbase = MSM_CSR_BASE;
217 msm_clocks[MSM_CLOCK_DGT].regbase = MSM_CSR_BASE + 0x10;
218 } else if (cpu_is_msm8x60() || cpu_is_msm8960()) {
219 msm_clocks[MSM_CLOCK_GPT].regbase = MSM_TMR_BASE + 0x04;
220 msm_clocks[MSM_CLOCK_DGT].regbase = MSM_TMR_BASE + 0x24;
221
222 /* Use CPU0's timer as the global timer. */
223 global_offset = MSM_TMR0_BASE - MSM_TMR_BASE;
224 } else
225 BUG();
222 226
223#ifdef CONFIG_ARCH_MSM_SCORPIONMP 227#ifdef CONFIG_ARCH_MSM_SCORPIONMP
224 writel(DGT_CLK_CTL_DIV_4, MSM_TMR_BASE + DGT_CLK_CTL); 228 writel(DGT_CLK_CTL_DIV_4, MSM_TMR_BASE + DGT_CLK_CTL);
@@ -228,6 +232,10 @@ static void __init msm_timer_init(void)
228 struct msm_clock *clock = &msm_clocks[i]; 232 struct msm_clock *clock = &msm_clocks[i];
229 struct clock_event_device *ce = &clock->clockevent; 233 struct clock_event_device *ce = &clock->clockevent;
230 struct clocksource *cs = &clock->clocksource; 234 struct clocksource *cs = &clock->clocksource;
235
236 clock->local_counter = clock->regbase + TIMER_COUNT_VAL;
237 clock->global_counter = clock->local_counter + global_offset;
238
231 writel(0, clock->regbase + TIMER_ENABLE); 239 writel(0, clock->regbase + TIMER_ENABLE);
232 writel(0, clock->regbase + TIMER_CLEAR); 240 writel(0, clock->regbase + TIMER_CLEAR);
233 writel(~0, clock->regbase + TIMER_MATCH_VAL); 241 writel(~0, clock->regbase + TIMER_MATCH_VAL);