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