1 /* $NetBSD: ichlpcib.c,v 1.23 2010/01/08 19:43:26 dyoung Exp $ */ 2 3 /*- 4 * Copyright (c) 2004 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Minoura Makoto and Matthew R. Green. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 /* 33 * Intel I/O Controller Hub (ICHn) LPC Interface Bridge driver 34 * 35 * LPC Interface Bridge is basically a pcib (PCI-ISA Bridge), but has 36 * some power management and monitoring functions. 37 * Currently we support the watchdog timer, SpeedStep (on some systems) 38 * and the power management timer. 39 */ 40 41 #include <sys/cdefs.h> 42 __KERNEL_RCSID(0, "$NetBSD: ichlpcib.c,v 1.23 2010/01/08 19:43:26 dyoung Exp $"); 43 44 #include <sys/types.h> 45 #include <sys/param.h> 46 #include <sys/systm.h> 47 #include <sys/device.h> 48 #include <sys/sysctl.h> 49 #include <sys/timetc.h> 50 #include <sys/gpio.h> 51 #include <machine/bus.h> 52 53 #include <dev/pci/pcivar.h> 54 #include <dev/pci/pcireg.h> 55 #include <dev/pci/pcidevs.h> 56 57 #include <dev/gpio/gpiovar.h> 58 #include <dev/sysmon/sysmonvar.h> 59 60 #include <dev/ic/acpipmtimer.h> 61 #include <dev/ic/i82801lpcreg.h> 62 #include <dev/ic/hpetreg.h> 63 #include <dev/ic/hpetvar.h> 64 65 #include "hpet.h" 66 #include "pcibvar.h" 67 #include "gpio.h" 68 69 #define LPCIB_GPIO_NPINS 64 70 71 struct lpcib_softc { 72 /* we call pcibattach() which assumes this starts like this: */ 73 struct pcib_softc sc_pcib; 74 75 struct pci_attach_args sc_pa; 76 int sc_has_rcba; 77 int sc_has_ich5_hpet; 78 79 /* RCBA */ 80 bus_space_tag_t sc_rcbat; 81 bus_space_handle_t sc_rcbah; 82 pcireg_t sc_rcba_reg; 83 84 /* Watchdog variables. */ 85 struct sysmon_wdog sc_smw; 86 bus_space_tag_t sc_iot; 87 bus_space_handle_t sc_ioh; 88 bus_size_t sc_iosize; 89 90 #if NHPET > 0 91 /* HPET variables. */ 92 uint32_t sc_hpet_reg; 93 #endif 94 95 #if NGPIO > 0 96 device_t sc_gpiobus; 97 kmutex_t sc_gpio_mtx; 98 bus_space_tag_t sc_gpio_iot; 99 bus_space_handle_t sc_gpio_ioh; 100 bus_size_t sc_gpio_ios; 101 struct gpio_chipset_tag sc_gpio_gc; 102 gpio_pin_t sc_gpio_pins[LPCIB_GPIO_NPINS]; 103 #endif 104 105 /* Speedstep */ 106 pcireg_t sc_pmcon_orig; 107 108 /* Power management */ 109 pcireg_t sc_pirq[2]; 110 pcireg_t sc_pmcon; 111 pcireg_t sc_fwhsel2; 112 113 /* Child devices */ 114 device_t sc_hpetbus; 115 acpipmtimer_t sc_pmtimer; 116 pcireg_t sc_acpi_cntl; 117 118 struct sysctllog *sc_log; 119 }; 120 121 static int lpcibmatch(device_t, cfdata_t, void *); 122 static void lpcibattach(device_t, device_t, void *); 123 static int lpcibdetach(device_t, int); 124 static void lpcibchilddet(device_t, device_t); 125 static int lpcibrescan(device_t, const char *, const int *); 126 static bool lpcib_suspend(device_t, pmf_qual_t); 127 static bool lpcib_resume(device_t, pmf_qual_t); 128 static bool lpcib_shutdown(device_t, int); 129 130 static void pmtimer_configure(device_t); 131 static int pmtimer_unconfigure(device_t, int); 132 133 static void tcotimer_configure(device_t); 134 static int tcotimer_unconfigure(device_t, int); 135 static int tcotimer_setmode(struct sysmon_wdog *); 136 static int tcotimer_tickle(struct sysmon_wdog *); 137 static void tcotimer_stop(struct lpcib_softc *); 138 static void tcotimer_start(struct lpcib_softc *); 139 static void tcotimer_status_reset(struct lpcib_softc *); 140 static int tcotimer_disable_noreboot(device_t); 141 142 static void speedstep_configure(device_t); 143 static void speedstep_unconfigure(device_t); 144 static int speedstep_sysctl_helper(SYSCTLFN_ARGS); 145 146 #if NHPET > 0 147 static void lpcib_hpet_configure(device_t); 148 static int lpcib_hpet_unconfigure(device_t, int); 149 #endif 150 151 #if NGPIO > 0 152 static void lpcib_gpio_configure(device_t); 153 static int lpcib_gpio_unconfigure(device_t, int); 154 static int lpcib_gpio_pin_read(void *, int); 155 static void lpcib_gpio_pin_write(void *, int, int); 156 static void lpcib_gpio_pin_ctl(void *, int, int); 157 #endif 158 159 struct lpcib_softc *speedstep_cookie; /* XXX */ 160 161 CFATTACH_DECL2_NEW(ichlpcib, sizeof(struct lpcib_softc), 162 lpcibmatch, lpcibattach, lpcibdetach, NULL, lpcibrescan, lpcibchilddet); 163 164 static struct lpcib_device { 165 pcireg_t vendor, product; 166 int has_rcba; 167 int has_ich5_hpet; 168 } lpcib_devices[] = { 169 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801AA_LPC, 0, 0 }, 170 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801BA_LPC, 0, 0 }, 171 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801BAM_LPC, 0, 0 }, 172 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801CA_LPC, 0, 0 }, 173 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801CAM_LPC, 0, 0 }, 174 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801DB_LPC, 0, 0 }, 175 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801DB_ISA, 0, 0 }, 176 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801EB_LPC, 0, 1 }, 177 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801FB_LPC, 1, 0 }, 178 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801FBM_LPC, 1, 0 }, 179 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801G_LPC, 1, 0 }, 180 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801GBM_LPC, 1, 0 }, 181 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801GHM_LPC, 1, 0 }, 182 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801H_LPC, 1, 0 }, 183 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801HEM_LPC, 1, 0 }, 184 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801HH_LPC, 1, 0 }, 185 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801HO_LPC, 1, 0 }, 186 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801HBM_LPC, 1, 0 }, 187 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801IH_LPC, 1, 0 }, 188 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801IO_LPC, 1, 0 }, 189 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801IR_LPC, 1, 0 }, 190 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801IEM_LPC, 1, 0 }, 191 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801IB_LPC, 1, 0 }, 192 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_63XXESB_LPC, 1, 0 }, 193 194 { 0, 0, 0, 0 }, 195 }; 196 197 /* 198 * Autoconf callbacks. 199 */ 200 static int 201 lpcibmatch(device_t parent, cfdata_t match, void *aux) 202 { 203 struct pci_attach_args *pa = aux; 204 struct lpcib_device *lpcib_dev; 205 206 /* We are ISA bridge, of course */ 207 if (PCI_CLASS(pa->pa_class) != PCI_CLASS_BRIDGE || 208 PCI_SUBCLASS(pa->pa_class) != PCI_SUBCLASS_BRIDGE_ISA) 209 return 0; 210 211 for (lpcib_dev = lpcib_devices; lpcib_dev->vendor; ++lpcib_dev) { 212 if (PCI_VENDOR(pa->pa_id) == lpcib_dev->vendor && 213 PCI_PRODUCT(pa->pa_id) == lpcib_dev->product) 214 return 10; 215 } 216 217 return 0; 218 } 219 220 static void 221 lpcibattach(device_t parent, device_t self, void *aux) 222 { 223 struct pci_attach_args *pa = aux; 224 struct lpcib_softc *sc = device_private(self); 225 struct lpcib_device *lpcib_dev; 226 227 sc->sc_pa = *pa; 228 229 for (lpcib_dev = lpcib_devices; lpcib_dev->vendor; ++lpcib_dev) { 230 if (PCI_VENDOR(pa->pa_id) != lpcib_dev->vendor || 231 PCI_PRODUCT(pa->pa_id) != lpcib_dev->product) 232 continue; 233 sc->sc_has_rcba = lpcib_dev->has_rcba; 234 sc->sc_has_ich5_hpet = lpcib_dev->has_ich5_hpet; 235 break; 236 } 237 238 pcibattach(parent, self, aux); 239 240 /* 241 * Part of our I/O registers are used as ACPI PM regs. 242 * Since our ACPI subsystem accesses the I/O space directly so far, 243 * we do not have to bother bus_space I/O map confliction. 244 */ 245 if (pci_mapreg_map(pa, LPCIB_PCI_PMBASE, PCI_MAPREG_TYPE_IO, 0, 246 &sc->sc_iot, &sc->sc_ioh, NULL, &sc->sc_iosize)) { 247 aprint_error_dev(self, "can't map power management i/o space"); 248 return; 249 } 250 251 sc->sc_pmcon_orig = pci_conf_read(sc->sc_pcib.sc_pc, sc->sc_pcib.sc_tag, 252 LPCIB_PCI_GEN_PMCON_1); 253 254 /* For ICH6 and later, always enable RCBA */ 255 if (sc->sc_has_rcba) { 256 pcireg_t rcba; 257 258 sc->sc_rcbat = sc->sc_pa.pa_memt; 259 260 rcba = pci_conf_read(sc->sc_pcib.sc_pc, sc->sc_pcib.sc_tag, 261 LPCIB_RCBA); 262 if ((rcba & LPCIB_RCBA_EN) == 0) { 263 aprint_error_dev(self, "RCBA is not enabled"); 264 return; 265 } 266 rcba &= ~LPCIB_RCBA_EN; 267 268 if (bus_space_map(sc->sc_rcbat, rcba, LPCIB_RCBA_SIZE, 0, 269 &sc->sc_rcbah)) { 270 aprint_error_dev(self, "RCBA could not be mapped"); 271 return; 272 } 273 } 274 275 /* Set up the power management timer. */ 276 pmtimer_configure(self); 277 278 /* Set up the TCO (watchdog). */ 279 tcotimer_configure(self); 280 281 /* Set up SpeedStep. */ 282 speedstep_configure(self); 283 284 #if NHPET > 0 285 /* Set up HPET. */ 286 lpcib_hpet_configure(self); 287 #endif 288 289 #if NGPIO > 0 290 /* Set up GPIO */ 291 lpcib_gpio_configure(self); 292 #endif 293 294 /* Install power handler */ 295 if (!pmf_device_register1(self, lpcib_suspend, lpcib_resume, 296 lpcib_shutdown)) 297 aprint_error_dev(self, "couldn't establish power handler\n"); 298 } 299 300 static void 301 lpcibchilddet(device_t self, device_t child) 302 { 303 struct lpcib_softc *sc = device_private(self); 304 uint32_t val; 305 306 #if NGPIO > 0 307 if (sc->sc_gpiobus == child) { 308 sc->sc_gpiobus = NULL; 309 return; 310 } 311 #endif 312 if (sc->sc_hpetbus != child) { 313 pcibchilddet(self, child); 314 return; 315 } 316 sc->sc_hpetbus = NULL; 317 if (sc->sc_has_ich5_hpet) { 318 val = pci_conf_read(sc->sc_pcib.sc_pc, sc->sc_pcib.sc_tag, 319 LPCIB_PCI_GEN_CNTL); 320 switch (val & LPCIB_ICH5_HPTC_WIN_MASK) { 321 case LPCIB_ICH5_HPTC_0000: 322 case LPCIB_ICH5_HPTC_1000: 323 case LPCIB_ICH5_HPTC_2000: 324 case LPCIB_ICH5_HPTC_3000: 325 break; 326 default: 327 return; 328 } 329 val &= ~LPCIB_ICH5_HPTC_EN; 330 pci_conf_write(sc->sc_pcib.sc_pc, sc->sc_pcib.sc_tag, 331 LPCIB_PCI_GEN_CNTL, val); 332 } else if (sc->sc_has_rcba) { 333 val = bus_space_read_4(sc->sc_rcbat, sc->sc_rcbah, 334 LPCIB_RCBA_HPTC); 335 switch (val & LPCIB_RCBA_HPTC_WIN_MASK) { 336 case LPCIB_RCBA_HPTC_0000: 337 case LPCIB_RCBA_HPTC_1000: 338 case LPCIB_RCBA_HPTC_2000: 339 case LPCIB_RCBA_HPTC_3000: 340 break; 341 default: 342 return; 343 } 344 val &= ~LPCIB_RCBA_HPTC_EN; 345 bus_space_write_4(sc->sc_rcbat, sc->sc_rcbah, LPCIB_RCBA_HPTC, 346 val); 347 } 348 } 349 350 static int 351 lpcibrescan(device_t self, const char *ifattr, const int *locators) 352 { 353 #if NHPET > 0 || NGPIO > 0 354 struct lpcib_softc *sc = device_private(self); 355 #endif 356 357 #if NHPET > 0 358 if (ifattr_match(ifattr, "hpetichbus") && sc->sc_hpetbus == NULL) 359 lpcib_hpet_configure(self); 360 #endif 361 362 #if NGPIO > 0 363 if (ifattr_match(ifattr, "gpiobus") && sc->sc_gpiobus == NULL) 364 lpcib_gpio_configure(self); 365 #endif 366 367 return pcibrescan(self, ifattr, locators); 368 } 369 370 static int 371 lpcibdetach(device_t self, int flags) 372 { 373 struct lpcib_softc *sc = device_private(self); 374 int rc; 375 376 pmf_device_deregister(self); 377 378 #if NHPET > 0 379 if ((rc = lpcib_hpet_unconfigure(self, flags)) != 0) 380 return rc; 381 #endif 382 383 #if NGPIO > 0 384 if ((rc = lpcib_gpio_unconfigure(self, flags)) != 0) 385 return rc; 386 #endif 387 388 /* Set up SpeedStep. */ 389 speedstep_unconfigure(self); 390 391 if ((rc = tcotimer_unconfigure(self, flags)) != 0) 392 return rc; 393 394 if ((rc = pmtimer_unconfigure(self, flags)) != 0) 395 return rc; 396 397 if (sc->sc_has_rcba) 398 bus_space_unmap(sc->sc_rcbat, sc->sc_rcbah, LPCIB_RCBA_SIZE); 399 400 bus_space_unmap(sc->sc_iot, sc->sc_ioh, sc->sc_iosize); 401 402 return pcibdetach(self, flags); 403 } 404 405 static bool 406 lpcib_shutdown(device_t dv, int howto) 407 { 408 struct lpcib_softc *sc = device_private(dv); 409 410 pci_conf_write(sc->sc_pcib.sc_pc, sc->sc_pcib.sc_tag, 411 LPCIB_PCI_GEN_PMCON_1, sc->sc_pmcon_orig); 412 413 return true; 414 } 415 416 static bool 417 lpcib_suspend(device_t dv, pmf_qual_t qual) 418 { 419 struct lpcib_softc *sc = device_private(dv); 420 pci_chipset_tag_t pc = sc->sc_pcib.sc_pc; 421 pcitag_t tag = sc->sc_pcib.sc_tag; 422 423 /* capture PIRQ routing control registers */ 424 sc->sc_pirq[0] = pci_conf_read(pc, tag, LPCIB_PCI_PIRQA_ROUT); 425 sc->sc_pirq[1] = pci_conf_read(pc, tag, LPCIB_PCI_PIRQE_ROUT); 426 427 sc->sc_pmcon = pci_conf_read(pc, tag, LPCIB_PCI_GEN_PMCON_1); 428 sc->sc_fwhsel2 = pci_conf_read(pc, tag, LPCIB_PCI_GEN_STA); 429 430 if (sc->sc_has_rcba) { 431 sc->sc_rcba_reg = pci_conf_read(pc, tag, LPCIB_RCBA); 432 #if NHPET > 0 433 sc->sc_hpet_reg = bus_space_read_4(sc->sc_rcbat, sc->sc_rcbah, 434 LPCIB_RCBA_HPTC); 435 #endif 436 } else if (sc->sc_has_ich5_hpet) { 437 #if NHPET > 0 438 sc->sc_hpet_reg = pci_conf_read(pc, tag, LPCIB_PCI_GEN_CNTL); 439 #endif 440 } 441 442 return true; 443 } 444 445 static bool 446 lpcib_resume(device_t dv, pmf_qual_t qual) 447 { 448 struct lpcib_softc *sc = device_private(dv); 449 pci_chipset_tag_t pc = sc->sc_pcib.sc_pc; 450 pcitag_t tag = sc->sc_pcib.sc_tag; 451 452 /* restore PIRQ routing control registers */ 453 pci_conf_write(pc, tag, LPCIB_PCI_PIRQA_ROUT, sc->sc_pirq[0]); 454 pci_conf_write(pc, tag, LPCIB_PCI_PIRQE_ROUT, sc->sc_pirq[1]); 455 456 pci_conf_write(pc, tag, LPCIB_PCI_GEN_PMCON_1, sc->sc_pmcon); 457 pci_conf_write(pc, tag, LPCIB_PCI_GEN_STA, sc->sc_fwhsel2); 458 459 if (sc->sc_has_rcba) { 460 pci_conf_write(pc, tag, LPCIB_RCBA, sc->sc_rcba_reg); 461 #if NHPET > 0 462 bus_space_write_4(sc->sc_rcbat, sc->sc_rcbah, LPCIB_RCBA_HPTC, 463 sc->sc_hpet_reg); 464 #endif 465 } else if (sc->sc_has_ich5_hpet) { 466 #if NHPET > 0 467 pci_conf_write(pc, tag, LPCIB_PCI_GEN_CNTL, sc->sc_hpet_reg); 468 #endif 469 } 470 471 return true; 472 } 473 474 /* 475 * Initialize the power management timer. 476 */ 477 static void 478 pmtimer_configure(device_t self) 479 { 480 struct lpcib_softc *sc = device_private(self); 481 pcireg_t control; 482 483 /* 484 * Check if power management I/O space is enabled and enable the ACPI_EN 485 * bit if it's disabled. 486 */ 487 control = pci_conf_read(sc->sc_pcib.sc_pc, sc->sc_pcib.sc_tag, 488 LPCIB_PCI_ACPI_CNTL); 489 sc->sc_acpi_cntl = control; 490 if ((control & LPCIB_PCI_ACPI_CNTL_EN) == 0) { 491 control |= LPCIB_PCI_ACPI_CNTL_EN; 492 pci_conf_write(sc->sc_pcib.sc_pc, sc->sc_pcib.sc_tag, 493 LPCIB_PCI_ACPI_CNTL, control); 494 } 495 496 /* Attach our PM timer with the generic acpipmtimer function */ 497 sc->sc_pmtimer = acpipmtimer_attach(self, sc->sc_iot, sc->sc_ioh, 498 LPCIB_PM1_TMR, 0); 499 } 500 501 static int 502 pmtimer_unconfigure(device_t self, int flags) 503 { 504 struct lpcib_softc *sc = device_private(self); 505 int rc; 506 507 if (sc->sc_pmtimer != NULL && 508 (rc = acpipmtimer_detach(sc->sc_pmtimer, flags)) != 0) 509 return rc; 510 511 pci_conf_write(sc->sc_pcib.sc_pc, sc->sc_pcib.sc_tag, 512 LPCIB_PCI_ACPI_CNTL, sc->sc_acpi_cntl); 513 514 return 0; 515 } 516 517 /* 518 * Initialize the watchdog timer. 519 */ 520 static void 521 tcotimer_configure(device_t self) 522 { 523 struct lpcib_softc *sc = device_private(self); 524 uint32_t ioreg; 525 unsigned int period; 526 527 /* Explicitly stop the TCO timer. */ 528 tcotimer_stop(sc); 529 530 /* 531 * Enable TCO timeout SMI only if the hardware reset does not 532 * work. We don't know what the SMBIOS does. 533 */ 534 ioreg = bus_space_read_4(sc->sc_iot, sc->sc_ioh, LPCIB_SMI_EN); 535 ioreg &= ~LPCIB_SMI_EN_TCO_EN; 536 537 /* 538 * Clear the No Reboot (NR) bit. If this fails, enabling the TCO_EN bit 539 * in the SMI_EN register is the last chance. 540 */ 541 if (tcotimer_disable_noreboot(self)) { 542 ioreg |= LPCIB_SMI_EN_TCO_EN; 543 } 544 if ((ioreg & LPCIB_SMI_EN_GBL_SMI_EN) != 0) { 545 bus_space_write_4(sc->sc_iot, sc->sc_ioh, LPCIB_SMI_EN, ioreg); 546 } 547 548 /* Reset the watchdog status registers. */ 549 tcotimer_status_reset(sc); 550 551 /* 552 * Register the driver with the sysmon watchdog framework. 553 */ 554 sc->sc_smw.smw_name = device_xname(self); 555 sc->sc_smw.smw_cookie = sc; 556 sc->sc_smw.smw_setmode = tcotimer_setmode; 557 sc->sc_smw.smw_tickle = tcotimer_tickle; 558 if (sc->sc_has_rcba) 559 period = LPCIB_TCOTIMER2_MAX_TICK; 560 else 561 period = LPCIB_TCOTIMER_MAX_TICK; 562 sc->sc_smw.smw_period = lpcib_tcotimer_tick_to_second(period); 563 564 if (sysmon_wdog_register(&sc->sc_smw)) { 565 aprint_error_dev(self, "unable to register TCO timer" 566 "as a sysmon watchdog device.\n"); 567 return; 568 } 569 570 aprint_verbose_dev(self, "TCO (watchdog) timer configured.\n"); 571 } 572 573 static int 574 tcotimer_unconfigure(device_t self, int flags) 575 { 576 struct lpcib_softc *sc = device_private(self); 577 int rc; 578 579 if ((rc = sysmon_wdog_unregister(&sc->sc_smw)) != 0) { 580 if (rc == ERESTART) 581 rc = EINTR; 582 return rc; 583 } 584 585 /* Explicitly stop the TCO timer. */ 586 tcotimer_stop(sc); 587 588 /* XXX Set No Reboot? */ 589 590 return 0; 591 } 592 593 594 /* 595 * Sysmon watchdog callbacks. 596 */ 597 static int 598 tcotimer_setmode(struct sysmon_wdog *smw) 599 { 600 struct lpcib_softc *sc = smw->smw_cookie; 601 unsigned int period; 602 uint16_t ich6period = 0; 603 uint8_t ich5period = 0; 604 605 if ((smw->smw_mode & WDOG_MODE_MASK) == WDOG_MODE_DISARMED) { 606 /* Stop the TCO timer. */ 607 tcotimer_stop(sc); 608 } else { 609 /* 610 * ICH6 or newer are limited to 2s min and 613s max. 611 * ICH5 or older are limited to 4s min and 39s max. 612 */ 613 period = lpcib_tcotimer_second_to_tick(smw->smw_period); 614 if (sc->sc_has_rcba) { 615 if (period < LPCIB_TCOTIMER2_MIN_TICK || 616 period > LPCIB_TCOTIMER2_MAX_TICK) 617 return EINVAL; 618 } else { 619 if (period < LPCIB_TCOTIMER_MIN_TICK || 620 period > LPCIB_TCOTIMER_MAX_TICK) 621 return EINVAL; 622 } 623 624 /* Stop the TCO timer, */ 625 tcotimer_stop(sc); 626 627 /* set the timeout, */ 628 if (sc->sc_has_rcba) { 629 /* ICH6 or newer */ 630 ich6period = bus_space_read_2(sc->sc_iot, sc->sc_ioh, 631 LPCIB_TCO_TMR2); 632 ich6period &= 0xfc00; 633 bus_space_write_2(sc->sc_iot, sc->sc_ioh, 634 LPCIB_TCO_TMR2, ich6period | period); 635 } else { 636 /* ICH5 or older */ 637 ich5period = bus_space_read_1(sc->sc_iot, sc->sc_ioh, 638 LPCIB_TCO_TMR); 639 ich5period &= 0xc0; 640 bus_space_write_1(sc->sc_iot, sc->sc_ioh, 641 LPCIB_TCO_TMR, ich5period | period); 642 } 643 644 /* and start/reload the timer. */ 645 tcotimer_start(sc); 646 tcotimer_tickle(smw); 647 } 648 649 return 0; 650 } 651 652 static int 653 tcotimer_tickle(struct sysmon_wdog *smw) 654 { 655 struct lpcib_softc *sc = smw->smw_cookie; 656 657 /* any value is allowed */ 658 if (sc->sc_has_rcba) 659 bus_space_write_2(sc->sc_iot, sc->sc_ioh, LPCIB_TCO_RLD, 1); 660 else 661 bus_space_write_1(sc->sc_iot, sc->sc_ioh, LPCIB_TCO_RLD, 1); 662 663 return 0; 664 } 665 666 static void 667 tcotimer_stop(struct lpcib_softc *sc) 668 { 669 uint16_t ioreg; 670 671 ioreg = bus_space_read_2(sc->sc_iot, sc->sc_ioh, LPCIB_TCO1_CNT); 672 ioreg |= LPCIB_TCO1_CNT_TCO_TMR_HLT; 673 bus_space_write_2(sc->sc_iot, sc->sc_ioh, LPCIB_TCO1_CNT, ioreg); 674 } 675 676 static void 677 tcotimer_start(struct lpcib_softc *sc) 678 { 679 uint16_t ioreg; 680 681 ioreg = bus_space_read_2(sc->sc_iot, sc->sc_ioh, LPCIB_TCO1_CNT); 682 ioreg &= ~LPCIB_TCO1_CNT_TCO_TMR_HLT; 683 bus_space_write_2(sc->sc_iot, sc->sc_ioh, LPCIB_TCO1_CNT, ioreg); 684 } 685 686 static void 687 tcotimer_status_reset(struct lpcib_softc *sc) 688 { 689 bus_space_write_2(sc->sc_iot, sc->sc_ioh, LPCIB_TCO1_STS, 690 LPCIB_TCO1_STS_TIMEOUT); 691 bus_space_write_2(sc->sc_iot, sc->sc_ioh, LPCIB_TCO2_STS, 692 LPCIB_TCO2_STS_BOOT_STS); 693 bus_space_write_2(sc->sc_iot, sc->sc_ioh, LPCIB_TCO2_STS, 694 LPCIB_TCO2_STS_SECONDS_TO_STS); 695 } 696 697 /* 698 * Clear the No Reboot (NR) bit, this enables reboots when the timer 699 * reaches the timeout for the second time. 700 */ 701 static int 702 tcotimer_disable_noreboot(device_t self) 703 { 704 struct lpcib_softc *sc = device_private(self); 705 706 if (sc->sc_has_rcba) { 707 uint32_t status; 708 709 status = bus_space_read_4(sc->sc_rcbat, sc->sc_rcbah, 710 LPCIB_GCS_OFFSET); 711 status &= ~LPCIB_GCS_NO_REBOOT; 712 bus_space_write_4(sc->sc_rcbat, sc->sc_rcbah, 713 LPCIB_GCS_OFFSET, status); 714 status = bus_space_read_4(sc->sc_rcbat, sc->sc_rcbah, 715 LPCIB_GCS_OFFSET); 716 if (status & LPCIB_GCS_NO_REBOOT) 717 goto error; 718 } else { 719 pcireg_t pcireg; 720 721 pcireg = pci_conf_read(sc->sc_pcib.sc_pc, sc->sc_pcib.sc_tag, 722 LPCIB_PCI_GEN_STA); 723 if (pcireg & LPCIB_PCI_GEN_STA_NO_REBOOT) { 724 /* TCO timeout reset is disabled; try to enable it */ 725 pcireg &= ~LPCIB_PCI_GEN_STA_NO_REBOOT; 726 pci_conf_write(sc->sc_pcib.sc_pc, sc->sc_pcib.sc_tag, 727 LPCIB_PCI_GEN_STA, pcireg); 728 if (pcireg & LPCIB_PCI_GEN_STA_NO_REBOOT) 729 goto error; 730 } 731 } 732 733 return 0; 734 error: 735 aprint_error_dev(self, "TCO timer reboot disabled by hardware; " 736 "hope SMBIOS properly handles it.\n"); 737 return EINVAL; 738 } 739 740 741 /* 742 * Intel ICH SpeedStep support. 743 */ 744 #define SS_READ(sc, reg) \ 745 bus_space_read_1((sc)->sc_iot, (sc)->sc_ioh, (reg)) 746 #define SS_WRITE(sc, reg, val) \ 747 bus_space_write_1((sc)->sc_iot, (sc)->sc_ioh, (reg), (val)) 748 749 /* 750 * Linux driver says that SpeedStep on older chipsets cause 751 * lockups on Dell Inspiron 8000 and 8100. 752 * It should also not be enabled on systems with the 82855GM 753 * Hub, which typically have an EST-enabled CPU. 754 */ 755 static int 756 speedstep_bad_hb_check(struct pci_attach_args *pa) 757 { 758 759 if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_INTEL_82815_FULL_HUB && 760 PCI_REVISION(pa->pa_class) < 5) 761 return 1; 762 763 if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_INTEL_82855GM_MCH) 764 return 1; 765 766 return 0; 767 } 768 769 static void 770 speedstep_configure(device_t self) 771 { 772 struct lpcib_softc *sc = device_private(self); 773 const struct sysctlnode *node, *ssnode; 774 int rv; 775 776 /* Supported on ICH2-M, ICH3-M and ICH4-M. */ 777 if (PCI_PRODUCT(sc->sc_pa.pa_id) == PCI_PRODUCT_INTEL_82801DB_ISA || 778 PCI_PRODUCT(sc->sc_pa.pa_id) == PCI_PRODUCT_INTEL_82801CAM_LPC || 779 (PCI_PRODUCT(sc->sc_pa.pa_id) == PCI_PRODUCT_INTEL_82801BAM_LPC && 780 pci_find_device(&sc->sc_pa, speedstep_bad_hb_check) == 0)) { 781 pcireg_t pmcon; 782 783 /* Enable SpeedStep if it isn't already enabled. */ 784 pmcon = pci_conf_read(sc->sc_pcib.sc_pc, sc->sc_pcib.sc_tag, 785 LPCIB_PCI_GEN_PMCON_1); 786 if ((pmcon & LPCIB_PCI_GEN_PMCON_1_SS_EN) == 0) 787 pci_conf_write(sc->sc_pcib.sc_pc, sc->sc_pcib.sc_tag, 788 LPCIB_PCI_GEN_PMCON_1, 789 pmcon | LPCIB_PCI_GEN_PMCON_1_SS_EN); 790 791 /* Put in machdep.speedstep_state (0 for low, 1 for high). */ 792 if ((rv = sysctl_createv(&sc->sc_log, 0, NULL, &node, 793 CTLFLAG_PERMANENT, CTLTYPE_NODE, "machdep", NULL, 794 NULL, 0, NULL, 0, CTL_MACHDEP, CTL_EOL)) != 0) 795 goto err; 796 797 /* CTLFLAG_ANYWRITE? kernel option like EST? */ 798 if ((rv = sysctl_createv(&sc->sc_log, 0, &node, &ssnode, 799 CTLFLAG_READWRITE, CTLTYPE_INT, "speedstep_state", NULL, 800 speedstep_sysctl_helper, 0, NULL, 0, CTL_CREATE, 801 CTL_EOL)) != 0) 802 goto err; 803 804 /* XXX save the sc for IO tag/handle */ 805 speedstep_cookie = sc; 806 aprint_verbose_dev(self, "SpeedStep enabled\n"); 807 } 808 809 return; 810 811 err: 812 aprint_normal("%s: sysctl_createv failed (rv = %d)\n", __func__, rv); 813 } 814 815 static void 816 speedstep_unconfigure(device_t self) 817 { 818 struct lpcib_softc *sc = device_private(self); 819 820 sysctl_teardown(&sc->sc_log); 821 pci_conf_write(sc->sc_pcib.sc_pc, sc->sc_pcib.sc_tag, 822 LPCIB_PCI_GEN_PMCON_1, sc->sc_pmcon_orig); 823 824 speedstep_cookie = NULL; 825 } 826 827 /* 828 * get/set the SpeedStep state: 0 == low power, 1 == high power. 829 */ 830 static int 831 speedstep_sysctl_helper(SYSCTLFN_ARGS) 832 { 833 struct sysctlnode node; 834 struct lpcib_softc *sc = speedstep_cookie; 835 uint8_t state, state2; 836 int ostate, nstate, s, error = 0; 837 838 /* 839 * We do the dance with spl's to avoid being at high ipl during 840 * sysctl_lookup() which can both copyin and copyout. 841 */ 842 s = splserial(); 843 state = SS_READ(sc, LPCIB_PM_SS_CNTL); 844 splx(s); 845 if ((state & LPCIB_PM_SS_STATE_LOW) == 0) 846 ostate = 1; 847 else 848 ostate = 0; 849 nstate = ostate; 850 851 node = *rnode; 852 node.sysctl_data = &nstate; 853 854 error = sysctl_lookup(SYSCTLFN_CALL(&node)); 855 if (error || newp == NULL) 856 goto out; 857 858 /* Only two states are available */ 859 if (nstate != 0 && nstate != 1) { 860 error = EINVAL; 861 goto out; 862 } 863 864 s = splserial(); 865 state2 = SS_READ(sc, LPCIB_PM_SS_CNTL); 866 if ((state2 & LPCIB_PM_SS_STATE_LOW) == 0) 867 ostate = 1; 868 else 869 ostate = 0; 870 871 if (ostate != nstate) { 872 uint8_t cntl; 873 874 if (nstate == 0) 875 state2 |= LPCIB_PM_SS_STATE_LOW; 876 else 877 state2 &= ~LPCIB_PM_SS_STATE_LOW; 878 879 /* 880 * Must disable bus master arbitration during the change. 881 */ 882 cntl = SS_READ(sc, LPCIB_PM_CTRL); 883 SS_WRITE(sc, LPCIB_PM_CTRL, cntl | LPCIB_PM_SS_CNTL_ARB_DIS); 884 SS_WRITE(sc, LPCIB_PM_SS_CNTL, state2); 885 SS_WRITE(sc, LPCIB_PM_CTRL, cntl); 886 } 887 splx(s); 888 out: 889 return error; 890 } 891 892 #if NHPET > 0 893 struct lpcib_hpet_attach_arg { 894 bus_space_tag_t hpet_mem_t; 895 uint32_t hpet_reg; 896 }; 897 898 static int 899 lpcib_hpet_match(device_t parent, cfdata_t match, void *aux) 900 { 901 struct lpcib_hpet_attach_arg *arg = aux; 902 bus_space_tag_t tag; 903 bus_space_handle_t handle; 904 905 tag = arg->hpet_mem_t; 906 907 if (bus_space_map(tag, arg->hpet_reg, HPET_WINDOW_SIZE, 0, &handle)) { 908 aprint_verbose_dev(parent, "HPET window not mapped, skipping\n"); 909 return 0; 910 } 911 bus_space_unmap(tag, handle, HPET_WINDOW_SIZE); 912 913 return 1; 914 } 915 916 static int 917 lpcib_hpet_detach(device_t self, int flags) 918 { 919 struct hpet_softc *sc = device_private(self); 920 int rc; 921 922 if ((rc = hpet_detach(self, flags)) != 0) 923 return rc; 924 925 bus_space_unmap(sc->sc_memt, sc->sc_memh, HPET_WINDOW_SIZE); 926 927 return 0; 928 } 929 930 static void 931 lpcib_hpet_attach(device_t parent, device_t self, void *aux) 932 { 933 struct hpet_softc *sc = device_private(self); 934 struct lpcib_hpet_attach_arg *arg = aux; 935 936 aprint_naive("\n"); 937 aprint_normal("\n"); 938 939 sc->sc_memt = arg->hpet_mem_t; 940 941 if (bus_space_map(sc->sc_memt, arg->hpet_reg, HPET_WINDOW_SIZE, 0, 942 &sc->sc_memh)) { 943 aprint_error_dev(self, 944 "HPET memory window could not be mapped"); 945 return; 946 } 947 948 hpet_attach_subr(self); 949 } 950 951 CFATTACH_DECL_NEW(ichlpcib_hpet, sizeof(struct hpet_softc), lpcib_hpet_match, 952 lpcib_hpet_attach, lpcib_hpet_detach, NULL); 953 954 static void 955 lpcib_hpet_configure(device_t self) 956 { 957 struct lpcib_softc *sc = device_private(self); 958 struct lpcib_hpet_attach_arg arg; 959 uint32_t hpet_reg, val; 960 961 if (sc->sc_has_ich5_hpet) { 962 val = pci_conf_read(sc->sc_pcib.sc_pc, sc->sc_pcib.sc_tag, 963 LPCIB_PCI_GEN_CNTL); 964 switch (val & LPCIB_ICH5_HPTC_WIN_MASK) { 965 case LPCIB_ICH5_HPTC_0000: 966 hpet_reg = LPCIB_ICH5_HPTC_0000_BASE; 967 break; 968 case LPCIB_ICH5_HPTC_1000: 969 hpet_reg = LPCIB_ICH5_HPTC_1000_BASE; 970 break; 971 case LPCIB_ICH5_HPTC_2000: 972 hpet_reg = LPCIB_ICH5_HPTC_2000_BASE; 973 break; 974 case LPCIB_ICH5_HPTC_3000: 975 hpet_reg = LPCIB_ICH5_HPTC_3000_BASE; 976 break; 977 default: 978 return; 979 } 980 val |= sc->sc_hpet_reg | LPCIB_ICH5_HPTC_EN; 981 pci_conf_write(sc->sc_pcib.sc_pc, sc->sc_pcib.sc_tag, 982 LPCIB_PCI_GEN_CNTL, val); 983 } else if (sc->sc_has_rcba) { 984 val = bus_space_read_4(sc->sc_rcbat, sc->sc_rcbah, 985 LPCIB_RCBA_HPTC); 986 switch (val & LPCIB_RCBA_HPTC_WIN_MASK) { 987 case LPCIB_RCBA_HPTC_0000: 988 hpet_reg = LPCIB_RCBA_HPTC_0000_BASE; 989 break; 990 case LPCIB_RCBA_HPTC_1000: 991 hpet_reg = LPCIB_RCBA_HPTC_1000_BASE; 992 break; 993 case LPCIB_RCBA_HPTC_2000: 994 hpet_reg = LPCIB_RCBA_HPTC_2000_BASE; 995 break; 996 case LPCIB_RCBA_HPTC_3000: 997 hpet_reg = LPCIB_RCBA_HPTC_3000_BASE; 998 break; 999 default: 1000 return; 1001 } 1002 val |= LPCIB_RCBA_HPTC_EN; 1003 bus_space_write_4(sc->sc_rcbat, sc->sc_rcbah, LPCIB_RCBA_HPTC, 1004 val); 1005 } else { 1006 /* No HPET here */ 1007 return; 1008 } 1009 1010 arg.hpet_mem_t = sc->sc_pa.pa_memt; 1011 arg.hpet_reg = hpet_reg; 1012 1013 sc->sc_hpetbus = config_found_ia(self, "hpetichbus", &arg, NULL); 1014 } 1015 1016 static int 1017 lpcib_hpet_unconfigure(device_t self, int flags) 1018 { 1019 struct lpcib_softc *sc = device_private(self); 1020 int rc; 1021 1022 if (sc->sc_hpetbus != NULL && 1023 (rc = config_detach(sc->sc_hpetbus, flags)) != 0) 1024 return rc; 1025 1026 return 0; 1027 } 1028 #endif 1029 1030 #if NGPIO > 0 1031 static void 1032 lpcib_gpio_configure(device_t self) 1033 { 1034 struct lpcib_softc *sc = device_private(self); 1035 struct gpiobus_attach_args gba; 1036 pcireg_t gpio_cntl; 1037 uint32_t use, io, bit; 1038 int pin, shift, base_reg, cntl_reg, reg; 1039 1040 /* this implies ICH >= 6, and thus different mapreg */ 1041 if (sc->sc_has_rcba) { 1042 base_reg = LPCIB_PCI_GPIO_BASE_ICH6; 1043 cntl_reg = LPCIB_PCI_GPIO_CNTL_ICH6; 1044 } else { 1045 base_reg = LPCIB_PCI_GPIO_BASE; 1046 cntl_reg = LPCIB_PCI_GPIO_CNTL; 1047 } 1048 1049 gpio_cntl = pci_conf_read(sc->sc_pcib.sc_pc, sc->sc_pcib.sc_tag, 1050 cntl_reg); 1051 1052 /* Is GPIO enabled? */ 1053 if ((gpio_cntl & LPCIB_PCI_GPIO_CNTL_EN) == 0) 1054 return; 1055 1056 if (pci_mapreg_map(&sc->sc_pa, base_reg, PCI_MAPREG_TYPE_IO, 0, 1057 &sc->sc_gpio_iot, &sc->sc_gpio_ioh, 1058 NULL, &sc->sc_gpio_ios)) { 1059 aprint_error_dev(self, "can't map general purpose i/o space\n"); 1060 return; 1061 } 1062 1063 mutex_init(&sc->sc_gpio_mtx, MUTEX_DEFAULT, IPL_NONE); 1064 1065 for (pin = 0; pin < LPCIB_GPIO_NPINS; pin++) { 1066 sc->sc_gpio_pins[pin].pin_num = pin; 1067 1068 /* Read initial state */ 1069 reg = (pin < 32) ? LPCIB_GPIO_GPIO_USE_SEL : LPCIB_GPIO_GPIO_USE_SEL2; 1070 use = bus_space_read_4(sc->sc_gpio_iot, sc->sc_gpio_ioh, reg); 1071 reg = (pin < 32) ? LPCIB_GPIO_GP_IO_SEL : LPCIB_GPIO_GP_IO_SEL; 1072 io = bus_space_read_4(sc->sc_gpio_iot, sc->sc_gpio_ioh, 4); 1073 shift = pin % 32; 1074 bit = __BIT(shift); 1075 1076 if ((use & bit) != 0) { 1077 sc->sc_gpio_pins[pin].pin_caps = 1078 GPIO_PIN_INPUT | GPIO_PIN_OUTPUT; 1079 if (pin < 32) 1080 sc->sc_gpio_pins[pin].pin_caps |= 1081 GPIO_PIN_PULSATE; 1082 if ((io & bit) != 0) 1083 sc->sc_gpio_pins[pin].pin_flags = 1084 GPIO_PIN_INPUT; 1085 else 1086 sc->sc_gpio_pins[pin].pin_flags = 1087 GPIO_PIN_OUTPUT; 1088 } else 1089 sc->sc_gpio_pins[pin].pin_caps = 0; 1090 1091 if (lpcib_gpio_pin_read(sc, pin) == 0) 1092 sc->sc_gpio_pins[pin].pin_state = GPIO_PIN_LOW; 1093 else 1094 sc->sc_gpio_pins[pin].pin_state = GPIO_PIN_HIGH; 1095 1096 } 1097 1098 /* Create controller tag */ 1099 sc->sc_gpio_gc.gp_cookie = sc; 1100 sc->sc_gpio_gc.gp_pin_read = lpcib_gpio_pin_read; 1101 sc->sc_gpio_gc.gp_pin_write = lpcib_gpio_pin_write; 1102 sc->sc_gpio_gc.gp_pin_ctl = lpcib_gpio_pin_ctl; 1103 1104 memset(&gba, 0, sizeof(gba)); 1105 1106 gba.gba_gc = &sc->sc_gpio_gc; 1107 gba.gba_pins = sc->sc_gpio_pins; 1108 gba.gba_npins = LPCIB_GPIO_NPINS; 1109 1110 sc->sc_gpiobus = config_found_ia(self, "gpiobus", &gba, gpiobus_print); 1111 } 1112 1113 static int 1114 lpcib_gpio_unconfigure(device_t self, int flags) 1115 { 1116 struct lpcib_softc *sc = device_private(self); 1117 int rc; 1118 1119 if (sc->sc_gpiobus != NULL && 1120 (rc = config_detach(sc->sc_gpiobus, flags)) != 0) 1121 return rc; 1122 1123 mutex_destroy(&sc->sc_gpio_mtx); 1124 1125 bus_space_unmap(sc->sc_gpio_iot, sc->sc_gpio_ioh, sc->sc_gpio_ios); 1126 1127 return 0; 1128 } 1129 1130 static int 1131 lpcib_gpio_pin_read(void *arg, int pin) 1132 { 1133 struct lpcib_softc *sc = arg; 1134 uint32_t data; 1135 int reg, shift; 1136 1137 reg = (pin < 32) ? LPCIB_GPIO_GP_LVL : LPCIB_GPIO_GP_LVL2; 1138 shift = pin % 32; 1139 1140 mutex_enter(&sc->sc_gpio_mtx); 1141 data = bus_space_read_4(sc->sc_gpio_iot, sc->sc_gpio_ioh, reg); 1142 mutex_exit(&sc->sc_gpio_mtx); 1143 1144 return (__SHIFTOUT(data, __BIT(shift)) ? GPIO_PIN_HIGH : GPIO_PIN_LOW); 1145 } 1146 1147 static void 1148 lpcib_gpio_pin_write(void *arg, int pin, int value) 1149 { 1150 struct lpcib_softc *sc = arg; 1151 uint32_t data; 1152 int reg, shift; 1153 1154 reg = (pin < 32) ? LPCIB_GPIO_GP_LVL : LPCIB_GPIO_GP_LVL2; 1155 shift = pin % 32; 1156 1157 mutex_enter(&sc->sc_gpio_mtx); 1158 1159 data = bus_space_read_4(sc->sc_gpio_iot, sc->sc_gpio_ioh, reg); 1160 1161 if(value) 1162 data |= __BIT(shift); 1163 else 1164 data &= ~__BIT(shift); 1165 1166 bus_space_write_4(sc->sc_gpio_iot, sc->sc_gpio_ioh, reg, data); 1167 1168 mutex_exit(&sc->sc_gpio_mtx); 1169 } 1170 1171 static void 1172 lpcib_gpio_pin_ctl(void *arg, int pin, int flags) 1173 { 1174 struct lpcib_softc *sc = arg; 1175 uint32_t data; 1176 int reg, shift; 1177 1178 shift = pin % 32; 1179 reg = (pin < 32) ? LPCIB_GPIO_GP_IO_SEL : LPCIB_GPIO_GP_IO_SEL2; 1180 1181 mutex_enter(&sc->sc_gpio_mtx); 1182 1183 data = bus_space_read_4(sc->sc_gpio_iot, sc->sc_gpio_ioh, reg); 1184 1185 if (flags & GPIO_PIN_OUTPUT) 1186 data &= ~__BIT(shift); 1187 1188 if (flags & GPIO_PIN_INPUT) 1189 data |= __BIT(shift); 1190 1191 bus_space_write_4(sc->sc_gpio_iot, sc->sc_gpio_ioh, reg, data); 1192 1193 1194 if (pin < 32) { 1195 reg = LPCIB_GPIO_GPO_BLINK; 1196 data = bus_space_read_4(sc->sc_gpio_iot, sc->sc_gpio_ioh, reg); 1197 1198 if (flags & GPIO_PIN_PULSATE) 1199 data |= __BIT(shift); 1200 else 1201 data &= ~__BIT(shift); 1202 1203 bus_space_write_4(sc->sc_gpio_iot, sc->sc_gpio_ioh, reg, data); 1204 } 1205 1206 mutex_exit(&sc->sc_gpio_mtx); 1207 } 1208 #endif 1209