Module Name: src
Committed By: jmcneill
Date: Sun Oct 29 16:02:46 UTC 2017
Modified Files:
src/sys/arch/arm/sunxi: sunxi_musb.c
src/sys/arch/evbarm/conf: SUNXI
Log Message:
Create a custom bus space tag and use it to remap registers instead of
relying on options MOTG_ALLWINNER.
To generate a diff of this commit:
cvs rdiff -u -r1.1 -r1.2 src/sys/arch/arm/sunxi/sunxi_musb.c
cvs rdiff -u -r1.49 -r1.50 src/sys/arch/evbarm/conf/SUNXI
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/arch/arm/sunxi/sunxi_musb.c
diff -u src/sys/arch/arm/sunxi/sunxi_musb.c:1.1 src/sys/arch/arm/sunxi/sunxi_musb.c:1.2
--- src/sys/arch/arm/sunxi/sunxi_musb.c:1.1 Sat Sep 9 12:01:04 2017
+++ src/sys/arch/arm/sunxi/sunxi_musb.c Sun Oct 29 16:02:46 2017
@@ -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 <[email protected]>
@@ -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 @@ __KERNEL_RCSID(0, "$NetBSD: sunxi_musb.c
#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 @@ static const struct of_compat_data compa
{ 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 @@ sunxi_musb_match(device_t parent, cfdata
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 @@ sunxi_musb_attach(device_t parent, devic
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));
sc->sc_size = size;
- sc->sc_iot = faa->faa_bst;
- if (bus_space_map(sc->sc_iot, addr, size, 0, &sc->sc_ioh) != 0) {
+ sc->sc_iot = &msc->sc_bs;
+ if (bus_space_map(faa->faa_bst, addr, size, 0, &sc->sc_ioh) != 0) {
aprint_error(": couldn't map registers\n");
return;
}
Index: src/sys/arch/evbarm/conf/SUNXI
diff -u src/sys/arch/evbarm/conf/SUNXI:1.49 src/sys/arch/evbarm/conf/SUNXI:1.50
--- src/sys/arch/evbarm/conf/SUNXI:1.49 Sun Oct 29 15:00:00 2017
+++ src/sys/arch/evbarm/conf/SUNXI Sun Oct 29 16:02:46 2017
@@ -1,5 +1,5 @@
#
-# $NetBSD: SUNXI,v 1.49 2017/10/29 15:00:00 jmcneill Exp $
+# $NetBSD: SUNXI,v 1.50 2017/10/29 16:02:46 jmcneill Exp $
#
# Allwinner sunxi family
#
@@ -239,7 +239,6 @@ sunxiusbphy* at fdt? pass 9 # USB PHY
ehci* at fdt? # EHCI
ohci* at fdt? # OHCI
motg* at fdt? # USB OTG
-options MOTG_ALLWINNER # XXX this should be a driver flag
usb* at ehci?
usb* at ohci?
usb* at motg?