diff options
| author | rkujawa <rkujawa@NetBSD.org> | 2013-04-20 11:52:40 +0000 |
|---|---|---|
| committer | rkujawa <rkujawa@NetBSD.org> | 2013-04-20 11:52:40 +0000 |
| commit | b60110e705ec304fb7b78abd1c4e7fbadd698665 (patch) | |
| tree | da3024e2a752625b3bba3320b1d590121142cc5c /sys/dev/ic/com.c | |
| parent | ec1fc9525168a8def5e67ecc8383c8b15f29ee69 (diff) | |
Add support for 16750 style UARTs. Activated by defining COM_16750.
Obtained from Marvell, Semihalf.
Diffstat (limited to 'sys/dev/ic/com.c')
| -rw-r--r-- | sys/dev/ic/com.c | 50 |
1 files changed, 47 insertions, 3 deletions
diff --git a/sys/dev/ic/com.c b/sys/dev/ic/com.c index 0124650712b..8b2478169a1 100644 --- a/sys/dev/ic/com.c +++ b/sys/dev/ic/com.c @@ -1,4 +1,4 @@ -/* $NetBSD: com.c,v 1.308 2013/02/24 06:21:36 matt Exp $ */ +/* $NetBSD: com.c,v 1.309 2013/04/20 11:52:40 rkujawa Exp $ */ /*- * Copyright (c) 1998, 1999, 2004, 2008 The NetBSD Foundation, Inc. @@ -66,7 +66,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: com.c,v 1.308 2013/02/24 06:21:36 matt Exp $"); +__KERNEL_RCSID(0, "$NetBSD: com.c,v 1.309 2013/04/20 11:52:40 rkujawa Exp $"); #include "opt_com.h" #include "opt_ddb.h" @@ -246,8 +246,17 @@ void com_kgdb_putc(void *, int); #define COM_REG_16550 { \ com_data, com_data, com_dlbl, com_dlbh, com_ier, com_iir, com_fifo, \ com_efr, com_lcr, com_mcr, com_lsr, com_msr } - +/* 16750-specific register set, additional UART status register */ +#define COM_REG_16750 { \ + com_data, com_data, com_dlbl, com_dlbh, com_ier, com_iir, com_fifo, \ + com_efr, com_lcr, com_mcr, com_lsr, com_msr, 0, 0, 0, 0, 0, 0, 0, 0, \ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, com_usr } + +#ifdef COM_16750 +const bus_size_t com_std_map[32] = COM_REG_16750; +#else const bus_size_t com_std_map[16] = COM_REG_16550; +#endif /* COM_16750 */ #endif /* COM_REGMAP */ #define COMUNIT_MASK 0x7ffff @@ -1466,6 +1475,20 @@ com_iflush(struct com_softc *sc) if (!timo) aprint_error_dev(sc->sc_dev, "com_iflush timeout %02x\n", reg); #endif + +#ifdef COM_16750 + uint8_t fifo; + /* + * Reset all Rx/Tx FIFO, preserve current FIFO length. + * This should prevent triggering busy interrupt while + * manipulating divisors. + */ + fifo = CSR_READ_1(regsp, COM_REG_FIFO) & (FIFO_TRIGGER_1 | + FIFO_TRIGGER_4 | FIFO_TRIGGER_8 | FIFO_TRIGGER_14); + CSR_WRITE_1(regsp, COM_REG_FIFO, fifo | FIFO_ENABLE | FIFO_RCV_RST | + FIFO_XMT_RST); + delay(100); +#endif } void @@ -1892,6 +1915,27 @@ comintr(void *arg) mutex_spin_enter(&sc->sc_lock); iir = CSR_READ_1(regsp, COM_REG_IIR); + + /* Handle ns16750-specific busy interrupt. */ +#ifdef COM_16750 + int timeout; + if ((iir & IIR_BUSY) == IIR_BUSY) { + for (timeout = 10000; + (CSR_READ_1(regsp, COM_REG_USR) & 0x1) != 0; timeout--) + if (timeout <= 0) { + aprint_error_dev(sc->sc_dev, + "timeout while waiting for BUSY interrupt " + "acknowledge\n"); + mutex_spin_exit(&sc->sc_lock); + return (0); + } + + CSR_WRITE_1(regsp, COM_REG_LCR, sc->sc_lcr); + iir = CSR_READ_1(regsp, COM_REG_IIR); + } +#endif /* COM_16750 */ + + if (ISSET(iir, IIR_NOPEND)) { mutex_spin_exit(&sc->sc_lock); return (0); |
