Blame view
arch/arm/mach-at91/at91rm9200_time.c
5.7 KB
73a59c1c4 [ARM] 3240/2: AT9... |
1 |
/* |
9d0412680 [ARM] 4124/1: Ren... |
2 |
* linux/arch/arm/mach-at91/at91rm9200_time.c |
73a59c1c4 [ARM] 3240/2: AT9... |
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
* * Copyright (C) 2003 SAN People * Copyright (C) 2003 ATMEL * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ |
5e802dfab [ARM] 4539/1: clo... |
21 |
#include <linux/kernel.h> |
73a59c1c4 [ARM] 3240/2: AT9... |
22 |
#include <linux/interrupt.h> |
07d265dd5 [ARM] 3683/2: AR... |
23 |
#include <linux/irq.h> |
5e802dfab [ARM] 4539/1: clo... |
24 |
#include <linux/clockchips.h> |
73a59c1c4 [ARM] 3240/2: AT9... |
25 |
|
73a59c1c4 [ARM] 3240/2: AT9... |
26 |
#include <asm/mach/time.h> |
a09e64fbc [ARM] Move includ... |
27 |
#include <mach/at91_st.h> |
55d8baee4 [ARM] 3954/1: AT9... |
28 |
|
963151f24 [ARM] 3579/1: AT9... |
29 |
static unsigned long last_crtr; |
5e802dfab [ARM] 4539/1: clo... |
30 31 |
static u32 irqmask; static struct clock_event_device clkevt; |
963151f24 [ARM] 3579/1: AT9... |
32 |
|
2f5893cf4 ARM: at91: define... |
33 |
#define RM9200_TIMER_LATCH ((AT91_SLOW_CLOCK + HZ/2) / HZ) |
73a59c1c4 [ARM] 3240/2: AT9... |
34 |
/* |
5e802dfab [ARM] 4539/1: clo... |
35 36 37 |
* The ST_CRTR is updated asynchronously to the master clock ... but * the updates as seen by the CPU don't seem to be strictly monotonic. * Waiting until we read the same value twice avoids glitching. |
73a59c1c4 [ARM] 3240/2: AT9... |
38 |
*/ |
5e802dfab [ARM] 4539/1: clo... |
39 40 |
static inline unsigned long read_CRTR(void) { |
73a59c1c4 [ARM] 3240/2: AT9... |
41 |
unsigned long x1, x2; |
5e802dfab [ARM] 4539/1: clo... |
42 |
x1 = at91_sys_read(AT91_ST_CRTR); |
73a59c1c4 [ARM] 3240/2: AT9... |
43 |
do { |
73a59c1c4 [ARM] 3240/2: AT9... |
44 |
x2 = at91_sys_read(AT91_ST_CRTR); |
5e802dfab [ARM] 4539/1: clo... |
45 46 47 48 |
if (x1 == x2) break; x1 = x2; } while (1); |
73a59c1c4 [ARM] 3240/2: AT9... |
49 50 51 52 |
return x1; } /* |
73a59c1c4 [ARM] 3240/2: AT9... |
53 54 |
* IRQ handler for the timer. */ |
0cd61b68c Initial blind fix... |
55 |
static irqreturn_t at91rm9200_timer_interrupt(int irq, void *dev_id) |
73a59c1c4 [ARM] 3240/2: AT9... |
56 |
{ |
5e802dfab [ARM] 4539/1: clo... |
57 |
u32 sr = at91_sys_read(AT91_ST_SR) & irqmask; |
73a59c1c4 [ARM] 3240/2: AT9... |
58 |
|
501d70383 arm/at91: Don't d... |
59 60 61 62 63 |
/* * irqs should be disabled here, but as the irq is shared they are only * guaranteed to be off if the timer irq is registered first. */ WARN_ON_ONCE(!irqs_disabled()); |
5e802dfab [ARM] 4539/1: clo... |
64 65 66 67 68 |
/* simulate "oneshot" timer with alarm */ if (sr & AT91_ST_ALMS) { clkevt.event_handler(&clkevt); return IRQ_HANDLED; } |
73a59c1c4 [ARM] 3240/2: AT9... |
69 |
|
5e802dfab [ARM] 4539/1: clo... |
70 71 72 |
/* periodic mode should handle delayed ticks */ if (sr & AT91_ST_PITS) { u32 crtr = read_CRTR(); |
73a59c1c4 [ARM] 3240/2: AT9... |
73 |
|
2f5893cf4 ARM: at91: define... |
74 75 |
while (((crtr - last_crtr) & AT91_ST_CRTV) >= RM9200_TIMER_LATCH) { last_crtr += RM9200_TIMER_LATCH; |
5e802dfab [ARM] 4539/1: clo... |
76 77 |
clkevt.event_handler(&clkevt); } |
73a59c1c4 [ARM] 3240/2: AT9... |
78 79 |
return IRQ_HANDLED; } |
5e802dfab [ARM] 4539/1: clo... |
80 81 82 |
/* this irq is shared ... */ return IRQ_NONE; |
73a59c1c4 [ARM] 3240/2: AT9... |
83 84 85 86 |
} static struct irqaction at91rm9200_timer_irq = { .name = "at91_tick", |
b30fabada Add IRQF_IRQPOLL ... |
87 |
.flags = IRQF_SHARED | IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, |
73a59c1c4 [ARM] 3240/2: AT9... |
88 89 |
.handler = at91rm9200_timer_interrupt }; |
8e19608e8 clocksource: pass... |
90 |
static cycle_t read_clk32k(struct clocksource *cs) |
2a6f9902c [ARM] 3580/1: AT9... |
91 |
{ |
5e802dfab [ARM] 4539/1: clo... |
92 93 |
return read_CRTR(); } |
2a6f9902c [ARM] 3580/1: AT9... |
94 |
|
5e802dfab [ARM] 4539/1: clo... |
95 96 97 98 99 |
static struct clocksource clk32k = { .name = "32k_counter", .rating = 150, .read = read_clk32k, .mask = CLOCKSOURCE_MASK(20), |
5e802dfab [ARM] 4539/1: clo... |
100 101 102 103 104 105 106 107 108 |
.flags = CLOCK_SOURCE_IS_CONTINUOUS, }; static void clkevt32k_mode(enum clock_event_mode mode, struct clock_event_device *dev) { /* Disable and flush pending timer interrupts */ at91_sys_write(AT91_ST_IDR, AT91_ST_PITS | AT91_ST_ALMS); (void) at91_sys_read(AT91_ST_SR); |
2a6f9902c [ARM] 3580/1: AT9... |
109 |
|
5e802dfab [ARM] 4539/1: clo... |
110 111 112 113 114 |
last_crtr = read_CRTR(); switch (mode) { case CLOCK_EVT_MODE_PERIODIC: /* PIT for periodic irqs; fixed rate of 1/HZ */ irqmask = AT91_ST_PITS; |
2f5893cf4 ARM: at91: define... |
115 |
at91_sys_write(AT91_ST_PIMR, RM9200_TIMER_LATCH); |
5e802dfab [ARM] 4539/1: clo... |
116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 |
break; case CLOCK_EVT_MODE_ONESHOT: /* ALM for oneshot irqs, set by next_event() * before 32 seconds have passed */ irqmask = AT91_ST_ALMS; at91_sys_write(AT91_ST_RTAR, last_crtr); break; case CLOCK_EVT_MODE_SHUTDOWN: case CLOCK_EVT_MODE_UNUSED: case CLOCK_EVT_MODE_RESUME: irqmask = 0; break; } at91_sys_write(AT91_ST_IER, irqmask); } |
2a6f9902c [ARM] 3580/1: AT9... |
132 |
|
5e802dfab [ARM] 4539/1: clo... |
133 134 135 |
static int clkevt32k_next_event(unsigned long delta, struct clock_event_device *dev) { |
5e802dfab [ARM] 4539/1: clo... |
136 137 138 139 |
u32 alm; int status = 0; BUG_ON(delta < 2); |
5e802dfab [ARM] 4539/1: clo... |
140 141 142 143 144 145 146 147 148 149 150 151 152 |
/* The alarm IRQ uses absolute time (now+delta), not the relative * time (delta) in our calling convention. Like all clockevents * using such "match" hardware, we have a race to defend against. * * Our defense here is to have set up the clockevent device so the * delta is at least two. That way we never end up writing RTAR * with the value then held in CRTR ... which would mean the match * wouldn't trigger until 32 seconds later, after CRTR wraps. */ alm = read_CRTR(); /* Cancel any pending alarm; flush any pending IRQ */ at91_sys_write(AT91_ST_RTAR, alm); |
d100f2595 [ARM] 3955/1: AT9... |
153 |
(void) at91_sys_read(AT91_ST_SR); |
5e802dfab [ARM] 4539/1: clo... |
154 155 156 |
/* Schedule alarm by writing RTAR. */ alm += delta; at91_sys_write(AT91_ST_RTAR, alm); |
5e802dfab [ARM] 4539/1: clo... |
157 |
return status; |
2a6f9902c [ARM] 3580/1: AT9... |
158 |
} |
5e802dfab [ARM] 4539/1: clo... |
159 160 161 162 163 |
static struct clock_event_device clkevt = { .name = "at91_tick", .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, .shift = 32, .rating = 150, |
5e802dfab [ARM] 4539/1: clo... |
164 165 166 |
.set_next_event = clkevt32k_next_event, .set_mode = clkevt32k_mode, }; |
73a59c1c4 [ARM] 3240/2: AT9... |
167 |
/* |
5e802dfab [ARM] 4539/1: clo... |
168 |
* ST (system timer) module supports both clockevents and clocksource. |
73a59c1c4 [ARM] 3240/2: AT9... |
169 170 171 |
*/ void __init at91rm9200_timer_init(void) { |
5e802dfab [ARM] 4539/1: clo... |
172 173 174 175 |
/* Disable all timer interrupts, and clear any pending ones */ at91_sys_write(AT91_ST_IDR, AT91_ST_PITS | AT91_ST_WDOVF | AT91_ST_RTTINC | AT91_ST_ALMS); (void) at91_sys_read(AT91_ST_SR); |
73a59c1c4 [ARM] 3240/2: AT9... |
176 |
|
2a6f9902c [ARM] 3580/1: AT9... |
177 |
/* Make IRQs happen for the system timer */ |
73a59c1c4 [ARM] 3240/2: AT9... |
178 |
setup_irq(AT91_ID_SYS, &at91rm9200_timer_irq); |
5e802dfab [ARM] 4539/1: clo... |
179 180 181 182 183 |
/* The 32KiHz "Slow Clock" (tick every 30517.58 nanoseconds) is used * directly for the clocksource and all clockevents, after adjusting * its prescaler from the 1 Hz default. */ at91_sys_write(AT91_ST_RTMR, 1); |
73a59c1c4 [ARM] 3240/2: AT9... |
184 |
|
5e802dfab [ARM] 4539/1: clo... |
185 186 187 188 |
/* Setup timer clockevent, with minimum of two ticks (important!!) */ clkevt.mult = div_sc(AT91_SLOW_CLOCK, NSEC_PER_SEC, clkevt.shift); clkevt.max_delta_ns = clockevent_delta2ns(AT91_ST_ALMV, &clkevt); clkevt.min_delta_ns = clockevent_delta2ns(2, &clkevt) + 1; |
320ab2b0b cpumask: convert ... |
189 |
clkevt.cpumask = cpumask_of(0); |
5e802dfab [ARM] 4539/1: clo... |
190 |
clockevents_register_device(&clkevt); |
2a6f9902c [ARM] 3580/1: AT9... |
191 |
|
5e802dfab [ARM] 4539/1: clo... |
192 |
/* register clocksource */ |
132b16325 ARM: AT91: update... |
193 |
clocksource_register_hz(&clk32k, AT91_SLOW_CLOCK); |
73a59c1c4 [ARM] 3240/2: AT9... |
194 195 196 197 |
} struct sys_timer at91rm9200_timer = { .init = at91rm9200_timer_init, |
73a59c1c4 [ARM] 3240/2: AT9... |
198 |
}; |
2a6f9902c [ARM] 3580/1: AT9... |
199 |