1 /* $NetBSD: ichlpcib.c,v 1.62 2024/12/18 18:18:30 hans 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 * the gpio interface, hpet timer, hardware random number generator, 39 * and the power management timer. 40 */ 41 42 #include <sys/cdefs.h> 43 __KERNEL_RCSID(0, "$NetBSD: ichlpcib.c,v 1.62 2024/12/18 18:18:30 hans Exp $"); 44 45 #include <sys/types.h> 46 #include <sys/param.h> 47 #include <sys/systm.h> 48 #include <sys/device.h> 49 #include <sys/sysctl.h> 50 #include <sys/timetc.h> 51 #include <sys/gpio.h> 52 #include <sys/bus.h> 53 54 #include <dev/pci/pcivar.h> 55 #include <dev/pci/pcireg.h> 56 #include <dev/pci/pcidevs.h> 57 58 #include <dev/gpio/gpiovar.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 <arch/x86/pci/tco.h> 67 68 #include "pcibvar.h" 69 #include "gpio.h" 70 #include "fwhrng.h" 71 72 #define LPCIB_GPIO_NPINS 64 73 74 struct lpcib_softc { 75 /* we call pcibattach() which assumes this starts like this: */ 76 struct pcib_softc sc_pcib; 77 78 struct pci_attach_args sc_pa; 79 int sc_has_rcba; 80 int sc_has_ich5_hpet; 81 82 /* RCBA */ 83 bus_space_tag_t sc_rcbat; 84 bus_space_handle_t sc_rcbah; 85 pcireg_t sc_rcba_reg; 86 87 /* Power management variables. */ 88 bus_space_tag_t sc_pmt; 89 bus_space_handle_t sc_pmh; 90 bus_size_t sc_iosize; 91 92 /* TCO variables. */ 93 bus_space_tag_t sc_tcot; 94 bus_space_handle_t sc_tcoh; 95 bus_size_t sc_tcosz; 96 97 /* HPET variables. */ 98 uint32_t sc_hpet_reg; 99 100 #if NGPIO > 0 101 device_t sc_gpiobus; 102 kmutex_t sc_gpio_mtx; 103 bus_space_tag_t sc_gpio_iot; 104 bus_space_handle_t sc_gpio_ioh; 105 bus_size_t sc_gpio_ios; 106 struct gpio_chipset_tag sc_gpio_gc; 107 gpio_pin_t sc_gpio_pins[LPCIB_GPIO_NPINS]; 108 #endif 109 110 #if NFWHRNG > 0 111 device_t sc_fwhbus; 112 #endif 113 114 /* Speedstep */ 115 pcireg_t sc_pmcon_orig; 116 117 /* Power management */ 118 pcireg_t sc_pirq[2]; 119 pcireg_t sc_pmcon; 120 pcireg_t sc_fwhsel2; 121 122 /* Child devices */ 123 device_t sc_tco; 124 device_t sc_hpetbus; 125 acpipmtimer_t sc_pmtimer; 126 pcireg_t sc_acpi_cntl; 127 128 struct sysctllog *sc_log; 129 }; 130 131 static int lpcibmatch(device_t, cfdata_t, void *); 132 static void lpcibattach(device_t, device_t, void *); 133 static int lpcibdetach(device_t, int); 134 static void lpcibchilddet(device_t, device_t); 135 static int lpcibrescan(device_t, const char *, const int *); 136 static bool lpcib_suspend(device_t, const pmf_qual_t *); 137 static bool lpcib_resume(device_t, const pmf_qual_t *); 138 static bool lpcib_shutdown(device_t, int); 139 140 static void pmtimer_configure(device_t); 141 static void pmtimer_unconfigure(device_t, int); 142 143 static void tcotimer_configure(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 151 #if NGPIO > 0 152 static void lpcib_gpio_configure(device_t); 153 static void lpcib_gpio_unconfigure(device_t); 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 #if NFWHRNG > 0 160 static void lpcib_fwh_configure(device_t); 161 #endif 162 163 struct lpcib_softc *speedstep_cookie; /* XXX */ 164 165 CFATTACH_DECL2_NEW(ichlpcib, sizeof(struct lpcib_softc), 166 lpcibmatch, lpcibattach, lpcibdetach, NULL, lpcibrescan, lpcibchilddet); 167 168 static const struct lpcib_device { 169 pcireg_t vendor, product; 170 int has_rcba; 171 int has_ich5_hpet; 172 } lpcib_devices[] = { 173 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_3400_LPC, 1, 0 }, 174 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_3420_LPC, 1, 0 }, 175 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_3450_LPC, 1, 0 }, 176 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_6300ESB_LPC, 1, 0 }, 177 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_63XXESB_LPC, 1, 0 }, 178 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801AA_LPC, 0, 0 }, 179 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801AB_LPC, 0, 0 }, 180 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801BA_LPC, 0, 0 }, 181 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801BAM_LPC, 0, 0 }, 182 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801CA_LPC, 0, 0 }, 183 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801CAM_LPC, 0, 0 }, 184 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801DB_LPC, 0, 0 }, 185 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801DBM_LPC, 0, 0 }, 186 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801E_LPC, 0, 1 }, 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_82801GH_LPC, 1, 0 }, 193 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801GHM_LPC, 1, 0 }, 194 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801H_LPC, 1, 0 }, 195 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801HEM_LPC, 1, 0 }, 196 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801HH_LPC, 1, 0 }, 197 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801HO_LPC, 1, 0 }, 198 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801HBM_LPC, 1, 0 }, 199 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801IB_LPC, 1, 0 }, 200 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801IH_LPC, 1, 0 }, 201 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801IM_LPC, 1, 0 }, 202 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801IO_LPC, 1, 0 }, 203 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801IR_LPC, 1, 0 }, 204 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801IEM_LPC, 1, 0 }, 205 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801JD_LPC, 1, 0 }, 206 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801JDO_LPC, 1, 0 }, 207 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801JIB_LPC, 1, 0 }, 208 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801JIR_LPC, 1, 0 }, 209 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_C202_LPC, 1, 0 }, 210 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_C204_LPC, 1, 0 }, 211 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_C206_LPC, 1, 0 }, 212 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_C216_LPC, 1, 0 }, 213 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_NM10_LPC, 1, 0 }, 214 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_H55_LPC, 1, 0 }, 215 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_H57_LPC, 1, 0 }, 216 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_HM55_LPC, 1, 0 }, 217 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_HM57_LPC, 1, 0 }, 218 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_P55_LPC, 1, 0 }, 219 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_PM55_LPC, 1, 0 }, 220 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_Q57_LPC, 1, 0 }, 221 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_QM57_LPC, 1, 0 }, 222 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_QS57_LPC, 1, 0 }, 223 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_B65_LPC, 1, 0 }, 224 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_H61_LPC, 1, 0 }, 225 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_H67_LPC, 1, 0 }, 226 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_HM65_LPC, 1, 0 }, 227 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_HM67_LPC, 1, 0 }, 228 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_P67_LPC, 1, 0 }, 229 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_Q65_LPC, 1, 0 }, 230 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_Q67_LPC, 1, 0 }, 231 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_QM67_LPC, 1, 0 }, 232 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_QS67_LPC, 1, 0 }, 233 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_UM67_LPC, 1, 0 }, 234 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_Z68_LPC, 1, 0 }, 235 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_B75_LPC, 1, 0 }, 236 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_H77_LPC, 1, 0 }, 237 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_MOBILE_HM70_LPC, 1, 0 }, 238 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_MOBILE_HM75_LPC, 1, 0 }, 239 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_MOBILE_HM76_LPC, 1, 0 }, 240 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_MOBILE_HM77_LPC, 1, 0 }, 241 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_MOBILE_QM77_LPC, 1, 0 }, 242 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_MOBILE_QS77_LPC, 1, 0 }, 243 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_MOBILE_UM77_LPC, 1, 0 }, 244 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_NM70_LPC, 1, 0 }, 245 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_Q75_LPC, 1, 0 }, 246 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_Q77_LPC, 1, 0 }, 247 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_Z75_LPC, 1, 0 }, 248 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_Z77_LPC, 1, 0 }, 249 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_Z87_LPC, 1, 0 }, 250 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_Z85_LPC, 1, 0 }, 251 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_HM86_LPC, 1, 0 }, 252 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_H87_LPC, 1, 0 }, 253 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_HM87_LPC, 1, 0 }, 254 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_Q85_LPC, 1, 0 }, 255 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_Q87_LPC, 1, 0 }, 256 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_QM87_LPC, 1, 0 }, 257 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_B85_LPC, 1, 0 }, 258 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_H97_LPC, 1, 0 }, 259 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_Z97_LPC, 1, 0 }, 260 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_X99_LPC, 1, 0 }, 261 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_X99_LPC_2, 1, 0 }, 262 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_CORE5G_M_LPC_4, 1, 0 }, 263 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_CORE5G_M_LPC_7, 1, 0 }, 264 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_C222_LPC, 1, 0 }, 265 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_C224_LPC, 1, 0 }, 266 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_C226_LPC, 1, 0 }, 267 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_H81_LPC, 1, 0 }, 268 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_C600_LPC, 1, 0 }, 269 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_DH89XXCC_LPC, 1, 0 }, 270 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_DH89XXCL_LPC, 1, 0 }, 271 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_BSW_PCU_LPC, 0, 1 }, 272 #if 0 273 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_C2000_PCU_1, 1, 0 }, 274 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_C2000_PCU_2, 1, 0 }, 275 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_C2000_PCU_3, 1, 0 }, 276 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_C2000_PCU_4, 1, 0 }, 277 #endif 278 279 { 0, 0, 0, 0 }, 280 }; 281 282 /* 283 * Allow user to enable GPIO functionality if they really need it. The 284 * vast majority of systems with an ICH should not expose GPIO to the 285 * kernel or user. In at least one instance the gpio_resume() handler 286 * on ICH GPIO was found to sabotage S3 suspend/resume. 287 */ 288 int ichlpcib_gpio_disable = 1; 289 290 /* 291 * Autoconf callbacks. 292 */ 293 static int 294 lpcibmatch(device_t parent, cfdata_t match, void *aux) 295 { 296 struct pci_attach_args *pa = aux; 297 const struct lpcib_device *lpcib_dev; 298 299 /* We are ISA bridge, of course */ 300 if (PCI_CLASS(pa->pa_class) != PCI_CLASS_BRIDGE || 301 PCI_SUBCLASS(pa->pa_class) != PCI_SUBCLASS_BRIDGE_ISA) 302 return 0; 303 304 for (lpcib_dev = lpcib_devices; lpcib_dev->vendor; ++lpcib_dev) { 305 if (PCI_VENDOR(pa->pa_id) == lpcib_dev->vendor && 306 PCI_PRODUCT(pa->pa_id) == lpcib_dev->product) 307 return 10; 308 } 309 310 return 0; 311 } 312 313 static void 314 lpcibattach(device_t parent, device_t self, void *aux) 315 { 316 struct pci_attach_args *pa = aux; 317 struct lpcib_softc *sc = device_private(self); 318 const struct lpcib_device *lpcib_dev; 319 pcireg_t pmbase; 320 321 sc->sc_pa = *pa; 322 323 for (lpcib_dev = lpcib_devices; lpcib_dev->vendor; ++lpcib_dev) { 324 if (PCI_VENDOR(pa->pa_id) != lpcib_dev->vendor || 325 PCI_PRODUCT(pa->pa_id) != lpcib_dev->product) 326 continue; 327 sc->sc_has_rcba = lpcib_dev->has_rcba; 328 sc->sc_has_ich5_hpet = lpcib_dev->has_ich5_hpet; 329 break; 330 } 331 332 pcibattach(parent, self, aux); 333 334 /* 335 * Part of our I/O registers are used as ACPI PM regs. 336 * Since our ACPI subsystem accesses the I/O space directly so far, 337 * we do not have to bother bus_space I/O map confliction. 338 * 339 * The PMBASE register is alike PCI BAR but not completely compatible 340 * with it. The PMBASE define the base address and the type but 341 * not describe the size. The value of the register may be lower 342 * than LPCIB_PCI_PM_SIZE. It makes impossible to use 343 * pci_mapreg_submap() because the function does range check. 344 */ 345 sc->sc_pmt = pa->pa_iot; 346 pmbase = pci_conf_read(pa->pa_pc, pa->pa_tag, LPCIB_PCI_PMBASE); 347 if (bus_space_map(sc->sc_pmt, PCI_MAPREG_IO_ADDR(pmbase), 348 LPCIB_PCI_PM_SIZE, 0, &sc->sc_pmh) != 0) { 349 aprint_error_dev(self, 350 "can't map power management i/o space\n"); 351 return; 352 } 353 354 if (bus_space_subregion(sc->sc_pmt, sc->sc_pmh, PMC_TCO_BASE, 355 TCO_REGSIZE, &sc->sc_tcoh)) { 356 aprint_error_dev(self, "can't map TCO space\n"); 357 } else { 358 sc->sc_tcot = sc->sc_pmt; 359 } 360 361 sc->sc_pmcon_orig = pci_conf_read(sc->sc_pcib.sc_pc, sc->sc_pcib.sc_tag, 362 LPCIB_PCI_GEN_PMCON_1); 363 364 /* For ICH6 and later, always enable RCBA */ 365 if (sc->sc_has_rcba) { 366 pcireg_t rcba; 367 368 sc->sc_rcbat = sc->sc_pa.pa_memt; 369 370 rcba = pci_conf_read(sc->sc_pcib.sc_pc, sc->sc_pcib.sc_tag, 371 LPCIB_RCBA); 372 if ((rcba & LPCIB_RCBA_EN) == 0) { 373 aprint_error_dev(self, "RCBA is not enabled\n"); 374 return; 375 } 376 rcba &= ~LPCIB_RCBA_EN; 377 378 if (bus_space_map(sc->sc_rcbat, rcba, LPCIB_RCBA_SIZE, 0, 379 &sc->sc_rcbah)) { 380 aprint_error_dev(self, "RCBA could not be mapped\n"); 381 return; 382 } 383 } 384 385 /* Set up the power management timer. */ 386 pmtimer_configure(self); 387 388 /* Set up the TCO (watchdog). */ 389 tcotimer_configure(self); 390 391 /* Set up SpeedStep. */ 392 speedstep_configure(self); 393 394 /* Set up HPET. */ 395 lpcib_hpet_configure(self); 396 397 #if NGPIO > 0 398 /* Set up GPIO */ 399 lpcib_gpio_configure(self); 400 #endif 401 402 #if NFWHRNG > 0 403 lpcib_fwh_configure(self); 404 #endif 405 406 /* Install power handler */ 407 if (!pmf_device_register1(self, lpcib_suspend, lpcib_resume, 408 lpcib_shutdown)) 409 aprint_error_dev(self, "couldn't establish power handler\n"); 410 } 411 412 static void 413 lpcibchilddet(device_t self, device_t child) 414 { 415 struct lpcib_softc *sc = device_private(self); 416 uint32_t val; 417 418 #if NFWHRNG > 0 419 if (sc->sc_fwhbus == child) { 420 sc->sc_fwhbus = NULL; 421 return; 422 } 423 #endif 424 #if NGPIO > 0 425 if (sc->sc_gpiobus == child) { 426 sc->sc_gpiobus = NULL; 427 return; 428 } 429 #endif 430 if (sc->sc_tco == child) { 431 sc->sc_tco = NULL; 432 return; 433 } 434 435 if (sc->sc_hpetbus != child) { 436 pcibchilddet(self, child); 437 return; 438 } 439 sc->sc_hpetbus = NULL; 440 if (sc->sc_has_ich5_hpet) { 441 val = pci_conf_read(sc->sc_pcib.sc_pc, sc->sc_pcib.sc_tag, 442 LPCIB_PCI_GEN_CNTL); 443 switch (val & LPCIB_ICH5_HPTC_WIN_MASK) { 444 case LPCIB_ICH5_HPTC_0000: 445 case LPCIB_ICH5_HPTC_1000: 446 case LPCIB_ICH5_HPTC_2000: 447 case LPCIB_ICH5_HPTC_3000: 448 break; 449 default: 450 return; 451 } 452 val &= ~LPCIB_ICH5_HPTC_EN; 453 pci_conf_write(sc->sc_pcib.sc_pc, sc->sc_pcib.sc_tag, 454 LPCIB_PCI_GEN_CNTL, val); 455 } else if (sc->sc_has_rcba) { 456 val = bus_space_read_4(sc->sc_rcbat, sc->sc_rcbah, 457 LPCIB_RCBA_HPTC); 458 switch (val & LPCIB_RCBA_HPTC_WIN_MASK) { 459 case LPCIB_RCBA_HPTC_0000: 460 case LPCIB_RCBA_HPTC_1000: 461 case LPCIB_RCBA_HPTC_2000: 462 case LPCIB_RCBA_HPTC_3000: 463 break; 464 default: 465 return; 466 } 467 val &= ~LPCIB_RCBA_HPTC_EN; 468 bus_space_write_4(sc->sc_rcbat, sc->sc_rcbah, LPCIB_RCBA_HPTC, 469 val); 470 } 471 } 472 473 static int 474 lpcibrescan(device_t self, const char *ifattr, const int *locators) 475 { 476 struct lpcib_softc *sc = device_private(self); 477 478 if (ifattr_match(ifattr, "tcoichbus") && sc->sc_tco == NULL) 479 tcotimer_configure(self); 480 481 #if NFWHRNG > 0 482 if (ifattr_match(ifattr, "fwhichbus") && sc->sc_fwhbus == NULL) 483 lpcib_fwh_configure(self); 484 #endif 485 486 if (ifattr_match(ifattr, "hpetichbus") && sc->sc_hpetbus == NULL) 487 lpcib_hpet_configure(self); 488 489 #if NGPIO > 0 490 if (ifattr_match(ifattr, "gpiobus") && sc->sc_gpiobus == NULL) 491 lpcib_gpio_configure(self); 492 #endif 493 494 return pcibrescan(self, ifattr, locators); 495 } 496 497 static int 498 lpcibdetach(device_t self, int flags) 499 { 500 struct lpcib_softc *sc = device_private(self); 501 int error; 502 503 error = config_detach_children(self, flags); 504 if (error) 505 return error; 506 507 pmf_device_deregister(self); 508 509 #if NGPIO > 0 510 lpcib_gpio_unconfigure(self); 511 #endif 512 513 /* Set up SpeedStep. */ 514 speedstep_unconfigure(self); 515 516 pmtimer_unconfigure(self, flags); 517 518 if (sc->sc_has_rcba) 519 bus_space_unmap(sc->sc_rcbat, sc->sc_rcbah, LPCIB_RCBA_SIZE); 520 521 bus_space_unmap(sc->sc_pmt, sc->sc_pmh, sc->sc_iosize); 522 523 error = pcibdetach(self, flags); 524 KASSERTMSG(error == 0, "error=%d", error); 525 526 return 0; 527 } 528 529 static bool 530 lpcib_shutdown(device_t dv, int howto) 531 { 532 struct lpcib_softc *sc = device_private(dv); 533 534 pci_conf_write(sc->sc_pcib.sc_pc, sc->sc_pcib.sc_tag, 535 LPCIB_PCI_GEN_PMCON_1, sc->sc_pmcon_orig); 536 537 return true; 538 } 539 540 static bool 541 lpcib_suspend(device_t dv, const pmf_qual_t *qual) 542 { 543 struct lpcib_softc *sc = device_private(dv); 544 pci_chipset_tag_t pc = sc->sc_pcib.sc_pc; 545 pcitag_t tag = sc->sc_pcib.sc_tag; 546 547 /* capture PIRQ routing control registers */ 548 sc->sc_pirq[0] = pci_conf_read(pc, tag, LPCIB_PCI_PIRQA_ROUT); 549 sc->sc_pirq[1] = pci_conf_read(pc, tag, LPCIB_PCI_PIRQE_ROUT); 550 551 sc->sc_pmcon = pci_conf_read(pc, tag, LPCIB_PCI_GEN_PMCON_1); 552 sc->sc_fwhsel2 = pci_conf_read(pc, tag, LPCIB_PCI_GEN_STA); 553 554 if (sc->sc_has_rcba) { 555 sc->sc_rcba_reg = pci_conf_read(pc, tag, LPCIB_RCBA); 556 sc->sc_hpet_reg = bus_space_read_4(sc->sc_rcbat, sc->sc_rcbah, 557 LPCIB_RCBA_HPTC); 558 } else if (sc->sc_has_ich5_hpet) { 559 sc->sc_hpet_reg = pci_conf_read(pc, tag, LPCIB_PCI_GEN_CNTL); 560 } 561 562 return true; 563 } 564 565 static bool 566 lpcib_resume(device_t dv, const pmf_qual_t *qual) 567 { 568 struct lpcib_softc *sc = device_private(dv); 569 pci_chipset_tag_t pc = sc->sc_pcib.sc_pc; 570 pcitag_t tag = sc->sc_pcib.sc_tag; 571 572 /* restore PIRQ routing control registers */ 573 pci_conf_write(pc, tag, LPCIB_PCI_PIRQA_ROUT, sc->sc_pirq[0]); 574 pci_conf_write(pc, tag, LPCIB_PCI_PIRQE_ROUT, sc->sc_pirq[1]); 575 576 pci_conf_write(pc, tag, LPCIB_PCI_GEN_PMCON_1, sc->sc_pmcon); 577 pci_conf_write(pc, tag, LPCIB_PCI_GEN_STA, sc->sc_fwhsel2); 578 579 if (sc->sc_has_rcba) { 580 pci_conf_write(pc, tag, LPCIB_RCBA, sc->sc_rcba_reg); 581 bus_space_write_4(sc->sc_rcbat, sc->sc_rcbah, LPCIB_RCBA_HPTC, 582 sc->sc_hpet_reg); 583 } else if (sc->sc_has_ich5_hpet) { 584 pci_conf_write(pc, tag, LPCIB_PCI_GEN_CNTL, sc->sc_hpet_reg); 585 } 586 587 return true; 588 } 589 590 /* 591 * Initialize the power management timer. 592 */ 593 static void 594 pmtimer_configure(device_t self) 595 { 596 struct lpcib_softc *sc = device_private(self); 597 pcireg_t control; 598 599 /* 600 * Check if power management I/O space is enabled and enable the ACPI_EN 601 * bit if it's disabled. 602 */ 603 control = pci_conf_read(sc->sc_pcib.sc_pc, sc->sc_pcib.sc_tag, 604 LPCIB_PCI_ACPI_CNTL); 605 sc->sc_acpi_cntl = control; 606 if ((control & LPCIB_PCI_ACPI_CNTL_EN) == 0) { 607 control |= LPCIB_PCI_ACPI_CNTL_EN; 608 pci_conf_write(sc->sc_pcib.sc_pc, sc->sc_pcib.sc_tag, 609 LPCIB_PCI_ACPI_CNTL, control); 610 } 611 612 /* Attach our PM timer with the generic acpipmtimer function */ 613 sc->sc_pmtimer = acpipmtimer_attach(self, sc->sc_pmt, sc->sc_pmh, 614 PMC_PM1_TMR, 0); 615 } 616 617 static void 618 pmtimer_unconfigure(device_t self, int flags) 619 { 620 struct lpcib_softc *sc = device_private(self); 621 int error __diagused; 622 623 if (sc->sc_pmtimer != NULL) { 624 error = acpipmtimer_detach(sc->sc_pmtimer, flags); 625 KASSERTMSG(error == 0, "error=%d", error); 626 } 627 628 pci_conf_write(sc->sc_pcib.sc_pc, sc->sc_pcib.sc_tag, 629 LPCIB_PCI_ACPI_CNTL, sc->sc_acpi_cntl); 630 } 631 632 /* 633 * Configure the watchdog timer. 634 */ 635 static void 636 tcotimer_configure(device_t self) 637 { 638 struct lpcib_softc *sc = device_private(self); 639 struct tco_attach_args arg; 640 641 if (sc->sc_has_rcba) 642 arg.ta_version = TCO_VERSION_RCBA; 643 else 644 arg.ta_version = TCO_VERSION_PCIB; 645 arg.ta_pmt = sc->sc_pmt; 646 arg.ta_pmh = sc->sc_pmh; 647 arg.ta_rcbat = sc->sc_rcbat; 648 arg.ta_rcbah = sc->sc_rcbah; 649 arg.ta_pcib = &sc->sc_pcib; 650 arg.ta_tcot = sc->sc_tcot; 651 arg.ta_tcoh = sc->sc_tcoh; 652 653 sc->sc_tco = config_found(self, &arg, NULL, 654 CFARGS(.iattr = "tcoichbus")); 655 } 656 657 658 /* 659 * Intel ICH SpeedStep support. 660 */ 661 #define SS_READ(sc, reg) \ 662 bus_space_read_1((sc)->sc_pmt, (sc)->sc_pmh, (reg)) 663 #define SS_WRITE(sc, reg, val) \ 664 bus_space_write_1((sc)->sc_pmt, (sc)->sc_pmh, (reg), (val)) 665 666 /* 667 * Linux driver says that SpeedStep on older chipsets cause 668 * lockups on Dell Inspiron 8000 and 8100. 669 * It should also not be enabled on systems with the 82855GM 670 * Hub, which typically have an EST-enabled CPU. 671 */ 672 static int 673 speedstep_bad_hb_check(const struct pci_attach_args *pa) 674 { 675 676 if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_INTEL_82815_FULL_HUB && 677 PCI_REVISION(pa->pa_class) < 5) 678 return 1; 679 680 if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_INTEL_82855GM_MCH) 681 return 1; 682 683 return 0; 684 } 685 686 static void 687 speedstep_configure(device_t self) 688 { 689 struct lpcib_softc *sc = device_private(self); 690 const struct sysctlnode *node, *ssnode; 691 int rv; 692 693 /* Supported on ICH2-M, ICH3-M and ICH4-M. */ 694 if (PCI_PRODUCT(sc->sc_pa.pa_id) == PCI_PRODUCT_INTEL_82801DBM_LPC || 695 PCI_PRODUCT(sc->sc_pa.pa_id) == PCI_PRODUCT_INTEL_82801CAM_LPC || 696 (PCI_PRODUCT(sc->sc_pa.pa_id) == PCI_PRODUCT_INTEL_82801BAM_LPC && 697 pci_find_device(&sc->sc_pa, speedstep_bad_hb_check) == 0)) { 698 pcireg_t pmcon; 699 700 /* Enable SpeedStep if it isn't already enabled. */ 701 pmcon = pci_conf_read(sc->sc_pcib.sc_pc, sc->sc_pcib.sc_tag, 702 LPCIB_PCI_GEN_PMCON_1); 703 if ((pmcon & LPCIB_PCI_GEN_PMCON_1_SS_EN) == 0) 704 pci_conf_write(sc->sc_pcib.sc_pc, sc->sc_pcib.sc_tag, 705 LPCIB_PCI_GEN_PMCON_1, 706 pmcon | LPCIB_PCI_GEN_PMCON_1_SS_EN); 707 708 /* Put in machdep.speedstep_state (0 for low, 1 for high). */ 709 if ((rv = sysctl_createv(&sc->sc_log, 0, NULL, &node, 710 CTLFLAG_PERMANENT, CTLTYPE_NODE, "machdep", NULL, 711 NULL, 0, NULL, 0, CTL_MACHDEP, CTL_EOL)) != 0) 712 goto err; 713 714 /* CTLFLAG_ANYWRITE? kernel option like EST? */ 715 if ((rv = sysctl_createv(&sc->sc_log, 0, &node, &ssnode, 716 CTLFLAG_READWRITE, CTLTYPE_INT, "speedstep_state", NULL, 717 speedstep_sysctl_helper, 0, NULL, 0, CTL_CREATE, 718 CTL_EOL)) != 0) 719 goto err; 720 721 /* XXX save the sc for IO tag/handle */ 722 speedstep_cookie = sc; 723 aprint_verbose_dev(self, "SpeedStep enabled\n"); 724 } 725 726 return; 727 728 err: 729 aprint_normal("%s: sysctl_createv failed (rv = %d)\n", __func__, rv); 730 } 731 732 static void 733 speedstep_unconfigure(device_t self) 734 { 735 struct lpcib_softc *sc = device_private(self); 736 737 sysctl_teardown(&sc->sc_log); 738 pci_conf_write(sc->sc_pcib.sc_pc, sc->sc_pcib.sc_tag, 739 LPCIB_PCI_GEN_PMCON_1, sc->sc_pmcon_orig); 740 741 speedstep_cookie = NULL; 742 } 743 744 /* 745 * get/set the SpeedStep state: 0 == low power, 1 == high power. 746 */ 747 static int 748 speedstep_sysctl_helper(SYSCTLFN_ARGS) 749 { 750 struct sysctlnode node; 751 struct lpcib_softc *sc = speedstep_cookie; 752 uint8_t state, state2; 753 int ostate, nstate, s, error = 0; 754 755 /* 756 * We do the dance with spl's to avoid being at high ipl during 757 * sysctl_lookup() which can both copyin and copyout. 758 */ 759 s = splserial(); 760 state = SS_READ(sc, PMC_PM_SS_CNTL); 761 splx(s); 762 if ((state & PMC_PM_SS_STATE_LOW) == 0) 763 ostate = 1; 764 else 765 ostate = 0; 766 nstate = ostate; 767 768 node = *rnode; 769 node.sysctl_data = &nstate; 770 771 error = sysctl_lookup(SYSCTLFN_CALL(&node)); 772 if (error || newp == NULL) 773 goto out; 774 775 /* Only two states are available */ 776 if (nstate != 0 && nstate != 1) { 777 error = EINVAL; 778 goto out; 779 } 780 781 s = splserial(); 782 state2 = SS_READ(sc, PMC_PM_SS_CNTL); 783 if ((state2 & PMC_PM_SS_STATE_LOW) == 0) 784 ostate = 1; 785 else 786 ostate = 0; 787 788 if (ostate != nstate) { 789 uint8_t cntl; 790 791 if (nstate == 0) 792 state2 |= PMC_PM_SS_STATE_LOW; 793 else 794 state2 &= ~PMC_PM_SS_STATE_LOW; 795 796 /* 797 * Must disable bus master arbitration during the change. 798 */ 799 cntl = SS_READ(sc, PMC_PM_CTRL); 800 SS_WRITE(sc, PMC_PM_CTRL, cntl | PMC_PM_SS_CNTL_ARB_DIS); 801 SS_WRITE(sc, PMC_PM_SS_CNTL, state2); 802 SS_WRITE(sc, PMC_PM_CTRL, cntl); 803 } 804 splx(s); 805 out: 806 return error; 807 } 808 809 static void 810 lpcib_hpet_configure(device_t self) 811 { 812 struct lpcib_softc *sc = device_private(self); 813 struct lpcib_hpet_attach_args arg; 814 uint32_t hpet_reg, val; 815 816 if (sc->sc_has_ich5_hpet) { 817 val = pci_conf_read(sc->sc_pcib.sc_pc, sc->sc_pcib.sc_tag, 818 LPCIB_PCI_GEN_CNTL); 819 switch (val & LPCIB_ICH5_HPTC_WIN_MASK) { 820 case LPCIB_ICH5_HPTC_0000: 821 hpet_reg = LPCIB_ICH5_HPTC_0000_BASE; 822 break; 823 case LPCIB_ICH5_HPTC_1000: 824 hpet_reg = LPCIB_ICH5_HPTC_1000_BASE; 825 break; 826 case LPCIB_ICH5_HPTC_2000: 827 hpet_reg = LPCIB_ICH5_HPTC_2000_BASE; 828 break; 829 case LPCIB_ICH5_HPTC_3000: 830 hpet_reg = LPCIB_ICH5_HPTC_3000_BASE; 831 break; 832 default: 833 return; 834 } 835 val |= sc->sc_hpet_reg | LPCIB_ICH5_HPTC_EN; 836 pci_conf_write(sc->sc_pcib.sc_pc, sc->sc_pcib.sc_tag, 837 LPCIB_PCI_GEN_CNTL, val); 838 } else if (sc->sc_has_rcba) { 839 val = bus_space_read_4(sc->sc_rcbat, sc->sc_rcbah, 840 LPCIB_RCBA_HPTC); 841 switch (val & LPCIB_RCBA_HPTC_WIN_MASK) { 842 case LPCIB_RCBA_HPTC_0000: 843 hpet_reg = LPCIB_RCBA_HPTC_0000_BASE; 844 break; 845 case LPCIB_RCBA_HPTC_1000: 846 hpet_reg = LPCIB_RCBA_HPTC_1000_BASE; 847 break; 848 case LPCIB_RCBA_HPTC_2000: 849 hpet_reg = LPCIB_RCBA_HPTC_2000_BASE; 850 break; 851 case LPCIB_RCBA_HPTC_3000: 852 hpet_reg = LPCIB_RCBA_HPTC_3000_BASE; 853 break; 854 default: 855 return; 856 } 857 val |= LPCIB_RCBA_HPTC_EN; 858 bus_space_write_4(sc->sc_rcbat, sc->sc_rcbah, LPCIB_RCBA_HPTC, 859 val); 860 } else { 861 /* No HPET here */ 862 return; 863 } 864 865 arg.hpet_mem_t = sc->sc_pa.pa_memt; 866 arg.hpet_reg = hpet_reg; 867 868 sc->sc_hpetbus = config_found(self, &arg, NULL, 869 CFARGS(.iattr = "hpetichbus")); 870 } 871 872 #if NGPIO > 0 873 static void 874 lpcib_gpio_configure(device_t self) 875 { 876 struct lpcib_softc *sc = device_private(self); 877 struct gpiobus_attach_args gba; 878 pcireg_t gpio_cntl; 879 uint32_t use, io, bit; 880 int pin, shift, base_reg, cntl_reg, reg; 881 int rv; 882 883 if (ichlpcib_gpio_disable != 0) 884 return; 885 886 /* this implies ICH >= 6, and thus different mapreg */ 887 if (sc->sc_has_rcba) { 888 base_reg = LPCIB_PCI_GPIO_BASE_ICH6; 889 cntl_reg = LPCIB_PCI_GPIO_CNTL_ICH6; 890 } else { 891 base_reg = LPCIB_PCI_GPIO_BASE; 892 cntl_reg = LPCIB_PCI_GPIO_CNTL; 893 } 894 895 gpio_cntl = pci_conf_read(sc->sc_pcib.sc_pc, sc->sc_pcib.sc_tag, 896 cntl_reg); 897 898 /* Is GPIO enabled? */ 899 if ((gpio_cntl & LPCIB_PCI_GPIO_CNTL_EN) == 0) 900 return; 901 /* 902 * The GPIO_BASE register is alike PCI BAR but not completely 903 * compatible with it. The PMBASE define the base address and the type 904 * but not describe the size. The value of the register may be lower 905 * than LPCIB_PCI_GPIO_SIZE. It makes impossible to use 906 * pci_mapreg_submap() because the function does range check. 907 */ 908 sc->sc_gpio_iot = sc->sc_pa.pa_iot; 909 reg = pci_conf_read(sc->sc_pa.pa_pc, sc->sc_pa.pa_tag, base_reg); 910 rv = bus_space_map(sc->sc_gpio_iot, PCI_MAPREG_IO_ADDR(reg), 911 LPCIB_PCI_GPIO_SIZE, 0, &sc->sc_gpio_ioh); 912 if (rv != 0) { 913 aprint_error_dev(self, "can't map general purpose i/o space(rv = %d)\n", rv); 914 return; 915 } 916 917 mutex_init(&sc->sc_gpio_mtx, MUTEX_DEFAULT, IPL_NONE); 918 919 for (pin = 0; pin < LPCIB_GPIO_NPINS; pin++) { 920 sc->sc_gpio_pins[pin].pin_num = pin; 921 922 /* Read initial state */ 923 reg = (pin < 32) ? LPCIB_GPIO_GPIO_USE_SEL : LPCIB_GPIO_GPIO_USE_SEL2; 924 use = bus_space_read_4(sc->sc_gpio_iot, sc->sc_gpio_ioh, reg); 925 reg = (pin < 32) ? LPCIB_GPIO_GP_IO_SEL : LPCIB_GPIO_GP_IO_SEL; 926 io = bus_space_read_4(sc->sc_gpio_iot, sc->sc_gpio_ioh, 4); 927 shift = pin % 32; 928 bit = __BIT(shift); 929 930 if ((use & bit) != 0) { 931 sc->sc_gpio_pins[pin].pin_caps = 932 GPIO_PIN_INPUT | GPIO_PIN_OUTPUT; 933 if (pin < 32) 934 sc->sc_gpio_pins[pin].pin_caps |= 935 GPIO_PIN_PULSATE; 936 if ((io & bit) != 0) 937 sc->sc_gpio_pins[pin].pin_flags = 938 GPIO_PIN_INPUT; 939 else 940 sc->sc_gpio_pins[pin].pin_flags = 941 GPIO_PIN_OUTPUT; 942 } else 943 sc->sc_gpio_pins[pin].pin_caps = 0; 944 945 if (lpcib_gpio_pin_read(sc, pin) == 0) 946 sc->sc_gpio_pins[pin].pin_state = GPIO_PIN_LOW; 947 else 948 sc->sc_gpio_pins[pin].pin_state = GPIO_PIN_HIGH; 949 950 } 951 952 /* Create controller tag */ 953 sc->sc_gpio_gc.gp_cookie = sc; 954 sc->sc_gpio_gc.gp_pin_read = lpcib_gpio_pin_read; 955 sc->sc_gpio_gc.gp_pin_write = lpcib_gpio_pin_write; 956 sc->sc_gpio_gc.gp_pin_ctl = lpcib_gpio_pin_ctl; 957 958 memset(&gba, 0, sizeof(gba)); 959 960 gba.gba_gc = &sc->sc_gpio_gc; 961 gba.gba_pins = sc->sc_gpio_pins; 962 gba.gba_npins = LPCIB_GPIO_NPINS; 963 964 sc->sc_gpiobus = config_found(self, &gba, gpiobus_print, 965 CFARGS(.iattr = "gpiobus")); 966 } 967 968 static void 969 lpcib_gpio_unconfigure(device_t self) 970 { 971 struct lpcib_softc *sc = device_private(self); 972 973 mutex_destroy(&sc->sc_gpio_mtx); 974 975 bus_space_unmap(sc->sc_gpio_iot, sc->sc_gpio_ioh, sc->sc_gpio_ios); 976 } 977 978 static int 979 lpcib_gpio_pin_read(void *arg, int pin) 980 { 981 struct lpcib_softc *sc = arg; 982 uint32_t data; 983 int reg, shift; 984 985 reg = (pin < 32) ? LPCIB_GPIO_GP_LVL : LPCIB_GPIO_GP_LVL2; 986 shift = pin % 32; 987 988 mutex_enter(&sc->sc_gpio_mtx); 989 data = bus_space_read_4(sc->sc_gpio_iot, sc->sc_gpio_ioh, reg); 990 mutex_exit(&sc->sc_gpio_mtx); 991 992 return (__SHIFTOUT(data, __BIT(shift)) ? GPIO_PIN_HIGH : GPIO_PIN_LOW); 993 } 994 995 static void 996 lpcib_gpio_pin_write(void *arg, int pin, int value) 997 { 998 struct lpcib_softc *sc = arg; 999 uint32_t data; 1000 int reg, shift; 1001 1002 reg = (pin < 32) ? LPCIB_GPIO_GP_LVL : LPCIB_GPIO_GP_LVL2; 1003 shift = pin % 32; 1004 1005 mutex_enter(&sc->sc_gpio_mtx); 1006 1007 data = bus_space_read_4(sc->sc_gpio_iot, sc->sc_gpio_ioh, reg); 1008 1009 if (value) 1010 data |= __BIT(shift); 1011 else 1012 data &= ~__BIT(shift); 1013 1014 bus_space_write_4(sc->sc_gpio_iot, sc->sc_gpio_ioh, reg, data); 1015 1016 mutex_exit(&sc->sc_gpio_mtx); 1017 } 1018 1019 static void 1020 lpcib_gpio_pin_ctl(void *arg, int pin, int flags) 1021 { 1022 struct lpcib_softc *sc = arg; 1023 uint32_t data; 1024 int reg, shift; 1025 1026 shift = pin % 32; 1027 reg = (pin < 32) ? LPCIB_GPIO_GP_IO_SEL : LPCIB_GPIO_GP_IO_SEL2; 1028 1029 mutex_enter(&sc->sc_gpio_mtx); 1030 1031 data = bus_space_read_4(sc->sc_gpio_iot, sc->sc_gpio_ioh, reg); 1032 1033 if (flags & GPIO_PIN_OUTPUT) 1034 data &= ~__BIT(shift); 1035 1036 if (flags & GPIO_PIN_INPUT) 1037 data |= __BIT(shift); 1038 1039 bus_space_write_4(sc->sc_gpio_iot, sc->sc_gpio_ioh, reg, data); 1040 1041 1042 if (pin < 32) { 1043 reg = LPCIB_GPIO_GPO_BLINK; 1044 data = bus_space_read_4(sc->sc_gpio_iot, sc->sc_gpio_ioh, reg); 1045 1046 if (flags & GPIO_PIN_PULSATE) 1047 data |= __BIT(shift); 1048 else 1049 data &= ~__BIT(shift); 1050 1051 bus_space_write_4(sc->sc_gpio_iot, sc->sc_gpio_ioh, reg, data); 1052 } 1053 1054 mutex_exit(&sc->sc_gpio_mtx); 1055 } 1056 #endif 1057 1058 #if NFWHRNG > 0 1059 static void 1060 lpcib_fwh_configure(device_t self) 1061 { 1062 struct lpcib_softc *sc; 1063 pcireg_t pr; 1064 1065 sc = device_private(self); 1066 1067 if (sc->sc_has_rcba) { 1068 /* 1069 * Very unlikely to find a 82802 on a ICH6 or newer. 1070 * Also the write enable register moved at that point. 1071 */ 1072 return; 1073 } else { 1074 /* Enable FWH write to identify FWH. */ 1075 pr = pci_conf_read(sc->sc_pcib.sc_pc, sc->sc_pcib.sc_tag, 1076 LPCIB_PCI_BIOS_CNTL); 1077 pci_conf_write(sc->sc_pcib.sc_pc, sc->sc_pcib.sc_tag, 1078 LPCIB_PCI_BIOS_CNTL, pr|LPCIB_PCI_BIOS_CNTL_BWE); 1079 } 1080 1081 sc->sc_fwhbus = config_found(self, NULL, NULL, 1082 CFARGS(.iattr = "fwhichbus")); 1083 1084 /* restore previous write enable setting */ 1085 pci_conf_write(sc->sc_pcib.sc_pc, sc->sc_pcib.sc_tag, 1086 LPCIB_PCI_BIOS_CNTL, pr); 1087 } 1088 #endif 1089