/drivers/net/wireless/bcmdhd_29/siutils.c

https://bitbucket.org/cyanogenmod/android_kernel_asus_tf300t · C · 1915 lines · 1416 code · 320 blank · 179 comment · 508 complexity · 0a496f5b2db014c90a6f25eba2e494e8 MD5 · raw file

  1. /*
  2. * Misc utility routines for accessing chip-specific features
  3. * of the SiliconBackplane-based Broadcom chips.
  4. *
  5. * Copyright (C) 1999-2011, Broadcom Corporation
  6. *
  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:
  12. *
  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.
  20. *
  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.
  24. *
  25. * $Id: siutils.c,v 1.813.2.36 2011-02-10 23:43:55 $
  26. */
  27. #include <typedefs.h>
  28. #include <bcmdefs.h>
  29. #include <osl.h>
  30. #include <bcmutils.h>
  31. #include <siutils.h>
  32. #include <bcmdevs.h>
  33. #include <hndsoc.h>
  34. #include <sbchipc.h>
  35. #include <pcicfg.h>
  36. #include <sbpcmcia.h>
  37. #include <sbsocram.h>
  38. #include <bcmsdh.h>
  39. #include <sdio.h>
  40. #include <sbsdio.h>
  41. #include <sbhnddma.h>
  42. #include <sbsdpcmdev.h>
  43. #include <bcmsdpcm.h>
  44. #include <hndpmu.h>
  45. #include "siutils_priv.h"
  46. /* local prototypes */
  47. static si_info_t *si_doattach(si_info_t *sii, uint devid, osl_t *osh, void *regs,
  48. uint bustype, void *sdh, char **vars, uint *varsz);
  49. static bool si_buscore_prep(si_info_t *sii, uint bustype, uint devid, void *sdh);
  50. static bool si_buscore_setup(si_info_t *sii, chipcregs_t *cc, uint bustype, uint32 savewin,
  51. uint *origidx, void *regs);
  52. /* global variable to indicate reservation/release of gpio's */
  53. static uint32 si_gpioreservation = 0;
  54. /* global flag to prevent shared resources from being initialized multiple times in si_attach() */
  55. /*
  56. * Allocate a si handle.
  57. * devid - pci device id (used to determine chip#)
  58. * osh - opaque OS handle
  59. * regs - virtual address of initial core registers
  60. * bustype - pci/pcmcia/sb/sdio/etc
  61. * vars - pointer to a pointer area for "environment" variables
  62. * varsz - pointer to int to return the size of the vars
  63. */
  64. si_t *
  65. si_attach(uint devid, osl_t *osh, void *regs,
  66. uint bustype, void *sdh, char **vars, uint *varsz)
  67. {
  68. si_info_t *sii;
  69. /* alloc si_info_t */
  70. if ((sii = MALLOC(osh, sizeof (si_info_t))) == NULL) {
  71. SI_ERROR(("si_attach: malloc failed! malloced %d bytes\n", MALLOCED(osh)));
  72. return (NULL);
  73. }
  74. if (si_doattach(sii, devid, osh, regs, bustype, sdh, vars, varsz) == NULL) {
  75. MFREE(osh, sii, sizeof(si_info_t));
  76. return (NULL);
  77. }
  78. sii->vars = vars ? *vars : NULL;
  79. sii->varsz = varsz ? *varsz : 0;
  80. return (si_t *)sii;
  81. }
  82. /* global kernel resource */
  83. static si_info_t ksii;
  84. static uint32 wd_msticks; /* watchdog timer ticks normalized to ms */
  85. /* generic kernel variant of si_attach() */
  86. si_t *
  87. si_kattach(osl_t *osh)
  88. {
  89. static bool ksii_attached = FALSE;
  90. if (!ksii_attached) {
  91. void *regs;
  92. regs = REG_MAP(SI_ENUM_BASE, SI_CORE_SIZE);
  93. if (si_doattach(&ksii, BCM4710_DEVICE_ID, osh, regs,
  94. SI_BUS, NULL,
  95. osh != SI_OSH ? &ksii.vars : NULL,
  96. osh != SI_OSH ? &ksii.varsz : NULL) == NULL) {
  97. SI_ERROR(("si_kattach: si_doattach failed\n"));
  98. REG_UNMAP(regs);
  99. return NULL;
  100. }
  101. REG_UNMAP(regs);
  102. /* save ticks normalized to ms for si_watchdog_ms() */
  103. if (PMUCTL_ENAB(&ksii.pub)) {
  104. /* based on 32KHz ILP clock */
  105. wd_msticks = 32;
  106. } else {
  107. wd_msticks = ALP_CLOCK / 1000;
  108. }
  109. ksii_attached = TRUE;
  110. SI_MSG(("si_kattach done. ccrev = %d, wd_msticks = %d\n",
  111. ksii.pub.ccrev, wd_msticks));
  112. }
  113. return &ksii.pub;
  114. }
  115. static bool
  116. si_buscore_prep(si_info_t *sii, uint bustype, uint devid, void *sdh)
  117. {
  118. /* need to set memseg flag for CF card first before any sb registers access */
  119. if (BUSTYPE(bustype) == PCMCIA_BUS)
  120. sii->memseg = TRUE;
  121. if (BUSTYPE(bustype) == SDIO_BUS) {
  122. int err;
  123. uint8 clkset;
  124. /* Try forcing SDIO core to do ALPAvail request only */
  125. clkset = SBSDIO_FORCE_HW_CLKREQ_OFF | SBSDIO_ALP_AVAIL_REQ;
  126. bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, clkset, &err);
  127. if (!err) {
  128. uint8 clkval;
  129. /* If register supported, wait for ALPAvail and then force ALP */
  130. clkval = bcmsdh_cfg_read(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, NULL);
  131. if ((clkval & ~SBSDIO_AVBITS) == clkset) {
  132. SPINWAIT(((clkval = bcmsdh_cfg_read(sdh, SDIO_FUNC_1,
  133. SBSDIO_FUNC1_CHIPCLKCSR, NULL)), !SBSDIO_ALPAV(clkval)),
  134. PMU_MAX_TRANSITION_DLY);
  135. if (!SBSDIO_ALPAV(clkval)) {
  136. SI_ERROR(("timeout on ALPAV wait, clkval 0x%02x\n",
  137. clkval));
  138. return FALSE;
  139. }
  140. clkset = SBSDIO_FORCE_HW_CLKREQ_OFF | SBSDIO_FORCE_ALP;
  141. bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR,
  142. clkset, &err);
  143. OSL_DELAY(65);
  144. }
  145. }
  146. /* Also, disable the extra SDIO pull-ups */
  147. bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_SDIOPULLUP, 0, NULL);
  148. }
  149. return TRUE;
  150. }
  151. static bool
  152. si_buscore_setup(si_info_t *sii, chipcregs_t *cc, uint bustype, uint32 savewin,
  153. uint *origidx, void *regs)
  154. {
  155. bool pci, pcie;
  156. uint i;
  157. uint pciidx, pcieidx, pcirev, pcierev;
  158. cc = si_setcoreidx(&sii->pub, SI_CC_IDX);
  159. ASSERT((uintptr)cc);
  160. /* get chipcommon rev */
  161. sii->pub.ccrev = (int)si_corerev(&sii->pub);
  162. /* get chipcommon chipstatus */
  163. if (sii->pub.ccrev >= 11)
  164. sii->pub.chipst = R_REG(sii->osh, &cc->chipstatus);
  165. /* get chipcommon capabilites */
  166. sii->pub.cccaps = R_REG(sii->osh, &cc->capabilities);
  167. /* get chipcommon extended capabilities */
  168. if (sii->pub.ccrev >= 35)
  169. sii->pub.cccaps_ext = R_REG(sii->osh, &cc->capabilities_ext);
  170. /* get pmu rev and caps */
  171. if (sii->pub.cccaps & CC_CAP_PMU) {
  172. sii->pub.pmucaps = R_REG(sii->osh, &cc->pmucapabilities);
  173. sii->pub.pmurev = sii->pub.pmucaps & PCAP_REV_MASK;
  174. }
  175. SI_MSG(("Chipc: rev %d, caps 0x%x, chipst 0x%x pmurev %d, pmucaps 0x%x\n",
  176. sii->pub.ccrev, sii->pub.cccaps, sii->pub.chipst, sii->pub.pmurev,
  177. sii->pub.pmucaps));
  178. /* figure out bus/orignal core idx */
  179. sii->pub.buscoretype = NODEV_CORE_ID;
  180. sii->pub.buscorerev = (uint)NOREV;
  181. sii->pub.buscoreidx = BADIDX;
  182. pci = pcie = FALSE;
  183. pcirev = pcierev = (uint)NOREV;
  184. pciidx = pcieidx = BADIDX;
  185. for (i = 0; i < sii->numcores; i++) {
  186. uint cid, crev;
  187. si_setcoreidx(&sii->pub, i);
  188. cid = si_coreid(&sii->pub);
  189. crev = si_corerev(&sii->pub);
  190. /* Display cores found */
  191. SI_VMSG(("CORE[%d]: id 0x%x rev %d base 0x%x regs 0x%p\n",
  192. i, cid, crev, sii->coresba[i], sii->regs[i]));
  193. if (BUSTYPE(bustype) == PCI_BUS) {
  194. if (cid == PCI_CORE_ID) {
  195. pciidx = i;
  196. pcirev = crev;
  197. pci = TRUE;
  198. } else if (cid == PCIE_CORE_ID) {
  199. pcieidx = i;
  200. pcierev = crev;
  201. pcie = TRUE;
  202. }
  203. } else if ((BUSTYPE(bustype) == PCMCIA_BUS) &&
  204. (cid == PCMCIA_CORE_ID)) {
  205. sii->pub.buscorerev = crev;
  206. sii->pub.buscoretype = cid;
  207. sii->pub.buscoreidx = i;
  208. }
  209. else if (((BUSTYPE(bustype) == SDIO_BUS) ||
  210. (BUSTYPE(bustype) == SPI_BUS)) &&
  211. ((cid == PCMCIA_CORE_ID) ||
  212. (cid == SDIOD_CORE_ID))) {
  213. sii->pub.buscorerev = crev;
  214. sii->pub.buscoretype = cid;
  215. sii->pub.buscoreidx = i;
  216. }
  217. /* find the core idx before entering this func. */
  218. if ((savewin && (savewin == sii->coresba[i])) ||
  219. (regs == sii->regs[i]))
  220. *origidx = i;
  221. }
  222. if (pci) {
  223. sii->pub.buscoretype = PCI_CORE_ID;
  224. sii->pub.buscorerev = pcirev;
  225. sii->pub.buscoreidx = pciidx;
  226. } else if (pcie) {
  227. sii->pub.buscoretype = PCIE_CORE_ID;
  228. sii->pub.buscorerev = pcierev;
  229. sii->pub.buscoreidx = pcieidx;
  230. }
  231. SI_VMSG(("Buscore id/type/rev %d/0x%x/%d\n", sii->pub.buscoreidx, sii->pub.buscoretype,
  232. sii->pub.buscorerev));
  233. if (BUSTYPE(sii->pub.bustype) == SI_BUS && (CHIPID(sii->pub.chip) == BCM4712_CHIP_ID) &&
  234. (sii->pub.chippkg != BCM4712LARGE_PKG_ID) && (CHIPREV(sii->pub.chiprev) <= 3))
  235. OR_REG(sii->osh, &cc->slow_clk_ctl, SCC_SS_XTAL);
  236. /* Make sure any on-chip ARM is off (in case strapping is wrong), or downloaded code was
  237. * already running.
  238. */
  239. if ((BUSTYPE(bustype) == SDIO_BUS) || (BUSTYPE(bustype) == SPI_BUS)) {
  240. if (si_setcore(&sii->pub, ARM7S_CORE_ID, 0) ||
  241. si_setcore(&sii->pub, ARMCM3_CORE_ID, 0))
  242. si_core_disable(&sii->pub, 0);
  243. }
  244. /* return to the original core */
  245. si_setcoreidx(&sii->pub, *origidx);
  246. return TRUE;
  247. }
  248. static si_info_t *
  249. si_doattach(si_info_t *sii, uint devid, osl_t *osh, void *regs,
  250. uint bustype, void *sdh, char **vars, uint *varsz)
  251. {
  252. struct si_pub *sih = &sii->pub;
  253. uint32 w, savewin;
  254. chipcregs_t *cc;
  255. char *pvars = NULL;
  256. uint origidx;
  257. ASSERT(GOODREGS(regs));
  258. bzero((uchar*)sii, sizeof(si_info_t));
  259. savewin = 0;
  260. sih->buscoreidx = BADIDX;
  261. sii->curmap = regs;
  262. sii->sdh = sdh;
  263. sii->osh = osh;
  264. /* find Chipcommon address */
  265. if (bustype == PCI_BUS) {
  266. savewin = OSL_PCI_READ_CONFIG(sii->osh, PCI_BAR0_WIN, sizeof(uint32));
  267. if (!GOODCOREADDR(savewin, SI_ENUM_BASE))
  268. savewin = SI_ENUM_BASE;
  269. OSL_PCI_WRITE_CONFIG(sii->osh, PCI_BAR0_WIN, 4, SI_ENUM_BASE);
  270. cc = (chipcregs_t *)regs;
  271. } else if ((bustype == SDIO_BUS) || (bustype == SPI_BUS)) {
  272. cc = (chipcregs_t *)sii->curmap;
  273. } else {
  274. cc = (chipcregs_t *)REG_MAP(SI_ENUM_BASE, SI_CORE_SIZE);
  275. }
  276. sih->bustype = bustype;
  277. if (bustype != BUSTYPE(bustype)) {
  278. SI_ERROR(("si_doattach: bus type %d does not match configured bus type %d\n",
  279. bustype, BUSTYPE(bustype)));
  280. return NULL;
  281. }
  282. /* bus/core/clk setup for register access */
  283. if (!si_buscore_prep(sii, bustype, devid, sdh)) {
  284. SI_ERROR(("si_doattach: si_core_clk_prep failed %d\n", bustype));
  285. return NULL;
  286. }
  287. /* ChipID recognition.
  288. * We assume we can read chipid at offset 0 from the regs arg.
  289. * If we add other chiptypes (or if we need to support old sdio hosts w/o chipcommon),
  290. * some way of recognizing them needs to be added here.
  291. */
  292. w = R_REG(osh, &cc->chipid);
  293. sih->socitype = (w & CID_TYPE_MASK) >> CID_TYPE_SHIFT;
  294. /* Might as wll fill in chip id rev & pkg */
  295. sih->chip = w & CID_ID_MASK;
  296. sih->chiprev = (w & CID_REV_MASK) >> CID_REV_SHIFT;
  297. sih->chippkg = (w & CID_PKG_MASK) >> CID_PKG_SHIFT;
  298. if (CHIPID(sih->chip) == BCM4322_CHIP_ID && (((sih->chipst & CST4322_SPROM_OTP_SEL_MASK)
  299. >> CST4322_SPROM_OTP_SEL_SHIFT) == (CST4322_OTP_PRESENT |
  300. CST4322_SPROM_PRESENT))) {
  301. SI_ERROR(("%s: Invalid setting: both SPROM and OTP strapped.\n", __FUNCTION__));
  302. return NULL;
  303. }
  304. #if defined(HW_OOB)
  305. if (CHIPID(sih->chip) == BCM43362_CHIP_ID) {
  306. uint32 gpiocontrol, addr;
  307. addr = SI_ENUM_BASE + OFFSETOF(chipcregs_t, gpiocontrol);
  308. gpiocontrol = bcmsdh_reg_read(sdh, addr, 4);
  309. gpiocontrol |= 0x2;
  310. bcmsdh_reg_write(sdh, addr, 4, gpiocontrol);
  311. bcmsdh_cfg_write(sdh, SDIO_FUNC_1, 0x10005, 0xf, NULL);
  312. bcmsdh_cfg_write(sdh, SDIO_FUNC_1, 0x10006, 0x0, NULL);
  313. bcmsdh_cfg_write(sdh, SDIO_FUNC_1, 0x10007, 0x2, NULL);
  314. }
  315. #endif
  316. if ((CHIPID(sih->chip) == BCM4329_CHIP_ID) && (sih->chiprev == 0) &&
  317. (sih->chippkg != BCM4329_289PIN_PKG_ID)) {
  318. sih->chippkg = BCM4329_182PIN_PKG_ID;
  319. }
  320. sih->issim = IS_SIM(sih->chippkg);
  321. /* scan for cores */
  322. if (CHIPTYPE(sii->pub.socitype) == SOCI_SB) {
  323. SI_MSG(("Found chip type SB (0x%08x)\n", w));
  324. sb_scan(&sii->pub, regs, devid);
  325. } else if (CHIPTYPE(sii->pub.socitype) == SOCI_AI) {
  326. SI_MSG(("Found chip type AI (0x%08x)\n", w));
  327. /* pass chipc address instead of original core base */
  328. ai_scan(&sii->pub, (void *)(uintptr)cc, devid);
  329. } else if (CHIPTYPE(sii->pub.socitype) == SOCI_UBUS) {
  330. SI_MSG(("Found chip type UBUS (0x%08x), chip id = 0x%4x\n", w, sih->chip));
  331. /* pass chipc address instead of original core base */
  332. ub_scan(&sii->pub, (void *)(uintptr)cc, devid);
  333. } else {
  334. SI_ERROR(("Found chip of unknown type (0x%08x)\n", w));
  335. return NULL;
  336. }
  337. /* no cores found, bail out */
  338. if (sii->numcores == 0) {
  339. SI_ERROR(("si_doattach: could not find any cores\n"));
  340. return NULL;
  341. }
  342. /* bus/core/clk setup */
  343. origidx = SI_CC_IDX;
  344. if (!si_buscore_setup(sii, cc, bustype, savewin, &origidx, regs)) {
  345. SI_ERROR(("si_doattach: si_buscore_setup failed\n"));
  346. goto exit;
  347. }
  348. /* assume current core is CC */
  349. if ((sii->pub.ccrev == 0x25) && ((CHIPID(sih->chip) == BCM43234_CHIP_ID ||
  350. CHIPID(sih->chip) == BCM43235_CHIP_ID ||
  351. CHIPID(sih->chip) == BCM43236_CHIP_ID ||
  352. CHIPID(sih->chip) == BCM43238_CHIP_ID) &&
  353. (CHIPREV(sii->pub.chiprev) == 0))) {
  354. if ((cc->chipstatus & CST43236_BP_CLK) != 0) {
  355. uint clkdiv;
  356. clkdiv = R_REG(osh, &cc->clkdiv);
  357. /* otp_clk_div is even number, 120/14 < 9mhz */
  358. clkdiv = (clkdiv & ~CLKD_OTP) | (14 << CLKD_OTP_SHIFT);
  359. W_REG(osh, &cc->clkdiv, clkdiv);
  360. SI_ERROR(("%s: set clkdiv to %x\n", __FUNCTION__, clkdiv));
  361. }
  362. OSL_DELAY(10);
  363. }
  364. pvars = NULL;
  365. if (sii->pub.ccrev >= 20) {
  366. cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0);
  367. ASSERT(cc != NULL);
  368. W_REG(osh, &cc->gpiopullup, 0);
  369. W_REG(osh, &cc->gpiopulldown, 0);
  370. si_setcoreidx(sih, origidx);
  371. }
  372. return (sii);
  373. exit:
  374. return NULL;
  375. }
  376. /* may be called with core in reset */
  377. void
  378. si_detach(si_t *sih)
  379. {
  380. si_info_t *sii;
  381. uint idx;
  382. sii = SI_INFO(sih);
  383. if (sii == NULL)
  384. return;
  385. if (BUSTYPE(sih->bustype) == SI_BUS)
  386. for (idx = 0; idx < SI_MAXCORES; idx++)
  387. if (sii->regs[idx]) {
  388. REG_UNMAP(sii->regs[idx]);
  389. sii->regs[idx] = NULL;
  390. }
  391. #if !defined(BCMBUSTYPE) || (BCMBUSTYPE == SI_BUS)
  392. if (sii != &ksii)
  393. #endif /* !BCMBUSTYPE || (BCMBUSTYPE == SI_BUS) */
  394. MFREE(sii->osh, sii, sizeof(si_info_t));
  395. }
  396. void *
  397. si_osh(si_t *sih)
  398. {
  399. si_info_t *sii;
  400. sii = SI_INFO(sih);
  401. return sii->osh;
  402. }
  403. void
  404. si_setosh(si_t *sih, osl_t *osh)
  405. {
  406. si_info_t *sii;
  407. sii = SI_INFO(sih);
  408. if (sii->osh != NULL) {
  409. SI_ERROR(("osh is already set....\n"));
  410. ASSERT(!sii->osh);
  411. }
  412. sii->osh = osh;
  413. }
  414. /* register driver interrupt disabling and restoring callback functions */
  415. void
  416. si_register_intr_callback(si_t *sih, void *intrsoff_fn, void *intrsrestore_fn,
  417. void *intrsenabled_fn, void *intr_arg)
  418. {
  419. si_info_t *sii;
  420. sii = SI_INFO(sih);
  421. sii->intr_arg = intr_arg;
  422. sii->intrsoff_fn = (si_intrsoff_t)intrsoff_fn;
  423. sii->intrsrestore_fn = (si_intrsrestore_t)intrsrestore_fn;
  424. sii->intrsenabled_fn = (si_intrsenabled_t)intrsenabled_fn;
  425. /* save current core id. when this function called, the current core
  426. * must be the core which provides driver functions(il, et, wl, etc.)
  427. */
  428. sii->dev_coreid = sii->coreid[sii->curidx];
  429. }
  430. void
  431. si_deregister_intr_callback(si_t *sih)
  432. {
  433. si_info_t *sii;
  434. sii = SI_INFO(sih);
  435. sii->intrsoff_fn = NULL;
  436. }
  437. uint
  438. si_intflag(si_t *sih)
  439. {
  440. si_info_t *sii = SI_INFO(sih);
  441. if (CHIPTYPE(sih->socitype) == SOCI_SB)
  442. return sb_intflag(sih);
  443. else if (CHIPTYPE(sih->socitype) == SOCI_AI)
  444. return R_REG(sii->osh, ((uint32 *)(uintptr)
  445. (sii->oob_router + OOB_STATUSA)));
  446. else {
  447. ASSERT(0);
  448. return 0;
  449. }
  450. }
  451. uint
  452. si_flag(si_t *sih)
  453. {
  454. if (CHIPTYPE(sih->socitype) == SOCI_SB)
  455. return sb_flag(sih);
  456. else if (CHIPTYPE(sih->socitype) == SOCI_AI)
  457. return ai_flag(sih);
  458. else if (CHIPTYPE(sih->socitype) == SOCI_UBUS)
  459. return ub_flag(sih);
  460. else {
  461. ASSERT(0);
  462. return 0;
  463. }
  464. }
  465. void
  466. si_setint(si_t *sih, int siflag)
  467. {
  468. if (CHIPTYPE(sih->socitype) == SOCI_SB)
  469. sb_setint(sih, siflag);
  470. else if (CHIPTYPE(sih->socitype) == SOCI_AI)
  471. ai_setint(sih, siflag);
  472. else if (CHIPTYPE(sih->socitype) == SOCI_UBUS)
  473. ub_setint(sih, siflag);
  474. else
  475. ASSERT(0);
  476. }
  477. uint
  478. si_coreid(si_t *sih)
  479. {
  480. si_info_t *sii;
  481. sii = SI_INFO(sih);
  482. return sii->coreid[sii->curidx];
  483. }
  484. uint
  485. si_coreidx(si_t *sih)
  486. {
  487. si_info_t *sii;
  488. sii = SI_INFO(sih);
  489. return sii->curidx;
  490. }
  491. /* return the core-type instantiation # of the current core */
  492. uint
  493. si_coreunit(si_t *sih)
  494. {
  495. si_info_t *sii;
  496. uint idx;
  497. uint coreid;
  498. uint coreunit;
  499. uint i;
  500. sii = SI_INFO(sih);
  501. coreunit = 0;
  502. idx = sii->curidx;
  503. ASSERT(GOODREGS(sii->curmap));
  504. coreid = si_coreid(sih);
  505. /* count the cores of our type */
  506. for (i = 0; i < idx; i++)
  507. if (sii->coreid[i] == coreid)
  508. coreunit++;
  509. return (coreunit);
  510. }
  511. uint
  512. si_corevendor(si_t *sih)
  513. {
  514. if (CHIPTYPE(sih->socitype) == SOCI_SB)
  515. return sb_corevendor(sih);
  516. else if (CHIPTYPE(sih->socitype) == SOCI_AI)
  517. return ai_corevendor(sih);
  518. else if (CHIPTYPE(sih->socitype) == SOCI_UBUS)
  519. return ub_corevendor(sih);
  520. else {
  521. ASSERT(0);
  522. return 0;
  523. }
  524. }
  525. bool
  526. si_backplane64(si_t *sih)
  527. {
  528. return ((sih->cccaps & CC_CAP_BKPLN64) != 0);
  529. }
  530. uint
  531. si_corerev(si_t *sih)
  532. {
  533. if (CHIPTYPE(sih->socitype) == SOCI_SB)
  534. return sb_corerev(sih);
  535. else if (CHIPTYPE(sih->socitype) == SOCI_AI)
  536. return ai_corerev(sih);
  537. else if (CHIPTYPE(sih->socitype) == SOCI_UBUS)
  538. return ub_corerev(sih);
  539. else {
  540. ASSERT(0);
  541. return 0;
  542. }
  543. }
  544. /* return index of coreid or BADIDX if not found */
  545. uint
  546. si_findcoreidx(si_t *sih, uint coreid, uint coreunit)
  547. {
  548. si_info_t *sii;
  549. uint found;
  550. uint i;
  551. sii = SI_INFO(sih);
  552. found = 0;
  553. for (i = 0; i < sii->numcores; i++)
  554. if (sii->coreid[i] == coreid) {
  555. if (found == coreunit)
  556. return (i);
  557. found++;
  558. }
  559. return (BADIDX);
  560. }
  561. /* return list of found cores */
  562. uint
  563. si_corelist(si_t *sih, uint coreid[])
  564. {
  565. si_info_t *sii;
  566. sii = SI_INFO(sih);
  567. bcopy((uchar*)sii->coreid, (uchar*)coreid, (sii->numcores * sizeof(uint)));
  568. return (sii->numcores);
  569. }
  570. /* return current register mapping */
  571. void *
  572. si_coreregs(si_t *sih)
  573. {
  574. si_info_t *sii;
  575. sii = SI_INFO(sih);
  576. ASSERT(GOODREGS(sii->curmap));
  577. return (sii->curmap);
  578. }
  579. /*
  580. * This function changes logical "focus" to the indicated core;
  581. * must be called with interrupts off.
  582. * Moreover, callers should keep interrupts off during switching out of and back to d11 core
  583. */
  584. void *
  585. si_setcore(si_t *sih, uint coreid, uint coreunit)
  586. {
  587. uint idx;
  588. idx = si_findcoreidx(sih, coreid, coreunit);
  589. if (!GOODIDX(idx))
  590. return (NULL);
  591. if (CHIPTYPE(sih->socitype) == SOCI_SB)
  592. return sb_setcoreidx(sih, idx);
  593. else if (CHIPTYPE(sih->socitype) == SOCI_AI)
  594. return ai_setcoreidx(sih, idx);
  595. else if (CHIPTYPE(sih->socitype) == SOCI_UBUS)
  596. return ub_setcoreidx(sih, idx);
  597. else {
  598. ASSERT(0);
  599. return NULL;
  600. }
  601. }
  602. void *
  603. si_setcoreidx(si_t *sih, uint coreidx)
  604. {
  605. if (CHIPTYPE(sih->socitype) == SOCI_SB)
  606. return sb_setcoreidx(sih, coreidx);
  607. else if (CHIPTYPE(sih->socitype) == SOCI_AI)
  608. return ai_setcoreidx(sih, coreidx);
  609. else if (CHIPTYPE(sih->socitype) == SOCI_UBUS)
  610. return ub_setcoreidx(sih, coreidx);
  611. else {
  612. ASSERT(0);
  613. return NULL;
  614. }
  615. }
  616. /* Turn off interrupt as required by sb_setcore, before switch core */
  617. void *
  618. si_switch_core(si_t *sih, uint coreid, uint *origidx, uint *intr_val)
  619. {
  620. void *cc;
  621. si_info_t *sii;
  622. sii = SI_INFO(sih);
  623. if (SI_FAST(sii)) {
  624. /* Overloading the origidx variable to remember the coreid,
  625. * this works because the core ids cannot be confused with
  626. * core indices.
  627. */
  628. *origidx = coreid;
  629. if (coreid == CC_CORE_ID)
  630. return (void *)CCREGS_FAST(sii);
  631. else if (coreid == sih->buscoretype)
  632. return (void *)PCIEREGS(sii);
  633. }
  634. INTR_OFF(sii, *intr_val);
  635. *origidx = sii->curidx;
  636. cc = si_setcore(sih, coreid, 0);
  637. ASSERT(cc != NULL);
  638. return cc;
  639. }
  640. /* restore coreidx and restore interrupt */
  641. void
  642. si_restore_core(si_t *sih, uint coreid, uint intr_val)
  643. {
  644. si_info_t *sii;
  645. sii = SI_INFO(sih);
  646. if (SI_FAST(sii) && ((coreid == CC_CORE_ID) || (coreid == sih->buscoretype)))
  647. return;
  648. si_setcoreidx(sih, coreid);
  649. INTR_RESTORE(sii, intr_val);
  650. }
  651. int
  652. si_numaddrspaces(si_t *sih)
  653. {
  654. if (CHIPTYPE(sih->socitype) == SOCI_SB)
  655. return sb_numaddrspaces(sih);
  656. else if (CHIPTYPE(sih->socitype) == SOCI_AI)
  657. return ai_numaddrspaces(sih);
  658. else if (CHIPTYPE(sih->socitype) == SOCI_UBUS)
  659. return ub_numaddrspaces(sih);
  660. else {
  661. ASSERT(0);
  662. return 0;
  663. }
  664. }
  665. uint32
  666. si_addrspace(si_t *sih, uint asidx)
  667. {
  668. if (CHIPTYPE(sih->socitype) == SOCI_SB)
  669. return sb_addrspace(sih, asidx);
  670. else if (CHIPTYPE(sih->socitype) == SOCI_AI)
  671. return ai_addrspace(sih, asidx);
  672. else if (CHIPTYPE(sih->socitype) == SOCI_UBUS)
  673. return ub_addrspace(sih, asidx);
  674. else {
  675. ASSERT(0);
  676. return 0;
  677. }
  678. }
  679. uint32
  680. si_addrspacesize(si_t *sih, uint asidx)
  681. {
  682. if (CHIPTYPE(sih->socitype) == SOCI_SB)
  683. return sb_addrspacesize(sih, asidx);
  684. else if (CHIPTYPE(sih->socitype) == SOCI_AI)
  685. return ai_addrspacesize(sih, asidx);
  686. else if (CHIPTYPE(sih->socitype) == SOCI_UBUS)
  687. return ub_addrspacesize(sih, asidx);
  688. else {
  689. ASSERT(0);
  690. return 0;
  691. }
  692. }
  693. uint32
  694. si_core_cflags(si_t *sih, uint32 mask, uint32 val)
  695. {
  696. if (CHIPTYPE(sih->socitype) == SOCI_SB)
  697. return sb_core_cflags(sih, mask, val);
  698. else if (CHIPTYPE(sih->socitype) == SOCI_AI)
  699. return ai_core_cflags(sih, mask, val);
  700. else if (CHIPTYPE(sih->socitype) == SOCI_UBUS)
  701. return ub_core_cflags(sih, mask, val);
  702. else {
  703. ASSERT(0);
  704. return 0;
  705. }
  706. }
  707. void
  708. si_core_cflags_wo(si_t *sih, uint32 mask, uint32 val)
  709. {
  710. if (CHIPTYPE(sih->socitype) == SOCI_SB)
  711. sb_core_cflags_wo(sih, mask, val);
  712. else if (CHIPTYPE(sih->socitype) == SOCI_AI)
  713. ai_core_cflags_wo(sih, mask, val);
  714. else if (CHIPTYPE(sih->socitype) == SOCI_UBUS)
  715. ub_core_cflags_wo(sih, mask, val);
  716. else
  717. ASSERT(0);
  718. }
  719. uint32
  720. si_core_sflags(si_t *sih, uint32 mask, uint32 val)
  721. {
  722. if (CHIPTYPE(sih->socitype) == SOCI_SB)
  723. return sb_core_sflags(sih, mask, val);
  724. else if (CHIPTYPE(sih->socitype) == SOCI_AI)
  725. return ai_core_sflags(sih, mask, val);
  726. else if (CHIPTYPE(sih->socitype) == SOCI_UBUS)
  727. return ub_core_sflags(sih, mask, val);
  728. else {
  729. ASSERT(0);
  730. return 0;
  731. }
  732. }
  733. bool
  734. si_iscoreup(si_t *sih)
  735. {
  736. if (CHIPTYPE(sih->socitype) == SOCI_SB)
  737. return sb_iscoreup(sih);
  738. else if (CHIPTYPE(sih->socitype) == SOCI_AI)
  739. return ai_iscoreup(sih);
  740. else if (CHIPTYPE(sih->socitype) == SOCI_UBUS)
  741. return ub_iscoreup(sih);
  742. else {
  743. ASSERT(0);
  744. return FALSE;
  745. }
  746. }
  747. uint
  748. si_wrapperreg(si_t *sih, uint32 offset, uint32 mask, uint32 val)
  749. {
  750. /* only for AI back plane chips */
  751. if (CHIPTYPE(sih->socitype) == SOCI_AI)
  752. return (ai_wrap_reg(sih, offset, mask, val));
  753. return 0;
  754. }
  755. uint
  756. si_corereg(si_t *sih, uint coreidx, uint regoff, uint mask, uint val)
  757. {
  758. if (CHIPTYPE(sih->socitype) == SOCI_SB)
  759. return sb_corereg(sih, coreidx, regoff, mask, val);
  760. else if (CHIPTYPE(sih->socitype) == SOCI_AI)
  761. return ai_corereg(sih, coreidx, regoff, mask, val);
  762. else if (CHIPTYPE(sih->socitype) == SOCI_UBUS)
  763. return ub_corereg(sih, coreidx, regoff, mask, val);
  764. else {
  765. ASSERT(0);
  766. return 0;
  767. }
  768. }
  769. void
  770. si_core_disable(si_t *sih, uint32 bits)
  771. {
  772. if (CHIPTYPE(sih->socitype) == SOCI_SB)
  773. sb_core_disable(sih, bits);
  774. else if (CHIPTYPE(sih->socitype) == SOCI_AI)
  775. ai_core_disable(sih, bits);
  776. else if (CHIPTYPE(sih->socitype) == SOCI_UBUS)
  777. ub_core_disable(sih, bits);
  778. }
  779. void
  780. si_core_reset(si_t *sih, uint32 bits, uint32 resetbits)
  781. {
  782. if (CHIPTYPE(sih->socitype) == SOCI_SB)
  783. sb_core_reset(sih, bits, resetbits);
  784. else if (CHIPTYPE(sih->socitype) == SOCI_AI)
  785. ai_core_reset(sih, bits, resetbits);
  786. else if (CHIPTYPE(sih->socitype) == SOCI_UBUS)
  787. ub_core_reset(sih, bits, resetbits);
  788. }
  789. /* Run bist on current core. Caller needs to take care of core-specific bist hazards */
  790. int
  791. si_corebist(si_t *sih)
  792. {
  793. uint32 cflags;
  794. int result = 0;
  795. /* Read core control flags */
  796. cflags = si_core_cflags(sih, 0, 0);
  797. /* Set bist & fgc */
  798. si_core_cflags(sih, ~0, (SICF_BIST_EN | SICF_FGC));
  799. /* Wait for bist done */
  800. SPINWAIT(((si_core_sflags(sih, 0, 0) & SISF_BIST_DONE) == 0), 100000);
  801. if (si_core_sflags(sih, 0, 0) & SISF_BIST_ERROR)
  802. result = BCME_ERROR;
  803. /* Reset core control flags */
  804. si_core_cflags(sih, 0xffff, cflags);
  805. return result;
  806. }
  807. static uint32
  808. factor6(uint32 x)
  809. {
  810. switch (x) {
  811. case CC_F6_2: return 2;
  812. case CC_F6_3: return 3;
  813. case CC_F6_4: return 4;
  814. case CC_F6_5: return 5;
  815. case CC_F6_6: return 6;
  816. case CC_F6_7: return 7;
  817. default: return 0;
  818. }
  819. }
  820. /* calculate the speed the SI would run at given a set of clockcontrol values */
  821. uint32
  822. si_clock_rate(uint32 pll_type, uint32 n, uint32 m)
  823. {
  824. uint32 n1, n2, clock, m1, m2, m3, mc;
  825. n1 = n & CN_N1_MASK;
  826. n2 = (n & CN_N2_MASK) >> CN_N2_SHIFT;
  827. if (pll_type == PLL_TYPE6) {
  828. if (m & CC_T6_MMASK)
  829. return CC_T6_M1;
  830. else
  831. return CC_T6_M0;
  832. } else if ((pll_type == PLL_TYPE1) ||
  833. (pll_type == PLL_TYPE3) ||
  834. (pll_type == PLL_TYPE4) ||
  835. (pll_type == PLL_TYPE7)) {
  836. n1 = factor6(n1);
  837. n2 += CC_F5_BIAS;
  838. } else if (pll_type == PLL_TYPE2) {
  839. n1 += CC_T2_BIAS;
  840. n2 += CC_T2_BIAS;
  841. ASSERT((n1 >= 2) && (n1 <= 7));
  842. ASSERT((n2 >= 5) && (n2 <= 23));
  843. } else if (pll_type == PLL_TYPE5) {
  844. return (100000000);
  845. } else
  846. ASSERT(0);
  847. /* PLL types 3 and 7 use BASE2 (25Mhz) */
  848. if ((pll_type == PLL_TYPE3) ||
  849. (pll_type == PLL_TYPE7)) {
  850. clock = CC_CLOCK_BASE2 * n1 * n2;
  851. } else
  852. clock = CC_CLOCK_BASE1 * n1 * n2;
  853. if (clock == 0)
  854. return 0;
  855. m1 = m & CC_M1_MASK;
  856. m2 = (m & CC_M2_MASK) >> CC_M2_SHIFT;
  857. m3 = (m & CC_M3_MASK) >> CC_M3_SHIFT;
  858. mc = (m & CC_MC_MASK) >> CC_MC_SHIFT;
  859. if ((pll_type == PLL_TYPE1) ||
  860. (pll_type == PLL_TYPE3) ||
  861. (pll_type == PLL_TYPE4) ||
  862. (pll_type == PLL_TYPE7)) {
  863. m1 = factor6(m1);
  864. if ((pll_type == PLL_TYPE1) || (pll_type == PLL_TYPE3))
  865. m2 += CC_F5_BIAS;
  866. else
  867. m2 = factor6(m2);
  868. m3 = factor6(m3);
  869. switch (mc) {
  870. case CC_MC_BYPASS: return (clock);
  871. case CC_MC_M1: return (clock / m1);
  872. case CC_MC_M1M2: return (clock / (m1 * m2));
  873. case CC_MC_M1M2M3: return (clock / (m1 * m2 * m3));
  874. case CC_MC_M1M3: return (clock / (m1 * m3));
  875. default: return (0);
  876. }
  877. } else {
  878. ASSERT(pll_type == PLL_TYPE2);
  879. m1 += CC_T2_BIAS;
  880. m2 += CC_T2M2_BIAS;
  881. m3 += CC_T2_BIAS;
  882. ASSERT((m1 >= 2) && (m1 <= 7));
  883. ASSERT((m2 >= 3) && (m2 <= 10));
  884. ASSERT((m3 >= 2) && (m3 <= 7));
  885. if ((mc & CC_T2MC_M1BYP) == 0)
  886. clock /= m1;
  887. if ((mc & CC_T2MC_M2BYP) == 0)
  888. clock /= m2;
  889. if ((mc & CC_T2MC_M3BYP) == 0)
  890. clock /= m3;
  891. return (clock);
  892. }
  893. }
  894. /* set chip watchdog reset timer to fire in 'ticks' */
  895. void
  896. si_watchdog(si_t *sih, uint ticks)
  897. {
  898. uint nb, maxt;
  899. if (PMUCTL_ENAB(sih)) {
  900. if ((CHIPID(sih->chip) == BCM4319_CHIP_ID) &&
  901. (CHIPREV(sih->chiprev) == 0) && (ticks != 0)) {
  902. si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, clk_ctl_st), ~0, 0x2);
  903. si_setcore(sih, USB20D_CORE_ID, 0);
  904. si_core_disable(sih, 1);
  905. si_setcore(sih, CC_CORE_ID, 0);
  906. }
  907. nb = (sih->ccrev < 26) ? 16 : ((sih->ccrev >= 37) ? 32 : 24);
  908. /* The mips compiler uses the sllv instruction,
  909. * so we specially handle the 32-bit case.
  910. */
  911. if (nb == 32)
  912. maxt = 0xffffffff;
  913. else
  914. maxt = ((1 << nb) - 1);
  915. if (ticks == 1)
  916. ticks = 2;
  917. else if (ticks > maxt)
  918. ticks = maxt;
  919. si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, pmuwatchdog), ~0, ticks);
  920. } else {
  921. maxt = (1 << 28) - 1;
  922. if (ticks > maxt)
  923. ticks = maxt;
  924. si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, watchdog), ~0, ticks);
  925. }
  926. }
  927. /* trigger watchdog reset after ms milliseconds */
  928. void
  929. si_watchdog_ms(si_t *sih, uint32 ms)
  930. {
  931. si_watchdog(sih, wd_msticks * ms);
  932. }
  933. /* return the slow clock source - LPO, XTAL, or PCI */
  934. static uint
  935. si_slowclk_src(si_info_t *sii)
  936. {
  937. chipcregs_t *cc;
  938. ASSERT(SI_FAST(sii) || si_coreid(&sii->pub) == CC_CORE_ID);
  939. if (sii->pub.ccrev < 6) {
  940. if ((BUSTYPE(sii->pub.bustype) == PCI_BUS) &&
  941. (OSL_PCI_READ_CONFIG(sii->osh, PCI_GPIO_OUT, sizeof(uint32)) &
  942. PCI_CFG_GPIO_SCS))
  943. return (SCC_SS_PCI);
  944. else
  945. return (SCC_SS_XTAL);
  946. } else if (sii->pub.ccrev < 10) {
  947. cc = (chipcregs_t *)si_setcoreidx(&sii->pub, sii->curidx);
  948. return (R_REG(sii->osh, &cc->slow_clk_ctl) & SCC_SS_MASK);
  949. } else /* Insta-clock */
  950. return (SCC_SS_XTAL);
  951. }
  952. /* return the ILP (slowclock) min or max frequency */
  953. static uint
  954. si_slowclk_freq(si_info_t *sii, bool max_freq, chipcregs_t *cc)
  955. {
  956. uint32 slowclk;
  957. uint div;
  958. ASSERT(SI_FAST(sii) || si_coreid(&sii->pub) == CC_CORE_ID);
  959. /* shouldn't be here unless we've established the chip has dynamic clk control */
  960. ASSERT(R_REG(sii->osh, &cc->capabilities) & CC_CAP_PWR_CTL);
  961. slowclk = si_slowclk_src(sii);
  962. if (sii->pub.ccrev < 6) {
  963. if (slowclk == SCC_SS_PCI)
  964. return (max_freq ? (PCIMAXFREQ / 64) : (PCIMINFREQ / 64));
  965. else
  966. return (max_freq ? (XTALMAXFREQ / 32) : (XTALMINFREQ / 32));
  967. } else if (sii->pub.ccrev < 10) {
  968. div = 4 *
  969. (((R_REG(sii->osh, &cc->slow_clk_ctl) & SCC_CD_MASK) >> SCC_CD_SHIFT) + 1);
  970. if (slowclk == SCC_SS_LPO)
  971. return (max_freq ? LPOMAXFREQ : LPOMINFREQ);
  972. else if (slowclk == SCC_SS_XTAL)
  973. return (max_freq ? (XTALMAXFREQ / div) : (XTALMINFREQ / div));
  974. else if (slowclk == SCC_SS_PCI)
  975. return (max_freq ? (PCIMAXFREQ / div) : (PCIMINFREQ / div));
  976. else
  977. ASSERT(0);
  978. } else {
  979. /* Chipc rev 10 is InstaClock */
  980. div = R_REG(sii->osh, &cc->system_clk_ctl) >> SYCC_CD_SHIFT;
  981. div = 4 * (div + 1);
  982. return (max_freq ? XTALMAXFREQ : (XTALMINFREQ / div));
  983. }
  984. return (0);
  985. }
  986. static void
  987. si_clkctl_setdelay(si_info_t *sii, void *chipcregs)
  988. {
  989. chipcregs_t *cc = (chipcregs_t *)chipcregs;
  990. uint slowmaxfreq, pll_delay, slowclk;
  991. uint pll_on_delay, fref_sel_delay;
  992. pll_delay = PLL_DELAY;
  993. /* If the slow clock is not sourced by the xtal then add the xtal_on_delay
  994. * since the xtal will also be powered down by dynamic clk control logic.
  995. */
  996. slowclk = si_slowclk_src(sii);
  997. if (slowclk != SCC_SS_XTAL)
  998. pll_delay += XTAL_ON_DELAY;
  999. /* Starting with 4318 it is ILP that is used for the delays */
  1000. slowmaxfreq = si_slowclk_freq(sii, (sii->pub.ccrev >= 10) ? FALSE : TRUE, cc);
  1001. pll_on_delay = ((slowmaxfreq * pll_delay) + 999999) / 1000000;
  1002. fref_sel_delay = ((slowmaxfreq * FREF_DELAY) + 999999) / 1000000;
  1003. W_REG(sii->osh, &cc->pll_on_delay, pll_on_delay);
  1004. W_REG(sii->osh, &cc->fref_sel_delay, fref_sel_delay);
  1005. }
  1006. /* initialize power control delay registers */
  1007. void
  1008. si_clkctl_init(si_t *sih)
  1009. {
  1010. si_info_t *sii;
  1011. uint origidx = 0;
  1012. chipcregs_t *cc;
  1013. bool fast;
  1014. if (!CCCTL_ENAB(sih))
  1015. return;
  1016. sii = SI_INFO(sih);
  1017. fast = SI_FAST(sii);
  1018. if (!fast) {
  1019. origidx = sii->curidx;
  1020. if ((cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0)) == NULL)
  1021. return;
  1022. } else if ((cc = (chipcregs_t *)CCREGS_FAST(sii)) == NULL)
  1023. return;
  1024. ASSERT(cc != NULL);
  1025. /* set all Instaclk chip ILP to 1 MHz */
  1026. if (sih->ccrev >= 10)
  1027. SET_REG(sii->osh, &cc->system_clk_ctl, SYCC_CD_MASK,
  1028. (ILP_DIV_1MHZ << SYCC_CD_SHIFT));
  1029. si_clkctl_setdelay(sii, (void *)(uintptr)cc);
  1030. if (!fast)
  1031. si_setcoreidx(sih, origidx);
  1032. }
  1033. /* change logical "focus" to the gpio core for optimized access */
  1034. void *
  1035. si_gpiosetcore(si_t *sih)
  1036. {
  1037. return (si_setcoreidx(sih, SI_CC_IDX));
  1038. }
  1039. /* mask&set gpiocontrol bits */
  1040. uint32
  1041. si_gpiocontrol(si_t *sih, uint32 mask, uint32 val, uint8 priority)
  1042. {
  1043. uint regoff;
  1044. regoff = 0;
  1045. /* gpios could be shared on router platforms
  1046. * ignore reservation if it's high priority (e.g., test apps)
  1047. */
  1048. if ((priority != GPIO_HI_PRIORITY) &&
  1049. (BUSTYPE(sih->bustype) == SI_BUS) && (val || mask)) {
  1050. mask = priority ? (si_gpioreservation & mask) :
  1051. ((si_gpioreservation | mask) & ~(si_gpioreservation));
  1052. val &= mask;
  1053. }
  1054. regoff = OFFSETOF(chipcregs_t, gpiocontrol);
  1055. return (si_corereg(sih, SI_CC_IDX, regoff, mask, val));
  1056. }
  1057. /* mask&set gpio output enable bits */
  1058. uint32
  1059. si_gpioouten(si_t *sih, uint32 mask, uint32 val, uint8 priority)
  1060. {
  1061. uint regoff;
  1062. regoff = 0;
  1063. /* gpios could be shared on router platforms
  1064. * ignore reservation if it's high priority (e.g., test apps)
  1065. */
  1066. if ((priority != GPIO_HI_PRIORITY) &&
  1067. (BUSTYPE(sih->bustype) == SI_BUS) && (val || mask)) {
  1068. mask = priority ? (si_gpioreservation & mask) :
  1069. ((si_gpioreservation | mask) & ~(si_gpioreservation));
  1070. val &= mask;
  1071. }
  1072. regoff = OFFSETOF(chipcregs_t, gpioouten);
  1073. return (si_corereg(sih, SI_CC_IDX, regoff, mask, val));
  1074. }
  1075. /* mask&set gpio output bits */
  1076. uint32
  1077. si_gpioout(si_t *sih, uint32 mask, uint32 val, uint8 priority)
  1078. {
  1079. uint regoff;
  1080. regoff = 0;
  1081. /* gpios could be shared on router platforms
  1082. * ignore reservation if it's high priority (e.g., test apps)
  1083. */
  1084. if ((priority != GPIO_HI_PRIORITY) &&
  1085. (BUSTYPE(sih->bustype) == SI_BUS) && (val || mask)) {
  1086. mask = priority ? (si_gpioreservation & mask) :
  1087. ((si_gpioreservation | mask) & ~(si_gpioreservation));
  1088. val &= mask;
  1089. }
  1090. regoff = OFFSETOF(chipcregs_t, gpioout);
  1091. return (si_corereg(sih, SI_CC_IDX, regoff, mask, val));
  1092. }
  1093. /* reserve one gpio */
  1094. uint32
  1095. si_gpioreserve(si_t *sih, uint32 gpio_bitmask, uint8 priority)
  1096. {
  1097. si_info_t *sii;
  1098. sii = SI_INFO(sih);
  1099. /* only cores on SI_BUS share GPIO's and only applcation users need to
  1100. * reserve/release GPIO
  1101. */
  1102. if ((BUSTYPE(sih->bustype) != SI_BUS) || (!priority)) {
  1103. ASSERT((BUSTYPE(sih->bustype) == SI_BUS) && (priority));
  1104. return 0xffffffff;
  1105. }
  1106. /* make sure only one bit is set */
  1107. if ((!gpio_bitmask) || ((gpio_bitmask) & (gpio_bitmask - 1))) {
  1108. ASSERT((gpio_bitmask) && !((gpio_bitmask) & (gpio_bitmask - 1)));
  1109. return 0xffffffff;
  1110. }
  1111. /* already reserved */
  1112. if (si_gpioreservation & gpio_bitmask)
  1113. return 0xffffffff;
  1114. /* set reservation */
  1115. si_gpioreservation |= gpio_bitmask;
  1116. return si_gpioreservation;
  1117. }
  1118. /* release one gpio */
  1119. /*
  1120. * releasing the gpio doesn't change the current value on the GPIO last write value
  1121. * persists till some one overwrites it
  1122. */
  1123. uint32
  1124. si_gpiorelease(si_t *sih, uint32 gpio_bitmask, uint8 priority)
  1125. {
  1126. si_info_t *sii;
  1127. sii = SI_INFO(sih);
  1128. /* only cores on SI_BUS share GPIO's and only applcation users need to
  1129. * reserve/release GPIO
  1130. */
  1131. if ((BUSTYPE(sih->bustype) != SI_BUS) || (!priority)) {
  1132. ASSERT((BUSTYPE(sih->bustype) == SI_BUS) && (priority));
  1133. return 0xffffffff;
  1134. }
  1135. /* make sure only one bit is set */
  1136. if ((!gpio_bitmask) || ((gpio_bitmask) & (gpio_bitmask - 1))) {
  1137. ASSERT((gpio_bitmask) && !((gpio_bitmask) & (gpio_bitmask - 1)));
  1138. return 0xffffffff;
  1139. }
  1140. /* already released */
  1141. if (!(si_gpioreservation & gpio_bitmask))
  1142. return 0xffffffff;
  1143. /* clear reservation */
  1144. si_gpioreservation &= ~gpio_bitmask;
  1145. return si_gpioreservation;
  1146. }
  1147. /* return the current gpioin register value */
  1148. uint32
  1149. si_gpioin(si_t *sih)
  1150. {
  1151. si_info_t *sii;
  1152. uint regoff;
  1153. sii = SI_INFO(sih);
  1154. regoff = 0;
  1155. regoff = OFFSETOF(chipcregs_t, gpioin);
  1156. return (si_corereg(sih, SI_CC_IDX, regoff, 0, 0));
  1157. }
  1158. /* mask&set gpio interrupt polarity bits */
  1159. uint32
  1160. si_gpiointpolarity(si_t *sih, uint32 mask, uint32 val, uint8 priority)
  1161. {
  1162. si_info_t *sii;
  1163. uint regoff;
  1164. sii = SI_INFO(sih);
  1165. regoff = 0;
  1166. /* gpios could be shared on router platforms */
  1167. if ((BUSTYPE(sih->bustype) == SI_BUS) && (val || mask)) {
  1168. mask = priority ? (si_gpioreservation & mask) :
  1169. ((si_gpioreservation | mask) & ~(si_gpioreservation));
  1170. val &= mask;
  1171. }
  1172. regoff = OFFSETOF(chipcregs_t, gpiointpolarity);
  1173. return (si_corereg(sih, SI_CC_IDX, regoff, mask, val));
  1174. }
  1175. /* mask&set gpio interrupt mask bits */
  1176. uint32
  1177. si_gpiointmask(si_t *sih, uint32 mask, uint32 val, uint8 priority)
  1178. {
  1179. si_info_t *sii;
  1180. uint regoff;
  1181. sii = SI_INFO(sih);
  1182. regoff = 0;
  1183. /* gpios could be shared on router platforms */
  1184. if ((BUSTYPE(sih->bustype) == SI_BUS) && (val || mask)) {
  1185. mask = priority ? (si_gpioreservation & mask) :
  1186. ((si_gpioreservation | mask) & ~(si_gpioreservation));
  1187. val &= mask;
  1188. }
  1189. regoff = OFFSETOF(chipcregs_t, gpiointmask);
  1190. return (si_corereg(sih, SI_CC_IDX, regoff, mask, val));
  1191. }
  1192. /* assign the gpio to an led */
  1193. uint32
  1194. si_gpioled(si_t *sih, uint32 mask, uint32 val)
  1195. {
  1196. si_info_t *sii;
  1197. sii = SI_INFO(sih);
  1198. if (sih->ccrev < 16)
  1199. return 0xffffffff;
  1200. /* gpio led powersave reg */
  1201. return (si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, gpiotimeroutmask), mask, val));
  1202. }
  1203. /* mask&set gpio timer val */
  1204. uint32
  1205. si_gpiotimerval(si_t *sih, uint32 mask, uint32 gpiotimerval)
  1206. {
  1207. si_info_t *sii;
  1208. sii = SI_INFO(sih);
  1209. if (sih->ccrev < 16)
  1210. return 0xffffffff;
  1211. return (si_corereg(sih, SI_CC_IDX,
  1212. OFFSETOF(chipcregs_t, gpiotimerval), mask, gpiotimerval));
  1213. }
  1214. uint32
  1215. si_gpiopull(si_t *sih, bool updown, uint32 mask, uint32 val)
  1216. {
  1217. si_info_t *sii;
  1218. uint offs;
  1219. sii = SI_INFO(sih);
  1220. if (sih->ccrev < 20)
  1221. return 0xffffffff;
  1222. offs = (updown ? OFFSETOF(chipcregs_t, gpiopulldown) : OFFSETOF(chipcregs_t, gpiopullup));
  1223. return (si_corereg(sih, SI_CC_IDX, offs, mask, val));
  1224. }
  1225. uint32
  1226. si_gpioevent(si_t *sih, uint regtype, uint32 mask, uint32 val)
  1227. {
  1228. si_info_t *sii;
  1229. uint offs;
  1230. sii = SI_INFO(sih);
  1231. if (sih->ccrev < 11)
  1232. return 0xffffffff;
  1233. if (regtype == GPIO_REGEVT)
  1234. offs = OFFSETOF(chipcregs_t, gpioevent);
  1235. else if (regtype == GPIO_REGEVT_INTMSK)
  1236. offs = OFFSETOF(chipcregs_t, gpioeventintmask);
  1237. else if (regtype == GPIO_REGEVT_INTPOL)
  1238. offs = OFFSETOF(chipcregs_t, gpioeventintpolarity);
  1239. else
  1240. return 0xffffffff;
  1241. return (si_corereg(sih, SI_CC_IDX, offs, mask, val));
  1242. }
  1243. void *
  1244. si_gpio_handler_register(si_t *sih, uint32 event,
  1245. bool level, gpio_handler_t cb, void *arg)
  1246. {
  1247. si_info_t *sii;
  1248. gpioh_item_t *gi;
  1249. ASSERT(event);
  1250. ASSERT(cb != NULL);
  1251. sii = SI_INFO(sih);
  1252. if (sih->ccrev < 11)
  1253. return NULL;
  1254. if ((gi = MALLOC(sii->osh, sizeof(gpioh_item_t))) == NULL)
  1255. return NULL;
  1256. bzero(gi, sizeof(gpioh_item_t));
  1257. gi->event = event;
  1258. gi->handler = cb;
  1259. gi->arg = arg;
  1260. gi->level = level;
  1261. gi->next = sii->gpioh_head;
  1262. sii->gpioh_head = gi;
  1263. return (void *)(gi);
  1264. }
  1265. void
  1266. si_gpio_handler_unregister(si_t *sih, void *gpioh)
  1267. {
  1268. si_info_t *sii;
  1269. gpioh_item_t *p, *n;
  1270. sii = SI_INFO(sih);
  1271. if (sih->ccrev < 11)
  1272. return;
  1273. ASSERT(sii->gpioh_head != NULL);
  1274. if ((void*)sii->gpioh_head == gpioh) {
  1275. sii->gpioh_head = sii->gpioh_head->next;
  1276. MFREE(sii->osh, gpioh, sizeof(gpioh_item_t));
  1277. return;
  1278. } else {
  1279. p = sii->gpioh_head;
  1280. n = p->next;
  1281. while (n) {
  1282. if ((void*)n == gpioh) {
  1283. p->next = n->next;
  1284. MFREE(sii->osh, gpioh, sizeof(gpioh_item_t));
  1285. return;
  1286. }
  1287. p = n;
  1288. n = n->next;
  1289. }
  1290. }
  1291. ASSERT(0); /* Not found in list */
  1292. }
  1293. void
  1294. si_gpio_handler_process(si_t *sih)
  1295. {
  1296. si_info_t *sii;
  1297. gpioh_item_t *h;
  1298. uint32 level = si_gpioin(sih);
  1299. uint32 levelp = si_gpiointpolarity(sih, 0, 0, 0);
  1300. uint32 edge = si_gpioevent(sih, GPIO_REGEVT, 0, 0);
  1301. uint32 edgep = si_gpioevent(sih, GPIO_REGEVT_INTPOL, 0, 0);
  1302. sii = SI_INFO(sih);
  1303. for (h = sii->gpioh_head; h != NULL; h = h->next) {
  1304. if (h->handler) {
  1305. uint32 status = (h->level ? level : edge) & h->event;
  1306. uint32 polarity = (h->level ? levelp : edgep) & h->event;
  1307. /* polarity bitval is opposite of status bitval */
  1308. if (status ^ polarity)
  1309. h->handler(status, h->arg);
  1310. }
  1311. }
  1312. si_gpioevent(sih, GPIO_REGEVT, edge, edge); /* clear edge-trigger status */
  1313. }
  1314. uint32
  1315. si_gpio_int_enable(si_t *sih, bool enable)
  1316. {
  1317. si_info_t *sii;
  1318. uint offs;
  1319. sii = SI_INFO(sih);
  1320. if (sih->ccrev < 11)
  1321. return 0xffffffff;
  1322. offs = OFFSETOF(chipcregs_t, intmask);
  1323. return (si_corereg(sih, SI_CC_IDX, offs, CI_GPIO, (enable ? CI_GPIO : 0)));
  1324. }
  1325. /* Return the size of the specified SOCRAM bank */
  1326. static uint
  1327. socram_banksize(si_info_t *sii, sbsocramregs_t *regs, uint8 index, uint8 mem_type)
  1328. {
  1329. uint banksize, bankinfo;
  1330. uint bankidx = index | (mem_type << SOCRAM_BANKIDX_MEMTYPE_SHIFT);
  1331. ASSERT(mem_type <= SOCRAM_MEMTYPE_DEVRAM);
  1332. W_REG(sii->osh, &regs->bankidx, bankidx);
  1333. bankinfo = R_REG(sii->osh, &regs->bankinfo);
  1334. banksize = SOCRAM_BANKINFO_SZBASE * ((bankinfo & SOCRAM_BANKINFO_SZMASK) + 1);
  1335. return banksize;
  1336. }
  1337. void
  1338. si_socdevram(si_t *sih, bool set, uint8 *enable, uint8 *protect)
  1339. {
  1340. si_info_t *sii;
  1341. uint origidx;
  1342. uint intr_val = 0;
  1343. sbsocramregs_t *regs;
  1344. bool wasup;
  1345. uint corerev;
  1346. sii = SI_INFO(sih);
  1347. /* Block ints and save current core */
  1348. INTR_OFF(sii, intr_val);
  1349. origidx = si_coreidx(sih);
  1350. if (!set)
  1351. *enable = *protect = 0;
  1352. /* Switch to SOCRAM core */
  1353. if (!(regs = si_setcore(sih, SOCRAM_CORE_ID, 0)))
  1354. goto done;
  1355. /* Get info for determining size */
  1356. if (!(wasup = si_iscoreup(sih)))
  1357. si_core_reset(sih, 0, 0);
  1358. corerev = si_corerev(sih);
  1359. if (corerev >= 10) {
  1360. uint32 extcinfo;
  1361. uint8 nb;
  1362. uint8 i;
  1363. uint32 bankidx, bankinfo;
  1364. extcinfo = R_REG(sii->osh, &regs->extracoreinfo);
  1365. nb = ((extcinfo & SOCRAM_DEVRAMBANK_MASK) >> SOCRAM_DEVRAMBANK_SHIFT);
  1366. for (i = 0; i < nb; i++) {
  1367. bankidx = i | (SOCRAM_MEMTYPE_DEVRAM << SOCRAM_BANKIDX_MEMTYPE_SHIFT);
  1368. W_REG(sii->osh, &regs->bankidx, bankidx);
  1369. bankinfo = R_REG(sii->osh, &regs->bankinfo);
  1370. if (set) {
  1371. bankinfo &= ~SOCRAM_BANKINFO_DEVRAMSEL_MASK;
  1372. bankinfo &= ~SOCRAM_BANKINFO_DEVRAMPRO_MASK;
  1373. if (*enable) {
  1374. bankinfo |= (1 << SOCRAM_BANKINFO_DEVRAMSEL_SHIFT);
  1375. if (*protect)
  1376. bankinfo |= (1 << SOCRAM_BANKINFO_DEVRAMPRO_SHIFT);
  1377. }
  1378. W_REG(sii->osh, &regs->bankinfo, bankinfo);
  1379. }
  1380. else if (i == 0) {
  1381. if (bankinfo & SOCRAM_BANKINFO_DEVRAMSEL_MASK) {
  1382. *enable = 1;
  1383. if (bankinfo & SOCRAM_BANKINFO_DEVRAMPRO_MASK)
  1384. *protect = 1;
  1385. }
  1386. }
  1387. }
  1388. }
  1389. /* Return to previous state and core */
  1390. if (!wasup)
  1391. si_core_disable(sih, 0);
  1392. si_setcoreidx(sih, origidx);
  1393. done:
  1394. INTR_RESTORE(sii, intr_val);
  1395. }
  1396. bool
  1397. si_socdevram_pkg(si_t *sih)
  1398. {
  1399. if (si_socdevram_size(sih) > 0)
  1400. return TRUE;
  1401. else
  1402. return FALSE;
  1403. }
  1404. uint32
  1405. si_socdevram_size(si_t *sih)
  1406. {
  1407. si_info_t *sii;
  1408. uint origidx;
  1409. uint intr_val = 0;
  1410. uint32 memsize = 0;
  1411. sbsocramregs_t *regs;
  1412. bool wasup;
  1413. uint corerev;
  1414. sii = SI_INFO(sih);
  1415. /* Block ints and save current core */
  1416. INTR_OFF(sii, intr_val);
  1417. origidx = si_coreidx(sih);
  1418. /* Switch to SOCRAM core */
  1419. if (!(regs = si_setcore(sih, SOCRAM_CORE_ID, 0)))
  1420. goto done;
  1421. /* Get info for determining size */
  1422. if (!(wasup = si_iscoreup(sih)))
  1423. si_core_reset(sih, 0, 0);
  1424. corerev = si_corerev(sih);
  1425. if (corerev >= 10) {
  1426. uint32 extcinfo;
  1427. uint8 nb;
  1428. uint8 i;
  1429. extcinfo = R_REG(sii->osh, &regs->extracoreinfo);
  1430. nb = (((extcinfo & SOCRAM_DEVRAMBANK_MASK) >> SOCRAM_DEVRAMBANK_SHIFT));
  1431. for (i = 0; i < nb; i++)
  1432. memsize += socram_banksize(sii, regs, i, SOCRAM_MEMTYPE_DEVRAM);
  1433. }
  1434. /* Return to previous state and core */
  1435. if (!wasup)
  1436. si_core_disable(sih, 0);
  1437. si_setcoreidx(sih, origidx);
  1438. done:
  1439. INTR_RESTORE(sii, intr_val);
  1440. return memsize;
  1441. }
  1442. /* Return the RAM size of the SOCRAM core */
  1443. uint32
  1444. si_socram_size(si_t *sih)
  1445. {
  1446. si_info_t *sii;
  1447. uint origidx;
  1448. uint intr_val = 0;
  1449. sbsocramregs_t *regs;
  1450. bool wasup;
  1451. uint corerev;
  1452. uint32 coreinfo;
  1453. uint memsize = 0;
  1454. sii = SI_INFO(sih);
  1455. /* Block ints and save current core */
  1456. INTR_OFF(sii, intr_val);
  1457. origidx = si_coreidx(sih);
  1458. /* Switch to SOCRAM core */
  1459. if (!(regs = si_setcore(sih, SOCRAM_CORE_ID, 0)))
  1460. goto done;
  1461. /* Get info for determining size */
  1462. if (!(wasup = si_iscoreup(sih)))
  1463. si_core_reset(sih, 0, 0);
  1464. corerev = si_corerev(sih);
  1465. coreinfo = R_REG(sii->osh, &regs->coreinfo);
  1466. /* Calculate size from coreinfo based on rev */
  1467. if (corerev == 0)
  1468. memsize = 1 << (16 + (coreinfo & SRCI_MS0_MASK));
  1469. else if (corerev < 3) {
  1470. memsize = 1 << (SR_BSZ_BASE + (coreinfo & SRCI_SRBSZ_MASK));
  1471. memsize *= (coreinfo & SRCI_SRNB_MASK) >> SRCI_SRNB_SHIFT;
  1472. } else if ((corerev <= 7) || (corerev == 12)) {
  1473. uint nb = (coreinfo & SRCI_SRNB_MASK) >> SRCI_SRNB_SHIFT;
  1474. uint bsz = (coreinfo & SRCI_SRBSZ_MASK);
  1475. uint lss = (coreinfo & SRCI_LSS_MASK) >> SRCI_LSS_SHIFT;
  1476. if (lss != 0)
  1477. nb --;
  1478. memsize = nb * (1 << (bsz + SR_BSZ_BASE));
  1479. if (lss != 0)
  1480. memsize += (1 << ((lss - 1) + SR_BSZ_BASE));
  1481. } else {
  1482. uint8 i;
  1483. uint nb = (coreinfo & SRCI_SRNB_MASK) >> SRCI_SRNB_SHIFT;
  1484. for (i = 0; i < nb; i++)
  1485. memsize += socram_banksize(sii, regs, i, SOCRAM_MEMTYPE_RAM);
  1486. }
  1487. /* Return to previous state and core */
  1488. if (!wasup)
  1489. si_core_disable(sih, 0);
  1490. si_setcoreidx(sih, origidx);
  1491. done:
  1492. INTR_RESTORE(sii, intr_val);
  1493. return memsize;
  1494. }
  1495. void
  1496. si_btcgpiowar(si_t *sih)
  1497. {
  1498. si_info_t *sii;
  1499. uint origidx;
  1500. uint intr_val = 0;
  1501. chipcregs_t *cc;
  1502. sii = SI_INFO(sih);
  1503. /* Make sure that there is ChipCommon core present &&
  1504. * UART_TX is strapped to 1
  1505. */
  1506. if (!(sih->cccaps & CC_CAP_UARTGPIO))
  1507. return;
  1508. /* si_corereg cannot be used as we have to guarantee 8-bit read/writes */
  1509. INTR_OFF(sii, intr_val);
  1510. origidx = si_coreidx(sih);
  1511. cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0);
  1512. ASSERT(cc != NULL);
  1513. W_REG(sii->osh, &cc->uart0mcr, R_REG(sii->osh, &cc->uart0mcr) | 0x04);
  1514. /* restore the original index */
  1515. si_setcoreidx(sih, origidx);
  1516. INTR_RESTORE(sii, intr_val);
  1517. }
  1518. uint
  1519. si_pll_reset(si_t *sih)
  1520. {
  1521. uint err = 0;
  1522. return (err);
  1523. }
  1524. /* check if the device is removed */
  1525. bool
  1526. si_deviceremoved(si_t *sih)
  1527. {
  1528. uint32 w;
  1529. si_info_t *sii;
  1530. sii = SI_INFO(sih);
  1531. switch (BUSTYPE(sih->bustype)) {
  1532. case PCI_BUS:
  1533. ASSERT(sii->osh != NULL);
  1534. w = OSL_PCI_READ_CONFIG(sii->osh, PCI_CFG_VID, sizeof(uint32));
  1535. if ((w & 0xFFFF) != VENDOR_BROADCOM)
  1536. return TRUE;
  1537. break;
  1538. }
  1539. return FALSE;
  1540. }
  1541. bool
  1542. si_is_sprom_available(si_t *sih)
  1543. {
  1544. if (sih->ccrev >= 31) {
  1545. si_info_t *sii;
  1546. uint origidx;
  1547. chipcregs_t *cc;
  1548. uint32 sromctrl;
  1549. if ((sih->cccaps & CC_CAP_SROM) == 0)
  1550. return FALSE;
  1551. sii = SI_INFO(sih);
  1552. origidx = sii->curidx;
  1553. cc = si_setcoreidx(sih, SI_CC_IDX);
  1554. sromctrl = R_REG(sii->osh, &cc->sromcontrol);
  1555. si_setcoreidx(sih, origidx);
  1556. return (sromctrl & SRC_PRESENT);
  1557. }
  1558. switch (CHIPID(sih->chip)) {
  1559. case BCM4312_CHIP_ID:
  1560. return ((sih->chipst & CST4312_SPROM_OTP_SEL_MASK) != CST4312_OTP_SEL);
  1561. case BCM4325_CHIP_ID:
  1562. return (sih->chipst & CST4325_SPROM_SEL) != 0;
  1563. case BCM4322_CHIP_ID:
  1564. case BCM43221_CHIP_ID:
  1565. case BCM43231_CHIP_ID:
  1566. case BCM43222_CHIP_ID:
  1567. case BCM43111_CHIP_ID:
  1568. case BCM43112_CHIP_ID:
  1569. case BCM4342_CHIP_ID:
  1570. {
  1571. uint32 spromotp;
  1572. spromotp = (sih->chipst & CST4322_SPROM_OTP_SEL_MASK) >>
  1573. CST4322_SPROM_OTP_SEL_SHIFT;
  1574. return (spromotp & CST4322_SPROM_PRESENT) != 0;
  1575. }
  1576. case BCM4329_CHIP_ID:
  1577. return (sih->chipst & CST4329_SPROM_SEL) != 0;
  1578. case BCM4315_CHIP_ID:
  1579. return (sih->chipst & CST4315_SPROM_SEL) != 0;
  1580. case BCM4319_CHIP_ID:
  1581. return (sih->chipst & CST4319_SPROM_SEL) != 0;
  1582. case BCM4336_CHIP_ID:
  1583. case BCM43362_CHIP_ID:
  1584. return (sih->chipst & CST4336_SPROM_PRESENT) != 0;
  1585. case BCM4330_CHIP_ID:
  1586. return (sih->chipst & CST4330_SPROM_PRESENT) != 0;
  1587. case BCM4313_CHIP_ID:
  1588. return (sih->chipst & CST4313_SPROM_PRESENT) != 0;
  1589. case BCM43239_CHIP_ID:
  1590. return ((sih->chipst & CST43239_SPROM_MASK) &&
  1591. !(sih->chipst & CST43239_SFLASH_MASK));
  1592. default:
  1593. return TRUE;
  1594. }
  1595. }