vserver 1.9.3
[linux-2.6.git] / arch / arm / mach-pxa / mainstone.c
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/pxafb.h>
37
38 #include "generic.h"
39
40
41 static unsigned long mainstone_irq_enabled;
42
43 static void mainstone_mask_irq(unsigned int irq)
44 {
45         int mainstone_irq = (irq - MAINSTONE_IRQ(0));
46         MST_INTMSKENA = (mainstone_irq_enabled &= ~(1 << mainstone_irq));
47 }
48
49 static void mainstone_unmask_irq(unsigned int irq)
50 {
51         int mainstone_irq = (irq - MAINSTONE_IRQ(0));
52         /* the irq can be acknowledged only if deasserted, so it's done here */
53         MST_INTSETCLR &= ~(1 << mainstone_irq);
54         MST_INTMSKENA = (mainstone_irq_enabled |= (1 << mainstone_irq));
55 }
56
57 static struct irqchip mainstone_irq_chip = {
58         .ack            = mainstone_mask_irq,
59         .mask           = mainstone_mask_irq,
60         .unmask         = mainstone_unmask_irq,
61 };
62
63
64 static void mainstone_irq_handler(unsigned int irq, struct irqdesc *desc,
65                                   struct pt_regs *regs)
66 {
67         unsigned long pending = MST_INTSETCLR & mainstone_irq_enabled;
68         do {
69                 GEDR(0) = GPIO_bit(0);  /* clear useless edge notification */
70                 if (likely(pending)) {
71                         irq = MAINSTONE_IRQ(0) + __ffs(pending);
72                         desc = irq_desc + irq;
73                         desc->handle(irq, desc, regs);
74                 }
75                 pending = MST_INTSETCLR & mainstone_irq_enabled;
76         } while (pending);
77 }
78
79 static void __init mainstone_init_irq(void)
80 {
81         int irq;
82
83         pxa_init_irq();
84
85         /* setup extra Mainstone irqs */
86         for(irq = MAINSTONE_IRQ(0); irq <= MAINSTONE_IRQ(15); irq++) {
87                 set_irq_chip(irq, &mainstone_irq_chip);
88                 set_irq_handler(irq, do_level_IRQ);
89                 set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
90         }
91         set_irq_flags(MAINSTONE_IRQ(8), 0);
92         set_irq_flags(MAINSTONE_IRQ(12), 0);
93
94         MST_INTMSKENA = 0;
95         MST_INTSETCLR = 0;
96
97         set_irq_chained_handler(IRQ_GPIO(0), mainstone_irq_handler);
98         set_irq_type(IRQ_GPIO(0), IRQT_FALLING);
99 }
100
101
102 static struct resource smc91x_resources[] = {
103         [0] = {
104                 .start  = (MST_ETH_PHYS + 0x300),
105                 .end    = (MST_ETH_PHYS + 0xfffff),
106                 .flags  = IORESOURCE_MEM,
107         },
108         [1] = {
109                 .start  = MAINSTONE_IRQ(3),
110                 .end    = MAINSTONE_IRQ(3),
111                 .flags  = IORESOURCE_IRQ,
112         }
113 };
114
115 static struct platform_device smc91x_device = {
116         .name           = "smc91x",
117         .id             = 0,
118         .num_resources  = ARRAY_SIZE(smc91x_resources),
119         .resource       = smc91x_resources,
120 };
121
122
123 static void mainstone_backlight_power(int on)
124 {
125         if (on) {
126                 pxa_gpio_mode(GPIO16_PWM0_MD);
127                 pxa_set_cken(CKEN0_PWM0, 1);
128                 PWM_CTRL0 = 0;
129                 PWM_PWDUTY0 = 0x3ff;
130                 PWM_PERVAL0 = 0x3ff;
131         } else {
132                 PWM_CTRL0 = 0;
133                 PWM_PWDUTY0 = 0x0;
134                 PWM_PERVAL0 = 0x3FF;
135                 pxa_set_cken(CKEN0_PWM0, 0);
136         }
137 }
138
139 static struct pxafb_mach_info toshiba_ltm04c380k __initdata = {
140         .pixclock               = 50000,
141         .xres                   = 640,
142         .yres                   = 480,
143         .bpp                    = 16,
144         .hsync_len              = 1,
145         .left_margin            = 0x9f,
146         .right_margin           = 1,
147         .vsync_len              = 44,
148         .upper_margin           = 0,
149         .lower_margin           = 0,
150         .sync                   = FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT,
151         .lccr0                  = LCCR0_Act,
152         .lccr3                  = LCCR3_PCP,
153         .pxafb_backlight_power  = mainstone_backlight_power,
154 };
155
156 static struct pxafb_mach_info toshiba_ltm035a776c __initdata = {
157         .pixclock               = 110000,
158         .xres                   = 240,
159         .yres                   = 320,
160         .bpp                    = 16,
161         .hsync_len              = 4,
162         .left_margin            = 8,
163         .right_margin           = 20,
164         .vsync_len              = 3,
165         .upper_margin           = 1,
166         .lower_margin           = 10,
167         .sync                   = FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT,
168         .lccr0                  = LCCR0_Act,
169         .lccr3                  = LCCR3_PCP,
170         .pxafb_backlight_power  = mainstone_backlight_power,
171 };
172
173 static void __init mainstone_init(void)
174 {
175         platform_device_register(&smc91x_device);
176
177         /* reading Mainstone's "Virtual Configuration Register"
178            might be handy to select LCD type here */
179         if (0)
180                 set_pxa_fb_info(&toshiba_ltm04c380k);
181         else
182                 set_pxa_fb_info(&toshiba_ltm035a776c);
183 }
184
185
186 static struct map_desc mainstone_io_desc[] __initdata = {
187   { MST_FPGA_VIRT, MST_FPGA_PHYS, 0x00100000, MT_DEVICE }, /* CPLD */
188 };
189
190 static void __init mainstone_map_io(void)
191 {
192         pxa_map_io();
193         iotable_init(mainstone_io_desc, ARRAY_SIZE(mainstone_io_desc));
194 }
195
196 MACHINE_START(MAINSTONE, "Intel HCDDBBVA0 Development Platform (aka Mainstone)")
197         MAINTAINER("MontaVista Software Inc.")
198         BOOT_MEM(0xa0000000, 0x40000000, io_p2v(0x40000000))
199         MAPIO(mainstone_map_io)
200         INITIRQ(mainstone_init_irq)
201         INITTIME(pxa_init_time)
202         INIT_MACHINE(mainstone_init)
203 MACHINE_END