From: kettenis Date: Thu, 14 Jul 2022 19:06:29 +0000 (+0000) Subject: Add sxirintc(4), a driver for the "wake up" interrupt controller found X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=cb45c7e573b2e95edf879d1c8cf99aff8fd144b5;p=openbsd Add sxirintc(4), a driver for the "wake up" interrupt controller found on various Allwinner SoCs. ok anton@ --- diff --git a/sys/arch/arm64/conf/GENERIC b/sys/arch/arm64/conf/GENERIC index b7848aee9d5..10876ec302e 100644 --- a/sys/arch/arm64/conf/GENERIC +++ b/sys/arch/arm64/conf/GENERIC @@ -1,4 +1,4 @@ -# $OpenBSD: GENERIC,v 1.232 2022/07/13 09:28:18 kettenis Exp $ +# $OpenBSD: GENERIC,v 1.233 2022/07/14 19:06:29 kettenis Exp $ # # GENERIC machine description file # @@ -296,6 +296,7 @@ gpio* at sxipio? sxiccmu* at fdt? early 1 # Clock Control Module/Unit sxidog* at fdt? sxipwm* at fdt? +sxirintc* at fdt? sxirsb* at fdt? early 1 # Reduced Serial Bus axppmic* at rsb? sxirtc* at fdt? early 1 # Real Time Clock diff --git a/sys/dev/fdt/files.fdt b/sys/dev/fdt/files.fdt index ca24869c0f1..6a721edfa3e 100644 --- a/sys/dev/fdt/files.fdt +++ b/sys/dev/fdt/files.fdt @@ -1,4 +1,4 @@ -# $OpenBSD: files.fdt,v 1.163 2022/06/09 12:13:56 kettenis Exp $ +# $OpenBSD: files.fdt,v 1.164 2022/07/14 19:06:29 kettenis Exp $ # # Config file and device description for machine-independent FDT code. # Included by ports that need it. @@ -60,6 +60,10 @@ device sximmc: sdmmcbus attach sximmc at fdt file dev/fdt/sximmc.c sximmc +device sxirintc +attach sxirintc at fdt +file dev/fdt/sxirintc.c sxirintc + device sxisid attach sxisid at fdt file dev/fdt/sxisid.c sxisid diff --git a/sys/dev/fdt/sxirintc.c b/sys/dev/fdt/sxirintc.c new file mode 100644 index 00000000000..142b59db902 --- /dev/null +++ b/sys/dev/fdt/sxirintc.c @@ -0,0 +1,113 @@ +/* $OpenBSD: sxirintc.c,v 1.1 2022/07/14 19:06:29 kettenis Exp $ */ +/* + * Copyright (c) 2022 Mark Kettenis + * + * 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 +#include +#include + +#include +#include + +#include +#include + +#define RINTC_IRQ_PENDING 0x10 +#define RINTC_IRQ_ENABLE 0x40 +#define RINTC_IRQ_ENABLE_NMI (1 << 0) + +#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 sxirintc_softc { + struct device sc_dev; + bus_space_tag_t sc_iot; + bus_space_handle_t sc_ioh; +}; + +int sxirintc_match(struct device *, void *, void *); +void sxirintc_attach(struct device *, struct device *, void *); +int sxirintc_activate(struct device *, int); + +const struct cfattach sxirintc_ca = { + sizeof(struct sxirintc_softc), sxirintc_match, sxirintc_attach, + NULL, sxirintc_activate +}; + +struct cfdriver sxirintc_cd = { + NULL, "sxirintc", DV_DULL +}; + +int +sxirintc_match(struct device *parent, void *match, void *aux) +{ + struct fdt_attach_args *faa = aux; + + return OF_is_compatible(faa->fa_node, "allwinner,sun6i-a31-r-intc"); +} + +void +sxirintc_attach(struct device *parent, struct device *self, void *aux) +{ + struct sxirintc_softc *sc = (struct sxirintc_softc *)self; + struct fdt_attach_args *faa = aux; + + if (faa->fa_nreg < 1) { + printf(": no registers\n"); + 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)) { + printf(": can't map registers\n"); + return; + } + + printf("\n"); +} + +int +sxirintc_activate(struct device *self, int act) +{ + struct sxirintc_softc *sc = (struct sxirintc_softc *)self; + + /* + * Typically the "NMI" interrupt is controlled by the PMIC. + * This interrupt is routed in parallel to the GIC and the + * ARISC coprocessor. Enable this interrupt when we suspend + * such that the firmware running on the ARISC coprocessor can + * wake up the SoC when the PMIC triggers this interrupt. + */ + + switch (act) { + case DVACT_SUSPEND: + HWRITE4(sc, RINTC_IRQ_PENDING, ~0); + HSET4(sc, RINTC_IRQ_ENABLE, RINTC_IRQ_ENABLE_NMI); + break; + case DVACT_RESUME: + HCLR4(sc, RINTC_IRQ_ENABLE, RINTC_IRQ_ENABLE_NMI); + break; + } + + return 0; +}