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> 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 #include <dm/device.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 */ 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 */ 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 */ 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 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 | 144*6b7185f3SÁlvaro Fernández Rojas /* set 1 stop bit */ 145*6b7185f3SÁ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 */ 16030581040SÁlvaro Fernández Rojas val = (clk / baudrate) / 16; 16130581040SÁlvaro Fernández Rojas if (val & 0x1) 16230581040SÁlvaro Fernández Rojas val = val; 16330581040SÁlvaro Fernández Rojas else 16430581040SÁlvaro Fernández Rojas val = val / 2 - 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 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 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 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 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 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 */ 23630581040SÁlvaro Fernández Rojas addr = dev_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; 24630581040SÁlvaro Fernández Rojas priv->uartclk = clk_get_rate(&clk) / 2; 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 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 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 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