blob: 8b693105893c036726e6617ef9f535653296715e [file] [log] [blame]
Paul Mundt373e68b2006-09-27 15:41:24 +09001/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07002 * 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
Linus Torvalds1da177e2005-04-16 15:20:36 -070012#include <linux/init.h>
13#include <linux/irq.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070014#include <linux/ide.h>
15#include <asm/io.h>
Paul Mundt373e68b2006-09-27 15:41:24 +090016#include <asm/se7751.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070017
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. */
28static void __init smsc_config(int index, int data)
29{
30 outb_p(index, INDEX_PORT);
31 outb_p(data, DATA_PORT);
32}
33
34static 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
78const char *get_system_type(void)
79{
80 return "7751 SolutionEngine";
81}
82
83#ifdef CONFIG_SH_KGDB
84static int kgdb_uart_setup(void);
85static struct kgdb_sermap kgdb_uart_sermap =
86{ "ttyS", 0, kgdb_uart_setup, NULL };
87#endif
88
89/*
90 * Initialize the board
91 */
92void __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
123struct uart_port {
124 int base;
125};
126#define UART_NPORTS 2
127struct uart_port uart_ports[] = {
128 { COM1_PORT },
129 { COM2_PORT },
130};
131struct 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)
138static 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
153static 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 */
164static 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 */