2 * Misc utility routines for accessing chip-specific features
3 * of the SiliconBackplane-based Broadcom chips.
5 * Copyright (C) 1999-2017, Broadcom Corporation
7 * Unless you and Broadcom execute a separate written software license
8 * agreement governing use of this software, this software is licensed to you
9 * under the terms of the GNU General Public License version 2 (the "GPL"),
10 * available at http://www.broadcom.com/licenses/GPLv2.php, with the
11 * following added to such license:
13 * As a special exception, the copyright holders of this software give you
14 * permission to link this software with independent modules, and to copy and
15 * distribute the resulting executable under terms of your choice, provided that
16 * you also meet, for each linked independent module, the terms and conditions of
17 * the license of that module. An independent module is a module which is not
18 * derived from this software. The special exception does not apply to any
19 * modifications of the software.
21 * Notwithstanding the above, under no circumstances may you combine this
22 * software in any way with any other Broadcom software provided under a license
23 * other than the GPL, without Broadcom's express prior written consent.
26 * <<Broadcom-WL-IPTag/Open:>>
28 * $Id: siutils.c 668442 2016-11-03 08:42:43Z $
43 #endif /* BCMPCIEDEV */
53 #include <sbsdpcmdev.h>
63 #endif /* BCM_SDRBL */
72 #include "siutils_priv.h"
74 /* Defines the set of GPIOs to be used for SECI UART if not specified in NVRAM */
75 #define DEFAULT_SECI_UART_PINMUX_43430 0x0102
76 static bool force_seci_clk
= 0;
77 #endif /* SECI_UART */
80 * A set of PMU registers is clocked in the ILP domain, which has an implication on register write
81 * behavior: if such a register is written, it takes multiple ILP clocks for the PMU block to absorb
82 * the write. During that time the 'SlowWritePending' bit in the PMUStatus register is set.
84 #define PMUREGS_ILP_SENSITIVE(regoff) \
85 ((regoff) == OFFSETOF(pmuregs_t, pmutimer) || \
86 (regoff) == OFFSETOF(pmuregs_t, pmuwatchdog) || \
87 (regoff) == OFFSETOF(pmuregs_t, res_req_timer))
89 #define CHIPCREGS_ILP_SENSITIVE(regoff) \
90 ((regoff) == OFFSETOF(chipcregs_t, pmutimer) || \
91 (regoff) == OFFSETOF(chipcregs_t, pmuwatchdog) || \
92 (regoff) == OFFSETOF(chipcregs_t, res_req_timer))
94 #define GCI_FEM_CTRL_WAR 0x11111111
96 /* local prototypes */
97 static si_info_t
*si_doattach(si_info_t
*sii
, uint devid
, osl_t
*osh
, volatile void *regs
,
98 uint bustype
, void *sdh
, char **vars
, uint
*varsz
);
99 static bool si_buscore_prep(si_info_t
*sii
, uint bustype
, uint devid
, void *sdh
);
100 static bool si_buscore_setup(si_info_t
*sii
, chipcregs_t
*cc
, uint bustype
, uint32 savewin
,
101 uint
*origidx
, volatile void *regs
);
104 static bool si_pmu_is_ilp_sensitive(uint32 idx
, uint regoff
);
108 /* global variable to indicate reservation/release of gpio's */
109 static uint32 si_gpioreservation
= 0;
111 /* global flag to prevent shared resources from being initialized multiple times in si_attach() */
112 static bool si_onetimeinit
= FALSE
;
115 static const uint32 si_power_island_test_array
[] = {
116 0x0000, 0x0001, 0x0010, 0x0011,
117 0x0100, 0x0101, 0x0110, 0x0111,
118 0x1000, 0x1001, 0x1010, 0x1011,
119 0x1100, 0x1101, 0x1110, 0x1111
121 #endif /* SR_DEBUG */
123 int do_4360_pcie2_war
= 0;
126 /* Variable to store boot_type: warm_boot/cold_boot/etc. */
127 static int boot_type
= 0;
130 /* global kernel resource */
131 static si_info_t ksii
;
132 static si_cores_info_t ksii_cores_info
;
134 static const char rstr_rmin
[] = "rmin";
135 static const char rstr_rmax
[] = "rmax";
138 * Allocate an si handle. This function may be called multiple times.
140 * devid - pci device id (used to determine chip#)
141 * osh - opaque OS handle
142 * regs - virtual address of initial core registers
143 * bustype - pci/pcmcia/sb/sdio/etc
144 * vars - pointer to a to-be created pointer area for "environment" variables. Some callers of this
145 * function set 'vars' to NULL, making dereferencing of this parameter undesired.
146 * varsz - pointer to int to return the size of the vars
149 si_attach(uint devid
, osl_t
*osh
, volatile void *regs
,
150 uint bustype
, void *sdh
, char **vars
, uint
*varsz
)
153 si_cores_info_t
*cores_info
;
154 /* alloc si_info_t */
155 if ((sii
= MALLOCZ(osh
, sizeof (si_info_t
))) == NULL
) {
156 SI_ERROR(("si_attach: malloc failed! malloced %d bytes\n", MALLOCED(osh
)));
160 /* alloc si_cores_info_t */
161 if ((cores_info
= (si_cores_info_t
*)MALLOCZ(osh
, sizeof (si_cores_info_t
))) == NULL
) {
162 SI_ERROR(("si_attach: malloc failed! malloced %d bytes\n", MALLOCED(osh
)));
163 MFREE(osh
, sii
, sizeof(si_info_t
));
166 sii
->cores_info
= cores_info
;
168 if (si_doattach(sii
, devid
, osh
, regs
, bustype
, sdh
, vars
, varsz
) == NULL
) {
169 MFREE(osh
, sii
, sizeof(si_info_t
));
170 MFREE(osh
, cores_info
, sizeof(si_cores_info_t
));
173 sii
->vars
= vars
? *vars
: NULL
;
174 sii
->varsz
= varsz
? *varsz
: 0;
180 static uint32 wd_msticks
; /**< watchdog timer ticks normalized to ms */
182 /** generic kernel variant of si_attach() */
184 si_kattach(osl_t
*osh
)
186 static bool ksii_attached
= FALSE
;
187 si_cores_info_t
*cores_info
;
189 if (!ksii_attached
) {
191 regs
= REG_MAP(SI_ENUM_BASE
, SI_CORE_SIZE
);
192 cores_info
= (si_cores_info_t
*)&ksii_cores_info
;
193 ksii
.cores_info
= cores_info
;
196 if (si_doattach(&ksii
, BCM4710_DEVICE_ID
, osh
, regs
,
198 osh
!= SI_OSH
? &(ksii
.vars
) : NULL
,
199 osh
!= SI_OSH
? &(ksii
.varsz
) : NULL
) == NULL
) {
200 SI_ERROR(("si_kattach: si_doattach failed\n"));
206 /* save ticks normalized to ms for si_watchdog_ms() */
207 if (PMUCTL_ENAB(&ksii
.pub
)) {
209 /* based on 32KHz ILP clock */
213 wd_msticks
= ALP_CLOCK
/ 1000;
216 ksii_attached
= TRUE
;
217 SI_MSG(("si_kattach done. ccrev = %d, wd_msticks = %d\n",
218 CCREV(ksii
.pub
.ccrev
), wd_msticks
));
225 si_buscore_prep(si_info_t
*sii
, uint bustype
, uint devid
, void *sdh
)
228 BCM_REFERENCE(devid
);
229 /* need to set memseg flag for CF card first before any sb registers access */
230 if (BUSTYPE(bustype
) == PCMCIA_BUS
)
235 if (BUSTYPE(bustype
) == SDIO_BUS
) {
239 /* Try forcing SDIO core to do ALPAvail request only */
240 clkset
= SBSDIO_FORCE_HW_CLKREQ_OFF
| SBSDIO_ALP_AVAIL_REQ
;
241 bcmsdh_cfg_write(sdh
, SDIO_FUNC_1
, SBSDIO_FUNC1_CHIPCLKCSR
, clkset
, &err
);
245 /* If register supported, wait for ALPAvail and then force ALP */
246 clkval
= bcmsdh_cfg_read(sdh
, SDIO_FUNC_1
, SBSDIO_FUNC1_CHIPCLKCSR
, NULL
);
247 if ((clkval
& ~SBSDIO_AVBITS
) == clkset
) {
248 SPINWAIT(((clkval
= bcmsdh_cfg_read(sdh
, SDIO_FUNC_1
,
249 SBSDIO_FUNC1_CHIPCLKCSR
, NULL
)), !SBSDIO_ALPAV(clkval
)),
250 PMU_MAX_TRANSITION_DLY
);
251 if (!SBSDIO_ALPAV(clkval
)) {
252 SI_ERROR(("timeout on ALPAV wait, clkval 0x%02x\n",
256 clkset
= SBSDIO_FORCE_HW_CLKREQ_OFF
| SBSDIO_FORCE_ALP
;
257 bcmsdh_cfg_write(sdh
, SDIO_FUNC_1
, SBSDIO_FUNC1_CHIPCLKCSR
,
263 /* Also, disable the extra SDIO pull-ups */
264 bcmsdh_cfg_write(sdh
, SDIO_FUNC_1
, SBSDIO_FUNC1_SDIOPULLUP
, 0, NULL
);
268 /* Avoid backplane accesses before wake-wlan (i.e. htavail) for spi.
269 * F1 read accesses may return correct data but with data-not-available dstatus bit set.
271 if (BUSTYPE(bustype
) == SPI_BUS
) {
275 /* wake up wlan function :WAKE_UP goes as HT_AVAIL request in hardware */
276 regdata
= bcmsdh_cfg_read_word(sdh
, SDIO_FUNC_0
, SPID_CONFIG
, NULL
);
277 SI_MSG(("F0 REG0 rd = 0x%x\n", regdata
));
280 bcmsdh_cfg_write_word(sdh
, SDIO_FUNC_0
, SPID_CONFIG
, regdata
, &err
);
285 #endif /* BCMSDIO && BCMDONGLEHOST */
291 si_get_pmu_reg_addr(si_t
*sih
, uint32 offset
)
293 si_info_t
*sii
= SI_INFO(sih
);
294 uint32 pmuaddr
= INVALID_ADDR
;
297 SI_MSG(("%s: pmu access, offset: %x\n", __FUNCTION__
, offset
));
298 if (!(sii
->pub
.cccaps
& CC_CAP_PMU
)) {
301 if (AOB_ENAB(&sii
->pub
)) {
304 SI_MSG(("%s: AOBENAB: %x\n", __FUNCTION__
, offset
));
305 origidx
= sii
->curidx
;
306 pmucoreidx
= si_findcoreidx(&sii
->pub
, PMU_CORE_ID
, 0);
307 pmu
= si_setcoreidx(&sii
->pub
, pmucoreidx
);
308 pmuaddr
= (uint32
)(uintptr
)((volatile uint8
*)pmu
+ offset
);
309 si_setcoreidx(sih
, origidx
);
311 pmuaddr
= SI_ENUM_BASE
+ offset
;
314 printf("%s: addrRET: %x\n", __FUNCTION__
, pmuaddr
);
319 si_buscore_setup(si_info_t
*sii
, chipcregs_t
*cc
, uint bustype
, uint32 savewin
,
320 uint
*origidx
, volatile void *regs
)
322 si_cores_info_t
*cores_info
= (si_cores_info_t
*)sii
->cores_info
;
323 bool pci
, pcie
, pcie_gen2
= FALSE
;
325 uint pciidx
, pcieidx
, pcirev
, pcierev
;
327 #if defined(BCM_BACKPLANE_TIMEOUT) || defined(AXI_TIMEOUTS)
328 /* first, enable backplane timeouts */
329 si_slave_wrapper_add(&sii
->pub
);
333 cc
= si_setcoreidx(&sii
->pub
, SI_CC_IDX
);
336 /* get chipcommon rev */
337 sii
->pub
.ccrev
= (int)si_corerev(&sii
->pub
);
339 /* get chipcommon chipstatus */
340 if (CCREV(sii
->pub
.ccrev
) >= 11)
341 sii
->pub
.chipst
= R_REG(sii
->osh
, &cc
->chipstatus
);
343 /* get chipcommon capabilites */
344 sii
->pub
.cccaps
= R_REG(sii
->osh
, &cc
->capabilities
);
345 /* get chipcommon extended capabilities */
347 if (CCREV(sii
->pub
.ccrev
) >= 35)
348 sii
->pub
.cccaps_ext
= R_REG(sii
->osh
, &cc
->capabilities_ext
);
350 /* get pmu rev and caps */
351 if (sii
->pub
.cccaps
& CC_CAP_PMU
) {
352 if (AOB_ENAB(&sii
->pub
)) {
355 struct si_pub
*sih
= &sii
->pub
;
357 pmucoreidx
= si_findcoreidx(&sii
->pub
, PMU_CORE_ID
, 0);
358 if (!GOODIDX(pmucoreidx
)) {
359 SI_ERROR(("si_buscore_setup: si_findcoreidx failed\n"));
363 pmu
= si_setcoreidx(&sii
->pub
, pmucoreidx
);
364 sii
->pub
.pmucaps
= R_REG(sii
->osh
, &pmu
->pmucapabilities
);
365 si_setcoreidx(&sii
->pub
, SI_CC_IDX
);
367 sii
->pub
.gcirev
= si_corereg(sih
,
369 GCI_OFFSETOF(sih
, gci_corecaps0
), 0, 0) & GCI_CAP0_REV_MASK
;
371 sii
->pub
.pmucaps
= R_REG(sii
->osh
, &cc
->pmucapabilities
);
373 sii
->pub
.pmurev
= sii
->pub
.pmucaps
& PCAP_REV_MASK
;
376 SI_MSG(("Chipc: rev %d, caps 0x%x, chipst 0x%x pmurev %d, pmucaps 0x%x\n",
377 CCREV(sii
->pub
.ccrev
), sii
->pub
.cccaps
, sii
->pub
.chipst
, sii
->pub
.pmurev
,
380 /* figure out bus/orignal core idx */
381 sii
->pub
.buscoretype
= NODEV_CORE_ID
;
382 sii
->pub
.buscorerev
= (uint
)NOREV
;
383 sii
->pub
.buscoreidx
= BADIDX
;
386 pcirev
= pcierev
= (uint
)NOREV
;
387 pciidx
= pcieidx
= BADIDX
;
389 for (i
= 0; i
< sii
->numcores
; i
++) {
392 si_setcoreidx(&sii
->pub
, i
);
393 cid
= si_coreid(&sii
->pub
);
394 crev
= si_corerev(&sii
->pub
);
396 /* Display cores found */
397 SI_VMSG(("CORE[%d]: id 0x%x rev %d base 0x%x regs 0x%p\n",
398 i
, cid
, crev
, cores_info
->coresba
[i
], cores_info
->regs
[i
]));
400 if (BUSTYPE(bustype
) == SI_BUS
) {
401 /* now look at the chipstatus register to figure the pacakge */
402 /* for SDIO but downloaded on PCIE dev */
403 if (cid
== PCIE2_CORE_ID
) {
404 if (BCM43602_CHIP(sii
->pub
.chip
) ||
405 (CHIPID(sii
->pub
.chip
) == BCM4365_CHIP_ID
) ||
406 (CHIPID(sii
->pub
.chip
) == BCM4347_CHIP_ID
) ||
407 (CHIPID(sii
->pub
.chip
) == BCM4366_CHIP_ID
) ||
408 ((BCM4345_CHIP(sii
->pub
.chip
) ||
409 BCM4349_CHIP(sii
->pub
.chip
)) &&
410 CST4345_CHIPMODE_PCIE(sii
->pub
.chipst
))) {
418 } else if (BUSTYPE(bustype
) == PCI_BUS
) {
419 if (cid
== PCI_CORE_ID
) {
423 } else if ((cid
== PCIE_CORE_ID
) || (cid
== PCIE2_CORE_ID
)) {
427 if (cid
== PCIE2_CORE_ID
)
430 } else if ((BUSTYPE(bustype
) == PCMCIA_BUS
) &&
431 (cid
== PCMCIA_CORE_ID
)) {
432 sii
->pub
.buscorerev
= crev
;
433 sii
->pub
.buscoretype
= cid
;
434 sii
->pub
.buscoreidx
= i
;
437 else if (((BUSTYPE(bustype
) == SDIO_BUS
) ||
438 (BUSTYPE(bustype
) == SPI_BUS
)) &&
439 ((cid
== PCMCIA_CORE_ID
) ||
440 (cid
== SDIOD_CORE_ID
))) {
441 sii
->pub
.buscorerev
= crev
;
442 sii
->pub
.buscoretype
= cid
;
443 sii
->pub
.buscoreidx
= i
;
447 /* find the core idx before entering this func. */
448 if ((savewin
&& (savewin
== cores_info
->coresba
[i
])) ||
449 (regs
== cores_info
->regs
[i
]))
454 #if defined(PCIE_FULL_DONGLE)
457 sii
->pub
.buscoretype
= PCIE2_CORE_ID
;
459 sii
->pub
.buscoretype
= PCIE_CORE_ID
;
460 sii
->pub
.buscorerev
= pcierev
;
461 sii
->pub
.buscoreidx
= pcieidx
;
464 BCM_REFERENCE(pcirev
);
465 BCM_REFERENCE(pciidx
);
468 sii
->pub
.buscoretype
= PCI_CORE_ID
;
469 sii
->pub
.buscorerev
= pcirev
;
470 sii
->pub
.buscoreidx
= pciidx
;
473 sii
->pub
.buscoretype
= PCIE2_CORE_ID
;
475 sii
->pub
.buscoretype
= PCIE_CORE_ID
;
476 sii
->pub
.buscorerev
= pcierev
;
477 sii
->pub
.buscoreidx
= pcieidx
;
479 #endif /* defined(PCIE_FULL_DONGLE) */
481 SI_VMSG(("Buscore id/type/rev %d/0x%x/%d\n", sii
->pub
.buscoreidx
, sii
->pub
.buscoretype
,
482 sii
->pub
.buscorerev
));
486 /* Make sure any on-chip ARM is off (in case strapping is wrong), or downloaded code was
489 if ((BUSTYPE(bustype
) == SDIO_BUS
) || (BUSTYPE(bustype
) == SPI_BUS
)) {
490 if (si_setcore(&sii
->pub
, ARM7S_CORE_ID
, 0) ||
491 si_setcore(&sii
->pub
, ARMCM3_CORE_ID
, 0))
492 si_core_disable(&sii
->pub
, 0);
494 #endif /* BCMSDIO && BCMDONGLEHOST */
496 /* return to the original core */
497 si_setcoreidx(&sii
->pub
, *origidx
);
509 si_info_t
*sii
= SI_INFO(sih
);
511 return (sii
->chipnew
) ? sii
->chipnew
: sih
->chip
;
514 /* CHIP_ID's being mapped here should not be used anywhere else in the code */
516 si_chipid_fixup(si_t
*sih
)
518 si_info_t
*sii
= SI_INFO(sih
);
520 ASSERT(sii
->chipnew
== 0);
522 case BCM43567_CHIP_ID
:
523 sii
->chipnew
= sih
->chip
; /* save it */
524 sii
->pub
.chip
= BCM43570_CHIP_ID
; /* chip class */
526 case BCM43562_CHIP_ID
:
527 case BCM4358_CHIP_ID
:
528 case BCM43566_CHIP_ID
:
529 sii
->chipnew
= sih
->chip
; /* save it */
530 sii
->pub
.chip
= BCM43569_CHIP_ID
; /* chip class */
532 case BCM4356_CHIP_ID
:
533 case BCM4371_CHIP_ID
:
534 sii
->chipnew
= sih
->chip
; /* save it */
535 sii
->pub
.chip
= BCM4354_CHIP_ID
; /* chip class */
537 case BCM4357_CHIP_ID
:
538 case BCM4361_CHIP_ID
:
539 sii
->chipnew
= sih
->chip
; /* save it */
540 sii
->pub
.chip
= BCM4347_CHIP_ID
; /* chip class */
549 si_check_boot_type(si_t
*sih
, osl_t
*osh
)
551 if (sih
->pmurev
>= 30) {
552 boot_type
= PMU_REG_NEW(sih
, swscratch
, 0, 0);
554 boot_type
= CHIPC_REG(sih
, flashdata
, 0, 0);
557 SI_ERROR(("%s: boot_type: 0x%08x\n", __func__
, boot_type
));
562 * Allocate an si handle. This function may be called multiple times.
564 * vars - pointer to a to-be created pointer area for "environment" variables. Some callers of this
565 * function set 'vars' to NULL.
568 si_doattach(si_info_t
*sii
, uint devid
, osl_t
*osh
, volatile void *regs
,
569 uint bustype
, void *sdh
, char **vars
, uint
*varsz
)
571 struct si_pub
*sih
= &sii
->pub
;
576 #if !defined(_CFEZ_) || defined(CFG_WL)
579 ASSERT(GOODREGS(regs
));
583 sih
->buscoreidx
= BADIDX
;
584 sii
->device_removed
= FALSE
;
589 sii
->second_bar0win
= ~0x0;
591 #if defined(BCM_BACKPLANE_TIMEOUT)
592 sih
->err_info
= MALLOCZ(osh
, sizeof(si_axi_error_info_t
));
593 if (sih
->err_info
== NULL
) {
594 SI_ERROR(("%s: %d bytes MALLOC FAILED",
595 __FUNCTION__
, sizeof(si_axi_error_info_t
)));
598 #endif /* BCM_BACKPLANE_TIMEOUT */
601 /* check to see if we are a si core mimic'ing a pci core */
602 if ((bustype
== PCI_BUS
) &&
603 (OSL_PCI_READ_CONFIG(sii
->osh
, PCI_SPROM_CONTROL
, sizeof(uint32
)) == 0xffffffff)) {
604 SI_ERROR(("%s: incoming bus is PCI but it's a lie, switching to SI "
605 "devid:0x%x\n", __FUNCTION__
, devid
));
609 /* find Chipcommon address */
610 if (bustype
== PCI_BUS
) {
611 savewin
= OSL_PCI_READ_CONFIG(sii
->osh
, PCI_BAR0_WIN
, sizeof(uint32
));
612 if (!GOODCOREADDR(savewin
, SI_ENUM_BASE
))
613 savewin
= SI_ENUM_BASE
;
614 OSL_PCI_WRITE_CONFIG(sii
->osh
, PCI_BAR0_WIN
, 4, SI_ENUM_BASE
);
617 cc
= (chipcregs_t
*)regs
;
619 } else if ((bustype
== SDIO_BUS
) || (bustype
== SPI_BUS
)) {
620 cc
= (chipcregs_t
*)sii
->curmap
;
623 cc
= (chipcregs_t
*)REG_MAP(SI_ENUM_BASE
, SI_CORE_SIZE
);
626 sih
->bustype
= bustype
;
627 if (bustype
!= BUSTYPE(bustype
)) {
628 SI_ERROR(("si_doattach: bus type %d does not match configured bus type %d\n",
629 bustype
, BUSTYPE(bustype
)));
633 /* bus/core/clk setup for register access */
634 if (!si_buscore_prep(sii
, bustype
, devid
, sdh
)) {
635 SI_ERROR(("si_doattach: si_core_clk_prep failed %d\n", bustype
));
639 /* ChipID recognition.
640 * We assume we can read chipid at offset 0 from the regs arg.
641 * If we add other chiptypes (or if we need to support old sdio hosts w/o chipcommon),
642 * some way of recognizing them needs to be added here.
645 SI_ERROR(("%s: chipcommon register space is null \n", __FUNCTION__
));
648 w
= R_REG(osh
, &cc
->chipid
);
649 if ((w
& 0xfffff) == 148277) w
-= 65532;
650 sih
->socitype
= (w
& CID_TYPE_MASK
) >> CID_TYPE_SHIFT
;
651 /* Might as wll fill in chip id rev & pkg */
652 sih
->chip
= w
& CID_ID_MASK
;
653 sih
->chiprev
= (w
& CID_REV_MASK
) >> CID_REV_SHIFT
;
654 sih
->chippkg
= (w
& CID_PKG_MASK
) >> CID_PKG_SHIFT
;
656 si_chipid_fixup(sih
);
658 sih
->issim
= IS_SIM(sih
->chippkg
);
661 if (CHIPTYPE(sii
->pub
.socitype
) == SOCI_SB
) {
662 SI_MSG(("Found chip type SB (0x%08x)\n", w
));
663 sb_scan(&sii
->pub
, regs
, devid
);
664 } else if ((CHIPTYPE(sii
->pub
.socitype
) == SOCI_AI
) ||
665 (CHIPTYPE(sii
->pub
.socitype
) == SOCI_NAI
)) {
666 if (CHIPTYPE(sii
->pub
.socitype
) == SOCI_AI
)
667 SI_MSG(("Found chip type AI (0x%08x)\n", w
));
669 SI_MSG(("Found chip type NAI (0x%08x)\n", w
));
670 /* pass chipc address instead of original core base */
672 sii
->axi_wrapper
= (axi_wrapper_t
*)MALLOCZ(sii
->osh
,
673 (sizeof(axi_wrapper_t
) * SI_MAX_AXI_WRAPPERS
));
675 if (sii
->axi_wrapper
== NULL
) {
676 SI_ERROR(("%s: %zu bytes MALLOC Failed", __FUNCTION__
,
677 (sizeof(axi_wrapper_t
) * SI_MAX_AXI_WRAPPERS
)));
681 ai_scan(&sii
->pub
, (void *)(uintptr
)cc
, devid
);
682 } else if (CHIPTYPE(sii
->pub
.socitype
) == SOCI_UBUS
) {
683 SI_MSG(("Found chip type UBUS (0x%08x), chip id = 0x%4x\n", w
, sih
->chip
));
684 /* pass chipc address instead of original core base */
685 ub_scan(&sii
->pub
, (void *)(uintptr
)cc
, devid
);
687 SI_ERROR(("Found chip of unknown type (0x%08x)\n", w
));
690 /* no cores found, bail out */
691 if (sii
->numcores
== 0) {
692 SI_ERROR(("si_doattach: could not find any cores\n"));
695 /* bus/core/clk setup */
697 if (!si_buscore_setup(sii
, cc
, bustype
, savewin
, &origidx
, regs
)) {
698 SI_ERROR(("si_doattach: si_buscore_setup failed\n"));
702 si_check_boot_type(sih
, osh
);
704 if (ulp_module_init(osh
, sih
) != BCME_OK
) {
705 ULP_ERR(("%s: err in ulp_module_init\n", __FUNCTION__
));
710 #if !defined(_CFEZ_) || defined(CFG_WL)
711 /* assume current core is CC */
712 if ((CCREV(sii
->pub
.ccrev
) == 0x25) && ((CHIPID(sih
->chip
) == BCM43236_CHIP_ID
||
713 CHIPID(sih
->chip
) == BCM43235_CHIP_ID
||
714 CHIPID(sih
->chip
) == BCM43234_CHIP_ID
||
715 CHIPID(sih
->chip
) == BCM43238_CHIP_ID
) &&
716 (CHIPREV(sii
->pub
.chiprev
) <= 2))) {
718 if ((cc
->chipstatus
& CST43236_BP_CLK
) != 0) {
720 clkdiv
= R_REG(osh
, &cc
->clkdiv
);
721 /* otp_clk_div is even number, 120/14 < 9mhz */
722 clkdiv
= (clkdiv
& ~CLKD_OTP
) | (14 << CLKD_OTP_SHIFT
);
723 W_REG(osh
, &cc
->clkdiv
, clkdiv
);
724 SI_ERROR(("%s: set clkdiv to %x\n", __FUNCTION__
, clkdiv
));
729 if (bustype
== PCI_BUS
) {
734 /* 4360 rom bootloader in PCIE case, if the SDR is enabled, But preotection is
735 * not turned on, then we want to hold arm in reset.
736 * Bottomline: In sdrenable case, we allow arm to boot only when protection is
739 if (CHIP_HOSTIF_PCIE(&(sii
->pub
))) {
740 uint32 sflags
= si_arm_sflags(&(sii
->pub
));
742 /* If SDR is enabled but protection is not turned on
743 * then we want to force arm to WFI.
745 if ((sflags
& (SISF_SDRENABLE
| SISF_TCMPROT
)) == SISF_SDRENABLE
) {
752 #endif /* BCM_SDRBL */
755 BCM_REFERENCE(pvars
);
757 if (!si_onetimeinit
) {
760 if (CCREV(sii
->pub
.ccrev
) >= 20) {
761 uint32 gpiopullup
= 0, gpiopulldown
= 0;
762 cc
= (chipcregs_t
*)si_setcore(sih
, CC_CORE_ID
, 0);
765 /* 4314/43142 has pin muxing, don't clear gpio bits */
766 if ((CHIPID(sih
->chip
) == BCM4314_CHIP_ID
) ||
767 (CHIPID(sih
->chip
) == BCM43142_CHIP_ID
)) {
768 gpiopullup
|= 0x402e0;
769 gpiopulldown
|= 0x20500;
773 W_REG(osh
, &cc
->gpiopullup
, gpiopullup
);
774 W_REG(osh
, &cc
->gpiopulldown
, gpiopulldown
);
775 si_setcoreidx(sih
, origidx
);
780 /* clear any previous epidiag-induced target abort */
781 ASSERT(!si_taclear(sih
, FALSE
));
784 #ifdef BOOTLOADER_CONSOLE_OUTPUT
785 /* Enable console prints */
796 /** may be called with core in reset */
800 si_info_t
*sii
= SI_INFO(sih
);
801 si_cores_info_t
*cores_info
= (si_cores_info_t
*)sii
->cores_info
;
805 if (BUSTYPE(sih
->bustype
) == SI_BUS
)
806 for (idx
= 0; idx
< SI_MAXCORES
; idx
++)
807 if (cores_info
->regs
[idx
]) {
808 REG_UNMAP(cores_info
->regs
[idx
]);
809 cores_info
->regs
[idx
] = NULL
;
813 #if !defined(BCMBUSTYPE) || (BCMBUSTYPE == SI_BUS)
814 if (cores_info
!= &ksii_cores_info
)
815 #endif /* !BCMBUSTYPE || (BCMBUSTYPE == SI_BUS) */
816 MFREE(sii
->osh
, cores_info
, sizeof(si_cores_info_t
));
818 #if defined(BCM_BACKPLANE_TIMEOUT)
820 MFREE(sii
->osh
, sih
->err_info
, sizeof(si_axi_error_info_t
));
821 sii
->pub
.err_info
= NULL
;
823 #endif /* BCM_BACKPLANE_TIMEOUT */
825 if (sii
->axi_wrapper
) {
826 MFREE(sii
->osh
, sii
->axi_wrapper
,
827 (sizeof(axi_wrapper_t
) * SI_MAX_AXI_WRAPPERS
));
828 sii
->axi_wrapper
= NULL
;
831 #if !defined(BCMBUSTYPE) || (BCMBUSTYPE == SI_BUS)
833 #endif /* !BCMBUSTYPE || (BCMBUSTYPE == SI_BUS) */
834 MFREE(sii
->osh
, sii
, sizeof(si_info_t
));
847 si_setosh(si_t
*sih
, osl_t
*osh
)
852 if (sii
->osh
!= NULL
) {
853 SI_ERROR(("osh is already set....\n"));
859 /** register driver interrupt disabling and restoring callback functions */
861 si_register_intr_callback(si_t
*sih
, void *intrsoff_fn
, void *intrsrestore_fn
,
862 void *intrsenabled_fn
, void *intr_arg
)
864 si_info_t
*sii
= SI_INFO(sih
);
865 si_cores_info_t
*cores_info
= (si_cores_info_t
*)sii
->cores_info
;
866 sii
->intr_arg
= intr_arg
;
867 sii
->intrsoff_fn
= (si_intrsoff_t
)intrsoff_fn
;
868 sii
->intrsrestore_fn
= (si_intrsrestore_t
)intrsrestore_fn
;
869 sii
->intrsenabled_fn
= (si_intrsenabled_t
)intrsenabled_fn
;
870 /* save current core id. when this function called, the current core
871 * must be the core which provides driver functions(il, et, wl, etc.)
873 sii
->dev_coreid
= cores_info
->coreid
[sii
->curidx
];
877 si_deregister_intr_callback(si_t
*sih
)
882 sii
->intrsoff_fn
= NULL
;
883 sii
->intrsrestore_fn
= NULL
;
884 sii
->intrsenabled_fn
= NULL
;
888 si_intflag(si_t
*sih
)
890 si_info_t
*sii
= SI_INFO(sih
);
892 if (CHIPTYPE(sih
->socitype
) == SOCI_SB
)
893 return sb_intflag(sih
);
894 else if ((CHIPTYPE(sih
->socitype
) == SOCI_AI
) || (CHIPTYPE(sih
->socitype
) == SOCI_NAI
))
895 return R_REG(sii
->osh
, ((uint32
*)(uintptr
)
896 (sii
->oob_router
+ OOB_STATUSA
)));
906 if (CHIPTYPE(sih
->socitype
) == SOCI_SB
)
908 else if ((CHIPTYPE(sih
->socitype
) == SOCI_AI
) || (CHIPTYPE(sih
->socitype
) == SOCI_NAI
))
910 else if (CHIPTYPE(sih
->socitype
) == SOCI_UBUS
)
919 si_flag_alt(si_t
*sih
)
921 if ((CHIPTYPE(sih
->socitype
) == SOCI_AI
) || (CHIPTYPE(sih
->socitype
) == SOCI_NAI
))
922 return ai_flag_alt(sih
);
930 si_setint(si_t
*sih
, int siflag
)
932 if (CHIPTYPE(sih
->socitype
) == SOCI_SB
)
933 sb_setint(sih
, siflag
);
934 else if ((CHIPTYPE(sih
->socitype
) == SOCI_AI
) || (CHIPTYPE(sih
->socitype
) == SOCI_NAI
))
935 ai_setint(sih
, siflag
);
936 else if (CHIPTYPE(sih
->socitype
) == SOCI_UBUS
)
937 ub_setint(sih
, siflag
);
945 si_info_t
*sii
= SI_INFO(sih
);
946 si_cores_info_t
*cores_info
= (si_cores_info_t
*)sii
->cores_info
;
948 return cores_info
->coreid
[sii
->curidx
];
952 si_coreidx(si_t
*sih
)
961 si_d11_switch_addrbase(si_t
*sih
, uint coreunit
)
963 return si_setcore(sih
, D11_CORE_ID
, coreunit
);
966 /** return the core-type instantiation # of the current core */
968 si_coreunit(si_t
*sih
)
970 si_info_t
*sii
= SI_INFO(sih
);
971 si_cores_info_t
*cores_info
= (si_cores_info_t
*)sii
->cores_info
;
981 ASSERT(GOODREGS(sii
->curmap
));
982 coreid
= si_coreid(sih
);
984 /* count the cores of our type */
985 for (i
= 0; i
< idx
; i
++)
986 if (cores_info
->coreid
[i
] == coreid
)
993 si_corevendor(si_t
*sih
)
995 if (CHIPTYPE(sih
->socitype
) == SOCI_SB
)
996 return sb_corevendor(sih
);
997 else if ((CHIPTYPE(sih
->socitype
) == SOCI_AI
) || (CHIPTYPE(sih
->socitype
) == SOCI_NAI
))
998 return ai_corevendor(sih
);
999 else if (CHIPTYPE(sih
->socitype
) == SOCI_UBUS
)
1000 return ub_corevendor(sih
);
1008 si_backplane64(si_t
*sih
)
1010 return ((sih
->cccaps
& CC_CAP_BKPLN64
) != 0);
1014 si_corerev(si_t
*sih
)
1016 if (CHIPTYPE(sih
->socitype
) == SOCI_SB
)
1017 return sb_corerev(sih
);
1018 else if ((CHIPTYPE(sih
->socitype
) == SOCI_AI
) || (CHIPTYPE(sih
->socitype
) == SOCI_NAI
))
1019 return ai_corerev(sih
);
1020 else if (CHIPTYPE(sih
->socitype
) == SOCI_UBUS
)
1021 return ub_corerev(sih
);
1028 /* return index of coreid or BADIDX if not found */
1030 si_findcoreidx(si_t
*sih
, uint coreid
, uint coreunit
)
1032 si_info_t
*sii
= SI_INFO(sih
);
1033 si_cores_info_t
*cores_info
= (si_cores_info_t
*)sii
->cores_info
;
1040 for (i
= 0; i
< sii
->numcores
; i
++)
1041 if (cores_info
->coreid
[i
] == coreid
) {
1042 if (found
== coreunit
)
1050 /** return total coreunit of coreid or zero if not found */
1052 si_numcoreunits(si_t
*sih
, uint coreid
)
1054 if ((CHIPID(sih
->chip
) == BCM4347_CHIP_ID
) &&
1055 (CHIPREV(sih
->chiprev
) == 0)) {
1057 * 4347TC2 does not have Aux core.
1058 * fixed to 1 here because EROM (using 4349 EROM) has two entries
1062 si_info_t
*sii
= SI_INFO(sih
);
1063 si_cores_info_t
*cores_info
= (si_cores_info_t
*)sii
->cores_info
;
1067 for (i
= 0; i
< sii
->numcores
; i
++) {
1068 if (cores_info
->coreid
[i
] == coreid
) {
1077 /** return total D11 coreunits */
1079 BCMRAMFN(si_numd11coreunits
)(si_t
*sih
)
1083 found
= si_numcoreunits(sih
, D11_CORE_ID
);
1085 #if defined(WLRSDB) && defined(WLRSDB_DISABLED)
1086 /* If RSDB functionality is compiled out,
1087 * then ignore any D11 cores beyond the first
1088 * Used in norsdb dongle build variants for rsdb chip.
1091 #endif /* defined(WLRSDB) && !defined(WLRSDB_DISABLED) */
1096 /** return list of found cores */
1098 si_corelist(si_t
*sih
, uint coreid
[])
1100 si_info_t
*sii
= SI_INFO(sih
);
1101 si_cores_info_t
*cores_info
= (si_cores_info_t
*)sii
->cores_info
;
1103 bcopy((uchar
*)cores_info
->coreid
, (uchar
*)coreid
, (sii
->numcores
* sizeof(uint
)));
1104 return (sii
->numcores
);
1107 /** return current wrapper mapping */
1109 si_wrapperregs(si_t
*sih
)
1114 ASSERT(GOODREGS(sii
->curwrap
));
1116 return (sii
->curwrap
);
1119 /** return current register mapping */
1121 si_coreregs(si_t
*sih
)
1126 ASSERT(GOODREGS(sii
->curmap
));
1128 return (sii
->curmap
);
1133 * This function changes logical "focus" to the indicated core;
1134 * must be called with interrupts off.
1135 * Moreover, callers should keep interrupts off during switching out of and back to d11 core
1138 si_setcore(si_t
*sih
, uint coreid
, uint coreunit
)
1142 idx
= si_findcoreidx(sih
, coreid
, coreunit
);
1146 if (CHIPTYPE(sih
->socitype
) == SOCI_SB
)
1147 return sb_setcoreidx(sih
, idx
);
1148 else if ((CHIPTYPE(sih
->socitype
) == SOCI_AI
) || (CHIPTYPE(sih
->socitype
) == SOCI_NAI
))
1149 return ai_setcoreidx(sih
, idx
);
1150 else if (CHIPTYPE(sih
->socitype
) == SOCI_UBUS
)
1151 return ub_setcoreidx(sih
, idx
);
1159 si_setcoreidx(si_t
*sih
, uint coreidx
)
1161 if (CHIPTYPE(sih
->socitype
) == SOCI_SB
)
1162 return sb_setcoreidx(sih
, coreidx
);
1163 else if ((CHIPTYPE(sih
->socitype
) == SOCI_AI
) || (CHIPTYPE(sih
->socitype
) == SOCI_NAI
))
1164 return ai_setcoreidx(sih
, coreidx
);
1165 else if (CHIPTYPE(sih
->socitype
) == SOCI_UBUS
)
1166 return ub_setcoreidx(sih
, coreidx
);
1173 /** Turn off interrupt as required by sb_setcore, before switch core */
1175 si_switch_core(si_t
*sih
, uint coreid
, uint
*origidx
, uint
*intr_val
)
1178 si_info_t
*sii
= SI_INFO(sih
);
1181 /* Overloading the origidx variable to remember the coreid,
1182 * this works because the core ids cannot be confused with
1186 if (coreid
== CC_CORE_ID
)
1187 return (volatile void *)CCREGS_FAST(sii
);
1188 else if (coreid
== BUSCORETYPE(sih
->buscoretype
))
1189 return (volatile void *)PCIEREGS(sii
);
1191 INTR_OFF(sii
, *intr_val
);
1192 *origidx
= sii
->curidx
;
1193 cc
= si_setcore(sih
, coreid
, 0);
1199 /* restore coreidx and restore interrupt */
1201 si_restore_core(si_t
*sih
, uint coreid
, uint intr_val
)
1203 si_info_t
*sii
= SI_INFO(sih
);
1205 if (SI_FAST(sii
) && ((coreid
== CC_CORE_ID
) || (coreid
== BUSCORETYPE(sih
->buscoretype
))))
1208 si_setcoreidx(sih
, coreid
);
1209 INTR_RESTORE(sii
, intr_val
);
1213 si_numaddrspaces(si_t
*sih
)
1215 if (CHIPTYPE(sih
->socitype
) == SOCI_SB
)
1216 return sb_numaddrspaces(sih
);
1217 else if ((CHIPTYPE(sih
->socitype
) == SOCI_AI
) || (CHIPTYPE(sih
->socitype
) == SOCI_NAI
))
1218 return ai_numaddrspaces(sih
);
1219 else if (CHIPTYPE(sih
->socitype
) == SOCI_UBUS
)
1220 return ub_numaddrspaces(sih
);
1228 si_addrspace(si_t
*sih
, uint asidx
)
1230 if (CHIPTYPE(sih
->socitype
) == SOCI_SB
)
1231 return sb_addrspace(sih
, asidx
);
1232 else if ((CHIPTYPE(sih
->socitype
) == SOCI_AI
) || (CHIPTYPE(sih
->socitype
) == SOCI_NAI
))
1233 return ai_addrspace(sih
, asidx
);
1234 else if (CHIPTYPE(sih
->socitype
) == SOCI_UBUS
)
1235 return ub_addrspace(sih
, asidx
);
1243 si_addrspacesize(si_t
*sih
, uint asidx
)
1245 if (CHIPTYPE(sih
->socitype
) == SOCI_SB
)
1246 return sb_addrspacesize(sih
, asidx
);
1247 else if ((CHIPTYPE(sih
->socitype
) == SOCI_AI
) || (CHIPTYPE(sih
->socitype
) == SOCI_NAI
))
1248 return ai_addrspacesize(sih
, asidx
);
1249 else if (CHIPTYPE(sih
->socitype
) == SOCI_UBUS
)
1250 return ub_addrspacesize(sih
, asidx
);
1258 si_coreaddrspaceX(si_t
*sih
, uint asidx
, uint32
*addr
, uint32
*size
)
1260 /* Only supported for SOCI_AI */
1261 if ((CHIPTYPE(sih
->socitype
) == SOCI_AI
) || (CHIPTYPE(sih
->socitype
) == SOCI_NAI
))
1262 ai_coreaddrspaceX(sih
, asidx
, addr
, size
);
1268 si_core_cflags(si_t
*sih
, uint32 mask
, uint32 val
)
1270 if (CHIPTYPE(sih
->socitype
) == SOCI_SB
)
1271 return sb_core_cflags(sih
, mask
, val
);
1272 else if ((CHIPTYPE(sih
->socitype
) == SOCI_AI
) || (CHIPTYPE(sih
->socitype
) == SOCI_NAI
))
1273 return ai_core_cflags(sih
, mask
, val
);
1274 else if (CHIPTYPE(sih
->socitype
) == SOCI_UBUS
)
1275 return ub_core_cflags(sih
, mask
, val
);
1283 si_core_cflags_wo(si_t
*sih
, uint32 mask
, uint32 val
)
1285 if (CHIPTYPE(sih
->socitype
) == SOCI_SB
)
1286 sb_core_cflags_wo(sih
, mask
, val
);
1287 else if ((CHIPTYPE(sih
->socitype
) == SOCI_AI
) || (CHIPTYPE(sih
->socitype
) == SOCI_NAI
))
1288 ai_core_cflags_wo(sih
, mask
, val
);
1289 else if (CHIPTYPE(sih
->socitype
) == SOCI_UBUS
)
1290 ub_core_cflags_wo(sih
, mask
, val
);
1296 si_core_sflags(si_t
*sih
, uint32 mask
, uint32 val
)
1298 if (CHIPTYPE(sih
->socitype
) == SOCI_SB
)
1299 return sb_core_sflags(sih
, mask
, val
);
1300 else if ((CHIPTYPE(sih
->socitype
) == SOCI_AI
) || (CHIPTYPE(sih
->socitype
) == SOCI_NAI
))
1301 return ai_core_sflags(sih
, mask
, val
);
1302 else if (CHIPTYPE(sih
->socitype
) == SOCI_UBUS
)
1303 return ub_core_sflags(sih
, mask
, val
);
1311 si_commit(si_t
*sih
)
1313 if (CHIPTYPE(sih
->socitype
) == SOCI_SB
)
1315 else if (CHIPTYPE(sih
->socitype
) == SOCI_AI
|| CHIPTYPE(sih
->socitype
) == SOCI_NAI
)
1317 else if (CHIPTYPE(sih
->socitype
) == SOCI_UBUS
)
1325 si_iscoreup(si_t
*sih
)
1327 if (CHIPTYPE(sih
->socitype
) == SOCI_SB
)
1328 return sb_iscoreup(sih
);
1329 else if ((CHIPTYPE(sih
->socitype
) == SOCI_AI
) || (CHIPTYPE(sih
->socitype
) == SOCI_NAI
))
1330 return ai_iscoreup(sih
);
1331 else if (CHIPTYPE(sih
->socitype
) == SOCI_UBUS
)
1332 return ub_iscoreup(sih
);
1340 si_wrapperreg(si_t
*sih
, uint32 offset
, uint32 mask
, uint32 val
)
1342 /* only for AI back plane chips */
1343 if ((CHIPTYPE(sih
->socitype
) == SOCI_AI
) || (CHIPTYPE(sih
->socitype
) == SOCI_NAI
))
1344 return (ai_wrap_reg(sih
, offset
, mask
, val
));
1347 /* si_backplane_access is used to read full backplane address from host for PCIE FD
1348 * it uses secondary bar-0 window which lies at an offset of 16K from primary bar-0
1349 * Provides support for read/write of 1/2/4 bytes of backplane address
1350 * Can be used to read/write
1355 * For accessing any 32 bit backplane address, [31 : 12] of backplane should be given in "region"
1356 * [11 : 0] should be the "regoff"
1357 * for reading 4 bytes from reg 0x200 of d11 core use it like below
1358 * : si_backplane_access(sih, 0x18001000, 0x200, 4, 0, TRUE)
1360 static int si_backplane_addr_sane(uint addr
, uint size
)
1362 int bcmerror
= BCME_OK
;
1364 /* For 2 byte access, address has to be 2 byte aligned */
1367 bcmerror
= BCME_ERROR
;
1370 /* For 4 byte access, address has to be 4 byte aligned */
1373 bcmerror
= BCME_ERROR
;
1380 si_invalidate_second_bar0win(si_t
*sih
)
1382 si_info_t
*sii
= SI_INFO(sih
);
1383 sii
->second_bar0win
= ~0x0;
1387 si_backplane_access(si_t
*sih
, uint addr
, uint size
, uint
*val
, bool read
)
1389 volatile uint32
*r
= NULL
;
1391 si_info_t
*sii
= SI_INFO(sih
);
1393 /* Valid only for pcie bus */
1394 if (BUSTYPE(sih
->bustype
) != PCI_BUS
) {
1395 SI_ERROR(("Valid only for pcie bus \n"));
1399 /* Split adrr into region and address offset */
1400 region
= (addr
& (0xFFFFF << 12));
1401 addr
= addr
& 0xFFF;
1403 /* check for address and size sanity */
1404 if (si_backplane_addr_sane(addr
, size
) != BCME_OK
)
1407 /* Update window if required */
1408 if (sii
->second_bar0win
!= region
) {
1409 OSL_PCI_WRITE_CONFIG(sii
->osh
, PCIE2_BAR0_CORE2_WIN
, 4, region
);
1410 sii
->second_bar0win
= region
;
1413 /* Estimate effective address
1414 * sii->curmap : bar-0 virtual address
1415 * PCI_SECOND_BAR0_OFFSET : secondar bar-0 offset
1416 * regoff : actual reg offset
1418 r
= (volatile uint32
*)((volatile char *)sii
->curmap
+ PCI_SECOND_BAR0_OFFSET
+ addr
);
1420 SI_VMSG(("si curmap %p region %x regaddr %x effective addr %p READ %d\n",
1421 (volatile char*)sii
->curmap
, region
, addr
, r
, read
));
1424 case sizeof(uint8
) :
1426 *val
= R_REG(sii
->osh
, (volatile uint8
*)r
);
1428 W_REG(sii
->osh
, (volatile uint8
*)r
, *val
);
1430 case sizeof(uint16
) :
1432 *val
= R_REG(sii
->osh
, (volatile uint16
*)r
);
1434 W_REG(sii
->osh
, (volatile uint16
*)r
, *val
);
1436 case sizeof(uint32
) :
1438 *val
= R_REG(sii
->osh
, (volatile uint32
*)r
);
1440 W_REG(sii
->osh
, (volatile uint32
*)r
, *val
);
1443 SI_ERROR(("Invalid size %d \n", size
));
1444 return (BCME_ERROR
);
1451 si_corereg(si_t
*sih
, uint coreidx
, uint regoff
, uint mask
, uint val
)
1453 if (CHIPTYPE(sih
->socitype
) == SOCI_SB
)
1454 return sb_corereg(sih
, coreidx
, regoff
, mask
, val
);
1455 else if ((CHIPTYPE(sih
->socitype
) == SOCI_AI
) || (CHIPTYPE(sih
->socitype
) == SOCI_NAI
))
1456 return ai_corereg(sih
, coreidx
, regoff
, mask
, val
);
1457 else if (CHIPTYPE(sih
->socitype
) == SOCI_UBUS
)
1458 return ub_corereg(sih
, coreidx
, regoff
, mask
, val
);
1465 /** ILP sensitive register access needs special treatment to avoid backplane stalls */
1466 bool si_pmu_is_ilp_sensitive(uint32 idx
, uint regoff
)
1468 if (idx
== SI_CC_IDX
) {
1469 if (CHIPCREGS_ILP_SENSITIVE(regoff
))
1471 } else if (PMUREGS_ILP_SENSITIVE(regoff
)) {
1478 /** 'idx' should refer either to the chipcommon core or the PMU core */
1480 si_pmu_corereg(si_t
*sih
, uint32 idx
, uint regoff
, uint mask
, uint val
)
1482 int pmustatus_offset
;
1484 /* prevent backplane stall on double write to 'ILP domain' registers in the PMU */
1485 if (mask
!= 0 && PMUREV(sih
->pmurev
) >= 22 &&
1486 si_pmu_is_ilp_sensitive(idx
, regoff
)) {
1487 pmustatus_offset
= AOB_ENAB(sih
) ? OFFSETOF(pmuregs_t
, pmustatus
) :
1488 OFFSETOF(chipcregs_t
, pmustatus
);
1490 while (si_corereg(sih
, idx
, pmustatus_offset
, 0, 0) & PST_SLOW_WR_PENDING
)
1494 return si_corereg(sih
, idx
, regoff
, mask
, val
);
1498 * If there is no need for fiddling with interrupts or core switches (typically silicon
1499 * back plane registers, pci registers and chipcommon registers), this function
1500 * returns the register offset on this core to a mapped address. This address can
1501 * be used for W_REG/R_REG directly.
1503 * For accessing registers that would need a core switch, this function will return
1507 si_corereg_addr(si_t
*sih
, uint coreidx
, uint regoff
)
1509 if (CHIPTYPE(sih
->socitype
) == SOCI_SB
)
1510 return sb_corereg_addr(sih
, coreidx
, regoff
);
1511 else if ((CHIPTYPE(sih
->socitype
) == SOCI_AI
) || (CHIPTYPE(sih
->socitype
) == SOCI_NAI
))
1512 return ai_corereg_addr(sih
, coreidx
, regoff
);
1519 si_core_disable(si_t
*sih
, uint32 bits
)
1521 if (CHIPTYPE(sih
->socitype
) == SOCI_SB
)
1522 sb_core_disable(sih
, bits
);
1523 else if ((CHIPTYPE(sih
->socitype
) == SOCI_AI
) || (CHIPTYPE(sih
->socitype
) == SOCI_NAI
))
1524 ai_core_disable(sih
, bits
);
1525 else if (CHIPTYPE(sih
->socitype
) == SOCI_UBUS
)
1526 ub_core_disable(sih
, bits
);
1530 si_core_reset(si_t
*sih
, uint32 bits
, uint32 resetbits
)
1532 if (CHIPTYPE(sih
->socitype
) == SOCI_SB
)
1533 sb_core_reset(sih
, bits
, resetbits
);
1534 else if ((CHIPTYPE(sih
->socitype
) == SOCI_AI
) || (CHIPTYPE(sih
->socitype
) == SOCI_NAI
))
1535 ai_core_reset(sih
, bits
, resetbits
);
1536 else if (CHIPTYPE(sih
->socitype
) == SOCI_UBUS
)
1537 ub_core_reset(sih
, bits
, resetbits
);
1540 /** Run bist on current core. Caller needs to take care of core-specific bist hazards */
1542 si_corebist(si_t
*sih
)
1547 /* Read core control flags */
1548 cflags
= si_core_cflags(sih
, 0, 0);
1550 /* Set bist & fgc */
1551 si_core_cflags(sih
, ~0, (SICF_BIST_EN
| SICF_FGC
));
1553 /* Wait for bist done */
1554 SPINWAIT(((si_core_sflags(sih
, 0, 0) & SISF_BIST_DONE
) == 0), 100000);
1556 if (si_core_sflags(sih
, 0, 0) & SISF_BIST_ERROR
)
1557 result
= BCME_ERROR
;
1559 /* Reset core control flags */
1560 si_core_cflags(sih
, 0xffff, cflags
);
1566 si_num_slaveports(si_t
*sih
, uint coreid
)
1568 uint idx
= si_findcoreidx(sih
, coreid
, 0);
1571 if ((CHIPTYPE(sih
->socitype
) == SOCI_AI
))
1572 num
= ai_num_slaveports(sih
, idx
);
1578 si_get_slaveport_addr(si_t
*sih
, uint asidx
, uint core_id
, uint coreunit
)
1580 si_info_t
*sii
= SI_INFO(sih
);
1581 uint origidx
= sii
->curidx
;
1584 if (!((CHIPTYPE(sih
->socitype
) == SOCI_AI
) || (CHIPTYPE(sih
->socitype
) == SOCI_NAI
)))
1587 si_setcore(sih
, core_id
, coreunit
);
1589 addr
= ai_addrspace(sih
, asidx
);
1591 si_setcoreidx(sih
, origidx
);
1598 si_get_d11_slaveport_addr(si_t
*sih
, uint asidx
, uint coreunit
)
1600 si_info_t
*sii
= SI_INFO(sih
);
1601 uint origidx
= sii
->curidx
;
1604 if (!((CHIPTYPE(sih
->socitype
) == SOCI_AI
) || (CHIPTYPE(sih
->socitype
) == SOCI_NAI
)))
1607 si_setcore(sih
, D11_CORE_ID
, coreunit
);
1609 addr
= ai_addrspace(sih
, asidx
);
1611 si_setcoreidx(sih
, origidx
);
1621 case CC_F6_2
: return 2;
1622 case CC_F6_3
: return 3;
1623 case CC_F6_4
: return 4;
1624 case CC_F6_5
: return 5;
1625 case CC_F6_6
: return 6;
1626 case CC_F6_7
: return 7;
1632 * Divide the clock by the divisor with protection for
1636 divide_clock(uint32 clock
, uint32 div
)
1638 return div
? clock
/ div
: 0;
1642 /** calculate the speed the SI would run at given a set of clockcontrol values */
1644 si_clock_rate(uint32 pll_type
, uint32 n
, uint32 m
)
1646 uint32 n1
, n2
, clock
, m1
, m2
, m3
, mc
;
1648 n1
= n
& CN_N1_MASK
;
1649 n2
= (n
& CN_N2_MASK
) >> CN_N2_SHIFT
;
1651 if (pll_type
== PLL_TYPE6
) {
1652 if (m
& CC_T6_MMASK
)
1656 } else if ((pll_type
== PLL_TYPE1
) ||
1657 (pll_type
== PLL_TYPE3
) ||
1658 (pll_type
== PLL_TYPE4
) ||
1659 (pll_type
== PLL_TYPE7
)) {
1662 } else if (pll_type
== PLL_TYPE2
) {
1665 ASSERT((n1
>= 2) && (n1
<= 7));
1666 ASSERT((n2
>= 5) && (n2
<= 23));
1667 } else if (pll_type
== PLL_TYPE5
) {
1671 /* PLL types 3 and 7 use BASE2 (25Mhz) */
1672 if ((pll_type
== PLL_TYPE3
) ||
1673 (pll_type
== PLL_TYPE7
)) {
1674 clock
= CC_CLOCK_BASE2
* n1
* n2
;
1676 clock
= CC_CLOCK_BASE1
* n1
* n2
;
1681 m1
= m
& CC_M1_MASK
;
1682 m2
= (m
& CC_M2_MASK
) >> CC_M2_SHIFT
;
1683 m3
= (m
& CC_M3_MASK
) >> CC_M3_SHIFT
;
1684 mc
= (m
& CC_MC_MASK
) >> CC_MC_SHIFT
;
1686 if ((pll_type
== PLL_TYPE1
) ||
1687 (pll_type
== PLL_TYPE3
) ||
1688 (pll_type
== PLL_TYPE4
) ||
1689 (pll_type
== PLL_TYPE7
)) {
1691 if ((pll_type
== PLL_TYPE1
) || (pll_type
== PLL_TYPE3
))
1698 case CC_MC_BYPASS
: return (clock
);
1699 case CC_MC_M1
: return divide_clock(clock
, m1
);
1700 case CC_MC_M1M2
: return divide_clock(clock
, m1
* m2
);
1701 case CC_MC_M1M2M3
: return divide_clock(clock
, m1
* m2
* m3
);
1702 case CC_MC_M1M3
: return divide_clock(clock
, m1
* m3
);
1703 default: return (0);
1706 ASSERT(pll_type
== PLL_TYPE2
);
1711 ASSERT((m1
>= 2) && (m1
<= 7));
1712 ASSERT((m2
>= 3) && (m2
<= 10));
1713 ASSERT((m3
>= 2) && (m3
<= 7));
1715 if ((mc
& CC_T2MC_M1BYP
) == 0)
1717 if ((mc
& CC_T2MC_M2BYP
) == 0)
1719 if ((mc
& CC_T2MC_M3BYP
) == 0)
1727 * Some chips could have multiple host interfaces, however only one will be active.
1728 * For a given chip. Depending pkgopt and cc_chipst return the active host interface.
1731 si_chip_hostif(si_t
*sih
)
1735 switch (CHIPID(sih
->chip
)) {
1736 case BCM43018_CHIP_ID
:
1737 case BCM43430_CHIP_ID
:
1738 hosti
= CHIP_HOSTIF_SDIOMODE
;
1740 case BCM43012_CHIP_ID
:
1741 hosti
= CHIP_HOSTIF_SDIOMODE
;
1744 hosti
= CHIP_HOSTIF_PCIEMODE
;
1747 case BCM4360_CHIP_ID
:
1748 /* chippkg bit-0 == 0 is PCIE only pkgs
1749 * chippkg bit-0 == 1 has both PCIE and USB cores enabled
1751 if ((sih
->chippkg
& 0x1) && (sih
->chipst
& CST4360_MODE_USB
))
1752 hosti
= CHIP_HOSTIF_USBMODE
;
1754 hosti
= CHIP_HOSTIF_PCIEMODE
;
1758 case BCM4335_CHIP_ID
:
1759 /* TBD: like in 4360, do we need to check pkg? */
1760 if (CST4335_CHIPMODE_USB20D(sih
->chipst
))
1761 hosti
= CHIP_HOSTIF_USBMODE
;
1762 else if (CST4335_CHIPMODE_SDIOD(sih
->chipst
))
1763 hosti
= CHIP_HOSTIF_SDIOMODE
;
1765 hosti
= CHIP_HOSTIF_PCIEMODE
;
1769 if (CST4345_CHIPMODE_USB20D(sih
->chipst
) || CST4345_CHIPMODE_HSIC(sih
->chipst
))
1770 hosti
= CHIP_HOSTIF_USBMODE
;
1771 else if (CST4345_CHIPMODE_SDIOD(sih
->chipst
))
1772 hosti
= CHIP_HOSTIF_SDIOMODE
;
1773 else if (CST4345_CHIPMODE_PCIE(sih
->chipst
))
1774 hosti
= CHIP_HOSTIF_PCIEMODE
;
1777 case BCM4349_CHIP_GRPID
:
1778 case BCM53573_CHIP_GRPID
:
1779 if (CST4349_CHIPMODE_SDIOD(sih
->chipst
))
1780 hosti
= CHIP_HOSTIF_SDIOMODE
;
1781 else if (CST4349_CHIPMODE_PCIE(sih
->chipst
))
1782 hosti
= CHIP_HOSTIF_PCIEMODE
;
1784 case BCM4347_CHIP_ID
:
1785 if (CST4347_CHIPMODE_SDIOD(sih
->chipst
))
1786 hosti
= CHIP_HOSTIF_SDIOMODE
;
1787 else if (CST4347_CHIPMODE_PCIE(sih
->chipst
))
1788 hosti
= CHIP_HOSTIF_PCIEMODE
;
1791 case BCM4350_CHIP_ID
:
1792 case BCM4354_CHIP_ID
:
1793 case BCM43556_CHIP_ID
:
1794 case BCM43558_CHIP_ID
:
1795 case BCM43566_CHIP_ID
:
1796 case BCM43568_CHIP_ID
:
1797 case BCM43569_CHIP_ID
:
1798 case BCM43570_CHIP_ID
:
1799 case BCM4358_CHIP_ID
:
1800 if (CST4350_CHIPMODE_USB20D(sih
->chipst
) ||
1801 CST4350_CHIPMODE_HSIC20D(sih
->chipst
) ||
1802 CST4350_CHIPMODE_USB30D(sih
->chipst
) ||
1803 CST4350_CHIPMODE_USB30D_WL(sih
->chipst
) ||
1804 CST4350_CHIPMODE_HSIC30D(sih
->chipst
))
1805 hosti
= CHIP_HOSTIF_USBMODE
;
1806 else if (CST4350_CHIPMODE_SDIOD(sih
->chipst
))
1807 hosti
= CHIP_HOSTIF_SDIOMODE
;
1808 else if (CST4350_CHIPMODE_PCIE(sih
->chipst
))
1809 hosti
= CHIP_HOSTIF_PCIEMODE
;
1820 /** set chip watchdog reset timer to fire in 'ticks' */
1822 si_watchdog(si_t
*sih
, uint ticks
)
1828 if (PMUCTL_ENAB(sih
) && pmu_wdt
) {
1829 nb
= (CCREV(sih
->ccrev
) < 26) ? 16 : ((CCREV(sih
->ccrev
) >= 37) ? 32 : 24);
1830 /* The mips compiler uses the sllv instruction,
1831 * so we specially handle the 32-bit case.
1836 maxt
= ((1 << nb
) - 1);
1840 else if (ticks
> maxt
)
1842 if (CHIPID(sih
->chip
) == BCM43012_CHIP_ID
) {
1843 PMU_REG_NEW(sih
, min_res_mask
, ~0, DEFAULT_43012_MIN_RES_MASK
);
1844 PMU_REG_NEW(sih
, watchdog_res_mask
, ~0, DEFAULT_43012_MIN_RES_MASK
);
1845 PMU_REG_NEW(sih
, pmustatus
, PST_WDRESET
, PST_WDRESET
);
1846 PMU_REG_NEW(sih
, pmucontrol_ext
, PCTL_EXT_FASTLPO_SWENAB
, 0);
1847 SPINWAIT((PMU_REG(sih
, pmustatus
, 0, 0) & PST_ILPFASTLPO
),
1848 PMU_MAX_TRANSITION_DLY
);
1851 pmu_corereg(sih
, SI_CC_IDX
, pmuwatchdog
, ~0, ticks
);
1853 maxt
= (1 << 28) - 1;
1857 si_corereg(sih
, SI_CC_IDX
, OFFSETOF(chipcregs_t
, watchdog
), ~0, ticks
);
1861 /** trigger watchdog reset after ms milliseconds */
1863 si_watchdog_ms(si_t
*sih
, uint32 ms
)
1865 si_watchdog(sih
, wd_msticks
* ms
);
1868 uint32
si_watchdog_msticks(void)
1874 si_taclear(si_t
*sih
, bool details
)
1881 /** return the slow clock source - LPO, XTAL, or PCI */
1883 si_slowclk_src(si_info_t
*sii
)
1887 ASSERT(SI_FAST(sii
) || si_coreid(&sii
->pub
) == CC_CORE_ID
);
1889 if (CCREV(sii
->pub
.ccrev
) < 6) {
1890 if ((BUSTYPE(sii
->pub
.bustype
) == PCI_BUS
) &&
1891 (OSL_PCI_READ_CONFIG(sii
->osh
, PCI_GPIO_OUT
, sizeof(uint32
)) &
1893 return (SCC_SS_PCI
);
1895 return (SCC_SS_XTAL
);
1896 } else if (CCREV(sii
->pub
.ccrev
) < 10) {
1897 cc
= (chipcregs_t
*)si_setcoreidx(&sii
->pub
, sii
->curidx
);
1899 return (R_REG(sii
->osh
, &cc
->slow_clk_ctl
) & SCC_SS_MASK
);
1900 } else /* Insta-clock */
1901 return (SCC_SS_XTAL
);
1904 /** return the ILP (slowclock) min or max frequency */
1906 si_slowclk_freq(si_info_t
*sii
, bool max_freq
, chipcregs_t
*cc
)
1911 ASSERT(SI_FAST(sii
) || si_coreid(&sii
->pub
) == CC_CORE_ID
);
1913 /* shouldn't be here unless we've established the chip has dynamic clk control */
1914 ASSERT(R_REG(sii
->osh
, &cc
->capabilities
) & CC_CAP_PWR_CTL
);
1916 slowclk
= si_slowclk_src(sii
);
1917 if (CCREV(sii
->pub
.ccrev
) < 6) {
1918 if (slowclk
== SCC_SS_PCI
)
1919 return (max_freq
? (PCIMAXFREQ
/ 64) : (PCIMINFREQ
/ 64));
1921 return (max_freq
? (XTALMAXFREQ
/ 32) : (XTALMINFREQ
/ 32));
1922 } else if (CCREV(sii
->pub
.ccrev
) < 10) {
1924 (((R_REG(sii
->osh
, &cc
->slow_clk_ctl
) & SCC_CD_MASK
) >> SCC_CD_SHIFT
) + 1);
1925 if (slowclk
== SCC_SS_LPO
)
1926 return (max_freq
? LPOMAXFREQ
: LPOMINFREQ
);
1927 else if (slowclk
== SCC_SS_XTAL
)
1928 return (max_freq
? (XTALMAXFREQ
/ div
) : (XTALMINFREQ
/ div
));
1929 else if (slowclk
== SCC_SS_PCI
)
1930 return (max_freq
? (PCIMAXFREQ
/ div
) : (PCIMINFREQ
/ div
));
1934 /* Chipc rev 10 is InstaClock */
1935 div
= R_REG(sii
->osh
, &cc
->system_clk_ctl
) >> SYCC_CD_SHIFT
;
1936 div
= 4 * (div
+ 1);
1937 return (max_freq
? XTALMAXFREQ
: (XTALMINFREQ
/ div
));
1943 si_clkctl_setdelay(si_info_t
*sii
, void *chipcregs
)
1945 chipcregs_t
*cc
= (chipcregs_t
*)chipcregs
;
1946 uint slowmaxfreq
, pll_delay
, slowclk
;
1947 uint pll_on_delay
, fref_sel_delay
;
1949 pll_delay
= PLL_DELAY
;
1951 /* If the slow clock is not sourced by the xtal then add the xtal_on_delay
1952 * since the xtal will also be powered down by dynamic clk control logic.
1955 slowclk
= si_slowclk_src(sii
);
1956 if (slowclk
!= SCC_SS_XTAL
)
1957 pll_delay
+= XTAL_ON_DELAY
;
1959 /* Starting with 4318 it is ILP that is used for the delays */
1960 slowmaxfreq
= si_slowclk_freq(sii
, (CCREV(sii
->pub
.ccrev
) >= 10) ? FALSE
: TRUE
, cc
);
1962 pll_on_delay
= ((slowmaxfreq
* pll_delay
) + 999999) / 1000000;
1963 fref_sel_delay
= ((slowmaxfreq
* FREF_DELAY
) + 999999) / 1000000;
1965 W_REG(sii
->osh
, &cc
->pll_on_delay
, pll_on_delay
);
1966 W_REG(sii
->osh
, &cc
->fref_sel_delay
, fref_sel_delay
);
1969 /** initialize power control delay registers */
1971 si_clkctl_init(si_t
*sih
)
1978 if (!CCCTL_ENAB(sih
))
1982 fast
= SI_FAST(sii
);
1984 origidx
= sii
->curidx
;
1985 if ((cc
= (chipcregs_t
*)si_setcore(sih
, CC_CORE_ID
, 0)) == NULL
)
1987 } else if ((cc
= (chipcregs_t
*)CCREGS_FAST(sii
)) == NULL
)
1991 /* set all Instaclk chip ILP to 1 MHz */
1992 if (CCREV(sih
->ccrev
) >= 10)
1993 SET_REG(sii
->osh
, &cc
->system_clk_ctl
, SYCC_CD_MASK
,
1994 (ILP_DIV_1MHZ
<< SYCC_CD_SHIFT
));
1996 si_clkctl_setdelay(sii
, (void *)(uintptr
)cc
);
2001 si_setcoreidx(sih
, origidx
);
2005 /** change logical "focus" to the gpio core for optimized access */
2007 si_gpiosetcore(si_t
*sih
)
2009 return (si_setcoreidx(sih
, SI_CC_IDX
));
2013 * mask & set gpiocontrol bits.
2014 * If a gpiocontrol bit is set to 0, chipcommon controls the corresponding GPIO pin.
2015 * If a gpiocontrol bit is set to 1, the GPIO pin is no longer a GPIO and becomes dedicated
2016 * to some chip-specific purpose.
2019 si_gpiocontrol(si_t
*sih
, uint32 mask
, uint32 val
, uint8 priority
)
2025 /* gpios could be shared on router platforms
2026 * ignore reservation if it's high priority (e.g., test apps)
2028 if ((priority
!= GPIO_HI_PRIORITY
) &&
2029 (BUSTYPE(sih
->bustype
) == SI_BUS
) && (val
|| mask
)) {
2030 mask
= priority
? (si_gpioreservation
& mask
) :
2031 ((si_gpioreservation
| mask
) & ~(si_gpioreservation
));
2035 regoff
= OFFSETOF(chipcregs_t
, gpiocontrol
);
2036 return (si_corereg(sih
, SI_CC_IDX
, regoff
, mask
, val
));
2039 /** mask&set gpio output enable bits */
2041 si_gpioouten(si_t
*sih
, uint32 mask
, uint32 val
, uint8 priority
)
2047 /* gpios could be shared on router platforms
2048 * ignore reservation if it's high priority (e.g., test apps)
2050 if ((priority
!= GPIO_HI_PRIORITY
) &&
2051 (BUSTYPE(sih
->bustype
) == SI_BUS
) && (val
|| mask
)) {
2052 mask
= priority
? (si_gpioreservation
& mask
) :
2053 ((si_gpioreservation
| mask
) & ~(si_gpioreservation
));
2057 regoff
= OFFSETOF(chipcregs_t
, gpioouten
);
2058 return (si_corereg(sih
, SI_CC_IDX
, regoff
, mask
, val
));
2061 /** mask&set gpio output bits */
2063 si_gpioout(si_t
*sih
, uint32 mask
, uint32 val
, uint8 priority
)
2069 /* gpios could be shared on router platforms
2070 * ignore reservation if it's high priority (e.g., test apps)
2072 if ((priority
!= GPIO_HI_PRIORITY
) &&
2073 (BUSTYPE(sih
->bustype
) == SI_BUS
) && (val
|| mask
)) {
2074 mask
= priority
? (si_gpioreservation
& mask
) :
2075 ((si_gpioreservation
| mask
) & ~(si_gpioreservation
));
2079 regoff
= OFFSETOF(chipcregs_t
, gpioout
);
2080 return (si_corereg(sih
, SI_CC_IDX
, regoff
, mask
, val
));
2083 /** reserve one gpio */
2085 si_gpioreserve(si_t
*sih
, uint32 gpio_bitmask
, uint8 priority
)
2087 /* only cores on SI_BUS share GPIO's and only applcation users need to
2088 * reserve/release GPIO
2090 if ((BUSTYPE(sih
->bustype
) != SI_BUS
) || (!priority
)) {
2091 ASSERT((BUSTYPE(sih
->bustype
) == SI_BUS
) && (priority
));
2094 /* make sure only one bit is set */
2095 if ((!gpio_bitmask
) || ((gpio_bitmask
) & (gpio_bitmask
- 1))) {
2096 ASSERT((gpio_bitmask
) && !((gpio_bitmask
) & (gpio_bitmask
- 1)));
2100 /* already reserved */
2101 if (si_gpioreservation
& gpio_bitmask
)
2103 /* set reservation */
2104 si_gpioreservation
|= gpio_bitmask
;
2106 return si_gpioreservation
;
2112 * releasing the gpio doesn't change the current value on the GPIO last write value
2113 * persists till someone overwrites it.
2116 si_gpiorelease(si_t
*sih
, uint32 gpio_bitmask
, uint8 priority
)
2118 /* only cores on SI_BUS share GPIO's and only applcation users need to
2119 * reserve/release GPIO
2121 if ((BUSTYPE(sih
->bustype
) != SI_BUS
) || (!priority
)) {
2122 ASSERT((BUSTYPE(sih
->bustype
) == SI_BUS
) && (priority
));
2125 /* make sure only one bit is set */
2126 if ((!gpio_bitmask
) || ((gpio_bitmask
) & (gpio_bitmask
- 1))) {
2127 ASSERT((gpio_bitmask
) && !((gpio_bitmask
) & (gpio_bitmask
- 1)));
2131 /* already released */
2132 if (!(si_gpioreservation
& gpio_bitmask
))
2135 /* clear reservation */
2136 si_gpioreservation
&= ~gpio_bitmask
;
2138 return si_gpioreservation
;
2141 /* return the current gpioin register value */
2143 si_gpioin(si_t
*sih
)
2147 regoff
= OFFSETOF(chipcregs_t
, gpioin
);
2148 return (si_corereg(sih
, SI_CC_IDX
, regoff
, 0, 0));
2151 /* mask&set gpio interrupt polarity bits */
2153 si_gpiointpolarity(si_t
*sih
, uint32 mask
, uint32 val
, uint8 priority
)
2157 /* gpios could be shared on router platforms */
2158 if ((BUSTYPE(sih
->bustype
) == SI_BUS
) && (val
|| mask
)) {
2159 mask
= priority
? (si_gpioreservation
& mask
) :
2160 ((si_gpioreservation
| mask
) & ~(si_gpioreservation
));
2164 regoff
= OFFSETOF(chipcregs_t
, gpiointpolarity
);
2165 return (si_corereg(sih
, SI_CC_IDX
, regoff
, mask
, val
));
2168 /* mask&set gpio interrupt mask bits */
2170 si_gpiointmask(si_t
*sih
, uint32 mask
, uint32 val
, uint8 priority
)
2174 /* gpios could be shared on router platforms */
2175 if ((BUSTYPE(sih
->bustype
) == SI_BUS
) && (val
|| mask
)) {
2176 mask
= priority
? (si_gpioreservation
& mask
) :
2177 ((si_gpioreservation
| mask
) & ~(si_gpioreservation
));
2181 regoff
= OFFSETOF(chipcregs_t
, gpiointmask
);
2182 return (si_corereg(sih
, SI_CC_IDX
, regoff
, mask
, val
));
2186 si_gpioeventintmask(si_t
*sih
, uint32 mask
, uint32 val
, uint8 priority
)
2189 /* gpios could be shared on router platforms */
2190 if ((BUSTYPE(sih
->bustype
) == SI_BUS
) && (val
|| mask
)) {
2191 mask
= priority
? (si_gpioreservation
& mask
) :
2192 ((si_gpioreservation
| mask
) & ~(si_gpioreservation
));
2195 regoff
= OFFSETOF(chipcregs_t
, gpioeventintmask
);
2196 return (si_corereg(sih
, SI_CC_IDX
, regoff
, mask
, val
));
2199 /* assign the gpio to an led */
2201 si_gpioled(si_t
*sih
, uint32 mask
, uint32 val
)
2203 if (CCREV(sih
->ccrev
) < 16)
2206 /* gpio led powersave reg */
2207 return (si_corereg(sih
, SI_CC_IDX
, OFFSETOF(chipcregs_t
, gpiotimeroutmask
), mask
, val
));
2210 /* mask&set gpio timer val */
2212 si_gpiotimerval(si_t
*sih
, uint32 mask
, uint32 gpiotimerval
)
2214 if (CCREV(sih
->ccrev
) < 16)
2217 return (si_corereg(sih
, SI_CC_IDX
,
2218 OFFSETOF(chipcregs_t
, gpiotimerval
), mask
, gpiotimerval
));
2222 si_gpiopull(si_t
*sih
, bool updown
, uint32 mask
, uint32 val
)
2226 if (CCREV(sih
->ccrev
) < 20)
2229 offs
= (updown
? OFFSETOF(chipcregs_t
, gpiopulldown
) : OFFSETOF(chipcregs_t
, gpiopullup
));
2230 return (si_corereg(sih
, SI_CC_IDX
, offs
, mask
, val
));
2234 si_gpioevent(si_t
*sih
, uint regtype
, uint32 mask
, uint32 val
)
2238 if (CCREV(sih
->ccrev
) < 11)
2241 if (regtype
== GPIO_REGEVT
)
2242 offs
= OFFSETOF(chipcregs_t
, gpioevent
);
2243 else if (regtype
== GPIO_REGEVT_INTMSK
)
2244 offs
= OFFSETOF(chipcregs_t
, gpioeventintmask
);
2245 else if (regtype
== GPIO_REGEVT_INTPOL
)
2246 offs
= OFFSETOF(chipcregs_t
, gpioeventintpolarity
);
2250 return (si_corereg(sih
, SI_CC_IDX
, offs
, mask
, val
));
2254 si_gpio_int_enable(si_t
*sih
, bool enable
)
2258 if (CCREV(sih
->ccrev
) < 11)
2261 offs
= OFFSETOF(chipcregs_t
, intmask
);
2262 return (si_corereg(sih
, SI_CC_IDX
, offs
, CI_GPIO
, (enable
? CI_GPIO
: 0)));
2265 /** Return the size of the specified SYSMEM bank */
2267 sysmem_banksize(si_info_t
*sii
, sysmemregs_t
*regs
, uint8 idx
)
2269 uint banksize
, bankinfo
;
2272 W_REG(sii
->osh
, ®s
->bankidx
, bankidx
);
2273 bankinfo
= R_REG(sii
->osh
, ®s
->bankinfo
);
2274 banksize
= SYSMEM_BANKINFO_SZBASE
* ((bankinfo
& SYSMEM_BANKINFO_SZMASK
) + 1);
2278 /** Return the RAM size of the SYSMEM core */
2280 si_sysmem_size(si_t
*sih
)
2282 si_info_t
*sii
= SI_INFO(sih
);
2293 /* Block ints and save current core */
2294 INTR_OFF(sii
, intr_val
);
2295 origidx
= si_coreidx(sih
);
2297 /* Switch to SYSMEM core */
2298 if (!(regs
= si_setcore(sih
, SYSMEM_CORE_ID
, 0)))
2301 /* Get info for determining size */
2302 if (!(wasup
= si_iscoreup(sih
)))
2303 si_core_reset(sih
, 0, 0);
2304 coreinfo
= R_REG(sii
->osh
, ®s
->coreinfo
);
2306 /* Number of ROM banks, SW need to skip the ROM banks. */
2307 nrb
= (coreinfo
& SYSMEM_SRCI_ROMNB_MASK
) >> SYSMEM_SRCI_ROMNB_SHIFT
;
2309 nb
= (coreinfo
& SYSMEM_SRCI_SRNB_MASK
) >> SYSMEM_SRCI_SRNB_SHIFT
;
2310 for (i
= 0; i
< nb
; i
++)
2311 memsize
+= sysmem_banksize(sii
, regs
, i
+ nrb
);
2313 si_setcoreidx(sih
, origidx
);
2316 INTR_RESTORE(sii
, intr_val
);
2321 /** Return the size of the specified SOCRAM bank */
2323 socram_banksize(si_info_t
*sii
, sbsocramregs_t
*regs
, uint8 idx
, uint8 mem_type
)
2325 uint banksize
, bankinfo
;
2326 uint bankidx
= idx
| (mem_type
<< SOCRAM_BANKIDX_MEMTYPE_SHIFT
);
2328 ASSERT(mem_type
<= SOCRAM_MEMTYPE_DEVRAM
);
2330 W_REG(sii
->osh
, ®s
->bankidx
, bankidx
);
2331 bankinfo
= R_REG(sii
->osh
, ®s
->bankinfo
);
2332 banksize
= SOCRAM_BANKINFO_SZBASE
* ((bankinfo
& SOCRAM_BANKINFO_SZMASK
) + 1);
2336 void si_socram_set_bankpda(si_t
*sih
, uint32 bankidx
, uint32 bankpda
)
2338 si_info_t
*sii
= SI_INFO(sih
);
2341 sbsocramregs_t
*regs
;
2345 /* Block ints and save current core */
2346 INTR_OFF(sii
, intr_val
);
2347 origidx
= si_coreidx(sih
);
2349 /* Switch to SOCRAM core */
2350 if (!(regs
= si_setcore(sih
, SOCRAM_CORE_ID
, 0)))
2353 if (!(wasup
= si_iscoreup(sih
)))
2354 si_core_reset(sih
, 0, 0);
2356 corerev
= si_corerev(sih
);
2357 if (corerev
>= 16) {
2358 W_REG(sii
->osh
, ®s
->bankidx
, bankidx
);
2359 W_REG(sii
->osh
, ®s
->bankpda
, bankpda
);
2362 /* Return to previous state and core */
2364 si_core_disable(sih
, 0);
2365 si_setcoreidx(sih
, origidx
);
2368 INTR_RESTORE(sii
, intr_val
);
2372 si_socdevram(si_t
*sih
, bool set
, uint8
*enable
, uint8
*protect
, uint8
*remap
)
2374 si_info_t
*sii
= SI_INFO(sih
);
2377 sbsocramregs_t
*regs
;
2381 /* Block ints and save current core */
2382 INTR_OFF(sii
, intr_val
);
2383 origidx
= si_coreidx(sih
);
2386 *enable
= *protect
= *remap
= 0;
2388 /* Switch to SOCRAM core */
2389 if (!(regs
= si_setcore(sih
, SOCRAM_CORE_ID
, 0)))
2392 /* Get info for determining size */
2393 if (!(wasup
= si_iscoreup(sih
)))
2394 si_core_reset(sih
, 0, 0);
2396 corerev
= si_corerev(sih
);
2397 if (corerev
>= 10) {
2401 uint32 bankidx
, bankinfo
;
2403 extcinfo
= R_REG(sii
->osh
, ®s
->extracoreinfo
);
2404 nb
= ((extcinfo
& SOCRAM_DEVRAMBANK_MASK
) >> SOCRAM_DEVRAMBANK_SHIFT
);
2405 for (i
= 0; i
< nb
; i
++) {
2406 bankidx
= i
| (SOCRAM_MEMTYPE_DEVRAM
<< SOCRAM_BANKIDX_MEMTYPE_SHIFT
);
2407 W_REG(sii
->osh
, ®s
->bankidx
, bankidx
);
2408 bankinfo
= R_REG(sii
->osh
, ®s
->bankinfo
);
2410 bankinfo
&= ~SOCRAM_BANKINFO_DEVRAMSEL_MASK
;
2411 bankinfo
&= ~SOCRAM_BANKINFO_DEVRAMPRO_MASK
;
2412 bankinfo
&= ~SOCRAM_BANKINFO_DEVRAMREMAP_MASK
;
2414 bankinfo
|= (1 << SOCRAM_BANKINFO_DEVRAMSEL_SHIFT
);
2416 bankinfo
|= (1 << SOCRAM_BANKINFO_DEVRAMPRO_SHIFT
);
2417 if ((corerev
>= 16) && *remap
)
2419 (1 << SOCRAM_BANKINFO_DEVRAMREMAP_SHIFT
);
2421 W_REG(sii
->osh
, ®s
->bankinfo
, bankinfo
);
2422 } else if (i
== 0) {
2423 if (bankinfo
& SOCRAM_BANKINFO_DEVRAMSEL_MASK
) {
2425 if (bankinfo
& SOCRAM_BANKINFO_DEVRAMPRO_MASK
)
2427 if (bankinfo
& SOCRAM_BANKINFO_DEVRAMREMAP_MASK
)
2434 /* Return to previous state and core */
2436 si_core_disable(sih
, 0);
2437 si_setcoreidx(sih
, origidx
);
2440 INTR_RESTORE(sii
, intr_val
);
2444 si_socdevram_remap_isenb(si_t
*sih
)
2446 si_info_t
*sii
= SI_INFO(sih
);
2449 sbsocramregs_t
*regs
;
2450 bool wasup
, remap
= FALSE
;
2455 uint32 bankidx
, bankinfo
;
2457 /* Block ints and save current core */
2458 INTR_OFF(sii
, intr_val
);
2459 origidx
= si_coreidx(sih
);
2461 /* Switch to SOCRAM core */
2462 if (!(regs
= si_setcore(sih
, SOCRAM_CORE_ID
, 0)))
2465 /* Get info for determining size */
2466 if (!(wasup
= si_iscoreup(sih
)))
2467 si_core_reset(sih
, 0, 0);
2469 corerev
= si_corerev(sih
);
2470 if (corerev
>= 16) {
2471 extcinfo
= R_REG(sii
->osh
, ®s
->extracoreinfo
);
2472 nb
= ((extcinfo
& SOCRAM_DEVRAMBANK_MASK
) >> SOCRAM_DEVRAMBANK_SHIFT
);
2473 for (i
= 0; i
< nb
; i
++) {
2474 bankidx
= i
| (SOCRAM_MEMTYPE_DEVRAM
<< SOCRAM_BANKIDX_MEMTYPE_SHIFT
);
2475 W_REG(sii
->osh
, ®s
->bankidx
, bankidx
);
2476 bankinfo
= R_REG(sii
->osh
, ®s
->bankinfo
);
2477 if (bankinfo
& SOCRAM_BANKINFO_DEVRAMREMAP_MASK
) {
2484 /* Return to previous state and core */
2486 si_core_disable(sih
, 0);
2487 si_setcoreidx(sih
, origidx
);
2490 INTR_RESTORE(sii
, intr_val
);
2495 si_socdevram_pkg(si_t
*sih
)
2497 if (si_socdevram_size(sih
) > 0)
2504 si_socdevram_size(si_t
*sih
)
2506 si_info_t
*sii
= SI_INFO(sih
);
2510 sbsocramregs_t
*regs
;
2514 /* Block ints and save current core */
2515 INTR_OFF(sii
, intr_val
);
2516 origidx
= si_coreidx(sih
);
2518 /* Switch to SOCRAM core */
2519 if (!(regs
= si_setcore(sih
, SOCRAM_CORE_ID
, 0)))
2522 /* Get info for determining size */
2523 if (!(wasup
= si_iscoreup(sih
)))
2524 si_core_reset(sih
, 0, 0);
2526 corerev
= si_corerev(sih
);
2527 if (corerev
>= 10) {
2532 extcinfo
= R_REG(sii
->osh
, ®s
->extracoreinfo
);
2533 nb
= (((extcinfo
& SOCRAM_DEVRAMBANK_MASK
) >> SOCRAM_DEVRAMBANK_SHIFT
));
2534 for (i
= 0; i
< nb
; i
++)
2535 memsize
+= socram_banksize(sii
, regs
, i
, SOCRAM_MEMTYPE_DEVRAM
);
2538 /* Return to previous state and core */
2540 si_core_disable(sih
, 0);
2541 si_setcoreidx(sih
, origidx
);
2544 INTR_RESTORE(sii
, intr_val
);
2550 si_socdevram_remap_size(si_t
*sih
)
2552 si_info_t
*sii
= SI_INFO(sih
);
2555 uint32 memsize
= 0, banksz
;
2556 sbsocramregs_t
*regs
;
2562 uint32 bankidx
, bankinfo
;
2564 /* Block ints and save current core */
2565 INTR_OFF(sii
, intr_val
);
2566 origidx
= si_coreidx(sih
);
2568 /* Switch to SOCRAM core */
2569 if (!(regs
= si_setcore(sih
, SOCRAM_CORE_ID
, 0)))
2572 /* Get info for determining size */
2573 if (!(wasup
= si_iscoreup(sih
)))
2574 si_core_reset(sih
, 0, 0);
2576 corerev
= si_corerev(sih
);
2577 if (corerev
>= 16) {
2578 extcinfo
= R_REG(sii
->osh
, ®s
->extracoreinfo
);
2579 nb
= (((extcinfo
& SOCRAM_DEVRAMBANK_MASK
) >> SOCRAM_DEVRAMBANK_SHIFT
));
2582 * FIX: A0 Issue: Max addressable is 512KB, instead 640KB
2583 * Only four banks are accessible to ARM
2585 if ((corerev
== 16) && (nb
== 5))
2588 for (i
= 0; i
< nb
; i
++) {
2589 bankidx
= i
| (SOCRAM_MEMTYPE_DEVRAM
<< SOCRAM_BANKIDX_MEMTYPE_SHIFT
);
2590 W_REG(sii
->osh
, ®s
->bankidx
, bankidx
);
2591 bankinfo
= R_REG(sii
->osh
, ®s
->bankinfo
);
2592 if (bankinfo
& SOCRAM_BANKINFO_DEVRAMREMAP_MASK
) {
2593 banksz
= socram_banksize(sii
, regs
, i
, SOCRAM_MEMTYPE_DEVRAM
);
2596 /* Account only consecutive banks for now */
2602 /* Return to previous state and core */
2604 si_core_disable(sih
, 0);
2605 si_setcoreidx(sih
, origidx
);
2608 INTR_RESTORE(sii
, intr_val
);
2613 /** Return the RAM size of the SOCRAM core */
2615 si_socram_size(si_t
*sih
)
2617 si_info_t
*sii
= SI_INFO(sih
);
2621 sbsocramregs_t
*regs
;
2627 /* Block ints and save current core */
2628 INTR_OFF(sii
, intr_val
);
2629 origidx
= si_coreidx(sih
);
2631 /* Switch to SOCRAM core */
2632 if (!(regs
= si_setcore(sih
, SOCRAM_CORE_ID
, 0)))
2635 /* Get info for determining size */
2636 if (!(wasup
= si_iscoreup(sih
)))
2637 si_core_reset(sih
, 0, 0);
2638 corerev
= si_corerev(sih
);
2639 coreinfo
= R_REG(sii
->osh
, ®s
->coreinfo
);
2641 /* Calculate size from coreinfo based on rev */
2643 memsize
= 1 << (16 + (coreinfo
& SRCI_MS0_MASK
));
2644 else if (corerev
< 3) {
2645 memsize
= 1 << (SR_BSZ_BASE
+ (coreinfo
& SRCI_SRBSZ_MASK
));
2646 memsize
*= (coreinfo
& SRCI_SRNB_MASK
) >> SRCI_SRNB_SHIFT
;
2647 } else if ((corerev
<= 7) || (corerev
== 12)) {
2648 uint nb
= (coreinfo
& SRCI_SRNB_MASK
) >> SRCI_SRNB_SHIFT
;
2649 uint bsz
= (coreinfo
& SRCI_SRBSZ_MASK
);
2650 uint lss
= (coreinfo
& SRCI_LSS_MASK
) >> SRCI_LSS_SHIFT
;
2653 memsize
= nb
* (1 << (bsz
+ SR_BSZ_BASE
));
2655 memsize
+= (1 << ((lss
- 1) + SR_BSZ_BASE
));
2659 /* length of SRAM Banks increased for corerev greater than 23 */
2660 if (corerev
>= 23) {
2661 nb
= (coreinfo
& (SRCI_SRNB_MASK
| SRCI_SRNB_MASK_EXT
)) >> SRCI_SRNB_SHIFT
;
2663 nb
= (coreinfo
& SRCI_SRNB_MASK
) >> SRCI_SRNB_SHIFT
;
2665 for (i
= 0; i
< nb
; i
++)
2666 memsize
+= socram_banksize(sii
, regs
, i
, SOCRAM_MEMTYPE_RAM
);
2669 /* Return to previous state and core */
2671 si_core_disable(sih
, 0);
2672 si_setcoreidx(sih
, origidx
);
2675 INTR_RESTORE(sii
, intr_val
);
2681 /** Return the TCM-RAM size of the ARMCR4 core. */
2683 si_tcm_size(si_t
*sih
)
2685 si_info_t
*sii
= SI_INFO(sih
);
2688 volatile uint8
*regs
;
2697 volatile uint32
*arm_cap_reg
;
2698 volatile uint32
*arm_bidx
;
2699 volatile uint32
*arm_binfo
;
2701 /* Block ints and save current core */
2702 INTR_OFF(sii
, intr_val
);
2703 origidx
= si_coreidx(sih
);
2705 /* Switch to CR4 core */
2706 if (!(regs
= si_setcore(sih
, ARMCR4_CORE_ID
, 0)))
2709 /* Get info for determining size. If in reset, come out of reset,
2710 * but remain in halt
2712 if (!(wasup
= si_iscoreup(sih
)))
2713 si_core_reset(sih
, SICF_CPUHALT
, SICF_CPUHALT
);
2715 arm_cap_reg
= (volatile uint32
*)(regs
+ SI_CR4_CAP
);
2716 corecap
= R_REG(sii
->osh
, arm_cap_reg
);
2718 nab
= (corecap
& ARMCR4_TCBANB_MASK
) >> ARMCR4_TCBANB_SHIFT
;
2719 nbb
= (corecap
& ARMCR4_TCBBNB_MASK
) >> ARMCR4_TCBBNB_SHIFT
;
2722 arm_bidx
= (volatile uint32
*)(regs
+ SI_CR4_BANKIDX
);
2723 arm_binfo
= (volatile uint32
*)(regs
+ SI_CR4_BANKINFO
);
2724 for (idx
= 0; idx
< totb
; idx
++) {
2725 W_REG(sii
->osh
, arm_bidx
, idx
);
2727 bxinfo
= R_REG(sii
->osh
, arm_binfo
);
2728 memsize
+= ((bxinfo
& ARMCR4_BSZ_MASK
) + 1) * ARMCR4_BSZ_MULT
;
2731 /* Return to previous state and core */
2733 si_core_disable(sih
, 0);
2734 si_setcoreidx(sih
, origidx
);
2737 INTR_RESTORE(sii
, intr_val
);
2743 si_has_flops(si_t
*sih
)
2745 uint origidx
, cr4_rev
;
2747 /* Find out CR4 core revision */
2748 origidx
= si_coreidx(sih
);
2749 if (si_setcore(sih
, ARMCR4_CORE_ID
, 0)) {
2750 cr4_rev
= si_corerev(sih
);
2751 si_setcoreidx(sih
, origidx
);
2753 if (cr4_rev
== 1 || cr4_rev
>= 3)
2760 si_socram_srmem_size(si_t
*sih
)
2762 si_info_t
*sii
= SI_INFO(sih
);
2766 sbsocramregs_t
*regs
;
2772 if ((CHIPID(sih
->chip
) == BCM4334_CHIP_ID
) && (CHIPREV(sih
->chiprev
) < 2)) {
2776 if (CHIPID(sih
->chip
) == BCM43430_CHIP_ID
||
2777 CHIPID(sih
->chip
) == BCM43018_CHIP_ID
) {
2781 /* Block ints and save current core */
2782 INTR_OFF(sii
, intr_val
);
2783 origidx
= si_coreidx(sih
);
2785 /* Switch to SOCRAM core */
2786 if (!(regs
= si_setcore(sih
, SOCRAM_CORE_ID
, 0)))
2789 /* Get info for determining size */
2790 if (!(wasup
= si_iscoreup(sih
)))
2791 si_core_reset(sih
, 0, 0);
2792 corerev
= si_corerev(sih
);
2793 coreinfo
= R_REG(sii
->osh
, ®s
->coreinfo
);
2795 /* Calculate size from coreinfo based on rev */
2796 if (corerev
>= 16) {
2798 uint nb
= (coreinfo
& SRCI_SRNB_MASK
) >> SRCI_SRNB_SHIFT
;
2799 for (i
= 0; i
< nb
; i
++) {
2800 W_REG(sii
->osh
, ®s
->bankidx
, i
);
2801 if (R_REG(sii
->osh
, ®s
->bankinfo
) & SOCRAM_BANKINFO_RETNTRAM_MASK
)
2802 memsize
+= socram_banksize(sii
, regs
, i
, SOCRAM_MEMTYPE_RAM
);
2806 /* Return to previous state and core */
2808 si_core_disable(sih
, 0);
2809 si_setcoreidx(sih
, origidx
);
2812 INTR_RESTORE(sii
, intr_val
);
2818 #if !defined(_CFEZ_) || defined(CFG_WL)
2820 si_btcgpiowar(si_t
*sih
)
2822 si_info_t
*sii
= SI_INFO(sih
);
2827 /* Make sure that there is ChipCommon core present &&
2828 * UART_TX is strapped to 1
2830 if (!(sih
->cccaps
& CC_CAP_UARTGPIO
))
2833 /* si_corereg cannot be used as we have to guarantee 8-bit read/writes */
2834 INTR_OFF(sii
, intr_val
);
2836 origidx
= si_coreidx(sih
);
2838 cc
= (chipcregs_t
*)si_setcore(sih
, CC_CORE_ID
, 0);
2841 W_REG(sii
->osh
, &cc
->uart0mcr
, R_REG(sii
->osh
, &cc
->uart0mcr
) | 0x04);
2843 /* restore the original index */
2844 si_setcoreidx(sih
, origidx
);
2846 INTR_RESTORE(sii
, intr_val
);
2850 si_chipcontrl_btshd0_4331(si_t
*sih
, bool on
)
2852 si_info_t
*sii
= SI_INFO(sih
);
2858 INTR_OFF(sii
, intr_val
);
2860 origidx
= si_coreidx(sih
);
2862 if ((cc
= (chipcregs_t
*)si_setcore(sih
, CC_CORE_ID
, 0)) == NULL
) {
2863 SI_ERROR(("%s: Failed to find CORE ID!\n", __FUNCTION__
));
2867 val
= R_REG(sii
->osh
, &cc
->chipcontrol
);
2869 /* bt_shd0 controls are same for 4331 chiprevs 0 and 1, packages 12x9 and 12x12 */
2871 /* Enable bt_shd0 on gpio4: */
2872 val
|= (CCTRL4331_BT_SHD0_ON_GPIO4
);
2873 W_REG(sii
->osh
, &cc
->chipcontrol
, val
);
2875 val
&= ~(CCTRL4331_BT_SHD0_ON_GPIO4
);
2876 W_REG(sii
->osh
, &cc
->chipcontrol
, val
);
2879 /* restore the original index */
2880 si_setcoreidx(sih
, origidx
);
2882 INTR_RESTORE(sii
, intr_val
);
2886 si_chipcontrl_restore(si_t
*sih
, uint32 val
)
2888 si_info_t
*sii
= SI_INFO(sih
);
2890 uint origidx
= si_coreidx(sih
);
2892 if ((cc
= (chipcregs_t
*)si_setcore(sih
, CC_CORE_ID
, 0)) == NULL
) {
2893 SI_ERROR(("%s: Failed to find CORE ID!\n", __FUNCTION__
));
2896 W_REG(sii
->osh
, &cc
->chipcontrol
, val
);
2897 si_setcoreidx(sih
, origidx
);
2901 si_chipcontrl_read(si_t
*sih
)
2903 si_info_t
*sii
= SI_INFO(sih
);
2905 uint origidx
= si_coreidx(sih
);
2908 if ((cc
= (chipcregs_t
*)si_setcore(sih
, CC_CORE_ID
, 0)) == NULL
) {
2909 SI_ERROR(("%s: Failed to find CORE ID!\n", __FUNCTION__
));
2912 val
= R_REG(sii
->osh
, &cc
->chipcontrol
);
2913 si_setcoreidx(sih
, origidx
);
2918 si_chipcontrl_epa4331(si_t
*sih
, bool on
)
2920 si_info_t
*sii
= SI_INFO(sih
);
2922 uint origidx
= si_coreidx(sih
);
2925 if ((cc
= (chipcregs_t
*)si_setcore(sih
, CC_CORE_ID
, 0)) == NULL
) {
2926 SI_ERROR(("%s: Failed to find CORE ID!\n", __FUNCTION__
));
2929 val
= R_REG(sii
->osh
, &cc
->chipcontrol
);
2932 if (sih
->chippkg
== 9 || sih
->chippkg
== 0xb) {
2933 val
|= (CCTRL4331_EXTPA_EN
| CCTRL4331_EXTPA_ON_GPIO2_5
);
2934 /* Ext PA Controls for 4331 12x9 Package */
2935 W_REG(sii
->osh
, &cc
->chipcontrol
, val
);
2937 /* Ext PA Controls for 4331 12x12 Package */
2938 if (CHIPREV(sih
->chiprev
) > 0) {
2939 W_REG(sii
->osh
, &cc
->chipcontrol
, val
|
2940 (CCTRL4331_EXTPA_EN
) | (CCTRL4331_EXTPA_EN2
));
2942 W_REG(sii
->osh
, &cc
->chipcontrol
, val
| (CCTRL4331_EXTPA_EN
));
2946 val
&= ~(CCTRL4331_EXTPA_EN
| CCTRL4331_EXTPA_EN2
| CCTRL4331_EXTPA_ON_GPIO2_5
);
2947 W_REG(sii
->osh
, &cc
->chipcontrol
, val
);
2950 si_setcoreidx(sih
, origidx
);
2953 /** switch muxed pins, on: SROM, off: FEMCTRL. Called for a family of ac chips, not just 4360. */
2955 si_chipcontrl_srom4360(si_t
*sih
, bool on
)
2957 si_info_t
*sii
= SI_INFO(sih
);
2959 uint origidx
= si_coreidx(sih
);
2962 if ((cc
= (chipcregs_t
*)si_setcore(sih
, CC_CORE_ID
, 0)) == NULL
) {
2963 SI_ERROR(("%s: Failed to find CORE ID!\n", __FUNCTION__
));
2966 val
= R_REG(sii
->osh
, &cc
->chipcontrol
);
2969 val
&= ~(CCTRL4360_SECI_MODE
|
2970 CCTRL4360_BTSWCTRL_MODE
|
2971 CCTRL4360_EXTRA_FEMCTRL_MODE
|
2972 CCTRL4360_BT_LGCY_MODE
|
2973 CCTRL4360_CORE2FEMCTRL4_ON
);
2975 W_REG(sii
->osh
, &cc
->chipcontrol
, val
);
2979 si_setcoreidx(sih
, origidx
);
2983 si_clk_srom4365(si_t
*sih
)
2985 si_info_t
*sii
= SI_INFO(sih
);
2987 uint origidx
= si_coreidx(sih
);
2990 if ((cc
= (chipcregs_t
*)si_setcore(sih
, CC_CORE_ID
, 0)) == NULL
) {
2991 SI_ERROR(("%s: Failed to find CORE ID!\n", __FUNCTION__
));
2994 val
= R_REG(sii
->osh
, &cc
->clkdiv2
);
2995 W_REG(sii
->osh
, &cc
->clkdiv2
, ((val
&~0xf) | 0x4));
2997 si_setcoreidx(sih
, origidx
);
3001 si_chipcontrl_epa4331_wowl(si_t
*sih
, bool enter_wowl
)
3009 sel_chip
= (CHIPID(sih
->chip
) == BCM4331_CHIP_ID
) ||
3010 (CHIPID(sih
->chip
) == BCM43431_CHIP_ID
);
3011 sel_chip
&= ((sih
->chippkg
== 9 || sih
->chippkg
== 0xb));
3017 origidx
= si_coreidx(sih
);
3019 if ((cc
= (chipcregs_t
*)si_setcore(sih
, CC_CORE_ID
, 0)) == NULL
) {
3020 SI_ERROR(("%s: Failed to find CORE ID!\n", __FUNCTION__
));
3024 val
= R_REG(sii
->osh
, &cc
->chipcontrol
);
3027 val
|= CCTRL4331_EXTPA_EN
;
3028 W_REG(sii
->osh
, &cc
->chipcontrol
, val
);
3030 val
|= (CCTRL4331_EXTPA_EN
| CCTRL4331_EXTPA_ON_GPIO2_5
);
3031 W_REG(sii
->osh
, &cc
->chipcontrol
, val
);
3033 si_setcoreidx(sih
, origidx
);
3038 si_pll_reset(si_t
*sih
)
3045 /** Enable BT-COEX & Ex-PA for 4313 */
3047 si_epa_4313war(si_t
*sih
)
3049 si_info_t
*sii
= SI_INFO(sih
);
3051 uint origidx
= si_coreidx(sih
);
3053 if ((cc
= (chipcregs_t
*)si_setcore(sih
, CC_CORE_ID
, 0)) == NULL
) {
3054 SI_ERROR(("%s: Failed to find CORE ID!\n", __FUNCTION__
));
3059 W_REG(sii
->osh
, &cc
->gpiocontrol
,
3060 R_REG(sii
->osh
, &cc
->gpiocontrol
) | GPIO_CTRL_EPA_EN_MASK
);
3062 si_setcoreidx(sih
, origidx
);
3066 si_clk_pmu_htavail_set(si_t
*sih
, bool set_clear
)
3071 si_pmu_avb_clk_set(si_t
*sih
, osl_t
*osh
, bool set_flag
)
3075 /** Re-enable synth_pwrsw resource in min_res_mask for 4313 */
3077 si_pmu_synth_pwrsw_4313_war(si_t
*sih
)
3081 /** WL/BT control for 4313 btcombo boards >= P250 */
3083 si_btcombo_p250_4313_war(si_t
*sih
)
3085 si_info_t
*sii
= SI_INFO(sih
);
3087 uint origidx
= si_coreidx(sih
);
3089 if ((cc
= (chipcregs_t
*)si_setcore(sih
, CC_CORE_ID
, 0)) == NULL
) {
3090 SI_ERROR(("%s: Failed to find CORE ID!\n", __FUNCTION__
));
3093 W_REG(sii
->osh
, &cc
->gpiocontrol
,
3094 R_REG(sii
->osh
, &cc
->gpiocontrol
) | GPIO_CTRL_5_6_EN_MASK
);
3096 W_REG(sii
->osh
, &cc
->gpioouten
,
3097 R_REG(sii
->osh
, &cc
->gpioouten
) | GPIO_CTRL_5_6_EN_MASK
);
3099 si_setcoreidx(sih
, origidx
);
3102 si_btc_enable_chipcontrol(si_t
*sih
)
3104 si_info_t
*sii
= SI_INFO(sih
);
3106 uint origidx
= si_coreidx(sih
);
3108 if ((cc
= (chipcregs_t
*)si_setcore(sih
, CC_CORE_ID
, 0)) == NULL
) {
3109 SI_ERROR(("%s: Failed to find CORE ID!\n", __FUNCTION__
));
3114 W_REG(sii
->osh
, &cc
->chipcontrol
,
3115 R_REG(sii
->osh
, &cc
->chipcontrol
) | CC_BTCOEX_EN_MASK
);
3117 si_setcoreidx(sih
, origidx
);
3120 si_btcombo_43228_war(si_t
*sih
)
3122 si_info_t
*sii
= SI_INFO(sih
);
3124 uint origidx
= si_coreidx(sih
);
3126 if ((cc
= (chipcregs_t
*)si_setcore(sih
, CC_CORE_ID
, 0)) == NULL
) {
3127 SI_ERROR(("%s: Failed to find CORE ID!\n", __FUNCTION__
));
3131 W_REG(sii
->osh
, &cc
->gpioouten
, GPIO_CTRL_7_6_EN_MASK
);
3132 W_REG(sii
->osh
, &cc
->gpioout
, GPIO_OUT_7_EN_MASK
);
3134 si_setcoreidx(sih
, origidx
);
3137 /** cache device removed state */
3138 void si_set_device_removed(si_t
*sih
, bool status
)
3140 si_info_t
*sii
= SI_INFO(sih
);
3142 sii
->device_removed
= status
;
3145 /** check if the device is removed */
3147 si_deviceremoved(si_t
*sih
)
3150 si_info_t
*sii
= SI_INFO(sih
);
3152 if (sii
->device_removed
) {
3156 switch (BUSTYPE(sih
->bustype
)) {
3158 ASSERT(SI_INFO(sih
)->osh
!= NULL
);
3159 w
= OSL_PCI_READ_CONFIG(SI_INFO(sih
)->osh
, PCI_CFG_VID
, sizeof(uint32
));
3160 if ((w
& 0xFFFF) != VENDOR_BROADCOM
)
3168 si_is_warmboot(void)
3172 return (boot_type
== WARM_BOOT
);
3179 si_is_sprom_available(si_t
*sih
)
3181 if (CCREV(sih
->ccrev
) >= 31) {
3187 if ((sih
->cccaps
& CC_CAP_SROM
) == 0)
3191 origidx
= sii
->curidx
;
3192 cc
= si_setcoreidx(sih
, SI_CC_IDX
);
3194 sromctrl
= R_REG(sii
->osh
, &cc
->sromcontrol
);
3195 si_setcoreidx(sih
, origidx
);
3196 return (sromctrl
& SRC_PRESENT
);
3199 switch (CHIPID(sih
->chip
)) {
3200 case BCM43018_CHIP_ID
:
3201 case BCM43430_CHIP_ID
:
3203 case BCM4336_CHIP_ID
:
3204 case BCM43362_CHIP_ID
:
3205 return (sih
->chipst
& CST4336_SPROM_PRESENT
) != 0;
3206 case BCM4330_CHIP_ID
:
3207 return (sih
->chipst
& CST4330_SPROM_PRESENT
) != 0;
3208 case BCM4313_CHIP_ID
:
3209 return (sih
->chipst
& CST4313_SPROM_PRESENT
) != 0;
3210 case BCM4331_CHIP_ID
:
3211 case BCM43431_CHIP_ID
:
3212 return (sih
->chipst
& CST4331_SPROM_PRESENT
) != 0;
3213 case BCM43239_CHIP_ID
:
3214 return ((sih
->chipst
& CST43239_SPROM_MASK
) &&
3215 !(sih
->chipst
& CST43239_SFLASH_MASK
));
3216 case BCM4324_CHIP_ID
:
3217 case BCM43242_CHIP_ID
:
3218 return ((sih
->chipst
& CST4324_SPROM_MASK
) &&
3219 !(sih
->chipst
& CST4324_SFLASH_MASK
));
3220 case BCM4335_CHIP_ID
:
3222 return ((sih
->chipst
& CST4335_SPROM_MASK
) &&
3223 !(sih
->chipst
& CST4335_SFLASH_MASK
));
3224 case BCM4349_CHIP_GRPID
:
3225 return (sih
->chipst
& CST4349_SPROM_PRESENT
) != 0;
3226 case BCM53573_CHIP_GRPID
:
3227 return FALSE
; /* SPROM PRESENT is not defined for 53573 as of now */
3228 case BCM4347_CHIP_ID
:
3229 return (sih
->chipst
& CST4347_SPROM_PRESENT
) != 0;
3231 case BCM4350_CHIP_ID
:
3232 case BCM4354_CHIP_ID
:
3233 case BCM43556_CHIP_ID
:
3234 case BCM43558_CHIP_ID
:
3235 case BCM43566_CHIP_ID
:
3236 case BCM43568_CHIP_ID
:
3237 case BCM43569_CHIP_ID
:
3238 case BCM43570_CHIP_ID
:
3239 case BCM4358_CHIP_ID
:
3240 return (sih
->chipst
& CST4350_SPROM_PRESENT
) != 0;
3242 return (sih
->chipst
& CST43602_SPROM_PRESENT
) != 0;
3243 case BCM43131_CHIP_ID
:
3244 case BCM43217_CHIP_ID
:
3245 case BCM43227_CHIP_ID
:
3246 case BCM43228_CHIP_ID
:
3247 case BCM43428_CHIP_ID
:
3248 return (sih
->chipst
& CST43228_OTP_PRESENT
) != CST43228_OTP_PRESENT
;
3249 case BCM43012_CHIP_ID
:
3257 uint32
si_get_sromctl(si_t
*sih
)
3260 uint origidx
= si_coreidx(sih
);
3262 osl_t
*osh
= si_osh(sih
);
3264 cc
= si_setcoreidx(sih
, SI_CC_IDX
);
3265 ASSERT((uintptr
)cc
);
3267 sromctl
= R_REG(osh
, &cc
->sromcontrol
);
3269 /* return to the original core */
3270 si_setcoreidx(sih
, origidx
);
3274 int si_set_sromctl(si_t
*sih
, uint32 value
)
3277 uint origidx
= si_coreidx(sih
);
3278 osl_t
*osh
= si_osh(sih
);
3281 cc
= si_setcoreidx(sih
, SI_CC_IDX
);
3282 ASSERT((uintptr
)cc
);
3284 /* get chipcommon rev */
3285 if (si_corerev(sih
) >= 32) {
3286 /* SpromCtrl is only accessible if CoreCapabilities.SpromSupported and
3287 * SpromPresent is 1.
3289 if ((R_REG(osh
, &cc
->capabilities
) & CC_CAP_SROM
) != 0 &&
3290 (R_REG(osh
, &cc
->sromcontrol
) & SRC_PRESENT
)) {
3291 W_REG(osh
, &cc
->sromcontrol
, value
);
3293 ret
= BCME_NODEVICE
;
3296 ret
= BCME_UNSUPPORTED
;
3299 /* return to the original core */
3300 si_setcoreidx(sih
, origidx
);
3306 si_core_wrapperreg(si_t
*sih
, uint32 coreidx
, uint32 offset
, uint32 mask
, uint32 val
)
3308 uint origidx
, intr_val
= 0;
3310 si_info_t
*sii
= SI_INFO(sih
);
3312 origidx
= si_coreidx(sih
);
3314 INTR_OFF(sii
, intr_val
);
3315 si_setcoreidx(sih
, coreidx
);
3317 ret_val
= si_wrapperreg(sih
, offset
, mask
, val
);
3319 /* return to the original core */
3320 si_setcoreidx(sih
, origidx
);
3321 INTR_RESTORE(sii
, intr_val
);
3326 /* cleanup the timer from the host when ARM is been halted
3327 * without a chance for ARM cleanup its resources
3328 * If left not cleanup, Intr from a software timer can still
3329 * request HT clk when ARM is halted.
3332 si_pmu_res_req_timer_clr(si_t
*sih
)
3336 mask
= PRRT_REQ_ACTIVE
| PRRT_INTEN
| PRRT_HT_REQ
;
3338 /* clear mask bits */
3339 pmu_corereg(sih
, SI_CC_IDX
, res_req_timer
, mask
, 0);
3340 /* readback to ensure write completes */
3341 return pmu_corereg(sih
, SI_CC_IDX
, res_req_timer
, 0, 0);
3344 /** turn on/off rfldo */
3346 si_pmu_rfldo(si_t
*sih
, bool on
)
3351 #ifdef SURVIVE_PERST_ENAB
3353 si_pcie_survive_perst(si_t
*sih
, uint32 mask
, uint32 val
)
3362 return pcie_survive_perst(sii
->pch
, mask
, val
);
3366 si_watchdog_reset(si_t
*sih
)
3370 /* issue a watchdog reset */
3371 pmu_corereg(sih
, SI_CC_IDX
, pmuwatchdog
, 2, 2);
3372 /* do busy wait for 20ms */
3373 for (i
= 0; i
< 2000; i
++) {
3377 #endif /* SURVIVE_PERST_ENAB */
3380 si_survive_perst_war(si_t
*sih
, bool reset
, uint32 sperst_mask
, uint32 sperst_val
)
3382 #ifdef SURVIVE_PERST_ENAB
3383 if (BUSTYPE(sih
->bustype
) != PCI_BUS
)
3386 if ((CHIPID(sih
->chip
) != BCM4360_CHIP_ID
&& CHIPID(sih
->chip
) != BCM4352_CHIP_ID
) ||
3387 (CHIPREV(sih
->chiprev
) >= 4))
3391 si_info_t
*sii
= SI_INFO(sih
);
3392 uint32 bar0win
, bar0win_after
;
3394 /* save the bar0win */
3395 bar0win
= OSL_PCI_READ_CONFIG(sii
->osh
, PCI_BAR0_WIN
, sizeof(uint32
));
3397 si_watchdog_reset(sih
);
3399 bar0win_after
= OSL_PCI_READ_CONFIG(sii
->osh
, PCI_BAR0_WIN
, sizeof(uint32
));
3400 if (bar0win_after
!= bar0win
) {
3401 SI_ERROR(("%s: bar0win before %08x, bar0win after %08x\n",
3402 __FUNCTION__
, bar0win
, bar0win_after
));
3403 OSL_PCI_WRITE_CONFIG(sii
->osh
, PCI_BAR0_WIN
, sizeof(uint32
), bar0win
);
3407 /* enable survive perst */
3408 si_pcie_survive_perst(sih
, sperst_mask
, sperst_val
);
3410 #endif /* SURVIVE_PERST_ENAB */
3413 /* Caller of this function should make sure is on PCIE core
3414 * Used in pciedev.c.
3417 si_pcie_disable_oobselltr(si_t
*sih
)
3419 ASSERT(si_coreid(sih
) == PCIE2_CORE_ID
);
3420 si_wrapperreg(sih
, AI_OOBSELIND30
, ~0, 0);
3424 si_pcie_ltr_war(si_t
*sih
)
3429 si_pcie_hw_LTR_war(si_t
*sih
)
3434 si_pciedev_reg_pm_clk_period(si_t
*sih
)
3439 si_pciedev_crwlpciegen2(si_t
*sih
)
3444 si_pcie_prep_D3(si_t
*sih
, bool enter_D3
)
3449 #ifdef BCM_BACKPLANE_TIMEOUT
3451 si_clear_backplane_to_fast(si_t
*sih
, void * addr
)
3453 if (CHIPTYPE(sih
->socitype
) == SOCI_AI
) {
3454 return ai_clear_backplane_to_fast(sih
, addr
);
3460 const si_axi_error_info_t
* si_get_axi_errlog_info(si_t
* sih
)
3462 if (CHIPTYPE(sih
->socitype
) == SOCI_AI
) {
3463 return (const si_axi_error_info_t
*)sih
->err_info
;
3469 void si_reset_axi_errlog_info(si_t
* sih
)
3471 sih
->err_info
->count
= 0;
3473 #endif /* BCM_BACKPLANE_TIMEOUT */
3475 #if defined(AXI_TIMEOUTS) || defined(BCM_BACKPLANE_TIMEOUT)
3477 si_clear_backplane_to_per_core(si_t
*sih
, uint coreid
, uint coreunit
, void * wrap
)
3479 if (CHIPTYPE(sih
->socitype
) == SOCI_AI
) {
3480 return ai_clear_backplane_to_per_core(sih
, coreid
, coreunit
, wrap
);
3483 return AXI_WRAP_STS_NONE
;
3485 #endif /* AXI_TIMEOUTS || BCM_BACKPLANE_TIMEOUT */
3488 si_clear_backplane_to(si_t
*sih
)
3490 if (CHIPTYPE(sih
->socitype
) == SOCI_AI
) {
3491 return ai_clear_backplane_to(sih
);
3498 * This routine adds the AXI timeouts for
3499 * chipcommon, pcie and ARM slave wrappers
3502 si_slave_wrapper_add(si_t
*sih
)
3504 #if defined(AXI_TIMEOUTS) || defined(BCM_BACKPLANE_TIMEOUT)
3505 /* Enable only for AXI */
3506 if (CHIPTYPE(sih
->socitype
) != SOCI_AI
) {
3510 if (CHIPID(sih
->chip
) == BCM4345_CHIP_ID
&& CHIPREV(sih
->chiprev
) >= 6) {
3511 si_info_t
*sii
= SI_INFO(sih
);
3513 int wrapper_idx
= (int)sii
->axi_num_wrappers
- 1;
3515 ASSERT(wrapper_idx
>= 0); /* axi_wrapper[] not initialised */
3517 if (sii
->axi_wrapper
[wrapper_idx
].wrapper_type
== AI_SLAVE_WRAPPER
&&
3518 sii
->axi_wrapper
[wrapper_idx
].cid
== 0xfff) {
3519 sii
->axi_wrapper
[wrapper_idx
].wrapper_addr
= 0x1810b000;
3522 } while (wrapper_idx
-- > 0);
3523 ASSERT(wrapper_idx
>= 0); /* all addresses valid for the chiprev under test */
3526 /* All required slave wrappers are added in ai_scan */
3527 ai_enable_backplane_timeouts(sih
);
3528 #endif /* AXI_TIMEOUTS || BCM_BACKPLANE_TIMEOUT */
3533 si_pll_sr_reinit(si_t
*sih
)
3538 /* Programming d11 core oob settings for 4364
3539 * WARs for HW4364-237 and HW4364-166
3542 si_config_4364_d11_oob(si_t
*sih
, uint coreid
)
3546 save_idx
= si_coreidx(sih
);
3547 si_setcore(sih
, coreid
, 0);
3548 si_wrapperreg(sih
, AI_OOBSELINC30
, ~0, 0x81828180);
3549 si_wrapperreg(sih
, AI_OOBSELINC74
, ~0, 0x87868183);
3550 si_wrapperreg(sih
, AI_OOBSELOUTB74
, ~0, 0x84858484);
3551 si_setcore(sih
, coreid
, 1);
3552 si_wrapperreg(sih
, AI_OOBSELINC30
, ~0, 0x81828180);
3553 si_wrapperreg(sih
, AI_OOBSELINC74
, ~0, 0x87868184);
3554 si_wrapperreg(sih
, AI_OOBSELOUTB74
, ~0, 0x84868484);
3555 si_setcoreidx(sih
, save_idx
);
3559 si_pll_closeloop(si_t
*sih
)
3561 #if defined(SAVERESTORE)
3564 /* disable PLL open loop operation */
3565 switch (CHIPID(sih
->chip
)) {
3567 case BCM43018_CHIP_ID
:
3568 case BCM43430_CHIP_ID
:
3569 if (SR_ENAB() && sr_isenab(sih
)) {
3570 /* read back the pll openloop state */
3571 data
= si_pmu_pllcontrol(sih
, PMU1_PLL0_PLLCTL8
, 0, 0);
3572 /* current mode is openloop (possible POR) */
3573 if ((data
& PMU1_PLLCTL8_OPENLOOP_MASK
) != 0) {
3574 si_pmu_pllcontrol(sih
, PMU1_PLL0_PLLCTL8
,
3575 PMU1_PLLCTL8_OPENLOOP_MASK
, 0);
3580 #endif /* SAVERESTORE */
3582 /* any unsupported chip bail */
3589 si_update_macclk_mul_fact(si_t
*sih
, uint32 mul_fact
)
3591 si_info_t
*sii
= SI_INFO(sih
);
3592 sii
->macclk_mul_fact
= mul_fact
;
3596 si_get_macclk_mul_fact(si_t
*sih
)
3598 si_info_t
*sii
= SI_INFO(sih
);
3599 return sii
->macclk_mul_fact
;
3603 #if defined(BCMSRPWR) && !defined(BCMSRPWR_DISABLED)
3604 bool _bcmsrpwr
= TRUE
;
3606 bool _bcmsrpwr
= FALSE
;
3610 si_srpwr_request(si_t
*sih
, uint32 mask
, uint32 val
)
3612 uint32 r
, offset
= OFFSETOF(chipcregs_t
, powerctl
); /* Same 0x1e8 per core */
3613 uint cidx
= (BUSTYPE(sih
->bustype
) == SI_BUS
) ? SI_CC_IDX
: sih
->buscoreidx
;
3616 mask
<<= SRPWR_REQON_SHIFT
;
3617 val
<<= SRPWR_REQON_SHIFT
;
3619 r
= ((si_corereg(sih
, cidx
, offset
, 0, 0) & ~mask
) | val
);
3620 r
= si_corereg(sih
, cidx
, offset
, ~0, r
);
3622 r
= si_corereg(sih
, cidx
, offset
, 0, 0);
3629 si_srpwr_stat_spinwait(si_t
*sih
, uint32 mask
, uint32 val
)
3631 uint32 r
, offset
= OFFSETOF(chipcregs_t
, powerctl
); /* Same 0x1e8 per core */
3632 uint cidx
= (BUSTYPE(sih
->bustype
) == SI_BUS
) ? SI_CC_IDX
: sih
->buscoreidx
;
3637 /* spinwait on pwrstatus */
3638 mask
<<= SRPWR_STATUS_SHIFT
;
3639 val
<<= SRPWR_STATUS_SHIFT
;
3641 SPINWAIT(((si_corereg(sih
, cidx
, offset
, 0, 0) & mask
) != val
),
3642 PMU_MAX_TRANSITION_DLY
);
3643 ASSERT((si_corereg(sih
, cidx
, offset
, 0, 0) & mask
) == val
);
3645 r
= si_corereg(sih
, cidx
, offset
, 0, 0) & mask
;
3646 r
= (r
>> SRPWR_STATUS_SHIFT
) & SRPWR_DMN_ALL_MASK
;
3652 si_srpwr_stat(si_t
*sih
)
3654 uint32 r
, offset
= OFFSETOF(chipcregs_t
, powerctl
); /* Same 0x1e8 per core */
3655 uint cidx
= (BUSTYPE(sih
->bustype
) == SI_BUS
) ? SI_CC_IDX
: sih
->buscoreidx
;
3657 r
= si_corereg(sih
, cidx
, offset
, 0, 0);
3658 r
= (r
>> SRPWR_STATUS_SHIFT
) & SRPWR_DMN_ALL_MASK
;
3664 si_srpwr_domain(si_t
*sih
)
3666 uint32 r
, offset
= OFFSETOF(chipcregs_t
, powerctl
); /* Same 0x1e8 per core */
3667 uint cidx
= (BUSTYPE(sih
->bustype
) == SI_BUS
) ? SI_CC_IDX
: sih
->buscoreidx
;
3669 r
= si_corereg(sih
, cidx
, offset
, 0, 0);
3670 r
= (r
>> SRPWR_DMN_SHIFT
) & SRPWR_DMN_ALL_MASK
;
3675 /* Utility API to read/write the raw registers with absolute address.
3676 * This function can be invoked from either FW or host driver.
3679 si_raw_reg(si_t
*sih
, uint32 reg
, uint32 val
, uint32 wrire_req
)
3681 si_info_t
*sii
= SI_INFO(sih
);
3682 uint32 address_space
= reg
& ~0xFFF;
3683 volatile uint32
* addr
= (void*)(uintptr
)(reg
);
3684 uint32 prev_value
= 0;
3691 /* No need to translate the absolute address on SI bus */
3692 if (BUSTYPE(sih
->bustype
) == SI_BUS
) {
3696 /* This API supports only the PCI host interface */
3697 if (BUSTYPE(sih
->bustype
) != PCI_BUS
) {
3698 return ID32_INVALID
;
3701 if (PCIE_GEN2(sii
)) {
3702 /* Use BAR0 Secondary window is PCIe Gen2.
3703 * Set the secondary BAR0 Window to current register of interest
3705 addr
= (volatile uint32
*)(((volatile uint8
*)sii
->curmap
) +
3706 PCI_SEC_BAR0_WIN_OFFSET
+ (reg
& 0xfff));
3707 cfg_reg
= PCIE2_BAR0_CORE2_WIN
;
3710 /* PCIe Gen1 do not have secondary BAR0 window.
3711 * reuse the BAR0 WIN2
3713 addr
= (volatile uint32
*)(((volatile uint8
*)sii
->curmap
) +
3714 PCI_BAR0_WIN2_OFFSET
+ (reg
& 0xfff));
3715 cfg_reg
= PCI_BAR0_WIN2
;
3718 prev_value
= OSL_PCI_READ_CONFIG(sii
->osh
, cfg_reg
, 4);
3720 if (prev_value
!= address_space
) {
3721 OSL_PCI_WRITE_CONFIG(sii
->osh
, cfg_reg
,
3722 sizeof(uint32
), address_space
);
3729 W_REG(sii
->osh
, addr
, val
);
3731 val
= R_REG(sii
->osh
, addr
);
3735 /* Restore BAR0 WIN2 for PCIE GEN1 devices */
3736 OSL_PCI_WRITE_CONFIG(sii
->osh
,
3737 cfg_reg
, sizeof(uint32
), prev_value
);