162306a36Sopenharmony_ci/* 262306a36Sopenharmony_ci * Copyright (c) 2010 Broadcom Corporation 362306a36Sopenharmony_ci * 462306a36Sopenharmony_ci * Permission to use, copy, modify, and/or distribute this software for any 562306a36Sopenharmony_ci * purpose with or without fee is hereby granted, provided that the above 662306a36Sopenharmony_ci * copyright notice and this permission notice appear in all copies. 762306a36Sopenharmony_ci * 862306a36Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 962306a36Sopenharmony_ci * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 1062306a36Sopenharmony_ci * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 1162306a36Sopenharmony_ci * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 1262306a36Sopenharmony_ci * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION 1362306a36Sopenharmony_ci * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 1462306a36Sopenharmony_ci * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 1562306a36Sopenharmony_ci * 1662306a36Sopenharmony_ci * File contents: support functions for PCI/PCIe 1762306a36Sopenharmony_ci */ 1862306a36Sopenharmony_ci 1962306a36Sopenharmony_ci#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 2062306a36Sopenharmony_ci 2162306a36Sopenharmony_ci#include <linux/delay.h> 2262306a36Sopenharmony_ci 2362306a36Sopenharmony_ci#include <defs.h> 2462306a36Sopenharmony_ci#include <chipcommon.h> 2562306a36Sopenharmony_ci#include <brcmu_utils.h> 2662306a36Sopenharmony_ci#include <brcm_hw_ids.h> 2762306a36Sopenharmony_ci#include <soc.h> 2862306a36Sopenharmony_ci#include "types.h" 2962306a36Sopenharmony_ci#include "pub.h" 3062306a36Sopenharmony_ci#include "pmu.h" 3162306a36Sopenharmony_ci#include "aiutils.h" 3262306a36Sopenharmony_ci 3362306a36Sopenharmony_ci/* slow_clk_ctl */ 3462306a36Sopenharmony_ci /* slow clock source mask */ 3562306a36Sopenharmony_ci#define SCC_SS_MASK 0x00000007 3662306a36Sopenharmony_ci /* source of slow clock is LPO */ 3762306a36Sopenharmony_ci#define SCC_SS_LPO 0x00000000 3862306a36Sopenharmony_ci /* source of slow clock is crystal */ 3962306a36Sopenharmony_ci#define SCC_SS_XTAL 0x00000001 4062306a36Sopenharmony_ci /* source of slow clock is PCI */ 4162306a36Sopenharmony_ci#define SCC_SS_PCI 0x00000002 4262306a36Sopenharmony_ci /* LPOFreqSel, 1: 160Khz, 0: 32KHz */ 4362306a36Sopenharmony_ci#define SCC_LF 0x00000200 4462306a36Sopenharmony_ci /* LPOPowerDown, 1: LPO is disabled, 0: LPO is enabled */ 4562306a36Sopenharmony_ci#define SCC_LP 0x00000400 4662306a36Sopenharmony_ci /* ForceSlowClk, 1: sb/cores running on slow clock, 0: power logic control */ 4762306a36Sopenharmony_ci#define SCC_FS 0x00000800 4862306a36Sopenharmony_ci /* IgnorePllOffReq, 1/0: 4962306a36Sopenharmony_ci * power logic ignores/honors PLL clock disable requests from core 5062306a36Sopenharmony_ci */ 5162306a36Sopenharmony_ci#define SCC_IP 0x00001000 5262306a36Sopenharmony_ci /* XtalControlEn, 1/0: 5362306a36Sopenharmony_ci * power logic does/doesn't disable crystal when appropriate 5462306a36Sopenharmony_ci */ 5562306a36Sopenharmony_ci#define SCC_XC 0x00002000 5662306a36Sopenharmony_ci /* XtalPU (RO), 1/0: crystal running/disabled */ 5762306a36Sopenharmony_ci#define SCC_XP 0x00004000 5862306a36Sopenharmony_ci /* ClockDivider (SlowClk = 1/(4+divisor)) */ 5962306a36Sopenharmony_ci#define SCC_CD_MASK 0xffff0000 6062306a36Sopenharmony_ci#define SCC_CD_SHIFT 16 6162306a36Sopenharmony_ci 6262306a36Sopenharmony_ci/* system_clk_ctl */ 6362306a36Sopenharmony_ci /* ILPen: Enable Idle Low Power */ 6462306a36Sopenharmony_ci#define SYCC_IE 0x00000001 6562306a36Sopenharmony_ci /* ALPen: Enable Active Low Power */ 6662306a36Sopenharmony_ci#define SYCC_AE 0x00000002 6762306a36Sopenharmony_ci /* ForcePLLOn */ 6862306a36Sopenharmony_ci#define SYCC_FP 0x00000004 6962306a36Sopenharmony_ci /* Force ALP (or HT if ALPen is not set */ 7062306a36Sopenharmony_ci#define SYCC_AR 0x00000008 7162306a36Sopenharmony_ci /* Force HT */ 7262306a36Sopenharmony_ci#define SYCC_HR 0x00000010 7362306a36Sopenharmony_ci /* ClkDiv (ILP = 1/(4 * (divisor + 1)) */ 7462306a36Sopenharmony_ci#define SYCC_CD_MASK 0xffff0000 7562306a36Sopenharmony_ci#define SYCC_CD_SHIFT 16 7662306a36Sopenharmony_ci 7762306a36Sopenharmony_ci#define CST4329_SPROM_OTP_SEL_MASK 0x00000003 7862306a36Sopenharmony_ci /* OTP is powered up, use def. CIS, no SPROM */ 7962306a36Sopenharmony_ci#define CST4329_DEFCIS_SEL 0 8062306a36Sopenharmony_ci /* OTP is powered up, SPROM is present */ 8162306a36Sopenharmony_ci#define CST4329_SPROM_SEL 1 8262306a36Sopenharmony_ci /* OTP is powered up, no SPROM */ 8362306a36Sopenharmony_ci#define CST4329_OTP_SEL 2 8462306a36Sopenharmony_ci /* OTP is powered down, SPROM is present */ 8562306a36Sopenharmony_ci#define CST4329_OTP_PWRDN 3 8662306a36Sopenharmony_ci 8762306a36Sopenharmony_ci#define CST4329_SPI_SDIO_MODE_MASK 0x00000004 8862306a36Sopenharmony_ci#define CST4329_SPI_SDIO_MODE_SHIFT 2 8962306a36Sopenharmony_ci 9062306a36Sopenharmony_ci/* 43224 chip-specific ChipControl register bits */ 9162306a36Sopenharmony_ci#define CCTRL43224_GPIO_TOGGLE 0x8000 9262306a36Sopenharmony_ci /* 12 mA drive strength */ 9362306a36Sopenharmony_ci#define CCTRL_43224A0_12MA_LED_DRIVE 0x00F000F0 9462306a36Sopenharmony_ci /* 12 mA drive strength for later 43224s */ 9562306a36Sopenharmony_ci#define CCTRL_43224B0_12MA_LED_DRIVE 0xF0 9662306a36Sopenharmony_ci 9762306a36Sopenharmony_ci/* 43236 Chip specific ChipStatus register bits */ 9862306a36Sopenharmony_ci#define CST43236_SFLASH_MASK 0x00000040 9962306a36Sopenharmony_ci#define CST43236_OTP_MASK 0x00000080 10062306a36Sopenharmony_ci#define CST43236_HSIC_MASK 0x00000100 /* USB/HSIC */ 10162306a36Sopenharmony_ci#define CST43236_BP_CLK 0x00000200 /* 120/96Mbps */ 10262306a36Sopenharmony_ci#define CST43236_BOOT_MASK 0x00001800 10362306a36Sopenharmony_ci#define CST43236_BOOT_SHIFT 11 10462306a36Sopenharmony_ci#define CST43236_BOOT_FROM_SRAM 0 /* boot from SRAM, ARM in reset */ 10562306a36Sopenharmony_ci#define CST43236_BOOT_FROM_ROM 1 /* boot from ROM */ 10662306a36Sopenharmony_ci#define CST43236_BOOT_FROM_FLASH 2 /* boot from FLASH */ 10762306a36Sopenharmony_ci#define CST43236_BOOT_FROM_INVALID 3 10862306a36Sopenharmony_ci 10962306a36Sopenharmony_ci/* 4331 chip-specific ChipControl register bits */ 11062306a36Sopenharmony_ci /* 0 disable */ 11162306a36Sopenharmony_ci#define CCTRL4331_BT_COEXIST (1<<0) 11262306a36Sopenharmony_ci /* 0 SECI is disabled (JTAG functional) */ 11362306a36Sopenharmony_ci#define CCTRL4331_SECI (1<<1) 11462306a36Sopenharmony_ci /* 0 disable */ 11562306a36Sopenharmony_ci#define CCTRL4331_EXT_LNA (1<<2) 11662306a36Sopenharmony_ci /* sprom/gpio13-15 mux */ 11762306a36Sopenharmony_ci#define CCTRL4331_SPROM_GPIO13_15 (1<<3) 11862306a36Sopenharmony_ci /* 0 ext pa disable, 1 ext pa enabled */ 11962306a36Sopenharmony_ci#define CCTRL4331_EXTPA_EN (1<<4) 12062306a36Sopenharmony_ci /* set drive out GPIO_CLK on sprom_cs pin */ 12162306a36Sopenharmony_ci#define CCTRL4331_GPIOCLK_ON_SPROMCS (1<<5) 12262306a36Sopenharmony_ci /* use sprom_cs pin as PCIE mdio interface */ 12362306a36Sopenharmony_ci#define CCTRL4331_PCIE_MDIO_ON_SPROMCS (1<<6) 12462306a36Sopenharmony_ci /* aband extpa will be at gpio2/5 and sprom_dout */ 12562306a36Sopenharmony_ci#define CCTRL4331_EXTPA_ON_GPIO2_5 (1<<7) 12662306a36Sopenharmony_ci /* override core control on pipe_AuxClkEnable */ 12762306a36Sopenharmony_ci#define CCTRL4331_OVR_PIPEAUXCLKEN (1<<8) 12862306a36Sopenharmony_ci /* override core control on pipe_AuxPowerDown */ 12962306a36Sopenharmony_ci#define CCTRL4331_OVR_PIPEAUXPWRDOWN (1<<9) 13062306a36Sopenharmony_ci /* pcie_auxclkenable */ 13162306a36Sopenharmony_ci#define CCTRL4331_PCIE_AUXCLKEN (1<<10) 13262306a36Sopenharmony_ci /* pcie_pipe_pllpowerdown */ 13362306a36Sopenharmony_ci#define CCTRL4331_PCIE_PIPE_PLLDOWN (1<<11) 13462306a36Sopenharmony_ci /* enable bt_shd0 at gpio4 */ 13562306a36Sopenharmony_ci#define CCTRL4331_BT_SHD0_ON_GPIO4 (1<<16) 13662306a36Sopenharmony_ci /* enable bt_shd1 at gpio5 */ 13762306a36Sopenharmony_ci#define CCTRL4331_BT_SHD1_ON_GPIO5 (1<<17) 13862306a36Sopenharmony_ci 13962306a36Sopenharmony_ci/* 4331 Chip specific ChipStatus register bits */ 14062306a36Sopenharmony_ci /* crystal frequency 20/40Mhz */ 14162306a36Sopenharmony_ci#define CST4331_XTAL_FREQ 0x00000001 14262306a36Sopenharmony_ci#define CST4331_SPROM_PRESENT 0x00000002 14362306a36Sopenharmony_ci#define CST4331_OTP_PRESENT 0x00000004 14462306a36Sopenharmony_ci#define CST4331_LDO_RF 0x00000008 14562306a36Sopenharmony_ci#define CST4331_LDO_PAR 0x00000010 14662306a36Sopenharmony_ci 14762306a36Sopenharmony_ci/* 4319 chip-specific ChipStatus register bits */ 14862306a36Sopenharmony_ci#define CST4319_SPI_CPULESSUSB 0x00000001 14962306a36Sopenharmony_ci#define CST4319_SPI_CLK_POL 0x00000002 15062306a36Sopenharmony_ci#define CST4319_SPI_CLK_PH 0x00000008 15162306a36Sopenharmony_ci /* gpio [7:6], SDIO CIS selection */ 15262306a36Sopenharmony_ci#define CST4319_SPROM_OTP_SEL_MASK 0x000000c0 15362306a36Sopenharmony_ci#define CST4319_SPROM_OTP_SEL_SHIFT 6 15462306a36Sopenharmony_ci /* use default CIS, OTP is powered up */ 15562306a36Sopenharmony_ci#define CST4319_DEFCIS_SEL 0x00000000 15662306a36Sopenharmony_ci /* use SPROM, OTP is powered up */ 15762306a36Sopenharmony_ci#define CST4319_SPROM_SEL 0x00000040 15862306a36Sopenharmony_ci /* use OTP, OTP is powered up */ 15962306a36Sopenharmony_ci#define CST4319_OTP_SEL 0x00000080 16062306a36Sopenharmony_ci /* use SPROM, OTP is powered down */ 16162306a36Sopenharmony_ci#define CST4319_OTP_PWRDN 0x000000c0 16262306a36Sopenharmony_ci /* gpio [8], sdio/usb mode */ 16362306a36Sopenharmony_ci#define CST4319_SDIO_USB_MODE 0x00000100 16462306a36Sopenharmony_ci#define CST4319_REMAP_SEL_MASK 0x00000600 16562306a36Sopenharmony_ci#define CST4319_ILPDIV_EN 0x00000800 16662306a36Sopenharmony_ci#define CST4319_XTAL_PD_POL 0x00001000 16762306a36Sopenharmony_ci#define CST4319_LPO_SEL 0x00002000 16862306a36Sopenharmony_ci#define CST4319_RES_INIT_MODE 0x0000c000 16962306a36Sopenharmony_ci /* PALDO is configured with external PNP */ 17062306a36Sopenharmony_ci#define CST4319_PALDO_EXTPNP 0x00010000 17162306a36Sopenharmony_ci#define CST4319_CBUCK_MODE_MASK 0x00060000 17262306a36Sopenharmony_ci#define CST4319_CBUCK_MODE_BURST 0x00020000 17362306a36Sopenharmony_ci#define CST4319_CBUCK_MODE_LPBURST 0x00060000 17462306a36Sopenharmony_ci#define CST4319_RCAL_VALID 0x01000000 17562306a36Sopenharmony_ci#define CST4319_RCAL_VALUE_MASK 0x3e000000 17662306a36Sopenharmony_ci#define CST4319_RCAL_VALUE_SHIFT 25 17762306a36Sopenharmony_ci 17862306a36Sopenharmony_ci/* 4336 chip-specific ChipStatus register bits */ 17962306a36Sopenharmony_ci#define CST4336_SPI_MODE_MASK 0x00000001 18062306a36Sopenharmony_ci#define CST4336_SPROM_PRESENT 0x00000002 18162306a36Sopenharmony_ci#define CST4336_OTP_PRESENT 0x00000004 18262306a36Sopenharmony_ci#define CST4336_ARMREMAP_0 0x00000008 18362306a36Sopenharmony_ci#define CST4336_ILPDIV_EN_MASK 0x00000010 18462306a36Sopenharmony_ci#define CST4336_ILPDIV_EN_SHIFT 4 18562306a36Sopenharmony_ci#define CST4336_XTAL_PD_POL_MASK 0x00000020 18662306a36Sopenharmony_ci#define CST4336_XTAL_PD_POL_SHIFT 5 18762306a36Sopenharmony_ci#define CST4336_LPO_SEL_MASK 0x00000040 18862306a36Sopenharmony_ci#define CST4336_LPO_SEL_SHIFT 6 18962306a36Sopenharmony_ci#define CST4336_RES_INIT_MODE_MASK 0x00000180 19062306a36Sopenharmony_ci#define CST4336_RES_INIT_MODE_SHIFT 7 19162306a36Sopenharmony_ci#define CST4336_CBUCK_MODE_MASK 0x00000600 19262306a36Sopenharmony_ci#define CST4336_CBUCK_MODE_SHIFT 9 19362306a36Sopenharmony_ci 19462306a36Sopenharmony_ci/* 4313 chip-specific ChipStatus register bits */ 19562306a36Sopenharmony_ci#define CST4313_SPROM_PRESENT 1 19662306a36Sopenharmony_ci#define CST4313_OTP_PRESENT 2 19762306a36Sopenharmony_ci#define CST4313_SPROM_OTP_SEL_MASK 0x00000002 19862306a36Sopenharmony_ci#define CST4313_SPROM_OTP_SEL_SHIFT 0 19962306a36Sopenharmony_ci 20062306a36Sopenharmony_ci/* 4313 Chip specific ChipControl register bits */ 20162306a36Sopenharmony_ci /* 12 mA drive strengh for later 4313 */ 20262306a36Sopenharmony_ci#define CCTRL_4313_12MA_LED_DRIVE 0x00000007 20362306a36Sopenharmony_ci 20462306a36Sopenharmony_ci/* Manufacturer Ids */ 20562306a36Sopenharmony_ci#define MFGID_ARM 0x43b 20662306a36Sopenharmony_ci#define MFGID_BRCM 0x4bf 20762306a36Sopenharmony_ci#define MFGID_MIPS 0x4a7 20862306a36Sopenharmony_ci 20962306a36Sopenharmony_ci/* Enumeration ROM registers */ 21062306a36Sopenharmony_ci#define ER_EROMENTRY 0x000 21162306a36Sopenharmony_ci#define ER_REMAPCONTROL 0xe00 21262306a36Sopenharmony_ci#define ER_REMAPSELECT 0xe04 21362306a36Sopenharmony_ci#define ER_MASTERSELECT 0xe10 21462306a36Sopenharmony_ci#define ER_ITCR 0xf00 21562306a36Sopenharmony_ci#define ER_ITIP 0xf04 21662306a36Sopenharmony_ci 21762306a36Sopenharmony_ci/* Erom entries */ 21862306a36Sopenharmony_ci#define ER_TAG 0xe 21962306a36Sopenharmony_ci#define ER_TAG1 0x6 22062306a36Sopenharmony_ci#define ER_VALID 1 22162306a36Sopenharmony_ci#define ER_CI 0 22262306a36Sopenharmony_ci#define ER_MP 2 22362306a36Sopenharmony_ci#define ER_ADD 4 22462306a36Sopenharmony_ci#define ER_END 0xe 22562306a36Sopenharmony_ci#define ER_BAD 0xffffffff 22662306a36Sopenharmony_ci 22762306a36Sopenharmony_ci/* EROM CompIdentA */ 22862306a36Sopenharmony_ci#define CIA_MFG_MASK 0xfff00000 22962306a36Sopenharmony_ci#define CIA_MFG_SHIFT 20 23062306a36Sopenharmony_ci#define CIA_CID_MASK 0x000fff00 23162306a36Sopenharmony_ci#define CIA_CID_SHIFT 8 23262306a36Sopenharmony_ci#define CIA_CCL_MASK 0x000000f0 23362306a36Sopenharmony_ci#define CIA_CCL_SHIFT 4 23462306a36Sopenharmony_ci 23562306a36Sopenharmony_ci/* EROM CompIdentB */ 23662306a36Sopenharmony_ci#define CIB_REV_MASK 0xff000000 23762306a36Sopenharmony_ci#define CIB_REV_SHIFT 24 23862306a36Sopenharmony_ci#define CIB_NSW_MASK 0x00f80000 23962306a36Sopenharmony_ci#define CIB_NSW_SHIFT 19 24062306a36Sopenharmony_ci#define CIB_NMW_MASK 0x0007c000 24162306a36Sopenharmony_ci#define CIB_NMW_SHIFT 14 24262306a36Sopenharmony_ci#define CIB_NSP_MASK 0x00003e00 24362306a36Sopenharmony_ci#define CIB_NSP_SHIFT 9 24462306a36Sopenharmony_ci#define CIB_NMP_MASK 0x000001f0 24562306a36Sopenharmony_ci#define CIB_NMP_SHIFT 4 24662306a36Sopenharmony_ci 24762306a36Sopenharmony_ci/* EROM AddrDesc */ 24862306a36Sopenharmony_ci#define AD_ADDR_MASK 0xfffff000 24962306a36Sopenharmony_ci#define AD_SP_MASK 0x00000f00 25062306a36Sopenharmony_ci#define AD_SP_SHIFT 8 25162306a36Sopenharmony_ci#define AD_ST_MASK 0x000000c0 25262306a36Sopenharmony_ci#define AD_ST_SHIFT 6 25362306a36Sopenharmony_ci#define AD_ST_SLAVE 0x00000000 25462306a36Sopenharmony_ci#define AD_ST_BRIDGE 0x00000040 25562306a36Sopenharmony_ci#define AD_ST_SWRAP 0x00000080 25662306a36Sopenharmony_ci#define AD_ST_MWRAP 0x000000c0 25762306a36Sopenharmony_ci#define AD_SZ_MASK 0x00000030 25862306a36Sopenharmony_ci#define AD_SZ_SHIFT 4 25962306a36Sopenharmony_ci#define AD_SZ_4K 0x00000000 26062306a36Sopenharmony_ci#define AD_SZ_8K 0x00000010 26162306a36Sopenharmony_ci#define AD_SZ_16K 0x00000020 26262306a36Sopenharmony_ci#define AD_SZ_SZD 0x00000030 26362306a36Sopenharmony_ci#define AD_AG32 0x00000008 26462306a36Sopenharmony_ci#define AD_ADDR_ALIGN 0x00000fff 26562306a36Sopenharmony_ci#define AD_SZ_BASE 0x00001000 /* 4KB */ 26662306a36Sopenharmony_ci 26762306a36Sopenharmony_ci/* EROM SizeDesc */ 26862306a36Sopenharmony_ci#define SD_SZ_MASK 0xfffff000 26962306a36Sopenharmony_ci#define SD_SG32 0x00000008 27062306a36Sopenharmony_ci#define SD_SZ_ALIGN 0x00000fff 27162306a36Sopenharmony_ci 27262306a36Sopenharmony_ci/* PCI config space bit 4 for 4306c0 slow clock source */ 27362306a36Sopenharmony_ci#define PCI_CFG_GPIO_SCS 0x10 27462306a36Sopenharmony_ci/* PCI config space GPIO 14 for Xtal power-up */ 27562306a36Sopenharmony_ci#define PCI_CFG_GPIO_XTAL 0x40 27662306a36Sopenharmony_ci/* PCI config space GPIO 15 for PLL power-down */ 27762306a36Sopenharmony_ci#define PCI_CFG_GPIO_PLL 0x80 27862306a36Sopenharmony_ci 27962306a36Sopenharmony_ci/* power control defines */ 28062306a36Sopenharmony_ci#define PLL_DELAY 150 /* us pll on delay */ 28162306a36Sopenharmony_ci#define FREF_DELAY 200 /* us fref change delay */ 28262306a36Sopenharmony_ci#define XTAL_ON_DELAY 1000 /* us crystal power-on delay */ 28362306a36Sopenharmony_ci 28462306a36Sopenharmony_ci/* resetctrl */ 28562306a36Sopenharmony_ci#define AIRC_RESET 1 28662306a36Sopenharmony_ci 28762306a36Sopenharmony_ci#define NOREV -1 /* Invalid rev */ 28862306a36Sopenharmony_ci 28962306a36Sopenharmony_ci/* GPIO Based LED powersave defines */ 29062306a36Sopenharmony_ci#define DEFAULT_GPIO_ONTIME 10 /* Default: 10% on */ 29162306a36Sopenharmony_ci#define DEFAULT_GPIO_OFFTIME 90 /* Default: 10% on */ 29262306a36Sopenharmony_ci 29362306a36Sopenharmony_ci/* When Srom support present, fields in sromcontrol */ 29462306a36Sopenharmony_ci#define SRC_START 0x80000000 29562306a36Sopenharmony_ci#define SRC_BUSY 0x80000000 29662306a36Sopenharmony_ci#define SRC_OPCODE 0x60000000 29762306a36Sopenharmony_ci#define SRC_OP_READ 0x00000000 29862306a36Sopenharmony_ci#define SRC_OP_WRITE 0x20000000 29962306a36Sopenharmony_ci#define SRC_OP_WRDIS 0x40000000 30062306a36Sopenharmony_ci#define SRC_OP_WREN 0x60000000 30162306a36Sopenharmony_ci#define SRC_OTPSEL 0x00000010 30262306a36Sopenharmony_ci#define SRC_LOCK 0x00000008 30362306a36Sopenharmony_ci#define SRC_SIZE_MASK 0x00000006 30462306a36Sopenharmony_ci#define SRC_SIZE_1K 0x00000000 30562306a36Sopenharmony_ci#define SRC_SIZE_4K 0x00000002 30662306a36Sopenharmony_ci#define SRC_SIZE_16K 0x00000004 30762306a36Sopenharmony_ci#define SRC_SIZE_SHIFT 1 30862306a36Sopenharmony_ci#define SRC_PRESENT 0x00000001 30962306a36Sopenharmony_ci 31062306a36Sopenharmony_ci/* External PA enable mask */ 31162306a36Sopenharmony_ci#define GPIO_CTRL_EPA_EN_MASK 0x40 31262306a36Sopenharmony_ci 31362306a36Sopenharmony_ci#define DEFAULT_GPIOTIMERVAL \ 31462306a36Sopenharmony_ci ((DEFAULT_GPIO_ONTIME << GPIO_ONTIME_SHIFT) | DEFAULT_GPIO_OFFTIME) 31562306a36Sopenharmony_ci 31662306a36Sopenharmony_ci#define BADIDX (SI_MAXCORES + 1) 31762306a36Sopenharmony_ci 31862306a36Sopenharmony_ci#define IS_SIM(chippkg) \ 31962306a36Sopenharmony_ci ((chippkg == HDLSIM_PKG_ID) || (chippkg == HWSIM_PKG_ID)) 32062306a36Sopenharmony_ci 32162306a36Sopenharmony_ci#define GOODCOREADDR(x, b) \ 32262306a36Sopenharmony_ci (((x) >= (b)) && ((x) < ((b) + SI_MAXCORES * SI_CORE_SIZE)) && \ 32362306a36Sopenharmony_ci IS_ALIGNED((x), SI_CORE_SIZE)) 32462306a36Sopenharmony_ci 32562306a36Sopenharmony_cistruct aidmp { 32662306a36Sopenharmony_ci u32 oobselina30; /* 0x000 */ 32762306a36Sopenharmony_ci u32 oobselina74; /* 0x004 */ 32862306a36Sopenharmony_ci u32 PAD[6]; 32962306a36Sopenharmony_ci u32 oobselinb30; /* 0x020 */ 33062306a36Sopenharmony_ci u32 oobselinb74; /* 0x024 */ 33162306a36Sopenharmony_ci u32 PAD[6]; 33262306a36Sopenharmony_ci u32 oobselinc30; /* 0x040 */ 33362306a36Sopenharmony_ci u32 oobselinc74; /* 0x044 */ 33462306a36Sopenharmony_ci u32 PAD[6]; 33562306a36Sopenharmony_ci u32 oobselind30; /* 0x060 */ 33662306a36Sopenharmony_ci u32 oobselind74; /* 0x064 */ 33762306a36Sopenharmony_ci u32 PAD[38]; 33862306a36Sopenharmony_ci u32 oobselouta30; /* 0x100 */ 33962306a36Sopenharmony_ci u32 oobselouta74; /* 0x104 */ 34062306a36Sopenharmony_ci u32 PAD[6]; 34162306a36Sopenharmony_ci u32 oobseloutb30; /* 0x120 */ 34262306a36Sopenharmony_ci u32 oobseloutb74; /* 0x124 */ 34362306a36Sopenharmony_ci u32 PAD[6]; 34462306a36Sopenharmony_ci u32 oobseloutc30; /* 0x140 */ 34562306a36Sopenharmony_ci u32 oobseloutc74; /* 0x144 */ 34662306a36Sopenharmony_ci u32 PAD[6]; 34762306a36Sopenharmony_ci u32 oobseloutd30; /* 0x160 */ 34862306a36Sopenharmony_ci u32 oobseloutd74; /* 0x164 */ 34962306a36Sopenharmony_ci u32 PAD[38]; 35062306a36Sopenharmony_ci u32 oobsynca; /* 0x200 */ 35162306a36Sopenharmony_ci u32 oobseloutaen; /* 0x204 */ 35262306a36Sopenharmony_ci u32 PAD[6]; 35362306a36Sopenharmony_ci u32 oobsyncb; /* 0x220 */ 35462306a36Sopenharmony_ci u32 oobseloutben; /* 0x224 */ 35562306a36Sopenharmony_ci u32 PAD[6]; 35662306a36Sopenharmony_ci u32 oobsyncc; /* 0x240 */ 35762306a36Sopenharmony_ci u32 oobseloutcen; /* 0x244 */ 35862306a36Sopenharmony_ci u32 PAD[6]; 35962306a36Sopenharmony_ci u32 oobsyncd; /* 0x260 */ 36062306a36Sopenharmony_ci u32 oobseloutden; /* 0x264 */ 36162306a36Sopenharmony_ci u32 PAD[38]; 36262306a36Sopenharmony_ci u32 oobaextwidth; /* 0x300 */ 36362306a36Sopenharmony_ci u32 oobainwidth; /* 0x304 */ 36462306a36Sopenharmony_ci u32 oobaoutwidth; /* 0x308 */ 36562306a36Sopenharmony_ci u32 PAD[5]; 36662306a36Sopenharmony_ci u32 oobbextwidth; /* 0x320 */ 36762306a36Sopenharmony_ci u32 oobbinwidth; /* 0x324 */ 36862306a36Sopenharmony_ci u32 oobboutwidth; /* 0x328 */ 36962306a36Sopenharmony_ci u32 PAD[5]; 37062306a36Sopenharmony_ci u32 oobcextwidth; /* 0x340 */ 37162306a36Sopenharmony_ci u32 oobcinwidth; /* 0x344 */ 37262306a36Sopenharmony_ci u32 oobcoutwidth; /* 0x348 */ 37362306a36Sopenharmony_ci u32 PAD[5]; 37462306a36Sopenharmony_ci u32 oobdextwidth; /* 0x360 */ 37562306a36Sopenharmony_ci u32 oobdinwidth; /* 0x364 */ 37662306a36Sopenharmony_ci u32 oobdoutwidth; /* 0x368 */ 37762306a36Sopenharmony_ci u32 PAD[37]; 37862306a36Sopenharmony_ci u32 ioctrlset; /* 0x400 */ 37962306a36Sopenharmony_ci u32 ioctrlclear; /* 0x404 */ 38062306a36Sopenharmony_ci u32 ioctrl; /* 0x408 */ 38162306a36Sopenharmony_ci u32 PAD[61]; 38262306a36Sopenharmony_ci u32 iostatus; /* 0x500 */ 38362306a36Sopenharmony_ci u32 PAD[127]; 38462306a36Sopenharmony_ci u32 ioctrlwidth; /* 0x700 */ 38562306a36Sopenharmony_ci u32 iostatuswidth; /* 0x704 */ 38662306a36Sopenharmony_ci u32 PAD[62]; 38762306a36Sopenharmony_ci u32 resetctrl; /* 0x800 */ 38862306a36Sopenharmony_ci u32 resetstatus; /* 0x804 */ 38962306a36Sopenharmony_ci u32 resetreadid; /* 0x808 */ 39062306a36Sopenharmony_ci u32 resetwriteid; /* 0x80c */ 39162306a36Sopenharmony_ci u32 PAD[60]; 39262306a36Sopenharmony_ci u32 errlogctrl; /* 0x900 */ 39362306a36Sopenharmony_ci u32 errlogdone; /* 0x904 */ 39462306a36Sopenharmony_ci u32 errlogstatus; /* 0x908 */ 39562306a36Sopenharmony_ci u32 errlogaddrlo; /* 0x90c */ 39662306a36Sopenharmony_ci u32 errlogaddrhi; /* 0x910 */ 39762306a36Sopenharmony_ci u32 errlogid; /* 0x914 */ 39862306a36Sopenharmony_ci u32 errloguser; /* 0x918 */ 39962306a36Sopenharmony_ci u32 errlogflags; /* 0x91c */ 40062306a36Sopenharmony_ci u32 PAD[56]; 40162306a36Sopenharmony_ci u32 intstatus; /* 0xa00 */ 40262306a36Sopenharmony_ci u32 PAD[127]; 40362306a36Sopenharmony_ci u32 config; /* 0xe00 */ 40462306a36Sopenharmony_ci u32 PAD[63]; 40562306a36Sopenharmony_ci u32 itcr; /* 0xf00 */ 40662306a36Sopenharmony_ci u32 PAD[3]; 40762306a36Sopenharmony_ci u32 itipooba; /* 0xf10 */ 40862306a36Sopenharmony_ci u32 itipoobb; /* 0xf14 */ 40962306a36Sopenharmony_ci u32 itipoobc; /* 0xf18 */ 41062306a36Sopenharmony_ci u32 itipoobd; /* 0xf1c */ 41162306a36Sopenharmony_ci u32 PAD[4]; 41262306a36Sopenharmony_ci u32 itipoobaout; /* 0xf30 */ 41362306a36Sopenharmony_ci u32 itipoobbout; /* 0xf34 */ 41462306a36Sopenharmony_ci u32 itipoobcout; /* 0xf38 */ 41562306a36Sopenharmony_ci u32 itipoobdout; /* 0xf3c */ 41662306a36Sopenharmony_ci u32 PAD[4]; 41762306a36Sopenharmony_ci u32 itopooba; /* 0xf50 */ 41862306a36Sopenharmony_ci u32 itopoobb; /* 0xf54 */ 41962306a36Sopenharmony_ci u32 itopoobc; /* 0xf58 */ 42062306a36Sopenharmony_ci u32 itopoobd; /* 0xf5c */ 42162306a36Sopenharmony_ci u32 PAD[4]; 42262306a36Sopenharmony_ci u32 itopoobain; /* 0xf70 */ 42362306a36Sopenharmony_ci u32 itopoobbin; /* 0xf74 */ 42462306a36Sopenharmony_ci u32 itopoobcin; /* 0xf78 */ 42562306a36Sopenharmony_ci u32 itopoobdin; /* 0xf7c */ 42662306a36Sopenharmony_ci u32 PAD[4]; 42762306a36Sopenharmony_ci u32 itopreset; /* 0xf90 */ 42862306a36Sopenharmony_ci u32 PAD[15]; 42962306a36Sopenharmony_ci u32 peripherialid4; /* 0xfd0 */ 43062306a36Sopenharmony_ci u32 peripherialid5; /* 0xfd4 */ 43162306a36Sopenharmony_ci u32 peripherialid6; /* 0xfd8 */ 43262306a36Sopenharmony_ci u32 peripherialid7; /* 0xfdc */ 43362306a36Sopenharmony_ci u32 peripherialid0; /* 0xfe0 */ 43462306a36Sopenharmony_ci u32 peripherialid1; /* 0xfe4 */ 43562306a36Sopenharmony_ci u32 peripherialid2; /* 0xfe8 */ 43662306a36Sopenharmony_ci u32 peripherialid3; /* 0xfec */ 43762306a36Sopenharmony_ci u32 componentid0; /* 0xff0 */ 43862306a36Sopenharmony_ci u32 componentid1; /* 0xff4 */ 43962306a36Sopenharmony_ci u32 componentid2; /* 0xff8 */ 44062306a36Sopenharmony_ci u32 componentid3; /* 0xffc */ 44162306a36Sopenharmony_ci}; 44262306a36Sopenharmony_ci 44362306a36Sopenharmony_cistatic bool 44462306a36Sopenharmony_ciai_buscore_setup(struct si_info *sii, struct bcma_device *cc) 44562306a36Sopenharmony_ci{ 44662306a36Sopenharmony_ci /* no cores found, bail out */ 44762306a36Sopenharmony_ci if (cc->bus->nr_cores == 0) 44862306a36Sopenharmony_ci return false; 44962306a36Sopenharmony_ci 45062306a36Sopenharmony_ci /* get chipcommon rev */ 45162306a36Sopenharmony_ci sii->pub.ccrev = cc->id.rev; 45262306a36Sopenharmony_ci 45362306a36Sopenharmony_ci /* get chipcommon chipstatus */ 45462306a36Sopenharmony_ci sii->chipst = bcma_read32(cc, CHIPCREGOFFS(chipstatus)); 45562306a36Sopenharmony_ci 45662306a36Sopenharmony_ci /* get chipcommon capabilites */ 45762306a36Sopenharmony_ci sii->pub.cccaps = bcma_read32(cc, CHIPCREGOFFS(capabilities)); 45862306a36Sopenharmony_ci 45962306a36Sopenharmony_ci /* get pmu rev and caps */ 46062306a36Sopenharmony_ci if (ai_get_cccaps(&sii->pub) & CC_CAP_PMU) { 46162306a36Sopenharmony_ci sii->pub.pmucaps = bcma_read32(cc, 46262306a36Sopenharmony_ci CHIPCREGOFFS(pmucapabilities)); 46362306a36Sopenharmony_ci sii->pub.pmurev = sii->pub.pmucaps & PCAP_REV_MASK; 46462306a36Sopenharmony_ci } 46562306a36Sopenharmony_ci 46662306a36Sopenharmony_ci return true; 46762306a36Sopenharmony_ci} 46862306a36Sopenharmony_ci 46962306a36Sopenharmony_cistatic struct si_info *ai_doattach(struct si_info *sii, 47062306a36Sopenharmony_ci struct bcma_bus *pbus) 47162306a36Sopenharmony_ci{ 47262306a36Sopenharmony_ci struct si_pub *sih = &sii->pub; 47362306a36Sopenharmony_ci struct bcma_device *cc; 47462306a36Sopenharmony_ci 47562306a36Sopenharmony_ci sii->icbus = pbus; 47662306a36Sopenharmony_ci sii->pcibus = pbus->host_pci; 47762306a36Sopenharmony_ci 47862306a36Sopenharmony_ci /* switch to Chipcommon core */ 47962306a36Sopenharmony_ci cc = pbus->drv_cc.core; 48062306a36Sopenharmony_ci 48162306a36Sopenharmony_ci sih->chip = pbus->chipinfo.id; 48262306a36Sopenharmony_ci sih->chiprev = pbus->chipinfo.rev; 48362306a36Sopenharmony_ci sih->chippkg = pbus->chipinfo.pkg; 48462306a36Sopenharmony_ci sih->boardvendor = pbus->boardinfo.vendor; 48562306a36Sopenharmony_ci sih->boardtype = pbus->boardinfo.type; 48662306a36Sopenharmony_ci 48762306a36Sopenharmony_ci if (!ai_buscore_setup(sii, cc)) 48862306a36Sopenharmony_ci goto exit; 48962306a36Sopenharmony_ci 49062306a36Sopenharmony_ci /* === NVRAM, clock is ready === */ 49162306a36Sopenharmony_ci bcma_write32(cc, CHIPCREGOFFS(gpiopullup), 0); 49262306a36Sopenharmony_ci bcma_write32(cc, CHIPCREGOFFS(gpiopulldown), 0); 49362306a36Sopenharmony_ci 49462306a36Sopenharmony_ci /* PMU specific initializations */ 49562306a36Sopenharmony_ci if (ai_get_cccaps(sih) & CC_CAP_PMU) { 49662306a36Sopenharmony_ci (void)si_pmu_measure_alpclk(sih); 49762306a36Sopenharmony_ci } 49862306a36Sopenharmony_ci 49962306a36Sopenharmony_ci return sii; 50062306a36Sopenharmony_ci 50162306a36Sopenharmony_ci exit: 50262306a36Sopenharmony_ci 50362306a36Sopenharmony_ci return NULL; 50462306a36Sopenharmony_ci} 50562306a36Sopenharmony_ci 50662306a36Sopenharmony_ci/* 50762306a36Sopenharmony_ci * Allocate a si handle and do the attach. 50862306a36Sopenharmony_ci */ 50962306a36Sopenharmony_cistruct si_pub * 51062306a36Sopenharmony_ciai_attach(struct bcma_bus *pbus) 51162306a36Sopenharmony_ci{ 51262306a36Sopenharmony_ci struct si_info *sii; 51362306a36Sopenharmony_ci 51462306a36Sopenharmony_ci /* alloc struct si_info */ 51562306a36Sopenharmony_ci sii = kzalloc(sizeof(struct si_info), GFP_ATOMIC); 51662306a36Sopenharmony_ci if (sii == NULL) 51762306a36Sopenharmony_ci return NULL; 51862306a36Sopenharmony_ci 51962306a36Sopenharmony_ci if (ai_doattach(sii, pbus) == NULL) { 52062306a36Sopenharmony_ci kfree(sii); 52162306a36Sopenharmony_ci return NULL; 52262306a36Sopenharmony_ci } 52362306a36Sopenharmony_ci 52462306a36Sopenharmony_ci return (struct si_pub *) sii; 52562306a36Sopenharmony_ci} 52662306a36Sopenharmony_ci 52762306a36Sopenharmony_ci/* may be called with core in reset */ 52862306a36Sopenharmony_civoid ai_detach(struct si_pub *sih) 52962306a36Sopenharmony_ci{ 53062306a36Sopenharmony_ci struct si_info *sii; 53162306a36Sopenharmony_ci 53262306a36Sopenharmony_ci sii = container_of(sih, struct si_info, pub); 53362306a36Sopenharmony_ci 53462306a36Sopenharmony_ci kfree(sii); 53562306a36Sopenharmony_ci} 53662306a36Sopenharmony_ci 53762306a36Sopenharmony_ci/* 53862306a36Sopenharmony_ci * read/modify chipcommon core register. 53962306a36Sopenharmony_ci */ 54062306a36Sopenharmony_ciuint ai_cc_reg(struct si_pub *sih, uint regoff, u32 mask, u32 val) 54162306a36Sopenharmony_ci{ 54262306a36Sopenharmony_ci struct bcma_device *cc; 54362306a36Sopenharmony_ci u32 w; 54462306a36Sopenharmony_ci struct si_info *sii; 54562306a36Sopenharmony_ci 54662306a36Sopenharmony_ci sii = container_of(sih, struct si_info, pub); 54762306a36Sopenharmony_ci cc = sii->icbus->drv_cc.core; 54862306a36Sopenharmony_ci 54962306a36Sopenharmony_ci /* mask and set */ 55062306a36Sopenharmony_ci if (mask || val) 55162306a36Sopenharmony_ci bcma_maskset32(cc, regoff, ~mask, val); 55262306a36Sopenharmony_ci 55362306a36Sopenharmony_ci /* readback */ 55462306a36Sopenharmony_ci w = bcma_read32(cc, regoff); 55562306a36Sopenharmony_ci 55662306a36Sopenharmony_ci return w; 55762306a36Sopenharmony_ci} 55862306a36Sopenharmony_ci 55962306a36Sopenharmony_ci/* return the slow clock source - LPO, XTAL, or PCI */ 56062306a36Sopenharmony_cistatic uint ai_slowclk_src(struct si_pub *sih, struct bcma_device *cc) 56162306a36Sopenharmony_ci{ 56262306a36Sopenharmony_ci return SCC_SS_XTAL; 56362306a36Sopenharmony_ci} 56462306a36Sopenharmony_ci 56562306a36Sopenharmony_ci/* 56662306a36Sopenharmony_ci* return the ILP (slowclock) min or max frequency 56762306a36Sopenharmony_ci* precondition: we've established the chip has dynamic clk control 56862306a36Sopenharmony_ci*/ 56962306a36Sopenharmony_cistatic uint ai_slowclk_freq(struct si_pub *sih, bool max_freq, 57062306a36Sopenharmony_ci struct bcma_device *cc) 57162306a36Sopenharmony_ci{ 57262306a36Sopenharmony_ci uint div; 57362306a36Sopenharmony_ci 57462306a36Sopenharmony_ci /* Chipc rev 10 is InstaClock */ 57562306a36Sopenharmony_ci div = bcma_read32(cc, CHIPCREGOFFS(system_clk_ctl)); 57662306a36Sopenharmony_ci div = 4 * ((div >> SYCC_CD_SHIFT) + 1); 57762306a36Sopenharmony_ci return max_freq ? XTALMAXFREQ : (XTALMINFREQ / div); 57862306a36Sopenharmony_ci} 57962306a36Sopenharmony_ci 58062306a36Sopenharmony_cistatic void 58162306a36Sopenharmony_ciai_clkctl_setdelay(struct si_pub *sih, struct bcma_device *cc) 58262306a36Sopenharmony_ci{ 58362306a36Sopenharmony_ci uint slowmaxfreq, pll_delay, slowclk; 58462306a36Sopenharmony_ci uint pll_on_delay, fref_sel_delay; 58562306a36Sopenharmony_ci 58662306a36Sopenharmony_ci pll_delay = PLL_DELAY; 58762306a36Sopenharmony_ci 58862306a36Sopenharmony_ci /* 58962306a36Sopenharmony_ci * If the slow clock is not sourced by the xtal then 59062306a36Sopenharmony_ci * add the xtal_on_delay since the xtal will also be 59162306a36Sopenharmony_ci * powered down by dynamic clk control logic. 59262306a36Sopenharmony_ci */ 59362306a36Sopenharmony_ci 59462306a36Sopenharmony_ci slowclk = ai_slowclk_src(sih, cc); 59562306a36Sopenharmony_ci if (slowclk != SCC_SS_XTAL) 59662306a36Sopenharmony_ci pll_delay += XTAL_ON_DELAY; 59762306a36Sopenharmony_ci 59862306a36Sopenharmony_ci /* Starting with 4318 it is ILP that is used for the delays */ 59962306a36Sopenharmony_ci slowmaxfreq = 60062306a36Sopenharmony_ci ai_slowclk_freq(sih, false, cc); 60162306a36Sopenharmony_ci 60262306a36Sopenharmony_ci pll_on_delay = ((slowmaxfreq * pll_delay) + 999999) / 1000000; 60362306a36Sopenharmony_ci fref_sel_delay = ((slowmaxfreq * FREF_DELAY) + 999999) / 1000000; 60462306a36Sopenharmony_ci 60562306a36Sopenharmony_ci bcma_write32(cc, CHIPCREGOFFS(pll_on_delay), pll_on_delay); 60662306a36Sopenharmony_ci bcma_write32(cc, CHIPCREGOFFS(fref_sel_delay), fref_sel_delay); 60762306a36Sopenharmony_ci} 60862306a36Sopenharmony_ci 60962306a36Sopenharmony_ci/* initialize power control delay registers */ 61062306a36Sopenharmony_civoid ai_clkctl_init(struct si_pub *sih) 61162306a36Sopenharmony_ci{ 61262306a36Sopenharmony_ci struct si_info *sii = container_of(sih, struct si_info, pub); 61362306a36Sopenharmony_ci struct bcma_device *cc; 61462306a36Sopenharmony_ci 61562306a36Sopenharmony_ci if (!(ai_get_cccaps(sih) & CC_CAP_PWR_CTL)) 61662306a36Sopenharmony_ci return; 61762306a36Sopenharmony_ci 61862306a36Sopenharmony_ci cc = sii->icbus->drv_cc.core; 61962306a36Sopenharmony_ci if (cc == NULL) 62062306a36Sopenharmony_ci return; 62162306a36Sopenharmony_ci 62262306a36Sopenharmony_ci /* set all Instaclk chip ILP to 1 MHz */ 62362306a36Sopenharmony_ci bcma_maskset32(cc, CHIPCREGOFFS(system_clk_ctl), SYCC_CD_MASK, 62462306a36Sopenharmony_ci (ILP_DIV_1MHZ << SYCC_CD_SHIFT)); 62562306a36Sopenharmony_ci 62662306a36Sopenharmony_ci ai_clkctl_setdelay(sih, cc); 62762306a36Sopenharmony_ci} 62862306a36Sopenharmony_ci 62962306a36Sopenharmony_ci/* 63062306a36Sopenharmony_ci * return the value suitable for writing to the 63162306a36Sopenharmony_ci * dot11 core FAST_PWRUP_DELAY register 63262306a36Sopenharmony_ci */ 63362306a36Sopenharmony_ciu16 ai_clkctl_fast_pwrup_delay(struct si_pub *sih) 63462306a36Sopenharmony_ci{ 63562306a36Sopenharmony_ci struct si_info *sii; 63662306a36Sopenharmony_ci struct bcma_device *cc; 63762306a36Sopenharmony_ci uint slowminfreq; 63862306a36Sopenharmony_ci u16 fpdelay; 63962306a36Sopenharmony_ci 64062306a36Sopenharmony_ci sii = container_of(sih, struct si_info, pub); 64162306a36Sopenharmony_ci if (ai_get_cccaps(sih) & CC_CAP_PMU) { 64262306a36Sopenharmony_ci fpdelay = si_pmu_fast_pwrup_delay(sih); 64362306a36Sopenharmony_ci return fpdelay; 64462306a36Sopenharmony_ci } 64562306a36Sopenharmony_ci 64662306a36Sopenharmony_ci if (!(ai_get_cccaps(sih) & CC_CAP_PWR_CTL)) 64762306a36Sopenharmony_ci return 0; 64862306a36Sopenharmony_ci 64962306a36Sopenharmony_ci fpdelay = 0; 65062306a36Sopenharmony_ci cc = sii->icbus->drv_cc.core; 65162306a36Sopenharmony_ci if (cc) { 65262306a36Sopenharmony_ci slowminfreq = ai_slowclk_freq(sih, false, cc); 65362306a36Sopenharmony_ci fpdelay = (((bcma_read32(cc, CHIPCREGOFFS(pll_on_delay)) + 2) 65462306a36Sopenharmony_ci * 1000000) + (slowminfreq - 1)) / slowminfreq; 65562306a36Sopenharmony_ci } 65662306a36Sopenharmony_ci return fpdelay; 65762306a36Sopenharmony_ci} 65862306a36Sopenharmony_ci 65962306a36Sopenharmony_ci/* 66062306a36Sopenharmony_ci * clock control policy function throught chipcommon 66162306a36Sopenharmony_ci * 66262306a36Sopenharmony_ci * set dynamic clk control mode (forceslow, forcefast, dynamic) 66362306a36Sopenharmony_ci * returns true if we are forcing fast clock 66462306a36Sopenharmony_ci * this is a wrapper over the next internal function 66562306a36Sopenharmony_ci * to allow flexible policy settings for outside caller 66662306a36Sopenharmony_ci */ 66762306a36Sopenharmony_cibool ai_clkctl_cc(struct si_pub *sih, enum bcma_clkmode mode) 66862306a36Sopenharmony_ci{ 66962306a36Sopenharmony_ci struct si_info *sii; 67062306a36Sopenharmony_ci struct bcma_device *cc; 67162306a36Sopenharmony_ci 67262306a36Sopenharmony_ci sii = container_of(sih, struct si_info, pub); 67362306a36Sopenharmony_ci 67462306a36Sopenharmony_ci cc = sii->icbus->drv_cc.core; 67562306a36Sopenharmony_ci bcma_core_set_clockmode(cc, mode); 67662306a36Sopenharmony_ci return mode == BCMA_CLKMODE_FAST; 67762306a36Sopenharmony_ci} 67862306a36Sopenharmony_ci 67962306a36Sopenharmony_ci/* Enable BT-COEX & Ex-PA for 4313 */ 68062306a36Sopenharmony_civoid ai_epa_4313war(struct si_pub *sih) 68162306a36Sopenharmony_ci{ 68262306a36Sopenharmony_ci struct si_info *sii = container_of(sih, struct si_info, pub); 68362306a36Sopenharmony_ci struct bcma_device *cc; 68462306a36Sopenharmony_ci 68562306a36Sopenharmony_ci cc = sii->icbus->drv_cc.core; 68662306a36Sopenharmony_ci 68762306a36Sopenharmony_ci /* EPA Fix */ 68862306a36Sopenharmony_ci bcma_set32(cc, CHIPCREGOFFS(gpiocontrol), GPIO_CTRL_EPA_EN_MASK); 68962306a36Sopenharmony_ci} 69062306a36Sopenharmony_ci 69162306a36Sopenharmony_ci/* check if the device is removed */ 69262306a36Sopenharmony_cibool ai_deviceremoved(struct si_pub *sih) 69362306a36Sopenharmony_ci{ 69462306a36Sopenharmony_ci u32 w = 0; 69562306a36Sopenharmony_ci struct si_info *sii; 69662306a36Sopenharmony_ci 69762306a36Sopenharmony_ci sii = container_of(sih, struct si_info, pub); 69862306a36Sopenharmony_ci 69962306a36Sopenharmony_ci if (sii->icbus->hosttype != BCMA_HOSTTYPE_PCI) 70062306a36Sopenharmony_ci return false; 70162306a36Sopenharmony_ci 70262306a36Sopenharmony_ci pci_read_config_dword(sii->pcibus, PCI_VENDOR_ID, &w); 70362306a36Sopenharmony_ci if ((w & 0xFFFF) != PCI_VENDOR_ID_BROADCOM) 70462306a36Sopenharmony_ci return true; 70562306a36Sopenharmony_ci 70662306a36Sopenharmony_ci return false; 70762306a36Sopenharmony_ci} 708