Current-Users archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

com(4) 16750 vs ARMADAXP



Hi! ARMADAXP user and all,


I think that the support for com_16750 into which I was merged with
ARMADAXP is not related to 16750.
This is extended function included in ARMADAXP, and 16750 does not
include such a function.  I looked at the data sheet of TL16C750 and
SC16C750.
The data sheet of ARMADAXP don't describe compatible with 16750.  I
moved these ARMADAXP extended function to com_mv.c.
My OpenBlocksAX3 works fine.

Moreover, I added 64Byte FIFO support for TL16C750.
However, since I did not own this device, I was not able to check and
confirm.  I am going to commit attaching patch at next weekend.

The 16950 support before written by me further also plan to commit.
http://mail-index.netbsd.org/current-users/2010/03/01/msg012772.html

Thanks,
--
kiyohara

Index: ic/com.c
===================================================================
RCS file: /cvsroot/src/sys/dev/ic/com.c,v
retrieving revision 1.312
diff -u -r1.312 com.c
--- ic/com.c    27 Jul 2013 06:54:35 -0000      1.312
+++ ic/com.c    24 Aug 2013 05:39:38 -0000
@@ -246,17 +246,7 @@
 #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
@@ -416,10 +404,7 @@
                            (u_long)comcons_info.regs.cr_iobase);
                }
 
-#ifdef COM_16750
-               /* Use in comintr(). */
                sc->sc_lcr = cflag2lcr(comcons_info.cflag);
-#endif
 
                /* Make sure the console is always "hardwired". */
                delay(10000);                   /* wait for output to finish */
@@ -1479,19 +1498,19 @@
                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
+       if (sc->sc_type == COM_TYPE_ARMADAXP) {
+               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);
+       }
 }
 
 void
Index: ic/comreg.h
===================================================================
RCS file: /cvsroot/src/sys/dev/ic/comreg.h,v
retrieving revision 1.18
diff -u -r1.18 comreg.h
--- ic/comreg.h 20 Apr 2013 11:52:41 -0000      1.18
+++ ic/comreg.h 24 Aug 2013 05:39:38 -0000
@@ -56,15 +56,15 @@
 /* interrupt identification register */
 #define        IIR_IMASK       0xf
 #define        IIR_RXTOUT      0xc
+/* ARMADAXP's ns16550 ports have extra value in this register */
+#define IIR_BUSY       0x7     /* Busy indicator */
 #define        IIR_RLS         0x6     /* Line status change */
 #define        IIR_RXRDY       0x4     /* Receiver ready */
 #define        IIR_TXRDY       0x2     /* Transmitter ready */
 #define        IIR_MLSC        0x0     /* Modem status */
 #define        IIR_NOPEND      0x1     /* No pending interrupts */
+#define        IIR_64B_FIFO    0x20    /* 64byte FIFO Enabled (16750) */
 #define        IIR_FIFO_MASK   0xc0    /* set if FIFOs are enabled */
-#ifdef COM_16750
-#define IIR_BUSY       0x7     /* Busy indicator */
-#endif
 
 /* fifo control register */
 #define        FIFO_ENABLE     0x01    /* Turn the FIFO on */
@@ -72,6 +72,7 @@
 #define        FIFO_XMT_RST    0x04    /* Reset TX FIFO */
 #define        FIFO_DMA_MODE   0x08
 #define        FIFO_TRIGGER_1  0x00    /* Trigger RXRDY intr on 1 character */
+#define        FIFO_64B_ENABLE 0x20    /* 64byte FIFO Enable (16750) */
 #define        FIFO_TRIGGER_4  0x40    /* ibid 4 */
 #define        FIFO_TRIGGER_8  0x80    /* ibid 8 */
 #define        FIFO_TRIGGER_14 0xc0    /* ibid 14 */
Index: ic/comvar.h
===================================================================
RCS file: /cvsroot/src/sys/dev/ic/comvar.h,v
retrieving revision 1.75
diff -u -r1.75 comvar.h
--- ic/comvar.h 17 Jul 2013 19:51:56 -0000      1.75
+++ ic/comvar.h 24 Aug 2013 05:39:38 -0000
@@ -91,27 +91,16 @@
 #define        COM_REG_MCR             9
 #define        COM_REG_LSR             10
 #define        COM_REG_MSR             11
-#ifdef COM_16750
-#define        COM_REG_USR             31
-#endif
 
 struct com_regs {
        bus_space_tag_t         cr_iot;
        bus_space_handle_t      cr_ioh;
        bus_addr_t              cr_iobase;
        bus_size_t              cr_nports;
-#ifdef COM_16750
-       bus_size_t              cr_map[32];
-#else
        bus_size_t              cr_map[16];
-#endif
 };
 
-#ifdef COM_16750
-extern const bus_size_t com_std_map[32];
-#else
 extern const bus_size_t com_std_map[16];
-#endif
 
 #define        COM_INIT_REGS(regs, tag, hdl, addr)                             
\
        do {                                                            \
@@ -138,9 +127,6 @@
 #define        COM_REG_TCR             com_msr
 #define        COM_REG_TLR             com_scratch
 #define        COM_REG_MDR1            8
-#ifdef COM_16750
-#define COM_REG_USR            com_usr
-#endif
 
 struct com_regs {
        bus_space_tag_t         cr_iot;
@@ -233,6 +219,7 @@
 #define        COM_TYPE_AU1x00         3       /* AMD/Alchemy Au1x000 proc. 
built-in */
 #define        COM_TYPE_OMAP           4       /* TI OMAP processor built-in */
 #define        COM_TYPE_16550_NOERS    5       /* like a 16550, no ERS */
+#define        COM_TYPE_ARMADAXP       6       /* Marvell ARMADA XP proc. 
built-in */
 
        /* power management hooks */
        int (*enable)(struct com_softc *);
Index: ic/ns16550reg.h
===================================================================
RCS file: /cvsroot/src/sys/dev/ic/ns16550reg.h,v
retrieving revision 1.8
diff -u -r1.8 ns16550reg.h
--- ic/ns16550reg.h     20 Apr 2013 11:52:41 -0000      1.8
+++ ic/ns16550reg.h     24 Aug 2013 05:39:40 -0000
@@ -47,11 +47,3 @@
 #define        com_lsr         5       /* line status register (R/W) */
 #define        com_msr         6       /* modem status register (R/W) */
 #define        com_scratch     7       /* scratch register (R/W) */
-
-/*
- * Additional register present in NS16750 
- */
-#ifdef COM_16750
-#define com_usr                31      /* status register (R) */
-#endif
-
Index: marvell/com_mv.c
===================================================================
RCS file: /cvsroot/src/sys/dev/marvell/com_mv.c,v
retrieving revision 1.5
diff -u -r1.5 com_mv.c
--- marvell/com_mv.c    28 Jan 2011 16:12:22 -0000      1.5
+++ marvell/com_mv.c    24 Aug 2013 05:39:41 -0000
@@ -34,6 +34,7 @@
 #include <sys/bus.h>
 #include <sys/device.h>
 #include <sys/errno.h>
+#include <sys/mutex.h>
 #include <sys/termios.h>
 
 #include <dev/marvell/gtvar.h>
@@ -44,34 +45,56 @@
 
 #include <prop/proplib.h>
 
-#define MVUART_SIZE            0x20
+#define MVUART_SIZE            0x80
+
+#define MVUART_REG_USR         0x7c    /* XXXX: What is this??? */
 
 
 static int mvuart_match(device_t, struct cfdata *, void *);
 static void mvuart_attach(device_t, device_t, void *);
 
+static int mvuart_intr(void *);
+
 CFATTACH_DECL_NEW(mvuart_gt, sizeof(struct com_softc),
     mvuart_match, mvuart_attach, NULL, NULL);
 CFATTACH_DECL_NEW(mvuart_mbus, sizeof(struct com_softc),
     mvuart_match, mvuart_attach, NULL, NULL);
 
 #ifdef COM_REGMAP
-#define MVUART_INIT_REGS(regs, tag, hdl, addr, size)           \
-       do {                                                    \
-               int i;                                          \
-                                                               \
-               regs.cr_iot = tag;                              \
-               regs.cr_ioh = hdl;                              \
-               regs.cr_iobase = addr;                          \
-               regs.cr_nports = size;                          \
-               for (i = 0; i < __arraycount(regs.cr_map); i++) \
-                       regs.cr_map[i] = com_std_map[i] << 2;   \
+#define MVUART_INIT_REGS(regs, tag, hdl, addr, size)                   \
+       do {                                                            \
+               int _i;                                                 \
+                                                                       \
+               regs.cr_iot = tag;                                      \
+               regs.cr_ioh = hdl;                                      \
+               regs.cr_iobase = addr;                                  \
+               regs.cr_nports = size;                                  \
+               for (_i = 0; _i < __arraycount(regs.cr_map); _i++)      \
+                       regs.cr_map[_i] = com_std_map[_i] << 2;         \
        } while (0)
+#define CSR_WRITE_1(r, o, v)    \
+       bus_space_write_1((r)->cr_iot, (r)->cr_ioh, (r)->cr_map[o], v)
+#define CSR_READ_1(r, o)        \
+       bus_space_read_1((r)->cr_iot, (r)->cr_ioh, (r)->cr_map[o])
 #else
 #define MVUART_INIT_REGS(regs, tag, hdl, addr, size) \
        COM_INIT_REGS(regs, tag, hdl, addr)
+#define CSR_WRITE_1(r, o, v)    \
+        bus_space_write_1((r)->cr_iot, (r)->cr_ioh, o, v)
+#define CSR_READ_1(r, o)        \
+       bus_space_read_1((r)->cr_iot, (r)->cr_ioh, o)
 #endif
 
+struct {
+       int model;
+       int type;
+} mvuart_extensions[] = {
+       { MARVELL_ARMADAXP_MV78130,     COM_TYPE_ARMADAXP },
+       { MARVELL_ARMADAXP_MV78160,     COM_TYPE_ARMADAXP },
+       { MARVELL_ARMADAXP_MV78230,     COM_TYPE_ARMADAXP },
+       { MARVELL_ARMADAXP_MV78260,     COM_TYPE_ARMADAXP },
+       { MARVELL_ARMADAXP_MV78460,     COM_TYPE_ARMADAXP },
+};
 
 /* ARGSUSED */
 static int
@@ -111,6 +134,7 @@
        bus_space_tag_t iot;
        bus_space_handle_t ioh;
        prop_dictionary_t dict = device_properties(self);
+       int i;
 
        sc->sc_dev = self;
 
@@ -130,9 +154,59 @@
        MVUART_INIT_REGS(sc->sc_regs,
            iot, ioh, mva->mva_addr + mva->mva_offset, mva->mva_size);
 
+       for (i = 0; i < __arraycount(mvuart_extensions); i++)
+               if (mva->mva_model == mvuart_extensions[i].model) {
+                       sc->sc_type = mvuart_extensions[i].type;
+                       break;
+               }
+
        com_attach_subr(sc);
 
-       marvell_intr_establish(mva->mva_irq, IPL_SERIAL, comintr, sc);
+       if (sc->sc_type == COM_TYPE_ARMADAXP)
+               marvell_intr_establish(mva->mva_irq, IPL_SERIAL,
+                   mvuart_intr, sc);
+       else
+               marvell_intr_establish(mva->mva_irq, IPL_SERIAL, comintr, sc);
+}
+
+static int
+mvuart_intr(void *arg)
+{
+       struct com_softc *sc = arg;
+       struct com_regs *regsp = &sc->sc_regs;
+       int timeout;
+       uint8_t iir, v;
+
+       if (!device_is_active(sc->sc_dev))
+               return 0;
+
+       KASSERT(regsp != NULL);
+
+       mutex_spin_enter(&sc->sc_lock);
+       iir = CSR_READ_1(regsp, COM_REG_IIR);
+       if ((iir & IIR_BUSY) == IIR_BUSY) {
+               /*
+                * XXXXX: What is this?  I don't found in Marvell datasheet.
+                *        Maybe workaround for BUG in UART.
+                */
+               v = bus_space_read_1(regsp->cr_iot, regsp->cr_ioh,
+                   MVUART_REG_USR);
+               for (timeout = 10000; (v & 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;
+                       }
+                       v = bus_space_read_1(regsp->cr_iot, regsp->cr_ioh,
+                           MVUART_REG_USR);
+               }
+               CSR_WRITE_1(regsp, COM_REG_LCR, sc->sc_lcr);
+       }
+       mutex_spin_exit(&sc->sc_lock);
+
+       return comintr(arg);
 }
 
 #ifdef COM_REGMAP
Index: ic/com.c
===================================================================
RCS file: /cvsroot/src/sys/dev/ic/com.c,v
retrieving revision 1.312
diff -u -r1.312 com.c
--- ic/com.c    27 Jul 2013 06:54:35 -0000      1.312
+++ ic/com.c    24 Aug 2013 05:39:38 -0000
@@ -384,9 +374,7 @@
 {
        struct com_regs *regsp = &sc->sc_regs;
        struct tty *tp;
-#ifdef COM_16650
        u_int8_t lcr;
-#endif
        const char *fifo_msg = NULL;
        prop_dictionary_t       dict;
        bool is_console = true;
@@ -493,6 +478,37 @@
 #endif
                                sc->sc_fifolen = 16;
 
+                       /*
+                        * TL16C750 can enable 64byte FIFO, only when DLAB
+                        * is 1.  However, some 16750 may always enable.  For
+                        * example, restrictions according to DLAB in a data
+                        * sheet for SC16C750 were not described.
+                        * Please enable 'options COM_16650', supposing you
+                        * use SC16C750.  Probably 32 bytes of FIFO and HW FLOW
+                        * should become effective.
+                        */
+                       uint8_t iir1, iir2;
+                       const uint8_t fcr = FIFO_ENABLE | FIFO_TRIGGER_14;
+
+                       lcr = CSR_READ_1(regsp, COM_REG_LCR);
+                       CSR_WRITE_1(regsp, COM_REG_LCR, lcr & ~LCR_DLAB);
+                       CSR_WRITE_1(regsp, COM_REG_FIFO, fcr | FIFO_64B_ENABLE);
+                       iir1 = CSR_READ_1(regsp, COM_REG_IIR);
+                       CSR_WRITE_1(regsp, COM_REG_FIFO, fcr);
+                       CSR_WRITE_1(regsp, COM_REG_LCR, lcr | LCR_DLAB);
+                       CSR_WRITE_1(regsp, COM_REG_FIFO, fcr | FIFO_64B_ENABLE);
+                       iir2 = CSR_READ_1(regsp, COM_REG_IIR);
+
+                       CSR_WRITE_1(regsp, COM_REG_LCR, lcr);
+
+                       if (!ISSET(iir1, IIR_64B_FIFO) &&
+                           ISSET(iir2, IIR_64B_FIFO)) {
+                               /* It is TL16C750. */
+                               sc->sc_fifolen = 64;
+                               SET(sc->sc_hwflags, COM_HW_FLOW);
+                       } else
+                               CSR_WRITE_1(regsp, COM_REG_FIFO, fcr);
+
 #ifdef COM_16650
                        CSR_WRITE_1(regsp, COM_REG_LCR, lcr);
                        if (sc->sc_fifolen == 0)
@@ -501,6 +517,9 @@
                                fifo_msg = "st16650a, working fifo";
                        else
 #endif
+                       if (sc->sc_fifolen == 64)
+                               fifo_msg = "tl16c750, working fifo";
+                       else
                                fifo_msg = "ns16550a, working fifo";
                } else
                        fifo_msg = "ns16550, broken fifo";
@@ -1479,19 +1498,19 @@
                aprint_error_dev(sc->sc_dev, "com_iflush timeout %02x\n", reg);
 #endif
 
Index: ic/comreg.h
===================================================================
RCS file: /cvsroot/src/sys/dev/ic/comreg.h,v
retrieving revision 1.18
diff -u -r1.18 comreg.h
--- ic/comreg.h 20 Apr 2013 11:52:41 -0000      1.18
+++ ic/comreg.h 24 Aug 2013 05:39:38 -0000
@@ -63,6 +63,7 @@
 #define        IIR_TXRDY       0x2     /* Transmitter ready */
 #define        IIR_MLSC        0x0     /* Modem status */
 #define        IIR_NOPEND      0x1     /* No pending interrupts */
+#define        IIR_64B_FIFO    0x20    /* 64byte FIFO Enabled (16750) */
 #define        IIR_FIFO_MASK   0xc0    /* set if FIFOs are enabled */
 
@@ -72,6 +72,7 @@
 #define        FIFO_XMT_RST    0x04    /* Reset TX FIFO */
 #define        FIFO_DMA_MODE   0x08
 #define        FIFO_TRIGGER_1  0x00    /* Trigger RXRDY intr on 1 character */
+#define        FIFO_64B_ENABLE 0x20    /* 64byte FIFO Enable (16750) */
 #define        FIFO_TRIGGER_4  0x40    /* ibid 4 */
 #define        FIFO_TRIGGER_8  0x80    /* ibid 8 */
 #define        FIFO_TRIGGER_14 0xc0    /* ibid 14 */


Home | Main Index | Thread Index | Old Index