Merge git://git.infradead.org/mtd-2.6
[linux-2.6] / arch / sh / boards / se / 7751 / setup.c
1 /* 
2  * linux/arch/sh/kernel/setup_7751se.c
3  *
4  * Copyright (C) 2000  Kazumoto Kojima
5  *
6  * Hitachi SolutionEngine Support.
7  *
8  * Modified for 7751 Solution Engine by
9  * Ian da Silva and Jeremy Siegel, 2001.
10  */
11
12 #include <linux/init.h>
13 #include <linux/irq.h>
14
15 #include <linux/hdreg.h>
16 #include <linux/ide.h>
17 #include <asm/io.h>
18 #include <asm/se7751/se7751.h>
19
20 #ifdef CONFIG_SH_KGDB
21 #include <asm/kgdb.h>
22 #endif
23
24 /*
25  * Configure the Super I/O chip
26  */
27 #if 0
28 /* Leftover code from regular Solution Engine, for reference. */
29 /* The SH7751 Solution Engine has a different SuperIO. */
30 static void __init smsc_config(int index, int data)
31 {
32         outb_p(index, INDEX_PORT);
33         outb_p(data, DATA_PORT);
34 }
35
36 static void __init init_smsc(void)
37 {
38         outb_p(CONFIG_ENTER, CONFIG_PORT);
39         outb_p(CONFIG_ENTER, CONFIG_PORT);
40
41         /* FDC */
42         smsc_config(CURRENT_LDN_INDEX, LDN_FDC);
43         smsc_config(ACTIVATE_INDEX, 0x01);
44         smsc_config(IRQ_SELECT_INDEX, 6); /* IRQ6 */
45
46         /* IDE1 */
47         smsc_config(CURRENT_LDN_INDEX, LDN_IDE1);
48         smsc_config(ACTIVATE_INDEX, 0x01);
49         smsc_config(IRQ_SELECT_INDEX, 14); /* IRQ14 */
50
51         /* AUXIO (GPIO): to use IDE1 */
52         smsc_config(CURRENT_LDN_INDEX, LDN_AUXIO);
53         smsc_config(GPIO46_INDEX, 0x00); /* nIOROP */
54         smsc_config(GPIO47_INDEX, 0x00); /* nIOWOP */
55
56         /* COM1 */
57         smsc_config(CURRENT_LDN_INDEX, LDN_COM1);
58         smsc_config(ACTIVATE_INDEX, 0x01);
59         smsc_config(IO_BASE_HI_INDEX, 0x03);
60         smsc_config(IO_BASE_LO_INDEX, 0xf8);
61         smsc_config(IRQ_SELECT_INDEX, 4); /* IRQ4 */
62
63         /* COM2 */
64         smsc_config(CURRENT_LDN_INDEX, LDN_COM2);
65         smsc_config(ACTIVATE_INDEX, 0x01);
66         smsc_config(IO_BASE_HI_INDEX, 0x02);
67         smsc_config(IO_BASE_LO_INDEX, 0xf8);
68         smsc_config(IRQ_SELECT_INDEX, 3); /* IRQ3 */
69
70         /* RTC */
71         smsc_config(CURRENT_LDN_INDEX, LDN_RTC);
72         smsc_config(ACTIVATE_INDEX, 0x01);
73         smsc_config(IRQ_SELECT_INDEX, 8); /* IRQ8 */
74
75         /* XXX: PARPORT, KBD, and MOUSE will come here... */
76         outb_p(CONFIG_EXIT, CONFIG_PORT);
77 }
78 #endif
79
80 const char *get_system_type(void)
81 {
82         return "7751 SolutionEngine";
83 }
84
85 #ifdef CONFIG_SH_KGDB
86 static int kgdb_uart_setup(void);
87 static struct kgdb_sermap kgdb_uart_sermap = 
88 { "ttyS", 0, kgdb_uart_setup, NULL };
89 #endif
90  
91 /*
92  * Initialize the board
93  */
94 void __init platform_setup(void)
95 {
96         /* Call init_smsc() replacement to set up SuperIO. */
97         /* XXX: RTC setting comes here */
98 #ifdef CONFIG_SH_KGDB
99         kgdb_register_sermap(&kgdb_uart_sermap);
100 #endif
101 }
102
103 /*********************************************************************
104  * Currently a hack (e.g. does not interact well w/serial.c, lots of *
105  * hardcoded stuff) but may be useful if SCI/F needs debugging.      *
106  * Mostly copied from x86 code (see files asm-i386/kgdb_local.h and  *
107  * arch/i386/lib/kgdb_serial.c).                                     *
108  *********************************************************************/
109
110 #ifdef CONFIG_SH_KGDB
111 #include <linux/types.h>
112 #include <linux/serial.h>
113 #include <linux/serialP.h>
114 #include <linux/serial_reg.h>
115
116 #define COM1_PORT 0x3f8  /* Base I/O address */
117 #define COM1_IRQ  4      /* IRQ not used yet */
118 #define COM2_PORT 0x2f8  /* Base I/O address */
119 #define COM2_IRQ  3      /* IRQ not used yet */
120
121 #define SB_CLOCK 1843200 /* Serial baud clock */
122 #define SB_BASE (SB_CLOCK/16)
123 #define SB_MCR UART_MCR_OUT2 | UART_MCR_DTR | UART_MCR_RTS
124
125 struct uart_port {
126         int base;
127 };
128 #define UART_NPORTS 2
129 struct uart_port uart_ports[] = {
130         { COM1_PORT },
131         { COM2_PORT },
132 };
133 struct uart_port *kgdb_uart_port;
134
135 #define UART_IN(reg)    inb_p(kgdb_uart_port->base + reg)
136 #define UART_OUT(reg,v) outb_p((v), kgdb_uart_port->base + reg)
137
138 /* Basic read/write functions for the UART */
139 #define UART_LSR_RXCERR    (UART_LSR_BI | UART_LSR_FE | UART_LSR_PE)
140 static int kgdb_uart_getchar(void)
141 {
142         int lsr;
143         int c = -1;
144
145         while (c == -1) {
146                 lsr = UART_IN(UART_LSR);
147                 if (lsr & UART_LSR_DR) 
148                         c = UART_IN(UART_RX);
149                 if ((lsr & UART_LSR_RXCERR))
150                         c = -1;
151         }
152         return c;
153 }
154
155 static void kgdb_uart_putchar(int c)
156 {
157         while ((UART_IN(UART_LSR) & UART_LSR_THRE) == 0)
158                 ;
159         UART_OUT(UART_TX, c);
160 }
161
162 /*
163  * Initialize UART to configured/requested values.
164  * (But we don't interrupts yet, or interact w/serial.c)
165  */
166 static int kgdb_uart_setup(void)
167 {
168         int port;
169         int lcr = 0;
170         int bdiv = 0;
171
172         if (kgdb_portnum >= UART_NPORTS) {
173                 KGDB_PRINTK("uart port %d invalid.\n", kgdb_portnum);
174                 return -1;
175         }
176
177         kgdb_uart_port = &uart_ports[kgdb_portnum];
178
179         /* Init sequence from gdb_hook_interrupt */
180         UART_IN(UART_RX);
181         UART_OUT(UART_IER, 0);
182
183         UART_IN(UART_RX);       /* Serial driver comments say */
184         UART_IN(UART_IIR);      /* this clears interrupt regs */
185         UART_IN(UART_MSR);
186
187         /* Figure basic LCR values */
188         switch (kgdb_bits) {
189         case '7':
190                 lcr |= UART_LCR_WLEN7;
191                 break;
192         default: case '8': 
193                 lcr |= UART_LCR_WLEN8;
194                 break;
195         }
196         switch (kgdb_parity) {
197         case 'O':
198                 lcr |= UART_LCR_PARITY;
199                 break;
200         case 'E':
201                 lcr |= (UART_LCR_PARITY | UART_LCR_EPAR);
202                 break;
203         default: break;
204         }
205
206         /* Figure the baud rate divisor */
207         bdiv = (SB_BASE/kgdb_baud);
208         
209         /* Set the baud rate and LCR values */
210         UART_OUT(UART_LCR, (lcr | UART_LCR_DLAB));
211         UART_OUT(UART_DLL, (bdiv & 0xff));
212         UART_OUT(UART_DLM, ((bdiv >> 8) & 0xff));
213         UART_OUT(UART_LCR, lcr);
214
215         /* Set the MCR */
216         UART_OUT(UART_MCR, SB_MCR);
217
218         /* Turn off FIFOs for now */
219         UART_OUT(UART_FCR, 0);
220
221         /* Setup complete: initialize function pointers */
222         kgdb_getchar = kgdb_uart_getchar;
223         kgdb_putchar = kgdb_uart_putchar;
224
225         return 0;
226 }
227 #endif /* CONFIG_SH_KGDB */