1/* $NetBSD: gtpci.c,v 1.28 2011/05/17 17:34:54 dyoung 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.28 2011/05/17 17:34:54 dyoung 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 65static int gtpci_match(device_t, struct cfdata *, void *); 66static void gtpci_attach(device_t, device_t, void *); 67 68static void gtpci_init(struct gtpci_softc *, struct gtpci_prot *); 69static void gtpci_barinit(struct gtpci_softc *); 70static void gtpci_protinit(struct gtpci_softc *, struct gtpci_prot *); 71#if NPCI > 0 72static 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 78CFATTACH_DECL_NEW(gtpci_gt, sizeof(struct gtpci_softc), 79 gtpci_match, gtpci_attach, NULL, NULL); 80CFATTACH_DECL_NEW(gtpci_mbus, sizeof(struct gtpci_softc), 81 gtpci_match, gtpci_attach, NULL, NULL); 82 83 84/* ARGSUSED */ 85static int 86gtpci_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 */ 113static void 114gtpci_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 233static void 234gtpci_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 260static void 261gtpci_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 355static void 356gtpci_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 442static void 443gtpci_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, NULL, 0, EX_NOWAIT); 458 memext = extent_create("pcimem", memstart, memend, NULL, 0, EX_NOWAIT); 459 if (ioext != NULL && memext != NULL) 460 pci_configure_bus(pc, ioext, memext, NULL, 461 GTPCI_P2PC_BUSNUMBER(p2pc), cacheline_size); 462 else 463 aprint_error_dev(sc->sc_dev, "can't create extent %s%s%s\n", 464 ioext == NULL ? "io" : "", 465 ioext == NULL && memext == NULL ? " and " : "", 466 memext == NULL ? "mem" : ""); 467 if (ioext != NULL) 468 extent_destroy(ioext); 469 if (memext != NULL) 470 extent_destroy(memext); 471#endif 472 473 pba.pba_iot = iot; 474 pba.pba_memt = memt; 475 pba.pba_dmat = dmat; 476 pba.pba_dmat64 = NULL; 477 pba.pba_pc = pc; 478 if (iot == NULL || memt == NULL) { 479 pba.pba_flags = 0; 480 aprint_error_dev(sc->sc_dev, ""); 481 if (iot == NULL) 482 aprint_error("io "); 483 else 484 pba.pba_flags |= PCI_FLAGS_IO_OKAY; 485 if (iot == NULL && memt == NULL) 486 aprint_error("and "); 487 if (memt == NULL) 488 aprint_error("mem"); 489 else 490 pba.pba_flags |= PCI_FLAGS_MEM_OKAY; 491 aprint_error(" access disabled\n"); 492 } else 493 pba.pba_flags = PCI_FLAGS_IO_OKAY | PCI_FLAGS_MEM_OKAY; 494 command = GTPCI_READ(sc, GTPCI_C); 495 if (command & GTPCI_C_MRDMUL) 496 pba.pba_flags |= PCI_FLAGS_MRM_OKAY; 497 if (command & GTPCI_C_MRDLINE) 498 pba.pba_flags |= PCI_FLAGS_MRL_OKAY; 499 pba.pba_flags |= PCI_FLAGS_MWI_OKAY; 500 pba.pba_bus = GTPCI_P2PC_BUSNUMBER(p2pc); 501 pba.pba_bridgetag = NULL; 502 config_found_ia(sc->sc_dev, "pcibus", &pba, NULL); 503} 504 505 506/* 507 * Dependent code of PCI Interface of Marvell 508 */ 509 510/* ARGSUSED */ 511void 512gtpci_attach_hook(device_t parent, device_t self, 513 struct pcibus_attach_args *pba) 514{ 515 516 /* Nothing */ 517} 518 519/* 520 * Bit map for configuration register: 521 * [31] ConfigEn 522 * [30:24] Reserved 523 * [23:16] BusNum 524 * [15:11] DevNum 525 * [10: 8] FunctNum 526 * [ 7: 2] RegNum 527 * [ 1: 0] reserved 528 */ 529 530/* ARGSUSED */ 531int 532gtpci_bus_maxdevs(void *v, int busno) 533{ 534 535 return 32; /* 32 device/bus */ 536} 537 538/* ARGSUSED */ 539pcitag_t 540gtpci_make_tag(void *v, int bus, int dev, int func) 541{ 542 543#if DIAGNOSTIC 544 if (bus >= 256 || dev >= 32 || func >= 8) 545 panic("pci_make_tag: bad request"); 546#endif 547 548 return (bus << 16) | (dev << 11) | (func << 8); 549} 550 551/* ARGSUSED */ 552void 553gtpci_decompose_tag(void *v, pcitag_t tag, int *bp, int *dp, int *fp) 554{ 555 556 if (bp != NULL) 557 *bp = (tag >> 16) & 0xff; 558 if (dp != NULL) 559 *dp = (tag >> 11) & 0x1f; 560 if (fp != NULL) 561 *fp = (tag >> 8) & 0x07; 562} 563 564pcireg_t 565gtpci_conf_read(void *v, pcitag_t tag, int reg) 566{ 567 struct gtpci_softc *sc = v; 568 const pcireg_t addr = tag | reg; 569 570 GTPCI_WRITE(sc, GTPCI_CA, addr | GTPCI_CA_CONFIGEN); 571 if ((addr | GTPCI_CA_CONFIGEN) != GTPCI_READ(sc, GTPCI_CA)) 572 return -1; 573 574 return GTPCI_READ(sc, GTPCI_CD); 575} 576 577void 578gtpci_conf_write(void *v, pcitag_t tag, int reg, pcireg_t data) 579{ 580 struct gtpci_softc *sc = v; 581 pcireg_t addr = tag | (reg & 0xfc); 582 583 GTPCI_WRITE(sc, GTPCI_CA, addr | GTPCI_CA_CONFIGEN); 584 if ((addr | GTPCI_CA_CONFIGEN) != GTPCI_READ(sc, GTPCI_CA)) 585 return; 586 587 GTPCI_WRITE(sc, GTPCI_CD, data); 588} 589 590/* ARGSUSED */ 591int 592gtpci_conf_hook(pci_chipset_tag_t pc, int bus, int dev, int func, pcireg_t id) 593{ 594 /* Oops, We have two PCI buses. */ 595 if (dev == 0 && 596 PCI_VENDOR(id) == PCI_VENDOR_MARVELL) { 597 switch (PCI_PRODUCT(id)) { 598 case MARVELL_DISCOVERY: 599 case MARVELL_DISCOVERY_II: 600 case MARVELL_DISCOVERY_III: 601#if 0 602 case MARVELL_DISCOVERY_LT: 603 case MARVELL_DISCOVERY_V: 604 case MARVELL_DISCOVERY_VI: 605#endif 606 case MARVELL_ORION_1_88F5180N: 607 case MARVELL_ORION_1_88F5181: 608 case MARVELL_ORION_1_88F5182: 609 case MARVELL_ORION_2_88F5281: 610 case MARVELL_ORION_1_88W8660: 611 /* Don't configure us. */ 612 return 0; 613 } 614 } 615 616 return PCI_CONF_DEFAULT; 617} 618#endif /* NPCI > 0 */ 619