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