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