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