gemini lake gpio

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

gemini lake gpio

James Hastings
New driver for Gemini Lake GPIO controller.

Nearly identical to Apollo Lake with few changes.
Pad configuration is now 16 bytes starting at offset 0x600.

Index: share/man/man4/Makefile
===================================================================
RCS file: /cvs/src/share/man/man4/Makefile,v
retrieving revision 1.714
diff -u -p -u -r1.714 Makefile
--- share/man/man4/Makefile 17 Jun 2019 18:28:17 -0000 1.714
+++ share/man/man4/Makefile 22 Jun 2019 08:49:36 -0000
@@ -27,7 +27,8 @@ MAN= aac.4 abcrtc.4 ac97.4 acphy.4 acrtc
  eso.4 ess.4 et.4 etherip.4 etphy.4 ex.4 exphy.4 exrtc.4 \
  fanpwr.4 fd.4 fdc.4 fec.4 fins.4 fintek.4 fms.4 fusbtc.4 fuse.4 \
  fxp.4 gdt.4 gentbi.4 gem.4 gif.4 \
- glenv.4 gpio.4 gpiodcf.4 gpioiic.4 gpioow.4 gpr.4 gre.4 gscsio.4 \
+ glenv.4 glkgpio.4 gpio.4 gpiodcf.4 gpioiic.4 gpioow.4 \
+ gpr.4 gre.4 gscsio.4 \
  hds.4 hiclock.4 hidwusb.4 hifn.4 hil.4 hilid.4 hilkbd.4 hilms.4 \
  hireset.4 hitemp.4 hme.4 hotplug.4 hsq.4 \
  hvn.4 hvs.4 hyperv.4 \
Index: share/man/man4/acpi.4
===================================================================
RCS file: /cvs/src/share/man/man4/acpi.4,v
retrieving revision 1.58
diff -u -p -u -r1.58 acpi.4
--- share/man/man4/acpi.4 17 Jun 2019 18:28:17 -0000 1.58
+++ share/man/man4/acpi.4 22 Jun 2019 08:49:36 -0000
@@ -100,6 +100,8 @@ AMD cryptographic co-processor
 Intel Cherry View GPIO controller
 .It Xr dwiic 4
 Synopsys DesignWare I2C controller
+.It Xr glkgpio 4
+Intel Gemini Lake GPIO controller
 .It Xr tpm 4
 Trusted Platform Module device
 .El
Index: share/man/man4/glkgpio.4
===================================================================
RCS file: share/man/man4/glkgpio.4
diff -N share/man/man4/glkgpio.4
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ share/man/man4/glkgpio.4 22 Jun 2019 08:49:36 -0000
@@ -0,0 +1,50 @@
+.\" $OpenBSD$
+.\"
+.\" Copyright (c) 2019 James Hastings
+.\"
+.\" 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.
+.\"
+.Dd $Mdocdate$
+.Dt GLKGPIO 4
+.Os
+.Sh NAME
+.Nm glkgpio
+.Nd Intel Gemini Lake GPIO controller
+.Sh SYNOPSIS
+.Cd "glkgpio* at acpi?"
+.Sh DESCRIPTION
+The
+.Nm
+driver provides support for the GPIO controllers found on Intel's Gemini
+Lake SoC.
+It does not provide direct device driver entry points but makes its
+functions available to
+.Xr acpi 4 .
+.Sh SEE ALSO
+.Xr acpi 4 ,
+.Xr intro 4
+.Sh HISTORY
+The
+.Nm
+driver first appeared in
+.Ox 6.6 .
+.Sh AUTHORS
+.An -nosplit
+The
+.Nm
+driver was written by
+.An James Hastings
+based on the
+.Xr bytgpio 4
+driver by
+.An Mark Kettenis Aq Mt [hidden email] .
Index: sys/arch/amd64/conf/GENERIC
===================================================================
RCS file: /cvs/src/sys/arch/amd64/conf/GENERIC,v
retrieving revision 1.474
diff -u -p -u -r1.474 GENERIC
--- sys/arch/amd64/conf/GENERIC 17 Jun 2019 18:28:17 -0000 1.474
+++ sys/arch/amd64/conf/GENERIC 22 Jun 2019 08:49:37 -0000
@@ -64,6 +64,7 @@ aibs* at acpi?
 aplgpio* at acpi?
 bytgpio* at acpi?
 chvgpio* at acpi?
+glkgpio* at acpi?
 sdhc* at acpi?
 acpicbkbd* at acpi?
 acpials* at acpi?
Index: sys/arch/amd64/conf/RAMDISK_CD
===================================================================
RCS file: /cvs/src/sys/arch/amd64/conf/RAMDISK_CD,v
retrieving revision 1.180
diff -u -p -u -r1.180 RAMDISK_CD
--- sys/arch/amd64/conf/RAMDISK_CD 17 Jun 2019 18:28:18 -0000 1.180
+++ sys/arch/amd64/conf/RAMDISK_CD 22 Jun 2019 08:49:37 -0000
@@ -47,6 +47,7 @@ bytgpio* at acpi?
 sdhc* at acpi?
 acpihve* at acpi?
 chvgpio*        at acpi?
+glkgpio* at acpi?
 
 mpbios0 at bios0
 
Index: sys/dev/acpi/files.acpi
===================================================================
RCS file: /cvs/src/sys/dev/acpi/files.acpi,v
retrieving revision 1.51
diff -u -p -u -r1.51 files.acpi
--- sys/dev/acpi/files.acpi 17 Jun 2019 18:28:18 -0000 1.51
+++ sys/dev/acpi/files.acpi 22 Jun 2019 08:49:39 -0000
@@ -131,6 +131,11 @@ device chvgpio
 attach chvgpio at acpi
 file dev/acpi/chvgpio.c chvgpio
 
+# Intel Gemini Lake GPIO
+device glkgpio
+attach glkgpio at acpi
+file dev/acpi/glkgpio.c glkgpio
+
 # "Intel" Dollar Cove TI PMIC
 device tipmic
 attach tipmic at i2c
Index: sys/dev/acpi/glkgpio.c
===================================================================
RCS file: sys/dev/acpi/glkgpio.c
diff -N sys/dev/acpi/glkgpio.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ sys/dev/acpi/glkgpio.c 22 Jun 2019 08:49:39 -0000
@@ -0,0 +1,304 @@
+/* $OpenBSD$ */
+/*
+ * Copyright (c) 2016 Mark Kettenis
+ * Copyright (c) 2019 James Hastings
+ *
+ * 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/malloc.h>
+#include <sys/systm.h>
+
+#include <dev/acpi/acpireg.h>
+#include <dev/acpi/acpivar.h>
+#include <dev/acpi/acpidev.h>
+#include <dev/acpi/amltypes.h>
+#include <dev/acpi/dsdt.h>
+
+#define GLKGPIO_CONF_TXSTATE 0x00000001
+#define GLKGPIO_CONF_RXSTATE 0x00000002
+#define GLKGPIO_CONF_RXINV 0x00800000
+#define GLKGPIO_CONF_RXEV_EDGE 0x02000000
+#define GLKGPIO_CONF_RXEV_ZERO 0x04000000
+#define GLKGPIO_CONF_RXEV_MASK 0x06000000
+
+#define GLKGPIO_IRQ_STS 0x100
+#define GLKGPIO_IRQ_EN 0x110
+#define GLKGPIO_PAD_CFG0 0x600
+
+struct glkgpio_intrhand {
+ int (*ih_func)(void *);
+ void *ih_arg;
+};
+
+struct glkgpio_softc {
+ struct device sc_dev;
+ struct acpi_softc *sc_acpi;
+ struct aml_node *sc_node;
+
+ bus_space_tag_t sc_memt;
+ bus_space_handle_t sc_memh;
+ bus_addr_t sc_addr;
+ bus_size_t sc_size;
+
+ int sc_irq;
+ int sc_irq_flags;
+ void *sc_ih;
+
+ int sc_npins;
+ struct glkgpio_intrhand *sc_pin_ih;
+
+ struct acpi_gpio sc_gpio;
+};
+
+int glkgpio_match(struct device *, void *, void *);
+void glkgpio_attach(struct device *, struct device *, void *);
+
+struct cfattach glkgpio_ca = {
+ sizeof(struct glkgpio_softc), glkgpio_match, glkgpio_attach
+};
+
+struct cfdriver glkgpio_cd = {
+ NULL, "glkgpio", DV_DULL
+};
+
+const char *glkgpio_hids[] = {
+ "INT3453",
+ NULL
+};
+
+int glkgpio_parse_resources(int, union acpi_resource *, void *);
+int glkgpio_read_pin(void *, int);
+void glkgpio_write_pin(void *, int, int);
+void glkgpio_intr_establish(void *, int, int, int (*)(), void *);
+int glkgpio_intr(void *);
+
+int
+glkgpio_match(struct device *parent, void *match, void *aux)
+{
+ struct acpi_attach_args *aaa = aux;
+ struct cfdata *cf = match;
+
+ return acpi_matchhids(aaa, glkgpio_hids, cf->cf_driver->cd_name);
+}
+
+void
+glkgpio_attach(struct device *parent, struct device *self, void *aux)
+{
+ struct acpi_attach_args *aaa = aux;
+ struct glkgpio_softc *sc = (struct glkgpio_softc *)self;
+ struct aml_value res;
+ int64_t uid;
+ int i;
+
+ sc->sc_acpi = (struct acpi_softc *)parent;
+ sc->sc_node = aaa->aaa_node;
+ printf(": %s", sc->sc_node->name);
+
+ if (aml_evalinteger(sc->sc_acpi, sc->sc_node, "_UID", 0, NULL, &uid)) {
+ printf(", can't find uid\n");
+ return;
+ }
+
+ printf(" uid %lld", uid);
+
+ switch (uid) {
+ case 1:
+ sc->sc_npins = 80;
+ break;
+ case 2:
+ sc->sc_npins = 80;
+ break;
+ case 3:
+ sc->sc_npins = 20;
+ break;
+ case 4:
+ sc->sc_npins = 35;
+ break;
+ default:
+ printf("\n");
+ return;
+ }
+
+ if (aml_evalname(sc->sc_acpi, sc->sc_node, "_CRS", 0, NULL, &res)) {
+ printf(", can't find registers\n");
+ return;
+ }
+
+ aml_parse_resource(&res, glkgpio_parse_resources, sc);
+ printf(" addr 0x%lx/0x%lx", sc->sc_addr, sc->sc_size);
+ if (sc->sc_addr == 0 || sc->sc_size == 0) {
+ printf("\n");
+ return;
+ }
+ aml_freevalue(&res);
+
+ sc->sc_pin_ih = mallocarray(sc->sc_npins, sizeof(*sc->sc_pin_ih),
+    M_DEVBUF, M_NOWAIT | M_ZERO);
+ if (sc->sc_pin_ih == NULL) {
+ printf("\n");
+ return;
+ }
+
+ printf(" irq %d", sc->sc_irq);
+
+ sc->sc_memt = aaa->aaa_memt;
+ if (bus_space_map(sc->sc_memt, sc->sc_addr, sc->sc_size, 0,
+    &sc->sc_memh)) {
+ printf(", can't map registers\n");
+ goto free;
+ }
+
+ sc->sc_ih = acpi_intr_establish(sc->sc_irq, sc->sc_irq_flags, IPL_BIO,
+    glkgpio_intr, sc, sc->sc_dev.dv_xname);
+ if (sc->sc_ih == NULL) {
+ printf(", can't establish interrupt\n");
+ goto unmap;
+ }
+
+ sc->sc_gpio.cookie = sc;
+ sc->sc_gpio.read_pin = glkgpio_read_pin;
+ sc->sc_gpio.write_pin = glkgpio_write_pin;
+ sc->sc_gpio.intr_establish = glkgpio_intr_establish;
+ sc->sc_node->gpio = &sc->sc_gpio;
+
+ /* Mask and clear all interrupts. */
+ for (i = 0; i < sc->sc_npins; i++) {
+ if (i % 32 == 0) {
+ bus_space_write_4(sc->sc_memt, sc->sc_memh,
+    GLKGPIO_IRQ_EN + (i / 32) * 4, 0x00000000);
+ bus_space_write_4(sc->sc_memt, sc->sc_memh,
+    GLKGPIO_IRQ_STS + (i / 32) * 4, 0xffffffff);
+ }
+ }
+
+ printf(", %d pins\n", sc->sc_npins);
+
+ acpi_register_gpio(sc->sc_acpi, sc->sc_node);
+ return;
+
+unmap:
+ bus_space_unmap(sc->sc_memt, sc->sc_memh, sc->sc_size);
+free:
+ free(sc->sc_pin_ih, M_DEVBUF, sc->sc_npins * sizeof(*sc->sc_pin_ih));
+}
+
+int
+glkgpio_parse_resources(int crsidx, union acpi_resource *crs, void *arg)
+{
+ struct glkgpio_softc *sc = arg;
+ int type = AML_CRSTYPE(crs);
+
+ switch (type) {
+ case LR_MEM32FIXED:
+ sc->sc_addr = crs->lr_m32fixed._bas;
+ sc->sc_size = crs->lr_m32fixed._len;
+ break;
+ case LR_EXTIRQ:
+ sc->sc_irq = crs->lr_extirq.irq[0];
+ sc->sc_irq_flags = crs->lr_extirq.flags;
+ break;
+ default:
+ printf(" type 0x%x\n", type);
+ break;
+ }
+
+ return 0;
+}
+
+int
+glkgpio_read_pin(void *cookie, int pin)
+{
+ struct glkgpio_softc *sc = cookie;
+ uint32_t reg;
+
+ reg = bus_space_read_4(sc->sc_memt, sc->sc_memh,
+    GLKGPIO_PAD_CFG0 + pin * 16);
+
+ return !!(reg & GLKGPIO_CONF_RXSTATE);
+}
+
+void
+glkgpio_write_pin(void *cookie, int pin, int value)
+{
+ struct glkgpio_softc *sc = cookie;
+ uint32_t reg;
+
+ reg = bus_space_read_4(sc->sc_memt, sc->sc_memh,
+    GLKGPIO_PAD_CFG0 + pin * 16);
+ if (value)
+ reg |= GLKGPIO_CONF_TXSTATE;
+ else
+ reg &= ~GLKGPIO_CONF_TXSTATE;
+ bus_space_write_4(sc->sc_memt, sc->sc_memh,
+    GLKGPIO_PAD_CFG0 + pin * 16, reg);
+}
+
+void
+glkgpio_intr_establish(void *cookie, int pin, int flags,
+    int (*func)(void *), void *arg)
+{
+ struct glkgpio_softc *sc = cookie;
+ uint32_t reg;
+
+ KASSERT(pin >= 0 && pin < sc->sc_npins);
+
+ sc->sc_pin_ih[pin].ih_func = func;
+ sc->sc_pin_ih[pin].ih_arg = arg;
+
+ reg = bus_space_read_4(sc->sc_memt, sc->sc_memh,
+    GLKGPIO_PAD_CFG0 + pin * 16);
+ reg &= ~(GLKGPIO_CONF_RXEV_MASK | GLKGPIO_CONF_RXINV);
+ if ((flags & LR_GPIO_MODE) == 1)
+ reg |= GLKGPIO_CONF_RXEV_EDGE;
+ if ((flags & LR_GPIO_POLARITY) == LR_GPIO_ACTLO)
+ reg |= GLKGPIO_CONF_RXINV;
+ if ((flags & LR_GPIO_POLARITY) == LR_GPIO_ACTBOTH)
+ reg |= GLKGPIO_CONF_RXEV_EDGE | GLKGPIO_CONF_RXEV_ZERO;
+ bus_space_write_4(sc->sc_memt, sc->sc_memh,
+    GLKGPIO_PAD_CFG0 + pin * 16, reg);
+
+ reg = bus_space_read_4(sc->sc_memt, sc->sc_memh,
+    GLKGPIO_IRQ_EN + (pin / 32) * 4);
+ reg |= (1 << (pin % 32));
+ bus_space_write_4(sc->sc_memt, sc->sc_memh,
+    GLKGPIO_IRQ_EN + (pin / 32) * 4, reg);
+}
+
+int
+glkgpio_intr(void *arg)
+{
+ struct glkgpio_softc *sc = arg;
+ uint32_t status, enable;
+ int rc = 0;
+ int pin;
+
+ for (pin = 0; pin < sc->sc_npins; pin++) {
+ if (pin % 32 == 0) {
+ status = bus_space_read_4(sc->sc_memt, sc->sc_memh,
+    GLKGPIO_IRQ_STS + (pin / 32) * 4);
+ bus_space_write_4(sc->sc_memt, sc->sc_memh,
+    GLKGPIO_IRQ_STS + (pin / 32) * 4, status);
+ enable = bus_space_read_4(sc->sc_memt, sc->sc_memh,
+    GLKGPIO_IRQ_EN + (pin / 32) * 4);
+ status &= enable;
+ }
+ if (status & (1 << (pin % 32))) {
+ if (sc->sc_pin_ih[pin].ih_func)
+ sc->sc_pin_ih[pin].ih_func(sc->sc_pin_ih[pin].ih_arg);
+ rc = 1;
+ }
+ }
+ return rc;
+}

Reply | Threaded
Open this post in threaded view
|

Re: gemini lake gpio

Mark Kettenis
> From: James Hastings <[hidden email]>
> Date: Sun, 23 Jun 2019 17:15:57 -0400 (EDT)
>
> New driver for Gemini Lake GPIO controller.
>
> Nearly identical to Apollo Lake with few changes.
> Pad configuration is now 16 bytes starting at offset 0x600.

Thanks!  I've committed the diff.  I'm going to look at your sdhc(4)
diffs as well ASAP.  I'd like to test those on a couple of machines
first though.

Cheers,

Mark

> Index: share/man/man4/Makefile
> ===================================================================
> RCS file: /cvs/src/share/man/man4/Makefile,v
> retrieving revision 1.714
> diff -u -p -u -r1.714 Makefile
> --- share/man/man4/Makefile 17 Jun 2019 18:28:17 -0000 1.714
> +++ share/man/man4/Makefile 22 Jun 2019 08:49:36 -0000
> @@ -27,7 +27,8 @@ MAN= aac.4 abcrtc.4 ac97.4 acphy.4 acrtc
>   eso.4 ess.4 et.4 etherip.4 etphy.4 ex.4 exphy.4 exrtc.4 \
>   fanpwr.4 fd.4 fdc.4 fec.4 fins.4 fintek.4 fms.4 fusbtc.4 fuse.4 \
>   fxp.4 gdt.4 gentbi.4 gem.4 gif.4 \
> - glenv.4 gpio.4 gpiodcf.4 gpioiic.4 gpioow.4 gpr.4 gre.4 gscsio.4 \
> + glenv.4 glkgpio.4 gpio.4 gpiodcf.4 gpioiic.4 gpioow.4 \
> + gpr.4 gre.4 gscsio.4 \
>   hds.4 hiclock.4 hidwusb.4 hifn.4 hil.4 hilid.4 hilkbd.4 hilms.4 \
>   hireset.4 hitemp.4 hme.4 hotplug.4 hsq.4 \
>   hvn.4 hvs.4 hyperv.4 \
> Index: share/man/man4/acpi.4
> ===================================================================
> RCS file: /cvs/src/share/man/man4/acpi.4,v
> retrieving revision 1.58
> diff -u -p -u -r1.58 acpi.4
> --- share/man/man4/acpi.4 17 Jun 2019 18:28:17 -0000 1.58
> +++ share/man/man4/acpi.4 22 Jun 2019 08:49:36 -0000
> @@ -100,6 +100,8 @@ AMD cryptographic co-processor
>  Intel Cherry View GPIO controller
>  .It Xr dwiic 4
>  Synopsys DesignWare I2C controller
> +.It Xr glkgpio 4
> +Intel Gemini Lake GPIO controller
>  .It Xr tpm 4
>  Trusted Platform Module device
>  .El
> Index: share/man/man4/glkgpio.4
> ===================================================================
> RCS file: share/man/man4/glkgpio.4
> diff -N share/man/man4/glkgpio.4
> --- /dev/null 1 Jan 1970 00:00:00 -0000
> +++ share/man/man4/glkgpio.4 22 Jun 2019 08:49:36 -0000
> @@ -0,0 +1,50 @@
> +.\" $OpenBSD$
> +.\"
> +.\" Copyright (c) 2019 James Hastings
> +.\"
> +.\" 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.
> +.\"
> +.Dd $Mdocdate$
> +.Dt GLKGPIO 4
> +.Os
> +.Sh NAME
> +.Nm glkgpio
> +.Nd Intel Gemini Lake GPIO controller
> +.Sh SYNOPSIS
> +.Cd "glkgpio* at acpi?"
> +.Sh DESCRIPTION
> +The
> +.Nm
> +driver provides support for the GPIO controllers found on Intel's Gemini
> +Lake SoC.
> +It does not provide direct device driver entry points but makes its
> +functions available to
> +.Xr acpi 4 .
> +.Sh SEE ALSO
> +.Xr acpi 4 ,
> +.Xr intro 4
> +.Sh HISTORY
> +The
> +.Nm
> +driver first appeared in
> +.Ox 6.6 .
> +.Sh AUTHORS
> +.An -nosplit
> +The
> +.Nm
> +driver was written by
> +.An James Hastings
> +based on the
> +.Xr bytgpio 4
> +driver by
> +.An Mark Kettenis Aq Mt [hidden email] .
> Index: sys/arch/amd64/conf/GENERIC
> ===================================================================
> RCS file: /cvs/src/sys/arch/amd64/conf/GENERIC,v
> retrieving revision 1.474
> diff -u -p -u -r1.474 GENERIC
> --- sys/arch/amd64/conf/GENERIC 17 Jun 2019 18:28:17 -0000 1.474
> +++ sys/arch/amd64/conf/GENERIC 22 Jun 2019 08:49:37 -0000
> @@ -64,6 +64,7 @@ aibs* at acpi?
>  aplgpio* at acpi?
>  bytgpio* at acpi?
>  chvgpio* at acpi?
> +glkgpio* at acpi?
>  sdhc* at acpi?
>  acpicbkbd* at acpi?
>  acpials* at acpi?
> Index: sys/arch/amd64/conf/RAMDISK_CD
> ===================================================================
> RCS file: /cvs/src/sys/arch/amd64/conf/RAMDISK_CD,v
> retrieving revision 1.180
> diff -u -p -u -r1.180 RAMDISK_CD
> --- sys/arch/amd64/conf/RAMDISK_CD 17 Jun 2019 18:28:18 -0000 1.180
> +++ sys/arch/amd64/conf/RAMDISK_CD 22 Jun 2019 08:49:37 -0000
> @@ -47,6 +47,7 @@ bytgpio* at acpi?
>  sdhc* at acpi?
>  acpihve* at acpi?
>  chvgpio*        at acpi?
> +glkgpio* at acpi?
>  
>  mpbios0 at bios0
>  
> Index: sys/dev/acpi/files.acpi
> ===================================================================
> RCS file: /cvs/src/sys/dev/acpi/files.acpi,v
> retrieving revision 1.51
> diff -u -p -u -r1.51 files.acpi
> --- sys/dev/acpi/files.acpi 17 Jun 2019 18:28:18 -0000 1.51
> +++ sys/dev/acpi/files.acpi 22 Jun 2019 08:49:39 -0000
> @@ -131,6 +131,11 @@ device chvgpio
>  attach chvgpio at acpi
>  file dev/acpi/chvgpio.c chvgpio
>  
> +# Intel Gemini Lake GPIO
> +device glkgpio
> +attach glkgpio at acpi
> +file dev/acpi/glkgpio.c glkgpio
> +
>  # "Intel" Dollar Cove TI PMIC
>  device tipmic
>  attach tipmic at i2c
> Index: sys/dev/acpi/glkgpio.c
> ===================================================================
> RCS file: sys/dev/acpi/glkgpio.c
> diff -N sys/dev/acpi/glkgpio.c
> --- /dev/null 1 Jan 1970 00:00:00 -0000
> +++ sys/dev/acpi/glkgpio.c 22 Jun 2019 08:49:39 -0000
> @@ -0,0 +1,304 @@
> +/* $OpenBSD$ */
> +/*
> + * Copyright (c) 2016 Mark Kettenis
> + * Copyright (c) 2019 James Hastings
> + *
> + * 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/malloc.h>
> +#include <sys/systm.h>
> +
> +#include <dev/acpi/acpireg.h>
> +#include <dev/acpi/acpivar.h>
> +#include <dev/acpi/acpidev.h>
> +#include <dev/acpi/amltypes.h>
> +#include <dev/acpi/dsdt.h>
> +
> +#define GLKGPIO_CONF_TXSTATE 0x00000001
> +#define GLKGPIO_CONF_RXSTATE 0x00000002
> +#define GLKGPIO_CONF_RXINV 0x00800000
> +#define GLKGPIO_CONF_RXEV_EDGE 0x02000000
> +#define GLKGPIO_CONF_RXEV_ZERO 0x04000000
> +#define GLKGPIO_CONF_RXEV_MASK 0x06000000
> +
> +#define GLKGPIO_IRQ_STS 0x100
> +#define GLKGPIO_IRQ_EN 0x110
> +#define GLKGPIO_PAD_CFG0 0x600
> +
> +struct glkgpio_intrhand {
> + int (*ih_func)(void *);
> + void *ih_arg;
> +};
> +
> +struct glkgpio_softc {
> + struct device sc_dev;
> + struct acpi_softc *sc_acpi;
> + struct aml_node *sc_node;
> +
> + bus_space_tag_t sc_memt;
> + bus_space_handle_t sc_memh;
> + bus_addr_t sc_addr;
> + bus_size_t sc_size;
> +
> + int sc_irq;
> + int sc_irq_flags;
> + void *sc_ih;
> +
> + int sc_npins;
> + struct glkgpio_intrhand *sc_pin_ih;
> +
> + struct acpi_gpio sc_gpio;
> +};
> +
> +int glkgpio_match(struct device *, void *, void *);
> +void glkgpio_attach(struct device *, struct device *, void *);
> +
> +struct cfattach glkgpio_ca = {
> + sizeof(struct glkgpio_softc), glkgpio_match, glkgpio_attach
> +};
> +
> +struct cfdriver glkgpio_cd = {
> + NULL, "glkgpio", DV_DULL
> +};
> +
> +const char *glkgpio_hids[] = {
> + "INT3453",
> + NULL
> +};
> +
> +int glkgpio_parse_resources(int, union acpi_resource *, void *);
> +int glkgpio_read_pin(void *, int);
> +void glkgpio_write_pin(void *, int, int);
> +void glkgpio_intr_establish(void *, int, int, int (*)(), void *);
> +int glkgpio_intr(void *);
> +
> +int
> +glkgpio_match(struct device *parent, void *match, void *aux)
> +{
> + struct acpi_attach_args *aaa = aux;
> + struct cfdata *cf = match;
> +
> + return acpi_matchhids(aaa, glkgpio_hids, cf->cf_driver->cd_name);
> +}
> +
> +void
> +glkgpio_attach(struct device *parent, struct device *self, void *aux)
> +{
> + struct acpi_attach_args *aaa = aux;
> + struct glkgpio_softc *sc = (struct glkgpio_softc *)self;
> + struct aml_value res;
> + int64_t uid;
> + int i;
> +
> + sc->sc_acpi = (struct acpi_softc *)parent;
> + sc->sc_node = aaa->aaa_node;
> + printf(": %s", sc->sc_node->name);
> +
> + if (aml_evalinteger(sc->sc_acpi, sc->sc_node, "_UID", 0, NULL, &uid)) {
> + printf(", can't find uid\n");
> + return;
> + }
> +
> + printf(" uid %lld", uid);
> +
> + switch (uid) {
> + case 1:
> + sc->sc_npins = 80;
> + break;
> + case 2:
> + sc->sc_npins = 80;
> + break;
> + case 3:
> + sc->sc_npins = 20;
> + break;
> + case 4:
> + sc->sc_npins = 35;
> + break;
> + default:
> + printf("\n");
> + return;
> + }
> +
> + if (aml_evalname(sc->sc_acpi, sc->sc_node, "_CRS", 0, NULL, &res)) {
> + printf(", can't find registers\n");
> + return;
> + }
> +
> + aml_parse_resource(&res, glkgpio_parse_resources, sc);
> + printf(" addr 0x%lx/0x%lx", sc->sc_addr, sc->sc_size);
> + if (sc->sc_addr == 0 || sc->sc_size == 0) {
> + printf("\n");
> + return;
> + }
> + aml_freevalue(&res);
> +
> + sc->sc_pin_ih = mallocarray(sc->sc_npins, sizeof(*sc->sc_pin_ih),
> +    M_DEVBUF, M_NOWAIT | M_ZERO);
> + if (sc->sc_pin_ih == NULL) {
> + printf("\n");
> + return;
> + }
> +
> + printf(" irq %d", sc->sc_irq);
> +
> + sc->sc_memt = aaa->aaa_memt;
> + if (bus_space_map(sc->sc_memt, sc->sc_addr, sc->sc_size, 0,
> +    &sc->sc_memh)) {
> + printf(", can't map registers\n");
> + goto free;
> + }
> +
> + sc->sc_ih = acpi_intr_establish(sc->sc_irq, sc->sc_irq_flags, IPL_BIO,
> +    glkgpio_intr, sc, sc->sc_dev.dv_xname);
> + if (sc->sc_ih == NULL) {
> + printf(", can't establish interrupt\n");
> + goto unmap;
> + }
> +
> + sc->sc_gpio.cookie = sc;
> + sc->sc_gpio.read_pin = glkgpio_read_pin;
> + sc->sc_gpio.write_pin = glkgpio_write_pin;
> + sc->sc_gpio.intr_establish = glkgpio_intr_establish;
> + sc->sc_node->gpio = &sc->sc_gpio;
> +
> + /* Mask and clear all interrupts. */
> + for (i = 0; i < sc->sc_npins; i++) {
> + if (i % 32 == 0) {
> + bus_space_write_4(sc->sc_memt, sc->sc_memh,
> +    GLKGPIO_IRQ_EN + (i / 32) * 4, 0x00000000);
> + bus_space_write_4(sc->sc_memt, sc->sc_memh,
> +    GLKGPIO_IRQ_STS + (i / 32) * 4, 0xffffffff);
> + }
> + }
> +
> + printf(", %d pins\n", sc->sc_npins);
> +
> + acpi_register_gpio(sc->sc_acpi, sc->sc_node);
> + return;
> +
> +unmap:
> + bus_space_unmap(sc->sc_memt, sc->sc_memh, sc->sc_size);
> +free:
> + free(sc->sc_pin_ih, M_DEVBUF, sc->sc_npins * sizeof(*sc->sc_pin_ih));
> +}
> +
> +int
> +glkgpio_parse_resources(int crsidx, union acpi_resource *crs, void *arg)
> +{
> + struct glkgpio_softc *sc = arg;
> + int type = AML_CRSTYPE(crs);
> +
> + switch (type) {
> + case LR_MEM32FIXED:
> + sc->sc_addr = crs->lr_m32fixed._bas;
> + sc->sc_size = crs->lr_m32fixed._len;
> + break;
> + case LR_EXTIRQ:
> + sc->sc_irq = crs->lr_extirq.irq[0];
> + sc->sc_irq_flags = crs->lr_extirq.flags;
> + break;
> + default:
> + printf(" type 0x%x\n", type);
> + break;
> + }
> +
> + return 0;
> +}
> +
> +int
> +glkgpio_read_pin(void *cookie, int pin)
> +{
> + struct glkgpio_softc *sc = cookie;
> + uint32_t reg;
> +
> + reg = bus_space_read_4(sc->sc_memt, sc->sc_memh,
> +    GLKGPIO_PAD_CFG0 + pin * 16);
> +
> + return !!(reg & GLKGPIO_CONF_RXSTATE);
> +}
> +
> +void
> +glkgpio_write_pin(void *cookie, int pin, int value)
> +{
> + struct glkgpio_softc *sc = cookie;
> + uint32_t reg;
> +
> + reg = bus_space_read_4(sc->sc_memt, sc->sc_memh,
> +    GLKGPIO_PAD_CFG0 + pin * 16);
> + if (value)
> + reg |= GLKGPIO_CONF_TXSTATE;
> + else
> + reg &= ~GLKGPIO_CONF_TXSTATE;
> + bus_space_write_4(sc->sc_memt, sc->sc_memh,
> +    GLKGPIO_PAD_CFG0 + pin * 16, reg);
> +}
> +
> +void
> +glkgpio_intr_establish(void *cookie, int pin, int flags,
> +    int (*func)(void *), void *arg)
> +{
> + struct glkgpio_softc *sc = cookie;
> + uint32_t reg;
> +
> + KASSERT(pin >= 0 && pin < sc->sc_npins);
> +
> + sc->sc_pin_ih[pin].ih_func = func;
> + sc->sc_pin_ih[pin].ih_arg = arg;
> +
> + reg = bus_space_read_4(sc->sc_memt, sc->sc_memh,
> +    GLKGPIO_PAD_CFG0 + pin * 16);
> + reg &= ~(GLKGPIO_CONF_RXEV_MASK | GLKGPIO_CONF_RXINV);
> + if ((flags & LR_GPIO_MODE) == 1)
> + reg |= GLKGPIO_CONF_RXEV_EDGE;
> + if ((flags & LR_GPIO_POLARITY) == LR_GPIO_ACTLO)
> + reg |= GLKGPIO_CONF_RXINV;
> + if ((flags & LR_GPIO_POLARITY) == LR_GPIO_ACTBOTH)
> + reg |= GLKGPIO_CONF_RXEV_EDGE | GLKGPIO_CONF_RXEV_ZERO;
> + bus_space_write_4(sc->sc_memt, sc->sc_memh,
> +    GLKGPIO_PAD_CFG0 + pin * 16, reg);
> +
> + reg = bus_space_read_4(sc->sc_memt, sc->sc_memh,
> +    GLKGPIO_IRQ_EN + (pin / 32) * 4);
> + reg |= (1 << (pin % 32));
> + bus_space_write_4(sc->sc_memt, sc->sc_memh,
> +    GLKGPIO_IRQ_EN + (pin / 32) * 4, reg);
> +}
> +
> +int
> +glkgpio_intr(void *arg)
> +{
> + struct glkgpio_softc *sc = arg;
> + uint32_t status, enable;
> + int rc = 0;
> + int pin;
> +
> + for (pin = 0; pin < sc->sc_npins; pin++) {
> + if (pin % 32 == 0) {
> + status = bus_space_read_4(sc->sc_memt, sc->sc_memh,
> +    GLKGPIO_IRQ_STS + (pin / 32) * 4);
> + bus_space_write_4(sc->sc_memt, sc->sc_memh,
> +    GLKGPIO_IRQ_STS + (pin / 32) * 4, status);
> + enable = bus_space_read_4(sc->sc_memt, sc->sc_memh,
> +    GLKGPIO_IRQ_EN + (pin / 32) * 4);
> + status &= enable;
> + }
> + if (status & (1 << (pin % 32))) {
> + if (sc->sc_pin_ih[pin].ih_func)
> + sc->sc_pin_ih[pin].ih_func(sc->sc_pin_ih[pin].ih_arg);
> + rc = 1;
> + }
> + }
> + return rc;
> +}
>
>