From 297b60346df8beafee954a0fd7c2d64f33f3b9bc Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Sat, 11 May 2024 01:44:05 +0000
Subject: [PATCH] rtl8211F_led_control
---
kernel/drivers/net/wireless/rockchip_wlan/cywdhd/bcmdhd/siutils.c | 1759 +++++++++++++++++++++++++++++++++++++++-------------------
1 files changed, 1,183 insertions(+), 576 deletions(-)
diff --git a/kernel/drivers/net/wireless/rockchip_wlan/cywdhd/bcmdhd/siutils.c b/kernel/drivers/net/wireless/rockchip_wlan/cywdhd/bcmdhd/siutils.c
index cb64267..f2746a3 100644
--- a/kernel/drivers/net/wireless/rockchip_wlan/cywdhd/bcmdhd/siutils.c
+++ b/kernel/drivers/net/wireless/rockchip_wlan/cywdhd/bcmdhd/siutils.c
@@ -1,16 +1,17 @@
-/* SPDX-License-Identifier: GPL-2.0 */
/*
* Misc utility routines for accessing chip-specific features
* of the SiliconBackplane-based Broadcom chips.
*
- * Copyright (C) 1999-2019, Broadcom Corporation
- *
+ * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
+ *
+ * Copyright (C) 1999-2017, Broadcom Corporation
+ *
* Unless you and Broadcom execute a separate written software license
* agreement governing use of this software, this software is licensed to you
* under the terms of the GNU General Public License version 2 (the "GPL"),
* available at http://www.broadcom.com/licenses/GPLv2.php, with the
* following added to such license:
- *
+ *
* As a special exception, the copyright holders of this software give you
* permission to link this software with independent modules, and to copy and
* distribute the resulting executable under terms of your choice, provided that
@@ -18,7 +19,7 @@
* the license of that module. An independent module is a module which is not
* derived from this software. The special exception does not apply to any
* modifications of the software.
- *
+ *
* Notwithstanding the above, under no circumstances may you combine this
* software in any way with any other Broadcom software provided under a license
* other than the GPL, without Broadcom's express prior written consent.
@@ -26,7 +27,7 @@
*
* <<Broadcom-WL-IPTag/Open:>>
*
- * $Id: siutils.c 722050 2019-08-21 02:24:57Z $
+ * $Id: siutils.c 701025 2017-05-23 10:23:52Z $
*/
#include <bcm_cfg.h>
@@ -38,8 +39,12 @@
#include <bcmdevs.h>
#include <hndsoc.h>
#include <sbchipc.h>
+#include <sbgci.h>
+#ifndef BCMSDIO
+#include <pcie_core.h>
+#endif // endif
#ifdef BCMPCIEDEV
-#include <pciedev.h>
+/
#endif /* BCMPCIEDEV */
#include <pcicfg.h>
#include <sbpcmcia.h>
@@ -54,10 +59,9 @@
#include <bcmsdpcm.h>
#endif /* BCMSDIO */
#include <hndpmu.h>
-
-#ifdef LOAD_DHD_WITH_FW_ALIVE
-#include <dhd_chip_info.h>
-#endif
+#ifdef BCMSPI
+#include <spid.h>
+#endif /* BCMSPI */
#ifdef BCM_SDRBL
#include <hndcpu.h>
@@ -65,8 +69,28 @@
#ifdef HNDGCI
#include <hndgci.h>
#endif /* HNDGCI */
+#ifdef WLGCIMBHLR
+#include <hnd_gci.h>
+#endif /* WLGCIMBHLR */
+#ifdef BCMULP
+#include <ulp.h>
+#endif /* BCMULP */
+#include <hndlhl.h>
+
+#include <lpflags.h>
#include "siutils_priv.h"
+#ifdef SECI_UART
+/* Defines the set of GPIOs to be used for SECI UART if not specified in NVRAM */
+/* For further details on each ppin functionality please refer to PINMUX table in
+ * Top level architecture of BCMXXXX Chip
+ */
+#define DEFAULT_SECI_UART_PINMUX 0x08090a0b
+#define DEFAULT_SECI_UART_PINMUX_43430 0x0102
+static bool force_seci_clk = 0;
+#endif /* SECI_UART */
+
+#define XTAL_FREQ_26000KHZ 26000
/**
* A set of PMU registers is clocked in the ILP domain, which has an implication on register write
@@ -83,26 +107,35 @@
(regoff) == OFFSETOF(chipcregs_t, pmuwatchdog) || \
(regoff) == OFFSETOF(chipcregs_t, res_req_timer))
+#define GCI_FEM_CTRL_WAR 0x11111111
+
+#ifndef AXI_TO_VAL
+#define AXI_TO_VAL 19
+#endif /* AXI_TO_VAL */
+
+#ifndef AXI_TO_VAL_4347
+/*
+ * Increase BP timeout for fast clock and short PCIe timeouts
+ * New timeout: 2 ** 25 cycles
+ */
+#define AXI_TO_VAL_4347 25
+#endif /* AXI_TO_VAL_4347 */
+
/* local prototypes */
-static si_info_t *si_doattach(si_info_t *sii, uint devid, osl_t *osh, void *regs,
+static si_info_t *si_doattach(si_info_t *sii, uint devid, osl_t *osh, volatile void *regs,
uint bustype, void *sdh, char **vars, uint *varsz);
static bool si_buscore_prep(si_info_t *sii, uint bustype, uint devid, void *sdh);
static bool si_buscore_setup(si_info_t *sii, chipcregs_t *cc, uint bustype, uint32 savewin,
- uint *origidx, void *regs);
-
+ uint *origidx, volatile void *regs);
static bool si_pmu_is_ilp_sensitive(uint32 idx, uint regoff);
-
-#ifdef BCMLTECOEX
-static void si_config_gcigpio(si_t *sih, uint32 gci_pos, uint8 gcigpio,
- uint8 gpioctl_mask, uint8 gpioctl_val);
-#endif /* BCMLTECOEX */
-
/* global variable to indicate reservation/release of gpio's */
static uint32 si_gpioreservation = 0;
/* global flag to prevent shared resources from being initialized multiple times in si_attach() */
+static bool si_onetimeinit = FALSE;
+
#ifdef SR_DEBUG
static const uint32 si_power_island_test_array[] = {
0x0000, 0x0001, 0x0010, 0x0011,
@@ -113,6 +146,11 @@
#endif /* SR_DEBUG */
int do_4360_pcie2_war = 0;
+
+#ifdef BCMULP
+/* Variable to store boot_type: warm_boot/cold_boot/etc. */
+static int boot_type = 0;
+#endif // endif
/* global kernel resource */
static si_info_t ksii;
@@ -130,19 +168,21 @@
* varsz - pointer to int to return the size of the vars
*/
si_t *
-si_attach(uint devid, osl_t *osh, void *regs,
+si_attach(uint devid, osl_t *osh, volatile void *regs,
uint bustype, void *sdh, char **vars, uint *varsz)
{
si_info_t *sii;
si_cores_info_t *cores_info;
/* alloc si_info_t */
- if ((sii = MALLOCZ(osh, sizeof (si_info_t))) == NULL) {
+ /* freed after ucode download for firmware builds */
+ if ((sii = MALLOCZ_NOPERSIST(osh, sizeof(si_info_t))) == NULL) {
SI_ERROR(("si_attach: malloc failed! malloced %d bytes\n", MALLOCED(osh)));
return (NULL);
}
/* alloc si_cores_info_t */
- if ((cores_info = (si_cores_info_t *)MALLOCZ(osh, sizeof (si_cores_info_t))) == NULL) {
+ if ((cores_info = (si_cores_info_t *)MALLOCZ(osh,
+ sizeof(si_cores_info_t))) == NULL) {
SI_ERROR(("si_attach: malloc failed! malloced %d bytes\n", MALLOCED(osh)));
MFREE(osh, sii, sizeof(si_info_t));
return (NULL);
@@ -160,10 +200,39 @@
return (si_t *)sii;
}
+static uint32 wd_msticks; /**< watchdog timer ticks normalized to ms */
-static uint32 wd_msticks; /* watchdog timer ticks normalized to ms */
+/** Returns the backplane address of the chipcommon core for a particular chip */
+uint32
+si_enum_base(uint devid)
+{
+ // NIC/DHD build
+ switch (devid) {
+ case BCM7271_CHIP_ID:
+ case BCM7271_D11AC_ID:
+ case BCM7271_D11AC2G_ID:
+ case BCM7271_D11AC5G_ID:
+ return 0xF1800000;
+ }
-/** generic kernel variant of si_attach() */
+ return SI_ENUM_BASE_DEFAULT;
+}
+
+/** Returns the backplane address of the PCIE core for a particular chip */
+uint32
+si_pcie_enum_base(uint devid)
+{
+ switch (devid) {
+ case CYW55560_WLAN_ID:
+ case CYW89570_WLAN_ID:
+ return SI_ENUM_PCIE2_BASE;
+ }
+
+ /* Default - In future chips if devid is not matched */
+ return SI_ENUM_PCIE2_BASE;
+}
+
+/** generic kernel variant of si_attach(). Is not called for Linux WLAN NIC builds. */
si_t *
si_kattach(osl_t *osh)
{
@@ -172,12 +241,14 @@
if (!ksii_attached) {
void *regs = NULL;
- regs = REG_MAP(SI_ENUM_BASE, SI_CORE_SIZE);
+ const uint device_id = BCM4710_DEVICE_ID; // pick an arbitrary default device_id
+
+ regs = REG_MAP(si_enum_base(device_id), SI_CORE_SIZE); // map physical to virtual
cores_info = (si_cores_info_t *)&ksii_cores_info;
ksii.cores_info = cores_info;
ASSERT(osh);
- if (si_doattach(&ksii, BCM4710_DEVICE_ID, osh, regs,
+ if (si_doattach(&ksii, device_id, osh, regs,
SI_BUS, NULL,
osh != SI_OSH ? &(ksii.vars) : NULL,
osh != SI_OSH ? &(ksii.varsz) : NULL) == NULL) {
@@ -189,30 +260,30 @@
/* save ticks normalized to ms for si_watchdog_ms() */
if (PMUCTL_ENAB(&ksii.pub)) {
- /* based on 32KHz ILP clock */
- wd_msticks = 32;
+ /* based on 32KHz ILP clock */
+ wd_msticks = 32;
} else {
wd_msticks = ALP_CLOCK / 1000;
}
ksii_attached = TRUE;
SI_MSG(("si_kattach done. ccrev = %d, wd_msticks = %d\n",
- ksii.pub.ccrev, wd_msticks));
+ CCREV(ksii.pub.ccrev), wd_msticks));
}
return &ksii.pub;
}
-
static bool
si_buscore_prep(si_info_t *sii, uint bustype, uint devid, void *sdh)
{
+ BCM_REFERENCE(sdh);
+ BCM_REFERENCE(devid);
/* need to set memseg flag for CF card first before any sb registers access */
if (BUSTYPE(bustype) == PCMCIA_BUS)
sii->memseg = TRUE;
-
-#if defined(BCMSDIO)
+#if defined(BCMSDIO) && !defined(BCMSDIOLITE)
if (BUSTYPE(bustype) == SDIO_BUS) {
int err;
uint8 clkset;
@@ -245,7 +316,25 @@
bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_SDIOPULLUP, 0, NULL);
}
-#endif /* BCMSDIO && BCMDONGLEHOST */
+#ifdef BCMSPI
+ /* Avoid backplane accesses before wake-wlan (i.e. htavail) for spi.
+ * F1 read accesses may return correct data but with data-not-available dstatus bit set.
+ */
+ if (BUSTYPE(bustype) == SPI_BUS) {
+
+ int err;
+ uint32 regdata;
+ /* wake up wlan function :WAKE_UP goes as HT_AVAIL request in hardware */
+ regdata = bcmsdh_cfg_read_word(sdh, SDIO_FUNC_0, SPID_CONFIG, NULL);
+ SI_MSG(("F0 REG0 rd = 0x%x\n", regdata));
+ regdata |= WAKE_UP;
+
+ bcmsdh_cfg_write_word(sdh, SDIO_FUNC_0, SPID_CONFIG, regdata, &err);
+
+ OSL_DELAY(100000);
+ }
+#endif /* BCMSPI */
+#endif /* BCMSDIO && BCMDONGLEHOST && !BCMSDIOLITE */
return TRUE;
}
@@ -268,46 +357,31 @@
origidx = sii->curidx;
pmucoreidx = si_findcoreidx(&sii->pub, PMU_CORE_ID, 0);
pmu = si_setcoreidx(&sii->pub, pmucoreidx);
- pmuaddr = (uint32)(unsigned long)((uint8*)pmu + offset);
+ pmuaddr = (uint32)(uintptr)((volatile uint8*)pmu + offset);
si_setcoreidx(sih, origidx);
} else
- pmuaddr = SI_ENUM_BASE + offset;
+ pmuaddr = SI_ENUM_BASE(sih) + offset;
done:
- SI_MSG(("%s: addrRET: %x\n", __FUNCTION__, pmuaddr));
+ printf("%s: addrRET: %x\n", __FUNCTION__, pmuaddr);
return pmuaddr;
}
static bool
si_buscore_setup(si_info_t *sii, chipcregs_t *cc, uint bustype, uint32 savewin,
- uint *origidx, void *regs)
+ uint *origidx, volatile void *regs)
{
si_cores_info_t *cores_info = (si_cores_info_t *)sii->cores_info;
bool pci, pcie, pcie_gen2 = FALSE;
uint i;
uint pciidx, pcieidx, pcirev, pcierev;
+ struct si_pub *sih = &sii->pub;
-#ifdef LOAD_DHD_WITH_FW_ALIVE
- if(alive == FW_ALIVE_MAGIC) {
- switch(card_dev) {
- case BCM43430_CHIP_ID:
- if(card_rev == 2)
- memcpy(&sii->pub, &sii_pub_43436, sizeof(sii->pub));
- else
- memcpy(&sii->pub, &sii_pub_43430, sizeof(sii->pub));
- break;
-
- case BCM43012_CHIP_ID:
- memcpy(&sii->pub, &sii_pub_43012, sizeof(sii->pub));
- break;
- }
- return true;
- }
-#endif
-
+#if defined(BCM_BACKPLANE_TIMEOUT) || defined(AXI_TIMEOUTS)
/* first, enable backplane timeouts */
- if (CHIPTYPE(sii->pub.socitype) == SOCI_AI)
- ai_enable_backplane_timeouts(&sii->pub);
+ si_slave_wrapper_add(&sii->pub);
+#endif // endif
+ sii->curidx = 0;
cc = si_setcoreidx(&sii->pub, SI_CC_IDX);
ASSERT((uintptr)cc);
@@ -316,33 +390,50 @@
sii->pub.ccrev = (int)si_corerev(&sii->pub);
/* get chipcommon chipstatus */
- if (sii->pub.ccrev >= 11)
- sii->pub.chipst = R_REG(sii->osh, &cc->chipstatus);
+ if (CCREV(sii->pub.ccrev) >= 11) {
+ /* TODO : We need a better approach to avoid this access in secure mode chips */
+ if (sii->pub.chip != CYW55500_CHIP_ID &&
+ sii->pub.chip != CYW55560_CHIP_ID) {
+ sii->pub.chipst = R_REG(sii->osh, &cc->chipstatus);
+ }
+ }
- /* get chipcommon capabilites */
- sii->pub.cccaps = R_REG(sii->osh, &cc->capabilities);
- /* get chipcommon extended capabilities */
+ if (!sih->chipidpresent) {
+ /* get chipcommon capabilites */
+ sii->pub.cccaps = R_REG(sii->osh, &cc->capabilities);
+ /* get chipcommon extended capabilities */
+ if (CCREV(sii->pub.ccrev) >= 35)
+ sii->pub.cccaps_ext = R_REG(sii->osh, &cc->capabilities_ext);
- if (sii->pub.ccrev >= 35)
- sii->pub.cccaps_ext = R_REG(sii->osh, &cc->capabilities_ext);
+ /* get pmu rev and caps */
+ if (sii->pub.cccaps & CC_CAP_PMU) {
+ if (AOB_ENAB(&sii->pub)) {
+ uint pmucoreidx;
+ pmuregs_t *pmu;
+ struct si_pub *sih = &sii->pub;
- /* get pmu rev and caps */
- if (sii->pub.cccaps & CC_CAP_PMU) {
- if (AOB_ENAB(&sii->pub)) {
- uint pmucoreidx;
- pmuregs_t *pmu;
- pmucoreidx = si_findcoreidx(&sii->pub, PMU_CORE_ID, 0);
- pmu = si_setcoreidx(&sii->pub, pmucoreidx);
- sii->pub.pmucaps = R_REG(sii->osh, &pmu->pmucapabilities);
- si_setcoreidx(&sii->pub, SI_CC_IDX);
- } else
- sii->pub.pmucaps = R_REG(sii->osh, &cc->pmucapabilities);
+ pmucoreidx = si_findcoreidx(&sii->pub, PMU_CORE_ID, 0);
+ if (!GOODIDX(pmucoreidx)) {
+ SI_ERROR(("si_buscore_setup: si_findcoreidx failed\n"));
+ return FALSE;
+ }
- sii->pub.pmurev = sii->pub.pmucaps & PCAP_REV_MASK;
+ pmu = si_setcoreidx(&sii->pub, pmucoreidx);
+ sii->pub.pmucaps = R_REG(sii->osh, &pmu->pmucapabilities);
+ si_setcoreidx(&sii->pub, SI_CC_IDX);
+
+ sii->pub.gcirev = si_corereg(sih, GCI_CORE_IDX(sih),
+ GCI_OFFSETOF(sih, gci_corecaps0), 0, 0) &
+ GCI_CAP0_REV_MASK;
+ } else
+ sii->pub.pmucaps = R_REG(sii->osh, &cc->pmucapabilities);
+
+ sii->pub.pmurev = sii->pub.pmucaps & PCAP_REV_MASK;
+ }
}
SI_MSG(("Chipc: rev %d, caps 0x%x, chipst 0x%x pmurev %d, pmucaps 0x%x\n",
- sii->pub.ccrev, sii->pub.cccaps, sii->pub.chipst, sii->pub.pmurev,
+ CCREV(sii->pub.ccrev), sii->pub.cccaps, sii->pub.chipst, sii->pub.pmurev,
sii->pub.pmucaps));
/* figure out bus/orignal core idx */
@@ -362,28 +453,23 @@
crev = si_corerev(&sii->pub);
/* Display cores found */
- SI_VMSG(("CORE[%d]: id 0x%x rev %d base 0x%x regs 0x%p\n",
- i, cid, crev, cores_info->coresba[i], cores_info->regs[i]));
+ SI_VMSG(("CORE[%d]: id 0x%x rev %d base 0x%x size:%x regs 0x%p\n",
+ i, cid, crev, sii->coresba[i], sii->coresba_size[i],
+ OSL_OBFUSCATE_BUF(sii->regs[i])));
if (BUSTYPE(bustype) == SI_BUS) {
/* now look at the chipstatus register to figure the pacakge */
/* for SDIO but downloaded on PCIE dev */
+#ifdef BCMPCIEDEV_ENABLED
if (cid == PCIE2_CORE_ID) {
- if (BCM43602_CHIP(sii->pub.chip) ||
- (CHIPID(sii->pub.chip) == BCM4365_CHIP_ID) ||
- (CHIPID(sii->pub.chip) == BCM4366_CHIP_ID) ||
- ((CHIPID(sii->pub.chip) == BCM4345_CHIP_ID ||
- CHIPID(sii->pub.chip) == BCM43454_CHIP_ID) &&
- CST4345_CHIPMODE_PCIE(sii->pub.chipst))) {
pcieidx = i;
pcierev = crev;
pcie = TRUE;
pcie_gen2 = TRUE;
- }
}
+#endif // endif
- }
- else if (BUSTYPE(bustype) == PCI_BUS) {
+ } else if (BUSTYPE(bustype) == PCI_BUS) {
if (cid == PCI_CORE_ID) {
pciidx = i;
pcirev = crev;
@@ -418,7 +504,6 @@
*origidx = i;
}
-
#if defined(PCIE_FULL_DONGLE)
if (pcie) {
if (pcie_gen2)
@@ -449,11 +534,6 @@
SI_VMSG(("Buscore id/type/rev %d/0x%x/%d\n", sii->pub.buscoreidx, sii->pub.buscoretype,
sii->pub.buscorerev));
- if (BUSTYPE(sii->pub.bustype) == SI_BUS && (CHIPID(sii->pub.chip) == BCM4712_CHIP_ID) &&
- (sii->pub.chippkg != BCM4712LARGE_PKG_ID) && (CHIPREV(sii->pub.chiprev) <= 3))
- OR_REG(sii->osh, &cc->slow_clk_ctl, SCC_SS_XTAL);
-
-
#if defined(BCMSDIO)
/* Make sure any on-chip ARM is off (in case strapping is wrong), or downloaded code was
* already running.
@@ -471,9 +551,6 @@
return TRUE;
}
-
-
-
uint16
si_chipid(si_t *sih)
{
@@ -482,6 +559,7 @@
return (sii->chipnew) ? sii->chipnew : sih->chip;
}
+/* CHIP_ID's being mapped here should not be used anywhere else in the code */
static void
si_chipid_fixup(si_t *sih)
{
@@ -493,49 +571,162 @@
sii->chipnew = sih->chip; /* save it */
sii->pub.chip = BCM43570_CHIP_ID; /* chip class */
break;
+ case BCM43562_CHIP_ID:
case BCM4358_CHIP_ID:
case BCM43566_CHIP_ID:
sii->chipnew = sih->chip; /* save it */
sii->pub.chip = BCM43569_CHIP_ID; /* chip class */
break;
case BCM4356_CHIP_ID:
+ case BCM4371_CHIP_ID:
sii->chipnew = sih->chip; /* save it */
sii->pub.chip = BCM4354_CHIP_ID; /* chip class */
break;
+ case BCM4357_CHIP_ID:
+ case BCM4361_CHIP_ID:
+ sii->chipnew = sih->chip; /* save it */
+ sii->pub.chip = BCM4347_CHIP_ID; /* chip class */
+ break;
+#ifdef CHIPS_CUSTOMER_HW6
+ case BCM4377_CHIP_ID:
+ sii->chipnew = sih->chip; /* save it */
+ sii->pub.chip = BCM4369_CHIP_ID; /* chip class */
+ break;
+#endif /* CHIPS_CUSTOMER_HW6 */
default:
break;
}
}
+#ifdef BCMULP
+static void
+si_check_boot_type(si_t *sih, osl_t *osh)
+{
+ if (sih->pmurev >= 30) {
+ boot_type = PMU_REG_NEW(sih, swscratch, 0, 0);
+ } else {
+ boot_type = CHIPC_REG(sih, flashdata, 0, 0);
+ }
+
+ SI_ERROR(("%s: boot_type: 0x%08x\n", __func__, boot_type));
+}
+#endif /* BCMULP */
+
+#ifdef BCM_BACKPLANE_TIMEOUT
+uint32
+si_clear_backplane_to_fast(void *sih, void *addr)
+{
+ si_t *_sih = DISCARD_QUAL(sih, si_t);
+
+ if (CHIPTYPE(_sih->socitype) == SOCI_AI) {
+ return ai_clear_backplane_to_fast(_sih, addr);
+ }
+
+ return 0;
+}
+
+const si_axi_error_info_t *
+si_get_axi_errlog_info(si_t *sih)
+{
+ if (CHIPTYPE(sih->socitype) == SOCI_AI) {
+ return (const si_axi_error_info_t *)sih->err_info;
+ }
+
+ return NULL;
+}
+
+void
+si_reset_axi_errlog_info(si_t *sih)
+{
+ if (sih->err_info) {
+ sih->err_info->count = 0;
+ }
+}
+#endif /* BCM_BACKPLANE_TIMEOUT */
+
+#ifdef BCMSDIO
+void *
+si_get_sdio_addrbase(void *sdh)
+{
+ uint8 devctl;
+ int err = 0;
+ uint32 addr = 0;
+
+ devctl = bcmsdh_cfg_read(sdh, SDIO_FUNC_1, SBSDIO_DEVICE_CTL, &err);
+ if (err)
+ return NULL;
+
+ bcmsdh_cfg_write(sdh, SDIO_FUNC_1,
+ SBSDIO_DEVICE_CTL, devctl | SBSDIO_DEVCTL_ADDR_RESET, &err);
+ if (err)
+ goto exit;
+
+ addr |= (bcmsdh_cfg_read(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_SBADDRLOW, NULL) << 8) |
+ (bcmsdh_cfg_read(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_SBADDRMID, NULL) << 16) |
+ (bcmsdh_cfg_read(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_SBADDRHIGH, NULL) << 24);
+
+ SI_MSG(("%s: sdiod core address is 0x%x\n", __FUNCTION__, addr));
+exit:
+ if (err) {
+ SI_ERROR(("%s: Get SDIO core base address failed, err=%d", __FUNCTION__, err));
+ addr = 0;
+ }
+ bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_DEVICE_CTL, devctl, &err);
+
+ return (void *)((uintptr)addr);
+}
+#endif /* BCMSDIO */
+
/**
- * Allocate an si handle. This function may be called multiple times.
+ * Allocate an si handle. This function may be called multiple times. This function is called by
+ * both si_attach() and si_kattach().
*
* vars - pointer to a to-be created pointer area for "environment" variables. Some callers of this
* function set 'vars' to NULL.
*/
static si_info_t *
-si_doattach(si_info_t *sii, uint devid, osl_t *osh, void *regs,
+si_doattach(si_info_t *sii, uint devid, osl_t *osh, volatile void *regs,
uint bustype, void *sdh, char **vars, uint *varsz)
{
struct si_pub *sih = &sii->pub;
- uint32 w, savewin;
+ uint32 w = 0;
+ uint32 savewin;
chipcregs_t *cc;
char *pvars = NULL;
uint origidx;
-#if !defined(_CFEZ_) || defined(CFG_WL)
-#endif
+#ifdef NVSRCX
+ char *sromvars;
+#endif // endif
+ uint32 erombase;
+#ifdef BCMSDIO
+ uint8 cardcap;
+ sdpcmd_regs_t *sdioc;
+#endif // endif
ASSERT(GOODREGS(regs));
savewin = 0;
sih->buscoreidx = BADIDX;
+ sii->device_removed = FALSE;
sii->curmap = regs;
sii->sdh = sdh;
sii->osh = osh;
sii->second_bar0win = ~0x0;
+ sih->enum_base = si_enum_base(devid);
+#if defined(BCM_BACKPLANE_TIMEOUT)
+ sih->err_info = MALLOCZ(osh, sizeof(si_axi_error_info_t));
+ if (sih->err_info == NULL) {
+ SI_ERROR(("%s: %zu bytes MALLOC FAILED",
+ __FUNCTION__, sizeof(si_axi_error_info_t)));
+ }
+#endif /* BCM_BACKPLANE_TIMEOUT */
+
+#if defined(BCM_BACKPLANE_TIMEOUT)
+ osl_set_bpt_cb(osh, (void *)si_clear_backplane_to_fast, (void *)sih);
+#endif // endif
/* check to see if we are a si core mimic'ing a pci core */
if ((bustype == PCI_BUS) &&
@@ -548,29 +739,42 @@
/* find Chipcommon address */
if (bustype == PCI_BUS) {
savewin = OSL_PCI_READ_CONFIG(sii->osh, PCI_BAR0_WIN, sizeof(uint32));
- if (!GOODCOREADDR(savewin, SI_ENUM_BASE))
- savewin = SI_ENUM_BASE;
- OSL_PCI_WRITE_CONFIG(sii->osh, PCI_BAR0_WIN, 4, SI_ENUM_BASE);
+ if (!GOODCOREADDR(savewin, SI_ENUM_BASE(sih)))
+ savewin = SI_ENUM_BASE(sih);
+ OSL_PCI_WRITE_CONFIG(sii->osh, PCI_BAR0_WIN, 4, SI_ENUM_BASE(sih));
if (!regs)
return NULL;
cc = (chipcregs_t *)regs;
+ erombase = R_REG(osh, &cc->eromptr);
#ifdef BCMSDIO
} else if ((bustype == SDIO_BUS) || (bustype == SPI_BUS)) {
cc = (chipcregs_t *)sii->curmap;
-#endif
+ cardcap = bcmsdh_cfg_read(sdh, SDIO_FUNC_0, SDIOD_CCCR_BRCM_CARDCAP, NULL);
+ if (cardcap & SDIOD_CCCR_BRCM_CARDCAP_CHIPID_PRESENT) {
+ sih->chipidpresent = TRUE;
+ sdioc = si_get_sdio_addrbase(sdh);
+ w = R_REG(osh, &sdioc->chipid);
+ erombase = R_REG(osh, &sdioc->eromptr);
+ } else {
+ erombase = R_REG(osh, &cc->eromptr);
+ }
+ if (cardcap & SDIOD_CCCR_BRCM_CARDCAP_SECURE_MODE) {
+ sih->secureboot = TRUE;
+ }
+#endif // endif
} else {
- cc = (chipcregs_t *)REG_MAP(SI_ENUM_BASE, SI_CORE_SIZE);
+ cc = (chipcregs_t *)REG_MAP(SI_ENUM_BASE(sih), SI_CORE_SIZE);
+ erombase = R_REG(osh, &cc->eromptr);
}
sih->bustype = bustype;
#ifdef BCMBUSTYPE
- /* Fix the -Werror=tautological-compare compiling error */
if (bustype != BUSTYPE(bustype)) {
SI_ERROR(("si_doattach: bus type %d does not match configured bus type %d\n",
bustype, BUSTYPE(bustype)));
return NULL;
}
-#endif
+#endif // endif
/* bus/core/clk setup for register access */
if (!si_buscore_prep(sii, bustype, devid, sdh)) {
@@ -587,7 +791,8 @@
SI_ERROR(("%s: chipcommon register space is null \n", __FUNCTION__));
return NULL;
}
- w = R_REG(osh, &cc->chipid);
+ if (!w)
+ w = R_REG(osh, &cc->chipid);
if ((w & 0xfffff) == 148277) w -= 65532;
sih->socitype = (w & CID_TYPE_MASK) >> CID_TYPE_SHIFT;
/* Might as wll fill in chip id rev & pkg */
@@ -597,24 +802,50 @@
si_chipid_fixup(sih);
- if ((CHIPID(sih->chip) == BCM4329_CHIP_ID) && CHIPREV(sih->chiprev == 0) &&
- (sih->chippkg != BCM4329_289PIN_PKG_ID)) {
- sih->chippkg = BCM4329_182PIN_PKG_ID;
+ if (CHIPID(sih->chip) == BCM43465_CHIP_ID) {
+ sih->chip = BCM4366_CHIP_ID;
+ } else if (CHIPID(sih->chip) == BCM43525_CHIP_ID) {
+ sih->chip = BCM4365_CHIP_ID;
}
+
sih->issim = IS_SIM(sih->chippkg);
+
+#ifdef CHIPS_CUSTOMER_HW6
+ if (MULTIBP_CAP(sih))
+ {
+ sih->_multibp_enable = TRUE;
+ }
+#endif // endif
/* scan for cores */
if (CHIPTYPE(sii->pub.socitype) == SOCI_SB) {
SI_MSG(("Found chip type SB (0x%08x)\n", w));
sb_scan(&sii->pub, regs, devid);
} else if ((CHIPTYPE(sii->pub.socitype) == SOCI_AI) ||
- (CHIPTYPE(sii->pub.socitype) == SOCI_NAI)) {
+ (CHIPTYPE(sii->pub.socitype) == SOCI_NAI) ||
+ (CHIPTYPE(sii->pub.socitype) == SOCI_DVTBUS)) {
+
if (CHIPTYPE(sii->pub.socitype) == SOCI_AI)
SI_MSG(("Found chip type AI (0x%08x)\n", w));
- else
+ else if (CHIPTYPE(sii->pub.socitype) == SOCI_NAI)
SI_MSG(("Found chip type NAI (0x%08x)\n", w));
+ else
+ SI_MSG(("Found chip type DVT (0x%08x)\n", w));
/* pass chipc address instead of original core base */
- ai_scan(&sii->pub, (void *)(uintptr)cc, devid);
+
+ if (sii->osh) {
+ sii->axi_wrapper = (axi_wrapper_t *)MALLOCZ(sii->osh,
+ (sizeof(axi_wrapper_t) * SI_MAX_AXI_WRAPPERS));
+
+ if (sii->axi_wrapper == NULL) {
+ SI_ERROR(("%s: %zu bytes MALLOC Failed", __FUNCTION__,
+ (sizeof(axi_wrapper_t) * SI_MAX_AXI_WRAPPERS)));
+ }
+ } else {
+ sii->axi_wrapper = NULL;
+ }
+
+ ai_scan(&sii->pub, (void *)(uintptr)cc, erombase, devid);
} else if (CHIPTYPE(sii->pub.socitype) == SOCI_UBUS) {
SI_MSG(("Found chip type UBUS (0x%08x), chip id = 0x%4x\n", w, sih->chip));
/* pass chipc address instead of original core base */
@@ -634,17 +865,19 @@
SI_ERROR(("si_doattach: si_buscore_setup failed\n"));
goto exit;
}
+#ifdef BCMULP
+ if (BCMULP_ENAB()) {
+ si_check_boot_type(sih, osh);
+ if (ulp_module_init(osh, sih) != BCME_OK) {
+ ULP_ERR(("%s: err in ulp_module_init\n", __FUNCTION__));
+ goto exit;
+ }
+ }
+#endif /* BCMULP */
#if !defined(_CFEZ_) || defined(CFG_WL)
- if (CHIPID(sih->chip) == BCM4322_CHIP_ID && (((sih->chipst & CST4322_SPROM_OTP_SEL_MASK)
- >> CST4322_SPROM_OTP_SEL_SHIFT) == (CST4322_OTP_PRESENT |
- CST4322_SPROM_PRESENT))) {
- SI_ERROR(("%s: Invalid setting: both SPROM and OTP strapped.\n", __FUNCTION__));
- return NULL;
- }
-
/* assume current core is CC */
- if ((sii->pub.ccrev == 0x25) && ((CHIPID(sih->chip) == BCM43236_CHIP_ID ||
+ if ((CCREV(sii->pub.ccrev) == 0x25) && ((CHIPID(sih->chip) == BCM43236_CHIP_ID ||
CHIPID(sih->chip) == BCM43235_CHIP_ID ||
CHIPID(sih->chip) == BCM43234_CHIP_ID ||
CHIPID(sih->chip) == BCM43238_CHIP_ID) &&
@@ -661,10 +894,54 @@
OSL_DELAY(10);
}
+ /* Set the clkdiv2 divisor bits (2:0) to 0x4 if srom is present */
+ if (bustype == SI_BUS) {
+ uint32 clkdiv2, sromprsnt, capabilities, srom_supported;
+ capabilities = R_REG(osh, &cc->capabilities);
+ srom_supported = capabilities & SROM_SUPPORTED;
+ if (srom_supported)
+ {
+ sromprsnt = R_REG(osh, &cc->sromcontrol);
+ sromprsnt = sromprsnt & SROM_PRSNT_MASK;
+ if (sromprsnt) {
+ /* SROM clock come from backplane clock/div2. Must <= 1Mhz */
+ clkdiv2 = (R_REG(osh, &cc->clkdiv2) & ~CLKD2_SROM);
+ clkdiv2 |= CLKD2_SROMDIV_192;
+ W_REG(osh, &cc->clkdiv2, clkdiv2);
+ }
+ }
+ }
+
if (bustype == PCI_BUS) {
+#ifdef BCMQT
+ /* Set OTPClkDiv to smaller value otherwise OTP always reads 0xFFFF.
+ * For real-chip we shouldn't set OTPClkDiv to 2 because 20/2 = 10 > 9Mhz
+ */
+ {
+ uint otpclkdiv = 0;
+
+ if ((CHIPID(sih->chip) == BCM43131_CHIP_ID) ||
+ (CHIPID(sih->chip) == BCM43217_CHIP_ID)) {
+ otpclkdiv = 4;
+ }
+
+ if (otpclkdiv != 0) {
+ uint clkdiv, savecore;
+ savecore = si_coreidx(sih);
+ si_setcore(sih, CC_CORE_ID, 0);
+
+ clkdiv = R_REG(osh, &cc->clkdiv);
+ clkdiv = (clkdiv & ~CLKD_OTP) | (otpclkdiv << CLKD_OTP_SHIFT);
+ W_REG(osh, &cc->clkdiv, clkdiv);
+
+ SI_ERROR(("%s: set clkdiv to 0x%x for QT\n", __FUNCTION__, clkdiv));
+ si_setcoreidx(sih, savecore);
+ }
+ }
+#endif /* BCMQT */
}
-#endif
+#endif // endif
#ifdef BCM_SDRBL
/* 4360 rom bootloader in PCIE case, if the SDR is enabled, But preotection is
* not turned on, then we want to hold arm in reset.
@@ -689,35 +966,34 @@
pvars = NULL;
BCM_REFERENCE(pvars);
+ {
+ sii->lhl_ps_mode = LHL_PS_MODE_0;
+ }
+ if (!si_onetimeinit) {
- if (sii->pub.ccrev >= 20) {
+ if (CCREV(sii->pub.ccrev) >= 20) {
uint32 gpiopullup = 0, gpiopulldown = 0;
cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0);
ASSERT(cc != NULL);
-
- /* 4314/43142 has pin muxing, don't clear gpio bits */
- if ((CHIPID(sih->chip) == BCM4314_CHIP_ID) ||
- (CHIPID(sih->chip) == BCM43142_CHIP_ID)) {
- gpiopullup |= 0x402e0;
- gpiopulldown |= 0x20500;
- }
-
-
- W_REG(osh, &cc->gpiopullup, gpiopullup);
- W_REG(osh, &cc->gpiopulldown, gpiopulldown);
+ BCM_REFERENCE(gpiopullup);
+ BCM_REFERENCE(gpiopulldown);
si_setcoreidx(sih, origidx);
}
+ }
/* clear any previous epidiag-induced target abort */
ASSERT(!si_taclear(sih, FALSE));
+#if defined(BCMPMU_STATS) && !defined(BCMPMU_STATS_DISABLED)
+ si_pmustatstimer_init(sih);
+#endif /* BCMPMU_STATS */
#ifdef BOOTLOADER_CONSOLE_OUTPUT
/* Enable console prints */
si_muxenab(sii, 3);
-#endif
+#endif // endif
return (sii);
@@ -734,7 +1010,6 @@
si_cores_info_t *cores_info = (si_cores_info_t *)sii->cores_info;
uint idx;
-
if (BUSTYPE(sih->bustype) == SI_BUS)
for (idx = 0; idx < SI_MAXCORES; idx++)
if (cores_info->regs[idx]) {
@@ -742,11 +1017,23 @@
cores_info->regs[idx] = NULL;
}
-
#if !defined(BCMBUSTYPE) || (BCMBUSTYPE == SI_BUS)
if (cores_info != &ksii_cores_info)
#endif /* !BCMBUSTYPE || (BCMBUSTYPE == SI_BUS) */
MFREE(sii->osh, cores_info, sizeof(si_cores_info_t));
+
+#if defined(BCM_BACKPLANE_TIMEOUT)
+ if (sih->err_info) {
+ MFREE(sii->osh, sih->err_info, sizeof(si_axi_error_info_t));
+ sii->pub.err_info = NULL;
+ }
+#endif /* BCM_BACKPLANE_TIMEOUT */
+
+ if (sii->axi_wrapper) {
+ MFREE(sii->osh, sii->axi_wrapper,
+ (sizeof(axi_wrapper_t) * SI_MAX_AXI_WRAPPERS));
+ sii->axi_wrapper = NULL;
+ }
#if !defined(BCMBUSTYPE) || (BCMBUSTYPE == SI_BUS)
if (sii != &ksii)
@@ -811,7 +1098,9 @@
if (CHIPTYPE(sih->socitype) == SOCI_SB)
return sb_intflag(sih);
- else if ((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NAI))
+ else if ((CHIPTYPE(sih->socitype) == SOCI_AI) ||
+ (CHIPTYPE(sih->socitype) == SOCI_DVTBUS) ||
+ (CHIPTYPE(sih->socitype) == SOCI_NAI))
return R_REG(sii->osh, ((uint32 *)(uintptr)
(sii->oob_router + OOB_STATUSA)));
else {
@@ -825,7 +1114,9 @@
{
if (CHIPTYPE(sih->socitype) == SOCI_SB)
return sb_flag(sih);
- else if ((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NAI))
+ else if ((CHIPTYPE(sih->socitype) == SOCI_AI) ||
+ (CHIPTYPE(sih->socitype) == SOCI_DVTBUS) ||
+ (CHIPTYPE(sih->socitype) == SOCI_NAI))
return ai_flag(sih);
else if (CHIPTYPE(sih->socitype) == SOCI_UBUS)
return ub_flag(sih);
@@ -838,7 +1129,9 @@
uint
si_flag_alt(si_t *sih)
{
- if ((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NAI))
+ if ((CHIPTYPE(sih->socitype) == SOCI_AI) ||
+ (CHIPTYPE(sih->socitype) == SOCI_DVTBUS) ||
+ (CHIPTYPE(sih->socitype) == SOCI_NAI))
return ai_flag_alt(sih);
else {
ASSERT(0);
@@ -851,12 +1144,31 @@
{
if (CHIPTYPE(sih->socitype) == SOCI_SB)
sb_setint(sih, siflag);
- else if ((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NAI))
+ else if ((CHIPTYPE(sih->socitype) == SOCI_AI) ||
+ (CHIPTYPE(sih->socitype) == SOCI_DVTBUS) ||
+ (CHIPTYPE(sih->socitype) == SOCI_NAI))
ai_setint(sih, siflag);
else if (CHIPTYPE(sih->socitype) == SOCI_UBUS)
ub_setint(sih, siflag);
else
ASSERT(0);
+}
+
+uint32
+si_oobr_baseaddr(si_t *sih, bool second)
+{
+ si_info_t *sii = SI_INFO(sih);
+
+ if (CHIPTYPE(sih->socitype) == SOCI_SB)
+ return 0;
+ else if ((CHIPTYPE(sih->socitype) == SOCI_AI) ||
+ (CHIPTYPE(sih->socitype) == SOCI_DVTBUS) ||
+ (CHIPTYPE(sih->socitype) == SOCI_NAI))
+ return (second ? sii->oob_router1 : sii->oob_router);
+ else {
+ ASSERT(0);
+ return 0;
+ }
}
uint
@@ -877,7 +1189,7 @@
return sii->curidx;
}
-void *
+volatile void *
si_d11_switch_addrbase(si_t *sih, uint coreunit)
{
return si_setcore(sih, D11_CORE_ID, coreunit);
@@ -914,7 +1226,9 @@
{
if (CHIPTYPE(sih->socitype) == SOCI_SB)
return sb_corevendor(sih);
- else if ((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NAI))
+ else if ((CHIPTYPE(sih->socitype) == SOCI_AI) ||
+ (CHIPTYPE(sih->socitype) == SOCI_DVTBUS) ||
+ (CHIPTYPE(sih->socitype) == SOCI_NAI))
return ai_corevendor(sih);
else if (CHIPTYPE(sih->socitype) == SOCI_UBUS)
return ub_corevendor(sih);
@@ -935,7 +1249,9 @@
{
if (CHIPTYPE(sih->socitype) == SOCI_SB)
return sb_corerev(sih);
- else if ((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NAI))
+ else if ((CHIPTYPE(sih->socitype) == SOCI_AI) ||
+ (CHIPTYPE(sih->socitype) == SOCI_DVTBUS) ||
+ (CHIPTYPE(sih->socitype) == SOCI_NAI))
return ai_corerev(sih);
else if (CHIPTYPE(sih->socitype) == SOCI_UBUS)
return ub_corerev(sih);
@@ -945,6 +1261,15 @@
}
}
+uint
+si_corerev_minor(si_t *sih)
+{
+ if (CHIPTYPE(sih->socitype) == SOCI_AI) {
+ return ai_corerev_minor(sih);
+ } else {
+ return 0;
+ }
+}
/* return index of coreid or BADIDX if not found */
uint
@@ -954,7 +1279,6 @@
si_cores_info_t *cores_info = (si_cores_info_t *)sii->cores_info;
uint found;
uint i;
-
found = 0;
@@ -1029,7 +1353,7 @@
}
/** return current register mapping */
-void *
+volatile void *
si_coreregs(si_t *sih)
{
si_info_t *sii;
@@ -1045,7 +1369,7 @@
* must be called with interrupts off.
* Moreover, callers should keep interrupts off during switching out of and back to d11 core
*/
-void *
+volatile void *
si_setcore(si_t *sih, uint coreid, uint coreunit)
{
uint idx;
@@ -1056,7 +1380,9 @@
if (CHIPTYPE(sih->socitype) == SOCI_SB)
return sb_setcoreidx(sih, idx);
- else if ((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NAI))
+ else if ((CHIPTYPE(sih->socitype) == SOCI_AI) ||
+ (CHIPTYPE(sih->socitype) == SOCI_DVTBUS) ||
+ (CHIPTYPE(sih->socitype) == SOCI_NAI))
return ai_setcoreidx(sih, idx);
else if (CHIPTYPE(sih->socitype) == SOCI_UBUS)
return ub_setcoreidx(sih, idx);
@@ -1066,12 +1392,14 @@
}
}
-void *
+volatile void *
si_setcoreidx(si_t *sih, uint coreidx)
{
if (CHIPTYPE(sih->socitype) == SOCI_SB)
return sb_setcoreidx(sih, coreidx);
- else if ((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NAI))
+ else if ((CHIPTYPE(sih->socitype) == SOCI_AI) ||
+ (CHIPTYPE(sih->socitype) == SOCI_DVTBUS) ||
+ (CHIPTYPE(sih->socitype) == SOCI_NAI))
return ai_setcoreidx(sih, coreidx);
else if (CHIPTYPE(sih->socitype) == SOCI_UBUS)
return ub_setcoreidx(sih, coreidx);
@@ -1082,12 +1410,11 @@
}
/** Turn off interrupt as required by sb_setcore, before switch core */
-void *
+volatile void *
si_switch_core(si_t *sih, uint coreid, uint *origidx, uint *intr_val)
{
- void *cc;
+ volatile void *cc;
si_info_t *sii = SI_INFO(sih);
- si_cores_info_t *cores_info = (si_cores_info_t *)sii->cores_info;
if (SI_FAST(sii)) {
/* Overloading the origidx variable to remember the coreid,
@@ -1096,9 +1423,9 @@
*/
*origidx = coreid;
if (coreid == CC_CORE_ID)
- return (void *)CCREGS_FAST(sii);
- else if (coreid == sih->buscoretype)
- return (void *)PCIEREGS(sii);
+ return (volatile void *)CCREGS_FAST(sii);
+ else if (coreid == BUSCORETYPE(sih->buscoretype))
+ return (volatile void *)PCIEREGS(sii);
}
INTR_OFF(sii, *intr_val);
*origidx = sii->curidx;
@@ -1113,9 +1440,8 @@
si_restore_core(si_t *sih, uint coreid, uint intr_val)
{
si_info_t *sii = SI_INFO(sih);
- si_cores_info_t *cores_info = (si_cores_info_t *)sii->cores_info;
- if (SI_FAST(sii) && ((coreid == CC_CORE_ID) || (coreid == sih->buscoretype)))
+ if (SI_FAST(sii) && ((coreid == CC_CORE_ID) || (coreid == BUSCORETYPE(sih->buscoretype))))
return;
si_setcoreidx(sih, coreid);
@@ -1127,7 +1453,9 @@
{
if (CHIPTYPE(sih->socitype) == SOCI_SB)
return sb_numaddrspaces(sih);
- else if ((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NAI))
+ else if ((CHIPTYPE(sih->socitype) == SOCI_AI) ||
+ (CHIPTYPE(sih->socitype) == SOCI_DVTBUS) ||
+ (CHIPTYPE(sih->socitype) == SOCI_NAI))
return ai_numaddrspaces(sih);
else if (CHIPTYPE(sih->socitype) == SOCI_UBUS)
return ub_numaddrspaces(sih);
@@ -1137,30 +1465,47 @@
}
}
+/* Return the address of the nth address space in the current core
+ * Arguments:
+ * sih : Pointer to struct si_t
+ * spidx : slave port index
+ * baidx : base address index
+ */
+
uint32
-si_addrspace(si_t *sih, uint asidx)
+si_addrspace(si_t *sih, uint spidx, uint baidx)
{
if (CHIPTYPE(sih->socitype) == SOCI_SB)
- return sb_addrspace(sih, asidx);
- else if ((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NAI))
- return ai_addrspace(sih, asidx);
+ return sb_addrspace(sih, baidx);
+ else if ((CHIPTYPE(sih->socitype) == SOCI_AI) ||
+ (CHIPTYPE(sih->socitype) == SOCI_DVTBUS) ||
+ (CHIPTYPE(sih->socitype) == SOCI_NAI))
+ return ai_addrspace(sih, spidx, baidx);
else if (CHIPTYPE(sih->socitype) == SOCI_UBUS)
- return ub_addrspace(sih, asidx);
+ return ub_addrspace(sih, baidx);
else {
ASSERT(0);
return 0;
}
}
+/* Return the size of the nth address space in the current core
+ * Arguments:
+ * sih : Pointer to struct si_t
+ * spidx : slave port index
+ * baidx : base address index
+ */
uint32
-si_addrspacesize(si_t *sih, uint asidx)
+si_addrspacesize(si_t *sih, uint spidx, uint baidx)
{
if (CHIPTYPE(sih->socitype) == SOCI_SB)
- return sb_addrspacesize(sih, asidx);
- else if ((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NAI))
- return ai_addrspacesize(sih, asidx);
+ return sb_addrspacesize(sih, baidx);
+ else if ((CHIPTYPE(sih->socitype) == SOCI_AI) ||
+ (CHIPTYPE(sih->socitype) == SOCI_DVTBUS) ||
+ (CHIPTYPE(sih->socitype) == SOCI_NAI))
+ return ai_addrspacesize(sih, spidx, baidx);
else if (CHIPTYPE(sih->socitype) == SOCI_UBUS)
- return ub_addrspacesize(sih, asidx);
+ return ub_addrspacesize(sih, baidx);
else {
ASSERT(0);
return 0;
@@ -1171,7 +1516,9 @@
si_coreaddrspaceX(si_t *sih, uint asidx, uint32 *addr, uint32 *size)
{
/* Only supported for SOCI_AI */
- if ((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NAI))
+ if ((CHIPTYPE(sih->socitype) == SOCI_AI) ||
+ (CHIPTYPE(sih->socitype) == SOCI_DVTBUS) ||
+ (CHIPTYPE(sih->socitype) == SOCI_NAI))
ai_coreaddrspaceX(sih, asidx, addr, size);
else
*size = 0;
@@ -1182,7 +1529,9 @@
{
if (CHIPTYPE(sih->socitype) == SOCI_SB)
return sb_core_cflags(sih, mask, val);
- else if ((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NAI))
+ else if ((CHIPTYPE(sih->socitype) == SOCI_AI) ||
+ (CHIPTYPE(sih->socitype) == SOCI_DVTBUS) ||
+ (CHIPTYPE(sih->socitype) == SOCI_NAI))
return ai_core_cflags(sih, mask, val);
else if (CHIPTYPE(sih->socitype) == SOCI_UBUS)
return ub_core_cflags(sih, mask, val);
@@ -1197,7 +1546,9 @@
{
if (CHIPTYPE(sih->socitype) == SOCI_SB)
sb_core_cflags_wo(sih, mask, val);
- else if ((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NAI))
+ else if ((CHIPTYPE(sih->socitype) == SOCI_AI) ||
+ (CHIPTYPE(sih->socitype) == SOCI_DVTBUS) ||
+ (CHIPTYPE(sih->socitype) == SOCI_NAI))
ai_core_cflags_wo(sih, mask, val);
else if (CHIPTYPE(sih->socitype) == SOCI_UBUS)
ub_core_cflags_wo(sih, mask, val);
@@ -1210,7 +1561,9 @@
{
if (CHIPTYPE(sih->socitype) == SOCI_SB)
return sb_core_sflags(sih, mask, val);
- else if ((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NAI))
+ else if ((CHIPTYPE(sih->socitype) == SOCI_AI) ||
+ (CHIPTYPE(sih->socitype) == SOCI_DVTBUS) ||
+ (CHIPTYPE(sih->socitype) == SOCI_NAI))
return ai_core_sflags(sih, mask, val);
else if (CHIPTYPE(sih->socitype) == SOCI_UBUS)
return ub_core_sflags(sih, mask, val);
@@ -1220,12 +1573,30 @@
}
}
+void
+si_commit(si_t *sih)
+{
+ if (CHIPTYPE(sih->socitype) == SOCI_SB)
+ sb_commit(sih);
+ else if ((CHIPTYPE(sih->socitype) == SOCI_AI) ||
+ (CHIPTYPE(sih->socitype) == SOCI_DVTBUS) ||
+ (CHIPTYPE(sih->socitype) == SOCI_NAI))
+ ;
+ else if (CHIPTYPE(sih->socitype) == SOCI_UBUS)
+ ;
+ else {
+ ASSERT(0);
+ }
+}
+
bool
si_iscoreup(si_t *sih)
{
if (CHIPTYPE(sih->socitype) == SOCI_SB)
return sb_iscoreup(sih);
- else if ((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NAI))
+ else if ((CHIPTYPE(sih->socitype) == SOCI_AI) ||
+ (CHIPTYPE(sih->socitype) == SOCI_DVTBUS) ||
+ (CHIPTYPE(sih->socitype) == SOCI_NAI))
return ai_iscoreup(sih);
else if (CHIPTYPE(sih->socitype) == SOCI_UBUS)
return ub_iscoreup(sih);
@@ -1239,7 +1610,9 @@
si_wrapperreg(si_t *sih, uint32 offset, uint32 mask, uint32 val)
{
/* only for AI back plane chips */
- if ((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NAI))
+ if ((CHIPTYPE(sih->socitype) == SOCI_AI) ||
+ (CHIPTYPE(sih->socitype) == SOCI_DVTBUS) ||
+ (CHIPTYPE(sih->socitype) == SOCI_NAI))
return (ai_wrap_reg(sih, offset, mask, val));
return 0;
}
@@ -1272,13 +1645,20 @@
bcmerror = BCME_ERROR;
}
}
-
return bcmerror;
}
-uint
+
+void
+si_invalidate_second_bar0win(si_t *sih)
+{
+ si_info_t *sii = SI_INFO(sih);
+ sii->second_bar0win = ~0x0;
+}
+
+int
si_backplane_access(si_t *sih, uint addr, uint size, uint *val, bool read)
{
- uint32 *r = NULL;
+ volatile uint32 *r = NULL;
uint32 region = 0;
si_info_t *sii = SI_INFO(sih);
@@ -1307,31 +1687,30 @@
* PCI_SECOND_BAR0_OFFSET : secondar bar-0 offset
* regoff : actual reg offset
*/
- r = (uint32 *)((char *)sii->curmap + PCI_SECOND_BAR0_OFFSET + addr);
+ r = (volatile uint32 *)((volatile char *)sii->curmap + PCI_SECOND_BAR0_OFFSET + addr);
SI_VMSG(("si curmap %p region %x regaddr %x effective addr %p READ %d\n",
- (char*)sii->curmap, region, addr, r, read));
+ (volatile char*)sii->curmap, region, addr, r, read));
switch (size) {
case sizeof(uint8) :
if (read)
- *val = R_REG(sii->osh, (uint8*)r);
+ *val = R_REG(sii->osh, (volatile uint8*)r);
else
- W_REG(sii->osh, (uint8*)r, *val);
+ W_REG(sii->osh, (volatile uint8*)r, *val);
break;
case sizeof(uint16) :
if (read)
- *val = R_REG(sii->osh, (uint16*)r);
+ *val = R_REG(sii->osh, (volatile uint16*)r);
else
- W_REG(sii->osh, (uint16*)r, *val);
+ W_REG(sii->osh, (volatile uint16*)r, *val);
break;
case sizeof(uint32) :
if (read)
- *val = R_REG(sii->osh, (uint32*)r);
+ *val = R_REG(sii->osh, (volatile uint32*)r);
else
- W_REG(sii->osh, (uint32*)r, *val);
+ W_REG(sii->osh, (volatile uint32*)r, *val);
break;
-
default :
SI_ERROR(("Invalid size %d \n", size));
return (BCME_ERROR);
@@ -1345,7 +1724,9 @@
{
if (CHIPTYPE(sih->socitype) == SOCI_SB)
return sb_corereg(sih, coreidx, regoff, mask, val);
- else if ((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NAI))
+ else if ((CHIPTYPE(sih->socitype) == SOCI_AI) ||
+ (CHIPTYPE(sih->socitype) == SOCI_DVTBUS) ||
+ (CHIPTYPE(sih->socitype) == SOCI_NAI))
return ai_corereg(sih, coreidx, regoff, mask, val);
else if (CHIPTYPE(sih->socitype) == SOCI_UBUS)
return ub_corereg(sih, coreidx, regoff, mask, val);
@@ -1353,6 +1734,12 @@
ASSERT(0);
return 0;
}
+}
+
+uint
+si_corereg_writeonly(si_t *sih, uint coreidx, uint regoff, uint mask, uint val)
+{
+ return ai_corereg_writeonly(sih, coreidx, regoff, mask, val);
}
/** ILP sensitive register access needs special treatment to avoid backplane stalls */
@@ -1375,7 +1762,7 @@
int pmustatus_offset;
/* prevent backplane stall on double write to 'ILP domain' registers in the PMU */
- if (mask != 0 && sih->pmurev >= 22 &&
+ if (mask != 0 && PMUREV(sih->pmurev) >= 22 &&
si_pmu_is_ilp_sensitive(idx, regoff)) {
pmustatus_offset = AOB_ENAB(sih) ? OFFSETOF(pmuregs_t, pmustatus) :
OFFSETOF(chipcregs_t, pmustatus);
@@ -1396,12 +1783,14 @@
* For accessing registers that would need a core switch, this function will return
* NULL.
*/
-uint32 *
+volatile uint32 *
si_corereg_addr(si_t *sih, uint coreidx, uint regoff)
{
if (CHIPTYPE(sih->socitype) == SOCI_SB)
return sb_corereg_addr(sih, coreidx, regoff);
- else if ((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NAI))
+ else if ((CHIPTYPE(sih->socitype) == SOCI_AI) ||
+ (CHIPTYPE(sih->socitype) == SOCI_DVTBUS) ||
+ (CHIPTYPE(sih->socitype) == SOCI_NAI))
return ai_corereg_addr(sih, coreidx, regoff);
else {
return 0;
@@ -1413,7 +1802,9 @@
{
if (CHIPTYPE(sih->socitype) == SOCI_SB)
sb_core_disable(sih, bits);
- else if ((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NAI))
+ else if ((CHIPTYPE(sih->socitype) == SOCI_AI) ||
+ (CHIPTYPE(sih->socitype) == SOCI_DVTBUS) ||
+ (CHIPTYPE(sih->socitype) == SOCI_NAI))
ai_core_disable(sih, bits);
else if (CHIPTYPE(sih->socitype) == SOCI_UBUS)
ub_core_disable(sih, bits);
@@ -1424,7 +1815,9 @@
{
if (CHIPTYPE(sih->socitype) == SOCI_SB)
sb_core_reset(sih, bits, resetbits);
- else if ((CHIPTYPE(sih->socitype) == SOCI_AI) || (CHIPTYPE(sih->socitype) == SOCI_NAI))
+ else if ((CHIPTYPE(sih->socitype) == SOCI_AI) ||
+ (CHIPTYPE(sih->socitype) == SOCI_DVTBUS) ||
+ (CHIPTYPE(sih->socitype) == SOCI_NAI))
ai_core_reset(sih, bits, resetbits);
else if (CHIPTYPE(sih->socitype) == SOCI_UBUS)
ub_core_reset(sih, bits, resetbits);
@@ -1455,6 +1848,64 @@
return result;
}
+uint
+si_num_slaveports(si_t *sih, uint coreid)
+{
+ uint idx = si_findcoreidx(sih, coreid, 0);
+ uint num = 0;
+
+ if (idx != BADIDX) {
+ if (CHIPTYPE(sih->socitype) == SOCI_AI) {
+ num = ai_num_slaveports(sih, idx);
+ }
+ }
+ return num;
+}
+
+uint32
+si_get_slaveport_addr(si_t *sih, uint spidx, uint baidx, uint core_id, uint coreunit)
+{
+ si_info_t *sii = SI_INFO(sih);
+ uint origidx = sii->curidx;
+ uint32 addr = 0x0;
+
+ if (!((CHIPTYPE(sih->socitype) == SOCI_AI) ||
+ (CHIPTYPE(sih->socitype) == SOCI_DVTBUS) ||
+ (CHIPTYPE(sih->socitype) == SOCI_NAI)))
+ goto done;
+
+ si_setcore(sih, core_id, coreunit);
+
+ addr = ai_addrspace(sih, spidx, baidx);
+
+ si_setcoreidx(sih, origidx);
+
+done:
+ return addr;
+}
+
+uint32
+si_get_d11_slaveport_addr(si_t *sih, uint spidx, uint baidx, uint coreunit)
+{
+ si_info_t *sii = SI_INFO(sih);
+ uint origidx = sii->curidx;
+ uint32 addr = 0x0;
+
+ if (!((CHIPTYPE(sih->socitype) == SOCI_AI) ||
+ (CHIPTYPE(sih->socitype) == SOCI_DVTBUS) ||
+ (CHIPTYPE(sih->socitype) == SOCI_NAI)))
+ goto done;
+
+ si_setcore(sih, D11_CORE_ID, coreunit);
+
+ addr = ai_addrspace(sih, spidx, baidx);
+
+ si_setcoreidx(sih, origidx);
+
+done:
+ return addr;
+}
+
static uint32
factor6(uint32 x)
{
@@ -1478,7 +1929,6 @@
{
return div ? clock / div : 0;
}
-
/** calculate the speed the SI would run at given a set of clockcontrol values */
uint32
@@ -1562,7 +2012,6 @@
return (clock);
}
- return 0;
}
/**
@@ -1575,7 +2024,13 @@
uint hosti = 0;
switch (CHIPID(sih->chip)) {
-
+ case BCM43018_CHIP_ID:
+ case BCM43430_CHIP_ID:
+ hosti = CHIP_HOSTIF_SDIOMODE;
+ break;
+ case BCM43012_CHIP_ID:
+ hosti = CHIP_HOSTIF_SDIOMODE;
+ break;
CASE_BCM43602_CHIP:
hosti = CHIP_HOSTIF_PCIEMODE;
break;
@@ -1601,8 +2056,7 @@
hosti = CHIP_HOSTIF_PCIEMODE;
break;
- case BCM4345_CHIP_ID:
- case BCM43454_CHIP_ID:
+ CASE_BCM4345_CHIP:
if (CST4345_CHIPMODE_USB20D(sih->chipst) || CST4345_CHIPMODE_HSIC(sih->chipst))
hosti = CHIP_HOSTIF_USBMODE;
else if (CST4345_CHIPMODE_SDIOD(sih->chipst))
@@ -1612,22 +2066,47 @@
break;
case BCM4349_CHIP_GRPID:
+ case BCM53573_CHIP_GRPID:
if (CST4349_CHIPMODE_SDIOD(sih->chipst))
hosti = CHIP_HOSTIF_SDIOMODE;
else if (CST4349_CHIPMODE_PCIE(sih->chipst))
hosti = CHIP_HOSTIF_PCIEMODE;
break;
+ case BCM4364_CHIP_ID:
+ if (CST4364_CHIPMODE_SDIOD(sih->chipst))
+ hosti = CHIP_HOSTIF_SDIOMODE;
+ else if (CST4364_CHIPMODE_PCIE(sih->chipst))
+ hosti = CHIP_HOSTIF_PCIEMODE;
+ break;
case BCM4373_CHIP_ID:
- if (CST4373_CHIPMODE_USB20D(sih->chipst))
- hosti = CHIP_HOSTIF_USBMODE;
- else if (CST4373_CHIPMODE_SDIOD(sih->chipst))
- hosti = CHIP_HOSTIF_SDIOMODE;
- else if (CST4373_CHIPMODE_PCIE(sih->chipst))
- hosti = CHIP_HOSTIF_PCIEMODE;
- break;
+ if (CST4373_CHIPMODE_USB20D(sih->chipst))
+ hosti = CHIP_HOSTIF_USBMODE;
+ else if (CST4373_CHIPMODE_SDIOD(sih->chipst))
+ hosti = CHIP_HOSTIF_SDIOMODE;
+ else if (CST4373_CHIPMODE_PCIE(sih->chipst))
+ hosti = CHIP_HOSTIF_PCIEMODE;
+ break;
+
+ case BCM4347_CHIP_GRPID:
+ if (CST4347_CHIPMODE_SDIOD(sih->chipst))
+ hosti = CHIP_HOSTIF_SDIOMODE;
+ else if (CST4347_CHIPMODE_PCIE(sih->chipst))
+ hosti = CHIP_HOSTIF_PCIEMODE;
+ break;
+ case BCM4369_CHIP_GRPID:
+ if (CST4369_CHIPMODE_SDIOD(sih->chipst))
+ hosti = CHIP_HOSTIF_SDIOMODE;
+ else if (CST4369_CHIPMODE_PCIE(sih->chipst))
+ hosti = CHIP_HOSTIF_PCIEMODE;
+ break;
+#ifdef CHIPS_CUSTOMER_HW6
+ case BCM4368_CHIP_GRPID:
+ hosti = CHIP_HOSTIF_PCIEMODE;
+ break;
+#endif /* CHIPS_CUSTOMER_HW6 */
+
case BCM4350_CHIP_ID:
case BCM4354_CHIP_ID:
- case BCM4356_CHIP_ID:
case BCM43556_CHIP_ID:
case BCM43558_CHIP_ID:
case BCM43566_CHIP_ID:
@@ -1654,26 +2133,15 @@
return hosti;
}
-
/** set chip watchdog reset timer to fire in 'ticks' */
void
si_watchdog(si_t *sih, uint ticks)
{
uint nb, maxt;
+ uint pmu_wdt = 1;
- if (PMUCTL_ENAB(sih)) {
-
-#if !defined(_CFEZ_) || defined(CFG_WL)
- if ((CHIPID(sih->chip) == BCM4319_CHIP_ID) &&
- (CHIPREV(sih->chiprev) == 0) && (ticks != 0)) {
- si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, clk_ctl_st), ~0, 0x2);
- si_setcore(sih, USB20D_CORE_ID, 0);
- si_core_disable(sih, 1);
- si_setcore(sih, CC_CORE_ID, 0);
- }
-#endif
-
- nb = (sih->ccrev < 26) ? 16 : ((sih->ccrev >= 37) ? 32 : 24);
+ if (PMUCTL_ENAB(sih) && pmu_wdt) {
+ nb = (CCREV(sih->ccrev) < 26) ? 16 : ((CCREV(sih->ccrev) >= 37) ? 32 : 24);
/* The mips compiler uses the sllv instruction,
* so we specially handle the 32-bit case.
*/
@@ -1694,8 +2162,13 @@
SPINWAIT((PMU_REG(sih, pmustatus, 0, 0) & PST_ILPFASTLPO),
PMU_MAX_TRANSITION_DLY);
}
-
- pmu_corereg(sih, SI_CC_IDX, pmuwatchdog, ~0, ticks);
+ if (sih->chip == CYW55500_CHIP_ID ||
+ sih->chip == CYW55560_CHIP_ID) {
+ si_corereg(sih, si_findcoreidx(sih, PMU_CORE_ID, 0),
+ OFFSETOF(pmuregs_t, pmuwatchdog), ~0, ticks);
+ } else {
+ pmu_corereg(sih, SI_CC_IDX, pmuwatchdog, ~0, ticks);
+ }
} else {
maxt = (1 << 28) - 1;
if (ticks > maxt)
@@ -1723,8 +2196,6 @@
return FALSE;
}
-
-
/** return the slow clock source - LPO, XTAL, or PCI */
static uint
si_slowclk_src(si_info_t *sii)
@@ -1733,14 +2204,14 @@
ASSERT(SI_FAST(sii) || si_coreid(&sii->pub) == CC_CORE_ID);
- if (sii->pub.ccrev < 6) {
+ if (CCREV(sii->pub.ccrev) < 6) {
if ((BUSTYPE(sii->pub.bustype) == PCI_BUS) &&
(OSL_PCI_READ_CONFIG(sii->osh, PCI_GPIO_OUT, sizeof(uint32)) &
PCI_CFG_GPIO_SCS))
return (SCC_SS_PCI);
else
return (SCC_SS_XTAL);
- } else if (sii->pub.ccrev < 10) {
+ } else if (CCREV(sii->pub.ccrev) < 10) {
cc = (chipcregs_t *)si_setcoreidx(&sii->pub, sii->curidx);
ASSERT(cc);
return (R_REG(sii->osh, &cc->slow_clk_ctl) & SCC_SS_MASK);
@@ -1761,12 +2232,12 @@
ASSERT(R_REG(sii->osh, &cc->capabilities) & CC_CAP_PWR_CTL);
slowclk = si_slowclk_src(sii);
- if (sii->pub.ccrev < 6) {
+ if (CCREV(sii->pub.ccrev) < 6) {
if (slowclk == SCC_SS_PCI)
return (max_freq ? (PCIMAXFREQ / 64) : (PCIMINFREQ / 64));
else
return (max_freq ? (XTALMAXFREQ / 32) : (XTALMINFREQ / 32));
- } else if (sii->pub.ccrev < 10) {
+ } else if (CCREV(sii->pub.ccrev) < 10) {
div = 4 *
(((R_REG(sii->osh, &cc->slow_clk_ctl) & SCC_CD_MASK) >> SCC_CD_SHIFT) + 1);
if (slowclk == SCC_SS_LPO)
@@ -1804,7 +2275,7 @@
pll_delay += XTAL_ON_DELAY;
/* Starting with 4318 it is ILP that is used for the delays */
- slowmaxfreq = si_slowclk_freq(sii, (sii->pub.ccrev >= 10) ? FALSE : TRUE, cc);
+ slowmaxfreq = si_slowclk_freq(sii, (CCREV(sii->pub.ccrev) >= 10) ? FALSE : TRUE, cc);
pll_on_delay = ((slowmaxfreq * pll_delay) + 999999) / 1000000;
fref_sel_delay = ((slowmaxfreq * FREF_DELAY) + 999999) / 1000000;
@@ -1836,7 +2307,7 @@
ASSERT(cc != NULL);
/* set all Instaclk chip ILP to 1 MHz */
- if (sih->ccrev >= 10)
+ if (CCREV(sih->ccrev) >= 10)
SET_REG(sii->osh, &cc->system_clk_ctl, SYCC_CD_MASK,
(ILP_DIV_1MHZ << SYCC_CD_SHIFT));
@@ -1848,9 +2319,8 @@
si_setcoreidx(sih, origidx);
}
-
/** change logical "focus" to the gpio core for optimized access */
-void *
+volatile void *
si_gpiosetcore(si_t *sih)
{
return (si_setcoreidx(sih, SI_CC_IDX));
@@ -2029,11 +2499,25 @@
return (si_corereg(sih, SI_CC_IDX, regoff, mask, val));
}
+uint32
+si_gpioeventintmask(si_t *sih, uint32 mask, uint32 val, uint8 priority)
+{
+ uint regoff;
+ /* gpios could be shared on router platforms */
+ if ((BUSTYPE(sih->bustype) == SI_BUS) && (val || mask)) {
+ mask = priority ? (si_gpioreservation & mask) :
+ ((si_gpioreservation | mask) & ~(si_gpioreservation));
+ val &= mask;
+ }
+ regoff = OFFSETOF(chipcregs_t, gpioeventintmask);
+ return (si_corereg(sih, SI_CC_IDX, regoff, mask, val));
+}
+
/* assign the gpio to an led */
uint32
si_gpioled(si_t *sih, uint32 mask, uint32 val)
{
- if (sih->ccrev < 16)
+ if (CCREV(sih->ccrev) < 16)
return 0xffffffff;
/* gpio led powersave reg */
@@ -2044,7 +2528,7 @@
uint32
si_gpiotimerval(si_t *sih, uint32 mask, uint32 gpiotimerval)
{
- if (sih->ccrev < 16)
+ if (CCREV(sih->ccrev) < 16)
return 0xffffffff;
return (si_corereg(sih, SI_CC_IDX,
@@ -2056,7 +2540,7 @@
{
uint offs;
- if (sih->ccrev < 20)
+ if (CCREV(sih->ccrev) < 20)
return 0xffffffff;
offs = (updown ? OFFSETOF(chipcregs_t, gpiopulldown) : OFFSETOF(chipcregs_t, gpiopullup));
@@ -2068,7 +2552,7 @@
{
uint offs;
- if (sih->ccrev < 11)
+ if (CCREV(sih->ccrev) < 11)
return 0xffffffff;
if (regtype == GPIO_REGEVT)
@@ -2088,7 +2572,7 @@
{
uint offs;
- if (sih->ccrev < 11)
+ if (CCREV(sih->ccrev) < 11)
return 0xffffffff;
offs = OFFSETOF(chipcregs_t, intmask);
@@ -2113,7 +2597,6 @@
si_sysmem_size(si_t *sih)
{
si_info_t *sii = SI_INFO(sih);
- si_cores_info_t *cores_info = (si_cores_info_t *)sii->cores_info;
uint origidx;
uint intr_val = 0;
@@ -2170,7 +2653,6 @@
void si_socram_set_bankpda(si_t *sih, uint32 bankidx, uint32 bankpda)
{
si_info_t *sii = SI_INFO(sih);
- si_cores_info_t *cores_info = (si_cores_info_t *)sii->cores_info;
uint origidx;
uint intr_val = 0;
sbsocramregs_t *regs;
@@ -2207,7 +2689,6 @@
si_socdevram(si_t *sih, bool set, uint8 *enable, uint8 *protect, uint8 *remap)
{
si_info_t *sii = SI_INFO(sih);
- si_cores_info_t *cores_info = (si_cores_info_t *)sii->cores_info;
uint origidx;
uint intr_val = 0;
sbsocramregs_t *regs;
@@ -2255,8 +2736,7 @@
(1 << SOCRAM_BANKINFO_DEVRAMREMAP_SHIFT);
}
W_REG(sii->osh, ®s->bankinfo, bankinfo);
- }
- else if (i == 0) {
+ } else if (i == 0) {
if (bankinfo & SOCRAM_BANKINFO_DEVRAMSEL_MASK) {
*enable = 1;
if (bankinfo & SOCRAM_BANKINFO_DEVRAMPRO_MASK)
@@ -2281,7 +2761,6 @@
si_socdevram_remap_isenb(si_t *sih)
{
si_info_t *sii = SI_INFO(sih);
- si_cores_info_t *cores_info = (si_cores_info_t *)sii->cores_info;
uint origidx;
uint intr_val = 0;
sbsocramregs_t *regs;
@@ -2342,7 +2821,6 @@
si_socdevram_size(si_t *sih)
{
si_info_t *sii = SI_INFO(sih);
- si_cores_info_t *cores_info = (si_cores_info_t *)sii->cores_info;
uint origidx;
uint intr_val = 0;
uint32 memsize = 0;
@@ -2389,7 +2867,6 @@
si_socdevram_remap_size(si_t *sih)
{
si_info_t *sii = SI_INFO(sih);
- si_cores_info_t *cores_info = (si_cores_info_t *)sii->cores_info;
uint origidx;
uint intr_val = 0;
uint32 memsize = 0, banksz;
@@ -2455,7 +2932,6 @@
si_socram_size(si_t *sih)
{
si_info_t *sii = SI_INFO(sih);
- si_cores_info_t *cores_info = (si_cores_info_t *)sii->cores_info;
uint origidx;
uint intr_val = 0;
@@ -2518,27 +2994,26 @@
return memsize;
}
-
/** Return the TCM-RAM size of the ARMCR4 core. */
uint32
si_tcm_size(si_t *sih)
{
si_info_t *sii = SI_INFO(sih);
- si_cores_info_t *cores_info = (si_cores_info_t *)sii->cores_info;
uint origidx;
uint intr_val = 0;
- uint8 *regs;
- bool wasup;
+ volatile uint8 *regs;
+ bool wasup = FALSE;
uint32 corecap;
uint memsize = 0;
+ uint banku_size = 0;
uint32 nab = 0;
uint32 nbb = 0;
uint32 totb = 0;
uint32 bxinfo = 0;
uint32 idx = 0;
- uint32 *arm_cap_reg;
- uint32 *arm_bidx;
- uint32 *arm_binfo;
+ volatile uint32 *arm_cap_reg;
+ volatile uint32 *arm_bidx;
+ volatile uint32 *arm_binfo;
/* Block ints and save current core */
INTR_OFF(sii, intr_val);
@@ -2551,28 +3026,37 @@
/* Get info for determining size. If in reset, come out of reset,
* but remain in halt
*/
- if (!(wasup = si_iscoreup(sih)))
- si_core_reset(sih, SICF_CPUHALT, SICF_CPUHALT);
+ if (!sih->secureboot) {
+ if (!(wasup = si_iscoreup(sih)))
+ si_core_reset(sih, SICF_CPUHALT, SICF_CPUHALT);
+ }
- arm_cap_reg = (uint32 *)(regs + SI_CR4_CAP);
+ arm_cap_reg = (volatile uint32 *)(regs + SI_CR4_CAP);
corecap = R_REG(sii->osh, arm_cap_reg);
nab = (corecap & ARMCR4_TCBANB_MASK) >> ARMCR4_TCBANB_SHIFT;
nbb = (corecap & ARMCR4_TCBBNB_MASK) >> ARMCR4_TCBBNB_SHIFT;
totb = nab + nbb;
- arm_bidx = (uint32 *)(regs + SI_CR4_BANKIDX);
- arm_binfo = (uint32 *)(regs + SI_CR4_BANKINFO);
+ arm_bidx = (volatile uint32 *)(regs + SI_CR4_BANKIDX);
+ arm_binfo = (volatile uint32 *)(regs + SI_CR4_BANKINFO);
for (idx = 0; idx < totb; idx++) {
W_REG(sii->osh, arm_bidx, idx);
bxinfo = R_REG(sii->osh, arm_binfo);
- memsize += ((bxinfo & ARMCR4_BSZ_MASK) + 1) * ARMCR4_BSZ_MULT;
+ if (bxinfo & ARMCR4_BUNITSZ_MASK) {
+ banku_size = ARMCR4_BSZ_1K;
+ } else {
+ banku_size = ARMCR4_BSZ_8K;
+ }
+ memsize += ((bxinfo & ARMCR4_BSZ_MASK) + 1) * banku_size;
}
/* Return to previous state and core */
- if (!wasup)
- si_core_disable(sih, 0);
+ if (!sih->secureboot) {
+ if (!wasup)
+ si_core_disable(sih, 0);
+ }
si_setcoreidx(sih, origidx);
done:
@@ -2602,7 +3086,6 @@
si_socram_srmem_size(si_t *sih)
{
si_info_t *sii = SI_INFO(sih);
- si_cores_info_t *cores_info = (si_cores_info_t *)sii->cores_info;
uint origidx;
uint intr_val = 0;
@@ -2611,10 +3094,6 @@
uint corerev;
uint32 coreinfo;
uint memsize = 0;
-
- if ((CHIPID(sih->chip) == BCM4334_CHIP_ID) && (CHIPREV(sih->chiprev) < 2)) {
- return (32 * 1024);
- }
if (CHIPID(sih->chip) == BCM43430_CHIP_ID ||
CHIPID(sih->chip) == BCM43018_CHIP_ID) {
@@ -2657,13 +3136,11 @@
return memsize;
}
-
#if !defined(_CFEZ_) || defined(CFG_WL)
void
si_btcgpiowar(si_t *sih)
{
si_info_t *sii = SI_INFO(sih);
- si_cores_info_t *cores_info = (si_cores_info_t *)sii->cores_info;
uint origidx;
uint intr_val = 0;
chipcregs_t *cc;
@@ -2683,43 +3160,6 @@
ASSERT(cc != NULL);
W_REG(sii->osh, &cc->uart0mcr, R_REG(sii->osh, &cc->uart0mcr) | 0x04);
-
- /* restore the original index */
- si_setcoreidx(sih, origidx);
-
- INTR_RESTORE(sii, intr_val);
-}
-
-void
-si_chipcontrl_btshd0_4331(si_t *sih, bool on)
-{
- si_info_t *sii = SI_INFO(sih);
- si_cores_info_t *cores_info = (si_cores_info_t *)sii->cores_info;
- chipcregs_t *cc;
- uint origidx;
- uint32 val;
- uint intr_val = 0;
-
- INTR_OFF(sii, intr_val);
-
- origidx = si_coreidx(sih);
-
- if ((cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0)) == NULL) {
- SI_ERROR(("%s: Failed to find CORE ID!\n", __FUNCTION__));
- return;
- }
-
- val = R_REG(sii->osh, &cc->chipcontrol);
-
- /* bt_shd0 controls are same for 4331 chiprevs 0 and 1, packages 12x9 and 12x12 */
- if (on) {
- /* Enable bt_shd0 on gpio4: */
- val |= (CCTRL4331_BT_SHD0_ON_GPIO4);
- W_REG(sii->osh, &cc->chipcontrol, val);
- } else {
- val &= ~(CCTRL4331_BT_SHD0_ON_GPIO4);
- W_REG(sii->osh, &cc->chipcontrol, val);
- }
/* restore the original index */
si_setcoreidx(sih, origidx);
@@ -2759,42 +3199,6 @@
return val;
}
-void
-si_chipcontrl_epa4331(si_t *sih, bool on)
-{
- si_info_t *sii = SI_INFO(sih);
- chipcregs_t *cc;
- uint origidx = si_coreidx(sih);
- uint32 val;
-
- if ((cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0)) == NULL) {
- SI_ERROR(("%s: Failed to find CORE ID!\n", __FUNCTION__));
- return;
- }
- val = R_REG(sii->osh, &cc->chipcontrol);
-
- if (on) {
- if (sih->chippkg == 9 || sih->chippkg == 0xb) {
- val |= (CCTRL4331_EXTPA_EN | CCTRL4331_EXTPA_ON_GPIO2_5);
- /* Ext PA Controls for 4331 12x9 Package */
- W_REG(sii->osh, &cc->chipcontrol, val);
- } else {
- /* Ext PA Controls for 4331 12x12 Package */
- if (CHIPREV(sih->chiprev) > 0) {
- W_REG(sii->osh, &cc->chipcontrol, val |
- (CCTRL4331_EXTPA_EN) | (CCTRL4331_EXTPA_EN2));
- } else {
- W_REG(sii->osh, &cc->chipcontrol, val | (CCTRL4331_EXTPA_EN));
- }
- }
- } else {
- val &= ~(CCTRL4331_EXTPA_EN | CCTRL4331_EXTPA_EN2 | CCTRL4331_EXTPA_ON_GPIO2_5);
- W_REG(sii->osh, &cc->chipcontrol, val);
- }
-
- si_setcoreidx(sih, origidx);
-}
-
/** switch muxed pins, on: SROM, off: FEMCTRL. Called for a family of ac chips, not just 4360. */
void
si_chipcontrl_srom4360(si_t *sih, bool on)
@@ -2824,141 +3228,41 @@
si_setcoreidx(sih, origidx);
}
+/**
+ * The SROM clock is derived from the backplane clock. 4365 (200Mhz) and 43684 (240Mhz) have a fast
+ * backplane clock that requires a higher-than-POR-default clock divisor ratio for the SROM clock.
+ */
void
-si_clk_srom4365(si_t *sih)
+si_srom_clk_set(si_t *sih)
{
si_info_t *sii = SI_INFO(sih);
chipcregs_t *cc;
uint origidx = si_coreidx(sih);
uint32 val;
+ uint32 divisor = 1;
if ((cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0)) == NULL) {
SI_ERROR(("%s: Failed to find CORE ID!\n", __FUNCTION__));
return;
}
+
val = R_REG(sii->osh, &cc->clkdiv2);
- W_REG(sii->osh, &cc->clkdiv2, ((val&~0xf) | 0x4));
-
- si_setcoreidx(sih, origidx);
-}
-
-void
-si_d11rsdb_core1_alt_reg_clk_dis(si_t *sih)
-{
-#if defined(WLRSDB) && !defined(WLRSDB_DISABLED)
- ai_d11rsdb_core1_alt_reg_clk_dis(sih);
-#endif /* defined(WLRSDB) && !defined(WLRSDB_DISABLED) */
-}
-
-void
-si_d11rsdb_core1_alt_reg_clk_en(si_t *sih)
-{
-#if defined(WLRSDB) && !defined(WLRSDB_DISABLED)
- ai_d11rsdb_core1_alt_reg_clk_en(sih);
-#endif /* defined(WLRSDB) && !defined(WLRSDB_DISABLED) */
-}
-
-void
-si_chipcontrl_epa4331_wowl(si_t *sih, bool enter_wowl)
-{
- si_info_t *sii;
- chipcregs_t *cc;
- uint origidx;
- uint32 val;
- bool sel_chip;
-
- sel_chip = (CHIPID(sih->chip) == BCM4331_CHIP_ID) ||
- (CHIPID(sih->chip) == BCM43431_CHIP_ID);
- sel_chip &= ((sih->chippkg == 9 || sih->chippkg == 0xb));
-
- if (!sel_chip)
- return;
-
- sii = SI_INFO(sih);
- origidx = si_coreidx(sih);
-
- if ((cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0)) == NULL) {
- SI_ERROR(("%s: Failed to find CORE ID!\n", __FUNCTION__));
- return;
- }
-
- val = R_REG(sii->osh, &cc->chipcontrol);
-
- if (enter_wowl) {
- val |= CCTRL4331_EXTPA_EN;
- W_REG(sii->osh, &cc->chipcontrol, val);
+ if (BCM4365_CHIP(sih->chip)) {
+ divisor = CLKD2_SROMDIV_192; /* divide 200 by 192 -> SPROM clock ~ 1.04Mhz */
} else {
- val |= (CCTRL4331_EXTPA_EN | CCTRL4331_EXTPA_ON_GPIO2_5);
- W_REG(sii->osh, &cc->chipcontrol, val);
- }
- si_setcoreidx(sih, origidx);
-}
-#endif
-
-uint
-si_pll_reset(si_t *sih)
-{
- uint err = 0;
-
- return (err);
-}
-
-/** Enable BT-COEX & Ex-PA for 4313 */
-void
-si_epa_4313war(si_t *sih)
-{
- si_info_t *sii = SI_INFO(sih);
- chipcregs_t *cc;
- uint origidx = si_coreidx(sih);
-
- if ((cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0)) == NULL) {
- SI_ERROR(("%s: Failed to find CORE ID!\n", __FUNCTION__));
- return;
+ ASSERT(0);
}
- /* EPA Fix */
- W_REG(sii->osh, &cc->gpiocontrol,
- R_REG(sii->osh, &cc->gpiocontrol) | GPIO_CTRL_EPA_EN_MASK);
-
+ W_REG(sii->osh, &cc->clkdiv2, ((val & ~CLKD2_SROM) | divisor));
si_setcoreidx(sih, origidx);
}
-
-void
-si_clk_pmu_htavail_set(si_t *sih, bool set_clear)
-{
-}
+#endif // endif
void
si_pmu_avb_clk_set(si_t *sih, osl_t *osh, bool set_flag)
{
}
-/** Re-enable synth_pwrsw resource in min_res_mask for 4313 */
-void
-si_pmu_synth_pwrsw_4313_war(si_t *sih)
-{
-}
-
-/** WL/BT control for 4313 btcombo boards >= P250 */
-void
-si_btcombo_p250_4313_war(si_t *sih)
-{
- si_info_t *sii = SI_INFO(sih);
- chipcregs_t *cc;
- uint origidx = si_coreidx(sih);
-
- if ((cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0)) == NULL) {
- SI_ERROR(("%s: Failed to find CORE ID!\n", __FUNCTION__));
- return;
- }
- W_REG(sii->osh, &cc->gpiocontrol,
- R_REG(sii->osh, &cc->gpiocontrol) | GPIO_CTRL_5_6_EN_MASK);
-
- W_REG(sii->osh, &cc->gpioouten,
- R_REG(sii->osh, &cc->gpioouten) | GPIO_CTRL_5_6_EN_MASK);
-
- si_setcoreidx(sih, origidx);
-}
void
si_btc_enable_chipcontrol(si_t *sih)
{
@@ -2977,22 +3281,13 @@
si_setcoreidx(sih, origidx);
}
-void
-si_btcombo_43228_war(si_t *sih)
+
+/** cache device removed state */
+void si_set_device_removed(si_t *sih, bool status)
{
si_info_t *sii = SI_INFO(sih);
- chipcregs_t *cc;
- uint origidx = si_coreidx(sih);
- if ((cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0)) == NULL) {
- SI_ERROR(("%s: Failed to find CORE ID!\n", __FUNCTION__));
- return;
- }
-
- W_REG(sii->osh, &cc->gpioouten, GPIO_CTRL_7_6_EN_MASK);
- W_REG(sii->osh, &cc->gpioout, GPIO_OUT_7_EN_MASK);
-
- si_setcoreidx(sih, origidx);
+ sii->device_removed = status;
}
/** check if the device is removed */
@@ -3000,6 +3295,11 @@
si_deviceremoved(si_t *sih)
{
uint32 w;
+ si_info_t *sii = SI_INFO(sih);
+
+ if (sii->device_removed) {
+ return TRUE;
+ }
switch (BUSTYPE(sih->bustype)) {
case PCI_BUS:
@@ -3013,9 +3313,20 @@
}
bool
+si_is_warmboot(void)
+{
+
+#ifdef BCMULP
+ return (boot_type == WARM_BOOT);
+#else
+ return FALSE;
+#endif // endif
+}
+
+bool
si_is_sprom_available(si_t *sih)
{
- if (sih->ccrev >= 31) {
+ if (CCREV(sih->ccrev) >= 31) {
si_info_t *sii;
uint origidx;
chipcregs_t *cc;
@@ -3034,52 +3345,35 @@
}
switch (CHIPID(sih->chip)) {
- case BCM4312_CHIP_ID:
- return ((sih->chipst & CST4312_SPROM_OTP_SEL_MASK) != CST4312_OTP_SEL);
- case BCM4325_CHIP_ID:
- return (sih->chipst & CST4325_SPROM_SEL) != 0;
- case BCM4322_CHIP_ID: case BCM43221_CHIP_ID: case BCM43231_CHIP_ID:
- case BCM43222_CHIP_ID: case BCM43111_CHIP_ID: case BCM43112_CHIP_ID:
- case BCM4342_CHIP_ID: {
- uint32 spromotp;
- spromotp = (sih->chipst & CST4322_SPROM_OTP_SEL_MASK) >>
- CST4322_SPROM_OTP_SEL_SHIFT;
- return (spromotp & CST4322_SPROM_PRESENT) != 0;
- }
- case BCM4329_CHIP_ID:
- return (sih->chipst & CST4329_SPROM_SEL) != 0;
- case BCM4315_CHIP_ID:
- return (sih->chipst & CST4315_SPROM_SEL) != 0;
- case BCM4319_CHIP_ID:
- return (sih->chipst & CST4319_SPROM_SEL) != 0;
- case BCM4336_CHIP_ID:
- case BCM43362_CHIP_ID:
- return (sih->chipst & CST4336_SPROM_PRESENT) != 0;
- case BCM4330_CHIP_ID:
- return (sih->chipst & CST4330_SPROM_PRESENT) != 0;
- case BCM4313_CHIP_ID:
- return (sih->chipst & CST4313_SPROM_PRESENT) != 0;
- case BCM4331_CHIP_ID:
- case BCM43431_CHIP_ID:
- return (sih->chipst & CST4331_SPROM_PRESENT) != 0;
- case BCM43239_CHIP_ID:
- return ((sih->chipst & CST43239_SPROM_MASK) &&
- !(sih->chipst & CST43239_SFLASH_MASK));
- case BCM4324_CHIP_ID:
- case BCM43242_CHIP_ID:
- return ((sih->chipst & CST4324_SPROM_MASK) &&
- !(sih->chipst & CST4324_SFLASH_MASK));
+ case BCM43018_CHIP_ID:
+ case BCM43430_CHIP_ID:
+ return FALSE;
case BCM4335_CHIP_ID:
- case BCM4345_CHIP_ID:
- case BCM43454_CHIP_ID:
+ CASE_BCM4345_CHIP:
return ((sih->chipst & CST4335_SPROM_MASK) &&
!(sih->chipst & CST4335_SFLASH_MASK));
case BCM4349_CHIP_GRPID:
return (sih->chipst & CST4349_SPROM_PRESENT) != 0;
+ case BCM53573_CHIP_GRPID:
+ return FALSE; /* SPROM PRESENT is not defined for 53573 as of now */
+ case BCM4364_CHIP_ID:
+ return (sih->chipst & CST4364_SPROM_PRESENT) != 0;
+ case BCM4369_CHIP_GRPID:
+ if (CHIPREV(sih->chiprev) == 0) {
+ /* WAR for 4369a0: HW4369-1729. no sprom, default to otp always. */
+ return 0;
+ } else {
+ return (sih->chipst & CST4369_SPROM_PRESENT) != 0;
+ }
+#ifdef CHIPS_CUSTOMER_HW6
+ case BCM4368_CHIP_ID:
+ return FALSE;
+#endif /* CHIPS_CUSTOMER_HW6 */
+ case BCM4347_CHIP_GRPID:
+ return (sih->chipst & CST4347_SPROM_PRESENT) != 0;
break;
case BCM4350_CHIP_ID:
case BCM4354_CHIP_ID:
- case BCM4356_CHIP_ID:
case BCM43556_CHIP_ID:
case BCM43558_CHIP_ID:
case BCM43566_CHIP_ID:
@@ -3092,15 +3386,15 @@
return (sih->chipst & CST43602_SPROM_PRESENT) != 0;
case BCM43131_CHIP_ID:
case BCM43217_CHIP_ID:
- case BCM43227_CHIP_ID:
- case BCM43228_CHIP_ID:
case BCM43428_CHIP_ID:
return (sih->chipst & CST43228_OTP_PRESENT) != CST43228_OTP_PRESENT;
+ case BCM4373_CHIP_ID:
+ case BCM43012_CHIP_ID:
+ return FALSE;
default:
return TRUE;
}
}
-
uint32 si_get_sromctl(si_t *sih)
{
@@ -3156,7 +3450,6 @@
uint origidx, intr_val = 0;
uint ret_val;
si_info_t *sii = SI_INFO(sih);
- si_cores_info_t *cores_info = (si_cores_info_t *)sii->cores_info;
origidx = si_coreidx(sih);
@@ -3171,7 +3464,6 @@
return ret_val;
}
-
/* cleanup the timer from the host when ARM is been halted
* without a chance for ARM cleanup its resources
* If left not cleanup, Intr from a software timer can still
@@ -3183,8 +3475,7 @@
uint32 mask;
mask = PRRT_REQ_ACTIVE | PRRT_INTEN | PRRT_HT_REQ;
- if (CHIPID(sih->chip) != BCM4328_CHIP_ID)
- mask <<= 14;
+ mask <<= 14;
/* clear mask bits */
pmu_corereg(sih, SI_CC_IDX, res_req_timer, mask, 0);
/* readback to ensure write completes */
@@ -3197,67 +3488,17 @@
{
}
-
-#ifdef SURVIVE_PERST_ENAB
-static uint32
-si_pcie_survive_perst(si_t *sih, uint32 mask, uint32 val)
-{
- si_info_t *sii;
-
- sii = SI_INFO(sih);
-
- if (!PCIE(sii))
- return (0);
-
- return pcie_survive_perst(sii->pch, mask, val);
-}
-
-static void
-si_watchdog_reset(si_t *sih)
-{
- uint32 i;
-
- /* issue a watchdog reset */
- pmu_corereg(sih, SI_CC_IDX, pmuwatchdog, 2, 2);
- /* do busy wait for 20ms */
- for (i = 0; i < 2000; i++) {
- OSL_DELAY(10);
- }
-}
-#endif /* SURVIVE_PERST_ENAB */
-
+/* Caller of this function should make sure is on PCIE core
+ * Used in pciedev.c.
+ */
void
-si_survive_perst_war(si_t *sih, bool reset, uint32 sperst_mask, uint32 sperst_val)
+si_pcie_disable_oobselltr(si_t *sih)
{
-#ifdef SURVIVE_PERST_ENAB
- if (BUSTYPE(sih->bustype) != PCI_BUS)
- return;
-
- if ((CHIPID(sih->chip) != BCM4360_CHIP_ID && CHIPID(sih->chip) != BCM4352_CHIP_ID) ||
- (CHIPREV(sih->chiprev) >= 4))
- return;
-
- if (reset) {
- si_info_t *sii = SI_INFO(sih);
- uint32 bar0win, bar0win_after;
-
- /* save the bar0win */
- bar0win = OSL_PCI_READ_CONFIG(sii->osh, PCI_BAR0_WIN, sizeof(uint32));
-
- si_watchdog_reset(sih);
-
- bar0win_after = OSL_PCI_READ_CONFIG(sii->osh, PCI_BAR0_WIN, sizeof(uint32));
- if (bar0win_after != bar0win) {
- SI_ERROR(("%s: bar0win before %08x, bar0win after %08x\n",
- __FUNCTION__, bar0win, bar0win_after));
- OSL_PCI_WRITE_CONFIG(sii->osh, PCI_BAR0_WIN, sizeof(uint32), bar0win);
- }
- }
- if (sperst_mask) {
- /* enable survive perst */
- si_pcie_survive_perst(sih, sperst_mask, sperst_val);
- }
-#endif /* SURVIVE_PERST_ENAB */
+ ASSERT(si_coreid(sih) == PCIE2_CORE_ID);
+ if (PCIECOREREV(sih->buscorerev) >= 23)
+ si_wrapperreg(sih, AI_OOBSELIND74, ~0, 0);
+ else
+ si_wrapperreg(sih, AI_OOBSELIND30, ~0, 0);
}
void
@@ -3285,11 +3526,117 @@
{
}
+#if defined(AXI_TIMEOUTS) || defined(BCM_BACKPLANE_TIMEOUT)
+uint32
+si_clear_backplane_to_per_core(si_t *sih, uint coreid, uint coreunit, void * wrap)
+{
+ if ((CHIPTYPE(sih->socitype) == SOCI_AI) ||
+ (CHIPTYPE(sih->socitype) == SOCI_DVTBUS)) {
+ return ai_clear_backplane_to_per_core(sih, coreid, coreunit, wrap);
+ }
+ return AXI_WRAP_STS_NONE;
+}
+#endif /* AXI_TIMEOUTS || BCM_BACKPLANE_TIMEOUT */
+
+uint32
+si_clear_backplane_to(si_t *sih)
+{
+ if ((CHIPTYPE(sih->socitype) == SOCI_AI) ||
+ (CHIPTYPE(sih->socitype) == SOCI_DVTBUS)) {
+ return ai_clear_backplane_to(sih);
+ }
+
+ return 0;
+}
+
+void
+si_update_backplane_timeouts(si_t *sih, bool enable, uint32 timeout_exp, uint32 cid)
+{
+#if defined(AXI_TIMEOUTS) || defined(BCM_BACKPLANE_TIMEOUT)
+ /* Enable only for AXI */
+ if (CHIPTYPE(sih->socitype) != SOCI_AI) {
+ return;
+ }
+
+ ai_update_backplane_timeouts(sih, enable, timeout_exp, cid);
+#endif /* AXI_TIMEOUTS || BCM_BACKPLANE_TIMEOUT */
+}
+
+/*
+ * This routine adds the AXI timeouts for
+ * chipcommon, pcie and ARM slave wrappers
+ */
+void
+si_slave_wrapper_add(si_t *sih)
+{
+#if defined(AXI_TIMEOUTS) || defined(BCM_BACKPLANE_TIMEOUT)
+ uint32 axi_to = 0;
+
+ /* Enable only for AXI */
+ if ((CHIPTYPE(sih->socitype) != SOCI_AI) &&
+ (CHIPTYPE(sih->socitype) != SOCI_DVTBUS)) {
+ return;
+ }
+
+ if (CHIPID(sih->chip) == BCM4345_CHIP_ID && CHIPREV(sih->chiprev) >= 6) {
+ si_info_t *sii = SI_INFO(sih);
+
+ int wrapper_idx = (int)sii->axi_num_wrappers - 1;
+
+ ASSERT(wrapper_idx >= 0); /* axi_wrapper[] not initialised */
+ do {
+ if (sii->axi_wrapper[wrapper_idx].wrapper_type == AI_SLAVE_WRAPPER &&
+ sii->axi_wrapper[wrapper_idx].cid == 0xfff) {
+ sii->axi_wrapper[wrapper_idx].wrapper_addr = 0x1810b000;
+ break;
+ }
+ } while (wrapper_idx-- > 0);
+ ASSERT(wrapper_idx >= 0); /* all addresses valid for the chiprev under test */
+ }
+
+ if (BCM4347_CHIP(sih->chip)) {
+ axi_to = AXI_TO_VAL_4347;
+ }
+ else {
+ axi_to = AXI_TO_VAL;
+ }
+
+ /* All required slave wrappers are added in ai_scan */
+ ai_update_backplane_timeouts(sih, TRUE, axi_to, 0);
+
+#ifdef DISABLE_PCIE2_AXI_TIMEOUT
+ ai_update_backplane_timeouts(sih, FALSE, 0, PCIE_CORE_ID);
+ ai_update_backplane_timeouts(sih, FALSE, 0, PCIE2_CORE_ID);
+#endif // endif
+
+#endif /* AXI_TIMEOUTS || BCM_BACKPLANE_TIMEOUT */
+
+}
void
si_pll_sr_reinit(si_t *sih)
{
+}
+
+/* Programming d11 core oob settings for 4364
+ * WARs for HW4364-237 and HW4364-166
+*/
+void
+si_config_4364_d11_oob(si_t *sih, uint coreid)
+{
+ uint save_idx;
+
+ save_idx = si_coreidx(sih);
+ si_setcore(sih, coreid, 0);
+ si_wrapperreg(sih, AI_OOBSELINC30, ~0, 0x81828180);
+ si_wrapperreg(sih, AI_OOBSELINC74, ~0, 0x87868183);
+ si_wrapperreg(sih, AI_OOBSELOUTB74, ~0, 0x84858484);
+ si_setcore(sih, coreid, 1);
+ si_wrapperreg(sih, AI_OOBSELINC30, ~0, 0x81828180);
+ si_wrapperreg(sih, AI_OOBSELINC74, ~0, 0x87868184);
+ si_wrapperreg(sih, AI_OOBSELOUTB74, ~0, 0x84868484);
+ si_setcoreidx(sih, save_idx);
}
void
@@ -3301,6 +3648,7 @@
/* disable PLL open loop operation */
switch (CHIPID(sih->chip)) {
#ifdef SAVERESTORE
+ case BCM43018_CHIP_ID:
case BCM43430_CHIP_ID:
if (SR_ENAB() && sr_isenab(sih)) {
/* read back the pll openloop state */
@@ -3314,9 +3662,268 @@
}
break;
#endif /* SAVERESTORE */
+ case BCM4347_CHIP_GRPID:
+ case BCM4369_CHIP_GRPID:
+ si_pmu_chipcontrol(sih, PMU_CHIPCTL1,
+ PMU_CC1_ENABLE_CLOSED_LOOP_MASK, PMU_CC1_ENABLE_CLOSED_LOOP);
+ break;
default:
/* any unsupported chip bail */
return;
}
-#endif
+#endif // endif
+}
+
+#if defined(BCMSRPWR) && !defined(BCMSRPWR_DISABLED)
+bool _bcmsrpwr = TRUE;
+#else
+bool _bcmsrpwr = FALSE;
+#endif // endif
+
+#define PWRREQ_OFFSET(sih) OFFSETOF(chipcregs_t, powerctl)
+
+static void
+si_corereg_pciefast_write(si_t *sih, uint regoff, uint val)
+{
+ volatile uint32 *r = NULL;
+ si_info_t *sii = SI_INFO(sih);
+
+ ASSERT((BUSTYPE(sih->bustype) == PCI_BUS));
+
+ r = (volatile uint32 *)((volatile char *)sii->curmap +
+ PCI_16KB0_PCIREGS_OFFSET + regoff);
+
+ W_REG(sii->osh, r, val);
+}
+
+static uint
+si_corereg_pciefast_read(si_t *sih, uint regoff)
+{
+ volatile uint32 *r = NULL;
+ si_info_t *sii = SI_INFO(sih);
+
+ ASSERT((BUSTYPE(sih->bustype) == PCI_BUS));
+
+ r = (volatile uint32 *)((volatile char *)sii->curmap +
+ PCI_16KB0_PCIREGS_OFFSET + regoff);
+
+ return R_REG(sii->osh, r);
+}
+
+uint32
+si_srpwr_request(si_t *sih, uint32 mask, uint32 val)
+{
+ uint32 r, offset = (BUSTYPE(sih->bustype) == SI_BUS) ?
+ OFFSETOF(chipcregs_t, powerctl) : PWRREQ_OFFSET(sih);
+ uint32 mask2 = mask;
+ uint32 val2 = val;
+ volatile uint32 *fast_srpwr_addr = (volatile uint32 *)((uintptr)SI_ENUM_BASE(sih)
+ + (uintptr)offset);
+
+ if (mask || val) {
+ mask <<= SRPWR_REQON_SHIFT;
+ val <<= SRPWR_REQON_SHIFT;
+
+ /* Return if requested power request is already set */
+ if (BUSTYPE(sih->bustype) == SI_BUS) {
+ r = R_REG(OSH_NULL, fast_srpwr_addr);
+ } else {
+ r = si_corereg_pciefast_read(sih, offset);
+ }
+
+ if ((r & mask) == val) {
+ return r;
+ }
+
+ r = (r & ~mask) | val;
+
+ if (BUSTYPE(sih->bustype) == SI_BUS) {
+ W_REG(OSH_NULL, fast_srpwr_addr, r);
+ r = R_REG(OSH_NULL, fast_srpwr_addr);
+ } else {
+ si_corereg_pciefast_write(sih, offset, r);
+ r = si_corereg_pciefast_read(sih, offset);
+ }
+
+ if (val2) {
+ if ((r & (mask2 << SRPWR_STATUS_SHIFT)) ==
+ (val2 << SRPWR_STATUS_SHIFT)) {
+ return r;
+ }
+ si_srpwr_stat_spinwait(sih, mask2, val2);
+ }
+ } else {
+ if (BUSTYPE(sih->bustype) == SI_BUS) {
+ r = R_REG(OSH_NULL, fast_srpwr_addr);
+ } else {
+ r = si_corereg_pciefast_read(sih, offset);
+ }
+ }
+
+ return r;
+}
+
+uint32
+si_srpwr_stat_spinwait(si_t *sih, uint32 mask, uint32 val)
+{
+ uint32 r, offset = (BUSTYPE(sih->bustype) == SI_BUS) ?
+ OFFSETOF(chipcregs_t, powerctl) : PWRREQ_OFFSET(sih);
+ volatile uint32 *fast_srpwr_addr = (volatile uint32 *)((uintptr)SI_ENUM_BASE(sih)
+ + (uintptr)offset);
+
+ ASSERT(mask);
+ ASSERT(val);
+
+ /* spinwait on pwrstatus */
+ mask <<= SRPWR_STATUS_SHIFT;
+ val <<= SRPWR_STATUS_SHIFT;
+
+ if (BUSTYPE(sih->bustype) == SI_BUS) {
+ SPINWAIT(((R_REG(OSH_NULL, fast_srpwr_addr) & mask) != val),
+ PMU_MAX_TRANSITION_DLY);
+ r = R_REG(OSH_NULL, fast_srpwr_addr) & mask;
+ ASSERT(r == val);
+ } else {
+ SPINWAIT(((si_corereg_pciefast_read(sih, offset) & mask) != val),
+ PMU_MAX_TRANSITION_DLY);
+ r = si_corereg_pciefast_read(sih, offset) & mask;
+ ASSERT(r == val);
+ }
+
+ r = (r >> SRPWR_STATUS_SHIFT) & SRPWR_DMN_ALL_MASK(sih);
+
+ return r;
+}
+
+uint32
+si_srpwr_stat(si_t *sih)
+{
+ uint32 r, offset = (BUSTYPE(sih->bustype) == SI_BUS) ?
+ OFFSETOF(chipcregs_t, powerctl) : PWRREQ_OFFSET(sih);
+ uint cidx = (BUSTYPE(sih->bustype) == SI_BUS) ? SI_CC_IDX : sih->buscoreidx;
+
+ if (BUSTYPE(sih->bustype) == SI_BUS) {
+ r = si_corereg(sih, cidx, offset, 0, 0);
+ } else {
+ r = si_corereg_pciefast_read(sih, offset);
+ }
+
+ r = (r >> SRPWR_STATUS_SHIFT) & SRPWR_DMN_ALL_MASK(sih);
+
+ return r;
+}
+
+uint32
+si_srpwr_domain(si_t *sih)
+{
+ uint32 r, offset = (BUSTYPE(sih->bustype) == SI_BUS) ?
+ OFFSETOF(chipcregs_t, powerctl) : PWRREQ_OFFSET(sih);
+ uint cidx = (BUSTYPE(sih->bustype) == SI_BUS) ? SI_CC_IDX : sih->buscoreidx;
+
+ if (BUSTYPE(sih->bustype) == SI_BUS) {
+ r = si_corereg(sih, cidx, offset, 0, 0);
+ } else {
+ r = si_corereg_pciefast_read(sih, offset);
+ }
+
+ r = (r >> SRPWR_DMN_ID_SHIFT) & SRPWR_DMN_ID_MASK;
+
+ return r;
+}
+
+uint32
+si_srpwr_domain_all_mask(si_t *sih)
+{
+ uint32 mask = SRPWR_DMN0_PCIE_MASK |
+ SRPWR_DMN1_ARMBPSD_MASK |
+ SRPWR_DMN2_MACAUX_MASK |
+ SRPWR_DMN3_MACMAIN_MASK;
+
+ if (si_scan_core_present(sih)) {
+ mask |= SRPWR_DMN4_MACSCAN_MASK;
+ }
+
+ return mask;
+}
+
+/* Utility API to read/write the raw registers with absolute address.
+ * This function can be invoked from either FW or host driver.
+ */
+uint32
+si_raw_reg(si_t *sih, uint32 reg, uint32 val, uint32 wrire_req)
+{
+ si_info_t *sii = SI_INFO(sih);
+ uint32 address_space = reg & ~0xFFF;
+ volatile uint32 * addr = (void*)(uintptr)(reg);
+ uint32 prev_value = 0;
+ uint32 cfg_reg = 0;
+
+ if (sii == NULL) {
+ return 0;
+ }
+
+ /* No need to translate the absolute address on SI bus */
+ if (BUSTYPE(sih->bustype) == SI_BUS) {
+ goto skip_cfg;
+ }
+
+ /* This API supports only the PCI host interface */
+ if (BUSTYPE(sih->bustype) != PCI_BUS) {
+ return ID32_INVALID;
+ }
+
+ if (PCIE_GEN2(sii)) {
+ /* Use BAR0 Secondary window is PCIe Gen2.
+ * Set the secondary BAR0 Window to current register of interest
+ */
+ addr = (volatile uint32*)(((volatile uint8*)sii->curmap) +
+ PCI_SEC_BAR0_WIN_OFFSET + (reg & 0xfff));
+ cfg_reg = PCIE2_BAR0_CORE2_WIN;
+
+ } else {
+ /* PCIe Gen1 do not have secondary BAR0 window.
+ * reuse the BAR0 WIN2
+ */
+ addr = (volatile uint32*)(((volatile uint8*)sii->curmap) +
+ PCI_BAR0_WIN2_OFFSET + (reg & 0xfff));
+ cfg_reg = PCI_BAR0_WIN2;
+ }
+
+ prev_value = OSL_PCI_READ_CONFIG(sii->osh, cfg_reg, 4);
+
+ if (prev_value != address_space) {
+ OSL_PCI_WRITE_CONFIG(sii->osh, cfg_reg,
+ sizeof(uint32), address_space);
+ } else {
+ prev_value = 0;
+ }
+
+skip_cfg:
+ if (wrire_req) {
+ W_REG(sii->osh, addr, val);
+ } else {
+ val = R_REG(sii->osh, addr);
+ }
+
+ if (prev_value) {
+ /* Restore BAR0 WIN2 for PCIE GEN1 devices */
+ OSL_PCI_WRITE_CONFIG(sii->osh,
+ cfg_reg, sizeof(uint32), prev_value);
+ }
+
+ return val;
+}
+
+uint8
+si_lhl_ps_mode(si_t *sih)
+{
+ si_info_t *sii = SI_INFO(sih);
+ return sii->lhl_ps_mode;
+}
+
+bool
+BCMRAMFN(si_scan_core_present)(si_t *sih)
+{
+ return ((si_numcoreunits(sih, D11_CORE_ID) >= 2) &&
+ (si_numcoreunits(sih, SR_CORE_ID) > 4));
}
--
Gitblit v1.6.2