summaryrefslogtreecommitdiffstats
path: root/sys/dev/sio/sio.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/sio/sio.c')
-rw-r--r--sys/dev/sio/sio.c34
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
OpenPOWER on IntegriCloud