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/0a48cc1af8d5
branches: trunk
changeset: 357172:0a48cc1af8d5
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 1c793480dd82 -r 0a48cc1af8d5 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