2 * Copyright (c) 2010 Broadcom Corporation
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20 #include <linux/kernel.h>
21 #include <linux/string.h>
29 #include <pcie_core.h>
40 #include <sbsdpcmdev.h>
45 /* this file now contains only definitions for sb functions, only necessary
46 *for devices using Sonics backplanes (bcm4329)
49 /* if an amba SDIO device is supported, please further restrict the inclusion
53 #include "siutils_priv.h"
56 /* local prototypes */
57 static si_info_t
*si_doattach(si_info_t
*sii
, uint devid
, osl_t
*osh
,
58 void *regs
, uint bustype
, void *sdh
, char **vars
,
60 static bool si_buscore_prep(si_info_t
*sii
, uint bustype
, uint devid
,
62 static bool si_buscore_setup(si_info_t
*sii
, chipcregs_t
*cc
, uint bustype
,
63 uint32 savewin
, uint
*origidx
, void *regs
);
64 static void si_nvram_process(si_info_t
*sii
, char *pvars
);
66 /* dev path concatenation util */
67 static char *si_devpathvar(si_t
*sih
, char *var
, int len
, const char *name
);
68 static bool _si_clkctl_cc(si_info_t
*sii
, uint mode
);
69 static bool si_ispcie(si_info_t
*sii
);
70 static uint
BCMINITFN(socram_banksize
) (si_info_t
*sii
, sbsocramregs_t
*r
,
73 /* global variable to indicate reservation/release of gpio's */
74 static uint32 si_gpioreservation
;
76 /* global flag to prevent shared resources from being initialized multiple times in si_attach() */
79 * Allocate a si handle.
80 * devid - pci device id (used to determine chip#)
81 * osh - opaque OS handle
82 * regs - virtual address of initial core registers
83 * bustype - pci/sb/sdio/etc
84 * vars - pointer to a pointer area for "environment" variables
85 * varsz - pointer to int to return the size of the vars
87 si_t
*BCMATTACHFN(si_attach
) (uint devid
, osl_t
*osh
, void *regs
,
88 uint bustype
, void *sdh
, char **vars
,
93 sii
= MALLOC(osh
, sizeof(si_info_t
));
95 SI_ERROR(("si_attach: malloc failed! malloced %d bytes\n",
100 if (si_doattach(sii
, devid
, osh
, regs
, bustype
, sdh
, vars
, varsz
) ==
102 MFREE(osh
, sii
, sizeof(si_info_t
));
105 sii
->vars
= vars
? *vars
: NULL
;
106 sii
->varsz
= varsz
? *varsz
: 0;
111 /* global kernel resource */
112 static si_info_t ksii
;
114 static uint32 wd_msticks
; /* watchdog timer ticks normalized to ms */
117 BCMATTACHFN(si_buscore_prep
) (si_info_t
*sii
, uint bustype
, uint devid
,
121 /* kludge to enable the clock on the 4306 which lacks a slowclock */
122 if (BUSTYPE(bustype
) == PCI_BUS
&& !si_ispcie(sii
))
123 si_clkctl_xtal(&sii
->pub
, XTAL
| PLL
, ON
);
127 if (BUSTYPE(bustype
) == SDIO_BUS
) {
131 /* Try forcing SDIO core to do ALPAvail request only */
132 clkset
= SBSDIO_FORCE_HW_CLKREQ_OFF
| SBSDIO_ALP_AVAIL_REQ
;
133 bcmsdh_cfg_write(sdh
, SDIO_FUNC_1
, SBSDIO_FUNC1_CHIPCLKCSR
,
138 /* If register supported, wait for ALPAvail and then force ALP */
140 bcmsdh_cfg_read(sdh
, SDIO_FUNC_1
,
141 SBSDIO_FUNC1_CHIPCLKCSR
, NULL
);
142 if ((clkval
& ~SBSDIO_AVBITS
) == clkset
) {
144 bcmsdh_cfg_read(sdh
, SDIO_FUNC_1
,
145 SBSDIO_FUNC1_CHIPCLKCSR
,
147 !SBSDIO_ALPAV(clkval
)),
148 PMU_MAX_TRANSITION_DLY
);
149 if (!SBSDIO_ALPAV(clkval
)) {
150 SI_ERROR(("timeout on ALPAV wait, clkval 0x%02x\n", clkval
));
154 SBSDIO_FORCE_HW_CLKREQ_OFF
|
156 bcmsdh_cfg_write(sdh
, SDIO_FUNC_1
,
157 SBSDIO_FUNC1_CHIPCLKCSR
,
163 /* Also, disable the extra SDIO pull-ups */
164 bcmsdh_cfg_write(sdh
, SDIO_FUNC_1
, SBSDIO_FUNC1_SDIOPULLUP
, 0,
167 #endif /* defined(BCMSDIO) */
173 BCMATTACHFN(si_buscore_setup
) (si_info_t
*sii
, chipcregs_t
*cc
, uint bustype
,
174 uint32 savewin
, uint
*origidx
, void *regs
) {
177 uint pciidx
, pcieidx
, pcirev
, pcierev
;
179 cc
= si_setcoreidx(&sii
->pub
, SI_CC_IDX
);
180 ASSERT((uintptr
) cc
);
182 /* get chipcommon rev */
183 sii
->pub
.ccrev
= (int)si_corerev(&sii
->pub
);
185 /* get chipcommon chipstatus */
186 if (sii
->pub
.ccrev
>= 11)
187 sii
->pub
.chipst
= R_REG(sii
->osh
, &cc
->chipstatus
);
189 /* get chipcommon capabilites */
190 sii
->pub
.cccaps
= R_REG(sii
->osh
, &cc
->capabilities
);
191 /* get chipcommon extended capabilities */
194 if (sii
->pub
.ccrev
>= 35)
195 sii
->pub
.cccaps_ext
= R_REG(sii
->osh
, &cc
->capabilities_ext
);
197 /* get pmu rev and caps */
198 if (sii
->pub
.cccaps
& CC_CAP_PMU
) {
199 sii
->pub
.pmucaps
= R_REG(sii
->osh
, &cc
->pmucapabilities
);
200 sii
->pub
.pmurev
= sii
->pub
.pmucaps
& PCAP_REV_MASK
;
204 SI_MSG(("Chipc: rev %d, caps 0x%x, chipst 0x%x pmurev %d, pmucaps 0x%x\n",
205 sii->pub.ccrev, sii->pub.cccaps, sii->pub.chipst, sii->pub.pmurev,
209 /* figure out bus/orignal core idx */
210 sii
->pub
.buscoretype
= NODEV_CORE_ID
;
211 sii
->pub
.buscorerev
= NOREV
;
212 sii
->pub
.buscoreidx
= BADIDX
;
215 pcirev
= pcierev
= NOREV
;
216 pciidx
= pcieidx
= BADIDX
;
218 for (i
= 0; i
< sii
->numcores
; i
++) {
221 si_setcoreidx(&sii
->pub
, i
);
222 cid
= si_coreid(&sii
->pub
);
223 crev
= si_corerev(&sii
->pub
);
225 /* Display cores found */
226 SI_VMSG(("CORE[%d]: id 0x%x rev %d base 0x%x regs 0x%p\n",
227 i
, cid
, crev
, sii
->coresba
[i
], sii
->regs
[i
]));
229 if (BUSTYPE(bustype
) == PCI_BUS
) {
230 if (cid
== PCI_CORE_ID
) {
234 } else if (cid
== PCIE_CORE_ID
) {
241 else if (((BUSTYPE(bustype
) == SDIO_BUS
) ||
242 (BUSTYPE(bustype
) == SPI_BUS
)) &&
243 ((cid
== PCMCIA_CORE_ID
) || (cid
== SDIOD_CORE_ID
))) {
244 sii
->pub
.buscorerev
= crev
;
245 sii
->pub
.buscoretype
= cid
;
246 sii
->pub
.buscoreidx
= i
;
250 /* find the core idx before entering this func. */
251 if ((savewin
&& (savewin
== sii
->coresba
[i
])) ||
252 (regs
== sii
->regs
[i
]))
257 SI_MSG(("Buscore id/type/rev %d/0x%x/%d\n", sii
->pub
.buscoreidx
,
258 sii
->pub
.buscoretype
, sii
->pub
.buscorerev
));
260 /* Make sure any on-chip ARM is off (in case strapping is wrong),
261 * or downloaded code was
264 if ((BUSTYPE(bustype
) == SDIO_BUS
) || (BUSTYPE(bustype
) == SPI_BUS
)) {
265 if (si_setcore(&sii
->pub
, ARM7S_CORE_ID
, 0) ||
266 si_setcore(&sii
->pub
, ARMCM3_CORE_ID
, 0))
267 si_core_disable(&sii
->pub
, 0);
277 sii
->pub
.buscoretype
= PCI_CORE_ID
;
278 sii
->pub
.buscorerev
= pcirev
;
279 sii
->pub
.buscoreidx
= pciidx
;
281 sii
->pub
.buscoretype
= PCIE_CORE_ID
;
282 sii
->pub
.buscorerev
= pcierev
;
283 sii
->pub
.buscoreidx
= pcieidx
;
286 SI_VMSG(("Buscore id/type/rev %d/0x%x/%d\n", sii
->pub
.buscoreidx
,
287 sii
->pub
.buscoretype
, sii
->pub
.buscorerev
));
289 /* fixup necessary chip/core configurations */
290 if (BUSTYPE(sii
->pub
.bustype
) == PCI_BUS
) {
293 sii
->pch
= (void *)(uintptr
)pcicore_init(
295 (void *)PCIEREGS(sii
));
296 if (sii
->pch
== NULL
)
300 if (si_pci_fixcfg(&sii
->pub
)) {
301 SI_ERROR(("si_doattach: sb_pci_fixcfg failed\n"));
306 /* return to the original core */
307 si_setcoreidx(&sii
->pub
, *origidx
);
312 static __used
void BCMATTACHFN(si_nvram_process
) (si_info_t
*sii
, char *pvars
)
316 /* get boardtype and boardrev */
317 switch (BUSTYPE(sii
->pub
.bustype
)) {
319 /* do a pci config read to get subsystem id and subvendor id */
320 w
= OSL_PCI_READ_CONFIG(sii
->osh
, PCI_CFG_SVID
, sizeof(uint32
));
321 /* Let nvram variables override subsystem Vend/ID */
322 sii
->pub
.boardvendor
= (u16
)si_getdevpathintvar(&sii
->pub
,
324 if (sii
->pub
.boardvendor
== 0)
325 sii
->pub
.boardvendor
= w
& 0xffff;
327 SI_ERROR(("Overriding boardvendor: 0x%x instead of 0x%x\n", sii
->pub
.boardvendor
, w
& 0xffff));
328 sii
->pub
.boardtype
= (u16
)si_getdevpathintvar(&sii
->pub
,
330 if (sii
->pub
.boardtype
== 0)
331 sii
->pub
.boardtype
= (w
>> 16) & 0xffff;
333 SI_ERROR(("Overriding boardtype: 0x%x instead of 0x%x\n", sii
->pub
.boardtype
, (w
>> 16) & 0xffff));
339 sii
->pub
.boardvendor
= getintvar(pvars
, "manfid");
340 sii
->pub
.boardtype
= getintvar(pvars
, "prodid");
345 sii
->pub
.boardvendor
= VENDOR_BROADCOM
;
346 sii
->pub
.boardtype
= SPI_BOARD
;
352 sii
->pub
.boardvendor
= VENDOR_BROADCOM
;
353 sii
->pub
.boardtype
= getintvar(pvars
, "prodid");
354 if (pvars
== NULL
|| (sii
->pub
.boardtype
== 0)) {
355 sii
->pub
.boardtype
= getintvar(NULL
, "boardtype");
356 if (sii
->pub
.boardtype
== 0)
357 sii
->pub
.boardtype
= 0xffff;
362 if (sii
->pub
.boardtype
== 0) {
363 SI_ERROR(("si_doattach: unknown board type\n"));
364 ASSERT(sii
->pub
.boardtype
);
367 sii
->pub
.boardflags
= getintvar(pvars
, "boardflags");
370 /* this is will make Sonics calls directly, since Sonics is no longer supported in the Si abstraction */
371 /* this has been customized for the bcm 4329 ONLY */
373 static si_info_t
*BCMATTACHFN(si_doattach
) (si_info_t
*sii
, uint devid
,
374 osl_t
*osh
, void *regs
,
375 uint bustype
, void *sdh
,
376 char **vars
, uint
*varsz
) {
377 struct si_pub
*sih
= &sii
->pub
;
383 ASSERT(GOODREGS(regs
));
385 bzero((unsigned char *) sii
, sizeof(si_info_t
));
389 sih
->buscoreidx
= BADIDX
;
395 /* find Chipcommon address */
396 cc
= (chipcregs_t
*) sii
->curmap
;
397 sih
->bustype
= bustype
;
399 if (bustype
!= BUSTYPE(bustype
)) {
400 SI_ERROR(("si_doattach: bus type %d does not match configured bus type %d\n", bustype
, BUSTYPE(bustype
)));
404 /* bus/core/clk setup for register access */
405 if (!si_buscore_prep(sii
, bustype
, devid
, sdh
)) {
406 SI_ERROR(("si_doattach: si_core_clk_prep failed %d\n",
411 /* ChipID recognition.
412 * We assume we can read chipid at offset 0 from the regs arg.
413 * If we add other chiptypes (or if we need to support old sdio hosts w/o chipcommon),
414 * some way of recognizing them needs to be added here.
416 w
= R_REG(osh
, &cc
->chipid
);
417 sih
->socitype
= (w
& CID_TYPE_MASK
) >> CID_TYPE_SHIFT
;
418 /* Might as wll fill in chip id rev & pkg */
419 sih
->chip
= w
& CID_ID_MASK
;
420 sih
->chiprev
= (w
& CID_REV_MASK
) >> CID_REV_SHIFT
;
421 sih
->chippkg
= (w
& CID_PKG_MASK
) >> CID_PKG_SHIFT
;
423 if ((CHIPID(sih
->chip
) == BCM4329_CHIP_ID
) &&
424 (sih
->chippkg
!= BCM4329_289PIN_PKG_ID
))
425 sih
->chippkg
= BCM4329_182PIN_PKG_ID
;
427 sih
->issim
= IS_SIM(sih
->chippkg
);
430 /* SI_MSG(("Found chip type SB (0x%08x)\n", w)); */
431 sb_scan(&sii
->pub
, regs
, devid
);
433 /* no cores found, bail out */
434 if (sii
->numcores
== 0) {
435 SI_ERROR(("si_doattach: could not find any cores\n"));
438 /* bus/core/clk setup */
440 if (!si_buscore_setup(sii
, cc
, bustype
, savewin
, &origidx
, regs
)) {
441 SI_ERROR(("si_doattach: si_buscore_setup failed\n"));
448 /* Init nvram from flash if it exists */
449 nvram_init((void *)&(sii
->pub
));
451 /* Init nvram from sprom/otp if they exist */
453 (&sii
->pub
, BUSTYPE(bustype
), regs
, sii
->osh
, vars
, varsz
)) {
454 SI_ERROR(("si_doattach: srom_var_init failed: bad srom\n"));
457 pvars
= vars
? *vars
: NULL
;
458 si_nvram_process(sii
, pvars
);
461 /* === NVRAM, clock is ready === */
464 if (sii
->pub
.ccrev
>= 20) {
466 cc
= (chipcregs_t
*) si_setcore(sih
, CC_CORE_ID
, 0);
467 W_REG(osh
, &cc
->gpiopullup
, 0);
468 W_REG(osh
, &cc
->gpiopulldown
, 0);
469 sb_setcoreidx(sih
, origidx
);
475 /* PMU specific initializations */
476 if (PMUCTL_ENAB(sih
)) {
478 si_pmu_init(sih
, sii
->osh
);
479 si_pmu_chip_init(sih
, sii
->osh
);
480 xtalfreq
= getintvar(pvars
, "xtalfreq");
481 /* If xtalfreq var not available, try to measure it */
483 xtalfreq
= si_pmu_measure_alpclk(sih
, sii
->osh
);
484 si_pmu_pll_init(sih
, sii
->osh
, xtalfreq
);
485 si_pmu_res_init(sih
, sii
->osh
);
486 si_pmu_swreg_init(sih
, sii
->osh
);
489 /* setup the GPIO based LED powersave register */
490 w
= getintvar(pvars
, "leddc");
492 w
= DEFAULT_GPIOTIMERVAL
;
493 sb_corereg(sih
, SI_CC_IDX
, OFFSETOF(chipcregs_t
, gpiotimerval
), ~0, w
);
496 /* clear any previous epidiag-induced target abort */
497 sb_taclear(sih
, FALSE
);
508 static si_info_t
*BCMATTACHFN(si_doattach
) (si_info_t
*sii
, uint devid
,
509 osl_t
*osh
, void *regs
,
510 uint bustype
, void *sdh
,
511 char **vars
, uint
*varsz
) {
512 struct si_pub
*sih
= &sii
->pub
;
518 ASSERT(GOODREGS(regs
));
520 bzero((unsigned char *) sii
, sizeof(si_info_t
));
524 sih
->buscoreidx
= BADIDX
;
530 /* check to see if we are a si core mimic'ing a pci core */
531 if ((bustype
== PCI_BUS
) &&
532 (OSL_PCI_READ_CONFIG(sii
->osh
, PCI_SPROM_CONTROL
, sizeof(uint32
)) ==
534 SI_ERROR(("%s: incoming bus is PCI but it's a lie, switching to SI " "devid:0x%x\n", __func__
, devid
));
538 /* find Chipcommon address */
539 if (bustype
== PCI_BUS
) {
541 OSL_PCI_READ_CONFIG(sii
->osh
, PCI_BAR0_WIN
, sizeof(uint32
));
542 if (!GOODCOREADDR(savewin
, SI_ENUM_BASE
))
543 savewin
= SI_ENUM_BASE
;
544 OSL_PCI_WRITE_CONFIG(sii
->osh
, PCI_BAR0_WIN
, 4, SI_ENUM_BASE
);
545 cc
= (chipcregs_t
*) regs
;
547 cc
= (chipcregs_t
*) REG_MAP(SI_ENUM_BASE
, SI_CORE_SIZE
);
550 sih
->bustype
= bustype
;
551 if (bustype
!= BUSTYPE(bustype
)) {
552 SI_ERROR(("si_doattach: bus type %d does not match configured bus type %d\n", bustype
, BUSTYPE(bustype
)));
556 /* bus/core/clk setup for register access */
557 if (!si_buscore_prep(sii
, bustype
, devid
, sdh
)) {
558 SI_ERROR(("si_doattach: si_core_clk_prep failed %d\n",
563 /* ChipID recognition.
564 * We assume we can read chipid at offset 0 from the regs arg.
565 * If we add other chiptypes (or if we need to support old sdio hosts w/o chipcommon),
566 * some way of recognizing them needs to be added here.
568 w
= R_REG(osh
, &cc
->chipid
);
569 sih
->socitype
= (w
& CID_TYPE_MASK
) >> CID_TYPE_SHIFT
;
570 /* Might as wll fill in chip id rev & pkg */
571 sih
->chip
= w
& CID_ID_MASK
;
572 sih
->chiprev
= (w
& CID_REV_MASK
) >> CID_REV_SHIFT
;
573 sih
->chippkg
= (w
& CID_PKG_MASK
) >> CID_PKG_SHIFT
;
575 sih
->issim
= IS_SIM(sih
->chippkg
);
578 if (CHIPTYPE(sii
->pub
.socitype
) == SOCI_AI
) {
579 SI_MSG(("Found chip type AI (0x%08x)\n", w
));
580 /* pass chipc address instead of original core base */
581 ai_scan(&sii
->pub
, (void *)(uintptr
) cc
, devid
);
583 SI_ERROR(("Found chip of unknown type (0x%08x)\n", w
));
586 /* no cores found, bail out */
587 if (sii
->numcores
== 0) {
588 SI_ERROR(("si_doattach: could not find any cores\n"));
591 /* bus/core/clk setup */
593 if (!si_buscore_setup(sii
, cc
, bustype
, savewin
, &origidx
, regs
)) {
594 SI_ERROR(("si_doattach: si_buscore_setup failed\n"));
598 /* assume current core is CC */
599 if ((sii
->pub
.ccrev
== 0x25)
601 ((CHIPID(sih
->chip
) == BCM43236_CHIP_ID
602 || CHIPID(sih
->chip
) == BCM43235_CHIP_ID
603 || CHIPID(sih
->chip
) == BCM43238_CHIP_ID
)
604 && (CHIPREV(sii
->pub
.chiprev
) <= 2))) {
606 if ((cc
->chipstatus
& CST43236_BP_CLK
) != 0) {
608 clkdiv
= R_REG(osh
, &cc
->clkdiv
);
609 /* otp_clk_div is even number, 120/14 < 9mhz */
610 clkdiv
= (clkdiv
& ~CLKD_OTP
) | (14 << CLKD_OTP_SHIFT
);
611 W_REG(osh
, &cc
->clkdiv
, clkdiv
);
612 SI_ERROR(("%s: set clkdiv to %x\n", __func__
, clkdiv
));
617 /* Init nvram from flash if it exists */
618 nvram_init((void *)&(sii
->pub
));
620 /* Init nvram from sprom/otp if they exist */
622 (&sii
->pub
, BUSTYPE(bustype
), regs
, sii
->osh
, vars
, varsz
)) {
623 SI_ERROR(("si_doattach: srom_var_init failed: bad srom\n"));
626 pvars
= vars
? *vars
: NULL
;
627 si_nvram_process(sii
, pvars
);
629 /* === NVRAM, clock is ready === */
630 cc
= (chipcregs_t
*) si_setcore(sih
, CC_CORE_ID
, 0);
631 W_REG(osh
, &cc
->gpiopullup
, 0);
632 W_REG(osh
, &cc
->gpiopulldown
, 0);
633 si_setcoreidx(sih
, origidx
);
635 /* PMU specific initializations */
636 if (PMUCTL_ENAB(sih
)) {
638 si_pmu_init(sih
, sii
->osh
);
639 si_pmu_chip_init(sih
, sii
->osh
);
640 xtalfreq
= getintvar(pvars
, "xtalfreq");
641 /* If xtalfreq var not available, try to measure it */
643 xtalfreq
= si_pmu_measure_alpclk(sih
, sii
->osh
);
644 si_pmu_pll_init(sih
, sii
->osh
, xtalfreq
);
645 si_pmu_res_init(sih
, sii
->osh
);
646 si_pmu_swreg_init(sih
, sii
->osh
);
649 /* setup the GPIO based LED powersave register */
650 w
= getintvar(pvars
, "leddc");
652 w
= DEFAULT_GPIOTIMERVAL
;
653 si_corereg(sih
, SI_CC_IDX
, OFFSETOF(chipcregs_t
, gpiotimerval
), ~0, w
);
656 ASSERT(sii
->pch
!= NULL
);
657 pcicore_attach(sii
->pch
, pvars
, SI_DOATTACH
);
660 if ((CHIPID(sih
->chip
) == BCM43224_CHIP_ID
) ||
661 (CHIPID(sih
->chip
) == BCM43421_CHIP_ID
)) {
662 /* enable 12 mA drive strenth for 43224 and set chipControl register bit 15 */
663 if (CHIPREV(sih
->chiprev
) == 0) {
664 SI_MSG(("Applying 43224A0 WARs\n"));
665 si_corereg(sih
, SI_CC_IDX
,
666 OFFSETOF(chipcregs_t
, chipcontrol
),
667 CCTRL43224_GPIO_TOGGLE
,
668 CCTRL43224_GPIO_TOGGLE
);
669 si_pmu_chipcontrol(sih
, 0, CCTRL_43224A0_12MA_LED_DRIVE
,
670 CCTRL_43224A0_12MA_LED_DRIVE
);
672 if (CHIPREV(sih
->chiprev
) >= 1) {
673 SI_MSG(("Applying 43224B0+ WARs\n"));
674 si_pmu_chipcontrol(sih
, 0, CCTRL_43224B0_12MA_LED_DRIVE
,
675 CCTRL_43224B0_12MA_LED_DRIVE
);
679 if (CHIPID(sih
->chip
) == BCM4313_CHIP_ID
) {
680 /* enable 12 mA drive strenth for 4313 and set chipControl register bit 1 */
681 SI_MSG(("Applying 4313 WARs\n"));
682 si_pmu_chipcontrol(sih
, 0, CCTRL_4313_12MA_LED_DRIVE
,
683 CCTRL_4313_12MA_LED_DRIVE
);
686 if (CHIPID(sih
->chip
) == BCM4331_CHIP_ID
) {
687 /* Enable Ext PA lines depending on chip package option */
688 si_chipcontrl_epa4331(sih
, TRUE
);
693 if (BUSTYPE(sih
->bustype
) == PCI_BUS
) {
695 pcicore_deinit(sii
->pch
);
703 /* may be called with core in reset */
704 void BCMATTACHFN(si_detach
) (si_t
*sih
)
709 struct si_pub
*si_local
= NULL
;
710 bcopy(&sih
, &si_local
, sizeof(si_t
**));
717 if (BUSTYPE(sih
->bustype
) == SI_BUS
)
718 for (idx
= 0; idx
< SI_MAXCORES
; idx
++)
719 if (sii
->regs
[idx
]) {
720 REG_UNMAP(sii
->regs
[idx
]);
721 sii
->regs
[idx
] = NULL
;
725 nvram_exit((void *)si_local
); /* free up nvram buffers */
727 if (BUSTYPE(sih
->bustype
) == PCI_BUS
) {
729 pcicore_deinit(sii
->pch
);
733 #if !defined(BCMBUSTYPE) || (BCMBUSTYPE == SI_BUS)
735 #endif /* !BCMBUSTYPE || (BCMBUSTYPE == SI_BUS) */
736 MFREE(sii
->osh
, sii
, sizeof(si_info_t
));
739 void *si_osh(si_t
*sih
)
747 void si_setosh(si_t
*sih
, osl_t
*osh
)
752 if (sii
->osh
!= NULL
) {
753 SI_ERROR(("osh is already set....\n"));
759 /* register driver interrupt disabling and restoring callback functions */
761 si_register_intr_callback(si_t
*sih
, void *intrsoff_fn
, void *intrsrestore_fn
,
762 void *intrsenabled_fn
, void *intr_arg
)
767 sii
->intr_arg
= intr_arg
;
768 sii
->intrsoff_fn
= (si_intrsoff_t
) intrsoff_fn
;
769 sii
->intrsrestore_fn
= (si_intrsrestore_t
) intrsrestore_fn
;
770 sii
->intrsenabled_fn
= (si_intrsenabled_t
) intrsenabled_fn
;
771 /* save current core id. when this function called, the current core
772 * must be the core which provides driver functions(il, et, wl, etc.)
774 sii
->dev_coreid
= sii
->coreid
[sii
->curidx
];
777 void si_deregister_intr_callback(si_t
*sih
)
782 sii
->intrsoff_fn
= NULL
;
785 uint
si_intflag(si_t
*sih
)
787 si_info_t
*sii
= SI_INFO(sih
);
789 if (CHIPTYPE(sih
->socitype
) == SOCI_AI
)
790 return R_REG(sii
->osh
,
791 ((uint32
*) (uintptr
) (sii
->oob_router
+
799 uint
si_flag(si_t
*sih
)
801 if (CHIPTYPE(sih
->socitype
) == SOCI_AI
)
809 void si_setint(si_t
*sih
, int siflag
)
811 if (CHIPTYPE(sih
->socitype
) == SOCI_AI
)
812 ai_setint(sih
, siflag
);
818 uint
si_coreid(si_t
*sih
)
823 return sii
->coreid
[sii
->curidx
];
827 uint
si_coreidx(si_t
*sih
)
835 /* return the core-type instantiation # of the current core */
836 uint
si_coreunit(si_t
*sih
)
849 ASSERT(GOODREGS(sii
->curmap
));
850 coreid
= si_coreid(sih
);
852 /* count the cores of our type */
853 for (i
= 0; i
< idx
; i
++)
854 if (sii
->coreid
[i
] == coreid
)
860 uint
si_corevendor(si_t
*sih
)
862 if (CHIPTYPE(sih
->socitype
) == SOCI_AI
)
863 return ai_corevendor(sih
);
870 bool si_backplane64(si_t
*sih
)
872 return (sih
->cccaps
& CC_CAP_BKPLN64
) != 0;
876 uint
si_corerev(si_t
*sih
)
878 if (CHIPTYPE(sih
->socitype
) == SOCI_AI
)
879 return ai_corerev(sih
);
887 /* return index of coreid or BADIDX if not found */
888 uint
si_findcoreidx(si_t
*sih
, uint coreid
, uint coreunit
)
898 for (i
= 0; i
< sii
->numcores
; i
++)
899 if (sii
->coreid
[i
] == coreid
) {
900 if (found
== coreunit
)
908 /* return list of found cores */
909 uint
si_corelist(si_t
*sih
, uint coreid
[])
915 bcopy((unsigned char *) sii
->coreid
, (unsigned char *) coreid
,
916 (sii
->numcores
* sizeof(uint
)));
917 return sii
->numcores
;
920 /* return current register mapping */
921 void *si_coreregs(si_t
*sih
)
926 ASSERT(GOODREGS(sii
->curmap
));
932 * This function changes logical "focus" to the indicated core;
933 * must be called with interrupts off.
934 * Moreover, callers should keep interrupts off during switching out of and back to d11 core
936 void *si_setcore(si_t
*sih
, uint coreid
, uint coreunit
)
940 idx
= si_findcoreidx(sih
, coreid
, coreunit
);
944 if (CHIPTYPE(sih
->socitype
) == SOCI_AI
)
945 return ai_setcoreidx(sih
, idx
);
948 return sb_setcoreidx(sih
, idx
);
957 void *si_setcoreidx(si_t
*sih
, uint coreidx
)
959 if (CHIPTYPE(sih
->socitype
) == SOCI_AI
)
960 return ai_setcoreidx(sih
, coreidx
);
968 /* Turn off interrupt as required by sb_setcore, before switch core */
969 void *si_switch_core(si_t
*sih
, uint coreid
, uint
*origidx
, uint
*intr_val
)
977 /* Overloading the origidx variable to remember the coreid,
978 * this works because the core ids cannot be confused with
982 if (coreid
== CC_CORE_ID
)
983 return (void *)CCREGS_FAST(sii
);
984 else if (coreid
== sih
->buscoretype
)
985 return (void *)PCIEREGS(sii
);
987 INTR_OFF(sii
, *intr_val
);
988 *origidx
= sii
->curidx
;
989 cc
= si_setcore(sih
, coreid
, 0);
995 /* restore coreidx and restore interrupt */
996 void si_restore_core(si_t
*sih
, uint coreid
, uint intr_val
)
1002 && ((coreid
== CC_CORE_ID
) || (coreid
== sih
->buscoretype
)))
1005 si_setcoreidx(sih
, coreid
);
1006 INTR_RESTORE(sii
, intr_val
);
1009 int si_numaddrspaces(si_t
*sih
)
1011 if (CHIPTYPE(sih
->socitype
) == SOCI_AI
)
1012 return ai_numaddrspaces(sih
);
1019 uint32
si_addrspace(si_t
*sih
, uint asidx
)
1021 if (CHIPTYPE(sih
->socitype
) == SOCI_AI
)
1022 return ai_addrspace(sih
, asidx
);
1029 uint32
si_addrspacesize(si_t
*sih
, uint asidx
)
1031 if (CHIPTYPE(sih
->socitype
) == SOCI_AI
)
1032 return ai_addrspacesize(sih
, asidx
);
1039 uint32
si_core_cflags(si_t
*sih
, uint32 mask
, uint32 val
)
1041 if (CHIPTYPE(sih
->socitype
) == SOCI_AI
)
1042 return ai_core_cflags(sih
, mask
, val
);
1049 void si_core_cflags_wo(si_t
*sih
, uint32 mask
, uint32 val
)
1051 if (CHIPTYPE(sih
->socitype
) == SOCI_AI
)
1052 ai_core_cflags_wo(sih
, mask
, val
);
1057 uint32
si_core_sflags(si_t
*sih
, uint32 mask
, uint32 val
)
1059 if (CHIPTYPE(sih
->socitype
) == SOCI_AI
)
1060 return ai_core_sflags(sih
, mask
, val
);
1067 bool si_iscoreup(si_t
*sih
)
1069 if (CHIPTYPE(sih
->socitype
) == SOCI_AI
)
1070 return ai_iscoreup(sih
);
1073 return sb_iscoreup(sih
);
1081 void si_write_wrapperreg(si_t
*sih
, uint32 offset
, uint32 val
)
1083 /* only for 4319, no requirement for SOCI_SB */
1084 if (CHIPTYPE(sih
->socitype
) == SOCI_AI
) {
1085 ai_write_wrap_reg(sih
, offset
, val
);
1089 uint
si_corereg(si_t
*sih
, uint coreidx
, uint regoff
, uint mask
, uint val
)
1092 if (CHIPTYPE(sih
->socitype
) == SOCI_AI
)
1093 return ai_corereg(sih
, coreidx
, regoff
, mask
, val
);
1096 return sb_corereg(sih
, coreidx
, regoff
, mask
, val
);
1104 void si_core_disable(si_t
*sih
, uint32 bits
)
1107 if (CHIPTYPE(sih
->socitype
) == SOCI_AI
)
1108 ai_core_disable(sih
, bits
);
1111 sb_core_disable(sih
, bits
);
1115 void si_core_reset(si_t
*sih
, uint32 bits
, uint32 resetbits
)
1117 if (CHIPTYPE(sih
->socitype
) == SOCI_AI
)
1118 ai_core_reset(sih
, bits
, resetbits
);
1121 sb_core_reset(sih
, bits
, resetbits
);
1125 /* Run bist on current core. Caller needs to take care of core-specific bist hazards */
1126 int si_corebist(si_t
*sih
)
1131 /* Read core control flags */
1132 cflags
= si_core_cflags(sih
, 0, 0);
1134 /* Set bist & fgc */
1135 si_core_cflags(sih
, ~0, (SICF_BIST_EN
| SICF_FGC
));
1137 /* Wait for bist done */
1138 SPINWAIT(((si_core_sflags(sih
, 0, 0) & SISF_BIST_DONE
) == 0), 100000);
1140 if (si_core_sflags(sih
, 0, 0) & SISF_BIST_ERROR
)
1141 result
= BCME_ERROR
;
1143 /* Reset core control flags */
1144 si_core_cflags(sih
, 0xffff, cflags
);
1149 static uint32
BCMINITFN(factor6
) (uint32 x
)
1169 /* calculate the speed the SI would run at given a set of clockcontrol values */
1170 uint32
BCMINITFN(si_clock_rate
) (uint32 pll_type
, uint32 n
, uint32 m
)
1172 uint32 n1
, n2
, clock
, m1
, m2
, m3
, mc
;
1174 n1
= n
& CN_N1_MASK
;
1175 n2
= (n
& CN_N2_MASK
) >> CN_N2_SHIFT
;
1177 if (pll_type
== PLL_TYPE6
) {
1178 if (m
& CC_T6_MMASK
)
1182 } else if ((pll_type
== PLL_TYPE1
) ||
1183 (pll_type
== PLL_TYPE3
) ||
1184 (pll_type
== PLL_TYPE4
) || (pll_type
== PLL_TYPE7
)) {
1187 } else if (pll_type
== PLL_TYPE2
) {
1190 ASSERT((n1
>= 2) && (n1
<= 7));
1191 ASSERT((n2
>= 5) && (n2
<= 23));
1192 } else if (pll_type
== PLL_TYPE5
) {
1196 /* PLL types 3 and 7 use BASE2 (25Mhz) */
1197 if ((pll_type
== PLL_TYPE3
) || (pll_type
== PLL_TYPE7
)) {
1198 clock
= CC_CLOCK_BASE2
* n1
* n2
;
1200 clock
= CC_CLOCK_BASE1
* n1
* n2
;
1205 m1
= m
& CC_M1_MASK
;
1206 m2
= (m
& CC_M2_MASK
) >> CC_M2_SHIFT
;
1207 m3
= (m
& CC_M3_MASK
) >> CC_M3_SHIFT
;
1208 mc
= (m
& CC_MC_MASK
) >> CC_MC_SHIFT
;
1210 if ((pll_type
== PLL_TYPE1
) ||
1211 (pll_type
== PLL_TYPE3
) ||
1212 (pll_type
== PLL_TYPE4
) || (pll_type
== PLL_TYPE7
)) {
1214 if ((pll_type
== PLL_TYPE1
) || (pll_type
== PLL_TYPE3
))
1226 return clock
/ (m1
* m2
);
1228 return clock
/ (m1
* m2
* m3
);
1230 return clock
/ (m1
* m3
);
1235 ASSERT(pll_type
== PLL_TYPE2
);
1240 ASSERT((m1
>= 2) && (m1
<= 7));
1241 ASSERT((m2
>= 3) && (m2
<= 10));
1242 ASSERT((m3
>= 2) && (m3
<= 7));
1244 if ((mc
& CC_T2MC_M1BYP
) == 0)
1246 if ((mc
& CC_T2MC_M2BYP
) == 0)
1248 if ((mc
& CC_T2MC_M3BYP
) == 0)
1255 uint32
BCMINITFN(si_clock
) (si_t
*sih
)
1261 uint32 pll_type
, rate
;
1265 INTR_OFF(sii
, intr_val
);
1266 if (PMUCTL_ENAB(sih
)) {
1267 rate
= si_pmu_si_clock(sih
, sii
->osh
);
1272 cc
= (chipcregs_t
*) si_setcore(sih
, CC_CORE_ID
, 0);
1275 n
= R_REG(sii
->osh
, &cc
->clockcontrol_n
);
1276 pll_type
= sih
->cccaps
& CC_CAP_PLL_MASK
;
1277 if (pll_type
== PLL_TYPE6
)
1278 m
= R_REG(sii
->osh
, &cc
->clockcontrol_m3
);
1279 else if (pll_type
== PLL_TYPE3
)
1280 m
= R_REG(sii
->osh
, &cc
->clockcontrol_m2
);
1282 m
= R_REG(sii
->osh
, &cc
->clockcontrol_sb
);
1284 /* calculate rate */
1285 rate
= si_clock_rate(pll_type
, n
, m
);
1287 if (pll_type
== PLL_TYPE3
)
1290 /* switch back to previous core */
1291 si_setcoreidx(sih
, idx
);
1293 INTR_RESTORE(sii
, intr_val
);
1298 uint32
BCMINITFN(si_alp_clock
) (si_t
*sih
)
1300 if (PMUCTL_ENAB(sih
))
1301 return si_pmu_alp_clock(sih
, si_osh(sih
));
1306 uint32
BCMINITFN(si_ilp_clock
) (si_t
*sih
)
1308 if (PMUCTL_ENAB(sih
))
1309 return si_pmu_ilp_clock(sih
, si_osh(sih
));
1314 /* set chip watchdog reset timer to fire in 'ticks' */
1317 si_watchdog(si_t
*sih
, uint ticks
)
1319 if (PMUCTL_ENAB(sih
)) {
1321 if ((sih
->chip
== BCM4319_CHIP_ID
) && (sih
->chiprev
== 0) &&
1323 si_corereg(sih
, SI_CC_IDX
, OFFSETOF(chipcregs_t
,
1324 clk_ctl_st
), ~0, 0x2);
1325 si_setcore(sih
, USB20D_CORE_ID
, 0);
1326 si_core_disable(sih
, 1);
1327 si_setcore(sih
, CC_CORE_ID
, 0);
1332 si_corereg(sih
, SI_CC_IDX
, OFFSETOF(chipcregs_t
, pmuwatchdog
),
1336 si_corereg(sih
, SI_CC_IDX
, OFFSETOF(chipcregs_t
, watchdog
),
1341 void si_watchdog(si_t
*sih
, uint ticks
)
1345 if (PMUCTL_ENAB(sih
)) {
1347 if ((CHIPID(sih
->chip
) == BCM4319_CHIP_ID
) &&
1348 (CHIPREV(sih
->chiprev
) == 0) && (ticks
!= 0)) {
1349 si_corereg(sih
, SI_CC_IDX
,
1350 OFFSETOF(chipcregs_t
, clk_ctl_st
), ~0, 0x2);
1351 si_setcore(sih
, USB20D_CORE_ID
, 0);
1352 si_core_disable(sih
, 1);
1353 si_setcore(sih
, CC_CORE_ID
, 0);
1356 nb
= (sih
->ccrev
< 26) ? 16 : ((sih
->ccrev
>= 37) ? 32 : 24);
1357 /* The mips compiler uses the sllv instruction,
1358 * so we specially handle the 32-bit case.
1363 maxt
= ((1 << nb
) - 1);
1367 else if (ticks
> maxt
)
1370 si_corereg(sih
, SI_CC_IDX
, OFFSETOF(chipcregs_t
, pmuwatchdog
),
1373 /* make sure we come up in fast clock mode; or if clearing, clear clock */
1374 si_clkctl_cc(sih
, ticks
? CLK_FAST
: CLK_DYNAMIC
);
1375 maxt
= (1 << 28) - 1;
1379 si_corereg(sih
, SI_CC_IDX
, OFFSETOF(chipcregs_t
, watchdog
), ~0,
1385 /* trigger watchdog reset after ms milliseconds */
1386 void si_watchdog_ms(si_t
*sih
, uint32 ms
)
1388 si_watchdog(sih
, wd_msticks
* ms
);
1391 u16
BCMATTACHFN(si_d11_devid
) (si_t
*sih
)
1393 si_info_t
*sii
= SI_INFO(sih
);
1396 /* normal case: nvram variable with devpath->devid->wl0id */
1397 device
= (u16
) si_getdevpathintvar(sih
, "devid");
1401 /* Get devid from OTP/SPROM depending on where the SROM is read */
1402 device
= (u16
) getintvar(sii
->vars
, "devid");
1406 /* no longer support wl0id, but keep the code here for backward compatibility. */
1407 device
= (u16
) getintvar(sii
->vars
, "wl0id");
1418 /* return the slow clock source - LPO, XTAL, or PCI */
1419 static uint
si_slowclk_src(si_info_t
*sii
)
1423 ASSERT(SI_FAST(sii
) || si_coreid(&sii
->pub
) == CC_CORE_ID
);
1425 if (sii
->pub
.ccrev
< 6) {
1426 if ((BUSTYPE(sii
->pub
.bustype
) == PCI_BUS
) &&
1427 (OSL_PCI_READ_CONFIG(sii
->osh
, PCI_GPIO_OUT
, sizeof(uint32
))
1428 & PCI_CFG_GPIO_SCS
))
1432 } else if (sii
->pub
.ccrev
< 10) {
1433 cc
= (chipcregs_t
*) si_setcoreidx(&sii
->pub
, sii
->curidx
);
1434 return R_REG(sii
->osh
, &cc
->slow_clk_ctl
) & SCC_SS_MASK
;
1435 } else /* Insta-clock */
1439 /* return the ILP (slowclock) min or max frequency */
1440 static uint
si_slowclk_freq(si_info_t
*sii
, bool max_freq
, chipcregs_t
*cc
)
1445 ASSERT(SI_FAST(sii
) || si_coreid(&sii
->pub
) == CC_CORE_ID
);
1447 /* shouldn't be here unless we've established the chip has dynamic clk control */
1448 ASSERT(R_REG(sii
->osh
, &cc
->capabilities
) & CC_CAP_PWR_CTL
);
1450 slowclk
= si_slowclk_src(sii
);
1451 if (sii
->pub
.ccrev
< 6) {
1452 if (slowclk
== SCC_SS_PCI
)
1453 return max_freq
? (PCIMAXFREQ
/ 64)
1454 : (PCIMINFREQ
/ 64);
1456 return max_freq
? (XTALMAXFREQ
/ 32)
1457 : (XTALMINFREQ
/ 32);
1458 } else if (sii
->pub
.ccrev
< 10) {
1460 (((R_REG(sii
->osh
, &cc
->slow_clk_ctl
) & SCC_CD_MASK
) >>
1462 if (slowclk
== SCC_SS_LPO
)
1463 return max_freq
? LPOMAXFREQ
: LPOMINFREQ
;
1464 else if (slowclk
== SCC_SS_XTAL
)
1465 return max_freq
? (XTALMAXFREQ
/ div
)
1466 : (XTALMINFREQ
/ div
);
1467 else if (slowclk
== SCC_SS_PCI
)
1468 return max_freq
? (PCIMAXFREQ
/ div
)
1469 : (PCIMINFREQ
/ div
);
1473 /* Chipc rev 10 is InstaClock */
1474 div
= R_REG(sii
->osh
, &cc
->system_clk_ctl
) >> SYCC_CD_SHIFT
;
1475 div
= 4 * (div
+ 1);
1476 return max_freq
? XTALMAXFREQ
: (XTALMINFREQ
/ div
);
1481 static void BCMINITFN(si_clkctl_setdelay
) (si_info_t
*sii
, void *chipcregs
)
1483 chipcregs_t
*cc
= (chipcregs_t
*) chipcregs
;
1484 uint slowmaxfreq
, pll_delay
, slowclk
;
1485 uint pll_on_delay
, fref_sel_delay
;
1487 pll_delay
= PLL_DELAY
;
1489 /* If the slow clock is not sourced by the xtal then add the xtal_on_delay
1490 * since the xtal will also be powered down by dynamic clk control logic.
1493 slowclk
= si_slowclk_src(sii
);
1494 if (slowclk
!= SCC_SS_XTAL
)
1495 pll_delay
+= XTAL_ON_DELAY
;
1497 /* Starting with 4318 it is ILP that is used for the delays */
1499 si_slowclk_freq(sii
, (sii
->pub
.ccrev
>= 10) ? FALSE
: TRUE
, cc
);
1501 pll_on_delay
= ((slowmaxfreq
* pll_delay
) + 999999) / 1000000;
1502 fref_sel_delay
= ((slowmaxfreq
* FREF_DELAY
) + 999999) / 1000000;
1504 W_REG(sii
->osh
, &cc
->pll_on_delay
, pll_on_delay
);
1505 W_REG(sii
->osh
, &cc
->fref_sel_delay
, fref_sel_delay
);
1508 /* initialize power control delay registers */
1509 void BCMINITFN(si_clkctl_init
) (si_t
*sih
)
1516 if (!CCCTL_ENAB(sih
))
1520 fast
= SI_FAST(sii
);
1522 origidx
= sii
->curidx
;
1523 cc
= (chipcregs_t
*) si_setcore(sih
, CC_CORE_ID
, 0);
1527 cc
= (chipcregs_t
*) CCREGS_FAST(sii
);
1533 /* set all Instaclk chip ILP to 1 MHz */
1534 if (sih
->ccrev
>= 10)
1535 SET_REG(sii
->osh
, &cc
->system_clk_ctl
, SYCC_CD_MASK
,
1536 (ILP_DIV_1MHZ
<< SYCC_CD_SHIFT
));
1538 si_clkctl_setdelay(sii
, (void *)(uintptr
) cc
);
1541 si_setcoreidx(sih
, origidx
);
1544 /* return the value suitable for writing to the dot11 core FAST_PWRUP_DELAY register */
1545 u16
BCMINITFN(si_clkctl_fast_pwrup_delay
) (si_t
*sih
)
1556 if (PMUCTL_ENAB(sih
)) {
1557 INTR_OFF(sii
, intr_val
);
1558 fpdelay
= si_pmu_fast_pwrup_delay(sih
, sii
->osh
);
1559 INTR_RESTORE(sii
, intr_val
);
1563 if (!CCCTL_ENAB(sih
))
1566 fast
= SI_FAST(sii
);
1569 origidx
= sii
->curidx
;
1570 INTR_OFF(sii
, intr_val
);
1571 cc
= (chipcregs_t
*) si_setcore(sih
, CC_CORE_ID
, 0);
1575 cc
= (chipcregs_t
*) CCREGS_FAST(sii
);
1581 slowminfreq
= si_slowclk_freq(sii
, FALSE
, cc
);
1582 fpdelay
= (((R_REG(sii
->osh
, &cc
->pll_on_delay
) + 2) * 1000000) +
1583 (slowminfreq
- 1)) / slowminfreq
;
1587 si_setcoreidx(sih
, origidx
);
1588 INTR_RESTORE(sii
, intr_val
);
1593 /* turn primary xtal and/or pll off/on */
1594 int si_clkctl_xtal(si_t
*sih
, uint what
, bool on
)
1597 uint32 in
, out
, outen
;
1601 switch (BUSTYPE(sih
->bustype
)) {
1606 #endif /* BCMSDIO */
1609 /* pcie core doesn't have any mapping to control the xtal pu */
1613 in
= OSL_PCI_READ_CONFIG(sii
->osh
, PCI_GPIO_IN
, sizeof(uint32
));
1615 OSL_PCI_READ_CONFIG(sii
->osh
, PCI_GPIO_OUT
, sizeof(uint32
));
1617 OSL_PCI_READ_CONFIG(sii
->osh
, PCI_GPIO_OUTEN
,
1621 * Avoid glitching the clock if GPRS is already using it.
1622 * We can't actually read the state of the PLLPD so we infer it
1623 * by the value of XTAL_PU which *is* readable via gpioin.
1625 if (on
&& (in
& PCI_CFG_GPIO_XTAL
))
1629 outen
|= PCI_CFG_GPIO_XTAL
;
1631 outen
|= PCI_CFG_GPIO_PLL
;
1634 /* turn primary xtal on */
1636 out
|= PCI_CFG_GPIO_XTAL
;
1638 out
|= PCI_CFG_GPIO_PLL
;
1639 OSL_PCI_WRITE_CONFIG(sii
->osh
, PCI_GPIO_OUT
,
1640 sizeof(uint32
), out
);
1641 OSL_PCI_WRITE_CONFIG(sii
->osh
, PCI_GPIO_OUTEN
,
1642 sizeof(uint32
), outen
);
1643 OSL_DELAY(XTAL_ON_DELAY
);
1648 out
&= ~PCI_CFG_GPIO_PLL
;
1649 OSL_PCI_WRITE_CONFIG(sii
->osh
, PCI_GPIO_OUT
,
1650 sizeof(uint32
), out
);
1655 out
&= ~PCI_CFG_GPIO_XTAL
;
1657 out
|= PCI_CFG_GPIO_PLL
;
1658 OSL_PCI_WRITE_CONFIG(sii
->osh
, PCI_GPIO_OUT
,
1659 sizeof(uint32
), out
);
1660 OSL_PCI_WRITE_CONFIG(sii
->osh
, PCI_GPIO_OUTEN
,
1661 sizeof(uint32
), outen
);
1672 * clock control policy function throught chipcommon
1674 * set dynamic clk control mode (forceslow, forcefast, dynamic)
1675 * returns true if we are forcing fast clock
1676 * this is a wrapper over the next internal function
1677 * to allow flexible policy settings for outside caller
1679 bool si_clkctl_cc(si_t
*sih
, uint mode
)
1685 /* chipcommon cores prior to rev6 don't support dynamic clock control */
1689 if (PCI_FORCEHT(sii
))
1690 return mode
== CLK_FAST
;
1692 return _si_clkctl_cc(sii
, mode
);
1695 /* clk control mechanism through chipcommon, no policy checking */
1696 static bool _si_clkctl_cc(si_info_t
*sii
, uint mode
)
1702 bool fast
= SI_FAST(sii
);
1704 /* chipcommon cores prior to rev6 don't support dynamic clock control */
1705 if (sii
->pub
.ccrev
< 6)
1708 /* Chips with ccrev 10 are EOL and they don't have SYCC_HR which we use below */
1709 ASSERT(sii
->pub
.ccrev
!= 10);
1712 INTR_OFF(sii
, intr_val
);
1713 origidx
= sii
->curidx
;
1715 if ((BUSTYPE(sii
->pub
.bustype
) == SI_BUS
) &&
1716 si_setcore(&sii
->pub
, MIPS33_CORE_ID
, 0) &&
1717 (si_corerev(&sii
->pub
) <= 7) && (sii
->pub
.ccrev
>= 10))
1720 cc
= (chipcregs_t
*) si_setcore(&sii
->pub
, CC_CORE_ID
, 0);
1722 cc
= (chipcregs_t
*) CCREGS_FAST(sii
);
1728 if (!CCCTL_ENAB(&sii
->pub
) && (sii
->pub
.ccrev
< 20))
1732 case CLK_FAST
: /* FORCEHT, fast (pll) clock */
1733 if (sii
->pub
.ccrev
< 10) {
1734 /* don't forget to force xtal back on before we clear SCC_DYN_XTAL.. */
1735 si_clkctl_xtal(&sii
->pub
, XTAL
, ON
);
1736 SET_REG(sii
->osh
, &cc
->slow_clk_ctl
,
1737 (SCC_XC
| SCC_FS
| SCC_IP
), SCC_IP
);
1738 } else if (sii
->pub
.ccrev
< 20) {
1739 OR_REG(sii
->osh
, &cc
->system_clk_ctl
, SYCC_HR
);
1741 OR_REG(sii
->osh
, &cc
->clk_ctl_st
, CCS_FORCEHT
);
1744 /* wait for the PLL */
1745 if (PMUCTL_ENAB(&sii
->pub
)) {
1746 uint32 htavail
= CCS_HTAVAIL
;
1747 SPINWAIT(((R_REG(sii
->osh
, &cc
->clk_ctl_st
) & htavail
)
1748 == 0), PMU_MAX_TRANSITION_DLY
);
1749 ASSERT(R_REG(sii
->osh
, &cc
->clk_ctl_st
) & htavail
);
1751 OSL_DELAY(PLL_DELAY
);
1755 case CLK_DYNAMIC
: /* enable dynamic clock control */
1756 if (sii
->pub
.ccrev
< 10) {
1757 scc
= R_REG(sii
->osh
, &cc
->slow_clk_ctl
);
1758 scc
&= ~(SCC_FS
| SCC_IP
| SCC_XC
);
1759 if ((scc
& SCC_SS_MASK
) != SCC_SS_XTAL
)
1761 W_REG(sii
->osh
, &cc
->slow_clk_ctl
, scc
);
1763 /* for dynamic control, we have to release our xtal_pu "force on" */
1765 si_clkctl_xtal(&sii
->pub
, XTAL
, OFF
);
1766 } else if (sii
->pub
.ccrev
< 20) {
1768 AND_REG(sii
->osh
, &cc
->system_clk_ctl
, ~SYCC_HR
);
1770 AND_REG(sii
->osh
, &cc
->clk_ctl_st
, ~CCS_FORCEHT
);
1780 si_setcoreidx(&sii
->pub
, origidx
);
1781 INTR_RESTORE(sii
, intr_val
);
1783 return mode
== CLK_FAST
;
1786 /* Build device path. Support SI, PCI, and JTAG for now. */
1787 int BCMATTACHFN(si_devpath
) (si_t
*sih
, char *path
, int size
)
1791 ASSERT(path
!= NULL
);
1792 ASSERT(size
>= SI_DEVPATH_BUFSZ
);
1794 if (!path
|| size
<= 0)
1797 switch (BUSTYPE(sih
->bustype
)) {
1800 slen
= snprintf(path
, (size_t) size
, "sb/%u/", si_coreidx(sih
));
1803 ASSERT((SI_INFO(sih
))->osh
!= NULL
);
1804 slen
= snprintf(path
, (size_t) size
, "pci/%u/%u/",
1805 OSL_PCI_BUS((SI_INFO(sih
))->osh
),
1806 OSL_PCI_SLOT((SI_INFO(sih
))->osh
));
1811 SI_ERROR(("si_devpath: device 0 assumed\n"));
1812 slen
= snprintf(path
, (size_t) size
, "sd/%u/", si_coreidx(sih
));
1821 if (slen
< 0 || slen
>= size
) {
1829 /* Get a variable, but only if it has a devpath prefix */
1830 char *BCMATTACHFN(si_getdevpathvar
) (si_t
*sih
, const char *name
)
1832 char varname
[SI_DEVPATH_BUFSZ
+ 32];
1834 si_devpathvar(sih
, varname
, sizeof(varname
), name
);
1836 return getvar(NULL
, varname
);
1839 /* Get a variable, but only if it has a devpath prefix */
1840 int BCMATTACHFN(si_getdevpathintvar
) (si_t
*sih
, const char *name
)
1842 #if defined(BCMBUSTYPE) && (BCMBUSTYPE == SI_BUS)
1843 return getintvar(NULL
, name
);
1845 char varname
[SI_DEVPATH_BUFSZ
+ 32];
1847 si_devpathvar(sih
, varname
, sizeof(varname
), name
);
1849 return getintvar(NULL
, varname
);
1853 char *si_getnvramflvar(si_t
*sih
, const char *name
)
1855 return getvar(NULL
, name
);
1858 /* Concatenate the dev path with a varname into the given 'var' buffer
1859 * and return the 'var' pointer.
1860 * Nothing is done to the arguments if len == 0 or var is NULL, var is still returned.
1861 * On overflow, the first char will be set to '\0'.
1863 static char *BCMATTACHFN(si_devpathvar
) (si_t
*sih
, char *var
, int len
,
1867 if (!var
|| len
<= 0)
1870 if (si_devpath(sih
, var
, len
) == 0) {
1871 path_len
= strlen(var
);
1873 if (strlen(name
) + 1 > (uint
) (len
- path_len
))
1876 strncpy(var
+ path_len
, name
, len
- path_len
- 1);
1882 uint32
si_pciereg(si_t
*sih
, uint32 offset
, uint32 mask
, uint32 val
, uint type
)
1889 SI_ERROR(("%s: Not a PCIE device\n", __func__
));
1893 return pcicore_pciereg(sii
->pch
, offset
, mask
, val
, type
);
1897 si_pcieserdesreg(si_t
*sih
, uint32 mdioslave
, uint32 offset
, uint32 mask
,
1905 SI_ERROR(("%s: Not a PCIE device\n", __func__
));
1909 return pcicore_pcieserdesreg(sii
->pch
, mdioslave
, offset
, mask
, val
);
1913 /* return TRUE if PCIE capability exists in the pci config space */
1914 static __used
bool si_ispcie(si_info_t
*sii
)
1918 if (BUSTYPE(sii
->pub
.bustype
) != PCI_BUS
)
1922 pcicore_find_pci_capability(sii
->osh
, PCI_CAP_PCIECAP_ID
, NULL
,
1930 /* Wake-on-wireless-LAN (WOWL) support functions */
1931 /* Enable PME generation and disable clkreq */
1932 void si_pci_pmeen(si_t
*sih
)
1938 pcicore_pmeen(sii
->pch
);
1941 /* Return TRUE if PME status is set */
1942 bool si_pci_pmestat(si_t
*sih
)
1948 return pcicore_pmestat(sii
->pch
);
1951 /* Disable PME generation, clear the PME status bit if set */
1952 void si_pci_pmeclr(si_t
*sih
)
1958 pcicore_pmeclr(sii
->pch
);
1962 /* initialize the sdio core */
1963 void si_sdio_init(si_t
*sih
)
1965 si_info_t
*sii
= SI_INFO(sih
);
1967 if (((sih
->buscoretype
== PCMCIA_CORE_ID
) && (sih
->buscorerev
>= 8)) ||
1968 (sih
->buscoretype
== SDIOD_CORE_ID
)) {
1970 sdpcmd_regs_t
*sdpregs
;
1972 /* get the current core index */
1974 ASSERT(idx
== si_findcoreidx(sih
, D11_CORE_ID
, 0));
1976 /* switch to sdio core */
1977 sdpregs
= (sdpcmd_regs_t
*) si_setcore(sih
, PCMCIA_CORE_ID
, 0);
1980 (sdpcmd_regs_t
*) si_setcore(sih
, SDIOD_CORE_ID
, 0);
1983 SI_MSG(("si_sdio_init: For PCMCIA/SDIO Corerev %d, enable ints from core %d " "through SD core %d (%p)\n", sih
->buscorerev
, idx
, sii
->curidx
, sdpregs
));
1985 /* enable backplane error and core interrupts */
1986 W_REG(sii
->osh
, &sdpregs
->hostintmask
, I_SBINT
);
1987 W_REG(sii
->osh
, &sdpregs
->sbintmask
,
1988 (I_SB_SERR
| I_SB_RESPERR
| (1 << idx
)));
1990 /* switch back to previous core */
1991 si_setcoreidx(sih
, idx
);
1994 /* enable interrupts */
1995 bcmsdh_intr_enable(sii
->sdh
);
1998 #endif /* BCMSDIO */
2000 bool BCMATTACHFN(si_pci_war16165
) (si_t
*sih
)
2006 return PCI(sii
) && (sih
->buscorerev
<= 10);
2009 /* Disable pcie_war_ovr for some platforms (sigh!)
2010 * This is for boards that have BFL2_PCIEWAR_OVR set
2011 * but are in systems that still want the benefits of ASPM
2012 * Note that this should be done AFTER si_doattach
2014 void si_pcie_war_ovr_update(si_t
*sih
, u8 aspm
)
2023 pcie_war_ovr_aspm_update(sii
->pch
, aspm
);
2026 /* back door for other module to override chippkg */
2027 void si_chippkg_set(si_t
*sih
, uint val
)
2033 sii
->pub
.chippkg
= val
;
2036 void BCMINITFN(si_pci_up
) (si_t
*sih
)
2042 /* if not pci bus, we're done */
2043 if (BUSTYPE(sih
->bustype
) != PCI_BUS
)
2046 if (PCI_FORCEHT(sii
))
2047 _si_clkctl_cc(sii
, CLK_FAST
);
2050 pcicore_up(sii
->pch
, SI_PCIUP
);
2054 /* Unconfigure and/or apply various WARs when system is going to sleep mode */
2055 void BCMUNINITFN(si_pci_sleep
) (si_t
*sih
)
2061 pcicore_sleep(sii
->pch
);
2064 /* Unconfigure and/or apply various WARs when going down */
2065 void BCMINITFN(si_pci_down
) (si_t
*sih
)
2071 /* if not pci bus, we're done */
2072 if (BUSTYPE(sih
->bustype
) != PCI_BUS
)
2075 /* release FORCEHT since chip is going to "down" state */
2076 if (PCI_FORCEHT(sii
))
2077 _si_clkctl_cc(sii
, CLK_DYNAMIC
);
2079 pcicore_down(sii
->pch
, SI_PCIDOWN
);
2083 * Configure the pci core for pci client (NIC) action
2084 * coremask is the bitvec of cores by index to be enabled.
2086 void BCMATTACHFN(si_pci_setup
) (si_t
*sih
, uint coremask
)
2089 sbpciregs_t
*pciregs
= NULL
;
2090 uint32 siflag
= 0, w
;
2095 if (BUSTYPE(sii
->pub
.bustype
) != PCI_BUS
)
2098 ASSERT(PCI(sii
) || PCIE(sii
));
2099 ASSERT(sii
->pub
.buscoreidx
!= BADIDX
);
2102 /* get current core index */
2105 /* we interrupt on this backplane flag number */
2106 siflag
= si_flag(sih
);
2108 /* switch over to pci core */
2110 (sbpciregs_t
*) si_setcoreidx(sih
, sii
->pub
.buscoreidx
);
2114 * Enable sb->pci interrupts. Assume
2115 * PCI rev 2.3 support was added in pci core rev 6 and things changed..
2117 if (PCIE(sii
) || (PCI(sii
) && ((sii
->pub
.buscorerev
) >= 6))) {
2118 /* pci config write to set this core bit in PCIIntMask */
2119 w
= OSL_PCI_READ_CONFIG(sii
->osh
, PCI_INT_MASK
, sizeof(uint32
));
2120 w
|= (coremask
<< PCI_SBIM_SHIFT
);
2121 OSL_PCI_WRITE_CONFIG(sii
->osh
, PCI_INT_MASK
, sizeof(uint32
), w
);
2123 /* set sbintvec bit for our flag number */
2124 si_setint(sih
, siflag
);
2128 OR_REG(sii
->osh
, &pciregs
->sbtopci2
,
2129 (SBTOPCI_PREF
| SBTOPCI_BURST
));
2130 if (sii
->pub
.buscorerev
>= 11) {
2131 OR_REG(sii
->osh
, &pciregs
->sbtopci2
,
2132 SBTOPCI_RC_READMULTI
);
2133 w
= R_REG(sii
->osh
, &pciregs
->clkrun
);
2134 W_REG(sii
->osh
, &pciregs
->clkrun
,
2135 (w
| PCI_CLKRUN_DSBL
));
2136 w
= R_REG(sii
->osh
, &pciregs
->clkrun
);
2139 /* switch back to previous core */
2140 si_setcoreidx(sih
, idx
);
2144 u8
si_pcieclkreq(si_t
*sih
, uint32 mask
, uint32 val
)
2152 return pcie_clkreq(sii
->pch
, mask
, val
);
2155 uint32
si_pcielcreg(si_t
*sih
, uint32 mask
, uint32 val
)
2164 return pcie_lcreg(sii
->pch
, mask
, val
);
2167 /* indirect way to read pcie config regs */
2168 uint
si_pcie_readreg(void *sih
, uint addrtype
, uint offset
)
2170 return pcie_readreg(((si_info_t
*) sih
)->osh
,
2171 (sbpcieregs_t
*) PCIEREGS(((si_info_t
*) sih
)),
2176 * Fixup SROMless PCI device's configuration.
2177 * The current core may be changed upon return.
2179 int si_pci_fixcfg(si_t
*sih
)
2181 uint origidx
, pciidx
;
2182 sbpciregs_t
*pciregs
= NULL
;
2183 sbpcieregs_t
*pcieregs
= NULL
;
2185 u16 val16
, *reg16
= NULL
;
2187 si_info_t
*sii
= SI_INFO(sih
);
2189 ASSERT(BUSTYPE(sii
->pub
.bustype
) == PCI_BUS
);
2191 /* Fixup PI in SROM shadow area to enable the correct PCI core access */
2192 /* save the current index */
2193 origidx
= si_coreidx(&sii
->pub
);
2195 /* check 'pi' is correct and fix it if not */
2196 if (sii
->pub
.buscoretype
== PCIE_CORE_ID
) {
2198 (sbpcieregs_t
*) si_setcore(&sii
->pub
, PCIE_CORE_ID
, 0);
2200 ASSERT(pcieregs
!= NULL
);
2201 reg16
= &pcieregs
->sprom
[SRSH_PI_OFFSET
];
2202 } else if (sii
->pub
.buscoretype
== PCI_CORE_ID
) {
2203 pciregs
= (sbpciregs_t
*) si_setcore(&sii
->pub
, PCI_CORE_ID
, 0);
2205 ASSERT(pciregs
!= NULL
);
2206 reg16
= &pciregs
->sprom
[SRSH_PI_OFFSET
];
2208 pciidx
= si_coreidx(&sii
->pub
);
2209 val16
= R_REG(sii
->osh
, reg16
);
2210 if (((val16
& SRSH_PI_MASK
) >> SRSH_PI_SHIFT
) != (u16
) pciidx
) {
2212 (u16
) (pciidx
<< SRSH_PI_SHIFT
) | (val16
&
2214 W_REG(sii
->osh
, reg16
, val16
);
2217 /* restore the original index */
2218 si_setcoreidx(&sii
->pub
, origidx
);
2220 pcicore_hwup(sii
->pch
);
2224 /* change logical "focus" to the gpio core for optimized access */
2225 void *si_gpiosetcore(si_t
*sih
)
2227 return si_setcoreidx(sih
, SI_CC_IDX
);
2230 /* mask&set gpiocontrol bits */
2231 uint32
si_gpiocontrol(si_t
*sih
, uint32 mask
, uint32 val
, u8 priority
)
2237 /* gpios could be shared on router platforms
2238 * ignore reservation if it's high priority (e.g., test apps)
2240 if ((priority
!= GPIO_HI_PRIORITY
) &&
2241 (BUSTYPE(sih
->bustype
) == SI_BUS
) && (val
|| mask
)) {
2242 mask
= priority
? (si_gpioreservation
& mask
) :
2243 ((si_gpioreservation
| mask
) & ~(si_gpioreservation
));
2247 regoff
= OFFSETOF(chipcregs_t
, gpiocontrol
);
2248 return si_corereg(sih
, SI_CC_IDX
, regoff
, mask
, val
);
2251 /* mask&set gpio output enable bits */
2252 uint32
si_gpioouten(si_t
*sih
, uint32 mask
, uint32 val
, u8 priority
)
2258 /* gpios could be shared on router platforms
2259 * ignore reservation if it's high priority (e.g., test apps)
2261 if ((priority
!= GPIO_HI_PRIORITY
) &&
2262 (BUSTYPE(sih
->bustype
) == SI_BUS
) && (val
|| mask
)) {
2263 mask
= priority
? (si_gpioreservation
& mask
) :
2264 ((si_gpioreservation
| mask
) & ~(si_gpioreservation
));
2268 regoff
= OFFSETOF(chipcregs_t
, gpioouten
);
2269 return si_corereg(sih
, SI_CC_IDX
, regoff
, mask
, val
);
2272 /* mask&set gpio output bits */
2273 uint32
si_gpioout(si_t
*sih
, uint32 mask
, uint32 val
, u8 priority
)
2279 /* gpios could be shared on router platforms
2280 * ignore reservation if it's high priority (e.g., test apps)
2282 if ((priority
!= GPIO_HI_PRIORITY
) &&
2283 (BUSTYPE(sih
->bustype
) == SI_BUS
) && (val
|| mask
)) {
2284 mask
= priority
? (si_gpioreservation
& mask
) :
2285 ((si_gpioreservation
| mask
) & ~(si_gpioreservation
));
2289 regoff
= OFFSETOF(chipcregs_t
, gpioout
);
2290 return si_corereg(sih
, SI_CC_IDX
, regoff
, mask
, val
);
2293 /* reserve one gpio */
2294 uint32
si_gpioreserve(si_t
*sih
, uint32 gpio_bitmask
, u8 priority
)
2300 /* only cores on SI_BUS share GPIO's and only applcation users need to
2301 * reserve/release GPIO
2303 if ((BUSTYPE(sih
->bustype
) != SI_BUS
) || (!priority
)) {
2304 ASSERT((BUSTYPE(sih
->bustype
) == SI_BUS
) && (priority
));
2307 /* make sure only one bit is set */
2308 if ((!gpio_bitmask
) || ((gpio_bitmask
) & (gpio_bitmask
- 1))) {
2309 ASSERT((gpio_bitmask
)
2310 && !((gpio_bitmask
) & (gpio_bitmask
- 1)));
2314 /* already reserved */
2315 if (si_gpioreservation
& gpio_bitmask
)
2317 /* set reservation */
2318 si_gpioreservation
|= gpio_bitmask
;
2320 return si_gpioreservation
;
2323 /* release one gpio */
2325 * releasing the gpio doesn't change the current value on the GPIO last write value
2326 * persists till some one overwrites it
2329 uint32
si_gpiorelease(si_t
*sih
, uint32 gpio_bitmask
, u8 priority
)
2335 /* only cores on SI_BUS share GPIO's and only applcation users need to
2336 * reserve/release GPIO
2338 if ((BUSTYPE(sih
->bustype
) != SI_BUS
) || (!priority
)) {
2339 ASSERT((BUSTYPE(sih
->bustype
) == SI_BUS
) && (priority
));
2342 /* make sure only one bit is set */
2343 if ((!gpio_bitmask
) || ((gpio_bitmask
) & (gpio_bitmask
- 1))) {
2344 ASSERT((gpio_bitmask
)
2345 && !((gpio_bitmask
) & (gpio_bitmask
- 1)));
2349 /* already released */
2350 if (!(si_gpioreservation
& gpio_bitmask
))
2353 /* clear reservation */
2354 si_gpioreservation
&= ~gpio_bitmask
;
2356 return si_gpioreservation
;
2359 /* return the current gpioin register value */
2360 uint32
si_gpioin(si_t
*sih
)
2368 regoff
= OFFSETOF(chipcregs_t
, gpioin
);
2369 return si_corereg(sih
, SI_CC_IDX
, regoff
, 0, 0);
2372 /* mask&set gpio interrupt polarity bits */
2373 uint32
si_gpiointpolarity(si_t
*sih
, uint32 mask
, uint32 val
, u8 priority
)
2381 /* gpios could be shared on router platforms */
2382 if ((BUSTYPE(sih
->bustype
) == SI_BUS
) && (val
|| mask
)) {
2383 mask
= priority
? (si_gpioreservation
& mask
) :
2384 ((si_gpioreservation
| mask
) & ~(si_gpioreservation
));
2388 regoff
= OFFSETOF(chipcregs_t
, gpiointpolarity
);
2389 return si_corereg(sih
, SI_CC_IDX
, regoff
, mask
, val
);
2392 /* mask&set gpio interrupt mask bits */
2393 uint32
si_gpiointmask(si_t
*sih
, uint32 mask
, uint32 val
, u8 priority
)
2401 /* gpios could be shared on router platforms */
2402 if ((BUSTYPE(sih
->bustype
) == SI_BUS
) && (val
|| mask
)) {
2403 mask
= priority
? (si_gpioreservation
& mask
) :
2404 ((si_gpioreservation
| mask
) & ~(si_gpioreservation
));
2408 regoff
= OFFSETOF(chipcregs_t
, gpiointmask
);
2409 return si_corereg(sih
, SI_CC_IDX
, regoff
, mask
, val
);
2412 /* assign the gpio to an led */
2413 uint32
si_gpioled(si_t
*sih
, uint32 mask
, uint32 val
)
2418 if (sih
->ccrev
< 16)
2421 /* gpio led powersave reg */
2423 (sih
, SI_CC_IDX
, OFFSETOF(chipcregs_t
, gpiotimeroutmask
), mask
,
2427 /* mask&set gpio timer val */
2428 uint32
si_gpiotimerval(si_t
*sih
, uint32 mask
, uint32 gpiotimerval
)
2434 if (sih
->ccrev
< 16)
2437 return si_corereg(sih
, SI_CC_IDX
,
2438 OFFSETOF(chipcregs_t
, gpiotimerval
), mask
,
2442 uint32
si_gpiopull(si_t
*sih
, bool updown
, uint32 mask
, uint32 val
)
2448 if (sih
->ccrev
< 20)
2452 (updown
? OFFSETOF(chipcregs_t
, gpiopulldown
) :
2453 OFFSETOF(chipcregs_t
, gpiopullup
));
2454 return si_corereg(sih
, SI_CC_IDX
, offs
, mask
, val
);
2457 uint32
si_gpioevent(si_t
*sih
, uint regtype
, uint32 mask
, uint32 val
)
2463 if (sih
->ccrev
< 11)
2466 if (regtype
== GPIO_REGEVT
)
2467 offs
= OFFSETOF(chipcregs_t
, gpioevent
);
2468 else if (regtype
== GPIO_REGEVT_INTMSK
)
2469 offs
= OFFSETOF(chipcregs_t
, gpioeventintmask
);
2470 else if (regtype
== GPIO_REGEVT_INTPOL
)
2471 offs
= OFFSETOF(chipcregs_t
, gpioeventintpolarity
);
2475 return si_corereg(sih
, SI_CC_IDX
, offs
, mask
, val
);
2478 void *BCMATTACHFN(si_gpio_handler_register
) (si_t
*sih
, uint32 event
,
2479 bool level
, gpio_handler_t cb
,
2488 if (sih
->ccrev
< 11)
2491 gi
= MALLOC(sii
->osh
, sizeof(gpioh_item_t
));
2495 bzero(gi
, sizeof(gpioh_item_t
));
2501 gi
->next
= sii
->gpioh_head
;
2502 sii
->gpioh_head
= gi
;
2504 return (void *)(gi
);
2507 void BCMATTACHFN(si_gpio_handler_unregister
) (si_t
*sih
, void *gpioh
)
2510 gpioh_item_t
*p
, *n
;
2513 if (sih
->ccrev
< 11)
2516 ASSERT(sii
->gpioh_head
!= NULL
);
2517 if ((void *)sii
->gpioh_head
== gpioh
) {
2518 sii
->gpioh_head
= sii
->gpioh_head
->next
;
2519 MFREE(sii
->osh
, gpioh
, sizeof(gpioh_item_t
));
2522 p
= sii
->gpioh_head
;
2525 if ((void *)n
== gpioh
) {
2527 MFREE(sii
->osh
, gpioh
, sizeof(gpioh_item_t
));
2535 ASSERT(0); /* Not found in list */
2538 void si_gpio_handler_process(si_t
*sih
)
2543 uint32 level
= si_gpioin(sih
);
2544 uint32 edge
= si_gpioevent(sih
, GPIO_REGEVT
, 0, 0);
2547 for (h
= sii
->gpioh_head
; h
!= NULL
; h
= h
->next
) {
2549 status
= (h
->level
? level
: edge
);
2551 if (status
& h
->event
)
2552 h
->handler(status
, h
->arg
);
2556 si_gpioevent(sih
, GPIO_REGEVT
, edge
, edge
); /* clear edge-trigger status */
2559 uint32
si_gpio_int_enable(si_t
*sih
, bool enable
)
2565 if (sih
->ccrev
< 11)
2568 offs
= OFFSETOF(chipcregs_t
, intmask
);
2570 (sih
, SI_CC_IDX
, offs
, CI_GPIO
, (enable
? CI_GPIO
: 0));
2573 /* Return the size of the specified SOCRAM bank */
2575 socram_banksize(si_info_t
*sii
, sbsocramregs_t
*regs
, u8 index
,
2578 uint banksize
, bankinfo
;
2579 uint bankidx
= index
| (mem_type
<< SOCRAM_BANKIDX_MEMTYPE_SHIFT
);
2581 ASSERT(mem_type
<= SOCRAM_MEMTYPE_DEVRAM
);
2583 W_REG(sii
->osh
, ®s
->bankidx
, bankidx
);
2584 bankinfo
= R_REG(sii
->osh
, ®s
->bankinfo
);
2586 SOCRAM_BANKINFO_SZBASE
* ((bankinfo
& SOCRAM_BANKINFO_SZMASK
) + 1);
2590 void si_socdevram(si_t
*sih
, bool set
, u8
*enable
, u8
*protect
)
2595 sbsocramregs_t
*regs
;
2601 /* Block ints and save current core */
2602 INTR_OFF(sii
, intr_val
);
2603 origidx
= si_coreidx(sih
);
2606 *enable
= *protect
= 0;
2608 /* Switch to SOCRAM core */
2609 regs
= si_setcore(sih
, SOCRAM_CORE_ID
, 0);
2613 /* Get info for determining size */
2614 wasup
= si_iscoreup(sih
);
2616 si_core_reset(sih
, 0, 0);
2618 corerev
= si_corerev(sih
);
2619 if (corerev
>= 10) {
2623 uint32 bankidx
, bankinfo
;
2625 extcinfo
= R_REG(sii
->osh
, ®s
->extracoreinfo
);
2626 nb
= ((extcinfo
& SOCRAM_DEVRAMBANK_MASK
) >>
2627 SOCRAM_DEVRAMBANK_SHIFT
);
2628 for (i
= 0; i
< nb
; i
++) {
2630 i
| (SOCRAM_MEMTYPE_DEVRAM
<<
2631 SOCRAM_BANKIDX_MEMTYPE_SHIFT
);
2632 W_REG(sii
->osh
, ®s
->bankidx
, bankidx
);
2633 bankinfo
= R_REG(sii
->osh
, ®s
->bankinfo
);
2635 bankinfo
&= ~SOCRAM_BANKINFO_DEVRAMSEL_MASK
;
2636 bankinfo
&= ~SOCRAM_BANKINFO_DEVRAMPRO_MASK
;
2640 SOCRAM_BANKINFO_DEVRAMSEL_SHIFT
);
2644 SOCRAM_BANKINFO_DEVRAMPRO_SHIFT
);
2646 W_REG(sii
->osh
, ®s
->bankinfo
, bankinfo
);
2647 } else if (i
== 0) {
2648 if (bankinfo
& SOCRAM_BANKINFO_DEVRAMSEL_MASK
) {
2651 SOCRAM_BANKINFO_DEVRAMPRO_MASK
)
2658 /* Return to previous state and core */
2660 si_core_disable(sih
, 0);
2661 si_setcoreidx(sih
, origidx
);
2664 INTR_RESTORE(sii
, intr_val
);
2667 bool si_socdevram_pkg(si_t
*sih
)
2669 if (si_socdevram_size(sih
) > 0)
2675 uint32
si_socdevram_size(si_t
*sih
)
2681 sbsocramregs_t
*regs
;
2687 /* Block ints and save current core */
2688 INTR_OFF(sii
, intr_val
);
2689 origidx
= si_coreidx(sih
);
2691 /* Switch to SOCRAM core */
2692 regs
= si_setcore(sih
, SOCRAM_CORE_ID
, 0);
2696 /* Get info for determining size */
2697 wasup
= si_iscoreup(sih
);
2699 si_core_reset(sih
, 0, 0);
2701 corerev
= si_corerev(sih
);
2702 if (corerev
>= 10) {
2707 extcinfo
= R_REG(sii
->osh
, ®s
->extracoreinfo
);
2708 nb
= (((extcinfo
& SOCRAM_DEVRAMBANK_MASK
) >>
2709 SOCRAM_DEVRAMBANK_SHIFT
));
2710 for (i
= 0; i
< nb
; i
++)
2712 socram_banksize(sii
, regs
, i
,
2713 SOCRAM_MEMTYPE_DEVRAM
);
2716 /* Return to previous state and core */
2718 si_core_disable(sih
, 0);
2719 si_setcoreidx(sih
, origidx
);
2722 INTR_RESTORE(sii
, intr_val
);
2727 /* Return the RAM size of the SOCRAM core */
2728 uint32
si_socram_size(si_t
*sih
)
2734 sbsocramregs_t
*regs
;
2742 /* Block ints and save current core */
2743 INTR_OFF(sii
, intr_val
);
2744 origidx
= si_coreidx(sih
);
2746 /* Switch to SOCRAM core */
2747 regs
= si_setcore(sih
, SOCRAM_CORE_ID
, 0);
2751 /* Get info for determining size */
2752 wasup
= si_iscoreup(sih
);
2754 si_core_reset(sih
, 0, 0);
2755 corerev
= si_corerev(sih
);
2756 coreinfo
= R_REG(sii
->osh
, ®s
->coreinfo
);
2758 /* Calculate size from coreinfo based on rev */
2760 memsize
= 1 << (16 + (coreinfo
& SRCI_MS0_MASK
));
2761 else if (corerev
< 3) {
2762 memsize
= 1 << (SR_BSZ_BASE
+ (coreinfo
& SRCI_SRBSZ_MASK
));
2763 memsize
*= (coreinfo
& SRCI_SRNB_MASK
) >> SRCI_SRNB_SHIFT
;
2764 } else if ((corerev
<= 7) || (corerev
== 12)) {
2765 uint nb
= (coreinfo
& SRCI_SRNB_MASK
) >> SRCI_SRNB_SHIFT
;
2766 uint bsz
= (coreinfo
& SRCI_SRBSZ_MASK
);
2767 uint lss
= (coreinfo
& SRCI_LSS_MASK
) >> SRCI_LSS_SHIFT
;
2770 memsize
= nb
* (1 << (bsz
+ SR_BSZ_BASE
));
2772 memsize
+= (1 << ((lss
- 1) + SR_BSZ_BASE
));
2775 uint nb
= (coreinfo
& SRCI_SRNB_MASK
) >> SRCI_SRNB_SHIFT
;
2776 for (i
= 0; i
< nb
; i
++)
2778 socram_banksize(sii
, regs
, i
, SOCRAM_MEMTYPE_RAM
);
2781 /* Return to previous state and core */
2783 si_core_disable(sih
, 0);
2784 si_setcoreidx(sih
, origidx
);
2787 INTR_RESTORE(sii
, intr_val
);
2792 void si_chipcontrl_epa4331(si_t
*sih
, bool on
)
2800 origidx
= si_coreidx(sih
);
2802 cc
= (chipcregs_t
*) si_setcore(sih
, CC_CORE_ID
, 0);
2804 val
= R_REG(sii
->osh
, &cc
->chipcontrol
);
2807 if (sih
->chippkg
== 9 || sih
->chippkg
== 0xb) {
2808 /* Ext PA Controls for 4331 12x9 Package */
2809 W_REG(sii
->osh
, &cc
->chipcontrol
, val
|
2810 (CCTRL4331_EXTPA_EN
|
2811 CCTRL4331_EXTPA_ON_GPIO2_5
));
2813 /* Ext PA Controls for 4331 12x12 Package */
2814 W_REG(sii
->osh
, &cc
->chipcontrol
,
2815 val
| (CCTRL4331_EXTPA_EN
));
2818 val
&= ~(CCTRL4331_EXTPA_EN
| CCTRL4331_EXTPA_ON_GPIO2_5
);
2819 W_REG(sii
->osh
, &cc
->chipcontrol
, val
);
2822 si_setcoreidx(sih
, origidx
);
2825 /* Enable BT-COEX & Ex-PA for 4313 */
2826 void si_epa_4313war(si_t
*sih
)
2833 origidx
= si_coreidx(sih
);
2835 cc
= (chipcregs_t
*) si_setcore(sih
, CC_CORE_ID
, 0);
2838 W_REG(sii
->osh
, &cc
->gpiocontrol
,
2839 R_REG(sii
->osh
, &cc
->gpiocontrol
) | GPIO_CTRL_EPA_EN_MASK
);
2841 si_setcoreidx(sih
, origidx
);
2844 /* check if the device is removed */
2845 bool si_deviceremoved(si_t
*sih
)
2852 switch (BUSTYPE(sih
->bustype
)) {
2854 ASSERT(sii
->osh
!= NULL
);
2855 w
= OSL_PCI_READ_CONFIG(sii
->osh
, PCI_CFG_VID
, sizeof(uint32
));
2856 if ((w
& 0xFFFF) != VENDOR_BROADCOM
)
2863 bool si_is_sprom_available(si_t
*sih
)
2865 if (sih
->ccrev
>= 31) {
2871 if ((sih
->cccaps
& CC_CAP_SROM
) == 0)
2875 origidx
= sii
->curidx
;
2876 cc
= si_setcoreidx(sih
, SI_CC_IDX
);
2877 sromctrl
= R_REG(sii
->osh
, &cc
->sromcontrol
);
2878 si_setcoreidx(sih
, origidx
);
2879 return sromctrl
& SRC_PRESENT
;
2882 switch (CHIPID(sih
->chip
)) {
2883 case BCM4329_CHIP_ID
:
2884 return (sih
->chipst
& CST4329_SPROM_SEL
) != 0;
2885 case BCM4319_CHIP_ID
:
2886 return (sih
->chipst
& CST4319_SPROM_SEL
) != 0;
2887 case BCM4336_CHIP_ID
:
2888 return (sih
->chipst
& CST4336_SPROM_PRESENT
) != 0;
2889 case BCM4330_CHIP_ID
:
2890 return (sih
->chipst
& CST4330_SPROM_PRESENT
) != 0;
2891 case BCM4313_CHIP_ID
:
2892 return (sih
->chipst
& CST4313_SPROM_PRESENT
) != 0;
2893 case BCM4331_CHIP_ID
:
2894 return (sih
->chipst
& CST4331_SPROM_PRESENT
) != 0;
2900 bool si_is_otp_disabled(si_t
*sih
)
2902 switch (CHIPID(sih
->chip
)) {
2903 case BCM4329_CHIP_ID
:
2904 return (sih
->chipst
& CST4329_SPROM_OTP_SEL_MASK
) ==
2906 case BCM4319_CHIP_ID
:
2907 return (sih
->chipst
& CST4319_SPROM_OTP_SEL_MASK
) ==
2909 case BCM4336_CHIP_ID
:
2910 return (sih
->chipst
& CST4336_OTP_PRESENT
) == 0;
2911 case BCM4330_CHIP_ID
:
2912 return (sih
->chipst
& CST4330_OTP_PRESENT
) == 0;
2913 case BCM4313_CHIP_ID
:
2914 return (sih
->chipst
& CST4313_OTP_PRESENT
) == 0;
2915 /* These chips always have their OTP on */
2916 case BCM43224_CHIP_ID
:
2917 case BCM43225_CHIP_ID
:
2918 case BCM43421_CHIP_ID
:
2919 case BCM43235_CHIP_ID
:
2920 case BCM43236_CHIP_ID
:
2921 case BCM43238_CHIP_ID
:
2922 case BCM4331_CHIP_ID
:
2928 bool si_is_otp_powered(si_t
*sih
)
2930 if (PMUCTL_ENAB(sih
))
2931 return si_pmu_is_otp_powered(sih
, si_osh(sih
));
2935 void si_otp_power(si_t
*sih
, bool on
)
2937 if (PMUCTL_ENAB(sih
))
2938 si_pmu_otp_power(sih
, si_osh(sih
), on
);
2944 si_is_sprom_enabled(si_t
*sih
)
2946 BCMATTACHFN(si_is_sprom_enabled
) (si_t
*sih
)
2955 si_sprom_enable(si_t
*sih
, bool enable
)
2957 BCMATTACHFN(si_sprom_enable
) (si_t
*sih
, bool enable
)
2960 if (PMUCTL_ENAB(sih
))
2961 si_pmu_sprom_enable(sih
, si_osh(sih
), enable
);
2964 /* Return BCME_NOTFOUND if the card doesn't have CIS format nvram */
2965 int si_cis_source(si_t
*sih
)
2967 /* Many chips have the same mapping of their chipstatus field */
2968 static const uint cis_sel
[] = {
2969 CIS_DEFAULT
, CIS_SROM
, CIS_OTP
, CIS_SROM
};
2970 static const uint cis_43236_sel
[] = {
2971 CIS_DEFAULT
, CIS_SROM
, CIS_OTP
, CIS_OTP
};
2973 /* PCI chips use SROM format instead of CIS */
2974 if (BUSTYPE(sih
->bustype
) == PCI_BUS
)
2975 return BCME_NOTFOUND
;
2977 switch (CHIPID(sih
->chip
)) {
2978 case BCM43235_CHIP_ID
:
2979 case BCM43236_CHIP_ID
:
2980 case BCM43238_CHIP_ID
:{
2983 chipst
& CST4322_SPROM_OTP_SEL_MASK
) >>
2984 CST4322_SPROM_OTP_SEL_SHIFT
;
2986 sizeof(cis_sel
)) ? CIS_DEFAULT
:
2987 cis_43236_sel
[strap
]);
2990 case BCM4329_CHIP_ID
:
2991 return ((sih
->chipst
& CST4329_SPROM_OTP_SEL_MASK
) >=
2992 sizeof(cis_sel
)) ? CIS_DEFAULT
: cis_sel
[(sih
->
2994 CST4329_SPROM_OTP_SEL_MASK
)];
2995 case BCM4319_CHIP_ID
:{
2998 chipst
& CST4319_SPROM_OTP_SEL_MASK
) >>
2999 CST4319_SPROM_OTP_SEL_SHIFT
);
3000 return (cis_sel4319
>=
3001 sizeof(cis_sel
)) ? CIS_DEFAULT
:
3002 cis_sel
[cis_sel4319
];
3004 case BCM4336_CHIP_ID
:{
3005 if (sih
->chipst
& CST4336_SPROM_PRESENT
)
3007 if (sih
->chipst
& CST4336_OTP_PRESENT
)
3011 case BCM4330_CHIP_ID
:{
3012 if (sih
->chipst
& CST4330_SPROM_PRESENT
)
3014 if (sih
->chipst
& CST4330_OTP_PRESENT
)