2 * Misc utility routines for accessing chip-specific features
3 * of the SiliconBackplane-based Broadcom chips.
5 * Copyright (C) 1999-2011, Broadcom Corporation
7 * Unless you and Broadcom execute a separate written software license
8 * agreement governing use of this software, this software is licensed to you
9 * under the terms of the GNU General Public License version 2 (the "GPL"),
10 * available at http://www.broadcom.com/licenses/GPLv2.php, with the
11 * following added to such license:
13 * As a special exception, the copyright holders of this software give you
14 * permission to link this software with independent modules, and to copy and
15 * distribute the resulting executable under terms of your choice, provided that
16 * you also meet, for each linked independent module, the terms and conditions of
17 * the license of that module. An independent module is a module which is not
18 * derived from this software. The special exception does not apply to any
19 * modifications of the software.
21 * Notwithstanding the above, under no circumstances may you combine this
22 * software in any way with any other Broadcom software provided under a license
23 * other than the GPL, without Broadcom's express prior written consent.
25 * $Id: siutils.c,v 1.813.2.33 2011-01-13 19:11:51 $
43 #include <sbsdpcmdev.h>
50 #include "siutils_priv.h"
52 /* local prototypes */
53 static si_info_t *si_doattach(si_info_t *sii, uint devid, osl_t *osh, void *regs,
54 uint bustype, void *sdh, char **vars, uint *varsz);
55 static bool si_buscore_prep(si_info_t *sii, uint bustype, uint devid, void *sdh);
56 static bool si_buscore_setup(si_info_t *sii, chipcregs_t *cc, uint bustype, uint32 savewin,
57 uint *origidx, void *regs);
60 /* global variable to indicate reservation/release of gpio's */
61 static uint32 si_gpioreservation = 0;
63 /* global flag to prevent shared resources from being initialized multiple times in si_attach() */
66 * Allocate a si handle.
67 * devid - pci device id (used to determine chip#)
68 * osh - opaque OS handle
69 * regs - virtual address of initial core registers
70 * bustype - pci/pcmcia/sb/sdio/etc
71 * vars - pointer to a pointer area for "environment" variables
72 * varsz - pointer to int to return the size of the vars
75 si_attach(uint devid, osl_t *osh, void *regs,
76 uint bustype, void *sdh, char **vars, uint *varsz)
81 if ((sii = MALLOC(osh, sizeof (si_info_t))) == NULL) {
82 SI_ERROR(("si_attach: malloc failed! malloced %d bytes\n", MALLOCED(osh)));
86 if (si_doattach(sii, devid, osh, regs, bustype, sdh, vars, varsz) == NULL) {
87 MFREE(osh, sii, sizeof(si_info_t));
90 sii->vars = vars ? *vars : NULL;
91 sii->varsz = varsz ? *varsz : 0;
96 /* global kernel resource */
97 static si_info_t ksii;
99 static uint32 wd_msticks; /* watchdog timer ticks normalized to ms */
101 /* generic kernel variant of si_attach() */
103 si_kattach(osl_t *osh)
105 static bool ksii_attached = FALSE;
107 if (!ksii_attached) {
109 regs = REG_MAP(SI_ENUM_BASE, SI_CORE_SIZE);
111 if (si_doattach(&ksii, BCM4710_DEVICE_ID, osh, regs,
113 osh != SI_OSH ? &ksii.vars : NULL,
114 osh != SI_OSH ? &ksii.varsz : NULL) == NULL) {
115 SI_ERROR(("si_kattach: si_doattach failed\n"));
121 /* save ticks normalized to ms for si_watchdog_ms() */
122 if (PMUCTL_ENAB(&ksii.pub)) {
123 /* based on 32KHz ILP clock */
126 wd_msticks = ALP_CLOCK / 1000;
129 ksii_attached = TRUE;
130 SI_MSG(("si_kattach done. ccrev = %d, wd_msticks = %d\n",
131 ksii.pub.ccrev, wd_msticks));
139 si_buscore_prep(si_info_t *sii, uint bustype, uint devid, void *sdh)
141 /* need to set memseg flag for CF card first before any sb registers access */
142 if (BUSTYPE(bustype) == PCMCIA_BUS)
146 if (BUSTYPE(bustype) == SDIO_BUS) {
150 /* Try forcing SDIO core to do ALPAvail request only */
151 clkset = SBSDIO_FORCE_HW_CLKREQ_OFF | SBSDIO_ALP_AVAIL_REQ;
152 bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, clkset, &err);
156 /* If register supported, wait for ALPAvail and then force ALP */
157 clkval = bcmsdh_cfg_read(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, NULL);
158 if ((clkval & ~SBSDIO_AVBITS) == clkset) {
159 SPINWAIT(((clkval = bcmsdh_cfg_read(sdh, SDIO_FUNC_1,
160 SBSDIO_FUNC1_CHIPCLKCSR, NULL)), !SBSDIO_ALPAV(clkval)),
161 PMU_MAX_TRANSITION_DLY);
162 if (!SBSDIO_ALPAV(clkval)) {
163 SI_ERROR(("timeout on ALPAV wait, clkval 0x%02x\n",
167 clkset = SBSDIO_FORCE_HW_CLKREQ_OFF | SBSDIO_FORCE_ALP;
168 bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR,
174 /* Also, disable the extra SDIO pull-ups */
175 bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_SDIOPULLUP, 0, NULL);
179 /* Avoid backplane accesses before wake-wlan (i.e. htavail) for spi.
180 * F1 read accesses may return correct data but with data-not-available dstatus bit set.
182 if (BUSTYPE(bustype) == SPI_BUS) {
186 /* wake up wlan function :WAKE_UP goes as HT_AVAIL request in hardware */
187 regdata = bcmsdh_cfg_read_word(sdh, SDIO_FUNC_0, SPID_CONFIG, NULL);
188 SI_MSG(("F0 REG0 rd = 0x%x\n", regdata));
191 bcmsdh_cfg_write_word(sdh, SDIO_FUNC_0, SPID_CONFIG, regdata, &err);
201 si_buscore_setup(si_info_t *sii, chipcregs_t *cc, uint bustype, uint32 savewin,
202 uint *origidx, void *regs)
206 uint pciidx, pcieidx, pcirev, pcierev;
208 cc = si_setcoreidx(&sii->pub, SI_CC_IDX);
211 /* get chipcommon rev */
212 sii->pub.ccrev = (int)si_corerev(&sii->pub);
214 /* get chipcommon chipstatus */
215 if (sii->pub.ccrev >= 11)
216 sii->pub.chipst = R_REG(sii->osh, &cc->chipstatus);
218 /* get chipcommon capabilites */
219 sii->pub.cccaps = R_REG(sii->osh, &cc->capabilities);
220 /* get chipcommon extended capabilities */
222 if (sii->pub.ccrev >= 35)
223 sii->pub.cccaps_ext = R_REG(sii->osh, &cc->capabilities_ext);
225 /* get pmu rev and caps */
226 if (sii->pub.cccaps & CC_CAP_PMU) {
227 sii->pub.pmucaps = R_REG(sii->osh, &cc->pmucapabilities);
228 sii->pub.pmurev = sii->pub.pmucaps & PCAP_REV_MASK;
231 SI_MSG(("Chipc: rev %d, caps 0x%x, chipst 0x%x pmurev %d, pmucaps 0x%x\n",
232 sii->pub.ccrev, sii->pub.cccaps, sii->pub.chipst, sii->pub.pmurev,
235 /* figure out bus/orignal core idx */
236 sii->pub.buscoretype = NODEV_CORE_ID;
237 sii->pub.buscorerev = NOREV;
238 sii->pub.buscoreidx = BADIDX;
241 pcirev = pcierev = NOREV;
242 pciidx = pcieidx = BADIDX;
244 for (i = 0; i < sii->numcores; i++) {
247 si_setcoreidx(&sii->pub, i);
248 cid = si_coreid(&sii->pub);
249 crev = si_corerev(&sii->pub);
251 /* Display cores found */
252 SI_VMSG(("CORE[%d]: id 0x%x rev %d base 0x%x regs 0x%p\n",
253 i, cid, crev, sii->coresba[i], sii->regs[i]));
255 if (BUSTYPE(bustype) == PCI_BUS) {
256 if (cid == PCI_CORE_ID) {
260 } else if (cid == PCIE_CORE_ID) {
265 } else if ((BUSTYPE(bustype) == PCMCIA_BUS) &&
266 (cid == PCMCIA_CORE_ID)) {
267 sii->pub.buscorerev = crev;
268 sii->pub.buscoretype = cid;
269 sii->pub.buscoreidx = i;
271 else if (((BUSTYPE(bustype) == SDIO_BUS) ||
272 (BUSTYPE(bustype) == SPI_BUS)) &&
273 ((cid == PCMCIA_CORE_ID) ||
274 (cid == SDIOD_CORE_ID))) {
275 sii->pub.buscorerev = crev;
276 sii->pub.buscoretype = cid;
277 sii->pub.buscoreidx = i;
280 /* find the core idx before entering this func. */
281 if ((savewin && (savewin == sii->coresba[i])) ||
282 (regs == sii->regs[i]))
287 sii->pub.buscoretype = PCI_CORE_ID;
288 sii->pub.buscorerev = pcirev;
289 sii->pub.buscoreidx = pciidx;
291 sii->pub.buscoretype = PCIE_CORE_ID;
292 sii->pub.buscorerev = pcierev;
293 sii->pub.buscoreidx = pcieidx;
296 SI_VMSG(("Buscore id/type/rev %d/0x%x/%d\n", sii->pub.buscoreidx, sii->pub.buscoretype,
297 sii->pub.buscorerev));
299 if (BUSTYPE(sii->pub.bustype) == SI_BUS && (CHIPID(sii->pub.chip) == BCM4712_CHIP_ID) &&
300 (sii->pub.chippkg != BCM4712LARGE_PKG_ID) && (CHIPREV(sii->pub.chiprev) <= 3))
301 OR_REG(sii->osh, &cc->slow_clk_ctl, SCC_SS_XTAL);
304 /* Make sure any on-chip ARM is off (in case strapping is wrong), or downloaded code was
307 if ((BUSTYPE(bustype) == SDIO_BUS) || (BUSTYPE(bustype) == SPI_BUS)) {
308 if (si_setcore(&sii->pub, ARM7S_CORE_ID, 0) ||
309 si_setcore(&sii->pub, ARMCM3_CORE_ID, 0))
310 si_core_disable(&sii->pub, 0);
313 /* return to the original core */
314 si_setcoreidx(&sii->pub, *origidx);
322 si_doattach(si_info_t *sii, uint devid, osl_t *osh, void *regs,
323 uint bustype, void *sdh, char **vars, uint *varsz)
325 struct si_pub *sih = &sii->pub;
331 ASSERT(GOODREGS(regs));
333 bzero((uchar*)sii, sizeof(si_info_t));
337 sih->buscoreidx = BADIDX;
345 /* find Chipcommon address */
346 if (bustype == PCI_BUS) {
347 savewin = OSL_PCI_READ_CONFIG(sii->osh, PCI_BAR0_WIN, sizeof(uint32));
348 if (!GOODCOREADDR(savewin, SI_ENUM_BASE))
349 savewin = SI_ENUM_BASE;
350 OSL_PCI_WRITE_CONFIG(sii->osh, PCI_BAR0_WIN, 4, SI_ENUM_BASE);
351 cc = (chipcregs_t *)regs;
352 } else if ((bustype == SDIO_BUS) || (bustype == SPI_BUS)) {
353 cc = (chipcregs_t *)sii->curmap;
355 cc = (chipcregs_t *)REG_MAP(SI_ENUM_BASE, SI_CORE_SIZE);
358 sih->bustype = bustype;
359 if (bustype != BUSTYPE(bustype)) {
360 SI_ERROR(("si_doattach: bus type %d does not match configured bus type %d\n",
361 bustype, BUSTYPE(bustype)));
365 /* bus/core/clk setup for register access */
366 if (!si_buscore_prep(sii, bustype, devid, sdh)) {
367 SI_ERROR(("si_doattach: si_core_clk_prep failed %d\n", bustype));
371 /* ChipID recognition.
372 * We assume we can read chipid at offset 0 from the regs arg.
373 * If we add other chiptypes (or if we need to support old sdio hosts w/o chipcommon),
374 * some way of recognizing them needs to be added here.
376 w = R_REG(osh, &cc->chipid);
377 sih->socitype = (w & CID_TYPE_MASK) >> CID_TYPE_SHIFT;
378 /* Might as wll fill in chip id rev & pkg */
379 sih->chip = w & CID_ID_MASK;
380 sih->chiprev = (w & CID_REV_MASK) >> CID_REV_SHIFT;
381 sih->chippkg = (w & CID_PKG_MASK) >> CID_PKG_SHIFT;
382 if (CHIPID(sih->chip) == BCM4322_CHIP_ID && (((sih->chipst & CST4322_SPROM_OTP_SEL_MASK)
383 >> CST4322_SPROM_OTP_SEL_SHIFT) == (CST4322_OTP_PRESENT |
384 CST4322_SPROM_PRESENT))) {
385 SI_ERROR(("%s: Invalid setting: both SPROM and OTP strapped.\n", __FUNCTION__));
389 if ((CHIPID(sih->chip) == BCM4329_CHIP_ID) && (sih->chiprev == 0) &&
390 (sih->chippkg != BCM4329_289PIN_PKG_ID)) {
391 sih->chippkg = BCM4329_182PIN_PKG_ID;
394 sih->issim = IS_SIM(sih->chippkg);
397 if (CHIPTYPE(sii->pub.socitype) == SOCI_SB) {
398 SI_MSG(("Found chip type SB (0x%08x)\n", w));
399 sb_scan(&sii->pub, regs, devid);
400 } else if (CHIPTYPE(sii->pub.socitype) == SOCI_AI) {
401 SI_MSG(("Found chip type AI (0x%08x)\n", w));
402 /* pass chipc address instead of original core base */
403 ai_scan(&sii->pub, (void *)(uintptr)cc, devid);
404 } else if (CHIPTYPE(sii->pub.socitype) == SOCI_UBUS) {
405 SI_MSG(("Found chip type UBUS (0x%08x), chip id = 0x%4x\n", w, sih->chip));
406 /* pass chipc address instead of original core base */
407 ub_scan(&sii->pub, (void *)(uintptr)cc, devid);
409 SI_ERROR(("Found chip of unknown type (0x%08x)\n", w));
412 /* no cores found, bail out */
413 if (sii->numcores == 0) {
414 SI_ERROR(("si_doattach: could not find any cores\n"));
417 /* bus/core/clk setup */
419 if (!si_buscore_setup(sii, cc, bustype, savewin, &origidx, regs)) {
420 SI_ERROR(("si_doattach: si_buscore_setup failed\n"));
424 /* assume current core is CC */
425 if ((sii->pub.ccrev == 0x25) && ((CHIPID(sih->chip) == BCM43236_CHIP_ID ||
426 CHIPID(sih->chip) == BCM43235_CHIP_ID ||
427 CHIPID(sih->chip) == BCM43238_CHIP_ID) &&
428 (CHIPREV(sii->pub.chiprev) == 0))) {
430 if ((cc->chipstatus & CST43236_BP_CLK) != 0) {
432 clkdiv = R_REG(osh, &cc->clkdiv);
433 /* otp_clk_div is even number, 120/14 < 9mhz */
434 clkdiv = (clkdiv & ~CLKD_OTP) | (14 << CLKD_OTP_SHIFT);
435 W_REG(osh, &cc->clkdiv, clkdiv);
436 SI_ERROR(("%s: set clkdiv to %x\n", __FUNCTION__, clkdiv));
446 if (sii->pub.ccrev >= 20) {
447 cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0);
449 W_REG(osh, &cc->gpiopullup, 0);
450 W_REG(osh, &cc->gpiopulldown, 0);
451 si_setcoreidx(sih, origidx);
464 /* may be called with core in reset */
477 if (BUSTYPE(sih->bustype) == SI_BUS)
478 for (idx = 0; idx < SI_MAXCORES; idx++)
479 if (sii->regs[idx]) {
480 REG_UNMAP(sii->regs[idx]);
481 sii->regs[idx] = NULL;
486 #if !defined(BCMBUSTYPE) || (BCMBUSTYPE == SI_BUS)
488 #endif /* !BCMBUSTYPE || (BCMBUSTYPE == SI_BUS) */
489 MFREE(sii->osh, sii, sizeof(si_info_t));
502 si_setosh(si_t *sih, osl_t *osh)
507 if (sii->osh != NULL) {
508 SI_ERROR(("osh is already set....\n"));
514 /* register driver interrupt disabling and restoring callback functions */
516 si_register_intr_callback(si_t *sih, void *intrsoff_fn, void *intrsrestore_fn,
517 void *intrsenabled_fn, void *intr_arg)
522 sii->intr_arg = intr_arg;
523 sii->intrsoff_fn = (si_intrsoff_t)intrsoff_fn;
524 sii->intrsrestore_fn = (si_intrsrestore_t)intrsrestore_fn;
525 sii->intrsenabled_fn = (si_intrsenabled_t)intrsenabled_fn;
526 /* save current core id. when this function called, the current core
527 * must be the core which provides driver functions(il, et, wl, etc.)
529 sii->dev_coreid = sii->coreid[sii->curidx];
533 si_deregister_intr_callback(si_t *sih)
538 sii->intrsoff_fn = NULL;
542 si_intflag(si_t *sih)
544 si_info_t *sii = SI_INFO(sih);
546 if (CHIPTYPE(sih->socitype) == SOCI_SB)
547 return sb_intflag(sih);
548 else if (CHIPTYPE(sih->socitype) == SOCI_AI)
549 return R_REG(sii->osh, ((uint32 *)(uintptr)
550 (sii->oob_router + OOB_STATUSA)));
560 if (CHIPTYPE(sih->socitype) == SOCI_SB)
562 else if (CHIPTYPE(sih->socitype) == SOCI_AI)
564 else if (CHIPTYPE(sih->socitype) == SOCI_UBUS)
573 si_setint(si_t *sih, int siflag)
575 if (CHIPTYPE(sih->socitype) == SOCI_SB)
576 sb_setint(sih, siflag);
577 else if (CHIPTYPE(sih->socitype) == SOCI_AI)
578 ai_setint(sih, siflag);
579 else if (CHIPTYPE(sih->socitype) == SOCI_UBUS)
580 ub_setint(sih, siflag);
591 return sii->coreid[sii->curidx];
595 si_coreidx(si_t *sih)
603 /* return the core-type instantiation # of the current core */
605 si_coreunit(si_t *sih)
618 ASSERT(GOODREGS(sii->curmap));
619 coreid = si_coreid(sih);
621 /* count the cores of our type */
622 for (i = 0; i < idx; i++)
623 if (sii->coreid[i] == coreid)
630 si_corevendor(si_t *sih)
632 if (CHIPTYPE(sih->socitype) == SOCI_SB)
633 return sb_corevendor(sih);
634 else if (CHIPTYPE(sih->socitype) == SOCI_AI)
635 return ai_corevendor(sih);
636 else if (CHIPTYPE(sih->socitype) == SOCI_UBUS)
637 return ub_corevendor(sih);
645 si_backplane64(si_t *sih)
647 return ((sih->cccaps & CC_CAP_BKPLN64) != 0);
651 si_corerev(si_t *sih)
653 if (CHIPTYPE(sih->socitype) == SOCI_SB)
654 return sb_corerev(sih);
655 else if (CHIPTYPE(sih->socitype) == SOCI_AI)
656 return ai_corerev(sih);
657 else if (CHIPTYPE(sih->socitype) == SOCI_UBUS)
658 return ub_corerev(sih);
665 /* return index of coreid or BADIDX if not found */
667 si_findcoreidx(si_t *sih, uint coreid, uint coreunit)
677 for (i = 0; i < sii->numcores; i++)
678 if (sii->coreid[i] == coreid) {
679 if (found == coreunit)
687 /* return list of found cores */
689 si_corelist(si_t *sih, uint coreid[])
695 bcopy((uchar*)sii->coreid, (uchar*)coreid, (sii->numcores * sizeof(uint)));
696 return (sii->numcores);
699 /* return current register mapping */
701 si_coreregs(si_t *sih)
706 ASSERT(GOODREGS(sii->curmap));
708 return (sii->curmap);
712 * This function changes logical "focus" to the indicated core;
713 * must be called with interrupts off.
714 * Moreover, callers should keep interrupts off during switching out of and back to d11 core
717 si_setcore(si_t *sih, uint coreid, uint coreunit)
721 idx = si_findcoreidx(sih, coreid, coreunit);
725 if (CHIPTYPE(sih->socitype) == SOCI_SB)
726 return sb_setcoreidx(sih, idx);
727 else if (CHIPTYPE(sih->socitype) == SOCI_AI)
728 return ai_setcoreidx(sih, idx);
729 else if (CHIPTYPE(sih->socitype) == SOCI_UBUS)
730 return ub_setcoreidx(sih, idx);
738 si_setcoreidx(si_t *sih, uint coreidx)
740 if (CHIPTYPE(sih->socitype) == SOCI_SB)
741 return sb_setcoreidx(sih, coreidx);
742 else if (CHIPTYPE(sih->socitype) == SOCI_AI)
743 return ai_setcoreidx(sih, coreidx);
744 else if (CHIPTYPE(sih->socitype) == SOCI_UBUS)
745 return ub_setcoreidx(sih, coreidx);
752 /* Turn off interrupt as required by sb_setcore, before switch core */
754 si_switch_core(si_t *sih, uint coreid, uint *origidx, uint *intr_val)
762 /* Overloading the origidx variable to remember the coreid,
763 * this works because the core ids cannot be confused with
767 if (coreid == CC_CORE_ID)
768 return (void *)CCREGS_FAST(sii);
769 else if (coreid == sih->buscoretype)
770 return (void *)PCIEREGS(sii);
772 INTR_OFF(sii, *intr_val);
773 *origidx = sii->curidx;
774 cc = si_setcore(sih, coreid, 0);
780 /* restore coreidx and restore interrupt */
782 si_restore_core(si_t *sih, uint coreid, uint intr_val)
787 if (SI_FAST(sii) && ((coreid == CC_CORE_ID) || (coreid == sih->buscoretype)))
790 si_setcoreidx(sih, coreid);
791 INTR_RESTORE(sii, intr_val);
795 si_numaddrspaces(si_t *sih)
797 if (CHIPTYPE(sih->socitype) == SOCI_SB)
798 return sb_numaddrspaces(sih);
799 else if (CHIPTYPE(sih->socitype) == SOCI_AI)
800 return ai_numaddrspaces(sih);
801 else if (CHIPTYPE(sih->socitype) == SOCI_UBUS)
802 return ub_numaddrspaces(sih);
810 si_addrspace(si_t *sih, uint asidx)
812 if (CHIPTYPE(sih->socitype) == SOCI_SB)
813 return sb_addrspace(sih, asidx);
814 else if (CHIPTYPE(sih->socitype) == SOCI_AI)
815 return ai_addrspace(sih, asidx);
816 else if (CHIPTYPE(sih->socitype) == SOCI_UBUS)
817 return ub_addrspace(sih, asidx);
825 si_addrspacesize(si_t *sih, uint asidx)
827 if (CHIPTYPE(sih->socitype) == SOCI_SB)
828 return sb_addrspacesize(sih, asidx);
829 else if (CHIPTYPE(sih->socitype) == SOCI_AI)
830 return ai_addrspacesize(sih, asidx);
831 else if (CHIPTYPE(sih->socitype) == SOCI_UBUS)
832 return ub_addrspacesize(sih, asidx);
840 si_core_cflags(si_t *sih, uint32 mask, uint32 val)
842 if (CHIPTYPE(sih->socitype) == SOCI_SB)
843 return sb_core_cflags(sih, mask, val);
844 else if (CHIPTYPE(sih->socitype) == SOCI_AI)
845 return ai_core_cflags(sih, mask, val);
846 else if (CHIPTYPE(sih->socitype) == SOCI_UBUS)
847 return ub_core_cflags(sih, mask, val);
855 si_core_cflags_wo(si_t *sih, uint32 mask, uint32 val)
857 if (CHIPTYPE(sih->socitype) == SOCI_SB)
858 sb_core_cflags_wo(sih, mask, val);
859 else if (CHIPTYPE(sih->socitype) == SOCI_AI)
860 ai_core_cflags_wo(sih, mask, val);
861 else if (CHIPTYPE(sih->socitype) == SOCI_UBUS)
862 ub_core_cflags_wo(sih, mask, val);
868 si_core_sflags(si_t *sih, uint32 mask, uint32 val)
870 if (CHIPTYPE(sih->socitype) == SOCI_SB)
871 return sb_core_sflags(sih, mask, val);
872 else if (CHIPTYPE(sih->socitype) == SOCI_AI)
873 return ai_core_sflags(sih, mask, val);
874 else if (CHIPTYPE(sih->socitype) == SOCI_UBUS)
875 return ub_core_sflags(sih, mask, val);
883 si_iscoreup(si_t *sih)
885 if (CHIPTYPE(sih->socitype) == SOCI_SB)
886 return sb_iscoreup(sih);
887 else if (CHIPTYPE(sih->socitype) == SOCI_AI)
888 return ai_iscoreup(sih);
889 else if (CHIPTYPE(sih->socitype) == SOCI_UBUS)
890 return ub_iscoreup(sih);
898 si_wrapperreg(si_t *sih, uint32 offset, uint32 mask, uint32 val)
900 /* only for AI back plane chips */
901 if (CHIPTYPE(sih->socitype) == SOCI_AI)
902 return (ai_wrap_reg(sih, offset, mask, val));
907 si_corereg(si_t *sih, uint coreidx, uint regoff, uint mask, uint val)
909 if (CHIPTYPE(sih->socitype) == SOCI_SB)
910 return sb_corereg(sih, coreidx, regoff, mask, val);
911 else if (CHIPTYPE(sih->socitype) == SOCI_AI)
912 return ai_corereg(sih, coreidx, regoff, mask, val);
913 else if (CHIPTYPE(sih->socitype) == SOCI_UBUS)
914 return ub_corereg(sih, coreidx, regoff, mask, val);
922 si_core_disable(si_t *sih, uint32 bits)
924 if (CHIPTYPE(sih->socitype) == SOCI_SB)
925 sb_core_disable(sih, bits);
926 else if (CHIPTYPE(sih->socitype) == SOCI_AI)
927 ai_core_disable(sih, bits);
928 else if (CHIPTYPE(sih->socitype) == SOCI_UBUS)
929 ub_core_disable(sih, bits);
933 si_core_reset(si_t *sih, uint32 bits, uint32 resetbits)
935 if (CHIPTYPE(sih->socitype) == SOCI_SB)
936 sb_core_reset(sih, bits, resetbits);
937 else if (CHIPTYPE(sih->socitype) == SOCI_AI)
938 ai_core_reset(sih, bits, resetbits);
939 else if (CHIPTYPE(sih->socitype) == SOCI_UBUS)
940 ub_core_reset(sih, bits, resetbits);
943 /* Run bist on current core. Caller needs to take care of core-specific bist hazards */
945 si_corebist(si_t *sih)
950 /* Read core control flags */
951 cflags = si_core_cflags(sih, 0, 0);
954 si_core_cflags(sih, ~0, (SICF_BIST_EN | SICF_FGC));
956 /* Wait for bist done */
957 SPINWAIT(((si_core_sflags(sih, 0, 0) & SISF_BIST_DONE) == 0), 100000);
959 if (si_core_sflags(sih, 0, 0) & SISF_BIST_ERROR)
962 /* Reset core control flags */
963 si_core_cflags(sih, 0xffff, cflags);
972 case CC_F6_2: return 2;
973 case CC_F6_3: return 3;
974 case CC_F6_4: return 4;
975 case CC_F6_5: return 5;
976 case CC_F6_6: return 6;
977 case CC_F6_7: return 7;
982 /* calculate the speed the SI would run at given a set of clockcontrol values */
984 si_clock_rate(uint32 pll_type, uint32 n, uint32 m)
986 uint32 n1, n2, clock, m1, m2, m3, mc;
989 n2 = (n & CN_N2_MASK) >> CN_N2_SHIFT;
991 if (pll_type == PLL_TYPE6) {
996 } else if ((pll_type == PLL_TYPE1) ||
997 (pll_type == PLL_TYPE3) ||
998 (pll_type == PLL_TYPE4) ||
999 (pll_type == PLL_TYPE7)) {
1002 } else if (pll_type == PLL_TYPE2) {
1005 ASSERT((n1 >= 2) && (n1 <= 7));
1006 ASSERT((n2 >= 5) && (n2 <= 23));
1007 } else if (pll_type == PLL_TYPE5) {
1011 /* PLL types 3 and 7 use BASE2 (25Mhz) */
1012 if ((pll_type == PLL_TYPE3) ||
1013 (pll_type == PLL_TYPE7)) {
1014 clock = CC_CLOCK_BASE2 * n1 * n2;
1016 clock = CC_CLOCK_BASE1 * n1 * n2;
1021 m1 = m & CC_M1_MASK;
1022 m2 = (m & CC_M2_MASK) >> CC_M2_SHIFT;
1023 m3 = (m & CC_M3_MASK) >> CC_M3_SHIFT;
1024 mc = (m & CC_MC_MASK) >> CC_MC_SHIFT;
1026 if ((pll_type == PLL_TYPE1) ||
1027 (pll_type == PLL_TYPE3) ||
1028 (pll_type == PLL_TYPE4) ||
1029 (pll_type == PLL_TYPE7)) {
1031 if ((pll_type == PLL_TYPE1) || (pll_type == PLL_TYPE3))
1038 case CC_MC_BYPASS: return (clock);
1039 case CC_MC_M1: return (clock / m1);
1040 case CC_MC_M1M2: return (clock / (m1 * m2));
1041 case CC_MC_M1M2M3: return (clock / (m1 * m2 * m3));
1042 case CC_MC_M1M3: return (clock / (m1 * m3));
1043 default: return (0);
1046 ASSERT(pll_type == PLL_TYPE2);
1051 ASSERT((m1 >= 2) && (m1 <= 7));
1052 ASSERT((m2 >= 3) && (m2 <= 10));
1053 ASSERT((m3 >= 2) && (m3 <= 7));
1055 if ((mc & CC_T2MC_M1BYP) == 0)
1057 if ((mc & CC_T2MC_M2BYP) == 0)
1059 if ((mc & CC_T2MC_M3BYP) == 0)
1067 /* set chip watchdog reset timer to fire in 'ticks' */
1069 si_watchdog(si_t *sih, uint ticks)
1073 if (PMUCTL_ENAB(sih)) {
1075 if ((CHIPID(sih->chip) == BCM4319_CHIP_ID) &&
1076 (CHIPREV(sih->chiprev) == 0) && (ticks != 0)) {
1077 si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, clk_ctl_st), ~0, 0x2);
1078 si_setcore(sih, USB20D_CORE_ID, 0);
1079 si_core_disable(sih, 1);
1080 si_setcore(sih, CC_CORE_ID, 0);
1083 nb = (sih->ccrev < 26) ? 16 : ((sih->ccrev >= 37) ? 32 : 24);
1084 /* The mips compiler uses the sllv instruction,
1085 * so we specially handle the 32-bit case.
1090 maxt = ((1 << nb) - 1);
1094 else if (ticks > maxt)
1097 si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, pmuwatchdog), ~0, ticks);
1099 maxt = (1 << 28) - 1;
1103 si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, watchdog), ~0, ticks);
1107 /* trigger watchdog reset after ms milliseconds */
1109 si_watchdog_ms(si_t *sih, uint32 ms)
1111 si_watchdog(sih, wd_msticks * ms);
1117 /* return the slow clock source - LPO, XTAL, or PCI */
1119 si_slowclk_src(si_info_t *sii)
1123 ASSERT(SI_FAST(sii) || si_coreid(&sii->pub) == CC_CORE_ID);
1125 if (sii->pub.ccrev < 6) {
1126 if ((BUSTYPE(sii->pub.bustype) == PCI_BUS) &&
1127 (OSL_PCI_READ_CONFIG(sii->osh, PCI_GPIO_OUT, sizeof(uint32)) &
1129 return (SCC_SS_PCI);
1131 return (SCC_SS_XTAL);
1132 } else if (sii->pub.ccrev < 10) {
1133 cc = (chipcregs_t *)si_setcoreidx(&sii->pub, sii->curidx);
1134 return (R_REG(sii->osh, &cc->slow_clk_ctl) & SCC_SS_MASK);
1135 } else /* Insta-clock */
1136 return (SCC_SS_XTAL);
1139 /* return the ILP (slowclock) min or max frequency */
1141 si_slowclk_freq(si_info_t *sii, bool max_freq, chipcregs_t *cc)
1146 ASSERT(SI_FAST(sii) || si_coreid(&sii->pub) == CC_CORE_ID);
1148 /* shouldn't be here unless we've established the chip has dynamic clk control */
1149 ASSERT(R_REG(sii->osh, &cc->capabilities) & CC_CAP_PWR_CTL);
1151 slowclk = si_slowclk_src(sii);
1152 if (sii->pub.ccrev < 6) {
1153 if (slowclk == SCC_SS_PCI)
1154 return (max_freq ? (PCIMAXFREQ / 64) : (PCIMINFREQ / 64));
1156 return (max_freq ? (XTALMAXFREQ / 32) : (XTALMINFREQ / 32));
1157 } else if (sii->pub.ccrev < 10) {
1159 (((R_REG(sii->osh, &cc->slow_clk_ctl) & SCC_CD_MASK) >> SCC_CD_SHIFT) + 1);
1160 if (slowclk == SCC_SS_LPO)
1161 return (max_freq ? LPOMAXFREQ : LPOMINFREQ);
1162 else if (slowclk == SCC_SS_XTAL)
1163 return (max_freq ? (XTALMAXFREQ / div) : (XTALMINFREQ / div));
1164 else if (slowclk == SCC_SS_PCI)
1165 return (max_freq ? (PCIMAXFREQ / div) : (PCIMINFREQ / div));
1169 /* Chipc rev 10 is InstaClock */
1170 div = R_REG(sii->osh, &cc->system_clk_ctl) >> SYCC_CD_SHIFT;
1171 div = 4 * (div + 1);
1172 return (max_freq ? XTALMAXFREQ : (XTALMINFREQ / div));
1178 si_clkctl_setdelay(si_info_t *sii, void *chipcregs)
1180 chipcregs_t *cc = (chipcregs_t *)chipcregs;
1181 uint slowmaxfreq, pll_delay, slowclk;
1182 uint pll_on_delay, fref_sel_delay;
1184 pll_delay = PLL_DELAY;
1186 /* If the slow clock is not sourced by the xtal then add the xtal_on_delay
1187 * since the xtal will also be powered down by dynamic clk control logic.
1190 slowclk = si_slowclk_src(sii);
1191 if (slowclk != SCC_SS_XTAL)
1192 pll_delay += XTAL_ON_DELAY;
1194 /* Starting with 4318 it is ILP that is used for the delays */
1195 slowmaxfreq = si_slowclk_freq(sii, (sii->pub.ccrev >= 10) ? FALSE : TRUE, cc);
1197 pll_on_delay = ((slowmaxfreq * pll_delay) + 999999) / 1000000;
1198 fref_sel_delay = ((slowmaxfreq * FREF_DELAY) + 999999) / 1000000;
1200 W_REG(sii->osh, &cc->pll_on_delay, pll_on_delay);
1201 W_REG(sii->osh, &cc->fref_sel_delay, fref_sel_delay);
1204 /* initialize power control delay registers */
1206 si_clkctl_init(si_t *sih)
1213 if (!CCCTL_ENAB(sih))
1217 fast = SI_FAST(sii);
1219 origidx = sii->curidx;
1220 if ((cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0)) == NULL)
1222 } else if ((cc = (chipcregs_t *)CCREGS_FAST(sii)) == NULL)
1226 /* set all Instaclk chip ILP to 1 MHz */
1227 if (sih->ccrev >= 10)
1228 SET_REG(sii->osh, &cc->system_clk_ctl, SYCC_CD_MASK,
1229 (ILP_DIV_1MHZ << SYCC_CD_SHIFT));
1231 si_clkctl_setdelay(sii, (void *)(uintptr)cc);
1234 si_setcoreidx(sih, origidx);
1238 /* change logical "focus" to the gpio core for optimized access */
1240 si_gpiosetcore(si_t *sih)
1242 return (si_setcoreidx(sih, SI_CC_IDX));
1245 /* mask&set gpiocontrol bits */
1247 si_gpiocontrol(si_t *sih, uint32 mask, uint32 val, uint8 priority)
1253 /* gpios could be shared on router platforms
1254 * ignore reservation if it's high priority (e.g., test apps)
1256 if ((priority != GPIO_HI_PRIORITY) &&
1257 (BUSTYPE(sih->bustype) == SI_BUS) && (val || mask)) {
1258 mask = priority ? (si_gpioreservation & mask) :
1259 ((si_gpioreservation | mask) & ~(si_gpioreservation));
1263 regoff = OFFSETOF(chipcregs_t, gpiocontrol);
1264 return (si_corereg(sih, SI_CC_IDX, regoff, mask, val));
1267 /* mask&set gpio output enable bits */
1269 si_gpioouten(si_t *sih, uint32 mask, uint32 val, uint8 priority)
1275 /* gpios could be shared on router platforms
1276 * ignore reservation if it's high priority (e.g., test apps)
1278 if ((priority != GPIO_HI_PRIORITY) &&
1279 (BUSTYPE(sih->bustype) == SI_BUS) && (val || mask)) {
1280 mask = priority ? (si_gpioreservation & mask) :
1281 ((si_gpioreservation | mask) & ~(si_gpioreservation));
1285 regoff = OFFSETOF(chipcregs_t, gpioouten);
1286 return (si_corereg(sih, SI_CC_IDX, regoff, mask, val));
1289 /* mask&set gpio output bits */
1291 si_gpioout(si_t *sih, uint32 mask, uint32 val, uint8 priority)
1297 /* gpios could be shared on router platforms
1298 * ignore reservation if it's high priority (e.g., test apps)
1300 if ((priority != GPIO_HI_PRIORITY) &&
1301 (BUSTYPE(sih->bustype) == SI_BUS) && (val || mask)) {
1302 mask = priority ? (si_gpioreservation & mask) :
1303 ((si_gpioreservation | mask) & ~(si_gpioreservation));
1307 regoff = OFFSETOF(chipcregs_t, gpioout);
1308 return (si_corereg(sih, SI_CC_IDX, regoff, mask, val));
1311 /* reserve one gpio */
1313 si_gpioreserve(si_t *sih, uint32 gpio_bitmask, uint8 priority)
1319 /* only cores on SI_BUS share GPIO's and only applcation users need to
1320 * reserve/release GPIO
1322 if ((BUSTYPE(sih->bustype) != SI_BUS) || (!priority)) {
1323 ASSERT((BUSTYPE(sih->bustype) == SI_BUS) && (priority));
1326 /* make sure only one bit is set */
1327 if ((!gpio_bitmask) || ((gpio_bitmask) & (gpio_bitmask - 1))) {
1328 ASSERT((gpio_bitmask) && !((gpio_bitmask) & (gpio_bitmask - 1)));
1332 /* already reserved */
1333 if (si_gpioreservation & gpio_bitmask)
1335 /* set reservation */
1336 si_gpioreservation |= gpio_bitmask;
1338 return si_gpioreservation;
1341 /* release one gpio */
1343 * releasing the gpio doesn't change the current value on the GPIO last write value
1344 * persists till some one overwrites it
1348 si_gpiorelease(si_t *sih, uint32 gpio_bitmask, uint8 priority)
1354 /* only cores on SI_BUS share GPIO's and only applcation users need to
1355 * reserve/release GPIO
1357 if ((BUSTYPE(sih->bustype) != SI_BUS) || (!priority)) {
1358 ASSERT((BUSTYPE(sih->bustype) == SI_BUS) && (priority));
1361 /* make sure only one bit is set */
1362 if ((!gpio_bitmask) || ((gpio_bitmask) & (gpio_bitmask - 1))) {
1363 ASSERT((gpio_bitmask) && !((gpio_bitmask) & (gpio_bitmask - 1)));
1367 /* already released */
1368 if (!(si_gpioreservation & gpio_bitmask))
1371 /* clear reservation */
1372 si_gpioreservation &= ~gpio_bitmask;
1374 return si_gpioreservation;
1377 /* return the current gpioin register value */
1379 si_gpioin(si_t *sih)
1387 regoff = OFFSETOF(chipcregs_t, gpioin);
1388 return (si_corereg(sih, SI_CC_IDX, regoff, 0, 0));
1391 /* mask&set gpio interrupt polarity bits */
1393 si_gpiointpolarity(si_t *sih, uint32 mask, uint32 val, uint8 priority)
1401 /* gpios could be shared on router platforms */
1402 if ((BUSTYPE(sih->bustype) == SI_BUS) && (val || mask)) {
1403 mask = priority ? (si_gpioreservation & mask) :
1404 ((si_gpioreservation | mask) & ~(si_gpioreservation));
1408 regoff = OFFSETOF(chipcregs_t, gpiointpolarity);
1409 return (si_corereg(sih, SI_CC_IDX, regoff, mask, val));
1412 /* mask&set gpio interrupt mask bits */
1414 si_gpiointmask(si_t *sih, uint32 mask, uint32 val, uint8 priority)
1422 /* gpios could be shared on router platforms */
1423 if ((BUSTYPE(sih->bustype) == SI_BUS) && (val || mask)) {
1424 mask = priority ? (si_gpioreservation & mask) :
1425 ((si_gpioreservation | mask) & ~(si_gpioreservation));
1429 regoff = OFFSETOF(chipcregs_t, gpiointmask);
1430 return (si_corereg(sih, SI_CC_IDX, regoff, mask, val));
1433 /* assign the gpio to an led */
1435 si_gpioled(si_t *sih, uint32 mask, uint32 val)
1440 if (sih->ccrev < 16)
1443 /* gpio led powersave reg */
1444 return (si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, gpiotimeroutmask), mask, val));
1447 /* mask&set gpio timer val */
1449 si_gpiotimerval(si_t *sih, uint32 mask, uint32 gpiotimerval)
1455 if (sih->ccrev < 16)
1458 return (si_corereg(sih, SI_CC_IDX,
1459 OFFSETOF(chipcregs_t, gpiotimerval), mask, gpiotimerval));
1463 si_gpiopull(si_t *sih, bool updown, uint32 mask, uint32 val)
1469 if (sih->ccrev < 20)
1472 offs = (updown ? OFFSETOF(chipcregs_t, gpiopulldown) : OFFSETOF(chipcregs_t, gpiopullup));
1473 return (si_corereg(sih, SI_CC_IDX, offs, mask, val));
1477 si_gpioevent(si_t *sih, uint regtype, uint32 mask, uint32 val)
1483 if (sih->ccrev < 11)
1486 if (regtype == GPIO_REGEVT)
1487 offs = OFFSETOF(chipcregs_t, gpioevent);
1488 else if (regtype == GPIO_REGEVT_INTMSK)
1489 offs = OFFSETOF(chipcregs_t, gpioeventintmask);
1490 else if (regtype == GPIO_REGEVT_INTPOL)
1491 offs = OFFSETOF(chipcregs_t, gpioeventintpolarity);
1495 return (si_corereg(sih, SI_CC_IDX, offs, mask, val));
1499 si_gpio_handler_register(si_t *sih, uint32 event,
1500 bool level, gpio_handler_t cb, void *arg)
1509 if (sih->ccrev < 11)
1512 if ((gi = MALLOC(sii->osh, sizeof(gpioh_item_t))) == NULL)
1515 bzero(gi, sizeof(gpioh_item_t));
1521 gi->next = sii->gpioh_head;
1522 sii->gpioh_head = gi;
1524 return (void *)(gi);
1528 si_gpio_handler_unregister(si_t *sih, void *gpioh)
1531 gpioh_item_t *p, *n;
1534 if (sih->ccrev < 11)
1537 ASSERT(sii->gpioh_head != NULL);
1538 if ((void*)sii->gpioh_head == gpioh) {
1539 sii->gpioh_head = sii->gpioh_head->next;
1540 MFREE(sii->osh, gpioh, sizeof(gpioh_item_t));
1543 p = sii->gpioh_head;
1546 if ((void*)n == gpioh) {
1548 MFREE(sii->osh, gpioh, sizeof(gpioh_item_t));
1556 ASSERT(0); /* Not found in list */
1560 si_gpio_handler_process(si_t *sih)
1565 uint32 level = si_gpioin(sih);
1566 uint32 edge = si_gpioevent(sih, GPIO_REGEVT, 0, 0);
1569 for (h = sii->gpioh_head; h != NULL; h = h->next) {
1571 status = (h->level ? level : edge);
1573 if (status & h->event)
1574 h->handler(status, h->arg);
1578 si_gpioevent(sih, GPIO_REGEVT, edge, edge); /* clear edge-trigger status */
1582 si_gpio_int_enable(si_t *sih, bool enable)
1588 if (sih->ccrev < 11)
1591 offs = OFFSETOF(chipcregs_t, intmask);
1592 return (si_corereg(sih, SI_CC_IDX, offs, CI_GPIO, (enable ? CI_GPIO : 0)));
1596 /* Return the size of the specified SOCRAM bank */
1598 socram_banksize(si_info_t *sii, sbsocramregs_t *regs, uint8 index, uint8 mem_type)
1600 uint banksize, bankinfo;
1601 uint bankidx = index | (mem_type << SOCRAM_BANKIDX_MEMTYPE_SHIFT);
1603 ASSERT(mem_type <= SOCRAM_MEMTYPE_DEVRAM);
1605 W_REG(sii->osh, ®s->bankidx, bankidx);
1606 bankinfo = R_REG(sii->osh, ®s->bankinfo);
1607 banksize = SOCRAM_BANKINFO_SZBASE * ((bankinfo & SOCRAM_BANKINFO_SZMASK) + 1);
1612 si_socdevram(si_t *sih, bool set, uint8 *enable, uint8 *protect)
1617 sbsocramregs_t *regs;
1623 /* Block ints and save current core */
1624 INTR_OFF(sii, intr_val);
1625 origidx = si_coreidx(sih);
1628 *enable = *protect = 0;
1630 /* Switch to SOCRAM core */
1631 if (!(regs = si_setcore(sih, SOCRAM_CORE_ID, 0)))
1634 /* Get info for determining size */
1635 if (!(wasup = si_iscoreup(sih)))
1636 si_core_reset(sih, 0, 0);
1638 corerev = si_corerev(sih);
1639 if (corerev >= 10) {
1643 uint32 bankidx, bankinfo;
1645 extcinfo = R_REG(sii->osh, ®s->extracoreinfo);
1646 nb = ((extcinfo & SOCRAM_DEVRAMBANK_MASK) >> SOCRAM_DEVRAMBANK_SHIFT);
1647 for (i = 0; i < nb; i++) {
1648 bankidx = i | (SOCRAM_MEMTYPE_DEVRAM << SOCRAM_BANKIDX_MEMTYPE_SHIFT);
1649 W_REG(sii->osh, ®s->bankidx, bankidx);
1650 bankinfo = R_REG(sii->osh, ®s->bankinfo);
1652 bankinfo &= ~SOCRAM_BANKINFO_DEVRAMSEL_MASK;
1653 bankinfo &= ~SOCRAM_BANKINFO_DEVRAMPRO_MASK;
1655 bankinfo |= (1 << SOCRAM_BANKINFO_DEVRAMSEL_SHIFT);
1657 bankinfo |= (1 << SOCRAM_BANKINFO_DEVRAMPRO_SHIFT);
1659 W_REG(sii->osh, ®s->bankinfo, bankinfo);
1662 if (bankinfo & SOCRAM_BANKINFO_DEVRAMSEL_MASK) {
1664 if (bankinfo & SOCRAM_BANKINFO_DEVRAMPRO_MASK)
1671 /* Return to previous state and core */
1673 si_core_disable(sih, 0);
1674 si_setcoreidx(sih, origidx);
1677 INTR_RESTORE(sii, intr_val);
1681 si_socdevram_pkg(si_t *sih)
1683 if (si_socdevram_size(sih) > 0)
1690 si_socdevram_size(si_t *sih)
1696 sbsocramregs_t *regs;
1702 /* Block ints and save current core */
1703 INTR_OFF(sii, intr_val);
1704 origidx = si_coreidx(sih);
1706 /* Switch to SOCRAM core */
1707 if (!(regs = si_setcore(sih, SOCRAM_CORE_ID, 0)))
1710 /* Get info for determining size */
1711 if (!(wasup = si_iscoreup(sih)))
1712 si_core_reset(sih, 0, 0);
1714 corerev = si_corerev(sih);
1715 if (corerev >= 10) {
1720 extcinfo = R_REG(sii->osh, ®s->extracoreinfo);
1721 nb = (((extcinfo & SOCRAM_DEVRAMBANK_MASK) >> SOCRAM_DEVRAMBANK_SHIFT));
1722 for (i = 0; i < nb; i++)
1723 memsize += socram_banksize(sii, regs, i, SOCRAM_MEMTYPE_DEVRAM);
1726 /* Return to previous state and core */
1728 si_core_disable(sih, 0);
1729 si_setcoreidx(sih, origidx);
1732 INTR_RESTORE(sii, intr_val);
1737 /* Return the RAM size of the SOCRAM core */
1739 si_socram_size(si_t *sih)
1745 sbsocramregs_t *regs;
1753 /* Block ints and save current core */
1754 INTR_OFF(sii, intr_val);
1755 origidx = si_coreidx(sih);
1757 /* Switch to SOCRAM core */
1758 if (!(regs = si_setcore(sih, SOCRAM_CORE_ID, 0)))
1761 /* Get info for determining size */
1762 if (!(wasup = si_iscoreup(sih)))
1763 si_core_reset(sih, 0, 0);
1764 corerev = si_corerev(sih);
1765 coreinfo = R_REG(sii->osh, ®s->coreinfo);
1767 /* Calculate size from coreinfo based on rev */
1769 memsize = 1 << (16 + (coreinfo & SRCI_MS0_MASK));
1770 else if (corerev < 3) {
1771 memsize = 1 << (SR_BSZ_BASE + (coreinfo & SRCI_SRBSZ_MASK));
1772 memsize *= (coreinfo & SRCI_SRNB_MASK) >> SRCI_SRNB_SHIFT;
1773 } else if ((corerev <= 7) || (corerev == 12)) {
1774 uint nb = (coreinfo & SRCI_SRNB_MASK) >> SRCI_SRNB_SHIFT;
1775 uint bsz = (coreinfo & SRCI_SRBSZ_MASK);
1776 uint lss = (coreinfo & SRCI_LSS_MASK) >> SRCI_LSS_SHIFT;
1779 memsize = nb * (1 << (bsz + SR_BSZ_BASE));
1781 memsize += (1 << ((lss - 1) + SR_BSZ_BASE));
1784 uint nb = (coreinfo & SRCI_SRNB_MASK) >> SRCI_SRNB_SHIFT;
1785 for (i = 0; i < nb; i++)
1786 memsize += socram_banksize(sii, regs, i, SOCRAM_MEMTYPE_RAM);
1789 /* Return to previous state and core */
1791 si_core_disable(sih, 0);
1792 si_setcoreidx(sih, origidx);
1795 INTR_RESTORE(sii, intr_val);
1802 si_btcgpiowar(si_t *sih)
1811 /* Make sure that there is ChipCommon core present &&
1812 * UART_TX is strapped to 1
1814 if (!(sih->cccaps & CC_CAP_UARTGPIO))
1817 /* si_corereg cannot be used as we have to guarantee 8-bit read/writes */
1818 INTR_OFF(sii, intr_val);
1820 origidx = si_coreidx(sih);
1822 cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0);
1825 W_REG(sii->osh, &cc->uart0mcr, R_REG(sii->osh, &cc->uart0mcr) | 0x04);
1827 /* restore the original index */
1828 si_setcoreidx(sih, origidx);
1830 INTR_RESTORE(sii, intr_val);
1834 si_pll_reset(si_t *sih)
1841 /* check if the device is removed */
1843 si_deviceremoved(si_t *sih)
1850 switch (BUSTYPE(sih->bustype)) {
1852 ASSERT(sii->osh != NULL);
1853 w = OSL_PCI_READ_CONFIG(sii->osh, PCI_CFG_VID, sizeof(uint32));
1854 if ((w & 0xFFFF) != VENDOR_BROADCOM)
1862 si_is_sprom_available(si_t *sih)
1864 if (sih->ccrev >= 31) {
1870 if ((sih->cccaps & CC_CAP_SROM) == 0)
1874 origidx = sii->curidx;
1875 cc = si_setcoreidx(sih, SI_CC_IDX);
1876 sromctrl = R_REG(sii->osh, &cc->sromcontrol);
1877 si_setcoreidx(sih, origidx);
1878 return (sromctrl & SRC_PRESENT);
1881 switch (CHIPID(sih->chip)) {
1882 case BCM4312_CHIP_ID:
1883 return ((sih->chipst & CST4312_SPROM_OTP_SEL_MASK) != CST4312_OTP_SEL);
1884 case BCM4325_CHIP_ID:
1885 return (sih->chipst & CST4325_SPROM_SEL) != 0;
1886 case BCM4322_CHIP_ID:
1887 case BCM43221_CHIP_ID:
1888 case BCM43231_CHIP_ID:
1889 case BCM43222_CHIP_ID:
1890 case BCM43111_CHIP_ID:
1891 case BCM43112_CHIP_ID:
1892 case BCM4342_CHIP_ID:
1895 spromotp = (sih->chipst & CST4322_SPROM_OTP_SEL_MASK) >>
1896 CST4322_SPROM_OTP_SEL_SHIFT;
1897 return (spromotp & CST4322_SPROM_PRESENT) != 0;
1899 case BCM4329_CHIP_ID:
1900 return (sih->chipst & CST4329_SPROM_SEL) != 0;
1901 case BCM4315_CHIP_ID:
1902 return (sih->chipst & CST4315_SPROM_SEL) != 0;
1903 case BCM4319_CHIP_ID:
1904 return (sih->chipst & CST4319_SPROM_SEL) != 0;
1905 case BCM4336_CHIP_ID:
1906 case BCM43362_CHIP_ID:
1907 return (sih->chipst & CST4336_SPROM_PRESENT) != 0;
1908 case BCM4330_CHIP_ID:
1909 return (sih->chipst & CST4330_SPROM_PRESENT) != 0;
1910 case BCM4313_CHIP_ID:
1911 return (sih->chipst & CST4313_SPROM_PRESENT) != 0;
1912 case BCM43239_CHIP_ID:
1913 return ((sih->chipst & CST43239_SPROM_MASK) &&
1914 !(sih->chipst & CST43239_SFLASH_MASK));