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