1/* 2 * Misc utility routines for accessing chip-specific features 3 * of the SiliconBackplane-based Broadcom chips. 4 * 5 * Copyright (C) 2015, Broadcom Corporation. All Rights Reserved. 6 * 7 * Permission to use, copy, modify, and/or distribute this software for any 8 * purpose with or without fee is hereby granted, provided that the above 9 * copyright notice and this permission notice appear in all copies. 10 * 11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 14 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION 16 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 17 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 18 * 19 * $Id: siutils.c 505047 2014-09-26 07:54:55Z $ 20 */ 21 22#include <bcm_cfg.h> 23#include <typedefs.h> 24#include <bcmdefs.h> 25#include <osl.h> 26#include <bcmutils.h> 27#include <siutils.h> 28#include <bcmdevs.h> 29#include <hndsoc.h> 30#include <sbchipc.h> 31#include <pci_core.h> 32#include <pcie_core.h> 33#include <nicpci.h> 34#include <bcmnvram.h> 35#include <bcmsrom.h> 36#include <hndtcam.h> 37#include <pcicfg.h> 38#include <sbpcmcia.h> 39#include <sbsocram.h> 40#include <bcmotp.h> 41#include <hndpmu.h> 42#ifdef BCMSPI 43#include <spid.h> 44#endif /* BCMSPI */ 45#if !defined(BCM_BOOTLOADER) && defined(SR_ESSENTIALS) 46#include <saverestore.h> 47#endif /* BCM_BOOTLOADER / SR_ESSENTIALS */ 48 49#ifdef BCM_SDRBL 50#include <hndcpu.h> 51#endif /* BCM_SDRBL */ 52 53#include "siutils_priv.h" 54 55/* local prototypes */ 56static si_info_t *si_doattach(si_info_t *sii, uint devid, osl_t *osh, void *regs, 57 uint bustype, void *sdh, char **vars, uint *varsz); 58static bool si_buscore_prep(si_info_t *sii, uint bustype, uint devid, void *sdh); 59static bool si_buscore_setup(si_info_t *sii, chipcregs_t *cc, uint bustype, uint32 savewin, 60 uint *origidx, void *regs); 61 62static void si_nvram_process(si_info_t *sii, char *pvars); 63#if (!defined(_CFE_) && !defined(_CFEZ_)) || defined(CFG_WL) 64static void si_sromvars_fixup_4331(si_t *sih, char *pvars); 65#endif /* (!_CFE_ && !_CFEZ_) || CFG_WL */ 66 67/* dev path concatenation util */ 68static char *si_devpathvar(si_t *sih, char *var, int len, const char *name); 69static bool _si_clkctl_cc(si_info_t *sii, uint mode); 70static bool si_ispcie(si_info_t *sii); 71static uint BCMINITFN(socram_banksize)(si_info_t *sii, sbsocramregs_t *r, uint8 idx, uint8 mtype); 72 73void si_gci_chipctrl_overrides(osl_t *osh, si_t *sih, char *pvars); 74 75 76/* global variable to indicate reservation/release of gpio's */ 77static uint32 si_gpioreservation = 0; 78 79/* global flag to prevent shared resources from being initialized multiple times in si_attach() */ 80 81int do_4360_pcie2_war = 0; 82 83/** 84 * Allocate a si handle. 85 * devid - pci device id (used to determine chip#) 86 * osh - opaque OS handle 87 * regs - virtual address of initial core registers 88 * bustype - pci/pcmcia/sb/sdio/etc 89 * vars - pointer to a pointer area for "environment" variables 90 * varsz - pointer to int to return the size of the vars 91 */ 92si_t * 93BCMATTACHFN(si_attach)(uint devid, osl_t *osh, void *regs, 94 uint bustype, void *sdh, char **vars, uint *varsz) 95{ 96 si_info_t *sii; 97 98 /* alloc si_info_t */ 99 if ((sii = MALLOC(osh, sizeof (si_info_t))) == NULL) { 100 SI_ERROR(("si_attach: malloc failed! malloced %d bytes\n", MALLOCED(osh))); 101 return (NULL); 102 } 103 104 if (si_doattach(sii, devid, osh, regs, bustype, sdh, vars, varsz) == NULL) { 105 MFREE(osh, sii, sizeof(si_info_t)); 106 return (NULL); 107 } 108 sii->vars = vars ? *vars : NULL; 109 sii->varsz = varsz ? *varsz : 0; 110 111 return (si_t *)sii; 112} 113 114/* global kernel resource */ 115static si_info_t ksii; 116 117static uint32 wd_msticks; /* watchdog timer ticks normalized to ms */ 118 119/** generic kernel variant of si_attach() */ 120si_t * 121BCMATTACHFN(si_kattach)(osl_t *osh) 122{ 123 static bool ksii_attached = FALSE; 124 125 if (!ksii_attached) { 126 void *regs; 127#ifndef SI_ENUM_BASE_VARIABLE 128 regs = REG_MAP(SI_ENUM_BASE, SI_CORE_SIZE); 129#endif 130 131 if (si_doattach(&ksii, BCM4710_DEVICE_ID, osh, regs, 132 SI_BUS, NULL, 133 osh != SI_OSH ? &ksii.vars : NULL, 134 osh != SI_OSH ? &ksii.varsz : NULL) == NULL) { 135 SI_ERROR(("si_kattach: si_doattach failed\n")); 136 REG_UNMAP(regs); 137 return NULL; 138 } 139 REG_UNMAP(regs); 140 141 /* save ticks normalized to ms for si_watchdog_ms() */ 142 if (PMUCTL_ENAB(&ksii.pub)) { 143 if (CHIPID(ksii.pub.chip) == BCM4706_CHIP_ID) { 144 /* 4706 CC and PMU watchdogs are clocked at 1/4 of ALP clock */ 145 wd_msticks = (si_alp_clock(&ksii.pub) / 4) / 1000; 146 } 147 else 148 /* based on 32KHz ILP clock */ 149 wd_msticks = 32; 150 } else { 151 if (ksii.pub.ccrev < 18) 152 wd_msticks = si_clock(&ksii.pub) / 1000; 153 else 154 wd_msticks = si_alp_clock(&ksii.pub) / 1000; 155 } 156 157 ksii_attached = TRUE; 158 SI_MSG(("si_kattach done. ccrev = %d, wd_msticks = %d\n", 159 ksii.pub.ccrev, wd_msticks)); 160 } 161 162 return &ksii.pub; 163} 164 165bool 166si_ldo_war(si_t *sih, uint devid) 167{ 168 si_info_t *sii = SI_INFO(sih); 169 uint32 w; 170 chipcregs_t *cc; 171 void *regs = sii->curmap; 172 uint32 rev_id, ccst; 173 174 rev_id = OSL_PCI_READ_CONFIG(sii->osh, PCI_CFG_REV, sizeof(uint32)); 175 rev_id &= 0xff; 176 if (!(((CHIPID(devid) == BCM4322_CHIP_ID) || 177 (CHIPID(devid) == BCM4342_CHIP_ID) || 178 (CHIPID(devid) == BCM4322_D11N_ID) || 179 (CHIPID(devid) == BCM4322_D11N2G_ID) || 180 (CHIPID(devid) == BCM4322_D11N5G_ID)) && 181 (rev_id == 0))) 182 return TRUE; 183 184 SI_MSG(("si_ldo_war: PCI devid 0x%x rev %d, HACK to fix 4322a0 LDO/PMU\n", devid, rev_id)); 185 186 /* switch to chipcommon */ 187 w = OSL_PCI_READ_CONFIG(sii->osh, PCI_BAR0_WIN, sizeof(uint32)); 188 OSL_PCI_WRITE_CONFIG(sii->osh, PCI_BAR0_WIN, sizeof(uint32), SI_ENUM_BASE); 189 cc = (chipcregs_t *)regs; 190 191 /* clear bit 7 to fix LDO 192 * write to register *blindly* WITHOUT read since read may timeout 193 * because the default clock is 32k ILP 194 */ 195 W_REG(sii->osh, &cc->regcontrol_addr, 0); 196 /* AND_REG(sii->osh, &cc->regcontrol_data, ~0x80); */ 197 W_REG(sii->osh, &cc->regcontrol_data, 0x3001); 198 199 OSL_DELAY(5000); 200 201 /* request ALP_AVAIL through PMU to move sb out of ILP */ 202 W_REG(sii->osh, &cc->min_res_mask, 0x0d); 203 204 SPINWAIT(((ccst = OSL_PCI_READ_CONFIG(sii->osh, PCI_CLK_CTL_ST, 4)) & CCS_ALPAVAIL) 205 == 0, PMU_MAX_TRANSITION_DLY); 206 207 if ((ccst & CCS_ALPAVAIL) == 0) { 208 SI_ERROR(("ALP never came up clk_ctl_st: 0x%x\n", ccst)); 209 return FALSE; 210 } 211 SI_MSG(("si_ldo_war: 4322a0 HACK done\n")); 212 213 OSL_PCI_WRITE_CONFIG(sii->osh, PCI_BAR0_WIN, sizeof(uint32), w); 214 215 return TRUE; 216} 217 218static bool 219BCMATTACHFN(si_buscore_prep)(si_info_t *sii, uint bustype, uint devid, void *sdh) 220{ 221 /* need to set memseg flag for CF card first before any sb registers access */ 222 if (BUSTYPE(bustype) == PCMCIA_BUS) 223 sii->memseg = TRUE; 224 225 if (BUSTYPE(bustype) == PCI_BUS) { 226 if (!si_ldo_war((si_t *)sii, devid)) 227 return FALSE; 228 } 229 230 /* kludge to enable the clock on the 4306 which lacks a slowclock */ 231 if (BUSTYPE(bustype) == PCI_BUS && !si_ispcie(sii)) 232 si_clkctl_xtal(&sii->pub, XTAL|PLL, ON); 233 234 235 return TRUE; 236} 237 238static bool 239BCMATTACHFN(si_buscore_setup)(si_info_t *sii, chipcregs_t *cc, uint bustype, uint32 savewin, 240 uint *origidx, void *regs) 241{ 242 bool pci, pcie, pcie_gen2 = FALSE; 243 uint i; 244 uint pciidx, pcieidx, pcirev, pcierev; 245 246 cc = si_setcoreidx(&sii->pub, SI_CC_IDX); 247 ASSERT((uintptr)cc); 248 249 /* get chipcommon rev */ 250 sii->pub.ccrev = (int)si_corerev(&sii->pub); 251 252 /* get chipcommon chipstatus */ 253 if (sii->pub.ccrev >= 11) 254 sii->pub.chipst = R_REG(sii->osh, &cc->chipstatus); 255 256 /* get chipcommon capabilites */ 257 sii->pub.cccaps = R_REG(sii->osh, &cc->capabilities); 258 /* get chipcommon extended capabilities */ 259 260 if (sii->pub.ccrev >= 35) 261 sii->pub.cccaps_ext = R_REG(sii->osh, &cc->capabilities_ext); 262 263 /* get pmu rev and caps */ 264 if (sii->pub.cccaps & CC_CAP_PMU) { 265 sii->pub.pmucaps = R_REG(sii->osh, &cc->pmucapabilities); 266 sii->pub.pmurev = sii->pub.pmucaps & PCAP_REV_MASK; 267 } 268 269 SI_MSG(("Chipc: rev %d, caps 0x%x, chipst 0x%x pmurev %d, pmucaps 0x%x\n", 270 sii->pub.ccrev, sii->pub.cccaps, sii->pub.chipst, sii->pub.pmurev, 271 sii->pub.pmucaps)); 272 273 /* figure out bus/orignal core idx */ 274 sii->pub.buscoretype = NODEV_CORE_ID; 275 sii->pub.buscorerev = (uint)NOREV; 276 sii->pub.buscoreidx = BADIDX; 277 278 pci = pcie = FALSE; 279 pcirev = pcierev = (uint)NOREV; 280 pciidx = pcieidx = BADIDX; 281 282 for (i = 0; i < sii->numcores; i++) { 283 uint cid, crev; 284 285 si_setcoreidx(&sii->pub, i); 286 cid = si_coreid(&sii->pub); 287 crev = si_corerev(&sii->pub); 288 289 /* Display cores found */ 290 SI_VMSG(("CORE[%d]: id 0x%x rev %d base 0x%x regs 0x%p\n", 291 i, cid, crev, sii->coresba[i], sii->regs[i])); 292 293 if (BUSTYPE(bustype) == PCI_BUS) { 294 if (cid == PCI_CORE_ID) { 295 pciidx = i; 296 pcirev = crev; 297 pci = TRUE; 298 } else if ((cid == PCIE_CORE_ID) || (cid == PCIE2_CORE_ID)) { 299 pcieidx = i; 300 pcierev = crev; 301 pcie = TRUE; 302 if (cid == PCIE2_CORE_ID) 303 pcie_gen2 = TRUE; 304 } 305 } else if ((BUSTYPE(bustype) == PCMCIA_BUS) && 306 (cid == PCMCIA_CORE_ID)) { 307 sii->pub.buscorerev = crev; 308 sii->pub.buscoretype = cid; 309 sii->pub.buscoreidx = i; 310 } 311 312 /* find the core idx before entering this func. */ 313 if ((savewin && (savewin == sii->coresba[i])) || 314 (regs == sii->regs[i])) 315 *origidx = i; 316 } 317 318 if (pci && pcie) { 319 if (si_ispcie(sii)) 320 pci = FALSE; 321 else 322 pcie = FALSE; 323 } 324 if (pci) { 325 sii->pub.buscoretype = PCI_CORE_ID; 326 sii->pub.buscorerev = pcirev; 327 sii->pub.buscoreidx = pciidx; 328 } else if (pcie) { 329 if (pcie_gen2) 330 sii->pub.buscoretype = PCIE2_CORE_ID; 331 else 332 sii->pub.buscoretype = PCIE_CORE_ID; 333 sii->pub.buscorerev = pcierev; 334 sii->pub.buscoreidx = pcieidx; 335 } 336 337 SI_VMSG(("Buscore id/type/rev %d/0x%x/%d\n", sii->pub.buscoreidx, sii->pub.buscoretype, 338 sii->pub.buscorerev)); 339 340 if (BUSTYPE(sii->pub.bustype) == SI_BUS && (CHIPID(sii->pub.chip) == BCM4712_CHIP_ID) && 341 (sii->pub.chippkg != BCM4712LARGE_PKG_ID) && (CHIPREV(sii->pub.chiprev) <= 3)) 342 OR_REG(sii->osh, &cc->slow_clk_ctl, SCC_SS_XTAL); 343 344 /* fixup necessary chip/core configurations */ 345 if (BUSTYPE(sii->pub.bustype) == PCI_BUS) { 346 if (SI_FAST(sii)) { 347 if (!sii->pch && 348 ((sii->pch = (void *)(uintptr)pcicore_init(&sii->pub, sii->osh, 349 (void *)PCIEREGS(sii))) == NULL)) 350 return FALSE; 351 } 352 if (si_pci_fixcfg(&sii->pub)) { 353 SI_ERROR(("si_doattach: si_pci_fixcfg failed\n")); 354 return FALSE; 355 } 356 } 357 358 359 /* return to the original core */ 360 si_setcoreidx(&sii->pub, *origidx); 361 362 return TRUE; 363} 364 365static uint32 366si_fixup_vid(si_info_t *sii, char *pvars, uint32 conf_vid) 367{ 368 struct si_pub *sih = &sii->pub; 369 uint32 srom_vid; 370 371 if (BUSTYPE(sih->bustype) != PCI_BUS) 372 return conf_vid; 373 374 if ((CHIPID(sih->chip) != BCM4331_CHIP_ID) && (CHIPID(sih->chip) != BCM43431_CHIP_ID)) 375 return conf_vid; 376 377 /* Ext PA Controls for 4331 12x9 Package */ 378 if (sih->chippkg != 9) 379 return conf_vid; 380 381 srom_vid = (getintvar(pvars, "boardtype") << 16) | getintvar(pvars, "subvid"); 382 if (srom_vid != conf_vid) { 383 SI_ERROR(("%s: Override mismatch conf_vid(0x%04x) with srom_vid(0x%04x)\n", 384 __FUNCTION__, conf_vid, srom_vid)); 385 conf_vid = srom_vid; 386 } 387 388 return conf_vid; 389} 390 391static void 392BCMATTACHFN(si_nvram_process)(si_info_t *sii, char *pvars) 393{ 394 uint w = 0; 395 if (BUSTYPE(sii->pub.bustype) == PCMCIA_BUS) { 396 w = getintvar(pvars, "regwindowsz"); 397 sii->memseg = (w <= CFTABLE_REGWIN_2K) ? TRUE : FALSE; 398 } 399 400 /* get boardtype and boardrev */ 401 switch (BUSTYPE(sii->pub.bustype)) { 402 case PCI_BUS: 403 /* do a pci config read to get subsystem id and subvendor id */ 404 w = OSL_PCI_READ_CONFIG(sii->osh, PCI_CFG_SVID, sizeof(uint32)); 405 w = si_fixup_vid(sii, pvars, w); 406 407 /* Let nvram variables override subsystem Vend/ID */ 408 if ((sii->pub.boardvendor = (uint16)si_getdevpathintvar(&sii->pub, "boardvendor")) 409 == 0) { 410#ifdef BCMHOSTVARS 411 if ((w & 0xffff) == 0) 412 sii->pub.boardvendor = VENDOR_BROADCOM; 413 else 414#endif /* !BCMHOSTVARS */ 415 sii->pub.boardvendor = w & 0xffff; 416 } 417 else 418 SI_ERROR(("Overriding boardvendor: 0x%x instead of 0x%x\n", 419 sii->pub.boardvendor, w & 0xffff)); 420 if ((sii->pub.boardtype = (uint16)si_getdevpathintvar(&sii->pub, "boardtype")) 421 == 0) { 422 if ((sii->pub.boardtype = getintvar(pvars, "boardtype")) == 0) 423 sii->pub.boardtype = (w >> 16) & 0xffff; 424 } 425 else 426 SI_ERROR(("Overriding boardtype: 0x%x instead of 0x%x\n", 427 sii->pub.boardtype, (w >> 16) & 0xffff)); 428 break; 429 430 case PCMCIA_BUS: 431 sii->pub.boardvendor = getintvar(pvars, "manfid"); 432 sii->pub.boardtype = getintvar(pvars, "prodid"); 433 break; 434 435 436 case SI_BUS: 437 case JTAG_BUS: 438 sii->pub.boardvendor = VENDOR_BROADCOM; 439 if (pvars == NULL || ((sii->pub.boardtype = getintvar(pvars, "prodid")) == 0)) 440 if ((sii->pub.boardtype = getintvar(NULL, "boardtype")) == 0) 441 sii->pub.boardtype = 0xffff; 442 443 if (CHIPTYPE(sii->pub.socitype) == SOCI_UBUS) { 444 /* do a pci config read to get subsystem id and subvendor id */ 445 w = OSL_PCI_READ_CONFIG(sii->osh, PCI_CFG_SVID, sizeof(uint32)); 446 sii->pub.boardvendor = w & 0xffff; 447 sii->pub.boardtype = (w >> 16) & 0xffff; 448 } 449 break; 450 } 451 452 if (sii->pub.boardtype == 0) { 453 SI_ERROR(("si_doattach: unknown board type\n")); 454 ASSERT(sii->pub.boardtype); 455 } 456 457 sii->pub.boardrev = getintvar(pvars, "boardrev"); 458 sii->pub.boardflags = getintvar(pvars, "boardflags"); 459#ifdef BCM_SDRBL 460 sii->pub.boardflags2 |= ((!CHIP_HOSTIF_USB(&(sii->pub))) ? ((si_arm_sflags(&(sii->pub)) 461 & SISF_SDRENABLE) ? BFL2_SDR_EN:0): 462 (((uint)getintvar(pvars, "boardflags2")) & BFL2_SDR_EN)); 463#endif /* BCM_SDRBL */ 464} 465 466#if (!defined(_CFE_) && !defined(_CFEZ_)) || defined(CFG_WL) 467static void 468BCMATTACHFN(si_sromvars_fixup_4331)(si_t *sih, char *pvars) 469{ 470 471 const char *sromvars[] = 472 {"extpagain2g", "extpagain5g"}; 473 int sromvars_size = sizeof(sromvars)/sizeof(char *); 474 int ii; 475 uint boardtype = sih->boardtype; 476 uint boardrev = sih->boardrev; 477 bool update = ((boardtype == BCM94331BU_SSID) || 478 (boardtype == BCM94331S9BU_SSID) || 479 (boardtype == BCM94331MCI_SSID) || 480 (boardtype == BCM94331MC_SSID) || 481 (boardtype == BCM94331PCIEBT4_SSID) || 482 (boardtype == BCM94331X19 && boardrev == 0x1100) || 483 (boardtype == BCM94331HM_SSID && boardrev < 0x1152)); 484 485 if (pvars == NULL || !update) { 486 return; 487 } 488 489 for (ii = 0; ii < sromvars_size; ii++) { 490 char* val = getvar(pvars, sromvars[ii]); 491 492 while (val && *val) { 493 *val = '0'; 494 val++; 495 } 496 } 497} 498#endif /* (!_CFE_ && !_CFEZ_) || CFG_WL */ 499 500#if defined(CONFIG_XIP) && defined(BCMTCAM) 501extern uint8 patch_pair; 502#endif /* CONFIG_XIP && BCMTCAM */ 503 504typedef struct { 505 uint8 uart_tx; 506 uint32 uart_rx; 507} si_mux_uartopt_t; 508 509/* note: each index corr to MUXENAB4335_UART mask >> shift - 1 */ 510static const si_mux_uartopt_t BCMATTACHDATA(mux4335_uartopt)[] = { 511 {CC4335_PIN_GPIO_06, CC4335_PIN_GPIO_02}, 512 {CC4335_PIN_GPIO_12, CC4335_PIN_GPIO_13}, 513 {CC4335_PIN_SDIO_DATA0, CC4335_PIN_SDIO_CMD}, 514 {CC4335_PIN_RF_SW_CTRL_9, CC4335_PIN_RF_SW_CTRL_8} 515}; 516 517/* note: each index corr to MUXENAB4335_HOSTWAKE mask > shift - 1 */ 518static const uint8 BCMATTACHDATA(mux4335_hostwakeopt)[] = { 519 CC4335_PIN_GPIO_00, 520 CC4335_PIN_GPIO_05, 521 CC4335_PIN_GPIO_09 522}; 523 524static const si_mux_uartopt_t BCMATTACHDATA(mux4350_uartopt)[] = { 525 {CC4350_PIN_GPIO_00, CC4350_PIN_GPIO_01}, 526 {CC4350_PIN_GPIO_05, CC4350_PIN_GPIO_04}, 527 {CC4350_PIN_GPIO_15, CC4350_PIN_GPIO_14}, 528}; 529 530/* note: each index corr to MUXENAB4350_HOSTWAKE mask >> shift - 1 */ 531static const uint8 BCMATTACHDATA(mux4350_hostwakeopt)[] = { 532 CC4335_PIN_GPIO_00, 533}; 534 535 536/** want to have this available all the time to switch mux for debugging */ 537void 538BCMATTACHFN(si_muxenab)(si_t *sih, uint32 w) 539{ 540 uint32 chipcontrol, pmu_chipcontrol; 541 542 pmu_chipcontrol = si_pmu_chipcontrol(sih, 1, 0, 0); 543 chipcontrol = si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, chipcontrol), 544 0, 0); 545 546 switch (CHIPID(sih->chip)) { 547 case BCM4330_CHIP_ID: 548 /* clear the bits */ 549 chipcontrol &= ~(CCTRL_4330_JTAG_DISABLE | CCTRL_4330_ERCX_SEL | 550 CCTRL_4330_GPIO_SEL | CCTRL_4330_SDIO_HOST_WAKE); 551 pmu_chipcontrol &= ~PCTL_4330_SERIAL_ENAB; 552 553 /* 4330 default is to have jtag enabled */ 554 if (!(w & MUXENAB_JTAG)) 555 chipcontrol |= CCTRL_4330_JTAG_DISABLE; 556 if (w & MUXENAB_UART) 557 pmu_chipcontrol |= PCTL_4330_SERIAL_ENAB; 558 if (w & MUXENAB_GPIO) 559 chipcontrol |= CCTRL_4330_GPIO_SEL; 560 if (w & MUXENAB_ERCX) 561 chipcontrol |= CCTRL_4330_ERCX_SEL; 562 if (w & MUXENAB_HOST_WAKE) 563 chipcontrol |= CCTRL_4330_SDIO_HOST_WAKE; 564 break; 565 case BCM4336_CHIP_ID: 566 if (w & MUXENAB_UART) 567 pmu_chipcontrol |= PCTL_4336_SERIAL_ENAB; 568 else 569 pmu_chipcontrol &= ~PCTL_4336_SERIAL_ENAB; 570 break; 571 case BCM4360_CHIP_ID: 572 case BCM43460_CHIP_ID: 573 case BCM4352_CHIP_ID: 574 case BCM43526_CHIP_ID: 575 if (w & MUXENAB_UART) 576 chipcontrol |= CCTRL4360_UART_MODE; 577 break; 578 case BCM43143_CHIP_ID: 579 chipcontrol = 0; 580 /* 43143 does not support ERCX */ 581 if (!(w & MUXENAB_UART)) 582 chipcontrol |= CCTRL_43143_RF_XSWCTRL; 583 /* JTAG is enabled when SECI is disabled */ 584 if (w & MUXENAB_SECI) 585 chipcontrol |= CCTRL_43143_SECI; 586 if (w & MUXENAB_BT_LEGACY) 587 chipcontrol |= CCTRL_43143_BT_LEGACY; 588 if (w & MUXENAB_I2S_EN) 589 chipcontrol |= CCTRL_43143_I2S_MODE; 590 if (w & MUXENAB_I2S_MASTER) 591 chipcontrol |= CCTRL_43143_I2S_MASTER; 592 if (w & MUXENAB_I2S_FULL) 593 chipcontrol |= CCTRL_43143_I2S_FULL; 594 if (!(w & MUXENAB_SFLASH)) 595 chipcontrol |= CCTRL_43143_GSIO; 596 if (w & MUXENAB_RFSWCTRL0) 597 chipcontrol |= CCTRL_43143_RF_SWCTRL_0; 598 if (w & MUXENAB_RFSWCTRL1) 599 chipcontrol |= CCTRL_43143_RF_SWCTRL_1; 600 if (w & MUXENAB_RFSWCTRL2) 601 chipcontrol |= CCTRL_43143_RF_SWCTRL_2; 602 if (w & MUXENAB_HOST_WAKE) 603 chipcontrol |= CCTRL_43143_HOST_WAKE0; 604 if (w & MUXENAB_HOST_WAKE1) 605 chipcontrol |= CCTRL_43143_HOST_WAKE1; 606 break; 607 case BCM43242_CHIP_ID: 608 case BCM43243_CHIP_ID: 609 /* clear the bits */ 610 pmu_chipcontrol &= ~CCTRL1_4324_GPIO_SEL; 611 if (w & MUXENAB_GPIO) 612 pmu_chipcontrol |= CCTRL1_4324_GPIO_SEL; 613 break; 614 615 case BCM4335_CHIP_ID: 616 /* drive default pins for UART. Note: 15 values possible; 617 * 0 means disabled; 1 means index to 0 in mux4335_uartopt 618 * array, etc. 619 */ 620 if (w & MUXENAB4335_UART_MASK) { 621 uint32 uart_rx = 0, uart_tx = 0; 622 uint8 uartopt_ix = MUXENAB4335_GETIX(w, UART); 623 624 uart_rx = mux4335_uartopt[uartopt_ix].uart_rx; 625 uart_tx = mux4335_uartopt[uartopt_ix].uart_tx; 626 627 if (uartopt_ix > 628 sizeof(mux4335_uartopt)/sizeof(mux4335_uartopt[0]) - 1) { 629 SI_ERROR(("%s: wrong index %d for uart\n", 630 __FUNCTION__, uartopt_ix)); 631 break; 632 } 633 634 si_gci_set_functionsel(sih, uart_rx, CC4335_FNSEL_UART); 635 si_gci_set_functionsel(sih, uart_tx, CC4335_FNSEL_UART); 636 637 if ((uart_rx == CC4335_PIN_GPIO_02) && (uart_tx == CC4335_PIN_GPIO_06)) 638 si_gci_chipcontrol(sih, CC_GCI_CHIPCTRL_06, 639 CC_GCI_06_JTAG_SEL_MASK, 640 (1 << CC_GCI_06_JTAG_SEL_SHIFT)); 641 } 642 /* 643 * 0x10 : use GPIO0 as host wake up pin 644 * 0x20 : use GPIO5 as host wake up pin 645 * 0x30 : use GPIO9 as host wake up pin 646 * 0x40 ~ 0xf0: Reserved 647 */ 648 if (w & MUXENAB4335_HOSTWAKE_MASK) { 649 uint8 hostwake = 0; 650 uint8 hostwake_ix = MUXENAB4335_GETIX(w, HOSTWAKE); 651 652 if (hostwake_ix > 653 sizeof(mux4335_hostwakeopt)/sizeof(mux4335_hostwakeopt[0]) - 1) { 654 SI_ERROR(("%s: wrong index %d for hostwake\n", 655 __FUNCTION__, hostwake_ix)); 656 break; 657 } 658 659 hostwake = mux4335_hostwakeopt[hostwake_ix]; 660 si_gci_set_functionsel(sih, hostwake, CC4335_FNSEL_MISC1); 661 } 662 break; 663 664 case BCM4350_CHIP_ID: 665 if (w & MUXENAB4350_UART_MASK) { 666 uint32 uart_rx = 0, uart_tx = 0; 667 uint8 uartopt_idx = (w & MUXENAB4350_UART_MASK) - 1; 668 uint8 uartopt_size = sizeof(mux4350_uartopt)/sizeof(mux4350_uartopt[0]); 669 670 if (uartopt_idx < uartopt_size) { 671 uart_rx = mux4350_uartopt[uartopt_idx].uart_rx; 672 uart_tx = mux4350_uartopt[uartopt_idx].uart_tx; 673 si_gci_set_functionsel(sih, uart_rx, CC4350_FNSEL_UART); 674 si_gci_set_functionsel(sih, uart_tx, CC4350_FNSEL_UART); 675 } else { 676 SI_MSG(("si_muxenab: Invalid uart OTP setting\n")); 677 } 678 } 679 680 if (w & MUXENAB4350_HOSTWAKE_MASK) { 681 uint8 hostwake = 0; 682 uint8 hostwake_ix = 683 ((w & MUXENAB4350_HOSTWAKE_MASK)>>MUXENAB4350_HOSTWAKE_SHIFT)- 1; 684 685 if (hostwake_ix > 686 sizeof(mux4350_hostwakeopt)/sizeof(mux4350_hostwakeopt[0]) - 1) { 687 SI_ERROR(("%s: wrong index %d for hostwake\n", 688 __FUNCTION__, hostwake_ix)); 689 break; 690 } 691 692 hostwake = mux4350_hostwakeopt[hostwake_ix]; 693 si_gci_set_functionsel(sih, hostwake, CC4350_FNSEL_MISC1); 694 } 695 696 break; 697 default: 698 /* muxenab specified for an unsupported chip */ 699 ASSERT(0); 700 break; 701 } 702 703 /* write both updated values to hw */ 704 si_pmu_chipcontrol(sih, 1, ~0, pmu_chipcontrol); 705 si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, chipcontrol), 706 ~0, chipcontrol); 707} 708 709/* ltecx GCI reg access */ 710uint32 711si_gci_direct(si_t *sih, uint offset, uint32 mask, uint32 val) 712{ 713 /* gci direct reg access */ 714 return si_corereg(sih, SI_CC_IDX, offset, mask, val); 715} 716uint32 717si_gci_indirect(si_t *sih, uint regidx, uint offset, uint32 mask, uint32 val) 718{ 719 /* gci indirect reg access */ 720 si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, gci_indirect_addr), ~0, regidx); 721 return si_corereg(sih, SI_CC_IDX, offset, mask, val); 722} 723uint32 724si_gci_input(si_t *sih, uint reg) 725{ 726 /* gci_input[] */ 727 return si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, gci_input[reg]), 0, 0); 728} 729uint32 730si_gci_output(si_t *sih, uint reg, uint32 mask, uint32 val) 731{ 732 /* gci_output[] */ 733 return si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, gci_output[reg]), mask, val); 734} 735uint32 736si_gci_int_enable(si_t *sih, bool enable) 737{ 738 uint offs; 739 740 /* enable GCI interrupt */ 741 offs = OFFSETOF(chipcregs_t, intmask); 742 return (si_corereg(sih, SI_CC_IDX, offs, CI_ECI, (enable ? CI_ECI : 0))); 743} 744void 745si_gci_reset(si_t *sih) 746{ 747 int i; 748 749 /* reset SECI block */ 750 si_gci_direct(sih, OFFSETOF(chipcregs_t, gci_corectrl), 0xFFFFFFFF, 0x01); 751 for (i = 0; i < 100; i++); 752 si_gci_direct(sih, OFFSETOF(chipcregs_t, gci_corectrl), 0xFFFFFFFF, 0x00); 753 754 /* clear events */ 755 for (i = 0; i < 32; i++) 756 si_gci_direct(sih, OFFSETOF(chipcregs_t, gci_event[i]), 0xFFFFFFFF, 0x00); 757} 758void 759si_ercx_init(si_t *sih) 760{ 761 if (CHIPID(sih->chip) == BCM4334_CHIP_ID) { 762 /* enable ERCX: jtagSel bit=0, gpio as ercx bit=1 */ 763 si_pmu_chipcontrol(sih, PMU1_PLL0_CHIPCTL1, 0x0000000F, 0x0000000A); 764 } 765 else if (CHIPID(sih->chip) == BCM4335_CHIP_ID || 766 0) { 767 /* reset GCI block */ 768 si_gci_reset(sih); 769 770 /* enable ERCX (pure gpio) mode */ 771 si_gci_direct(sih, OFFSETOF(chipcregs_t, gci_corectrl), 0xFFFFFFFF, 0x30); 772 773 /* GPIO config for 4335b0 ref board */ 774 /* config GPIO 2-3-4-5-6 as pure GPIO for ERCX */ 775 si_gci_set_functionsel(sih, CC4335_PIN_GPIO_02, CC4335_FNSEL_GCI0); 776 si_gci_set_functionsel(sih, CC4335_PIN_GPIO_03, CC4335_FNSEL_GCI0); 777 si_gci_set_functionsel(sih, CC4335_PIN_GPIO_04, CC4335_FNSEL_GCI0); 778 si_gci_set_functionsel(sih, CC4335_PIN_GPIO_05, CC4335_FNSEL_GCI0); 779 si_gci_set_functionsel(sih, CC4335_PIN_GPIO_06, CC4335_FNSEL_GCI0); 780 /* enable gpio0 for debug */ 781 si_gci_set_functionsel(sih, CC4335_PIN_GPIO_00, CC4335_FNSEL_SAMEASPIN); 782 si_gpiocontrol(sih, 0x01, 0x01, GPIO_DRV_PRIORITY); 783 784 /* gpio-2/7 as output & gpio-0/1/6 as input */ 785 si_gci_indirect(sih, 0, 786 OFFSETOF(chipcregs_t, gci_gpioctl), 0xFFFFFFFF, 0x00020101); 787 si_gci_indirect(sih, 1, 788 OFFSETOF(chipcregs_t, gci_gpioctl), 0xFFFFFFFF, 0x02010000); 789 /* gpio mapping: 790 * wlan_prio(gpio5(7)),frmsync(gpio2(1)), 791 * mws_tx(gpio3(0)),mws_rx(gpio4(6)) 792 */ 793 si_gci_indirect(sih, 0x10010, 794 OFFSETOF(chipcregs_t, gci_gpiomask), 0xFFFFFFFF, 0x00000001); 795 si_gci_indirect(sih, 0x60010, 796 OFFSETOF(chipcregs_t, gci_gpiomask), 0xFFFFFFFF, 0x00000002); 797 si_gci_indirect(sih, 0x00010, 798 OFFSETOF(chipcregs_t, gci_gpiomask), 0xFFFFFFFF, 0x00000004); 799 si_gci_indirect(sih, 0x70000, 800 OFFSETOF(chipcregs_t, gci_gpiomask), 0xFFFFFFFF, 0x00000010); 801 si_gci_indirect(sih, 0x20000, 802 OFFSETOF(chipcregs_t, gci_gpiomask), 0xFFFFFFFF, 0x00000040); 803 } 804} 805void 806si_wci2_init(si_t *sih) 807{ 808 if (CHIPID(sih->chip) == BCM4335_CHIP_ID || 809 0) { 810 /* reset GCI block */ 811 si_gci_reset(sih); 812 813 /* enable BT-SIG mode */ 814 si_gci_direct(sih, OFFSETOF(chipcregs_t, gci_corectrl), 0xFFFFFFFF, 0x24); 815 /* config GPIO pins 4/5 as SECI_IN/SECI_OUT */ 816 si_gci_set_functionsel(sih, CC4335_PIN_GPIO_04, CC4335_FNSEL_GCI0); 817 si_gci_set_functionsel(sih, CC4335_PIN_GPIO_05, CC4335_FNSEL_GCI0); 818 /* baudrate:3mbps, escseq:0xdb, high baudrate, enable seci_tx/rx */ 819 si_gci_direct(sih, OFFSETOF(chipcregs_t, gci_miscctl), 0x000F, 0x0000); 820 si_gci_direct(sih, OFFSETOF(chipcregs_t, gci_secibauddiv), 0xFFFFFFFF, 0xF4); 821 si_gci_direct(sih, OFFSETOF(chipcregs_t, gci_secifcr), 0xFFFFFFFF, 0x00); 822 si_gci_direct(sih, OFFSETOF(chipcregs_t, gci_secimcr), 0xFFFFFFFF, 0x89); 823 si_gci_direct(sih, OFFSETOF(chipcregs_t, gci_secilcr), 0xFFFFFFFF, 0x28); 824 si_gci_direct(sih, OFFSETOF(chipcregs_t, gci_uartescval), 0xFFFFFFFF, 0xDB); 825 si_gci_direct(sih, OFFSETOF(chipcregs_t, gci_baudadj), 0xFFFFFFFF, 0x22); 826 827 /* GPIO 3-7 as BT_SIG complaint */ 828 /* config GPIO pins 3-7 as input */ 829 si_gci_indirect(sih, 0, 830 OFFSETOF(chipcregs_t, gci_gpioctl), 0x20000000, 0x20000000); 831 si_gci_indirect(sih, 1, 832 OFFSETOF(chipcregs_t, gci_gpioctl), 0x20202020, 0x20202020); 833 /* gpio mapping: frmsync-gpio7, mws_rx-gpio6, mws_tx-gpio5, 834 * pat[0]-gpio4, pat[1]-gpio3 835 */ 836 si_gci_indirect(sih, 0x70010, 837 OFFSETOF(chipcregs_t, gci_gpiomask), 0x00000001, 0x00000001); 838 si_gci_indirect(sih, 0x60010, 839 OFFSETOF(chipcregs_t, gci_gpiomask), 0x00000002, 0x00000002); 840 si_gci_indirect(sih, 0x50010, 841 OFFSETOF(chipcregs_t, gci_gpiomask), 0x00000004, 0x00000004); 842 si_gci_indirect(sih, 0x40010, 843 OFFSETOF(chipcregs_t, gci_gpiomask), 0x06000000, 0x06000000); 844 si_gci_indirect(sih, 0x30010, 845 OFFSETOF(chipcregs_t, gci_gpiomask), 0x08000000, 0x08000000); 846 /* gpio mapping: wlan_rx_prio-gpio5, wlan_tx_on-gpio4 */ 847 si_gci_indirect(sih, 0x50000, 848 OFFSETOF(chipcregs_t, gci_gpiomask), 0x00000010, 0x00000010); 849 si_gci_indirect(sih, 0x40000, 850 OFFSETOF(chipcregs_t, gci_gpiomask), 0x00000020, 0x00000020); 851 /* enable gpio out on gpio4(wlanrxprio), gpio5(wlantxon) */ 852 si_gci_direct(sih, 853 OFFSETOF(chipcregs_t, gci_control_0), 0x00000030, 0x00000030); 854 } 855} 856 857uint16 858si_cc_get_reg16(uint32 reg_offs) 859{ 860 return (*((volatile uint16 *)((char *)SI_ENUM_BASE + reg_offs))); 861} 862 863uint32 864si_cc_get_reg32(uint32 reg_offs) 865{ 866 return (*((volatile uint32 *)((char *)SI_ENUM_BASE + reg_offs))); 867} 868 869uint32 870si_cc_set_reg32(uint32 reg_offs, uint32 val) 871{ 872 *((volatile uint32 *)((char *)SI_ENUM_BASE + reg_offs)) = val; 873 return si_cc_get_reg32(reg_offs); 874} 875 876uint32 877si_gci_preinit_upd_indirect(uint32 regidx, uint32 setval, uint32 mask) 878{ 879 uint32 val = 0; 880 881 si_cc_set_reg32(CC_GCI_INDIRECT_ADDR_REG, regidx); 882 val = si_cc_get_reg32(CC_GCI_CHIP_CTRL_REG); 883 884 val &= ~mask; 885 val |= setval; 886 887 return si_cc_set_reg32(CC_GCI_CHIP_CTRL_REG, val); 888} 889 890void 891si_gci_seci_init(si_t *sih) 892{ 893 if (CHIPID(sih->chip) == BCM4335_CHIP_ID || 894 0) { 895 /* reset GCI block */ 896 si_gci_reset(sih); 897 898 /* enable SECI mode */ 899 si_gci_direct(sih, OFFSETOF(chipcregs_t, gci_corectrl), 0xFFFFFFFF, 0x14); 900 /* config GPIO pins 4/5 as SECI_IN/SECI_OUT */ 901 si_gci_set_functionsel(sih, CC4335_PIN_GPIO_04, CC4335_FNSEL_GCI0); 902 si_gci_set_functionsel(sih, CC4335_PIN_GPIO_05, CC4335_FNSEL_GCI0); 903 /* baudrate:3mbps, escseq:0xdb, high baudrate, enable seci_tx/rx */ 904 si_gci_direct(sih, OFFSETOF(chipcregs_t, gci_miscctl), 0x0000000F, 0x0000); 905 si_gci_direct(sih, OFFSETOF(chipcregs_t, gci_secibauddiv), 0xFFFFFFFF, 0xF4); 906 si_gci_direct(sih, OFFSETOF(chipcregs_t, gci_secifcr), 0xFFFFFFFF, 0x00); 907 si_gci_direct(sih, OFFSETOF(chipcregs_t, gci_secimcr), 0xFFFFFFFF, 0x89); 908 si_gci_direct(sih, OFFSETOF(chipcregs_t, gci_secilcr), 0xFFFFFFFF, 0x28); 909 si_gci_direct(sih, OFFSETOF(chipcregs_t, gci_uartescval), 0xFFFFFFFF, 0xDB); 910 si_gci_direct(sih, OFFSETOF(chipcregs_t, gci_baudadj), 0xFFFFFFFF, 0x22); 911 912 /* map nibble from IP=4 (LTE) with addr 0-11 to LTE space 913 * (lower nibble addr; upper nibble IP) 914 */ 915 si_gci_indirect(sih, 0, 916 OFFSETOF(chipcregs_t, gci_secif0rx_offset), 0xFFFFFFFF, 0x43424140); 917 si_gci_indirect(sih, 1, 918 OFFSETOF(chipcregs_t, gci_secif0rx_offset), 0xFFFFFFFF, 0x47464544); 919 si_gci_indirect(sih, 2, 920 OFFSETOF(chipcregs_t, gci_secif0rx_offset), 0xFFFFFFFF, 0x4b4a4948); 921 922 /* select nibbles to be communicated using format-I: wlan nibble 1/4, bt nibble 1 */ 923 /* note: we can only select 1st 12 nibbles of each IP for format_0 */ 924 si_gci_indirect(sih, 0, 925 OFFSETOF(chipcregs_t, gci_seciusef0tx_reg), 0xFFFFFFFF, 0x00000012); 926 si_gci_indirect(sih, 1, 927 OFFSETOF(chipcregs_t, gci_seciusef0tx_reg), 0xFFFFFFFF, 0x00000002); 928 929 /* assigns address to To LTE nibbles from BT-WLAN IP space (addr 0 to 11) */ 930 /* wlan nibble1: addr0, wlan nibble4: addr1, wlan nibble12: can't be communicated */ 931 /* bt nibble1: addr2, bt nibble12/13: can't be communicated */ 932 si_gci_indirect(sih, 0, 933 OFFSETOF(chipcregs_t, gci_secif0tx_offset), 0x000F00F0, 0x00010000); 934 si_gci_indirect(sih, 4, 935 OFFSETOF(chipcregs_t, gci_secif0tx_offset), 0x000000F0, 0x00000020); 936 937 /* enable wlan nibble 1 and 4 control bits */ 938 /* NOTE: BT should enable bits for nibble 1 */ 939 si_gci_direct(sih, 940 OFFSETOF(chipcregs_t, gci_control_0), 0xFFFFFFFF, 0x000F00F0); 941 942 /* mailbox 1 to 1 mapping: 943 * mailbox data generated by an IP goes to its own mailbox space in peer GCI chip 944 */ 945 si_gci_direct(sih, 946 OFFSETOF(chipcregs_t, gci_secif1tx_offset), 0xFFFFFFFF, 0x00043210); 947 } 948} 949 950 951/** write 'val' to the gci chip control register indexed by 'reg' */ 952uint32 953si_gci_chipcontrol(si_t *sih, uint reg, uint32 mask, uint32 val) 954{ 955 /* because NFLASH and GCI clashes in 0xC00 */ 956#ifndef NFLASH_SUPPORT 957 si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, gci_indirect_addr), ~0, reg); 958 return si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, gci_chipctrl), mask, val); 959#else /* NFLASH_SUPPORT */ 960 ASSERT(0); 961 return 0xFFFFFFFF; 962#endif 963} 964 965/* input: pin number 966* output: chipcontrol reg and bits to shift for pin fn-sel's first regbit. 967* eg: gpio9 will give regidx: 1 and pos 4 968*/ 969uint8 970si_gci_get_chipctrlreg_idx(uint32 pin, uint32 *regidx, uint32 *pos) 971{ 972 *regidx = (pin / 8); 973 *pos = (pin % 8)*4; 974 975 SI_MSG(("si_gci_get_chipctrlreg_idx:%d:%d:%d\n", pin, *regidx, *pos)); 976 977 return 0; 978} 979 980/** setup a given pin for fnsel function */ 981void 982si_gci_set_functionsel(si_t *sih, uint32 pin, uint8 fnsel) 983{ 984 uint32 reg = 0, pos = 0; 985 986 SI_MSG(("si_gci_set_functionsel:%d\n", pin)); 987 988 si_gci_get_chipctrlreg_idx(pin, ®, &pos); 989 si_gci_chipcontrol(sih, reg, GCIMASK(pos), GCIPOSVAL(fnsel, pos)); 990} 991 992void 993BCMATTACHFN(si_gci_chipctrl_overrides)(osl_t *osh, si_t *sih, char *pvars) 994{ 995 uint8 num_cc = 0; 996 char gciccstr[16]; 997 const char *otp_val; 998 uint32 gciccval = 0, cap1 = 0; 999 int i = 0; 1000 1001/* because NFLASH and GCI clashes in 0xC00 */ 1002#ifndef NFLASH_SUPPORT 1003 cap1 = si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, gci_corecaps1), 0, 0); 1004#else /* NFLASH_SUPPORT */ 1005 ASSERT(0); 1006#endif 1007 num_cc = CC_GCI_NUMCHIPCTRLREGS(cap1); 1008 1009 for (i = 0; i < num_cc; i++) { 1010 snprintf(gciccstr, sizeof(gciccstr), "gcr%d", i); 1011 1012 if ((otp_val = getvar(NULL, gciccstr)) == NULL) 1013 continue; 1014 1015 gciccval = (uint32) getintvar(pvars, gciccstr); 1016 si_gci_chipcontrol(sih, i, ~0, gciccval); 1017 } 1018} 1019 1020static si_info_t * 1021BCMATTACHFN(si_doattach)(si_info_t *sii, uint devid, osl_t *osh, void *regs, 1022 uint bustype, void *sdh, char **vars, uint *varsz) 1023{ 1024 struct si_pub *sih = &sii->pub; 1025 uint32 w, savewin; 1026 chipcregs_t *cc; 1027 char *pvars = NULL; 1028 uint origidx; 1029#if (!defined(_CFE_) && !defined(_CFEZ_)) || defined(CFG_WL) 1030 bool fixup_boardtype = FALSE; 1031#endif /* (!_CFE_ && !_CFEZ_) || CFG_WL */ 1032 ASSERT(GOODREGS(regs)); 1033 1034 bzero((uchar*)sii, sizeof(si_info_t)); 1035 1036 savewin = 0; 1037 1038 sih->buscoreidx = BADIDX; 1039 1040 sii->curmap = regs; 1041 sii->sdh = sdh; 1042 sii->osh = osh; 1043 1044#ifdef SI_ENUM_BASE_VARIABLE 1045 si_enum_base_init(sih, bustype); 1046#endif /* SI_ENUM_BASE_VARIABLE */ 1047 1048 /* check to see if we are a si core mimic'ing a pci core */ 1049 if ((bustype == PCI_BUS) && 1050 (OSL_PCI_READ_CONFIG(sii->osh, PCI_SPROM_CONTROL, sizeof(uint32)) == 0xffffffff)) { 1051 SI_ERROR(("%s: incoming bus is PCI but it's a lie, switching to SI " 1052 "devid:0x%x\n", __FUNCTION__, devid)); 1053 bustype = SI_BUS; 1054 } 1055 1056 /* find Chipcommon address */ 1057 if (bustype == PCI_BUS) { 1058 savewin = OSL_PCI_READ_CONFIG(sii->osh, PCI_BAR0_WIN, sizeof(uint32)); 1059 if (!GOODCOREADDR(savewin, SI_ENUM_BASE)) 1060 savewin = SI_ENUM_BASE; 1061 OSL_PCI_WRITE_CONFIG(sii->osh, PCI_BAR0_WIN, 4, SI_ENUM_BASE); 1062 if (!regs) 1063 return NULL; 1064 cc = (chipcregs_t *)regs; 1065 } else { 1066 cc = (chipcregs_t *)REG_MAP(SI_ENUM_BASE, SI_CORE_SIZE); 1067 } 1068 1069 sih->bustype = bustype; 1070 if (bustype != BUSTYPE(bustype)) { 1071 SI_ERROR(("si_doattach: bus type %d does not match configured bus type %d\n", 1072 bustype, BUSTYPE(bustype))); 1073 return NULL; 1074 } 1075 1076 /* bus/core/clk setup for register access */ 1077 if (!si_buscore_prep(sii, bustype, devid, sdh)) { 1078 SI_ERROR(("si_doattach: si_core_clk_prep failed %d\n", bustype)); 1079 return NULL; 1080 } 1081 1082 /* ChipID recognition. 1083 * We assume we can read chipid at offset 0 from the regs arg. 1084 * If we add other chiptypes (or if we need to support old sdio hosts w/o chipcommon), 1085 * some way of recognizing them needs to be added here. 1086 */ 1087 if (!cc) { 1088 SI_ERROR(("%s: chipcommon register space is null \n", __FUNCTION__)); 1089 return NULL; 1090 } 1091 w = R_REG(osh, &cc->chipid); 1092 sih->socitype = (w & CID_TYPE_MASK) >> CID_TYPE_SHIFT; 1093 /* Might as wll fill in chip id rev & pkg */ 1094 sih->chip = w & CID_ID_MASK; 1095 sih->chiprev = (w & CID_REV_MASK) >> CID_REV_SHIFT; 1096 sih->chippkg = (w & CID_PKG_MASK) >> CID_PKG_SHIFT; 1097 1098 if ((CHIPID(sih->chip) == BCM4329_CHIP_ID) && (sih->chiprev == 0) && 1099 (sih->chippkg != BCM4329_289PIN_PKG_ID)) { 1100 sih->chippkg = BCM4329_182PIN_PKG_ID; 1101 } 1102 sih->issim = IS_SIM(sih->chippkg); 1103 1104 /* scan for cores */ 1105 if (CHIPTYPE(sii->pub.socitype) == SOCI_SB) { 1106 SI_MSG(("Found chip type SB (0x%08x)\n", w)); 1107 sb_scan(&sii->pub, regs, devid); 1108 } else if ((CHIPTYPE(sii->pub.socitype) == SOCI_AI) || 1109 (CHIPTYPE(sii->pub.socitype) == SOCI_NAI)) { 1110 if (CHIPTYPE(sii->pub.socitype) == SOCI_AI) 1111 SI_MSG(("Found chip type AI (0x%08x)\n", w)); 1112 else 1113 SI_MSG(("Found chip type NAI (0x%08x)\n", w)); 1114 /* pass chipc address instead of original core base */ 1115 ai_scan(&sii->pub, (void *)(uintptr)cc, devid); 1116 } else if (CHIPTYPE(sii->pub.socitype) == SOCI_UBUS) { 1117 SI_MSG(("Found chip type UBUS (0x%08x), chip id = 0x%4x\n", w, sih->chip)); 1118 /* pass chipc address instead of original core base */ 1119 ub_scan(&sii->pub, (void *)(uintptr)cc, devid); 1120 } else { 1121 SI_ERROR(("Found chip of unknown type (0x%08x)\n", w)); 1122 return NULL; 1123 } 1124 /* no cores found, bail out */ 1125 if (sii->numcores == 0) { 1126 SI_ERROR(("si_doattach: could not find any cores\n")); 1127 return NULL; 1128 } 1129 /* bus/core/clk setup */ 1130 origidx = SI_CC_IDX; 1131 if (!si_buscore_setup(sii, cc, bustype, savewin, &origidx, regs)) { 1132 SI_ERROR(("si_doattach: si_buscore_setup failed\n")); 1133 goto exit; 1134 } 1135 1136#if (!defined(_CFE_) && !defined(_CFEZ_)) || defined(CFG_WL) 1137 if (CHIPID(sih->chip) == BCM4322_CHIP_ID && (((sih->chipst & CST4322_SPROM_OTP_SEL_MASK) 1138 >> CST4322_SPROM_OTP_SEL_SHIFT) == (CST4322_OTP_PRESENT | 1139 CST4322_SPROM_PRESENT))) { 1140 SI_ERROR(("%s: Invalid setting: both SPROM and OTP strapped.\n", __FUNCTION__)); 1141 return NULL; 1142 } 1143 1144 /* assume current core is CC */ 1145 if ((sii->pub.ccrev == 0x25) && ((CHIPID(sih->chip) == BCM43236_CHIP_ID || 1146 CHIPID(sih->chip) == BCM43235_CHIP_ID || 1147 CHIPID(sih->chip) == BCM43234_CHIP_ID || 1148 CHIPID(sih->chip) == BCM43238_CHIP_ID) && 1149 (CHIPREV(sii->pub.chiprev) <= 2))) { 1150 1151 if ((cc->chipstatus & CST43236_BP_CLK) != 0) { 1152 uint clkdiv; 1153 clkdiv = R_REG(osh, &cc->clkdiv); 1154 /* otp_clk_div is even number, 120/14 < 9mhz */ 1155 clkdiv = (clkdiv & ~CLKD_OTP) | (14 << CLKD_OTP_SHIFT); 1156 W_REG(osh, &cc->clkdiv, clkdiv); 1157 SI_ERROR(("%s: set clkdiv to %x\n", __FUNCTION__, clkdiv)); 1158 } 1159 OSL_DELAY(10); 1160 } 1161 1162 if (bustype == PCI_BUS) { 1163 if ((CHIPID(sih->chip) == BCM4331_CHIP_ID) || 1164 (CHIPID(sih->chip) == BCM43431_CHIP_ID)) { 1165 /* Check Ext PA Controls for 4331 12x9 Package before the fixup */ 1166 if (sih->chippkg == 9) { 1167 uint32 val = si_chipcontrl_read(sih); 1168 fixup_boardtype = ((val & CCTRL4331_EXTPA_ON_GPIO2_5) == 1169 CCTRL4331_EXTPA_ON_GPIO2_5); 1170 } 1171 /* set default mux pin to SROM */ 1172 si_chipcontrl_epa4331(sih, FALSE); 1173 si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, watchdog), ~0, 100); 1174 OSL_DELAY(20000); /* Srom read takes ~12mS */ 1175 } 1176 1177 if (((CHIPID(sih->chip) == BCM4360_CHIP_ID) || 1178 (CHIPID(sih->chip) == BCM43460_CHIP_ID) || 1179 (CHIPID(sih->chip) == BCM4352_CHIP_ID)) && 1180 (CHIPREV(sih->chiprev) <= 2)) { 1181 pcie_disable_TL_clk_gating(sii->pch); 1182 pcie_set_L1_entry_time(sii->pch, 0x40); 1183 } 1184 1185#ifdef BCMQT 1186 /* Set OTPClkDiv to smaller value otherwise OTP always reads 0xFFFF. 1187 * For real-chip we shouldn't set OTPClkDiv to 2 because 20/2 = 10 > 9Mhz 1188 * but for 4314 QT if we set it to 4. OTP reads 0xFFFF every two words. 1189 */ 1190 { 1191 uint otpclkdiv = 0; 1192 1193 if ((CHIPID(sih->chip) == BCM4314_CHIP_ID) || 1194 (CHIPID(sih->chip) == BCM43142_CHIP_ID)) { 1195 otpclkdiv = 2; 1196 } else if ((CHIPID(sih->chip) == BCM43131_CHIP_ID) || 1197 (CHIPID(sih->chip) == BCM43217_CHIP_ID) || 1198 (CHIPID(sih->chip) == BCM43227_CHIP_ID) || 1199 (CHIPID(sih->chip) == BCM43228_CHIP_ID)) { 1200 otpclkdiv = 4; 1201 } 1202 1203 if (otpclkdiv != 0) { 1204 uint clkdiv, savecore; 1205 savecore = si_coreidx(sih); 1206 si_setcore(sih, CC_CORE_ID, 0); 1207 1208 clkdiv = R_REG(osh, &cc->clkdiv); 1209 clkdiv = (clkdiv & ~CLKD_OTP) | (otpclkdiv << CLKD_OTP_SHIFT); 1210 W_REG(osh, &cc->clkdiv, clkdiv); 1211 1212 SI_ERROR(("%s: set clkdiv to 0x%x for QT\n", __FUNCTION__, clkdiv)); 1213 si_setcoreidx(sih, savecore); 1214 } 1215 } 1216#endif /* BCMQT */ 1217 } 1218#endif /* (!_CFE_ && !_CFEZ_) || CFG_WL */ 1219#ifdef BCM_SDRBL 1220 /* 4360 rom bootloader in PCIE case, if the SDR is enabled, But protection is 1221 * not turned on, then we want to hold arm in reset. 1222 * Bottomline: In sdrenable case, we allow arm to boot only when protection is 1223 * turned on. 1224 */ 1225 if (CHIP_HOSTIF_PCIE(&(sii->pub))) { 1226 uint32 sflags = si_arm_sflags(&(sii->pub)); 1227 1228 /* If SDR is enabled but protection is not turned on 1229 * then we want to force arm to WFI. 1230 */ 1231 if ((sflags & (SISF_SDRENABLE | SISF_TCMPROT)) == SISF_SDRENABLE) { 1232 disable_arm_irq(); 1233 while (1) { 1234 hnd_cpu_wait(sih); 1235 } 1236 } 1237 } 1238#endif /* BCM_SDRBL */ 1239#ifdef SI_SPROM_PROBE 1240 si_sprom_init(sih); 1241#endif /* SI_SPROM_PROBE */ 1242 1243#if !defined(BCMHIGHSDIO) 1244 /* Init nvram from flash if it exists */ 1245 nvram_init((void *)&(sii->pub)); 1246 1247#if defined(_CFE_) && defined(BCM_DEVINFO) 1248 devinfo_nvram_init((void *)&(sii->pub)); 1249#endif 1250 1251 /* Init nvram from sprom/otp if they exist */ 1252 if (srom_var_init(&sii->pub, BUSTYPE(bustype), regs, sii->osh, vars, varsz)) { 1253 SI_ERROR(("si_doattach: srom_var_init failed: bad srom\n")); 1254 goto exit; 1255 } 1256 pvars = vars ? *vars : NULL; 1257 1258 si_nvram_process(sii, pvars); 1259 1260#if (!defined(_CFE_) && !defined(_CFEZ_)) || defined(CFG_WL) 1261 if (bustype == PCI_BUS) { 1262 if ((CHIPID(sih->chip) == BCM4331_CHIP_ID) || 1263 (CHIPID(sih->chip) == BCM43431_CHIP_ID)) { 1264 si_sromvars_fixup_4331(sih, pvars); 1265 if (fixup_boardtype) 1266 sii->pub.boardtype = getintvar(pvars, "boardtype"); 1267 } 1268 } 1269#endif /* (!_CFE_ && !_CFEZ_) || CFG_WL */ 1270 1271 /* === NVRAM, clock is ready === */ 1272#else 1273 pvars = NULL; 1274 BCM_REFERENCE(pvars); 1275#endif 1276 1277 1278#if defined(CONFIG_XIP) && defined(BCMTCAM) 1279 /* patch the ROM if there are any patch pairs from OTP/SPROM */ 1280 if (patch_pair) { 1281 1282#if defined(__ARM_ARCH_7R__) 1283 hnd_tcam_bootloader_load(si_setcore(sih, ARMCR4_CORE_ID, 0), pvars); 1284#else 1285 hnd_tcam_bootloader_load(si_setcore(sih, SOCRAM_CORE_ID, 0), pvars); 1286#endif 1287 si_setcoreidx(sih, origidx); 1288 } 1289#endif /* CONFIG_XIP && BCMTCAM */ 1290 1291 /* bootloader should retain default pulls */ 1292#ifndef BCM_BOOTLOADER 1293 if (sii->pub.ccrev >= 20) { 1294 uint32 gpiopullup = 0, gpiopulldown = 0; 1295 cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0); 1296 ASSERT(cc != NULL); 1297 1298 /* 4314/43142 has pin muxing, don't clear gpio bits */ 1299 if ((CHIPID(sih->chip) == BCM4314_CHIP_ID) || 1300 (CHIPID(sih->chip) == BCM43142_CHIP_ID)) { 1301 gpiopullup |= 0x402e0; 1302 gpiopulldown |= 0x20500; 1303 } 1304 1305 W_REG(osh, &cc->gpiopullup, gpiopullup); 1306 W_REG(osh, &cc->gpiopulldown, gpiopulldown); 1307 si_setcoreidx(sih, origidx); 1308 } 1309#endif /* !BCM_BOOTLOADER */ 1310 1311 /* PMU specific initializations */ 1312 if (PMUCTL_ENAB(sih)) { 1313 uint32 xtalfreq, mode; 1314 si_pmu_init(sih, sii->osh); 1315 si_pmu_chip_init(sih, sii->osh); 1316 xtalfreq = getintvar(pvars, "xtalfreq"); 1317 switch (CHIPID(sih->chip)) { 1318 case BCM43242_CHIP_ID: 1319 case BCM43243_CHIP_ID: 1320 xtalfreq = 37400; 1321 break; 1322 case BCM43143_CHIP_ID: 1323 xtalfreq = 20000; 1324 break; 1325 case BCM4350_CHIP_ID: 1326 if (xtalfreq == 0) { 1327 mode = CST4350_IFC_MODE(sih->chipst); 1328 if ((mode == CST4350_IFC_MODE_USB20D) || 1329 (mode == CST4350_IFC_MODE_USB30D) || 1330 (mode == CST4350_IFC_MODE_USB30D_WL)) 1331 xtalfreq = 40000; 1332 else 1333 xtalfreq = 37400; 1334 } 1335 break; 1336 default: 1337 break; 1338 } 1339 /* If xtalfreq var not available, try to measure it */ 1340 if (xtalfreq == 0) 1341 xtalfreq = si_pmu_measure_alpclk(sih, sii->osh); 1342#if !defined(BCMHIGHSDIO) 1343 si_pmu_pll_init(sih, sii->osh, xtalfreq); 1344#endif 1345 1346#if defined(SR_ESSENTIALS) 1347 /* Only needs to be done once. 1348 * Needs this before si_pmu_res_init() to use sr_isenab() 1349 */ 1350 if (SR_ESSENTIALS_ENAB()) 1351 sr_save_restore_init(sih); 1352#endif /* SR_ESSENTIALS */ 1353#if !defined(BCMHIGHSDIO) 1354 si_pmu_res_init(sih, sii->osh); 1355#endif 1356 si_pmu_swreg_init(sih, sii->osh); 1357 } 1358 1359#ifdef WLLED 1360 /* setup the GPIO based LED powersave register */ 1361 if (sii->pub.ccrev >= 16) { 1362 if ((w = getintvar(pvars, "leddc")) == 0) 1363 w = DEFAULT_GPIOTIMERVAL; 1364 si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, gpiotimerval), ~0, w); 1365 } 1366#endif 1367 if (PCI_FORCEHT(sii)) { 1368 SI_MSG(("si_doattach: force HT\n")); 1369 sih->pci_pr32414 = TRUE; 1370 si_clkctl_init(sih); 1371 _si_clkctl_cc(sii, CLK_FAST); 1372 } 1373 1374#if (!defined(_CFE_) && !defined(_CFEZ_)) || defined(CFG_WL) 1375 if (PCIE(sii)) { 1376 ASSERT(sii->pch != NULL); 1377 1378 pcicore_attach(sii->pch, pvars, SI_DOATTACH); 1379 1380 if (((CHIPID(sih->chip) == BCM4311_CHIP_ID) && (CHIPREV(sih->chiprev) == 2)) || 1381 (CHIPID(sih->chip) == BCM4312_CHIP_ID)) { 1382 SI_MSG(("si_doattach: clear initiator timeout\n")); 1383 sb_set_initiator_to(sih, 0x3, si_findcoreidx(sih, D11_CORE_ID, 0)); 1384 } 1385 } 1386 1387 if ((CHIPID(sih->chip) == BCM43224_CHIP_ID) || 1388 (CHIPID(sih->chip) == BCM43421_CHIP_ID)) { 1389 /* enable 12 mA drive strenth for 43224 and set chipControl register bit 15 */ 1390 if (CHIPREV(sih->chiprev) == 0) { 1391 SI_MSG(("Applying 43224A0 WARs\n")); 1392 si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, chipcontrol), 1393 CCTRL43224_GPIO_TOGGLE, CCTRL43224_GPIO_TOGGLE); 1394 si_pmu_chipcontrol(sih, 0, CCTRL_43224A0_12MA_LED_DRIVE, 1395 CCTRL_43224A0_12MA_LED_DRIVE); 1396 } 1397 if (CHIPREV(sih->chiprev) >= 1) { 1398 SI_MSG(("Applying 43224B0+ WARs\n")); 1399 si_pmu_chipcontrol(sih, 0, CCTRL_43224B0_12MA_LED_DRIVE, 1400 CCTRL_43224B0_12MA_LED_DRIVE); 1401 } 1402 } 1403 1404 /* configure default pinmux enables for the chip */ 1405 if (getvar(pvars, "muxenab") != NULL) { 1406 w = getintvar(pvars, "muxenab"); 1407 si_muxenab((si_t *)sii, w); 1408 } 1409 1410 /* enable GPIO interrupts when clocks are off */ 1411 if (sii->pub.ccrev >= 21) { 1412 uint32 corecontrol; 1413 corecontrol = si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, corecontrol), 1414 0, 0); 1415 corecontrol |= CC_ASYNCGPIO; 1416 si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, corecontrol), 1417 corecontrol, corecontrol); 1418 } 1419 1420 if (CHIPID(sih->chip) == BCM4313_CHIP_ID) { 1421 /* enable 12 mA drive strenth for 4313 and set chipControl register bit 1 */ 1422 SI_MSG(("Applying 4313 WARs\n")); 1423 si_pmu_chipcontrol(sih, 0, CCTRL_4313_12MA_LED_DRIVE, CCTRL_4313_12MA_LED_DRIVE); 1424 } 1425#endif /* (!_CFE_ && !_CFEZ_) || CFG_WL */ 1426 /* clear any previous epidiag-induced target abort */ 1427 ASSERT(!si_taclear(sih, FALSE)); 1428 1429 if ((CHIPID(sih->chip) == BCM4335_CHIP_ID) || 1430#ifndef BCM4350_FPGA 1431 (CHIPID(sih->chip) == BCM4350_CHIP_ID) || 1432#endif 1433 0) { 1434 si_gci_chipctrl_overrides(osh, sih, pvars); 1435 } 1436 1437 return (sii); 1438 1439exit: 1440 if (BUSTYPE(sih->bustype) == PCI_BUS) { 1441 if (sii->pch) 1442 pcicore_deinit(sii->pch); 1443 sii->pch = NULL; 1444 } 1445 1446 return NULL; 1447} 1448 1449/** may be called with core in reset */ 1450void 1451BCMATTACHFN(si_detach)(si_t *sih) 1452{ 1453 si_info_t *sii; 1454 uint idx; 1455 1456#if defined(STA) 1457 struct si_pub *si_local = NULL; 1458 bcopy(&sih, &si_local, sizeof(si_t*)); 1459#endif 1460 1461 sii = SI_INFO(sih); 1462 1463 if (sii == NULL) 1464 return; 1465 1466 if (BUSTYPE(sih->bustype) == SI_BUS) 1467 for (idx = 0; idx < SI_MAXCORES; idx++) 1468 if (sii->regs[idx]) { 1469 REG_UNMAP(sii->regs[idx]); 1470 sii->regs[idx] = NULL; 1471 } 1472 1473#if defined(STA) 1474#if !defined(BCMHIGHSDIO) 1475 srom_var_deinit((void *)si_local); 1476#endif 1477 nvram_exit((void *)si_local); /* free up nvram buffers */ 1478#endif 1479 1480#if defined(STB) 1481 nvram_exit((void *)sih); 1482#endif /* defined(STB) */ 1483 1484 if (BUSTYPE(sih->bustype) == PCI_BUS) { 1485 if (sii->pch) 1486 pcicore_deinit(sii->pch); 1487 sii->pch = NULL; 1488 } 1489 1490#if !defined(BCMBUSTYPE) || (BCMBUSTYPE == SI_BUS) 1491 if (sii != &ksii) 1492#endif /* !BCMBUSTYPE || (BCMBUSTYPE == SI_BUS) */ 1493 MFREE(sii->osh, sii, sizeof(si_info_t)); 1494} 1495 1496void * 1497si_osh(si_t *sih) 1498{ 1499 si_info_t *sii; 1500 1501 sii = SI_INFO(sih); 1502 return sii->osh; 1503} 1504 1505void 1506si_setosh(si_t *sih, osl_t *osh) 1507{ 1508 si_info_t *sii; 1509 1510 sii = SI_INFO(sih); 1511 if (sii->osh != NULL) { 1512 SI_ERROR(("osh is already set....\n")); 1513 ASSERT(!sii->osh); 1514 } 1515 sii->osh = osh; 1516} 1517 1518/** register driver interrupt disabling and restoring callback functions */ 1519void 1520si_register_intr_callback(si_t *sih, void *intrsoff_fn, void *intrsrestore_fn, 1521 void *intrsenabled_fn, void *intr_arg) 1522{ 1523 si_info_t *sii; 1524 1525 sii = SI_INFO(sih); 1526 sii->intr_arg = intr_arg; 1527 sii->intrsoff_fn = (si_intrsoff_t)intrsoff_fn; 1528 sii->intrsrestore_fn = (si_intrsrestore_t)intrsrestore_fn; 1529 sii->intrsenabled_fn = (si_intrsenabled_t)intrsenabled_fn; 1530 /* save current core id. when this function called, the current core 1531 * must be the core which provides driver functions(il, et, wl, etc.) 1532 */ 1533 sii->dev_coreid = sii->coreid[sii->curidx]; 1534} 1535 1536void 1537si_deregister_intr_callback(si_t *sih) 1538{ 1539 si_info_t *sii; 1540 1541 sii = SI_INFO(sih); 1542 sii->intrsoff_fn = NULL; 1543} 1544 1545uint 1546si_intflag(si_t *sih) 1547{ 1548 si_info_t *sii = SI_INFO(sih); 1549 1550 if (CHIPTYPE(sih->socitype) == SOCI_SB) 1551 return sb_intflag(sih); 1552 else if ((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NAI)) 1553 return R_REG(sii->osh, ((uint32 *)(uintptr) 1554 (sii->oob_router + OOB_STATUSA))); 1555 else { 1556 ASSERT(0); 1557 return 0; 1558 } 1559} 1560 1561uint 1562si_flag(si_t *sih) 1563{ 1564 if (CHIPTYPE(sih->socitype) == SOCI_SB) 1565 return sb_flag(sih); 1566 else if ((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NAI)) 1567 return ai_flag(sih); 1568 else if (CHIPTYPE(sih->socitype) == SOCI_UBUS) 1569 return ub_flag(sih); 1570 else { 1571 ASSERT(0); 1572 return 0; 1573 } 1574} 1575 1576uint 1577si_flag_alt(si_t *sih) 1578{ 1579 if ((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NAI)) 1580 return ai_flag_alt(sih); 1581 else { 1582 ASSERT(0); 1583 return 0; 1584 } 1585} 1586 1587void 1588si_setint(si_t *sih, int siflag) 1589{ 1590 if (CHIPTYPE(sih->socitype) == SOCI_SB) 1591 sb_setint(sih, siflag); 1592 else if ((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NAI)) 1593 ai_setint(sih, siflag); 1594 else if (CHIPTYPE(sih->socitype) == SOCI_UBUS) 1595 ub_setint(sih, siflag); 1596 else 1597 ASSERT(0); 1598} 1599 1600uint 1601si_coreid(si_t *sih) 1602{ 1603 si_info_t *sii; 1604 1605 sii = SI_INFO(sih); 1606 return sii->coreid[sii->curidx]; 1607} 1608 1609uint 1610si_coreidx(si_t *sih) 1611{ 1612 si_info_t *sii; 1613 1614 sii = SI_INFO(sih); 1615 return sii->curidx; 1616} 1617 1618/** return the core-type instantiation # of the current core */ 1619uint 1620si_coreunit(si_t *sih) 1621{ 1622 si_info_t *sii; 1623 uint idx; 1624 uint coreid; 1625 uint coreunit; 1626 uint i; 1627 1628 sii = SI_INFO(sih); 1629 coreunit = 0; 1630 1631 idx = sii->curidx; 1632 1633 ASSERT(GOODREGS(sii->curmap)); 1634 coreid = si_coreid(sih); 1635 1636 /* count the cores of our type */ 1637 for (i = 0; i < idx; i++) 1638 if (sii->coreid[i] == coreid) 1639 coreunit++; 1640 1641 return (coreunit); 1642} 1643 1644uint 1645si_corevendor(si_t *sih) 1646{ 1647 if (CHIPTYPE(sih->socitype) == SOCI_SB) 1648 return sb_corevendor(sih); 1649 else if ((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NAI)) 1650 return ai_corevendor(sih); 1651 else if (CHIPTYPE(sih->socitype) == SOCI_UBUS) 1652 return ub_corevendor(sih); 1653 else { 1654 ASSERT(0); 1655 return 0; 1656 } 1657} 1658 1659bool 1660si_backplane64(si_t *sih) 1661{ 1662 return ((sih->cccaps & CC_CAP_BKPLN64) != 0); 1663} 1664 1665uint 1666si_corerev(si_t *sih) 1667{ 1668 if (CHIPTYPE(sih->socitype) == SOCI_SB) 1669 return sb_corerev(sih); 1670 else if ((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NAI)) 1671 return ai_corerev(sih); 1672 else if (CHIPTYPE(sih->socitype) == SOCI_UBUS) 1673 return ub_corerev(sih); 1674 else { 1675 ASSERT(0); 1676 return 0; 1677 } 1678} 1679 1680/** return index of coreid or BADIDX if not found */ 1681uint 1682si_findcoreidx(si_t *sih, uint coreid, uint coreunit) 1683{ 1684 si_info_t *sii; 1685 uint found; 1686 uint i; 1687 1688 sii = SI_INFO(sih); 1689 1690 found = 0; 1691 1692 for (i = 0; i < sii->numcores; i++) 1693 if (sii->coreid[i] == coreid) { 1694 if (found == coreunit) 1695 return (i); 1696 found++; 1697 } 1698 1699 return (BADIDX); 1700} 1701 1702/** return list of found cores */ 1703uint 1704si_corelist(si_t *sih, uint coreid[]) 1705{ 1706 si_info_t *sii; 1707 1708 sii = SI_INFO(sih); 1709 1710 bcopy((uchar*)sii->coreid, (uchar*)coreid, (sii->numcores * sizeof(uint))); 1711 return (sii->numcores); 1712} 1713 1714/** return current wrapper mapping */ 1715void * 1716si_wrapperregs(si_t *sih) 1717{ 1718 si_info_t *sii; 1719 1720 sii = SI_INFO(sih); 1721 ASSERT(GOODREGS(sii->curwrap)); 1722 1723 return (sii->curwrap); 1724} 1725 1726/** return current register mapping */ 1727void * 1728si_coreregs(si_t *sih) 1729{ 1730 si_info_t *sii; 1731 1732 sii = SI_INFO(sih); 1733 ASSERT(GOODREGS(sii->curmap)); 1734 1735 return (sii->curmap); 1736} 1737 1738/** 1739 * This function changes logical "focus" to the indicated core; 1740 * must be called with interrupts off. 1741 * Moreover, callers should keep interrupts off during switching out of and back to d11 core 1742 */ 1743void * 1744si_setcore(si_t *sih, uint coreid, uint coreunit) 1745{ 1746 uint idx; 1747 1748 idx = si_findcoreidx(sih, coreid, coreunit); 1749 if (!GOODIDX(idx)) 1750 return (NULL); 1751 1752 if (CHIPTYPE(sih->socitype) == SOCI_SB) 1753 return sb_setcoreidx(sih, idx); 1754 else if ((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NAI)) 1755 return ai_setcoreidx(sih, idx); 1756 else if (CHIPTYPE(sih->socitype) == SOCI_UBUS) 1757 return ub_setcoreidx(sih, idx); 1758 else { 1759 ASSERT(0); 1760 return NULL; 1761 } 1762} 1763 1764void * 1765si_setcoreidx(si_t *sih, uint coreidx) 1766{ 1767 if (CHIPTYPE(sih->socitype) == SOCI_SB) 1768 return sb_setcoreidx(sih, coreidx); 1769 else if ((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NAI)) 1770 return ai_setcoreidx(sih, coreidx); 1771 else if (CHIPTYPE(sih->socitype) == SOCI_UBUS) 1772 return ub_setcoreidx(sih, coreidx); 1773 else { 1774 ASSERT(0); 1775 return NULL; 1776 } 1777} 1778 1779/** Turn off interrupt as required by sb_setcore, before switch core */ 1780void * 1781si_switch_core(si_t *sih, uint coreid, uint *origidx, uint *intr_val) 1782{ 1783 void *cc; 1784 si_info_t *sii; 1785 1786 sii = SI_INFO(sih); 1787 1788 if (SI_FAST(sii)) { 1789 /* Overloading the origidx variable to remember the coreid, 1790 * this works because the core ids cannot be confused with 1791 * core indices. 1792 */ 1793 *origidx = coreid; 1794 if (coreid == CC_CORE_ID) 1795 return (void *)CCREGS_FAST(sii); 1796 else if (coreid == sih->buscoretype) 1797 return (void *)PCIEREGS(sii); 1798 } 1799 INTR_OFF(sii, *intr_val); 1800 *origidx = sii->curidx; 1801 cc = si_setcore(sih, coreid, 0); 1802 ASSERT(cc != NULL); 1803 1804 return cc; 1805} 1806 1807/* restore coreidx and restore interrupt */ 1808void 1809si_restore_core(si_t *sih, uint coreid, uint intr_val) 1810{ 1811 si_info_t *sii; 1812 1813 sii = SI_INFO(sih); 1814 if (SI_FAST(sii) && ((coreid == CC_CORE_ID) || (coreid == sih->buscoretype))) 1815 return; 1816 1817 si_setcoreidx(sih, coreid); 1818 INTR_RESTORE(sii, intr_val); 1819} 1820 1821int 1822si_numaddrspaces(si_t *sih) 1823{ 1824 if (CHIPTYPE(sih->socitype) == SOCI_SB) 1825 return sb_numaddrspaces(sih); 1826 else if ((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NAI)) 1827 return ai_numaddrspaces(sih); 1828 else if (CHIPTYPE(sih->socitype) == SOCI_UBUS) 1829 return ub_numaddrspaces(sih); 1830 else { 1831 ASSERT(0); 1832 return 0; 1833 } 1834} 1835 1836uint32 1837si_addrspace(si_t *sih, uint asidx) 1838{ 1839 if (CHIPTYPE(sih->socitype) == SOCI_SB) 1840 return sb_addrspace(sih, asidx); 1841 else if ((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NAI)) 1842 return ai_addrspace(sih, asidx); 1843 else if (CHIPTYPE(sih->socitype) == SOCI_UBUS) 1844 return ub_addrspace(sih, asidx); 1845 else { 1846 ASSERT(0); 1847 return 0; 1848 } 1849} 1850 1851uint32 1852si_addrspacesize(si_t *sih, uint asidx) 1853{ 1854 if (CHIPTYPE(sih->socitype) == SOCI_SB) 1855 return sb_addrspacesize(sih, asidx); 1856 else if ((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NAI)) 1857 return ai_addrspacesize(sih, asidx); 1858 else if (CHIPTYPE(sih->socitype) == SOCI_UBUS) 1859 return ub_addrspacesize(sih, asidx); 1860 else { 1861 ASSERT(0); 1862 return 0; 1863 } 1864} 1865 1866void 1867si_coreaddrspaceX(si_t *sih, uint asidx, uint32 *addr, uint32 *size) 1868{ 1869 /* Only supported for SOCI_AI */ 1870 if ((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NAI)) 1871 ai_coreaddrspaceX(sih, asidx, addr, size); 1872 else 1873 *size = 0; 1874} 1875 1876uint32 1877si_core_cflags(si_t *sih, uint32 mask, uint32 val) 1878{ 1879 if (CHIPTYPE(sih->socitype) == SOCI_SB) 1880 return sb_core_cflags(sih, mask, val); 1881 else if ((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NAI)) 1882 return ai_core_cflags(sih, mask, val); 1883 else if (CHIPTYPE(sih->socitype) == SOCI_UBUS) 1884 return ub_core_cflags(sih, mask, val); 1885 else { 1886 ASSERT(0); 1887 return 0; 1888 } 1889} 1890 1891void 1892si_core_cflags_wo(si_t *sih, uint32 mask, uint32 val) 1893{ 1894 if (CHIPTYPE(sih->socitype) == SOCI_SB) 1895 sb_core_cflags_wo(sih, mask, val); 1896 else if ((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NAI)) 1897 ai_core_cflags_wo(sih, mask, val); 1898 else if (CHIPTYPE(sih->socitype) == SOCI_UBUS) 1899 ub_core_cflags_wo(sih, mask, val); 1900 else 1901 ASSERT(0); 1902} 1903 1904uint32 1905si_core_sflags(si_t *sih, uint32 mask, uint32 val) 1906{ 1907 if (CHIPTYPE(sih->socitype) == SOCI_SB) 1908 return sb_core_sflags(sih, mask, val); 1909 else if ((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NAI)) 1910 return ai_core_sflags(sih, mask, val); 1911 else if (CHIPTYPE(sih->socitype) == SOCI_UBUS) 1912 return ub_core_sflags(sih, mask, val); 1913 else { 1914 ASSERT(0); 1915 return 0; 1916 } 1917} 1918 1919bool 1920si_iscoreup(si_t *sih) 1921{ 1922 if (CHIPTYPE(sih->socitype) == SOCI_SB) 1923 return sb_iscoreup(sih); 1924 else if ((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NAI)) 1925 return ai_iscoreup(sih); 1926 else if (CHIPTYPE(sih->socitype) == SOCI_UBUS) 1927 return ub_iscoreup(sih); 1928 else { 1929 ASSERT(0); 1930 return FALSE; 1931 } 1932} 1933 1934uint 1935si_wrapperreg(si_t *sih, uint32 offset, uint32 mask, uint32 val) 1936{ 1937 /* only for AI back plane chips */ 1938 if ((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NAI)) 1939 return (ai_wrap_reg(sih, offset, mask, val)); 1940 return 0; 1941} 1942 1943uint 1944si_corereg(si_t *sih, uint coreidx, uint regoff, uint mask, uint val) 1945{ 1946 if (CHIPTYPE(sih->socitype) == SOCI_SB) 1947 return sb_corereg(sih, coreidx, regoff, mask, val); 1948 else if ((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NAI)) 1949 return ai_corereg(sih, coreidx, regoff, mask, val); 1950 else if (CHIPTYPE(sih->socitype) == SOCI_UBUS) 1951 return ub_corereg(sih, coreidx, regoff, mask, val); 1952 else { 1953 ASSERT(0); 1954 return 0; 1955 } 1956} 1957 1958void 1959si_core_disable(si_t *sih, uint32 bits) 1960{ 1961 if (CHIPTYPE(sih->socitype) == SOCI_SB) 1962 sb_core_disable(sih, bits); 1963 else if ((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NAI)) 1964 ai_core_disable(sih, bits); 1965 else if (CHIPTYPE(sih->socitype) == SOCI_UBUS) 1966 ub_core_disable(sih, bits); 1967} 1968 1969void 1970si_core_reset(si_t *sih, uint32 bits, uint32 resetbits) 1971{ 1972 if (CHIPTYPE(sih->socitype) == SOCI_SB) 1973 sb_core_reset(sih, bits, resetbits); 1974 else if ((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NAI)) 1975 ai_core_reset(sih, bits, resetbits); 1976 else if (CHIPTYPE(sih->socitype) == SOCI_UBUS) 1977 ub_core_reset(sih, bits, resetbits); 1978} 1979 1980/** Run bist on current core. Caller needs to take care of core-specific bist hazards */ 1981int 1982si_corebist(si_t *sih) 1983{ 1984 uint32 cflags; 1985 int result = 0; 1986 1987 /* Read core control flags */ 1988 cflags = si_core_cflags(sih, 0, 0); 1989 1990 /* Set bist & fgc */ 1991 si_core_cflags(sih, ~0, (SICF_BIST_EN | SICF_FGC)); 1992 1993 /* Wait for bist done */ 1994 SPINWAIT(((si_core_sflags(sih, 0, 0) & SISF_BIST_DONE) == 0), 100000); 1995 1996 if (si_core_sflags(sih, 0, 0) & SISF_BIST_ERROR) 1997 result = BCME_ERROR; 1998 1999 /* Reset core control flags */ 2000 si_core_cflags(sih, 0xffff, cflags); 2001 2002 return result; 2003} 2004 2005static uint32 2006BCMINITFN(factor6)(uint32 x) 2007{ 2008 switch (x) { 2009 case CC_F6_2: return 2; 2010 case CC_F6_3: return 3; 2011 case CC_F6_4: return 4; 2012 case CC_F6_5: return 5; 2013 case CC_F6_6: return 6; 2014 case CC_F6_7: return 7; 2015 default: return 0; 2016 } 2017} 2018 2019/** calculate the speed the SI would run at given a set of clockcontrol values */ 2020uint32 2021BCMINITFN(si_clock_rate)(uint32 pll_type, uint32 n, uint32 m) 2022{ 2023 uint32 n1, n2, clock, m1, m2, m3, mc; 2024 2025 n1 = n & CN_N1_MASK; 2026 n2 = (n & CN_N2_MASK) >> CN_N2_SHIFT; 2027 2028 if (pll_type == PLL_TYPE6) { 2029 if (m & CC_T6_MMASK) 2030 return CC_T6_M1; 2031 else 2032 return CC_T6_M0; 2033 } else if ((pll_type == PLL_TYPE1) || 2034 (pll_type == PLL_TYPE3) || 2035 (pll_type == PLL_TYPE4) || 2036 (pll_type == PLL_TYPE7)) { 2037 n1 = factor6(n1); 2038 n2 += CC_F5_BIAS; 2039 } else if (pll_type == PLL_TYPE2) { 2040 n1 += CC_T2_BIAS; 2041 n2 += CC_T2_BIAS; 2042 ASSERT((n1 >= 2) && (n1 <= 7)); 2043 ASSERT((n2 >= 5) && (n2 <= 23)); 2044 } else if (pll_type == PLL_TYPE5) { 2045 return (100000000); 2046 } else 2047 ASSERT(0); 2048 /* PLL types 3 and 7 use BASE2 (25Mhz) */ 2049 if ((pll_type == PLL_TYPE3) || 2050 (pll_type == PLL_TYPE7)) { 2051 clock = CC_CLOCK_BASE2 * n1 * n2; 2052 } else 2053 clock = CC_CLOCK_BASE1 * n1 * n2; 2054 2055 if (clock == 0) 2056 return 0; 2057 2058 m1 = m & CC_M1_MASK; 2059 m2 = (m & CC_M2_MASK) >> CC_M2_SHIFT; 2060 m3 = (m & CC_M3_MASK) >> CC_M3_SHIFT; 2061 mc = (m & CC_MC_MASK) >> CC_MC_SHIFT; 2062 2063 if ((pll_type == PLL_TYPE1) || 2064 (pll_type == PLL_TYPE3) || 2065 (pll_type == PLL_TYPE4) || 2066 (pll_type == PLL_TYPE7)) { 2067 m1 = factor6(m1); 2068 if ((pll_type == PLL_TYPE1) || (pll_type == PLL_TYPE3)) 2069 m2 += CC_F5_BIAS; 2070 else 2071 m2 = factor6(m2); 2072 m3 = factor6(m3); 2073 2074 switch (mc) { 2075 case CC_MC_BYPASS: return (clock); 2076 case CC_MC_M1: return (clock / m1); 2077 case CC_MC_M1M2: return (clock / (m1 * m2)); 2078 case CC_MC_M1M2M3: return (clock / (m1 * m2 * m3)); 2079 case CC_MC_M1M3: return (clock / (m1 * m3)); 2080 default: return (0); 2081 } 2082 } else { 2083 ASSERT(pll_type == PLL_TYPE2); 2084 2085 m1 += CC_T2_BIAS; 2086 m2 += CC_T2M2_BIAS; 2087 m3 += CC_T2_BIAS; 2088 ASSERT((m1 >= 2) && (m1 <= 7)); 2089 ASSERT((m2 >= 3) && (m2 <= 10)); 2090 ASSERT((m3 >= 2) && (m3 <= 7)); 2091 2092 if ((mc & CC_T2MC_M1BYP) == 0) 2093 clock /= m1; 2094 if ((mc & CC_T2MC_M2BYP) == 0) 2095 clock /= m2; 2096 if ((mc & CC_T2MC_M3BYP) == 0) 2097 clock /= m3; 2098 2099 return (clock); 2100 } 2101} 2102 2103/* Some chips could have multiple host interfaces, however only one will be active. 2104 * For a given chip. Depending pkgopt and cc_chipst return the active host interface. 2105 */ 2106uint 2107si_chip_hostif(si_t *sih) 2108{ 2109 uint hosti = 0; 2110 2111 switch (CHIPID(sih->chip)) { 2112 case BCM4360_CHIP_ID: 2113 case BCM43460_CHIP_ID: 2114 case BCM43526_CHIP_ID: 2115 /* chippkg bit-0 == 0 is PCIE only pkgs 2116 * chippkg bit-0 == 1 has both PCIE and USB cores enabled 2117 */ 2118 if ((sih->chippkg & 0x1) && (sih->chipst & CST4360_MODE_USB)) 2119 hosti = CHIP_HOSTIF_USBMODE; 2120 else 2121 hosti = CHIP_HOSTIF_PCIEMODE; 2122 2123 break; 2124 2125 case BCM4335_CHIP_ID: 2126 /* TBD: like in 4360, do we need to check pkg? */ 2127 if (CST4335_CHIPMODE_USB20D(sih->chipst)) 2128 hosti = CHIP_HOSTIF_USBMODE; 2129 else if (CST4335_CHIPMODE_SDIOD(sih->chipst)) 2130 hosti = CHIP_HOSTIF_SDIOMODE; 2131 else if (CST4335_CHIPMODE_PCIE(sih->chipst)) 2132 hosti = CHIP_HOSTIF_PCIEMODE; 2133 break; 2134 2135 2136 default: 2137 break; 2138 } 2139 2140 return hosti; 2141} 2142 2143bool si_read_pmu_autopll(si_t *sih) 2144{ 2145 si_info_t *sii; 2146 sii = SI_INFO(sih); 2147 return (si_pmu_is_autoresetphyclk_disabled(sih, sii->osh)); 2148} 2149 2150uint32 2151BCMINITFN(si_clock)(si_t *sih) 2152{ 2153 si_info_t *sii; 2154 chipcregs_t *cc; 2155 uint32 n, m; 2156 uint idx; 2157 uint32 pll_type, rate; 2158 uint intr_val = 0; 2159 2160 if (BCM4707_CHIP(CHIPID(sih->chip))) { 2161 if (sih->chippkg == BCM4709_PKG_ID) { 2162 return NS_SI_CLOCK; 2163 } else 2164 return NS_SLOW_SI_CLOCK; 2165 } 2166 2167 sii = SI_INFO(sih); 2168 INTR_OFF(sii, intr_val); 2169 if (PMUCTL_ENAB(sih)) { 2170 rate = si_pmu_si_clock(sih, sii->osh); 2171 goto exit; 2172 } 2173 2174 idx = sii->curidx; 2175 cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0); 2176 ASSERT(cc != NULL); 2177 2178 n = R_REG(sii->osh, &cc->clockcontrol_n); 2179 pll_type = sih->cccaps & CC_CAP_PLL_MASK; 2180 if (pll_type == PLL_TYPE6) 2181 m = R_REG(sii->osh, &cc->clockcontrol_m3); 2182 else if (pll_type == PLL_TYPE3) 2183 m = R_REG(sii->osh, &cc->clockcontrol_m2); 2184 else 2185 m = R_REG(sii->osh, &cc->clockcontrol_sb); 2186 2187 /* calculate rate */ 2188 rate = si_clock_rate(pll_type, n, m); 2189 2190 if (pll_type == PLL_TYPE3) 2191 rate = rate / 2; 2192 2193 /* switch back to previous core */ 2194 si_setcoreidx(sih, idx); 2195exit: 2196 INTR_RESTORE(sii, intr_val); 2197 2198 return rate; 2199} 2200 2201/** returns value in [Hz] units */ 2202static uint32 2203BCMINITFN(si_ns_alp_clock)(si_t *sih) 2204{ 2205 osl_t *osh; 2206 uint32 *genpll_base; 2207 uint32 val; 2208 uint32 pdiv, ndiv_int, mdiv, clkrate; 2209 2210 osh = si_osh(sih); 2211 2212 /* reg map for genpll base address */ 2213 genpll_base = (uint32 *)REG_MAP(0x1800C140, 4096); 2214 2215 /* get divider integer from the cru_genpll_control5 */ 2216 val = R_REG(osh, (genpll_base + 0x5)); 2217 ndiv_int = (val >> 20) & 0x3ff; 2218 if (ndiv_int == 0) 2219 ndiv_int = 1 << 10; 2220 2221 /* get pdiv from the cru_genpll_control6 */ 2222 val = R_REG(osh, (genpll_base + 0x6)); 2223 pdiv = (val >> 24) & 0x7; 2224 if (pdiv == 0) 2225 pdiv = 1 << 3; 2226 2227 /* get mdiv from the cru_genpll_control7 */ 2228 val = R_REG(osh, (genpll_base + 0x7)); 2229 mdiv = val & 0xff; 2230 if (mdiv == 0) 2231 mdiv = 1 << 8; 2232 2233 /* caculate clock rate based on 25MHz reference clock */ 2234 clkrate = (25000000 / (pdiv * mdiv)) * ndiv_int; 2235 2236 /* round to the nearest Hz */ 2237 clkrate = ((clkrate + 500000) / 1000000) * 1000000; 2238 2239 /* reg unmap */ 2240 REG_UNMAP((void *)genpll_base); 2241 2242 return clkrate; 2243} 2244 2245uint32 2246BCMINITFN(si_alp_clock)(si_t *sih) 2247{ 2248 if (PMUCTL_ENAB(sih)) 2249 return si_pmu_alp_clock(sih, si_osh(sih)); 2250 else if (BCM4707_CHIP(CHIPID(sih->chip))) 2251 return si_ns_alp_clock(sih); 2252 2253 return ALP_CLOCK; 2254} 2255 2256uint32 2257BCMINITFN(si_ilp_clock)(si_t *sih) 2258{ 2259 if (PMUCTL_ENAB(sih)) 2260 return si_pmu_ilp_clock(sih, si_osh(sih)); 2261 2262 return ILP_CLOCK; 2263} 2264 2265/** set chip watchdog reset timer to fire in 'ticks' */ 2266void 2267si_watchdog(si_t *sih, uint ticks) 2268{ 2269 uint nb, maxt; 2270 2271 if (PMUCTL_ENAB(sih)) { 2272 2273#if (!defined(_CFE_) && !defined(_CFEZ_)) || defined(CFG_WL) 2274 if ((CHIPID(sih->chip) == BCM4319_CHIP_ID) && 2275 (CHIPREV(sih->chiprev) == 0) && (ticks != 0)) { 2276 si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, clk_ctl_st), ~0, 0x2); 2277 si_setcore(sih, USB20D_CORE_ID, 0); 2278 si_core_disable(sih, 1); 2279 si_setcore(sih, CC_CORE_ID, 0); 2280 } 2281#endif /* (!_CFE_ && !_CFEZ_) || CFG_WL */ 2282 2283 if (CHIPID(sih->chip) == BCM4706_CHIP_ID) 2284 nb = 32; 2285 else 2286 nb = (sih->ccrev < 26) ? 16 : ((sih->ccrev >= 37) ? 32 : 24); 2287 /* The mips compiler uses the sllv instruction, 2288 * so we specially handle the 32-bit case. 2289 */ 2290 if (nb == 32) 2291 maxt = 0xffffffff; 2292 else 2293 maxt = ((1 << nb) - 1); 2294 2295 if (ticks == 1) 2296 ticks = 2; 2297 else if (ticks > maxt) 2298 ticks = maxt; 2299 2300 si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, pmuwatchdog), ~0, ticks); 2301 } else { 2302 if (!BCM4707_CHIP(CHIPID(sih->chip))) { 2303 /* make sure we come up in fast clock mode; or if clearing, clear clock */ 2304 si_clkctl_cc(sih, ticks ? CLK_FAST : CLK_DYNAMIC); 2305 } 2306 maxt = (1 << 28) - 1; 2307 if (ticks > maxt) 2308 ticks = maxt; 2309 2310 si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, watchdog), ~0, ticks); 2311 } 2312} 2313 2314/** trigger watchdog reset after ms milliseconds */ 2315void 2316si_watchdog_ms(si_t *sih, uint32 ms) 2317{ 2318 si_watchdog(sih, wd_msticks * ms); 2319} 2320 2321uint32 2322si_watchdog_msticks(void) 2323{ 2324 return wd_msticks; 2325} 2326 2327bool 2328si_taclear(si_t *sih, bool details) 2329{ 2330#if defined(BCMDBG_ERR) || defined(BCMASSERT_SUPPORT) 2331 if (CHIPTYPE(sih->socitype) == SOCI_SB) 2332 return sb_taclear(sih, details); 2333 else if ((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NAI)) 2334 return FALSE; 2335 else if (CHIPTYPE(sih->socitype) == SOCI_UBUS) 2336 return FALSE; 2337 else { 2338 ASSERT(0); 2339 return FALSE; 2340 } 2341#else 2342 return FALSE; 2343#endif 2344} 2345 2346uint16 2347BCMATTACHFN(si_d11_devid)(si_t *sih) 2348{ 2349 si_info_t *sii = SI_INFO(sih); 2350 uint16 device; 2351 2352 /* Fix device id for dual band BCM4328 */ 2353 if (CHIPID(sih->chip) == BCM4328_CHIP_ID && 2354 (sih->chippkg == BCM4328USBDUAL_PKG_ID || sih->chippkg == BCM4328SDIODUAL_PKG_ID)) { 2355 device = BCM4328_D11DUAL_ID; 2356 } 2357#ifdef BCMPCIDEV 2358 else if (CHIPID(sih->chip) == BCM4352_CHIP_ID) { 2359 device = BCM4352_D11AC_ID; 2360 } else if (CHIPID(sih->chip) == BCM4360_CHIP_ID) { 2361 device = BCM4360_D11AC_ID; 2362 } else if (CHIPID(sih->chip) == BCM4350_CHIP_ID) { 2363 device = BCM4350_D11AC_ID; 2364 } 2365#endif 2366 else { 2367 /* normal case: nvram variable with devpath->devid->wl0id */ 2368 if ((device = (uint16)si_getdevpathintvar(sih, "devid")) != 0) 2369 ; 2370 /* Get devid from OTP/SPROM depending on where the SROM is read */ 2371 else if ((device = (uint16)getintvar(sii->vars, "devid")) != 0) 2372 ; 2373 /* no longer support wl0id, but keep the code here for backward compatibility. */ 2374 else if ((device = (uint16)getintvar(sii->vars, "wl0id")) != 0) 2375 ; 2376 else if (CHIPID(sih->chip) == BCM4712_CHIP_ID) { 2377 /* Chip specific conversion */ 2378 if (sih->chippkg == BCM4712SMALL_PKG_ID) 2379 device = BCM4306_D11G_ID; 2380 else 2381 device = BCM4306_D11DUAL_ID; 2382 } else { 2383 /* ignore it */ 2384 device = 0xffff; 2385 } 2386 } 2387 return device; 2388} 2389 2390int 2391BCMATTACHFN(si_corepciid)(si_t *sih, uint func, uint16 *pcivendor, uint16 *pcidevice, 2392 uint8 *pciclass, uint8 *pcisubclass, uint8 *pciprogif, 2393 uint8 *pciheader) 2394{ 2395 uint16 vendor = 0xffff, device = 0xffff; 2396 uint8 class, subclass, progif = 0; 2397 uint8 header = PCI_HEADER_NORMAL; 2398 uint32 core = si_coreid(sih); 2399 2400 /* Verify whether the function exists for the core */ 2401 if (func >= (uint)((core == USB20H_CORE_ID) || (core == NS_USB20_CORE_ID) ? 2 : 1)) 2402 return BCME_ERROR; 2403 2404 /* Known vendor translations */ 2405 switch (si_corevendor(sih)) { 2406 case SB_VEND_BCM: 2407 case MFGID_BRCM: 2408 vendor = VENDOR_BROADCOM; 2409 break; 2410 default: 2411 return BCME_ERROR; 2412 } 2413 2414 /* Determine class based on known core codes */ 2415 switch (core) { 2416 case ENET_CORE_ID: 2417 class = PCI_CLASS_NET; 2418 subclass = PCI_NET_ETHER; 2419 device = BCM47XX_ENET_ID; 2420 break; 2421 case GIGETH_CORE_ID: 2422 class = PCI_CLASS_NET; 2423 subclass = PCI_NET_ETHER; 2424 device = BCM47XX_GIGETH_ID; 2425 break; 2426 case GMAC_CORE_ID: 2427 class = PCI_CLASS_NET; 2428 subclass = PCI_NET_ETHER; 2429 device = BCM47XX_GMAC_ID; 2430 break; 2431 case SDRAM_CORE_ID: 2432 case MEMC_CORE_ID: 2433 case DMEMC_CORE_ID: 2434 case SOCRAM_CORE_ID: 2435 class = PCI_CLASS_MEMORY; 2436 subclass = PCI_MEMORY_RAM; 2437 device = (uint16)core; 2438 break; 2439 case PCI_CORE_ID: 2440 case PCIE_CORE_ID: 2441 case PCIE2_CORE_ID: 2442 class = PCI_CLASS_BRIDGE; 2443 subclass = PCI_BRIDGE_PCI; 2444 device = (uint16)core; 2445 header = PCI_HEADER_BRIDGE; 2446 break; 2447 case MIPS33_CORE_ID: 2448 case MIPS74K_CORE_ID: 2449 class = PCI_CLASS_CPU; 2450 subclass = PCI_CPU_MIPS; 2451 device = (uint16)core; 2452 break; 2453 case CODEC_CORE_ID: 2454 class = PCI_CLASS_COMM; 2455 subclass = PCI_COMM_MODEM; 2456 device = BCM47XX_V90_ID; 2457 break; 2458 case I2S_CORE_ID: 2459 class = PCI_CLASS_MMEDIA; 2460 subclass = PCI_MMEDIA_AUDIO; 2461 device = BCM47XX_AUDIO_ID; 2462 break; 2463 case USB_CORE_ID: 2464 case USB11H_CORE_ID: 2465 class = PCI_CLASS_SERIAL; 2466 subclass = PCI_SERIAL_USB; 2467 progif = 0x10; /* OHCI */ 2468 device = BCM47XX_USBH_ID; 2469 break; 2470 case USB20H_CORE_ID: 2471 case NS_USB20_CORE_ID: 2472 class = PCI_CLASS_SERIAL; 2473 subclass = PCI_SERIAL_USB; 2474 progif = func == 0 ? 0x10 : 0x20; /* OHCI/EHCI value defined in spec */ 2475 device = BCM47XX_USB20H_ID; 2476 header = PCI_HEADER_MULTI; /* multifunction */ 2477 break; 2478 case IPSEC_CORE_ID: 2479 class = PCI_CLASS_CRYPT; 2480 subclass = PCI_CRYPT_NETWORK; 2481 device = BCM47XX_IPSEC_ID; 2482 break; 2483 case NS_USB30_CORE_ID: 2484 class = PCI_CLASS_SERIAL; 2485 subclass = PCI_SERIAL_USB; 2486 progif = 0x30; /* XHCI */ 2487 device = BCM47XX_USB30H_ID; 2488 break; 2489 case ROBO_CORE_ID: 2490 /* Don't use class NETWORK, so wl/et won't attempt to recognize it */ 2491 class = PCI_CLASS_COMM; 2492 subclass = PCI_COMM_OTHER; 2493 device = BCM47XX_ROBO_ID; 2494 break; 2495 case CC_CORE_ID: 2496 class = PCI_CLASS_MEMORY; 2497 subclass = PCI_MEMORY_FLASH; 2498 device = (uint16)core; 2499 break; 2500 case SATAXOR_CORE_ID: 2501 class = PCI_CLASS_XOR; 2502 subclass = PCI_XOR_QDMA; 2503 device = BCM47XX_SATAXOR_ID; 2504 break; 2505 case ATA100_CORE_ID: 2506 class = PCI_CLASS_DASDI; 2507 subclass = PCI_DASDI_IDE; 2508 device = BCM47XX_ATA100_ID; 2509 break; 2510 case USB11D_CORE_ID: 2511 class = PCI_CLASS_SERIAL; 2512 subclass = PCI_SERIAL_USB; 2513 device = BCM47XX_USBD_ID; 2514 break; 2515 case USB20D_CORE_ID: 2516 class = PCI_CLASS_SERIAL; 2517 subclass = PCI_SERIAL_USB; 2518 device = BCM47XX_USB20D_ID; 2519 break; 2520 case D11_CORE_ID: 2521 class = PCI_CLASS_NET; 2522 subclass = PCI_NET_OTHER; 2523 device = si_d11_devid(sih); 2524 break; 2525 2526 default: 2527 class = subclass = progif = 0xff; 2528 device = (uint16)core; 2529 break; 2530 } 2531 2532 *pcivendor = vendor; 2533 *pcidevice = device; 2534 *pciclass = class; 2535 *pcisubclass = subclass; 2536 *pciprogif = progif; 2537 *pciheader = header; 2538 2539 return 0; 2540} 2541 2542#if defined(BCMDBG) 2543/** print interesting sbconfig registers */ 2544void 2545si_dumpregs(si_t *sih, struct bcmstrbuf *b) 2546{ 2547 si_info_t *sii; 2548 uint origidx, intr_val = 0; 2549 2550 sii = SI_INFO(sih); 2551 origidx = sii->curidx; 2552 2553 INTR_OFF(sii, intr_val); 2554 if (CHIPTYPE(sih->socitype) == SOCI_SB) 2555 sb_dumpregs(sih, b); 2556 else if ((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NAI)) 2557 ai_dumpregs(sih, b); 2558 else if (CHIPTYPE(sih->socitype) == SOCI_UBUS) 2559 ub_dumpregs(sih, b); 2560 else 2561 ASSERT(0); 2562 2563 si_setcoreidx(sih, origidx); 2564 INTR_RESTORE(sii, intr_val); 2565} 2566#endif 2567 2568#ifdef BCMDBG 2569void 2570si_view(si_t *sih, bool verbose) 2571{ 2572 if (CHIPTYPE(sih->socitype) == SOCI_SB) 2573 sb_view(sih, verbose); 2574 else if ((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NAI)) 2575 ai_view(sih, verbose); 2576 else if (CHIPTYPE(sih->socitype) == SOCI_UBUS) 2577 ub_view(sih, verbose); 2578 else 2579 ASSERT(0); 2580} 2581 2582void 2583si_viewall(si_t *sih, bool verbose) 2584{ 2585 si_info_t *sii; 2586 uint curidx, i; 2587 uint intr_val = 0; 2588 2589 sii = SI_INFO(sih); 2590 curidx = sii->curidx; 2591 2592 INTR_OFF(sii, intr_val); 2593 if ((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NAI)) 2594 ai_viewall(sih, verbose); 2595 else { 2596 SI_ERROR(("si_viewall: num_cores %d\n", sii->numcores)); 2597 for (i = 0; i < sii->numcores; i++) { 2598 si_setcoreidx(sih, i); 2599 si_view(sih, verbose); 2600 } 2601 } 2602 si_setcoreidx(sih, curidx); 2603 INTR_RESTORE(sii, intr_val); 2604} 2605#endif /* BCMDBG */ 2606 2607/** return the slow clock source - LPO, XTAL, or PCI */ 2608static uint 2609si_slowclk_src(si_info_t *sii) 2610{ 2611 chipcregs_t *cc; 2612 2613 ASSERT(SI_FAST(sii) || si_coreid(&sii->pub) == CC_CORE_ID); 2614 2615 if (sii->pub.ccrev < 6) { 2616 if ((BUSTYPE(sii->pub.bustype) == PCI_BUS) && 2617 (OSL_PCI_READ_CONFIG(sii->osh, PCI_GPIO_OUT, sizeof(uint32)) & 2618 PCI_CFG_GPIO_SCS)) 2619 return (SCC_SS_PCI); 2620 else 2621 return (SCC_SS_XTAL); 2622 } else if (sii->pub.ccrev < 10) { 2623 cc = (chipcregs_t *)si_setcoreidx(&sii->pub, sii->curidx); 2624 return (R_REG(sii->osh, &cc->slow_clk_ctl) & SCC_SS_MASK); 2625 } else /* Insta-clock */ 2626 return (SCC_SS_XTAL); 2627} 2628 2629/** return the ILP (slowclock) min or max frequency */ 2630static uint 2631si_slowclk_freq(si_info_t *sii, bool max_freq, chipcregs_t *cc) 2632{ 2633 uint32 slowclk; 2634 uint div; 2635 2636 ASSERT(SI_FAST(sii) || si_coreid(&sii->pub) == CC_CORE_ID); 2637 2638 /* shouldn't be here unless we've established the chip has dynamic clk control */ 2639 ASSERT(R_REG(sii->osh, &cc->capabilities) & CC_CAP_PWR_CTL); 2640 2641 slowclk = si_slowclk_src(sii); 2642 if (sii->pub.ccrev < 6) { 2643 if (slowclk == SCC_SS_PCI) 2644 return (max_freq ? (PCIMAXFREQ / 64) : (PCIMINFREQ / 64)); 2645 else 2646 return (max_freq ? (XTALMAXFREQ / 32) : (XTALMINFREQ / 32)); 2647 } else if (sii->pub.ccrev < 10) { 2648 div = 4 * 2649 (((R_REG(sii->osh, &cc->slow_clk_ctl) & SCC_CD_MASK) >> SCC_CD_SHIFT) + 1); 2650 if (slowclk == SCC_SS_LPO) 2651 return (max_freq ? LPOMAXFREQ : LPOMINFREQ); 2652 else if (slowclk == SCC_SS_XTAL) 2653 return (max_freq ? (XTALMAXFREQ / div) : (XTALMINFREQ / div)); 2654 else if (slowclk == SCC_SS_PCI) 2655 return (max_freq ? (PCIMAXFREQ / div) : (PCIMINFREQ / div)); 2656 else 2657 ASSERT(0); 2658 } else { 2659 /* Chipc rev 10 is InstaClock */ 2660 div = R_REG(sii->osh, &cc->system_clk_ctl) >> SYCC_CD_SHIFT; 2661 div = 4 * (div + 1); 2662 return (max_freq ? XTALMAXFREQ : (XTALMINFREQ / div)); 2663 } 2664 return (0); 2665} 2666 2667static void 2668BCMINITFN(si_clkctl_setdelay)(si_info_t *sii, void *chipcregs) 2669{ 2670 chipcregs_t *cc = (chipcregs_t *)chipcregs; 2671 uint slowmaxfreq, pll_delay, slowclk; 2672 uint pll_on_delay, fref_sel_delay; 2673 2674 pll_delay = PLL_DELAY; 2675 2676 /* If the slow clock is not sourced by the xtal then add the xtal_on_delay 2677 * since the xtal will also be powered down by dynamic clk control logic. 2678 */ 2679 2680 slowclk = si_slowclk_src(sii); 2681 if (slowclk != SCC_SS_XTAL) 2682 pll_delay += XTAL_ON_DELAY; 2683 2684 /* Starting with 4318 it is ILP that is used for the delays */ 2685 slowmaxfreq = si_slowclk_freq(sii, (sii->pub.ccrev >= 10) ? FALSE : TRUE, cc); 2686 2687 pll_on_delay = ((slowmaxfreq * pll_delay) + 999999) / 1000000; 2688 fref_sel_delay = ((slowmaxfreq * FREF_DELAY) + 999999) / 1000000; 2689 2690 W_REG(sii->osh, &cc->pll_on_delay, pll_on_delay); 2691 W_REG(sii->osh, &cc->fref_sel_delay, fref_sel_delay); 2692} 2693 2694/** initialize power control delay registers */ 2695void 2696BCMINITFN(si_clkctl_init)(si_t *sih) 2697{ 2698 si_info_t *sii; 2699 uint origidx = 0; 2700 chipcregs_t *cc; 2701 bool fast; 2702 2703 if (!CCCTL_ENAB(sih)) 2704 return; 2705 2706 sii = SI_INFO(sih); 2707 fast = SI_FAST(sii); 2708 if (!fast) { 2709 origidx = sii->curidx; 2710 if ((cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0)) == NULL) 2711 return; 2712 } else if ((cc = (chipcregs_t *)CCREGS_FAST(sii)) == NULL) 2713 return; 2714 ASSERT(cc != NULL); 2715 2716 /* set all Instaclk chip ILP to 1 MHz */ 2717 if (sih->ccrev >= 10) 2718 SET_REG(sii->osh, &cc->system_clk_ctl, SYCC_CD_MASK, 2719 (ILP_DIV_1MHZ << SYCC_CD_SHIFT)); 2720 2721 si_clkctl_setdelay(sii, (void *)(uintptr)cc); 2722 2723 OSL_DELAY(20000); 2724 2725 if (!fast) 2726 si_setcoreidx(sih, origidx); 2727} 2728 2729/** return the value suitable for writing to the dot11 core FAST_PWRUP_DELAY register */ 2730uint16 2731BCMINITFN(si_clkctl_fast_pwrup_delay)(si_t *sih) 2732{ 2733 si_info_t *sii; 2734 uint origidx = 0; 2735 chipcregs_t *cc; 2736 uint slowminfreq; 2737 uint16 fpdelay; 2738 uint intr_val = 0; 2739 bool fast; 2740 2741 sii = SI_INFO(sih); 2742 if (PMUCTL_ENAB(sih)) { 2743 INTR_OFF(sii, intr_val); 2744 fpdelay = si_pmu_fast_pwrup_delay(sih, sii->osh); 2745 INTR_RESTORE(sii, intr_val); 2746 return fpdelay; 2747 } 2748 2749 if (!CCCTL_ENAB(sih)) 2750 return 0; 2751 2752 fast = SI_FAST(sii); 2753 fpdelay = 0; 2754 if (!fast) { 2755 origidx = sii->curidx; 2756 INTR_OFF(sii, intr_val); 2757 if ((cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0)) == NULL) 2758 goto done; 2759 } 2760 else if ((cc = (chipcregs_t *)CCREGS_FAST(sii)) == NULL) 2761 goto done; 2762 ASSERT(cc != NULL); 2763 2764 slowminfreq = si_slowclk_freq(sii, FALSE, cc); 2765 fpdelay = (((R_REG(sii->osh, &cc->pll_on_delay) + 2) * 1000000) + 2766 (slowminfreq - 1)) / slowminfreq; 2767 2768done: 2769 if (!fast) { 2770 si_setcoreidx(sih, origidx); 2771 INTR_RESTORE(sii, intr_val); 2772 } 2773 return fpdelay; 2774} 2775 2776/** turn primary xtal and/or pll off/on */ 2777int 2778si_clkctl_xtal(si_t *sih, uint what, bool on) 2779{ 2780 si_info_t *sii; 2781 uint32 in, out, outen; 2782 2783 sii = SI_INFO(sih); 2784 2785 switch (BUSTYPE(sih->bustype)) { 2786 2787 2788 case PCMCIA_BUS: 2789 return (0); 2790 2791 2792 case PCI_BUS: 2793 /* pcie core doesn't have any mapping to control the xtal pu */ 2794 if (PCIE(sii)) 2795 return -1; 2796 2797 in = OSL_PCI_READ_CONFIG(sii->osh, PCI_GPIO_IN, sizeof(uint32)); 2798 out = OSL_PCI_READ_CONFIG(sii->osh, PCI_GPIO_OUT, sizeof(uint32)); 2799 outen = OSL_PCI_READ_CONFIG(sii->osh, PCI_GPIO_OUTEN, sizeof(uint32)); 2800 2801 /* 2802 * Avoid glitching the clock if GPRS is already using it. 2803 * We can't actually read the state of the PLLPD so we infer it 2804 * by the value of XTAL_PU which *is* readable via gpioin. 2805 */ 2806 if (on && (in & PCI_CFG_GPIO_XTAL)) 2807 return (0); 2808 2809 if (what & XTAL) 2810 outen |= PCI_CFG_GPIO_XTAL; 2811 if (what & PLL) 2812 outen |= PCI_CFG_GPIO_PLL; 2813 2814 if (on) { 2815 /* turn primary xtal on */ 2816 if (what & XTAL) { 2817 out |= PCI_CFG_GPIO_XTAL; 2818 if (what & PLL) 2819 out |= PCI_CFG_GPIO_PLL; 2820 OSL_PCI_WRITE_CONFIG(sii->osh, PCI_GPIO_OUT, 2821 sizeof(uint32), out); 2822 OSL_PCI_WRITE_CONFIG(sii->osh, PCI_GPIO_OUTEN, 2823 sizeof(uint32), outen); 2824 OSL_DELAY(XTAL_ON_DELAY); 2825 } 2826 2827 /* turn pll on */ 2828 if (what & PLL) { 2829 out &= ~PCI_CFG_GPIO_PLL; 2830 OSL_PCI_WRITE_CONFIG(sii->osh, PCI_GPIO_OUT, 2831 sizeof(uint32), out); 2832 OSL_DELAY(2000); 2833 } 2834 } else { 2835 if (what & XTAL) 2836 out &= ~PCI_CFG_GPIO_XTAL; 2837 if (what & PLL) 2838 out |= PCI_CFG_GPIO_PLL; 2839 OSL_PCI_WRITE_CONFIG(sii->osh, PCI_GPIO_OUT, sizeof(uint32), out); 2840 OSL_PCI_WRITE_CONFIG(sii->osh, PCI_GPIO_OUTEN, sizeof(uint32), 2841 outen); 2842 } 2843 return 0; 2844 2845 default: 2846 return (-1); 2847 } 2848 2849 return (0); 2850} 2851 2852/** 2853 * clock control policy function throught chipcommon 2854 * 2855 * set dynamic clk control mode (forceslow, forcefast, dynamic) 2856 * returns true if we are forcing fast clock 2857 * this is a wrapper over the next internal function 2858 * to allow flexible policy settings for outside caller 2859 */ 2860bool 2861si_clkctl_cc(si_t *sih, uint mode) 2862{ 2863 si_info_t *sii; 2864 2865 sii = SI_INFO(sih); 2866 2867 /* chipcommon cores prior to rev6 don't support dynamic clock control */ 2868 if (sih->ccrev < 6) 2869 return FALSE; 2870 2871 if (PCI_FORCEHT(sii)) 2872 return (mode == CLK_FAST); 2873 2874 return _si_clkctl_cc(sii, mode); 2875} 2876 2877/* clk control mechanism through chipcommon, no policy checking */ 2878static bool 2879_si_clkctl_cc(si_info_t *sii, uint mode) 2880{ 2881 uint origidx = 0; 2882 chipcregs_t *cc; 2883 uint32 scc; 2884 uint intr_val = 0; 2885 bool fast = SI_FAST(sii); 2886 2887 /* chipcommon cores prior to rev6 don't support dynamic clock control */ 2888 if (sii->pub.ccrev < 6) 2889 return (FALSE); 2890 2891 /* Chips with ccrev 10 are EOL and they don't have SYCC_HR which we use below */ 2892 ASSERT(sii->pub.ccrev != 10); 2893 2894 if (!fast) { 2895 INTR_OFF(sii, intr_val); 2896 origidx = sii->curidx; 2897 2898 if ((BUSTYPE(sii->pub.bustype) == SI_BUS) && 2899 si_setcore(&sii->pub, MIPS33_CORE_ID, 0) && 2900 (si_corerev(&sii->pub) <= 7) && (sii->pub.ccrev >= 10)) 2901 goto done; 2902 2903 cc = (chipcregs_t *) si_setcore(&sii->pub, CC_CORE_ID, 0); 2904 } else if ((cc = (chipcregs_t *) CCREGS_FAST(sii)) == NULL) 2905 goto done; 2906 ASSERT(cc != NULL); 2907 2908 if (!CCCTL_ENAB(&sii->pub) && (sii->pub.ccrev < 20)) 2909 goto done; 2910 2911 switch (mode) { 2912 case CLK_FAST: /* FORCEHT, fast (pll) clock */ 2913 if (sii->pub.ccrev < 10) { 2914 /* don't forget to force xtal back on before we clear SCC_DYN_XTAL.. */ 2915 si_clkctl_xtal(&sii->pub, XTAL, ON); 2916 SET_REG(sii->osh, &cc->slow_clk_ctl, (SCC_XC | SCC_FS | SCC_IP), SCC_IP); 2917 } else if (sii->pub.ccrev < 20) { 2918 OR_REG(sii->osh, &cc->system_clk_ctl, SYCC_HR); 2919 } else { 2920 OR_REG(sii->osh, &cc->clk_ctl_st, CCS_FORCEHT); 2921 } 2922 2923 /* wait for the PLL */ 2924 if (PMUCTL_ENAB(&sii->pub)) { 2925 uint32 htavail = CCS_HTAVAIL; 2926 if (CHIPID(sii->pub.chip) == BCM4328_CHIP_ID) 2927 htavail = CCS0_HTAVAIL; 2928 SPINWAIT(((R_REG(sii->osh, &cc->clk_ctl_st) & htavail) == 0), 2929 PMU_MAX_TRANSITION_DLY); 2930 ASSERT(R_REG(sii->osh, &cc->clk_ctl_st) & htavail); 2931 } else { 2932 OSL_DELAY(PLL_DELAY); 2933 } 2934 break; 2935 2936 case CLK_DYNAMIC: /* enable dynamic clock control */ 2937 if (sii->pub.ccrev < 10) { 2938 scc = R_REG(sii->osh, &cc->slow_clk_ctl); 2939 scc &= ~(SCC_FS | SCC_IP | SCC_XC); 2940 if ((scc & SCC_SS_MASK) != SCC_SS_XTAL) 2941 scc |= SCC_XC; 2942 W_REG(sii->osh, &cc->slow_clk_ctl, scc); 2943 2944 /* for dynamic control, we have to release our xtal_pu "force on" */ 2945 if (scc & SCC_XC) 2946 si_clkctl_xtal(&sii->pub, XTAL, OFF); 2947 } else if (sii->pub.ccrev < 20) { 2948 /* Instaclock */ 2949 AND_REG(sii->osh, &cc->system_clk_ctl, ~SYCC_HR); 2950 } else { 2951 AND_REG(sii->osh, &cc->clk_ctl_st, ~CCS_FORCEHT); 2952 } 2953 2954 /* wait for the PLL */ 2955 if (PMUCTL_ENAB(&sii->pub)) { 2956 uint32 htavail = CCS_HTAVAIL; 2957 if (CHIPID(sii->pub.chip) == BCM4328_CHIP_ID) 2958 htavail = CCS0_HTAVAIL; 2959 SPINWAIT(((R_REG(sii->osh, &cc->clk_ctl_st) & htavail) != 0), 2960 PMU_MAX_TRANSITION_DLY); 2961 ASSERT(!(R_REG(sii->osh, &cc->clk_ctl_st) & htavail)); 2962 } else { 2963 OSL_DELAY(PLL_DELAY); 2964 } 2965 2966 break; 2967 2968 default: 2969 ASSERT(0); 2970 } 2971 2972done: 2973 if (!fast) { 2974 si_setcoreidx(&sii->pub, origidx); 2975 INTR_RESTORE(sii, intr_val); 2976 } 2977 return (mode == CLK_FAST); 2978} 2979 2980/** Build device path. Support SI, PCI, and JTAG for now. */ 2981int 2982BCMNMIATTACHFN(si_devpath)(si_t *sih, char *path, int size) 2983{ 2984 int slen; 2985 2986 ASSERT(path != NULL); 2987 ASSERT(size >= SI_DEVPATH_BUFSZ); 2988 2989 if (!path || size <= 0) 2990 return -1; 2991 2992 switch (BUSTYPE(sih->bustype)) { 2993 case SI_BUS: 2994 case JTAG_BUS: 2995 slen = snprintf(path, (size_t)size, "sb/%u/", si_coreidx(sih)); 2996 break; 2997 case PCI_BUS: 2998 ASSERT((SI_INFO(sih))->osh != NULL); 2999 slen = snprintf(path, (size_t)size, "pci/%u/%u/", 3000 OSL_PCI_BUS((SI_INFO(sih))->osh), 3001 OSL_PCI_SLOT((SI_INFO(sih))->osh)); 3002 break; 3003 case PCMCIA_BUS: 3004 SI_ERROR(("si_devpath: OSL_PCMCIA_BUS() not implemented, bus 1 assumed\n")); 3005 SI_ERROR(("si_devpath: OSL_PCMCIA_SLOT() not implemented, slot 1 assumed\n")); 3006 slen = snprintf(path, (size_t)size, "pc/1/1/"); 3007 break; 3008 default: 3009 slen = -1; 3010 ASSERT(0); 3011 break; 3012 } 3013 3014 if (slen < 0 || slen >= size) { 3015 path[0] = '\0'; 3016 return -1; 3017 } 3018 3019 return 0; 3020} 3021 3022char * 3023BCMATTACHFN(si_coded_devpathvar)(si_t *sih, char *varname, int var_len, const char *name) 3024{ 3025 char pathname[SI_DEVPATH_BUFSZ + 32]; 3026 char devpath[SI_DEVPATH_BUFSZ + 32]; 3027 char devpath_pcie[SI_DEVPATH_BUFSZ + 32]; 3028 char *p; 3029 int idx; 3030 int len1; 3031 int len2; 3032 int len3 = 0; 3033 3034 if (BUSTYPE(sih->bustype) == PCI_BUS) { 3035 snprintf(devpath_pcie, SI_DEVPATH_BUFSZ, "pcie/%u/%u", 3036 OSL_PCIE_DOMAIN((SI_INFO(sih))->osh), 3037 OSL_PCIE_BUS((SI_INFO(sih))->osh)); 3038 len3 = strlen(devpath_pcie); 3039 } 3040 /* try to get compact devpath if it exist */ 3041 if (si_devpath(sih, devpath, SI_DEVPATH_BUFSZ) == 0) { 3042 /* eliminate ending '/' (if present) */ 3043 len1 = strlen(devpath); 3044 if (devpath[len1 - 1] == '/') 3045 len1--; 3046 3047 for (idx = 0; idx < SI_MAXCORES; idx++) { 3048 snprintf(pathname, SI_DEVPATH_BUFSZ, "devpath%d", idx); 3049 if ((p = getvar(NULL, pathname)) == NULL) 3050 continue; 3051 3052 /* eliminate ending '/' (if present) */ 3053 len2 = strlen(p); 3054 if (p[len2 - 1] == '/') 3055 len2--; 3056 3057 /* check that both lengths match and if so compare */ 3058 /* the strings (minus trailing '/'s if present */ 3059 if ((len1 == len2) && (memcmp(p, devpath, len1) == 0)) { 3060 snprintf(varname, var_len, "%d:%s", idx, name); 3061 return varname; 3062 } 3063 3064 /* try the new PCIe devpath format if it exists */ 3065 if (len3 && (len3 == len2) && (memcmp(p, devpath_pcie, len3) == 0)) { 3066 snprintf(varname, var_len, "%d:%s", idx, name); 3067 return varname; 3068 } 3069 } 3070 } 3071 3072 return NULL; 3073} 3074 3075/** Get a variable, but only if it has a devpath prefix */ 3076char * 3077BCMATTACHFN(si_getdevpathvar)(si_t *sih, const char *name) 3078{ 3079 char varname[SI_DEVPATH_BUFSZ + 32]; 3080 char *val; 3081 3082 si_devpathvar(sih, varname, sizeof(varname), name); 3083 3084 if ((val = getvar(NULL, varname)) != NULL) 3085 return val; 3086 3087 /* try to get compact devpath if it exist */ 3088 if (si_coded_devpathvar(sih, varname, sizeof(varname), name) == NULL) 3089 return NULL; 3090 3091 return (getvar(NULL, varname)); 3092} 3093 3094/** Get a variable, but only if it has a devpath prefix */ 3095int 3096BCMATTACHFN(si_getdevpathintvar)(si_t *sih, const char *name) 3097{ 3098#if defined(BCMBUSTYPE) && (BCMBUSTYPE == SI_BUS) 3099 return (getintvar(NULL, name)); 3100#else 3101 char varname[SI_DEVPATH_BUFSZ + 32]; 3102 int val; 3103 3104 si_devpathvar(sih, varname, sizeof(varname), name); 3105 3106 if ((val = getintvar(NULL, varname)) != 0) 3107 return val; 3108 3109 /* try to get compact devpath if it exist */ 3110 if (si_coded_devpathvar(sih, varname, sizeof(varname), name) == NULL) 3111 return 0; 3112 3113 return (getintvar(NULL, varname)); 3114#endif /* BCMBUSTYPE && BCMBUSTYPE == SI_BUS */ 3115} 3116 3117#ifndef DONGLEBUILD 3118char * 3119si_getnvramflvar(si_t *sih, const char *name) 3120{ 3121 return (getvar(NULL, name)); 3122} 3123#endif /* DONGLEBUILD */ 3124 3125/** 3126 * Concatenate the dev path with a varname into the given 'var' buffer 3127 * and return the 'var' pointer. 3128 * Nothing is done to the arguments if len == 0 or var is NULL, var is still returned. 3129 * On overflow, the first char will be set to '\0'. 3130 */ 3131static char * 3132BCMATTACHFN(si_devpathvar)(si_t *sih, char *var, int len, const char *name) 3133{ 3134 uint path_len; 3135 3136 if (!var || len <= 0) 3137 return var; 3138 3139 if (si_devpath(sih, var, len) == 0) { 3140 path_len = strlen(var); 3141 3142 if (strlen(name) + 1 > (uint)(len - path_len)) 3143 var[0] = '\0'; 3144 else 3145 strncpy(var + path_len, name, len - path_len - 1); 3146 } 3147 3148 return var; 3149} 3150 3151/* Function to write a chipcommon register */ 3152uint32 3153write_ccreg(si_t *sih, uint32 offset, uint32 mask, uint32 val) 3154{ 3155 si_info_t *sii; 3156 uint32 reg_val = 0; 3157 3158 sii = SI_INFO(sih); 3159 3160 /* abort for invalid offset */ 3161 if (offset > sizeof(chipcregs_t)) 3162 return 0; 3163 3164 reg_val = si_corereg(&sii->pub, SI_CC_IDX, offset, mask, val); 3165 3166 return reg_val; 3167} 3168uint32 3169si_ccreg(si_t *sih, uint32 offset, uint32 mask, uint32 val) 3170{ 3171 si_info_t *sii; 3172 uint32 reg_val = 0; 3173 3174 sii = SI_INFO(sih); 3175 3176 /* abort for invalid offset */ 3177 if (offset > sizeof(chipcregs_t)) 3178 return 0; 3179 3180 reg_val = si_corereg(&sii->pub, SI_CC_IDX, offset, mask, val); 3181 3182 return reg_val; 3183} 3184 3185 3186uint32 3187si_pciereg(si_t *sih, uint32 offset, uint32 mask, uint32 val, uint type) 3188{ 3189 si_info_t *sii; 3190 3191 sii = SI_INFO(sih); 3192 3193 if (!PCIE(sii)) { 3194 SI_ERROR(("%s: Not a PCIE device\n", __FUNCTION__)); 3195 return 0; 3196 } 3197 3198 return pcicore_pciereg(sii->pch, offset, mask, val, type); 3199} 3200 3201uint32 3202si_pcieserdesreg(si_t *sih, uint32 mdioslave, uint32 offset, uint32 mask, uint32 val) 3203{ 3204 si_info_t *sii; 3205 3206 sii = SI_INFO(sih); 3207 3208 if (!PCIE(sii)) { 3209 SI_ERROR(("%s: Not a PCIE device\n", __FUNCTION__)); 3210 return 0; 3211 } 3212 3213 return pcicore_pcieserdesreg(sii->pch, mdioslave, offset, mask, val); 3214 3215} 3216 3217/** return TRUE if PCIE capability exists in the pci config space */ 3218static bool 3219si_ispcie(si_info_t *sii) 3220{ 3221 uint8 cap_ptr; 3222 3223 if (BUSTYPE(sii->pub.bustype) != PCI_BUS) 3224 return FALSE; 3225 3226 cap_ptr = pcicore_find_pci_capability(sii->osh, PCI_CAP_PCIECAP_ID, NULL, NULL); 3227 if (!cap_ptr) 3228 return FALSE; 3229 3230 return TRUE; 3231} 3232 3233/* Wake-on-wireless-LAN (WOWL) support functions */ 3234/** Enable PME generation and disable clkreq */ 3235void 3236si_pci_pmeen(si_t *sih) 3237{ 3238 si_info_t *sii; 3239 3240 sii = SI_INFO(sih); 3241 3242 pcicore_pmeen(sii->pch); 3243} 3244 3245/** Return TRUE if PME status is set */ 3246bool 3247si_pci_pmestat(si_t *sih) 3248{ 3249 si_info_t *sii; 3250 3251 sii = SI_INFO(sih); 3252 3253 return pcicore_pmestat(sii->pch); 3254} 3255 3256/** Disable PME generation, clear the PME status bit if set */ 3257void 3258si_pci_pmeclr(si_t *sih) 3259{ 3260 si_info_t *sii; 3261 3262 sii = SI_INFO(sih); 3263 3264 pcicore_pmeclr(sii->pch); 3265} 3266 3267void 3268si_pci_pmestatclr(si_t *sih) 3269{ 3270 si_info_t *sii; 3271 3272 sii = SI_INFO(sih); 3273 3274 pcicore_pmestatclr(sii->pch); 3275} 3276 3277/** initialize the pcmcia core */ 3278void 3279si_pcmcia_init(si_t *sih) 3280{ 3281 si_info_t *sii; 3282 uint8 cor = 0; 3283 3284 sii = SI_INFO(sih); 3285 3286 /* enable d11 mac interrupts */ 3287 OSL_PCMCIA_READ_ATTR(sii->osh, PCMCIA_FCR0 + PCMCIA_COR, &cor, 1); 3288 cor |= COR_IRQEN | COR_FUNEN; 3289 OSL_PCMCIA_WRITE_ATTR(sii->osh, PCMCIA_FCR0 + PCMCIA_COR, &cor, 1); 3290 3291} 3292 3293 3294bool 3295BCMATTACHFN(si_pci_war16165)(si_t *sih) 3296{ 3297 si_info_t *sii; 3298 3299 sii = SI_INFO(sih); 3300 3301 return (PCI(sii) && (sih->buscorerev <= 10)); 3302} 3303 3304/** 3305 * Disable pcie_war_ovr for some platforms (sigh!) 3306 * This is for boards that have BFL2_PCIEWAR_OVR set 3307 * but are in systems that still want the benefits of ASPM 3308 * Note that this should be done AFTER si_doattach 3309 */ 3310void 3311si_pcie_war_ovr_update(si_t *sih, uint8 aspm) 3312{ 3313 si_info_t *sii; 3314 3315 sii = SI_INFO(sih); 3316 3317 if (!PCIE_GEN1(sii)) 3318 return; 3319 3320 pcie_war_ovr_aspm_update(sii->pch, aspm); 3321} 3322 3323void 3324si_pcie_power_save_enable(si_t *sih, bool enable) 3325{ 3326 si_info_t *sii; 3327 3328 sii = SI_INFO(sih); 3329 3330 if (!PCIE_GEN1(sii)) 3331 return; 3332 3333 pcie_power_save_enable(sii->pch, enable); 3334} 3335 3336void 3337si_pcie_set_maxpayload_size(si_t *sih, uint16 size) 3338{ 3339 si_info_t *sii; 3340 3341 sii = SI_INFO(sih); 3342 3343 if (!PCIE(sii)) 3344 return; 3345 3346 pcie_set_maxpayload_size(sii->pch, size); 3347} 3348 3349uint16 3350si_pcie_get_maxpayload_size(si_t *sih) 3351{ 3352 si_info_t *sii; 3353 3354 sii = SI_INFO(sih); 3355 3356 if (!PCIE(sii)) 3357 return (0); 3358 3359 return pcie_get_maxpayload_size(sii->pch); 3360} 3361 3362void 3363si_pcie_set_request_size(si_t *sih, uint16 size) 3364{ 3365 si_info_t *sii; 3366 3367 sii = SI_INFO(sih); 3368 3369 if (!PCIE(sii)) 3370 return; 3371 3372 pcie_set_request_size(sii->pch, size); 3373} 3374 3375uint16 3376si_pcie_get_request_size(si_t *sih) 3377{ 3378 si_info_t *sii; 3379 3380 sii = SI_INFO(sih); 3381 3382 if (!PCIE_GEN1(sii)) 3383 return (0); 3384 3385 return pcie_get_request_size(sii->pch); 3386} 3387 3388 3389uint16 3390si_pcie_get_ssid(si_t *sih) 3391{ 3392 si_info_t *sii; 3393 3394 sii = SI_INFO(sih); 3395 3396 if (!PCIE_GEN1(sii)) 3397 return (0); 3398 3399 return pcie_get_ssid(sii->pch); 3400} 3401 3402uint32 3403si_pcie_get_bar0(si_t *sih) 3404{ 3405 si_info_t *sii; 3406 3407 sii = SI_INFO(sih); 3408 3409 if (!PCIE(sii)) 3410 return (0); 3411 3412 return pcie_get_bar0(sii->pch); 3413} 3414 3415int 3416si_pcie_configspace_cache(si_t *sih) 3417{ 3418 si_info_t *sii; 3419 3420 sii = SI_INFO(sih); 3421 3422 if (!PCIE(sii)) 3423 return -1; 3424 3425 return pcie_configspace_cache(sii->pch); 3426} 3427 3428int 3429si_pcie_configspace_restore(si_t *sih) 3430{ 3431 si_info_t *sii; 3432 3433 sii = SI_INFO(sih); 3434 3435 if (!PCIE(sii)) 3436 return -1; 3437 3438 return pcie_configspace_restore(sii->pch); 3439} 3440 3441int 3442si_pcie_configspace_get(si_t *sih, uint8 *buf, uint size) 3443{ 3444 si_info_t *sii; 3445 3446 sii = SI_INFO(sih); 3447 3448 if (!PCIE(sii) || size > PCI_CONFIG_SPACE_SIZE) 3449 return -1; 3450 3451 return pcie_configspace_get(sii->pch, buf, size); 3452} 3453 3454/** back door for other module to override chippkg */ 3455void 3456si_chippkg_set(si_t *sih, uint val) 3457{ 3458 si_info_t *sii; 3459 3460 sii = SI_INFO(sih); 3461 3462 sii->pub.chippkg = val; 3463} 3464 3465void 3466BCMINITFN(si_pci_up)(si_t *sih) 3467{ 3468 si_info_t *sii; 3469 3470 sii = SI_INFO(sih); 3471 3472 /* if not pci bus, we're done */ 3473 if (BUSTYPE(sih->bustype) != PCI_BUS) 3474 return; 3475 3476 if (PCI_FORCEHT(sii)) 3477 _si_clkctl_cc(sii, CLK_FAST); 3478 3479 if (PCIE(sii)) { 3480 pcicore_up(sii->pch, SI_PCIUP); 3481 if (((CHIPID(sih->chip) == BCM4311_CHIP_ID) && (CHIPREV(sih->chiprev) == 2)) || 3482 (CHIPID(sih->chip) == BCM4312_CHIP_ID)) 3483 sb_set_initiator_to((void *)sii, 0x3, 3484 si_findcoreidx((void *)sii, D11_CORE_ID, 0)); 3485 } 3486} 3487 3488/** Unconfigure and/or apply various WARs when system is going to sleep mode */ 3489void 3490BCMUNINITFN(si_pci_sleep)(si_t *sih) 3491{ 3492 si_info_t *sii; 3493 3494 do_4360_pcie2_war = 0; 3495 3496 sii = SI_INFO(sih); 3497 3498 pcicore_sleep(sii->pch); 3499} 3500 3501/** Unconfigure and/or apply various WARs when going down */ 3502void 3503BCMINITFN(si_pci_down)(si_t *sih) 3504{ 3505 si_info_t *sii; 3506 3507 sii = SI_INFO(sih); 3508 3509 /* if not pci bus, we're done */ 3510 if (BUSTYPE(sih->bustype) != PCI_BUS) 3511 return; 3512 3513 /* release FORCEHT since chip is going to "down" state */ 3514 if (PCI_FORCEHT(sii)) 3515 _si_clkctl_cc(sii, CLK_DYNAMIC); 3516 3517 pcicore_down(sii->pch, SI_PCIDOWN); 3518} 3519 3520/** 3521 * Configure the pci core for pci client (NIC) action 3522 * coremask is the bitvec of cores by index to be enabled. 3523 */ 3524void 3525BCMATTACHFN(si_pci_setup)(si_t *sih, uint coremask) 3526{ 3527 si_info_t *sii; 3528 sbpciregs_t *pciregs = NULL; 3529 uint32 siflag = 0, w; 3530 uint idx = 0; 3531 3532 sii = SI_INFO(sih); 3533 3534 if (BUSTYPE(sii->pub.bustype) != PCI_BUS) 3535 return; 3536 3537 ASSERT(PCI(sii) || PCIE(sii)); 3538 ASSERT(sii->pub.buscoreidx != BADIDX); 3539 3540 if (PCI(sii)) { 3541 /* get current core index */ 3542 idx = sii->curidx; 3543 3544 /* we interrupt on this backplane flag number */ 3545 siflag = si_flag(sih); 3546 3547 /* switch over to pci core */ 3548 pciregs = (sbpciregs_t *)si_setcoreidx(sih, sii->pub.buscoreidx); 3549 } 3550 3551 /* 3552 * Enable sb->pci interrupts. Assume 3553 * PCI rev 2.3 support was added in pci core rev 6 and things changed.. 3554 */ 3555 if (PCIE(sii) || (PCI(sii) && ((sii->pub.buscorerev) >= 6))) { 3556 /* pci config write to set this core bit in PCIIntMask */ 3557 w = OSL_PCI_READ_CONFIG(sii->osh, PCI_INT_MASK, sizeof(uint32)); 3558 w |= (coremask << PCI_SBIM_SHIFT); 3559#ifdef USER_MODE 3560 /* User mode operate with interrupt disabled */ 3561 w &= !(coremask << PCI_SBIM_SHIFT); 3562#endif 3563 OSL_PCI_WRITE_CONFIG(sii->osh, PCI_INT_MASK, sizeof(uint32), w); 3564 } else { 3565 /* set sbintvec bit for our flag number */ 3566 si_setint(sih, siflag); 3567 } 3568 3569 if (PCI(sii)) { 3570 OR_REG(sii->osh, &pciregs->sbtopci2, (SBTOPCI_PREF | SBTOPCI_BURST)); 3571 if (sii->pub.buscorerev >= 11) { 3572 OR_REG(sii->osh, &pciregs->sbtopci2, SBTOPCI_RC_READMULTI); 3573 w = R_REG(sii->osh, &pciregs->clkrun); 3574 W_REG(sii->osh, &pciregs->clkrun, (w | PCI_CLKRUN_DSBL)); 3575 w = R_REG(sii->osh, &pciregs->clkrun); 3576 } 3577 3578 /* switch back to previous core */ 3579 si_setcoreidx(sih, idx); 3580 } 3581} 3582 3583uint8 3584si_pcieclkreq(si_t *sih, uint32 mask, uint32 val) 3585{ 3586 si_info_t *sii; 3587 3588 sii = SI_INFO(sih); 3589 3590 if (!(PCIE(sii))) 3591 return 0; 3592 3593 return pcie_clkreq(sii->pch, mask, val); 3594} 3595 3596uint32 3597si_pcielcreg(si_t *sih, uint32 mask, uint32 val) 3598{ 3599 si_info_t *sii; 3600 3601 sii = SI_INFO(sih); 3602 3603 if (!PCIE(sii)) 3604 return 0; 3605 3606 return pcie_lcreg(sii->pch, mask, val); 3607} 3608 3609uint8 3610si_pcieltrenable(si_t *sih, uint32 mask, uint32 val) 3611{ 3612 si_info_t *sii; 3613 3614 sii = SI_INFO(sih); 3615 3616 if (!(PCIE(sii))) 3617 return 0; 3618 3619 return pcie_ltrenable(sii->pch, mask, val); 3620} 3621 3622uint8 3623si_pcieobffenable(si_t *sih, uint32 mask, uint32 val) 3624{ 3625 si_info_t *sii; 3626 3627 sii = SI_INFO(sih); 3628 3629 if (!(PCIE(sii))) 3630 return 0; 3631 3632 return pcie_obffenable(sii->pch, mask, val); 3633} 3634 3635uint32 3636si_pcieltr_reg(si_t *sih, uint32 reg, uint32 mask, uint32 val) 3637{ 3638 si_info_t *sii; 3639 3640 sii = SI_INFO(sih); 3641 3642 if (!(PCIE(sii))) 3643 return 0; 3644 3645 return pcie_ltr_reg(sii->pch, reg, mask, val); 3646} 3647 3648uint32 3649si_pcieltrspacing_reg(si_t *sih, uint32 mask, uint32 val) 3650{ 3651 si_info_t *sii; 3652 3653 sii = SI_INFO(sih); 3654 3655 if (!(PCIE(sii))) 3656 return 0; 3657 3658 return pcieltrspacing_reg(sii->pch, mask, val); 3659} 3660 3661uint32 3662si_pcieltrhysteresiscnt_reg(si_t *sih, uint32 mask, uint32 val) 3663{ 3664 si_info_t *sii; 3665 3666 sii = SI_INFO(sih); 3667 3668 if (!(PCIE(sii))) 3669 return 0; 3670 3671 return pcieltrhysteresiscnt_reg(sii->pch, mask, val); 3672} 3673 3674void 3675si_pcie_set_error_injection(si_t *sih, uint32 mode) 3676{ 3677 si_info_t *sii; 3678 3679 sii = SI_INFO(sih); 3680 3681 if (!PCIE(sii)) 3682 return; 3683 3684 pcie_set_error_injection(sii->pch, mode); 3685} 3686 3687void 3688si_pcie_set_L1substate(si_t *sih, uint32 substate) 3689{ 3690 si_info_t *sii; 3691 3692 sii = SI_INFO(sih); 3693 3694 if (!PCIE_GEN2(sii)) 3695 return; 3696 3697 pcie_set_L1substate(sii->pch, substate); 3698} 3699 3700uint32 3701si_pcie_get_L1substate(si_t *sih) 3702{ 3703 si_info_t *sii; 3704 3705 sii = SI_INFO(sih); 3706 3707 if (!PCIE_GEN2(sii)) 3708 return 0; 3709 3710 return pcie_get_L1substate(sii->pch); 3711} 3712 3713/** indirect way to read pcie config regs */ 3714uint 3715si_pcie_readreg(void *sih, uint addrtype, uint offset) 3716{ 3717 return pcie_readreg(sih, (sbpcieregs_t *)PCIEREGS(((si_info_t *)sih)), 3718 addrtype, offset); 3719} 3720 3721/* indirect way to write pcie config regs */ 3722uint 3723si_pcie_writereg(void *sih, uint addrtype, uint offset, uint val) 3724{ 3725 return pcie_writereg(sih, (sbpcieregs_t *)PCIEREGS(((si_info_t *)sih)), 3726 addrtype, offset, val); 3727} 3728 3729 3730/** 3731 * Fixup SROMless PCI device's configuration. 3732 * The current core may be changed upon return. 3733 */ 3734int 3735si_pci_fixcfg(si_t *sih) 3736{ 3737 uint origidx, pciidx; 3738 sbpciregs_t *pciregs = NULL; 3739 sbpcieregs_t *pcieregs = NULL; 3740 uint16 val16, *reg16 = NULL; 3741 uint32 w; 3742 3743 si_info_t *sii = SI_INFO(sih); 3744 3745 ASSERT(BUSTYPE(sii->pub.bustype) == PCI_BUS); 3746 3747 if ((CHIPID(sii->pub.chip) == BCM4321_CHIP_ID) && (CHIPREV(sii->pub.chiprev) < 2)) { 3748 w = (CHIPREV(sii->pub.chiprev) == 0) ? 3749 CHIPCTRL_4321A0_DEFAULT : CHIPCTRL_4321A1_DEFAULT; 3750 si_corereg(&sii->pub, SI_CC_IDX, OFFSETOF(chipcregs_t, chipcontrol), ~0, w); 3751 } 3752 3753 /* Fixup PI in SROM shadow area to enable the correct PCI core access */ 3754 /* save the current index */ 3755 origidx = si_coreidx(&sii->pub); 3756 3757 /* check 'pi' is correct and fix it if not */ 3758 if (sii->pub.buscoretype == PCIE2_CORE_ID) { 3759 pcieregs = (sbpcieregs_t *)si_setcore(&sii->pub, PCIE2_CORE_ID, 0); 3760 ASSERT(pcieregs != NULL); 3761 reg16 = &pcieregs->sprom[SRSH_PI_OFFSET]; 3762 } else if (sii->pub.buscoretype == PCIE_CORE_ID) { 3763 pcieregs = (sbpcieregs_t *)si_setcore(&sii->pub, PCIE_CORE_ID, 0); 3764 ASSERT(pcieregs != NULL); 3765 reg16 = &pcieregs->sprom[SRSH_PI_OFFSET]; 3766 } else if (sii->pub.buscoretype == PCI_CORE_ID) { 3767 pciregs = (sbpciregs_t *)si_setcore(&sii->pub, PCI_CORE_ID, 0); 3768 ASSERT(pciregs != NULL); 3769 reg16 = &pciregs->sprom[SRSH_PI_OFFSET]; 3770 } 3771 pciidx = si_coreidx(&sii->pub); 3772 3773 if (!reg16) return -1; 3774 3775 val16 = R_REG(sii->osh, reg16); 3776 if (((val16 & SRSH_PI_MASK) >> SRSH_PI_SHIFT) != (uint16)pciidx) { 3777 val16 = (uint16)(pciidx << SRSH_PI_SHIFT) | (val16 & ~SRSH_PI_MASK); 3778 W_REG(sii->osh, reg16, val16); 3779 } 3780 3781 /* restore the original index */ 3782 si_setcoreidx(&sii->pub, origidx); 3783 3784 pcicore_hwup(sii->pch); 3785 return 0; 3786} 3787 3788#if defined(BCMDBG) || defined(WLTEST) 3789int 3790si_dump_pcieinfo(si_t *sih, struct bcmstrbuf *b) 3791{ 3792 si_info_t *sii; 3793 3794 sii = SI_INFO(sih); 3795 3796 if (!PCIE_GEN1(sii) && !PCIE_GEN2(sii)) 3797 return BCME_ERROR; 3798 3799 return pcicore_dump_pcieinfo(sii->pch, b); 3800} 3801#endif 3802 3803#if defined(BCMDBG) 3804#endif 3805 3806/** change logical "focus" to the gpio core for optimized access */ 3807void * 3808si_gpiosetcore(si_t *sih) 3809{ 3810 return (si_setcoreidx(sih, SI_CC_IDX)); 3811} 3812 3813/** 3814 * mask & set gpiocontrol bits. 3815 * If a gpiocontrol bit is set to 0, chipcommon controls the corresponding GPIO pin. 3816 * If a gpiocontrol bit is set to 1, the GPIO pin is no longer a GPIO and becomes dedicated 3817 * to some chip-specific purpose. 3818 */ 3819uint32 3820si_gpiocontrol(si_t *sih, uint32 mask, uint32 val, uint8 priority) 3821{ 3822 uint regoff; 3823 3824 regoff = 0; 3825 3826 /* gpios could be shared on router platforms 3827 * ignore reservation if it's high priority (e.g., test apps) 3828 */ 3829 if ((priority != GPIO_HI_PRIORITY) && 3830 (BUSTYPE(sih->bustype) == SI_BUS) && (val || mask)) { 3831 mask = priority ? (si_gpioreservation & mask) : 3832 ((si_gpioreservation | mask) & ~(si_gpioreservation)); 3833 val &= mask; 3834 } 3835 3836 regoff = OFFSETOF(chipcregs_t, gpiocontrol); 3837 return (si_corereg(sih, SI_CC_IDX, regoff, mask, val)); 3838} 3839 3840/** mask&set gpio output enable bits */ 3841uint32 3842si_gpioouten(si_t *sih, uint32 mask, uint32 val, uint8 priority) 3843{ 3844 uint regoff; 3845 3846 regoff = 0; 3847 3848 /* gpios could be shared on router platforms 3849 * ignore reservation if it's high priority (e.g., test apps) 3850 */ 3851 if ((priority != GPIO_HI_PRIORITY) && 3852 (BUSTYPE(sih->bustype) == SI_BUS) && (val || mask)) { 3853 mask = priority ? (si_gpioreservation & mask) : 3854 ((si_gpioreservation | mask) & ~(si_gpioreservation)); 3855 val &= mask; 3856 } 3857 3858 regoff = OFFSETOF(chipcregs_t, gpioouten); 3859 return (si_corereg(sih, SI_CC_IDX, regoff, mask, val)); 3860} 3861 3862/** mask&set gpio output bits */ 3863uint32 3864si_gpioout(si_t *sih, uint32 mask, uint32 val, uint8 priority) 3865{ 3866 uint regoff; 3867 3868 regoff = 0; 3869 3870 /* gpios could be shared on router platforms 3871 * ignore reservation if it's high priority (e.g., test apps) 3872 */ 3873 if ((priority != GPIO_HI_PRIORITY) && 3874 (BUSTYPE(sih->bustype) == SI_BUS) && (val || mask)) { 3875 mask = priority ? (si_gpioreservation & mask) : 3876 ((si_gpioreservation | mask) & ~(si_gpioreservation)); 3877 val &= mask; 3878 } 3879 3880 regoff = OFFSETOF(chipcregs_t, gpioout); 3881 return (si_corereg(sih, SI_CC_IDX, regoff, mask, val)); 3882} 3883 3884/** reserve one gpio */ 3885uint32 3886si_gpioreserve(si_t *sih, uint32 gpio_bitmask, uint8 priority) 3887{ 3888 /* only cores on SI_BUS share GPIO's and only applcation users need to 3889 * reserve/release GPIO 3890 */ 3891 if ((BUSTYPE(sih->bustype) != SI_BUS) || (!priority)) { 3892 ASSERT((BUSTYPE(sih->bustype) == SI_BUS) && (priority)); 3893 return 0xffffffff; 3894 } 3895 /* make sure only one bit is set */ 3896 if ((!gpio_bitmask) || ((gpio_bitmask) & (gpio_bitmask - 1))) { 3897 ASSERT((gpio_bitmask) && !((gpio_bitmask) & (gpio_bitmask - 1))); 3898 return 0xffffffff; 3899 } 3900 3901 /* already reserved */ 3902 if (si_gpioreservation & gpio_bitmask) 3903 return 0xffffffff; 3904 /* set reservation */ 3905 si_gpioreservation |= gpio_bitmask; 3906 3907 return si_gpioreservation; 3908} 3909 3910/** 3911 * release one gpio. 3912 * 3913 * releasing the gpio doesn't change the current value on the GPIO last write value 3914 * persists till someone overwrites it. 3915 */ 3916uint32 3917si_gpiorelease(si_t *sih, uint32 gpio_bitmask, uint8 priority) 3918{ 3919 /* only cores on SI_BUS share GPIO's and only applcation users need to 3920 * reserve/release GPIO 3921 */ 3922 if ((BUSTYPE(sih->bustype) != SI_BUS) || (!priority)) { 3923 ASSERT((BUSTYPE(sih->bustype) == SI_BUS) && (priority)); 3924 return 0xffffffff; 3925 } 3926 /* make sure only one bit is set */ 3927 if ((!gpio_bitmask) || ((gpio_bitmask) & (gpio_bitmask - 1))) { 3928 ASSERT((gpio_bitmask) && !((gpio_bitmask) & (gpio_bitmask - 1))); 3929 return 0xffffffff; 3930 } 3931 3932 /* already released */ 3933 if (!(si_gpioreservation & gpio_bitmask)) 3934 return 0xffffffff; 3935 3936 /* clear reservation */ 3937 si_gpioreservation &= ~gpio_bitmask; 3938 3939 return si_gpioreservation; 3940} 3941 3942/* return the current gpioin register value */ 3943uint32 3944si_gpioin(si_t *sih) 3945{ 3946 uint regoff; 3947 3948 regoff = OFFSETOF(chipcregs_t, gpioin); 3949 return (si_corereg(sih, SI_CC_IDX, regoff, 0, 0)); 3950} 3951 3952/* mask&set gpio interrupt polarity bits */ 3953uint32 3954si_gpiointpolarity(si_t *sih, uint32 mask, uint32 val, uint8 priority) 3955{ 3956 uint regoff; 3957 3958 /* gpios could be shared on router platforms */ 3959 if ((BUSTYPE(sih->bustype) == SI_BUS) && (val || mask)) { 3960 mask = priority ? (si_gpioreservation & mask) : 3961 ((si_gpioreservation | mask) & ~(si_gpioreservation)); 3962 val &= mask; 3963 } 3964 3965 regoff = OFFSETOF(chipcregs_t, gpiointpolarity); 3966 return (si_corereg(sih, SI_CC_IDX, regoff, mask, val)); 3967} 3968 3969/* mask&set gpio interrupt mask bits */ 3970uint32 3971si_gpiointmask(si_t *sih, uint32 mask, uint32 val, uint8 priority) 3972{ 3973 uint regoff; 3974 3975 /* gpios could be shared on router platforms */ 3976 if ((BUSTYPE(sih->bustype) == SI_BUS) && (val || mask)) { 3977 mask = priority ? (si_gpioreservation & mask) : 3978 ((si_gpioreservation | mask) & ~(si_gpioreservation)); 3979 val &= mask; 3980 } 3981 3982 regoff = OFFSETOF(chipcregs_t, gpiointmask); 3983 return (si_corereg(sih, SI_CC_IDX, regoff, mask, val)); 3984} 3985 3986/* assign the gpio to an led */ 3987uint32 3988si_gpioled(si_t *sih, uint32 mask, uint32 val) 3989{ 3990 if (sih->ccrev < 16) 3991 return 0xffffffff; 3992 3993 /* gpio led powersave reg */ 3994 return (si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, gpiotimeroutmask), mask, val)); 3995} 3996 3997/* mask&set gpio timer val */ 3998uint32 3999si_gpiotimerval(si_t *sih, uint32 mask, uint32 gpiotimerval) 4000{ 4001 if (sih->ccrev < 16) 4002 return 0xffffffff; 4003 4004 return (si_corereg(sih, SI_CC_IDX, 4005 OFFSETOF(chipcregs_t, gpiotimerval), mask, gpiotimerval)); 4006} 4007 4008uint32 4009si_gpiopull(si_t *sih, bool updown, uint32 mask, uint32 val) 4010{ 4011 uint offs; 4012 4013 if (sih->ccrev < 20) 4014 return 0xffffffff; 4015 4016 offs = (updown ? OFFSETOF(chipcregs_t, gpiopulldown) : OFFSETOF(chipcregs_t, gpiopullup)); 4017 return (si_corereg(sih, SI_CC_IDX, offs, mask, val)); 4018} 4019 4020uint32 4021si_gpioevent(si_t *sih, uint regtype, uint32 mask, uint32 val) 4022{ 4023 uint offs; 4024 4025 if (sih->ccrev < 11) 4026 return 0xffffffff; 4027 4028 if (regtype == GPIO_REGEVT) 4029 offs = OFFSETOF(chipcregs_t, gpioevent); 4030 else if (regtype == GPIO_REGEVT_INTMSK) 4031 offs = OFFSETOF(chipcregs_t, gpioeventintmask); 4032 else if (regtype == GPIO_REGEVT_INTPOL) 4033 offs = OFFSETOF(chipcregs_t, gpioeventintpolarity); 4034 else 4035 return 0xffffffff; 4036 4037 return (si_corereg(sih, SI_CC_IDX, offs, mask, val)); 4038} 4039 4040void * 4041BCMATTACHFN(si_gpio_handler_register)(si_t *sih, uint32 event, 4042 bool level, gpio_handler_t cb, void *arg) 4043{ 4044 si_info_t *sii; 4045 gpioh_item_t *gi; 4046 4047 ASSERT(event); 4048 ASSERT(cb != NULL); 4049 4050 sii = SI_INFO(sih); 4051 if (sih->ccrev < 11) 4052 return NULL; 4053 4054 if ((gi = MALLOC(sii->osh, sizeof(gpioh_item_t))) == NULL) 4055 return NULL; 4056 4057 bzero(gi, sizeof(gpioh_item_t)); 4058 gi->event = event; 4059 gi->handler = cb; 4060 gi->arg = arg; 4061 gi->level = level; 4062 4063 gi->next = sii->gpioh_head; 4064 sii->gpioh_head = gi; 4065 4066#ifdef BCMDBG_ERR 4067 { 4068 gpioh_item_t *h = sii->gpioh_head; 4069 int cnt = 0; 4070 4071 for (; h; h = h->next) { 4072 cnt++; 4073 SI_ERROR(("gpiohdler=%p cb=%p event=0x%x\n", 4074 h, h->handler, h->event)); 4075 } 4076 SI_ERROR(("gpiohdler total=%d\n", cnt)); 4077 } 4078#endif 4079 return (void *)(gi); 4080} 4081 4082void 4083BCMATTACHFN(si_gpio_handler_unregister)(si_t *sih, void *gpioh) 4084{ 4085 si_info_t *sii; 4086 gpioh_item_t *p, *n; 4087 4088 sii = SI_INFO(sih); 4089 if (sih->ccrev < 11) 4090 return; 4091 4092 ASSERT(sii->gpioh_head != NULL); 4093 if ((void*)sii->gpioh_head == gpioh) { 4094 sii->gpioh_head = sii->gpioh_head->next; 4095 MFREE(sii->osh, gpioh, sizeof(gpioh_item_t)); 4096 return; 4097 } else { 4098 p = sii->gpioh_head; 4099 n = p->next; 4100 while (n) { 4101 if ((void*)n == gpioh) { 4102 p->next = n->next; 4103 MFREE(sii->osh, gpioh, sizeof(gpioh_item_t)); 4104 return; 4105 } 4106 p = n; 4107 n = n->next; 4108 } 4109 } 4110 4111#ifdef BCMDBG_ERR 4112 { 4113 gpioh_item_t *h = sii->gpioh_head; 4114 int cnt = 0; 4115 4116 for (; h; h = h->next) { 4117 cnt++; 4118 SI_ERROR(("gpiohdler=%p cb=%p event=0x%x\n", 4119 h, h->handler, h->event)); 4120 } 4121 SI_ERROR(("gpiohdler total=%d\n", cnt)); 4122 } 4123#endif 4124 ASSERT(0); /* Not found in list */ 4125} 4126 4127void 4128si_gpio_handler_process(si_t *sih) 4129{ 4130 si_info_t *sii; 4131 gpioh_item_t *h; 4132 uint32 level = si_gpioin(sih); 4133 uint32 levelp = si_gpiointpolarity(sih, 0, 0, 0); 4134 uint32 edge = si_gpioevent(sih, GPIO_REGEVT, 0, 0); 4135 uint32 edgep = si_gpioevent(sih, GPIO_REGEVT_INTPOL, 0, 0); 4136 4137 sii = SI_INFO(sih); 4138 for (h = sii->gpioh_head; h != NULL; h = h->next) { 4139 if (h->handler) { 4140 uint32 status = (h->level ? level : edge) & h->event; 4141 uint32 polarity = (h->level ? levelp : edgep) & h->event; 4142 4143 /* polarity bitval is opposite of status bitval */ 4144 if (status ^ polarity) 4145 h->handler(status, h->arg); 4146 } 4147 } 4148 4149 si_gpioevent(sih, GPIO_REGEVT, edge, edge); /* clear edge-trigger status */ 4150} 4151 4152uint32 4153si_gpio_int_enable(si_t *sih, bool enable) 4154{ 4155 uint offs; 4156 4157 if (sih->ccrev < 11) 4158 return 0xffffffff; 4159 4160 offs = OFFSETOF(chipcregs_t, intmask); 4161 return (si_corereg(sih, SI_CC_IDX, offs, CI_GPIO, (enable ? CI_GPIO : 0))); 4162} 4163 4164 4165/** Return the size of the specified SOCRAM bank */ 4166static uint 4167socram_banksize(si_info_t *sii, sbsocramregs_t *regs, uint8 idx, uint8 mem_type) 4168{ 4169 uint banksize, bankinfo; 4170 uint bankidx = idx | (mem_type << SOCRAM_BANKIDX_MEMTYPE_SHIFT); 4171 4172 ASSERT(mem_type <= SOCRAM_MEMTYPE_DEVRAM); 4173 4174 W_REG(sii->osh, ®s->bankidx, bankidx); 4175 bankinfo = R_REG(sii->osh, ®s->bankinfo); 4176 banksize = SOCRAM_BANKINFO_SZBASE * ((bankinfo & SOCRAM_BANKINFO_SZMASK) + 1); 4177 return banksize; 4178} 4179 4180void 4181si_socdevram(si_t *sih, bool set, uint8 *enable, uint8 *protect, uint8 *remap) 4182{ 4183 si_info_t *sii; 4184 uint origidx; 4185 uint intr_val = 0; 4186 sbsocramregs_t *regs; 4187 bool wasup; 4188 uint corerev; 4189 4190 sii = SI_INFO(sih); 4191 4192 /* Block ints and save current core */ 4193 INTR_OFF(sii, intr_val); 4194 origidx = si_coreidx(sih); 4195 4196 if (!set) 4197 *enable = *protect = *remap = 0; 4198 4199 /* Switch to SOCRAM core */ 4200 if (!(regs = si_setcore(sih, SOCRAM_CORE_ID, 0))) 4201 goto done; 4202 4203 /* Get info for determining size */ 4204 if (!(wasup = si_iscoreup(sih))) 4205 si_core_reset(sih, 0, 0); 4206 4207 corerev = si_corerev(sih); 4208 if (corerev >= 10) { 4209 uint32 extcinfo; 4210 uint8 nb; 4211 uint8 i; 4212 uint32 bankidx, bankinfo; 4213 4214 extcinfo = R_REG(sii->osh, ®s->extracoreinfo); 4215 nb = ((extcinfo & SOCRAM_DEVRAMBANK_MASK) >> SOCRAM_DEVRAMBANK_SHIFT); 4216 for (i = 0; i < nb; i++) { 4217 bankidx = i | (SOCRAM_MEMTYPE_DEVRAM << SOCRAM_BANKIDX_MEMTYPE_SHIFT); 4218 W_REG(sii->osh, ®s->bankidx, bankidx); 4219 bankinfo = R_REG(sii->osh, ®s->bankinfo); 4220 if (set) { 4221 bankinfo &= ~SOCRAM_BANKINFO_DEVRAMSEL_MASK; 4222 bankinfo &= ~SOCRAM_BANKINFO_DEVRAMPRO_MASK; 4223 bankinfo &= ~SOCRAM_BANKINFO_DEVRAMREMAP_MASK; 4224 if (*enable) { 4225 bankinfo |= (1 << SOCRAM_BANKINFO_DEVRAMSEL_SHIFT); 4226 if (*protect) 4227 bankinfo |= (1 << SOCRAM_BANKINFO_DEVRAMPRO_SHIFT); 4228 if ((corerev >= 16) && *remap) 4229 bankinfo |= 4230 (1 << SOCRAM_BANKINFO_DEVRAMREMAP_SHIFT); 4231 } 4232 W_REG(sii->osh, ®s->bankinfo, bankinfo); 4233 } 4234 else if (i == 0) { 4235 if (bankinfo & SOCRAM_BANKINFO_DEVRAMSEL_MASK) { 4236 *enable = 1; 4237 if (bankinfo & SOCRAM_BANKINFO_DEVRAMPRO_MASK) 4238 *protect = 1; 4239 if (bankinfo & SOCRAM_BANKINFO_DEVRAMREMAP_MASK) 4240 *remap = 1; 4241 } 4242 } 4243 } 4244 } 4245 4246 /* Return to previous state and core */ 4247 if (!wasup) 4248 si_core_disable(sih, 0); 4249 si_setcoreidx(sih, origidx); 4250 4251done: 4252 INTR_RESTORE(sii, intr_val); 4253} 4254 4255bool 4256si_socdevram_remap_isenb(si_t *sih) 4257{ 4258 si_info_t *sii; 4259 uint origidx; 4260 uint intr_val = 0; 4261 sbsocramregs_t *regs; 4262 bool wasup, remap = FALSE; 4263 uint corerev; 4264 uint32 extcinfo; 4265 uint8 nb; 4266 uint8 i; 4267 uint32 bankidx, bankinfo; 4268 4269 sii = SI_INFO(sih); 4270 4271 /* Block ints and save current core */ 4272 INTR_OFF(sii, intr_val); 4273 origidx = si_coreidx(sih); 4274 4275 /* Switch to SOCRAM core */ 4276 if (!(regs = si_setcore(sih, SOCRAM_CORE_ID, 0))) 4277 goto done; 4278 4279 /* Get info for determining size */ 4280 if (!(wasup = si_iscoreup(sih))) 4281 si_core_reset(sih, 0, 0); 4282 4283 corerev = si_corerev(sih); 4284 if (corerev >= 16) { 4285 extcinfo = R_REG(sii->osh, ®s->extracoreinfo); 4286 nb = ((extcinfo & SOCRAM_DEVRAMBANK_MASK) >> SOCRAM_DEVRAMBANK_SHIFT); 4287 for (i = 0; i < nb; i++) { 4288 bankidx = i | (SOCRAM_MEMTYPE_DEVRAM << SOCRAM_BANKIDX_MEMTYPE_SHIFT); 4289 W_REG(sii->osh, ®s->bankidx, bankidx); 4290 bankinfo = R_REG(sii->osh, ®s->bankinfo); 4291 if (bankinfo & SOCRAM_BANKINFO_DEVRAMREMAP_MASK) { 4292 remap = TRUE; 4293 break; 4294 } 4295 } 4296 } 4297 4298 /* Return to previous state and core */ 4299 if (!wasup) 4300 si_core_disable(sih, 0); 4301 si_setcoreidx(sih, origidx); 4302 4303done: 4304 INTR_RESTORE(sii, intr_val); 4305 return remap; 4306} 4307 4308bool 4309si_socdevram_pkg(si_t *sih) 4310{ 4311 if (si_socdevram_size(sih) > 0) 4312 return TRUE; 4313 else 4314 return FALSE; 4315} 4316 4317uint32 4318si_socdevram_size(si_t *sih) 4319{ 4320 si_info_t *sii; 4321 uint origidx; 4322 uint intr_val = 0; 4323 uint32 memsize = 0; 4324 sbsocramregs_t *regs; 4325 bool wasup; 4326 uint corerev; 4327 4328 sii = SI_INFO(sih); 4329 4330 /* Block ints and save current core */ 4331 INTR_OFF(sii, intr_val); 4332 origidx = si_coreidx(sih); 4333 4334 /* Switch to SOCRAM core */ 4335 if (!(regs = si_setcore(sih, SOCRAM_CORE_ID, 0))) 4336 goto done; 4337 4338 /* Get info for determining size */ 4339 if (!(wasup = si_iscoreup(sih))) 4340 si_core_reset(sih, 0, 0); 4341 4342 corerev = si_corerev(sih); 4343 if (corerev >= 10) { 4344 uint32 extcinfo; 4345 uint8 nb; 4346 uint8 i; 4347 4348 extcinfo = R_REG(sii->osh, ®s->extracoreinfo); 4349 nb = (((extcinfo & SOCRAM_DEVRAMBANK_MASK) >> SOCRAM_DEVRAMBANK_SHIFT)); 4350 for (i = 0; i < nb; i++) 4351 memsize += socram_banksize(sii, regs, i, SOCRAM_MEMTYPE_DEVRAM); 4352 } 4353 4354 /* Return to previous state and core */ 4355 if (!wasup) 4356 si_core_disable(sih, 0); 4357 si_setcoreidx(sih, origidx); 4358 4359done: 4360 INTR_RESTORE(sii, intr_val); 4361 4362 return memsize; 4363} 4364 4365uint32 4366si_socdevram_remap_size(si_t *sih) 4367{ 4368 si_info_t *sii; 4369 uint origidx; 4370 uint intr_val = 0; 4371 uint32 memsize = 0, banksz; 4372 sbsocramregs_t *regs; 4373 bool wasup; 4374 uint corerev; 4375 uint32 extcinfo; 4376 uint8 nb; 4377 uint8 i; 4378 uint32 bankidx, bankinfo; 4379 4380 sii = SI_INFO(sih); 4381 4382 /* Block ints and save current core */ 4383 INTR_OFF(sii, intr_val); 4384 origidx = si_coreidx(sih); 4385 4386 /* Switch to SOCRAM core */ 4387 if (!(regs = si_setcore(sih, SOCRAM_CORE_ID, 0))) 4388 goto done; 4389 4390 /* Get info for determining size */ 4391 if (!(wasup = si_iscoreup(sih))) 4392 si_core_reset(sih, 0, 0); 4393 4394 corerev = si_corerev(sih); 4395 if (corerev >= 16) { 4396 extcinfo = R_REG(sii->osh, ®s->extracoreinfo); 4397 nb = (((extcinfo & SOCRAM_DEVRAMBANK_MASK) >> SOCRAM_DEVRAMBANK_SHIFT)); 4398 4399 /* 4400 * FIX: A0 Issue: Max addressable is 512KB, instead 640KB 4401 * Only four banks are accessible to ARM 4402 */ 4403 if ((corerev == 16) && (nb == 5)) 4404 nb = 4; 4405 4406 for (i = 0; i < nb; i++) { 4407 bankidx = i | (SOCRAM_MEMTYPE_DEVRAM << SOCRAM_BANKIDX_MEMTYPE_SHIFT); 4408 W_REG(sii->osh, ®s->bankidx, bankidx); 4409 bankinfo = R_REG(sii->osh, ®s->bankinfo); 4410 if (bankinfo & SOCRAM_BANKINFO_DEVRAMREMAP_MASK) { 4411 banksz = socram_banksize(sii, regs, i, SOCRAM_MEMTYPE_DEVRAM); 4412 memsize += banksz; 4413 } else { 4414 /* Account only consecutive banks for now */ 4415 break; 4416 } 4417 } 4418 } 4419 4420 /* Return to previous state and core */ 4421 if (!wasup) 4422 si_core_disable(sih, 0); 4423 si_setcoreidx(sih, origidx); 4424 4425done: 4426 INTR_RESTORE(sii, intr_val); 4427 4428 return memsize; 4429} 4430 4431/** Return the RAM size of the SOCRAM core */ 4432uint32 4433si_socram_size(si_t *sih) 4434{ 4435 si_info_t *sii; 4436 uint origidx; 4437 uint intr_val = 0; 4438 4439 sbsocramregs_t *regs; 4440 bool wasup; 4441 uint corerev; 4442 uint32 coreinfo; 4443 uint memsize = 0; 4444 4445 sii = SI_INFO(sih); 4446 4447 /* Block ints and save current core */ 4448 INTR_OFF(sii, intr_val); 4449 origidx = si_coreidx(sih); 4450 4451 /* Switch to SOCRAM core */ 4452 if (!(regs = si_setcore(sih, SOCRAM_CORE_ID, 0))) 4453 goto done; 4454 4455 /* Get info for determining size */ 4456 if (!(wasup = si_iscoreup(sih))) 4457 si_core_reset(sih, 0, 0); 4458 corerev = si_corerev(sih); 4459 coreinfo = R_REG(sii->osh, ®s->coreinfo); 4460 4461 /* Calculate size from coreinfo based on rev */ 4462 if (corerev == 0) 4463 memsize = 1 << (16 + (coreinfo & SRCI_MS0_MASK)); 4464 else if (corerev < 3) { 4465 memsize = 1 << (SR_BSZ_BASE + (coreinfo & SRCI_SRBSZ_MASK)); 4466 memsize *= (coreinfo & SRCI_SRNB_MASK) >> SRCI_SRNB_SHIFT; 4467 } else if ((corerev <= 7) || (corerev == 12)) { 4468 uint nb = (coreinfo & SRCI_SRNB_MASK) >> SRCI_SRNB_SHIFT; 4469 uint bsz = (coreinfo & SRCI_SRBSZ_MASK); 4470 uint lss = (coreinfo & SRCI_LSS_MASK) >> SRCI_LSS_SHIFT; 4471 if (lss != 0) 4472 nb --; 4473 memsize = nb * (1 << (bsz + SR_BSZ_BASE)); 4474 if (lss != 0) 4475 memsize += (1 << ((lss - 1) + SR_BSZ_BASE)); 4476 } else { 4477 uint8 i; 4478 uint nb = (coreinfo & SRCI_SRNB_MASK) >> SRCI_SRNB_SHIFT; 4479 for (i = 0; i < nb; i++) 4480 memsize += socram_banksize(sii, regs, i, SOCRAM_MEMTYPE_RAM); 4481 } 4482 4483 /* Return to previous state and core */ 4484 if (!wasup) 4485 si_core_disable(sih, 0); 4486 si_setcoreidx(sih, origidx); 4487 4488done: 4489 INTR_RESTORE(sii, intr_val); 4490 4491 return memsize; 4492} 4493 4494#if defined(WLOFFLD) 4495 4496/** Return the TCM-RAM size of the ARMCR4 core. */ 4497uint32 4498si_tcm_size(si_t *sih) 4499{ 4500 si_info_t *sii; 4501 uint origidx; 4502 uint intr_val = 0; 4503 uint8 *regs; 4504 bool wasup; 4505 uint32 corecap; 4506 uint memsize = 0; 4507 uint32 nab = 0; 4508 uint32 nbb = 0; 4509 uint32 totb = 0; 4510 uint32 bxinfo = 0; 4511 uint32 idx = 0; 4512 uint32 *arm_cap_reg; 4513 uint32 *arm_bidx; 4514 uint32 *arm_binfo; 4515 4516 sii = SI_INFO(sih); 4517 4518 /* Block ints and save current core */ 4519 INTR_OFF(sii, intr_val); 4520 origidx = si_coreidx(sih); 4521 4522 /* Switch to CR4 core */ 4523 if (!(regs = si_setcore(sih, ARMCR4_CORE_ID, 0))) 4524 goto done; 4525 4526 /* Get info for determining size. If in reset, come out of reset, 4527 * but remain in halt 4528 */ 4529 if (!(wasup = si_iscoreup(sih))) 4530 si_core_reset(sih, SICF_CPUHALT, SICF_CPUHALT); 4531 4532 arm_cap_reg = (uint32 *)(regs + SI_CR4_CAP); 4533 corecap = R_REG(sii->osh, arm_cap_reg); 4534 4535 nab = (corecap & ARMCR4_TCBANB_MASK) >> ARMCR4_TCBANB_SHIFT; 4536 nbb = (corecap & ARMCR4_TCBBNB_MASK) >> ARMCR4_TCBBNB_SHIFT; 4537 totb = nab + nbb; 4538 4539 arm_bidx = (uint32 *)(regs + SI_CR4_BANKIDX); 4540 arm_binfo = (uint32 *)(regs + SI_CR4_BANKINFO); 4541 for (idx = 0; idx < totb; idx++) { 4542 W_REG(sii->osh, arm_bidx, idx); 4543 4544 bxinfo = R_REG(sii->osh, arm_binfo); 4545 memsize += ((bxinfo & ARMCR4_BSZ_MASK) + 1) * ARMCR4_BSZ_MULT; 4546 } 4547 4548 /* Return to previous state and core */ 4549 if (!wasup) 4550 si_core_disable(sih, 0); 4551 si_setcoreidx(sih, origidx); 4552 4553done: 4554 INTR_RESTORE(sii, intr_val); 4555 4556 return memsize; 4557} 4558 4559bool 4560si_has_flops(si_t *sih) 4561{ 4562 uint origidx, cr4_rev; 4563 4564 /* Find out CR4 core revision */ 4565 origidx = si_coreidx(sih); 4566 if (si_setcore(sih, ARMCR4_CORE_ID, 0)) { 4567 cr4_rev = si_corerev(sih); 4568 si_setcoreidx(sih, origidx); 4569 4570 if (cr4_rev == 1 || cr4_rev >= 3) 4571 return TRUE; 4572 } 4573 return FALSE; 4574} 4575#endif 4576 4577#ifdef BCMECICOEX 4578#define NOTIFY_BT_FM_DISABLE(sih, val) \ 4579 si_eci_notify_bt((sih), ECI_OUT_FM_DISABLE_MASK(sih->ccrev), \ 4580 ((val) << ECI_OUT_FM_DISABLE_SHIFT(sih->ccrev)), FALSE) 4581 4582/** Query OTP to see if FM is disabled */ 4583static int 4584BCMINITFN(si_query_FMDisabled_from_OTP)(si_t *sih, uint16 *FMDisabled) 4585{ 4586 int error = BCME_OK; 4587 uint bitoff = 0; 4588 bool wasup; 4589 void *oh; 4590 uint32 min_res_mask = 0; 4591 4592 /* Determine the bit for the chip */ 4593 switch (CHIPID(sih->chip)) { 4594 case BCM4325_CHIP_ID: 4595 if (CHIPREV(sih->chiprev) >= 6) 4596 bitoff = OTP4325_FM_DISABLED_OFFSET; 4597 break; 4598 default: 4599 break; 4600 } 4601 4602 /* If there is a bit for this chip, check it */ 4603 if (bitoff) { 4604 if (!(wasup = si_is_otp_powered(sih))) { 4605 si_otp_power(sih, TRUE, &min_res_mask); 4606 } 4607 4608 if ((oh = otp_init(sih)) != NULL) 4609 *FMDisabled = !otp_read_bit(oh, OTP4325_FM_DISABLED_OFFSET); 4610 else 4611 error = BCME_NOTFOUND; 4612 4613 if (!wasup) { 4614 si_otp_power(sih, FALSE, &min_res_mask); 4615 } 4616 } 4617 4618 return error; 4619} 4620 4621bool 4622si_eci(si_t *sih) 4623{ 4624 return (!!(sih->cccaps & CC_CAP_ECI)); 4625} 4626 4627bool 4628si_seci(si_t *sih) 4629{ 4630 return (sih->cccaps_ext & CC_CAP_EXT_SECI_PRESENT); 4631} 4632 4633bool 4634si_gci(si_t *sih) 4635{ 4636 return (sih->cccaps_ext & CC_CAP_EXT_GCI_PRESENT); 4637} 4638 4639/** ECI Init routine */ 4640int 4641BCMINITFN(si_eci_init)(si_t *sih) 4642{ 4643 uint32 origidx = 0; 4644 si_info_t *sii; 4645 chipcregs_t *cc; 4646 bool fast; 4647 uint16 FMDisabled = FALSE; 4648 4649 /* check for ECI capability */ 4650 if (!(sih->cccaps & CC_CAP_ECI)) 4651 return BCME_ERROR; 4652 4653 sii = SI_INFO(sih); 4654 fast = SI_FAST(sii); 4655 if (!fast) { 4656 origidx = sii->curidx; 4657 if ((cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0)) == NULL) 4658 return BCME_ERROR; 4659 } else if ((cc = (chipcregs_t *)CCREGS_FAST(sii)) == NULL) 4660 return BCME_ERROR; 4661 ASSERT(cc); 4662 4663 /* disable level based interrupts */ 4664 if (sih->ccrev < 35) { 4665 W_REG(sii->osh, &cc->eci.lt35.eci_intmaskhi, 0x0); 4666 W_REG(sii->osh, &cc->eci.lt35.eci_intmaskmi, 0x0); 4667 W_REG(sii->osh, &cc->eci.lt35.eci_intmasklo, 0x0); 4668 } 4669 else { 4670 W_REG(sii->osh, &cc->eci.ge35.eci_intmaskhi, 0x0); 4671 W_REG(sii->osh, &cc->eci.ge35.eci_intmasklo, 0x0); 4672 } 4673 4674 /* Assign eci_output bits between 'wl' and dot11mac */ 4675 if (sih->ccrev < 35) { 4676 W_REG(sii->osh, &cc->eci.lt35.eci_control, ECI_MACCTRL_BITS); 4677 } 4678 else { 4679 W_REG(sii->osh, &cc->eci.ge35.eci_controllo, ECI_MACCTRLLO_BITS); 4680 W_REG(sii->osh, &cc->eci.ge35.eci_controlhi, ECI_MACCTRLHI_BITS); 4681 } 4682 4683 /* enable only edge based interrupts 4684 * only toggle on bit 62 triggers an interrupt 4685 */ 4686 if (sih->ccrev < 35) { 4687 W_REG(sii->osh, &cc->eci.lt35.eci_eventmaskhi, 0x0); 4688 W_REG(sii->osh, &cc->eci.lt35.eci_eventmaskmi, 0x0); 4689 W_REG(sii->osh, &cc->eci.lt35.eci_eventmasklo, 0x0); 4690 } 4691 else { 4692 W_REG(sii->osh, &cc->eci.ge35.eci_eventmaskhi, 0x0); 4693 W_REG(sii->osh, &cc->eci.ge35.eci_eventmasklo, 0x0); 4694 } 4695 4696 /* restore previous core */ 4697 if (!fast) 4698 si_setcoreidx(sih, origidx); 4699 4700 /* if FM disabled in OTP, let BT know */ 4701 if (!si_query_FMDisabled_from_OTP(sih, &FMDisabled)) { 4702 if (FMDisabled) { 4703 NOTIFY_BT_FM_DISABLE(sih, 1); 4704 } 4705 } 4706 4707 return 0; 4708} 4709 4710/** Write values to BT on eci_output. */ 4711void 4712si_eci_notify_bt(si_t *sih, uint32 mask, uint32 val, bool interrupt) 4713{ 4714 uint32 offset; 4715 4716 if ((sih->cccaps & CC_CAP_ECI) || 4717 (si_seci(sih))) 4718 { 4719 /* ECI or SECI mode */ 4720 /* Clear interrupt bit by default */ 4721 if (interrupt) 4722 si_corereg(sih, SI_CC_IDX, 4723 (sih->ccrev < 35 ? 4724 OFFSETOF(chipcregs_t, eci.lt35.eci_output) : 4725 OFFSETOF(chipcregs_t, eci.ge35.eci_outputlo)), 4726 (1 << 30), 0); 4727 4728 if (sih->ccrev >= 35) { 4729 if ((mask & 0xFFFF0000) == ECI48_OUT_MASKMAGIC_HIWORD) { 4730 offset = OFFSETOF(chipcregs_t, eci.ge35.eci_outputhi); 4731 mask = mask & ~0xFFFF0000; 4732 } 4733 else { 4734 offset = OFFSETOF(chipcregs_t, eci.ge35.eci_outputlo); 4735 mask = mask | (1<<30); 4736 val = val & ~(1 << 30); 4737 } 4738 } 4739 else { 4740 offset = OFFSETOF(chipcregs_t, eci.lt35.eci_output); 4741 val = val & ~(1 << 30); 4742 } 4743 4744 si_corereg(sih, SI_CC_IDX, offset, mask, val); 4745 4746 /* Set interrupt bit if needed */ 4747 if (interrupt) 4748 si_corereg(sih, SI_CC_IDX, 4749 (sih->ccrev < 35 ? 4750 OFFSETOF(chipcregs_t, eci.lt35.eci_output) : 4751 OFFSETOF(chipcregs_t, eci.ge35.eci_outputlo)), 4752 (1 << 30), (1 << 30)); 4753 } 4754 else if (sih->cccaps_ext & CC_CAP_EXT_GCI_PRESENT) 4755 { 4756 /* GCI Mode */ 4757 if ((mask & 0xFFFF0000) == ECI48_OUT_MASKMAGIC_HIWORD) { 4758 mask = mask & ~0xFFFF0000; 4759 si_gci_direct(sih, OFFSETOF(chipcregs_t, gci_output[1]), mask, val); 4760 } 4761 } 4762} 4763 4764/** seci clock enable/disable */ 4765static void 4766si_seci_clkreq(si_t *sih, bool enable) 4767{ 4768 uint32 clk_ctl_st; 4769 uint32 offset; 4770 uint32 val; 4771 4772 if (!si_seci(sih)) 4773 return; 4774 4775 if (enable) 4776 val = CLKCTL_STS_SECI_CLK_REQ; 4777 else 4778 val = 0; 4779 4780 offset = OFFSETOF(chipcregs_t, clk_ctl_st); 4781 4782 si_corereg(sih, SI_CC_IDX, offset, CLKCTL_STS_SECI_CLK_REQ, val); 4783 4784 if (!enable) 4785 return; 4786 4787 SPINWAIT(!(si_corereg(sih, 0, offset, 0, 0) & CLKCTL_STS_SECI_CLK_AVAIL), 4788 PMU_MAX_TRANSITION_DLY); 4789 4790 clk_ctl_st = si_corereg(sih, 0, offset, 0, 0); 4791 if (enable) { 4792 if (!(clk_ctl_st & CLKCTL_STS_SECI_CLK_AVAIL)) { 4793 SI_ERROR(("SECI clock is still not available\n")); 4794 return; 4795 } 4796 } 4797} 4798 4799void 4800BCMINITFN(si_seci_down)(si_t *sih) 4801{ 4802 uint32 origidx = 0; 4803 si_info_t *sii; 4804 chipcregs_t *cc; 4805 bool fast; 4806 uint32 seci_conf; 4807 4808 if (!si_seci(sih)) 4809 return; 4810 4811 sii = SI_INFO(sih); 4812 fast = SI_FAST(sii); 4813 4814 if (!fast) { 4815 origidx = sii->curidx; 4816 if ((cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0)) == NULL) 4817 return; 4818 } else if ((cc = (chipcregs_t *)CCREGS_FAST(sii)) == NULL) 4819 return; 4820 ASSERT(cc); 4821 /* 4331 X28 sign off seci */ 4822 if (CHIPID(sih->chip) == BCM4331_CHIP_ID) { 4823 /* flush seci */ 4824 seci_conf = R_REG(sii->osh, &cc->SECI_config); 4825 seci_conf |= SECI_UPD_SECI; 4826 W_REG(sii->osh, &cc->SECI_config, seci_conf); 4827 SPINWAIT((R_REG(sii->osh, &cc->SECI_config) & SECI_UPD_SECI), 1000); 4828 4829 /* SECI sign off */ 4830 W_REG(sii->osh, &cc->seci_uart_data, SECI_SIGNOFF_0); 4831 W_REG(sii->osh, &cc->seci_uart_data, SECI_SIGNOFF_1); 4832 SPINWAIT((R_REG(sii->osh, &cc->seci_uart_lsr) & (1 << 2)), 1000); 4833 /* put seci in reset */ 4834 seci_conf = R_REG(sii->osh, &cc->SECI_config); 4835 seci_conf &= ~SECI_ENAB_SECI_ECI; 4836 W_REG(sii->osh, &cc->SECI_config, seci_conf); 4837 seci_conf |= SECI_RESET; 4838 W_REG(sii->osh, &cc->SECI_config, seci_conf); 4839 } 4840 4841 /* bring down the clock if up */ 4842 si_seci_clkreq(sih, FALSE); 4843 4844 /* restore previous core */ 4845 if (!fast) 4846 si_setcoreidx(sih, origidx); 4847} 4848 4849void 4850si_seci_upd(si_t *sih, bool enable) 4851{ 4852 uint32 origidx = 0; 4853 si_info_t *sii; 4854 chipcregs_t *cc; 4855 bool fast; 4856 uint32 regval, seci_ctrl; 4857 uint intr_val = 0; 4858 4859 if (!si_seci(sih)) 4860 return; 4861 4862 sii = SI_INFO(sih); 4863 fast = SI_FAST(sii); 4864 INTR_OFF(sii, intr_val); 4865 if (!fast) { 4866 origidx = sii->curidx; 4867 if ((cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0)) == NULL) 4868 goto exit; 4869 } else if ((cc = (chipcregs_t *)CCREGS_FAST(sii)) == NULL) 4870 goto exit; 4871 4872 ASSERT(cc); 4873 4874 /* Select SECI based on enable input */ 4875 if ((CHIPID(sih->chip) == BCM4331_CHIP_ID) || 4876 (CHIPID(sih->chip) == BCM4352_CHIP_ID) || 4877 (CHIPID(sih->chip) == BCM4360_CHIP_ID)) { 4878 regval = R_REG(sii->osh, &cc->chipcontrol); 4879 4880 if (CHIPID(sih->chip) == BCM4331_CHIP_ID) { 4881 seci_ctrl = CCTRL4331_SECI; 4882 } else { 4883 seci_ctrl = CCTRL4360_SECI_ON_GPIO01; 4884 } 4885 4886 if (enable) { 4887 regval |= seci_ctrl; 4888 } else { 4889 regval &= ~seci_ctrl; 4890 } 4891 W_REG(sii->osh, &cc->chipcontrol, regval); 4892 4893 if (enable) { 4894 /* Send ECI update to BT */ 4895 regval = R_REG(sii->osh, &cc->SECI_config); 4896 regval |= SECI_UPD_SECI; 4897 W_REG(sii->osh, &cc->SECI_config, regval); 4898 SPINWAIT((R_REG(sii->osh, &cc->SECI_config) & SECI_UPD_SECI), 1000); 4899 /* Request ECI update from BT */ 4900 W_REG(sii->osh, &cc->seci_uart_data, SECI_SLIP_ESC_CHAR); 4901 W_REG(sii->osh, &cc->seci_uart_data, SECI_REFRESH_REQ); 4902 } 4903 } 4904 4905exit: 4906 /* restore previous core */ 4907 if (!fast) 4908 si_setcoreidx(sih, origidx); 4909 4910 INTR_RESTORE(sii, intr_val); 4911} 4912 4913/** SECI Init routine, pass in seci_mode */ 4914void * 4915BCMINITFN(si_seci_init)(si_t *sih, uint8 seci_mode) 4916{ 4917 uint32 origidx = 0; 4918 uint32 offset; 4919 si_info_t *sii; 4920 void *ptr; 4921 chipcregs_t *cc; 4922 bool fast; 4923 uint32 seci_conf; 4924 uint32 regval; 4925 4926 if (sih->ccrev < 35) 4927 return NULL; 4928 4929 if (!si_seci(sih)) 4930 return NULL; 4931 4932 if (seci_mode > SECI_MODE_MASK) 4933 return NULL; 4934 4935 sii = SI_INFO(sih); 4936 fast = SI_FAST(sii); 4937 if (!fast) { 4938 origidx = sii->curidx; 4939 if ((ptr = si_setcore(sih, CC_CORE_ID, 0)) == NULL) 4940 return NULL; 4941 } else if ((ptr = CCREGS_FAST(sii)) == NULL) 4942 return NULL; 4943 cc = (chipcregs_t *)ptr; 4944 ASSERT(cc); 4945 4946 4947 /* 43236 (ccrev 36) muxes SECI on JTAG pins. Select SECI. */ 4948 if (CHIPID(sih->chip) == BCM43236_CHIP_ID || 4949 CHIPID(sih->chip) == BCM4331_CHIP_ID) { 4950 regval = R_REG(sii->osh, &cc->chipcontrol); 4951 regval |= CCTRL4331_SECI; 4952 W_REG(sii->osh, &cc->chipcontrol, regval); 4953 } 4954 4955 /* 43143 (ccrev 43) mux SECI on JTAG pins. Select SECI. */ 4956 if (CHIPID(sih->chip) == BCM43143_CHIP_ID) { 4957 regval = R_REG(sii->osh, &cc->chipcontrol); 4958 regval &= ~(CCTRL_43143_SECI | CCTRL_43143_BT_LEGACY); 4959 switch (seci_mode) { 4960 case SECI_MODE_LEGACY_3WIRE_WLAN: 4961 regval |= CCTRL_43143_BT_LEGACY; 4962 break; 4963 case SECI_MODE_SECI: 4964 regval |= CCTRL_43143_SECI; 4965 break; 4966 default: 4967 ASSERT(0); 4968 } 4969 W_REG(sii->osh, &cc->chipcontrol, regval); 4970 } 4971 4972 if ((CHIPID(sih->chip) == BCM43236_CHIP_ID) || 4973 (CHIPID(sih->chip) == BCM43143_CHIP_ID)) { 4974 regval = R_REG(sii->osh, &cc->jtagctrl); 4975 regval |= 0x1; 4976 W_REG(sii->osh, &cc->jtagctrl, regval); 4977 } 4978 4979 /* enable SECI clock */ 4980 si_seci_clkreq(sih, TRUE); 4981 4982 /* put the SECI in reset */ 4983 seci_conf = R_REG(sii->osh, &cc->SECI_config); 4984 seci_conf &= ~SECI_ENAB_SECI_ECI; 4985 W_REG(sii->osh, &cc->SECI_config, seci_conf); 4986 seci_conf = SECI_RESET; 4987 W_REG(sii->osh, &cc->SECI_config, seci_conf); 4988 4989 /* set force-low, and set EN_SECI for all non-legacy modes */ 4990 seci_conf |= SECI_ENAB_SECIOUT_DIS; 4991 if ((seci_mode == SECI_MODE_UART) || (seci_mode == SECI_MODE_SECI) || 4992 (seci_mode == SECI_MODE_HALF_SECI)) 4993 { 4994 seci_conf |= SECI_ENAB_SECI_ECI; 4995 } 4996 W_REG(sii->osh, &cc->SECI_config, seci_conf); 4997 4998 /* take seci out of reset */ 4999 seci_conf = R_REG(sii->osh, &cc->SECI_config); 5000 seci_conf &= ~(SECI_RESET); 5001 W_REG(sii->osh, &cc->SECI_config, seci_conf); 5002 5003 /* set UART/SECI baud rate */ 5004 /* hard-coded at 4MBaud for now */ 5005 if ((seci_mode == SECI_MODE_UART) || (seci_mode == SECI_MODE_SECI) || 5006 (seci_mode == SECI_MODE_HALF_SECI)) { 5007 if ((CHIPID(sih->chip) == BCM43236_CHIP_ID) || 5008 (CHIPID(sih->chip) == BCM4331_CHIP_ID) || 5009 (CHIPID(sih->chip) == BCM43143_CHIP_ID)) { 5010 /* 43236 ccrev = 36 and MAC clk = 96MHz */ 5011 /* 4331,43143 MAC clk = 96MHz */ 5012 offset = OFFSETOF(chipcregs_t, seci_uart_bauddiv); 5013 si_corereg(sih, SI_CC_IDX, offset, 0xFF, 0xFF); 5014 offset = OFFSETOF(chipcregs_t, seci_uart_baudadj); 5015 si_corereg(sih, SI_CC_IDX, offset, 0xFF, 0x44); 5016 } 5017 else if ((CHIPID(sih->chip) == BCM4360_CHIP_ID) || 5018 (CHIPID(sih->chip) == BCM43460_CHIP_ID) || 5019 (CHIPID(sih->chip) == BCM43526_CHIP_ID) || 5020 (CHIPID(sih->chip) == BCM4352_CHIP_ID)) { 5021 /* MAC clk is 160MHz */ 5022 offset = OFFSETOF(chipcregs_t, seci_uart_bauddiv); 5023 si_corereg(sih, SI_CC_IDX, offset, 0xFF, 0xFE); 5024 offset = OFFSETOF(chipcregs_t, seci_uart_baudadj); 5025 si_corereg(sih, SI_CC_IDX, offset, 0xFF, 0x44); 5026 } 5027 else { 5028 /* 4336 MAC clk is 80MHz */ 5029 offset = OFFSETOF(chipcregs_t, seci_uart_bauddiv); 5030 si_corereg(sih, SI_CC_IDX, offset, 0xFF, 0xFF); 5031 offset = OFFSETOF(chipcregs_t, seci_uart_baudadj); 5032 si_corereg(sih, SI_CC_IDX, offset, 0xFF, 0x22); 5033 } 5034 5035 /* LCR/MCR settings */ 5036 offset = OFFSETOF(chipcregs_t, seci_uart_lcr); 5037 si_corereg(sih, SI_CC_IDX, offset, 0xFF, 5038 (SECI_UART_LCR_RX_EN | SECI_UART_LCR_TXO_EN)); /* 0x28 */ 5039 offset = OFFSETOF(chipcregs_t, seci_uart_mcr); 5040 si_corereg(sih, SI_CC_IDX, offset, 5041 0xFF, (SECI_UART_MCR_TX_EN | SECI_UART_MCR_BAUD_ADJ_EN)); /* 0x81 */ 5042 5043 /* Give control of ECI output regs to MAC core */ 5044 offset = OFFSETOF(chipcregs_t, eci.ge35.eci_controllo); 5045 si_corereg(sih, SI_CC_IDX, offset, 0xFFFFFFFF, ECI_MACCTRLLO_BITS); 5046 offset = OFFSETOF(chipcregs_t, eci.ge35.eci_controlhi); 5047 si_corereg(sih, SI_CC_IDX, offset, 0xFFFF, ECI_MACCTRLHI_BITS); 5048 } 5049 5050 /* set the seci mode in seci conf register */ 5051 seci_conf = R_REG(sii->osh, &cc->SECI_config); 5052 seci_conf &= ~(SECI_MODE_MASK << SECI_MODE_SHIFT); 5053 seci_conf |= (seci_mode << SECI_MODE_SHIFT); 5054 W_REG(sii->osh, &cc->SECI_config, seci_conf); 5055 5056 /* Clear force-low bit */ 5057 seci_conf = R_REG(sii->osh, &cc->SECI_config); 5058 seci_conf &= ~SECI_ENAB_SECIOUT_DIS; 5059 W_REG(sii->osh, &cc->SECI_config, seci_conf); 5060 5061 /* restore previous core */ 5062 if (!fast) 5063 si_setcoreidx(sih, origidx); 5064 5065 return ptr; 5066} 5067 5068void * 5069BCMINITFN(si_gci_init)(si_t *sih) 5070{ 5071 if (sih->cccaps_ext & CC_CAP_EXT_GCI_PRESENT) 5072 { 5073 si_gci_reset(sih); 5074 /* Set GCI Control bits 40 - 47 to be SW Controlled. These bits 5075 contain WL channel info and are sent to BT. 5076 */ 5077 si_gci_direct(sih, OFFSETOF(chipcregs_t, gci_control_1), 5078 GCI_WL_CHN_INFO_MASK, GCI_WL_CHN_INFO_MASK); 5079 } 5080 return (NULL); 5081} 5082#endif /* BCMECICOEX */ 5083 5084#if (!defined(_CFE_) && !defined(_CFEZ_)) || defined(CFG_WL) 5085void 5086si_btcgpiowar(si_t *sih) 5087{ 5088 si_info_t *sii; 5089 uint origidx; 5090 uint intr_val = 0; 5091 chipcregs_t *cc; 5092 5093 sii = SI_INFO(sih); 5094 5095 /* Make sure that there is ChipCommon core present && 5096 * UART_TX is strapped to 1 5097 */ 5098 if (!(sih->cccaps & CC_CAP_UARTGPIO)) 5099 return; 5100 5101 /* si_corereg cannot be used as we have to guarantee 8-bit read/writes */ 5102 INTR_OFF(sii, intr_val); 5103 5104 origidx = si_coreidx(sih); 5105 5106 cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0); 5107 ASSERT(cc != NULL); 5108 5109 W_REG(sii->osh, &cc->uart0mcr, R_REG(sii->osh, &cc->uart0mcr) | 0x04); 5110 5111 /* restore the original index */ 5112 si_setcoreidx(sih, origidx); 5113 5114 INTR_RESTORE(sii, intr_val); 5115} 5116 5117void 5118si_chipcontrl_btshd0_4331(si_t *sih, bool on) 5119{ 5120 si_info_t *sii; 5121 chipcregs_t *cc; 5122 uint origidx; 5123 uint32 val; 5124 uint intr_val = 0; 5125 5126 sii = SI_INFO(sih); 5127 5128 INTR_OFF(sii, intr_val); 5129 5130 origidx = si_coreidx(sih); 5131 5132 cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0); 5133 5134 val = R_REG(sii->osh, &cc->chipcontrol); 5135 5136 /* bt_shd0 controls are same for 4331 chiprevs 0 and 1, packages 12x9 and 12x12 */ 5137 if (on) { 5138 /* Enable bt_shd0 on gpio4: */ 5139 val |= (CCTRL4331_BT_SHD0_ON_GPIO4); 5140 W_REG(sii->osh, &cc->chipcontrol, val); 5141 } else { 5142 val &= ~(CCTRL4331_BT_SHD0_ON_GPIO4); 5143 W_REG(sii->osh, &cc->chipcontrol, val); 5144 } 5145 5146 /* restore the original index */ 5147 si_setcoreidx(sih, origidx); 5148 5149 INTR_RESTORE(sii, intr_val); 5150} 5151 5152void 5153si_chipcontrl_restore(si_t *sih, uint32 val) 5154{ 5155 si_info_t *sii; 5156 chipcregs_t *cc; 5157 uint origidx; 5158 5159 sii = SI_INFO(sih); 5160 origidx = si_coreidx(sih); 5161 cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0); 5162 W_REG(sii->osh, &cc->chipcontrol, val); 5163 si_setcoreidx(sih, origidx); 5164} 5165 5166uint32 5167si_chipcontrl_read(si_t *sih) 5168{ 5169 si_info_t *sii; 5170 chipcregs_t *cc; 5171 uint origidx; 5172 uint32 val; 5173 5174 sii = SI_INFO(sih); 5175 origidx = si_coreidx(sih); 5176 cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0); 5177 val = R_REG(sii->osh, &cc->chipcontrol); 5178 si_setcoreidx(sih, origidx); 5179 return val; 5180} 5181 5182void 5183si_chipcontrl_epa4331(si_t *sih, bool on) 5184{ 5185 si_info_t *sii; 5186 chipcregs_t *cc; 5187 uint origidx; 5188 uint32 val; 5189 5190 sii = SI_INFO(sih); 5191 origidx = si_coreidx(sih); 5192 5193 cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0); 5194 5195 val = R_REG(sii->osh, &cc->chipcontrol); 5196 5197 if (on) { 5198 if (sih->chippkg == 9 || sih->chippkg == 0xb) { 5199 val |= (CCTRL4331_EXTPA_EN | CCTRL4331_EXTPA_ON_GPIO2_5); 5200 /* Ext PA Controls for 4331 12x9 Package */ 5201 W_REG(sii->osh, &cc->chipcontrol, val); 5202 } else { 5203 /* Ext PA Controls for 4331 12x12 Package */ 5204 if (sih->chiprev > 0) { 5205 W_REG(sii->osh, &cc->chipcontrol, val | 5206 (CCTRL4331_EXTPA_EN) | (CCTRL4331_EXTPA_EN2)); 5207 } else { 5208 W_REG(sii->osh, &cc->chipcontrol, val | (CCTRL4331_EXTPA_EN)); 5209 } 5210 } 5211 } else { 5212 val &= ~(CCTRL4331_EXTPA_EN | CCTRL4331_EXTPA_EN2 | CCTRL4331_EXTPA_ON_GPIO2_5); 5213 W_REG(sii->osh, &cc->chipcontrol, val); 5214 } 5215 5216 si_setcoreidx(sih, origidx); 5217} 5218 5219/** switch muxed pins, on: SROM, off: FEMCTRL. Called for a family of ac chips, not just 4360. */ 5220void 5221si_chipcontrl_srom4360(si_t *sih, bool on) 5222{ 5223 si_info_t *sii; 5224 chipcregs_t *cc; 5225 uint origidx; 5226 uint32 val; 5227 5228 sii = SI_INFO(sih); 5229 origidx = si_coreidx(sih); 5230 5231 cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0); 5232 5233 val = R_REG(sii->osh, &cc->chipcontrol); 5234 5235 if (on) { 5236 val &= ~(CCTRL4360_SECI_MODE | 5237 CCTRL4360_BTSWCTRL_MODE | 5238 CCTRL4360_EXTRA_FEMCTRL_MODE | 5239 CCTRL4360_BT_LGCY_MODE | 5240 CCTRL4360_CORE2FEMCTRL4_ON); 5241 5242 W_REG(sii->osh, &cc->chipcontrol, val); 5243 } else { 5244 } 5245 5246 si_setcoreidx(sih, origidx); 5247} 5248 5249void 5250si_chipcontrl_epa4331_wowl(si_t *sih, bool enter_wowl) 5251{ 5252 si_info_t *sii; 5253 chipcregs_t *cc; 5254 uint origidx; 5255 uint32 val; 5256 bool sel_chip; 5257 5258 sel_chip = (CHIPID(sih->chip) == BCM4331_CHIP_ID) || 5259 (CHIPID(sih->chip) == BCM43431_CHIP_ID); 5260 sel_chip &= ((sih->chippkg == 9 || sih->chippkg == 0xb)); 5261 5262 if (!sel_chip) 5263 return; 5264 5265 sii = SI_INFO(sih); 5266 origidx = si_coreidx(sih); 5267 5268 cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0); 5269 5270 val = R_REG(sii->osh, &cc->chipcontrol); 5271 5272 if (enter_wowl) { 5273 val |= CCTRL4331_EXTPA_EN; 5274 W_REG(sii->osh, &cc->chipcontrol, val); 5275 } else { 5276 val |= (CCTRL4331_EXTPA_EN | CCTRL4331_EXTPA_ON_GPIO2_5); 5277 W_REG(sii->osh, &cc->chipcontrol, val); 5278 } 5279 si_setcoreidx(sih, origidx); 5280} 5281#endif /* (!_CFE_ && !_CFEZ_) || CFG_WL */ 5282 5283uint 5284si_pll_reset(si_t *sih) 5285{ 5286 uint err = 0; 5287 5288 uint intr_val = 0; 5289 si_info_t *sii; 5290 sii = SI_INFO(sih); 5291 INTR_OFF(sii, intr_val); 5292 err = si_pll_minresmask_reset(sih, sii->osh); 5293 INTR_RESTORE(sii, intr_val); 5294 return (err); 5295} 5296 5297/** Enable BT-COEX & Ex-PA for 4313 */ 5298void 5299si_epa_4313war(si_t *sih) 5300{ 5301 si_info_t *sii; 5302 chipcregs_t *cc; 5303 uint origidx; 5304 5305 sii = SI_INFO(sih); 5306 origidx = si_coreidx(sih); 5307 5308 cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0); 5309 5310 /* EPA Fix */ 5311 W_REG(sii->osh, &cc->gpiocontrol, 5312 R_REG(sii->osh, &cc->gpiocontrol) | GPIO_CTRL_EPA_EN_MASK); 5313 5314 si_setcoreidx(sih, origidx); 5315} 5316 5317void 5318si_clk_pmu_htavail_set(si_t *sih, bool set_clear) 5319{ 5320 si_info_t *sii; 5321 sii = SI_INFO(sih); 5322 5323 si_pmu_minresmask_htavail_set(sih, sii->osh, set_clear); 5324} 5325 5326/** Re-enable synth_pwrsw resource in min_res_mask for 4313 */ 5327void 5328si_pmu_synth_pwrsw_4313_war(si_t *sih) 5329{ 5330 si_info_t *sii; 5331 chipcregs_t *cc; 5332 uint origidx; 5333 5334 sii = SI_INFO(sih); 5335 origidx = si_coreidx(sih); 5336 5337 cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0); 5338 if (!(cc->min_res_mask & PMURES_BIT(RES4313_SYNTH_PWRSW_RSRC))) 5339 OR_REG(sii->osh, &cc->min_res_mask, PMURES_BIT(RES4313_SYNTH_PWRSW_RSRC)); 5340 5341 si_setcoreidx(sih, origidx); 5342} 5343 5344/** WL/BT control for 4313 btcombo boards >= P250 */ 5345void 5346si_btcombo_p250_4313_war(si_t *sih) 5347{ 5348 si_info_t *sii; 5349 chipcregs_t *cc; 5350 uint origidx; 5351 5352 sii = SI_INFO(sih); 5353 origidx = si_coreidx(sih); 5354 5355 cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0); 5356 W_REG(sii->osh, &cc->gpiocontrol, 5357 R_REG(sii->osh, &cc->gpiocontrol) | GPIO_CTRL_5_6_EN_MASK); 5358 5359 W_REG(sii->osh, &cc->gpioouten, 5360 R_REG(sii->osh, &cc->gpioouten) | GPIO_CTRL_5_6_EN_MASK); 5361 5362 si_setcoreidx(sih, origidx); 5363} 5364void 5365si_btc_enable_chipcontrol(si_t *sih) 5366{ 5367 si_info_t *sii; 5368 chipcregs_t *cc; 5369 uint origidx; 5370 5371 sii = SI_INFO(sih); 5372 origidx = si_coreidx(sih); 5373 5374 cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0); 5375 5376 /* BT fix */ 5377 W_REG(sii->osh, &cc->chipcontrol, 5378 R_REG(sii->osh, &cc->chipcontrol) | CC_BTCOEX_EN_MASK); 5379 5380 si_setcoreidx(sih, origidx); 5381} 5382void 5383si_btcombo_43228_war(si_t *sih) 5384{ 5385 si_info_t *sii; 5386 chipcregs_t *cc; 5387 uint origidx; 5388 5389 sii = SI_INFO(sih); 5390 origidx = si_coreidx(sih); 5391 5392 cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0); 5393 5394 W_REG(sii->osh, &cc->gpioouten, GPIO_CTRL_7_6_EN_MASK); 5395 W_REG(sii->osh, &cc->gpioout, GPIO_OUT_7_EN_MASK); 5396 5397 si_setcoreidx(sih, origidx); 5398} 5399 5400/** check if the device is removed */ 5401bool 5402si_deviceremoved(si_t *sih) 5403{ 5404 uint32 w; 5405 si_info_t *sii; 5406 5407 sii = SI_INFO(sih); 5408 5409 switch (BUSTYPE(sih->bustype)) { 5410 case PCI_BUS: 5411 ASSERT(sii->osh != NULL); 5412 w = OSL_PCI_READ_CONFIG(sii->osh, PCI_CFG_VID, sizeof(uint32)); 5413 if ((w & 0xFFFF) != VENDOR_BROADCOM) 5414 return TRUE; 5415 break; 5416 } 5417 return FALSE; 5418} 5419 5420bool 5421si_is_sprom_available(si_t *sih) 5422{ 5423 if (sih->ccrev >= 31) { 5424 si_info_t *sii; 5425 uint origidx; 5426 chipcregs_t *cc; 5427 uint32 sromctrl; 5428 5429 if ((sih->cccaps & CC_CAP_SROM) == 0) 5430 return FALSE; 5431 5432 sii = SI_INFO(sih); 5433 origidx = sii->curidx; 5434 cc = si_setcoreidx(sih, SI_CC_IDX); 5435 sromctrl = R_REG(sii->osh, &cc->sromcontrol); 5436 si_setcoreidx(sih, origidx); 5437 return (sromctrl & SRC_PRESENT); 5438 } 5439 5440 switch (CHIPID(sih->chip)) { 5441 case BCM4312_CHIP_ID: 5442 return ((sih->chipst & CST4312_SPROM_OTP_SEL_MASK) != CST4312_OTP_SEL); 5443 case BCM4325_CHIP_ID: 5444 return (sih->chipst & CST4325_SPROM_SEL) != 0; 5445 case BCM4322_CHIP_ID: case BCM43221_CHIP_ID: case BCM43231_CHIP_ID: 5446 case BCM43222_CHIP_ID: case BCM43111_CHIP_ID: case BCM43112_CHIP_ID: 5447 case BCM4342_CHIP_ID: { 5448 uint32 spromotp; 5449 spromotp = (sih->chipst & CST4322_SPROM_OTP_SEL_MASK) >> 5450 CST4322_SPROM_OTP_SEL_SHIFT; 5451 return (spromotp & CST4322_SPROM_PRESENT) != 0; 5452 } 5453 case BCM4329_CHIP_ID: 5454 return (sih->chipst & CST4329_SPROM_SEL) != 0; 5455 case BCM4315_CHIP_ID: 5456 return (sih->chipst & CST4315_SPROM_SEL) != 0; 5457 case BCM4319_CHIP_ID: 5458 return (sih->chipst & CST4319_SPROM_SEL) != 0; 5459 case BCM4336_CHIP_ID: 5460 case BCM43362_CHIP_ID: 5461 return (sih->chipst & CST4336_SPROM_PRESENT) != 0; 5462 case BCM4330_CHIP_ID: 5463 return (sih->chipst & CST4330_SPROM_PRESENT) != 0; 5464 case BCM4313_CHIP_ID: 5465 return (sih->chipst & CST4313_SPROM_PRESENT) != 0; 5466 case BCM4331_CHIP_ID: 5467 case BCM43431_CHIP_ID: 5468 return (sih->chipst & CST4331_SPROM_PRESENT) != 0; 5469 case BCM43239_CHIP_ID: 5470 return ((sih->chipst & CST43239_SPROM_MASK) && 5471 !(sih->chipst & CST43239_SFLASH_MASK)); 5472 case BCM4324_CHIP_ID: 5473 case BCM43242_CHIP_ID: 5474 return ((sih->chipst & CST4324_SPROM_MASK) && 5475 !(sih->chipst & CST4324_SFLASH_MASK)); 5476 case BCM4335_CHIP_ID: 5477 return ((sih->chipst & CST4335_SPROM_MASK) && 5478 !(sih->chipst & CST4335_SFLASH_MASK)); 5479 5480 case BCM4350_CHIP_ID: 5481 return (sih->chipst & CST4350_SPROM_PRESENT) != 0; 5482 case BCM43131_CHIP_ID: 5483 case BCM43217_CHIP_ID: 5484 case BCM43227_CHIP_ID: 5485 case BCM43228_CHIP_ID: 5486 case BCM43428_CHIP_ID: 5487 return (sih->chipst & CST43228_OTP_PRESENT) != CST43228_OTP_PRESENT; 5488 default: 5489 return TRUE; 5490 } 5491} 5492 5493bool 5494si_is_otp_disabled(si_t *sih) 5495{ 5496 switch (CHIPID(sih->chip)) { 5497 case BCM4325_CHIP_ID: 5498 return (sih->chipst & CST4325_SPROM_OTP_SEL_MASK) == CST4325_OTP_PWRDN; 5499 case BCM4322_CHIP_ID: 5500 case BCM43221_CHIP_ID: 5501 case BCM43231_CHIP_ID: 5502 case BCM4342_CHIP_ID: 5503 return (((sih->chipst & CST4322_SPROM_OTP_SEL_MASK) >> 5504 CST4322_SPROM_OTP_SEL_SHIFT) & CST4322_OTP_PRESENT) != 5505 CST4322_OTP_PRESENT; 5506 case BCM4329_CHIP_ID: 5507 return (sih->chipst & CST4329_SPROM_OTP_SEL_MASK) == CST4329_OTP_PWRDN; 5508 case BCM4315_CHIP_ID: 5509 return (sih->chipst & CST4315_SPROM_OTP_SEL_MASK) == CST4315_OTP_PWRDN; 5510 case BCM4319_CHIP_ID: 5511 return (sih->chipst & CST4319_SPROM_OTP_SEL_MASK) == CST4319_OTP_PWRDN; 5512 case BCM4336_CHIP_ID: 5513 case BCM43362_CHIP_ID: 5514 return ((sih->chipst & CST4336_OTP_PRESENT) == 0); 5515 case BCM4330_CHIP_ID: 5516 return ((sih->chipst & CST4330_OTP_PRESENT) == 0); 5517 case BCM43237_CHIP_ID: 5518 return FALSE; 5519 case BCM4313_CHIP_ID: 5520 return (sih->chipst & CST4313_OTP_PRESENT) == 0; 5521 case BCM4331_CHIP_ID: 5522 return (sih->chipst & CST4331_OTP_PRESENT) != CST4331_OTP_PRESENT; 5523 case BCM4360_CHIP_ID: 5524 case BCM43526_CHIP_ID: 5525 case BCM43460_CHIP_ID: 5526 case BCM4352_CHIP_ID: 5527 /* 4360 OTP is always powered and enabled */ 5528 return FALSE; 5529 /* These chips always have their OTP on */ 5530 case BCM43111_CHIP_ID: case BCM43112_CHIP_ID: case BCM43222_CHIP_ID: 5531 case BCM43224_CHIP_ID: case BCM43225_CHIP_ID: 5532 case BCM43421_CHIP_ID: 5533 case BCM43226_CHIP_ID: 5534 case BCM43235_CHIP_ID: case BCM43236_CHIP_ID: case BCM43238_CHIP_ID: 5535 case BCM43234_CHIP_ID: case BCM43239_CHIP_ID: case BCM4324_CHIP_ID: 5536 case BCM43431_CHIP_ID: 5537 case BCM43131_CHIP_ID: 5538 case BCM43217_CHIP_ID: 5539 case BCM43227_CHIP_ID: 5540 case BCM43228_CHIP_ID: 5541 case BCM43428_CHIP_ID: case BCM4335_CHIP_ID: 5542 case BCM4350_CHIP_ID: 5543 case BCM43143_CHIP_ID: 5544 case BCM43242_CHIP_ID: 5545 case BCM43243_CHIP_ID: 5546 default: 5547 return FALSE; 5548 } 5549} 5550 5551bool 5552si_is_otp_powered(si_t *sih) 5553{ 5554 if (PMUCTL_ENAB(sih)) 5555 return si_pmu_is_otp_powered(sih, si_osh(sih)); 5556 return TRUE; 5557} 5558 5559void 5560si_otp_power(si_t *sih, bool on, uint32* min_res_mask) 5561{ 5562 if (PMUCTL_ENAB(sih)) 5563 si_pmu_otp_power(sih, si_osh(sih), on, min_res_mask); 5564 OSL_DELAY(1000); 5565} 5566 5567bool 5568#if defined(BCMDBG) || defined(WLTEST) || defined(BCMDBG_ERR) 5569si_is_sprom_enabled(si_t *sih) 5570#else 5571BCMATTACHFN(si_is_sprom_enabled)(si_t *sih) 5572#endif 5573{ 5574 if (PMUCTL_ENAB(sih)) 5575 return si_pmu_is_sprom_enabled(sih, si_osh(sih)); 5576 return TRUE; 5577} 5578 5579void 5580#if defined(BCMDBG) || defined(WLTEST) || defined(BCMDBG_ERR) 5581si_sprom_enable(si_t *sih, bool enable) 5582#else 5583BCMATTACHFN(si_sprom_enable)(si_t *sih, bool enable) 5584#endif 5585{ 5586 if (PMUCTL_ENAB(sih)) 5587 si_pmu_sprom_enable(sih, si_osh(sih), enable); 5588} 5589 5590/* Return BCME_NOTFOUND if the card doesn't have CIS format nvram */ 5591int 5592si_cis_source(si_t *sih) 5593{ 5594 /* Many chips have the same mapping of their chipstatus field */ 5595 static const uint cis_sel[] = { CIS_DEFAULT, CIS_SROM, CIS_OTP, CIS_SROM }; 5596 static const uint cis_43236_sel[] = { CIS_DEFAULT, CIS_OTP }; 5597 5598 /* PCI chips use SROM format instead of CIS */ 5599 if (BUSTYPE(sih->bustype) == PCI_BUS) 5600 return BCME_NOTFOUND; 5601 5602 switch (CHIPID(sih->chip)) { 5603 case BCM4325_CHIP_ID: 5604 return ((sih->chipst & CST4325_SPROM_OTP_SEL_MASK) >= ARRAYSIZE(cis_sel)) ? 5605 CIS_DEFAULT : cis_sel[(sih->chipst & CST4325_SPROM_OTP_SEL_MASK)]; 5606 case BCM4322_CHIP_ID: case BCM43221_CHIP_ID: case BCM43231_CHIP_ID: 5607 case BCM4342_CHIP_ID: { 5608 uint8 strap = (sih->chipst & CST4322_SPROM_OTP_SEL_MASK) >> 5609 CST4322_SPROM_OTP_SEL_SHIFT; 5610 5611 return ((strap >= ARRAYSIZE(cis_sel)) ? CIS_DEFAULT : cis_sel[strap]); 5612 5613 } 5614 5615 case BCM43235_CHIP_ID: case BCM43236_CHIP_ID: case BCM43238_CHIP_ID: 5616 case BCM43234_CHIP_ID: { 5617 uint8 strap = (sih->chipst & CST43236_OTP_SEL_MASK) >> 5618 CST43236_OTP_SEL_SHIFT; 5619 return ((strap >= ARRAYSIZE(cis_43236_sel)) ? CIS_DEFAULT : cis_43236_sel[strap]); 5620 } 5621 5622 case BCM4329_CHIP_ID: 5623 return ((sih->chipst & CST4329_SPROM_OTP_SEL_MASK) >= ARRAYSIZE(cis_sel)) ? 5624 CIS_DEFAULT : cis_sel[(sih->chipst & CST4329_SPROM_OTP_SEL_MASK)]; 5625 5626 case BCM4315_CHIP_ID: 5627 5628 return ((sih->chipst & CST4315_SPROM_OTP_SEL_MASK) >= ARRAYSIZE(cis_sel)) ? 5629 CIS_DEFAULT : cis_sel[(sih->chipst & CST4315_SPROM_OTP_SEL_MASK)]; 5630 5631 case BCM4319_CHIP_ID: { 5632 uint cis_sel4319 = ((sih->chipst & CST4319_SPROM_OTP_SEL_MASK) >> 5633 CST4319_SPROM_OTP_SEL_SHIFT); 5634 return (cis_sel4319 >= ARRAYSIZE(cis_sel)) ? CIS_DEFAULT : cis_sel[cis_sel4319]; 5635 } 5636 case BCM4336_CHIP_ID: 5637 case BCM43362_CHIP_ID: { 5638 if (sih->chipst & CST4336_SPROM_PRESENT) 5639 return CIS_SROM; 5640 if (sih->chipst & CST4336_OTP_PRESENT) 5641 return CIS_OTP; 5642 return CIS_DEFAULT; 5643 } 5644 case BCM4330_CHIP_ID: { 5645 if (sih->chipst & CST4330_SPROM_PRESENT) 5646 return CIS_SROM; 5647 if (sih->chipst & CST4330_OTP_PRESENT) 5648 return CIS_OTP; 5649 return CIS_DEFAULT; 5650 } 5651 case BCM43239_CHIP_ID: { 5652 if ((sih->chipst & CST43239_SPROM_MASK) && !(sih->chipst & CST43239_SFLASH_MASK)) 5653 return CIS_SROM; 5654 return CIS_OTP; 5655 } 5656 case BCM4324_CHIP_ID: 5657 { 5658 if ((sih->chipst & CST4324_SPROM_MASK) && !(sih->chipst & CST4324_SFLASH_MASK)) 5659 return CIS_SROM; 5660 return CIS_OTP; 5661 } 5662 case BCM4335_CHIP_ID: 5663 { 5664 if ((sih->chipst & CST4335_SPROM_MASK) && !(sih->chipst & CST4335_SFLASH_MASK)) 5665 return CIS_SROM; 5666 return CIS_OTP; 5667 } 5668 case BCM4350_CHIP_ID: 5669 { 5670 if (sih->chipst & CST4350_SPROM_PRESENT) 5671 return CIS_SROM; 5672 return CIS_OTP; 5673 } 5674 case BCM43237_CHIP_ID: { 5675 uint8 strap = (sih->chipst & CST43237_OTP_SEL_MASK) >> 5676 CST43237_OTP_SEL_SHIFT; 5677 return ((strap >= ARRAYSIZE(cis_43236_sel)) ? CIS_DEFAULT : cis_43236_sel[strap]); 5678 } 5679 case BCM43143_CHIP_ID: { 5680 return CIS_OTP; /* BCM43143 does not support SROM nor OTP strappings */ 5681 } 5682 case BCM43242_CHIP_ID: 5683 case BCM43243_CHIP_ID: 5684 { 5685 return CIS_OTP; /* BCM43242 does not support SPROM */ 5686 } 5687 case BCM4360_CHIP_ID: 5688 case BCM43460_CHIP_ID: 5689 case BCM4352_CHIP_ID: 5690 case BCM43526_CHIP_ID: { 5691 if ((sih->chipst & CST4360_OTP_ENABLED)) 5692 return CIS_OTP; 5693 return CIS_DEFAULT; 5694 } 5695 default: 5696 return CIS_DEFAULT; 5697 } 5698} 5699 5700/** Read/write to OTP to find the FAB manf */ 5701int 5702BCMINITFN(si_otp_fabid)(si_t *sih, uint16 *fabid, bool rw) 5703{ 5704 int error = BCME_OK; 5705 uint offset = 0; 5706 uint16 data, mask = 0, shift = 0; 5707 5708 switch (CHIPID(sih->chip)) { 5709 case BCM4329_CHIP_ID: 5710 /* Bit locations 133-130 */ 5711 if (sih->chiprev >= 3) { 5712 offset = 8; 5713 mask = 0x3c; 5714 shift = 2; 5715 } 5716 break; 5717 case BCM43362_CHIP_ID: 5718 /* Bit locations 134-130 */ 5719 offset = 8; 5720 mask = 0x7c; 5721 shift = 2; 5722 break; 5723 case BCM5356_CHIP_ID: 5724 /* Bit locations 133-130 */ 5725 offset = 8; 5726 mask = 0x3c; 5727 shift = 2; 5728 break; 5729 default: 5730 error = BCME_EPERM; 5731 return error; 5732 } 5733 5734 if (rw == TRUE) { 5735 /* TRUE --> read */ 5736 error = otp_read_word(sih, offset, &data); 5737 if (!error) 5738 *fabid = (data & mask) >> shift; 5739 } else { 5740 data = *fabid; 5741 data = (data << shift) & mask; 5742#ifdef BCMNVRAMW 5743 error = otp_write_word(sih, offset, data); 5744#endif /* BCMNVRAMW */ 5745 } 5746 5747 return error; 5748} 5749 5750uint16 BCMATTACHFN(si_fabid)(si_t *sih) 5751{ 5752 uint32 data; 5753 uint16 fabid = 0; 5754 5755 switch (CHIPID(sih->chip)) { 5756 case BCM4329_CHIP_ID: 5757 case BCM43362_CHIP_ID: 5758 case BCM5356_CHIP_ID: 5759 if (si_otp_fabid(sih, &fabid, TRUE) != BCME_OK) 5760 { 5761 SI_ERROR(("si_fabid: reading fabid from otp failed.\n")); 5762 } 5763 break; 5764 5765 case BCM4330_CHIP_ID: 5766 data = si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, chipcontrol), 5767 0, 0); 5768 fabid = ((data & 0xc0000000) >> 30)+((data & 0x20000000) >> 27); 5769 break; 5770 5771 case BCM4334_CHIP_ID: 5772 data = si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, fabid), 0, 0); 5773 fabid = data & 0xf; 5774 break; 5775 5776 case BCM4324_CHIP_ID: 5777 case BCM4335_CHIP_ID: 5778 case BCM4350_CHIP_ID: 5779 case BCM43143_CHIP_ID: 5780 case BCM43242_CHIP_ID: 5781 case BCM43243_CHIP_ID: 5782 /* intentional fallthrough */ 5783 data = si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, fabid), 0, 0); 5784 fabid = data & 0xf; 5785 break; 5786 5787 default: 5788 break; 5789 } 5790 5791 return fabid; 5792} 5793 5794uint32 BCMATTACHFN(si_get_sromctl)(si_t *sih) 5795{ 5796 chipcregs_t *cc; 5797 uint origidx; 5798 uint32 sromctl; 5799 osl_t *osh; 5800 5801 osh = si_osh(sih); 5802 origidx = si_coreidx(sih); 5803 cc = si_setcoreidx(sih, SI_CC_IDX); 5804 ASSERT((uintptr)cc); 5805 5806 sromctl = R_REG(osh, &cc->sromcontrol); 5807 5808 /* return to the original core */ 5809 si_setcoreidx(sih, origidx); 5810 return sromctl; 5811} 5812 5813int BCMATTACHFN(si_set_sromctl)(si_t *sih, uint32 value) 5814{ 5815 chipcregs_t *cc; 5816 uint origidx; 5817 osl_t *osh; 5818 5819 osh = si_osh(sih); 5820 origidx = si_coreidx(sih); 5821 cc = si_setcoreidx(sih, SI_CC_IDX); 5822 ASSERT((uintptr)cc); 5823 5824 /* get chipcommon rev */ 5825 if (si_corerev(sih) < 32) 5826 return BCME_UNSUPPORTED; 5827 5828 W_REG(osh, &cc->sromcontrol, value); 5829 5830 /* return to the original core */ 5831 si_setcoreidx(sih, origidx); 5832 return BCME_OK; 5833 5834} 5835 5836uint 5837si_core_wrapperreg(si_t *sih, uint32 coreidx, uint32 offset, uint32 mask, uint32 val) 5838{ 5839 uint origidx; 5840 uint ret_val; 5841 5842 origidx = si_coreidx(sih); 5843 5844 si_setcoreidx(sih, coreidx); 5845 5846 ret_val = si_wrapperreg(sih, offset, mask, val); 5847 5848 /* return to the original core */ 5849 si_setcoreidx(sih, origidx); 5850 return ret_val; 5851} 5852 5853#ifdef WLC_LOW 5854/** 5855 * To make sure that, res mask is minimal to save power and also, to indicate 5856 * specifically for 4335 host about the SR logic. 5857 */ 5858void 5859si_update_masks(si_t *sih) 5860{ 5861 si_info_t *sii = SI_INFO(sih); 5862 5863 switch (CHIPID(sih->chip)) { 5864 case BCM4350_CHIP_ID: 5865 if (PMUCTL_ENAB(sih)) 5866 si_pmu_res_minmax_update(sih, sii->osh); 5867 break; 5868 case BCM4335_CHIP_ID: { 5869#if defined(SAVERESTORE) 5870 if (PMUCTL_ENAB(sih)) 5871 si_pmu_res_minmax_update(sih, sii->osh); 5872#endif 5873#if defined(PMU_OPT) 5874 /* set max res mask */ 5875 si_ccreg(sih, MAXRESMASKREG, ~0, 0x7fff3fff); 5876 5877 /* Moved from ucode to driver for 4335 */ 5878 si_ccreg(sih, PMUREG_RESREQ_MASK, ~0, 0x7ffb3e77); 5879#else 5880 si_ccreg(sih, PMUREG_RESREQ_MASK, ~0, 0x7ffbfff); 5881#endif 5882 /* set_sdio_aos_wakeup_mask */ 5883 si_pmu_chipcontrol(sih, CHIPCTRLREG2, 0x01000000, 0x01000000); 5884 5885 /* Enable BBPLL power down */ 5886 si_pmu_chipcontrol(sih, CHIPCTRLREG1, 0x10, 0x10); 5887 5888 /* BBPLL closed loop lock time = 1 (default=4) */ 5889 si_pmu_chipcontrol(sih, CHIPCTRLREG1, 0xf0000, 0x10000); 5890#if defined(PMU_OPT) 5891#if defined(USE_MEMLPLDO) 5892 /* Set MEMLPDO=0.88125V (bits 20:18=0x7) */ 5893 si_pmu_regcontrol(sih, REGCTRLREG4, 0x1c0000, 0x1c0000); 5894#endif 5895 /* Disable BBPLL openloop mode */ 5896 si_pmu_chipcontrol(sih, CHIPCTRLREG1, 0x80, 0x0); 5897 5898 /* 0 LQ clks with pmu-mem-disable-for-sleep */ 5899 si_pmu_chipcontrol(sih, CHIPCTRLREG5, 0x1f00, 0x0); 5900 5901 /* Enable pmu-mem-disable-for-sleep */ 5902 si_pmu_chipcontrol(sih, CHIPCTRLREG5, 0x2000, 0x2000); 5903#if defined(PMU_OPT_REV6) 5904 if ((CHIPREV(sih->chiprev) >= 2)) { 5905 /* mac_res_req_mask for rev6 */ 5906 si_ccreg(sih, PMUREG_RESREQ_MASK, ~0, 0x7ffb3647); 5907 5908 /* Make all "higher" clock requests, request for "lower" clocks also. 5909 * Like HT_AVAIL/MAC_CLK/PHY_CLK etc requests (all "higher" than ALP_AVAIL) 5910 * also requests for ALP_AVAIL (bits 22:20=0x7) 5911 */ 5912 si_pmu_chipcontrol(sih, CHIPCTRLREG6, (0x7 << 20), (0x7 << 20)); 5913 5914 /* Set HQRequired to avoid using LQ clocks (bit 24=0x1) */ 5915 si_pmu_chipcontrol(sih, CHIPCTRLREG6, (1 << 24), (1 << 24)); 5916 5917 /* Start clocks earlier */ 5918 si_pmu_chipcontrol(sih, CHIPCTRLREG6, (1 << 18), (1 << 18)); 5919 } 5920#endif /* defined(PMU_OPT_REV6) */ 5921#endif /* defined(PMU_OPT) */ 5922 } break; 5923 default: 5924 ASSERT(0); 5925 break; 5926 } 5927} 5928 5929void 5930si_force_islanding(si_t *sih, bool enable) 5931{ 5932 switch (CHIPID(sih->chip)) { 5933 case BCM4335_CHIP_ID: { 5934 if (enable) { 5935 /* Turn on the islands */ 5936 si_pmu_chipcontrol(sih, CHIPCTRLREG2, 0x1c0000, 0x0); 5937#if !defined(USE_MEMLPLDO) 5938 /* Force vddm pwrsw always on */ 5939 si_pmu_chipcontrol(sih, CHIPCTRLREG2, 0x100000, 0x100000); 5940#endif 5941 } else { 5942 /* Turn off the islands */ 5943 si_pmu_chipcontrol(sih, CHIPCTRLREG2, 0x3c0000, 0x3c0000); 5944 } 5945 } break; 5946 default: 5947 ASSERT(0); 5948 break; 5949 } 5950} 5951#endif /* WLC_LOW */ 5952 5953/** 5954 * cleanup the hndrte timer from the host when ARM is been halted 5955 * without a chance for ARM cleanup its resources 5956 * If left not cleanup, Intr from a software timer can still 5957 * request HT clk when ARM is halted. 5958 */ 5959uint32 5960si_pmu_res_req_timer_clr(si_t *sih) 5961{ 5962 uint32 mask; 5963 5964 mask = PRRT_REQ_ACTIVE | PRRT_INTEN; 5965 if (CHIPID(sih->chip) != BCM4328_CHIP_ID) 5966 mask <<= 14; 5967 /* clear mask bits */ 5968 si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, res_req_timer), mask, 0); 5969 /* readback to ensure write completes */ 5970 return si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, res_req_timer), 0, 0); 5971} 5972 5973/** turn on/off rfldo */ 5974void 5975si_pmu_rfldo(si_t *sih, bool on) 5976{ 5977 switch (CHIPID(sih->chip)) { 5978 case BCM4360_CHIP_ID: 5979 case BCM4352_CHIP_ID: 5980 case BCM43526_CHIP_ID: { 5981 si_pmu_regcontrol(sih, 0, RCTRL4360_RFLDO_PWR_DOWN, 5982 on ? 0 : RCTRL4360_RFLDO_PWR_DOWN); 5983 break; 5984 } 5985 default: 5986 ASSERT(0); 5987 break; 5988 } 5989} 5990 5991uint 5992si_chipid_override(si_t *sih) 5993{ 5994 uint chipid = 0; 5995 switch (CHIPID(sih->chip)) { 5996 case BCM4335_CHIP_ID: 5997 if (CHIPREV(sih->chip) == 2) { 5998 chipid = BCM4339_CHIP_ID; 5999 } else { 6000 chipid = sih->chip; 6001 } 6002 break; 6003 default: 6004 chipid = sih->chip; 6005 break; 6006 } 6007 return chipid; 6008} 6009 6010uint 6011si_chiprev_override(si_t *sih) 6012{ 6013 uint chiprev = 0; 6014 switch (CHIPID(sih->chip)) { 6015 case BCM4335_CHIP_ID: 6016 if (CHIPREV(sih->chip) == 2) { 6017 chiprev = 1; 6018 } else { 6019 chiprev = sih->chiprev; 6020 } 6021 break; 6022 default: 6023 chiprev = sih->chiprev; 6024 break; 6025 } 6026 return chiprev; 6027} 6028 6029#ifdef SURVIVE_PERST_ENAB 6030static uint32 6031si_pcie_survive_perst(si_t *sih, uint32 mask, uint32 val) 6032{ 6033 si_info_t *sii; 6034 6035 sii = SI_INFO(sih); 6036 6037 if (!PCIE(sii)) 6038 return (0); 6039 6040 return pcie_survive_perst(sii->pch, mask, val); 6041} 6042 6043static void 6044si_watchdog_reset(si_t *sih) 6045{ 6046 si_info_t *sii = SI_INFO(sih); 6047 chipcregs_t *cc; 6048 uint32 origidx, i; 6049 6050 origidx = si_coreidx(sih); 6051 cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0); 6052 /* issue a watchdog reset */ 6053 W_REG(sii->osh, &cc->pmuwatchdog, 2); 6054 /* do busy wait for 20ms */ 6055 for (i = 0; i < 2000; i++) { 6056 OSL_DELAY(10); 6057 } 6058 si_setcoreidx(sih, origidx); 6059 BCM_REFERENCE(sii); 6060} 6061#endif /* SURVIVE_PERST_ENAB */ 6062 6063void 6064si_survive_perst_war(si_t *sih, bool reset, uint32 sperst_mask, uint32 sperst_val) 6065{ 6066#ifdef SURVIVE_PERST_ENAB 6067 if ((BUSTYPE(sih->bustype) != PCI_BUS) || 6068 ((CHIPID(sih->chip) != BCM4360_CHIP_ID) && 6069 (CHIPID(sih->chip) != BCM4352_CHIP_ID))) 6070 return; 6071 if (reset) { 6072 si_info_t *sii = SI_INFO(sih); 6073 uint32 bar0win, bar0win_after; 6074 6075 /* save the bar0win */ 6076 bar0win = OSL_PCI_READ_CONFIG(sii->osh, PCI_BAR0_WIN, sizeof(uint32)); 6077 6078 si_watchdog_reset(sih); 6079 6080 bar0win_after = OSL_PCI_READ_CONFIG(sii->osh, PCI_BAR0_WIN, sizeof(uint32)); 6081 if (bar0win_after != bar0win) { 6082 SI_ERROR(("%s: bar0win before %08x, bar0win after %08x\n", 6083 __FUNCTION__, bar0win, bar0win_after)); 6084 OSL_PCI_WRITE_CONFIG(sii->osh, PCI_BAR0_WIN, sizeof(uint32), bar0win); 6085 } 6086 } 6087 if (sperst_mask) { 6088 /* enable survive perst */ 6089 si_pcie_survive_perst(sih, sperst_mask, sperst_val); 6090 } 6091#endif /* SURVIVE_PERST_ENAB */ 6092} 6093 6094void 6095si_pcie_ltr_war(si_t *sih) 6096{ 6097 if (BUSTYPE(sih->bustype) == PCI_BUS) { 6098 if ((sih->buscoretype == PCIE2_CORE_ID) && 6099 (sih->buscorerev == 1)) { 6100 if (!si_pcieltrenable(sih, 0, 0)) { 6101 uint origidx = si_coreidx(sih); 6102 si_setcore(sih, D11_CORE_ID, 0); 6103 6104 si_wrapperreg(sih, AI_OOBSELOUTD30, ~0, 0x2848180); 6105 si_wrapperreg(sih, AI_OOBSELOUTD74, ~0, 0x3); 6106 6107 si_setcoreidx(sih, origidx); 6108 } else { 6109 uint origidx = si_coreidx(sih); 6110 si_setcore(sih, D11_CORE_ID, 0); 6111 6112 si_wrapperreg(sih, AI_OOBSELOUTD30, ~0, 0x02838280); 6113 si_wrapperreg(sih, AI_OOBSELOUTD74, ~0, 0x3); 6114 6115 si_setcoreidx(sih, origidx); 6116 } 6117 } 6118 } 6119} 6120 6121#ifdef WLC_LOW 6122uint 6123si_corereg_ifup(si_t *sih, uint core_id, uint regoff, uint mask, uint val) 6124{ 6125 bool isup; 6126 void *regs; 6127 uint origidx, ret_val, coreidx; 6128 6129 /* Remember original core before switch to chipc */ 6130 origidx = si_coreidx(sih); 6131 regs = si_setcore(sih, core_id, 0); 6132 ASSERT(regs != NULL); 6133 6134 coreidx = si_coreidx(sih); 6135 6136 isup = si_iscoreup(sih); 6137 if (isup == TRUE) { 6138 ret_val = si_corereg(sih, coreidx, regoff, mask, val); 6139 } else { 6140 ret_val = 0; 6141 } 6142 6143 /* Return to original core */ 6144 si_setcoreidx(sih, origidx); 6145 return ret_val; 6146} 6147 6148void 6149si_lowpwr_opt(si_t *sih) 6150{ 6151 uint hosti = 0; 6152 uint origidx, mask, val; 6153 void *regs; 6154 6155 /* 4335 chip (all revision) related changes */ 6156 if (CHIPID(sih->chip) == BCM4335_CHIP_ID) { 6157 6158 /* Remember original core before switch to new core */ 6159 origidx = si_coreidx(sih); 6160 6161 /* Find the current host interface */ 6162 if (CST4335_CHIPMODE_USB20D(sih->chipst)) 6163 hosti = CHIP_HOSTIF_USBMODE; 6164 else if (CST4335_CHIPMODE_SDIOD(sih->chipst)) 6165 hosti = CHIP_HOSTIF_SDIOMODE; 6166 else if (CST4335_CHIPMODE_PCIE(sih->chipst)) 6167 hosti = CHIP_HOSTIF_PCIEMODE; 6168 6169 regs = si_setcore(sih, CC_CORE_ID, 0); 6170 ASSERT(regs != NULL); 6171 /* disable usb app clk */ 6172 /* Can be done any time. If it is not USB, then do it. In case */ 6173 /* of USB, do not write it */ 6174 if (hosti != CHIP_HOSTIF_USBMODE) { 6175 si_pmu_chipcontrol(sih, PMU_CHIPCTL5, (1 << USBAPP_CLK_BIT), 0); 6176 } 6177 /* disable pcie clks */ 6178 if (hosti != CHIP_HOSTIF_PCIEMODE) { 6179 si_pmu_chipcontrol(sih, PMU_CHIPCTL5, (1 << PCIE_CLK_BIT), 0); 6180 } 6181 6182 /* disable armcr4 debug clk */ 6183 /* Can be done anytime as long as driver is functional. */ 6184 /* In TCL, dhalt commands needs to change to undo this */ 6185 si_pmu_chipcontrol(sih, PMU_CHIPCTL5, (1 << ARMCR4_DBG_CLK_BIT), 0); 6186 /* Power down unused BBPLL ch-6(pcie_tl_clk) and ch-5(sample-sync-clk), */ 6187 /* valid in all modes, ch-5 needs to be reenabled for sample-capture */ 6188 /* this needs to be done in the pmu init path, at the beginning. Should not be */ 6189 /* a pcie driver. Enable the sample-sync-clk in the sample capture function */ 6190 mask = (0x1 << SAMPLE_SYNC_CLK_BIT) | (0x1 << PCIE_TL_CLK_BIT); 6191 val = (0x1 << SAMPLE_SYNC_CLK_BIT) | (0x1 << PCIE_TL_CLK_BIT); 6192 si_pmu_pllcontrol(sih, PMU1_PLL0_PLLCTL0, mask, val); 6193 si_pmu_pllupd(sih); 6194 6195 /* 4335C0 specific changes */ 6196 if (CHIPREV(sih->chiprev) >= 2) { 6197 /* Enable mem clk gating */ 6198 mask = (0x1 << MEM_CLK_GATE_BIT); 6199 val = (0x1 << MEM_CLK_GATE_BIT); 6200 6201 /* d11 core neets to be out of reset */ 6202 si_corereg_ifup(sih, D11_CORE_ID, SI_PWR_CTL_ST, mask, val); 6203 6204#if defined(__ARM_ARCH_7R__) 6205 /* ARM needs to be out of reset. It is, if driver is running */ 6206 si_corereg_ifup(sih, ARMCR4_CORE_ID, SI_PWR_CTL_ST, mask, val); 6207#endif /* __ARM_ARCH_7R__ */ 6208 6209 /* SDIO needs to be out of reset. In the wl up path, check if SDIO is up, */ 6210 /* only then do the register write */ 6211 si_corereg_ifup(sih, SDIOD_CORE_ID, SI_PWR_CTL_ST, mask, val); 6212 6213 /* enable clk gating for usb20d core */ 6214 si_corereg_ifup(sih, USB20D_CORE_ID, SI_PWR_CTL_ST, mask, val); 6215 6216 /* enable clk gating for pciegen2 core */ 6217 si_corereg_ifup(sih, PCIE2_CORE_ID, SI_PWR_CTL_ST, mask, val); 6218 6219 /* enable gci_clk gating */ 6220 /* GCI is always up. Can be done any time. */ 6221 mask = (0x1<< GCI_CLK_GATE_BIT); 6222 val = 0; 6223 si_corereg_ifup(sih, CC_CORE_ID, 0xc0c, mask, val); 6224 6225 /* Set HQRequired */ 6226 /* This can be done anytime */ 6227 mask = (0x1 << HQ_REQ_BIT); 6228 val = (0x1 << HQ_REQ_BIT); 6229 si_pmu_chipcontrol(sih, PMU_CHIPCTL6, mask, val); 6230 6231 /* Disable PLL div2 outputs, valid in all modes */ 6232 /* make sure AVB clk in mac is not used, lq_clk is not used */ 6233 /* (set HQRequired) */ 6234 /* Initialize the tcl, load the driver, do "checkclk ccs all" in tcl. */ 6235 /* if AVB request is zero, then this bit can be set statically */ 6236 /* in the driver */ 6237 si_pmu_chipcontrol(sih, PMU_CHIPCTL6, PLL_DIV2_MASK, PLL_DIV2_DIS_OP); 6238 } 6239 6240 /* Return to original core */ 6241 si_setcoreidx(sih, origidx); 6242 } 6243} 6244#endif /* WLC_LOW */ 6245 6246#if defined(WLTEST) 6247/* access internal jtag user reg */ 6248#define JTAGM_RETRIES 10000 /* # of retries for Jtag master */ 6249#define LV_IR_SIZE 32 6250#define LV_DR_SIZE 32 6251#define LV_BASE 0xfe03ff3a 6252#define LV_REG_MASK 0x01f00000 6253#define LV_REG_SHIFT 20 6254#define LV_RO 0x00080000 6255#define LV_USER_BASE 0x10 6256#define LV_REG_IR(reg, base) (base | (((reg) << LV_REG_SHIFT) & LV_REG_MASK)) 6257 6258static uint32 6259jtagm_rreg(osl_t *osh, chipcregs_t *cc, uint reg) 6260{ 6261 switch (reg) { 6262 case CC_JTAGCMD: 6263 return R_REG(osh, &cc->jtagcmd); 6264 case CC_JTAGIR: 6265 return R_REG(osh, &cc->jtagir); 6266 case CC_JTAGDR: 6267 return R_REG(osh, &cc->jtagdr); 6268 case CC_JTAGCTRL: 6269 return R_REG(osh, &cc->jtagctrl); 6270 default: 6271 return 0; 6272 } 6273 return 0; 6274} 6275 6276static void 6277jtagm_wreg(osl_t *osh, chipcregs_t *cc, uint reg, uint32 data) 6278{ 6279 switch (reg) { 6280 case CC_JTAGCMD: 6281 W_REG(osh, &cc->jtagcmd, data); 6282 break; 6283 case CC_JTAGIR: 6284 W_REG(osh, &cc->jtagir, data); 6285 break; 6286 case CC_JTAGDR: 6287 W_REG(osh, &cc->jtagdr, data); 6288 break; 6289 case CC_JTAGCTRL: 6290 W_REG(osh, &cc->jtagctrl, data); 6291 break; 6292 default: 6293 return; 6294 } 6295} 6296 6297static uint 6298jtagm_scmd(si_t *sih, uint ir, uint irw, uint dr, uint drw) 6299{ 6300 uint32 data, i; 6301 chipcregs_t *cc; 6302 uint origidx; 6303 osl_t *osh; 6304 6305 osh = si_osh(sih); 6306 origidx = si_coreidx(sih); 6307 cc = si_setcoreidx(sih, SI_CC_IDX); 6308 ASSERT((uintptr)cc); 6309 6310 data = jtagm_rreg(osh, cc, CC_JTAGCTRL); 6311 data &= ~JCTRL_EXT_EN; /* ExternalEnable, clear it to access internal TAP */ 6312 data |= JCTRL_EN; /* JtagEnable (JE) */ 6313 jtagm_wreg(osh, cc, CC_JTAGCTRL, data); 6314 6315 jtagm_wreg(osh, cc, CC_JTAGIR, ir); 6316 jtagm_wreg(osh, cc, CC_JTAGDR, dr); 6317 jtagm_wreg(osh, cc, CC_JTAGCMD, 6318 (JCMD_START | JCMD_ACC_IRDR | ((irw - 1) << JCMD_IRW_SHIFT) | (drw - 1))); 6319 6320 i = 0; 6321 while ((i < JTAGM_RETRIES) && 6322 ((jtagm_rreg(osh, cc, CC_JTAGCMD) & JCMD_BUSY) == JCMD_BUSY)) { 6323 OSL_DELAY(1); 6324 i++; 6325 } 6326 6327 if (i == JTAGM_RETRIES) { 6328 data = 0xffffffff; 6329 ASSERT(0); 6330 } 6331 else 6332 data = jtagm_rreg(osh, cc, CC_JTAGDR); 6333 6334 /* return to the original core */ 6335 si_setcoreidx(sih, origidx); 6336 6337 return data; 6338} 6339 6340uint 6341si_jtag_ureg_read(si_t *sih, uint num) 6342{ 6343 SI_MSG(("si_jtag_ureg_read %d\n", num)); 6344 return jtagm_scmd(sih, LV_REG_IR(LV_USER_BASE + num, LV_BASE) | LV_RO, 32, 0, 32); 6345} 6346 6347void 6348si_jtag_ureg_write(si_t *sih, uint num, uint data) 6349{ 6350 SI_MSG(("si_jtag_ureg_write %d %08x\n", num, data)); 6351 jtagm_scmd(sih, LV_REG_IR(LV_USER_BASE + num, LV_BASE), 32, data, 32); 6352} 6353#endif 6354 6355#ifdef BBPLL_WAR 6356uint 6357si_bbpll_war(si_t *sih, uint state) 6358{ 6359 uint32 data; 6360 6361 if ((CHIPID(sih->chip) != BCM4360_CHIP_ID) || (CHIPREV(sih->chiprev) > 3)) 6362 return 0; 6363 6364 /* if ovr bit is set, don't apply WAR */ 6365 if ((si_jtag_ureg_read(sih, 3) & 0x00010000) != 0) { 6366 /* Check if PLL still Lock */ 6367 /* ccreg 0x2c Bit[11] = 1 ; Assert if it is not */ 6368 data = si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, chipstatus), 0, 0); 6369 ASSERT(data & CST4360_BBPLL_LOCK); 6370 6371 /* set MaxRsrcMax */ 6372 si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, max_res_mask), ~0, 0x1ff); 6373 /* Wait 200us . */ 6374 OSL_DELAY(200); 6375 return 1; 6376 } 6377 6378 /* pll up seq on Up Path (state 0) and Down Path (state 1) */ 6379 switch (state) { 6380 case 0: 6381 /* Write BBPLL Defaults (mdiv, ndiv, frac). */ 6382 si_jtag_ureg_write(sih, 5, 0x06060c03); 6383 si_jtag_ureg_write(sih, 6, 0x16180606); 6384 si_jtag_ureg_write(sih, 7, 0x0000100e); 6385 ASSERT(si_jtag_ureg_read(sih, 5) == 0x06060c03); 6386 ASSERT(si_jtag_ureg_read(sih, 6) == 0x16180606); 6387 ASSERT(si_jtag_ureg_read(sih, 7) == 0x0000100e); 6388 6389 /* bbpll_pwrdn 1 , areset 1, dreset 1, ovr 0 */ 6390 si_jtag_ureg_write(sih, 3, 0x000c0010); 6391 ASSERT(si_jtag_ureg_read(sih, 3) == 0x000c0010); 6392 6393 /* bbpll_pwrdn 1 , areset 1, dreset 1, ovr 1 */ 6394 si_jtag_ureg_write(sih, 3, 0x000d0010); 6395 ASSERT(si_jtag_ureg_read(sih, 3) == 0x000d0010); 6396 6397 /* bbpll_pwrdn 0, areset 1, dreset 1 , ovr 1 */ 6398 si_jtag_ureg_write(sih, 3, 0x000d0000); 6399 ASSERT(si_jtag_ureg_read(sih, 3) == 0x000d0000); 6400 6401 /* Wait 30us */ 6402 OSL_DELAY(30); 6403 6404 /* bbpll_pwrdn 0, areset 0, dreset 1 , ovr 1 */ 6405 si_jtag_ureg_write(sih, 3, 0x00090000); 6406 ASSERT(si_jtag_ureg_read(sih, 3) == 0x00090000); 6407 6408 /* Wait 100 us */ 6409 OSL_DELAY(100); 6410 6411 /* Check if PLL Lock */ 6412 /* ccreg 0x2c Bit[11] = 1 ; Assert if it is not */ 6413 data = si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, chipstatus), 0, 0); 6414 ASSERT(data & CST4360_BBPLL_LOCK); 6415 6416 /* take out of dreset; bbpll_pwrdn 0, areset 0, dreset 0 , ovr 1 */ 6417 si_jtag_ureg_write(sih, 3, 0x00010000); 6418 ASSERT(si_jtag_ureg_read(sih, 3) == 0x00010000); 6419 6420 /* set MaxRsrcMax */ 6421 si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, max_res_mask), ~0, 0x1ff); 6422 6423 /* Wait 200us . */ 6424 OSL_DELAY(200); 6425 break; 6426 case 1: 6427 si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, min_res_mask), ~0, 0x13b); 6428 break; 6429 default: 6430 ASSERT(0); 6431 } 6432 return 1; 6433} 6434#endif /* BBPLL_WAR */ 6435