summaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
authorPatrick Wildt <patrick@cvs.openbsd.org>2019-04-01 08:40:38 +0000
committerPatrick Wildt <patrick@cvs.openbsd.org>2019-04-01 08:40:38 +0000
commit6817529b64f6f4aa8c950ed338d067dc510c5bf7 (patch)
treed54c973b88e1d83f146234f8ac68c2315c7f77db /sys/dev
parentbb50f1ac872ef7d8d4a1722f5fe8f6642f0af5d6 (diff)
In the upstreamed and official device tree for i.MX8MQ the power domains are
not separate nodes, but instead part of imxgpc(4). ok kettenis@
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/fdt/imxgpc.c49
1 files changed, 48 insertions, 1 deletions
diff --git a/sys/dev/fdt/imxgpc.c b/sys/dev/fdt/imxgpc.c
index 574113014af..ffff9ef5025 100644
--- a/sys/dev/fdt/imxgpc.c
+++ b/sys/dev/fdt/imxgpc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: imxgpc.c,v 1.4 2018/08/06 10:52:30 patrick Exp $ */
+/* $OpenBSD: imxgpc.c,v 1.5 2019/04/01 08:40:37 patrick Exp $ */
/*
* Copyright (c) 2016 Mark Kettenis
*
@@ -18,18 +18,30 @@
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/device.h>
+#include <sys/malloc.h>
+#if defined(__arm64__)
+#include <machine/cpufunc.h>
+#endif
#include <machine/fdt.h>
#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_power.h>
+
+#define FSL_SIP_GPC 0xc2000000
+#define FSL_SIP_CONFIG_GPC_PM_DOMAIN 0x03
struct imxgpc_softc {
struct device sc_dev;
struct interrupt_controller sc_ic;
+
+ int sc_npd;
+ struct power_domain_device *sc_pd;
};
int imxgpc_match(struct device *, void *, void *);
void imxgpc_attach(struct device *, struct device *, void *);
+void imxgpc_enable(void *, uint32_t *, int);
struct cfattach imxgpc_ca = {
sizeof(struct imxgpc_softc), imxgpc_match, imxgpc_attach
@@ -54,6 +66,7 @@ imxgpc_attach(struct device *parent, struct device *self, void *aux)
{
struct fdt_attach_args *faa = aux;
struct imxgpc_softc *sc = (struct imxgpc_softc *)self;
+ int i, node, list;
sc->sc_ic.ic_node = faa->fa_node;
sc->sc_ic.ic_cookie = &sc->sc_ic;
@@ -62,4 +75,38 @@ imxgpc_attach(struct device *parent, struct device *self, void *aux)
fdt_intr_register(&sc->sc_ic);
printf("\n");
+
+ if (OF_is_compatible(faa->fa_node, "fsl,imx8mq-gpc")) {
+ list = OF_child(faa->fa_node);
+ if (!list)
+ return;
+ for (node = OF_child(list); node; node = OF_peer(node))
+ sc->sc_npd++;
+ if (!sc->sc_npd)
+ return;
+ sc->sc_pd = mallocarray(sc->sc_npd, sizeof(*sc->sc_pd),
+ M_DEVBUF, M_WAITOK);
+ for (node = OF_child(list), i = 0; node;
+ node = OF_peer(node), i++){
+ sc->sc_pd[i].pd_node = node;
+ sc->sc_pd[i].pd_cookie = &sc->sc_pd[i];
+ sc->sc_pd[i].pd_enable = imxgpc_enable;
+ power_domain_register(&sc->sc_pd[i]);
+ }
+ }
+}
+
+void
+imxgpc_enable(void *cookie, uint32_t *cells, int on)
+{
+#if defined(__arm64__)
+ struct power_domain_device *pd = cookie;
+ int domain;
+
+ domain = OF_getpropint(pd->pd_node, "reg", 0);
+
+ /* Set up power domain */
+ smc_call(FSL_SIP_GPC, FSL_SIP_CONFIG_GPC_PM_DOMAIN,
+ domain, on);
+#endif
}