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