1/*
2 * serialGT.c
3 *
4 * BRIEF MODULE DESCRIPTION
5 *  Low Level Serial Port control for use
6 *  with the Galileo EVB64120A MIPS eval board and
7 *  its on board two channel 16552 Uart.
8 *
9 * Copyright (C) 2000 RidgeRun, Inc.
10 * Author: RidgeRun, Inc.
11 *   glonnon@ridgerun.com, skranz@ridgerun.com, stevej@ridgerun.com
12 *
13 *  This program is free software; you can redistribute  it and/or modify it
14 *  under  the terms of  the GNU General  Public License as published by the
15 *  Free Software Foundation;  either version 2 of the  License, or (at your
16 *  option) any later version.
17 *
18 *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
19 *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
20 *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
21 *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
22 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
24 *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
25 *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
26 *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 *
29 *  You should have received a copy of the  GNU General Public License along
30 *  with this program; if not, write  to the Free Software Foundation, Inc.,
31 *  675 Mass Ave, Cambridge, MA 02139, USA.
32 *
33 */
34
35// Note:
36//   Serial CHANNELS - 0 is the bottom connector of evb64120A.
37//                       (The one that maps to the "B" channel of the
38//                       board's uart)
39//                     1 is the top connector of evb64120A.
40//                       (The one that maps to the "A" channel of the
41//                       board's uart)
42int DEBUG_CHANNEL = 0;		// See Note Above
43int CONSOLE_CHANNEL = 1;	// See Note Above
44
45#define DUART 0xBD000000	/* Base address of Uart. */
46#define CHANNELOFFSET 0x20	/* DUART+CHANNELOFFSET gets you to the ChanA
47				   register set of the 16552 Uart device.
48				   DUART+0 gets you to the ChanB register set.
49				 */
50#define DUART_DELTA 0x4
51#define FIFO_ENABLE 0x07
52#define INT_ENABLE  0x04	/* default interrupt mask */
53
54#define RBR 0x00
55#define THR 0x00
56#define DLL 0x00
57#define IER 0x01
58#define DLM 0x01
59#define IIR 0x02
60#define FCR 0x02
61#define LCR 0x03
62#define MCR 0x04
63#define LSR 0x05
64#define MSR 0x06
65#define SCR 0x07
66
67#define LCR_DLAB 0x80
68#define XTAL 1843200
69#define LSR_THRE 0x20
70#define LSR_BI   0x10
71#define LSR_DR   0x01
72#define MCR_LOOP 0x10
73#define ACCESS_DELAY 0x10000
74
75/******************************
76 Routine:
77 Description:
78 ******************************/
79int inreg(int channel, int reg)
80{
81	int val;
82	val =
83	    *((volatile unsigned char *) DUART +
84	      (channel * CHANNELOFFSET) + (reg * DUART_DELTA));
85	return val;
86}
87
88/******************************
89 Routine:
90 Description:
91 ******************************/
92void outreg(int channel, int reg, unsigned char val)
93{
94	*((volatile unsigned char *) DUART + (channel * CHANNELOFFSET)
95	  + (reg * DUART_DELTA)) = val;
96}
97
98/******************************
99 Routine:
100 Description:
101   Initialize the device driver.
102 ******************************/
103void serial_init(int channel)
104{
105	/*
106	 * Configure active port, (CHANNELOFFSET already set.)
107	 *
108	 * Set 8 bits, 1 stop bit, no parity.
109	 *
110	 * LCR<7>       0       divisor latch access bit
111	 * LCR<6>       0       break control (1=send break)
112	 * LCR<5>       0       stick parity (0=space, 1=mark)
113	 * LCR<4>       0       parity even (0=odd, 1=even)
114	 * LCR<3>       0       parity enable (1=enabled)
115	 * LCR<2>       0       # stop bits (0=1, 1=1.5)
116	 * LCR<1:0>     11      bits per character(00=5, 01=6, 10=7, 11=8)
117	 */
118	outreg(channel, LCR, 0x3);
119
120	outreg(channel, FCR, FIFO_ENABLE);	/* Enable the FIFO */
121
122	outreg(channel, IER, INT_ENABLE);	/* Enable appropriate interrupts */
123}
124
125/******************************
126 Routine:
127 Description:
128   Set the baud rate.
129 ******************************/
130void serial_set(int channel, unsigned long baud)
131{
132	unsigned char sav_lcr;
133
134	/*
135	 * Enable access to the divisor latches by setting DLAB in LCR.
136	 *
137	 */
138	sav_lcr = inreg(channel, LCR);
139
140	/*
141	 * Note: Set baud rate, hardcoded here for rate of 115200
142	 * since became unsure of above "buad rate" algorithm (??).
143	 */
144	outreg(channel, LCR, 0x83);
145	outreg(channel, DLM, 0x00);	// See note above
146	outreg(channel, DLL, 0x02);	// See note above.
147	outreg(channel, LCR, 0x03);
148
149	/*
150	 * Restore line control register
151	 */
152	outreg(channel, LCR, sav_lcr);
153}
154
155
156/******************************
157 Routine:
158 Description:
159   Transmit a character.
160 ******************************/
161void serial_putc(int channel, int c)
162{
163	while ((inreg(channel, LSR) & LSR_THRE) == 0);
164	outreg(channel, THR, c);
165}
166
167/******************************
168 Routine:
169 Description:
170    Read a received character if one is
171    available.  Return -1 otherwise.
172 ******************************/
173int serial_getc(int channel)
174{
175	if (inreg(channel, LSR) & LSR_DR) {
176		return inreg(channel, RBR);
177	}
178	return -1;
179}
180
181/******************************
182 Routine:
183 Description:
184   Used by embedded gdb client. (example; gdb-stub.c)
185 ******************************/
186char getDebugChar()
187{
188	int val;
189	while ((val = serial_getc(DEBUG_CHANNEL)) == -1);	// loop until we get a character in.
190	return (char) val;
191}
192
193/******************************
194 Routine:
195 Description:
196   Used by embedded gdb target. (example; gdb-stub.c)
197 ******************************/
198void putDebugChar(char c)
199{
200	serial_putc(DEBUG_CHANNEL, (int) c);
201}
202