uart_dev_at91usart.c revision 259759
1/*- 2 * Copyright (c) 2005 M. Warner Losh 3 * Copyright (c) 2005 Olivier Houchard 4 * Copyright (c) 2012 Ian Lepore 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 */ 29 30#include <sys/cdefs.h> 31__FBSDID("$FreeBSD: stable/10/sys/arm/at91/uart_dev_at91usart.c 259759 2013-12-23 01:24:32Z imp $"); 32 33#include <sys/param.h> 34#include <sys/systm.h> 35#include <sys/bus.h> 36#include <sys/conf.h> 37#include <sys/cons.h> 38#include <sys/tty.h> 39#include <machine/bus.h> 40 41#include <dev/uart/uart.h> 42#include <dev/uart/uart_cpu.h> 43#include <dev/uart/uart_bus.h> 44#include <arm/at91/at91_usartreg.h> 45#include <arm/at91/at91_pdcreg.h> 46#include <arm/at91/at91_piovar.h> 47#include <arm/at91/at91_pioreg.h> 48#include <arm/at91/at91rm92reg.h> 49#include <arm/at91/at91var.h> 50 51#include "uart_if.h" 52 53#define DEFAULT_RCLK at91_master_clock 54#define USART_DEFAULT_FIFO_BYTES 128 55 56#define USART_DCE_CHANGE_BITS (USART_CSR_CTSIC | USART_CSR_DCDIC | \ 57 USART_CSR_DSRIC | USART_CSR_RIIC) 58 59/* 60 * High-level UART interface. 61 */ 62struct at91_usart_rx { 63 bus_addr_t pa; 64 uint8_t *buffer; 65 bus_dmamap_t map; 66}; 67 68struct at91_usart_softc { 69 struct uart_softc base; 70 bus_dma_tag_t tx_tag; 71 bus_dmamap_t tx_map; 72 uint32_t flags; 73#define HAS_TIMEOUT 0x1 74#define USE_RTS0_WORKAROUND 0x2 75 bus_dma_tag_t rx_tag; 76 struct at91_usart_rx ping_pong[2]; 77 struct at91_usart_rx *ping; 78 struct at91_usart_rx *pong; 79}; 80 81#define RD4(bas, reg) \ 82 bus_space_read_4((bas)->bst, (bas)->bsh, uart_regofs(bas, reg)) 83#define WR4(bas, reg, value) \ 84 bus_space_write_4((bas)->bst, (bas)->bsh, uart_regofs(bas, reg), value) 85 86#define SIGCHG(c, i, s, d) \ 87 do { \ 88 if (c) { \ 89 i |= (i & s) ? s : s | d; \ 90 } else { \ 91 i = (i & s) ? (i & ~s) | d : i; \ 92 } \ 93 } while (0); 94 95#define BAUD2DIVISOR(b) \ 96 ((((DEFAULT_RCLK * 10) / ((b) * 16)) + 5) / 10) 97 98/* 99 * Low-level UART interface. 100 */ 101static int at91_usart_probe(struct uart_bas *bas); 102static void at91_usart_init(struct uart_bas *bas, int, int, int, int); 103static void at91_usart_term(struct uart_bas *bas); 104static void at91_usart_putc(struct uart_bas *bas, int); 105static int at91_usart_rxready(struct uart_bas *bas); 106static int at91_usart_getc(struct uart_bas *bas, struct mtx *hwmtx); 107 108extern SLIST_HEAD(uart_devinfo_list, uart_devinfo) uart_sysdevs; 109 110static int 111at91_usart_param(struct uart_bas *bas, int baudrate, int databits, 112 int stopbits, int parity) 113{ 114 uint32_t mr; 115 116 /* 117 * Assume 3-wire RS-232 configuration. 118 * XXX Not sure how uart will present the other modes to us, so 119 * XXX they are unimplemented. maybe ioctl? 120 */ 121 mr = USART_MR_MODE_NORMAL; 122 mr |= USART_MR_USCLKS_MCK; /* Assume MCK */ 123 124 /* 125 * Or in the databits requested 126 */ 127 if (databits < 9) 128 mr &= ~USART_MR_MODE9; 129 switch (databits) { 130 case 5: 131 mr |= USART_MR_CHRL_5BITS; 132 break; 133 case 6: 134 mr |= USART_MR_CHRL_6BITS; 135 break; 136 case 7: 137 mr |= USART_MR_CHRL_7BITS; 138 break; 139 case 8: 140 mr |= USART_MR_CHRL_8BITS; 141 break; 142 case 9: 143 mr |= USART_MR_CHRL_8BITS | USART_MR_MODE9; 144 break; 145 default: 146 return (EINVAL); 147 } 148 149 /* 150 * Or in the parity 151 */ 152 switch (parity) { 153 case UART_PARITY_NONE: 154 mr |= USART_MR_PAR_NONE; 155 break; 156 case UART_PARITY_ODD: 157 mr |= USART_MR_PAR_ODD; 158 break; 159 case UART_PARITY_EVEN: 160 mr |= USART_MR_PAR_EVEN; 161 break; 162 case UART_PARITY_MARK: 163 mr |= USART_MR_PAR_MARK; 164 break; 165 case UART_PARITY_SPACE: 166 mr |= USART_MR_PAR_SPACE; 167 break; 168 default: 169 return (EINVAL); 170 } 171 172 /* 173 * Or in the stop bits. Note: The hardware supports 1.5 stop 174 * bits in async mode, but there's no way to specify that 175 * AFAICT. Instead, rely on the convention documented at 176 * http://www.lammertbies.nl/comm/info/RS-232_specs.html which 177 * states that 1.5 stop bits are used for 5 bit bytes and 178 * 2 stop bits only for longer bytes. 179 */ 180 if (stopbits == 1) 181 mr |= USART_MR_NBSTOP_1; 182 else if (databits > 5) 183 mr |= USART_MR_NBSTOP_2; 184 else 185 mr |= USART_MR_NBSTOP_1_5; 186 187 /* 188 * We want normal plumbing mode too, none of this fancy 189 * loopback or echo mode. 190 */ 191 mr |= USART_MR_CHMODE_NORMAL; 192 193 mr &= ~USART_MR_MSBF; /* lsb first */ 194 mr &= ~USART_MR_CKLO_SCK; /* Don't drive SCK */ 195 196 WR4(bas, USART_MR, mr); 197 198 /* 199 * Set the baud rate (only if we know our master clock rate) 200 */ 201 if (DEFAULT_RCLK != 0) 202 WR4(bas, USART_BRGR, BAUD2DIVISOR(baudrate)); 203 204 /* 205 * Set the receive timeout based on the baud rate. The idea is to 206 * compromise between being responsive on an interactive connection and 207 * giving a bulk data sender a bit of time to queue up a new buffer 208 * without mistaking it for a stopping point in the transmission. For 209 * 19.2kbps and below, use 20 * bit time (2 characters). For faster 210 * connections use 500 microseconds worth of bits. 211 */ 212 if (baudrate <= 19200) 213 WR4(bas, USART_RTOR, 20); 214 else 215 WR4(bas, USART_RTOR, baudrate / 2000); 216 WR4(bas, USART_CR, USART_CR_STTTO); 217 218 /* XXX Need to take possible synchronous mode into account */ 219 return (0); 220} 221 222static void 223at91_usart_grab(struct uart_bas *bas) 224{ 225 226 WR4(bas, USART_IDR, USART_CSR_RXRDY); 227} 228 229static void 230at91_usart_ungrab(struct uart_bas *bas) 231{ 232 233 WR4(bas, USART_IER, USART_CSR_RXRDY); 234} 235 236static struct uart_ops at91_usart_ops = { 237 .probe = at91_usart_probe, 238 .init = at91_usart_init, 239 .term = at91_usart_term, 240 .putc = at91_usart_putc, 241 .rxready = at91_usart_rxready, 242 .getc = at91_usart_getc, 243 .grab = at91_usart_grab, 244 .ungrab = at91_usart_ungrab, 245}; 246 247static int 248at91_usart_probe(struct uart_bas *bas) 249{ 250 251 /* We know that this is always here */ 252 return (0); 253} 254 255/* 256 * Initialize this device for use as a console. 257 */ 258static void 259at91_usart_init(struct uart_bas *bas, int baudrate, int databits, int stopbits, 260 int parity) 261{ 262 263 at91_usart_param(bas, baudrate, databits, stopbits, parity); 264 265 /* Reset the rx and tx buffers and turn on rx and tx */ 266 WR4(bas, USART_CR, USART_CR_RSTSTA | USART_CR_RSTRX | USART_CR_RSTTX); 267 WR4(bas, USART_CR, USART_CR_RXEN | USART_CR_TXEN); 268 WR4(bas, USART_IDR, 0xffffffff); 269} 270 271/* 272 * Free resources now that we're no longer the console. This appears to 273 * be never called, and I'm unsure quite what to do if I am called. 274 */ 275static void 276at91_usart_term(struct uart_bas *bas) 277{ 278 279 /* XXX */ 280} 281 282/* 283 * Put a character of console output (so we do it here polling rather than 284 * interrupt driven). 285 */ 286static void 287at91_usart_putc(struct uart_bas *bas, int c) 288{ 289 290 while (!(RD4(bas, USART_CSR) & USART_CSR_TXRDY)) 291 continue; 292 WR4(bas, USART_THR, c); 293} 294 295/* 296 * Check for a character available. 297 */ 298static int 299at91_usart_rxready(struct uart_bas *bas) 300{ 301 302 return ((RD4(bas, USART_CSR) & USART_CSR_RXRDY) != 0 ? 1 : 0); 303} 304 305/* 306 * Block waiting for a character. 307 */ 308static int 309at91_usart_getc(struct uart_bas *bas, struct mtx *hwmtx) 310{ 311 int c; 312 313 uart_lock(hwmtx); 314 while (!(RD4(bas, USART_CSR) & USART_CSR_RXRDY)) { 315 uart_unlock(hwmtx); 316 DELAY(4); 317 uart_lock(hwmtx); 318 } 319 c = RD4(bas, USART_RHR) & 0xff; 320 uart_unlock(hwmtx); 321 return (c); 322} 323 324static int at91_usart_bus_probe(struct uart_softc *sc); 325static int at91_usart_bus_attach(struct uart_softc *sc); 326static int at91_usart_bus_flush(struct uart_softc *, int); 327static int at91_usart_bus_getsig(struct uart_softc *); 328static int at91_usart_bus_ioctl(struct uart_softc *, int, intptr_t); 329static int at91_usart_bus_ipend(struct uart_softc *); 330static int at91_usart_bus_param(struct uart_softc *, int, int, int, int); 331static int at91_usart_bus_receive(struct uart_softc *); 332static int at91_usart_bus_setsig(struct uart_softc *, int); 333static int at91_usart_bus_transmit(struct uart_softc *); 334 335static kobj_method_t at91_usart_methods[] = { 336 KOBJMETHOD(uart_probe, at91_usart_bus_probe), 337 KOBJMETHOD(uart_attach, at91_usart_bus_attach), 338 KOBJMETHOD(uart_flush, at91_usart_bus_flush), 339 KOBJMETHOD(uart_getsig, at91_usart_bus_getsig), 340 KOBJMETHOD(uart_ioctl, at91_usart_bus_ioctl), 341 KOBJMETHOD(uart_ipend, at91_usart_bus_ipend), 342 KOBJMETHOD(uart_param, at91_usart_bus_param), 343 KOBJMETHOD(uart_receive, at91_usart_bus_receive), 344 KOBJMETHOD(uart_setsig, at91_usart_bus_setsig), 345 KOBJMETHOD(uart_transmit, at91_usart_bus_transmit), 346 347 KOBJMETHOD_END 348}; 349 350int 351at91_usart_bus_probe(struct uart_softc *sc) 352{ 353 int value; 354 355 value = USART_DEFAULT_FIFO_BYTES; 356 resource_int_value(device_get_name(sc->sc_dev), 357 device_get_unit(sc->sc_dev), "fifo_bytes", &value); 358 value = roundup2(value, arm_dcache_align); 359 sc->sc_txfifosz = value; 360 sc->sc_rxfifosz = value; 361 sc->sc_hwiflow = 0; 362 return (0); 363} 364 365static void 366at91_getaddr(void *arg, bus_dma_segment_t *segs, int nsegs, int error) 367{ 368 369 if (error != 0) 370 return; 371 *(bus_addr_t *)arg = segs[0].ds_addr; 372} 373 374static int 375at91_usart_requires_rts0_workaround(struct uart_softc *sc) 376{ 377 int value; 378 int unit; 379 380 unit = device_get_unit(sc->sc_dev); 381 382 /* 383 * On the rm9200 chips, the PA21/RTS0 pin is not correctly wired to the 384 * usart device interally (so-called 'erratum 39', but it's 41.14 in rev 385 * I of the manual). This prevents use of the hardware flow control 386 * feature in the usart itself. It also means that if we are to 387 * implement RTS/CTS flow via the tty layer logic, we must use pin PA21 388 * as a gpio and manually manipulate it in at91_usart_bus_setsig(). We 389 * can only safely do so if we've been given permission via a hint, 390 * otherwise we might manipulate a pin that's attached to who-knows-what 391 * and Bad Things could happen. 392 */ 393 if (at91_is_rm92() && unit == 1) { 394 value = 0; 395 resource_int_value(device_get_name(sc->sc_dev), unit, 396 "use_rts0_workaround", &value); 397 if (value != 0) { 398 at91_pio_use_gpio(AT91RM92_PIOA_BASE, AT91C_PIO_PA21); 399 at91_pio_gpio_output(AT91RM92_PIOA_BASE, 400 AT91C_PIO_PA21, 1); 401 at91_pio_use_periph_a(AT91RM92_PIOA_BASE, 402 AT91C_PIO_PA20, 0); 403 return (1); 404 } 405 } 406 return (0); 407} 408 409static int 410at91_usart_bus_attach(struct uart_softc *sc) 411{ 412 int err; 413 int i; 414 uint32_t cr; 415 struct at91_usart_softc *atsc; 416 417 atsc = (struct at91_usart_softc *)sc; 418 419 if (at91_usart_requires_rts0_workaround(sc)) 420 atsc->flags |= USE_RTS0_WORKAROUND; 421 422 /* 423 * See if we have a TIMEOUT bit. We disable all interrupts as 424 * a side effect. Boot loaders may have enabled them. Since 425 * a TIMEOUT interrupt can't happen without other setup, the 426 * apparent race here can't actually happen. 427 */ 428 WR4(&sc->sc_bas, USART_IDR, 0xffffffff); 429 WR4(&sc->sc_bas, USART_IER, USART_CSR_TIMEOUT); 430 if (RD4(&sc->sc_bas, USART_IMR) & USART_CSR_TIMEOUT) 431 atsc->flags |= HAS_TIMEOUT; 432 WR4(&sc->sc_bas, USART_IDR, 0xffffffff); 433 434 /* 435 * Allocate transmit DMA tag and map. We allow a transmit buffer 436 * to be any size, but it must map to a single contiguous physical 437 * extent. 438 */ 439 err = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), 1, 0, 440 BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL, 441 BUS_SPACE_MAXSIZE_32BIT, 1, BUS_SPACE_MAXSIZE_32BIT, 0, NULL, 442 NULL, &atsc->tx_tag); 443 if (err != 0) 444 goto errout; 445 err = bus_dmamap_create(atsc->tx_tag, 0, &atsc->tx_map); 446 if (err != 0) 447 goto errout; 448 449 if (atsc->flags & HAS_TIMEOUT) { 450 /* 451 * Allocate receive DMA tags, maps, and buffers. 452 * The receive buffers should be aligned to arm_dcache_align, 453 * otherwise partial cache line flushes on every receive 454 * interrupt are pretty much guaranteed. 455 */ 456 err = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), 457 arm_dcache_align, 0, BUS_SPACE_MAXADDR_32BIT, 458 BUS_SPACE_MAXADDR, NULL, NULL, sc->sc_rxfifosz, 1, 459 sc->sc_rxfifosz, BUS_DMA_ALLOCNOW, NULL, NULL, 460 &atsc->rx_tag); 461 if (err != 0) 462 goto errout; 463 for (i = 0; i < 2; i++) { 464 err = bus_dmamem_alloc(atsc->rx_tag, 465 (void **)&atsc->ping_pong[i].buffer, 466 BUS_DMA_NOWAIT, &atsc->ping_pong[i].map); 467 if (err != 0) 468 goto errout; 469 err = bus_dmamap_load(atsc->rx_tag, 470 atsc->ping_pong[i].map, 471 atsc->ping_pong[i].buffer, sc->sc_rxfifosz, 472 at91_getaddr, &atsc->ping_pong[i].pa, 0); 473 if (err != 0) 474 goto errout; 475 bus_dmamap_sync(atsc->rx_tag, atsc->ping_pong[i].map, 476 BUS_DMASYNC_PREREAD); 477 } 478 atsc->ping = &atsc->ping_pong[0]; 479 atsc->pong = &atsc->ping_pong[1]; 480 } 481 482 /* Turn on rx and tx */ 483 cr = USART_CR_RSTSTA | USART_CR_RSTRX | USART_CR_RSTTX; 484 WR4(&sc->sc_bas, USART_CR, cr); 485 WR4(&sc->sc_bas, USART_CR, USART_CR_RXEN | USART_CR_TXEN); 486 487 /* 488 * Setup the PDC to receive data. We use the ping-pong buffers 489 * so that we can more easily bounce between the two and so that 490 * we get an interrupt 1/2 way through the software 'fifo' we have 491 * to avoid overruns. 492 */ 493 if (atsc->flags & HAS_TIMEOUT) { 494 WR4(&sc->sc_bas, PDC_RPR, atsc->ping->pa); 495 WR4(&sc->sc_bas, PDC_RCR, sc->sc_rxfifosz); 496 WR4(&sc->sc_bas, PDC_RNPR, atsc->pong->pa); 497 WR4(&sc->sc_bas, PDC_RNCR, sc->sc_rxfifosz); 498 WR4(&sc->sc_bas, PDC_PTCR, PDC_PTCR_RXTEN); 499 500 /* 501 * Set the receive timeout to be 1.5 character times 502 * assuming 8N1. 503 */ 504 WR4(&sc->sc_bas, USART_RTOR, 15); 505 WR4(&sc->sc_bas, USART_CR, USART_CR_STTTO); 506 WR4(&sc->sc_bas, USART_IER, USART_CSR_TIMEOUT | 507 USART_CSR_RXBUFF | USART_CSR_ENDRX); 508 } else { 509 WR4(&sc->sc_bas, USART_IER, USART_CSR_RXRDY); 510 } 511 WR4(&sc->sc_bas, USART_IER, USART_CSR_RXBRK | USART_DCE_CHANGE_BITS); 512 513 /* Prime sc->hwsig with the initial hw line states. */ 514 at91_usart_bus_getsig(sc); 515 516errout: 517 return (err); 518} 519 520static int 521at91_usart_bus_transmit(struct uart_softc *sc) 522{ 523 bus_addr_t addr; 524 struct at91_usart_softc *atsc; 525 int err; 526 527 err = 0; 528 atsc = (struct at91_usart_softc *)sc; 529 uart_lock(sc->sc_hwmtx); 530 if (bus_dmamap_load(atsc->tx_tag, atsc->tx_map, sc->sc_txbuf, 531 sc->sc_txdatasz, at91_getaddr, &addr, 0) != 0) { 532 err = EAGAIN; 533 goto errout; 534 } 535 bus_dmamap_sync(atsc->tx_tag, atsc->tx_map, BUS_DMASYNC_PREWRITE); 536 sc->sc_txbusy = 1; 537 /* 538 * Setup the PDC to transfer the data and interrupt us when it 539 * is done. We've already requested the interrupt. 540 */ 541 WR4(&sc->sc_bas, PDC_TPR, addr); 542 WR4(&sc->sc_bas, PDC_TCR, sc->sc_txdatasz); 543 WR4(&sc->sc_bas, PDC_PTCR, PDC_PTCR_TXTEN); 544 WR4(&sc->sc_bas, USART_IER, USART_CSR_ENDTX); 545errout: 546 uart_unlock(sc->sc_hwmtx); 547 return (err); 548} 549 550static int 551at91_usart_bus_setsig(struct uart_softc *sc, int sig) 552{ 553 uint32_t new, old, cr; 554 struct at91_usart_softc *atsc; 555 556 atsc = (struct at91_usart_softc *)sc; 557 558 do { 559 old = sc->sc_hwsig; 560 new = old; 561 if (sig & SER_DDTR) 562 SIGCHG(sig & SER_DTR, new, SER_DTR, SER_DDTR); 563 if (sig & SER_DRTS) 564 SIGCHG(sig & SER_RTS, new, SER_RTS, SER_DRTS); 565 } while (!atomic_cmpset_32(&sc->sc_hwsig, old, new)); 566 567 cr = 0; 568 if (new & SER_DTR) 569 cr |= USART_CR_DTREN; 570 else 571 cr |= USART_CR_DTRDIS; 572 if (new & SER_RTS) 573 cr |= USART_CR_RTSEN; 574 else 575 cr |= USART_CR_RTSDIS; 576 577 uart_lock(sc->sc_hwmtx); 578 WR4(&sc->sc_bas, USART_CR, cr); 579 if (atsc->flags & USE_RTS0_WORKAROUND) { 580 /* Signal is active-low. */ 581 if (new & SER_RTS) 582 at91_pio_gpio_clear(AT91RM92_PIOA_BASE, AT91C_PIO_PA21); 583 else 584 at91_pio_gpio_set(AT91RM92_PIOA_BASE,AT91C_PIO_PA21); 585 } 586 uart_unlock(sc->sc_hwmtx); 587 588 return (0); 589} 590 591static int 592at91_usart_bus_receive(struct uart_softc *sc) 593{ 594 595 return (0); 596} 597 598static int 599at91_usart_bus_param(struct uart_softc *sc, int baudrate, int databits, 600 int stopbits, int parity) 601{ 602 603 return (at91_usart_param(&sc->sc_bas, baudrate, databits, stopbits, 604 parity)); 605} 606 607static __inline void 608at91_rx_put(struct uart_softc *sc, int key) 609{ 610 611#if defined(KDB) 612 if (sc->sc_sysdev != NULL && sc->sc_sysdev->type == UART_DEV_CONSOLE) 613 kdb_alt_break(key, &sc->sc_altbrk); 614#endif 615 uart_rx_put(sc, key); 616} 617 618static int 619at91_usart_bus_ipend(struct uart_softc *sc) 620{ 621 struct at91_usart_softc *atsc; 622 struct at91_usart_rx *p; 623 int i, ipend, len; 624 uint32_t csr; 625 626 ipend = 0; 627 atsc = (struct at91_usart_softc *)sc; 628 uart_lock(sc->sc_hwmtx); 629 csr = RD4(&sc->sc_bas, USART_CSR); 630 631 if (csr & USART_CSR_OVRE) { 632 WR4(&sc->sc_bas, USART_CR, USART_CR_RSTSTA); 633 ipend |= SER_INT_OVERRUN; 634 } 635 636 if (csr & USART_DCE_CHANGE_BITS) 637 ipend |= SER_INT_SIGCHG; 638 639 if (csr & USART_CSR_ENDTX) { 640 bus_dmamap_sync(atsc->tx_tag, atsc->tx_map, 641 BUS_DMASYNC_POSTWRITE); 642 bus_dmamap_unload(atsc->tx_tag, atsc->tx_map); 643 } 644 if (csr & (USART_CSR_TXRDY | USART_CSR_ENDTX)) { 645 if (sc->sc_txbusy) 646 ipend |= SER_INT_TXIDLE; 647 WR4(&sc->sc_bas, USART_IDR, csr & (USART_CSR_TXRDY | 648 USART_CSR_ENDTX)); 649 } 650 651 /* 652 * Due to the contraints of the DMA engine present in the 653 * atmel chip, I can't just say I have a rx interrupt pending 654 * and do all the work elsewhere. I need to look at the CSR 655 * bits right now and do things based on them to avoid races. 656 */ 657 if (atsc->flags & HAS_TIMEOUT) { 658 if (csr & USART_CSR_RXBUFF) { 659 /* 660 * We have a buffer overflow. Consume data from ping 661 * and give it back to the hardware before worrying 662 * about pong, to minimze data loss. Insert an overrun 663 * marker after the contents of the pong buffer. 664 */ 665 WR4(&sc->sc_bas, PDC_PTCR, PDC_PTCR_RXTDIS); 666 bus_dmamap_sync(atsc->rx_tag, atsc->ping->map, 667 BUS_DMASYNC_POSTREAD); 668 for (i = 0; i < sc->sc_rxfifosz; i++) 669 at91_rx_put(sc, atsc->ping->buffer[i]); 670 bus_dmamap_sync(atsc->rx_tag, atsc->ping->map, 671 BUS_DMASYNC_PREREAD); 672 WR4(&sc->sc_bas, PDC_RPR, atsc->ping->pa); 673 WR4(&sc->sc_bas, PDC_RCR, sc->sc_rxfifosz); 674 WR4(&sc->sc_bas, PDC_PTCR, PDC_PTCR_RXTEN); 675 bus_dmamap_sync(atsc->rx_tag, atsc->pong->map, 676 BUS_DMASYNC_POSTREAD); 677 for (i = 0; i < sc->sc_rxfifosz; i++) 678 at91_rx_put(sc, atsc->pong->buffer[i]); 679 uart_rx_put(sc, UART_STAT_OVERRUN); 680 bus_dmamap_sync(atsc->rx_tag, atsc->pong->map, 681 BUS_DMASYNC_PREREAD); 682 WR4(&sc->sc_bas, PDC_RNPR, atsc->pong->pa); 683 WR4(&sc->sc_bas, PDC_RNCR, sc->sc_rxfifosz); 684 ipend |= SER_INT_RXREADY; 685 } else if (csr & USART_CSR_ENDRX) { 686 /* 687 * Consume data from ping of ping pong buffer, but leave 688 * current pong in place, as it has become the new ping. 689 * We need to copy data and setup the old ping as the 690 * new pong when we're done. 691 */ 692 bus_dmamap_sync(atsc->rx_tag, atsc->ping->map, 693 BUS_DMASYNC_POSTREAD); 694 for (i = 0; i < sc->sc_rxfifosz; i++) 695 at91_rx_put(sc, atsc->ping->buffer[i]); 696 p = atsc->ping; 697 atsc->ping = atsc->pong; 698 atsc->pong = p; 699 bus_dmamap_sync(atsc->rx_tag, atsc->pong->map, 700 BUS_DMASYNC_PREREAD); 701 WR4(&sc->sc_bas, PDC_RNPR, atsc->pong->pa); 702 WR4(&sc->sc_bas, PDC_RNCR, sc->sc_rxfifosz); 703 ipend |= SER_INT_RXREADY; 704 } else if (csr & USART_CSR_TIMEOUT) { 705 /* 706 * On a timeout, one of the following applies: 707 * 1. Two empty buffers. The last received byte exactly 708 * filled a buffer, causing an ENDTX that got 709 * processed earlier; no new bytes have arrived. 710 * 2. Ping buffer contains some data and pong is empty. 711 * This should be the most common timeout condition. 712 * 3. Ping buffer is full and pong is now being filled. 713 * This is exceedingly rare; it can happen only if 714 * the ping buffer is almost full when a timeout is 715 * signaled, and then dataflow resumes and the ping 716 * buffer filled up between the time we read the 717 * status register above and the point where the 718 * RXTDIS takes effect here. Yes, it can happen. 719 * Because dataflow can resume at any time following a 720 * timeout (it may have already resumed before we get 721 * here), it's important to minimize the time the PDC is 722 * disabled -- just long enough to take the ping buffer 723 * out of service (so we can consume it) and install the 724 * pong buffer as the active one. Note that in case 3 725 * the hardware has already done the ping-pong swap. 726 */ 727 WR4(&sc->sc_bas, PDC_PTCR, PDC_PTCR_RXTDIS); 728 if (RD4(&sc->sc_bas, PDC_RNCR) == 0) { 729 len = sc->sc_rxfifosz; 730 } else { 731 len = sc->sc_rxfifosz - RD4(&sc->sc_bas, PDC_RCR); 732 WR4(&sc->sc_bas, PDC_RPR, atsc->pong->pa); 733 WR4(&sc->sc_bas, PDC_RCR, sc->sc_rxfifosz); 734 WR4(&sc->sc_bas, PDC_RNCR, 0); 735 } 736 WR4(&sc->sc_bas, USART_CR, USART_CR_STTTO); 737 WR4(&sc->sc_bas, PDC_PTCR, PDC_PTCR_RXTEN); 738 bus_dmamap_sync(atsc->rx_tag, atsc->ping->map, 739 BUS_DMASYNC_POSTREAD); 740 for (i = 0; i < len; i++) 741 at91_rx_put(sc, atsc->ping->buffer[i]); 742 bus_dmamap_sync(atsc->rx_tag, atsc->ping->map, 743 BUS_DMASYNC_PREREAD); 744 p = atsc->ping; 745 atsc->ping = atsc->pong; 746 atsc->pong = p; 747 WR4(&sc->sc_bas, PDC_RNPR, atsc->pong->pa); 748 WR4(&sc->sc_bas, PDC_RNCR, sc->sc_rxfifosz); 749 ipend |= SER_INT_RXREADY; 750 } 751 } else if (csr & USART_CSR_RXRDY) { 752 /* 753 * We have another charater in a device that doesn't support 754 * timeouts, so we do it one character at a time. 755 */ 756 at91_rx_put(sc, RD4(&sc->sc_bas, USART_RHR) & 0xff); 757 ipend |= SER_INT_RXREADY; 758 } 759 760 if (csr & USART_CSR_RXBRK) { 761 ipend |= SER_INT_BREAK; 762 WR4(&sc->sc_bas, USART_CR, USART_CR_RSTSTA); 763 } 764 uart_unlock(sc->sc_hwmtx); 765 return (ipend); 766} 767 768static int 769at91_usart_bus_flush(struct uart_softc *sc, int what) 770{ 771 772 return (0); 773} 774 775static int 776at91_usart_bus_getsig(struct uart_softc *sc) 777{ 778 uint32_t csr, new, old, sig; 779 780 /* 781 * Note that the atmel channel status register DCE status bits reflect 782 * the electrical state of the lines, not the logical state. Since they 783 * are logically active-low signals, we invert the tests here. 784 */ 785 do { 786 old = sc->sc_hwsig; 787 sig = old; 788 csr = RD4(&sc->sc_bas, USART_CSR); 789 SIGCHG(!(csr & USART_CSR_DSR), sig, SER_DSR, SER_DDSR); 790 SIGCHG(!(csr & USART_CSR_CTS), sig, SER_CTS, SER_DCTS); 791 SIGCHG(!(csr & USART_CSR_DCD), sig, SER_DCD, SER_DDCD); 792 SIGCHG(!(csr & USART_CSR_RI), sig, SER_RI, SER_DRI); 793 new = sig & ~SER_MASK_DELTA; 794 } while (!atomic_cmpset_32(&sc->sc_hwsig, old, new)); 795 796 return (sig); 797} 798 799static int 800at91_usart_bus_ioctl(struct uart_softc *sc, int request, intptr_t data) 801{ 802 803 switch (request) { 804 case UART_IOCTL_BREAK: 805 case UART_IOCTL_IFLOW: 806 case UART_IOCTL_OFLOW: 807 break; 808 case UART_IOCTL_BAUD: 809 /* only if we know our master clock rate */ 810 if (DEFAULT_RCLK != 0) 811 WR4(&sc->sc_bas, USART_BRGR, 812 BAUD2DIVISOR(*(int *)data)); 813 return (0); 814 } 815 return (EINVAL); 816} 817 818struct uart_class at91_usart_class = { 819 "at91_usart", 820 at91_usart_methods, 821 sizeof(struct at91_usart_softc), 822 .uc_ops = &at91_usart_ops, 823 .uc_range = 8 824}; 825