# BRCM_VERSION=3
[bcm963xx.git] / kernel / linux / arch / arm / mach-versatile / core.c
1 /*
2  *  linux/arch/arm/mach-versatile/core.c
3  *
4  *  Copyright (C) 1999 - 2003 ARM Limited
5  *  Copyright (C) 2000 Deep Blue Solutions Ltd
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  */
21 #include <linux/config.h>
22 #include <linux/init.h>
23 #include <linux/device.h>
24 #include <linux/sysdev.h>
25 #include <linux/interrupt.h>
26
27 #include <asm/system.h>
28 #include <asm/hardware.h>
29 #include <asm/io.h>
30 #include <asm/irq.h>
31 #include <asm/leds.h>
32 #include <asm/mach-types.h>
33 #include <asm/hardware/amba.h>
34
35 #include <asm/mach/arch.h>
36 #include <asm/mach/flash.h>
37 #include <asm/mach/irq.h>
38 #include <asm/mach/time.h>
39 #include <asm/mach/map.h>
40 #ifdef CONFIG_MMC
41 #include <asm/mach/mmc.h>
42 #endif
43
44 /*
45  * All IO addresses are mapped onto VA 0xFFFx.xxxx, where x.xxxx
46  * is the (PA >> 12).
47  *
48  * Setup a VA for the Versatile Vectored Interrupt Controller.
49  */
50 #define VA_VIC_BASE              IO_ADDRESS(VERSATILE_VIC_BASE)
51 #define VA_SIC_BASE              IO_ADDRESS(VERSATILE_SIC_BASE)
52
53 static void vic_mask_irq(unsigned int irq)
54 {
55         irq -= IRQ_VIC_START;
56         writel(1 << irq, VA_VIC_BASE + VIC_IRQ_ENABLE_CLEAR);
57 }
58
59 static void vic_unmask_irq(unsigned int irq)
60 {
61         irq -= IRQ_VIC_START;
62         writel(1 << irq, VA_VIC_BASE + VIC_IRQ_ENABLE);
63 }
64
65 static struct irqchip vic_chip = {
66         .ack    = vic_mask_irq,
67         .mask   = vic_mask_irq,
68         .unmask = vic_unmask_irq,
69 };
70
71 static void sic_mask_irq(unsigned int irq)
72 {
73         irq -= IRQ_SIC_START;
74         writel(1 << irq, VA_SIC_BASE + SIC_IRQ_ENABLE_CLEAR);
75 }
76
77 static void sic_unmask_irq(unsigned int irq)
78 {
79         irq -= IRQ_SIC_START;
80         writel(1 << irq, VA_SIC_BASE + SIC_IRQ_ENABLE_SET);
81 }
82
83 static struct irqchip sic_chip = {
84         .ack    = sic_mask_irq,
85         .mask   = sic_mask_irq,
86         .unmask = sic_unmask_irq,
87 };
88
89 static void
90 sic_handle_irq(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs)
91 {
92         unsigned long status = readl(VA_SIC_BASE + SIC_IRQ_STATUS);
93
94         if (status == 0) {
95                 do_bad_IRQ(irq, desc, regs);
96                 return;
97         }
98
99         do {
100                 irq = ffs(status) - 1;
101                 status &= ~(1 << irq);
102
103                 irq += IRQ_SIC_START;
104
105                 desc = irq_desc + irq;
106                 desc->handle(irq, desc, regs);
107         } while (status);
108 }
109
110 #if 1
111 #define IRQ_MMCI0A      IRQ_VICSOURCE22
112 #define IRQ_MMCI1A      IRQ_VICSOURCE23
113 #define IRQ_AACI        IRQ_VICSOURCE24
114 #define IRQ_ETH         IRQ_VICSOURCE25
115 #define PIC_MASK        0xFFD00000
116 #else
117 #define IRQ_MMCI0A      IRQ_SIC_MMCI0A
118 #define IRQ_MMCI1A      IRQ_SIC_MMCI1A
119 #define IRQ_AACI        IRQ_SIC_AACI
120 #define IRQ_ETH         IRQ_SIC_ETH
121 #define PIC_MASK        0
122 #endif
123
124 static void __init versatile_init_irq(void)
125 {
126         unsigned int i, value;
127
128         /* Disable all interrupts initially. */
129
130         writel(0, VA_VIC_BASE + VIC_INT_SELECT);
131         writel(0, VA_VIC_BASE + VIC_IRQ_ENABLE);
132         writel(~0, VA_VIC_BASE + VIC_IRQ_ENABLE_CLEAR);
133         writel(0, VA_VIC_BASE + VIC_IRQ_STATUS);
134         writel(0, VA_VIC_BASE + VIC_ITCR);
135         writel(~0, VA_VIC_BASE + VIC_IRQ_SOFT_CLEAR);
136
137         /*
138          * Make sure we clear all existing interrupts
139          */
140         writel(0, VA_VIC_BASE + VIC_VECT_ADDR);
141         for (i = 0; i < 19; i++) {
142                 value = readl(VA_VIC_BASE + VIC_VECT_ADDR);
143                 writel(value, VA_VIC_BASE + VIC_VECT_ADDR);
144         }
145
146         for (i = 0; i < 16; i++) {
147                 value = readl(VA_VIC_BASE + VIC_VECT_CNTL0 + (i * 4));
148                 writel(value | VICVectCntl_Enable | i, VA_VIC_BASE + VIC_VECT_CNTL0 + (i * 4));
149         }
150
151         writel(32, VA_VIC_BASE + VIC_DEF_VECT_ADDR);
152
153         for (i = IRQ_VIC_START; i <= IRQ_VIC_END; i++) {
154                 if (i != IRQ_VICSOURCE31) {
155                         set_irq_chip(i, &vic_chip);
156                         set_irq_handler(i, do_level_IRQ);
157                         set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
158                 }
159         }
160
161         set_irq_handler(IRQ_VICSOURCE31, sic_handle_irq);
162         vic_unmask_irq(IRQ_VICSOURCE31);
163
164         /* Do second interrupt controller */
165         writel(~0, VA_SIC_BASE + SIC_IRQ_ENABLE_CLEAR);
166
167         for (i = IRQ_SIC_START; i <= IRQ_SIC_END; i++) {
168                 if ((PIC_MASK & (1 << (i - IRQ_SIC_START))) == 0) {
169                         set_irq_chip(i, &sic_chip);
170                         set_irq_handler(i, do_level_IRQ);
171                         set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
172                 }
173         }
174
175         /*
176          * Interrupts on secondary controller from 0 to 8 are routed to
177          * source 31 on PIC.
178          * Interrupts from 21 to 31 are routed directly to the VIC on
179          * the corresponding number on primary controller. This is controlled
180          * by setting PIC_ENABLEx.
181          */
182         writel(PIC_MASK, VA_SIC_BASE + SIC_INT_PIC_ENABLE);
183 }
184
185 static struct map_desc versatile_io_desc[] __initdata = {
186  { IO_ADDRESS(VERSATILE_SYS_BASE),   VERSATILE_SYS_BASE,   SZ_4K,      MT_DEVICE },
187  { IO_ADDRESS(VERSATILE_SIC_BASE),   VERSATILE_SIC_BASE,   SZ_4K,      MT_DEVICE },
188  { IO_ADDRESS(VERSATILE_VIC_BASE),   VERSATILE_VIC_BASE,   SZ_4K,      MT_DEVICE },
189  { IO_ADDRESS(VERSATILE_SCTL_BASE),  VERSATILE_SCTL_BASE,  SZ_4K * 9,  MT_DEVICE },
190 #ifdef CONFIG_DEBUG_LL
191  { IO_ADDRESS(VERSATILE_UART0_BASE), VERSATILE_UART0_BASE, SZ_4K,      MT_DEVICE },
192 #endif
193 #ifdef FIXME
194  { PCI_MEMORY_VADDR,                 PHYS_PCI_MEM_BASE,    SZ_16M,     MT_DEVICE },
195  { PCI_CONFIG_VADDR,                 PHYS_PCI_CONFIG_BASE, SZ_16M,     MT_DEVICE },
196  { PCI_V3_VADDR,                     PHYS_PCI_V3_BASE,     SZ_512K,    MT_DEVICE },
197  { PCI_IO_VADDR,                     PHYS_PCI_IO_BASE,     SZ_64K,     MT_DEVICE },
198 #endif
199 };
200
201 static void __init versatile_map_io(void)
202 {
203         iotable_init(versatile_io_desc, ARRAY_SIZE(versatile_io_desc));
204 }
205
206 #define VERSATILE_REFCOUNTER    (IO_ADDRESS(VERSATILE_SYS_BASE) + VERSATILE_SYS_24MHz_OFFSET)
207
208 /*
209  * This is the VersatilePB sched_clock implementation.  This has
210  * a resolution of 41.7ns, and a maximum value of about 179s.
211  */
212 unsigned long long sched_clock(void)
213 {
214         unsigned long long v;
215
216         v = (unsigned long long)readl(VERSATILE_REFCOUNTER) * 125;
217         do_div(v, 3);
218
219         return v;
220 }
221
222
223 #define VERSATILE_FLASHCTRL    (IO_ADDRESS(VERSATILE_SYS_BASE) + VERSATILE_SYS_FLASH_OFFSET)
224
225 static int versatile_flash_init(void)
226 {
227         u32 val;
228
229         val = __raw_readl(VERSATILE_FLASHCTRL);
230         val &= ~VERSATILE_FLASHPROG_FLVPPEN;
231         __raw_writel(val, VERSATILE_FLASHCTRL);
232
233         return 0;
234 }
235
236 static void versatile_flash_exit(void)
237 {
238         u32 val;
239
240         val = __raw_readl(VERSATILE_FLASHCTRL);
241         val &= ~VERSATILE_FLASHPROG_FLVPPEN;
242         __raw_writel(val, VERSATILE_FLASHCTRL);
243 }
244
245 static void versatile_flash_set_vpp(int on)
246 {
247         u32 val;
248
249         val = __raw_readl(VERSATILE_FLASHCTRL);
250         if (on)
251                 val |= VERSATILE_FLASHPROG_FLVPPEN;
252         else
253                 val &= ~VERSATILE_FLASHPROG_FLVPPEN;
254         __raw_writel(val, VERSATILE_FLASHCTRL);
255 }
256
257 static struct flash_platform_data versatile_flash_data = {
258         .map_name               = "cfi_probe",
259         .width                  = 4,
260         .init                   = versatile_flash_init,
261         .exit                   = versatile_flash_exit,
262         .set_vpp                = versatile_flash_set_vpp,
263 };
264
265 static struct resource versatile_flash_resource = {
266         .start                  = VERSATILE_FLASH_BASE,
267         .end                    = VERSATILE_FLASH_BASE + VERSATILE_FLASH_SIZE,
268         .flags                  = IORESOURCE_MEM,
269 };
270
271 static struct platform_device versatile_flash_device = {
272         .name                   = "armflash",
273         .id                     = 0,
274         .dev                    = {
275                 .platform_data  = &versatile_flash_data,
276         },
277         .num_resources          = 1,
278         .resource               = &versatile_flash_resource,
279 };
280
281 static struct resource smc91x_resources[] = {
282         [0] = {
283                 .start          = VERSATILE_ETH_BASE,
284                 .end            = VERSATILE_ETH_BASE + SZ_64K - 1,
285                 .flags          = IORESOURCE_MEM,
286         },
287         [1] = {
288                 .start          = IRQ_ETH,
289                 .end            = IRQ_ETH,
290                 .flags          = IORESOURCE_IRQ,
291         },
292 };
293
294 static struct platform_device smc91x_device = {
295         .name           = "smc91x",
296         .id             = 0,
297         .num_resources  = ARRAY_SIZE(smc91x_resources),
298         .resource       = smc91x_resources,
299 };
300
301 #define VERSATILE_SYSMCI        (IO_ADDRESS(VERSATILE_SYS_BASE) + VERSATILE_SYS_MCI_OFFSET)
302
303 #ifdef CONFIG_MMC
304 static unsigned int mmc_status(struct device *dev)
305 {
306         struct amba_device *adev = container_of(dev, struct amba_device, dev);
307         u32 mask;
308
309         if (adev->res.start == VERSATILE_MMCI0_BASE)
310                 mask = 1;
311         else
312                 mask = 2;
313
314         return readl(VERSATILE_SYSMCI) & mask;
315 }
316
317 static struct mmc_platform_data mmc0_plat_data = {
318         .ocr_mask       = MMC_VDD_32_33|MMC_VDD_33_34,
319         .status         = mmc_status,
320 };
321
322 static struct mmc_platform_data mmc1_plat_data = {
323         .ocr_mask       = MMC_VDD_32_33|MMC_VDD_33_34,
324         .status         = mmc_status,
325 };
326 #endif
327
328 #define AMBA_DEVICE(name,busid,base,plat)                       \
329 static struct amba_device name##_device = {                     \
330         .dev            = {                                     \
331                 .coherent_dma_mask = ~0,                        \
332                 .bus_id = busid,                                \
333                 .platform_data = plat,                          \
334         },                                                      \
335         .res            = {                                     \
336                 .start  = VERSATILE_##base##_BASE,              \
337                 .end    = (VERSATILE_##base##_BASE) + SZ_4K - 1,\
338                 .flags  = IORESOURCE_MEM,                       \
339         },                                                      \
340         .dma_mask       = ~0,                                   \
341         .irq            = base##_IRQ,                           \
342         /* .dma         = base##_DMA,*/                         \
343 }
344
345 #define AACI_IRQ        { IRQ_AACI, NO_IRQ }
346 #define AACI_DMA        { 0x80, 0x81 }
347 #define MMCI0_IRQ       { IRQ_MMCI0A,IRQ_SIC_MMCI0B }
348 #define MMCI0_DMA       { 0x84, 0 }
349 #define KMI0_IRQ        { IRQ_SIC_KMI0, NO_IRQ }
350 #define KMI0_DMA        { 0, 0 }
351 #define KMI1_IRQ        { IRQ_SIC_KMI1, NO_IRQ }
352 #define KMI1_DMA        { 0, 0 }
353 #define UART3_IRQ       { IRQ_SIC_UART3, NO_IRQ }
354 #define UART3_DMA       { 0x86, 0x87 }
355 #define SCI1_IRQ        { IRQ_SIC_SCI3, NO_IRQ }
356 #define SCI1_DMA        { 0x88, 0x89 }
357 #define MMCI1_IRQ       { IRQ_MMCI1A, IRQ_SIC_MMCI1B }
358 #define MMCI1_DMA       { 0x85, 0 }
359
360 /*
361  * These devices are connected directly to the multi-layer AHB switch
362  */
363 #define SMC_IRQ         { NO_IRQ, NO_IRQ }
364 #define SMC_DMA         { 0, 0 }
365 #define MPMC_IRQ        { NO_IRQ, NO_IRQ }
366 #define MPMC_DMA        { 0, 0 }
367 #define CLCD_IRQ        { IRQ_CLCDINT, NO_IRQ }
368 #define CLCD_DMA        { 0, 0 }
369 #define DMAC_IRQ        { IRQ_DMAINT, NO_IRQ }
370 #define DMAC_DMA        { 0, 0 }
371
372 /*
373  * These devices are connected via the core APB bridge
374  */
375 #define SCTL_IRQ        { NO_IRQ, NO_IRQ }
376 #define SCTL_DMA        { 0, 0 }
377 #define WATCHDOG_IRQ    { IRQ_WDOGINT, NO_IRQ }
378 #define WATCHDOG_DMA    { 0, 0 }
379 #define GPIO0_IRQ       { IRQ_GPIOINT0, NO_IRQ }
380 #define GPIO0_DMA       { 0, 0 }
381 #define GPIO1_IRQ       { IRQ_GPIOINT1, NO_IRQ }
382 #define GPIO1_DMA       { 0, 0 }
383 #define GPIO2_IRQ       { IRQ_GPIOINT2, NO_IRQ }
384 #define GPIO2_DMA       { 0, 0 }
385 #define GPIO3_IRQ       { IRQ_GPIOINT3, NO_IRQ }
386 #define GPIO3_DMA       { 0, 0 }
387 #define RTC_IRQ         { IRQ_RTCINT, NO_IRQ }
388 #define RTC_DMA         { 0, 0 }
389
390 /*
391  * These devices are connected via the DMA APB bridge
392  */
393 #define SCI_IRQ         { IRQ_SCIINT, NO_IRQ }
394 #define SCI_DMA         { 7, 6 }
395 #define UART0_IRQ       { IRQ_UARTINT0, NO_IRQ }
396 #define UART0_DMA       { 15, 14 }
397 #define UART1_IRQ       { IRQ_UARTINT1, NO_IRQ }
398 #define UART1_DMA       { 13, 12 }
399 #define UART2_IRQ       { IRQ_UARTINT2, NO_IRQ }
400 #define UART2_DMA       { 11, 10 }
401 #define SSP_IRQ         { IRQ_SSPINT, NO_IRQ }
402 #define SSP_DMA         { 9, 8 }
403
404 /* FPGA Primecells */
405 AMBA_DEVICE(aaci,  "fpga:04", AACI,     NULL);
406 #ifdef CONFIG_MMC
407 AMBA_DEVICE(mmc0,  "fpga:05", MMCI0,    &mmc0_plat_data);
408 #endif
409 AMBA_DEVICE(kmi0,  "fpga:06", KMI0,     NULL);
410 AMBA_DEVICE(kmi1,  "fpga:07", KMI1,     NULL);
411 AMBA_DEVICE(uart3, "fpga:09", UART3,    NULL);
412 AMBA_DEVICE(sci1,  "fpga:0a", SCI1,     NULL);
413 #ifdef CONFIG_MMC
414 AMBA_DEVICE(mmc1,  "fpga:0b", MMCI1,    &mmc1_plat_data);
415 #endif
416
417 /* DevChip Primecells */
418 AMBA_DEVICE(smc,   "dev:00",  SMC,      NULL);
419 AMBA_DEVICE(mpmc,  "dev:10",  MPMC,     NULL);
420 AMBA_DEVICE(clcd,  "dev:20",  CLCD,     NULL);
421 AMBA_DEVICE(dmac,  "dev:30",  DMAC,     NULL);
422 AMBA_DEVICE(sctl,  "dev:e0",  SCTL,     NULL);
423 AMBA_DEVICE(wdog,  "dev:e1",  WATCHDOG, NULL);
424 AMBA_DEVICE(gpio0, "dev:e4",  GPIO0,    NULL);
425 AMBA_DEVICE(gpio1, "dev:e5",  GPIO1,    NULL);
426 AMBA_DEVICE(gpio2, "dev:e6",  GPIO2,    NULL);
427 AMBA_DEVICE(gpio3, "dev:e7",  GPIO3,    NULL);
428 AMBA_DEVICE(rtc,   "dev:e8",  RTC,      NULL);
429 AMBA_DEVICE(sci0,  "dev:f0",  SCI,      NULL);
430 AMBA_DEVICE(uart0, "dev:f1",  UART0,    NULL);
431 AMBA_DEVICE(uart1, "dev:f2",  UART1,    NULL);
432 AMBA_DEVICE(uart2, "dev:f3",  UART2,    NULL);
433 AMBA_DEVICE(ssp0,  "dev:f4",  SSP,      NULL);
434
435 static struct amba_device *amba_devs[] __initdata = {
436         &dmac_device,
437         &uart0_device,
438         &uart1_device,
439         &uart2_device,
440         &uart3_device,
441         &smc_device,
442         &mpmc_device,
443         &clcd_device,
444         &sctl_device,
445         &wdog_device,
446         &gpio0_device,
447         &gpio1_device,
448         &gpio2_device,
449         &gpio3_device,
450         &rtc_device,
451         &sci0_device,
452         &ssp0_device,
453         &aaci_device,
454 #ifdef CONFIG_MMC
455         &mmc0_device,
456 #endif
457         &kmi0_device,
458         &kmi1_device,
459         &sci1_device,
460 #ifdef CONFIG_MMC
461         &mmc1_device,
462 #endif
463 };
464
465 #define VA_LEDS_BASE (IO_ADDRESS(VERSATILE_SYS_BASE) + VERSATILE_SYS_LED_OFFSET)
466
467 static void versatile_leds_event(led_event_t ledevt)
468 {
469         unsigned long flags;
470         u32 val;
471
472         local_irq_save(flags);
473         val = readl(VA_LEDS_BASE);
474
475         switch (ledevt) {
476         case led_idle_start:
477                 val = val & ~VERSATILE_SYS_LED0;
478                 break;
479
480         case led_idle_end:
481                 val = val | VERSATILE_SYS_LED0;
482                 break;
483
484         case led_timer:
485                 val = val ^ VERSATILE_SYS_LED1;
486                 break;
487
488         case led_halted:
489                 val = 0;
490                 break;
491
492         default:
493                 break;
494         }
495
496         writel(val, VA_LEDS_BASE);
497         local_irq_restore(flags);
498 }
499
500 static void __init versatile_init(void)
501 {
502         int i;
503
504         platform_device_register(&versatile_flash_device);
505         platform_device_register(&smc91x_device);
506
507         for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
508                 struct amba_device *d = amba_devs[i];
509                 amba_device_register(d, &iomem_resource);
510         }
511
512         leds_event = versatile_leds_event;
513 }
514
515 /*
516  * Where is the timer (VA)?
517  */
518 #define TIMER0_VA_BASE           IO_ADDRESS(VERSATILE_TIMER0_1_BASE)
519 #define TIMER1_VA_BASE          (IO_ADDRESS(VERSATILE_TIMER0_1_BASE) + 0x20)
520 #define TIMER2_VA_BASE           IO_ADDRESS(VERSATILE_TIMER2_3_BASE)
521 #define TIMER3_VA_BASE          (IO_ADDRESS(VERSATILE_TIMER2_3_BASE) + 0x20)
522 #define VA_IC_BASE               IO_ADDRESS(VERSATILE_VIC_BASE) 
523
524 /*
525  * How long is the timer interval?
526  */
527 #define TIMER_INTERVAL  (TICKS_PER_uSEC * mSEC_10)
528 #if TIMER_INTERVAL >= 0x100000
529 #define TIMER_RELOAD    (TIMER_INTERVAL >> 8)           /* Divide by 256 */
530 #define TIMER_CTRL      0x88                            /* Enable, Clock / 256 */
531 #define TICKS2USECS(x)  (256 * (x) / TICKS_PER_uSEC)
532 #elif TIMER_INTERVAL >= 0x10000
533 #define TIMER_RELOAD    (TIMER_INTERVAL >> 4)           /* Divide by 16 */
534 #define TIMER_CTRL      0x84                            /* Enable, Clock / 16 */
535 #define TICKS2USECS(x)  (16 * (x) / TICKS_PER_uSEC)
536 #else
537 #define TIMER_RELOAD    (TIMER_INTERVAL)
538 #define TIMER_CTRL      0x80                            /* Enable */
539 #define TICKS2USECS(x)  ((x) / TICKS_PER_uSEC)
540 #endif
541
542 #define TIMER_CTRL_IE   (1 << 5)        /* Interrupt Enable */
543
544 /*
545  * What does it look like?
546  */
547 typedef struct TimerStruct {
548         unsigned long TimerLoad;
549         unsigned long TimerValue;
550         unsigned long TimerControl;
551         unsigned long TimerClear;
552 } TimerStruct_t;
553
554 extern unsigned long (*gettimeoffset)(void);
555
556 /*
557  * Returns number of ms since last clock interrupt.  Note that interrupts
558  * will have been disabled by do_gettimeoffset()
559  */
560 static unsigned long versatile_gettimeoffset(void)
561 {
562         volatile TimerStruct_t *timer0 = (TimerStruct_t *)TIMER0_VA_BASE;
563         unsigned long ticks1, ticks2, status;
564
565         /*
566          * Get the current number of ticks.  Note that there is a race
567          * condition between us reading the timer and checking for
568          * an interrupt.  We get around this by ensuring that the
569          * counter has not reloaded between our two reads.
570          */
571         ticks2 = timer0->TimerValue & 0xffff;
572         do {
573                 ticks1 = ticks2;
574                 status = __raw_readl(VA_IC_BASE + VIC_IRQ_RAW_STATUS);
575                 ticks2 = timer0->TimerValue & 0xffff;
576         } while (ticks2 > ticks1);
577
578         /*
579          * Number of ticks since last interrupt.
580          */
581         ticks1 = TIMER_RELOAD - ticks2;
582
583         /*
584          * Interrupt pending?  If so, we've reloaded once already.
585          *
586          * FIXME: Need to check this is effectively timer 0 that expires
587          */
588         if (status & IRQMASK_TIMERINT0_1)
589                 ticks1 += TIMER_RELOAD;
590
591         /*
592          * Convert the ticks to usecs
593          */
594         return TICKS2USECS(ticks1);
595 }
596
597 /*
598  * IRQ handler for the timer
599  */
600 static irqreturn_t versatile_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
601 {
602         volatile TimerStruct_t *timer0 = (volatile TimerStruct_t *)TIMER0_VA_BASE;
603
604         // ...clear the interrupt
605         timer0->TimerClear = 1;
606
607         timer_tick(regs);
608
609         return IRQ_HANDLED;
610 }
611
612 static struct irqaction versatile_timer_irq = {
613         .name           = "Versatile Timer Tick",
614         .flags          = SA_INTERRUPT,
615         .handler        = versatile_timer_interrupt
616 };
617
618 /*
619  * Set up timer interrupt, and return the current time in seconds.
620  */
621 void __init versatile_init_time(void)
622 {
623         volatile TimerStruct_t *timer0 = (volatile TimerStruct_t *)TIMER0_VA_BASE;
624         volatile TimerStruct_t *timer1 = (volatile TimerStruct_t *)TIMER1_VA_BASE;
625         volatile TimerStruct_t *timer2 = (volatile TimerStruct_t *)TIMER2_VA_BASE;
626         volatile TimerStruct_t *timer3 = (volatile TimerStruct_t *)TIMER3_VA_BASE;
627
628         /* 
629          * set clock frequency: 
630          *      VERSATILE_REFCLK is 32KHz
631          *      VERSATILE_TIMCLK is 1MHz
632          */
633         *(volatile unsigned int *)IO_ADDRESS(VERSATILE_SCTL_BASE) |= 
634           ((VERSATILE_TIMCLK << VERSATILE_TIMER1_EnSel) | (VERSATILE_TIMCLK << VERSATILE_TIMER2_EnSel) | 
635            (VERSATILE_TIMCLK << VERSATILE_TIMER3_EnSel) | (VERSATILE_TIMCLK << VERSATILE_TIMER4_EnSel));
636
637         /*
638          * Initialise to a known state (all timers off)
639          */
640         timer0->TimerControl = 0;
641         timer1->TimerControl = 0;
642         timer2->TimerControl = 0;
643         timer3->TimerControl = 0;
644
645         timer0->TimerLoad    = TIMER_RELOAD;
646         timer0->TimerValue   = TIMER_RELOAD;
647         timer0->TimerControl = TIMER_CTRL | 0x40 | TIMER_CTRL_IE;  /* periodic + IE */
648
649         /* 
650          * Make irqs happen for the system timer
651          */
652         setup_irq(IRQ_TIMERINT0_1, &versatile_timer_irq);
653         gettimeoffset = versatile_gettimeoffset;
654 }
655
656 MACHINE_START(VERSATILE_PB, "ARM-Versatile PB")
657         MAINTAINER("ARM Ltd/Deep Blue Solutions Ltd")
658         BOOT_MEM(0x00000000, 0x101f1000, 0xf11f1000)
659         BOOT_PARAMS(0x00000100)
660         MAPIO(versatile_map_io)
661         INITIRQ(versatile_init_irq)
662         INITTIME(versatile_init_time)
663         INIT_MACHINE(versatile_init)
664 MACHINE_END