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 <jmcne...@invisible.ca>
@@ -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?

Reply via email to