X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=drivers%2Fserial%2Fserial_uniphier.c;h=8878079666de67d43e5423a780918909c61a1213;hb=93cf0ae7758d66475963a6b2186e41c51a1840aa;hp=3f3d4152134af0a1706535e0b11e21849442ef84;hpb=2dbbda08b92b006b541a099a3025cac12c6d720e;p=u-boot diff --git a/drivers/serial/serial_uniphier.c b/drivers/serial/serial_uniphier.c index 3f3d415213..8878079666 100644 --- a/drivers/serial/serial_uniphier.c +++ b/drivers/serial/serial_uniphier.c @@ -1,55 +1,41 @@ +// SPDX-License-Identifier: GPL-2.0+ /* - * Copyright (C) 2012-2014 Panasonic Corporation - * Author: Masahiro Yamada - * - * SPDX-License-Identifier: GPL-2.0+ + * Copyright (C) 2012-2015 Panasonic Corporation + * Copyright (C) 2015-2016 Socionext Inc. + * Author: Masahiro Yamada */ #include -#include -#include -#include -#include +#include +#include +#include +#include +#include #include - -#define UART_REG(x) \ - u8 x; \ - u8 postpad_##x[3]; +#include /* * Note: Register map is slightly different from that of 16550. */ struct uniphier_serial { - UART_REG(rbr); /* 0x00 */ - UART_REG(ier); /* 0x04 */ - UART_REG(iir); /* 0x08 */ - UART_REG(fcr); /* 0x0c */ - u8 mcr; /* 0x10 */ - u8 lcr; - u16 __postpad; - UART_REG(lsr); /* 0x14 */ - UART_REG(msr); /* 0x18 */ - u32 __none1; - u32 __none2; - u16 dlr; - u16 __postpad2; + u32 rx; /* In: Receive buffer */ +#define tx rx /* Out: Transmit buffer */ + u32 ier; /* Interrupt Enable Register */ + u32 iir; /* In: Interrupt ID Register */ + u32 char_fcr; /* Charactor / FIFO Control Register */ + u32 lcr_mcr; /* Line/Modem Control Register */ +#define LCR_SHIFT 8 +#define LCR_MASK (0xff << (LCR_SHIFT)) + u32 lsr; /* In: Line Status Register */ + u32 msr; /* In: Modem Status Register */ + u32 __rsv0; + u32 __rsv1; + u32 dlr; /* Divisor Latch Register */ }; -#define thr rbr - -/* - * These are the definitions for the Line Control Register - */ -#define UART_LCR_WLS_8 0x03 /* 8 bit character length */ - -/* - * These are the definitions for the Line Status Register - */ -#define UART_LSR_DR 0x01 /* Data ready */ -#define UART_LSR_THRE 0x20 /* Xmit holding register empty */ - struct uniphier_serial_private_data { struct uniphier_serial __iomem *membase; + unsigned int uartclk; }; #define uniphier_serial_port(dev) \ @@ -57,16 +43,14 @@ struct uniphier_serial_private_data { static int uniphier_serial_setbrg(struct udevice *dev, int baudrate) { - struct uniphier_serial_platform_data *plat = dev_get_platdata(dev); + struct uniphier_serial_private_data *priv = dev_get_priv(dev); struct uniphier_serial __iomem *port = uniphier_serial_port(dev); const unsigned int mode_x_div = 16; unsigned int divisor; - writeb(UART_LCR_WLS_8, &port->lcr); + divisor = DIV_ROUND_CLOSEST(priv->uartclk, mode_x_div * baudrate); - divisor = DIV_ROUND_CLOSEST(plat->uartclk, mode_x_div * baudrate); - - writew(divisor, &port->dlr); + writel(divisor, &port->dlr); return 0; } @@ -75,20 +59,20 @@ static int uniphier_serial_getc(struct udevice *dev) { struct uniphier_serial __iomem *port = uniphier_serial_port(dev); - if (!(readb(&port->lsr) & UART_LSR_DR)) + if (!(readl(&port->lsr) & UART_LSR_DR)) return -EAGAIN; - return readb(&port->rbr); + return readl(&port->rx); } static int uniphier_serial_putc(struct udevice *dev, const char c) { struct uniphier_serial __iomem *port = uniphier_serial_port(dev); - if (!(readb(&port->lsr) & UART_LSR_THRE)) + if (!(readl(&port->lsr) & UART_LSR_THRE)) return -EAGAIN; - writeb(c, &port->thr); + writel(c, &port->tx); return 0; } @@ -98,48 +82,45 @@ static int uniphier_serial_pending(struct udevice *dev, bool input) struct uniphier_serial __iomem *port = uniphier_serial_port(dev); if (input) - return readb(&port->lsr) & UART_LSR_DR; + return readl(&port->lsr) & UART_LSR_DR; else - return !(readb(&port->lsr) & UART_LSR_THRE); + return !(readl(&port->lsr) & UART_LSR_THRE); } static int uniphier_serial_probe(struct udevice *dev) { + DECLARE_GLOBAL_DATA_PTR; struct uniphier_serial_private_data *priv = dev_get_priv(dev); - struct uniphier_serial_platform_data *plat = dev_get_platdata(dev); + struct uniphier_serial __iomem *port; + fdt_addr_t base; + u32 tmp; - priv->membase = map_sysmem(plat->base, sizeof(struct uniphier_serial)); + base = devfdt_get_addr(dev); + if (base == FDT_ADDR_T_NONE) + return -EINVAL; - if (!priv->membase) + port = devm_ioremap(dev, base, SZ_64); + if (!port) return -ENOMEM; - return 0; -} + priv->membase = port; -static int uniphier_serial_remove(struct udevice *dev) -{ - unmap_sysmem(uniphier_serial_port(dev)); + priv->uartclk = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev), + "clock-frequency", 0); + + tmp = readl(&port->lcr_mcr); + tmp &= ~LCR_MASK; + tmp |= UART_LCR_WLEN8 << LCR_SHIFT; + writel(tmp, &port->lcr_mcr); return 0; } -#ifdef CONFIG_OF_CONTROL -static const struct udevice_id uniphier_uart_of_match = { - { .compatible = "panasonic,uniphier-uart"}, - {}, +static const struct udevice_id uniphier_uart_of_match[] = { + { .compatible = "socionext,uniphier-uart" }, + { /* sentinel */ } }; -static int uniphier_serial_ofdata_to_platdata(struct udevice *dev) -{ - /* - * TODO: Masahiro Yamada (yamada.m@jp.panasonic.com) - * - * Implement conversion code from DTB to platform data - * when supporting CONFIG_OF_CONTROL on UniPhir platform. - */ -} -#endif - static const struct dm_serial_ops uniphier_serial_ops = { .setbrg = uniphier_serial_setbrg, .getc = uniphier_serial_getc, @@ -148,15 +129,10 @@ static const struct dm_serial_ops uniphier_serial_ops = { }; U_BOOT_DRIVER(uniphier_serial) = { - .name = DRIVER_NAME, + .name = "uniphier-uart", .id = UCLASS_SERIAL, - .of_match = of_match_ptr(uniphier_uart_of_match), - .ofdata_to_platdata = of_match_ptr(uniphier_serial_ofdata_to_platdata), + .of_match = uniphier_uart_of_match, .probe = uniphier_serial_probe, - .remove = uniphier_serial_remove, .priv_auto_alloc_size = sizeof(struct uniphier_serial_private_data), - .platdata_auto_alloc_size = - sizeof(struct uniphier_serial_platform_data), .ops = &uniphier_serial_ops, - .flags = DM_FLAG_PRE_RELOC, };