2 * Copyright (c) 2010 Broadcom Corporation
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
26 #include <pcie_core.h>
38 #include <sbsdpcmdev.h>
43 /* this file now contains only definitions for sb functions, only necessary
44 *for devices using Sonics backplanes (bcm4329)
47 /* if an amba SDIO device is supported, please further restrict the inclusion
51 #include "siutils_priv.h"
54 /* local prototypes */
55 static si_info_t *si_doattach(si_info_t *sii, uint devid, osl_t *osh,
56 void *regs, uint bustype, void *sdh, char **vars,
58 static bool si_buscore_prep(si_info_t *sii, uint bustype, uint devid,
60 static bool si_buscore_setup(si_info_t *sii, chipcregs_t *cc, uint bustype,
61 uint32 savewin, uint *origidx, void *regs);
62 static void si_nvram_process(si_info_t *sii, char *pvars);
64 /* dev path concatenation util */
65 static char *si_devpathvar(si_t *sih, char *var, int len, const char *name);
66 static bool _si_clkctl_cc(si_info_t *sii, uint mode);
67 static bool si_ispcie(si_info_t *sii);
68 static uint BCMINITFN(socram_banksize) (si_info_t *sii, sbsocramregs_t *r,
69 uint8 idx, uint8 mtype);
71 /* global variable to indicate reservation/release of gpio's */
72 static uint32 si_gpioreservation = 0;
74 /* global flag to prevent shared resources from being initialized multiple times in si_attach() */
77 * Allocate a si handle.
78 * devid - pci device id (used to determine chip#)
79 * osh - opaque OS handle
80 * regs - virtual address of initial core registers
81 * bustype - pci/sb/sdio/etc
82 * vars - pointer to a pointer area for "environment" variables
83 * varsz - pointer to int to return the size of the vars
85 si_t *BCMATTACHFN(si_attach) (uint devid, osl_t *osh, void *regs,
86 uint bustype, void *sdh, char **vars,
91 if ((sii = MALLOC(osh, sizeof(si_info_t))) == NULL) {
92 SI_ERROR(("si_attach: malloc failed! malloced %d bytes\n",
97 if (si_doattach(sii, devid, osh, regs, bustype, sdh, vars, varsz) ==
99 MFREE(osh, sii, sizeof(si_info_t));
102 sii->vars = vars ? *vars : NULL;
103 sii->varsz = varsz ? *varsz : 0;
108 /* global kernel resource */
109 static si_info_t ksii;
111 static uint32 wd_msticks; /* watchdog timer ticks normalized to ms */
114 BCMATTACHFN(si_buscore_prep) (si_info_t *sii, uint bustype, uint devid,
117 /* kludge to enable the clock on the 4306 which lacks a slowclock */
118 if (BUSTYPE(bustype) == PCI_BUS && !si_ispcie(sii))
119 si_clkctl_xtal(&sii->pub, XTAL | PLL, ON);
122 if (BUSTYPE(bustype) == SDIO_BUS) {
126 /* Try forcing SDIO core to do ALPAvail request only */
127 clkset = SBSDIO_FORCE_HW_CLKREQ_OFF | SBSDIO_ALP_AVAIL_REQ;
128 bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR,
133 /* If register supported, wait for ALPAvail and then force ALP */
135 bcmsdh_cfg_read(sdh, SDIO_FUNC_1,
136 SBSDIO_FUNC1_CHIPCLKCSR, NULL);
137 if ((clkval & ~SBSDIO_AVBITS) == clkset) {
139 bcmsdh_cfg_read(sdh, SDIO_FUNC_1,
140 SBSDIO_FUNC1_CHIPCLKCSR,
142 !SBSDIO_ALPAV(clkval)),
143 PMU_MAX_TRANSITION_DLY);
144 if (!SBSDIO_ALPAV(clkval)) {
145 SI_ERROR(("timeout on ALPAV wait, clkval 0x%02x\n", clkval));
149 SBSDIO_FORCE_HW_CLKREQ_OFF |
151 bcmsdh_cfg_write(sdh, SDIO_FUNC_1,
152 SBSDIO_FUNC1_CHIPCLKCSR,
158 /* Also, disable the extra SDIO pull-ups */
159 bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_SDIOPULLUP, 0,
162 #endif /* defined(BCMSDIO) */
168 BCMATTACHFN(si_buscore_setup) (si_info_t *sii, chipcregs_t *cc, uint bustype,
169 uint32 savewin, uint *origidx, void *regs) {
172 uint pciidx, pcieidx, pcirev, pcierev;
174 cc = si_setcoreidx(&sii->pub, SI_CC_IDX);
175 ASSERT((uintptr) cc);
177 /* get chipcommon rev */
178 sii->pub.ccrev = (int)si_corerev(&sii->pub);
180 /* get chipcommon chipstatus */
181 if (sii->pub.ccrev >= 11)
182 sii->pub.chipst = R_REG(sii->osh, &cc->chipstatus);
184 /* get chipcommon capabilites */
185 sii->pub.cccaps = R_REG(sii->osh, &cc->capabilities);
186 /* get chipcommon extended capabilities */
188 if (sii->pub.ccrev >= 35)
189 sii->pub.cccaps_ext = R_REG(sii->osh, &cc->capabilities_ext);
191 /* get pmu rev and caps */
192 if (sii->pub.cccaps & CC_CAP_PMU) {
193 sii->pub.pmucaps = R_REG(sii->osh, &cc->pmucapabilities);
194 sii->pub.pmurev = sii->pub.pmucaps & PCAP_REV_MASK;
198 SI_MSG(("Chipc: rev %d, caps 0x%x, chipst 0x%x pmurev %d, pmucaps 0x%x\n",
199 sii->pub.ccrev, sii->pub.cccaps, sii->pub.chipst, sii->pub.pmurev,
203 /* figure out bus/orignal core idx */
204 sii->pub.buscoretype = NODEV_CORE_ID;
205 sii->pub.buscorerev = NOREV;
206 sii->pub.buscoreidx = BADIDX;
209 pcirev = pcierev = NOREV;
210 pciidx = pcieidx = BADIDX;
212 for (i = 0; i < sii->numcores; i++) {
215 si_setcoreidx(&sii->pub, i);
216 cid = si_coreid(&sii->pub);
217 crev = si_corerev(&sii->pub);
219 /* Display cores found */
220 SI_VMSG(("CORE[%d]: id 0x%x rev %d base 0x%x regs 0x%p\n",
221 i, cid, crev, sii->coresba[i], sii->regs[i]));
223 if (BUSTYPE(bustype) == PCI_BUS) {
224 if (cid == PCI_CORE_ID) {
228 } else if (cid == PCIE_CORE_ID) {
235 else if (((BUSTYPE(bustype) == SDIO_BUS) ||
236 (BUSTYPE(bustype) == SPI_BUS)) &&
237 ((cid == PCMCIA_CORE_ID) || (cid == SDIOD_CORE_ID))) {
238 sii->pub.buscorerev = crev;
239 sii->pub.buscoretype = cid;
240 sii->pub.buscoreidx = i;
244 /* find the core idx before entering this func. */
245 if ((savewin && (savewin == sii->coresba[i])) ||
246 (regs == sii->regs[i]))
257 sii->pub.buscoretype = PCI_CORE_ID;
258 sii->pub.buscorerev = pcirev;
259 sii->pub.buscoreidx = pciidx;
261 sii->pub.buscoretype = PCIE_CORE_ID;
262 sii->pub.buscorerev = pcierev;
263 sii->pub.buscoreidx = pcieidx;
266 SI_VMSG(("Buscore id/type/rev %d/0x%x/%d\n", sii->pub.buscoreidx,
267 sii->pub.buscoretype, sii->pub.buscorerev));
269 /* fixup necessary chip/core configurations */
270 if (BUSTYPE(sii->pub.bustype) == PCI_BUS) {
274 (void *)(uintptr) pcicore_init(&sii->pub,
281 if (si_pci_fixcfg(&sii->pub)) {
282 SI_ERROR(("si_doattach: sb_pci_fixcfg failed\n"));
287 /* return to the original core */
288 si_setcoreidx(&sii->pub, *origidx);
293 static void BCMATTACHFN(si_nvram_process) (si_info_t *sii, char *pvars)
297 /* get boardtype and boardrev */
298 switch (BUSTYPE(sii->pub.bustype)) {
300 /* do a pci config read to get subsystem id and subvendor id */
301 w = OSL_PCI_READ_CONFIG(sii->osh, PCI_CFG_SVID, sizeof(uint32));
302 /* Let nvram variables override subsystem Vend/ID */
303 if ((sii->pub.boardvendor =
304 (uint16) si_getdevpathintvar(&sii->pub, "boardvendor"))
306 sii->pub.boardvendor = w & 0xffff;
308 SI_ERROR(("Overriding boardvendor: 0x%x instead of 0x%x\n", sii->pub.boardvendor, w & 0xffff));
309 if ((sii->pub.boardtype =
310 (uint16) si_getdevpathintvar(&sii->pub, "boardtype"))
312 sii->pub.boardtype = (w >> 16) & 0xffff;
314 SI_ERROR(("Overriding boardtype: 0x%x instead of 0x%x\n", sii->pub.boardtype, (w >> 16) & 0xffff));
320 sii->pub.boardvendor = getintvar(pvars, "manfid");
321 sii->pub.boardtype = getintvar(pvars, "prodid");
326 sii->pub.boardvendor = VENDOR_BROADCOM;
327 sii->pub.boardtype = SPI_BOARD;
333 sii->pub.boardvendor = VENDOR_BROADCOM;
335 || ((sii->pub.boardtype = getintvar(pvars, "prodid")) == 0))
336 if ((sii->pub.boardtype =
337 getintvar(NULL, "boardtype")) == 0)
338 sii->pub.boardtype = 0xffff;
342 if (sii->pub.boardtype == 0) {
343 SI_ERROR(("si_doattach: unknown board type\n"));
344 ASSERT(sii->pub.boardtype);
347 sii->pub.boardflags = getintvar(pvars, "boardflags");
350 /* this is will make Sonics calls directly, since Sonics is no longer supported in the Si abstraction */
351 /* this has been customized for the bcm 4329 ONLY */
353 static si_info_t *BCMATTACHFN(si_doattach) (si_info_t *sii, uint devid,
354 osl_t *osh, void *regs,
355 uint bustype, void *sdh,
356 char **vars, uint *varsz) {
357 struct si_pub *sih = &sii->pub;
363 ASSERT(GOODREGS(regs));
365 bzero((uchar *) sii, sizeof(si_info_t));
369 sih->buscoreidx = BADIDX;
375 /* find Chipcommon address */
376 cc = (chipcregs_t *) sii->curmap;
377 sih->bustype = bustype;
379 if (bustype != BUSTYPE(bustype)) {
380 SI_ERROR(("si_doattach: bus type %d does not match configured bus type %d\n", bustype, BUSTYPE(bustype)));
384 /* bus/core/clk setup for register access */
385 if (!si_buscore_prep(sii, bustype, devid, sdh)) {
386 SI_ERROR(("si_doattach: si_core_clk_prep failed %d\n",
391 /* ChipID recognition.
392 * We assume we can read chipid at offset 0 from the regs arg.
393 * If we add other chiptypes (or if we need to support old sdio hosts w/o chipcommon),
394 * some way of recognizing them needs to be added here.
396 w = R_REG(osh, &cc->chipid);
397 sih->socitype = (w & CID_TYPE_MASK) >> CID_TYPE_SHIFT;
398 /* Might as wll fill in chip id rev & pkg */
399 sih->chip = w & CID_ID_MASK;
400 sih->chiprev = (w & CID_REV_MASK) >> CID_REV_SHIFT;
401 sih->chippkg = (w & CID_PKG_MASK) >> CID_PKG_SHIFT;
403 if ((CHIPID(sih->chip) == BCM4329_CHIP_ID) && (sih->chiprev == 0) &&
404 (sih->chippkg != BCM4329_289PIN_PKG_ID)) {
405 sih->chippkg = BCM4329_182PIN_PKG_ID;
407 sih->issim = IS_SIM(sih->chippkg);
410 /* SI_MSG(("Found chip type SB (0x%08x)\n", w)); */
411 sb_scan(&sii->pub, regs, devid);
413 /* no cores found, bail out */
414 if (sii->numcores == 0) {
415 SI_ERROR(("si_doattach: could not find any cores\n"));
418 /* bus/core/clk setup */
420 if (!si_buscore_setup(sii, cc, bustype, savewin, &origidx, regs)) {
421 SI_ERROR(("si_doattach: si_buscore_setup failed\n"));
425 /* Init nvram from flash if it exists */
426 nvram_init((void *)&(sii->pub));
428 /* Init nvram from sprom/otp if they exist */
430 (&sii->pub, BUSTYPE(bustype), regs, sii->osh, vars, varsz)) {
431 SI_ERROR(("si_doattach: srom_var_init failed: bad srom\n"));
434 pvars = vars ? *vars : NULL;
435 si_nvram_process(sii, pvars);
437 /* === NVRAM, clock is ready === */
439 cc = (chipcregs_t *) si_setcore(sih, CC_CORE_ID, 0);
440 W_REG(osh, &cc->gpiopullup, 0);
441 W_REG(osh, &cc->gpiopulldown, 0);
442 sb_setcoreidx(sih, origidx);
444 /* PMU specific initializations */
445 if (PMUCTL_ENAB(sih)) {
447 si_pmu_init(sih, sii->osh);
448 si_pmu_chip_init(sih, sii->osh);
449 xtalfreq = getintvar(pvars, "xtalfreq");
450 /* If xtalfreq var not available, try to measure it */
452 xtalfreq = si_pmu_measure_alpclk(sih, sii->osh);
453 si_pmu_pll_init(sih, sii->osh, xtalfreq);
454 si_pmu_res_init(sih, sii->osh);
455 si_pmu_swreg_init(sih, sii->osh);
458 /* setup the GPIO based LED powersave register */
459 if ((w = getintvar(pvars, "leddc")) == 0)
460 w = DEFAULT_GPIOTIMERVAL;
461 sb_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, gpiotimerval), ~0, w);
464 /* clear any previous epidiag-induced target abort */
465 sb_taclear(sih, FALSE);
475 static si_info_t *BCMATTACHFN(si_doattach) (si_info_t *sii, uint devid,
476 osl_t *osh, void *regs,
477 uint bustype, void *sdh,
478 char **vars, uint *varsz) {
479 struct si_pub *sih = &sii->pub;
485 ASSERT(GOODREGS(regs));
487 bzero((uchar *) sii, sizeof(si_info_t));
491 sih->buscoreidx = BADIDX;
497 /* check to see if we are a si core mimic'ing a pci core */
498 if ((bustype == PCI_BUS) &&
499 (OSL_PCI_READ_CONFIG(sii->osh, PCI_SPROM_CONTROL, sizeof(uint32)) ==
501 SI_ERROR(("%s: incoming bus is PCI but it's a lie, switching to SI " "devid:0x%x\n", __func__, devid));
505 /* find Chipcommon address */
506 if (bustype == PCI_BUS) {
508 OSL_PCI_READ_CONFIG(sii->osh, PCI_BAR0_WIN, sizeof(uint32));
509 if (!GOODCOREADDR(savewin, SI_ENUM_BASE))
510 savewin = SI_ENUM_BASE;
511 OSL_PCI_WRITE_CONFIG(sii->osh, PCI_BAR0_WIN, 4, SI_ENUM_BASE);
512 cc = (chipcregs_t *) regs;
514 cc = (chipcregs_t *) REG_MAP(SI_ENUM_BASE, SI_CORE_SIZE);
517 sih->bustype = bustype;
518 if (bustype != BUSTYPE(bustype)) {
519 SI_ERROR(("si_doattach: bus type %d does not match configured bus type %d\n", bustype, BUSTYPE(bustype)));
523 /* bus/core/clk setup for register access */
524 if (!si_buscore_prep(sii, bustype, devid, sdh)) {
525 SI_ERROR(("si_doattach: si_core_clk_prep failed %d\n",
530 /* ChipID recognition.
531 * We assume we can read chipid at offset 0 from the regs arg.
532 * If we add other chiptypes (or if we need to support old sdio hosts w/o chipcommon),
533 * some way of recognizing them needs to be added here.
535 w = R_REG(osh, &cc->chipid);
536 sih->socitype = (w & CID_TYPE_MASK) >> CID_TYPE_SHIFT;
537 /* Might as wll fill in chip id rev & pkg */
538 sih->chip = w & CID_ID_MASK;
539 sih->chiprev = (w & CID_REV_MASK) >> CID_REV_SHIFT;
540 sih->chippkg = (w & CID_PKG_MASK) >> CID_PKG_SHIFT;
542 sih->issim = IS_SIM(sih->chippkg);
545 if (CHIPTYPE(sii->pub.socitype) == SOCI_AI) {
546 SI_MSG(("Found chip type AI (0x%08x)\n", w));
547 /* pass chipc address instead of original core base */
548 ai_scan(&sii->pub, (void *)(uintptr) cc, devid);
550 SI_ERROR(("Found chip of unknown type (0x%08x)\n", w));
553 /* no cores found, bail out */
554 if (sii->numcores == 0) {
555 SI_ERROR(("si_doattach: could not find any cores\n"));
558 /* bus/core/clk setup */
560 if (!si_buscore_setup(sii, cc, bustype, savewin, &origidx, regs)) {
561 SI_ERROR(("si_doattach: si_buscore_setup failed\n"));
565 /* assume current core is CC */
566 if ((sii->pub.ccrev == 0x25)
568 ((CHIPID(sih->chip) == BCM43236_CHIP_ID
569 || CHIPID(sih->chip) == BCM43235_CHIP_ID
570 || CHIPID(sih->chip) == BCM43238_CHIP_ID)
571 && (CHIPREV(sii->pub.chiprev) <= 2))) {
573 if ((cc->chipstatus & CST43236_BP_CLK) != 0) {
575 clkdiv = R_REG(osh, &cc->clkdiv);
576 /* otp_clk_div is even number, 120/14 < 9mhz */
577 clkdiv = (clkdiv & ~CLKD_OTP) | (14 << CLKD_OTP_SHIFT);
578 W_REG(osh, &cc->clkdiv, clkdiv);
579 SI_ERROR(("%s: set clkdiv to %x\n", __func__, clkdiv));
584 /* Init nvram from flash if it exists */
585 nvram_init((void *)&(sii->pub));
587 /* Init nvram from sprom/otp if they exist */
589 (&sii->pub, BUSTYPE(bustype), regs, sii->osh, vars, varsz)) {
590 SI_ERROR(("si_doattach: srom_var_init failed: bad srom\n"));
593 pvars = vars ? *vars : NULL;
594 si_nvram_process(sii, pvars);
596 /* === NVRAM, clock is ready === */
597 cc = (chipcregs_t *) si_setcore(sih, CC_CORE_ID, 0);
598 W_REG(osh, &cc->gpiopullup, 0);
599 W_REG(osh, &cc->gpiopulldown, 0);
600 si_setcoreidx(sih, origidx);
602 /* PMU specific initializations */
603 if (PMUCTL_ENAB(sih)) {
605 si_pmu_init(sih, sii->osh);
606 si_pmu_chip_init(sih, sii->osh);
607 xtalfreq = getintvar(pvars, "xtalfreq");
608 /* If xtalfreq var not available, try to measure it */
610 xtalfreq = si_pmu_measure_alpclk(sih, sii->osh);
611 si_pmu_pll_init(sih, sii->osh, xtalfreq);
612 si_pmu_res_init(sih, sii->osh);
613 si_pmu_swreg_init(sih, sii->osh);
616 /* setup the GPIO based LED powersave register */
617 if ((w = getintvar(pvars, "leddc")) == 0)
618 w = DEFAULT_GPIOTIMERVAL;
619 si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, gpiotimerval), ~0, w);
622 ASSERT(sii->pch != NULL);
623 pcicore_attach(sii->pch, pvars, SI_DOATTACH);
626 if ((CHIPID(sih->chip) == BCM43224_CHIP_ID) ||
627 (CHIPID(sih->chip) == BCM43421_CHIP_ID)) {
628 /* enable 12 mA drive strenth for 43224 and set chipControl register bit 15 */
629 if (CHIPREV(sih->chiprev) == 0) {
630 SI_MSG(("Applying 43224A0 WARs\n"));
631 si_corereg(sih, SI_CC_IDX,
632 OFFSETOF(chipcregs_t, chipcontrol),
633 CCTRL43224_GPIO_TOGGLE,
634 CCTRL43224_GPIO_TOGGLE);
635 si_pmu_chipcontrol(sih, 0, CCTRL_43224A0_12MA_LED_DRIVE,
636 CCTRL_43224A0_12MA_LED_DRIVE);
638 if (CHIPREV(sih->chiprev) >= 1) {
639 SI_MSG(("Applying 43224B0+ WARs\n"));
640 si_pmu_chipcontrol(sih, 0, CCTRL_43224B0_12MA_LED_DRIVE,
641 CCTRL_43224B0_12MA_LED_DRIVE);
645 if (CHIPID(sih->chip) == BCM4313_CHIP_ID) {
646 /* enable 12 mA drive strenth for 4313 and set chipControl register bit 1 */
647 SI_MSG(("Applying 4313 WARs\n"));
648 si_pmu_chipcontrol(sih, 0, CCTRL_4313_12MA_LED_DRIVE,
649 CCTRL_4313_12MA_LED_DRIVE);
652 if (CHIPID(sih->chip) == BCM4331_CHIP_ID) {
653 /* Enable Ext PA lines depending on chip package option */
654 si_chipcontrl_epa4331(sih, TRUE);
659 if (BUSTYPE(sih->bustype) == PCI_BUS) {
661 pcicore_deinit(sii->pch);
669 /* may be called with core in reset */
670 void BCMATTACHFN(si_detach) (si_t *sih)
675 struct si_pub *si_local = NULL;
676 bcopy(&sih, &si_local, sizeof(si_t **));
683 if (BUSTYPE(sih->bustype) == SI_BUS)
684 for (idx = 0; idx < SI_MAXCORES; idx++)
685 if (sii->regs[idx]) {
686 REG_UNMAP(sii->regs[idx]);
687 sii->regs[idx] = NULL;
690 nvram_exit((void *)si_local); /* free up nvram buffers */
692 if (BUSTYPE(sih->bustype) == PCI_BUS) {
694 pcicore_deinit(sii->pch);
697 #if !defined(BCMBUSTYPE) || (BCMBUSTYPE == SI_BUS)
699 #endif /* !BCMBUSTYPE || (BCMBUSTYPE == SI_BUS) */
700 MFREE(sii->osh, sii, sizeof(si_info_t));
703 void *si_osh(si_t *sih)
711 void si_setosh(si_t *sih, osl_t *osh)
716 if (sii->osh != NULL) {
717 SI_ERROR(("osh is already set....\n"));
723 /* register driver interrupt disabling and restoring callback functions */
725 si_register_intr_callback(si_t *sih, void *intrsoff_fn, void *intrsrestore_fn,
726 void *intrsenabled_fn, void *intr_arg)
731 sii->intr_arg = intr_arg;
732 sii->intrsoff_fn = (si_intrsoff_t) intrsoff_fn;
733 sii->intrsrestore_fn = (si_intrsrestore_t) intrsrestore_fn;
734 sii->intrsenabled_fn = (si_intrsenabled_t) intrsenabled_fn;
735 /* save current core id. when this function called, the current core
736 * must be the core which provides driver functions(il, et, wl, etc.)
738 sii->dev_coreid = sii->coreid[sii->curidx];
741 void si_deregister_intr_callback(si_t *sih)
746 sii->intrsoff_fn = NULL;
749 uint si_intflag(si_t *sih)
751 si_info_t *sii = SI_INFO(sih);
753 if (CHIPTYPE(sih->socitype) == SOCI_AI)
754 return R_REG(sii->osh,
755 ((uint32 *) (uintptr) (sii->oob_router +
763 uint si_flag(si_t *sih)
765 if (CHIPTYPE(sih->socitype) == SOCI_AI)
773 void si_setint(si_t *sih, int siflag)
775 if (CHIPTYPE(sih->socitype) == SOCI_AI)
776 ai_setint(sih, siflag);
782 uint si_coreid(si_t *sih)
787 return sii->coreid[sii->curidx];
791 uint si_coreidx(si_t *sih)
799 /* return the core-type instantiation # of the current core */
800 uint si_coreunit(si_t *sih)
813 ASSERT(GOODREGS(sii->curmap));
814 coreid = si_coreid(sih);
816 /* count the cores of our type */
817 for (i = 0; i < idx; i++)
818 if (sii->coreid[i] == coreid)
824 uint si_corevendor(si_t *sih)
826 if (CHIPTYPE(sih->socitype) == SOCI_AI)
827 return ai_corevendor(sih);
834 bool si_backplane64(si_t *sih)
836 return ((sih->cccaps & CC_CAP_BKPLN64) != 0);
840 uint si_corerev(si_t *sih)
842 if (CHIPTYPE(sih->socitype) == SOCI_AI)
843 return ai_corerev(sih);
851 /* return index of coreid or BADIDX if not found */
852 uint si_findcoreidx(si_t *sih, uint coreid, uint coreunit)
862 for (i = 0; i < sii->numcores; i++)
863 if (sii->coreid[i] == coreid) {
864 if (found == coreunit)
872 /* return list of found cores */
873 uint si_corelist(si_t *sih, uint coreid[])
879 bcopy((uchar *) sii->coreid, (uchar *) coreid,
880 (sii->numcores * sizeof(uint)));
881 return (sii->numcores);
884 /* return current register mapping */
885 void *si_coreregs(si_t *sih)
890 ASSERT(GOODREGS(sii->curmap));
892 return (sii->curmap);
896 * This function changes logical "focus" to the indicated core;
897 * must be called with interrupts off.
898 * Moreover, callers should keep interrupts off during switching out of and back to d11 core
900 void *si_setcore(si_t *sih, uint coreid, uint coreunit)
904 idx = si_findcoreidx(sih, coreid, coreunit);
908 if (CHIPTYPE(sih->socitype) == SOCI_AI)
909 return ai_setcoreidx(sih, idx);
912 return sb_setcoreidx(sih, idx);
921 void *si_setcoreidx(si_t *sih, uint coreidx)
923 if (CHIPTYPE(sih->socitype) == SOCI_AI)
924 return ai_setcoreidx(sih, coreidx);
932 /* Turn off interrupt as required by sb_setcore, before switch core */
933 void *si_switch_core(si_t *sih, uint coreid, uint *origidx, uint *intr_val)
941 /* Overloading the origidx variable to remember the coreid,
942 * this works because the core ids cannot be confused with
946 if (coreid == CC_CORE_ID)
947 return (void *)CCREGS_FAST(sii);
948 else if (coreid == sih->buscoretype)
949 return (void *)PCIEREGS(sii);
951 INTR_OFF(sii, *intr_val);
952 *origidx = sii->curidx;
953 cc = si_setcore(sih, coreid, 0);
959 /* restore coreidx and restore interrupt */
960 void si_restore_core(si_t *sih, uint coreid, uint intr_val)
966 && ((coreid == CC_CORE_ID) || (coreid == sih->buscoretype)))
969 si_setcoreidx(sih, coreid);
970 INTR_RESTORE(sii, intr_val);
973 int si_numaddrspaces(si_t *sih)
975 if (CHIPTYPE(sih->socitype) == SOCI_AI)
976 return ai_numaddrspaces(sih);
983 uint32 si_addrspace(si_t *sih, uint asidx)
985 if (CHIPTYPE(sih->socitype) == SOCI_AI)
986 return ai_addrspace(sih, asidx);
993 uint32 si_addrspacesize(si_t *sih, uint asidx)
995 if (CHIPTYPE(sih->socitype) == SOCI_AI)
996 return ai_addrspacesize(sih, asidx);
1003 uint32 si_core_cflags(si_t *sih, uint32 mask, uint32 val)
1005 if (CHIPTYPE(sih->socitype) == SOCI_AI)
1006 return ai_core_cflags(sih, mask, val);
1013 void si_core_cflags_wo(si_t *sih, uint32 mask, uint32 val)
1015 if (CHIPTYPE(sih->socitype) == SOCI_AI)
1016 ai_core_cflags_wo(sih, mask, val);
1021 uint32 si_core_sflags(si_t *sih, uint32 mask, uint32 val)
1023 if (CHIPTYPE(sih->socitype) == SOCI_AI)
1024 return ai_core_sflags(sih, mask, val);
1031 bool si_iscoreup(si_t *sih)
1033 if (CHIPTYPE(sih->socitype) == SOCI_AI)
1034 return ai_iscoreup(sih);
1037 return sb_iscoreup(sih);
1045 void si_write_wrapperreg(si_t *sih, uint32 offset, uint32 val)
1047 /* only for 4319, no requirement for SOCI_SB */
1048 if (CHIPTYPE(sih->socitype) == SOCI_AI) {
1049 ai_write_wrap_reg(sih, offset, val);
1053 uint si_corereg(si_t *sih, uint coreidx, uint regoff, uint mask, uint val)
1056 if (CHIPTYPE(sih->socitype) == SOCI_AI)
1057 return ai_corereg(sih, coreidx, regoff, mask, val);
1060 return sb_corereg(sih, coreidx, regoff, mask, val);
1068 void si_core_disable(si_t *sih, uint32 bits)
1071 if (CHIPTYPE(sih->socitype) == SOCI_AI)
1072 ai_core_disable(sih, bits);
1075 sb_core_disable(sih, bits);
1079 void si_core_reset(si_t *sih, uint32 bits, uint32 resetbits)
1081 if (CHIPTYPE(sih->socitype) == SOCI_AI)
1082 ai_core_reset(sih, bits, resetbits);
1085 sb_core_reset(sih, bits, resetbits);
1089 /* Run bist on current core. Caller needs to take care of core-specific bist hazards */
1090 int si_corebist(si_t *sih)
1095 /* Read core control flags */
1096 cflags = si_core_cflags(sih, 0, 0);
1098 /* Set bist & fgc */
1099 si_core_cflags(sih, ~0, (SICF_BIST_EN | SICF_FGC));
1101 /* Wait for bist done */
1102 SPINWAIT(((si_core_sflags(sih, 0, 0) & SISF_BIST_DONE) == 0), 100000);
1104 if (si_core_sflags(sih, 0, 0) & SISF_BIST_ERROR)
1105 result = BCME_ERROR;
1107 /* Reset core control flags */
1108 si_core_cflags(sih, 0xffff, cflags);
1113 static uint32 BCMINITFN(factor6) (uint32 x)
1133 /* calculate the speed the SI would run at given a set of clockcontrol values */
1134 uint32 BCMINITFN(si_clock_rate) (uint32 pll_type, uint32 n, uint32 m)
1136 uint32 n1, n2, clock, m1, m2, m3, mc;
1138 n1 = n & CN_N1_MASK;
1139 n2 = (n & CN_N2_MASK) >> CN_N2_SHIFT;
1141 if (pll_type == PLL_TYPE6) {
1142 if (m & CC_T6_MMASK)
1146 } else if ((pll_type == PLL_TYPE1) ||
1147 (pll_type == PLL_TYPE3) ||
1148 (pll_type == PLL_TYPE4) || (pll_type == PLL_TYPE7)) {
1151 } else if (pll_type == PLL_TYPE2) {
1154 ASSERT((n1 >= 2) && (n1 <= 7));
1155 ASSERT((n2 >= 5) && (n2 <= 23));
1156 } else if (pll_type == PLL_TYPE5) {
1160 /* PLL types 3 and 7 use BASE2 (25Mhz) */
1161 if ((pll_type == PLL_TYPE3) || (pll_type == PLL_TYPE7)) {
1162 clock = CC_CLOCK_BASE2 * n1 * n2;
1164 clock = CC_CLOCK_BASE1 * n1 * n2;
1169 m1 = m & CC_M1_MASK;
1170 m2 = (m & CC_M2_MASK) >> CC_M2_SHIFT;
1171 m3 = (m & CC_M3_MASK) >> CC_M3_SHIFT;
1172 mc = (m & CC_MC_MASK) >> CC_MC_SHIFT;
1174 if ((pll_type == PLL_TYPE1) ||
1175 (pll_type == PLL_TYPE3) ||
1176 (pll_type == PLL_TYPE4) || (pll_type == PLL_TYPE7)) {
1178 if ((pll_type == PLL_TYPE1) || (pll_type == PLL_TYPE3))
1188 return (clock / m1);
1190 return (clock / (m1 * m2));
1192 return (clock / (m1 * m2 * m3));
1194 return (clock / (m1 * m3));
1199 ASSERT(pll_type == PLL_TYPE2);
1204 ASSERT((m1 >= 2) && (m1 <= 7));
1205 ASSERT((m2 >= 3) && (m2 <= 10));
1206 ASSERT((m3 >= 2) && (m3 <= 7));
1208 if ((mc & CC_T2MC_M1BYP) == 0)
1210 if ((mc & CC_T2MC_M2BYP) == 0)
1212 if ((mc & CC_T2MC_M3BYP) == 0)
1219 uint32 BCMINITFN(si_clock) (si_t *sih)
1225 uint32 pll_type, rate;
1229 INTR_OFF(sii, intr_val);
1230 if (PMUCTL_ENAB(sih)) {
1231 rate = si_pmu_si_clock(sih, sii->osh);
1236 cc = (chipcregs_t *) si_setcore(sih, CC_CORE_ID, 0);
1239 n = R_REG(sii->osh, &cc->clockcontrol_n);
1240 pll_type = sih->cccaps & CC_CAP_PLL_MASK;
1241 if (pll_type == PLL_TYPE6)
1242 m = R_REG(sii->osh, &cc->clockcontrol_m3);
1243 else if (pll_type == PLL_TYPE3)
1244 m = R_REG(sii->osh, &cc->clockcontrol_m2);
1246 m = R_REG(sii->osh, &cc->clockcontrol_sb);
1248 /* calculate rate */
1249 rate = si_clock_rate(pll_type, n, m);
1251 if (pll_type == PLL_TYPE3)
1254 /* switch back to previous core */
1255 si_setcoreidx(sih, idx);
1257 INTR_RESTORE(sii, intr_val);
1262 uint32 BCMINITFN(si_alp_clock) (si_t *sih)
1264 if (PMUCTL_ENAB(sih))
1265 return si_pmu_alp_clock(sih, si_osh(sih));
1270 uint32 BCMINITFN(si_ilp_clock) (si_t *sih)
1272 if (PMUCTL_ENAB(sih))
1273 return si_pmu_ilp_clock(sih, si_osh(sih));
1278 /* set chip watchdog reset timer to fire in 'ticks' */
1279 void si_watchdog(si_t *sih, uint ticks)
1283 if (PMUCTL_ENAB(sih)) {
1285 if ((CHIPID(sih->chip) == BCM4319_CHIP_ID) &&
1286 (CHIPREV(sih->chiprev) == 0) && (ticks != 0)) {
1287 si_corereg(sih, SI_CC_IDX,
1288 OFFSETOF(chipcregs_t, clk_ctl_st), ~0, 0x2);
1289 si_setcore(sih, USB20D_CORE_ID, 0);
1290 si_core_disable(sih, 1);
1291 si_setcore(sih, CC_CORE_ID, 0);
1294 nb = (sih->ccrev < 26) ? 16 : ((sih->ccrev >= 37) ? 32 : 24);
1295 /* The mips compiler uses the sllv instruction,
1296 * so we specially handle the 32-bit case.
1301 maxt = ((1 << nb) - 1);
1305 else if (ticks > maxt)
1308 si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, pmuwatchdog),
1311 /* make sure we come up in fast clock mode; or if clearing, clear clock */
1312 si_clkctl_cc(sih, ticks ? CLK_FAST : CLK_DYNAMIC);
1313 maxt = (1 << 28) - 1;
1317 si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, watchdog), ~0,
1322 /* trigger watchdog reset after ms milliseconds */
1323 void si_watchdog_ms(si_t *sih, uint32 ms)
1325 si_watchdog(sih, wd_msticks * ms);
1328 uint16 BCMATTACHFN(si_d11_devid) (si_t *sih)
1330 si_info_t *sii = SI_INFO(sih);
1333 /* normal case: nvram variable with devpath->devid->wl0id */
1334 if ((device = (uint16) si_getdevpathintvar(sih, "devid")) != 0) ;
1335 /* Get devid from OTP/SPROM depending on where the SROM is read */
1336 else if ((device = (uint16) getintvar(sii->vars, "devid")) != 0) ;
1337 /* no longer support wl0id, but keep the code here for backward compatibility. */
1338 else if ((device = (uint16) getintvar(sii->vars, "wl0id")) != 0) ;
1346 /* return the slow clock source - LPO, XTAL, or PCI */
1347 static uint si_slowclk_src(si_info_t *sii)
1351 ASSERT(SI_FAST(sii) || si_coreid(&sii->pub) == CC_CORE_ID);
1353 if (sii->pub.ccrev < 6) {
1354 if ((BUSTYPE(sii->pub.bustype) == PCI_BUS) &&
1355 (OSL_PCI_READ_CONFIG(sii->osh, PCI_GPIO_OUT, sizeof(uint32))
1356 & PCI_CFG_GPIO_SCS))
1357 return (SCC_SS_PCI);
1359 return (SCC_SS_XTAL);
1360 } else if (sii->pub.ccrev < 10) {
1361 cc = (chipcregs_t *) si_setcoreidx(&sii->pub, sii->curidx);
1362 return (R_REG(sii->osh, &cc->slow_clk_ctl) & SCC_SS_MASK);
1363 } else /* Insta-clock */
1364 return (SCC_SS_XTAL);
1367 /* return the ILP (slowclock) min or max frequency */
1368 static uint si_slowclk_freq(si_info_t *sii, bool max_freq, chipcregs_t *cc)
1373 ASSERT(SI_FAST(sii) || si_coreid(&sii->pub) == CC_CORE_ID);
1375 /* shouldn't be here unless we've established the chip has dynamic clk control */
1376 ASSERT(R_REG(sii->osh, &cc->capabilities) & CC_CAP_PWR_CTL);
1378 slowclk = si_slowclk_src(sii);
1379 if (sii->pub.ccrev < 6) {
1380 if (slowclk == SCC_SS_PCI)
1381 return (max_freq ? (PCIMAXFREQ / 64)
1382 : (PCIMINFREQ / 64));
1384 return (max_freq ? (XTALMAXFREQ / 32)
1385 : (XTALMINFREQ / 32));
1386 } else if (sii->pub.ccrev < 10) {
1388 (((R_REG(sii->osh, &cc->slow_clk_ctl) & SCC_CD_MASK) >>
1390 if (slowclk == SCC_SS_LPO)
1391 return (max_freq ? LPOMAXFREQ : LPOMINFREQ);
1392 else if (slowclk == SCC_SS_XTAL)
1393 return (max_freq ? (XTALMAXFREQ / div)
1394 : (XTALMINFREQ / div));
1395 else if (slowclk == SCC_SS_PCI)
1396 return (max_freq ? (PCIMAXFREQ / div)
1397 : (PCIMINFREQ / div));
1401 /* Chipc rev 10 is InstaClock */
1402 div = R_REG(sii->osh, &cc->system_clk_ctl) >> SYCC_CD_SHIFT;
1403 div = 4 * (div + 1);
1404 return (max_freq ? XTALMAXFREQ : (XTALMINFREQ / div));
1409 static void BCMINITFN(si_clkctl_setdelay) (si_info_t *sii, void *chipcregs)
1411 chipcregs_t *cc = (chipcregs_t *) chipcregs;
1412 uint slowmaxfreq, pll_delay, slowclk;
1413 uint pll_on_delay, fref_sel_delay;
1415 pll_delay = PLL_DELAY;
1417 /* If the slow clock is not sourced by the xtal then add the xtal_on_delay
1418 * since the xtal will also be powered down by dynamic clk control logic.
1421 slowclk = si_slowclk_src(sii);
1422 if (slowclk != SCC_SS_XTAL)
1423 pll_delay += XTAL_ON_DELAY;
1425 /* Starting with 4318 it is ILP that is used for the delays */
1427 si_slowclk_freq(sii, (sii->pub.ccrev >= 10) ? FALSE : TRUE, cc);
1429 pll_on_delay = ((slowmaxfreq * pll_delay) + 999999) / 1000000;
1430 fref_sel_delay = ((slowmaxfreq * FREF_DELAY) + 999999) / 1000000;
1432 W_REG(sii->osh, &cc->pll_on_delay, pll_on_delay);
1433 W_REG(sii->osh, &cc->fref_sel_delay, fref_sel_delay);
1436 /* initialize power control delay registers */
1437 void BCMINITFN(si_clkctl_init) (si_t *sih)
1444 if (!CCCTL_ENAB(sih))
1448 fast = SI_FAST(sii);
1450 origidx = sii->curidx;
1452 (chipcregs_t *) si_setcore(sih, CC_CORE_ID, 0)) == NULL)
1454 } else if ((cc = (chipcregs_t *) CCREGS_FAST(sii)) == NULL)
1458 /* set all Instaclk chip ILP to 1 MHz */
1459 if (sih->ccrev >= 10)
1460 SET_REG(sii->osh, &cc->system_clk_ctl, SYCC_CD_MASK,
1461 (ILP_DIV_1MHZ << SYCC_CD_SHIFT));
1463 si_clkctl_setdelay(sii, (void *)(uintptr) cc);
1466 si_setcoreidx(sih, origidx);
1469 /* return the value suitable for writing to the dot11 core FAST_PWRUP_DELAY register */
1470 uint16 BCMINITFN(si_clkctl_fast_pwrup_delay) (si_t *sih)
1481 if (PMUCTL_ENAB(sih)) {
1482 INTR_OFF(sii, intr_val);
1483 fpdelay = si_pmu_fast_pwrup_delay(sih, sii->osh);
1484 INTR_RESTORE(sii, intr_val);
1488 if (!CCCTL_ENAB(sih))
1491 fast = SI_FAST(sii);
1494 origidx = sii->curidx;
1495 INTR_OFF(sii, intr_val);
1497 (chipcregs_t *) si_setcore(sih, CC_CORE_ID, 0)) == NULL)
1499 } else if ((cc = (chipcregs_t *) CCREGS_FAST(sii)) == NULL)
1503 slowminfreq = si_slowclk_freq(sii, FALSE, cc);
1504 fpdelay = (((R_REG(sii->osh, &cc->pll_on_delay) + 2) * 1000000) +
1505 (slowminfreq - 1)) / slowminfreq;
1509 si_setcoreidx(sih, origidx);
1510 INTR_RESTORE(sii, intr_val);
1515 /* turn primary xtal and/or pll off/on */
1516 int si_clkctl_xtal(si_t *sih, uint what, bool on)
1519 uint32 in, out, outen;
1523 switch (BUSTYPE(sih->bustype)) {
1528 #endif /* BCMSDIO */
1531 /* pcie core doesn't have any mapping to control the xtal pu */
1535 in = OSL_PCI_READ_CONFIG(sii->osh, PCI_GPIO_IN, sizeof(uint32));
1537 OSL_PCI_READ_CONFIG(sii->osh, PCI_GPIO_OUT, sizeof(uint32));
1539 OSL_PCI_READ_CONFIG(sii->osh, PCI_GPIO_OUTEN,
1543 * Avoid glitching the clock if GPRS is already using it.
1544 * We can't actually read the state of the PLLPD so we infer it
1545 * by the value of XTAL_PU which *is* readable via gpioin.
1547 if (on && (in & PCI_CFG_GPIO_XTAL))
1551 outen |= PCI_CFG_GPIO_XTAL;
1553 outen |= PCI_CFG_GPIO_PLL;
1556 /* turn primary xtal on */
1558 out |= PCI_CFG_GPIO_XTAL;
1560 out |= PCI_CFG_GPIO_PLL;
1561 OSL_PCI_WRITE_CONFIG(sii->osh, PCI_GPIO_OUT,
1562 sizeof(uint32), out);
1563 OSL_PCI_WRITE_CONFIG(sii->osh, PCI_GPIO_OUTEN,
1564 sizeof(uint32), outen);
1565 OSL_DELAY(XTAL_ON_DELAY);
1570 out &= ~PCI_CFG_GPIO_PLL;
1571 OSL_PCI_WRITE_CONFIG(sii->osh, PCI_GPIO_OUT,
1572 sizeof(uint32), out);
1577 out &= ~PCI_CFG_GPIO_XTAL;
1579 out |= PCI_CFG_GPIO_PLL;
1580 OSL_PCI_WRITE_CONFIG(sii->osh, PCI_GPIO_OUT,
1581 sizeof(uint32), out);
1582 OSL_PCI_WRITE_CONFIG(sii->osh, PCI_GPIO_OUTEN,
1583 sizeof(uint32), outen);
1594 * clock control policy function throught chipcommon
1596 * set dynamic clk control mode (forceslow, forcefast, dynamic)
1597 * returns true if we are forcing fast clock
1598 * this is a wrapper over the next internal function
1599 * to allow flexible policy settings for outside caller
1601 bool si_clkctl_cc(si_t *sih, uint mode)
1607 /* chipcommon cores prior to rev6 don't support dynamic clock control */
1611 if (PCI_FORCEHT(sii))
1612 return (mode == CLK_FAST);
1614 return _si_clkctl_cc(sii, mode);
1617 /* clk control mechanism through chipcommon, no policy checking */
1618 static bool _si_clkctl_cc(si_info_t *sii, uint mode)
1624 bool fast = SI_FAST(sii);
1626 /* chipcommon cores prior to rev6 don't support dynamic clock control */
1627 if (sii->pub.ccrev < 6)
1630 /* Chips with ccrev 10 are EOL and they don't have SYCC_HR which we use below */
1631 ASSERT(sii->pub.ccrev != 10);
1634 INTR_OFF(sii, intr_val);
1635 origidx = sii->curidx;
1637 if ((BUSTYPE(sii->pub.bustype) == SI_BUS) &&
1638 si_setcore(&sii->pub, MIPS33_CORE_ID, 0) &&
1639 (si_corerev(&sii->pub) <= 7) && (sii->pub.ccrev >= 10))
1642 cc = (chipcregs_t *) si_setcore(&sii->pub, CC_CORE_ID, 0);
1643 } else if ((cc = (chipcregs_t *) CCREGS_FAST(sii)) == NULL)
1647 if (!CCCTL_ENAB(&sii->pub) && (sii->pub.ccrev < 20))
1651 case CLK_FAST: /* FORCEHT, fast (pll) clock */
1652 if (sii->pub.ccrev < 10) {
1653 /* don't forget to force xtal back on before we clear SCC_DYN_XTAL.. */
1654 si_clkctl_xtal(&sii->pub, XTAL, ON);
1655 SET_REG(sii->osh, &cc->slow_clk_ctl,
1656 (SCC_XC | SCC_FS | SCC_IP), SCC_IP);
1657 } else if (sii->pub.ccrev < 20) {
1658 OR_REG(sii->osh, &cc->system_clk_ctl, SYCC_HR);
1660 OR_REG(sii->osh, &cc->clk_ctl_st, CCS_FORCEHT);
1663 /* wait for the PLL */
1664 if (PMUCTL_ENAB(&sii->pub)) {
1665 uint32 htavail = CCS_HTAVAIL;
1666 SPINWAIT(((R_REG(sii->osh, &cc->clk_ctl_st) & htavail)
1667 == 0), PMU_MAX_TRANSITION_DLY);
1668 ASSERT(R_REG(sii->osh, &cc->clk_ctl_st) & htavail);
1670 OSL_DELAY(PLL_DELAY);
1674 case CLK_DYNAMIC: /* enable dynamic clock control */
1675 if (sii->pub.ccrev < 10) {
1676 scc = R_REG(sii->osh, &cc->slow_clk_ctl);
1677 scc &= ~(SCC_FS | SCC_IP | SCC_XC);
1678 if ((scc & SCC_SS_MASK) != SCC_SS_XTAL)
1680 W_REG(sii->osh, &cc->slow_clk_ctl, scc);
1682 /* for dynamic control, we have to release our xtal_pu "force on" */
1684 si_clkctl_xtal(&sii->pub, XTAL, OFF);
1685 } else if (sii->pub.ccrev < 20) {
1687 AND_REG(sii->osh, &cc->system_clk_ctl, ~SYCC_HR);
1689 AND_REG(sii->osh, &cc->clk_ctl_st, ~CCS_FORCEHT);
1699 si_setcoreidx(&sii->pub, origidx);
1700 INTR_RESTORE(sii, intr_val);
1702 return (mode == CLK_FAST);
1705 /* Build device path. Support SI, PCI, and JTAG for now. */
1706 int BCMATTACHFN(si_devpath) (si_t *sih, char *path, int size)
1710 ASSERT(path != NULL);
1711 ASSERT(size >= SI_DEVPATH_BUFSZ);
1713 if (!path || size <= 0)
1716 switch (BUSTYPE(sih->bustype)) {
1719 slen = snprintf(path, (size_t) size, "sb/%u/", si_coreidx(sih));
1722 ASSERT((SI_INFO(sih))->osh != NULL);
1723 slen = snprintf(path, (size_t) size, "pci/%u/%u/",
1724 OSL_PCI_BUS((SI_INFO(sih))->osh),
1725 OSL_PCI_SLOT((SI_INFO(sih))->osh));
1730 SI_ERROR(("si_devpath: device 0 assumed\n"));
1731 slen = snprintf(path, (size_t) size, "sd/%u/", si_coreidx(sih));
1740 if (slen < 0 || slen >= size) {
1748 /* Get a variable, but only if it has a devpath prefix */
1749 char *BCMATTACHFN(si_getdevpathvar) (si_t *sih, const char *name)
1751 char varname[SI_DEVPATH_BUFSZ + 32];
1753 si_devpathvar(sih, varname, sizeof(varname), name);
1755 return (getvar(NULL, varname));
1758 /* Get a variable, but only if it has a devpath prefix */
1759 int BCMATTACHFN(si_getdevpathintvar) (si_t *sih, const char *name)
1761 #if defined(BCMBUSTYPE) && (BCMBUSTYPE == SI_BUS)
1762 return (getintvar(NULL, name));
1764 char varname[SI_DEVPATH_BUFSZ + 32];
1766 si_devpathvar(sih, varname, sizeof(varname), name);
1768 return (getintvar(NULL, varname));
1772 char *si_getnvramflvar(si_t *sih, const char *name)
1774 return (getvar(NULL, name));
1777 /* Concatenate the dev path with a varname into the given 'var' buffer
1778 * and return the 'var' pointer.
1779 * Nothing is done to the arguments if len == 0 or var is NULL, var is still returned.
1780 * On overflow, the first char will be set to '\0'.
1782 static char *BCMATTACHFN(si_devpathvar) (si_t *sih, char *var, int len,
1786 if (!var || len <= 0)
1789 if (si_devpath(sih, var, len) == 0) {
1790 path_len = strlen(var);
1792 if (strlen(name) + 1 > (uint) (len - path_len))
1795 strncpy(var + path_len, name, len - path_len - 1);
1801 uint32 si_pciereg(si_t *sih, uint32 offset, uint32 mask, uint32 val, uint type)
1808 SI_ERROR(("%s: Not a PCIE device\n", __func__));
1812 return pcicore_pciereg(sii->pch, offset, mask, val, type);
1816 si_pcieserdesreg(si_t *sih, uint32 mdioslave, uint32 offset, uint32 mask,
1824 SI_ERROR(("%s: Not a PCIE device\n", __func__));
1828 return pcicore_pcieserdesreg(sii->pch, mdioslave, offset, mask, val);
1832 /* return TRUE if PCIE capability exists in the pci config space */
1833 static bool si_ispcie(si_info_t *sii)
1837 if (BUSTYPE(sii->pub.bustype) != PCI_BUS)
1841 pcicore_find_pci_capability(sii->osh, PCI_CAP_PCIECAP_ID, NULL,
1849 /* Wake-on-wireless-LAN (WOWL) support functions */
1850 /* Enable PME generation and disable clkreq */
1851 void si_pci_pmeen(si_t *sih)
1857 pcicore_pmeen(sii->pch);
1860 /* Return TRUE if PME status is set */
1861 bool si_pci_pmestat(si_t *sih)
1867 return pcicore_pmestat(sii->pch);
1870 /* Disable PME generation, clear the PME status bit if set */
1871 void si_pci_pmeclr(si_t *sih)
1877 pcicore_pmeclr(sii->pch);
1881 /* initialize the sdio core */
1882 void si_sdio_init(si_t *sih)
1884 si_info_t *sii = SI_INFO(sih);
1886 if (((sih->buscoretype == PCMCIA_CORE_ID) && (sih->buscorerev >= 8)) ||
1887 (sih->buscoretype == SDIOD_CORE_ID)) {
1889 sdpcmd_regs_t *sdpregs;
1891 /* get the current core index */
1893 ASSERT(idx == si_findcoreidx(sih, D11_CORE_ID, 0));
1895 /* switch to sdio core */
1898 (sdpcmd_regs_t *) si_setcore(sih, PCMCIA_CORE_ID, 0)))
1900 (sdpcmd_regs_t *) si_setcore(sih, SDIOD_CORE_ID, 0);
1903 SI_MSG(("si_sdio_init: For PCMCIA/SDIO Corerev %d, enable ints from core %d " "through SD core %d (%p)\n", sih->buscorerev, idx, sii->curidx, sdpregs));
1905 /* enable backplane error and core interrupts */
1906 W_REG(sii->osh, &sdpregs->hostintmask, I_SBINT);
1907 W_REG(sii->osh, &sdpregs->sbintmask,
1908 (I_SB_SERR | I_SB_RESPERR | (1 << idx)));
1910 /* switch back to previous core */
1911 si_setcoreidx(sih, idx);
1914 /* enable interrupts */
1915 bcmsdh_intr_enable(sii->sdh);
1918 #endif /* BCMSDIO */
1920 bool BCMATTACHFN(si_pci_war16165) (si_t *sih)
1926 return (PCI(sii) && (sih->buscorerev <= 10));
1929 /* Disable pcie_war_ovr for some platforms (sigh!)
1930 * This is for boards that have BFL2_PCIEWAR_OVR set
1931 * but are in systems that still want the benefits of ASPM
1932 * Note that this should be done AFTER si_doattach
1934 void si_pcie_war_ovr_update(si_t *sih, uint8 aspm)
1943 pcie_war_ovr_aspm_update(sii->pch, aspm);
1946 /* back door for other module to override chippkg */
1947 void si_chippkg_set(si_t *sih, uint val)
1953 sii->pub.chippkg = val;
1956 void BCMINITFN(si_pci_up) (si_t *sih)
1962 /* if not pci bus, we're done */
1963 if (BUSTYPE(sih->bustype) != PCI_BUS)
1966 if (PCI_FORCEHT(sii))
1967 _si_clkctl_cc(sii, CLK_FAST);
1970 pcicore_up(sii->pch, SI_PCIUP);
1974 /* Unconfigure and/or apply various WARs when system is going to sleep mode */
1975 void BCMUNINITFN(si_pci_sleep) (si_t *sih)
1981 pcicore_sleep(sii->pch);
1984 /* Unconfigure and/or apply various WARs when going down */
1985 void BCMINITFN(si_pci_down) (si_t *sih)
1991 /* if not pci bus, we're done */
1992 if (BUSTYPE(sih->bustype) != PCI_BUS)
1995 /* release FORCEHT since chip is going to "down" state */
1996 if (PCI_FORCEHT(sii))
1997 _si_clkctl_cc(sii, CLK_DYNAMIC);
1999 pcicore_down(sii->pch, SI_PCIDOWN);
2003 * Configure the pci core for pci client (NIC) action
2004 * coremask is the bitvec of cores by index to be enabled.
2006 void BCMATTACHFN(si_pci_setup) (si_t *sih, uint coremask)
2009 sbpciregs_t *pciregs = NULL;
2010 uint32 siflag = 0, w;
2015 if (BUSTYPE(sii->pub.bustype) != PCI_BUS)
2018 ASSERT(PCI(sii) || PCIE(sii));
2019 ASSERT(sii->pub.buscoreidx != BADIDX);
2022 /* get current core index */
2025 /* we interrupt on this backplane flag number */
2026 siflag = si_flag(sih);
2028 /* switch over to pci core */
2030 (sbpciregs_t *) si_setcoreidx(sih, sii->pub.buscoreidx);
2034 * Enable sb->pci interrupts. Assume
2035 * PCI rev 2.3 support was added in pci core rev 6 and things changed..
2037 if (PCIE(sii) || (PCI(sii) && ((sii->pub.buscorerev) >= 6))) {
2038 /* pci config write to set this core bit in PCIIntMask */
2039 w = OSL_PCI_READ_CONFIG(sii->osh, PCI_INT_MASK, sizeof(uint32));
2040 w |= (coremask << PCI_SBIM_SHIFT);
2041 OSL_PCI_WRITE_CONFIG(sii->osh, PCI_INT_MASK, sizeof(uint32), w);
2043 /* set sbintvec bit for our flag number */
2044 si_setint(sih, siflag);
2048 OR_REG(sii->osh, &pciregs->sbtopci2,
2049 (SBTOPCI_PREF | SBTOPCI_BURST));
2050 if (sii->pub.buscorerev >= 11) {
2051 OR_REG(sii->osh, &pciregs->sbtopci2,
2052 SBTOPCI_RC_READMULTI);
2053 w = R_REG(sii->osh, &pciregs->clkrun);
2054 W_REG(sii->osh, &pciregs->clkrun,
2055 (w | PCI_CLKRUN_DSBL));
2056 w = R_REG(sii->osh, &pciregs->clkrun);
2059 /* switch back to previous core */
2060 si_setcoreidx(sih, idx);
2064 uint8 si_pcieclkreq(si_t *sih, uint32 mask, uint32 val)
2072 return pcie_clkreq(sii->pch, mask, val);
2075 uint32 si_pcielcreg(si_t *sih, uint32 mask, uint32 val)
2084 return pcie_lcreg(sii->pch, mask, val);
2087 /* indirect way to read pcie config regs */
2088 uint si_pcie_readreg(void *sih, uint addrtype, uint offset)
2090 return pcie_readreg(((si_info_t *) sih)->osh,
2091 (sbpcieregs_t *) PCIEREGS(((si_info_t *) sih)),
2096 * Fixup SROMless PCI device's configuration.
2097 * The current core may be changed upon return.
2099 int si_pci_fixcfg(si_t *sih)
2101 uint origidx, pciidx;
2102 sbpciregs_t *pciregs = NULL;
2103 sbpcieregs_t *pcieregs = NULL;
2105 uint16 val16, *reg16 = NULL;
2107 si_info_t *sii = SI_INFO(sih);
2109 ASSERT(BUSTYPE(sii->pub.bustype) == PCI_BUS);
2111 /* Fixup PI in SROM shadow area to enable the correct PCI core access */
2112 /* save the current index */
2113 origidx = si_coreidx(&sii->pub);
2115 /* check 'pi' is correct and fix it if not */
2116 if (sii->pub.buscoretype == PCIE_CORE_ID) {
2118 (sbpcieregs_t *) si_setcore(&sii->pub, PCIE_CORE_ID, 0);
2120 ASSERT(pcieregs != NULL);
2121 reg16 = &pcieregs->sprom[SRSH_PI_OFFSET];
2122 } else if (sii->pub.buscoretype == PCI_CORE_ID) {
2123 pciregs = (sbpciregs_t *) si_setcore(&sii->pub, PCI_CORE_ID, 0);
2125 ASSERT(pciregs != NULL);
2126 reg16 = &pciregs->sprom[SRSH_PI_OFFSET];
2128 pciidx = si_coreidx(&sii->pub);
2129 val16 = R_REG(sii->osh, reg16);
2130 if (((val16 & SRSH_PI_MASK) >> SRSH_PI_SHIFT) != (uint16) pciidx) {
2132 (uint16) (pciidx << SRSH_PI_SHIFT) | (val16 &
2134 W_REG(sii->osh, reg16, val16);
2137 /* restore the original index */
2138 si_setcoreidx(&sii->pub, origidx);
2140 pcicore_hwup(sii->pch);
2144 /* change logical "focus" to the gpio core for optimized access */
2145 void *si_gpiosetcore(si_t *sih)
2147 return (si_setcoreidx(sih, SI_CC_IDX));
2150 /* mask&set gpiocontrol bits */
2151 uint32 si_gpiocontrol(si_t *sih, uint32 mask, uint32 val, uint8 priority)
2157 /* gpios could be shared on router platforms
2158 * ignore reservation if it's high priority (e.g., test apps)
2160 if ((priority != GPIO_HI_PRIORITY) &&
2161 (BUSTYPE(sih->bustype) == SI_BUS) && (val || mask)) {
2162 mask = priority ? (si_gpioreservation & mask) :
2163 ((si_gpioreservation | mask) & ~(si_gpioreservation));
2167 regoff = OFFSETOF(chipcregs_t, gpiocontrol);
2168 return (si_corereg(sih, SI_CC_IDX, regoff, mask, val));
2171 /* mask&set gpio output enable bits */
2172 uint32 si_gpioouten(si_t *sih, uint32 mask, uint32 val, uint8 priority)
2178 /* gpios could be shared on router platforms
2179 * ignore reservation if it's high priority (e.g., test apps)
2181 if ((priority != GPIO_HI_PRIORITY) &&
2182 (BUSTYPE(sih->bustype) == SI_BUS) && (val || mask)) {
2183 mask = priority ? (si_gpioreservation & mask) :
2184 ((si_gpioreservation | mask) & ~(si_gpioreservation));
2188 regoff = OFFSETOF(chipcregs_t, gpioouten);
2189 return (si_corereg(sih, SI_CC_IDX, regoff, mask, val));
2192 /* mask&set gpio output bits */
2193 uint32 si_gpioout(si_t *sih, uint32 mask, uint32 val, uint8 priority)
2199 /* gpios could be shared on router platforms
2200 * ignore reservation if it's high priority (e.g., test apps)
2202 if ((priority != GPIO_HI_PRIORITY) &&
2203 (BUSTYPE(sih->bustype) == SI_BUS) && (val || mask)) {
2204 mask = priority ? (si_gpioreservation & mask) :
2205 ((si_gpioreservation | mask) & ~(si_gpioreservation));
2209 regoff = OFFSETOF(chipcregs_t, gpioout);
2210 return (si_corereg(sih, SI_CC_IDX, regoff, mask, val));
2213 /* reserve one gpio */
2214 uint32 si_gpioreserve(si_t *sih, uint32 gpio_bitmask, uint8 priority)
2220 /* only cores on SI_BUS share GPIO's and only applcation users need to
2221 * reserve/release GPIO
2223 if ((BUSTYPE(sih->bustype) != SI_BUS) || (!priority)) {
2224 ASSERT((BUSTYPE(sih->bustype) == SI_BUS) && (priority));
2227 /* make sure only one bit is set */
2228 if ((!gpio_bitmask) || ((gpio_bitmask) & (gpio_bitmask - 1))) {
2229 ASSERT((gpio_bitmask)
2230 && !((gpio_bitmask) & (gpio_bitmask - 1)));
2234 /* already reserved */
2235 if (si_gpioreservation & gpio_bitmask)
2237 /* set reservation */
2238 si_gpioreservation |= gpio_bitmask;
2240 return si_gpioreservation;
2243 /* release one gpio */
2245 * releasing the gpio doesn't change the current value on the GPIO last write value
2246 * persists till some one overwrites it
2249 uint32 si_gpiorelease(si_t *sih, uint32 gpio_bitmask, uint8 priority)
2255 /* only cores on SI_BUS share GPIO's and only applcation users need to
2256 * reserve/release GPIO
2258 if ((BUSTYPE(sih->bustype) != SI_BUS) || (!priority)) {
2259 ASSERT((BUSTYPE(sih->bustype) == SI_BUS) && (priority));
2262 /* make sure only one bit is set */
2263 if ((!gpio_bitmask) || ((gpio_bitmask) & (gpio_bitmask - 1))) {
2264 ASSERT((gpio_bitmask)
2265 && !((gpio_bitmask) & (gpio_bitmask - 1)));
2269 /* already released */
2270 if (!(si_gpioreservation & gpio_bitmask))
2273 /* clear reservation */
2274 si_gpioreservation &= ~gpio_bitmask;
2276 return si_gpioreservation;
2279 /* return the current gpioin register value */
2280 uint32 si_gpioin(si_t *sih)
2288 regoff = OFFSETOF(chipcregs_t, gpioin);
2289 return (si_corereg(sih, SI_CC_IDX, regoff, 0, 0));
2292 /* mask&set gpio interrupt polarity bits */
2293 uint32 si_gpiointpolarity(si_t *sih, uint32 mask, uint32 val, uint8 priority)
2301 /* gpios could be shared on router platforms */
2302 if ((BUSTYPE(sih->bustype) == SI_BUS) && (val || mask)) {
2303 mask = priority ? (si_gpioreservation & mask) :
2304 ((si_gpioreservation | mask) & ~(si_gpioreservation));
2308 regoff = OFFSETOF(chipcregs_t, gpiointpolarity);
2309 return (si_corereg(sih, SI_CC_IDX, regoff, mask, val));
2312 /* mask&set gpio interrupt mask bits */
2313 uint32 si_gpiointmask(si_t *sih, uint32 mask, uint32 val, uint8 priority)
2321 /* gpios could be shared on router platforms */
2322 if ((BUSTYPE(sih->bustype) == SI_BUS) && (val || mask)) {
2323 mask = priority ? (si_gpioreservation & mask) :
2324 ((si_gpioreservation | mask) & ~(si_gpioreservation));
2328 regoff = OFFSETOF(chipcregs_t, gpiointmask);
2329 return (si_corereg(sih, SI_CC_IDX, regoff, mask, val));
2332 /* assign the gpio to an led */
2333 uint32 si_gpioled(si_t *sih, uint32 mask, uint32 val)
2338 if (sih->ccrev < 16)
2341 /* gpio led powersave reg */
2343 (sih, SI_CC_IDX, OFFSETOF(chipcregs_t, gpiotimeroutmask), mask,
2347 /* mask&set gpio timer val */
2348 uint32 si_gpiotimerval(si_t *sih, uint32 mask, uint32 gpiotimerval)
2354 if (sih->ccrev < 16)
2357 return (si_corereg(sih, SI_CC_IDX,
2358 OFFSETOF(chipcregs_t, gpiotimerval), mask,
2362 uint32 si_gpiopull(si_t *sih, bool updown, uint32 mask, uint32 val)
2368 if (sih->ccrev < 20)
2372 (updown ? OFFSETOF(chipcregs_t, gpiopulldown) :
2373 OFFSETOF(chipcregs_t, gpiopullup));
2374 return (si_corereg(sih, SI_CC_IDX, offs, mask, val));
2377 uint32 si_gpioevent(si_t *sih, uint regtype, uint32 mask, uint32 val)
2383 if (sih->ccrev < 11)
2386 if (regtype == GPIO_REGEVT)
2387 offs = OFFSETOF(chipcregs_t, gpioevent);
2388 else if (regtype == GPIO_REGEVT_INTMSK)
2389 offs = OFFSETOF(chipcregs_t, gpioeventintmask);
2390 else if (regtype == GPIO_REGEVT_INTPOL)
2391 offs = OFFSETOF(chipcregs_t, gpioeventintpolarity);
2395 return (si_corereg(sih, SI_CC_IDX, offs, mask, val));
2398 void *BCMATTACHFN(si_gpio_handler_register) (si_t *sih, uint32 event,
2399 bool level, gpio_handler_t cb,
2408 if (sih->ccrev < 11)
2411 if ((gi = MALLOC(sii->osh, sizeof(gpioh_item_t))) == NULL)
2414 bzero(gi, sizeof(gpioh_item_t));
2420 gi->next = sii->gpioh_head;
2421 sii->gpioh_head = gi;
2423 return (void *)(gi);
2426 void BCMATTACHFN(si_gpio_handler_unregister) (si_t *sih, void *gpioh)
2429 gpioh_item_t *p, *n;
2432 if (sih->ccrev < 11)
2435 ASSERT(sii->gpioh_head != NULL);
2436 if ((void *)sii->gpioh_head == gpioh) {
2437 sii->gpioh_head = sii->gpioh_head->next;
2438 MFREE(sii->osh, gpioh, sizeof(gpioh_item_t));
2441 p = sii->gpioh_head;
2444 if ((void *)n == gpioh) {
2446 MFREE(sii->osh, gpioh, sizeof(gpioh_item_t));
2454 ASSERT(0); /* Not found in list */
2457 void si_gpio_handler_process(si_t *sih)
2462 uint32 level = si_gpioin(sih);
2463 uint32 edge = si_gpioevent(sih, GPIO_REGEVT, 0, 0);
2466 for (h = sii->gpioh_head; h != NULL; h = h->next) {
2468 status = (h->level ? level : edge);
2470 if (status & h->event)
2471 h->handler(status, h->arg);
2475 si_gpioevent(sih, GPIO_REGEVT, edge, edge); /* clear edge-trigger status */
2478 uint32 si_gpio_int_enable(si_t *sih, bool enable)
2484 if (sih->ccrev < 11)
2487 offs = OFFSETOF(chipcregs_t, intmask);
2489 (sih, SI_CC_IDX, offs, CI_GPIO, (enable ? CI_GPIO : 0)));
2492 /* Return the size of the specified SOCRAM bank */
2494 socram_banksize(si_info_t *sii, sbsocramregs_t *regs, uint8 index,
2497 uint banksize, bankinfo;
2498 uint bankidx = index | (mem_type << SOCRAM_BANKIDX_MEMTYPE_SHIFT);
2500 ASSERT(mem_type <= SOCRAM_MEMTYPE_DEVRAM);
2502 W_REG(sii->osh, ®s->bankidx, bankidx);
2503 bankinfo = R_REG(sii->osh, ®s->bankinfo);
2505 SOCRAM_BANKINFO_SZBASE * ((bankinfo & SOCRAM_BANKINFO_SZMASK) + 1);
2509 void si_socdevram(si_t *sih, bool set, uint8 *enable, uint8 *protect)
2514 sbsocramregs_t *regs;
2520 /* Block ints and save current core */
2521 INTR_OFF(sii, intr_val);
2522 origidx = si_coreidx(sih);
2525 *enable = *protect = 0;
2527 /* Switch to SOCRAM core */
2528 if (!(regs = si_setcore(sih, SOCRAM_CORE_ID, 0)))
2531 /* Get info for determining size */
2532 if (!(wasup = si_iscoreup(sih)))
2533 si_core_reset(sih, 0, 0);
2535 corerev = si_corerev(sih);
2536 if (corerev >= 10) {
2540 uint32 bankidx, bankinfo;
2542 extcinfo = R_REG(sii->osh, ®s->extracoreinfo);
2543 nb = ((extcinfo & SOCRAM_DEVRAMBANK_MASK) >>
2544 SOCRAM_DEVRAMBANK_SHIFT);
2545 for (i = 0; i < nb; i++) {
2547 i | (SOCRAM_MEMTYPE_DEVRAM <<
2548 SOCRAM_BANKIDX_MEMTYPE_SHIFT);
2549 W_REG(sii->osh, ®s->bankidx, bankidx);
2550 bankinfo = R_REG(sii->osh, ®s->bankinfo);
2552 bankinfo &= ~SOCRAM_BANKINFO_DEVRAMSEL_MASK;
2553 bankinfo &= ~SOCRAM_BANKINFO_DEVRAMPRO_MASK;
2557 SOCRAM_BANKINFO_DEVRAMSEL_SHIFT);
2561 SOCRAM_BANKINFO_DEVRAMPRO_SHIFT);
2563 W_REG(sii->osh, ®s->bankinfo, bankinfo);
2564 } else if (i == 0) {
2565 if (bankinfo & SOCRAM_BANKINFO_DEVRAMSEL_MASK) {
2568 SOCRAM_BANKINFO_DEVRAMPRO_MASK)
2575 /* Return to previous state and core */
2577 si_core_disable(sih, 0);
2578 si_setcoreidx(sih, origidx);
2581 INTR_RESTORE(sii, intr_val);
2584 bool si_socdevram_pkg(si_t *sih)
2586 if (si_socdevram_size(sih) > 0)
2592 uint32 si_socdevram_size(si_t *sih)
2598 sbsocramregs_t *regs;
2604 /* Block ints and save current core */
2605 INTR_OFF(sii, intr_val);
2606 origidx = si_coreidx(sih);
2608 /* Switch to SOCRAM core */
2609 if (!(regs = si_setcore(sih, SOCRAM_CORE_ID, 0)))
2612 /* Get info for determining size */
2613 if (!(wasup = si_iscoreup(sih)))
2614 si_core_reset(sih, 0, 0);
2616 corerev = si_corerev(sih);
2617 if (corerev >= 10) {
2622 extcinfo = R_REG(sii->osh, ®s->extracoreinfo);
2623 nb = (((extcinfo & SOCRAM_DEVRAMBANK_MASK) >>
2624 SOCRAM_DEVRAMBANK_SHIFT));
2625 for (i = 0; i < nb; i++)
2627 socram_banksize(sii, regs, i,
2628 SOCRAM_MEMTYPE_DEVRAM);
2631 /* Return to previous state and core */
2633 si_core_disable(sih, 0);
2634 si_setcoreidx(sih, origidx);
2637 INTR_RESTORE(sii, intr_val);
2642 /* Return the RAM size of the SOCRAM core */
2643 uint32 si_socram_size(si_t *sih)
2649 sbsocramregs_t *regs;
2657 /* Block ints and save current core */
2658 INTR_OFF(sii, intr_val);
2659 origidx = si_coreidx(sih);
2661 /* Switch to SOCRAM core */
2662 if (!(regs = si_setcore(sih, SOCRAM_CORE_ID, 0)))
2665 /* Get info for determining size */
2666 if (!(wasup = si_iscoreup(sih)))
2667 si_core_reset(sih, 0, 0);
2668 corerev = si_corerev(sih);
2669 coreinfo = R_REG(sii->osh, ®s->coreinfo);
2671 /* Calculate size from coreinfo based on rev */
2673 memsize = 1 << (16 + (coreinfo & SRCI_MS0_MASK));
2674 else if (corerev < 3) {
2675 memsize = 1 << (SR_BSZ_BASE + (coreinfo & SRCI_SRBSZ_MASK));
2676 memsize *= (coreinfo & SRCI_SRNB_MASK) >> SRCI_SRNB_SHIFT;
2677 } else if ((corerev <= 7) || (corerev == 12)) {
2678 uint nb = (coreinfo & SRCI_SRNB_MASK) >> SRCI_SRNB_SHIFT;
2679 uint bsz = (coreinfo & SRCI_SRBSZ_MASK);
2680 uint lss = (coreinfo & SRCI_LSS_MASK) >> SRCI_LSS_SHIFT;
2683 memsize = nb * (1 << (bsz + SR_BSZ_BASE));
2685 memsize += (1 << ((lss - 1) + SR_BSZ_BASE));
2688 uint nb = (coreinfo & SRCI_SRNB_MASK) >> SRCI_SRNB_SHIFT;
2689 for (i = 0; i < nb; i++)
2691 socram_banksize(sii, regs, i, SOCRAM_MEMTYPE_RAM);
2694 /* Return to previous state and core */
2696 si_core_disable(sih, 0);
2697 si_setcoreidx(sih, origidx);
2700 INTR_RESTORE(sii, intr_val);
2705 void si_chipcontrl_epa4331(si_t *sih, bool on)
2713 origidx = si_coreidx(sih);
2715 cc = (chipcregs_t *) si_setcore(sih, CC_CORE_ID, 0);
2717 val = R_REG(sii->osh, &cc->chipcontrol);
2720 if (sih->chippkg == 9 || sih->chippkg == 0xb) {
2721 /* Ext PA Controls for 4331 12x9 Package */
2722 W_REG(sii->osh, &cc->chipcontrol, val |
2723 (CCTRL4331_EXTPA_EN |
2724 CCTRL4331_EXTPA_ON_GPIO2_5));
2726 /* Ext PA Controls for 4331 12x12 Package */
2727 W_REG(sii->osh, &cc->chipcontrol,
2728 val | (CCTRL4331_EXTPA_EN));
2731 val &= ~(CCTRL4331_EXTPA_EN | CCTRL4331_EXTPA_ON_GPIO2_5);
2732 W_REG(sii->osh, &cc->chipcontrol, val);
2735 si_setcoreidx(sih, origidx);
2738 /* Enable BT-COEX & Ex-PA for 4313 */
2739 void si_epa_4313war(si_t *sih)
2746 origidx = si_coreidx(sih);
2748 cc = (chipcregs_t *) si_setcore(sih, CC_CORE_ID, 0);
2751 W_REG(sii->osh, &cc->gpiocontrol,
2752 R_REG(sii->osh, &cc->gpiocontrol) | GPIO_CTRL_EPA_EN_MASK);
2754 si_setcoreidx(sih, origidx);
2757 /* check if the device is removed */
2758 bool si_deviceremoved(si_t *sih)
2765 switch (BUSTYPE(sih->bustype)) {
2767 ASSERT(sii->osh != NULL);
2768 w = OSL_PCI_READ_CONFIG(sii->osh, PCI_CFG_VID, sizeof(uint32));
2769 if ((w & 0xFFFF) != VENDOR_BROADCOM)
2776 bool si_is_sprom_available(si_t *sih)
2778 if (sih->ccrev >= 31) {
2784 if ((sih->cccaps & CC_CAP_SROM) == 0)
2788 origidx = sii->curidx;
2789 cc = si_setcoreidx(sih, SI_CC_IDX);
2790 sromctrl = R_REG(sii->osh, &cc->sromcontrol);
2791 si_setcoreidx(sih, origidx);
2792 return (sromctrl & SRC_PRESENT);
2795 switch (CHIPID(sih->chip)) {
2796 case BCM4329_CHIP_ID:
2797 return (sih->chipst & CST4329_SPROM_SEL) != 0;
2798 case BCM4319_CHIP_ID:
2799 return (sih->chipst & CST4319_SPROM_SEL) != 0;
2800 case BCM4336_CHIP_ID:
2801 return (sih->chipst & CST4336_SPROM_PRESENT) != 0;
2802 case BCM4330_CHIP_ID:
2803 return (sih->chipst & CST4330_SPROM_PRESENT) != 0;
2804 case BCM4313_CHIP_ID:
2805 return (sih->chipst & CST4313_SPROM_PRESENT) != 0;
2806 case BCM4331_CHIP_ID:
2807 return (sih->chipst & CST4331_SPROM_PRESENT) != 0;
2813 bool si_is_otp_disabled(si_t *sih)
2815 switch (CHIPID(sih->chip)) {
2816 case BCM4329_CHIP_ID:
2817 return (sih->chipst & CST4329_SPROM_OTP_SEL_MASK) ==
2819 case BCM4319_CHIP_ID:
2820 return (sih->chipst & CST4319_SPROM_OTP_SEL_MASK) ==
2822 case BCM4336_CHIP_ID:
2823 return ((sih->chipst & CST4336_OTP_PRESENT) == 0);
2824 case BCM4330_CHIP_ID:
2825 return ((sih->chipst & CST4330_OTP_PRESENT) == 0);
2826 case BCM4313_CHIP_ID:
2827 return (sih->chipst & CST4313_OTP_PRESENT) == 0;
2828 /* These chips always have their OTP on */
2829 case BCM43224_CHIP_ID:
2830 case BCM43225_CHIP_ID:
2831 case BCM43421_CHIP_ID:
2832 case BCM43235_CHIP_ID:
2833 case BCM43236_CHIP_ID:
2834 case BCM43238_CHIP_ID:
2835 case BCM4331_CHIP_ID:
2841 bool si_is_otp_powered(si_t *sih)
2843 if (PMUCTL_ENAB(sih))
2844 return si_pmu_is_otp_powered(sih, si_osh(sih));
2848 void si_otp_power(si_t *sih, bool on)
2850 if (PMUCTL_ENAB(sih))
2851 si_pmu_otp_power(sih, si_osh(sih), on);
2857 si_is_sprom_enabled(si_t *sih)
2859 BCMATTACHFN(si_is_sprom_enabled) (si_t *sih)
2868 si_sprom_enable(si_t *sih, bool enable)
2870 BCMATTACHFN(si_sprom_enable) (si_t *sih, bool enable)
2873 if (PMUCTL_ENAB(sih))
2874 si_pmu_sprom_enable(sih, si_osh(sih), enable);
2877 /* Return BCME_NOTFOUND if the card doesn't have CIS format nvram */
2878 int si_cis_source(si_t *sih)
2880 /* Many chips have the same mapping of their chipstatus field */
2881 static const uint cis_sel[] =
2882 { CIS_DEFAULT, CIS_SROM, CIS_OTP, CIS_SROM };
2883 static const uint cis_43236_sel[] =
2884 { CIS_DEFAULT, CIS_SROM, CIS_OTP, CIS_OTP };
2886 /* PCI chips use SROM format instead of CIS */
2887 if (BUSTYPE(sih->bustype) == PCI_BUS)
2888 return BCME_NOTFOUND;
2890 switch (CHIPID(sih->chip)) {
2891 case BCM43235_CHIP_ID:
2892 case BCM43236_CHIP_ID:
2893 case BCM43238_CHIP_ID:{
2896 chipst & CST4322_SPROM_OTP_SEL_MASK) >>
2897 CST4322_SPROM_OTP_SEL_SHIFT;
2899 sizeof(cis_sel)) ? CIS_DEFAULT :
2900 cis_43236_sel[strap]);
2903 case BCM4329_CHIP_ID:
2904 return ((sih->chipst & CST4329_SPROM_OTP_SEL_MASK) >=
2905 sizeof(cis_sel)) ? CIS_DEFAULT : cis_sel[(sih->
2907 CST4329_SPROM_OTP_SEL_MASK)];
2908 case BCM4319_CHIP_ID:{
2911 chipst & CST4319_SPROM_OTP_SEL_MASK) >>
2912 CST4319_SPROM_OTP_SEL_SHIFT);
2913 return (cis_sel4319 >=
2914 sizeof(cis_sel)) ? CIS_DEFAULT :
2915 cis_sel[cis_sel4319];
2917 case BCM4336_CHIP_ID:{
2918 if (sih->chipst & CST4336_SPROM_PRESENT)
2920 if (sih->chipst & CST4336_OTP_PRESENT)
2924 case BCM4330_CHIP_ID:{
2925 if (sih->chipst & CST4330_SPROM_PRESENT)
2927 if (sih->chipst & CST4330_OTP_PRESENT)