uart.h revision 331722
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 * NETLOGIC_BSD
29 * $FreeBSD: stable/11/sys/mips/nlm/hal/uart.h 331722 2018-03-29 02:50:57Z eadler $
30 */
31
32#ifndef __XLP_HAL_UART_H__
33#define	__XLP_HAL_UART_H__
34
35/* UART Specific registers */
36#define	UART_RX_DATA		0x00
37#define	UART_TX_DATA		0x00
38
39#define	UART_INT_EN		0x01
40#define	UART_INT_ID		0x02
41#define	UART_FIFO_CTL		0x02
42#define	UART_LINE_CTL		0x03
43#define	UART_MODEM_CTL		0x04
44#define	UART_LINE_STS		0x05
45#define	UART_MODEM_STS		0x06
46
47#define	UART_DIVISOR0		0x00
48#define	UART_DIVISOR1		0x01
49
50#define	BASE_BAUD		(XLP_IO_CLK/16)
51#define	BAUD_DIVISOR(baud)	(BASE_BAUD / baud)
52
53/* LCR mask values */
54#define	LCR_5BITS		0x00
55#define	LCR_6BITS		0x01
56#define	LCR_7BITS		0x02
57#define	LCR_8BITS		0x03
58#define	LCR_STOPB		0x04
59#define	LCR_PENAB		0x08
60#define	LCR_PODD		0x00
61#define	LCR_PEVEN		0x10
62#define	LCR_PONE		0x20
63#define	LCR_PZERO		0x30
64#define	LCR_SBREAK		0x40
65#define	LCR_EFR_ENABLE		0xbf
66#define	LCR_DLAB		0x80
67
68/* MCR mask values */
69#define	MCR_DTR			0x01
70#define	MCR_RTS			0x02
71#define	MCR_DRS			0x04
72#define	MCR_IE			0x08
73#define	MCR_LOOPBACK		0x10
74
75/* FCR mask values */
76#define	FCR_RCV_RST		0x02
77#define	FCR_XMT_RST		0x04
78#define	FCR_RX_LOW		0x00
79#define	FCR_RX_MEDL		0x40
80#define	FCR_RX_MEDH		0x80
81#define	FCR_RX_HIGH		0xc0
82
83/* IER mask values */
84#define	IER_ERXRDY		0x1
85#define	IER_ETXRDY		0x2
86#define	IER_ERLS		0x4
87#define	IER_EMSC		0x8
88
89#if !defined(LOCORE) && !defined(__ASSEMBLY__)
90
91#define	nlm_read_uart_reg(b, r)		nlm_read_reg(b, r)
92#define	nlm_write_uart_reg(b, r, v)	nlm_write_reg(b, r, v)
93#define	nlm_get_uart_pcibase(node, inst)	\
94		nlm_pcicfg_base(XLP_IO_UART_OFFSET(node, inst))
95#define	nlm_get_uart_regbase(node, inst)	\
96			(nlm_get_uart_pcibase(node, inst) + XLP_IO_PCI_HDRSZ)
97
98static inline void
99nlm_uart_set_baudrate(uint64_t base, int baud)
100{
101	uint32_t lcr;
102
103	lcr = nlm_read_uart_reg(base, UART_LINE_CTL);
104
105	/* enable divisor register, and write baud values */
106	nlm_write_uart_reg(base, UART_LINE_CTL, lcr | (1 << 7));
107	nlm_write_uart_reg(base, UART_DIVISOR0,
108			(BAUD_DIVISOR(baud) & 0xff));
109	nlm_write_uart_reg(base, UART_DIVISOR1,
110			((BAUD_DIVISOR(baud) >> 8) & 0xff));
111
112	/* restore default lcr */
113	nlm_write_uart_reg(base, UART_LINE_CTL, lcr);
114}
115
116static inline void
117nlm_uart_outbyte(uint64_t base, char c)
118{
119	uint32_t lsr;
120
121	for (;;) {
122		lsr = nlm_read_uart_reg(base, UART_LINE_STS);
123		if (lsr & 0x20)
124			break;
125	}
126
127	nlm_write_uart_reg(base, UART_TX_DATA, (int)c);
128}
129
130static inline char
131nlm_uart_inbyte(uint64_t base)
132{
133	int data, lsr;
134
135	for (;;) {
136		lsr = nlm_read_uart_reg(base, UART_LINE_STS);
137		if (lsr & 0x80) { /* parity/frame/break-error - push a zero */
138			data = 0;
139			break;
140		}
141		if (lsr & 0x01) {	/* Rx data */
142			data = nlm_read_uart_reg(base, UART_RX_DATA);
143			break;
144		}
145	}
146
147	return (char)data;
148}
149
150static inline int
151nlm_uart_init(uint64_t base, int baud, int databits, int stopbits,
152	int parity, int int_en, int loopback)
153{
154	uint32_t lcr;
155
156	lcr = 0;
157	if (databits >= 8)
158		lcr |= LCR_8BITS;
159	else if (databits == 7)
160		lcr |= LCR_7BITS;
161	else if (databits == 6)
162		lcr |= LCR_6BITS;
163	else
164		lcr |= LCR_5BITS;
165
166	if (stopbits > 1)
167		lcr |= LCR_STOPB;
168
169	lcr |= parity << 3;
170
171	/* setup default lcr */
172	nlm_write_uart_reg(base, UART_LINE_CTL, lcr);
173
174	/* Reset the FIFOs */
175	nlm_write_uart_reg(base, UART_LINE_CTL, FCR_RCV_RST | FCR_XMT_RST);
176
177	nlm_uart_set_baudrate(base, baud);
178
179	if (loopback)
180		nlm_write_uart_reg(base, UART_MODEM_CTL, 0x1f);
181
182	if (int_en)
183		nlm_write_uart_reg(base, UART_INT_EN, IER_ERXRDY | IER_ETXRDY);
184
185	return 0;
186}
187#endif /* !LOCORE && !__ASSEMBLY__ */
188#endif /* __XLP_HAL_UART_H__ */
189