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