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