Merge branch 'pl022' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux...
[sfrench/cifs-2.6.git] / arch / arm / mach-integrator / integrator_cp.c
1 /*
2  *  linux/arch/arm/mach-integrator/integrator_cp.c
3  *
4  *  Copyright (C) 2003 Deep Blue Solutions Ltd
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License.
9  */
10 #include <linux/types.h>
11 #include <linux/kernel.h>
12 #include <linux/init.h>
13 #include <linux/list.h>
14 #include <linux/platform_device.h>
15 #include <linux/dma-mapping.h>
16 #include <linux/string.h>
17 #include <linux/device.h>
18 #include <linux/amba/bus.h>
19 #include <linux/amba/kmi.h>
20 #include <linux/amba/clcd.h>
21 #include <linux/amba/mmci.h>
22 #include <linux/io.h>
23 #include <linux/gfp.h>
24 #include <linux/clkdev.h>
25 #include <linux/mtd/physmap.h>
26
27 #include <mach/hardware.h>
28 #include <mach/platform.h>
29 #include <asm/setup.h>
30 #include <asm/mach-types.h>
31 #include <asm/hardware/arm_timer.h>
32 #include <asm/hardware/icst.h>
33
34 #include <mach/cm.h>
35 #include <mach/lm.h>
36 #include <mach/irqs.h>
37
38 #include <asm/mach/arch.h>
39 #include <asm/mach/irq.h>
40 #include <asm/mach/map.h>
41 #include <asm/mach/time.h>
42
43 #include <asm/hardware/timer-sp.h>
44
45 #include <plat/clcd.h>
46 #include <plat/fpga-irq.h>
47 #include <plat/sched_clock.h>
48
49 #include "common.h"
50
51 #define INTCP_PA_FLASH_BASE             0x24000000
52 #define INTCP_FLASH_SIZE                SZ_32M
53
54 #define INTCP_PA_CLCD_BASE              0xc0000000
55
56 #define INTCP_VA_CIC_BASE               __io_address(INTEGRATOR_HDR_BASE + 0x40)
57 #define INTCP_VA_PIC_BASE               __io_address(INTEGRATOR_IC_BASE)
58 #define INTCP_VA_SIC_BASE               __io_address(INTEGRATOR_CP_SIC_BASE)
59
60 #define INTCP_ETH_SIZE                  0x10
61
62 #define INTCP_VA_CTRL_BASE              IO_ADDRESS(INTEGRATOR_CP_CTL_BASE)
63 #define INTCP_FLASHPROG                 0x04
64 #define CINTEGRATOR_FLASHPROG_FLVPPEN   (1 << 0)
65 #define CINTEGRATOR_FLASHPROG_FLWREN    (1 << 1)
66
67 /*
68  * Logical      Physical
69  * f1000000     10000000        Core module registers
70  * f1100000     11000000        System controller registers
71  * f1200000     12000000        EBI registers
72  * f1300000     13000000        Counter/Timer
73  * f1400000     14000000        Interrupt controller
74  * f1600000     16000000        UART 0
75  * f1700000     17000000        UART 1
76  * f1a00000     1a000000        Debug LEDs
77  * fc900000     c9000000        GPIO
78  * fca00000     ca000000        SIC
79  * fcb00000     cb000000        CP system control
80  */
81
82 static struct map_desc intcp_io_desc[] __initdata = {
83         {
84                 .virtual        = IO_ADDRESS(INTEGRATOR_HDR_BASE),
85                 .pfn            = __phys_to_pfn(INTEGRATOR_HDR_BASE),
86                 .length         = SZ_4K,
87                 .type           = MT_DEVICE
88         }, {
89                 .virtual        = IO_ADDRESS(INTEGRATOR_SC_BASE),
90                 .pfn            = __phys_to_pfn(INTEGRATOR_SC_BASE),
91                 .length         = SZ_4K,
92                 .type           = MT_DEVICE
93         }, {
94                 .virtual        = IO_ADDRESS(INTEGRATOR_EBI_BASE),
95                 .pfn            = __phys_to_pfn(INTEGRATOR_EBI_BASE),
96                 .length         = SZ_4K,
97                 .type           = MT_DEVICE
98         }, {
99                 .virtual        = IO_ADDRESS(INTEGRATOR_CT_BASE),
100                 .pfn            = __phys_to_pfn(INTEGRATOR_CT_BASE),
101                 .length         = SZ_4K,
102                 .type           = MT_DEVICE
103         }, {
104                 .virtual        = IO_ADDRESS(INTEGRATOR_IC_BASE),
105                 .pfn            = __phys_to_pfn(INTEGRATOR_IC_BASE),
106                 .length         = SZ_4K,
107                 .type           = MT_DEVICE
108         }, {
109                 .virtual        = IO_ADDRESS(INTEGRATOR_UART0_BASE),
110                 .pfn            = __phys_to_pfn(INTEGRATOR_UART0_BASE),
111                 .length         = SZ_4K,
112                 .type           = MT_DEVICE
113         }, {
114                 .virtual        = IO_ADDRESS(INTEGRATOR_UART1_BASE),
115                 .pfn            = __phys_to_pfn(INTEGRATOR_UART1_BASE),
116                 .length         = SZ_4K,
117                 .type           = MT_DEVICE
118         }, {
119                 .virtual        = IO_ADDRESS(INTEGRATOR_DBG_BASE),
120                 .pfn            = __phys_to_pfn(INTEGRATOR_DBG_BASE),
121                 .length         = SZ_4K,
122                 .type           = MT_DEVICE
123         }, {
124                 .virtual        = IO_ADDRESS(INTEGRATOR_CP_GPIO_BASE),
125                 .pfn            = __phys_to_pfn(INTEGRATOR_CP_GPIO_BASE),
126                 .length         = SZ_4K,
127                 .type           = MT_DEVICE
128         }, {
129                 .virtual        = IO_ADDRESS(INTEGRATOR_CP_SIC_BASE),
130                 .pfn            = __phys_to_pfn(INTEGRATOR_CP_SIC_BASE),
131                 .length         = SZ_4K,
132                 .type           = MT_DEVICE
133         }, {
134                 .virtual        = IO_ADDRESS(INTEGRATOR_CP_CTL_BASE),
135                 .pfn            = __phys_to_pfn(INTEGRATOR_CP_CTL_BASE),
136                 .length         = SZ_4K,
137                 .type           = MT_DEVICE
138         }
139 };
140
141 static void __init intcp_map_io(void)
142 {
143         iotable_init(intcp_io_desc, ARRAY_SIZE(intcp_io_desc));
144 }
145
146 static void __init intcp_init_irq(void)
147 {
148         u32 pic_mask, cic_mask, sic_mask;
149
150         /* These masks are for the HW IRQ registers */
151         pic_mask = ~((~0u) << (11 - IRQ_PIC_START));
152         pic_mask |= (~((~0u) << (29 - 22))) << 22;
153         cic_mask = ~((~0u) << (1 + IRQ_CIC_END - IRQ_CIC_START));
154         sic_mask = ~((~0u) << (1 + IRQ_SIC_END - IRQ_SIC_START));
155
156         /*
157          * Disable all interrupt sources
158          */
159         writel(0xffffffff, INTCP_VA_PIC_BASE + IRQ_ENABLE_CLEAR);
160         writel(0xffffffff, INTCP_VA_PIC_BASE + FIQ_ENABLE_CLEAR);
161         writel(0xffffffff, INTCP_VA_CIC_BASE + IRQ_ENABLE_CLEAR);
162         writel(0xffffffff, INTCP_VA_CIC_BASE + FIQ_ENABLE_CLEAR);
163         writel(sic_mask, INTCP_VA_SIC_BASE + IRQ_ENABLE_CLEAR);
164         writel(sic_mask, INTCP_VA_SIC_BASE + FIQ_ENABLE_CLEAR);
165
166         fpga_irq_init(INTCP_VA_PIC_BASE, "PIC", IRQ_PIC_START,
167                       -1, pic_mask, NULL);
168
169         fpga_irq_init(INTCP_VA_CIC_BASE, "CIC", IRQ_CIC_START,
170                       -1, cic_mask, NULL);
171
172         fpga_irq_init(INTCP_VA_SIC_BASE, "SIC", IRQ_SIC_START,
173                       IRQ_CP_CPPLDINT, sic_mask, NULL);
174 }
175
176 /*
177  * Clock handling
178  */
179 #define CM_LOCK         (__io_address(INTEGRATOR_HDR_BASE)+INTEGRATOR_HDR_LOCK_OFFSET)
180 #define CM_AUXOSC       (__io_address(INTEGRATOR_HDR_BASE)+0x1c)
181
182 static const struct icst_params cp_auxvco_params = {
183         .ref            = 24000000,
184         .vco_max        = ICST525_VCO_MAX_5V,
185         .vco_min        = ICST525_VCO_MIN,
186         .vd_min         = 8,
187         .vd_max         = 263,
188         .rd_min         = 3,
189         .rd_max         = 65,
190         .s2div          = icst525_s2div,
191         .idx2s          = icst525_idx2s,
192 };
193
194 static void cp_auxvco_set(struct clk *clk, struct icst_vco vco)
195 {
196         u32 val;
197
198         val = readl(clk->vcoreg) & ~0x7ffff;
199         val |= vco.v | (vco.r << 9) | (vco.s << 16);
200
201         writel(0xa05f, CM_LOCK);
202         writel(val, clk->vcoreg);
203         writel(0, CM_LOCK);
204 }
205
206 static const struct clk_ops cp_auxclk_ops = {
207         .round  = icst_clk_round,
208         .set    = icst_clk_set,
209         .setvco = cp_auxvco_set,
210 };
211
212 static struct clk cp_auxclk = {
213         .ops    = &cp_auxclk_ops,
214         .params = &cp_auxvco_params,
215         .vcoreg = CM_AUXOSC,
216 };
217
218 static struct clk sp804_clk = {
219         .rate   = 1000000,
220 };
221
222 static struct clk_lookup cp_lookups[] = {
223         {       /* CLCD */
224                 .dev_id         = "mb:c0",
225                 .clk            = &cp_auxclk,
226         }, {    /* SP804 timers */
227                 .dev_id         = "sp804",
228                 .clk            = &sp804_clk,
229         },
230 };
231
232 /*
233  * Flash handling.
234  */
235 static int intcp_flash_init(struct platform_device *dev)
236 {
237         u32 val;
238
239         val = readl(INTCP_VA_CTRL_BASE + INTCP_FLASHPROG);
240         val |= CINTEGRATOR_FLASHPROG_FLWREN;
241         writel(val, INTCP_VA_CTRL_BASE + INTCP_FLASHPROG);
242
243         return 0;
244 }
245
246 static void intcp_flash_exit(struct platform_device *dev)
247 {
248         u32 val;
249
250         val = readl(INTCP_VA_CTRL_BASE + INTCP_FLASHPROG);
251         val &= ~(CINTEGRATOR_FLASHPROG_FLVPPEN|CINTEGRATOR_FLASHPROG_FLWREN);
252         writel(val, INTCP_VA_CTRL_BASE + INTCP_FLASHPROG);
253 }
254
255 static void intcp_flash_set_vpp(struct platform_device *pdev, int on)
256 {
257         u32 val;
258
259         val = readl(INTCP_VA_CTRL_BASE + INTCP_FLASHPROG);
260         if (on)
261                 val |= CINTEGRATOR_FLASHPROG_FLVPPEN;
262         else
263                 val &= ~CINTEGRATOR_FLASHPROG_FLVPPEN;
264         writel(val, INTCP_VA_CTRL_BASE + INTCP_FLASHPROG);
265 }
266
267 static struct physmap_flash_data intcp_flash_data = {
268         .width          = 4,
269         .init           = intcp_flash_init,
270         .exit           = intcp_flash_exit,
271         .set_vpp        = intcp_flash_set_vpp,
272 };
273
274 static struct resource intcp_flash_resource = {
275         .start          = INTCP_PA_FLASH_BASE,
276         .end            = INTCP_PA_FLASH_BASE + INTCP_FLASH_SIZE - 1,
277         .flags          = IORESOURCE_MEM,
278 };
279
280 static struct platform_device intcp_flash_device = {
281         .name           = "physmap-flash",
282         .id             = 0,
283         .dev            = {
284                 .platform_data  = &intcp_flash_data,
285         },
286         .num_resources  = 1,
287         .resource       = &intcp_flash_resource,
288 };
289
290 static struct resource smc91x_resources[] = {
291         [0] = {
292                 .start  = INTEGRATOR_CP_ETH_BASE,
293                 .end    = INTEGRATOR_CP_ETH_BASE + INTCP_ETH_SIZE - 1,
294                 .flags  = IORESOURCE_MEM,
295         },
296         [1] = {
297                 .start  = IRQ_CP_ETHINT,
298                 .end    = IRQ_CP_ETHINT,
299                 .flags  = IORESOURCE_IRQ,
300         },
301 };
302
303 static struct platform_device smc91x_device = {
304         .name           = "smc91x",
305         .id             = 0,
306         .num_resources  = ARRAY_SIZE(smc91x_resources),
307         .resource       = smc91x_resources,
308 };
309
310 static struct platform_device *intcp_devs[] __initdata = {
311         &intcp_flash_device,
312         &smc91x_device,
313 };
314
315 /*
316  * It seems that the card insertion interrupt remains active after
317  * we've acknowledged it.  We therefore ignore the interrupt, and
318  * rely on reading it from the SIC.  This also means that we must
319  * clear the latched interrupt.
320  */
321 static unsigned int mmc_status(struct device *dev)
322 {
323         unsigned int status = readl(IO_ADDRESS(0xca000000 + 4));
324         writel(8, IO_ADDRESS(INTEGRATOR_CP_CTL_BASE + 8));
325
326         return status & 8;
327 }
328
329 static struct mmci_platform_data mmc_data = {
330         .ocr_mask       = MMC_VDD_32_33|MMC_VDD_33_34,
331         .status         = mmc_status,
332         .gpio_wp        = -1,
333         .gpio_cd        = -1,
334 };
335
336 #define INTEGRATOR_CP_MMC_IRQS  { IRQ_CP_MMCIINT0, IRQ_CP_MMCIINT1 }
337 #define INTEGRATOR_CP_AACI_IRQS { IRQ_CP_AACIINT }
338
339 static AMBA_APB_DEVICE(mmc, "mb:1c", 0, INTEGRATOR_CP_MMC_BASE,
340         INTEGRATOR_CP_MMC_IRQS, &mmc_data);
341
342 static AMBA_APB_DEVICE(aaci, "mb:1d", 0, INTEGRATOR_CP_AACI_BASE,
343         INTEGRATOR_CP_AACI_IRQS, NULL);
344
345
346 /*
347  * CLCD support
348  */
349 /*
350  * Ensure VGA is selected.
351  */
352 static void cp_clcd_enable(struct clcd_fb *fb)
353 {
354         struct fb_var_screeninfo *var = &fb->fb.var;
355         u32 val = CM_CTRL_STATIC1 | CM_CTRL_STATIC2;
356
357         if (var->bits_per_pixel <= 8 ||
358             (var->bits_per_pixel == 16 && var->green.length == 5))
359                 /* Pseudocolor, RGB555, BGR555 */
360                 val |= CM_CTRL_LCDMUXSEL_VGA555_TFT555;
361         else if (fb->fb.var.bits_per_pixel <= 16)
362                 /* truecolor RGB565 */
363                 val |= CM_CTRL_LCDMUXSEL_VGA565_TFT555;
364         else
365                 val = 0; /* no idea for this, don't trust the docs */
366
367         cm_control(CM_CTRL_LCDMUXSEL_MASK|
368                    CM_CTRL_LCDEN0|
369                    CM_CTRL_LCDEN1|
370                    CM_CTRL_STATIC1|
371                    CM_CTRL_STATIC2|
372                    CM_CTRL_STATIC|
373                    CM_CTRL_n24BITEN, val);
374 }
375
376 static int cp_clcd_setup(struct clcd_fb *fb)
377 {
378         fb->panel = versatile_clcd_get_panel("VGA");
379         if (!fb->panel)
380                 return -EINVAL;
381
382         return versatile_clcd_setup_dma(fb, SZ_1M);
383 }
384
385 static struct clcd_board clcd_data = {
386         .name           = "Integrator/CP",
387         .caps           = CLCD_CAP_5551 | CLCD_CAP_RGB565 | CLCD_CAP_888,
388         .check          = clcdfb_check,
389         .decode         = clcdfb_decode,
390         .enable         = cp_clcd_enable,
391         .setup          = cp_clcd_setup,
392         .mmap           = versatile_clcd_mmap_dma,
393         .remove         = versatile_clcd_remove_dma,
394 };
395
396 static AMBA_AHB_DEVICE(clcd, "mb:c0", 0, INTCP_PA_CLCD_BASE,
397         { IRQ_CP_CLCDCINT }, &clcd_data);
398
399 static struct amba_device *amba_devs[] __initdata = {
400         &mmc_device,
401         &aaci_device,
402         &clcd_device,
403 };
404
405 #define REFCOUNTER (__io_address(INTEGRATOR_HDR_BASE) + 0x28)
406
407 static void __init intcp_init_early(void)
408 {
409         clkdev_add_table(cp_lookups, ARRAY_SIZE(cp_lookups));
410
411         integrator_init_early();
412
413 #ifdef CONFIG_PLAT_VERSATILE_SCHED_CLOCK
414         versatile_sched_clock_init(REFCOUNTER, 24000000);
415 #endif
416 }
417
418 static void __init intcp_init(void)
419 {
420         int i;
421
422         platform_add_devices(intcp_devs, ARRAY_SIZE(intcp_devs));
423
424         for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
425                 struct amba_device *d = amba_devs[i];
426                 amba_device_register(d, &iomem_resource);
427         }
428 }
429
430 #define TIMER0_VA_BASE __io_address(INTEGRATOR_TIMER0_BASE)
431 #define TIMER1_VA_BASE __io_address(INTEGRATOR_TIMER1_BASE)
432 #define TIMER2_VA_BASE __io_address(INTEGRATOR_TIMER2_BASE)
433
434 static void __init intcp_timer_init(void)
435 {
436         writel(0, TIMER0_VA_BASE + TIMER_CTRL);
437         writel(0, TIMER1_VA_BASE + TIMER_CTRL);
438         writel(0, TIMER2_VA_BASE + TIMER_CTRL);
439
440         sp804_clocksource_init(TIMER2_VA_BASE, "timer2");
441         sp804_clockevents_init(TIMER1_VA_BASE, IRQ_TIMERINT1, "timer1");
442 }
443
444 static struct sys_timer cp_timer = {
445         .init           = intcp_timer_init,
446 };
447
448 MACHINE_START(CINTEGRATOR, "ARM-IntegratorCP")
449         /* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */
450         .atag_offset    = 0x100,
451         .reserve        = integrator_reserve,
452         .map_io         = intcp_map_io,
453         .nr_irqs        = NR_IRQS_INTEGRATOR_CP,
454         .init_early     = intcp_init_early,
455         .init_irq       = intcp_init_irq,
456         .handle_irq     = fpga_handle_irq,
457         .timer          = &cp_timer,
458         .init_machine   = intcp_init,
459         .restart        = integrator_restart,
460 MACHINE_END