1 /* $NetBSD: gtpci.c,v 1.22 2010/04/28 13:51:56 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.22 2010/04/28 13:51:56 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/gpio.h> 40 #include <sys/malloc.h> 41 42 #include <prop/proplib.h> 43 44 #include <dev/pci/pcireg.h> 45 #include <dev/pci/pcivar.h> 46 #include <dev/pci/pciconf.h> 47 48 #include <dev/marvell/gtpcireg.h> 49 #include <dev/marvell/gtpcivar.h> 50 #include <dev/marvell/marvellreg.h> 51 #include <dev/marvell/marvellvar.h> 52 53 #include <machine/pci_machdep.h> 54 55 #include "locators.h" 56 57 58 #define GTPCI_READ(sc, r) \ 59 bus_space_read_4((sc)->sc_iot, (sc)->sc_ioh, r((sc)->sc_unit)) 60 #define GTPCI_WRITE(sc, r, v) \ 61 bus_space_write_4((sc)->sc_iot, (sc)->sc_ioh, r((sc)->sc_unit), (v)) 62 #define GTPCI_WRITE_AC(sc, r, n, v) \ 63 bus_space_write_4((sc)->sc_iot, (sc)->sc_ioh, r((sc)->sc_unit, (n)), (v)) 64 65 66 static int gtpci_match(device_t, struct cfdata *, void *); 67 static void gtpci_attach(device_t, device_t, void *); 68 69 static void gtpci_init(struct gtpci_softc *); 70 static void gtpci_barinit(struct gtpci_softc *); 71 static void gtpci_protinit(struct gtpci_softc *); 72 #if NPCI > 0 73 static void gtpci_pci_config(struct gtpci_softc *, bus_space_tag_t, 74 bus_space_tag_t, bus_dma_tag_t, pci_chipset_tag_t, 75 u_long, u_long, u_long, u_long, int); 76 #endif 77 78 79 CFATTACH_DECL_NEW(gtpci_gt, sizeof(struct gtpci_softc), 80 gtpci_match, gtpci_attach, NULL, NULL); 81 CFATTACH_DECL_NEW(gtpci_mbus, sizeof(struct gtpci_softc), 82 gtpci_match, gtpci_attach, NULL, NULL); 83 84 85 /* ARGSUSED */ 86 static int 87 gtpci_match(device_t parent, struct cfdata *match, void *aux) 88 { 89 struct marvell_attach_args *mva = aux; 90 91 if (strcmp(mva->mva_name, match->cf_name) != 0) 92 return 0; 93 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_unit == GTCF_UNIT_DEFAULT || 104 mva->mva_offset != GTCF_OFFSET_DEFAULT) 105 return 0; 106 break; 107 108 case MARVELL_ORION_1_88F5180N: 109 case MARVELL_ORION_1_88F5181: 110 case MARVELL_ORION_1_88F5182: 111 case MARVELL_ORION_2_88F5281: 112 case MARVELL_ORION_1_88W8660: 113 if (mva->mva_offset == GTCF_OFFSET_DEFAULT) 114 return 0; 115 mva->mva_unit = 0; /* unit 0 only */ 116 break; 117 118 default: 119 return 0; 120 } 121 122 mva->mva_size = GTPCI_SIZE; 123 return 1; 124 } 125 126 /* ARGSUSED */ 127 static void 128 gtpci_attach(device_t parent, device_t self, void *aux) 129 { 130 struct gtpci_softc *sc = device_private(self); 131 struct marvell_attach_args *mva = aux; 132 #if NPCI > 0 133 prop_dictionary_t dict = device_properties(self); 134 prop_object_t pc, iot, memt; 135 prop_array_t int2gpp; 136 prop_object_t gpp; 137 pci_chipset_tag_t gtpci_chipset; 138 bus_space_tag_t gtpci_io_bs_tag, gtpci_mem_bs_tag; 139 uint64_t iostart = 0, ioend = 0, memstart = 0, memend = 0; 140 int cl_size = 0, intr; 141 #endif 142 143 aprint_normal(": Marvell PCI Interface\n"); 144 aprint_naive("\n"); 145 146 #if NPCI > 0 147 iot = prop_dictionary_get(dict, "io-bus-tag"); 148 if (iot == NULL) 149 aprint_error_dev(self, "no io-bus-tag property\n"); 150 KASSERT(prop_object_type(iot) == PROP_TYPE_DATA); 151 gtpci_io_bs_tag = __UNCONST(prop_data_data_nocopy(iot)); 152 memt = prop_dictionary_get(dict, "mem-bus-tag"); 153 if (memt == NULL) 154 aprint_error_dev(self, "no mem-bus-tag property\n"); 155 KASSERT(prop_object_type(memt) == PROP_TYPE_DATA); 156 gtpci_mem_bs_tag = __UNCONST(prop_data_data_nocopy(memt)); 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 != GTCF_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); 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 intrrupt 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) 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 gtpci_protinit(sc); 246 247 reg = GTPCI_READ(sc, GTPCI_ADC); 248 reg |= GTPCI_ADC_REMAPWRDIS; 249 GTPCI_WRITE(sc, GTPCI_ADC, reg); 250 251 /* enable CPU-2-PCI ordering */ 252 reg = GTPCI_READ(sc, GTPCI_C); 253 reg |= GTPCI_C_CPU2PCIORDERING; 254 GTPCI_WRITE(sc, GTPCI_C, reg); 255 } 256 257 static void 258 gtpci_barinit(struct gtpci_softc *sc) 259 { 260 static const struct { 261 int tag; 262 int bars[2]; /* BAR Size registers */ 263 int bare; /* Bits of Base Address Registers Enable */ 264 int func; 265 int balow; 266 int bahigh; 267 } maps[] = { 268 { MARVELL_TAG_SDRAM_CS0, 269 { GTPCI_CS0BARS(0), GTPCI_CS0BARS(1) }, 270 GTPCI_BARE_CS0EN, 0, 0x10, 0x14 }, 271 { MARVELL_TAG_SDRAM_CS1, 272 { GTPCI_CS1BARS(0), GTPCI_CS1BARS(1) }, 273 GTPCI_BARE_CS1EN, 0, 0x18, 0x1c }, 274 { MARVELL_TAG_SDRAM_CS2, 275 { GTPCI_CS2BARS(0), GTPCI_CS2BARS(1) }, 276 GTPCI_BARE_CS2EN, 1, 0x10, 0x14 }, 277 { MARVELL_TAG_SDRAM_CS3, 278 { GTPCI_CS3BARS(0), GTPCI_CS3BARS(1) }, 279 GTPCI_BARE_CS3EN, 1, 0x18, 0x1c }, 280 #if 0 281 { ORION_TARGETID_INTERNALREG, 282 { -1, -1 }, 283 GTPCI_BARE_INTMEMEN, 0, 0x20, 0x24 }, 284 285 { ORION_TARGETID_DEVICE_CS0, 286 { GTPCI_DCS0BARS(0), GTPCI_DCS0BARS(1) }, 287 GTPCI_BARE_DEVCS0EN, 2, 0x10, 0x14 }, 288 { ORION_TARGETID_DEVICE_CS1, 289 { GTPCI_DCS1BARS(0), GTPCI_DCS1BARS(1) }, 290 GTPCI_BARE_DEVCS1EN, 2, 0x18, 0x1c }, 291 { ORION_TARGETID_DEVICE_CS2, 292 { GTPCI_DCS2BARS(0), GTPCI_DCS2BARS(1) }, 293 GTPCI_BARE_DEVCS2EN, 2, 0x20, 0x24 }, 294 { ORION_TARGETID_DEVICE_BOOTCS, 295 { GTPCI_BCSBARS(0), GTPCI_BCSBARS(1) }, 296 GTPCI_BARE_BOOTCSEN, 3, 0x18, 0x1c }, 297 { P2P Mem0 BAR, 298 { GTPCI_P2PM0BARS(0), GTPCI_P2PM0BARS(1) }, 299 GTPCI_BARE_P2PMEM0EN, 4, 0x10, 0x14 }, 300 { P2P I/O BAR, 301 { GTPCI_P2PIOBARS(0), GTPCI_P2PIOBARS(1) }, 302 GTPCI_BARE_P2PIO0EN, 4, 0x20, 0x24 }, 303 { Expansion ROM BAR, 304 { GTPCI_EROMBARS(0), GTPCI_EROMBARS(1) }, 305 0, }, 306 #endif 307 308 { MARVELL_TAG_UNDEFINED, 309 { -1, -1 }, 310 -1, -1, 0x00, 0x00 }, 311 }; 312 device_t pdev = device_parent(sc->sc_dev); 313 uint64_t base; 314 uint32_t p2pc, size, bare; 315 int map, bus, dev, rv; 316 317 p2pc = GTPCI_READ(sc, GTPCI_P2PC); 318 bus = GTPCI_P2PC_BUSNUMBER(p2pc); 319 dev = GTPCI_P2PC_DEVNUM(p2pc); 320 321 bare = GTPCI_BARE_ALLDISABLE; 322 for (map = 0; maps[map].tag != MARVELL_TAG_UNDEFINED; map++) { 323 rv = marvell_winparams_by_tag(pdev, maps[map].tag, NULL, NULL, 324 &base, &size); 325 if (rv != 0 || size == 0) 326 continue; 327 328 if (maps[map].bars[sc->sc_unit] != -1) 329 bus_space_write_4(sc->sc_iot, sc->sc_ioh, 330 maps[map].bars[sc->sc_unit], GTPCI_BARSIZE(size)); 331 bare &= ~maps[map].bare; 332 333 #if 0 /* shall move to pchb(4)? */ 334 if (maps[map].func != -1) { 335 pcitag_t tag; 336 pcireg_t reg; 337 338 tag = gtpci_make_tag(NULL, bus, dev, maps[map].func); 339 reg = gtpci_conf_read(sc, tag, maps[map].balow); 340 reg &= ~GTPCI_BARLOW_MASK; 341 reg |= GTPCI_BARLOW_BASE(base); 342 gtpci_conf_write(sc, tag, maps[map].balow, reg); 343 reg = gtpci_conf_read(sc, tag, maps[map].bahigh); 344 reg = (base >> 16) >> 16; 345 gtpci_conf_write(sc, tag, maps[map].bahigh, reg); 346 } 347 #endif 348 } 349 GTPCI_WRITE(sc, GTPCI_BARE, bare); 350 } 351 352 static void 353 gtpci_protinit(struct gtpci_softc *sc) 354 { 355 enum { 356 gt64260 = 0, 357 mv64360, 358 soc, 359 }; 360 const struct gtpci_prot { 361 uint32_t acbl_flags; 362 uint32_t acbl_base_rshift; 363 uint32_t acs_flags; 364 uint32_t acs_size_rshift; 365 } gtpci_prots[] = { 366 { /* GT64260 */ 367 #if 0 368 GTPCI_GT64260_ACBL_PCISWAP_NOSWAP | 369 GTPCI_GT64260_ACBL_WBURST_4_QW | 370 GTPCI_GT64260_ACBL_RDMULPREFETCH | 371 GTPCI_GT64260_ACBL_RDLINEPREFETCH | 372 GTPCI_GT64260_ACBL_RDPREFETCH | 373 GTPCI_GT64260_ACBL_DREADEN, 374 #else 375 GTPCI_GT64260_ACBL_PCISWAP_NOSWAP | 376 GTPCI_GT64260_ACBL_WBURST_8_QW | 377 GTPCI_GT64260_ACBL_RDMULPREFETCH | 378 GTPCI_GT64260_ACBL_RDLINEPREFETCH | 379 GTPCI_GT64260_ACBL_RDPREFETCH | 380 GTPCI_GT64260_ACBL_PREFETCHEN, 381 #endif 382 20, 383 0, 384 20 385 }, 386 { /* MV64360 and after */ 387 GTPCI_ACBL_RDSIZE_256BYTE | 388 GTPCI_ACBL_RDMBURST_128BYTE | 389 GTPCI_ACBL_PCISWAP_NOSWAP | 390 GTPCI_ACBL_SNOOP_NONE | 391 GTPCI_ACBL_EN, 392 0, 393 0, 394 0 395 }, 396 { /* Orion */ 397 GTPCI_ACBL_RDSIZE_256BYTE | 398 GTPCI_ACBL_RDMBURST_128BYTE | 399 GTPCI_ACBL_PCISWAP_BYTESWAP, 400 0, 401 GTPCI_ACS_WRMBURST_128BYTE, 402 0 403 }, 404 }; 405 const uint32_t prot_tags[] = { 406 MARVELL_TAG_SDRAM_CS0, 407 MARVELL_TAG_SDRAM_CS1, 408 MARVELL_TAG_SDRAM_CS2, 409 MARVELL_TAG_SDRAM_CS3, 410 MARVELL_TAG_UNDEFINED 411 }; 412 device_t pdev = device_parent(sc->sc_dev); 413 uint64_t acbase, base; 414 uint32_t acsize, size; 415 int acbl_base_rshift, acbl_flags, acs_size_rshift, acs_flags; 416 int prot, rv, p, t; 417 418 switch (sc->sc_model) { 419 case MARVELL_DISCOVERY: 420 p = gt64260; 421 break; 422 423 case MARVELL_DISCOVERY_II: 424 case MARVELL_DISCOVERY_III: 425 #if 0 426 case MARVELL_DISCOVERY_LT: 427 case MARVELL_DISCOVERY_V: 428 case MARVELL_DISCOVERY_VI: 429 #endif 430 p = mv64360; 431 break; 432 433 default: 434 p = soc; 435 break; 436 } 437 acbl_base_rshift = gtpci_prots[p].acbl_base_rshift; 438 acbl_flags = gtpci_prots[p].acbl_flags; 439 acs_size_rshift = gtpci_prots[p].acs_size_rshift; 440 acs_flags = gtpci_prots[p].acs_flags; 441 442 t = 0; 443 for (prot = 0; prot < GTPCI_NPCIAC; prot++) { 444 acbase = acsize = 0; 445 446 for ( ; prot_tags[t] != MARVELL_TAG_UNDEFINED; t++) { 447 rv = marvell_winparams_by_tag(pdev, prot_tags[t], 448 NULL, NULL, &base, &size); 449 if (rv != 0 || size == 0) 450 continue; 451 452 if (acsize == 0 || base + size == acbase) 453 acbase = base; 454 else if (acbase + acsize != base) 455 break; 456 acsize += size; 457 } 458 459 if (acsize != 0) { 460 GTPCI_WRITE_AC(sc, GTPCI_ACBL, prot, 461 ((acbase & 0xffffffff) >> acbl_base_rshift) | 462 acbl_flags); 463 GTPCI_WRITE_AC(sc, GTPCI_ACBH, prot, 464 (acbase >> 32) & 0xffffffff); 465 GTPCI_WRITE_AC(sc, GTPCI_ACS, prot, 466 ((acsize - 1) >> acs_size_rshift) | acs_flags); 467 } else { 468 GTPCI_WRITE_AC(sc, GTPCI_ACBL, prot, 0); 469 GTPCI_WRITE_AC(sc, GTPCI_ACBH, prot, 0); 470 GTPCI_WRITE_AC(sc, GTPCI_ACS, prot, 0); 471 } 472 } 473 return; 474 } 475 476 #if NPCI > 0 477 static void 478 gtpci_pci_config(struct gtpci_softc *sc, bus_space_tag_t iot, 479 bus_space_tag_t memt, bus_dma_tag_t dmat, pci_chipset_tag_t pc, 480 u_long iostart, u_long ioend, u_long memstart, u_long memend, 481 int cacheline_size) 482 { 483 struct pcibus_attach_args pba; 484 #ifdef PCI_NETBSD_CONFIGURE 485 struct extent *ioext = NULL, *memext = NULL; 486 #endif 487 uint32_t p2pc, command; 488 489 p2pc = GTPCI_READ(sc, GTPCI_P2PC); 490 491 #ifdef PCI_NETBSD_CONFIGURE 492 ioext = extent_create("pciio", iostart, ioend, M_DEVBUF, NULL, 0, 493 EX_NOWAIT); 494 memext = extent_create("pcimem", memstart, memend, M_DEVBUF, NULL, 0, 495 EX_NOWAIT); 496 if (ioext != NULL && memext != NULL) 497 pci_configure_bus(pc, ioext, memext, NULL, 498 GTPCI_P2PC_BUSNUMBER(p2pc), cacheline_size); 499 else 500 aprint_error_dev(sc->sc_dev, "can't create extent %s%s%s\n", 501 ioext == NULL ? "io" : "", 502 ioext == NULL && memext == NULL ? " and " : "", 503 memext == NULL ? "mem" : ""); 504 if (ioext != NULL) 505 extent_destroy(ioext); 506 if (memext != NULL) 507 extent_destroy(memext); 508 #endif 509 510 pba.pba_iot = iot; 511 pba.pba_memt = memt; 512 pba.pba_dmat = dmat; 513 pba.pba_dmat64 = NULL; 514 pba.pba_pc = pc; 515 if (iot == NULL || memt == NULL) { 516 pba.pba_flags = 0; 517 aprint_error_dev(sc->sc_dev, ""); 518 if (iot == NULL) 519 aprint_error("io "); 520 else 521 pba.pba_flags |= PCI_FLAGS_IO_ENABLED; 522 if (iot == NULL && memt == NULL) 523 aprint_error("and "); 524 if (memt == NULL) 525 aprint_error("mem"); 526 else 527 pba.pba_flags |= PCI_FLAGS_MEM_ENABLED; 528 aprint_error(" access disabled\n"); 529 } else 530 pba.pba_flags = PCI_FLAGS_IO_ENABLED | PCI_FLAGS_MEM_ENABLED; 531 command = GTPCI_READ(sc, GTPCI_C); 532 if (command & GTPCI_C_MRDMUL) 533 pba.pba_flags |= PCI_FLAGS_MRM_OKAY; 534 if (command & GTPCI_C_MRDLINE) 535 pba.pba_flags |= PCI_FLAGS_MRL_OKAY; 536 pba.pba_flags |= PCI_FLAGS_MWI_OKAY; 537 pba.pba_bus = GTPCI_P2PC_BUSNUMBER(p2pc); 538 pba.pba_bridgetag = NULL; 539 config_found_ia(sc->sc_dev, "pcibus", &pba, NULL); 540 } 541 542 543 /* 544 * Dependent code of PCI Interface of Marvell 545 */ 546 547 /* ARGSUSED */ 548 void 549 gtpci_attach_hook(device_t parent, device_t self, 550 struct pcibus_attach_args *pba) 551 { 552 553 /* Nothing */ 554 } 555 556 /* 557 * Bit map for configuration register: 558 * [31] ConfigEn 559 * [30:24] Reserved 560 * [23:16] BusNum 561 * [15:11] DevNum 562 * [10: 8] FunctNum 563 * [ 7: 2] RegNum 564 * [ 1: 0] reserved 565 */ 566 567 /* ARGSUSED */ 568 int 569 gtpci_bus_maxdevs(void *v, int busno) 570 { 571 572 return 32; /* 32 device/bus */ 573 } 574 575 /* ARGSUSED */ 576 pcitag_t 577 gtpci_make_tag(void *v, int bus, int dev, int func) 578 { 579 580 #if DIAGNOSTIC 581 if (bus >= 256 || dev >= 32 || func >= 8) 582 panic("pci_make_tag: bad request"); 583 #endif 584 585 return (bus << 16) | (dev << 11) | (func << 8); 586 } 587 588 /* ARGSUSED */ 589 void 590 gtpci_decompose_tag(void *v, pcitag_t tag, int *bp, int *dp, int *fp) 591 { 592 593 if (bp != NULL) 594 *bp = (tag >> 16) & 0xff; 595 if (dp != NULL) 596 *dp = (tag >> 11) & 0x1f; 597 if (fp != NULL) 598 *fp = (tag >> 8) & 0x07; 599 } 600 601 pcireg_t 602 gtpci_conf_read(void *v, pcitag_t tag, int reg) 603 { 604 struct gtpci_softc *sc = v; 605 const pcireg_t addr = tag | reg; 606 607 GTPCI_WRITE(sc, GTPCI_CA, addr | GTPCI_CA_CONFIGEN); 608 if ((addr | GTPCI_CA_CONFIGEN) != GTPCI_READ(sc, GTPCI_CA)) 609 return -1; 610 611 return GTPCI_READ(sc, GTPCI_CD); 612 } 613 614 void 615 gtpci_conf_write(void *v, pcitag_t tag, int reg, pcireg_t data) 616 { 617 struct gtpci_softc *sc = v; 618 pcireg_t addr = tag | (reg & 0xfc); 619 620 GTPCI_WRITE(sc, GTPCI_CA, addr | GTPCI_CA_CONFIGEN); 621 if ((addr | GTPCI_CA_CONFIGEN) != GTPCI_READ(sc, GTPCI_CA)) 622 return; 623 624 GTPCI_WRITE(sc, GTPCI_CD, data); 625 } 626 627 /* ARGSUSED */ 628 int 629 gtpci_conf_hook(pci_chipset_tag_t pc, int bus, int dev, int func, pcireg_t id) 630 { 631 /* Oops, We have two PCI buses. */ 632 if (dev == 0 && 633 PCI_VENDOR(id) == PCI_VENDOR_MARVELL) { 634 switch (PCI_PRODUCT(id)) { 635 case MARVELL_DISCOVERY: 636 case MARVELL_DISCOVERY_II: 637 case MARVELL_DISCOVERY_III: 638 #if 0 639 case MARVELL_DISCOVERY_LT: 640 case MARVELL_DISCOVERY_V: 641 case MARVELL_DISCOVERY_VI: 642 #endif 643 case MARVELL_ORION_1_88F5180N: 644 case MARVELL_ORION_1_88F5181: 645 case MARVELL_ORION_1_88F5182: 646 case MARVELL_ORION_2_88F5281: 647 case MARVELL_ORION_1_88W8660: 648 /* Don't configure us. */ 649 return 0; 650 } 651 } 652 653 return PCI_CONF_DEFAULT; 654 } 655 #endif /* NPCI > 0 */ 656