xref: /OK3568_Linux_fs/kernel/drivers/tty/serial/mvebu-uart.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0+
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun * ***************************************************************************
4*4882a593Smuzhiyun * Marvell Armada-3700 Serial Driver
5*4882a593Smuzhiyun * Author: Wilson Ding <dingwei@marvell.com>
6*4882a593Smuzhiyun * Copyright (C) 2015 Marvell International Ltd.
7*4882a593Smuzhiyun * ***************************************************************************
8*4882a593Smuzhiyun */
9*4882a593Smuzhiyun 
10*4882a593Smuzhiyun #include <linux/clk.h>
11*4882a593Smuzhiyun #include <linux/console.h>
12*4882a593Smuzhiyun #include <linux/delay.h>
13*4882a593Smuzhiyun #include <linux/device.h>
14*4882a593Smuzhiyun #include <linux/init.h>
15*4882a593Smuzhiyun #include <linux/io.h>
16*4882a593Smuzhiyun #include <linux/iopoll.h>
17*4882a593Smuzhiyun #include <linux/of.h>
18*4882a593Smuzhiyun #include <linux/of_address.h>
19*4882a593Smuzhiyun #include <linux/of_device.h>
20*4882a593Smuzhiyun #include <linux/of_irq.h>
21*4882a593Smuzhiyun #include <linux/of_platform.h>
22*4882a593Smuzhiyun #include <linux/platform_device.h>
23*4882a593Smuzhiyun #include <linux/serial.h>
24*4882a593Smuzhiyun #include <linux/serial_core.h>
25*4882a593Smuzhiyun #include <linux/slab.h>
26*4882a593Smuzhiyun #include <linux/tty.h>
27*4882a593Smuzhiyun #include <linux/tty_flip.h>
28*4882a593Smuzhiyun 
29*4882a593Smuzhiyun /* Register Map */
30*4882a593Smuzhiyun #define UART_STD_RBR		0x00
31*4882a593Smuzhiyun #define UART_EXT_RBR		0x18
32*4882a593Smuzhiyun 
33*4882a593Smuzhiyun #define UART_STD_TSH		0x04
34*4882a593Smuzhiyun #define UART_EXT_TSH		0x1C
35*4882a593Smuzhiyun 
36*4882a593Smuzhiyun #define UART_STD_CTRL1		0x08
37*4882a593Smuzhiyun #define UART_EXT_CTRL1		0x04
38*4882a593Smuzhiyun #define  CTRL_SOFT_RST		BIT(31)
39*4882a593Smuzhiyun #define  CTRL_TXFIFO_RST	BIT(15)
40*4882a593Smuzhiyun #define  CTRL_RXFIFO_RST	BIT(14)
41*4882a593Smuzhiyun #define  CTRL_SND_BRK_SEQ	BIT(11)
42*4882a593Smuzhiyun #define  CTRL_BRK_DET_INT	BIT(3)
43*4882a593Smuzhiyun #define  CTRL_FRM_ERR_INT	BIT(2)
44*4882a593Smuzhiyun #define  CTRL_PAR_ERR_INT	BIT(1)
45*4882a593Smuzhiyun #define  CTRL_OVR_ERR_INT	BIT(0)
46*4882a593Smuzhiyun #define  CTRL_BRK_INT		(CTRL_BRK_DET_INT | CTRL_FRM_ERR_INT | \
47*4882a593Smuzhiyun 				CTRL_PAR_ERR_INT | CTRL_OVR_ERR_INT)
48*4882a593Smuzhiyun 
49*4882a593Smuzhiyun #define UART_STD_CTRL2		UART_STD_CTRL1
50*4882a593Smuzhiyun #define UART_EXT_CTRL2		0x20
51*4882a593Smuzhiyun #define  CTRL_STD_TX_RDY_INT	BIT(5)
52*4882a593Smuzhiyun #define  CTRL_EXT_TX_RDY_INT	BIT(6)
53*4882a593Smuzhiyun #define  CTRL_STD_RX_RDY_INT	BIT(4)
54*4882a593Smuzhiyun #define  CTRL_EXT_RX_RDY_INT	BIT(5)
55*4882a593Smuzhiyun 
56*4882a593Smuzhiyun #define UART_STAT		0x0C
57*4882a593Smuzhiyun #define  STAT_TX_FIFO_EMP	BIT(13)
58*4882a593Smuzhiyun #define  STAT_TX_FIFO_FUL	BIT(11)
59*4882a593Smuzhiyun #define  STAT_TX_EMP		BIT(6)
60*4882a593Smuzhiyun #define  STAT_STD_TX_RDY	BIT(5)
61*4882a593Smuzhiyun #define  STAT_EXT_TX_RDY	BIT(15)
62*4882a593Smuzhiyun #define  STAT_STD_RX_RDY	BIT(4)
63*4882a593Smuzhiyun #define  STAT_EXT_RX_RDY	BIT(14)
64*4882a593Smuzhiyun #define  STAT_BRK_DET		BIT(3)
65*4882a593Smuzhiyun #define  STAT_FRM_ERR		BIT(2)
66*4882a593Smuzhiyun #define  STAT_PAR_ERR		BIT(1)
67*4882a593Smuzhiyun #define  STAT_OVR_ERR		BIT(0)
68*4882a593Smuzhiyun #define  STAT_BRK_ERR		(STAT_BRK_DET | STAT_FRM_ERR \
69*4882a593Smuzhiyun 				 | STAT_PAR_ERR | STAT_OVR_ERR)
70*4882a593Smuzhiyun 
71*4882a593Smuzhiyun #define UART_BRDV		0x10
72*4882a593Smuzhiyun #define  BRDV_BAUD_MASK         0x3FF
73*4882a593Smuzhiyun 
74*4882a593Smuzhiyun #define UART_OSAMP		0x14
75*4882a593Smuzhiyun #define  OSAMP_DEFAULT_DIVISOR	16
76*4882a593Smuzhiyun #define  OSAMP_DIVISORS_MASK	0x3F3F3F3F
77*4882a593Smuzhiyun 
78*4882a593Smuzhiyun #define MVEBU_NR_UARTS		2
79*4882a593Smuzhiyun 
80*4882a593Smuzhiyun #define MVEBU_UART_TYPE		"mvebu-uart"
81*4882a593Smuzhiyun #define DRIVER_NAME		"mvebu_serial"
82*4882a593Smuzhiyun 
83*4882a593Smuzhiyun enum {
84*4882a593Smuzhiyun 	/* Either there is only one summed IRQ... */
85*4882a593Smuzhiyun 	UART_IRQ_SUM = 0,
86*4882a593Smuzhiyun 	/* ...or there are two separate IRQ for RX and TX */
87*4882a593Smuzhiyun 	UART_RX_IRQ = 0,
88*4882a593Smuzhiyun 	UART_TX_IRQ,
89*4882a593Smuzhiyun 	UART_IRQ_COUNT
90*4882a593Smuzhiyun };
91*4882a593Smuzhiyun 
92*4882a593Smuzhiyun /* Diverging register offsets */
93*4882a593Smuzhiyun struct uart_regs_layout {
94*4882a593Smuzhiyun 	unsigned int rbr;
95*4882a593Smuzhiyun 	unsigned int tsh;
96*4882a593Smuzhiyun 	unsigned int ctrl;
97*4882a593Smuzhiyun 	unsigned int intr;
98*4882a593Smuzhiyun };
99*4882a593Smuzhiyun 
100*4882a593Smuzhiyun /* Diverging flags */
101*4882a593Smuzhiyun struct uart_flags {
102*4882a593Smuzhiyun 	unsigned int ctrl_tx_rdy_int;
103*4882a593Smuzhiyun 	unsigned int ctrl_rx_rdy_int;
104*4882a593Smuzhiyun 	unsigned int stat_tx_rdy;
105*4882a593Smuzhiyun 	unsigned int stat_rx_rdy;
106*4882a593Smuzhiyun };
107*4882a593Smuzhiyun 
108*4882a593Smuzhiyun /* Driver data, a structure for each UART port */
109*4882a593Smuzhiyun struct mvebu_uart_driver_data {
110*4882a593Smuzhiyun 	bool is_ext;
111*4882a593Smuzhiyun 	struct uart_regs_layout regs;
112*4882a593Smuzhiyun 	struct uart_flags flags;
113*4882a593Smuzhiyun };
114*4882a593Smuzhiyun 
115*4882a593Smuzhiyun /* Saved registers during suspend */
116*4882a593Smuzhiyun struct mvebu_uart_pm_regs {
117*4882a593Smuzhiyun 	unsigned int rbr;
118*4882a593Smuzhiyun 	unsigned int tsh;
119*4882a593Smuzhiyun 	unsigned int ctrl;
120*4882a593Smuzhiyun 	unsigned int intr;
121*4882a593Smuzhiyun 	unsigned int stat;
122*4882a593Smuzhiyun 	unsigned int brdv;
123*4882a593Smuzhiyun 	unsigned int osamp;
124*4882a593Smuzhiyun };
125*4882a593Smuzhiyun 
126*4882a593Smuzhiyun /* MVEBU UART driver structure */
127*4882a593Smuzhiyun struct mvebu_uart {
128*4882a593Smuzhiyun 	struct uart_port *port;
129*4882a593Smuzhiyun 	struct clk *clk;
130*4882a593Smuzhiyun 	int irq[UART_IRQ_COUNT];
131*4882a593Smuzhiyun 	unsigned char __iomem *nb;
132*4882a593Smuzhiyun 	struct mvebu_uart_driver_data *data;
133*4882a593Smuzhiyun #if defined(CONFIG_PM)
134*4882a593Smuzhiyun 	struct mvebu_uart_pm_regs pm_regs;
135*4882a593Smuzhiyun #endif /* CONFIG_PM */
136*4882a593Smuzhiyun };
137*4882a593Smuzhiyun 
to_mvuart(struct uart_port * port)138*4882a593Smuzhiyun static struct mvebu_uart *to_mvuart(struct uart_port *port)
139*4882a593Smuzhiyun {
140*4882a593Smuzhiyun 	return (struct mvebu_uart *)port->private_data;
141*4882a593Smuzhiyun }
142*4882a593Smuzhiyun 
143*4882a593Smuzhiyun #define IS_EXTENDED(port) (to_mvuart(port)->data->is_ext)
144*4882a593Smuzhiyun 
145*4882a593Smuzhiyun #define UART_RBR(port) (to_mvuart(port)->data->regs.rbr)
146*4882a593Smuzhiyun #define UART_TSH(port) (to_mvuart(port)->data->regs.tsh)
147*4882a593Smuzhiyun #define UART_CTRL(port) (to_mvuart(port)->data->regs.ctrl)
148*4882a593Smuzhiyun #define UART_INTR(port) (to_mvuart(port)->data->regs.intr)
149*4882a593Smuzhiyun 
150*4882a593Smuzhiyun #define CTRL_TX_RDY_INT(port) (to_mvuart(port)->data->flags.ctrl_tx_rdy_int)
151*4882a593Smuzhiyun #define CTRL_RX_RDY_INT(port) (to_mvuart(port)->data->flags.ctrl_rx_rdy_int)
152*4882a593Smuzhiyun #define STAT_TX_RDY(port) (to_mvuart(port)->data->flags.stat_tx_rdy)
153*4882a593Smuzhiyun #define STAT_RX_RDY(port) (to_mvuart(port)->data->flags.stat_rx_rdy)
154*4882a593Smuzhiyun 
155*4882a593Smuzhiyun static struct uart_port mvebu_uart_ports[MVEBU_NR_UARTS];
156*4882a593Smuzhiyun 
157*4882a593Smuzhiyun /* Core UART Driver Operations */
mvebu_uart_tx_empty(struct uart_port * port)158*4882a593Smuzhiyun static unsigned int mvebu_uart_tx_empty(struct uart_port *port)
159*4882a593Smuzhiyun {
160*4882a593Smuzhiyun 	unsigned long flags;
161*4882a593Smuzhiyun 	unsigned int st;
162*4882a593Smuzhiyun 
163*4882a593Smuzhiyun 	spin_lock_irqsave(&port->lock, flags);
164*4882a593Smuzhiyun 	st = readl(port->membase + UART_STAT);
165*4882a593Smuzhiyun 	spin_unlock_irqrestore(&port->lock, flags);
166*4882a593Smuzhiyun 
167*4882a593Smuzhiyun 	return (st & STAT_TX_EMP) ? TIOCSER_TEMT : 0;
168*4882a593Smuzhiyun }
169*4882a593Smuzhiyun 
mvebu_uart_get_mctrl(struct uart_port * port)170*4882a593Smuzhiyun static unsigned int mvebu_uart_get_mctrl(struct uart_port *port)
171*4882a593Smuzhiyun {
172*4882a593Smuzhiyun 	return TIOCM_CTS | TIOCM_DSR | TIOCM_CAR;
173*4882a593Smuzhiyun }
174*4882a593Smuzhiyun 
mvebu_uart_set_mctrl(struct uart_port * port,unsigned int mctrl)175*4882a593Smuzhiyun static void mvebu_uart_set_mctrl(struct uart_port *port,
176*4882a593Smuzhiyun 				 unsigned int mctrl)
177*4882a593Smuzhiyun {
178*4882a593Smuzhiyun /*
179*4882a593Smuzhiyun  * Even if we do not support configuring the modem control lines, this
180*4882a593Smuzhiyun  * function must be proided to the serial core
181*4882a593Smuzhiyun  */
182*4882a593Smuzhiyun }
183*4882a593Smuzhiyun 
mvebu_uart_stop_tx(struct uart_port * port)184*4882a593Smuzhiyun static void mvebu_uart_stop_tx(struct uart_port *port)
185*4882a593Smuzhiyun {
186*4882a593Smuzhiyun 	unsigned int ctl = readl(port->membase + UART_INTR(port));
187*4882a593Smuzhiyun 
188*4882a593Smuzhiyun 	ctl &= ~CTRL_TX_RDY_INT(port);
189*4882a593Smuzhiyun 	writel(ctl, port->membase + UART_INTR(port));
190*4882a593Smuzhiyun }
191*4882a593Smuzhiyun 
mvebu_uart_start_tx(struct uart_port * port)192*4882a593Smuzhiyun static void mvebu_uart_start_tx(struct uart_port *port)
193*4882a593Smuzhiyun {
194*4882a593Smuzhiyun 	unsigned int ctl;
195*4882a593Smuzhiyun 	struct circ_buf *xmit = &port->state->xmit;
196*4882a593Smuzhiyun 
197*4882a593Smuzhiyun 	if (IS_EXTENDED(port) && !uart_circ_empty(xmit)) {
198*4882a593Smuzhiyun 		writel(xmit->buf[xmit->tail], port->membase + UART_TSH(port));
199*4882a593Smuzhiyun 		xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
200*4882a593Smuzhiyun 		port->icount.tx++;
201*4882a593Smuzhiyun 	}
202*4882a593Smuzhiyun 
203*4882a593Smuzhiyun 	ctl = readl(port->membase + UART_INTR(port));
204*4882a593Smuzhiyun 	ctl |= CTRL_TX_RDY_INT(port);
205*4882a593Smuzhiyun 	writel(ctl, port->membase + UART_INTR(port));
206*4882a593Smuzhiyun }
207*4882a593Smuzhiyun 
mvebu_uart_stop_rx(struct uart_port * port)208*4882a593Smuzhiyun static void mvebu_uart_stop_rx(struct uart_port *port)
209*4882a593Smuzhiyun {
210*4882a593Smuzhiyun 	unsigned int ctl;
211*4882a593Smuzhiyun 
212*4882a593Smuzhiyun 	ctl = readl(port->membase + UART_CTRL(port));
213*4882a593Smuzhiyun 	ctl &= ~CTRL_BRK_INT;
214*4882a593Smuzhiyun 	writel(ctl, port->membase + UART_CTRL(port));
215*4882a593Smuzhiyun 
216*4882a593Smuzhiyun 	ctl = readl(port->membase + UART_INTR(port));
217*4882a593Smuzhiyun 	ctl &= ~CTRL_RX_RDY_INT(port);
218*4882a593Smuzhiyun 	writel(ctl, port->membase + UART_INTR(port));
219*4882a593Smuzhiyun }
220*4882a593Smuzhiyun 
mvebu_uart_break_ctl(struct uart_port * port,int brk)221*4882a593Smuzhiyun static void mvebu_uart_break_ctl(struct uart_port *port, int brk)
222*4882a593Smuzhiyun {
223*4882a593Smuzhiyun 	unsigned int ctl;
224*4882a593Smuzhiyun 	unsigned long flags;
225*4882a593Smuzhiyun 
226*4882a593Smuzhiyun 	spin_lock_irqsave(&port->lock, flags);
227*4882a593Smuzhiyun 	ctl = readl(port->membase + UART_CTRL(port));
228*4882a593Smuzhiyun 	if (brk == -1)
229*4882a593Smuzhiyun 		ctl |= CTRL_SND_BRK_SEQ;
230*4882a593Smuzhiyun 	else
231*4882a593Smuzhiyun 		ctl &= ~CTRL_SND_BRK_SEQ;
232*4882a593Smuzhiyun 	writel(ctl, port->membase + UART_CTRL(port));
233*4882a593Smuzhiyun 	spin_unlock_irqrestore(&port->lock, flags);
234*4882a593Smuzhiyun }
235*4882a593Smuzhiyun 
mvebu_uart_rx_chars(struct uart_port * port,unsigned int status)236*4882a593Smuzhiyun static void mvebu_uart_rx_chars(struct uart_port *port, unsigned int status)
237*4882a593Smuzhiyun {
238*4882a593Smuzhiyun 	struct tty_port *tport = &port->state->port;
239*4882a593Smuzhiyun 	unsigned char ch = 0;
240*4882a593Smuzhiyun 	char flag = 0;
241*4882a593Smuzhiyun 	int ret;
242*4882a593Smuzhiyun 
243*4882a593Smuzhiyun 	do {
244*4882a593Smuzhiyun 		if (status & STAT_RX_RDY(port)) {
245*4882a593Smuzhiyun 			ch = readl(port->membase + UART_RBR(port));
246*4882a593Smuzhiyun 			ch &= 0xff;
247*4882a593Smuzhiyun 			flag = TTY_NORMAL;
248*4882a593Smuzhiyun 			port->icount.rx++;
249*4882a593Smuzhiyun 
250*4882a593Smuzhiyun 			if (status & STAT_PAR_ERR)
251*4882a593Smuzhiyun 				port->icount.parity++;
252*4882a593Smuzhiyun 		}
253*4882a593Smuzhiyun 
254*4882a593Smuzhiyun 		/*
255*4882a593Smuzhiyun 		 * For UART2, error bits are not cleared on buffer read.
256*4882a593Smuzhiyun 		 * This causes interrupt loop and system hang.
257*4882a593Smuzhiyun 		 */
258*4882a593Smuzhiyun 		if (IS_EXTENDED(port) && (status & STAT_BRK_ERR)) {
259*4882a593Smuzhiyun 			ret = readl(port->membase + UART_STAT);
260*4882a593Smuzhiyun 			ret |= STAT_BRK_ERR;
261*4882a593Smuzhiyun 			writel(ret, port->membase + UART_STAT);
262*4882a593Smuzhiyun 		}
263*4882a593Smuzhiyun 
264*4882a593Smuzhiyun 		if (status & STAT_BRK_DET) {
265*4882a593Smuzhiyun 			port->icount.brk++;
266*4882a593Smuzhiyun 			status &= ~(STAT_FRM_ERR | STAT_PAR_ERR);
267*4882a593Smuzhiyun 			if (uart_handle_break(port))
268*4882a593Smuzhiyun 				goto ignore_char;
269*4882a593Smuzhiyun 		}
270*4882a593Smuzhiyun 
271*4882a593Smuzhiyun 		if (status & STAT_OVR_ERR)
272*4882a593Smuzhiyun 			port->icount.overrun++;
273*4882a593Smuzhiyun 
274*4882a593Smuzhiyun 		if (status & STAT_FRM_ERR)
275*4882a593Smuzhiyun 			port->icount.frame++;
276*4882a593Smuzhiyun 
277*4882a593Smuzhiyun 		if (uart_handle_sysrq_char(port, ch))
278*4882a593Smuzhiyun 			goto ignore_char;
279*4882a593Smuzhiyun 
280*4882a593Smuzhiyun 		if (status & port->ignore_status_mask & STAT_PAR_ERR)
281*4882a593Smuzhiyun 			status &= ~STAT_RX_RDY(port);
282*4882a593Smuzhiyun 
283*4882a593Smuzhiyun 		status &= port->read_status_mask;
284*4882a593Smuzhiyun 
285*4882a593Smuzhiyun 		if (status & STAT_PAR_ERR)
286*4882a593Smuzhiyun 			flag = TTY_PARITY;
287*4882a593Smuzhiyun 
288*4882a593Smuzhiyun 		status &= ~port->ignore_status_mask;
289*4882a593Smuzhiyun 
290*4882a593Smuzhiyun 		if (status & STAT_RX_RDY(port))
291*4882a593Smuzhiyun 			tty_insert_flip_char(tport, ch, flag);
292*4882a593Smuzhiyun 
293*4882a593Smuzhiyun 		if (status & STAT_BRK_DET)
294*4882a593Smuzhiyun 			tty_insert_flip_char(tport, 0, TTY_BREAK);
295*4882a593Smuzhiyun 
296*4882a593Smuzhiyun 		if (status & STAT_FRM_ERR)
297*4882a593Smuzhiyun 			tty_insert_flip_char(tport, 0, TTY_FRAME);
298*4882a593Smuzhiyun 
299*4882a593Smuzhiyun 		if (status & STAT_OVR_ERR)
300*4882a593Smuzhiyun 			tty_insert_flip_char(tport, 0, TTY_OVERRUN);
301*4882a593Smuzhiyun 
302*4882a593Smuzhiyun ignore_char:
303*4882a593Smuzhiyun 		status = readl(port->membase + UART_STAT);
304*4882a593Smuzhiyun 	} while (status & (STAT_RX_RDY(port) | STAT_BRK_DET));
305*4882a593Smuzhiyun 
306*4882a593Smuzhiyun 	tty_flip_buffer_push(tport);
307*4882a593Smuzhiyun }
308*4882a593Smuzhiyun 
mvebu_uart_tx_chars(struct uart_port * port,unsigned int status)309*4882a593Smuzhiyun static void mvebu_uart_tx_chars(struct uart_port *port, unsigned int status)
310*4882a593Smuzhiyun {
311*4882a593Smuzhiyun 	struct circ_buf *xmit = &port->state->xmit;
312*4882a593Smuzhiyun 	unsigned int count;
313*4882a593Smuzhiyun 	unsigned int st;
314*4882a593Smuzhiyun 
315*4882a593Smuzhiyun 	if (port->x_char) {
316*4882a593Smuzhiyun 		writel(port->x_char, port->membase + UART_TSH(port));
317*4882a593Smuzhiyun 		port->icount.tx++;
318*4882a593Smuzhiyun 		port->x_char = 0;
319*4882a593Smuzhiyun 		return;
320*4882a593Smuzhiyun 	}
321*4882a593Smuzhiyun 
322*4882a593Smuzhiyun 	if (uart_circ_empty(xmit) || uart_tx_stopped(port)) {
323*4882a593Smuzhiyun 		mvebu_uart_stop_tx(port);
324*4882a593Smuzhiyun 		return;
325*4882a593Smuzhiyun 	}
326*4882a593Smuzhiyun 
327*4882a593Smuzhiyun 	for (count = 0; count < port->fifosize; count++) {
328*4882a593Smuzhiyun 		writel(xmit->buf[xmit->tail], port->membase + UART_TSH(port));
329*4882a593Smuzhiyun 		xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
330*4882a593Smuzhiyun 		port->icount.tx++;
331*4882a593Smuzhiyun 
332*4882a593Smuzhiyun 		if (uart_circ_empty(xmit))
333*4882a593Smuzhiyun 			break;
334*4882a593Smuzhiyun 
335*4882a593Smuzhiyun 		st = readl(port->membase + UART_STAT);
336*4882a593Smuzhiyun 		if (st & STAT_TX_FIFO_FUL)
337*4882a593Smuzhiyun 			break;
338*4882a593Smuzhiyun 	}
339*4882a593Smuzhiyun 
340*4882a593Smuzhiyun 	if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
341*4882a593Smuzhiyun 		uart_write_wakeup(port);
342*4882a593Smuzhiyun 
343*4882a593Smuzhiyun 	if (uart_circ_empty(xmit))
344*4882a593Smuzhiyun 		mvebu_uart_stop_tx(port);
345*4882a593Smuzhiyun }
346*4882a593Smuzhiyun 
mvebu_uart_isr(int irq,void * dev_id)347*4882a593Smuzhiyun static irqreturn_t mvebu_uart_isr(int irq, void *dev_id)
348*4882a593Smuzhiyun {
349*4882a593Smuzhiyun 	struct uart_port *port = (struct uart_port *)dev_id;
350*4882a593Smuzhiyun 	unsigned int st = readl(port->membase + UART_STAT);
351*4882a593Smuzhiyun 
352*4882a593Smuzhiyun 	if (st & (STAT_RX_RDY(port) | STAT_OVR_ERR | STAT_FRM_ERR |
353*4882a593Smuzhiyun 		  STAT_BRK_DET))
354*4882a593Smuzhiyun 		mvebu_uart_rx_chars(port, st);
355*4882a593Smuzhiyun 
356*4882a593Smuzhiyun 	if (st & STAT_TX_RDY(port))
357*4882a593Smuzhiyun 		mvebu_uart_tx_chars(port, st);
358*4882a593Smuzhiyun 
359*4882a593Smuzhiyun 	return IRQ_HANDLED;
360*4882a593Smuzhiyun }
361*4882a593Smuzhiyun 
mvebu_uart_rx_isr(int irq,void * dev_id)362*4882a593Smuzhiyun static irqreturn_t mvebu_uart_rx_isr(int irq, void *dev_id)
363*4882a593Smuzhiyun {
364*4882a593Smuzhiyun 	struct uart_port *port = (struct uart_port *)dev_id;
365*4882a593Smuzhiyun 	unsigned int st = readl(port->membase + UART_STAT);
366*4882a593Smuzhiyun 
367*4882a593Smuzhiyun 	if (st & (STAT_RX_RDY(port) | STAT_OVR_ERR | STAT_FRM_ERR |
368*4882a593Smuzhiyun 			STAT_BRK_DET))
369*4882a593Smuzhiyun 		mvebu_uart_rx_chars(port, st);
370*4882a593Smuzhiyun 
371*4882a593Smuzhiyun 	return IRQ_HANDLED;
372*4882a593Smuzhiyun }
373*4882a593Smuzhiyun 
mvebu_uart_tx_isr(int irq,void * dev_id)374*4882a593Smuzhiyun static irqreturn_t mvebu_uart_tx_isr(int irq, void *dev_id)
375*4882a593Smuzhiyun {
376*4882a593Smuzhiyun 	struct uart_port *port = (struct uart_port *)dev_id;
377*4882a593Smuzhiyun 	unsigned int st = readl(port->membase + UART_STAT);
378*4882a593Smuzhiyun 
379*4882a593Smuzhiyun 	if (st & STAT_TX_RDY(port))
380*4882a593Smuzhiyun 		mvebu_uart_tx_chars(port, st);
381*4882a593Smuzhiyun 
382*4882a593Smuzhiyun 	return IRQ_HANDLED;
383*4882a593Smuzhiyun }
384*4882a593Smuzhiyun 
mvebu_uart_startup(struct uart_port * port)385*4882a593Smuzhiyun static int mvebu_uart_startup(struct uart_port *port)
386*4882a593Smuzhiyun {
387*4882a593Smuzhiyun 	struct mvebu_uart *mvuart = to_mvuart(port);
388*4882a593Smuzhiyun 	unsigned int ctl;
389*4882a593Smuzhiyun 	int ret;
390*4882a593Smuzhiyun 
391*4882a593Smuzhiyun 	writel(CTRL_TXFIFO_RST | CTRL_RXFIFO_RST,
392*4882a593Smuzhiyun 	       port->membase + UART_CTRL(port));
393*4882a593Smuzhiyun 	udelay(1);
394*4882a593Smuzhiyun 
395*4882a593Smuzhiyun 	/* Clear the error bits of state register before IRQ request */
396*4882a593Smuzhiyun 	ret = readl(port->membase + UART_STAT);
397*4882a593Smuzhiyun 	ret |= STAT_BRK_ERR;
398*4882a593Smuzhiyun 	writel(ret, port->membase + UART_STAT);
399*4882a593Smuzhiyun 
400*4882a593Smuzhiyun 	writel(CTRL_BRK_INT, port->membase + UART_CTRL(port));
401*4882a593Smuzhiyun 
402*4882a593Smuzhiyun 	ctl = readl(port->membase + UART_INTR(port));
403*4882a593Smuzhiyun 	ctl |= CTRL_RX_RDY_INT(port);
404*4882a593Smuzhiyun 	writel(ctl, port->membase + UART_INTR(port));
405*4882a593Smuzhiyun 
406*4882a593Smuzhiyun 	if (!mvuart->irq[UART_TX_IRQ]) {
407*4882a593Smuzhiyun 		/* Old bindings with just one interrupt (UART0 only) */
408*4882a593Smuzhiyun 		ret = devm_request_irq(port->dev, mvuart->irq[UART_IRQ_SUM],
409*4882a593Smuzhiyun 				       mvebu_uart_isr, port->irqflags,
410*4882a593Smuzhiyun 				       dev_name(port->dev), port);
411*4882a593Smuzhiyun 		if (ret) {
412*4882a593Smuzhiyun 			dev_err(port->dev, "unable to request IRQ %d\n",
413*4882a593Smuzhiyun 				mvuart->irq[UART_IRQ_SUM]);
414*4882a593Smuzhiyun 			return ret;
415*4882a593Smuzhiyun 		}
416*4882a593Smuzhiyun 	} else {
417*4882a593Smuzhiyun 		/* New bindings with an IRQ for RX and TX (both UART) */
418*4882a593Smuzhiyun 		ret = devm_request_irq(port->dev, mvuart->irq[UART_RX_IRQ],
419*4882a593Smuzhiyun 				       mvebu_uart_rx_isr, port->irqflags,
420*4882a593Smuzhiyun 				       dev_name(port->dev), port);
421*4882a593Smuzhiyun 		if (ret) {
422*4882a593Smuzhiyun 			dev_err(port->dev, "unable to request IRQ %d\n",
423*4882a593Smuzhiyun 				mvuart->irq[UART_RX_IRQ]);
424*4882a593Smuzhiyun 			return ret;
425*4882a593Smuzhiyun 		}
426*4882a593Smuzhiyun 
427*4882a593Smuzhiyun 		ret = devm_request_irq(port->dev, mvuart->irq[UART_TX_IRQ],
428*4882a593Smuzhiyun 				       mvebu_uart_tx_isr, port->irqflags,
429*4882a593Smuzhiyun 				       dev_name(port->dev),
430*4882a593Smuzhiyun 				       port);
431*4882a593Smuzhiyun 		if (ret) {
432*4882a593Smuzhiyun 			dev_err(port->dev, "unable to request IRQ %d\n",
433*4882a593Smuzhiyun 				mvuart->irq[UART_TX_IRQ]);
434*4882a593Smuzhiyun 			devm_free_irq(port->dev, mvuart->irq[UART_RX_IRQ],
435*4882a593Smuzhiyun 				      port);
436*4882a593Smuzhiyun 			return ret;
437*4882a593Smuzhiyun 		}
438*4882a593Smuzhiyun 	}
439*4882a593Smuzhiyun 
440*4882a593Smuzhiyun 	return 0;
441*4882a593Smuzhiyun }
442*4882a593Smuzhiyun 
mvebu_uart_shutdown(struct uart_port * port)443*4882a593Smuzhiyun static void mvebu_uart_shutdown(struct uart_port *port)
444*4882a593Smuzhiyun {
445*4882a593Smuzhiyun 	struct mvebu_uart *mvuart = to_mvuart(port);
446*4882a593Smuzhiyun 
447*4882a593Smuzhiyun 	writel(0, port->membase + UART_INTR(port));
448*4882a593Smuzhiyun 
449*4882a593Smuzhiyun 	if (!mvuart->irq[UART_TX_IRQ]) {
450*4882a593Smuzhiyun 		devm_free_irq(port->dev, mvuart->irq[UART_IRQ_SUM], port);
451*4882a593Smuzhiyun 	} else {
452*4882a593Smuzhiyun 		devm_free_irq(port->dev, mvuart->irq[UART_RX_IRQ], port);
453*4882a593Smuzhiyun 		devm_free_irq(port->dev, mvuart->irq[UART_TX_IRQ], port);
454*4882a593Smuzhiyun 	}
455*4882a593Smuzhiyun }
456*4882a593Smuzhiyun 
mvebu_uart_baud_rate_set(struct uart_port * port,unsigned int baud)457*4882a593Smuzhiyun static unsigned int mvebu_uart_baud_rate_set(struct uart_port *port, unsigned int baud)
458*4882a593Smuzhiyun {
459*4882a593Smuzhiyun 	unsigned int d_divisor, m_divisor;
460*4882a593Smuzhiyun 	u32 brdv, osamp;
461*4882a593Smuzhiyun 
462*4882a593Smuzhiyun 	if (!port->uartclk)
463*4882a593Smuzhiyun 		return 0;
464*4882a593Smuzhiyun 
465*4882a593Smuzhiyun 	/*
466*4882a593Smuzhiyun 	 * The baudrate is derived from the UART clock thanks to two divisors:
467*4882a593Smuzhiyun 	 *   > D ("baud generator"): can divide the clock from 2 to 2^10 - 1.
468*4882a593Smuzhiyun 	 *   > M ("fractional divisor"): allows a better accuracy for
469*4882a593Smuzhiyun 	 *     baudrates higher than 230400.
470*4882a593Smuzhiyun 	 *
471*4882a593Smuzhiyun 	 * As the derivation of M is rather complicated, the code sticks to its
472*4882a593Smuzhiyun 	 * default value (x16) when all the prescalers are zeroed, and only
473*4882a593Smuzhiyun 	 * makes use of D to configure the desired baudrate.
474*4882a593Smuzhiyun 	 */
475*4882a593Smuzhiyun 	m_divisor = OSAMP_DEFAULT_DIVISOR;
476*4882a593Smuzhiyun 	d_divisor = DIV_ROUND_CLOSEST(port->uartclk, baud * m_divisor);
477*4882a593Smuzhiyun 
478*4882a593Smuzhiyun 	brdv = readl(port->membase + UART_BRDV);
479*4882a593Smuzhiyun 	brdv &= ~BRDV_BAUD_MASK;
480*4882a593Smuzhiyun 	brdv |= d_divisor;
481*4882a593Smuzhiyun 	writel(brdv, port->membase + UART_BRDV);
482*4882a593Smuzhiyun 
483*4882a593Smuzhiyun 	osamp = readl(port->membase + UART_OSAMP);
484*4882a593Smuzhiyun 	osamp &= ~OSAMP_DIVISORS_MASK;
485*4882a593Smuzhiyun 	writel(osamp, port->membase + UART_OSAMP);
486*4882a593Smuzhiyun 
487*4882a593Smuzhiyun 	return DIV_ROUND_CLOSEST(port->uartclk, d_divisor * m_divisor);
488*4882a593Smuzhiyun }
489*4882a593Smuzhiyun 
mvebu_uart_set_termios(struct uart_port * port,struct ktermios * termios,struct ktermios * old)490*4882a593Smuzhiyun static void mvebu_uart_set_termios(struct uart_port *port,
491*4882a593Smuzhiyun 				   struct ktermios *termios,
492*4882a593Smuzhiyun 				   struct ktermios *old)
493*4882a593Smuzhiyun {
494*4882a593Smuzhiyun 	unsigned long flags;
495*4882a593Smuzhiyun 	unsigned int baud, min_baud, max_baud;
496*4882a593Smuzhiyun 
497*4882a593Smuzhiyun 	spin_lock_irqsave(&port->lock, flags);
498*4882a593Smuzhiyun 
499*4882a593Smuzhiyun 	port->read_status_mask = STAT_RX_RDY(port) | STAT_OVR_ERR |
500*4882a593Smuzhiyun 		STAT_TX_RDY(port) | STAT_TX_FIFO_FUL;
501*4882a593Smuzhiyun 
502*4882a593Smuzhiyun 	if (termios->c_iflag & INPCK)
503*4882a593Smuzhiyun 		port->read_status_mask |= STAT_FRM_ERR | STAT_PAR_ERR;
504*4882a593Smuzhiyun 
505*4882a593Smuzhiyun 	port->ignore_status_mask = 0;
506*4882a593Smuzhiyun 	if (termios->c_iflag & IGNPAR)
507*4882a593Smuzhiyun 		port->ignore_status_mask |=
508*4882a593Smuzhiyun 			STAT_FRM_ERR | STAT_PAR_ERR | STAT_OVR_ERR;
509*4882a593Smuzhiyun 
510*4882a593Smuzhiyun 	if ((termios->c_cflag & CREAD) == 0)
511*4882a593Smuzhiyun 		port->ignore_status_mask |= STAT_RX_RDY(port) | STAT_BRK_ERR;
512*4882a593Smuzhiyun 
513*4882a593Smuzhiyun 	/*
514*4882a593Smuzhiyun 	 * Maximal divisor is 1023 * 16 when using default (x16) scheme.
515*4882a593Smuzhiyun 	 * Maximum achievable frequency with simple baudrate divisor is 230400.
516*4882a593Smuzhiyun 	 * Since the error per bit frame would be of more than 15%, achieving
517*4882a593Smuzhiyun 	 * higher frequencies would require to implement the fractional divisor
518*4882a593Smuzhiyun 	 * feature.
519*4882a593Smuzhiyun 	 */
520*4882a593Smuzhiyun 	min_baud = DIV_ROUND_UP(port->uartclk, 1023 * 16);
521*4882a593Smuzhiyun 	max_baud = 230400;
522*4882a593Smuzhiyun 
523*4882a593Smuzhiyun 	baud = uart_get_baud_rate(port, termios, old, min_baud, max_baud);
524*4882a593Smuzhiyun 	baud = mvebu_uart_baud_rate_set(port, baud);
525*4882a593Smuzhiyun 
526*4882a593Smuzhiyun 	/* In case baudrate cannot be changed, report previous old value */
527*4882a593Smuzhiyun 	if (baud == 0 && old)
528*4882a593Smuzhiyun 		baud = tty_termios_baud_rate(old);
529*4882a593Smuzhiyun 
530*4882a593Smuzhiyun 	/* Only the following flag changes are supported */
531*4882a593Smuzhiyun 	if (old) {
532*4882a593Smuzhiyun 		termios->c_iflag &= INPCK | IGNPAR;
533*4882a593Smuzhiyun 		termios->c_iflag |= old->c_iflag & ~(INPCK | IGNPAR);
534*4882a593Smuzhiyun 		termios->c_cflag &= CREAD | CBAUD;
535*4882a593Smuzhiyun 		termios->c_cflag |= old->c_cflag & ~(CREAD | CBAUD);
536*4882a593Smuzhiyun 		termios->c_cflag |= CS8;
537*4882a593Smuzhiyun 	}
538*4882a593Smuzhiyun 
539*4882a593Smuzhiyun 	if (baud != 0) {
540*4882a593Smuzhiyun 		tty_termios_encode_baud_rate(termios, baud, baud);
541*4882a593Smuzhiyun 		uart_update_timeout(port, termios->c_cflag, baud);
542*4882a593Smuzhiyun 	}
543*4882a593Smuzhiyun 
544*4882a593Smuzhiyun 	spin_unlock_irqrestore(&port->lock, flags);
545*4882a593Smuzhiyun }
546*4882a593Smuzhiyun 
mvebu_uart_type(struct uart_port * port)547*4882a593Smuzhiyun static const char *mvebu_uart_type(struct uart_port *port)
548*4882a593Smuzhiyun {
549*4882a593Smuzhiyun 	return MVEBU_UART_TYPE;
550*4882a593Smuzhiyun }
551*4882a593Smuzhiyun 
mvebu_uart_release_port(struct uart_port * port)552*4882a593Smuzhiyun static void mvebu_uart_release_port(struct uart_port *port)
553*4882a593Smuzhiyun {
554*4882a593Smuzhiyun 	/* Nothing to do here */
555*4882a593Smuzhiyun }
556*4882a593Smuzhiyun 
mvebu_uart_request_port(struct uart_port * port)557*4882a593Smuzhiyun static int mvebu_uart_request_port(struct uart_port *port)
558*4882a593Smuzhiyun {
559*4882a593Smuzhiyun 	return 0;
560*4882a593Smuzhiyun }
561*4882a593Smuzhiyun 
562*4882a593Smuzhiyun #ifdef CONFIG_CONSOLE_POLL
mvebu_uart_get_poll_char(struct uart_port * port)563*4882a593Smuzhiyun static int mvebu_uart_get_poll_char(struct uart_port *port)
564*4882a593Smuzhiyun {
565*4882a593Smuzhiyun 	unsigned int st = readl(port->membase + UART_STAT);
566*4882a593Smuzhiyun 
567*4882a593Smuzhiyun 	if (!(st & STAT_RX_RDY(port)))
568*4882a593Smuzhiyun 		return NO_POLL_CHAR;
569*4882a593Smuzhiyun 
570*4882a593Smuzhiyun 	return readl(port->membase + UART_RBR(port));
571*4882a593Smuzhiyun }
572*4882a593Smuzhiyun 
mvebu_uart_put_poll_char(struct uart_port * port,unsigned char c)573*4882a593Smuzhiyun static void mvebu_uart_put_poll_char(struct uart_port *port, unsigned char c)
574*4882a593Smuzhiyun {
575*4882a593Smuzhiyun 	unsigned int st;
576*4882a593Smuzhiyun 
577*4882a593Smuzhiyun 	for (;;) {
578*4882a593Smuzhiyun 		st = readl(port->membase + UART_STAT);
579*4882a593Smuzhiyun 
580*4882a593Smuzhiyun 		if (!(st & STAT_TX_FIFO_FUL))
581*4882a593Smuzhiyun 			break;
582*4882a593Smuzhiyun 
583*4882a593Smuzhiyun 		udelay(1);
584*4882a593Smuzhiyun 	}
585*4882a593Smuzhiyun 
586*4882a593Smuzhiyun 	writel(c, port->membase + UART_TSH(port));
587*4882a593Smuzhiyun }
588*4882a593Smuzhiyun #endif
589*4882a593Smuzhiyun 
590*4882a593Smuzhiyun static const struct uart_ops mvebu_uart_ops = {
591*4882a593Smuzhiyun 	.tx_empty	= mvebu_uart_tx_empty,
592*4882a593Smuzhiyun 	.set_mctrl	= mvebu_uart_set_mctrl,
593*4882a593Smuzhiyun 	.get_mctrl	= mvebu_uart_get_mctrl,
594*4882a593Smuzhiyun 	.stop_tx	= mvebu_uart_stop_tx,
595*4882a593Smuzhiyun 	.start_tx	= mvebu_uart_start_tx,
596*4882a593Smuzhiyun 	.stop_rx	= mvebu_uart_stop_rx,
597*4882a593Smuzhiyun 	.break_ctl	= mvebu_uart_break_ctl,
598*4882a593Smuzhiyun 	.startup	= mvebu_uart_startup,
599*4882a593Smuzhiyun 	.shutdown	= mvebu_uart_shutdown,
600*4882a593Smuzhiyun 	.set_termios	= mvebu_uart_set_termios,
601*4882a593Smuzhiyun 	.type		= mvebu_uart_type,
602*4882a593Smuzhiyun 	.release_port	= mvebu_uart_release_port,
603*4882a593Smuzhiyun 	.request_port	= mvebu_uart_request_port,
604*4882a593Smuzhiyun #ifdef CONFIG_CONSOLE_POLL
605*4882a593Smuzhiyun 	.poll_get_char	= mvebu_uart_get_poll_char,
606*4882a593Smuzhiyun 	.poll_put_char	= mvebu_uart_put_poll_char,
607*4882a593Smuzhiyun #endif
608*4882a593Smuzhiyun };
609*4882a593Smuzhiyun 
610*4882a593Smuzhiyun /* Console Driver Operations  */
611*4882a593Smuzhiyun 
612*4882a593Smuzhiyun #ifdef CONFIG_SERIAL_MVEBU_CONSOLE
613*4882a593Smuzhiyun /* Early Console */
mvebu_uart_putc(struct uart_port * port,int c)614*4882a593Smuzhiyun static void mvebu_uart_putc(struct uart_port *port, int c)
615*4882a593Smuzhiyun {
616*4882a593Smuzhiyun 	unsigned int st;
617*4882a593Smuzhiyun 
618*4882a593Smuzhiyun 	for (;;) {
619*4882a593Smuzhiyun 		st = readl(port->membase + UART_STAT);
620*4882a593Smuzhiyun 		if (!(st & STAT_TX_FIFO_FUL))
621*4882a593Smuzhiyun 			break;
622*4882a593Smuzhiyun 	}
623*4882a593Smuzhiyun 
624*4882a593Smuzhiyun 	/* At early stage, DT is not parsed yet, only use UART0 */
625*4882a593Smuzhiyun 	writel(c, port->membase + UART_STD_TSH);
626*4882a593Smuzhiyun 
627*4882a593Smuzhiyun 	for (;;) {
628*4882a593Smuzhiyun 		st = readl(port->membase + UART_STAT);
629*4882a593Smuzhiyun 		if (st & STAT_TX_FIFO_EMP)
630*4882a593Smuzhiyun 			break;
631*4882a593Smuzhiyun 	}
632*4882a593Smuzhiyun }
633*4882a593Smuzhiyun 
mvebu_uart_putc_early_write(struct console * con,const char * s,unsigned n)634*4882a593Smuzhiyun static void mvebu_uart_putc_early_write(struct console *con,
635*4882a593Smuzhiyun 					const char *s,
636*4882a593Smuzhiyun 					unsigned n)
637*4882a593Smuzhiyun {
638*4882a593Smuzhiyun 	struct earlycon_device *dev = con->data;
639*4882a593Smuzhiyun 
640*4882a593Smuzhiyun 	uart_console_write(&dev->port, s, n, mvebu_uart_putc);
641*4882a593Smuzhiyun }
642*4882a593Smuzhiyun 
643*4882a593Smuzhiyun static int __init
mvebu_uart_early_console_setup(struct earlycon_device * device,const char * opt)644*4882a593Smuzhiyun mvebu_uart_early_console_setup(struct earlycon_device *device,
645*4882a593Smuzhiyun 			       const char *opt)
646*4882a593Smuzhiyun {
647*4882a593Smuzhiyun 	if (!device->port.membase)
648*4882a593Smuzhiyun 		return -ENODEV;
649*4882a593Smuzhiyun 
650*4882a593Smuzhiyun 	device->con->write = mvebu_uart_putc_early_write;
651*4882a593Smuzhiyun 
652*4882a593Smuzhiyun 	return 0;
653*4882a593Smuzhiyun }
654*4882a593Smuzhiyun 
655*4882a593Smuzhiyun EARLYCON_DECLARE(ar3700_uart, mvebu_uart_early_console_setup);
656*4882a593Smuzhiyun OF_EARLYCON_DECLARE(ar3700_uart, "marvell,armada-3700-uart",
657*4882a593Smuzhiyun 		    mvebu_uart_early_console_setup);
658*4882a593Smuzhiyun 
wait_for_xmitr(struct uart_port * port)659*4882a593Smuzhiyun static void wait_for_xmitr(struct uart_port *port)
660*4882a593Smuzhiyun {
661*4882a593Smuzhiyun 	u32 val;
662*4882a593Smuzhiyun 
663*4882a593Smuzhiyun 	readl_poll_timeout_atomic(port->membase + UART_STAT, val,
664*4882a593Smuzhiyun 				  (val & STAT_TX_RDY(port)), 1, 10000);
665*4882a593Smuzhiyun }
666*4882a593Smuzhiyun 
wait_for_xmite(struct uart_port * port)667*4882a593Smuzhiyun static void wait_for_xmite(struct uart_port *port)
668*4882a593Smuzhiyun {
669*4882a593Smuzhiyun 	u32 val;
670*4882a593Smuzhiyun 
671*4882a593Smuzhiyun 	readl_poll_timeout_atomic(port->membase + UART_STAT, val,
672*4882a593Smuzhiyun 				  (val & STAT_TX_EMP), 1, 10000);
673*4882a593Smuzhiyun }
674*4882a593Smuzhiyun 
mvebu_uart_console_putchar(struct uart_port * port,int ch)675*4882a593Smuzhiyun static void mvebu_uart_console_putchar(struct uart_port *port, int ch)
676*4882a593Smuzhiyun {
677*4882a593Smuzhiyun 	wait_for_xmitr(port);
678*4882a593Smuzhiyun 	writel(ch, port->membase + UART_TSH(port));
679*4882a593Smuzhiyun }
680*4882a593Smuzhiyun 
mvebu_uart_console_write(struct console * co,const char * s,unsigned int count)681*4882a593Smuzhiyun static void mvebu_uart_console_write(struct console *co, const char *s,
682*4882a593Smuzhiyun 				     unsigned int count)
683*4882a593Smuzhiyun {
684*4882a593Smuzhiyun 	struct uart_port *port = &mvebu_uart_ports[co->index];
685*4882a593Smuzhiyun 	unsigned long flags;
686*4882a593Smuzhiyun 	unsigned int ier, intr, ctl;
687*4882a593Smuzhiyun 	int locked = 1;
688*4882a593Smuzhiyun 
689*4882a593Smuzhiyun 	if (oops_in_progress)
690*4882a593Smuzhiyun 		locked = spin_trylock_irqsave(&port->lock, flags);
691*4882a593Smuzhiyun 	else
692*4882a593Smuzhiyun 		spin_lock_irqsave(&port->lock, flags);
693*4882a593Smuzhiyun 
694*4882a593Smuzhiyun 	ier = readl(port->membase + UART_CTRL(port)) & CTRL_BRK_INT;
695*4882a593Smuzhiyun 	intr = readl(port->membase + UART_INTR(port)) &
696*4882a593Smuzhiyun 		(CTRL_RX_RDY_INT(port) | CTRL_TX_RDY_INT(port));
697*4882a593Smuzhiyun 	writel(0, port->membase + UART_CTRL(port));
698*4882a593Smuzhiyun 	writel(0, port->membase + UART_INTR(port));
699*4882a593Smuzhiyun 
700*4882a593Smuzhiyun 	uart_console_write(port, s, count, mvebu_uart_console_putchar);
701*4882a593Smuzhiyun 
702*4882a593Smuzhiyun 	wait_for_xmite(port);
703*4882a593Smuzhiyun 
704*4882a593Smuzhiyun 	if (ier)
705*4882a593Smuzhiyun 		writel(ier, port->membase + UART_CTRL(port));
706*4882a593Smuzhiyun 
707*4882a593Smuzhiyun 	if (intr) {
708*4882a593Smuzhiyun 		ctl = intr | readl(port->membase + UART_INTR(port));
709*4882a593Smuzhiyun 		writel(ctl, port->membase + UART_INTR(port));
710*4882a593Smuzhiyun 	}
711*4882a593Smuzhiyun 
712*4882a593Smuzhiyun 	if (locked)
713*4882a593Smuzhiyun 		spin_unlock_irqrestore(&port->lock, flags);
714*4882a593Smuzhiyun }
715*4882a593Smuzhiyun 
mvebu_uart_console_setup(struct console * co,char * options)716*4882a593Smuzhiyun static int mvebu_uart_console_setup(struct console *co, char *options)
717*4882a593Smuzhiyun {
718*4882a593Smuzhiyun 	struct uart_port *port;
719*4882a593Smuzhiyun 	int baud = 9600;
720*4882a593Smuzhiyun 	int bits = 8;
721*4882a593Smuzhiyun 	int parity = 'n';
722*4882a593Smuzhiyun 	int flow = 'n';
723*4882a593Smuzhiyun 
724*4882a593Smuzhiyun 	if (co->index < 0 || co->index >= MVEBU_NR_UARTS)
725*4882a593Smuzhiyun 		return -EINVAL;
726*4882a593Smuzhiyun 
727*4882a593Smuzhiyun 	port = &mvebu_uart_ports[co->index];
728*4882a593Smuzhiyun 
729*4882a593Smuzhiyun 	if (!port->mapbase || !port->membase) {
730*4882a593Smuzhiyun 		pr_debug("console on ttyMV%i not present\n", co->index);
731*4882a593Smuzhiyun 		return -ENODEV;
732*4882a593Smuzhiyun 	}
733*4882a593Smuzhiyun 
734*4882a593Smuzhiyun 	if (options)
735*4882a593Smuzhiyun 		uart_parse_options(options, &baud, &parity, &bits, &flow);
736*4882a593Smuzhiyun 
737*4882a593Smuzhiyun 	return uart_set_options(port, co, baud, parity, bits, flow);
738*4882a593Smuzhiyun }
739*4882a593Smuzhiyun 
740*4882a593Smuzhiyun static struct uart_driver mvebu_uart_driver;
741*4882a593Smuzhiyun 
742*4882a593Smuzhiyun static struct console mvebu_uart_console = {
743*4882a593Smuzhiyun 	.name	= "ttyMV",
744*4882a593Smuzhiyun 	.write	= mvebu_uart_console_write,
745*4882a593Smuzhiyun 	.device	= uart_console_device,
746*4882a593Smuzhiyun 	.setup	= mvebu_uart_console_setup,
747*4882a593Smuzhiyun 	.flags	= CON_PRINTBUFFER,
748*4882a593Smuzhiyun 	.index	= -1,
749*4882a593Smuzhiyun 	.data	= &mvebu_uart_driver,
750*4882a593Smuzhiyun };
751*4882a593Smuzhiyun 
mvebu_uart_console_init(void)752*4882a593Smuzhiyun static int __init mvebu_uart_console_init(void)
753*4882a593Smuzhiyun {
754*4882a593Smuzhiyun 	register_console(&mvebu_uart_console);
755*4882a593Smuzhiyun 	return 0;
756*4882a593Smuzhiyun }
757*4882a593Smuzhiyun 
758*4882a593Smuzhiyun console_initcall(mvebu_uart_console_init);
759*4882a593Smuzhiyun 
760*4882a593Smuzhiyun 
761*4882a593Smuzhiyun #endif /* CONFIG_SERIAL_MVEBU_CONSOLE */
762*4882a593Smuzhiyun 
763*4882a593Smuzhiyun static struct uart_driver mvebu_uart_driver = {
764*4882a593Smuzhiyun 	.owner			= THIS_MODULE,
765*4882a593Smuzhiyun 	.driver_name		= DRIVER_NAME,
766*4882a593Smuzhiyun 	.dev_name		= "ttyMV",
767*4882a593Smuzhiyun 	.nr			= MVEBU_NR_UARTS,
768*4882a593Smuzhiyun #ifdef CONFIG_SERIAL_MVEBU_CONSOLE
769*4882a593Smuzhiyun 	.cons			= &mvebu_uart_console,
770*4882a593Smuzhiyun #endif
771*4882a593Smuzhiyun };
772*4882a593Smuzhiyun 
773*4882a593Smuzhiyun #if defined(CONFIG_PM)
mvebu_uart_suspend(struct device * dev)774*4882a593Smuzhiyun static int mvebu_uart_suspend(struct device *dev)
775*4882a593Smuzhiyun {
776*4882a593Smuzhiyun 	struct mvebu_uart *mvuart = dev_get_drvdata(dev);
777*4882a593Smuzhiyun 	struct uart_port *port = mvuart->port;
778*4882a593Smuzhiyun 
779*4882a593Smuzhiyun 	uart_suspend_port(&mvebu_uart_driver, port);
780*4882a593Smuzhiyun 
781*4882a593Smuzhiyun 	mvuart->pm_regs.rbr = readl(port->membase + UART_RBR(port));
782*4882a593Smuzhiyun 	mvuart->pm_regs.tsh = readl(port->membase + UART_TSH(port));
783*4882a593Smuzhiyun 	mvuart->pm_regs.ctrl = readl(port->membase + UART_CTRL(port));
784*4882a593Smuzhiyun 	mvuart->pm_regs.intr = readl(port->membase + UART_INTR(port));
785*4882a593Smuzhiyun 	mvuart->pm_regs.stat = readl(port->membase + UART_STAT);
786*4882a593Smuzhiyun 	mvuart->pm_regs.brdv = readl(port->membase + UART_BRDV);
787*4882a593Smuzhiyun 	mvuart->pm_regs.osamp = readl(port->membase + UART_OSAMP);
788*4882a593Smuzhiyun 
789*4882a593Smuzhiyun 	device_set_wakeup_enable(dev, true);
790*4882a593Smuzhiyun 
791*4882a593Smuzhiyun 	return 0;
792*4882a593Smuzhiyun }
793*4882a593Smuzhiyun 
mvebu_uart_resume(struct device * dev)794*4882a593Smuzhiyun static int mvebu_uart_resume(struct device *dev)
795*4882a593Smuzhiyun {
796*4882a593Smuzhiyun 	struct mvebu_uart *mvuart = dev_get_drvdata(dev);
797*4882a593Smuzhiyun 	struct uart_port *port = mvuart->port;
798*4882a593Smuzhiyun 
799*4882a593Smuzhiyun 	writel(mvuart->pm_regs.rbr, port->membase + UART_RBR(port));
800*4882a593Smuzhiyun 	writel(mvuart->pm_regs.tsh, port->membase + UART_TSH(port));
801*4882a593Smuzhiyun 	writel(mvuart->pm_regs.ctrl, port->membase + UART_CTRL(port));
802*4882a593Smuzhiyun 	writel(mvuart->pm_regs.intr, port->membase + UART_INTR(port));
803*4882a593Smuzhiyun 	writel(mvuart->pm_regs.stat, port->membase + UART_STAT);
804*4882a593Smuzhiyun 	writel(mvuart->pm_regs.brdv, port->membase + UART_BRDV);
805*4882a593Smuzhiyun 	writel(mvuart->pm_regs.osamp, port->membase + UART_OSAMP);
806*4882a593Smuzhiyun 
807*4882a593Smuzhiyun 	uart_resume_port(&mvebu_uart_driver, port);
808*4882a593Smuzhiyun 
809*4882a593Smuzhiyun 	return 0;
810*4882a593Smuzhiyun }
811*4882a593Smuzhiyun 
812*4882a593Smuzhiyun static const struct dev_pm_ops mvebu_uart_pm_ops = {
813*4882a593Smuzhiyun 	.suspend        = mvebu_uart_suspend,
814*4882a593Smuzhiyun 	.resume         = mvebu_uart_resume,
815*4882a593Smuzhiyun };
816*4882a593Smuzhiyun #endif /* CONFIG_PM */
817*4882a593Smuzhiyun 
818*4882a593Smuzhiyun static const struct of_device_id mvebu_uart_of_match[];
819*4882a593Smuzhiyun 
820*4882a593Smuzhiyun /* Counter to keep track of each UART port id when not using CONFIG_OF */
821*4882a593Smuzhiyun static int uart_num_counter;
822*4882a593Smuzhiyun 
mvebu_uart_probe(struct platform_device * pdev)823*4882a593Smuzhiyun static int mvebu_uart_probe(struct platform_device *pdev)
824*4882a593Smuzhiyun {
825*4882a593Smuzhiyun 	struct resource *reg = platform_get_resource(pdev, IORESOURCE_MEM, 0);
826*4882a593Smuzhiyun 	const struct of_device_id *match = of_match_device(mvebu_uart_of_match,
827*4882a593Smuzhiyun 							   &pdev->dev);
828*4882a593Smuzhiyun 	struct uart_port *port;
829*4882a593Smuzhiyun 	struct mvebu_uart *mvuart;
830*4882a593Smuzhiyun 	int id, irq;
831*4882a593Smuzhiyun 
832*4882a593Smuzhiyun 	if (!reg) {
833*4882a593Smuzhiyun 		dev_err(&pdev->dev, "no registers defined\n");
834*4882a593Smuzhiyun 		return -EINVAL;
835*4882a593Smuzhiyun 	}
836*4882a593Smuzhiyun 
837*4882a593Smuzhiyun 	/* Assume that all UART ports have a DT alias or none has */
838*4882a593Smuzhiyun 	id = of_alias_get_id(pdev->dev.of_node, "serial");
839*4882a593Smuzhiyun 	if (!pdev->dev.of_node || id < 0)
840*4882a593Smuzhiyun 		pdev->id = uart_num_counter++;
841*4882a593Smuzhiyun 	else
842*4882a593Smuzhiyun 		pdev->id = id;
843*4882a593Smuzhiyun 
844*4882a593Smuzhiyun 	if (pdev->id >= MVEBU_NR_UARTS) {
845*4882a593Smuzhiyun 		dev_err(&pdev->dev, "cannot have more than %d UART ports\n",
846*4882a593Smuzhiyun 			MVEBU_NR_UARTS);
847*4882a593Smuzhiyun 		return -EINVAL;
848*4882a593Smuzhiyun 	}
849*4882a593Smuzhiyun 
850*4882a593Smuzhiyun 	port = &mvebu_uart_ports[pdev->id];
851*4882a593Smuzhiyun 
852*4882a593Smuzhiyun 	spin_lock_init(&port->lock);
853*4882a593Smuzhiyun 
854*4882a593Smuzhiyun 	port->dev        = &pdev->dev;
855*4882a593Smuzhiyun 	port->type       = PORT_MVEBU;
856*4882a593Smuzhiyun 	port->ops        = &mvebu_uart_ops;
857*4882a593Smuzhiyun 	port->regshift   = 0;
858*4882a593Smuzhiyun 
859*4882a593Smuzhiyun 	port->fifosize   = 32;
860*4882a593Smuzhiyun 	port->iotype     = UPIO_MEM32;
861*4882a593Smuzhiyun 	port->flags      = UPF_FIXED_PORT;
862*4882a593Smuzhiyun 	port->line       = pdev->id;
863*4882a593Smuzhiyun 
864*4882a593Smuzhiyun 	/*
865*4882a593Smuzhiyun 	 * IRQ number is not stored in this structure because we may have two of
866*4882a593Smuzhiyun 	 * them per port (RX and TX). Instead, use the driver UART structure
867*4882a593Smuzhiyun 	 * array so called ->irq[].
868*4882a593Smuzhiyun 	 */
869*4882a593Smuzhiyun 	port->irq        = 0;
870*4882a593Smuzhiyun 	port->irqflags   = 0;
871*4882a593Smuzhiyun 	port->mapbase    = reg->start;
872*4882a593Smuzhiyun 
873*4882a593Smuzhiyun 	port->membase = devm_ioremap_resource(&pdev->dev, reg);
874*4882a593Smuzhiyun 	if (IS_ERR(port->membase))
875*4882a593Smuzhiyun 		return PTR_ERR(port->membase);
876*4882a593Smuzhiyun 
877*4882a593Smuzhiyun 	mvuart = devm_kzalloc(&pdev->dev, sizeof(struct mvebu_uart),
878*4882a593Smuzhiyun 			      GFP_KERNEL);
879*4882a593Smuzhiyun 	if (!mvuart)
880*4882a593Smuzhiyun 		return -ENOMEM;
881*4882a593Smuzhiyun 
882*4882a593Smuzhiyun 	/* Get controller data depending on the compatible string */
883*4882a593Smuzhiyun 	mvuart->data = (struct mvebu_uart_driver_data *)match->data;
884*4882a593Smuzhiyun 	mvuart->port = port;
885*4882a593Smuzhiyun 
886*4882a593Smuzhiyun 	port->private_data = mvuart;
887*4882a593Smuzhiyun 	platform_set_drvdata(pdev, mvuart);
888*4882a593Smuzhiyun 
889*4882a593Smuzhiyun 	/* Get fixed clock frequency */
890*4882a593Smuzhiyun 	mvuart->clk = devm_clk_get(&pdev->dev, NULL);
891*4882a593Smuzhiyun 	if (IS_ERR(mvuart->clk)) {
892*4882a593Smuzhiyun 		if (PTR_ERR(mvuart->clk) == -EPROBE_DEFER)
893*4882a593Smuzhiyun 			return PTR_ERR(mvuart->clk);
894*4882a593Smuzhiyun 
895*4882a593Smuzhiyun 		if (IS_EXTENDED(port)) {
896*4882a593Smuzhiyun 			dev_err(&pdev->dev, "unable to get UART clock\n");
897*4882a593Smuzhiyun 			return PTR_ERR(mvuart->clk);
898*4882a593Smuzhiyun 		}
899*4882a593Smuzhiyun 	} else {
900*4882a593Smuzhiyun 		if (!clk_prepare_enable(mvuart->clk))
901*4882a593Smuzhiyun 			port->uartclk = clk_get_rate(mvuart->clk);
902*4882a593Smuzhiyun 	}
903*4882a593Smuzhiyun 
904*4882a593Smuzhiyun 	/* Manage interrupts */
905*4882a593Smuzhiyun 	if (platform_irq_count(pdev) == 1) {
906*4882a593Smuzhiyun 		/* Old bindings: no name on the single unamed UART0 IRQ */
907*4882a593Smuzhiyun 		irq = platform_get_irq(pdev, 0);
908*4882a593Smuzhiyun 		if (irq < 0)
909*4882a593Smuzhiyun 			return irq;
910*4882a593Smuzhiyun 
911*4882a593Smuzhiyun 		mvuart->irq[UART_IRQ_SUM] = irq;
912*4882a593Smuzhiyun 	} else {
913*4882a593Smuzhiyun 		/*
914*4882a593Smuzhiyun 		 * New bindings: named interrupts (RX, TX) for both UARTS,
915*4882a593Smuzhiyun 		 * only make use of uart-rx and uart-tx interrupts, do not use
916*4882a593Smuzhiyun 		 * uart-sum of UART0 port.
917*4882a593Smuzhiyun 		 */
918*4882a593Smuzhiyun 		irq = platform_get_irq_byname(pdev, "uart-rx");
919*4882a593Smuzhiyun 		if (irq < 0)
920*4882a593Smuzhiyun 			return irq;
921*4882a593Smuzhiyun 
922*4882a593Smuzhiyun 		mvuart->irq[UART_RX_IRQ] = irq;
923*4882a593Smuzhiyun 
924*4882a593Smuzhiyun 		irq = platform_get_irq_byname(pdev, "uart-tx");
925*4882a593Smuzhiyun 		if (irq < 0)
926*4882a593Smuzhiyun 			return irq;
927*4882a593Smuzhiyun 
928*4882a593Smuzhiyun 		mvuart->irq[UART_TX_IRQ] = irq;
929*4882a593Smuzhiyun 	}
930*4882a593Smuzhiyun 
931*4882a593Smuzhiyun 	/* UART Soft Reset*/
932*4882a593Smuzhiyun 	writel(CTRL_SOFT_RST, port->membase + UART_CTRL(port));
933*4882a593Smuzhiyun 	udelay(1);
934*4882a593Smuzhiyun 	writel(0, port->membase + UART_CTRL(port));
935*4882a593Smuzhiyun 
936*4882a593Smuzhiyun 	return uart_add_one_port(&mvebu_uart_driver, port);
937*4882a593Smuzhiyun }
938*4882a593Smuzhiyun 
939*4882a593Smuzhiyun static struct mvebu_uart_driver_data uart_std_driver_data = {
940*4882a593Smuzhiyun 	.is_ext = false,
941*4882a593Smuzhiyun 	.regs.rbr = UART_STD_RBR,
942*4882a593Smuzhiyun 	.regs.tsh = UART_STD_TSH,
943*4882a593Smuzhiyun 	.regs.ctrl = UART_STD_CTRL1,
944*4882a593Smuzhiyun 	.regs.intr = UART_STD_CTRL2,
945*4882a593Smuzhiyun 	.flags.ctrl_tx_rdy_int = CTRL_STD_TX_RDY_INT,
946*4882a593Smuzhiyun 	.flags.ctrl_rx_rdy_int = CTRL_STD_RX_RDY_INT,
947*4882a593Smuzhiyun 	.flags.stat_tx_rdy = STAT_STD_TX_RDY,
948*4882a593Smuzhiyun 	.flags.stat_rx_rdy = STAT_STD_RX_RDY,
949*4882a593Smuzhiyun };
950*4882a593Smuzhiyun 
951*4882a593Smuzhiyun static struct mvebu_uart_driver_data uart_ext_driver_data = {
952*4882a593Smuzhiyun 	.is_ext = true,
953*4882a593Smuzhiyun 	.regs.rbr = UART_EXT_RBR,
954*4882a593Smuzhiyun 	.regs.tsh = UART_EXT_TSH,
955*4882a593Smuzhiyun 	.regs.ctrl = UART_EXT_CTRL1,
956*4882a593Smuzhiyun 	.regs.intr = UART_EXT_CTRL2,
957*4882a593Smuzhiyun 	.flags.ctrl_tx_rdy_int = CTRL_EXT_TX_RDY_INT,
958*4882a593Smuzhiyun 	.flags.ctrl_rx_rdy_int = CTRL_EXT_RX_RDY_INT,
959*4882a593Smuzhiyun 	.flags.stat_tx_rdy = STAT_EXT_TX_RDY,
960*4882a593Smuzhiyun 	.flags.stat_rx_rdy = STAT_EXT_RX_RDY,
961*4882a593Smuzhiyun };
962*4882a593Smuzhiyun 
963*4882a593Smuzhiyun /* Match table for of_platform binding */
964*4882a593Smuzhiyun static const struct of_device_id mvebu_uart_of_match[] = {
965*4882a593Smuzhiyun 	{
966*4882a593Smuzhiyun 		.compatible = "marvell,armada-3700-uart",
967*4882a593Smuzhiyun 		.data = (void *)&uart_std_driver_data,
968*4882a593Smuzhiyun 	},
969*4882a593Smuzhiyun 	{
970*4882a593Smuzhiyun 		.compatible = "marvell,armada-3700-uart-ext",
971*4882a593Smuzhiyun 		.data = (void *)&uart_ext_driver_data,
972*4882a593Smuzhiyun 	},
973*4882a593Smuzhiyun 	{}
974*4882a593Smuzhiyun };
975*4882a593Smuzhiyun 
976*4882a593Smuzhiyun static struct platform_driver mvebu_uart_platform_driver = {
977*4882a593Smuzhiyun 	.probe	= mvebu_uart_probe,
978*4882a593Smuzhiyun 	.driver	= {
979*4882a593Smuzhiyun 		.name  = "mvebu-uart",
980*4882a593Smuzhiyun 		.of_match_table = of_match_ptr(mvebu_uart_of_match),
981*4882a593Smuzhiyun 		.suppress_bind_attrs = true,
982*4882a593Smuzhiyun #if defined(CONFIG_PM)
983*4882a593Smuzhiyun 		.pm	= &mvebu_uart_pm_ops,
984*4882a593Smuzhiyun #endif /* CONFIG_PM */
985*4882a593Smuzhiyun 	},
986*4882a593Smuzhiyun };
987*4882a593Smuzhiyun 
mvebu_uart_init(void)988*4882a593Smuzhiyun static int __init mvebu_uart_init(void)
989*4882a593Smuzhiyun {
990*4882a593Smuzhiyun 	int ret;
991*4882a593Smuzhiyun 
992*4882a593Smuzhiyun 	ret = uart_register_driver(&mvebu_uart_driver);
993*4882a593Smuzhiyun 	if (ret)
994*4882a593Smuzhiyun 		return ret;
995*4882a593Smuzhiyun 
996*4882a593Smuzhiyun 	ret = platform_driver_register(&mvebu_uart_platform_driver);
997*4882a593Smuzhiyun 	if (ret)
998*4882a593Smuzhiyun 		uart_unregister_driver(&mvebu_uart_driver);
999*4882a593Smuzhiyun 
1000*4882a593Smuzhiyun 	return ret;
1001*4882a593Smuzhiyun }
1002*4882a593Smuzhiyun arch_initcall(mvebu_uart_init);
1003