1/*
2 * NS16550 Serial Port
3 * originally from linux source (arch/powerpc/boot/ns16550.h)
4 *
5 * Cleanup and unification
6 * (C) 2009 by Detlev Zundel, DENX Software Engineering GmbH
7 *
8 * modified slightly to
9 * have addresses as offsets from CONFIG_SYS_ISA_BASE
10 * added a few more definitions
11 * added prototypes for ns16550.c
12 * reduced no of com ports to 2
13 * modifications (c) Rob Taylor, Flying Pig Systems. 2000.
14 *
15 * added support for port on 64-bit bus
16 * by Richard Danter (richard.danter@windriver.com), (C) 2005 Wind River Systems
17 */
18
19/*
20 * Note that the following macro magic uses the fact that the compiler
21 * will not allocate storage for arrays of size 0
22 */
23
24#ifndef __ns16550_h
25#define __ns16550_h
26
27#include <linux/types.h>
28
29#if CONFIG_IS_ENABLED(DM_SERIAL) ||  defined(CONFIG_NS16550_DYNAMIC) || \
30	defined(CONFIG_DEBUG_UART)
31/*
32 * For driver model we always use one byte per register, and sort out the
33 * differences in the driver. In the case of CONFIG_NS16550_DYNAMIC we do
34 * similar, and CONFIG_DEBUG_UART is responsible for shifts in its own manner.
35 */
36#define UART_REG(x)	unsigned char x
37#else
38#if !defined(CONFIG_SYS_NS16550_REG_SIZE) || (CONFIG_SYS_NS16550_REG_SIZE == 0)
39#error "Please define NS16550 registers size."
40#elif (CONFIG_SYS_NS16550_REG_SIZE > 0)
41#define UART_REG(x)						   \
42	unsigned char prepad_##x[CONFIG_SYS_NS16550_REG_SIZE - 1]; \
43	unsigned char x;
44#elif (CONFIG_SYS_NS16550_REG_SIZE < 0)
45#define UART_REG(x)							\
46	unsigned char x;						\
47	unsigned char postpad_##x[-CONFIG_SYS_NS16550_REG_SIZE - 1];
48#endif
49#endif /* CONFIG_NS16550_DYNAMIC */
50
51enum ns16550_flags {
52	NS16550_FLAG_IO		= 1 << 0, /* Use I/O access (else mem-mapped) */
53	NS16550_FLAG_ENDIAN	= 1 << 1, /* Use out_le/be_32() */
54	NS16550_FLAG_BE		= 1 << 2, /* Big-endian access (else little) */
55};
56
57/**
58 * struct ns16550_plat - information about a NS16550 port
59 *
60 * @base:		Base register address
61 * @size:		Size of register area in bytes
62 * @reg_width:		IO accesses size of registers (in bytes, 1 or 4)
63 * @reg_shift:		Shift size of registers (0=byte, 1=16bit, 2=32bit...)
64 * @reg_offset:		Offset to start of registers (normally 0)
65 * @clock:		UART base clock speed in Hz
66 * @fcr:		Offset of FCR register (normally UART_FCR_DEFVAL)
67 * @flags:		A few flags (enum ns16550_flags)
68 * @bdf:		PCI slot/function (pci_dev_t)
69 */
70struct ns16550_plat {
71	ulong base;
72	ulong size;
73	int reg_width;
74	int reg_shift;
75	int reg_offset;
76	int clock;
77	u32 fcr;
78	int flags;
79#if defined(CONFIG_PCI) && defined(CONFIG_SPL)
80	int bdf;
81#endif
82};
83
84struct udevice;
85
86struct ns16550 {
87	UART_REG(rbr);		/* 0 */
88	UART_REG(ier);		/* 1 */
89	UART_REG(fcr);		/* 2 */
90	UART_REG(lcr);		/* 3 */
91	UART_REG(mcr);		/* 4 */
92	UART_REG(lsr);		/* 5 */
93	UART_REG(msr);		/* 6 */
94	UART_REG(spr);		/* 7 */
95#ifdef CONFIG_SOC_DA8XX
96	UART_REG(reg8);		/* 8 */
97	UART_REG(reg9);		/* 9 */
98	UART_REG(revid1);	/* A */
99	UART_REG(revid2);	/* B */
100	UART_REG(pwr_mgmt);	/* C */
101	UART_REG(mdr1);		/* D */
102#else
103	UART_REG(mdr1);		/* 8 */
104	UART_REG(reg9);		/* 9 */
105	UART_REG(regA);		/* A */
106	UART_REG(regB);		/* B */
107	UART_REG(regC);		/* C */
108	UART_REG(regD);		/* D */
109	UART_REG(regE);		/* E */
110	UART_REG(uasr);		/* F */
111	UART_REG(scr);		/* 10*/
112	UART_REG(ssr);		/* 11*/
113#endif
114#if CONFIG_IS_ENABLED(DM_SERIAL)
115	struct ns16550_plat *plat;
116#endif
117};
118
119#define thr rbr
120#define iir fcr
121#define dll rbr
122#define dlm ier
123
124/*
125 * These are the definitions for the FIFO Control Register
126 */
127#define UART_FCR_FIFO_EN	0x01 /* Fifo enable */
128#define UART_FCR_CLEAR_RCVR	0x02 /* Clear the RCVR FIFO */
129#define UART_FCR_CLEAR_XMIT	0x04 /* Clear the XMIT FIFO */
130#define UART_FCR_DMA_SELECT	0x08 /* For DMA applications */
131#define UART_FCR_TRIGGER_MASK	0xC0 /* Mask for the FIFO trigger range */
132#define UART_FCR_TRIGGER_1	0x00 /* Mask for trigger set at 1 */
133#define UART_FCR_TRIGGER_4	0x40 /* Mask for trigger set at 4 */
134#define UART_FCR_TRIGGER_8	0x80 /* Mask for trigger set at 8 */
135#define UART_FCR_TRIGGER_14	0xC0 /* Mask for trigger set at 14 */
136
137#define UART_FCR_RXSR		0x02 /* Receiver soft reset */
138#define UART_FCR_TXSR		0x04 /* Transmitter soft reset */
139
140/* Ingenic JZ47xx specific UART-enable bit. */
141#define UART_FCR_UME		0x10
142
143/* Clear & enable FIFOs */
144#define UART_FCR_DEFVAL (UART_FCR_FIFO_EN | \
145			UART_FCR_RXSR |	\
146			UART_FCR_TXSR)
147
148/*
149 * These are the definitions for the Modem Control Register
150 */
151#define UART_MCR_DTR	0x01		/* DTR   */
152#define UART_MCR_RTS	0x02		/* RTS   */
153#define UART_MCR_OUT1	0x04		/* Out 1 */
154#define UART_MCR_OUT2	0x08		/* Out 2 */
155#define UART_MCR_LOOP	0x10		/* Enable loopback test mode */
156#define UART_MCR_AFE	0x20		/* Enable auto-RTS/CTS */
157
158#define UART_MCR_DMA_EN	0x04
159#define UART_MCR_TX_DFR	0x08
160
161/*
162 * These are the definitions for the Line Control Register
163 *
164 * Note: if the word length is 5 bits (UART_LCR_WLEN5), then setting
165 * UART_LCR_STOP will select 1.5 stop bits, not 2 stop bits.
166 */
167#define UART_LCR_WLS_MSK 0x03		/* character length select mask */
168#define UART_LCR_WLS_5	0x00		/* 5 bit character length */
169#define UART_LCR_WLS_6	0x01		/* 6 bit character length */
170#define UART_LCR_WLS_7	0x02		/* 7 bit character length */
171#define UART_LCR_WLS_8	0x03		/* 8 bit character length */
172#define UART_LCR_STB	0x04		/* # stop Bits, off=1, on=1.5 or 2) */
173#define UART_LCR_PEN	0x08		/* Parity eneble */
174#define UART_LCR_EPS	0x10		/* Even Parity Select */
175#define UART_LCR_STKP	0x20		/* Stick Parity */
176#define UART_LCR_SBRK	0x40		/* Set Break */
177#define UART_LCR_BKSE	0x80		/* Bank select enable */
178#define UART_LCR_DLAB	0x80		/* Divisor latch access bit */
179
180/*
181 * These are the definitions for the Line Status Register
182 */
183#define UART_LSR_DR	0x01		/* Data ready */
184#define UART_LSR_OE	0x02		/* Overrun */
185#define UART_LSR_PE	0x04		/* Parity error */
186#define UART_LSR_FE	0x08		/* Framing error */
187#define UART_LSR_BI	0x10		/* Break */
188#define UART_LSR_THRE	0x20		/* Xmit holding register empty */
189#define UART_LSR_TEMT	0x40		/* Xmitter empty */
190#define UART_LSR_ERR	0x80		/* Error */
191
192#define UART_MSR_DCD	0x80		/* Data Carrier Detect */
193#define UART_MSR_RI	0x40		/* Ring Indicator */
194#define UART_MSR_DSR	0x20		/* Data Set Ready */
195#define UART_MSR_CTS	0x10		/* Clear to Send */
196#define UART_MSR_DDCD	0x08		/* Delta DCD */
197#define UART_MSR_TERI	0x04		/* Trailing edge ring indicator */
198#define UART_MSR_DDSR	0x02		/* Delta DSR */
199#define UART_MSR_DCTS	0x01		/* Delta CTS */
200
201/*
202 * These are the definitions for the Interrupt Identification Register
203 */
204#define UART_IIR_NO_INT	0x01	/* No interrupts pending */
205#define UART_IIR_ID	0x06	/* Mask for the interrupt ID */
206
207#define UART_IIR_MSI	0x00	/* Modem status interrupt */
208#define UART_IIR_THRI	0x02	/* Transmitter holding register empty */
209#define UART_IIR_RDI	0x04	/* Receiver data interrupt */
210#define UART_IIR_RLSI	0x06	/* Receiver line status interrupt */
211
212/*
213 * These are the definitions for the Interrupt Enable Register
214 */
215#define UART_IER_MSI	0x08	/* Enable Modem status interrupt */
216#define UART_IER_RLSI	0x04	/* Enable receiver line status interrupt */
217#define UART_IER_THRI	0x02	/* Enable Transmitter holding register int. */
218#define UART_IER_RDI	0x01	/* Enable receiver data interrupt */
219
220/* useful defaults for LCR */
221#define UART_LCR_8N1	0x03
222
223void ns16550_init(struct ns16550 *com_port, int baud_divisor);
224void ns16550_putc(struct ns16550 *com_port, char c);
225char ns16550_getc(struct ns16550 *com_port);
226int ns16550_tstc(struct ns16550 *com_port);
227void ns16550_reinit(struct ns16550 *com_port, int baud_divisor);
228
229/**
230 * ns16550_calc_divisor() - calculate the divisor given clock and baud rate
231 *
232 * Given the UART input clock and required baudrate, calculate the divisor
233 * that should be used.
234 *
235 * @port:	UART port
236 * @clock:	UART input clock speed in Hz
237 * @baudrate:	Required baud rate
238 * Return: baud rate divisor that should be used
239 */
240int ns16550_calc_divisor(struct ns16550 *port, int clock, int baudrate);
241
242/**
243 * ns16550_serial_of_to_plat() - convert DT to platform data
244 *
245 * Decode a device tree node for an ns16550 device. This includes the
246 * register base address and register shift properties. The caller must set
247 * up the clock frequency.
248 *
249 * @dev:	dev to decode platform data for
250 * @return:	0 if OK, -EINVAL on error
251 */
252int ns16550_serial_of_to_plat(struct udevice *dev);
253
254/**
255 * ns16550_serial_probe() - probe a serial port
256 *
257 * This sets up the serial port ready for use, except for the baud rate
258 * Return: 0, or -ve on error
259 */
260int ns16550_serial_probe(struct udevice *dev);
261
262/**
263 * struct ns16550_serial_ops - ns16550 serial operations
264 *
265 * These should be used by the client driver for the driver's 'ops' member
266 */
267extern const struct dm_serial_ops ns16550_serial_ops;
268
269#endif /* __ns16550_h */
270