1 /* $NetBSD: piixpm.c,v 1.54 2019/07/13 09:24:17 msaitoh Exp $ */ 2 /* $OpenBSD: piixpm.c,v 1.39 2013/10/01 20:06:02 sf Exp $ */ 3 4 /* 5 * Copyright (c) 2005, 2006 Alexander Yurchenko <grange@openbsd.org> 6 * 7 * Permission to use, copy, modify, and distribute this software for any 8 * purpose with or without fee is hereby granted, provided that the above 9 * copyright notice and this permission notice appear in all copies. 10 * 11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 18 */ 19 20 /* 21 * Intel PIIX and compatible Power Management controller driver. 22 */ 23 24 #include <sys/cdefs.h> 25 __KERNEL_RCSID(0, "$NetBSD: piixpm.c,v 1.54 2019/07/13 09:24:17 msaitoh Exp $"); 26 27 #include <sys/param.h> 28 #include <sys/systm.h> 29 #include <sys/device.h> 30 #include <sys/kernel.h> 31 #include <sys/mutex.h> 32 #include <sys/proc.h> 33 34 #include <sys/bus.h> 35 36 #include <dev/pci/pcidevs.h> 37 #include <dev/pci/pcireg.h> 38 #include <dev/pci/pcivar.h> 39 40 #include <dev/pci/piixpmreg.h> 41 42 #include <dev/i2c/i2cvar.h> 43 44 #include <dev/ic/acpipmtimer.h> 45 46 #ifdef PIIXPM_DEBUG 47 #define DPRINTF(x) printf x 48 #else 49 #define DPRINTF(x) 50 #endif 51 52 #define PIIXPM_IS_CSB5(sc) \ 53 (PCI_VENDOR((sc)->sc_id) == PCI_VENDOR_SERVERWORKS && \ 54 PCI_PRODUCT((sc)->sc_id) == PCI_PRODUCT_SERVERWORKS_CSB5) 55 #define PIIXPM_DELAY 200 56 #define PIIXPM_TIMEOUT 1 57 58 #define PIIXPM_IS_SB800GRP(sc) \ 59 ((PCI_VENDOR((sc)->sc_id) == PCI_VENDOR_ATI) && \ 60 ((PCI_PRODUCT((sc)->sc_id) == PCI_PRODUCT_ATI_SB600_SMB) && \ 61 ((sc)->sc_rev >= 0x40))) 62 63 #define PIIXPM_IS_HUDSON(sc) \ 64 ((PCI_VENDOR((sc)->sc_id) == PCI_VENDOR_AMD) && \ 65 (PCI_PRODUCT((sc)->sc_id) == PCI_PRODUCT_AMD_HUDSON_SMB)) 66 67 #define PIIXPM_IS_KERNCZ(sc) \ 68 ((PCI_VENDOR((sc)->sc_id) == PCI_VENDOR_AMD) && \ 69 (PCI_PRODUCT((sc)->sc_id) == PCI_PRODUCT_AMD_KERNCZ_SMB)) 70 71 #define PIIXPM_IS_FCHGRP(sc) (PIIXPM_IS_HUDSON(sc) || PIIXPM_IS_KERNCZ(sc)) 72 73 struct piixpm_smbus { 74 int sda; 75 struct piixpm_softc *softc; 76 }; 77 78 struct piixpm_softc { 79 device_t sc_dev; 80 81 bus_space_tag_t sc_iot; 82 #define sc_pm_iot sc_iot 83 #define sc_smb_iot sc_iot 84 bus_space_handle_t sc_pm_ioh; 85 bus_space_handle_t sc_sb800_ioh; 86 bus_space_handle_t sc_smb_ioh; 87 void * sc_smb_ih; 88 int sc_poll; 89 90 pci_chipset_tag_t sc_pc; 91 pcitag_t sc_pcitag; 92 pcireg_t sc_id; 93 pcireg_t sc_rev; 94 95 int sc_numbusses; 96 device_t sc_i2c_device[4]; 97 struct piixpm_smbus sc_busses[4]; 98 struct i2c_controller sc_i2c_tags[4]; 99 100 kmutex_t sc_i2c_mutex; 101 struct { 102 i2c_op_t op; 103 void * buf; 104 size_t len; 105 int flags; 106 volatile int error; 107 } sc_i2c_xfer; 108 109 pcireg_t sc_devact[2]; 110 }; 111 112 static int piixpm_match(device_t, cfdata_t, void *); 113 static void piixpm_attach(device_t, device_t, void *); 114 static int piixpm_rescan(device_t, const char *, const int *); 115 static void piixpm_chdet(device_t, device_t); 116 117 static bool piixpm_suspend(device_t, const pmf_qual_t *); 118 static bool piixpm_resume(device_t, const pmf_qual_t *); 119 120 static int piixpm_sb800_init(struct piixpm_softc *); 121 static void piixpm_csb5_reset(void *); 122 static int piixpm_i2c_acquire_bus(void *, int); 123 static void piixpm_i2c_release_bus(void *, int); 124 static int piixpm_i2c_exec(void *, i2c_op_t, i2c_addr_t, const void *, 125 size_t, void *, size_t, int); 126 127 static int piixpm_intr(void *); 128 129 CFATTACH_DECL3_NEW(piixpm, sizeof(struct piixpm_softc), 130 piixpm_match, piixpm_attach, NULL, NULL, piixpm_rescan, piixpm_chdet, 0); 131 132 static int 133 piixpm_match(device_t parent, cfdata_t match, void *aux) 134 { 135 struct pci_attach_args *pa; 136 137 pa = (struct pci_attach_args *)aux; 138 switch (PCI_VENDOR(pa->pa_id)) { 139 case PCI_VENDOR_INTEL: 140 switch (PCI_PRODUCT(pa->pa_id)) { 141 case PCI_PRODUCT_INTEL_82371AB_PMC: 142 case PCI_PRODUCT_INTEL_82440MX_PMC: 143 return 1; 144 } 145 break; 146 case PCI_VENDOR_ATI: 147 switch (PCI_PRODUCT(pa->pa_id)) { 148 case PCI_PRODUCT_ATI_SB200_SMB: 149 case PCI_PRODUCT_ATI_SB300_SMB: 150 case PCI_PRODUCT_ATI_SB400_SMB: 151 case PCI_PRODUCT_ATI_SB600_SMB: /* matches SB600/SB700/SB800 */ 152 return 1; 153 } 154 break; 155 case PCI_VENDOR_SERVERWORKS: 156 switch (PCI_PRODUCT(pa->pa_id)) { 157 case PCI_PRODUCT_SERVERWORKS_OSB4: 158 case PCI_PRODUCT_SERVERWORKS_CSB5: 159 case PCI_PRODUCT_SERVERWORKS_CSB6: 160 case PCI_PRODUCT_SERVERWORKS_HT1000SB: 161 case PCI_PRODUCT_SERVERWORKS_HT1100SB: 162 return 1; 163 } 164 break; 165 case PCI_VENDOR_AMD: 166 switch (PCI_PRODUCT(pa->pa_id)) { 167 case PCI_PRODUCT_AMD_HUDSON_SMB: 168 case PCI_PRODUCT_AMD_KERNCZ_SMB: 169 return 1; 170 } 171 break; 172 } 173 174 return 0; 175 } 176 177 static void 178 piixpm_attach(device_t parent, device_t self, void *aux) 179 { 180 struct piixpm_softc *sc = device_private(self); 181 struct pci_attach_args *pa = aux; 182 pcireg_t base, conf; 183 pcireg_t pmmisc; 184 pci_intr_handle_t ih; 185 bool usesmi = false; 186 const char *intrstr = NULL; 187 int i, flags; 188 char intrbuf[PCI_INTRSTR_LEN]; 189 190 sc->sc_dev = self; 191 sc->sc_iot = pa->pa_iot; 192 sc->sc_id = pa->pa_id; 193 sc->sc_rev = PCI_REVISION(pa->pa_class); 194 sc->sc_pc = pa->pa_pc; 195 sc->sc_pcitag = pa->pa_tag; 196 sc->sc_numbusses = 1; 197 198 pci_aprint_devinfo(pa, NULL); 199 200 if (!pmf_device_register(self, piixpm_suspend, piixpm_resume)) 201 aprint_error_dev(self, "couldn't establish power handler\n"); 202 203 if ((PCI_VENDOR(pa->pa_id) != PCI_VENDOR_INTEL) || 204 (PCI_PRODUCT(pa->pa_id) != PCI_PRODUCT_INTEL_82371AB_PMC)) 205 goto nopowermanagement; 206 207 /* check whether I/O access to PM regs is enabled */ 208 pmmisc = pci_conf_read(pa->pa_pc, pa->pa_tag, PIIX_PMREGMISC); 209 if (!(pmmisc & 1)) 210 goto nopowermanagement; 211 212 /* Map I/O space */ 213 base = pci_conf_read(pa->pa_pc, pa->pa_tag, PIIX_PM_BASE); 214 if (base == 0 || bus_space_map(sc->sc_pm_iot, PCI_MAPREG_IO_ADDR(base), 215 PIIX_PM_SIZE, 0, &sc->sc_pm_ioh)) { 216 aprint_error_dev(self, 217 "can't map power management I/O space\n"); 218 goto nopowermanagement; 219 } 220 221 /* 222 * Revision 0 and 1 are PIIX4, 2 is PIIX4E, 3 is PIIX4M. 223 * PIIX4 and PIIX4E have a bug in the timer latch, see Errata #20 224 * in the "Specification update" (document #297738). 225 */ 226 acpipmtimer_attach(self, sc->sc_pm_iot, sc->sc_pm_ioh, PIIX_PM_PMTMR, 227 (PCI_REVISION(pa->pa_class) < 3) ? ACPIPMT_BADLATCH : 0); 228 229 nopowermanagement: 230 231 /* SB800 rev 0x40+, AMD HUDSON and newer need special initialization */ 232 if (PIIXPM_IS_FCHGRP(sc) || PIIXPM_IS_SB800GRP(sc)) { 233 if (piixpm_sb800_init(sc) == 0) { 234 sc->sc_numbusses = 4; 235 236 /* Read configuration */ 237 conf = pci_conf_read(pa->pa_pc, pa->pa_tag, 238 SB800_SMB_HOSTC); 239 DPRINTF(("%s: conf 0x%08x\n", device_xname(self), 240 conf)); 241 242 usesmi = conf & SB800_SMB_HOSTC_SMI; 243 goto setintr; 244 } 245 aprint_normal_dev(self, "SMBus initialization failed\n"); 246 return; 247 } 248 249 /* Read configuration */ 250 conf = pci_conf_read(pa->pa_pc, pa->pa_tag, PIIX_SMB_HOSTC); 251 DPRINTF(("%s: conf 0x%08x\n", device_xname(self), conf)); 252 253 if ((conf & PIIX_SMB_HOSTC_HSTEN) == 0) { 254 aprint_normal_dev(self, "SMBus disabled\n"); 255 return; 256 } 257 usesmi = (conf & PIIX_SMB_HOSTC_INTMASK) == PIIX_SMB_HOSTC_SMI; 258 259 /* Map I/O space */ 260 base = pci_conf_read(pa->pa_pc, pa->pa_tag, PIIX_SMB_BASE) & 0xffff; 261 if (base == 0 || 262 bus_space_map(sc->sc_smb_iot, PCI_MAPREG_IO_ADDR(base), 263 PIIX_SMB_SIZE, 0, &sc->sc_smb_ioh)) { 264 aprint_error_dev(self, "can't map smbus I/O space\n"); 265 return; 266 } 267 268 setintr: 269 sc->sc_poll = 1; 270 aprint_normal_dev(self, ""); 271 if (usesmi) { 272 /* No PCI IRQ */ 273 aprint_normal("interrupting at SMI, "); 274 } else { 275 if ((conf & PIIX_SMB_HOSTC_INTMASK) == PIIX_SMB_HOSTC_IRQ) { 276 /* Install interrupt handler */ 277 if (pci_intr_map(pa, &ih) == 0) { 278 intrstr = pci_intr_string(pa->pa_pc, ih, 279 intrbuf, sizeof(intrbuf)); 280 sc->sc_smb_ih = pci_intr_establish_xname( 281 pa->pa_pc, ih, IPL_BIO, piixpm_intr, 282 sc, device_xname(sc->sc_dev)); 283 if (sc->sc_smb_ih != NULL) { 284 aprint_normal("interrupting at %s", 285 intrstr); 286 sc->sc_poll = 0; 287 } 288 } 289 } 290 if (sc->sc_poll) 291 aprint_normal("polling"); 292 } 293 294 aprint_normal("\n"); 295 296 for (i = 0; i < sc->sc_numbusses; i++) 297 sc->sc_i2c_device[i] = NULL; 298 299 flags = 0; 300 mutex_init(&sc->sc_i2c_mutex, MUTEX_DEFAULT, IPL_NONE); 301 piixpm_rescan(self, "i2cbus", &flags); 302 } 303 304 static int 305 piixpm_iicbus_print(void *aux, const char *pnp) 306 { 307 struct i2cbus_attach_args *iba = aux; 308 struct i2c_controller *tag = iba->iba_tag; 309 struct piixpm_smbus *bus = tag->ic_cookie; 310 struct piixpm_softc *sc = bus->softc; 311 312 iicbus_print(aux, pnp); 313 if (sc->sc_numbusses != 0) 314 aprint_normal(" port %d", bus->sda); 315 316 return UNCONF; 317 } 318 static int 319 piixpm_rescan(device_t self, const char *ifattr, const int *flags) 320 { 321 struct piixpm_softc *sc = device_private(self); 322 struct i2cbus_attach_args iba; 323 int i; 324 325 if (!ifattr_match(ifattr, "i2cbus")) 326 return 0; 327 328 /* Attach I2C bus */ 329 330 for (i = 0; i < sc->sc_numbusses; i++) { 331 if (sc->sc_i2c_device[i]) 332 continue; 333 sc->sc_busses[i].sda = i; 334 sc->sc_busses[i].softc = sc; 335 sc->sc_i2c_tags[i].ic_cookie = &sc->sc_busses[i]; 336 sc->sc_i2c_tags[i].ic_acquire_bus = piixpm_i2c_acquire_bus; 337 sc->sc_i2c_tags[i].ic_release_bus = piixpm_i2c_release_bus; 338 sc->sc_i2c_tags[i].ic_exec = piixpm_i2c_exec; 339 memset(&iba, 0, sizeof(iba)); 340 iba.iba_type = I2C_TYPE_SMBUS; 341 iba.iba_tag = &sc->sc_i2c_tags[i]; 342 sc->sc_i2c_device[i] = config_found_ia(self, ifattr, &iba, 343 piixpm_iicbus_print); 344 } 345 346 return 0; 347 } 348 349 static void 350 piixpm_chdet(device_t self, device_t child) 351 { 352 struct piixpm_softc *sc = device_private(self); 353 int i; 354 355 for (i = 0; i < sc->sc_numbusses; i++) { 356 if (sc->sc_i2c_device[i] == child) { 357 sc->sc_i2c_device[i] = NULL; 358 break; 359 } 360 } 361 } 362 363 364 static bool 365 piixpm_suspend(device_t dv, const pmf_qual_t *qual) 366 { 367 struct piixpm_softc *sc = device_private(dv); 368 369 sc->sc_devact[0] = pci_conf_read(sc->sc_pc, sc->sc_pcitag, 370 PIIX_DEVACTA); 371 sc->sc_devact[1] = pci_conf_read(sc->sc_pc, sc->sc_pcitag, 372 PIIX_DEVACTB); 373 374 return true; 375 } 376 377 static bool 378 piixpm_resume(device_t dv, const pmf_qual_t *qual) 379 { 380 struct piixpm_softc *sc = device_private(dv); 381 382 pci_conf_write(sc->sc_pc, sc->sc_pcitag, PIIX_DEVACTA, 383 sc->sc_devact[0]); 384 pci_conf_write(sc->sc_pc, sc->sc_pcitag, PIIX_DEVACTB, 385 sc->sc_devact[1]); 386 387 return true; 388 } 389 390 /* 391 * Extract SMBus base address from SB800 Power Management (PM) registers. 392 * The PM registers can be accessed either through indirect I/O (CD6/CD7) or 393 * direct mapping if AcpiMMioDecodeEn is enabled. Since this function is only 394 * called once it uses indirect I/O for simplicity. 395 */ 396 static int 397 piixpm_sb800_init(struct piixpm_softc *sc) 398 { 399 bus_space_tag_t iot = sc->sc_iot; 400 bus_space_handle_t ioh; /* indirect I/O handle */ 401 uint16_t val, base_addr; 402 bool enabled; 403 404 /* Fetch SMB base address */ 405 if (bus_space_map(iot, 406 SB800_INDIRECTIO_BASE, SB800_INDIRECTIO_SIZE, 0, &ioh)) { 407 device_printf(sc->sc_dev, "couldn't map indirect I/O space\n"); 408 return EBUSY; 409 } 410 if (PIIXPM_IS_FCHGRP(sc)) { 411 bus_space_write_1(iot, ioh, SB800_INDIRECTIO_INDEX, 412 AMDFCH41_PM_DECODE_EN0); 413 val = bus_space_read_1(iot, ioh, SB800_INDIRECTIO_DATA); 414 enabled = val & AMDFCH41_SMBUS_EN; 415 if (!enabled) 416 return ENOENT; 417 418 bus_space_write_1(iot, ioh, SB800_INDIRECTIO_INDEX, 419 AMDFCH41_PM_DECODE_EN1); 420 val = bus_space_read_1(iot, ioh, SB800_INDIRECTIO_DATA) << 8; 421 base_addr = val; 422 } else { 423 bus_space_write_1(iot, ioh, SB800_INDIRECTIO_INDEX, 424 SB800_PM_SMBUS0EN_LO); 425 val = bus_space_read_1(iot, ioh, SB800_INDIRECTIO_DATA); 426 enabled = val & SB800_PM_SMBUS0EN_ENABLE; 427 if (!enabled) 428 return ENOENT; 429 430 bus_space_write_1(iot, ioh, SB800_INDIRECTIO_INDEX, 431 SB800_PM_SMBUS0EN_HI); 432 val |= bus_space_read_1(iot, ioh, SB800_INDIRECTIO_DATA) << 8; 433 base_addr = val & SB800_PM_SMBUS0EN_BADDR; 434 435 bus_space_write_1(iot, ioh, SB800_INDIRECTIO_INDEX, 436 SB800_PM_SMBUS0SELEN); 437 bus_space_write_1(iot, ioh, SB800_INDIRECTIO_DATA, 438 SB800_PM_SMBUS0EN_ENABLE); 439 } 440 441 sc->sc_sb800_ioh = ioh; 442 aprint_debug_dev(sc->sc_dev, "SMBus @ 0x%04x\n", base_addr); 443 444 if (bus_space_map(iot, PCI_MAPREG_IO_ADDR(base_addr), 445 PIIX_SMB_SIZE, 0, &sc->sc_smb_ioh)) { 446 aprint_error_dev(sc->sc_dev, "can't map smbus I/O space\n"); 447 return EBUSY; 448 } 449 450 return 0; 451 } 452 453 static void 454 piixpm_csb5_reset(void *arg) 455 { 456 struct piixpm_softc *sc = arg; 457 pcireg_t base, hostc, pmbase; 458 459 base = pci_conf_read(sc->sc_pc, sc->sc_pcitag, PIIX_SMB_BASE); 460 hostc = pci_conf_read(sc->sc_pc, sc->sc_pcitag, PIIX_SMB_HOSTC); 461 462 pmbase = pci_conf_read(sc->sc_pc, sc->sc_pcitag, PIIX_PM_BASE); 463 pmbase |= PIIX_PM_BASE_CSB5_RESET; 464 pci_conf_write(sc->sc_pc, sc->sc_pcitag, PIIX_PM_BASE, pmbase); 465 pmbase &= ~PIIX_PM_BASE_CSB5_RESET; 466 pci_conf_write(sc->sc_pc, sc->sc_pcitag, PIIX_PM_BASE, pmbase); 467 468 pci_conf_write(sc->sc_pc, sc->sc_pcitag, PIIX_SMB_BASE, base); 469 pci_conf_write(sc->sc_pc, sc->sc_pcitag, PIIX_SMB_HOSTC, hostc); 470 471 (void) tsleep(&sc, PRIBIO, "csb5reset", hz/2); 472 } 473 474 static int 475 piixpm_i2c_acquire_bus(void *cookie, int flags) 476 { 477 struct piixpm_smbus *smbus = cookie; 478 struct piixpm_softc *sc = smbus->softc; 479 480 if (!cold) 481 mutex_enter(&sc->sc_i2c_mutex); 482 483 if (PIIXPM_IS_KERNCZ(sc)) { 484 bus_space_write_1(sc->sc_iot, sc->sc_sb800_ioh, 485 SB800_INDIRECTIO_INDEX, AMDFCH41_PM_PORT_INDEX); 486 bus_space_write_1(sc->sc_iot, sc->sc_sb800_ioh, 487 SB800_INDIRECTIO_DATA, smbus->sda << 3); 488 } else if (PIIXPM_IS_SB800GRP(sc) || PIIXPM_IS_HUDSON(sc)) { 489 bus_space_write_1(sc->sc_iot, sc->sc_sb800_ioh, 490 SB800_INDIRECTIO_INDEX, SB800_PM_SMBUS0SEL); 491 bus_space_write_1(sc->sc_iot, sc->sc_sb800_ioh, 492 SB800_INDIRECTIO_DATA, smbus->sda << 1); 493 } 494 495 return 0; 496 } 497 498 static void 499 piixpm_i2c_release_bus(void *cookie, int flags) 500 { 501 struct piixpm_smbus *smbus = cookie; 502 struct piixpm_softc *sc = smbus->softc; 503 504 if (PIIXPM_IS_KERNCZ(sc)) { 505 bus_space_write_1(sc->sc_iot, sc->sc_sb800_ioh, 506 SB800_INDIRECTIO_INDEX, AMDFCH41_PM_PORT_INDEX); 507 bus_space_write_1(sc->sc_iot, sc->sc_sb800_ioh, 508 SB800_INDIRECTIO_DATA, 0); 509 } else if (PIIXPM_IS_SB800GRP(sc) || PIIXPM_IS_HUDSON(sc)) { 510 /* 511 * HP Microserver hangs after reboot if not set to SDA0. 512 * Also add shutdown hook? 513 */ 514 bus_space_write_1(sc->sc_iot, sc->sc_sb800_ioh, 515 SB800_INDIRECTIO_INDEX, SB800_PM_SMBUS0SEL); 516 bus_space_write_1(sc->sc_iot, sc->sc_sb800_ioh, 517 SB800_INDIRECTIO_DATA, 0); 518 } 519 520 if (!cold) 521 mutex_exit(&sc->sc_i2c_mutex); 522 } 523 524 static int 525 piixpm_i2c_exec(void *cookie, i2c_op_t op, i2c_addr_t addr, 526 const void *cmdbuf, size_t cmdlen, void *buf, size_t len, int flags) 527 { 528 struct piixpm_smbus *smbus = cookie; 529 struct piixpm_softc *sc = smbus->softc; 530 const uint8_t *b; 531 uint8_t ctl = 0, st; 532 int retries; 533 534 DPRINTF(("%s: exec: op %d, addr 0x%02x, cmdlen %zu, len %zu, " 535 "flags 0x%x\n", 536 device_xname(sc->sc_dev), op, addr, cmdlen, len, flags)); 537 538 /* Clear status bits */ 539 bus_space_write_1(sc->sc_smb_iot, sc->sc_smb_ioh, PIIX_SMB_HS, 540 PIIX_SMB_HS_INTR | PIIX_SMB_HS_DEVERR | 541 PIIX_SMB_HS_BUSERR | PIIX_SMB_HS_FAILED); 542 bus_space_barrier(sc->sc_smb_iot, sc->sc_smb_ioh, PIIX_SMB_HS, 1, 543 BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE); 544 545 /* Wait for bus to be idle */ 546 for (retries = 100; retries > 0; retries--) { 547 st = bus_space_read_1(sc->sc_smb_iot, sc->sc_smb_ioh, 548 PIIX_SMB_HS); 549 if (!(st & PIIX_SMB_HS_BUSY)) 550 break; 551 DELAY(PIIXPM_DELAY); 552 } 553 DPRINTF(("%s: exec: st %#x\n", device_xname(sc->sc_dev), st & 0xff)); 554 if (st & PIIX_SMB_HS_BUSY) 555 return (1); 556 557 if (cold || sc->sc_poll) 558 flags |= I2C_F_POLL; 559 560 if (!I2C_OP_STOP_P(op) || cmdlen > 1 || len > 2 || 561 (cmdlen == 0 && len > 1)) 562 return (1); 563 564 /* Setup transfer */ 565 sc->sc_i2c_xfer.op = op; 566 sc->sc_i2c_xfer.buf = buf; 567 sc->sc_i2c_xfer.len = len; 568 sc->sc_i2c_xfer.flags = flags; 569 sc->sc_i2c_xfer.error = 0; 570 571 /* Set slave address and transfer direction */ 572 bus_space_write_1(sc->sc_smb_iot, sc->sc_smb_ioh, PIIX_SMB_TXSLVA, 573 PIIX_SMB_TXSLVA_ADDR(addr) | 574 (I2C_OP_READ_P(op) ? PIIX_SMB_TXSLVA_READ : 0)); 575 576 b = cmdbuf; 577 if (cmdlen > 0) 578 /* Set command byte */ 579 bus_space_write_1(sc->sc_smb_iot, sc->sc_smb_ioh, 580 PIIX_SMB_HCMD, b[0]); 581 582 if (I2C_OP_WRITE_P(op)) { 583 /* Write data */ 584 b = buf; 585 if (cmdlen == 0 && len == 1) 586 bus_space_write_1(sc->sc_smb_iot, sc->sc_smb_ioh, 587 PIIX_SMB_HCMD, b[0]); 588 else if (len > 0) 589 bus_space_write_1(sc->sc_smb_iot, sc->sc_smb_ioh, 590 PIIX_SMB_HD0, b[0]); 591 if (len > 1) 592 bus_space_write_1(sc->sc_smb_iot, sc->sc_smb_ioh, 593 PIIX_SMB_HD1, b[1]); 594 } 595 596 /* Set SMBus command */ 597 if (cmdlen == 0) { 598 if (len == 0) 599 ctl = PIIX_SMB_HC_CMD_QUICK; 600 else 601 ctl = PIIX_SMB_HC_CMD_BYTE; 602 } else if (len == 1) 603 ctl = PIIX_SMB_HC_CMD_BDATA; 604 else if (len == 2) 605 ctl = PIIX_SMB_HC_CMD_WDATA; 606 else 607 panic("%s: unexpected len %zu", __func__, len); 608 609 if ((flags & I2C_F_POLL) == 0) 610 ctl |= PIIX_SMB_HC_INTREN; 611 612 /* Start transaction */ 613 ctl |= PIIX_SMB_HC_START; 614 bus_space_write_1(sc->sc_smb_iot, sc->sc_smb_ioh, PIIX_SMB_HC, ctl); 615 616 if (flags & I2C_F_POLL) { 617 /* Poll for completion */ 618 if (PIIXPM_IS_CSB5(sc)) 619 DELAY(2*PIIXPM_DELAY); 620 else 621 DELAY(PIIXPM_DELAY); 622 for (retries = 1000; retries > 0; retries--) { 623 st = bus_space_read_1(sc->sc_smb_iot, sc->sc_smb_ioh, 624 PIIX_SMB_HS); 625 if ((st & PIIX_SMB_HS_BUSY) == 0) 626 break; 627 DELAY(PIIXPM_DELAY); 628 } 629 if (st & PIIX_SMB_HS_BUSY) 630 goto timeout; 631 piixpm_intr(sc); 632 } else { 633 /* Wait for interrupt */ 634 if (tsleep(sc, PRIBIO, "piixpm", PIIXPM_TIMEOUT * hz)) 635 goto timeout; 636 } 637 638 if (sc->sc_i2c_xfer.error) 639 return (1); 640 641 return (0); 642 643 timeout: 644 /* 645 * Transfer timeout. Kill the transaction and clear status bits. 646 */ 647 aprint_error_dev(sc->sc_dev, "timeout, status 0x%x\n", st); 648 bus_space_write_1(sc->sc_smb_iot, sc->sc_smb_ioh, PIIX_SMB_HC, 649 PIIX_SMB_HC_KILL); 650 DELAY(PIIXPM_DELAY); 651 st = bus_space_read_1(sc->sc_smb_iot, sc->sc_smb_ioh, PIIX_SMB_HS); 652 if ((st & PIIX_SMB_HS_FAILED) == 0) 653 aprint_error_dev(sc->sc_dev, 654 "transaction abort failed, status 0x%x\n", st); 655 bus_space_write_1(sc->sc_smb_iot, sc->sc_smb_ioh, PIIX_SMB_HS, st); 656 /* 657 * CSB5 needs hard reset to unlock the smbus after timeout. 658 */ 659 if (PIIXPM_IS_CSB5(sc)) 660 piixpm_csb5_reset(sc); 661 return (1); 662 } 663 664 static int 665 piixpm_intr(void *arg) 666 { 667 struct piixpm_softc *sc = arg; 668 uint8_t st; 669 uint8_t *b; 670 size_t len; 671 672 /* Read status */ 673 st = bus_space_read_1(sc->sc_smb_iot, sc->sc_smb_ioh, PIIX_SMB_HS); 674 if ((st & PIIX_SMB_HS_BUSY) != 0 || (st & (PIIX_SMB_HS_INTR | 675 PIIX_SMB_HS_DEVERR | PIIX_SMB_HS_BUSERR | 676 PIIX_SMB_HS_FAILED)) == 0) 677 /* Interrupt was not for us */ 678 return (0); 679 680 DPRINTF(("%s: intr st %#x\n", device_xname(sc->sc_dev), st & 0xff)); 681 682 /* Clear status bits */ 683 bus_space_write_1(sc->sc_smb_iot, sc->sc_smb_ioh, PIIX_SMB_HS, st); 684 685 /* Check for errors */ 686 if (st & (PIIX_SMB_HS_DEVERR | PIIX_SMB_HS_BUSERR | 687 PIIX_SMB_HS_FAILED)) { 688 sc->sc_i2c_xfer.error = 1; 689 goto done; 690 } 691 692 if (st & PIIX_SMB_HS_INTR) { 693 if (I2C_OP_WRITE_P(sc->sc_i2c_xfer.op)) 694 goto done; 695 696 /* Read data */ 697 b = sc->sc_i2c_xfer.buf; 698 len = sc->sc_i2c_xfer.len; 699 if (len > 0) 700 b[0] = bus_space_read_1(sc->sc_smb_iot, sc->sc_smb_ioh, 701 PIIX_SMB_HD0); 702 if (len > 1) 703 b[1] = bus_space_read_1(sc->sc_smb_iot, sc->sc_smb_ioh, 704 PIIX_SMB_HD1); 705 } 706 707 done: 708 if ((sc->sc_i2c_xfer.flags & I2C_F_POLL) == 0) 709 wakeup(sc); 710 return (1); 711 } 712