xref: /openbmc/linux/drivers/net/wireless/broadcom/brcm80211/brcmsmac/aiutils.c (revision 762f99f4f3cb41a775b5157dd761217beba65873)
1*05491d2cSKalle Valo /*
2*05491d2cSKalle Valo  * Copyright (c) 2010 Broadcom Corporation
3*05491d2cSKalle Valo  *
4*05491d2cSKalle Valo  * Permission to use, copy, modify, and/or distribute this software for any
5*05491d2cSKalle Valo  * purpose with or without fee is hereby granted, provided that the above
6*05491d2cSKalle Valo  * copyright notice and this permission notice appear in all copies.
7*05491d2cSKalle Valo  *
8*05491d2cSKalle Valo  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9*05491d2cSKalle Valo  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10*05491d2cSKalle Valo  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11*05491d2cSKalle Valo  * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12*05491d2cSKalle Valo  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13*05491d2cSKalle Valo  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14*05491d2cSKalle Valo  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15*05491d2cSKalle Valo  *
16*05491d2cSKalle Valo  * File contents: support functions for PCI/PCIe
17*05491d2cSKalle Valo  */
18*05491d2cSKalle Valo 
19*05491d2cSKalle Valo #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
20*05491d2cSKalle Valo 
21*05491d2cSKalle Valo #include <linux/delay.h>
22*05491d2cSKalle Valo 
23*05491d2cSKalle Valo #include <defs.h>
24*05491d2cSKalle Valo #include <chipcommon.h>
25*05491d2cSKalle Valo #include <brcmu_utils.h>
26*05491d2cSKalle Valo #include <brcm_hw_ids.h>
27*05491d2cSKalle Valo #include <soc.h>
28*05491d2cSKalle Valo #include "types.h"
29*05491d2cSKalle Valo #include "pub.h"
30*05491d2cSKalle Valo #include "pmu.h"
31*05491d2cSKalle Valo #include "aiutils.h"
32*05491d2cSKalle Valo 
33*05491d2cSKalle Valo /* slow_clk_ctl */
34*05491d2cSKalle Valo  /* slow clock source mask */
35*05491d2cSKalle Valo #define SCC_SS_MASK		0x00000007
36*05491d2cSKalle Valo  /* source of slow clock is LPO */
37*05491d2cSKalle Valo #define	SCC_SS_LPO		0x00000000
38*05491d2cSKalle Valo  /* source of slow clock is crystal */
39*05491d2cSKalle Valo #define	SCC_SS_XTAL		0x00000001
40*05491d2cSKalle Valo  /* source of slow clock is PCI */
41*05491d2cSKalle Valo #define	SCC_SS_PCI		0x00000002
42*05491d2cSKalle Valo  /* LPOFreqSel, 1: 160Khz, 0: 32KHz */
43*05491d2cSKalle Valo #define SCC_LF			0x00000200
44*05491d2cSKalle Valo  /* LPOPowerDown, 1: LPO is disabled, 0: LPO is enabled */
45*05491d2cSKalle Valo #define SCC_LP			0x00000400
46*05491d2cSKalle Valo  /* ForceSlowClk, 1: sb/cores running on slow clock, 0: power logic control */
47*05491d2cSKalle Valo #define SCC_FS			0x00000800
48*05491d2cSKalle Valo  /* IgnorePllOffReq, 1/0:
49*05491d2cSKalle Valo   *  power logic ignores/honors PLL clock disable requests from core
50*05491d2cSKalle Valo   */
51*05491d2cSKalle Valo #define SCC_IP			0x00001000
52*05491d2cSKalle Valo  /* XtalControlEn, 1/0:
53*05491d2cSKalle Valo   *  power logic does/doesn't disable crystal when appropriate
54*05491d2cSKalle Valo   */
55*05491d2cSKalle Valo #define SCC_XC			0x00002000
56*05491d2cSKalle Valo  /* XtalPU (RO), 1/0: crystal running/disabled */
57*05491d2cSKalle Valo #define SCC_XP			0x00004000
58*05491d2cSKalle Valo  /* ClockDivider (SlowClk = 1/(4+divisor)) */
59*05491d2cSKalle Valo #define SCC_CD_MASK		0xffff0000
60*05491d2cSKalle Valo #define SCC_CD_SHIFT		16
61*05491d2cSKalle Valo 
62*05491d2cSKalle Valo /* system_clk_ctl */
63*05491d2cSKalle Valo  /* ILPen: Enable Idle Low Power */
64*05491d2cSKalle Valo #define	SYCC_IE			0x00000001
65*05491d2cSKalle Valo  /* ALPen: Enable Active Low Power */
66*05491d2cSKalle Valo #define	SYCC_AE			0x00000002
67*05491d2cSKalle Valo  /* ForcePLLOn */
68*05491d2cSKalle Valo #define	SYCC_FP			0x00000004
69*05491d2cSKalle Valo  /* Force ALP (or HT if ALPen is not set */
70*05491d2cSKalle Valo #define	SYCC_AR			0x00000008
71*05491d2cSKalle Valo  /* Force HT */
72*05491d2cSKalle Valo #define	SYCC_HR			0x00000010
73*05491d2cSKalle Valo  /* ClkDiv  (ILP = 1/(4 * (divisor + 1)) */
74*05491d2cSKalle Valo #define SYCC_CD_MASK		0xffff0000
75*05491d2cSKalle Valo #define SYCC_CD_SHIFT		16
76*05491d2cSKalle Valo 
77*05491d2cSKalle Valo #define CST4329_SPROM_OTP_SEL_MASK	0x00000003
78*05491d2cSKalle Valo  /* OTP is powered up, use def. CIS, no SPROM */
79*05491d2cSKalle Valo #define CST4329_DEFCIS_SEL		0
80*05491d2cSKalle Valo  /* OTP is powered up, SPROM is present */
81*05491d2cSKalle Valo #define CST4329_SPROM_SEL		1
82*05491d2cSKalle Valo  /* OTP is powered up, no SPROM */
83*05491d2cSKalle Valo #define CST4329_OTP_SEL			2
84*05491d2cSKalle Valo  /* OTP is powered down, SPROM is present */
85*05491d2cSKalle Valo #define CST4329_OTP_PWRDN		3
86*05491d2cSKalle Valo 
87*05491d2cSKalle Valo #define CST4329_SPI_SDIO_MODE_MASK	0x00000004
88*05491d2cSKalle Valo #define CST4329_SPI_SDIO_MODE_SHIFT	2
89*05491d2cSKalle Valo 
90*05491d2cSKalle Valo /* 43224 chip-specific ChipControl register bits */
91*05491d2cSKalle Valo #define CCTRL43224_GPIO_TOGGLE          0x8000
92*05491d2cSKalle Valo  /* 12 mA drive strength */
93*05491d2cSKalle Valo #define CCTRL_43224A0_12MA_LED_DRIVE    0x00F000F0
94*05491d2cSKalle Valo  /* 12 mA drive strength for later 43224s */
95*05491d2cSKalle Valo #define CCTRL_43224B0_12MA_LED_DRIVE    0xF0
96*05491d2cSKalle Valo 
97*05491d2cSKalle Valo /* 43236 Chip specific ChipStatus register bits */
98*05491d2cSKalle Valo #define CST43236_SFLASH_MASK		0x00000040
99*05491d2cSKalle Valo #define CST43236_OTP_MASK		0x00000080
100*05491d2cSKalle Valo #define CST43236_HSIC_MASK		0x00000100	/* USB/HSIC */
101*05491d2cSKalle Valo #define CST43236_BP_CLK			0x00000200	/* 120/96Mbps */
102*05491d2cSKalle Valo #define CST43236_BOOT_MASK		0x00001800
103*05491d2cSKalle Valo #define CST43236_BOOT_SHIFT		11
104*05491d2cSKalle Valo #define CST43236_BOOT_FROM_SRAM		0 /* boot from SRAM, ARM in reset */
105*05491d2cSKalle Valo #define CST43236_BOOT_FROM_ROM		1 /* boot from ROM */
106*05491d2cSKalle Valo #define CST43236_BOOT_FROM_FLASH	2 /* boot from FLASH */
107*05491d2cSKalle Valo #define CST43236_BOOT_FROM_INVALID	3
108*05491d2cSKalle Valo 
109*05491d2cSKalle Valo /* 4331 chip-specific ChipControl register bits */
110*05491d2cSKalle Valo  /* 0 disable */
111*05491d2cSKalle Valo #define CCTRL4331_BT_COEXIST		(1<<0)
112*05491d2cSKalle Valo  /* 0 SECI is disabled (JTAG functional) */
113*05491d2cSKalle Valo #define CCTRL4331_SECI			(1<<1)
114*05491d2cSKalle Valo  /* 0 disable */
115*05491d2cSKalle Valo #define CCTRL4331_EXT_LNA		(1<<2)
116*05491d2cSKalle Valo  /* sprom/gpio13-15 mux */
117*05491d2cSKalle Valo #define CCTRL4331_SPROM_GPIO13_15       (1<<3)
118*05491d2cSKalle Valo  /* 0 ext pa disable, 1 ext pa enabled */
119*05491d2cSKalle Valo #define CCTRL4331_EXTPA_EN		(1<<4)
120*05491d2cSKalle Valo  /* set drive out GPIO_CLK on sprom_cs pin */
121*05491d2cSKalle Valo #define CCTRL4331_GPIOCLK_ON_SPROMCS	(1<<5)
122*05491d2cSKalle Valo  /* use sprom_cs pin as PCIE mdio interface */
123*05491d2cSKalle Valo #define CCTRL4331_PCIE_MDIO_ON_SPROMCS	(1<<6)
124*05491d2cSKalle Valo  /* aband extpa will be at gpio2/5 and sprom_dout */
125*05491d2cSKalle Valo #define CCTRL4331_EXTPA_ON_GPIO2_5	(1<<7)
126*05491d2cSKalle Valo  /* override core control on pipe_AuxClkEnable */
127*05491d2cSKalle Valo #define CCTRL4331_OVR_PIPEAUXCLKEN	(1<<8)
128*05491d2cSKalle Valo  /* override core control on pipe_AuxPowerDown */
129*05491d2cSKalle Valo #define CCTRL4331_OVR_PIPEAUXPWRDOWN	(1<<9)
130*05491d2cSKalle Valo  /* pcie_auxclkenable */
131*05491d2cSKalle Valo #define CCTRL4331_PCIE_AUXCLKEN		(1<<10)
132*05491d2cSKalle Valo  /* pcie_pipe_pllpowerdown */
133*05491d2cSKalle Valo #define CCTRL4331_PCIE_PIPE_PLLDOWN	(1<<11)
134*05491d2cSKalle Valo  /* enable bt_shd0 at gpio4 */
135*05491d2cSKalle Valo #define CCTRL4331_BT_SHD0_ON_GPIO4	(1<<16)
136*05491d2cSKalle Valo  /* enable bt_shd1 at gpio5 */
137*05491d2cSKalle Valo #define CCTRL4331_BT_SHD1_ON_GPIO5	(1<<17)
138*05491d2cSKalle Valo 
139*05491d2cSKalle Valo /* 4331 Chip specific ChipStatus register bits */
140*05491d2cSKalle Valo  /* crystal frequency 20/40Mhz */
141*05491d2cSKalle Valo #define	CST4331_XTAL_FREQ		0x00000001
142*05491d2cSKalle Valo #define	CST4331_SPROM_PRESENT		0x00000002
143*05491d2cSKalle Valo #define	CST4331_OTP_PRESENT		0x00000004
144*05491d2cSKalle Valo #define	CST4331_LDO_RF			0x00000008
145*05491d2cSKalle Valo #define	CST4331_LDO_PAR			0x00000010
146*05491d2cSKalle Valo 
147*05491d2cSKalle Valo /* 4319 chip-specific ChipStatus register bits */
148*05491d2cSKalle Valo #define	CST4319_SPI_CPULESSUSB		0x00000001
149*05491d2cSKalle Valo #define	CST4319_SPI_CLK_POL		0x00000002
150*05491d2cSKalle Valo #define	CST4319_SPI_CLK_PH		0x00000008
151*05491d2cSKalle Valo  /* gpio [7:6], SDIO CIS selection */
152*05491d2cSKalle Valo #define	CST4319_SPROM_OTP_SEL_MASK	0x000000c0
153*05491d2cSKalle Valo #define	CST4319_SPROM_OTP_SEL_SHIFT	6
154*05491d2cSKalle Valo  /* use default CIS, OTP is powered up */
155*05491d2cSKalle Valo #define	CST4319_DEFCIS_SEL		0x00000000
156*05491d2cSKalle Valo  /* use SPROM, OTP is powered up */
157*05491d2cSKalle Valo #define	CST4319_SPROM_SEL		0x00000040
158*05491d2cSKalle Valo  /* use OTP, OTP is powered up */
159*05491d2cSKalle Valo #define	CST4319_OTP_SEL			0x00000080
160*05491d2cSKalle Valo  /* use SPROM, OTP is powered down */
161*05491d2cSKalle Valo #define	CST4319_OTP_PWRDN		0x000000c0
162*05491d2cSKalle Valo  /* gpio [8], sdio/usb mode */
163*05491d2cSKalle Valo #define	CST4319_SDIO_USB_MODE		0x00000100
164*05491d2cSKalle Valo #define	CST4319_REMAP_SEL_MASK		0x00000600
165*05491d2cSKalle Valo #define	CST4319_ILPDIV_EN		0x00000800
166*05491d2cSKalle Valo #define	CST4319_XTAL_PD_POL		0x00001000
167*05491d2cSKalle Valo #define	CST4319_LPO_SEL			0x00002000
168*05491d2cSKalle Valo #define	CST4319_RES_INIT_MODE		0x0000c000
169*05491d2cSKalle Valo  /* PALDO is configured with external PNP */
170*05491d2cSKalle Valo #define	CST4319_PALDO_EXTPNP		0x00010000
171*05491d2cSKalle Valo #define	CST4319_CBUCK_MODE_MASK		0x00060000
172*05491d2cSKalle Valo #define CST4319_CBUCK_MODE_BURST	0x00020000
173*05491d2cSKalle Valo #define CST4319_CBUCK_MODE_LPBURST	0x00060000
174*05491d2cSKalle Valo #define	CST4319_RCAL_VALID		0x01000000
175*05491d2cSKalle Valo #define	CST4319_RCAL_VALUE_MASK		0x3e000000
176*05491d2cSKalle Valo #define	CST4319_RCAL_VALUE_SHIFT	25
177*05491d2cSKalle Valo 
178*05491d2cSKalle Valo /* 4336 chip-specific ChipStatus register bits */
179*05491d2cSKalle Valo #define	CST4336_SPI_MODE_MASK		0x00000001
180*05491d2cSKalle Valo #define	CST4336_SPROM_PRESENT		0x00000002
181*05491d2cSKalle Valo #define	CST4336_OTP_PRESENT		0x00000004
182*05491d2cSKalle Valo #define	CST4336_ARMREMAP_0		0x00000008
183*05491d2cSKalle Valo #define	CST4336_ILPDIV_EN_MASK		0x00000010
184*05491d2cSKalle Valo #define	CST4336_ILPDIV_EN_SHIFT		4
185*05491d2cSKalle Valo #define	CST4336_XTAL_PD_POL_MASK	0x00000020
186*05491d2cSKalle Valo #define	CST4336_XTAL_PD_POL_SHIFT	5
187*05491d2cSKalle Valo #define	CST4336_LPO_SEL_MASK		0x00000040
188*05491d2cSKalle Valo #define	CST4336_LPO_SEL_SHIFT		6
189*05491d2cSKalle Valo #define	CST4336_RES_INIT_MODE_MASK	0x00000180
190*05491d2cSKalle Valo #define	CST4336_RES_INIT_MODE_SHIFT	7
191*05491d2cSKalle Valo #define	CST4336_CBUCK_MODE_MASK		0x00000600
192*05491d2cSKalle Valo #define	CST4336_CBUCK_MODE_SHIFT	9
193*05491d2cSKalle Valo 
194*05491d2cSKalle Valo /* 4313 chip-specific ChipStatus register bits */
195*05491d2cSKalle Valo #define	CST4313_SPROM_PRESENT			1
196*05491d2cSKalle Valo #define	CST4313_OTP_PRESENT			2
197*05491d2cSKalle Valo #define	CST4313_SPROM_OTP_SEL_MASK		0x00000002
198*05491d2cSKalle Valo #define	CST4313_SPROM_OTP_SEL_SHIFT		0
199*05491d2cSKalle Valo 
200*05491d2cSKalle Valo /* 4313 Chip specific ChipControl register bits */
201*05491d2cSKalle Valo  /* 12 mA drive strengh for later 4313 */
202*05491d2cSKalle Valo #define CCTRL_4313_12MA_LED_DRIVE    0x00000007
203*05491d2cSKalle Valo 
204*05491d2cSKalle Valo /* Manufacturer Ids */
205*05491d2cSKalle Valo #define	MFGID_ARM		0x43b
206*05491d2cSKalle Valo #define	MFGID_BRCM		0x4bf
207*05491d2cSKalle Valo #define	MFGID_MIPS		0x4a7
208*05491d2cSKalle Valo 
209*05491d2cSKalle Valo /* Enumeration ROM registers */
210*05491d2cSKalle Valo #define	ER_EROMENTRY		0x000
211*05491d2cSKalle Valo #define	ER_REMAPCONTROL		0xe00
212*05491d2cSKalle Valo #define	ER_REMAPSELECT		0xe04
213*05491d2cSKalle Valo #define	ER_MASTERSELECT		0xe10
214*05491d2cSKalle Valo #define	ER_ITCR			0xf00
215*05491d2cSKalle Valo #define	ER_ITIP			0xf04
216*05491d2cSKalle Valo 
217*05491d2cSKalle Valo /* Erom entries */
218*05491d2cSKalle Valo #define	ER_TAG			0xe
219*05491d2cSKalle Valo #define	ER_TAG1			0x6
220*05491d2cSKalle Valo #define	ER_VALID		1
221*05491d2cSKalle Valo #define	ER_CI			0
222*05491d2cSKalle Valo #define	ER_MP			2
223*05491d2cSKalle Valo #define	ER_ADD			4
224*05491d2cSKalle Valo #define	ER_END			0xe
225*05491d2cSKalle Valo #define	ER_BAD			0xffffffff
226*05491d2cSKalle Valo 
227*05491d2cSKalle Valo /* EROM CompIdentA */
228*05491d2cSKalle Valo #define	CIA_MFG_MASK		0xfff00000
229*05491d2cSKalle Valo #define	CIA_MFG_SHIFT		20
230*05491d2cSKalle Valo #define	CIA_CID_MASK		0x000fff00
231*05491d2cSKalle Valo #define	CIA_CID_SHIFT		8
232*05491d2cSKalle Valo #define	CIA_CCL_MASK		0x000000f0
233*05491d2cSKalle Valo #define	CIA_CCL_SHIFT		4
234*05491d2cSKalle Valo 
235*05491d2cSKalle Valo /* EROM CompIdentB */
236*05491d2cSKalle Valo #define	CIB_REV_MASK		0xff000000
237*05491d2cSKalle Valo #define	CIB_REV_SHIFT		24
238*05491d2cSKalle Valo #define	CIB_NSW_MASK		0x00f80000
239*05491d2cSKalle Valo #define	CIB_NSW_SHIFT		19
240*05491d2cSKalle Valo #define	CIB_NMW_MASK		0x0007c000
241*05491d2cSKalle Valo #define	CIB_NMW_SHIFT		14
242*05491d2cSKalle Valo #define	CIB_NSP_MASK		0x00003e00
243*05491d2cSKalle Valo #define	CIB_NSP_SHIFT		9
244*05491d2cSKalle Valo #define	CIB_NMP_MASK		0x000001f0
245*05491d2cSKalle Valo #define	CIB_NMP_SHIFT		4
246*05491d2cSKalle Valo 
247*05491d2cSKalle Valo /* EROM AddrDesc */
248*05491d2cSKalle Valo #define	AD_ADDR_MASK		0xfffff000
249*05491d2cSKalle Valo #define	AD_SP_MASK		0x00000f00
250*05491d2cSKalle Valo #define	AD_SP_SHIFT		8
251*05491d2cSKalle Valo #define	AD_ST_MASK		0x000000c0
252*05491d2cSKalle Valo #define	AD_ST_SHIFT		6
253*05491d2cSKalle Valo #define	AD_ST_SLAVE		0x00000000
254*05491d2cSKalle Valo #define	AD_ST_BRIDGE		0x00000040
255*05491d2cSKalle Valo #define	AD_ST_SWRAP		0x00000080
256*05491d2cSKalle Valo #define	AD_ST_MWRAP		0x000000c0
257*05491d2cSKalle Valo #define	AD_SZ_MASK		0x00000030
258*05491d2cSKalle Valo #define	AD_SZ_SHIFT		4
259*05491d2cSKalle Valo #define	AD_SZ_4K		0x00000000
260*05491d2cSKalle Valo #define	AD_SZ_8K		0x00000010
261*05491d2cSKalle Valo #define	AD_SZ_16K		0x00000020
262*05491d2cSKalle Valo #define	AD_SZ_SZD		0x00000030
263*05491d2cSKalle Valo #define	AD_AG32			0x00000008
264*05491d2cSKalle Valo #define	AD_ADDR_ALIGN		0x00000fff
265*05491d2cSKalle Valo #define	AD_SZ_BASE		0x00001000	/* 4KB */
266*05491d2cSKalle Valo 
267*05491d2cSKalle Valo /* EROM SizeDesc */
268*05491d2cSKalle Valo #define	SD_SZ_MASK		0xfffff000
269*05491d2cSKalle Valo #define	SD_SG32			0x00000008
270*05491d2cSKalle Valo #define	SD_SZ_ALIGN		0x00000fff
271*05491d2cSKalle Valo 
272*05491d2cSKalle Valo /* PCI config space bit 4 for 4306c0 slow clock source */
273*05491d2cSKalle Valo #define	PCI_CFG_GPIO_SCS	0x10
274*05491d2cSKalle Valo /* PCI config space GPIO 14 for Xtal power-up */
275*05491d2cSKalle Valo #define PCI_CFG_GPIO_XTAL	0x40
276*05491d2cSKalle Valo /* PCI config space GPIO 15 for PLL power-down */
277*05491d2cSKalle Valo #define PCI_CFG_GPIO_PLL	0x80
278*05491d2cSKalle Valo 
279*05491d2cSKalle Valo /* power control defines */
280*05491d2cSKalle Valo #define PLL_DELAY		150	/* us pll on delay */
281*05491d2cSKalle Valo #define FREF_DELAY		200	/* us fref change delay */
282*05491d2cSKalle Valo #define	XTAL_ON_DELAY		1000	/* us crystal power-on delay */
283*05491d2cSKalle Valo 
284*05491d2cSKalle Valo /* resetctrl */
285*05491d2cSKalle Valo #define	AIRC_RESET		1
286*05491d2cSKalle Valo 
287*05491d2cSKalle Valo #define	NOREV		-1	/* Invalid rev */
288*05491d2cSKalle Valo 
289*05491d2cSKalle Valo /* GPIO Based LED powersave defines */
290*05491d2cSKalle Valo #define DEFAULT_GPIO_ONTIME	10	/* Default: 10% on */
291*05491d2cSKalle Valo #define DEFAULT_GPIO_OFFTIME	90	/* Default: 10% on */
292*05491d2cSKalle Valo 
293*05491d2cSKalle Valo /* When Srom support present, fields in sromcontrol */
294*05491d2cSKalle Valo #define	SRC_START		0x80000000
295*05491d2cSKalle Valo #define	SRC_BUSY		0x80000000
296*05491d2cSKalle Valo #define	SRC_OPCODE		0x60000000
297*05491d2cSKalle Valo #define	SRC_OP_READ		0x00000000
298*05491d2cSKalle Valo #define	SRC_OP_WRITE		0x20000000
299*05491d2cSKalle Valo #define	SRC_OP_WRDIS		0x40000000
300*05491d2cSKalle Valo #define	SRC_OP_WREN		0x60000000
301*05491d2cSKalle Valo #define	SRC_OTPSEL		0x00000010
302*05491d2cSKalle Valo #define	SRC_LOCK		0x00000008
303*05491d2cSKalle Valo #define	SRC_SIZE_MASK		0x00000006
304*05491d2cSKalle Valo #define	SRC_SIZE_1K		0x00000000
305*05491d2cSKalle Valo #define	SRC_SIZE_4K		0x00000002
306*05491d2cSKalle Valo #define	SRC_SIZE_16K		0x00000004
307*05491d2cSKalle Valo #define	SRC_SIZE_SHIFT		1
308*05491d2cSKalle Valo #define	SRC_PRESENT		0x00000001
309*05491d2cSKalle Valo 
310*05491d2cSKalle Valo /* External PA enable mask */
311*05491d2cSKalle Valo #define GPIO_CTRL_EPA_EN_MASK 0x40
312*05491d2cSKalle Valo 
313*05491d2cSKalle Valo #define DEFAULT_GPIOTIMERVAL \
314*05491d2cSKalle Valo 	((DEFAULT_GPIO_ONTIME << GPIO_ONTIME_SHIFT) | DEFAULT_GPIO_OFFTIME)
315*05491d2cSKalle Valo 
316*05491d2cSKalle Valo #define	BADIDX		(SI_MAXCORES + 1)
317*05491d2cSKalle Valo 
318*05491d2cSKalle Valo #define	IS_SIM(chippkg)	\
319*05491d2cSKalle Valo 	((chippkg == HDLSIM_PKG_ID) || (chippkg == HWSIM_PKG_ID))
320*05491d2cSKalle Valo 
321*05491d2cSKalle Valo #define	GOODCOREADDR(x, b) \
322*05491d2cSKalle Valo 	(((x) >= (b)) && ((x) < ((b) + SI_MAXCORES * SI_CORE_SIZE)) && \
323*05491d2cSKalle Valo 		IS_ALIGNED((x), SI_CORE_SIZE))
324*05491d2cSKalle Valo 
325*05491d2cSKalle Valo struct aidmp {
326*05491d2cSKalle Valo 	u32 oobselina30;	/* 0x000 */
327*05491d2cSKalle Valo 	u32 oobselina74;	/* 0x004 */
328*05491d2cSKalle Valo 	u32 PAD[6];
329*05491d2cSKalle Valo 	u32 oobselinb30;	/* 0x020 */
330*05491d2cSKalle Valo 	u32 oobselinb74;	/* 0x024 */
331*05491d2cSKalle Valo 	u32 PAD[6];
332*05491d2cSKalle Valo 	u32 oobselinc30;	/* 0x040 */
333*05491d2cSKalle Valo 	u32 oobselinc74;	/* 0x044 */
334*05491d2cSKalle Valo 	u32 PAD[6];
335*05491d2cSKalle Valo 	u32 oobselind30;	/* 0x060 */
336*05491d2cSKalle Valo 	u32 oobselind74;	/* 0x064 */
337*05491d2cSKalle Valo 	u32 PAD[38];
338*05491d2cSKalle Valo 	u32 oobselouta30;	/* 0x100 */
339*05491d2cSKalle Valo 	u32 oobselouta74;	/* 0x104 */
340*05491d2cSKalle Valo 	u32 PAD[6];
341*05491d2cSKalle Valo 	u32 oobseloutb30;	/* 0x120 */
342*05491d2cSKalle Valo 	u32 oobseloutb74;	/* 0x124 */
343*05491d2cSKalle Valo 	u32 PAD[6];
344*05491d2cSKalle Valo 	u32 oobseloutc30;	/* 0x140 */
345*05491d2cSKalle Valo 	u32 oobseloutc74;	/* 0x144 */
346*05491d2cSKalle Valo 	u32 PAD[6];
347*05491d2cSKalle Valo 	u32 oobseloutd30;	/* 0x160 */
348*05491d2cSKalle Valo 	u32 oobseloutd74;	/* 0x164 */
349*05491d2cSKalle Valo 	u32 PAD[38];
350*05491d2cSKalle Valo 	u32 oobsynca;	/* 0x200 */
351*05491d2cSKalle Valo 	u32 oobseloutaen;	/* 0x204 */
352*05491d2cSKalle Valo 	u32 PAD[6];
353*05491d2cSKalle Valo 	u32 oobsyncb;	/* 0x220 */
354*05491d2cSKalle Valo 	u32 oobseloutben;	/* 0x224 */
355*05491d2cSKalle Valo 	u32 PAD[6];
356*05491d2cSKalle Valo 	u32 oobsyncc;	/* 0x240 */
357*05491d2cSKalle Valo 	u32 oobseloutcen;	/* 0x244 */
358*05491d2cSKalle Valo 	u32 PAD[6];
359*05491d2cSKalle Valo 	u32 oobsyncd;	/* 0x260 */
360*05491d2cSKalle Valo 	u32 oobseloutden;	/* 0x264 */
361*05491d2cSKalle Valo 	u32 PAD[38];
362*05491d2cSKalle Valo 	u32 oobaextwidth;	/* 0x300 */
363*05491d2cSKalle Valo 	u32 oobainwidth;	/* 0x304 */
364*05491d2cSKalle Valo 	u32 oobaoutwidth;	/* 0x308 */
365*05491d2cSKalle Valo 	u32 PAD[5];
366*05491d2cSKalle Valo 	u32 oobbextwidth;	/* 0x320 */
367*05491d2cSKalle Valo 	u32 oobbinwidth;	/* 0x324 */
368*05491d2cSKalle Valo 	u32 oobboutwidth;	/* 0x328 */
369*05491d2cSKalle Valo 	u32 PAD[5];
370*05491d2cSKalle Valo 	u32 oobcextwidth;	/* 0x340 */
371*05491d2cSKalle Valo 	u32 oobcinwidth;	/* 0x344 */
372*05491d2cSKalle Valo 	u32 oobcoutwidth;	/* 0x348 */
373*05491d2cSKalle Valo 	u32 PAD[5];
374*05491d2cSKalle Valo 	u32 oobdextwidth;	/* 0x360 */
375*05491d2cSKalle Valo 	u32 oobdinwidth;	/* 0x364 */
376*05491d2cSKalle Valo 	u32 oobdoutwidth;	/* 0x368 */
377*05491d2cSKalle Valo 	u32 PAD[37];
378*05491d2cSKalle Valo 	u32 ioctrlset;	/* 0x400 */
379*05491d2cSKalle Valo 	u32 ioctrlclear;	/* 0x404 */
380*05491d2cSKalle Valo 	u32 ioctrl;		/* 0x408 */
381*05491d2cSKalle Valo 	u32 PAD[61];
382*05491d2cSKalle Valo 	u32 iostatus;	/* 0x500 */
383*05491d2cSKalle Valo 	u32 PAD[127];
384*05491d2cSKalle Valo 	u32 ioctrlwidth;	/* 0x700 */
385*05491d2cSKalle Valo 	u32 iostatuswidth;	/* 0x704 */
386*05491d2cSKalle Valo 	u32 PAD[62];
387*05491d2cSKalle Valo 	u32 resetctrl;	/* 0x800 */
388*05491d2cSKalle Valo 	u32 resetstatus;	/* 0x804 */
389*05491d2cSKalle Valo 	u32 resetreadid;	/* 0x808 */
390*05491d2cSKalle Valo 	u32 resetwriteid;	/* 0x80c */
391*05491d2cSKalle Valo 	u32 PAD[60];
392*05491d2cSKalle Valo 	u32 errlogctrl;	/* 0x900 */
393*05491d2cSKalle Valo 	u32 errlogdone;	/* 0x904 */
394*05491d2cSKalle Valo 	u32 errlogstatus;	/* 0x908 */
395*05491d2cSKalle Valo 	u32 errlogaddrlo;	/* 0x90c */
396*05491d2cSKalle Valo 	u32 errlogaddrhi;	/* 0x910 */
397*05491d2cSKalle Valo 	u32 errlogid;	/* 0x914 */
398*05491d2cSKalle Valo 	u32 errloguser;	/* 0x918 */
399*05491d2cSKalle Valo 	u32 errlogflags;	/* 0x91c */
400*05491d2cSKalle Valo 	u32 PAD[56];
401*05491d2cSKalle Valo 	u32 intstatus;	/* 0xa00 */
402*05491d2cSKalle Valo 	u32 PAD[127];
403*05491d2cSKalle Valo 	u32 config;		/* 0xe00 */
404*05491d2cSKalle Valo 	u32 PAD[63];
405*05491d2cSKalle Valo 	u32 itcr;		/* 0xf00 */
406*05491d2cSKalle Valo 	u32 PAD[3];
407*05491d2cSKalle Valo 	u32 itipooba;	/* 0xf10 */
408*05491d2cSKalle Valo 	u32 itipoobb;	/* 0xf14 */
409*05491d2cSKalle Valo 	u32 itipoobc;	/* 0xf18 */
410*05491d2cSKalle Valo 	u32 itipoobd;	/* 0xf1c */
411*05491d2cSKalle Valo 	u32 PAD[4];
412*05491d2cSKalle Valo 	u32 itipoobaout;	/* 0xf30 */
413*05491d2cSKalle Valo 	u32 itipoobbout;	/* 0xf34 */
414*05491d2cSKalle Valo 	u32 itipoobcout;	/* 0xf38 */
415*05491d2cSKalle Valo 	u32 itipoobdout;	/* 0xf3c */
416*05491d2cSKalle Valo 	u32 PAD[4];
417*05491d2cSKalle Valo 	u32 itopooba;	/* 0xf50 */
418*05491d2cSKalle Valo 	u32 itopoobb;	/* 0xf54 */
419*05491d2cSKalle Valo 	u32 itopoobc;	/* 0xf58 */
420*05491d2cSKalle Valo 	u32 itopoobd;	/* 0xf5c */
421*05491d2cSKalle Valo 	u32 PAD[4];
422*05491d2cSKalle Valo 	u32 itopoobain;	/* 0xf70 */
423*05491d2cSKalle Valo 	u32 itopoobbin;	/* 0xf74 */
424*05491d2cSKalle Valo 	u32 itopoobcin;	/* 0xf78 */
425*05491d2cSKalle Valo 	u32 itopoobdin;	/* 0xf7c */
426*05491d2cSKalle Valo 	u32 PAD[4];
427*05491d2cSKalle Valo 	u32 itopreset;	/* 0xf90 */
428*05491d2cSKalle Valo 	u32 PAD[15];
429*05491d2cSKalle Valo 	u32 peripherialid4;	/* 0xfd0 */
430*05491d2cSKalle Valo 	u32 peripherialid5;	/* 0xfd4 */
431*05491d2cSKalle Valo 	u32 peripherialid6;	/* 0xfd8 */
432*05491d2cSKalle Valo 	u32 peripherialid7;	/* 0xfdc */
433*05491d2cSKalle Valo 	u32 peripherialid0;	/* 0xfe0 */
434*05491d2cSKalle Valo 	u32 peripherialid1;	/* 0xfe4 */
435*05491d2cSKalle Valo 	u32 peripherialid2;	/* 0xfe8 */
436*05491d2cSKalle Valo 	u32 peripherialid3;	/* 0xfec */
437*05491d2cSKalle Valo 	u32 componentid0;	/* 0xff0 */
438*05491d2cSKalle Valo 	u32 componentid1;	/* 0xff4 */
439*05491d2cSKalle Valo 	u32 componentid2;	/* 0xff8 */
440*05491d2cSKalle Valo 	u32 componentid3;	/* 0xffc */
441*05491d2cSKalle Valo };
442*05491d2cSKalle Valo 
443*05491d2cSKalle Valo static bool
ai_buscore_setup(struct si_info * sii,struct bcma_device * cc)444*05491d2cSKalle Valo ai_buscore_setup(struct si_info *sii, struct bcma_device *cc)
445*05491d2cSKalle Valo {
446*05491d2cSKalle Valo 	/* no cores found, bail out */
447*05491d2cSKalle Valo 	if (cc->bus->nr_cores == 0)
448*05491d2cSKalle Valo 		return false;
449*05491d2cSKalle Valo 
450*05491d2cSKalle Valo 	/* get chipcommon rev */
451*05491d2cSKalle Valo 	sii->pub.ccrev = cc->id.rev;
452*05491d2cSKalle Valo 
453*05491d2cSKalle Valo 	/* get chipcommon chipstatus */
454*05491d2cSKalle Valo 	sii->chipst = bcma_read32(cc, CHIPCREGOFFS(chipstatus));
455*05491d2cSKalle Valo 
456*05491d2cSKalle Valo 	/* get chipcommon capabilites */
457*05491d2cSKalle Valo 	sii->pub.cccaps = bcma_read32(cc, CHIPCREGOFFS(capabilities));
458*05491d2cSKalle Valo 
459*05491d2cSKalle Valo 	/* get pmu rev and caps */
460*05491d2cSKalle Valo 	if (ai_get_cccaps(&sii->pub) & CC_CAP_PMU) {
461*05491d2cSKalle Valo 		sii->pub.pmucaps = bcma_read32(cc,
462*05491d2cSKalle Valo 					       CHIPCREGOFFS(pmucapabilities));
463*05491d2cSKalle Valo 		sii->pub.pmurev = sii->pub.pmucaps & PCAP_REV_MASK;
464*05491d2cSKalle Valo 	}
465*05491d2cSKalle Valo 
466*05491d2cSKalle Valo 	return true;
467*05491d2cSKalle Valo }
468*05491d2cSKalle Valo 
ai_doattach(struct si_info * sii,struct bcma_bus * pbus)469*05491d2cSKalle Valo static struct si_info *ai_doattach(struct si_info *sii,
470*05491d2cSKalle Valo 				   struct bcma_bus *pbus)
471*05491d2cSKalle Valo {
472*05491d2cSKalle Valo 	struct si_pub *sih = &sii->pub;
473*05491d2cSKalle Valo 	struct bcma_device *cc;
474*05491d2cSKalle Valo 
475*05491d2cSKalle Valo 	sii->icbus = pbus;
476*05491d2cSKalle Valo 	sii->pcibus = pbus->host_pci;
477*05491d2cSKalle Valo 
478*05491d2cSKalle Valo 	/* switch to Chipcommon core */
479*05491d2cSKalle Valo 	cc = pbus->drv_cc.core;
480*05491d2cSKalle Valo 
481*05491d2cSKalle Valo 	sih->chip = pbus->chipinfo.id;
482*05491d2cSKalle Valo 	sih->chiprev = pbus->chipinfo.rev;
483*05491d2cSKalle Valo 	sih->chippkg = pbus->chipinfo.pkg;
484*05491d2cSKalle Valo 	sih->boardvendor = pbus->boardinfo.vendor;
485*05491d2cSKalle Valo 	sih->boardtype = pbus->boardinfo.type;
486*05491d2cSKalle Valo 
487*05491d2cSKalle Valo 	if (!ai_buscore_setup(sii, cc))
488*05491d2cSKalle Valo 		goto exit;
489*05491d2cSKalle Valo 
490*05491d2cSKalle Valo 	/* === NVRAM, clock is ready === */
491*05491d2cSKalle Valo 	bcma_write32(cc, CHIPCREGOFFS(gpiopullup), 0);
492*05491d2cSKalle Valo 	bcma_write32(cc, CHIPCREGOFFS(gpiopulldown), 0);
493*05491d2cSKalle Valo 
494*05491d2cSKalle Valo 	/* PMU specific initializations */
495*05491d2cSKalle Valo 	if (ai_get_cccaps(sih) & CC_CAP_PMU) {
496*05491d2cSKalle Valo 		(void)si_pmu_measure_alpclk(sih);
497*05491d2cSKalle Valo 	}
498*05491d2cSKalle Valo 
499*05491d2cSKalle Valo 	return sii;
500*05491d2cSKalle Valo 
501*05491d2cSKalle Valo  exit:
502*05491d2cSKalle Valo 
503*05491d2cSKalle Valo 	return NULL;
504*05491d2cSKalle Valo }
505*05491d2cSKalle Valo 
506*05491d2cSKalle Valo /*
507*05491d2cSKalle Valo  * Allocate a si handle and do the attach.
508*05491d2cSKalle Valo  */
509*05491d2cSKalle Valo struct si_pub *
ai_attach(struct bcma_bus * pbus)510*05491d2cSKalle Valo ai_attach(struct bcma_bus *pbus)
511*05491d2cSKalle Valo {
512*05491d2cSKalle Valo 	struct si_info *sii;
513*05491d2cSKalle Valo 
514*05491d2cSKalle Valo 	/* alloc struct si_info */
515*05491d2cSKalle Valo 	sii = kzalloc(sizeof(struct si_info), GFP_ATOMIC);
516*05491d2cSKalle Valo 	if (sii == NULL)
517*05491d2cSKalle Valo 		return NULL;
518*05491d2cSKalle Valo 
519*05491d2cSKalle Valo 	if (ai_doattach(sii, pbus) == NULL) {
520*05491d2cSKalle Valo 		kfree(sii);
521*05491d2cSKalle Valo 		return NULL;
522*05491d2cSKalle Valo 	}
523*05491d2cSKalle Valo 
524*05491d2cSKalle Valo 	return (struct si_pub *) sii;
525*05491d2cSKalle Valo }
526*05491d2cSKalle Valo 
527*05491d2cSKalle Valo /* may be called with core in reset */
ai_detach(struct si_pub * sih)528*05491d2cSKalle Valo void ai_detach(struct si_pub *sih)
529*05491d2cSKalle Valo {
530*05491d2cSKalle Valo 	struct si_info *sii;
531*05491d2cSKalle Valo 
532*05491d2cSKalle Valo 	sii = container_of(sih, struct si_info, pub);
533*05491d2cSKalle Valo 
534*05491d2cSKalle Valo 	kfree(sii);
535*05491d2cSKalle Valo }
536*05491d2cSKalle Valo 
537*05491d2cSKalle Valo /*
538*05491d2cSKalle Valo  * read/modify chipcommon core register.
539*05491d2cSKalle Valo  */
ai_cc_reg(struct si_pub * sih,uint regoff,u32 mask,u32 val)540*05491d2cSKalle Valo uint ai_cc_reg(struct si_pub *sih, uint regoff, u32 mask, u32 val)
541*05491d2cSKalle Valo {
542*05491d2cSKalle Valo 	struct bcma_device *cc;
543*05491d2cSKalle Valo 	u32 w;
544*05491d2cSKalle Valo 	struct si_info *sii;
545*05491d2cSKalle Valo 
546*05491d2cSKalle Valo 	sii = container_of(sih, struct si_info, pub);
547*05491d2cSKalle Valo 	cc = sii->icbus->drv_cc.core;
548*05491d2cSKalle Valo 
549*05491d2cSKalle Valo 	/* mask and set */
550*05491d2cSKalle Valo 	if (mask || val)
551*05491d2cSKalle Valo 		bcma_maskset32(cc, regoff, ~mask, val);
552*05491d2cSKalle Valo 
553*05491d2cSKalle Valo 	/* readback */
554*05491d2cSKalle Valo 	w = bcma_read32(cc, regoff);
555*05491d2cSKalle Valo 
556*05491d2cSKalle Valo 	return w;
557*05491d2cSKalle Valo }
558*05491d2cSKalle Valo 
559*05491d2cSKalle Valo /* return the slow clock source - LPO, XTAL, or PCI */
ai_slowclk_src(struct si_pub * sih,struct bcma_device * cc)560*05491d2cSKalle Valo static uint ai_slowclk_src(struct si_pub *sih, struct bcma_device *cc)
561*05491d2cSKalle Valo {
562*05491d2cSKalle Valo 	return SCC_SS_XTAL;
563*05491d2cSKalle Valo }
564*05491d2cSKalle Valo 
565*05491d2cSKalle Valo /*
566*05491d2cSKalle Valo * return the ILP (slowclock) min or max frequency
567*05491d2cSKalle Valo * precondition: we've established the chip has dynamic clk control
568*05491d2cSKalle Valo */
ai_slowclk_freq(struct si_pub * sih,bool max_freq,struct bcma_device * cc)569*05491d2cSKalle Valo static uint ai_slowclk_freq(struct si_pub *sih, bool max_freq,
570*05491d2cSKalle Valo 			    struct bcma_device *cc)
571*05491d2cSKalle Valo {
572*05491d2cSKalle Valo 	uint div;
573*05491d2cSKalle Valo 
574*05491d2cSKalle Valo 	/* Chipc rev 10 is InstaClock */
575*05491d2cSKalle Valo 	div = bcma_read32(cc, CHIPCREGOFFS(system_clk_ctl));
576*05491d2cSKalle Valo 	div = 4 * ((div >> SYCC_CD_SHIFT) + 1);
577*05491d2cSKalle Valo 	return max_freq ? XTALMAXFREQ : (XTALMINFREQ / div);
578*05491d2cSKalle Valo }
579*05491d2cSKalle Valo 
580*05491d2cSKalle Valo static void
ai_clkctl_setdelay(struct si_pub * sih,struct bcma_device * cc)581*05491d2cSKalle Valo ai_clkctl_setdelay(struct si_pub *sih, struct bcma_device *cc)
582*05491d2cSKalle Valo {
583*05491d2cSKalle Valo 	uint slowmaxfreq, pll_delay, slowclk;
584*05491d2cSKalle Valo 	uint pll_on_delay, fref_sel_delay;
585*05491d2cSKalle Valo 
586*05491d2cSKalle Valo 	pll_delay = PLL_DELAY;
587*05491d2cSKalle Valo 
588*05491d2cSKalle Valo 	/*
589*05491d2cSKalle Valo 	 * If the slow clock is not sourced by the xtal then
590*05491d2cSKalle Valo 	 * add the xtal_on_delay since the xtal will also be
591*05491d2cSKalle Valo 	 * powered down by dynamic clk control logic.
592*05491d2cSKalle Valo 	 */
593*05491d2cSKalle Valo 
594*05491d2cSKalle Valo 	slowclk = ai_slowclk_src(sih, cc);
595*05491d2cSKalle Valo 	if (slowclk != SCC_SS_XTAL)
596*05491d2cSKalle Valo 		pll_delay += XTAL_ON_DELAY;
597*05491d2cSKalle Valo 
598*05491d2cSKalle Valo 	/* Starting with 4318 it is ILP that is used for the delays */
599*05491d2cSKalle Valo 	slowmaxfreq =
600*05491d2cSKalle Valo 	    ai_slowclk_freq(sih, false, cc);
601*05491d2cSKalle Valo 
602*05491d2cSKalle Valo 	pll_on_delay = ((slowmaxfreq * pll_delay) + 999999) / 1000000;
603*05491d2cSKalle Valo 	fref_sel_delay = ((slowmaxfreq * FREF_DELAY) + 999999) / 1000000;
604*05491d2cSKalle Valo 
605*05491d2cSKalle Valo 	bcma_write32(cc, CHIPCREGOFFS(pll_on_delay), pll_on_delay);
606*05491d2cSKalle Valo 	bcma_write32(cc, CHIPCREGOFFS(fref_sel_delay), fref_sel_delay);
607*05491d2cSKalle Valo }
608*05491d2cSKalle Valo 
609*05491d2cSKalle Valo /* initialize power control delay registers */
ai_clkctl_init(struct si_pub * sih)610*05491d2cSKalle Valo void ai_clkctl_init(struct si_pub *sih)
611*05491d2cSKalle Valo {
612*05491d2cSKalle Valo 	struct si_info *sii = container_of(sih, struct si_info, pub);
613*05491d2cSKalle Valo 	struct bcma_device *cc;
614*05491d2cSKalle Valo 
615*05491d2cSKalle Valo 	if (!(ai_get_cccaps(sih) & CC_CAP_PWR_CTL))
616*05491d2cSKalle Valo 		return;
617*05491d2cSKalle Valo 
618*05491d2cSKalle Valo 	cc = sii->icbus->drv_cc.core;
619*05491d2cSKalle Valo 	if (cc == NULL)
620*05491d2cSKalle Valo 		return;
621*05491d2cSKalle Valo 
622*05491d2cSKalle Valo 	/* set all Instaclk chip ILP to 1 MHz */
623*05491d2cSKalle Valo 	bcma_maskset32(cc, CHIPCREGOFFS(system_clk_ctl), SYCC_CD_MASK,
624*05491d2cSKalle Valo 		       (ILP_DIV_1MHZ << SYCC_CD_SHIFT));
625*05491d2cSKalle Valo 
626*05491d2cSKalle Valo 	ai_clkctl_setdelay(sih, cc);
627*05491d2cSKalle Valo }
628*05491d2cSKalle Valo 
629*05491d2cSKalle Valo /*
630*05491d2cSKalle Valo  * return the value suitable for writing to the
631*05491d2cSKalle Valo  * dot11 core FAST_PWRUP_DELAY register
632*05491d2cSKalle Valo  */
ai_clkctl_fast_pwrup_delay(struct si_pub * sih)633*05491d2cSKalle Valo u16 ai_clkctl_fast_pwrup_delay(struct si_pub *sih)
634*05491d2cSKalle Valo {
635*05491d2cSKalle Valo 	struct si_info *sii;
636*05491d2cSKalle Valo 	struct bcma_device *cc;
637*05491d2cSKalle Valo 	uint slowminfreq;
638*05491d2cSKalle Valo 	u16 fpdelay;
639*05491d2cSKalle Valo 
640*05491d2cSKalle Valo 	sii = container_of(sih, struct si_info, pub);
641*05491d2cSKalle Valo 	if (ai_get_cccaps(sih) & CC_CAP_PMU) {
642*05491d2cSKalle Valo 		fpdelay = si_pmu_fast_pwrup_delay(sih);
643*05491d2cSKalle Valo 		return fpdelay;
644*05491d2cSKalle Valo 	}
645*05491d2cSKalle Valo 
646*05491d2cSKalle Valo 	if (!(ai_get_cccaps(sih) & CC_CAP_PWR_CTL))
647*05491d2cSKalle Valo 		return 0;
648*05491d2cSKalle Valo 
649*05491d2cSKalle Valo 	fpdelay = 0;
650*05491d2cSKalle Valo 	cc = sii->icbus->drv_cc.core;
651*05491d2cSKalle Valo 	if (cc) {
652*05491d2cSKalle Valo 		slowminfreq = ai_slowclk_freq(sih, false, cc);
653*05491d2cSKalle Valo 		fpdelay = (((bcma_read32(cc, CHIPCREGOFFS(pll_on_delay)) + 2)
654*05491d2cSKalle Valo 			    * 1000000) + (slowminfreq - 1)) / slowminfreq;
655*05491d2cSKalle Valo 	}
656*05491d2cSKalle Valo 	return fpdelay;
657*05491d2cSKalle Valo }
658*05491d2cSKalle Valo 
659*05491d2cSKalle Valo /*
660*05491d2cSKalle Valo  *  clock control policy function throught chipcommon
661*05491d2cSKalle Valo  *
662*05491d2cSKalle Valo  *    set dynamic clk control mode (forceslow, forcefast, dynamic)
663*05491d2cSKalle Valo  *    returns true if we are forcing fast clock
664*05491d2cSKalle Valo  *    this is a wrapper over the next internal function
665*05491d2cSKalle Valo  *      to allow flexible policy settings for outside caller
666*05491d2cSKalle Valo  */
ai_clkctl_cc(struct si_pub * sih,enum bcma_clkmode mode)667*05491d2cSKalle Valo bool ai_clkctl_cc(struct si_pub *sih, enum bcma_clkmode mode)
668*05491d2cSKalle Valo {
669*05491d2cSKalle Valo 	struct si_info *sii;
670*05491d2cSKalle Valo 	struct bcma_device *cc;
671*05491d2cSKalle Valo 
672*05491d2cSKalle Valo 	sii = container_of(sih, struct si_info, pub);
673*05491d2cSKalle Valo 
674*05491d2cSKalle Valo 	cc = sii->icbus->drv_cc.core;
675*05491d2cSKalle Valo 	bcma_core_set_clockmode(cc, mode);
676*05491d2cSKalle Valo 	return mode == BCMA_CLKMODE_FAST;
677*05491d2cSKalle Valo }
678*05491d2cSKalle Valo 
679*05491d2cSKalle Valo /* Enable BT-COEX & Ex-PA for 4313 */
ai_epa_4313war(struct si_pub * sih)680*05491d2cSKalle Valo void ai_epa_4313war(struct si_pub *sih)
681*05491d2cSKalle Valo {
682*05491d2cSKalle Valo 	struct si_info *sii = container_of(sih, struct si_info, pub);
683*05491d2cSKalle Valo 	struct bcma_device *cc;
684*05491d2cSKalle Valo 
685*05491d2cSKalle Valo 	cc = sii->icbus->drv_cc.core;
686*05491d2cSKalle Valo 
687*05491d2cSKalle Valo 	/* EPA Fix */
688*05491d2cSKalle Valo 	bcma_set32(cc, CHIPCREGOFFS(gpiocontrol), GPIO_CTRL_EPA_EN_MASK);
689*05491d2cSKalle Valo }
690*05491d2cSKalle Valo 
691*05491d2cSKalle Valo /* check if the device is removed */
ai_deviceremoved(struct si_pub * sih)692*05491d2cSKalle Valo bool ai_deviceremoved(struct si_pub *sih)
693*05491d2cSKalle Valo {
694*05491d2cSKalle Valo 	u32 w = 0;
695*05491d2cSKalle Valo 	struct si_info *sii;
696*05491d2cSKalle Valo 
697*05491d2cSKalle Valo 	sii = container_of(sih, struct si_info, pub);
698*05491d2cSKalle Valo 
699*05491d2cSKalle Valo 	if (sii->icbus->hosttype != BCMA_HOSTTYPE_PCI)
700*05491d2cSKalle Valo 		return false;
701*05491d2cSKalle Valo 
702*05491d2cSKalle Valo 	pci_read_config_dword(sii->pcibus, PCI_VENDOR_ID, &w);
703*05491d2cSKalle Valo 	if ((w & 0xFFFF) != PCI_VENDOR_ID_BROADCOM)
704*05491d2cSKalle Valo 		return true;
705*05491d2cSKalle Valo 
706*05491d2cSKalle Valo 	return false;
707*05491d2cSKalle Valo }
708