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