1 /* $NetBSD: gtpci.c,v 1.27 2010/08/01 06:57:06 kiyohara Exp $ */ 2 /* 3 * Copyright (c) 2008, 2009 KIYOHARA Takashi 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 19 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 21 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 23 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 24 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25 * POSSIBILITY OF SUCH DAMAGE. 26 */ 27 28 #include <sys/cdefs.h> 29 __KERNEL_RCSID(0, "$NetBSD: gtpci.c,v 1.27 2010/08/01 06:57:06 kiyohara Exp $"); 30 31 #include "opt_pci.h" 32 #include "pci.h" 33 34 #include <sys/param.h> 35 #include <sys/bus.h> 36 #include <sys/device.h> 37 #include <sys/errno.h> 38 #include <sys/extent.h> 39 #include <sys/malloc.h> 40 41 #include <prop/proplib.h> 42 43 #include <dev/pci/pcireg.h> 44 #include <dev/pci/pcivar.h> 45 #include <dev/pci/pciconf.h> 46 47 #include <dev/marvell/gtpcireg.h> 48 #include <dev/marvell/gtpcivar.h> 49 #include <dev/marvell/marvellreg.h> 50 #include <dev/marvell/marvellvar.h> 51 52 #include <machine/pci_machdep.h> 53 54 #include "locators.h" 55 56 57 #define GTPCI_READ(sc, r) \ 58 bus_space_read_4((sc)->sc_iot, (sc)->sc_ioh, r((sc)->sc_unit)) 59 #define GTPCI_WRITE(sc, r, v) \ 60 bus_space_write_4((sc)->sc_iot, (sc)->sc_ioh, r((sc)->sc_unit), (v)) 61 #define GTPCI_WRITE_AC(sc, r, n, v) \ 62 bus_space_write_4((sc)->sc_iot, (sc)->sc_ioh, r((sc)->sc_unit, (n)), (v)) 63 64 65 static int gtpci_match(device_t, struct cfdata *, void *); 66 static void gtpci_attach(device_t, device_t, void *); 67 68 static void gtpci_init(struct gtpci_softc *, struct gtpci_prot *); 69 static void gtpci_barinit(struct gtpci_softc *); 70 static void gtpci_protinit(struct gtpci_softc *, struct gtpci_prot *); 71 #if NPCI > 0 72 static void gtpci_pci_config(struct gtpci_softc *, bus_space_tag_t, 73 bus_space_tag_t, bus_dma_tag_t, pci_chipset_tag_t, 74 u_long, u_long, u_long, u_long, int); 75 #endif 76 77 78 CFATTACH_DECL_NEW(gtpci_gt, sizeof(struct gtpci_softc), 79 gtpci_match, gtpci_attach, NULL, NULL); 80 CFATTACH_DECL_NEW(gtpci_mbus, sizeof(struct gtpci_softc), 81 gtpci_match, gtpci_attach, NULL, NULL); 82 83 84 /* ARGSUSED */ 85 static int 86 gtpci_match(device_t parent, struct cfdata *match, void *aux) 87 { 88 struct marvell_attach_args *mva = aux; 89 90 if (strcmp(mva->mva_name, match->cf_name) != 0) 91 return 0; 92 93 if (mva->mva_unit == MVA_UNIT_DEFAULT) 94 return 0; 95 switch (mva->mva_model) { 96 case MARVELL_DISCOVERY: 97 case MARVELL_DISCOVERY_II: 98 case MARVELL_DISCOVERY_III: 99 #if 0 /* XXXXX */ 100 case MARVELL_DISCOVERY_LT: 101 case MARVELL_DISCOVERY_V: 102 case MARVELL_DISCOVERY_VI: 103 #endif 104 if (mva->mva_offset != MVA_OFFSET_DEFAULT) 105 return 0; 106 } 107 108 mva->mva_size = GTPCI_SIZE; 109 return 1; 110 } 111 112 /* ARGSUSED */ 113 static void 114 gtpci_attach(device_t parent, device_t self, void *aux) 115 { 116 struct gtpci_softc *sc = device_private(self); 117 struct marvell_attach_args *mva = aux; 118 struct gtpci_prot *gtpci_prot; 119 prop_dictionary_t dict = device_properties(self); 120 prop_object_t prot; 121 #if NPCI > 0 122 prop_object_t pc, iot, memt; 123 prop_array_t int2gpp; 124 prop_object_t gpp; 125 pci_chipset_tag_t gtpci_chipset; 126 bus_space_tag_t gtpci_io_bs_tag, gtpci_mem_bs_tag; 127 uint64_t iostart = 0, ioend = 0, memstart = 0, memend = 0; 128 int cl_size = 0, intr; 129 #endif 130 131 aprint_normal(": Marvell PCI Interface\n"); 132 aprint_naive("\n"); 133 134 prot = prop_dictionary_get(dict, "prot"); 135 if (prot != NULL) { 136 KASSERT(prop_object_type(prot) == PROP_TYPE_DATA); 137 gtpci_prot = __UNCONST(prop_data_data_nocopy(prot)); 138 } else { 139 aprint_verbose_dev(self, "no protection property\n"); 140 gtpci_prot = NULL; 141 } 142 #if NPCI > 0 143 iot = prop_dictionary_get(dict, "io-bus-tag"); 144 if (iot != NULL) { 145 KASSERT(prop_object_type(iot) == PROP_TYPE_DATA); 146 gtpci_io_bs_tag = __UNCONST(prop_data_data_nocopy(iot)); 147 } else { 148 aprint_error_dev(self, "no io-bus-tag property\n"); 149 gtpci_io_bs_tag = NULL; 150 } 151 memt = prop_dictionary_get(dict, "mem-bus-tag"); 152 if (memt != NULL) { 153 KASSERT(prop_object_type(memt) == PROP_TYPE_DATA); 154 gtpci_mem_bs_tag = __UNCONST(prop_data_data_nocopy(memt)); 155 } else { 156 aprint_error_dev(self, "no mem-bus-tag property\n"); 157 gtpci_mem_bs_tag = NULL; 158 } 159 pc = prop_dictionary_get(dict, "pci-chipset"); 160 if (pc == NULL) { 161 aprint_error_dev(self, "no pci-chipset property\n"); 162 return; 163 } 164 KASSERT(prop_object_type(pc) == PROP_TYPE_DATA); 165 gtpci_chipset = __UNCONST(prop_data_data_nocopy(pc)); 166 #ifdef PCI_NETBSD_CONFIGURE 167 if (!prop_dictionary_get_uint64(dict, "iostart", &iostart)) { 168 aprint_error_dev(self, "no iostart property\n"); 169 return; 170 } 171 if (!prop_dictionary_get_uint64(dict, "ioend", &ioend)) { 172 aprint_error_dev(self, "no ioend property\n"); 173 return; 174 } 175 if (!prop_dictionary_get_uint64(dict, "memstart", &memstart)) { 176 aprint_error_dev(self, "no memstart property\n"); 177 return; 178 } 179 if (!prop_dictionary_get_uint64(dict, "memend", &memend)) { 180 aprint_error_dev(self, "no memend property\n"); 181 return; 182 } 183 if (!prop_dictionary_get_uint32(dict, "cache-line-size", &cl_size)) { 184 aprint_error_dev(self, "no cache-line-size property\n"); 185 return; 186 } 187 #endif 188 #endif 189 190 sc->sc_dev = self; 191 sc->sc_model = mva->mva_model; 192 sc->sc_rev = mva->mva_revision; 193 sc->sc_unit = mva->mva_unit; 194 sc->sc_iot = mva->mva_iot; 195 if (bus_space_subregion(mva->mva_iot, mva->mva_ioh, 196 (mva->mva_offset != MVA_OFFSET_DEFAULT) ? mva->mva_offset : 0, 197 mva->mva_size, &sc->sc_ioh)) { 198 aprint_error_dev(self, "can't map registers\n"); 199 return; 200 } 201 sc->sc_pc = gtpci_chipset; 202 gtpci_init(sc, gtpci_prot); 203 204 #if NPCI > 0 205 int2gpp = prop_dictionary_get(dict, "int2gpp"); 206 if (int2gpp != NULL) { 207 if (prop_object_type(int2gpp) != PROP_TYPE_ARRAY) { 208 aprint_error_dev(self, "int2gpp not an array\n"); 209 return; 210 } 211 aprint_normal_dev(self, "use intrrupt pin:"); 212 for (intr = PCI_INTERRUPT_PIN_A; 213 intr <= PCI_INTERRUPT_PIN_D && 214 intr < prop_array_count(int2gpp); 215 intr++) { 216 gpp = prop_array_get(int2gpp, intr); 217 if (prop_object_type(gpp) != PROP_TYPE_NUMBER) { 218 aprint_error_dev(self, 219 "int2gpp[%d] not an number\n", intr); 220 return; 221 } 222 aprint_normal(" %d", 223 (int)prop_number_integer_value(gpp)); 224 } 225 aprint_normal("\n"); 226 } 227 228 gtpci_pci_config(sc, gtpci_io_bs_tag, gtpci_mem_bs_tag, mva->mva_dmat, 229 gtpci_chipset, iostart, ioend, memstart, memend, cl_size); 230 #endif 231 } 232 233 static void 234 gtpci_init(struct gtpci_softc *sc, struct gtpci_prot *prot) 235 { 236 uint32_t reg; 237 238 /* First, all disable. Also WA CQ 4382 (bit15 must set 1)*/ 239 GTPCI_WRITE(sc, GTPCI_BARE, GTPCI_BARE_ALLDISABLE | (1 << 15)); 240 241 /* Enable Internal Arbiter */ 242 reg = GTPCI_READ(sc, GTPCI_AC); 243 reg |= GTPCI_AC_EN; 244 GTPCI_WRITE(sc, GTPCI_AC, reg); 245 246 gtpci_barinit(sc); 247 if (prot != NULL) 248 gtpci_protinit(sc, prot); 249 250 reg = GTPCI_READ(sc, GTPCI_ADC); 251 reg |= GTPCI_ADC_REMAPWRDIS; 252 GTPCI_WRITE(sc, GTPCI_ADC, reg); 253 254 /* enable CPU-2-PCI ordering */ 255 reg = GTPCI_READ(sc, GTPCI_C); 256 reg |= GTPCI_C_CPU2PCIORDERING; 257 GTPCI_WRITE(sc, GTPCI_C, reg); 258 } 259 260 static void 261 gtpci_barinit(struct gtpci_softc *sc) 262 { 263 static const struct { 264 int tag; 265 int bars[2]; /* BAR Size registers */ 266 int bare; /* Bits of Base Address Registers Enable */ 267 int func; 268 int balow; 269 int bahigh; 270 } maps[] = { 271 { MARVELL_TAG_SDRAM_CS0, 272 { GTPCI_CS0BARS(0), GTPCI_CS0BARS(1) }, 273 GTPCI_BARE_CS0EN, 0, 0x10, 0x14 }, 274 { MARVELL_TAG_SDRAM_CS1, 275 { GTPCI_CS1BARS(0), GTPCI_CS1BARS(1) }, 276 GTPCI_BARE_CS1EN, 0, 0x18, 0x1c }, 277 { MARVELL_TAG_SDRAM_CS2, 278 { GTPCI_CS2BARS(0), GTPCI_CS2BARS(1) }, 279 GTPCI_BARE_CS2EN, 1, 0x10, 0x14 }, 280 { MARVELL_TAG_SDRAM_CS3, 281 { GTPCI_CS3BARS(0), GTPCI_CS3BARS(1) }, 282 GTPCI_BARE_CS3EN, 1, 0x18, 0x1c }, 283 #if 0 284 { ORION_TARGETID_INTERNALREG, 285 { -1, -1 }, 286 GTPCI_BARE_INTMEMEN, 0, 0x20, 0x24 }, 287 288 { ORION_TARGETID_DEVICE_CS0, 289 { GTPCI_DCS0BARS(0), GTPCI_DCS0BARS(1) }, 290 GTPCI_BARE_DEVCS0EN, 2, 0x10, 0x14 }, 291 { ORION_TARGETID_DEVICE_CS1, 292 { GTPCI_DCS1BARS(0), GTPCI_DCS1BARS(1) }, 293 GTPCI_BARE_DEVCS1EN, 2, 0x18, 0x1c }, 294 { ORION_TARGETID_DEVICE_CS2, 295 { GTPCI_DCS2BARS(0), GTPCI_DCS2BARS(1) }, 296 GTPCI_BARE_DEVCS2EN, 2, 0x20, 0x24 }, 297 { ORION_TARGETID_DEVICE_BOOTCS, 298 { GTPCI_BCSBARS(0), GTPCI_BCSBARS(1) }, 299 GTPCI_BARE_BOOTCSEN, 3, 0x18, 0x1c }, 300 { P2P Mem0 BAR, 301 { GTPCI_P2PM0BARS(0), GTPCI_P2PM0BARS(1) }, 302 GTPCI_BARE_P2PMEM0EN, 4, 0x10, 0x14 }, 303 { P2P I/O BAR, 304 { GTPCI_P2PIOBARS(0), GTPCI_P2PIOBARS(1) }, 305 GTPCI_BARE_P2PIO0EN, 4, 0x20, 0x24 }, 306 { Expansion ROM BAR, 307 { GTPCI_EROMBARS(0), GTPCI_EROMBARS(1) }, 308 0, }, 309 #endif 310 311 { MARVELL_TAG_UNDEFINED, 312 { -1, -1 }, 313 -1, -1, 0x00, 0x00 }, 314 }; 315 device_t pdev = device_parent(sc->sc_dev); 316 uint64_t base; 317 uint32_t p2pc, size, bare; 318 int map, bus, dev, rv; 319 320 p2pc = GTPCI_READ(sc, GTPCI_P2PC); 321 bus = GTPCI_P2PC_BUSNUMBER(p2pc); 322 dev = GTPCI_P2PC_DEVNUM(p2pc); 323 324 bare = GTPCI_BARE_ALLDISABLE; 325 for (map = 0; maps[map].tag != MARVELL_TAG_UNDEFINED; map++) { 326 rv = marvell_winparams_by_tag(pdev, maps[map].tag, NULL, NULL, 327 &base, &size); 328 if (rv != 0 || size == 0) 329 continue; 330 331 if (maps[map].bars[sc->sc_unit] != -1) 332 bus_space_write_4(sc->sc_iot, sc->sc_ioh, 333 maps[map].bars[sc->sc_unit], GTPCI_BARSIZE(size)); 334 bare &= ~maps[map].bare; 335 336 #if 0 /* shall move to pchb(4)? */ 337 if (maps[map].func != -1) { 338 pcitag_t tag; 339 pcireg_t reg; 340 341 tag = gtpci_make_tag(NULL, bus, dev, maps[map].func); 342 reg = gtpci_conf_read(sc, tag, maps[map].balow); 343 reg &= ~GTPCI_BARLOW_MASK; 344 reg |= GTPCI_BARLOW_BASE(base); 345 gtpci_conf_write(sc, tag, maps[map].balow, reg); 346 reg = gtpci_conf_read(sc, tag, maps[map].bahigh); 347 reg = (base >> 16) >> 16; 348 gtpci_conf_write(sc, tag, maps[map].bahigh, reg); 349 } 350 #endif 351 } 352 GTPCI_WRITE(sc, GTPCI_BARE, bare); 353 } 354 355 static void 356 gtpci_protinit(struct gtpci_softc *sc, struct gtpci_prot *ac_flags) 357 { 358 enum { 359 gt642xx = 0, 360 mv643xx, 361 arm_soc, 362 }; 363 const struct gtpci_ac_rshift { 364 uint32_t base_rshift; 365 uint32_t size_rshift; 366 } ac_rshifts[] = { 367 { 20, 20, }, /* GT642xx */ 368 { 0, 0, }, /* MV643xx and after */ 369 { 0, 0, }, /* ARM SoC */ 370 }; 371 const uint32_t prot_tags[] = { 372 MARVELL_TAG_SDRAM_CS0, 373 MARVELL_TAG_SDRAM_CS1, 374 MARVELL_TAG_SDRAM_CS2, 375 MARVELL_TAG_SDRAM_CS3, 376 MARVELL_TAG_UNDEFINED 377 }; 378 device_t pdev = device_parent(sc->sc_dev); 379 uint64_t acbase, base; 380 uint32_t acsize, size; 381 int base_rshift, size_rshift, acbl_flags, acs_flags; 382 int prot, rv, p, t; 383 384 switch (sc->sc_model) { 385 case MARVELL_DISCOVERY: 386 p = gt642xx; 387 break; 388 389 case MARVELL_DISCOVERY_II: 390 case MARVELL_DISCOVERY_III: 391 #if 0 392 case MARVELL_DISCOVERY_LT: 393 case MARVELL_DISCOVERY_V: 394 case MARVELL_DISCOVERY_VI: 395 #endif 396 p = mv643xx; 397 break; 398 399 default: 400 p = arm_soc; 401 break; 402 } 403 base_rshift = ac_rshifts[p].base_rshift; 404 size_rshift = ac_rshifts[p].size_rshift; 405 acbl_flags = ac_flags->acbl_flags; 406 acs_flags = ac_flags->acs_flags; 407 408 t = 0; 409 for (prot = 0; prot < GTPCI_NPCIAC; prot++) { 410 acbase = acsize = 0; 411 412 for ( ; prot_tags[t] != MARVELL_TAG_UNDEFINED; t++) { 413 rv = marvell_winparams_by_tag(pdev, prot_tags[t], 414 NULL, NULL, &base, &size); 415 if (rv != 0 || size == 0) 416 continue; 417 418 if (acsize == 0 || base + size == acbase) 419 acbase = base; 420 else if (acbase + acsize != base) 421 break; 422 acsize += size; 423 } 424 425 if (acsize != 0) { 426 GTPCI_WRITE_AC(sc, GTPCI_ACBL, prot, 427 ((acbase & 0xffffffff) >> base_rshift) | acbl_flags); 428 GTPCI_WRITE_AC(sc, GTPCI_ACBH, prot, 429 (acbase >> 32) & 0xffffffff); 430 GTPCI_WRITE_AC(sc, GTPCI_ACS, prot, 431 ((acsize - 1) >> size_rshift) | acs_flags); 432 } else { 433 GTPCI_WRITE_AC(sc, GTPCI_ACBL, prot, 0); 434 GTPCI_WRITE_AC(sc, GTPCI_ACBH, prot, 0); 435 GTPCI_WRITE_AC(sc, GTPCI_ACS, prot, 0); 436 } 437 } 438 return; 439 } 440 441 #if NPCI > 0 442 static void 443 gtpci_pci_config(struct gtpci_softc *sc, bus_space_tag_t iot, 444 bus_space_tag_t memt, bus_dma_tag_t dmat, pci_chipset_tag_t pc, 445 u_long iostart, u_long ioend, u_long memstart, u_long memend, 446 int cacheline_size) 447 { 448 struct pcibus_attach_args pba; 449 #ifdef PCI_NETBSD_CONFIGURE 450 struct extent *ioext = NULL, *memext = NULL; 451 #endif 452 uint32_t p2pc, command; 453 454 p2pc = GTPCI_READ(sc, GTPCI_P2PC); 455 456 #ifdef PCI_NETBSD_CONFIGURE 457 ioext = extent_create("pciio", iostart, ioend, M_DEVBUF, NULL, 0, 458 EX_NOWAIT); 459 memext = extent_create("pcimem", memstart, memend, M_DEVBUF, NULL, 0, 460 EX_NOWAIT); 461 if (ioext != NULL && memext != NULL) 462 pci_configure_bus(pc, ioext, memext, NULL, 463 GTPCI_P2PC_BUSNUMBER(p2pc), cacheline_size); 464 else 465 aprint_error_dev(sc->sc_dev, "can't create extent %s%s%s\n", 466 ioext == NULL ? "io" : "", 467 ioext == NULL && memext == NULL ? " and " : "", 468 memext == NULL ? "mem" : ""); 469 if (ioext != NULL) 470 extent_destroy(ioext); 471 if (memext != NULL) 472 extent_destroy(memext); 473 #endif 474 475 pba.pba_iot = iot; 476 pba.pba_memt = memt; 477 pba.pba_dmat = dmat; 478 pba.pba_dmat64 = NULL; 479 pba.pba_pc = pc; 480 if (iot == NULL || memt == NULL) { 481 pba.pba_flags = 0; 482 aprint_error_dev(sc->sc_dev, ""); 483 if (iot == NULL) 484 aprint_error("io "); 485 else 486 pba.pba_flags |= PCI_FLAGS_IO_ENABLED; 487 if (iot == NULL && memt == NULL) 488 aprint_error("and "); 489 if (memt == NULL) 490 aprint_error("mem"); 491 else 492 pba.pba_flags |= PCI_FLAGS_MEM_ENABLED; 493 aprint_error(" access disabled\n"); 494 } else 495 pba.pba_flags = PCI_FLAGS_IO_ENABLED | PCI_FLAGS_MEM_ENABLED; 496 command = GTPCI_READ(sc, GTPCI_C); 497 if (command & GTPCI_C_MRDMUL) 498 pba.pba_flags |= PCI_FLAGS_MRM_OKAY; 499 if (command & GTPCI_C_MRDLINE) 500 pba.pba_flags |= PCI_FLAGS_MRL_OKAY; 501 pba.pba_flags |= PCI_FLAGS_MWI_OKAY; 502 pba.pba_bus = GTPCI_P2PC_BUSNUMBER(p2pc); 503 pba.pba_bridgetag = NULL; 504 config_found_ia(sc->sc_dev, "pcibus", &pba, NULL); 505 } 506 507 508 /* 509 * Dependent code of PCI Interface of Marvell 510 */ 511 512 /* ARGSUSED */ 513 void 514 gtpci_attach_hook(device_t parent, device_t self, 515 struct pcibus_attach_args *pba) 516 { 517 518 /* Nothing */ 519 } 520 521 /* 522 * Bit map for configuration register: 523 * [31] ConfigEn 524 * [30:24] Reserved 525 * [23:16] BusNum 526 * [15:11] DevNum 527 * [10: 8] FunctNum 528 * [ 7: 2] RegNum 529 * [ 1: 0] reserved 530 */ 531 532 /* ARGSUSED */ 533 int 534 gtpci_bus_maxdevs(void *v, int busno) 535 { 536 537 return 32; /* 32 device/bus */ 538 } 539 540 /* ARGSUSED */ 541 pcitag_t 542 gtpci_make_tag(void *v, int bus, int dev, int func) 543 { 544 545 #if DIAGNOSTIC 546 if (bus >= 256 || dev >= 32 || func >= 8) 547 panic("pci_make_tag: bad request"); 548 #endif 549 550 return (bus << 16) | (dev << 11) | (func << 8); 551 } 552 553 /* ARGSUSED */ 554 void 555 gtpci_decompose_tag(void *v, pcitag_t tag, int *bp, int *dp, int *fp) 556 { 557 558 if (bp != NULL) 559 *bp = (tag >> 16) & 0xff; 560 if (dp != NULL) 561 *dp = (tag >> 11) & 0x1f; 562 if (fp != NULL) 563 *fp = (tag >> 8) & 0x07; 564 } 565 566 pcireg_t 567 gtpci_conf_read(void *v, pcitag_t tag, int reg) 568 { 569 struct gtpci_softc *sc = v; 570 const pcireg_t addr = tag | reg; 571 572 GTPCI_WRITE(sc, GTPCI_CA, addr | GTPCI_CA_CONFIGEN); 573 if ((addr | GTPCI_CA_CONFIGEN) != GTPCI_READ(sc, GTPCI_CA)) 574 return -1; 575 576 return GTPCI_READ(sc, GTPCI_CD); 577 } 578 579 void 580 gtpci_conf_write(void *v, pcitag_t tag, int reg, pcireg_t data) 581 { 582 struct gtpci_softc *sc = v; 583 pcireg_t addr = tag | (reg & 0xfc); 584 585 GTPCI_WRITE(sc, GTPCI_CA, addr | GTPCI_CA_CONFIGEN); 586 if ((addr | GTPCI_CA_CONFIGEN) != GTPCI_READ(sc, GTPCI_CA)) 587 return; 588 589 GTPCI_WRITE(sc, GTPCI_CD, data); 590 } 591 592 /* ARGSUSED */ 593 int 594 gtpci_conf_hook(pci_chipset_tag_t pc, int bus, int dev, int func, pcireg_t id) 595 { 596 /* Oops, We have two PCI buses. */ 597 if (dev == 0 && 598 PCI_VENDOR(id) == PCI_VENDOR_MARVELL) { 599 switch (PCI_PRODUCT(id)) { 600 case MARVELL_DISCOVERY: 601 case MARVELL_DISCOVERY_II: 602 case MARVELL_DISCOVERY_III: 603 #if 0 604 case MARVELL_DISCOVERY_LT: 605 case MARVELL_DISCOVERY_V: 606 case MARVELL_DISCOVERY_VI: 607 #endif 608 case MARVELL_ORION_1_88F5180N: 609 case MARVELL_ORION_1_88F5181: 610 case MARVELL_ORION_1_88F5182: 611 case MARVELL_ORION_2_88F5281: 612 case MARVELL_ORION_1_88W8660: 613 /* Don't configure us. */ 614 return 0; 615 } 616 } 617 618 return PCI_CONF_DEFAULT; 619 } 620 #endif /* NPCI > 0 */ 621