aboutsummaryrefslogtreecommitdiff
path: root/arch/mips/gt64120/ev64120/serialGT.c
blob: 16e34a546e547d0cfe9dc15c1fc04785fb3fc1db (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
/*
 * serialGT.c
 *
 * BRIEF MODULE DESCRIPTION
 *  Low Level Serial Port control for use
 *  with the Galileo EVB64120A MIPS eval board and
 *  its on board two channel 16552 Uart.
 *
 * Copyright (C) 2000 RidgeRun, Inc.
 * Author: RidgeRun, Inc.
 *   glonnon@ridgerun.com, skranz@ridgerun.com, stevej@ridgerun.com
 *
 *  This program is free software; you can redistribute  it and/or modify it
 *  under  the terms of  the GNU General  Public License as published by the
 *  Free Software Foundation;  either version 2 of the  License, or (at your
 *  option) any later version.
 *
 *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
 *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
 *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
 *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
 *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
 *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
 *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 *  You should have received a copy of the  GNU General Public License along
 *  with this program; if not, write  to the Free Software Foundation, Inc.,
 *  675 Mass Ave, Cambridge, MA 02139, USA.
 *
 */

// Note:
//   Serial CHANNELS - 0 is the bottom connector of evb64120A.
//                       (The one that maps to the "B" channel of the
//                       board's uart)
//                     1 is the top connector of evb64120A.
//                       (The one that maps to the "A" channel of the
//                       board's uart)
int DEBUG_CHANNEL = 0;		// See Note Above
int CONSOLE_CHANNEL = 1;	// See Note Above

#define DUART 0xBD000000	/* Base address of Uart. */
#define CHANNELOFFSET 0x20	/* DUART+CHANNELOFFSET gets you to the ChanA
				   register set of the 16552 Uart device.
				   DUART+0 gets you to the ChanB register set.
				 */
#define DUART_DELTA 0x4
#define FIFO_ENABLE 0x07
#define INT_ENABLE  0x04	/* default interrupt mask */

#define RBR 0x00
#define THR 0x00
#define DLL 0x00
#define IER 0x01
#define DLM 0x01
#define IIR 0x02
#define FCR 0x02
#define LCR 0x03
#define MCR 0x04
#define LSR 0x05
#define MSR 0x06
#define SCR 0x07

#define LCR_DLAB 0x80
#define XTAL 1843200
#define LSR_THRE 0x20
#define LSR_BI   0x10
#define LSR_DR   0x01
#define MCR_LOOP 0x10
#define ACCESS_DELAY 0x10000

/******************************
 Routine:
 Description:
 ******************************/
int inreg(int channel, int reg)
{
	int val;
	val =
	    *((volatile unsigned char *) DUART +
	      (channel * CHANNELOFFSET) + (reg * DUART_DELTA));
	return val;
}

/******************************
 Routine:
 Description:
 ******************************/
void outreg(int channel, int reg, unsigned char val)
{
	*((volatile unsigned char *) DUART + (channel * CHANNELOFFSET)
	  + (reg * DUART_DELTA)) = val;
}

/******************************
 Routine:
 Description:
   Initialize the device driver.
 ******************************/
void serial_init(int channel)
{
	/*
	 * Configure active port, (CHANNELOFFSET already set.)
	 *
	 * Set 8 bits, 1 stop bit, no parity.
	 *
	 * LCR<7>       0       divisor latch access bit
	 * LCR<6>       0       break control (1=send break)
	 * LCR<5>       0       stick parity (0=space, 1=mark)
	 * LCR<4>       0       parity even (0=odd, 1=even)
	 * LCR<3>       0       parity enable (1=enabled)
	 * LCR<2>       0       # stop bits (0=1, 1=1.5)
	 * LCR<1:0>     11      bits per character(00=5, 01=6, 10=7, 11=8)
	 */
	outreg(channel, LCR, 0x3);

	outreg(channel, FCR, FIFO_ENABLE);	/* Enable the FIFO */

	outreg(channel, IER, INT_ENABLE);	/* Enable appropriate interrupts */
}

/******************************
 Routine:
 Description:
   Set the baud rate.
 ******************************/
void serial_set(int channel, unsigned long baud)
{
	unsigned char sav_lcr;

	/*
	 * Enable access to the divisor latches by setting DLAB in LCR.
	 *
	 */
	sav_lcr = inreg(channel, LCR);

#if 0
	/*
	 * Set baud rate
	 */
	outreg(channel, LCR, LCR_DLAB | sav_lcr);
	//  outreg(DLL,(XTAL/(16*2*(baud))-2));
	outreg(channel, DLL, XTAL / (16 * baud));
	//  outreg(DLM,(XTAL/(16*2*(baud))-2)>>8);
	outreg(channel, DLM, (XTAL / (16 * baud)) >> 8);
#else
	/*
	 * Note: Set baud rate, hardcoded here for rate of 115200
	 * since became unsure of above "buad rate" algorithm (??).
	 */
	outreg(channel, LCR, 0x83);
	outreg(channel, DLM, 0x00);	// See note above
	outreg(channel, DLL, 0x02);	// See note above.
	outreg(channel, LCR, 0x03);
#endif

	/*
	 * Restore line control register
	 */
	outreg(channel, LCR, sav_lcr);
}


/******************************
 Routine:
 Description:
   Transmit a character.
 ******************************/
void serial_putc(int channel, int c)
{
	while ((inreg(channel, LSR) & LSR_THRE) == 0);
	outreg(channel, THR, c);
}

/******************************
 Routine:
 Description:
    Read a received character if one is
    available.  Return -1 otherwise.
 ******************************/
int serial_getc(int channel)
{
	if (inreg(channel, LSR) & LSR_DR) {
		return inreg(channel, RBR);
	}
	return -1;
}

/******************************
 Routine:
 Description:
   Used by embedded gdb client. (example; gdb-stub.c)
 ******************************/
char getDebugChar()
{
	int val;
	while ((val = serial_getc(DEBUG_CHANNEL)) == -1);	// loop until we get a character in.
	return (char) val;
}

/******************************
 Routine:
 Description:
   Used by embedded gdb target. (example; gdb-stub.c)
 ******************************/
void putDebugChar(char c)
{
	serial_putc(DEBUG_CHANNEL, (int) c);
}