1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Serial Port driver for Aspeed VUART device 4 * 5 * Copyright (C) 2016 Jeremy Kerr <jk@ozlabs.org>, IBM Corp. 6 * Copyright (C) 2006 Arnd Bergmann <arnd@arndb.de>, IBM Corp. 7 */ 8 #if defined(CONFIG_SERIAL_8250_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) 9 #define SUPPORT_SYSRQ 10 #endif 11 12 #include <linux/device.h> 13 #include <linux/module.h> 14 #include <linux/of_address.h> 15 #include <linux/of_irq.h> 16 #include <linux/of_platform.h> 17 #include <linux/tty.h> 18 #include <linux/tty_flip.h> 19 #include <linux/clk.h> 20 21 #include "8250.h" 22 23 #define ASPEED_VUART_GCRA 0x20 24 #define ASPEED_VUART_GCRA_VUART_EN BIT(0) 25 #define ASPEED_VUART_GCRA_DISABLE_HOST_TX_DISCARD BIT(5) 26 #define ASPEED_VUART_GCRB 0x24 27 #define ASPEED_VUART_GCRB_HOST_SIRQ_MASK GENMASK(7, 4) 28 #define ASPEED_VUART_GCRB_HOST_SIRQ_SHIFT 4 29 #define ASPEED_VUART_ADDRL 0x28 30 #define ASPEED_VUART_ADDRH 0x2c 31 32 struct aspeed_vuart { 33 struct device *dev; 34 void __iomem *regs; 35 struct clk *clk; 36 int line; 37 struct timer_list unthrottle_timer; 38 struct uart_8250_port *port; 39 }; 40 41 /* 42 * If we fill the tty flip buffers, we throttle the data ready interrupt 43 * to prevent dropped characters. This timeout defines how long we wait 44 * to (conditionally, depending on buffer state) unthrottle. 45 */ 46 static const int unthrottle_timeout = HZ/10; 47 48 /* 49 * The VUART is basically two UART 'front ends' connected by their FIFO 50 * (no actual serial line in between). One is on the BMC side (management 51 * controller) and one is on the host CPU side. 52 * 53 * It allows the BMC to provide to the host a "UART" that pipes into 54 * the BMC itself and can then be turned by the BMC into a network console 55 * of some sort for example. 56 * 57 * This driver is for the BMC side. The sysfs files allow the BMC 58 * userspace which owns the system configuration policy, to specify 59 * at what IO port and interrupt number the host side will appear 60 * to the host on the Host <-> BMC LPC bus. It could be different on a 61 * different system (though most of them use 3f8/4). 62 */ 63 64 static ssize_t lpc_address_show(struct device *dev, 65 struct device_attribute *attr, char *buf) 66 { 67 struct aspeed_vuart *vuart = dev_get_drvdata(dev); 68 u16 addr; 69 70 addr = (readb(vuart->regs + ASPEED_VUART_ADDRH) << 8) | 71 (readb(vuart->regs + ASPEED_VUART_ADDRL)); 72 73 return snprintf(buf, PAGE_SIZE - 1, "0x%x\n", addr); 74 } 75 76 static ssize_t lpc_address_store(struct device *dev, 77 struct device_attribute *attr, 78 const char *buf, size_t count) 79 { 80 struct aspeed_vuart *vuart = dev_get_drvdata(dev); 81 unsigned long val; 82 int err; 83 84 err = kstrtoul(buf, 0, &val); 85 if (err) 86 return err; 87 88 writeb(val >> 8, vuart->regs + ASPEED_VUART_ADDRH); 89 writeb(val >> 0, vuart->regs + ASPEED_VUART_ADDRL); 90 91 return count; 92 } 93 94 static DEVICE_ATTR_RW(lpc_address); 95 96 static ssize_t sirq_show(struct device *dev, 97 struct device_attribute *attr, char *buf) 98 { 99 struct aspeed_vuart *vuart = dev_get_drvdata(dev); 100 u8 reg; 101 102 reg = readb(vuart->regs + ASPEED_VUART_GCRB); 103 reg &= ASPEED_VUART_GCRB_HOST_SIRQ_MASK; 104 reg >>= ASPEED_VUART_GCRB_HOST_SIRQ_SHIFT; 105 106 return snprintf(buf, PAGE_SIZE - 1, "%u\n", reg); 107 } 108 109 static ssize_t sirq_store(struct device *dev, struct device_attribute *attr, 110 const char *buf, size_t count) 111 { 112 struct aspeed_vuart *vuart = dev_get_drvdata(dev); 113 unsigned long val; 114 int err; 115 u8 reg; 116 117 err = kstrtoul(buf, 0, &val); 118 if (err) 119 return err; 120 121 val <<= ASPEED_VUART_GCRB_HOST_SIRQ_SHIFT; 122 val &= ASPEED_VUART_GCRB_HOST_SIRQ_MASK; 123 124 reg = readb(vuart->regs + ASPEED_VUART_GCRB); 125 reg &= ~ASPEED_VUART_GCRB_HOST_SIRQ_MASK; 126 reg |= val; 127 writeb(reg, vuart->regs + ASPEED_VUART_GCRB); 128 129 return count; 130 } 131 132 static DEVICE_ATTR_RW(sirq); 133 134 static struct attribute *aspeed_vuart_attrs[] = { 135 &dev_attr_sirq.attr, 136 &dev_attr_lpc_address.attr, 137 NULL, 138 }; 139 140 static const struct attribute_group aspeed_vuart_attr_group = { 141 .attrs = aspeed_vuart_attrs, 142 }; 143 144 static void aspeed_vuart_set_enabled(struct aspeed_vuart *vuart, bool enabled) 145 { 146 u8 reg = readb(vuart->regs + ASPEED_VUART_GCRA); 147 148 if (enabled) 149 reg |= ASPEED_VUART_GCRA_VUART_EN; 150 else 151 reg &= ~ASPEED_VUART_GCRA_VUART_EN; 152 153 writeb(reg, vuart->regs + ASPEED_VUART_GCRA); 154 } 155 156 static void aspeed_vuart_set_host_tx_discard(struct aspeed_vuart *vuart, 157 bool discard) 158 { 159 u8 reg; 160 161 reg = readb(vuart->regs + ASPEED_VUART_GCRA); 162 163 /* If the DISABLE_HOST_TX_DISCARD bit is set, discard is disabled */ 164 if (!discard) 165 reg |= ASPEED_VUART_GCRA_DISABLE_HOST_TX_DISCARD; 166 else 167 reg &= ~ASPEED_VUART_GCRA_DISABLE_HOST_TX_DISCARD; 168 169 writeb(reg, vuart->regs + ASPEED_VUART_GCRA); 170 } 171 172 static int aspeed_vuart_startup(struct uart_port *uart_port) 173 { 174 struct uart_8250_port *uart_8250_port = up_to_u8250p(uart_port); 175 struct aspeed_vuart *vuart = uart_8250_port->port.private_data; 176 int rc; 177 178 rc = serial8250_do_startup(uart_port); 179 if (rc) 180 return rc; 181 182 aspeed_vuart_set_host_tx_discard(vuart, false); 183 184 return 0; 185 } 186 187 static void aspeed_vuart_shutdown(struct uart_port *uart_port) 188 { 189 struct uart_8250_port *uart_8250_port = up_to_u8250p(uart_port); 190 struct aspeed_vuart *vuart = uart_8250_port->port.private_data; 191 192 aspeed_vuart_set_host_tx_discard(vuart, true); 193 194 serial8250_do_shutdown(uart_port); 195 } 196 197 static void __aspeed_vuart_set_throttle(struct uart_8250_port *up, 198 bool throttle) 199 { 200 unsigned char irqs = UART_IER_RLSI | UART_IER_RDI; 201 202 up->ier &= ~irqs; 203 if (!throttle) 204 up->ier |= irqs; 205 serial_out(up, UART_IER, up->ier); 206 } 207 static void aspeed_vuart_set_throttle(struct uart_port *port, bool throttle) 208 { 209 struct uart_8250_port *up = up_to_u8250p(port); 210 unsigned long flags; 211 212 spin_lock_irqsave(&port->lock, flags); 213 __aspeed_vuart_set_throttle(up, throttle); 214 spin_unlock_irqrestore(&port->lock, flags); 215 } 216 217 static void aspeed_vuart_throttle(struct uart_port *port) 218 { 219 aspeed_vuart_set_throttle(port, true); 220 } 221 222 static void aspeed_vuart_unthrottle(struct uart_port *port) 223 { 224 aspeed_vuart_set_throttle(port, false); 225 } 226 227 static void aspeed_vuart_unthrottle_exp(struct timer_list *timer) 228 { 229 struct aspeed_vuart *vuart = from_timer(vuart, timer, unthrottle_timer); 230 struct uart_8250_port *up = vuart->port; 231 232 if (!tty_buffer_space_avail(&up->port.state->port)) { 233 mod_timer(&vuart->unthrottle_timer, 234 jiffies + unthrottle_timeout); 235 return; 236 } 237 238 aspeed_vuart_unthrottle(&up->port); 239 } 240 241 /* 242 * Custom interrupt handler to manage finer-grained flow control. Although we 243 * have throttle/unthrottle callbacks, we've seen that the VUART device can 244 * deliver characters faster than the ldisc has a chance to check buffer space 245 * against the throttle threshold. This results in dropped characters before 246 * the throttle. 247 * 248 * We do this by checking for flip buffer space before RX. If we have no space, 249 * throttle now and schedule an unthrottle for later, once the ldisc has had 250 * a chance to drain the buffers. 251 */ 252 static int aspeed_vuart_handle_irq(struct uart_port *port) 253 { 254 struct uart_8250_port *up = up_to_u8250p(port); 255 unsigned int iir, lsr; 256 unsigned long flags; 257 int space, count; 258 259 iir = serial_port_in(port, UART_IIR); 260 261 if (iir & UART_IIR_NO_INT) 262 return 0; 263 264 spin_lock_irqsave(&port->lock, flags); 265 266 lsr = serial_port_in(port, UART_LSR); 267 268 if (lsr & (UART_LSR_DR | UART_LSR_BI)) { 269 space = tty_buffer_space_avail(&port->state->port); 270 271 if (!space) { 272 /* throttle and schedule an unthrottle later */ 273 struct aspeed_vuart *vuart = port->private_data; 274 __aspeed_vuart_set_throttle(up, true); 275 276 if (!timer_pending(&vuart->unthrottle_timer)) { 277 vuart->port = up; 278 mod_timer(&vuart->unthrottle_timer, 279 jiffies + unthrottle_timeout); 280 } 281 282 } else { 283 count = min(space, 256); 284 285 do { 286 serial8250_read_char(up, lsr); 287 lsr = serial_in(up, UART_LSR); 288 if (--count == 0) 289 break; 290 } while (lsr & (UART_LSR_DR | UART_LSR_BI)); 291 292 tty_flip_buffer_push(&port->state->port); 293 } 294 } 295 296 serial8250_modem_status(up); 297 if (lsr & UART_LSR_THRE) 298 serial8250_tx_chars(up); 299 300 uart_unlock_and_check_sysrq(port, flags); 301 302 return 1; 303 } 304 305 static int aspeed_vuart_probe(struct platform_device *pdev) 306 { 307 struct uart_8250_port port; 308 struct aspeed_vuart *vuart; 309 struct device_node *np; 310 struct resource *res; 311 u32 clk, prop; 312 int rc; 313 314 np = pdev->dev.of_node; 315 316 vuart = devm_kzalloc(&pdev->dev, sizeof(*vuart), GFP_KERNEL); 317 if (!vuart) 318 return -ENOMEM; 319 320 vuart->dev = &pdev->dev; 321 timer_setup(&vuart->unthrottle_timer, aspeed_vuart_unthrottle_exp, 0); 322 323 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 324 vuart->regs = devm_ioremap_resource(&pdev->dev, res); 325 if (IS_ERR(vuart->regs)) 326 return PTR_ERR(vuart->regs); 327 328 memset(&port, 0, sizeof(port)); 329 port.port.private_data = vuart; 330 port.port.membase = vuart->regs; 331 port.port.mapbase = res->start; 332 port.port.mapsize = resource_size(res); 333 port.port.startup = aspeed_vuart_startup; 334 port.port.shutdown = aspeed_vuart_shutdown; 335 port.port.throttle = aspeed_vuart_throttle; 336 port.port.unthrottle = aspeed_vuart_unthrottle; 337 port.port.status = UPSTAT_SYNC_FIFO; 338 port.port.dev = &pdev->dev; 339 340 rc = sysfs_create_group(&vuart->dev->kobj, &aspeed_vuart_attr_group); 341 if (rc < 0) 342 return rc; 343 344 if (of_property_read_u32(np, "clock-frequency", &clk)) { 345 vuart->clk = devm_clk_get(&pdev->dev, NULL); 346 if (IS_ERR(vuart->clk)) { 347 dev_warn(&pdev->dev, 348 "clk or clock-frequency not defined\n"); 349 rc = PTR_ERR(vuart->clk); 350 goto err_sysfs_remove; 351 } 352 353 rc = clk_prepare_enable(vuart->clk); 354 if (rc < 0) 355 goto err_sysfs_remove; 356 357 clk = clk_get_rate(vuart->clk); 358 } 359 360 /* If current-speed was set, then try not to change it. */ 361 if (of_property_read_u32(np, "current-speed", &prop) == 0) 362 port.port.custom_divisor = clk / (16 * prop); 363 364 /* Check for shifted address mapping */ 365 if (of_property_read_u32(np, "reg-offset", &prop) == 0) 366 port.port.mapbase += prop; 367 368 /* Check for registers offset within the devices address range */ 369 if (of_property_read_u32(np, "reg-shift", &prop) == 0) 370 port.port.regshift = prop; 371 372 /* Check for fifo size */ 373 if (of_property_read_u32(np, "fifo-size", &prop) == 0) 374 port.port.fifosize = prop; 375 376 /* Check for a fixed line number */ 377 rc = of_alias_get_id(np, "serial"); 378 if (rc >= 0) 379 port.port.line = rc; 380 381 port.port.irq = irq_of_parse_and_map(np, 0); 382 port.port.irqflags = IRQF_SHARED; 383 port.port.handle_irq = aspeed_vuart_handle_irq; 384 port.port.iotype = UPIO_MEM; 385 port.port.type = PORT_16550A; 386 port.port.uartclk = clk; 387 port.port.flags = UPF_SHARE_IRQ | UPF_BOOT_AUTOCONF 388 | UPF_FIXED_PORT | UPF_FIXED_TYPE | UPF_NO_THRE_TEST; 389 390 if (of_property_read_bool(np, "no-loopback-test")) 391 port.port.flags |= UPF_SKIP_TEST; 392 393 if (port.port.fifosize) 394 port.capabilities = UART_CAP_FIFO; 395 396 if (of_property_read_bool(np, "auto-flow-control")) 397 port.capabilities |= UART_CAP_AFE; 398 399 rc = serial8250_register_8250_port(&port); 400 if (rc < 0) 401 goto err_clk_disable; 402 403 vuart->line = rc; 404 405 aspeed_vuart_set_enabled(vuart, true); 406 aspeed_vuart_set_host_tx_discard(vuart, true); 407 platform_set_drvdata(pdev, vuart); 408 409 return 0; 410 411 err_clk_disable: 412 clk_disable_unprepare(vuart->clk); 413 irq_dispose_mapping(port.port.irq); 414 err_sysfs_remove: 415 sysfs_remove_group(&vuart->dev->kobj, &aspeed_vuart_attr_group); 416 return rc; 417 } 418 419 static int aspeed_vuart_remove(struct platform_device *pdev) 420 { 421 struct aspeed_vuart *vuart = platform_get_drvdata(pdev); 422 423 del_timer_sync(&vuart->unthrottle_timer); 424 aspeed_vuart_set_enabled(vuart, false); 425 serial8250_unregister_port(vuart->line); 426 sysfs_remove_group(&vuart->dev->kobj, &aspeed_vuart_attr_group); 427 clk_disable_unprepare(vuart->clk); 428 429 return 0; 430 } 431 432 static const struct of_device_id aspeed_vuart_table[] = { 433 { .compatible = "aspeed,ast2400-vuart" }, 434 { .compatible = "aspeed,ast2500-vuart" }, 435 { }, 436 }; 437 438 static struct platform_driver aspeed_vuart_driver = { 439 .driver = { 440 .name = "aspeed-vuart", 441 .of_match_table = aspeed_vuart_table, 442 }, 443 .probe = aspeed_vuart_probe, 444 .remove = aspeed_vuart_remove, 445 }; 446 447 module_platform_driver(aspeed_vuart_driver); 448 449 MODULE_AUTHOR("Jeremy Kerr <jk@ozlabs.org>"); 450 MODULE_LICENSE("GPL"); 451 MODULE_DESCRIPTION("Driver for Aspeed VUART device"); 452