diff options
Diffstat (limited to 'arch/x86/kernel/apb_timer.c')
-rw-r--r-- | arch/x86/kernel/apb_timer.c | 409 |
1 files changed, 69 insertions, 340 deletions
diff --git a/arch/x86/kernel/apb_timer.c b/arch/x86/kernel/apb_timer.c index 2b6630d75e17..afdc3f756dea 100644 --- a/arch/x86/kernel/apb_timer.c +++ b/arch/x86/kernel/apb_timer.c | |||
@@ -27,15 +27,12 @@ | |||
27 | * timer, but by default APB timer has higher rating than local APIC timers. | 27 | * timer, but by default APB timer has higher rating than local APIC timers. |
28 | */ | 28 | */ |
29 | 29 | ||
30 | #include <linux/clocksource.h> | ||
31 | #include <linux/clockchips.h> | ||
32 | #include <linux/delay.h> | 30 | #include <linux/delay.h> |
31 | #include <linux/dw_apb_timer.h> | ||
33 | #include <linux/errno.h> | 32 | #include <linux/errno.h> |
34 | #include <linux/init.h> | 33 | #include <linux/init.h> |
35 | #include <linux/sysdev.h> | ||
36 | #include <linux/slab.h> | 34 | #include <linux/slab.h> |
37 | #include <linux/pm.h> | 35 | #include <linux/pm.h> |
38 | #include <linux/pci.h> | ||
39 | #include <linux/sfi.h> | 36 | #include <linux/sfi.h> |
40 | #include <linux/interrupt.h> | 37 | #include <linux/interrupt.h> |
41 | #include <linux/cpu.h> | 38 | #include <linux/cpu.h> |
@@ -46,75 +43,46 @@ | |||
46 | #include <asm/mrst.h> | 43 | #include <asm/mrst.h> |
47 | #include <asm/time.h> | 44 | #include <asm/time.h> |
48 | 45 | ||
49 | #define APBT_MASK CLOCKSOURCE_MASK(32) | ||
50 | #define APBT_SHIFT 22 | ||
51 | #define APBT_CLOCKEVENT_RATING 110 | 46 | #define APBT_CLOCKEVENT_RATING 110 |
52 | #define APBT_CLOCKSOURCE_RATING 250 | 47 | #define APBT_CLOCKSOURCE_RATING 250 |
53 | #define APBT_MIN_DELTA_USEC 200 | ||
54 | 48 | ||
55 | #define EVT_TO_APBT_DEV(evt) container_of(evt, struct apbt_dev, evt) | ||
56 | #define APBT_CLOCKEVENT0_NUM (0) | 49 | #define APBT_CLOCKEVENT0_NUM (0) |
57 | #define APBT_CLOCKEVENT1_NUM (1) | ||
58 | #define APBT_CLOCKSOURCE_NUM (2) | 50 | #define APBT_CLOCKSOURCE_NUM (2) |
59 | 51 | ||
60 | static unsigned long apbt_address; | 52 | static phys_addr_t apbt_address; |
61 | static int apb_timer_block_enabled; | 53 | static int apb_timer_block_enabled; |
62 | static void __iomem *apbt_virt_address; | 54 | static void __iomem *apbt_virt_address; |
63 | static int phy_cs_timer_id; | ||
64 | 55 | ||
65 | /* | 56 | /* |
66 | * Common DW APB timer info | 57 | * Common DW APB timer info |
67 | */ | 58 | */ |
68 | static uint64_t apbt_freq; | 59 | static unsigned long apbt_freq; |
69 | |||
70 | static void apbt_set_mode(enum clock_event_mode mode, | ||
71 | struct clock_event_device *evt); | ||
72 | static int apbt_next_event(unsigned long delta, | ||
73 | struct clock_event_device *evt); | ||
74 | static cycle_t apbt_read_clocksource(struct clocksource *cs); | ||
75 | static void apbt_restart_clocksource(struct clocksource *cs); | ||
76 | 60 | ||
77 | struct apbt_dev { | 61 | struct apbt_dev { |
78 | struct clock_event_device evt; | 62 | struct dw_apb_clock_event_device *timer; |
79 | unsigned int num; | 63 | unsigned int num; |
80 | int cpu; | 64 | int cpu; |
81 | unsigned int irq; | 65 | unsigned int irq; |
82 | unsigned int tick; | 66 | char name[10]; |
83 | unsigned int count; | ||
84 | unsigned int flags; | ||
85 | char name[10]; | ||
86 | }; | 67 | }; |
87 | 68 | ||
88 | static DEFINE_PER_CPU(struct apbt_dev, cpu_apbt_dev); | 69 | static struct dw_apb_clocksource *clocksource_apbt; |
89 | 70 | ||
90 | #ifdef CONFIG_SMP | 71 | static inline void __iomem *adev_virt_addr(struct apbt_dev *adev) |
91 | static unsigned int apbt_num_timers_used; | ||
92 | static struct apbt_dev *apbt_devs; | ||
93 | #endif | ||
94 | |||
95 | static inline unsigned long apbt_readl_reg(unsigned long a) | ||
96 | { | 72 | { |
97 | return readl(apbt_virt_address + a); | 73 | return apbt_virt_address + adev->num * APBTMRS_REG_SIZE; |
98 | } | 74 | } |
99 | 75 | ||
100 | static inline void apbt_writel_reg(unsigned long d, unsigned long a) | 76 | static DEFINE_PER_CPU(struct apbt_dev, cpu_apbt_dev); |
101 | { | ||
102 | writel(d, apbt_virt_address + a); | ||
103 | } | ||
104 | |||
105 | static inline unsigned long apbt_readl(int n, unsigned long a) | ||
106 | { | ||
107 | return readl(apbt_virt_address + a + n * APBTMRS_REG_SIZE); | ||
108 | } | ||
109 | 77 | ||
110 | static inline void apbt_writel(int n, unsigned long d, unsigned long a) | 78 | #ifdef CONFIG_SMP |
111 | { | 79 | static unsigned int apbt_num_timers_used; |
112 | writel(d, apbt_virt_address + a + n * APBTMRS_REG_SIZE); | 80 | #endif |
113 | } | ||
114 | 81 | ||
115 | static inline void apbt_set_mapping(void) | 82 | static inline void apbt_set_mapping(void) |
116 | { | 83 | { |
117 | struct sfi_timer_table_entry *mtmr; | 84 | struct sfi_timer_table_entry *mtmr; |
85 | int phy_cs_timer_id = 0; | ||
118 | 86 | ||
119 | if (apbt_virt_address) { | 87 | if (apbt_virt_address) { |
120 | pr_debug("APBT base already mapped\n"); | 88 | pr_debug("APBT base already mapped\n"); |
@@ -126,21 +94,18 @@ static inline void apbt_set_mapping(void) | |||
126 | APBT_CLOCKEVENT0_NUM); | 94 | APBT_CLOCKEVENT0_NUM); |
127 | return; | 95 | return; |
128 | } | 96 | } |
129 | apbt_address = (unsigned long)mtmr->phys_addr; | 97 | apbt_address = (phys_addr_t)mtmr->phys_addr; |
130 | if (!apbt_address) { | 98 | if (!apbt_address) { |
131 | printk(KERN_WARNING "No timer base from SFI, use default\n"); | 99 | printk(KERN_WARNING "No timer base from SFI, use default\n"); |
132 | apbt_address = APBT_DEFAULT_BASE; | 100 | apbt_address = APBT_DEFAULT_BASE; |
133 | } | 101 | } |
134 | apbt_virt_address = ioremap_nocache(apbt_address, APBT_MMAP_SIZE); | 102 | apbt_virt_address = ioremap_nocache(apbt_address, APBT_MMAP_SIZE); |
135 | if (apbt_virt_address) { | 103 | if (!apbt_virt_address) { |
136 | pr_debug("Mapped APBT physical addr %p at virtual addr %p\n",\ | 104 | pr_debug("Failed mapping APBT phy address at %lu\n",\ |
137 | (void *)apbt_address, (void *)apbt_virt_address); | 105 | (unsigned long)apbt_address); |
138 | } else { | ||
139 | pr_debug("Failed mapping APBT phy address at %p\n",\ | ||
140 | (void *)apbt_address); | ||
141 | goto panic_noapbt; | 106 | goto panic_noapbt; |
142 | } | 107 | } |
143 | apbt_freq = mtmr->freq_hz / USEC_PER_SEC; | 108 | apbt_freq = mtmr->freq_hz; |
144 | sfi_free_mtmr(mtmr); | 109 | sfi_free_mtmr(mtmr); |
145 | 110 | ||
146 | /* Now figure out the physical timer id for clocksource device */ | 111 | /* Now figure out the physical timer id for clocksource device */ |
@@ -149,9 +114,14 @@ static inline void apbt_set_mapping(void) | |||
149 | goto panic_noapbt; | 114 | goto panic_noapbt; |
150 | 115 | ||
151 | /* Now figure out the physical timer id */ | 116 | /* Now figure out the physical timer id */ |
152 | phy_cs_timer_id = (unsigned int)(mtmr->phys_addr & 0xff) | 117 | pr_debug("Use timer %d for clocksource\n", |
153 | / APBTMRS_REG_SIZE; | 118 | (int)(mtmr->phys_addr & 0xff) / APBTMRS_REG_SIZE); |
154 | pr_debug("Use timer %d for clocksource\n", phy_cs_timer_id); | 119 | phy_cs_timer_id = (unsigned int)(mtmr->phys_addr & 0xff) / |
120 | APBTMRS_REG_SIZE; | ||
121 | |||
122 | clocksource_apbt = dw_apb_clocksource_init(APBT_CLOCKSOURCE_RATING, | ||
123 | "apbt0", apbt_virt_address + phy_cs_timer_id * | ||
124 | APBTMRS_REG_SIZE, apbt_freq); | ||
155 | return; | 125 | return; |
156 | 126 | ||
157 | panic_noapbt: | 127 | panic_noapbt: |
@@ -173,82 +143,6 @@ static inline int is_apbt_capable(void) | |||
173 | return apbt_virt_address ? 1 : 0; | 143 | return apbt_virt_address ? 1 : 0; |
174 | } | 144 | } |
175 | 145 | ||
176 | static struct clocksource clocksource_apbt = { | ||
177 | .name = "apbt", | ||
178 | .rating = APBT_CLOCKSOURCE_RATING, | ||
179 | .read = apbt_read_clocksource, | ||
180 | .mask = APBT_MASK, | ||
181 | .flags = CLOCK_SOURCE_IS_CONTINUOUS, | ||
182 | .resume = apbt_restart_clocksource, | ||
183 | }; | ||
184 | |||
185 | /* boot APB clock event device */ | ||
186 | static struct clock_event_device apbt_clockevent = { | ||
187 | .name = "apbt0", | ||
188 | .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, | ||
189 | .set_mode = apbt_set_mode, | ||
190 | .set_next_event = apbt_next_event, | ||
191 | .shift = APBT_SHIFT, | ||
192 | .irq = 0, | ||
193 | .rating = APBT_CLOCKEVENT_RATING, | ||
194 | }; | ||
195 | |||
196 | /* | ||
197 | * start count down from 0xffff_ffff. this is done by toggling the enable bit | ||
198 | * then load initial load count to ~0. | ||
199 | */ | ||
200 | static void apbt_start_counter(int n) | ||
201 | { | ||
202 | unsigned long ctrl = apbt_readl(n, APBTMR_N_CONTROL); | ||
203 | |||
204 | ctrl &= ~APBTMR_CONTROL_ENABLE; | ||
205 | apbt_writel(n, ctrl, APBTMR_N_CONTROL); | ||
206 | apbt_writel(n, ~0, APBTMR_N_LOAD_COUNT); | ||
207 | /* enable, mask interrupt */ | ||
208 | ctrl &= ~APBTMR_CONTROL_MODE_PERIODIC; | ||
209 | ctrl |= (APBTMR_CONTROL_ENABLE | APBTMR_CONTROL_INT); | ||
210 | apbt_writel(n, ctrl, APBTMR_N_CONTROL); | ||
211 | /* read it once to get cached counter value initialized */ | ||
212 | apbt_read_clocksource(&clocksource_apbt); | ||
213 | } | ||
214 | |||
215 | static irqreturn_t apbt_interrupt_handler(int irq, void *data) | ||
216 | { | ||
217 | struct apbt_dev *dev = (struct apbt_dev *)data; | ||
218 | struct clock_event_device *aevt = &dev->evt; | ||
219 | |||
220 | if (!aevt->event_handler) { | ||
221 | printk(KERN_INFO "Spurious APBT timer interrupt on %d\n", | ||
222 | dev->num); | ||
223 | return IRQ_NONE; | ||
224 | } | ||
225 | aevt->event_handler(aevt); | ||
226 | return IRQ_HANDLED; | ||
227 | } | ||
228 | |||
229 | static void apbt_restart_clocksource(struct clocksource *cs) | ||
230 | { | ||
231 | apbt_start_counter(phy_cs_timer_id); | ||
232 | } | ||
233 | |||
234 | static void apbt_enable_int(int n) | ||
235 | { | ||
236 | unsigned long ctrl = apbt_readl(n, APBTMR_N_CONTROL); | ||
237 | /* clear pending intr */ | ||
238 | apbt_readl(n, APBTMR_N_EOI); | ||
239 | ctrl &= ~APBTMR_CONTROL_INT; | ||
240 | apbt_writel(n, ctrl, APBTMR_N_CONTROL); | ||
241 | } | ||
242 | |||
243 | static void apbt_disable_int(int n) | ||
244 | { | ||
245 | unsigned long ctrl = apbt_readl(n, APBTMR_N_CONTROL); | ||
246 | |||
247 | ctrl |= APBTMR_CONTROL_INT; | ||
248 | apbt_writel(n, ctrl, APBTMR_N_CONTROL); | ||
249 | } | ||
250 | |||
251 | |||
252 | static int __init apbt_clockevent_register(void) | 146 | static int __init apbt_clockevent_register(void) |
253 | { | 147 | { |
254 | struct sfi_timer_table_entry *mtmr; | 148 | struct sfi_timer_table_entry *mtmr; |
@@ -261,45 +155,21 @@ static int __init apbt_clockevent_register(void) | |||
261 | return -ENODEV; | 155 | return -ENODEV; |
262 | } | 156 | } |
263 | 157 | ||
264 | /* | ||
265 | * We need to calculate the scaled math multiplication factor for | ||
266 | * nanosecond to apbt tick conversion. | ||
267 | * mult = (nsec/cycle)*2^APBT_SHIFT | ||
268 | */ | ||
269 | apbt_clockevent.mult = div_sc((unsigned long) mtmr->freq_hz | ||
270 | , NSEC_PER_SEC, APBT_SHIFT); | ||
271 | |||
272 | /* Calculate the min / max delta */ | ||
273 | apbt_clockevent.max_delta_ns = clockevent_delta2ns(0x7FFFFFFF, | ||
274 | &apbt_clockevent); | ||
275 | apbt_clockevent.min_delta_ns = clockevent_delta2ns( | ||
276 | APBT_MIN_DELTA_USEC*apbt_freq, | ||
277 | &apbt_clockevent); | ||
278 | /* | ||
279 | * Start apbt with the boot cpu mask and make it | ||
280 | * global if not used for per cpu timer. | ||
281 | */ | ||
282 | apbt_clockevent.cpumask = cpumask_of(smp_processor_id()); | ||
283 | adev->num = smp_processor_id(); | 158 | adev->num = smp_processor_id(); |
284 | memcpy(&adev->evt, &apbt_clockevent, sizeof(struct clock_event_device)); | 159 | adev->timer = dw_apb_clockevent_init(smp_processor_id(), "apbt0", |
160 | mrst_timer_options == MRST_TIMER_LAPIC_APBT ? | ||
161 | APBT_CLOCKEVENT_RATING - 100 : APBT_CLOCKEVENT_RATING, | ||
162 | adev_virt_addr(adev), 0, apbt_freq); | ||
163 | /* Firmware does EOI handling for us. */ | ||
164 | adev->timer->eoi = NULL; | ||
285 | 165 | ||
286 | if (mrst_timer_options == MRST_TIMER_LAPIC_APBT) { | 166 | if (mrst_timer_options == MRST_TIMER_LAPIC_APBT) { |
287 | adev->evt.rating = APBT_CLOCKEVENT_RATING - 100; | 167 | global_clock_event = &adev->timer->ced; |
288 | global_clock_event = &adev->evt; | ||
289 | printk(KERN_DEBUG "%s clockevent registered as global\n", | 168 | printk(KERN_DEBUG "%s clockevent registered as global\n", |
290 | global_clock_event->name); | 169 | global_clock_event->name); |
291 | } | 170 | } |
292 | 171 | ||
293 | if (request_irq(apbt_clockevent.irq, apbt_interrupt_handler, | 172 | dw_apb_clockevent_register(adev->timer); |
294 | IRQF_TIMER | IRQF_DISABLED | IRQF_NOBALANCING, | ||
295 | apbt_clockevent.name, adev)) { | ||
296 | printk(KERN_ERR "Failed request IRQ for APBT%d\n", | ||
297 | apbt_clockevent.irq); | ||
298 | } | ||
299 | |||
300 | clockevents_register_device(&adev->evt); | ||
301 | /* Start APBT 0 interrupts */ | ||
302 | apbt_enable_int(APBT_CLOCKEVENT0_NUM); | ||
303 | 173 | ||
304 | sfi_free_mtmr(mtmr); | 174 | sfi_free_mtmr(mtmr); |
305 | return 0; | 175 | return 0; |
@@ -317,52 +187,34 @@ static void apbt_setup_irq(struct apbt_dev *adev) | |||
317 | irq_set_affinity(adev->irq, cpumask_of(adev->cpu)); | 187 | irq_set_affinity(adev->irq, cpumask_of(adev->cpu)); |
318 | /* APB timer irqs are set up as mp_irqs, timer is edge type */ | 188 | /* APB timer irqs are set up as mp_irqs, timer is edge type */ |
319 | __irq_set_handler(adev->irq, handle_edge_irq, 0, "edge"); | 189 | __irq_set_handler(adev->irq, handle_edge_irq, 0, "edge"); |
320 | |||
321 | if (system_state == SYSTEM_BOOTING) { | ||
322 | if (request_irq(adev->irq, apbt_interrupt_handler, | ||
323 | IRQF_TIMER | IRQF_DISABLED | | ||
324 | IRQF_NOBALANCING, | ||
325 | adev->name, adev)) { | ||
326 | printk(KERN_ERR "Failed request IRQ for APBT%d\n", | ||
327 | adev->num); | ||
328 | } | ||
329 | } else | ||
330 | enable_irq(adev->irq); | ||
331 | } | 190 | } |
332 | 191 | ||
333 | /* Should be called with per cpu */ | 192 | /* Should be called with per cpu */ |
334 | void apbt_setup_secondary_clock(void) | 193 | void apbt_setup_secondary_clock(void) |
335 | { | 194 | { |
336 | struct apbt_dev *adev; | 195 | struct apbt_dev *adev; |
337 | struct clock_event_device *aevt; | ||
338 | int cpu; | 196 | int cpu; |
339 | 197 | ||
340 | /* Don't register boot CPU clockevent */ | 198 | /* Don't register boot CPU clockevent */ |
341 | cpu = smp_processor_id(); | 199 | cpu = smp_processor_id(); |
342 | if (!cpu) | 200 | if (!cpu) |
343 | return; | 201 | return; |
344 | /* | ||
345 | * We need to calculate the scaled math multiplication factor for | ||
346 | * nanosecond to apbt tick conversion. | ||
347 | * mult = (nsec/cycle)*2^APBT_SHIFT | ||
348 | */ | ||
349 | printk(KERN_INFO "Init per CPU clockevent %d\n", cpu); | ||
350 | adev = &per_cpu(cpu_apbt_dev, cpu); | ||
351 | aevt = &adev->evt; | ||
352 | 202 | ||
353 | memcpy(aevt, &apbt_clockevent, sizeof(*aevt)); | 203 | adev = &__get_cpu_var(cpu_apbt_dev); |
354 | aevt->cpumask = cpumask_of(cpu); | 204 | if (!adev->timer) { |
355 | aevt->name = adev->name; | 205 | adev->timer = dw_apb_clockevent_init(cpu, adev->name, |
356 | aevt->mode = CLOCK_EVT_MODE_UNUSED; | 206 | APBT_CLOCKEVENT_RATING, adev_virt_addr(adev), |
207 | adev->irq, apbt_freq); | ||
208 | adev->timer->eoi = NULL; | ||
209 | } else { | ||
210 | dw_apb_clockevent_resume(adev->timer); | ||
211 | } | ||
357 | 212 | ||
358 | printk(KERN_INFO "Registering CPU %d clockevent device %s, mask %08x\n", | 213 | printk(KERN_INFO "Registering CPU %d clockevent device %s, cpu %08x\n", |
359 | cpu, aevt->name, *(u32 *)aevt->cpumask); | 214 | cpu, adev->name, adev->cpu); |
360 | 215 | ||
361 | apbt_setup_irq(adev); | 216 | apbt_setup_irq(adev); |
362 | 217 | dw_apb_clockevent_register(adev->timer); | |
363 | clockevents_register_device(aevt); | ||
364 | |||
365 | apbt_enable_int(cpu); | ||
366 | 218 | ||
367 | return; | 219 | return; |
368 | } | 220 | } |
@@ -385,13 +237,12 @@ static int apbt_cpuhp_notify(struct notifier_block *n, | |||
385 | 237 | ||
386 | switch (action & 0xf) { | 238 | switch (action & 0xf) { |
387 | case CPU_DEAD: | 239 | case CPU_DEAD: |
388 | disable_irq(adev->irq); | 240 | dw_apb_clockevent_pause(adev->timer); |
389 | apbt_disable_int(cpu); | ||
390 | if (system_state == SYSTEM_RUNNING) { | 241 | if (system_state == SYSTEM_RUNNING) { |
391 | pr_debug("skipping APBT CPU %lu offline\n", cpu); | 242 | pr_debug("skipping APBT CPU %lu offline\n", cpu); |
392 | } else if (adev) { | 243 | } else if (adev) { |
393 | pr_debug("APBT clockevent for cpu %lu offline\n", cpu); | 244 | pr_debug("APBT clockevent for cpu %lu offline\n", cpu); |
394 | free_irq(adev->irq, adev); | 245 | dw_apb_clockevent_stop(adev->timer); |
395 | } | 246 | } |
396 | break; | 247 | break; |
397 | default: | 248 | default: |
@@ -416,116 +267,16 @@ void apbt_setup_secondary_clock(void) {} | |||
416 | 267 | ||
417 | #endif /* CONFIG_SMP */ | 268 | #endif /* CONFIG_SMP */ |
418 | 269 | ||
419 | static void apbt_set_mode(enum clock_event_mode mode, | ||
420 | struct clock_event_device *evt) | ||
421 | { | ||
422 | unsigned long ctrl; | ||
423 | uint64_t delta; | ||
424 | int timer_num; | ||
425 | struct apbt_dev *adev = EVT_TO_APBT_DEV(evt); | ||
426 | |||
427 | BUG_ON(!apbt_virt_address); | ||
428 | |||
429 | timer_num = adev->num; | ||
430 | pr_debug("%s CPU %d timer %d mode=%d\n", | ||
431 | __func__, first_cpu(*evt->cpumask), timer_num, mode); | ||
432 | |||
433 | switch (mode) { | ||
434 | case CLOCK_EVT_MODE_PERIODIC: | ||
435 | delta = ((uint64_t)(NSEC_PER_SEC/HZ)) * apbt_clockevent.mult; | ||
436 | delta >>= apbt_clockevent.shift; | ||
437 | ctrl = apbt_readl(timer_num, APBTMR_N_CONTROL); | ||
438 | ctrl |= APBTMR_CONTROL_MODE_PERIODIC; | ||
439 | apbt_writel(timer_num, ctrl, APBTMR_N_CONTROL); | ||
440 | /* | ||
441 | * DW APB p. 46, have to disable timer before load counter, | ||
442 | * may cause sync problem. | ||
443 | */ | ||
444 | ctrl &= ~APBTMR_CONTROL_ENABLE; | ||
445 | apbt_writel(timer_num, ctrl, APBTMR_N_CONTROL); | ||
446 | udelay(1); | ||
447 | pr_debug("Setting clock period %d for HZ %d\n", (int)delta, HZ); | ||
448 | apbt_writel(timer_num, delta, APBTMR_N_LOAD_COUNT); | ||
449 | ctrl |= APBTMR_CONTROL_ENABLE; | ||
450 | apbt_writel(timer_num, ctrl, APBTMR_N_CONTROL); | ||
451 | break; | ||
452 | /* APB timer does not have one-shot mode, use free running mode */ | ||
453 | case CLOCK_EVT_MODE_ONESHOT: | ||
454 | ctrl = apbt_readl(timer_num, APBTMR_N_CONTROL); | ||
455 | /* | ||
456 | * set free running mode, this mode will let timer reload max | ||
457 | * timeout which will give time (3min on 25MHz clock) to rearm | ||
458 | * the next event, therefore emulate the one-shot mode. | ||
459 | */ | ||
460 | ctrl &= ~APBTMR_CONTROL_ENABLE; | ||
461 | ctrl &= ~APBTMR_CONTROL_MODE_PERIODIC; | ||
462 | |||
463 | apbt_writel(timer_num, ctrl, APBTMR_N_CONTROL); | ||
464 | /* write again to set free running mode */ | ||
465 | apbt_writel(timer_num, ctrl, APBTMR_N_CONTROL); | ||
466 | |||
467 | /* | ||
468 | * DW APB p. 46, load counter with all 1s before starting free | ||
469 | * running mode. | ||
470 | */ | ||
471 | apbt_writel(timer_num, ~0, APBTMR_N_LOAD_COUNT); | ||
472 | ctrl &= ~APBTMR_CONTROL_INT; | ||
473 | ctrl |= APBTMR_CONTROL_ENABLE; | ||
474 | apbt_writel(timer_num, ctrl, APBTMR_N_CONTROL); | ||
475 | break; | ||
476 | |||
477 | case CLOCK_EVT_MODE_UNUSED: | ||
478 | case CLOCK_EVT_MODE_SHUTDOWN: | ||
479 | apbt_disable_int(timer_num); | ||
480 | ctrl = apbt_readl(timer_num, APBTMR_N_CONTROL); | ||
481 | ctrl &= ~APBTMR_CONTROL_ENABLE; | ||
482 | apbt_writel(timer_num, ctrl, APBTMR_N_CONTROL); | ||
483 | break; | ||
484 | |||
485 | case CLOCK_EVT_MODE_RESUME: | ||
486 | apbt_enable_int(timer_num); | ||
487 | break; | ||
488 | } | ||
489 | } | ||
490 | |||
491 | static int apbt_next_event(unsigned long delta, | ||
492 | struct clock_event_device *evt) | ||
493 | { | ||
494 | unsigned long ctrl; | ||
495 | int timer_num; | ||
496 | |||
497 | struct apbt_dev *adev = EVT_TO_APBT_DEV(evt); | ||
498 | |||
499 | timer_num = adev->num; | ||
500 | /* Disable timer */ | ||
501 | ctrl = apbt_readl(timer_num, APBTMR_N_CONTROL); | ||
502 | ctrl &= ~APBTMR_CONTROL_ENABLE; | ||
503 | apbt_writel(timer_num, ctrl, APBTMR_N_CONTROL); | ||
504 | /* write new count */ | ||
505 | apbt_writel(timer_num, delta, APBTMR_N_LOAD_COUNT); | ||
506 | ctrl |= APBTMR_CONTROL_ENABLE; | ||
507 | apbt_writel(timer_num, ctrl, APBTMR_N_CONTROL); | ||
508 | return 0; | ||
509 | } | ||
510 | |||
511 | static cycle_t apbt_read_clocksource(struct clocksource *cs) | ||
512 | { | ||
513 | unsigned long current_count; | ||
514 | |||
515 | current_count = apbt_readl(phy_cs_timer_id, APBTMR_N_CURRENT_VALUE); | ||
516 | return (cycle_t)~current_count; | ||
517 | } | ||
518 | |||
519 | static int apbt_clocksource_register(void) | 270 | static int apbt_clocksource_register(void) |
520 | { | 271 | { |
521 | u64 start, now; | 272 | u64 start, now; |
522 | cycle_t t1; | 273 | cycle_t t1; |
523 | 274 | ||
524 | /* Start the counter, use timer 2 as source, timer 0/1 for event */ | 275 | /* Start the counter, use timer 2 as source, timer 0/1 for event */ |
525 | apbt_start_counter(phy_cs_timer_id); | 276 | dw_apb_clocksource_start(clocksource_apbt); |
526 | 277 | ||
527 | /* Verify whether apbt counter works */ | 278 | /* Verify whether apbt counter works */ |
528 | t1 = apbt_read_clocksource(&clocksource_apbt); | 279 | t1 = dw_apb_clocksource_read(clocksource_apbt); |
529 | rdtscll(start); | 280 | rdtscll(start); |
530 | 281 | ||
531 | /* | 282 | /* |
@@ -540,10 +291,10 @@ static int apbt_clocksource_register(void) | |||
540 | } while ((now - start) < 200000UL); | 291 | } while ((now - start) < 200000UL); |
541 | 292 | ||
542 | /* APBT is the only always on clocksource, it has to work! */ | 293 | /* APBT is the only always on clocksource, it has to work! */ |
543 | if (t1 == apbt_read_clocksource(&clocksource_apbt)) | 294 | if (t1 == dw_apb_clocksource_read(clocksource_apbt)) |
544 | panic("APBT counter not counting. APBT disabled\n"); | 295 | panic("APBT counter not counting. APBT disabled\n"); |
545 | 296 | ||
546 | clocksource_register_khz(&clocksource_apbt, (u32)apbt_freq*1000); | 297 | dw_apb_clocksource_register(clocksource_apbt); |
547 | 298 | ||
548 | return 0; | 299 | return 0; |
549 | } | 300 | } |
@@ -567,10 +318,7 @@ void __init apbt_time_init(void) | |||
567 | if (apb_timer_block_enabled) | 318 | if (apb_timer_block_enabled) |
568 | return; | 319 | return; |
569 | apbt_set_mapping(); | 320 | apbt_set_mapping(); |
570 | if (apbt_virt_address) { | 321 | if (!apbt_virt_address) |
571 | pr_debug("Found APBT version 0x%lx\n",\ | ||
572 | apbt_readl_reg(APBTMRS_COMP_VERSION)); | ||
573 | } else | ||
574 | goto out_noapbt; | 322 | goto out_noapbt; |
575 | /* | 323 | /* |
576 | * Read the frequency and check for a sane value, for ESL model | 324 | * Read the frequency and check for a sane value, for ESL model |
@@ -578,7 +326,7 @@ void __init apbt_time_init(void) | |||
578 | */ | 326 | */ |
579 | 327 | ||
580 | if (apbt_freq < APBT_MIN_FREQ || apbt_freq > APBT_MAX_FREQ) { | 328 | if (apbt_freq < APBT_MIN_FREQ || apbt_freq > APBT_MAX_FREQ) { |
581 | pr_debug("APBT has invalid freq 0x%llx\n", apbt_freq); | 329 | pr_debug("APBT has invalid freq 0x%lx\n", apbt_freq); |
582 | goto out_noapbt; | 330 | goto out_noapbt; |
583 | } | 331 | } |
584 | if (apbt_clocksource_register()) { | 332 | if (apbt_clocksource_register()) { |
@@ -604,30 +352,20 @@ void __init apbt_time_init(void) | |||
604 | } else { | 352 | } else { |
605 | percpu_timer = 0; | 353 | percpu_timer = 0; |
606 | apbt_num_timers_used = 1; | 354 | apbt_num_timers_used = 1; |
607 | adev = &per_cpu(cpu_apbt_dev, 0); | ||
608 | adev->flags &= ~APBT_DEV_USED; | ||
609 | } | 355 | } |
610 | pr_debug("%s: %d APB timers used\n", __func__, apbt_num_timers_used); | 356 | pr_debug("%s: %d APB timers used\n", __func__, apbt_num_timers_used); |
611 | 357 | ||
612 | /* here we set up per CPU timer data structure */ | 358 | /* here we set up per CPU timer data structure */ |
613 | apbt_devs = kzalloc(sizeof(struct apbt_dev) * apbt_num_timers_used, | ||
614 | GFP_KERNEL); | ||
615 | if (!apbt_devs) { | ||
616 | printk(KERN_ERR "Failed to allocate APB timer devices\n"); | ||
617 | return; | ||
618 | } | ||
619 | for (i = 0; i < apbt_num_timers_used; i++) { | 359 | for (i = 0; i < apbt_num_timers_used; i++) { |
620 | adev = &per_cpu(cpu_apbt_dev, i); | 360 | adev = &per_cpu(cpu_apbt_dev, i); |
621 | adev->num = i; | 361 | adev->num = i; |
622 | adev->cpu = i; | 362 | adev->cpu = i; |
623 | p_mtmr = sfi_get_mtmr(i); | 363 | p_mtmr = sfi_get_mtmr(i); |
624 | if (p_mtmr) { | 364 | if (p_mtmr) |
625 | adev->tick = p_mtmr->freq_hz; | ||
626 | adev->irq = p_mtmr->irq; | 365 | adev->irq = p_mtmr->irq; |
627 | } else | 366 | else |
628 | printk(KERN_ERR "Failed to get timer for cpu %d\n", i); | 367 | printk(KERN_ERR "Failed to get timer for cpu %d\n", i); |
629 | adev->count = 0; | 368 | snprintf(adev->name, sizeof(adev->name) - 1, "apbt%d", i); |
630 | sprintf(adev->name, "apbt%d", i); | ||
631 | } | 369 | } |
632 | #endif | 370 | #endif |
633 | 371 | ||
@@ -639,17 +377,8 @@ out_noapbt: | |||
639 | panic("failed to enable APB timer\n"); | 377 | panic("failed to enable APB timer\n"); |
640 | } | 378 | } |
641 | 379 | ||
642 | static inline void apbt_disable(int n) | ||
643 | { | ||
644 | if (is_apbt_capable()) { | ||
645 | unsigned long ctrl = apbt_readl(n, APBTMR_N_CONTROL); | ||
646 | ctrl &= ~APBTMR_CONTROL_ENABLE; | ||
647 | apbt_writel(n, ctrl, APBTMR_N_CONTROL); | ||
648 | } | ||
649 | } | ||
650 | |||
651 | /* called before apb_timer_enable, use early map */ | 380 | /* called before apb_timer_enable, use early map */ |
652 | unsigned long apbt_quick_calibrate() | 381 | unsigned long apbt_quick_calibrate(void) |
653 | { | 382 | { |
654 | int i, scale; | 383 | int i, scale; |
655 | u64 old, new; | 384 | u64 old, new; |
@@ -658,31 +387,31 @@ unsigned long apbt_quick_calibrate() | |||
658 | u32 loop, shift; | 387 | u32 loop, shift; |
659 | 388 | ||
660 | apbt_set_mapping(); | 389 | apbt_set_mapping(); |
661 | apbt_start_counter(phy_cs_timer_id); | 390 | dw_apb_clocksource_start(clocksource_apbt); |
662 | 391 | ||
663 | /* check if the timer can count down, otherwise return */ | 392 | /* check if the timer can count down, otherwise return */ |
664 | old = apbt_read_clocksource(&clocksource_apbt); | 393 | old = dw_apb_clocksource_read(clocksource_apbt); |
665 | i = 10000; | 394 | i = 10000; |
666 | while (--i) { | 395 | while (--i) { |
667 | if (old != apbt_read_clocksource(&clocksource_apbt)) | 396 | if (old != dw_apb_clocksource_read(clocksource_apbt)) |
668 | break; | 397 | break; |
669 | } | 398 | } |
670 | if (!i) | 399 | if (!i) |
671 | goto failed; | 400 | goto failed; |
672 | 401 | ||
673 | /* count 16 ms */ | 402 | /* count 16 ms */ |
674 | loop = (apbt_freq * 1000) << 4; | 403 | loop = (apbt_freq / 1000) << 4; |
675 | 404 | ||
676 | /* restart the timer to ensure it won't get to 0 in the calibration */ | 405 | /* restart the timer to ensure it won't get to 0 in the calibration */ |
677 | apbt_start_counter(phy_cs_timer_id); | 406 | dw_apb_clocksource_start(clocksource_apbt); |
678 | 407 | ||
679 | old = apbt_read_clocksource(&clocksource_apbt); | 408 | old = dw_apb_clocksource_read(clocksource_apbt); |
680 | old += loop; | 409 | old += loop; |
681 | 410 | ||
682 | t1 = __native_read_tsc(); | 411 | t1 = __native_read_tsc(); |
683 | 412 | ||
684 | do { | 413 | do { |
685 | new = apbt_read_clocksource(&clocksource_apbt); | 414 | new = dw_apb_clocksource_read(clocksource_apbt); |
686 | } while (new < old); | 415 | } while (new < old); |
687 | 416 | ||
688 | t2 = __native_read_tsc(); | 417 | t2 = __native_read_tsc(); |
@@ -694,7 +423,7 @@ unsigned long apbt_quick_calibrate() | |||
694 | return 0; | 423 | return 0; |
695 | } | 424 | } |
696 | scale = (int)div_u64((t2 - t1), loop >> shift); | 425 | scale = (int)div_u64((t2 - t1), loop >> shift); |
697 | khz = (scale * apbt_freq * 1000) >> shift; | 426 | khz = (scale * (apbt_freq / 1000)) >> shift; |
698 | printk(KERN_INFO "TSC freq calculated by APB timer is %lu khz\n", khz); | 427 | printk(KERN_INFO "TSC freq calculated by APB timer is %lu khz\n", khz); |
699 | return khz; | 428 | return khz; |
700 | failed: | 429 | failed: |