Mon May 4 22:59:36 2015 UTC ()
For Tegra K1, set IE_RX_TIMEOUT (bit 4) in IER register. RX_TIMEOUT occurs
when data has been sitting in the Rx FIFO for more than 4 character times
without being read because there is not enough data to reach the trigger
level. With this change, enable FIFO usage for Tegra UARTs.


(jmcneill)
diff -r1.335 -r1.336 src/sys/dev/ic/com.c

cvs diff -r1.335 -r1.336 src/sys/dev/ic/com.c (expand / switch to unified diff)

--- src/sys/dev/ic/com.c 2015/05/04 20:25:48 1.335
+++ src/sys/dev/ic/com.c 2015/05/04 22:59:36 1.336
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: com.c,v 1.335 2015/05/04 20:25:48 macallan Exp $ */ 1/* $NetBSD: com.c,v 1.336 2015/05/04 22:59:36 jmcneill Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 1998, 1999, 2004, 2008 The NetBSD Foundation, Inc. 4 * Copyright (c) 1998, 1999, 2004, 2008 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Charles M. Hannum. 8 * by Charles M. Hannum.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -56,27 +56,27 @@ @@ -56,27 +56,27 @@
56 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 56 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
57 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 57 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
58 * SUCH DAMAGE. 58 * SUCH DAMAGE.
59 * 59 *
60 * @(#)com.c 7.5 (Berkeley) 5/16/91 60 * @(#)com.c 7.5 (Berkeley) 5/16/91
61 */ 61 */
62 62
63/* 63/*
64 * COM driver, uses National Semiconductor NS16450/NS16550AF UART 64 * COM driver, uses National Semiconductor NS16450/NS16550AF UART
65 * Supports automatic hardware flow control on StarTech ST16C650A UART 65 * Supports automatic hardware flow control on StarTech ST16C650A UART
66 */ 66 */
67 67
68#include <sys/cdefs.h> 68#include <sys/cdefs.h>
69__KERNEL_RCSID(0, "$NetBSD: com.c,v 1.335 2015/05/04 20:25:48 macallan Exp $"); 69__KERNEL_RCSID(0, "$NetBSD: com.c,v 1.336 2015/05/04 22:59:36 jmcneill Exp $");
70 70
71#include "opt_com.h" 71#include "opt_com.h"
72#include "opt_ddb.h" 72#include "opt_ddb.h"
73#include "opt_kgdb.h" 73#include "opt_kgdb.h"
74#include "opt_lockdebug.h" 74#include "opt_lockdebug.h"
75#include "opt_multiprocessor.h" 75#include "opt_multiprocessor.h"
76#include "opt_ntp.h" 76#include "opt_ntp.h"
77 77
78/* The COM16650 option was renamed to COM_16650. */ 78/* The COM16650 option was renamed to COM_16650. */
79#ifdef COM16650 79#ifdef COM16650
80#error Obsolete COM16650 option; use COM_16650 instead. 80#error Obsolete COM16650 option; use COM_16650 instead.
81#endif 81#endif
82 82
@@ -370,27 +370,28 @@ comprobe1(bus_space_tag_t iot, bus_space @@ -370,27 +370,28 @@ comprobe1(bus_space_tag_t iot, bus_space
370 370
371/* 371/*
372 * No locking in this routine; it is only called during attach, 372 * No locking in this routine; it is only called during attach,
373 * or with the port already locked. 373 * or with the port already locked.
374 */ 374 */
375static void 375static void
376com_enable_debugport(struct com_softc *sc) 376com_enable_debugport(struct com_softc *sc)
377{ 377{
378 378
379 /* Turn on line break interrupt, set carrier. */ 379 /* Turn on line break interrupt, set carrier. */
380 sc->sc_ier = IER_ERXRDY; 380 sc->sc_ier = IER_ERXRDY;
381 if (sc->sc_type == COM_TYPE_PXA2x0) 381 if (sc->sc_type == COM_TYPE_PXA2x0)
382 sc->sc_ier |= IER_EUART | IER_ERXTOUT; 382 sc->sc_ier |= IER_EUART | IER_ERXTOUT;
383 if (sc->sc_type == COM_TYPE_INGENIC) 383 if (sc->sc_type == COM_TYPE_INGENIC ||
 384 sc->sc_type == COM_TYPE_TEGRA)
384 sc->sc_ier |= IER_ERXTOUT; 385 sc->sc_ier |= IER_ERXTOUT;
385 CSR_WRITE_1(&sc->sc_regs, COM_REG_IER, sc->sc_ier); 386 CSR_WRITE_1(&sc->sc_regs, COM_REG_IER, sc->sc_ier);
386 SET(sc->sc_mcr, MCR_DTR | MCR_RTS); 387 SET(sc->sc_mcr, MCR_DTR | MCR_RTS);
387 CSR_WRITE_1(&sc->sc_regs, COM_REG_MCR, sc->sc_mcr); 388 CSR_WRITE_1(&sc->sc_regs, COM_REG_MCR, sc->sc_mcr);
388} 389}
389 390
390void 391void
391com_attach_subr(struct com_softc *sc) 392com_attach_subr(struct com_softc *sc)
392{ 393{
393 struct com_regs *regsp = &sc->sc_regs; 394 struct com_regs *regsp = &sc->sc_regs;
394 struct tty *tp; 395 struct tty *tp;
395#if defined(COM_16650) || defined(COM_16750) 396#if defined(COM_16650) || defined(COM_16750)
396 u_int8_t lcr; 397 u_int8_t lcr;
@@ -456,31 +457,26 @@ com_attach_subr(struct com_softc *sc) @@ -456,31 +457,26 @@ com_attach_subr(struct com_softc *sc)
456 457
457 case COM_TYPE_OMAP: 458 case COM_TYPE_OMAP:
458 sc->sc_fifolen = 64; 459 sc->sc_fifolen = 64;
459 fifo_msg = "OMAP UART, working fifo"; 460 fifo_msg = "OMAP UART, working fifo";
460 SET(sc->sc_hwflags, COM_HW_FIFO); 461 SET(sc->sc_hwflags, COM_HW_FIFO);
461 goto fifodelay; 462 goto fifodelay;
462 463
463 case COM_TYPE_INGENIC: 464 case COM_TYPE_INGENIC:
464 sc->sc_fifolen = 16; 465 sc->sc_fifolen = 16;
465 fifo_msg = "Ingenic UART, working fifo"; 466 fifo_msg = "Ingenic UART, working fifo";
466 SET(sc->sc_hwflags, COM_HW_FIFO); 467 SET(sc->sc_hwflags, COM_HW_FIFO);
467 SET(sc->sc_hwflags, COM_HW_NOIEN); 468 SET(sc->sc_hwflags, COM_HW_NOIEN);
468 goto fifodelay; 469 goto fifodelay;
469 
470 case COM_TYPE_TEGRA: 
471 sc->sc_fifolen = 1; 
472 fifo_msg = "Tegra UART, broken fifo"; 
473 goto fifodelay; 
474 } 470 }
475 471
476 sc->sc_fifolen = 1; 472 sc->sc_fifolen = 1;
477 /* look for a NS 16550AF UART with FIFOs */ 473 /* look for a NS 16550AF UART with FIFOs */
478 if (sc->sc_type == COM_TYPE_INGENIC) { 474 if (sc->sc_type == COM_TYPE_INGENIC) {
479 CSR_WRITE_1(regsp, COM_REG_FIFO, 475 CSR_WRITE_1(regsp, COM_REG_FIFO,
480 FIFO_ENABLE | FIFO_RCV_RST | FIFO_XMT_RST |  476 FIFO_ENABLE | FIFO_RCV_RST | FIFO_XMT_RST |
481 FIFO_TRIGGER_14 | FIFO_UART_ON); 477 FIFO_TRIGGER_14 | FIFO_UART_ON);
482 } else 478 } else
483 CSR_WRITE_1(regsp, COM_REG_FIFO, 479 CSR_WRITE_1(regsp, COM_REG_FIFO,
484 FIFO_ENABLE | FIFO_RCV_RST | FIFO_XMT_RST | FIFO_TRIGGER_14); 480 FIFO_ENABLE | FIFO_RCV_RST | FIFO_XMT_RST | FIFO_TRIGGER_14);
485 delay(100); 481 delay(100);
486 if (ISSET(CSR_READ_1(regsp, COM_REG_IIR), IIR_FIFO_MASK) 482 if (ISSET(CSR_READ_1(regsp, COM_REG_IIR), IIR_FIFO_MASK)
@@ -808,27 +804,28 @@ com_shutdown(struct com_softc *sc) @@ -808,27 +804,28 @@ com_shutdown(struct com_softc *sc)
808 */ 804 */
809 if (ISSET(tp->t_cflag, HUPCL)) { 805 if (ISSET(tp->t_cflag, HUPCL)) {
810 com_modem(sc, 0); 806 com_modem(sc, 0);
811 mutex_spin_exit(&sc->sc_lock); 807 mutex_spin_exit(&sc->sc_lock);
812 /* XXX will only timeout */ 808 /* XXX will only timeout */
813 (void) kpause(ttclos, false, hz, NULL); 809 (void) kpause(ttclos, false, hz, NULL);
814 mutex_spin_enter(&sc->sc_lock); 810 mutex_spin_enter(&sc->sc_lock);
815 } 811 }
816 812
817 /* Turn off interrupts. */ 813 /* Turn off interrupts. */
818 if (ISSET(sc->sc_hwflags, COM_HW_CONSOLE)) { 814 if (ISSET(sc->sc_hwflags, COM_HW_CONSOLE)) {
819 sc->sc_ier = IER_ERXRDY; /* interrupt on break */ 815 sc->sc_ier = IER_ERXRDY; /* interrupt on break */
820 if ((sc->sc_type == COM_TYPE_PXA2x0) || 816 if ((sc->sc_type == COM_TYPE_PXA2x0) ||
821 (sc->sc_type == COM_TYPE_INGENIC)) 817 (sc->sc_type == COM_TYPE_INGENIC) ||
 818 (sc->sc_type == COM_TYPE_TEGRA))
822 sc->sc_ier |= IER_ERXTOUT; 819 sc->sc_ier |= IER_ERXTOUT;
823 } else 820 } else
824 sc->sc_ier = 0; 821 sc->sc_ier = 0;
825 822
826 if (sc->sc_type == COM_TYPE_PXA2x0) 823 if (sc->sc_type == COM_TYPE_PXA2x0)
827 sc->sc_ier |= IER_EUART; 824 sc->sc_ier |= IER_EUART;
828 825
829 CSR_WRITE_1(&sc->sc_regs, COM_REG_IER, sc->sc_ier); 826 CSR_WRITE_1(&sc->sc_regs, COM_REG_IER, sc->sc_ier);
830 827
831 mutex_spin_exit(&sc->sc_lock); 828 mutex_spin_exit(&sc->sc_lock);
832 829
833 if (sc->disable) { 830 if (sc->disable) {
834#ifdef DIAGNOSTIC 831#ifdef DIAGNOSTIC
@@ -890,27 +887,28 @@ comopen(dev_t dev, int flag, int mode, s @@ -890,27 +887,28 @@ comopen(dev_t dev, int flag, int mode, s
890 sc->enabled = 1; 887 sc->enabled = 1;
891 com_config(sc); 888 com_config(sc);
892 } else { 889 } else {
893 mutex_spin_enter(&sc->sc_lock); 890 mutex_spin_enter(&sc->sc_lock);
894 } 891 }
895 892
896 /* Turn on interrupts. */ 893 /* Turn on interrupts. */
897 sc->sc_ier = IER_ERXRDY | IER_ERLS; 894 sc->sc_ier = IER_ERXRDY | IER_ERLS;
898 if (!ISSET(tp->t_cflag, CLOCAL)) 895 if (!ISSET(tp->t_cflag, CLOCAL))
899 sc->sc_ier |= IER_EMSC; 896 sc->sc_ier |= IER_EMSC;
900 897
901 if (sc->sc_type == COM_TYPE_PXA2x0) 898 if (sc->sc_type == COM_TYPE_PXA2x0)
902 sc->sc_ier |= IER_EUART | IER_ERXTOUT; 899 sc->sc_ier |= IER_EUART | IER_ERXTOUT;
903 else if (sc->sc_type == COM_TYPE_INGENIC) 900 else if (sc->sc_type == COM_TYPE_INGENIC ||
 901 sc->sc_type == COM_TYPE_TEGRA)
904 sc->sc_ier |= IER_ERXTOUT; 902 sc->sc_ier |= IER_ERXTOUT;
905 CSR_WRITE_1(&sc->sc_regs, COM_REG_IER, sc->sc_ier); 903 CSR_WRITE_1(&sc->sc_regs, COM_REG_IER, sc->sc_ier);
906 904
907 /* Fetch the current modem control status, needed later. */ 905 /* Fetch the current modem control status, needed later. */
908 sc->sc_msr = CSR_READ_1(&sc->sc_regs, COM_REG_MSR); 906 sc->sc_msr = CSR_READ_1(&sc->sc_regs, COM_REG_MSR);
909 907
910 /* Clear PPS capture state on first open. */ 908 /* Clear PPS capture state on first open. */
911 mutex_spin_enter(&timecounter_lock); 909 mutex_spin_enter(&timecounter_lock);
912 memset(&sc->sc_pps_state, 0, sizeof(sc->sc_pps_state)); 910 memset(&sc->sc_pps_state, 0, sizeof(sc->sc_pps_state));
913 sc->sc_pps_state.ppscap = PPS_CAPTUREASSERT | PPS_CAPTURECLEAR; 911 sc->sc_pps_state.ppscap = PPS_CAPTUREASSERT | PPS_CAPTURECLEAR;
914 pps_init(&sc->sc_pps_state); 912 pps_init(&sc->sc_pps_state);
915 mutex_spin_exit(&timecounter_lock); 913 mutex_spin_exit(&timecounter_lock);
916 914
@@ -1899,27 +1897,28 @@ com_rxsoft(struct com_softc *sc, struct  @@ -1899,27 +1897,28 @@ com_rxsoft(struct com_softc *sc, struct
1899 sc->sc_rbget = get; 1897 sc->sc_rbget = get;
1900 mutex_spin_enter(&sc->sc_lock); 1898 mutex_spin_enter(&sc->sc_lock);
1901 1899
1902 cc = sc->sc_rbavail += scc - cc; 1900 cc = sc->sc_rbavail += scc - cc;
1903 /* Buffers should be ok again, release possible block. */ 1901 /* Buffers should be ok again, release possible block. */
1904 if (cc >= sc->sc_r_lowat) { 1902 if (cc >= sc->sc_r_lowat) {
1905 if (ISSET(sc->sc_rx_flags, RX_IBUF_OVERFLOWED)) { 1903 if (ISSET(sc->sc_rx_flags, RX_IBUF_OVERFLOWED)) {
1906 CLR(sc->sc_rx_flags, RX_IBUF_OVERFLOWED); 1904 CLR(sc->sc_rx_flags, RX_IBUF_OVERFLOWED);
1907 SET(sc->sc_ier, IER_ERXRDY); 1905 SET(sc->sc_ier, IER_ERXRDY);
1908#ifdef COM_PXA2X0 1906#ifdef COM_PXA2X0
1909 if (sc->sc_type == COM_TYPE_PXA2x0) 1907 if (sc->sc_type == COM_TYPE_PXA2x0)
1910 SET(sc->sc_ier, IER_ERXTOUT); 1908 SET(sc->sc_ier, IER_ERXTOUT);
1911#endif 1909#endif
1912 if (sc->sc_type == COM_TYPE_INGENIC) 1910 if (sc->sc_type == COM_TYPE_INGENIC ||
 1911 sc->sc_type == COM_TYPE_TEGRA)
1913 SET(sc->sc_ier, IER_ERXTOUT); 1912 SET(sc->sc_ier, IER_ERXTOUT);
1914 1913
1915 CSR_WRITE_1(&sc->sc_regs, COM_REG_IER, 1914 CSR_WRITE_1(&sc->sc_regs, COM_REG_IER,
1916 sc->sc_ier); 1915 sc->sc_ier);
1917 } 1916 }
1918 if (ISSET(sc->sc_rx_flags, RX_IBUF_BLOCKED)) { 1917 if (ISSET(sc->sc_rx_flags, RX_IBUF_BLOCKED)) {
1919 CLR(sc->sc_rx_flags, RX_IBUF_BLOCKED); 1918 CLR(sc->sc_rx_flags, RX_IBUF_BLOCKED);
1920 com_hwiflow(sc); 1919 com_hwiflow(sc);
1921 } 1920 }
1922 } 1921 }
1923 mutex_spin_exit(&sc->sc_lock); 1922 mutex_spin_exit(&sc->sc_lock);
1924 } 1923 }
1925} 1924}
@@ -2105,27 +2104,28 @@ again: do { @@ -2105,27 +2104,28 @@ again: do {
2105 } 2104 }
2106 2105
2107 /* 2106 /*
2108 * If we're out of space, disable receive interrupts 2107 * If we're out of space, disable receive interrupts
2109 * until the queue has drained a bit. 2108 * until the queue has drained a bit.
2110 */ 2109 */
2111 if (!cc) { 2110 if (!cc) {
2112 SET(sc->sc_rx_flags, RX_IBUF_OVERFLOWED); 2111 SET(sc->sc_rx_flags, RX_IBUF_OVERFLOWED);
2113#ifdef COM_PXA2X0 2112#ifdef COM_PXA2X0
2114 if (sc->sc_type == COM_TYPE_PXA2x0) 2113 if (sc->sc_type == COM_TYPE_PXA2x0)
2115 CLR(sc->sc_ier, IER_ERXRDY|IER_ERXTOUT); 2114 CLR(sc->sc_ier, IER_ERXRDY|IER_ERXTOUT);
2116 else 2115 else
2117#endif 2116#endif
2118 if (sc->sc_type == COM_TYPE_INGENIC) 2117 if (sc->sc_type == COM_TYPE_INGENIC ||
 2118 sc->sc_type == COM_TYPE_TEGRA)
2119 CLR(sc->sc_ier, 2119 CLR(sc->sc_ier,
2120 IER_ERXRDY | IER_ERXTOUT); 2120 IER_ERXRDY | IER_ERXTOUT);
2121 else  2121 else
2122 CLR(sc->sc_ier, IER_ERXRDY); 2122 CLR(sc->sc_ier, IER_ERXRDY);
2123 CSR_WRITE_1(regsp, COM_REG_IER, sc->sc_ier); 2123 CSR_WRITE_1(regsp, COM_REG_IER, sc->sc_ier);
2124 } 2124 }
2125 } else { 2125 } else {
2126 if ((iir & (IIR_RXRDY|IIR_TXRDY)) == IIR_RXRDY) { 2126 if ((iir & (IIR_RXRDY|IIR_TXRDY)) == IIR_RXRDY) {
2127 (void) CSR_READ_1(regsp, COM_REG_RXDATA); 2127 (void) CSR_READ_1(regsp, COM_REG_RXDATA);
2128 continue; 2128 continue;
2129 } 2129 }
2130 } 2130 }
2131 2131