1 /* $OpenBSD: bytgpio.c,v 1.11 2016/05/08 11:08:01 kettenis Exp $ */ 2 /* 3 * Copyright (c) 2016 Mark Kettenis 4 * 5 * Permission to use, copy, modify, and distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 */ 17 18 #include <sys/param.h> 19 #include <sys/malloc.h> 20 #include <sys/systm.h> 21 22 #include <dev/acpi/acpireg.h> 23 #include <dev/acpi/acpivar.h> 24 #include <dev/acpi/acpidev.h> 25 #include <dev/acpi/amltypes.h> 26 #include <dev/acpi/dsdt.h> 27 28 #define BYTGPIO_CONF_GD_LEVEL 0x01000000 29 #define BYTGPIO_CONF_GD_TPE 0x02000000 30 #define BYTGPIO_CONF_GD_TNE 0x04000000 31 #define BYTGPIO_CONF_GD_MASK 0x07000000 32 #define BYTGPIO_CONF_DIRECT_IRQ_EN 0x08000000 33 34 #define BYTGPIO_PAD_VAL 0x00000001 35 36 #define BYTGPIO_IRQ_TS_0 0x800 37 #define BYTGPIO_IRQ_TS_1 0x804 38 #define BYTGPIO_IRQ_TS_2 0x808 39 40 struct bytgpio_intrhand { 41 int (*ih_func)(void *); 42 void *ih_arg; 43 }; 44 45 struct bytgpio_softc { 46 struct device sc_dev; 47 struct acpi_softc *sc_acpi; 48 struct aml_node *sc_node; 49 50 bus_space_tag_t sc_memt; 51 bus_space_handle_t sc_memh; 52 bus_addr_t sc_addr; 53 bus_size_t sc_size; 54 55 int sc_irq; 56 int sc_irq_flags; 57 void *sc_ih; 58 59 const int *sc_pins; 60 int sc_npins; 61 struct bytgpio_intrhand *sc_pin_ih; 62 63 struct acpi_gpio sc_gpio; 64 }; 65 66 int bytgpio_match(struct device *, void *, void *); 67 void bytgpio_attach(struct device *, struct device *, void *); 68 69 struct cfattach bytgpio_ca = { 70 sizeof(struct bytgpio_softc), bytgpio_match, bytgpio_attach 71 }; 72 73 struct cfdriver bytgpio_cd = { 74 NULL, "bytgpio", DV_DULL 75 }; 76 77 const char *bytgpio_hids[] = { 78 "INT33FC", 79 NULL 80 }; 81 82 /* 83 * The pads for the pins are randomly ordered. 84 */ 85 86 const int byt_score_pins[] = { 87 85, 89, 93, 96, 99, 102, 98, 101, 34, 37, 36, 38, 39, 35, 40, 88 84, 62, 61, 64, 59, 54, 56, 60, 55, 63, 57, 51, 50, 53, 47, 89 52, 49, 48, 43, 46, 41, 45, 42, 58, 44, 95, 105, 70, 68, 67, 90 66, 69, 71, 65, 72, 86, 90, 88, 92, 103, 77, 79, 83, 78, 81, 91 80, 82, 13, 12, 15, 14, 17, 18, 19, 16, 2, 1, 0, 4, 6, 7, 9, 92 8, 33, 32, 31, 30, 29, 27, 25, 28, 26, 23, 21, 20, 24, 22, 5, 93 3, 10, 11, 106, 87, 91, 104, 97, 100 94 }; 95 96 const int byt_ncore_pins[] = { 97 19, 18, 17, 20, 21, 22, 24, 25, 23, 16, 14, 15, 12, 26, 27, 98 1, 4, 8, 11, 0, 3, 6, 10, 13, 2, 5, 9, 7 99 }; 100 101 const int byt_sus_pins[] = { 102 29, 33, 30, 31, 32, 34, 36, 35, 38, 37, 18, 7, 11, 20, 17, 1, 103 8, 10, 19, 12, 0, 2, 23, 39, 28, 27, 22, 21, 24, 25, 26, 51, 104 56, 54, 49, 55, 48, 57, 50, 58, 52, 53, 59, 40 105 }; 106 107 int bytgpio_parse_resources(union acpi_resource *, void *); 108 int bytgpio_read_pin(void *, int); 109 void bytgpio_write_pin(void *, int, int); 110 void bytgpio_intr_establish(void *, int, int, int (*)(), void *); 111 int bytgpio_intr(void *); 112 113 int 114 bytgpio_match(struct device *parent, void *match, void *aux) 115 { 116 struct acpi_attach_args *aaa = aux; 117 struct cfdata *cf = match; 118 119 return acpi_matchhids(aaa, bytgpio_hids, cf->cf_driver->cd_name); 120 } 121 122 void 123 bytgpio_attach(struct device *parent, struct device *self, void *aux) 124 { 125 struct acpi_attach_args *aaa = aux; 126 struct bytgpio_softc *sc = (struct bytgpio_softc *)self; 127 struct aml_value res; 128 struct aml_value arg[2]; 129 struct aml_node *node; 130 int64_t uid; 131 uint32_t reg; 132 int i; 133 134 sc->sc_acpi = (struct acpi_softc *)parent; 135 sc->sc_node = aaa->aaa_node; 136 printf(": %s", sc->sc_node->name); 137 138 if (aml_evalinteger(sc->sc_acpi, sc->sc_node, "_UID", 0, NULL, &uid)) { 139 printf(", can't find uid\n"); 140 return; 141 } 142 143 printf(" uid %lld", uid); 144 145 switch (uid) { 146 case 1: 147 sc->sc_pins = byt_score_pins; 148 sc->sc_npins = nitems(byt_score_pins); 149 break; 150 case 2: 151 sc->sc_pins = byt_ncore_pins; 152 sc->sc_npins = nitems(byt_ncore_pins); 153 break; 154 case 3: 155 sc->sc_pins = byt_sus_pins; 156 sc->sc_npins = nitems(byt_sus_pins); 157 break; 158 default: 159 printf("\n"); 160 return; 161 } 162 163 if (aml_evalname(sc->sc_acpi, sc->sc_node, "_CRS", 0, NULL, &res)) { 164 printf(", can't find registers\n"); 165 return; 166 } 167 168 aml_parse_resource(&res, bytgpio_parse_resources, sc); 169 printf(" addr 0x%lx/0x%lx", sc->sc_addr, sc->sc_size); 170 if (sc->sc_addr == 0 || sc->sc_size == 0) { 171 printf("\n"); 172 return; 173 } 174 aml_freevalue(&res); 175 176 sc->sc_pin_ih = mallocarray(sc->sc_npins, sizeof(*sc->sc_pin_ih), 177 M_DEVBUF, M_NOWAIT | M_ZERO); 178 if (sc->sc_pin_ih == NULL) { 179 printf("\n"); 180 return; 181 } 182 183 printf(" irq %d", sc->sc_irq); 184 185 sc->sc_memt = aaa->aaa_memt; 186 if (bus_space_map(sc->sc_memt, sc->sc_addr, sc->sc_size, 0, 187 &sc->sc_memh)) { 188 printf(", can't map registers\n"); 189 goto free; 190 } 191 192 sc->sc_ih = acpi_intr_establish(sc->sc_irq, sc->sc_irq_flags, IPL_BIO, 193 bytgpio_intr, sc, sc->sc_dev.dv_xname); 194 if (sc->sc_ih == NULL) { 195 printf(", can't establish interrupt\n"); 196 goto unmap; 197 } 198 199 sc->sc_gpio.cookie = sc; 200 sc->sc_gpio.read_pin = bytgpio_read_pin; 201 sc->sc_gpio.write_pin = bytgpio_write_pin; 202 sc->sc_gpio.intr_establish = bytgpio_intr_establish; 203 sc->sc_node->gpio = &sc->sc_gpio; 204 205 /* Mask all interrupts. */ 206 for (i = 0; i < sc->sc_npins; i++) { 207 reg = bus_space_read_4(sc->sc_memt, sc->sc_memh, sc->sc_pins[i] * 16); 208 209 /* 210 * Skip pins configured as direct IRQ. Those are tied 211 * directly to the APIC. 212 */ 213 if (reg & BYTGPIO_CONF_DIRECT_IRQ_EN) 214 continue; 215 216 reg &= ~BYTGPIO_CONF_GD_MASK; 217 bus_space_write_4(sc->sc_memt, sc->sc_memh, sc->sc_pins[i] * 16, reg); 218 } 219 220 printf(", %d pins\n", sc->sc_npins); 221 222 /* Register address space. */ 223 memset(&arg, 0, sizeof(arg)); 224 arg[0].type = AML_OBJTYPE_INTEGER; 225 arg[0].v_integer = ACPI_OPREG_GPIO; 226 arg[1].type = AML_OBJTYPE_INTEGER; 227 arg[1].v_integer = 1; 228 node = aml_searchname(sc->sc_node, "_REG"); 229 if (node && aml_evalnode(sc->sc_acpi, node, 2, arg, NULL)) 230 printf("%s: _REG failed\n", sc->sc_dev.dv_xname); 231 232 return; 233 234 unmap: 235 bus_space_unmap(sc->sc_memt, sc->sc_memh, sc->sc_size); 236 free: 237 free(sc->sc_pin_ih, M_DEVBUF, sc->sc_npins * sizeof(*sc->sc_pin_ih)); 238 } 239 240 int 241 bytgpio_parse_resources(union acpi_resource *crs, void *arg) 242 { 243 struct bytgpio_softc *sc = arg; 244 int type = AML_CRSTYPE(crs); 245 246 switch (type) { 247 case LR_MEM32FIXED: 248 sc->sc_addr = crs->lr_m32fixed._bas; 249 sc->sc_size = crs->lr_m32fixed._len; 250 break; 251 case LR_EXTIRQ: 252 sc->sc_irq = crs->lr_extirq.irq[0]; 253 sc->sc_irq_flags = crs->lr_extirq.flags; 254 break; 255 default: 256 printf(" type 0x%x\n", type); 257 break; 258 } 259 260 return 0; 261 } 262 263 int 264 bytgpio_read_pin(void *cookie, int pin) 265 { 266 struct bytgpio_softc *sc = cookie; 267 uint32_t reg; 268 269 reg = bus_space_read_4(sc->sc_memt, sc->sc_memh, sc->sc_pins[pin] * 16 + 8); 270 return (reg & BYTGPIO_PAD_VAL); 271 } 272 273 void 274 bytgpio_write_pin(void *cookie, int pin, int value) 275 { 276 struct bytgpio_softc *sc = cookie; 277 uint32_t reg; 278 279 reg = bus_space_read_4(sc->sc_memt, sc->sc_memh, sc->sc_pins[pin] * 16 + 8); 280 if (value) 281 reg |= BYTGPIO_PAD_VAL; 282 else 283 reg &= ~BYTGPIO_PAD_VAL; 284 bus_space_write_4(sc->sc_memt, sc->sc_memh, sc->sc_pins[pin] * 16 + 8, reg); 285 } 286 287 void 288 bytgpio_intr_establish(void *cookie, int pin, int flags, 289 int (*func)(void *), void *arg) 290 { 291 struct bytgpio_softc *sc = cookie; 292 uint32_t reg; 293 294 KASSERT(pin >= 0 && pin < sc->sc_npins); 295 296 sc->sc_pin_ih[pin].ih_func = func; 297 sc->sc_pin_ih[pin].ih_arg = arg; 298 299 reg = bus_space_read_4(sc->sc_memt, sc->sc_memh, sc->sc_pins[pin] * 16); 300 reg &= ~BYTGPIO_CONF_GD_MASK; 301 if ((flags & LR_GPIO_MODE) == 0) 302 reg |= BYTGPIO_CONF_GD_LEVEL; 303 if ((flags & LR_GPIO_POLARITY) == LR_GPIO_ACTLO) 304 reg |= BYTGPIO_CONF_GD_TNE; 305 if ((flags & LR_GPIO_POLARITY) == LR_GPIO_ACTHI) 306 reg |= BYTGPIO_CONF_GD_TPE; 307 if ((flags & LR_GPIO_POLARITY) == LR_GPIO_ACTBOTH) 308 reg |= BYTGPIO_CONF_GD_TNE | BYTGPIO_CONF_GD_TPE; 309 bus_space_write_4(sc->sc_memt, sc->sc_memh, sc->sc_pins[pin] * 16, reg); 310 } 311 312 int 313 bytgpio_intr(void *arg) 314 { 315 struct bytgpio_softc *sc = arg; 316 uint32_t reg; 317 int rc = 0; 318 int pin; 319 320 for (pin = 0; pin < sc->sc_npins; pin++) { 321 if (pin % 32 == 0) { 322 reg = bus_space_read_4(sc->sc_memt, sc->sc_memh, 323 BYTGPIO_IRQ_TS_0 + (pin / 8)); 324 bus_space_write_4(sc->sc_memt, sc->sc_memh, 325 BYTGPIO_IRQ_TS_0 + (pin / 8), reg); 326 } 327 if (reg & (1 << (pin % 32))) { 328 if (sc->sc_pin_ih[pin].ih_func) 329 sc->sc_pin_ih[pin].ih_func(sc->sc_pin_ih[pin].ih_arg); 330 rc = 1; 331 } 332 } 333 334 return rc; 335 } 336