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