2 * Misc utility routines for accessing chip-specific features
3 * of the SiliconBackplane-based Broadcom chips.
5 * Copyright (C) 2011, Broadcom Corporation. All Rights Reserved.
7 * Permission to use, copy, modify, and/or distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
14 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
16 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
17 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19 * $Id: siutils.c 330112 2012-04-27 22:31:26Z $
32 #include <pcie_core.h>
45 #if !defined(BCM_BOOTLOADER) && defined(SAVERESTORE)
46 #include <saverestore.h>
49 #include "siutils_priv.h"
51 /* local prototypes */
52 static si_info_t
*si_doattach(si_info_t
*sii
, uint devid
, osl_t
*osh
, void *regs
,
53 uint bustype
, void *sdh
, char **vars
, uint
*varsz
);
54 static bool si_buscore_prep(si_info_t
*sii
, uint bustype
, uint devid
, void *sdh
);
55 static bool si_buscore_setup(si_info_t
*sii
, chipcregs_t
*cc
, uint bustype
, uint32 savewin
,
56 uint
*origidx
, void *regs
);
58 static void si_nvram_process(si_info_t
*sii
, char *pvars
);
59 static void si_sromvars_fixup_4331(si_t
*sih
, char *pvars
);
61 /* dev path concatenation util */
62 static char *si_devpathvar(si_t
*sih
, char *var
, int len
, const char *name
);
63 static bool _si_clkctl_cc(si_info_t
*sii
, uint mode
);
64 static bool si_ispcie(si_info_t
*sii
);
65 static uint
BCMINITFN(socram_banksize
)(si_info_t
*sii
, sbsocramregs_t
*r
, uint8 idx
, uint8 mtype
);
68 /* global variable to indicate reservation/release of gpio's */
69 static uint32 si_gpioreservation
= 0;
71 /* global flag to prevent shared resources from being initialized multiple times in si_attach() */
73 int do_4360_pcie2_war
= 0;
76 * Allocate a si handle.
77 * devid - pci device id (used to determine chip#)
78 * osh - opaque OS handle
79 * regs - virtual address of initial core registers
80 * bustype - pci/pcmcia/sb/sdio/etc
81 * vars - pointer to a pointer area for "environment" variables
82 * varsz - pointer to int to return the size of the vars
85 BCMATTACHFN(si_attach
)(uint devid
, osl_t
*osh
, void *regs
,
86 uint bustype
, void *sdh
, char **vars
, uint
*varsz
)
91 if ((sii
= MALLOC(osh
, sizeof (si_info_t
))) == NULL
) {
92 SI_ERROR(("si_attach: malloc failed! malloced %d bytes\n", MALLOCED(osh
)));
96 if (si_doattach(sii
, devid
, osh
, regs
, bustype
, sdh
, vars
, varsz
) == NULL
) {
97 MFREE(osh
, sii
, sizeof(si_info_t
));
100 sii
->vars
= vars
? *vars
: NULL
;
101 sii
->varsz
= varsz
? *varsz
: 0;
106 /* global kernel resource */
107 static si_info_t ksii
;
109 static uint32 wd_msticks
; /* watchdog timer ticks normalized to ms */
111 /* generic kernel variant of si_attach() */
113 BCMATTACHFN(si_kattach
)(osl_t
*osh
)
115 static bool ksii_attached
= FALSE
;
117 if (!ksii_attached
) {
119 #ifndef SI_ENUM_BASE_VARIABLE
120 regs
= REG_MAP(SI_ENUM_BASE
, SI_CORE_SIZE
);
123 if (si_doattach(&ksii
, BCM4710_DEVICE_ID
, osh
, regs
,
125 osh
!= SI_OSH
? &ksii
.vars
: NULL
,
126 osh
!= SI_OSH
? &ksii
.varsz
: NULL
) == NULL
) {
127 SI_ERROR(("si_kattach: si_doattach failed\n"));
133 /* save ticks normalized to ms for si_watchdog_ms() */
134 if (PMUCTL_ENAB(&ksii
.pub
)) {
135 if (CHIPID(ksii
.pub
.chip
) == BCM4706_CHIP_ID
) {
136 /* 4706 CC and PMU watchdogs are clocked at 1/4 of ALP clock */
137 wd_msticks
= (si_alp_clock(&ksii
.pub
) / 4) / 1000;
140 /* based on 32KHz ILP clock */
143 if (ksii
.pub
.ccrev
< 18)
144 wd_msticks
= si_clock(&ksii
.pub
) / 1000;
146 wd_msticks
= si_alp_clock(&ksii
.pub
) / 1000;
149 ksii_attached
= TRUE
;
150 SI_MSG(("si_kattach done. ccrev = %d, wd_msticks = %d\n",
151 ksii
.pub
.ccrev
, wd_msticks
));
158 si_ldo_war(si_t
*sih
, uint devid
)
160 si_info_t
*sii
= SI_INFO(sih
);
163 void *regs
= sii
->curmap
;
166 rev_id
= OSL_PCI_READ_CONFIG(sii
->osh
, PCI_CFG_REV
, sizeof(uint32
));
168 if (!(((CHIPID(devid
) == BCM4322_CHIP_ID
) ||
169 (CHIPID(devid
) == BCM4342_CHIP_ID
) ||
170 (CHIPID(devid
) == BCM4322_D11N_ID
) ||
171 (CHIPID(devid
) == BCM4322_D11N2G_ID
) ||
172 (CHIPID(devid
) == BCM4322_D11N5G_ID
)) &&
176 SI_MSG(("si_ldo_war: PCI devid 0x%x rev %d, HACK to fix 4322a0 LDO/PMU\n", devid
, rev_id
));
178 /* switch to chipcommon */
179 w
= OSL_PCI_READ_CONFIG(sii
->osh
, PCI_BAR0_WIN
, sizeof(uint32
));
180 OSL_PCI_WRITE_CONFIG(sii
->osh
, PCI_BAR0_WIN
, sizeof(uint32
), SI_ENUM_BASE
);
181 cc
= (chipcregs_t
*)regs
;
183 /* clear bit 7 to fix LDO
184 * write to register *blindly* WITHOUT read since read may timeout
185 * because the default clock is 32k ILP
187 W_REG(sii
->osh
, &cc
->regcontrol_addr
, 0);
188 /* AND_REG(sii->osh, &cc->regcontrol_data, ~0x80); */
189 W_REG(sii
->osh
, &cc
->regcontrol_data
, 0x3001);
193 /* request ALP_AVAIL through PMU to move sb out of ILP */
194 W_REG(sii
->osh
, &cc
->min_res_mask
, 0x0d);
196 SPINWAIT(((ccst
= OSL_PCI_READ_CONFIG(sii
->osh
, PCI_CLK_CTL_ST
, 4)) & CCS_ALPAVAIL
)
197 == 0, PMU_MAX_TRANSITION_DLY
);
199 if ((ccst
& CCS_ALPAVAIL
) == 0) {
200 SI_ERROR(("ALP never came up clk_ctl_st: 0x%x\n", ccst
));
203 SI_MSG(("si_ldo_war: 4322a0 HACK done\n"));
205 OSL_PCI_WRITE_CONFIG(sii
->osh
, PCI_BAR0_WIN
, sizeof(uint32
), w
);
211 BCMATTACHFN(si_buscore_prep
)(si_info_t
*sii
, uint bustype
, uint devid
, void *sdh
)
213 /* need to set memseg flag for CF card first before any sb registers access */
214 if (BUSTYPE(bustype
) == PCMCIA_BUS
)
217 if (BUSTYPE(bustype
) == PCI_BUS
) {
218 if (!si_ldo_war((si_t
*)sii
, devid
))
222 /* kludge to enable the clock on the 4306 which lacks a slowclock */
223 if (BUSTYPE(bustype
) == PCI_BUS
&& !si_ispcie(sii
))
224 si_clkctl_xtal(&sii
->pub
, XTAL
|PLL
, ON
);
231 BCMATTACHFN(si_buscore_setup
)(si_info_t
*sii
, chipcregs_t
*cc
, uint bustype
, uint32 savewin
,
232 uint
*origidx
, void *regs
)
234 bool pci
, pcie
, pcie_gen2
= FALSE
;
236 uint pciidx
, pcieidx
, pcirev
, pcierev
;
238 cc
= si_setcoreidx(&sii
->pub
, SI_CC_IDX
);
241 /* get chipcommon rev */
242 sii
->pub
.ccrev
= (int)si_corerev(&sii
->pub
);
244 /* get chipcommon chipstatus */
245 if (sii
->pub
.ccrev
>= 11)
246 sii
->pub
.chipst
= R_REG(sii
->osh
, &cc
->chipstatus
);
248 /* get chipcommon capabilites */
249 sii
->pub
.cccaps
= R_REG(sii
->osh
, &cc
->capabilities
);
250 /* get chipcommon extended capabilities */
252 if (sii
->pub
.ccrev
>= 35)
253 sii
->pub
.cccaps_ext
= R_REG(sii
->osh
, &cc
->capabilities_ext
);
255 /* get pmu rev and caps */
256 if (sii
->pub
.cccaps
& CC_CAP_PMU
) {
257 sii
->pub
.pmucaps
= R_REG(sii
->osh
, &cc
->pmucapabilities
);
258 sii
->pub
.pmurev
= sii
->pub
.pmucaps
& PCAP_REV_MASK
;
261 SI_MSG(("Chipc: rev %d, caps 0x%x, chipst 0x%x pmurev %d, pmucaps 0x%x\n",
262 sii
->pub
.ccrev
, sii
->pub
.cccaps
, sii
->pub
.chipst
, sii
->pub
.pmurev
,
265 /* figure out bus/orignal core idx */
266 sii
->pub
.buscoretype
= NODEV_CORE_ID
;
267 sii
->pub
.buscorerev
= (uint
)NOREV
;
268 sii
->pub
.buscoreidx
= BADIDX
;
271 pcirev
= pcierev
= (uint
)NOREV
;
272 pciidx
= pcieidx
= BADIDX
;
274 for (i
= 0; i
< sii
->numcores
; i
++) {
277 si_setcoreidx(&sii
->pub
, i
);
278 cid
= si_coreid(&sii
->pub
);
279 crev
= si_corerev(&sii
->pub
);
281 /* Display cores found */
282 SI_VMSG(("CORE[%d]: id 0x%x rev %d base 0x%x regs 0x%p\n",
283 i
, cid
, crev
, sii
->coresba
[i
], sii
->regs
[i
]));
285 if (BUSTYPE(bustype
) == PCI_BUS
) {
286 if (cid
== PCI_CORE_ID
) {
290 } else if ((cid
== PCIE_CORE_ID
) || (cid
== PCIE2_CORE_ID
)) {
294 if (cid
== PCIE2_CORE_ID
)
297 } else if ((BUSTYPE(bustype
) == PCMCIA_BUS
) &&
298 (cid
== PCMCIA_CORE_ID
)) {
299 sii
->pub
.buscorerev
= crev
;
300 sii
->pub
.buscoretype
= cid
;
301 sii
->pub
.buscoreidx
= i
;
304 /* find the core idx before entering this func. */
305 if ((savewin
&& (savewin
== sii
->coresba
[i
])) ||
306 (regs
== sii
->regs
[i
]))
317 sii
->pub
.buscoretype
= PCI_CORE_ID
;
318 sii
->pub
.buscorerev
= pcirev
;
319 sii
->pub
.buscoreidx
= pciidx
;
322 sii
->pub
.buscoretype
= PCIE2_CORE_ID
;
324 sii
->pub
.buscoretype
= PCIE_CORE_ID
;
325 sii
->pub
.buscorerev
= pcierev
;
326 sii
->pub
.buscoreidx
= pcieidx
;
329 SI_VMSG(("Buscore id/type/rev %d/0x%x/%d\n", sii
->pub
.buscoreidx
, sii
->pub
.buscoretype
,
330 sii
->pub
.buscorerev
));
332 if (BUSTYPE(sii
->pub
.bustype
) == SI_BUS
&& (CHIPID(sii
->pub
.chip
) == BCM4712_CHIP_ID
) &&
333 (sii
->pub
.chippkg
!= BCM4712LARGE_PKG_ID
) && (CHIPREV(sii
->pub
.chiprev
) <= 3))
334 OR_REG(sii
->osh
, &cc
->slow_clk_ctl
, SCC_SS_XTAL
);
336 /* fixup necessary chip/core configurations */
337 if (BUSTYPE(sii
->pub
.bustype
) == PCI_BUS
) {
340 ((sii
->pch
= (void *)(uintptr
)pcicore_init(&sii
->pub
, sii
->osh
,
341 (void *)PCIEREGS(sii
))) == NULL
))
344 if (si_pci_fixcfg(&sii
->pub
)) {
345 SI_ERROR(("si_doattach: si_pci_fixcfg failed\n"));
351 /* return to the original core */
352 si_setcoreidx(&sii
->pub
, *origidx
);
358 BCMATTACHFN(si_nvram_process
)(si_info_t
*sii
, char *pvars
)
361 if (BUSTYPE(sii
->pub
.bustype
) == PCMCIA_BUS
) {
362 w
= getintvar(pvars
, "regwindowsz");
363 sii
->memseg
= (w
<= CFTABLE_REGWIN_2K
) ? TRUE
: FALSE
;
366 /* get boardtype and boardrev */
367 switch (BUSTYPE(sii
->pub
.bustype
)) {
369 /* do a pci config read to get subsystem id and subvendor id */
370 w
= OSL_PCI_READ_CONFIG(sii
->osh
, PCI_CFG_SVID
, sizeof(uint32
));
371 /* Let nvram variables override subsystem Vend/ID */
372 if ((sii
->pub
.boardvendor
= (uint16
)si_getdevpathintvar(&sii
->pub
, "boardvendor"))
375 if ((w
& 0xffff) == 0)
376 sii
->pub
.boardvendor
= VENDOR_BROADCOM
;
378 #endif /* !BCMHOSTVARS */
379 sii
->pub
.boardvendor
= w
& 0xffff;
382 SI_ERROR(("Overriding boardvendor: 0x%x instead of 0x%x\n",
383 sii
->pub
.boardvendor
, w
& 0xffff));
384 if ((sii
->pub
.boardtype
= (uint16
)si_getdevpathintvar(&sii
->pub
, "boardtype"))
386 if ((sii
->pub
.boardtype
= getintvar(pvars
, "boardtype")) == 0)
387 sii
->pub
.boardtype
= (w
>> 16) & 0xffff;
390 SI_ERROR(("Overriding boardtype: 0x%x instead of 0x%x\n",
391 sii
->pub
.boardtype
, (w
>> 16) & 0xffff));
395 sii
->pub
.boardvendor
= getintvar(pvars
, "manfid");
396 sii
->pub
.boardtype
= getintvar(pvars
, "prodid");
402 sii
->pub
.boardvendor
= VENDOR_BROADCOM
;
403 if (pvars
== NULL
|| ((sii
->pub
.boardtype
= getintvar(pvars
, "prodid")) == 0))
404 if ((sii
->pub
.boardtype
= getintvar(NULL
, "boardtype")) == 0)
405 sii
->pub
.boardtype
= 0xffff;
407 if (CHIPTYPE(sii
->pub
.socitype
) == SOCI_UBUS
) {
408 /* do a pci config read to get subsystem id and subvendor id */
409 w
= OSL_PCI_READ_CONFIG(sii
->osh
, PCI_CFG_SVID
, sizeof(uint32
));
410 sii
->pub
.boardvendor
= w
& 0xffff;
411 sii
->pub
.boardtype
= (w
>> 16) & 0xffff;
416 if (sii
->pub
.boardtype
== 0) {
417 SI_ERROR(("si_doattach: unknown board type\n"));
418 ASSERT(sii
->pub
.boardtype
);
421 sii
->pub
.boardrev
= getintvar(pvars
, "boardrev");
422 sii
->pub
.boardflags
= getintvar(pvars
, "boardflags");
426 BCMATTACHFN(si_sromvars_fixup_4331
)(si_t
*sih
, char *pvars
)
429 const char *sromvars
[] =
430 {"extpagain2g", "extpagain5g"};
431 int sromvars_size
= sizeof(sromvars
)/sizeof(char *);
433 uint boardtype
= sih
->boardtype
;
434 uint boardrev
= sih
->boardrev
;
435 bool update
= ((boardtype
== BCM94331BU_SSID
) ||
436 (boardtype
== BCM94331S9BU_SSID
) ||
437 (boardtype
== BCM94331MCI_SSID
) ||
438 (boardtype
== BCM94331MC_SSID
) ||
439 (boardtype
== BCM94331PCIEBT4_SSID
) ||
440 (boardtype
== BCM94331X19
&& boardrev
== 0x1100) ||
441 (boardtype
== BCM94331HM_SSID
&& boardrev
< 0x1152));
443 if (pvars
== NULL
|| !update
) {
447 for (ii
= 0; ii
< sromvars_size
; ii
++) {
448 char* val
= getvar(pvars
, sromvars
[ii
]);
450 while (val
&& *val
) {
457 #if defined(CONFIG_XIP) && defined(BCMTCAM)
458 extern uint8 patch_pair
;
459 #endif /* CONFIG_XIP && BCMTCAM */
465 } si_mux4335_uartopt_t
;
467 /* note: each index corr to MUXENAB4335_UART mask - 1 */
468 static const si_mux4335_uartopt_t
BCMATTACHDATA(mux4335_uartopt
)[] = {
469 {CC4335_PIN_GPIO_06
, CC4335_PIN_GPIO_02
},
470 {CC4335_PIN_GPIO_12
, CC4335_PIN_GPIO_13
},
471 {CC4335_PIN_SDIO_DATA0
, CC4335_PIN_SDIO_CMD
},
472 {CC4335_PIN_RF_SW_CTRL_9
, CC4335_PIN_RF_SW_CTRL_8
}
475 /* want to have this available all the time to switch mux for debugging */
477 BCMATTACHFN(si_muxenab
)(si_t
*sih
, uint32 w
)
479 uint32 chipcontrol
, pmu_chipcontrol
;
481 pmu_chipcontrol
= si_pmu_chipcontrol(sih
, 1, 0, 0);
482 chipcontrol
= si_corereg(sih
, SI_CC_IDX
, OFFSETOF(chipcregs_t
, chipcontrol
),
485 switch (CHIPID(sih
->chip
)) {
486 case BCM4330_CHIP_ID
:
488 chipcontrol
&= ~(CCTRL_4330_JTAG_DISABLE
| CCTRL_4330_ERCX_SEL
|
489 CCTRL_4330_GPIO_SEL
| CCTRL_4330_SDIO_HOST_WAKE
);
490 pmu_chipcontrol
&= ~PCTL_4330_SERIAL_ENAB
;
492 /* 4330 default is to have jtag enabled */
493 if (!(w
& MUXENAB_JTAG
))
494 chipcontrol
|= CCTRL_4330_JTAG_DISABLE
;
495 if (w
& MUXENAB_UART
)
496 pmu_chipcontrol
|= PCTL_4330_SERIAL_ENAB
;
497 if (w
& MUXENAB_GPIO
)
498 chipcontrol
|= CCTRL_4330_GPIO_SEL
;
499 if (w
& MUXENAB_ERCX
)
500 chipcontrol
|= CCTRL_4330_ERCX_SEL
;
501 if (w
& MUXENAB_HOST_WAKE
)
502 chipcontrol
|= CCTRL_4330_SDIO_HOST_WAKE
;
504 case BCM4336_CHIP_ID
:
505 if (w
& MUXENAB_UART
)
506 pmu_chipcontrol
|= PCTL_4336_SERIAL_ENAB
;
508 pmu_chipcontrol
&= ~PCTL_4336_SERIAL_ENAB
;
510 case BCM4360_CHIP_ID
:
511 case BCM43460_CHIP_ID
:
512 case BCM4352_CHIP_ID
:
513 if (w
& MUXENAB_UART
)
514 chipcontrol
|= CCTL_4360_UART_SEL
;
517 case BCM4335_CHIP_ID
:
518 /* drive default pins for UART. Note: 15 values possible;
519 * 0 means disabled; 1 means index to 0 in mux4335_uartopt
522 if (w
& MUXENAB4335_UART_MASK
) {
523 uint32 uart_rx
= 0, uart_tx
= 0;
524 uint8 uartopt_ix
= (w
& MUXENAB4335_UART_MASK
) - 1;
526 uart_rx
= mux4335_uartopt
[uartopt_ix
].uart_rx
;
527 uart_tx
= mux4335_uartopt
[uartopt_ix
].uart_tx
;
529 si_gci_set_functionsel(sih
, uart_rx
, CC4335_FNSEL_UART
);
530 si_gci_set_functionsel(sih
, uart_tx
, CC4335_FNSEL_UART
);
535 /* muxenab specified for an unsupported chip */
540 /* write both updated values to hw */
541 si_pmu_chipcontrol(sih
, 1, ~0, pmu_chipcontrol
);
542 si_corereg(sih
, SI_CC_IDX
, OFFSETOF(chipcregs_t
, chipcontrol
),
546 /* write 'val' to the gci chip control register indexed by 'reg' */
548 si_gci_chipcontrol(si_t
*sih
, uint reg
, uint32 mask
, uint32 val
)
550 /* because NFLASH and GCI clashes in 0xC00 */
551 #ifndef NFLASH_SUPPORT
552 si_corereg(sih
, SI_CC_IDX
, OFFSETOF(chipcregs_t
, gci_indirect_addr
), ~0, reg
);
553 return si_corereg(sih
, SI_CC_IDX
, OFFSETOF(chipcregs_t
, gci_chipctrl
), mask
, val
);
554 #else /* NFLASH_SUPPORT */
561 * output: chipcontrol reg and bits to shift for pin fn-sel's first regbit.
562 * eg: gpio9 will give regidx: 1 and pos 4
565 si_gci_get_chipctrlreg_idx(uint32 pin
, uint32
*regidx
, uint32
*pos
)
570 SI_MSG(("si_gci_get_chipctrlreg_idx:%d:%d:%d\n", pin
, *regidx
, *pos
));
575 /* setup a given pin for fnsel function */
577 si_gci_set_functionsel(si_t
*sih
, uint32 pin
, uint8 fnsel
)
579 uint32 reg
= 0, pos
= 0;
581 SI_MSG(("si_gci_set_functionsel:%d\n", pin
));
583 si_gci_get_chipctrlreg_idx(pin
, ®
, &pos
);
584 si_gci_chipcontrol(sih
, reg
, GCIMASK(pos
), GCIPOSVAL(fnsel
, pos
));
588 BCMATTACHFN(si_doattach
)(si_info_t
*sii
, uint devid
, osl_t
*osh
, void *regs
,
589 uint bustype
, void *sdh
, char **vars
, uint
*varsz
)
591 struct si_pub
*sih
= &sii
->pub
;
596 bool fixup_boardtype
= FALSE
;
597 ASSERT(GOODREGS(regs
));
599 bzero((uchar
*)sii
, sizeof(si_info_t
));
603 sih
->buscoreidx
= BADIDX
;
609 #ifdef SI_ENUM_BASE_VARIABLE
610 si_enum_base_init(sih
, bustype
);
611 #endif /* SI_ENUM_BASE_VARIABLE */
613 /* check to see if we are a si core mimic'ing a pci core */
614 if ((bustype
== PCI_BUS
) &&
615 (OSL_PCI_READ_CONFIG(sii
->osh
, PCI_SPROM_CONTROL
, sizeof(uint32
)) == 0xffffffff)) {
616 SI_ERROR(("%s: incoming bus is PCI but it's a lie, switching to SI "
617 "devid:0x%x\n", __FUNCTION__
, devid
));
621 /* find Chipcommon address */
622 if (bustype
== PCI_BUS
) {
623 savewin
= OSL_PCI_READ_CONFIG(sii
->osh
, PCI_BAR0_WIN
, sizeof(uint32
));
624 if (!GOODCOREADDR(savewin
, SI_ENUM_BASE
))
625 savewin
= SI_ENUM_BASE
;
626 OSL_PCI_WRITE_CONFIG(sii
->osh
, PCI_BAR0_WIN
, 4, SI_ENUM_BASE
);
627 cc
= (chipcregs_t
*)regs
;
629 cc
= (chipcregs_t
*)REG_MAP(SI_ENUM_BASE
, SI_CORE_SIZE
);
632 sih
->bustype
= bustype
;
633 if (bustype
!= BUSTYPE(bustype
)) {
634 SI_ERROR(("si_doattach: bus type %d does not match configured bus type %d\n",
635 bustype
, BUSTYPE(bustype
)));
639 /* bus/core/clk setup for register access */
640 if (!si_buscore_prep(sii
, bustype
, devid
, sdh
)) {
641 SI_ERROR(("si_doattach: si_core_clk_prep failed %d\n", bustype
));
645 /* ChipID recognition.
646 * We assume we can read chipid at offset 0 from the regs arg.
647 * If we add other chiptypes (or if we need to support old sdio hosts w/o chipcommon),
648 * some way of recognizing them needs to be added here.
651 SI_ERROR(("%s: chipcommon register space is null \n", __FUNCTION__
));
654 w
= R_REG(osh
, &cc
->chipid
);
655 sih
->socitype
= (w
& CID_TYPE_MASK
) >> CID_TYPE_SHIFT
;
656 /* Might as wll fill in chip id rev & pkg */
657 sih
->chip
= w
& CID_ID_MASK
;
658 sih
->chiprev
= (w
& CID_REV_MASK
) >> CID_REV_SHIFT
;
659 sih
->chippkg
= (w
& CID_PKG_MASK
) >> CID_PKG_SHIFT
;
661 if ((CHIPID(sih
->chip
) == BCM4329_CHIP_ID
) && (sih
->chiprev
== 0) &&
662 (sih
->chippkg
!= BCM4329_289PIN_PKG_ID
)) {
663 sih
->chippkg
= BCM4329_182PIN_PKG_ID
;
665 sih
->issim
= IS_SIM(sih
->chippkg
);
668 if (CHIPTYPE(sii
->pub
.socitype
) == SOCI_SB
) {
669 SI_MSG(("Found chip type SB (0x%08x)\n", w
));
670 sb_scan(&sii
->pub
, regs
, devid
);
671 } else if (CHIPTYPE(sii
->pub
.socitype
) == SOCI_AI
) {
672 SI_MSG(("Found chip type AI (0x%08x)\n", w
));
673 /* pass chipc address instead of original core base */
674 ai_scan(&sii
->pub
, (void *)(uintptr
)cc
, devid
);
675 } else if (CHIPTYPE(sii
->pub
.socitype
) == SOCI_UBUS
) {
676 SI_MSG(("Found chip type UBUS (0x%08x), chip id = 0x%4x\n", w
, sih
->chip
));
677 /* pass chipc address instead of original core base */
678 ub_scan(&sii
->pub
, (void *)(uintptr
)cc
, devid
);
680 SI_ERROR(("Found chip of unknown type (0x%08x)\n", w
));
683 /* no cores found, bail out */
684 if (sii
->numcores
== 0) {
685 SI_ERROR(("si_doattach: could not find any cores\n"));
688 /* bus/core/clk setup */
690 if (!si_buscore_setup(sii
, cc
, bustype
, savewin
, &origidx
, regs
)) {
691 SI_ERROR(("si_doattach: si_buscore_setup failed\n"));
695 if (CHIPID(sih
->chip
) == BCM4322_CHIP_ID
&& (((sih
->chipst
& CST4322_SPROM_OTP_SEL_MASK
)
696 >> CST4322_SPROM_OTP_SEL_SHIFT
) == (CST4322_OTP_PRESENT
|
697 CST4322_SPROM_PRESENT
))) {
698 SI_ERROR(("%s: Invalid setting: both SPROM and OTP strapped.\n", __FUNCTION__
));
702 /* assume current core is CC */
703 if ((sii
->pub
.ccrev
== 0x25) && ((CHIPID(sih
->chip
) == BCM43236_CHIP_ID
||
704 CHIPID(sih
->chip
) == BCM43235_CHIP_ID
||
705 CHIPID(sih
->chip
) == BCM43234_CHIP_ID
||
706 CHIPID(sih
->chip
) == BCM43238_CHIP_ID
) &&
707 (CHIPREV(sii
->pub
.chiprev
) <= 2))) {
709 if ((cc
->chipstatus
& CST43236_BP_CLK
) != 0) {
711 clkdiv
= R_REG(osh
, &cc
->clkdiv
);
712 /* otp_clk_div is even number, 120/14 < 9mhz */
713 clkdiv
= (clkdiv
& ~CLKD_OTP
) | (14 << CLKD_OTP_SHIFT
);
714 W_REG(osh
, &cc
->clkdiv
, clkdiv
);
715 SI_ERROR(("%s: set clkdiv to %x\n", __FUNCTION__
, clkdiv
));
720 if (bustype
== PCI_BUS
) {
721 if ((CHIPID(sih
->chip
) == BCM4331_CHIP_ID
) ||
722 (CHIPID(sih
->chip
) == BCM43431_CHIP_ID
)) {
723 /* Check Ext PA Controls for 4331 12x9 Package before the fixup */
724 if (sih
->chippkg
== 9) {
725 uint32 val
= si_chipcontrl_read(sih
);
726 fixup_boardtype
= ((val
& CCTRL4331_EXTPA_ON_GPIO2_5
) ==
727 CCTRL4331_EXTPA_ON_GPIO2_5
);
729 /* set default mux pin to SROM */
730 si_chipcontrl_epa4331(sih
, FALSE
);
731 si_corereg(sih
, SI_CC_IDX
, OFFSETOF(chipcregs_t
, watchdog
), ~0, 100);
732 OSL_DELAY(20000); /* Srom read takes ~12mS */
735 if (((CHIPID(sih
->chip
) == BCM4360_CHIP_ID
) ||
736 (CHIPID(sih
->chip
) == BCM43460_CHIP_ID
) ||
737 (CHIPID(sih
->chip
) == BCM4352_CHIP_ID
)) &&
738 (CHIPREV(sih
->chiprev
) <= 2)) {
739 pcie_disable_TL_clk_gating(sii
->pch
);
740 pcie_set_L1_entry_time(sii
->pch
, 0x40);
744 /* Set OTPClkDiv to smaller value otherwise OTP always reads 0xFFFF.
745 * For real-chip we shouldn't set OTPClkDiv to 2 because 20/2 = 10 > 9Mhz
746 * but for 4314 QT if we set it to 4. OTP reads 0xFFFF every two words.
751 if ((CHIPID(sih
->chip
) == BCM4314_CHIP_ID
) ||
752 (CHIPID(sih
->chip
) == BCM43142_CHIP_ID
)) {
754 } else if ((CHIPID(sih
->chip
) == BCM43131_CHIP_ID
) ||
755 (CHIPID(sih
->chip
) == BCM43217_CHIP_ID
) ||
756 (CHIPID(sih
->chip
) == BCM43227_CHIP_ID
) ||
757 (CHIPID(sih
->chip
) == BCM43228_CHIP_ID
)) {
761 if (otpclkdiv
!= 0) {
762 uint clkdiv
, savecore
;
763 savecore
= si_coreidx(sih
);
764 si_setcore(sih
, CC_CORE_ID
, 0);
766 clkdiv
= R_REG(osh
, &cc
->clkdiv
);
767 clkdiv
= (clkdiv
& ~CLKD_OTP
) | (otpclkdiv
<< CLKD_OTP_SHIFT
);
768 W_REG(osh
, &cc
->clkdiv
, clkdiv
);
770 SI_ERROR(("%s: set clkdiv to 0x%x for QT\n", __FUNCTION__
, clkdiv
));
771 si_setcoreidx(sih
, savecore
);
776 #ifdef SI_SPROM_PROBE
778 #endif /* SI_SPROM_PROBE */
780 #if !defined(BCMHIGHSDIO)
781 /* Init nvram from flash if it exists */
782 nvram_init((void *)&(sii
->pub
));
784 /* Init nvram from sprom/otp if they exist */
785 if (srom_var_init(&sii
->pub
, BUSTYPE(bustype
), regs
, sii
->osh
, vars
, varsz
)) {
786 SI_ERROR(("si_doattach: srom_var_init failed: bad srom\n"));
789 pvars
= vars
? *vars
: NULL
;
791 si_nvram_process(sii
, pvars
);
793 if (bustype
== PCI_BUS
) {
794 if ((CHIPID(sih
->chip
) == BCM4331_CHIP_ID
) ||
795 (CHIPID(sih
->chip
) == BCM43431_CHIP_ID
)) {
796 si_sromvars_fixup_4331(sih
, pvars
);
798 sii
->pub
.boardtype
= getintvar(pvars
, "boardtype");
802 /* === NVRAM, clock is ready === */
805 BCM_REFERENCE(pvars
);
809 #if defined(CONFIG_XIP) && defined(BCMTCAM)
810 /* patch the ROM if there are any patch pairs from OTP/SPROM */
813 #if defined(__ARM_ARCH_7R__)
814 hnd_tcam_bootloader_load(si_setcore(sih
, ARMCR4_CORE_ID
, 0), pvars
);
816 hnd_tcam_bootloader_load(si_setcore(sih
, SOCRAM_CORE_ID
, 0), pvars
);
818 si_setcoreidx(sih
, origidx
);
820 #endif /* CONFIG_XIP && BCMTCAM */
822 /* bootloader should retain default pulls */
823 #ifndef BCM_BOOTLOADER
824 if (sii
->pub
.ccrev
>= 20) {
825 uint32 gpiopullup
= 0, gpiopulldown
= 0;
826 cc
= (chipcregs_t
*)si_setcore(sih
, CC_CORE_ID
, 0);
829 /* 4314/43142 has pin muxing, don't clear gpio bits */
830 if ((CHIPID(sih
->chip
) == BCM4314_CHIP_ID
) ||
831 (CHIPID(sih
->chip
) == BCM43142_CHIP_ID
)) {
832 gpiopullup
|= 0x402e0;
833 gpiopulldown
|= 0x20500;
836 W_REG(osh
, &cc
->gpiopullup
, gpiopullup
);
837 W_REG(osh
, &cc
->gpiopulldown
, gpiopulldown
);
838 si_setcoreidx(sih
, origidx
);
840 #endif /* !BCM_BOOTLOADER */
842 /* PMU specific initializations */
843 if (PMUCTL_ENAB(sih
)) {
845 si_pmu_init(sih
, sii
->osh
);
846 si_pmu_chip_init(sih
, sii
->osh
);
847 xtalfreq
= getintvar(pvars
, "xtalfreq");
848 /* If xtalfreq var not available, try to measure it */
850 xtalfreq
= si_pmu_measure_alpclk(sih
, sii
->osh
);
851 #if !defined(BCMHIGHSDIO)
852 si_pmu_pll_init(sih
, sii
->osh
, xtalfreq
);
853 si_pmu_res_init(sih
, sii
->osh
);
855 si_pmu_swreg_init(sih
, sii
->osh
);
858 /* setup the GPIO based LED powersave register */
859 if (sii
->pub
.ccrev
>= 16) {
860 if ((w
= getintvar(pvars
, "leddc")) == 0)
861 w
= DEFAULT_GPIOTIMERVAL
;
862 si_corereg(sih
, SI_CC_IDX
, OFFSETOF(chipcregs_t
, gpiotimerval
), ~0, w
);
865 if (PCI_FORCEHT(sii
)) {
866 SI_MSG(("si_doattach: force HT\n"));
867 sih
->pci_pr32414
= TRUE
;
869 _si_clkctl_cc(sii
, CLK_FAST
);
873 ASSERT(sii
->pch
!= NULL
);
875 pcicore_attach(sii
->pch
, pvars
, SI_DOATTACH
);
877 if (((CHIPID(sih
->chip
) == BCM4311_CHIP_ID
) && (CHIPREV(sih
->chiprev
) == 2)) ||
878 (CHIPID(sih
->chip
) == BCM4312_CHIP_ID
)) {
879 SI_MSG(("si_doattach: clear initiator timeout\n"));
880 sb_set_initiator_to(sih
, 0x3, si_findcoreidx(sih
, D11_CORE_ID
, 0));
884 if ((CHIPID(sih
->chip
) == BCM43224_CHIP_ID
) ||
885 (CHIPID(sih
->chip
) == BCM43421_CHIP_ID
)) {
886 /* enable 12 mA drive strenth for 43224 and set chipControl register bit 15 */
887 if (CHIPREV(sih
->chiprev
) == 0) {
888 SI_MSG(("Applying 43224A0 WARs\n"));
889 si_corereg(sih
, SI_CC_IDX
, OFFSETOF(chipcregs_t
, chipcontrol
),
890 CCTRL43224_GPIO_TOGGLE
, CCTRL43224_GPIO_TOGGLE
);
891 si_pmu_chipcontrol(sih
, 0, CCTRL_43224A0_12MA_LED_DRIVE
,
892 CCTRL_43224A0_12MA_LED_DRIVE
);
894 if (CHIPREV(sih
->chiprev
) >= 1) {
895 SI_MSG(("Applying 43224B0+ WARs\n"));
896 si_pmu_chipcontrol(sih
, 0, CCTRL_43224B0_12MA_LED_DRIVE
,
897 CCTRL_43224B0_12MA_LED_DRIVE
);
901 /* configure default pinmux enables for the chip */
902 if (getvar(pvars
, "muxenab") != NULL
) {
903 w
= getintvar(pvars
, "muxenab");
904 si_muxenab((si_t
*)sii
, w
);
907 /* enable GPIO interrupts when clocks are off */
908 if (sii
->pub
.ccrev
>= 21) {
910 corecontrol
= si_corereg(sih
, SI_CC_IDX
, OFFSETOF(chipcregs_t
, corecontrol
),
912 corecontrol
|= CC_ASYNCGPIO
;
913 si_corereg(sih
, SI_CC_IDX
, OFFSETOF(chipcregs_t
, corecontrol
),
914 corecontrol
, corecontrol
);
917 if (CHIPID(sih
->chip
) == BCM4313_CHIP_ID
) {
918 /* enable 12 mA drive strenth for 4313 and set chipControl register bit 1 */
919 SI_MSG(("Applying 4313 WARs\n"));
920 si_pmu_chipcontrol(sih
, 0, CCTRL_4313_12MA_LED_DRIVE
, CCTRL_4313_12MA_LED_DRIVE
);
923 #if defined(SAVERESTORE)
924 sr_save_restore_init(sih
);
926 /* clear any previous epidiag-induced target abort */
927 ASSERT(!si_taclear(sih
, FALSE
));
932 if (BUSTYPE(sih
->bustype
) == PCI_BUS
) {
934 pcicore_deinit(sii
->pch
);
941 /* may be called with core in reset */
943 BCMATTACHFN(si_detach
)(si_t
*sih
)
949 struct si_pub
*si_local
= NULL
;
950 bcopy(&sih
, &si_local
, sizeof(si_t
*));
958 if (BUSTYPE(sih
->bustype
) == SI_BUS
)
959 for (idx
= 0; idx
< SI_MAXCORES
; idx
++)
960 if (sii
->regs
[idx
]) {
961 REG_UNMAP(sii
->regs
[idx
]);
962 sii
->regs
[idx
] = NULL
;
966 #if !defined(BCMHIGHSDIO)
967 srom_var_deinit((void *)si_local
);
969 nvram_exit((void *)si_local
); /* free up nvram buffers */
972 if (BUSTYPE(sih
->bustype
) == PCI_BUS
) {
974 pcicore_deinit(sii
->pch
);
978 #if !defined(BCMBUSTYPE) || (BCMBUSTYPE == SI_BUS)
980 #endif /* !BCMBUSTYPE || (BCMBUSTYPE == SI_BUS) */
981 MFREE(sii
->osh
, sii
, sizeof(si_info_t
));
994 si_setosh(si_t
*sih
, osl_t
*osh
)
999 if (sii
->osh
!= NULL
) {
1000 SI_ERROR(("osh is already set....\n"));
1006 /* register driver interrupt disabling and restoring callback functions */
1008 si_register_intr_callback(si_t
*sih
, void *intrsoff_fn
, void *intrsrestore_fn
,
1009 void *intrsenabled_fn
, void *intr_arg
)
1014 sii
->intr_arg
= intr_arg
;
1015 sii
->intrsoff_fn
= (si_intrsoff_t
)intrsoff_fn
;
1016 sii
->intrsrestore_fn
= (si_intrsrestore_t
)intrsrestore_fn
;
1017 sii
->intrsenabled_fn
= (si_intrsenabled_t
)intrsenabled_fn
;
1018 /* save current core id. when this function called, the current core
1019 * must be the core which provides driver functions(il, et, wl, etc.)
1021 sii
->dev_coreid
= sii
->coreid
[sii
->curidx
];
1025 si_deregister_intr_callback(si_t
*sih
)
1030 sii
->intrsoff_fn
= NULL
;
1034 si_intflag(si_t
*sih
)
1036 si_info_t
*sii
= SI_INFO(sih
);
1038 if (CHIPTYPE(sih
->socitype
) == SOCI_SB
)
1039 return sb_intflag(sih
);
1040 else if (CHIPTYPE(sih
->socitype
) == SOCI_AI
)
1041 return R_REG(sii
->osh
, ((uint32
*)(uintptr
)
1042 (sii
->oob_router
+ OOB_STATUSA
)));
1052 if (CHIPTYPE(sih
->socitype
) == SOCI_SB
)
1053 return sb_flag(sih
);
1054 else if (CHIPTYPE(sih
->socitype
) == SOCI_AI
)
1055 return ai_flag(sih
);
1056 else if (CHIPTYPE(sih
->socitype
) == SOCI_UBUS
)
1057 return ub_flag(sih
);
1065 si_setint(si_t
*sih
, int siflag
)
1067 if (CHIPTYPE(sih
->socitype
) == SOCI_SB
)
1068 sb_setint(sih
, siflag
);
1069 else if (CHIPTYPE(sih
->socitype
) == SOCI_AI
)
1070 ai_setint(sih
, siflag
);
1071 else if (CHIPTYPE(sih
->socitype
) == SOCI_UBUS
)
1072 ub_setint(sih
, siflag
);
1078 si_coreid(si_t
*sih
)
1083 return sii
->coreid
[sii
->curidx
];
1087 si_coreidx(si_t
*sih
)
1095 /* return the core-type instantiation # of the current core */
1097 si_coreunit(si_t
*sih
)
1110 ASSERT(GOODREGS(sii
->curmap
));
1111 coreid
= si_coreid(sih
);
1113 /* count the cores of our type */
1114 for (i
= 0; i
< idx
; i
++)
1115 if (sii
->coreid
[i
] == coreid
)
1122 si_corevendor(si_t
*sih
)
1124 if (CHIPTYPE(sih
->socitype
) == SOCI_SB
)
1125 return sb_corevendor(sih
);
1126 else if (CHIPTYPE(sih
->socitype
) == SOCI_AI
)
1127 return ai_corevendor(sih
);
1128 else if (CHIPTYPE(sih
->socitype
) == SOCI_UBUS
)
1129 return ub_corevendor(sih
);
1137 si_backplane64(si_t
*sih
)
1139 return ((sih
->cccaps
& CC_CAP_BKPLN64
) != 0);
1143 si_corerev(si_t
*sih
)
1145 if (CHIPTYPE(sih
->socitype
) == SOCI_SB
)
1146 return sb_corerev(sih
);
1147 else if (CHIPTYPE(sih
->socitype
) == SOCI_AI
)
1148 return ai_corerev(sih
);
1149 else if (CHIPTYPE(sih
->socitype
) == SOCI_UBUS
)
1150 return ub_corerev(sih
);
1157 /* return index of coreid or BADIDX if not found */
1159 si_findcoreidx(si_t
*sih
, uint coreid
, uint coreunit
)
1169 for (i
= 0; i
< sii
->numcores
; i
++)
1170 if (sii
->coreid
[i
] == coreid
) {
1171 if (found
== coreunit
)
1179 /* return list of found cores */
1181 si_corelist(si_t
*sih
, uint coreid
[])
1187 bcopy((uchar
*)sii
->coreid
, (uchar
*)coreid
, (sii
->numcores
* sizeof(uint
)));
1188 return (sii
->numcores
);
1191 /* return current register mapping */
1193 si_coreregs(si_t
*sih
)
1198 ASSERT(GOODREGS(sii
->curmap
));
1200 return (sii
->curmap
);
1204 * This function changes logical "focus" to the indicated core;
1205 * must be called with interrupts off.
1206 * Moreover, callers should keep interrupts off during switching out of and back to d11 core
1209 si_setcore(si_t
*sih
, uint coreid
, uint coreunit
)
1213 idx
= si_findcoreidx(sih
, coreid
, coreunit
);
1217 if (CHIPTYPE(sih
->socitype
) == SOCI_SB
)
1218 return sb_setcoreidx(sih
, idx
);
1219 else if (CHIPTYPE(sih
->socitype
) == SOCI_AI
)
1220 return ai_setcoreidx(sih
, idx
);
1221 else if (CHIPTYPE(sih
->socitype
) == SOCI_UBUS
)
1222 return ub_setcoreidx(sih
, idx
);
1230 si_setcoreidx(si_t
*sih
, uint coreidx
)
1232 if (CHIPTYPE(sih
->socitype
) == SOCI_SB
)
1233 return sb_setcoreidx(sih
, coreidx
);
1234 else if (CHIPTYPE(sih
->socitype
) == SOCI_AI
)
1235 return ai_setcoreidx(sih
, coreidx
);
1236 else if (CHIPTYPE(sih
->socitype
) == SOCI_UBUS
)
1237 return ub_setcoreidx(sih
, coreidx
);
1244 /* Turn off interrupt as required by sb_setcore, before switch core */
1246 si_switch_core(si_t
*sih
, uint coreid
, uint
*origidx
, uint
*intr_val
)
1254 /* Overloading the origidx variable to remember the coreid,
1255 * this works because the core ids cannot be confused with
1259 if (coreid
== CC_CORE_ID
)
1260 return (void *)CCREGS_FAST(sii
);
1261 else if (coreid
== sih
->buscoretype
)
1262 return (void *)PCIEREGS(sii
);
1264 INTR_OFF(sii
, *intr_val
);
1265 *origidx
= sii
->curidx
;
1266 cc
= si_setcore(sih
, coreid
, 0);
1272 /* restore coreidx and restore interrupt */
1274 si_restore_core(si_t
*sih
, uint coreid
, uint intr_val
)
1279 if (SI_FAST(sii
) && ((coreid
== CC_CORE_ID
) || (coreid
== sih
->buscoretype
)))
1282 si_setcoreidx(sih
, coreid
);
1283 INTR_RESTORE(sii
, intr_val
);
1287 si_numaddrspaces(si_t
*sih
)
1289 if (CHIPTYPE(sih
->socitype
) == SOCI_SB
)
1290 return sb_numaddrspaces(sih
);
1291 else if (CHIPTYPE(sih
->socitype
) == SOCI_AI
)
1292 return ai_numaddrspaces(sih
);
1293 else if (CHIPTYPE(sih
->socitype
) == SOCI_UBUS
)
1294 return ub_numaddrspaces(sih
);
1302 si_addrspace(si_t
*sih
, uint asidx
)
1304 if (CHIPTYPE(sih
->socitype
) == SOCI_SB
)
1305 return sb_addrspace(sih
, asidx
);
1306 else if (CHIPTYPE(sih
->socitype
) == SOCI_AI
)
1307 return ai_addrspace(sih
, asidx
);
1308 else if (CHIPTYPE(sih
->socitype
) == SOCI_UBUS
)
1309 return ub_addrspace(sih
, asidx
);
1317 si_addrspacesize(si_t
*sih
, uint asidx
)
1319 if (CHIPTYPE(sih
->socitype
) == SOCI_SB
)
1320 return sb_addrspacesize(sih
, asidx
);
1321 else if (CHIPTYPE(sih
->socitype
) == SOCI_AI
)
1322 return ai_addrspacesize(sih
, asidx
);
1323 else if (CHIPTYPE(sih
->socitype
) == SOCI_UBUS
)
1324 return ub_addrspacesize(sih
, asidx
);
1332 si_coreaddrspaceX(si_t
*sih
, uint asidx
, uint32
*addr
, uint32
*size
)
1334 /* Only supported for SOCI_AI */
1335 if (CHIPTYPE(sih
->socitype
) == SOCI_AI
)
1336 ai_coreaddrspaceX(sih
, asidx
, addr
, size
);
1342 si_core_cflags(si_t
*sih
, uint32 mask
, uint32 val
)
1344 if (CHIPTYPE(sih
->socitype
) == SOCI_SB
)
1345 return sb_core_cflags(sih
, mask
, val
);
1346 else if (CHIPTYPE(sih
->socitype
) == SOCI_AI
)
1347 return ai_core_cflags(sih
, mask
, val
);
1348 else if (CHIPTYPE(sih
->socitype
) == SOCI_UBUS
)
1349 return ub_core_cflags(sih
, mask
, val
);
1357 si_core_cflags_wo(si_t
*sih
, uint32 mask
, uint32 val
)
1359 if (CHIPTYPE(sih
->socitype
) == SOCI_SB
)
1360 sb_core_cflags_wo(sih
, mask
, val
);
1361 else if (CHIPTYPE(sih
->socitype
) == SOCI_AI
)
1362 ai_core_cflags_wo(sih
, mask
, val
);
1363 else if (CHIPTYPE(sih
->socitype
) == SOCI_UBUS
)
1364 ub_core_cflags_wo(sih
, mask
, val
);
1370 si_core_sflags(si_t
*sih
, uint32 mask
, uint32 val
)
1372 if (CHIPTYPE(sih
->socitype
) == SOCI_SB
)
1373 return sb_core_sflags(sih
, mask
, val
);
1374 else if (CHIPTYPE(sih
->socitype
) == SOCI_AI
)
1375 return ai_core_sflags(sih
, mask
, val
);
1376 else if (CHIPTYPE(sih
->socitype
) == SOCI_UBUS
)
1377 return ub_core_sflags(sih
, mask
, val
);
1385 si_iscoreup(si_t
*sih
)
1387 if (CHIPTYPE(sih
->socitype
) == SOCI_SB
)
1388 return sb_iscoreup(sih
);
1389 else if (CHIPTYPE(sih
->socitype
) == SOCI_AI
)
1390 return ai_iscoreup(sih
);
1391 else if (CHIPTYPE(sih
->socitype
) == SOCI_UBUS
)
1392 return ub_iscoreup(sih
);
1400 si_wrapperreg(si_t
*sih
, uint32 offset
, uint32 mask
, uint32 val
)
1402 /* only for AI back plane chips */
1403 if (CHIPTYPE(sih
->socitype
) == SOCI_AI
)
1404 return (ai_wrap_reg(sih
, offset
, mask
, val
));
1409 si_corereg(si_t
*sih
, uint coreidx
, uint regoff
, uint mask
, uint val
)
1411 if (CHIPTYPE(sih
->socitype
) == SOCI_SB
)
1412 return sb_corereg(sih
, coreidx
, regoff
, mask
, val
);
1413 else if (CHIPTYPE(sih
->socitype
) == SOCI_AI
)
1414 return ai_corereg(sih
, coreidx
, regoff
, mask
, val
);
1415 else if (CHIPTYPE(sih
->socitype
) == SOCI_UBUS
)
1416 return ub_corereg(sih
, coreidx
, regoff
, mask
, val
);
1424 si_core_disable(si_t
*sih
, uint32 bits
)
1426 if (CHIPTYPE(sih
->socitype
) == SOCI_SB
)
1427 sb_core_disable(sih
, bits
);
1428 else if (CHIPTYPE(sih
->socitype
) == SOCI_AI
)
1429 ai_core_disable(sih
, bits
);
1430 else if (CHIPTYPE(sih
->socitype
) == SOCI_UBUS
)
1431 ub_core_disable(sih
, bits
);
1435 si_core_reset(si_t
*sih
, uint32 bits
, uint32 resetbits
)
1437 if (CHIPTYPE(sih
->socitype
) == SOCI_SB
)
1438 sb_core_reset(sih
, bits
, resetbits
);
1439 else if (CHIPTYPE(sih
->socitype
) == SOCI_AI
)
1440 ai_core_reset(sih
, bits
, resetbits
);
1441 else if (CHIPTYPE(sih
->socitype
) == SOCI_UBUS
)
1442 ub_core_reset(sih
, bits
, resetbits
);
1445 /* Run bist on current core. Caller needs to take care of core-specific bist hazards */
1447 si_corebist(si_t
*sih
)
1452 /* Read core control flags */
1453 cflags
= si_core_cflags(sih
, 0, 0);
1455 /* Set bist & fgc */
1456 si_core_cflags(sih
, ~0, (SICF_BIST_EN
| SICF_FGC
));
1458 /* Wait for bist done */
1459 SPINWAIT(((si_core_sflags(sih
, 0, 0) & SISF_BIST_DONE
) == 0), 100000);
1461 if (si_core_sflags(sih
, 0, 0) & SISF_BIST_ERROR
)
1462 result
= BCME_ERROR
;
1464 /* Reset core control flags */
1465 si_core_cflags(sih
, 0xffff, cflags
);
1471 BCMINITFN(factor6
)(uint32 x
)
1474 case CC_F6_2
: return 2;
1475 case CC_F6_3
: return 3;
1476 case CC_F6_4
: return 4;
1477 case CC_F6_5
: return 5;
1478 case CC_F6_6
: return 6;
1479 case CC_F6_7
: return 7;
1484 /* calculate the speed the SI would run at given a set of clockcontrol values */
1486 BCMINITFN(si_clock_rate
)(uint32 pll_type
, uint32 n
, uint32 m
)
1488 uint32 n1
, n2
, clock
, m1
, m2
, m3
, mc
;
1490 n1
= n
& CN_N1_MASK
;
1491 n2
= (n
& CN_N2_MASK
) >> CN_N2_SHIFT
;
1493 if (pll_type
== PLL_TYPE6
) {
1494 if (m
& CC_T6_MMASK
)
1498 } else if ((pll_type
== PLL_TYPE1
) ||
1499 (pll_type
== PLL_TYPE3
) ||
1500 (pll_type
== PLL_TYPE4
) ||
1501 (pll_type
== PLL_TYPE7
)) {
1504 } else if (pll_type
== PLL_TYPE2
) {
1507 ASSERT((n1
>= 2) && (n1
<= 7));
1508 ASSERT((n2
>= 5) && (n2
<= 23));
1509 } else if (pll_type
== PLL_TYPE5
) {
1513 /* PLL types 3 and 7 use BASE2 (25Mhz) */
1514 if ((pll_type
== PLL_TYPE3
) ||
1515 (pll_type
== PLL_TYPE7
)) {
1516 clock
= CC_CLOCK_BASE2
* n1
* n2
;
1518 clock
= CC_CLOCK_BASE1
* n1
* n2
;
1523 m1
= m
& CC_M1_MASK
;
1524 m2
= (m
& CC_M2_MASK
) >> CC_M2_SHIFT
;
1525 m3
= (m
& CC_M3_MASK
) >> CC_M3_SHIFT
;
1526 mc
= (m
& CC_MC_MASK
) >> CC_MC_SHIFT
;
1528 if ((pll_type
== PLL_TYPE1
) ||
1529 (pll_type
== PLL_TYPE3
) ||
1530 (pll_type
== PLL_TYPE4
) ||
1531 (pll_type
== PLL_TYPE7
)) {
1533 if ((pll_type
== PLL_TYPE1
) || (pll_type
== PLL_TYPE3
))
1540 case CC_MC_BYPASS
: return (clock
);
1541 case CC_MC_M1
: return (clock
/ m1
);
1542 case CC_MC_M1M2
: return (clock
/ (m1
* m2
));
1543 case CC_MC_M1M2M3
: return (clock
/ (m1
* m2
* m3
));
1544 case CC_MC_M1M3
: return (clock
/ (m1
* m3
));
1545 default: return (0);
1548 ASSERT(pll_type
== PLL_TYPE2
);
1553 ASSERT((m1
>= 2) && (m1
<= 7));
1554 ASSERT((m2
>= 3) && (m2
<= 10));
1555 ASSERT((m3
>= 2) && (m3
<= 7));
1557 if ((mc
& CC_T2MC_M1BYP
) == 0)
1559 if ((mc
& CC_T2MC_M2BYP
) == 0)
1561 if ((mc
& CC_T2MC_M3BYP
) == 0)
1568 bool si_read_pmu_autopll(si_t
*sih
)
1572 return (si_pmu_is_autoresetphyclk_disabled(sih
, sii
->osh
));
1576 BCMINITFN(si_clock
)(si_t
*sih
)
1582 uint32 pll_type
, rate
;
1586 INTR_OFF(sii
, intr_val
);
1587 if (PMUCTL_ENAB(sih
)) {
1588 rate
= si_pmu_si_clock(sih
, sii
->osh
);
1593 cc
= (chipcregs_t
*)si_setcore(sih
, CC_CORE_ID
, 0);
1596 n
= R_REG(sii
->osh
, &cc
->clockcontrol_n
);
1597 pll_type
= sih
->cccaps
& CC_CAP_PLL_MASK
;
1598 if (pll_type
== PLL_TYPE6
)
1599 m
= R_REG(sii
->osh
, &cc
->clockcontrol_m3
);
1600 else if (pll_type
== PLL_TYPE3
)
1601 m
= R_REG(sii
->osh
, &cc
->clockcontrol_m2
);
1603 m
= R_REG(sii
->osh
, &cc
->clockcontrol_sb
);
1605 /* calculate rate */
1606 rate
= si_clock_rate(pll_type
, n
, m
);
1608 if (pll_type
== PLL_TYPE3
)
1611 /* switch back to previous core */
1612 si_setcoreidx(sih
, idx
);
1614 INTR_RESTORE(sii
, intr_val
);
1620 BCMINITFN(si_alp_clock
)(si_t
*sih
)
1622 if (PMUCTL_ENAB(sih
))
1623 return si_pmu_alp_clock(sih
, si_osh(sih
));
1629 BCMINITFN(si_ilp_clock
)(si_t
*sih
)
1631 if (PMUCTL_ENAB(sih
))
1632 return si_pmu_ilp_clock(sih
, si_osh(sih
));
1637 /* set chip watchdog reset timer to fire in 'ticks' */
1639 si_watchdog(si_t
*sih
, uint ticks
)
1643 if (PMUCTL_ENAB(sih
)) {
1645 if ((CHIPID(sih
->chip
) == BCM4319_CHIP_ID
) &&
1646 (CHIPREV(sih
->chiprev
) == 0) && (ticks
!= 0)) {
1647 si_corereg(sih
, SI_CC_IDX
, OFFSETOF(chipcregs_t
, clk_ctl_st
), ~0, 0x2);
1648 si_setcore(sih
, USB20D_CORE_ID
, 0);
1649 si_core_disable(sih
, 1);
1650 si_setcore(sih
, CC_CORE_ID
, 0);
1653 if (CHIPID(sih
->chip
) == BCM4706_CHIP_ID
)
1656 nb
= (sih
->ccrev
< 26) ? 16 : ((sih
->ccrev
>= 37) ? 32 : 24);
1657 /* The mips compiler uses the sllv instruction,
1658 * so we specially handle the 32-bit case.
1663 maxt
= ((1 << nb
) - 1);
1667 else if (ticks
> maxt
)
1670 si_corereg(sih
, SI_CC_IDX
, OFFSETOF(chipcregs_t
, pmuwatchdog
), ~0, ticks
);
1672 /* make sure we come up in fast clock mode; or if clearing, clear clock */
1673 si_clkctl_cc(sih
, ticks
? CLK_FAST
: CLK_DYNAMIC
);
1674 maxt
= (1 << 28) - 1;
1678 si_corereg(sih
, SI_CC_IDX
, OFFSETOF(chipcregs_t
, watchdog
), ~0, ticks
);
1682 /* trigger watchdog reset after ms milliseconds */
1684 si_watchdog_ms(si_t
*sih
, uint32 ms
)
1686 si_watchdog(sih
, wd_msticks
* ms
);
1690 si_watchdog_msticks(void)
1695 #if defined(BCMDBG_ERR) || defined(BCMASSERT_SUPPORT)
1697 si_taclear(si_t
*sih
, bool details
)
1699 if (CHIPTYPE(sih
->socitype
) == SOCI_SB
)
1700 return sb_taclear(sih
, details
);
1701 else if (CHIPTYPE(sih
->socitype
) == SOCI_AI
)
1703 else if (CHIPTYPE(sih
->socitype
) == SOCI_UBUS
)
1713 BCMATTACHFN(si_d11_devid
)(si_t
*sih
)
1715 si_info_t
*sii
= SI_INFO(sih
);
1718 /* Fix device id for dual band BCM4328 */
1719 if (CHIPID(sih
->chip
) == BCM4328_CHIP_ID
&&
1720 (sih
->chippkg
== BCM4328USBDUAL_PKG_ID
|| sih
->chippkg
== BCM4328SDIODUAL_PKG_ID
))
1721 device
= BCM4328_D11DUAL_ID
;
1723 /* normal case: nvram variable with devpath->devid->wl0id */
1724 if ((device
= (uint16
)si_getdevpathintvar(sih
, "devid")) != 0)
1726 /* Get devid from OTP/SPROM depending on where the SROM is read */
1727 else if ((device
= (uint16
)getintvar(sii
->vars
, "devid")) != 0)
1729 /* no longer support wl0id, but keep the code here for backward compatibility. */
1730 else if ((device
= (uint16
)getintvar(sii
->vars
, "wl0id")) != 0)
1732 else if (CHIPID(sih
->chip
) == BCM4712_CHIP_ID
) {
1733 /* Chip specific conversion */
1734 if (sih
->chippkg
== BCM4712SMALL_PKG_ID
)
1735 device
= BCM4306_D11G_ID
;
1737 device
= BCM4306_D11DUAL_ID
;
1747 BCMATTACHFN(si_corepciid
)(si_t
*sih
, uint func
, uint16
*pcivendor
, uint16
*pcidevice
,
1748 uint8
*pciclass
, uint8
*pcisubclass
, uint8
*pciprogif
,
1751 uint16 vendor
= 0xffff, device
= 0xffff;
1752 uint8
class, subclass
, progif
= 0;
1753 uint8 header
= PCI_HEADER_NORMAL
;
1754 uint32 core
= si_coreid(sih
);
1756 /* Verify whether the function exists for the core */
1757 if (func
>= (uint
)(core
== USB20H_CORE_ID
? 2 : 1))
1760 /* Known vendor translations */
1761 switch (si_corevendor(sih
)) {
1764 vendor
= VENDOR_BROADCOM
;
1770 /* Determine class based on known core codes */
1773 class = PCI_CLASS_NET
;
1774 subclass
= PCI_NET_ETHER
;
1775 device
= BCM47XX_ENET_ID
;
1777 case GIGETH_CORE_ID
:
1778 class = PCI_CLASS_NET
;
1779 subclass
= PCI_NET_ETHER
;
1780 device
= BCM47XX_GIGETH_ID
;
1783 class = PCI_CLASS_NET
;
1784 subclass
= PCI_NET_ETHER
;
1785 device
= BCM47XX_GMAC_ID
;
1790 case SOCRAM_CORE_ID
:
1791 class = PCI_CLASS_MEMORY
;
1792 subclass
= PCI_MEMORY_RAM
;
1793 device
= (uint16
)core
;
1798 class = PCI_CLASS_BRIDGE
;
1799 subclass
= PCI_BRIDGE_PCI
;
1800 device
= (uint16
)core
;
1801 header
= PCI_HEADER_BRIDGE
;
1803 case MIPS33_CORE_ID
:
1804 case MIPS74K_CORE_ID
:
1805 class = PCI_CLASS_CPU
;
1806 subclass
= PCI_CPU_MIPS
;
1807 device
= (uint16
)core
;
1810 class = PCI_CLASS_COMM
;
1811 subclass
= PCI_COMM_MODEM
;
1812 device
= BCM47XX_V90_ID
;
1815 class = PCI_CLASS_MMEDIA
;
1816 subclass
= PCI_MMEDIA_AUDIO
;
1817 device
= BCM47XX_AUDIO_ID
;
1820 case USB11H_CORE_ID
:
1821 class = PCI_CLASS_SERIAL
;
1822 subclass
= PCI_SERIAL_USB
;
1823 progif
= 0x10; /* OHCI */
1824 device
= BCM47XX_USBH_ID
;
1826 case USB20H_CORE_ID
:
1827 class = PCI_CLASS_SERIAL
;
1828 subclass
= PCI_SERIAL_USB
;
1829 progif
= func
== 0 ? 0x10 : 0x20; /* OHCI/EHCI */
1830 device
= BCM47XX_USB20H_ID
;
1831 header
= 0x80; /* multifunction */
1834 class = PCI_CLASS_CRYPT
;
1835 subclass
= PCI_CRYPT_NETWORK
;
1836 device
= BCM47XX_IPSEC_ID
;
1839 /* Don't use class NETWORK, so wl/et won't attempt to recognize it */
1840 class = PCI_CLASS_COMM
;
1841 subclass
= PCI_COMM_OTHER
;
1842 device
= BCM47XX_ROBO_ID
;
1845 class = PCI_CLASS_MEMORY
;
1846 subclass
= PCI_MEMORY_FLASH
;
1847 device
= (uint16
)core
;
1849 case SATAXOR_CORE_ID
:
1850 class = PCI_CLASS_XOR
;
1851 subclass
= PCI_XOR_QDMA
;
1852 device
= BCM47XX_SATAXOR_ID
;
1854 case ATA100_CORE_ID
:
1855 class = PCI_CLASS_DASDI
;
1856 subclass
= PCI_DASDI_IDE
;
1857 device
= BCM47XX_ATA100_ID
;
1859 case USB11D_CORE_ID
:
1860 class = PCI_CLASS_SERIAL
;
1861 subclass
= PCI_SERIAL_USB
;
1862 device
= BCM47XX_USBD_ID
;
1864 case USB20D_CORE_ID
:
1865 class = PCI_CLASS_SERIAL
;
1866 subclass
= PCI_SERIAL_USB
;
1867 device
= BCM47XX_USB20D_ID
;
1870 class = PCI_CLASS_NET
;
1871 subclass
= PCI_NET_OTHER
;
1872 device
= si_d11_devid(sih
);
1876 class = subclass
= progif
= 0xff;
1877 device
= (uint16
)core
;
1881 *pcivendor
= vendor
;
1882 *pcidevice
= device
;
1884 *pcisubclass
= subclass
;
1885 *pciprogif
= progif
;
1886 *pciheader
= header
;
1892 /* print interesting sbconfig registers */
1894 si_dumpregs(si_t
*sih
, struct bcmstrbuf
*b
)
1897 uint origidx
, intr_val
= 0;
1900 origidx
= sii
->curidx
;
1902 INTR_OFF(sii
, intr_val
);
1903 if (CHIPTYPE(sih
->socitype
) == SOCI_SB
)
1904 sb_dumpregs(sih
, b
);
1905 else if (CHIPTYPE(sih
->socitype
) == SOCI_AI
)
1906 ai_dumpregs(sih
, b
);
1907 else if (CHIPTYPE(sih
->socitype
) == SOCI_UBUS
)
1908 ub_dumpregs(sih
, b
);
1912 si_setcoreidx(sih
, origidx
);
1913 INTR_RESTORE(sii
, intr_val
);
1919 si_view(si_t
*sih
, bool verbose
)
1921 if (CHIPTYPE(sih
->socitype
) == SOCI_SB
)
1922 sb_view(sih
, verbose
);
1923 else if (CHIPTYPE(sih
->socitype
) == SOCI_AI
)
1924 ai_view(sih
, verbose
);
1925 else if (CHIPTYPE(sih
->socitype
) == SOCI_UBUS
)
1926 ub_view(sih
, verbose
);
1932 si_viewall(si_t
*sih
, bool verbose
)
1939 curidx
= sii
->curidx
;
1941 INTR_OFF(sii
, intr_val
);
1942 if (CHIPTYPE(sih
->socitype
) == SOCI_AI
)
1943 ai_viewall(sih
, verbose
);
1945 SI_ERROR(("si_viewall: num_cores %d\n", sii
->numcores
));
1946 for (i
= 0; i
< sii
->numcores
; i
++) {
1947 si_setcoreidx(sih
, i
);
1948 si_view(sih
, verbose
);
1951 si_setcoreidx(sih
, curidx
);
1952 INTR_RESTORE(sii
, intr_val
);
1956 /* return the slow clock source - LPO, XTAL, or PCI */
1958 si_slowclk_src(si_info_t
*sii
)
1962 ASSERT(SI_FAST(sii
) || si_coreid(&sii
->pub
) == CC_CORE_ID
);
1964 if (sii
->pub
.ccrev
< 6) {
1965 if ((BUSTYPE(sii
->pub
.bustype
) == PCI_BUS
) &&
1966 (OSL_PCI_READ_CONFIG(sii
->osh
, PCI_GPIO_OUT
, sizeof(uint32
)) &
1968 return (SCC_SS_PCI
);
1970 return (SCC_SS_XTAL
);
1971 } else if (sii
->pub
.ccrev
< 10) {
1972 cc
= (chipcregs_t
*)si_setcoreidx(&sii
->pub
, sii
->curidx
);
1973 return (R_REG(sii
->osh
, &cc
->slow_clk_ctl
) & SCC_SS_MASK
);
1974 } else /* Insta-clock */
1975 return (SCC_SS_XTAL
);
1978 /* return the ILP (slowclock) min or max frequency */
1980 si_slowclk_freq(si_info_t
*sii
, bool max_freq
, chipcregs_t
*cc
)
1985 ASSERT(SI_FAST(sii
) || si_coreid(&sii
->pub
) == CC_CORE_ID
);
1987 /* shouldn't be here unless we've established the chip has dynamic clk control */
1988 ASSERT(R_REG(sii
->osh
, &cc
->capabilities
) & CC_CAP_PWR_CTL
);
1990 slowclk
= si_slowclk_src(sii
);
1991 if (sii
->pub
.ccrev
< 6) {
1992 if (slowclk
== SCC_SS_PCI
)
1993 return (max_freq
? (PCIMAXFREQ
/ 64) : (PCIMINFREQ
/ 64));
1995 return (max_freq
? (XTALMAXFREQ
/ 32) : (XTALMINFREQ
/ 32));
1996 } else if (sii
->pub
.ccrev
< 10) {
1998 (((R_REG(sii
->osh
, &cc
->slow_clk_ctl
) & SCC_CD_MASK
) >> SCC_CD_SHIFT
) + 1);
1999 if (slowclk
== SCC_SS_LPO
)
2000 return (max_freq
? LPOMAXFREQ
: LPOMINFREQ
);
2001 else if (slowclk
== SCC_SS_XTAL
)
2002 return (max_freq
? (XTALMAXFREQ
/ div
) : (XTALMINFREQ
/ div
));
2003 else if (slowclk
== SCC_SS_PCI
)
2004 return (max_freq
? (PCIMAXFREQ
/ div
) : (PCIMINFREQ
/ div
));
2008 /* Chipc rev 10 is InstaClock */
2009 div
= R_REG(sii
->osh
, &cc
->system_clk_ctl
) >> SYCC_CD_SHIFT
;
2010 div
= 4 * (div
+ 1);
2011 return (max_freq
? XTALMAXFREQ
: (XTALMINFREQ
/ div
));
2017 BCMINITFN(si_clkctl_setdelay
)(si_info_t
*sii
, void *chipcregs
)
2019 chipcregs_t
*cc
= (chipcregs_t
*)chipcregs
;
2020 uint slowmaxfreq
, pll_delay
, slowclk
;
2021 uint pll_on_delay
, fref_sel_delay
;
2023 pll_delay
= PLL_DELAY
;
2025 /* If the slow clock is not sourced by the xtal then add the xtal_on_delay
2026 * since the xtal will also be powered down by dynamic clk control logic.
2029 slowclk
= si_slowclk_src(sii
);
2030 if (slowclk
!= SCC_SS_XTAL
)
2031 pll_delay
+= XTAL_ON_DELAY
;
2033 /* Starting with 4318 it is ILP that is used for the delays */
2034 slowmaxfreq
= si_slowclk_freq(sii
, (sii
->pub
.ccrev
>= 10) ? FALSE
: TRUE
, cc
);
2036 pll_on_delay
= ((slowmaxfreq
* pll_delay
) + 999999) / 1000000;
2037 fref_sel_delay
= ((slowmaxfreq
* FREF_DELAY
) + 999999) / 1000000;
2039 W_REG(sii
->osh
, &cc
->pll_on_delay
, pll_on_delay
);
2040 W_REG(sii
->osh
, &cc
->fref_sel_delay
, fref_sel_delay
);
2043 /* initialize power control delay registers */
2045 BCMINITFN(si_clkctl_init
)(si_t
*sih
)
2052 if (!CCCTL_ENAB(sih
))
2056 fast
= SI_FAST(sii
);
2058 origidx
= sii
->curidx
;
2059 if ((cc
= (chipcregs_t
*)si_setcore(sih
, CC_CORE_ID
, 0)) == NULL
)
2061 } else if ((cc
= (chipcregs_t
*)CCREGS_FAST(sii
)) == NULL
)
2065 /* set all Instaclk chip ILP to 1 MHz */
2066 if (sih
->ccrev
>= 10)
2067 SET_REG(sii
->osh
, &cc
->system_clk_ctl
, SYCC_CD_MASK
,
2068 (ILP_DIV_1MHZ
<< SYCC_CD_SHIFT
));
2070 si_clkctl_setdelay(sii
, (void *)(uintptr
)cc
);
2073 si_setcoreidx(sih
, origidx
);
2076 /* return the value suitable for writing to the dot11 core FAST_PWRUP_DELAY register */
2078 BCMINITFN(si_clkctl_fast_pwrup_delay
)(si_t
*sih
)
2089 if (PMUCTL_ENAB(sih
)) {
2090 INTR_OFF(sii
, intr_val
);
2091 fpdelay
= si_pmu_fast_pwrup_delay(sih
, sii
->osh
);
2092 INTR_RESTORE(sii
, intr_val
);
2096 if (!CCCTL_ENAB(sih
))
2099 fast
= SI_FAST(sii
);
2102 origidx
= sii
->curidx
;
2103 INTR_OFF(sii
, intr_val
);
2104 if ((cc
= (chipcregs_t
*)si_setcore(sih
, CC_CORE_ID
, 0)) == NULL
)
2107 else if ((cc
= (chipcregs_t
*)CCREGS_FAST(sii
)) == NULL
)
2111 slowminfreq
= si_slowclk_freq(sii
, FALSE
, cc
);
2112 fpdelay
= (((R_REG(sii
->osh
, &cc
->pll_on_delay
) + 2) * 1000000) +
2113 (slowminfreq
- 1)) / slowminfreq
;
2117 si_setcoreidx(sih
, origidx
);
2118 INTR_RESTORE(sii
, intr_val
);
2123 /* turn primary xtal and/or pll off/on */
2125 si_clkctl_xtal(si_t
*sih
, uint what
, bool on
)
2128 uint32 in
, out
, outen
;
2132 switch (BUSTYPE(sih
->bustype
)) {
2140 /* pcie core doesn't have any mapping to control the xtal pu */
2144 in
= OSL_PCI_READ_CONFIG(sii
->osh
, PCI_GPIO_IN
, sizeof(uint32
));
2145 out
= OSL_PCI_READ_CONFIG(sii
->osh
, PCI_GPIO_OUT
, sizeof(uint32
));
2146 outen
= OSL_PCI_READ_CONFIG(sii
->osh
, PCI_GPIO_OUTEN
, sizeof(uint32
));
2149 * Avoid glitching the clock if GPRS is already using it.
2150 * We can't actually read the state of the PLLPD so we infer it
2151 * by the value of XTAL_PU which *is* readable via gpioin.
2153 if (on
&& (in
& PCI_CFG_GPIO_XTAL
))
2157 outen
|= PCI_CFG_GPIO_XTAL
;
2159 outen
|= PCI_CFG_GPIO_PLL
;
2162 /* turn primary xtal on */
2164 out
|= PCI_CFG_GPIO_XTAL
;
2166 out
|= PCI_CFG_GPIO_PLL
;
2167 OSL_PCI_WRITE_CONFIG(sii
->osh
, PCI_GPIO_OUT
,
2168 sizeof(uint32
), out
);
2169 OSL_PCI_WRITE_CONFIG(sii
->osh
, PCI_GPIO_OUTEN
,
2170 sizeof(uint32
), outen
);
2171 OSL_DELAY(XTAL_ON_DELAY
);
2176 out
&= ~PCI_CFG_GPIO_PLL
;
2177 OSL_PCI_WRITE_CONFIG(sii
->osh
, PCI_GPIO_OUT
,
2178 sizeof(uint32
), out
);
2183 out
&= ~PCI_CFG_GPIO_XTAL
;
2185 out
|= PCI_CFG_GPIO_PLL
;
2186 OSL_PCI_WRITE_CONFIG(sii
->osh
, PCI_GPIO_OUT
, sizeof(uint32
), out
);
2187 OSL_PCI_WRITE_CONFIG(sii
->osh
, PCI_GPIO_OUTEN
, sizeof(uint32
),
2200 * clock control policy function throught chipcommon
2202 * set dynamic clk control mode (forceslow, forcefast, dynamic)
2203 * returns true if we are forcing fast clock
2204 * this is a wrapper over the next internal function
2205 * to allow flexible policy settings for outside caller
2208 si_clkctl_cc(si_t
*sih
, uint mode
)
2214 /* chipcommon cores prior to rev6 don't support dynamic clock control */
2218 if (PCI_FORCEHT(sii
))
2219 return (mode
== CLK_FAST
);
2221 return _si_clkctl_cc(sii
, mode
);
2224 /* clk control mechanism through chipcommon, no policy checking */
2226 _si_clkctl_cc(si_info_t
*sii
, uint mode
)
2232 bool fast
= SI_FAST(sii
);
2234 /* chipcommon cores prior to rev6 don't support dynamic clock control */
2235 if (sii
->pub
.ccrev
< 6)
2238 /* Chips with ccrev 10 are EOL and they don't have SYCC_HR which we use below */
2239 ASSERT(sii
->pub
.ccrev
!= 10);
2242 INTR_OFF(sii
, intr_val
);
2243 origidx
= sii
->curidx
;
2245 if ((BUSTYPE(sii
->pub
.bustype
) == SI_BUS
) &&
2246 si_setcore(&sii
->pub
, MIPS33_CORE_ID
, 0) &&
2247 (si_corerev(&sii
->pub
) <= 7) && (sii
->pub
.ccrev
>= 10))
2250 cc
= (chipcregs_t
*) si_setcore(&sii
->pub
, CC_CORE_ID
, 0);
2251 } else if ((cc
= (chipcregs_t
*) CCREGS_FAST(sii
)) == NULL
)
2255 if (!CCCTL_ENAB(&sii
->pub
) && (sii
->pub
.ccrev
< 20))
2259 case CLK_FAST
: /* FORCEHT, fast (pll) clock */
2260 if (sii
->pub
.ccrev
< 10) {
2261 /* don't forget to force xtal back on before we clear SCC_DYN_XTAL.. */
2262 si_clkctl_xtal(&sii
->pub
, XTAL
, ON
);
2263 SET_REG(sii
->osh
, &cc
->slow_clk_ctl
, (SCC_XC
| SCC_FS
| SCC_IP
), SCC_IP
);
2264 } else if (sii
->pub
.ccrev
< 20) {
2265 OR_REG(sii
->osh
, &cc
->system_clk_ctl
, SYCC_HR
);
2267 OR_REG(sii
->osh
, &cc
->clk_ctl_st
, CCS_FORCEHT
);
2270 /* wait for the PLL */
2271 if (PMUCTL_ENAB(&sii
->pub
)) {
2272 uint32 htavail
= CCS_HTAVAIL
;
2273 if (CHIPID(sii
->pub
.chip
) == BCM4328_CHIP_ID
)
2274 htavail
= CCS0_HTAVAIL
;
2275 SPINWAIT(((R_REG(sii
->osh
, &cc
->clk_ctl_st
) & htavail
) == 0),
2276 PMU_MAX_TRANSITION_DLY
);
2277 ASSERT(R_REG(sii
->osh
, &cc
->clk_ctl_st
) & htavail
);
2279 OSL_DELAY(PLL_DELAY
);
2283 case CLK_DYNAMIC
: /* enable dynamic clock control */
2284 if (sii
->pub
.ccrev
< 10) {
2285 scc
= R_REG(sii
->osh
, &cc
->slow_clk_ctl
);
2286 scc
&= ~(SCC_FS
| SCC_IP
| SCC_XC
);
2287 if ((scc
& SCC_SS_MASK
) != SCC_SS_XTAL
)
2289 W_REG(sii
->osh
, &cc
->slow_clk_ctl
, scc
);
2291 /* for dynamic control, we have to release our xtal_pu "force on" */
2293 si_clkctl_xtal(&sii
->pub
, XTAL
, OFF
);
2294 } else if (sii
->pub
.ccrev
< 20) {
2296 AND_REG(sii
->osh
, &cc
->system_clk_ctl
, ~SYCC_HR
);
2298 AND_REG(sii
->osh
, &cc
->clk_ctl_st
, ~CCS_FORCEHT
);
2308 si_setcoreidx(&sii
->pub
, origidx
);
2309 INTR_RESTORE(sii
, intr_val
);
2311 return (mode
== CLK_FAST
);
2314 /* Build device path. Support SI, PCI, and JTAG for now. */
2316 BCMNMIATTACHFN(si_devpath
)(si_t
*sih
, char *path
, int size
)
2320 ASSERT(path
!= NULL
);
2321 ASSERT(size
>= SI_DEVPATH_BUFSZ
);
2323 if (!path
|| size
<= 0)
2326 switch (BUSTYPE(sih
->bustype
)) {
2329 slen
= snprintf(path
, (size_t)size
, "sb/%u/", si_coreidx(sih
));
2332 ASSERT((SI_INFO(sih
))->osh
!= NULL
);
2333 slen
= snprintf(path
, (size_t)size
, "pci/%u/%u/",
2334 OSL_PCI_BUS((SI_INFO(sih
))->osh
),
2335 OSL_PCI_SLOT((SI_INFO(sih
))->osh
));
2338 SI_ERROR(("si_devpath: OSL_PCMCIA_BUS() not implemented, bus 1 assumed\n"));
2339 SI_ERROR(("si_devpath: OSL_PCMCIA_SLOT() not implemented, slot 1 assumed\n"));
2340 slen
= snprintf(path
, (size_t)size
, "pc/1/1/");
2348 if (slen
< 0 || slen
>= size
) {
2357 BCMATTACHFN(si_coded_devpathvar
)(si_t
*sih
, char *varname
, int var_len
, const char *name
)
2359 char pathname
[SI_DEVPATH_BUFSZ
+ 32];
2360 char devpath
[SI_DEVPATH_BUFSZ
+ 32];
2365 /* try to get compact devpath if it exist */
2366 if (si_devpath(sih
, devpath
, SI_DEVPATH_BUFSZ
) == 0) {
2367 len
= strlen(devpath
);
2368 devpath
[len
- 1] = '\0';
2369 for (idx
= 0; idx
< SI_MAXCORES
; idx
++) {
2370 snprintf(pathname
, SI_DEVPATH_BUFSZ
, "devpath%d", idx
);
2371 if ((p
= getvar(NULL
, pathname
)) == NULL
)
2374 if (strncmp(p
, devpath
, len
) == 0) {
2375 snprintf(varname
, var_len
, "%d:%s", idx
, name
);
2384 /* Get a variable, but only if it has a devpath prefix */
2386 BCMATTACHFN(si_getdevpathvar
)(si_t
*sih
, const char *name
)
2388 char varname
[SI_DEVPATH_BUFSZ
+ 32];
2391 si_devpathvar(sih
, varname
, sizeof(varname
), name
);
2393 if ((val
= getvar(NULL
, varname
)) != NULL
)
2396 /* try to get compact devpath if it exist */
2397 if (si_coded_devpathvar(sih
, varname
, sizeof(varname
), name
) == NULL
)
2400 return (getvar(NULL
, varname
));
2403 /* Get a variable, but only if it has a devpath prefix */
2405 BCMATTACHFN(si_getdevpathintvar
)(si_t
*sih
, const char *name
)
2407 #if defined(BCMBUSTYPE) && (BCMBUSTYPE == SI_BUS)
2408 return (getintvar(NULL
, name
));
2410 char varname
[SI_DEVPATH_BUFSZ
+ 32];
2413 si_devpathvar(sih
, varname
, sizeof(varname
), name
);
2415 if ((val
= getintvar(NULL
, varname
)) != 0)
2418 /* try to get compact devpath if it exist */
2419 if (si_coded_devpathvar(sih
, varname
, sizeof(varname
), name
) == NULL
)
2422 return (getintvar(NULL
, varname
));
2423 #endif /* BCMBUSTYPE && BCMBUSTYPE == SI_BUS */
2428 si_getnvramflvar(si_t
*sih
, const char *name
)
2430 return (getvar(NULL
, name
));
2432 #endif /* DONGLEBUILD */
2434 /* Concatenate the dev path with a varname into the given 'var' buffer
2435 * and return the 'var' pointer.
2436 * Nothing is done to the arguments if len == 0 or var is NULL, var is still returned.
2437 * On overflow, the first char will be set to '\0'.
2440 BCMATTACHFN(si_devpathvar
)(si_t
*sih
, char *var
, int len
, const char *name
)
2444 if (!var
|| len
<= 0)
2447 if (si_devpath(sih
, var
, len
) == 0) {
2448 path_len
= strlen(var
);
2450 if (strlen(name
) + 1 > (uint
)(len
- path_len
))
2453 strncpy(var
+ path_len
, name
, len
- path_len
- 1);
2461 si_pciereg(si_t
*sih
, uint32 offset
, uint32 mask
, uint32 val
, uint type
)
2468 SI_ERROR(("%s: Not a PCIE device\n", __FUNCTION__
));
2472 return pcicore_pciereg(sii
->pch
, offset
, mask
, val
, type
);
2476 si_pcieserdesreg(si_t
*sih
, uint32 mdioslave
, uint32 offset
, uint32 mask
, uint32 val
)
2483 SI_ERROR(("%s: Not a PCIE device\n", __FUNCTION__
));
2487 return pcicore_pcieserdesreg(sii
->pch
, mdioslave
, offset
, mask
, val
);
2491 /* return TRUE if PCIE capability exists in the pci config space */
2493 si_ispcie(si_info_t
*sii
)
2497 if (BUSTYPE(sii
->pub
.bustype
) != PCI_BUS
)
2500 cap_ptr
= pcicore_find_pci_capability(sii
->osh
, PCI_CAP_PCIECAP_ID
, NULL
, NULL
);
2507 /* Wake-on-wireless-LAN (WOWL) support functions */
2508 /* Enable PME generation and disable clkreq */
2510 si_pci_pmeen(si_t
*sih
)
2516 pcicore_pmeen(sii
->pch
);
2519 /* Return TRUE if PME status is set */
2521 si_pci_pmestat(si_t
*sih
)
2527 return pcicore_pmestat(sii
->pch
);
2530 /* Disable PME generation, clear the PME status bit if set */
2532 si_pci_pmeclr(si_t
*sih
)
2538 pcicore_pmeclr(sii
->pch
);
2542 si_pci_pmestatclr(si_t
*sih
)
2548 pcicore_pmestatclr(sii
->pch
);
2551 /* initialize the pcmcia core */
2553 si_pcmcia_init(si_t
*sih
)
2560 /* enable d11 mac interrupts */
2561 OSL_PCMCIA_READ_ATTR(sii
->osh
, PCMCIA_FCR0
+ PCMCIA_COR
, &cor
, 1);
2562 cor
|= COR_IRQEN
| COR_FUNEN
;
2563 OSL_PCMCIA_WRITE_ATTR(sii
->osh
, PCMCIA_FCR0
+ PCMCIA_COR
, &cor
, 1);
2569 BCMATTACHFN(si_pci_war16165
)(si_t
*sih
)
2575 return (PCI(sii
) && (sih
->buscorerev
<= 10));
2578 /* Disable pcie_war_ovr for some platforms (sigh!)
2579 * This is for boards that have BFL2_PCIEWAR_OVR set
2580 * but are in systems that still want the benefits of ASPM
2581 * Note that this should be done AFTER si_doattach
2584 si_pcie_war_ovr_update(si_t
*sih
, uint8 aspm
)
2590 if (!PCIE_GEN1(sii
))
2593 pcie_war_ovr_aspm_update(sii
->pch
, aspm
);
2597 si_pcie_power_save_enable(si_t
*sih
, bool enable
)
2603 if (!PCIE_GEN1(sii
))
2606 pcie_power_save_enable(sii
->pch
, enable
);
2610 si_pcie_set_maxpayload_size(si_t
*sih
, uint16 size
)
2619 pcie_set_maxpayload_size(sii
->pch
, size
);
2623 si_pcie_get_maxpayload_size(si_t
*sih
)
2632 return pcie_get_maxpayload_size(sii
->pch
);
2636 si_pcie_set_request_size(si_t
*sih
, uint16 size
)
2645 pcie_set_request_size(sii
->pch
, size
);
2649 si_pcie_get_request_size(si_t
*sih
)
2655 if (!PCIE_GEN1(sii
))
2658 return pcie_get_request_size(sii
->pch
);
2663 si_pcie_get_ssid(si_t
*sih
)
2669 if (!PCIE_GEN1(sii
))
2672 return pcie_get_ssid(sii
->pch
);
2676 si_pcie_get_bar0(si_t
*sih
)
2685 return pcie_get_bar0(sii
->pch
);
2689 si_pcie_configspace_cache(si_t
*sih
)
2698 return pcie_configspace_cache(sii
->pch
);
2702 si_pcie_configspace_restore(si_t
*sih
)
2711 return pcie_configspace_restore(sii
->pch
);
2715 si_pcie_configspace_get(si_t
*sih
, uint8
*buf
, uint size
)
2721 if (!PCIE(sii
) || size
> PCI_CONFIG_SPACE_SIZE
)
2724 return pcie_configspace_get(sii
->pch
, buf
, size
);
2727 /* back door for other module to override chippkg */
2729 si_chippkg_set(si_t
*sih
, uint val
)
2735 sii
->pub
.chippkg
= val
;
2739 BCMINITFN(si_pci_up
)(si_t
*sih
)
2745 /* if not pci bus, we're done */
2746 if (BUSTYPE(sih
->bustype
) != PCI_BUS
)
2749 if (PCI_FORCEHT(sii
))
2750 _si_clkctl_cc(sii
, CLK_FAST
);
2753 pcicore_up(sii
->pch
, SI_PCIUP
);
2754 if (((CHIPID(sih
->chip
) == BCM4311_CHIP_ID
) && (CHIPREV(sih
->chiprev
) == 2)) ||
2755 (CHIPID(sih
->chip
) == BCM4312_CHIP_ID
))
2756 sb_set_initiator_to((void *)sii
, 0x3,
2757 si_findcoreidx((void *)sii
, D11_CORE_ID
, 0));
2761 /* Unconfigure and/or apply various WARs when system is going to sleep mode */
2763 BCMUNINITFN(si_pci_sleep
)(si_t
*sih
)
2767 do_4360_pcie2_war
= 0;
2771 pcicore_sleep(sii
->pch
);
2774 /* Unconfigure and/or apply various WARs when going down */
2776 BCMINITFN(si_pci_down
)(si_t
*sih
)
2782 /* if not pci bus, we're done */
2783 if (BUSTYPE(sih
->bustype
) != PCI_BUS
)
2786 /* release FORCEHT since chip is going to "down" state */
2787 if (PCI_FORCEHT(sii
))
2788 _si_clkctl_cc(sii
, CLK_DYNAMIC
);
2790 pcicore_down(sii
->pch
, SI_PCIDOWN
);
2794 * Configure the pci core for pci client (NIC) action
2795 * coremask is the bitvec of cores by index to be enabled.
2798 BCMATTACHFN(si_pci_setup
)(si_t
*sih
, uint coremask
)
2801 sbpciregs_t
*pciregs
= NULL
;
2802 uint32 siflag
= 0, w
;
2807 if (BUSTYPE(sii
->pub
.bustype
) != PCI_BUS
)
2810 ASSERT(PCI(sii
) || PCIE(sii
));
2811 ASSERT(sii
->pub
.buscoreidx
!= BADIDX
);
2814 /* get current core index */
2817 /* we interrupt on this backplane flag number */
2818 siflag
= si_flag(sih
);
2820 /* switch over to pci core */
2821 pciregs
= (sbpciregs_t
*)si_setcoreidx(sih
, sii
->pub
.buscoreidx
);
2825 * Enable sb->pci interrupts. Assume
2826 * PCI rev 2.3 support was added in pci core rev 6 and things changed..
2828 if (PCIE(sii
) || (PCI(sii
) && ((sii
->pub
.buscorerev
) >= 6))) {
2829 /* pci config write to set this core bit in PCIIntMask */
2830 w
= OSL_PCI_READ_CONFIG(sii
->osh
, PCI_INT_MASK
, sizeof(uint32
));
2831 w
|= (coremask
<< PCI_SBIM_SHIFT
);
2833 /* User mode operate with interrupt disabled */
2834 w
&= !(coremask
<< PCI_SBIM_SHIFT
);
2836 OSL_PCI_WRITE_CONFIG(sii
->osh
, PCI_INT_MASK
, sizeof(uint32
), w
);
2838 /* set sbintvec bit for our flag number */
2839 si_setint(sih
, siflag
);
2843 OR_REG(sii
->osh
, &pciregs
->sbtopci2
, (SBTOPCI_PREF
| SBTOPCI_BURST
));
2844 if (sii
->pub
.buscorerev
>= 11) {
2845 OR_REG(sii
->osh
, &pciregs
->sbtopci2
, SBTOPCI_RC_READMULTI
);
2846 w
= R_REG(sii
->osh
, &pciregs
->clkrun
);
2847 W_REG(sii
->osh
, &pciregs
->clkrun
, (w
| PCI_CLKRUN_DSBL
));
2848 w
= R_REG(sii
->osh
, &pciregs
->clkrun
);
2851 /* switch back to previous core */
2852 si_setcoreidx(sih
, idx
);
2857 si_pcieclkreq(si_t
*sih
, uint32 mask
, uint32 val
)
2866 return pcie_clkreq(sii
->pch
, mask
, val
);
2870 si_pcielcreg(si_t
*sih
, uint32 mask
, uint32 val
)
2879 return pcie_lcreg(sii
->pch
, mask
, val
);
2883 si_pcie_set_error_injection(si_t
*sih
, uint32 mode
)
2892 pcie_set_error_injection(sii
->pch
, mode
);
2895 /* indirect way to read pcie config regs */
2897 si_pcie_readreg(void *sih
, uint addrtype
, uint offset
)
2899 return pcie_readreg(sih
, (sbpcieregs_t
*)PCIEREGS(((si_info_t
*)sih
)),
2904 * Fixup SROMless PCI device's configuration.
2905 * The current core may be changed upon return.
2908 si_pci_fixcfg(si_t
*sih
)
2910 uint origidx
, pciidx
;
2911 sbpciregs_t
*pciregs
= NULL
;
2912 sbpcieregs_t
*pcieregs
= NULL
;
2913 uint16 val16
, *reg16
= NULL
;
2916 si_info_t
*sii
= SI_INFO(sih
);
2918 ASSERT(BUSTYPE(sii
->pub
.bustype
) == PCI_BUS
);
2920 if ((CHIPID(sii
->pub
.chip
) == BCM4321_CHIP_ID
) && (CHIPREV(sii
->pub
.chiprev
) < 2)) {
2921 w
= (CHIPREV(sii
->pub
.chiprev
) == 0) ?
2922 CHIPCTRL_4321A0_DEFAULT
: CHIPCTRL_4321A1_DEFAULT
;
2923 si_corereg(&sii
->pub
, SI_CC_IDX
, OFFSETOF(chipcregs_t
, chipcontrol
), ~0, w
);
2926 /* Fixup PI in SROM shadow area to enable the correct PCI core access */
2927 /* save the current index */
2928 origidx
= si_coreidx(&sii
->pub
);
2930 /* check 'pi' is correct and fix it if not */
2931 if (sii
->pub
.buscoretype
== PCIE2_CORE_ID
) {
2932 pcieregs
= (sbpcieregs_t
*)si_setcore(&sii
->pub
, PCIE2_CORE_ID
, 0);
2933 ASSERT(pcieregs
!= NULL
);
2934 reg16
= &pcieregs
->sprom
[SRSH_PI_OFFSET
];
2935 } else if (sii
->pub
.buscoretype
== PCIE_CORE_ID
) {
2936 pcieregs
= (sbpcieregs_t
*)si_setcore(&sii
->pub
, PCIE_CORE_ID
, 0);
2937 ASSERT(pcieregs
!= NULL
);
2938 reg16
= &pcieregs
->sprom
[SRSH_PI_OFFSET
];
2939 } else if (sii
->pub
.buscoretype
== PCI_CORE_ID
) {
2940 pciregs
= (sbpciregs_t
*)si_setcore(&sii
->pub
, PCI_CORE_ID
, 0);
2941 ASSERT(pciregs
!= NULL
);
2942 reg16
= &pciregs
->sprom
[SRSH_PI_OFFSET
];
2944 pciidx
= si_coreidx(&sii
->pub
);
2946 if (!reg16
) return -1;
2948 val16
= R_REG(sii
->osh
, reg16
);
2949 if (((val16
& SRSH_PI_MASK
) >> SRSH_PI_SHIFT
) != (uint16
)pciidx
) {
2950 val16
= (uint16
)(pciidx
<< SRSH_PI_SHIFT
) | (val16
& ~SRSH_PI_MASK
);
2951 W_REG(sii
->osh
, reg16
, val16
);
2954 /* restore the original index */
2955 si_setcoreidx(&sii
->pub
, origidx
);
2957 pcicore_hwup(sii
->pch
);
2964 /* change logical "focus" to the gpio core for optimized access */
2966 si_gpiosetcore(si_t
*sih
)
2968 return (si_setcoreidx(sih
, SI_CC_IDX
));
2972 * mask & set gpiocontrol bits.
2973 * If a gpiocontrol bit is set to 0, chipcommon controls the corresponding GPIO pin.
2974 * If a gpiocontrol bit is set to 1, the GPIO pin is no longer a GPIO and becomes dedicated
2975 * to some chip-specific purpose.
2978 si_gpiocontrol(si_t
*sih
, uint32 mask
, uint32 val
, uint8 priority
)
2984 /* gpios could be shared on router platforms
2985 * ignore reservation if it's high priority (e.g., test apps)
2987 if ((priority
!= GPIO_HI_PRIORITY
) &&
2988 (BUSTYPE(sih
->bustype
) == SI_BUS
) && (val
|| mask
)) {
2989 mask
= priority
? (si_gpioreservation
& mask
) :
2990 ((si_gpioreservation
| mask
) & ~(si_gpioreservation
));
2994 regoff
= OFFSETOF(chipcregs_t
, gpiocontrol
);
2995 return (si_corereg(sih
, SI_CC_IDX
, regoff
, mask
, val
));
2998 /* mask&set gpio output enable bits */
3000 si_gpioouten(si_t
*sih
, uint32 mask
, uint32 val
, uint8 priority
)
3006 /* gpios could be shared on router platforms
3007 * ignore reservation if it's high priority (e.g., test apps)
3009 if ((priority
!= GPIO_HI_PRIORITY
) &&
3010 (BUSTYPE(sih
->bustype
) == SI_BUS
) && (val
|| mask
)) {
3011 mask
= priority
? (si_gpioreservation
& mask
) :
3012 ((si_gpioreservation
| mask
) & ~(si_gpioreservation
));
3016 regoff
= OFFSETOF(chipcregs_t
, gpioouten
);
3017 return (si_corereg(sih
, SI_CC_IDX
, regoff
, mask
, val
));
3020 /* mask&set gpio output bits */
3022 si_gpioout(si_t
*sih
, uint32 mask
, uint32 val
, uint8 priority
)
3028 /* gpios could be shared on router platforms
3029 * ignore reservation if it's high priority (e.g., test apps)
3031 if ((priority
!= GPIO_HI_PRIORITY
) &&
3032 (BUSTYPE(sih
->bustype
) == SI_BUS
) && (val
|| mask
)) {
3033 mask
= priority
? (si_gpioreservation
& mask
) :
3034 ((si_gpioreservation
| mask
) & ~(si_gpioreservation
));
3038 regoff
= OFFSETOF(chipcregs_t
, gpioout
);
3039 return (si_corereg(sih
, SI_CC_IDX
, regoff
, mask
, val
));
3042 /* reserve one gpio */
3044 si_gpioreserve(si_t
*sih
, uint32 gpio_bitmask
, uint8 priority
)
3046 /* only cores on SI_BUS share GPIO's and only applcation users need to
3047 * reserve/release GPIO
3049 if ((BUSTYPE(sih
->bustype
) != SI_BUS
) || (!priority
)) {
3050 ASSERT((BUSTYPE(sih
->bustype
) == SI_BUS
) && (priority
));
3053 /* make sure only one bit is set */
3054 if ((!gpio_bitmask
) || ((gpio_bitmask
) & (gpio_bitmask
- 1))) {
3055 ASSERT((gpio_bitmask
) && !((gpio_bitmask
) & (gpio_bitmask
- 1)));
3059 /* already reserved */
3060 if (si_gpioreservation
& gpio_bitmask
)
3062 /* set reservation */
3063 si_gpioreservation
|= gpio_bitmask
;
3065 return si_gpioreservation
;
3068 /* release one gpio */
3070 * releasing the gpio doesn't change the current value on the GPIO last write value
3071 * persists till some one overwrites it
3075 si_gpiorelease(si_t
*sih
, uint32 gpio_bitmask
, uint8 priority
)
3077 /* only cores on SI_BUS share GPIO's and only applcation users need to
3078 * reserve/release GPIO
3080 if ((BUSTYPE(sih
->bustype
) != SI_BUS
) || (!priority
)) {
3081 ASSERT((BUSTYPE(sih
->bustype
) == SI_BUS
) && (priority
));
3084 /* make sure only one bit is set */
3085 if ((!gpio_bitmask
) || ((gpio_bitmask
) & (gpio_bitmask
- 1))) {
3086 ASSERT((gpio_bitmask
) && !((gpio_bitmask
) & (gpio_bitmask
- 1)));
3090 /* already released */
3091 if (!(si_gpioreservation
& gpio_bitmask
))
3094 /* clear reservation */
3095 si_gpioreservation
&= ~gpio_bitmask
;
3097 return si_gpioreservation
;
3100 /* return the current gpioin register value */
3102 si_gpioin(si_t
*sih
)
3106 regoff
= OFFSETOF(chipcregs_t
, gpioin
);
3107 return (si_corereg(sih
, SI_CC_IDX
, regoff
, 0, 0));
3110 /* mask&set gpio interrupt polarity bits */
3112 si_gpiointpolarity(si_t
*sih
, uint32 mask
, uint32 val
, uint8 priority
)
3116 /* gpios could be shared on router platforms */
3117 if ((BUSTYPE(sih
->bustype
) == SI_BUS
) && (val
|| mask
)) {
3118 mask
= priority
? (si_gpioreservation
& mask
) :
3119 ((si_gpioreservation
| mask
) & ~(si_gpioreservation
));
3123 regoff
= OFFSETOF(chipcregs_t
, gpiointpolarity
);
3124 return (si_corereg(sih
, SI_CC_IDX
, regoff
, mask
, val
));
3127 /* mask&set gpio interrupt mask bits */
3129 si_gpiointmask(si_t
*sih
, uint32 mask
, uint32 val
, uint8 priority
)
3133 /* gpios could be shared on router platforms */
3134 if ((BUSTYPE(sih
->bustype
) == SI_BUS
) && (val
|| mask
)) {
3135 mask
= priority
? (si_gpioreservation
& mask
) :
3136 ((si_gpioreservation
| mask
) & ~(si_gpioreservation
));
3140 regoff
= OFFSETOF(chipcregs_t
, gpiointmask
);
3141 return (si_corereg(sih
, SI_CC_IDX
, regoff
, mask
, val
));
3144 /* assign the gpio to an led */
3146 si_gpioled(si_t
*sih
, uint32 mask
, uint32 val
)
3148 if (sih
->ccrev
< 16)
3151 /* gpio led powersave reg */
3152 return (si_corereg(sih
, SI_CC_IDX
, OFFSETOF(chipcregs_t
, gpiotimeroutmask
), mask
, val
));
3155 /* mask&set gpio timer val */
3157 si_gpiotimerval(si_t
*sih
, uint32 mask
, uint32 gpiotimerval
)
3159 if (sih
->ccrev
< 16)
3162 return (si_corereg(sih
, SI_CC_IDX
,
3163 OFFSETOF(chipcregs_t
, gpiotimerval
), mask
, gpiotimerval
));
3167 si_gpiopull(si_t
*sih
, bool updown
, uint32 mask
, uint32 val
)
3171 if (sih
->ccrev
< 20)
3174 offs
= (updown
? OFFSETOF(chipcregs_t
, gpiopulldown
) : OFFSETOF(chipcregs_t
, gpiopullup
));
3175 return (si_corereg(sih
, SI_CC_IDX
, offs
, mask
, val
));
3179 si_gpioevent(si_t
*sih
, uint regtype
, uint32 mask
, uint32 val
)
3183 if (sih
->ccrev
< 11)
3186 if (regtype
== GPIO_REGEVT
)
3187 offs
= OFFSETOF(chipcregs_t
, gpioevent
);
3188 else if (regtype
== GPIO_REGEVT_INTMSK
)
3189 offs
= OFFSETOF(chipcregs_t
, gpioeventintmask
);
3190 else if (regtype
== GPIO_REGEVT_INTPOL
)
3191 offs
= OFFSETOF(chipcregs_t
, gpioeventintpolarity
);
3195 return (si_corereg(sih
, SI_CC_IDX
, offs
, mask
, val
));
3199 BCMATTACHFN(si_gpio_handler_register
)(si_t
*sih
, uint32 event
,
3200 bool level
, gpio_handler_t cb
, void *arg
)
3209 if (sih
->ccrev
< 11)
3212 if ((gi
= MALLOC(sii
->osh
, sizeof(gpioh_item_t
))) == NULL
)
3215 bzero(gi
, sizeof(gpioh_item_t
));
3221 gi
->next
= sii
->gpioh_head
;
3222 sii
->gpioh_head
= gi
;
3226 gpioh_item_t
*h
= sii
->gpioh_head
;
3229 for (; h
; h
= h
->next
) {
3231 SI_ERROR(("gpiohdler=%p cb=%p event=0x%x\n",
3232 h
, h
->handler
, h
->event
));
3234 SI_ERROR(("gpiohdler total=%d\n", cnt
));
3237 return (void *)(gi
);
3241 BCMATTACHFN(si_gpio_handler_unregister
)(si_t
*sih
, void *gpioh
)
3244 gpioh_item_t
*p
, *n
;
3247 if (sih
->ccrev
< 11)
3250 ASSERT(sii
->gpioh_head
!= NULL
);
3251 if ((void*)sii
->gpioh_head
== gpioh
) {
3252 sii
->gpioh_head
= sii
->gpioh_head
->next
;
3253 MFREE(sii
->osh
, gpioh
, sizeof(gpioh_item_t
));
3256 p
= sii
->gpioh_head
;
3259 if ((void*)n
== gpioh
) {
3261 MFREE(sii
->osh
, gpioh
, sizeof(gpioh_item_t
));
3271 gpioh_item_t
*h
= sii
->gpioh_head
;
3274 for (; h
; h
= h
->next
) {
3276 SI_ERROR(("gpiohdler=%p cb=%p event=0x%x\n",
3277 h
, h
->handler
, h
->event
));
3279 SI_ERROR(("gpiohdler total=%d\n", cnt
));
3282 ASSERT(0); /* Not found in list */
3286 si_gpio_handler_process(si_t
*sih
)
3290 uint32 level
= si_gpioin(sih
);
3291 uint32 levelp
= si_gpiointpolarity(sih
, 0, 0, 0);
3292 uint32 edge
= si_gpioevent(sih
, GPIO_REGEVT
, 0, 0);
3293 uint32 edgep
= si_gpioevent(sih
, GPIO_REGEVT_INTPOL
, 0, 0);
3296 for (h
= sii
->gpioh_head
; h
!= NULL
; h
= h
->next
) {
3298 uint32 status
= (h
->level
? level
: edge
) & h
->event
;
3299 uint32 polarity
= (h
->level
? levelp
: edgep
) & h
->event
;
3301 /* polarity bitval is opposite of status bitval */
3302 if (status
^ polarity
)
3303 h
->handler(status
, h
->arg
);
3307 si_gpioevent(sih
, GPIO_REGEVT
, edge
, edge
); /* clear edge-trigger status */
3311 si_gpio_int_enable(si_t
*sih
, bool enable
)
3315 if (sih
->ccrev
< 11)
3318 offs
= OFFSETOF(chipcregs_t
, intmask
);
3319 return (si_corereg(sih
, SI_CC_IDX
, offs
, CI_GPIO
, (enable
? CI_GPIO
: 0)));
3323 /* Return the size of the specified SOCRAM bank */
3325 socram_banksize(si_info_t
*sii
, sbsocramregs_t
*regs
, uint8 idx
, uint8 mem_type
)
3327 uint banksize
, bankinfo
;
3328 uint bankidx
= idx
| (mem_type
<< SOCRAM_BANKIDX_MEMTYPE_SHIFT
);
3330 ASSERT(mem_type
<= SOCRAM_MEMTYPE_DEVRAM
);
3332 W_REG(sii
->osh
, ®s
->bankidx
, bankidx
);
3333 bankinfo
= R_REG(sii
->osh
, ®s
->bankinfo
);
3334 banksize
= SOCRAM_BANKINFO_SZBASE
* ((bankinfo
& SOCRAM_BANKINFO_SZMASK
) + 1);
3339 si_socdevram(si_t
*sih
, bool set
, uint8
*enable
, uint8
*protect
, uint8
*remap
)
3344 sbsocramregs_t
*regs
;
3350 /* Block ints and save current core */
3351 INTR_OFF(sii
, intr_val
);
3352 origidx
= si_coreidx(sih
);
3355 *enable
= *protect
= *remap
= 0;
3357 /* Switch to SOCRAM core */
3358 if (!(regs
= si_setcore(sih
, SOCRAM_CORE_ID
, 0)))
3361 /* Get info for determining size */
3362 if (!(wasup
= si_iscoreup(sih
)))
3363 si_core_reset(sih
, 0, 0);
3365 corerev
= si_corerev(sih
);
3366 if (corerev
>= 10) {
3370 uint32 bankidx
, bankinfo
;
3372 extcinfo
= R_REG(sii
->osh
, ®s
->extracoreinfo
);
3373 nb
= ((extcinfo
& SOCRAM_DEVRAMBANK_MASK
) >> SOCRAM_DEVRAMBANK_SHIFT
);
3374 for (i
= 0; i
< nb
; i
++) {
3375 bankidx
= i
| (SOCRAM_MEMTYPE_DEVRAM
<< SOCRAM_BANKIDX_MEMTYPE_SHIFT
);
3376 W_REG(sii
->osh
, ®s
->bankidx
, bankidx
);
3377 bankinfo
= R_REG(sii
->osh
, ®s
->bankinfo
);
3379 bankinfo
&= ~SOCRAM_BANKINFO_DEVRAMSEL_MASK
;
3380 bankinfo
&= ~SOCRAM_BANKINFO_DEVRAMPRO_MASK
;
3381 bankinfo
&= ~SOCRAM_BANKINFO_DEVRAMREMAP_MASK
;
3383 bankinfo
|= (1 << SOCRAM_BANKINFO_DEVRAMSEL_SHIFT
);
3385 bankinfo
|= (1 << SOCRAM_BANKINFO_DEVRAMPRO_SHIFT
);
3386 if ((corerev
>= 16) && *remap
)
3388 (1 << SOCRAM_BANKINFO_DEVRAMREMAP_SHIFT
);
3390 W_REG(sii
->osh
, ®s
->bankinfo
, bankinfo
);
3393 if (bankinfo
& SOCRAM_BANKINFO_DEVRAMSEL_MASK
) {
3395 if (bankinfo
& SOCRAM_BANKINFO_DEVRAMPRO_MASK
)
3397 if (bankinfo
& SOCRAM_BANKINFO_DEVRAMREMAP_MASK
)
3404 /* Return to previous state and core */
3406 si_core_disable(sih
, 0);
3407 si_setcoreidx(sih
, origidx
);
3410 INTR_RESTORE(sii
, intr_val
);
3414 si_socdevram_remap_isenb(si_t
*sih
)
3419 sbsocramregs_t
*regs
;
3420 bool wasup
, remap
= FALSE
;
3425 uint32 bankidx
, bankinfo
;
3429 /* Block ints and save current core */
3430 INTR_OFF(sii
, intr_val
);
3431 origidx
= si_coreidx(sih
);
3433 /* Switch to SOCRAM core */
3434 if (!(regs
= si_setcore(sih
, SOCRAM_CORE_ID
, 0)))
3437 /* Get info for determining size */
3438 if (!(wasup
= si_iscoreup(sih
)))
3439 si_core_reset(sih
, 0, 0);
3441 corerev
= si_corerev(sih
);
3442 if (corerev
>= 16) {
3443 extcinfo
= R_REG(sii
->osh
, ®s
->extracoreinfo
);
3444 nb
= ((extcinfo
& SOCRAM_DEVRAMBANK_MASK
) >> SOCRAM_DEVRAMBANK_SHIFT
);
3445 for (i
= 0; i
< nb
; i
++) {
3446 bankidx
= i
| (SOCRAM_MEMTYPE_DEVRAM
<< SOCRAM_BANKIDX_MEMTYPE_SHIFT
);
3447 W_REG(sii
->osh
, ®s
->bankidx
, bankidx
);
3448 bankinfo
= R_REG(sii
->osh
, ®s
->bankinfo
);
3449 if (bankinfo
& SOCRAM_BANKINFO_DEVRAMREMAP_MASK
) {
3456 /* Return to previous state and core */
3458 si_core_disable(sih
, 0);
3459 si_setcoreidx(sih
, origidx
);
3462 INTR_RESTORE(sii
, intr_val
);
3467 si_socdevram_pkg(si_t
*sih
)
3469 if (si_socdevram_size(sih
) > 0)
3476 si_socdevram_size(si_t
*sih
)
3482 sbsocramregs_t
*regs
;
3488 /* Block ints and save current core */
3489 INTR_OFF(sii
, intr_val
);
3490 origidx
= si_coreidx(sih
);
3492 /* Switch to SOCRAM core */
3493 if (!(regs
= si_setcore(sih
, SOCRAM_CORE_ID
, 0)))
3496 /* Get info for determining size */
3497 if (!(wasup
= si_iscoreup(sih
)))
3498 si_core_reset(sih
, 0, 0);
3500 corerev
= si_corerev(sih
);
3501 if (corerev
>= 10) {
3506 extcinfo
= R_REG(sii
->osh
, ®s
->extracoreinfo
);
3507 nb
= (((extcinfo
& SOCRAM_DEVRAMBANK_MASK
) >> SOCRAM_DEVRAMBANK_SHIFT
));
3508 for (i
= 0; i
< nb
; i
++)
3509 memsize
+= socram_banksize(sii
, regs
, i
, SOCRAM_MEMTYPE_DEVRAM
);
3512 /* Return to previous state and core */
3514 si_core_disable(sih
, 0);
3515 si_setcoreidx(sih
, origidx
);
3518 INTR_RESTORE(sii
, intr_val
);
3524 si_socdevram_remap_size(si_t
*sih
)
3529 uint32 memsize
= 0, banksz
;
3530 sbsocramregs_t
*regs
;
3536 uint32 bankidx
, bankinfo
;
3540 /* Block ints and save current core */
3541 INTR_OFF(sii
, intr_val
);
3542 origidx
= si_coreidx(sih
);
3544 /* Switch to SOCRAM core */
3545 if (!(regs
= si_setcore(sih
, SOCRAM_CORE_ID
, 0)))
3548 /* Get info for determining size */
3549 if (!(wasup
= si_iscoreup(sih
)))
3550 si_core_reset(sih
, 0, 0);
3552 corerev
= si_corerev(sih
);
3553 if (corerev
>= 16) {
3554 extcinfo
= R_REG(sii
->osh
, ®s
->extracoreinfo
);
3555 nb
= (((extcinfo
& SOCRAM_DEVRAMBANK_MASK
) >> SOCRAM_DEVRAMBANK_SHIFT
));
3558 * FIX: A0 Issue: Max addressable is 512KB, instead 640KB
3559 * Only four banks are accessible to ARM
3561 if ((corerev
== 16) && (nb
== 5))
3564 for (i
= 0; i
< nb
; i
++) {
3565 bankidx
= i
| (SOCRAM_MEMTYPE_DEVRAM
<< SOCRAM_BANKIDX_MEMTYPE_SHIFT
);
3566 W_REG(sii
->osh
, ®s
->bankidx
, bankidx
);
3567 bankinfo
= R_REG(sii
->osh
, ®s
->bankinfo
);
3568 if (bankinfo
& SOCRAM_BANKINFO_DEVRAMREMAP_MASK
) {
3569 banksz
= socram_banksize(sii
, regs
, i
, SOCRAM_MEMTYPE_DEVRAM
);
3572 /* Account only consecutive banks for now */
3578 /* Return to previous state and core */
3580 si_core_disable(sih
, 0);
3581 si_setcoreidx(sih
, origidx
);
3584 INTR_RESTORE(sii
, intr_val
);
3589 /* Return the RAM size of the SOCRAM core */
3591 si_socram_size(si_t
*sih
)
3597 sbsocramregs_t
*regs
;
3605 /* Block ints and save current core */
3606 INTR_OFF(sii
, intr_val
);
3607 origidx
= si_coreidx(sih
);
3609 /* Switch to SOCRAM core */
3610 if (!(regs
= si_setcore(sih
, SOCRAM_CORE_ID
, 0)))
3613 /* Get info for determining size */
3614 if (!(wasup
= si_iscoreup(sih
)))
3615 si_core_reset(sih
, 0, 0);
3616 corerev
= si_corerev(sih
);
3617 coreinfo
= R_REG(sii
->osh
, ®s
->coreinfo
);
3619 /* Calculate size from coreinfo based on rev */
3621 memsize
= 1 << (16 + (coreinfo
& SRCI_MS0_MASK
));
3622 else if (corerev
< 3) {
3623 memsize
= 1 << (SR_BSZ_BASE
+ (coreinfo
& SRCI_SRBSZ_MASK
));
3624 memsize
*= (coreinfo
& SRCI_SRNB_MASK
) >> SRCI_SRNB_SHIFT
;
3625 } else if ((corerev
<= 7) || (corerev
== 12)) {
3626 uint nb
= (coreinfo
& SRCI_SRNB_MASK
) >> SRCI_SRNB_SHIFT
;
3627 uint bsz
= (coreinfo
& SRCI_SRBSZ_MASK
);
3628 uint lss
= (coreinfo
& SRCI_LSS_MASK
) >> SRCI_LSS_SHIFT
;
3631 memsize
= nb
* (1 << (bsz
+ SR_BSZ_BASE
));
3633 memsize
+= (1 << ((lss
- 1) + SR_BSZ_BASE
));
3636 uint nb
= (coreinfo
& SRCI_SRNB_MASK
) >> SRCI_SRNB_SHIFT
;
3637 for (i
= 0; i
< nb
; i
++)
3638 memsize
+= socram_banksize(sii
, regs
, i
, SOCRAM_MEMTYPE_RAM
);
3641 /* Return to previous state and core */
3643 si_core_disable(sih
, 0);
3644 si_setcoreidx(sih
, origidx
);
3647 INTR_RESTORE(sii
, intr_val
);
3654 #define NOTIFY_BT_FM_DISABLE(sih, val) \
3655 si_eci_notify_bt((sih), ECI_OUT_FM_DISABLE_MASK(sih->ccrev), \
3656 ((val) << ECI_OUT_FM_DISABLE_SHIFT(sih->ccrev)), FALSE)
3658 /* Query OTP to see if FM is disabled */
3660 BCMINITFN(si_query_FMDisabled_from_OTP
)(si_t
*sih
, uint16
*FMDisabled
)
3662 int error
= BCME_OK
;
3667 /* Determine the bit for the chip */
3668 switch (CHIPID(sih
->chip
)) {
3669 case BCM4325_CHIP_ID
:
3670 if (CHIPREV(sih
->chiprev
) >= 6)
3671 bitoff
= OTP4325_FM_DISABLED_OFFSET
;
3677 /* If there is a bit for this chip, check it */
3679 if (!(wasup
= si_is_otp_powered(sih
))) {
3680 si_otp_power(sih
, TRUE
);
3683 if ((oh
= otp_init(sih
)) != NULL
)
3684 *FMDisabled
= !otp_read_bit(oh
, OTP4325_FM_DISABLED_OFFSET
);
3686 error
= BCME_NOTFOUND
;
3689 si_otp_power(sih
, FALSE
);
3699 return (!!(sih
->cccaps
& CC_CAP_ECI
));
3705 return (sih
->cccaps_ext
& CC_CAP_EXT_SECI_PRESENT
);
3708 /* ECI Init routine */
3710 BCMINITFN(si_eci_init
)(si_t
*sih
)
3716 uint16 FMDisabled
= FALSE
;
3718 /* check for ECI capability */
3719 if (!(sih
->cccaps
& CC_CAP_ECI
))
3723 fast
= SI_FAST(sii
);
3725 origidx
= sii
->curidx
;
3726 if ((cc
= (chipcregs_t
*)si_setcore(sih
, CC_CORE_ID
, 0)) == NULL
)
3728 } else if ((cc
= (chipcregs_t
*)CCREGS_FAST(sii
)) == NULL
)
3732 /* disable level based interrupts */
3733 if (sih
->ccrev
< 35) {
3734 W_REG(sii
->osh
, &cc
->eci
.lt35
.eci_intmaskhi
, 0x0);
3735 W_REG(sii
->osh
, &cc
->eci
.lt35
.eci_intmaskmi
, 0x0);
3736 W_REG(sii
->osh
, &cc
->eci
.lt35
.eci_intmasklo
, 0x0);
3739 W_REG(sii
->osh
, &cc
->eci
.ge35
.eci_intmaskhi
, 0x0);
3740 W_REG(sii
->osh
, &cc
->eci
.ge35
.eci_intmasklo
, 0x0);
3743 /* Assign eci_output bits between 'wl' and dot11mac */
3744 if (sih
->ccrev
< 35) {
3745 W_REG(sii
->osh
, &cc
->eci
.lt35
.eci_control
, ECI_MACCTRL_BITS
);
3748 W_REG(sii
->osh
, &cc
->eci
.ge35
.eci_controllo
, ECI_MACCTRLLO_BITS
);
3749 W_REG(sii
->osh
, &cc
->eci
.ge35
.eci_controlhi
, ECI_MACCTRLHI_BITS
);
3752 /* enable only edge based interrupts
3753 * only toggle on bit 62 triggers an interrupt
3755 if (sih
->ccrev
< 35) {
3756 W_REG(sii
->osh
, &cc
->eci
.lt35
.eci_eventmaskhi
, 0x0);
3757 W_REG(sii
->osh
, &cc
->eci
.lt35
.eci_eventmaskmi
, 0x0);
3758 W_REG(sii
->osh
, &cc
->eci
.lt35
.eci_eventmasklo
, 0x0);
3761 W_REG(sii
->osh
, &cc
->eci
.ge35
.eci_eventmaskhi
, 0x0);
3762 W_REG(sii
->osh
, &cc
->eci
.ge35
.eci_eventmasklo
, 0x0);
3765 /* restore previous core */
3767 si_setcoreidx(sih
, origidx
);
3769 /* if FM disabled in OTP, let BT know */
3770 if (!si_query_FMDisabled_from_OTP(sih
, &FMDisabled
)) {
3772 NOTIFY_BT_FM_DISABLE(sih
, 1);
3780 * Write values to BT on eci_output.
3783 si_eci_notify_bt(si_t
*sih
, uint32 mask
, uint32 val
, bool interrupt
)
3787 /* Nothing to do if there is no eci */
3788 if ((sih
->cccaps
& CC_CAP_ECI
) == 0)
3791 /* Clear interrupt bit by default */
3793 si_corereg(sih
, SI_CC_IDX
,
3795 OFFSETOF(chipcregs_t
, eci
.lt35
.eci_output
) :
3796 OFFSETOF(chipcregs_t
, eci
.ge35
.eci_outputlo
)),
3799 if (sih
->ccrev
>= 35) {
3800 if ((mask
& 0xFFFF0000) == ECI48_OUT_MASKMAGIC_HIWORD
) {
3801 offset
= OFFSETOF(chipcregs_t
, eci
.ge35
.eci_outputhi
);
3802 mask
= mask
& ~0xFFFF0000;
3805 offset
= OFFSETOF(chipcregs_t
, eci
.ge35
.eci_outputlo
);
3806 mask
= mask
| (1<<30);
3807 val
= val
& ~(1 << 30);
3811 offset
= OFFSETOF(chipcregs_t
, eci
.lt35
.eci_output
);
3812 val
= val
& ~(1 << 30);
3815 si_corereg(sih
, SI_CC_IDX
, offset
, mask
, val
);
3817 /* Set interrupt bit if needed */
3819 si_corereg(sih
, SI_CC_IDX
,
3821 OFFSETOF(chipcregs_t
, eci
.lt35
.eci_output
) :
3822 OFFSETOF(chipcregs_t
, eci
.ge35
.eci_outputlo
)),
3823 (1 << 30), (1 << 30));
3826 /* seci clock enable/disable */
3828 si_seci_clkreq(si_t
*sih
, bool enable
)
3838 val
= CLKCTL_STS_SECI_CLK_REQ
;
3842 offset
= OFFSETOF(chipcregs_t
, clk_ctl_st
);
3844 si_corereg(sih
, SI_CC_IDX
, offset
, CLKCTL_STS_SECI_CLK_REQ
, val
);
3849 SPINWAIT(!(si_corereg(sih
, 0, offset
, 0, 0) & CLKCTL_STS_SECI_CLK_AVAIL
),
3850 PMU_MAX_TRANSITION_DLY
);
3852 clk_ctl_st
= si_corereg(sih
, 0, offset
, 0, 0);
3854 if (!(clk_ctl_st
& CLKCTL_STS_SECI_CLK_AVAIL
)) {
3855 SI_ERROR(("SECI clock is still not available\n"));
3862 BCMINITFN(si_seci_down
)(si_t
*sih
)
3874 fast
= SI_FAST(sii
);
3877 origidx
= sii
->curidx
;
3878 if ((cc
= (chipcregs_t
*)si_setcore(sih
, CC_CORE_ID
, 0)) == NULL
)
3880 } else if ((cc
= (chipcregs_t
*)CCREGS_FAST(sii
)) == NULL
)
3883 /* 4331 X28 sign off seci */
3884 if (CHIPID(sih
->chip
) == BCM4331_CHIP_ID
) {
3886 seci_conf
= R_REG(sii
->osh
, &cc
->SECI_config
);
3887 seci_conf
|= SECI_UPD_SECI
;
3888 W_REG(sii
->osh
, &cc
->SECI_config
, seci_conf
);
3889 SPINWAIT((R_REG(sii
->osh
, &cc
->SECI_config
) & SECI_UPD_SECI
), 1000);
3892 W_REG(sii
->osh
, &cc
->seci_uart_data
, SECI_SIGNOFF_0
);
3893 W_REG(sii
->osh
, &cc
->seci_uart_data
, SECI_SIGNOFF_1
);
3894 SPINWAIT((R_REG(sii
->osh
, &cc
->seci_uart_lsr
) & (1 << 2)), 1000);
3895 /* put seci in reset */
3896 seci_conf
= R_REG(sii
->osh
, &cc
->SECI_config
);
3897 seci_conf
&= ~SECI_ENAB_SECI_ECI
;
3898 W_REG(sii
->osh
, &cc
->SECI_config
, seci_conf
);
3899 seci_conf
|= SECI_RESET
;
3900 W_REG(sii
->osh
, &cc
->SECI_config
, seci_conf
);
3903 /* bring down the clock if up */
3904 si_seci_clkreq(sih
, FALSE
);
3906 /* restore previous core */
3908 si_setcoreidx(sih
, origidx
);
3912 si_seci_upd(si_t
*sih
, bool enable
)
3925 fast
= SI_FAST(sii
);
3926 INTR_OFF(sii
, intr_val
);
3928 origidx
= sii
->curidx
;
3929 if ((cc
= (chipcregs_t
*)si_setcore(sih
, CC_CORE_ID
, 0)) == NULL
)
3931 } else if ((cc
= (chipcregs_t
*)CCREGS_FAST(sii
)) == NULL
)
3936 /* 4331 Select SECI based on enable input */
3937 if (CHIPID(sih
->chip
) == BCM4331_CHIP_ID
) {
3938 regval
= R_REG(sii
->osh
, &cc
->chipcontrol
);
3940 regval
|= CCTRL4331_SECI
;
3942 regval
&= ~CCTRL4331_SECI
;
3943 W_REG(sii
->osh
, &cc
->chipcontrol
, regval
);
3946 /* restore previous core */
3948 si_setcoreidx(sih
, origidx
);
3950 INTR_RESTORE(sii
, intr_val
);
3953 /* SECI Init routine, pass in seci_mode */
3955 BCMINITFN(si_seci_init
)(si_t
*sih
, uint8 seci_mode
)
3966 if (sih
->ccrev
< 35)
3972 if (seci_mode
> SECI_MODE_MASK
)
3976 fast
= SI_FAST(sii
);
3978 origidx
= sii
->curidx
;
3979 if ((ptr
= si_setcore(sih
, CC_CORE_ID
, 0)) == NULL
)
3981 } else if ((ptr
= CCREGS_FAST(sii
)) == NULL
)
3983 cc
= (chipcregs_t
*)ptr
;
3987 /* 43236 (ccrev 36) muxes SECI on JTAG pins. Select SECI. */
3988 if (CHIPID(sih
->chip
) == BCM43236_CHIP_ID
||
3989 CHIPID(sih
->chip
) == BCM4331_CHIP_ID
) {
3990 regval
= R_REG(sii
->osh
, &cc
->chipcontrol
);
3991 regval
|= CCTRL4331_SECI
;
3992 W_REG(sii
->osh
, &cc
->chipcontrol
, regval
);
3996 if ((CHIPID(sih
->chip
) == BCM43236_CHIP_ID
) ||
3998 regval
= R_REG(sii
->osh
, &cc
->jtagctrl
);
4000 W_REG(sii
->osh
, &cc
->jtagctrl
, regval
);
4003 /* enable SECI clock */
4004 si_seci_clkreq(sih
, TRUE
);
4006 /* put the SECI in reset */
4007 seci_conf
= R_REG(sii
->osh
, &cc
->SECI_config
);
4008 seci_conf
&= ~SECI_ENAB_SECI_ECI
;
4009 W_REG(sii
->osh
, &cc
->SECI_config
, seci_conf
);
4010 seci_conf
= SECI_RESET
;
4011 W_REG(sii
->osh
, &cc
->SECI_config
, seci_conf
);
4013 /* set force-low, and set EN_SECI for all non-legacy modes */
4014 seci_conf
|= SECI_ENAB_SECIOUT_DIS
;
4015 if ((seci_mode
== SECI_MODE_UART
) || (seci_mode
== SECI_MODE_SECI
) ||
4016 (seci_mode
== SECI_MODE_HALF_SECI
))
4018 seci_conf
|= SECI_ENAB_SECI_ECI
;
4020 W_REG(sii
->osh
, &cc
->SECI_config
, seci_conf
);
4022 /* take seci out of reset */
4023 seci_conf
= R_REG(sii
->osh
, &cc
->SECI_config
);
4024 seci_conf
&= ~(SECI_RESET
);
4025 W_REG(sii
->osh
, &cc
->SECI_config
, seci_conf
);
4027 /* set UART/SECI baud rate */
4028 /* hard-coded at 4MBaud for now */
4029 if ((seci_mode
== SECI_MODE_UART
) || (seci_mode
== SECI_MODE_SECI
) ||
4030 (seci_mode
== SECI_MODE_HALF_SECI
)) {
4031 offset
= OFFSETOF(chipcregs_t
, seci_uart_bauddiv
);
4032 si_corereg(sih
, SI_CC_IDX
, offset
, 0xFF, 0xFF); /* 4MBaud */
4033 offset
= OFFSETOF(chipcregs_t
, seci_uart_baudadj
);
4034 if ((CHIPID(sih
->chip
) == BCM43236_CHIP_ID
) ||
4035 (CHIPID(sih
->chip
) == BCM4331_CHIP_ID
) ||
4037 /* 43236 ccrev = 36 and MAC clk = 96MHz */
4038 /* 4331,43143 MAC clk = 96MHz */
4039 si_corereg(sih
, SI_CC_IDX
, offset
, 0xFF, 0x44);
4042 /* 4336 MAC clk is 80MHz */
4043 si_corereg(sih
, SI_CC_IDX
, offset
, 0xFF, 0x22);
4046 /* LCR/MCR settings */
4047 offset
= OFFSETOF(chipcregs_t
, seci_uart_lcr
);
4048 si_corereg(sih
, SI_CC_IDX
, offset
, 0xFF,
4049 (SECI_UART_LCR_RX_EN
| SECI_UART_LCR_TXO_EN
)); /* 0x28 */
4050 offset
= OFFSETOF(chipcregs_t
, seci_uart_mcr
);
4051 si_corereg(sih
, SI_CC_IDX
, offset
,
4052 0xFF, (SECI_UART_MCR_TX_EN
| SECI_UART_MCR_BAUD_ADJ_EN
)); /* 0x81 */
4054 /* Give control of ECI output regs to MAC core */
4055 offset
= OFFSETOF(chipcregs_t
, eci
.ge35
.eci_controllo
);
4056 si_corereg(sih
, SI_CC_IDX
, offset
, 0xFFFFFFFF, ECI_MACCTRLLO_BITS
);
4057 offset
= OFFSETOF(chipcregs_t
, eci
.ge35
.eci_controlhi
);
4058 si_corereg(sih
, SI_CC_IDX
, offset
, 0xFFFF, ECI_MACCTRLHI_BITS
);
4061 /* set the seci mode in seci conf register */
4062 seci_conf
= R_REG(sii
->osh
, &cc
->SECI_config
);
4063 seci_conf
&= ~(SECI_MODE_MASK
<< SECI_MODE_SHIFT
);
4064 seci_conf
|= (seci_mode
<< SECI_MODE_SHIFT
);
4065 W_REG(sii
->osh
, &cc
->SECI_config
, seci_conf
);
4067 /* Clear force-low bit */
4068 seci_conf
= R_REG(sii
->osh
, &cc
->SECI_config
);
4069 seci_conf
&= ~SECI_ENAB_SECIOUT_DIS
;
4070 W_REG(sii
->osh
, &cc
->SECI_config
, seci_conf
);
4072 /* restore previous core */
4074 si_setcoreidx(sih
, origidx
);
4078 #endif /* BCMECICOEX */
4081 si_btcgpiowar(si_t
*sih
)
4090 /* Make sure that there is ChipCommon core present &&
4091 * UART_TX is strapped to 1
4093 if (!(sih
->cccaps
& CC_CAP_UARTGPIO
))
4096 /* si_corereg cannot be used as we have to guarantee 8-bit read/writes */
4097 INTR_OFF(sii
, intr_val
);
4099 origidx
= si_coreidx(sih
);
4101 cc
= (chipcregs_t
*)si_setcore(sih
, CC_CORE_ID
, 0);
4104 W_REG(sii
->osh
, &cc
->uart0mcr
, R_REG(sii
->osh
, &cc
->uart0mcr
) | 0x04);
4106 /* restore the original index */
4107 si_setcoreidx(sih
, origidx
);
4109 INTR_RESTORE(sii
, intr_val
);
4113 si_chipcontrl_btshd0_4331(si_t
*sih
, bool on
)
4123 INTR_OFF(sii
, intr_val
);
4125 origidx
= si_coreidx(sih
);
4127 cc
= (chipcregs_t
*)si_setcore(sih
, CC_CORE_ID
, 0);
4129 val
= R_REG(sii
->osh
, &cc
->chipcontrol
);
4131 /* bt_shd0 controls are same for 4331 chiprevs 0 and 1, packages 12x9 and 12x12 */
4133 /* Enable bt_shd0 on gpio4: */
4134 val
|= (CCTRL4331_BT_SHD0_ON_GPIO4
);
4135 W_REG(sii
->osh
, &cc
->chipcontrol
, val
);
4137 val
&= ~(CCTRL4331_BT_SHD0_ON_GPIO4
);
4138 W_REG(sii
->osh
, &cc
->chipcontrol
, val
);
4141 /* restore the original index */
4142 si_setcoreidx(sih
, origidx
);
4144 INTR_RESTORE(sii
, intr_val
);
4148 si_chipcontrl_restore(si_t
*sih
, uint32 val
)
4155 origidx
= si_coreidx(sih
);
4156 cc
= (chipcregs_t
*)si_setcore(sih
, CC_CORE_ID
, 0);
4157 W_REG(sii
->osh
, &cc
->chipcontrol
, val
);
4158 si_setcoreidx(sih
, origidx
);
4162 si_chipcontrl_read(si_t
*sih
)
4170 origidx
= si_coreidx(sih
);
4171 cc
= (chipcregs_t
*)si_setcore(sih
, CC_CORE_ID
, 0);
4172 val
= R_REG(sii
->osh
, &cc
->chipcontrol
);
4173 si_setcoreidx(sih
, origidx
);
4178 si_chipcontrl_epa4331(si_t
*sih
, bool on
)
4186 origidx
= si_coreidx(sih
);
4188 cc
= (chipcregs_t
*)si_setcore(sih
, CC_CORE_ID
, 0);
4190 val
= R_REG(sii
->osh
, &cc
->chipcontrol
);
4193 if (sih
->chippkg
== 9 || sih
->chippkg
== 0xb) {
4194 val
|= (CCTRL4331_EXTPA_EN
| CCTRL4331_EXTPA_ON_GPIO2_5
);
4195 /* Ext PA Controls for 4331 12x9 Package */
4196 W_REG(sii
->osh
, &cc
->chipcontrol
, val
);
4198 /* Ext PA Controls for 4331 12x12 Package */
4199 if (sih
->chiprev
> 0) {
4200 W_REG(sii
->osh
, &cc
->chipcontrol
, val
|
4201 (CCTRL4331_EXTPA_EN
) | (CCTRL4331_EXTPA_EN2
));
4203 W_REG(sii
->osh
, &cc
->chipcontrol
, val
| (CCTRL4331_EXTPA_EN
));
4207 val
&= ~(CCTRL4331_EXTPA_EN
| CCTRL4331_EXTPA_EN2
| CCTRL4331_EXTPA_ON_GPIO2_5
);
4208 W_REG(sii
->osh
, &cc
->chipcontrol
, val
);
4211 si_setcoreidx(sih
, origidx
);
4214 /* switch muxed pins, on: SROM, off: FEMCTRL */
4216 si_chipcontrl_srom4360(si_t
*sih
, bool on
)
4224 origidx
= si_coreidx(sih
);
4226 cc
= (chipcregs_t
*)si_setcore(sih
, CC_CORE_ID
, 0);
4228 val
= R_REG(sii
->osh
, &cc
->chipcontrol
);
4231 val
&= ~(CCTRL4360_SECI_MODE
|
4232 CCTRL4360_BTSWCTRL_MODE
|
4233 CCTRL4360_EXTRA_FEMCTRL_MODE
|
4234 CCTRL4360_BT_LGCY_MODE
|
4235 CCTRL4360_CORE2FEMCTRL4_ON
);
4237 W_REG(sii
->osh
, &cc
->chipcontrol
, val
);
4241 si_setcoreidx(sih
, origidx
);
4245 si_chipcontrl_epa4331_wowl(si_t
*sih
, bool enter_wowl
)
4253 sel_chip
= (CHIPID(sih
->chip
) == BCM4331_CHIP_ID
) ||
4254 (CHIPID(sih
->chip
) == BCM43431_CHIP_ID
);
4255 sel_chip
&= ((sih
->chippkg
== 9 || sih
->chippkg
== 0xb));
4261 origidx
= si_coreidx(sih
);
4263 cc
= (chipcregs_t
*)si_setcore(sih
, CC_CORE_ID
, 0);
4265 val
= R_REG(sii
->osh
, &cc
->chipcontrol
);
4268 val
|= CCTRL4331_EXTPA_EN
;
4269 W_REG(sii
->osh
, &cc
->chipcontrol
, val
);
4271 val
|= (CCTRL4331_EXTPA_EN
| CCTRL4331_EXTPA_ON_GPIO2_5
);
4272 W_REG(sii
->osh
, &cc
->chipcontrol
, val
);
4274 si_setcoreidx(sih
, origidx
);
4278 si_pll_reset(si_t
*sih
)
4285 INTR_OFF(sii
, intr_val
);
4286 err
= si_pll_minresmask_reset(sih
, sii
->osh
);
4287 INTR_RESTORE(sii
, intr_val
);
4291 /* Enable BT-COEX & Ex-PA for 4313 */
4293 si_epa_4313war(si_t
*sih
)
4300 origidx
= si_coreidx(sih
);
4302 cc
= (chipcregs_t
*)si_setcore(sih
, CC_CORE_ID
, 0);
4305 W_REG(sii
->osh
, &cc
->gpiocontrol
,
4306 R_REG(sii
->osh
, &cc
->gpiocontrol
) | GPIO_CTRL_EPA_EN_MASK
);
4308 si_setcoreidx(sih
, origidx
);
4312 si_clk_pmu_htavail_set(si_t
*sih
, bool set_clear
)
4317 si_pmu_minresmask_htavail_set(sih
, sii
->osh
, set_clear
);
4320 /* WL/BT control for 4313 btcombo boards >= P250 */
4322 si_btcombo_p250_4313_war(si_t
*sih
)
4329 origidx
= si_coreidx(sih
);
4331 cc
= (chipcregs_t
*)si_setcore(sih
, CC_CORE_ID
, 0);
4332 W_REG(sii
->osh
, &cc
->gpiocontrol
,
4333 R_REG(sii
->osh
, &cc
->gpiocontrol
) | GPIO_CTRL_5_6_EN_MASK
);
4335 W_REG(sii
->osh
, &cc
->gpioouten
,
4336 R_REG(sii
->osh
, &cc
->gpioouten
) | GPIO_CTRL_5_6_EN_MASK
);
4338 si_setcoreidx(sih
, origidx
);
4341 si_btc_enable_chipcontrol(si_t
*sih
)
4348 origidx
= si_coreidx(sih
);
4350 cc
= (chipcregs_t
*)si_setcore(sih
, CC_CORE_ID
, 0);
4353 W_REG(sii
->osh
, &cc
->chipcontrol
,
4354 R_REG(sii
->osh
, &cc
->chipcontrol
) | CC_BTCOEX_EN_MASK
);
4356 si_setcoreidx(sih
, origidx
);
4359 si_btcombo_43228_war(si_t
*sih
)
4366 origidx
= si_coreidx(sih
);
4368 cc
= (chipcregs_t
*)si_setcore(sih
, CC_CORE_ID
, 0);
4370 W_REG(sii
->osh
, &cc
->gpioouten
, GPIO_CTRL_7_6_EN_MASK
);
4371 W_REG(sii
->osh
, &cc
->gpioout
, GPIO_OUT_7_EN_MASK
);
4373 si_setcoreidx(sih
, origidx
);
4376 /* check if the device is removed */
4378 si_deviceremoved(si_t
*sih
)
4385 switch (BUSTYPE(sih
->bustype
)) {
4387 ASSERT(sii
->osh
!= NULL
);
4388 w
= OSL_PCI_READ_CONFIG(sii
->osh
, PCI_CFG_VID
, sizeof(uint32
));
4389 if ((w
& 0xFFFF) != VENDOR_BROADCOM
)
4397 si_is_sprom_available(si_t
*sih
)
4399 if (sih
->ccrev
>= 31) {
4405 if ((sih
->cccaps
& CC_CAP_SROM
) == 0)
4409 origidx
= sii
->curidx
;
4410 cc
= si_setcoreidx(sih
, SI_CC_IDX
);
4411 sromctrl
= R_REG(sii
->osh
, &cc
->sromcontrol
);
4412 si_setcoreidx(sih
, origidx
);
4413 return (sromctrl
& SRC_PRESENT
);
4416 switch (CHIPID(sih
->chip
)) {
4417 case BCM4312_CHIP_ID
:
4418 return ((sih
->chipst
& CST4312_SPROM_OTP_SEL_MASK
) != CST4312_OTP_SEL
);
4419 case BCM4325_CHIP_ID
:
4420 return (sih
->chipst
& CST4325_SPROM_SEL
) != 0;
4421 case BCM4322_CHIP_ID
: case BCM43221_CHIP_ID
: case BCM43231_CHIP_ID
:
4422 case BCM43222_CHIP_ID
: case BCM43111_CHIP_ID
: case BCM43112_CHIP_ID
:
4423 case BCM4342_CHIP_ID
: {
4425 spromotp
= (sih
->chipst
& CST4322_SPROM_OTP_SEL_MASK
) >>
4426 CST4322_SPROM_OTP_SEL_SHIFT
;
4427 return (spromotp
& CST4322_SPROM_PRESENT
) != 0;
4429 case BCM4329_CHIP_ID
:
4430 return (sih
->chipst
& CST4329_SPROM_SEL
) != 0;
4431 case BCM4315_CHIP_ID
:
4432 return (sih
->chipst
& CST4315_SPROM_SEL
) != 0;
4433 case BCM4319_CHIP_ID
:
4434 return (sih
->chipst
& CST4319_SPROM_SEL
) != 0;
4435 case BCM4336_CHIP_ID
:
4436 case BCM43362_CHIP_ID
:
4437 return (sih
->chipst
& CST4336_SPROM_PRESENT
) != 0;
4438 case BCM4330_CHIP_ID
:
4439 return (sih
->chipst
& CST4330_SPROM_PRESENT
) != 0;
4440 case BCM4313_CHIP_ID
:
4441 return (sih
->chipst
& CST4313_SPROM_PRESENT
) != 0;
4442 case BCM4331_CHIP_ID
:
4443 case BCM43431_CHIP_ID
:
4444 return (sih
->chipst
& CST4331_SPROM_PRESENT
) != 0;
4445 case BCM43239_CHIP_ID
:
4446 return ((sih
->chipst
& CST43239_SPROM_MASK
) &&
4447 !(sih
->chipst
& CST43239_SFLASH_MASK
));
4448 case BCM4324_CHIP_ID
:
4449 return ((sih
->chipst
& CST4324_SPROM_MASK
) &&
4450 !(sih
->chipst
& CST4324_SFLASH_MASK
));
4451 case BCM4335_CHIP_ID
:
4452 return ((sih
->chipst
& CST4335_SPROM_MASK
) &&
4453 !(sih
->chipst
& CST4335_SFLASH_MASK
));
4454 case BCM43131_CHIP_ID
:
4455 case BCM43217_CHIP_ID
:
4456 case BCM43227_CHIP_ID
:
4457 case BCM43228_CHIP_ID
:
4458 case BCM43428_CHIP_ID
:
4459 return (sih
->chipst
& CST43228_OTP_PRESENT
) != CST43228_OTP_PRESENT
;
4466 si_is_otp_disabled(si_t
*sih
)
4468 switch (CHIPID(sih
->chip
)) {
4469 case BCM4325_CHIP_ID
:
4470 return (sih
->chipst
& CST4325_SPROM_OTP_SEL_MASK
) == CST4325_OTP_PWRDN
;
4471 case BCM4322_CHIP_ID
:
4472 case BCM43221_CHIP_ID
:
4473 case BCM43231_CHIP_ID
:
4474 case BCM4342_CHIP_ID
:
4475 return (((sih
->chipst
& CST4322_SPROM_OTP_SEL_MASK
) >>
4476 CST4322_SPROM_OTP_SEL_SHIFT
) & CST4322_OTP_PRESENT
) !=
4477 CST4322_OTP_PRESENT
;
4478 case BCM4329_CHIP_ID
:
4479 return (sih
->chipst
& CST4329_SPROM_OTP_SEL_MASK
) == CST4329_OTP_PWRDN
;
4480 case BCM4315_CHIP_ID
:
4481 return (sih
->chipst
& CST4315_SPROM_OTP_SEL_MASK
) == CST4315_OTP_PWRDN
;
4482 case BCM4319_CHIP_ID
:
4483 return (sih
->chipst
& CST4319_SPROM_OTP_SEL_MASK
) == CST4319_OTP_PWRDN
;
4484 case BCM4336_CHIP_ID
:
4485 case BCM43362_CHIP_ID
:
4486 return ((sih
->chipst
& CST4336_OTP_PRESENT
) == 0);
4487 case BCM4330_CHIP_ID
:
4488 return ((sih
->chipst
& CST4330_OTP_PRESENT
) == 0);
4489 case BCM43237_CHIP_ID
:
4491 case BCM4313_CHIP_ID
:
4492 return (sih
->chipst
& CST4313_OTP_PRESENT
) == 0;
4493 case BCM4331_CHIP_ID
:
4494 return (sih
->chipst
& CST4331_OTP_PRESENT
) != CST4331_OTP_PRESENT
;
4495 case BCM4360_CHIP_ID
:
4496 case BCM43526_CHIP_ID
:
4497 case BCM43460_CHIP_ID
:
4498 case BCM4352_CHIP_ID
:
4499 /* 4360 OTP is always powered and enabled */
4501 /* These chips always have their OTP on */
4502 case BCM43111_CHIP_ID
: case BCM43112_CHIP_ID
: case BCM43222_CHIP_ID
:
4503 case BCM43224_CHIP_ID
: case BCM43225_CHIP_ID
:
4504 case BCM43421_CHIP_ID
:
4505 case BCM43226_CHIP_ID
:
4506 case BCM43235_CHIP_ID
: case BCM43236_CHIP_ID
: case BCM43238_CHIP_ID
:
4507 case BCM43234_CHIP_ID
: case BCM43239_CHIP_ID
: case BCM4324_CHIP_ID
:
4508 case BCM43431_CHIP_ID
:
4509 case BCM43131_CHIP_ID
:
4510 case BCM43217_CHIP_ID
:
4511 case BCM43227_CHIP_ID
:
4512 case BCM43228_CHIP_ID
:
4513 case BCM43428_CHIP_ID
: case BCM4335_CHIP_ID
:
4520 si_is_otp_powered(si_t
*sih
)
4522 if (PMUCTL_ENAB(sih
))
4523 return si_pmu_is_otp_powered(sih
, si_osh(sih
));
4528 si_otp_power(si_t
*sih
, bool on
)
4530 if (PMUCTL_ENAB(sih
))
4531 si_pmu_otp_power(sih
, si_osh(sih
), on
);
4536 #if defined(BCMDBG) || defined(WLTEST) || defined(BCMDBG_ERR)
4537 si_is_sprom_enabled(si_t
*sih
)
4539 BCMATTACHFN(si_is_sprom_enabled
)(si_t
*sih
)
4542 if (PMUCTL_ENAB(sih
))
4543 return si_pmu_is_sprom_enabled(sih
, si_osh(sih
));
4548 #if defined(BCMDBG) || defined(WLTEST) || defined(BCMDBG_ERR)
4549 si_sprom_enable(si_t
*sih
, bool enable
)
4551 BCMATTACHFN(si_sprom_enable
)(si_t
*sih
, bool enable
)
4554 if (PMUCTL_ENAB(sih
))
4555 si_pmu_sprom_enable(sih
, si_osh(sih
), enable
);
4558 /* Return BCME_NOTFOUND if the card doesn't have CIS format nvram */
4560 si_cis_source(si_t
*sih
)
4562 /* Many chips have the same mapping of their chipstatus field */
4563 static const uint cis_sel
[] = { CIS_DEFAULT
, CIS_SROM
, CIS_OTP
, CIS_SROM
};
4564 static const uint cis_43236_sel
[] = { CIS_DEFAULT
, CIS_OTP
};
4566 /* PCI chips use SROM format instead of CIS */
4567 if (BUSTYPE(sih
->bustype
) == PCI_BUS
)
4568 return BCME_NOTFOUND
;
4570 switch (CHIPID(sih
->chip
)) {
4571 case BCM4325_CHIP_ID
:
4572 return ((sih
->chipst
& CST4325_SPROM_OTP_SEL_MASK
) >= ARRAYSIZE(cis_sel
)) ?
4573 CIS_DEFAULT
: cis_sel
[(sih
->chipst
& CST4325_SPROM_OTP_SEL_MASK
)];
4574 case BCM4322_CHIP_ID
: case BCM43221_CHIP_ID
: case BCM43231_CHIP_ID
:
4575 case BCM4342_CHIP_ID
: {
4576 uint8 strap
= (sih
->chipst
& CST4322_SPROM_OTP_SEL_MASK
) >>
4577 CST4322_SPROM_OTP_SEL_SHIFT
;
4579 return ((strap
>= ARRAYSIZE(cis_sel
)) ? CIS_DEFAULT
: cis_sel
[strap
]);
4583 case BCM43235_CHIP_ID
: case BCM43236_CHIP_ID
: case BCM43238_CHIP_ID
:
4584 case BCM43234_CHIP_ID
: {
4585 uint8 strap
= (sih
->chipst
& CST43236_OTP_SEL_MASK
) >>
4586 CST43236_OTP_SEL_SHIFT
;
4587 return ((strap
>= ARRAYSIZE(cis_43236_sel
)) ? CIS_DEFAULT
: cis_43236_sel
[strap
]);
4590 case BCM4329_CHIP_ID
:
4591 return ((sih
->chipst
& CST4329_SPROM_OTP_SEL_MASK
) >= ARRAYSIZE(cis_sel
)) ?
4592 CIS_DEFAULT
: cis_sel
[(sih
->chipst
& CST4329_SPROM_OTP_SEL_MASK
)];
4594 case BCM4315_CHIP_ID
:
4596 return ((sih
->chipst
& CST4315_SPROM_OTP_SEL_MASK
) >= ARRAYSIZE(cis_sel
)) ?
4597 CIS_DEFAULT
: cis_sel
[(sih
->chipst
& CST4315_SPROM_OTP_SEL_MASK
)];
4599 case BCM4319_CHIP_ID
: {
4600 uint cis_sel4319
= ((sih
->chipst
& CST4319_SPROM_OTP_SEL_MASK
) >>
4601 CST4319_SPROM_OTP_SEL_SHIFT
);
4602 return (cis_sel4319
>= ARRAYSIZE(cis_sel
)) ? CIS_DEFAULT
: cis_sel
[cis_sel4319
];
4604 case BCM4336_CHIP_ID
:
4605 case BCM43362_CHIP_ID
: {
4606 if (sih
->chipst
& CST4336_SPROM_PRESENT
)
4608 if (sih
->chipst
& CST4336_OTP_PRESENT
)
4612 case BCM4330_CHIP_ID
: {
4613 if (sih
->chipst
& CST4330_SPROM_PRESENT
)
4615 if (sih
->chipst
& CST4330_OTP_PRESENT
)
4619 case BCM43239_CHIP_ID
: {
4620 if ((sih
->chipst
& CST43239_SPROM_MASK
) && !(sih
->chipst
& CST43239_SFLASH_MASK
))
4624 case BCM4324_CHIP_ID
:
4626 if ((sih
->chipst
& CST4324_SPROM_MASK
) && !(sih
->chipst
& CST4324_SFLASH_MASK
))
4630 case BCM4335_CHIP_ID
: {
4631 if ((sih
->chipst
& CST4335_SPROM_MASK
) && !(sih
->chipst
& CST4335_SFLASH_MASK
))
4635 case BCM43237_CHIP_ID
: {
4636 uint8 strap
= (sih
->chipst
& CST43237_OTP_SEL_MASK
) >>
4637 CST43237_OTP_SEL_SHIFT
;
4638 return ((strap
>= ARRAYSIZE(cis_43236_sel
)) ? CIS_DEFAULT
: cis_43236_sel
[strap
]);
4641 case BCM4360_CHIP_ID
:
4642 case BCM43526_CHIP_ID
: {
4643 if ((sih
->chipst
& CST4360_OTP_ENABLED
))
4652 /* Read/write to OTP to find the FAB manf */
4654 BCMINITFN(si_otp_fabid
)(si_t
*sih
, uint16
*fabid
, bool rw
)
4656 int error
= BCME_OK
;
4658 uint16 data
, mask
= 0, shift
= 0;
4660 switch (CHIPID(sih
->chip
)) {
4661 case BCM4329_CHIP_ID
:
4662 /* Bit locations 133-130 */
4663 if (sih
->chiprev
>= 3) {
4669 case BCM43362_CHIP_ID
:
4670 /* Bit locations 134-130 */
4675 case BCM5356_CHIP_ID
:
4676 /* Bit locations 133-130 */
4688 error
= otp_read_word(sih
, offset
, &data
);
4690 *fabid
= (data
& mask
) >> shift
;
4693 data
= (data
<< shift
) & mask
;
4695 error
= otp_write_word(sih
, offset
, data
);
4696 #endif /* BCMNVRAMW */
4701 uint16
BCMINITFN(si_fabid
)(si_t
*sih
)
4706 switch (CHIPID(sih
->chip
)) {
4707 case BCM4329_CHIP_ID
:
4708 case BCM43362_CHIP_ID
:
4709 case BCM5356_CHIP_ID
:
4710 if (si_otp_fabid(sih
, &fabid
, TRUE
) != BCME_OK
)
4712 SI_ERROR(("si_fabid: reading fabid from otp failed.\n"));
4716 case BCM4330_CHIP_ID
:
4717 data
= si_corereg(sih
, SI_CC_IDX
, OFFSETOF(chipcregs_t
, chipcontrol
),
4719 fabid
= ((data
& 0xc0000000) >> 30)+((data
& 0x20000000) >> 27);
4722 case BCM4334_CHIP_ID
:
4723 data
= si_corereg(sih
, SI_CC_IDX
, OFFSETOF(chipcregs_t
, fabid
), 0, 0);
4727 case BCM4324_CHIP_ID
:
4728 case BCM4335_CHIP_ID
:
4729 data
= si_corereg(sih
, SI_CC_IDX
, OFFSETOF(chipcregs_t
, fabid
), 0, 0);
4740 uint32
si_get_sromctl(si_t
*sih
)
4748 origidx
= si_coreidx(sih
);
4749 cc
= si_setcoreidx(sih
, SI_CC_IDX
);
4750 ASSERT((uintptr
)cc
);
4752 sromctl
= R_REG(osh
, &cc
->sromcontrol
);
4754 /* return to the original core */
4755 si_setcoreidx(sih
, origidx
);
4759 int si_set_sromctl(si_t
*sih
, uint32 value
)
4766 origidx
= si_coreidx(sih
);
4767 cc
= si_setcoreidx(sih
, SI_CC_IDX
);
4768 ASSERT((uintptr
)cc
);
4770 /* get chipcommon rev */
4771 if (si_corerev(sih
) < 32)
4772 return BCME_UNSUPPORTED
;
4774 W_REG(osh
, &cc
->sromcontrol
, value
);
4776 /* return to the original core */
4777 si_setcoreidx(sih
, origidx
);