2 * Copyright (c) 2011 Broadcom Corporation
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.
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.
16 #include <linux/kernel.h>
17 #include <linux/types.h>
18 #include <linux/delay.h>
28 * d11 slow to fast clock transition time in slow clock cycles
30 #define D11SCC_SLOW2FAST_TRANSITION 2
33 * external LPO crystal frequency
35 #define EXT_ILP_HZ 32768
38 * Duration for ILP clock frequency measurment in milliseconds
40 * remark: 1000 must be an integer multiple of this duration
42 #define ILP_CALC_DUR 10
47 #define FVCO_880 880000 /* 880MHz */
48 #define FVCO_1760 1760000 /* 1760MHz */
49 #define FVCO_1440 1440000 /* 1440MHz */
50 #define FVCO_960 960000 /* 960MHz */
53 * PMU crystal table indices for 1440MHz fvco
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
73 * PMU crystal table indices for 960MHz fvco
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
93 * PMU crystal table indices for 880MHz fvco
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
113 * crystal frequency values
115 #define XTAL_FREQ_24000MHZ 24000
116 #define XTAL_FREQ_30000MHZ 30000
117 #define XTAL_FREQ_37400MHZ 37400
118 #define XTAL_FREQ_48000MHZ 48000
121 * Resource dependancies mask change action
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
127 #define RES_DEPEND_SET 0
128 #define RES_DEPEND_ADD 1
129 #define RES_DEPEND_REMOVE -1
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
143 /* Fields in clkstretch */
144 #define CSTRETCH_HT 0xffff0000
145 #define CSTRETCH_ALP 0x0000ffff
147 /* d11 slow to fast clock transition time in slow clock cycles */
148 #define D11SCC_SLOW2FAST_TRANSITION 2
151 #define ILP_CLOCK 32000
153 /* ALP clock on pre-PMU chips */
154 #define ALP_CLOCK 20000000
157 #define HT_CLOCK 80000000
159 #define OTPS_READY 0x00001000
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
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
181 /* PMU resource bit position */
182 #define PMURES_BIT(bit) (1 << (bit))
184 /* PMU resource number limit */
185 #define PMURES_MAX_RESNUM 30
187 /* PMU chip control0 register */
188 #define PMU_CHIPCTL0 0
190 /* PMU chip control1 register */
191 #define PMU_CHIPCTL1 1
192 #define PMU_CC1_RXC_DLL_BYPASS 0x00010000
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
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
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.
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
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
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
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
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
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
260 #define PMU1_PLL0_CHIPCTL0 0
261 #define PMU1_PLL0_CHIPCTL1 1
262 #define PMU1_PLL0_CHIPCTL2 2
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)
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
282 #define PMU1_PLL0_PLLCTL3 3
283 #define PMU1_PLL0_PC3_NDIV_FRAC_MASK 0x00ffffff
284 #define PMU1_PLL0_PC3_NDIV_FRAC_SHIFT 0
287 #define PMU1_PLL0_PLLCTL4 4
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
294 /* PMU rev 2 control words */
295 #define PMU2_PHY_PLL_PLLCTL 4
296 #define PMU2_SI_PLL_PLLCTL 10
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
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
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
330 #define PMU2_PLL_PLLCTL3 3
331 #define PMU2_PLL_PC3_NDIV_FRAC_MASK 0x00ffffff
332 #define PMU2_PLL_PC3_NDIV_FRAC_SHIFT 0
335 #define PMU2_PLL_PLLCTL4 4
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
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
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
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
386 #define PMU7_PLL_PLLCTL7 7
387 #define PMU7_PLL_PLLCTL8 8
388 #define PMU7_PLL_PLLCTL11 11
390 /* PLL usage in 4716/47162 */
391 #define PMU4716_MAINPLL_PLL0 12
393 /* PLL usage in 5356/5357 */
394 #define PMU5356_MAINPLL_PLL0 0
395 #define PMU5357_MAINPLL_PLL0 0
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 */
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 */
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 */
449 /* 4325 C1 resources */
450 #define RES4325C1_LNLDO2_PU 12 /* 0x00001000 */
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 */
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 */
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 */
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
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
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
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
596 /* PMU resource up transition time in ILP cycles */
597 #define PMURES_UP_TRANSITION 2
599 /* Setup resource up/down timers */
605 /* Change resource dependancies masks */
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 */
613 /* setup pll and query clock speed */
624 * prototypes used in resource tables
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);
631 static const pmu_res_updown_t bcm4328a0_res_updown[] = {
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}
655 static const pmu_res_depend_t bcm4328a0_res_depend[] = {
656 /* Adjust ILP request resource not to force ext/BB switchers into burst mode */
658 PMURES_BIT(RES4328_ILP_REQUEST),
660 PMURES_BIT(RES4328_EXT_SWITCHER_PWM) |
661 PMURES_BIT(RES4328_BB_SWITCHER_PWM), NULL}
664 static const pmu_res_updown_t bcm4325a0_res_updown_qt[] = {
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}
676 static const pmu_res_updown_t bcm4325a0_res_updown[] = {
678 RES4325_XTAL_PU, 0x1501}
681 static const pmu_res_depend_t bcm4325a0_res_depend[] = {
682 /* Adjust OTP PU resource dependencies - remove BB BURST */
684 PMURES_BIT(RES4325_OTP_PU),
686 PMURES_BIT(RES4325_BUCK_BOOST_BURST), NULL},
687 /* Adjust ALP/HT Avail resource dependencies - bring up BB along if it is used. */
689 PMURES_BIT(RES4325_ALP_AVAIL) | PMURES_BIT(RES4325_HT_AVAIL),
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. */
695 PMURES_BIT(RES4325_HT_AVAIL),
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. */
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}
722 static const pmu_res_updown_t bcm4315a0_res_updown_qt[] = {
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}
734 static const pmu_res_updown_t bcm4315a0_res_updown[] = {
736 RES4315_XTAL_PU, 0x2501}
739 static const pmu_res_depend_t bcm4315a0_res_depend[] = {
740 /* Adjust OTP PU resource dependencies - not need PALDO unless write */
742 PMURES_BIT(RES4315_OTP_PU),
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. */
747 PMURES_BIT(RES4315_ALP_AVAIL) | PMURES_BIT(RES4315_HT_AVAIL),
749 PMURES_BIT(RES4315_PALDO_PU), si_pmu_res_depfltr_paldo},
750 /* Adjust HT Avail resource dependencies - bring up RF switches along with HT. */
752 PMURES_BIT(RES4315_HT_AVAIL),
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. */
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}
778 /* 4329 specific. needs to come back this issue later */
779 static const pmu_res_updown_t bcm4329_res_updown[] = {
781 RES4329_XTAL_PU, 0x1501}
784 static const pmu_res_depend_t bcm4329_res_depend[] = {
785 /* Adjust HT Avail resource dependencies */
787 PMURES_BIT(RES4329_HT_AVAIL),
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}
805 static const pmu_res_updown_t bcm4319a0_res_updown_qt[] = {
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}
817 static const pmu_res_updown_t bcm4319a0_res_updown[] = {
819 RES4319_XTAL_PU, 0x3f01}
822 static const pmu_res_depend_t bcm4319a0_res_depend[] = {
823 /* Adjust OTP PU resource dependencies - not need PALDO unless write */
825 PMURES_BIT(RES4319_OTP_PU),
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. */
830 PMURES_BIT(RES4319_HT_AVAIL),
832 PMURES_BIT(RES4319_PALDO_PU), si_pmu_res_depfltr_paldo},
833 /* Adjust HT Avail resource dependencies - bring up RF switches along with HT. */
835 PMURES_BIT(RES4319_HT_AVAIL),
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}
844 static const pmu_res_updown_t bcm4336a0_res_updown_qt[] = {
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}
854 static const pmu_res_updown_t bcm4336a0_res_updown[] = {
856 RES4336_HT_AVAIL, 0x0D01}
859 static const pmu_res_depend_t bcm4336a0_res_depend[] = {
860 /* Just a dummy entry for now */
862 PMURES_BIT(RES4336_RSVD), RES_DEPEND_ADD, 0, NULL}
865 static const pmu_res_updown_t bcm4330a0_res_updown_qt[] = {
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}
875 static const pmu_res_updown_t bcm4330a0_res_updown[] = {
877 RES4330_HT_AVAIL, 0x0e02}
880 static const pmu_res_depend_t bcm4330a0_res_depend[] = {
881 /* Just a dummy entry for now */
883 PMURES_BIT(RES4330_HT_AVAIL), RES_DEPEND_ADD, 0, NULL}
886 /* the following table is based on 1440Mhz fvco */
887 static const pmu1_xtaltab0_t pmu1_xtaltab0_1440[] = {
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}, {
908 static const pmu1_xtaltab0_t pmu1_xtaltab0_960[] = {
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}, {
929 static const pmu1_xtaltab0_t pmu1_xtaltab0_880_4329[] = {
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}, {
950 /* the following table is based on 880Mhz fvco */
951 static const pmu1_xtaltab0_t pmu1_xtaltab0_880[] = {
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}, {
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)
975 return (sih->boardflags & BFL_BUCKBOOST) != 0;
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)
982 return (sih->boardflags & BFL_NOCBUCK) != 0;
985 /* true if the power topology uses the PALDO */
986 static bool si_pmu_res_depfltr_paldo(si_t *sih)
988 return (sih->boardflags & BFL_PALDO) != 0;
991 /* true if the power topology doesn't use the PALDO */
992 static bool si_pmu_res_depfltr_npaldo(si_t *sih)
994 return (sih->boardflags & BFL_PALDO) == 0;
997 /* Return dependancies (direct or all/indirect) for the given resources */
999 si_pmu_res_deps(si_t *sih, chipcregs_t *cc, u32 rsrcs,
1005 for (i = 0; i <= PMURES_MAX_RESNUM; i++) {
1006 if (!(rsrcs & PMURES_BIT(i)))
1008 W_REG(&cc->res_table_sel, i);
1009 deps |= R_REG(&cc->res_dep_mask);
1012 return !all ? deps : (deps
1014 si_pmu_res_deps(sih, cc, deps,
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)
1021 u32 min_mask = 0, max_mask = 0;
1026 rsrcs = (sih->pmucaps & PCAP_RC_MASK) >> PCAP_RC_SHIFT;
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:
1041 case BCM4329_CHIP_ID:
1042 /* 4329 spedific issue. Needs to come back this issue later */
1043 /* Down to save the power. */
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;
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);
1055 /* Allow everything else to be turned on upon requests */
1056 max_mask = ~(~0 << rsrcs);
1058 case BCM4336_CHIP_ID:
1059 /* Down to save the power. */
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;
1068 case BCM4330_CHIP_ID:
1069 /* Down to save the power. */
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;
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);
1089 /* Apply nvram override to min mask */
1090 val = getvar(NULL, "rmin");
1092 min_mask = (u32) simple_strtoul(val, NULL, 0);
1094 /* Apply nvram override to max mask */
1095 val = getvar(NULL, "rmax");
1097 max_mask = (u32) simple_strtoul(val, NULL, 0);
1104 /* Return up time in ILP cycles for the given resource. */
1106 si_pmu_res_uptime(si_t *sih, chipcregs_t *cc, u8 rsrc) {
1108 uint up, i, dup, dmax;
1109 u32 min_mask = 0, max_mask = 0;
1111 /* uptime of resource 'rsrc' */
1112 W_REG(&cc->res_table_sel, rsrc);
1113 up = (R_REG(&cc->res_updn_timer) >> 8) & 0xff;
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)))
1120 deps &= ~si_pmu_res_deps(sih, cc, PMURES_BIT(i), true);
1122 si_pmu_res_masks(sih, &min_mask, &max_mask);
1125 /* max uptime of direct dependancies */
1127 for (i = 0; i <= PMURES_MAX_RESNUM; i++) {
1128 if (!(deps & PMURES_BIT(i)))
1130 dup = si_pmu_res_uptime(sih, cc, (u8) i);
1135 return up + dmax + PMURES_UP_TRANSITION;
1139 si_pmu_spuravoid_pllupdate(si_t *sih, chipcregs_t *cc, u8 spuravoid)
1142 u8 phypll_offset = 0;
1143 u8 bcm5357_bcm43236_p1div[] = { 0x1, 0x5, 0x5 };
1144 u8 bcm5357_bcm43236_ndiv[] = { 0x30, 0xf6, 0xfc };
1146 switch (sih->chip) {
1147 case BCM5357_CHIP_ID:
1148 case BCM43235_CHIP_ID:
1149 case BCM43236_CHIP_ID:
1150 case BCM43238_CHIP_ID:
1153 * BCM5357 needs to touch PLL1_PLLCTL[02],
1154 * so offset PLL0_PLLCTL[02] by 6
1156 phypll_offset = (sih->chip == BCM5357_CHIP_ID) ? 6 : 0;
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));
1164 (bcm5357_bcm43236_p1div[spuravoid] <<
1165 PMU1_PLL0_PC0_P1DIV_SHIFT);
1166 W_REG(&cc->pllcontrol_data, tmp);
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);
1174 (bcm5357_bcm43236_ndiv[spuravoid]) <<
1175 PMU1_PLL0_PC2_NDIV_INT_SHIFT;
1176 W_REG(&cc->pllcontrol_data, tmp);
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);
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);
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);
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);
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);
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);
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);
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);
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);
1298 /* enable 40/80/160Mhz clock mode */
1299 W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2);
1300 W_REG(&cc->pllcontrol_data, 0x05001828);
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);
1308 W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1);
1309 W_REG(&cc->pllcontrol_data, 0x0C0C0C0C);
1311 W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2);
1312 W_REG(&cc->pllcontrol_data, 0x01240C0C);
1314 W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4);
1315 W_REG(&cc->pllcontrol_data, 0x202C2820);
1317 W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5);
1318 W_REG(&cc->pllcontrol_data, 0x88888825);
1320 W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3);
1322 W_REG(&cc->pllcontrol_data, 0x00EC4EC4);
1324 W_REG(&cc->pllcontrol_data, 0x00762762);
1326 tmp = PCTL_PLL_PLLCTL_UPD;
1334 tmp |= R_REG(&cc->pmucontrol);
1335 W_REG(&cc->pmucontrol, tmp);
1338 /* select default xtal frequency for each chip */
1339 static const pmu1_xtaltab0_t *si_pmu1_xtaldef0(si_t *sih)
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];
1356 return &pmu1_xtaltab0_1440[PMU1_XTALTAB0_1440_37400K];
1363 /* select xtal table for each chip */
1364 static const pmu1_xtaltab0_t *si_pmu1_xtaltab0(si_t *sih)
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;
1377 return pmu1_xtaltab0_1440;
1384 /* query alp/xtal clock frequency */
1386 si_pmu1_alpclk0(si_t *sih, chipcregs_t *cc)
1388 const pmu1_xtaltab0_t *xt;
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++)
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;
1403 /* select default pll fvco for each chip */
1404 static u32 si_pmu1_pllfvco0(si_t *sih)
1406 switch (sih->chip) {
1407 case BCM4329_CHIP_ID:
1409 case BCM4319_CHIP_ID:
1411 case BCM4336_CHIP_ID:
1413 case BCM4330_CHIP_ID:
1414 if (CST4330_CHIPMODE_SDIOD(sih->chipst))
1424 static void si_pmu_set_4330_plldivs(si_t *sih)
1426 u32 FVCO = si_pmu1_pllfvco0(sih) / 1000;
1427 u32 m1div, m2div, m3div, m4div, m5div, m6div;
1430 m2div = m3div = m4div = m6div = FVCO / 80;
1433 if (CST4330_CHIPMODE_SDIOD(sih->chipst))
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);
1444 pllc2 = si_pmu_pllcontrol(sih, PMU1_PLL0_PLLCTL1, 0, 0);
1445 pllc2 &= ~(PMU1_PLL0_PC2_M5DIV_MASK | PMU1_PLL0_PC2_M6DIV_MASK);
1447 ((m5div << PMU1_PLL0_PC2_M5DIV_SHIFT) |
1448 (m6div << PMU1_PLL0_PC2_M6DIV_SHIFT));
1449 si_pmu_pllcontrol(sih, PMU1_PLL0_PLLCTL2, ~0, pllc2);
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.
1458 static void si_pmu1_pllinit0(si_t *sih, chipcregs_t *cc, u32 xtal)
1460 const pmu1_xtaltab0_t *xt;
1462 u32 buf_strength = 0;
1465 /* Use h/w default PLL config */
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)
1475 /* Check current PLL state, bail out if it has been programmed or
1476 * we don't know how to program it.
1478 if (xt == NULL || xt->fref == 0) {
1481 /* for 4319 bootloader already programs the PLL but bootloader does not
1482 * program the PLL4 and PLL5. So Skip this check for 4319
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)))
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)
1505 else if (xt->fref == 37400)
1507 else if (xt->fref == 26000)
1510 tmp = 0x200005C0; /* Chip Dflt Settings */
1511 W_REG(&cc->pllcontrol_data, tmp);
1512 W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5);
1514 R_REG(&cc->pllcontrol_data) & PMU1_PLL0_PC5_CLK_DRV_MASK;
1515 if ((xt->fref == 38400) || (xt->fref == 37400)
1516 || (xt->fref == 26000))
1519 tmp |= 0x25; /* Chip Dflt Settings */
1520 W_REG(&cc->pllcontrol_data, tmp);
1523 case BCM4319_CHIP_ID:
1524 /* Change the BBPLL drive strength to 2 for all channels */
1525 buf_strength = 0x222222;
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.
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)));
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)));
1544 SPINWAIT(R_REG(&cc->clk_ctl_st) & CCS_HTAVAIL,
1545 PMU_MAX_TRANSITION_DLY);
1546 W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4);
1548 W_REG(&cc->pllcontrol_data, tmp);
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)));
1559 SPINWAIT(R_REG(&cc->clk_ctl_st) & CCS_HTAVAIL,
1560 PMU_MAX_TRANSITION_DLY);
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)));
1571 SPINWAIT(R_REG(&cc->clk_ctl_st) & CCS_HTAVAIL,
1572 PMU_MAX_TRANSITION_DLY);
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);
1585 p1div << PMU1_PLL0_PC0_P1DIV_SHIFT) & PMU1_PLL0_PC0_P1DIV_MASK) |
1587 p2div << PMU1_PLL0_PC0_P2DIV_SHIFT) & PMU1_PLL0_PC0_P2DIV_MASK);
1588 W_REG(&cc->pllcontrol_data, tmp);
1590 if ((sih->chip == BCM4330_CHIP_ID))
1591 si_pmu_set_4330_plldivs(sih);
1593 if ((sih->chip == BCM4329_CHIP_ID)
1594 && (sih->chiprev == 0)) {
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);
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;
1607 ndiv_mode = PMU1_PLL0_PC2_NDIV_MODE_MASH;
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);
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);
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);
1628 /* Write clock driving strength to pllcontrol[5] */
1630 W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5);
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);
1637 /* to operate the 4319 usb in 24MHz/48MHz; chipcontrol[2][84:83] needs
1640 if ((sih->chip == BCM4319_CHIP_ID)
1641 && (xt->fref != XTAL_FREQ_30000MHZ)) {
1642 W_REG(&cc->chipcontrol_addr, PMU1_PLL0_CHIPCTL2);
1644 R_REG(&cc->chipcontrol_data) & ~CCTL_4319USB_XTAL_SEL_MASK;
1645 if (xt->fref == XTAL_FREQ_24000MHZ) {
1647 (CCTL_4319USB_24MHZ_PLL_SEL <<
1648 CCTL_4319USB_XTAL_SEL_SHIFT);
1649 } else if (xt->fref == XTAL_FREQ_48000MHZ) {
1651 (CCTL_4319USB_48MHZ_PLL_SEL <<
1652 CCTL_4319USB_XTAL_SEL_SHIFT);
1654 W_REG(&cc->chipcontrol_data, tmp);
1657 /* Flush deferred pll control registers writes */
1658 if (sih->pmurev >= 2)
1659 OR_REG(&cc->pmucontrol, PCTL_PLL_PLLCTL_UPD);
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);
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;
1675 W_REG(&cc->pmucontrol, tmp);
1678 u32 si_pmu_ilp_clock(si_t *sih)
1680 static u32 ilpcycles_per_sec;
1682 if (ISSIM_ENAB(sih) || !PMUCTL_ENAB(sih))
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);
1697 return ilpcycles_per_sec;
1700 void si_pmu_set_ldo_voltage(si_t *sih, u8 ldo, u8 voltage)
1702 u8 sr_cntl_shift = 0, rc_shift = 0, shift = 0, mask = 0;
1705 switch (sih->chip) {
1706 case BCM4336_CHIP_ID:
1708 case SET_LDO_VOLTAGE_CLDO_PWM:
1713 case SET_LDO_VOLTAGE_CLDO_BURST:
1718 case SET_LDO_VOLTAGE_LNLDO1:
1727 case BCM4330_CHIP_ID:
1729 case SET_LDO_VOLTAGE_CBUCK_PWM:
1742 shift = sr_cntl_shift + rc_shift;
1744 ai_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, regcontrol_addr),
1746 ai_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, regcontrol_data),
1747 mask << shift, (voltage & mask) << shift);
1750 u16 si_pmu_fast_pwrup_delay(si_t *sih)
1752 uint delay = PMU_MAX_TRANSITION_DLY;
1757 chn[0] = 0; /* to suppress compile error */
1760 /* Remember original core before switch to chipc */
1761 origidx = ai_coreidx(sih);
1762 cc = ai_setcoreidx(sih, SI_CC_IDX);
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;
1776 case BCM4329_CHIP_ID:
1777 if (ISSIM_ENAB(sih))
1780 u32 ilp = si_pmu_ilp_clock(sih);
1782 (si_pmu_res_uptime(sih, cc, RES4329_HT_AVAIL) +
1783 D11SCC_SLOW2FAST_TRANSITION) * ((1000000 + ilp -
1785 delay = (11 * delay) / 10;
1788 case BCM4319_CHIP_ID:
1789 delay = ISSIM_ENAB(sih) ? 70 : 3700;
1791 case BCM4336_CHIP_ID:
1792 if (ISSIM_ENAB(sih))
1795 u32 ilp = si_pmu_ilp_clock(sih);
1797 (si_pmu_res_uptime(sih, cc, RES4336_HT_AVAIL) +
1798 D11SCC_SLOW2FAST_TRANSITION) * ((1000000 + ilp -
1800 delay = (11 * delay) / 10;
1803 case BCM4330_CHIP_ID:
1804 if (ISSIM_ENAB(sih))
1807 u32 ilp = si_pmu_ilp_clock(sih);
1809 (si_pmu_res_uptime(sih, cc, RES4330_HT_AVAIL) +
1810 D11SCC_SLOW2FAST_TRANSITION) * ((1000000 + ilp -
1812 delay = (11 * delay) / 10;
1818 /* Return to original core */
1819 ai_setcoreidx(sih, origidx);
1824 void si_pmu_sprom_enable(si_t *sih, bool enable)
1829 /* Remember original core before switch to chipc */
1830 origidx = ai_coreidx(sih);
1831 cc = ai_setcoreidx(sih, SI_CC_IDX);
1833 /* Return to original core */
1834 ai_setcoreidx(sih, origidx);
1837 /* Read/write a chipcontrol reg */
1838 u32 si_pmu_chipcontrol(si_t *sih, uint reg, u32 mask, u32 val)
1840 ai_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, chipcontrol_addr), ~0,
1842 return ai_corereg(sih, SI_CC_IDX,
1843 offsetof(chipcregs_t, chipcontrol_data), mask, val);
1846 /* Read/write a regcontrol reg */
1847 u32 si_pmu_regcontrol(si_t *sih, uint reg, u32 mask, u32 val)
1849 ai_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, regcontrol_addr), ~0,
1851 return ai_corereg(sih, SI_CC_IDX,
1852 offsetof(chipcregs_t, regcontrol_data), mask, val);
1855 /* Read/write a pllcontrol reg */
1856 u32 si_pmu_pllcontrol(si_t *sih, uint reg, u32 mask, u32 val)
1858 ai_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, pllcontrol_addr), ~0,
1860 return ai_corereg(sih, SI_CC_IDX,
1861 offsetof(chipcregs_t, pllcontrol_data), mask, val);
1864 /* PMU PLL update */
1865 void si_pmu_pllupd(si_t *sih)
1867 ai_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, pmucontrol),
1868 PCTL_PLL_PLLCTL_UPD, PCTL_PLL_PLLCTL_UPD);
1871 /* query alp/xtal clock frequency */
1872 u32 si_pmu_alp_clock(si_t *sih)
1876 u32 clock = ALP_CLOCK;
1878 /* bail out with default */
1879 if (!PMUCTL_ENAB(sih))
1882 /* Remember original core before switch to chipc */
1883 origidx = ai_coreidx(sih);
1884 cc = ai_setcoreidx(sih, SI_CC_IDX);
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:
1901 clock = 20000 * 1000;
1903 case BCM4329_CHIP_ID:
1904 case BCM4319_CHIP_ID:
1905 case BCM4336_CHIP_ID:
1906 case BCM4330_CHIP_ID:
1908 clock = si_pmu1_alpclk0(sih, cc);
1910 case BCM5356_CHIP_ID:
1912 clock = 25000 * 1000;
1918 /* Return to original core */
1919 ai_setcoreidx(sih, origidx);
1923 void si_pmu_spuravoid(si_t *sih, u8 spuravoid)
1926 uint origidx, intr_val;
1929 /* Remember original core before switch to chipc */
1930 cc = (chipcregs_t *) ai_switch_core(sih, CC_CORE_ID, &origidx,
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),
1943 /* update the pll changes */
1944 si_pmu_spuravoid_pllupdate(sih, cc, spuravoid);
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);
1953 /* Return to original core */
1954 ai_restore_core(sih, origidx, intr_val);
1957 /* initialize PMU */
1958 void si_pmu_init(si_t *sih)
1963 /* Remember original core before switch to chipc */
1964 origidx = ai_coreidx(sih);
1965 cc = ai_setcoreidx(sih, SI_CC_IDX);
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);
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);
1977 W_REG(&cc->regcontrol_addr, 3);
1978 OR_REG(&cc->regcontrol_data, 0x4);
1981 /* Return to original core */
1982 ai_setcoreidx(sih, origidx);
1985 /* initialize PMU chip controls and other chip level stuff */
1986 void si_pmu_chip_init(si_t *sih)
1990 /* Gate off SPROM clock and chip select signals */
1991 si_pmu_sprom_enable(sih, false);
1993 /* Remember original core */
1994 origidx = ai_coreidx(sih);
1996 /* Return to original core */
1997 ai_setcoreidx(sih, origidx);
2000 /* initialize PMU switch/regulators */
2001 void si_pmu_swreg_init(si_t *sih)
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,
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);
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);
2025 /* initialize PLL */
2026 void si_pmu_pll_init(si_t *sih, uint xtalfreq)
2031 /* Remember original core before switch to chipc */
2032 origidx = ai_coreidx(sih);
2033 cc = ai_setcoreidx(sih, SI_CC_IDX);
2035 switch (sih->chip) {
2036 case BCM4329_CHIP_ID:
2039 si_pmu1_pllinit0(sih, cc, xtalfreq);
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:
2052 case BCM4319_CHIP_ID:
2053 case BCM4336_CHIP_ID:
2054 case BCM4330_CHIP_ID:
2055 si_pmu1_pllinit0(sih, cc, xtalfreq);
2061 /* Return to original core */
2062 ai_setcoreidx(sih, origidx);
2065 /* initialize PMU resources */
2066 void si_pmu_res_init(si_t *sih)
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;
2078 /* Remember original core before switch to chipc */
2079 origidx = ai_coreidx(sih);
2080 cc = ai_setcoreidx(sih, SI_CC_IDX);
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;
2089 pmu_res_updown_table = bcm4329_res_updown;
2090 pmu_res_updown_table_sz =
2091 ARRAY_SIZE(bcm4329_res_updown);
2093 /* Optimize resources dependencies */
2094 pmu_res_depend_table = bcm4329_res_depend;
2095 pmu_res_depend_table_sz = ARRAY_SIZE(bcm4329_res_depend);
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);
2105 pmu_res_updown_table = bcm4319a0_res_updown;
2106 pmu_res_updown_table_sz =
2107 ARRAY_SIZE(bcm4319a0_res_updown);
2109 /* Optimize resources dependancies masks */
2110 pmu_res_depend_table = bcm4319a0_res_depend;
2111 pmu_res_depend_table_sz = ARRAY_SIZE(bcm4319a0_res_depend);
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);
2121 pmu_res_updown_table = bcm4336a0_res_updown;
2122 pmu_res_updown_table_sz =
2123 ARRAY_SIZE(bcm4336a0_res_updown);
2125 /* Optimize resources dependancies masks */
2126 pmu_res_depend_table = bcm4336a0_res_depend;
2127 pmu_res_depend_table_sz = ARRAY_SIZE(bcm4336a0_res_depend);
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);
2137 pmu_res_updown_table = bcm4330a0_res_updown;
2138 pmu_res_updown_table_sz =
2139 ARRAY_SIZE(bcm4330a0_res_updown);
2141 /* Optimize resources dependancies masks */
2142 pmu_res_depend_table = bcm4330a0_res_depend;
2143 pmu_res_depend_table_sz = ARRAY_SIZE(bcm4330a0_res_depend);
2151 rsrcs = (sih->pmucaps & PCAP_RC_MASK) >> PCAP_RC_SHIFT;
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);
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);
2166 W_REG(&cc->res_table_sel, (u32) i);
2167 W_REG(&cc->res_updn_timer,
2168 (u32) simple_strtoul(val, NULL, 0));
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].
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)
2181 W_REG(&cc->res_table_sel, i);
2182 switch (pmu_res_depend_table[pmu_res_depend_table_sz].
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);
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);
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);
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);
2210 W_REG(&cc->res_table_sel, (u32) i);
2211 W_REG(&cc->res_dep_mask,
2212 (u32) simple_strtoul(val, NULL, 0));
2215 /* Determine min/max rsrc masks */
2216 si_pmu_res_masks(sih, &min_mask, &max_mask);
2218 /* It is required to program max_mask first and then min_mask */
2220 /* Program max resource mask */
2223 W_REG(&cc->max_res_mask, max_mask);
2225 /* Program min resource mask */
2228 W_REG(&cc->min_res_mask, min_mask);
2230 /* Add some delay; allow resources to come up and settle. */
2233 /* Return to original core */
2234 ai_setcoreidx(sih, origidx);
2237 u32 si_pmu_measure_alpclk(si_t *sih)
2243 if (sih->pmurev < 10)
2246 /* Remember original core before switch to chipc */
2247 origidx = ai_coreidx(sih);
2248 cc = ai_setcoreidx(sih, SI_CC_IDX);
2250 if (R_REG(&cc->pmustatus) & PST_EXTLPOAVAIL) {
2251 u32 ilp_ctr, alp_hz;
2254 * Enable the reg to measure the freq,
2255 * in case it was disabled before
2257 W_REG(&cc->pmu_xtalfreq,
2258 1U << PMU_XTALFREQ_REG_MEASURE_SHIFT);
2260 /* Delay for well over 4 ILP clocks */
2263 /* Read the latched number of ALP ticks per 4 ILP ticks */
2265 R_REG(&cc->pmu_xtalfreq) & PMU_XTALFREQ_REG_ILPCTR_MASK;
2268 * Turn off the PMU_XTALFREQ_REG_MEASURE_SHIFT
2271 W_REG(&cc->pmu_xtalfreq, 0);
2273 /* Calculate ALP frequency */
2274 alp_hz = (ilp_ctr * EXT_ILP_HZ) / 4;
2277 * Round to nearest 100KHz, and at
2278 * the same time convert to KHz
2280 alp_khz = (alp_hz + 50000) / 100000 * 100;
2284 /* Return to original core */
2285 ai_setcoreidx(sih, origidx);
2290 bool si_pmu_is_otp_powered(si_t *sih)
2296 /* Remember original core before switch to chipc */
2297 idx = ai_coreidx(sih);
2298 cc = ai_setcoreidx(sih, SI_CC_IDX);
2300 switch (sih->chip) {
2301 case BCM4329_CHIP_ID:
2302 st = (R_REG(&cc->res_state) & PMURES_BIT(RES4329_OTP_PU))
2305 case BCM4319_CHIP_ID:
2306 st = (R_REG(&cc->res_state) & PMURES_BIT(RES4319_OTP_PU))
2309 case BCM4336_CHIP_ID:
2310 st = (R_REG(&cc->res_state) & PMURES_BIT(RES4336_OTP_PU))
2313 case BCM4330_CHIP_ID:
2314 st = (R_REG(&cc->res_state) & PMURES_BIT(RES4330_OTP_PU))
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.
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:
2334 /* Return to original core */
2335 ai_setcoreidx(sih, idx);
2339 /* power up/down OTP through PMU resources */
2340 void si_pmu_otp_power(si_t *sih, bool on)
2344 u32 rsrcs = 0; /* rsrcs to turn on/off OTP power */
2346 /* Don't do anything if OTP is disabled */
2347 if (ai_is_otp_disabled(sih))
2350 /* Remember original core before switch to chipc */
2351 origidx = ai_coreidx(sih);
2352 cc = ai_setcoreidx(sih, SI_CC_IDX);
2354 switch (sih->chip) {
2355 case BCM4329_CHIP_ID:
2356 rsrcs = PMURES_BIT(RES4329_OTP_PU);
2358 case BCM4319_CHIP_ID:
2359 rsrcs = PMURES_BIT(RES4319_OTP_PU);
2361 case BCM4336_CHIP_ID:
2362 rsrcs = PMURES_BIT(RES4336_OTP_PU);
2364 case BCM4330_CHIP_ID:
2365 rsrcs = PMURES_BIT(RES4330_OTP_PU);
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);
2379 /* Turn on/off the power */
2381 OR_REG(&cc->min_res_mask, (rsrcs | deps));
2382 SPINWAIT(!(R_REG(&cc->res_state) & rsrcs),
2383 PMU_MAX_TRANSITION_DLY);
2385 AND_REG(&cc->min_res_mask, ~(rsrcs | deps));
2388 SPINWAIT((((otps = R_REG(&cc->otpstatus)) & OTPS_READY) !=
2389 (on ? OTPS_READY : 0)), 100);
2392 /* Return to original core */
2393 ai_setcoreidx(sih, origidx);