1*30581040SÁlvaro Fernández Rojas /*
2*30581040SÁlvaro Fernández Rojas  * Copyright (C) 2017 Álvaro Fernández Rojas <noltari@gmail.com>
3*30581040SÁlvaro Fernández Rojas  *
4*30581040SÁlvaro Fernández Rojas  * Derived from linux/drivers/tty/serial/bcm63xx_uart.c:
5*30581040SÁlvaro Fernández Rojas  *	Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr>
6*30581040SÁlvaro Fernández Rojas  *
7*30581040SÁlvaro Fernández Rojas  * SPDX-License-Identifier:	GPL-2.0+
8*30581040SÁlvaro Fernández Rojas  */
9*30581040SÁlvaro Fernández Rojas 
10*30581040SÁlvaro Fernández Rojas #include <clk.h>
11*30581040SÁlvaro Fernández Rojas #include <debug_uart.h>
12*30581040SÁlvaro Fernández Rojas #include <errno.h>
13*30581040SÁlvaro Fernández Rojas #include <serial.h>
14*30581040SÁlvaro Fernández Rojas #include <asm/io.h>
15*30581040SÁlvaro Fernández Rojas #include <asm/types.h>
16*30581040SÁlvaro Fernández Rojas #include <dm/device.h>
17*30581040SÁlvaro Fernández Rojas 
18*30581040SÁlvaro Fernández Rojas /* UART Control register */
19*30581040SÁlvaro Fernández Rojas #define UART_CTL_REG			0x0
20*30581040SÁlvaro Fernández Rojas #define UART_CTL_RXTIMEOUT_MASK		0x1f
21*30581040SÁlvaro Fernández Rojas #define UART_CTL_RXTIMEOUT_5		0x5
22*30581040SÁlvaro Fernández Rojas #define UART_CTL_RSTRXFIFO_SHIFT	6
23*30581040SÁlvaro Fernández Rojas #define UART_CTL_RSTRXFIFO_MASK		(1 << UART_CTL_RSTRXFIFO_SHIFT)
24*30581040SÁlvaro Fernández Rojas #define UART_CTL_RSTTXFIFO_SHIFT	7
25*30581040SÁlvaro Fernández Rojas #define UART_CTL_RSTTXFIFO_MASK		(1 << UART_CTL_RSTTXFIFO_SHIFT)
26*30581040SÁlvaro Fernández Rojas #define UART_CTL_STOPBITS_SHIFT		8
27*30581040SÁlvaro Fernández Rojas #define UART_CTL_STOPBITS_MASK		(0xf << UART_CTL_STOPBITS_SHIFT)
28*30581040SÁlvaro Fernández Rojas #define UART_CTL_STOPBITS_1		(0x7 << UART_CTL_STOPBITS_SHIFT)
29*30581040SÁlvaro Fernández Rojas #define UART_CTL_BITSPERSYM_SHIFT	12
30*30581040SÁlvaro Fernández Rojas #define UART_CTL_BITSPERSYM_MASK	(0x3 << UART_CTL_BITSPERSYM_SHIFT)
31*30581040SÁlvaro Fernández Rojas #define UART_CTL_BITSPERSYM_8		(0x3 << UART_CTL_BITSPERSYM_SHIFT)
32*30581040SÁlvaro Fernández Rojas #define UART_CTL_XMITBRK_SHIFT		14
33*30581040SÁlvaro Fernández Rojas #define UART_CTL_XMITBRK_MASK		(1 << UART_CTL_XMITBRK_SHIFT)
34*30581040SÁlvaro Fernández Rojas #define UART_CTL_RSVD_SHIFT		15
35*30581040SÁlvaro Fernández Rojas #define UART_CTL_RSVD_MASK		(1 << UART_CTL_RSVD_SHIFT)
36*30581040SÁlvaro Fernández Rojas #define UART_CTL_RXPAREVEN_SHIFT	16
37*30581040SÁlvaro Fernández Rojas #define UART_CTL_RXPAREVEN_MASK		(1 << UART_CTL_RXPAREVEN_SHIFT)
38*30581040SÁlvaro Fernández Rojas #define UART_CTL_RXPAREN_SHIFT		17
39*30581040SÁlvaro Fernández Rojas #define UART_CTL_RXPAREN_MASK		(1 << UART_CTL_RXPAREN_SHIFT)
40*30581040SÁlvaro Fernández Rojas #define UART_CTL_TXPAREVEN_SHIFT	18
41*30581040SÁlvaro Fernández Rojas #define UART_CTL_TXPAREVEN_MASK		(1 << UART_CTL_TXPAREVEN_SHIFT)
42*30581040SÁlvaro Fernández Rojas #define UART_CTL_TXPAREN_SHIFT		19
43*30581040SÁlvaro Fernández Rojas #define UART_CTL_TXPAREN_MASK		(1 << UART_CTL_TXPAREN_SHIFT)
44*30581040SÁlvaro Fernández Rojas #define UART_CTL_LOOPBACK_SHIFT		20
45*30581040SÁlvaro Fernández Rojas #define UART_CTL_LOOPBACK_MASK		(1 << UART_CTL_LOOPBACK_SHIFT)
46*30581040SÁlvaro Fernández Rojas #define UART_CTL_RXEN_SHIFT		21
47*30581040SÁlvaro Fernández Rojas #define UART_CTL_RXEN_MASK		(1 << UART_CTL_RXEN_SHIFT)
48*30581040SÁlvaro Fernández Rojas #define UART_CTL_TXEN_SHIFT		22
49*30581040SÁlvaro Fernández Rojas #define UART_CTL_TXEN_MASK		(1 << UART_CTL_TXEN_SHIFT)
50*30581040SÁlvaro Fernández Rojas #define UART_CTL_BRGEN_SHIFT		23
51*30581040SÁlvaro Fernández Rojas #define UART_CTL_BRGEN_MASK		(1 << UART_CTL_BRGEN_SHIFT)
52*30581040SÁlvaro Fernández Rojas 
53*30581040SÁlvaro Fernández Rojas /* UART Baudword register */
54*30581040SÁlvaro Fernández Rojas #define UART_BAUD_REG			0x4
55*30581040SÁlvaro Fernández Rojas 
56*30581040SÁlvaro Fernández Rojas /* UART FIFO Config register */
57*30581040SÁlvaro Fernández Rojas #define UART_FIFO_CFG_REG		0x8
58*30581040SÁlvaro Fernández Rojas #define UART_FIFO_CFG_RX_SHIFT		8
59*30581040SÁlvaro Fernández Rojas #define UART_FIFO_CFG_RX_MASK		(0xf << UART_FIFO_CFG_RX_SHIFT)
60*30581040SÁlvaro Fernández Rojas #define UART_FIFO_CFG_RX_4		(0x4 << UART_FIFO_CFG_RX_SHIFT)
61*30581040SÁlvaro Fernández Rojas #define UART_FIFO_CFG_TX_SHIFT		12
62*30581040SÁlvaro Fernández Rojas #define UART_FIFO_CFG_TX_MASK		(0xf << UART_FIFO_CFG_TX_SHIFT)
63*30581040SÁlvaro Fernández Rojas #define UART_FIFO_CFG_TX_4		(0x4 << UART_FIFO_CFG_TX_SHIFT)
64*30581040SÁlvaro Fernández Rojas 
65*30581040SÁlvaro Fernández Rojas /* UART Interrupt register */
66*30581040SÁlvaro Fernández Rojas #define UART_IR_REG			0x10
67*30581040SÁlvaro Fernández Rojas #define UART_IR_STAT(x)			(1 << (x))
68*30581040SÁlvaro Fernández Rojas #define UART_IR_TXEMPTY			5
69*30581040SÁlvaro Fernández Rojas #define UART_IR_RXOVER			7
70*30581040SÁlvaro Fernández Rojas #define UART_IR_RXNOTEMPTY		11
71*30581040SÁlvaro Fernández Rojas 
72*30581040SÁlvaro Fernández Rojas /* UART FIFO register */
73*30581040SÁlvaro Fernández Rojas #define UART_FIFO_REG			0x14
74*30581040SÁlvaro Fernández Rojas #define UART_FIFO_VALID_MASK		0xff
75*30581040SÁlvaro Fernández Rojas #define UART_FIFO_FRAMEERR_SHIFT	8
76*30581040SÁlvaro Fernández Rojas #define UART_FIFO_FRAMEERR_MASK		(1 << UART_FIFO_FRAMEERR_SHIFT)
77*30581040SÁlvaro Fernández Rojas #define UART_FIFO_PARERR_SHIFT		9
78*30581040SÁlvaro Fernández Rojas #define UART_FIFO_PARERR_MASK		(1 << UART_FIFO_PARERR_SHIFT)
79*30581040SÁlvaro Fernández Rojas #define UART_FIFO_BRKDET_SHIFT		10
80*30581040SÁlvaro Fernández Rojas #define UART_FIFO_BRKDET_MASK		(1 << UART_FIFO_BRKDET_SHIFT)
81*30581040SÁlvaro Fernández Rojas #define UART_FIFO_ANYERR_MASK		(UART_FIFO_FRAMEERR_MASK |	\
82*30581040SÁlvaro Fernández Rojas 					UART_FIFO_PARERR_MASK |		\
83*30581040SÁlvaro Fernández Rojas 					UART_FIFO_BRKDET_MASK)
84*30581040SÁlvaro Fernández Rojas 
85*30581040SÁlvaro Fernández Rojas struct bcm6345_serial_priv {
86*30581040SÁlvaro Fernández Rojas 	void __iomem *base;
87*30581040SÁlvaro Fernández Rojas 	ulong uartclk;
88*30581040SÁlvaro Fernández Rojas };
89*30581040SÁlvaro Fernández Rojas 
90*30581040SÁlvaro Fernández Rojas /* enable rx & tx operation on uart */
91*30581040SÁlvaro Fernández Rojas static void bcm6345_serial_enable(void __iomem *base)
92*30581040SÁlvaro Fernández Rojas {
93*30581040SÁlvaro Fernández Rojas 	setbits_be32(base + UART_CTL_REG, UART_CTL_BRGEN_MASK |
94*30581040SÁlvaro Fernández Rojas 		     UART_CTL_TXEN_MASK | UART_CTL_RXEN_MASK);
95*30581040SÁlvaro Fernández Rojas }
96*30581040SÁlvaro Fernández Rojas 
97*30581040SÁlvaro Fernández Rojas /* disable rx & tx operation on uart */
98*30581040SÁlvaro Fernández Rojas static void bcm6345_serial_disable(void __iomem *base)
99*30581040SÁlvaro Fernández Rojas {
100*30581040SÁlvaro Fernández Rojas 	clrbits_be32(base + UART_CTL_REG, UART_CTL_BRGEN_MASK |
101*30581040SÁlvaro Fernández Rojas 		     UART_CTL_TXEN_MASK | UART_CTL_RXEN_MASK);
102*30581040SÁlvaro Fernández Rojas }
103*30581040SÁlvaro Fernández Rojas 
104*30581040SÁlvaro Fernández Rojas /* clear all unread data in rx fifo and unsent data in tx fifo */
105*30581040SÁlvaro Fernández Rojas static void bcm6345_serial_flush(void __iomem *base)
106*30581040SÁlvaro Fernández Rojas {
107*30581040SÁlvaro Fernández Rojas 	/* empty rx and tx fifo */
108*30581040SÁlvaro Fernández Rojas 	setbits_be32(base + UART_CTL_REG, UART_CTL_RSTRXFIFO_MASK |
109*30581040SÁlvaro Fernández Rojas 		     UART_CTL_RSTTXFIFO_MASK);
110*30581040SÁlvaro Fernández Rojas 
111*30581040SÁlvaro Fernández Rojas 	/* read any pending char to make sure all irq status are cleared */
112*30581040SÁlvaro Fernández Rojas 	readl_be(base + UART_FIFO_REG);
113*30581040SÁlvaro Fernández Rojas }
114*30581040SÁlvaro Fernández Rojas 
115*30581040SÁlvaro Fernández Rojas static int bcm6345_serial_init(void __iomem *base, ulong clk, u32 baudrate)
116*30581040SÁlvaro Fernández Rojas {
117*30581040SÁlvaro Fernández Rojas 	u32 val;
118*30581040SÁlvaro Fernández Rojas 
119*30581040SÁlvaro Fernández Rojas 	/* mask all irq and flush port */
120*30581040SÁlvaro Fernández Rojas 	bcm6345_serial_disable(base);
121*30581040SÁlvaro Fernández Rojas 	bcm6345_serial_flush(base);
122*30581040SÁlvaro Fernández Rojas 
123*30581040SÁlvaro Fernández Rojas 	/* set uart control config */
124*30581040SÁlvaro Fernández Rojas 	clrsetbits_be32(base + UART_CTL_REG,
125*30581040SÁlvaro Fernández Rojas 			/* clear rx timeout */
126*30581040SÁlvaro Fernández Rojas 			UART_CTL_RXTIMEOUT_MASK |
127*30581040SÁlvaro Fernández Rojas 			/* clear stop bits */
128*30581040SÁlvaro Fernández Rojas 			UART_CTL_STOPBITS_MASK |
129*30581040SÁlvaro Fernández Rojas 			/* clear bits per symbol */
130*30581040SÁlvaro Fernández Rojas 			UART_CTL_BITSPERSYM_MASK |
131*30581040SÁlvaro Fernández Rojas 			/* clear xmit break */
132*30581040SÁlvaro Fernández Rojas 			UART_CTL_XMITBRK_MASK |
133*30581040SÁlvaro Fernández Rojas 			/* clear reserved bit */
134*30581040SÁlvaro Fernández Rojas 			UART_CTL_RSVD_MASK |
135*30581040SÁlvaro Fernández Rojas 			/* disable parity */
136*30581040SÁlvaro Fernández Rojas 			UART_CTL_RXPAREN_MASK |
137*30581040SÁlvaro Fernández Rojas 			UART_CTL_TXPAREN_MASK |
138*30581040SÁlvaro Fernández Rojas 			/* disable loopback */
139*30581040SÁlvaro Fernández Rojas 			UART_CTL_LOOPBACK_MASK,
140*30581040SÁlvaro Fernández Rojas 			/* set timeout to 5 */
141*30581040SÁlvaro Fernández Rojas 			UART_CTL_RXTIMEOUT_5 |
142*30581040SÁlvaro Fernández Rojas 			/* set 8 bits/symbol */
143*30581040SÁlvaro Fernández Rojas 			UART_CTL_BITSPERSYM_8 |
144*30581040SÁlvaro Fernández Rojas 			/* set parity to even */
145*30581040SÁlvaro Fernández Rojas 			UART_CTL_RXPAREVEN_MASK |
146*30581040SÁlvaro Fernández Rojas 			UART_CTL_TXPAREVEN_MASK);
147*30581040SÁlvaro Fernández Rojas 
148*30581040SÁlvaro Fernández Rojas 	/* set uart fifo config */
149*30581040SÁlvaro Fernández Rojas 	clrsetbits_be32(base + UART_FIFO_CFG_REG,
150*30581040SÁlvaro Fernández Rojas 			/* clear fifo config */
151*30581040SÁlvaro Fernández Rojas 			UART_FIFO_CFG_RX_MASK |
152*30581040SÁlvaro Fernández Rojas 			UART_FIFO_CFG_TX_MASK,
153*30581040SÁlvaro Fernández Rojas 			/* set fifo config to 4 */
154*30581040SÁlvaro Fernández Rojas 			UART_FIFO_CFG_RX_4 |
155*30581040SÁlvaro Fernández Rojas 			UART_FIFO_CFG_TX_4);
156*30581040SÁlvaro Fernández Rojas 
157*30581040SÁlvaro Fernández Rojas 	/* set baud rate */
158*30581040SÁlvaro Fernández Rojas 	val = (clk / baudrate) / 16;
159*30581040SÁlvaro Fernández Rojas 	if (val & 0x1)
160*30581040SÁlvaro Fernández Rojas 		val = val;
161*30581040SÁlvaro Fernández Rojas 	else
162*30581040SÁlvaro Fernández Rojas 		val = val / 2 - 1;
163*30581040SÁlvaro Fernández Rojas 	writel_be(val, base + UART_BAUD_REG);
164*30581040SÁlvaro Fernández Rojas 
165*30581040SÁlvaro Fernández Rojas 	/* clear interrupts */
166*30581040SÁlvaro Fernández Rojas 	writel_be(0, base + UART_IR_REG);
167*30581040SÁlvaro Fernández Rojas 
168*30581040SÁlvaro Fernández Rojas 	/* enable uart */
169*30581040SÁlvaro Fernández Rojas 	bcm6345_serial_enable(base);
170*30581040SÁlvaro Fernández Rojas 
171*30581040SÁlvaro Fernández Rojas 	return 0;
172*30581040SÁlvaro Fernández Rojas }
173*30581040SÁlvaro Fernández Rojas 
174*30581040SÁlvaro Fernández Rojas static int bcm6345_serial_pending(struct udevice *dev, bool input)
175*30581040SÁlvaro Fernández Rojas {
176*30581040SÁlvaro Fernández Rojas 	struct bcm6345_serial_priv *priv = dev_get_priv(dev);
177*30581040SÁlvaro Fernández Rojas 	u32 val = readl_be(priv->base + UART_IR_REG);
178*30581040SÁlvaro Fernández Rojas 
179*30581040SÁlvaro Fernández Rojas 	if (input)
180*30581040SÁlvaro Fernández Rojas 		return !!(val & UART_IR_STAT(UART_IR_RXNOTEMPTY));
181*30581040SÁlvaro Fernández Rojas 	else
182*30581040SÁlvaro Fernández Rojas 		return !(val & UART_IR_STAT(UART_IR_TXEMPTY));
183*30581040SÁlvaro Fernández Rojas }
184*30581040SÁlvaro Fernández Rojas 
185*30581040SÁlvaro Fernández Rojas static int bcm6345_serial_setbrg(struct udevice *dev, int baudrate)
186*30581040SÁlvaro Fernández Rojas {
187*30581040SÁlvaro Fernández Rojas 	struct bcm6345_serial_priv *priv = dev_get_priv(dev);
188*30581040SÁlvaro Fernández Rojas 
189*30581040SÁlvaro Fernández Rojas 	return bcm6345_serial_init(priv->base, priv->uartclk, baudrate);
190*30581040SÁlvaro Fernández Rojas }
191*30581040SÁlvaro Fernández Rojas 
192*30581040SÁlvaro Fernández Rojas static int bcm6345_serial_putc(struct udevice *dev, const char ch)
193*30581040SÁlvaro Fernández Rojas {
194*30581040SÁlvaro Fernández Rojas 	struct bcm6345_serial_priv *priv = dev_get_priv(dev);
195*30581040SÁlvaro Fernández Rojas 	u32 val;
196*30581040SÁlvaro Fernández Rojas 
197*30581040SÁlvaro Fernández Rojas 	val = readl_be(priv->base + UART_IR_REG);
198*30581040SÁlvaro Fernández Rojas 	if (!(val & UART_IR_STAT(UART_IR_TXEMPTY)))
199*30581040SÁlvaro Fernández Rojas 		return -EAGAIN;
200*30581040SÁlvaro Fernández Rojas 
201*30581040SÁlvaro Fernández Rojas 	writel_be(ch, priv->base + UART_FIFO_REG);
202*30581040SÁlvaro Fernández Rojas 
203*30581040SÁlvaro Fernández Rojas 	return 0;
204*30581040SÁlvaro Fernández Rojas }
205*30581040SÁlvaro Fernández Rojas 
206*30581040SÁlvaro Fernández Rojas static int bcm6345_serial_getc(struct udevice *dev)
207*30581040SÁlvaro Fernández Rojas {
208*30581040SÁlvaro Fernández Rojas 	struct bcm6345_serial_priv *priv = dev_get_priv(dev);
209*30581040SÁlvaro Fernández Rojas 	u32 val;
210*30581040SÁlvaro Fernández Rojas 
211*30581040SÁlvaro Fernández Rojas 	val = readl_be(priv->base + UART_IR_REG);
212*30581040SÁlvaro Fernández Rojas 	if (val & UART_IR_STAT(UART_IR_RXOVER))
213*30581040SÁlvaro Fernández Rojas 		setbits_be32(priv->base + UART_CTL_REG,
214*30581040SÁlvaro Fernández Rojas 			     UART_CTL_RSTRXFIFO_MASK);
215*30581040SÁlvaro Fernández Rojas 	if (!(val & UART_IR_STAT(UART_IR_RXNOTEMPTY)))
216*30581040SÁlvaro Fernández Rojas 		return -EAGAIN;
217*30581040SÁlvaro Fernández Rojas 
218*30581040SÁlvaro Fernández Rojas 	val = readl_be(priv->base + UART_FIFO_REG);
219*30581040SÁlvaro Fernández Rojas 	if (val & UART_FIFO_ANYERR_MASK)
220*30581040SÁlvaro Fernández Rojas 		return -EAGAIN;
221*30581040SÁlvaro Fernández Rojas 
222*30581040SÁlvaro Fernández Rojas 	return val & UART_FIFO_VALID_MASK;
223*30581040SÁlvaro Fernández Rojas }
224*30581040SÁlvaro Fernández Rojas 
225*30581040SÁlvaro Fernández Rojas static int bcm6345_serial_probe(struct udevice *dev)
226*30581040SÁlvaro Fernández Rojas {
227*30581040SÁlvaro Fernández Rojas 	struct bcm6345_serial_priv *priv = dev_get_priv(dev);
228*30581040SÁlvaro Fernández Rojas 	struct clk clk;
229*30581040SÁlvaro Fernández Rojas 	fdt_addr_t addr;
230*30581040SÁlvaro Fernández Rojas 	fdt_size_t size;
231*30581040SÁlvaro Fernández Rojas 	int ret;
232*30581040SÁlvaro Fernández Rojas 
233*30581040SÁlvaro Fernández Rojas 	/* get address */
234*30581040SÁlvaro Fernández Rojas 	addr = dev_get_addr_size_index(dev, 0, &size);
235*30581040SÁlvaro Fernández Rojas 	if (addr == FDT_ADDR_T_NONE)
236*30581040SÁlvaro Fernández Rojas 		return -EINVAL;
237*30581040SÁlvaro Fernández Rojas 
238*30581040SÁlvaro Fernández Rojas 	priv->base = ioremap(addr, size);
239*30581040SÁlvaro Fernández Rojas 
240*30581040SÁlvaro Fernández Rojas 	/* get clock rate */
241*30581040SÁlvaro Fernández Rojas 	ret = clk_get_by_index(dev, 0, &clk);
242*30581040SÁlvaro Fernández Rojas 	if (ret < 0)
243*30581040SÁlvaro Fernández Rojas 		return ret;
244*30581040SÁlvaro Fernández Rojas 	priv->uartclk = clk_get_rate(&clk) / 2;
245*30581040SÁlvaro Fernández Rojas 	clk_free(&clk);
246*30581040SÁlvaro Fernández Rojas 
247*30581040SÁlvaro Fernández Rojas 	/* initialize serial */
248*30581040SÁlvaro Fernández Rojas 	return bcm6345_serial_init(priv->base, priv->uartclk, CONFIG_BAUDRATE);
249*30581040SÁlvaro Fernández Rojas }
250*30581040SÁlvaro Fernández Rojas 
251*30581040SÁlvaro Fernández Rojas static const struct dm_serial_ops bcm6345_serial_ops = {
252*30581040SÁlvaro Fernández Rojas 	.putc = bcm6345_serial_putc,
253*30581040SÁlvaro Fernández Rojas 	.pending = bcm6345_serial_pending,
254*30581040SÁlvaro Fernández Rojas 	.getc = bcm6345_serial_getc,
255*30581040SÁlvaro Fernández Rojas 	.setbrg = bcm6345_serial_setbrg,
256*30581040SÁlvaro Fernández Rojas };
257*30581040SÁlvaro Fernández Rojas 
258*30581040SÁlvaro Fernández Rojas static const struct udevice_id bcm6345_serial_ids[] = {
259*30581040SÁlvaro Fernández Rojas 	{ .compatible = "brcm,bcm6345-uart" },
260*30581040SÁlvaro Fernández Rojas 	{ /* sentinel */ }
261*30581040SÁlvaro Fernández Rojas };
262*30581040SÁlvaro Fernández Rojas 
263*30581040SÁlvaro Fernández Rojas U_BOOT_DRIVER(bcm6345_serial) = {
264*30581040SÁlvaro Fernández Rojas 	.name = "bcm6345-uart",
265*30581040SÁlvaro Fernández Rojas 	.id = UCLASS_SERIAL,
266*30581040SÁlvaro Fernández Rojas 	.of_match = bcm6345_serial_ids,
267*30581040SÁlvaro Fernández Rojas 	.probe = bcm6345_serial_probe,
268*30581040SÁlvaro Fernández Rojas 	.priv_auto_alloc_size = sizeof(struct bcm6345_serial_priv),
269*30581040SÁlvaro Fernández Rojas 	.ops = &bcm6345_serial_ops,
270*30581040SÁlvaro Fernández Rojas 	.flags = DM_FLAG_PRE_RELOC,
271*30581040SÁlvaro Fernández Rojas };
272*30581040SÁlvaro Fernández Rojas 
273*30581040SÁlvaro Fernández Rojas #ifdef CONFIG_DEBUG_UART_BCM6345
274*30581040SÁlvaro Fernández Rojas static inline void _debug_uart_init(void)
275*30581040SÁlvaro Fernández Rojas {
276*30581040SÁlvaro Fernández Rojas 	void __iomem *base = (void __iomem *)CONFIG_DEBUG_UART_BASE;
277*30581040SÁlvaro Fernández Rojas 
278*30581040SÁlvaro Fernández Rojas 	bcm6345_serial_init(base, CONFIG_DEBUG_UART_CLOCK, CONFIG_BAUDRATE);
279*30581040SÁlvaro Fernández Rojas }
280*30581040SÁlvaro Fernández Rojas 
281*30581040SÁlvaro Fernández Rojas static inline void wait_xfered(void __iomem *base)
282*30581040SÁlvaro Fernández Rojas {
283*30581040SÁlvaro Fernández Rojas 	do {
284*30581040SÁlvaro Fernández Rojas 		u32 val = readl_be(base + UART_IR_REG);
285*30581040SÁlvaro Fernández Rojas 		if (val & UART_IR_STAT(UART_IR_TXEMPTY))
286*30581040SÁlvaro Fernández Rojas 			break;
287*30581040SÁlvaro Fernández Rojas 	} while (1);
288*30581040SÁlvaro Fernández Rojas }
289*30581040SÁlvaro Fernández Rojas 
290*30581040SÁlvaro Fernández Rojas static inline void _debug_uart_putc(int ch)
291*30581040SÁlvaro Fernández Rojas {
292*30581040SÁlvaro Fernández Rojas 	void __iomem *base = (void __iomem *)CONFIG_DEBUG_UART_BASE;
293*30581040SÁlvaro Fernández Rojas 
294*30581040SÁlvaro Fernández Rojas 	wait_xfered(base);
295*30581040SÁlvaro Fernández Rojas 	writel_be(ch, base + UART_FIFO_REG);
296*30581040SÁlvaro Fernández Rojas 	wait_xfered(base);
297*30581040SÁlvaro Fernández Rojas }
298*30581040SÁlvaro Fernández Rojas 
299*30581040SÁlvaro Fernández Rojas DEBUG_UART_FUNCS
300*30581040SÁlvaro Fernández Rojas #endif
301