more changes on original files
[linux-2.4.git] / arch / arm / mach-sa1100 / graphicsmaster.c
1 /*
2  * linux/arch/arm/mach-sa1100/graphicsmaster.c
3  *
4  * Pieces specific to the GraphicsMaster board
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation.
9  */
10
11 #include <linux/init.h>
12 #include <linux/sched.h>
13 #include <linux/interrupt.h>
14 #include <linux/ptrace.h>
15 #include <linux/serial_core.h>
16 #include <linux/delay.h>
17 #include <linux/list.h>
18 #include <linux/timer.h>
19
20 #include <asm/hardware.h>
21 #include <asm/hardware/sa1111.h>
22 #include <asm/setup.h>
23 #include <asm/irq.h>
24
25 #include <asm/mach/irq.h>
26 #include <asm/mach/arch.h>
27 #include <asm/mach/map.h>
28 #include <asm/mach/serial_sa1100.h>
29
30 #include <asm/arch/irq.h>
31
32 #include "generic.h"
33 #include "sa1111.h"
34
35 static int __init graphicsmaster_init(void)
36 {
37         int ret;
38
39         if (!machine_is_graphicsmaster())
40                 return -ENODEV;
41
42         /*
43          * Ensure that the memory bus request/grant signals are setup,
44          * and the grant is held in its inactive state
45          */
46         sa1110_mb_disable();
47
48         /* GraphicsMaster uses GPIO pins for SPI interface to AVR
49          */
50
51         /* use the alternate SSP pins */
52         PPAR |= PPAR_SSPGPIO;
53
54         // Set RTS low during sleep
55         PGSR |= GPIO_GPIO15 | GPIO_GPIO17 | GPIO_GPIO19;
56
57         /*
58          * Probe for SA1111.
59          */
60         ret = sa1111_probe(ADS_SA1111_BASE);
61         if (ret < 0)
62                 return ret;
63
64         /*
65          * We found it.  Wake the chip up.
66          */
67         sa1111_wake();
68
69         /*
70          * The SDRAM configuration of the SA1110 and the SA1111 must
71          * match.  This is very important to ensure that SA1111 accesses
72          * don't corrupt the SDRAM.  Note that this ungates the SA1111's
73          * MBGNT signal, so we must have called sa1110_mb_disable()
74          * beforehand.
75          */
76         sa1111_configure_smc(1,
77                              FExtr(MDCNFG, MDCNFG_SA1110_DRAC0),
78                              FExtr(MDCNFG, MDCNFG_SA1110_TDL0));
79
80         /*
81          * Enable PWM control for LCD
82          */
83         SKPCR |= SKPCR_PWMCLKEN;
84         SACR1 &= ~SACR1_L3EN;
85         ADS_DCR |= DCR_BACKLITE_ON;
86         SKPWM0 = 0x01;                          // Backlight
87         SKPEN0 = 1;
88         SKPWM1 = 0x7F;                          // VEE
89         SKPEN1 = 1;
90
91         /*
92          * We only need to turn on DCLK whenever we want to use the
93          * DMA.  It can otherwise be held firmly in the off position.
94          */
95         SKPCR |= SKPCR_DCLKEN;
96
97         /*
98          * Enable the SA1110 memory bus request and grant signals.
99          */
100         sa1110_mb_enable();
101
102         sa1111_init_irq(IRQ_GRAPHICSMASTER_SA1111);
103
104         return 0;
105 }
106
107 __initcall(graphicsmaster_init);
108
109 /*
110  * Handlers for GraphicsMaster's external IRQ logic
111  */
112
113 #define GRAPHICSMASTER_N_IRQ (IRQ_GRAPHICSMASTER_END - IRQ_GRAPHICSMASTER_START)
114
115 static void ADS_IRQ_demux( int irq, void *dev_id, struct pt_regs *regs )
116 {
117         int i;
118
119         while( (irq = ADS_INT_ST1 | (ADS_INT_ST2 << 8)) ){
120                 for( i = 0; i < GRAPHICSMASTER_N_IRQ; i++ )
121                         if( irq & (1<<i) ) {
122                                 do_IRQ( IRQ_GRAPHICSMASTER_START + i, regs );
123                         }
124         }
125 }
126
127 static struct irqaction ADS_ext_irq = {
128         .name           = "ADS_ext_IRQ",
129         .handler        = ADS_IRQ_demux,
130         .flags          = SA_INTERRUPT
131 };
132
133 static void ADS_mask_and_ack_irq0(unsigned int irq)
134 {
135         int mask = (1 << (irq - IRQ_GRAPHICSMASTER_START));
136         ADS_INT_EN1 &= ~mask;
137         ADS_INT_ST1 = mask;
138 }
139
140 static void ADS_mask_irq0(unsigned int irq)
141 {
142         ADS_INT_ST1 = (1 << (irq - IRQ_GRAPHICSMASTER_START));
143 }
144
145 static void ADS_unmask_irq0(unsigned int irq)
146 {
147         ADS_INT_EN1 |= (1 << (irq - IRQ_GRAPHICSMASTER_START));
148 }
149
150 static void ADS_mask_and_ack_irq1(unsigned int irq)
151 {
152         int mask = (1 << (irq - (IRQ_GRAPHICSMASTER_UCB1200)));
153         ADS_INT_EN2 &= ~mask;
154         ADS_INT_ST2 = mask;
155 }
156
157 static void ADS_mask_irq1(unsigned int irq)
158 {
159         ADS_INT_ST2 = (1 << (irq - (IRQ_GRAPHICSMASTER_UCB1200)));
160 }
161
162 static void ADS_unmask_irq1(unsigned int irq)
163 {
164         ADS_INT_EN2 |= (1 << (irq - (IRQ_GRAPHICSMASTER_UCB1200)));
165 }
166
167 static void __init graphicsmaster_init_irq(void)
168 {
169         int irq;
170
171         /* First the standard SA1100 IRQs */
172         sa1100_init_irq();
173
174         /* disable all IRQs */
175         ADS_INT_EN1 = 0;
176         ADS_INT_EN2 = 0;
177         /* clear all IRQs */
178         ADS_INT_ST1 = 0xff;
179         ADS_INT_ST2 = 0xff;
180
181         for (irq = IRQ_GRAPHICSMASTER_START; irq < IRQ_GRAPHICSMASTER_UCB1200; irq++) {
182                 irq_desc[irq].valid     = 1;
183                 irq_desc[irq].probe_ok  = 1;
184                 irq_desc[irq].mask_ack  = ADS_mask_and_ack_irq0;
185                 irq_desc[irq].mask      = ADS_mask_irq0;
186                 irq_desc[irq].unmask    = ADS_unmask_irq0;
187         }
188         for (irq = IRQ_GRAPHICSMASTER_UCB1200; irq < IRQ_GRAPHICSMASTER_END; irq++) {
189                 irq_desc[irq].valid     = 1;
190                 irq_desc[irq].probe_ok  = 1;
191                 irq_desc[irq].mask_ack  = ADS_mask_and_ack_irq1;
192                 irq_desc[irq].mask      = ADS_mask_irq1;
193                 irq_desc[irq].unmask    = ADS_unmask_irq1;
194         }
195
196         GPDR &= ~GPIO_GPIO0;
197         set_GPIO_IRQ_edge(GPIO_GPIO0, GPIO_FALLING_EDGE);
198         setup_arm_irq( IRQ_GPIO0, &ADS_ext_irq );
199 }
200
201
202 static struct map_desc graphicsmaster_io_desc[] __initdata = {
203  /* virtual     physical    length      domain     r  w  c  b */
204   { 0xe8000000, 0x08000000, 0x02000000, DOMAIN_IO, 0, 1, 0, 0 }, /* Flash bank 1 */
205   { 0xf0000000, 0x10000000, 0x00400000, DOMAIN_IO, 0, 1, 0, 0 }, /* CPLD */
206   { 0xf1000000, 0x40000000, 0x00400000, DOMAIN_IO, 0, 1, 0, 0 }, /* CAN */
207   { 0xf4000000, 0x18000000, 0x00800000, DOMAIN_IO, 0, 1, 0, 0 }, /* SA-1111 */
208   LAST_DESC
209 };
210
211 static int graphicsmaster_uart_open(struct uart_port *port, struct uart_info *info)
212 {
213         int     ret = 0;
214
215         if (port->mapbase == _Ser1UTCR0) {
216                 Ser1SDCR0 |= SDCR0_UART;
217         }
218         else if (port->mapbase == _Ser2UTCR0) {
219                 Ser2UTCR4 = Ser2HSCR0 = 0;
220         }
221         return ret;
222 }
223
224 static u_int graphicsmaster_get_mctrl(struct uart_port *port)
225 {
226         u_int result = TIOCM_CD | TIOCM_DSR;
227
228         if (port->mapbase == _Ser1UTCR0) {
229                 if (!(GPLR & GPIO_GPIO14))
230                         result |= TIOCM_CTS;
231         } else if (port->mapbase == _Ser2UTCR0) {
232                 if (!(GPLR & GPIO_GPIO16))
233                         result |= TIOCM_CTS;
234         } else if (port->mapbase == _Ser3UTCR0) {
235                 if (!(GPLR & GPIO_GPIO18))
236                         result |= TIOCM_CTS;
237         } else {
238                 result = TIOCM_CTS;
239         }
240
241         return result;
242 }
243
244 static void graphicsmaster_set_mctrl(struct uart_port *port, u_int mctrl)
245 {
246         if (port->mapbase == _Ser1UTCR0) {
247                 if (mctrl & TIOCM_RTS)
248                         GPCR = GPIO_GPIO15;
249                 else
250                         GPSR = GPIO_GPIO15;
251         } else if (port->mapbase == _Ser2UTCR0) {
252                 if (mctrl & TIOCM_RTS)
253                         GPCR = GPIO_GPIO17;
254                 else
255                         GPSR = GPIO_GPIO17;
256         } else if (port->mapbase == _Ser3UTCR0) {
257                 if (mctrl & TIOCM_RTS)
258                         GPCR = GPIO_GPIO19;
259                 else
260                         GPSR = GPIO_GPIO19;
261         }
262 }
263
264 static void
265 graphicsmaster_uart_pm(struct uart_port *port, u_int state, u_int oldstate)
266 {
267         // state has ACPI D0-D3
268         // ACPI D0        : resume from suspend
269         // ACPI D1-D3 : enter to a suspend state
270         if (port->mapbase == _Ser1UTCR0) {
271                 if (state) {
272                         // disable uart
273                         Ser1UTCR3 = 0;
274                 }
275         }
276         else if (port->mapbase == _Ser2UTCR0) {
277                 if (state) {
278                         // disable uart
279                         Ser2UTCR3 = 0;
280                         Ser2HSCR0 = 0;
281                 }
282         }
283         else if (port->mapbase == _Ser3UTCR0) {
284                 if (state) {
285                         // disable uart
286                         Ser3UTCR3 = 0;
287                 }
288         }
289 }
290
291 static struct sa1100_port_fns graphicsmaster_port_fns __initdata = {
292         .open           = graphicsmaster_uart_open,
293         .get_mctrl      = graphicsmaster_get_mctrl,
294         .set_mctrl      = graphicsmaster_set_mctrl,
295         .pm             = graphicsmaster_uart_pm,
296 };
297
298 static void __init graphicsmaster_map_io(void)
299 {
300         sa1100_map_io();
301         iotable_init(graphicsmaster_io_desc);
302
303         sa1100_register_uart_fns(&graphicsmaster_port_fns);
304         sa1100_register_uart(0, 3);
305         sa1100_register_uart(1, 1);
306         // don't register if you want to use IRDA
307 #ifndef CONFIG_SA1100_FIR
308         sa1100_register_uart(2, 2);
309 #endif
310
311         /* set GPDR now */
312         GPDR |= GPIO_GPIO15 | GPIO_GPIO17 | GPIO_GPIO19;
313         GPDR &= ~(GPIO_GPIO14 | GPIO_GPIO16 | GPIO_GPIO18);
314 }
315
316 MACHINE_START(GRAPHICSMASTER, "ADS GraphicsMaster")
317         BOOT_PARAMS(0xc000003c)
318         BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
319         MAPIO(graphicsmaster_map_io)
320         INITIRQ(graphicsmaster_init_irq)
321 MACHINE_END