aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/plat-nomadik
diff options
context:
space:
mode:
authorLinus Walleij <linus.walleij@stericsson.com>2010-06-01 03:26:49 -0400
committerRussell King <rmk+kernel@arm.linux.org.uk>2010-06-16 17:29:31 -0400
commit2917947a673763be5f94313a59e5f28ee01b3d9d (patch)
tree7cf356130bf1cf94c9ca26494ae5fd92a14073b3 /arch/arm/plat-nomadik
parentf6aa01c2b8950a29503e93fc8b91f0d64f440c34 (diff)
ARM: 6153/1: nomadik MTU to use dynamic shift and mult assignment
This removes the hard-coded shift values for the MTU timer, since the different platforms using this has very different running frequencies doing this dynamically is a better idea. Also take this opportunity to make a more through shutdown of the MTU clockevent when requested. Acked-by: Alessandro Rubini <rubini@unipv.it> Signed-off-by: Linus Walleij <linus.walleij@stericsson.com> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm/plat-nomadik')
-rw-r--r--arch/arm/plat-nomadik/include/plat/mtu.h6
-rw-r--r--arch/arm/plat-nomadik/timer.c14
2 files changed, 16 insertions, 4 deletions
diff --git a/arch/arm/plat-nomadik/include/plat/mtu.h b/arch/arm/plat-nomadik/include/plat/mtu.h
index 42c907258b14..65704a3d4241 100644
--- a/arch/arm/plat-nomadik/include/plat/mtu.h
+++ b/arch/arm/plat-nomadik/include/plat/mtu.h
@@ -1,6 +1,12 @@
1#ifndef __PLAT_MTU_H 1#ifndef __PLAT_MTU_H
2#define __PLAT_MTU_H 2#define __PLAT_MTU_H
3 3
4/*
5 * Guaranteed runtime conversion range in seconds for
6 * the clocksource and clockevent.
7 */
8#define MTU_MIN_RANGE 4
9
4/* should be set by the platform code */ 10/* should be set by the platform code */
5extern void __iomem *mtu_base; 11extern void __iomem *mtu_base;
6 12
diff --git a/arch/arm/plat-nomadik/timer.c b/arch/arm/plat-nomadik/timer.c
index 08aaa4a7f65f..ea3ca86c5283 100644
--- a/arch/arm/plat-nomadik/timer.c
+++ b/arch/arm/plat-nomadik/timer.c
@@ -42,7 +42,6 @@ static struct clocksource nmdk_clksrc = {
42 .rating = 200, 42 .rating = 200,
43 .read = nmdk_read_timer_dummy, 43 .read = nmdk_read_timer_dummy,
44 .mask = CLOCKSOURCE_MASK(32), 44 .mask = CLOCKSOURCE_MASK(32),
45 .shift = 20,
46 .flags = CLOCK_SOURCE_IS_CONTINUOUS, 45 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
47}; 46};
48 47
@@ -82,6 +81,12 @@ static void nmdk_clkevt_mode(enum clock_event_mode mode,
82 case CLOCK_EVT_MODE_UNUSED: 81 case CLOCK_EVT_MODE_UNUSED:
83 /* disable irq */ 82 /* disable irq */
84 writel(0, mtu_base + MTU_IMSC); 83 writel(0, mtu_base + MTU_IMSC);
84 /* disable timer */
85 cr = readl(mtu_base + MTU_CR(1));
86 cr &= ~MTU_CRn_ENA;
87 writel(cr, mtu_base + MTU_CR(1));
88 /* load some high default value */
89 writel(0xffffffff, mtu_base + MTU_LR(1));
85 break; 90 break;
86 case CLOCK_EVT_MODE_RESUME: 91 case CLOCK_EVT_MODE_RESUME:
87 break; 92 break;
@@ -98,7 +103,6 @@ static int nmdk_clkevt_next(unsigned long evt, struct clock_event_device *ev)
98static struct clock_event_device nmdk_clkevt = { 103static struct clock_event_device nmdk_clkevt = {
99 .name = "mtu_1", 104 .name = "mtu_1",
100 .features = CLOCK_EVT_FEAT_ONESHOT, 105 .features = CLOCK_EVT_FEAT_ONESHOT,
101 .shift = 32,
102 .rating = 200, 106 .rating = 200,
103 .set_mode = nmdk_clkevt_mode, 107 .set_mode = nmdk_clkevt_mode,
104 .set_next_event = nmdk_clkevt_next, 108 .set_next_event = nmdk_clkevt_next,
@@ -151,6 +155,7 @@ void __init nmdk_timer_init(void)
151 } else { 155 } else {
152 cr |= MTU_CRn_PRESCALE_1; 156 cr |= MTU_CRn_PRESCALE_1;
153 } 157 }
158 clocksource_calc_mult_shift(&nmdk_clksrc, rate, MTU_MIN_RANGE);
154 159
155 /* Timer 0 is the free running clocksource */ 160 /* Timer 0 is the free running clocksource */
156 writel(cr, mtu_base + MTU_CR(0)); 161 writel(cr, mtu_base + MTU_CR(0));
@@ -158,7 +163,6 @@ void __init nmdk_timer_init(void)
158 writel(0, mtu_base + MTU_BGLR(0)); 163 writel(0, mtu_base + MTU_BGLR(0));
159 writel(cr | MTU_CRn_ENA, mtu_base + MTU_CR(0)); 164 writel(cr | MTU_CRn_ENA, mtu_base + MTU_CR(0));
160 165
161 nmdk_clksrc.mult = clocksource_hz2mult(rate, nmdk_clksrc.shift);
162 /* Now the scheduling clock is ready */ 166 /* Now the scheduling clock is ready */
163 nmdk_clksrc.read = nmdk_read_timer; 167 nmdk_clksrc.read = nmdk_read_timer;
164 168
@@ -175,8 +179,10 @@ void __init nmdk_timer_init(void)
175 } else { 179 } else {
176 cr |= MTU_CRn_PRESCALE_1; 180 cr |= MTU_CRn_PRESCALE_1;
177 } 181 }
182 clockevents_calc_mult_shift(&nmdk_clkevt, rate, MTU_MIN_RANGE);
183
178 writel(cr | MTU_CRn_ONESHOT, mtu_base + MTU_CR(1)); /* off, currently */ 184 writel(cr | MTU_CRn_ONESHOT, mtu_base + MTU_CR(1)); /* off, currently */
179 nmdk_clkevt.mult = div_sc(rate, NSEC_PER_SEC, nmdk_clkevt.shift); 185
180 nmdk_clkevt.max_delta_ns = 186 nmdk_clkevt.max_delta_ns =
181 clockevent_delta2ns(0xffffffff, &nmdk_clkevt); 187 clockevent_delta2ns(0xffffffff, &nmdk_clkevt);
182 nmdk_clkevt.min_delta_ns = 188 nmdk_clkevt.min_delta_ns =