blob: 73e826310ba8748379395871c663681cbfa99939 [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
Paul Mundt2c7834a2006-09-27 18:17:31 +090018void heartbeat_7751se(void);
19void init_7751se_IRQ(void);
20
Linus Torvalds1da177e2005-04-16 15:20:36 -070021#ifdef CONFIG_SH_KGDB
22#include <asm/kgdb.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070023static int kgdb_uart_setup(void);
24static struct kgdb_sermap kgdb_uart_sermap =
25{ "ttyS", 0, kgdb_uart_setup, NULL };
26#endif
27
28/*
29 * Initialize the board
30 */
Paul Mundt2c7834a2006-09-27 18:17:31 +090031static void __init sh7751se_setup(char **cmdline_p)
Linus Torvalds1da177e2005-04-16 15:20:36 -070032{
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
62struct uart_port {
63 int base;
64};
65#define UART_NPORTS 2
66struct uart_port uart_ports[] = {
67 { COM1_PORT },
68 { COM2_PORT },
69};
70struct 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)
77static 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
92static 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 */
103static 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 */
Paul Mundt2c7834a2006-09-27 18:17:31 +0900165
166
167/*
168 * The Machine Vector
169 */
170
171struct 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};
198ALIAS_MV(7751se)