ARM: footbridge: nw_gpio_lock is raw_spin_lock
[pandora-kernel.git] / arch / arm / mach-pxa / cm-x2xx.c
1 /*
2  * linux/arch/arm/mach-pxa/cm-x2xx.c
3  *
4  * Copyright (C) 2008 CompuLab, Ltd.
5  * Mike Rapoport <mike@compulab.co.il>
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 version 2 as
9  * published by the Free Software Foundation.
10  */
11
12 #include <linux/platform_device.h>
13 #include <linux/syscore_ops.h>
14 #include <linux/irq.h>
15 #include <linux/gpio.h>
16
17 #include <linux/dm9000.h>
18 #include <linux/leds.h>
19
20 #include <asm/mach/arch.h>
21 #include <asm/mach-types.h>
22 #include <asm/mach/map.h>
23
24 #include <mach/pxa25x.h>
25 #undef GPIO24_SSP1_SFRM
26 #include <mach/pxa27x.h>
27 #include <mach/audio.h>
28 #include <mach/pxafb.h>
29 #include <mach/smemc.h>
30
31 #include <asm/hardware/it8152.h>
32
33 #include "generic.h"
34 #include "cm-x2xx-pci.h"
35
36 extern void cmx255_init(void);
37 extern void cmx270_init(void);
38
39 /* reserve IRQs for IT8152 */
40 #define CMX2XX_NR_IRQS          (IRQ_BOARD_START + 40)
41
42 /* virtual addresses for statically mapped regions */
43 #define CMX2XX_VIRT_BASE        (void __iomem *)(0xe8000000)
44 #define CMX2XX_IT8152_VIRT      (CMX2XX_VIRT_BASE)
45
46 /* physical address if local-bus attached devices */
47 #define CMX255_DM9000_PHYS_BASE (PXA_CS1_PHYS + (8 << 22))
48 #define CMX270_DM9000_PHYS_BASE (PXA_CS1_PHYS + (6 << 22))
49
50 /* leds */
51 #define CMX255_GPIO_RED         (27)
52 #define CMX255_GPIO_GREEN       (32)
53 #define CMX270_GPIO_RED         (93)
54 #define CMX270_GPIO_GREEN       (94)
55
56 /* GPIO IRQ usage */
57 #define GPIO22_ETHIRQ           (22)
58 #define GPIO10_ETHIRQ           (10)
59 #define CMX255_GPIO_IT8152_IRQ  (0)
60 #define CMX270_GPIO_IT8152_IRQ  (22)
61
62 #define CMX255_ETHIRQ           PXA_GPIO_TO_IRQ(GPIO22_ETHIRQ)
63 #define CMX270_ETHIRQ           PXA_GPIO_TO_IRQ(GPIO10_ETHIRQ)
64
65 #if defined(CONFIG_DM9000) || defined(CONFIG_DM9000_MODULE)
66 static struct resource cmx255_dm9000_resource[] = {
67         [0] = {
68                 .start = CMX255_DM9000_PHYS_BASE,
69                 .end   = CMX255_DM9000_PHYS_BASE + 3,
70                 .flags = IORESOURCE_MEM,
71         },
72         [1] = {
73                 .start = CMX255_DM9000_PHYS_BASE + 4,
74                 .end   = CMX255_DM9000_PHYS_BASE + 4 + 500,
75                 .flags = IORESOURCE_MEM,
76         },
77         [2] = {
78                 .start = CMX255_ETHIRQ,
79                 .end   = CMX255_ETHIRQ,
80                 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
81         }
82 };
83
84 static struct resource cmx270_dm9000_resource[] = {
85         [0] = {
86                 .start = CMX270_DM9000_PHYS_BASE,
87                 .end   = CMX270_DM9000_PHYS_BASE + 3,
88                 .flags = IORESOURCE_MEM,
89         },
90         [1] = {
91                 .start = CMX270_DM9000_PHYS_BASE + 8,
92                 .end   = CMX270_DM9000_PHYS_BASE + 8 + 500,
93                 .flags = IORESOURCE_MEM,
94         },
95         [2] = {
96                 .start = CMX270_ETHIRQ,
97                 .end   = CMX270_ETHIRQ,
98                 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
99         }
100 };
101
102 static struct dm9000_plat_data cmx270_dm9000_platdata = {
103         .flags          = DM9000_PLATF_32BITONLY | DM9000_PLATF_NO_EEPROM,
104 };
105
106 static struct platform_device cmx2xx_dm9000_device = {
107         .name           = "dm9000",
108         .id             = 0,
109         .num_resources  = ARRAY_SIZE(cmx270_dm9000_resource),
110         .dev            = {
111                 .platform_data = &cmx270_dm9000_platdata,
112         }
113 };
114
115 static void __init cmx2xx_init_dm9000(void)
116 {
117         if (cpu_is_pxa25x())
118                 cmx2xx_dm9000_device.resource = cmx255_dm9000_resource;
119         else
120                 cmx2xx_dm9000_device.resource = cmx270_dm9000_resource;
121         platform_device_register(&cmx2xx_dm9000_device);
122 }
123 #else
124 static inline void cmx2xx_init_dm9000(void) {}
125 #endif
126
127 /* UCB1400 touchscreen controller */
128 #if defined(CONFIG_TOUCHSCREEN_UCB1400) || defined(CONFIG_TOUCHSCREEN_UCB1400_MODULE)
129 static struct platform_device cmx2xx_ts_device = {
130         .name           = "ucb1400_core",
131         .id             = -1,
132 };
133
134 static void __init cmx2xx_init_touchscreen(void)
135 {
136         platform_device_register(&cmx2xx_ts_device);
137 }
138 #else
139 static inline void cmx2xx_init_touchscreen(void) {}
140 #endif
141
142 /* CM-X270 LEDs */
143 #if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE)
144 static struct gpio_led cmx2xx_leds[] = {
145         [0] = {
146                 .name = "cm-x2xx:red",
147                 .default_trigger = "nand-disk",
148                 .active_low = 1,
149         },
150         [1] = {
151                 .name = "cm-x2xx:green",
152                 .default_trigger = "heartbeat",
153                 .active_low = 1,
154         },
155 };
156
157 static struct gpio_led_platform_data cmx2xx_gpio_led_pdata = {
158         .num_leds = ARRAY_SIZE(cmx2xx_leds),
159         .leds = cmx2xx_leds,
160 };
161
162 static struct platform_device cmx2xx_led_device = {
163         .name           = "leds-gpio",
164         .id             = -1,
165         .dev            = {
166                 .platform_data = &cmx2xx_gpio_led_pdata,
167         },
168 };
169
170 static void __init cmx2xx_init_leds(void)
171 {
172         if (cpu_is_pxa25x()) {
173                 cmx2xx_leds[0].gpio = CMX255_GPIO_RED;
174                 cmx2xx_leds[1].gpio = CMX255_GPIO_GREEN;
175         } else {
176                 cmx2xx_leds[0].gpio = CMX270_GPIO_RED;
177                 cmx2xx_leds[1].gpio = CMX270_GPIO_GREEN;
178         }
179         platform_device_register(&cmx2xx_led_device);
180 }
181 #else
182 static inline void cmx2xx_init_leds(void) {}
183 #endif
184
185 #if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE)
186 /*
187   Display definitions
188   keep these for backwards compatibility, although symbolic names (as
189   e.g. in lpd270.c) looks better
190 */
191 #define MTYPE_STN320x240        0
192 #define MTYPE_TFT640x480        1
193 #define MTYPE_CRT640x480        2
194 #define MTYPE_CRT800x600        3
195 #define MTYPE_TFT320x240        6
196 #define MTYPE_STN640x480        7
197
198 static struct pxafb_mode_info generic_stn_320x240_mode = {
199         .pixclock       = 76923,
200         .bpp            = 8,
201         .xres           = 320,
202         .yres           = 240,
203         .hsync_len      = 3,
204         .vsync_len      = 2,
205         .left_margin    = 3,
206         .upper_margin   = 0,
207         .right_margin   = 3,
208         .lower_margin   = 0,
209         .sync           = (FB_SYNC_HOR_HIGH_ACT |
210                            FB_SYNC_VERT_HIGH_ACT),
211         .cmap_greyscale = 0,
212 };
213
214 static struct pxafb_mach_info generic_stn_320x240 = {
215         .modes          = &generic_stn_320x240_mode,
216         .num_modes      = 1,
217         .lcd_conn       = LCD_COLOR_STN_8BPP | LCD_PCLK_EDGE_FALL |\
218                           LCD_AC_BIAS_FREQ(0xff),
219         .cmap_inverse   = 0,
220         .cmap_static    = 0,
221 };
222
223 static struct pxafb_mode_info generic_tft_640x480_mode = {
224         .pixclock       = 38461,
225         .bpp            = 8,
226         .xres           = 640,
227         .yres           = 480,
228         .hsync_len      = 60,
229         .vsync_len      = 2,
230         .left_margin    = 70,
231         .upper_margin   = 10,
232         .right_margin   = 70,
233         .lower_margin   = 5,
234         .sync           = 0,
235         .cmap_greyscale = 0,
236 };
237
238 static struct pxafb_mach_info generic_tft_640x480 = {
239         .modes          = &generic_tft_640x480_mode,
240         .num_modes      = 1,
241         .lcd_conn       = LCD_COLOR_TFT_8BPP | LCD_PCLK_EDGE_FALL |\
242                           LCD_AC_BIAS_FREQ(0xff),
243         .cmap_inverse   = 0,
244         .cmap_static    = 0,
245 };
246
247 static struct pxafb_mode_info generic_crt_640x480_mode = {
248         .pixclock       = 38461,
249         .bpp            = 8,
250         .xres           = 640,
251         .yres           = 480,
252         .hsync_len      = 63,
253         .vsync_len      = 2,
254         .left_margin    = 81,
255         .upper_margin   = 33,
256         .right_margin   = 16,
257         .lower_margin   = 10,
258         .sync           = (FB_SYNC_HOR_HIGH_ACT |
259                            FB_SYNC_VERT_HIGH_ACT),
260         .cmap_greyscale = 0,
261 };
262
263 static struct pxafb_mach_info generic_crt_640x480 = {
264         .modes          = &generic_crt_640x480_mode,
265         .num_modes      = 1,
266         .lcd_conn       = LCD_COLOR_TFT_8BPP | LCD_AC_BIAS_FREQ(0xff),
267         .cmap_inverse   = 0,
268         .cmap_static    = 0,
269 };
270
271 static struct pxafb_mode_info generic_crt_800x600_mode = {
272         .pixclock       = 28846,
273         .bpp            = 8,
274         .xres           = 800,
275         .yres           = 600,
276         .hsync_len      = 63,
277         .vsync_len      = 2,
278         .left_margin    = 26,
279         .upper_margin   = 21,
280         .right_margin   = 26,
281         .lower_margin   = 11,
282         .sync           = (FB_SYNC_HOR_HIGH_ACT |
283                            FB_SYNC_VERT_HIGH_ACT),
284         .cmap_greyscale = 0,
285 };
286
287 static struct pxafb_mach_info generic_crt_800x600 = {
288         .modes          = &generic_crt_800x600_mode,
289         .num_modes      = 1,
290         .lcd_conn       = LCD_COLOR_TFT_8BPP | LCD_AC_BIAS_FREQ(0xff),
291         .cmap_inverse   = 0,
292         .cmap_static    = 0,
293 };
294
295 static struct pxafb_mode_info generic_tft_320x240_mode = {
296         .pixclock       = 134615,
297         .bpp            = 16,
298         .xres           = 320,
299         .yres           = 240,
300         .hsync_len      = 63,
301         .vsync_len      = 7,
302         .left_margin    = 75,
303         .upper_margin   = 0,
304         .right_margin   = 15,
305         .lower_margin   = 15,
306         .sync           = 0,
307         .cmap_greyscale = 0,
308 };
309
310 static struct pxafb_mach_info generic_tft_320x240 = {
311         .modes          = &generic_tft_320x240_mode,
312         .num_modes      = 1,
313         .lcd_conn       = LCD_COLOR_TFT_16BPP | LCD_AC_BIAS_FREQ(0xff),
314         .cmap_inverse   = 0,
315         .cmap_static    = 0,
316 };
317
318 static struct pxafb_mode_info generic_stn_640x480_mode = {
319         .pixclock       = 57692,
320         .bpp            = 8,
321         .xres           = 640,
322         .yres           = 480,
323         .hsync_len      = 4,
324         .vsync_len      = 2,
325         .left_margin    = 10,
326         .upper_margin   = 5,
327         .right_margin   = 10,
328         .lower_margin   = 5,
329         .sync           = (FB_SYNC_HOR_HIGH_ACT |
330                            FB_SYNC_VERT_HIGH_ACT),
331         .cmap_greyscale = 0,
332 };
333
334 static struct pxafb_mach_info generic_stn_640x480 = {
335         .modes          = &generic_stn_640x480_mode,
336         .num_modes      = 1,
337         .lcd_conn       = LCD_COLOR_STN_8BPP | LCD_AC_BIAS_FREQ(0xff),
338         .cmap_inverse   = 0,
339         .cmap_static    = 0,
340 };
341
342 static struct pxafb_mach_info *cmx2xx_display = &generic_crt_640x480;
343
344 static int __init cmx2xx_set_display(char *str)
345 {
346         int disp_type = simple_strtol(str, NULL, 0);
347         switch (disp_type) {
348         case MTYPE_STN320x240:
349                 cmx2xx_display = &generic_stn_320x240;
350                 break;
351         case MTYPE_TFT640x480:
352                 cmx2xx_display = &generic_tft_640x480;
353                 break;
354         case MTYPE_CRT640x480:
355                 cmx2xx_display = &generic_crt_640x480;
356                 break;
357         case MTYPE_CRT800x600:
358                 cmx2xx_display = &generic_crt_800x600;
359                 break;
360         case MTYPE_TFT320x240:
361                 cmx2xx_display = &generic_tft_320x240;
362                 break;
363         case MTYPE_STN640x480:
364                 cmx2xx_display = &generic_stn_640x480;
365                 break;
366         default: /* fallback to CRT 640x480 */
367                 cmx2xx_display = &generic_crt_640x480;
368                 break;
369         }
370         return 1;
371 }
372
373 /*
374    This should be done really early to get proper configuration for
375    frame buffer.
376    Indeed, pxafb parameters can be used istead, but CM-X2XX bootloader
377    has limitied line length for kernel command line, and also it will
378    break compatibitlty with proprietary releases already in field.
379 */
380 __setup("monitor=", cmx2xx_set_display);
381
382 static void __init cmx2xx_init_display(void)
383 {
384         pxa_set_fb_info(NULL, cmx2xx_display);
385 }
386 #else
387 static inline void cmx2xx_init_display(void) {}
388 #endif
389
390 #ifdef CONFIG_PM
391 static unsigned long sleep_save_msc[10];
392
393 static int cmx2xx_suspend(void)
394 {
395         cmx2xx_pci_suspend();
396
397         /* save MSC registers */
398         sleep_save_msc[0] = __raw_readl(MSC0);
399         sleep_save_msc[1] = __raw_readl(MSC1);
400         sleep_save_msc[2] = __raw_readl(MSC2);
401
402         /* setup power saving mode registers */
403         PCFR = 0x0;
404         PSLR = 0xff400000;
405         PMCR  = 0x00000005;
406         PWER  = 0x80000000;
407         PFER  = 0x00000000;
408         PRER  = 0x00000000;
409         PGSR0 = 0xC0018800;
410         PGSR1 = 0x004F0002;
411         PGSR2 = 0x6021C000;
412         PGSR3 = 0x00020000;
413
414         return 0;
415 }
416
417 static void cmx2xx_resume(void)
418 {
419         cmx2xx_pci_resume();
420
421         /* restore MSC registers */
422         __raw_writel(sleep_save_msc[0], MSC0);
423         __raw_writel(sleep_save_msc[1], MSC1);
424         __raw_writel(sleep_save_msc[2], MSC2);
425 }
426
427 static struct syscore_ops cmx2xx_pm_syscore_ops = {
428         .resume = cmx2xx_resume,
429         .suspend = cmx2xx_suspend,
430 };
431
432 static int __init cmx2xx_pm_init(void)
433 {
434         register_syscore_ops(&cmx2xx_pm_syscore_ops);
435
436         return 0;
437 }
438 #else
439 static int __init cmx2xx_pm_init(void) { return 0; }
440 #endif
441
442 #if defined(CONFIG_SND_PXA2XX_AC97) || defined(CONFIG_SND_PXA2XX_AC97_MODULE)
443 static void __init cmx2xx_init_ac97(void)
444 {
445         pxa_set_ac97_info(NULL);
446 }
447 #else
448 static inline void cmx2xx_init_ac97(void) {}
449 #endif
450
451 static void __init cmx2xx_init(void)
452 {
453         pxa_set_ffuart_info(NULL);
454         pxa_set_btuart_info(NULL);
455         pxa_set_stuart_info(NULL);
456
457         cmx2xx_pm_init();
458
459         if (cpu_is_pxa25x())
460                 cmx255_init();
461         else
462                 cmx270_init();
463
464         cmx2xx_init_dm9000();
465         cmx2xx_init_display();
466         cmx2xx_init_ac97();
467         cmx2xx_init_touchscreen();
468         cmx2xx_init_leds();
469 }
470
471 static void __init cmx2xx_init_irq(void)
472 {
473         if (cpu_is_pxa25x()) {
474                 pxa25x_init_irq();
475                 cmx2xx_pci_init_irq(CMX255_GPIO_IT8152_IRQ);
476         } else {
477                 pxa27x_init_irq();
478                 cmx2xx_pci_init_irq(CMX270_GPIO_IT8152_IRQ);
479         }
480 }
481
482 #ifdef CONFIG_PCI
483 /* Map PCI companion statically */
484 static struct map_desc cmx2xx_io_desc[] __initdata = {
485         [0] = { /* PCI bridge */
486                 .virtual        = (unsigned long)CMX2XX_IT8152_VIRT,
487                 .pfn            = __phys_to_pfn(PXA_CS4_PHYS),
488                 .length         = SZ_64M,
489                 .type           = MT_DEVICE
490         },
491 };
492
493 static void __init cmx2xx_map_io(void)
494 {
495         if (cpu_is_pxa25x())
496                 pxa25x_map_io();
497
498         if (cpu_is_pxa27x())
499                 pxa27x_map_io();
500
501         iotable_init(cmx2xx_io_desc, ARRAY_SIZE(cmx2xx_io_desc));
502
503         it8152_base_address = CMX2XX_IT8152_VIRT;
504 }
505 #else
506 static void __init cmx2xx_map_io(void)
507 {
508         if (cpu_is_pxa25x())
509                 pxa25x_map_io();
510
511         if (cpu_is_pxa27x())
512                 pxa27x_map_io();
513 }
514 #endif
515
516 MACHINE_START(ARMCORE, "Compulab CM-X2XX")
517         .atag_offset    = 0x100,
518         .map_io         = cmx2xx_map_io,
519         .nr_irqs        = CMX2XX_NR_IRQS,
520         .init_irq       = cmx2xx_init_irq,
521         /* NOTE: pxa25x_handle_irq() works on PXA27x w/o camera support */
522         .handle_irq     = pxa25x_handle_irq,
523         .timer          = &pxa_timer,
524         .init_machine   = cmx2xx_init,
525 #ifdef CONFIG_PCI
526         .dma_zone_size  = SZ_64M,
527 #endif
528         .restart        = pxa_restart,
529 MACHINE_END