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