diff options
author | Jürgen Schindele <linux@schindele.name> | 2006-06-29 11:01:43 -0400 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2006-06-29 11:25:37 -0400 |
commit | 326764a85b7676388db3ebad6488f312631d7661 (patch) | |
tree | 26c0b1e7ce4fe32fcb6ed26258d8532af3eba30f /arch/arm/mach-pxa/trizeps4.c | |
parent | a144a5633c1e625c3134c2ce8d549a054468fd98 (diff) |
[ARM] 3666/1: TRIZEPS4 [1/5] core
Patch from Jürgen Schindele
This patch adds support for Trizeps4 SoM and ConXS-evalboard
from "Keith und Koep" This DIMM-module is based on PXA270.
Signed-off-by: Jürgen Schindele <linux@schindele.name>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm/mach-pxa/trizeps4.c')
-rw-r--r-- | arch/arm/mach-pxa/trizeps4.c | 471 |
1 files changed, 471 insertions, 0 deletions
diff --git a/arch/arm/mach-pxa/trizeps4.c b/arch/arm/mach-pxa/trizeps4.c new file mode 100644 index 000000000000..4ffff9e95eca --- /dev/null +++ b/arch/arm/mach-pxa/trizeps4.c | |||
@@ -0,0 +1,471 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/mach-pxa/trizeps4.c | ||
3 | * | ||
4 | * Support for the Keith und Koep Trizeps4 Module Platform. | ||
5 | * | ||
6 | * Author: Jürgen Schindele | ||
7 | * Created: 20 02, 2006 | ||
8 | * Copyright: Jürgen Schindele | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License version 2 as | ||
12 | * published by the Free Software Foundation. | ||
13 | */ | ||
14 | |||
15 | #include <linux/init.h> | ||
16 | #include <linux/kernel.h> | ||
17 | #include <linux/platform_device.h> | ||
18 | #include <linux/sysdev.h> | ||
19 | #include <linux/interrupt.h> | ||
20 | #include <linux/sched.h> | ||
21 | #include <linux/bitops.h> | ||
22 | #include <linux/fb.h> | ||
23 | #include <linux/ioport.h> | ||
24 | #include <linux/delay.h> | ||
25 | #include <linux/serial_8250.h> | ||
26 | #include <linux/mtd/mtd.h> | ||
27 | #include <linux/mtd/partitions.h> | ||
28 | |||
29 | #include <asm/types.h> | ||
30 | #include <asm/setup.h> | ||
31 | #include <asm/memory.h> | ||
32 | #include <asm/mach-types.h> | ||
33 | #include <asm/hardware.h> | ||
34 | #include <asm/irq.h> | ||
35 | #include <asm/sizes.h> | ||
36 | |||
37 | #include <asm/mach/arch.h> | ||
38 | #include <asm/mach/map.h> | ||
39 | #include <asm/mach/irq.h> | ||
40 | #include <asm/mach/flash.h> | ||
41 | |||
42 | #include <asm/arch/pxa-regs.h> | ||
43 | #include <asm/arch/trizeps4.h> | ||
44 | #include <asm/arch/audio.h> | ||
45 | #include <asm/arch/pxafb.h> | ||
46 | #include <asm/arch/mmc.h> | ||
47 | #include <asm/arch/irda.h> | ||
48 | #include <asm/arch/ohci.h> | ||
49 | |||
50 | #include "generic.h" | ||
51 | |||
52 | /******************************************************************************************** | ||
53 | * ONBOARD FLASH | ||
54 | ********************************************************************************************/ | ||
55 | static struct mtd_partition trizeps4_partitions[] = { | ||
56 | { | ||
57 | .name = "Bootloader", | ||
58 | .size = 0x00040000, | ||
59 | .offset = 0, | ||
60 | .mask_flags = MTD_WRITEABLE /* force read-only */ | ||
61 | },{ | ||
62 | .name = "Kernel", | ||
63 | .size = 0x00400000, | ||
64 | .offset = 0x00040000 | ||
65 | },{ | ||
66 | .name = "Filesystem", | ||
67 | .size = MTDPART_SIZ_FULL, | ||
68 | .offset = 0x00440000 | ||
69 | } | ||
70 | }; | ||
71 | |||
72 | static struct flash_platform_data trizeps4_flash_data[] = { | ||
73 | { | ||
74 | .map_name = "cfi_probe", | ||
75 | .parts = trizeps4_partitions, | ||
76 | .nr_parts = ARRAY_SIZE(trizeps4_partitions) | ||
77 | } | ||
78 | }; | ||
79 | |||
80 | static struct resource flash_resource = { | ||
81 | .start = PXA_CS0_PHYS, | ||
82 | .end = PXA_CS0_PHYS + SZ_64M - 1, | ||
83 | .flags = IORESOURCE_MEM, | ||
84 | }; | ||
85 | |||
86 | static struct platform_device flash_device = { | ||
87 | .name = "pxa2xx-flash", | ||
88 | .id = 0, | ||
89 | .dev = { | ||
90 | .platform_data = &trizeps4_flash_data, | ||
91 | }, | ||
92 | .resource = &flash_resource, | ||
93 | .num_resources = 1, | ||
94 | }; | ||
95 | |||
96 | /******************************************************************************************** | ||
97 | * DAVICOM DM9000 Ethernet | ||
98 | ********************************************************************************************/ | ||
99 | static struct resource dm9000_resources[] = { | ||
100 | [0] = { | ||
101 | .start = TRIZEPS4_ETH_PHYS+0x300, | ||
102 | .end = TRIZEPS4_ETH_PHYS+0x400-1, | ||
103 | .flags = IORESOURCE_MEM, | ||
104 | }, | ||
105 | [1] = { | ||
106 | .start = TRIZEPS4_ETH_PHYS+0x8300, | ||
107 | .end = TRIZEPS4_ETH_PHYS+0x8400-1, | ||
108 | .flags = IORESOURCE_MEM, | ||
109 | }, | ||
110 | [2] = { | ||
111 | .start = TRIZEPS4_ETH_IRQ, | ||
112 | .end = TRIZEPS4_ETH_IRQ, | ||
113 | .flags = (IORESOURCE_IRQ | IRQT_RISING), | ||
114 | }, | ||
115 | }; | ||
116 | |||
117 | static struct platform_device dm9000_device = { | ||
118 | .name = "dm9000", | ||
119 | .id = -1, | ||
120 | .num_resources = ARRAY_SIZE(dm9000_resources), | ||
121 | .resource = dm9000_resources, | ||
122 | }; | ||
123 | |||
124 | /******************************************************************************************** | ||
125 | * PXA270 serial ports | ||
126 | ********************************************************************************************/ | ||
127 | static struct plat_serial8250_port tri_serial_ports[] = { | ||
128 | #ifdef CONFIG_SERIAL_PXA | ||
129 | /* this uses the own PXA driver */ | ||
130 | { | ||
131 | 0, | ||
132 | }, | ||
133 | #else | ||
134 | /* this uses the generic 8520 driver */ | ||
135 | [0] = { | ||
136 | .membase = (void *)&FFUART, | ||
137 | .irq = IRQ_FFUART, | ||
138 | .flags = UPF_BOOT_AUTOCONF, | ||
139 | .iotype = UPIO_MEM32, | ||
140 | .regshift = 2, | ||
141 | .uartclk = (921600*16), | ||
142 | }, | ||
143 | [1] = { | ||
144 | .membase = (void *)&BTUART, | ||
145 | .irq = IRQ_BTUART, | ||
146 | .flags = UPF_BOOT_AUTOCONF, | ||
147 | .iotype = UPIO_MEM32, | ||
148 | .regshift = 2, | ||
149 | .uartclk = (921600*16), | ||
150 | }, | ||
151 | { | ||
152 | 0, | ||
153 | }, | ||
154 | #endif | ||
155 | }; | ||
156 | |||
157 | static struct platform_device uart_devices = { | ||
158 | .name = "serial8250", | ||
159 | .id = 0, | ||
160 | .dev = { | ||
161 | .platform_data = tri_serial_ports, | ||
162 | }, | ||
163 | .num_resources = 0, | ||
164 | .resource = NULL, | ||
165 | }; | ||
166 | |||
167 | /******************************************************************************************** | ||
168 | * PXA270 ac97 sound codec | ||
169 | ********************************************************************************************/ | ||
170 | static struct platform_device ac97_audio_device = { | ||
171 | .name = "pxa2xx-ac97", | ||
172 | .id = -1, | ||
173 | }; | ||
174 | |||
175 | static struct platform_device * trizeps4_devices[] __initdata = { | ||
176 | &flash_device, | ||
177 | &uart_devices, | ||
178 | &dm9000_device, | ||
179 | &ac97_audio_device, | ||
180 | }; | ||
181 | |||
182 | #ifdef CONFIG_MACH_TRIZEPS4_CONXS | ||
183 | static short trizeps_conxs_bcr; | ||
184 | |||
185 | /* PCCARD power switching supports only 3,3V */ | ||
186 | void board_pcmcia_power(int power) | ||
187 | { | ||
188 | if (power) { | ||
189 | /* switch power on, put in reset and enable buffers */ | ||
190 | trizeps_conxs_bcr |= power; | ||
191 | trizeps_conxs_bcr |= ConXS_BCR_CF_RESET; | ||
192 | trizeps_conxs_bcr &= ~(ConXS_BCR_CF_BUF_EN); | ||
193 | ConXS_BCR = trizeps_conxs_bcr; | ||
194 | /* wait a little */ | ||
195 | udelay(2000); | ||
196 | /* take reset away */ | ||
197 | trizeps_conxs_bcr &= ~(ConXS_BCR_CF_RESET); | ||
198 | ConXS_BCR = trizeps_conxs_bcr; | ||
199 | udelay(2000); | ||
200 | } else { | ||
201 | /* put in reset */ | ||
202 | trizeps_conxs_bcr |= ConXS_BCR_CF_RESET; | ||
203 | ConXS_BCR = trizeps_conxs_bcr; | ||
204 | udelay(1000); | ||
205 | /* switch power off */ | ||
206 | trizeps_conxs_bcr &= ~(0xf); | ||
207 | ConXS_BCR = trizeps_conxs_bcr; | ||
208 | |||
209 | } | ||
210 | pr_debug("%s: o%s 0x%x\n", __FUNCTION__, power ? "n": "ff", trizeps_conxs_bcr); | ||
211 | } | ||
212 | |||
213 | /* backlight power switching for LCD panel */ | ||
214 | static void board_backlight_power(int on) | ||
215 | { | ||
216 | if (on) { | ||
217 | trizeps_conxs_bcr |= ConXS_BCR_L_DISP; | ||
218 | } else { | ||
219 | trizeps_conxs_bcr &= ~ConXS_BCR_L_DISP; | ||
220 | } | ||
221 | pr_debug("%s: o%s 0x%x\n", __FUNCTION__, on ? "n" : "ff", trizeps_conxs_bcr); | ||
222 | ConXS_BCR = trizeps_conxs_bcr; | ||
223 | } | ||
224 | |||
225 | /* Powersupply for MMC/SD cardslot */ | ||
226 | static void board_mci_power(struct device *dev, unsigned int vdd) | ||
227 | { | ||
228 | struct pxamci_platform_data* p_d = dev->platform_data; | ||
229 | |||
230 | if (( 1 << vdd) & p_d->ocr_mask) { | ||
231 | pr_debug("%s: on\n", __FUNCTION__); | ||
232 | /* FIXME fill in values here */ | ||
233 | } else { | ||
234 | pr_debug("%s: off\n", __FUNCTION__); | ||
235 | /* FIXME fill in values here */ | ||
236 | } | ||
237 | } | ||
238 | |||
239 | static short trizeps_conxs_ircr; | ||
240 | |||
241 | /* Switch modes and Power for IRDA receiver */ | ||
242 | static void board_irda_mode(struct device *dev, int mode) | ||
243 | { | ||
244 | unsigned long flags; | ||
245 | |||
246 | local_irq_save(flags); | ||
247 | if (mode & IR_SIRMODE) { | ||
248 | /* Slow mode */ | ||
249 | trizeps_conxs_ircr &= ~ConXS_IRCR_MODE; | ||
250 | } else if (mode & IR_FIRMODE) { | ||
251 | /* Fast mode */ | ||
252 | trizeps_conxs_ircr |= ConXS_IRCR_MODE; | ||
253 | } | ||
254 | if (mode & IR_OFF) { | ||
255 | trizeps_conxs_ircr |= ConXS_IRCR_SD; | ||
256 | } else { | ||
257 | trizeps_conxs_ircr &= ~ConXS_IRCR_SD; | ||
258 | } | ||
259 | /* FIXME write values to register */ | ||
260 | local_irq_restore(flags); | ||
261 | } | ||
262 | |||
263 | #else | ||
264 | /* for other baseboards define dummies */ | ||
265 | void board_pcmcia_power(int power) {;} | ||
266 | #define board_backlight_power NULL | ||
267 | #define board_mci_power NULL | ||
268 | #define board_irda_mode NULL | ||
269 | |||
270 | #endif /* CONFIG_MACH_TRIZEPS4_CONXS */ | ||
271 | EXPORT_SYMBOL(board_pcmcia_power); | ||
272 | |||
273 | static int trizeps4_mci_init(struct device *dev, irqreturn_t (*mci_detect_int)(int, void *, struct pt_regs *), void *data) | ||
274 | { | ||
275 | int err; | ||
276 | /* setup GPIO for PXA27x MMC controller */ | ||
277 | pxa_gpio_mode(GPIO32_MMCCLK_MD); | ||
278 | pxa_gpio_mode(GPIO112_MMCCMD_MD); | ||
279 | pxa_gpio_mode(GPIO92_MMCDAT0_MD); | ||
280 | pxa_gpio_mode(GPIO109_MMCDAT1_MD); | ||
281 | pxa_gpio_mode(GPIO110_MMCDAT2_MD); | ||
282 | pxa_gpio_mode(GPIO111_MMCDAT3_MD); | ||
283 | |||
284 | pxa_gpio_mode(GPIO_MMC_DET | GPIO_IN); | ||
285 | |||
286 | err = request_irq(TRIZEPS4_MMC_IRQ, mci_detect_int, SA_INTERRUPT | SA_TRIGGER_RISING, "MMC card detect", data); | ||
287 | if (err) { | ||
288 | printk(KERN_ERR "trizeps4_mci_init: MMC/SD: can't request MMC card detect IRQ\n"); | ||
289 | return -1; | ||
290 | } | ||
291 | return 0; | ||
292 | } | ||
293 | |||
294 | static void trizeps4_mci_exit(struct device *dev, void *data) | ||
295 | { | ||
296 | free_irq(TRIZEPS4_MMC_IRQ, data); | ||
297 | } | ||
298 | |||
299 | static struct pxamci_platform_data trizeps4_mci_platform_data = { | ||
300 | .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, | ||
301 | .init = trizeps4_mci_init, | ||
302 | .exit = trizeps4_mci_exit, | ||
303 | .setpower = board_mci_power, | ||
304 | }; | ||
305 | |||
306 | static struct pxaficp_platform_data trizeps4_ficp_platform_data = { | ||
307 | .transceiver_cap = IR_SIRMODE | IR_FIRMODE | IR_OFF, | ||
308 | .transceiver_mode = board_irda_mode, | ||
309 | }; | ||
310 | |||
311 | static int trizeps4_ohci_init(struct device *dev) | ||
312 | { | ||
313 | /* setup Port1 GPIO pin. */ | ||
314 | pxa_gpio_mode( 88 | GPIO_ALT_FN_1_IN); /* USBHPWR1 */ | ||
315 | pxa_gpio_mode( 89 | GPIO_ALT_FN_2_OUT); /* USBHPEN1 */ | ||
316 | |||
317 | /* Set the Power Control Polarity Low and Power Sense | ||
318 | Polarity Low to active low. */ | ||
319 | UHCHR = (UHCHR | UHCHR_PCPL | UHCHR_PSPL) & | ||
320 | ~(UHCHR_SSEP1 | UHCHR_SSEP2 | UHCHR_SSEP3 | UHCHR_SSE); | ||
321 | |||
322 | return 0; | ||
323 | } | ||
324 | |||
325 | static void trizeps4_ohci_exit(struct device *dev) | ||
326 | { | ||
327 | ; | ||
328 | } | ||
329 | |||
330 | static struct pxaohci_platform_data trizeps4_ohci_platform_data = { | ||
331 | .port_mode = PMM_PERPORT_MODE, | ||
332 | .init = trizeps4_ohci_init, | ||
333 | .exit = trizeps4_ohci_exit, | ||
334 | }; | ||
335 | |||
336 | static struct map_desc trizeps4_io_desc[] __initdata = { | ||
337 | { /* ConXS CFSR */ | ||
338 | .virtual = TRIZEPS4_CFSR_VIRT, | ||
339 | .pfn = __phys_to_pfn(TRIZEPS4_CFSR_PHYS), | ||
340 | .length = 0x00001000, | ||
341 | .type = MT_DEVICE | ||
342 | }, | ||
343 | { /* ConXS BCR */ | ||
344 | .virtual = TRIZEPS4_BOCR_VIRT, | ||
345 | .pfn = __phys_to_pfn(TRIZEPS4_BOCR_PHYS), | ||
346 | .length = 0x00001000, | ||
347 | .type = MT_DEVICE | ||
348 | }, | ||
349 | { /* ConXS IRCR */ | ||
350 | .virtual = TRIZEPS4_IRCR_VIRT, | ||
351 | .pfn = __phys_to_pfn(TRIZEPS4_IRCR_PHYS), | ||
352 | .length = 0x00001000, | ||
353 | .type = MT_DEVICE | ||
354 | }, | ||
355 | { /* ConXS DCR */ | ||
356 | .virtual = TRIZEPS4_DICR_VIRT, | ||
357 | .pfn = __phys_to_pfn(TRIZEPS4_DICR_PHYS), | ||
358 | .length = 0x00001000, | ||
359 | .type = MT_DEVICE | ||
360 | }, | ||
361 | { /* ConXS UPSR */ | ||
362 | .virtual = TRIZEPS4_UPSR_VIRT, | ||
363 | .pfn = __phys_to_pfn(TRIZEPS4_UPSR_PHYS), | ||
364 | .length = 0x00001000, | ||
365 | .type = MT_DEVICE | ||
366 | } | ||
367 | }; | ||
368 | |||
369 | static struct pxafb_mach_info sharp_lcd __initdata = { | ||
370 | .pixclock = 78000, | ||
371 | .xres = 640, | ||
372 | .yres = 480, | ||
373 | .bpp = 8, | ||
374 | .hsync_len = 4, | ||
375 | .left_margin = 4, | ||
376 | .right_margin = 4, | ||
377 | .vsync_len = 2, | ||
378 | .upper_margin = 0, | ||
379 | .lower_margin = 0, | ||
380 | .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, | ||
381 | .cmap_greyscale = 0, | ||
382 | .cmap_inverse = 0, | ||
383 | .cmap_static = 0, | ||
384 | .lccr0 = LCCR0_Color | LCCR0_Pas | LCCR0_Dual, | ||
385 | .lccr3 = 0x0340ff02, | ||
386 | .pxafb_backlight_power = board_backlight_power, | ||
387 | }; | ||
388 | |||
389 | static void __init trizeps4_fixup(struct machine_desc *desc, struct tag *tags, char **cmdline, struct meminfo *mi) | ||
390 | { | ||
391 | } | ||
392 | |||
393 | static void __init trizeps4_init(void) | ||
394 | { | ||
395 | platform_add_devices(trizeps4_devices, ARRAY_SIZE(trizeps4_devices)); | ||
396 | |||
397 | set_pxa_fb_info(&sharp_lcd); | ||
398 | |||
399 | pxa_set_mci_info(&trizeps4_mci_platform_data); | ||
400 | pxa_set_ficp_info(&trizeps4_ficp_platform_data); | ||
401 | pxa_set_ohci_info(&trizeps4_ohci_platform_data); | ||
402 | } | ||
403 | |||
404 | static void __init trizeps4_map_io(void) | ||
405 | { | ||
406 | pxa_map_io(); | ||
407 | iotable_init(trizeps4_io_desc, ARRAY_SIZE(trizeps4_io_desc)); | ||
408 | |||
409 | /* for DiskOnChip */ | ||
410 | pxa_gpio_mode(GPIO15_nCS_1_MD); | ||
411 | |||
412 | /* for off-module PIC on ConXS board */ | ||
413 | pxa_gpio_mode(GPIO_PIC | GPIO_IN); | ||
414 | |||
415 | /* UCB1400 irq */ | ||
416 | pxa_gpio_mode(GPIO_UCB1400 | GPIO_IN); | ||
417 | |||
418 | /* for DM9000 LAN */ | ||
419 | pxa_gpio_mode(GPIO78_nCS_2_MD); | ||
420 | pxa_gpio_mode(GPIO_DM9000 | GPIO_IN); | ||
421 | |||
422 | /* for PCMCIA device */ | ||
423 | pxa_gpio_mode(GPIO_PCD | GPIO_IN); | ||
424 | pxa_gpio_mode(GPIO_PRDY | GPIO_IN); | ||
425 | |||
426 | /* for I2C adapter */ | ||
427 | pxa_gpio_mode(GPIO117_I2CSCL_MD); | ||
428 | pxa_gpio_mode(GPIO118_I2CSDA_MD); | ||
429 | |||
430 | /* MMC_DET s.o. */ | ||
431 | pxa_gpio_mode(GPIO_MMC_DET | GPIO_IN); | ||
432 | |||
433 | /* whats that for ??? */ | ||
434 | pxa_gpio_mode(GPIO79_nCS_3_MD); | ||
435 | |||
436 | pxa_gpio_mode( GPIO_SYS_BUSY_LED | GPIO_OUT); /* LED1 */ | ||
437 | pxa_gpio_mode( GPIO_HEARTBEAT_LED | GPIO_OUT); /* LED2 */ | ||
438 | |||
439 | #ifdef CONFIG_MACH_TRIZEPS4_CONXS | ||
440 | #ifdef CONFIG_IDE_PXA_CF | ||
441 | /* if boot direct from compact flash dont disable power */ | ||
442 | trizeps_conxs_bcr = 0x0009; | ||
443 | #else | ||
444 | /* this is the reset value */ | ||
445 | trizeps_conxs_bcr = 0x00A0; | ||
446 | #endif | ||
447 | ConXS_BCR = trizeps_conxs_bcr; | ||
448 | #endif | ||
449 | |||
450 | PWER = 0x00000002; | ||
451 | PFER = 0x00000000; | ||
452 | PRER = 0x00000002; | ||
453 | PGSR0 = 0x0158C000; | ||
454 | PGSR1 = 0x00FF0080; | ||
455 | PGSR2 = 0x0001C004; | ||
456 | /* Stop 3.6MHz and drive HIGH to PCMCIA and CS */ | ||
457 | PCFR |= PCFR_OPDE; | ||
458 | } | ||
459 | |||
460 | MACHINE_START(TRIZEPS4, "Keith und Koep Trizeps IV module") | ||
461 | /* MAINTAINER("Jürgen Schindele") */ | ||
462 | .phys_io = 0x40000000, | ||
463 | .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, | ||
464 | .boot_params = TRIZEPS4_SDRAM_BASE + 0x100, | ||
465 | .fixup = trizeps4_fixup, | ||
466 | .init_machine = trizeps4_init, | ||
467 | .map_io = trizeps4_map_io, | ||
468 | .init_irq = pxa_init_irq, | ||
469 | .timer = &pxa_timer, | ||
470 | MACHINE_END | ||
471 | |||