diff options
author | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
commit | 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch) | |
tree | 0bba044c4ce775e45a88a51686b5d9f90697ea9d /arch/arm/mach-pxa/mainstone.c |
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history,
even though we have it. We can create a separate "historical" git
archive of that later if we want to, and in the meantime it's about
3.2GB when imported into git - space that would just make the early
git days unnecessarily complicated, when we don't have a lot of good
infrastructure for it.
Let it rip!
Diffstat (limited to 'arch/arm/mach-pxa/mainstone.c')
-rw-r--r-- | arch/arm/mach-pxa/mainstone.c | 316 |
1 files changed, 316 insertions, 0 deletions
diff --git a/arch/arm/mach-pxa/mainstone.c b/arch/arm/mach-pxa/mainstone.c new file mode 100644 index 000000000000..3f952237ae3d --- /dev/null +++ b/arch/arm/mach-pxa/mainstone.c | |||
@@ -0,0 +1,316 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/mach-pxa/mainstone.c | ||
3 | * | ||
4 | * Support for the Intel HCDDBBVA0 Development Platform. | ||
5 | * (go figure how they came up with such name...) | ||
6 | * | ||
7 | * Author: Nicolas Pitre | ||
8 | * Created: Nov 05, 2002 | ||
9 | * Copyright: MontaVista Software Inc. | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or modify | ||
12 | * it under the terms of the GNU General Public License version 2 as | ||
13 | * published by the Free Software Foundation. | ||
14 | */ | ||
15 | |||
16 | #include <linux/init.h> | ||
17 | #include <linux/device.h> | ||
18 | #include <linux/interrupt.h> | ||
19 | #include <linux/sched.h> | ||
20 | #include <linux/bitops.h> | ||
21 | #include <linux/fb.h> | ||
22 | |||
23 | #include <asm/types.h> | ||
24 | #include <asm/setup.h> | ||
25 | #include <asm/memory.h> | ||
26 | #include <asm/mach-types.h> | ||
27 | #include <asm/hardware.h> | ||
28 | #include <asm/irq.h> | ||
29 | |||
30 | #include <asm/mach/arch.h> | ||
31 | #include <asm/mach/map.h> | ||
32 | #include <asm/mach/irq.h> | ||
33 | |||
34 | #include <asm/arch/pxa-regs.h> | ||
35 | #include <asm/arch/mainstone.h> | ||
36 | #include <asm/arch/audio.h> | ||
37 | #include <asm/arch/pxafb.h> | ||
38 | #include <asm/arch/mmc.h> | ||
39 | |||
40 | #include "generic.h" | ||
41 | |||
42 | |||
43 | static unsigned long mainstone_irq_enabled; | ||
44 | |||
45 | static void mainstone_mask_irq(unsigned int irq) | ||
46 | { | ||
47 | int mainstone_irq = (irq - MAINSTONE_IRQ(0)); | ||
48 | MST_INTMSKENA = (mainstone_irq_enabled &= ~(1 << mainstone_irq)); | ||
49 | } | ||
50 | |||
51 | static void mainstone_unmask_irq(unsigned int irq) | ||
52 | { | ||
53 | int mainstone_irq = (irq - MAINSTONE_IRQ(0)); | ||
54 | /* the irq can be acknowledged only if deasserted, so it's done here */ | ||
55 | MST_INTSETCLR &= ~(1 << mainstone_irq); | ||
56 | MST_INTMSKENA = (mainstone_irq_enabled |= (1 << mainstone_irq)); | ||
57 | } | ||
58 | |||
59 | static struct irqchip mainstone_irq_chip = { | ||
60 | .ack = mainstone_mask_irq, | ||
61 | .mask = mainstone_mask_irq, | ||
62 | .unmask = mainstone_unmask_irq, | ||
63 | }; | ||
64 | |||
65 | |||
66 | static void mainstone_irq_handler(unsigned int irq, struct irqdesc *desc, | ||
67 | struct pt_regs *regs) | ||
68 | { | ||
69 | unsigned long pending = MST_INTSETCLR & mainstone_irq_enabled; | ||
70 | do { | ||
71 | GEDR(0) = GPIO_bit(0); /* clear useless edge notification */ | ||
72 | if (likely(pending)) { | ||
73 | irq = MAINSTONE_IRQ(0) + __ffs(pending); | ||
74 | desc = irq_desc + irq; | ||
75 | desc->handle(irq, desc, regs); | ||
76 | } | ||
77 | pending = MST_INTSETCLR & mainstone_irq_enabled; | ||
78 | } while (pending); | ||
79 | } | ||
80 | |||
81 | static void __init mainstone_init_irq(void) | ||
82 | { | ||
83 | int irq; | ||
84 | |||
85 | pxa_init_irq(); | ||
86 | |||
87 | /* setup extra Mainstone irqs */ | ||
88 | for(irq = MAINSTONE_IRQ(0); irq <= MAINSTONE_IRQ(15); irq++) { | ||
89 | set_irq_chip(irq, &mainstone_irq_chip); | ||
90 | set_irq_handler(irq, do_level_IRQ); | ||
91 | set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); | ||
92 | } | ||
93 | set_irq_flags(MAINSTONE_IRQ(8), 0); | ||
94 | set_irq_flags(MAINSTONE_IRQ(12), 0); | ||
95 | |||
96 | MST_INTMSKENA = 0; | ||
97 | MST_INTSETCLR = 0; | ||
98 | |||
99 | set_irq_chained_handler(IRQ_GPIO(0), mainstone_irq_handler); | ||
100 | set_irq_type(IRQ_GPIO(0), IRQT_FALLING); | ||
101 | } | ||
102 | |||
103 | |||
104 | static struct resource smc91x_resources[] = { | ||
105 | [0] = { | ||
106 | .start = (MST_ETH_PHYS + 0x300), | ||
107 | .end = (MST_ETH_PHYS + 0xfffff), | ||
108 | .flags = IORESOURCE_MEM, | ||
109 | }, | ||
110 | [1] = { | ||
111 | .start = MAINSTONE_IRQ(3), | ||
112 | .end = MAINSTONE_IRQ(3), | ||
113 | .flags = IORESOURCE_IRQ, | ||
114 | } | ||
115 | }; | ||
116 | |||
117 | static struct platform_device smc91x_device = { | ||
118 | .name = "smc91x", | ||
119 | .id = 0, | ||
120 | .num_resources = ARRAY_SIZE(smc91x_resources), | ||
121 | .resource = smc91x_resources, | ||
122 | }; | ||
123 | |||
124 | static int mst_audio_startup(snd_pcm_substream_t *substream, void *priv) | ||
125 | { | ||
126 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | ||
127 | MST_MSCWR2 &= ~MST_MSCWR2_AC97_SPKROFF; | ||
128 | return 0; | ||
129 | } | ||
130 | |||
131 | static void mst_audio_shutdown(snd_pcm_substream_t *substream, void *priv) | ||
132 | { | ||
133 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | ||
134 | MST_MSCWR2 |= MST_MSCWR2_AC97_SPKROFF; | ||
135 | } | ||
136 | |||
137 | static long mst_audio_suspend_mask; | ||
138 | |||
139 | static void mst_audio_suspend(void *priv) | ||
140 | { | ||
141 | mst_audio_suspend_mask = MST_MSCWR2; | ||
142 | MST_MSCWR2 |= MST_MSCWR2_AC97_SPKROFF; | ||
143 | } | ||
144 | |||
145 | static void mst_audio_resume(void *priv) | ||
146 | { | ||
147 | MST_MSCWR2 &= mst_audio_suspend_mask | ~MST_MSCWR2_AC97_SPKROFF; | ||
148 | } | ||
149 | |||
150 | static pxa2xx_audio_ops_t mst_audio_ops = { | ||
151 | .startup = mst_audio_startup, | ||
152 | .shutdown = mst_audio_shutdown, | ||
153 | .suspend = mst_audio_suspend, | ||
154 | .resume = mst_audio_resume, | ||
155 | }; | ||
156 | |||
157 | static struct platform_device mst_audio_device = { | ||
158 | .name = "pxa2xx-ac97", | ||
159 | .id = -1, | ||
160 | .dev = { .platform_data = &mst_audio_ops }, | ||
161 | }; | ||
162 | |||
163 | static void mainstone_backlight_power(int on) | ||
164 | { | ||
165 | if (on) { | ||
166 | pxa_gpio_mode(GPIO16_PWM0_MD); | ||
167 | pxa_set_cken(CKEN0_PWM0, 1); | ||
168 | PWM_CTRL0 = 0; | ||
169 | PWM_PWDUTY0 = 0x3ff; | ||
170 | PWM_PERVAL0 = 0x3ff; | ||
171 | } else { | ||
172 | PWM_CTRL0 = 0; | ||
173 | PWM_PWDUTY0 = 0x0; | ||
174 | PWM_PERVAL0 = 0x3FF; | ||
175 | pxa_set_cken(CKEN0_PWM0, 0); | ||
176 | } | ||
177 | } | ||
178 | |||
179 | static struct pxafb_mach_info toshiba_ltm04c380k __initdata = { | ||
180 | .pixclock = 50000, | ||
181 | .xres = 640, | ||
182 | .yres = 480, | ||
183 | .bpp = 16, | ||
184 | .hsync_len = 1, | ||
185 | .left_margin = 0x9f, | ||
186 | .right_margin = 1, | ||
187 | .vsync_len = 44, | ||
188 | .upper_margin = 0, | ||
189 | .lower_margin = 0, | ||
190 | .sync = FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, | ||
191 | .lccr0 = LCCR0_Act, | ||
192 | .lccr3 = LCCR3_PCP, | ||
193 | .pxafb_backlight_power = mainstone_backlight_power, | ||
194 | }; | ||
195 | |||
196 | static struct pxafb_mach_info toshiba_ltm035a776c __initdata = { | ||
197 | .pixclock = 110000, | ||
198 | .xres = 240, | ||
199 | .yres = 320, | ||
200 | .bpp = 16, | ||
201 | .hsync_len = 4, | ||
202 | .left_margin = 8, | ||
203 | .right_margin = 20, | ||
204 | .vsync_len = 3, | ||
205 | .upper_margin = 1, | ||
206 | .lower_margin = 10, | ||
207 | .sync = FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, | ||
208 | .lccr0 = LCCR0_Act, | ||
209 | .lccr3 = LCCR3_PCP, | ||
210 | .pxafb_backlight_power = mainstone_backlight_power, | ||
211 | }; | ||
212 | |||
213 | static int mainstone_mci_init(struct device *dev, irqreturn_t (*mstone_detect_int)(int, void *, struct pt_regs *), void *data) | ||
214 | { | ||
215 | int err; | ||
216 | |||
217 | /* | ||
218 | * setup GPIO for PXA27x MMC controller | ||
219 | */ | ||
220 | pxa_gpio_mode(GPIO32_MMCCLK_MD); | ||
221 | pxa_gpio_mode(GPIO112_MMCCMD_MD); | ||
222 | pxa_gpio_mode(GPIO92_MMCDAT0_MD); | ||
223 | pxa_gpio_mode(GPIO109_MMCDAT1_MD); | ||
224 | pxa_gpio_mode(GPIO110_MMCDAT2_MD); | ||
225 | pxa_gpio_mode(GPIO111_MMCDAT3_MD); | ||
226 | |||
227 | /* make sure SD/Memory Stick multiplexer's signals | ||
228 | * are routed to MMC controller | ||
229 | */ | ||
230 | MST_MSCWR1 &= ~MST_MSCWR1_MS_SEL; | ||
231 | |||
232 | err = request_irq(MAINSTONE_MMC_IRQ, mstone_detect_int, SA_INTERRUPT, | ||
233 | "MMC card detect", data); | ||
234 | if (err) { | ||
235 | printk(KERN_ERR "mainstone_mci_init: MMC/SD: can't request MMC card detect IRQ\n"); | ||
236 | return -1; | ||
237 | } | ||
238 | |||
239 | return 0; | ||
240 | } | ||
241 | |||
242 | static void mainstone_mci_setpower(struct device *dev, unsigned int vdd) | ||
243 | { | ||
244 | struct pxamci_platform_data* p_d = dev->platform_data; | ||
245 | |||
246 | if (( 1 << vdd) & p_d->ocr_mask) { | ||
247 | printk(KERN_DEBUG "%s: on\n", __FUNCTION__); | ||
248 | MST_MSCWR1 |= MST_MSCWR1_MMC_ON; | ||
249 | MST_MSCWR1 &= ~MST_MSCWR1_MS_SEL; | ||
250 | } else { | ||
251 | printk(KERN_DEBUG "%s: off\n", __FUNCTION__); | ||
252 | MST_MSCWR1 &= ~MST_MSCWR1_MMC_ON; | ||
253 | } | ||
254 | } | ||
255 | |||
256 | static void mainstone_mci_exit(struct device *dev, void *data) | ||
257 | { | ||
258 | free_irq(MAINSTONE_MMC_IRQ, data); | ||
259 | } | ||
260 | |||
261 | static struct pxamci_platform_data mainstone_mci_platform_data = { | ||
262 | .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, | ||
263 | .init = mainstone_mci_init, | ||
264 | .setpower = mainstone_mci_setpower, | ||
265 | .exit = mainstone_mci_exit, | ||
266 | }; | ||
267 | |||
268 | static void __init mainstone_init(void) | ||
269 | { | ||
270 | /* | ||
271 | * On Mainstone, we route AC97_SYSCLK via GPIO45 to | ||
272 | * the audio daughter card | ||
273 | */ | ||
274 | pxa_gpio_mode(GPIO45_SYSCLK_AC97_MD); | ||
275 | |||
276 | platform_device_register(&smc91x_device); | ||
277 | platform_device_register(&mst_audio_device); | ||
278 | |||
279 | /* reading Mainstone's "Virtual Configuration Register" | ||
280 | might be handy to select LCD type here */ | ||
281 | if (0) | ||
282 | set_pxa_fb_info(&toshiba_ltm04c380k); | ||
283 | else | ||
284 | set_pxa_fb_info(&toshiba_ltm035a776c); | ||
285 | |||
286 | pxa_set_mci_info(&mainstone_mci_platform_data); | ||
287 | } | ||
288 | |||
289 | |||
290 | static struct map_desc mainstone_io_desc[] __initdata = { | ||
291 | { MST_FPGA_VIRT, MST_FPGA_PHYS, 0x00100000, MT_DEVICE }, /* CPLD */ | ||
292 | }; | ||
293 | |||
294 | static void __init mainstone_map_io(void) | ||
295 | { | ||
296 | pxa_map_io(); | ||
297 | iotable_init(mainstone_io_desc, ARRAY_SIZE(mainstone_io_desc)); | ||
298 | |||
299 | /* initialize sleep mode regs (wake-up sources, etc) */ | ||
300 | PGSR0 = 0x00008800; | ||
301 | PGSR1 = 0x00000002; | ||
302 | PGSR2 = 0x0001FC00; | ||
303 | PGSR3 = 0x00001F81; | ||
304 | PWER = 0xC0000002; | ||
305 | PRER = 0x00000002; | ||
306 | PFER = 0x00000002; | ||
307 | } | ||
308 | |||
309 | MACHINE_START(MAINSTONE, "Intel HCDDBBVA0 Development Platform (aka Mainstone)") | ||
310 | MAINTAINER("MontaVista Software Inc.") | ||
311 | BOOT_MEM(0xa0000000, 0x40000000, io_p2v(0x40000000)) | ||
312 | MAPIO(mainstone_map_io) | ||
313 | INITIRQ(mainstone_init_irq) | ||
314 | .timer = &pxa_timer, | ||
315 | INIT_MACHINE(mainstone_init) | ||
316 | MACHINE_END | ||