diff options
author | Patrick Wildt <patrick@cvs.openbsd.org> | 2019-04-01 08:40:38 +0000 |
---|---|---|
committer | Patrick Wildt <patrick@cvs.openbsd.org> | 2019-04-01 08:40:38 +0000 |
commit | 6817529b64f6f4aa8c950ed338d067dc510c5bf7 (patch) | |
tree | d54c973b88e1d83f146234f8ac68c2315c7f77db /sys/dev | |
parent | bb50f1ac872ef7d8d4a1722f5fe8f6642f0af5d6 (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.c | 49 |
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 } |