]> git.karo-electronics.de Git - mv-sheeva.git/blob - drivers/staging/brcm80211/brcmsmac/wlc_pmu.c
e9230a883ad8740615fe9eb925c44b7cbc8bfffc
[mv-sheeva.git] / drivers / staging / brcm80211 / brcmsmac / wlc_pmu.c
1 /*
2  * Copyright (c) 2011 Broadcom Corporation
3  *
4  * Permission to use, copy, modify, and/or distribute this software for any
5  * purpose with or without fee is hereby granted, provided that the above
6  * copyright notice and this permission notice appear in all copies.
7  *
8  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11  * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15  */
16 #include <linux/kernel.h>
17 #include <linux/types.h>
18 #include <linux/delay.h>
19 #include <linux/io.h>
20
21 #include <bcmdevs.h>
22 #include <sbchipc.h>
23 #include <bcmutils.h>
24 #include <bcmnvram.h>
25 #include "wlc_pmu.h"
26
27 /*
28  * d11 slow to fast clock transition time in slow clock cycles
29  */
30 #define D11SCC_SLOW2FAST_TRANSITION     2
31
32 /*
33  * external LPO crystal frequency
34  */
35 #define EXT_ILP_HZ 32768
36
37 /*
38  * Duration for ILP clock frequency measurment in milliseconds
39  *
40  * remark: 1000 must be an integer multiple of this duration
41  */
42 #define ILP_CALC_DUR    10
43
44 /*
45  * FVCO frequency
46  */
47 #define FVCO_880        880000  /* 880MHz */
48 #define FVCO_1760       1760000 /* 1760MHz */
49 #define FVCO_1440       1440000 /* 1440MHz */
50 #define FVCO_960        960000  /* 960MHz */
51
52 /*
53  * PMU crystal table indices for 1440MHz fvco
54  */
55 #define PMU1_XTALTAB0_1440_12000K       0
56 #define PMU1_XTALTAB0_1440_13000K       1
57 #define PMU1_XTALTAB0_1440_14400K       2
58 #define PMU1_XTALTAB0_1440_15360K       3
59 #define PMU1_XTALTAB0_1440_16200K       4
60 #define PMU1_XTALTAB0_1440_16800K       5
61 #define PMU1_XTALTAB0_1440_19200K       6
62 #define PMU1_XTALTAB0_1440_19800K       7
63 #define PMU1_XTALTAB0_1440_20000K       8
64 #define PMU1_XTALTAB0_1440_25000K       9
65 #define PMU1_XTALTAB0_1440_26000K       10
66 #define PMU1_XTALTAB0_1440_30000K       11
67 #define PMU1_XTALTAB0_1440_37400K       12
68 #define PMU1_XTALTAB0_1440_38400K       13
69 #define PMU1_XTALTAB0_1440_40000K       14
70 #define PMU1_XTALTAB0_1440_48000K       15
71
72 /*
73  * PMU crystal table indices for 960MHz fvco
74  */
75 #define PMU1_XTALTAB0_960_12000K        0
76 #define PMU1_XTALTAB0_960_13000K        1
77 #define PMU1_XTALTAB0_960_14400K        2
78 #define PMU1_XTALTAB0_960_15360K        3
79 #define PMU1_XTALTAB0_960_16200K        4
80 #define PMU1_XTALTAB0_960_16800K        5
81 #define PMU1_XTALTAB0_960_19200K        6
82 #define PMU1_XTALTAB0_960_19800K        7
83 #define PMU1_XTALTAB0_960_20000K        8
84 #define PMU1_XTALTAB0_960_25000K        9
85 #define PMU1_XTALTAB0_960_26000K        10
86 #define PMU1_XTALTAB0_960_30000K        11
87 #define PMU1_XTALTAB0_960_37400K        12
88 #define PMU1_XTALTAB0_960_38400K        13
89 #define PMU1_XTALTAB0_960_40000K        14
90 #define PMU1_XTALTAB0_960_48000K        15
91
92 /*
93  * PMU crystal table indices for 880MHz fvco
94  */
95 #define PMU1_XTALTAB0_880_12000K        0
96 #define PMU1_XTALTAB0_880_13000K        1
97 #define PMU1_XTALTAB0_880_14400K        2
98 #define PMU1_XTALTAB0_880_15360K        3
99 #define PMU1_XTALTAB0_880_16200K        4
100 #define PMU1_XTALTAB0_880_16800K        5
101 #define PMU1_XTALTAB0_880_19200K        6
102 #define PMU1_XTALTAB0_880_19800K        7
103 #define PMU1_XTALTAB0_880_20000K        8
104 #define PMU1_XTALTAB0_880_24000K        9
105 #define PMU1_XTALTAB0_880_25000K        10
106 #define PMU1_XTALTAB0_880_26000K        11
107 #define PMU1_XTALTAB0_880_30000K        12
108 #define PMU1_XTALTAB0_880_37400K        13
109 #define PMU1_XTALTAB0_880_38400K        14
110 #define PMU1_XTALTAB0_880_40000K        15
111
112 /*
113  * crystal frequency values
114  */
115 #define XTAL_FREQ_24000MHZ              24000
116 #define XTAL_FREQ_30000MHZ              30000
117 #define XTAL_FREQ_37400MHZ              37400
118 #define XTAL_FREQ_48000MHZ              48000
119
120 /*
121  * Resource dependancies mask change action
122  *
123  * @RES_DEPEND_SET: Override the dependancies mask
124  * @RES_DEPEND_ADD: Add to the  dependancies mask
125  * @RES_DEPEND_REMOVE: Remove from the dependancies mask
126  */
127 #define RES_DEPEND_SET          0
128 #define RES_DEPEND_ADD          1
129 #define RES_DEPEND_REMOVE       -1
130
131 /* Fields in pmucontrol */
132 #define PCTL_ILP_DIV_MASK       0xffff0000
133 #define PCTL_ILP_DIV_SHIFT      16
134 #define PCTL_PLL_PLLCTL_UPD     0x00000400      /* rev 2 */
135 #define PCTL_NOILP_ON_WAIT      0x00000200      /* rev 1 */
136 #define PCTL_HT_REQ_EN          0x00000100
137 #define PCTL_ALP_REQ_EN         0x00000080
138 #define PCTL_XTALFREQ_MASK      0x0000007c
139 #define PCTL_XTALFREQ_SHIFT     2
140 #define PCTL_ILP_DIV_EN         0x00000002
141 #define PCTL_LPO_SEL            0x00000001
142
143 /* Fields in clkstretch */
144 #define CSTRETCH_HT             0xffff0000
145 #define CSTRETCH_ALP            0x0000ffff
146
147 /* d11 slow to fast clock transition time in slow clock cycles */
148 #define D11SCC_SLOW2FAST_TRANSITION     2
149
150 /* ILP clock */
151 #define ILP_CLOCK               32000
152
153 /* ALP clock on pre-PMU chips */
154 #define ALP_CLOCK               20000000
155
156 /* HT clock */
157 #define HT_CLOCK                80000000
158
159 #define OTPS_READY              0x00001000
160
161 /* pmustatus */
162 #define PST_EXTLPOAVAIL 0x0100
163 #define PST_WDRESET     0x0080
164 #define PST_INTPEND     0x0040
165 #define PST_SBCLKST     0x0030
166 #define PST_SBCLKST_ILP 0x0010
167 #define PST_SBCLKST_ALP 0x0020
168 #define PST_SBCLKST_HT  0x0030
169 #define PST_ALPAVAIL    0x0008
170 #define PST_HTAVAIL     0x0004
171 #define PST_RESINIT     0x0003
172
173 /* PMU Resource Request Timer registers */
174 /* This is based on PmuRev0 */
175 #define PRRT_TIME_MASK  0x03ff
176 #define PRRT_INTEN      0x0400
177 #define PRRT_REQ_ACTIVE 0x0800
178 #define PRRT_ALP_REQ    0x1000
179 #define PRRT_HT_REQ     0x2000
180
181 /* PMU resource bit position */
182 #define PMURES_BIT(bit) (1 << (bit))
183
184 /* PMU resource number limit */
185 #define PMURES_MAX_RESNUM       30
186
187 /* PMU chip control0 register */
188 #define PMU_CHIPCTL0            0
189
190 /* PMU chip control1 register */
191 #define PMU_CHIPCTL1                    1
192 #define PMU_CC1_RXC_DLL_BYPASS          0x00010000
193
194 #define PMU_CC1_IF_TYPE_MASK            0x00000030
195 #define PMU_CC1_IF_TYPE_RMII            0x00000000
196 #define PMU_CC1_IF_TYPE_MII             0x00000010
197 #define PMU_CC1_IF_TYPE_RGMII           0x00000020
198
199 #define PMU_CC1_SW_TYPE_MASK            0x000000c0
200 #define PMU_CC1_SW_TYPE_EPHY            0x00000000
201 #define PMU_CC1_SW_TYPE_EPHYMII         0x00000040
202 #define PMU_CC1_SW_TYPE_EPHYRMII        0x00000080
203 #define PMU_CC1_SW_TYPE_RGMII           0x000000c0
204
205 /* PMU corerev and chip specific PLL controls.
206  * PMU<rev>_PLL<num>_XX where <rev> is PMU corerev and <num> is an arbitrary number
207  * to differentiate different PLLs controlled by the same PMU rev.
208  */
209 /* pllcontrol registers */
210 /* PDIV, div_phy, div_arm, div_adc, dith_sel, ioff, kpd_scale, lsb_sel, mash_sel, lf_c & lf_r */
211 #define PMU0_PLL0_PLLCTL0               0
212 #define PMU0_PLL0_PC0_PDIV_MASK         1
213 #define PMU0_PLL0_PC0_PDIV_FREQ         25000
214 #define PMU0_PLL0_PC0_DIV_ARM_MASK      0x00000038
215 #define PMU0_PLL0_PC0_DIV_ARM_SHIFT     3
216 #define PMU0_PLL0_PC0_DIV_ARM_BASE      8
217
218 /* PC0_DIV_ARM for PLLOUT_ARM */
219 #define PMU0_PLL0_PC0_DIV_ARM_110MHZ    0
220 #define PMU0_PLL0_PC0_DIV_ARM_97_7MHZ   1
221 #define PMU0_PLL0_PC0_DIV_ARM_88MHZ     2
222 #define PMU0_PLL0_PC0_DIV_ARM_80MHZ     3       /* Default */
223 #define PMU0_PLL0_PC0_DIV_ARM_73_3MHZ   4
224 #define PMU0_PLL0_PC0_DIV_ARM_67_7MHZ   5
225 #define PMU0_PLL0_PC0_DIV_ARM_62_9MHZ   6
226 #define PMU0_PLL0_PC0_DIV_ARM_58_6MHZ   7
227
228 /* Wildcard base, stop_mod, en_lf_tp, en_cal & lf_r2 */
229 #define PMU0_PLL0_PLLCTL1               1
230 #define PMU0_PLL0_PC1_WILD_INT_MASK     0xf0000000
231 #define PMU0_PLL0_PC1_WILD_INT_SHIFT    28
232 #define PMU0_PLL0_PC1_WILD_FRAC_MASK    0x0fffff00
233 #define PMU0_PLL0_PC1_WILD_FRAC_SHIFT   8
234 #define PMU0_PLL0_PC1_STOP_MOD          0x00000040
235
236 /* Wildcard base, vco_calvar, vco_swc, vco_var_selref, vso_ical & vco_sel_avdd */
237 #define PMU0_PLL0_PLLCTL2               2
238 #define PMU0_PLL0_PC2_WILD_INT_MASK     0xf
239 #define PMU0_PLL0_PC2_WILD_INT_SHIFT    4
240
241 /* pllcontrol registers */
242 /* ndiv_pwrdn, pwrdn_ch<x>, refcomp_pwrdn, dly_ch<x>, p1div, p2div, _bypass_sdmod */
243 #define PMU1_PLL0_PLLCTL0               0
244 #define PMU1_PLL0_PC0_P1DIV_MASK        0x00f00000
245 #define PMU1_PLL0_PC0_P1DIV_SHIFT       20
246 #define PMU1_PLL0_PC0_P2DIV_MASK        0x0f000000
247 #define PMU1_PLL0_PC0_P2DIV_SHIFT       24
248
249 /* m<x>div */
250 #define PMU1_PLL0_PLLCTL1               1
251 #define PMU1_PLL0_PC1_M1DIV_MASK        0x000000ff
252 #define PMU1_PLL0_PC1_M1DIV_SHIFT       0
253 #define PMU1_PLL0_PC1_M2DIV_MASK        0x0000ff00
254 #define PMU1_PLL0_PC1_M2DIV_SHIFT       8
255 #define PMU1_PLL0_PC1_M3DIV_MASK        0x00ff0000
256 #define PMU1_PLL0_PC1_M3DIV_SHIFT       16
257 #define PMU1_PLL0_PC1_M4DIV_MASK        0xff000000
258 #define PMU1_PLL0_PC1_M4DIV_SHIFT       24
259
260 #define PMU1_PLL0_CHIPCTL0              0
261 #define PMU1_PLL0_CHIPCTL1              1
262 #define PMU1_PLL0_CHIPCTL2              2
263
264 #define DOT11MAC_880MHZ_CLK_DIVISOR_SHIFT 8
265 #define DOT11MAC_880MHZ_CLK_DIVISOR_MASK (0xFF << DOT11MAC_880MHZ_CLK_DIVISOR_SHIFT)
266 #define DOT11MAC_880MHZ_CLK_DIVISOR_VAL  (0xE << DOT11MAC_880MHZ_CLK_DIVISOR_SHIFT)
267
268 /* m<x>div, ndiv_dither_mfb, ndiv_mode, ndiv_int */
269 #define PMU1_PLL0_PLLCTL2               2
270 #define PMU1_PLL0_PC2_M5DIV_MASK        0x000000ff
271 #define PMU1_PLL0_PC2_M5DIV_SHIFT       0
272 #define PMU1_PLL0_PC2_M6DIV_MASK        0x0000ff00
273 #define PMU1_PLL0_PC2_M6DIV_SHIFT       8
274 #define PMU1_PLL0_PC2_NDIV_MODE_MASK    0x000e0000
275 #define PMU1_PLL0_PC2_NDIV_MODE_SHIFT   17
276 #define PMU1_PLL0_PC2_NDIV_MODE_MASH    1
277 #define PMU1_PLL0_PC2_NDIV_MODE_MFB     2       /* recommended for 4319 */
278 #define PMU1_PLL0_PC2_NDIV_INT_MASK     0x1ff00000
279 #define PMU1_PLL0_PC2_NDIV_INT_SHIFT    20
280
281 /* ndiv_frac */
282 #define PMU1_PLL0_PLLCTL3               3
283 #define PMU1_PLL0_PC3_NDIV_FRAC_MASK    0x00ffffff
284 #define PMU1_PLL0_PC3_NDIV_FRAC_SHIFT   0
285
286 /* pll_ctrl */
287 #define PMU1_PLL0_PLLCTL4               4
288
289 /* pll_ctrl, vco_rng, clkdrive_ch<x> */
290 #define PMU1_PLL0_PLLCTL5               5
291 #define PMU1_PLL0_PC5_CLK_DRV_MASK 0xffffff00
292 #define PMU1_PLL0_PC5_CLK_DRV_SHIFT 8
293
294 /* PMU rev 2 control words */
295 #define PMU2_PHY_PLL_PLLCTL             4
296 #define PMU2_SI_PLL_PLLCTL              10
297
298 /* PMU rev 2 */
299 /* pllcontrol registers */
300 /* ndiv_pwrdn, pwrdn_ch<x>, refcomp_pwrdn, dly_ch<x>, p1div, p2div, _bypass_sdmod */
301 #define PMU2_PLL_PLLCTL0                0
302 #define PMU2_PLL_PC0_P1DIV_MASK         0x00f00000
303 #define PMU2_PLL_PC0_P1DIV_SHIFT        20
304 #define PMU2_PLL_PC0_P2DIV_MASK         0x0f000000
305 #define PMU2_PLL_PC0_P2DIV_SHIFT        24
306
307 /* m<x>div */
308 #define PMU2_PLL_PLLCTL1                1
309 #define PMU2_PLL_PC1_M1DIV_MASK         0x000000ff
310 #define PMU2_PLL_PC1_M1DIV_SHIFT        0
311 #define PMU2_PLL_PC1_M2DIV_MASK         0x0000ff00
312 #define PMU2_PLL_PC1_M2DIV_SHIFT        8
313 #define PMU2_PLL_PC1_M3DIV_MASK         0x00ff0000
314 #define PMU2_PLL_PC1_M3DIV_SHIFT        16
315 #define PMU2_PLL_PC1_M4DIV_MASK         0xff000000
316 #define PMU2_PLL_PC1_M4DIV_SHIFT        24
317
318 /* m<x>div, ndiv_dither_mfb, ndiv_mode, ndiv_int */
319 #define PMU2_PLL_PLLCTL2                2
320 #define PMU2_PLL_PC2_M5DIV_MASK         0x000000ff
321 #define PMU2_PLL_PC2_M5DIV_SHIFT        0
322 #define PMU2_PLL_PC2_M6DIV_MASK         0x0000ff00
323 #define PMU2_PLL_PC2_M6DIV_SHIFT        8
324 #define PMU2_PLL_PC2_NDIV_MODE_MASK     0x000e0000
325 #define PMU2_PLL_PC2_NDIV_MODE_SHIFT    17
326 #define PMU2_PLL_PC2_NDIV_INT_MASK      0x1ff00000
327 #define PMU2_PLL_PC2_NDIV_INT_SHIFT     20
328
329 /* ndiv_frac */
330 #define PMU2_PLL_PLLCTL3                3
331 #define PMU2_PLL_PC3_NDIV_FRAC_MASK     0x00ffffff
332 #define PMU2_PLL_PC3_NDIV_FRAC_SHIFT    0
333
334 /* pll_ctrl */
335 #define PMU2_PLL_PLLCTL4                4
336
337 /* pll_ctrl, vco_rng, clkdrive_ch<x> */
338 #define PMU2_PLL_PLLCTL5                5
339 #define PMU2_PLL_PC5_CLKDRIVE_CH1_MASK  0x00000f00
340 #define PMU2_PLL_PC5_CLKDRIVE_CH1_SHIFT 8
341 #define PMU2_PLL_PC5_CLKDRIVE_CH2_MASK  0x0000f000
342 #define PMU2_PLL_PC5_CLKDRIVE_CH2_SHIFT 12
343 #define PMU2_PLL_PC5_CLKDRIVE_CH3_MASK  0x000f0000
344 #define PMU2_PLL_PC5_CLKDRIVE_CH3_SHIFT 16
345 #define PMU2_PLL_PC5_CLKDRIVE_CH4_MASK  0x00f00000
346 #define PMU2_PLL_PC5_CLKDRIVE_CH4_SHIFT 20
347 #define PMU2_PLL_PC5_CLKDRIVE_CH5_MASK  0x0f000000
348 #define PMU2_PLL_PC5_CLKDRIVE_CH5_SHIFT 24
349 #define PMU2_PLL_PC5_CLKDRIVE_CH6_MASK  0xf0000000
350 #define PMU2_PLL_PC5_CLKDRIVE_CH6_SHIFT 28
351
352 /* PMU rev 5 (& 6) */
353 #define PMU5_PLL_P1P2_OFF               0
354 #define PMU5_PLL_P1_MASK                0x0f000000
355 #define PMU5_PLL_P1_SHIFT               24
356 #define PMU5_PLL_P2_MASK                0x00f00000
357 #define PMU5_PLL_P2_SHIFT               20
358 #define PMU5_PLL_M14_OFF                1
359 #define PMU5_PLL_MDIV_MASK              0x000000ff
360 #define PMU5_PLL_MDIV_WIDTH             8
361 #define PMU5_PLL_NM5_OFF                2
362 #define PMU5_PLL_NDIV_MASK              0xfff00000
363 #define PMU5_PLL_NDIV_SHIFT             20
364 #define PMU5_PLL_NDIV_MODE_MASK         0x000e0000
365 #define PMU5_PLL_NDIV_MODE_SHIFT        17
366 #define PMU5_PLL_FMAB_OFF               3
367 #define PMU5_PLL_MRAT_MASK              0xf0000000
368 #define PMU5_PLL_MRAT_SHIFT             28
369 #define PMU5_PLL_ABRAT_MASK             0x08000000
370 #define PMU5_PLL_ABRAT_SHIFT            27
371 #define PMU5_PLL_FDIV_MASK              0x07ffffff
372 #define PMU5_PLL_PLLCTL_OFF             4
373 #define PMU5_PLL_PCHI_OFF               5
374 #define PMU5_PLL_PCHI_MASK              0x0000003f
375
376 /* pmu XtalFreqRatio */
377 #define PMU_XTALFREQ_REG_ILPCTR_MASK    0x00001FFF
378 #define PMU_XTALFREQ_REG_MEASURE_MASK   0x80000000
379 #define PMU_XTALFREQ_REG_MEASURE_SHIFT  31
380
381 /* Divider allocation in 4716/47162/5356/5357 */
382 #define PMU5_MAINPLL_CPU                1
383 #define PMU5_MAINPLL_MEM                2
384 #define PMU5_MAINPLL_SI                 3
385
386 #define PMU7_PLL_PLLCTL7                7
387 #define PMU7_PLL_PLLCTL8                8
388 #define PMU7_PLL_PLLCTL11               11
389
390 /* PLL usage in 4716/47162 */
391 #define PMU4716_MAINPLL_PLL0            12
392
393 /* PLL usage in 5356/5357 */
394 #define PMU5356_MAINPLL_PLL0            0
395 #define PMU5357_MAINPLL_PLL0            0
396
397 /* 4328 resources */
398 #define RES4328_EXT_SWITCHER_PWM        0       /* 0x00001 */
399 #define RES4328_BB_SWITCHER_PWM         1       /* 0x00002 */
400 #define RES4328_BB_SWITCHER_BURST       2       /* 0x00004 */
401 #define RES4328_BB_EXT_SWITCHER_BURST   3       /* 0x00008 */
402 #define RES4328_ILP_REQUEST             4       /* 0x00010 */
403 #define RES4328_RADIO_SWITCHER_PWM      5       /* 0x00020 */
404 #define RES4328_RADIO_SWITCHER_BURST    6       /* 0x00040 */
405 #define RES4328_ROM_SWITCH              7       /* 0x00080 */
406 #define RES4328_PA_REF_LDO              8       /* 0x00100 */
407 #define RES4328_RADIO_LDO               9       /* 0x00200 */
408 #define RES4328_AFE_LDO                 10      /* 0x00400 */
409 #define RES4328_PLL_LDO                 11      /* 0x00800 */
410 #define RES4328_BG_FILTBYP              12      /* 0x01000 */
411 #define RES4328_TX_FILTBYP              13      /* 0x02000 */
412 #define RES4328_RX_FILTBYP              14      /* 0x04000 */
413 #define RES4328_XTAL_PU                 15      /* 0x08000 */
414 #define RES4328_XTAL_EN                 16      /* 0x10000 */
415 #define RES4328_BB_PLL_FILTBYP          17      /* 0x20000 */
416 #define RES4328_RF_PLL_FILTBYP          18      /* 0x40000 */
417 #define RES4328_BB_PLL_PU               19      /* 0x80000 */
418
419 /* 4325 A0/A1 resources */
420 #define RES4325_BUCK_BOOST_BURST        0       /* 0x00000001 */
421 #define RES4325_CBUCK_BURST             1       /* 0x00000002 */
422 #define RES4325_CBUCK_PWM               2       /* 0x00000004 */
423 #define RES4325_CLDO_CBUCK_BURST        3       /* 0x00000008 */
424 #define RES4325_CLDO_CBUCK_PWM          4       /* 0x00000010 */
425 #define RES4325_BUCK_BOOST_PWM          5       /* 0x00000020 */
426 #define RES4325_ILP_REQUEST             6       /* 0x00000040 */
427 #define RES4325_ABUCK_BURST             7       /* 0x00000080 */
428 #define RES4325_ABUCK_PWM               8       /* 0x00000100 */
429 #define RES4325_LNLDO1_PU               9       /* 0x00000200 */
430 #define RES4325_OTP_PU                  10      /* 0x00000400 */
431 #define RES4325_LNLDO3_PU               11      /* 0x00000800 */
432 #define RES4325_LNLDO4_PU               12      /* 0x00001000 */
433 #define RES4325_XTAL_PU                 13      /* 0x00002000 */
434 #define RES4325_ALP_AVAIL               14      /* 0x00004000 */
435 #define RES4325_RX_PWRSW_PU             15      /* 0x00008000 */
436 #define RES4325_TX_PWRSW_PU             16      /* 0x00010000 */
437 #define RES4325_RFPLL_PWRSW_PU          17      /* 0x00020000 */
438 #define RES4325_LOGEN_PWRSW_PU          18      /* 0x00040000 */
439 #define RES4325_AFE_PWRSW_PU            19      /* 0x00080000 */
440 #define RES4325_BBPLL_PWRSW_PU          20      /* 0x00100000 */
441 #define RES4325_HT_AVAIL                21      /* 0x00200000 */
442
443 /* 4325 B0/C0 resources */
444 #define RES4325B0_CBUCK_LPOM            1       /* 0x00000002 */
445 #define RES4325B0_CBUCK_BURST           2       /* 0x00000004 */
446 #define RES4325B0_CBUCK_PWM             3       /* 0x00000008 */
447 #define RES4325B0_CLDO_PU               4       /* 0x00000010 */
448
449 /* 4325 C1 resources */
450 #define RES4325C1_LNLDO2_PU             12      /* 0x00001000 */
451
452 #define RES4329_RESERVED0               0       /* 0x00000001 */
453 #define RES4329_CBUCK_LPOM              1       /* 0x00000002 */
454 #define RES4329_CBUCK_BURST             2       /* 0x00000004 */
455 #define RES4329_CBUCK_PWM               3       /* 0x00000008 */
456 #define RES4329_CLDO_PU                 4       /* 0x00000010 */
457 #define RES4329_PALDO_PU                5       /* 0x00000020 */
458 #define RES4329_ILP_REQUEST             6       /* 0x00000040 */
459 #define RES4329_RESERVED7               7       /* 0x00000080 */
460 #define RES4329_RESERVED8               8       /* 0x00000100 */
461 #define RES4329_LNLDO1_PU               9       /* 0x00000200 */
462 #define RES4329_OTP_PU                  10      /* 0x00000400 */
463 #define RES4329_RESERVED11              11      /* 0x00000800 */
464 #define RES4329_LNLDO2_PU               12      /* 0x00001000 */
465 #define RES4329_XTAL_PU                 13      /* 0x00002000 */
466 #define RES4329_ALP_AVAIL               14      /* 0x00004000 */
467 #define RES4329_RX_PWRSW_PU             15      /* 0x00008000 */
468 #define RES4329_TX_PWRSW_PU             16      /* 0x00010000 */
469 #define RES4329_RFPLL_PWRSW_PU          17      /* 0x00020000 */
470 #define RES4329_LOGEN_PWRSW_PU          18      /* 0x00040000 */
471 #define RES4329_AFE_PWRSW_PU            19      /* 0x00080000 */
472 #define RES4329_BBPLL_PWRSW_PU          20      /* 0x00100000 */
473 #define RES4329_HT_AVAIL                21      /* 0x00200000 */
474
475 /* 4315 resources */
476 #define RES4315_CBUCK_LPOM              1       /* 0x00000002 */
477 #define RES4315_CBUCK_BURST             2       /* 0x00000004 */
478 #define RES4315_CBUCK_PWM               3       /* 0x00000008 */
479 #define RES4315_CLDO_PU                 4       /* 0x00000010 */
480 #define RES4315_PALDO_PU                5       /* 0x00000020 */
481 #define RES4315_ILP_REQUEST             6       /* 0x00000040 */
482 #define RES4315_LNLDO1_PU               9       /* 0x00000200 */
483 #define RES4315_OTP_PU                  10      /* 0x00000400 */
484 #define RES4315_LNLDO2_PU               12      /* 0x00001000 */
485 #define RES4315_XTAL_PU                 13      /* 0x00002000 */
486 #define RES4315_ALP_AVAIL               14      /* 0x00004000 */
487 #define RES4315_RX_PWRSW_PU             15      /* 0x00008000 */
488 #define RES4315_TX_PWRSW_PU             16      /* 0x00010000 */
489 #define RES4315_RFPLL_PWRSW_PU          17      /* 0x00020000 */
490 #define RES4315_LOGEN_PWRSW_PU          18      /* 0x00040000 */
491 #define RES4315_AFE_PWRSW_PU            19      /* 0x00080000 */
492 #define RES4315_BBPLL_PWRSW_PU          20      /* 0x00100000 */
493 #define RES4315_HT_AVAIL                21      /* 0x00200000 */
494
495 /* 4319 resources */
496 #define RES4319_CBUCK_LPOM              1       /* 0x00000002 */
497 #define RES4319_CBUCK_BURST             2       /* 0x00000004 */
498 #define RES4319_CBUCK_PWM               3       /* 0x00000008 */
499 #define RES4319_CLDO_PU                 4       /* 0x00000010 */
500 #define RES4319_PALDO_PU                5       /* 0x00000020 */
501 #define RES4319_ILP_REQUEST             6       /* 0x00000040 */
502 #define RES4319_LNLDO1_PU               9       /* 0x00000200 */
503 #define RES4319_OTP_PU                  10      /* 0x00000400 */
504 #define RES4319_LNLDO2_PU               12      /* 0x00001000 */
505 #define RES4319_XTAL_PU                 13      /* 0x00002000 */
506 #define RES4319_ALP_AVAIL               14      /* 0x00004000 */
507 #define RES4319_RX_PWRSW_PU             15      /* 0x00008000 */
508 #define RES4319_TX_PWRSW_PU             16      /* 0x00010000 */
509 #define RES4319_RFPLL_PWRSW_PU          17      /* 0x00020000 */
510 #define RES4319_LOGEN_PWRSW_PU          18      /* 0x00040000 */
511 #define RES4319_AFE_PWRSW_PU            19      /* 0x00080000 */
512 #define RES4319_BBPLL_PWRSW_PU          20      /* 0x00100000 */
513 #define RES4319_HT_AVAIL                21      /* 0x00200000 */
514
515 #define CCTL_4319USB_XTAL_SEL_MASK      0x00180000
516 #define CCTL_4319USB_XTAL_SEL_SHIFT     19
517 #define CCTL_4319USB_48MHZ_PLL_SEL      1
518 #define CCTL_4319USB_24MHZ_PLL_SEL      2
519
520 /* PMU resources for 4336 */
521 #define RES4336_CBUCK_LPOM              0
522 #define RES4336_CBUCK_BURST             1
523 #define RES4336_CBUCK_LP_PWM            2
524 #define RES4336_CBUCK_PWM               3
525 #define RES4336_CLDO_PU                 4
526 #define RES4336_DIS_INT_RESET_PD        5
527 #define RES4336_ILP_REQUEST             6
528 #define RES4336_LNLDO_PU                7
529 #define RES4336_LDO3P3_PU               8
530 #define RES4336_OTP_PU                  9
531 #define RES4336_XTAL_PU                 10
532 #define RES4336_ALP_AVAIL               11
533 #define RES4336_RADIO_PU                12
534 #define RES4336_BG_PU                   13
535 #define RES4336_VREG1p4_PU_PU           14
536 #define RES4336_AFE_PWRSW_PU            15
537 #define RES4336_RX_PWRSW_PU             16
538 #define RES4336_TX_PWRSW_PU             17
539 #define RES4336_BB_PWRSW_PU             18
540 #define RES4336_SYNTH_PWRSW_PU          19
541 #define RES4336_MISC_PWRSW_PU           20
542 #define RES4336_LOGEN_PWRSW_PU          21
543 #define RES4336_BBPLL_PWRSW_PU          22
544 #define RES4336_MACPHY_CLKAVAIL         23
545 #define RES4336_HT_AVAIL                24
546 #define RES4336_RSVD                    25
547
548 /* 4330 resources */
549 #define RES4330_CBUCK_LPOM              0
550 #define RES4330_CBUCK_BURST             1
551 #define RES4330_CBUCK_LP_PWM            2
552 #define RES4330_CBUCK_PWM               3
553 #define RES4330_CLDO_PU                 4
554 #define RES4330_DIS_INT_RESET_PD        5
555 #define RES4330_ILP_REQUEST             6
556 #define RES4330_LNLDO_PU                7
557 #define RES4330_LDO3P3_PU               8
558 #define RES4330_OTP_PU                  9
559 #define RES4330_XTAL_PU                 10
560 #define RES4330_ALP_AVAIL               11
561 #define RES4330_RADIO_PU                12
562 #define RES4330_BG_PU                   13
563 #define RES4330_VREG1p4_PU_PU           14
564 #define RES4330_AFE_PWRSW_PU            15
565 #define RES4330_RX_PWRSW_PU             16
566 #define RES4330_TX_PWRSW_PU             17
567 #define RES4330_BB_PWRSW_PU             18
568 #define RES4330_SYNTH_PWRSW_PU          19
569 #define RES4330_MISC_PWRSW_PU           20
570 #define RES4330_LOGEN_PWRSW_PU          21
571 #define RES4330_BBPLL_PWRSW_PU          22
572 #define RES4330_MACPHY_CLKAVAIL         23
573 #define RES4330_HT_AVAIL                24
574 #define RES4330_5gRX_PWRSW_PU           25
575 #define RES4330_5gTX_PWRSW_PU           26
576 #define RES4330_5g_LOGEN_PWRSW_PU       27
577
578 /* 4313 resources */
579 #define RES4313_BB_PU_RSRC              0
580 #define RES4313_ILP_REQ_RSRC            1
581 #define RES4313_XTAL_PU_RSRC            2
582 #define RES4313_ALP_AVAIL_RSRC          3
583 #define RES4313_RADIO_PU_RSRC           4
584 #define RES4313_BG_PU_RSRC              5
585 #define RES4313_VREG1P4_PU_RSRC         6
586 #define RES4313_AFE_PWRSW_RSRC          7
587 #define RES4313_RX_PWRSW_RSRC           8
588 #define RES4313_TX_PWRSW_RSRC           9
589 #define RES4313_BB_PWRSW_RSRC           10
590 #define RES4313_SYNTH_PWRSW_RSRC        11
591 #define RES4313_MISC_PWRSW_RSRC         12
592 #define RES4313_BB_PLL_PWRSW_RSRC       13
593 #define RES4313_HT_AVAIL_RSRC           14
594 #define RES4313_MACPHY_CLK_AVAIL_RSRC   15
595
596 /* PMU resource up transition time in ILP cycles */
597 #define PMURES_UP_TRANSITION    2
598
599 /* Setup resource up/down timers */
600 typedef struct {
601         u8 resnum;
602         u16 updown;
603 } pmu_res_updown_t;
604
605 /* Change resource dependancies masks */
606 typedef struct {
607         u32 res_mask;   /* resources (chip specific) */
608         s8 action;              /* action */
609         u32 depend_mask;        /* changes to the dependancies mask */
610          bool(*filter) (si_t *sih);     /* action is taken when filter is NULL or return true */
611 } pmu_res_depend_t;
612
613 /* setup pll and query clock speed */
614 typedef struct {
615         u16 fref;
616         u8 xf;
617         u8 p1div;
618         u8 p2div;
619         u8 ndiv_int;
620         u32 ndiv_frac;
621 } pmu1_xtaltab0_t;
622
623 /*
624  * prototypes used in resource tables
625  */
626 static bool si_pmu_res_depfltr_bb(si_t *sih);
627 static bool si_pmu_res_depfltr_ncb(si_t *sih);
628 static bool si_pmu_res_depfltr_paldo(si_t *sih);
629 static bool si_pmu_res_depfltr_npaldo(si_t *sih);
630
631 static const pmu_res_updown_t bcm4328a0_res_updown[] = {
632         {
633         RES4328_EXT_SWITCHER_PWM, 0x0101}, {
634         RES4328_BB_SWITCHER_PWM, 0x1f01}, {
635         RES4328_BB_SWITCHER_BURST, 0x010f}, {
636         RES4328_BB_EXT_SWITCHER_BURST, 0x0101}, {
637         RES4328_ILP_REQUEST, 0x0202}, {
638         RES4328_RADIO_SWITCHER_PWM, 0x0f01}, {
639         RES4328_RADIO_SWITCHER_BURST, 0x0f01}, {
640         RES4328_ROM_SWITCH, 0x0101}, {
641         RES4328_PA_REF_LDO, 0x0f01}, {
642         RES4328_RADIO_LDO, 0x0f01}, {
643         RES4328_AFE_LDO, 0x0f01}, {
644         RES4328_PLL_LDO, 0x0f01}, {
645         RES4328_BG_FILTBYP, 0x0101}, {
646         RES4328_TX_FILTBYP, 0x0101}, {
647         RES4328_RX_FILTBYP, 0x0101}, {
648         RES4328_XTAL_PU, 0x0101}, {
649         RES4328_XTAL_EN, 0xa001}, {
650         RES4328_BB_PLL_FILTBYP, 0x0101}, {
651         RES4328_RF_PLL_FILTBYP, 0x0101}, {
652         RES4328_BB_PLL_PU, 0x0701}
653 };
654
655 static const pmu_res_depend_t bcm4328a0_res_depend[] = {
656         /* Adjust ILP request resource not to force ext/BB switchers into burst mode */
657         {
658         PMURES_BIT(RES4328_ILP_REQUEST),
659                     RES_DEPEND_SET,
660                     PMURES_BIT(RES4328_EXT_SWITCHER_PWM) |
661                     PMURES_BIT(RES4328_BB_SWITCHER_PWM), NULL}
662 };
663
664 static const pmu_res_updown_t bcm4325a0_res_updown_qt[] = {
665         {
666         RES4325_HT_AVAIL, 0x0300}, {
667         RES4325_BBPLL_PWRSW_PU, 0x0101}, {
668         RES4325_RFPLL_PWRSW_PU, 0x0101}, {
669         RES4325_ALP_AVAIL, 0x0100}, {
670         RES4325_XTAL_PU, 0x1000}, {
671         RES4325_LNLDO1_PU, 0x0800}, {
672         RES4325_CLDO_CBUCK_PWM, 0x0101}, {
673         RES4325_CBUCK_PWM, 0x0803}
674 };
675
676 static const pmu_res_updown_t bcm4325a0_res_updown[] = {
677         {
678         RES4325_XTAL_PU, 0x1501}
679 };
680
681 static const pmu_res_depend_t bcm4325a0_res_depend[] = {
682         /* Adjust OTP PU resource dependencies - remove BB BURST */
683         {
684         PMURES_BIT(RES4325_OTP_PU),
685                     RES_DEPEND_REMOVE,
686                     PMURES_BIT(RES4325_BUCK_BOOST_BURST), NULL},
687             /* Adjust ALP/HT Avail resource dependencies - bring up BB along if it is used. */
688         {
689         PMURES_BIT(RES4325_ALP_AVAIL) | PMURES_BIT(RES4325_HT_AVAIL),
690                     RES_DEPEND_ADD,
691                     PMURES_BIT(RES4325_BUCK_BOOST_BURST) |
692                     PMURES_BIT(RES4325_BUCK_BOOST_PWM), si_pmu_res_depfltr_bb},
693             /* Adjust HT Avail resource dependencies - bring up RF switches along with HT. */
694         {
695         PMURES_BIT(RES4325_HT_AVAIL),
696                     RES_DEPEND_ADD,
697                     PMURES_BIT(RES4325_RX_PWRSW_PU) |
698                     PMURES_BIT(RES4325_TX_PWRSW_PU) |
699                     PMURES_BIT(RES4325_LOGEN_PWRSW_PU) |
700                     PMURES_BIT(RES4325_AFE_PWRSW_PU), NULL},
701             /* Adjust ALL resource dependencies - remove CBUCK dependancies if it is not used. */
702         {
703         PMURES_BIT(RES4325_ILP_REQUEST) |
704                     PMURES_BIT(RES4325_ABUCK_BURST) |
705                     PMURES_BIT(RES4325_ABUCK_PWM) |
706                     PMURES_BIT(RES4325_LNLDO1_PU) |
707                     PMURES_BIT(RES4325C1_LNLDO2_PU) |
708                     PMURES_BIT(RES4325_XTAL_PU) |
709                     PMURES_BIT(RES4325_ALP_AVAIL) |
710                     PMURES_BIT(RES4325_RX_PWRSW_PU) |
711                     PMURES_BIT(RES4325_TX_PWRSW_PU) |
712                     PMURES_BIT(RES4325_RFPLL_PWRSW_PU) |
713                     PMURES_BIT(RES4325_LOGEN_PWRSW_PU) |
714                     PMURES_BIT(RES4325_AFE_PWRSW_PU) |
715                     PMURES_BIT(RES4325_BBPLL_PWRSW_PU) |
716                     PMURES_BIT(RES4325_HT_AVAIL), RES_DEPEND_REMOVE,
717                     PMURES_BIT(RES4325B0_CBUCK_LPOM) |
718                     PMURES_BIT(RES4325B0_CBUCK_BURST) |
719                     PMURES_BIT(RES4325B0_CBUCK_PWM), si_pmu_res_depfltr_ncb}
720 };
721
722 static const pmu_res_updown_t bcm4315a0_res_updown_qt[] = {
723         {
724         RES4315_HT_AVAIL, 0x0101}, {
725         RES4315_XTAL_PU, 0x0100}, {
726         RES4315_LNLDO1_PU, 0x0100}, {
727         RES4315_PALDO_PU, 0x0100}, {
728         RES4315_CLDO_PU, 0x0100}, {
729         RES4315_CBUCK_PWM, 0x0100}, {
730         RES4315_CBUCK_BURST, 0x0100}, {
731         RES4315_CBUCK_LPOM, 0x0100}
732 };
733
734 static const pmu_res_updown_t bcm4315a0_res_updown[] = {
735         {
736         RES4315_XTAL_PU, 0x2501}
737 };
738
739 static const pmu_res_depend_t bcm4315a0_res_depend[] = {
740         /* Adjust OTP PU resource dependencies - not need PALDO unless write */
741         {
742         PMURES_BIT(RES4315_OTP_PU),
743                     RES_DEPEND_REMOVE,
744                     PMURES_BIT(RES4315_PALDO_PU), si_pmu_res_depfltr_npaldo},
745             /* Adjust ALP/HT Avail resource dependencies - bring up PALDO along if it is used. */
746         {
747         PMURES_BIT(RES4315_ALP_AVAIL) | PMURES_BIT(RES4315_HT_AVAIL),
748                     RES_DEPEND_ADD,
749                     PMURES_BIT(RES4315_PALDO_PU), si_pmu_res_depfltr_paldo},
750             /* Adjust HT Avail resource dependencies - bring up RF switches along with HT. */
751         {
752         PMURES_BIT(RES4315_HT_AVAIL),
753                     RES_DEPEND_ADD,
754                     PMURES_BIT(RES4315_RX_PWRSW_PU) |
755                     PMURES_BIT(RES4315_TX_PWRSW_PU) |
756                     PMURES_BIT(RES4315_LOGEN_PWRSW_PU) |
757                     PMURES_BIT(RES4315_AFE_PWRSW_PU), NULL},
758             /* Adjust ALL resource dependencies - remove CBUCK dependancies if it is not used. */
759         {
760         PMURES_BIT(RES4315_CLDO_PU) | PMURES_BIT(RES4315_ILP_REQUEST) |
761                     PMURES_BIT(RES4315_LNLDO1_PU) |
762                     PMURES_BIT(RES4315_OTP_PU) |
763                     PMURES_BIT(RES4315_LNLDO2_PU) |
764                     PMURES_BIT(RES4315_XTAL_PU) |
765                     PMURES_BIT(RES4315_ALP_AVAIL) |
766                     PMURES_BIT(RES4315_RX_PWRSW_PU) |
767                     PMURES_BIT(RES4315_TX_PWRSW_PU) |
768                     PMURES_BIT(RES4315_RFPLL_PWRSW_PU) |
769                     PMURES_BIT(RES4315_LOGEN_PWRSW_PU) |
770                     PMURES_BIT(RES4315_AFE_PWRSW_PU) |
771                     PMURES_BIT(RES4315_BBPLL_PWRSW_PU) |
772                     PMURES_BIT(RES4315_HT_AVAIL), RES_DEPEND_REMOVE,
773                     PMURES_BIT(RES4315_CBUCK_LPOM) |
774                     PMURES_BIT(RES4315_CBUCK_BURST) |
775                     PMURES_BIT(RES4315_CBUCK_PWM), si_pmu_res_depfltr_ncb}
776 };
777
778         /* 4329 specific. needs to come back this issue later */
779 static const pmu_res_updown_t bcm4329_res_updown[] = {
780         {
781         RES4329_XTAL_PU, 0x1501}
782 };
783
784 static const pmu_res_depend_t bcm4329_res_depend[] = {
785         /* Adjust HT Avail resource dependencies */
786         {
787         PMURES_BIT(RES4329_HT_AVAIL),
788                     RES_DEPEND_ADD,
789                     PMURES_BIT(RES4329_CBUCK_LPOM) |
790                     PMURES_BIT(RES4329_CBUCK_BURST) |
791                     PMURES_BIT(RES4329_CBUCK_PWM) |
792                     PMURES_BIT(RES4329_CLDO_PU) |
793                     PMURES_BIT(RES4329_PALDO_PU) |
794                     PMURES_BIT(RES4329_LNLDO1_PU) |
795                     PMURES_BIT(RES4329_XTAL_PU) |
796                     PMURES_BIT(RES4329_ALP_AVAIL) |
797                     PMURES_BIT(RES4329_RX_PWRSW_PU) |
798                     PMURES_BIT(RES4329_TX_PWRSW_PU) |
799                     PMURES_BIT(RES4329_RFPLL_PWRSW_PU) |
800                     PMURES_BIT(RES4329_LOGEN_PWRSW_PU) |
801                     PMURES_BIT(RES4329_AFE_PWRSW_PU) |
802                     PMURES_BIT(RES4329_BBPLL_PWRSW_PU), NULL}
803 };
804
805 static const pmu_res_updown_t bcm4319a0_res_updown_qt[] = {
806         {
807         RES4319_HT_AVAIL, 0x0101}, {
808         RES4319_XTAL_PU, 0x0100}, {
809         RES4319_LNLDO1_PU, 0x0100}, {
810         RES4319_PALDO_PU, 0x0100}, {
811         RES4319_CLDO_PU, 0x0100}, {
812         RES4319_CBUCK_PWM, 0x0100}, {
813         RES4319_CBUCK_BURST, 0x0100}, {
814         RES4319_CBUCK_LPOM, 0x0100}
815 };
816
817 static const pmu_res_updown_t bcm4319a0_res_updown[] = {
818         {
819         RES4319_XTAL_PU, 0x3f01}
820 };
821
822 static const pmu_res_depend_t bcm4319a0_res_depend[] = {
823         /* Adjust OTP PU resource dependencies - not need PALDO unless write */
824         {
825         PMURES_BIT(RES4319_OTP_PU),
826                     RES_DEPEND_REMOVE,
827                     PMURES_BIT(RES4319_PALDO_PU), si_pmu_res_depfltr_npaldo},
828             /* Adjust HT Avail resource dependencies - bring up PALDO along if it is used. */
829         {
830         PMURES_BIT(RES4319_HT_AVAIL),
831                     RES_DEPEND_ADD,
832                     PMURES_BIT(RES4319_PALDO_PU), si_pmu_res_depfltr_paldo},
833             /* Adjust HT Avail resource dependencies - bring up RF switches along with HT. */
834         {
835         PMURES_BIT(RES4319_HT_AVAIL),
836                     RES_DEPEND_ADD,
837                     PMURES_BIT(RES4319_RX_PWRSW_PU) |
838                     PMURES_BIT(RES4319_TX_PWRSW_PU) |
839                     PMURES_BIT(RES4319_RFPLL_PWRSW_PU) |
840                     PMURES_BIT(RES4319_LOGEN_PWRSW_PU) |
841                     PMURES_BIT(RES4319_AFE_PWRSW_PU), NULL}
842 };
843
844 static const pmu_res_updown_t bcm4336a0_res_updown_qt[] = {
845         {
846         RES4336_HT_AVAIL, 0x0101}, {
847         RES4336_XTAL_PU, 0x0100}, {
848         RES4336_CLDO_PU, 0x0100}, {
849         RES4336_CBUCK_PWM, 0x0100}, {
850         RES4336_CBUCK_BURST, 0x0100}, {
851         RES4336_CBUCK_LPOM, 0x0100}
852 };
853
854 static const pmu_res_updown_t bcm4336a0_res_updown[] = {
855         {
856         RES4336_HT_AVAIL, 0x0D01}
857 };
858
859 static const pmu_res_depend_t bcm4336a0_res_depend[] = {
860         /* Just a dummy entry for now */
861         {
862         PMURES_BIT(RES4336_RSVD), RES_DEPEND_ADD, 0, NULL}
863 };
864
865 static const pmu_res_updown_t bcm4330a0_res_updown_qt[] = {
866         {
867         RES4330_HT_AVAIL, 0x0101}, {
868         RES4330_XTAL_PU, 0x0100}, {
869         RES4330_CLDO_PU, 0x0100}, {
870         RES4330_CBUCK_PWM, 0x0100}, {
871         RES4330_CBUCK_BURST, 0x0100}, {
872         RES4330_CBUCK_LPOM, 0x0100}
873 };
874
875 static const pmu_res_updown_t bcm4330a0_res_updown[] = {
876         {
877         RES4330_HT_AVAIL, 0x0e02}
878 };
879
880 static const pmu_res_depend_t bcm4330a0_res_depend[] = {
881         /* Just a dummy entry for now */
882         {
883         PMURES_BIT(RES4330_HT_AVAIL), RES_DEPEND_ADD, 0, NULL}
884 };
885
886 /* the following table is based on 1440Mhz fvco */
887 static const pmu1_xtaltab0_t pmu1_xtaltab0_1440[] = {
888         {
889         12000, 1, 1, 1, 0x78, 0x0}, {
890         13000, 2, 1, 1, 0x6E, 0xC4EC4E}, {
891         14400, 3, 1, 1, 0x64, 0x0}, {
892         15360, 4, 1, 1, 0x5D, 0xC00000}, {
893         16200, 5, 1, 1, 0x58, 0xE38E38}, {
894         16800, 6, 1, 1, 0x55, 0xB6DB6D}, {
895         19200, 7, 1, 1, 0x4B, 0}, {
896         19800, 8, 1, 1, 0x48, 0xBA2E8B}, {
897         20000, 9, 1, 1, 0x48, 0x0}, {
898         25000, 10, 1, 1, 0x39, 0x999999}, {
899         26000, 11, 1, 1, 0x37, 0x627627}, {
900         30000, 12, 1, 1, 0x30, 0x0}, {
901         37400, 13, 2, 1, 0x4D, 0x15E76}, {
902         38400, 13, 2, 1, 0x4B, 0x0}, {
903         40000, 14, 2, 1, 0x48, 0x0}, {
904         48000, 15, 2, 1, 0x3c, 0x0}, {
905         0, 0, 0, 0, 0, 0}
906 };
907
908 static const pmu1_xtaltab0_t pmu1_xtaltab0_960[] = {
909         {
910         12000, 1, 1, 1, 0x50, 0x0}, {
911         13000, 2, 1, 1, 0x49, 0xD89D89}, {
912         14400, 3, 1, 1, 0x42, 0xAAAAAA}, {
913         15360, 4, 1, 1, 0x3E, 0x800000}, {
914         16200, 5, 1, 1, 0x39, 0x425ED0}, {
915         16800, 6, 1, 1, 0x39, 0x249249}, {
916         19200, 7, 1, 1, 0x32, 0x0}, {
917         19800, 8, 1, 1, 0x30, 0x7C1F07}, {
918         20000, 9, 1, 1, 0x30, 0x0}, {
919         25000, 10, 1, 1, 0x26, 0x666666}, {
920         26000, 11, 1, 1, 0x24, 0xEC4EC4}, {
921         30000, 12, 1, 1, 0x20, 0x0}, {
922         37400, 13, 2, 1, 0x33, 0x563EF9}, {
923         38400, 14, 2, 1, 0x32, 0x0}, {
924         40000, 15, 2, 1, 0x30, 0x0}, {
925         48000, 16, 2, 1, 0x28, 0x0}, {
926         0, 0, 0, 0, 0, 0}
927 };
928
929 static const pmu1_xtaltab0_t pmu1_xtaltab0_880_4329[] = {
930         {
931         12000, 1, 3, 22, 0x9, 0xFFFFEF}, {
932         13000, 2, 1, 6, 0xb, 0x483483}, {
933         14400, 3, 1, 10, 0xa, 0x1C71C7}, {
934         15360, 4, 1, 5, 0xb, 0x755555}, {
935         16200, 5, 1, 10, 0x5, 0x6E9E06}, {
936         16800, 6, 1, 10, 0x5, 0x3Cf3Cf}, {
937         19200, 7, 1, 4, 0xb, 0x755555}, {
938         19800, 8, 1, 11, 0x4, 0xA57EB}, {
939         20000, 9, 1, 11, 0x4, 0x0}, {
940         24000, 10, 3, 11, 0xa, 0x0}, {
941         25000, 11, 5, 16, 0xb, 0x0}, {
942         26000, 12, 1, 1, 0x21, 0xD89D89}, {
943         30000, 13, 3, 8, 0xb, 0x0}, {
944         37400, 14, 3, 1, 0x46, 0x969696}, {
945         38400, 15, 1, 1, 0x16, 0xEAAAAA}, {
946         40000, 16, 1, 2, 0xb, 0}, {
947         0, 0, 0, 0, 0, 0}
948 };
949
950 /* the following table is based on 880Mhz fvco */
951 static const pmu1_xtaltab0_t pmu1_xtaltab0_880[] = {
952         {
953         12000, 1, 3, 22, 0x9, 0xFFFFEF}, {
954         13000, 2, 1, 6, 0xb, 0x483483}, {
955         14400, 3, 1, 10, 0xa, 0x1C71C7}, {
956         15360, 4, 1, 5, 0xb, 0x755555}, {
957         16200, 5, 1, 10, 0x5, 0x6E9E06}, {
958         16800, 6, 1, 10, 0x5, 0x3Cf3Cf}, {
959         19200, 7, 1, 4, 0xb, 0x755555}, {
960         19800, 8, 1, 11, 0x4, 0xA57EB}, {
961         20000, 9, 1, 11, 0x4, 0x0}, {
962         24000, 10, 3, 11, 0xa, 0x0}, {
963         25000, 11, 5, 16, 0xb, 0x0}, {
964         26000, 12, 1, 2, 0x10, 0xEC4EC4}, {
965         30000, 13, 3, 8, 0xb, 0x0}, {
966         33600, 14, 1, 2, 0xd, 0x186186}, {
967         38400, 15, 1, 2, 0xb, 0x755555}, {
968         40000, 16, 1, 2, 0xb, 0}, {
969         0, 0, 0, 0, 0, 0}
970 };
971
972 /* true if the power topology uses the buck boost to provide 3.3V to VDDIO_RF and WLAN PA */
973 static bool si_pmu_res_depfltr_bb(si_t *sih)
974 {
975         return (sih->boardflags & BFL_BUCKBOOST) != 0;
976 }
977
978 /* true if the power topology doesn't use the cbuck. Key on chiprev also if the chip is BCM4325. */
979 static bool si_pmu_res_depfltr_ncb(si_t *sih)
980 {
981
982         return (sih->boardflags & BFL_NOCBUCK) != 0;
983 }
984
985 /* true if the power topology uses the PALDO */
986 static bool si_pmu_res_depfltr_paldo(si_t *sih)
987 {
988         return (sih->boardflags & BFL_PALDO) != 0;
989 }
990
991 /* true if the power topology doesn't use the PALDO */
992 static bool si_pmu_res_depfltr_npaldo(si_t *sih)
993 {
994         return (sih->boardflags & BFL_PALDO) == 0;
995 }
996
997 /* Return dependancies (direct or all/indirect) for the given resources */
998 static u32
999 si_pmu_res_deps(si_t *sih, chipcregs_t *cc, u32 rsrcs,
1000                 bool all)
1001 {
1002         u32 deps = 0;
1003         u32 i;
1004
1005         for (i = 0; i <= PMURES_MAX_RESNUM; i++) {
1006                 if (!(rsrcs & PMURES_BIT(i)))
1007                         continue;
1008                 W_REG(&cc->res_table_sel, i);
1009                 deps |= R_REG(&cc->res_dep_mask);
1010         }
1011
1012         return !all ? deps : (deps
1013                               ? (deps |
1014                                  si_pmu_res_deps(sih, cc, deps,
1015                                                  true)) : 0);
1016 }
1017
1018 /* Determine min/max rsrc masks. Value 0 leaves hardware at default. */
1019 static void si_pmu_res_masks(si_t *sih, u32 * pmin, u32 * pmax)
1020 {
1021         u32 min_mask = 0, max_mask = 0;
1022         uint rsrcs;
1023         char *val;
1024
1025         /* # resources */
1026         rsrcs = (sih->pmucaps & PCAP_RC_MASK) >> PCAP_RC_SHIFT;
1027
1028         /* determine min/max rsrc masks */
1029         switch (sih->chip) {
1030         case BCM43224_CHIP_ID:
1031         case BCM43225_CHIP_ID:
1032         case BCM43421_CHIP_ID:
1033         case BCM43235_CHIP_ID:
1034         case BCM43236_CHIP_ID:
1035         case BCM43238_CHIP_ID:
1036         case BCM4331_CHIP_ID:
1037         case BCM6362_CHIP_ID:
1038                 /* ??? */
1039                 break;
1040
1041         case BCM4329_CHIP_ID:
1042                 /* 4329 spedific issue. Needs to come back this issue later */
1043                 /* Down to save the power. */
1044                 min_mask =
1045                     PMURES_BIT(RES4329_CBUCK_LPOM) |
1046                     PMURES_BIT(RES4329_CLDO_PU);
1047                 /* Allow (but don't require) PLL to turn on */
1048                 max_mask = 0x3ff63e;
1049                 break;
1050         case BCM4319_CHIP_ID:
1051                 /* We only need a few resources to be kept on all the time */
1052                 min_mask = PMURES_BIT(RES4319_CBUCK_LPOM) |
1053                     PMURES_BIT(RES4319_CLDO_PU);
1054
1055                 /* Allow everything else to be turned on upon requests */
1056                 max_mask = ~(~0 << rsrcs);
1057                 break;
1058         case BCM4336_CHIP_ID:
1059                 /* Down to save the power. */
1060                 min_mask =
1061                     PMURES_BIT(RES4336_CBUCK_LPOM) | PMURES_BIT(RES4336_CLDO_PU)
1062                     | PMURES_BIT(RES4336_LDO3P3_PU) | PMURES_BIT(RES4336_OTP_PU)
1063                     | PMURES_BIT(RES4336_DIS_INT_RESET_PD);
1064                 /* Allow (but don't require) PLL to turn on */
1065                 max_mask = 0x1ffffff;
1066                 break;
1067
1068         case BCM4330_CHIP_ID:
1069                 /* Down to save the power. */
1070                 min_mask =
1071                     PMURES_BIT(RES4330_CBUCK_LPOM) | PMURES_BIT(RES4330_CLDO_PU)
1072                     | PMURES_BIT(RES4330_DIS_INT_RESET_PD) |
1073                     PMURES_BIT(RES4330_LDO3P3_PU) | PMURES_BIT(RES4330_OTP_PU);
1074                 /* Allow (but don't require) PLL to turn on */
1075                 max_mask = 0xfffffff;
1076                 break;
1077
1078         case BCM4313_CHIP_ID:
1079                 min_mask = PMURES_BIT(RES4313_BB_PU_RSRC) |
1080                     PMURES_BIT(RES4313_XTAL_PU_RSRC) |
1081                     PMURES_BIT(RES4313_ALP_AVAIL_RSRC) |
1082                     PMURES_BIT(RES4313_BB_PLL_PWRSW_RSRC);
1083                 max_mask = 0xffff;
1084                 break;
1085         default:
1086                 break;
1087         }
1088
1089         /* Apply nvram override to min mask */
1090         val = getvar(NULL, "rmin");
1091         if (val != NULL) {
1092                 min_mask = (u32) simple_strtoul(val, NULL, 0);
1093         }
1094         /* Apply nvram override to max mask */
1095         val = getvar(NULL, "rmax");
1096         if (val != NULL) {
1097                 max_mask = (u32) simple_strtoul(val, NULL, 0);
1098         }
1099
1100         *pmin = min_mask;
1101         *pmax = max_mask;
1102 }
1103
1104 /* Return up time in ILP cycles for the given resource. */
1105 static uint
1106 si_pmu_res_uptime(si_t *sih, chipcregs_t *cc, u8 rsrc) {
1107         u32 deps;
1108         uint up, i, dup, dmax;
1109         u32 min_mask = 0, max_mask = 0;
1110
1111         /* uptime of resource 'rsrc' */
1112         W_REG(&cc->res_table_sel, rsrc);
1113         up = (R_REG(&cc->res_updn_timer) >> 8) & 0xff;
1114
1115         /* direct dependancies of resource 'rsrc' */
1116         deps = si_pmu_res_deps(sih, cc, PMURES_BIT(rsrc), false);
1117         for (i = 0; i <= PMURES_MAX_RESNUM; i++) {
1118                 if (!(deps & PMURES_BIT(i)))
1119                         continue;
1120                 deps &= ~si_pmu_res_deps(sih, cc, PMURES_BIT(i), true);
1121         }
1122         si_pmu_res_masks(sih, &min_mask, &max_mask);
1123         deps &= ~min_mask;
1124
1125         /* max uptime of direct dependancies */
1126         dmax = 0;
1127         for (i = 0; i <= PMURES_MAX_RESNUM; i++) {
1128                 if (!(deps & PMURES_BIT(i)))
1129                         continue;
1130                 dup = si_pmu_res_uptime(sih, cc, (u8) i);
1131                 if (dmax < dup)
1132                         dmax = dup;
1133         }
1134
1135         return up + dmax + PMURES_UP_TRANSITION;
1136 }
1137
1138 static void
1139 si_pmu_spuravoid_pllupdate(si_t *sih, chipcregs_t *cc, u8 spuravoid)
1140 {
1141         u32 tmp = 0;
1142         u8 phypll_offset = 0;
1143         u8 bcm5357_bcm43236_p1div[] = { 0x1, 0x5, 0x5 };
1144         u8 bcm5357_bcm43236_ndiv[] = { 0x30, 0xf6, 0xfc };
1145
1146         switch (sih->chip) {
1147         case BCM5357_CHIP_ID:
1148         case BCM43235_CHIP_ID:
1149         case BCM43236_CHIP_ID:
1150         case BCM43238_CHIP_ID:
1151
1152                 /*
1153                  * BCM5357 needs to touch PLL1_PLLCTL[02],
1154                  * so offset PLL0_PLLCTL[02] by 6
1155                  */
1156                 phypll_offset = (sih->chip == BCM5357_CHIP_ID) ? 6 : 0;
1157
1158                 /* RMW only the P1 divider */
1159                 W_REG(&cc->pllcontrol_addr,
1160                       PMU1_PLL0_PLLCTL0 + phypll_offset);
1161                 tmp = R_REG(&cc->pllcontrol_data);
1162                 tmp &= (~(PMU1_PLL0_PC0_P1DIV_MASK));
1163                 tmp |=
1164                     (bcm5357_bcm43236_p1div[spuravoid] <<
1165                      PMU1_PLL0_PC0_P1DIV_SHIFT);
1166                 W_REG(&cc->pllcontrol_data, tmp);
1167
1168                 /* RMW only the int feedback divider */
1169                 W_REG(&cc->pllcontrol_addr,
1170                       PMU1_PLL0_PLLCTL2 + phypll_offset);
1171                 tmp = R_REG(&cc->pllcontrol_data);
1172                 tmp &= ~(PMU1_PLL0_PC2_NDIV_INT_MASK);
1173                 tmp |=
1174                     (bcm5357_bcm43236_ndiv[spuravoid]) <<
1175                     PMU1_PLL0_PC2_NDIV_INT_SHIFT;
1176                 W_REG(&cc->pllcontrol_data, tmp);
1177
1178                 tmp = 1 << 10;
1179                 break;
1180
1181         case BCM4331_CHIP_ID:
1182                 if (spuravoid == 2) {
1183                         W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0);
1184                         W_REG(&cc->pllcontrol_data, 0x11500014);
1185                         W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2);
1186                         W_REG(&cc->pllcontrol_data, 0x0FC00a08);
1187                 } else if (spuravoid == 1) {
1188                         W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0);
1189                         W_REG(&cc->pllcontrol_data, 0x11500014);
1190                         W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2);
1191                         W_REG(&cc->pllcontrol_data, 0x0F600a08);
1192                 } else {
1193                         W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0);
1194                         W_REG(&cc->pllcontrol_data, 0x11100014);
1195                         W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2);
1196                         W_REG(&cc->pllcontrol_data, 0x03000a08);
1197                 }
1198                 tmp = 1 << 10;
1199                 break;
1200
1201         case BCM43224_CHIP_ID:
1202         case BCM43225_CHIP_ID:
1203         case BCM43421_CHIP_ID:
1204         case BCM6362_CHIP_ID:
1205                 if (spuravoid == 1) {
1206                         W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0);
1207                         W_REG(&cc->pllcontrol_data, 0x11500010);
1208                         W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1);
1209                         W_REG(&cc->pllcontrol_data, 0x000C0C06);
1210                         W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2);
1211                         W_REG(&cc->pllcontrol_data, 0x0F600a08);
1212                         W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3);
1213                         W_REG(&cc->pllcontrol_data, 0x00000000);
1214                         W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4);
1215                         W_REG(&cc->pllcontrol_data, 0x2001E920);
1216                         W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5);
1217                         W_REG(&cc->pllcontrol_data, 0x88888815);
1218                 } else {
1219                         W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0);
1220                         W_REG(&cc->pllcontrol_data, 0x11100010);
1221                         W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1);
1222                         W_REG(&cc->pllcontrol_data, 0x000c0c06);
1223                         W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2);
1224                         W_REG(&cc->pllcontrol_data, 0x03000a08);
1225                         W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3);
1226                         W_REG(&cc->pllcontrol_data, 0x00000000);
1227                         W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4);
1228                         W_REG(&cc->pllcontrol_data, 0x200005c0);
1229                         W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5);
1230                         W_REG(&cc->pllcontrol_data, 0x88888815);
1231                 }
1232                 tmp = 1 << 10;
1233                 break;
1234
1235                 W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0);
1236                 W_REG(&cc->pllcontrol_data, 0x11100008);
1237                 W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1);
1238                 W_REG(&cc->pllcontrol_data, 0x0c000c06);
1239                 W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2);
1240                 W_REG(&cc->pllcontrol_data, 0x03000a08);
1241                 W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3);
1242                 W_REG(&cc->pllcontrol_data, 0x00000000);
1243                 W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4);
1244                 W_REG(&cc->pllcontrol_data, 0x200005c0);
1245                 W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5);
1246                 W_REG(&cc->pllcontrol_data, 0x88888855);
1247
1248                 tmp = 1 << 10;
1249                 break;
1250
1251         case BCM4716_CHIP_ID:
1252         case BCM4748_CHIP_ID:
1253         case BCM47162_CHIP_ID:
1254                 if (spuravoid == 1) {
1255                         W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0);
1256                         W_REG(&cc->pllcontrol_data, 0x11500060);
1257                         W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1);
1258                         W_REG(&cc->pllcontrol_data, 0x080C0C06);
1259                         W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2);
1260                         W_REG(&cc->pllcontrol_data, 0x0F600000);
1261                         W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3);
1262                         W_REG(&cc->pllcontrol_data, 0x00000000);
1263                         W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4);
1264                         W_REG(&cc->pllcontrol_data, 0x2001E924);
1265                         W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5);
1266                         W_REG(&cc->pllcontrol_data, 0x88888815);
1267                 } else {
1268                         W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0);
1269                         W_REG(&cc->pllcontrol_data, 0x11100060);
1270                         W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1);
1271                         W_REG(&cc->pllcontrol_data, 0x080c0c06);
1272                         W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2);
1273                         W_REG(&cc->pllcontrol_data, 0x03000000);
1274                         W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3);
1275                         W_REG(&cc->pllcontrol_data, 0x00000000);
1276                         W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4);
1277                         W_REG(&cc->pllcontrol_data, 0x200005c0);
1278                         W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5);
1279                         W_REG(&cc->pllcontrol_data, 0x88888815);
1280                 }
1281
1282                 tmp = 3 << 9;
1283                 break;
1284
1285         case BCM4319_CHIP_ID:
1286                 W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0);
1287                 W_REG(&cc->pllcontrol_data, 0x11100070);
1288                 W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1);
1289                 W_REG(&cc->pllcontrol_data, 0x1014140a);
1290                 W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5);
1291                 W_REG(&cc->pllcontrol_data, 0x88888854);
1292
1293                 if (spuravoid == 1) {
1294                         /* spur_avoid ON, so enable 41/82/164Mhz clock mode */
1295                         W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2);
1296                         W_REG(&cc->pllcontrol_data, 0x05201828);
1297                 } else {
1298                         /* enable 40/80/160Mhz clock mode */
1299                         W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2);
1300                         W_REG(&cc->pllcontrol_data, 0x05001828);
1301                 }
1302                 break;
1303         case BCM4336_CHIP_ID:
1304                 /* Looks like these are only for default xtal freq 26MHz */
1305                 W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0);
1306                 W_REG(&cc->pllcontrol_data, 0x02100020);
1307
1308                 W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1);
1309                 W_REG(&cc->pllcontrol_data, 0x0C0C0C0C);
1310
1311                 W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2);
1312                 W_REG(&cc->pllcontrol_data, 0x01240C0C);
1313
1314                 W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4);
1315                 W_REG(&cc->pllcontrol_data, 0x202C2820);
1316
1317                 W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5);
1318                 W_REG(&cc->pllcontrol_data, 0x88888825);
1319
1320                 W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3);
1321                 if (spuravoid == 1)
1322                         W_REG(&cc->pllcontrol_data, 0x00EC4EC4);
1323                 else
1324                         W_REG(&cc->pllcontrol_data, 0x00762762);
1325
1326                 tmp = PCTL_PLL_PLLCTL_UPD;
1327                 break;
1328
1329         default:
1330                 /* bail out */
1331                 return;
1332         }
1333
1334         tmp |= R_REG(&cc->pmucontrol);
1335         W_REG(&cc->pmucontrol, tmp);
1336 }
1337
1338 /* select default xtal frequency for each chip */
1339 static const pmu1_xtaltab0_t *si_pmu1_xtaldef0(si_t *sih)
1340 {
1341         switch (sih->chip) {
1342         case BCM4329_CHIP_ID:
1343                 /* Default to 38400Khz */
1344                 return &pmu1_xtaltab0_880_4329[PMU1_XTALTAB0_880_38400K];
1345         case BCM4319_CHIP_ID:
1346                 /* Default to 30000Khz */
1347                 return &pmu1_xtaltab0_1440[PMU1_XTALTAB0_1440_30000K];
1348         case BCM4336_CHIP_ID:
1349                 /* Default to 26000Khz */
1350                 return &pmu1_xtaltab0_960[PMU1_XTALTAB0_960_26000K];
1351         case BCM4330_CHIP_ID:
1352                 /* Default to 37400Khz */
1353                 if (CST4330_CHIPMODE_SDIOD(sih->chipst))
1354                         return &pmu1_xtaltab0_960[PMU1_XTALTAB0_960_37400K];
1355                 else
1356                         return &pmu1_xtaltab0_1440[PMU1_XTALTAB0_1440_37400K];
1357         default:
1358                 break;
1359         }
1360         return NULL;
1361 }
1362
1363 /* select xtal table for each chip */
1364 static const pmu1_xtaltab0_t *si_pmu1_xtaltab0(si_t *sih)
1365 {
1366         switch (sih->chip) {
1367         case BCM4329_CHIP_ID:
1368                 return pmu1_xtaltab0_880_4329;
1369         case BCM4319_CHIP_ID:
1370                 return pmu1_xtaltab0_1440;
1371         case BCM4336_CHIP_ID:
1372                 return pmu1_xtaltab0_960;
1373         case BCM4330_CHIP_ID:
1374                 if (CST4330_CHIPMODE_SDIOD(sih->chipst))
1375                         return pmu1_xtaltab0_960;
1376                 else
1377                         return pmu1_xtaltab0_1440;
1378         default:
1379                 break;
1380         }
1381         return NULL;
1382 }
1383
1384 /* query alp/xtal clock frequency */
1385 static u32
1386 si_pmu1_alpclk0(si_t *sih, chipcregs_t *cc)
1387 {
1388         const pmu1_xtaltab0_t *xt;
1389         u32 xf;
1390
1391         /* Find the frequency in the table */
1392         xf = (R_REG(&cc->pmucontrol) & PCTL_XTALFREQ_MASK) >>
1393             PCTL_XTALFREQ_SHIFT;
1394         for (xt = si_pmu1_xtaltab0(sih); xt != NULL && xt->fref != 0; xt++)
1395                 if (xt->xf == xf)
1396                         break;
1397         /* Could not find it so assign a default value */
1398         if (xt == NULL || xt->fref == 0)
1399                 xt = si_pmu1_xtaldef0(sih);
1400         return xt->fref * 1000;
1401 }
1402
1403 /* select default pll fvco for each chip */
1404 static u32 si_pmu1_pllfvco0(si_t *sih)
1405 {
1406         switch (sih->chip) {
1407         case BCM4329_CHIP_ID:
1408                 return FVCO_880;
1409         case BCM4319_CHIP_ID:
1410                 return FVCO_1440;
1411         case BCM4336_CHIP_ID:
1412                 return FVCO_960;
1413         case BCM4330_CHIP_ID:
1414                 if (CST4330_CHIPMODE_SDIOD(sih->chipst))
1415                         return FVCO_960;
1416                 else
1417                         return FVCO_1440;
1418         default:
1419                 break;
1420         }
1421         return 0;
1422 }
1423
1424 static void si_pmu_set_4330_plldivs(si_t *sih)
1425 {
1426         u32 FVCO = si_pmu1_pllfvco0(sih) / 1000;
1427         u32 m1div, m2div, m3div, m4div, m5div, m6div;
1428         u32 pllc1, pllc2;
1429
1430         m2div = m3div = m4div = m6div = FVCO / 80;
1431         m5div = FVCO / 160;
1432
1433         if (CST4330_CHIPMODE_SDIOD(sih->chipst))
1434                 m1div = FVCO / 80;
1435         else
1436                 m1div = FVCO / 90;
1437         pllc1 =
1438             (m1div << PMU1_PLL0_PC1_M1DIV_SHIFT) | (m2div <<
1439                                                     PMU1_PLL0_PC1_M2DIV_SHIFT) |
1440             (m3div << PMU1_PLL0_PC1_M3DIV_SHIFT) | (m4div <<
1441                                                     PMU1_PLL0_PC1_M4DIV_SHIFT);
1442         si_pmu_pllcontrol(sih, PMU1_PLL0_PLLCTL1, ~0, pllc1);
1443
1444         pllc2 = si_pmu_pllcontrol(sih, PMU1_PLL0_PLLCTL1, 0, 0);
1445         pllc2 &= ~(PMU1_PLL0_PC2_M5DIV_MASK | PMU1_PLL0_PC2_M6DIV_MASK);
1446         pllc2 |=
1447             ((m5div << PMU1_PLL0_PC2_M5DIV_SHIFT) |
1448              (m6div << PMU1_PLL0_PC2_M6DIV_SHIFT));
1449         si_pmu_pllcontrol(sih, PMU1_PLL0_PLLCTL2, ~0, pllc2);
1450 }
1451
1452 /* Set up PLL registers in the PMU as per the crystal speed.
1453  * XtalFreq field in pmucontrol register being 0 indicates the PLL
1454  * is not programmed and the h/w default is assumed to work, in which
1455  * case the xtal frequency is unknown to the s/w so we need to call
1456  * si_pmu1_xtaldef0() wherever it is needed to return a default value.
1457  */
1458 static void si_pmu1_pllinit0(si_t *sih, chipcregs_t *cc, u32 xtal)
1459 {
1460         const pmu1_xtaltab0_t *xt;
1461         u32 tmp;
1462         u32 buf_strength = 0;
1463         u8 ndiv_mode = 1;
1464
1465         /* Use h/w default PLL config */
1466         if (xtal == 0) {
1467                 return;
1468         }
1469
1470         /* Find the frequency in the table */
1471         for (xt = si_pmu1_xtaltab0(sih); xt != NULL && xt->fref != 0; xt++)
1472                 if (xt->fref == xtal)
1473                         break;
1474
1475         /* Check current PLL state, bail out if it has been programmed or
1476          * we don't know how to program it.
1477          */
1478         if (xt == NULL || xt->fref == 0) {
1479                 return;
1480         }
1481         /* for 4319 bootloader already programs the PLL but bootloader does not
1482          * program the PLL4 and PLL5. So Skip this check for 4319
1483          */
1484         if ((((R_REG(&cc->pmucontrol) & PCTL_XTALFREQ_MASK) >>
1485               PCTL_XTALFREQ_SHIFT) == xt->xf) &&
1486             !((sih->chip == BCM4319_CHIP_ID)
1487               || (sih->chip == BCM4330_CHIP_ID)))
1488                 return;
1489
1490         switch (sih->chip) {
1491         case BCM4329_CHIP_ID:
1492                 /* Change the BBPLL drive strength to 8 for all channels */
1493                 buf_strength = 0x888888;
1494                 AND_REG(&cc->min_res_mask,
1495                         ~(PMURES_BIT(RES4329_BBPLL_PWRSW_PU) |
1496                           PMURES_BIT(RES4329_HT_AVAIL)));
1497                 AND_REG(&cc->max_res_mask,
1498                         ~(PMURES_BIT(RES4329_BBPLL_PWRSW_PU) |
1499                           PMURES_BIT(RES4329_HT_AVAIL)));
1500                 SPINWAIT(R_REG(&cc->clk_ctl_st) & CCS_HTAVAIL,
1501                          PMU_MAX_TRANSITION_DLY);
1502                 W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4);
1503                 if (xt->fref == 38400)
1504                         tmp = 0x200024C0;
1505                 else if (xt->fref == 37400)
1506                         tmp = 0x20004500;
1507                 else if (xt->fref == 26000)
1508                         tmp = 0x200024C0;
1509                 else
1510                         tmp = 0x200005C0;       /* Chip Dflt Settings */
1511                 W_REG(&cc->pllcontrol_data, tmp);
1512                 W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5);
1513                 tmp =
1514                     R_REG(&cc->pllcontrol_data) & PMU1_PLL0_PC5_CLK_DRV_MASK;
1515                 if ((xt->fref == 38400) || (xt->fref == 37400)
1516                     || (xt->fref == 26000))
1517                         tmp |= 0x15;
1518                 else
1519                         tmp |= 0x25;    /* Chip Dflt Settings */
1520                 W_REG(&cc->pllcontrol_data, tmp);
1521                 break;
1522
1523         case BCM4319_CHIP_ID:
1524                 /* Change the BBPLL drive strength to 2 for all channels */
1525                 buf_strength = 0x222222;
1526
1527                 /* Make sure the PLL is off */
1528                 /* WAR65104: Disable the HT_AVAIL resource first and then
1529                  * after a delay (more than downtime for HT_AVAIL) remove the
1530                  * BBPLL resource; backplane clock moves to ALP from HT.
1531                  */
1532                 AND_REG(&cc->min_res_mask,
1533                         ~(PMURES_BIT(RES4319_HT_AVAIL)));
1534                 AND_REG(&cc->max_res_mask,
1535                         ~(PMURES_BIT(RES4319_HT_AVAIL)));
1536
1537                 udelay(100);
1538                 AND_REG(&cc->min_res_mask,
1539                         ~(PMURES_BIT(RES4319_BBPLL_PWRSW_PU)));
1540                 AND_REG(&cc->max_res_mask,
1541                         ~(PMURES_BIT(RES4319_BBPLL_PWRSW_PU)));
1542
1543                 udelay(100);
1544                 SPINWAIT(R_REG(&cc->clk_ctl_st) & CCS_HTAVAIL,
1545                          PMU_MAX_TRANSITION_DLY);
1546                 W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4);
1547                 tmp = 0x200005c0;
1548                 W_REG(&cc->pllcontrol_data, tmp);
1549                 break;
1550
1551         case BCM4336_CHIP_ID:
1552                 AND_REG(&cc->min_res_mask,
1553                         ~(PMURES_BIT(RES4336_HT_AVAIL) |
1554                           PMURES_BIT(RES4336_MACPHY_CLKAVAIL)));
1555                 AND_REG(&cc->max_res_mask,
1556                         ~(PMURES_BIT(RES4336_HT_AVAIL) |
1557                           PMURES_BIT(RES4336_MACPHY_CLKAVAIL)));
1558                 udelay(100);
1559                 SPINWAIT(R_REG(&cc->clk_ctl_st) & CCS_HTAVAIL,
1560                          PMU_MAX_TRANSITION_DLY);
1561                 break;
1562
1563         case BCM4330_CHIP_ID:
1564                 AND_REG(&cc->min_res_mask,
1565                         ~(PMURES_BIT(RES4330_HT_AVAIL) |
1566                           PMURES_BIT(RES4330_MACPHY_CLKAVAIL)));
1567                 AND_REG(&cc->max_res_mask,
1568                         ~(PMURES_BIT(RES4330_HT_AVAIL) |
1569                           PMURES_BIT(RES4330_MACPHY_CLKAVAIL)));
1570                 udelay(100);
1571                 SPINWAIT(R_REG(&cc->clk_ctl_st) & CCS_HTAVAIL,
1572                          PMU_MAX_TRANSITION_DLY);
1573                 break;
1574
1575         default:
1576                 break;
1577         }
1578
1579         /* Write p1div and p2div to pllcontrol[0] */
1580         W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0);
1581         tmp = R_REG(&cc->pllcontrol_data) &
1582             ~(PMU1_PLL0_PC0_P1DIV_MASK | PMU1_PLL0_PC0_P2DIV_MASK);
1583         tmp |=
1584             ((xt->
1585               p1div << PMU1_PLL0_PC0_P1DIV_SHIFT) & PMU1_PLL0_PC0_P1DIV_MASK) |
1586             ((xt->
1587               p2div << PMU1_PLL0_PC0_P2DIV_SHIFT) & PMU1_PLL0_PC0_P2DIV_MASK);
1588         W_REG(&cc->pllcontrol_data, tmp);
1589
1590         if ((sih->chip == BCM4330_CHIP_ID))
1591                 si_pmu_set_4330_plldivs(sih);
1592
1593         if ((sih->chip == BCM4329_CHIP_ID)
1594             && (sih->chiprev == 0)) {
1595
1596                 W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1);
1597                 tmp = R_REG(&cc->pllcontrol_data);
1598                 tmp = tmp & (~DOT11MAC_880MHZ_CLK_DIVISOR_MASK);
1599                 tmp = tmp | DOT11MAC_880MHZ_CLK_DIVISOR_VAL;
1600                 W_REG(&cc->pllcontrol_data, tmp);
1601         }
1602         if ((sih->chip == BCM4319_CHIP_ID) ||
1603             (sih->chip == BCM4336_CHIP_ID) ||
1604             (sih->chip == BCM4330_CHIP_ID))
1605                 ndiv_mode = PMU1_PLL0_PC2_NDIV_MODE_MFB;
1606         else
1607                 ndiv_mode = PMU1_PLL0_PC2_NDIV_MODE_MASH;
1608
1609         /* Write ndiv_int and ndiv_mode to pllcontrol[2] */
1610         W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2);
1611         tmp = R_REG(&cc->pllcontrol_data) &
1612             ~(PMU1_PLL0_PC2_NDIV_INT_MASK | PMU1_PLL0_PC2_NDIV_MODE_MASK);
1613         tmp |=
1614             ((xt->
1615               ndiv_int << PMU1_PLL0_PC2_NDIV_INT_SHIFT) &
1616              PMU1_PLL0_PC2_NDIV_INT_MASK) | ((ndiv_mode <<
1617                                               PMU1_PLL0_PC2_NDIV_MODE_SHIFT) &
1618                                              PMU1_PLL0_PC2_NDIV_MODE_MASK);
1619         W_REG(&cc->pllcontrol_data, tmp);
1620
1621         /* Write ndiv_frac to pllcontrol[3] */
1622         W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3);
1623         tmp = R_REG(&cc->pllcontrol_data) & ~PMU1_PLL0_PC3_NDIV_FRAC_MASK;
1624         tmp |= ((xt->ndiv_frac << PMU1_PLL0_PC3_NDIV_FRAC_SHIFT) &
1625                 PMU1_PLL0_PC3_NDIV_FRAC_MASK);
1626         W_REG(&cc->pllcontrol_data, tmp);
1627
1628         /* Write clock driving strength to pllcontrol[5] */
1629         if (buf_strength) {
1630                 W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5);
1631                 tmp =
1632                     R_REG(&cc->pllcontrol_data) & ~PMU1_PLL0_PC5_CLK_DRV_MASK;
1633                 tmp |= (buf_strength << PMU1_PLL0_PC5_CLK_DRV_SHIFT);
1634                 W_REG(&cc->pllcontrol_data, tmp);
1635         }
1636
1637         /* to operate the 4319 usb in 24MHz/48MHz; chipcontrol[2][84:83] needs
1638          * to be updated.
1639          */
1640         if ((sih->chip == BCM4319_CHIP_ID)
1641             && (xt->fref != XTAL_FREQ_30000MHZ)) {
1642                 W_REG(&cc->chipcontrol_addr, PMU1_PLL0_CHIPCTL2);
1643                 tmp =
1644                     R_REG(&cc->chipcontrol_data) & ~CCTL_4319USB_XTAL_SEL_MASK;
1645                 if (xt->fref == XTAL_FREQ_24000MHZ) {
1646                         tmp |=
1647                             (CCTL_4319USB_24MHZ_PLL_SEL <<
1648                              CCTL_4319USB_XTAL_SEL_SHIFT);
1649                 } else if (xt->fref == XTAL_FREQ_48000MHZ) {
1650                         tmp |=
1651                             (CCTL_4319USB_48MHZ_PLL_SEL <<
1652                              CCTL_4319USB_XTAL_SEL_SHIFT);
1653                 }
1654                 W_REG(&cc->chipcontrol_data, tmp);
1655         }
1656
1657         /* Flush deferred pll control registers writes */
1658         if (sih->pmurev >= 2)
1659                 OR_REG(&cc->pmucontrol, PCTL_PLL_PLLCTL_UPD);
1660
1661         /* Write XtalFreq. Set the divisor also. */
1662         tmp = R_REG(&cc->pmucontrol) &
1663             ~(PCTL_ILP_DIV_MASK | PCTL_XTALFREQ_MASK);
1664         tmp |= (((((xt->fref + 127) / 128) - 1) << PCTL_ILP_DIV_SHIFT) &
1665                 PCTL_ILP_DIV_MASK) |
1666             ((xt->xf << PCTL_XTALFREQ_SHIFT) & PCTL_XTALFREQ_MASK);
1667
1668         if ((sih->chip == BCM4329_CHIP_ID)
1669             && sih->chiprev == 0) {
1670                 /* clear the htstretch before clearing HTReqEn */
1671                 AND_REG(&cc->clkstretch, ~CSTRETCH_HT);
1672                 tmp &= ~PCTL_HT_REQ_EN;
1673         }
1674
1675         W_REG(&cc->pmucontrol, tmp);
1676 }
1677
1678 u32 si_pmu_ilp_clock(si_t *sih)
1679 {
1680         static u32 ilpcycles_per_sec;
1681
1682         if (ISSIM_ENAB(sih) || !PMUCTL_ENAB(sih))
1683                 return ILP_CLOCK;
1684
1685         if (ilpcycles_per_sec == 0) {
1686                 u32 start, end, delta;
1687                 u32 origidx = ai_coreidx(sih);
1688                 chipcregs_t *cc = ai_setcoreidx(sih, SI_CC_IDX);
1689                 start = R_REG(&cc->pmutimer);
1690                 mdelay(ILP_CALC_DUR);
1691                 end = R_REG(&cc->pmutimer);
1692                 delta = end - start;
1693                 ilpcycles_per_sec = delta * (1000 / ILP_CALC_DUR);
1694                 ai_setcoreidx(sih, origidx);
1695         }
1696
1697         return ilpcycles_per_sec;
1698 }
1699
1700 void si_pmu_set_ldo_voltage(si_t *sih, u8 ldo, u8 voltage)
1701 {
1702         u8 sr_cntl_shift = 0, rc_shift = 0, shift = 0, mask = 0;
1703         u8 addr = 0;
1704
1705         switch (sih->chip) {
1706         case BCM4336_CHIP_ID:
1707                 switch (ldo) {
1708                 case SET_LDO_VOLTAGE_CLDO_PWM:
1709                         addr = 4;
1710                         rc_shift = 1;
1711                         mask = 0xf;
1712                         break;
1713                 case SET_LDO_VOLTAGE_CLDO_BURST:
1714                         addr = 4;
1715                         rc_shift = 5;
1716                         mask = 0xf;
1717                         break;
1718                 case SET_LDO_VOLTAGE_LNLDO1:
1719                         addr = 4;
1720                         rc_shift = 17;
1721                         mask = 0xf;
1722                         break;
1723                 default:
1724                         return;
1725                 }
1726                 break;
1727         case BCM4330_CHIP_ID:
1728                 switch (ldo) {
1729                 case SET_LDO_VOLTAGE_CBUCK_PWM:
1730                         addr = 3;
1731                         rc_shift = 0;
1732                         mask = 0x1f;
1733                         break;
1734                 default:
1735                         return;
1736                 }
1737                 break;
1738         default:
1739                 return;
1740         }
1741
1742         shift = sr_cntl_shift + rc_shift;
1743
1744         ai_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, regcontrol_addr),
1745                    ~0, addr);
1746         ai_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, regcontrol_data),
1747                    mask << shift, (voltage & mask) << shift);
1748 }
1749
1750 u16 si_pmu_fast_pwrup_delay(si_t *sih)
1751 {
1752         uint delay = PMU_MAX_TRANSITION_DLY;
1753         chipcregs_t *cc;
1754         uint origidx;
1755 #ifdef BCMDBG
1756         char chn[8];
1757         chn[0] = 0;             /* to suppress compile error */
1758 #endif
1759
1760         /* Remember original core before switch to chipc */
1761         origidx = ai_coreidx(sih);
1762         cc = ai_setcoreidx(sih, SI_CC_IDX);
1763
1764         switch (sih->chip) {
1765         case BCM43224_CHIP_ID:
1766         case BCM43225_CHIP_ID:
1767         case BCM43421_CHIP_ID:
1768         case BCM43235_CHIP_ID:
1769         case BCM43236_CHIP_ID:
1770         case BCM43238_CHIP_ID:
1771         case BCM4331_CHIP_ID:
1772         case BCM6362_CHIP_ID:
1773         case BCM4313_CHIP_ID:
1774                 delay = ISSIM_ENAB(sih) ? 70 : 3700;
1775                 break;
1776         case BCM4329_CHIP_ID:
1777                 if (ISSIM_ENAB(sih))
1778                         delay = 70;
1779                 else {
1780                         u32 ilp = si_pmu_ilp_clock(sih);
1781                         delay =
1782                             (si_pmu_res_uptime(sih, cc, RES4329_HT_AVAIL) +
1783                              D11SCC_SLOW2FAST_TRANSITION) * ((1000000 + ilp -
1784                                                               1) / ilp);
1785                         delay = (11 * delay) / 10;
1786                 }
1787                 break;
1788         case BCM4319_CHIP_ID:
1789                 delay = ISSIM_ENAB(sih) ? 70 : 3700;
1790                 break;
1791         case BCM4336_CHIP_ID:
1792                 if (ISSIM_ENAB(sih))
1793                         delay = 70;
1794                 else {
1795                         u32 ilp = si_pmu_ilp_clock(sih);
1796                         delay =
1797                             (si_pmu_res_uptime(sih, cc, RES4336_HT_AVAIL) +
1798                              D11SCC_SLOW2FAST_TRANSITION) * ((1000000 + ilp -
1799                                                               1) / ilp);
1800                         delay = (11 * delay) / 10;
1801                 }
1802                 break;
1803         case BCM4330_CHIP_ID:
1804                 if (ISSIM_ENAB(sih))
1805                         delay = 70;
1806                 else {
1807                         u32 ilp = si_pmu_ilp_clock(sih);
1808                         delay =
1809                             (si_pmu_res_uptime(sih, cc, RES4330_HT_AVAIL) +
1810                              D11SCC_SLOW2FAST_TRANSITION) * ((1000000 + ilp -
1811                                                               1) / ilp);
1812                         delay = (11 * delay) / 10;
1813                 }
1814                 break;
1815         default:
1816                 break;
1817         }
1818         /* Return to original core */
1819         ai_setcoreidx(sih, origidx);
1820
1821         return (u16) delay;
1822 }
1823
1824 void si_pmu_sprom_enable(si_t *sih, bool enable)
1825 {
1826         chipcregs_t *cc;
1827         uint origidx;
1828
1829         /* Remember original core before switch to chipc */
1830         origidx = ai_coreidx(sih);
1831         cc = ai_setcoreidx(sih, SI_CC_IDX);
1832
1833         /* Return to original core */
1834         ai_setcoreidx(sih, origidx);
1835 }
1836
1837 /* Read/write a chipcontrol reg */
1838 u32 si_pmu_chipcontrol(si_t *sih, uint reg, u32 mask, u32 val)
1839 {
1840         ai_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, chipcontrol_addr), ~0,
1841                    reg);
1842         return ai_corereg(sih, SI_CC_IDX,
1843                           offsetof(chipcregs_t, chipcontrol_data), mask, val);
1844 }
1845
1846 /* Read/write a regcontrol reg */
1847 u32 si_pmu_regcontrol(si_t *sih, uint reg, u32 mask, u32 val)
1848 {
1849         ai_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, regcontrol_addr), ~0,
1850                    reg);
1851         return ai_corereg(sih, SI_CC_IDX,
1852                           offsetof(chipcregs_t, regcontrol_data), mask, val);
1853 }
1854
1855 /* Read/write a pllcontrol reg */
1856 u32 si_pmu_pllcontrol(si_t *sih, uint reg, u32 mask, u32 val)
1857 {
1858         ai_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, pllcontrol_addr), ~0,
1859                    reg);
1860         return ai_corereg(sih, SI_CC_IDX,
1861                           offsetof(chipcregs_t, pllcontrol_data), mask, val);
1862 }
1863
1864 /* PMU PLL update */
1865 void si_pmu_pllupd(si_t *sih)
1866 {
1867         ai_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, pmucontrol),
1868                    PCTL_PLL_PLLCTL_UPD, PCTL_PLL_PLLCTL_UPD);
1869 }
1870
1871 /* query alp/xtal clock frequency */
1872 u32 si_pmu_alp_clock(si_t *sih)
1873 {
1874         chipcregs_t *cc;
1875         uint origidx;
1876         u32 clock = ALP_CLOCK;
1877
1878         /* bail out with default */
1879         if (!PMUCTL_ENAB(sih))
1880                 return clock;
1881
1882         /* Remember original core before switch to chipc */
1883         origidx = ai_coreidx(sih);
1884         cc = ai_setcoreidx(sih, SI_CC_IDX);
1885
1886         switch (sih->chip) {
1887         case BCM43224_CHIP_ID:
1888         case BCM43225_CHIP_ID:
1889         case BCM43421_CHIP_ID:
1890         case BCM43235_CHIP_ID:
1891         case BCM43236_CHIP_ID:
1892         case BCM43238_CHIP_ID:
1893         case BCM4331_CHIP_ID:
1894         case BCM6362_CHIP_ID:
1895         case BCM4716_CHIP_ID:
1896         case BCM4748_CHIP_ID:
1897         case BCM47162_CHIP_ID:
1898         case BCM4313_CHIP_ID:
1899         case BCM5357_CHIP_ID:
1900                 /* always 20Mhz */
1901                 clock = 20000 * 1000;
1902                 break;
1903         case BCM4329_CHIP_ID:
1904         case BCM4319_CHIP_ID:
1905         case BCM4336_CHIP_ID:
1906         case BCM4330_CHIP_ID:
1907
1908                 clock = si_pmu1_alpclk0(sih, cc);
1909                 break;
1910         case BCM5356_CHIP_ID:
1911                 /* always 25Mhz */
1912                 clock = 25000 * 1000;
1913                 break;
1914         default:
1915                 break;
1916         }
1917
1918         /* Return to original core */
1919         ai_setcoreidx(sih, origidx);
1920         return clock;
1921 }
1922
1923 void si_pmu_spuravoid(si_t *sih, u8 spuravoid)
1924 {
1925         chipcregs_t *cc;
1926         uint origidx, intr_val;
1927         u32 tmp = 0;
1928
1929         /* Remember original core before switch to chipc */
1930         cc = (chipcregs_t *) ai_switch_core(sih, CC_CORE_ID, &origidx,
1931                                             &intr_val);
1932
1933         /* force the HT off  */
1934         if (sih->chip == BCM4336_CHIP_ID) {
1935                 tmp = R_REG(&cc->max_res_mask);
1936                 tmp &= ~RES4336_HT_AVAIL;
1937                 W_REG(&cc->max_res_mask, tmp);
1938                 /* wait for the ht to really go away */
1939                 SPINWAIT(((R_REG(&cc->clk_ctl_st) & CCS_HTAVAIL) == 0),
1940                          10000);
1941         }
1942
1943         /* update the pll changes */
1944         si_pmu_spuravoid_pllupdate(sih, cc, spuravoid);
1945
1946         /* enable HT back on  */
1947         if (sih->chip == BCM4336_CHIP_ID) {
1948                 tmp = R_REG(&cc->max_res_mask);
1949                 tmp |= RES4336_HT_AVAIL;
1950                 W_REG(&cc->max_res_mask, tmp);
1951         }
1952
1953         /* Return to original core */
1954         ai_restore_core(sih, origidx, intr_val);
1955 }
1956
1957 /* initialize PMU */
1958 void si_pmu_init(si_t *sih)
1959 {
1960         chipcregs_t *cc;
1961         uint origidx;
1962
1963         /* Remember original core before switch to chipc */
1964         origidx = ai_coreidx(sih);
1965         cc = ai_setcoreidx(sih, SI_CC_IDX);
1966
1967         if (sih->pmurev == 1)
1968                 AND_REG(&cc->pmucontrol, ~PCTL_NOILP_ON_WAIT);
1969         else if (sih->pmurev >= 2)
1970                 OR_REG(&cc->pmucontrol, PCTL_NOILP_ON_WAIT);
1971
1972         if ((sih->chip == BCM4329_CHIP_ID) && (sih->chiprev == 2)) {
1973                 /* Fix for 4329b0 bad LPOM state. */
1974                 W_REG(&cc->regcontrol_addr, 2);
1975                 OR_REG(&cc->regcontrol_data, 0x100);
1976
1977                 W_REG(&cc->regcontrol_addr, 3);
1978                 OR_REG(&cc->regcontrol_data, 0x4);
1979         }
1980
1981         /* Return to original core */
1982         ai_setcoreidx(sih, origidx);
1983 }
1984
1985 /* initialize PMU chip controls and other chip level stuff */
1986 void si_pmu_chip_init(si_t *sih)
1987 {
1988         uint origidx;
1989
1990         /* Gate off SPROM clock and chip select signals */
1991         si_pmu_sprom_enable(sih, false);
1992
1993         /* Remember original core */
1994         origidx = ai_coreidx(sih);
1995
1996         /* Return to original core */
1997         ai_setcoreidx(sih, origidx);
1998 }
1999
2000 /* initialize PMU switch/regulators */
2001 void si_pmu_swreg_init(si_t *sih)
2002 {
2003         switch (sih->chip) {
2004         case BCM4336_CHIP_ID:
2005                 /* Reduce CLDO PWM output voltage to 1.2V */
2006                 si_pmu_set_ldo_voltage(sih, SET_LDO_VOLTAGE_CLDO_PWM, 0xe);
2007                 /* Reduce CLDO BURST output voltage to 1.2V */
2008                 si_pmu_set_ldo_voltage(sih, SET_LDO_VOLTAGE_CLDO_BURST,
2009                                        0xe);
2010                 /* Reduce LNLDO1 output voltage to 1.2V */
2011                 si_pmu_set_ldo_voltage(sih, SET_LDO_VOLTAGE_LNLDO1, 0xe);
2012                 if (sih->chiprev == 0)
2013                         si_pmu_regcontrol(sih, 2, 0x400000, 0x400000);
2014                 break;
2015
2016         case BCM4330_CHIP_ID:
2017                 /* CBUCK Voltage is 1.8 by default and set that to 1.5 */
2018                 si_pmu_set_ldo_voltage(sih, SET_LDO_VOLTAGE_CBUCK_PWM, 0);
2019                 break;
2020         default:
2021                 break;
2022         }
2023 }
2024
2025 /* initialize PLL */
2026 void si_pmu_pll_init(si_t *sih, uint xtalfreq)
2027 {
2028         chipcregs_t *cc;
2029         uint origidx;
2030
2031         /* Remember original core before switch to chipc */
2032         origidx = ai_coreidx(sih);
2033         cc = ai_setcoreidx(sih, SI_CC_IDX);
2034
2035         switch (sih->chip) {
2036         case BCM4329_CHIP_ID:
2037                 if (xtalfreq == 0)
2038                         xtalfreq = 38400;
2039                 si_pmu1_pllinit0(sih, cc, xtalfreq);
2040                 break;
2041         case BCM4313_CHIP_ID:
2042         case BCM43224_CHIP_ID:
2043         case BCM43225_CHIP_ID:
2044         case BCM43421_CHIP_ID:
2045         case BCM43235_CHIP_ID:
2046         case BCM43236_CHIP_ID:
2047         case BCM43238_CHIP_ID:
2048         case BCM4331_CHIP_ID:
2049         case BCM6362_CHIP_ID:
2050                 /* ??? */
2051                 break;
2052         case BCM4319_CHIP_ID:
2053         case BCM4336_CHIP_ID:
2054         case BCM4330_CHIP_ID:
2055                 si_pmu1_pllinit0(sih, cc, xtalfreq);
2056                 break;
2057         default:
2058                 break;
2059         }
2060
2061         /* Return to original core */
2062         ai_setcoreidx(sih, origidx);
2063 }
2064
2065 /* initialize PMU resources */
2066 void si_pmu_res_init(si_t *sih)
2067 {
2068         chipcregs_t *cc;
2069         uint origidx;
2070         const pmu_res_updown_t *pmu_res_updown_table = NULL;
2071         uint pmu_res_updown_table_sz = 0;
2072         const pmu_res_depend_t *pmu_res_depend_table = NULL;
2073         uint pmu_res_depend_table_sz = 0;
2074         u32 min_mask = 0, max_mask = 0;
2075         char name[8], *val;
2076         uint i, rsrcs;
2077
2078         /* Remember original core before switch to chipc */
2079         origidx = ai_coreidx(sih);
2080         cc = ai_setcoreidx(sih, SI_CC_IDX);
2081
2082         switch (sih->chip) {
2083         case BCM4329_CHIP_ID:
2084                 /* Optimize resources up/down timers */
2085                 if (ISSIM_ENAB(sih)) {
2086                         pmu_res_updown_table = NULL;
2087                         pmu_res_updown_table_sz = 0;
2088                 } else {
2089                         pmu_res_updown_table = bcm4329_res_updown;
2090                         pmu_res_updown_table_sz =
2091                                 ARRAY_SIZE(bcm4329_res_updown);
2092                 }
2093                 /* Optimize resources dependencies */
2094                 pmu_res_depend_table = bcm4329_res_depend;
2095                 pmu_res_depend_table_sz = ARRAY_SIZE(bcm4329_res_depend);
2096                 break;
2097
2098         case BCM4319_CHIP_ID:
2099                 /* Optimize resources up/down timers */
2100                 if (ISSIM_ENAB(sih)) {
2101                         pmu_res_updown_table = bcm4319a0_res_updown_qt;
2102                         pmu_res_updown_table_sz =
2103                             ARRAY_SIZE(bcm4319a0_res_updown_qt);
2104                 } else {
2105                         pmu_res_updown_table = bcm4319a0_res_updown;
2106                         pmu_res_updown_table_sz =
2107                             ARRAY_SIZE(bcm4319a0_res_updown);
2108                 }
2109                 /* Optimize resources dependancies masks */
2110                 pmu_res_depend_table = bcm4319a0_res_depend;
2111                 pmu_res_depend_table_sz = ARRAY_SIZE(bcm4319a0_res_depend);
2112                 break;
2113
2114         case BCM4336_CHIP_ID:
2115                 /* Optimize resources up/down timers */
2116                 if (ISSIM_ENAB(sih)) {
2117                         pmu_res_updown_table = bcm4336a0_res_updown_qt;
2118                         pmu_res_updown_table_sz =
2119                             ARRAY_SIZE(bcm4336a0_res_updown_qt);
2120                 } else {
2121                         pmu_res_updown_table = bcm4336a0_res_updown;
2122                         pmu_res_updown_table_sz =
2123                             ARRAY_SIZE(bcm4336a0_res_updown);
2124                 }
2125                 /* Optimize resources dependancies masks */
2126                 pmu_res_depend_table = bcm4336a0_res_depend;
2127                 pmu_res_depend_table_sz = ARRAY_SIZE(bcm4336a0_res_depend);
2128                 break;
2129
2130         case BCM4330_CHIP_ID:
2131                 /* Optimize resources up/down timers */
2132                 if (ISSIM_ENAB(sih)) {
2133                         pmu_res_updown_table = bcm4330a0_res_updown_qt;
2134                         pmu_res_updown_table_sz =
2135                             ARRAY_SIZE(bcm4330a0_res_updown_qt);
2136                 } else {
2137                         pmu_res_updown_table = bcm4330a0_res_updown;
2138                         pmu_res_updown_table_sz =
2139                             ARRAY_SIZE(bcm4330a0_res_updown);
2140                 }
2141                 /* Optimize resources dependancies masks */
2142                 pmu_res_depend_table = bcm4330a0_res_depend;
2143                 pmu_res_depend_table_sz = ARRAY_SIZE(bcm4330a0_res_depend);
2144                 break;
2145
2146         default:
2147                 break;
2148         }
2149
2150         /* # resources */
2151         rsrcs = (sih->pmucaps & PCAP_RC_MASK) >> PCAP_RC_SHIFT;
2152
2153         /* Program up/down timers */
2154         while (pmu_res_updown_table_sz--) {
2155                 W_REG(&cc->res_table_sel,
2156                       pmu_res_updown_table[pmu_res_updown_table_sz].resnum);
2157                 W_REG(&cc->res_updn_timer,
2158                       pmu_res_updown_table[pmu_res_updown_table_sz].updown);
2159         }
2160         /* Apply nvram overrides to up/down timers */
2161         for (i = 0; i < rsrcs; i++) {
2162                 snprintf(name, sizeof(name), "r%dt", i);
2163                 val = getvar(NULL, name);
2164                 if (val == NULL)
2165                         continue;
2166                 W_REG(&cc->res_table_sel, (u32) i);
2167                 W_REG(&cc->res_updn_timer,
2168                       (u32) simple_strtoul(val, NULL, 0));
2169         }
2170
2171         /* Program resource dependencies table */
2172         while (pmu_res_depend_table_sz--) {
2173                 if (pmu_res_depend_table[pmu_res_depend_table_sz].filter != NULL
2174                     && !(pmu_res_depend_table[pmu_res_depend_table_sz].
2175                          filter) (sih))
2176                         continue;
2177                 for (i = 0; i < rsrcs; i++) {
2178                         if ((pmu_res_depend_table[pmu_res_depend_table_sz].
2179                              res_mask & PMURES_BIT(i)) == 0)
2180                                 continue;
2181                         W_REG(&cc->res_table_sel, i);
2182                         switch (pmu_res_depend_table[pmu_res_depend_table_sz].
2183                                 action) {
2184                         case RES_DEPEND_SET:
2185                                 W_REG(&cc->res_dep_mask,
2186                                       pmu_res_depend_table
2187                                       [pmu_res_depend_table_sz].depend_mask);
2188                                 break;
2189                         case RES_DEPEND_ADD:
2190                                 OR_REG(&cc->res_dep_mask,
2191                                        pmu_res_depend_table
2192                                        [pmu_res_depend_table_sz].depend_mask);
2193                                 break;
2194                         case RES_DEPEND_REMOVE:
2195                                 AND_REG(&cc->res_dep_mask,
2196                                         ~pmu_res_depend_table
2197                                         [pmu_res_depend_table_sz].depend_mask);
2198                                 break;
2199                         default:
2200                                 break;
2201                         }
2202                 }
2203         }
2204         /* Apply nvram overrides to dependancies masks */
2205         for (i = 0; i < rsrcs; i++) {
2206                 snprintf(name, sizeof(name), "r%dd", i);
2207                 val = getvar(NULL, name);
2208                 if (val == NULL)
2209                         continue;
2210                 W_REG(&cc->res_table_sel, (u32) i);
2211                 W_REG(&cc->res_dep_mask,
2212                       (u32) simple_strtoul(val, NULL, 0));
2213         }
2214
2215         /* Determine min/max rsrc masks */
2216         si_pmu_res_masks(sih, &min_mask, &max_mask);
2217
2218         /* It is required to program max_mask first and then min_mask */
2219
2220         /* Program max resource mask */
2221
2222         if (max_mask)
2223                 W_REG(&cc->max_res_mask, max_mask);
2224
2225         /* Program min resource mask */
2226
2227         if (min_mask)
2228                 W_REG(&cc->min_res_mask, min_mask);
2229
2230         /* Add some delay; allow resources to come up and settle. */
2231         mdelay(2);
2232
2233         /* Return to original core */
2234         ai_setcoreidx(sih, origidx);
2235 }
2236
2237 u32 si_pmu_measure_alpclk(si_t *sih)
2238 {
2239         chipcregs_t *cc;
2240         uint origidx;
2241         u32 alp_khz;
2242
2243         if (sih->pmurev < 10)
2244                 return 0;
2245
2246         /* Remember original core before switch to chipc */
2247         origidx = ai_coreidx(sih);
2248         cc = ai_setcoreidx(sih, SI_CC_IDX);
2249
2250         if (R_REG(&cc->pmustatus) & PST_EXTLPOAVAIL) {
2251                 u32 ilp_ctr, alp_hz;
2252
2253                 /*
2254                  * Enable the reg to measure the freq,
2255                  * in case it was disabled before
2256                  */
2257                 W_REG(&cc->pmu_xtalfreq,
2258                       1U << PMU_XTALFREQ_REG_MEASURE_SHIFT);
2259
2260                 /* Delay for well over 4 ILP clocks */
2261                 udelay(1000);
2262
2263                 /* Read the latched number of ALP ticks per 4 ILP ticks */
2264                 ilp_ctr =
2265                     R_REG(&cc->pmu_xtalfreq) & PMU_XTALFREQ_REG_ILPCTR_MASK;
2266
2267                 /*
2268                  * Turn off the PMU_XTALFREQ_REG_MEASURE_SHIFT
2269                  * bit to save power
2270                  */
2271                 W_REG(&cc->pmu_xtalfreq, 0);
2272
2273                 /* Calculate ALP frequency */
2274                 alp_hz = (ilp_ctr * EXT_ILP_HZ) / 4;
2275
2276                 /*
2277                  * Round to nearest 100KHz, and at
2278                  * the same time convert to KHz
2279                  */
2280                 alp_khz = (alp_hz + 50000) / 100000 * 100;
2281         } else
2282                 alp_khz = 0;
2283
2284         /* Return to original core */
2285         ai_setcoreidx(sih, origidx);
2286
2287         return alp_khz;
2288 }
2289
2290 bool si_pmu_is_otp_powered(si_t *sih)
2291 {
2292         uint idx;
2293         chipcregs_t *cc;
2294         bool st;
2295
2296         /* Remember original core before switch to chipc */
2297         idx = ai_coreidx(sih);
2298         cc = ai_setcoreidx(sih, SI_CC_IDX);
2299
2300         switch (sih->chip) {
2301         case BCM4329_CHIP_ID:
2302                 st = (R_REG(&cc->res_state) & PMURES_BIT(RES4329_OTP_PU))
2303                     != 0;
2304                 break;
2305         case BCM4319_CHIP_ID:
2306                 st = (R_REG(&cc->res_state) & PMURES_BIT(RES4319_OTP_PU))
2307                     != 0;
2308                 break;
2309         case BCM4336_CHIP_ID:
2310                 st = (R_REG(&cc->res_state) & PMURES_BIT(RES4336_OTP_PU))
2311                     != 0;
2312                 break;
2313         case BCM4330_CHIP_ID:
2314                 st = (R_REG(&cc->res_state) & PMURES_BIT(RES4330_OTP_PU))
2315                     != 0;
2316                 break;
2317
2318                 /* These chip doesn't use PMU bit to power up/down OTP. OTP always on.
2319                  * Use OTP_INIT command to reset/refresh state.
2320                  */
2321         case BCM43224_CHIP_ID:
2322         case BCM43225_CHIP_ID:
2323         case BCM43421_CHIP_ID:
2324         case BCM43236_CHIP_ID:
2325         case BCM43235_CHIP_ID:
2326         case BCM43238_CHIP_ID:
2327                 st = true;
2328                 break;
2329         default:
2330                 st = true;
2331                 break;
2332         }
2333
2334         /* Return to original core */
2335         ai_setcoreidx(sih, idx);
2336         return st;
2337 }
2338
2339 /* power up/down OTP through PMU resources */
2340 void si_pmu_otp_power(si_t *sih, bool on)
2341 {
2342         chipcregs_t *cc;
2343         uint origidx;
2344         u32 rsrcs = 0;  /* rsrcs to turn on/off OTP power */
2345
2346         /* Don't do anything if OTP is disabled */
2347         if (ai_is_otp_disabled(sih))
2348                 return;
2349
2350         /* Remember original core before switch to chipc */
2351         origidx = ai_coreidx(sih);
2352         cc = ai_setcoreidx(sih, SI_CC_IDX);
2353
2354         switch (sih->chip) {
2355         case BCM4329_CHIP_ID:
2356                 rsrcs = PMURES_BIT(RES4329_OTP_PU);
2357                 break;
2358         case BCM4319_CHIP_ID:
2359                 rsrcs = PMURES_BIT(RES4319_OTP_PU);
2360                 break;
2361         case BCM4336_CHIP_ID:
2362                 rsrcs = PMURES_BIT(RES4336_OTP_PU);
2363                 break;
2364         case BCM4330_CHIP_ID:
2365                 rsrcs = PMURES_BIT(RES4330_OTP_PU);
2366                 break;
2367         default:
2368                 break;
2369         }
2370
2371         if (rsrcs != 0) {
2372                 u32 otps;
2373
2374                 /* Figure out the dependancies (exclude min_res_mask) */
2375                 u32 deps = si_pmu_res_deps(sih, cc, rsrcs, true);
2376                 u32 min_mask = 0, max_mask = 0;
2377                 si_pmu_res_masks(sih, &min_mask, &max_mask);
2378                 deps &= ~min_mask;
2379                 /* Turn on/off the power */
2380                 if (on) {
2381                         OR_REG(&cc->min_res_mask, (rsrcs | deps));
2382                         SPINWAIT(!(R_REG(&cc->res_state) & rsrcs),
2383                                  PMU_MAX_TRANSITION_DLY);
2384                 } else {
2385                         AND_REG(&cc->min_res_mask, ~(rsrcs | deps));
2386                 }
2387
2388                 SPINWAIT((((otps = R_REG(&cc->otpstatus)) & OTPS_READY) !=
2389                           (on ? OTPS_READY : 0)), 100);
2390         }
2391
2392         /* Return to original core */
2393         ai_setcoreidx(sih, origidx);
2394 }