From 6817529b64f6f4aa8c950ed338d067dc510c5bf7 Mon Sep 17 00:00:00 2001 From: Patrick Wildt Date: Mon, 1 Apr 2019 08:40:38 +0000 Subject: 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@ --- sys/dev/fdt/imxgpc.c | 49 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-) (limited to 'sys') 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 #include #include +#include +#if defined(__arm64__) +#include +#endif #include #include +#include + +#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 } -- cgit v1.2.3