uart.h revision 224110
1/*-
2 * Copyright 2003-2011 Netlogic Microsystems (Netlogic). All rights
3 * reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 *    notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 *    notice, this list of conditions and the following disclaimer in
13 *    the documentation and/or other materials provided with the
14 *    distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY Netlogic Microsystems ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NETLOGIC OR CONTRIBUTORS BE
20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
26 * THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 * $FreeBSD: head/sys/mips/nlm/hal/uart.h 224110 2011-07-16 19:35:44Z jchandra $
29 * NETLOGIC_BSD */
30
31#ifndef __XLP_UART_H__
32#define __XLP_UART_H__
33
34/* UART Specific registers */
35#define XLP_UART_RX_DATA_REG		0x40
36#define XLP_UART_TX_DATA_REG		0x40
37
38#define XLP_UART_INT_EN_REG		0x41
39#define XLP_UART_INT_ID_REG		0x42
40#define XLP_UART_FIFO_CTL_REG		0x42
41#define XLP_UART_LINE_CTL_REG		0x43
42#define XLP_UART_MODEM_CTL_REG		0x44
43#define XLP_UART_LINE_STS_REG		0x45
44#define XLP_UART_MODEM_STS_REG		0x46
45
46#define XLP_UART_DIVISOR0_REG		0x40
47#define XLP_UART_DIVISOR1_REG		0x41
48
49#define XLP_UART_BASE_BAUD		(133000000/16)
50#define XLP_UART_BAUD_DIVISOR(baud)	(XLP_UART_BASE_BAUD / baud)
51
52/* LCR mask values */
53#define LCR_5BITS			0x00
54#define LCR_6BITS			0x01
55#define LCR_7BITS			0x02
56#define LCR_8BITS			0x03
57#define LCR_STOPB			0x04
58#define LCR_PENAB			0x08
59#define LCR_PODD			0x00
60#define LCR_PEVEN			0x10
61#define LCR_PONE			0x20
62#define LCR_PZERO			0x30
63#define LCR_SBREAK			0x40
64#define LCR_EFR_ENABLE			0xbf
65#define LCR_DLAB			0x80
66
67/* MCR mask values */
68#define MCR_DTR				0x01
69#define MCR_RTS				0x02
70#define MCR_DRS				0x04
71#define MCR_IE				0x08
72#define MCR_LOOPBACK			0x10
73
74/* FCR mask values */
75#define FCR_RCV_RST			0x02
76#define FCR_XMT_RST			0x04
77#define FCR_RX_LOW			0x00
78#define FCR_RX_MEDL			0x40
79#define FCR_RX_MEDH			0x80
80#define FCR_RX_HIGH			0xc0
81
82/* IER mask values */
83#define IER_ERXRDY			0x1
84#define IER_ETXRDY			0x2
85#define IER_ERLS			0x4
86#define IER_EMSC			0x8
87
88/* uart IRQ info */
89#define XLP_NODE0_UART0_IRQ		17
90#define XLP_NODE1_UART0_IRQ		18
91#define XLP_NODE2_UART0_IRQ		19
92#define XLP_NODE3_UART0_IRQ		20
93#define XLP_NODE0_UART1_IRQ		21
94#define XLP_NODE1_UART1_IRQ		22
95#define XLP_NODE2_UART1_IRQ		23
96#define XLP_NODE3_UART1_IRQ		24
97
98#if !defined(LOCORE) && !defined(__ASSEMBLY__)
99
100#define	nlm_rdreg_uart(b, r)		nlm_read_reg_kseg(b,r)
101#define	nlm_wreg_uart(b, r, v)		nlm_write_reg_kseg(b,r,v)
102#define nlm_pcibase_uart(node, inst)	nlm_pcicfg_base(XLP_IO_UART_OFFSET(node, inst))
103#define nlm_regbase_uart(node, inst)	nlm_pcibase_uart(node, inst)
104
105static __inline__ void
106nlm_uart_set_baudrate(uint64_t base, int baud)
107{
108	uint32_t lcr;
109
110	lcr = nlm_rdreg_uart(base, XLP_UART_LINE_CTL_REG);
111
112	/* enable divisor register, and write baud values */
113	nlm_wreg_uart(base, XLP_UART_LINE_CTL_REG, lcr | (1 << 7));
114	nlm_wreg_uart(base, XLP_UART_DIVISOR0_REG,
115			(XLP_UART_BAUD_DIVISOR(baud) & 0xff));
116	nlm_wreg_uart(base, XLP_UART_DIVISOR1_REG,
117			((XLP_UART_BAUD_DIVISOR(baud) >> 8) & 0xff));
118
119	/* restore default lcr */
120	nlm_wreg_uart(base, XLP_UART_LINE_CTL_REG, lcr);
121}
122
123static __inline__ void
124nlm_outbyte (uint64_t base, char c)
125{
126	uint32_t lsr;
127
128	for (;;) {
129		lsr = nlm_rdreg_uart(base, XLP_UART_LINE_STS_REG);
130		if (lsr & 0x20) break;
131	}
132
133	nlm_wreg_uart(base, XLP_UART_TX_DATA_REG, (int)c);
134}
135
136static __inline__ char
137nlm_inbyte (uint64_t base)
138{
139	int data, lsr;
140
141	for(;;) {
142		lsr = nlm_rdreg_uart(base, XLP_UART_LINE_STS_REG);
143		if (lsr & 0x80) {	/* parity/frame/break-error - push a zero */
144			data = 0;
145			break;
146		}
147		if (lsr & 0x01) { 	/* Rx data */
148			data = nlm_rdreg_uart(base, XLP_UART_RX_DATA_REG);
149			break;
150		}
151	}
152
153	return (char)data;
154}
155
156static __inline__ int
157nlm_uart_init(uint64_t base, int baud, int databits, int stopbits,
158		int parity, int int_en, int loopback)
159{
160	uint32_t lcr;
161
162	lcr = 0;
163	if (databits >= 8)
164		lcr |= LCR_8BITS;
165	else if (databits == 7)
166		lcr |= LCR_7BITS;
167	else if (databits == 6)
168		lcr |= LCR_6BITS;
169	else
170		lcr |= LCR_5BITS;
171
172	if (stopbits > 1)
173		lcr |= LCR_STOPB;
174
175	lcr |= parity << 3;
176
177	/* setup default lcr */
178	nlm_wreg_uart(base, XLP_UART_LINE_CTL_REG, lcr);
179
180	/* Reset the FIFOs */
181	nlm_wreg_uart(base, XLP_UART_LINE_CTL_REG, FCR_RCV_RST | FCR_XMT_RST);
182
183	nlm_uart_set_baudrate(base, baud);
184
185	if (loopback)
186		nlm_wreg_uart(base, XLP_UART_MODEM_CTL_REG, 0x1f);
187
188	if (int_en)
189		nlm_wreg_uart(base, XLP_UART_INT_EN_REG, IER_ERXRDY | IER_ETXRDY);
190
191	return 0;
192}
193
194#endif /* !LOCORE && !__ASSEMBLY__ */
195#endif /* __XLP_UART_H__ */
196
197