1/* 2 * Low-Level PCI and SI support for BCM47xx 3 * 4 * Copyright (C) 2010, Broadcom Corporation. All Rights Reserved. 5 * 6 * Permission to use, copy, modify, and/or distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 13 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION 15 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 16 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 * 18 * $Id: hndpci.c,v 1.49.2.2 2010/11/16 21:44:41 Exp $ 19 */ 20 21#include <typedefs.h> 22#include <osl.h> 23#include <pcicfg.h> 24#include <bcmdevs.h> 25#include <hndsoc.h> 26#include <bcmutils.h> 27#include <siutils.h> 28#include <pci_core.h> 29#include <pcie_core.h> 30#include <bcmendian.h> 31#include <bcmnvram.h> 32#include <hndcpu.h> 33#include <hndpci.h> 34#include <nicpci.h> 35#include <sbchipc.h> 36 37/* For now we need some real Silicon Backplane utils */ 38#include "siutils_priv.h" 39 40/* debug/trace */ 41#ifdef BCMDBG_PCI 42#define PCI_MSG(args) printf args 43#else 44#define PCI_MSG(args) 45#endif 46 47/* to free some function memory after boot */ 48#ifndef linux 49#define __init 50#endif /* linux */ 51 52/* Emulated configuration space */ 53typedef struct { 54 int n; 55 uint size[PCI_BAR_MAX]; 56} si_bar_cfg_t; 57static pci_config_regs si_config_regs[SI_MAXCORES]; 58static si_bar_cfg_t si_bar_cfg[SI_MAXCORES]; 59 60/* Links to emulated and real PCI configuration spaces */ 61#define MAXFUNCS 2 62typedef struct { 63 pci_config_regs *emu; /* emulated PCI config */ 64 pci_config_regs *pci; /* real PCI config */ 65 si_bar_cfg_t *bar; /* region sizes */ 66} si_pci_cfg_t; 67static si_pci_cfg_t si_pci_cfg[SI_MAXCORES][MAXFUNCS]; 68 69/* Special emulated config space for non-existing device */ 70static pci_config_regs si_pci_null = { 0xffff, 0xffff }; 71 72/* Banned cores */ 73static uint16 pci_ban[SI_MAXCORES] = { 0 }; 74static uint pci_banned = 0; 75 76/* CardBus mode */ 77static bool cardbus = FALSE; 78 79/* The OS's enumerated bus numbers for supported PCI/PCIe core units */ 80static uint pci_busid[SI_PCI_MAXCORES] = { 0, }; 81 82static uint32 pci_membase_cfg[SI_PCI_MAXCORES] = { 83 SI_PCI_CFG, 84}; 85 86static uint32 pci_membase[SI_PCI_MAXCORES] = { 87 SI_PCI_DMA, 88}; 89 90static uint32 pci_membase_1G[SI_PCI_MAXCORES] = { 91 SI_PCI_DMA, 92}; 93 94/* Disable PCI host core */ 95static bool pci_disabled[SI_PCI_MAXCORES] = { FALSE }; 96 97/* Host bridge slot #, default to 0 */ 98static uint8 pci_hbslot = 0; 99 100/* Internal macros */ 101#define PCI_SLOTAD_MAP 16 /* SLOT<n> mapps to AD<n+16> */ 102#define PCI_HBSBCFG_REV 8 /* MIN corerev to access host bridge PCI cfg space from SB */ 103 104/* Functions for accessing external PCI configuration space, Assume one-hot slot wiring */ 105#define PCI_SLOT_MAX 16 /* Max. PCI Slots */ 106 107static void 108hndpci_set_busid(uint busid) 109{ int i; 110 111 for (i = 0; i < SI_PCI_MAXCORES; i++) { 112 if (pci_busid[i] == 0) { 113 pci_busid[i] = busid; 114 printf("PCI/PCIe coreunit %d is set to bus %d.\n", i, pci_busid[i]); 115 return; 116 } 117 if (busid == pci_busid[i]) 118 return; 119 } 120} 121 122static int 123hndpci_pci_coreunit(uint bus) 124{ uint i; 125 126 ASSERT(bus >= 1); 127 for (i = SI_PCI_MAXCORES - 1; i >= 0; i--) { 128 if (pci_busid[i] && bus >= pci_busid[i]) 129 return i; 130 } 131 return -1; 132} 133 134bool 135hndpci_is_hostbridge(uint bus, uint dev) 136{ uint i; 137 138 ASSERT(bus >= 1); 139 if (dev != pci_hbslot) 140 return FALSE; 141 142 for (i = 0; i < SI_PCI_MAXCORES; i++) 143 if (bus == pci_busid[i]) 144 return TRUE; 145 146 return FALSE; 147} 148 149uint32 hndpci_get_membase(uint bus) 150{ 151 int coreunit; 152 153 coreunit = hndpci_pci_coreunit(bus); 154 ASSERT(coreunit >= 0); 155 ASSERT(pci_membase[coreunit]); 156 return pci_membase[coreunit]; 157} 158 159static uint32 160config_cmd(si_t *sih, uint coreunit, uint bus, uint dev, uint func, uint off) 161{ 162 uint coreidx; 163 sbpciregs_t *pci; 164 uint32 addr = 0, *sbtopci1; 165 osl_t *osh; 166 167 /* CardBusMode supports only one device */ 168 if (cardbus && dev > 1) 169 return 0; 170 171 osh = si_osh(sih); 172 173 coreidx = si_coreidx(sih); 174 pci = (sbpciregs_t *)si_setcore(sih, PCI_CORE_ID, coreunit); 175 176 if (pci) { 177 sbtopci1 = &pci->sbtopci1; 178 } else { 179 sbpcieregs_t *pcie; 180 181 pcie = (sbpcieregs_t *)si_setcore(sih, PCIE_CORE_ID, coreunit); 182 183 /* Issue config commands only when the data link is up (atleast 184 * one external pcie device is present). 185 */ 186 if (pcie && (dev < 2) && 187 (pcie_readreg(osh, pcie, PCIE_PCIEREGS, 188 PCIE_DLLP_LSREG) & PCIE_DLLP_LSREG_LINKUP)) { 189 sbtopci1 = &pcie->sbtopcie1; 190 } else { 191 si_setcoreidx(sih, coreidx); 192 return 0; 193 } 194 } 195 196 197 /* Type 0 transaction */ 198 if (!hndpci_is_hostbridge(bus, dev)) { 199 /* Skip unwired slots */ 200 if (dev < PCI_SLOT_MAX) { 201 /* Slide the PCI window to the appropriate slot */ 202 if (pci) { 203 uint32 win; 204 205 win = (SBTOPCI_CFG0 | 206 ((1 << (dev + PCI_SLOTAD_MAP)) & SBTOPCI1_MASK)); 207 W_REG(osh, sbtopci1, win); 208 addr = (pci_membase_cfg[coreunit] | 209 ((1 << (dev + PCI_SLOTAD_MAP)) & ~SBTOPCI1_MASK) | 210 (func << PCICFG_FUN_SHIFT) | 211 (off & ~3)); 212 } else { 213 W_REG(osh, sbtopci1, SBTOPCI_CFG0); 214 addr = (pci_membase_cfg[coreunit] | 215 (dev << PCIECFG_SLOT_SHIFT) | 216 (func << PCIECFG_FUN_SHIFT) | 217 (off & ~3)); 218 } 219 } 220 } else { 221 /* Type 1 transaction */ 222 W_REG(osh, sbtopci1, SBTOPCI_CFG1); 223 addr = (pci_membase_cfg[coreunit] | 224 (pci ? PCI_CONFIG_ADDR(bus, dev, func, (off & ~3)) : 225 PCIE_CONFIG_ADDR((bus - 1), dev, func, (off & ~3)))); 226 } 227 228 si_setcoreidx(sih, coreidx); 229 230 return addr; 231} 232 233/* 234 * Read host bridge PCI config registers from Silicon Backplane ( >= rev8 ). 235 * 236 * It returns TRUE to indicate that access to the host bridge's pci config 237 * from SI is ok, and values in 'addr' and 'val' are valid. 238 * 239 * It can only read registers at multiple of 4-bytes. Callers must pick up 240 * needed bytes from 'val' based on 'off' value. Value in 'addr' reflects 241 * the register address where value in 'val' is read. 242 */ 243static bool 244si_pcihb_read_config(si_t *sih, uint coreunit, uint bus, uint dev, uint func, 245 uint off, uint32 **addr, uint32 *val) 246{ 247 sbpciregs_t *pci; 248 osl_t *osh; 249 uint coreidx; 250 bool ret = FALSE; 251 252 /* sanity check */ 253 ASSERT(hndpci_is_hostbridge(bus, dev)); 254 255 /* we support only two functions on device 0 */ 256 if (func > 1) 257 return FALSE; 258 259 osh = si_osh(sih); 260 261 /* read pci config when core rev >= 8 */ 262 coreidx = si_coreidx(sih); 263 pci = (sbpciregs_t *)si_setcore(sih, PCI_CORE_ID, coreunit); 264 if (pci) { 265 if (si_corerev(sih) >= PCI_HBSBCFG_REV) { 266 *addr = (uint32 *)&pci->pcicfg[func][off >> 2]; 267 *val = R_REG(osh, *addr); 268 ret = TRUE; 269 } 270 } else { 271 sbpcieregs_t *pcie; 272 273 /* read pcie config */ 274 pcie = (sbpcieregs_t *)si_setcore(sih, PCIE_CORE_ID, coreunit); 275 if (pcie != NULL) { 276 /* accesses to config registers with offsets >= 256 277 * requires indirect access. 278 */ 279 if (off >= 256) 280 *val = pcie_readreg(osh, pcie, PCIE_CONFIGREGS, 281 PCIE_CONFIG_INDADDR(func, off)); 282 else { 283 *addr = (uint32 *)&pcie->pciecfg[func][off >> 2]; 284 *val = R_REG(osh, *addr); 285 } 286 ret = TRUE; 287 } 288 } 289 290 si_setcoreidx(sih, coreidx); 291 292 return ret; 293} 294 295int 296extpci_read_config(si_t *sih, uint bus, uint dev, uint func, uint off, void *buf, int len) 297{ 298 uint32 addr = 0, *reg = NULL, val; 299 int ret = 0; 300 int coreunit = hndpci_pci_coreunit(bus); 301 302 if (coreunit < 0) 303 return -1; 304 305 /* 306 * Set value to -1 when: 307 * flag 'pci_disabled' is true; 308 * value of 'addr' is zero; 309 * REG_MAP() fails; 310 * BUSPROBE() fails; 311 */ 312 if (pci_disabled[coreunit]) 313 val = 0xffffffff; 314 else if (hndpci_is_hostbridge(bus, dev)) { 315 if (!si_pcihb_read_config(sih, coreunit, bus, dev, func, off, ®, &val)) 316 return -1; 317 } else if (((addr = config_cmd(sih, coreunit, bus, dev, func, off)) == 0) || 318 ((reg = (uint32 *)REG_MAP(addr, len)) == 0) || 319 (BUSPROBE(val, reg) != 0)) { 320 PCI_MSG(("%s: Failed to read!\n", __FUNCTION__)); 321 val = 0xffffffff; 322 } 323 324 PCI_MSG(("%s: 0x%x <= 0x%p(0x%x), len %d, off 0x%x, buf 0x%p\n", 325 __FUNCTION__, val, reg, addr, len, off, buf)); 326 327 val >>= 8 * (off & 3); 328 if (len == 4) 329 *((uint32 *)buf) = val; 330 else if (len == 2) 331 *((uint16 *)buf) = (uint16) val; 332 else if (len == 1) 333 *((uint8 *)buf) = (uint8) val; 334 else 335 ret = -1; 336 337 if (reg && addr) 338 REG_UNMAP(reg); 339 340 return ret; 341} 342 343int 344extpci_write_config(si_t *sih, uint bus, uint dev, uint func, uint off, void *buf, int len) 345{ 346 osl_t *osh; 347 uint32 addr = 0, *reg = NULL, val; 348 int ret = 0; 349 bool is_hostbridge; 350 int coreunit = hndpci_pci_coreunit(bus); 351 352 if (coreunit < 0) 353 return -1; 354 355 osh = si_osh(sih); 356 357 /* 358 * Ignore write attempt when: 359 * flag 'pci_disabled' is true; 360 * value of 'addr' is zero; 361 * REG_MAP() fails; 362 * BUSPROBE() fails; 363 */ 364 if (pci_disabled[coreunit]) 365 return 0; 366 if ((is_hostbridge = hndpci_is_hostbridge(bus, dev))) { 367 if (!si_pcihb_read_config(sih, coreunit, bus, dev, func, off, ®, &val)) 368 return -1; 369 } else if (((addr = config_cmd(sih, coreunit, bus, dev, func, off)) == 0) || 370 ((reg = (uint32 *)REG_MAP(addr, len)) == 0) || 371 (BUSPROBE(val, reg) != 0)) { 372 PCI_MSG(("%s: Failed to write!\n", __FUNCTION__)); 373 goto done; 374 } 375 376 if (len == 4) 377 val = *((uint32 *)buf); 378 else if (len == 2) { 379 val &= ~(0xffff << (8 * (off & 3))); 380 val |= *((uint16 *)buf) << (8 * (off & 3)); 381 } else if (len == 1) { 382 val &= ~(0xff << (8 * (off & 3))); 383 val |= *((uint8 *)buf) << (8 * (off & 3)); 384 } else { 385 ret = -1; 386 goto done; 387 } 388 389 PCI_MSG(("%s: 0x%x => 0x%p\n", __FUNCTION__, val, reg)); 390 391 if (is_hostbridge && reg == NULL) { 392 sbpcieregs_t *pcie; 393 uint coreidx; 394 395 coreidx = si_coreidx(sih); 396 397 /* read pcie config */ 398 pcie = (sbpcieregs_t *)si_setcore(sih, PCIE_CORE_ID, coreunit); 399 if (pcie != NULL) 400 /* accesses to config registers with offsets >= 256 401 * requires indirect access. 402 */ 403 pcie_writereg(osh, pcie, PCIE_CONFIGREGS, 404 PCIE_CONFIG_INDADDR(func, off), val); 405 406 si_setcoreidx(sih, coreidx); 407 } else { 408 W_REG(osh, reg, val); 409 410 if ((CHIPID(sih->chip) == BCM4716_CHIP_ID) || 411 (CHIPID(sih->chip) == BCM4748_CHIP_ID)) 412 (void)R_REG(osh, reg); 413 } 414 415 416done: 417 if (reg && addr) 418 REG_UNMAP(reg); 419 420 return ret; 421} 422 423/* 424 * Must access emulated PCI configuration at these locations even when 425 * the real PCI config space exists and is accessible. 426 * 427 * PCI_CFG_VID (0x00) 428 * PCI_CFG_DID (0x02) 429 * PCI_CFG_PROGIF (0x09) 430 * PCI_CFG_SUBCL (0x0a) 431 * PCI_CFG_BASECL (0x0b) 432 * PCI_CFG_HDR (0x0e) 433 * PCI_CFG_INT (0x3c) 434 * PCI_CFG_PIN (0x3d) 435 */ 436#define FORCE_EMUCFG(off, len) \ 437 ((off == PCI_CFG_VID) || (off == PCI_CFG_DID) || \ 438 (off == PCI_CFG_PROGIF) || \ 439 (off == PCI_CFG_SUBCL) || (off == PCI_CFG_BASECL) || \ 440 (off == PCI_CFG_HDR) || \ 441 (off == PCI_CFG_INT) || (off == PCI_CFG_PIN)) 442 443/* Sync the emulation registers and the real PCI config registers. */ 444static void 445si_pcid_read_config(si_t *sih, uint coreidx, si_pci_cfg_t *cfg, uint off, uint len) 446{ 447 osl_t *osh; 448 uint oldidx; 449 450 ASSERT(cfg); 451 ASSERT(cfg->emu); 452 ASSERT(cfg->pci); 453 454 /* decide if real PCI config register access is necessary */ 455 if (FORCE_EMUCFG(off, len)) 456 return; 457 458 osh = si_osh(sih); 459 460 /* access to the real pci config space only when the core is up */ 461 oldidx = si_coreidx(sih); 462 si_setcoreidx(sih, coreidx); 463 if (si_iscoreup(sih)) { 464 if (len == 4) 465 *(uint32 *)((ulong)cfg->emu + off) = 466 htol32(R_REG(osh, (uint32 *)((ulong)cfg->pci + off))); 467 else if (len == 2) 468 *(uint16 *)((ulong)cfg->emu + off) = 469 htol16(R_REG(osh, (uint16 *)((ulong)cfg->pci + off))); 470 else if (len == 1) 471 *(uint8 *)((ulong)cfg->emu + off) = 472 R_REG(osh, (uint8 *)((ulong)cfg->pci + off)); 473 } 474 si_setcoreidx(sih, oldidx); 475} 476 477static void 478si_pcid_write_config(si_t *sih, uint coreidx, si_pci_cfg_t *cfg, uint off, uint len) 479{ 480 osl_t *osh; 481 uint oldidx; 482 483 ASSERT(cfg); 484 ASSERT(cfg->emu); 485 ASSERT(cfg->pci); 486 487 osh = si_osh(sih); 488 489 /* decide if real PCI config register access is necessary */ 490 if (FORCE_EMUCFG(off, len)) 491 return; 492 493 /* access to the real pci config space only when the core is up */ 494 oldidx = si_coreidx(sih); 495 si_setcoreidx(sih, coreidx); 496 if (si_iscoreup(sih)) { 497 if (len == 4) 498 W_REG(osh, (uint32 *)((ulong)cfg->pci + off), 499 ltoh32(*(uint32 *)((ulong)cfg->emu + off))); 500 else if (len == 2) 501 W_REG(osh, (uint16 *)((ulong)cfg->pci + off), 502 ltoh16(*(uint16 *)((ulong)cfg->emu + off))); 503 else if (len == 1) 504 W_REG(osh, (uint8 *)((ulong)cfg->pci + off), 505 *(uint8 *)((ulong)cfg->emu + off)); 506 } 507 si_setcoreidx(sih, oldidx); 508} 509 510/* 511 * Functions for accessing translated SI configuration space 512 */ 513static int 514si_read_config(si_t *sih, uint bus, uint dev, uint func, uint off, void *buf, int len) 515{ 516 pci_config_regs *cfg; 517 518 if (dev >= SI_MAXCORES || func >= MAXFUNCS || (off + len) > sizeof(pci_config_regs)) 519 return -1; 520 521 cfg = si_pci_cfg[dev][func].emu; 522 523 ASSERT(ISALIGNED(off, len)); 524 ASSERT(ISALIGNED((uintptr)buf, len)); 525 526 /* use special config space if the device does not exist */ 527 if (!cfg) 528 cfg = &si_pci_null; 529 /* sync emulation with real PCI config if necessary */ 530 else if (si_pci_cfg[dev][func].pci) 531 si_pcid_read_config(sih, dev, &si_pci_cfg[dev][func], off, len); 532 533 if (len == 4) 534 *((uint32 *)buf) = ltoh32(*((uint32 *)((ulong) cfg + off))); 535 else if (len == 2) 536 *((uint16 *)buf) = ltoh16(*((uint16 *)((ulong) cfg + off))); 537 else if (len == 1) 538 *((uint8 *)buf) = *((uint8 *)((ulong) cfg + off)); 539 else 540 return -1; 541 542 return 0; 543} 544 545static int 546si_write_config(si_t *sih, uint bus, uint dev, uint func, uint off, void *buf, int len) 547{ 548 uint coreidx; 549 void *regs; 550 pci_config_regs *cfg; 551 osl_t *osh; 552 si_bar_cfg_t *bar; 553 554 if (dev >= SI_MAXCORES || func >= MAXFUNCS || (off + len) > sizeof(pci_config_regs)) 555 return -1; 556 cfg = si_pci_cfg[dev][func].emu; 557 if (!cfg) 558 return -1; 559 560 ASSERT(ISALIGNED(off, len)); 561 ASSERT(ISALIGNED((uintptr)buf, len)); 562 563 osh = si_osh(sih); 564 565 if (cfg->header_type == PCI_HEADER_BRIDGE) { 566 uint busid = 0; 567 if (off == OFFSETOF(ppb_config_regs, prim_bus) && len >= 2) 568 busid = (*((uint16 *)buf) & 0xff00) >> 8; 569 else if (off == OFFSETOF(ppb_config_regs, sec_bus)) 570 busid = *((uint8 *)buf); 571 if (busid) 572 hndpci_set_busid(busid); 573 } 574 575 /* Emulate BAR sizing */ 576 if (off >= OFFSETOF(pci_config_regs, base[0]) && 577 off <= OFFSETOF(pci_config_regs, base[3]) && 578 len == 4 && *((uint32 *)buf) == ~0) { 579 coreidx = si_coreidx(sih); 580 if ((regs = si_setcoreidx(sih, dev))) { 581 bar = si_pci_cfg[dev][func].bar; 582 /* Highest numbered address match register */ 583 if (off == OFFSETOF(pci_config_regs, base[0])) 584 cfg->base[0] = ~(bar->size[0] - 1); 585 else if (off == OFFSETOF(pci_config_regs, base[1]) && bar->n >= 1) 586 cfg->base[1] = ~(bar->size[1] - 1); 587 else if (off == OFFSETOF(pci_config_regs, base[2]) && bar->n >= 2) 588 cfg->base[2] = ~(bar->size[2] - 1); 589 else if (off == OFFSETOF(pci_config_regs, base[3]) && bar->n >= 3) 590 cfg->base[3] = ~(bar->size[3] - 1); 591 } 592 si_setcoreidx(sih, coreidx); 593 } else if (len == 4) 594 *((uint32 *)((ulong) cfg + off)) = htol32(*((uint32 *)buf)); 595 else if (len == 2) 596 *((uint16 *)((ulong) cfg + off)) = htol16(*((uint16 *)buf)); 597 else if (len == 1) 598 *((uint8 *)((ulong) cfg + off)) = *((uint8 *)buf); 599 else 600 return -1; 601 602 /* sync emulation with real PCI config if necessary */ 603 if (si_pci_cfg[dev][func].pci) 604 si_pcid_write_config(sih, dev, &si_pci_cfg[dev][func], off, len); 605 606 return 0; 607} 608 609int 610hndpci_read_config(si_t *sih, uint bus, uint dev, uint func, uint off, void *buf, int len) 611{ 612 if (bus == 0) 613 return si_read_config(sih, bus, dev, func, off, buf, len); 614 else 615 return extpci_read_config(sih, bus, dev, func, off, buf, len); 616} 617 618int 619hndpci_write_config(si_t *sih, uint bus, uint dev, uint func, uint off, void *buf, int len) 620{ 621 if (bus == 0) 622 return si_write_config(sih, bus, dev, func, off, buf, len); 623 else 624 return extpci_write_config(sih, bus, dev, func, off, buf, len); 625} 626 627void 628hndpci_ban(uint16 core) 629{ 630 if (pci_banned < ARRAYSIZE(pci_ban)) 631 pci_ban[pci_banned++] = core; 632} 633 634/* return cap_offset if requested capability exists in the PCI config space */ 635uint8 636hndpci_find_pci_capability(si_t *sih, uint bus, uint dev, uint func, 637 uint8 req_cap_id, uchar *buf, uint32 *buflen) 638{ 639 uint8 cap_id; 640 uint8 cap_ptr = 0; 641 uint32 bufsize; 642 uint8 byte_val; 643 644 /* check for Header type 0 */ 645 hndpci_read_config(sih, bus, dev, func, PCI_CFG_HDR, &byte_val, sizeof(uint8)); 646 if ((byte_val & 0x7f) != PCI_HEADER_NORMAL) 647 return (cap_ptr); 648 649 /* check if the capability pointer field exists */ 650 hndpci_read_config(sih, bus, dev, func, PCI_CFG_STAT, &byte_val, sizeof(uint8)); 651 if (!(byte_val & PCI_CAPPTR_PRESENT)) 652 return (cap_ptr); 653 654 /* check if the capability pointer is 0x00 */ 655 hndpci_read_config(sih, bus, dev, func, PCI_CFG_CAPPTR, &cap_ptr, sizeof(uint8)); 656 if (cap_ptr == 0x00) 657 return (cap_ptr); 658 659 /* loop thr'u the capability list and see if the requested capabilty exists */ 660 hndpci_read_config(sih, bus, dev, func, cap_ptr, &cap_id, sizeof(uint8)); 661 while (cap_id != req_cap_id) { 662 hndpci_read_config(sih, bus, dev, func, cap_ptr + 1, &cap_ptr, sizeof(uint8)); 663 if (cap_ptr == 0x00) 664 return (cap_ptr); 665 hndpci_read_config(sih, bus, dev, func, cap_ptr, &cap_id, sizeof(uint8)); 666 } 667 668 /* found the caller requested capability */ 669 if ((buf != NULL) && (buflen != NULL)) { 670 uint8 cap_data; 671 672 bufsize = *buflen; 673 if (!bufsize) 674 return (cap_ptr); 675 676 *buflen = 0; 677 678 /* copy the cpability data excluding cap ID and next ptr */ 679 cap_data = cap_ptr + 2; 680 if ((bufsize + cap_data) > SZPCR) 681 bufsize = SZPCR - cap_data; 682 *buflen = bufsize; 683 while (bufsize--) { 684 hndpci_read_config(sih, bus, dev, func, cap_data, buf, sizeof(uint8)); 685 cap_data++; 686 buf++; 687 } 688 } 689 690 return (cap_ptr); 691} 692 693 694/* 695 * Initiliaze PCI core. 696 * Return 0 after a successful initialization. 697 * Otherwise return -1 to indicate there is no PCI core and 698 * return 1 to indicate PCI core is disabled. 699 */ 700int __init 701BCMATTACHFN(hndpci_init_pci)(si_t *sih, uint coreunit) 702{ 703 uint chip, chiprev, chippkg, host; 704 uint32 boardflags; 705 sbpciregs_t *pci; 706 sbpcieregs_t *pcie = NULL; 707 uint32 val; 708 int ret = 0; 709 char *hbslot; 710 osl_t *osh; 711 int bus; 712 713 chip = sih->chip; 714 chiprev = sih->chiprev; 715 chippkg = sih->chippkg; 716 717 osh = si_osh(sih); 718 719 pci = (sbpciregs_t *)si_setcore(sih, PCI_CORE_ID, coreunit); 720 if (pci == NULL) { 721 pcie = (sbpcieregs_t *)si_setcore(sih, PCIE_CORE_ID, coreunit); 722 if (pcie == NULL) { 723 printf("PCI: no core\n"); 724 pci_disabled[coreunit] = TRUE; 725 return -1; 726 } 727 } 728 729 if ((CHIPID(chip) == BCM4706_CHIP_ID) && (coreunit == 1)) { 730 /* Check if PCIE 1 is disabled */ 731 if (sih->chipst & CST4706_PCIE1_DISABLE) { 732 pci_disabled[coreunit] = TRUE; 733 host = 0; 734 PCI_MSG(("PCIE port %d is disabled\n", port)); 735 } 736 } 737 738 boardflags = (uint32)getintvar(NULL, "boardflags"); 739 740 /* 741 * The NOPCI boardflag indicates we should not touch the PCI core, 742 * it may not be bonded out or the pins may be floating. 743 * The 200-pin BCM4712 package does not bond out PCI, and routers 744 * based on it did not use the boardflag. 745 */ 746 if ((boardflags & BFL_NOPCI) || 747 ((chip == BCM4712_CHIP_ID) && 748 ((chippkg == BCM4712SMALL_PKG_ID) || (chippkg == BCM4712MID_PKG_ID)))) { 749 pci_disabled[coreunit] = TRUE; 750 host = 0; 751 } else { 752 /* Enable the core */ 753 si_core_reset(sih, 0, 0); 754 755 /* Figure out if it is in host mode: 756 * In host mode, it returns 0, in client mode, this register access will trap 757 * Trap handler must be implemented to support this like hndrte_mips.c 758 */ 759 host = !BUSPROBE(val, (pci ? &pci->control : &pcie->control)); 760 } 761 762 if (!host) { 763 ret = 1; 764 765 /* Disable PCI interrupts in client mode */ 766 si_setint(sih, -1); 767 768 /* Disable the PCI bridge in client mode */ 769 hndpci_ban(pci? PCI_CORE_ID : PCIE_CORE_ID); 770 771 /* Make sure the core is disabled */ 772 si_core_disable(sih, 0); 773 774 /* On 4716 (and other AXI chips?) make sure the slave wrapper 775 * is also put in reset. 776 */ 777 if ((chip == BCM4716_CHIP_ID) || (chip == BCM4748_CHIP_ID) || 778 (chip == BCM4706_CHIP_ID)) { 779 uint32 *resetctrl; 780 781 resetctrl = (uint32 *)OSL_UNCACHED(SI_WRAP_BASE + (9 * SI_CORE_SIZE) + 782 AI_RESETCTRL); 783 W_REG(osh, resetctrl, AIRC_RESET); 784 } 785 786 printf("PCI: Disabled\n"); 787 } else { 788 printf("PCI: Initializing host\n"); 789 790 /* Disable PCI SBReqeustTimeout for BCM4785 rev. < 2 */ 791 if (chip == BCM4785_CHIP_ID && chiprev < 2) { 792 sbconfig_t *sb; 793 sb = (sbconfig_t *)((ulong) pci + SBCONFIGOFF); 794 AND_REG(osh, &sb->sbimconfiglow, ~0x00000070); 795 sb_commit(sih); 796 } 797 798 if (pci) { 799 /* Reset the external PCI bus and enable the clock */ 800 W_REG(osh, &pci->control, 0x5); /* enable tristate drivers */ 801 W_REG(osh, &pci->control, 0xd); /* enable the PCI clock */ 802 OSL_DELAY(150); /* delay > 100 us */ 803 W_REG(osh, &pci->control, 0xf); /* deassert PCI reset */ 804 /* Use internal arbiter and park REQ/GRNT at external master 0 805 * We will set it later after the bus has been probed 806 */ 807 W_REG(osh, &pci->arbcontrol, PCI_INT_ARB); 808 OSL_DELAY(1); /* delay 1 us */ 809 } else { 810 printf("PCI: Reset RC\n"); 811 OSL_DELAY(3000); 812 W_REG(osh, &pcie->control, PCIE_RST_OE); 813 OSL_DELAY(50000); /* delay 50 ms *//*borg, for 4706 reboot issue*/ 814 W_REG(osh, &pcie->control, PCIE_RST | PCIE_RST_OE); 815 } 816 817 /* Enable CardBusMode */ 818 cardbus = getintvar(NULL, "cardbus") == 1; 819 if (cardbus) { 820 printf("PCI: Enabling CardBus\n"); 821 /* GPIO 1 resets the CardBus device on bcm94710ap */ 822 si_gpioout(sih, 1, 1, GPIO_DRV_PRIORITY); 823 si_gpioouten(sih, 1, 1, GPIO_DRV_PRIORITY); 824 W_REG(osh, &pci->sprom[0], R_REG(osh, &pci->sprom[0]) | 0x400); 825 } 826 827 /* Host bridge slot # nvram overwrite */ 828 if ((hbslot = nvram_get("pcihbslot"))) { 829 pci_hbslot = bcm_strtoul(hbslot, NULL, 0); 830 ASSERT(pci_hbslot < PCI_MAX_DEVICES); 831 } 832 833 bus = pci_busid[coreunit] = coreunit + 1; 834 if (pci) { 835 /* 64 MB I/O access window */ 836 W_REG(osh, &pci->sbtopci0, SBTOPCI_IO); 837 /* 64 MB configuration access window */ 838 W_REG(osh, &pci->sbtopci1, SBTOPCI_CFG0); 839 /* 1 GB memory access window */ 840 W_REG(osh, &pci->sbtopci2, SBTOPCI_MEM | SI_PCI_DMA); 841 } else { 842 uint8 cap_ptr, root_ctrl, root_cap, dev; 843 uint16 val16; 844 845 /* 64 MB I/O access window. On 4716, use 846 * sbtopcie0 to access the device registers. We 847 * can't use address match 2 (1 GB window) region 848 * as mips can't generate 64-bit address on the 849 * backplane. 850 */ 851 if ((chip == BCM4716_CHIP_ID) || (chip == BCM4748_CHIP_ID)) 852 W_REG(osh, &pcie->sbtopcie0, SBTOPCIE_MEM | 853 (pci_membase[coreunit] = SI_PCI_MEM)); 854 else if (chip == BCM4706_CHIP_ID) { 855 if (coreunit == 0) { 856 pci_membase[coreunit] = SI_PCI_MEM; 857 pci_membase_1G[coreunit] = SI_PCIE_DMA_H32; 858 } else if (coreunit == 1) { 859 pci_membase_cfg[coreunit] = SI_PCI1_CFG; 860 pci_membase[coreunit] = SI_PCI1_MEM; 861 pci_membase_1G[coreunit] = SI_PCIE1_DMA_H32; 862 } 863 W_REG(osh, &pcie->sbtopcie0, 864 SBTOPCIE_MEM | SBTOPCIE_PF | SBTOPCIE_WR_BURST | 865 pci_membase[coreunit]); 866 } 867 else 868 W_REG(osh, &pcie->sbtopcie0, SBTOPCIE_IO); 869 870 /* 64 MB configuration access window */ 871 W_REG(osh, &pcie->sbtopcie1, SBTOPCIE_CFG0); 872 873 /* 1 GB memory access window */ 874 W_REG(osh, &pcie->sbtopcie2, SBTOPCIE_MEM | 875 pci_membase_1G[coreunit]); 876 877 /* As per PCI Express Base Spec 1.1 we need to wait for 878 * at least 100 ms from the end of a reset (cold/warm/hot) 879 * before issuing configuration requests to PCI Express 880 * devices. 881 */ 882 OSL_DELAY(100000); 883 884 /* If the root port is capable of returning Config Request 885 * Retry Status (CRS) Completion Status to software then 886 * enable the feature. 887 */ 888 cap_ptr = hndpci_find_pci_capability(sih, bus, pci_hbslot, 0, 889 PCI_CAP_PCIECAP_ID, NULL, NULL); 890 ASSERT(cap_ptr); 891 892 root_cap = cap_ptr + OFFSETOF(pciconfig_cap_pcie, root_cap); 893 hndpci_read_config(sih, bus, pci_hbslot, 0, root_cap, 894 &val16, sizeof(uint16)); 895 if (val16 & PCIE_RC_CRS_VISIBILITY) { 896 /* Enable CRS software visibility */ 897 root_ctrl = cap_ptr + OFFSETOF(pciconfig_cap_pcie, root_ctrl); 898 val16 = PCIE_RC_CRS_EN; 899 hndpci_write_config(sih, bus, pci_hbslot, 0, root_ctrl, 900 &val16, sizeof(uint16)); 901 902 /* Initiate a configuration request to read the vendor id 903 * field of the device function's config space header after 904 * 100 ms wait time from the end of Reset. If the device is 905 * not done with its internal initialization, it must at 906 * least return a completion TLP, with a completion status 907 * of "Configuration Request Retry Status (CRS)". The root 908 * complex must complete the request to the host by returning 909 * a read-data value of 0001h for the Vendor ID field and 910 * all 1s for any additional bytes included in the request. 911 * Poll using the config reads for max wait time of 1 sec or 912 * until we receive the successful completion status. Repeat 913 * the procedure for all the devices. 914 */ 915 for (dev = pci_hbslot + 1; dev < PCI_MAX_DEVICES; dev++) { 916 SPINWAIT((hndpci_read_config(sih, bus, dev, 0, 917 PCI_CFG_VID, &val16, sizeof(val16)), 918 (val16 == 0x1)), 1000000); 919 if (val16 == 0x1) 920 printf("PCI: Broken device in slot %d\n", dev); 921 } 922 } 923 } 924 925 /* Enable PCI bridge BAR0 memory & master access */ 926 val = PCI_CMD_MASTER | PCI_CMD_MEMORY; 927 hndpci_write_config(sih, bus, pci_hbslot, 0, PCI_CFG_CMD, &val, sizeof(val)); 928 929 /* Enable PCI interrupts */ 930 if (pci) 931 W_REG(osh, &pci->intmask, PCI_INTA); 932 else 933 W_REG(osh, &pcie->intmask, PCI_INTA); 934 } 935 936 /* Reset busid to 0. Bus number will be assigned by OS later */ 937 pci_busid[coreunit] = 0; 938 return ret; 939} 940 941void 942hndpci_arb_park(si_t *sih, uint parkid) 943{ 944 sbpciregs_t *pci; 945 uint pcirev; 946 uint32 arb; 947 948 pci = (sbpciregs_t *)si_setcore(sih, PCI_CORE_ID, 0); 949 if ((pci == NULL) || pci_disabled[0]) { 950 /* Should not happen */ 951 PCI_MSG(("%s: no PCI core\n", __FUNCTION__)); 952 return; 953 } 954 955 pcirev = si_corerev(sih); 956 957 /* Nothing to do, not supported for these revs */ 958 if (pcirev < 8) 959 return; 960 961 /* Get parkid from NVRAM */ 962 if (parkid == PCI_PARK_NVRAM) { 963 parkid = getintvar(NULL, "parkid"); 964 if (getvar(NULL, "parkid") == NULL) 965 /* Not present in NVRAM use defaults */ 966 parkid = (pcirev >= 11) ? PCI11_PARKID_LAST : PCI_PARKID_LAST; 967 } 968 969 /* Check the parkid is valid, if not set it to default */ 970 if (parkid > ((pcirev >= 11) ? PCI11_PARKID_LAST : PCI_PARKID_LAST)) { 971 printf("%s: Invalid parkid %d\n", __FUNCTION__, parkid); 972 parkid = (pcirev >= 11) ? PCI11_PARKID_LAST : PCI_PARKID_LAST; 973 } 974 975 /* Now set the parkid */ 976 arb = R_REG(si_osh(sih), &pci->arbcontrol); 977 arb &= ~PCI_PARKID_MASK; 978 arb |= parkid << PCI_PARKID_SHIFT; 979 W_REG(si_osh(sih), &pci->arbcontrol, arb); 980 OSL_DELAY(1); 981} 982 983/*borg, for 4706 reboot issue*/ 984int 985hndpci_deinit_pci(si_t *sih, uint coreunit) 986{ 987 int coreidx; 988 sbpciregs_t *pci; 989 sbpcieregs_t *pcie = NULL; 990 991 if (pci_disabled[coreunit]) 992 return 0; 993 994 coreidx = si_coreidx(sih); 995 pci = (sbpciregs_t *)si_setcore(sih, PCI_CORE_ID, coreunit); 996 if (pci == NULL) { 997 pcie = (sbpcieregs_t *)si_setcore(sih, PCIE_CORE_ID, coreunit); 998 if (pcie == NULL) { 999 printf("PCI: no core\n"); 1000 return -1; 1001 } 1002 } 1003 1004 if (pci) 1005 W_REG(osh, &pci->control, PCI_RST_OE); 1006 else 1007 W_REG(osh, &pcie->control, PCIE_RST_OE); 1008 1009 si_core_disable(sih, 0); 1010 si_setcoreidx(sih, coreidx); 1011 return 0; 1012} 1013 1014/* 1015 * Deinitialize PCI(e) cores 1016 */ 1017void 1018hndpci_deinit(si_t *sih) 1019{ 1020 int coreunit; 1021 1022 for (coreunit = 0; coreunit < SI_PCI_MAXCORES; coreunit++) 1023 hndpci_deinit_pci(sih, coreunit); 1024} 1025 1026/* 1027 * Get the PCI region address and size information. 1028 */ 1029static void __init 1030BCMATTACHFN(hndpci_init_regions)(si_t *sih, uint func, pci_config_regs *cfg, si_bar_cfg_t *bar) 1031{ 1032 bool issb = sih->socitype == SOCI_SB; 1033 uint i, n; 1034 1035 if (si_coreid(sih) == USB20H_CORE_ID) { 1036 uint32 base, base1; 1037 1038 base = htol32(si_addrspace(sih, 0)); 1039 if (issb) { 1040 base1 = base + 0x800; /* OHCI/EHCI */ 1041 } else { 1042 /* In AI chips EHCI is addrspace 0, OHCI is 1 */ 1043 base1 = base; 1044 if ((CHIPID(sih->chip) == BCM5357_CHIP_ID || 1045 (CHIPID(sih->chip) == BCM4749_CHIP_ID)) && 1046 CHIPREV(sih->chiprev) == 0) 1047 base = 0x18009000; 1048 else 1049 base = htol32(si_addrspace(sih, 1)); 1050 } 1051 1052 i = bar->n = 1; 1053 cfg->base[0] = func == 0 ? base : base1; 1054 bar->size[0] = issb ? 0x800 : 0x1000; 1055 } else { 1056 bar->n = n = si_numaddrspaces(sih); 1057 for (i = 0; i < n; i++) { 1058 int size = si_addrspacesize(sih, i); 1059 1060 if (size) { 1061 cfg->base[i] = htol32(si_addrspace(sih, i)); 1062 bar->size[i] = size; 1063 } 1064 } 1065 } 1066 for (; i < PCI_BAR_MAX; i++) { 1067 cfg->base[i] = 0; 1068 bar->size[i] = 0; 1069 } 1070} 1071 1072/* 1073 * Construct PCI config spaces for SB cores to be accessed as if they were PCI devices. 1074 */ 1075void __init 1076BCMATTACHFN(hndpci_init_cores)(si_t *sih) 1077{ 1078 uint chiprev, coreidx, i; 1079 pci_config_regs *cfg, *pci; 1080 si_bar_cfg_t *bar; 1081 void *regs; 1082 osl_t *osh; 1083 uint16 vendor, device; 1084 uint16 coreid; 1085 uint8 class, subclass, progif; 1086 uint dev; 1087 uint8 header; 1088 uint func; 1089 1090 chiprev = sih->chiprev; 1091 coreidx = si_coreidx(sih); 1092 1093 osh = si_osh(sih); 1094 1095 /* Scan the SI bus */ 1096 bzero(si_config_regs, sizeof(si_config_regs)); 1097 bzero(si_bar_cfg, sizeof(si_bar_cfg)); 1098 bzero(si_pci_cfg, sizeof(si_pci_cfg)); 1099 memset(&si_pci_null, -1, sizeof(si_pci_null)); 1100 cfg = si_config_regs; 1101 bar = si_bar_cfg; 1102 for (dev = 0; dev < SI_MAXCORES; dev ++) { 1103 /* Check if the core exists */ 1104 if (!(regs = si_setcoreidx(sih, dev))) 1105 continue; 1106 1107 /* Check if this core is banned */ 1108 coreid = si_coreid(sih); 1109 for (i = 0; i < pci_banned; i++) 1110 if (coreid == pci_ban[i]) 1111 break; 1112 if (i < pci_banned) 1113 continue; 1114 1115 if (coreid == USB20H_CORE_ID) { 1116 if (((CHIPID(sih->chip) == BCM5357_CHIP_ID) || 1117 (CHIPID(sih->chip) == BCM4749_CHIP_ID)) && 1118 (sih->chippkg == BCM5357_PKG_ID)) { 1119 printf("PCI: skip disabled USB20H\n"); 1120 continue; 1121 } 1122 } 1123 1124 if ((CHIPID(sih->chip) == BCM4706_CHIP_ID)) { 1125 if (coreid == GMAC_CORE_ID) { 1126 /* Only GMAC core 0 is used by 4706 */ 1127 if (si_coreunit(sih) > 0) { 1128 continue; 1129 } 1130 } 1131 } 1132 1133 for (func = 0; func < MAXFUNCS; ++func) { 1134 /* Make sure we won't go beyond the limit */ 1135 if (cfg >= &si_config_regs[SI_MAXCORES]) { 1136 printf("PCI: too many emulated devices\n"); 1137 goto done; 1138 } 1139 1140 /* Convert core id to pci id */ 1141 if (si_corepciid(sih, func, &vendor, &device, &class, &subclass, 1142 &progif, &header)) 1143 continue; 1144 1145 /* 1146 * Differentiate real PCI config from emulated. 1147 * non zero 'pci' indicate there is a real PCI config space 1148 * for this device. 1149 */ 1150 switch (device) { 1151 case BCM47XX_GIGETH_ID: 1152 pci = (pci_config_regs *)((uint32)regs + 0x800); 1153 break; 1154 case BCM47XX_SATAXOR_ID: 1155 pci = (pci_config_regs *)((uint32)regs + 0x400); 1156 break; 1157 case BCM47XX_ATA100_ID: 1158 pci = (pci_config_regs *)((uint32)regs + 0x800); 1159 break; 1160 default: 1161 pci = NULL; 1162 break; 1163 } 1164 /* Supported translations */ 1165 cfg->vendor = htol16(vendor); 1166 cfg->device = htol16(device); 1167 cfg->rev_id = chiprev; 1168 cfg->prog_if = progif; 1169 cfg->sub_class = subclass; 1170 cfg->base_class = class; 1171 cfg->header_type = header; 1172 hndpci_init_regions(sih, func, cfg, bar); 1173 /* Save core interrupt flag */ 1174 cfg->int_pin = si_flag(sih); 1175 /* Save core interrupt assignment */ 1176 cfg->int_line = si_irq(sih); 1177 /* Indicate there is no SROM */ 1178 *((uint32 *)&cfg->sprom_control) = 0xffffffff; 1179 1180 /* Point to the PCI config spaces */ 1181 si_pci_cfg[dev][func].emu = cfg; 1182 si_pci_cfg[dev][func].pci = pci; 1183 si_pci_cfg[dev][func].bar = bar; 1184 cfg ++; 1185 bar ++; 1186 } 1187 } 1188 1189done: 1190 si_setcoreidx(sih, coreidx); 1191} 1192 1193/* 1194 * Initialize PCI core and construct PCI config spaces for SI cores. 1195 * Must propagate hndpci_init_pci() return value to the caller to let 1196 * them know the PCI core initialization status. 1197 */ 1198int __init 1199BCMATTACHFN(hndpci_init)(si_t *sih) 1200{ 1201 int coreunit, status = 0; 1202 1203 for (coreunit = 0; coreunit < SI_PCI_MAXCORES; coreunit++) 1204 status |= hndpci_init_pci(sih, coreunit); 1205 hndpci_init_cores(sih); 1206 return status; 1207} 1208