Source-Changes-HG archive

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

[src/trunk]: src/sys/arch Create a custom bus space tag and use it to remap r...



details:   https://anonhg.NetBSD.org/src/rev/f1a118fc812f
branches:  trunk
changeset: 827473:f1a118fc812f
user:      jmcneill <jmcneill%NetBSD.org@localhost>
date:      Sun Oct 29 16:02:46 2017 +0000

description:
Create a custom bus space tag and use it to remap registers instead of
relying on options MOTG_ALLWINNER.

diffstat:

 sys/arch/arm/sunxi/sunxi_musb.c |  252 ++++++++++++++++++++++++++++++++++++++-
 sys/arch/evbarm/conf/SUNXI      |    3 +-
 2 files changed, 244 insertions(+), 11 deletions(-)

diffs (truncated from 326 to 300 lines):

diff -r 2e0fa39e745c -r f1a118fc812f sys/arch/arm/sunxi/sunxi_musb.c
--- a/sys/arch/arm/sunxi/sunxi_musb.c   Sun Oct 29 15:29:34 2017 +0000
+++ b/sys/arch/arm/sunxi/sunxi_musb.c   Sun Oct 29 16:02:46 2017 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: sunxi_musb.c,v 1.1 2017/09/09 12:01:04 jmcneill Exp $ */
+/* $NetBSD: sunxi_musb.c,v 1.2 2017/10/29 16:02:46 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2017 Jared McNeill <jmcneill%invisible.ca@localhost>
@@ -26,8 +26,13 @@
  * SUCH DAMAGE.
  */
 
+#include "opt_motg.h"
+#ifdef MOTG_ALLWINNER
+# error Do not define MOTG_ALLWINNER when using this driver
+#endif
+
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: sunxi_musb.c,v 1.1 2017/09/09 12:01:04 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sunxi_musb.c,v 1.2 2017/10/29 16:02:46 jmcneill Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -41,18 +46,23 @@
 #include <dev/usb/usbdi.h>
 #include <dev/usb/usbdivar.h>
 #include <dev/usb/motgvar.h>
+#include <dev/usb/motgreg.h>
 
 #include <dev/fdt/fdtvar.h>
 
+#include <machine/bus_defs.h>
+
 #define        MUSB2_REG_AWIN_VEND0    0x43
-#define        MUSB2_REG_INTTX         0x44
-#define        MUSB2_REG_INTRX         0x46
-#define        MUSB2_REG_INTUSB        0x4c
 
 static int     sunxi_musb_match(device_t, cfdata_t, void *);
 static void    sunxi_musb_attach(device_t, device_t, void *);
 
-CFATTACH_DECL_NEW(sunxi_musb, sizeof(struct motg_softc),
+struct sunxi_musb_softc {
+       struct motg_softc       sc_otg;
+       struct bus_space        sc_bs;
+};
+
+CFATTACH_DECL_NEW(sunxi_musb, sizeof(struct sunxi_musb_softc),
        sunxi_musb_match, sunxi_musb_attach, NULL, NULL);
 
 static const struct of_compat_data compat_data[] = {
@@ -63,6 +73,217 @@
        { NULL }
 };
 
+#define        REMAPFLAG       0x8000
+#define        REGDECL(a, b)   [(a)] = ((b) | REMAPFLAG)
+
+/* Allwinner USB DRD register mappings */
+static const uint16_t sunxi_musb_regmap[] = {
+       REGDECL(MUSB2_REG_EPFIFO(0),    0x0000),
+       REGDECL(MUSB2_REG_EPFIFO(1),    0x0004),
+       REGDECL(MUSB2_REG_EPFIFO(2),    0x0008),
+       REGDECL(MUSB2_REG_EPFIFO(3),    0x000c),
+       REGDECL(MUSB2_REG_EPFIFO(4),    0x0010),
+       REGDECL(MUSB2_REG_EPFIFO(5),    0x0014),
+       REGDECL(MUSB2_REG_POWER,        0x0040),
+       REGDECL(MUSB2_REG_DEVCTL,       0x0041),
+       REGDECL(MUSB2_REG_EPINDEX,      0x0042),
+       REGDECL(MUSB2_REG_AWIN_VEND0,   0x0043),
+       REGDECL(MUSB2_REG_INTTX,        0x0044),
+       REGDECL(MUSB2_REG_INTRX,        0x0046),
+       REGDECL(MUSB2_REG_INTTXE,       0x0048),
+       REGDECL(MUSB2_REG_INTRXE,       0x004a),
+       REGDECL(MUSB2_REG_INTUSB,       0x004c),
+       REGDECL(MUSB2_REG_INTUSBE,      0x0050),
+       REGDECL(MUSB2_REG_FRAME,        0x0054),
+       REGDECL(MUSB2_REG_TESTMODE,     0x007c),
+       REGDECL(MUSB2_REG_TXMAXP,       0x0080),
+       REGDECL(MUSB2_REG_TXCSRL,       0x0082),
+       REGDECL(MUSB2_REG_TXCSRH,       0x0083),
+       REGDECL(MUSB2_REG_RXMAXP,       0x0084),
+       REGDECL(MUSB2_REG_RXCSRL,       0x0086),
+       REGDECL(MUSB2_REG_RXCSRH,       0x0087),
+       REGDECL(MUSB2_REG_RXCOUNT,      0x0088),
+       REGDECL(MUSB2_REG_TXTI,         0x008c),
+       REGDECL(MUSB2_REG_TXNAKLIMIT,   0x008d),
+       REGDECL(MUSB2_REG_RXNAKLIMIT,   0x008d),
+       REGDECL(MUSB2_REG_RXTI,         0x008e),
+       REGDECL(MUSB2_REG_TXFIFOSZ,     0x0090),
+       REGDECL(MUSB2_REG_TXFIFOADD,    0x0092),
+       REGDECL(MUSB2_REG_RXFIFOSZ,     0x0094),
+       REGDECL(MUSB2_REG_RXFIFOADD,    0x0096),
+       REGDECL(MUSB2_REG_FADDR,        0x0098),
+       REGDECL(MUSB2_REG_TXFADDR(0),   0x0098),
+       REGDECL(MUSB2_REG_TXHADDR(0),   0x009a),
+       REGDECL(MUSB2_REG_TXHUBPORT(0), 0x009b),
+       REGDECL(MUSB2_REG_RXFADDR(0),   0x009c),
+       REGDECL(MUSB2_REG_RXHADDR(0),   0x009e),
+       REGDECL(MUSB2_REG_RXHUBPORT(0), 0x009f),
+       REGDECL(MUSB2_REG_TXFADDR(1),   0x0098),
+       REGDECL(MUSB2_REG_TXHADDR(1),   0x009a),
+       REGDECL(MUSB2_REG_TXHUBPORT(1), 0x009b),
+       REGDECL(MUSB2_REG_RXFADDR(1),   0x009c),
+       REGDECL(MUSB2_REG_RXHADDR(1),   0x009e),
+       REGDECL(MUSB2_REG_RXHUBPORT(1), 0x009f),
+       REGDECL(MUSB2_REG_TXFADDR(2),   0x0098),
+       REGDECL(MUSB2_REG_TXHADDR(2),   0x009a),
+       REGDECL(MUSB2_REG_TXHUBPORT(2), 0x009b),
+       REGDECL(MUSB2_REG_RXFADDR(2),   0x009c),
+       REGDECL(MUSB2_REG_RXHADDR(2),   0x009e),
+       REGDECL(MUSB2_REG_RXHUBPORT(2), 0x009f),
+       REGDECL(MUSB2_REG_TXFADDR(3),   0x0098),
+       REGDECL(MUSB2_REG_TXHADDR(3),   0x009a),
+       REGDECL(MUSB2_REG_TXHUBPORT(3), 0x009b),
+       REGDECL(MUSB2_REG_RXFADDR(3),   0x009c),
+       REGDECL(MUSB2_REG_RXHADDR(3),   0x009e),
+       REGDECL(MUSB2_REG_RXHUBPORT(3), 0x009f),
+       REGDECL(MUSB2_REG_TXFADDR(4),   0x0098),
+       REGDECL(MUSB2_REG_TXHADDR(4),   0x009a),
+       REGDECL(MUSB2_REG_TXHUBPORT(4), 0x009b),
+       REGDECL(MUSB2_REG_RXFADDR(4),   0x009c),
+       REGDECL(MUSB2_REG_RXHADDR(4),   0x009e),
+       REGDECL(MUSB2_REG_RXHUBPORT(4), 0x009f),
+       REGDECL(MUSB2_REG_TXFADDR(5),   0x0098),
+       REGDECL(MUSB2_REG_TXHADDR(5),   0x009a),
+       REGDECL(MUSB2_REG_TXHUBPORT(5), 0x009b),
+       REGDECL(MUSB2_REG_RXFADDR(5),   0x009c),
+       REGDECL(MUSB2_REG_RXHADDR(5),   0x009e),
+       REGDECL(MUSB2_REG_RXHUBPORT(5), 0x009f),
+       REGDECL(MUSB2_REG_CONFDATA,     0x00c0),
+};
+
+static bus_size_t
+sunxi_musb_reg(bus_size_t o)
+{
+       bus_size_t v;
+
+       if (o >= __arraycount(sunxi_musb_regmap))
+               return o;
+
+       v = sunxi_musb_regmap[o];
+       KASSERTMSG((v & REMAPFLAG) != 0, "%s: reg %#lx not in regmap",
+           __func__, o);
+
+       return v & ~REMAPFLAG;
+}
+
+static int
+sunxi_musb_filt(bus_size_t o)
+{
+       switch (o) {
+       case MUSB2_REG_MISC:
+       case MUSB2_REG_RXDBDIS:
+       case MUSB2_REG_TXDBDIS:
+               return 1;
+       default:
+               return 0;
+       }
+}
+
+static uint8_t
+sunxi_musb_bs_r_1(void *t, bus_space_handle_t h, bus_size_t o)
+{
+       const struct bus_space *bs = t;
+       const struct bus_space *bs_parent = bs->bs_cookie;
+
+       switch (o) {
+       case MUSB2_REG_HWVERS:
+               return 0;       /* no known equivalent */
+       }
+
+       return bus_space_read_1(bs_parent, h, sunxi_musb_reg(o));
+}
+
+static uint16_t
+sunxi_musb_bs_r_2(void *t, bus_space_handle_t h, bus_size_t o)
+{
+       const struct bus_space *bs = t;
+       const struct bus_space *bs_parent = bs->bs_cookie;
+
+       return bus_space_read_2(bs_parent, h, sunxi_musb_reg(o));
+}
+
+static void
+sunxi_musb_bs_w_1(void *t, bus_space_handle_t h, bus_size_t o,
+    uint8_t v)
+{
+       const struct bus_space *bs = t;
+       const struct bus_space *bs_parent = bs->bs_cookie;
+
+       if (sunxi_musb_filt(o) != 0)
+               return;
+
+       bus_space_write_1(bs_parent, h, sunxi_musb_reg(o), v);
+}
+
+static void
+sunxi_musb_bs_w_2(void *t, bus_space_handle_t h, bus_size_t o,
+    uint16_t v)
+{
+       const struct bus_space *bs = t;
+       const struct bus_space *bs_parent = bs->bs_cookie;
+
+       if (sunxi_musb_filt(o) != 0)
+               return;
+
+       bus_space_write_2(bs_parent, h, sunxi_musb_reg(o), v);
+}
+
+static void
+sunxi_musb_bs_rm_1(void *t, bus_space_handle_t h, bus_size_t o,
+    uint8_t *d, bus_size_t c)
+{
+       const struct bus_space *bs = t;
+       const struct bus_space *bs_parent = bs->bs_cookie;
+
+       bus_space_read_multi_1(bs_parent, h, sunxi_musb_reg(o), d, c);
+}
+
+static void
+sunxi_musb_bs_rm_4(void *t, bus_space_handle_t h, bus_size_t o,
+    uint32_t *d, bus_size_t c)
+{
+       const struct bus_space *bs = t;
+       const struct bus_space *bs_parent = bs->bs_cookie;
+
+       bus_space_read_multi_4(bs_parent, h, sunxi_musb_reg(o), d, c);
+}
+
+static void
+sunxi_musb_bs_wm_1(void *t, bus_space_handle_t h, bus_size_t o,
+    const uint8_t *d, bus_size_t c)
+{
+       const struct bus_space *bs = t;
+       const struct bus_space *bs_parent = bs->bs_cookie;
+
+       if (sunxi_musb_filt(o) != 0)
+               return;
+
+       bus_space_write_multi_1(bs_parent, h, sunxi_musb_reg(o), d, c);
+}
+
+static void
+sunxi_musb_bs_wm_4(void *t, bus_space_handle_t h, bus_size_t o,
+    const uint32_t *d, bus_size_t c)
+{
+       const struct bus_space *bs = t;
+       const struct bus_space *bs_parent = bs->bs_cookie;
+
+       if (sunxi_musb_filt(o) != 0)
+               return;
+
+       bus_space_write_multi_4(bs_parent, h, sunxi_musb_reg(o), d, c);
+}
+
+static void
+sunxi_musb_bs_barrier(void *t, bus_space_handle_t h, bus_size_t o,
+    bus_size_t l, int f)
+{
+       const struct bus_space *bs = t;
+       const struct bus_space *bs_parent = bs->bs_cookie;
+
+       bus_space_barrier(bs_parent, h, o, l, f);
+}
+
 static int
 sunxi_musb_intr(void *priv)
 {
@@ -111,7 +332,8 @@
 static void
 sunxi_musb_attach(device_t parent, device_t self, void *aux)
 {
-       struct motg_softc * const sc = device_private(self);
+       struct sunxi_musb_softc * const msc = device_private(self);
+       struct motg_softc * const sc = &msc->sc_otg;
        struct fdt_attach_args * const faa = aux;
        const int phandle = faa->faa_phandle;
        struct fdtbus_reset *rst;
@@ -156,13 +378,25 @@
                return;
        }
 
+       /* Create custom bus space tag for remapping registers */
+       msc->sc_bs.bs_cookie = faa->faa_bst;
+       msc->sc_bs.bs_r_1 = sunxi_musb_bs_r_1;
+       msc->sc_bs.bs_r_2 = sunxi_musb_bs_r_2;
+       msc->sc_bs.bs_w_1 = sunxi_musb_bs_w_1;
+       msc->sc_bs.bs_w_2 = sunxi_musb_bs_w_2;
+       msc->sc_bs.bs_rm_1 = sunxi_musb_bs_rm_1;
+       msc->sc_bs.bs_rm_4 = sunxi_musb_bs_rm_4;
+       msc->sc_bs.bs_wm_1 = sunxi_musb_bs_wm_1;
+       msc->sc_bs.bs_wm_4 = sunxi_musb_bs_wm_4;
+       msc->sc_bs.bs_barrier = sunxi_musb_bs_barrier;
+
        sc->sc_dev = self;
        sc->sc_bus.ub_hcpriv = sc;
        sc->sc_bus.ub_dmatag = faa->faa_dmat;
        strlcpy(sc->sc_vendor, "Allwinner", sizeof(sc->sc_vendor));



Home | Main Index | Thread Index | Old Index