1 /*- 2 * Copyright (C) 2014 Intel Corporation 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. Neither the name of Intel Corporation nor the names of its 14 * contributors may be used to endorse or promote products derived from 15 * this software without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 */ 29 30 #include <sys/cdefs.h> 31 __FBSDID("$FreeBSD$"); 32 33 #include <sys/param.h> 34 #include <sys/systm.h> 35 #include <sys/bus.h> 36 #include <sys/errno.h> 37 #include <sys/kernel.h> 38 #include <sys/lock.h> 39 #include <sys/module.h> 40 #include <sys/priority.h> 41 #include <sys/proc.h> 42 #include <sys/syslog.h> 43 44 #include <machine/bus.h> 45 #include <sys/rman.h> 46 #include <machine/resource.h> 47 48 #include <dev/pci/pcireg.h> 49 #include <dev/pci/pcivar.h> 50 #include <dev/smbus/smbconf.h> 51 52 #include "smbus_if.h" 53 54 #define ISMT_DESC_ENTRIES 32 55 56 /* Hardware Descriptor Constants - Control Field */ 57 #define ISMT_DESC_CWRL 0x01 /* Command/Write Length */ 58 #define ISMT_DESC_BLK 0X04 /* Perform Block Transaction */ 59 #define ISMT_DESC_FAIR 0x08 /* Set fairness flag upon successful arbit. */ 60 #define ISMT_DESC_PEC 0x10 /* Packet Error Code */ 61 #define ISMT_DESC_I2C 0x20 /* I2C Enable */ 62 #define ISMT_DESC_INT 0x40 /* Interrupt */ 63 #define ISMT_DESC_SOE 0x80 /* Stop On Error */ 64 65 /* Hardware Descriptor Constants - Status Field */ 66 #define ISMT_DESC_SCS 0x01 /* Success */ 67 #define ISMT_DESC_DLTO 0x04 /* Data Low Time Out */ 68 #define ISMT_DESC_NAK 0x08 /* NAK Received */ 69 #define ISMT_DESC_CRC 0x10 /* CRC Error */ 70 #define ISMT_DESC_CLTO 0x20 /* Clock Low Time Out */ 71 #define ISMT_DESC_COL 0x40 /* Collisions */ 72 #define ISMT_DESC_LPR 0x80 /* Large Packet Received */ 73 74 /* Macros */ 75 #define ISMT_DESC_ADDR_RW(addr, is_read) ((addr << 1) | (is_read)) 76 77 /* iSMT General Register address offsets (SMBBAR + <addr>) */ 78 #define ISMT_GR_GCTRL 0x000 /* General Control */ 79 #define ISMT_GR_SMTICL 0x008 /* SMT Interrupt Cause Location */ 80 #define ISMT_GR_ERRINTMSK 0x010 /* Error Interrupt Mask */ 81 #define ISMT_GR_ERRAERMSK 0x014 /* Error AER Mask */ 82 #define ISMT_GR_ERRSTS 0x018 /* Error Status */ 83 #define ISMT_GR_ERRINFO 0x01c /* Error Information */ 84 85 /* iSMT Master Registers */ 86 #define ISMT_MSTR_MDBA 0x100 /* Master Descriptor Base Address */ 87 #define ISMT_MSTR_MCTRL 0x108 /* Master Control */ 88 #define ISMT_MSTR_MSTS 0x10c /* Master Status */ 89 #define ISMT_MSTR_MDS 0x110 /* Master Descriptor Size */ 90 #define ISMT_MSTR_RPOLICY 0x114 /* Retry Policy */ 91 92 /* iSMT Miscellaneous Registers */ 93 #define ISMT_SPGT 0x300 /* SMBus PHY Global Timing */ 94 95 /* General Control Register (GCTRL) bit definitions */ 96 #define ISMT_GCTRL_TRST 0x04 /* Target Reset */ 97 #define ISMT_GCTRL_KILL 0x08 /* Kill */ 98 #define ISMT_GCTRL_SRST 0x40 /* Soft Reset */ 99 100 /* Master Control Register (MCTRL) bit definitions */ 101 #define ISMT_MCTRL_SS 0x01 /* Start/Stop */ 102 #define ISMT_MCTRL_MEIE 0x10 /* Master Error Interrupt Enable */ 103 #define ISMT_MCTRL_FMHP 0x00ff0000 /* Firmware Master Head Ptr (FMHP) */ 104 105 /* Master Status Register (MSTS) bit definitions */ 106 #define ISMT_MSTS_HMTP 0xff0000 /* HW Master Tail Pointer (HMTP) */ 107 #define ISMT_MSTS_MIS 0x20 /* Master Interrupt Status (MIS) */ 108 #define ISMT_MSTS_MEIS 0x10 /* Master Error Int Status (MEIS) */ 109 #define ISMT_MSTS_IP 0x01 /* In Progress */ 110 111 /* Master Descriptor Size (MDS) bit definitions */ 112 #define ISMT_MDS_MASK 0xff /* Master Descriptor Size mask (MDS) */ 113 114 /* SMBus PHY Global Timing Register (SPGT) bit definitions */ 115 #define ISMT_SPGT_SPD_MASK 0xc0000000 /* SMBus Speed mask */ 116 #define ISMT_SPGT_SPD_80K 0x00 /* 80 kHz */ 117 #define ISMT_SPGT_SPD_100K (0x1 << 30) /* 100 kHz */ 118 #define ISMT_SPGT_SPD_400K (0x2 << 30) /* 400 kHz */ 119 #define ISMT_SPGT_SPD_1M (0x3 << 30) /* 1 MHz */ 120 121 /* MSI Control Register (MSICTL) bit definitions */ 122 #define ISMT_MSICTL_MSIE 0x01 /* MSI Enable */ 123 124 #define ISMT_MAX_BLOCK_SIZE 32 /* per SMBus spec */ 125 126 //#define ISMT_DEBUG device_printf 127 #ifndef ISMT_DEBUG 128 #define ISMT_DEBUG(...) 129 #endif 130 131 /* iSMT Hardware Descriptor */ 132 struct ismt_desc { 133 uint8_t tgtaddr_rw; /* target address & r/w bit */ 134 uint8_t wr_len_cmd; /* write length in bytes or a command */ 135 uint8_t rd_len; /* read length */ 136 uint8_t control; /* control bits */ 137 uint8_t status; /* status bits */ 138 uint8_t retry; /* collision retry and retry count */ 139 uint8_t rxbytes; /* received bytes */ 140 uint8_t txbytes; /* transmitted bytes */ 141 uint32_t dptr_low; /* lower 32 bit of the data pointer */ 142 uint32_t dptr_high; /* upper 32 bit of the data pointer */ 143 } __packed; 144 145 #define DESC_SIZE (ISMT_DESC_ENTRIES * sizeof(struct ismt_desc)) 146 147 #define DMA_BUFFER_SIZE 64 148 149 struct ismt_softc { 150 device_t pcidev; 151 device_t smbdev; 152 153 struct thread *bus_reserved; 154 155 int intr_rid; 156 struct resource *intr_res; 157 void *intr_handle; 158 159 bus_space_tag_t mmio_tag; 160 bus_space_handle_t mmio_handle; 161 int mmio_rid; 162 struct resource *mmio_res; 163 164 uint8_t head; 165 166 struct ismt_desc *desc; 167 bus_dma_tag_t desc_dma_tag; 168 bus_dmamap_t desc_dma_map; 169 uint64_t desc_bus_addr; 170 171 uint8_t *dma_buffer; 172 bus_dma_tag_t dma_buffer_dma_tag; 173 bus_dmamap_t dma_buffer_dma_map; 174 uint64_t dma_buffer_bus_addr; 175 176 uint8_t using_msi; 177 }; 178 179 static void 180 ismt_intr(void *arg) 181 { 182 struct ismt_softc *sc = arg; 183 uint32_t val; 184 185 val = bus_read_4(sc->mmio_res, ISMT_MSTR_MSTS); 186 ISMT_DEBUG(sc->pcidev, "%s MSTS=0x%x\n", __func__, val); 187 188 val |= (ISMT_MSTS_MIS | ISMT_MSTS_MEIS); 189 bus_write_4(sc->mmio_res, ISMT_MSTR_MSTS, val); 190 191 wakeup(sc); 192 } 193 194 static int 195 ismt_callback(device_t dev, int index, void *data) 196 { 197 struct ismt_softc *sc; 198 int acquired, err; 199 200 sc = device_get_softc(dev); 201 202 switch (index) { 203 case SMB_REQUEST_BUS: 204 acquired = atomic_cmpset_ptr( 205 (uintptr_t *)&sc->bus_reserved, 206 (uintptr_t)NULL, (uintptr_t)curthread); 207 ISMT_DEBUG(dev, "SMB_REQUEST_BUS acquired=%d\n", acquired); 208 if (acquired) 209 err = 0; 210 else 211 err = EWOULDBLOCK; 212 break; 213 case SMB_RELEASE_BUS: 214 KASSERT(sc->bus_reserved == curthread, 215 ("SMB_RELEASE_BUS called by wrong thread\n")); 216 ISMT_DEBUG(dev, "SMB_RELEASE_BUS\n"); 217 atomic_store_rel_ptr((uintptr_t *)&sc->bus_reserved, 218 (uintptr_t)NULL); 219 err = 0; 220 break; 221 default: 222 err = SMB_EABORT; 223 break; 224 } 225 226 return (err); 227 } 228 229 static struct ismt_desc * 230 ismt_alloc_desc(struct ismt_softc *sc) 231 { 232 struct ismt_desc *desc; 233 234 KASSERT(sc->bus_reserved == curthread, 235 ("curthread %p did not request bus (%p has reserved)\n", 236 curthread, sc->bus_reserved)); 237 238 desc = &sc->desc[sc->head++]; 239 if (sc->head == ISMT_DESC_ENTRIES) 240 sc->head = 0; 241 242 memset(desc, 0, sizeof(*desc)); 243 244 return (desc); 245 } 246 247 static int 248 ismt_submit(struct ismt_softc *sc, struct ismt_desc *desc, uint8_t slave, 249 uint8_t is_read) 250 { 251 uint32_t err, fmhp, val; 252 253 desc->control |= ISMT_DESC_FAIR; 254 if (sc->using_msi) 255 desc->control |= ISMT_DESC_INT; 256 257 desc->tgtaddr_rw = ISMT_DESC_ADDR_RW(slave, is_read); 258 desc->dptr_low = (sc->dma_buffer_bus_addr & 0xFFFFFFFFLL); 259 desc->dptr_high = (sc->dma_buffer_bus_addr >> 32); 260 261 wmb(); 262 263 fmhp = sc->head << 16; 264 val = bus_read_4(sc->mmio_res, ISMT_MSTR_MCTRL); 265 val &= ~ISMT_MCTRL_FMHP; 266 val |= fmhp; 267 bus_write_4(sc->mmio_res, ISMT_MSTR_MCTRL, val); 268 269 /* set the start bit */ 270 val = bus_read_4(sc->mmio_res, ISMT_MSTR_MCTRL); 271 val |= ISMT_MCTRL_SS; 272 bus_write_4(sc->mmio_res, ISMT_MSTR_MCTRL, val); 273 274 err = tsleep(sc, PWAIT, "ismt_wait", 5 * hz); 275 276 if (err != 0) { 277 ISMT_DEBUG(sc->pcidev, "%s timeout\n", __func__); 278 return (SMB_ETIMEOUT); 279 } 280 281 ISMT_DEBUG(sc->pcidev, "%s status=0x%x\n", __func__, desc->status); 282 283 if (desc->status & ISMT_DESC_SCS) 284 return (SMB_ENOERR); 285 286 if (desc->status & ISMT_DESC_NAK) 287 return (SMB_ENOACK); 288 289 if (desc->status & ISMT_DESC_CRC) 290 return (SMB_EBUSERR); 291 292 if (desc->status & ISMT_DESC_COL) 293 return (SMB_ECOLLI); 294 295 if (desc->status & ISMT_DESC_LPR) 296 return (SMB_EINVAL); 297 298 if (desc->status & (ISMT_DESC_DLTO | ISMT_DESC_CLTO)) 299 return (SMB_ETIMEOUT); 300 301 return (SMB_EBUSERR); 302 } 303 304 305 static int 306 ismt_quick(device_t dev, u_char slave, int how) 307 { 308 struct ismt_desc *desc; 309 struct ismt_softc *sc; 310 int is_read; 311 312 ISMT_DEBUG(dev, "%s\n", __func__); 313 314 if (how != SMB_QREAD && how != SMB_QWRITE) { 315 return (SMB_ENOTSUPP); 316 } 317 318 sc = device_get_softc(dev); 319 desc = ismt_alloc_desc(sc); 320 is_read = (how == SMB_QREAD ? 1 : 0); 321 return (ismt_submit(sc, desc, slave, is_read)); 322 } 323 324 static int 325 ismt_sendb(device_t dev, u_char slave, char byte) 326 { 327 struct ismt_desc *desc; 328 struct ismt_softc *sc; 329 330 ISMT_DEBUG(dev, "%s\n", __func__); 331 332 sc = device_get_softc(dev); 333 desc = ismt_alloc_desc(sc); 334 desc->control = ISMT_DESC_CWRL; 335 desc->wr_len_cmd = byte; 336 337 return (ismt_submit(sc, desc, slave, 0)); 338 } 339 340 static int 341 ismt_recvb(device_t dev, u_char slave, char *byte) 342 { 343 struct ismt_desc *desc; 344 struct ismt_softc *sc; 345 int err; 346 347 ISMT_DEBUG(dev, "%s\n", __func__); 348 349 sc = device_get_softc(dev); 350 desc = ismt_alloc_desc(sc); 351 desc->rd_len = 1; 352 353 err = ismt_submit(sc, desc, slave, 1); 354 355 if (err != SMB_ENOERR) 356 return (err); 357 358 *byte = sc->dma_buffer[0]; 359 360 return (err); 361 } 362 363 static int 364 ismt_writeb(device_t dev, u_char slave, char cmd, char byte) 365 { 366 struct ismt_desc *desc; 367 struct ismt_softc *sc; 368 369 ISMT_DEBUG(dev, "%s\n", __func__); 370 371 sc = device_get_softc(dev); 372 desc = ismt_alloc_desc(sc); 373 desc->wr_len_cmd = 2; 374 sc->dma_buffer[0] = cmd; 375 sc->dma_buffer[1] = byte; 376 377 return (ismt_submit(sc, desc, slave, 0)); 378 } 379 380 static int 381 ismt_writew(device_t dev, u_char slave, char cmd, short word) 382 { 383 struct ismt_desc *desc; 384 struct ismt_softc *sc; 385 386 ISMT_DEBUG(dev, "%s\n", __func__); 387 388 sc = device_get_softc(dev); 389 desc = ismt_alloc_desc(sc); 390 desc->wr_len_cmd = 3; 391 sc->dma_buffer[0] = cmd; 392 sc->dma_buffer[1] = word & 0xFF; 393 sc->dma_buffer[2] = word >> 8; 394 395 return (ismt_submit(sc, desc, slave, 0)); 396 } 397 398 static int 399 ismt_readb(device_t dev, u_char slave, char cmd, char *byte) 400 { 401 struct ismt_desc *desc; 402 struct ismt_softc *sc; 403 int err; 404 405 ISMT_DEBUG(dev, "%s\n", __func__); 406 407 sc = device_get_softc(dev); 408 desc = ismt_alloc_desc(sc); 409 desc->control = ISMT_DESC_CWRL; 410 desc->wr_len_cmd = cmd; 411 desc->rd_len = 1; 412 413 err = ismt_submit(sc, desc, slave, 1); 414 415 if (err != SMB_ENOERR) 416 return (err); 417 418 *byte = sc->dma_buffer[0]; 419 420 return (err); 421 } 422 423 static int 424 ismt_readw(device_t dev, u_char slave, char cmd, short *word) 425 { 426 struct ismt_desc *desc; 427 struct ismt_softc *sc; 428 int err; 429 430 ISMT_DEBUG(dev, "%s\n", __func__); 431 432 sc = device_get_softc(dev); 433 desc = ismt_alloc_desc(sc); 434 desc->control = ISMT_DESC_CWRL; 435 desc->wr_len_cmd = cmd; 436 desc->rd_len = 2; 437 438 err = ismt_submit(sc, desc, slave, 1); 439 440 if (err != SMB_ENOERR) 441 return (err); 442 443 *word = sc->dma_buffer[0] | (sc->dma_buffer[1] << 8); 444 445 return (err); 446 } 447 448 static int 449 ismt_pcall(device_t dev, u_char slave, char cmd, short sdata, short *rdata) 450 { 451 struct ismt_desc *desc; 452 struct ismt_softc *sc; 453 int err; 454 455 ISMT_DEBUG(dev, "%s\n", __func__); 456 457 sc = device_get_softc(dev); 458 desc = ismt_alloc_desc(sc); 459 desc->wr_len_cmd = 3; 460 desc->rd_len = 2; 461 sc->dma_buffer[0] = cmd; 462 sc->dma_buffer[1] = sdata & 0xff; 463 sc->dma_buffer[2] = sdata >> 8; 464 465 err = ismt_submit(sc, desc, slave, 0); 466 467 if (err != SMB_ENOERR) 468 return (err); 469 470 *rdata = sc->dma_buffer[0] | (sc->dma_buffer[1] << 8); 471 472 return (err); 473 } 474 475 static int 476 ismt_bwrite(device_t dev, u_char slave, char cmd, u_char count, char *buf) 477 { 478 struct ismt_desc *desc; 479 struct ismt_softc *sc; 480 481 ISMT_DEBUG(dev, "%s\n", __func__); 482 483 if (count == 0 || count > ISMT_MAX_BLOCK_SIZE) 484 return (SMB_EINVAL); 485 486 sc = device_get_softc(dev); 487 desc = ismt_alloc_desc(sc); 488 desc->control = ISMT_DESC_I2C; 489 desc->wr_len_cmd = count + 1; 490 sc->dma_buffer[0] = cmd; 491 memcpy(&sc->dma_buffer[1], buf, count); 492 493 return (ismt_submit(sc, desc, slave, 0)); 494 } 495 496 static int 497 ismt_bread(device_t dev, u_char slave, char cmd, u_char *count, char *buf) 498 { 499 struct ismt_desc *desc; 500 struct ismt_softc *sc; 501 int err; 502 503 ISMT_DEBUG(dev, "%s\n", __func__); 504 505 if (*count == 0 || *count > ISMT_MAX_BLOCK_SIZE) 506 return (SMB_EINVAL); 507 508 sc = device_get_softc(dev); 509 desc = ismt_alloc_desc(sc); 510 desc->control = ISMT_DESC_I2C | ISMT_DESC_CWRL; 511 desc->wr_len_cmd = cmd; 512 desc->rd_len = *count; 513 514 err = ismt_submit(sc, desc, slave, 0); 515 516 if (err != SMB_ENOERR) 517 return (err); 518 519 memcpy(buf, sc->dma_buffer, desc->rxbytes); 520 *count = desc->rxbytes; 521 522 return (err); 523 } 524 525 static int 526 ismt_detach(device_t dev) 527 { 528 struct ismt_softc *sc; 529 int error; 530 531 ISMT_DEBUG(dev, "%s\n", __func__); 532 sc = device_get_softc(dev); 533 534 error = bus_generic_detach(dev); 535 if (error) 536 return (error); 537 538 device_delete_child(dev, sc->smbdev); 539 540 if (sc->intr_handle != NULL) { 541 bus_teardown_intr(dev, sc->intr_res, sc->intr_handle); 542 sc->intr_handle = NULL; 543 } 544 if (sc->intr_res != NULL) { 545 bus_release_resource(dev, 546 SYS_RES_IRQ, sc->intr_rid, sc->intr_res); 547 sc->intr_res = NULL; 548 } 549 if (sc->using_msi == 1) 550 pci_release_msi(dev); 551 552 if (sc->mmio_res != NULL) { 553 bus_release_resource(dev, 554 SYS_RES_MEMORY, sc->mmio_rid, sc->mmio_res); 555 sc->mmio_res = NULL; 556 } 557 558 bus_dmamap_unload(sc->desc_dma_tag, sc->desc_dma_map); 559 bus_dmamap_unload(sc->dma_buffer_dma_tag, sc->dma_buffer_dma_map); 560 561 bus_dmamem_free(sc->desc_dma_tag, sc->desc, 562 sc->desc_dma_map); 563 bus_dmamem_free(sc->dma_buffer_dma_tag, sc->dma_buffer, 564 sc->dma_buffer_dma_map); 565 566 bus_dma_tag_destroy(sc->desc_dma_tag); 567 bus_dma_tag_destroy(sc->dma_buffer_dma_tag); 568 569 pci_disable_busmaster(dev); 570 571 return 0; 572 } 573 574 static void 575 ismt_single_map(void *arg, bus_dma_segment_t *seg, int nseg, int error) 576 { 577 uint64_t *bus_addr = (uint64_t *)arg; 578 579 KASSERT(error == 0, ("%s: error=%d\n", __func__, error)); 580 KASSERT(nseg == 1, ("%s: nseg=%d\n", __func__, nseg)); 581 582 *bus_addr = seg[0].ds_addr; 583 } 584 585 static int 586 ismt_attach(device_t dev) 587 { 588 struct ismt_softc *sc = device_get_softc(dev); 589 int err, num_vectors, val; 590 591 sc->pcidev = dev; 592 pci_enable_busmaster(dev); 593 594 if ((sc->smbdev = device_add_child(dev, "smbus", -1)) == NULL) { 595 device_printf(dev, "no smbus child found\n"); 596 err = ENXIO; 597 goto fail; 598 } 599 600 sc->mmio_rid = PCIR_BAR(0); 601 sc->mmio_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, 602 &sc->mmio_rid, RF_ACTIVE); 603 if (sc->mmio_res == NULL) { 604 device_printf(dev, "cannot allocate mmio region\n"); 605 err = ENOMEM; 606 goto fail; 607 } 608 609 sc->mmio_tag = rman_get_bustag(sc->mmio_res); 610 sc->mmio_handle = rman_get_bushandle(sc->mmio_res); 611 612 /* Attach "smbus" child */ 613 if ((err = bus_generic_attach(dev)) != 0) { 614 device_printf(dev, "failed to attach child: %d\n", err); 615 err = ENXIO; 616 goto fail; 617 } 618 619 bus_dma_tag_create(bus_get_dma_tag(dev), 4, PAGE_SIZE, 620 BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, NULL, NULL, 621 DESC_SIZE, 1, DESC_SIZE, 622 0, NULL, NULL, &sc->desc_dma_tag); 623 624 bus_dma_tag_create(bus_get_dma_tag(dev), 4, PAGE_SIZE, 625 BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, NULL, NULL, 626 DMA_BUFFER_SIZE, 1, DMA_BUFFER_SIZE, 627 0, NULL, NULL, &sc->dma_buffer_dma_tag); 628 629 bus_dmamap_create(sc->desc_dma_tag, 0, 630 &sc->desc_dma_map); 631 bus_dmamap_create(sc->dma_buffer_dma_tag, 0, 632 &sc->dma_buffer_dma_map); 633 634 bus_dmamem_alloc(sc->desc_dma_tag, 635 (void **)&sc->desc, BUS_DMA_WAITOK, 636 &sc->desc_dma_map); 637 bus_dmamem_alloc(sc->dma_buffer_dma_tag, 638 (void **)&sc->dma_buffer, BUS_DMA_WAITOK, 639 &sc->dma_buffer_dma_map); 640 641 bus_dmamap_load(sc->desc_dma_tag, 642 sc->desc_dma_map, sc->desc, DESC_SIZE, 643 ismt_single_map, &sc->desc_bus_addr, 0); 644 bus_dmamap_load(sc->dma_buffer_dma_tag, 645 sc->dma_buffer_dma_map, sc->dma_buffer, DMA_BUFFER_SIZE, 646 ismt_single_map, &sc->dma_buffer_bus_addr, 0); 647 648 bus_write_4(sc->mmio_res, ISMT_MSTR_MDBA, 649 (sc->desc_bus_addr & 0xFFFFFFFFLL)); 650 bus_write_4(sc->mmio_res, ISMT_MSTR_MDBA + 4, 651 (sc->desc_bus_addr >> 32)); 652 653 /* initialize the Master Control Register (MCTRL) */ 654 bus_write_4(sc->mmio_res, ISMT_MSTR_MCTRL, ISMT_MCTRL_MEIE); 655 656 /* initialize the Master Status Register (MSTS) */ 657 bus_write_4(sc->mmio_res, ISMT_MSTR_MSTS, 0); 658 659 /* initialize the Master Descriptor Size (MDS) */ 660 val = bus_read_4(sc->mmio_res, ISMT_MSTR_MDS); 661 val &= ~ISMT_MDS_MASK; 662 val |= (ISMT_DESC_ENTRIES - 1); 663 bus_write_4(sc->mmio_res, ISMT_MSTR_MDS, val); 664 665 sc->using_msi = 1; 666 667 if (pci_msi_count(dev) == 0) { 668 sc->using_msi = 0; 669 goto intx; 670 } 671 672 num_vectors = 1; 673 if (pci_alloc_msi(dev, &num_vectors) != 0) { 674 sc->using_msi = 0; 675 goto intx; 676 } 677 678 sc->intr_rid = 1; 679 sc->intr_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, 680 &sc->intr_rid, RF_ACTIVE); 681 682 if (sc->intr_res == NULL) { 683 sc->using_msi = 0; 684 pci_release_msi(dev); 685 } 686 687 intx: 688 if (sc->using_msi == 0) { 689 sc->intr_rid = 0; 690 sc->intr_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, 691 &sc->intr_rid, RF_SHAREABLE | RF_ACTIVE); 692 if (sc->intr_res == NULL) { 693 device_printf(dev, "cannot allocate irq\n"); 694 err = ENXIO; 695 goto fail; 696 } 697 } 698 699 ISMT_DEBUG(dev, "using_msi = %d\n", sc->using_msi); 700 701 err = bus_setup_intr(dev, sc->intr_res, 702 INTR_TYPE_MISC | INTR_MPSAFE, NULL, ismt_intr, sc, 703 &sc->intr_handle); 704 if (err != 0) { 705 device_printf(dev, "cannot setup interrupt\n"); 706 err = ENXIO; 707 goto fail; 708 } 709 710 return (0); 711 712 fail: 713 ismt_detach(dev); 714 return (err); 715 } 716 717 #define ID_INTEL_S1200_SMT0 0x0c598086 718 #define ID_INTEL_S1200_SMT1 0x0c5a8086 719 #define ID_INTEL_C2000_SMT 0x1f158086 720 721 static int 722 ismt_probe(device_t dev) 723 { 724 const char *desc; 725 726 switch (pci_get_devid(dev)) { 727 case ID_INTEL_S1200_SMT0: 728 desc = "Atom Processor S1200 SMBus 2.0 Controller 0"; 729 break; 730 case ID_INTEL_S1200_SMT1: 731 desc = "Atom Processor S1200 SMBus 2.0 Controller 1"; 732 break; 733 case ID_INTEL_C2000_SMT: 734 desc = "Atom Processor C2000 SMBus 2.0"; 735 break; 736 default: 737 return (ENXIO); 738 } 739 740 device_set_desc(dev, desc); 741 return (BUS_PROBE_DEFAULT); 742 } 743 744 /* Device methods */ 745 static device_method_t ismt_pci_methods[] = { 746 DEVMETHOD(device_probe, ismt_probe), 747 DEVMETHOD(device_attach, ismt_attach), 748 DEVMETHOD(device_detach, ismt_detach), 749 750 DEVMETHOD(smbus_callback, ismt_callback), 751 DEVMETHOD(smbus_quick, ismt_quick), 752 DEVMETHOD(smbus_sendb, ismt_sendb), 753 DEVMETHOD(smbus_recvb, ismt_recvb), 754 DEVMETHOD(smbus_writeb, ismt_writeb), 755 DEVMETHOD(smbus_writew, ismt_writew), 756 DEVMETHOD(smbus_readb, ismt_readb), 757 DEVMETHOD(smbus_readw, ismt_readw), 758 DEVMETHOD(smbus_pcall, ismt_pcall), 759 DEVMETHOD(smbus_bwrite, ismt_bwrite), 760 DEVMETHOD(smbus_bread, ismt_bread), 761 762 DEVMETHOD_END 763 }; 764 765 static driver_t ismt_pci_driver = { 766 "ismt", 767 ismt_pci_methods, 768 sizeof(struct ismt_softc) 769 }; 770 771 static devclass_t ismt_pci_devclass; 772 773 DRIVER_MODULE(ismt, pci, ismt_pci_driver, ismt_pci_devclass, 0, 0); 774 DRIVER_MODULE(smbus, ismt, smbus_driver, smbus_devclass, 0, 0); 775 776 MODULE_DEPEND(ismt, pci, 1, 1, 1); 777 MODULE_DEPEND(ismt, smbus, SMBUS_MINVER, SMBUS_PREFVER, SMBUS_MAXVER); 778 MODULE_VERSION(ismt, 1); 779