diff options
author | Mark Kettenis <kettenis@cvs.openbsd.org> | 2022-09-10 13:14:40 +0000 |
---|---|---|
committer | Mark Kettenis <kettenis@cvs.openbsd.org> | 2022-09-10 13:14:40 +0000 |
commit | 26b48406b1577bdb765633cb79ff9de4ef972e6b (patch) | |
tree | 31d9e64d177a9f43745060fb5bde7c90cb5de0ce /sys/dev | |
parent | 139db9828936b1eb0976f61423ec42ae78526597 (diff) |
Generalize the code such that it works on SC7180 SoCs as well.
ok mglocker@, patrick@
Diffstat (limited to 'sys/dev')
-rw-r--r-- | sys/dev/acpi/qcgpio.c | 75 |
1 files changed, 58 insertions, 17 deletions
diff --git a/sys/dev/acpi/qcgpio.c b/sys/dev/acpi/qcgpio.c index 3a606924884..532e89ab360 100644 --- a/sys/dev/acpi/qcgpio.c +++ b/sys/dev/acpi/qcgpio.c @@ -1,4 +1,4 @@ -/* $OpenBSD: qcgpio.c,v 1.2 2022/09/08 06:32:32 kettenis Exp $ */ +/* $OpenBSD: qcgpio.c,v 1.3 2022/09/10 13:14:39 kettenis Exp $ */ /* * Copyright (c) 2022 Mark Kettenis <kettenis@openbsd.org> * @@ -43,6 +43,11 @@ #define TLMM_GPIO_INTR_STATUS(pin) (0x000c + 0x1000 * (pin)) #define TLMM_GPIO_INTR_STATUS_INTR_STATUS (1 << 0) +/* SC7180 has multiple tiles */ +#define QCGPIO_SC7180_WEST 0x00100000 +#define QCGPIO_SC7180_NORTH 0x00500000 +#define QCGPIO_SC7180_SOUTH 0x00900000 + #define HREAD4(sc, reg) \ (bus_space_read_4((sc)->sc_iot, (sc)->sc_ioh, (reg))) #define HWRITE4(sc, reg, val) \ @@ -68,6 +73,7 @@ struct qcgpio_softc { void *sc_ih; uint32_t sc_npins; + int (*sc_pin_map)(int, bus_size_t *); struct qcgpio_intrhand *sc_pin_ih; struct acpi_gpio sc_gpio; @@ -86,9 +92,13 @@ struct cfdriver qcgpio_cd = { const char *qcgpio_hids[] = { "QCOM060C", + "QCOM080D", NULL }; +int qcgpio_sc7180_pin_map(int, bus_size_t *); +int qcgpio_sc8280xp_pin_map(int, bus_size_t *); + int qcgpio_read_pin(void *, int); void qcgpio_write_pin(void *, int, int); void qcgpio_intr_establish(void *, int, int, int (*)(void *), void *); @@ -125,7 +135,15 @@ qcgpio_attach(struct device *parent, struct device *self, void *aux) return; } - sc->sc_npins = 1024; + if (strcmp(aaa->aaa_dev, "QCOM080D") == 0) { + sc->sc_npins = 119; + sc->sc_pin_map = qcgpio_sc7180_pin_map; + } else if (strcmp(aaa->aaa_dev, "QCOM060C") == 0) { + sc->sc_npins = 228; + sc->sc_pin_map = qcgpio_sc8280xp_pin_map; + } + KASSERT(sc->sc_npins != 0); + sc->sc_pin_ih = mallocarray(sc->sc_npins, sizeof(*sc->sc_pin_ih), M_DEVBUF, M_WAITOK | M_ZERO); @@ -157,17 +175,31 @@ unmap: bus_space_unmap(sc->sc_iot, sc->sc_ioh, aaa->aaa_size[0]); } +int +qcgpio_sc7180_pin_map(int pin, bus_size_t *off) +{ + switch (pin) { + case 33: + case 0x180: + *off = QCGPIO_SC7180_NORTH; + return 33; + default: + return -1; + } +} int -qcgpio_pin_map(int pin) +qcgpio_sc8280xp_pin_map(int pin, bus_size_t *off) { switch (pin) { case 107: case 175: return pin; - case 832: + case 0x2c0: + return 107; + case 0x340: return 104; - case 896: + case 0x380: return 182; default: return -1; @@ -178,13 +210,14 @@ int qcgpio_read_pin(void *cookie, int pin) { struct qcgpio_softc *sc = cookie; + bus_size_t off = 0; uint32_t reg; - pin = qcgpio_pin_map(pin); + pin = sc->sc_pin_map(pin, &off); if (pin < 0 || pin >= sc->sc_npins) return 0; - reg = HREAD4(sc, TLMM_GPIO_IN_OUT(pin)); + reg = HREAD4(sc, off + TLMM_GPIO_IN_OUT(pin)); return !!(reg & TLMM_GPIO_IN_OUT_GPIO_IN); } @@ -192,15 +225,19 @@ void qcgpio_write_pin(void *cookie, int pin, int val) { struct qcgpio_softc *sc = cookie; + bus_size_t off = 0; - pin = qcgpio_pin_map(pin); + pin = sc->sc_pin_map(pin, &off); if (pin < 0 || pin >= sc->sc_npins) return; - if (val) - HSET4(sc, TLMM_GPIO_IN_OUT(pin), TLMM_GPIO_IN_OUT_GPIO_OUT); - else - HCLR4(sc, TLMM_GPIO_IN_OUT(pin), TLMM_GPIO_IN_OUT_GPIO_OUT); + if (val) { + HSET4(sc, off + TLMM_GPIO_IN_OUT(pin), + TLMM_GPIO_IN_OUT_GPIO_OUT); + } else { + HCLR4(sc, off + TLMM_GPIO_IN_OUT(pin), + TLMM_GPIO_IN_OUT_GPIO_OUT); + } } void @@ -208,16 +245,17 @@ qcgpio_intr_establish(void *cookie, int pin, int flags, int (*func)(void *), void *arg) { struct qcgpio_softc *sc = cookie; + bus_size_t off = 0; uint32_t reg; - pin = qcgpio_pin_map(pin); + pin = sc->sc_pin_map(pin, &off); if (pin < 0 || pin >= sc->sc_npins) return; sc->sc_pin_ih[pin].ih_func = func; sc->sc_pin_ih[pin].ih_arg = arg; - reg = HREAD4(sc, TLMM_GPIO_INTR_CFG(pin)); + reg = HREAD4(sc, off + TLMM_GPIO_INTR_CFG(pin)); reg &= ~TLMM_GPIO_INTR_CFG_INTR_DECT_CTL_MASK; reg &= ~TLMM_GPIO_INTR_CFG_INTR_POL_CTL; switch (flags & (LR_GPIO_MODE | LR_GPIO_POLARITY)) { @@ -248,7 +286,7 @@ qcgpio_intr_establish(void *cookie, int pin, int flags, reg |= TLMM_GPIO_INTR_CFG_TARGET_PROC_RPM; reg |= TLMM_GPIO_INTR_CFG_INTR_RAW_STATUS_EN; reg |= TLMM_GPIO_INTR_CFG_INTR_ENABLE; - HWRITE4(sc, TLMM_GPIO_INTR_CFG(pin), reg); + HWRITE4(sc, off + TLMM_GPIO_INTR_CFG(pin), reg); } int @@ -256,18 +294,21 @@ qcgpio_intr(void *arg) { struct qcgpio_softc *sc = arg; int pin, handled = 0; + bus_size_t off = 0; uint32_t stat; for (pin = 0; pin < sc->sc_npins; pin++) { if (sc->sc_pin_ih[pin].ih_func == NULL) continue; - stat = HREAD4(sc, TLMM_GPIO_INTR_STATUS(pin)); + sc->sc_pin_map(pin, &off); + + stat = HREAD4(sc, off + TLMM_GPIO_INTR_STATUS(pin)); if (stat & TLMM_GPIO_INTR_STATUS_INTR_STATUS) { sc->sc_pin_ih[pin].ih_func(sc->sc_pin_ih[pin].ih_arg); handled = 1; } - HWRITE4(sc, TLMM_GPIO_INTR_STATUS(pin), + HWRITE4(sc, off + TLMM_GPIO_INTR_STATUS(pin), stat & ~TLMM_GPIO_INTR_STATUS_INTR_STATUS); } |