summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorpatrick <patrick@openbsd.org>2017-08-25 20:00:34 +0000
committerpatrick <patrick@openbsd.org>2017-08-25 20:00:34 +0000
commitad84f3865b9f46b70729e4c68659b694fd1a3d8f (patch)
tree612b91521c7d480d287986d556169871dbc82432
parentQuery the lower coordinate limits. (diff)
downloadwireguard-openbsd-ad84f3865b9f46b70729e4c68659b694fd1a3d8f.tar.xz
wireguard-openbsd-ad84f3865b9f46b70729e4c68659b694fd1a3d8f.zip
Add mvpinctrl(4), a driver to configure pins on Marvell SoCs. For now,
only the Armada 388 (SolidRun ClearFog, Turris Omnia) is supported. ok kettenis@
-rw-r--r--sys/arch/armv7/conf/GENERIC3
-rw-r--r--sys/arch/armv7/conf/RAMDISK3
-rw-r--r--sys/dev/fdt/files.fdt6
-rw-r--r--sys/dev/fdt/mvpinctrl.c182
4 files changed, 191 insertions, 3 deletions
diff --git a/sys/arch/armv7/conf/GENERIC b/sys/arch/armv7/conf/GENERIC
index 3df5045e810..08014408480 100644
--- a/sys/arch/armv7/conf/GENERIC
+++ b/sys/arch/armv7/conf/GENERIC
@@ -1,4 +1,4 @@
-# $OpenBSD: GENERIC,v 1.88 2017/08/14 21:46:02 ians Exp $
+# $OpenBSD: GENERIC,v 1.89 2017/08/25 20:00:34 patrick Exp $
#
# For further information on compiling OpenBSD kernels, see the config(8)
# man page.
@@ -152,6 +152,7 @@ mvmbus* at fdt?
mvxhci* at fdt?
usb* at mvxhci?
mvahci* at fdt?
+mvpinctrl* at fdt?
# Rockchip SoCs
rkclock* at fdt? early 1
diff --git a/sys/arch/armv7/conf/RAMDISK b/sys/arch/armv7/conf/RAMDISK
index 317c7af181e..7e3589cab51 100644
--- a/sys/arch/armv7/conf/RAMDISK
+++ b/sys/arch/armv7/conf/RAMDISK
@@ -1,4 +1,4 @@
-# $OpenBSD: RAMDISK,v 1.83 2017/07/25 20:39:12 kettenis Exp $
+# $OpenBSD: RAMDISK,v 1.84 2017/08/25 20:00:34 patrick Exp $
machine armv7 arm
@@ -146,6 +146,7 @@ mvmbus* at fdt?
mvxhci* at fdt?
usb* at mvxhci?
mvahci* at fdt?
+mvpinctrl* at fdt?
# Rockchip SoCs
rkclock* at fdt? early 1
diff --git a/sys/dev/fdt/files.fdt b/sys/dev/fdt/files.fdt
index cb2fd79d9b6..4e128d54187 100644
--- a/sys/dev/fdt/files.fdt
+++ b/sys/dev/fdt/files.fdt
@@ -1,4 +1,4 @@
-# $OpenBSD: files.fdt,v 1.22 2017/08/25 10:29:54 kettenis Exp $
+# $OpenBSD: files.fdt,v 1.23 2017/08/25 20:00:35 patrick Exp $
#
# Config file and device description for machine-independent FDT code.
# Included by ports that need it.
@@ -107,3 +107,7 @@ file dev/fdt/dwmmc.c dwmmc
device dwdog
attach dwdog at fdt
file dev/fdt/dwdog.c dwdog
+
+device mvpinctrl
+attach mvpinctrl at fdt
+file dev/fdt/mvpinctrl.c mvpinctrl
diff --git a/sys/dev/fdt/mvpinctrl.c b/sys/dev/fdt/mvpinctrl.c
new file mode 100644
index 00000000000..4e2e818ec26
--- /dev/null
+++ b/sys/dev/fdt/mvpinctrl.c
@@ -0,0 +1,182 @@
+/* $OpenBSD: mvpinctrl.c,v 1.1 2017/08/25 20:00:35 patrick Exp $ */
+/*
+ * Copyright (c) 2013,2016 Patrick Wildt <patrick@blueri.se>
+ * Copyright (c) 2016 Mark Kettenis <kettenis@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/device.h>
+#include <sys/malloc.h>
+
+#include <machine/intr.h>
+#include <machine/bus.h>
+#include <machine/fdt.h>
+
+#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_pinctrl.h>
+#include <dev/ofw/fdt.h>
+
+#define HREAD4(sc, reg) \
+ (bus_space_read_4((sc)->sc_iot, (sc)->sc_ioh, (reg)))
+#define HWRITE4(sc, reg, val) \
+ bus_space_write_4((sc)->sc_iot, (sc)->sc_ioh, (reg), (val))
+#define HSET4(sc, reg, bits) \
+ HWRITE4((sc), (reg), HREAD4((sc), (reg)) | (bits))
+#define HCLR4(sc, reg, bits) \
+ HWRITE4((sc), (reg), HREAD4((sc), (reg)) & ~(bits))
+
+struct mvpinctrl_pin {
+ char *pin;
+ char *function;
+ int value;
+ int pid;
+};
+
+struct mvpinctrl_softc {
+ struct device sc_dev;
+ bus_space_tag_t sc_iot;
+ bus_space_handle_t sc_ioh;
+ struct mvpinctrl_pin *sc_pins;
+ int sc_npins;
+};
+
+int mvpinctrl_match(struct device *, void *, void *);
+void mvpinctrl_attach(struct device *, struct device *, void *);
+int mvpinctrl_pinctrl(uint32_t, void *);
+
+struct cfattach mvpinctrl_ca = {
+ sizeof (struct mvpinctrl_softc), mvpinctrl_match, mvpinctrl_attach
+};
+
+struct cfdriver mvpinctrl_cd = {
+ NULL, "mvpinctrl", DV_DULL
+};
+
+#define STR_HELPER(x) #x
+#define STR(x) STR_HELPER(x)
+#define MPP(id, func, val) { STR(mpp ## id), func, val, id }
+
+struct mvpinctrl_pin mv88f6828_pins[] = {
+ MPP(4, "ge", 1),
+ MPP(5, "ge", 1),
+ MPP(6, "ge0", 1),
+ MPP(7, "ge0", 1),
+ MPP(8, "ge0", 1),
+ MPP(9, "ge0", 1),
+ MPP(10, "ge0", 1),
+ MPP(11, "ge0", 1),
+ MPP(12, "ge0", 1),
+ MPP(13, "ge0", 1),
+ MPP(14, "ge0", 1),
+ MPP(15, "ge0", 1),
+ MPP(16, "ge0", 1),
+ MPP(17, "ge0", 1),
+ MPP(20, "gpio", 0),
+ MPP(21, "sd0", 4),
+ MPP(23, "gpio", 0),
+ MPP(28, "sd0", 4),
+ MPP(37, "sd0", 4),
+ MPP(38, "sd0", 4),
+ MPP(39, "sd0", 4),
+ MPP(40, "sd0", 4),
+ MPP(41, "gpio", 0),
+ MPP(45, "ref", 1),
+ MPP(46, "ref", 1),
+};
+
+int
+mvpinctrl_match(struct device *parent, void *match, void *aux)
+{
+ struct fdt_attach_args *faa = aux;
+
+ return OF_is_compatible(faa->fa_node, "marvell,mv88f6828-pinctrl");
+}
+
+void
+mvpinctrl_attach(struct device *parent, struct device *self, void *aux)
+{
+ struct fdt_attach_args *faa = aux;
+ struct mvpinctrl_softc *sc = (struct mvpinctrl_softc *) self;
+
+ sc->sc_iot = faa->fa_iot;
+ if (bus_space_map(sc->sc_iot, faa->fa_reg[0].addr,
+ faa->fa_reg[0].size, 0, &sc->sc_ioh))
+ panic("mvpinctrl_attach: bus_space_map failed!");
+
+ sc->sc_pins = mv88f6828_pins;
+ sc->sc_npins = sizeof(mv88f6828_pins) / sizeof(struct mvpinctrl_pin);
+ pinctrl_register(faa->fa_node, mvpinctrl_pinctrl, sc);
+
+ printf("\n");
+}
+
+int
+mvpinctrl_pinctrl(uint32_t phandle, void *cookie)
+{
+ struct mvpinctrl_softc *sc = cookie;
+ char *pins, *pin, *func;
+ int i, flen, plen, node;
+
+ node = OF_getnodebyphandle(phandle);
+ if (node == 0)
+ return -1;
+
+ flen = OF_getproplen(node, "marvell,function");
+ if (flen <= 0)
+ return -1;
+
+ func = malloc(flen, M_TEMP, M_WAITOK);
+ OF_getprop(node, "marvell,function", func, flen);
+
+ plen = OF_getproplen(node, "marvell,pins");
+ if (plen <= 0)
+ return -1;
+
+ pin = pins = malloc(plen, M_TEMP, M_WAITOK);
+ OF_getprop(node, "marvell,pins", pins, plen);
+
+ while (plen > 0) {
+ int found = 0;
+
+ for (i = 0; i < sc->sc_npins; i++) {
+ uint32_t off, shift;
+
+ if (strcmp(sc->sc_pins[i].pin, pin))
+ continue;
+ if (strcmp(sc->sc_pins[i].function, func))
+ continue;
+
+ found++;
+
+ off = (sc->sc_pins[i].pid / 8) * sizeof(uint32_t);
+ shift = (sc->sc_pins[i].pid % 8) * 4;
+
+ HWRITE4(sc, off, (HREAD4(sc, off) & ~(0xf << shift)) |
+ (sc->sc_pins[i].value << shift));
+ }
+
+ if (found == 0)
+ printf("%s: unsupported pin %s function %s\n",
+ sc->sc_dev.dv_xname, pin, func);
+
+ plen -= strlen(pin) + 1;
+ pin += strlen(pin) + 1;
+ }
+
+ free(func, M_TEMP, flen);
+ free(pins, M_TEMP, plen);
+ return 0;
+}