The two source files have been separated where aiutils is only used by the brcmsmac driver and the siutils is only used by the brcmfmac driver. Reviewed-by: Roland Vossen <rvossen@xxxxxxxxxxxx> Reviewed-by: Henry Ptasinski <henryp@xxxxxxxxxxxx> Signed-off-by: Arend van Spriel <arend@xxxxxxxxxxxx> --- drivers/staging/brcm80211/brcmfmac/Makefile | 1 - drivers/staging/brcm80211/brcmsmac/Makefile | 1 - drivers/staging/brcm80211/brcmsmac/d11.h | 2 + .../staging/brcm80211/brcmsmac/phy/wlc_phy_hal.h | 2 +- .../staging/brcm80211/brcmsmac/phy/wlc_phy_lcn.c | 4 +- drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_n.c | 2 +- drivers/staging/brcm80211/brcmsmac/wlc_alloc.c | 2 +- drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c | 2 +- drivers/staging/brcm80211/brcmsmac/wlc_antsel.c | 2 +- drivers/staging/brcm80211/brcmsmac/wlc_bmac.c | 4 +- drivers/staging/brcm80211/brcmsmac/wlc_channel.c | 2 +- drivers/staging/brcm80211/brcmsmac/wlc_main.c | 2 +- drivers/staging/brcm80211/brcmsmac/wlc_phy_shim.c | 2 +- drivers/staging/brcm80211/brcmsmac/wlc_pmu.c | 22 +- drivers/staging/brcm80211/brcmsmac/wlc_pmu.h | 2 +- drivers/staging/brcm80211/brcmsmac/wlc_rate.c | 2 +- drivers/staging/brcm80211/brcmsmac/wlc_stf.c | 2 +- drivers/staging/brcm80211/include/aiutils.h | 565 +++++++ drivers/staging/brcm80211/include/siutils.h | 25 - drivers/staging/brcm80211/util/aiutils.c | 1582 +++++++++++++++++++- drivers/staging/brcm80211/util/bcmotp.c | 18 +- drivers/staging/brcm80211/util/siutils.c | 435 +------ 22 files changed, 2195 insertions(+), 486 deletions(-) create mode 100644 drivers/staging/brcm80211/include/aiutils.h diff --git a/drivers/staging/brcm80211/brcmfmac/Makefile b/drivers/staging/brcm80211/brcmfmac/Makefile index ac5a7d4..f8c0bdd 100644 --- a/drivers/staging/brcm80211/brcmfmac/Makefile +++ b/drivers/staging/brcm80211/brcmfmac/Makefile @@ -52,7 +52,6 @@ DHDOFILES = \ bcmsdh_linux.o \ bcmsdh_sdmmc.o \ bcmsdh_sdmmc_linux.o \ - aiutils.o \ siutils.o \ sbutils.o \ bcmutils.o \ diff --git a/drivers/staging/brcm80211/brcmsmac/Makefile b/drivers/staging/brcm80211/brcmsmac/Makefile index 65a1a25..3d9e04b 100644 --- a/drivers/staging/brcm80211/brcmsmac/Makefile +++ b/drivers/staging/brcm80211/brcmsmac/Makefile @@ -47,7 +47,6 @@ BRCMSMAC_OFILES := \ phy/wlc_phytbl_lcn.o \ phy/wlc_phytbl_n.o \ ../util/aiutils.o \ - ../util/siutils.o \ ../util/bcmutils.o \ ../util/bcmwifi.o \ ../util/bcmotp.o \ diff --git a/drivers/staging/brcm80211/brcmsmac/d11.h b/drivers/staging/brcm80211/brcmsmac/d11.h index a9d182f..d91e418 100644 --- a/drivers/staging/brcm80211/brcmsmac/d11.h +++ b/drivers/staging/brcm80211/brcmsmac/d11.h @@ -17,6 +17,8 @@ #ifndef _D11_H #define _D11_H +#include <sbconfig.h> + #ifndef WL_RSSI_ANT_MAX #define WL_RSSI_ANT_MAX 4 /* max possible rx antennas */ #elif WL_RSSI_ANT_MAX != 4 diff --git a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_hal.h b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_hal.h index 6faf7a5..d839ca9 100644 --- a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_hal.h +++ b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_hal.h @@ -18,7 +18,7 @@ #define _wlc_phy_h_ #include <wlioctl.h> -#include <siutils.h> +#include <aiutils.h> #include <d11.h> #include <wlc_phy_shim.h> diff --git a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_lcn.c b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_lcn.c index e2d468e..7b78e63 100644 --- a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_lcn.c +++ b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_lcn.c @@ -21,8 +21,8 @@ #include <wlc_cfg.h> #include <qmath.h> #include <linux/pci.h> -#include <siutils.h> -#include <hndpmu.h> +#include <aiutils.h> +#include <wlc_pmu.h> #include <bcmdevs.h> #include <sbhnddma.h> diff --git a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_n.c b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_n.c index f703a68..9e6100b 100644 --- a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_n.c +++ b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_n.c @@ -20,7 +20,7 @@ #include <wlc_cfg.h> #include <linux/delay.h> #include <linux/pci.h> -#include <siutils.h> +#include <aiutils.h> #include <sbchipc.h> #include <hndpmu.h> diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_alloc.c b/drivers/staging/brcm80211/brcmsmac/wlc_alloc.c index 1f591bc..d02364b 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_alloc.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_alloc.c @@ -18,7 +18,7 @@ #include <bcmdefs.h> #include <bcmutils.h> -#include <siutils.h> +#include <aiutils.h> #include <wlioctl.h> #include <sbhnddma.h> diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c b/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c index b9db568..c9d4e89 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c @@ -18,7 +18,7 @@ #include <bcmdefs.h> #include <bcmutils.h> -#include <siutils.h> +#include <aiutils.h> #include <wlioctl.h> #include <sbhnddma.h> #include <hnddma.h> diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_antsel.c b/drivers/staging/brcm80211/brcmsmac/wlc_antsel.c index 9e44991..4516377 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_antsel.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_antsel.c @@ -22,7 +22,7 @@ #include <bcmdefs.h> #include <bcmutils.h> -#include <siutils.h> +#include <aiutils.h> #include <bcmdevs.h> #include <sbhnddma.h> #include <wlioctl.h> diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c b/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c index c135f28..f538def 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c @@ -25,7 +25,7 @@ #include <bcmdefs.h> #include <bcmdevs.h> #include <bcmwifi.h> -#include <siutils.h> +#include <aiutils.h> #include <bcmsrom.h> #include <bcmotp.h> #include <bcmutils.h> @@ -845,7 +845,7 @@ int wlc_bmac_attach(struct wlc_info *wlc, u16 vendor, u16 device, uint unit, wlc_hw->band->bandtype = j ? WLC_BAND_5G : WLC_BAND_2G; wlc->band->bandunit = j; wlc->band->bandtype = j ? WLC_BAND_5G : WLC_BAND_2G; - wlc->core->coreidx = si_coreidx(wlc_hw->sih); + wlc->core->coreidx = ai_coreidx(wlc_hw->sih); wlc_hw->machwcap = R_REG(®s->machwcap); wlc_hw->machwcap_backup = wlc_hw->machwcap; diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_channel.c b/drivers/staging/brcm80211/brcmsmac/wlc_channel.c index ca8fd0e..e170b88 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_channel.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_channel.c @@ -21,7 +21,7 @@ #include <bcmdefs.h> #include <bcmutils.h> -#include <siutils.h> +#include <aiutils.h> #include <sbhnddma.h> #include <wlioctl.h> diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_main.c b/drivers/staging/brcm80211/brcmsmac/wlc_main.c index 1500361..66d1d99 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_main.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_main.c @@ -23,7 +23,7 @@ #include <bcmdevs.h> #include <bcmutils.h> #include <bcmwifi.h> -#include <siutils.h> +#include <aiutils.h> #include <pcicfg.h> #include <bcmsrom.h> #include <wlioctl.h> diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_phy_shim.c b/drivers/staging/brcm80211/brcmsmac/wlc_phy_shim.c index 63f42c8..6f4b6a7 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_phy_shim.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_phy_shim.c @@ -29,7 +29,7 @@ #include <bcmdefs.h> #include <bcmutils.h> #include <bcmwifi.h> -#include <siutils.h> +#include <aiutils.h> #include <wlioctl.h> #include <sbconfig.h> #include <sbchipc.h> diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_pmu.c b/drivers/staging/brcm80211/brcmsmac/wlc_pmu.c index e26df70..f5b1779 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_pmu.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_pmu.c @@ -1220,7 +1220,7 @@ u32 si_pmu_ilp_clock(si_t *sih) if (ilpcycles_per_sec == 0) { u32 start, end, delta; - u32 origidx = si_coreidx(sih); + u32 origidx = ai_coreidx(sih); chipcregs_t *cc = si_setcoreidx(sih, SI_CC_IDX); ASSERT(cc != NULL); start = R_REG(&cc->pmutimer); @@ -1302,7 +1302,7 @@ u16 si_pmu_fast_pwrup_delay(si_t *sih) ASSERT(sih->cccaps & CC_CAP_PMU); /* Remember original core before switch to chipc */ - origidx = si_coreidx(sih); + origidx = ai_coreidx(sih); cc = si_setcoreidx(sih, SI_CC_IDX); ASSERT(cc != NULL); @@ -1372,7 +1372,7 @@ void si_pmu_sprom_enable(si_t *sih, bool enable) uint origidx; /* Remember original core before switch to chipc */ - origidx = si_coreidx(sih); + origidx = ai_coreidx(sih); cc = si_setcoreidx(sih, SI_CC_IDX); ASSERT(cc != NULL); @@ -1428,7 +1428,7 @@ u32 si_pmu_alp_clock(si_t *sih) ASSERT(sih->cccaps & CC_CAP_PMU); /* Remember original core before switch to chipc */ - origidx = si_coreidx(sih); + origidx = ai_coreidx(sih); cc = si_setcoreidx(sih, SI_CC_IDX); ASSERT(cc != NULL); @@ -1514,7 +1514,7 @@ void si_pmu_init(si_t *sih) ASSERT(sih->cccaps & CC_CAP_PMU); /* Remember original core before switch to chipc */ - origidx = si_coreidx(sih); + origidx = ai_coreidx(sih); cc = si_setcoreidx(sih, SI_CC_IDX); ASSERT(cc != NULL); @@ -1547,7 +1547,7 @@ void si_pmu_chip_init(si_t *sih) si_pmu_sprom_enable(sih, false); /* Remember original core */ - origidx = si_coreidx(sih); + origidx = ai_coreidx(sih); /* Return to original core */ si_setcoreidx(sih, origidx); @@ -1589,7 +1589,7 @@ void si_pmu_pll_init(si_t *sih, uint xtalfreq) ASSERT(sih->cccaps & CC_CAP_PMU); /* Remember original core before switch to chipc */ - origidx = si_coreidx(sih); + origidx = ai_coreidx(sih); cc = si_setcoreidx(sih, SI_CC_IDX); ASSERT(cc != NULL); @@ -1639,7 +1639,7 @@ void si_pmu_res_init(si_t *sih) ASSERT(sih->cccaps & CC_CAP_PMU); /* Remember original core before switch to chipc */ - origidx = si_coreidx(sih); + origidx = ai_coreidx(sih); cc = si_setcoreidx(sih, SI_CC_IDX); ASSERT(cc != NULL); @@ -1814,7 +1814,7 @@ u32 si_pmu_measure_alpclk(si_t *sih) ASSERT(sih->cccaps & CC_CAP_PMU); /* Remember original core before switch to chipc */ - origidx = si_coreidx(sih); + origidx = ai_coreidx(sih); cc = si_setcoreidx(sih, SI_CC_IDX); ASSERT(cc != NULL); @@ -1856,7 +1856,7 @@ bool si_pmu_is_otp_powered(si_t *sih) bool st; /* Remember original core before switch to chipc */ - idx = si_coreidx(sih); + idx = ai_coreidx(sih); cc = si_setcoreidx(sih, SI_CC_IDX); ASSERT(cc != NULL); @@ -1914,7 +1914,7 @@ void si_pmu_otp_power(si_t *sih, bool on) } /* Remember original core before switch to chipc */ - origidx = si_coreidx(sih); + origidx = ai_coreidx(sih); cc = si_setcoreidx(sih, SI_CC_IDX); ASSERT(cc != NULL); diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_pmu.h b/drivers/staging/brcm80211/brcmsmac/wlc_pmu.h index 9fa48e4..516a618 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_pmu.h +++ b/drivers/staging/brcm80211/brcmsmac/wlc_pmu.h @@ -20,7 +20,7 @@ #include <linux/types.h> -#include <siutils.h> +#include <aiutils.h> /* * LDO selections used in si_pmu_set_ldo_voltage diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_rate.c b/drivers/staging/brcm80211/brcmsmac/wlc_rate.c index d284f1a..9741f9a 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_rate.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_rate.c @@ -19,7 +19,7 @@ #include <proto/802.11.h> #include <bcmdefs.h> #include <bcmutils.h> -#include <siutils.h> +#include <aiutils.h> #include <wlioctl.h> #include <sbhnddma.h> diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_stf.c b/drivers/staging/brcm80211/brcmsmac/wlc_stf.c index 78c74c9..fdd9524 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_stf.c +++ b/drivers/staging/brcm80211/brcmsmac/wlc_stf.c @@ -21,7 +21,7 @@ #include <bcmdefs.h> #include <bcmutils.h> -#include <siutils.h> +#include <aiutils.h> #include <wlioctl.h> #include <bcmwifi.h> #include <sbhnddma.h> diff --git a/drivers/staging/brcm80211/include/aiutils.h b/drivers/staging/brcm80211/include/aiutils.h new file mode 100644 index 0000000..3b7235c --- /dev/null +++ b/drivers/staging/brcm80211/include/aiutils.h @@ -0,0 +1,565 @@ +/* + * Copyright (c) 2011 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _aiutils_h_ +#define _aiutils_h_ + +/* cpp contortions to concatenate w/arg prescan */ +#ifndef PAD +#define _PADLINE(line) pad ## line +#define _XSTR(line) _PADLINE(line) +#define PAD _XSTR(__LINE__) +#endif + +/* Include the soci specific files */ +#include <aidmp.h> + +/* + * SOC Interconnect Address Map. + * All regions may not exist on all chips. + */ +/* Physical SDRAM */ +#define SI_SDRAM_BASE 0x00000000 +/* Host Mode sb2pcitranslation0 (64 MB) */ +#define SI_PCI_MEM 0x08000000 +#define SI_PCI_MEM_SZ (64 * 1024 * 1024) +/* Host Mode sb2pcitranslation1 (64 MB) */ +#define SI_PCI_CFG 0x0c000000 +/* Byteswapped Physical SDRAM */ +#define SI_SDRAM_SWAPPED 0x10000000 +/* Region 2 for sdram (512 MB) */ +#define SI_SDRAM_R2 0x80000000 + +#ifdef SI_ENUM_BASE_VARIABLE +#define SI_ENUM_BASE (sii->pub.si_enum_base) +#else +#define SI_ENUM_BASE 0x18000000 /* Enumeration space base */ +#endif /* SI_ENUM_BASE_VARIABLE */ + +/* Wrapper space base */ +#define SI_WRAP_BASE 0x18100000 +/* each core gets 4Kbytes for registers */ +#define SI_CORE_SIZE 0x1000 +/* + * Max cores (this is arbitrary, for software + * convenience and could be changed if we + * make any larger chips + */ +#define SI_MAXCORES 16 + +/* On-chip RAM on chips that also have DDR */ +#define SI_FASTRAM 0x19000000 +#define SI_FASTRAM_SWAPPED 0x19800000 + +/* Flash Region 2 (region 1 shadowed here) */ +#define SI_FLASH2 0x1c000000 +/* Size of Flash Region 2 */ +#define SI_FLASH2_SZ 0x02000000 +/* ARM Cortex-M3 ROM */ +#define SI_ARMCM3_ROM 0x1e000000 +/* MIPS Flash Region 1 */ +#define SI_FLASH1 0x1fc00000 +/* MIPS Size of Flash Region 1 */ +#define SI_FLASH1_SZ 0x00400000 +/* ARM7TDMI-S ROM */ +#define SI_ARM7S_ROM 0x20000000 +/* ARM Cortex-M3 SRAM Region 2 */ +#define SI_ARMCM3_SRAM2 0x60000000 +/* ARM7TDMI-S SRAM Region 2 */ +#define SI_ARM7S_SRAM2 0x80000000 +/* ARM Flash Region 1 */ +#define SI_ARM_FLASH1 0xffff0000 +/* ARM Size of Flash Region 1 */ +#define SI_ARM_FLASH1_SZ 0x00010000 + +/* Client Mode sb2pcitranslation2 (1 GB) */ +#define SI_PCI_DMA 0x40000000 +/* Client Mode sb2pcitranslation2 (1 GB) */ +#define SI_PCI_DMA2 0x80000000 +/* Client Mode sb2pcitranslation2 size in bytes */ +#define SI_PCI_DMA_SZ 0x40000000 +/* PCIE Client Mode sb2pcitranslation2 (2 ZettaBytes), low 32 bits */ +#define SI_PCIE_DMA_L32 0x00000000 +/* PCIE Client Mode sb2pcitranslation2 (2 ZettaBytes), high 32 bits */ +#define SI_PCIE_DMA_H32 0x80000000 + +/* core codes */ +#define NODEV_CORE_ID 0x700 /* Invalid coreid */ +#define CC_CORE_ID 0x800 /* chipcommon core */ +#define ILINE20_CORE_ID 0x801 /* iline20 core */ +#define SRAM_CORE_ID 0x802 /* sram core */ +#define SDRAM_CORE_ID 0x803 /* sdram core */ +#define PCI_CORE_ID 0x804 /* pci core */ +#define MIPS_CORE_ID 0x805 /* mips core */ +#define ENET_CORE_ID 0x806 /* enet mac core */ +#define CODEC_CORE_ID 0x807 /* v90 codec core */ +#define USB_CORE_ID 0x808 /* usb 1.1 host/device core */ +#define ADSL_CORE_ID 0x809 /* ADSL core */ +#define ILINE100_CORE_ID 0x80a /* iline100 core */ +#define IPSEC_CORE_ID 0x80b /* ipsec core */ +#define UTOPIA_CORE_ID 0x80c /* utopia core */ +#define PCMCIA_CORE_ID 0x80d /* pcmcia core */ +#define SOCRAM_CORE_ID 0x80e /* internal memory core */ +#define MEMC_CORE_ID 0x80f /* memc sdram core */ +#define OFDM_CORE_ID 0x810 /* OFDM phy core */ +#define EXTIF_CORE_ID 0x811 /* external interface core */ +#define D11_CORE_ID 0x812 /* 802.11 MAC core */ +#define APHY_CORE_ID 0x813 /* 802.11a phy core */ +#define BPHY_CORE_ID 0x814 /* 802.11b phy core */ +#define GPHY_CORE_ID 0x815 /* 802.11g phy core */ +#define MIPS33_CORE_ID 0x816 /* mips3302 core */ +#define USB11H_CORE_ID 0x817 /* usb 1.1 host core */ +#define USB11D_CORE_ID 0x818 /* usb 1.1 device core */ +#define USB20H_CORE_ID 0x819 /* usb 2.0 host core */ +#define USB20D_CORE_ID 0x81a /* usb 2.0 device core */ +#define SDIOH_CORE_ID 0x81b /* sdio host core */ +#define ROBO_CORE_ID 0x81c /* roboswitch core */ +#define ATA100_CORE_ID 0x81d /* parallel ATA core */ +#define SATAXOR_CORE_ID 0x81e /* serial ATA & XOR DMA core */ +#define GIGETH_CORE_ID 0x81f /* gigabit ethernet core */ +#define PCIE_CORE_ID 0x820 /* pci express core */ +#define NPHY_CORE_ID 0x821 /* 802.11n 2x2 phy core */ +#define SRAMC_CORE_ID 0x822 /* SRAM controller core */ +#define MINIMAC_CORE_ID 0x823 /* MINI MAC/phy core */ +#define ARM11_CORE_ID 0x824 /* ARM 1176 core */ +#define ARM7S_CORE_ID 0x825 /* ARM7tdmi-s core */ +#define LPPHY_CORE_ID 0x826 /* 802.11a/b/g phy core */ +#define PMU_CORE_ID 0x827 /* PMU core */ +#define SSNPHY_CORE_ID 0x828 /* 802.11n single-stream phy core */ +#define SDIOD_CORE_ID 0x829 /* SDIO device core */ +#define ARMCM3_CORE_ID 0x82a /* ARM Cortex M3 core */ +#define HTPHY_CORE_ID 0x82b /* 802.11n 4x4 phy core */ +#define MIPS74K_CORE_ID 0x82c /* mips 74k core */ +#define GMAC_CORE_ID 0x82d /* Gigabit MAC core */ +#define DMEMC_CORE_ID 0x82e /* DDR1/2 memory controller core */ +#define PCIERC_CORE_ID 0x82f /* PCIE Root Complex core */ +#define OCP_CORE_ID 0x830 /* OCP2OCP bridge core */ +#define SC_CORE_ID 0x831 /* shared common core */ +#define AHB_CORE_ID 0x832 /* OCP2AHB bridge core */ +#define SPIH_CORE_ID 0x833 /* SPI host core */ +#define I2S_CORE_ID 0x834 /* I2S core */ +#define DMEMS_CORE_ID 0x835 /* SDR/DDR1 memory controller core */ +#define DEF_SHIM_COMP 0x837 /* SHIM component in ubus/6362 */ +#define OOB_ROUTER_CORE_ID 0x367 /* OOB router core ID */ +#define DEF_AI_COMP 0xfff /* Default component, in ai chips it + * maps all unused address ranges + */ + +/* There are TWO constants on all HND chips: SI_ENUM_BASE above, + * and chipcommon being the first core: + */ +#define SI_CC_IDX 0 + +/* SOC Interconnect types (aka chip types) */ +#define SOCI_AI 1 + +/* Common core control flags */ +#define SICF_BIST_EN 0x8000 +#define SICF_PME_EN 0x4000 +#define SICF_CORE_BITS 0x3ffc +#define SICF_FGC 0x0002 +#define SICF_CLOCK_EN 0x0001 + +/* Common core status flags */ +#define SISF_BIST_DONE 0x8000 +#define SISF_BIST_ERROR 0x4000 +#define SISF_GATED_CLK 0x2000 +#define SISF_DMA64 0x1000 +#define SISF_CORE_BITS 0x0fff + +/* A register that is common to all cores to + * communicate w/PMU regarding clock control. + */ +#define SI_CLK_CTL_ST 0x1e0 /* clock control and status */ + +/* clk_ctl_st register */ +#define CCS_FORCEALP 0x00000001 /* force ALP request */ +#define CCS_FORCEHT 0x00000002 /* force HT request */ +#define CCS_FORCEILP 0x00000004 /* force ILP request */ +#define CCS_ALPAREQ 0x00000008 /* ALP Avail Request */ +#define CCS_HTAREQ 0x00000010 /* HT Avail Request */ +#define CCS_FORCEHWREQOFF 0x00000020 /* Force HW Clock Request Off */ +#define CCS_ERSRC_REQ_MASK 0x00000700 /* external resource requests */ +#define CCS_ERSRC_REQ_SHIFT 8 +#define CCS_ALPAVAIL 0x00010000 /* ALP is available */ +#define CCS_HTAVAIL 0x00020000 /* HT is available */ +#define CCS_BP_ON_APL 0x00040000 /* RO: running on ALP clock */ +#define CCS_BP_ON_HT 0x00080000 /* RO: running on HT clock */ +#define CCS_ERSRC_STS_MASK 0x07000000 /* external resource status */ +#define CCS_ERSRC_STS_SHIFT 24 + +/* HT avail in chipc and pcmcia on 4328a0 */ +#define CCS0_HTAVAIL 0x00010000 +/* ALP avail in chipc and pcmcia on 4328a0 */ +#define CCS0_ALPAVAIL 0x00020000 + +/* Not really related to SOC Interconnect, but a couple of software + * conventions for the use the flash space: + */ + +/* Minumum amount of flash we support */ +#define FLASH_MIN 0x00020000 /* Minimum flash size */ + +/* A boot/binary may have an embedded block that describes its size */ +#define BISZ_OFFSET 0x3e0 /* At this offset into the binary */ +#define BISZ_MAGIC 0x4249535a /* Marked with value: 'BISZ' */ +#define BISZ_MAGIC_IDX 0 /* Word 0: magic */ +#define BISZ_TXTST_IDX 1 /* 1: text start */ +#define BISZ_TXTEND_IDX 2 /* 2: text end */ +#define BISZ_DATAST_IDX 3 /* 3: data start */ +#define BISZ_DATAEND_IDX 4 /* 4: data end */ +#define BISZ_BSSST_IDX 5 /* 5: bss start */ +#define BISZ_BSSEND_IDX 6 /* 6: bss end */ +#define BISZ_SIZE 7 /* descriptor size in 32-bit integers */ + +#define SI_INFO(sih) (si_info_t *)sih + +#define GOODCOREADDR(x, b) \ + (((x) >= (b)) && ((x) < ((b) + SI_MAXCORES * SI_CORE_SIZE)) && \ + IS_ALIGNED((x), SI_CORE_SIZE)) +#define GOODREGS(regs) \ + ((regs) != NULL && IS_ALIGNED((unsigned long)(regs), SI_CORE_SIZE)) +#define BADCOREADDR 0 +#define GOODIDX(idx) (((uint)idx) < SI_MAXCORES) +#define NOREV -1 /* Invalid rev */ + +/* Newer chips can access PCI/PCIE and CC core without requiring to change + * PCI BAR0 WIN + */ +#define SI_FAST(si) (((si)->pub.buscoretype == PCIE_CORE_ID) || \ + (((si)->pub.buscoretype == PCI_CORE_ID) && \ + (si)->pub.buscorerev >= 13)) + +#define PCIEREGS(si) (((char *)((si)->curmap) + PCI_16KB0_PCIREGS_OFFSET)) +#define CCREGS_FAST(si) (((char *)((si)->curmap) + PCI_16KB0_CCREGS_OFFSET)) + +/* + * Macros to disable/restore function core(D11, ENET, ILINE20, etc) interrupts + * before after core switching to avoid invalid register accesss inside ISR. + */ +#define INTR_OFF(si, intr_val) \ + if ((si)->intrsoff_fn && \ + (si)->coreid[(si)->curidx] == (si)->dev_coreid) \ + intr_val = (*(si)->intrsoff_fn)((si)->intr_arg) +#define INTR_RESTORE(si, intr_val) \ + if ((si)->intrsrestore_fn && \ + (si)->coreid[(si)->curidx] == (si)->dev_coreid) \ + (*(si)->intrsrestore_fn)((si)->intr_arg, intr_val) + +/* dynamic clock control defines */ +#define LPOMINFREQ 25000 /* low power oscillator min */ +#define LPOMAXFREQ 43000 /* low power oscillator max */ +#define XTALMINFREQ 19800000 /* 20 MHz - 1% */ +#define XTALMAXFREQ 20200000 /* 20 MHz + 1% */ +#define PCIMINFREQ 25000000 /* 25 MHz */ +#define PCIMAXFREQ 34000000 /* 33 MHz + fudge */ + +#define ILP_DIV_5MHZ 0 /* ILP = 5 MHz */ +#define ILP_DIV_1MHZ 4 /* ILP = 1 MHz */ + +#define PCI(si) (((si)->pub.bustype == PCI_BUS) && \ + ((si)->pub.buscoretype == PCI_CORE_ID)) +#define PCIE(si) (((si)->pub.bustype == PCI_BUS) && \ + ((si)->pub.buscoretype == PCIE_CORE_ID)) +#define PCI_FORCEHT(si) \ + (PCIE(si) && (si->pub.chip == BCM4716_CHIP_ID)) + +/* GPIO Based LED powersave defines */ +#define DEFAULT_GPIO_ONTIME 10 /* Default: 10% on */ +#define DEFAULT_GPIO_OFFTIME 90 /* Default: 10% on */ + +#ifndef DEFAULT_GPIOTIMERVAL +#define DEFAULT_GPIOTIMERVAL \ + ((DEFAULT_GPIO_ONTIME << GPIO_ONTIME_SHIFT) | DEFAULT_GPIO_OFFTIME) +#endif + +/* + * Data structure to export all chip specific common variables + * public (read-only) portion of aiutils handle returned by si_attach() + */ +struct si_pub { + uint socitype; /* SOCI_SB, SOCI_AI */ + + uint bustype; /* SI_BUS, PCI_BUS */ + uint buscoretype; /* PCI_CORE_ID, PCIE_CORE_ID, PCMCIA_CORE_ID */ + uint buscorerev; /* buscore rev */ + uint buscoreidx; /* buscore index */ + int ccrev; /* chip common core rev */ + u32 cccaps; /* chip common capabilities */ + u32 cccaps_ext; /* chip common capabilities extension */ + int pmurev; /* pmu core rev */ + u32 pmucaps; /* pmu capabilities */ + uint boardtype; /* board type */ + uint boardvendor; /* board vendor */ + uint boardflags; /* board flags */ + uint boardflags2; /* board flags2 */ + uint chip; /* chip number */ + uint chiprev; /* chip revision */ + uint chippkg; /* chip package option */ + u32 chipst; /* chip status */ + bool issim; /* chip is in simulation or emulation */ + uint socirev; /* SOC interconnect rev */ + bool pci_pr32414; + +}; + +/* + * for HIGH_ONLY driver, the si_t must be writable to allow states sync from + * BMAC to HIGH driver for monolithic driver, it is readonly to prevent accident + * change + */ +typedef const struct si_pub si_t; + +/* + * Many of the routines below take an 'sih' handle as their first arg. + * Allocate this by calling si_attach(). Free it by calling si_detach(). + * At any one time, the sih is logically focused on one particular si core + * (the "current core"). + * Use si_setcore() or si_setcoreidx() to change the association to another core + */ + +#define BADIDX (SI_MAXCORES + 1) + +/* clkctl xtal what flags */ +#define XTAL 0x1 /* primary crystal oscillator (2050) */ +#define PLL 0x2 /* main chip pll */ + +/* clkctl clk mode */ +#define CLK_FAST 0 /* force fast (pll) clock */ +#define CLK_DYNAMIC 2 /* enable dynamic clock control */ + +/* GPIO usage priorities */ +#define GPIO_DRV_PRIORITY 0 /* Driver */ +#define GPIO_APP_PRIORITY 1 /* Application */ +#define GPIO_HI_PRIORITY 2 /* Highest priority. Ignore GPIO + * reservation + */ + +/* GPIO pull up/down */ +#define GPIO_PULLUP 0 +#define GPIO_PULLDN 1 + +/* GPIO event regtype */ +#define GPIO_REGEVT 0 /* GPIO register event */ +#define GPIO_REGEVT_INTMSK 1 /* GPIO register event int mask */ +#define GPIO_REGEVT_INTPOL 2 /* GPIO register event int polarity */ + +/* device path */ +#define SI_DEVPATH_BUFSZ 16 /* min buffer size in bytes */ + +/* SI routine enumeration: to be used by update function with multiple hooks */ +#define SI_DOATTACH 1 +#define SI_PCIDOWN 2 +#define SI_PCIUP 3 + +#define ISSIM_ENAB(sih) 0 + +/* PMU clock/power control */ +#if defined(BCMPMUCTL) +#define PMUCTL_ENAB(sih) (BCMPMUCTL) +#else +#define PMUCTL_ENAB(sih) ((sih)->cccaps & CC_CAP_PMU) +#endif + +/* chipcommon clock/power control (exclusive with PMU's) */ +#if defined(BCMPMUCTL) && BCMPMUCTL +#define CCCTL_ENAB(sih) (0) +#define CCPLL_ENAB(sih) (0) +#else +#define CCCTL_ENAB(sih) ((sih)->cccaps & CC_CAP_PWR_CTL) +#define CCPLL_ENAB(sih) ((sih)->cccaps & CC_CAP_PLL_MASK) +#endif + +typedef void (*gpio_handler_t) (u32 stat, void *arg); + +/* External PA enable mask */ +#define GPIO_CTRL_EPA_EN_MASK 0x40 + +#define SI_ERROR(args) + +#ifdef BCMDBG +#define SI_MSG(args) printk args +#else +#define SI_MSG(args) +#endif /* BCMDBG */ + +/* Define SI_VMSG to printf for verbose debugging, but don't check it in */ +#define SI_VMSG(args) + +#define IS_SIM(chippkg) \ + ((chippkg == HDLSIM_PKG_ID) || (chippkg == HWSIM_PKG_ID)) + +typedef u32(*si_intrsoff_t) (void *intr_arg); +typedef void (*si_intrsrestore_t) (void *intr_arg, u32 arg); +typedef bool(*si_intrsenabled_t) (void *intr_arg); + +typedef struct gpioh_item { + void *arg; + bool level; + gpio_handler_t handler; + u32 event; + struct gpioh_item *next; +} gpioh_item_t; + +/* misc si info needed by some of the routines */ +typedef struct si_info { + struct si_pub pub; /* back plane public state (must be first) */ + void *pbus; /* handle to bus (pci/sdio/..) */ + uint dev_coreid; /* the core provides driver functions */ + void *intr_arg; /* interrupt callback function arg */ + si_intrsoff_t intrsoff_fn; /* turns chip interrupts off */ + si_intrsrestore_t intrsrestore_fn; /* restore chip interrupts */ + si_intrsenabled_t intrsenabled_fn; /* check if interrupts are enabled */ + + void *pch; /* PCI/E core handle */ + + gpioh_item_t *gpioh_head; /* GPIO event handlers list */ + + bool memseg; /* flag to toggle MEM_SEG register */ + + char *vars; + uint varsz; + + void *curmap; /* current regs va */ + void *regs[SI_MAXCORES]; /* other regs va */ + + uint curidx; /* current core index */ + uint numcores; /* # discovered cores */ + uint coreid[SI_MAXCORES]; /* id of each core */ + u32 coresba[SI_MAXCORES]; /* backplane address of each core */ + void *regs2[SI_MAXCORES]; /* 2nd virtual address per core (usbh20) */ + u32 coresba2[SI_MAXCORES]; /* 2nd phys address per core (usbh20) */ + u32 coresba_size[SI_MAXCORES]; /* backplane address space size */ + u32 coresba2_size[SI_MAXCORES]; /* second address space size */ + + void *curwrap; /* current wrapper va */ + void *wrappers[SI_MAXCORES]; /* other cores wrapper va */ + u32 wrapba[SI_MAXCORES]; /* address of controlling wrapper */ + + u32 cia[SI_MAXCORES]; /* erom cia entry for each core */ + u32 cib[SI_MAXCORES]; /* erom cia entry for each core */ + u32 oob_router; /* oob router registers for axi */ +} si_info_t; + +/* AMBA Interconnect exported externs */ +#if 0 +extern si_t *ai_attach(uint pcidev, struct osl_info *osh, void *regs, + uint bustype, void *sdh, char **vars, uint *varsz); +extern si_t *ai_kattach(struct osl_info *osh); +#endif +extern void ai_scan(si_t *sih, void *regs, uint devid); + +extern uint ai_flag(si_t *sih); +extern void ai_setint(si_t *sih, int siflag); +extern uint ai_coreidx(si_t *sih); +extern uint ai_corevendor(si_t *sih); +extern uint ai_corerev(si_t *sih); +extern bool ai_iscoreup(si_t *sih); +extern void *ai_setcoreidx(si_t *sih, uint coreidx); +extern u32 ai_core_cflags(si_t *sih, u32 mask, u32 val); +extern void ai_core_cflags_wo(si_t *sih, u32 mask, u32 val); +extern u32 ai_core_sflags(si_t *sih, u32 mask, u32 val); +extern uint ai_corereg(si_t *sih, uint coreidx, uint regoff, uint mask, + uint val); +extern void ai_core_reset(si_t *sih, u32 bits, u32 resetbits); +extern void ai_core_disable(si_t *sih, u32 bits); +extern int ai_numaddrspaces(si_t *sih); +extern u32 ai_addrspace(si_t *sih, uint asidx); +extern u32 ai_addrspacesize(si_t *sih, uint asidx); +extern void ai_write_wrap_reg(si_t *sih, u32 offset, u32 val); + +/* === exported functions === */ +extern si_t *si_attach(uint pcidev, void *regs, uint bustype, + void *sdh, char **vars, uint *varsz); + +extern void si_detach(si_t *sih); +extern bool si_pci_war16165(si_t *sih); + +extern uint si_coreid(si_t *sih); +extern uint si_flag(si_t *sih); +extern uint si_corerev(si_t *sih); +struct osl_info *si_osh(si_t *sih); +extern uint si_corereg(si_t *sih, uint coreidx, uint regoff, uint mask, + uint val); +extern void si_write_wrapperreg(si_t *sih, u32 offset, u32 val); +extern u32 si_core_cflags(si_t *sih, u32 mask, u32 val); +extern u32 si_core_sflags(si_t *sih, u32 mask, u32 val); +extern bool si_iscoreup(si_t *sih); +extern uint si_findcoreidx(si_t *sih, uint coreid, uint coreunit); +extern void *si_setcoreidx(si_t *sih, uint coreidx); +extern void *si_setcore(si_t *sih, uint coreid, uint coreunit); +extern void *si_switch_core(si_t *sih, uint coreid, uint *origidx, + uint *intr_val); +extern void si_restore_core(si_t *sih, uint coreid, uint intr_val); +extern void si_core_reset(si_t *sih, u32 bits, u32 resetbits); +extern void si_core_disable(si_t *sih, u32 bits); +extern u32 si_alp_clock(si_t *sih); +extern u32 si_ilp_clock(si_t *sih); +extern void si_pci_setup(si_t *sih, uint coremask); +extern void si_setint(si_t *sih, int siflag); +extern bool si_backplane64(si_t *sih); +extern void si_register_intr_callback(si_t *sih, void *intrsoff_fn, + void *intrsrestore_fn, + void *intrsenabled_fn, void *intr_arg); +extern void si_deregister_intr_callback(si_t *sih); +extern void si_clkctl_init(si_t *sih); +extern u16 si_clkctl_fast_pwrup_delay(si_t *sih); +extern bool si_clkctl_cc(si_t *sih, uint mode); +extern int si_clkctl_xtal(si_t *sih, uint what, bool on); +extern bool si_deviceremoved(si_t *sih); +extern u32 si_socram_size(si_t *sih); + +extern void si_watchdog(si_t *sih, uint ticks); +extern u32 si_gpiocontrol(si_t *sih, u32 mask, u32 val, + u8 priority); + +#define si_eci(sih) 0 +#define si_eci_init(sih) (0) +#define si_eci_notify_bt(sih, type, val) (0) +#define si_seci(sih) 0 + +/* OTP status */ +extern bool si_is_otp_disabled(si_t *sih); +extern bool si_is_otp_powered(si_t *sih); +extern void si_otp_power(si_t *sih, bool on); + +/* SPROM availability */ +extern bool si_is_sprom_available(si_t *sih); + +/* + * Build device path. Path size must be >= SI_DEVPATH_BUFSZ. + * The returned path is NULL terminated and has trailing '/'. + * Return 0 on success, nonzero otherwise. + */ +extern int si_devpath(si_t *sih, char *path, int size); +/* Read variable with prepending the devpath to the name */ +extern char *si_getdevpathvar(si_t *sih, const char *name); +extern int si_getdevpathintvar(si_t *sih, const char *name); + +extern void si_war42780_clkreq(si_t *sih, bool clkreq); +extern void si_pci_sleep(si_t *sih); +extern void si_pci_down(si_t *sih); +extern void si_pci_up(si_t *sih); +extern void si_pcie_extendL1timer(si_t *sih, bool extend); +extern int si_pci_fixcfg(si_t *sih); + +extern void si_chipcontrl_epa4331(si_t *sih, bool on); +/* Enable Ex-PA for 4313 */ +extern void si_epa_4313war(si_t *sih); + +char *si_getnvramflvar(si_t *sih, const char *name); + +#endif /* _aiutils_h_ */ diff --git a/drivers/staging/brcm80211/include/siutils.h b/drivers/staging/brcm80211/include/siutils.h index 101e9a4..6faf6a6 100644 --- a/drivers/staging/brcm80211/include/siutils.h +++ b/drivers/staging/brcm80211/include/siutils.h @@ -327,31 +327,6 @@ extern void si_epa_4313war(si_t *sih); char *si_getnvramflvar(si_t *sih, const char *name); -/* AMBA Interconnect exported externs */ -extern si_t *ai_attach(uint pcidev, void *regs, uint bustype, - void *sdh, char **vars, uint *varsz); -extern si_t *ai_kattach(void); -extern void ai_scan(si_t *sih, void *regs, uint devid); - -extern uint ai_flag(si_t *sih); -extern void ai_setint(si_t *sih, int siflag); -extern uint ai_coreidx(si_t *sih); -extern uint ai_corevendor(si_t *sih); -extern uint ai_corerev(si_t *sih); -extern bool ai_iscoreup(si_t *sih); -extern void *ai_setcoreidx(si_t *sih, uint coreidx); -extern u32 ai_core_cflags(si_t *sih, u32 mask, u32 val); -extern void ai_core_cflags_wo(si_t *sih, u32 mask, u32 val); -extern u32 ai_core_sflags(si_t *sih, u32 mask, u32 val); -extern uint ai_corereg(si_t *sih, uint coreidx, uint regoff, uint mask, - uint val); -extern void ai_core_reset(si_t *sih, u32 bits, u32 resetbits); -extern void ai_core_disable(si_t *sih, u32 bits); -extern int ai_numaddrspaces(si_t *sih); -extern u32 ai_addrspace(si_t *sih, uint asidx); -extern u32 ai_addrspacesize(si_t *sih, uint asidx); -extern void ai_write_wrap_reg(si_t *sih, u32 offset, u32 val); - #ifdef BCMSDIO #define si_setcoreidx(sih, idx) sb_setcoreidx(sih, idx) #define si_coreid(sih) sb_coreid(sih) diff --git a/drivers/staging/brcm80211/util/aiutils.c b/drivers/staging/brcm80211/util/aiutils.c index 5708690..0451044 100644 --- a/drivers/staging/brcm80211/util/aiutils.c +++ b/drivers/staging/brcm80211/util/aiutils.c @@ -21,12 +21,20 @@ #include <linux/module.h> #include <linux/pci.h> #include <bcmutils.h> -#include <siutils.h> +#include <aiutils.h> #include <hndsoc.h> #include <sbchipc.h> #include <pcicfg.h> #include <bcmdevs.h> +/* ********** from siutils.c *********** */ +#include <pci_core.h> +#include <pcie_core.h> +#include <nicpci.h> +#include <bcmnvram.h> +#include <bcmsrom.h> +#include <hndpmu.h> + #define BCM47162_DMP() ((sih->chip == BCM47162_CHIP_ID) && \ (sih->chiprev == 0) && \ (sii->coreid[sii->curidx] == MIPS74K_CORE_ID)) @@ -542,7 +550,7 @@ uint ai_corereg(si_t *sih, uint coreidx, uint regoff, uint mask, uint val) INTR_OFF(sii, intr_val); /* save current core index */ - origidx = si_coreidx(&sii->pub); + origidx = ai_coreidx(&sii->pub); /* switch core */ r = (u32 *) ((unsigned char *) ai_setcoreidx(&sii->pub, coreidx) + @@ -703,3 +711,1573 @@ u32 ai_core_sflags(si_t *sih, u32 mask, u32 val) return R_REG(&ai->iostatus); } +/* *************** from siutils.c ************** */ +/* local prototypes */ +static si_info_t *si_doattach(si_info_t *sii, uint devid, 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, + u32 savewin, uint *origidx, void *regs); +static void si_nvram_process(si_info_t *sii, char *pvars); + +/* dev path concatenation util */ +static char *si_devpathvar(si_t *sih, char *var, int len, const char *name); +static bool _si_clkctl_cc(si_info_t *sii, uint mode); +static bool si_ispcie(si_info_t *sii); + +/* global variable to indicate reservation/release of gpio's */ +static u32 si_gpioreservation; + +/* + * Allocate a si handle. + * devid - pci device id (used to determine chip#) + * osh - opaque OS handle + * regs - virtual address of initial core registers + * bustype - pci/sb/sdio/etc + * vars - pointer to a pointer area for "environment" variables + * varsz - pointer to int to return the size of the vars + */ +si_t *si_attach(uint devid, void *regs, uint bustype, + void *sdh, char **vars, uint *varsz) +{ + si_info_t *sii; + + /* alloc si_info_t */ + sii = kmalloc(sizeof(si_info_t), GFP_ATOMIC); + if (sii == NULL) { + SI_ERROR(("si_attach: malloc failed!\n")); + return NULL; + } + + if (si_doattach(sii, devid, regs, bustype, sdh, vars, varsz) == + NULL) { + kfree(sii); + return NULL; + } + sii->vars = vars ? *vars : NULL; + sii->varsz = varsz ? *varsz : 0; + + return (si_t *) sii; +} + +/* global kernel resource */ +static si_info_t ksii; + +static bool si_buscore_prep(si_info_t *sii, uint bustype, uint devid, + void *sdh) +{ + /* kludge to enable the clock on the 4306 which lacks a slowclock */ + if (bustype == PCI_BUS && !si_ispcie(sii)) + si_clkctl_xtal(&sii->pub, XTAL | PLL, ON); + return true; +} + +static bool si_buscore_setup(si_info_t *sii, chipcregs_t *cc, uint bustype, + u32 savewin, uint *origidx, void *regs) +{ + bool pci, pcie; + uint i; + uint pciidx, pcieidx, pcirev, pcierev; + + cc = si_setcoreidx(&sii->pub, SI_CC_IDX); + ASSERT(cc); + + /* get chipcommon rev */ + sii->pub.ccrev = (int)si_corerev(&sii->pub); + + /* get chipcommon chipstatus */ + if (sii->pub.ccrev >= 11) + sii->pub.chipst = R_REG(&cc->chipstatus); + + /* get chipcommon capabilites */ + sii->pub.cccaps = R_REG(&cc->capabilities); + /* get chipcommon extended capabilities */ + + if (sii->pub.ccrev >= 35) + sii->pub.cccaps_ext = R_REG(&cc->capabilities_ext); + + /* get pmu rev and caps */ + if (sii->pub.cccaps & CC_CAP_PMU) { + sii->pub.pmucaps = R_REG(&cc->pmucapabilities); + sii->pub.pmurev = sii->pub.pmucaps & PCAP_REV_MASK; + } + + /* figure out bus/orignal core idx */ + sii->pub.buscoretype = NODEV_CORE_ID; + sii->pub.buscorerev = NOREV; + sii->pub.buscoreidx = BADIDX; + + pci = pcie = false; + pcirev = pcierev = NOREV; + pciidx = pcieidx = BADIDX; + + for (i = 0; i < sii->numcores; i++) { + uint cid, crev; + + si_setcoreidx(&sii->pub, i); + cid = si_coreid(&sii->pub); + 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, sii->coresba[i], sii->regs[i])); + + if (bustype == PCI_BUS) { + if (cid == PCI_CORE_ID) { + pciidx = i; + pcirev = crev; + pci = true; + } else if (cid == PCIE_CORE_ID) { + pcieidx = i; + pcierev = crev; + pcie = true; + } + } + + /* find the core idx before entering this func. */ + if ((savewin && (savewin == sii->coresba[i])) || + (regs == sii->regs[i])) + *origidx = i; + } + + if (pci && pcie) { + if (si_ispcie(sii)) + pci = false; + else + pcie = false; + } + if (pci) { + sii->pub.buscoretype = PCI_CORE_ID; + sii->pub.buscorerev = pcirev; + sii->pub.buscoreidx = pciidx; + } else if (pcie) { + sii->pub.buscoretype = PCIE_CORE_ID; + sii->pub.buscorerev = pcierev; + sii->pub.buscoreidx = pcieidx; + } + + SI_VMSG(("Buscore id/type/rev %d/0x%x/%d\n", sii->pub.buscoreidx, + sii->pub.buscoretype, sii->pub.buscorerev)); + + /* fixup necessary chip/core configurations */ + if (sii->pub.bustype == PCI_BUS) { + if (SI_FAST(sii)) { + if (!sii->pch) { + sii->pch = (void *)pcicore_init( + &sii->pub, sii->pbus, + (void *)PCIEREGS(sii)); + if (sii->pch == NULL) + return false; + } + } + if (si_pci_fixcfg(&sii->pub)) { + SI_ERROR(("si_doattach: si_pci_fixcfg failed\n")); + return false; + } + } + + /* return to the original core */ + si_setcoreidx(&sii->pub, *origidx); + + return true; +} + +static __used void si_nvram_process(si_info_t *sii, char *pvars) +{ + uint w = 0; + + /* get boardtype and boardrev */ + switch (sii->pub.bustype) { + case PCI_BUS: + /* do a pci config read to get subsystem id and subvendor id */ + pci_read_config_dword(sii->pbus, PCI_CFG_SVID, &w); + /* Let nvram variables override subsystem Vend/ID */ + sii->pub.boardvendor = (u16)si_getdevpathintvar(&sii->pub, + "boardvendor"); + if (sii->pub.boardvendor == 0) + sii->pub.boardvendor = w & 0xffff; + else + SI_ERROR(("Overriding boardvendor: 0x%x instead of " + "0x%x\n", sii->pub.boardvendor, w & 0xffff)); + sii->pub.boardtype = (u16)si_getdevpathintvar(&sii->pub, + "boardtype"); + if (sii->pub.boardtype == 0) + sii->pub.boardtype = (w >> 16) & 0xffff; + else + SI_ERROR(("Overriding boardtype: 0x%x instead of 0x%x\n" + , sii->pub.boardtype, (w >> 16) & 0xffff)); + break; + + sii->pub.boardvendor = getintvar(pvars, "manfid"); + sii->pub.boardtype = getintvar(pvars, "prodid"); + break; + + case SI_BUS: + case JTAG_BUS: + sii->pub.boardvendor = PCI_VENDOR_ID_BROADCOM; + sii->pub.boardtype = getintvar(pvars, "prodid"); + if (pvars == NULL || (sii->pub.boardtype == 0)) { + sii->pub.boardtype = getintvar(NULL, "boardtype"); + if (sii->pub.boardtype == 0) + sii->pub.boardtype = 0xffff; + } + break; + } + + if (sii->pub.boardtype == 0) { + SI_ERROR(("si_doattach: unknown board type\n")); + ASSERT(sii->pub.boardtype); + } + + sii->pub.boardflags = getintvar(pvars, "boardflags"); +} + +static si_info_t *si_doattach(si_info_t *sii, uint devid, + void *regs, uint bustype, void *pbus, + char **vars, uint *varsz) +{ + struct si_pub *sih = &sii->pub; + u32 w, savewin; + chipcregs_t *cc; + char *pvars = NULL; + uint origidx; + + ASSERT(GOODREGS(regs)); + + memset((unsigned char *) sii, 0, sizeof(si_info_t)); + + savewin = 0; + + sih->buscoreidx = BADIDX; + + sii->curmap = regs; + sii->pbus = pbus; + + /* check to see if we are a si core mimic'ing a pci core */ + if (bustype == PCI_BUS) { + pci_read_config_dword(sii->pbus, PCI_SPROM_CONTROL, &w); + if (w == 0xffffffff) { + SI_ERROR(("%s: incoming bus is PCI but it's a lie, " + " switching to SI devid:0x%x\n", + __func__, devid)); + bustype = SI_BUS; + } + } + + /* find Chipcommon address */ + if (bustype == PCI_BUS) { + pci_read_config_dword(sii->pbus, PCI_BAR0_WIN, &savewin); + if (!GOODCOREADDR(savewin, SI_ENUM_BASE)) + savewin = SI_ENUM_BASE; + pci_write_config_dword(sii->pbus, PCI_BAR0_WIN, + SI_ENUM_BASE); + cc = (chipcregs_t *) regs; + } else { + cc = (chipcregs_t *) REG_MAP(SI_ENUM_BASE, SI_CORE_SIZE); + } + + sih->bustype = bustype; + + /* bus/core/clk setup for register access */ + if (!si_buscore_prep(sii, bustype, devid, pbus)) { + SI_ERROR(("si_doattach: si_core_clk_prep failed %d\n", + bustype)); + return NULL; + } + + /* + * ChipID recognition. + * We assume we can read chipid at offset 0 from the regs arg. + * If we add other chiptypes (or if we need to support old sdio + * hosts w/o chipcommon), some way of recognizing them needs to + * be added here. + */ + w = R_REG(&cc->chipid); + sih->socitype = (w & CID_TYPE_MASK) >> CID_TYPE_SHIFT; + /* Might as wll fill in chip id rev & pkg */ + sih->chip = w & CID_ID_MASK; + sih->chiprev = (w & CID_REV_MASK) >> CID_REV_SHIFT; + sih->chippkg = (w & CID_PKG_MASK) >> CID_PKG_SHIFT; + + sih->issim = IS_SIM(sih->chippkg); + + /* scan for cores */ + if (sii->pub.socitype == SOCI_AI) { + SI_MSG(("Found chip type AI (0x%08x)\n", w)); + /* pass chipc address instead of original core base */ + ai_scan(&sii->pub, (void *)cc, devid); + } else { + SI_ERROR(("Found chip of unknown type (0x%08x)\n", w)); + return NULL; + } + /* no cores found, bail out */ + if (sii->numcores == 0) { + SI_ERROR(("si_doattach: could not find any cores\n")); + return NULL; + } + /* bus/core/clk setup */ + origidx = SI_CC_IDX; + if (!si_buscore_setup(sii, cc, bustype, savewin, &origidx, regs)) { + SI_ERROR(("si_doattach: si_buscore_setup failed\n")); + goto exit; + } + + /* assume current core is CC */ + if ((sii->pub.ccrev == 0x25) + && + ((sih->chip == BCM43236_CHIP_ID + || sih->chip == BCM43235_CHIP_ID + || sih->chip == BCM43238_CHIP_ID) + && (sii->pub.chiprev <= 2))) { + + if ((cc->chipstatus & CST43236_BP_CLK) != 0) { + uint clkdiv; + clkdiv = R_REG(&cc->clkdiv); + /* otp_clk_div is even number, 120/14 < 9mhz */ + clkdiv = (clkdiv & ~CLKD_OTP) | (14 << CLKD_OTP_SHIFT); + W_REG(&cc->clkdiv, clkdiv); + SI_ERROR(("%s: set clkdiv to %x\n", __func__, clkdiv)); + } + udelay(10); + } + + /* Init nvram from flash if it exists */ + nvram_init((void *)&(sii->pub)); + + /* Init nvram from sprom/otp if they exist */ + if (srom_var_init + (&sii->pub, bustype, regs, vars, varsz)) { + SI_ERROR(("si_doattach: srom_var_init failed: bad srom\n")); + goto exit; + } + pvars = vars ? *vars : NULL; + si_nvram_process(sii, pvars); + + /* === NVRAM, clock is ready === */ + cc = (chipcregs_t *) si_setcore(sih, CC_CORE_ID, 0); + W_REG(&cc->gpiopullup, 0); + W_REG(&cc->gpiopulldown, 0); + si_setcoreidx(sih, origidx); + + /* PMU specific initializations */ + if (PMUCTL_ENAB(sih)) { + u32 xtalfreq; + si_pmu_init(sih); + si_pmu_chip_init(sih); + xtalfreq = getintvar(pvars, "xtalfreq"); + /* If xtalfreq var not available, try to measure it */ + if (xtalfreq == 0) + xtalfreq = si_pmu_measure_alpclk(sih); + si_pmu_pll_init(sih, xtalfreq); + si_pmu_res_init(sih); + si_pmu_swreg_init(sih); + } + + /* setup the GPIO based LED powersave register */ + w = getintvar(pvars, "leddc"); + if (w == 0) + w = DEFAULT_GPIOTIMERVAL; + si_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, gpiotimerval), ~0, w); + + if (PCIE(sii)) { + ASSERT(sii->pch != NULL); + pcicore_attach(sii->pch, pvars, SI_DOATTACH); + } + + if ((sih->chip == BCM43224_CHIP_ID) || + (sih->chip == BCM43421_CHIP_ID)) { + /* + * enable 12 mA drive strenth for 43224 and + * set chipControl register bit 15 + */ + if (sih->chiprev == 0) { + SI_MSG(("Applying 43224A0 WARs\n")); + si_corereg(sih, SI_CC_IDX, + offsetof(chipcregs_t, chipcontrol), + CCTRL43224_GPIO_TOGGLE, + CCTRL43224_GPIO_TOGGLE); + si_pmu_chipcontrol(sih, 0, CCTRL_43224A0_12MA_LED_DRIVE, + CCTRL_43224A0_12MA_LED_DRIVE); + } + if (sih->chiprev >= 1) { + SI_MSG(("Applying 43224B0+ WARs\n")); + si_pmu_chipcontrol(sih, 0, CCTRL_43224B0_12MA_LED_DRIVE, + CCTRL_43224B0_12MA_LED_DRIVE); + } + } + + if (sih->chip == BCM4313_CHIP_ID) { + /* + * enable 12 mA drive strenth for 4313 and + * set chipControl register bit 1 + */ + SI_MSG(("Applying 4313 WARs\n")); + si_pmu_chipcontrol(sih, 0, CCTRL_4313_12MA_LED_DRIVE, + CCTRL_4313_12MA_LED_DRIVE); + } + + if (sih->chip == BCM4331_CHIP_ID) { + /* Enable Ext PA lines depending on chip package option */ + si_chipcontrl_epa4331(sih, true); + } + + return sii; + exit: + if (sih->bustype == PCI_BUS) { + if (sii->pch) + pcicore_deinit(sii->pch); + sii->pch = NULL; + } + + return NULL; +} + +/* may be called with core in reset */ +void si_detach(si_t *sih) +{ + si_info_t *sii; + uint idx; + + struct si_pub *si_local = NULL; + bcopy(&sih, &si_local, sizeof(si_t **)); + + sii = SI_INFO(sih); + + if (sii == NULL) + return; + + if (sih->bustype == SI_BUS) + for (idx = 0; idx < SI_MAXCORES; idx++) + if (sii->regs[idx]) { + iounmap(sii->regs[idx]); + sii->regs[idx] = NULL; + } + + nvram_exit((void *)si_local); /* free up nvram buffers */ + + if (sih->bustype == PCI_BUS) { + if (sii->pch) + pcicore_deinit(sii->pch); + sii->pch = NULL; + } + + if (sii != &ksii) + kfree(sii); +} + +/* register driver interrupt disabling and restoring callback functions */ +void +si_register_intr_callback(si_t *sih, void *intrsoff_fn, void *intrsrestore_fn, + void *intrsenabled_fn, void *intr_arg) +{ + si_info_t *sii; + + sii = SI_INFO(sih); + sii->intr_arg = intr_arg; + sii->intrsoff_fn = (si_intrsoff_t) intrsoff_fn; + sii->intrsrestore_fn = (si_intrsrestore_t) intrsrestore_fn; + sii->intrsenabled_fn = (si_intrsenabled_t) intrsenabled_fn; + /* save current core id. when this function called, the current core + * must be the core which provides driver functions(il, et, wl, etc.) + */ + sii->dev_coreid = sii->coreid[sii->curidx]; +} + +void si_deregister_intr_callback(si_t *sih) +{ + si_info_t *sii; + + sii = SI_INFO(sih); + sii->intrsoff_fn = NULL; +} + +uint si_flag(si_t *sih) +{ + if (sih->socitype == SOCI_AI) + return ai_flag(sih); + else { + ASSERT(0); + return 0; + } +} + +void si_setint(si_t *sih, int siflag) +{ + if (sih->socitype == SOCI_AI) + ai_setint(sih, siflag); + else + ASSERT(0); +} + +uint si_coreid(si_t *sih) +{ + si_info_t *sii; + + sii = SI_INFO(sih); + return sii->coreid[sii->curidx]; +} + +uint ai_coreidx(si_t *sih) +{ + si_info_t *sii; + + sii = SI_INFO(sih); + return sii->curidx; +} + +bool si_backplane64(si_t *sih) +{ + return (sih->cccaps & CC_CAP_BKPLN64) != 0; +} + +uint si_corerev(si_t *sih) +{ + if (sih->socitype == SOCI_AI) + return ai_corerev(sih); + else { + ASSERT(0); + return 0; + } +} + +/* return index of coreid or BADIDX if not found */ +uint si_findcoreidx(si_t *sih, uint coreid, uint coreunit) +{ + si_info_t *sii; + uint found; + uint i; + + sii = SI_INFO(sih); + + found = 0; + + for (i = 0; i < sii->numcores; i++) + if (sii->coreid[i] == coreid) { + if (found == coreunit) + return i; + found++; + } + + return BADIDX; +} + +/* + * This function changes logical "focus" to the indicated core; + * must be called with interrupts off. + * Moreover, callers should keep interrupts off during switching + * out of and back to d11 core. + */ +void *si_setcore(si_t *sih, uint coreid, uint coreunit) +{ + uint idx; + + idx = si_findcoreidx(sih, coreid, coreunit); + if (!GOODIDX(idx)) + return NULL; + + if (sih->socitype == SOCI_AI) + return ai_setcoreidx(sih, idx); + else { + ASSERT(0); + return NULL; + } +} + +void *si_setcoreidx(si_t *sih, uint coreidx) +{ + if (sih->socitype == SOCI_AI) + return ai_setcoreidx(sih, coreidx); + else { + ASSERT(0); + return NULL; + } +} + +/* Turn off interrupt as required by si_setcore, before switch core */ +void *si_switch_core(si_t *sih, uint coreid, uint *origidx, uint *intr_val) +{ + void *cc; + si_info_t *sii; + + sii = SI_INFO(sih); + + if (SI_FAST(sii)) { + /* Overloading the origidx variable to remember the coreid, + * this works because the core ids cannot be confused with + * core indices. + */ + *origidx = coreid; + if (coreid == CC_CORE_ID) + return (void *)CCREGS_FAST(sii); + else if (coreid == sih->buscoretype) + return (void *)PCIEREGS(sii); + } + INTR_OFF(sii, *intr_val); + *origidx = sii->curidx; + cc = si_setcore(sih, coreid, 0); + ASSERT(cc != NULL); + + return cc; +} + +/* restore coreidx and restore interrupt */ +void si_restore_core(si_t *sih, uint coreid, uint intr_val) +{ + si_info_t *sii; + + sii = SI_INFO(sih); + if (SI_FAST(sii) + && ((coreid == CC_CORE_ID) || (coreid == sih->buscoretype))) + return; + + si_setcoreidx(sih, coreid); + INTR_RESTORE(sii, intr_val); +} + +u32 si_core_cflags(si_t *sih, u32 mask, u32 val) +{ + if (sih->socitype == SOCI_AI) + return ai_core_cflags(sih, mask, val); + else { + ASSERT(0); + return 0; + } +} + +u32 si_core_sflags(si_t *sih, u32 mask, u32 val) +{ + if (sih->socitype == SOCI_AI) + return ai_core_sflags(sih, mask, val); + else { + ASSERT(0); + return 0; + } +} + +bool si_iscoreup(si_t *sih) +{ + if (sih->socitype == SOCI_AI) + return ai_iscoreup(sih); + else { + ASSERT(0); + return false; + } +} + +void si_write_wrapperreg(si_t *sih, u32 offset, u32 val) +{ + /* only for 4319, no requirement for SOCI_SB */ + if (sih->socitype == SOCI_AI) + ai_write_wrap_reg(sih, offset, val); +} + +uint si_corereg(si_t *sih, uint coreidx, uint regoff, uint mask, uint val) +{ + + if (sih->socitype == SOCI_AI) + return ai_corereg(sih, coreidx, regoff, mask, val); + else { + ASSERT(0); + return 0; + } +} + +void si_core_disable(si_t *sih, u32 bits) +{ + + if (sih->socitype == SOCI_AI) + ai_core_disable(sih, bits); +} + +void si_core_reset(si_t *sih, u32 bits, u32 resetbits) +{ + if (sih->socitype == SOCI_AI) + ai_core_reset(sih, bits, resetbits); +} + +u32 si_alp_clock(si_t *sih) +{ + if (PMUCTL_ENAB(sih)) + return si_pmu_alp_clock(sih); + + return ALP_CLOCK; +} + +u32 si_ilp_clock(si_t *sih) +{ + if (PMUCTL_ENAB(sih)) + return si_pmu_ilp_clock(sih); + + return ILP_CLOCK; +} + +/* set chip watchdog reset timer to fire in 'ticks' */ +void si_watchdog(si_t *sih, uint ticks) +{ + uint nb, maxt; + + if (PMUCTL_ENAB(sih)) { + + if ((sih->chip == BCM4319_CHIP_ID) && + (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); + } + + nb = (sih->ccrev < 26) ? 16 : ((sih->ccrev >= 37) ? 32 : 24); + /* The mips compiler uses the sllv instruction, + * so we specially handle the 32-bit case. + */ + if (nb == 32) + maxt = 0xffffffff; + else + maxt = ((1 << nb) - 1); + + if (ticks == 1) + ticks = 2; + else if (ticks > maxt) + ticks = maxt; + + si_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, pmuwatchdog), + ~0, ticks); + } else { + /* + * make sure we come up in fast clock mode; + * or if clearing, clear clock + */ + si_clkctl_cc(sih, ticks ? CLK_FAST : CLK_DYNAMIC); + maxt = (1 << 28) - 1; + if (ticks > maxt) + ticks = maxt; + + si_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, watchdog), ~0, + ticks); + } +} + +/* return the slow clock source - LPO, XTAL, or PCI */ +static uint si_slowclk_src(si_info_t *sii) +{ + chipcregs_t *cc; + u32 val; + + ASSERT(SI_FAST(sii) || si_coreid(&sii->pub) == CC_CORE_ID); + + if (sii->pub.ccrev < 6) { + if (sii->pub.bustype == PCI_BUS) { + pci_read_config_dword(sii->pbus, PCI_GPIO_OUT, + &val); + if (val & PCI_CFG_GPIO_SCS) + return SCC_SS_PCI; + } + return SCC_SS_XTAL; + } else if (sii->pub.ccrev < 10) { + cc = (chipcregs_t *) si_setcoreidx(&sii->pub, sii->curidx); + return R_REG(&cc->slow_clk_ctl) & SCC_SS_MASK; + } else /* Insta-clock */ + return SCC_SS_XTAL; +} + +/* return the ILP (slowclock) min or max frequency */ +static uint si_slowclk_freq(si_info_t *sii, bool max_freq, chipcregs_t *cc) +{ + u32 slowclk; + uint div; + + ASSERT(SI_FAST(sii) || si_coreid(&sii->pub) == CC_CORE_ID); + + /* + * shouldn't be here unless we've established + * the chip has dynamic clk control + */ + ASSERT(R_REG(&cc->capabilities) & CC_CAP_PWR_CTL); + + slowclk = si_slowclk_src(sii); + if (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) { + div = 4 * + (((R_REG(&cc->slow_clk_ctl) & SCC_CD_MASK) >> + SCC_CD_SHIFT) + 1); + if (slowclk == SCC_SS_LPO) + return max_freq ? LPOMAXFREQ : LPOMINFREQ; + else if (slowclk == SCC_SS_XTAL) + return max_freq ? (XTALMAXFREQ / div) + : (XTALMINFREQ / div); + else if (slowclk == SCC_SS_PCI) + return max_freq ? (PCIMAXFREQ / div) + : (PCIMINFREQ / div); + else + ASSERT(0); + } else { + /* Chipc rev 10 is InstaClock */ + div = R_REG(&cc->system_clk_ctl) >> SYCC_CD_SHIFT; + div = 4 * (div + 1); + return max_freq ? XTALMAXFREQ : (XTALMINFREQ / div); + } + return 0; +} + +static void si_clkctl_setdelay(si_info_t *sii, void *chipcregs) +{ + chipcregs_t *cc = (chipcregs_t *) chipcregs; + uint slowmaxfreq, pll_delay, slowclk; + uint pll_on_delay, fref_sel_delay; + + pll_delay = PLL_DELAY; + + /* + * If the slow clock is not sourced by the xtal then + * add the xtal_on_delay since the xtal will also be + * powered down by dynamic clk control logic. + */ + slowclk = si_slowclk_src(sii); + if (slowclk != SCC_SS_XTAL) + 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); + + pll_on_delay = ((slowmaxfreq * pll_delay) + 999999) / 1000000; + fref_sel_delay = ((slowmaxfreq * FREF_DELAY) + 999999) / 1000000; + + W_REG(&cc->pll_on_delay, pll_on_delay); + W_REG(&cc->fref_sel_delay, fref_sel_delay); +} + +/* initialize power control delay registers */ +void si_clkctl_init(si_t *sih) +{ + si_info_t *sii; + uint origidx = 0; + chipcregs_t *cc; + bool fast; + + if (!CCCTL_ENAB(sih)) + return; + + sii = SI_INFO(sih); + fast = SI_FAST(sii); + if (!fast) { + origidx = sii->curidx; + cc = (chipcregs_t *) si_setcore(sih, CC_CORE_ID, 0); + if (cc == NULL) + return; + } else { + cc = (chipcregs_t *) CCREGS_FAST(sii); + if (cc == NULL) + return; + } + ASSERT(cc != NULL); + + /* set all Instaclk chip ILP to 1 MHz */ + if (sih->ccrev >= 10) + SET_REG(&cc->system_clk_ctl, SYCC_CD_MASK, + (ILP_DIV_1MHZ << SYCC_CD_SHIFT)); + + si_clkctl_setdelay(sii, (void *)cc); + + if (!fast) + si_setcoreidx(sih, origidx); +} + +/* + * return the value suitable for writing to the + * dot11 core FAST_PWRUP_DELAY register + */ +u16 si_clkctl_fast_pwrup_delay(si_t *sih) +{ + si_info_t *sii; + uint origidx = 0; + chipcregs_t *cc; + uint slowminfreq; + u16 fpdelay; + uint intr_val = 0; + bool fast; + + sii = SI_INFO(sih); + if (PMUCTL_ENAB(sih)) { + INTR_OFF(sii, intr_val); + fpdelay = si_pmu_fast_pwrup_delay(sih); + INTR_RESTORE(sii, intr_val); + return fpdelay; + } + + if (!CCCTL_ENAB(sih)) + return 0; + + fast = SI_FAST(sii); + fpdelay = 0; + if (!fast) { + origidx = sii->curidx; + INTR_OFF(sii, intr_val); + cc = (chipcregs_t *) si_setcore(sih, CC_CORE_ID, 0); + if (cc == NULL) + goto done; + } else { + cc = (chipcregs_t *) CCREGS_FAST(sii); + if (cc == NULL) + goto done; + } + ASSERT(cc != NULL); + + slowminfreq = si_slowclk_freq(sii, false, cc); + fpdelay = (((R_REG(&cc->pll_on_delay) + 2) * 1000000) + + (slowminfreq - 1)) / slowminfreq; + + done: + if (!fast) { + si_setcoreidx(sih, origidx); + INTR_RESTORE(sii, intr_val); + } + return fpdelay; +} + +/* turn primary xtal and/or pll off/on */ +int si_clkctl_xtal(si_t *sih, uint what, bool on) +{ + si_info_t *sii; + u32 in, out, outen; + + sii = SI_INFO(sih); + + switch (sih->bustype) { + + case PCI_BUS: + /* pcie core doesn't have any mapping to control the xtal pu */ + if (PCIE(sii)) + return -1; + + pci_read_config_dword(sii->pbus, PCI_GPIO_IN, &in); + pci_read_config_dword(sii->pbus, PCI_GPIO_OUT, &out); + pci_read_config_dword(sii->pbus, PCI_GPIO_OUTEN, &outen); + + /* + * Avoid glitching the clock if GPRS is already using it. + * We can't actually read the state of the PLLPD so we infer it + * by the value of XTAL_PU which *is* readable via gpioin. + */ + if (on && (in & PCI_CFG_GPIO_XTAL)) + return 0; + + if (what & XTAL) + outen |= PCI_CFG_GPIO_XTAL; + if (what & PLL) + outen |= PCI_CFG_GPIO_PLL; + + if (on) { + /* turn primary xtal on */ + if (what & XTAL) { + out |= PCI_CFG_GPIO_XTAL; + if (what & PLL) + out |= PCI_CFG_GPIO_PLL; + pci_write_config_dword(sii->pbus, + PCI_GPIO_OUT, out); + pci_write_config_dword(sii->pbus, + PCI_GPIO_OUTEN, outen); + udelay(XTAL_ON_DELAY); + } + + /* turn pll on */ + if (what & PLL) { + out &= ~PCI_CFG_GPIO_PLL; + pci_write_config_dword(sii->pbus, + PCI_GPIO_OUT, out); + mdelay(2); + } + } else { + if (what & XTAL) + out &= ~PCI_CFG_GPIO_XTAL; + if (what & PLL) + out |= PCI_CFG_GPIO_PLL; + pci_write_config_dword(sii->pbus, + PCI_GPIO_OUT, out); + pci_write_config_dword(sii->pbus, + PCI_GPIO_OUTEN, outen); + } + + default: + return -1; + } + + return 0; +} + +/* + * clock control policy function throught chipcommon + * + * set dynamic clk control mode (forceslow, forcefast, dynamic) + * returns true if we are forcing fast clock + * this is a wrapper over the next internal function + * to allow flexible policy settings for outside caller + */ +bool si_clkctl_cc(si_t *sih, uint mode) +{ + si_info_t *sii; + + sii = SI_INFO(sih); + + /* chipcommon cores prior to rev6 don't support dynamic clock control */ + if (sih->ccrev < 6) + return false; + + if (PCI_FORCEHT(sii)) + return mode == CLK_FAST; + + return _si_clkctl_cc(sii, mode); +} + +/* clk control mechanism through chipcommon, no policy checking */ +static bool _si_clkctl_cc(si_info_t *sii, uint mode) +{ + uint origidx = 0; + chipcregs_t *cc; + u32 scc; + uint intr_val = 0; + bool fast = SI_FAST(sii); + + /* chipcommon cores prior to rev6 don't support dynamic clock control */ + if (sii->pub.ccrev < 6) + return false; + + /* + * Chips with ccrev 10 are EOL and they + * don't have SYCC_HR which we use below + */ + ASSERT(sii->pub.ccrev != 10); + + if (!fast) { + INTR_OFF(sii, intr_val); + origidx = sii->curidx; + + if ((sii->pub.bustype == SI_BUS) && + si_setcore(&sii->pub, MIPS33_CORE_ID, 0) && + (si_corerev(&sii->pub) <= 7) && (sii->pub.ccrev >= 10)) + goto done; + + cc = (chipcregs_t *) si_setcore(&sii->pub, CC_CORE_ID, 0); + } else { + cc = (chipcregs_t *) CCREGS_FAST(sii); + if (cc == NULL) + goto done; + } + ASSERT(cc != NULL); + + if (!CCCTL_ENAB(&sii->pub) && (sii->pub.ccrev < 20)) + goto done; + + switch (mode) { + case CLK_FAST: /* FORCEHT, fast (pll) clock */ + if (sii->pub.ccrev < 10) { + /* + * don't forget to force xtal back + * on before we clear SCC_DYN_XTAL.. + */ + si_clkctl_xtal(&sii->pub, XTAL, ON); + SET_REG(&cc->slow_clk_ctl, + (SCC_XC | SCC_FS | SCC_IP), SCC_IP); + } else if (sii->pub.ccrev < 20) { + OR_REG(&cc->system_clk_ctl, SYCC_HR); + } else { + OR_REG(&cc->clk_ctl_st, CCS_FORCEHT); + } + + /* wait for the PLL */ + if (PMUCTL_ENAB(&sii->pub)) { + u32 htavail = CCS_HTAVAIL; + SPINWAIT(((R_REG(&cc->clk_ctl_st) & htavail) + == 0), PMU_MAX_TRANSITION_DLY); + ASSERT(R_REG(&cc->clk_ctl_st) & htavail); + } else { + udelay(PLL_DELAY); + } + break; + + case CLK_DYNAMIC: /* enable dynamic clock control */ + if (sii->pub.ccrev < 10) { + scc = R_REG(&cc->slow_clk_ctl); + scc &= ~(SCC_FS | SCC_IP | SCC_XC); + if ((scc & SCC_SS_MASK) != SCC_SS_XTAL) + scc |= SCC_XC; + W_REG(&cc->slow_clk_ctl, scc); + + /* + * for dynamic control, we have to + * release our xtal_pu "force on" + */ + if (scc & SCC_XC) + si_clkctl_xtal(&sii->pub, XTAL, OFF); + } else if (sii->pub.ccrev < 20) { + /* Instaclock */ + AND_REG(&cc->system_clk_ctl, ~SYCC_HR); + } else { + AND_REG(&cc->clk_ctl_st, ~CCS_FORCEHT); + } + break; + + default: + ASSERT(0); + } + + done: + if (!fast) { + si_setcoreidx(&sii->pub, origidx); + INTR_RESTORE(sii, intr_val); + } + return mode == CLK_FAST; +} + +/* Build device path. Support SI, PCI, and JTAG for now. */ +int si_devpath(si_t *sih, char *path, int size) +{ + int slen; + + ASSERT(path != NULL); + ASSERT(size >= SI_DEVPATH_BUFSZ); + + if (!path || size <= 0) + return -1; + + switch (sih->bustype) { + case SI_BUS: + case JTAG_BUS: + slen = snprintf(path, (size_t) size, "sb/%u/", ai_coreidx(sih)); + break; + case PCI_BUS: + ASSERT((SI_INFO(sih))->pbus != NULL); + slen = snprintf(path, (size_t) size, "pci/%u/%u/", + ((struct pci_dev *)((SI_INFO(sih))->pbus))->bus->number, + PCI_SLOT( + ((struct pci_dev *)((SI_INFO(sih))->pbus))->devfn)); + break; + + default: + slen = -1; + ASSERT(0); + break; + } + + if (slen < 0 || slen >= size) { + path[0] = '\0'; + return -1; + } + + return 0; +} + +/* Get a variable, but only if it has a devpath prefix */ +char *si_getdevpathvar(si_t *sih, const char *name) +{ + char varname[SI_DEVPATH_BUFSZ + 32]; + + si_devpathvar(sih, varname, sizeof(varname), name); + + return getvar(NULL, varname); +} + +/* Get a variable, but only if it has a devpath prefix */ +int si_getdevpathintvar(si_t *sih, const char *name) +{ +#if defined(BCMBUSTYPE) && (BCMBUSTYPE == SI_BUS) + return getintvar(NULL, name); +#else + char varname[SI_DEVPATH_BUFSZ + 32]; + + si_devpathvar(sih, varname, sizeof(varname), name); + + return getintvar(NULL, varname); +#endif +} + +char *si_getnvramflvar(si_t *sih, const char *name) +{ + return getvar(NULL, name); +} + +/* Concatenate the dev path with a varname into the given 'var' buffer + * and return the 'var' pointer. Nothing is done to the arguments if + * len == 0 or var is NULL, var is still returned. On overflow, the + * first char will be set to '\0'. + */ +static char *si_devpathvar(si_t *sih, char *var, int len, const char *name) +{ + uint path_len; + + if (!var || len <= 0) + return var; + + if (si_devpath(sih, var, len) == 0) { + path_len = strlen(var); + + if (strlen(name) + 1 > (uint) (len - path_len)) + var[0] = '\0'; + else + strncpy(var + path_len, name, len - path_len - 1); + } + + return var; +} + +/* return true if PCIE capability exists in the pci config space */ +static __used bool si_ispcie(si_info_t *sii) +{ + u8 cap_ptr; + + if (sii->pub.bustype != PCI_BUS) + return false; + + cap_ptr = + pcicore_find_pci_capability(sii->pbus, PCI_CAP_PCIECAP_ID, NULL, + NULL); + if (!cap_ptr) + return false; + + return true; +} + +bool si_pci_war16165(si_t *sih) +{ + si_info_t *sii; + + sii = SI_INFO(sih); + + return PCI(sii) && (sih->buscorerev <= 10); +} + +void si_pci_up(si_t *sih) +{ + si_info_t *sii; + + sii = SI_INFO(sih); + + /* if not pci bus, we're done */ + if (sih->bustype != PCI_BUS) + return; + + if (PCI_FORCEHT(sii)) + _si_clkctl_cc(sii, CLK_FAST); + + if (PCIE(sii)) + pcicore_up(sii->pch, SI_PCIUP); + +} + +/* Unconfigure and/or apply various WARs when system is going to sleep mode */ +void si_pci_sleep(si_t *sih) +{ + si_info_t *sii; + + sii = SI_INFO(sih); + + pcicore_sleep(sii->pch); +} + +/* Unconfigure and/or apply various WARs when going down */ +void si_pci_down(si_t *sih) +{ + si_info_t *sii; + + sii = SI_INFO(sih); + + /* if not pci bus, we're done */ + if (sih->bustype != PCI_BUS) + return; + + /* release FORCEHT since chip is going to "down" state */ + if (PCI_FORCEHT(sii)) + _si_clkctl_cc(sii, CLK_DYNAMIC); + + pcicore_down(sii->pch, SI_PCIDOWN); +} + +/* + * Configure the pci core for pci client (NIC) action + * coremask is the bitvec of cores by index to be enabled. + */ +void si_pci_setup(si_t *sih, uint coremask) +{ + si_info_t *sii; + struct sbpciregs *pciregs = NULL; + u32 siflag = 0, w; + uint idx = 0; + + sii = SI_INFO(sih); + + if (sii->pub.bustype != PCI_BUS) + return; + + ASSERT(PCI(sii) || PCIE(sii)); + ASSERT(sii->pub.buscoreidx != BADIDX); + + if (PCI(sii)) { + /* get current core index */ + idx = sii->curidx; + + /* we interrupt on this backplane flag number */ + siflag = si_flag(sih); + + /* switch over to pci core */ + pciregs = si_setcoreidx(sih, sii->pub.buscoreidx); + } + + /* + * Enable sb->pci interrupts. Assume + * PCI rev 2.3 support was added in pci core rev 6 and things changed.. + */ + if (PCIE(sii) || (PCI(sii) && ((sii->pub.buscorerev) >= 6))) { + /* pci config write to set this core bit in PCIIntMask */ + pci_read_config_dword(sii->pbus, PCI_INT_MASK, &w); + w |= (coremask << PCI_SBIM_SHIFT); + pci_write_config_dword(sii->pbus, PCI_INT_MASK, w); + } else { + /* set sbintvec bit for our flag number */ + si_setint(sih, siflag); + } + + if (PCI(sii)) { + OR_REG(&pciregs->sbtopci2, + (SBTOPCI_PREF | SBTOPCI_BURST)); + if (sii->pub.buscorerev >= 11) { + OR_REG(&pciregs->sbtopci2, + SBTOPCI_RC_READMULTI); + w = R_REG(&pciregs->clkrun); + W_REG(&pciregs->clkrun, + (w | PCI_CLKRUN_DSBL)); + w = R_REG(&pciregs->clkrun); + } + + /* switch back to previous core */ + si_setcoreidx(sih, idx); + } +} + +/* + * Fixup SROMless PCI device's configuration. + * The current core may be changed upon return. + */ +int si_pci_fixcfg(si_t *sih) +{ + uint origidx, pciidx; + struct sbpciregs *pciregs = NULL; + sbpcieregs_t *pcieregs = NULL; + void *regs = NULL; + u16 val16, *reg16 = NULL; + + si_info_t *sii = SI_INFO(sih); + + ASSERT(sii->pub.bustype == PCI_BUS); + + /* Fixup PI in SROM shadow area to enable the correct PCI core access */ + /* save the current index */ + origidx = ai_coreidx(&sii->pub); + + /* check 'pi' is correct and fix it if not */ + if (sii->pub.buscoretype == PCIE_CORE_ID) { + pcieregs = si_setcore(&sii->pub, PCIE_CORE_ID, 0); + regs = pcieregs; + ASSERT(pcieregs != NULL); + reg16 = &pcieregs->sprom[SRSH_PI_OFFSET]; + } else if (sii->pub.buscoretype == PCI_CORE_ID) { + pciregs = si_setcore(&sii->pub, PCI_CORE_ID, 0); + regs = pciregs; + ASSERT(pciregs != NULL); + reg16 = &pciregs->sprom[SRSH_PI_OFFSET]; + } + pciidx = ai_coreidx(&sii->pub); + val16 = R_REG(reg16); + if (((val16 & SRSH_PI_MASK) >> SRSH_PI_SHIFT) != (u16) pciidx) { + val16 = + (u16) (pciidx << SRSH_PI_SHIFT) | (val16 & + ~SRSH_PI_MASK); + W_REG(reg16, val16); + } + + /* restore the original index */ + si_setcoreidx(&sii->pub, origidx); + + pcicore_hwup(sii->pch); + return 0; +} + +/* mask&set gpiocontrol bits */ +u32 si_gpiocontrol(si_t *sih, u32 mask, u32 val, u8 priority) +{ + uint regoff; + + regoff = 0; + + /* gpios could be shared on router platforms + * ignore reservation if it's high priority (e.g., test apps) + */ + if ((priority != GPIO_HI_PRIORITY) && + (sih->bustype == SI_BUS) && (val || mask)) { + mask = priority ? (si_gpioreservation & mask) : + ((si_gpioreservation | mask) & ~(si_gpioreservation)); + val &= mask; + } + + regoff = offsetof(chipcregs_t, gpiocontrol); + return si_corereg(sih, SI_CC_IDX, regoff, mask, val); +} + +void si_chipcontrl_epa4331(si_t *sih, bool on) +{ + si_info_t *sii; + chipcregs_t *cc; + uint origidx; + u32 val; + + sii = SI_INFO(sih); + origidx = ai_coreidx(sih); + + cc = (chipcregs_t *) si_setcore(sih, CC_CORE_ID, 0); + + val = R_REG(&cc->chipcontrol); + + if (on) { + if (sih->chippkg == 9 || sih->chippkg == 0xb) { + /* Ext PA Controls for 4331 12x9 Package */ + W_REG(&cc->chipcontrol, val | + (CCTRL4331_EXTPA_EN | + CCTRL4331_EXTPA_ON_GPIO2_5)); + } else { + /* Ext PA Controls for 4331 12x12 Package */ + W_REG(&cc->chipcontrol, + val | (CCTRL4331_EXTPA_EN)); + } + } else { + val &= ~(CCTRL4331_EXTPA_EN | CCTRL4331_EXTPA_ON_GPIO2_5); + W_REG(&cc->chipcontrol, val); + } + + si_setcoreidx(sih, origidx); +} + +/* Enable BT-COEX & Ex-PA for 4313 */ +void si_epa_4313war(si_t *sih) +{ + si_info_t *sii; + chipcregs_t *cc; + uint origidx; + + sii = SI_INFO(sih); + origidx = ai_coreidx(sih); + + cc = (chipcregs_t *) si_setcore(sih, CC_CORE_ID, 0); + + /* EPA Fix */ + W_REG(&cc->gpiocontrol, + R_REG(&cc->gpiocontrol) | GPIO_CTRL_EPA_EN_MASK); + + si_setcoreidx(sih, origidx); +} + +/* check if the device is removed */ +bool si_deviceremoved(si_t *sih) +{ + u32 w; + si_info_t *sii; + + sii = SI_INFO(sih); + + switch (sih->bustype) { + case PCI_BUS: + ASSERT(sii->pbus != NULL); + pci_read_config_dword(sii->pbus, PCI_CFG_VID, &w); + if ((w & 0xFFFF) != PCI_VENDOR_ID_BROADCOM) + return true; + break; + } + return false; +} + +bool si_is_sprom_available(si_t *sih) +{ + if (sih->ccrev >= 31) { + si_info_t *sii; + uint origidx; + chipcregs_t *cc; + u32 sromctrl; + + if ((sih->cccaps & CC_CAP_SROM) == 0) + return false; + + sii = SI_INFO(sih); + origidx = sii->curidx; + cc = si_setcoreidx(sih, SI_CC_IDX); + sromctrl = R_REG(&cc->sromcontrol); + si_setcoreidx(sih, origidx); + return sromctrl & SRC_PRESENT; + } + + switch (sih->chip) { + case BCM4329_CHIP_ID: + return (sih->chipst & CST4329_SPROM_SEL) != 0; + case BCM4319_CHIP_ID: + return (sih->chipst & CST4319_SPROM_SEL) != 0; + case BCM4336_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: + return (sih->chipst & CST4331_SPROM_PRESENT) != 0; + default: + return true; + } +} + +bool si_is_otp_disabled(si_t *sih) +{ + switch (sih->chip) { + case BCM4329_CHIP_ID: + return (sih->chipst & CST4329_SPROM_OTP_SEL_MASK) == + CST4329_OTP_PWRDN; + case BCM4319_CHIP_ID: + return (sih->chipst & CST4319_SPROM_OTP_SEL_MASK) == + CST4319_OTP_PWRDN; + case BCM4336_CHIP_ID: + return (sih->chipst & CST4336_OTP_PRESENT) == 0; + case BCM4330_CHIP_ID: + return (sih->chipst & CST4330_OTP_PRESENT) == 0; + case BCM4313_CHIP_ID: + return (sih->chipst & CST4313_OTP_PRESENT) == 0; + /* These chips always have their OTP on */ + case BCM43224_CHIP_ID: + case BCM43225_CHIP_ID: + case BCM43421_CHIP_ID: + case BCM43235_CHIP_ID: + case BCM43236_CHIP_ID: + case BCM43238_CHIP_ID: + case BCM4331_CHIP_ID: + default: + return false; + } +} + +bool si_is_otp_powered(si_t *sih) +{ + if (PMUCTL_ENAB(sih)) + return si_pmu_is_otp_powered(sih); + return true; +} + +void si_otp_power(si_t *sih, bool on) +{ + if (PMUCTL_ENAB(sih)) + si_pmu_otp_power(sih, on); + udelay(1000); +} + diff --git a/drivers/staging/brcm80211/util/bcmotp.c b/drivers/staging/brcm80211/util/bcmotp.c index 41c9c43..37b08b1 100644 --- a/drivers/staging/brcm80211/util/bcmotp.c +++ b/drivers/staging/brcm80211/util/bcmotp.c @@ -17,16 +17,16 @@ #include <linux/delay.h> #include <linux/kernel.h> #include <linux/string.h> -#include <bcmdefs.h> #include <linux/module.h> #include <linux/pci.h> + +#include <bcmdefs.h> #include <bcmdevs.h> #include <bcmutils.h> -#include <siutils.h> +#include <aiutils.h> #include <hndsoc.h> #include <sbchipc.h> #include <bcmotp.h> -#include "siutils_priv.h" /* * There are two different OTP controllers so far: @@ -360,7 +360,7 @@ static void *ipxotp_init(si_t *sih) } /* Retrieve OTP region info */ - idx = si_coreidx(sih); + idx = ai_coreidx(sih); cc = si_setcoreidx(sih, SI_CC_IDX); ASSERT(cc != NULL); @@ -444,7 +444,7 @@ static int ipxotp_read_region(void *oh, int region, u16 *data, uint *wlen) return -BCME_BADARG; } - idx = si_coreidx(oi->sih); + idx = ai_coreidx(oi->sih); cc = si_setcoreidx(oi->sih, SI_CC_IDX); ASSERT(cc != NULL); @@ -631,7 +631,7 @@ static void *hndotp_init(si_t *sih) oi = &otpinfo; - idx = si_coreidx(sih); + idx = ai_coreidx(sih); /* Check for otp */ cc = si_setcoreidx(sih, SI_CC_IDX); @@ -713,7 +713,7 @@ static int hndotp_read_region(void *oh, int region, u16 *data, uint *wlen) *wlen = ((int)*wlen < oi->boundary / 2) ? *wlen : (uint) oi->boundary / 2; - idx = si_coreidx(oi->sih); + idx = ai_coreidx(oi->sih); cc = si_setcoreidx(oi->sih, SI_CC_IDX); ASSERT(cc != NULL); @@ -737,7 +737,7 @@ static int hndotp_nvread(void *oh, char *data, uint *len) u16 *rawotp = NULL; /* save the orig core */ - idx = si_coreidx(oi->sih); + idx = ai_coreidx(oi->sih); cc = si_setcoreidx(oi->sih, SI_CC_IDX); ASSERT(cc != NULL); @@ -876,7 +876,7 @@ int otp_size(void *oh) u16 otp_read_bit(void *oh, uint offset) { otpinfo_t *oi = (otpinfo_t *) oh; - uint idx = si_coreidx(oi->sih); + uint idx = ai_coreidx(oi->sih); chipcregs_t *cc = si_setcoreidx(oi->sih, SI_CC_IDX); u16 readBit = (u16) oi->fn->read_bit(oh, cc, offset); si_setcoreidx(oi->sih, idx); diff --git a/drivers/staging/brcm80211/util/siutils.c b/drivers/staging/brcm80211/util/siutils.c index e88a7bb..8ff0722 100644 --- a/drivers/staging/brcm80211/util/siutils.c +++ b/drivers/staging/brcm80211/util/siutils.c @@ -32,26 +32,18 @@ #include <bcmsrom.h> #include <pcicfg.h> #include <sbsocram.h> -#ifdef BCMSDIO #include <bcmsdh.h> #include <sdio.h> #include <sbsdio.h> #include <sbhnddma.h> #include <sbsdpcmdev.h> #include <bcmsdpcm.h> -#endif /* BCMSDIO */ #include <hndpmu.h> /* this file now contains only definitions for sb functions, only necessary *for devices using Sonics backplanes (bcm4329) */ - -/* if an amba SDIO device is supported, please further restrict the inclusion - * of this file - */ -#ifdef BCMSDIO #include "siutils_priv.h" -#endif /* local prototypes */ static si_info_t *si_doattach(si_info_t *sii, uint devid, void *regs, @@ -112,13 +104,6 @@ static bool si_buscore_prep(si_info_t *sii, uint bustype, uint devid, void *sdh) { -#ifndef BRCM_FULLMAC - /* kludge to enable the clock on the 4306 which lacks a slowclock */ - if (bustype == PCI_BUS && !si_ispcie(sii)) - si_clkctl_xtal(&sii->pub, XTAL | PLL, ON); -#endif - -#if defined(BCMSDIO) if (bustype == SDIO_BUS) { int err; u8 clkset; @@ -159,7 +144,6 @@ static bool si_buscore_prep(si_info_t *sii, uint bustype, uint devid, bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_SDIOPULLUP, 0, NULL); } -#endif /* defined(BCMSDIO) */ return true; } @@ -185,10 +169,6 @@ static bool si_buscore_setup(si_info_t *sii, chipcregs_t *cc, uint bustype, sii->pub.cccaps = R_REG(&cc->capabilities); /* get chipcommon extended capabilities */ -#ifndef BRCM_FULLMAC - if (sii->pub.ccrev >= 35) - sii->pub.cccaps_ext = R_REG(&cc->capabilities_ext); -#endif /* get pmu rev and caps */ if (sii->pub.cccaps & CC_CAP_PMU) { sii->pub.pmucaps = R_REG(&cc->pmucapabilities); @@ -232,7 +212,6 @@ static bool si_buscore_setup(si_info_t *sii, chipcregs_t *cc, uint bustype, pcie = true; } } -#ifdef BCMSDIO else if (((bustype == SDIO_BUS) || (bustype == SPI_BUS)) && ((cid == PCMCIA_CORE_ID) || (cid == SDIOD_CORE_ID))) { @@ -240,7 +219,6 @@ static bool si_buscore_setup(si_info_t *sii, chipcregs_t *cc, uint bustype, sii->pub.buscoretype = cid; sii->pub.buscoreidx = i; } -#endif /* BCMSDIO */ /* find the core idx before entering this func. */ if ((savewin && (savewin == sii->coresba[i])) || @@ -248,7 +226,6 @@ static bool si_buscore_setup(si_info_t *sii, chipcregs_t *cc, uint bustype, *origidx = i; } -#ifdef BRCM_FULLMAC SI_MSG(("Buscore id/type/rev %d/0x%x/%d\n", sii->pub.buscoreidx, sii->pub.buscoretype, sii->pub.buscorerev)); @@ -261,43 +238,6 @@ static bool si_buscore_setup(si_info_t *sii, chipcregs_t *cc, uint bustype, si_setcore(&sii->pub, ARMCM3_CORE_ID, 0)) si_core_disable(&sii->pub, 0); } -#else - if (pci && pcie) { - if (si_ispcie(sii)) - pci = false; - else - pcie = false; - } - if (pci) { - sii->pub.buscoretype = PCI_CORE_ID; - sii->pub.buscorerev = pcirev; - sii->pub.buscoreidx = pciidx; - } else if (pcie) { - sii->pub.buscoretype = PCIE_CORE_ID; - sii->pub.buscorerev = pcierev; - sii->pub.buscoreidx = pcieidx; - } - - SI_VMSG(("Buscore id/type/rev %d/0x%x/%d\n", sii->pub.buscoreidx, - sii->pub.buscoretype, sii->pub.buscorerev)); - - /* fixup necessary chip/core configurations */ - if (sii->pub.bustype == PCI_BUS) { - if (SI_FAST(sii)) { - if (!sii->pch) { - sii->pch = (void *)pcicore_init( - &sii->pub, sii->pbus, - (void *)PCIEREGS(sii)); - if (sii->pch == NULL) - return false; - } - } - if (si_pci_fixcfg(&sii->pub)) { - SI_ERROR(("si_doattach: sb_pci_fixcfg failed\n")); - return false; - } - } -#endif /* return to the original core */ si_setcoreidx(&sii->pub, *origidx); @@ -328,19 +268,15 @@ static __used void si_nvram_process(si_info_t *sii, char *pvars) SI_ERROR(("Overriding boardtype: 0x%x instead of 0x%x\n", sii->pub.boardtype, (w >> 16) & 0xffff)); break; -#ifdef BCMSDIO case SDIO_BUS: -#endif sii->pub.boardvendor = getintvar(pvars, "manfid"); sii->pub.boardtype = getintvar(pvars, "prodid"); break; -#ifdef BCMSDIO case SPI_BUS: sii->pub.boardvendor = PCI_VENDOR_ID_BROADCOM; sii->pub.boardtype = SPI_BOARD; break; -#endif case SI_BUS: case JTAG_BUS: @@ -364,7 +300,6 @@ static __used void si_nvram_process(si_info_t *sii, char *pvars) /* this is will make Sonics calls directly, since Sonics is no longer supported in the Si abstraction */ /* this has been customized for the bcm 4329 ONLY */ -#ifdef BRCM_FULLMAC static si_info_t *si_doattach(si_info_t *sii, uint devid, void *regs, uint bustype, void *pbus, char **vars, uint *varsz) @@ -440,199 +375,6 @@ static si_info_t *si_doattach(si_info_t *sii, uint devid, exit: return NULL; } -#else /* BRCM_FULLMAC */ -static si_info_t *si_doattach(si_info_t *sii, uint devid, - void *regs, uint bustype, void *pbus, - char **vars, uint *varsz) -{ - struct si_pub *sih = &sii->pub; - u32 w, savewin; - chipcregs_t *cc; - char *pvars = NULL; - uint origidx; - - ASSERT(GOODREGS(regs)); - - memset((unsigned char *) sii, 0, sizeof(si_info_t)); - - savewin = 0; - - sih->buscoreidx = BADIDX; - - sii->curmap = regs; - sii->pbus = pbus; - - /* check to see if we are a si core mimic'ing a pci core */ - if (bustype == PCI_BUS) { - pci_read_config_dword(sii->pbus, PCI_SPROM_CONTROL, &w); - if (w == 0xffffffff) { - SI_ERROR(("%s: incoming bus is PCI but it's a lie, " - " switching to SI devid:0x%x\n", - __func__, devid)); - bustype = SI_BUS; - } - } - - /* find Chipcommon address */ - if (bustype == PCI_BUS) { - pci_read_config_dword(sii->pbus, PCI_BAR0_WIN, &savewin); - if (!GOODCOREADDR(savewin, SI_ENUM_BASE)) - savewin = SI_ENUM_BASE; - pci_write_config_dword(sii->pbus, PCI_BAR0_WIN, - SI_ENUM_BASE); - cc = (chipcregs_t *) regs; - } else { - cc = (chipcregs_t *) REG_MAP(SI_ENUM_BASE, SI_CORE_SIZE); - } - - sih->bustype = bustype; - - /* bus/core/clk setup for register access */ - if (!si_buscore_prep(sii, bustype, devid, pbus)) { - SI_ERROR(("si_doattach: si_core_clk_prep failed %d\n", - bustype)); - return NULL; - } - - /* ChipID recognition. - * We assume we can read chipid at offset 0 from the regs arg. - * If we add other chiptypes (or if we need to support old sdio hosts w/o chipcommon), - * some way of recognizing them needs to be added here. - */ - w = R_REG(&cc->chipid); - sih->socitype = (w & CID_TYPE_MASK) >> CID_TYPE_SHIFT; - /* Might as wll fill in chip id rev & pkg */ - sih->chip = w & CID_ID_MASK; - sih->chiprev = (w & CID_REV_MASK) >> CID_REV_SHIFT; - sih->chippkg = (w & CID_PKG_MASK) >> CID_PKG_SHIFT; - - sih->issim = IS_SIM(sih->chippkg); - - /* scan for cores */ - if (sii->pub.socitype == SOCI_AI) { - SI_MSG(("Found chip type AI (0x%08x)\n", w)); - /* pass chipc address instead of original core base */ - ai_scan(&sii->pub, (void *)cc, devid); - } else { - SI_ERROR(("Found chip of unknown type (0x%08x)\n", w)); - return NULL; - } - /* no cores found, bail out */ - if (sii->numcores == 0) { - SI_ERROR(("si_doattach: could not find any cores\n")); - return NULL; - } - /* bus/core/clk setup */ - origidx = SI_CC_IDX; - if (!si_buscore_setup(sii, cc, bustype, savewin, &origidx, regs)) { - SI_ERROR(("si_doattach: si_buscore_setup failed\n")); - goto exit; - } - - /* assume current core is CC */ - if ((sii->pub.ccrev == 0x25) - && - ((sih->chip == BCM43236_CHIP_ID - || sih->chip == BCM43235_CHIP_ID - || sih->chip == BCM43238_CHIP_ID) - && (sii->pub.chiprev <= 2))) { - - if ((cc->chipstatus & CST43236_BP_CLK) != 0) { - uint clkdiv; - clkdiv = R_REG(&cc->clkdiv); - /* otp_clk_div is even number, 120/14 < 9mhz */ - clkdiv = (clkdiv & ~CLKD_OTP) | (14 << CLKD_OTP_SHIFT); - W_REG(&cc->clkdiv, clkdiv); - SI_ERROR(("%s: set clkdiv to %x\n", __func__, clkdiv)); - } - udelay(10); - } - - /* Init nvram from flash if it exists */ - nvram_init((void *)&(sii->pub)); - - /* Init nvram from sprom/otp if they exist */ - if (srom_var_init - (&sii->pub, bustype, regs, vars, varsz)) { - SI_ERROR(("si_doattach: srom_var_init failed: bad srom\n")); - goto exit; - } - pvars = vars ? *vars : NULL; - si_nvram_process(sii, pvars); - - /* === NVRAM, clock is ready === */ - cc = (chipcregs_t *) si_setcore(sih, CC_CORE_ID, 0); - W_REG(&cc->gpiopullup, 0); - W_REG(&cc->gpiopulldown, 0); - si_setcoreidx(sih, origidx); - - /* PMU specific initializations */ - if (PMUCTL_ENAB(sih)) { - u32 xtalfreq; - si_pmu_init(sih); - si_pmu_chip_init(sih); - xtalfreq = getintvar(pvars, "xtalfreq"); - /* If xtalfreq var not available, try to measure it */ - if (xtalfreq == 0) - xtalfreq = si_pmu_measure_alpclk(sih); - si_pmu_pll_init(sih, xtalfreq); - si_pmu_res_init(sih); - si_pmu_swreg_init(sih); - } - - /* setup the GPIO based LED powersave register */ - w = getintvar(pvars, "leddc"); - if (w == 0) - w = DEFAULT_GPIOTIMERVAL; - si_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, gpiotimerval), ~0, w); - - if (PCIE(sii)) { - ASSERT(sii->pch != NULL); - pcicore_attach(sii->pch, pvars, SI_DOATTACH); - } - - if ((sih->chip == BCM43224_CHIP_ID) || - (sih->chip == BCM43421_CHIP_ID)) { - /* enable 12 mA drive strenth for 43224 and set chipControl register bit 15 */ - if (sih->chiprev == 0) { - SI_MSG(("Applying 43224A0 WARs\n")); - si_corereg(sih, SI_CC_IDX, - offsetof(chipcregs_t, chipcontrol), - CCTRL43224_GPIO_TOGGLE, - CCTRL43224_GPIO_TOGGLE); - si_pmu_chipcontrol(sih, 0, CCTRL_43224A0_12MA_LED_DRIVE, - CCTRL_43224A0_12MA_LED_DRIVE); - } - if (sih->chiprev >= 1) { - SI_MSG(("Applying 43224B0+ WARs\n")); - si_pmu_chipcontrol(sih, 0, CCTRL_43224B0_12MA_LED_DRIVE, - CCTRL_43224B0_12MA_LED_DRIVE); - } - } - - if (sih->chip == BCM4313_CHIP_ID) { - /* enable 12 mA drive strenth for 4313 and set chipControl register bit 1 */ - SI_MSG(("Applying 4313 WARs\n")); - si_pmu_chipcontrol(sih, 0, CCTRL_4313_12MA_LED_DRIVE, - CCTRL_4313_12MA_LED_DRIVE); - } - - if (sih->chip == BCM4331_CHIP_ID) { - /* Enable Ext PA lines depending on chip package option */ - si_chipcontrl_epa4331(sih, true); - } - - return sii; - exit: - if (sih->bustype == PCI_BUS) { - if (sii->pch) - pcicore_deinit(sii->pch); - sii->pch = NULL; - } - - return NULL; -} -#endif /* BRCM_FULLMAC */ /* may be called with core in reset */ void si_detach(si_t *sih) @@ -655,15 +397,6 @@ void si_detach(si_t *sih) sii->regs[idx] = NULL; } -#ifndef BRCM_FULLMAC - nvram_exit((void *)si_local); /* free up nvram buffers */ - - if (sih->bustype == PCI_BUS) { - if (sii->pch) - pcicore_deinit(sii->pch); - sii->pch = NULL; - } -#endif #if !defined(BCMBUSTYPE) || (BCMBUSTYPE == SI_BUS) if (sii != &ksii) #endif /* !BCMBUSTYPE || (BCMBUSTYPE == SI_BUS) */ @@ -698,32 +431,15 @@ void si_deregister_intr_callback(si_t *sih) uint si_flag(si_t *sih) { - if (sih->socitype == SOCI_AI) - return ai_flag(sih); - else { - ASSERT(0); - return 0; - } + ASSERT(0); + return 0; } void si_setint(si_t *sih, int siflag) { - if (sih->socitype == SOCI_AI) - ai_setint(sih, siflag); - else - ASSERT(0); + ASSERT(0); } -#ifndef BCMSDIO -uint si_coreid(si_t *sih) -{ - si_info_t *sii; - - sii = SI_INFO(sih); - return sii->coreid[sii->curidx]; -} -#endif - uint si_coreidx(si_t *sih) { si_info_t *sii; @@ -737,18 +453,6 @@ bool si_backplane64(si_t *sih) return (sih->cccaps & CC_CAP_BKPLN64) != 0; } -#ifndef BCMSDIO -uint si_corerev(si_t *sih) -{ - if (sih->socitype == SOCI_AI) - return ai_corerev(sih); - else { - ASSERT(0); - return 0; - } -} -#endif - /* return index of coreid or BADIDX if not found */ uint si_findcoreidx(si_t *sih, uint coreid, uint coreunit) { @@ -783,30 +487,9 @@ void *si_setcore(si_t *sih, uint coreid, uint coreunit) if (!GOODIDX(idx)) return NULL; - if (sih->socitype == SOCI_AI) - return ai_setcoreidx(sih, idx); - else { -#ifdef BCMSDIO - return sb_setcoreidx(sih, idx); -#else - ASSERT(0); - return NULL; -#endif - } + return sb_setcoreidx(sih, idx); } -#ifndef BCMSDIO -void *si_setcoreidx(si_t *sih, uint coreidx) -{ - if (sih->socitype == SOCI_AI) - return ai_setcoreidx(sih, coreidx); - else { - ASSERT(0); - return NULL; - } -} -#endif - /* Turn off interrupt as required by sb_setcore, before switch core */ void *si_switch_core(si_t *sih, uint coreid, uint *origidx, uint *intr_val) { @@ -850,80 +533,38 @@ void si_restore_core(si_t *sih, uint coreid, uint intr_val) u32 si_core_cflags(si_t *sih, u32 mask, u32 val) { - if (sih->socitype == SOCI_AI) - return ai_core_cflags(sih, mask, val); - else { - ASSERT(0); - return 0; - } + ASSERT(0); + return 0; } u32 si_core_sflags(si_t *sih, u32 mask, u32 val) { - if (sih->socitype == SOCI_AI) - return ai_core_sflags(sih, mask, val); - else { - ASSERT(0); - return 0; - } + ASSERT(0); + return 0; } bool si_iscoreup(si_t *sih) { - if (sih->socitype == SOCI_AI) - return ai_iscoreup(sih); - else { -#ifdef BCMSDIO - return sb_iscoreup(sih); -#else - ASSERT(0); - return false; -#endif - } + return sb_iscoreup(sih); } void si_write_wrapperreg(si_t *sih, u32 offset, u32 val) { - /* only for 4319, no requirement for SOCI_SB */ - if (sih->socitype == SOCI_AI) { - ai_write_wrap_reg(sih, offset, val); - } } uint si_corereg(si_t *sih, uint coreidx, uint regoff, uint mask, uint val) { - - if (sih->socitype == SOCI_AI) - return ai_corereg(sih, coreidx, regoff, mask, val); - else { -#ifdef BCMSDIO - return sb_corereg(sih, coreidx, regoff, mask, val); -#else - ASSERT(0); - return 0; -#endif - } + return sb_corereg(sih, coreidx, regoff, mask, val); } void si_core_disable(si_t *sih, u32 bits) { - - if (sih->socitype == SOCI_AI) - ai_core_disable(sih, bits); -#ifdef BCMSDIO - else - sb_core_disable(sih, bits); -#endif + sb_core_disable(sih, bits); } void si_core_reset(si_t *sih, u32 bits, u32 resetbits) { - if (sih->socitype == SOCI_AI) - ai_core_reset(sih, bits, resetbits); -#ifdef BCMSDIO - else - sb_core_reset(sih, bits, resetbits); -#endif + sb_core_reset(sih, bits, resetbits); } u32 si_alp_clock(si_t *sih) @@ -943,7 +584,6 @@ u32 si_ilp_clock(si_t *sih) } /* set chip watchdog reset timer to fire in 'ticks' */ -#ifdef BRCM_FULLMAC void si_watchdog(si_t *sih, uint ticks) { @@ -968,50 +608,6 @@ si_watchdog(si_t *sih, uint ticks) ~0, ticks); } } -#else -void si_watchdog(si_t *sih, uint ticks) -{ - uint nb, maxt; - - if (PMUCTL_ENAB(sih)) { - - if ((sih->chip == BCM4319_CHIP_ID) && - (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); - } - - nb = (sih->ccrev < 26) ? 16 : ((sih->ccrev >= 37) ? 32 : 24); - /* The mips compiler uses the sllv instruction, - * so we specially handle the 32-bit case. - */ - if (nb == 32) - maxt = 0xffffffff; - else - maxt = ((1 << nb) - 1); - - if (ticks == 1) - ticks = 2; - else if (ticks > maxt) - ticks = maxt; - - si_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, pmuwatchdog), - ~0, ticks); - } else { - /* make sure we come up in fast clock mode; or if clearing, clear clock */ - si_clkctl_cc(sih, ticks ? CLK_FAST : CLK_DYNAMIC); - maxt = (1 << 28) - 1; - if (ticks > maxt) - ticks = maxt; - - si_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, watchdog), ~0, - ticks); - } -} -#endif /* return the slow clock source - LPO, XTAL, or PCI */ static uint si_slowclk_src(si_info_t *sii) @@ -1200,10 +796,8 @@ int si_clkctl_xtal(si_t *sih, uint what, bool on) switch (sih->bustype) { -#ifdef BCMSDIO case SDIO_BUS: return -1; -#endif /* BCMSDIO */ case PCI_BUS: /* pcie core doesn't have any mapping to control the xtal pu */ @@ -1404,12 +998,11 @@ int si_devpath(si_t *sih, char *path, int size) ((struct pci_dev *)((SI_INFO(sih))->pbus))->devfn)); break; -#ifdef BCMSDIO case SDIO_BUS: SI_ERROR(("si_devpath: device 0 assumed\n")); slen = snprintf(path, (size_t) size, "sd/%u/", si_coreidx(sih)); break; -#endif + default: slen = -1; ASSERT(0); @@ -1494,7 +1087,6 @@ static __used bool si_ispcie(si_info_t *sii) return true; } -#ifdef BCMSDIO /* initialize the sdio core */ void si_sdio_init(si_t *sih) { @@ -1531,7 +1123,6 @@ void si_sdio_init(si_t *sih) bcmsdh_intr_enable(sii->pbus); } -#endif /* BCMSDIO */ bool si_pci_war16165(si_t *sih) { -- 1.7.1 _______________________________________________ devel mailing list devel@xxxxxxxxxxxxxxxxxxxxxx http://driverdev.linuxdriverproject.org/mailman/listinfo/devel