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 /* 28 * This hardware is similar to 8250, but its register map is a bit different: 29 * - MMIO32 (regshift = 2) 30 * - FCR is not at 2, but 3 31 * - LCR and MCR are not at 3 and 4, they share 4 32 * - No SCR (Instead, CHAR can be used as a scratch register) 33 * - Divisor latch at 9, no divisor latch access bit 34 */ 35 36 #define UNIPHIER_UART_REGSHIFT 2 37 38 /* bit[15:8] = CHAR, bit[7:0] = FCR */ 39 #define UNIPHIER_UART_CHAR_FCR (3 << (UNIPHIER_UART_REGSHIFT)) 40 /* bit[15:8] = LCR, bit[7:0] = MCR */ 41 #define UNIPHIER_UART_LCR_MCR (4 << (UNIPHIER_UART_REGSHIFT)) 42 /* Divisor Latch Register */ 43 #define UNIPHIER_UART_DLR (9 << (UNIPHIER_UART_REGSHIFT)) 44 45 struct uniphier8250_priv { 46 int line; 47 struct clk *clk; 48 spinlock_t atomic_write_lock; 49 }; 50 51 #ifdef CONFIG_SERIAL_8250_CONSOLE 52 static int __init uniphier_early_console_setup(struct earlycon_device *device, 53 const char *options) 54 { 55 if (!device->port.membase) 56 return -ENODEV; 57 58 /* This hardware always expects MMIO32 register interface. */ 59 device->port.iotype = UPIO_MEM32; 60 device->port.regshift = UNIPHIER_UART_REGSHIFT; 61 62 /* 63 * Do not touch the divisor register in early_serial8250_setup(); 64 * we assume it has been initialized by a boot loader. 65 */ 66 device->baud = 0; 67 68 return early_serial8250_setup(device, options); 69 } 70 OF_EARLYCON_DECLARE(uniphier, "socionext,uniphier-uart", 71 uniphier_early_console_setup); 72 #endif 73 74 /* 75 * The register map is slightly different from that of 8250. 76 * IO callbacks must be overridden for correct access to FCR, LCR, MCR and SCR. 77 */ 78 static unsigned int uniphier_serial_in(struct uart_port *p, int offset) 79 { 80 unsigned int valshift = 0; 81 82 switch (offset) { 83 case UART_SCR: 84 /* No SCR for this hardware. Use CHAR as a scratch register */ 85 valshift = 8; 86 offset = UNIPHIER_UART_CHAR_FCR; 87 break; 88 case UART_LCR: 89 valshift = 8; 90 /* fall through */ 91 case UART_MCR: 92 offset = UNIPHIER_UART_LCR_MCR; 93 break; 94 default: 95 offset <<= UNIPHIER_UART_REGSHIFT; 96 break; 97 } 98 99 /* 100 * The return value must be masked with 0xff because some registers 101 * share the same offset that must be accessed by 32-bit write/read. 102 * 8 or 16 bit access to this hardware result in unexpected behavior. 103 */ 104 return (readl(p->membase + offset) >> valshift) & 0xff; 105 } 106 107 static void uniphier_serial_out(struct uart_port *p, int offset, int value) 108 { 109 unsigned int valshift = 0; 110 bool normal = false; 111 112 switch (offset) { 113 case UART_SCR: 114 /* No SCR for this hardware. Use CHAR as a scratch register */ 115 valshift = 8; 116 /* fall through */ 117 case UART_FCR: 118 offset = UNIPHIER_UART_CHAR_FCR; 119 break; 120 case UART_LCR: 121 valshift = 8; 122 /* Divisor latch access bit does not exist. */ 123 value &= ~UART_LCR_DLAB; 124 /* fall through */ 125 case UART_MCR: 126 offset = UNIPHIER_UART_LCR_MCR; 127 break; 128 default: 129 offset <<= UNIPHIER_UART_REGSHIFT; 130 normal = true; 131 break; 132 } 133 134 if (normal) { 135 writel(value, p->membase + offset); 136 } else { 137 /* 138 * Special case: two registers share the same address that 139 * must be 32-bit accessed. As this is not longer atomic safe, 140 * take a lock just in case. 141 */ 142 struct uniphier8250_priv *priv = p->private_data; 143 unsigned long flags; 144 u32 tmp; 145 146 spin_lock_irqsave(&priv->atomic_write_lock, flags); 147 tmp = readl(p->membase + offset); 148 tmp &= ~(0xff << valshift); 149 tmp |= value << valshift; 150 writel(tmp, p->membase + offset); 151 spin_unlock_irqrestore(&priv->atomic_write_lock, flags); 152 } 153 } 154 155 /* 156 * This hardware does not have the divisor latch access bit. 157 * The divisor latch register exists at different address. 158 * Override dl_read/write callbacks. 159 */ 160 static int uniphier_serial_dl_read(struct uart_8250_port *up) 161 { 162 return readl(up->port.membase + UNIPHIER_UART_DLR); 163 } 164 165 static void uniphier_serial_dl_write(struct uart_8250_port *up, int value) 166 { 167 writel(value, up->port.membase + UNIPHIER_UART_DLR); 168 } 169 170 static int uniphier_of_serial_setup(struct device *dev, struct uart_port *port, 171 struct uniphier8250_priv *priv) 172 { 173 int ret; 174 u32 prop; 175 struct device_node *np = dev->of_node; 176 177 ret = of_alias_get_id(np, "serial"); 178 if (ret < 0) { 179 dev_err(dev, "failed to get alias id\n"); 180 return ret; 181 } 182 port->line = ret; 183 184 /* Get clk rate through clk driver */ 185 priv->clk = devm_clk_get(dev, NULL); 186 if (IS_ERR(priv->clk)) { 187 dev_err(dev, "failed to get clock\n"); 188 return PTR_ERR(priv->clk); 189 } 190 191 ret = clk_prepare_enable(priv->clk); 192 if (ret < 0) 193 return ret; 194 195 port->uartclk = clk_get_rate(priv->clk); 196 197 /* Check for fifo size */ 198 if (of_property_read_u32(np, "fifo-size", &prop) == 0) 199 port->fifosize = prop; 200 else 201 port->fifosize = UNIPHIER_UART_DEFAULT_FIFO_SIZE; 202 203 return 0; 204 } 205 206 static int uniphier_uart_probe(struct platform_device *pdev) 207 { 208 struct device *dev = &pdev->dev; 209 struct uart_8250_port up; 210 struct uniphier8250_priv *priv; 211 struct resource *regs; 212 void __iomem *membase; 213 int irq; 214 int ret; 215 216 regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); 217 if (!regs) { 218 dev_err(dev, "failed to get memory resource\n"); 219 return -EINVAL; 220 } 221 222 membase = devm_ioremap(dev, regs->start, resource_size(regs)); 223 if (!membase) 224 return -ENOMEM; 225 226 irq = platform_get_irq(pdev, 0); 227 if (irq < 0) { 228 dev_err(dev, "failed to get IRQ number\n"); 229 return irq; 230 } 231 232 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); 233 if (!priv) 234 return -ENOMEM; 235 236 memset(&up, 0, sizeof(up)); 237 238 ret = uniphier_of_serial_setup(dev, &up.port, priv); 239 if (ret < 0) 240 return ret; 241 242 spin_lock_init(&priv->atomic_write_lock); 243 244 up.port.dev = dev; 245 up.port.private_data = priv; 246 up.port.mapbase = regs->start; 247 up.port.mapsize = resource_size(regs); 248 up.port.membase = membase; 249 up.port.irq = irq; 250 251 up.port.type = PORT_16550A; 252 up.port.iotype = UPIO_MEM32; 253 up.port.regshift = UNIPHIER_UART_REGSHIFT; 254 up.port.flags = UPF_FIXED_PORT | UPF_FIXED_TYPE; 255 up.capabilities = UART_CAP_FIFO; 256 257 up.port.serial_in = uniphier_serial_in; 258 up.port.serial_out = uniphier_serial_out; 259 up.dl_read = uniphier_serial_dl_read; 260 up.dl_write = uniphier_serial_dl_write; 261 262 priv->line = serial8250_register_8250_port(&up); 263 if (priv->line < 0) { 264 dev_err(dev, "failed to register 8250 port\n"); 265 clk_disable_unprepare(priv->clk); 266 return ret; 267 } 268 269 platform_set_drvdata(pdev, priv); 270 271 return 0; 272 } 273 274 static int uniphier_uart_remove(struct platform_device *pdev) 275 { 276 struct uniphier8250_priv *priv = platform_get_drvdata(pdev); 277 278 serial8250_unregister_port(priv->line); 279 clk_disable_unprepare(priv->clk); 280 281 return 0; 282 } 283 284 static int __maybe_unused uniphier_uart_suspend(struct device *dev) 285 { 286 struct uniphier8250_priv *priv = dev_get_drvdata(dev); 287 struct uart_8250_port *up = serial8250_get_port(priv->line); 288 289 serial8250_suspend_port(priv->line); 290 291 if (!uart_console(&up->port) || console_suspend_enabled) 292 clk_disable_unprepare(priv->clk); 293 294 return 0; 295 } 296 297 static int __maybe_unused uniphier_uart_resume(struct device *dev) 298 { 299 struct uniphier8250_priv *priv = dev_get_drvdata(dev); 300 struct uart_8250_port *up = serial8250_get_port(priv->line); 301 int ret; 302 303 if (!uart_console(&up->port) || console_suspend_enabled) { 304 ret = clk_prepare_enable(priv->clk); 305 if (ret) 306 return ret; 307 } 308 309 serial8250_resume_port(priv->line); 310 311 return 0; 312 } 313 314 static const struct dev_pm_ops uniphier_uart_pm_ops = { 315 SET_SYSTEM_SLEEP_PM_OPS(uniphier_uart_suspend, uniphier_uart_resume) 316 }; 317 318 static const struct of_device_id uniphier_uart_match[] = { 319 { .compatible = "socionext,uniphier-uart" }, 320 { /* sentinel */ } 321 }; 322 MODULE_DEVICE_TABLE(of, uniphier_uart_match); 323 324 static struct platform_driver uniphier_uart_platform_driver = { 325 .probe = uniphier_uart_probe, 326 .remove = uniphier_uart_remove, 327 .driver = { 328 .name = "uniphier-uart", 329 .of_match_table = uniphier_uart_match, 330 .pm = &uniphier_uart_pm_ops, 331 }, 332 }; 333 module_platform_driver(uniphier_uart_platform_driver); 334 335 MODULE_AUTHOR("Masahiro Yamada <yamada.masahiro@socionext.com>"); 336 MODULE_DESCRIPTION("UniPhier UART driver"); 337 MODULE_LICENSE("GPL"); 338