2 * Misc utility routines for accessing chip-specific features
3 * of the SiliconBackplane-based Broadcom chips.
5 * Copyright (C) 2012, 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 350835 2012-08-15 22:17:37Z $
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 #if !defined(_CFE_) || defined(CFG_WL)
60 static void si_sromvars_fixup_4331(si_t
*sih
, char *pvars
);
61 #endif /* !_CFE_ || CFG_WL */
63 /* dev path concatenation util */
64 static char *si_devpathvar(si_t
*sih
, char *var
, int len
, const char *name
);
65 static bool _si_clkctl_cc(si_info_t
*sii
, uint mode
);
66 static bool si_ispcie(si_info_t
*sii
);
67 static uint
BCMINITFN(socram_banksize
)(si_info_t
*sii
, sbsocramregs_t
*r
, uint8 idx
, uint8 mtype
);
69 void si_gci_chipctrl_overrides(osl_t
*osh
, si_t
*sih
, char *pvars
);
72 /* global variable to indicate reservation/release of gpio's */
73 static uint32 si_gpioreservation
= 0;
75 /* global flag to prevent shared resources from being initialized multiple times in si_attach() */
77 int do_4360_pcie2_war
= 0;
80 * Allocate a si handle.
81 * devid - pci device id (used to determine chip#)
82 * osh - opaque OS handle
83 * regs - virtual address of initial core registers
84 * bustype - pci/pcmcia/sb/sdio/etc
85 * vars - pointer to a pointer area for "environment" variables
86 * varsz - pointer to int to return the size of the vars
89 BCMATTACHFN(si_attach
)(uint devid
, osl_t
*osh
, void *regs
,
90 uint bustype
, void *sdh
, char **vars
, uint
*varsz
)
95 if ((sii
= MALLOC(osh
, sizeof (si_info_t
))) == NULL
) {
96 SI_ERROR(("si_attach: malloc failed! malloced %d bytes\n", MALLOCED(osh
)));
100 if (si_doattach(sii
, devid
, osh
, regs
, bustype
, sdh
, vars
, varsz
) == NULL
) {
101 MFREE(osh
, sii
, sizeof(si_info_t
));
104 sii
->vars
= vars
? *vars
: NULL
;
105 sii
->varsz
= varsz
? *varsz
: 0;
110 /* global kernel resource */
111 static si_info_t ksii
;
113 static uint32 wd_msticks
; /* watchdog timer ticks normalized to ms */
115 /* generic kernel variant of si_attach() */
117 BCMATTACHFN(si_kattach
)(osl_t
*osh
)
119 static bool ksii_attached
= FALSE
;
121 if (!ksii_attached
) {
123 #ifndef SI_ENUM_BASE_VARIABLE
124 regs
= REG_MAP(SI_ENUM_BASE
, SI_CORE_SIZE
);
127 if (si_doattach(&ksii
, BCM4710_DEVICE_ID
, osh
, regs
,
129 osh
!= SI_OSH
? &ksii
.vars
: NULL
,
130 osh
!= SI_OSH
? &ksii
.varsz
: NULL
) == NULL
) {
131 SI_ERROR(("si_kattach: si_doattach failed\n"));
137 /* save ticks normalized to ms for si_watchdog_ms() */
138 if (PMUCTL_ENAB(&ksii
.pub
)) {
139 if (CHIPID(ksii
.pub
.chip
) == BCM4706_CHIP_ID
) {
140 /* 4706 CC and PMU watchdogs are clocked at 1/4 of ALP clock */
141 wd_msticks
= (si_alp_clock(&ksii
.pub
) / 4) / 1000;
144 /* based on 32KHz ILP clock */
147 if (ksii
.pub
.ccrev
< 18)
148 wd_msticks
= si_clock(&ksii
.pub
) / 1000;
150 wd_msticks
= si_alp_clock(&ksii
.pub
) / 1000;
153 ksii_attached
= TRUE
;
154 SI_MSG(("si_kattach done. ccrev = %d, wd_msticks = %d\n",
155 ksii
.pub
.ccrev
, wd_msticks
));
162 si_ldo_war(si_t
*sih
, uint devid
)
164 si_info_t
*sii
= SI_INFO(sih
);
167 void *regs
= sii
->curmap
;
170 rev_id
= OSL_PCI_READ_CONFIG(sii
->osh
, PCI_CFG_REV
, sizeof(uint32
));
172 if (!(((CHIPID(devid
) == BCM4322_CHIP_ID
) ||
173 (CHIPID(devid
) == BCM4342_CHIP_ID
) ||
174 (CHIPID(devid
) == BCM4322_D11N_ID
) ||
175 (CHIPID(devid
) == BCM4322_D11N2G_ID
) ||
176 (CHIPID(devid
) == BCM4322_D11N5G_ID
)) &&
180 SI_MSG(("si_ldo_war: PCI devid 0x%x rev %d, HACK to fix 4322a0 LDO/PMU\n", devid
, rev_id
));
182 /* switch to chipcommon */
183 w
= OSL_PCI_READ_CONFIG(sii
->osh
, PCI_BAR0_WIN
, sizeof(uint32
));
184 OSL_PCI_WRITE_CONFIG(sii
->osh
, PCI_BAR0_WIN
, sizeof(uint32
), SI_ENUM_BASE
);
185 cc
= (chipcregs_t
*)regs
;
187 /* clear bit 7 to fix LDO
188 * write to register *blindly* WITHOUT read since read may timeout
189 * because the default clock is 32k ILP
191 W_REG(sii
->osh
, &cc
->regcontrol_addr
, 0);
192 /* AND_REG(sii->osh, &cc->regcontrol_data, ~0x80); */
193 W_REG(sii
->osh
, &cc
->regcontrol_data
, 0x3001);
197 /* request ALP_AVAIL through PMU to move sb out of ILP */
198 W_REG(sii
->osh
, &cc
->min_res_mask
, 0x0d);
200 SPINWAIT(((ccst
= OSL_PCI_READ_CONFIG(sii
->osh
, PCI_CLK_CTL_ST
, 4)) & CCS_ALPAVAIL
)
201 == 0, PMU_MAX_TRANSITION_DLY
);
203 if ((ccst
& CCS_ALPAVAIL
) == 0) {
204 SI_ERROR(("ALP never came up clk_ctl_st: 0x%x\n", ccst
));
207 SI_MSG(("si_ldo_war: 4322a0 HACK done\n"));
209 OSL_PCI_WRITE_CONFIG(sii
->osh
, PCI_BAR0_WIN
, sizeof(uint32
), w
);
215 BCMATTACHFN(si_buscore_prep
)(si_info_t
*sii
, uint bustype
, uint devid
, void *sdh
)
217 /* need to set memseg flag for CF card first before any sb registers access */
218 if (BUSTYPE(bustype
) == PCMCIA_BUS
)
221 if (BUSTYPE(bustype
) == PCI_BUS
) {
222 if (!si_ldo_war((si_t
*)sii
, devid
))
226 /* kludge to enable the clock on the 4306 which lacks a slowclock */
227 if (BUSTYPE(bustype
) == PCI_BUS
&& !si_ispcie(sii
))
228 si_clkctl_xtal(&sii
->pub
, XTAL
|PLL
, ON
);
235 BCMATTACHFN(si_buscore_setup
)(si_info_t
*sii
, chipcregs_t
*cc
, uint bustype
, uint32 savewin
,
236 uint
*origidx
, void *regs
)
238 bool pci
, pcie
, pcie_gen2
= FALSE
;
240 uint pciidx
, pcieidx
, pcirev
, pcierev
;
242 cc
= si_setcoreidx(&sii
->pub
, SI_CC_IDX
);
245 /* get chipcommon rev */
246 sii
->pub
.ccrev
= (int)si_corerev(&sii
->pub
);
248 /* get chipcommon chipstatus */
249 if (sii
->pub
.ccrev
>= 11)
250 sii
->pub
.chipst
= R_REG(sii
->osh
, &cc
->chipstatus
);
252 /* get chipcommon capabilites */
253 sii
->pub
.cccaps
= R_REG(sii
->osh
, &cc
->capabilities
);
254 /* get chipcommon extended capabilities */
256 if (sii
->pub
.ccrev
>= 35)
257 sii
->pub
.cccaps_ext
= R_REG(sii
->osh
, &cc
->capabilities_ext
);
259 /* get pmu rev and caps */
260 if (sii
->pub
.cccaps
& CC_CAP_PMU
) {
261 sii
->pub
.pmucaps
= R_REG(sii
->osh
, &cc
->pmucapabilities
);
262 sii
->pub
.pmurev
= sii
->pub
.pmucaps
& PCAP_REV_MASK
;
265 SI_MSG(("Chipc: rev %d, caps 0x%x, chipst 0x%x pmurev %d, pmucaps 0x%x\n",
266 sii
->pub
.ccrev
, sii
->pub
.cccaps
, sii
->pub
.chipst
, sii
->pub
.pmurev
,
269 /* figure out bus/orignal core idx */
270 sii
->pub
.buscoretype
= NODEV_CORE_ID
;
271 sii
->pub
.buscorerev
= (uint
)NOREV
;
272 sii
->pub
.buscoreidx
= BADIDX
;
275 pcirev
= pcierev
= (uint
)NOREV
;
276 pciidx
= pcieidx
= BADIDX
;
278 for (i
= 0; i
< sii
->numcores
; i
++) {
281 si_setcoreidx(&sii
->pub
, i
);
282 cid
= si_coreid(&sii
->pub
);
283 crev
= si_corerev(&sii
->pub
);
285 /* Display cores found */
286 SI_VMSG(("CORE[%d]: id 0x%x rev %d base 0x%x regs 0x%p\n",
287 i
, cid
, crev
, sii
->coresba
[i
], sii
->regs
[i
]));
289 if (BUSTYPE(bustype
) == PCI_BUS
) {
290 if (cid
== PCI_CORE_ID
) {
294 } else if ((cid
== PCIE_CORE_ID
) || (cid
== PCIE2_CORE_ID
)) {
298 if (cid
== PCIE2_CORE_ID
)
301 } else if ((BUSTYPE(bustype
) == PCMCIA_BUS
) &&
302 (cid
== PCMCIA_CORE_ID
)) {
303 sii
->pub
.buscorerev
= crev
;
304 sii
->pub
.buscoretype
= cid
;
305 sii
->pub
.buscoreidx
= i
;
308 /* find the core idx before entering this func. */
309 if ((savewin
&& (savewin
== sii
->coresba
[i
])) ||
310 (regs
== sii
->regs
[i
]))
321 sii
->pub
.buscoretype
= PCI_CORE_ID
;
322 sii
->pub
.buscorerev
= pcirev
;
323 sii
->pub
.buscoreidx
= pciidx
;
326 sii
->pub
.buscoretype
= PCIE2_CORE_ID
;
328 sii
->pub
.buscoretype
= PCIE_CORE_ID
;
329 sii
->pub
.buscorerev
= pcierev
;
330 sii
->pub
.buscoreidx
= pcieidx
;
333 SI_VMSG(("Buscore id/type/rev %d/0x%x/%d\n", sii
->pub
.buscoreidx
, sii
->pub
.buscoretype
,
334 sii
->pub
.buscorerev
));
336 if (BUSTYPE(sii
->pub
.bustype
) == SI_BUS
&& (CHIPID(sii
->pub
.chip
) == BCM4712_CHIP_ID
) &&
337 (sii
->pub
.chippkg
!= BCM4712LARGE_PKG_ID
) && (CHIPREV(sii
->pub
.chiprev
) <= 3))
338 OR_REG(sii
->osh
, &cc
->slow_clk_ctl
, SCC_SS_XTAL
);
340 /* fixup necessary chip/core configurations */
341 if (BUSTYPE(sii
->pub
.bustype
) == PCI_BUS
) {
344 ((sii
->pch
= (void *)(uintptr
)pcicore_init(&sii
->pub
, sii
->osh
,
345 (void *)PCIEREGS(sii
))) == NULL
))
348 if (si_pci_fixcfg(&sii
->pub
)) {
349 SI_ERROR(("si_doattach: si_pci_fixcfg failed\n"));
355 /* return to the original core */
356 si_setcoreidx(&sii
->pub
, *origidx
);
362 si_fixup_vid(si_info_t
*sii
, char *pvars
, uint32 conf_vid
)
364 struct si_pub
*sih
= &sii
->pub
;
367 if (BUSTYPE(sih
->bustype
) != PCI_BUS
)
370 if ((CHIPID(sih
->chip
) != BCM4331_CHIP_ID
) && (CHIPID(sih
->chip
) != BCM43431_CHIP_ID
))
373 /* Ext PA Controls for 4331 12x9 Package */
374 if (sih
->chippkg
!= 9)
377 srom_vid
= (getintvar(pvars
, "boardtype") << 16) | getintvar(pvars
, "subvid");
378 if (srom_vid
!= conf_vid
) {
379 SI_ERROR(("%s: Override mismatch conf_vid(0x%04x) with srom_vid(0x%04x)\n",
380 __FUNCTION__
, conf_vid
, srom_vid
));
388 BCMATTACHFN(si_nvram_process
)(si_info_t
*sii
, char *pvars
)
391 if (BUSTYPE(sii
->pub
.bustype
) == PCMCIA_BUS
) {
392 w
= getintvar(pvars
, "regwindowsz");
393 sii
->memseg
= (w
<= CFTABLE_REGWIN_2K
) ? TRUE
: FALSE
;
396 /* get boardtype and boardrev */
397 switch (BUSTYPE(sii
->pub
.bustype
)) {
399 /* do a pci config read to get subsystem id and subvendor id */
400 w
= OSL_PCI_READ_CONFIG(sii
->osh
, PCI_CFG_SVID
, sizeof(uint32
));
401 w
= si_fixup_vid(sii
, pvars
, w
);
403 /* Let nvram variables override subsystem Vend/ID */
404 if ((sii
->pub
.boardvendor
= (uint16
)si_getdevpathintvar(&sii
->pub
, "boardvendor"))
407 if ((w
& 0xffff) == 0)
408 sii
->pub
.boardvendor
= VENDOR_BROADCOM
;
410 #endif /* !BCMHOSTVARS */
411 sii
->pub
.boardvendor
= w
& 0xffff;
414 SI_ERROR(("Overriding boardvendor: 0x%x instead of 0x%x\n",
415 sii
->pub
.boardvendor
, w
& 0xffff));
416 if ((sii
->pub
.boardtype
= (uint16
)si_getdevpathintvar(&sii
->pub
, "boardtype"))
418 if ((sii
->pub
.boardtype
= getintvar(pvars
, "boardtype")) == 0)
419 sii
->pub
.boardtype
= (w
>> 16) & 0xffff;
422 SI_ERROR(("Overriding boardtype: 0x%x instead of 0x%x\n",
423 sii
->pub
.boardtype
, (w
>> 16) & 0xffff));
427 sii
->pub
.boardvendor
= getintvar(pvars
, "manfid");
428 sii
->pub
.boardtype
= getintvar(pvars
, "prodid");
434 sii
->pub
.boardvendor
= VENDOR_BROADCOM
;
435 if (pvars
== NULL
|| ((sii
->pub
.boardtype
= getintvar(pvars
, "prodid")) == 0))
436 if ((sii
->pub
.boardtype
= getintvar(NULL
, "boardtype")) == 0)
437 sii
->pub
.boardtype
= 0xffff;
439 if (CHIPTYPE(sii
->pub
.socitype
) == SOCI_UBUS
) {
440 /* do a pci config read to get subsystem id and subvendor id */
441 w
= OSL_PCI_READ_CONFIG(sii
->osh
, PCI_CFG_SVID
, sizeof(uint32
));
442 sii
->pub
.boardvendor
= w
& 0xffff;
443 sii
->pub
.boardtype
= (w
>> 16) & 0xffff;
448 if (sii
->pub
.boardtype
== 0) {
449 SI_ERROR(("si_doattach: unknown board type\n"));
450 ASSERT(sii
->pub
.boardtype
);
453 sii
->pub
.boardrev
= getintvar(pvars
, "boardrev");
454 sii
->pub
.boardflags
= getintvar(pvars
, "boardflags");
457 #if !defined(_CFE_) || defined(CFG_WL)
459 BCMATTACHFN(si_sromvars_fixup_4331
)(si_t
*sih
, char *pvars
)
462 const char *sromvars
[] =
463 {"extpagain2g", "extpagain5g"};
464 int sromvars_size
= sizeof(sromvars
)/sizeof(char *);
466 uint boardtype
= sih
->boardtype
;
467 uint boardrev
= sih
->boardrev
;
468 bool update
= ((boardtype
== BCM94331BU_SSID
) ||
469 (boardtype
== BCM94331S9BU_SSID
) ||
470 (boardtype
== BCM94331MCI_SSID
) ||
471 (boardtype
== BCM94331MC_SSID
) ||
472 (boardtype
== BCM94331PCIEBT4_SSID
) ||
473 (boardtype
== BCM94331X19
&& boardrev
== 0x1100) ||
474 (boardtype
== BCM94331HM_SSID
&& boardrev
< 0x1152));
476 if (pvars
== NULL
|| !update
) {
480 for (ii
= 0; ii
< sromvars_size
; ii
++) {
481 char* val
= getvar(pvars
, sromvars
[ii
]);
483 while (val
&& *val
) {
489 #endif /* !_CFE_ || CFG_WL */
491 #if defined(CONFIG_XIP) && defined(BCMTCAM)
492 extern uint8 patch_pair
;
493 #endif /* CONFIG_XIP && BCMTCAM */
498 } si_mux4335_uartopt_t
;
500 /* note: each index corr to MUXENAB4335_UART mask - 1 */
501 static const si_mux4335_uartopt_t
BCMATTACHDATA(mux4335_uartopt
)[] = {
502 {CC4335_PIN_GPIO_06
, CC4335_PIN_GPIO_02
},
503 {CC4335_PIN_GPIO_12
, CC4335_PIN_GPIO_13
},
504 {CC4335_PIN_SDIO_DATA0
, CC4335_PIN_SDIO_CMD
},
505 {CC4335_PIN_RF_SW_CTRL_9
, CC4335_PIN_RF_SW_CTRL_8
}
508 /* want to have this available all the time to switch mux for debugging */
510 BCMATTACHFN(si_muxenab
)(si_t
*sih
, uint32 w
)
512 uint32 chipcontrol
, pmu_chipcontrol
;
514 pmu_chipcontrol
= si_pmu_chipcontrol(sih
, 1, 0, 0);
515 chipcontrol
= si_corereg(sih
, SI_CC_IDX
, OFFSETOF(chipcregs_t
, chipcontrol
),
518 switch (CHIPID(sih
->chip
)) {
519 case BCM4330_CHIP_ID
:
521 chipcontrol
&= ~(CCTRL_4330_JTAG_DISABLE
| CCTRL_4330_ERCX_SEL
|
522 CCTRL_4330_GPIO_SEL
| CCTRL_4330_SDIO_HOST_WAKE
);
523 pmu_chipcontrol
&= ~PCTL_4330_SERIAL_ENAB
;
525 /* 4330 default is to have jtag enabled */
526 if (!(w
& MUXENAB_JTAG
))
527 chipcontrol
|= CCTRL_4330_JTAG_DISABLE
;
528 if (w
& MUXENAB_UART
)
529 pmu_chipcontrol
|= PCTL_4330_SERIAL_ENAB
;
530 if (w
& MUXENAB_GPIO
)
531 chipcontrol
|= CCTRL_4330_GPIO_SEL
;
532 if (w
& MUXENAB_ERCX
)
533 chipcontrol
|= CCTRL_4330_ERCX_SEL
;
534 if (w
& MUXENAB_HOST_WAKE
)
535 chipcontrol
|= CCTRL_4330_SDIO_HOST_WAKE
;
537 case BCM4336_CHIP_ID
:
538 if (w
& MUXENAB_UART
)
539 pmu_chipcontrol
|= PCTL_4336_SERIAL_ENAB
;
541 pmu_chipcontrol
&= ~PCTL_4336_SERIAL_ENAB
;
543 case BCM4360_CHIP_ID
:
544 case BCM43460_CHIP_ID
:
545 case BCM4352_CHIP_ID
:
546 if (w
& MUXENAB_UART
)
547 chipcontrol
|= CCTL_4360_UART_SEL
;
549 case BCM43143_CHIP_ID
:
551 /* 43143 does not support ERCX */
552 if (!(w
& MUXENAB_UART
))
553 chipcontrol
|= CCTRL_43143_RF_XSWCTRL
;
554 /* JTAG is enabled when SECI is disabled */
555 if (w
& MUXENAB_SECI
)
556 chipcontrol
|= CCTRL_43143_SECI
;
557 if (w
& MUXENAB_BT_LEGACY
)
558 chipcontrol
|= CCTRL_43143_BT_LEGACY
;
559 if (w
& MUXENAB_I2S_EN
)
560 chipcontrol
|= CCTRL_43143_I2S_MODE
;
561 if (w
& MUXENAB_I2S_MASTER
)
562 chipcontrol
|= CCTRL_43143_I2S_MASTER
;
563 if (w
& MUXENAB_I2S_FULL
)
564 chipcontrol
|= CCTRL_43143_I2S_FULL
;
565 if (!(w
& MUXENAB_SFLASH
))
566 chipcontrol
|= CCTRL_43143_GSIO
;
567 if (w
& MUXENAB_RFSWCTRL0
)
568 chipcontrol
|= CCTRL_43143_RF_SWCTRL_0
;
569 if (w
& MUXENAB_RFSWCTRL1
)
570 chipcontrol
|= CCTRL_43143_RF_SWCTRL_1
;
571 if (w
& MUXENAB_RFSWCTRL2
)
572 chipcontrol
|= CCTRL_43143_RF_SWCTRL_2
;
573 if (w
& MUXENAB_HOST_WAKE
)
574 chipcontrol
|= CCTRL_43143_HOST_WAKE0
;
575 if (w
& MUXENAB_HOST_WAKE1
)
576 chipcontrol
|= CCTRL_43143_HOST_WAKE1
;
578 case BCM43242_CHIP_ID
:
579 case BCM43243_CHIP_ID
:
581 pmu_chipcontrol
&= ~CCTRL1_4324_GPIO_SEL
;
582 if (w
& MUXENAB_GPIO
)
583 pmu_chipcontrol
|= CCTRL1_4324_GPIO_SEL
;
586 case BCM4335_CHIP_ID
:
587 /* drive default pins for UART. Note: 15 values possible;
588 * 0 means disabled; 1 means index to 0 in mux4335_uartopt
591 if (w
& MUXENAB4335_UART_MASK
) {
592 uint32 uart_rx
= 0, uart_tx
= 0;
593 uint8 uartopt_ix
= (w
& MUXENAB4335_UART_MASK
) - 1;
595 uart_rx
= mux4335_uartopt
[uartopt_ix
].uart_rx
;
596 uart_tx
= mux4335_uartopt
[uartopt_ix
].uart_tx
;
598 si_gci_set_functionsel(sih
, uart_rx
, CC4335_FNSEL_UART
);
599 si_gci_set_functionsel(sih
, uart_tx
, CC4335_FNSEL_UART
);
604 /* muxenab specified for an unsupported chip */
609 /* write both updated values to hw */
610 si_pmu_chipcontrol(sih
, 1, ~0, pmu_chipcontrol
);
611 si_corereg(sih
, SI_CC_IDX
, OFFSETOF(chipcregs_t
, chipcontrol
),
615 /* write 'val' to the gci chip control register indexed by 'reg' */
617 si_gci_chipcontrol(si_t
*sih
, uint reg
, uint32 mask
, uint32 val
)
619 /* because NFLASH and GCI clashes in 0xC00 */
620 #ifndef NFLASH_SUPPORT
621 si_corereg(sih
, SI_CC_IDX
, OFFSETOF(chipcregs_t
, gci_indirect_addr
), ~0, reg
);
622 return si_corereg(sih
, SI_CC_IDX
, OFFSETOF(chipcregs_t
, gci_chipctrl
), mask
, val
);
623 #else /* NFLASH_SUPPORT */
630 * output: chipcontrol reg and bits to shift for pin fn-sel's first regbit.
631 * eg: gpio9 will give regidx: 1 and pos 4
634 si_gci_get_chipctrlreg_idx(uint32 pin
, uint32
*regidx
, uint32
*pos
)
639 SI_MSG(("si_gci_get_chipctrlreg_idx:%d:%d:%d\n", pin
, *regidx
, *pos
));
644 /* setup a given pin for fnsel function */
646 si_gci_set_functionsel(si_t
*sih
, uint32 pin
, uint8 fnsel
)
648 uint32 reg
= 0, pos
= 0;
650 SI_MSG(("si_gci_set_functionsel:%d\n", pin
));
652 si_gci_get_chipctrlreg_idx(pin
, ®
, &pos
);
653 si_gci_chipcontrol(sih
, reg
, GCIMASK(pos
), GCIPOSVAL(fnsel
, pos
));
657 si_gci_chipctrl_overrides(osl_t
*osh
, si_t
*sih
, char *pvars
)
662 uint32 gciccval
= 0, cap1
= 0;
665 /* because NFLASH and GCI clashes in 0xC00 */
666 #ifndef NFLASH_SUPPORT
667 cap1
= si_corereg(sih
, SI_CC_IDX
, OFFSETOF(chipcregs_t
, gci_corecaps1
), 0, 0);
668 #else /* NFLASH_SUPPORT */
671 num_cc
= CC_GCI_NUMCHIPCTRLREGS(cap1
);
673 for (i
= 0; i
< num_cc
; i
++) {
674 snprintf(gciccstr
, sizeof(gciccstr
), "gcr%d", i
);
676 if ((otp_val
= getvar(NULL
, gciccstr
)) == NULL
)
679 gciccval
= (uint32
) getintvar(pvars
, gciccstr
);
680 si_gci_chipcontrol(sih
, i
, ~0, gciccval
);
685 BCMATTACHFN(si_doattach
)(si_info_t
*sii
, uint devid
, osl_t
*osh
, void *regs
,
686 uint bustype
, void *sdh
, char **vars
, uint
*varsz
)
688 struct si_pub
*sih
= &sii
->pub
;
693 #if !defined(_CFE_) || defined(CFG_WL)
694 bool fixup_boardtype
= FALSE
;
695 #endif /* !defined(_CFE_) || defined(CFG_WL) */
696 ASSERT(GOODREGS(regs
));
698 bzero((uchar
*)sii
, sizeof(si_info_t
));
702 sih
->buscoreidx
= BADIDX
;
708 #ifdef SI_ENUM_BASE_VARIABLE
709 si_enum_base_init(sih
, bustype
);
710 #endif /* SI_ENUM_BASE_VARIABLE */
712 /* check to see if we are a si core mimic'ing a pci core */
713 if ((bustype
== PCI_BUS
) &&
714 (OSL_PCI_READ_CONFIG(sii
->osh
, PCI_SPROM_CONTROL
, sizeof(uint32
)) == 0xffffffff)) {
715 SI_ERROR(("%s: incoming bus is PCI but it's a lie, switching to SI "
716 "devid:0x%x\n", __FUNCTION__
, devid
));
720 /* find Chipcommon address */
721 if (bustype
== PCI_BUS
) {
722 savewin
= OSL_PCI_READ_CONFIG(sii
->osh
, PCI_BAR0_WIN
, sizeof(uint32
));
723 if (!GOODCOREADDR(savewin
, SI_ENUM_BASE
))
724 savewin
= SI_ENUM_BASE
;
725 OSL_PCI_WRITE_CONFIG(sii
->osh
, PCI_BAR0_WIN
, 4, SI_ENUM_BASE
);
726 cc
= (chipcregs_t
*)regs
;
728 cc
= (chipcregs_t
*)REG_MAP(SI_ENUM_BASE
, SI_CORE_SIZE
);
731 sih
->bustype
= bustype
;
732 if (bustype
!= BUSTYPE(bustype
)) {
733 SI_ERROR(("si_doattach: bus type %d does not match configured bus type %d\n",
734 bustype
, BUSTYPE(bustype
)));
738 /* bus/core/clk setup for register access */
739 if (!si_buscore_prep(sii
, bustype
, devid
, sdh
)) {
740 SI_ERROR(("si_doattach: si_core_clk_prep failed %d\n", bustype
));
744 /* ChipID recognition.
745 * We assume we can read chipid at offset 0 from the regs arg.
746 * If we add other chiptypes (or if we need to support old sdio hosts w/o chipcommon),
747 * some way of recognizing them needs to be added here.
750 SI_ERROR(("%s: chipcommon register space is null \n", __FUNCTION__
));
753 w
= R_REG(osh
, &cc
->chipid
);
754 sih
->socitype
= (w
& CID_TYPE_MASK
) >> CID_TYPE_SHIFT
;
755 /* Might as wll fill in chip id rev & pkg */
756 sih
->chip
= w
& CID_ID_MASK
;
757 sih
->chiprev
= (w
& CID_REV_MASK
) >> CID_REV_SHIFT
;
758 sih
->chippkg
= (w
& CID_PKG_MASK
) >> CID_PKG_SHIFT
;
760 if ((CHIPID(sih
->chip
) == BCM4329_CHIP_ID
) && (sih
->chiprev
== 0) &&
761 (sih
->chippkg
!= BCM4329_289PIN_PKG_ID
)) {
762 sih
->chippkg
= BCM4329_182PIN_PKG_ID
;
764 sih
->issim
= IS_SIM(sih
->chippkg
);
767 if (CHIPTYPE(sii
->pub
.socitype
) == SOCI_SB
) {
768 SI_MSG(("Found chip type SB (0x%08x)\n", w
));
769 sb_scan(&sii
->pub
, regs
, devid
);
770 } else if ((CHIPTYPE(sii
->pub
.socitype
) == SOCI_AI
) ||
771 (CHIPTYPE(sii
->pub
.socitype
) == SOCI_NAI
)) {
772 if (CHIPTYPE(sii
->pub
.socitype
) == SOCI_AI
)
773 SI_MSG(("Found chip type AI (0x%08x)\n", w
));
775 SI_MSG(("Found chip type NAI (0x%08x)\n", w
));
776 /* pass chipc address instead of original core base */
777 ai_scan(&sii
->pub
, (void *)(uintptr
)cc
, devid
);
778 } else if (CHIPTYPE(sii
->pub
.socitype
) == SOCI_UBUS
) {
779 SI_MSG(("Found chip type UBUS (0x%08x), chip id = 0x%4x\n", w
, sih
->chip
));
780 /* pass chipc address instead of original core base */
781 ub_scan(&sii
->pub
, (void *)(uintptr
)cc
, devid
);
783 SI_ERROR(("Found chip of unknown type (0x%08x)\n", w
));
786 /* no cores found, bail out */
787 if (sii
->numcores
== 0) {
788 SI_ERROR(("si_doattach: could not find any cores\n"));
791 /* bus/core/clk setup */
793 if (!si_buscore_setup(sii
, cc
, bustype
, savewin
, &origidx
, regs
)) {
794 SI_ERROR(("si_doattach: si_buscore_setup failed\n"));
798 #if !defined(_CFE_) || defined(CFG_WL)
799 if (CHIPID(sih
->chip
) == BCM4322_CHIP_ID
&& (((sih
->chipst
& CST4322_SPROM_OTP_SEL_MASK
)
800 >> CST4322_SPROM_OTP_SEL_SHIFT
) == (CST4322_OTP_PRESENT
|
801 CST4322_SPROM_PRESENT
))) {
802 SI_ERROR(("%s: Invalid setting: both SPROM and OTP strapped.\n", __FUNCTION__
));
806 /* assume current core is CC */
807 if ((sii
->pub
.ccrev
== 0x25) && ((CHIPID(sih
->chip
) == BCM43236_CHIP_ID
||
808 CHIPID(sih
->chip
) == BCM43235_CHIP_ID
||
809 CHIPID(sih
->chip
) == BCM43234_CHIP_ID
||
810 CHIPID(sih
->chip
) == BCM43238_CHIP_ID
) &&
811 (CHIPREV(sii
->pub
.chiprev
) <= 2))) {
813 if ((cc
->chipstatus
& CST43236_BP_CLK
) != 0) {
815 clkdiv
= R_REG(osh
, &cc
->clkdiv
);
816 /* otp_clk_div is even number, 120/14 < 9mhz */
817 clkdiv
= (clkdiv
& ~CLKD_OTP
) | (14 << CLKD_OTP_SHIFT
);
818 W_REG(osh
, &cc
->clkdiv
, clkdiv
);
819 SI_ERROR(("%s: set clkdiv to %x\n", __FUNCTION__
, clkdiv
));
824 if (bustype
== PCI_BUS
) {
825 if ((CHIPID(sih
->chip
) == BCM4331_CHIP_ID
) ||
826 (CHIPID(sih
->chip
) == BCM43431_CHIP_ID
)) {
827 /* Check Ext PA Controls for 4331 12x9 Package before the fixup */
828 if (sih
->chippkg
== 9) {
829 uint32 val
= si_chipcontrl_read(sih
);
830 fixup_boardtype
= ((val
& CCTRL4331_EXTPA_ON_GPIO2_5
) ==
831 CCTRL4331_EXTPA_ON_GPIO2_5
);
833 /* set default mux pin to SROM */
834 si_chipcontrl_epa4331(sih
, FALSE
);
835 si_corereg(sih
, SI_CC_IDX
, OFFSETOF(chipcregs_t
, watchdog
), ~0, 100);
836 OSL_DELAY(20000); /* Srom read takes ~12mS */
839 if (((CHIPID(sih
->chip
) == BCM4360_CHIP_ID
) ||
840 (CHIPID(sih
->chip
) == BCM43460_CHIP_ID
) ||
841 (CHIPID(sih
->chip
) == BCM4352_CHIP_ID
)) &&
842 (CHIPREV(sih
->chiprev
) <= 2)) {
843 pcie_disable_TL_clk_gating(sii
->pch
);
844 pcie_set_L1_entry_time(sii
->pch
, 0x40);
848 /* Set OTPClkDiv to smaller value otherwise OTP always reads 0xFFFF.
849 * For real-chip we shouldn't set OTPClkDiv to 2 because 20/2 = 10 > 9Mhz
850 * but for 4314 QT if we set it to 4. OTP reads 0xFFFF every two words.
855 if ((CHIPID(sih
->chip
) == BCM4314_CHIP_ID
) ||
856 (CHIPID(sih
->chip
) == BCM43142_CHIP_ID
)) {
858 } else if ((CHIPID(sih
->chip
) == BCM43131_CHIP_ID
) ||
859 (CHIPID(sih
->chip
) == BCM43217_CHIP_ID
) ||
860 (CHIPID(sih
->chip
) == BCM43227_CHIP_ID
) ||
861 (CHIPID(sih
->chip
) == BCM43228_CHIP_ID
)) {
865 if (otpclkdiv
!= 0) {
866 uint clkdiv
, savecore
;
867 savecore
= si_coreidx(sih
);
868 si_setcore(sih
, CC_CORE_ID
, 0);
870 clkdiv
= R_REG(osh
, &cc
->clkdiv
);
871 clkdiv
= (clkdiv
& ~CLKD_OTP
) | (otpclkdiv
<< CLKD_OTP_SHIFT
);
872 W_REG(osh
, &cc
->clkdiv
, clkdiv
);
874 SI_ERROR(("%s: set clkdiv to 0x%x for QT\n", __FUNCTION__
, clkdiv
));
875 si_setcoreidx(sih
, savecore
);
880 #endif /* !_CFE_ || CFG_WL */
881 #ifdef SI_SPROM_PROBE
883 #endif /* SI_SPROM_PROBE */
885 #if !defined(BCMHIGHSDIO)
886 /* Init nvram from flash if it exists */
887 nvram_init((void *)&(sii
->pub
));
889 /* Init nvram from sprom/otp if they exist */
890 if (srom_var_init(&sii
->pub
, BUSTYPE(bustype
), regs
, sii
->osh
, vars
, varsz
)) {
891 SI_ERROR(("si_doattach: srom_var_init failed: bad srom\n"));
894 pvars
= vars
? *vars
: NULL
;
896 si_nvram_process(sii
, pvars
);
898 #if !defined(_CFE_) || defined(CFG_WL)
899 if (bustype
== PCI_BUS
) {
900 if ((CHIPID(sih
->chip
) == BCM4331_CHIP_ID
) ||
901 (CHIPID(sih
->chip
) == BCM43431_CHIP_ID
)) {
902 si_sromvars_fixup_4331(sih
, pvars
);
904 sii
->pub
.boardtype
= getintvar(pvars
, "boardtype");
907 #endif /* !_CFE_ || CFG_WL */
909 /* === NVRAM, clock is ready === */
912 BCM_REFERENCE(pvars
);
916 #if defined(CONFIG_XIP) && defined(BCMTCAM)
917 /* patch the ROM if there are any patch pairs from OTP/SPROM */
920 #if defined(__ARM_ARCH_7R__)
921 hnd_tcam_bootloader_load(si_setcore(sih
, ARMCR4_CORE_ID
, 0), pvars
);
923 hnd_tcam_bootloader_load(si_setcore(sih
, SOCRAM_CORE_ID
, 0), pvars
);
925 si_setcoreidx(sih
, origidx
);
927 #endif /* CONFIG_XIP && BCMTCAM */
929 /* bootloader should retain default pulls */
930 #ifndef BCM_BOOTLOADER
931 if (sii
->pub
.ccrev
>= 20) {
932 uint32 gpiopullup
= 0, gpiopulldown
= 0;
933 cc
= (chipcregs_t
*)si_setcore(sih
, CC_CORE_ID
, 0);
936 /* 4314/43142 has pin muxing, don't clear gpio bits */
937 if ((CHIPID(sih
->chip
) == BCM4314_CHIP_ID
) ||
938 (CHIPID(sih
->chip
) == BCM43142_CHIP_ID
)) {
939 gpiopullup
|= 0x402e0;
940 gpiopulldown
|= 0x20500;
943 W_REG(osh
, &cc
->gpiopullup
, gpiopullup
);
944 W_REG(osh
, &cc
->gpiopulldown
, gpiopulldown
);
945 si_setcoreidx(sih
, origidx
);
947 #endif /* !BCM_BOOTLOADER */
949 /* PMU specific initializations */
950 if (PMUCTL_ENAB(sih
)) {
952 si_pmu_init(sih
, sii
->osh
);
953 si_pmu_chip_init(sih
, sii
->osh
);
954 xtalfreq
= getintvar(pvars
, "xtalfreq");
955 switch (CHIPID(sih
->chip
)) {
956 case BCM43242_CHIP_ID
:
957 case BCM43243_CHIP_ID
:
960 case BCM43143_CHIP_ID
:
966 /* If xtalfreq var not available, try to measure it */
968 xtalfreq
= si_pmu_measure_alpclk(sih
, sii
->osh
);
969 #if !defined(BCMHIGHSDIO)
970 si_pmu_pll_init(sih
, sii
->osh
, xtalfreq
);
971 si_pmu_res_init(sih
, sii
->osh
);
973 si_pmu_swreg_init(sih
, sii
->osh
);
976 /* setup the GPIO based LED powersave register */
977 if (sii
->pub
.ccrev
>= 16) {
978 if ((w
= getintvar(pvars
, "leddc")) == 0)
979 w
= DEFAULT_GPIOTIMERVAL
;
980 si_corereg(sih
, SI_CC_IDX
, OFFSETOF(chipcregs_t
, gpiotimerval
), ~0, w
);
983 if (PCI_FORCEHT(sii
)) {
984 SI_MSG(("si_doattach: force HT\n"));
985 sih
->pci_pr32414
= TRUE
;
987 _si_clkctl_cc(sii
, CLK_FAST
);
990 #if !defined(_CFE_) || defined(CFG_WL)
992 ASSERT(sii
->pch
!= NULL
);
994 pcicore_attach(sii
->pch
, pvars
, SI_DOATTACH
);
996 if (((CHIPID(sih
->chip
) == BCM4311_CHIP_ID
) && (CHIPREV(sih
->chiprev
) == 2)) ||
997 (CHIPID(sih
->chip
) == BCM4312_CHIP_ID
)) {
998 SI_MSG(("si_doattach: clear initiator timeout\n"));
999 sb_set_initiator_to(sih
, 0x3, si_findcoreidx(sih
, D11_CORE_ID
, 0));
1003 if ((CHIPID(sih
->chip
) == BCM43224_CHIP_ID
) ||
1004 (CHIPID(sih
->chip
) == BCM43421_CHIP_ID
)) {
1005 /* enable 12 mA drive strenth for 43224 and set chipControl register bit 15 */
1006 if (CHIPREV(sih
->chiprev
) == 0) {
1007 SI_MSG(("Applying 43224A0 WARs\n"));
1008 si_corereg(sih
, SI_CC_IDX
, OFFSETOF(chipcregs_t
, chipcontrol
),
1009 CCTRL43224_GPIO_TOGGLE
, CCTRL43224_GPIO_TOGGLE
);
1010 si_pmu_chipcontrol(sih
, 0, CCTRL_43224A0_12MA_LED_DRIVE
,
1011 CCTRL_43224A0_12MA_LED_DRIVE
);
1013 if (CHIPREV(sih
->chiprev
) >= 1) {
1014 SI_MSG(("Applying 43224B0+ WARs\n"));
1015 si_pmu_chipcontrol(sih
, 0, CCTRL_43224B0_12MA_LED_DRIVE
,
1016 CCTRL_43224B0_12MA_LED_DRIVE
);
1020 /* configure default pinmux enables for the chip */
1021 if (getvar(pvars
, "muxenab") != NULL
) {
1022 w
= getintvar(pvars
, "muxenab");
1023 si_muxenab((si_t
*)sii
, w
);
1026 /* enable GPIO interrupts when clocks are off */
1027 if (sii
->pub
.ccrev
>= 21) {
1029 corecontrol
= si_corereg(sih
, SI_CC_IDX
, OFFSETOF(chipcregs_t
, corecontrol
),
1031 corecontrol
|= CC_ASYNCGPIO
;
1032 si_corereg(sih
, SI_CC_IDX
, OFFSETOF(chipcregs_t
, corecontrol
),
1033 corecontrol
, corecontrol
);
1036 if (CHIPID(sih
->chip
) == BCM4313_CHIP_ID
) {
1037 /* enable 12 mA drive strenth for 4313 and set chipControl register bit 1 */
1038 SI_MSG(("Applying 4313 WARs\n"));
1039 si_pmu_chipcontrol(sih
, 0, CCTRL_4313_12MA_LED_DRIVE
, CCTRL_4313_12MA_LED_DRIVE
);
1041 #endif /* !_CFE_ || CFG_WL */
1043 #if defined(SAVERESTORE)
1044 sr_save_restore_init(sih
);
1046 /* clear any previous epidiag-induced target abort */
1047 ASSERT(!si_taclear(sih
, FALSE
));
1049 if ((CHIPID(sih
->chip
) == BCM4335_CHIP_ID
) ||
1051 si_gci_chipctrl_overrides(osh
, sih
, pvars
);
1057 if (BUSTYPE(sih
->bustype
) == PCI_BUS
) {
1059 pcicore_deinit(sii
->pch
);
1066 /* may be called with core in reset */
1068 BCMATTACHFN(si_detach
)(si_t
*sih
)
1074 struct si_pub
*si_local
= NULL
;
1075 bcopy(&sih
, &si_local
, sizeof(si_t
*));
1083 if (BUSTYPE(sih
->bustype
) == SI_BUS
)
1084 for (idx
= 0; idx
< SI_MAXCORES
; idx
++)
1085 if (sii
->regs
[idx
]) {
1086 REG_UNMAP(sii
->regs
[idx
]);
1087 sii
->regs
[idx
] = NULL
;
1091 #if !defined(BCMHIGHSDIO)
1092 srom_var_deinit((void *)si_local
);
1094 nvram_exit((void *)si_local
); /* free up nvram buffers */
1097 if (BUSTYPE(sih
->bustype
) == PCI_BUS
) {
1099 pcicore_deinit(sii
->pch
);
1103 #if !defined(BCMBUSTYPE) || (BCMBUSTYPE == SI_BUS)
1105 #endif /* !BCMBUSTYPE || (BCMBUSTYPE == SI_BUS) */
1106 MFREE(sii
->osh
, sii
, sizeof(si_info_t
));
1119 si_setosh(si_t
*sih
, osl_t
*osh
)
1124 if (sii
->osh
!= NULL
) {
1125 SI_ERROR(("osh is already set....\n"));
1131 /* register driver interrupt disabling and restoring callback functions */
1133 si_register_intr_callback(si_t
*sih
, void *intrsoff_fn
, void *intrsrestore_fn
,
1134 void *intrsenabled_fn
, void *intr_arg
)
1139 sii
->intr_arg
= intr_arg
;
1140 sii
->intrsoff_fn
= (si_intrsoff_t
)intrsoff_fn
;
1141 sii
->intrsrestore_fn
= (si_intrsrestore_t
)intrsrestore_fn
;
1142 sii
->intrsenabled_fn
= (si_intrsenabled_t
)intrsenabled_fn
;
1143 /* save current core id. when this function called, the current core
1144 * must be the core which provides driver functions(il, et, wl, etc.)
1146 sii
->dev_coreid
= sii
->coreid
[sii
->curidx
];
1150 si_deregister_intr_callback(si_t
*sih
)
1155 sii
->intrsoff_fn
= NULL
;
1159 si_intflag(si_t
*sih
)
1161 si_info_t
*sii
= SI_INFO(sih
);
1163 if (CHIPTYPE(sih
->socitype
) == SOCI_SB
)
1164 return sb_intflag(sih
);
1165 else if ((CHIPTYPE(sih
->socitype
) == SOCI_AI
) || (CHIPTYPE(sih
->socitype
) == SOCI_NAI
))
1166 return R_REG(sii
->osh
, ((uint32
*)(uintptr
)
1167 (sii
->oob_router
+ OOB_STATUSA
)));
1177 if (CHIPTYPE(sih
->socitype
) == SOCI_SB
)
1178 return sb_flag(sih
);
1179 else if ((CHIPTYPE(sih
->socitype
) == SOCI_AI
) || (CHIPTYPE(sih
->socitype
) == SOCI_NAI
))
1180 return ai_flag(sih
);
1181 else if (CHIPTYPE(sih
->socitype
) == SOCI_UBUS
)
1182 return ub_flag(sih
);
1190 si_setint(si_t
*sih
, int siflag
)
1192 if (CHIPTYPE(sih
->socitype
) == SOCI_SB
)
1193 sb_setint(sih
, siflag
);
1194 else if ((CHIPTYPE(sih
->socitype
) == SOCI_AI
) || (CHIPTYPE(sih
->socitype
) == SOCI_NAI
))
1195 ai_setint(sih
, siflag
);
1196 else if (CHIPTYPE(sih
->socitype
) == SOCI_UBUS
)
1197 ub_setint(sih
, siflag
);
1203 si_coreid(si_t
*sih
)
1208 return sii
->coreid
[sii
->curidx
];
1212 si_coreidx(si_t
*sih
)
1220 /* return the core-type instantiation # of the current core */
1222 si_coreunit(si_t
*sih
)
1235 ASSERT(GOODREGS(sii
->curmap
));
1236 coreid
= si_coreid(sih
);
1238 /* count the cores of our type */
1239 for (i
= 0; i
< idx
; i
++)
1240 if (sii
->coreid
[i
] == coreid
)
1247 si_corevendor(si_t
*sih
)
1249 if (CHIPTYPE(sih
->socitype
) == SOCI_SB
)
1250 return sb_corevendor(sih
);
1251 else if ((CHIPTYPE(sih
->socitype
) == SOCI_AI
) || (CHIPTYPE(sih
->socitype
) == SOCI_NAI
))
1252 return ai_corevendor(sih
);
1253 else if (CHIPTYPE(sih
->socitype
) == SOCI_UBUS
)
1254 return ub_corevendor(sih
);
1262 si_backplane64(si_t
*sih
)
1264 return ((sih
->cccaps
& CC_CAP_BKPLN64
) != 0);
1268 si_corerev(si_t
*sih
)
1270 if (CHIPTYPE(sih
->socitype
) == SOCI_SB
)
1271 return sb_corerev(sih
);
1272 else if ((CHIPTYPE(sih
->socitype
) == SOCI_AI
) || (CHIPTYPE(sih
->socitype
) == SOCI_NAI
))
1273 return ai_corerev(sih
);
1274 else if (CHIPTYPE(sih
->socitype
) == SOCI_UBUS
)
1275 return ub_corerev(sih
);
1282 /* return index of coreid or BADIDX if not found */
1284 si_findcoreidx(si_t
*sih
, uint coreid
, uint coreunit
)
1294 for (i
= 0; i
< sii
->numcores
; i
++)
1295 if (sii
->coreid
[i
] == coreid
) {
1296 if (found
== coreunit
)
1304 /* return list of found cores */
1306 si_corelist(si_t
*sih
, uint coreid
[])
1312 bcopy((uchar
*)sii
->coreid
, (uchar
*)coreid
, (sii
->numcores
* sizeof(uint
)));
1313 return (sii
->numcores
);
1316 /* return current register mapping */
1318 si_coreregs(si_t
*sih
)
1323 ASSERT(GOODREGS(sii
->curmap
));
1325 return (sii
->curmap
);
1329 * This function changes logical "focus" to the indicated core;
1330 * must be called with interrupts off.
1331 * Moreover, callers should keep interrupts off during switching out of and back to d11 core
1334 si_setcore(si_t
*sih
, uint coreid
, uint coreunit
)
1338 idx
= si_findcoreidx(sih
, coreid
, coreunit
);
1342 if (CHIPTYPE(sih
->socitype
) == SOCI_SB
)
1343 return sb_setcoreidx(sih
, idx
);
1344 else if ((CHIPTYPE(sih
->socitype
) == SOCI_AI
) || (CHIPTYPE(sih
->socitype
) == SOCI_NAI
))
1345 return ai_setcoreidx(sih
, idx
);
1346 else if (CHIPTYPE(sih
->socitype
) == SOCI_UBUS
)
1347 return ub_setcoreidx(sih
, idx
);
1355 si_setcoreidx(si_t
*sih
, uint coreidx
)
1357 if (CHIPTYPE(sih
->socitype
) == SOCI_SB
)
1358 return sb_setcoreidx(sih
, coreidx
);
1359 else if ((CHIPTYPE(sih
->socitype
) == SOCI_AI
) || (CHIPTYPE(sih
->socitype
) == SOCI_NAI
))
1360 return ai_setcoreidx(sih
, coreidx
);
1361 else if (CHIPTYPE(sih
->socitype
) == SOCI_UBUS
)
1362 return ub_setcoreidx(sih
, coreidx
);
1369 /* Turn off interrupt as required by sb_setcore, before switch core */
1371 si_switch_core(si_t
*sih
, uint coreid
, uint
*origidx
, uint
*intr_val
)
1379 /* Overloading the origidx variable to remember the coreid,
1380 * this works because the core ids cannot be confused with
1384 if (coreid
== CC_CORE_ID
)
1385 return (void *)CCREGS_FAST(sii
);
1386 else if (coreid
== sih
->buscoretype
)
1387 return (void *)PCIEREGS(sii
);
1389 INTR_OFF(sii
, *intr_val
);
1390 *origidx
= sii
->curidx
;
1391 cc
= si_setcore(sih
, coreid
, 0);
1397 /* restore coreidx and restore interrupt */
1399 si_restore_core(si_t
*sih
, uint coreid
, uint intr_val
)
1404 if (SI_FAST(sii
) && ((coreid
== CC_CORE_ID
) || (coreid
== sih
->buscoretype
)))
1407 si_setcoreidx(sih
, coreid
);
1408 INTR_RESTORE(sii
, intr_val
);
1412 si_numaddrspaces(si_t
*sih
)
1414 if (CHIPTYPE(sih
->socitype
) == SOCI_SB
)
1415 return sb_numaddrspaces(sih
);
1416 else if ((CHIPTYPE(sih
->socitype
) == SOCI_AI
) || (CHIPTYPE(sih
->socitype
) == SOCI_NAI
))
1417 return ai_numaddrspaces(sih
);
1418 else if (CHIPTYPE(sih
->socitype
) == SOCI_UBUS
)
1419 return ub_numaddrspaces(sih
);
1427 si_addrspace(si_t
*sih
, uint asidx
)
1429 if (CHIPTYPE(sih
->socitype
) == SOCI_SB
)
1430 return sb_addrspace(sih
, asidx
);
1431 else if ((CHIPTYPE(sih
->socitype
) == SOCI_AI
) || (CHIPTYPE(sih
->socitype
) == SOCI_NAI
))
1432 return ai_addrspace(sih
, asidx
);
1433 else if (CHIPTYPE(sih
->socitype
) == SOCI_UBUS
)
1434 return ub_addrspace(sih
, asidx
);
1442 si_addrspacesize(si_t
*sih
, uint asidx
)
1444 if (CHIPTYPE(sih
->socitype
) == SOCI_SB
)
1445 return sb_addrspacesize(sih
, asidx
);
1446 else if ((CHIPTYPE(sih
->socitype
) == SOCI_AI
) || (CHIPTYPE(sih
->socitype
) == SOCI_NAI
))
1447 return ai_addrspacesize(sih
, asidx
);
1448 else if (CHIPTYPE(sih
->socitype
) == SOCI_UBUS
)
1449 return ub_addrspacesize(sih
, asidx
);
1457 si_coreaddrspaceX(si_t
*sih
, uint asidx
, uint32
*addr
, uint32
*size
)
1459 /* Only supported for SOCI_AI */
1460 if ((CHIPTYPE(sih
->socitype
) == SOCI_AI
) || (CHIPTYPE(sih
->socitype
) == SOCI_NAI
))
1461 ai_coreaddrspaceX(sih
, asidx
, addr
, size
);
1467 si_core_cflags(si_t
*sih
, uint32 mask
, uint32 val
)
1469 if (CHIPTYPE(sih
->socitype
) == SOCI_SB
)
1470 return sb_core_cflags(sih
, mask
, val
);
1471 else if ((CHIPTYPE(sih
->socitype
) == SOCI_AI
) || (CHIPTYPE(sih
->socitype
) == SOCI_NAI
))
1472 return ai_core_cflags(sih
, mask
, val
);
1473 else if (CHIPTYPE(sih
->socitype
) == SOCI_UBUS
)
1474 return ub_core_cflags(sih
, mask
, val
);
1482 si_core_cflags_wo(si_t
*sih
, uint32 mask
, uint32 val
)
1484 if (CHIPTYPE(sih
->socitype
) == SOCI_SB
)
1485 sb_core_cflags_wo(sih
, mask
, val
);
1486 else if ((CHIPTYPE(sih
->socitype
) == SOCI_AI
) || (CHIPTYPE(sih
->socitype
) == SOCI_NAI
))
1487 ai_core_cflags_wo(sih
, mask
, val
);
1488 else if (CHIPTYPE(sih
->socitype
) == SOCI_UBUS
)
1489 ub_core_cflags_wo(sih
, mask
, val
);
1495 si_core_sflags(si_t
*sih
, uint32 mask
, uint32 val
)
1497 if (CHIPTYPE(sih
->socitype
) == SOCI_SB
)
1498 return sb_core_sflags(sih
, mask
, val
);
1499 else if ((CHIPTYPE(sih
->socitype
) == SOCI_AI
) || (CHIPTYPE(sih
->socitype
) == SOCI_NAI
))
1500 return ai_core_sflags(sih
, mask
, val
);
1501 else if (CHIPTYPE(sih
->socitype
) == SOCI_UBUS
)
1502 return ub_core_sflags(sih
, mask
, val
);
1510 si_iscoreup(si_t
*sih
)
1512 if (CHIPTYPE(sih
->socitype
) == SOCI_SB
)
1513 return sb_iscoreup(sih
);
1514 else if ((CHIPTYPE(sih
->socitype
) == SOCI_AI
) || (CHIPTYPE(sih
->socitype
) == SOCI_NAI
))
1515 return ai_iscoreup(sih
);
1516 else if (CHIPTYPE(sih
->socitype
) == SOCI_UBUS
)
1517 return ub_iscoreup(sih
);
1525 si_wrapperreg(si_t
*sih
, uint32 offset
, uint32 mask
, uint32 val
)
1527 /* only for AI back plane chips */
1528 if ((CHIPTYPE(sih
->socitype
) == SOCI_AI
) || (CHIPTYPE(sih
->socitype
) == SOCI_NAI
))
1529 return (ai_wrap_reg(sih
, offset
, mask
, val
));
1534 si_corereg(si_t
*sih
, uint coreidx
, uint regoff
, uint mask
, uint val
)
1536 if (CHIPTYPE(sih
->socitype
) == SOCI_SB
)
1537 return sb_corereg(sih
, coreidx
, regoff
, mask
, val
);
1538 else if ((CHIPTYPE(sih
->socitype
) == SOCI_AI
) || (CHIPTYPE(sih
->socitype
) == SOCI_NAI
))
1539 return ai_corereg(sih
, coreidx
, regoff
, mask
, val
);
1540 else if (CHIPTYPE(sih
->socitype
) == SOCI_UBUS
)
1541 return ub_corereg(sih
, coreidx
, regoff
, mask
, val
);
1549 si_core_disable(si_t
*sih
, uint32 bits
)
1551 if (CHIPTYPE(sih
->socitype
) == SOCI_SB
)
1552 sb_core_disable(sih
, bits
);
1553 else if ((CHIPTYPE(sih
->socitype
) == SOCI_AI
) || (CHIPTYPE(sih
->socitype
) == SOCI_NAI
))
1554 ai_core_disable(sih
, bits
);
1555 else if (CHIPTYPE(sih
->socitype
) == SOCI_UBUS
)
1556 ub_core_disable(sih
, bits
);
1560 si_core_reset(si_t
*sih
, uint32 bits
, uint32 resetbits
)
1562 if (CHIPTYPE(sih
->socitype
) == SOCI_SB
)
1563 sb_core_reset(sih
, bits
, resetbits
);
1564 else if ((CHIPTYPE(sih
->socitype
) == SOCI_AI
) || (CHIPTYPE(sih
->socitype
) == SOCI_NAI
))
1565 ai_core_reset(sih
, bits
, resetbits
);
1566 else if (CHIPTYPE(sih
->socitype
) == SOCI_UBUS
)
1567 ub_core_reset(sih
, bits
, resetbits
);
1570 /* Run bist on current core. Caller needs to take care of core-specific bist hazards */
1572 si_corebist(si_t
*sih
)
1577 /* Read core control flags */
1578 cflags
= si_core_cflags(sih
, 0, 0);
1580 /* Set bist & fgc */
1581 si_core_cflags(sih
, ~0, (SICF_BIST_EN
| SICF_FGC
));
1583 /* Wait for bist done */
1584 SPINWAIT(((si_core_sflags(sih
, 0, 0) & SISF_BIST_DONE
) == 0), 100000);
1586 if (si_core_sflags(sih
, 0, 0) & SISF_BIST_ERROR
)
1587 result
= BCME_ERROR
;
1589 /* Reset core control flags */
1590 si_core_cflags(sih
, 0xffff, cflags
);
1596 BCMINITFN(factor6
)(uint32 x
)
1599 case CC_F6_2
: return 2;
1600 case CC_F6_3
: return 3;
1601 case CC_F6_4
: return 4;
1602 case CC_F6_5
: return 5;
1603 case CC_F6_6
: return 6;
1604 case CC_F6_7
: return 7;
1609 /* calculate the speed the SI would run at given a set of clockcontrol values */
1611 BCMINITFN(si_clock_rate
)(uint32 pll_type
, uint32 n
, uint32 m
)
1613 uint32 n1
, n2
, clock
, m1
, m2
, m3
, mc
;
1615 n1
= n
& CN_N1_MASK
;
1616 n2
= (n
& CN_N2_MASK
) >> CN_N2_SHIFT
;
1618 if (pll_type
== PLL_TYPE6
) {
1619 if (m
& CC_T6_MMASK
)
1623 } else if ((pll_type
== PLL_TYPE1
) ||
1624 (pll_type
== PLL_TYPE3
) ||
1625 (pll_type
== PLL_TYPE4
) ||
1626 (pll_type
== PLL_TYPE7
)) {
1629 } else if (pll_type
== PLL_TYPE2
) {
1632 ASSERT((n1
>= 2) && (n1
<= 7));
1633 ASSERT((n2
>= 5) && (n2
<= 23));
1634 } else if (pll_type
== PLL_TYPE5
) {
1638 /* PLL types 3 and 7 use BASE2 (25Mhz) */
1639 if ((pll_type
== PLL_TYPE3
) ||
1640 (pll_type
== PLL_TYPE7
)) {
1641 clock
= CC_CLOCK_BASE2
* n1
* n2
;
1643 clock
= CC_CLOCK_BASE1
* n1
* n2
;
1648 m1
= m
& CC_M1_MASK
;
1649 m2
= (m
& CC_M2_MASK
) >> CC_M2_SHIFT
;
1650 m3
= (m
& CC_M3_MASK
) >> CC_M3_SHIFT
;
1651 mc
= (m
& CC_MC_MASK
) >> CC_MC_SHIFT
;
1653 if ((pll_type
== PLL_TYPE1
) ||
1654 (pll_type
== PLL_TYPE3
) ||
1655 (pll_type
== PLL_TYPE4
) ||
1656 (pll_type
== PLL_TYPE7
)) {
1658 if ((pll_type
== PLL_TYPE1
) || (pll_type
== PLL_TYPE3
))
1665 case CC_MC_BYPASS
: return (clock
);
1666 case CC_MC_M1
: return (clock
/ m1
);
1667 case CC_MC_M1M2
: return (clock
/ (m1
* m2
));
1668 case CC_MC_M1M2M3
: return (clock
/ (m1
* m2
* m3
));
1669 case CC_MC_M1M3
: return (clock
/ (m1
* m3
));
1670 default: return (0);
1673 ASSERT(pll_type
== PLL_TYPE2
);
1678 ASSERT((m1
>= 2) && (m1
<= 7));
1679 ASSERT((m2
>= 3) && (m2
<= 10));
1680 ASSERT((m3
>= 2) && (m3
<= 7));
1682 if ((mc
& CC_T2MC_M1BYP
) == 0)
1684 if ((mc
& CC_T2MC_M2BYP
) == 0)
1686 if ((mc
& CC_T2MC_M3BYP
) == 0)
1693 bool si_read_pmu_autopll(si_t
*sih
)
1697 return (si_pmu_is_autoresetphyclk_disabled(sih
, sii
->osh
));
1701 BCMINITFN(si_clock
)(si_t
*sih
)
1707 uint32 pll_type
, rate
;
1710 if (CHIPID(sih
->chip
) == BCM4707_CHIP_ID
) {
1711 if (sih
->chippkg
== BCM4709_PKG_ID
) {
1714 return NS_SLOW_SI_CLOCK
;
1718 INTR_OFF(sii
, intr_val
);
1719 if (PMUCTL_ENAB(sih
)) {
1720 rate
= si_pmu_si_clock(sih
, sii
->osh
);
1725 cc
= (chipcregs_t
*)si_setcore(sih
, CC_CORE_ID
, 0);
1728 n
= R_REG(sii
->osh
, &cc
->clockcontrol_n
);
1729 pll_type
= sih
->cccaps
& CC_CAP_PLL_MASK
;
1730 if (pll_type
== PLL_TYPE6
)
1731 m
= R_REG(sii
->osh
, &cc
->clockcontrol_m3
);
1732 else if (pll_type
== PLL_TYPE3
)
1733 m
= R_REG(sii
->osh
, &cc
->clockcontrol_m2
);
1735 m
= R_REG(sii
->osh
, &cc
->clockcontrol_sb
);
1737 /* calculate rate */
1738 rate
= si_clock_rate(pll_type
, n
, m
);
1740 if (pll_type
== PLL_TYPE3
)
1743 /* switch back to previous core */
1744 si_setcoreidx(sih
, idx
);
1746 INTR_RESTORE(sii
, intr_val
);
1752 BCMINITFN(si_alp_clock
)(si_t
*sih
)
1754 if (PMUCTL_ENAB(sih
))
1755 return si_pmu_alp_clock(sih
, si_osh(sih
));
1756 else if (CHIPID(sih
->chip
) == BCM4707_CHIP_ID
) {
1757 if (sih
->chippkg
== BCM4709_PKG_ID
)
1758 return NS_ALP_CLOCK
;
1760 return NS_SLOW_ALP_CLOCK
;
1767 BCMINITFN(si_ilp_clock
)(si_t
*sih
)
1769 if (PMUCTL_ENAB(sih
))
1770 return si_pmu_ilp_clock(sih
, si_osh(sih
));
1775 /* set chip watchdog reset timer to fire in 'ticks' */
1777 si_watchdog(si_t
*sih
, uint ticks
)
1781 if (PMUCTL_ENAB(sih
)) {
1783 #if !defined(_CFE_) || defined(CFG_WL)
1784 if ((CHIPID(sih
->chip
) == BCM4319_CHIP_ID
) &&
1785 (CHIPREV(sih
->chiprev
) == 0) && (ticks
!= 0)) {
1786 si_corereg(sih
, SI_CC_IDX
, OFFSETOF(chipcregs_t
, clk_ctl_st
), ~0, 0x2);
1787 si_setcore(sih
, USB20D_CORE_ID
, 0);
1788 si_core_disable(sih
, 1);
1789 si_setcore(sih
, CC_CORE_ID
, 0);
1791 #endif /* !_CFE_ || CFG_WL */
1793 if (CHIPID(sih
->chip
) == BCM4706_CHIP_ID
)
1796 nb
= (sih
->ccrev
< 26) ? 16 : ((sih
->ccrev
>= 37) ? 32 : 24);
1797 /* The mips compiler uses the sllv instruction,
1798 * so we specially handle the 32-bit case.
1803 maxt
= ((1 << nb
) - 1);
1807 else if (ticks
> maxt
)
1810 si_corereg(sih
, SI_CC_IDX
, OFFSETOF(chipcregs_t
, pmuwatchdog
), ~0, ticks
);
1812 /* make sure we come up in fast clock mode; or if clearing, clear clock */
1813 si_clkctl_cc(sih
, ticks
? CLK_FAST
: CLK_DYNAMIC
);
1814 maxt
= (1 << 28) - 1;
1818 si_corereg(sih
, SI_CC_IDX
, OFFSETOF(chipcregs_t
, watchdog
), ~0, ticks
);
1822 /* trigger watchdog reset after ms milliseconds */
1824 si_watchdog_ms(si_t
*sih
, uint32 ms
)
1826 si_watchdog(sih
, wd_msticks
* ms
);
1830 si_watchdog_msticks(void)
1836 si_taclear(si_t
*sih
, bool details
)
1838 #if defined(BCMDBG_ERR) || defined(BCMASSERT_SUPPORT)
1839 if (CHIPTYPE(sih
->socitype
) == SOCI_SB
)
1840 return sb_taclear(sih
, details
);
1841 else if ((CHIPTYPE(sih
->socitype
) == SOCI_AI
) || (CHIPTYPE(sih
->socitype
) == SOCI_NAI
))
1843 else if (CHIPTYPE(sih
->socitype
) == SOCI_UBUS
)
1855 BCMATTACHFN(si_d11_devid
)(si_t
*sih
)
1857 si_info_t
*sii
= SI_INFO(sih
);
1860 /* Fix device id for dual band BCM4328 */
1861 if (CHIPID(sih
->chip
) == BCM4328_CHIP_ID
&&
1862 (sih
->chippkg
== BCM4328USBDUAL_PKG_ID
|| sih
->chippkg
== BCM4328SDIODUAL_PKG_ID
))
1863 device
= BCM4328_D11DUAL_ID
;
1865 /* normal case: nvram variable with devpath->devid->wl0id */
1866 if ((device
= (uint16
)si_getdevpathintvar(sih
, "devid")) != 0)
1868 /* Get devid from OTP/SPROM depending on where the SROM is read */
1869 else if ((device
= (uint16
)getintvar(sii
->vars
, "devid")) != 0)
1871 /* no longer support wl0id, but keep the code here for backward compatibility. */
1872 else if ((device
= (uint16
)getintvar(sii
->vars
, "wl0id")) != 0)
1874 else if (CHIPID(sih
->chip
) == BCM4712_CHIP_ID
) {
1875 /* Chip specific conversion */
1876 if (sih
->chippkg
== BCM4712SMALL_PKG_ID
)
1877 device
= BCM4306_D11G_ID
;
1879 device
= BCM4306_D11DUAL_ID
;
1889 BCMATTACHFN(si_corepciid
)(si_t
*sih
, uint func
, uint16
*pcivendor
, uint16
*pcidevice
,
1890 uint8
*pciclass
, uint8
*pcisubclass
, uint8
*pciprogif
,
1893 uint16 vendor
= 0xffff, device
= 0xffff;
1894 uint8
class, subclass
, progif
= 0;
1895 uint8 header
= PCI_HEADER_NORMAL
;
1896 uint32 core
= si_coreid(sih
);
1898 /* Verify whether the function exists for the core */
1899 if (func
>= (uint
)(core
== USB20H_CORE_ID
? 2 : 1))
1902 /* Known vendor translations */
1903 switch (si_corevendor(sih
)) {
1906 vendor
= VENDOR_BROADCOM
;
1912 /* Determine class based on known core codes */
1915 class = PCI_CLASS_NET
;
1916 subclass
= PCI_NET_ETHER
;
1917 device
= BCM47XX_ENET_ID
;
1919 case GIGETH_CORE_ID
:
1920 class = PCI_CLASS_NET
;
1921 subclass
= PCI_NET_ETHER
;
1922 device
= BCM47XX_GIGETH_ID
;
1925 class = PCI_CLASS_NET
;
1926 subclass
= PCI_NET_ETHER
;
1927 device
= BCM47XX_GMAC_ID
;
1932 case SOCRAM_CORE_ID
:
1933 class = PCI_CLASS_MEMORY
;
1934 subclass
= PCI_MEMORY_RAM
;
1935 device
= (uint16
)core
;
1940 class = PCI_CLASS_BRIDGE
;
1941 subclass
= PCI_BRIDGE_PCI
;
1942 device
= (uint16
)core
;
1943 header
= PCI_HEADER_BRIDGE
;
1945 case MIPS33_CORE_ID
:
1946 case MIPS74K_CORE_ID
:
1947 class = PCI_CLASS_CPU
;
1948 subclass
= PCI_CPU_MIPS
;
1949 device
= (uint16
)core
;
1952 class = PCI_CLASS_COMM
;
1953 subclass
= PCI_COMM_MODEM
;
1954 device
= BCM47XX_V90_ID
;
1957 class = PCI_CLASS_MMEDIA
;
1958 subclass
= PCI_MMEDIA_AUDIO
;
1959 device
= BCM47XX_AUDIO_ID
;
1962 case USB11H_CORE_ID
:
1963 class = PCI_CLASS_SERIAL
;
1964 subclass
= PCI_SERIAL_USB
;
1965 progif
= 0x10; /* OHCI */
1966 device
= BCM47XX_USBH_ID
;
1968 case USB20H_CORE_ID
:
1969 class = PCI_CLASS_SERIAL
;
1970 subclass
= PCI_SERIAL_USB
;
1971 progif
= func
== 0 ? 0x10 : 0x20; /* OHCI/EHCI */
1972 device
= BCM47XX_USB20H_ID
;
1973 header
= 0x80; /* multifunction */
1976 class = PCI_CLASS_CRYPT
;
1977 subclass
= PCI_CRYPT_NETWORK
;
1978 device
= BCM47XX_IPSEC_ID
;
1980 case NS_USB20_CORE_ID
:
1981 class = PCI_CLASS_SERIAL
;
1982 subclass
= PCI_SERIAL_USB
;
1983 progif
= 0x20; /* EHCI */
1984 device
= BCM47XX_USB20H_ID
;
1986 case NS_USB30_CORE_ID
:
1987 class = PCI_CLASS_SERIAL
;
1988 subclass
= PCI_SERIAL_USB
;
1989 progif
= 0x30; /* XHCI */
1990 device
= BCM47XX_USB30H_ID
;
1993 /* Don't use class NETWORK, so wl/et won't attempt to recognize it */
1994 class = PCI_CLASS_COMM
;
1995 subclass
= PCI_COMM_OTHER
;
1996 device
= BCM47XX_ROBO_ID
;
1999 class = PCI_CLASS_MEMORY
;
2000 subclass
= PCI_MEMORY_FLASH
;
2001 device
= (uint16
)core
;
2003 case SATAXOR_CORE_ID
:
2004 class = PCI_CLASS_XOR
;
2005 subclass
= PCI_XOR_QDMA
;
2006 device
= BCM47XX_SATAXOR_ID
;
2008 case ATA100_CORE_ID
:
2009 class = PCI_CLASS_DASDI
;
2010 subclass
= PCI_DASDI_IDE
;
2011 device
= BCM47XX_ATA100_ID
;
2013 case USB11D_CORE_ID
:
2014 class = PCI_CLASS_SERIAL
;
2015 subclass
= PCI_SERIAL_USB
;
2016 device
= BCM47XX_USBD_ID
;
2018 case USB20D_CORE_ID
:
2019 class = PCI_CLASS_SERIAL
;
2020 subclass
= PCI_SERIAL_USB
;
2021 device
= BCM47XX_USB20D_ID
;
2024 class = PCI_CLASS_NET
;
2025 subclass
= PCI_NET_OTHER
;
2026 device
= si_d11_devid(sih
);
2030 class = subclass
= progif
= 0xff;
2031 device
= (uint16
)core
;
2035 *pcivendor
= vendor
;
2036 *pcidevice
= device
;
2038 *pcisubclass
= subclass
;
2039 *pciprogif
= progif
;
2040 *pciheader
= header
;
2046 /* print interesting sbconfig registers */
2048 si_dumpregs(si_t
*sih
, struct bcmstrbuf
*b
)
2051 uint origidx
, intr_val
= 0;
2054 origidx
= sii
->curidx
;
2056 INTR_OFF(sii
, intr_val
);
2057 if (CHIPTYPE(sih
->socitype
) == SOCI_SB
)
2058 sb_dumpregs(sih
, b
);
2059 else if ((CHIPTYPE(sih
->socitype
) == SOCI_AI
) || (CHIPTYPE(sih
->socitype
) == SOCI_NAI
))
2060 ai_dumpregs(sih
, b
);
2061 else if (CHIPTYPE(sih
->socitype
) == SOCI_UBUS
)
2062 ub_dumpregs(sih
, b
);
2066 si_setcoreidx(sih
, origidx
);
2067 INTR_RESTORE(sii
, intr_val
);
2073 si_view(si_t
*sih
, bool verbose
)
2075 if (CHIPTYPE(sih
->socitype
) == SOCI_SB
)
2076 sb_view(sih
, verbose
);
2077 else if ((CHIPTYPE(sih
->socitype
) == SOCI_AI
) || (CHIPTYPE(sih
->socitype
) == SOCI_NAI
))
2078 ai_view(sih
, verbose
);
2079 else if (CHIPTYPE(sih
->socitype
) == SOCI_UBUS
)
2080 ub_view(sih
, verbose
);
2086 si_viewall(si_t
*sih
, bool verbose
)
2093 curidx
= sii
->curidx
;
2095 INTR_OFF(sii
, intr_val
);
2096 if ((CHIPTYPE(sih
->socitype
) == SOCI_AI
) || (CHIPTYPE(sih
->socitype
) == SOCI_NAI
))
2097 ai_viewall(sih
, verbose
);
2099 SI_ERROR(("si_viewall: num_cores %d\n", sii
->numcores
));
2100 for (i
= 0; i
< sii
->numcores
; i
++) {
2101 si_setcoreidx(sih
, i
);
2102 si_view(sih
, verbose
);
2105 si_setcoreidx(sih
, curidx
);
2106 INTR_RESTORE(sii
, intr_val
);
2110 /* return the slow clock source - LPO, XTAL, or PCI */
2112 si_slowclk_src(si_info_t
*sii
)
2116 ASSERT(SI_FAST(sii
) || si_coreid(&sii
->pub
) == CC_CORE_ID
);
2118 if (sii
->pub
.ccrev
< 6) {
2119 if ((BUSTYPE(sii
->pub
.bustype
) == PCI_BUS
) &&
2120 (OSL_PCI_READ_CONFIG(sii
->osh
, PCI_GPIO_OUT
, sizeof(uint32
)) &
2122 return (SCC_SS_PCI
);
2124 return (SCC_SS_XTAL
);
2125 } else if (sii
->pub
.ccrev
< 10) {
2126 cc
= (chipcregs_t
*)si_setcoreidx(&sii
->pub
, sii
->curidx
);
2127 return (R_REG(sii
->osh
, &cc
->slow_clk_ctl
) & SCC_SS_MASK
);
2128 } else /* Insta-clock */
2129 return (SCC_SS_XTAL
);
2132 /* return the ILP (slowclock) min or max frequency */
2134 si_slowclk_freq(si_info_t
*sii
, bool max_freq
, chipcregs_t
*cc
)
2139 ASSERT(SI_FAST(sii
) || si_coreid(&sii
->pub
) == CC_CORE_ID
);
2141 /* shouldn't be here unless we've established the chip has dynamic clk control */
2142 ASSERT(R_REG(sii
->osh
, &cc
->capabilities
) & CC_CAP_PWR_CTL
);
2144 slowclk
= si_slowclk_src(sii
);
2145 if (sii
->pub
.ccrev
< 6) {
2146 if (slowclk
== SCC_SS_PCI
)
2147 return (max_freq
? (PCIMAXFREQ
/ 64) : (PCIMINFREQ
/ 64));
2149 return (max_freq
? (XTALMAXFREQ
/ 32) : (XTALMINFREQ
/ 32));
2150 } else if (sii
->pub
.ccrev
< 10) {
2152 (((R_REG(sii
->osh
, &cc
->slow_clk_ctl
) & SCC_CD_MASK
) >> SCC_CD_SHIFT
) + 1);
2153 if (slowclk
== SCC_SS_LPO
)
2154 return (max_freq
? LPOMAXFREQ
: LPOMINFREQ
);
2155 else if (slowclk
== SCC_SS_XTAL
)
2156 return (max_freq
? (XTALMAXFREQ
/ div
) : (XTALMINFREQ
/ div
));
2157 else if (slowclk
== SCC_SS_PCI
)
2158 return (max_freq
? (PCIMAXFREQ
/ div
) : (PCIMINFREQ
/ div
));
2162 /* Chipc rev 10 is InstaClock */
2163 div
= R_REG(sii
->osh
, &cc
->system_clk_ctl
) >> SYCC_CD_SHIFT
;
2164 div
= 4 * (div
+ 1);
2165 return (max_freq
? XTALMAXFREQ
: (XTALMINFREQ
/ div
));
2171 BCMINITFN(si_clkctl_setdelay
)(si_info_t
*sii
, void *chipcregs
)
2173 chipcregs_t
*cc
= (chipcregs_t
*)chipcregs
;
2174 uint slowmaxfreq
, pll_delay
, slowclk
;
2175 uint pll_on_delay
, fref_sel_delay
;
2177 pll_delay
= PLL_DELAY
;
2179 /* If the slow clock is not sourced by the xtal then add the xtal_on_delay
2180 * since the xtal will also be powered down by dynamic clk control logic.
2183 slowclk
= si_slowclk_src(sii
);
2184 if (slowclk
!= SCC_SS_XTAL
)
2185 pll_delay
+= XTAL_ON_DELAY
;
2187 /* Starting with 4318 it is ILP that is used for the delays */
2188 slowmaxfreq
= si_slowclk_freq(sii
, (sii
->pub
.ccrev
>= 10) ? FALSE
: TRUE
, cc
);
2190 pll_on_delay
= ((slowmaxfreq
* pll_delay
) + 999999) / 1000000;
2191 fref_sel_delay
= ((slowmaxfreq
* FREF_DELAY
) + 999999) / 1000000;
2193 W_REG(sii
->osh
, &cc
->pll_on_delay
, pll_on_delay
);
2194 W_REG(sii
->osh
, &cc
->fref_sel_delay
, fref_sel_delay
);
2197 /* initialize power control delay registers */
2199 BCMINITFN(si_clkctl_init
)(si_t
*sih
)
2206 if (!CCCTL_ENAB(sih
))
2210 fast
= SI_FAST(sii
);
2212 origidx
= sii
->curidx
;
2213 if ((cc
= (chipcregs_t
*)si_setcore(sih
, CC_CORE_ID
, 0)) == NULL
)
2215 } else if ((cc
= (chipcregs_t
*)CCREGS_FAST(sii
)) == NULL
)
2219 /* set all Instaclk chip ILP to 1 MHz */
2220 if (sih
->ccrev
>= 10)
2221 SET_REG(sii
->osh
, &cc
->system_clk_ctl
, SYCC_CD_MASK
,
2222 (ILP_DIV_1MHZ
<< SYCC_CD_SHIFT
));
2224 si_clkctl_setdelay(sii
, (void *)(uintptr
)cc
);
2229 si_setcoreidx(sih
, origidx
);
2232 /* return the value suitable for writing to the dot11 core FAST_PWRUP_DELAY register */
2234 BCMINITFN(si_clkctl_fast_pwrup_delay
)(si_t
*sih
)
2245 if (PMUCTL_ENAB(sih
)) {
2246 INTR_OFF(sii
, intr_val
);
2247 fpdelay
= si_pmu_fast_pwrup_delay(sih
, sii
->osh
);
2248 INTR_RESTORE(sii
, intr_val
);
2252 if (!CCCTL_ENAB(sih
))
2255 fast
= SI_FAST(sii
);
2258 origidx
= sii
->curidx
;
2259 INTR_OFF(sii
, intr_val
);
2260 if ((cc
= (chipcregs_t
*)si_setcore(sih
, CC_CORE_ID
, 0)) == NULL
)
2263 else if ((cc
= (chipcregs_t
*)CCREGS_FAST(sii
)) == NULL
)
2267 slowminfreq
= si_slowclk_freq(sii
, FALSE
, cc
);
2268 fpdelay
= (((R_REG(sii
->osh
, &cc
->pll_on_delay
) + 2) * 1000000) +
2269 (slowminfreq
- 1)) / slowminfreq
;
2273 si_setcoreidx(sih
, origidx
);
2274 INTR_RESTORE(sii
, intr_val
);
2279 /* turn primary xtal and/or pll off/on */
2281 si_clkctl_xtal(si_t
*sih
, uint what
, bool on
)
2284 uint32 in
, out
, outen
;
2288 switch (BUSTYPE(sih
->bustype
)) {
2296 /* pcie core doesn't have any mapping to control the xtal pu */
2300 in
= OSL_PCI_READ_CONFIG(sii
->osh
, PCI_GPIO_IN
, sizeof(uint32
));
2301 out
= OSL_PCI_READ_CONFIG(sii
->osh
, PCI_GPIO_OUT
, sizeof(uint32
));
2302 outen
= OSL_PCI_READ_CONFIG(sii
->osh
, PCI_GPIO_OUTEN
, sizeof(uint32
));
2305 * Avoid glitching the clock if GPRS is already using it.
2306 * We can't actually read the state of the PLLPD so we infer it
2307 * by the value of XTAL_PU which *is* readable via gpioin.
2309 if (on
&& (in
& PCI_CFG_GPIO_XTAL
))
2313 outen
|= PCI_CFG_GPIO_XTAL
;
2315 outen
|= PCI_CFG_GPIO_PLL
;
2318 /* turn primary xtal on */
2320 out
|= PCI_CFG_GPIO_XTAL
;
2322 out
|= PCI_CFG_GPIO_PLL
;
2323 OSL_PCI_WRITE_CONFIG(sii
->osh
, PCI_GPIO_OUT
,
2324 sizeof(uint32
), out
);
2325 OSL_PCI_WRITE_CONFIG(sii
->osh
, PCI_GPIO_OUTEN
,
2326 sizeof(uint32
), outen
);
2327 OSL_DELAY(XTAL_ON_DELAY
);
2332 out
&= ~PCI_CFG_GPIO_PLL
;
2333 OSL_PCI_WRITE_CONFIG(sii
->osh
, PCI_GPIO_OUT
,
2334 sizeof(uint32
), out
);
2339 out
&= ~PCI_CFG_GPIO_XTAL
;
2341 out
|= PCI_CFG_GPIO_PLL
;
2342 OSL_PCI_WRITE_CONFIG(sii
->osh
, PCI_GPIO_OUT
, sizeof(uint32
), out
);
2343 OSL_PCI_WRITE_CONFIG(sii
->osh
, PCI_GPIO_OUTEN
, sizeof(uint32
),
2356 * clock control policy function throught chipcommon
2358 * set dynamic clk control mode (forceslow, forcefast, dynamic)
2359 * returns true if we are forcing fast clock
2360 * this is a wrapper over the next internal function
2361 * to allow flexible policy settings for outside caller
2364 si_clkctl_cc(si_t
*sih
, uint mode
)
2370 /* chipcommon cores prior to rev6 don't support dynamic clock control */
2374 if (PCI_FORCEHT(sii
))
2375 return (mode
== CLK_FAST
);
2377 return _si_clkctl_cc(sii
, mode
);
2380 /* clk control mechanism through chipcommon, no policy checking */
2382 _si_clkctl_cc(si_info_t
*sii
, uint mode
)
2388 bool fast
= SI_FAST(sii
);
2390 /* chipcommon cores prior to rev6 don't support dynamic clock control */
2391 if (sii
->pub
.ccrev
< 6)
2394 /* Chips with ccrev 10 are EOL and they don't have SYCC_HR which we use below */
2395 ASSERT(sii
->pub
.ccrev
!= 10);
2398 INTR_OFF(sii
, intr_val
);
2399 origidx
= sii
->curidx
;
2401 if ((BUSTYPE(sii
->pub
.bustype
) == SI_BUS
) &&
2402 si_setcore(&sii
->pub
, MIPS33_CORE_ID
, 0) &&
2403 (si_corerev(&sii
->pub
) <= 7) && (sii
->pub
.ccrev
>= 10))
2406 cc
= (chipcregs_t
*) si_setcore(&sii
->pub
, CC_CORE_ID
, 0);
2407 } else if ((cc
= (chipcregs_t
*) CCREGS_FAST(sii
)) == NULL
)
2411 if (!CCCTL_ENAB(&sii
->pub
) && (sii
->pub
.ccrev
< 20))
2415 case CLK_FAST
: /* FORCEHT, fast (pll) clock */
2416 if (sii
->pub
.ccrev
< 10) {
2417 /* don't forget to force xtal back on before we clear SCC_DYN_XTAL.. */
2418 si_clkctl_xtal(&sii
->pub
, XTAL
, ON
);
2419 SET_REG(sii
->osh
, &cc
->slow_clk_ctl
, (SCC_XC
| SCC_FS
| SCC_IP
), SCC_IP
);
2420 } else if (sii
->pub
.ccrev
< 20) {
2421 OR_REG(sii
->osh
, &cc
->system_clk_ctl
, SYCC_HR
);
2423 OR_REG(sii
->osh
, &cc
->clk_ctl_st
, CCS_FORCEHT
);
2426 /* wait for the PLL */
2427 if (PMUCTL_ENAB(&sii
->pub
)) {
2428 uint32 htavail
= CCS_HTAVAIL
;
2429 if (CHIPID(sii
->pub
.chip
) == BCM4328_CHIP_ID
)
2430 htavail
= CCS0_HTAVAIL
;
2431 SPINWAIT(((R_REG(sii
->osh
, &cc
->clk_ctl_st
) & htavail
) == 0),
2432 PMU_MAX_TRANSITION_DLY
);
2433 ASSERT(R_REG(sii
->osh
, &cc
->clk_ctl_st
) & htavail
);
2435 OSL_DELAY(PLL_DELAY
);
2439 case CLK_DYNAMIC
: /* enable dynamic clock control */
2440 if (sii
->pub
.ccrev
< 10) {
2441 scc
= R_REG(sii
->osh
, &cc
->slow_clk_ctl
);
2442 scc
&= ~(SCC_FS
| SCC_IP
| SCC_XC
);
2443 if ((scc
& SCC_SS_MASK
) != SCC_SS_XTAL
)
2445 W_REG(sii
->osh
, &cc
->slow_clk_ctl
, scc
);
2447 /* for dynamic control, we have to release our xtal_pu "force on" */
2449 si_clkctl_xtal(&sii
->pub
, XTAL
, OFF
);
2450 } else if (sii
->pub
.ccrev
< 20) {
2452 AND_REG(sii
->osh
, &cc
->system_clk_ctl
, ~SYCC_HR
);
2454 AND_REG(sii
->osh
, &cc
->clk_ctl_st
, ~CCS_FORCEHT
);
2457 /* wait for the PLL */
2458 if (PMUCTL_ENAB(&sii
->pub
)) {
2459 uint32 htavail
= CCS_HTAVAIL
;
2460 if (CHIPID(sii
->pub
.chip
) == BCM4328_CHIP_ID
)
2461 htavail
= CCS0_HTAVAIL
;
2462 SPINWAIT(((R_REG(sii
->osh
, &cc
->clk_ctl_st
) & htavail
) != 0),
2463 PMU_MAX_TRANSITION_DLY
);
2464 ASSERT(!(R_REG(sii
->osh
, &cc
->clk_ctl_st
) & htavail
));
2466 OSL_DELAY(PLL_DELAY
);
2477 si_setcoreidx(&sii
->pub
, origidx
);
2478 INTR_RESTORE(sii
, intr_val
);
2480 return (mode
== CLK_FAST
);
2483 /* Build device path. Support SI, PCI, and JTAG for now. */
2485 BCMNMIATTACHFN(si_devpath
)(si_t
*sih
, char *path
, int size
)
2489 ASSERT(path
!= NULL
);
2490 ASSERT(size
>= SI_DEVPATH_BUFSZ
);
2492 if (!path
|| size
<= 0)
2495 switch (BUSTYPE(sih
->bustype
)) {
2498 slen
= snprintf(path
, (size_t)size
, "sb/%u/", si_coreidx(sih
));
2501 ASSERT((SI_INFO(sih
))->osh
!= NULL
);
2502 slen
= snprintf(path
, (size_t)size
, "pci/%u/%u/",
2503 OSL_PCI_BUS((SI_INFO(sih
))->osh
),
2504 OSL_PCI_SLOT((SI_INFO(sih
))->osh
));
2507 SI_ERROR(("si_devpath: OSL_PCMCIA_BUS() not implemented, bus 1 assumed\n"));
2508 SI_ERROR(("si_devpath: OSL_PCMCIA_SLOT() not implemented, slot 1 assumed\n"));
2509 slen
= snprintf(path
, (size_t)size
, "pc/1/1/");
2517 if (slen
< 0 || slen
>= size
) {
2526 BCMATTACHFN(si_coded_devpathvar
)(si_t
*sih
, char *varname
, int var_len
, const char *name
)
2528 char pathname
[SI_DEVPATH_BUFSZ
+ 32];
2529 char devpath
[SI_DEVPATH_BUFSZ
+ 32];
2535 /* try to get compact devpath if it exist */
2536 if (si_devpath(sih
, devpath
, SI_DEVPATH_BUFSZ
) == 0) {
2537 /* eliminate ending '/' (if present) */
2538 len1
= strlen(devpath
);
2539 if (devpath
[len1
- 1] == '/')
2542 for (idx
= 0; idx
< SI_MAXCORES
; idx
++) {
2543 snprintf(pathname
, SI_DEVPATH_BUFSZ
, "devpath%d", idx
);
2544 if ((p
= getvar(NULL
, pathname
)) == NULL
)
2547 /* eliminate ending '/' (if present) */
2549 if (p
[len2
- 1] == '/')
2552 /* check that both lengths match and if so compare */
2553 /* the strings (minus trailing '/'s if present */
2554 if ((len1
== len2
) && (memcmp(p
, devpath
, len1
) == 0)) {
2555 snprintf(varname
, var_len
, "%d:%s", idx
, name
);
2564 /* Get a variable, but only if it has a devpath prefix */
2566 BCMATTACHFN(si_getdevpathvar
)(si_t
*sih
, const char *name
)
2568 char varname
[SI_DEVPATH_BUFSZ
+ 32];
2571 si_devpathvar(sih
, varname
, sizeof(varname
), name
);
2573 if ((val
= getvar(NULL
, varname
)) != NULL
)
2576 /* try to get compact devpath if it exist */
2577 if (si_coded_devpathvar(sih
, varname
, sizeof(varname
), name
) == NULL
)
2580 return (getvar(NULL
, varname
));
2583 /* Get a variable, but only if it has a devpath prefix */
2585 BCMATTACHFN(si_getdevpathintvar
)(si_t
*sih
, const char *name
)
2587 #if defined(BCMBUSTYPE) && (BCMBUSTYPE == SI_BUS)
2588 return (getintvar(NULL
, name
));
2590 char varname
[SI_DEVPATH_BUFSZ
+ 32];
2593 si_devpathvar(sih
, varname
, sizeof(varname
), name
);
2595 if ((val
= getintvar(NULL
, varname
)) != 0)
2598 /* try to get compact devpath if it exist */
2599 if (si_coded_devpathvar(sih
, varname
, sizeof(varname
), name
) == NULL
)
2602 return (getintvar(NULL
, varname
));
2603 #endif /* BCMBUSTYPE && BCMBUSTYPE == SI_BUS */
2608 si_getnvramflvar(si_t
*sih
, const char *name
)
2610 return (getvar(NULL
, name
));
2612 #endif /* DONGLEBUILD */
2614 /* Concatenate the dev path with a varname into the given 'var' buffer
2615 * and return the 'var' pointer.
2616 * Nothing is done to the arguments if len == 0 or var is NULL, var is still returned.
2617 * On overflow, the first char will be set to '\0'.
2620 BCMATTACHFN(si_devpathvar
)(si_t
*sih
, char *var
, int len
, const char *name
)
2624 if (!var
|| len
<= 0)
2627 if (si_devpath(sih
, var
, len
) == 0) {
2628 path_len
= strlen(var
);
2630 if (strlen(name
) + 1 > (uint
)(len
- path_len
))
2633 strncpy(var
+ path_len
, name
, len
- path_len
- 1);
2641 si_pciereg(si_t
*sih
, uint32 offset
, uint32 mask
, uint32 val
, uint type
)
2648 SI_ERROR(("%s: Not a PCIE device\n", __FUNCTION__
));
2652 return pcicore_pciereg(sii
->pch
, offset
, mask
, val
, type
);
2656 si_pcieserdesreg(si_t
*sih
, uint32 mdioslave
, uint32 offset
, uint32 mask
, uint32 val
)
2663 SI_ERROR(("%s: Not a PCIE device\n", __FUNCTION__
));
2667 return pcicore_pcieserdesreg(sii
->pch
, mdioslave
, offset
, mask
, val
);
2671 /* return TRUE if PCIE capability exists in the pci config space */
2673 si_ispcie(si_info_t
*sii
)
2677 if (BUSTYPE(sii
->pub
.bustype
) != PCI_BUS
)
2680 cap_ptr
= pcicore_find_pci_capability(sii
->osh
, PCI_CAP_PCIECAP_ID
, NULL
, NULL
);
2687 /* Wake-on-wireless-LAN (WOWL) support functions */
2688 /* Enable PME generation and disable clkreq */
2690 si_pci_pmeen(si_t
*sih
)
2696 pcicore_pmeen(sii
->pch
);
2699 /* Return TRUE if PME status is set */
2701 si_pci_pmestat(si_t
*sih
)
2707 return pcicore_pmestat(sii
->pch
);
2710 /* Disable PME generation, clear the PME status bit if set */
2712 si_pci_pmeclr(si_t
*sih
)
2718 pcicore_pmeclr(sii
->pch
);
2722 si_pci_pmestatclr(si_t
*sih
)
2728 pcicore_pmestatclr(sii
->pch
);
2731 /* initialize the pcmcia core */
2733 si_pcmcia_init(si_t
*sih
)
2740 /* enable d11 mac interrupts */
2741 OSL_PCMCIA_READ_ATTR(sii
->osh
, PCMCIA_FCR0
+ PCMCIA_COR
, &cor
, 1);
2742 cor
|= COR_IRQEN
| COR_FUNEN
;
2743 OSL_PCMCIA_WRITE_ATTR(sii
->osh
, PCMCIA_FCR0
+ PCMCIA_COR
, &cor
, 1);
2749 BCMATTACHFN(si_pci_war16165
)(si_t
*sih
)
2755 return (PCI(sii
) && (sih
->buscorerev
<= 10));
2758 /* Disable pcie_war_ovr for some platforms (sigh!)
2759 * This is for boards that have BFL2_PCIEWAR_OVR set
2760 * but are in systems that still want the benefits of ASPM
2761 * Note that this should be done AFTER si_doattach
2764 si_pcie_war_ovr_update(si_t
*sih
, uint8 aspm
)
2770 if (!PCIE_GEN1(sii
))
2773 pcie_war_ovr_aspm_update(sii
->pch
, aspm
);
2777 si_pcie_power_save_enable(si_t
*sih
, bool enable
)
2783 if (!PCIE_GEN1(sii
))
2786 pcie_power_save_enable(sii
->pch
, enable
);
2790 si_pcie_set_maxpayload_size(si_t
*sih
, uint16 size
)
2799 pcie_set_maxpayload_size(sii
->pch
, size
);
2803 si_pcie_get_maxpayload_size(si_t
*sih
)
2812 return pcie_get_maxpayload_size(sii
->pch
);
2816 si_pcie_set_request_size(si_t
*sih
, uint16 size
)
2825 pcie_set_request_size(sii
->pch
, size
);
2829 si_pcie_get_request_size(si_t
*sih
)
2835 if (!PCIE_GEN1(sii
))
2838 return pcie_get_request_size(sii
->pch
);
2843 si_pcie_get_ssid(si_t
*sih
)
2849 if (!PCIE_GEN1(sii
))
2852 return pcie_get_ssid(sii
->pch
);
2856 si_pcie_get_bar0(si_t
*sih
)
2865 return pcie_get_bar0(sii
->pch
);
2869 si_pcie_configspace_cache(si_t
*sih
)
2878 return pcie_configspace_cache(sii
->pch
);
2882 si_pcie_configspace_restore(si_t
*sih
)
2891 return pcie_configspace_restore(sii
->pch
);
2895 si_pcie_configspace_get(si_t
*sih
, uint8
*buf
, uint size
)
2901 if (!PCIE(sii
) || size
> PCI_CONFIG_SPACE_SIZE
)
2904 return pcie_configspace_get(sii
->pch
, buf
, size
);
2907 /* back door for other module to override chippkg */
2909 si_chippkg_set(si_t
*sih
, uint val
)
2915 sii
->pub
.chippkg
= val
;
2919 BCMINITFN(si_pci_up
)(si_t
*sih
)
2925 /* if not pci bus, we're done */
2926 if (BUSTYPE(sih
->bustype
) != PCI_BUS
)
2929 if (PCI_FORCEHT(sii
))
2930 _si_clkctl_cc(sii
, CLK_FAST
);
2933 pcicore_up(sii
->pch
, SI_PCIUP
);
2934 if (((CHIPID(sih
->chip
) == BCM4311_CHIP_ID
) && (CHIPREV(sih
->chiprev
) == 2)) ||
2935 (CHIPID(sih
->chip
) == BCM4312_CHIP_ID
))
2936 sb_set_initiator_to((void *)sii
, 0x3,
2937 si_findcoreidx((void *)sii
, D11_CORE_ID
, 0));
2941 /* Unconfigure and/or apply various WARs when system is going to sleep mode */
2943 BCMUNINITFN(si_pci_sleep
)(si_t
*sih
)
2947 do_4360_pcie2_war
= 0;
2951 pcicore_sleep(sii
->pch
);
2954 /* Unconfigure and/or apply various WARs when going down */
2956 BCMINITFN(si_pci_down
)(si_t
*sih
)
2962 /* if not pci bus, we're done */
2963 if (BUSTYPE(sih
->bustype
) != PCI_BUS
)
2966 /* release FORCEHT since chip is going to "down" state */
2967 if (PCI_FORCEHT(sii
))
2968 _si_clkctl_cc(sii
, CLK_DYNAMIC
);
2970 pcicore_down(sii
->pch
, SI_PCIDOWN
);
2974 * Configure the pci core for pci client (NIC) action
2975 * coremask is the bitvec of cores by index to be enabled.
2978 BCMATTACHFN(si_pci_setup
)(si_t
*sih
, uint coremask
)
2981 sbpciregs_t
*pciregs
= NULL
;
2982 uint32 siflag
= 0, w
;
2987 if (BUSTYPE(sii
->pub
.bustype
) != PCI_BUS
)
2990 ASSERT(PCI(sii
) || PCIE(sii
));
2991 ASSERT(sii
->pub
.buscoreidx
!= BADIDX
);
2994 /* get current core index */
2997 /* we interrupt on this backplane flag number */
2998 siflag
= si_flag(sih
);
3000 /* switch over to pci core */
3001 pciregs
= (sbpciregs_t
*)si_setcoreidx(sih
, sii
->pub
.buscoreidx
);
3005 * Enable sb->pci interrupts. Assume
3006 * PCI rev 2.3 support was added in pci core rev 6 and things changed..
3008 if (PCIE(sii
) || (PCI(sii
) && ((sii
->pub
.buscorerev
) >= 6))) {
3009 /* pci config write to set this core bit in PCIIntMask */
3010 w
= OSL_PCI_READ_CONFIG(sii
->osh
, PCI_INT_MASK
, sizeof(uint32
));
3011 w
|= (coremask
<< PCI_SBIM_SHIFT
);
3013 /* User mode operate with interrupt disabled */
3014 w
&= !(coremask
<< PCI_SBIM_SHIFT
);
3016 OSL_PCI_WRITE_CONFIG(sii
->osh
, PCI_INT_MASK
, sizeof(uint32
), w
);
3018 /* set sbintvec bit for our flag number */
3019 si_setint(sih
, siflag
);
3023 OR_REG(sii
->osh
, &pciregs
->sbtopci2
, (SBTOPCI_PREF
| SBTOPCI_BURST
));
3024 if (sii
->pub
.buscorerev
>= 11) {
3025 OR_REG(sii
->osh
, &pciregs
->sbtopci2
, SBTOPCI_RC_READMULTI
);
3026 w
= R_REG(sii
->osh
, &pciregs
->clkrun
);
3027 W_REG(sii
->osh
, &pciregs
->clkrun
, (w
| PCI_CLKRUN_DSBL
));
3028 w
= R_REG(sii
->osh
, &pciregs
->clkrun
);
3031 /* switch back to previous core */
3032 si_setcoreidx(sih
, idx
);
3037 si_pcieclkreq(si_t
*sih
, uint32 mask
, uint32 val
)
3046 return pcie_clkreq(sii
->pch
, mask
, val
);
3050 si_pcielcreg(si_t
*sih
, uint32 mask
, uint32 val
)
3059 return pcie_lcreg(sii
->pch
, mask
, val
);
3063 si_pcieltrenable(si_t
*sih
, uint32 mask
, uint32 val
)
3072 return pcie_ltrenable(sii
->pch
, mask
, val
);
3076 si_pcie_set_error_injection(si_t
*sih
, uint32 mode
)
3085 pcie_set_error_injection(sii
->pch
, mode
);
3088 /* indirect way to read pcie config regs */
3090 si_pcie_readreg(void *sih
, uint addrtype
, uint offset
)
3092 return pcie_readreg(sih
, (sbpcieregs_t
*)PCIEREGS(((si_info_t
*)sih
)),
3097 * Fixup SROMless PCI device's configuration.
3098 * The current core may be changed upon return.
3101 si_pci_fixcfg(si_t
*sih
)
3103 uint origidx
, pciidx
;
3104 sbpciregs_t
*pciregs
= NULL
;
3105 sbpcieregs_t
*pcieregs
= NULL
;
3106 uint16 val16
, *reg16
= NULL
;
3109 si_info_t
*sii
= SI_INFO(sih
);
3111 ASSERT(BUSTYPE(sii
->pub
.bustype
) == PCI_BUS
);
3113 if ((CHIPID(sii
->pub
.chip
) == BCM4321_CHIP_ID
) && (CHIPREV(sii
->pub
.chiprev
) < 2)) {
3114 w
= (CHIPREV(sii
->pub
.chiprev
) == 0) ?
3115 CHIPCTRL_4321A0_DEFAULT
: CHIPCTRL_4321A1_DEFAULT
;
3116 si_corereg(&sii
->pub
, SI_CC_IDX
, OFFSETOF(chipcregs_t
, chipcontrol
), ~0, w
);
3119 /* Fixup PI in SROM shadow area to enable the correct PCI core access */
3120 /* save the current index */
3121 origidx
= si_coreidx(&sii
->pub
);
3123 /* check 'pi' is correct and fix it if not */
3124 if (sii
->pub
.buscoretype
== PCIE2_CORE_ID
) {
3125 pcieregs
= (sbpcieregs_t
*)si_setcore(&sii
->pub
, PCIE2_CORE_ID
, 0);
3126 ASSERT(pcieregs
!= NULL
);
3127 reg16
= &pcieregs
->sprom
[SRSH_PI_OFFSET
];
3128 } else if (sii
->pub
.buscoretype
== PCIE_CORE_ID
) {
3129 pcieregs
= (sbpcieregs_t
*)si_setcore(&sii
->pub
, PCIE_CORE_ID
, 0);
3130 ASSERT(pcieregs
!= NULL
);
3131 reg16
= &pcieregs
->sprom
[SRSH_PI_OFFSET
];
3132 } else if (sii
->pub
.buscoretype
== PCI_CORE_ID
) {
3133 pciregs
= (sbpciregs_t
*)si_setcore(&sii
->pub
, PCI_CORE_ID
, 0);
3134 ASSERT(pciregs
!= NULL
);
3135 reg16
= &pciregs
->sprom
[SRSH_PI_OFFSET
];
3137 pciidx
= si_coreidx(&sii
->pub
);
3139 if (!reg16
) return -1;
3141 val16
= R_REG(sii
->osh
, reg16
);
3142 if (((val16
& SRSH_PI_MASK
) >> SRSH_PI_SHIFT
) != (uint16
)pciidx
) {
3143 val16
= (uint16
)(pciidx
<< SRSH_PI_SHIFT
) | (val16
& ~SRSH_PI_MASK
);
3144 W_REG(sii
->osh
, reg16
, val16
);
3147 /* restore the original index */
3148 si_setcoreidx(&sii
->pub
, origidx
);
3150 pcicore_hwup(sii
->pch
);
3157 /* change logical "focus" to the gpio core for optimized access */
3159 si_gpiosetcore(si_t
*sih
)
3161 return (si_setcoreidx(sih
, SI_CC_IDX
));
3165 * mask & set gpiocontrol bits.
3166 * If a gpiocontrol bit is set to 0, chipcommon controls the corresponding GPIO pin.
3167 * If a gpiocontrol bit is set to 1, the GPIO pin is no longer a GPIO and becomes dedicated
3168 * to some chip-specific purpose.
3171 si_gpiocontrol(si_t
*sih
, uint32 mask
, uint32 val
, uint8 priority
)
3177 /* gpios could be shared on router platforms
3178 * ignore reservation if it's high priority (e.g., test apps)
3180 if ((priority
!= GPIO_HI_PRIORITY
) &&
3181 (BUSTYPE(sih
->bustype
) == SI_BUS
) && (val
|| mask
)) {
3182 mask
= priority
? (si_gpioreservation
& mask
) :
3183 ((si_gpioreservation
| mask
) & ~(si_gpioreservation
));
3187 regoff
= OFFSETOF(chipcregs_t
, gpiocontrol
);
3188 return (si_corereg(sih
, SI_CC_IDX
, regoff
, mask
, val
));
3191 /* mask&set gpio output enable bits */
3193 si_gpioouten(si_t
*sih
, uint32 mask
, uint32 val
, uint8 priority
)
3199 /* gpios could be shared on router platforms
3200 * ignore reservation if it's high priority (e.g., test apps)
3202 if ((priority
!= GPIO_HI_PRIORITY
) &&
3203 (BUSTYPE(sih
->bustype
) == SI_BUS
) && (val
|| mask
)) {
3204 mask
= priority
? (si_gpioreservation
& mask
) :
3205 ((si_gpioreservation
| mask
) & ~(si_gpioreservation
));
3209 regoff
= OFFSETOF(chipcregs_t
, gpioouten
);
3210 return (si_corereg(sih
, SI_CC_IDX
, regoff
, mask
, val
));
3213 /* mask&set gpio output bits */
3215 si_gpioout(si_t
*sih
, uint32 mask
, uint32 val
, uint8 priority
)
3221 /* gpios could be shared on router platforms
3222 * ignore reservation if it's high priority (e.g., test apps)
3224 if ((priority
!= GPIO_HI_PRIORITY
) &&
3225 (BUSTYPE(sih
->bustype
) == SI_BUS
) && (val
|| mask
)) {
3226 mask
= priority
? (si_gpioreservation
& mask
) :
3227 ((si_gpioreservation
| mask
) & ~(si_gpioreservation
));
3231 regoff
= OFFSETOF(chipcregs_t
, gpioout
);
3232 return (si_corereg(sih
, SI_CC_IDX
, regoff
, mask
, val
));
3235 /* reserve one gpio */
3237 si_gpioreserve(si_t
*sih
, uint32 gpio_bitmask
, uint8 priority
)
3239 /* only cores on SI_BUS share GPIO's and only applcation users need to
3240 * reserve/release GPIO
3242 if ((BUSTYPE(sih
->bustype
) != SI_BUS
) || (!priority
)) {
3243 ASSERT((BUSTYPE(sih
->bustype
) == SI_BUS
) && (priority
));
3246 /* make sure only one bit is set */
3247 if ((!gpio_bitmask
) || ((gpio_bitmask
) & (gpio_bitmask
- 1))) {
3248 ASSERT((gpio_bitmask
) && !((gpio_bitmask
) & (gpio_bitmask
- 1)));
3252 /* already reserved */
3253 if (si_gpioreservation
& gpio_bitmask
)
3255 /* set reservation */
3256 si_gpioreservation
|= gpio_bitmask
;
3258 return si_gpioreservation
;
3261 /* release one gpio */
3263 * releasing the gpio doesn't change the current value on the GPIO last write value
3264 * persists till some one overwrites it
3268 si_gpiorelease(si_t
*sih
, uint32 gpio_bitmask
, uint8 priority
)
3270 /* only cores on SI_BUS share GPIO's and only applcation users need to
3271 * reserve/release GPIO
3273 if ((BUSTYPE(sih
->bustype
) != SI_BUS
) || (!priority
)) {
3274 ASSERT((BUSTYPE(sih
->bustype
) == SI_BUS
) && (priority
));
3277 /* make sure only one bit is set */
3278 if ((!gpio_bitmask
) || ((gpio_bitmask
) & (gpio_bitmask
- 1))) {
3279 ASSERT((gpio_bitmask
) && !((gpio_bitmask
) & (gpio_bitmask
- 1)));
3283 /* already released */
3284 if (!(si_gpioreservation
& gpio_bitmask
))
3287 /* clear reservation */
3288 si_gpioreservation
&= ~gpio_bitmask
;
3290 return si_gpioreservation
;
3293 /* return the current gpioin register value */
3295 si_gpioin(si_t
*sih
)
3299 regoff
= OFFSETOF(chipcregs_t
, gpioin
);
3300 return (si_corereg(sih
, SI_CC_IDX
, regoff
, 0, 0));
3303 /* mask&set gpio interrupt polarity bits */
3305 si_gpiointpolarity(si_t
*sih
, uint32 mask
, uint32 val
, uint8 priority
)
3309 /* gpios could be shared on router platforms */
3310 if ((BUSTYPE(sih
->bustype
) == SI_BUS
) && (val
|| mask
)) {
3311 mask
= priority
? (si_gpioreservation
& mask
) :
3312 ((si_gpioreservation
| mask
) & ~(si_gpioreservation
));
3316 regoff
= OFFSETOF(chipcregs_t
, gpiointpolarity
);
3317 return (si_corereg(sih
, SI_CC_IDX
, regoff
, mask
, val
));
3320 /* mask&set gpio interrupt mask bits */
3322 si_gpiointmask(si_t
*sih
, uint32 mask
, uint32 val
, uint8 priority
)
3326 /* gpios could be shared on router platforms */
3327 if ((BUSTYPE(sih
->bustype
) == SI_BUS
) && (val
|| mask
)) {
3328 mask
= priority
? (si_gpioreservation
& mask
) :
3329 ((si_gpioreservation
| mask
) & ~(si_gpioreservation
));
3333 regoff
= OFFSETOF(chipcregs_t
, gpiointmask
);
3334 return (si_corereg(sih
, SI_CC_IDX
, regoff
, mask
, val
));
3337 /* assign the gpio to an led */
3339 si_gpioled(si_t
*sih
, uint32 mask
, uint32 val
)
3341 if (sih
->ccrev
< 16)
3344 /* gpio led powersave reg */
3345 return (si_corereg(sih
, SI_CC_IDX
, OFFSETOF(chipcregs_t
, gpiotimeroutmask
), mask
, val
));
3348 /* mask&set gpio timer val */
3350 si_gpiotimerval(si_t
*sih
, uint32 mask
, uint32 gpiotimerval
)
3352 if (sih
->ccrev
< 16)
3355 return (si_corereg(sih
, SI_CC_IDX
,
3356 OFFSETOF(chipcregs_t
, gpiotimerval
), mask
, gpiotimerval
));
3360 si_gpiopull(si_t
*sih
, bool updown
, uint32 mask
, uint32 val
)
3364 if (sih
->ccrev
< 20)
3367 offs
= (updown
? OFFSETOF(chipcregs_t
, gpiopulldown
) : OFFSETOF(chipcregs_t
, gpiopullup
));
3368 return (si_corereg(sih
, SI_CC_IDX
, offs
, mask
, val
));
3372 si_gpioevent(si_t
*sih
, uint regtype
, uint32 mask
, uint32 val
)
3376 if (sih
->ccrev
< 11)
3379 if (regtype
== GPIO_REGEVT
)
3380 offs
= OFFSETOF(chipcregs_t
, gpioevent
);
3381 else if (regtype
== GPIO_REGEVT_INTMSK
)
3382 offs
= OFFSETOF(chipcregs_t
, gpioeventintmask
);
3383 else if (regtype
== GPIO_REGEVT_INTPOL
)
3384 offs
= OFFSETOF(chipcregs_t
, gpioeventintpolarity
);
3388 return (si_corereg(sih
, SI_CC_IDX
, offs
, mask
, val
));
3392 BCMATTACHFN(si_gpio_handler_register
)(si_t
*sih
, uint32 event
,
3393 bool level
, gpio_handler_t cb
, void *arg
)
3402 if (sih
->ccrev
< 11)
3405 if ((gi
= MALLOC(sii
->osh
, sizeof(gpioh_item_t
))) == NULL
)
3408 bzero(gi
, sizeof(gpioh_item_t
));
3414 gi
->next
= sii
->gpioh_head
;
3415 sii
->gpioh_head
= gi
;
3419 gpioh_item_t
*h
= sii
->gpioh_head
;
3422 for (; h
; h
= h
->next
) {
3424 SI_ERROR(("gpiohdler=%p cb=%p event=0x%x\n",
3425 h
, h
->handler
, h
->event
));
3427 SI_ERROR(("gpiohdler total=%d\n", cnt
));
3430 return (void *)(gi
);
3434 BCMATTACHFN(si_gpio_handler_unregister
)(si_t
*sih
, void *gpioh
)
3437 gpioh_item_t
*p
, *n
;
3440 if (sih
->ccrev
< 11)
3443 ASSERT(sii
->gpioh_head
!= NULL
);
3444 if ((void*)sii
->gpioh_head
== gpioh
) {
3445 sii
->gpioh_head
= sii
->gpioh_head
->next
;
3446 MFREE(sii
->osh
, gpioh
, sizeof(gpioh_item_t
));
3449 p
= sii
->gpioh_head
;
3452 if ((void*)n
== gpioh
) {
3454 MFREE(sii
->osh
, gpioh
, sizeof(gpioh_item_t
));
3464 gpioh_item_t
*h
= sii
->gpioh_head
;
3467 for (; h
; h
= h
->next
) {
3469 SI_ERROR(("gpiohdler=%p cb=%p event=0x%x\n",
3470 h
, h
->handler
, h
->event
));
3472 SI_ERROR(("gpiohdler total=%d\n", cnt
));
3475 ASSERT(0); /* Not found in list */
3479 si_gpio_handler_process(si_t
*sih
)
3483 uint32 level
= si_gpioin(sih
);
3484 uint32 levelp
= si_gpiointpolarity(sih
, 0, 0, 0);
3485 uint32 edge
= si_gpioevent(sih
, GPIO_REGEVT
, 0, 0);
3486 uint32 edgep
= si_gpioevent(sih
, GPIO_REGEVT_INTPOL
, 0, 0);
3489 for (h
= sii
->gpioh_head
; h
!= NULL
; h
= h
->next
) {
3491 uint32 status
= (h
->level
? level
: edge
) & h
->event
;
3492 uint32 polarity
= (h
->level
? levelp
: edgep
) & h
->event
;
3494 /* polarity bitval is opposite of status bitval */
3495 if (status
^ polarity
)
3496 h
->handler(status
, h
->arg
);
3500 si_gpioevent(sih
, GPIO_REGEVT
, edge
, edge
); /* clear edge-trigger status */
3504 si_gpio_int_enable(si_t
*sih
, bool enable
)
3508 if (sih
->ccrev
< 11)
3511 offs
= OFFSETOF(chipcregs_t
, intmask
);
3512 return (si_corereg(sih
, SI_CC_IDX
, offs
, CI_GPIO
, (enable
? CI_GPIO
: 0)));
3516 /* Return the size of the specified SOCRAM bank */
3518 socram_banksize(si_info_t
*sii
, sbsocramregs_t
*regs
, uint8 idx
, uint8 mem_type
)
3520 uint banksize
, bankinfo
;
3521 uint bankidx
= idx
| (mem_type
<< SOCRAM_BANKIDX_MEMTYPE_SHIFT
);
3523 ASSERT(mem_type
<= SOCRAM_MEMTYPE_DEVRAM
);
3525 W_REG(sii
->osh
, ®s
->bankidx
, bankidx
);
3526 bankinfo
= R_REG(sii
->osh
, ®s
->bankinfo
);
3527 banksize
= SOCRAM_BANKINFO_SZBASE
* ((bankinfo
& SOCRAM_BANKINFO_SZMASK
) + 1);
3532 si_socdevram(si_t
*sih
, bool set
, uint8
*enable
, uint8
*protect
, uint8
*remap
)
3537 sbsocramregs_t
*regs
;
3543 /* Block ints and save current core */
3544 INTR_OFF(sii
, intr_val
);
3545 origidx
= si_coreidx(sih
);
3548 *enable
= *protect
= *remap
= 0;
3550 /* Switch to SOCRAM core */
3551 if (!(regs
= si_setcore(sih
, SOCRAM_CORE_ID
, 0)))
3554 /* Get info for determining size */
3555 if (!(wasup
= si_iscoreup(sih
)))
3556 si_core_reset(sih
, 0, 0);
3558 corerev
= si_corerev(sih
);
3559 if (corerev
>= 10) {
3563 uint32 bankidx
, bankinfo
;
3565 extcinfo
= R_REG(sii
->osh
, ®s
->extracoreinfo
);
3566 nb
= ((extcinfo
& SOCRAM_DEVRAMBANK_MASK
) >> SOCRAM_DEVRAMBANK_SHIFT
);
3567 for (i
= 0; i
< nb
; i
++) {
3568 bankidx
= i
| (SOCRAM_MEMTYPE_DEVRAM
<< SOCRAM_BANKIDX_MEMTYPE_SHIFT
);
3569 W_REG(sii
->osh
, ®s
->bankidx
, bankidx
);
3570 bankinfo
= R_REG(sii
->osh
, ®s
->bankinfo
);
3572 bankinfo
&= ~SOCRAM_BANKINFO_DEVRAMSEL_MASK
;
3573 bankinfo
&= ~SOCRAM_BANKINFO_DEVRAMPRO_MASK
;
3574 bankinfo
&= ~SOCRAM_BANKINFO_DEVRAMREMAP_MASK
;
3576 bankinfo
|= (1 << SOCRAM_BANKINFO_DEVRAMSEL_SHIFT
);
3578 bankinfo
|= (1 << SOCRAM_BANKINFO_DEVRAMPRO_SHIFT
);
3579 if ((corerev
>= 16) && *remap
)
3581 (1 << SOCRAM_BANKINFO_DEVRAMREMAP_SHIFT
);
3583 W_REG(sii
->osh
, ®s
->bankinfo
, bankinfo
);
3586 if (bankinfo
& SOCRAM_BANKINFO_DEVRAMSEL_MASK
) {
3588 if (bankinfo
& SOCRAM_BANKINFO_DEVRAMPRO_MASK
)
3590 if (bankinfo
& SOCRAM_BANKINFO_DEVRAMREMAP_MASK
)
3597 /* Return to previous state and core */
3599 si_core_disable(sih
, 0);
3600 si_setcoreidx(sih
, origidx
);
3603 INTR_RESTORE(sii
, intr_val
);
3607 si_socdevram_remap_isenb(si_t
*sih
)
3612 sbsocramregs_t
*regs
;
3613 bool wasup
, remap
= FALSE
;
3618 uint32 bankidx
, bankinfo
;
3622 /* Block ints and save current core */
3623 INTR_OFF(sii
, intr_val
);
3624 origidx
= si_coreidx(sih
);
3626 /* Switch to SOCRAM core */
3627 if (!(regs
= si_setcore(sih
, SOCRAM_CORE_ID
, 0)))
3630 /* Get info for determining size */
3631 if (!(wasup
= si_iscoreup(sih
)))
3632 si_core_reset(sih
, 0, 0);
3634 corerev
= si_corerev(sih
);
3635 if (corerev
>= 16) {
3636 extcinfo
= R_REG(sii
->osh
, ®s
->extracoreinfo
);
3637 nb
= ((extcinfo
& SOCRAM_DEVRAMBANK_MASK
) >> SOCRAM_DEVRAMBANK_SHIFT
);
3638 for (i
= 0; i
< nb
; i
++) {
3639 bankidx
= i
| (SOCRAM_MEMTYPE_DEVRAM
<< SOCRAM_BANKIDX_MEMTYPE_SHIFT
);
3640 W_REG(sii
->osh
, ®s
->bankidx
, bankidx
);
3641 bankinfo
= R_REG(sii
->osh
, ®s
->bankinfo
);
3642 if (bankinfo
& SOCRAM_BANKINFO_DEVRAMREMAP_MASK
) {
3649 /* Return to previous state and core */
3651 si_core_disable(sih
, 0);
3652 si_setcoreidx(sih
, origidx
);
3655 INTR_RESTORE(sii
, intr_val
);
3660 si_socdevram_pkg(si_t
*sih
)
3662 if (si_socdevram_size(sih
) > 0)
3669 si_socdevram_size(si_t
*sih
)
3675 sbsocramregs_t
*regs
;
3681 /* Block ints and save current core */
3682 INTR_OFF(sii
, intr_val
);
3683 origidx
= si_coreidx(sih
);
3685 /* Switch to SOCRAM core */
3686 if (!(regs
= si_setcore(sih
, SOCRAM_CORE_ID
, 0)))
3689 /* Get info for determining size */
3690 if (!(wasup
= si_iscoreup(sih
)))
3691 si_core_reset(sih
, 0, 0);
3693 corerev
= si_corerev(sih
);
3694 if (corerev
>= 10) {
3699 extcinfo
= R_REG(sii
->osh
, ®s
->extracoreinfo
);
3700 nb
= (((extcinfo
& SOCRAM_DEVRAMBANK_MASK
) >> SOCRAM_DEVRAMBANK_SHIFT
));
3701 for (i
= 0; i
< nb
; i
++)
3702 memsize
+= socram_banksize(sii
, regs
, i
, SOCRAM_MEMTYPE_DEVRAM
);
3705 /* Return to previous state and core */
3707 si_core_disable(sih
, 0);
3708 si_setcoreidx(sih
, origidx
);
3711 INTR_RESTORE(sii
, intr_val
);
3717 si_socdevram_remap_size(si_t
*sih
)
3722 uint32 memsize
= 0, banksz
;
3723 sbsocramregs_t
*regs
;
3729 uint32 bankidx
, bankinfo
;
3733 /* Block ints and save current core */
3734 INTR_OFF(sii
, intr_val
);
3735 origidx
= si_coreidx(sih
);
3737 /* Switch to SOCRAM core */
3738 if (!(regs
= si_setcore(sih
, SOCRAM_CORE_ID
, 0)))
3741 /* Get info for determining size */
3742 if (!(wasup
= si_iscoreup(sih
)))
3743 si_core_reset(sih
, 0, 0);
3745 corerev
= si_corerev(sih
);
3746 if (corerev
>= 16) {
3747 extcinfo
= R_REG(sii
->osh
, ®s
->extracoreinfo
);
3748 nb
= (((extcinfo
& SOCRAM_DEVRAMBANK_MASK
) >> SOCRAM_DEVRAMBANK_SHIFT
));
3751 * FIX: A0 Issue: Max addressable is 512KB, instead 640KB
3752 * Only four banks are accessible to ARM
3754 if ((corerev
== 16) && (nb
== 5))
3757 for (i
= 0; i
< nb
; i
++) {
3758 bankidx
= i
| (SOCRAM_MEMTYPE_DEVRAM
<< SOCRAM_BANKIDX_MEMTYPE_SHIFT
);
3759 W_REG(sii
->osh
, ®s
->bankidx
, bankidx
);
3760 bankinfo
= R_REG(sii
->osh
, ®s
->bankinfo
);
3761 if (bankinfo
& SOCRAM_BANKINFO_DEVRAMREMAP_MASK
) {
3762 banksz
= socram_banksize(sii
, regs
, i
, SOCRAM_MEMTYPE_DEVRAM
);
3765 /* Account only consecutive banks for now */
3771 /* Return to previous state and core */
3773 si_core_disable(sih
, 0);
3774 si_setcoreidx(sih
, origidx
);
3777 INTR_RESTORE(sii
, intr_val
);
3782 /* Return the RAM size of the SOCRAM core */
3784 si_socram_size(si_t
*sih
)
3790 sbsocramregs_t
*regs
;
3798 /* Block ints and save current core */
3799 INTR_OFF(sii
, intr_val
);
3800 origidx
= si_coreidx(sih
);
3802 /* Switch to SOCRAM core */
3803 if (!(regs
= si_setcore(sih
, SOCRAM_CORE_ID
, 0)))
3806 /* Get info for determining size */
3807 if (!(wasup
= si_iscoreup(sih
)))
3808 si_core_reset(sih
, 0, 0);
3809 corerev
= si_corerev(sih
);
3810 coreinfo
= R_REG(sii
->osh
, ®s
->coreinfo
);
3812 /* Calculate size from coreinfo based on rev */
3814 memsize
= 1 << (16 + (coreinfo
& SRCI_MS0_MASK
));
3815 else if (corerev
< 3) {
3816 memsize
= 1 << (SR_BSZ_BASE
+ (coreinfo
& SRCI_SRBSZ_MASK
));
3817 memsize
*= (coreinfo
& SRCI_SRNB_MASK
) >> SRCI_SRNB_SHIFT
;
3818 } else if ((corerev
<= 7) || (corerev
== 12)) {
3819 uint nb
= (coreinfo
& SRCI_SRNB_MASK
) >> SRCI_SRNB_SHIFT
;
3820 uint bsz
= (coreinfo
& SRCI_SRBSZ_MASK
);
3821 uint lss
= (coreinfo
& SRCI_LSS_MASK
) >> SRCI_LSS_SHIFT
;
3824 memsize
= nb
* (1 << (bsz
+ SR_BSZ_BASE
));
3826 memsize
+= (1 << ((lss
- 1) + SR_BSZ_BASE
));
3829 uint nb
= (coreinfo
& SRCI_SRNB_MASK
) >> SRCI_SRNB_SHIFT
;
3830 for (i
= 0; i
< nb
; i
++)
3831 memsize
+= socram_banksize(sii
, regs
, i
, SOCRAM_MEMTYPE_RAM
);
3834 /* Return to previous state and core */
3836 si_core_disable(sih
, 0);
3837 si_setcoreidx(sih
, origidx
);
3840 INTR_RESTORE(sii
, intr_val
);
3845 #if defined(WLOFFLD)
3847 /* Return the TCM-RAM size of the ARMCR4 core. */
3849 si_tcm_size(si_t
*sih
)
3863 uint32
*arm_cap_reg
;
3869 /* Block ints and save current core */
3870 INTR_OFF(sii
, intr_val
);
3871 origidx
= si_coreidx(sih
);
3873 /* Switch to CR4 core */
3874 if (!(regs
= si_setcore(sih
, ARMCR4_CORE_ID
, 0)))
3877 /* Get info for determining size. If in reset, come out of reset,
3878 * but remain in halt
3880 if (!(wasup
= si_iscoreup(sih
)))
3881 si_core_reset(sih
, SICF_CPUHALT
, SICF_CPUHALT
);
3883 arm_cap_reg
= (uint32
*)(regs
+ SI_CR4_CAP
);
3884 corecap
= R_REG(sii
->osh
, arm_cap_reg
);
3886 nab
= (corecap
& ARMCR4_TCBANB_MASK
) >> ARMCR4_TCBANB_SHIFT
;
3887 nbb
= (corecap
& ARMCR4_TCBBNB_MASK
) >> ARMCR4_TCBBNB_SHIFT
;
3890 arm_bidx
= (uint32
*)(regs
+ SI_CR4_BANKIDX
);
3891 arm_binfo
= (uint32
*)(regs
+ SI_CR4_BANKINFO
);
3892 for (idx
= 0; idx
< totb
; idx
++) {
3893 W_REG(sii
->osh
, arm_bidx
, idx
);
3895 bxinfo
= R_REG(sii
->osh
, arm_binfo
);
3896 memsize
+= ((bxinfo
& ARMCR4_BSZ_MASK
) + 1) * ARMCR4_BSZ_MULT
;
3899 /* Return to previous state and core */
3901 si_core_disable(sih
, 0);
3902 si_setcoreidx(sih
, origidx
);
3905 INTR_RESTORE(sii
, intr_val
);
3912 #define NOTIFY_BT_FM_DISABLE(sih, val) \
3913 si_eci_notify_bt((sih), ECI_OUT_FM_DISABLE_MASK(sih->ccrev), \
3914 ((val) << ECI_OUT_FM_DISABLE_SHIFT(sih->ccrev)), FALSE)
3916 /* Query OTP to see if FM is disabled */
3918 BCMINITFN(si_query_FMDisabled_from_OTP
)(si_t
*sih
, uint16
*FMDisabled
)
3920 int error
= BCME_OK
;
3925 /* Determine the bit for the chip */
3926 switch (CHIPID(sih
->chip
)) {
3927 case BCM4325_CHIP_ID
:
3928 if (CHIPREV(sih
->chiprev
) >= 6)
3929 bitoff
= OTP4325_FM_DISABLED_OFFSET
;
3935 /* If there is a bit for this chip, check it */
3937 if (!(wasup
= si_is_otp_powered(sih
))) {
3938 si_otp_power(sih
, TRUE
);
3941 if ((oh
= otp_init(sih
)) != NULL
)
3942 *FMDisabled
= !otp_read_bit(oh
, OTP4325_FM_DISABLED_OFFSET
);
3944 error
= BCME_NOTFOUND
;
3947 si_otp_power(sih
, FALSE
);
3957 return (!!(sih
->cccaps
& CC_CAP_ECI
));
3963 return (sih
->cccaps_ext
& CC_CAP_EXT_SECI_PRESENT
);
3966 /* ECI Init routine */
3968 BCMINITFN(si_eci_init
)(si_t
*sih
)
3974 uint16 FMDisabled
= FALSE
;
3976 /* check for ECI capability */
3977 if (!(sih
->cccaps
& CC_CAP_ECI
))
3981 fast
= SI_FAST(sii
);
3983 origidx
= sii
->curidx
;
3984 if ((cc
= (chipcregs_t
*)si_setcore(sih
, CC_CORE_ID
, 0)) == NULL
)
3986 } else if ((cc
= (chipcregs_t
*)CCREGS_FAST(sii
)) == NULL
)
3990 /* disable level based interrupts */
3991 if (sih
->ccrev
< 35) {
3992 W_REG(sii
->osh
, &cc
->eci
.lt35
.eci_intmaskhi
, 0x0);
3993 W_REG(sii
->osh
, &cc
->eci
.lt35
.eci_intmaskmi
, 0x0);
3994 W_REG(sii
->osh
, &cc
->eci
.lt35
.eci_intmasklo
, 0x0);
3997 W_REG(sii
->osh
, &cc
->eci
.ge35
.eci_intmaskhi
, 0x0);
3998 W_REG(sii
->osh
, &cc
->eci
.ge35
.eci_intmasklo
, 0x0);
4001 /* Assign eci_output bits between 'wl' and dot11mac */
4002 if (sih
->ccrev
< 35) {
4003 W_REG(sii
->osh
, &cc
->eci
.lt35
.eci_control
, ECI_MACCTRL_BITS
);
4006 W_REG(sii
->osh
, &cc
->eci
.ge35
.eci_controllo
, ECI_MACCTRLLO_BITS
);
4007 W_REG(sii
->osh
, &cc
->eci
.ge35
.eci_controlhi
, ECI_MACCTRLHI_BITS
);
4010 /* enable only edge based interrupts
4011 * only toggle on bit 62 triggers an interrupt
4013 if (sih
->ccrev
< 35) {
4014 W_REG(sii
->osh
, &cc
->eci
.lt35
.eci_eventmaskhi
, 0x0);
4015 W_REG(sii
->osh
, &cc
->eci
.lt35
.eci_eventmaskmi
, 0x0);
4016 W_REG(sii
->osh
, &cc
->eci
.lt35
.eci_eventmasklo
, 0x0);
4019 W_REG(sii
->osh
, &cc
->eci
.ge35
.eci_eventmaskhi
, 0x0);
4020 W_REG(sii
->osh
, &cc
->eci
.ge35
.eci_eventmasklo
, 0x0);
4023 /* restore previous core */
4025 si_setcoreidx(sih
, origidx
);
4027 /* if FM disabled in OTP, let BT know */
4028 if (!si_query_FMDisabled_from_OTP(sih
, &FMDisabled
)) {
4030 NOTIFY_BT_FM_DISABLE(sih
, 1);
4038 * Write values to BT on eci_output.
4041 si_eci_notify_bt(si_t
*sih
, uint32 mask
, uint32 val
, bool interrupt
)
4045 /* Nothing to do if there is no eci or seci */
4046 if (((sih
->cccaps
& CC_CAP_ECI
) == 0) && ((sih
->cccaps_ext
& CC_CAP_EXT_SECI_PRESENT
) == 0))
4049 /* Clear interrupt bit by default */
4051 si_corereg(sih
, SI_CC_IDX
,
4053 OFFSETOF(chipcregs_t
, eci
.lt35
.eci_output
) :
4054 OFFSETOF(chipcregs_t
, eci
.ge35
.eci_outputlo
)),
4057 if (sih
->ccrev
>= 35) {
4058 if ((mask
& 0xFFFF0000) == ECI48_OUT_MASKMAGIC_HIWORD
) {
4059 offset
= OFFSETOF(chipcregs_t
, eci
.ge35
.eci_outputhi
);
4060 mask
= mask
& ~0xFFFF0000;
4063 offset
= OFFSETOF(chipcregs_t
, eci
.ge35
.eci_outputlo
);
4064 mask
= mask
| (1<<30);
4065 val
= val
& ~(1 << 30);
4069 offset
= OFFSETOF(chipcregs_t
, eci
.lt35
.eci_output
);
4070 val
= val
& ~(1 << 30);
4073 si_corereg(sih
, SI_CC_IDX
, offset
, mask
, val
);
4075 /* Set interrupt bit if needed */
4077 si_corereg(sih
, SI_CC_IDX
,
4079 OFFSETOF(chipcregs_t
, eci
.lt35
.eci_output
) :
4080 OFFSETOF(chipcregs_t
, eci
.ge35
.eci_outputlo
)),
4081 (1 << 30), (1 << 30));
4084 /* seci clock enable/disable */
4086 si_seci_clkreq(si_t
*sih
, bool enable
)
4096 val
= CLKCTL_STS_SECI_CLK_REQ
;
4100 offset
= OFFSETOF(chipcregs_t
, clk_ctl_st
);
4102 si_corereg(sih
, SI_CC_IDX
, offset
, CLKCTL_STS_SECI_CLK_REQ
, val
);
4107 SPINWAIT(!(si_corereg(sih
, 0, offset
, 0, 0) & CLKCTL_STS_SECI_CLK_AVAIL
),
4108 PMU_MAX_TRANSITION_DLY
);
4110 clk_ctl_st
= si_corereg(sih
, 0, offset
, 0, 0);
4112 if (!(clk_ctl_st
& CLKCTL_STS_SECI_CLK_AVAIL
)) {
4113 SI_ERROR(("SECI clock is still not available\n"));
4120 BCMINITFN(si_seci_down
)(si_t
*sih
)
4132 fast
= SI_FAST(sii
);
4135 origidx
= sii
->curidx
;
4136 if ((cc
= (chipcregs_t
*)si_setcore(sih
, CC_CORE_ID
, 0)) == NULL
)
4138 } else if ((cc
= (chipcregs_t
*)CCREGS_FAST(sii
)) == NULL
)
4141 /* 4331 X28 sign off seci */
4142 if (CHIPID(sih
->chip
) == BCM4331_CHIP_ID
) {
4144 seci_conf
= R_REG(sii
->osh
, &cc
->SECI_config
);
4145 seci_conf
|= SECI_UPD_SECI
;
4146 W_REG(sii
->osh
, &cc
->SECI_config
, seci_conf
);
4147 SPINWAIT((R_REG(sii
->osh
, &cc
->SECI_config
) & SECI_UPD_SECI
), 1000);
4150 W_REG(sii
->osh
, &cc
->seci_uart_data
, SECI_SIGNOFF_0
);
4151 W_REG(sii
->osh
, &cc
->seci_uart_data
, SECI_SIGNOFF_1
);
4152 SPINWAIT((R_REG(sii
->osh
, &cc
->seci_uart_lsr
) & (1 << 2)), 1000);
4153 /* put seci in reset */
4154 seci_conf
= R_REG(sii
->osh
, &cc
->SECI_config
);
4155 seci_conf
&= ~SECI_ENAB_SECI_ECI
;
4156 W_REG(sii
->osh
, &cc
->SECI_config
, seci_conf
);
4157 seci_conf
|= SECI_RESET
;
4158 W_REG(sii
->osh
, &cc
->SECI_config
, seci_conf
);
4161 /* bring down the clock if up */
4162 si_seci_clkreq(sih
, FALSE
);
4164 /* restore previous core */
4166 si_setcoreidx(sih
, origidx
);
4170 si_seci_upd(si_t
*sih
, bool enable
)
4183 fast
= SI_FAST(sii
);
4184 INTR_OFF(sii
, intr_val
);
4186 origidx
= sii
->curidx
;
4187 if ((cc
= (chipcregs_t
*)si_setcore(sih
, CC_CORE_ID
, 0)) == NULL
)
4189 } else if ((cc
= (chipcregs_t
*)CCREGS_FAST(sii
)) == NULL
)
4194 /* 4331 Select SECI based on enable input */
4195 if (CHIPID(sih
->chip
) == BCM4331_CHIP_ID
) {
4196 regval
= R_REG(sii
->osh
, &cc
->chipcontrol
);
4198 regval
|= CCTRL4331_SECI
;
4200 regval
&= ~CCTRL4331_SECI
;
4201 W_REG(sii
->osh
, &cc
->chipcontrol
, regval
);
4204 /* restore previous core */
4206 si_setcoreidx(sih
, origidx
);
4208 INTR_RESTORE(sii
, intr_val
);
4211 /* SECI Init routine, pass in seci_mode */
4213 BCMINITFN(si_seci_init
)(si_t
*sih
, uint8 seci_mode
)
4224 if (sih
->ccrev
< 35)
4230 if (seci_mode
> SECI_MODE_MASK
)
4234 fast
= SI_FAST(sii
);
4236 origidx
= sii
->curidx
;
4237 if ((ptr
= si_setcore(sih
, CC_CORE_ID
, 0)) == NULL
)
4239 } else if ((ptr
= CCREGS_FAST(sii
)) == NULL
)
4241 cc
= (chipcregs_t
*)ptr
;
4245 /* 43236 (ccrev 36) muxes SECI on JTAG pins. Select SECI. */
4246 if (CHIPID(sih
->chip
) == BCM43236_CHIP_ID
||
4247 CHIPID(sih
->chip
) == BCM4331_CHIP_ID
) {
4248 regval
= R_REG(sii
->osh
, &cc
->chipcontrol
);
4249 regval
|= CCTRL4331_SECI
;
4250 W_REG(sii
->osh
, &cc
->chipcontrol
, regval
);
4253 /* 43143 (ccrev 43) mux SECI on JTAG pins. Select SECI. */
4254 if (CHIPID(sih
->chip
) == BCM43143_CHIP_ID
) {
4255 regval
= R_REG(sii
->osh
, &cc
->chipcontrol
);
4256 regval
&= ~(CCTRL_43143_SECI
| CCTRL_43143_BT_LEGACY
);
4257 switch (seci_mode
) {
4258 case SECI_MODE_LEGACY_3WIRE_WLAN
:
4259 regval
|= CCTRL_43143_BT_LEGACY
;
4261 case SECI_MODE_SECI
:
4262 regval
|= CCTRL_43143_SECI
;
4267 W_REG(sii
->osh
, &cc
->chipcontrol
, regval
);
4270 if ((CHIPID(sih
->chip
) == BCM43236_CHIP_ID
) ||
4271 (CHIPID(sih
->chip
) == BCM43143_CHIP_ID
)) {
4272 regval
= R_REG(sii
->osh
, &cc
->jtagctrl
);
4274 W_REG(sii
->osh
, &cc
->jtagctrl
, regval
);
4277 /* enable SECI clock */
4278 si_seci_clkreq(sih
, TRUE
);
4280 /* put the SECI in reset */
4281 seci_conf
= R_REG(sii
->osh
, &cc
->SECI_config
);
4282 seci_conf
&= ~SECI_ENAB_SECI_ECI
;
4283 W_REG(sii
->osh
, &cc
->SECI_config
, seci_conf
);
4284 seci_conf
= SECI_RESET
;
4285 W_REG(sii
->osh
, &cc
->SECI_config
, seci_conf
);
4287 /* set force-low, and set EN_SECI for all non-legacy modes */
4288 seci_conf
|= SECI_ENAB_SECIOUT_DIS
;
4289 if ((seci_mode
== SECI_MODE_UART
) || (seci_mode
== SECI_MODE_SECI
) ||
4290 (seci_mode
== SECI_MODE_HALF_SECI
))
4292 seci_conf
|= SECI_ENAB_SECI_ECI
;
4294 W_REG(sii
->osh
, &cc
->SECI_config
, seci_conf
);
4296 /* take seci out of reset */
4297 seci_conf
= R_REG(sii
->osh
, &cc
->SECI_config
);
4298 seci_conf
&= ~(SECI_RESET
);
4299 W_REG(sii
->osh
, &cc
->SECI_config
, seci_conf
);
4301 /* set UART/SECI baud rate */
4302 /* hard-coded at 4MBaud for now */
4303 if ((seci_mode
== SECI_MODE_UART
) || (seci_mode
== SECI_MODE_SECI
) ||
4304 (seci_mode
== SECI_MODE_HALF_SECI
)) {
4305 if ((CHIPID(sih
->chip
) == BCM43236_CHIP_ID
) ||
4306 (CHIPID(sih
->chip
) == BCM4331_CHIP_ID
) ||
4307 (CHIPID(sih
->chip
) == BCM43143_CHIP_ID
)) {
4308 /* 43236 ccrev = 36 and MAC clk = 96MHz */
4309 /* 4331,43143 MAC clk = 96MHz */
4310 offset
= OFFSETOF(chipcregs_t
, seci_uart_bauddiv
);
4311 si_corereg(sih
, SI_CC_IDX
, offset
, 0xFF, 0xFF);
4312 offset
= OFFSETOF(chipcregs_t
, seci_uart_baudadj
);
4313 si_corereg(sih
, SI_CC_IDX
, offset
, 0xFF, 0x44);
4315 else if ((CHIPID(sih
->chip
) == BCM4360_CHIP_ID
) ||
4316 (CHIPID(sih
->chip
) == BCM4352_CHIP_ID
)) {
4317 /* MAC clk is 160MHz */
4318 offset
= OFFSETOF(chipcregs_t
, seci_uart_bauddiv
);
4319 si_corereg(sih
, SI_CC_IDX
, offset
, 0xFF, 0xFE);
4320 offset
= OFFSETOF(chipcregs_t
, seci_uart_baudadj
);
4321 si_corereg(sih
, SI_CC_IDX
, offset
, 0xFF, 0x44);
4324 /* 4336 MAC clk is 80MHz */
4325 offset
= OFFSETOF(chipcregs_t
, seci_uart_bauddiv
);
4326 si_corereg(sih
, SI_CC_IDX
, offset
, 0xFF, 0xFF);
4327 offset
= OFFSETOF(chipcregs_t
, seci_uart_baudadj
);
4328 si_corereg(sih
, SI_CC_IDX
, offset
, 0xFF, 0x22);
4331 /* LCR/MCR settings */
4332 offset
= OFFSETOF(chipcregs_t
, seci_uart_lcr
);
4333 si_corereg(sih
, SI_CC_IDX
, offset
, 0xFF,
4334 (SECI_UART_LCR_RX_EN
| SECI_UART_LCR_TXO_EN
)); /* 0x28 */
4335 offset
= OFFSETOF(chipcregs_t
, seci_uart_mcr
);
4336 si_corereg(sih
, SI_CC_IDX
, offset
,
4337 0xFF, (SECI_UART_MCR_TX_EN
| SECI_UART_MCR_BAUD_ADJ_EN
)); /* 0x81 */
4339 /* Give control of ECI output regs to MAC core */
4340 offset
= OFFSETOF(chipcregs_t
, eci
.ge35
.eci_controllo
);
4341 si_corereg(sih
, SI_CC_IDX
, offset
, 0xFFFFFFFF, ECI_MACCTRLLO_BITS
);
4342 offset
= OFFSETOF(chipcregs_t
, eci
.ge35
.eci_controlhi
);
4343 si_corereg(sih
, SI_CC_IDX
, offset
, 0xFFFF, ECI_MACCTRLHI_BITS
);
4346 /* set the seci mode in seci conf register */
4347 seci_conf
= R_REG(sii
->osh
, &cc
->SECI_config
);
4348 seci_conf
&= ~(SECI_MODE_MASK
<< SECI_MODE_SHIFT
);
4349 seci_conf
|= (seci_mode
<< SECI_MODE_SHIFT
);
4350 W_REG(sii
->osh
, &cc
->SECI_config
, seci_conf
);
4352 /* Clear force-low bit */
4353 seci_conf
= R_REG(sii
->osh
, &cc
->SECI_config
);
4354 seci_conf
&= ~SECI_ENAB_SECIOUT_DIS
;
4355 W_REG(sii
->osh
, &cc
->SECI_config
, seci_conf
);
4357 /* restore previous core */
4359 si_setcoreidx(sih
, origidx
);
4363 #endif /* BCMECICOEX */
4365 #if !defined(_CFE_) || defined(CFG_WL)
4367 si_btcgpiowar(si_t
*sih
)
4376 /* Make sure that there is ChipCommon core present &&
4377 * UART_TX is strapped to 1
4379 if (!(sih
->cccaps
& CC_CAP_UARTGPIO
))
4382 /* si_corereg cannot be used as we have to guarantee 8-bit read/writes */
4383 INTR_OFF(sii
, intr_val
);
4385 origidx
= si_coreidx(sih
);
4387 cc
= (chipcregs_t
*)si_setcore(sih
, CC_CORE_ID
, 0);
4390 W_REG(sii
->osh
, &cc
->uart0mcr
, R_REG(sii
->osh
, &cc
->uart0mcr
) | 0x04);
4392 /* restore the original index */
4393 si_setcoreidx(sih
, origidx
);
4395 INTR_RESTORE(sii
, intr_val
);
4399 si_chipcontrl_btshd0_4331(si_t
*sih
, bool on
)
4409 INTR_OFF(sii
, intr_val
);
4411 origidx
= si_coreidx(sih
);
4413 cc
= (chipcregs_t
*)si_setcore(sih
, CC_CORE_ID
, 0);
4415 val
= R_REG(sii
->osh
, &cc
->chipcontrol
);
4417 /* bt_shd0 controls are same for 4331 chiprevs 0 and 1, packages 12x9 and 12x12 */
4419 /* Enable bt_shd0 on gpio4: */
4420 val
|= (CCTRL4331_BT_SHD0_ON_GPIO4
);
4421 W_REG(sii
->osh
, &cc
->chipcontrol
, val
);
4423 val
&= ~(CCTRL4331_BT_SHD0_ON_GPIO4
);
4424 W_REG(sii
->osh
, &cc
->chipcontrol
, val
);
4427 /* restore the original index */
4428 si_setcoreidx(sih
, origidx
);
4430 INTR_RESTORE(sii
, intr_val
);
4434 si_chipcontrl_restore(si_t
*sih
, uint32 val
)
4441 origidx
= si_coreidx(sih
);
4442 cc
= (chipcregs_t
*)si_setcore(sih
, CC_CORE_ID
, 0);
4443 W_REG(sii
->osh
, &cc
->chipcontrol
, val
);
4444 si_setcoreidx(sih
, origidx
);
4448 si_chipcontrl_read(si_t
*sih
)
4456 origidx
= si_coreidx(sih
);
4457 cc
= (chipcregs_t
*)si_setcore(sih
, CC_CORE_ID
, 0);
4458 val
= R_REG(sii
->osh
, &cc
->chipcontrol
);
4459 si_setcoreidx(sih
, origidx
);
4464 si_chipcontrl_epa4331(si_t
*sih
, bool on
)
4472 origidx
= si_coreidx(sih
);
4474 cc
= (chipcregs_t
*)si_setcore(sih
, CC_CORE_ID
, 0);
4476 val
= R_REG(sii
->osh
, &cc
->chipcontrol
);
4479 if (sih
->chippkg
== 9 || sih
->chippkg
== 0xb) {
4480 val
|= (CCTRL4331_EXTPA_EN
| CCTRL4331_EXTPA_ON_GPIO2_5
);
4481 /* Ext PA Controls for 4331 12x9 Package */
4482 W_REG(sii
->osh
, &cc
->chipcontrol
, val
);
4484 /* Ext PA Controls for 4331 12x12 Package */
4485 if (sih
->chiprev
> 0) {
4486 W_REG(sii
->osh
, &cc
->chipcontrol
, val
|
4487 (CCTRL4331_EXTPA_EN
) | (CCTRL4331_EXTPA_EN2
));
4489 W_REG(sii
->osh
, &cc
->chipcontrol
, val
| (CCTRL4331_EXTPA_EN
));
4493 val
&= ~(CCTRL4331_EXTPA_EN
| CCTRL4331_EXTPA_EN2
| CCTRL4331_EXTPA_ON_GPIO2_5
);
4494 W_REG(sii
->osh
, &cc
->chipcontrol
, val
);
4497 si_setcoreidx(sih
, origidx
);
4500 /* switch muxed pins, on: SROM, off: FEMCTRL */
4502 si_chipcontrl_srom4360(si_t
*sih
, bool on
)
4510 origidx
= si_coreidx(sih
);
4512 cc
= (chipcregs_t
*)si_setcore(sih
, CC_CORE_ID
, 0);
4514 val
= R_REG(sii
->osh
, &cc
->chipcontrol
);
4517 val
&= ~(CCTRL4360_SECI_MODE
|
4518 CCTRL4360_BTSWCTRL_MODE
|
4519 CCTRL4360_EXTRA_FEMCTRL_MODE
|
4520 CCTRL4360_BT_LGCY_MODE
|
4521 CCTRL4360_CORE2FEMCTRL4_ON
);
4523 W_REG(sii
->osh
, &cc
->chipcontrol
, val
);
4527 si_setcoreidx(sih
, origidx
);
4531 si_chipcontrl_epa4331_wowl(si_t
*sih
, bool enter_wowl
)
4539 sel_chip
= (CHIPID(sih
->chip
) == BCM4331_CHIP_ID
) ||
4540 (CHIPID(sih
->chip
) == BCM43431_CHIP_ID
);
4541 sel_chip
&= ((sih
->chippkg
== 9 || sih
->chippkg
== 0xb));
4547 origidx
= si_coreidx(sih
);
4549 cc
= (chipcregs_t
*)si_setcore(sih
, CC_CORE_ID
, 0);
4551 val
= R_REG(sii
->osh
, &cc
->chipcontrol
);
4554 val
|= CCTRL4331_EXTPA_EN
;
4555 W_REG(sii
->osh
, &cc
->chipcontrol
, val
);
4557 val
|= (CCTRL4331_EXTPA_EN
| CCTRL4331_EXTPA_ON_GPIO2_5
);
4558 W_REG(sii
->osh
, &cc
->chipcontrol
, val
);
4560 si_setcoreidx(sih
, origidx
);
4562 #endif /* !_CFE_ || CFG_WL */
4565 si_pll_reset(si_t
*sih
)
4572 INTR_OFF(sii
, intr_val
);
4573 err
= si_pll_minresmask_reset(sih
, sii
->osh
);
4574 INTR_RESTORE(sii
, intr_val
);
4578 /* Enable BT-COEX & Ex-PA for 4313 */
4580 si_epa_4313war(si_t
*sih
)
4587 origidx
= si_coreidx(sih
);
4589 cc
= (chipcregs_t
*)si_setcore(sih
, CC_CORE_ID
, 0);
4592 W_REG(sii
->osh
, &cc
->gpiocontrol
,
4593 R_REG(sii
->osh
, &cc
->gpiocontrol
) | GPIO_CTRL_EPA_EN_MASK
);
4595 si_setcoreidx(sih
, origidx
);
4599 si_clk_pmu_htavail_set(si_t
*sih
, bool set_clear
)
4604 si_pmu_minresmask_htavail_set(sih
, sii
->osh
, set_clear
);
4607 /* WL/BT control for 4313 btcombo boards >= P250 */
4609 si_btcombo_p250_4313_war(si_t
*sih
)
4616 origidx
= si_coreidx(sih
);
4618 cc
= (chipcregs_t
*)si_setcore(sih
, CC_CORE_ID
, 0);
4619 W_REG(sii
->osh
, &cc
->gpiocontrol
,
4620 R_REG(sii
->osh
, &cc
->gpiocontrol
) | GPIO_CTRL_5_6_EN_MASK
);
4622 W_REG(sii
->osh
, &cc
->gpioouten
,
4623 R_REG(sii
->osh
, &cc
->gpioouten
) | GPIO_CTRL_5_6_EN_MASK
);
4625 si_setcoreidx(sih
, origidx
);
4628 si_btc_enable_chipcontrol(si_t
*sih
)
4635 origidx
= si_coreidx(sih
);
4637 cc
= (chipcregs_t
*)si_setcore(sih
, CC_CORE_ID
, 0);
4640 W_REG(sii
->osh
, &cc
->chipcontrol
,
4641 R_REG(sii
->osh
, &cc
->chipcontrol
) | CC_BTCOEX_EN_MASK
);
4643 si_setcoreidx(sih
, origidx
);
4646 si_btcombo_43228_war(si_t
*sih
)
4653 origidx
= si_coreidx(sih
);
4655 cc
= (chipcregs_t
*)si_setcore(sih
, CC_CORE_ID
, 0);
4657 W_REG(sii
->osh
, &cc
->gpioouten
, GPIO_CTRL_7_6_EN_MASK
);
4658 W_REG(sii
->osh
, &cc
->gpioout
, GPIO_OUT_7_EN_MASK
);
4660 si_setcoreidx(sih
, origidx
);
4663 /* check if the device is removed */
4665 si_deviceremoved(si_t
*sih
)
4672 switch (BUSTYPE(sih
->bustype
)) {
4674 ASSERT(sii
->osh
!= NULL
);
4675 w
= OSL_PCI_READ_CONFIG(sii
->osh
, PCI_CFG_VID
, sizeof(uint32
));
4676 if ((w
& 0xFFFF) != VENDOR_BROADCOM
)
4684 si_is_sprom_available(si_t
*sih
)
4686 if (sih
->ccrev
>= 31) {
4692 if ((sih
->cccaps
& CC_CAP_SROM
) == 0)
4696 origidx
= sii
->curidx
;
4697 cc
= si_setcoreidx(sih
, SI_CC_IDX
);
4698 sromctrl
= R_REG(sii
->osh
, &cc
->sromcontrol
);
4699 si_setcoreidx(sih
, origidx
);
4700 return (sromctrl
& SRC_PRESENT
);
4703 switch (CHIPID(sih
->chip
)) {
4704 case BCM4312_CHIP_ID
:
4705 return ((sih
->chipst
& CST4312_SPROM_OTP_SEL_MASK
) != CST4312_OTP_SEL
);
4706 case BCM4325_CHIP_ID
:
4707 return (sih
->chipst
& CST4325_SPROM_SEL
) != 0;
4708 case BCM4322_CHIP_ID
: case BCM43221_CHIP_ID
: case BCM43231_CHIP_ID
:
4709 case BCM43222_CHIP_ID
: case BCM43111_CHIP_ID
: case BCM43112_CHIP_ID
:
4710 case BCM4342_CHIP_ID
: {
4712 spromotp
= (sih
->chipst
& CST4322_SPROM_OTP_SEL_MASK
) >>
4713 CST4322_SPROM_OTP_SEL_SHIFT
;
4714 return (spromotp
& CST4322_SPROM_PRESENT
) != 0;
4716 case BCM4329_CHIP_ID
:
4717 return (sih
->chipst
& CST4329_SPROM_SEL
) != 0;
4718 case BCM4315_CHIP_ID
:
4719 return (sih
->chipst
& CST4315_SPROM_SEL
) != 0;
4720 case BCM4319_CHIP_ID
:
4721 return (sih
->chipst
& CST4319_SPROM_SEL
) != 0;
4722 case BCM4336_CHIP_ID
:
4723 case BCM43362_CHIP_ID
:
4724 return (sih
->chipst
& CST4336_SPROM_PRESENT
) != 0;
4725 case BCM4330_CHIP_ID
:
4726 return (sih
->chipst
& CST4330_SPROM_PRESENT
) != 0;
4727 case BCM4313_CHIP_ID
:
4728 return (sih
->chipst
& CST4313_SPROM_PRESENT
) != 0;
4729 case BCM4331_CHIP_ID
:
4730 case BCM43431_CHIP_ID
:
4731 return (sih
->chipst
& CST4331_SPROM_PRESENT
) != 0;
4732 case BCM43239_CHIP_ID
:
4733 return ((sih
->chipst
& CST43239_SPROM_MASK
) &&
4734 !(sih
->chipst
& CST43239_SFLASH_MASK
));
4735 case BCM4324_CHIP_ID
:
4736 case BCM43242_CHIP_ID
:
4737 return ((sih
->chipst
& CST4324_SPROM_MASK
) &&
4738 !(sih
->chipst
& CST4324_SFLASH_MASK
));
4739 case BCM4335_CHIP_ID
:
4740 return ((sih
->chipst
& CST4335_SPROM_MASK
) &&
4741 !(sih
->chipst
& CST4335_SFLASH_MASK
));
4742 case BCM43131_CHIP_ID
:
4743 case BCM43217_CHIP_ID
:
4744 case BCM43227_CHIP_ID
:
4745 case BCM43228_CHIP_ID
:
4746 case BCM43428_CHIP_ID
:
4747 return (sih
->chipst
& CST43228_OTP_PRESENT
) != CST43228_OTP_PRESENT
;
4754 si_is_otp_disabled(si_t
*sih
)
4756 switch (CHIPID(sih
->chip
)) {
4757 case BCM4325_CHIP_ID
:
4758 return (sih
->chipst
& CST4325_SPROM_OTP_SEL_MASK
) == CST4325_OTP_PWRDN
;
4759 case BCM4322_CHIP_ID
:
4760 case BCM43221_CHIP_ID
:
4761 case BCM43231_CHIP_ID
:
4762 case BCM4342_CHIP_ID
:
4763 return (((sih
->chipst
& CST4322_SPROM_OTP_SEL_MASK
) >>
4764 CST4322_SPROM_OTP_SEL_SHIFT
) & CST4322_OTP_PRESENT
) !=
4765 CST4322_OTP_PRESENT
;
4766 case BCM4329_CHIP_ID
:
4767 return (sih
->chipst
& CST4329_SPROM_OTP_SEL_MASK
) == CST4329_OTP_PWRDN
;
4768 case BCM4315_CHIP_ID
:
4769 return (sih
->chipst
& CST4315_SPROM_OTP_SEL_MASK
) == CST4315_OTP_PWRDN
;
4770 case BCM4319_CHIP_ID
:
4771 return (sih
->chipst
& CST4319_SPROM_OTP_SEL_MASK
) == CST4319_OTP_PWRDN
;
4772 case BCM4336_CHIP_ID
:
4773 case BCM43362_CHIP_ID
:
4774 return ((sih
->chipst
& CST4336_OTP_PRESENT
) == 0);
4775 case BCM4330_CHIP_ID
:
4776 return ((sih
->chipst
& CST4330_OTP_PRESENT
) == 0);
4777 case BCM43237_CHIP_ID
:
4779 case BCM4313_CHIP_ID
:
4780 return (sih
->chipst
& CST4313_OTP_PRESENT
) == 0;
4781 case BCM4331_CHIP_ID
:
4782 return (sih
->chipst
& CST4331_OTP_PRESENT
) != CST4331_OTP_PRESENT
;
4783 case BCM4360_CHIP_ID
:
4784 case BCM43526_CHIP_ID
:
4785 case BCM43460_CHIP_ID
:
4786 case BCM4352_CHIP_ID
:
4787 /* 4360 OTP is always powered and enabled */
4789 /* These chips always have their OTP on */
4790 case BCM43111_CHIP_ID
: case BCM43112_CHIP_ID
: case BCM43222_CHIP_ID
:
4791 case BCM43224_CHIP_ID
: case BCM43225_CHIP_ID
:
4792 case BCM43421_CHIP_ID
:
4793 case BCM43226_CHIP_ID
:
4794 case BCM43235_CHIP_ID
: case BCM43236_CHIP_ID
: case BCM43238_CHIP_ID
:
4795 case BCM43234_CHIP_ID
: case BCM43239_CHIP_ID
: case BCM4324_CHIP_ID
:
4796 case BCM43431_CHIP_ID
:
4797 case BCM43131_CHIP_ID
:
4798 case BCM43217_CHIP_ID
:
4799 case BCM43227_CHIP_ID
:
4800 case BCM43228_CHIP_ID
:
4801 case BCM43428_CHIP_ID
: case BCM4335_CHIP_ID
:
4802 case BCM43143_CHIP_ID
:
4803 case BCM43242_CHIP_ID
:
4804 case BCM43243_CHIP_ID
:
4811 si_is_otp_powered(si_t
*sih
)
4813 if (PMUCTL_ENAB(sih
))
4814 return si_pmu_is_otp_powered(sih
, si_osh(sih
));
4819 si_otp_power(si_t
*sih
, bool on
)
4821 if (PMUCTL_ENAB(sih
))
4822 si_pmu_otp_power(sih
, si_osh(sih
), on
);
4827 #if defined(BCMDBG) || defined(WLTEST) || defined(BCMDBG_ERR)
4828 si_is_sprom_enabled(si_t
*sih
)
4830 BCMATTACHFN(si_is_sprom_enabled
)(si_t
*sih
)
4833 if (PMUCTL_ENAB(sih
))
4834 return si_pmu_is_sprom_enabled(sih
, si_osh(sih
));
4839 #if defined(BCMDBG) || defined(WLTEST) || defined(BCMDBG_ERR)
4840 si_sprom_enable(si_t
*sih
, bool enable
)
4842 BCMATTACHFN(si_sprom_enable
)(si_t
*sih
, bool enable
)
4845 if (PMUCTL_ENAB(sih
))
4846 si_pmu_sprom_enable(sih
, si_osh(sih
), enable
);
4849 /* Return BCME_NOTFOUND if the card doesn't have CIS format nvram */
4851 si_cis_source(si_t
*sih
)
4853 /* Many chips have the same mapping of their chipstatus field */
4854 static const uint cis_sel
[] = { CIS_DEFAULT
, CIS_SROM
, CIS_OTP
, CIS_SROM
};
4855 static const uint cis_43236_sel
[] = { CIS_DEFAULT
, CIS_OTP
};
4857 /* PCI chips use SROM format instead of CIS */
4858 if (BUSTYPE(sih
->bustype
) == PCI_BUS
)
4859 return BCME_NOTFOUND
;
4861 switch (CHIPID(sih
->chip
)) {
4862 case BCM4325_CHIP_ID
:
4863 return ((sih
->chipst
& CST4325_SPROM_OTP_SEL_MASK
) >= ARRAYSIZE(cis_sel
)) ?
4864 CIS_DEFAULT
: cis_sel
[(sih
->chipst
& CST4325_SPROM_OTP_SEL_MASK
)];
4865 case BCM4322_CHIP_ID
: case BCM43221_CHIP_ID
: case BCM43231_CHIP_ID
:
4866 case BCM4342_CHIP_ID
: {
4867 uint8 strap
= (sih
->chipst
& CST4322_SPROM_OTP_SEL_MASK
) >>
4868 CST4322_SPROM_OTP_SEL_SHIFT
;
4870 return ((strap
>= ARRAYSIZE(cis_sel
)) ? CIS_DEFAULT
: cis_sel
[strap
]);
4874 case BCM43235_CHIP_ID
: case BCM43236_CHIP_ID
: case BCM43238_CHIP_ID
:
4875 case BCM43234_CHIP_ID
: {
4876 uint8 strap
= (sih
->chipst
& CST43236_OTP_SEL_MASK
) >>
4877 CST43236_OTP_SEL_SHIFT
;
4878 return ((strap
>= ARRAYSIZE(cis_43236_sel
)) ? CIS_DEFAULT
: cis_43236_sel
[strap
]);
4881 case BCM4329_CHIP_ID
:
4882 return ((sih
->chipst
& CST4329_SPROM_OTP_SEL_MASK
) >= ARRAYSIZE(cis_sel
)) ?
4883 CIS_DEFAULT
: cis_sel
[(sih
->chipst
& CST4329_SPROM_OTP_SEL_MASK
)];
4885 case BCM4315_CHIP_ID
:
4887 return ((sih
->chipst
& CST4315_SPROM_OTP_SEL_MASK
) >= ARRAYSIZE(cis_sel
)) ?
4888 CIS_DEFAULT
: cis_sel
[(sih
->chipst
& CST4315_SPROM_OTP_SEL_MASK
)];
4890 case BCM4319_CHIP_ID
: {
4891 uint cis_sel4319
= ((sih
->chipst
& CST4319_SPROM_OTP_SEL_MASK
) >>
4892 CST4319_SPROM_OTP_SEL_SHIFT
);
4893 return (cis_sel4319
>= ARRAYSIZE(cis_sel
)) ? CIS_DEFAULT
: cis_sel
[cis_sel4319
];
4895 case BCM4336_CHIP_ID
:
4896 case BCM43362_CHIP_ID
: {
4897 if (sih
->chipst
& CST4336_SPROM_PRESENT
)
4899 if (sih
->chipst
& CST4336_OTP_PRESENT
)
4903 case BCM4330_CHIP_ID
: {
4904 if (sih
->chipst
& CST4330_SPROM_PRESENT
)
4906 if (sih
->chipst
& CST4330_OTP_PRESENT
)
4910 case BCM43239_CHIP_ID
: {
4911 if ((sih
->chipst
& CST43239_SPROM_MASK
) && !(sih
->chipst
& CST43239_SFLASH_MASK
))
4915 case BCM4324_CHIP_ID
:
4917 if ((sih
->chipst
& CST4324_SPROM_MASK
) && !(sih
->chipst
& CST4324_SFLASH_MASK
))
4921 case BCM4335_CHIP_ID
:
4923 if ((sih
->chipst
& CST4335_SPROM_MASK
) && !(sih
->chipst
& CST4335_SFLASH_MASK
))
4927 case BCM43237_CHIP_ID
: {
4928 uint8 strap
= (sih
->chipst
& CST43237_OTP_SEL_MASK
) >>
4929 CST43237_OTP_SEL_SHIFT
;
4930 return ((strap
>= ARRAYSIZE(cis_43236_sel
)) ? CIS_DEFAULT
: cis_43236_sel
[strap
]);
4932 case BCM43143_CHIP_ID
: {
4933 return CIS_OTP
; /* BCM43143 does not support SROM nor OTP strappings */
4935 case BCM43242_CHIP_ID
:
4936 case BCM43243_CHIP_ID
:
4938 return CIS_OTP
; /* BCM43242 does not support SPROM */
4940 case BCM4360_CHIP_ID
:
4941 case BCM4352_CHIP_ID
:
4942 case BCM43526_CHIP_ID
: {
4943 if ((sih
->chipst
& CST4360_OTP_ENABLED
))
4952 /* Read/write to OTP to find the FAB manf */
4954 BCMINITFN(si_otp_fabid
)(si_t
*sih
, uint16
*fabid
, bool rw
)
4956 int error
= BCME_OK
;
4958 uint16 data
, mask
= 0, shift
= 0;
4960 switch (CHIPID(sih
->chip
)) {
4961 case BCM4329_CHIP_ID
:
4962 /* Bit locations 133-130 */
4963 if (sih
->chiprev
>= 3) {
4969 case BCM43362_CHIP_ID
:
4970 /* Bit locations 134-130 */
4975 case BCM5356_CHIP_ID
:
4976 /* Bit locations 133-130 */
4988 error
= otp_read_word(sih
, offset
, &data
);
4990 *fabid
= (data
& mask
) >> shift
;
4993 data
= (data
<< shift
) & mask
;
4995 error
= otp_write_word(sih
, offset
, data
);
4996 #endif /* BCMNVRAMW */
5001 uint16
BCMINITFN(si_fabid
)(si_t
*sih
)
5006 switch (CHIPID(sih
->chip
)) {
5007 case BCM4329_CHIP_ID
:
5008 case BCM43362_CHIP_ID
:
5009 case BCM5356_CHIP_ID
:
5010 if (si_otp_fabid(sih
, &fabid
, TRUE
) != BCME_OK
)
5012 SI_ERROR(("si_fabid: reading fabid from otp failed.\n"));
5016 case BCM4330_CHIP_ID
:
5017 data
= si_corereg(sih
, SI_CC_IDX
, OFFSETOF(chipcregs_t
, chipcontrol
),
5019 fabid
= ((data
& 0xc0000000) >> 30)+((data
& 0x20000000) >> 27);
5022 case BCM4334_CHIP_ID
:
5023 data
= si_corereg(sih
, SI_CC_IDX
, OFFSETOF(chipcregs_t
, fabid
), 0, 0);
5027 case BCM4324_CHIP_ID
:
5028 case BCM4335_CHIP_ID
:
5029 case BCM43143_CHIP_ID
:
5030 case BCM43242_CHIP_ID
:
5031 case BCM43243_CHIP_ID
:
5032 /* intentional fallthrough */
5033 data
= si_corereg(sih
, SI_CC_IDX
, OFFSETOF(chipcregs_t
, fabid
), 0, 0);
5044 uint32
si_get_sromctl(si_t
*sih
)
5052 origidx
= si_coreidx(sih
);
5053 cc
= si_setcoreidx(sih
, SI_CC_IDX
);
5054 ASSERT((uintptr
)cc
);
5056 sromctl
= R_REG(osh
, &cc
->sromcontrol
);
5058 /* return to the original core */
5059 si_setcoreidx(sih
, origidx
);
5063 int si_set_sromctl(si_t
*sih
, uint32 value
)
5070 origidx
= si_coreidx(sih
);
5071 cc
= si_setcoreidx(sih
, SI_CC_IDX
);
5072 ASSERT((uintptr
)cc
);
5074 /* get chipcommon rev */
5075 if (si_corerev(sih
) < 32)
5076 return BCME_UNSUPPORTED
;
5078 W_REG(osh
, &cc
->sromcontrol
, value
);
5080 /* return to the original core */
5081 si_setcoreidx(sih
, origidx
);