aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-msm/timer.c
diff options
context:
space:
mode:
authorDavid Brown <davidb@codeaurora.org>2011-01-07 13:20:49 -0500
committerDavid Brown <davidb@codeaurora.org>2011-01-21 18:27:50 -0500
commit8c27e6f305242ffab0c88eed5dea8394b8ce86d0 (patch)
tree1fdcfc10f74a18883848b7273edd9f7e01cbcefe /arch/arm/mach-msm/timer.c
parent87fa28e972c223f69c1315a1b2ddb2a11d33ad0e (diff)
msm: Generalize timer register mappings
Allow the timer register to be determined dynamically instead of at compile time. Use common virtual addresses for the registers across all MSM chips, and select the register mappings based on the detected CPU. Signed-off-by: David Brown <davidb@codeaurora.org>
Diffstat (limited to 'arch/arm/mach-msm/timer.c')
-rw-r--r--arch/arm/mach-msm/timer.c43
1 files changed, 25 insertions, 18 deletions
diff --git a/arch/arm/mach-msm/timer.c b/arch/arm/mach-msm/timer.c
index c105d28b53e3..5548b156cff9 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,14 +49,9 @@ 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)
@@ -177,11 +169,7 @@ static struct msm_clock msm_clocks[] = {
177 .dev_id = &msm_clocks[0].clockevent, 169 .dev_id = &msm_clocks[0].clockevent,
178 .irq = INT_GP_TIMER_EXP 170 .irq = INT_GP_TIMER_EXP
179 }, 171 },
180 .regbase = MSM_GPT_BASE,
181 .freq = GPT_HZ, 172 .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 }, 173 },
186 [MSM_CLOCK_DGT] = { 174 [MSM_CLOCK_DGT] = {
187 .clockevent = { 175 .clockevent = {
@@ -206,12 +194,8 @@ static struct msm_clock msm_clocks[] = {
206 .dev_id = &msm_clocks[1].clockevent, 194 .dev_id = &msm_clocks[1].clockevent,
207 .irq = INT_DEBUG_TIMER_EXP 195 .irq = INT_DEBUG_TIMER_EXP
208 }, 196 },
209 .regbase = MSM_DGT_BASE,
210 .freq = DGT_HZ >> MSM_DGT_SHIFT, 197 .freq = DGT_HZ >> MSM_DGT_SHIFT,
211 .shift = MSM_DGT_SHIFT, 198 .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 } 199 }
216}; 200};
217 201
@@ -219,6 +203,25 @@ static void __init msm_timer_init(void)
219{ 203{
220 int i; 204 int i;
221 int res; 205 int res;
206 int global_offset = 0;
207
208 if (cpu_is_msm7x01()) {
209 msm_clocks[MSM_CLOCK_GPT].regbase = MSM_CSR_BASE;
210 msm_clocks[MSM_CLOCK_DGT].regbase = MSM_CSR_BASE + 0x10;
211 } else if (cpu_is_msm7x30()) {
212 msm_clocks[MSM_CLOCK_GPT].regbase = MSM_CSR_BASE + 0x04;
213 msm_clocks[MSM_CLOCK_DGT].regbase = MSM_CSR_BASE + 0x24;
214 } else if (cpu_is_qsd8x50()) {
215 msm_clocks[MSM_CLOCK_GPT].regbase = MSM_CSR_BASE;
216 msm_clocks[MSM_CLOCK_DGT].regbase = MSM_CSR_BASE + 0x10;
217 } else if (cpu_is_msm8x60()) {
218 msm_clocks[MSM_CLOCK_GPT].regbase = MSM_TMR_BASE + 0x04;
219 msm_clocks[MSM_CLOCK_DGT].regbase = MSM_TMR_BASE + 0x24;
220
221 /* Use CPU0's timer as the global timer. */
222 global_offset = MSM_TMR0_BASE - MSM_TMR_BASE;
223 } else
224 BUG();
222 225
223#ifdef CONFIG_ARCH_MSM_SCORPIONMP 226#ifdef CONFIG_ARCH_MSM_SCORPIONMP
224 writel(DGT_CLK_CTL_DIV_4, MSM_TMR_BASE + DGT_CLK_CTL); 227 writel(DGT_CLK_CTL_DIV_4, MSM_TMR_BASE + DGT_CLK_CTL);
@@ -228,6 +231,10 @@ static void __init msm_timer_init(void)
228 struct msm_clock *clock = &msm_clocks[i]; 231 struct msm_clock *clock = &msm_clocks[i];
229 struct clock_event_device *ce = &clock->clockevent; 232 struct clock_event_device *ce = &clock->clockevent;
230 struct clocksource *cs = &clock->clocksource; 233 struct clocksource *cs = &clock->clocksource;
234
235 clock->local_counter = clock->regbase + TIMER_COUNT_VAL;
236 clock->global_counter = clock->local_counter + global_offset;
237
231 writel(0, clock->regbase + TIMER_ENABLE); 238 writel(0, clock->regbase + TIMER_ENABLE);
232 writel(0, clock->regbase + TIMER_CLEAR); 239 writel(0, clock->regbase + TIMER_CLEAR);
233 writel(~0, clock->regbase + TIMER_MATCH_VAL); 240 writel(~0, clock->regbase + TIMER_MATCH_VAL);