summaryrefslogtreecommitdiff
path: root/sys/dev/fdt
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@cvs.openbsd.org>2019-10-16 22:11:18 +0000
committerMark Kettenis <kettenis@cvs.openbsd.org>2019-10-16 22:11:18 +0000
commitb224468d3aaa349217d8a5a61a48ed24ddbc9f21 (patch)
tree8a319d45cf6e50860f4830509d6a3f7bbddcf1bf /sys/dev/fdt
parent1d2f9e4bd5a0209d1018fbc909e1061fd572a6c0 (diff)
Move sxidog(4) such that we can use it on arm64.
ok patrick@
Diffstat (limited to 'sys/dev/fdt')
-rw-r--r--sys/dev/fdt/files.fdt6
-rw-r--r--sys/dev/fdt/sxidog.c174
2 files changed, 179 insertions, 1 deletions
diff --git a/sys/dev/fdt/files.fdt b/sys/dev/fdt/files.fdt
index 225c9805c84..b2f0edc584f 100644
--- a/sys/dev/fdt/files.fdt
+++ b/sys/dev/fdt/files.fdt
@@ -1,4 +1,4 @@
-# $OpenBSD: files.fdt,v 1.99 2019/10/13 17:21:25 kettenis Exp $
+# $OpenBSD: files.fdt,v 1.100 2019/10/16 22:11:17 kettenis Exp $
#
# Config file and device description for machine-independent FDT code.
# Included by ports that need it.
@@ -15,6 +15,10 @@ device sxiccmu
attach sxiccmu at fdt
file dev/fdt/sxiccmu.c sxiccmu
+device sxidog
+attach sxidog at fdt
+file dev/fdt/sxidog.c sxidog
+
device sxipio {}: gpiobus
attach sxipio at fdt
file dev/fdt/sxipio.c sxipio
diff --git a/sys/dev/fdt/sxidog.c b/sys/dev/fdt/sxidog.c
new file mode 100644
index 00000000000..50d78168b83
--- /dev/null
+++ b/sys/dev/fdt/sxidog.c
@@ -0,0 +1,174 @@
+/* $OpenBSD: sxidog.c,v 1.1 2019/10/16 22:11:17 kettenis Exp $ */
+/*
+ * Copyright (c) 2007,2009 Dale Rahn <drahn@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 <machine/bus.h>
+#include <machine/fdt.h>
+
+#include <armv7/armv7/armv7_machdep.h>
+#include <dev/fdt/sunxireg.h>
+
+#include <dev/ofw/openfirm.h>
+#include <dev/ofw/fdt.h>
+
+/* Allwinner A10 registers */
+#define WDOG_CTRL_REG 0x00
+#define WDOG_KEY (0x0a57 << 1)
+#define WDOG_RSTART 0x01
+#define WDOG_MODE_REG 0x04
+#define WDOG_EN (1 << 0)
+#define WDOG_RST_EN (1 << 1) /* system reset */
+#define WDOG_INTV_VALUE(x) ((x) << 3)
+
+/* Allwinner A31 registers */
+#define WDOG0_CTRL_REG 0x10
+#define WDOG0_KEY (0x0a57 << 1)
+#define WDOG0_RSTART (1 << 0)
+#define WDOG0_CFG_REG 0x14
+#define WDOG0_RST_EN (1 << 0)
+#define WDOG0_MODE_REG 0x18
+#define WDOG0_EN (1 << 0)
+#define WDOG0_INTV_VALUE(x) ((x) << 4)
+
+struct sxidog_softc {
+ struct device sc_dev;
+ bus_space_tag_t sc_iot;
+ bus_space_handle_t sc_ioh;
+ int sc_type;
+#define SXIDOG_A10 0
+#define SXIDOG_A31 1
+};
+
+struct sxidog_softc *sxidog_sc = NULL; /* for sxidog_reset() */
+
+int sxidog_match(struct device *, void *, void *);
+void sxidog_attach(struct device *, struct device *, void *);
+int sxidog_activate(struct device *, int);
+int sxidog_callback(void *, int);
+void sxidog_reset(void);
+
+struct cfattach sxidog_ca = {
+ sizeof (struct sxidog_softc), sxidog_match, sxidog_attach,
+ NULL, sxidog_activate
+};
+
+struct cfdriver sxidog_cd = {
+ NULL, "sxidog", DV_DULL
+};
+
+int
+sxidog_match(struct device *parent, void *match, void *aux)
+{
+ struct fdt_attach_args *faa = aux;
+
+ return (OF_is_compatible(faa->fa_node, "allwinner,sun4i-a10-wdt") ||
+ OF_is_compatible(faa->fa_node, "allwinner,sun6i-a31-wdt"));
+}
+
+void
+sxidog_attach(struct device *parent, struct device *self, void *aux)
+{
+ struct sxidog_softc *sc = (struct sxidog_softc *)self;
+ struct fdt_attach_args *faa = aux;
+
+ if (faa->fa_nreg < 1)
+ return;
+
+ 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("sxidog_attach: bus_space_map failed!");
+
+ if (OF_is_compatible(faa->fa_node, "allwinner,sun6i-a31-wdt")) {
+ SXIWRITE4(sc, WDOG0_CFG_REG, WDOG0_RST_EN);
+ sc->sc_type = SXIDOG_A31;
+ } else
+ sc->sc_type = SXIDOG_A10;
+
+ sxidog_sc = sc;
+ cpuresetfn = sxidog_reset;
+
+#ifndef SMALL_KERNEL
+ wdog_register(sxidog_callback, sc);
+#endif
+
+ printf("\n");
+}
+
+int
+sxidog_activate(struct device *self, int act)
+{
+ switch (act) {
+ case DVACT_POWERDOWN:
+#ifndef SMALL_KERNEL
+ wdog_shutdown(self);
+#endif
+ break;
+ }
+
+ return (0);
+}
+
+int
+sxidog_callback(void *arg, int period)
+{
+ struct sxidog_softc *sc = (struct sxidog_softc *)arg;
+ int enable;
+
+ if (period > 16)
+ period = 16;
+ else if (period < 0)
+ period = 0;
+
+ /* Convert to register encoding. */
+ if (period > 6)
+ period = 6 + (period - 5) / 2;
+
+ switch (sc->sc_type) {
+ case SXIDOG_A10:
+ enable = (period > 0) ? WDOG_RST_EN : 0;
+ SXIWRITE4(sc, WDOG_MODE_REG,
+ enable | WDOG_EN | WDOG_INTV_VALUE(period));
+ SXIWRITE4(sc, WDOG_CTRL_REG, WDOG_KEY | WDOG_RSTART);
+ break;
+ case SXIDOG_A31:
+ enable = (period > 0) ? WDOG0_EN : 0;
+ SXIWRITE4(sc, WDOG0_MODE_REG,
+ enable | WDOG0_INTV_VALUE(period));
+ SXIWRITE4(sc, WDOG0_CTRL_REG, WDOG0_KEY | WDOG0_RSTART);
+ break;
+ }
+
+ /* Convert back to seconds. */
+ if (period > 6)
+ period = 6 + (period - 6) * 2;
+
+ return period;
+}
+
+void
+sxidog_reset(void)
+{
+ if (sxidog_sc == NULL)
+ return;
+
+ sxidog_callback(sxidog_sc, 1);
+ delay(1500000);
+}