1 /* 2 * Copyright (C) 2015 Masahiro Yamada <yamada.masahiro@socionext.com> 3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation; either version 2 of the License, or 7 * (at your option) any later version. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 */ 14 15 #include <linux/clk.h> 16 #include <linux/console.h> 17 #include <linux/io.h> 18 #include <linux/module.h> 19 #include <linux/of.h> 20 #include <linux/platform_device.h> 21 22 #include "8250.h" 23 24 /* Most (but not all) of UniPhier UART devices have 64-depth FIFO. */ 25 #define UNIPHIER_UART_DEFAULT_FIFO_SIZE 64 26 27 #define UNIPHIER_UART_CHAR_FCR 3 /* Character / FIFO Control Register */ 28 #define UNIPHIER_UART_LCR_MCR 4 /* Line/Modem Control Register */ 29 #define UNIPHIER_UART_LCR_SHIFT 8 30 #define UNIPHIER_UART_DLR 9 /* Divisor Latch Register */ 31 32 struct uniphier8250_priv { 33 int line; 34 struct clk *clk; 35 spinlock_t atomic_write_lock; 36 }; 37 38 #ifdef CONFIG_SERIAL_8250_CONSOLE 39 static int __init uniphier_early_console_setup(struct earlycon_device *device, 40 const char *options) 41 { 42 if (!device->port.membase) 43 return -ENODEV; 44 45 /* This hardware always expects MMIO32 register interface. */ 46 device->port.iotype = UPIO_MEM32; 47 device->port.regshift = 2; 48 49 /* 50 * Do not touch the divisor register in early_serial8250_setup(); 51 * we assume it has been initialized by a boot loader. 52 */ 53 device->baud = 0; 54 55 return early_serial8250_setup(device, options); 56 } 57 OF_EARLYCON_DECLARE(uniphier, "socionext,uniphier-uart", 58 uniphier_early_console_setup); 59 #endif 60 61 /* 62 * The register map is slightly different from that of 8250. 63 * IO callbacks must be overridden for correct access to FCR, LCR, and MCR. 64 */ 65 static unsigned int uniphier_serial_in(struct uart_port *p, int offset) 66 { 67 unsigned int valshift = 0; 68 69 switch (offset) { 70 case UART_LCR: 71 valshift = UNIPHIER_UART_LCR_SHIFT; 72 /* fall through */ 73 case UART_MCR: 74 offset = UNIPHIER_UART_LCR_MCR; 75 break; 76 default: 77 break; 78 } 79 80 offset <<= p->regshift; 81 82 /* 83 * The return value must be masked with 0xff because LCR and MCR reside 84 * in the same register that must be accessed by 32-bit write/read. 85 * 8 or 16 bit access to this hardware result in unexpected behavior. 86 */ 87 return (readl(p->membase + offset) >> valshift) & 0xff; 88 } 89 90 static void uniphier_serial_out(struct uart_port *p, int offset, int value) 91 { 92 unsigned int valshift = 0; 93 bool normal = false; 94 95 switch (offset) { 96 case UART_FCR: 97 offset = UNIPHIER_UART_CHAR_FCR; 98 break; 99 case UART_LCR: 100 valshift = UNIPHIER_UART_LCR_SHIFT; 101 /* Divisor latch access bit does not exist. */ 102 value &= ~(UART_LCR_DLAB << valshift); 103 /* fall through */ 104 case UART_MCR: 105 offset = UNIPHIER_UART_LCR_MCR; 106 break; 107 default: 108 normal = true; 109 break; 110 } 111 112 offset <<= p->regshift; 113 114 if (normal) { 115 writel(value, p->membase + offset); 116 } else { 117 /* 118 * Special case: two registers share the same address that 119 * must be 32-bit accessed. As this is not longer atomic safe, 120 * take a lock just in case. 121 */ 122 struct uniphier8250_priv *priv = p->private_data; 123 unsigned long flags; 124 u32 tmp; 125 126 spin_lock_irqsave(&priv->atomic_write_lock, flags); 127 tmp = readl(p->membase + offset); 128 tmp &= ~(0xff << valshift); 129 tmp |= value << valshift; 130 writel(tmp, p->membase + offset); 131 spin_unlock_irqrestore(&priv->atomic_write_lock, flags); 132 } 133 } 134 135 /* 136 * This hardware does not have the divisor latch access bit. 137 * The divisor latch register exists at different address. 138 * Override dl_read/write callbacks. 139 */ 140 static int uniphier_serial_dl_read(struct uart_8250_port *up) 141 { 142 int offset = UNIPHIER_UART_DLR << up->port.regshift; 143 144 return readl(up->port.membase + offset); 145 } 146 147 static void uniphier_serial_dl_write(struct uart_8250_port *up, int value) 148 { 149 int offset = UNIPHIER_UART_DLR << up->port.regshift; 150 151 writel(value, up->port.membase + offset); 152 } 153 154 static int uniphier_of_serial_setup(struct device *dev, struct uart_port *port, 155 struct uniphier8250_priv *priv) 156 { 157 int ret; 158 u32 prop; 159 struct device_node *np = dev->of_node; 160 161 ret = of_alias_get_id(np, "serial"); 162 if (ret < 0) { 163 dev_err(dev, "failed to get alias id\n"); 164 return ret; 165 } 166 port->line = priv->line = ret; 167 168 /* Get clk rate through clk driver */ 169 priv->clk = devm_clk_get(dev, NULL); 170 if (IS_ERR(priv->clk)) { 171 dev_err(dev, "failed to get clock\n"); 172 return PTR_ERR(priv->clk); 173 } 174 175 ret = clk_prepare_enable(priv->clk); 176 if (ret < 0) 177 return ret; 178 179 port->uartclk = clk_get_rate(priv->clk); 180 181 /* Check for fifo size */ 182 if (of_property_read_u32(np, "fifo-size", &prop) == 0) 183 port->fifosize = prop; 184 else 185 port->fifosize = UNIPHIER_UART_DEFAULT_FIFO_SIZE; 186 187 return 0; 188 } 189 190 static int uniphier_uart_probe(struct platform_device *pdev) 191 { 192 struct device *dev = &pdev->dev; 193 struct uart_8250_port up; 194 struct uniphier8250_priv *priv; 195 struct resource *regs; 196 void __iomem *membase; 197 int irq; 198 int ret; 199 200 regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); 201 if (!regs) { 202 dev_err(dev, "failed to get memory resource"); 203 return -EINVAL; 204 } 205 206 membase = devm_ioremap(dev, regs->start, resource_size(regs)); 207 if (!membase) 208 return -ENOMEM; 209 210 irq = platform_get_irq(pdev, 0); 211 if (irq < 0) { 212 dev_err(dev, "failed to get IRQ number\n"); 213 return irq; 214 } 215 216 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); 217 if (!priv) 218 return -ENOMEM; 219 220 memset(&up, 0, sizeof(up)); 221 222 ret = uniphier_of_serial_setup(dev, &up.port, priv); 223 if (ret < 0) 224 return ret; 225 226 spin_lock_init(&priv->atomic_write_lock); 227 228 up.port.dev = dev; 229 up.port.private_data = priv; 230 up.port.mapbase = regs->start; 231 up.port.mapsize = resource_size(regs); 232 up.port.membase = membase; 233 up.port.irq = irq; 234 235 up.port.type = PORT_16550A; 236 up.port.iotype = UPIO_MEM32; 237 up.port.regshift = 2; 238 up.port.flags = UPF_FIXED_PORT | UPF_FIXED_TYPE; 239 up.capabilities = UART_CAP_FIFO; 240 241 up.port.serial_in = uniphier_serial_in; 242 up.port.serial_out = uniphier_serial_out; 243 up.dl_read = uniphier_serial_dl_read; 244 up.dl_write = uniphier_serial_dl_write; 245 246 ret = serial8250_register_8250_port(&up); 247 if (ret < 0) { 248 dev_err(dev, "failed to register 8250 port\n"); 249 clk_disable_unprepare(priv->clk); 250 return ret; 251 } 252 253 platform_set_drvdata(pdev, priv); 254 255 return 0; 256 } 257 258 static int uniphier_uart_remove(struct platform_device *pdev) 259 { 260 struct uniphier8250_priv *priv = platform_get_drvdata(pdev); 261 262 serial8250_unregister_port(priv->line); 263 clk_disable_unprepare(priv->clk); 264 265 return 0; 266 } 267 268 static const struct of_device_id uniphier_uart_match[] = { 269 { .compatible = "socionext,uniphier-uart" }, 270 { /* sentinel */ } 271 }; 272 MODULE_DEVICE_TABLE(of, uniphier_uart_match); 273 274 static struct platform_driver uniphier_uart_platform_driver = { 275 .probe = uniphier_uart_probe, 276 .remove = uniphier_uart_remove, 277 .driver = { 278 .name = "uniphier-uart", 279 .of_match_table = uniphier_uart_match, 280 }, 281 }; 282 module_platform_driver(uniphier_uart_platform_driver); 283 284 MODULE_AUTHOR("Masahiro Yamada <yamada.masahiro@socionext.com>"); 285 MODULE_DESCRIPTION("UniPhier UART driver"); 286 MODULE_LICENSE("GPL"); 287