# BRCM_VERSION=3
[bcm963xx.git] / kernel / linux / arch / arm / mach-sa1100 / flexanet.c
1 /*
2  * linux/arch/arm/mach-sa1100/flexanet.c
3  *
4  * Author: Jordi Colomer <jco@ict.es>
5  *
6  * This file contains all FlexaNet-specific tweaks.
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License version 2 as
10  * published by the Free Software Foundation.
11  */
12 #include <linux/init.h>
13 #include <linux/kernel.h>
14 #include <linux/tty.h>
15 #include <linux/module.h>
16 #include <linux/errno.h>
17 #include <linux/delay.h>
18
19 #include <asm/hardware.h>
20 #include <asm/setup.h>
21 #include <asm/page.h>
22 #include <asm/pgtable.h>
23
24 #include <asm/mach/arch.h>
25 #include <asm/mach/map.h>
26 #include <asm/mach/serial_sa1100.h>
27 #include <linux/serial_core.h>
28
29 #include "generic.h"
30
31
32 unsigned long flexanet_BCR = FHH_BCR_POWERUP;
33
34 EXPORT_SYMBOL(flexanet_BCR);
35
36 /* physical addresses */
37 #define _RCNR        0x90010004
38 #define _GPLR        0x90040000
39 #define _Ser4SSCR0   0x80070060
40
41 /*
42  * Get the modem-control register of the UARTs
43  *
44  */
45 static int flexanet_get_mctrl(struct uart_port *port)
46 {
47         int            stat = 0;
48         unsigned long  bsr;
49
50         /* only DSR and CTS are implemented in UART1 & 3 */
51         if (port->membase == (void *)&Ser1UTCR0)
52         {
53                 bsr = FHH_BSR;
54
55                 if ((bsr & FHH_BSR_DSR1) != 0)
56                         stat |= TIOCM_DSR;
57                 if ((bsr & FHH_BSR_CTS1) != 0)
58                         stat |= TIOCM_CTS;
59         }
60         else if (port->membase == (void *)&Ser3UTCR0)
61         {
62                 bsr = FHH_BSR;
63
64                 if ((bsr & FHH_BSR_DSR3) != 0)
65                         stat |= TIOCM_DSR;
66                 if ((bsr & FHH_BSR_CTS3) != 0)
67                         stat |= TIOCM_CTS;
68         }
69
70         return stat;
71 }
72
73 /*
74  * Set the modem-control register of the UARTs
75  *
76  */
77 static void flexanet_set_mctrl(struct uart_port *port, u_int mctrl)
78 {
79         unsigned long   flags;
80
81         /* only the RTS signal is implemented in UART1 & 3 */
82         if (port->membase == (void *)&Ser1UTCR0)
83         {
84                 local_irq_save(flags);
85
86                 if (mctrl & TIOCM_RTS)
87                         flexanet_BCR |= FHH_BCR_RTS1;
88                 else
89                         flexanet_BCR &= ~FHH_BCR_RTS1;
90
91                 FHH_BCR = flexanet_BCR;
92                 local_irq_restore(flags);
93         }
94         else if (port->membase == (void *)&Ser3UTCR0)
95         {
96                 local_irq_save(flags);
97
98                 if (mctrl & TIOCM_RTS)
99                         flexanet_BCR |= FHH_BCR_RTS3;
100                 else
101                         flexanet_BCR &= ~FHH_BCR_RTS3;
102
103                 FHH_BCR = flexanet_BCR;
104                 local_irq_restore(flags);
105         }
106 }
107
108 /*
109  * machine-specific serial port functions
110  *
111  * get_mctrl : set state of modem control lines
112  * set_mctrl : set the modem control lines
113  * pm        : power-management. Turn device on/off.
114  *
115  */
116 static struct sa1100_port_fns   flexanet_port_fns __initdata =
117 {
118         set_mctrl : flexanet_set_mctrl,
119         get_mctrl : flexanet_get_mctrl,
120         pm        : NULL,
121 };
122
123
124 /*
125  * Initialization and serial port mapping
126  *
127  */
128
129 static int flexanet_serial_init(void)
130 {
131         /* register low-level functions */
132         sa1100_register_uart_fns(&flexanet_port_fns);
133
134         /* UART port number mapping */
135         sa1100_register_uart(0, 1); /* RS232 */
136         sa1100_register_uart(1, 3); /* Radio */
137
138         /* Select UART function in Serial port 1 */
139         Ser1SDCR0 |= SDCR0_UART;
140
141         return 0;
142 }
143
144
145 static struct map_desc flexanet_io_desc[] __initdata = {
146  /* virtual     physical    length      type */
147   { 0xf0000000, 0x10000000, 0x00001000, MT_DEVICE }, /* Board Control Register */
148   { 0xf1000000, 0x18000000, 0x01000000, MT_DEVICE }, /* Ethernet controller */
149   { 0xD0000000, 0x40000000, 0x01000000, MT_DEVICE }, /* Instrument boards */
150   { 0xD8000000, 0x48000000, 0x01000000, MT_DEVICE }  /* External peripherals */
151 };
152
153 static void __init flexanet_map_io(void)
154 {
155         sa1100_map_io();
156         iotable_init(flexanet_io_desc, ARRAY_SIZE(flexanet_io_desc));
157         flexanet_serial_init();
158
159         /* wakeup source is GPIO-0 only */
160         PWER = PWER_GPIO0;
161
162         /* GPIOs set to zero during sleep */
163         PGSR = 0;
164
165         /*
166          * stop the 3.68 MHz oscillator and float control busses
167          * during sleep, since peripherals are powered off.
168          */
169         PCFR = PCFR_OPDE | PCFR_FP | PCFR_FS;
170
171         /* deassert the GUI reset */
172         FLEXANET_BCR_set(FHH_BCR_GUI_NRST);
173
174         /*
175          * Set IRQ edges
176          */
177         set_GPIO_IRQ_edge(GPIO_GUI_IRQ, GPIO_RISING_EDGE);
178 }
179
180
181 MACHINE_START(FLEXANET, "FlexaNet")
182         BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
183         BOOT_PARAMS(0xc0000100)
184         MAPIO(flexanet_map_io)
185         INITIRQ(sa1100_init_irq)
186         INITTIME(sa1100_init_time)
187 MACHINE_END
188