1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * altera_jtaguart.c -- Altera JTAG UART driver 4 * 5 * Based on mcf.c -- Freescale ColdFire UART driver 6 * 7 * (C) Copyright 2003-2007, Greg Ungerer <gerg@snapgear.com> 8 * (C) Copyright 2008, Thomas Chou <thomas@wytron.com.tw> 9 * (C) Copyright 2010, Tobias Klauser <tklauser@distanz.ch> 10 */ 11 12 #include <linux/kernel.h> 13 #include <linux/init.h> 14 #include <linux/interrupt.h> 15 #include <linux/module.h> 16 #include <linux/console.h> 17 #include <linux/of.h> 18 #include <linux/tty.h> 19 #include <linux/tty_flip.h> 20 #include <linux/serial.h> 21 #include <linux/serial_core.h> 22 #include <linux/platform_device.h> 23 #include <linux/io.h> 24 #include <linux/altera_jtaguart.h> 25 26 #define DRV_NAME "altera_jtaguart" 27 28 /* 29 * Altera JTAG UART register definitions according to the Altera JTAG UART 30 * datasheet: https://www.altera.com/literature/hb/nios2/n2cpu_nii51009.pdf 31 */ 32 33 #define ALTERA_JTAGUART_SIZE 8 34 35 #define ALTERA_JTAGUART_DATA_REG 0 36 37 #define ALTERA_JTAGUART_DATA_DATA_MSK 0x000000FF 38 #define ALTERA_JTAGUART_DATA_RVALID_MSK 0x00008000 39 #define ALTERA_JTAGUART_DATA_RAVAIL_MSK 0xFFFF0000 40 #define ALTERA_JTAGUART_DATA_RAVAIL_OFF 16 41 42 #define ALTERA_JTAGUART_CONTROL_REG 4 43 44 #define ALTERA_JTAGUART_CONTROL_RE_MSK 0x00000001 45 #define ALTERA_JTAGUART_CONTROL_WE_MSK 0x00000002 46 #define ALTERA_JTAGUART_CONTROL_RI_MSK 0x00000100 47 #define ALTERA_JTAGUART_CONTROL_RI_OFF 8 48 #define ALTERA_JTAGUART_CONTROL_WI_MSK 0x00000200 49 #define ALTERA_JTAGUART_CONTROL_AC_MSK 0x00000400 50 #define ALTERA_JTAGUART_CONTROL_WSPACE_MSK 0xFFFF0000 51 #define ALTERA_JTAGUART_CONTROL_WSPACE_OFF 16 52 53 /* 54 * Local per-uart structure. 55 */ 56 struct altera_jtaguart { 57 struct uart_port port; 58 unsigned int sigs; /* Local copy of line sigs */ 59 unsigned long imr; /* Local IMR mirror */ 60 }; 61 62 static unsigned int altera_jtaguart_tx_empty(struct uart_port *port) 63 { 64 return (readl(port->membase + ALTERA_JTAGUART_CONTROL_REG) & 65 ALTERA_JTAGUART_CONTROL_WSPACE_MSK) ? TIOCSER_TEMT : 0; 66 } 67 68 static unsigned int altera_jtaguart_get_mctrl(struct uart_port *port) 69 { 70 return TIOCM_CAR | TIOCM_DSR | TIOCM_CTS; 71 } 72 73 static void altera_jtaguart_set_mctrl(struct uart_port *port, unsigned int sigs) 74 { 75 } 76 77 static void altera_jtaguart_start_tx(struct uart_port *port) 78 { 79 struct altera_jtaguart *pp = 80 container_of(port, struct altera_jtaguart, port); 81 82 pp->imr |= ALTERA_JTAGUART_CONTROL_WE_MSK; 83 writel(pp->imr, port->membase + ALTERA_JTAGUART_CONTROL_REG); 84 } 85 86 static void altera_jtaguart_stop_tx(struct uart_port *port) 87 { 88 struct altera_jtaguart *pp = 89 container_of(port, struct altera_jtaguart, port); 90 91 pp->imr &= ~ALTERA_JTAGUART_CONTROL_WE_MSK; 92 writel(pp->imr, port->membase + ALTERA_JTAGUART_CONTROL_REG); 93 } 94 95 static void altera_jtaguart_stop_rx(struct uart_port *port) 96 { 97 struct altera_jtaguart *pp = 98 container_of(port, struct altera_jtaguart, port); 99 100 pp->imr &= ~ALTERA_JTAGUART_CONTROL_RE_MSK; 101 writel(pp->imr, port->membase + ALTERA_JTAGUART_CONTROL_REG); 102 } 103 104 static void altera_jtaguart_break_ctl(struct uart_port *port, int break_state) 105 { 106 } 107 108 static void altera_jtaguart_set_termios(struct uart_port *port, 109 struct ktermios *termios, 110 struct ktermios *old) 111 { 112 /* Just copy the old termios settings back */ 113 if (old) 114 tty_termios_copy_hw(termios, old); 115 } 116 117 static void altera_jtaguart_rx_chars(struct altera_jtaguart *pp) 118 { 119 struct uart_port *port = &pp->port; 120 unsigned char ch, flag; 121 unsigned long status; 122 123 while ((status = readl(port->membase + ALTERA_JTAGUART_DATA_REG)) & 124 ALTERA_JTAGUART_DATA_RVALID_MSK) { 125 ch = status & ALTERA_JTAGUART_DATA_DATA_MSK; 126 flag = TTY_NORMAL; 127 port->icount.rx++; 128 129 if (uart_handle_sysrq_char(port, ch)) 130 continue; 131 uart_insert_char(port, 0, 0, ch, flag); 132 } 133 134 spin_unlock(&port->lock); 135 tty_flip_buffer_push(&port->state->port); 136 spin_lock(&port->lock); 137 } 138 139 static void altera_jtaguart_tx_chars(struct altera_jtaguart *pp) 140 { 141 struct uart_port *port = &pp->port; 142 struct circ_buf *xmit = &port->state->xmit; 143 unsigned int pending, count; 144 145 if (port->x_char) { 146 /* Send special char - probably flow control */ 147 writel(port->x_char, port->membase + ALTERA_JTAGUART_DATA_REG); 148 port->x_char = 0; 149 port->icount.tx++; 150 return; 151 } 152 153 pending = uart_circ_chars_pending(xmit); 154 if (pending > 0) { 155 count = (readl(port->membase + ALTERA_JTAGUART_CONTROL_REG) & 156 ALTERA_JTAGUART_CONTROL_WSPACE_MSK) >> 157 ALTERA_JTAGUART_CONTROL_WSPACE_OFF; 158 if (count > pending) 159 count = pending; 160 if (count > 0) { 161 pending -= count; 162 while (count--) { 163 writel(xmit->buf[xmit->tail], 164 port->membase + ALTERA_JTAGUART_DATA_REG); 165 xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); 166 port->icount.tx++; 167 } 168 if (pending < WAKEUP_CHARS) 169 uart_write_wakeup(port); 170 } 171 } 172 173 if (pending == 0) { 174 pp->imr &= ~ALTERA_JTAGUART_CONTROL_WE_MSK; 175 writel(pp->imr, port->membase + ALTERA_JTAGUART_CONTROL_REG); 176 } 177 } 178 179 static irqreturn_t altera_jtaguart_interrupt(int irq, void *data) 180 { 181 struct uart_port *port = data; 182 struct altera_jtaguart *pp = 183 container_of(port, struct altera_jtaguart, port); 184 unsigned int isr; 185 186 isr = (readl(port->membase + ALTERA_JTAGUART_CONTROL_REG) >> 187 ALTERA_JTAGUART_CONTROL_RI_OFF) & pp->imr; 188 189 spin_lock(&port->lock); 190 191 if (isr & ALTERA_JTAGUART_CONTROL_RE_MSK) 192 altera_jtaguart_rx_chars(pp); 193 if (isr & ALTERA_JTAGUART_CONTROL_WE_MSK) 194 altera_jtaguart_tx_chars(pp); 195 196 spin_unlock(&port->lock); 197 198 return IRQ_RETVAL(isr); 199 } 200 201 static void altera_jtaguart_config_port(struct uart_port *port, int flags) 202 { 203 port->type = PORT_ALTERA_JTAGUART; 204 205 /* Clear mask, so no surprise interrupts. */ 206 writel(0, port->membase + ALTERA_JTAGUART_CONTROL_REG); 207 } 208 209 static int altera_jtaguart_startup(struct uart_port *port) 210 { 211 struct altera_jtaguart *pp = 212 container_of(port, struct altera_jtaguart, port); 213 unsigned long flags; 214 int ret; 215 216 ret = request_irq(port->irq, altera_jtaguart_interrupt, 0, 217 DRV_NAME, port); 218 if (ret) { 219 pr_err(DRV_NAME ": unable to attach Altera JTAG UART %d " 220 "interrupt vector=%d\n", port->line, port->irq); 221 return ret; 222 } 223 224 spin_lock_irqsave(&port->lock, flags); 225 226 /* Enable RX interrupts now */ 227 pp->imr = ALTERA_JTAGUART_CONTROL_RE_MSK; 228 writel(pp->imr, port->membase + ALTERA_JTAGUART_CONTROL_REG); 229 230 spin_unlock_irqrestore(&port->lock, flags); 231 232 return 0; 233 } 234 235 static void altera_jtaguart_shutdown(struct uart_port *port) 236 { 237 struct altera_jtaguart *pp = 238 container_of(port, struct altera_jtaguart, port); 239 unsigned long flags; 240 241 spin_lock_irqsave(&port->lock, flags); 242 243 /* Disable all interrupts now */ 244 pp->imr = 0; 245 writel(pp->imr, port->membase + ALTERA_JTAGUART_CONTROL_REG); 246 247 spin_unlock_irqrestore(&port->lock, flags); 248 249 free_irq(port->irq, port); 250 } 251 252 static const char *altera_jtaguart_type(struct uart_port *port) 253 { 254 return (port->type == PORT_ALTERA_JTAGUART) ? "Altera JTAG UART" : NULL; 255 } 256 257 static int altera_jtaguart_request_port(struct uart_port *port) 258 { 259 /* UARTs always present */ 260 return 0; 261 } 262 263 static void altera_jtaguart_release_port(struct uart_port *port) 264 { 265 /* Nothing to release... */ 266 } 267 268 static int altera_jtaguart_verify_port(struct uart_port *port, 269 struct serial_struct *ser) 270 { 271 if (ser->type != PORT_UNKNOWN && ser->type != PORT_ALTERA_JTAGUART) 272 return -EINVAL; 273 return 0; 274 } 275 276 /* 277 * Define the basic serial functions we support. 278 */ 279 static const struct uart_ops altera_jtaguart_ops = { 280 .tx_empty = altera_jtaguart_tx_empty, 281 .get_mctrl = altera_jtaguart_get_mctrl, 282 .set_mctrl = altera_jtaguart_set_mctrl, 283 .start_tx = altera_jtaguart_start_tx, 284 .stop_tx = altera_jtaguart_stop_tx, 285 .stop_rx = altera_jtaguart_stop_rx, 286 .break_ctl = altera_jtaguart_break_ctl, 287 .startup = altera_jtaguart_startup, 288 .shutdown = altera_jtaguart_shutdown, 289 .set_termios = altera_jtaguart_set_termios, 290 .type = altera_jtaguart_type, 291 .request_port = altera_jtaguart_request_port, 292 .release_port = altera_jtaguart_release_port, 293 .config_port = altera_jtaguart_config_port, 294 .verify_port = altera_jtaguart_verify_port, 295 }; 296 297 #define ALTERA_JTAGUART_MAXPORTS 1 298 static struct altera_jtaguart altera_jtaguart_ports[ALTERA_JTAGUART_MAXPORTS]; 299 300 #if defined(CONFIG_SERIAL_ALTERA_JTAGUART_CONSOLE) 301 302 #if defined(CONFIG_SERIAL_ALTERA_JTAGUART_CONSOLE_BYPASS) 303 static void altera_jtaguart_console_putc(struct uart_port *port, int c) 304 { 305 unsigned long status; 306 unsigned long flags; 307 308 spin_lock_irqsave(&port->lock, flags); 309 while (((status = readl(port->membase + ALTERA_JTAGUART_CONTROL_REG)) & 310 ALTERA_JTAGUART_CONTROL_WSPACE_MSK) == 0) { 311 if ((status & ALTERA_JTAGUART_CONTROL_AC_MSK) == 0) { 312 spin_unlock_irqrestore(&port->lock, flags); 313 return; /* no connection activity */ 314 } 315 spin_unlock_irqrestore(&port->lock, flags); 316 cpu_relax(); 317 spin_lock_irqsave(&port->lock, flags); 318 } 319 writel(c, port->membase + ALTERA_JTAGUART_DATA_REG); 320 spin_unlock_irqrestore(&port->lock, flags); 321 } 322 #else 323 static void altera_jtaguart_console_putc(struct uart_port *port, int c) 324 { 325 unsigned long flags; 326 327 spin_lock_irqsave(&port->lock, flags); 328 while ((readl(port->membase + ALTERA_JTAGUART_CONTROL_REG) & 329 ALTERA_JTAGUART_CONTROL_WSPACE_MSK) == 0) { 330 spin_unlock_irqrestore(&port->lock, flags); 331 cpu_relax(); 332 spin_lock_irqsave(&port->lock, flags); 333 } 334 writel(c, port->membase + ALTERA_JTAGUART_DATA_REG); 335 spin_unlock_irqrestore(&port->lock, flags); 336 } 337 #endif 338 339 static void altera_jtaguart_console_write(struct console *co, const char *s, 340 unsigned int count) 341 { 342 struct uart_port *port = &(altera_jtaguart_ports + co->index)->port; 343 344 uart_console_write(port, s, count, altera_jtaguart_console_putc); 345 } 346 347 static int __init altera_jtaguart_console_setup(struct console *co, 348 char *options) 349 { 350 struct uart_port *port; 351 352 if (co->index < 0 || co->index >= ALTERA_JTAGUART_MAXPORTS) 353 return -EINVAL; 354 port = &altera_jtaguart_ports[co->index].port; 355 if (port->membase == NULL) 356 return -ENODEV; 357 return 0; 358 } 359 360 static struct uart_driver altera_jtaguart_driver; 361 362 static struct console altera_jtaguart_console = { 363 .name = "ttyJ", 364 .write = altera_jtaguart_console_write, 365 .device = uart_console_device, 366 .setup = altera_jtaguart_console_setup, 367 .flags = CON_PRINTBUFFER, 368 .index = -1, 369 .data = &altera_jtaguart_driver, 370 }; 371 372 static int __init altera_jtaguart_console_init(void) 373 { 374 register_console(&altera_jtaguart_console); 375 return 0; 376 } 377 378 console_initcall(altera_jtaguart_console_init); 379 380 #define ALTERA_JTAGUART_CONSOLE (&altera_jtaguart_console) 381 382 static void altera_jtaguart_earlycon_write(struct console *co, const char *s, 383 unsigned int count) 384 { 385 struct earlycon_device *dev = co->data; 386 387 uart_console_write(&dev->port, s, count, altera_jtaguart_console_putc); 388 } 389 390 static int __init altera_jtaguart_earlycon_setup(struct earlycon_device *dev, 391 const char *options) 392 { 393 if (!dev->port.membase) 394 return -ENODEV; 395 396 dev->con->write = altera_jtaguart_earlycon_write; 397 return 0; 398 } 399 400 OF_EARLYCON_DECLARE(juart, "altr,juart-1.0", altera_jtaguart_earlycon_setup); 401 402 #else 403 404 #define ALTERA_JTAGUART_CONSOLE NULL 405 406 #endif /* CONFIG_SERIAL_ALTERA_JTAGUART_CONSOLE */ 407 408 static struct uart_driver altera_jtaguart_driver = { 409 .owner = THIS_MODULE, 410 .driver_name = "altera_jtaguart", 411 .dev_name = "ttyJ", 412 .major = ALTERA_JTAGUART_MAJOR, 413 .minor = ALTERA_JTAGUART_MINOR, 414 .nr = ALTERA_JTAGUART_MAXPORTS, 415 .cons = ALTERA_JTAGUART_CONSOLE, 416 }; 417 418 static int altera_jtaguart_probe(struct platform_device *pdev) 419 { 420 struct altera_jtaguart_platform_uart *platp = 421 dev_get_platdata(&pdev->dev); 422 struct uart_port *port; 423 struct resource *res_irq, *res_mem; 424 int i = pdev->id; 425 426 /* -1 emphasizes that the platform must have one port, no .N suffix */ 427 if (i == -1) 428 i = 0; 429 430 if (i >= ALTERA_JTAGUART_MAXPORTS) 431 return -EINVAL; 432 433 port = &altera_jtaguart_ports[i].port; 434 435 res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); 436 if (res_mem) 437 port->mapbase = res_mem->start; 438 else if (platp) 439 port->mapbase = platp->mapbase; 440 else 441 return -ENODEV; 442 443 res_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); 444 if (res_irq) 445 port->irq = res_irq->start; 446 else if (platp) 447 port->irq = platp->irq; 448 else 449 return -ENODEV; 450 451 port->membase = ioremap(port->mapbase, ALTERA_JTAGUART_SIZE); 452 if (!port->membase) 453 return -ENOMEM; 454 455 port->line = i; 456 port->type = PORT_ALTERA_JTAGUART; 457 port->iotype = SERIAL_IO_MEM; 458 port->ops = &altera_jtaguart_ops; 459 port->flags = UPF_BOOT_AUTOCONF; 460 port->dev = &pdev->dev; 461 462 uart_add_one_port(&altera_jtaguart_driver, port); 463 464 return 0; 465 } 466 467 static int altera_jtaguart_remove(struct platform_device *pdev) 468 { 469 struct uart_port *port; 470 int i = pdev->id; 471 472 if (i == -1) 473 i = 0; 474 475 port = &altera_jtaguart_ports[i].port; 476 uart_remove_one_port(&altera_jtaguart_driver, port); 477 iounmap(port->membase); 478 479 return 0; 480 } 481 482 #ifdef CONFIG_OF 483 static const struct of_device_id altera_jtaguart_match[] = { 484 { .compatible = "ALTR,juart-1.0", }, 485 { .compatible = "altr,juart-1.0", }, 486 {}, 487 }; 488 MODULE_DEVICE_TABLE(of, altera_jtaguart_match); 489 #endif /* CONFIG_OF */ 490 491 static struct platform_driver altera_jtaguart_platform_driver = { 492 .probe = altera_jtaguart_probe, 493 .remove = altera_jtaguart_remove, 494 .driver = { 495 .name = DRV_NAME, 496 .of_match_table = of_match_ptr(altera_jtaguart_match), 497 }, 498 }; 499 500 static int __init altera_jtaguart_init(void) 501 { 502 int rc; 503 504 rc = uart_register_driver(&altera_jtaguart_driver); 505 if (rc) 506 return rc; 507 rc = platform_driver_register(&altera_jtaguart_platform_driver); 508 if (rc) 509 uart_unregister_driver(&altera_jtaguart_driver); 510 return rc; 511 } 512 513 static void __exit altera_jtaguart_exit(void) 514 { 515 platform_driver_unregister(&altera_jtaguart_platform_driver); 516 uart_unregister_driver(&altera_jtaguart_driver); 517 } 518 519 module_init(altera_jtaguart_init); 520 module_exit(altera_jtaguart_exit); 521 522 MODULE_DESCRIPTION("Altera JTAG UART driver"); 523 MODULE_AUTHOR("Thomas Chou <thomas@wytron.com.tw>"); 524 MODULE_LICENSE("GPL"); 525 MODULE_ALIAS("platform:" DRV_NAME); 526