Commit | Line | Data |
---|---|---|
3696a8a4 | 1 | /* |
da591937 | 2 | * linux/arch/arm/mach-pxa/cm-x2xx.c |
3696a8a4 | 3 | * |
2f01a973 | 4 | * Copyright (C) 2007, 2008 CompuLab, Ltd. |
3696a8a4 MR |
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 | ||
3696a8a4 | 12 | #include <linux/platform_device.h> |
3696a8a4 | 13 | #include <linux/sysdev.h> |
2f01a973 MR |
14 | #include <linux/irq.h> |
15 | #include <linux/gpio.h> | |
3696a8a4 MR |
16 | |
17 | #include <linux/dm9000.h> | |
18 | #include <linux/rtc-v3020.h> | |
3696a8a4 | 19 | #include <video/mbxfb.h> |
2f01a973 | 20 | #include <linux/leds.h> |
3696a8a4 MR |
21 | |
22 | #include <asm/mach/arch.h> | |
23 | #include <asm/mach-types.h> | |
24 | #include <asm/mach/map.h> | |
25 | ||
a09e64fb RK |
26 | #include <mach/pxa2xx-regs.h> |
27 | #include <mach/mfp-pxa27x.h> | |
28 | #include <mach/pxa-regs.h> | |
29 | #include <mach/audio.h> | |
30 | #include <mach/pxafb.h> | |
31 | #include <mach/ohci.h> | |
32 | #include <mach/mmc.h> | |
33 | #include <mach/bitfield.h> | |
3696a8a4 MR |
34 | |
35 | #include <asm/hardware/it8152.h> | |
36 | ||
37 | #include "generic.h" | |
7d76e3f1 | 38 | #include "cm-x2xx-pci.h" |
3696a8a4 | 39 | |
2f01a973 | 40 | /* virtual addresses for statically mapped regions */ |
da591937 MR |
41 | #define CMX2XX_VIRT_BASE (0xe8000000) |
42 | #define CMX2XX_IT8152_VIRT (CMX2XX_VIRT_BASE) | |
2f01a973 | 43 | |
3696a8a4 | 44 | #define RTC_PHYS_BASE (PXA_CS1_PHYS + (5 << 22)) |
da591937 MR |
45 | #define CMX270_DM9000_PHYS_BASE (PXA_CS1_PHYS + (6 << 22)) |
46 | ||
47 | /* leds */ | |
48 | #define CMX270_GPIO_RED (93) | |
49 | #define CMX270_GPIO_GREEN (94) | |
3696a8a4 | 50 | |
2f01a973 MR |
51 | /* GPIO IRQ usage */ |
52 | #define GPIO10_ETHIRQ (10) | |
da591937 | 53 | #define CMX270_GPIO_IT8152_IRQ (22) |
2f01a973 MR |
54 | #define GPIO83_MMC_IRQ (83) |
55 | #define GPIO95_GFXIRQ (95) | |
56 | ||
57 | #define CMX270_ETHIRQ IRQ_GPIO(GPIO10_ETHIRQ) | |
2f01a973 MR |
58 | #define CMX270_MMC_IRQ IRQ_GPIO(GPIO83_MMC_IRQ) |
59 | #define CMX270_GFXIRQ IRQ_GPIO(GPIO95_GFXIRQ) | |
60 | ||
61 | /* MMC power enable */ | |
62 | #define GPIO105_MMC_POWER (105) | |
63 | ||
64 | static unsigned long cmx270_pin_config[] = { | |
65 | /* AC'97 */ | |
66 | GPIO28_AC97_BITCLK, | |
67 | GPIO29_AC97_SDATA_IN_0, | |
68 | GPIO30_AC97_SDATA_OUT, | |
69 | GPIO31_AC97_SYNC, | |
70 | GPIO98_AC97_SYSCLK, | |
71 | GPIO113_AC97_nRESET, | |
72 | ||
73 | /* BTUART */ | |
74 | GPIO42_BTUART_RXD, | |
75 | GPIO43_BTUART_TXD, | |
76 | GPIO44_BTUART_CTS, | |
77 | GPIO45_BTUART_RTS, | |
78 | ||
79 | /* STUART */ | |
80 | GPIO46_STUART_RXD, | |
81 | GPIO47_STUART_TXD, | |
82 | ||
83 | /* MCI controller */ | |
84 | GPIO32_MMC_CLK, | |
85 | GPIO112_MMC_CMD, | |
86 | GPIO92_MMC_DAT_0, | |
87 | GPIO109_MMC_DAT_1, | |
88 | GPIO110_MMC_DAT_2, | |
89 | GPIO111_MMC_DAT_3, | |
90 | ||
91 | /* LCD */ | |
92 | GPIO58_LCD_LDD_0, | |
93 | GPIO59_LCD_LDD_1, | |
94 | GPIO60_LCD_LDD_2, | |
95 | GPIO61_LCD_LDD_3, | |
96 | GPIO62_LCD_LDD_4, | |
97 | GPIO63_LCD_LDD_5, | |
98 | GPIO64_LCD_LDD_6, | |
99 | GPIO65_LCD_LDD_7, | |
100 | GPIO66_LCD_LDD_8, | |
101 | GPIO67_LCD_LDD_9, | |
102 | GPIO68_LCD_LDD_10, | |
103 | GPIO69_LCD_LDD_11, | |
104 | GPIO70_LCD_LDD_12, | |
105 | GPIO71_LCD_LDD_13, | |
106 | GPIO72_LCD_LDD_14, | |
107 | GPIO73_LCD_LDD_15, | |
108 | GPIO74_LCD_FCLK, | |
109 | GPIO75_LCD_LCLK, | |
110 | GPIO76_LCD_PCLK, | |
111 | GPIO77_LCD_BIAS, | |
112 | ||
113 | /* I2C */ | |
114 | GPIO117_I2C_SCL, | |
115 | GPIO118_I2C_SDA, | |
116 | ||
117 | /* SSP1 */ | |
118 | GPIO23_SSP1_SCLK, | |
119 | GPIO24_SSP1_SFRM, | |
120 | GPIO25_SSP1_TXD, | |
121 | GPIO26_SSP1_RXD, | |
122 | ||
123 | /* SSP2 */ | |
124 | GPIO19_SSP2_SCLK, | |
125 | GPIO14_SSP2_SFRM, | |
126 | GPIO87_SSP2_TXD, | |
127 | GPIO88_SSP2_RXD, | |
128 | ||
129 | /* PC Card */ | |
130 | GPIO48_nPOE, | |
131 | GPIO49_nPWE, | |
132 | GPIO50_nPIOR, | |
133 | GPIO51_nPIOW, | |
134 | GPIO85_nPCE_1, | |
135 | GPIO54_nPCE_2, | |
136 | GPIO55_nPREG, | |
137 | GPIO56_nPWAIT, | |
138 | GPIO57_nIOIS16, | |
139 | ||
140 | /* SDRAM and local bus */ | |
141 | GPIO15_nCS_1, | |
142 | GPIO78_nCS_2, | |
143 | GPIO79_nCS_3, | |
144 | GPIO80_nCS_4, | |
145 | GPIO33_nCS_5, | |
146 | GPIO49_nPWE, | |
147 | GPIO18_RDY, | |
148 | ||
149 | /* GPIO */ | |
150 | GPIO0_GPIO | WAKEUP_ON_EDGE_BOTH, | |
151 | GPIO105_GPIO | MFP_LPM_DRIVE_HIGH, /* MMC/SD power */ | |
152 | GPIO53_GPIO, /* PC card reset */ | |
153 | ||
154 | /* NAND controls */ | |
155 | GPIO11_GPIO | MFP_LPM_DRIVE_HIGH, /* NAND CE# */ | |
156 | GPIO89_GPIO, /* NAND Ready/Busy */ | |
157 | ||
158 | /* interrupts */ | |
159 | GPIO10_GPIO, /* DM9000 interrupt */ | |
160 | GPIO83_GPIO, /* MMC card detect */ | |
161 | }; | |
162 | ||
163 | #if defined(CONFIG_DM9000) || defined(CONFIG_DM9000_MODULE) | |
164 | static struct resource cmx270_dm9000_resource[] = { | |
3696a8a4 | 165 | [0] = { |
da591937 MR |
166 | .start = CMX270_DM9000_PHYS_BASE, |
167 | .end = CMX270_DM9000_PHYS_BASE + 3, | |
3696a8a4 MR |
168 | .flags = IORESOURCE_MEM, |
169 | }, | |
170 | [1] = { | |
da591937 MR |
171 | .start = CMX270_DM9000_PHYS_BASE + 8, |
172 | .end = CMX270_DM9000_PHYS_BASE + 8 + 500, | |
3696a8a4 MR |
173 | .flags = IORESOURCE_MEM, |
174 | }, | |
175 | [2] = { | |
176 | .start = CMX270_ETHIRQ, | |
177 | .end = CMX270_ETHIRQ, | |
2f01a973 | 178 | .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE, |
3696a8a4 MR |
179 | } |
180 | }; | |
181 | ||
2f01a973 | 182 | static struct dm9000_plat_data cmx270_dm9000_platdata = { |
3696a8a4 MR |
183 | .flags = DM9000_PLATF_32BITONLY, |
184 | }; | |
185 | ||
da591937 | 186 | static struct platform_device cmx2xx_dm9000_device = { |
3696a8a4 MR |
187 | .name = "dm9000", |
188 | .id = 0, | |
2f01a973 | 189 | .num_resources = ARRAY_SIZE(cmx270_dm9000_resource), |
3696a8a4 | 190 | .dev = { |
2f01a973 | 191 | .platform_data = &cmx270_dm9000_platdata, |
3696a8a4 MR |
192 | } |
193 | }; | |
194 | ||
da591937 | 195 | static void __init cmx2xx_init_dm9000(void) |
2f01a973 | 196 | { |
da591937 MR |
197 | cmx2xx_dm9000_device.resource = cmx270_dm9000_resource, |
198 | platform_device_register(&cmx2xx_dm9000_device); | |
2f01a973 MR |
199 | } |
200 | #else | |
da591937 | 201 | static inline void cmx2xx_init_dm9000(void) {} |
2f01a973 MR |
202 | #endif |
203 | ||
204 | /* UCB1400 touchscreen controller */ | |
205 | #if defined(CONFIG_TOUCHSCREEN_UCB1400) || defined(CONFIG_TOUCHSCREEN_UCB1400_MODULE) | |
da591937 | 206 | static struct platform_device cmx2xx_ts_device = { |
3696a8a4 MR |
207 | .name = "ucb1400_ts", |
208 | .id = -1, | |
209 | }; | |
210 | ||
da591937 | 211 | static void __init cmx2xx_init_touchscreen(void) |
2f01a973 | 212 | { |
da591937 | 213 | platform_device_register(&cmx2xx_ts_device); |
2f01a973 MR |
214 | } |
215 | #else | |
da591937 | 216 | static inline void cmx2xx_init_touchscreen(void) {} |
2f01a973 MR |
217 | #endif |
218 | ||
219 | /* V3020 RTC */ | |
220 | #if defined(CONFIG_RTC_DRV_V3020) || defined(CONFIG_RTC_DRV_V3020_MODULE) | |
3696a8a4 MR |
221 | static struct resource cmx270_v3020_resource[] = { |
222 | [0] = { | |
223 | .start = RTC_PHYS_BASE, | |
224 | .end = RTC_PHYS_BASE + 4, | |
225 | .flags = IORESOURCE_MEM, | |
226 | }, | |
227 | }; | |
228 | ||
229 | struct v3020_platform_data cmx270_v3020_pdata = { | |
230 | .leftshift = 16, | |
231 | }; | |
232 | ||
233 | static struct platform_device cmx270_rtc_device = { | |
234 | .name = "v3020", | |
235 | .num_resources = ARRAY_SIZE(cmx270_v3020_resource), | |
236 | .resource = cmx270_v3020_resource, | |
237 | .id = -1, | |
238 | .dev = { | |
239 | .platform_data = &cmx270_v3020_pdata, | |
240 | } | |
241 | }; | |
242 | ||
2f01a973 MR |
243 | static void __init cmx270_init_rtc(void) |
244 | { | |
245 | platform_device_register(&cmx270_rtc_device); | |
246 | } | |
247 | #else | |
da591937 | 248 | static inline void cmx2xx_init_rtc(void) {} |
2f01a973 MR |
249 | #endif |
250 | ||
251 | /* CM-X270 LEDs */ | |
252 | #if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE) | |
da591937 | 253 | static struct gpio_led cmx2xx_leds[] = { |
2f01a973 | 254 | [0] = { |
da591937 | 255 | .name = "cm-x2xx:red", |
2f01a973 | 256 | .default_trigger = "nand-disk", |
2f01a973 MR |
257 | .active_low = 1, |
258 | }, | |
259 | [1] = { | |
da591937 | 260 | .name = "cm-x2xx:green", |
2f01a973 | 261 | .default_trigger = "heartbeat", |
2f01a973 MR |
262 | .active_low = 1, |
263 | }, | |
264 | }; | |
265 | ||
da591937 MR |
266 | static struct gpio_led_platform_data cmx2xx_gpio_led_pdata = { |
267 | .num_leds = ARRAY_SIZE(cmx2xx_leds), | |
268 | .leds = cmx2xx_leds, | |
2f01a973 MR |
269 | }; |
270 | ||
da591937 | 271 | static struct platform_device cmx2xx_led_device = { |
2f01a973 | 272 | .name = "leds-gpio", |
3696a8a4 | 273 | .id = -1, |
2f01a973 | 274 | .dev = { |
da591937 | 275 | .platform_data = &cmx2xx_gpio_led_pdata, |
2f01a973 | 276 | }, |
3696a8a4 MR |
277 | }; |
278 | ||
da591937 | 279 | static void __init cmx2xx_init_leds(void) |
2f01a973 | 280 | { |
da591937 MR |
281 | cmx2xx_leds[0].gpio = CMX270_GPIO_RED; |
282 | cmx2xx_leds[1].gpio = CMX270_GPIO_GREEN; | |
283 | platform_device_register(&cmx2xx_led_device); | |
2f01a973 MR |
284 | } |
285 | #else | |
da591937 | 286 | static inline void cmx2xx_init_leds(void) {} |
2f01a973 MR |
287 | #endif |
288 | ||
3696a8a4 | 289 | /* 2700G graphics */ |
2f01a973 | 290 | #if defined(CONFIG_FB_MBX) || defined(CONFIG_FB_MBX_MODULE) |
3696a8a4 MR |
291 | static u64 fb_dma_mask = ~(u64)0; |
292 | ||
293 | static struct resource cmx270_2700G_resource[] = { | |
294 | /* frame buffer memory including ODFB and External SDRAM */ | |
295 | [0] = { | |
2f01a973 MR |
296 | .start = PXA_CS2_PHYS, |
297 | .end = PXA_CS2_PHYS + 0x01ffffff, | |
3696a8a4 MR |
298 | .flags = IORESOURCE_MEM, |
299 | }, | |
300 | /* Marathon registers */ | |
301 | [1] = { | |
2f01a973 MR |
302 | .start = PXA_CS2_PHYS + 0x03fe0000, |
303 | .end = PXA_CS2_PHYS + 0x03ffffff, | |
3696a8a4 MR |
304 | .flags = IORESOURCE_MEM, |
305 | }, | |
306 | }; | |
307 | ||
308 | static unsigned long save_lcd_regs[10]; | |
309 | ||
310 | static int cmx270_marathon_probe(struct fb_info *fb) | |
311 | { | |
312 | /* save PXA-270 pin settings before enabling 2700G */ | |
313 | save_lcd_regs[0] = GPDR1; | |
314 | save_lcd_regs[1] = GPDR2; | |
315 | save_lcd_regs[2] = GAFR1_U; | |
316 | save_lcd_regs[3] = GAFR2_L; | |
317 | save_lcd_regs[4] = GAFR2_U; | |
318 | ||
319 | /* Disable PXA-270 on-chip controller driving pins */ | |
320 | GPDR1 &= ~(0xfc000000); | |
321 | GPDR2 &= ~(0x00c03fff); | |
322 | GAFR1_U &= ~(0xfff00000); | |
323 | GAFR2_L &= ~(0x0fffffff); | |
324 | GAFR2_U &= ~(0x0000f000); | |
325 | return 0; | |
326 | } | |
327 | ||
328 | static int cmx270_marathon_remove(struct fb_info *fb) | |
329 | { | |
330 | GPDR1 = save_lcd_regs[0]; | |
331 | GPDR2 = save_lcd_regs[1]; | |
332 | GAFR1_U = save_lcd_regs[2]; | |
333 | GAFR2_L = save_lcd_regs[3]; | |
334 | GAFR2_U = save_lcd_regs[4]; | |
335 | return 0; | |
336 | } | |
337 | ||
338 | static struct mbxfb_platform_data cmx270_2700G_data = { | |
339 | .xres = { | |
340 | .min = 240, | |
341 | .max = 1200, | |
342 | .defval = 640, | |
343 | }, | |
344 | .yres = { | |
345 | .min = 240, | |
346 | .max = 1200, | |
347 | .defval = 480, | |
348 | }, | |
349 | .bpp = { | |
350 | .min = 16, | |
351 | .max = 32, | |
352 | .defval = 16, | |
353 | }, | |
354 | .memsize = 8*1024*1024, | |
355 | .probe = cmx270_marathon_probe, | |
356 | .remove = cmx270_marathon_remove, | |
357 | }; | |
358 | ||
359 | static struct platform_device cmx270_2700G = { | |
360 | .name = "mbx-fb", | |
361 | .dev = { | |
362 | .platform_data = &cmx270_2700G_data, | |
363 | .dma_mask = &fb_dma_mask, | |
364 | .coherent_dma_mask = 0xffffffff, | |
365 | }, | |
366 | .num_resources = ARRAY_SIZE(cmx270_2700G_resource), | |
367 | .resource = cmx270_2700G_resource, | |
368 | .id = -1, | |
369 | }; | |
370 | ||
2f01a973 MR |
371 | static void __init cmx270_init_2700G(void) |
372 | { | |
373 | platform_device_register(&cmx270_2700G); | |
374 | } | |
375 | #else | |
376 | static inline void cmx270_init_2700G(void) {} | |
377 | #endif | |
3696a8a4 | 378 | |
2f01a973 | 379 | #if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE) |
3696a8a4 MR |
380 | /* |
381 | Display definitions | |
382 | keep these for backwards compatibility, although symbolic names (as | |
383 | e.g. in lpd270.c) looks better | |
384 | */ | |
385 | #define MTYPE_STN320x240 0 | |
386 | #define MTYPE_TFT640x480 1 | |
387 | #define MTYPE_CRT640x480 2 | |
388 | #define MTYPE_CRT800x600 3 | |
389 | #define MTYPE_TFT320x240 6 | |
390 | #define MTYPE_STN640x480 7 | |
391 | ||
392 | static struct pxafb_mode_info generic_stn_320x240_mode = { | |
393 | .pixclock = 76923, | |
394 | .bpp = 8, | |
395 | .xres = 320, | |
396 | .yres = 240, | |
397 | .hsync_len = 3, | |
398 | .vsync_len = 2, | |
399 | .left_margin = 3, | |
400 | .upper_margin = 0, | |
401 | .right_margin = 3, | |
402 | .lower_margin = 0, | |
403 | .sync = (FB_SYNC_HOR_HIGH_ACT | | |
404 | FB_SYNC_VERT_HIGH_ACT), | |
405 | .cmap_greyscale = 0, | |
406 | }; | |
407 | ||
408 | static struct pxafb_mach_info generic_stn_320x240 = { | |
409 | .modes = &generic_stn_320x240_mode, | |
410 | .num_modes = 1, | |
411 | .lccr0 = 0, | |
412 | .lccr3 = (LCCR3_PixClkDiv(0x03) | | |
413 | LCCR3_Acb(0xff) | | |
414 | LCCR3_PCP), | |
415 | .cmap_inverse = 0, | |
416 | .cmap_static = 0, | |
417 | }; | |
418 | ||
419 | static struct pxafb_mode_info generic_tft_640x480_mode = { | |
420 | .pixclock = 38461, | |
421 | .bpp = 8, | |
422 | .xres = 640, | |
423 | .yres = 480, | |
424 | .hsync_len = 60, | |
425 | .vsync_len = 2, | |
426 | .left_margin = 70, | |
427 | .upper_margin = 10, | |
428 | .right_margin = 70, | |
429 | .lower_margin = 5, | |
430 | .sync = 0, | |
431 | .cmap_greyscale = 0, | |
432 | }; | |
433 | ||
434 | static struct pxafb_mach_info generic_tft_640x480 = { | |
435 | .modes = &generic_tft_640x480_mode, | |
436 | .num_modes = 1, | |
437 | .lccr0 = (LCCR0_PAS), | |
438 | .lccr3 = (LCCR3_PixClkDiv(0x01) | | |
439 | LCCR3_Acb(0xff) | | |
440 | LCCR3_PCP), | |
441 | .cmap_inverse = 0, | |
442 | .cmap_static = 0, | |
443 | }; | |
444 | ||
445 | static struct pxafb_mode_info generic_crt_640x480_mode = { | |
446 | .pixclock = 38461, | |
447 | .bpp = 8, | |
448 | .xres = 640, | |
449 | .yres = 480, | |
450 | .hsync_len = 63, | |
451 | .vsync_len = 2, | |
452 | .left_margin = 81, | |
453 | .upper_margin = 33, | |
454 | .right_margin = 16, | |
455 | .lower_margin = 10, | |
456 | .sync = (FB_SYNC_HOR_HIGH_ACT | | |
457 | FB_SYNC_VERT_HIGH_ACT), | |
458 | .cmap_greyscale = 0, | |
459 | }; | |
460 | ||
461 | static struct pxafb_mach_info generic_crt_640x480 = { | |
462 | .modes = &generic_crt_640x480_mode, | |
463 | .num_modes = 1, | |
464 | .lccr0 = (LCCR0_PAS), | |
465 | .lccr3 = (LCCR3_PixClkDiv(0x01) | | |
466 | LCCR3_Acb(0xff)), | |
467 | .cmap_inverse = 0, | |
468 | .cmap_static = 0, | |
469 | }; | |
470 | ||
471 | static struct pxafb_mode_info generic_crt_800x600_mode = { | |
472 | .pixclock = 28846, | |
473 | .bpp = 8, | |
474 | .xres = 800, | |
475 | .yres = 600, | |
476 | .hsync_len = 63, | |
477 | .vsync_len = 2, | |
478 | .left_margin = 26, | |
479 | .upper_margin = 21, | |
480 | .right_margin = 26, | |
481 | .lower_margin = 11, | |
482 | .sync = (FB_SYNC_HOR_HIGH_ACT | | |
483 | FB_SYNC_VERT_HIGH_ACT), | |
484 | .cmap_greyscale = 0, | |
485 | }; | |
486 | ||
487 | static struct pxafb_mach_info generic_crt_800x600 = { | |
488 | .modes = &generic_crt_800x600_mode, | |
489 | .num_modes = 1, | |
490 | .lccr0 = (LCCR0_PAS), | |
491 | .lccr3 = (LCCR3_PixClkDiv(0x02) | | |
492 | LCCR3_Acb(0xff)), | |
493 | .cmap_inverse = 0, | |
494 | .cmap_static = 0, | |
495 | }; | |
496 | ||
497 | static struct pxafb_mode_info generic_tft_320x240_mode = { | |
498 | .pixclock = 134615, | |
499 | .bpp = 16, | |
500 | .xres = 320, | |
501 | .yres = 240, | |
502 | .hsync_len = 63, | |
503 | .vsync_len = 7, | |
504 | .left_margin = 75, | |
505 | .upper_margin = 0, | |
506 | .right_margin = 15, | |
507 | .lower_margin = 15, | |
508 | .sync = 0, | |
509 | .cmap_greyscale = 0, | |
510 | }; | |
511 | ||
512 | static struct pxafb_mach_info generic_tft_320x240 = { | |
513 | .modes = &generic_tft_320x240_mode, | |
514 | .num_modes = 1, | |
515 | .lccr0 = (LCCR0_PAS), | |
516 | .lccr3 = (LCCR3_PixClkDiv(0x06) | | |
517 | LCCR3_Acb(0xff) | | |
518 | LCCR3_PCP), | |
519 | .cmap_inverse = 0, | |
520 | .cmap_static = 0, | |
521 | }; | |
522 | ||
523 | static struct pxafb_mode_info generic_stn_640x480_mode = { | |
524 | .pixclock = 57692, | |
525 | .bpp = 8, | |
526 | .xres = 640, | |
527 | .yres = 480, | |
528 | .hsync_len = 4, | |
529 | .vsync_len = 2, | |
530 | .left_margin = 10, | |
531 | .upper_margin = 5, | |
532 | .right_margin = 10, | |
533 | .lower_margin = 5, | |
534 | .sync = (FB_SYNC_HOR_HIGH_ACT | | |
535 | FB_SYNC_VERT_HIGH_ACT), | |
536 | .cmap_greyscale = 0, | |
537 | }; | |
538 | ||
539 | static struct pxafb_mach_info generic_stn_640x480 = { | |
540 | .modes = &generic_stn_640x480_mode, | |
541 | .num_modes = 1, | |
542 | .lccr0 = 0, | |
543 | .lccr3 = (LCCR3_PixClkDiv(0x02) | | |
544 | LCCR3_Acb(0xff)), | |
545 | .cmap_inverse = 0, | |
546 | .cmap_static = 0, | |
547 | }; | |
548 | ||
da591937 | 549 | static struct pxafb_mach_info *cmx2xx_display = &generic_crt_640x480; |
3696a8a4 | 550 | |
da591937 | 551 | static int __init cmx2xx_set_display(char *str) |
3696a8a4 MR |
552 | { |
553 | int disp_type = simple_strtol(str, NULL, 0); | |
554 | switch (disp_type) { | |
555 | case MTYPE_STN320x240: | |
da591937 | 556 | cmx2xx_display = &generic_stn_320x240; |
3696a8a4 MR |
557 | break; |
558 | case MTYPE_TFT640x480: | |
da591937 | 559 | cmx2xx_display = &generic_tft_640x480; |
3696a8a4 MR |
560 | break; |
561 | case MTYPE_CRT640x480: | |
da591937 | 562 | cmx2xx_display = &generic_crt_640x480; |
3696a8a4 MR |
563 | break; |
564 | case MTYPE_CRT800x600: | |
da591937 | 565 | cmx2xx_display = &generic_crt_800x600; |
3696a8a4 MR |
566 | break; |
567 | case MTYPE_TFT320x240: | |
da591937 | 568 | cmx2xx_display = &generic_tft_320x240; |
3696a8a4 MR |
569 | break; |
570 | case MTYPE_STN640x480: | |
da591937 | 571 | cmx2xx_display = &generic_stn_640x480; |
3696a8a4 MR |
572 | break; |
573 | default: /* fallback to CRT 640x480 */ | |
da591937 | 574 | cmx2xx_display = &generic_crt_640x480; |
3696a8a4 MR |
575 | break; |
576 | } | |
577 | return 1; | |
578 | } | |
579 | ||
580 | /* | |
581 | This should be done really early to get proper configuration for | |
582 | frame buffer. | |
da591937 | 583 | Indeed, pxafb parameters can be used istead, but CM-X2XX bootloader |
3696a8a4 MR |
584 | has limitied line length for kernel command line, and also it will |
585 | break compatibitlty with proprietary releases already in field. | |
586 | */ | |
da591937 | 587 | __setup("monitor=", cmx2xx_set_display); |
3696a8a4 | 588 | |
da591937 | 589 | static void __init cmx2xx_init_display(void) |
2f01a973 | 590 | { |
da591937 | 591 | set_pxa_fb_info(cmx2xx_display); |
2f01a973 MR |
592 | } |
593 | #else | |
da591937 | 594 | static inline void cmx2xx_init_display(void) {} |
2f01a973 MR |
595 | #endif |
596 | ||
3696a8a4 | 597 | /* PXA27x OHCI controller setup */ |
2f01a973 | 598 | #if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) |
3696a8a4 MR |
599 | static int cmx270_ohci_init(struct device *dev) |
600 | { | |
601 | /* Set the Power Control Polarity Low */ | |
602 | UHCHR = (UHCHR | UHCHR_PCPL) & | |
603 | ~(UHCHR_SSEP1 | UHCHR_SSEP2 | UHCHR_SSE); | |
604 | ||
605 | return 0; | |
606 | } | |
607 | ||
608 | static struct pxaohci_platform_data cmx270_ohci_platform_data = { | |
609 | .port_mode = PMM_PERPORT_MODE, | |
610 | .init = cmx270_ohci_init, | |
611 | }; | |
612 | ||
2f01a973 MR |
613 | static void __init cmx270_init_ohci(void) |
614 | { | |
615 | pxa_set_ohci_info(&cmx270_ohci_platform_data); | |
616 | } | |
617 | #else | |
618 | static inline void cmx270_init_ohci(void) {} | |
619 | #endif | |
3696a8a4 | 620 | |
2f01a973 | 621 | #if defined(CONFIG_MMC) || defined(CONFIG_MMC_MODULE) |
3696a8a4 MR |
622 | static int cmx270_mci_init(struct device *dev, |
623 | irq_handler_t cmx270_detect_int, | |
624 | void *data) | |
625 | { | |
626 | int err; | |
627 | ||
2f01a973 MR |
628 | err = gpio_request(GPIO105_MMC_POWER, "MMC/SD power"); |
629 | if (err) { | |
630 | dev_warn(dev, "power gpio unavailable\n"); | |
631 | return err; | |
632 | } | |
3696a8a4 | 633 | |
2f01a973 | 634 | gpio_direction_output(GPIO105_MMC_POWER, 0); |
3696a8a4 MR |
635 | |
636 | err = request_irq(CMX270_MMC_IRQ, cmx270_detect_int, | |
637 | IRQF_DISABLED | IRQF_TRIGGER_FALLING, | |
638 | "MMC card detect", data); | |
2f01a973 MR |
639 | if (err) { |
640 | gpio_free(GPIO105_MMC_POWER); | |
641 | dev_err(dev, "cmx270_mci_init: MMC/SD: can't" | |
642 | " request MMC card detect IRQ\n"); | |
643 | } | |
3696a8a4 | 644 | |
2687bd38 | 645 | return err; |
3696a8a4 MR |
646 | } |
647 | ||
648 | static void cmx270_mci_setpower(struct device *dev, unsigned int vdd) | |
649 | { | |
650 | struct pxamci_platform_data *p_d = dev->platform_data; | |
651 | ||
652 | if ((1 << vdd) & p_d->ocr_mask) { | |
2f01a973 MR |
653 | dev_dbg(dev, "power on\n"); |
654 | gpio_set_value(GPIO105_MMC_POWER, 0); | |
3696a8a4 | 655 | } else { |
2f01a973 MR |
656 | gpio_set_value(GPIO105_MMC_POWER, 1); |
657 | dev_dbg(dev, "power off\n"); | |
3696a8a4 MR |
658 | } |
659 | } | |
660 | ||
661 | static void cmx270_mci_exit(struct device *dev, void *data) | |
662 | { | |
663 | free_irq(CMX270_MMC_IRQ, data); | |
2f01a973 | 664 | gpio_free(GPIO105_MMC_POWER); |
3696a8a4 MR |
665 | } |
666 | ||
667 | static struct pxamci_platform_data cmx270_mci_platform_data = { | |
668 | .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, | |
669 | .init = cmx270_mci_init, | |
670 | .setpower = cmx270_mci_setpower, | |
671 | .exit = cmx270_mci_exit, | |
672 | }; | |
673 | ||
2f01a973 MR |
674 | static void __init cmx270_init_mmc(void) |
675 | { | |
676 | pxa_set_mci_info(&cmx270_mci_platform_data); | |
677 | } | |
678 | #else | |
679 | static inline void cmx270_init_mmc(void) {} | |
680 | #endif | |
681 | ||
3696a8a4 MR |
682 | #ifdef CONFIG_PM |
683 | static unsigned long sleep_save_msc[10]; | |
684 | ||
da591937 | 685 | static int cmx2xx_suspend(struct sys_device *dev, pm_message_t state) |
3696a8a4 | 686 | { |
da591937 | 687 | cmx2xx_pci_suspend(); |
3696a8a4 MR |
688 | |
689 | /* save MSC registers */ | |
690 | sleep_save_msc[0] = MSC0; | |
691 | sleep_save_msc[1] = MSC1; | |
692 | sleep_save_msc[2] = MSC2; | |
693 | ||
694 | /* setup power saving mode registers */ | |
695 | PCFR = 0x0; | |
696 | PSLR = 0xff400000; | |
697 | PMCR = 0x00000005; | |
698 | PWER = 0x80000000; | |
699 | PFER = 0x00000000; | |
700 | PRER = 0x00000000; | |
701 | PGSR0 = 0xC0018800; | |
702 | PGSR1 = 0x004F0002; | |
703 | PGSR2 = 0x6021C000; | |
704 | PGSR3 = 0x00020000; | |
705 | ||
706 | return 0; | |
707 | } | |
708 | ||
da591937 | 709 | static int cmx2xx_resume(struct sys_device *dev) |
3696a8a4 | 710 | { |
da591937 | 711 | cmx2xx_pci_resume(); |
3696a8a4 MR |
712 | |
713 | /* restore MSC registers */ | |
714 | MSC0 = sleep_save_msc[0]; | |
715 | MSC1 = sleep_save_msc[1]; | |
716 | MSC2 = sleep_save_msc[2]; | |
717 | ||
718 | return 0; | |
719 | } | |
720 | ||
da591937 | 721 | static struct sysdev_class cmx2xx_pm_sysclass = { |
af5ca3f4 | 722 | .name = "pm", |
da591937 MR |
723 | .resume = cmx2xx_resume, |
724 | .suspend = cmx2xx_suspend, | |
3696a8a4 MR |
725 | }; |
726 | ||
da591937 MR |
727 | static struct sys_device cmx2xx_pm_device = { |
728 | .cls = &cmx2xx_pm_sysclass, | |
3696a8a4 MR |
729 | }; |
730 | ||
da591937 | 731 | static int __init cmx2xx_pm_init(void) |
3696a8a4 MR |
732 | { |
733 | int error; | |
da591937 | 734 | error = sysdev_class_register(&cmx2xx_pm_sysclass); |
3696a8a4 | 735 | if (error == 0) |
da591937 | 736 | error = sysdev_register(&cmx2xx_pm_device); |
3696a8a4 MR |
737 | return error; |
738 | } | |
739 | #else | |
da591937 | 740 | static int __init cmx2xx_pm_init(void) { return 0; } |
3696a8a4 MR |
741 | #endif |
742 | ||
2f01a973 | 743 | #if defined(CONFIG_SND_PXA2XX_AC97) || defined(CONFIG_SND_PXA2XX_AC97_MODULE) |
da591937 | 744 | static void __init cmx2xx_init_ac97(void) |
3696a8a4 | 745 | { |
9f19d638 | 746 | pxa_set_ac97_info(NULL); |
2f01a973 MR |
747 | } |
748 | #else | |
da591937 | 749 | static inline void cmx2xx_init_ac97(void) {} |
2f01a973 | 750 | #endif |
3696a8a4 | 751 | |
2f01a973 MR |
752 | static void __init cmx270_init(void) |
753 | { | |
2f01a973 MR |
754 | pxa2xx_mfp_config(ARRAY_AND_SIZE(cmx270_pin_config)); |
755 | ||
2f01a973 | 756 | cmx270_init_rtc(); |
2f01a973 MR |
757 | cmx270_init_mmc(); |
758 | cmx270_init_ohci(); | |
2f01a973 | 759 | cmx270_init_2700G(); |
3696a8a4 MR |
760 | } |
761 | ||
da591937 MR |
762 | static void __init cmx2xx_init(void) |
763 | { | |
764 | cmx2xx_pm_init(); | |
765 | ||
766 | cmx270_init(); | |
767 | ||
768 | cmx2xx_init_dm9000(); | |
769 | cmx2xx_init_display(); | |
770 | cmx2xx_init_ac97(); | |
771 | cmx2xx_init_touchscreen(); | |
772 | cmx2xx_init_leds(); | |
773 | } | |
774 | ||
775 | static void __init cmx2xx_init_irq(void) | |
3696a8a4 MR |
776 | { |
777 | pxa27x_init_irq(); | |
778 | ||
da591937 | 779 | cmx2xx_pci_init_irq(CMX270_GPIO_IT8152_IRQ); |
2f01a973 | 780 | } |
3696a8a4 | 781 | |
2f01a973 MR |
782 | #ifdef CONFIG_PCI |
783 | /* Map PCI companion statically */ | |
da591937 | 784 | static struct map_desc cmx2xx_io_desc[] __initdata = { |
2f01a973 | 785 | [0] = { /* PCI bridge */ |
da591937 | 786 | .virtual = CMX2XX_IT8152_VIRT, |
2f01a973 MR |
787 | .pfn = __phys_to_pfn(PXA_CS4_PHYS), |
788 | .length = SZ_64M, | |
789 | .type = MT_DEVICE | |
790 | }, | |
791 | }; | |
3696a8a4 | 792 | |
da591937 | 793 | static void __init cmx2xx_map_io(void) |
2f01a973 MR |
794 | { |
795 | pxa_map_io(); | |
da591937 | 796 | iotable_init(cmx2xx_io_desc, ARRAY_SIZE(cmx2xx_io_desc)); |
3696a8a4 | 797 | |
da591937 | 798 | it8152_base_address = CMX2XX_IT8152_VIRT; |
3696a8a4 | 799 | } |
2f01a973 | 800 | #else |
da591937 | 801 | static void __init cmx2xx_map_io(void) |
3696a8a4 MR |
802 | { |
803 | pxa_map_io(); | |
3696a8a4 | 804 | } |
2f01a973 | 805 | #endif |
3696a8a4 | 806 | |
da591937 | 807 | MACHINE_START(ARMCORE, "Compulab CM-X2XX") |
3696a8a4 MR |
808 | .boot_params = 0xa0000100, |
809 | .phys_io = 0x40000000, | |
810 | .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, | |
da591937 MR |
811 | .map_io = cmx2xx_map_io, |
812 | .init_irq = cmx2xx_init_irq, | |
3696a8a4 | 813 | .timer = &pxa_timer, |
da591937 | 814 | .init_machine = cmx2xx_init, |
3696a8a4 | 815 | MACHINE_END |