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