1 /* $NetBSD: piixpm.c,v 1.17 2007/10/19 12:00:54 ad Exp $ */ 2 /* $OpenBSD: piixpm.c,v 1.20 2006/02/27 08:25:02 grange 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/param.h> 25 #include <sys/systm.h> 26 #include <sys/device.h> 27 #include <sys/kernel.h> 28 #include <sys/rwlock.h> 29 #include <sys/proc.h> 30 31 #include <sys/bus.h> 32 33 #include <dev/pci/pcidevs.h> 34 #include <dev/pci/pcireg.h> 35 #include <dev/pci/pcivar.h> 36 37 #include <dev/pci/piixpmreg.h> 38 39 #include <dev/i2c/i2cvar.h> 40 41 #include <dev/ic/acpipmtimer.h> 42 43 #ifdef PIIXPM_DEBUG 44 #define DPRINTF(x) printf x 45 #else 46 #define DPRINTF(x) 47 #endif 48 49 #define PIIXPM_DELAY 200 50 #define PIIXPM_TIMEOUT 1 51 52 struct piixpm_softc { 53 struct device sc_dev; 54 55 bus_space_tag_t sc_smb_iot; 56 bus_space_handle_t sc_smb_ioh; 57 void * sc_smb_ih; 58 int sc_poll; 59 60 bus_space_tag_t sc_pm_iot; 61 bus_space_handle_t sc_pm_ioh; 62 63 pci_chipset_tag_t sc_pc; 64 pcitag_t sc_pcitag; 65 66 struct i2c_controller sc_i2c_tag; 67 krwlock_t sc_i2c_rwlock; 68 struct { 69 i2c_op_t op; 70 void * buf; 71 size_t len; 72 int flags; 73 volatile int error; 74 } sc_i2c_xfer; 75 76 void * sc_powerhook; 77 struct pci_conf_state sc_pciconf; 78 pcireg_t sc_devact[2]; 79 }; 80 81 int piixpm_match(struct device *, struct cfdata *, void *); 82 void piixpm_attach(struct device *, struct device *, void *); 83 84 void piixpm_powerhook(int, void *); 85 86 int piixpm_i2c_acquire_bus(void *, int); 87 void piixpm_i2c_release_bus(void *, int); 88 int piixpm_i2c_exec(void *, i2c_op_t, i2c_addr_t, const void *, size_t, 89 void *, size_t, int); 90 91 int piixpm_intr(void *); 92 93 CFATTACH_DECL(piixpm, sizeof(struct piixpm_softc), 94 piixpm_match, piixpm_attach, NULL, NULL); 95 96 int 97 piixpm_match(struct device *parent, struct cfdata *match, 98 void *aux) 99 { 100 struct pci_attach_args *pa; 101 102 pa = (struct pci_attach_args *)aux; 103 switch (PCI_VENDOR(pa->pa_id)) { 104 case PCI_VENDOR_INTEL: 105 switch (PCI_PRODUCT(pa->pa_id)) { 106 case PCI_PRODUCT_INTEL_82371AB_PMC: 107 case PCI_PRODUCT_INTEL_82440MX_PMC: 108 return 1; 109 } 110 break; 111 case PCI_VENDOR_ATI: 112 switch (PCI_PRODUCT(pa->pa_id)) { 113 case PCI_PRODUCT_ATI_SB200_SMB: 114 case PCI_PRODUCT_ATI_SB300_SMB: 115 case PCI_PRODUCT_ATI_SB400_SMB: 116 return 1; 117 } 118 break; 119 case PCI_VENDOR_SERVERWORKS: 120 switch (PCI_PRODUCT(pa->pa_id)) { 121 case PCI_PRODUCT_SERVERWORKS_OSB4: 122 case PCI_PRODUCT_SERVERWORKS_CSB5: 123 case PCI_PRODUCT_SERVERWORKS_CSB6: 124 case PCI_PRODUCT_SERVERWORKS_HT1000SB: 125 return 1; 126 } 127 } 128 129 return 0; 130 } 131 132 void 133 piixpm_attach(struct device *parent, struct device *self, void *aux) 134 { 135 struct piixpm_softc *sc = (struct piixpm_softc *)self; 136 struct pci_attach_args *pa = aux; 137 struct i2cbus_attach_args iba; 138 pcireg_t base, conf; 139 pcireg_t pmmisc; 140 pci_intr_handle_t ih; 141 char devinfo[256]; 142 const char *intrstr = NULL; 143 144 sc->sc_pc = pa->pa_pc; 145 sc->sc_pcitag = pa->pa_tag; 146 147 aprint_naive("\n"); 148 149 pci_devinfo(pa->pa_id, pa->pa_class, 0, devinfo, sizeof(devinfo)); 150 aprint_normal("\n%s: %s (rev. 0x%02x)\n", 151 device_xname(self), devinfo, PCI_REVISION(pa->pa_class)); 152 153 sc->sc_powerhook = powerhook_establish(sc->sc_dev.dv_xname, 154 piixpm_powerhook, sc); 155 if (sc->sc_powerhook == NULL) 156 aprint_error("%s: can't establish powerhook\n", 157 sc->sc_dev.dv_xname); 158 159 /* Read configuration */ 160 conf = pci_conf_read(pa->pa_pc, pa->pa_tag, PIIX_SMB_HOSTC); 161 DPRINTF((": conf 0x%x", conf)); 162 163 if ((PCI_VENDOR(pa->pa_id) != PCI_VENDOR_INTEL) || 164 (PCI_PRODUCT(pa->pa_id) != PCI_PRODUCT_INTEL_82371AB_PMC)) 165 goto nopowermanagement; 166 167 /* check whether I/O access to PM regs is enabled */ 168 pmmisc = pci_conf_read(pa->pa_pc, pa->pa_tag, PIIX_PMREGMISC); 169 if (!(pmmisc & 1)) 170 goto nopowermanagement; 171 172 sc->sc_pm_iot = pa->pa_iot; 173 /* Map I/O space */ 174 base = pci_conf_read(pa->pa_pc, pa->pa_tag, PIIX_PM_BASE); 175 if (bus_space_map(sc->sc_pm_iot, PCI_MAPREG_IO_ADDR(base), 176 PIIX_PM_SIZE, 0, &sc->sc_pm_ioh)) { 177 aprint_error("%s: can't map power management I/O space\n", 178 sc->sc_dev.dv_xname); 179 goto nopowermanagement; 180 } 181 182 /* 183 * Revision 0 and 1 are PIIX4, 2 is PIIX4E, 3 is PIIX4M. 184 * PIIX4 and PIIX4E have a bug in the timer latch, see Errata #20 185 * in the "Specification update" (document #297738). 186 */ 187 acpipmtimer_attach(&sc->sc_dev, sc->sc_pm_iot, sc->sc_pm_ioh, 188 PIIX_PM_PMTMR, 189 (PCI_REVISION(pa->pa_class) < 3) ? ACPIPMT_BADLATCH : 0 ); 190 191 nopowermanagement: 192 if ((conf & PIIX_SMB_HOSTC_HSTEN) == 0) { 193 aprint_normal("%s: SMBus disabled\n", sc->sc_dev.dv_xname); 194 return; 195 } 196 197 /* Map I/O space */ 198 sc->sc_smb_iot = pa->pa_iot; 199 base = pci_conf_read(pa->pa_pc, pa->pa_tag, PIIX_SMB_BASE) & 0xffff; 200 if (bus_space_map(sc->sc_smb_iot, PCI_MAPREG_IO_ADDR(base), 201 PIIX_SMB_SIZE, 0, &sc->sc_smb_ioh)) { 202 aprint_error("%s: can't map smbus I/O space\n", 203 sc->sc_dev.dv_xname); 204 return; 205 } 206 207 sc->sc_poll = 1; 208 if ((conf & PIIX_SMB_HOSTC_INTMASK) == PIIX_SMB_HOSTC_SMI) { 209 /* No PCI IRQ */ 210 aprint_normal("%s: interrupting at SMI", sc->sc_dev.dv_xname); 211 } else if ((conf & PIIX_SMB_HOSTC_INTMASK) == PIIX_SMB_HOSTC_IRQ) { 212 /* Install interrupt handler */ 213 if (pci_intr_map(pa, &ih) == 0) { 214 intrstr = pci_intr_string(pa->pa_pc, ih); 215 sc->sc_smb_ih = pci_intr_establish(pa->pa_pc, ih, IPL_BIO, 216 piixpm_intr, sc); 217 if (sc->sc_smb_ih != NULL) { 218 aprint_normal("%s: interrupting at %s", 219 sc->sc_dev.dv_xname, intrstr); 220 sc->sc_poll = 0; 221 } 222 } 223 if (sc->sc_poll) 224 aprint_normal("%s: polling", sc->sc_dev.dv_xname); 225 } 226 227 aprint_normal("\n"); 228 229 /* Attach I2C bus */ 230 rw_init(&sc->sc_i2c_rwlock); 231 sc->sc_i2c_tag.ic_cookie = sc; 232 sc->sc_i2c_tag.ic_acquire_bus = piixpm_i2c_acquire_bus; 233 sc->sc_i2c_tag.ic_release_bus = piixpm_i2c_release_bus; 234 sc->sc_i2c_tag.ic_exec = piixpm_i2c_exec; 235 236 bzero(&iba, sizeof(iba)); 237 iba.iba_tag = &sc->sc_i2c_tag; 238 config_found_ia(self, "i2cbus", &iba, iicbus_print); 239 240 return; 241 } 242 243 void 244 piixpm_powerhook(int why, void *cookie) 245 { 246 struct piixpm_softc *sc = cookie; 247 pci_chipset_tag_t pc = sc->sc_pc; 248 pcitag_t tag = sc->sc_pcitag; 249 250 switch (why) { 251 case PWR_SUSPEND: 252 pci_conf_capture(pc, tag, &sc->sc_pciconf); 253 sc->sc_devact[0] = pci_conf_read(pc, tag, PIIX_DEVACTA); 254 sc->sc_devact[1] = pci_conf_read(pc, tag, PIIX_DEVACTB); 255 break; 256 case PWR_RESUME: 257 pci_conf_restore(pc, tag, &sc->sc_pciconf); 258 pci_conf_write(pc, tag, PIIX_DEVACTA, sc->sc_devact[0]); 259 pci_conf_write(pc, tag, PIIX_DEVACTB, sc->sc_devact[1]); 260 break; 261 } 262 263 return; 264 } 265 266 int 267 piixpm_i2c_acquire_bus(void *cookie, int flags) 268 { 269 struct piixpm_softc *sc = cookie; 270 271 if (cold || sc->sc_poll || (flags & I2C_F_POLL)) 272 return (0); 273 274 rw_enter(&sc->sc_i2c_rwlock, RW_WRITER); 275 return 0; 276 } 277 278 void 279 piixpm_i2c_release_bus(void *cookie, int flags) 280 { 281 struct piixpm_softc *sc = cookie; 282 283 if (cold || sc->sc_poll || (flags & I2C_F_POLL)) 284 return; 285 286 rw_exit(&sc->sc_i2c_rwlock); 287 } 288 289 int 290 piixpm_i2c_exec(void *cookie, i2c_op_t op, i2c_addr_t addr, 291 const void *cmdbuf, size_t cmdlen, void *buf, size_t len, int flags) 292 { 293 struct piixpm_softc *sc = cookie; 294 const u_int8_t *b; 295 u_int8_t ctl = 0, st; 296 int retries; 297 298 DPRINTF(("%s: exec: op %d, addr 0x%x, cmdlen %d, len %d, flags 0x%x\n", 299 sc->sc_dev.dv_xname, op, addr, cmdlen, len, flags)); 300 301 /* Wait for bus to be idle */ 302 for (retries = 100; retries > 0; retries--) { 303 st = bus_space_read_1(sc->sc_smb_iot, sc->sc_smb_ioh, 304 PIIX_SMB_HS); 305 if (!(st & PIIX_SMB_HS_BUSY)) 306 break; 307 DELAY(PIIXPM_DELAY); 308 } 309 DPRINTF(("%s: exec: st 0x%d\n", sc->sc_dev.dv_xname, st & 0xff)); 310 if (st & PIIX_SMB_HS_BUSY) 311 return (1); 312 313 if (cold || sc->sc_poll) 314 flags |= I2C_F_POLL; 315 316 if (!I2C_OP_STOP_P(op) || cmdlen > 1 || len > 2) 317 return (1); 318 319 /* Setup transfer */ 320 sc->sc_i2c_xfer.op = op; 321 sc->sc_i2c_xfer.buf = buf; 322 sc->sc_i2c_xfer.len = len; 323 sc->sc_i2c_xfer.flags = flags; 324 sc->sc_i2c_xfer.error = 0; 325 326 /* Set slave address and transfer direction */ 327 bus_space_write_1(sc->sc_smb_iot, sc->sc_smb_ioh, PIIX_SMB_TXSLVA, 328 PIIX_SMB_TXSLVA_ADDR(addr) | 329 (I2C_OP_READ_P(op) ? PIIX_SMB_TXSLVA_READ : 0)); 330 331 b = cmdbuf; 332 if (cmdlen > 0) 333 /* Set command byte */ 334 bus_space_write_1(sc->sc_smb_iot, sc->sc_smb_ioh, 335 PIIX_SMB_HCMD, b[0]); 336 337 if (I2C_OP_WRITE_P(op)) { 338 /* Write data */ 339 b = buf; 340 if (len > 0) 341 bus_space_write_1(sc->sc_smb_iot, sc->sc_smb_ioh, 342 PIIX_SMB_HD0, b[0]); 343 if (len > 1) 344 bus_space_write_1(sc->sc_smb_iot, sc->sc_smb_ioh, 345 PIIX_SMB_HD1, b[1]); 346 } 347 348 /* Set SMBus command */ 349 if (len == 0) 350 ctl = PIIX_SMB_HC_CMD_BYTE; 351 else if (len == 1) 352 ctl = PIIX_SMB_HC_CMD_BDATA; 353 else if (len == 2) 354 ctl = PIIX_SMB_HC_CMD_WDATA; 355 356 if ((flags & I2C_F_POLL) == 0) 357 ctl |= PIIX_SMB_HC_INTREN; 358 359 /* Start transaction */ 360 ctl |= PIIX_SMB_HC_START; 361 bus_space_write_1(sc->sc_smb_iot, sc->sc_smb_ioh, PIIX_SMB_HC, ctl); 362 363 if (flags & I2C_F_POLL) { 364 /* Poll for completion */ 365 DELAY(PIIXPM_DELAY); 366 for (retries = 1000; retries > 0; retries--) { 367 st = bus_space_read_1(sc->sc_smb_iot, sc->sc_smb_ioh, 368 PIIX_SMB_HS); 369 if ((st & PIIX_SMB_HS_BUSY) == 0) 370 break; 371 DELAY(PIIXPM_DELAY); 372 } 373 if (st & PIIX_SMB_HS_BUSY) 374 goto timeout; 375 piixpm_intr(sc); 376 } else { 377 /* Wait for interrupt */ 378 if (tsleep(sc, PRIBIO, "iicexec", PIIXPM_TIMEOUT * hz)) 379 goto timeout; 380 } 381 382 if (sc->sc_i2c_xfer.error) 383 return (1); 384 385 return (0); 386 387 timeout: 388 /* 389 * Transfer timeout. Kill the transaction and clear status bits. 390 */ 391 aprint_error("%s: timeout, status 0x%x\n", sc->sc_dev.dv_xname, st); 392 bus_space_write_1(sc->sc_smb_iot, sc->sc_smb_ioh, PIIX_SMB_HC, 393 PIIX_SMB_HC_KILL); 394 DELAY(PIIXPM_DELAY); 395 st = bus_space_read_1(sc->sc_smb_iot, sc->sc_smb_ioh, PIIX_SMB_HS); 396 if ((st & PIIX_SMB_HS_FAILED) == 0) 397 aprint_error("%s: transaction abort failed, status 0x%x\n", 398 sc->sc_dev.dv_xname, st); 399 bus_space_write_1(sc->sc_smb_iot, sc->sc_smb_ioh, PIIX_SMB_HS, st); 400 return (1); 401 } 402 403 int 404 piixpm_intr(void *arg) 405 { 406 struct piixpm_softc *sc = arg; 407 u_int8_t st; 408 u_int8_t *b; 409 size_t len; 410 411 /* Read status */ 412 st = bus_space_read_1(sc->sc_smb_iot, sc->sc_smb_ioh, PIIX_SMB_HS); 413 if ((st & PIIX_SMB_HS_BUSY) != 0 || (st & (PIIX_SMB_HS_INTR | 414 PIIX_SMB_HS_DEVERR | PIIX_SMB_HS_BUSERR | 415 PIIX_SMB_HS_FAILED)) == 0) 416 /* Interrupt was not for us */ 417 return (0); 418 419 DPRINTF(("%s: intr st 0x%d\n", sc->sc_dev.dv_xname, st & 0xff)); 420 421 /* Clear status bits */ 422 bus_space_write_1(sc->sc_smb_iot, sc->sc_smb_ioh, PIIX_SMB_HS, st); 423 424 /* Check for errors */ 425 if (st & (PIIX_SMB_HS_DEVERR | PIIX_SMB_HS_BUSERR | 426 PIIX_SMB_HS_FAILED)) { 427 sc->sc_i2c_xfer.error = 1; 428 goto done; 429 } 430 431 if (st & PIIX_SMB_HS_INTR) { 432 if (I2C_OP_WRITE_P(sc->sc_i2c_xfer.op)) 433 goto done; 434 435 /* Read data */ 436 b = sc->sc_i2c_xfer.buf; 437 len = sc->sc_i2c_xfer.len; 438 if (len > 0) 439 b[0] = bus_space_read_1(sc->sc_smb_iot, sc->sc_smb_ioh, 440 PIIX_SMB_HD0); 441 if (len > 1) 442 b[1] = bus_space_read_1(sc->sc_smb_iot, sc->sc_smb_ioh, 443 PIIX_SMB_HD1); 444 } 445 446 done: 447 if ((sc->sc_i2c_xfer.flags & I2C_F_POLL) == 0) 448 wakeup(sc); 449 return (1); 450 } 451