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