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