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.
20 #include <linux/kernel.h>
21 #include <linux/string.h>
29 #include <pcie_core.h>
41 #include <sbsdpcmdev.h>
46 /* this file now contains only definitions for sb functions, only necessary
47 *for devices using Sonics backplanes (bcm4329)
50 /* if an amba SDIO device is supported, please further restrict the inclusion
54 #include "siutils_priv.h"
57 /* local prototypes */
58 static si_info_t *si_doattach(si_info_t *sii, uint devid, osl_t *osh,
59 void *regs, uint bustype, void *sdh, char **vars,
61 static bool si_buscore_prep(si_info_t *sii, uint bustype, uint devid,
63 static bool si_buscore_setup(si_info_t *sii, chipcregs_t *cc, uint bustype,
64 uint32 savewin, uint *origidx, void *regs);
65 static void si_nvram_process(si_info_t *sii, char *pvars);
67 /* dev path concatenation util */
68 static char *si_devpathvar(si_t *sih, char *var, int len, const char *name);
69 static bool _si_clkctl_cc(si_info_t *sii, uint mode);
70 static bool si_ispcie(si_info_t *sii);
71 static uint BCMINITFN(socram_banksize) (si_info_t *sii, sbsocramregs_t *r,
74 /* global variable to indicate reservation/release of gpio's */
75 static uint32 si_gpioreservation;
77 /* global flag to prevent shared resources from being initialized multiple times in si_attach() */
80 * Allocate a si handle.
81 * devid - pci device id (used to determine chip#)
82 * osh - opaque OS handle
83 * regs - virtual address of initial core registers
84 * bustype - pci/sb/sdio/etc
85 * vars - pointer to a pointer area for "environment" variables
86 * varsz - pointer to int to return the size of the vars
88 si_t *BCMATTACHFN(si_attach) (uint devid, osl_t *osh, void *regs,
89 uint bustype, void *sdh, char **vars,
94 sii = MALLOC(osh, sizeof(si_info_t));
96 SI_ERROR(("si_attach: malloc failed! malloced %d bytes\n",
101 if (si_doattach(sii, devid, osh, regs, bustype, sdh, vars, varsz) ==
103 MFREE(osh, sii, sizeof(si_info_t));
106 sii->vars = vars ? *vars : NULL;
107 sii->varsz = varsz ? *varsz : 0;
112 /* global kernel resource */
113 static si_info_t ksii;
115 static uint32 wd_msticks; /* watchdog timer ticks normalized to ms */
118 BCMATTACHFN(si_buscore_prep) (si_info_t *sii, uint bustype, uint devid,
122 /* kludge to enable the clock on the 4306 which lacks a slowclock */
123 if (BUSTYPE(bustype) == PCI_BUS && !si_ispcie(sii))
124 si_clkctl_xtal(&sii->pub, XTAL | PLL, ON);
128 if (BUSTYPE(bustype) == SDIO_BUS) {
132 /* Try forcing SDIO core to do ALPAvail request only */
133 clkset = SBSDIO_FORCE_HW_CLKREQ_OFF | SBSDIO_ALP_AVAIL_REQ;
134 bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR,
139 /* If register supported, wait for ALPAvail and then force ALP */
141 bcmsdh_cfg_read(sdh, SDIO_FUNC_1,
142 SBSDIO_FUNC1_CHIPCLKCSR, NULL);
143 if ((clkval & ~SBSDIO_AVBITS) == clkset) {
145 bcmsdh_cfg_read(sdh, SDIO_FUNC_1,
146 SBSDIO_FUNC1_CHIPCLKCSR,
148 !SBSDIO_ALPAV(clkval)),
149 PMU_MAX_TRANSITION_DLY);
150 if (!SBSDIO_ALPAV(clkval)) {
151 SI_ERROR(("timeout on ALPAV wait, clkval 0x%02x\n", clkval));
155 SBSDIO_FORCE_HW_CLKREQ_OFF |
157 bcmsdh_cfg_write(sdh, SDIO_FUNC_1,
158 SBSDIO_FUNC1_CHIPCLKCSR,
164 /* Also, disable the extra SDIO pull-ups */
165 bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_SDIOPULLUP, 0,
168 #endif /* defined(BCMSDIO) */
174 BCMATTACHFN(si_buscore_setup) (si_info_t *sii, chipcregs_t *cc, uint bustype,
175 uint32 savewin, uint *origidx, void *regs) {
178 uint pciidx, pcieidx, pcirev, pcierev;
180 cc = si_setcoreidx(&sii->pub, SI_CC_IDX);
181 ASSERT((uintptr) cc);
183 /* get chipcommon rev */
184 sii->pub.ccrev = (int)si_corerev(&sii->pub);
186 /* get chipcommon chipstatus */
187 if (sii->pub.ccrev >= 11)
188 sii->pub.chipst = R_REG(sii->osh, &cc->chipstatus);
190 /* get chipcommon capabilites */
191 sii->pub.cccaps = R_REG(sii->osh, &cc->capabilities);
192 /* get chipcommon extended capabilities */
195 if (sii->pub.ccrev >= 35)
196 sii->pub.cccaps_ext = R_REG(sii->osh, &cc->capabilities_ext);
198 /* get pmu rev and caps */
199 if (sii->pub.cccaps & CC_CAP_PMU) {
200 sii->pub.pmucaps = R_REG(sii->osh, &cc->pmucapabilities);
201 sii->pub.pmurev = sii->pub.pmucaps & PCAP_REV_MASK;
205 SI_MSG(("Chipc: rev %d, caps 0x%x, chipst 0x%x pmurev %d, pmucaps 0x%x\n",
206 sii->pub.ccrev, sii->pub.cccaps, sii->pub.chipst, sii->pub.pmurev,
210 /* figure out bus/orignal core idx */
211 sii->pub.buscoretype = NODEV_CORE_ID;
212 sii->pub.buscorerev = NOREV;
213 sii->pub.buscoreidx = BADIDX;
216 pcirev = pcierev = NOREV;
217 pciidx = pcieidx = BADIDX;
219 for (i = 0; i < sii->numcores; i++) {
222 si_setcoreidx(&sii->pub, i);
223 cid = si_coreid(&sii->pub);
224 crev = si_corerev(&sii->pub);
226 /* Display cores found */
227 SI_VMSG(("CORE[%d]: id 0x%x rev %d base 0x%x regs 0x%p\n",
228 i, cid, crev, sii->coresba[i], sii->regs[i]));
230 if (BUSTYPE(bustype) == PCI_BUS) {
231 if (cid == PCI_CORE_ID) {
235 } else if (cid == PCIE_CORE_ID) {
242 else if (((BUSTYPE(bustype) == SDIO_BUS) ||
243 (BUSTYPE(bustype) == SPI_BUS)) &&
244 ((cid == PCMCIA_CORE_ID) || (cid == SDIOD_CORE_ID))) {
245 sii->pub.buscorerev = crev;
246 sii->pub.buscoretype = cid;
247 sii->pub.buscoreidx = i;
251 /* find the core idx before entering this func. */
252 if ((savewin && (savewin == sii->coresba[i])) ||
253 (regs == sii->regs[i]))
258 SI_MSG(("Buscore id/type/rev %d/0x%x/%d\n", sii->pub.buscoreidx,
259 sii->pub.buscoretype, sii->pub.buscorerev));
261 /* Make sure any on-chip ARM is off (in case strapping is wrong),
262 * or downloaded code was
265 if ((BUSTYPE(bustype) == SDIO_BUS) || (BUSTYPE(bustype) == SPI_BUS)) {
266 if (si_setcore(&sii->pub, ARM7S_CORE_ID, 0) ||
267 si_setcore(&sii->pub, ARMCM3_CORE_ID, 0))
268 si_core_disable(&sii->pub, 0);
278 sii->pub.buscoretype = PCI_CORE_ID;
279 sii->pub.buscorerev = pcirev;
280 sii->pub.buscoreidx = pciidx;
282 sii->pub.buscoretype = PCIE_CORE_ID;
283 sii->pub.buscorerev = pcierev;
284 sii->pub.buscoreidx = pcieidx;
287 SI_VMSG(("Buscore id/type/rev %d/0x%x/%d\n", sii->pub.buscoreidx,
288 sii->pub.buscoretype, sii->pub.buscorerev));
290 /* fixup necessary chip/core configurations */
291 if (BUSTYPE(sii->pub.bustype) == PCI_BUS) {
294 sii->pch = (void *)(uintptr)pcicore_init(
296 (void *)PCIEREGS(sii));
297 if (sii->pch == NULL)
301 if (si_pci_fixcfg(&sii->pub)) {
302 SI_ERROR(("si_doattach: sb_pci_fixcfg failed\n"));
307 /* return to the original core */
308 si_setcoreidx(&sii->pub, *origidx);
313 static __used void BCMATTACHFN(si_nvram_process) (si_info_t *sii, char *pvars)
317 /* get boardtype and boardrev */
318 switch (BUSTYPE(sii->pub.bustype)) {
320 /* do a pci config read to get subsystem id and subvendor id */
321 w = OSL_PCI_READ_CONFIG(sii->osh, PCI_CFG_SVID, sizeof(uint32));
322 /* Let nvram variables override subsystem Vend/ID */
323 sii->pub.boardvendor = (uint16)si_getdevpathintvar(&sii->pub,
325 if (sii->pub.boardvendor == 0)
326 sii->pub.boardvendor = w & 0xffff;
328 SI_ERROR(("Overriding boardvendor: 0x%x instead of 0x%x\n", sii->pub.boardvendor, w & 0xffff));
329 sii->pub.boardtype = (uint16)si_getdevpathintvar(&sii->pub,
331 if (sii->pub.boardtype == 0)
332 sii->pub.boardtype = (w >> 16) & 0xffff;
334 SI_ERROR(("Overriding boardtype: 0x%x instead of 0x%x\n", sii->pub.boardtype, (w >> 16) & 0xffff));
340 sii->pub.boardvendor = getintvar(pvars, "manfid");
341 sii->pub.boardtype = getintvar(pvars, "prodid");
346 sii->pub.boardvendor = VENDOR_BROADCOM;
347 sii->pub.boardtype = SPI_BOARD;
353 sii->pub.boardvendor = VENDOR_BROADCOM;
354 sii->pub.boardtype = getintvar(pvars, "prodid");
355 if (pvars == NULL || (sii->pub.boardtype == 0)) {
356 sii->pub.boardtype = getintvar(NULL, "boardtype");
357 if (sii->pub.boardtype == 0)
358 sii->pub.boardtype = 0xffff;
363 if (sii->pub.boardtype == 0) {
364 SI_ERROR(("si_doattach: unknown board type\n"));
365 ASSERT(sii->pub.boardtype);
368 sii->pub.boardflags = getintvar(pvars, "boardflags");
371 /* this is will make Sonics calls directly, since Sonics is no longer supported in the Si abstraction */
372 /* this has been customized for the bcm 4329 ONLY */
374 static si_info_t *BCMATTACHFN(si_doattach) (si_info_t *sii, uint devid,
375 osl_t *osh, void *regs,
376 uint bustype, void *sdh,
377 char **vars, uint *varsz) {
378 struct si_pub *sih = &sii->pub;
384 ASSERT(GOODREGS(regs));
386 bzero((uchar *) sii, sizeof(si_info_t));
390 sih->buscoreidx = BADIDX;
396 /* find Chipcommon address */
397 cc = (chipcregs_t *) sii->curmap;
398 sih->bustype = bustype;
400 if (bustype != BUSTYPE(bustype)) {
401 SI_ERROR(("si_doattach: bus type %d does not match configured bus type %d\n", bustype, BUSTYPE(bustype)));
405 /* bus/core/clk setup for register access */
406 if (!si_buscore_prep(sii, bustype, devid, sdh)) {
407 SI_ERROR(("si_doattach: si_core_clk_prep failed %d\n",
412 /* ChipID recognition.
413 * We assume we can read chipid at offset 0 from the regs arg.
414 * If we add other chiptypes (or if we need to support old sdio hosts w/o chipcommon),
415 * some way of recognizing them needs to be added here.
417 w = R_REG(osh, &cc->chipid);
418 sih->socitype = (w & CID_TYPE_MASK) >> CID_TYPE_SHIFT;
419 /* Might as wll fill in chip id rev & pkg */
420 sih->chip = w & CID_ID_MASK;
421 sih->chiprev = (w & CID_REV_MASK) >> CID_REV_SHIFT;
422 sih->chippkg = (w & CID_PKG_MASK) >> CID_PKG_SHIFT;
424 if ((CHIPID(sih->chip) == BCM4329_CHIP_ID) &&
425 (sih->chippkg != BCM4329_289PIN_PKG_ID))
426 sih->chippkg = BCM4329_182PIN_PKG_ID;
428 sih->issim = IS_SIM(sih->chippkg);
431 /* SI_MSG(("Found chip type SB (0x%08x)\n", w)); */
432 sb_scan(&sii->pub, regs, devid);
434 /* no cores found, bail out */
435 if (sii->numcores == 0) {
436 SI_ERROR(("si_doattach: could not find any cores\n"));
439 /* bus/core/clk setup */
441 if (!si_buscore_setup(sii, cc, bustype, savewin, &origidx, regs)) {
442 SI_ERROR(("si_doattach: si_buscore_setup failed\n"));
449 /* Init nvram from flash if it exists */
450 nvram_init((void *)&(sii->pub));
452 /* Init nvram from sprom/otp if they exist */
454 (&sii->pub, BUSTYPE(bustype), regs, sii->osh, vars, varsz)) {
455 SI_ERROR(("si_doattach: srom_var_init failed: bad srom\n"));
458 pvars = vars ? *vars : NULL;
459 si_nvram_process(sii, pvars);
462 /* === NVRAM, clock is ready === */
465 if (sii->pub.ccrev >= 20) {
467 cc = (chipcregs_t *) si_setcore(sih, CC_CORE_ID, 0);
468 W_REG(osh, &cc->gpiopullup, 0);
469 W_REG(osh, &cc->gpiopulldown, 0);
470 sb_setcoreidx(sih, origidx);
476 /* PMU specific initializations */
477 if (PMUCTL_ENAB(sih)) {
479 si_pmu_init(sih, sii->osh);
480 si_pmu_chip_init(sih, sii->osh);
481 xtalfreq = getintvar(pvars, "xtalfreq");
482 /* If xtalfreq var not available, try to measure it */
484 xtalfreq = si_pmu_measure_alpclk(sih, sii->osh);
485 si_pmu_pll_init(sih, sii->osh, xtalfreq);
486 si_pmu_res_init(sih, sii->osh);
487 si_pmu_swreg_init(sih, sii->osh);
490 /* setup the GPIO based LED powersave register */
491 w = getintvar(pvars, "leddc");
493 w = DEFAULT_GPIOTIMERVAL;
494 sb_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, gpiotimerval), ~0, w);
497 /* clear any previous epidiag-induced target abort */
498 sb_taclear(sih, FALSE);
509 static si_info_t *BCMATTACHFN(si_doattach) (si_info_t *sii, uint devid,
510 osl_t *osh, void *regs,
511 uint bustype, void *sdh,
512 char **vars, uint *varsz) {
513 struct si_pub *sih = &sii->pub;
519 ASSERT(GOODREGS(regs));
521 bzero((uchar *) sii, sizeof(si_info_t));
525 sih->buscoreidx = BADIDX;
531 /* check to see if we are a si core mimic'ing a pci core */
532 if ((bustype == PCI_BUS) &&
533 (OSL_PCI_READ_CONFIG(sii->osh, PCI_SPROM_CONTROL, sizeof(uint32)) ==
535 SI_ERROR(("%s: incoming bus is PCI but it's a lie, switching to SI " "devid:0x%x\n", __func__, devid));
539 /* find Chipcommon address */
540 if (bustype == PCI_BUS) {
542 OSL_PCI_READ_CONFIG(sii->osh, PCI_BAR0_WIN, sizeof(uint32));
543 if (!GOODCOREADDR(savewin, SI_ENUM_BASE))
544 savewin = SI_ENUM_BASE;
545 OSL_PCI_WRITE_CONFIG(sii->osh, PCI_BAR0_WIN, 4, SI_ENUM_BASE);
546 cc = (chipcregs_t *) regs;
548 cc = (chipcregs_t *) REG_MAP(SI_ENUM_BASE, SI_CORE_SIZE);
551 sih->bustype = bustype;
552 if (bustype != BUSTYPE(bustype)) {
553 SI_ERROR(("si_doattach: bus type %d does not match configured bus type %d\n", bustype, BUSTYPE(bustype)));
557 /* bus/core/clk setup for register access */
558 if (!si_buscore_prep(sii, bustype, devid, sdh)) {
559 SI_ERROR(("si_doattach: si_core_clk_prep failed %d\n",
564 /* ChipID recognition.
565 * We assume we can read chipid at offset 0 from the regs arg.
566 * If we add other chiptypes (or if we need to support old sdio hosts w/o chipcommon),
567 * some way of recognizing them needs to be added here.
569 w = R_REG(osh, &cc->chipid);
570 sih->socitype = (w & CID_TYPE_MASK) >> CID_TYPE_SHIFT;
571 /* Might as wll fill in chip id rev & pkg */
572 sih->chip = w & CID_ID_MASK;
573 sih->chiprev = (w & CID_REV_MASK) >> CID_REV_SHIFT;
574 sih->chippkg = (w & CID_PKG_MASK) >> CID_PKG_SHIFT;
576 sih->issim = IS_SIM(sih->chippkg);
579 if (CHIPTYPE(sii->pub.socitype) == SOCI_AI) {
580 SI_MSG(("Found chip type AI (0x%08x)\n", w));
581 /* pass chipc address instead of original core base */
582 ai_scan(&sii->pub, (void *)(uintptr) cc, devid);
584 SI_ERROR(("Found chip of unknown type (0x%08x)\n", w));
587 /* no cores found, bail out */
588 if (sii->numcores == 0) {
589 SI_ERROR(("si_doattach: could not find any cores\n"));
592 /* bus/core/clk setup */
594 if (!si_buscore_setup(sii, cc, bustype, savewin, &origidx, regs)) {
595 SI_ERROR(("si_doattach: si_buscore_setup failed\n"));
599 /* assume current core is CC */
600 if ((sii->pub.ccrev == 0x25)
602 ((CHIPID(sih->chip) == BCM43236_CHIP_ID
603 || CHIPID(sih->chip) == BCM43235_CHIP_ID
604 || CHIPID(sih->chip) == BCM43238_CHIP_ID)
605 && (CHIPREV(sii->pub.chiprev) <= 2))) {
607 if ((cc->chipstatus & CST43236_BP_CLK) != 0) {
609 clkdiv = R_REG(osh, &cc->clkdiv);
610 /* otp_clk_div is even number, 120/14 < 9mhz */
611 clkdiv = (clkdiv & ~CLKD_OTP) | (14 << CLKD_OTP_SHIFT);
612 W_REG(osh, &cc->clkdiv, clkdiv);
613 SI_ERROR(("%s: set clkdiv to %x\n", __func__, clkdiv));
618 /* Init nvram from flash if it exists */
619 nvram_init((void *)&(sii->pub));
621 /* Init nvram from sprom/otp if they exist */
623 (&sii->pub, BUSTYPE(bustype), regs, sii->osh, vars, varsz)) {
624 SI_ERROR(("si_doattach: srom_var_init failed: bad srom\n"));
627 pvars = vars ? *vars : NULL;
628 si_nvram_process(sii, pvars);
630 /* === NVRAM, clock is ready === */
631 cc = (chipcregs_t *) si_setcore(sih, CC_CORE_ID, 0);
632 W_REG(osh, &cc->gpiopullup, 0);
633 W_REG(osh, &cc->gpiopulldown, 0);
634 si_setcoreidx(sih, origidx);
636 /* PMU specific initializations */
637 if (PMUCTL_ENAB(sih)) {
639 si_pmu_init(sih, sii->osh);
640 si_pmu_chip_init(sih, sii->osh);
641 xtalfreq = getintvar(pvars, "xtalfreq");
642 /* If xtalfreq var not available, try to measure it */
644 xtalfreq = si_pmu_measure_alpclk(sih, sii->osh);
645 si_pmu_pll_init(sih, sii->osh, xtalfreq);
646 si_pmu_res_init(sih, sii->osh);
647 si_pmu_swreg_init(sih, sii->osh);
650 /* setup the GPIO based LED powersave register */
651 w = getintvar(pvars, "leddc");
653 w = DEFAULT_GPIOTIMERVAL;
654 si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, gpiotimerval), ~0, w);
657 ASSERT(sii->pch != NULL);
658 pcicore_attach(sii->pch, pvars, SI_DOATTACH);
661 if ((CHIPID(sih->chip) == BCM43224_CHIP_ID) ||
662 (CHIPID(sih->chip) == BCM43421_CHIP_ID)) {
663 /* enable 12 mA drive strenth for 43224 and set chipControl register bit 15 */
664 if (CHIPREV(sih->chiprev) == 0) {
665 SI_MSG(("Applying 43224A0 WARs\n"));
666 si_corereg(sih, SI_CC_IDX,
667 OFFSETOF(chipcregs_t, chipcontrol),
668 CCTRL43224_GPIO_TOGGLE,
669 CCTRL43224_GPIO_TOGGLE);
670 si_pmu_chipcontrol(sih, 0, CCTRL_43224A0_12MA_LED_DRIVE,
671 CCTRL_43224A0_12MA_LED_DRIVE);
673 if (CHIPREV(sih->chiprev) >= 1) {
674 SI_MSG(("Applying 43224B0+ WARs\n"));
675 si_pmu_chipcontrol(sih, 0, CCTRL_43224B0_12MA_LED_DRIVE,
676 CCTRL_43224B0_12MA_LED_DRIVE);
680 if (CHIPID(sih->chip) == BCM4313_CHIP_ID) {
681 /* enable 12 mA drive strenth for 4313 and set chipControl register bit 1 */
682 SI_MSG(("Applying 4313 WARs\n"));
683 si_pmu_chipcontrol(sih, 0, CCTRL_4313_12MA_LED_DRIVE,
684 CCTRL_4313_12MA_LED_DRIVE);
687 if (CHIPID(sih->chip) == BCM4331_CHIP_ID) {
688 /* Enable Ext PA lines depending on chip package option */
689 si_chipcontrl_epa4331(sih, TRUE);
694 if (BUSTYPE(sih->bustype) == PCI_BUS) {
696 pcicore_deinit(sii->pch);
704 /* may be called with core in reset */
705 void BCMATTACHFN(si_detach) (si_t *sih)
710 struct si_pub *si_local = NULL;
711 bcopy(&sih, &si_local, sizeof(si_t **));
718 if (BUSTYPE(sih->bustype) == SI_BUS)
719 for (idx = 0; idx < SI_MAXCORES; idx++)
720 if (sii->regs[idx]) {
721 REG_UNMAP(sii->regs[idx]);
722 sii->regs[idx] = NULL;
726 nvram_exit((void *)si_local); /* free up nvram buffers */
728 if (BUSTYPE(sih->bustype) == PCI_BUS) {
730 pcicore_deinit(sii->pch);
734 #if !defined(BCMBUSTYPE) || (BCMBUSTYPE == SI_BUS)
736 #endif /* !BCMBUSTYPE || (BCMBUSTYPE == SI_BUS) */
737 MFREE(sii->osh, sii, sizeof(si_info_t));
740 void *si_osh(si_t *sih)
748 void si_setosh(si_t *sih, osl_t *osh)
753 if (sii->osh != NULL) {
754 SI_ERROR(("osh is already set....\n"));
760 /* register driver interrupt disabling and restoring callback functions */
762 si_register_intr_callback(si_t *sih, void *intrsoff_fn, void *intrsrestore_fn,
763 void *intrsenabled_fn, void *intr_arg)
768 sii->intr_arg = intr_arg;
769 sii->intrsoff_fn = (si_intrsoff_t) intrsoff_fn;
770 sii->intrsrestore_fn = (si_intrsrestore_t) intrsrestore_fn;
771 sii->intrsenabled_fn = (si_intrsenabled_t) intrsenabled_fn;
772 /* save current core id. when this function called, the current core
773 * must be the core which provides driver functions(il, et, wl, etc.)
775 sii->dev_coreid = sii->coreid[sii->curidx];
778 void si_deregister_intr_callback(si_t *sih)
783 sii->intrsoff_fn = NULL;
786 uint si_intflag(si_t *sih)
788 si_info_t *sii = SI_INFO(sih);
790 if (CHIPTYPE(sih->socitype) == SOCI_AI)
791 return R_REG(sii->osh,
792 ((uint32 *) (uintptr) (sii->oob_router +
800 uint si_flag(si_t *sih)
802 if (CHIPTYPE(sih->socitype) == SOCI_AI)
810 void si_setint(si_t *sih, int siflag)
812 if (CHIPTYPE(sih->socitype) == SOCI_AI)
813 ai_setint(sih, siflag);
819 uint si_coreid(si_t *sih)
824 return sii->coreid[sii->curidx];
828 uint si_coreidx(si_t *sih)
836 /* return the core-type instantiation # of the current core */
837 uint si_coreunit(si_t *sih)
850 ASSERT(GOODREGS(sii->curmap));
851 coreid = si_coreid(sih);
853 /* count the cores of our type */
854 for (i = 0; i < idx; i++)
855 if (sii->coreid[i] == coreid)
861 uint si_corevendor(si_t *sih)
863 if (CHIPTYPE(sih->socitype) == SOCI_AI)
864 return ai_corevendor(sih);
871 bool si_backplane64(si_t *sih)
873 return (sih->cccaps & CC_CAP_BKPLN64) != 0;
877 uint si_corerev(si_t *sih)
879 if (CHIPTYPE(sih->socitype) == SOCI_AI)
880 return ai_corerev(sih);
888 /* return index of coreid or BADIDX if not found */
889 uint si_findcoreidx(si_t *sih, uint coreid, uint coreunit)
899 for (i = 0; i < sii->numcores; i++)
900 if (sii->coreid[i] == coreid) {
901 if (found == coreunit)
909 /* return list of found cores */
910 uint si_corelist(si_t *sih, uint coreid[])
916 bcopy((uchar *) sii->coreid, (uchar *) coreid,
917 (sii->numcores * sizeof(uint)));
918 return sii->numcores;
921 /* return current register mapping */
922 void *si_coreregs(si_t *sih)
927 ASSERT(GOODREGS(sii->curmap));
933 * This function changes logical "focus" to the indicated core;
934 * must be called with interrupts off.
935 * Moreover, callers should keep interrupts off during switching out of and back to d11 core
937 void *si_setcore(si_t *sih, uint coreid, uint coreunit)
941 idx = si_findcoreidx(sih, coreid, coreunit);
945 if (CHIPTYPE(sih->socitype) == SOCI_AI)
946 return ai_setcoreidx(sih, idx);
949 return sb_setcoreidx(sih, idx);
958 void *si_setcoreidx(si_t *sih, uint coreidx)
960 if (CHIPTYPE(sih->socitype) == SOCI_AI)
961 return ai_setcoreidx(sih, coreidx);
969 /* Turn off interrupt as required by sb_setcore, before switch core */
970 void *si_switch_core(si_t *sih, uint coreid, uint *origidx, uint *intr_val)
978 /* Overloading the origidx variable to remember the coreid,
979 * this works because the core ids cannot be confused with
983 if (coreid == CC_CORE_ID)
984 return (void *)CCREGS_FAST(sii);
985 else if (coreid == sih->buscoretype)
986 return (void *)PCIEREGS(sii);
988 INTR_OFF(sii, *intr_val);
989 *origidx = sii->curidx;
990 cc = si_setcore(sih, coreid, 0);
996 /* restore coreidx and restore interrupt */
997 void si_restore_core(si_t *sih, uint coreid, uint intr_val)
1003 && ((coreid == CC_CORE_ID) || (coreid == sih->buscoretype)))
1006 si_setcoreidx(sih, coreid);
1007 INTR_RESTORE(sii, intr_val);
1010 int si_numaddrspaces(si_t *sih)
1012 if (CHIPTYPE(sih->socitype) == SOCI_AI)
1013 return ai_numaddrspaces(sih);
1020 uint32 si_addrspace(si_t *sih, uint asidx)
1022 if (CHIPTYPE(sih->socitype) == SOCI_AI)
1023 return ai_addrspace(sih, asidx);
1030 uint32 si_addrspacesize(si_t *sih, uint asidx)
1032 if (CHIPTYPE(sih->socitype) == SOCI_AI)
1033 return ai_addrspacesize(sih, asidx);
1040 uint32 si_core_cflags(si_t *sih, uint32 mask, uint32 val)
1042 if (CHIPTYPE(sih->socitype) == SOCI_AI)
1043 return ai_core_cflags(sih, mask, val);
1050 void si_core_cflags_wo(si_t *sih, uint32 mask, uint32 val)
1052 if (CHIPTYPE(sih->socitype) == SOCI_AI)
1053 ai_core_cflags_wo(sih, mask, val);
1058 uint32 si_core_sflags(si_t *sih, uint32 mask, uint32 val)
1060 if (CHIPTYPE(sih->socitype) == SOCI_AI)
1061 return ai_core_sflags(sih, mask, val);
1068 bool si_iscoreup(si_t *sih)
1070 if (CHIPTYPE(sih->socitype) == SOCI_AI)
1071 return ai_iscoreup(sih);
1074 return sb_iscoreup(sih);
1082 void si_write_wrapperreg(si_t *sih, uint32 offset, uint32 val)
1084 /* only for 4319, no requirement for SOCI_SB */
1085 if (CHIPTYPE(sih->socitype) == SOCI_AI) {
1086 ai_write_wrap_reg(sih, offset, val);
1090 uint si_corereg(si_t *sih, uint coreidx, uint regoff, uint mask, uint val)
1093 if (CHIPTYPE(sih->socitype) == SOCI_AI)
1094 return ai_corereg(sih, coreidx, regoff, mask, val);
1097 return sb_corereg(sih, coreidx, regoff, mask, val);
1105 void si_core_disable(si_t *sih, uint32 bits)
1108 if (CHIPTYPE(sih->socitype) == SOCI_AI)
1109 ai_core_disable(sih, bits);
1112 sb_core_disable(sih, bits);
1116 void si_core_reset(si_t *sih, uint32 bits, uint32 resetbits)
1118 if (CHIPTYPE(sih->socitype) == SOCI_AI)
1119 ai_core_reset(sih, bits, resetbits);
1122 sb_core_reset(sih, bits, resetbits);
1126 /* Run bist on current core. Caller needs to take care of core-specific bist hazards */
1127 int si_corebist(si_t *sih)
1132 /* Read core control flags */
1133 cflags = si_core_cflags(sih, 0, 0);
1135 /* Set bist & fgc */
1136 si_core_cflags(sih, ~0, (SICF_BIST_EN | SICF_FGC));
1138 /* Wait for bist done */
1139 SPINWAIT(((si_core_sflags(sih, 0, 0) & SISF_BIST_DONE) == 0), 100000);
1141 if (si_core_sflags(sih, 0, 0) & SISF_BIST_ERROR)
1142 result = BCME_ERROR;
1144 /* Reset core control flags */
1145 si_core_cflags(sih, 0xffff, cflags);
1150 static uint32 BCMINITFN(factor6) (uint32 x)
1170 /* calculate the speed the SI would run at given a set of clockcontrol values */
1171 uint32 BCMINITFN(si_clock_rate) (uint32 pll_type, uint32 n, uint32 m)
1173 uint32 n1, n2, clock, m1, m2, m3, mc;
1175 n1 = n & CN_N1_MASK;
1176 n2 = (n & CN_N2_MASK) >> CN_N2_SHIFT;
1178 if (pll_type == PLL_TYPE6) {
1179 if (m & CC_T6_MMASK)
1183 } else if ((pll_type == PLL_TYPE1) ||
1184 (pll_type == PLL_TYPE3) ||
1185 (pll_type == PLL_TYPE4) || (pll_type == PLL_TYPE7)) {
1188 } else if (pll_type == PLL_TYPE2) {
1191 ASSERT((n1 >= 2) && (n1 <= 7));
1192 ASSERT((n2 >= 5) && (n2 <= 23));
1193 } else if (pll_type == PLL_TYPE5) {
1197 /* PLL types 3 and 7 use BASE2 (25Mhz) */
1198 if ((pll_type == PLL_TYPE3) || (pll_type == PLL_TYPE7)) {
1199 clock = CC_CLOCK_BASE2 * n1 * n2;
1201 clock = CC_CLOCK_BASE1 * n1 * n2;
1206 m1 = m & CC_M1_MASK;
1207 m2 = (m & CC_M2_MASK) >> CC_M2_SHIFT;
1208 m3 = (m & CC_M3_MASK) >> CC_M3_SHIFT;
1209 mc = (m & CC_MC_MASK) >> CC_MC_SHIFT;
1211 if ((pll_type == PLL_TYPE1) ||
1212 (pll_type == PLL_TYPE3) ||
1213 (pll_type == PLL_TYPE4) || (pll_type == PLL_TYPE7)) {
1215 if ((pll_type == PLL_TYPE1) || (pll_type == PLL_TYPE3))
1227 return clock / (m1 * m2);
1229 return clock / (m1 * m2 * m3);
1231 return clock / (m1 * m3);
1236 ASSERT(pll_type == PLL_TYPE2);
1241 ASSERT((m1 >= 2) && (m1 <= 7));
1242 ASSERT((m2 >= 3) && (m2 <= 10));
1243 ASSERT((m3 >= 2) && (m3 <= 7));
1245 if ((mc & CC_T2MC_M1BYP) == 0)
1247 if ((mc & CC_T2MC_M2BYP) == 0)
1249 if ((mc & CC_T2MC_M3BYP) == 0)
1256 uint32 BCMINITFN(si_clock) (si_t *sih)
1262 uint32 pll_type, rate;
1266 INTR_OFF(sii, intr_val);
1267 if (PMUCTL_ENAB(sih)) {
1268 rate = si_pmu_si_clock(sih, sii->osh);
1273 cc = (chipcregs_t *) si_setcore(sih, CC_CORE_ID, 0);
1276 n = R_REG(sii->osh, &cc->clockcontrol_n);
1277 pll_type = sih->cccaps & CC_CAP_PLL_MASK;
1278 if (pll_type == PLL_TYPE6)
1279 m = R_REG(sii->osh, &cc->clockcontrol_m3);
1280 else if (pll_type == PLL_TYPE3)
1281 m = R_REG(sii->osh, &cc->clockcontrol_m2);
1283 m = R_REG(sii->osh, &cc->clockcontrol_sb);
1285 /* calculate rate */
1286 rate = si_clock_rate(pll_type, n, m);
1288 if (pll_type == PLL_TYPE3)
1291 /* switch back to previous core */
1292 si_setcoreidx(sih, idx);
1294 INTR_RESTORE(sii, intr_val);
1299 uint32 BCMINITFN(si_alp_clock) (si_t *sih)
1301 if (PMUCTL_ENAB(sih))
1302 return si_pmu_alp_clock(sih, si_osh(sih));
1307 uint32 BCMINITFN(si_ilp_clock) (si_t *sih)
1309 if (PMUCTL_ENAB(sih))
1310 return si_pmu_ilp_clock(sih, si_osh(sih));
1315 /* set chip watchdog reset timer to fire in 'ticks' */
1318 si_watchdog(si_t *sih, uint ticks)
1320 if (PMUCTL_ENAB(sih)) {
1322 if ((sih->chip == BCM4319_CHIP_ID) && (sih->chiprev == 0) &&
1324 si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t,
1325 clk_ctl_st), ~0, 0x2);
1326 si_setcore(sih, USB20D_CORE_ID, 0);
1327 si_core_disable(sih, 1);
1328 si_setcore(sih, CC_CORE_ID, 0);
1333 si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, pmuwatchdog),
1337 si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, watchdog),
1342 void si_watchdog(si_t *sih, uint ticks)
1346 if (PMUCTL_ENAB(sih)) {
1348 if ((CHIPID(sih->chip) == BCM4319_CHIP_ID) &&
1349 (CHIPREV(sih->chiprev) == 0) && (ticks != 0)) {
1350 si_corereg(sih, SI_CC_IDX,
1351 OFFSETOF(chipcregs_t, clk_ctl_st), ~0, 0x2);
1352 si_setcore(sih, USB20D_CORE_ID, 0);
1353 si_core_disable(sih, 1);
1354 si_setcore(sih, CC_CORE_ID, 0);
1357 nb = (sih->ccrev < 26) ? 16 : ((sih->ccrev >= 37) ? 32 : 24);
1358 /* The mips compiler uses the sllv instruction,
1359 * so we specially handle the 32-bit case.
1364 maxt = ((1 << nb) - 1);
1368 else if (ticks > maxt)
1371 si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, pmuwatchdog),
1374 /* make sure we come up in fast clock mode; or if clearing, clear clock */
1375 si_clkctl_cc(sih, ticks ? CLK_FAST : CLK_DYNAMIC);
1376 maxt = (1 << 28) - 1;
1380 si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, watchdog), ~0,
1386 /* trigger watchdog reset after ms milliseconds */
1387 void si_watchdog_ms(si_t *sih, uint32 ms)
1389 si_watchdog(sih, wd_msticks * ms);
1392 uint16 BCMATTACHFN(si_d11_devid) (si_t *sih)
1394 si_info_t *sii = SI_INFO(sih);
1397 /* normal case: nvram variable with devpath->devid->wl0id */
1398 device = (uint16) si_getdevpathintvar(sih, "devid");
1402 /* Get devid from OTP/SPROM depending on where the SROM is read */
1403 device = (uint16) getintvar(sii->vars, "devid");
1407 /* no longer support wl0id, but keep the code here for backward compatibility. */
1408 device = (uint16) getintvar(sii->vars, "wl0id");
1419 /* return the slow clock source - LPO, XTAL, or PCI */
1420 static uint si_slowclk_src(si_info_t *sii)
1424 ASSERT(SI_FAST(sii) || si_coreid(&sii->pub) == CC_CORE_ID);
1426 if (sii->pub.ccrev < 6) {
1427 if ((BUSTYPE(sii->pub.bustype) == PCI_BUS) &&
1428 (OSL_PCI_READ_CONFIG(sii->osh, PCI_GPIO_OUT, sizeof(uint32))
1429 & PCI_CFG_GPIO_SCS))
1433 } else if (sii->pub.ccrev < 10) {
1434 cc = (chipcregs_t *) si_setcoreidx(&sii->pub, sii->curidx);
1435 return R_REG(sii->osh, &cc->slow_clk_ctl) & SCC_SS_MASK;
1436 } else /* Insta-clock */
1440 /* return the ILP (slowclock) min or max frequency */
1441 static uint si_slowclk_freq(si_info_t *sii, bool max_freq, chipcregs_t *cc)
1446 ASSERT(SI_FAST(sii) || si_coreid(&sii->pub) == CC_CORE_ID);
1448 /* shouldn't be here unless we've established the chip has dynamic clk control */
1449 ASSERT(R_REG(sii->osh, &cc->capabilities) & CC_CAP_PWR_CTL);
1451 slowclk = si_slowclk_src(sii);
1452 if (sii->pub.ccrev < 6) {
1453 if (slowclk == SCC_SS_PCI)
1454 return max_freq ? (PCIMAXFREQ / 64)
1455 : (PCIMINFREQ / 64);
1457 return max_freq ? (XTALMAXFREQ / 32)
1458 : (XTALMINFREQ / 32);
1459 } else if (sii->pub.ccrev < 10) {
1461 (((R_REG(sii->osh, &cc->slow_clk_ctl) & SCC_CD_MASK) >>
1463 if (slowclk == SCC_SS_LPO)
1464 return max_freq ? LPOMAXFREQ : LPOMINFREQ;
1465 else if (slowclk == SCC_SS_XTAL)
1466 return max_freq ? (XTALMAXFREQ / div)
1467 : (XTALMINFREQ / div);
1468 else if (slowclk == SCC_SS_PCI)
1469 return max_freq ? (PCIMAXFREQ / div)
1470 : (PCIMINFREQ / div);
1474 /* Chipc rev 10 is InstaClock */
1475 div = R_REG(sii->osh, &cc->system_clk_ctl) >> SYCC_CD_SHIFT;
1476 div = 4 * (div + 1);
1477 return max_freq ? XTALMAXFREQ : (XTALMINFREQ / div);
1482 static void BCMINITFN(si_clkctl_setdelay) (si_info_t *sii, void *chipcregs)
1484 chipcregs_t *cc = (chipcregs_t *) chipcregs;
1485 uint slowmaxfreq, pll_delay, slowclk;
1486 uint pll_on_delay, fref_sel_delay;
1488 pll_delay = PLL_DELAY;
1490 /* If the slow clock is not sourced by the xtal then add the xtal_on_delay
1491 * since the xtal will also be powered down by dynamic clk control logic.
1494 slowclk = si_slowclk_src(sii);
1495 if (slowclk != SCC_SS_XTAL)
1496 pll_delay += XTAL_ON_DELAY;
1498 /* Starting with 4318 it is ILP that is used for the delays */
1500 si_slowclk_freq(sii, (sii->pub.ccrev >= 10) ? FALSE : TRUE, cc);
1502 pll_on_delay = ((slowmaxfreq * pll_delay) + 999999) / 1000000;
1503 fref_sel_delay = ((slowmaxfreq * FREF_DELAY) + 999999) / 1000000;
1505 W_REG(sii->osh, &cc->pll_on_delay, pll_on_delay);
1506 W_REG(sii->osh, &cc->fref_sel_delay, fref_sel_delay);
1509 /* initialize power control delay registers */
1510 void BCMINITFN(si_clkctl_init) (si_t *sih)
1517 if (!CCCTL_ENAB(sih))
1521 fast = SI_FAST(sii);
1523 origidx = sii->curidx;
1524 cc = (chipcregs_t *) si_setcore(sih, CC_CORE_ID, 0);
1528 cc = (chipcregs_t *) CCREGS_FAST(sii);
1534 /* set all Instaclk chip ILP to 1 MHz */
1535 if (sih->ccrev >= 10)
1536 SET_REG(sii->osh, &cc->system_clk_ctl, SYCC_CD_MASK,
1537 (ILP_DIV_1MHZ << SYCC_CD_SHIFT));
1539 si_clkctl_setdelay(sii, (void *)(uintptr) cc);
1542 si_setcoreidx(sih, origidx);
1545 /* return the value suitable for writing to the dot11 core FAST_PWRUP_DELAY register */
1546 uint16 BCMINITFN(si_clkctl_fast_pwrup_delay) (si_t *sih)
1557 if (PMUCTL_ENAB(sih)) {
1558 INTR_OFF(sii, intr_val);
1559 fpdelay = si_pmu_fast_pwrup_delay(sih, sii->osh);
1560 INTR_RESTORE(sii, intr_val);
1564 if (!CCCTL_ENAB(sih))
1567 fast = SI_FAST(sii);
1570 origidx = sii->curidx;
1571 INTR_OFF(sii, intr_val);
1572 cc = (chipcregs_t *) si_setcore(sih, CC_CORE_ID, 0);
1576 cc = (chipcregs_t *) CCREGS_FAST(sii);
1582 slowminfreq = si_slowclk_freq(sii, FALSE, cc);
1583 fpdelay = (((R_REG(sii->osh, &cc->pll_on_delay) + 2) * 1000000) +
1584 (slowminfreq - 1)) / slowminfreq;
1588 si_setcoreidx(sih, origidx);
1589 INTR_RESTORE(sii, intr_val);
1594 /* turn primary xtal and/or pll off/on */
1595 int si_clkctl_xtal(si_t *sih, uint what, bool on)
1598 uint32 in, out, outen;
1602 switch (BUSTYPE(sih->bustype)) {
1607 #endif /* BCMSDIO */
1610 /* pcie core doesn't have any mapping to control the xtal pu */
1614 in = OSL_PCI_READ_CONFIG(sii->osh, PCI_GPIO_IN, sizeof(uint32));
1616 OSL_PCI_READ_CONFIG(sii->osh, PCI_GPIO_OUT, sizeof(uint32));
1618 OSL_PCI_READ_CONFIG(sii->osh, PCI_GPIO_OUTEN,
1622 * Avoid glitching the clock if GPRS is already using it.
1623 * We can't actually read the state of the PLLPD so we infer it
1624 * by the value of XTAL_PU which *is* readable via gpioin.
1626 if (on && (in & PCI_CFG_GPIO_XTAL))
1630 outen |= PCI_CFG_GPIO_XTAL;
1632 outen |= PCI_CFG_GPIO_PLL;
1635 /* turn primary xtal on */
1637 out |= PCI_CFG_GPIO_XTAL;
1639 out |= PCI_CFG_GPIO_PLL;
1640 OSL_PCI_WRITE_CONFIG(sii->osh, PCI_GPIO_OUT,
1641 sizeof(uint32), out);
1642 OSL_PCI_WRITE_CONFIG(sii->osh, PCI_GPIO_OUTEN,
1643 sizeof(uint32), outen);
1644 OSL_DELAY(XTAL_ON_DELAY);
1649 out &= ~PCI_CFG_GPIO_PLL;
1650 OSL_PCI_WRITE_CONFIG(sii->osh, PCI_GPIO_OUT,
1651 sizeof(uint32), out);
1656 out &= ~PCI_CFG_GPIO_XTAL;
1658 out |= PCI_CFG_GPIO_PLL;
1659 OSL_PCI_WRITE_CONFIG(sii->osh, PCI_GPIO_OUT,
1660 sizeof(uint32), out);
1661 OSL_PCI_WRITE_CONFIG(sii->osh, PCI_GPIO_OUTEN,
1662 sizeof(uint32), outen);
1673 * clock control policy function throught chipcommon
1675 * set dynamic clk control mode (forceslow, forcefast, dynamic)
1676 * returns true if we are forcing fast clock
1677 * this is a wrapper over the next internal function
1678 * to allow flexible policy settings for outside caller
1680 bool si_clkctl_cc(si_t *sih, uint mode)
1686 /* chipcommon cores prior to rev6 don't support dynamic clock control */
1690 if (PCI_FORCEHT(sii))
1691 return mode == CLK_FAST;
1693 return _si_clkctl_cc(sii, mode);
1696 /* clk control mechanism through chipcommon, no policy checking */
1697 static bool _si_clkctl_cc(si_info_t *sii, uint mode)
1703 bool fast = SI_FAST(sii);
1705 /* chipcommon cores prior to rev6 don't support dynamic clock control */
1706 if (sii->pub.ccrev < 6)
1709 /* Chips with ccrev 10 are EOL and they don't have SYCC_HR which we use below */
1710 ASSERT(sii->pub.ccrev != 10);
1713 INTR_OFF(sii, intr_val);
1714 origidx = sii->curidx;
1716 if ((BUSTYPE(sii->pub.bustype) == SI_BUS) &&
1717 si_setcore(&sii->pub, MIPS33_CORE_ID, 0) &&
1718 (si_corerev(&sii->pub) <= 7) && (sii->pub.ccrev >= 10))
1721 cc = (chipcregs_t *) si_setcore(&sii->pub, CC_CORE_ID, 0);
1723 cc = (chipcregs_t *) CCREGS_FAST(sii);
1729 if (!CCCTL_ENAB(&sii->pub) && (sii->pub.ccrev < 20))
1733 case CLK_FAST: /* FORCEHT, fast (pll) clock */
1734 if (sii->pub.ccrev < 10) {
1735 /* don't forget to force xtal back on before we clear SCC_DYN_XTAL.. */
1736 si_clkctl_xtal(&sii->pub, XTAL, ON);
1737 SET_REG(sii->osh, &cc->slow_clk_ctl,
1738 (SCC_XC | SCC_FS | SCC_IP), SCC_IP);
1739 } else if (sii->pub.ccrev < 20) {
1740 OR_REG(sii->osh, &cc->system_clk_ctl, SYCC_HR);
1742 OR_REG(sii->osh, &cc->clk_ctl_st, CCS_FORCEHT);
1745 /* wait for the PLL */
1746 if (PMUCTL_ENAB(&sii->pub)) {
1747 uint32 htavail = CCS_HTAVAIL;
1748 SPINWAIT(((R_REG(sii->osh, &cc->clk_ctl_st) & htavail)
1749 == 0), PMU_MAX_TRANSITION_DLY);
1750 ASSERT(R_REG(sii->osh, &cc->clk_ctl_st) & htavail);
1752 OSL_DELAY(PLL_DELAY);
1756 case CLK_DYNAMIC: /* enable dynamic clock control */
1757 if (sii->pub.ccrev < 10) {
1758 scc = R_REG(sii->osh, &cc->slow_clk_ctl);
1759 scc &= ~(SCC_FS | SCC_IP | SCC_XC);
1760 if ((scc & SCC_SS_MASK) != SCC_SS_XTAL)
1762 W_REG(sii->osh, &cc->slow_clk_ctl, scc);
1764 /* for dynamic control, we have to release our xtal_pu "force on" */
1766 si_clkctl_xtal(&sii->pub, XTAL, OFF);
1767 } else if (sii->pub.ccrev < 20) {
1769 AND_REG(sii->osh, &cc->system_clk_ctl, ~SYCC_HR);
1771 AND_REG(sii->osh, &cc->clk_ctl_st, ~CCS_FORCEHT);
1781 si_setcoreidx(&sii->pub, origidx);
1782 INTR_RESTORE(sii, intr_val);
1784 return mode == CLK_FAST;
1787 /* Build device path. Support SI, PCI, and JTAG for now. */
1788 int BCMATTACHFN(si_devpath) (si_t *sih, char *path, int size)
1792 ASSERT(path != NULL);
1793 ASSERT(size >= SI_DEVPATH_BUFSZ);
1795 if (!path || size <= 0)
1798 switch (BUSTYPE(sih->bustype)) {
1801 slen = snprintf(path, (size_t) size, "sb/%u/", si_coreidx(sih));
1804 ASSERT((SI_INFO(sih))->osh != NULL);
1805 slen = snprintf(path, (size_t) size, "pci/%u/%u/",
1806 OSL_PCI_BUS((SI_INFO(sih))->osh),
1807 OSL_PCI_SLOT((SI_INFO(sih))->osh));
1812 SI_ERROR(("si_devpath: device 0 assumed\n"));
1813 slen = snprintf(path, (size_t) size, "sd/%u/", si_coreidx(sih));
1822 if (slen < 0 || slen >= size) {
1830 /* Get a variable, but only if it has a devpath prefix */
1831 char *BCMATTACHFN(si_getdevpathvar) (si_t *sih, const char *name)
1833 char varname[SI_DEVPATH_BUFSZ + 32];
1835 si_devpathvar(sih, varname, sizeof(varname), name);
1837 return getvar(NULL, varname);
1840 /* Get a variable, but only if it has a devpath prefix */
1841 int BCMATTACHFN(si_getdevpathintvar) (si_t *sih, const char *name)
1843 #if defined(BCMBUSTYPE) && (BCMBUSTYPE == SI_BUS)
1844 return getintvar(NULL, name);
1846 char varname[SI_DEVPATH_BUFSZ + 32];
1848 si_devpathvar(sih, varname, sizeof(varname), name);
1850 return getintvar(NULL, varname);
1854 char *si_getnvramflvar(si_t *sih, const char *name)
1856 return getvar(NULL, name);
1859 /* Concatenate the dev path with a varname into the given 'var' buffer
1860 * and return the 'var' pointer.
1861 * Nothing is done to the arguments if len == 0 or var is NULL, var is still returned.
1862 * On overflow, the first char will be set to '\0'.
1864 static char *BCMATTACHFN(si_devpathvar) (si_t *sih, char *var, int len,
1868 if (!var || len <= 0)
1871 if (si_devpath(sih, var, len) == 0) {
1872 path_len = strlen(var);
1874 if (strlen(name) + 1 > (uint) (len - path_len))
1877 strncpy(var + path_len, name, len - path_len - 1);
1883 uint32 si_pciereg(si_t *sih, uint32 offset, uint32 mask, uint32 val, uint type)
1890 SI_ERROR(("%s: Not a PCIE device\n", __func__));
1894 return pcicore_pciereg(sii->pch, offset, mask, val, type);
1898 si_pcieserdesreg(si_t *sih, uint32 mdioslave, uint32 offset, uint32 mask,
1906 SI_ERROR(("%s: Not a PCIE device\n", __func__));
1910 return pcicore_pcieserdesreg(sii->pch, mdioslave, offset, mask, val);
1914 /* return TRUE if PCIE capability exists in the pci config space */
1915 static __used bool si_ispcie(si_info_t *sii)
1919 if (BUSTYPE(sii->pub.bustype) != PCI_BUS)
1923 pcicore_find_pci_capability(sii->osh, PCI_CAP_PCIECAP_ID, NULL,
1931 /* Wake-on-wireless-LAN (WOWL) support functions */
1932 /* Enable PME generation and disable clkreq */
1933 void si_pci_pmeen(si_t *sih)
1939 pcicore_pmeen(sii->pch);
1942 /* Return TRUE if PME status is set */
1943 bool si_pci_pmestat(si_t *sih)
1949 return pcicore_pmestat(sii->pch);
1952 /* Disable PME generation, clear the PME status bit if set */
1953 void si_pci_pmeclr(si_t *sih)
1959 pcicore_pmeclr(sii->pch);
1963 /* initialize the sdio core */
1964 void si_sdio_init(si_t *sih)
1966 si_info_t *sii = SI_INFO(sih);
1968 if (((sih->buscoretype == PCMCIA_CORE_ID) && (sih->buscorerev >= 8)) ||
1969 (sih->buscoretype == SDIOD_CORE_ID)) {
1971 sdpcmd_regs_t *sdpregs;
1973 /* get the current core index */
1975 ASSERT(idx == si_findcoreidx(sih, D11_CORE_ID, 0));
1977 /* switch to sdio core */
1978 sdpregs = (sdpcmd_regs_t *) si_setcore(sih, PCMCIA_CORE_ID, 0);
1981 (sdpcmd_regs_t *) si_setcore(sih, SDIOD_CORE_ID, 0);
1984 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));
1986 /* enable backplane error and core interrupts */
1987 W_REG(sii->osh, &sdpregs->hostintmask, I_SBINT);
1988 W_REG(sii->osh, &sdpregs->sbintmask,
1989 (I_SB_SERR | I_SB_RESPERR | (1 << idx)));
1991 /* switch back to previous core */
1992 si_setcoreidx(sih, idx);
1995 /* enable interrupts */
1996 bcmsdh_intr_enable(sii->sdh);
1999 #endif /* BCMSDIO */
2001 bool BCMATTACHFN(si_pci_war16165) (si_t *sih)
2007 return PCI(sii) && (sih->buscorerev <= 10);
2010 /* Disable pcie_war_ovr for some platforms (sigh!)
2011 * This is for boards that have BFL2_PCIEWAR_OVR set
2012 * but are in systems that still want the benefits of ASPM
2013 * Note that this should be done AFTER si_doattach
2015 void si_pcie_war_ovr_update(si_t *sih, u8 aspm)
2024 pcie_war_ovr_aspm_update(sii->pch, aspm);
2027 /* back door for other module to override chippkg */
2028 void si_chippkg_set(si_t *sih, uint val)
2034 sii->pub.chippkg = val;
2037 void BCMINITFN(si_pci_up) (si_t *sih)
2043 /* if not pci bus, we're done */
2044 if (BUSTYPE(sih->bustype) != PCI_BUS)
2047 if (PCI_FORCEHT(sii))
2048 _si_clkctl_cc(sii, CLK_FAST);
2051 pcicore_up(sii->pch, SI_PCIUP);
2055 /* Unconfigure and/or apply various WARs when system is going to sleep mode */
2056 void BCMUNINITFN(si_pci_sleep) (si_t *sih)
2062 pcicore_sleep(sii->pch);
2065 /* Unconfigure and/or apply various WARs when going down */
2066 void BCMINITFN(si_pci_down) (si_t *sih)
2072 /* if not pci bus, we're done */
2073 if (BUSTYPE(sih->bustype) != PCI_BUS)
2076 /* release FORCEHT since chip is going to "down" state */
2077 if (PCI_FORCEHT(sii))
2078 _si_clkctl_cc(sii, CLK_DYNAMIC);
2080 pcicore_down(sii->pch, SI_PCIDOWN);
2084 * Configure the pci core for pci client (NIC) action
2085 * coremask is the bitvec of cores by index to be enabled.
2087 void BCMATTACHFN(si_pci_setup) (si_t *sih, uint coremask)
2090 sbpciregs_t *pciregs = NULL;
2091 uint32 siflag = 0, w;
2096 if (BUSTYPE(sii->pub.bustype) != PCI_BUS)
2099 ASSERT(PCI(sii) || PCIE(sii));
2100 ASSERT(sii->pub.buscoreidx != BADIDX);
2103 /* get current core index */
2106 /* we interrupt on this backplane flag number */
2107 siflag = si_flag(sih);
2109 /* switch over to pci core */
2111 (sbpciregs_t *) si_setcoreidx(sih, sii->pub.buscoreidx);
2115 * Enable sb->pci interrupts. Assume
2116 * PCI rev 2.3 support was added in pci core rev 6 and things changed..
2118 if (PCIE(sii) || (PCI(sii) && ((sii->pub.buscorerev) >= 6))) {
2119 /* pci config write to set this core bit in PCIIntMask */
2120 w = OSL_PCI_READ_CONFIG(sii->osh, PCI_INT_MASK, sizeof(uint32));
2121 w |= (coremask << PCI_SBIM_SHIFT);
2122 OSL_PCI_WRITE_CONFIG(sii->osh, PCI_INT_MASK, sizeof(uint32), w);
2124 /* set sbintvec bit for our flag number */
2125 si_setint(sih, siflag);
2129 OR_REG(sii->osh, &pciregs->sbtopci2,
2130 (SBTOPCI_PREF | SBTOPCI_BURST));
2131 if (sii->pub.buscorerev >= 11) {
2132 OR_REG(sii->osh, &pciregs->sbtopci2,
2133 SBTOPCI_RC_READMULTI);
2134 w = R_REG(sii->osh, &pciregs->clkrun);
2135 W_REG(sii->osh, &pciregs->clkrun,
2136 (w | PCI_CLKRUN_DSBL));
2137 w = R_REG(sii->osh, &pciregs->clkrun);
2140 /* switch back to previous core */
2141 si_setcoreidx(sih, idx);
2145 u8 si_pcieclkreq(si_t *sih, uint32 mask, uint32 val)
2153 return pcie_clkreq(sii->pch, mask, val);
2156 uint32 si_pcielcreg(si_t *sih, uint32 mask, uint32 val)
2165 return pcie_lcreg(sii->pch, mask, val);
2168 /* indirect way to read pcie config regs */
2169 uint si_pcie_readreg(void *sih, uint addrtype, uint offset)
2171 return pcie_readreg(((si_info_t *) sih)->osh,
2172 (sbpcieregs_t *) PCIEREGS(((si_info_t *) sih)),
2177 * Fixup SROMless PCI device's configuration.
2178 * The current core may be changed upon return.
2180 int si_pci_fixcfg(si_t *sih)
2182 uint origidx, pciidx;
2183 sbpciregs_t *pciregs = NULL;
2184 sbpcieregs_t *pcieregs = NULL;
2186 uint16 val16, *reg16 = NULL;
2188 si_info_t *sii = SI_INFO(sih);
2190 ASSERT(BUSTYPE(sii->pub.bustype) == PCI_BUS);
2192 /* Fixup PI in SROM shadow area to enable the correct PCI core access */
2193 /* save the current index */
2194 origidx = si_coreidx(&sii->pub);
2196 /* check 'pi' is correct and fix it if not */
2197 if (sii->pub.buscoretype == PCIE_CORE_ID) {
2199 (sbpcieregs_t *) si_setcore(&sii->pub, PCIE_CORE_ID, 0);
2201 ASSERT(pcieregs != NULL);
2202 reg16 = &pcieregs->sprom[SRSH_PI_OFFSET];
2203 } else if (sii->pub.buscoretype == PCI_CORE_ID) {
2204 pciregs = (sbpciregs_t *) si_setcore(&sii->pub, PCI_CORE_ID, 0);
2206 ASSERT(pciregs != NULL);
2207 reg16 = &pciregs->sprom[SRSH_PI_OFFSET];
2209 pciidx = si_coreidx(&sii->pub);
2210 val16 = R_REG(sii->osh, reg16);
2211 if (((val16 & SRSH_PI_MASK) >> SRSH_PI_SHIFT) != (uint16) pciidx) {
2213 (uint16) (pciidx << SRSH_PI_SHIFT) | (val16 &
2215 W_REG(sii->osh, reg16, val16);
2218 /* restore the original index */
2219 si_setcoreidx(&sii->pub, origidx);
2221 pcicore_hwup(sii->pch);
2225 /* change logical "focus" to the gpio core for optimized access */
2226 void *si_gpiosetcore(si_t *sih)
2228 return si_setcoreidx(sih, SI_CC_IDX);
2231 /* mask&set gpiocontrol bits */
2232 uint32 si_gpiocontrol(si_t *sih, uint32 mask, uint32 val, u8 priority)
2238 /* gpios could be shared on router platforms
2239 * ignore reservation if it's high priority (e.g., test apps)
2241 if ((priority != GPIO_HI_PRIORITY) &&
2242 (BUSTYPE(sih->bustype) == SI_BUS) && (val || mask)) {
2243 mask = priority ? (si_gpioreservation & mask) :
2244 ((si_gpioreservation | mask) & ~(si_gpioreservation));
2248 regoff = OFFSETOF(chipcregs_t, gpiocontrol);
2249 return si_corereg(sih, SI_CC_IDX, regoff, mask, val);
2252 /* mask&set gpio output enable bits */
2253 uint32 si_gpioouten(si_t *sih, uint32 mask, uint32 val, u8 priority)
2259 /* gpios could be shared on router platforms
2260 * ignore reservation if it's high priority (e.g., test apps)
2262 if ((priority != GPIO_HI_PRIORITY) &&
2263 (BUSTYPE(sih->bustype) == SI_BUS) && (val || mask)) {
2264 mask = priority ? (si_gpioreservation & mask) :
2265 ((si_gpioreservation | mask) & ~(si_gpioreservation));
2269 regoff = OFFSETOF(chipcregs_t, gpioouten);
2270 return si_corereg(sih, SI_CC_IDX, regoff, mask, val);
2273 /* mask&set gpio output bits */
2274 uint32 si_gpioout(si_t *sih, uint32 mask, uint32 val, u8 priority)
2280 /* gpios could be shared on router platforms
2281 * ignore reservation if it's high priority (e.g., test apps)
2283 if ((priority != GPIO_HI_PRIORITY) &&
2284 (BUSTYPE(sih->bustype) == SI_BUS) && (val || mask)) {
2285 mask = priority ? (si_gpioreservation & mask) :
2286 ((si_gpioreservation | mask) & ~(si_gpioreservation));
2290 regoff = OFFSETOF(chipcregs_t, gpioout);
2291 return si_corereg(sih, SI_CC_IDX, regoff, mask, val);
2294 /* reserve one gpio */
2295 uint32 si_gpioreserve(si_t *sih, uint32 gpio_bitmask, u8 priority)
2301 /* only cores on SI_BUS share GPIO's and only applcation users need to
2302 * reserve/release GPIO
2304 if ((BUSTYPE(sih->bustype) != SI_BUS) || (!priority)) {
2305 ASSERT((BUSTYPE(sih->bustype) == SI_BUS) && (priority));
2308 /* make sure only one bit is set */
2309 if ((!gpio_bitmask) || ((gpio_bitmask) & (gpio_bitmask - 1))) {
2310 ASSERT((gpio_bitmask)
2311 && !((gpio_bitmask) & (gpio_bitmask - 1)));
2315 /* already reserved */
2316 if (si_gpioreservation & gpio_bitmask)
2318 /* set reservation */
2319 si_gpioreservation |= gpio_bitmask;
2321 return si_gpioreservation;
2324 /* release one gpio */
2326 * releasing the gpio doesn't change the current value on the GPIO last write value
2327 * persists till some one overwrites it
2330 uint32 si_gpiorelease(si_t *sih, uint32 gpio_bitmask, u8 priority)
2336 /* only cores on SI_BUS share GPIO's and only applcation users need to
2337 * reserve/release GPIO
2339 if ((BUSTYPE(sih->bustype) != SI_BUS) || (!priority)) {
2340 ASSERT((BUSTYPE(sih->bustype) == SI_BUS) && (priority));
2343 /* make sure only one bit is set */
2344 if ((!gpio_bitmask) || ((gpio_bitmask) & (gpio_bitmask - 1))) {
2345 ASSERT((gpio_bitmask)
2346 && !((gpio_bitmask) & (gpio_bitmask - 1)));
2350 /* already released */
2351 if (!(si_gpioreservation & gpio_bitmask))
2354 /* clear reservation */
2355 si_gpioreservation &= ~gpio_bitmask;
2357 return si_gpioreservation;
2360 /* return the current gpioin register value */
2361 uint32 si_gpioin(si_t *sih)
2369 regoff = OFFSETOF(chipcregs_t, gpioin);
2370 return si_corereg(sih, SI_CC_IDX, regoff, 0, 0);
2373 /* mask&set gpio interrupt polarity bits */
2374 uint32 si_gpiointpolarity(si_t *sih, uint32 mask, uint32 val, u8 priority)
2382 /* gpios could be shared on router platforms */
2383 if ((BUSTYPE(sih->bustype) == SI_BUS) && (val || mask)) {
2384 mask = priority ? (si_gpioreservation & mask) :
2385 ((si_gpioreservation | mask) & ~(si_gpioreservation));
2389 regoff = OFFSETOF(chipcregs_t, gpiointpolarity);
2390 return si_corereg(sih, SI_CC_IDX, regoff, mask, val);
2393 /* mask&set gpio interrupt mask bits */
2394 uint32 si_gpiointmask(si_t *sih, uint32 mask, uint32 val, u8 priority)
2402 /* gpios could be shared on router platforms */
2403 if ((BUSTYPE(sih->bustype) == SI_BUS) && (val || mask)) {
2404 mask = priority ? (si_gpioreservation & mask) :
2405 ((si_gpioreservation | mask) & ~(si_gpioreservation));
2409 regoff = OFFSETOF(chipcregs_t, gpiointmask);
2410 return si_corereg(sih, SI_CC_IDX, regoff, mask, val);
2413 /* assign the gpio to an led */
2414 uint32 si_gpioled(si_t *sih, uint32 mask, uint32 val)
2419 if (sih->ccrev < 16)
2422 /* gpio led powersave reg */
2424 (sih, SI_CC_IDX, OFFSETOF(chipcregs_t, gpiotimeroutmask), mask,
2428 /* mask&set gpio timer val */
2429 uint32 si_gpiotimerval(si_t *sih, uint32 mask, uint32 gpiotimerval)
2435 if (sih->ccrev < 16)
2438 return si_corereg(sih, SI_CC_IDX,
2439 OFFSETOF(chipcregs_t, gpiotimerval), mask,
2443 uint32 si_gpiopull(si_t *sih, bool updown, uint32 mask, uint32 val)
2449 if (sih->ccrev < 20)
2453 (updown ? OFFSETOF(chipcregs_t, gpiopulldown) :
2454 OFFSETOF(chipcregs_t, gpiopullup));
2455 return si_corereg(sih, SI_CC_IDX, offs, mask, val);
2458 uint32 si_gpioevent(si_t *sih, uint regtype, uint32 mask, uint32 val)
2464 if (sih->ccrev < 11)
2467 if (regtype == GPIO_REGEVT)
2468 offs = OFFSETOF(chipcregs_t, gpioevent);
2469 else if (regtype == GPIO_REGEVT_INTMSK)
2470 offs = OFFSETOF(chipcregs_t, gpioeventintmask);
2471 else if (regtype == GPIO_REGEVT_INTPOL)
2472 offs = OFFSETOF(chipcregs_t, gpioeventintpolarity);
2476 return si_corereg(sih, SI_CC_IDX, offs, mask, val);
2479 void *BCMATTACHFN(si_gpio_handler_register) (si_t *sih, uint32 event,
2480 bool level, gpio_handler_t cb,
2489 if (sih->ccrev < 11)
2492 gi = MALLOC(sii->osh, sizeof(gpioh_item_t));
2496 bzero(gi, sizeof(gpioh_item_t));
2502 gi->next = sii->gpioh_head;
2503 sii->gpioh_head = gi;
2505 return (void *)(gi);
2508 void BCMATTACHFN(si_gpio_handler_unregister) (si_t *sih, void *gpioh)
2511 gpioh_item_t *p, *n;
2514 if (sih->ccrev < 11)
2517 ASSERT(sii->gpioh_head != NULL);
2518 if ((void *)sii->gpioh_head == gpioh) {
2519 sii->gpioh_head = sii->gpioh_head->next;
2520 MFREE(sii->osh, gpioh, sizeof(gpioh_item_t));
2523 p = sii->gpioh_head;
2526 if ((void *)n == gpioh) {
2528 MFREE(sii->osh, gpioh, sizeof(gpioh_item_t));
2536 ASSERT(0); /* Not found in list */
2539 void si_gpio_handler_process(si_t *sih)
2544 uint32 level = si_gpioin(sih);
2545 uint32 edge = si_gpioevent(sih, GPIO_REGEVT, 0, 0);
2548 for (h = sii->gpioh_head; h != NULL; h = h->next) {
2550 status = (h->level ? level : edge);
2552 if (status & h->event)
2553 h->handler(status, h->arg);
2557 si_gpioevent(sih, GPIO_REGEVT, edge, edge); /* clear edge-trigger status */
2560 uint32 si_gpio_int_enable(si_t *sih, bool enable)
2566 if (sih->ccrev < 11)
2569 offs = OFFSETOF(chipcregs_t, intmask);
2571 (sih, SI_CC_IDX, offs, CI_GPIO, (enable ? CI_GPIO : 0));
2574 /* Return the size of the specified SOCRAM bank */
2576 socram_banksize(si_info_t *sii, sbsocramregs_t *regs, u8 index,
2579 uint banksize, bankinfo;
2580 uint bankidx = index | (mem_type << SOCRAM_BANKIDX_MEMTYPE_SHIFT);
2582 ASSERT(mem_type <= SOCRAM_MEMTYPE_DEVRAM);
2584 W_REG(sii->osh, ®s->bankidx, bankidx);
2585 bankinfo = R_REG(sii->osh, ®s->bankinfo);
2587 SOCRAM_BANKINFO_SZBASE * ((bankinfo & SOCRAM_BANKINFO_SZMASK) + 1);
2591 void si_socdevram(si_t *sih, bool set, u8 *enable, u8 *protect)
2596 sbsocramregs_t *regs;
2602 /* Block ints and save current core */
2603 INTR_OFF(sii, intr_val);
2604 origidx = si_coreidx(sih);
2607 *enable = *protect = 0;
2609 /* Switch to SOCRAM core */
2610 regs = si_setcore(sih, SOCRAM_CORE_ID, 0);
2614 /* Get info for determining size */
2615 wasup = si_iscoreup(sih);
2617 si_core_reset(sih, 0, 0);
2619 corerev = si_corerev(sih);
2620 if (corerev >= 10) {
2624 uint32 bankidx, bankinfo;
2626 extcinfo = R_REG(sii->osh, ®s->extracoreinfo);
2627 nb = ((extcinfo & SOCRAM_DEVRAMBANK_MASK) >>
2628 SOCRAM_DEVRAMBANK_SHIFT);
2629 for (i = 0; i < nb; i++) {
2631 i | (SOCRAM_MEMTYPE_DEVRAM <<
2632 SOCRAM_BANKIDX_MEMTYPE_SHIFT);
2633 W_REG(sii->osh, ®s->bankidx, bankidx);
2634 bankinfo = R_REG(sii->osh, ®s->bankinfo);
2636 bankinfo &= ~SOCRAM_BANKINFO_DEVRAMSEL_MASK;
2637 bankinfo &= ~SOCRAM_BANKINFO_DEVRAMPRO_MASK;
2641 SOCRAM_BANKINFO_DEVRAMSEL_SHIFT);
2645 SOCRAM_BANKINFO_DEVRAMPRO_SHIFT);
2647 W_REG(sii->osh, ®s->bankinfo, bankinfo);
2648 } else if (i == 0) {
2649 if (bankinfo & SOCRAM_BANKINFO_DEVRAMSEL_MASK) {
2652 SOCRAM_BANKINFO_DEVRAMPRO_MASK)
2659 /* Return to previous state and core */
2661 si_core_disable(sih, 0);
2662 si_setcoreidx(sih, origidx);
2665 INTR_RESTORE(sii, intr_val);
2668 bool si_socdevram_pkg(si_t *sih)
2670 if (si_socdevram_size(sih) > 0)
2676 uint32 si_socdevram_size(si_t *sih)
2682 sbsocramregs_t *regs;
2688 /* Block ints and save current core */
2689 INTR_OFF(sii, intr_val);
2690 origidx = si_coreidx(sih);
2692 /* Switch to SOCRAM core */
2693 regs = si_setcore(sih, SOCRAM_CORE_ID, 0);
2697 /* Get info for determining size */
2698 wasup = si_iscoreup(sih);
2700 si_core_reset(sih, 0, 0);
2702 corerev = si_corerev(sih);
2703 if (corerev >= 10) {
2708 extcinfo = R_REG(sii->osh, ®s->extracoreinfo);
2709 nb = (((extcinfo & SOCRAM_DEVRAMBANK_MASK) >>
2710 SOCRAM_DEVRAMBANK_SHIFT));
2711 for (i = 0; i < nb; i++)
2713 socram_banksize(sii, regs, i,
2714 SOCRAM_MEMTYPE_DEVRAM);
2717 /* Return to previous state and core */
2719 si_core_disable(sih, 0);
2720 si_setcoreidx(sih, origidx);
2723 INTR_RESTORE(sii, intr_val);
2728 /* Return the RAM size of the SOCRAM core */
2729 uint32 si_socram_size(si_t *sih)
2735 sbsocramregs_t *regs;
2743 /* Block ints and save current core */
2744 INTR_OFF(sii, intr_val);
2745 origidx = si_coreidx(sih);
2747 /* Switch to SOCRAM core */
2748 regs = si_setcore(sih, SOCRAM_CORE_ID, 0);
2752 /* Get info for determining size */
2753 wasup = si_iscoreup(sih);
2755 si_core_reset(sih, 0, 0);
2756 corerev = si_corerev(sih);
2757 coreinfo = R_REG(sii->osh, ®s->coreinfo);
2759 /* Calculate size from coreinfo based on rev */
2761 memsize = 1 << (16 + (coreinfo & SRCI_MS0_MASK));
2762 else if (corerev < 3) {
2763 memsize = 1 << (SR_BSZ_BASE + (coreinfo & SRCI_SRBSZ_MASK));
2764 memsize *= (coreinfo & SRCI_SRNB_MASK) >> SRCI_SRNB_SHIFT;
2765 } else if ((corerev <= 7) || (corerev == 12)) {
2766 uint nb = (coreinfo & SRCI_SRNB_MASK) >> SRCI_SRNB_SHIFT;
2767 uint bsz = (coreinfo & SRCI_SRBSZ_MASK);
2768 uint lss = (coreinfo & SRCI_LSS_MASK) >> SRCI_LSS_SHIFT;
2771 memsize = nb * (1 << (bsz + SR_BSZ_BASE));
2773 memsize += (1 << ((lss - 1) + SR_BSZ_BASE));
2776 uint nb = (coreinfo & SRCI_SRNB_MASK) >> SRCI_SRNB_SHIFT;
2777 for (i = 0; i < nb; i++)
2779 socram_banksize(sii, regs, i, SOCRAM_MEMTYPE_RAM);
2782 /* Return to previous state and core */
2784 si_core_disable(sih, 0);
2785 si_setcoreidx(sih, origidx);
2788 INTR_RESTORE(sii, intr_val);
2793 void si_chipcontrl_epa4331(si_t *sih, bool on)
2801 origidx = si_coreidx(sih);
2803 cc = (chipcregs_t *) si_setcore(sih, CC_CORE_ID, 0);
2805 val = R_REG(sii->osh, &cc->chipcontrol);
2808 if (sih->chippkg == 9 || sih->chippkg == 0xb) {
2809 /* Ext PA Controls for 4331 12x9 Package */
2810 W_REG(sii->osh, &cc->chipcontrol, val |
2811 (CCTRL4331_EXTPA_EN |
2812 CCTRL4331_EXTPA_ON_GPIO2_5));
2814 /* Ext PA Controls for 4331 12x12 Package */
2815 W_REG(sii->osh, &cc->chipcontrol,
2816 val | (CCTRL4331_EXTPA_EN));
2819 val &= ~(CCTRL4331_EXTPA_EN | CCTRL4331_EXTPA_ON_GPIO2_5);
2820 W_REG(sii->osh, &cc->chipcontrol, val);
2823 si_setcoreidx(sih, origidx);
2826 /* Enable BT-COEX & Ex-PA for 4313 */
2827 void si_epa_4313war(si_t *sih)
2834 origidx = si_coreidx(sih);
2836 cc = (chipcregs_t *) si_setcore(sih, CC_CORE_ID, 0);
2839 W_REG(sii->osh, &cc->gpiocontrol,
2840 R_REG(sii->osh, &cc->gpiocontrol) | GPIO_CTRL_EPA_EN_MASK);
2842 si_setcoreidx(sih, origidx);
2845 /* check if the device is removed */
2846 bool si_deviceremoved(si_t *sih)
2853 switch (BUSTYPE(sih->bustype)) {
2855 ASSERT(sii->osh != NULL);
2856 w = OSL_PCI_READ_CONFIG(sii->osh, PCI_CFG_VID, sizeof(uint32));
2857 if ((w & 0xFFFF) != VENDOR_BROADCOM)
2864 bool si_is_sprom_available(si_t *sih)
2866 if (sih->ccrev >= 31) {
2872 if ((sih->cccaps & CC_CAP_SROM) == 0)
2876 origidx = sii->curidx;
2877 cc = si_setcoreidx(sih, SI_CC_IDX);
2878 sromctrl = R_REG(sii->osh, &cc->sromcontrol);
2879 si_setcoreidx(sih, origidx);
2880 return sromctrl & SRC_PRESENT;
2883 switch (CHIPID(sih->chip)) {
2884 case BCM4329_CHIP_ID:
2885 return (sih->chipst & CST4329_SPROM_SEL) != 0;
2886 case BCM4319_CHIP_ID:
2887 return (sih->chipst & CST4319_SPROM_SEL) != 0;
2888 case BCM4336_CHIP_ID:
2889 return (sih->chipst & CST4336_SPROM_PRESENT) != 0;
2890 case BCM4330_CHIP_ID:
2891 return (sih->chipst & CST4330_SPROM_PRESENT) != 0;
2892 case BCM4313_CHIP_ID:
2893 return (sih->chipst & CST4313_SPROM_PRESENT) != 0;
2894 case BCM4331_CHIP_ID:
2895 return (sih->chipst & CST4331_SPROM_PRESENT) != 0;
2901 bool si_is_otp_disabled(si_t *sih)
2903 switch (CHIPID(sih->chip)) {
2904 case BCM4329_CHIP_ID:
2905 return (sih->chipst & CST4329_SPROM_OTP_SEL_MASK) ==
2907 case BCM4319_CHIP_ID:
2908 return (sih->chipst & CST4319_SPROM_OTP_SEL_MASK) ==
2910 case BCM4336_CHIP_ID:
2911 return (sih->chipst & CST4336_OTP_PRESENT) == 0;
2912 case BCM4330_CHIP_ID:
2913 return (sih->chipst & CST4330_OTP_PRESENT) == 0;
2914 case BCM4313_CHIP_ID:
2915 return (sih->chipst & CST4313_OTP_PRESENT) == 0;
2916 /* These chips always have their OTP on */
2917 case BCM43224_CHIP_ID:
2918 case BCM43225_CHIP_ID:
2919 case BCM43421_CHIP_ID:
2920 case BCM43235_CHIP_ID:
2921 case BCM43236_CHIP_ID:
2922 case BCM43238_CHIP_ID:
2923 case BCM4331_CHIP_ID:
2929 bool si_is_otp_powered(si_t *sih)
2931 if (PMUCTL_ENAB(sih))
2932 return si_pmu_is_otp_powered(sih, si_osh(sih));
2936 void si_otp_power(si_t *sih, bool on)
2938 if (PMUCTL_ENAB(sih))
2939 si_pmu_otp_power(sih, si_osh(sih), on);
2945 si_is_sprom_enabled(si_t *sih)
2947 BCMATTACHFN(si_is_sprom_enabled) (si_t *sih)
2956 si_sprom_enable(si_t *sih, bool enable)
2958 BCMATTACHFN(si_sprom_enable) (si_t *sih, bool enable)
2961 if (PMUCTL_ENAB(sih))
2962 si_pmu_sprom_enable(sih, si_osh(sih), enable);
2965 /* Return BCME_NOTFOUND if the card doesn't have CIS format nvram */
2966 int si_cis_source(si_t *sih)
2968 /* Many chips have the same mapping of their chipstatus field */
2969 static const uint cis_sel[] = {
2970 CIS_DEFAULT, CIS_SROM, CIS_OTP, CIS_SROM };
2971 static const uint cis_43236_sel[] = {
2972 CIS_DEFAULT, CIS_SROM, CIS_OTP, CIS_OTP };
2974 /* PCI chips use SROM format instead of CIS */
2975 if (BUSTYPE(sih->bustype) == PCI_BUS)
2976 return BCME_NOTFOUND;
2978 switch (CHIPID(sih->chip)) {
2979 case BCM43235_CHIP_ID:
2980 case BCM43236_CHIP_ID:
2981 case BCM43238_CHIP_ID:{
2984 chipst & CST4322_SPROM_OTP_SEL_MASK) >>
2985 CST4322_SPROM_OTP_SEL_SHIFT;
2987 sizeof(cis_sel)) ? CIS_DEFAULT :
2988 cis_43236_sel[strap]);
2991 case BCM4329_CHIP_ID:
2992 return ((sih->chipst & CST4329_SPROM_OTP_SEL_MASK) >=
2993 sizeof(cis_sel)) ? CIS_DEFAULT : cis_sel[(sih->
2995 CST4329_SPROM_OTP_SEL_MASK)];
2996 case BCM4319_CHIP_ID:{
2999 chipst & CST4319_SPROM_OTP_SEL_MASK) >>
3000 CST4319_SPROM_OTP_SEL_SHIFT);
3001 return (cis_sel4319 >=
3002 sizeof(cis_sel)) ? CIS_DEFAULT :
3003 cis_sel[cis_sel4319];
3005 case BCM4336_CHIP_ID:{
3006 if (sih->chipst & CST4336_SPROM_PRESENT)
3008 if (sih->chipst & CST4336_OTP_PRESENT)
3012 case BCM4330_CHIP_ID:{
3013 if (sih->chipst & CST4330_SPROM_PRESENT)
3015 if (sih->chipst & CST4330_OTP_PRESENT)