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