183d290c5STom Rini // SPDX-License-Identifier: GPL-2.0+
230581040SÁlvaro Fernández Rojas /*
330581040SÁlvaro Fernández Rojas  * Copyright (C) 2017 Álvaro Fernández Rojas <noltari@gmail.com>
430581040SÁlvaro Fernández Rojas  *
530581040SÁlvaro Fernández Rojas  * Derived from linux/drivers/tty/serial/bcm63xx_uart.c:
630581040SÁlvaro Fernández Rojas  *	Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr>
730581040SÁlvaro Fernández Rojas  */
830581040SÁlvaro Fernández Rojas 
930581040SÁlvaro Fernández Rojas #include <clk.h>
109d922450SSimon Glass #include <dm.h>
1130581040SÁlvaro Fernández Rojas #include <debug_uart.h>
1230581040SÁlvaro Fernández Rojas #include <errno.h>
1330581040SÁlvaro Fernández Rojas #include <serial.h>
1430581040SÁlvaro Fernández Rojas #include <asm/io.h>
1530581040SÁlvaro Fernández Rojas #include <asm/types.h>
1630581040SÁlvaro Fernández Rojas 
1730581040SÁlvaro Fernández Rojas /* UART Control register */
1830581040SÁlvaro Fernández Rojas #define UART_CTL_REG			0x0
1930581040SÁlvaro Fernández Rojas #define UART_CTL_RXTIMEOUT_MASK		0x1f
2030581040SÁlvaro Fernández Rojas #define UART_CTL_RXTIMEOUT_5		0x5
2130581040SÁlvaro Fernández Rojas #define UART_CTL_RSTRXFIFO_SHIFT	6
2230581040SÁlvaro Fernández Rojas #define UART_CTL_RSTRXFIFO_MASK		(1 << UART_CTL_RSTRXFIFO_SHIFT)
2330581040SÁlvaro Fernández Rojas #define UART_CTL_RSTTXFIFO_SHIFT	7
2430581040SÁlvaro Fernández Rojas #define UART_CTL_RSTTXFIFO_MASK		(1 << UART_CTL_RSTTXFIFO_SHIFT)
2530581040SÁlvaro Fernández Rojas #define UART_CTL_STOPBITS_SHIFT		8
2630581040SÁlvaro Fernández Rojas #define UART_CTL_STOPBITS_MASK		(0xf << UART_CTL_STOPBITS_SHIFT)
2730581040SÁlvaro Fernández Rojas #define UART_CTL_STOPBITS_1		(0x7 << UART_CTL_STOPBITS_SHIFT)
2830581040SÁlvaro Fernández Rojas #define UART_CTL_BITSPERSYM_SHIFT	12
2930581040SÁlvaro Fernández Rojas #define UART_CTL_BITSPERSYM_MASK	(0x3 << UART_CTL_BITSPERSYM_SHIFT)
3030581040SÁlvaro Fernández Rojas #define UART_CTL_BITSPERSYM_8		(0x3 << UART_CTL_BITSPERSYM_SHIFT)
3130581040SÁlvaro Fernández Rojas #define UART_CTL_XMITBRK_SHIFT		14
3230581040SÁlvaro Fernández Rojas #define UART_CTL_XMITBRK_MASK		(1 << UART_CTL_XMITBRK_SHIFT)
3330581040SÁlvaro Fernández Rojas #define UART_CTL_RSVD_SHIFT		15
3430581040SÁlvaro Fernández Rojas #define UART_CTL_RSVD_MASK		(1 << UART_CTL_RSVD_SHIFT)
3530581040SÁlvaro Fernández Rojas #define UART_CTL_RXPAREVEN_SHIFT	16
3630581040SÁlvaro Fernández Rojas #define UART_CTL_RXPAREVEN_MASK		(1 << UART_CTL_RXPAREVEN_SHIFT)
3730581040SÁlvaro Fernández Rojas #define UART_CTL_RXPAREN_SHIFT		17
3830581040SÁlvaro Fernández Rojas #define UART_CTL_RXPAREN_MASK		(1 << UART_CTL_RXPAREN_SHIFT)
3930581040SÁlvaro Fernández Rojas #define UART_CTL_TXPAREVEN_SHIFT	18
4030581040SÁlvaro Fernández Rojas #define UART_CTL_TXPAREVEN_MASK		(1 << UART_CTL_TXPAREVEN_SHIFT)
4130581040SÁlvaro Fernández Rojas #define UART_CTL_TXPAREN_SHIFT		19
4230581040SÁlvaro Fernández Rojas #define UART_CTL_TXPAREN_MASK		(1 << UART_CTL_TXPAREN_SHIFT)
4330581040SÁlvaro Fernández Rojas #define UART_CTL_LOOPBACK_SHIFT		20
4430581040SÁlvaro Fernández Rojas #define UART_CTL_LOOPBACK_MASK		(1 << UART_CTL_LOOPBACK_SHIFT)
4530581040SÁlvaro Fernández Rojas #define UART_CTL_RXEN_SHIFT		21
4630581040SÁlvaro Fernández Rojas #define UART_CTL_RXEN_MASK		(1 << UART_CTL_RXEN_SHIFT)
4730581040SÁlvaro Fernández Rojas #define UART_CTL_TXEN_SHIFT		22
4830581040SÁlvaro Fernández Rojas #define UART_CTL_TXEN_MASK		(1 << UART_CTL_TXEN_SHIFT)
4930581040SÁlvaro Fernández Rojas #define UART_CTL_BRGEN_SHIFT		23
5030581040SÁlvaro Fernández Rojas #define UART_CTL_BRGEN_MASK		(1 << UART_CTL_BRGEN_SHIFT)
5130581040SÁlvaro Fernández Rojas 
5230581040SÁlvaro Fernández Rojas /* UART Baudword register */
5330581040SÁlvaro Fernández Rojas #define UART_BAUD_REG			0x4
5430581040SÁlvaro Fernández Rojas 
5530581040SÁlvaro Fernández Rojas /* UART FIFO Config register */
5630581040SÁlvaro Fernández Rojas #define UART_FIFO_CFG_REG		0x8
5730581040SÁlvaro Fernández Rojas #define UART_FIFO_CFG_RX_SHIFT		8
5830581040SÁlvaro Fernández Rojas #define UART_FIFO_CFG_RX_MASK		(0xf << UART_FIFO_CFG_RX_SHIFT)
5930581040SÁlvaro Fernández Rojas #define UART_FIFO_CFG_RX_4		(0x4 << UART_FIFO_CFG_RX_SHIFT)
6030581040SÁlvaro Fernández Rojas #define UART_FIFO_CFG_TX_SHIFT		12
6130581040SÁlvaro Fernández Rojas #define UART_FIFO_CFG_TX_MASK		(0xf << UART_FIFO_CFG_TX_SHIFT)
6230581040SÁlvaro Fernández Rojas #define UART_FIFO_CFG_TX_4		(0x4 << UART_FIFO_CFG_TX_SHIFT)
6330581040SÁlvaro Fernández Rojas 
6430581040SÁlvaro Fernández Rojas /* UART Interrupt register */
6530581040SÁlvaro Fernández Rojas #define UART_IR_REG			0x10
6630581040SÁlvaro Fernández Rojas #define UART_IR_STAT(x)			(1 << (x))
6730581040SÁlvaro Fernández Rojas #define UART_IR_TXEMPTY			5
6830581040SÁlvaro Fernández Rojas #define UART_IR_RXOVER			7
6930581040SÁlvaro Fernández Rojas #define UART_IR_RXNOTEMPTY		11
7030581040SÁlvaro Fernández Rojas 
7130581040SÁlvaro Fernández Rojas /* UART FIFO register */
7230581040SÁlvaro Fernández Rojas #define UART_FIFO_REG			0x14
7330581040SÁlvaro Fernández Rojas #define UART_FIFO_VALID_MASK		0xff
7430581040SÁlvaro Fernández Rojas #define UART_FIFO_FRAMEERR_SHIFT	8
7530581040SÁlvaro Fernández Rojas #define UART_FIFO_FRAMEERR_MASK		(1 << UART_FIFO_FRAMEERR_SHIFT)
7630581040SÁlvaro Fernández Rojas #define UART_FIFO_PARERR_SHIFT		9
7730581040SÁlvaro Fernández Rojas #define UART_FIFO_PARERR_MASK		(1 << UART_FIFO_PARERR_SHIFT)
7830581040SÁlvaro Fernández Rojas #define UART_FIFO_BRKDET_SHIFT		10
7930581040SÁlvaro Fernández Rojas #define UART_FIFO_BRKDET_MASK		(1 << UART_FIFO_BRKDET_SHIFT)
8030581040SÁlvaro Fernández Rojas #define UART_FIFO_ANYERR_MASK		(UART_FIFO_FRAMEERR_MASK |	\
8130581040SÁlvaro Fernández Rojas 					UART_FIFO_PARERR_MASK |		\
8230581040SÁlvaro Fernández Rojas 					UART_FIFO_BRKDET_MASK)
8330581040SÁlvaro Fernández Rojas 
8430581040SÁlvaro Fernández Rojas struct bcm6345_serial_priv {
8530581040SÁlvaro Fernández Rojas 	void __iomem *base;
8630581040SÁlvaro Fernández Rojas 	ulong uartclk;
8730581040SÁlvaro Fernández Rojas };
8830581040SÁlvaro Fernández Rojas 
8930581040SÁlvaro Fernández Rojas /* enable rx & tx operation on uart */
bcm6345_serial_enable(void __iomem * base)9030581040SÁlvaro Fernández Rojas static void bcm6345_serial_enable(void __iomem *base)
9130581040SÁlvaro Fernández Rojas {
92*09ace916SÁlvaro Fernández Rojas 	setbits_32(base + UART_CTL_REG, UART_CTL_BRGEN_MASK |
9330581040SÁlvaro Fernández Rojas 		   UART_CTL_TXEN_MASK | UART_CTL_RXEN_MASK);
9430581040SÁlvaro Fernández Rojas }
9530581040SÁlvaro Fernández Rojas 
9630581040SÁlvaro Fernández Rojas /* disable rx & tx operation on uart */
bcm6345_serial_disable(void __iomem * base)9730581040SÁlvaro Fernández Rojas static void bcm6345_serial_disable(void __iomem *base)
9830581040SÁlvaro Fernández Rojas {
99*09ace916SÁlvaro Fernández Rojas 	clrbits_32(base + UART_CTL_REG, UART_CTL_BRGEN_MASK |
10030581040SÁlvaro Fernández Rojas 		   UART_CTL_TXEN_MASK | UART_CTL_RXEN_MASK);
10130581040SÁlvaro Fernández Rojas }
10230581040SÁlvaro Fernández Rojas 
10330581040SÁlvaro Fernández Rojas /* clear all unread data in rx fifo and unsent data in tx fifo */
bcm6345_serial_flush(void __iomem * base)10430581040SÁlvaro Fernández Rojas static void bcm6345_serial_flush(void __iomem *base)
10530581040SÁlvaro Fernández Rojas {
10630581040SÁlvaro Fernández Rojas 	/* empty rx and tx fifo */
107*09ace916SÁlvaro Fernández Rojas 	setbits_32(base + UART_CTL_REG, UART_CTL_RSTRXFIFO_MASK |
10830581040SÁlvaro Fernández Rojas 		   UART_CTL_RSTTXFIFO_MASK);
10930581040SÁlvaro Fernández Rojas 
11030581040SÁlvaro Fernández Rojas 	/* read any pending char to make sure all irq status are cleared */
111*09ace916SÁlvaro Fernández Rojas 	readl(base + UART_FIFO_REG);
11230581040SÁlvaro Fernández Rojas }
11330581040SÁlvaro Fernández Rojas 
bcm6345_serial_init(void __iomem * base,ulong clk,u32 baudrate)11430581040SÁlvaro Fernández Rojas static int bcm6345_serial_init(void __iomem *base, ulong clk, u32 baudrate)
11530581040SÁlvaro Fernández Rojas {
11630581040SÁlvaro Fernández Rojas 	u32 val;
11730581040SÁlvaro Fernández Rojas 
11830581040SÁlvaro Fernández Rojas 	/* mask all irq and flush port */
11930581040SÁlvaro Fernández Rojas 	bcm6345_serial_disable(base);
12030581040SÁlvaro Fernández Rojas 	bcm6345_serial_flush(base);
12130581040SÁlvaro Fernández Rojas 
12230581040SÁlvaro Fernández Rojas 	/* set uart control config */
123*09ace916SÁlvaro Fernández Rojas 	clrsetbits_32(base + UART_CTL_REG,
12430581040SÁlvaro Fernández Rojas 		      /* clear rx timeout */
12530581040SÁlvaro Fernández Rojas 		      UART_CTL_RXTIMEOUT_MASK |
12630581040SÁlvaro Fernández Rojas 		      /* clear stop bits */
12730581040SÁlvaro Fernández Rojas 		      UART_CTL_STOPBITS_MASK |
12830581040SÁlvaro Fernández Rojas 		      /* clear bits per symbol */
12930581040SÁlvaro Fernández Rojas 		      UART_CTL_BITSPERSYM_MASK |
13030581040SÁlvaro Fernández Rojas 		      /* clear xmit break */
13130581040SÁlvaro Fernández Rojas 		      UART_CTL_XMITBRK_MASK |
13230581040SÁlvaro Fernández Rojas 		      /* clear reserved bit */
13330581040SÁlvaro Fernández Rojas 		      UART_CTL_RSVD_MASK |
13430581040SÁlvaro Fernández Rojas 		      /* disable parity */
13530581040SÁlvaro Fernández Rojas 		      UART_CTL_RXPAREN_MASK |
13630581040SÁlvaro Fernández Rojas 		      UART_CTL_TXPAREN_MASK |
13730581040SÁlvaro Fernández Rojas 		      /* disable loopback */
13830581040SÁlvaro Fernández Rojas 		      UART_CTL_LOOPBACK_MASK,
13930581040SÁlvaro Fernández Rojas 		      /* set timeout to 5 */
14030581040SÁlvaro Fernández Rojas 		      UART_CTL_RXTIMEOUT_5 |
14130581040SÁlvaro Fernández Rojas 		      /* set 8 bits/symbol */
14230581040SÁlvaro Fernández Rojas 		      UART_CTL_BITSPERSYM_8 |
1436b7185f3SÁlvaro Fernández Rojas 		      /* set 1 stop bit */
1446b7185f3SÁlvaro Fernández Rojas 		      UART_CTL_STOPBITS_1 |
14530581040SÁlvaro Fernández Rojas 		      /* set parity to even */
14630581040SÁlvaro Fernández Rojas 		      UART_CTL_RXPAREVEN_MASK |
14730581040SÁlvaro Fernández Rojas 		      UART_CTL_TXPAREVEN_MASK);
14830581040SÁlvaro Fernández Rojas 
14930581040SÁlvaro Fernández Rojas 	/* set uart fifo config */
150*09ace916SÁlvaro Fernández Rojas 	clrsetbits_32(base + UART_FIFO_CFG_REG,
15130581040SÁlvaro Fernández Rojas 		      /* clear fifo config */
15230581040SÁlvaro Fernández Rojas 		      UART_FIFO_CFG_RX_MASK |
15330581040SÁlvaro Fernández Rojas 		      UART_FIFO_CFG_TX_MASK,
15430581040SÁlvaro Fernández Rojas 		      /* set fifo config to 4 */
15530581040SÁlvaro Fernández Rojas 		      UART_FIFO_CFG_RX_4 |
15630581040SÁlvaro Fernández Rojas 		      UART_FIFO_CFG_TX_4);
15730581040SÁlvaro Fernández Rojas 
15830581040SÁlvaro Fernández Rojas 	/* set baud rate */
15924f85482SÁlvaro Fernández Rojas 	val = ((clk / baudrate) >> 4);
16030581040SÁlvaro Fernández Rojas 	if (val & 0x1)
16124f85482SÁlvaro Fernández Rojas 		val = (val >> 1);
16230581040SÁlvaro Fernández Rojas 	else
16324f85482SÁlvaro Fernández Rojas 		val = (val >> 1) - 1;
164*09ace916SÁlvaro Fernández Rojas 	writel(val, base + UART_BAUD_REG);
16530581040SÁlvaro Fernández Rojas 
16630581040SÁlvaro Fernández Rojas 	/* clear interrupts */
167*09ace916SÁlvaro Fernández Rojas 	writel(0, base + UART_IR_REG);
16830581040SÁlvaro Fernández Rojas 
16930581040SÁlvaro Fernández Rojas 	/* enable uart */
17030581040SÁlvaro Fernández Rojas 	bcm6345_serial_enable(base);
17130581040SÁlvaro Fernández Rojas 
17230581040SÁlvaro Fernández Rojas 	return 0;
17330581040SÁlvaro Fernández Rojas }
17430581040SÁlvaro Fernández Rojas 
bcm6345_serial_pending(struct udevice * dev,bool input)17530581040SÁlvaro Fernández Rojas static int bcm6345_serial_pending(struct udevice *dev, bool input)
17630581040SÁlvaro Fernández Rojas {
17730581040SÁlvaro Fernández Rojas 	struct bcm6345_serial_priv *priv = dev_get_priv(dev);
178*09ace916SÁlvaro Fernández Rojas 	u32 val = readl(priv->base + UART_IR_REG);
17930581040SÁlvaro Fernández Rojas 
18030581040SÁlvaro Fernández Rojas 	if (input)
18130581040SÁlvaro Fernández Rojas 		return !!(val & UART_IR_STAT(UART_IR_RXNOTEMPTY));
18230581040SÁlvaro Fernández Rojas 	else
18330581040SÁlvaro Fernández Rojas 		return !(val & UART_IR_STAT(UART_IR_TXEMPTY));
18430581040SÁlvaro Fernández Rojas }
18530581040SÁlvaro Fernández Rojas 
bcm6345_serial_setbrg(struct udevice * dev,int baudrate)18630581040SÁlvaro Fernández Rojas static int bcm6345_serial_setbrg(struct udevice *dev, int baudrate)
18730581040SÁlvaro Fernández Rojas {
18830581040SÁlvaro Fernández Rojas 	struct bcm6345_serial_priv *priv = dev_get_priv(dev);
18930581040SÁlvaro Fernández Rojas 
19030581040SÁlvaro Fernández Rojas 	return bcm6345_serial_init(priv->base, priv->uartclk, baudrate);
19130581040SÁlvaro Fernández Rojas }
19230581040SÁlvaro Fernández Rojas 
bcm6345_serial_putc(struct udevice * dev,const char ch)19330581040SÁlvaro Fernández Rojas static int bcm6345_serial_putc(struct udevice *dev, const char ch)
19430581040SÁlvaro Fernández Rojas {
19530581040SÁlvaro Fernández Rojas 	struct bcm6345_serial_priv *priv = dev_get_priv(dev);
19630581040SÁlvaro Fernández Rojas 	u32 val;
19730581040SÁlvaro Fernández Rojas 
198*09ace916SÁlvaro Fernández Rojas 	val = readl(priv->base + UART_IR_REG);
19930581040SÁlvaro Fernández Rojas 	if (!(val & UART_IR_STAT(UART_IR_TXEMPTY)))
20030581040SÁlvaro Fernández Rojas 		return -EAGAIN;
20130581040SÁlvaro Fernández Rojas 
202*09ace916SÁlvaro Fernández Rojas 	writel(ch, priv->base + UART_FIFO_REG);
20330581040SÁlvaro Fernández Rojas 
20430581040SÁlvaro Fernández Rojas 	return 0;
20530581040SÁlvaro Fernández Rojas }
20630581040SÁlvaro Fernández Rojas 
bcm6345_serial_getc(struct udevice * dev)20730581040SÁlvaro Fernández Rojas static int bcm6345_serial_getc(struct udevice *dev)
20830581040SÁlvaro Fernández Rojas {
20930581040SÁlvaro Fernández Rojas 	struct bcm6345_serial_priv *priv = dev_get_priv(dev);
21030581040SÁlvaro Fernández Rojas 	u32 val;
21130581040SÁlvaro Fernández Rojas 
212*09ace916SÁlvaro Fernández Rojas 	val = readl(priv->base + UART_IR_REG);
21330581040SÁlvaro Fernández Rojas 	if (val & UART_IR_STAT(UART_IR_RXOVER))
214*09ace916SÁlvaro Fernández Rojas 		setbits_32(priv->base + UART_CTL_REG, UART_CTL_RSTRXFIFO_MASK);
21530581040SÁlvaro Fernández Rojas 	if (!(val & UART_IR_STAT(UART_IR_RXNOTEMPTY)))
21630581040SÁlvaro Fernández Rojas 		return -EAGAIN;
21730581040SÁlvaro Fernández Rojas 
218*09ace916SÁlvaro Fernández Rojas 	val = readl(priv->base + UART_FIFO_REG);
21930581040SÁlvaro Fernández Rojas 	if (val & UART_FIFO_ANYERR_MASK)
22030581040SÁlvaro Fernández Rojas 		return -EAGAIN;
22130581040SÁlvaro Fernández Rojas 
22230581040SÁlvaro Fernández Rojas 	return val & UART_FIFO_VALID_MASK;
22330581040SÁlvaro Fernández Rojas }
22430581040SÁlvaro Fernández Rojas 
bcm6345_serial_probe(struct udevice * dev)22530581040SÁlvaro Fernández Rojas static int bcm6345_serial_probe(struct udevice *dev)
22630581040SÁlvaro Fernández Rojas {
22730581040SÁlvaro Fernández Rojas 	struct bcm6345_serial_priv *priv = dev_get_priv(dev);
22830581040SÁlvaro Fernández Rojas 	struct clk clk;
22930581040SÁlvaro Fernández Rojas 	int ret;
23030581040SÁlvaro Fernández Rojas 
23130581040SÁlvaro Fernández Rojas 	/* get address */
2320f569937SÁlvaro Fernández Rojas 	priv->base = dev_remap_addr(dev);
2330f569937SÁlvaro Fernández Rojas 	if (!priv->base)
23430581040SÁlvaro Fernández Rojas 		return -EINVAL;
23530581040SÁlvaro Fernández Rojas 
23630581040SÁlvaro Fernández Rojas 	/* get clock rate */
23730581040SÁlvaro Fernández Rojas 	ret = clk_get_by_index(dev, 0, &clk);
23830581040SÁlvaro Fernández Rojas 	if (ret < 0)
23930581040SÁlvaro Fernández Rojas 		return ret;
24024f85482SÁlvaro Fernández Rojas 	priv->uartclk = clk_get_rate(&clk);
24130581040SÁlvaro Fernández Rojas 	clk_free(&clk);
24230581040SÁlvaro Fernández Rojas 
24330581040SÁlvaro Fernández Rojas 	/* initialize serial */
24430581040SÁlvaro Fernández Rojas 	return bcm6345_serial_init(priv->base, priv->uartclk, CONFIG_BAUDRATE);
24530581040SÁlvaro Fernández Rojas }
24630581040SÁlvaro Fernández Rojas 
24730581040SÁlvaro Fernández Rojas static const struct dm_serial_ops bcm6345_serial_ops = {
24830581040SÁlvaro Fernández Rojas 	.putc = bcm6345_serial_putc,
24930581040SÁlvaro Fernández Rojas 	.pending = bcm6345_serial_pending,
25030581040SÁlvaro Fernández Rojas 	.getc = bcm6345_serial_getc,
25130581040SÁlvaro Fernández Rojas 	.setbrg = bcm6345_serial_setbrg,
25230581040SÁlvaro Fernández Rojas };
25330581040SÁlvaro Fernández Rojas 
25430581040SÁlvaro Fernández Rojas static const struct udevice_id bcm6345_serial_ids[] = {
25530581040SÁlvaro Fernández Rojas 	{ .compatible = "brcm,bcm6345-uart" },
25630581040SÁlvaro Fernández Rojas 	{ /* sentinel */ }
25730581040SÁlvaro Fernández Rojas };
25830581040SÁlvaro Fernández Rojas 
25930581040SÁlvaro Fernández Rojas U_BOOT_DRIVER(bcm6345_serial) = {
26030581040SÁlvaro Fernández Rojas 	.name = "bcm6345-uart",
26130581040SÁlvaro Fernández Rojas 	.id = UCLASS_SERIAL,
26230581040SÁlvaro Fernández Rojas 	.of_match = bcm6345_serial_ids,
26330581040SÁlvaro Fernández Rojas 	.probe = bcm6345_serial_probe,
26430581040SÁlvaro Fernández Rojas 	.priv_auto_alloc_size = sizeof(struct bcm6345_serial_priv),
26530581040SÁlvaro Fernández Rojas 	.ops = &bcm6345_serial_ops,
26630581040SÁlvaro Fernández Rojas };
26730581040SÁlvaro Fernández Rojas 
26830581040SÁlvaro Fernández Rojas #ifdef CONFIG_DEBUG_UART_BCM6345
_debug_uart_init(void)26930581040SÁlvaro Fernández Rojas static inline void _debug_uart_init(void)
27030581040SÁlvaro Fernández Rojas {
27130581040SÁlvaro Fernández Rojas 	void __iomem *base = (void __iomem *)CONFIG_DEBUG_UART_BASE;
27230581040SÁlvaro Fernández Rojas 
27330581040SÁlvaro Fernández Rojas 	bcm6345_serial_init(base, CONFIG_DEBUG_UART_CLOCK, CONFIG_BAUDRATE);
27430581040SÁlvaro Fernández Rojas }
27530581040SÁlvaro Fernández Rojas 
wait_xfered(void __iomem * base)27630581040SÁlvaro Fernández Rojas static inline void wait_xfered(void __iomem *base)
27730581040SÁlvaro Fernández Rojas {
27830581040SÁlvaro Fernández Rojas 	do {
279*09ace916SÁlvaro Fernández Rojas 		u32 val = readl(base + UART_IR_REG);
28030581040SÁlvaro Fernández Rojas 		if (val & UART_IR_STAT(UART_IR_TXEMPTY))
28130581040SÁlvaro Fernández Rojas 			break;
28230581040SÁlvaro Fernández Rojas 	} while (1);
28330581040SÁlvaro Fernández Rojas }
28430581040SÁlvaro Fernández Rojas 
_debug_uart_putc(int ch)28530581040SÁlvaro Fernández Rojas static inline void _debug_uart_putc(int ch)
28630581040SÁlvaro Fernández Rojas {
28730581040SÁlvaro Fernández Rojas 	void __iomem *base = (void __iomem *)CONFIG_DEBUG_UART_BASE;
28830581040SÁlvaro Fernández Rojas 
28930581040SÁlvaro Fernández Rojas 	wait_xfered(base);
290*09ace916SÁlvaro Fernández Rojas 	writel(ch, base + UART_FIFO_REG);
29130581040SÁlvaro Fernández Rojas 	wait_xfered(base);
29230581040SÁlvaro Fernández Rojas }
29330581040SÁlvaro Fernández Rojas 
29430581040SÁlvaro Fernández Rojas DEBUG_UART_FUNCS
29530581040SÁlvaro Fernández Rojas #endif
296