Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
[pandora-kernel.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 void heartbeat_7751se(void);
19 void init_7751se_IRQ(void);
20
21 #ifdef CONFIG_SH_KGDB
22 #include <asm/kgdb.h>
23 static int kgdb_uart_setup(void);
24 static struct kgdb_sermap kgdb_uart_sermap = 
25 { "ttyS", 0, kgdb_uart_setup, NULL };
26 #endif
27  
28 /*
29  * Initialize the board
30  */
31 static void __init sh7751se_setup(char **cmdline_p)
32 {
33         /* Call init_smsc() replacement to set up SuperIO. */
34         /* XXX: RTC setting comes here */
35 #ifdef CONFIG_SH_KGDB
36         kgdb_register_sermap(&kgdb_uart_sermap);
37 #endif
38 }
39
40 /*********************************************************************
41  * Currently a hack (e.g. does not interact well w/serial.c, lots of *
42  * hardcoded stuff) but may be useful if SCI/F needs debugging.      *
43  * Mostly copied from x86 code (see files asm-i386/kgdb_local.h and  *
44  * arch/i386/lib/kgdb_serial.c).                                     *
45  *********************************************************************/
46
47 #ifdef CONFIG_SH_KGDB
48 #include <linux/types.h>
49 #include <linux/serial.h>
50 #include <linux/serialP.h>
51 #include <linux/serial_reg.h>
52
53 #define COM1_PORT 0x3f8  /* Base I/O address */
54 #define COM1_IRQ  4      /* IRQ not used yet */
55 #define COM2_PORT 0x2f8  /* Base I/O address */
56 #define COM2_IRQ  3      /* IRQ not used yet */
57
58 #define SB_CLOCK 1843200 /* Serial baud clock */
59 #define SB_BASE (SB_CLOCK/16)
60 #define SB_MCR UART_MCR_OUT2 | UART_MCR_DTR | UART_MCR_RTS
61
62 struct uart_port {
63         int base;
64 };
65 #define UART_NPORTS 2
66 struct uart_port uart_ports[] = {
67         { COM1_PORT },
68         { COM2_PORT },
69 };
70 struct uart_port *kgdb_uart_port;
71
72 #define UART_IN(reg)    inb_p(kgdb_uart_port->base + reg)
73 #define UART_OUT(reg,v) outb_p((v), kgdb_uart_port->base + reg)
74
75 /* Basic read/write functions for the UART */
76 #define UART_LSR_RXCERR    (UART_LSR_BI | UART_LSR_FE | UART_LSR_PE)
77 static int kgdb_uart_getchar(void)
78 {
79         int lsr;
80         int c = -1;
81
82         while (c == -1) {
83                 lsr = UART_IN(UART_LSR);
84                 if (lsr & UART_LSR_DR) 
85                         c = UART_IN(UART_RX);
86                 if ((lsr & UART_LSR_RXCERR))
87                         c = -1;
88         }
89         return c;
90 }
91
92 static void kgdb_uart_putchar(int c)
93 {
94         while ((UART_IN(UART_LSR) & UART_LSR_THRE) == 0)
95                 ;
96         UART_OUT(UART_TX, c);
97 }
98
99 /*
100  * Initialize UART to configured/requested values.
101  * (But we don't interrupts yet, or interact w/serial.c)
102  */
103 static int kgdb_uart_setup(void)
104 {
105         int port;
106         int lcr = 0;
107         int bdiv = 0;
108
109         if (kgdb_portnum >= UART_NPORTS) {
110                 KGDB_PRINTK("uart port %d invalid.\n", kgdb_portnum);
111                 return -1;
112         }
113
114         kgdb_uart_port = &uart_ports[kgdb_portnum];
115
116         /* Init sequence from gdb_hook_interrupt */
117         UART_IN(UART_RX);
118         UART_OUT(UART_IER, 0);
119
120         UART_IN(UART_RX);       /* Serial driver comments say */
121         UART_IN(UART_IIR);      /* this clears interrupt regs */
122         UART_IN(UART_MSR);
123
124         /* Figure basic LCR values */
125         switch (kgdb_bits) {
126         case '7':
127                 lcr |= UART_LCR_WLEN7;
128                 break;
129         default: case '8': 
130                 lcr |= UART_LCR_WLEN8;
131                 break;
132         }
133         switch (kgdb_parity) {
134         case 'O':
135                 lcr |= UART_LCR_PARITY;
136                 break;
137         case 'E':
138                 lcr |= (UART_LCR_PARITY | UART_LCR_EPAR);
139                 break;
140         default: break;
141         }
142
143         /* Figure the baud rate divisor */
144         bdiv = (SB_BASE/kgdb_baud);
145         
146         /* Set the baud rate and LCR values */
147         UART_OUT(UART_LCR, (lcr | UART_LCR_DLAB));
148         UART_OUT(UART_DLL, (bdiv & 0xff));
149         UART_OUT(UART_DLM, ((bdiv >> 8) & 0xff));
150         UART_OUT(UART_LCR, lcr);
151
152         /* Set the MCR */
153         UART_OUT(UART_MCR, SB_MCR);
154
155         /* Turn off FIFOs for now */
156         UART_OUT(UART_FCR, 0);
157
158         /* Setup complete: initialize function pointers */
159         kgdb_getchar = kgdb_uart_getchar;
160         kgdb_putchar = kgdb_uart_putchar;
161
162         return 0;
163 }
164 #endif /* CONFIG_SH_KGDB */
165
166
167 /*
168  * The Machine Vector
169  */
170
171 struct sh_machine_vector mv_7751se __initmv = {
172         .mv_name                = "7751 SolutionEngine",
173         .mv_setup               = sh7751se_setup,
174         .mv_nr_irqs             = 72,
175
176         .mv_inb                 = sh7751se_inb,
177         .mv_inw                 = sh7751se_inw,
178         .mv_inl                 = sh7751se_inl,
179         .mv_outb                = sh7751se_outb,
180         .mv_outw                = sh7751se_outw,
181         .mv_outl                = sh7751se_outl,
182
183         .mv_inb_p               = sh7751se_inb_p,
184         .mv_inw_p               = sh7751se_inw,
185         .mv_inl_p               = sh7751se_inl,
186         .mv_outb_p              = sh7751se_outb_p,
187         .mv_outw_p              = sh7751se_outw,
188         .mv_outl_p              = sh7751se_outl,
189
190         .mv_insl                = sh7751se_insl,
191         .mv_outsl               = sh7751se_outsl,
192
193         .mv_init_irq            = init_7751se_IRQ,
194 #ifdef CONFIG_HEARTBEAT
195         .mv_heartbeat           = heartbeat_7751se,
196 #endif
197 };
198 ALIAS_MV(7751se)