diff options
Diffstat (limited to 'sys/dev/sio/sio.c')
-rw-r--r-- | sys/dev/sio/sio.c | 34 |
1 files changed, 33 insertions, 1 deletions
diff --git a/sys/dev/sio/sio.c b/sys/dev/sio/sio.c index f5e7363..dcfd46a 100644 --- a/sys/dev/sio/sio.c +++ b/sys/dev/sio/sio.c @@ -120,6 +120,7 @@ #define COM_C_IIR_TXRDYBUG (0x80000) #define COM_IIR_TXRDYBUG(flags) ((flags) & COM_C_IIR_TXRDYBUG) #define COM_NOSCR(flags) ((flags) & 0x100000) +#define COM_TI16754(flags) ((flags) & 0x200000) #define COM_FIFOSIZE(flags) (((flags) & 0xff000000) >> 24) #define sio_getreg(com, off) \ @@ -605,6 +606,33 @@ sioprobe(dev, xrid, rclk, noprobe) /* EXTRA DELAY? */ /* + * For the TI16754 chips set prescaler to 1 (4 is often the + * default after-reset value), otherwise it's impossible to + * get highest baudrates. + */ + if (COM_TI16754(flags)) { + u_char t1, t2; + + /* Save LCR */ + t1 = sio_getreg(com, com_lctl); + /* Enable EFR */ + sio_setreg(com, com_lctl, 0xbf); + /* Save EFR */ + t2 = sio_getreg(com, com_iir); + /* Unlock MCR[7] */ + sio_setreg(com, com_iir, t2 | 0x10); + /* Disable EFR */ + sio_setreg(com, com_lctl, 0); + /* Set prescaler to 1 */ + sio_setreg(com, com_mcr, sio_getreg(com, com_mcr) & 0x7f); + /* Enable EFR */ + sio_setreg(com, com_lctl, 0xbf); + /* Restore EFR */ + sio_setreg(com, com_iir, t2); + /* Restore LCR */ + sio_setreg(com, com_lctl, t1); + } + /* * Initialize the speed and the word size and wait long enough to * drain the maximum of 16 bytes of junk in device output queues. * The speed is undefined after a master reset and must be set @@ -731,6 +759,7 @@ sioprobe(dev, xrid, rclk, noprobe) failures[0] = sio_getreg(com, com_cfcr) - CFCR_8BITS; failures[1] = sio_getreg(com, com_ier) - IER_ETXRDY; failures[2] = (sio_getreg(com, com_mcr) & 0x7f) - mcr_image; + failures[2] = sio_getreg(com, com_mcr) - mcr_image; DELAY(10000); /* Some internal modems need this time */ irqmap[1] = isa_irq_pending(); failures[4] = (sio_getreg(com, com_iir) & IIR_IMASK) - IIR_TXRDY; @@ -1007,6 +1036,9 @@ sioattach(dev, xrid, rclk) com->st16650a = 1; com->tx_fifo_size = 32; printf(" ST16650A"); + } else if (COM_TI16754(flags)) { + com->tx_fifo_size = 64; + printf(" TI16754"); } else { com->tx_fifo_size = COM_FIFOSIZE(flags); printf(" 16550A"); @@ -1019,7 +1051,7 @@ sioattach(dev, xrid, rclk) break; } #endif - if (!com->st16650a) { + if (!com->st16650a && !COM_TI16754(flags)) { if (!com->tx_fifo_size) com->tx_fifo_size = 16; else |