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