27b48be73676077e57f1e57433917331a4dcccfc
[linux-2.6.git] / arch / arm / mach-realview / core.c
1 /*
2  *  linux/arch/arm/mach-realview/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/init.h>
22 #include <linux/platform_device.h>
23 #include <linux/dma-mapping.h>
24 #include <linux/sysdev.h>
25 #include <linux/interrupt.h>
26 #include <linux/amba/bus.h>
27 #include <linux/amba/clcd.h>
28 #include <linux/clocksource.h>
29 #include <linux/clockchips.h>
30 #include <linux/io.h>
31 #include <linux/smc911x.h>
32
33 #include <asm/clkdev.h>
34 #include <asm/system.h>
35 #include <mach/hardware.h>
36 #include <asm/irq.h>
37 #include <asm/leds.h>
38 #include <asm/mach-types.h>
39 #include <asm/hardware/arm_timer.h>
40 #include <asm/hardware/icst307.h>
41
42 #include <asm/mach/arch.h>
43 #include <asm/mach/flash.h>
44 #include <asm/mach/irq.h>
45 #include <asm/mach/map.h>
46 #include <asm/mach/mmc.h>
47
48 #include <asm/hardware/gic.h>
49
50 #include "core.h"
51 #include "clock.h"
52
53 #define REALVIEW_REFCOUNTER     (__io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_24MHz_OFFSET)
54
55 /* used by entry-macro.S and platsmp.c */
56 void __iomem *gic_cpu_base_addr;
57
58 /*
59  * This is the RealView sched_clock implementation.  This has
60  * a resolution of 41.7ns, and a maximum value of about 179s.
61  */
62 unsigned long long sched_clock(void)
63 {
64         unsigned long long v;
65
66         v = (unsigned long long)readl(REALVIEW_REFCOUNTER) * 125;
67         do_div(v, 3);
68
69         return v;
70 }
71
72
73 #define REALVIEW_FLASHCTRL    (__io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_FLASH_OFFSET)
74
75 static int realview_flash_init(void)
76 {
77         u32 val;
78
79         val = __raw_readl(REALVIEW_FLASHCTRL);
80         val &= ~REALVIEW_FLASHPROG_FLVPPEN;
81         __raw_writel(val, REALVIEW_FLASHCTRL);
82
83         return 0;
84 }
85
86 static void realview_flash_exit(void)
87 {
88         u32 val;
89
90         val = __raw_readl(REALVIEW_FLASHCTRL);
91         val &= ~REALVIEW_FLASHPROG_FLVPPEN;
92         __raw_writel(val, REALVIEW_FLASHCTRL);
93 }
94
95 static void realview_flash_set_vpp(int on)
96 {
97         u32 val;
98
99         val = __raw_readl(REALVIEW_FLASHCTRL);
100         if (on)
101                 val |= REALVIEW_FLASHPROG_FLVPPEN;
102         else
103                 val &= ~REALVIEW_FLASHPROG_FLVPPEN;
104         __raw_writel(val, REALVIEW_FLASHCTRL);
105 }
106
107 static struct flash_platform_data realview_flash_data = {
108         .map_name               = "cfi_probe",
109         .width                  = 4,
110         .init                   = realview_flash_init,
111         .exit                   = realview_flash_exit,
112         .set_vpp                = realview_flash_set_vpp,
113 };
114
115 struct platform_device realview_flash_device = {
116         .name                   = "armflash",
117         .id                     = 0,
118         .dev                    = {
119                 .platform_data  = &realview_flash_data,
120         },
121 };
122
123 int realview_flash_register(struct resource *res, u32 num)
124 {
125         realview_flash_device.resource = res;
126         realview_flash_device.num_resources = num;
127         return platform_device_register(&realview_flash_device);
128 }
129
130 static struct smc911x_platdata realview_smc911x_platdata = {
131         .flags          = SMC911X_USE_32BIT,
132         .irq_flags      = IRQF_SHARED,
133         .irq_polarity   = 1,
134 };
135
136 static struct platform_device realview_eth_device = {
137         .name           = "smc911x",
138         .id             = 0,
139         .num_resources  = 2,
140 };
141
142 int realview_eth_register(const char *name, struct resource *res)
143 {
144         if (name)
145                 realview_eth_device.name = name;
146         realview_eth_device.resource = res;
147         if (strcmp(realview_eth_device.name, "smc911x") == 0)
148                 realview_eth_device.dev.platform_data = &realview_smc911x_platdata;
149
150         return platform_device_register(&realview_eth_device);
151 }
152
153 static struct resource realview_i2c_resource = {
154         .start          = REALVIEW_I2C_BASE,
155         .end            = REALVIEW_I2C_BASE + SZ_4K - 1,
156         .flags          = IORESOURCE_MEM,
157 };
158
159 struct platform_device realview_i2c_device = {
160         .name           = "versatile-i2c",
161         .id             = 0,
162         .num_resources  = 1,
163         .resource       = &realview_i2c_resource,
164 };
165
166 static struct i2c_board_info realview_i2c_board_info[] = {
167         {
168                 I2C_BOARD_INFO("rtc-ds1307", 0xd0 >> 1),
169                 .type = "ds1338",
170         },
171 };
172
173 static int __init realview_i2c_init(void)
174 {
175         return i2c_register_board_info(0, realview_i2c_board_info,
176                                        ARRAY_SIZE(realview_i2c_board_info));
177 }
178 arch_initcall(realview_i2c_init);
179
180 #define REALVIEW_SYSMCI (__io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_MCI_OFFSET)
181
182 static unsigned int realview_mmc_status(struct device *dev)
183 {
184         struct amba_device *adev = container_of(dev, struct amba_device, dev);
185         u32 mask;
186
187         if (adev->res.start == REALVIEW_MMCI0_BASE)
188                 mask = 1;
189         else
190                 mask = 2;
191
192         return readl(REALVIEW_SYSMCI) & mask;
193 }
194
195 struct mmc_platform_data realview_mmc0_plat_data = {
196         .ocr_mask       = MMC_VDD_32_33|MMC_VDD_33_34,
197         .status         = realview_mmc_status,
198 };
199
200 struct mmc_platform_data realview_mmc1_plat_data = {
201         .ocr_mask       = MMC_VDD_32_33|MMC_VDD_33_34,
202         .status         = realview_mmc_status,
203 };
204
205 /*
206  * Clock handling
207  */
208 static const struct icst307_params realview_oscvco_params = {
209         .ref            = 24000,
210         .vco_max        = 200000,
211         .vd_min         = 4 + 8,
212         .vd_max         = 511 + 8,
213         .rd_min         = 1 + 2,
214         .rd_max         = 127 + 2,
215 };
216
217 static void realview_oscvco_set(struct clk *clk, struct icst307_vco vco)
218 {
219         void __iomem *sys_lock = __io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_LOCK_OFFSET;
220         void __iomem *sys_osc;
221         u32 val;
222
223         if (machine_is_realview_pb1176())
224                 sys_osc = __io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_OSC0_OFFSET;
225         else
226                 sys_osc = __io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_OSC4_OFFSET;
227
228         val = readl(sys_osc) & ~0x7ffff;
229         val |= vco.v | (vco.r << 9) | (vco.s << 16);
230
231         writel(0xa05f, sys_lock);
232         writel(val, sys_osc);
233         writel(0, sys_lock);
234 }
235
236 static struct clk oscvco_clk = {
237         .params = &realview_oscvco_params,
238         .setvco = realview_oscvco_set,
239 };
240
241 /*
242  * These are fixed clocks.
243  */
244 static struct clk ref24_clk = {
245         .rate   = 24000000,
246 };
247
248 static struct clk_lookup lookups[] = {
249         {       /* UART0 */
250                 .dev_id         = "dev:f1",
251                 .clk            = &ref24_clk,
252         }, {    /* UART1 */
253                 .dev_id         = "dev:f2",
254                 .clk            = &ref24_clk,
255         }, {    /* UART2 */
256                 .dev_id         = "dev:f3",
257                 .clk            = &ref24_clk,
258         }, {    /* UART3 */
259                 .dev_id         = "fpga:09",
260                 .clk            = &ref24_clk,
261         }, {    /* KMI0 */
262                 .dev_id         = "fpga:06",
263                 .clk            = &ref24_clk,
264         }, {    /* KMI1 */
265                 .dev_id         = "fpga:07",
266                 .clk            = &ref24_clk,
267         }, {    /* MMC0 */
268                 .dev_id         = "fpga:05",
269                 .clk            = &ref24_clk,
270         }, {    /* EB:CLCD */
271                 .dev_id         = "dev:20",
272                 .clk            = &oscvco_clk,
273         }, {    /* PB:CLCD */
274                 .dev_id         = "issp:20",
275                 .clk            = &oscvco_clk,
276         }
277 };
278
279 static int __init clk_init(void)
280 {
281         int i;
282
283         for (i = 0; i < ARRAY_SIZE(lookups); i++)
284                 clkdev_add(&lookups[i]);
285         return 0;
286 }
287 arch_initcall(clk_init);
288
289 /*
290  * CLCD support.
291  */
292 #define SYS_CLCD_NLCDIOON       (1 << 2)
293 #define SYS_CLCD_VDDPOSSWITCH   (1 << 3)
294 #define SYS_CLCD_PWR3V5SWITCH   (1 << 4)
295 #define SYS_CLCD_ID_MASK        (0x1f << 8)
296 #define SYS_CLCD_ID_SANYO_3_8   (0x00 << 8)
297 #define SYS_CLCD_ID_UNKNOWN_8_4 (0x01 << 8)
298 #define SYS_CLCD_ID_EPSON_2_2   (0x02 << 8)
299 #define SYS_CLCD_ID_SANYO_2_5   (0x07 << 8)
300 #define SYS_CLCD_ID_VGA         (0x1f << 8)
301
302 static struct clcd_panel vga = {
303         .mode           = {
304                 .name           = "VGA",
305                 .refresh        = 60,
306                 .xres           = 640,
307                 .yres           = 480,
308                 .pixclock       = 39721,
309                 .left_margin    = 40,
310                 .right_margin   = 24,
311                 .upper_margin   = 32,
312                 .lower_margin   = 11,
313                 .hsync_len      = 96,
314                 .vsync_len      = 2,
315                 .sync           = 0,
316                 .vmode          = FB_VMODE_NONINTERLACED,
317         },
318         .width          = -1,
319         .height         = -1,
320         .tim2           = TIM2_BCD | TIM2_IPC,
321         .cntl           = CNTL_LCDTFT | CNTL_BGR | CNTL_LCDVCOMP(1),
322         .bpp            = 16,
323 };
324
325 static struct clcd_panel xvga = {
326         .mode           = {
327                 .name           = "XVGA",
328                 .refresh        = 60,
329                 .xres           = 1024,
330                 .yres           = 768,
331                 .pixclock       = 15748,
332                 .left_margin    = 152,
333                 .right_margin   = 48,
334                 .upper_margin   = 23,
335                 .lower_margin   = 3,
336                 .hsync_len      = 104,
337                 .vsync_len      = 4,
338                 .sync           = 0,
339                 .vmode          = FB_VMODE_NONINTERLACED,
340         },
341         .width          = -1,
342         .height         = -1,
343         .tim2           = TIM2_BCD | TIM2_IPC,
344         .cntl           = CNTL_LCDTFT | CNTL_BGR | CNTL_LCDVCOMP(1),
345         .bpp            = 16,
346 };
347
348 static struct clcd_panel sanyo_3_8_in = {
349         .mode           = {
350                 .name           = "Sanyo QVGA",
351                 .refresh        = 116,
352                 .xres           = 320,
353                 .yres           = 240,
354                 .pixclock       = 100000,
355                 .left_margin    = 6,
356                 .right_margin   = 6,
357                 .upper_margin   = 5,
358                 .lower_margin   = 5,
359                 .hsync_len      = 6,
360                 .vsync_len      = 6,
361                 .sync           = 0,
362                 .vmode          = FB_VMODE_NONINTERLACED,
363         },
364         .width          = -1,
365         .height         = -1,
366         .tim2           = TIM2_BCD,
367         .cntl           = CNTL_LCDTFT | CNTL_BGR | CNTL_LCDVCOMP(1),
368         .bpp            = 16,
369 };
370
371 static struct clcd_panel sanyo_2_5_in = {
372         .mode           = {
373                 .name           = "Sanyo QVGA Portrait",
374                 .refresh        = 116,
375                 .xres           = 240,
376                 .yres           = 320,
377                 .pixclock       = 100000,
378                 .left_margin    = 20,
379                 .right_margin   = 10,
380                 .upper_margin   = 2,
381                 .lower_margin   = 2,
382                 .hsync_len      = 10,
383                 .vsync_len      = 2,
384                 .sync           = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
385                 .vmode          = FB_VMODE_NONINTERLACED,
386         },
387         .width          = -1,
388         .height         = -1,
389         .tim2           = TIM2_IVS | TIM2_IHS | TIM2_IPC,
390         .cntl           = CNTL_LCDTFT | CNTL_BGR | CNTL_LCDVCOMP(1),
391         .bpp            = 16,
392 };
393
394 static struct clcd_panel epson_2_2_in = {
395         .mode           = {
396                 .name           = "Epson QCIF",
397                 .refresh        = 390,
398                 .xres           = 176,
399                 .yres           = 220,
400                 .pixclock       = 62500,
401                 .left_margin    = 3,
402                 .right_margin   = 2,
403                 .upper_margin   = 1,
404                 .lower_margin   = 0,
405                 .hsync_len      = 3,
406                 .vsync_len      = 2,
407                 .sync           = 0,
408                 .vmode          = FB_VMODE_NONINTERLACED,
409         },
410         .width          = -1,
411         .height         = -1,
412         .tim2           = TIM2_BCD | TIM2_IPC,
413         .cntl           = CNTL_LCDTFT | CNTL_BGR | CNTL_LCDVCOMP(1),
414         .bpp            = 16,
415 };
416
417 /*
418  * Detect which LCD panel is connected, and return the appropriate
419  * clcd_panel structure.  Note: we do not have any information on
420  * the required timings for the 8.4in panel, so we presently assume
421  * VGA timings.
422  */
423 static struct clcd_panel *realview_clcd_panel(void)
424 {
425         void __iomem *sys_clcd = __io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_CLCD_OFFSET;
426         struct clcd_panel *vga_panel;
427         struct clcd_panel *panel;
428         u32 val;
429
430         if (machine_is_realview_eb())
431                 vga_panel = &vga;
432         else
433                 vga_panel = &xvga;
434
435         val = readl(sys_clcd) & SYS_CLCD_ID_MASK;
436         if (val == SYS_CLCD_ID_SANYO_3_8)
437                 panel = &sanyo_3_8_in;
438         else if (val == SYS_CLCD_ID_SANYO_2_5)
439                 panel = &sanyo_2_5_in;
440         else if (val == SYS_CLCD_ID_EPSON_2_2)
441                 panel = &epson_2_2_in;
442         else if (val == SYS_CLCD_ID_VGA)
443                 panel = vga_panel;
444         else {
445                 printk(KERN_ERR "CLCD: unknown LCD panel ID 0x%08x, using VGA\n",
446                         val);
447                 panel = vga_panel;
448         }
449
450         return panel;
451 }
452
453 /*
454  * Disable all display connectors on the interface module.
455  */
456 static void realview_clcd_disable(struct clcd_fb *fb)
457 {
458         void __iomem *sys_clcd = __io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_CLCD_OFFSET;
459         u32 val;
460
461         val = readl(sys_clcd);
462         val &= ~SYS_CLCD_NLCDIOON | SYS_CLCD_PWR3V5SWITCH;
463         writel(val, sys_clcd);
464 }
465
466 /*
467  * Enable the relevant connector on the interface module.
468  */
469 static void realview_clcd_enable(struct clcd_fb *fb)
470 {
471         void __iomem *sys_clcd = __io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_CLCD_OFFSET;
472         u32 val;
473
474         /*
475          * Enable the PSUs
476          */
477         val = readl(sys_clcd);
478         val |= SYS_CLCD_NLCDIOON | SYS_CLCD_PWR3V5SWITCH;
479         writel(val, sys_clcd);
480 }
481
482 static int realview_clcd_setup(struct clcd_fb *fb)
483 {
484         unsigned long framesize;
485         dma_addr_t dma;
486
487         if (machine_is_realview_eb())
488                 /* VGA, 16bpp */
489                 framesize = 640 * 480 * 2;
490         else
491                 /* XVGA, 16bpp */
492                 framesize = 1024 * 768 * 2;
493
494         fb->panel               = realview_clcd_panel();
495
496         fb->fb.screen_base = dma_alloc_writecombine(&fb->dev->dev, framesize,
497                                                     &dma, GFP_KERNEL);
498         if (!fb->fb.screen_base) {
499                 printk(KERN_ERR "CLCD: unable to map framebuffer\n");
500                 return -ENOMEM;
501         }
502
503         fb->fb.fix.smem_start   = dma;
504         fb->fb.fix.smem_len     = framesize;
505
506         return 0;
507 }
508
509 static int realview_clcd_mmap(struct clcd_fb *fb, struct vm_area_struct *vma)
510 {
511         return dma_mmap_writecombine(&fb->dev->dev, vma,
512                                      fb->fb.screen_base,
513                                      fb->fb.fix.smem_start,
514                                      fb->fb.fix.smem_len);
515 }
516
517 static void realview_clcd_remove(struct clcd_fb *fb)
518 {
519         dma_free_writecombine(&fb->dev->dev, fb->fb.fix.smem_len,
520                               fb->fb.screen_base, fb->fb.fix.smem_start);
521 }
522
523 struct clcd_board clcd_plat_data = {
524         .name           = "RealView",
525         .check          = clcdfb_check,
526         .decode         = clcdfb_decode,
527         .disable        = realview_clcd_disable,
528         .enable         = realview_clcd_enable,
529         .setup          = realview_clcd_setup,
530         .mmap           = realview_clcd_mmap,
531         .remove         = realview_clcd_remove,
532 };
533
534 #ifdef CONFIG_LEDS
535 #define VA_LEDS_BASE (__io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_LED_OFFSET)
536
537 void realview_leds_event(led_event_t ledevt)
538 {
539         unsigned long flags;
540         u32 val;
541
542         local_irq_save(flags);
543         val = readl(VA_LEDS_BASE);
544
545         switch (ledevt) {
546         case led_idle_start:
547                 val = val & ~REALVIEW_SYS_LED0;
548                 break;
549
550         case led_idle_end:
551                 val = val | REALVIEW_SYS_LED0;
552                 break;
553
554         case led_timer:
555                 val = val ^ REALVIEW_SYS_LED1;
556                 break;
557
558         case led_halted:
559                 val = 0;
560                 break;
561
562         default:
563                 break;
564         }
565
566         writel(val, VA_LEDS_BASE);
567         local_irq_restore(flags);
568 }
569 #endif  /* CONFIG_LEDS */
570
571 /*
572  * Where is the timer (VA)?
573  */
574 void __iomem *timer0_va_base;
575 void __iomem *timer1_va_base;
576 void __iomem *timer2_va_base;
577 void __iomem *timer3_va_base;
578
579 /*
580  * How long is the timer interval?
581  */
582 #define TIMER_INTERVAL  (TICKS_PER_uSEC * mSEC_10)
583 #if TIMER_INTERVAL >= 0x100000
584 #define TIMER_RELOAD    (TIMER_INTERVAL >> 8)
585 #define TIMER_DIVISOR   (TIMER_CTRL_DIV256)
586 #define TICKS2USECS(x)  (256 * (x) / TICKS_PER_uSEC)
587 #elif TIMER_INTERVAL >= 0x10000
588 #define TIMER_RELOAD    (TIMER_INTERVAL >> 4)           /* Divide by 16 */
589 #define TIMER_DIVISOR   (TIMER_CTRL_DIV16)
590 #define TICKS2USECS(x)  (16 * (x) / TICKS_PER_uSEC)
591 #else
592 #define TIMER_RELOAD    (TIMER_INTERVAL)
593 #define TIMER_DIVISOR   (TIMER_CTRL_DIV1)
594 #define TICKS2USECS(x)  ((x) / TICKS_PER_uSEC)
595 #endif
596
597 static void timer_set_mode(enum clock_event_mode mode,
598                            struct clock_event_device *clk)
599 {
600         unsigned long ctrl;
601
602         switch(mode) {
603         case CLOCK_EVT_MODE_PERIODIC:
604                 writel(TIMER_RELOAD, timer0_va_base + TIMER_LOAD);
605
606                 ctrl = TIMER_CTRL_PERIODIC;
607                 ctrl |= TIMER_CTRL_32BIT | TIMER_CTRL_IE | TIMER_CTRL_ENABLE;
608                 break;
609         case CLOCK_EVT_MODE_ONESHOT:
610                 /* period set, and timer enabled in 'next_event' hook */
611                 ctrl = TIMER_CTRL_ONESHOT;
612                 ctrl |= TIMER_CTRL_32BIT | TIMER_CTRL_IE;
613                 break;
614         case CLOCK_EVT_MODE_UNUSED:
615         case CLOCK_EVT_MODE_SHUTDOWN:
616         default:
617                 ctrl = 0;
618         }
619
620         writel(ctrl, timer0_va_base + TIMER_CTRL);
621 }
622
623 static int timer_set_next_event(unsigned long evt,
624                                 struct clock_event_device *unused)
625 {
626         unsigned long ctrl = readl(timer0_va_base + TIMER_CTRL);
627
628         writel(evt, timer0_va_base + TIMER_LOAD);
629         writel(ctrl | TIMER_CTRL_ENABLE, timer0_va_base + TIMER_CTRL);
630
631         return 0;
632 }
633
634 static struct clock_event_device timer0_clockevent =     {
635         .name           = "timer0",
636         .shift          = 32,
637         .features       = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
638         .set_mode       = timer_set_mode,
639         .set_next_event = timer_set_next_event,
640         .rating         = 300,
641         .cpumask        = cpu_all_mask,
642 };
643
644 static void __init realview_clockevents_init(unsigned int timer_irq)
645 {
646         timer0_clockevent.irq = timer_irq;
647         timer0_clockevent.mult =
648                 div_sc(1000000, NSEC_PER_SEC, timer0_clockevent.shift);
649         timer0_clockevent.max_delta_ns =
650                 clockevent_delta2ns(0xffffffff, &timer0_clockevent);
651         timer0_clockevent.min_delta_ns =
652                 clockevent_delta2ns(0xf, &timer0_clockevent);
653
654         clockevents_register_device(&timer0_clockevent);
655 }
656
657 /*
658  * IRQ handler for the timer
659  */
660 static irqreturn_t realview_timer_interrupt(int irq, void *dev_id)
661 {
662         struct clock_event_device *evt = &timer0_clockevent;
663
664         /* clear the interrupt */
665         writel(1, timer0_va_base + TIMER_INTCLR);
666
667         evt->event_handler(evt);
668
669         return IRQ_HANDLED;
670 }
671
672 static struct irqaction realview_timer_irq = {
673         .name           = "RealView Timer Tick",
674         .flags          = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
675         .handler        = realview_timer_interrupt,
676 };
677
678 static cycle_t realview_get_cycles(void)
679 {
680         return ~readl(timer3_va_base + TIMER_VALUE);
681 }
682
683 static struct clocksource clocksource_realview = {
684         .name   = "timer3",
685         .rating = 200,
686         .read   = realview_get_cycles,
687         .mask   = CLOCKSOURCE_MASK(32),
688         .shift  = 20,
689         .flags  = CLOCK_SOURCE_IS_CONTINUOUS,
690 };
691
692 static void __init realview_clocksource_init(void)
693 {
694         /* setup timer 0 as free-running clocksource */
695         writel(0, timer3_va_base + TIMER_CTRL);
696         writel(0xffffffff, timer3_va_base + TIMER_LOAD);
697         writel(0xffffffff, timer3_va_base + TIMER_VALUE);
698         writel(TIMER_CTRL_32BIT | TIMER_CTRL_ENABLE | TIMER_CTRL_PERIODIC,
699                 timer3_va_base + TIMER_CTRL);
700
701         clocksource_realview.mult =
702                 clocksource_khz2mult(1000, clocksource_realview.shift);
703         clocksource_register(&clocksource_realview);
704 }
705
706 /*
707  * Set up the clock source and clock events devices
708  */
709 void __init realview_timer_init(unsigned int timer_irq)
710 {
711         u32 val;
712
713 #ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST
714         /*
715          * The dummy clock device has to be registered before the main device
716          * so that the latter will broadcast the clock events
717          */
718         local_timer_setup();
719 #endif
720
721         /* 
722          * set clock frequency: 
723          *      REALVIEW_REFCLK is 32KHz
724          *      REALVIEW_TIMCLK is 1MHz
725          */
726         val = readl(__io_address(REALVIEW_SCTL_BASE));
727         writel((REALVIEW_TIMCLK << REALVIEW_TIMER1_EnSel) |
728                (REALVIEW_TIMCLK << REALVIEW_TIMER2_EnSel) | 
729                (REALVIEW_TIMCLK << REALVIEW_TIMER3_EnSel) |
730                (REALVIEW_TIMCLK << REALVIEW_TIMER4_EnSel) | val,
731                __io_address(REALVIEW_SCTL_BASE));
732
733         /*
734          * Initialise to a known state (all timers off)
735          */
736         writel(0, timer0_va_base + TIMER_CTRL);
737         writel(0, timer1_va_base + TIMER_CTRL);
738         writel(0, timer2_va_base + TIMER_CTRL);
739         writel(0, timer3_va_base + TIMER_CTRL);
740
741         /* 
742          * Make irqs happen for the system timer
743          */
744         setup_irq(timer_irq, &realview_timer_irq);
745
746         realview_clocksource_init();
747         realview_clockevents_init(timer_irq);
748 }