1/*
2 * Misc utility routines for accessing PMU corerev specific features
3 * of the SiliconBackplane-based Broadcom chips.
4 *
5 * Copyright (C) 2015, Broadcom Corporation. All Rights Reserved.
6 *
7 * Permission to use, copy, modify, and/or distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
14 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
16 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
17 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 *
19 * $Id: hndpmu.c 472529 2014-04-24 08:55:47Z $
20 */
21
22
23/*
24 * Note: this file contains PLL/FLL related functions. A chip can contain multiple PLLs/FLLs.
25 * However, in the context of this file the baseband ('BB') PLL/FLL is referred to.
26 *
27 * Throughout this code, the prefixes 'pmu0_', 'pmu1_' and 'pmu2_' are used.
28 * They refer to different revisions of the PMU (which is at revision 18 @ Apr 25, 2012)
29 * pmu1_ marks the transition from PLL to ADFLL (Digital Frequency Locked Loop). It supports
30 * fractional frequency generation. pmu2_ does not support fractional frequency generation.
31 */
32
33#include <bcm_cfg.h>
34#include <typedefs.h>
35#include <bcmdefs.h>
36#include <osl.h>
37#include <bcmutils.h>
38#include <siutils.h>
39#include <bcmdevs.h>
40#include <hndsoc.h>
41#include <sbchipc.h>
42#include <hndpmu.h>
43#if defined DONGLEBUILD
44#include <hndcpu.h>
45#endif
46#include <bcmotp.h>
47#include "siutils_priv.h"
48#if defined(SAVERESTORE)
49#include <saverestore.h>
50#endif
51
52#define	PMU_ERROR(args)
53
54#define	PMU_MSG(args)
55
56/* To check in verbose debugging messages not intended
57 * to be on except on private builds.
58 */
59#define	PMU_NONE(args)
60
61/** contains resource bit positions for a specific chip */
62struct rsc_per_chip_s {
63	uint8 ht_avail;
64	uint8 macphy_clkavail;
65	uint8 ht_start;
66	uint8 otp_pu;
67};
68
69typedef struct rsc_per_chip_s rsc_per_chip_t;
70
71/* PLL controls/clocks */
72static void si_pmu0_pllinit0(si_t *sih, osl_t *osh, chipcregs_t *cc, uint32 xtal);
73static void si_pmu1_pllinit0(si_t *sih, osl_t *osh, chipcregs_t *cc, uint32 xtal);
74static void si_pmu1_pllinit1(si_t *sih, osl_t *osh, chipcregs_t *cc, uint32 xtal);
75static void si_pmu2_pllinit0(si_t *sih, osl_t *osh, chipcregs_t *cc, uint32 xtal);
76static void si_pmu_pll_off(si_t *sih, osl_t *osh, chipcregs_t *cc, uint32 *min_mask,
77	uint32 *max_mask, uint32 *clk_ctl_st);
78static void si_pmu_pll_off_isdone(si_t *sih, osl_t *osh, chipcregs_t *cc);
79static void si_pmu_pll_on(si_t *sih, osl_t *osh, chipcregs_t *cc, uint32 min_mask,
80	uint32 max_mask, uint32 clk_ctl_st);
81void si_pmu_otp_pllcontrol(si_t *sih, osl_t *osh);
82void si_pmu_otp_regcontrol(si_t *sih, osl_t *osh);
83void si_pmu_otp_chipcontrol(si_t *sih, osl_t *osh);
84uint32 si_pmu_def_alp_clock(si_t *sih, osl_t *osh);
85bool si_pmu_update_pllcontrol(si_t *sih, osl_t *osh, uint32 xtal, bool update_required);
86static uint32 si_pmu_htclk_mask(si_t *sih);
87
88static uint32 si_pmu0_alpclk0(si_t *sih, osl_t *osh, chipcregs_t *cc);
89static uint32 si_pmu0_cpuclk0(si_t *sih, osl_t *osh, chipcregs_t *cc);
90static uint32 si_pmu1_cpuclk0(si_t *sih, osl_t *osh, chipcregs_t *cc);
91static uint32 si_pmu1_alpclk0(si_t *sih, osl_t *osh, chipcregs_t *cc);
92static uint32 si_pmu2_alpclk0(si_t *sih, osl_t *osh, chipcregs_t *cc);
93static uint32 si_pmu2_cpuclk0(si_t *sih, osl_t *osh, chipcregs_t *cc);
94
95/* PMU resources */
96static bool si_pmu_res_depfltr_bb(si_t *sih);
97static bool si_pmu_res_depfltr_ncb(si_t *sih);
98static bool si_pmu_res_depfltr_paldo(si_t *sih);
99static bool si_pmu_res_depfltr_npaldo(si_t *sih);
100static uint32 si_pmu_res_deps(si_t *sih, osl_t *osh, chipcregs_t *cc, uint32 rsrcs, bool all);
101static uint si_pmu_res_uptime(si_t *sih, osl_t *osh, chipcregs_t *cc, uint8 rsrc);
102static void si_pmu_res_masks(si_t *sih, uint32 *pmin, uint32 *pmax);
103static void si_pmu_spuravoid_pllupdate(si_t *sih, chipcregs_t *cc, osl_t *osh, uint8 spuravoid);
104
105void si_pmu_set_4330_plldivs(si_t *sih, uint8 dacrate);
106static int8 si_pmu_cbuckout_to_vreg_ctrl(si_t *sih, uint16 cbuck_mv);
107
108int si_pmu_wait_for_steady_state(si_t *sih, osl_t *osh, chipcregs_t *cc);
109uint32 si_pmu_get_pmutime_diff(si_t *sih, osl_t *osh, chipcregs_t *cc, uint32 *prev);
110bool si_pmu_wait_for_res_pending(si_t *sih, osl_t *osh, chipcregs_t *cc, uint usec,
111	bool cond, uint32 *elapsed_time);
112uint32 si_pmu_get_pmutimer(si_t *sih, osl_t *osh, chipcregs_t *cc);
113/* PMU timer ticks once in 32uS */
114#define PMU_US_STEPS (32)
115
116
117void *g_si_pmutmr_lock_arg = NULL;
118si_pmu_callback_t g_si_pmutmr_lock_cb = NULL, g_si_pmutmr_unlock_cb = NULL;
119
120/* FVCO frequency */
121#define FVCO_880	880000	/* 880MHz */
122#define FVCO_1760	1760000	/* 1760MHz */
123#define FVCO_1440	1440000	/* 1440MHz */
124#define FVCO_960	960000	/* 960MHz */
125#define FVCO_963	963000	/* 963MHz */
126#define LPO_SEL_TIMEOUT 1000
127
128/* defines to make the code more readable */
129#define NO_SUCH_RESOURCE	0	/* means: chip does not have such a PMU resource */
130
131/*
132 * access to indirect register interfaces
133 */
134
135/** Read/write a chipcontrol reg */
136uint32
137si_pmu_chipcontrol(si_t *sih, uint reg, uint32 mask, uint32 val)
138{
139	pmu_corereg(sih, SI_CC_IDX, chipcontrol_addr, ~0, reg);
140	return pmu_corereg(sih, SI_CC_IDX, chipcontrol_data, mask, val);
141}
142
143/** Read/write a regcontrol reg */
144uint32
145si_pmu_regcontrol(si_t *sih, uint reg, uint32 mask, uint32 val)
146{
147	pmu_corereg(sih, SI_CC_IDX, regcontrol_addr, ~0, reg);
148	return pmu_corereg(sih, SI_CC_IDX, regcontrol_data, mask, val);
149}
150
151/** Read/write a pllcontrol reg */
152uint32
153si_pmu_pllcontrol(si_t *sih, uint reg, uint32 mask, uint32 val)
154{
155	pmu_corereg(sih, SI_CC_IDX, pllcontrol_addr, ~0, reg);
156	return pmu_corereg(sih, SI_CC_IDX, pllcontrol_data, mask, val);
157}
158
159/**
160 * The chip has one or more PLLs/FLLs (e.g. baseband PLL, USB PHY PLL). The settings of each PLL are
161 * contained within one or more 'PLL control' registers. Since the PLL hardware requires that
162 * changes for one PLL are committed at once, the PMU has a provision for 'updating' all PLL control
163 * registers at once.
164 *
165 * When software wants to change the any PLL parameters, it withdraws requests for that PLL clock,
166 * updates the PLL control registers being careful not to alter any control signals for the other
167 * PLLs, and then writes a 1 to PMUCtl.PllCtnlUpdate to commit the changes. Best usage model would
168 * be bring PLL down then update the PLL control register.
169 */
170void
171si_pmu_pllupd(si_t *sih)
172{
173	pmu_corereg(sih, SI_CC_IDX, pmucontrol,
174	           PCTL_PLL_PLLCTL_UPD, PCTL_PLL_PLLCTL_UPD);
175}
176
177static rsc_per_chip_t rsc_4313 =  {RES4313_HT_AVAIL_RSRC, RES4313_MACPHY_CLK_AVAIL_RSRC,
178	NO_SUCH_RESOURCE,  NO_SUCH_RESOURCE};
179static rsc_per_chip_t rsc_4314 =  {RES4314_HT_AVAIL,  RES4314_MACPHY_CLK_AVAIL,
180	NO_SUCH_RESOURCE,  RES4314_OTP_PU};
181static rsc_per_chip_t rsc_4315 =  {RES4315_HT_AVAIL,  NO_SUCH_RESOURCE,
182	NO_SUCH_RESOURCE,  RES4315_OTP_PU};
183static rsc_per_chip_t rsc_4319 =  {RES4319_HT_AVAIL,  NO_SUCH_RESOURCE,
184	NO_SUCH_RESOURCE,  RES4319_OTP_PU};
185static rsc_per_chip_t rsc_4322 =  {NO_SUCH_RESOURCE,  NO_SUCH_RESOURCE,
186	NO_SUCH_RESOURCE,  RES4322_OTP_PU};
187static rsc_per_chip_t rsc_4324 =  {RES4324_HT_AVAIL,  RES4324_MACPHY_CLKAVAIL,
188	NO_SUCH_RESOURCE,  RES4324_OTP_PU};
189static rsc_per_chip_t rsc_4325 =  {RES4325_HT_AVAIL,  NO_SUCH_RESOURCE,
190	NO_SUCH_RESOURCE,  RES4325_OTP_PU};
191static rsc_per_chip_t rsc_4329 =  {RES4329_HT_AVAIL,  NO_SUCH_RESOURCE,
192	NO_SUCH_RESOURCE,  RES4329_OTP_PU};
193static rsc_per_chip_t rsc_4330 =  {RES4330_HT_AVAIL,  RES4330_MACPHY_CLKAVAIL,
194	NO_SUCH_RESOURCE,  RES4330_OTP_PU};
195static rsc_per_chip_t rsc_4334 =  {RES4334_HT_AVAIL,  RES4334_MACPHY_CLK_AVAIL,
196	NO_SUCH_RESOURCE,  RES4334_OTP_PU};
197static rsc_per_chip_t rsc_4335 =  {RES4335_HT_AVAIL,  RES4335_MACPHY_CLKAVAIL,
198	RES4335_HT_START,  RES4335_OTP_PU};
199static rsc_per_chip_t rsc_4336 =  {RES4336_HT_AVAIL,  RES4336_MACPHY_CLKAVAIL,
200	NO_SUCH_RESOURCE,  RES4336_OTP_PU};
201static rsc_per_chip_t rsc_4350 =  {RES4350_HT_AVAIL,  RES4350_MACPHY_CLKAVAIL,
202	RES4350_HT_START,  RES4350_OTP_PU};
203static rsc_per_chip_t rsc_4352 =  {NO_SUCH_RESOURCE,  NO_SUCH_RESOURCE,
204	NO_SUCH_RESOURCE,  RES4360_OTP_PU}; /* 4360_OTP_PU is used for 4352, not a typo */
205static rsc_per_chip_t rsc_4360 =  {RES4360_HT_AVAIL,  NO_SUCH_RESOURCE,
206	NO_SUCH_RESOURCE,  RES4360_OTP_PU};
207static rsc_per_chip_t rsc_43143 = {RES43143_HT_AVAIL, RES43143_MACPHY_CLK_AVAIL,
208	NO_SUCH_RESOURCE,  RES43143_OTP_PU};
209static rsc_per_chip_t rsc_43236 =  {RES43236_HT_SI_AVAIL, NO_SUCH_RESOURCE,
210	NO_SUCH_RESOURCE,  NO_SUCH_RESOURCE};
211static rsc_per_chip_t rsc_43239 = {RES43239_HT_AVAIL, RES43239_MACPHY_CLKAVAIL,
212	NO_SUCH_RESOURCE,  RES43239_OTP_PU};
213static rsc_per_chip_t rsc_43602 = {RES43602_HT_AVAIL, RES43602_MACPHY_CLKAVAIL,
214	RES43602_HT_START, NO_SUCH_RESOURCE};
215
216/**
217* For each chip, location of resource bits (e.g., ht bit) in resource mask registers may differ.
218* This function abstracts the bit position of commonly used resources, thus making the rest of the
219* code in hndpmu.c cleaner.
220*/
221static rsc_per_chip_t* si_pmu_get_rsc_positions(si_t *sih)
222{
223	rsc_per_chip_t *rsc = NULL;
224
225	switch (CHIPID(sih->chip)) {
226	case BCM4313_CHIP_ID:
227		rsc = &rsc_4313;
228		break;
229	case BCM4314_CHIP_ID:
230	case BCM43142_CHIP_ID:
231		rsc = &rsc_4314;
232		break;
233	case BCM4315_CHIP_ID:
234		rsc = &rsc_4315;
235		break;
236	case BCM4319_CHIP_ID:
237		rsc = &rsc_4319;
238		break;
239	case BCM4322_CHIP_ID:
240	case BCM43221_CHIP_ID:
241	case BCM43231_CHIP_ID:
242	case BCM4342_CHIP_ID:
243		rsc = &rsc_4322;
244		break;
245	case BCM4324_CHIP_ID:
246	case BCM43242_CHIP_ID:
247	case BCM43243_CHIP_ID:
248		rsc = &rsc_4324;
249		break;
250	case BCM4325_CHIP_ID:
251		rsc = &rsc_4325;
252		break;
253	case BCM4329_CHIP_ID:
254		rsc = &rsc_4329;
255		break;
256	case BCM4330_CHIP_ID:
257		rsc = &rsc_4330;
258		break;
259	case BCM4331_CHIP_ID: /* fall through */
260	case BCM43236_CHIP_ID:
261		rsc = &rsc_43236;
262		break;
263	case BCM4334_CHIP_ID:
264	case BCM43341_CHIP_ID:
265		rsc = &rsc_4334;
266		break;
267	case BCM4335_CHIP_ID:
268		rsc = &rsc_4335;
269		break;
270	case BCM4336_CHIP_ID:
271	case BCM43362_CHIP_ID:
272		rsc = &rsc_4336;
273		break;
274	case BCM4345_CHIP_ID:	/* same resource defs for bits in struct rsc_per_chip_s as 4350 */
275	case BCM4350_CHIP_ID:
276	case BCM4354_CHIP_ID:
277	case BCM4356_CHIP_ID:
278	case BCM43556_CHIP_ID:
279	case BCM43558_CHIP_ID:
280	case BCM43566_CHIP_ID:
281	case BCM43568_CHIP_ID:
282	case BCM43569_CHIP_ID:
283	case BCM43570_CHIP_ID:
284		rsc = &rsc_4350;
285		break;
286	case BCM4352_CHIP_ID:
287	case BCM43526_CHIP_ID:	/* usb variant of 4352 */
288		rsc = &rsc_4352;
289		break;
290	case BCM4360_CHIP_ID:
291	case BCM43460_CHIP_ID:
292		rsc = &rsc_4360;
293		break;
294	case BCM43143_CHIP_ID:
295		rsc = &rsc_43143;
296		break;
297	case BCM43239_CHIP_ID:
298		rsc = &rsc_43239;
299		break;
300	case BCM43602_CHIP_ID:
301	case BCM43462_CHIP_ID:
302		rsc = &rsc_43602;
303		break;
304	default:
305		ASSERT(0);
306		break;
307	}
308
309	return rsc;
310}; /* si_pmu_get_rsc_positions */
311
312
313/* This function is not called in at least trunk nor PHOENIX2_BRANCH_6_10. Dead code? */
314/** PMU PLL reset */
315void
316si_pmu_pllreset(si_t *sih)
317{
318	chipcregs_t *cc;
319	uint origidx;
320	osl_t *osh;
321	uint32 max_res_mask, min_res_mask, clk_ctl_st;
322
323	if (!si_pmu_htclk_mask(sih))
324		return;
325
326	osh = si_osh(sih);
327	/* Remember original core before switch to chipc */
328	origidx = si_coreidx(sih);
329	cc = si_setcoreidx(sih, SI_CC_IDX);
330	ASSERT(cc != NULL);
331
332	si_pmu_pll_off(sih, osh, cc, &min_res_mask, &max_res_mask, &clk_ctl_st);
333
334	OR_REG(osh, PMUREG(sih, pmucontrol), PCTL_PLL_PLLCTL_UPD);
335	si_pmu_pll_on(sih, osh, cc, min_res_mask, max_res_mask, clk_ctl_st);
336
337	/* Return to original core */
338	si_setcoreidx(sih, origidx);
339}
340
341static const char BCMATTACHDATA(rstr_pllD)[] = "pll%d";
342static const char BCMATTACHDATA(rstr_regD)[] = "reg%d";
343static const char BCMATTACHDATA(rstr_chipcD)[] = "chipc%d";
344static const char BCMATTACHDATA(rstr_rmin)[] = "rmin";
345static const char BCMATTACHDATA(rstr_rmax)[] = "rmax";
346static const char BCMATTACHDATA(rstr_rDt)[] = "r%dt";
347static const char BCMATTACHDATA(rstr_rDd)[] = "r%dd";
348static const char BCMATTACHDATA(rstr_Invalid_Unsupported_xtal_value_D)[] =
349	"Invalid/Unsupported xtal value %d";
350static const char BCMATTACHDATA(rstr_dacrate2g)[] = "dacrate2g";
351static const char BCMATTACHDATA(rstr_clkreq_conf)[] = "clkreq_conf";
352static const char BCMATTACHDATA(rstr_cbuckout)[] = "cbuckout";
353static const char BCMATTACHDATA(rstr_cldo_ldo2)[] = "cldo_ldo2";
354static const char BCMATTACHDATA(rstr_cldo_pwm)[] = "cldo_pwm";
355static const char BCMATTACHDATA(rstr_force_pwm_cbuck)[] = "force_pwm_cbuck";
356static const char BCMATTACHDATA(rstr_xtalfreq)[] = "xtalfreq";
357static const char BCMATTACHDATA(rstr_avs_enab)[] = "avs_enab";
358
359/* The check for OTP parameters for the PLL control registers is done and if found the
360 * registers are updated accordingly.
361 */
362
363void
364BCMATTACHFN(si_pmu_otp_pllcontrol)(si_t *sih, osl_t *osh)
365{
366	char name[16];
367	const char *otp_val;
368	uint8 i;
369	uint32 val;
370	uint8 pll_ctrlcnt = 0;
371
372
373	if (sih->pmurev >= 5) {
374		pll_ctrlcnt = (sih->pmucaps & PCAP5_PC_MASK) >> PCAP5_PC_SHIFT;
375	}
376	else {
377		pll_ctrlcnt = (sih->pmucaps & PCAP_PC_MASK) >> PCAP_PC_SHIFT;
378	}
379
380	for (i = 0; i < pll_ctrlcnt; i++) {
381		snprintf(name, sizeof(name), rstr_pllD, i);
382		if ((otp_val = getvar(NULL, name)) == NULL)
383			continue;
384
385		val = (uint32)bcm_strtoul(otp_val, NULL, 0);
386		W_REG(osh, PMUREG(sih, pllcontrol_addr), i);
387		W_REG(osh, PMUREG(sih, pllcontrol_data), val);
388	}
389}
390
391/**
392 * The check for OTP parameters for the Voltage Regulator registers is done and if found the
393 * registers are updated accordingly.
394 */
395void
396BCMATTACHFN(si_pmu_otp_regcontrol)(si_t *sih, osl_t *osh)
397{
398	char name[16];
399	const char *otp_val;
400	uint8 i;
401	uint32 val;
402	uint8 vreg_ctrlcnt = 0;
403
404	if (sih->pmurev >= 5) {
405		vreg_ctrlcnt = (sih->pmucaps & PCAP5_VC_MASK) >> PCAP5_VC_SHIFT;
406	}
407	else {
408		vreg_ctrlcnt = (sih->pmucaps & PCAP_VC_MASK) >> PCAP_VC_SHIFT;
409	}
410
411	for (i = 0; i < vreg_ctrlcnt; i++) {
412		snprintf(name, sizeof(name), rstr_regD, i);
413		if ((otp_val = getvar(NULL, name)) == NULL)
414			continue;
415
416		val = (uint32)bcm_strtoul(otp_val, NULL, 0);
417		W_REG(osh, PMUREG(sih, regcontrol_addr), i);
418		W_REG(osh, PMUREG(sih, regcontrol_data), val);
419	}
420}
421
422/**
423 * The check for OTP parameters for the chip control registers is done and if found the
424 * registers are updated accordingly.
425 */
426void
427BCMATTACHFN(si_pmu_otp_chipcontrol)(si_t *sih, osl_t *osh)
428{
429	uint32 val, cc_ctrlcnt, i;
430	char name[16];
431	const char *otp_val;
432
433	if (sih->pmurev >= 5) {
434		cc_ctrlcnt = (sih->pmucaps & PCAP5_CC_MASK) >> PCAP5_CC_SHIFT;
435	}
436	else {
437		cc_ctrlcnt = (sih->pmucaps & PCAP_CC_MASK) >> PCAP_CC_SHIFT;
438	}
439
440	for (i = 0; i < cc_ctrlcnt; i++) {
441		snprintf(name, sizeof(name), rstr_chipcD, i);
442		if ((otp_val = getvar(NULL, name)) == NULL)
443			continue;
444
445		val = (uint32)bcm_strtoul(otp_val, NULL, 0);
446		W_REG(osh, PMUREG(sih, chipcontrol_addr), i);
447		W_REG(osh, PMUREG(sih, chipcontrol_data), val);
448	}
449}
450
451/** Setup switcher voltage */
452void
453BCMATTACHFN(si_pmu_set_switcher_voltage)(si_t *sih, osl_t *osh,
454                                         uint8 bb_voltage, uint8 rf_voltage)
455{
456	ASSERT(sih->cccaps & CC_CAP_PMU);
457
458	W_REG(osh, PMUREG(sih, regcontrol_addr), 0x01);
459	W_REG(osh, PMUREG(sih, regcontrol_data), (uint32)(bb_voltage & 0x1f) << 22);
460
461	W_REG(osh, PMUREG(sih, regcontrol_addr), 0x00);
462	W_REG(osh, PMUREG(sih, regcontrol_data), (uint32)(rf_voltage & 0x1f) << 14);
463}
464
465/**
466 * A chip contains one or more LDOs (Low Drop Out regulators). During chip bringup, it can turn out
467 * that the default (POR) voltage of a regulator is not right or optimal.
468 * This function is called only by si_pmu_swreg_init() for specific chips
469 */
470void
471BCMATTACHFN(si_pmu_set_ldo_voltage)(si_t *sih, osl_t *osh, uint8 ldo, uint8 voltage)
472{
473	uint8 sr_cntl_shift = 0, rc_shift = 0, shift = 0, mask = 0;
474	uint8 addr = 0;
475	uint8 do_reg2 = 0, rshift2 = 0, mask2 = 0, addr2 = 0;
476
477	ASSERT(sih->cccaps & CC_CAP_PMU);
478
479	switch (CHIPID(sih->chip)) {
480	case BCM4328_CHIP_ID:
481	case BCM5354_CHIP_ID:
482		switch (ldo) {
483		case SET_LDO_VOLTAGE_LDO1:
484			addr = 2;
485			sr_cntl_shift = 8;
486			rc_shift = 17;
487			mask = 0xf;
488			break;
489		case SET_LDO_VOLTAGE_LDO2:
490			addr = 3;
491			rc_shift = 1;
492			mask = 0xf;
493			break;
494		case SET_LDO_VOLTAGE_LDO3:
495			addr = 3;
496			rc_shift = 9;
497			mask = 0xf;
498			break;
499		case SET_LDO_VOLTAGE_PAREF:
500			addr = 3;
501			rc_shift = 17;
502			mask = 0x3f;
503			break;
504		default:
505			ASSERT(FALSE);
506			return;
507		}
508		break;
509	case BCM4312_CHIP_ID:
510		switch (ldo) {
511		case SET_LDO_VOLTAGE_PAREF:
512			addr = 0;
513			rc_shift = 21;
514			mask = 0x3f;
515			break;
516		default:
517			ASSERT(FALSE);
518			return;
519		}
520		break;
521	case BCM4325_CHIP_ID:
522		switch (ldo) {
523		case SET_LDO_VOLTAGE_CLDO_PWM:
524			addr = 5;
525			rc_shift = 9;
526			mask = 0xf;
527			break;
528		case SET_LDO_VOLTAGE_CLDO_BURST:
529			addr = 5;
530			rc_shift = 13;
531			mask = 0xf;
532			break;
533		case SET_LDO_VOLTAGE_CBUCK_PWM:
534			addr = 3;
535			rc_shift = 20;
536			mask = 0x1f;
537			/* Bit 116 & 119 are inverted in CLB for opt 2b */
538			if (((sih->chipst & CST4325_PMUTOP_2B_MASK) >>
539			     CST4325_PMUTOP_2B_SHIFT) == 1)
540				voltage ^= 0x9;
541			break;
542		case SET_LDO_VOLTAGE_CBUCK_BURST:
543			addr = 3;
544			rc_shift = 25;
545			mask = 0x1f;
546			/* Bit 121 & 124 are inverted in CLB for opt 2b */
547			if (((sih->chipst & CST4325_PMUTOP_2B_MASK) >>
548			     CST4325_PMUTOP_2B_SHIFT) == 1)
549				voltage ^= 0x9;
550			break;
551		case SET_LDO_VOLTAGE_LNLDO1:
552			addr = 5;
553			rc_shift = 17;
554			mask = 0x1f;
555			break;
556		case SET_LDO_VOLTAGE_LNLDO2_SEL:
557			addr = 6;
558			rc_shift = 0;
559			mask = 0x1;
560			break;
561		default:
562			ASSERT(FALSE);
563			return;
564		}
565		break;
566	case BCM4336_CHIP_ID:
567	case BCM43362_CHIP_ID:
568		switch (ldo) {
569		case SET_LDO_VOLTAGE_CLDO_PWM:
570			addr = 4;
571			rc_shift = 1;
572			mask = 0xf;
573			break;
574		case SET_LDO_VOLTAGE_CLDO_BURST:
575			addr = 4;
576			rc_shift = 5;
577			mask = 0xf;
578			break;
579		case SET_LDO_VOLTAGE_LNLDO1:
580			addr = 4;
581			rc_shift = 17;
582			mask = 0xf;
583			break;
584		case SET_LDO_VOLTAGE_CBUCK_PWM:
585			addr = 3;
586			rc_shift = 0;
587			mask = 0x1f;
588			break;
589		case SET_LDO_VOLTAGE_CBUCK_BURST:
590			addr = 3;
591			rc_shift = 5;
592			mask = 0x1f;
593			break;
594		case SET_LNLDO_PWERUP_LATCH_CTRL:
595			addr = 2;
596			rc_shift = 17;
597			mask = 0x3;
598			break;
599		default:
600			ASSERT(FALSE);
601			return;
602		}
603		break;
604	case BCM4330_CHIP_ID:
605		switch (ldo) {
606		case SET_LDO_VOLTAGE_CBUCK_PWM:
607			addr = 3;
608			rc_shift = 0;
609			mask = 0x1f;
610			break;
611		case SET_LDO_VOLTAGE_CBUCK_BURST:
612			addr = 3;
613			rc_shift = 5;
614			mask = 0x1f;
615			break;
616		default:
617			ASSERT(FALSE);
618			break;
619		}
620		break;
621	case BCM4331_CHIP_ID:
622	case BCM4360_CHIP_ID:
623	case BCM43460_CHIP_ID:
624	case BCM4352_CHIP_ID:
625	case BCM43526_CHIP_ID:
626		switch (ldo) {
627		case  SET_LDO_VOLTAGE_PAREF:
628			addr = 1;
629			rc_shift = 0;
630			mask = 0xf;
631			break;
632		default:
633			ASSERT(FALSE);
634			break;
635		}
636		break;
637	case BCM43602_CHIP_ID:
638	case BCM43462_CHIP_ID:
639		switch (ldo) {
640		case  SET_LDO_VOLTAGE_PAREF:
641			addr = 0;
642			rc_shift = 29;
643			mask = 0x7;
644			do_reg2 = 1;
645			addr2 = 1;
646			rshift2 = 3;
647			mask2 = 0x8;
648			break;
649		default:
650			ASSERT(FALSE);
651			break;
652		}
653		break;
654	case BCM4314_CHIP_ID:
655		switch (ldo) {
656		case  SET_LDO_VOLTAGE_LDO2:
657			addr = 4;
658			rc_shift = 14;
659			mask = 0x7;
660			break;
661		default:
662			ASSERT(FALSE);
663			break;
664		}
665		break;
666	case BCM43341_CHIP_ID:
667	case BCM4334_CHIP_ID:
668		switch (ldo) {
669		case SET_LDO_VOLTAGE_LDO1:
670			addr = PMU_VREG4_ADDR;
671			rc_shift = PMU_VREG4_LPLDO1_SHIFT;
672			mask = PMU_VREG4_LPLDO1_MASK;
673			break;
674		case SET_LDO_VOLTAGE_LDO2:
675			addr = PMU_VREG4_ADDR;
676			rc_shift = PMU_VREG4_LPLDO2_LVM_SHIFT;
677			mask = PMU_VREG4_LPLDO2_LVM_HVM_MASK;
678			break;
679		case SET_LDO_VOLTAGE_CLDO_PWM:
680			addr = PMU_VREG4_ADDR;
681			rc_shift = PMU_VREG4_CLDO_PWM_SHIFT;
682			mask = PMU_VREG4_CLDO_PWM_MASK;
683			break;
684		default:
685			ASSERT(FALSE);
686			break;
687		}
688		break;
689	case BCM43143_CHIP_ID:
690		switch (ldo) {
691		case SET_LDO_VOLTAGE_CBUCK_PWM:
692			addr = 0;
693			rc_shift = 5;
694			mask = 0xf;
695			break;
696		case SET_LDO_VOLTAGE_CBUCK_BURST:
697			addr = 4;
698			rc_shift = 8;
699			mask = 0xf;
700			break;
701		case SET_LDO_VOLTAGE_LNLDO1:
702			addr = 4;
703			rc_shift = 14;
704			mask = 0x7;
705			break;
706		default:
707			ASSERT(FALSE);
708			break;
709		}
710		break;
711	default:
712		ASSERT(FALSE);
713		return;
714	}
715
716	shift = sr_cntl_shift + rc_shift;
717
718	pmu_corereg(sih, SI_CC_IDX, regcontrol_addr, /* PMU VREG register */
719		~0, addr);
720	pmu_corereg(sih, SI_CC_IDX, regcontrol_data,
721		mask << shift, (voltage & mask) << shift);
722	if (do_reg2) {
723		si_pmu_regcontrol(sih, addr2, mask2 >> rshift2, (voltage & mask2) >> rshift2);
724	}
725} /* si_pmu_set_ldo_voltage */
726
727void
728si_pmu_paref_ldo_enable(si_t *sih, osl_t *osh, bool enable)
729{
730	uint ldo = 0;
731
732	ASSERT(sih->cccaps & CC_CAP_PMU);
733
734	switch (CHIPID(sih->chip)) {
735	case BCM4328_CHIP_ID:
736		ldo = RES4328_PA_REF_LDO;
737		break;
738	case BCM5354_CHIP_ID:
739		ldo = RES5354_PA_REF_LDO;
740		break;
741	case BCM4312_CHIP_ID:
742		ldo = RES4312_PA_REF_LDO;
743		break;
744	default:
745		return;
746	}
747
748	pmu_corereg(sih, SI_CC_IDX, min_res_mask,
749	           PMURES_BIT(ldo), enable ? PMURES_BIT(ldo) : 0);
750}
751
752/* d11 slow to fast clock transition time in slow clock cycles */
753#define D11SCC_SLOW2FAST_TRANSITION	2
754
755/**
756 * d11 core has a 'fastpwrup_dly' register that must be written to.
757 * This function returns d11 slow to fast clock transition time in [us] units.
758 * It does not write to the d11 core.
759 */
760uint16
761BCMINITFN(si_pmu_fast_pwrup_delay)(si_t *sih, osl_t *osh)
762{
763	uint pmudelay = PMU_MAX_TRANSITION_DLY;
764	chipcregs_t *cc;
765	uint origidx;
766	uint32 ilp;			/* ILP clock frequency in [Hz] */
767	rsc_per_chip_t *rsc;		/* chip specific resource bit positions */
768
769	ASSERT(sih->cccaps & CC_CAP_PMU);
770
771	/* Remember original core before switch to chipc */
772	origidx = si_coreidx(sih);
773	cc = si_setcoreidx(sih, SI_CC_IDX);
774	ASSERT(cc != NULL);
775
776	if (ISSIM_ENAB(sih)) {
777		pmudelay = 70;
778	} else {
779		switch (CHIPID(sih->chip)) {
780		case BCM4312_CHIP_ID:
781		case BCM4322_CHIP_ID:	case BCM43221_CHIP_ID:	case BCM43231_CHIP_ID:
782		case BCM43222_CHIP_ID:	case BCM43111_CHIP_ID:	case BCM43112_CHIP_ID:
783		case BCM43224_CHIP_ID:	case BCM43225_CHIP_ID:  case BCM43420_CHIP_ID:
784		case BCM43421_CHIP_ID:
785		case BCM43226_CHIP_ID:
786		case BCM43235_CHIP_ID:	case BCM43236_CHIP_ID:	case BCM43238_CHIP_ID:
787		case BCM43237_CHIP_ID:	case BCM43239_CHIP_ID:
788		case BCM43234_CHIP_ID:
789		case BCM4331_CHIP_ID:
790		case BCM43431_CHIP_ID:
791		case BCM43131_CHIP_ID:
792		case BCM43217_CHIP_ID:
793		case BCM43227_CHIP_ID:
794		case BCM43228_CHIP_ID:
795		case BCM43428_CHIP_ID:
796		case BCM6362_CHIP_ID:
797		case BCM4342_CHIP_ID:
798		case BCM4313_CHIP_ID:
799		case BCM43460_CHIP_ID:
800		case BCM43526_CHIP_ID:
801		case BCM4319_CHIP_ID:
802			pmudelay = 3700;
803			break;
804		case BCM4360_CHIP_ID:
805		case BCM4352_CHIP_ID:
806			if (CHIPREV(sih->chiprev) < 4) {
807				pmudelay = 1500;
808			} else {
809				pmudelay = 3000;
810			}
811			break;
812		case BCM4328_CHIP_ID:
813			pmudelay = 7000;
814			break;
815		case BCM4325_CHIP_ID:
816		case BCM4329_CHIP_ID:
817		case BCM4315_CHIP_ID:
818		case BCM4336_CHIP_ID:
819		case BCM43362_CHIP_ID:
820		case BCM4330_CHIP_ID:
821		case BCM4314_CHIP_ID:
822		case BCM43142_CHIP_ID:
823		case BCM43143_CHIP_ID:
824		case BCM43341_CHIP_ID:
825		case BCM4334_CHIP_ID:
826		case BCM4345_CHIP_ID:
827		case BCM43602_CHIP_ID:
828		case BCM43462_CHIP_ID:
829		case BCM4350_CHIP_ID:
830		case BCM4354_CHIP_ID:
831		case BCM4356_CHIP_ID:
832		case BCM43556_CHIP_ID:
833		case BCM43558_CHIP_ID:
834		case BCM43566_CHIP_ID:
835		case BCM43568_CHIP_ID:
836		case BCM43569_CHIP_ID:
837		case BCM43570_CHIP_ID:
838		case BCM4324_CHIP_ID:
839		case BCM43242_CHIP_ID:
840		case BCM43243_CHIP_ID:
841			rsc = si_pmu_get_rsc_positions(sih);
842			/* Retrieve time by reading it out of the hardware */
843			ilp = si_ilp_clock(sih);
844			pmudelay = (si_pmu_res_uptime(sih, osh, cc, rsc->ht_avail) +
845				D11SCC_SLOW2FAST_TRANSITION) * ((1000000 + ilp - 1) / ilp);
846			pmudelay = (11 * pmudelay) / 10;
847			break;
848		case BCM4335_CHIP_ID:
849			rsc = si_pmu_get_rsc_positions(sih);
850			ilp = si_ilp_clock(sih);
851			pmudelay = (si_pmu_res_uptime(sih, osh, cc, rsc->ht_avail) +
852				D11SCC_SLOW2FAST_TRANSITION) * ((1000000 + ilp - 1) / ilp);
853			/* Adding error margin of fixed 200usec instead of 10% */
854			pmudelay = pmudelay + 200;
855			break;
856
857		default:
858			break;
859		}
860	} /* if (ISSIM_ENAB(sih)) */
861
862	/* Return to original core */
863	si_setcoreidx(sih, origidx);
864
865	return (uint16)pmudelay;
866} /* si_pmu_fast_pwrup_delay */
867
868uint32
869BCMATTACHFN(si_pmu_force_ilp)(si_t *sih, osl_t *osh, bool force)
870{
871	uint32 oldpmucontrol;
872
873	ASSERT(sih->cccaps & CC_CAP_PMU);
874
875	oldpmucontrol = R_REG(osh, PMUREG(sih, pmucontrol));
876	if (force)
877		W_REG(osh, PMUREG(sih, pmucontrol), oldpmucontrol &
878			~(PCTL_HT_REQ_EN | PCTL_ALP_REQ_EN));
879	else
880		W_REG(osh, PMUREG(sih, pmucontrol), oldpmucontrol |
881			(PCTL_HT_REQ_EN | PCTL_ALP_REQ_EN));
882
883
884	return oldpmucontrol;
885}
886
887/*
888 * During chip bringup, it can turn out that the 'hard wired' PMU dependencies are not fully
889 * correct, or that up/down time values can be optimized. The following data structures and arrays
890 * deal with that.
891 */
892
893/* Setup resource up/down timers */
894typedef struct {
895	uint8 resnum;
896	uint32 updown;
897} pmu_res_updown_t;
898
899/* Change resource dependencies masks */
900typedef struct {
901	uint32 res_mask;		/* resources (chip specific) */
902	int8 action;			/* action, e.g. RES_DEPEND_SET */
903	uint32 depend_mask;		/* changes to the dependencies mask */
904	bool (*filter)(si_t *sih);	/* action is taken when filter is NULL or return TRUE */
905} pmu_res_depend_t;
906
907/* Resource dependencies mask change action */
908#define RES_DEPEND_SET		0	/* Override the dependencies mask */
909#define RES_DEPEND_ADD		1	/* Add to the  dependencies mask */
910#define RES_DEPEND_REMOVE	-1	/* Remove from the dependencies mask */
911
912static const pmu_res_updown_t BCMATTACHDATA(bcm4328a0_res_updown)[] = {
913	{ RES4328_EXT_SWITCHER_PWM, 0x0101 },
914	{ RES4328_BB_SWITCHER_PWM, 0x1f01 },
915	{ RES4328_BB_SWITCHER_BURST, 0x010f },
916	{ RES4328_BB_EXT_SWITCHER_BURST, 0x0101 },
917	{ RES4328_ILP_REQUEST, 0x0202 },
918	{ RES4328_RADIO_SWITCHER_PWM, 0x0f01 },
919	{ RES4328_RADIO_SWITCHER_BURST, 0x0f01 },
920	{ RES4328_ROM_SWITCH, 0x0101 },
921	{ RES4328_PA_REF_LDO, 0x0f01 },
922	{ RES4328_RADIO_LDO, 0x0f01 },
923	{ RES4328_AFE_LDO, 0x0f01 },
924	{ RES4328_PLL_LDO, 0x0f01 },
925	{ RES4328_BG_FILTBYP, 0x0101 },
926	{ RES4328_TX_FILTBYP, 0x0101 },
927	{ RES4328_RX_FILTBYP, 0x0101 },
928	{ RES4328_XTAL_PU, 0x0101 },
929	{ RES4328_XTAL_EN, 0xa001 },
930	{ RES4328_BB_PLL_FILTBYP, 0x0101 },
931	{ RES4328_RF_PLL_FILTBYP, 0x0101 },
932	{ RES4328_BB_PLL_PU, 0x0701 }
933};
934
935static const pmu_res_depend_t BCMATTACHDATA(bcm4328a0_res_depend)[] = {
936	/* Adjust ILP request resource not to force ext/BB switchers into burst mode */
937	{
938		PMURES_BIT(RES4328_ILP_REQUEST),
939		RES_DEPEND_SET,
940		PMURES_BIT(RES4328_EXT_SWITCHER_PWM) | PMURES_BIT(RES4328_BB_SWITCHER_PWM),
941		NULL
942	}
943};
944
945static const pmu_res_updown_t BCMATTACHDATA(bcm4325a0_res_updown_qt)[] = {
946	{ RES4325_HT_AVAIL, 0x0300 },
947	{ RES4325_BBPLL_PWRSW_PU, 0x0101 },
948	{ RES4325_RFPLL_PWRSW_PU, 0x0101 },
949	{ RES4325_ALP_AVAIL, 0x0100 },
950	{ RES4325_XTAL_PU, 0x1000 },
951	{ RES4325_LNLDO1_PU, 0x0800 },
952	{ RES4325_CLDO_CBUCK_PWM, 0x0101 },
953	{ RES4325_CBUCK_PWM, 0x0803 }
954};
955
956static const pmu_res_updown_t BCMATTACHDATA(bcm4325a0_res_updown)[] = {
957	{ RES4325_XTAL_PU, 0x1501 }
958};
959
960static const pmu_res_depend_t BCMATTACHDATA(bcm4325a0_res_depend)[] = {
961	/* Adjust OTP PU resource dependencies - remove BB BURST */
962	{
963		PMURES_BIT(RES4325_OTP_PU),
964		RES_DEPEND_REMOVE,
965		PMURES_BIT(RES4325_BUCK_BOOST_BURST),
966		NULL
967	},
968	/* Adjust ALP/HT Avail resource dependencies - bring up BB along if it is used. */
969	{
970		PMURES_BIT(RES4325_ALP_AVAIL) | PMURES_BIT(RES4325_HT_AVAIL),
971		RES_DEPEND_ADD,
972		PMURES_BIT(RES4325_BUCK_BOOST_BURST) | PMURES_BIT(RES4325_BUCK_BOOST_PWM),
973		si_pmu_res_depfltr_bb
974	},
975	/* Adjust HT Avail resource dependencies - bring up RF switches along with HT. */
976	{
977		PMURES_BIT(RES4325_HT_AVAIL),
978		RES_DEPEND_ADD,
979		PMURES_BIT(RES4325_RX_PWRSW_PU) | PMURES_BIT(RES4325_TX_PWRSW_PU) |
980		PMURES_BIT(RES4325_LOGEN_PWRSW_PU) | PMURES_BIT(RES4325_AFE_PWRSW_PU),
981		NULL
982	},
983	/* Adjust ALL resource dependencies - remove CBUCK dependencies if it is not used. */
984	{
985		PMURES_BIT(RES4325_ILP_REQUEST) | PMURES_BIT(RES4325_ABUCK_BURST) |
986		PMURES_BIT(RES4325_ABUCK_PWM) | PMURES_BIT(RES4325_LNLDO1_PU) |
987		PMURES_BIT(RES4325C1_LNLDO2_PU) | PMURES_BIT(RES4325_XTAL_PU) |
988		PMURES_BIT(RES4325_ALP_AVAIL) | PMURES_BIT(RES4325_RX_PWRSW_PU) |
989		PMURES_BIT(RES4325_TX_PWRSW_PU) | PMURES_BIT(RES4325_RFPLL_PWRSW_PU) |
990		PMURES_BIT(RES4325_LOGEN_PWRSW_PU) | PMURES_BIT(RES4325_AFE_PWRSW_PU) |
991		PMURES_BIT(RES4325_BBPLL_PWRSW_PU) | PMURES_BIT(RES4325_HT_AVAIL),
992		RES_DEPEND_REMOVE,
993		PMURES_BIT(RES4325B0_CBUCK_LPOM) | PMURES_BIT(RES4325B0_CBUCK_BURST) |
994		PMURES_BIT(RES4325B0_CBUCK_PWM),
995		si_pmu_res_depfltr_ncb
996	}
997};
998
999static const pmu_res_updown_t BCMATTACHDATA(bcm4315a0_res_updown_qt)[] = {
1000	{ RES4315_HT_AVAIL, 0x0101 },
1001	{ RES4315_XTAL_PU, 0x0100 },
1002	{ RES4315_LNLDO1_PU, 0x0100 },
1003	{ RES4315_PALDO_PU, 0x0100 },
1004	{ RES4315_CLDO_PU, 0x0100 },
1005	{ RES4315_CBUCK_PWM, 0x0100 },
1006	{ RES4315_CBUCK_BURST, 0x0100 },
1007	{ RES4315_CBUCK_LPOM, 0x0100 }
1008};
1009
1010static const pmu_res_updown_t BCMATTACHDATA(bcm4315a0_res_updown)[] = {
1011	{ RES4315_XTAL_PU, 0x2501 }
1012};
1013
1014static const pmu_res_depend_t BCMATTACHDATA(bcm4315a0_res_depend)[] = {
1015	/* Adjust OTP PU resource dependencies - not need PALDO unless write */
1016	{
1017		PMURES_BIT(RES4315_OTP_PU),
1018		RES_DEPEND_REMOVE,
1019		PMURES_BIT(RES4315_PALDO_PU),
1020		si_pmu_res_depfltr_npaldo
1021	},
1022	/* Adjust ALP/HT Avail resource dependencies - bring up PALDO along if it is used. */
1023	{
1024		PMURES_BIT(RES4315_ALP_AVAIL) | PMURES_BIT(RES4315_HT_AVAIL),
1025		RES_DEPEND_ADD,
1026		PMURES_BIT(RES4315_PALDO_PU),
1027		si_pmu_res_depfltr_paldo
1028	},
1029	/* Adjust HT Avail resource dependencies - bring up RF switches along with HT. */
1030	{
1031		PMURES_BIT(RES4315_HT_AVAIL),
1032		RES_DEPEND_ADD,
1033		PMURES_BIT(RES4315_RX_PWRSW_PU) | PMURES_BIT(RES4315_TX_PWRSW_PU) |
1034		PMURES_BIT(RES4315_LOGEN_PWRSW_PU) | PMURES_BIT(RES4315_AFE_PWRSW_PU),
1035		NULL
1036	},
1037	/* Adjust ALL resource dependencies - remove CBUCK dependencies if it is not used. */
1038	{
1039		PMURES_BIT(RES4315_CLDO_PU) | PMURES_BIT(RES4315_ILP_REQUEST) |
1040		PMURES_BIT(RES4315_LNLDO1_PU) | PMURES_BIT(RES4315_OTP_PU) |
1041		PMURES_BIT(RES4315_LNLDO2_PU) | PMURES_BIT(RES4315_XTAL_PU) |
1042		PMURES_BIT(RES4315_ALP_AVAIL) | PMURES_BIT(RES4315_RX_PWRSW_PU) |
1043		PMURES_BIT(RES4315_TX_PWRSW_PU) | PMURES_BIT(RES4315_RFPLL_PWRSW_PU) |
1044		PMURES_BIT(RES4315_LOGEN_PWRSW_PU) | PMURES_BIT(RES4315_AFE_PWRSW_PU) |
1045		PMURES_BIT(RES4315_BBPLL_PWRSW_PU) | PMURES_BIT(RES4315_HT_AVAIL),
1046		RES_DEPEND_REMOVE,
1047		PMURES_BIT(RES4315_CBUCK_LPOM) | PMURES_BIT(RES4315_CBUCK_BURST) |
1048		PMURES_BIT(RES4315_CBUCK_PWM),
1049		si_pmu_res_depfltr_ncb
1050	}
1051};
1052
1053static const pmu_res_updown_t BCMATTACHDATA(bcm4329_res_updown)[] = {
1054	{ RES4329_XTAL_PU, 0x3201 },
1055	{ RES4329_PALDO_PU, 0x3501 }
1056};
1057
1058static const pmu_res_depend_t BCMATTACHDATA(bcm4329_res_depend)[] = {
1059	/* Make lnldo1 independent of CBUCK_PWM and CBUCK_BURST */
1060	{
1061		PMURES_BIT(RES4329_LNLDO1_PU),
1062		RES_DEPEND_REMOVE,
1063		PMURES_BIT(RES4329_CBUCK_PWM) | PMURES_BIT(RES4329_CBUCK_BURST),
1064		NULL
1065	},
1066	{
1067		PMURES_BIT(RES4329_CBUCK_BURST),
1068		RES_DEPEND_ADD,
1069		PMURES_BIT(RES4329_CBUCK_LPOM) | PMURES_BIT(RES4329_PALDO_PU),
1070		NULL
1071	},
1072	{
1073		PMURES_BIT(RES4329_BBPLL_PWRSW_PU),
1074		RES_DEPEND_ADD,
1075		PMURES_BIT(RES4329_RX_PWRSW_PU) | PMURES_BIT(RES4329_TX_PWRSW_PU) |
1076		PMURES_BIT(RES4329_LOGEN_PWRSW_PU) | PMURES_BIT(RES4329_AFE_PWRSW_PU),
1077		NULL
1078	},
1079	/* Adjust HT Avail resource dependencies */
1080	{
1081		PMURES_BIT(RES4329_HT_AVAIL),
1082		RES_DEPEND_ADD,
1083		PMURES_BIT(RES4329_PALDO_PU) |
1084		PMURES_BIT(RES4329_RX_PWRSW_PU) | PMURES_BIT(RES4329_TX_PWRSW_PU) |
1085		PMURES_BIT(RES4329_LOGEN_PWRSW_PU) | PMURES_BIT(RES4329_AFE_PWRSW_PU),
1086		NULL
1087	}
1088};
1089
1090static const pmu_res_updown_t BCMATTACHDATA(bcm4319a0_res_updown_qt)[] = {
1091	{ RES4319_HT_AVAIL, 0x0101 },
1092	{ RES4319_XTAL_PU, 0x0100 },
1093	{ RES4319_LNLDO1_PU, 0x0100 },
1094	{ RES4319_PALDO_PU, 0x0100 },
1095	{ RES4319_CLDO_PU, 0x0100 },
1096	{ RES4319_CBUCK_PWM, 0x0100 },
1097	{ RES4319_CBUCK_BURST, 0x0100 },
1098	{ RES4319_CBUCK_LPOM, 0x0100 }
1099};
1100
1101static const pmu_res_updown_t BCMATTACHDATA(bcm4319a0_res_updown)[] = {
1102	{ RES4319_XTAL_PU, 0x3f01 }
1103};
1104
1105static const pmu_res_depend_t BCMATTACHDATA(bcm4319a0_res_depend)[] = {
1106	/* Adjust OTP PU resource dependencies - not need PALDO unless write */
1107	{
1108		PMURES_BIT(RES4319_OTP_PU),
1109		RES_DEPEND_REMOVE,
1110		PMURES_BIT(RES4319_PALDO_PU),
1111		si_pmu_res_depfltr_npaldo
1112	},
1113	/* Adjust HT Avail resource dependencies - bring up PALDO along if it is used. */
1114	{
1115		PMURES_BIT(RES4319_HT_AVAIL),
1116		RES_DEPEND_ADD,
1117		PMURES_BIT(RES4319_PALDO_PU),
1118		si_pmu_res_depfltr_paldo
1119	},
1120	/* Adjust HT Avail resource dependencies - bring up RF switches along with HT. */
1121	{
1122		PMURES_BIT(RES4319_HT_AVAIL),
1123		RES_DEPEND_ADD,
1124		PMURES_BIT(RES4319_RX_PWRSW_PU) | PMURES_BIT(RES4319_TX_PWRSW_PU) |
1125		PMURES_BIT(RES4319_RFPLL_PWRSW_PU) |
1126		PMURES_BIT(RES4319_LOGEN_PWRSW_PU) | PMURES_BIT(RES4319_AFE_PWRSW_PU),
1127		NULL
1128	}
1129};
1130
1131static const pmu_res_updown_t BCMATTACHDATA(bcm4336a0_res_updown_qt)[] = {
1132	{ RES4336_HT_AVAIL, 0x0101 },
1133	{ RES4336_XTAL_PU, 0x0100 },
1134	{ RES4336_CLDO_PU, 0x0100 },
1135	{ RES4336_CBUCK_PWM, 0x0100 },
1136	{ RES4336_CBUCK_BURST, 0x0100 },
1137	{ RES4336_CBUCK_LPOM, 0x0100 }
1138};
1139
1140static const pmu_res_updown_t BCMATTACHDATA(bcm4336a0_res_updown)[] = {
1141	{ RES4336_HT_AVAIL, 0x0D01}
1142};
1143
1144static const pmu_res_depend_t BCMATTACHDATA(bcm4336a0_res_depend)[] = {
1145	/* Just a dummy entry for now */
1146	{
1147		PMURES_BIT(RES4336_RSVD),
1148		RES_DEPEND_ADD,
1149		0,
1150		NULL
1151	}
1152};
1153
1154static const pmu_res_updown_t BCMATTACHDATA(bcm4330a0_res_updown_qt)[] = {
1155	{ RES4330_HT_AVAIL, 0x0101 },
1156	{ RES4330_XTAL_PU, 0x0100 },
1157	{ RES4330_CLDO_PU, 0x0100 },
1158	{ RES4330_CBUCK_PWM, 0x0100 },
1159	{ RES4330_CBUCK_BURST, 0x0100 },
1160	{ RES4330_CBUCK_LPOM, 0x0100 }
1161};
1162
1163static const pmu_res_updown_t BCMATTACHDATA(bcm4330a0_res_updown)[] = {
1164	{ RES4330_HT_AVAIL, 0x0e02}
1165};
1166
1167static const pmu_res_depend_t BCMATTACHDATA(bcm4330a0_res_depend)[] = {
1168	/* Just a dummy entry for now */
1169	{
1170		PMURES_BIT(RES4330_HT_AVAIL),
1171		RES_DEPEND_ADD,
1172		0,
1173		NULL
1174	}
1175};
1176
1177static const pmu_res_updown_t BCMATTACHDATA(bcm4334a0_res_updown_qt)[] = {{0, 0}};
1178static const pmu_res_updown_t BCMATTACHDATA(bcm4334a0_res_updown)[] = {{0, 0}};
1179static const pmu_res_depend_t BCMATTACHDATA(bcm4334a0_res_depend)[] = {{0, 0, 0, NULL}};
1180
1181static const pmu_res_updown_t BCMATTACHDATA(bcm4324a0_res_updown_qt)[] = {
1182	{RES4324_SR_SAVE_RESTORE, 0x00320032}
1183};
1184
1185static const pmu_res_updown_t BCMATTACHDATA(bcm4324a0_res_updown)[] = {
1186	{RES4324_SR_SAVE_RESTORE, 0x00020002},
1187#ifdef BCMUSBDEV_ENABLED
1188	{RES4324_XTAL_PU, 0x007d0001}
1189#else
1190	{RES4324_XTAL_PU, 0x00120001}
1191#endif
1192};
1193
1194static const pmu_res_updown_t BCMATTACHDATA(bcm4324b0_res_updown)[] = {
1195	{RES4324_SR_SAVE_RESTORE, 0x00050005},
1196	{RES4324_XTAL_PU, 0x00120001}
1197};
1198
1199static const pmu_res_updown_t BCMATTACHDATA(bcm4335_res_updown)[] = {
1200	{RES4335_XTAL_PU, 0x00260002},
1201	{RES4335_ALP_AVAIL, 0x00020005},
1202	{RES4335_WL_CORE_RDY, 0x00020005},
1203	{RES4335_LQ_START, 0x00060002},
1204	{RES4335_SR_CLK_START, 0x00060002}
1205};
1206static const pmu_res_depend_t BCMATTACHDATA(bcm4335b0_res_depend)[] = {
1207	{
1208		PMURES_BIT(RES4335_ALP_AVAIL) |
1209		PMURES_BIT(RES4335_HT_START) |
1210		PMURES_BIT(RES4335_HT_AVAIL) |
1211		PMURES_BIT(RES4335_MACPHY_CLKAVAIL) |
1212		PMURES_BIT(RES4335_RADIO_PU),
1213		RES_DEPEND_ADD,
1214		PMURES_BIT(RES4335_OTP_PU) | PMURES_BIT(RES4335_LDO3P3_PU),
1215		NULL
1216	},
1217	{
1218		PMURES_BIT(RES4335_MINI_PMU),
1219		RES_DEPEND_ADD,
1220		PMURES_BIT(RES4335_XTAL_PU),
1221		NULL
1222	}
1223};
1224
1225static const pmu_res_updown_t BCMATTACHDATA(bcm4350_res_updown)[] = {
1226#if defined(SAVERESTORE) && !defined(SAVERESTORE_DISABLED)
1227	{RES4350_SR_SAVE_RESTORE,	0x00190019},
1228#endif /* SAVERESTORE && !SAVERESTORE_DISABLED */
1229
1230	{RES4350_XTAL_PU,		0x00210001},
1231	{RES4350_LQ_AVAIL,		0x00010001},
1232	{RES4350_LQ_START,		0x00010001},
1233	{RES4350_WL_CORE_RDY,		0x00010001},
1234	{RES4350_ALP_AVAIL,		0x00010001},
1235	{RES4350_SR_CLK_STABLE,		0x00010001},
1236	{RES4350_SR_SLEEP,		0x00010001},
1237	{RES4350_HT_AVAIL,		0x00010001},
1238
1239#ifndef SRFAST
1240	{RES4350_SR_PHY_PWRSW,		0x00120002},
1241	{RES4350_SR_VDDM_PWRSW,		0x00120002},
1242	{RES4350_SR_SUBCORE_PWRSW,	0x00120002},
1243#else /* SRFAST */
1244	{RES4350_PMU_BG_PU,		0x00010001},
1245	{RES4350_PMU_SLEEP,		0x00100004},
1246	{RES4350_CBUCK_LPOM_PU,		0x00010001},
1247	{RES4350_CBUCK_PFM_PU,		0x00010001},
1248	{RES4350_COLD_START_WAIT,	0x00010001},
1249	{RES4350_LNLDO_PU,		0x00100001},
1250	{RES4350_XTALLDO_PU,		0x00050001},
1251	{RES4350_LDO3P3_PU,		0x00100001},
1252	{RES4350_OTP_PU,		0x00010001},
1253	{RES4350_SR_CLK_START,		0x00020001},
1254	{RES4350_PERST_OVR,		0x00010001},
1255	{RES4350_WL_CORE_RDY,		0x00010001},
1256	{RES4350_ALP_AVAIL,		0x00010001},
1257	{RES4350_MINI_PMU,		0x00010001},
1258	{RES4350_RADIO_PU,		0x00010001},
1259	{RES4350_SR_CLK_STABLE,		0x00010001},
1260	{RES4350_SR_SLEEP,		0x00010001},
1261	{RES4350_HT_START,		0x00050001},
1262	{RES4350_HT_AVAIL,		0x00010001},
1263	{RES4350_MACPHY_CLKAVAIL,	0x00010001},
1264#endif /* SRFAST */
1265};
1266
1267static const pmu_res_updown_t BCMATTACHDATA(bcm43602_res_updown)[] = {
1268	{RES43602_SR_SAVE_RESTORE,	0x00240024},
1269	{RES43602_XTAL_PU,		0x00280002},
1270};
1271
1272static const pmu_res_depend_t BCMATTACHDATA(bcm4350_res_depend)[] = {
1273#ifdef SRFAST
1274	{
1275		PMURES_BIT(RES4350_LDO3P3_PU),
1276		RES_DEPEND_REMOVE,
1277		PMURES_BIT(RES4350_PMU_SLEEP),
1278		NULL
1279	},
1280	{
1281		PMURES_BIT(RES4350_COLD_START_WAIT) |
1282		PMURES_BIT(RES4350_XTALLDO_PU) |
1283		PMURES_BIT(RES4350_XTAL_PU) |
1284		PMURES_BIT(RES4350_SR_CLK_START) |
1285		PMURES_BIT(RES4350_WL_CORE_RDY) |
1286		PMURES_BIT(RES4350_ALP_AVAIL) |
1287		PMURES_BIT(RES4350_SR_CLK_STABLE) |
1288		PMURES_BIT(RES4350_SR_SAVE_RESTORE) |
1289		PMURES_BIT(RES4350_SR_PHY_PWRSW) |
1290		PMURES_BIT(RES4350_SR_VDDM_PWRSW) |
1291		PMURES_BIT(RES4350_SR_SUBCORE_PWRSW) |
1292		PMURES_BIT(RES4350_SR_SLEEP) |
1293		PMURES_BIT(RES4350_HT_START) |
1294		PMURES_BIT(RES4350_HT_AVAIL),
1295		RES_DEPEND_ADD,
1296		PMURES_BIT(RES4350_LDO3P3_PU),
1297		NULL
1298	},
1299	{
1300		PMURES_BIT(RES4350_LNLDO_PU),
1301		RES_DEPEND_REMOVE,
1302		PMURES_BIT(RES4350_PMU_SLEEP) |
1303		PMURES_BIT(RES4350_CBUCK_LPOM_PU) |
1304		PMURES_BIT(RES4350_CBUCK_PFM_PU),
1305		NULL
1306	},
1307	{
1308		PMURES_BIT(RES4350_ALP_AVAIL) |
1309		PMURES_BIT(RES4350_RADIO_PU) |
1310		PMURES_BIT(RES4350_HT_START) |
1311		PMURES_BIT(RES4350_HT_AVAIL) |
1312		PMURES_BIT(RES4350_MACPHY_CLKAVAIL),
1313		RES_DEPEND_REMOVE,
1314		PMURES_BIT(RES4350_LQ_AVAIL) |
1315		PMURES_BIT(RES4350_LQ_START),
1316		NULL
1317	},
1318#else
1319	{0, 0, 0, NULL}
1320#endif /* SRFAST */
1321};
1322
1323#ifndef BCM_BOOTLOADER
1324static const pmu_res_depend_t BCMATTACHDATA(bcm4350_res_pciewar)[] = {
1325	{
1326		PMURES_BIT(RES4350_LQ_AVAIL),
1327		RES_DEPEND_ADD,
1328		PMURES_BIT(RES4350_LDO3P3_PU) |
1329		PMURES_BIT(RES4350_OTP_PU),
1330		NULL
1331	},
1332	{
1333		PMURES_BIT(RES4350_LQ_START),
1334		RES_DEPEND_ADD,
1335		PMURES_BIT(RES4350_LDO3P3_PU) |
1336		PMURES_BIT(RES4350_OTP_PU),
1337		NULL
1338	},
1339	{
1340		PMURES_BIT(RES4350_PERST_OVR),
1341		RES_DEPEND_SET,
1342		PMURES_BIT(RES4350_LPLDO_PU) |
1343		PMURES_BIT(RES4350_PMU_BG_PU) |
1344		PMURES_BIT(RES4350_PMU_SLEEP) |
1345		PMURES_BIT(RES4350_CBUCK_LPOM_PU) |
1346		PMURES_BIT(RES4350_CBUCK_PFM_PU) |
1347		PMURES_BIT(RES4350_COLD_START_WAIT) |
1348		PMURES_BIT(RES4350_LNLDO_PU) |
1349		PMURES_BIT(RES4350_XTALLDO_PU) |
1350		PMURES_BIT(RES4350_XTAL_PU) |
1351		PMURES_BIT(RES4350_SR_CLK_STABLE) |
1352		PMURES_BIT(RES4350_SR_SAVE_RESTORE) |
1353		PMURES_BIT(RES4350_SR_PHY_PWRSW) |
1354		PMURES_BIT(RES4350_SR_VDDM_PWRSW) |
1355		PMURES_BIT(RES4350_SR_SUBCORE_PWRSW) |
1356		PMURES_BIT(RES4350_SR_SLEEP),
1357		NULL
1358	},
1359	{
1360		PMURES_BIT(RES4350_WL_CORE_RDY),
1361		RES_DEPEND_ADD,
1362		PMURES_BIT(RES4350_PERST_OVR) |
1363		PMURES_BIT(RES4350_LDO3P3_PU) |
1364		PMURES_BIT(RES4350_OTP_PU),
1365		NULL
1366	},
1367	{
1368		PMURES_BIT(RES4350_ILP_REQ),
1369		RES_DEPEND_ADD,
1370		PMURES_BIT(RES4350_LDO3P3_PU) |
1371		PMURES_BIT(RES4350_OTP_PU),
1372		NULL
1373	},
1374	{
1375		PMURES_BIT(RES4350_ALP_AVAIL),
1376		RES_DEPEND_ADD,
1377		PMURES_BIT(RES4350_PERST_OVR) |
1378		PMURES_BIT(RES4350_LDO3P3_PU) |
1379		PMURES_BIT(RES4350_OTP_PU),
1380		NULL
1381	},
1382	{
1383		PMURES_BIT(RES4350_RADIO_PU),
1384		RES_DEPEND_ADD,
1385		PMURES_BIT(RES4350_PERST_OVR) |
1386		PMURES_BIT(RES4350_LDO3P3_PU) |
1387		PMURES_BIT(RES4350_OTP_PU),
1388		NULL
1389	},
1390	{
1391		PMURES_BIT(RES4350_SR_CLK_STABLE),
1392		RES_DEPEND_ADD,
1393		PMURES_BIT(RES4350_LDO3P3_PU) |
1394		PMURES_BIT(RES4350_OTP_PU),
1395		NULL
1396	},
1397	{
1398		PMURES_BIT(RES4350_SR_SAVE_RESTORE),
1399		RES_DEPEND_ADD,
1400		PMURES_BIT(RES4350_LDO3P3_PU) |
1401		PMURES_BIT(RES4350_OTP_PU),
1402		NULL
1403	},
1404	{
1405		PMURES_BIT(RES4350_SR_SUBCORE_PWRSW),
1406		RES_DEPEND_ADD,
1407		PMURES_BIT(RES4350_LDO3P3_PU) |
1408		PMURES_BIT(RES4350_OTP_PU),
1409		NULL
1410	},
1411	{
1412		PMURES_BIT(RES4350_SR_SLEEP),
1413		RES_DEPEND_ADD,
1414		PMURES_BIT(RES4350_LDO3P3_PU) |
1415		PMURES_BIT(RES4350_OTP_PU),
1416		NULL
1417	},
1418	{
1419		PMURES_BIT(RES4350_HT_START),
1420		RES_DEPEND_ADD,
1421		PMURES_BIT(RES4350_PERST_OVR) |
1422		PMURES_BIT(RES4350_LDO3P3_PU) |
1423		PMURES_BIT(RES4350_OTP_PU),
1424		NULL
1425	},
1426	{
1427		PMURES_BIT(RES4350_HT_AVAIL),
1428		RES_DEPEND_ADD,
1429		PMURES_BIT(RES4350_PERST_OVR) |
1430		PMURES_BIT(RES4350_LDO3P3_PU) |
1431		PMURES_BIT(RES4350_OTP_PU),
1432		NULL
1433	},
1434	{
1435		PMURES_BIT(RES4350_MACPHY_CLKAVAIL),
1436		RES_DEPEND_ADD,
1437		PMURES_BIT(RES4350_PERST_OVR) |
1438		PMURES_BIT(RES4350_LDO3P3_PU) |
1439		PMURES_BIT(RES4350_OTP_PU),
1440		NULL
1441	}
1442};
1443#endif /* !BCM_BOOTLOADER */
1444
1445static const pmu_res_updown_t BCMATTACHDATA(bcm4360_res_updown)[] = {
1446	{RES4360_BBPLLPWRSW_PU,		0x00200001}
1447};
1448
1449static const pmu_res_updown_t BCMATTACHDATA(bcm4345_res_updown)[] = {
1450#if defined(SAVERESTORE) && !defined(SAVERESTORE_DISABLED)
1451#ifndef SRFAST
1452	{RES4345_SR_SAVE_RESTORE,       0x00170017},
1453#else
1454	{RES4345_SR_SAVE_RESTORE,       0x000A000A},
1455	{RES4345_RSVD_7,                0x000c0001},
1456	{RES4345_PMU_BG_PU,		0x00010001},
1457	{RES4345_PMU_SLEEP,		0x000A0004},
1458	{RES4345_CBUCK_LPOM_PU,		0x00010001},
1459	{RES4345_CBUCK_PFM_PU,		0x00010001},
1460	{RES4345_COLD_START_WAIT,	0x00010001},
1461	{RES4345_LNLDO_PU,		0x000A0001},
1462	{RES4345_XTALLDO_PU,		0x00050001},
1463	{RES4345_XTAL_PU,		0x002C0001},
1464	{RES4345_LDO3P3_PU,		0x000A0001},
1465	{RES4345_OTP_PU,		0x00010001},
1466	{RES4345_SR_CLK_START,		0x00020001},
1467	{RES4345_PERST_OVR,		0x00010001},
1468	{RES4345_WL_CORE_RDY,		0x00010001},
1469	{RES4345_ALP_AVAIL,		0x00010001},
1470	{RES4345_MINI_PMU,		0x00010001},
1471	{RES4345_RADIO_PU,		0x00010001},
1472	{RES4345_SR_CLK_STABLE,		0x00010001},
1473	{RES4345_SR_SLEEP,		0x00010001},
1474	{RES4345_HT_START,		0x00050001},
1475	{RES4345_HT_AVAIL,		0x00010001},
1476	{RES4345_MACPHY_CLKAVAIL,	0x00010001},
1477#endif /* SRFAST */
1478#endif /* SAVERESTORE && !SAVERESTORE_DISABLED */
1479
1480	{RES4345_XTAL_PU,		0x600002},	/* 3 ms uptime for XTAL_PU */
1481};
1482
1483static const pmu_res_depend_t BCMATTACHDATA(bcm4345_res_depend)[] = {
1484#ifdef SRFAST
1485	{
1486		PMURES_BIT(RES4345_LDO3P3_PU),
1487		RES_DEPEND_REMOVE,
1488		PMURES_BIT(RES4345_PMU_SLEEP),
1489		NULL
1490	},
1491	{
1492		PMURES_BIT(RES4345_SR_CLK_START) |
1493		PMURES_BIT(RES4345_WL_CORE_RDY) |
1494		PMURES_BIT(RES4345_ALP_AVAIL) |
1495		PMURES_BIT(RES4345_SR_CLK_STABLE) |
1496		PMURES_BIT(RES4345_SR_SAVE_RESTORE) |
1497		PMURES_BIT(RES4345_SR_PHY_PWRSW) |
1498		PMURES_BIT(RES4345_SR_VDDM_PWRSW) |
1499		PMURES_BIT(RES4345_SR_SUBCORE_PWRSW) |
1500		PMURES_BIT(RES4345_SR_SLEEP) |
1501		PMURES_BIT(RES4345_RADIO_PU) |
1502		PMURES_BIT(RES4345_MACPHY_CLKAVAIL) |
1503		PMURES_BIT(RES4345_CBUCK_PFM_PU) |
1504		PMURES_BIT(RES4345_MINI_PMU) |
1505		PMURES_BIT(RES4345_HT_START) |
1506		PMURES_BIT(RES4345_HT_AVAIL),
1507		RES_DEPEND_ADD,
1508		PMURES_BIT(RES4345_RSVD_7),
1509		NULL
1510	},
1511	{
1512		PMURES_BIT(RES4345_SR_CLK_START) |
1513		PMURES_BIT(RES4345_WL_CORE_RDY) |
1514		PMURES_BIT(RES4345_SR_CLK_STABLE) |
1515		PMURES_BIT(RES4345_SR_SAVE_RESTORE) |
1516		PMURES_BIT(RES4345_SR_SLEEP) |
1517		PMURES_BIT(RES4345_RADIO_PU) |
1518		PMURES_BIT(RES4345_CBUCK_PFM_PU) |
1519		PMURES_BIT(RES4345_MINI_PMU),
1520		RES_DEPEND_ADD,
1521		PMURES_BIT(RES4345_XTAL_PU),
1522		NULL
1523	},
1524	{
1525		PMURES_BIT(RES4345_SR_CLK_START) |
1526		PMURES_BIT(RES4345_WL_CORE_RDY) |
1527		PMURES_BIT(RES4345_SR_CLK_STABLE) |
1528		PMURES_BIT(RES4345_SR_SAVE_RESTORE) |
1529		PMURES_BIT(RES4345_SR_SLEEP) |
1530		PMURES_BIT(RES4345_SR_PHY_PWRSW) |
1531		PMURES_BIT(RES4345_SR_VDDM_PWRSW) |
1532		PMURES_BIT(RES4345_SR_SUBCORE_PWRSW) |
1533		PMURES_BIT(RES4345_RADIO_PU) |
1534		PMURES_BIT(RES4345_CBUCK_PFM_PU) |
1535		PMURES_BIT(RES4345_MINI_PMU),
1536		RES_DEPEND_ADD,
1537		PMURES_BIT(RES4345_XTALLDO_PU),
1538		NULL
1539	},
1540	{
1541		PMURES_BIT(RES4345_COLD_START_WAIT) |
1542		PMURES_BIT(RES4345_XTALLDO_PU) |
1543		PMURES_BIT(RES4345_XTAL_PU) |
1544		PMURES_BIT(RES4345_SR_CLK_START) |
1545		PMURES_BIT(RES4345_SR_CLK_STABLE) |
1546		PMURES_BIT(RES4345_SR_PHY_PWRSW) |
1547		PMURES_BIT(RES4345_SR_VDDM_PWRSW) |
1548		PMURES_BIT(RES4345_SR_SUBCORE_PWRSW),
1549		RES_DEPEND_REMOVE,
1550		PMURES_BIT(RES4345_CBUCK_PFM_PU),
1551		NULL
1552	},
1553	{
1554		PMURES_BIT(RES4345_RSVD_7),
1555		RES_DEPEND_ADD,
1556		PMURES_BIT(RES4345_XTALLDO_PU) |
1557		PMURES_BIT(RES4345_COLD_START_WAIT) |
1558		PMURES_BIT(RES4345_LNLDO_PU) |
1559		PMURES_BIT(RES4345_LDO3P3_PU) |
1560		PMURES_BIT(RES4345_PMU_SLEEP) |
1561		PMURES_BIT(RES4345_CBUCK_LPOM_PU) |
1562		PMURES_BIT(RES4345_PMU_BG_PU) |
1563		PMURES_BIT(RES4345_LPLDO_PU),
1564		NULL
1565	},
1566	{
1567		PMURES_BIT(RES4345_COLD_START_WAIT) |
1568		PMURES_BIT(RES4345_XTALLDO_PU) |
1569		PMURES_BIT(RES4345_XTAL_PU) |
1570		PMURES_BIT(RES4345_SR_CLK_START) |
1571		PMURES_BIT(RES4345_WL_CORE_RDY) |
1572		PMURES_BIT(RES4345_ALP_AVAIL) |
1573		PMURES_BIT(RES4345_SR_CLK_STABLE) |
1574		PMURES_BIT(RES4345_SR_SAVE_RESTORE) |
1575		PMURES_BIT(RES4345_SR_PHY_PWRSW) |
1576		PMURES_BIT(RES4345_SR_VDDM_PWRSW) |
1577		PMURES_BIT(RES4345_SR_SUBCORE_PWRSW) |
1578		PMURES_BIT(RES4345_SR_SLEEP) |
1579		PMURES_BIT(RES4345_HT_START) |
1580		PMURES_BIT(RES4345_HT_AVAIL),
1581		RES_DEPEND_ADD,
1582		PMURES_BIT(RES4345_LDO3P3_PU),
1583		NULL
1584	},
1585	{
1586		PMURES_BIT(RES4345_LNLDO_PU),
1587		RES_DEPEND_REMOVE,
1588		PMURES_BIT(RES4345_PMU_SLEEP) |
1589		PMURES_BIT(RES4345_CBUCK_LPOM_PU) |
1590		PMURES_BIT(RES4345_CBUCK_PFM_PU),
1591		NULL
1592	},
1593	{
1594		PMURES_BIT(RES4345_ALP_AVAIL) |
1595		PMURES_BIT(RES4345_RADIO_PU) |
1596		PMURES_BIT(RES4345_HT_START) |
1597		PMURES_BIT(RES4345_HT_AVAIL) |
1598		PMURES_BIT(RES4345_MACPHY_CLKAVAIL),
1599		RES_DEPEND_REMOVE,
1600		PMURES_BIT(RES4345_LQ_AVAIL) |
1601		PMURES_BIT(RES4345_LQ_START),
1602		NULL
1603	},
1604#ifdef BCMPCIEDEV_ENABLED
1605	{
1606		PMURES_BIT(RES4345_PERST_OVR),
1607		RES_DEPEND_ADD,
1608		PMURES_BIT(RES4345_XTALLDO_PU) |
1609		PMURES_BIT(RES4345_XTAL_PU) |
1610		PMURES_BIT(RES4345_SR_CLK_STABLE) |
1611		PMURES_BIT(RES4345_SR_SAVE_RESTORE) |
1612		PMURES_BIT(RES4345_SR_PHY_PWRSW) |
1613		PMURES_BIT(RES4345_SR_VDDM_PWRSW) |
1614		PMURES_BIT(RES4345_SR_SUBCORE_PWRSW) |
1615		PMURES_BIT(RES4345_SR_SLEEP),
1616		NULL
1617	},
1618	{
1619		PMURES_BIT(RES4345_PERST_OVR),
1620		RES_DEPEND_REMOVE,
1621		PMURES_BIT(RES4345_XTALLDO_PU) |
1622		PMURES_BIT(RES4345_SR_CLK_START) |
1623		PMURES_BIT(RES4345_LDO3P3_PU) |
1624		PMURES_BIT(RES4345_OTP_PU),
1625		NULL
1626	},
1627	{
1628		PMURES_BIT(RES4345_ALP_AVAIL),
1629		RES_DEPEND_ADD,
1630		PMURES_BIT(RES4345_PERST_OVR),
1631		NULL
1632	},
1633	{
1634		PMURES_BIT(RES4345_RADIO_PU),
1635		RES_DEPEND_ADD,
1636		PMURES_BIT(RES4345_PERST_OVR),
1637		NULL
1638	},
1639	{
1640		PMURES_BIT(RES4345_HT_START),
1641		RES_DEPEND_ADD,
1642		PMURES_BIT(RES4345_PERST_OVR),
1643		NULL
1644	},
1645	{
1646		PMURES_BIT(RES4345_HT_AVAIL),
1647		RES_DEPEND_ADD,
1648		PMURES_BIT(RES4345_PERST_OVR),
1649		NULL
1650	},
1651	{
1652		PMURES_BIT(RES4345_MACPHY_CLKAVAIL),
1653		RES_DEPEND_ADD,
1654		PMURES_BIT(RES4345_PERST_OVR),
1655		NULL
1656	},
1657#endif /* BCMPCIEDEV_ENABLED */
1658#else
1659#ifdef BCMPCIEDEV_ENABLED
1660	{
1661		PMURES_BIT(RES4345_PERST_OVR),
1662		RES_DEPEND_ADD,
1663		PMURES_BIT(RES4345_XTALLDO_PU) |
1664		PMURES_BIT(RES4345_XTAL_PU) |
1665		PMURES_BIT(RES4345_SR_CLK_STABLE) |
1666		PMURES_BIT(RES4345_SR_SAVE_RESTORE) |
1667		PMURES_BIT(RES4345_SR_PHY_PWRSW) |
1668		PMURES_BIT(RES4345_SR_VDDM_PWRSW) |
1669		PMURES_BIT(RES4345_SR_SUBCORE_PWRSW) |
1670		PMURES_BIT(RES4345_SR_SLEEP),
1671		NULL
1672	},
1673	{
1674		PMURES_BIT(RES4345_PERST_OVR),
1675		RES_DEPEND_REMOVE,
1676		PMURES_BIT(RES4345_XTALLDO_PU) |
1677		PMURES_BIT(RES4345_SR_CLK_START) |
1678		PMURES_BIT(RES4345_LDO3P3_PU) |
1679		PMURES_BIT(RES4345_OTP_PU),
1680		NULL
1681	},
1682	{
1683		PMURES_BIT(RES4345_WL_CORE_RDY),
1684		RES_DEPEND_ADD,
1685		PMURES_BIT(RES4345_PERST_OVR),
1686		NULL
1687	},
1688	{
1689		PMURES_BIT(RES4345_ALP_AVAIL),
1690		RES_DEPEND_ADD,
1691		PMURES_BIT(RES4345_PERST_OVR),
1692		NULL
1693	},
1694	{
1695		PMURES_BIT(RES4345_RADIO_PU),
1696		RES_DEPEND_ADD,
1697		PMURES_BIT(RES4345_PERST_OVR),
1698		NULL
1699	},
1700	{
1701		PMURES_BIT(RES4345_HT_START),
1702		RES_DEPEND_ADD,
1703		PMURES_BIT(RES4345_PERST_OVR),
1704		NULL
1705	},
1706	{
1707		PMURES_BIT(RES4345_HT_AVAIL),
1708		RES_DEPEND_ADD,
1709		PMURES_BIT(RES4345_PERST_OVR),
1710		NULL
1711	},
1712	{
1713		PMURES_BIT(RES4345_MACPHY_CLKAVAIL),
1714		RES_DEPEND_ADD,
1715		PMURES_BIT(RES4345_PERST_OVR),
1716		NULL
1717	},
1718#else
1719	{0, 0, 0, NULL}
1720#endif /* BCMPCIEDEV_ENABLED */
1721#endif /* SRFAST */
1722};
1723
1724static const pmu_res_depend_t BCMATTACHDATA(bcm43602_res_depend)[] = {
1725	{
1726		PMURES_BIT(RES43602_SR_SUBCORE_PWRSW) | PMURES_BIT(RES43602_SR_CLK_STABLE) |
1727		PMURES_BIT(RES43602_SR_SAVE_RESTORE)  | PMURES_BIT(RES43602_SR_SLEEP) |
1728		PMURES_BIT(RES43602_LQ_START) | PMURES_BIT(RES43602_LQ_AVAIL) |
1729		PMURES_BIT(RES43602_WL_CORE_RDY) | PMURES_BIT(RES43602_ILP_REQ) |
1730		PMURES_BIT(RES43602_ALP_AVAIL) | PMURES_BIT(RES43602_RFLDO_PU) |
1731		PMURES_BIT(RES43602_HT_START) | PMURES_BIT(RES43602_HT_AVAIL) |
1732		PMURES_BIT(RES43602_MACPHY_CLKAVAIL),
1733		RES_DEPEND_ADD,
1734		PMURES_BIT(RES43602_SERDES_PU),
1735		NULL
1736	}
1737};
1738
1739#ifndef BCM_BOOTLOADER
1740static const pmu_res_depend_t BCMATTACHDATA(bcm43602_res_pciewar)[] = {
1741	{
1742		PMURES_BIT(RES43602_PERST_OVR),
1743		RES_DEPEND_SET,
1744		PMURES_BIT(RES43602_REGULATOR) |
1745		PMURES_BIT(RES43602_PMU_SLEEP) |
1746		PMURES_BIT(RES43602_XTALLDO_PU) |
1747		PMURES_BIT(RES43602_XTAL_PU) |
1748		PMURES_BIT(RES43602_RADIO_PU),
1749		NULL
1750	},
1751	{
1752		PMURES_BIT(RES43602_WL_CORE_RDY),
1753		RES_DEPEND_ADD,
1754		PMURES_BIT(RES43602_PERST_OVR),
1755		NULL
1756	},
1757	{
1758		PMURES_BIT(RES43602_LQ_START),
1759		RES_DEPEND_ADD,
1760		PMURES_BIT(RES43602_PERST_OVR),
1761		NULL
1762	},
1763	{
1764		PMURES_BIT(RES43602_LQ_AVAIL),
1765		RES_DEPEND_ADD,
1766		PMURES_BIT(RES43602_PERST_OVR),
1767		NULL
1768	},
1769	{
1770		PMURES_BIT(RES43602_ALP_AVAIL),
1771		RES_DEPEND_ADD,
1772		PMURES_BIT(RES43602_PERST_OVR),
1773		NULL
1774	},
1775	{
1776		PMURES_BIT(RES43602_HT_START),
1777		RES_DEPEND_ADD,
1778		PMURES_BIT(RES43602_PERST_OVR),
1779		NULL
1780	},
1781	{
1782		PMURES_BIT(RES43602_HT_AVAIL),
1783		RES_DEPEND_ADD,
1784		PMURES_BIT(RES43602_PERST_OVR),
1785		NULL
1786	},
1787	{
1788		PMURES_BIT(RES43602_MACPHY_CLKAVAIL),
1789		RES_DEPEND_ADD,
1790		PMURES_BIT(RES43602_PERST_OVR),
1791		NULL
1792	}
1793};
1794#endif /* !BCM_BOOTLOADER */
1795
1796static const pmu_res_updown_t BCMATTACHDATA(bcm4360B1_res_updown)[] = {
1797	/* Need to change elements here, should get default values for this - 4360B1 */
1798	{RES4360_XTAL_PU,		0x00430002}, /* Changed for 4360B1 */
1799};
1800
1801static const pmu_res_depend_t BCMATTACHDATA(bcm4324a0_res_depend)[] = {
1802	{
1803		PMURES_BIT(RES4324_SR_PHY_PWRSW) | PMURES_BIT(RES4324_SR_PHY_PIC),
1804		RES_DEPEND_SET,
1805		0x00000000,
1806		NULL
1807	},
1808	{
1809		PMURES_BIT(RES4324_WL_CORE_READY) | PMURES_BIT(RES4324_ILP_REQ) |
1810		PMURES_BIT(RES4324_ALP_AVAIL) | PMURES_BIT(RES4324_RADIO_PU) |
1811		PMURES_BIT(RES4324_SR_CLK_STABLE) | PMURES_BIT(RES4324_SR_SAVE_RESTORE) |
1812		PMURES_BIT(RES4324_SR_SUBCORE_PIC) | PMURES_BIT(RES4324_SR_MEM_PM0) |
1813		PMURES_BIT(RES4324_HT_AVAIL) | PMURES_BIT(RES4324_MACPHY_CLKAVAIL),
1814		RES_DEPEND_ADD,
1815		PMURES_BIT(RES4324_LPLDO_PU) | PMURES_BIT(RES4324_RESET_PULLDN_DIS) |
1816		PMURES_BIT(RES4324_PMU_BG_PU) | PMURES_BIT(RES4324_HSIC_LDO_PU) |
1817		PMURES_BIT(RES4324_CBUCK_LPOM_PU) | PMURES_BIT(RES4324_CBUCK_PFM_PU) |
1818		PMURES_BIT(RES4324_CLDO_PU) | PMURES_BIT(RES4324_LPLDO2_LVM),
1819		NULL
1820	},
1821	{
1822		PMURES_BIT(RES4324_WL_CORE_READY) | PMURES_BIT(RES4324_ILP_REQ) |
1823		PMURES_BIT(RES4324_ALP_AVAIL) | PMURES_BIT(RES4324_RADIO_PU) |
1824		PMURES_BIT(RES4324_HT_AVAIL) | PMURES_BIT(RES4324_MACPHY_CLKAVAIL),
1825		RES_DEPEND_ADD,
1826		PMURES_BIT(RES4324_SR_CLK_STABLE) | PMURES_BIT(RES4324_SR_SAVE_RESTORE) |
1827		PMURES_BIT(RES4324_SR_SUBCORE_PWRSW) | PMURES_BIT(RES4324_SR_SUBCORE_PIC),
1828		NULL
1829	},
1830	{
1831		PMURES_BIT(RES4324_WL_CORE_READY) | PMURES_BIT(RES4324_ILP_REQ) |
1832		PMURES_BIT(RES4324_ALP_AVAIL) | PMURES_BIT(RES4324_RADIO_PU) |
1833		PMURES_BIT(RES4324_SR_CLK_STABLE) | PMURES_BIT(RES4324_SR_SAVE_RESTORE) |
1834		PMURES_BIT(RES4324_HT_AVAIL) | PMURES_BIT(RES4324_MACPHY_CLKAVAIL),
1835		RES_DEPEND_ADD,
1836		PMURES_BIT(RES4324_LNLDO1_PU) | PMURES_BIT(RES4324_LNLDO2_PU) |
1837		PMURES_BIT(RES4324_BBPLL_PU) | PMURES_BIT(RES4324_LQ_AVAIL),
1838		NULL
1839	},
1840	{
1841		PMURES_BIT(RES4324_WL_CORE_READY) | PMURES_BIT(RES4324_ILP_REQ) |
1842		PMURES_BIT(RES4324_ALP_AVAIL) | PMURES_BIT(RES4324_RADIO_PU) |
1843		PMURES_BIT(RES4324_SR_CLK_STABLE) | PMURES_BIT(RES4324_SR_SAVE_RESTORE) |
1844		PMURES_BIT(RES4324_HT_AVAIL) | PMURES_BIT(RES4324_MACPHY_CLKAVAIL),
1845		RES_DEPEND_ADD,
1846		PMURES_BIT(RES4324_SR_MEM_PM0),
1847		NULL
1848	},
1849	{
1850		PMURES_BIT(RES4324_SR_CLK_STABLE) | PMURES_BIT(RES4324_SR_SAVE_RESTORE) |
1851		PMURES_BIT(RES4324_SR_MEM_PM0),
1852		RES_DEPEND_ADD,
1853		PMURES_BIT(RES4324_SR_SUBCORE_PWRSW) | PMURES_BIT(RES4324_SR_SUBCORE_PIC),
1854		NULL
1855	},
1856	{
1857		PMURES_BIT(RES4324_ILP_REQ) | PMURES_BIT(RES4324_ALP_AVAIL) |
1858		PMURES_BIT(RES4324_RADIO_PU) | PMURES_BIT(RES4324_HT_AVAIL) |
1859		PMURES_BIT(RES4324_MACPHY_CLKAVAIL),
1860		RES_DEPEND_ADD,
1861		PMURES_BIT(RES4324_WL_CORE_READY),
1862		NULL
1863	},
1864	{
1865		PMURES_BIT(RES4324_ALP_AVAIL) | PMURES_BIT(RES4324_RADIO_PU) |
1866		PMURES_BIT(RES4324_HT_AVAIL) | PMURES_BIT(RES4324_MACPHY_CLKAVAIL),
1867		RES_DEPEND_ADD,
1868		PMURES_BIT(RES4324_LQ_AVAIL),
1869		NULL
1870	},
1871	{
1872		PMURES_BIT(RES4324_SR_SAVE_RESTORE),
1873		RES_DEPEND_ADD,
1874		PMURES_BIT(RES4324_SR_CLK_STABLE),
1875		NULL
1876	},
1877	{
1878		PMURES_BIT(RES4324_SR_SUBCORE_PIC),
1879		RES_DEPEND_ADD,
1880		PMURES_BIT(RES4324_SR_SUBCORE_PWRSW),
1881		NULL
1882	},
1883	{
1884		PMURES_BIT(RES4324_RADIO_PU) | PMURES_BIT(RES4324_HT_AVAIL) |
1885		PMURES_BIT(RES4324_MACPHY_CLKAVAIL),
1886		RES_DEPEND_ADD,
1887		PMURES_BIT(RES4324_ALP_AVAIL),
1888		NULL
1889	},
1890	{
1891		PMURES_BIT(RES4324_RADIO_PU) | PMURES_BIT(RES4324_MACPHY_CLKAVAIL),
1892		RES_DEPEND_ADD,
1893		PMURES_BIT(RES4324_LDO3P3_PU) | PMURES_BIT(RES4324_PALDO_PU),
1894		NULL
1895	},
1896	{
1897		PMURES_BIT(RES4324_MACPHY_CLKAVAIL),
1898		RES_DEPEND_ADD,
1899		PMURES_BIT(RES4324_RADIO_PU) | PMURES_BIT(RES4324_HT_AVAIL),
1900		NULL
1901	},
1902	{
1903		PMURES_BIT(RES4324_ILP_REQ) | PMURES_BIT(RES4324_ALP_AVAIL) |
1904		PMURES_BIT(RES4324_RADIO_PU) | PMURES_BIT(RES4324_HT_AVAIL) |
1905		PMURES_BIT(RES4324_MACPHY_CLKAVAIL),
1906		RES_DEPEND_REMOVE,
1907		PMURES_BIT(RES4324_SR_PHY_PWRSW) | PMURES_BIT(RES4324_SR_PHY_PIC),
1908		NULL
1909	},
1910	{
1911		PMURES_BIT(RES4324_SR_CLK_STABLE) | PMURES_BIT(RES4324_SR_SAVE_RESTORE) |
1912		PMURES_BIT(RES4324_SR_SUBCORE_PIC) | PMURES_BIT(RES4324_SR_MEM_PM0),
1913		RES_DEPEND_REMOVE,
1914		PMURES_BIT(RES4324_WL_CORE_READY),
1915		NULL
1916	},
1917	{
1918		PMURES_BIT(RES4324_SR_SUBCORE_PIC) | PMURES_BIT(RES4324_SR_MEM_PM0),
1919		RES_DEPEND_REMOVE,
1920		PMURES_BIT(RES4324_LNLDO1_PU) | PMURES_BIT(RES4324_LNLDO2_PU) |
1921		PMURES_BIT(RES4324_BBPLL_PU) | PMURES_BIT(RES4324_LQ_AVAIL),
1922		NULL
1923	}
1924};
1925
1926static const pmu_res_updown_t BCMATTACHDATA(bcm4334b0_res_updown_qt)[] = {{0, 0}};
1927static const pmu_res_updown_t BCMATTACHDATA(bcm4334b0_res_updown)[] = {
1928	/* In ILP clock (32768 Hz) at 30.5us per tick */
1929#ifndef SRFAST
1930	/* SAVERESTORE */
1931	{RES4334_LOGIC_RET, 0x00050005},
1932	{RES4334_MACPHY_RET, 0x000c000c},
1933	/* 0x00160001 - corresponds to around 700 uSeconds uptime */
1934	{RES4334_XTAL_PU, 0x00160001}
1935#else
1936	/* Fast SR wakeup */
1937
1938	/* Make Cbuck LPOM shorter */
1939	{RES4334_CBUCK_LPOM_PU, 0xc000c},
1940	{RES4334_CBUCK_PFM_PU, 0x010001},
1941
1942	/* XTAL up timer */
1943	{RES4334_XTAL_PU, 0x130001},
1944
1945	/* Reduce 1 tick for below resources */
1946	{RES4334_PMU_BG_PU, 0x00060001},
1947
1948	/* Reduce 2 tick for below resources */
1949	{RES4334_CLDO_PU, 0x00010001},
1950	{RES4334_LNLDO_PU, 0x00010001},
1951	{RES4334_LDO3P3_PU, 0x00020001},
1952	{RES4334_WL_PMU_PU, 0x00010001},
1953	{RES4334_HT_AVAIL, 0x00010001},
1954
1955	/* Make all these resources to have 1 tick ILP clock only */
1956	{RES4334_HSIC_LDO_PU, 0x10001},
1957	{RES4334_LPLDO2_LVM, 0},
1958	{RES4334_WL_PWRSW_PU, 0},
1959	{RES4334_LQ_AVAIL, 0},
1960	{RES4334_MEM_SLEEP, 0},
1961	{RES4334_WL_CORE_READY, 0},
1962	{RES4334_ALP_AVAIL, 0},
1963
1964	{RES4334_OTP_PU, 0x10001},
1965	{RES4334_MISC_PWRSW_PU, 0},
1966	{RES4334_SYNTH_PWRSW_PU, 0},
1967	{RES4334_RX_PWRSW_PU, 0},
1968	{RES4334_RADIO_PU, 0},
1969	{RES4334_VCO_LDO_PU, 0},
1970	{RES4334_AFE_LDO_PU, 0},
1971	{RES4334_RX_LDO_PU, 0},
1972	{RES4334_TX_LDO_PU, 0},
1973	{RES4334_MACPHY_CLK_AVAIL, 0},
1974
1975	/* Reduce up down timer of Retention Mode */
1976	{RES4334_LOGIC_RET, 0x40004},
1977	{RES4334_MACPHY_RET, 0x70007},
1978#endif /* SRFAST */
1979
1980};
1981
1982static const pmu_res_depend_t BCMATTACHDATA(bcm4334b0_res_depend)[] = {
1983#ifndef BCM_BOOTLOADER
1984	{
1985		PMURES_BIT(RES4334_MACPHY_CLK_AVAIL),
1986		RES_DEPEND_ADD,
1987		PMURES_BIT(RES4334_LDO3P3_PU),
1988		NULL
1989	},
1990#ifdef SRFAST
1991	{
1992		PMURES_BIT(RES4334_ALP_AVAIL),
1993		RES_DEPEND_ADD,
1994		PMURES_BIT(RES4334_OTP_PU) | PMURES_BIT(RES4334_LDO3P3_PU),
1995		NULL
1996	}
1997#endif /* SRFAST */
1998#else
1999	{0, 0}
2000#endif /* BCM_BOOTLOADER */
2001};
2002
2003static const pmu_res_depend_t BCMATTACHDATA(bcm4334b0_res_hsic_depend)[] = {
2004#ifndef BCM_BOOTLOADER
2005	{
2006		PMURES_BIT(RES4334_MACPHY_CLK_AVAIL),
2007		RES_DEPEND_ADD,
2008		PMURES_BIT(RES4334_LDO3P3_PU),
2009		NULL
2010	},
2011	{
2012		PMURES_BIT(RES4334_LPLDO2_LVM),
2013		RES_DEPEND_REMOVE,
2014		(1 << RES4334_CBUCK_PFM_PU),
2015		NULL
2016	},
2017	{
2018		PMURES_BIT(RES4334_LNLDO_PU),
2019		RES_DEPEND_REMOVE,
2020		(1 << RES4334_CBUCK_PFM_PU),
2021		NULL
2022	},
2023	{
2024		PMURES_BIT(RES4334_OTP_PU),
2025		RES_DEPEND_REMOVE,
2026		(1 << RES4334_CBUCK_PFM_PU),
2027		NULL
2028	},
2029	{
2030		PMURES_BIT(RES4334_XTAL_PU),
2031		RES_DEPEND_REMOVE,
2032		(1 << RES4334_CBUCK_PFM_PU),
2033		NULL
2034	},
2035	{
2036		PMURES_BIT(RES4334_WL_PWRSW_PU),
2037		RES_DEPEND_REMOVE,
2038		(1 << RES4334_CBUCK_PFM_PU),
2039		NULL
2040	},
2041	{
2042		PMURES_BIT(RES4334_LQ_AVAIL),
2043		RES_DEPEND_REMOVE,
2044		(1 << RES4334_CBUCK_PFM_PU),
2045		NULL
2046	},
2047	{
2048		PMURES_BIT(RES4334_LOGIC_RET),
2049		RES_DEPEND_REMOVE,
2050		(1 << RES4334_CBUCK_PFM_PU),
2051		NULL
2052	},
2053	{
2054		PMURES_BIT(RES4334_MEM_SLEEP),
2055		RES_DEPEND_REMOVE,
2056		(1 << RES4334_CBUCK_PFM_PU),
2057		NULL
2058	},
2059	{
2060		PMURES_BIT(RES4334_MACPHY_RET),
2061		RES_DEPEND_REMOVE,
2062		(1 << RES4334_CBUCK_PFM_PU),
2063		NULL
2064	},
2065	{
2066		PMURES_BIT(RES4334_WL_CORE_READY),
2067		RES_DEPEND_REMOVE,
2068		(1 << RES4334_CBUCK_PFM_PU),
2069		NULL
2070	},
2071	{
2072		PMURES_BIT(RES4334_ILP_REQ),
2073		RES_DEPEND_REMOVE,
2074		(1 << RES4334_CBUCK_PFM_PU),
2075		NULL
2076	},
2077
2078#ifdef SRFAST
2079	/* Fast SR wakeup */
2080
2081	/* Make LNLDO and XTAL PU depends on WL_CORE_READY */
2082	{
2083		PMURES_BIT(RES4334_WL_CORE_READY),
2084		RES_DEPEND_ADD,
2085		(1 << RES4334_XTAL_PU) | (1 << RES4334_LNLDO_PU),
2086		NULL
2087	},
2088
2089	/* remove dependency on CBuck PFM */
2090	{
2091		PMURES_BIT(RES4334_LPLDO2_LVM),
2092		RES_DEPEND_SET,
2093		0x5f,
2094		NULL
2095	},
2096
2097	/* Make LNLDO depends on CBuck LPOM */
2098	{
2099		PMURES_BIT(RES4334_LNLDO_PU),
2100		RES_DEPEND_SET,
2101		0x1f,
2102		NULL
2103	},
2104
2105	/* Remove LPLDO2_LVM from WL power switch PU */
2106	{
2107		PMURES_BIT(RES4334_WL_PWRSW_PU),
2108		RES_DEPEND_REMOVE,
2109		(1 << RES4334_LPLDO2_LVM),
2110		NULL
2111	},
2112
2113	/* Remove rsrc 19 (RES4334_ALP_AVAIL) from all radio resource dependency(20 to 28) */
2114	{
2115		PMURES_BIT(RES4334_MISC_PWRSW_PU),
2116		RES_DEPEND_REMOVE,
2117		(1 << RES4334_ALP_AVAIL),
2118		NULL
2119	},
2120	{
2121		PMURES_BIT(RES4334_SYNTH_PWRSW_PU),
2122		RES_DEPEND_REMOVE,
2123		(1 << RES4334_ALP_AVAIL),
2124		NULL
2125	},
2126	{
2127		PMURES_BIT(RES4334_RX_PWRSW_PU),
2128		RES_DEPEND_REMOVE,
2129		(1 << RES4334_ALP_AVAIL),
2130		NULL
2131	},
2132	{
2133		PMURES_BIT(RES4334_RADIO_PU),
2134		RES_DEPEND_REMOVE,
2135		(1 << RES4334_ALP_AVAIL),
2136		NULL
2137	},
2138	{
2139		PMURES_BIT(RES4334_WL_PMU_PU),
2140		RES_DEPEND_REMOVE,
2141		(1 << RES4334_ALP_AVAIL),
2142		NULL
2143	},
2144	{
2145		PMURES_BIT(RES4334_VCO_LDO_PU),
2146		RES_DEPEND_REMOVE,
2147		(1 << RES4334_ALP_AVAIL),
2148		NULL
2149	},
2150	{
2151		PMURES_BIT(RES4334_AFE_LDO_PU),
2152		RES_DEPEND_REMOVE,
2153		(1 << RES4334_ALP_AVAIL),
2154		NULL
2155	},
2156	{
2157		PMURES_BIT(RES4334_RX_LDO_PU),
2158		RES_DEPEND_REMOVE,
2159		(1 << RES4334_ALP_AVAIL),
2160		NULL
2161	},
2162	{
2163		PMURES_BIT(RES4334_TX_LDO_PU),
2164		RES_DEPEND_REMOVE,
2165		(1 << RES4334_ALP_AVAIL),
2166		NULL
2167	},
2168	{
2169		PMURES_BIT(RES4334_CBUCK_PFM_PU),
2170		RES_DEPEND_ADD,
2171		(1 << RES4334_XTAL_PU),
2172		NULL
2173	},
2174	{
2175		PMURES_BIT(RES4334_ALP_AVAIL),
2176		RES_DEPEND_ADD,
2177		PMURES_BIT(RES4334_OTP_PU) | PMURES_BIT(RES4334_LDO3P3_PU),
2178		NULL
2179	}
2180#endif /* SRFAST */
2181#else
2182	{0, 0}
2183#endif /* BCM_BOOTLOADER */
2184};
2185
2186/* Filter '_depfltr_' functions used by the arrays above */
2187
2188/* TRUE if the power topology uses the buck boost to provide 3.3V to VDDIO_RF and WLAN PA */
2189static bool
2190BCMATTACHFN(si_pmu_res_depfltr_bb)(si_t *sih)
2191{
2192	return (sih->boardflags & BFL_BUCKBOOST) != 0;
2193}
2194
2195/* TRUE if the power topology doesn't use the cbuck. Key on chiprev also if the chip is BCM4325. */
2196static bool
2197BCMATTACHFN(si_pmu_res_depfltr_ncb)(si_t *sih)
2198{
2199	if (CHIPID(sih->chip) == BCM4325_CHIP_ID)
2200		return (CHIPREV(sih->chiprev) >= 2) && ((sih->boardflags & BFL_NOCBUCK) != 0);
2201	return ((sih->boardflags & BFL_NOCBUCK) != 0);
2202}
2203
2204/* TRUE if the power topology uses the PALDO */
2205static bool
2206BCMATTACHFN(si_pmu_res_depfltr_paldo)(si_t *sih)
2207{
2208	return (sih->boardflags & BFL_PALDO) != 0;
2209}
2210
2211/* TRUE if the power topology doesn't use the PALDO */
2212static bool
2213BCMATTACHFN(si_pmu_res_depfltr_npaldo)(si_t *sih)
2214{
2215	return (sih->boardflags & BFL_PALDO) == 0;
2216}
2217
2218#define BCM94325_BBVDDIOSD_BOARDS(sih) (sih->boardtype == BCM94325DEVBU_BOARD || \
2219					sih->boardtype == BCM94325BGABU_BOARD)
2220
2221/**
2222 * Determines min/max rsrc masks. Normally hardware contains these masks, and software reads the
2223 * masks from hardware. Note that masks are sometimes dependent on chip straps.
2224 */
2225static void
2226si_pmu_res_masks(si_t *sih, uint32 *pmin, uint32 *pmax)
2227{
2228	uint32 min_mask = 0, max_mask = 0;
2229	uint rsrcs;
2230	si_info_t * sii = SI_INFO(sih);
2231
2232	/* # resources */
2233	rsrcs = (sih->pmucaps & PCAP_RC_MASK) >> PCAP_RC_SHIFT;
2234
2235	/* determine min/max rsrc masks */
2236	switch (CHIPID(sih->chip)) {
2237	case BCM4328_CHIP_ID:
2238		/* Down to ILP request */
2239		min_mask = PMURES_BIT(RES4328_EXT_SWITCHER_PWM) |
2240		        PMURES_BIT(RES4328_BB_SWITCHER_PWM) |
2241		        PMURES_BIT(RES4328_XTAL_EN);
2242		/* Allow (but don't require) PLL to turn on */
2243		max_mask = 0xfffff;
2244		break;
2245	case BCM5354_CHIP_ID:
2246		/* Allow (but don't require) PLL to turn on */
2247		max_mask = 0xfffff;
2248		break;
2249	case BCM4325_CHIP_ID:
2250		ASSERT(CHIPREV(sih->chiprev) >= 2);
2251		/* Minimum rsrcs to work in sleep mode */
2252		if (!(sih->boardflags & BFL_NOCBUCK))
2253			min_mask |= PMURES_BIT(RES4325B0_CBUCK_LPOM);
2254		if (((sih->chipst & CST4325_PMUTOP_2B_MASK) >>
2255		     CST4325_PMUTOP_2B_SHIFT) == 1)
2256			min_mask |= PMURES_BIT(RES4325B0_CLDO_PU);
2257		if (!si_is_otp_disabled(sih))
2258			min_mask |= PMURES_BIT(RES4325_OTP_PU);
2259		/* Leave buck boost on in burst mode for certain boards */
2260		if ((sih->boardflags & BFL_BUCKBOOST) && (BCM94325_BBVDDIOSD_BOARDS(sih)))
2261			min_mask |= PMURES_BIT(RES4325_BUCK_BOOST_BURST);
2262		/* Allow all resources to be turned on upon requests */
2263		max_mask = ~(~0 << rsrcs);
2264		break;
2265	case BCM4312_CHIP_ID:
2266		/* default min_mask = 0x80000cbb is wrong */
2267		min_mask = 0xcbb;
2268		/*
2269		 * max_mask = 0x7fff;
2270		 * pmu_res_updown_table_sz = 0;
2271		 * pmu_res_depend_table_sz = 0;
2272		 */
2273		break;
2274	case BCM4322_CHIP_ID:
2275	case BCM43221_CHIP_ID:	case BCM43231_CHIP_ID:
2276	case BCM4342_CHIP_ID:
2277		if (CHIPREV(sih->chiprev) < 2) {
2278			/* request ALP(can skip for A1) */
2279			min_mask = PMURES_BIT(RES4322_RF_LDO) |
2280			        PMURES_BIT(RES4322_XTAL_PU) |
2281				PMURES_BIT(RES4322_ALP_AVAIL);
2282			if (BUSTYPE(sih->bustype) == SI_BUS) {
2283				min_mask += PMURES_BIT(RES4322_SI_PLL_ON) |
2284					PMURES_BIT(RES4322_HT_SI_AVAIL) |
2285					PMURES_BIT(RES4322_PHY_PLL_ON) |
2286					PMURES_BIT(RES4322_OTP_PU) |
2287					PMURES_BIT(RES4322_HT_PHY_AVAIL);
2288				max_mask = 0x1ff;
2289			}
2290		}
2291		break;
2292	case BCM43222_CHIP_ID:	case BCM43111_CHIP_ID:	case BCM43112_CHIP_ID:
2293	case BCM43224_CHIP_ID:	case BCM43225_CHIP_ID:	case BCM43421_CHIP_ID:
2294	case BCM43226_CHIP_ID:  case BCM43420_CHIP_ID:
2295	case BCM43235_CHIP_ID:	case BCM43236_CHIP_ID:	case BCM43238_CHIP_ID:
2296	case BCM43237_CHIP_ID:
2297	case BCM43234_CHIP_ID:
2298	case BCM4331_CHIP_ID:
2299	case BCM43431_CHIP_ID:
2300	case BCM6362_CHIP_ID:
2301
2302	case BCM4360_CHIP_ID:
2303	case BCM4352_CHIP_ID:
2304		if (CHIPREV(sih->chiprev) >= 0x4) {
2305			min_mask = 0x103;
2306		}
2307		/* Continue - Don't break */
2308	case BCM43460_CHIP_ID:
2309	case BCM43526_CHIP_ID:
2310		if (CHIPREV(sih->chiprev) >= 0x3) {
2311			int cst_ht = CST4360_RSRC_INIT_MODE(sih->chipst) & 0x1;
2312			if (cst_ht == 0)
2313				max_mask = 0x1ff;
2314		}
2315		break;
2316
2317	case BCM43602_CHIP_ID:
2318	case BCM43462_CHIP_ID:
2319		/* as a bare minimum, have ALP clock running */
2320		min_mask = PMURES_BIT(RES43602_LPLDO_PU)  | PMURES_BIT(RES43602_REGULATOR)      |
2321			PMURES_BIT(RES43602_PMU_SLEEP)    | PMURES_BIT(RES43602_XTALLDO_PU)     |
2322			PMURES_BIT(RES43602_SERDES_PU)    | PMURES_BIT(RES43602_BBPLL_PWRSW_PU) |
2323			PMURES_BIT(RES43602_SR_CLK_START) | PMURES_BIT(RES43602_SR_PHY_PWRSW)   |
2324			PMURES_BIT(RES43602_SR_SUBCORE_PWRSW) | PMURES_BIT(RES43602_XTAL_PU)    |
2325			PMURES_BIT(RES43602_PERST_OVR)    | PMURES_BIT(RES43602_SR_CLK_STABLE)  |
2326			PMURES_BIT(RES43602_SR_SAVE_RESTORE) | PMURES_BIT(RES43602_SR_SLEEP)    |
2327			PMURES_BIT(RES43602_LQ_START)     | PMURES_BIT(RES43602_LQ_AVAIL)       |
2328			PMURES_BIT(RES43602_WL_CORE_RDY)  |
2329			PMURES_BIT(RES43602_ALP_AVAIL);
2330		max_mask = (1<<3) | min_mask          | PMURES_BIT(RES43602_RADIO_PU)        |
2331			PMURES_BIT(RES43602_RFLDO_PU) | PMURES_BIT(RES43602_HT_START)        |
2332			PMURES_BIT(RES43602_HT_AVAIL) | PMURES_BIT(RES43602_MACPHY_CLKAVAIL);
2333
2334#if defined(SAVERESTORE)
2335		/* min_mask is updated after SR code is downloaded to txfifo */
2336		if (SR_ENAB() && sr_isenab(sih)) {
2337			min_mask = PMURES_BIT(RES43602_LPLDO_PU);
2338		}
2339#endif /* SAVERESTORE */
2340		break;
2341
2342	case BCM43143_CHIP_ID:
2343		max_mask = PMURES_BIT(RES43143_EXT_SWITCHER_PWM) | PMURES_BIT(RES43143_XTAL_PU) |
2344			PMURES_BIT(RES43143_ILP_REQUEST) | PMURES_BIT(RES43143_ALP_AVAIL) |
2345			PMURES_BIT(RES43143_WL_CORE_READY) | PMURES_BIT(RES43143_BBPLL_PWRSW_PU) |
2346			PMURES_BIT(RES43143_HT_AVAIL) | PMURES_BIT(RES43143_RADIO_PU) |
2347			PMURES_BIT(RES43143_MACPHY_CLK_AVAIL) | PMURES_BIT(RES43143_OTP_PU) |
2348			PMURES_BIT(RES43143_LQ_AVAIL);
2349		break;
2350
2351	case BCM4329_CHIP_ID:
2352
2353		/* Down to save the power. */
2354		if (CHIPREV(sih->chiprev) >= 0x2) {
2355			min_mask = PMURES_BIT(RES4329_CBUCK_LPOM) |
2356				PMURES_BIT(RES4329_LNLDO1_PU) | PMURES_BIT(RES4329_CLDO_PU);
2357		} else {
2358			min_mask = PMURES_BIT(RES4329_CBUCK_LPOM) | PMURES_BIT(RES4329_CLDO_PU);
2359		}
2360		if (!si_is_otp_disabled(sih))
2361			min_mask |= PMURES_BIT(RES4329_OTP_PU);
2362		/* Allow (but don't require) PLL to turn on */
2363		max_mask = 0x3ff63e;
2364
2365		break;
2366	case BCM4315_CHIP_ID:
2367		/* We only need a few resources to be kept on all the time */
2368		if (!(sih->boardflags & BFL_NOCBUCK))
2369			min_mask = PMURES_BIT(RES4315_CBUCK_LPOM);
2370		min_mask |= PMURES_BIT(RES4315_CLDO_PU);
2371		/* Allow everything else to be turned on upon requests */
2372		max_mask = ~(~0 << rsrcs);
2373		break;
2374	case BCM4319_CHIP_ID:
2375#ifdef	CONFIG_XIP
2376		/* Initialize to ResInitMode2 for bootloader */
2377		min_mask = PMURES_BIT(RES4319_CBUCK_LPOM) |
2378			PMURES_BIT(RES4319_CBUCK_BURST) |
2379			PMURES_BIT(RES4319_CBUCK_PWM) |
2380			PMURES_BIT(RES4319_CLDO_PU) |
2381			PMURES_BIT(RES4319_PALDO_PU) |
2382			PMURES_BIT(RES4319_LNLDO1_PU) |
2383			PMURES_BIT(RES4319_OTP_PU) |
2384			PMURES_BIT(RES4319_XTAL_PU) |
2385			PMURES_BIT(RES4319_ALP_AVAIL) |
2386			PMURES_BIT(RES4319_RFPLL_PWRSW_PU);
2387#else
2388		/* We only need a few resources to be kept on all the time */
2389		min_mask = PMURES_BIT(RES4319_CBUCK_LPOM) |
2390			PMURES_BIT(RES4319_CLDO_PU);
2391#endif	/* CONFIG_XIP */
2392
2393		/* Allow everything else to be turned on upon requests */
2394		max_mask = ~(~0 << rsrcs);
2395		break;
2396	case BCM4336_CHIP_ID:
2397	case BCM43362_CHIP_ID:
2398		/* Down to save the power. */
2399		min_mask = PMURES_BIT(RES4336_CBUCK_LPOM) | PMURES_BIT(RES4336_CLDO_PU) |
2400			PMURES_BIT(RES4336_LDO3P3_PU) | PMURES_BIT(RES4336_OTP_PU) |
2401			PMURES_BIT(RES4336_DIS_INT_RESET_PD);
2402		/* Allow (but don't require) PLL to turn on */
2403		max_mask = 0x1ffffff;
2404		break;
2405
2406	case BCM4330_CHIP_ID:
2407		/* Down to save the power. */
2408		min_mask = PMURES_BIT(RES4330_CBUCK_LPOM) | PMURES_BIT(RES4330_CLDO_PU) |
2409			PMURES_BIT(RES4330_DIS_INT_RESET_PD) | PMURES_BIT(RES4330_LDO3P3_PU) |
2410			PMURES_BIT(RES4330_OTP_PU);
2411		/* Allow (but don't require) PLL to turn on */
2412		max_mask = 0xfffffff;
2413		break;
2414
2415	case BCM4313_CHIP_ID:
2416		min_mask = PMURES_BIT(RES4313_BB_PU_RSRC) |
2417			PMURES_BIT(RES4313_XTAL_PU_RSRC) |
2418			PMURES_BIT(RES4313_ALP_AVAIL_RSRC) |
2419			PMURES_BIT(RES4313_SYNTH_PWRSW_RSRC) |
2420			PMURES_BIT(RES4313_BB_PLL_PWRSW_RSRC);
2421		max_mask = 0xffff;
2422		break;
2423
2424	case BCM43239_CHIP_ID:
2425	case BCM4324_CHIP_ID:
2426		/* Read the min_res_mask register. Set the mask to 0 as we need to only read. */
2427		min_mask = pmu_corereg(sih, SI_CC_IDX, min_res_mask, 0, 0);
2428		/* Set the bits for all resources in the max mask except for the SR Engine */
2429		max_mask = 0x7FFFFFFF;
2430		break;
2431	case BCM4335_CHIP_ID:
2432		/* Read the min_res_mask register. Set the mask to 0 as we need to only read. */
2433		min_mask = pmu_corereg(sih, SI_CC_IDX, min_res_mask, 0, 0);
2434		/* For 4335, min res mask is set to 1 after disabling power islanding */
2435		/* Write a non-zero value in chipcontrol reg 3 */
2436
2437#ifndef BCMPCIEDEV_ENABLED
2438		/* shouldnt enable SR feature for pcie full dongle. */
2439		si_pmu_chipcontrol(sih, 3, 0x1, 0x1);
2440#endif
2441		/* Set the bits for all resources in the max mask except for the SR Engine */
2442		max_mask = 0x7FFFFFFF;
2443		break;
2444
2445	case BCM4345_CHIP_ID:
2446		/* use chip default min resource mask */
2447		min_mask = PMURES_BIT(RES4345_LPLDO_PU) |
2448			PMURES_BIT(RES4345_PMU_BG_PU) |
2449			PMURES_BIT(RES4345_PMU_SLEEP) |
2450			PMURES_BIT(RES4345_CBUCK_LPOM_PU) |
2451			PMURES_BIT(RES4345_CBUCK_PFM_PU) |
2452			PMURES_BIT(RES4345_COLD_START_WAIT) |
2453			PMURES_BIT(RES4345_LNLDO_PU) |
2454			PMURES_BIT(RES4345_SR_CLK_START) |
2455			PMURES_BIT(RES4345_WL_CORE_RDY) |
2456			PMURES_BIT(RES4345_SR_CLK_STABLE) |
2457			PMURES_BIT(RES4345_SR_SAVE_RESTORE) |
2458			PMURES_BIT(RES4345_SR_PHY_PWRSW) |
2459			PMURES_BIT(RES4345_SR_VDDM_PWRSW) |
2460			PMURES_BIT(RES4345_SR_SUBCORE_PWRSW) |
2461			PMURES_BIT(RES4345_SR_SLEEP);
2462
2463#if defined(SAVERESTORE)
2464		/* min_mask is updated after SR code is downloaded to txfifo */
2465		if (SR_ENAB() && sr_isenab(sih))
2466			min_mask = PMURES_BIT(RES4345_LPLDO_PU);
2467#endif
2468		/* Set the bits for all resources in the max mask except for the SR Engine */
2469		max_mask = 0x7FFFFFFF;
2470		break;
2471
2472	case BCM4350_CHIP_ID:
2473	case BCM4354_CHIP_ID:
2474	case BCM4356_CHIP_ID:
2475	case BCM43556_CHIP_ID:
2476	case BCM43558_CHIP_ID:
2477	case BCM43566_CHIP_ID:
2478	case BCM43568_CHIP_ID:
2479	case BCM43569_CHIP_ID:
2480	case BCM43570_CHIP_ID:
2481		/* JIRA: SWWLAN-27486 Power consumption optimization when wireless is down */
2482#ifndef BCM_BOOTLOADER
2483		if (CST4350_IFC_MODE(sih->chipst) == CST4350_IFC_MODE_PCIE) {
2484			int L1substate = si_pcie_get_L1substate(sih);
2485			if (L1substate & 1)	/* L1.2 is enabled */
2486				min_mask = PMURES_BIT(RES4350_LPLDO_PU) |
2487					PMURES_BIT(RES4350_PMU_BG_PU) |
2488					PMURES_BIT(RES4350_PMU_SLEEP);
2489			else			/* use chip default min resource mask */
2490				min_mask = 0xfc22f77;
2491		} else {
2492#endif /* BCM_BOOTLOADER */
2493
2494			/* use chip default min resource mask */
2495			min_mask = pmu_corereg(sih, SI_CC_IDX,
2496				min_res_mask, 0, 0);
2497#ifndef BCM_BOOTLOADER
2498		}
2499#endif /* BCM_BOOTLOADER */
2500
2501#if defined(SAVERESTORE)
2502		/* min_mask is updated after SR code is downloaded to txfifo */
2503		if (SR_ENAB() && sr_isenab(sih)) {
2504			min_mask = PMURES_BIT(RES4350_LPLDO_PU);
2505
2506			if (CST4350_CHIPMODE_PCIE(sih->chipst) &&
2507				(CHIPREV(sih->chiprev) <= 5)) {
2508				min_mask = PMURES_BIT(RES4350_LDO3P3_PU) |
2509					PMURES_BIT(RES4350_PMU_SLEEP) |
2510					PMURES_BIT(RES4350_PMU_BG_PU) |
2511					PMURES_BIT(RES4350_LPLDO_PU);
2512			}
2513		}
2514#endif /* SAVERESTORE */
2515		/* Set the bits for all resources in the max mask except for the SR Engine */
2516		max_mask = 0x7FFFFFFF;
2517		break;
2518
2519	case BCM43242_CHIP_ID:
2520	case BCM43243_CHIP_ID:
2521		/* Read the min_res_mask register. Set the mask to 0 as we need to only read. */
2522		min_mask = pmu_corereg(sih, SI_CC_IDX, min_res_mask, 0, 0);
2523
2524		/* Set the bits for all resources in the max mask except for the SR Engine */
2525		max_mask = (1 << rsrcs) - 1;
2526		break;
2527
2528	case BCM4314_CHIP_ID:
2529		/* set 4314 min mask to 0x3_f6ff -- ILP available (DozeMode) */
2530		if ((sih->chippkg == BCM4314SDIO_PKG_ID) ||
2531			(sih->chippkg == BCM4314SDIO_ARM_PKG_ID) ||
2532			(sih->chippkg == BCM4314SDIO_FPBGA_PKG_ID)) {
2533			min_mask = PMURES_BIT(RES4314_LPLDO_PU) |
2534				PMURES_BIT(RES4314_PMU_SLEEP_DIS) |
2535				PMURES_BIT(RES4314_PMU_BG_PU) |
2536				PMURES_BIT(RES4314_CBUCK_LPOM_PU) |
2537				PMURES_BIT(RES4314_CBUCK_PFM_PU) |
2538				PMURES_BIT(RES4314_CLDO_PU) |
2539				PMURES_BIT(RES4314_OTP_PU);
2540		} else {
2541			min_mask = PMURES_BIT(RES4314_LPLDO_PU) |
2542				PMURES_BIT(RES4314_PMU_SLEEP_DIS) |
2543				PMURES_BIT(RES4314_PMU_BG_PU) |
2544				PMURES_BIT(RES4314_CBUCK_LPOM_PU) |
2545				PMURES_BIT(RES4314_CBUCK_PFM_PU) |
2546				PMURES_BIT(RES4314_CLDO_PU) |
2547				PMURES_BIT(RES4314_LPLDO2_LVM) |
2548				PMURES_BIT(RES4314_WL_PMU_PU) |
2549				PMURES_BIT(RES4314_LDO3P3_PU) |
2550				PMURES_BIT(RES4314_OTP_PU) |
2551				PMURES_BIT(RES4314_WL_PWRSW_PU) |
2552				PMURES_BIT(RES4314_LQ_AVAIL) |
2553				PMURES_BIT(RES4314_LOGIC_RET) |
2554				PMURES_BIT(RES4314_MEM_SLEEP) |
2555				PMURES_BIT(RES4314_MACPHY_RET) |
2556				PMURES_BIT(RES4314_WL_CORE_READY) |
2557				PMURES_BIT(RES4314_SYNTH_PWRSW_PU);
2558		}
2559		max_mask = 0x3FFFFFFF;
2560		break;
2561	case BCM43142_CHIP_ID:
2562		/* Only PCIe */
2563		min_mask = PMURES_BIT(RES4314_LPLDO_PU) |
2564			PMURES_BIT(RES4314_PMU_SLEEP_DIS) |
2565			PMURES_BIT(RES4314_PMU_BG_PU) |
2566			PMURES_BIT(RES4314_CBUCK_LPOM_PU) |
2567			PMURES_BIT(RES4314_CBUCK_PFM_PU) |
2568			PMURES_BIT(RES4314_CLDO_PU) |
2569			PMURES_BIT(RES4314_LPLDO2_LVM) |
2570			PMURES_BIT(RES4314_WL_PMU_PU) |
2571			PMURES_BIT(RES4314_LDO3P3_PU) |
2572			PMURES_BIT(RES4314_OTP_PU) |
2573			PMURES_BIT(RES4314_WL_PWRSW_PU) |
2574			PMURES_BIT(RES4314_LQ_AVAIL) |
2575			PMURES_BIT(RES4314_LOGIC_RET) |
2576			PMURES_BIT(RES4314_MEM_SLEEP) |
2577			PMURES_BIT(RES4314_MACPHY_RET) |
2578			PMURES_BIT(RES4314_WL_CORE_READY);
2579		max_mask = 0x3FFFFFFF;
2580		break;
2581	case BCM4334_CHIP_ID:
2582		/* Use default for boot loader */
2583#ifndef BCM_BOOTLOADER
2584		min_mask = PMURES_BIT(RES4334_LPLDO_PU) | PMURES_BIT(RES4334_RESET_PULLDN_DIS) |
2585			PMURES_BIT(RES4334_OTP_PU) | PMURES_BIT(RES4334_WL_CORE_READY);
2586#endif /* !BCM_BOOTLOADER */
2587
2588		max_mask = 0x7FFFFFFF;
2589		break;
2590	case BCM43341_CHIP_ID:
2591		/* Use default for boot loader */
2592#ifndef BCM_BOOTLOADER
2593		min_mask = PMURES_BIT(RES4334_LPLDO_PU);
2594
2595#endif /* !BCM_BOOTLOADER */
2596
2597		max_mask = 0x7FFFFFFF;
2598		break;
2599	default:
2600		PMU_ERROR(("MIN and MAX mask is not programmed\n"));
2601		break;
2602	}
2603
2604	/* Apply nvram override to min mask */
2605	if (sii->min_mask_valid == TRUE) {
2606		PMU_MSG(("Applying rmin=%d to min_mask\n", sii->nvram_min_mask));
2607		min_mask = sii->nvram_min_mask;
2608	}
2609	/* Apply nvram override to max mask */
2610	if (sii->max_mask_valid == TRUE) {
2611		PMU_MSG(("Applying rmax=%d to max_mask\n", sii->nvram_max_mask));
2612		max_mask = sii->nvram_max_mask;
2613	}
2614
2615	*pmin = min_mask;
2616	*pmax = max_mask;
2617} /* si_pmu_res_masks */
2618
2619#if !defined(_CFE_) && !defined(_CFEZ_)
2620static void
2621BCMATTACHFN(si_pmu_resdeptbl_upd)(si_t *sih, osl_t *osh,
2622	const pmu_res_depend_t *restable, uint tablesz)
2623{
2624	uint i, rsrcs;
2625
2626	if (tablesz == 0)
2627		return;
2628
2629	ASSERT(restable != NULL);
2630
2631	rsrcs = (sih->pmucaps & PCAP_RC_MASK) >> PCAP_RC_SHIFT;
2632	/* Program resource dependencies table */
2633	while (tablesz--) {
2634		if (restable[tablesz].filter != NULL &&
2635		    !(restable[tablesz].filter)(sih))
2636			continue;
2637		for (i = 0; i < rsrcs; i ++) {
2638			if ((restable[tablesz].res_mask &
2639			     PMURES_BIT(i)) == 0)
2640				continue;
2641			W_REG(osh, PMUREG(sih, res_table_sel), i);
2642			switch (restable[tablesz].action) {
2643				case RES_DEPEND_SET:
2644					PMU_MSG(("Changing rsrc %d res_dep_mask to 0x%x\n", i,
2645						restable[tablesz].depend_mask));
2646					W_REG(osh, PMUREG(sih, res_dep_mask),
2647					      restable[tablesz].depend_mask);
2648					break;
2649				case RES_DEPEND_ADD:
2650					PMU_MSG(("Adding 0x%x to rsrc %d res_dep_mask\n",
2651						restable[tablesz].depend_mask, i));
2652					OR_REG(osh, PMUREG(sih, res_dep_mask),
2653					       restable[tablesz].depend_mask);
2654					break;
2655				case RES_DEPEND_REMOVE:
2656					PMU_MSG(("Removing 0x%x from rsrc %d res_dep_mask\n",
2657						restable[tablesz].depend_mask, i));
2658					AND_REG(osh, PMUREG(sih, res_dep_mask),
2659						~restable[tablesz].depend_mask);
2660					break;
2661				default:
2662					ASSERT(0);
2663					break;
2664			}
2665		}
2666	}
2667}
2668#endif /* !defined(_CFE_) && !defined(_CFEZ_) */
2669
2670/** Initialize PMU hardware resources. */
2671void
2672BCMATTACHFN(si_pmu_res_init)(si_t *sih, osl_t *osh)
2673{
2674#if !defined(_CFE_) && !defined(_CFEZ_)
2675	chipcregs_t *cc;
2676	uint origidx;
2677	const pmu_res_updown_t *pmu_res_updown_table = NULL;
2678	uint pmu_res_updown_table_sz = 0;
2679	const pmu_res_depend_t *pmu_res_depend_table = NULL;
2680	uint pmu_res_depend_table_sz = 0;
2681#ifndef BCM_BOOTLOADER
2682	const pmu_res_depend_t *pmu_res_depend_pciewar_table = NULL;
2683	uint pmu_res_depend_pciewar_table_sz = 0;
2684#endif /* BCM_BOOTLOADER */
2685	uint32 min_mask = 0, max_mask = 0;
2686	char name[8];
2687	const char *val;
2688	uint i, rsrcs;
2689	si_info_t* sii = SI_INFO(sih);
2690
2691	ASSERT(sih->cccaps & CC_CAP_PMU);
2692
2693	/* Remember original core before switch to chipc */
2694	origidx = si_coreidx(sih);
2695	cc = si_setcoreidx(sih, SI_CC_IDX);
2696	ASSERT(cc != NULL);
2697
2698	/* Cache nvram override to min mask */
2699	if ((val = getvar(NULL, rstr_rmin)) != NULL) {
2700		sii->min_mask_valid = TRUE;
2701		sii->nvram_min_mask = (uint32)bcm_strtoul(val, NULL, 0);
2702	} else sii->min_mask_valid = FALSE;
2703	/* Cache nvram override to max mask */
2704	if ((val = getvar(NULL, rstr_rmax)) != NULL) {
2705		sii->max_mask_valid = TRUE;
2706		sii->nvram_max_mask = (uint32)bcm_strtoul(val, NULL, 0);
2707	} else sii->max_mask_valid = FALSE;
2708
2709	/*
2710	 * Hardware contains the resource updown and dependency tables. Only if a chip has a
2711	 * hardware problem, software tables can be used to override hardware tables.
2712	 */
2713	switch (CHIPID(sih->chip)) {
2714	case BCM4328_CHIP_ID:
2715		pmu_res_updown_table = bcm4328a0_res_updown;
2716		pmu_res_updown_table_sz = ARRAYSIZE(bcm4328a0_res_updown);
2717		pmu_res_depend_table = bcm4328a0_res_depend;
2718		pmu_res_depend_table_sz = ARRAYSIZE(bcm4328a0_res_depend);
2719		break;
2720	case BCM4325_CHIP_ID:
2721		/* Optimize resources up/down timers */
2722		if (ISSIM_ENAB(sih)) {
2723			pmu_res_updown_table = bcm4325a0_res_updown_qt;
2724			pmu_res_updown_table_sz = ARRAYSIZE(bcm4325a0_res_updown_qt);
2725		} else {
2726			pmu_res_updown_table = bcm4325a0_res_updown;
2727			pmu_res_updown_table_sz = ARRAYSIZE(bcm4325a0_res_updown);
2728		}
2729		/* Optimize resources dependencies */
2730		pmu_res_depend_table = bcm4325a0_res_depend;
2731		pmu_res_depend_table_sz = ARRAYSIZE(bcm4325a0_res_depend);
2732		break;
2733	case BCM4315_CHIP_ID:
2734		/* Optimize resources up/down timers */
2735		if (ISSIM_ENAB(sih)) {
2736			pmu_res_updown_table = bcm4315a0_res_updown_qt;
2737			pmu_res_updown_table_sz = ARRAYSIZE(bcm4315a0_res_updown_qt);
2738		}
2739		else {
2740			pmu_res_updown_table = bcm4315a0_res_updown;
2741			pmu_res_updown_table_sz = ARRAYSIZE(bcm4315a0_res_updown);
2742		}
2743		/* Optimize resources dependencies masks */
2744		pmu_res_depend_table = bcm4315a0_res_depend;
2745		pmu_res_depend_table_sz = ARRAYSIZE(bcm4315a0_res_depend);
2746		break;
2747	case BCM4329_CHIP_ID:
2748		/* Optimize resources up/down timers */
2749		if (ISSIM_ENAB(sih)) {
2750			pmu_res_updown_table = NULL;
2751			pmu_res_updown_table_sz = 0;
2752		} else {
2753			pmu_res_updown_table = bcm4329_res_updown;
2754			pmu_res_updown_table_sz = ARRAYSIZE(bcm4329_res_updown);
2755		}
2756		/* Optimize resources dependencies */
2757		pmu_res_depend_table = bcm4329_res_depend;
2758		pmu_res_depend_table_sz = ARRAYSIZE(bcm4329_res_depend);
2759		break;
2760
2761	case BCM4319_CHIP_ID:
2762		/* Optimize resources up/down timers */
2763		if (ISSIM_ENAB(sih)) {
2764			pmu_res_updown_table = bcm4319a0_res_updown_qt;
2765			pmu_res_updown_table_sz = ARRAYSIZE(bcm4319a0_res_updown_qt);
2766		}
2767		else {
2768			pmu_res_updown_table = bcm4319a0_res_updown;
2769			pmu_res_updown_table_sz = ARRAYSIZE(bcm4319a0_res_updown);
2770		}
2771		/* Optimize resources dependencies masks */
2772		pmu_res_depend_table = bcm4319a0_res_depend;
2773		pmu_res_depend_table_sz = ARRAYSIZE(bcm4319a0_res_depend);
2774		break;
2775
2776	case BCM4336_CHIP_ID:
2777	case BCM43362_CHIP_ID:
2778		/* Optimize resources up/down timers */
2779		if (ISSIM_ENAB(sih)) {
2780			pmu_res_updown_table = bcm4336a0_res_updown_qt;
2781			pmu_res_updown_table_sz = ARRAYSIZE(bcm4336a0_res_updown_qt);
2782		}
2783		else {
2784			pmu_res_updown_table = bcm4336a0_res_updown;
2785			pmu_res_updown_table_sz = ARRAYSIZE(bcm4336a0_res_updown);
2786		}
2787		/* Optimize resources dependencies masks */
2788		pmu_res_depend_table = bcm4336a0_res_depend;
2789		pmu_res_depend_table_sz = ARRAYSIZE(bcm4336a0_res_depend);
2790		break;
2791
2792	case BCM4330_CHIP_ID:
2793		/* Optimize resources up/down timers */
2794		if (ISSIM_ENAB(sih)) {
2795			pmu_res_updown_table = bcm4330a0_res_updown_qt;
2796			pmu_res_updown_table_sz = ARRAYSIZE(bcm4330a0_res_updown_qt);
2797		}
2798		else {
2799			pmu_res_updown_table = bcm4330a0_res_updown;
2800			pmu_res_updown_table_sz = ARRAYSIZE(bcm4330a0_res_updown);
2801		}
2802		/* Optimize resources dependencies masks */
2803		pmu_res_depend_table = bcm4330a0_res_depend;
2804		pmu_res_depend_table_sz = ARRAYSIZE(bcm4330a0_res_depend);
2805		break;
2806	case BCM4314_CHIP_ID:
2807		/* Enable SDIO wake up */
2808		if (!((sih->chippkg == BCM4314PCIE_ARM_PKG_ID) ||
2809			(sih->chippkg == BCM4314PCIE_PKG_ID) ||
2810			(sih->chippkg == BCM4314DEV_PKG_ID)))
2811		{
2812			uint32 tmp;
2813			W_REG(osh, PMUREG(sih, chipcontrol_addr), PMU_CHIPCTL3);
2814			tmp = R_REG(osh, PMUREG(sih, chipcontrol_data));
2815			tmp |= (1 << PMU_CC3_ENABLE_SDIO_WAKEUP_SHIFT);
2816			W_REG(osh, PMUREG(sih, chipcontrol_data), tmp);
2817		}
2818	case BCM43142_CHIP_ID:
2819	case BCM43341_CHIP_ID:
2820		/* Optimize resources up/down timers */
2821		if (ISSIM_ENAB(sih)) {
2822			pmu_res_updown_table = bcm4334b0_res_updown_qt;
2823			/* pmu_res_updown_table_sz = ARRAYSIZE(bcm4334b0_res_updown_qt); */
2824		}
2825		else {
2826			pmu_res_updown_table = bcm4334b0_res_updown;
2827			pmu_res_updown_table_sz = ARRAYSIZE(bcm4334b0_res_updown);
2828		}
2829		/* Optimize resources dependancies masks */
2830		if (CST4334_CHIPMODE_HSIC(sih->chipst)) {
2831			pmu_res_depend_table = bcm4334b0_res_hsic_depend;
2832			pmu_res_depend_table_sz = ARRAYSIZE(bcm4334b0_res_hsic_depend);
2833		}
2834		else {
2835			pmu_res_depend_table = bcm4334b0_res_depend;
2836			pmu_res_depend_table_sz = ARRAYSIZE(bcm4334b0_res_depend);
2837		}
2838		break;
2839	case BCM4334_CHIP_ID:
2840		/* Optimize resources up/down timers */
2841		if (ISSIM_ENAB(sih)) {
2842			pmu_res_updown_table = bcm4334a0_res_updown_qt;
2843			/* pmu_res_updown_table_sz = ARRAYSIZE(bcm4334a0_res_updown_qt); */
2844		}
2845		else {
2846			pmu_res_updown_table = bcm4334a0_res_updown;
2847			/* pmu_res_updown_table_sz = ARRAYSIZE(bcm4334a0_res_updown); */
2848		}
2849		/* Optimize resources dependencies masks */
2850		pmu_res_depend_table = bcm4334a0_res_depend;
2851		/* pmu_res_depend_table_sz = ARRAYSIZE(bcm4334a0_res_depend); */
2852		break;
2853	case BCM4324_CHIP_ID:
2854	case BCM43242_CHIP_ID:
2855	case BCM43243_CHIP_ID:
2856		/* Need to change the up down timer for SR qt */
2857		if (ISSIM_ENAB(sih)) {
2858			pmu_res_updown_table = bcm4324a0_res_updown_qt;
2859			pmu_res_updown_table_sz = ARRAYSIZE(bcm4324a0_res_updown_qt);
2860		} else if ((CHIPID(sih->chip) == BCM4324_CHIP_ID) && (CHIPREV(sih->chiprev) <= 1)) {
2861			pmu_res_updown_table = bcm4324a0_res_updown;
2862			pmu_res_updown_table_sz = ARRAYSIZE(bcm4324a0_res_updown);
2863		} else {
2864			pmu_res_updown_table = bcm4324b0_res_updown;
2865			pmu_res_updown_table_sz = ARRAYSIZE(bcm4324b0_res_updown);
2866		}
2867		pmu_res_depend_table = bcm4324a0_res_depend;
2868		pmu_res_depend_table_sz = ARRAYSIZE(bcm4324a0_res_depend);
2869		break;
2870	case BCM4335_CHIP_ID:
2871		pmu_res_updown_table = bcm4335_res_updown;
2872		pmu_res_updown_table_sz = ARRAYSIZE(bcm4335_res_updown);
2873		pmu_res_depend_table = bcm4335b0_res_depend;
2874		pmu_res_depend_table_sz = ARRAYSIZE(bcm4335b0_res_depend);
2875		break;
2876	case BCM4345_CHIP_ID:
2877		pmu_res_updown_table = bcm4345_res_updown;
2878		pmu_res_updown_table_sz = ARRAYSIZE(bcm4345_res_updown);
2879		pmu_res_depend_table = bcm4345_res_depend;
2880		pmu_res_depend_table_sz = ARRAYSIZE(bcm4345_res_depend);
2881		break;
2882	case BCM4350_CHIP_ID:
2883	case BCM4354_CHIP_ID:
2884	case BCM4356_CHIP_ID:
2885	case BCM43556_CHIP_ID:
2886	case BCM43558_CHIP_ID:
2887	case BCM43566_CHIP_ID:
2888	case BCM43568_CHIP_ID:
2889	case BCM43569_CHIP_ID:
2890	case BCM43570_CHIP_ID:
2891		pmu_res_updown_table = bcm4350_res_updown;
2892		pmu_res_updown_table_sz = ARRAYSIZE(bcm4350_res_updown);
2893		if (!CST4350_CHIPMODE_PCIE(sih->chipst)) {
2894			pmu_res_depend_table = bcm4350_res_depend;
2895			pmu_res_depend_table_sz = ARRAYSIZE(bcm4350_res_depend);
2896		}
2897#ifndef BCM_BOOTLOADER
2898		pmu_res_depend_pciewar_table = bcm4350_res_pciewar;
2899		pmu_res_depend_pciewar_table_sz = ARRAYSIZE(bcm4350_res_pciewar);
2900#endif /* !BCM_BOOTLOADER */
2901		break;
2902	case BCM4360_CHIP_ID:
2903	case BCM4352_CHIP_ID:
2904		if (CHIPREV(sih->chiprev) < 4) {
2905			pmu_res_updown_table = bcm4360_res_updown;
2906			pmu_res_updown_table_sz = ARRAYSIZE(bcm4360_res_updown);
2907		} else {
2908			/* FOR 4360B1 */
2909			pmu_res_updown_table = bcm4360B1_res_updown;
2910			pmu_res_updown_table_sz = ARRAYSIZE(bcm4360B1_res_updown);
2911		}
2912		break;
2913	case BCM43602_CHIP_ID:
2914	case BCM43462_CHIP_ID:
2915		pmu_res_updown_table = bcm43602_res_updown;
2916		pmu_res_updown_table_sz = ARRAYSIZE(bcm43602_res_updown);
2917		pmu_res_depend_table = bcm43602_res_depend;
2918		pmu_res_depend_table_sz = ARRAYSIZE(bcm43602_res_depend);
2919#ifndef BCM_BOOTLOADER
2920		pmu_res_depend_pciewar_table = bcm43602_res_pciewar;
2921		pmu_res_depend_pciewar_table_sz = ARRAYSIZE(bcm43602_res_pciewar);
2922#endif /* !BCM_BOOTLOADER */
2923		break;
2924	case BCM43143_CHIP_ID:
2925		/* POR values for up/down and dependency tables are sufficient. */
2926		/* fall through */
2927	default:
2928		break;
2929	}
2930
2931	/* # resources */
2932	rsrcs = (sih->pmucaps & PCAP_RC_MASK) >> PCAP_RC_SHIFT;
2933
2934	/* Program up/down timers */
2935	while (pmu_res_updown_table_sz--) {
2936		ASSERT(pmu_res_updown_table != NULL);
2937		PMU_MSG(("Changing rsrc %d res_updn_timer to 0x%x\n",
2938		         pmu_res_updown_table[pmu_res_updown_table_sz].resnum,
2939		         pmu_res_updown_table[pmu_res_updown_table_sz].updown));
2940		W_REG(osh, PMUREG(sih, res_table_sel),
2941		      pmu_res_updown_table[pmu_res_updown_table_sz].resnum);
2942		W_REG(osh, PMUREG(sih, res_updn_timer),
2943		      pmu_res_updown_table[pmu_res_updown_table_sz].updown);
2944	}
2945	/* Apply nvram overrides to up/down timers */
2946	for (i = 0; i < rsrcs; i ++) {
2947		uint32 r_val;
2948		snprintf(name, sizeof(name), rstr_rDt, i);
2949		if ((val = getvar(NULL, name)) == NULL)
2950			continue;
2951		r_val = (uint32)bcm_strtoul(val, NULL, 0);
2952		/* PMUrev = 13, pmu resource updown times are 12 bits(0:11 DT, 16:27 UT) */
2953		if (sih->pmurev >= 13) {
2954			if (r_val < (1 << 16)) {
2955				uint16 up_time = (r_val >> 8) & 0xFF;
2956				r_val &= 0xFF;
2957				r_val |= (up_time << 16);
2958			}
2959		}
2960		PMU_MSG(("Applying %s=%s to rsrc %d res_updn_timer\n", name, val, i));
2961		W_REG(osh, PMUREG(sih, res_table_sel), (uint32)i);
2962		W_REG(osh, PMUREG(sih, res_updn_timer), r_val);
2963	}
2964
2965	/* Program resource dependencies table */
2966	si_pmu_resdeptbl_upd(sih, osh, pmu_res_depend_table, pmu_res_depend_table_sz);
2967
2968	/* Apply nvram overrides to dependencies masks */
2969	for (i = 0; i < rsrcs; i ++) {
2970		snprintf(name, sizeof(name), rstr_rDd, i);
2971		if ((val = getvar(NULL, name)) == NULL)
2972			continue;
2973		PMU_MSG(("Applying %s=%s to rsrc %d res_dep_mask\n", name, val, i));
2974		W_REG(osh, PMUREG(sih, res_table_sel), (uint32)i);
2975		W_REG(osh, PMUREG(sih, res_dep_mask), (uint32)bcm_strtoul(val, NULL, 0));
2976	}
2977
2978#if !defined(BCM_BOOTLOADER) && !defined(BCM_OL_DEV)
2979	/* Initial any chip interface dependent PMU rsrc by looking at the
2980	 * chipstatus register to figure the selected interface
2981	 */
2982	if (BUSTYPE(sih->bustype) == PCI_BUS || BUSTYPE(sih->bustype) == SI_BUS) {
2983		bool is_pciedev = FALSE;
2984
2985		if ((CHIPID(sih->chip) == BCM4345_CHIP_ID) && CST4345_CHIPMODE_PCIE(sih->chipst))
2986			is_pciedev = TRUE;
2987		else if (BCM4350_CHIP(sih->chip) && CST4350_CHIPMODE_PCIE(sih->chipst))
2988			is_pciedev = TRUE;
2989		else if (CHIPID(sih->chip) == BCM43602_CHIP_ID)
2990			is_pciedev = TRUE;
2991
2992		if (is_pciedev && pmu_res_depend_pciewar_table && pmu_res_depend_pciewar_table_sz) {
2993			si_pmu_resdeptbl_upd(sih, osh,
2994				pmu_res_depend_pciewar_table, pmu_res_depend_pciewar_table_sz);
2995		}
2996	}
2997#endif /* !BCM_OL_DEV */
2998	/* Determine min/max rsrc masks */
2999	si_pmu_res_masks(sih, &min_mask, &max_mask);
3000
3001	/* Add min mask dependencies */
3002	min_mask |= si_pmu_res_deps(sih, osh, cc, min_mask, FALSE);
3003
3004	/* It is required to program max_mask first and then min_mask */
3005#ifdef BCM_BOOTLOADER
3006	if (CHIPID(sih->chip) == BCM4319_CHIP_ID) {
3007		min_mask |= R_REG(osh, PMUREG(sih, min_res_mask));
3008		max_mask |= R_REG(osh, PMUREG(sih, max_res_mask));
3009	}
3010#endif /* BCM_BOOTLOADER */
3011
3012#ifdef BCM_BOOTLOADER
3013	/* Apply nvram override to max mask */
3014	if ((val = getvar(NULL, "brmax")) != NULL) {
3015		PMU_MSG(("Applying brmax=%s to max_res_mask\n", val));
3016		max_mask = (uint32)bcm_strtoul(val, NULL, 0);
3017	}
3018
3019	/* Apply nvram override to min mask */
3020	if ((val = getvar(NULL, "brmin")) != NULL) {
3021		PMU_MSG(("Applying brmin=%s to min_res_mask\n", val));
3022		min_mask = (uint32)bcm_strtoul(val, NULL, 0);
3023	}
3024#endif /* BCM_BOOTLOADER */
3025
3026#ifndef BCM_OL_DEV
3027	if (((CHIPID(sih->chip) == BCM4360_CHIP_ID) || (CHIPID(sih->chip) == BCM4352_CHIP_ID)) &&
3028	    (CHIPREV(sih->chiprev) < 4) &&
3029	    ((CST4360_RSRC_INIT_MODE(sih->chipst) & 1) == 0)) {
3030		/* BBPLL */
3031		W_REG(osh, PMUREG(sih, pllcontrol_addr), 6);
3032		W_REG(osh, PMUREG(sih, pllcontrol_data), 0x09048562);
3033		/* AVB PLL */
3034		W_REG(osh, PMUREG(sih, pllcontrol_addr), 14);
3035		W_REG(osh, PMUREG(sih, pllcontrol_data), 0x09048562);
3036		si_pmu_pllupd(sih);
3037	} else if (((CHIPID(sih->chip) == BCM4360_CHIP_ID) ||
3038		(CHIPID(sih->chip) == BCM4352_CHIP_ID)) &&
3039		(CHIPREV(sih->chiprev) >= 4) &&
3040		((CST4360_RSRC_INIT_MODE(sih->chipst) & 1) == 0)) {
3041		/* Changes for 4360B1 */
3042
3043		/* Enable REFCLK bit 11 */
3044		W_REG(osh, PMUREG(sih, chipcontrol_addr), 1);
3045		OR_REG(osh, PMUREG(sih, chipcontrol_data), 0x800);
3046
3047		/* BBPLL */
3048		W_REG(osh, PMUREG(sih, pllcontrol_addr), 6);
3049		W_REG(osh, PMUREG(sih, pllcontrol_data), 0x080004e2);
3050
3051		W_REG(osh, PMUREG(sih, pllcontrol_addr), 7);
3052		W_REG(osh, PMUREG(sih, pllcontrol_data), 0xE);
3053		/* AVB PLL */
3054		W_REG(osh, PMUREG(sih, pllcontrol_addr), 14);
3055		W_REG(osh, PMUREG(sih, pllcontrol_data), 0x080004e2);
3056
3057		W_REG(osh, PMUREG(sih, pllcontrol_addr), 15);
3058		W_REG(osh, PMUREG(sih, pllcontrol_data), 0xE);
3059
3060		si_pmu_pllupd(sih);
3061	} else if ((CHIPID(sih->chip) == BCM43602_CHIP_ID ||
3062		CHIPID(sih->chip) == BCM43462_CHIP_ID) &&
3063		((CST4360_RSRC_INIT_MODE(sih->chipst) & 1) == 0)) {
3064
3065	}
3066#endif /* BCM_OL_DEV */
3067
3068	if (max_mask) {
3069		/* Ensure there is no bit set in min_mask which is not set in max_mask */
3070		max_mask |= min_mask;
3071
3072		/* First set the bits which change from 0 to 1 in max, then update the
3073		 * min_mask register and then reset the bits which change from 1 to 0
3074		 * in max. This is required as the bit in MAX should never go to 0 when
3075		 * the corresponding bit in min is still 1. Similarly the bit in min cannot
3076		 * be 1 when the corresponding bit in max is still 0.
3077		 */
3078		OR_REG(osh, PMUREG(sih, max_res_mask), max_mask);
3079	} else {
3080		/* First set the bits which change from 0 to 1 in max, then update the
3081		 * min_mask register and then reset the bits which change from 1 to 0
3082		 * in max. This is required as the bit in MAX should never go to 0 when
3083		 * the corresponding bit in min is still 1. Similarly the bit in min cannot
3084		 * be 1 when the corresponding bit in max is still 0.
3085		 */
3086		if (min_mask)
3087			OR_REG(osh, PMUREG(sih, max_res_mask), min_mask);
3088	}
3089
3090	/* Program min resource mask */
3091	if (min_mask) {
3092		PMU_MSG(("Changing min_res_mask to 0x%x\n", min_mask));
3093		W_REG(osh, PMUREG(sih, min_res_mask), min_mask);
3094	}
3095
3096	/* Program max resource mask */
3097	if (max_mask) {
3098		PMU_MSG(("Changing max_res_mask to 0x%x\n", max_mask));
3099		W_REG(osh, PMUREG(sih, max_res_mask), max_mask);
3100	}
3101
3102	/* request htavail thru pcie core */
3103	if (((CHIPID(sih->chip) == BCM4360_CHIP_ID) || (CHIPID(sih->chip) == BCM4352_CHIP_ID)) &&
3104	    (BUSTYPE(sih->bustype) == PCI_BUS) &&
3105	    (CHIPREV(sih->chiprev) < 4)) {
3106		uint32 pcie_clk_ctl_st;
3107
3108		pcie_clk_ctl_st = si_corereg(sih, 3, 0x1e0, 0, 0);
3109		si_corereg(sih, 3, 0x1e0, ~0, (pcie_clk_ctl_st | CCS_HTAREQ));
3110	}
3111
3112	si_pmu_wait_for_steady_state(sih, osh, cc);
3113	/* Add some delay; allow resources to come up and settle. */
3114	OSL_DELAY(2000);
3115
3116	/* Return to original core */
3117	si_setcoreidx(sih, origidx);
3118#endif /* !_CFE_ && !_CFEZ_ */
3119} /* si_pmu_res_init */
3120
3121/* setup pll and query clock speed */
3122typedef struct {
3123	uint16	freq;	/* x-tal frequency in [hz] */
3124	uint8	xf;	/* x-tal index as contained in PMU control reg, see PMU programmers guide */
3125	uint8	wbint;
3126	uint32	wbfrac;
3127} pmu0_xtaltab0_t;
3128
3129/* the following table is based on 880Mhz fvco */
3130static const pmu0_xtaltab0_t BCMINITDATA(pmu0_xtaltab0)[] = {
3131	{ 12000,	1,	73,	349525 },
3132	{ 13000,	2,	67,	725937 },
3133	{ 14400,	3,	61,	116508 },
3134	{ 15360,	4,	57,	305834 },
3135	{ 16200,	5,	54,	336579 },
3136	{ 16800,	6,	52,	399457 },
3137	{ 19200,	7,	45,	873813 },
3138	{ 19800,	8,	44,	466033 },
3139	{ 20000,	9,	44,	0 },
3140	{ 25000,	10,	70,	419430 },
3141	{ 26000,	11,	67,	725937 },
3142	{ 30000,	12,	58,	699050 },
3143	{ 38400,	13,	45,	873813 },
3144	{ 40000,	14,	45,	0 },
3145	{ 0,		0,	0,	0 }
3146};
3147
3148#ifdef BCMUSBDEV
3149#define	PMU0_XTAL0_DEFAULT	11
3150#else
3151#define PMU0_XTAL0_DEFAULT	8
3152#endif
3153
3154#ifdef BCMUSBDEV
3155/**
3156 * Set new backplane PLL clock frequency
3157 */
3158static void
3159BCMATTACHFN(si_pmu0_sbclk4328)(si_t *sih, int freq)
3160{
3161	uint32 tmp, oldmax, oldmin;
3162	osl_t *osh = si_osh(sih);
3163
3164
3165	/* Set new backplane PLL clock */
3166	W_REG(osh, PMUREG(sih, pllcontrol_addr), PMU0_PLL0_PLLCTL0);
3167	tmp = R_REG(osh, PMUREG(sih, pllcontrol_data));
3168	tmp &= ~(PMU0_PLL0_PC0_DIV_ARM_MASK);
3169	tmp |= freq << PMU0_PLL0_PC0_DIV_ARM_SHIFT;
3170	W_REG(osh, PMUREG(sih, pllcontrol_data), tmp);
3171
3172	/* Power cycle BB_PLL_PU by disabling/enabling it to take on new freq */
3173	/* Disable PLL */
3174	oldmin = R_REG(osh, PMUREG(sih, min_res_mask));
3175	oldmax = R_REG(osh, PMUREG(sih, max_res_mask));
3176	W_REG(osh, PMUREG(sih, min_res_mask), oldmin & ~PMURES_BIT(RES4328_BB_PLL_PU));
3177	W_REG(osh, PMUREG(sih, max_res_mask), oldmax & ~PMURES_BIT(RES4328_BB_PLL_PU));
3178
3179	/* It takes over several hundred usec to re-enable the PLL since the
3180	 * sequencer state machines run on ILP clock. Set delay at 450us to be safe.
3181	 *
3182	 * Be sure PLL is powered down first before re-enabling it.
3183	 */
3184
3185	OSL_DELAY(PLL_DELAY);
3186	SPINWAIT((R_REG(osh, PMUREG(sih, res_state)) & PMURES_BIT(RES4328_BB_PLL_PU)), PLL_DELAY*3);
3187	if (R_REG(osh, PMUREG(sih, res_state)) & PMURES_BIT(RES4328_BB_PLL_PU)) {
3188		/* If BB_PLL not powered down yet, new backplane PLL clock
3189		 *  may not take effect.
3190		 *
3191		 * Still early during bootup so no serial output here.
3192		 */
3193		PMU_ERROR(("Fatal: BB_PLL not power down yet!\n"));
3194		ASSERT(!(R_REG(osh, PMUREG(sih, res_state)) & PMURES_BIT(RES4328_BB_PLL_PU)));
3195	}
3196
3197	/* Enable PLL */
3198	W_REG(osh, PMUREG(sih, max_res_mask), oldmax);
3199} /* si_pmu0_sbclk4328 */
3200#endif /* BCMUSBDEV */
3201
3202/**
3203 * Set up PLL registers in the PMU as per the crystal speed.
3204 * Uses xtalfreq variable, or passed-in default.
3205 */
3206static void
3207BCMATTACHFN(si_pmu0_pllinit0)(si_t *sih, osl_t *osh, chipcregs_t *cc, uint32 xtal)
3208{
3209	uint32 tmp;
3210	const pmu0_xtaltab0_t *xt;
3211
3212	/* Find the frequency in the table */
3213	for (xt = pmu0_xtaltab0; xt->freq; xt ++)
3214		if (xt->freq == xtal)
3215			break;
3216	if (xt->freq == 0)
3217		xt = &pmu0_xtaltab0[PMU0_XTAL0_DEFAULT];
3218
3219	PMU_MSG(("XTAL %d.%d MHz (%d)\n", xtal / 1000, xtal % 1000, xt->xf));
3220
3221	/* Check current PLL state */
3222	tmp = (R_REG(osh, PMUREG(sih, pmucontrol)) & PCTL_XTALFREQ_MASK) >>
3223	        PCTL_XTALFREQ_SHIFT;
3224	if (tmp == xt->xf) {
3225		PMU_MSG(("PLL already programmed for %d.%d MHz\n",
3226		         xt->freq / 1000, xt->freq % 1000));
3227#ifdef BCMUSBDEV
3228		if (CHIPID(sih->chip) == BCM4328_CHIP_ID)
3229			si_pmu0_sbclk4328(sih, PMU0_PLL0_PC0_DIV_ARM_88MHZ);
3230#endif	/* BCMUSBDEV */
3231		return;
3232	}
3233
3234	if (tmp) {
3235		PMU_MSG(("Reprogramming PLL for %d.%d MHz (was %d.%dMHz)\n",
3236		         xt->freq / 1000, xt->freq % 1000,
3237		         pmu0_xtaltab0[tmp-1].freq / 1000, pmu0_xtaltab0[tmp-1].freq % 1000));
3238	} else {
3239		PMU_MSG(("Programming PLL for %d.%d MHz\n",
3240		         xt->freq / 1000, xt->freq % 1000));
3241	}
3242
3243	/* Make sure the PLL is off */
3244	switch (CHIPID(sih->chip)) {
3245	case BCM4328_CHIP_ID:
3246		AND_REG(osh, PMUREG(sih, min_res_mask), ~PMURES_BIT(RES4328_BB_PLL_PU));
3247		AND_REG(osh, PMUREG(sih, max_res_mask), ~PMURES_BIT(RES4328_BB_PLL_PU));
3248		break;
3249	case BCM5354_CHIP_ID:
3250		AND_REG(osh, PMUREG(sih, min_res_mask), ~PMURES_BIT(RES5354_BB_PLL_PU));
3251		AND_REG(osh, PMUREG(sih, max_res_mask), ~PMURES_BIT(RES5354_BB_PLL_PU));
3252		break;
3253	default:
3254		ASSERT(0);
3255	}
3256	SPINWAIT(R_REG(osh, &cc->clk_ctl_st) & CCS0_HTAVAIL, PMU_MAX_TRANSITION_DLY);
3257	ASSERT(!(R_REG(osh, &cc->clk_ctl_st) & CCS0_HTAVAIL));
3258
3259	PMU_MSG(("Done masking\n"));
3260
3261	/* Write PDIV in pllcontrol[0] */
3262	W_REG(osh, PMUREG(sih, pllcontrol_addr), PMU0_PLL0_PLLCTL0);
3263	tmp = R_REG(osh, PMUREG(sih, pllcontrol_data));
3264	if (xt->freq >= PMU0_PLL0_PC0_PDIV_FREQ)
3265		tmp |= PMU0_PLL0_PC0_PDIV_MASK;
3266	else
3267		tmp &= ~PMU0_PLL0_PC0_PDIV_MASK;
3268	W_REG(osh, PMUREG(sih, pllcontrol_data), tmp);
3269
3270	/* Write WILD in pllcontrol[1] */
3271	W_REG(osh, PMUREG(sih, pllcontrol_addr), PMU0_PLL0_PLLCTL1);
3272	tmp = R_REG(osh, PMUREG(sih, pllcontrol_data));
3273	tmp = ((tmp & ~(PMU0_PLL0_PC1_WILD_INT_MASK | PMU0_PLL0_PC1_WILD_FRAC_MASK)) |
3274	       (((xt->wbint << PMU0_PLL0_PC1_WILD_INT_SHIFT) &
3275	         PMU0_PLL0_PC1_WILD_INT_MASK) |
3276	        ((xt->wbfrac << PMU0_PLL0_PC1_WILD_FRAC_SHIFT) &
3277	         PMU0_PLL0_PC1_WILD_FRAC_MASK)));
3278	if (xt->wbfrac == 0)
3279		tmp |= PMU0_PLL0_PC1_STOP_MOD;
3280	else
3281		tmp &= ~PMU0_PLL0_PC1_STOP_MOD;
3282	W_REG(osh, PMUREG(sih, pllcontrol_data), tmp);
3283
3284	/* Write WILD in pllcontrol[2] */
3285	W_REG(osh, PMUREG(sih, pllcontrol_addr), PMU0_PLL0_PLLCTL2);
3286	tmp = R_REG(osh, PMUREG(sih, pllcontrol_data));
3287	tmp = ((tmp & ~PMU0_PLL0_PC2_WILD_INT_MASK) |
3288	       ((xt->wbint >> PMU0_PLL0_PC2_WILD_INT_SHIFT) &
3289	        PMU0_PLL0_PC2_WILD_INT_MASK));
3290	W_REG(osh, PMUREG(sih, pllcontrol_data), tmp);
3291
3292	PMU_MSG(("Done pll\n"));
3293
3294	/* Write XtalFreq. Set the divisor also. */
3295	tmp = R_REG(osh, PMUREG(sih, pmucontrol));
3296	tmp = ((tmp & ~PCTL_ILP_DIV_MASK) |
3297	       (((((xt->freq + 127) / 128) - 1) << PCTL_ILP_DIV_SHIFT) & PCTL_ILP_DIV_MASK));
3298	tmp = ((tmp & ~PCTL_XTALFREQ_MASK) |
3299	       ((xt->xf << PCTL_XTALFREQ_SHIFT) & PCTL_XTALFREQ_MASK));
3300	W_REG(osh, PMUREG(sih, pmucontrol), tmp);
3301} /* si_pmu0_pllinit0 */
3302
3303/** query alp/xtal clock frequency */
3304static uint32
3305BCMINITFN(si_pmu0_alpclk0)(si_t *sih, osl_t *osh, chipcregs_t *cc)
3306{
3307	const pmu0_xtaltab0_t *xt;
3308	uint32 xf;
3309
3310	/* Find the frequency in the table */
3311	xf = (R_REG(osh, PMUREG(sih, pmucontrol)) & PCTL_XTALFREQ_MASK) >>
3312	        PCTL_XTALFREQ_SHIFT;
3313	for (xt = pmu0_xtaltab0; xt->freq; xt++)
3314		if (xt->xf == xf)
3315			break;
3316	/* PLL must be configured before */
3317	ASSERT(xt->freq);
3318
3319	return xt->freq * 1000;
3320}
3321
3322/** query CPU clock frequency */
3323static uint32
3324BCMINITFN(si_pmu0_cpuclk0)(si_t *sih, osl_t *osh, chipcregs_t *cc)
3325{
3326	uint32 tmp, divarm;
3327	uint32 FVCO = FVCO_880;
3328
3329	/* Read divarm from pllcontrol[0] */
3330	W_REG(osh, PMUREG(sih, pllcontrol_addr), PMU0_PLL0_PLLCTL0);
3331	tmp = R_REG(osh, PMUREG(sih, pllcontrol_data));
3332	divarm = (tmp & PMU0_PLL0_PC0_DIV_ARM_MASK) >> PMU0_PLL0_PC0_DIV_ARM_SHIFT;
3333
3334
3335	/* Return ARM/SB clock */
3336	return FVCO / (divarm + PMU0_PLL0_PC0_DIV_ARM_BASE) * 1000;
3337} /* si_pmu0_cpuclk0 */
3338
3339/* setup pll and query clock speed */
3340typedef struct {
3341	uint16	fref;	/* x-tal frequency in [hz] */
3342	uint8	xf;	/* x-tal index as contained in PMU control reg, see PMU programmers guide */
3343	uint8	p1div;
3344	uint8	p2div;
3345	uint8	ndiv_int;
3346	uint32	ndiv_frac;
3347} pmu1_xtaltab0_t;
3348
3349static const pmu1_xtaltab0_t BCMINITDATA(pmu1_xtaltab0_880_4329)[] = {
3350	{12000,	1,	3,	22,	0x9,	0xFFFFEF},
3351	{13000,	2,	1,	6,	0xb,	0x483483},
3352	{14400,	3,	1,	10,	0xa,	0x1C71C7},
3353	{15360,	4,	1,	5,	0xb,	0x755555},
3354	{16200,	5,	1,	10,	0x5,	0x6E9E06},
3355	{16800,	6,	1,	10,	0x5,	0x3Cf3Cf},
3356	{19200,	7,	1,	4,	0xb,	0x755555},
3357	{19800,	8,	1,	11,	0x4,	0xA57EB},
3358	{20000,	9,	1,	11,	0x4,	0x0},
3359	{24000,	10,	3,	11,	0xa,	0x0},
3360	{25000,	11,	5,	16,	0xb,	0x0},
3361	{26000,	12,	1,	1,	0x21,	0xD89D89},
3362	{30000,	13,	3,	8,	0xb,	0x0},
3363	{37400,	14,	3,	1,	0x46,	0x969696},
3364	{38400,	15,	1,	1,	0x16,	0xEAAAAA},
3365	{40000,	16,	1,	2,	0xb,	0},
3366	{0,	0,	0,	0,	0,	0}
3367};
3368
3369/* the following table is based on 880Mhz fvco */
3370static const pmu1_xtaltab0_t BCMINITDATA(pmu1_xtaltab0_880)[] = {
3371	{12000,	1,	3,	22,	0x9,	0xFFFFEF},
3372	{13000,	2,	1,	6,	0xb,	0x483483},
3373	{14400,	3,	1,	10,	0xa,	0x1C71C7},
3374	{15360,	4,	1,	5,	0xb,	0x755555},
3375	{16200,	5,	1,	10,	0x5,	0x6E9E06},
3376	{16800,	6,	1,	10,	0x5,	0x3Cf3Cf},
3377	{19200,	7,	1,	4,	0xb,	0x755555},
3378	{19800,	8,	1,	11,	0x4,	0xA57EB},
3379	{20000,	9,	1,	11,	0x4,	0x0},
3380	{24000,	10,	3,	11,	0xa,	0x0},
3381	{25000,	11,	5,	16,	0xb,	0x0},
3382	{26000,	12,	1,	2,	0x10,	0xEC4EC4},
3383	{30000,	13,	3,	8,	0xb,	0x0},
3384	{33600,	14,	1,	2,	0xd,	0x186186},
3385	{38400,	15,	1,	2,	0xb,	0x755555},
3386	{40000,	16,	1,	2,	0xb,	0},
3387	{0,	0,	0,	0,	0,	0}
3388};
3389
3390/* indices into pmu1_xtaltab0_880[] */
3391#define PMU1_XTALTAB0_880_12000K	0
3392#define PMU1_XTALTAB0_880_13000K	1
3393#define PMU1_XTALTAB0_880_14400K	2
3394#define PMU1_XTALTAB0_880_15360K	3
3395#define PMU1_XTALTAB0_880_16200K	4
3396#define PMU1_XTALTAB0_880_16800K	5
3397#define PMU1_XTALTAB0_880_19200K	6
3398#define PMU1_XTALTAB0_880_19800K	7
3399#define PMU1_XTALTAB0_880_20000K	8
3400#define PMU1_XTALTAB0_880_24000K	9
3401#define PMU1_XTALTAB0_880_25000K	10
3402#define PMU1_XTALTAB0_880_26000K	11
3403#define PMU1_XTALTAB0_880_30000K	12
3404#define PMU1_XTALTAB0_880_37400K	13
3405#define PMU1_XTALTAB0_880_38400K	14
3406#define PMU1_XTALTAB0_880_40000K	15
3407
3408/* the following table is based on 1760Mhz fvco */
3409static const pmu1_xtaltab0_t BCMINITDATA(pmu1_xtaltab0_1760)[] = {
3410	{12000,	1,	3,	44,	0x9,	0xFFFFEF},
3411	{13000,	2,	1,	12,	0xb,	0x483483},
3412	{14400,	3,	1,	20,	0xa,	0x1C71C7},
3413	{15360,	4,	1,	10,	0xb,	0x755555},
3414	{16200,	5,	1,	20,	0x5,	0x6E9E06},
3415	{16800,	6,	1,	20,	0x5,	0x3Cf3Cf},
3416	{19200,	7,	1,	18,	0x5,	0x17B425},
3417	{19800,	8,	1,	22,	0x4,	0xA57EB},
3418	{20000,	9,	1,	22,	0x4,	0x0},
3419	{24000,	10,	3,	22,	0xa,	0x0},
3420	{25000,	11,	5,	32,	0xb,	0x0},
3421	{26000,	12,	1,	4,	0x10,	0xEC4EC4},
3422	{30000,	13,	3,	16,	0xb,	0x0},
3423	{38400,	14,	1,	10,	0x4,	0x955555},
3424	{40000,	15,	1,	4,	0xb,	0},
3425	{0,	0,	0,	0,	0,	0}
3426};
3427
3428/* indices into pmu1_xtaltab0_1760[] */
3429#define PMU1_XTALTAB0_1760_12000K	0
3430#define PMU1_XTALTAB0_1760_13000K	1
3431#define PMU1_XTALTAB0_1760_14400K	2
3432#define PMU1_XTALTAB0_1760_15360K	3
3433#define PMU1_XTALTAB0_1760_16200K	4
3434#define PMU1_XTALTAB0_1760_16800K	5
3435#define PMU1_XTALTAB0_1760_19200K	6
3436#define PMU1_XTALTAB0_1760_19800K	7
3437#define PMU1_XTALTAB0_1760_20000K	8
3438#define PMU1_XTALTAB0_1760_24000K	9
3439#define PMU1_XTALTAB0_1760_25000K	10
3440#define PMU1_XTALTAB0_1760_26000K	11
3441#define PMU1_XTALTAB0_1760_30000K	12
3442#define PMU1_XTALTAB0_1760_38400K	13
3443#define PMU1_XTALTAB0_1760_40000K	14
3444
3445/* the following table is based on 1440Mhz fvco */
3446static const pmu1_xtaltab0_t BCMINITDATA(pmu1_xtaltab0_1440)[] = {
3447	{12000,	1,	1,	1,	0x78,	0x0	},
3448	{13000,	2,	1,	1,	0x6E,	0xC4EC4E},
3449	{14400,	3,	1,	1,	0x64,	0x0	},
3450	{15360,	4,	1,	1,	0x5D,	0xC00000},
3451	{16200,	5,	1,	1,	0x58,	0xE38E38},
3452	{16800,	6,	1,	1,	0x55,	0xB6DB6D},
3453	{19200,	7,	1,	1,	0x4B,	0	},
3454	{19800,	8,	1,	1,	0x48,	0xBA2E8B},
3455	{20000,	9,	1,	1,	0x48,	0x0	},
3456	{25000,	10,	1,	1,	0x39,	0x999999},
3457	{26000, 11,     1,      1,      0x37,   0x627627},
3458	{30000,	12,	1,	1,	0x30,	0x0	},
3459	{37400, 13,     2,      1,     	0x4D, 	0x15E76	},
3460	{38400, 13,     2,      1,     	0x4B, 	0x0	},
3461	{40000,	14,	2,	1,	0x48,	0x0	},
3462	{48000,	15,	2,	1,	0x3c,	0x0	},
3463	{0,	0,	0,	0,	0,	0}
3464};
3465
3466/* indices into pmu1_xtaltab0_1440[] */
3467#define PMU1_XTALTAB0_1440_12000K	0
3468#define PMU1_XTALTAB0_1440_13000K	1
3469#define PMU1_XTALTAB0_1440_14400K	2
3470#define PMU1_XTALTAB0_1440_15360K	3
3471#define PMU1_XTALTAB0_1440_16200K	4
3472#define PMU1_XTALTAB0_1440_16800K	5
3473#define PMU1_XTALTAB0_1440_19200K	6
3474#define PMU1_XTALTAB0_1440_19800K	7
3475#define PMU1_XTALTAB0_1440_20000K	8
3476#define PMU1_XTALTAB0_1440_25000K	9
3477#define PMU1_XTALTAB0_1440_26000K	10
3478#define PMU1_XTALTAB0_1440_30000K	11
3479#define PMU1_XTALTAB0_1440_37400K	12
3480#define PMU1_XTALTAB0_1440_38400K	13
3481#define PMU1_XTALTAB0_1440_40000K	14
3482#define PMU1_XTALTAB0_1440_48000K	15
3483
3484#define XTAL_FREQ_24000MHZ		24000
3485#define XTAL_FREQ_30000MHZ		30000
3486#define XTAL_FREQ_37400MHZ		37400
3487#define XTAL_FREQ_48000MHZ		48000
3488
3489/* 'xf' values corresponding to the 'xf' definition in the PMU control register */
3490enum xtaltab0_960 {
3491	XTALTAB0_960_12000K = 1,
3492	XTALTAB0_960_13000K,
3493	XTALTAB0_960_14400K,
3494	XTALTAB0_960_15360K,
3495	XTALTAB0_960_16200K,
3496	XTALTAB0_960_16800K,
3497	XTALTAB0_960_19200K,
3498	XTALTAB0_960_19800K,
3499	XTALTAB0_960_20000K,
3500	XTALTAB0_960_24000K,
3501	XTALTAB0_960_25000K,
3502	XTALTAB0_960_26000K,
3503	XTALTAB0_960_30000K,
3504	XTALTAB0_960_33600K,
3505	XTALTAB0_960_37400K,
3506	XTALTAB0_960_38400K,
3507	XTALTAB0_960_40000K,
3508	XTALTAB0_960_48000K,
3509	XTALTAB0_960_52000K
3510};
3511
3512/**
3513 * given an x-tal frequency, this table specifies the PLL params to use to generate a 960Mhz output
3514 * clock. This output clock feeds the clock divider network. The defines of the form
3515 * PMU1_XTALTAB0_960_* index into this array.
3516 */
3517static const pmu1_xtaltab0_t BCMINITDATA(pmu1_xtaltab0_960)[] = {
3518/*	fref      xf                        p1div   p2div  ndiv_int  ndiv_frac */
3519	{12000,   1,       1,      1,     0x50,   0x0     }, /* array index 0 */
3520	{13000,   2,       1,      1,     0x49,   0xD89D89},
3521	{14400,   3,       1,      1,     0x42,   0xAAAAAA},
3522	{15360,   4,       1,      1,     0x3E,   0x800000},
3523	{16200,   5,       1,      1,     0x3B,   0x425ED0},
3524	{16800,   6,       1,      1,     0x39,   0x249249},
3525	{19200,   7,       1,      1,     0x32,   0x0     },
3526	{19800,   8,       1,      1,     0x30,   0x7C1F07},
3527	{20000,   9,       1,      1,     0x30,   0x0     },
3528	{24000,   10,      1,      1,     0x28,   0x0     },
3529	{25000,   11,      1,      1,     0x26,   0x666666}, /* array index 10 */
3530	{26000,   12,      1,      1,     0x24,   0xEC4EC4},
3531	{30000,   13,      1,      1,     0x20,   0x0     },
3532	{33600,   14,      1,      1,     0x1C,   0x924924},
3533	{37400,   15,      2,      1,     0x33,   0x563EF9},
3534	{38400,   16,      2,      1,     0x32,   0x0	  },
3535	{40000,   17,      2,      1,     0x30,   0x0     },
3536	{48000,   18,      2,      1,     0x28,   0x0     },
3537	{52000,   19,      2,      1,     0x24,   0xEC4EC4}, /* array index 18 */
3538	{0,	      0,       0,      0,     0,      0	      }
3539};
3540
3541/* Indices into array pmu1_xtaltab0_960[]. Keep array and these defines synchronized. */
3542#define PMU1_XTALTAB0_960_12000K	0
3543#define PMU1_XTALTAB0_960_13000K	1
3544#define PMU1_XTALTAB0_960_14400K	2
3545#define PMU1_XTALTAB0_960_15360K	3
3546#define PMU1_XTALTAB0_960_16200K	4
3547#define PMU1_XTALTAB0_960_16800K	5
3548#define PMU1_XTALTAB0_960_19200K	6
3549#define PMU1_XTALTAB0_960_19800K	7
3550#define PMU1_XTALTAB0_960_20000K	8
3551#define PMU1_XTALTAB0_960_24000K	9
3552#define PMU1_XTALTAB0_960_25000K	10
3553#define PMU1_XTALTAB0_960_26000K	11
3554#define PMU1_XTALTAB0_960_30000K	12
3555#define PMU1_XTALTAB0_960_33600K	13
3556#define PMU1_XTALTAB0_960_37400K	14
3557#define PMU1_XTALTAB0_960_38400K	15
3558#define PMU1_XTALTAB0_960_40000K	16
3559#define PMU1_XTALTAB0_960_48000K	17
3560#define PMU1_XTALTAB0_960_52000K	18
3561
3562#define PMU15_XTALTAB0_12000K	0
3563#define PMU15_XTALTAB0_20000K	1
3564#define PMU15_XTALTAB0_26000K	2
3565#define PMU15_XTALTAB0_37400K	3
3566#define PMU15_XTALTAB0_52000K	4
3567#define PMU15_XTALTAB0_END	5
3568
3569/* For having the pllcontrol data (info)
3570 * The table with the values of the registers will have one - one mapping.
3571 */
3572typedef struct {
3573	uint16 	clock;	/* x-tal frequency in [KHz] */
3574	uint8	mode;	/* spur mode */
3575	uint8	xf;	/* corresponds with xf bitfield in PMU control register */
3576} pllctrl_data_t;
3577
3578/*  *****************************  tables for 4335a0 *********************** */
3579
3580#ifdef BCM_BOOTLOADER
3581/**
3582 * PLL control register table giving info about the xtal supported for 4335.
3583 * There should be a one to one mapping between pmu1_pllctrl_tab_4335_960mhz[] and this table.
3584 */
3585static const pllctrl_data_t pmu1_xtaltab0_4335[] = {
3586	{12000, 0, XTALTAB0_960_12000K},
3587	{13000, 0, XTALTAB0_960_13000K},
3588	{14400, 0, XTALTAB0_960_14400K},
3589	{15360, 0, XTALTAB0_960_15360K},
3590	{16200, 0, XTALTAB0_960_16200K},
3591	{16800, 0, XTALTAB0_960_16800K},
3592	{19200, 0, XTALTAB0_960_19200K},
3593	{19800, 0, XTALTAB0_960_19800K},
3594	{20000, 0, XTALTAB0_960_20000K},
3595	{24000, 0, XTALTAB0_960_24000K},
3596	{25000, 0, XTALTAB0_960_25000K},
3597	{26000, 0, XTALTAB0_960_26000K},
3598	{30000, 0, XTALTAB0_960_30000K},
3599	{33600, 0, XTALTAB0_960_33600K},
3600	{37400, 0, XTALTAB0_960_37400K},
3601	{38400, 0, XTALTAB0_960_38400K},
3602	{40000, 0, XTALTAB0_960_40000K},
3603	{48000, 0, XTALTAB0_960_48000K},
3604	{52000, 0, XTALTAB0_960_52000K},
3605};
3606
3607/**
3608 * PLL control register values(all registers) for the xtal supported for 4335.
3609 * There should be a one to one mapping between pmu1_xtaltab0_4335[] and this table.
3610 */
3611static const uint32	pmu1_pllctrl_tab_4335_960mhz[] = {
3612/*      PLL 0       PLL 1       PLL 2       PLL 3       PLL 4       PLL 5                */
3613	0x50800000, 0x0C080803, 0x28010814, 0x61000000, 0x02600005, 0x0004FFFD, /* 12000 */
3614	0x50800000, 0x0C080803, 0x24B10814, 0x40D89D89, 0x02600005, 0x00049D87, /* 13000 */
3615	0x50800000, 0x0C080803, 0x21310814, 0x40AAAAAA, 0x02600005, 0x00042AA8, /* 14400 */
3616	0x50800000, 0x0C080803, 0x1F310814, 0x40800000, 0x02600005, 0x0003E7FE, /* 15360 */
3617	0x50800000, 0x0C080803, 0x1DB10814, 0x20425ED0, 0x02600005, 0x0003B424, /* 16200 */
3618	0x50800000, 0x0C080803, 0x1CB10814, 0x20249249, 0x02600005, 0x00039247, /* 16800 */
3619	0x50800000, 0x0C080803, 0x19010814, 0x01000000, 0x02600005, 0x00031FFE, /* 19200 */
3620	0x50800000, 0x0C080803, 0x18310814, 0x007C1F07, 0x02600005, 0x000307C0, /* 19800 */
3621	0x50800000, 0x0C080803, 0x18010814, 0x01000000, 0x02600005, 0x0002FFFE, /* 20000 */
3622	0x50800000, 0x0C080803, 0x14010814, 0xC1000000, 0x02600004, 0x00027FFE, /* 24000 */
3623	0x50800000, 0x0C080803, 0x13310814, 0xC0666666, 0x02600004, 0x00026665, /* 25000 */
3624	0x50800000, 0x0C080803, 0x12310814, 0xC0EC4EC4, 0x02600004, 0x00024EC4, /* 26000 */
3625	0x50800000, 0x0C080803, 0x10010814, 0xA1000000, 0x02600004, 0x0001FFFF, /* 30000 */
3626	0x50800000, 0x0C080803, 0x0E310814, 0xA0924924, 0x02600004, 0x0001C923, /* 33600 */
3627	0x50800000, 0x0C080803, 0x0CB10814, 0x80AB1F7C, 0x02600004, 0x00019AB1, /* 37400 */
3628	0x50800000, 0x0C080803, 0x0C810814, 0x81000000, 0x02600004, 0x00018FFF, /* 38400 */
3629	0x50800000, 0x0C080803, 0x0C010814, 0x81000000, 0x02600004, 0x00017FFF, /* 40000 */
3630	0x50800000, 0x0C080803, 0x0A010814, 0x61000000, 0x02600004, 0x00013FFF, /* 48000 */
3631	0x50800000, 0x0C080803, 0x09310814, 0x60762762, 0x02600004, 0x00012762, /* 52000 */
3632};
3633
3634#else /* BCM_BOOTLOADER */
3635/**
3636 * PLL control register table giving info about the xtal supported for 4335.
3637 * There should be a one to one mapping between pmu1_pllctrl_tab_4335_968mhz[] and this table.
3638 */
3639static const pllctrl_data_t pmu1_xtaltab0_4335_drv[] = {
3640	{37400, 0, XTALTAB0_960_37400K},
3641	{40000, 0, XTALTAB0_960_40000K},
3642};
3643
3644
3645/**
3646 * PLL control register values(all registers) for the xtal supported for 4335.
3647 * There should be a one to one mapping between pmu1_xtaltab0_4335_drv[] and this table.
3648 */
3649/*
3650 * This table corresponds to spur mode 8. This bbpll settings will be used for WLBGA Bx
3651 * as well as Cx
3652 */
3653static const uint32	pmu1_pllctrl_tab_4335_968mhz[] = {
3654/*      PLL 0       PLL 1       PLL 2       PLL 3       PLL 4       PLL 5                */
3655	0x50800000, 0x0A060803, 0x0CB10806, 0x80E1E1E2, 0x02600004, 0x00019AB1,	/* 37400 KHz */
3656	0x50800000, 0x0A060803, 0x0C310806, 0x80333333, 0x02600004, 0x00017FFF,	/* 40000 KHz */
3657};
3658
3659/* This table corresponds to spur mode 2. This bbpll settings will be used for WLCSP B0 */
3660static const uint32	pmu1_pllctrl_tab_4335_961mhz[] = {
3661/*      PLL 0       PLL 1       PLL 2       PLL 3       PLL 4       PLL 5                */
3662	0x50800000, 0x0A060803, 0x0CB10806, 0x80B1F7C9, 0x02600004, 0x00019AB1,	/* 37400 KHz */
3663	0x50800000, 0x0A060803, 0x0C310806, 0x80066666, 0x02600004, 0x00017FFF,	/* 40000 KHz */
3664};
3665
3666/* This table corresponds to spur mode 0. This bbpll settings will be used for WLCSP C0 */
3667static const uint32	pmu1_pllctrl_tab_4335_963mhz[] = {
3668/*      PLL 0       PLL 1       PLL 2       PLL 3       PLL 4       PLL 5                */
3669	0x50800000, 0x0A060803, 0x0CB10806, 0x80BFA863, 0x02600004, 0x00019AB1,	/* 37400 KHz */
3670	0x50800000, 0x0A060803, 0x0C310806, 0x80133333, 0x02600004, 0x00017FFF,	/* 40000 KHz */
3671};
3672
3673#endif /* BCM_BOOTLOADER */
3674
3675/*  ************************  tables for 4335a0 END *********************** */
3676
3677/*  *****************************  tables for 4345 *********************** */
3678
3679/* PLL control register table giving info about the xtal supported for 4345 series */
3680static const pllctrl_data_t BCMATTACHDATA(pmu1_xtaltab0_4345)[] = {
3681	{12000, 0, XTALTAB0_960_12000K},
3682	{13000, 0, XTALTAB0_960_13000K},
3683	{14400, 0, XTALTAB0_960_14400K},
3684	{15360, 0, XTALTAB0_960_15360K},
3685	{16200, 0, XTALTAB0_960_16200K},
3686	{16800, 0, XTALTAB0_960_16800K},
3687	{19200, 0, XTALTAB0_960_19200K},
3688	{19800, 0, XTALTAB0_960_19800K},
3689	{20000, 0, XTALTAB0_960_20000K},
3690	{24000, 0, XTALTAB0_960_24000K},
3691	{25000, 0, XTALTAB0_960_25000K},
3692	{26000, 0, XTALTAB0_960_26000K},
3693	{30000, 0, XTALTAB0_960_30000K},
3694	{33600, 0, XTALTAB0_960_33600K},
3695	{37400, 0, XTALTAB0_960_37400K},
3696	{38400, 0, XTALTAB0_960_38400K},
3697	{40000, 0, XTALTAB0_960_40000K},
3698	{48000, 0, XTALTAB0_960_48000K},
3699	{52000, 0, XTALTAB0_960_52000K},
3700};
3701
3702/*  ************************  tables for 4345 END *********************** */
3703
3704/*  *****************************  tables for 43242a0 *********************** */
3705/**
3706 * PLL control register table giving info about the xtal supported for 43242
3707 * There should be a one to one mapping between pmu1_pllctrl_tab_43242A0[]
3708 * and pmu1_pllctrl_tab_43242A1[] and this table.
3709 */
3710static const pllctrl_data_t BCMATTACHDATA(pmu1_xtaltab0_43242)[] = {
3711	{37400, 0, XTALTAB0_960_37400K},
3712};
3713
3714/*  ************************  tables for 4324a02 END *********************** */
3715
3716/*  *****************************  tables for 4350a0 *********************** */
3717
3718#define XTAL_DEFAULT_4350	37400
3719/**
3720 * PLL control register table giving info about the xtal supported for 4350
3721 * There should be a one to one mapping between pmu1_pllctrl_tab_4350_963mhz[] and this table.
3722 */
3723static const pllctrl_data_t pmu1_xtaltab0_4350[] = {
3724/*       clock  mode xf */
3725	{37400, 0,   XTALTAB0_960_37400K},
3726	{40000, 0,   XTALTAB0_960_40000K},
3727};
3728
3729/**
3730 * PLL control register table giving info about the xtal supported for 4335.
3731 * There should be a one to one mapping between pmu1_pllctrl_tab_4335_963mhz[] and this table.
3732 */
3733static const uint32	pmu1_pllctrl_tab_4350_963mhz[] = {
3734/*	PLL 0       PLL 1       PLL 2       PLL 3       PLL 4       PLL 5       PLL6         */
3735	0x50800000, 0x18060603, 0x0cb10814, 0x80bfaa00, 0x02600004, 0x00019AB1, 0x04a6c181,
3736	0x50800000, 0x18060603, 0x0C310814, 0x00133333, 0x02600004, 0x00017FFF, 0x04a6c181
3737};
3738static const uint32	pmu1_pllctrl_tab_4350C0_963mhz[] = {
3739/*	PLL 0       PLL 1       PLL 2       PLL 3       PLL 4       PLL 5       PLL6         */
3740	0x50800000, 0x08060603, 0x0cb10804, 0xe2bfaa00, 0x02600004, 0x00019AB1, 0x02a6c181,
3741	0x50800000, 0x08060603, 0x0C310804, 0xe2133333, 0x02600004, 0x00017FFF, 0x02a6c181
3742};
3743/*  ************************  tables for 4350a0 END *********************** */
3744
3745/* PLL control register values(all registers) for the xtal supported for 43242.
3746 * There should be a one to one mapping for "pllctrl_data_t" and the table below.
3747 * only support 37.4M
3748 */
3749static const uint32	BCMATTACHDATA(pmu1_pllctrl_tab_43242A0)[] = {
3750/*      PLL 0       PLL 1       PLL 2       PLL 3       PLL 4       PLL 5                */
3751	0xA7400040, 0x10080A06, 0x0CB11408, 0x80AB1F7C, 0x02600004, 0x00A6C4D3, /* 37400 */
3752};
3753
3754static const uint32	BCMATTACHDATA(pmu1_pllctrl_tab_43242A1)[] = {
3755/*      PLL 0       PLL 1       PLL 2       PLL 3       PLL 4       PLL 5                */
3756	0xA7400040, 0x10080A06, 0x0CB11408, 0x80AB1F7C, 0x02600004, 0x00A6C191, /* 37400 */
3757};
3758
3759/* 4334/4314 ADFLL freq target params */
3760typedef struct {
3761	uint16  fref;		/* x-tal frequency in [hz] */
3762	uint8   xf;			/* x-tal index as given by PMU programmers guide */
3763	uint32  freq_tgt;	/* freq_target: N_divide_ratio bitfield in DFLL */
3764} pmu2_xtaltab0_t;
3765
3766/**
3767 * If a DFLL clock of 480Mhz is desired, use this table to determine xf and freq_tgt for
3768 * a given x-tal frequency.
3769 */
3770static const pmu2_xtaltab0_t BCMINITDATA(pmu2_xtaltab0_adfll_480)[] = {
3771	{12000,		1,	0x4FFFC},
3772	{20000,		9,	0x2FFFD},
3773	{26000,		11,	0x24EC3},
3774	{37400,		13,	0x19AB1},
3775	{52000,		17,	0x12761},
3776	{0,		0,	0},
3777};
3778
3779static const pmu2_xtaltab0_t BCMINITDATA(pmu2_xtaltab0_adfll_492)[] = {
3780	{12000,		1,	0x51FFC},
3781	{20000,		9,	0x31330},
3782	{26000,		11,	0x25D88},
3783	{37400,		13,	0x1A4F5},
3784	{52000,		17,	0x12EC4},
3785	{0,		0,	0}
3786};
3787
3788static const pmu2_xtaltab0_t BCMINITDATA(pmu2_xtaltab0_adfll_485)[] = {
3789	{12000,		1,	0x50D52},
3790	{20000,		9,	0x307FE},
3791	{26000,		11,	0x254EA},
3792	{37400,		13,	0x19EF8},
3793	{52000,		17,	0x12A75},
3794	{0,		0,	0}
3795};
3796
3797/** returns xtal table for each chip */
3798static const pmu1_xtaltab0_t *
3799BCMINITFN(si_pmu1_xtaltab0)(si_t *sih)
3800{
3801	switch (CHIPID(sih->chip)) {
3802	case BCM4325_CHIP_ID:
3803		return pmu1_xtaltab0_880;
3804	case BCM4329_CHIP_ID:
3805		return pmu1_xtaltab0_880_4329;
3806	case BCM4315_CHIP_ID:
3807		return pmu1_xtaltab0_1760;
3808	case BCM4319_CHIP_ID:
3809		return pmu1_xtaltab0_1440;
3810	case BCM4336_CHIP_ID:
3811	case BCM43362_CHIP_ID:
3812	case BCM43239_CHIP_ID:
3813	case BCM4324_CHIP_ID:
3814	case BCM43242_CHIP_ID:
3815	case BCM43243_CHIP_ID:
3816	case BCM4335_CHIP_ID:
3817	case BCM4360_CHIP_ID:
3818	case BCM43460_CHIP_ID:
3819	case BCM4352_CHIP_ID:
3820	case BCM43526_CHIP_ID:
3821	case BCM4345_CHIP_ID:
3822	case BCM43602_CHIP_ID:
3823	case BCM43462_CHIP_ID:
3824	case BCM4350_CHIP_ID:
3825	case BCM4354_CHIP_ID:
3826	case BCM4356_CHIP_ID:
3827	case BCM43556_CHIP_ID:
3828	case BCM43558_CHIP_ID:
3829	case BCM43566_CHIP_ID:
3830	case BCM43568_CHIP_ID:
3831	case BCM43569_CHIP_ID:
3832	case BCM43570_CHIP_ID:
3833		return pmu1_xtaltab0_960;
3834	case BCM4330_CHIP_ID:
3835		if (CST4330_CHIPMODE_SDIOD(sih->chipst))
3836			return pmu1_xtaltab0_960;
3837		else
3838			return pmu1_xtaltab0_1440;
3839	default:
3840		PMU_MSG(("si_pmu1_xtaltab0: Unknown chipid %s\n", bcm_chipname(sih->chip, chn, 8)));
3841		break;
3842	}
3843	ASSERT(0);
3844	return NULL;
3845} /* si_pmu1_xtaltab0 */
3846
3847/** returns chip specific PLL settings for default xtal frequency and VCO output frequency */
3848static const pmu1_xtaltab0_t *
3849BCMINITFN(si_pmu1_xtaldef0)(si_t *sih)
3850{
3851
3852	switch (CHIPID(sih->chip)) {
3853	case BCM4325_CHIP_ID:
3854		/* Default to 26000Khz */
3855		return &pmu1_xtaltab0_880[PMU1_XTALTAB0_880_26000K];
3856	case BCM4329_CHIP_ID:
3857		/* Default to 38400Khz */
3858		return &pmu1_xtaltab0_880_4329[PMU1_XTALTAB0_880_38400K];
3859	case BCM4315_CHIP_ID:
3860#ifdef BCMUSBDEV
3861		/* Default to 30000Khz */
3862		return &pmu1_xtaltab0_1760[PMU1_XTALTAB0_1760_30000K];
3863#else
3864		/* Default to 26000Khz */
3865		return &pmu1_xtaltab0_1760[PMU1_XTALTAB0_1760_26000K];
3866#endif
3867	case BCM4319_CHIP_ID:
3868		/* Default to 30000Khz */
3869		return &pmu1_xtaltab0_1440[PMU1_XTALTAB0_1440_30000K];
3870	case BCM4336_CHIP_ID:
3871	case BCM43362_CHIP_ID:
3872	case BCM43239_CHIP_ID:
3873		/* Default to 26000Khz */
3874		return &pmu1_xtaltab0_960[PMU1_XTALTAB0_960_26000K];
3875	case BCM4324_CHIP_ID:
3876	case BCM43242_CHIP_ID:
3877	case BCM43243_CHIP_ID:
3878	case BCM4335_CHIP_ID:
3879	case BCM4360_CHIP_ID:
3880	case BCM4352_CHIP_ID:
3881	case BCM43460_CHIP_ID:
3882	case BCM43526_CHIP_ID:
3883	case BCM4345_CHIP_ID:
3884	case BCM4350_CHIP_ID:
3885	case BCM4354_CHIP_ID:
3886	case BCM4356_CHIP_ID:
3887	case BCM43556_CHIP_ID:
3888	case BCM43558_CHIP_ID:
3889	case BCM43566_CHIP_ID:
3890	case BCM43568_CHIP_ID:
3891	case BCM43569_CHIP_ID:
3892	case BCM43570_CHIP_ID:
3893		/* Default to 37400Khz */
3894		return &pmu1_xtaltab0_960[PMU1_XTALTAB0_960_37400K];
3895	case BCM43602_CHIP_ID:
3896	case BCM43462_CHIP_ID:
3897		return &pmu1_xtaltab0_960[PMU1_XTALTAB0_960_40000K];
3898
3899	case BCM4330_CHIP_ID:
3900		/* Default to 37400Khz */
3901		if (CST4330_CHIPMODE_SDIOD(sih->chipst))
3902			return &pmu1_xtaltab0_960[PMU1_XTALTAB0_960_37400K];
3903		else
3904			return &pmu1_xtaltab0_1440[PMU1_XTALTAB0_1440_37400K];
3905	default:
3906		PMU_MSG(("si_pmu1_xtaldef0: Unknown chipid %s\n", bcm_chipname(sih->chip, chn, 8)));
3907		break;
3908	}
3909	ASSERT(0);
3910	return NULL;
3911} /* si_pmu1_xtaldef0 */
3912
3913/** returns chip specific default pll fvco frequency in [khz] units */
3914static uint32
3915BCMINITFN(si_pmu1_pllfvco0)(si_t *sih)
3916{
3917
3918	switch (CHIPID(sih->chip)) {
3919	case BCM4325_CHIP_ID:
3920		return FVCO_880;
3921	case BCM4329_CHIP_ID:
3922		return FVCO_880;
3923	case BCM4315_CHIP_ID:
3924		return FVCO_1760;
3925	case BCM4319_CHIP_ID:
3926		return FVCO_1440;
3927	case BCM4336_CHIP_ID:
3928	case BCM43362_CHIP_ID:
3929	case BCM43239_CHIP_ID:
3930	case BCM4324_CHIP_ID:
3931	case BCM43242_CHIP_ID:
3932	case BCM43243_CHIP_ID:
3933	case BCM4360_CHIP_ID:
3934	case BCM4352_CHIP_ID:
3935	case BCM43460_CHIP_ID:
3936	case BCM43526_CHIP_ID:
3937		return FVCO_960;
3938
3939	case BCM43602_CHIP_ID:
3940	case BCM43462_CHIP_ID:
3941		return FVCO_960;
3942
3943	case BCM4345_CHIP_ID:
3944	case BCM4350_CHIP_ID:
3945	case BCM4354_CHIP_ID:
3946	case BCM4356_CHIP_ID:
3947	case BCM43556_CHIP_ID:
3948	case BCM43558_CHIP_ID:
3949	case BCM43566_CHIP_ID:
3950	case BCM43568_CHIP_ID:
3951	case BCM43569_CHIP_ID:
3952	case BCM43570_CHIP_ID:
3953		return FVCO_963;
3954	case BCM4335_CHIP_ID:
3955	{
3956		osl_t *osh;
3957
3958		osh = si_osh(sih);
3959		return (si_pmu_cal_fvco(sih, osh));
3960	}
3961	case BCM4330_CHIP_ID:
3962		if (CST4330_CHIPMODE_SDIOD(sih->chipst))
3963			return FVCO_960;
3964		else
3965			return FVCO_1440;
3966	default:
3967		PMU_MSG(("si_pmu1_pllfvco0: Unknown chipid %s\n", bcm_chipname(sih->chip, chn, 8)));
3968		break;
3969	}
3970	ASSERT(0);
3971	return 0;
3972} /* si_pmu1_pllfvco0 */
3973
3974/** query alp/xtal clock frequency */
3975static uint32
3976BCMINITFN(si_pmu1_alpclk0)(si_t *sih, osl_t *osh, chipcregs_t *cc)
3977{
3978	const pmu1_xtaltab0_t *xt;
3979	uint32 xf;
3980
3981	/* Find the frequency in the table */
3982	xf = (R_REG(osh, PMUREG(sih, pmucontrol)) & PCTL_XTALFREQ_MASK) >>
3983	        PCTL_XTALFREQ_SHIFT;
3984	for (xt = si_pmu1_xtaltab0(sih); xt != NULL && xt->fref != 0; xt ++)
3985		if (xt->xf == xf)
3986			break;
3987	/* Could not find it so assign a default value */
3988	if (xt == NULL || xt->fref == 0)
3989		xt = si_pmu1_xtaldef0(sih);
3990	ASSERT(xt != NULL && xt->fref != 0);
3991
3992	return xt->fref * 1000;
3993}
3994
3995/**
3996 * Before the PLL is switched off, the HT clocks need to be deactivated, and reactivated
3997 * when the PLL is switched on again.
3998 * This function returns the chip specific HT clock resources (HT and MACPHY clocks).
3999 */
4000static uint32
4001si_pmu_htclk_mask(si_t *sih)
4002{
4003	/* chip specific bit position of various resources */
4004	rsc_per_chip_t *rsc = si_pmu_get_rsc_positions(sih);
4005
4006	uint32 ht_req = (PMURES_BIT(rsc->ht_avail) | PMURES_BIT(rsc->macphy_clkavail));
4007
4008	switch (CHIPID(sih->chip))
4009	{
4010		case BCM4330_CHIP_ID:
4011			ht_req |= PMURES_BIT(RES4330_BBPLL_PWRSW_PU);
4012			break;
4013		case BCM43362_CHIP_ID:  /* Same HT_ vals as 4336 */
4014		case BCM4336_CHIP_ID:
4015			ht_req |= PMURES_BIT(RES4336_BBPLL_PWRSW_PU);
4016			break;
4017		case BCM4335_CHIP_ID:   /* Same HT_ vals as 4350 */
4018		case BCM4345_CHIP_ID:	/* Same HT_ vals as 4350 */
4019		case BCM43602_CHIP_ID:  /* Same HT_ vals as 4350 */
4020		case BCM43462_CHIP_ID:  /* Same HT_ vals as 4350 */
4021		case BCM4350_CHIP_ID:
4022		case BCM4354_CHIP_ID:
4023		case BCM4356_CHIP_ID:
4024		case BCM43556_CHIP_ID:
4025		case BCM43558_CHIP_ID:
4026		case BCM43566_CHIP_ID:
4027		case BCM43568_CHIP_ID:
4028		case BCM43569_CHIP_ID:
4029		case BCM43570_CHIP_ID:
4030			ht_req |= PMURES_BIT(rsc->ht_start);
4031			break;
4032		case BCM43143_CHIP_ID:
4033		case BCM43242_CHIP_ID:
4034			break;
4035		default:
4036			ASSERT(0);
4037			break;
4038	}
4039
4040	return ht_req;
4041} /* si_pmu_htclk_mask */
4042
4043void
4044si_pmu_minresmask_htavail_set(si_t *sih, osl_t *osh, bool set_clear)
4045{
4046	if (!set_clear) {
4047		switch (CHIPID(sih->chip)) {
4048		case BCM4313_CHIP_ID:
4049			if ((R_REG(osh, PMUREG(sih, min_res_mask))) &
4050				(PMURES_BIT(RES4313_HT_AVAIL_RSRC)))
4051				AND_REG(osh, PMUREG(sih, min_res_mask),
4052					~(PMURES_BIT(RES4313_HT_AVAIL_RSRC)));
4053			break;
4054		default:
4055			break;
4056		}
4057	}
4058}
4059
4060uint
4061si_pll_minresmask_reset(si_t *sih, osl_t *osh)
4062{
4063	uint err = BCME_OK;
4064
4065	switch (CHIPID(sih->chip)) {
4066		case BCM4313_CHIP_ID:
4067			/* write to min_res_mask 0x200d : clear min_rsrc_mask */
4068			AND_REG(osh, PMUREG(sih, min_res_mask),
4069				~(PMURES_BIT(RES4313_HT_AVAIL_RSRC)));
4070			OSL_DELAY(100);
4071			/* write to max_res_mask 0xBFFF: clear max_rsrc_mask */
4072			AND_REG(osh, PMUREG(sih, max_res_mask),
4073				~(PMURES_BIT(RES4313_HT_AVAIL_RSRC)));
4074			OSL_DELAY(100);
4075			/* write to max_res_mask 0xFFFF :set max_rsrc_mask */
4076			OR_REG(osh, PMUREG(sih, max_res_mask),
4077				(PMURES_BIT(RES4313_HT_AVAIL_RSRC)));
4078			break;
4079		default:
4080			PMU_ERROR(("%s: PLL reset not supported\n", __FUNCTION__));
4081			err = BCME_UNSUPPORTED;
4082			break;
4083	}
4084	return err;
4085}
4086
4087uint32
4088BCMATTACHFN(si_pmu_def_alp_clock)(si_t *sih, osl_t *osh)
4089{
4090	uint32 clock = ALP_CLOCK;
4091
4092	switch (CHIPID(sih->chip)) {
4093	case BCM4324_CHIP_ID:
4094	case BCM43242_CHIP_ID:
4095	case BCM43243_CHIP_ID:
4096	case BCM4335_CHIP_ID:
4097	case BCM4345_CHIP_ID:
4098	case BCM4350_CHIP_ID:
4099	case BCM4354_CHIP_ID:
4100	case BCM4356_CHIP_ID:
4101	case BCM43556_CHIP_ID:
4102	case BCM43558_CHIP_ID:
4103	case BCM43566_CHIP_ID:
4104	case BCM43568_CHIP_ID:
4105	case BCM43569_CHIP_ID:
4106	case BCM43570_CHIP_ID:
4107		clock = 37400*1000;
4108		break;
4109	case BCM43602_CHIP_ID:
4110	case BCM43462_CHIP_ID:
4111		clock = 40000 * 1000;
4112		break;
4113	}
4114	return clock;
4115}
4116
4117/**
4118 * The BBPLL register set needs to be reprogrammed because the x-tal frequency is not known at
4119 * compile time, or a different spur mode is selected. This function writes appropriate values into
4120 * the BBPLL registers. It returns the 'xf', corresponding to the 'xf' bitfield in the PMU control
4121 * register.
4122 *     'xtal'             : xtal frequency in [KHz]
4123 *     'pllctrlreg_update': contains info on what entries to use in 'pllctrlreg_val' for the given
4124 *                          x-tal frequency and spur mode
4125 *     'pllctrlreg_val'   : contains a superset of the BBPLL values to write
4126 *
4127 * Note: if cc is NULL, this function returns xf, without programming PLL registers.
4128 * This function is only called for pmu1_ type chips, perhaps we should rename it.
4129 */
4130static uint8
4131BCMATTACHFN(si_pmu_pllctrlreg_update)(si_t *sih, osl_t *osh, chipcregs_t *cc, uint32 xtal,
4132            uint8 spur_mode, const pllctrl_data_t *pllctrlreg_update, uint32 array_size,
4133            const uint32 *pllctrlreg_val)
4134{
4135	uint8 indx, reg_offset, xf = 0;
4136	uint8 pll_ctrlcnt = 0;
4137
4138	ASSERT(pllctrlreg_update);
4139
4140	if (sih->pmurev >= 5) {
4141		pll_ctrlcnt = (sih->pmucaps & PCAP5_PC_MASK) >> PCAP5_PC_SHIFT;
4142	} else {
4143		pll_ctrlcnt = (sih->pmucaps & PCAP_PC_MASK) >> PCAP_PC_SHIFT;
4144	}
4145
4146	/* Program the PLL control register if the xtal value matches with the table entry value */
4147	for (indx = 0; indx < array_size; indx++) {
4148		/* If the entry does not match the xtal and spur_mode just continue the loop */
4149		if (!((pllctrlreg_update[indx].clock == (uint16)xtal) &&
4150			(pllctrlreg_update[indx].mode == spur_mode)))
4151			continue;
4152		/*
4153		 * Don't program the PLL registers if register base is NULL.
4154		 * If NULL just return the xref.
4155		 */
4156		if (cc) {
4157			for (reg_offset = 0; reg_offset < pll_ctrlcnt; reg_offset++) {
4158				W_REG(osh, PMUREG(sih, pllcontrol_addr), reg_offset);
4159				W_REG(osh, PMUREG(sih, pllcontrol_data),
4160					pllctrlreg_val[indx*pll_ctrlcnt + reg_offset]);
4161			}
4162		}
4163		xf = pllctrlreg_update[indx].xf;
4164		break;
4165	}
4166	return xf;
4167} /* si_pmu_pllctrlreg_update */
4168
4169static void
4170BCMATTACHFN(si_pmu_set_4345_pllcontrol_regs)(si_t *sih, osl_t *osh, chipcregs_t *cc, uint32 xtal)
4171{
4172/* these defaults come from the recommeded values defined on the 4345 confluence PLL page */
4173/* Backplane/ARM CR4 clock controlled by m3div bits 23:16 of PLL_CONTROL1
4174 * 120Mhz : m3div = 0x8
4175 * 160Mhz : m3div = 0x6
4176 * 240Mhz : m3div = 0x4
4177 */
4178#define PLL_4345_CONTROL0_DEFAULT       0x50800000
4179#define PLL_4345_CONTROL1_DEFAULT       0x0C060803
4180#define PLL_4345_CONTROL2_DEFAULT       0x0CB10806
4181#define PLL_4345_CONTROL3_DEFAULT       0xE2BFA862
4182#define PLL_4345_CONTROL4_DEFAULT       0x02680004
4183#define PLL_4345_CONTROL5_DEFAULT       0x00019AB1
4184#define PLL_4345_CONTROL6_DEFAULT       0x005360C9
4185#define PLL_4345_CONTROL7_DEFAULT       0x000AB1F7
4186
4187	uint32 PLL_control[8] = {
4188		PLL_4345_CONTROL0_DEFAULT, PLL_4345_CONTROL1_DEFAULT,
4189		PLL_4345_CONTROL2_DEFAULT, PLL_4345_CONTROL3_DEFAULT,
4190		PLL_4345_CONTROL4_DEFAULT, PLL_4345_CONTROL5_DEFAULT,
4191		PLL_4345_CONTROL6_DEFAULT, PLL_4345_CONTROL7_DEFAULT
4192	};
4193	uint32 fvco = si_pmu1_pllfvco0(sih);	/* in [khz] */
4194	uint32 ndiv_int;
4195	uint32 ndiv_frac;
4196	uint32 temp_high, temp_low;
4197	uint8 p1div;
4198	uint8 ndiv_mode;
4199	uint8 i;
4200	uint32 min_res_mask = 0, max_res_mask = 0, clk_ctl_st = 0;
4201
4202	ASSERT(cc != NULL);
4203	ASSERT(xtal <= 0xFFFFFFFF / 1000);
4204
4205	/* force the HT off  */
4206	si_pmu_pll_off(sih, osh, cc, &min_res_mask, &max_res_mask, &clk_ctl_st);
4207
4208#ifdef SRFAST
4209	/* HW4345-446: PMU4345: Add support for calibrated internal clock oscillator */
4210	si_pmu_pllcontrol(sih, 1, PMU1_PLL0_PC1_M4DIV_MASK,
4211		PMU1_PLL0_PC1_M4DIV_BY_60 << PMU1_PLL0_PC1_M4DIV_SHIFT);
4212
4213	/* Start SR calibration: enable SR ext clk */
4214	si_pmu_regcontrol(sih, 6, VREG6_4350_SR_EXT_CLKEN_MASK,
4215		(1 << VREG6_4350_SR_EXT_CLKEN_SHIFT));
4216	OSL_DELAY(30); /* Wait 30us */
4217	/* Stop SR calibration: disable SR ext clk */
4218	si_pmu_regcontrol(sih, 6, VREG6_4350_SR_EXT_CLKEN_MASK,
4219		(0 << VREG6_4350_SR_EXT_CLKEN_SHIFT));
4220#endif
4221
4222	/* xtal and FVCO are in kHz.  xtal/p1div must be <= 50MHz */
4223	p1div = 1 + (uint8) ((xtal * 1000) / 50000000UL);
4224	ndiv_int = (fvco * p1div) / xtal;
4225
4226	/* ndiv_frac = (uint32) (((uint64) (fvco * p1div - xtal * ndiv_int) * (1 << 24)) / xtal) */
4227	bcm_uint64_multiple_add(&temp_high, &temp_low, fvco * p1div - xtal * ndiv_int, 1 << 24, 0);
4228	bcm_uint64_divide(&ndiv_frac, temp_high, temp_low, xtal);
4229
4230	ndiv_mode = (ndiv_frac == 0) ? 0 : 3;
4231
4232	/* change PLL_control[2] and PLL_control[3] */
4233	PLL_control[2] = (PLL_4345_CONTROL2_DEFAULT & 0x0000FFFF) |
4234	                 (p1div << 16) | (ndiv_mode << 20) | (ndiv_int << 23);
4235	PLL_control[3] = (PLL_4345_CONTROL3_DEFAULT & 0xFF000000) | ndiv_frac;
4236
4237	/* TODO - set PLL control field in PLL_control[3] & PLL_control[4] */
4238
4239	/* HSIC DFLL freq_target N_divide_ratio = 4096 * FVCO / xtal */
4240	fvco = FVCO_960;	/* USB/HSIC FVCO is always 960 MHz, regardless of BB FVCO */
4241	PLL_control[5] = (PLL_4345_CONTROL5_DEFAULT & 0xFFF00000) |
4242	                 ((((uint32) fvco << 12) / xtal) & 0x000FFFFF);
4243
4244	ndiv_int = (fvco * p1div) / xtal;
4245
4246	/*
4247	 * ndiv_frac = (uint32) (((uint64) (fvco * p1div - xtal * ndiv_int) * (1 << 20)) /
4248	 *                       xtal)
4249	 */
4250	bcm_uint64_multiple_add(&temp_high, &temp_low, fvco * p1div - xtal * ndiv_int, 1 << 20, 0);
4251	bcm_uint64_divide(&ndiv_frac, temp_high, temp_low, xtal);
4252
4253	/* change PLL_control[6] */
4254	PLL_control[6] = (PLL_4345_CONTROL6_DEFAULT & 0xFFFFE000) | p1div | (ndiv_int << 3);
4255
4256	/* change PLL_control[7] */
4257	PLL_control[7] = ndiv_frac;
4258
4259	/* write PLL Control Regs */
4260	PMU_MSG(("xtal    PLLCTRL0   PLLCTRL1   PLLCTRL2   PLLCTRL3"));
4261	PMU_MSG(("   PLLCTRL4   PLLCTRL5   PLLCTRL6   PLLCTRL7\n"));
4262	PMU_MSG(("%d ", xtal));
4263	for (i = 0; i < 6; i++) {
4264		PMU_MSG((" 0x%08X", PLL_control[i]));
4265		W_REG(osh, PMUREG(sih, pllcontrol_addr), i);
4266		W_REG(osh, PMUREG(sih, pllcontrol_data), PLL_control[i]);
4267	}
4268	PMU_MSG(("\n"));
4269
4270	/* Now toggle pllctlupdate so the pll sees the new values */
4271	si_pmu_pllupd(sih);
4272
4273	/* Need to toggle PLL's dreset_i signal to ensure output clocks are aligned */
4274	si_pmu_chipcontrol(sih, CHIPCTRLREG1, (1<<6), (0<<6));
4275	si_pmu_chipcontrol(sih, CHIPCTRLREG1, (1<<6), (1<<6));
4276	si_pmu_chipcontrol(sih, CHIPCTRLREG1, (1<<6), (0<<6));
4277
4278	/* enable HT back on  */
4279	si_pmu_pll_on(sih, osh, cc, min_res_mask, max_res_mask, clk_ctl_st);
4280} /* si_pmu_set_4345_pllcontrol_regs */
4281
4282/**
4283 * Chip-specific overrides to PLLCONTROL registers during init. If certain conditions (dependent on
4284 * x-tal frequency and current ALP frequency) are met, an update of the PLL is required.
4285 *
4286 * This takes less precedence over OTP PLLCONTROL overrides.
4287 * If update_required=FALSE, it returns TRUE if a update is about to occur.
4288 * No write happens.
4289 *
4290 * Return value: TRUE if the BBPLL registers 'update' field should be written by the caller.
4291 *
4292 * This function is only called for pmu1_ type chips, perhaps we should rename it.
4293 */
4294bool
4295BCMATTACHFN(si_pmu_update_pllcontrol)(si_t *sih, osl_t *osh, uint32 xtal, bool update_required)
4296{
4297	chipcregs_t *cc;
4298	uint origidx;
4299	bool write_en = FALSE;
4300	uint8 xf = 0;
4301	const pmu1_xtaltab0_t *xt;
4302	uint32 tmp, buf_strength = 0;
4303	const pllctrl_data_t *pllctrlreg_update = NULL;
4304	uint32 array_size = 0;
4305	/* points at a set of PLL register values to write for a given x-tal frequency: */
4306	const uint32 *pllctrlreg_val = NULL;
4307	uint8 ndiv_mode = PMU1_PLL0_PC2_NDIV_MODE_MASH;
4308	uint32 xtalfreq = 0;
4309
4310	/* If there is OTP or NVRAM entry for xtalfreq, program the
4311	 * PLL control register even if it is default xtal.
4312	 */
4313	xtalfreq = getintvar(NULL, rstr_xtalfreq);
4314	/* CASE1 */
4315	if (xtalfreq) {
4316		write_en = TRUE;
4317		xtal = xtalfreq;
4318	} else {
4319		/* There is NO OTP value */
4320		if (xtal) {
4321			/* CASE2: If the xtal value was calculated, program the PLL control
4322			 * registers only if it is not default xtal value.
4323			 */
4324			if (xtal != (si_pmu_def_alp_clock(sih, osh)/1000))
4325				write_en = TRUE;
4326		} else {
4327			/* CASE3: If the xtal obtained is "0", ie., clock is not measured, then
4328			 * leave the PLL control register as it is but program the xf in
4329			 * pmucontrol register with the default xtal value.
4330			 */
4331			xtal = si_pmu_def_alp_clock(sih, osh)/1000;
4332		}
4333	}
4334
4335	switch (CHIPID(sih->chip)) {
4336	case BCM43239_CHIP_ID:
4337#ifndef BCM_BOOTLOADER
4338		write_en = TRUE;
4339#endif
4340		break;
4341
4342	case BCM4335_CHIP_ID:
4343#ifdef BCM_BOOTLOADER
4344		pllctrlreg_update = pmu1_xtaltab0_4335;
4345		array_size = ARRAYSIZE(pmu1_xtaltab0_4335);
4346		pllctrlreg_val = pmu1_pllctrl_tab_4335_960mhz;
4347#else /* BCM_BOOTLOADER */
4348		pllctrlreg_update = pmu1_xtaltab0_4335_drv;
4349		array_size = ARRAYSIZE(pmu1_xtaltab0_4335_drv);
4350		if (sih->chippkg == BCM4335_WLBGA_PKG_ID) {
4351			pllctrlreg_val = pmu1_pllctrl_tab_4335_968mhz;
4352		} else {
4353			if (CHIPREV(sih->chiprev) <= 1) {
4354				/* for 4335 Ax/Bx Chips */
4355				pllctrlreg_val = pmu1_pllctrl_tab_4335_961mhz;
4356			} else if (CHIPREV(sih->chiprev) == 2) {
4357				/* for 4335 Cx chips */
4358				pllctrlreg_val = pmu1_pllctrl_tab_4335_968mhz;
4359			}
4360		}
4361#endif /* BCM_BOOTLOADER */
4362
4363#ifndef BCM_BOOTLOADER
4364		/* If PMU1_PLL0_PC2_MxxDIV_MASKxx have to change,
4365		 * then set write_en to true.
4366		 */
4367		write_en = TRUE;
4368#endif
4369		break;
4370
4371	case BCM4345_CHIP_ID:
4372		pllctrlreg_update = pmu1_xtaltab0_4345;
4373		array_size = ARRAYSIZE(pmu1_xtaltab0_4345);
4374		/* Note: no pllctrlreg_val table, because the PLL ctrl regs are calculated */
4375
4376#ifndef BCM_BOOTLOADER
4377		/* If PMU1_PLL0_PC2_MxxDIV_MASKxx have to change,
4378		 * then set write_en to true.
4379		 */
4380		write_en = TRUE;
4381#endif
4382		break;
4383
4384	case BCM4350_CHIP_ID:
4385	case BCM4354_CHIP_ID:
4386	case BCM4356_CHIP_ID:
4387	case BCM43556_CHIP_ID:
4388	case BCM43558_CHIP_ID:
4389	case BCM43566_CHIP_ID:
4390	case BCM43568_CHIP_ID:
4391	case BCM43569_CHIP_ID:
4392	case BCM43570_CHIP_ID:
4393		pllctrlreg_update = pmu1_xtaltab0_4350;
4394		array_size = ARRAYSIZE(pmu1_xtaltab0_4350);
4395
4396		if (CHIPID(sih->chip) == BCM4354_CHIP_ID ||
4397			CHIPID(sih->chip) == BCM4356_CHIP_ID ||
4398			CHIPID(sih->chip) == BCM43569_CHIP_ID ||
4399			CHIPID(sih->chip) == BCM43570_CHIP_ID)
4400			pllctrlreg_val = pmu1_pllctrl_tab_4350C0_963mhz;
4401		else {
4402			if (CHIPREV(sih->chiprev) >= 3)
4403				pllctrlreg_val = pmu1_pllctrl_tab_4350C0_963mhz;
4404			else
4405				pllctrlreg_val = pmu1_pllctrl_tab_4350_963mhz;
4406		}
4407
4408		/* If PMU1_PLL0_PC2_MxxDIV_MASKxx have to change,
4409		 * then set write_en to true.
4410		 */
4411#ifdef BCMUSB_NODISCONNECT
4412		write_en = FALSE;
4413#else
4414		write_en = TRUE;
4415#endif
4416#ifdef BCM_BOOTLOADER
4417		/* Bootloader need to change pll if it is not default 37.4M */
4418		if (xtal == XTAL_DEFAULT_4350)
4419			write_en = FALSE;
4420#endif /*  BCM_BOOTLOADER */
4421		break;
4422
4423	case BCM43242_CHIP_ID:
4424	case BCM43243_CHIP_ID:
4425		pllctrlreg_update = pmu1_xtaltab0_43242;
4426		array_size = ARRAYSIZE(pmu1_xtaltab0_43242);
4427		if (CHIPREV(sih->chiprev) == 0) {
4428			pllctrlreg_val = pmu1_pllctrl_tab_43242A0;
4429		} else {
4430			pllctrlreg_val = pmu1_pllctrl_tab_43242A1;
4431		}
4432		write_en = TRUE;
4433		break;
4434	case BCM43602_CHIP_ID:
4435	case BCM43462_CHIP_ID:
4436		/*
4437		 * XXX43602 has only 1 x-tal value, possibly insert case when an other BBPLL
4438		 * frequency than 960Mhz is required (e.g., for spur avoidance)
4439		 */
4440		 /* fall through */
4441	default:
4442		/* write_en is FALSE in this case. So returns from the function */
4443		write_en = FALSE;
4444		break;
4445	}
4446
4447	/* Remember original core before switch to chipc */
4448	origidx = si_coreidx(sih);
4449	cc = si_setcoreidx(sih, SI_CC_IDX);
4450	ASSERT(cc != NULL);
4451
4452	/* Check if the table has PLL control register values for the requested
4453	 * xtal. NOTE THAT, THIS IS not DONE FOR 43239,
4454	 * AS IT HAS ONLY ONE XTAL SUPPORT.
4455	 */
4456	if (!update_required && pllctrlreg_update) {
4457		/* Here the chipcommon register base is passed as NULL, so that we just get
4458		 * the xf for the xtal being programmed but don't program the registers now
4459		 * as the PLL is not yet turned OFF.
4460		 */
4461		xf = si_pmu_pllctrlreg_update(sih, osh, NULL, xtal, 0, pllctrlreg_update,
4462			array_size, pllctrlreg_val);
4463
4464		/* Program the PLL based on the xtal value. */
4465		if (xf != 0) {
4466			/* Write XtalFreq. Set the divisor also. */
4467			tmp = R_REG(osh, PMUREG(sih, pmucontrol)) &
4468				~(PCTL_ILP_DIV_MASK | PCTL_XTALFREQ_MASK);
4469			tmp |= (((((xtal + 127) / 128) - 1) << PCTL_ILP_DIV_SHIFT) &
4470				PCTL_ILP_DIV_MASK) |
4471				((xf << PCTL_XTALFREQ_SHIFT) & PCTL_XTALFREQ_MASK);
4472			W_REG(osh, PMUREG(sih, pmucontrol), tmp);
4473		} else {
4474			write_en = FALSE;
4475			printf(rstr_Invalid_Unsupported_xtal_value_D, xtal);
4476		}
4477	}
4478
4479	/* If its a check sequence or if there is nothing to write, return here */
4480	if ((update_required == FALSE) || (write_en == FALSE)) {
4481		goto exit;
4482	}
4483
4484	/* Update the PLL control register based on the xtal used. */
4485	if (pllctrlreg_val) {
4486		si_pmu_pllctrlreg_update(sih, osh, cc, xtal, 0, pllctrlreg_update, array_size,
4487			pllctrlreg_val);
4488	}
4489
4490	/* Chip specific changes to PLL Control registers is done here. */
4491	switch (CHIPID(sih->chip)) {
4492	case BCM43239_CHIP_ID:
4493#ifndef BCM_BOOTLOADER
4494		/* 43239: Change backplane and dot11mac clock to 120Mhz */
4495		si_pmu_pllcontrol(sih, PMU1_PLL0_PLLCTL2,
4496		  (PMU1_PLL0_PC2_M5DIV_MASK | PMU1_PLL0_PC2_M6DIV_MASK),
4497		  ((8 << PMU1_PLL0_PC2_M5DIV_SHIFT) | (8 << PMU1_PLL0_PC2_M6DIV_SHIFT)));
4498#endif
4499		/* To ensure the PLL control registers are not modified from what is default. */
4500		xtal = 0;
4501		break;
4502	case BCM4324_CHIP_ID:
4503#ifndef BCM_BOOTLOADER
4504		/* Change backplane clock (ARM input) to 137Mhz */
4505		si_pmu_pllcontrol(sih, PMU1_PLL0_PLLCTL1, PMU1_PLL0_PC1_M2DIV_MASK,
4506			(7 << PMU1_PLL0_PC1_M2DIV_SHIFT));
4507#endif
4508		break;
4509	case BCM43242_CHIP_ID:
4510	case BCM43243_CHIP_ID:
4511#ifndef BCM_BOOTLOADER
4512		/* Change backplane clock (ARM input) to 137Mhz */
4513		si_pmu_pllcontrol(sih, PMU1_PLL0_PLLCTL1, PMU1_PLL0_PC1_M2DIV_MASK,
4514			(7 << PMU1_PLL0_PC1_M2DIV_SHIFT));
4515#endif
4516		break;
4517	case BCM4345_CHIP_ID:
4518		si_pmu_set_4345_pllcontrol_regs(sih, osh, cc, xtal);
4519		/* To ensure the PLL control registers are not modified from what is default. */
4520		xtal = 0;
4521		break;
4522	default:
4523		break;
4524	}
4525
4526	/* Program the PLL based on the xtal value. */
4527	if (xtal != 0) {
4528
4529		/* Find the frequency in the table */
4530		for (xt = si_pmu1_xtaltab0(sih); xt != NULL && xt->fref != 0; xt ++)
4531			if (xt->fref == xtal)
4532				break;
4533
4534		/* Check current PLL state, bail out if it has been programmed or
4535		 * we don't know how to program it. But we might still have some programming
4536		 * like changing the ARM clock, etc. So cannot return from here.
4537		 */
4538		if (xt == NULL || xt->fref == 0)
4539			goto exit;
4540
4541		/* If the PLL is already programmed exit from here. */
4542		if (((R_REG(osh, PMUREG(sih, pmucontrol)) &
4543			PCTL_XTALFREQ_MASK) >> PCTL_XTALFREQ_SHIFT) == xt->xf)
4544			goto exit;
4545
4546		PMU_MSG(("XTAL %d.%d MHz (%d)\n", xtal / 1000, xtal % 1000, xt->xf));
4547		PMU_MSG(("Programming PLL for %d.%d MHz\n", xt->fref / 1000, xt->fref % 1000));
4548
4549		/* Write p1div and p2div to pllcontrol[0] */
4550		tmp = ((xt->p1div << PMU1_PLL0_PC0_P1DIV_SHIFT) & PMU1_PLL0_PC0_P1DIV_MASK) |
4551			((xt->p2div << PMU1_PLL0_PC0_P2DIV_SHIFT) & PMU1_PLL0_PC0_P2DIV_MASK);
4552		si_pmu_pllcontrol(sih, PMU1_PLL0_PLLCTL0,
4553			(PMU1_PLL0_PC0_P1DIV_MASK | PMU1_PLL0_PC0_P2DIV_MASK), tmp);
4554
4555		/* Write ndiv_int and ndiv_mode to pllcontrol[2] */
4556		tmp = ((xt->ndiv_int << PMU1_PLL0_PC2_NDIV_INT_SHIFT)
4557				& PMU1_PLL0_PC2_NDIV_INT_MASK) |
4558				((ndiv_mode << PMU1_PLL0_PC2_NDIV_MODE_SHIFT)
4559				& PMU1_PLL0_PC2_NDIV_MODE_MASK);
4560		si_pmu_pllcontrol(sih, PMU1_PLL0_PLLCTL2,
4561			(PMU1_PLL0_PC2_NDIV_INT_MASK | PMU1_PLL0_PC2_NDIV_MODE_MASK), tmp);
4562
4563		/* Write ndiv_frac to pllcontrol[3] */
4564		tmp = ((xt->ndiv_frac << PMU1_PLL0_PC3_NDIV_FRAC_SHIFT) &
4565			PMU1_PLL0_PC3_NDIV_FRAC_MASK);
4566		si_pmu_pllcontrol(sih, PMU1_PLL0_PLLCTL3, PMU1_PLL0_PC3_NDIV_FRAC_MASK, tmp);
4567
4568		/* Write clock driving strength to pllcontrol[5] */
4569		if (buf_strength) {
4570			PMU_MSG(("Adjusting PLL buffer drive strength: %x\n", buf_strength));
4571
4572			tmp = (buf_strength << PMU1_PLL0_PC5_CLK_DRV_SHIFT);
4573			si_pmu_pllcontrol(sih, PMU1_PLL0_PLLCTL5, PMU1_PLL0_PC5_CLK_DRV_MASK, tmp);
4574		}
4575
4576		/* Write XtalFreq. Set the divisor also. */
4577		tmp = R_REG(osh, PMUREG(sih, pmucontrol)) &
4578			~(PCTL_ILP_DIV_MASK | PCTL_XTALFREQ_MASK);
4579		tmp |= (((((xt->fref + 127) / 128) - 1) << PCTL_ILP_DIV_SHIFT) &
4580			PCTL_ILP_DIV_MASK) |
4581			((xt->xf << PCTL_XTALFREQ_SHIFT) & PCTL_XTALFREQ_MASK);
4582		W_REG(osh, PMUREG(sih, pmucontrol), tmp);
4583	}
4584
4585exit:
4586	/* Return to original core */
4587	si_setcoreidx(sih, origidx);
4588
4589	return write_en;
4590} /* si_pmu_update_pllcontrol */
4591
4592uint32
4593si_pmu_get_pmutimer(si_t *sih, osl_t *osh, chipcregs_t *cc)
4594{
4595	uint32 start;
4596	start = R_REG(osh, PMUREG(sih, pmutimer));
4597	if (start != R_REG(osh, PMUREG(sih, pmutimer)))
4598		start = R_REG(osh, PMUREG(sih, pmutimer));
4599	return (start);
4600}
4601
4602/* returns
4603 * a) diff between a 'prev' value of pmu timer and current value
4604 * b) the current pmutime value in 'prev'
4605 * 	So, 'prev' is an IO parameter.
4606 */
4607uint32
4608si_pmu_get_pmutime_diff(si_t *sih, osl_t *osh, chipcregs_t *cc, uint32 *prev)
4609{
4610	uint32 pmutime_diff = 0, pmutime_val = 0;
4611	uint32 prev_val = *prev;
4612
4613	/* read current value */
4614	pmutime_val = si_pmu_get_pmutimer(sih, osh, cc);
4615	/* diff btween prev and current value, take on wraparound case as well. */
4616	pmutime_diff = (pmutime_val >= prev_val) ?
4617		(pmutime_val - prev_val) :
4618		(~prev_val + pmutime_val + 1);
4619	*prev = pmutime_val;
4620	return pmutime_diff;
4621}
4622
4623/** wait for usec for the res_pending register to change. */
4624/*
4625	NOTE: usec SHOULD be > 32uS
4626	if cond = TRUE, res_pending will be read until it becomes == 0;
4627	If cond = FALSE, res_pending will be read until it becomes != 0;
4628	returns TRUE if timedout.
4629	returns elapsed time in this loop in elapsed_time
4630*/
4631bool
4632si_pmu_wait_for_res_pending(si_t *sih, osl_t *osh, chipcregs_t *cc, uint usec,
4633	bool cond, uint32 *elapsed_time)
4634{
4635	/* add 32uSec more */
4636	uint countdown = usec;
4637	uint32 pmutime_prev = 0, pmutime_elapsed = 0, res_pend;
4638	bool pending = FALSE;
4639
4640	/* store current time */
4641	pmutime_prev = si_pmu_get_pmutimer(sih, osh, cc);
4642	while (1) {
4643		res_pend = R_REG(osh, PMUREG(sih, res_pending));
4644
4645		/* based on the condition, check */
4646		if (cond == TRUE) {
4647			if (res_pend == 0) break;
4648		} else {
4649			if (res_pend != 0) break;
4650		}
4651
4652		/* if required time over */
4653		if ((pmutime_elapsed * PMU_US_STEPS) >= countdown) {
4654			/* timeout. so return as still pending */
4655			pending = TRUE;
4656			break;
4657		}
4658
4659		/* get elapsed time after adding diff between prev and current
4660		* pmutimer value
4661		*/
4662		pmutime_elapsed += si_pmu_get_pmutime_diff(sih, osh, cc, &pmutime_prev);
4663	}
4664
4665	*elapsed_time = pmutime_elapsed * PMU_US_STEPS;
4666	return pending;
4667} /* si_pmu_wait_for_res_pending */
4668
4669/**
4670 *	The algorithm for pending check is that,
4671 *	step1: 	wait till (res_pending !=0) OR pmu_max_trans_timeout.
4672 *			if max_trans_timeout, flag error and exit.
4673 *			wait for 1 ILP clk [64uS] based on pmu timer,
4674 *			polling to see if res_pending again goes high.
4675 *			if res_pending again goes high, go back to step1.
4676 *	Note: res_pending is checked repeatedly because, in between switching
4677 *	of dependent
4678 *	resources, res_pending resets to 0 for a short duration of time before
4679 *	it becomes 1 again.
4680 *	Note: return 0 is GOOD, 1 is BAD [mainly timeout].
4681 */
4682int si_pmu_wait_for_steady_state(si_t *sih, osl_t *osh, chipcregs_t *cc)
4683{
4684	int stat = 0;
4685	bool timedout = FALSE;
4686	uint32 elapsed = 0, pmutime_total_elapsed = 0;
4687
4688	while (1) {
4689		/* wait until all resources are settled down [till res_pending becomes 0] */
4690		timedout = si_pmu_wait_for_res_pending(sih, osh, cc,
4691			PMU_MAX_TRANSITION_DLY, TRUE, &elapsed);
4692
4693		if (timedout) {
4694			stat = 1;
4695			break;
4696		}
4697
4698		pmutime_total_elapsed += elapsed;
4699		/* wait to check if any resource comes back to non-zero indicating
4700		* that it pends again. The res_pending goes 0 for 1 ILP clock before
4701		* getting set for next resource in the sequence , so if res_pending
4702		* is 0 for more than 1 ILP clk it means nothing is pending
4703		* to indicate some pending dependency.
4704		*/
4705		timedout = si_pmu_wait_for_res_pending(sih, osh, cc,
4706			64, FALSE, &elapsed);
4707
4708		pmutime_total_elapsed += elapsed;
4709		/* Here, we can also check timedout, but we make sure that,
4710		* we read the res_pending again.
4711		*/
4712		if (timedout) {
4713			stat = 0;
4714			break;
4715		}
4716
4717		/* Total wait time for all the waits above added should be
4718		* less than  PMU_MAX_TRANSITION_DLY
4719		*/
4720		if (pmutime_total_elapsed >= PMU_MAX_TRANSITION_DLY) {
4721			/* timeout. so return as still pending */
4722			stat = 1;
4723			break;
4724		}
4725	}
4726	return stat;
4727} /* si_pmu_wait_for_steady_state */
4728
4729/** Turn Off the PLL - Required before setting the PLL registers */
4730static void
4731si_pmu_pll_off(si_t *sih, osl_t *osh, chipcregs_t *cc, uint32 *min_mask,
4732	uint32 *max_mask, uint32 *clk_ctl_st)
4733{
4734	uint32 ht_req;
4735
4736	/* Save the original register values */
4737	*min_mask = R_REG(osh, PMUREG(sih, min_res_mask));
4738	*max_mask = R_REG(osh, PMUREG(sih, max_res_mask));
4739	*clk_ctl_st = R_REG(osh, &cc->clk_ctl_st);
4740
4741	ht_req = si_pmu_htclk_mask(sih);
4742	if (ht_req == 0)
4743		return;
4744
4745	if ((CHIPID(sih->chip) == BCM4335_CHIP_ID) ||
4746		(CHIPID(sih->chip) == BCM4345_CHIP_ID) ||
4747		(CHIPID(sih->chip) == BCM43602_CHIP_ID) ||
4748		(CHIPID(sih->chip) == BCM43462_CHIP_ID) ||
4749		BCM4350_CHIP(sih->chip) ||
4750	0) {
4751		/* slightly different way for 4335, but this could be applied for other chips also.
4752		* If HT_AVAIL is not set, wait to see if any resources are availing HT.
4753		*/
4754		if (((R_REG(osh, &cc->clk_ctl_st) & CCS_HTAVAIL) != CCS_HTAVAIL))
4755			si_pmu_wait_for_steady_state(sih, osh, cc);
4756	} else {
4757		OR_REG(osh,  PMUREG(sih, max_res_mask), ht_req);
4758		/* wait for HT to be ready before taking the HT away...HT could be coming up... */
4759		SPINWAIT(((R_REG(osh, &cc->clk_ctl_st) & CCS_HTAVAIL) != CCS_HTAVAIL),
4760			PMU_MAX_TRANSITION_DLY);
4761		ASSERT((R_REG(osh, &cc->clk_ctl_st) & CCS_HTAVAIL));
4762	}
4763
4764	AND_REG(osh, PMUREG(sih, min_res_mask), ~ht_req);
4765	AND_REG(osh, PMUREG(sih, max_res_mask), ~ht_req);
4766
4767	SPINWAIT(((R_REG(osh, &cc->clk_ctl_st) & CCS_HTAVAIL) == CCS_HTAVAIL),
4768		PMU_MAX_TRANSITION_DLY);
4769	ASSERT(!(R_REG(osh, &cc->clk_ctl_st) & CCS_HTAVAIL));
4770	OSL_DELAY(100);
4771} /* si_pmu_pll_off */
4772
4773/* below function are for BBPLL parallel purpose */
4774/** Turn Off the PLL - Required before setting the PLL registers */
4775void
4776si_pmu_pll_off_PARR(si_t *sih, osl_t *osh, uint32 *min_mask,
4777uint32 *max_mask, uint32 *clk_ctl_st)
4778{
4779	chipcregs_t *cc;
4780	uint origidx, intr_val;
4781	uint32 ht_req;
4782
4783	/* Remember original core before switch to chipc */
4784	cc = (chipcregs_t *)si_switch_core(sih, CC_CORE_ID, &origidx, &intr_val);
4785	ASSERT(cc != NULL);
4786
4787	/* Save the original register values */
4788	*min_mask = R_REG(osh, PMUREG(sih, min_res_mask));
4789	*max_mask = R_REG(osh, PMUREG(sih, max_res_mask));
4790	*clk_ctl_st = R_REG(osh, &cc->clk_ctl_st);
4791	ht_req = si_pmu_htclk_mask(sih);
4792	if (ht_req == 0)
4793		return;
4794
4795	if ((CHIPID(sih->chip) == BCM4335_CHIP_ID) ||
4796		(CHIPID(sih->chip) == BCM4345_CHIP_ID) ||
4797		(CHIPID(sih->chip) == BCM43602_CHIP_ID) ||
4798		(CHIPID(sih->chip) == BCM43462_CHIP_ID) ||
4799		BCM4350_CHIP(sih->chip) ||
4800	0) {
4801		/* slightly different way for 4335, but this could be applied for other chips also.
4802		* If HT_AVAIL is not set, wait to see if any resources are availing HT.
4803		*/
4804		if (((R_REG(osh, &cc->clk_ctl_st) & CCS_HTAVAIL) != CCS_HTAVAIL))
4805			si_pmu_wait_for_steady_state(sih, osh, cc);
4806	} else {
4807		OR_REG(osh,  PMUREG(sih, max_res_mask), ht_req);
4808		/* wait for HT to be ready before taking the HT away...HT could be coming up... */
4809		SPINWAIT(((R_REG(osh, &cc->clk_ctl_st) & CCS_HTAVAIL) != CCS_HTAVAIL),
4810			PMU_MAX_TRANSITION_DLY);
4811		ASSERT((R_REG(osh, &cc->clk_ctl_st) & CCS_HTAVAIL));
4812	}
4813
4814	AND_REG(osh, PMUREG(sih, min_res_mask), ~ht_req);
4815	AND_REG(osh, PMUREG(sih, max_res_mask), ~ht_req);
4816
4817	/* Return to original core */
4818	si_restore_core(sih, origidx, intr_val);
4819} /* si_pmu_pll_off_PARR */
4820
4821
4822static void
4823si_pmu_pll_off_isdone(si_t *sih, osl_t *osh, chipcregs_t *cc)
4824{
4825	uint32 ht_req;
4826	ht_req = si_pmu_htclk_mask(sih);
4827	SPINWAIT(((R_REG(osh, PMUREG(sih, res_state)) & ht_req) != 0),
4828	PMU_MAX_TRANSITION_DLY);
4829	SPINWAIT(((R_REG(osh, &cc->clk_ctl_st) & CCS_HTAVAIL) == CCS_HTAVAIL),
4830		PMU_MAX_TRANSITION_DLY);
4831	ASSERT(!(R_REG(osh, &cc->clk_ctl_st) & CCS_HTAVAIL));
4832
4833}
4834
4835/* above function are for BBPLL parallel purpose */
4836
4837/** Turn ON/restore the PLL based on the mask received */
4838static void
4839si_pmu_pll_on(si_t *sih, osl_t *osh, chipcregs_t *cc, uint32 min_mask_mask,
4840	uint32 max_mask_mask, uint32 clk_ctl_st_mask)
4841{
4842	uint32 ht_req;
4843
4844	ht_req = si_pmu_htclk_mask(sih);
4845	if (ht_req == 0)
4846		return;
4847
4848	max_mask_mask &= ht_req;
4849	min_mask_mask &= ht_req;
4850
4851	if (max_mask_mask != 0)
4852		OR_REG(osh, PMUREG(sih, max_res_mask), max_mask_mask);
4853
4854	if (min_mask_mask != 0)
4855		OR_REG(osh, PMUREG(sih, min_res_mask), min_mask_mask);
4856
4857	if (clk_ctl_st_mask & CCS_HTAVAIL) {
4858		/* Wait for HT_AVAIL to come back */
4859		SPINWAIT(((R_REG(osh, &cc->clk_ctl_st) & CCS_HTAVAIL) != CCS_HTAVAIL),
4860			PMU_MAX_TRANSITION_DLY);
4861		ASSERT((R_REG(osh, &cc->clk_ctl_st) & CCS_HTAVAIL));
4862	}
4863}
4864
4865/**
4866 * Caller wants to know the default values to program into BB PLL/FLL hardware for a specific chip.
4867 *
4868 * The relation between x-tal frequency, HT clock and divisor values to write into the PLL hardware
4869 * is given by a set of tables, one table per PLL/FLL frequency (480/485 Mhz).
4870 *
4871 * This function returns the table entry corresponding with the (chip specific) default x-tal
4872 * frequency.
4873 */
4874static const pmu2_xtaltab0_t *
4875BCMINITFN(si_pmu2_xtaldef0)(si_t *sih)
4876{
4877	switch (CHIPID(sih->chip)) {
4878	case BCM4314_CHIP_ID:
4879	case BCM43142_CHIP_ID:
4880	case BCM43143_CHIP_ID:
4881#ifdef BCM_BOOTLOADER
4882		return &pmu2_xtaltab0_adfll_480[PMU15_XTALTAB0_20000K];
4883#else
4884		if (ISSIM_ENAB(sih))
4885			return &pmu2_xtaltab0_adfll_480[PMU15_XTALTAB0_20000K];
4886		else
4887			return &pmu2_xtaltab0_adfll_485[PMU15_XTALTAB0_20000K];
4888#endif
4889	case BCM43341_CHIP_ID:
4890	case BCM4334_CHIP_ID:
4891#ifdef BCM_BOOTLOADER
4892		return &pmu2_xtaltab0_adfll_480[PMU15_XTALTAB0_37400K];
4893#else
4894		if (ISSIM_ENAB(sih))
4895			return &pmu2_xtaltab0_adfll_480[PMU15_XTALTAB0_37400K];
4896		else
4897			return &pmu2_xtaltab0_adfll_485[PMU15_XTALTAB0_37400K];
4898#endif
4899	default:
4900		break;
4901	}
4902
4903	ASSERT(0);
4904	return NULL;
4905}
4906
4907static const pmu2_xtaltab0_t *
4908BCMINITFN(si_pmu2_xtaltab0)(si_t *sih)
4909{
4910	switch (CHIPID(sih->chip)) {
4911	case BCM4314_CHIP_ID:
4912	case BCM43142_CHIP_ID:
4913	case BCM43143_CHIP_ID:
4914	case BCM43341_CHIP_ID:
4915	case BCM4334_CHIP_ID:
4916#ifdef BCM_BOOTLOADER
4917		return pmu2_xtaltab0_adfll_480;
4918#else
4919		if (ISSIM_ENAB(sih))
4920			return pmu2_xtaltab0_adfll_480;
4921		else
4922			return pmu2_xtaltab0_adfll_485;
4923#endif
4924	default:
4925		break;
4926	}
4927
4928	ASSERT(0);
4929	return NULL;
4930}
4931
4932/** For hardware workarounds, OTP can contain an entry to update FLL control registers */
4933static void
4934BCMATTACHFN(si_pmu2_pll_vars_init)(si_t *sih, osl_t *osh, chipcregs_t *cc)
4935{
4936	char name[16];
4937	const char *otp_val;
4938	uint8 i, otp_entry_found = FALSE;
4939	uint32 pll_ctrlcnt;
4940	uint32 min_mask = 0, max_mask = 0, clk_ctl_st = 0;
4941
4942	if (sih->pmurev >= 5) {
4943		pll_ctrlcnt = (sih->pmucaps & PCAP5_PC_MASK) >> PCAP5_PC_SHIFT;
4944	}
4945	else {
4946		pll_ctrlcnt = (sih->pmucaps & PCAP_PC_MASK) >> PCAP_PC_SHIFT;
4947	}
4948
4949	/* Check if there is any otp enter for PLLcontrol registers */
4950	for (i = 0; i < pll_ctrlcnt; i++) {
4951		snprintf(name, sizeof(name), rstr_pllD, i);
4952		if ((otp_val = getvar(NULL, name)) == NULL)
4953			continue;
4954
4955		/* If OTP entry is found for PLL register, then turn off the PLL
4956		 * and set the status of the OTP entry accordingly.
4957		 */
4958		otp_entry_found = TRUE;
4959		break;
4960	}
4961
4962	/* If no OTP parameter is found, return. */
4963	if (otp_entry_found == FALSE)
4964		return;
4965
4966	/* Make sure PLL is off */
4967	si_pmu_pll_off(sih, osh, cc, &min_mask, &max_mask, &clk_ctl_st);
4968
4969	/* Update the PLL register if there is a OTP entry for PLL registers */
4970	si_pmu_otp_pllcontrol(sih, osh);
4971
4972	/* Flush deferred pll control registers writes */
4973	if (sih->pmurev >= 2)
4974		OR_REG(osh, PMUREG(sih, pmucontrol), PCTL_PLL_PLLCTL_UPD);
4975
4976	/* Restore back the register values. This ensures PLL remains on if it
4977	 * was originally on and remains off if it was originally off.
4978	 */
4979	si_pmu_pll_on(sih, osh, cc, min_mask, max_mask, clk_ctl_st);
4980} /* si_pmu2_pll_vars_init */
4981
4982/**
4983 * PLL needs to be initialized to the correct frequency. This function will skip that
4984 * initialization if the PLL is already at the correct frequency.
4985 */
4986static void
4987BCMATTACHFN(si_pmu2_pllinit0)(si_t *sih, osl_t *osh, chipcregs_t *cc, uint32 xtal)
4988{
4989	const pmu2_xtaltab0_t *xt;
4990	int xt_idx;
4991	uint32 freq_tgt, pll0;
4992	rsc_per_chip_t *rsc;
4993
4994	if (xtal == 0) {
4995		PMU_MSG(("Unspecified xtal frequency, skip PLL configuration\n"));
4996		goto exit;
4997	}
4998
4999	for (xt = si_pmu2_xtaltab0(sih), xt_idx = 0; xt != NULL && xt->fref != 0; xt++, xt_idx++) {
5000		if (xt->fref == xtal)
5001			break;
5002	}
5003
5004	if (xt == NULL || xt->fref == 0) {
5005		PMU_MSG(("Unsupported xtal frequency %d.%d MHz, skip PLL configuration\n",
5006		         xtal / 1000, xtal % 1000));
5007		goto exit;
5008	}
5009
5010	W_REG(osh, PMUREG(sih, pllcontrol_addr), PMU15_PLL_PLLCTL0);
5011	pll0 = R_REG(osh, PMUREG(sih, pllcontrol_data));
5012
5013	freq_tgt = (pll0 & PMU15_PLL_PC0_FREQTGT_MASK) >> PMU15_PLL_PC0_FREQTGT_SHIFT;
5014	if (freq_tgt == xt->freq_tgt) {
5015		PMU_MSG(("PLL already programmed for %d.%d MHz\n",
5016			xt->fref / 1000, xt->fref % 1000));
5017		goto exit;
5018	}
5019
5020	PMU_MSG(("XTAL %d.%d MHz (%d)\n", xtal / 1000, xtal % 1000, xt->xf));
5021	PMU_MSG(("Programming PLL for %d.%d MHz\n", xt->fref / 1000, xt->fref % 1000));
5022
5023	/* Make sure the PLL is off */
5024	switch (CHIPID(sih->chip)) {
5025	case BCM43341_CHIP_ID:
5026	case BCM4334_CHIP_ID:
5027	case BCM4314_CHIP_ID:
5028	case BCM43142_CHIP_ID:
5029	case BCM43143_CHIP_ID:
5030		rsc = si_pmu_get_rsc_positions(sih);
5031		AND_REG(osh, PMUREG(sih, min_res_mask),
5032			~(PMURES_BIT(rsc->ht_avail) | PMURES_BIT(rsc->macphy_clkavail)));
5033		AND_REG(osh, PMUREG(sih, max_res_mask),
5034			~(PMURES_BIT(rsc->ht_avail) | PMURES_BIT(rsc->macphy_clkavail)));
5035		SPINWAIT(R_REG(osh, &cc->clk_ctl_st) & CCS_HTAVAIL, PMU_MAX_TRANSITION_DLY);
5036		ASSERT(!(R_REG(osh, &cc->clk_ctl_st) & CCS_HTAVAIL));
5037		break;
5038	default:
5039		PMU_ERROR(("%s: Turn HT off for 0x%x????\n", __FUNCTION__, CHIPID(sih->chip)));
5040		break;
5041	}
5042
5043	pll0 = (pll0 & ~PMU15_PLL_PC0_FREQTGT_MASK) | (xt->freq_tgt << PMU15_PLL_PC0_FREQTGT_SHIFT);
5044	W_REG(osh, PMUREG(sih, pllcontrol_data), pll0);
5045
5046	if (CST4334_CHIPMODE_HSIC(sih->chipst)) {
5047		uint32 hsic_freq;
5048
5049		/* Only update target freq from 480Mhz table for HSIC */
5050		ASSERT(xt_idx < PMU15_XTALTAB0_END);
5051		hsic_freq = pmu2_xtaltab0_adfll_480[xt_idx].freq_tgt;
5052
5053		/*
5054		 * Update new tgt freq for PLL control 5
5055		 * This is activated when USB/HSIC core is taken out of reset (ch_reset())
5056		 */
5057		si_pmu_pllcontrol(sih, PMU15_PLL_PLLCTL5, PMU15_PLL_PC5_FREQTGT_MASK, hsic_freq);
5058	}
5059
5060	/* Flush deferred pll control registers writes */
5061	if (sih->pmurev >= 2)
5062		OR_REG(osh, PMUREG(sih, pmucontrol), PCTL_PLL_PLLCTL_UPD);
5063
5064exit:
5065	/* Vars over-rides */
5066	si_pmu2_pll_vars_init(sih, osh, cc);
5067} /* si_pmu2_pllinit0 */
5068
5069/** returns the clock frequency at which the ARM is running */
5070static uint32
5071BCMINITFN(si_pmu2_cpuclk0)(si_t *sih, osl_t *osh, chipcregs_t *cc)
5072{
5073	const pmu2_xtaltab0_t *xt;
5074	uint32 freq_tgt = 0, pll0 = 0;
5075
5076	switch (CHIPID(sih->chip)) {
5077	case BCM4314_CHIP_ID:
5078	case BCM43142_CHIP_ID:
5079	case BCM43143_CHIP_ID:
5080	case BCM43341_CHIP_ID:
5081	case BCM4334_CHIP_ID:
5082		W_REG(osh, PMUREG(sih, pllcontrol_addr), PMU15_PLL_PLLCTL0);
5083		pll0 = R_REG(osh, PMUREG(sih, pllcontrol_data));
5084		freq_tgt = (pll0 & PMU15_PLL_PC0_FREQTGT_MASK) >> PMU15_PLL_PC0_FREQTGT_SHIFT;
5085		break;
5086	default:
5087		ASSERT(0);
5088		break;
5089	}
5090
5091	for (xt = pmu2_xtaltab0_adfll_480; xt != NULL && xt->fref != 0; xt++) {
5092		if (xt->freq_tgt == freq_tgt)
5093			return PMU15_ARM_96MHZ;
5094	}
5095
5096#ifndef BCM_BOOTLOADER
5097	for (xt = pmu2_xtaltab0_adfll_485; xt != NULL && xt->fref != 0; xt++) {
5098		if (xt->freq_tgt == freq_tgt)
5099			return PMU15_ARM_97MHZ;
5100	}
5101#endif
5102
5103	/* default */
5104	return PMU15_ARM_96MHZ;
5105}
5106
5107/** Query ALP/xtal clock frequency */
5108static uint32
5109BCMINITFN(si_pmu2_alpclk0)(si_t *sih, osl_t *osh, chipcregs_t *cc)
5110{
5111	const pmu2_xtaltab0_t *xt;
5112	uint32 freq_tgt, pll0;
5113
5114	W_REG(osh, PMUREG(sih, pllcontrol_addr), PMU15_PLL_PLLCTL0);
5115	pll0 = R_REG(osh, PMUREG(sih, pllcontrol_data));
5116
5117	freq_tgt = (pll0 & PMU15_PLL_PC0_FREQTGT_MASK) >> PMU15_PLL_PC0_FREQTGT_SHIFT;
5118
5119
5120	for (xt = pmu2_xtaltab0_adfll_480; xt != NULL && xt->fref != 0; xt++) {
5121		if (xt->freq_tgt == freq_tgt)
5122			break;
5123	}
5124
5125#ifndef BCM_BOOTLOADER
5126	if (xt == NULL || xt->fref == 0) {
5127		for (xt = pmu2_xtaltab0_adfll_485; xt != NULL && xt->fref != 0; xt++) {
5128			if (xt->freq_tgt == freq_tgt)
5129				break;
5130		}
5131	}
5132#endif
5133
5134	/* Could not find it so assign a default value */
5135	if (xt == NULL || xt->fref == 0)
5136		xt = si_pmu2_xtaldef0(sih);
5137	ASSERT(xt != NULL && xt->fref != 0);
5138
5139	return xt->fref * 1000;
5140}
5141
5142/**
5143 * Set up PLL registers in the PMU as per the (optional) OTP values, or, if no OTP values are
5144 * present, optionally update with POR override values contained in firmware. Enables the BBPLL
5145 * when done.
5146 */
5147static void
5148BCMATTACHFN(si_pmu1_pllinit1)(si_t *sih, osl_t *osh, chipcregs_t *cc, uint32 xtal)
5149{
5150	char name[16];
5151	const char *otp_val;
5152	uint8 i, otp_entry_found = FALSE;
5153	uint32 pll_ctrlcnt;
5154	uint32 min_mask = 0, max_mask = 0, clk_ctl_st = 0;
5155
5156	if (sih->pmurev >= 5) {
5157		pll_ctrlcnt = (sih->pmucaps & PCAP5_PC_MASK) >> PCAP5_PC_SHIFT;
5158	}
5159	else {
5160		pll_ctrlcnt = (sih->pmucaps & PCAP_PC_MASK) >> PCAP_PC_SHIFT;
5161	}
5162
5163	/* Check if there is any otp enter for PLLcontrol registers */
5164	for (i = 0; i < pll_ctrlcnt; i++) {
5165		snprintf(name, sizeof(name), rstr_pllD, i);
5166		if ((otp_val = getvar(NULL, name)) == NULL)
5167			continue;
5168
5169		/* If OTP entry is found for PLL register, then turn off the PLL
5170		 * and set the status of the OTP entry accordingly.
5171		 */
5172		otp_entry_found = TRUE;
5173		break;
5174	}
5175
5176	/* If no OTP parameter is found and no chip-specific updates are needed, return. */
5177	if ((otp_entry_found == FALSE) &&
5178		(si_pmu_update_pllcontrol(sih, osh, xtal, FALSE) == FALSE))
5179		return;
5180
5181	/* Make sure PLL is off */
5182	si_pmu_pll_off(sih, osh, cc, &min_mask, &max_mask, &clk_ctl_st);
5183
5184	/* Update any chip-specific PLL registers. Does not write PLL 'update' bit yet. */
5185	si_pmu_update_pllcontrol(sih, osh, xtal, TRUE);
5186
5187	/* Update the PLL register if there is a OTP entry for PLL registers */
5188	si_pmu_otp_pllcontrol(sih, osh);
5189
5190	/* Flush ('update') the deferred pll control registers writes */
5191	if (sih->pmurev >= 2)
5192		OR_REG(osh, PMUREG(sih, pmucontrol), PCTL_PLL_PLLCTL_UPD);
5193
5194	/* Restore back the register values. This ensures PLL remains on if it
5195	 * was originally on and remains off if it was originally off.
5196	 */
5197	si_pmu_pll_on(sih, osh, cc, min_mask, max_mask, clk_ctl_st);
5198} /* si_pmu1_pllinit1 */
5199
5200/**
5201 * Set up PLL registers in the PMU as per the crystal speed.
5202 * XtalFreq field in pmucontrol register being 0 indicates the PLL
5203 * is not programmed and the h/w default is assumed to work, in which
5204 * case the xtal frequency is unknown to the s/w so we need to call
5205 * si_pmu1_xtaldef0() wherever it is needed to return a default value.
5206 */
5207static void
5208BCMATTACHFN(si_pmu1_pllinit0)(si_t *sih, osl_t *osh, chipcregs_t *cc, uint32 xtal)
5209{
5210	const pmu1_xtaltab0_t *xt;
5211	uint32 tmp;
5212	uint32 buf_strength = 0;
5213	uint8 ndiv_mode = 1;
5214	uint8 dacrate;
5215
5216	/* Use h/w default PLL config */
5217	if (xtal == 0) {
5218		PMU_MSG(("Unspecified xtal frequency, skip PLL configuration\n"));
5219		return;
5220	}
5221
5222	/* Find the frequency in the table */
5223	for (xt = si_pmu1_xtaltab0(sih); xt != NULL && xt->fref != 0; xt ++)
5224		if (xt->fref == xtal)
5225			break;
5226
5227	/* Check current PLL state, bail out if it has been programmed or
5228	 * we don't know how to program it.
5229	 */
5230	if (xt == NULL || xt->fref == 0) {
5231		PMU_MSG(("Unsupported xtal frequency %d.%d MHz, skip PLL configuration\n",
5232		         xtal / 1000, xtal % 1000));
5233		return;
5234	}
5235	/*  for 4319 bootloader already programs the PLL but bootloader does not program the
5236	    PLL4 and PLL5. So Skip this check for 4319
5237	*/
5238	if ((((R_REG(osh, PMUREG(sih, pmucontrol)) & PCTL_XTALFREQ_MASK) >>
5239		PCTL_XTALFREQ_SHIFT) == xt->xf) &&
5240		!((CHIPID(sih->chip) == BCM4319_CHIP_ID) || (CHIPID(sih->chip) == BCM4330_CHIP_ID)))
5241	{
5242		PMU_MSG(("PLL already programmed for %d.%d MHz\n",
5243			xt->fref / 1000, xt->fref % 1000));
5244		return;
5245	}
5246
5247	PMU_MSG(("XTAL %d.%d MHz (%d)\n", xtal / 1000, xtal % 1000, xt->xf));
5248	PMU_MSG(("Programming PLL for %d.%d MHz\n", xt->fref / 1000, xt->fref % 1000));
5249
5250	switch (CHIPID(sih->chip)) {
5251	case BCM4325_CHIP_ID:
5252		/* Change the BBPLL drive strength to 2 for all channels */
5253		buf_strength = 0x222222;
5254		/* Make sure the PLL is off */
5255		AND_REG(osh, PMUREG(sih, min_res_mask),
5256		        ~(PMURES_BIT(RES4325_BBPLL_PWRSW_PU) | PMURES_BIT(RES4325_HT_AVAIL)));
5257		AND_REG(osh, PMUREG(sih, max_res_mask),
5258		        ~(PMURES_BIT(RES4325_BBPLL_PWRSW_PU) | PMURES_BIT(RES4325_HT_AVAIL)));
5259		SPINWAIT(R_REG(osh, &cc->clk_ctl_st) & CCS_HTAVAIL, PMU_MAX_TRANSITION_DLY);
5260		ASSERT(!(R_REG(osh, &cc->clk_ctl_st) & CCS_HTAVAIL));
5261		break;
5262	case BCM4329_CHIP_ID:
5263		/* Change the BBPLL drive strength to 8 for all channels */
5264		buf_strength = 0x888888;
5265		AND_REG(osh, PMUREG(sih, min_res_mask),
5266		        ~(PMURES_BIT(RES4329_BBPLL_PWRSW_PU) | PMURES_BIT(RES4329_HT_AVAIL)));
5267		AND_REG(osh, PMUREG(sih, max_res_mask),
5268		        ~(PMURES_BIT(RES4329_BBPLL_PWRSW_PU) | PMURES_BIT(RES4329_HT_AVAIL)));
5269		SPINWAIT(R_REG(osh, &cc->clk_ctl_st) & CCS_HTAVAIL, PMU_MAX_TRANSITION_DLY);
5270		ASSERT(!(R_REG(osh, &cc->clk_ctl_st) & CCS_HTAVAIL));
5271		W_REG(osh, PMUREG(sih, pllcontrol_addr), PMU1_PLL0_PLLCTL4);
5272		if (xt->fref == 38400)
5273			tmp = 0x200024C0;
5274		else if (xt->fref == 37400)
5275			tmp = 0x20004500;
5276		else if (xt->fref == 26000)
5277			tmp = 0x200024C0;
5278		else
5279			tmp = 0x200005C0; /* Chip Dflt Settings */
5280		W_REG(osh, PMUREG(sih, pllcontrol_data), tmp);
5281		W_REG(osh, PMUREG(sih, pllcontrol_addr), PMU1_PLL0_PLLCTL5);
5282		tmp = R_REG(osh, PMUREG(sih, pllcontrol_data)) & PMU1_PLL0_PC5_CLK_DRV_MASK;
5283		if ((xt->fref == 38400) || (xt->fref == 37400) || (xt->fref == 26000))
5284			tmp |= 0x15;
5285		else
5286			tmp |= 0x25; /* Chip Dflt Settings */
5287		W_REG(osh, PMUREG(sih, pllcontrol_data), tmp);
5288		break;
5289	case BCM4315_CHIP_ID:
5290		/* Change the BBPLL drive strength to 2 for all channels */
5291		buf_strength = 0x222222;
5292		/* Make sure the PLL is off */
5293		AND_REG(osh, PMUREG(sih, min_res_mask), ~(PMURES_BIT(RES4315_HT_AVAIL)));
5294		AND_REG(osh, PMUREG(sih, max_res_mask), ~(PMURES_BIT(RES4315_HT_AVAIL)));
5295		OSL_DELAY(100);
5296
5297		AND_REG(osh, PMUREG(sih, min_res_mask), ~(PMURES_BIT(RES4315_BBPLL_PWRSW_PU)));
5298		AND_REG(osh, PMUREG(sih, max_res_mask), ~(PMURES_BIT(RES4315_BBPLL_PWRSW_PU)));
5299		OSL_DELAY(100);
5300
5301		SPINWAIT(R_REG(osh, &cc->clk_ctl_st) & CCS_HTAVAIL, PMU_MAX_TRANSITION_DLY);
5302		ASSERT(!(R_REG(osh, &cc->clk_ctl_st) & CCS_HTAVAIL));
5303		break;
5304
5305	case BCM4319_CHIP_ID:
5306		/* Change the BBPLL drive strength to 2 for all channels */
5307		buf_strength = 0x222222;
5308
5309		/* Make sure the PLL is off */
5310		/* WAR65104: Disable the HT_AVAIL resource first and then
5311		 * after a delay (more than downtime for HT_AVAIL) remove the
5312		 * BBPLL resource; backplane clock moves to ALP from HT.
5313		 */
5314		AND_REG(osh, PMUREG(sih, min_res_mask), ~(PMURES_BIT(RES4319_HT_AVAIL)));
5315		AND_REG(osh, PMUREG(sih, max_res_mask), ~(PMURES_BIT(RES4319_HT_AVAIL)));
5316
5317		OSL_DELAY(100);
5318		AND_REG(osh, PMUREG(sih, min_res_mask), ~(PMURES_BIT(RES4319_BBPLL_PWRSW_PU)));
5319		AND_REG(osh, PMUREG(sih, max_res_mask), ~(PMURES_BIT(RES4319_BBPLL_PWRSW_PU)));
5320
5321		OSL_DELAY(100);
5322		SPINWAIT(R_REG(osh, &cc->clk_ctl_st) & CCS_HTAVAIL, PMU_MAX_TRANSITION_DLY);
5323		ASSERT(!(R_REG(osh, &cc->clk_ctl_st) & CCS_HTAVAIL));
5324		W_REG(osh, PMUREG(sih, pllcontrol_addr), PMU1_PLL0_PLLCTL4);
5325		tmp = 0x200005c0;
5326		W_REG(osh, PMUREG(sih, pllcontrol_data), tmp);
5327		break;
5328
5329	case BCM4336_CHIP_ID:
5330	case BCM43362_CHIP_ID:
5331		AND_REG(osh, PMUREG(sih, min_res_mask),
5332			~(PMURES_BIT(RES4336_HT_AVAIL) | PMURES_BIT(RES4336_MACPHY_CLKAVAIL)));
5333		AND_REG(osh, PMUREG(sih, max_res_mask),
5334			~(PMURES_BIT(RES4336_HT_AVAIL) | PMURES_BIT(RES4336_MACPHY_CLKAVAIL)));
5335		OSL_DELAY(100);
5336		SPINWAIT(R_REG(osh, &cc->clk_ctl_st) & CCS_HTAVAIL, PMU_MAX_TRANSITION_DLY);
5337		ASSERT(!(R_REG(osh, &cc->clk_ctl_st) & CCS_HTAVAIL));
5338		break;
5339
5340	case BCM4330_CHIP_ID:
5341		AND_REG(osh, PMUREG(sih, min_res_mask),
5342			~(PMURES_BIT(RES4330_HT_AVAIL) | PMURES_BIT(RES4330_MACPHY_CLKAVAIL)));
5343		AND_REG(osh, PMUREG(sih, max_res_mask),
5344			~(PMURES_BIT(RES4330_HT_AVAIL) | PMURES_BIT(RES4330_MACPHY_CLKAVAIL)));
5345		OSL_DELAY(100);
5346		SPINWAIT(R_REG(osh, &cc->clk_ctl_st) & CCS_HTAVAIL, PMU_MAX_TRANSITION_DLY);
5347		ASSERT(!(R_REG(osh, &cc->clk_ctl_st) & CCS_HTAVAIL));
5348		break;
5349
5350	default:
5351		ASSERT(0);
5352	}
5353
5354	PMU_MSG(("Done masking\n"));
5355
5356	/* Write p1div and p2div to pllcontrol[0] */
5357	W_REG(osh, PMUREG(sih, pllcontrol_addr), PMU1_PLL0_PLLCTL0);
5358	tmp = R_REG(osh, PMUREG(sih, pllcontrol_data)) &
5359	        ~(PMU1_PLL0_PC0_P1DIV_MASK | PMU1_PLL0_PC0_P2DIV_MASK);
5360	tmp |= ((xt->p1div << PMU1_PLL0_PC0_P1DIV_SHIFT) & PMU1_PLL0_PC0_P1DIV_MASK) |
5361	        ((xt->p2div << PMU1_PLL0_PC0_P2DIV_SHIFT) & PMU1_PLL0_PC0_P2DIV_MASK);
5362	W_REG(osh, PMUREG(sih, pllcontrol_data), tmp);
5363
5364	if ((CHIPID(sih->chip) == BCM4330_CHIP_ID)) {
5365		if (CHIPREV(sih->chiprev) < 2)
5366			dacrate = 160;
5367		else {
5368			if (!(dacrate = (uint8)getintvar(NULL, rstr_dacrate2g)))
5369				dacrate = 80;
5370		}
5371		si_pmu_set_4330_plldivs(sih, dacrate);
5372	}
5373
5374	if ((CHIPID(sih->chip) == BCM4329_CHIP_ID) && (CHIPREV(sih->chiprev) == 0)) {
5375
5376		W_REG(osh, PMUREG(sih, pllcontrol_addr), PMU1_PLL0_PLLCTL1);
5377		tmp = R_REG(osh, PMUREG(sih, pllcontrol_data));
5378		tmp = tmp & (~DOT11MAC_880MHZ_CLK_DIVISOR_MASK);
5379		tmp = tmp | DOT11MAC_880MHZ_CLK_DIVISOR_VAL;
5380		W_REG(osh, PMUREG(sih, pllcontrol_data), tmp);
5381	}
5382	if ((CHIPID(sih->chip) == BCM4319_CHIP_ID) ||
5383		(CHIPID(sih->chip) == BCM4336_CHIP_ID) ||
5384		(CHIPID(sih->chip) == BCM43362_CHIP_ID) ||
5385		(CHIPID(sih->chip) == BCM4330_CHIP_ID))
5386		ndiv_mode = PMU1_PLL0_PC2_NDIV_MODE_MFB;
5387	else
5388		ndiv_mode = PMU1_PLL0_PC2_NDIV_MODE_MASH;
5389
5390	/* Write ndiv_int and ndiv_mode to pllcontrol[2] */
5391	W_REG(osh, PMUREG(sih, pllcontrol_addr), PMU1_PLL0_PLLCTL2);
5392	tmp = R_REG(osh, PMUREG(sih, pllcontrol_data)) &
5393	        ~(PMU1_PLL0_PC2_NDIV_INT_MASK | PMU1_PLL0_PC2_NDIV_MODE_MASK);
5394	tmp |= ((xt->ndiv_int << PMU1_PLL0_PC2_NDIV_INT_SHIFT) & PMU1_PLL0_PC2_NDIV_INT_MASK) |
5395	        ((ndiv_mode << PMU1_PLL0_PC2_NDIV_MODE_SHIFT) & PMU1_PLL0_PC2_NDIV_MODE_MASK);
5396	W_REG(osh, PMUREG(sih, pllcontrol_data), tmp);
5397
5398	/* Write ndiv_frac to pllcontrol[3] */
5399	W_REG(osh, PMUREG(sih, pllcontrol_addr), PMU1_PLL0_PLLCTL3);
5400	tmp = R_REG(osh, PMUREG(sih, pllcontrol_data)) & ~PMU1_PLL0_PC3_NDIV_FRAC_MASK;
5401	tmp |= ((xt->ndiv_frac << PMU1_PLL0_PC3_NDIV_FRAC_SHIFT) &
5402	        PMU1_PLL0_PC3_NDIV_FRAC_MASK);
5403	W_REG(osh, PMUREG(sih, pllcontrol_data), tmp);
5404
5405	/* Write clock driving strength to pllcontrol[5] */
5406	if (buf_strength) {
5407		PMU_MSG(("Adjusting PLL buffer drive strength: %x\n", buf_strength));
5408
5409		W_REG(osh, PMUREG(sih, pllcontrol_addr), PMU1_PLL0_PLLCTL5);
5410		tmp = R_REG(osh, PMUREG(sih, pllcontrol_data)) & ~PMU1_PLL0_PC5_CLK_DRV_MASK;
5411		tmp |= (buf_strength << PMU1_PLL0_PC5_CLK_DRV_SHIFT);
5412		W_REG(osh, PMUREG(sih, pllcontrol_data), tmp);
5413	}
5414
5415	PMU_MSG(("Done pll\n"));
5416
5417	/* to operate the 4319 usb in 24MHz/48MHz; chipcontrol[2][84:83] needs
5418	 * to be updated.
5419	 */
5420	if ((CHIPID(sih->chip) == BCM4319_CHIP_ID) && (xt->fref != XTAL_FREQ_30000MHZ)) {
5421		W_REG(osh, PMUREG(sih, chipcontrol_addr), PMU1_PLL0_CHIPCTL2);
5422		tmp = R_REG(osh, PMUREG(sih, chipcontrol_data)) & ~CCTL_4319USB_XTAL_SEL_MASK;
5423		if (xt->fref == XTAL_FREQ_24000MHZ) {
5424			tmp |= (CCTL_4319USB_24MHZ_PLL_SEL << CCTL_4319USB_XTAL_SEL_SHIFT);
5425		} else if (xt->fref == XTAL_FREQ_48000MHZ) {
5426			tmp |= (CCTL_4319USB_48MHZ_PLL_SEL << CCTL_4319USB_XTAL_SEL_SHIFT);
5427		}
5428		W_REG(osh, PMUREG(sih, chipcontrol_data), tmp);
5429	}
5430
5431	/* Flush deferred pll control registers writes */
5432	if (sih->pmurev >= 2)
5433		OR_REG(osh, PMUREG(sih, pmucontrol), PCTL_PLL_PLLCTL_UPD);
5434
5435	/* Write XtalFreq. Set the divisor also. */
5436	tmp = R_REG(osh, PMUREG(sih, pmucontrol)) &
5437	        ~(PCTL_ILP_DIV_MASK | PCTL_XTALFREQ_MASK);
5438	tmp |= (((((xt->fref + 127) / 128) - 1) << PCTL_ILP_DIV_SHIFT) &
5439	        PCTL_ILP_DIV_MASK) |
5440	       ((xt->xf << PCTL_XTALFREQ_SHIFT) & PCTL_XTALFREQ_MASK);
5441
5442	if ((CHIPID(sih->chip) == BCM4329_CHIP_ID) && CHIPREV(sih->chiprev) == 0) {
5443		/* clear the htstretch before clearing HTReqEn */
5444		AND_REG(osh, PMUREG(sih, clkstretch), ~CSTRETCH_HT);
5445		tmp &= ~PCTL_HT_REQ_EN;
5446	}
5447
5448	W_REG(osh, PMUREG(sih, pmucontrol), tmp);
5449} /* si_pmu1_pllinit0 */
5450
5451/**
5452 * returns the CPU clock frequency. Does this by determining current Fvco and the setting of the
5453 * clock divider that leads up to the ARM. Returns value in [Hz] units.
5454 */
5455static uint32
5456BCMINITFN(si_pmu1_cpuclk0)(si_t *sih, osl_t *osh, chipcregs_t *cc)
5457{
5458	uint32 tmp, mdiv = 1;
5459#ifndef BCM_OL_DEV
5460#endif /* BCM_OL_DEV */
5461	uint32 FVCO = si_pmu1_pllfvco0(sih);	/* in [khz] units */
5462
5463	if ((CHIPID(sih->chip) == BCM43602_CHIP_ID ||
5464	    CHIPID(sih->chip) == BCM43462_CHIP_ID) &&
5465#ifdef DONGLEBUILD
5466		(si_arm_clockratio(sih, 0) == 1) &&
5467#endif
5468		TRUE) {
5469		/* CR4 running on backplane_clk */
5470		return si_pmu_si_clock(sih, osh);	/* in [hz] units */
5471	}
5472	switch (CHIPID(sih->chip)) {
5473	case BCM4325_CHIP_ID:
5474	case BCM4329_CHIP_ID:
5475	case BCM4315_CHIP_ID:
5476	case BCM4319_CHIP_ID:
5477	case BCM4336_CHIP_ID:
5478	case BCM43362_CHIP_ID:
5479	case BCM4330_CHIP_ID:
5480		/* Read m1div from pllcontrol[1] */
5481		W_REG(osh, PMUREG(sih, pllcontrol_addr), PMU1_PLL0_PLLCTL1);
5482		tmp = R_REG(osh, PMUREG(sih, pllcontrol_data));
5483		mdiv = (tmp & PMU1_PLL0_PC1_M1DIV_MASK) >> PMU1_PLL0_PC1_M1DIV_SHIFT;
5484		break;
5485	case BCM43239_CHIP_ID:
5486		/* Read m6div from pllcontrol[2] */
5487		W_REG(osh, PMUREG(sih, pllcontrol_addr), PMU1_PLL0_PLLCTL2);
5488		tmp = R_REG(osh, PMUREG(sih, pllcontrol_data));
5489		mdiv = (tmp & PMU1_PLL0_PC2_M6DIV_MASK) >> PMU1_PLL0_PC2_M6DIV_SHIFT;
5490		break;
5491	case BCM4324_CHIP_ID:
5492	case BCM43242_CHIP_ID:
5493	case BCM43243_CHIP_ID:
5494		/* Read m2div from pllcontrol[1] */
5495		W_REG(osh, PMUREG(sih, pllcontrol_addr), PMU1_PLL0_PLLCTL1);
5496		tmp = R_REG(osh, PMUREG(sih, pllcontrol_data));
5497		mdiv = (tmp & PMU1_PLL0_PC1_M2DIV_MASK) >> PMU1_PLL0_PC1_M2DIV_SHIFT;
5498		break;
5499	case BCM4335_CHIP_ID:
5500	case BCM4345_CHIP_ID:
5501		/* Read m3div from pllcontrol[1] */
5502		W_REG(osh, PMUREG(sih, pllcontrol_addr), PMU1_PLL0_PLLCTL1);
5503		tmp = R_REG(osh, PMUREG(sih, pllcontrol_data));
5504		mdiv = (tmp & PMU1_PLL0_PC1_M3DIV_MASK) >> PMU1_PLL0_PC1_M3DIV_SHIFT;
5505		break;
5506	case BCM4350_CHIP_ID:
5507	case BCM43556_CHIP_ID:
5508	case BCM43558_CHIP_ID:
5509	case BCM43566_CHIP_ID:
5510	case BCM43568_CHIP_ID:
5511		if (CHIPREV(sih->chiprev) >= 3) {
5512			W_REG(osh, PMUREG(sih, pllcontrol_addr), PMU1_PLL0_PLLCTL2);
5513			tmp = R_REG(osh, PMUREG(sih, pllcontrol_data));
5514			mdiv = (tmp & PMU1_PLL0_PC2_M5DIV_MASK) >> PMU1_PLL0_PC2_M5DIV_SHIFT;
5515		}
5516		else {
5517			/* Read m3div from pllcontrol[1] */
5518			W_REG(osh, PMUREG(sih, pllcontrol_addr), PMU1_PLL0_PLLCTL1);
5519			tmp = R_REG(osh, PMUREG(sih, pllcontrol_data));
5520			mdiv = (tmp & PMU1_PLL0_PC1_M3DIV_MASK) >> PMU1_PLL0_PC1_M3DIV_SHIFT;
5521		}
5522		break;
5523	case BCM4354_CHIP_ID:
5524	case BCM4356_CHIP_ID:
5525	case BCM43569_CHIP_ID:
5526	case BCM43570_CHIP_ID:
5527		W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2);
5528		tmp = R_REG(osh, &cc->pllcontrol_data);
5529		mdiv = (tmp & PMU1_PLL0_PC2_M5DIV_MASK) >> PMU1_PLL0_PC2_M5DIV_SHIFT;
5530		break;
5531	case BCM4360_CHIP_ID:
5532	case BCM43460_CHIP_ID:
5533	case BCM43526_CHIP_ID:
5534	case BCM4352_CHIP_ID:
5535		/* Read m6div from pllcontrol[5] */
5536		W_REG(osh, PMUREG(sih, pllcontrol_addr), PMU1_PLL0_PLLCTL5);
5537		tmp = R_REG(osh, PMUREG(sih, pllcontrol_data));
5538		mdiv = (tmp & PMU1_PLL0_PC2_M6DIV_MASK) >> PMU1_PLL0_PC2_M6DIV_SHIFT;
5539		break;
5540#ifdef DONGLEBUILD
5541	case BCM43602_CHIP_ID:
5542	case BCM43462_CHIP_ID:
5543		ASSERT(si_arm_clockratio(sih, 0) == 2);
5544		/* CR4 running on armcr4_clk (Ch5). Read 'bbpll_i_m5div' from pllctl[5] */
5545		W_REG(osh, PMUREG(sih, pllcontrol_addr), PMU1_PLL0_PLLCTL5);
5546		tmp = R_REG(osh, PMUREG(sih, pllcontrol_data));
5547		mdiv = (tmp & PMU1_PLL0_PC2_M5DIV_MASK) >> PMU1_PLL0_PC2_M5DIV_SHIFT;
5548		break;
5549#endif /* DONGLEBUILD */
5550	default:
5551		PMU_MSG(("si_pmu1_cpuclk0: Unknown chipid %s\n", bcm_chipname(sih->chip, chn, 8)));
5552		ASSERT(0);
5553		break;
5554	}
5555#ifndef BCM_OL_DEV
5556#endif /* BCM_OL_DEV */
5557	/* Return ARM/SB clock */
5558	return FVCO / mdiv * 1000;
5559} /* si_pmu1_cpuclk0 */
5560
5561
5562/** 4335 specific code. Returns the MAC clock frequency. */
5563extern uint32
5564si_mac_clk(si_t *sih, osl_t *osh)
5565{
5566	uint8 mdiv2 = 0;
5567	uint32 pll_reg, mac_clk = 0;
5568	chipcregs_t *cc;
5569	uint origidx, intr_val;
5570
5571	uint32 FVCO = si_pmu1_pllfvco0(sih);	/* in [khz] units */
5572
5573	/* Remember original core before switch to chipc */
5574	cc = (chipcregs_t *)si_switch_core(sih, CC_CORE_ID, &origidx, &intr_val);
5575	ASSERT(cc != NULL);
5576	BCM_REFERENCE(cc);
5577
5578	switch (CHIPID(sih->chip)) {
5579	case BCM4335_CHIP_ID:
5580		pll_reg = si_pmu_pllcontrol(sih, PMU1_PLL0_PLLCTL1, 0, 0);
5581
5582		mdiv2 = (pll_reg & PMU4335_PLL0_PC1_MDIV2_MASK) >>
5583				PMU4335_PLL0_PC1_MDIV2_SHIFT;
5584		mac_clk = FVCO / mdiv2;
5585		break;
5586	default:
5587		PMU_MSG(("si_mac_clk: Unknown chipid %s\n", bcm_chipname(sih->chip, chn, 8)));
5588		ASSERT(0);
5589		break;
5590	}
5591
5592	/* Return to original core */
5593	si_restore_core(sih, origidx, intr_val);
5594
5595
5596	return mac_clk;
5597} /* si_mac_clk */
5598
5599/* Get chip's FVCO and PLLCTRL1 register value */
5600extern int
5601si_pmu_fvco_pllreg(si_t *sih, uint32 *fvco, uint32 *pllreg)
5602{
5603	chipcregs_t *cc;
5604	uint origidx, intr_val;
5605
5606	if (fvco)
5607		*fvco = si_pmu1_pllfvco0(sih)/1000;
5608
5609	/* Remember original core before switch to chipc */
5610	cc = (chipcregs_t *)si_switch_core(sih, CC_CORE_ID, &origidx, &intr_val);
5611	ASSERT(cc != NULL);
5612	BCM_REFERENCE(cc);
5613
5614	switch (CHIPID(sih->chip)) {
5615	case BCM4335_CHIP_ID:
5616	case BCM4345_CHIP_ID:
5617	case BCM4350_CHIP_ID:
5618	case BCM4354_CHIP_ID:
5619	case BCM4356_CHIP_ID:
5620	case BCM43556_CHIP_ID:
5621	case BCM43558_CHIP_ID:
5622	case BCM43566_CHIP_ID:
5623	case BCM43568_CHIP_ID:
5624	case BCM43569_CHIP_ID:
5625	case BCM43570_CHIP_ID:
5626		if (pllreg)
5627			*pllreg = si_pmu_pllcontrol(sih, PMU1_PLL0_PLLCTL1, 0, 0);
5628		break;
5629
5630	default:
5631		PMU_MSG(("si_mac_clk: Unknown chipid %s\n", bcm_chipname(sih->chip, chn, 8)));
5632		ASSERT(0);
5633		return -1;
5634	}
5635
5636	/* Return to original core */
5637	si_restore_core(sih, origidx, intr_val);
5638
5639	return 0;
5640}
5641
5642/* Is not called in PHOENIX2_BRANCH_6_10. Dead code ? */
5643bool
5644si_pmu_is_autoresetphyclk_disabled(si_t *sih, osl_t *osh)
5645{
5646	bool disable = FALSE;
5647
5648	switch (CHIPID(sih->chip)) {
5649	case BCM43239_CHIP_ID:
5650		W_REG(osh, PMUREG(sih, chipcontrol_addr), 0);
5651		if (R_REG(osh, PMUREG(sih, chipcontrol_data)) & 0x00000002)
5652			disable = TRUE;
5653		break;
5654	default:
5655		break;
5656	}
5657
5658	return disable;
5659}
5660
5661/* For 43602a0 MCH2/MCH5 boards: power up PA Reference LDO */
5662void
5663si_pmu_switch_on_PARLDO(si_t *sih, osl_t *osh)
5664{
5665	uint32 mask;
5666
5667	switch (CHIPID(sih->chip)) {
5668	case BCM43602_CHIP_ID:
5669	case BCM43462_CHIP_ID:
5670		mask = R_REG(osh, PMUREG(sih, min_res_mask)) | PMURES_BIT(RES43602_PARLDO_PU);
5671		W_REG(osh, PMUREG(sih, min_res_mask), mask);
5672		mask = R_REG(osh, PMUREG(sih, max_res_mask)) | PMURES_BIT(RES43602_PARLDO_PU);
5673		W_REG(osh, PMUREG(sih, max_res_mask), mask);
5674		break;
5675	default:
5676		break;
5677	}
5678}
5679
5680/**
5681 * Change VCO frequency (slightly), e.g. to avoid PHY errors due to spurs.
5682 */
5683static void
5684BCMATTACHFN(si_set_bb_vcofreq_frac)(si_t *sih, osl_t *osh, int vcofreq, int frac, int xtalfreq)
5685{
5686	uint32 vcofreq_withfrac, p1div, ndiv_int, fraca, ndiv_mode, reg;
5687	/* shifts / masks for PMU PLL control register #2 : */
5688	uint32 ndiv_int_shift, ndiv_mode_shift, p1div_shift, pllctrl2_mask;
5689	/* shifts / masks for PMU PLL control register #3 : */
5690	uint32 pllctrl3_mask;
5691
5692	if ((CHIPID(sih->chip) == BCM4360_CHIP_ID) ||
5693	    (CHIPID(sih->chip) == BCM43460_CHIP_ID) ||
5694	    (CHIPID(sih->chip) == BCM43602_CHIP_ID) ||
5695	    (CHIPID(sih->chip) == BCM43462_CHIP_ID) ||
5696	    (CHIPID(sih->chip) == BCM43526_CHIP_ID) ||
5697	    (CHIPID(sih->chip) == BCM4352_CHIP_ID)) {
5698		chipcregs_t *cc;
5699		cc = si_setcoreidx(sih, SI_CC_IDX);
5700
5701		/* changing BBPLL frequency would lead to USB interface problem */
5702		if (CHIPID(sih->chip) == BCM4360_CHIP_ID &&
5703		    (R_REG(osh, &cc->chipstatus) & CST4360_MODE_USB) &&
5704		    (R_REG(osh, &cc->clk_ctl_st) & CCS_HTAVAIL)) {
5705			PMU_MSG(("HTAVAIL is set, so not updating BBPLL Frequency \n"));
5706			return;
5707		}
5708
5709		ndiv_int_shift = 7;
5710		ndiv_mode_shift = 4;
5711		p1div_shift = 0;
5712		pllctrl2_mask = 0xffffffff;
5713		pllctrl3_mask = 0xffffffff;
5714	} else if (BCM4350_CHIP(sih->chip) &&
5715		(CST4350_IFC_MODE(sih->chipst) == CST4350_IFC_MODE_PCIE)) {
5716		ndiv_int_shift = 23;
5717		ndiv_mode_shift = 20;
5718		p1div_shift = 16;
5719		pllctrl2_mask = 0xffff0000;
5720		pllctrl3_mask = 0x00ffffff;
5721	} else {
5722		/* put more chips here */
5723		PMU_ERROR(("%s: only work on 4360, 4350\n", __FUNCTION__));
5724		return;
5725	}
5726
5727	vcofreq_withfrac = vcofreq * 10000 + frac;
5728	p1div = 0x1;
5729	ndiv_int = vcofreq / xtalfreq;
5730	ndiv_mode = (vcofreq_withfrac % (xtalfreq * 10000)) ? 3 : 0;
5731	PMU_ERROR(("ChangeVCO => vco:%d, xtalF:%d, frac: %d, ndivMode: %d, ndivint: %d\n",
5732		vcofreq, xtalfreq, frac, ndiv_mode, ndiv_int));
5733
5734	reg = (ndiv_int << ndiv_int_shift) |
5735	      (ndiv_mode << ndiv_mode_shift) |
5736	      (p1div << p1div_shift);
5737	PMU_ERROR(("Data written into the PLL_CNTRL_ADDR2: %08x\n", reg));
5738	si_pmu_pllcontrol(sih, 2, pllctrl2_mask, reg);
5739
5740	if (ndiv_mode) {
5741		/* frac = (vcofreq_withfrac % (xtalfreq * 10000)) * 2^24) / (xtalfreq * 10000) */
5742		uint32 r1, r0;
5743		bcm_uint64_multiple_add(
5744			&r1, &r0, vcofreq_withfrac % (xtalfreq * 10000), 1 << 24, 0);
5745		bcm_uint64_divide(&fraca, r1, r0, xtalfreq * 10000);
5746		PMU_ERROR(("Data written into the PLL_CNTRL_ADDR3 (Fractional): %08x\n", fraca));
5747		si_pmu_pllcontrol(sih, 3, pllctrl3_mask, fraca);
5748	}
5749
5750	si_pmu_pllupd(sih);
5751} /* si_set_bb_vcofreq_frac */
5752
5753/** given x-tal frequency, returns vcofreq with fraction in 100Hz */
5754uint32
5755si_pmu_get_bb_vcofreq(si_t *sih, osl_t *osh, int xtalfreq)
5756{
5757	uint32  ndiv_int,	/* 9 bits integer divider */
5758		ndiv_mode,
5759		frac = 0,	/* 24 bits fractional divider */
5760		p1div; 		/* predivider: divides x-tal freq */
5761	uint32 xtal1, vcofrac = 0, vcofreq;
5762	uint32 r1, r0, reg;
5763
5764	if ((CHIPID(sih->chip) == BCM4360_CHIP_ID) ||
5765	    (CHIPID(sih->chip) == BCM43460_CHIP_ID) ||
5766	    (CHIPID(sih->chip) == BCM43526_CHIP_ID) ||
5767	    (CHIPID(sih->chip) == BCM43602_CHIP_ID) ||
5768	    (CHIPID(sih->chip) == BCM43462_CHIP_ID) ||
5769	    (CHIPID(sih->chip) == BCM4352_CHIP_ID)) {
5770		reg = si_pmu_pllcontrol(sih, 2, 0, 0);
5771		ndiv_int = reg >> 7;
5772		ndiv_mode = (reg >> 4) & 7;
5773		p1div = 1; /* do not divide x-tal frequency */
5774
5775		if (ndiv_mode)
5776			frac = si_pmu_pllcontrol(sih, 3, 0, 0);
5777	} else if (BCM4350_CHIP(sih->chip) &&
5778		(CST4350_IFC_MODE(sih->chipst) == CST4350_IFC_MODE_PCIE)) {
5779		reg = si_pmu_pllcontrol(sih, 2, 0, 0);
5780		ndiv_int = reg >> 23;
5781		ndiv_mode = (reg >> 20) & 7;
5782		p1div = (reg >> 16) & 0xf;
5783
5784		if (ndiv_mode)
5785			frac = si_pmu_pllcontrol(sih, 3, 0, 0) & 0x00ffffff;
5786	} else {
5787		/* put more chips here */
5788		PMU_ERROR(("%s: only work on 4360, 4350\n", __FUNCTION__));
5789		return 0;
5790	}
5791
5792	xtal1 = 10000 * xtalfreq / p1div;		/* in [100Hz] units */
5793
5794	if (ndiv_mode) {
5795		/* vcofreq fraction = (xtal1 * frac + (1 << 23)) / (1 << 24);
5796		 * handle overflow
5797		 */
5798		bcm_uint64_multiple_add(&r1, &r0, xtal1, frac, 1 << 23);
5799		vcofrac = (r1 << 8) | (r0 >> 24);
5800	}
5801
5802	if ((int)xtal1 > (int)((0xffffffff - vcofrac) / ndiv_int)) {
5803		PMU_ERROR(("%s: xtalfreq is too big, %d\n", __FUNCTION__, xtalfreq));
5804		return 0;
5805	}
5806
5807	vcofreq = xtal1 * ndiv_int + vcofrac;
5808	return vcofreq;
5809} /* si_pmu_get_bb_vcofreq */
5810
5811/* Enable PMU 1Mhz clock */
5812static void
5813si_pmu_enb_slow_clk(si_t *sih, osl_t *osh, uint32 xtalfreq)
5814{
5815	uint32 val;
5816
5817	if ((sih->buscoretype != PCIE2_CORE_ID) ||
5818	    ((sih->buscorerev != 7) &&
5819	     (sih->buscorerev != 9) &&
5820	     (sih->buscorerev != 11)))
5821		return;
5822
5823	if (xtalfreq == 37400) {
5824		val = 0x101B6;
5825	} else if (xtalfreq == 40000) {
5826		val = 0x10199;
5827	} else {
5828		PMU_ERROR(("%s: xtalfreq is not supported, %d\n", __FUNCTION__, xtalfreq));
5829		return;
5830	}
5831	W_REG(osh, PMUREG(sih, slowclkperiod), val);
5832}
5833
5834/**
5835 * Initializes PLL given an x-tal frequency.
5836 * Calls si_pmuX_pllinitY() type of functions, where the reasoning behind 'X' and 'Y' is historical
5837 * rather than logical.
5838 *
5839 * xtalfreq : x-tal frequency in [KHz]
5840 */
5841void
5842BCMATTACHFN(si_pmu_pll_init)(si_t *sih, osl_t *osh, uint xtalfreq)
5843{
5844	chipcregs_t *cc;
5845	uint origidx;
5846
5847	ASSERT(sih->cccaps & CC_CAP_PMU);
5848
5849	/* Remember original core before switch to chipc */
5850	origidx = si_coreidx(sih);
5851	cc = si_setcoreidx(sih, SI_CC_IDX);
5852	ASSERT(cc != NULL);
5853
5854	switch (CHIPID(sih->chip)) {
5855	case BCM4328_CHIP_ID:
5856		si_pmu0_pllinit0(sih, osh, cc, xtalfreq);
5857		break;
5858	case BCM5354_CHIP_ID:
5859		if (xtalfreq == 0)
5860			xtalfreq = 25000;
5861		si_pmu0_pllinit0(sih, osh, cc, xtalfreq);
5862		break;
5863	case BCM4325_CHIP_ID:
5864		si_pmu1_pllinit0(sih, osh, cc, xtalfreq);
5865		break;
5866	case BCM4329_CHIP_ID:
5867		if (xtalfreq == 0)
5868			xtalfreq = 38400;
5869		si_pmu1_pllinit0(sih, osh, cc, xtalfreq);
5870		break;
5871	case BCM4312_CHIP_ID:
5872		/* assume default works */
5873		break;
5874	case BCM4322_CHIP_ID:
5875	case BCM43221_CHIP_ID:
5876	case BCM43231_CHIP_ID:
5877	case BCM4342_CHIP_ID: {
5878		if (CHIPREV(sih->chiprev) == 0) {
5879			uint32 minmask, maxmask;
5880
5881			minmask = R_REG(osh, PMUREG(sih, min_res_mask));
5882			maxmask = R_REG(osh, PMUREG(sih, max_res_mask));
5883
5884			/* Make sure the PLL is off: clear bit 4 & 5 of min/max_res_mask */
5885			/* Have to remove HT Avail request before powering off PLL */
5886			AND_REG(osh, PMUREG(sih, min_res_mask),	~(PMURES_BIT(RES4322_HT_SI_AVAIL)));
5887			AND_REG(osh, PMUREG(sih, max_res_mask),	~(PMURES_BIT(RES4322_HT_SI_AVAIL)));
5888			SPINWAIT(R_REG(osh, &cc->clk_ctl_st) & CCS_HTAVAIL, PMU_MAX_TRANSITION_DLY);
5889			AND_REG(osh, PMUREG(sih, min_res_mask),	~(PMURES_BIT(RES4322_SI_PLL_ON)));
5890			AND_REG(osh, PMUREG(sih, max_res_mask),	~(PMURES_BIT(RES4322_SI_PLL_ON)));
5891			OSL_DELAY(1000);
5892			ASSERT(!(R_REG(osh, &cc->clk_ctl_st) & CCS_HTAVAIL));
5893
5894
5895			W_REG(osh, PMUREG(sih, pllcontrol_addr), PMU2_SI_PLL_PLLCTL);
5896			W_REG(osh, PMUREG(sih, pllcontrol_data), 0x380005c0);
5897
5898
5899			OSL_DELAY(100);
5900			W_REG(osh, PMUREG(sih, max_res_mask), maxmask);
5901			OSL_DELAY(100);
5902			W_REG(osh, PMUREG(sih, min_res_mask), minmask);
5903			OSL_DELAY(100);
5904		}
5905
5906		break;
5907	}
5908
5909	case BCM4360_CHIP_ID: /* 4360B1 */
5910	case BCM43460_CHIP_ID:
5911	case BCM4352_CHIP_ID: {
5912		if (CHIPREV(sih->chiprev) > 2)
5913			si_set_bb_vcofreq_frac(sih, osh, 960, 98, 40);
5914		break;
5915	}
5916	case BCM43602_CHIP_ID:
5917	case BCM43462_CHIP_ID:
5918		si_set_bb_vcofreq_frac(sih, osh, 960, 98, 40);
5919		break;
5920	case BCM4313_CHIP_ID:
5921	case BCM43222_CHIP_ID:	case BCM43111_CHIP_ID:	case BCM43112_CHIP_ID:
5922	case BCM43224_CHIP_ID:	case BCM43225_CHIP_ID:  case BCM43420_CHIP_ID:
5923	case BCM43421_CHIP_ID:
5924	case BCM43226_CHIP_ID:
5925	case BCM43235_CHIP_ID:	case BCM43236_CHIP_ID:	case BCM43238_CHIP_ID:
5926	case BCM43237_CHIP_ID:
5927	case BCM43234_CHIP_ID:
5928	case BCM4331_CHIP_ID:
5929	case BCM43431_CHIP_ID:
5930	case BCM43131_CHIP_ID:
5931	case BCM43217_CHIP_ID:
5932	case BCM43227_CHIP_ID:
5933	case BCM43228_CHIP_ID:
5934	case BCM43428_CHIP_ID:
5935	case BCM6362_CHIP_ID:
5936		break;
5937	case BCM4315_CHIP_ID:
5938	case BCM4319_CHIP_ID:
5939	case BCM4336_CHIP_ID:
5940	case BCM43362_CHIP_ID:
5941	case BCM4330_CHIP_ID:
5942		si_pmu1_pllinit0(sih, osh, cc, xtalfreq);
5943		break;
5944	case BCM43239_CHIP_ID:
5945	case BCM4324_CHIP_ID:
5946	case BCM43242_CHIP_ID:
5947	case BCM43243_CHIP_ID:
5948	case BCM4335_CHIP_ID:
5949	case BCM4345_CHIP_ID:
5950		si_pmu1_pllinit1(sih, osh, cc, xtalfreq);
5951		break;
5952	case BCM4350_CHIP_ID:
5953	case BCM4354_CHIP_ID:
5954	case BCM4356_CHIP_ID:
5955	case BCM43556_CHIP_ID:
5956	case BCM43558_CHIP_ID:
5957	case BCM43566_CHIP_ID:
5958	case BCM43568_CHIP_ID:
5959	case BCM43569_CHIP_ID:
5960	case BCM43570_CHIP_ID:
5961		si_pmu1_pllinit1(sih, osh, cc, xtalfreq);
5962		if (xtalfreq == 40000)
5963			si_set_bb_vcofreq_frac(sih, osh, 968, 0, 40);
5964		break;
5965	case BCM4314_CHIP_ID:
5966	case BCM43142_CHIP_ID:
5967	case BCM43143_CHIP_ID:
5968	case BCM43341_CHIP_ID:
5969		if (xtalfreq == 0)
5970			xtalfreq = 20000;
5971		si_pmu2_pllinit0(sih, osh, cc, xtalfreq);
5972		break;
5973	case BCM4334_CHIP_ID:
5974		si_pmu2_pllinit0(sih, osh, cc, xtalfreq);
5975		break;
5976	default:
5977		PMU_MSG(("No PLL init done for chip %s rev %d pmurev %d\n",
5978		         bcm_chipname(sih->chip, chn, 8), sih->chiprev, sih->pmurev));
5979		break;
5980	}
5981
5982#ifdef BCMDBG_FORCEHT
5983	OR_REG(osh, &cc->clk_ctl_st, CCS_FORCEHT);
5984#endif
5985
5986	si_pmu_enb_slow_clk(sih, osh, xtalfreq);
5987
5988	/* Return to original core */
5989	si_setcoreidx(sih, origidx);
5990} /* si_pmu_pll_init */
5991
5992/** get alp clock frequency in [Hz] units */
5993uint32
5994BCMINITFN(si_pmu_alp_clock)(si_t *sih, osl_t *osh)
5995{
5996	chipcregs_t *cc;
5997	uint origidx;
5998	uint32 clock = ALP_CLOCK;
5999
6000	ASSERT(sih->cccaps & CC_CAP_PMU);
6001
6002	/* Remember original core before switch to chipc */
6003	origidx = si_coreidx(sih);
6004	cc = si_setcoreidx(sih, SI_CC_IDX);
6005	ASSERT(cc != NULL);
6006
6007	switch (CHIPID(sih->chip)) {
6008	case BCM4328_CHIP_ID:
6009		clock = si_pmu0_alpclk0(sih, osh, cc);
6010		break;
6011	case BCM5354_CHIP_ID:
6012		clock = si_pmu0_alpclk0(sih, osh, cc);
6013		break;
6014	case BCM4325_CHIP_ID:
6015		clock = si_pmu1_alpclk0(sih, osh, cc);
6016		break;
6017	case BCM4360_CHIP_ID:
6018	case BCM43460_CHIP_ID:
6019	case BCM4352_CHIP_ID:
6020	case BCM43526_CHIP_ID:
6021		if (sih->chipst & CST4360_XTAL_40MZ)
6022			clock = 40000 * 1000;
6023		else
6024			clock = 20000 * 1000;
6025		break;
6026
6027	case BCM43602_CHIP_ID:
6028	case BCM43462_CHIP_ID:
6029		/* always 40Mhz */
6030		clock = 40000 * 1000;
6031		break;
6032	case BCM4312_CHIP_ID:
6033	case BCM4322_CHIP_ID:	case BCM43221_CHIP_ID:	case BCM43231_CHIP_ID:
6034	case BCM43222_CHIP_ID:	case BCM43111_CHIP_ID:	case BCM43112_CHIP_ID:
6035	case BCM43224_CHIP_ID:	case BCM43225_CHIP_ID:  case BCM43420_CHIP_ID:
6036	case BCM43421_CHIP_ID:
6037	case BCM43226_CHIP_ID:
6038	case BCM43235_CHIP_ID:	case BCM43236_CHIP_ID:	case BCM43238_CHIP_ID:
6039	case BCM43237_CHIP_ID:	case BCM43239_CHIP_ID:
6040	case BCM43234_CHIP_ID:
6041	case BCM4331_CHIP_ID:
6042	case BCM43431_CHIP_ID:
6043	case BCM43131_CHIP_ID:
6044	case BCM43217_CHIP_ID:
6045	case BCM43227_CHIP_ID:
6046	case BCM43228_CHIP_ID:
6047	case BCM43428_CHIP_ID:
6048	case BCM6362_CHIP_ID:
6049	case BCM4342_CHIP_ID:
6050	case BCM4716_CHIP_ID:
6051	case BCM4748_CHIP_ID:
6052	case BCM47162_CHIP_ID:
6053	case BCM4313_CHIP_ID:
6054	case BCM5357_CHIP_ID:
6055	case BCM4749_CHIP_ID:
6056	case BCM53572_CHIP_ID:
6057		/* always 20Mhz */
6058		clock = 20000 * 1000;
6059		break;
6060	case BCM4329_CHIP_ID:
6061	case BCM4315_CHIP_ID:
6062	case BCM4319_CHIP_ID:
6063	case BCM4336_CHIP_ID:
6064	case BCM43362_CHIP_ID:
6065	case BCM4330_CHIP_ID:
6066	case BCM4324_CHIP_ID:
6067	case BCM43242_CHIP_ID:
6068	case BCM43243_CHIP_ID:
6069	case BCM4335_CHIP_ID:
6070	case BCM4345_CHIP_ID:
6071	case BCM4350_CHIP_ID:
6072	case BCM4354_CHIP_ID:
6073	case BCM4356_CHIP_ID:
6074	case BCM43556_CHIP_ID:
6075	case BCM43558_CHIP_ID:
6076	case BCM43566_CHIP_ID:
6077	case BCM43568_CHIP_ID:
6078	case BCM43569_CHIP_ID:
6079	case BCM43570_CHIP_ID:
6080		clock = si_pmu1_alpclk0(sih, osh, cc);
6081		break;
6082	case BCM4314_CHIP_ID:
6083	case BCM43142_CHIP_ID:
6084	case BCM43143_CHIP_ID:
6085	case BCM43341_CHIP_ID:
6086	case BCM4334_CHIP_ID:
6087		clock = si_pmu2_alpclk0(sih, osh, cc);
6088		break;
6089	case BCM5356_CHIP_ID:
6090	case BCM4706_CHIP_ID:
6091		/* always 25Mhz */
6092		clock = 25000 * 1000;
6093		break;
6094	default:
6095		PMU_MSG(("No ALP clock specified "
6096			"for chip %s rev %d pmurev %d, using default %d Hz\n",
6097			bcm_chipname(sih->chip, chn, 8), sih->chiprev, sih->pmurev, clock));
6098		break;
6099	}
6100
6101	/* Return to original core */
6102	si_setcoreidx(sih, origidx);
6103	return clock;
6104} /* si_pmu_alp_clock */
6105
6106/**
6107 * Find the output of the "m" pll divider given pll controls that start with
6108 * pllreg "pll0" i.e. 12 for main 6 for phy, 0 for misc.
6109 */
6110static uint32
6111BCMINITFN(si_pmu5_clock)(si_t *sih, osl_t *osh, chipcregs_t *cc, uint pll0, uint m)
6112{
6113	uint32 tmp, div, ndiv, p1, p2, fc;
6114
6115	if ((pll0 & 3) || (pll0 > PMU4716_MAINPLL_PLL0)) {
6116		PMU_ERROR(("%s: Bad pll0: %d\n", __FUNCTION__, pll0));
6117		return 0;
6118	}
6119
6120
6121	/* Strictly there is an m5 divider, but I'm not sure we use it */
6122	if ((m == 0) || (m > 4)) {
6123		PMU_ERROR(("%s: Bad m divider: %d\n", __FUNCTION__, m));
6124		return 0;
6125	}
6126
6127	if ((CHIPID(sih->chip) == BCM5357_CHIP_ID) ||
6128		(CHIPID(sih->chip) == BCM4749_CHIP_ID)) {
6129		/* Detect failure in clock setting */
6130		if ((R_REG(osh, &cc->chipstatus) & 0x40000) != 0) {
6131			return (133 * 1000000);
6132		}
6133	}
6134
6135	W_REG(osh, PMUREG(sih, pllcontrol_addr), pll0 + PMU5_PLL_P1P2_OFF);
6136	(void)R_REG(osh, PMUREG(sih, pllcontrol_addr));
6137	tmp = R_REG(osh, PMUREG(sih, pllcontrol_data));
6138	p1 = (tmp & PMU5_PLL_P1_MASK) >> PMU5_PLL_P1_SHIFT;
6139	p2 = (tmp & PMU5_PLL_P2_MASK) >> PMU5_PLL_P2_SHIFT;
6140
6141	W_REG(osh, PMUREG(sih, pllcontrol_addr), pll0 + PMU5_PLL_M14_OFF);
6142	(void)R_REG(osh, PMUREG(sih, pllcontrol_addr));
6143	tmp = R_REG(osh, PMUREG(sih, pllcontrol_data));
6144	div = (tmp >> ((m - 1) * PMU5_PLL_MDIV_WIDTH)) & PMU5_PLL_MDIV_MASK;
6145
6146	W_REG(osh, PMUREG(sih, pllcontrol_addr), pll0 + PMU5_PLL_NM5_OFF);
6147	(void)R_REG(osh, PMUREG(sih, pllcontrol_addr));
6148	tmp = R_REG(osh, PMUREG(sih, pllcontrol_data));
6149	ndiv = (tmp & PMU5_PLL_NDIV_MASK) >> PMU5_PLL_NDIV_SHIFT;
6150
6151	/* Do calculation in Mhz */
6152	fc = si_pmu_alp_clock(sih, osh) / 1000000;
6153	fc = (p1 * ndiv * fc) / p2;
6154
6155	PMU_NONE(("%s: p1=%d, p2=%d, ndiv=%d(0x%x), m%d=%d; fc=%d, clock=%d\n",
6156	          __FUNCTION__, p1, p2, ndiv, ndiv, m, div, fc, fc / div));
6157
6158	/* Return clock in Hertz */
6159	return ((fc / div) * 1000000);
6160} /* si_pmu5_clock */
6161
6162static uint32
6163BCMINITFN(si_4706_pmu_clock)(si_t *sih, osl_t *osh, chipcregs_t *cc, uint pll0, uint m)
6164{
6165	uint32 w, ndiv, p1div, p2div;
6166	uint32 clock;
6167
6168	/* Strictly there is an m5 divider, but I'm not sure we use it */
6169	if ((m == 0) || (m > 4)) {
6170		PMU_ERROR(("%s: Bad m divider: %d\n", __FUNCTION__, m));
6171		return 0;
6172	}
6173
6174	/* Get N, P1 and P2 dividers to determine CPU clock */
6175	W_REG(osh, PMUREG(sih, pllcontrol_addr), pll0 + PMU6_4706_PROCPLL_OFF);
6176	w = R_REG(NULL, PMUREG(sih, pllcontrol_data));
6177	ndiv = (w & PMU6_4706_PROC_NDIV_INT_MASK) >> PMU6_4706_PROC_NDIV_INT_SHIFT;
6178	p1div = (w & PMU6_4706_PROC_P1DIV_MASK) >> PMU6_4706_PROC_P1DIV_SHIFT;
6179	p2div = (w & PMU6_4706_PROC_P2DIV_MASK) >> PMU6_4706_PROC_P2DIV_SHIFT;
6180
6181	if (R_REG(osh, &cc->chipstatus) & CST4706_PKG_OPTION)
6182		/* Low cost bonding: Fixed reference clock 25MHz and m = 4 */
6183		clock = (25000000 / 4) * ndiv * p2div / p1div;
6184	else
6185		/* Fixed reference clock 25MHz and m = 2 */
6186		clock = (25000000 / 2) * ndiv * p2div / p1div;
6187
6188	if (m == PMU5_MAINPLL_MEM)
6189		clock = clock / 2;
6190	else if (m == PMU5_MAINPLL_SI)
6191		clock = clock / 4;
6192
6193	return clock;
6194}
6195
6196/**
6197 * Get backplane clock frequency, returns a value in [hz] units.
6198 * For designs that feed the same clock to both backplane and CPU just return the CPU clock speed.
6199 */
6200uint32
6201BCMINITFN(si_pmu_si_clock)(si_t *sih, osl_t *osh)
6202{
6203	chipcregs_t *cc;
6204	uint origidx;
6205	uint32 clock = HT_CLOCK;	/* in [hz] units */
6206
6207	ASSERT(sih->cccaps & CC_CAP_PMU);
6208
6209	/* Remember original core before switch to chipc */
6210	origidx = si_coreidx(sih);
6211	cc = si_setcoreidx(sih, SI_CC_IDX);
6212	ASSERT(cc != NULL);
6213
6214	switch (CHIPID(sih->chip)) {
6215	case BCM4328_CHIP_ID:
6216		clock = si_pmu0_cpuclk0(sih, osh, cc);
6217		break;
6218	case BCM5354_CHIP_ID:
6219		clock = 120000000;
6220		break;
6221	case BCM4325_CHIP_ID:
6222		clock = si_pmu1_cpuclk0(sih, osh, cc);
6223		break;
6224	case BCM4322_CHIP_ID:
6225	case BCM43221_CHIP_ID:	case BCM43231_CHIP_ID:
6226	case BCM43222_CHIP_ID:	case BCM43111_CHIP_ID:	case BCM43112_CHIP_ID:
6227	case BCM43224_CHIP_ID:  case BCM43420_CHIP_ID:
6228	case BCM43225_CHIP_ID:
6229	case BCM43421_CHIP_ID:
6230	case BCM43226_CHIP_ID:
6231	case BCM4331_CHIP_ID:
6232	case BCM43431_CHIP_ID:
6233	case BCM6362_CHIP_ID:
6234	case BCM4342_CHIP_ID:
6235		/* 96MHz backplane clock */
6236		clock = 96000 * 1000;
6237		break;
6238	case BCM4716_CHIP_ID:
6239	case BCM4748_CHIP_ID:
6240	case BCM47162_CHIP_ID:
6241		clock = si_pmu5_clock(sih, osh, cc, PMU4716_MAINPLL_PLL0, PMU5_MAINPLL_SI);
6242		break;
6243	case BCM4329_CHIP_ID:
6244		if (CHIPREV(sih->chiprev) == 0)
6245			clock = 38400 * 1000;
6246		else
6247			clock = si_pmu1_cpuclk0(sih, osh, cc);
6248		break;
6249	case BCM4315_CHIP_ID:
6250	case BCM4319_CHIP_ID:
6251	case BCM4336_CHIP_ID:
6252	case BCM43362_CHIP_ID:
6253	case BCM4330_CHIP_ID:
6254	case BCM43239_CHIP_ID:
6255	case BCM4324_CHIP_ID:
6256	case BCM43242_CHIP_ID:
6257	case BCM43243_CHIP_ID:
6258	case BCM4335_CHIP_ID:
6259	case BCM4345_CHIP_ID:
6260	case BCM4360_CHIP_ID:
6261	case BCM4350_CHIP_ID:
6262	case BCM4354_CHIP_ID:
6263	case BCM4356_CHIP_ID:
6264	case BCM43556_CHIP_ID:
6265	case BCM43558_CHIP_ID:
6266	case BCM43566_CHIP_ID:
6267	case BCM43568_CHIP_ID:
6268	case BCM43569_CHIP_ID:
6269	case BCM43570_CHIP_ID:
6270	case BCM43460_CHIP_ID:
6271	case BCM43526_CHIP_ID:
6272	case BCM4352_CHIP_ID:
6273		clock = si_pmu1_cpuclk0(sih, osh, cc);
6274		break;
6275	case BCM43462_CHIP_ID:
6276	case BCM43602_CHIP_ID: {
6277			uint32 mdiv;
6278			/* Ch3 is connected to backplane_clk. Read 'bbpll_i_m3div' from pllctl[4] */
6279			W_REG(osh, PMUREG(sih, pllcontrol_addr), PMU1_PLL0_PLLCTL4);
6280			mdiv = (R_REG(osh, PMUREG(sih, pllcontrol_data)) &
6281				PMU1_PLL0_PC1_M3DIV_MASK) >> PMU1_PLL0_PC1_M3DIV_SHIFT;
6282			clock = si_pmu1_pllfvco0(sih) / mdiv * 1000;
6283			break;
6284		}
6285	case BCM4313_CHIP_ID:
6286		/* 80MHz backplane clock */
6287		clock = 80000 * 1000;
6288		break;
6289	case BCM4314_CHIP_ID:
6290	case BCM43142_CHIP_ID:
6291	case BCM43143_CHIP_ID: /* HT clock and ARM clock have the same frequency */
6292	case BCM43341_CHIP_ID:
6293	case BCM4334_CHIP_ID:
6294		clock = si_pmu2_cpuclk0(sih, osh, cc);
6295		break;
6296	case BCM43235_CHIP_ID:	case BCM43236_CHIP_ID:	case BCM43238_CHIP_ID:
6297	case BCM43237_CHIP_ID:
6298	case BCM43234_CHIP_ID:
6299		clock = (cc->chipstatus & CST43236_BP_CLK) ? (120000 * 1000) : (96000 * 1000);
6300		break;
6301	case BCM5356_CHIP_ID:
6302		clock = si_pmu5_clock(sih, osh, cc, PMU5356_MAINPLL_PLL0, PMU5_MAINPLL_SI);
6303		break;
6304	case BCM5357_CHIP_ID:
6305	case BCM4749_CHIP_ID:
6306		clock = si_pmu5_clock(sih, osh, cc, PMU5357_MAINPLL_PLL0, PMU5_MAINPLL_SI);
6307		break;
6308	case BCM53572_CHIP_ID:
6309		clock = 75000000;
6310		break;
6311	case BCM4706_CHIP_ID:
6312		clock = si_4706_pmu_clock(sih, osh, cc, PMU4706_MAINPLL_PLL0, PMU5_MAINPLL_SI);
6313		break;
6314	default:
6315		PMU_MSG(("No backplane clock specified "
6316			"for chip %s rev %d pmurev %d, using default %d Hz\n",
6317			bcm_chipname(sih->chip, chn, 8), sih->chiprev, sih->pmurev, clock));
6318		break;
6319	}
6320
6321	/* Return to original core */
6322	si_setcoreidx(sih, origidx);
6323	return clock;
6324} /* si_pmu_si_clock */
6325
6326/** returns CPU clock frequency in [hz] units */
6327uint32
6328BCMINITFN(si_pmu_cpu_clock)(si_t *sih, osl_t *osh)
6329{
6330	chipcregs_t *cc;
6331	uint origidx;
6332	uint32 clock;	/* in [hz] units */
6333
6334	ASSERT(sih->cccaps & CC_CAP_PMU);
6335
6336	/* 5354 chip uses a non programmable PLL of frequency 240MHz */
6337	if (CHIPID(sih->chip) == BCM5354_CHIP_ID)
6338		return 240000000;
6339
6340	if (CHIPID(sih->chip) == BCM53572_CHIP_ID)
6341		return 300000000;
6342
6343	if ((sih->pmurev >= 5) &&
6344		!((CHIPID(sih->chip) == BCM4329_CHIP_ID) ||
6345		(CHIPID(sih->chip) == BCM4319_CHIP_ID) ||
6346		(CHIPID(sih->chip) == BCM43234_CHIP_ID) ||
6347		(CHIPID(sih->chip) == BCM43235_CHIP_ID) ||
6348		(CHIPID(sih->chip) == BCM43236_CHIP_ID) ||
6349		(CHIPID(sih->chip) == BCM43238_CHIP_ID) ||
6350		(CHIPID(sih->chip) == BCM43237_CHIP_ID) ||
6351		(CHIPID(sih->chip) == BCM43239_CHIP_ID) ||
6352		(CHIPID(sih->chip) == BCM4336_CHIP_ID) ||
6353		(CHIPID(sih->chip) == BCM43362_CHIP_ID) ||
6354		(CHIPID(sih->chip) == BCM4314_CHIP_ID) ||
6355		(CHIPID(sih->chip) == BCM43142_CHIP_ID) ||
6356		(CHIPID(sih->chip) == BCM43143_CHIP_ID) ||
6357		(CHIPID(sih->chip) == BCM43341_CHIP_ID) ||
6358		(CHIPID(sih->chip) == BCM4334_CHIP_ID) ||
6359		(CHIPID(sih->chip) == BCM4324_CHIP_ID) ||
6360		(CHIPID(sih->chip) == BCM43242_CHIP_ID) ||
6361		(CHIPID(sih->chip) == BCM43243_CHIP_ID) ||
6362		(CHIPID(sih->chip) == BCM4330_CHIP_ID) ||
6363		(CHIPID(sih->chip) == BCM4360_CHIP_ID) ||
6364		(CHIPID(sih->chip) == BCM4352_CHIP_ID) ||
6365		(CHIPID(sih->chip) == BCM43526_CHIP_ID) ||
6366		(CHIPID(sih->chip) == BCM43460_CHIP_ID) ||
6367		(CHIPID(sih->chip) == BCM4345_CHIP_ID) ||
6368		BCM4350_CHIP(sih->chip) ||
6369		(CHIPID(sih->chip) == BCM4335_CHIP_ID) ||
6370		0)) {
6371		uint pll;
6372
6373		switch (CHIPID(sih->chip)) {
6374		case BCM5356_CHIP_ID:
6375			pll = PMU5356_MAINPLL_PLL0;
6376			break;
6377		case BCM5357_CHIP_ID:
6378		case BCM4749_CHIP_ID:
6379			pll = PMU5357_MAINPLL_PLL0;
6380			break;
6381		default:
6382			pll = PMU4716_MAINPLL_PLL0;
6383			break;
6384		}
6385
6386		/* Remember original core before switch to chipc */
6387		origidx = si_coreidx(sih);
6388		cc = si_setcoreidx(sih, SI_CC_IDX);
6389		ASSERT(cc != NULL);
6390
6391		if (CHIPID(sih->chip) == BCM4706_CHIP_ID)
6392			clock = si_4706_pmu_clock(sih, osh, cc,
6393				PMU4706_MAINPLL_PLL0, PMU5_MAINPLL_CPU);
6394		else if (CHIPID(sih->chip) == BCM43602_CHIP_ID ||
6395			CHIPID(sih->chip) == BCM43462_CHIP_ID)
6396			clock = si_pmu1_cpuclk0(sih, osh, cc);
6397		else
6398			clock = si_pmu5_clock(sih, osh, cc, pll, PMU5_MAINPLL_CPU);
6399
6400		/* Return to original core */
6401		si_setcoreidx(sih, origidx);
6402	} else
6403		clock = si_pmu_si_clock(sih, osh);
6404
6405	return clock;
6406} /* si_pmu_cpu_clock */
6407
6408/** get memory clock frequency, which is the same as the HT clock for newer chips. Returns [Hz]. */
6409uint32
6410BCMINITFN(si_pmu_mem_clock)(si_t *sih, osl_t *osh)
6411{
6412	chipcregs_t *cc;
6413	uint origidx;
6414	uint32 clock;
6415
6416	ASSERT(sih->cccaps & CC_CAP_PMU);
6417
6418	if (CHIPID(sih->chip) == BCM53572_CHIP_ID)
6419		return 150000000;
6420
6421	if ((sih->pmurev >= 5) &&
6422		!((CHIPID(sih->chip) == BCM4329_CHIP_ID) ||
6423		(CHIPID(sih->chip) == BCM4319_CHIP_ID) ||
6424		(CHIPID(sih->chip) == BCM4330_CHIP_ID) ||
6425		(CHIPID(sih->chip) == BCM4314_CHIP_ID) ||
6426		(CHIPID(sih->chip) == BCM43142_CHIP_ID) ||
6427		(CHIPID(sih->chip) == BCM43143_CHIP_ID) ||
6428		(CHIPID(sih->chip) == BCM43341_CHIP_ID) ||
6429		(CHIPID(sih->chip) == BCM4334_CHIP_ID) ||
6430		(CHIPID(sih->chip) == BCM4336_CHIP_ID) ||
6431		(CHIPID(sih->chip) == BCM43362_CHIP_ID) ||
6432		(CHIPID(sih->chip) == BCM43234_CHIP_ID) ||
6433		(CHIPID(sih->chip) == BCM43235_CHIP_ID) ||
6434		(CHIPID(sih->chip) == BCM43236_CHIP_ID) ||
6435		(CHIPID(sih->chip) == BCM43238_CHIP_ID) ||
6436		(CHIPID(sih->chip) == BCM43237_CHIP_ID) ||
6437		(CHIPID(sih->chip) == BCM43239_CHIP_ID) ||
6438		(CHIPID(sih->chip) == BCM4324_CHIP_ID) ||
6439		(CHIPID(sih->chip) == BCM43242_CHIP_ID) ||
6440		(CHIPID(sih->chip) == BCM43243_CHIP_ID) ||
6441		(CHIPID(sih->chip) == BCM4335_CHIP_ID) ||
6442		(CHIPID(sih->chip) == BCM4345_CHIP_ID) ||
6443		(CHIPID(sih->chip) == BCM43602_CHIP_ID) ||
6444		(CHIPID(sih->chip) == BCM43462_CHIP_ID) ||
6445		BCM4350_CHIP(sih->chip) ||
6446		0)) {
6447		uint pll;
6448
6449		switch (CHIPID(sih->chip)) {
6450		case BCM5356_CHIP_ID:
6451			pll = PMU5356_MAINPLL_PLL0;
6452			break;
6453		case BCM5357_CHIP_ID:
6454		case BCM4749_CHIP_ID:
6455			pll = PMU5357_MAINPLL_PLL0;
6456			break;
6457		default:
6458			pll = PMU4716_MAINPLL_PLL0;
6459			break;
6460		}
6461
6462		/* Remember original core before switch to chipc */
6463		origidx = si_coreidx(sih);
6464		cc = si_setcoreidx(sih, SI_CC_IDX);
6465		ASSERT(cc != NULL);
6466
6467		if (CHIPID(sih->chip) == BCM4706_CHIP_ID)
6468			clock = si_4706_pmu_clock(sih, osh, cc,
6469				PMU4706_MAINPLL_PLL0, PMU5_MAINPLL_MEM);
6470		else
6471			clock = si_pmu5_clock(sih, osh, cc, pll, PMU5_MAINPLL_MEM);
6472
6473		/* Return to original core */
6474		si_setcoreidx(sih, origidx);
6475	} else {
6476		clock = si_pmu_si_clock(sih, osh);
6477	}
6478
6479	return clock;
6480} /* si_pmu_mem_clock */
6481
6482/*
6483 * ilpcycles per sec are now calculated during CPU init in a new way
6484 * for better accuracy.  We set it here for compatability.
6485 *
6486 * On platforms that do not do this we resort to the old way.
6487 */
6488
6489#define ILP_CALC_DUR	10	/* ms, make sure 1000 can be divided by it. */
6490
6491static uint32 ilpcycles_per_sec = 0;
6492
6493void
6494BCMINITFN(si_pmu_ilp_clock_set)(uint32 cycles_per_sec)
6495{
6496	ilpcycles_per_sec = cycles_per_sec;
6497}
6498
6499uint32
6500BCMINITFN(si_pmu_ilp_clock)(si_t *sih, osl_t *osh)
6501{
6502	if (ISSIM_ENAB(sih))
6503		return ILP_CLOCK;
6504
6505	if (ilpcycles_per_sec == 0) {
6506		uint32 start, end, delta;
6507		start = R_REG(osh, PMUREG(sih, pmutimer));
6508		if (start != R_REG(osh, PMUREG(sih, pmutimer)))
6509			start = R_REG(osh, PMUREG(sih, pmutimer));
6510		OSL_DELAY(ILP_CALC_DUR * 1000);
6511		end = R_REG(osh, PMUREG(sih, pmutimer));
6512		if (end != R_REG(osh, PMUREG(sih, pmutimer)))
6513			end = R_REG(osh, PMUREG(sih, pmutimer));
6514		delta = end - start;
6515		ilpcycles_per_sec = delta * (1000 / ILP_CALC_DUR);
6516	}
6517
6518	return ilpcycles_per_sec;
6519}
6520
6521/* SDIO Pad drive strength to select value mappings.
6522 * The last strength value in each table must be 0 (the tri-state value).
6523 */
6524typedef struct {
6525	uint8 strength;			/* Pad Drive Strength in mA */
6526	uint8 sel;			/* Chip-specific select value */
6527} sdiod_drive_str_t;
6528
6529/* SDIO Drive Strength to sel value table for PMU Rev 1 */
6530static const sdiod_drive_str_t BCMINITDATA(sdiod_drive_strength_tab1)[] = {
6531	{4, 0x2},
6532	{2, 0x3},
6533	{1, 0x0},
6534	{0, 0x0} };
6535
6536/* SDIO Drive Strength to sel value table for PMU Rev 2, 3 */
6537static const sdiod_drive_str_t BCMINITDATA(sdiod_drive_strength_tab2)[] = {
6538	{12, 0x7},
6539	{10, 0x6},
6540	{8, 0x5},
6541	{6, 0x4},
6542	{4, 0x2},
6543	{2, 0x1},
6544	{0, 0x0} };
6545
6546/* SDIO Drive Strength to sel value table for PMU Rev 8 (1.8V) */
6547static const sdiod_drive_str_t BCMINITDATA(sdiod_drive_strength_tab3)[] = {
6548	{32, 0x7},
6549	{26, 0x6},
6550	{22, 0x5},
6551	{16, 0x4},
6552	{12, 0x3},
6553	{8, 0x2},
6554	{4, 0x1},
6555	{0, 0x0} };
6556
6557/* SDIO Drive Strength to sel value table for PMU Rev 11 (1.8v) */
6558static const sdiod_drive_str_t BCMINITDATA(sdiod_drive_strength_tab4_1v8)[] = {
6559	{32, 0x6},
6560	{26, 0x7},
6561	{22, 0x4},
6562	{16, 0x5},
6563	{12, 0x2},
6564	{8, 0x3},
6565	{4, 0x0},
6566	{0, 0x1} };
6567
6568/* SDIO Drive Strength to sel value table for PMU Rev 11 (1.2v) */
6569
6570/* SDIO Drive Strength to sel value table for PMU Rev 11 (2.5v) */
6571
6572/* SDIO Drive Strength to sel value table for PMU Rev 13 (1.8v) */
6573static const sdiod_drive_str_t BCMINITDATA(sdiod_drive_strength_tab5_1v8)[] = {
6574	{6, 0x7},
6575	{5, 0x6},
6576	{4, 0x5},
6577	{3, 0x4},
6578	{2, 0x2},
6579	{1, 0x1},
6580	{0, 0x0} };
6581
6582/* SDIO Drive Strength to sel value table for PMU Rev 13 (3.3v) */
6583
6584/** SDIO Drive Strength to sel value table for PMU Rev 17 (1.8v) */
6585static const sdiod_drive_str_t BCMINITDATA(sdiod_drive_strength_tab6_1v8)[] = {
6586	{3, 0x3},
6587	{2, 0x2},
6588	{1, 0x1},
6589	{0, 0x0} };
6590
6591
6592/**
6593 * SDIO Drive Strength to sel value table for 43143 PMU Rev 17, see Confluence 43143 Toplevel
6594 * architecture page, section 'PMU Chip Control 1 Register definition', click link to picture
6595 * BCM43143_sel_sdio_signals.jpg. Valid after PMU Chip Control 0 Register, bit31 (override) has
6596 * been written '1'.
6597 */
6598#if !defined(BCM_SDIO_VDDIO) || BCM_SDIO_VDDIO == 33
6599
6600static const sdiod_drive_str_t BCMINITDATA(sdiod_drive_strength_tab7_3v3)[] = {
6601	/* note: for 14, 10, 6 and 2mA hw timing is not met according to rtl team */
6602	{16, 0x7},
6603	{12, 0x5},
6604	{8,  0x3},
6605	{4,  0x1} }; /* note: 43143 does not support tristate */
6606
6607#else
6608
6609static const sdiod_drive_str_t BCMINITDATA(sdiod_drive_strength_tab7_1v8)[] = {
6610	/* note: for 7, 5, 3 and 1mA hw timing is not met according to rtl team */
6611	{8, 0x7},
6612	{6, 0x5},
6613	{4,  0x3},
6614	{2,  0x1} }; /* note: 43143 does not support tristate */
6615
6616#endif /* BCM_SDIO_VDDIO */
6617
6618#define SDIOD_DRVSTR_KEY(chip, pmu)	(((chip) << 16) | (pmu))
6619
6620/**
6621 * Balance between stable SDIO operation and power consumption is achieved using this function.
6622 * Note that each drive strength table is for a specific VDDIO of the SDIO pads, ideally this
6623 * function should read the VDDIO itself to select the correct table. For now it has been solved
6624 * with the 'BCM_SDIO_VDDIO' preprocessor constant.
6625 *
6626 * 'drivestrength': desired pad drive strength in mA. Drive strength of 0 requests tri-state (if
6627 *		    hardware supports this), if no hw support drive strength is not programmed.
6628 */
6629void
6630BCMINITFN(si_sdiod_drive_strength_init)(si_t *sih, osl_t *osh, uint32 drivestrength)
6631{
6632	sdiod_drive_str_t *str_tab = NULL;
6633	uint32 str_mask = 0;	/* only alter desired bits in PMU chipcontrol 1 register */
6634	uint32 str_shift = 0;
6635	uint32 str_ovr_pmuctl = PMU_CHIPCTL0; /* PMU chipcontrol register containing override bit */
6636	uint32 str_ovr_pmuval = 0;            /* position of bit within this register */
6637
6638	if (!(sih->cccaps & CC_CAP_PMU)) {
6639		return;
6640	}
6641
6642	switch (SDIOD_DRVSTR_KEY(sih->chip, sih->pmurev)) {
6643	case SDIOD_DRVSTR_KEY(BCM4325_CHIP_ID, 1):
6644		str_tab = (sdiod_drive_str_t *)&sdiod_drive_strength_tab1;
6645		str_mask = 0x30000000;
6646		str_shift = 28;
6647		break;
6648	case SDIOD_DRVSTR_KEY(BCM4325_CHIP_ID, 2):
6649	case SDIOD_DRVSTR_KEY(BCM4325_CHIP_ID, 3):
6650	case SDIOD_DRVSTR_KEY(BCM4315_CHIP_ID, 4):
6651		str_tab = (sdiod_drive_str_t *)&sdiod_drive_strength_tab2;
6652		str_mask = 0x00003800;
6653		str_shift = 11;
6654		break;
6655	case SDIOD_DRVSTR_KEY(BCM4336_CHIP_ID, 8):
6656	case SDIOD_DRVSTR_KEY(BCM4336_CHIP_ID, 11):
6657		if (sih->pmurev == 8) {
6658			str_tab = (sdiod_drive_str_t *)&sdiod_drive_strength_tab3;
6659		}
6660		else if (sih->pmurev == 11) {
6661			str_tab = (sdiod_drive_str_t *)&sdiod_drive_strength_tab4_1v8;
6662		}
6663		str_mask = 0x00003800;
6664		str_shift = 11;
6665		break;
6666	case SDIOD_DRVSTR_KEY(BCM4330_CHIP_ID, 12):
6667		str_tab = (sdiod_drive_str_t *)&sdiod_drive_strength_tab4_1v8;
6668		str_mask = 0x00003800;
6669		str_shift = 11;
6670		break;
6671	case SDIOD_DRVSTR_KEY(BCM43362_CHIP_ID, 13):
6672		str_tab = (sdiod_drive_str_t *)&sdiod_drive_strength_tab5_1v8;
6673		str_mask = 0x00003800;
6674		str_shift = 11;
6675		break;
6676	case SDIOD_DRVSTR_KEY(BCM4334_CHIP_ID, 17):
6677		str_tab = (sdiod_drive_str_t *)&sdiod_drive_strength_tab6_1v8;
6678		str_mask = 0x00001800;
6679		str_shift = 11;
6680		break;
6681	case SDIOD_DRVSTR_KEY(BCM43143_CHIP_ID, 17):
6682#if !defined(BCM_SDIO_VDDIO) || BCM_SDIO_VDDIO == 33
6683		if (drivestrength >=  ARRAYLAST(sdiod_drive_strength_tab7_3v3)->strength) {
6684			str_tab = (sdiod_drive_str_t *)&sdiod_drive_strength_tab7_3v3;
6685		}
6686#else
6687		if (drivestrength >=  ARRAYLAST(sdiod_drive_strength_tab7_1v8)->strength) {
6688			str_tab = (sdiod_drive_str_t *)&sdiod_drive_strength_tab7_1v8;
6689		}
6690#endif /* BCM_SDIO_VDDIO */
6691		str_mask = 0x00000007;
6692		str_ovr_pmuval = PMU43143_CC0_SDIO_DRSTR_OVR;
6693		break;
6694	default:
6695		PMU_MSG(("No SDIO Drive strength init done for chip %s rev %d pmurev %d\n",
6696		         bcm_chipname(sih->chip, chn, 8), sih->chiprev, sih->pmurev));
6697		break;
6698	}
6699
6700	if (str_tab != NULL) {
6701		uint32 cc_data_temp;
6702		int i;
6703
6704		/* Pick the lowest available drive strength equal or greater than the
6705		 * requested strength.	Drive strength of 0 requests tri-state.
6706		 */
6707		for (i = 0; drivestrength < str_tab[i].strength; i++)
6708			;
6709
6710		if (i > 0 && drivestrength > str_tab[i].strength)
6711			i--;
6712
6713		W_REG(osh, PMUREG(sih, chipcontrol_addr), PMU_CHIPCTL1);
6714		cc_data_temp = R_REG(osh, PMUREG(sih, chipcontrol_data));
6715		cc_data_temp &= ~str_mask;
6716		cc_data_temp |= str_tab[i].sel << str_shift;
6717		W_REG(osh, PMUREG(sih, chipcontrol_data), cc_data_temp);
6718		if (str_ovr_pmuval) { /* enables the selected drive strength */
6719			W_REG(osh,  PMUREG(sih, chipcontrol_addr), str_ovr_pmuctl);
6720			OR_REG(osh, PMUREG(sih, chipcontrol_data), str_ovr_pmuval);
6721		}
6722		PMU_MSG(("SDIO: %dmA drive strength requested; set to %dmA\n",
6723		         drivestrength, str_tab[i].strength));
6724	}
6725} /* si_sdiod_drive_strength_init */
6726
6727/* initialize PMU */
6728void
6729BCMATTACHFN(si_pmu_init)(si_t *sih, osl_t *osh)
6730{
6731	ASSERT(sih->cccaps & CC_CAP_PMU);
6732
6733	if (sih->pmurev == 1)
6734		AND_REG(osh, PMUREG(sih, pmucontrol), ~PCTL_NOILP_ON_WAIT);
6735	else if (sih->pmurev >= 2)
6736		OR_REG(osh, PMUREG(sih, pmucontrol), PCTL_NOILP_ON_WAIT);
6737
6738	switch (CHIPID(sih->chip)) {
6739	case BCM4329_CHIP_ID:
6740		if (CHIPREV(sih->chiprev) == 2) {
6741			/* Fix for 4329b0 bad LPOM state. */
6742			W_REG(osh, PMUREG(sih, regcontrol_addr), 2);
6743			OR_REG(osh, PMUREG(sih, regcontrol_data), 0x100);
6744
6745			W_REG(osh, PMUREG(sih, regcontrol_addr), 3);
6746			OR_REG(osh, PMUREG(sih, regcontrol_data), 0x4);
6747		}
6748		break;
6749	case BCM4345_CHIP_ID:
6750#ifdef SRFAST
6751		OR_REG(osh, PMUREG(sih, pmucontrol_ext), 1 << PCTLEX_FTE_SHIFT);
6752#endif
6753		break;
6754	case BCM4354_CHIP_ID:
6755	case BCM4356_CHIP_ID:
6756	case BCM43569_CHIP_ID:
6757	case BCM43570_CHIP_ID:
6758#ifdef SRFAST
6759		/* Similar to 4350C0, rev 3 */
6760		OR_REG(osh, PMUREG(sih, pmucontrol_ext), 1 << PCTLEX_FTE_SHIFT);
6761#endif
6762		break;
6763	case BCM4350_CHIP_ID:
6764	case BCM43556_CHIP_ID:
6765	case BCM43558_CHIP_ID:
6766	case BCM43566_CHIP_ID:
6767	case BCM43568_CHIP_ID:
6768#ifdef SRFAST
6769		/* Does not apply to Bx */
6770		if (CHIPREV(sih->chiprev) > 2)
6771			OR_REG(osh, PMUREG(sih, pmucontrol_ext), 1 << PCTLEX_FTE_SHIFT);
6772#endif
6773		break;
6774	default:
6775		break;
6776	}
6777}
6778
6779static uint
6780BCMINITFN(si_pmu_res_uptime)(si_t *sih, osl_t *osh, chipcregs_t *cc, uint8 rsrc)
6781{
6782	uint32 deps;
6783	uint uptime, i, dup, dmax;
6784	uint32 min_mask = 0;
6785#ifndef SR_DEBUG
6786	uint32 max_mask = 0;
6787#endif /* SR_DEBUG */
6788
6789	/* uptime of resource 'rsrc' */
6790	W_REG(osh, PMUREG(sih, res_table_sel), rsrc);
6791	if (sih->pmurev >= 13)
6792		uptime = (R_REG(osh, PMUREG(sih, res_updn_timer)) >> 16) & 0x3ff;
6793	else
6794		uptime = (R_REG(osh, PMUREG(sih, res_updn_timer)) >> 8) & 0xff;
6795
6796	/* direct dependencies of resource 'rsrc' */
6797	deps = si_pmu_res_deps(sih, osh, cc, PMURES_BIT(rsrc), FALSE);
6798	for (i = 0; i <= PMURES_MAX_RESNUM; i ++) {
6799		if (!(deps & PMURES_BIT(i)))
6800			continue;
6801		deps &= ~si_pmu_res_deps(sih, osh, cc, PMURES_BIT(i), TRUE);
6802	}
6803#ifndef SR_DEBUG
6804	si_pmu_res_masks(sih, &min_mask, &max_mask);
6805#else
6806	/* Recalculate fast pwr up delay if min res mask/max res mask has changed */
6807	min_mask = R_REG(osh, &cc->min_res_mask);
6808#endif /* SR_DEBUG */
6809	deps &= ~min_mask;
6810
6811	/* max uptime of direct dependencies */
6812	dmax = 0;
6813	for (i = 0; i <= PMURES_MAX_RESNUM; i ++) {
6814		if (!(deps & PMURES_BIT(i)))
6815			continue;
6816		dup = si_pmu_res_uptime(sih, osh, cc, (uint8)i);
6817		if (dmax < dup)
6818			dmax = dup;
6819	}
6820
6821	PMU_MSG(("si_pmu_res_uptime: rsrc %u uptime %u(deps 0x%08x uptime %u)\n",
6822	         rsrc, uptime, deps, dmax));
6823
6824	return uptime + dmax + PMURES_UP_TRANSITION;
6825}
6826
6827/* Return dependencies (direct or all/indirect) for the given resources */
6828static uint32
6829si_pmu_res_deps(si_t *sih, osl_t *osh, chipcregs_t *cc, uint32 rsrcs, bool all)
6830{
6831	uint32 deps = 0;
6832	uint32 i;
6833
6834	for (i = 0; i <= PMURES_MAX_RESNUM; i ++) {
6835		if (!(rsrcs & PMURES_BIT(i)))
6836			continue;
6837		W_REG(osh, PMUREG(sih, res_table_sel), i);
6838		deps |= R_REG(osh, PMUREG(sih, res_dep_mask));
6839	}
6840
6841	return !all ? deps : (deps ? (deps | si_pmu_res_deps(sih, osh, cc, deps, TRUE)) : 0);
6842}
6843
6844/**
6845 * OTP is powered down/up as a means of resetting it, or for saving current when OTP is unused.
6846 * OTP is powered up/down through PMU resources.
6847 * OTP will turn OFF only if its not in the dependency of any "higher" rsrc in min_res_mask
6848 */
6849void
6850si_pmu_otp_power(si_t *sih, osl_t *osh, bool on, uint32* min_res_mask)
6851{
6852	chipcregs_t *cc;
6853	uint origidx;
6854	uint32 rsrcs = 0;	/* rsrcs to turn on/off OTP power */
6855	rsc_per_chip_t *rsc;	/* chip specific resource bit positions */
6856
6857	ASSERT(sih->cccaps & CC_CAP_PMU);
6858
6859	/* Don't do anything if OTP is disabled */
6860	if (si_is_otp_disabled(sih)) {
6861		PMU_MSG(("si_pmu_otp_power: OTP is disabled\n"));
6862		return;
6863	}
6864
6865	/* Remember original core before switch to chipc */
6866	origidx = si_coreidx(sih);
6867	cc = si_setcoreidx(sih, SI_CC_IDX);
6868	ASSERT(cc != NULL);
6869
6870	/*
6871	 * OTP can't be power cycled by toggling OTP_PU for always on OTP chips. For now
6872	 * corerev 45 is the only one that has always on OTP.
6873	 * Instead, the chipc register OTPCtrl1 (Offset 0xF4) bit 25 (forceOTPpwrDis) is used.
6874	 * Please refer to http://hwnbu-twiki.broadcom.com/bin/view/Mwgroup/ChipcommonRev45
6875	 */
6876	if (sih->ccrev == 45) {
6877		uint32 otpctrl1;
6878		otpctrl1 = R_REG(osh,  &cc->otpcontrol1);
6879		if (on)
6880			otpctrl1 &= ~OTPC_FORCE_PWR_OFF;
6881		else
6882			otpctrl1 |= OTPC_FORCE_PWR_OFF;
6883		W_REG(osh,  &cc->otpcontrol1, otpctrl1);
6884		/* Return to original core */
6885		si_setcoreidx(sih, origidx);
6886		return;
6887	}
6888
6889	switch (CHIPID(sih->chip)) {
6890	case BCM4322_CHIP_ID:
6891	case BCM43221_CHIP_ID:
6892	case BCM43231_CHIP_ID:
6893	case BCM4342_CHIP_ID:
6894	case BCM4325_CHIP_ID:
6895	case BCM4315_CHIP_ID:
6896	case BCM4329_CHIP_ID:
6897	case BCM4319_CHIP_ID:
6898	case BCM4336_CHIP_ID:
6899	case BCM43362_CHIP_ID:
6900	case BCM4330_CHIP_ID:
6901	case BCM4314_CHIP_ID:
6902	case BCM43142_CHIP_ID:
6903	case BCM43143_CHIP_ID:
6904	case BCM4334_CHIP_ID:
6905	case BCM4324_CHIP_ID:
6906	case BCM43242_CHIP_ID:
6907	case BCM43243_CHIP_ID:
6908	case BCM4335_CHIP_ID:
6909	case BCM4345_CHIP_ID:	/* same OTP PU as 4350 */
6910	case BCM4350_CHIP_ID:
6911	case BCM4354_CHIP_ID:
6912	case BCM4356_CHIP_ID:
6913	case BCM43556_CHIP_ID:
6914	case BCM43558_CHIP_ID:
6915	case BCM43566_CHIP_ID:
6916	case BCM43568_CHIP_ID:
6917	case BCM43569_CHIP_ID:
6918	case BCM43570_CHIP_ID:
6919	case BCM4360_CHIP_ID:
6920	case BCM43460_CHIP_ID:
6921	case BCM4352_CHIP_ID:
6922	case BCM43526_CHIP_ID:
6923		rsc = si_pmu_get_rsc_positions(sih);
6924		rsrcs = PMURES_BIT(rsc->otp_pu);
6925		break;
6926	default:
6927		break;
6928	}
6929
6930	if (rsrcs != 0) {
6931		uint32 otps;
6932		bool on_check = FALSE; /* Stores otp_ready state */
6933		uint32 min_mask = 0;
6934
6935		/* Turn on/off the power */
6936		if (on) {
6937			min_mask = R_REG(osh, PMUREG(sih, min_res_mask));
6938			*min_res_mask = min_mask;
6939
6940			min_mask |= rsrcs;
6941			min_mask |= si_pmu_res_deps(sih, osh, cc, min_mask, TRUE);
6942			on_check = TRUE;
6943			/* Assuming max rsc mask defines OTP_PU, so not programming max */
6944			PMU_MSG(("Adding rsrc 0x%x to min_res_mask\n", min_mask));
6945			W_REG(osh, PMUREG(sih, min_res_mask), min_mask);
6946			si_pmu_wait_for_steady_state(sih, osh, cc);
6947			OSL_DELAY(1000);
6948			SPINWAIT(!(R_REG(osh, PMUREG(sih, res_state)) & rsrcs),
6949				PMU_MAX_TRANSITION_DLY);
6950			ASSERT(R_REG(osh, PMUREG(sih, res_state)) & rsrcs);
6951		}
6952		else {
6953			/*
6954			 * Restore back the min_res_mask,
6955			 * but keep OTP powered off if allowed by dependencies
6956			 */
6957			if (*min_res_mask)
6958				min_mask = *min_res_mask;
6959			else
6960				min_mask = R_REG(osh, PMUREG(sih, min_res_mask));
6961
6962			min_mask &= ~rsrcs;
6963			/*
6964			 * OTP rsrc can be cleared only if its not
6965			 * in the dependency of any "higher" rsrc in min_res_mask
6966			 */
6967			min_mask |= si_pmu_res_deps(sih, osh, cc, min_mask, TRUE);
6968			on_check = ((min_mask & rsrcs) != 0);
6969
6970			PMU_MSG(("Removing rsrc 0x%x from min_res_mask\n", min_mask));
6971			W_REG(osh, PMUREG(sih, min_res_mask), min_mask);
6972			si_pmu_wait_for_steady_state(sih, osh, cc);
6973		}
6974
6975		SPINWAIT((((otps = R_REG(osh, &cc->otpstatus)) & OTPS_READY) !=
6976			(on_check ? OTPS_READY : 0)), 3000);
6977		ASSERT((otps & OTPS_READY) == (on_check ? OTPS_READY : 0));
6978		if ((otps & OTPS_READY) != (on_check ? OTPS_READY : 0))
6979			PMU_MSG(("OTP ready bit not %s after wait\n", (on_check ? "ON" : "OFF")));
6980	}
6981
6982	/* Return to original core */
6983	si_setcoreidx(sih, origidx);
6984} /* si_pmu_otp_power */
6985
6986/** only called for SSN and LP phy's. */
6987void
6988si_pmu_rcal(si_t *sih, osl_t *osh)
6989{
6990	chipcregs_t *cc;
6991	uint origidx;
6992	uint rcal_done, BT_out_of_reset;
6993
6994	ASSERT(sih->cccaps & CC_CAP_PMU);
6995
6996	/* Remember original core before switch to chipc */
6997	origidx = si_coreidx(sih);
6998	cc = si_setcoreidx(sih, SI_CC_IDX);
6999	ASSERT(cc != NULL);
7000
7001	switch (CHIPID(sih->chip)) {
7002	case BCM4325_CHIP_ID: {
7003		uint8 rcal_code;
7004		uint32 val;
7005
7006		/* Kick RCal */
7007		W_REG(osh, PMUREG(sih, chipcontrol_addr), 1);
7008
7009		/* Power Down RCAL Block */
7010		AND_REG(osh, PMUREG(sih, chipcontrol_data), ~0x04);
7011
7012		/* Check if RCAL is already done by BT */
7013		rcal_done = ((R_REG(osh, &cc->chipstatus)) & 0x8) >> 3;
7014
7015		/* If RCAL already done, note that BT is out of reset */
7016		if (rcal_done == 1) {
7017			BT_out_of_reset = 1;
7018		} else {
7019			BT_out_of_reset = 0;
7020		}
7021
7022		/* Power Up RCAL block */
7023		OR_REG(osh, PMUREG(sih, chipcontrol_data), 0x04);
7024
7025		/* Wait for completion */
7026		SPINWAIT(!(R_REG(osh, &cc->chipstatus) & 0x08), 10 * 1000 * 1000);
7027		ASSERT(R_REG(osh, &cc->chipstatus) & 0x08);
7028
7029		if (BT_out_of_reset) {
7030			rcal_code = 0x6;
7031		} else {
7032			/* Drop the LSB to convert from 5 bit code to 4 bit code */
7033			rcal_code =  (uint8)(R_REG(osh, &cc->chipstatus) >> 5) & 0x0f;
7034		}
7035
7036		PMU_MSG(("RCal completed, status 0x%x, code 0x%x\n",
7037			R_REG(osh, &cc->chipstatus), rcal_code));
7038
7039		/* Write RCal code into pmu_vreg_ctrl[32:29] */
7040		W_REG(osh, PMUREG(sih, regcontrol_addr), 0);
7041		val = R_REG(osh, PMUREG(sih, regcontrol_data)) & ~((uint32)0x07 << 29);
7042		val |= (uint32)(rcal_code & 0x07) << 29;
7043		W_REG(osh, PMUREG(sih, regcontrol_data), val);
7044		W_REG(osh, PMUREG(sih, regcontrol_addr), 1);
7045		val = R_REG(osh, PMUREG(sih, regcontrol_data)) & ~(uint32)0x01;
7046		val |= (uint32)((rcal_code >> 3) & 0x01);
7047		W_REG(osh, PMUREG(sih, regcontrol_data), val);
7048
7049		/* Write RCal code into pmu_chip_ctrl[33:30] */
7050		W_REG(osh, PMUREG(sih, chipcontrol_addr), 0);
7051		val = R_REG(osh, PMUREG(sih, chipcontrol_data)) & ~((uint32)0x03 << 30);
7052		val |= (uint32)(rcal_code & 0x03) << 30;
7053		W_REG(osh, PMUREG(sih, chipcontrol_data), val);
7054		W_REG(osh, PMUREG(sih, chipcontrol_addr), 1);
7055		val = R_REG(osh, PMUREG(sih, chipcontrol_data)) & ~(uint32)0x03;
7056		val |= (uint32)((rcal_code >> 2) & 0x03);
7057		W_REG(osh, PMUREG(sih, chipcontrol_data), val);
7058
7059		/* Set override in pmu_chip_ctrl[29] */
7060		W_REG(osh, PMUREG(sih, chipcontrol_addr), 0);
7061		OR_REG(osh, PMUREG(sih, chipcontrol_data), (0x01 << 29));
7062
7063		/* Power off RCal block */
7064		W_REG(osh, PMUREG(sih, chipcontrol_addr), 1);
7065		AND_REG(osh, PMUREG(sih, chipcontrol_data), ~0x04);
7066
7067		break;
7068	}
7069	case BCM4329_CHIP_ID: {
7070		uint8 rcal_code;
7071		uint32 val;
7072
7073		/* Kick RCal */
7074		W_REG(osh, PMUREG(sih, chipcontrol_addr), 1);
7075
7076		/* Power Down RCAL Block */
7077		AND_REG(osh, PMUREG(sih, chipcontrol_data), ~0x04);
7078
7079		/* Power Up RCAL block */
7080		OR_REG(osh, PMUREG(sih, chipcontrol_data), 0x04);
7081
7082		/* Wait for completion */
7083		SPINWAIT(!(R_REG(osh, &cc->chipstatus) & 0x08), 10 * 1000 * 1000);
7084		ASSERT(R_REG(osh, &cc->chipstatus) & 0x08);
7085
7086		/* Drop the LSB to convert from 5 bit code to 4 bit code */
7087		rcal_code =  (uint8)(R_REG(osh, &cc->chipstatus) >> 5) & 0x0f;
7088
7089		PMU_MSG(("RCal completed, status 0x%x, code 0x%x\n",
7090			R_REG(osh, &cc->chipstatus), rcal_code));
7091
7092		/* Write RCal code into pmu_vreg_ctrl[32:29] */
7093		W_REG(osh, PMUREG(sih, regcontrol_addr), 0);
7094		val = R_REG(osh, PMUREG(sih, regcontrol_data)) & ~((uint32)0x07 << 29);
7095		val |= (uint32)(rcal_code & 0x07) << 29;
7096		W_REG(osh, PMUREG(sih, regcontrol_data), val);
7097		W_REG(osh, PMUREG(sih, regcontrol_addr), 1);
7098		val = R_REG(osh, PMUREG(sih, regcontrol_data)) & ~(uint32)0x01;
7099		val |= (uint32)((rcal_code >> 3) & 0x01);
7100		W_REG(osh, PMUREG(sih, regcontrol_data), val);
7101
7102		/* Write RCal code into pmu_chip_ctrl[33:30] */
7103		W_REG(osh, PMUREG(sih, chipcontrol_addr), 0);
7104		val = R_REG(osh, PMUREG(sih, chipcontrol_data)) & ~((uint32)0x03 << 30);
7105		val |= (uint32)(rcal_code & 0x03) << 30;
7106		W_REG(osh, PMUREG(sih, chipcontrol_data), val);
7107		W_REG(osh, PMUREG(sih, chipcontrol_addr), 1);
7108		val = R_REG(osh, PMUREG(sih, chipcontrol_data)) & ~(uint32)0x03;
7109		val |= (uint32)((rcal_code >> 2) & 0x03);
7110		W_REG(osh, PMUREG(sih, chipcontrol_data), val);
7111
7112		/* Set override in pmu_chip_ctrl[29] */
7113		W_REG(osh, PMUREG(sih, chipcontrol_addr), 0);
7114		OR_REG(osh, PMUREG(sih, chipcontrol_data), (0x01 << 29));
7115
7116		/* Power off RCal block */
7117		W_REG(osh, PMUREG(sih, chipcontrol_addr), 1);
7118		AND_REG(osh, PMUREG(sih, chipcontrol_data), ~0x04);
7119
7120		break;
7121	}
7122	default:
7123		break;
7124	}
7125
7126	/* Return to original core */
7127	si_setcoreidx(sih, origidx);
7128} /* si_pmu_rcal */
7129
7130/** only called for HT, LCN and N phy's. */
7131void
7132si_pmu_spuravoid(si_t *sih, osl_t *osh, uint8 spuravoid)
7133{
7134	chipcregs_t *cc;
7135	uint origidx, intr_val;
7136	uint32 min_res_mask = 0, max_res_mask = 0, clk_ctl_st = 0;
7137	bool pll_off_on = FALSE;
7138
7139	ASSERT(CHIPID(sih->chip) != BCM43143_CHIP_ID); /* LCN40 PHY */
7140
7141#ifdef BCMUSBDEV_ENABLED
7142	if ((CHIPID(sih->chip) == BCM4324_CHIP_ID) && (CHIPREV(sih->chiprev) <= 2)) {
7143		return;
7144	}
7145	/* spuravoid is not ready for 43242 */
7146	if ((CHIPID(sih->chip) == BCM43242_CHIP_ID) || (CHIPID(sih->chip) == BCM43243_CHIP_ID)) {
7147		return;
7148	}
7149#endif
7150
7151	if ((CHIPID(sih->chip) == BCM4336_CHIP_ID) ||
7152		(CHIPID(sih->chip) == BCM43362_CHIP_ID) ||
7153		(CHIPID(sih->chip) == BCM43239_CHIP_ID) ||
7154		(CHIPID(sih->chip) == BCM4314_CHIP_ID) ||
7155		(CHIPID(sih->chip) == BCM43142_CHIP_ID) ||
7156		(CHIPID(sih->chip) == BCM4334_CHIP_ID) ||
7157		(CHIPID(sih->chip) == BCM43242_CHIP_ID) ||
7158		(CHIPID(sih->chip) == BCM43243_CHIP_ID) ||
7159		(CHIPID(sih->chip) == BCM43341_CHIP_ID) ||
7160		(CHIPID(sih->chip) == BCM4335_CHIP_ID) ||
7161		(CHIPID(sih->chip) == BCM4345_CHIP_ID) ||
7162		(CHIPID(sih->chip) == BCM4330_CHIP_ID))
7163	{
7164		pll_off_on = TRUE;
7165	}
7166
7167	/* Remember original core before switch to chipc */
7168	cc = (chipcregs_t *)si_switch_core(sih, CC_CORE_ID, &origidx, &intr_val);
7169	ASSERT(cc != NULL);
7170
7171	/* force the HT off  */
7172	if (pll_off_on)
7173		si_pmu_pll_off(sih, osh, cc, &min_res_mask, &max_res_mask, &clk_ctl_st);
7174
7175	/* update the pll changes */
7176	si_pmu_spuravoid_pllupdate(sih, cc, osh, spuravoid);
7177
7178	/* enable HT back on  */
7179	if (pll_off_on)
7180		si_pmu_pll_on(sih, osh, cc, min_res_mask, max_res_mask, clk_ctl_st);
7181
7182	/* Return to original core */
7183	si_restore_core(sih, origidx, intr_val);
7184} /* si_pmu_spuravoid */
7185
7186/* below function are only for BBPLL parallel purpose */
7187/** only called for HT, LCN and N phy's. */
7188void
7189si_pmu_spuravoid_isdone(si_t *sih, osl_t *osh, uint32 min_res_mask,
7190uint32 max_res_mask, uint32 clk_ctl_st, uint8 spuravoid)
7191{
7192
7193	chipcregs_t *cc;
7194	uint origidx, intr_val;
7195	bool pll_off_on = FALSE;
7196
7197	ASSERT(CHIPID(sih->chip) != BCM43143_CHIP_ID); /* LCN40 PHY */
7198
7199#ifdef BCMUSBDEV_ENABLED
7200	if ((CHIPID(sih->chip) == BCM4324_CHIP_ID) && (CHIPREV(sih->chiprev) <= 2)) {
7201		return;
7202	}
7203	/* spuravoid is not ready for 43242 */
7204	if ((CHIPID(sih->chip) == BCM43242_CHIP_ID) || (CHIPID(sih->chip) == BCM43243_CHIP_ID)) {
7205		return;
7206	}
7207#endif
7208
7209	if ((CHIPID(sih->chip) == BCM4336_CHIP_ID) ||
7210		(CHIPID(sih->chip) == BCM43362_CHIP_ID) ||
7211		(CHIPID(sih->chip) == BCM43239_CHIP_ID) ||
7212		(CHIPID(sih->chip) == BCM4314_CHIP_ID) ||
7213		(CHIPID(sih->chip) == BCM43142_CHIP_ID) ||
7214		(CHIPID(sih->chip) == BCM4334_CHIP_ID) ||
7215		(CHIPID(sih->chip) == BCM43242_CHIP_ID) ||
7216		(CHIPID(sih->chip) == BCM43243_CHIP_ID) ||
7217		(CHIPID(sih->chip) == BCM4335_CHIP_ID) ||
7218		(CHIPID(sih->chip) == BCM4345_CHIP_ID) ||
7219		(CHIPID(sih->chip) == BCM4330_CHIP_ID))
7220	{
7221		pll_off_on = TRUE;
7222	}
7223	/* Remember original core before switch to chipc */
7224	cc = (chipcregs_t *)si_switch_core(sih, CC_CORE_ID, &origidx, &intr_val);
7225	ASSERT(cc != NULL);
7226
7227	if (pll_off_on)
7228	  si_pmu_pll_off_isdone(sih, osh, cc);
7229	/* update the pll changes */
7230	si_pmu_spuravoid_pllupdate(sih, cc, osh, spuravoid);
7231
7232	/* enable HT back on  */
7233	if (pll_off_on)
7234		si_pmu_pll_on(sih, osh, cc, min_res_mask, max_res_mask, clk_ctl_st);
7235
7236	/* Return to original core */
7237	si_restore_core(sih, origidx, intr_val);
7238} /* si_pmu_spuravoid_isdone */
7239
7240/* below function are only for BBPLL parallel purpose */
7241
7242/* For having the pllcontrol data values for spuravoid */
7243typedef struct {
7244	uint8	spuravoid_mode;
7245	uint8	pllctrl_reg;
7246	uint32	pllctrl_regval;
7247} pllctrl_spuravoid_t;
7248
7249/* LCNXN */
7250/* PLL Settings for spur avoidance on/off mode */
7251static const pllctrl_spuravoid_t spuravoid_4324[] = {
7252	{1, PMU1_PLL0_PLLCTL0, 0xA7400040},
7253	{1, PMU1_PLL0_PLLCTL1, 0x10080706},
7254	{1, PMU1_PLL0_PLLCTL2, 0x0D311408},
7255	{1, PMU1_PLL0_PLLCTL3, 0x804F66AC},
7256	{1, PMU1_PLL0_PLLCTL4, 0x02600004},
7257	{1, PMU1_PLL0_PLLCTL5, 0x00019AB1},
7258
7259	{2, PMU1_PLL0_PLLCTL0, 0xA7400040},
7260	{2, PMU1_PLL0_PLLCTL1, 0x10080706},
7261	{2, PMU1_PLL0_PLLCTL2, 0x0D311408},
7262	{2, PMU1_PLL0_PLLCTL3, 0x80F3ADDC},
7263	{2, PMU1_PLL0_PLLCTL4, 0x02600004},
7264	{2, PMU1_PLL0_PLLCTL5, 0x00019AB1},
7265
7266	{0, PMU1_PLL0_PLLCTL0, 0xA7400040},
7267	{0, PMU1_PLL0_PLLCTL1, 0x10080706},
7268	{0, PMU1_PLL0_PLLCTL2, 0x0CB11408},
7269	{0, PMU1_PLL0_PLLCTL3, 0x80AB1F7C},
7270	{0, PMU1_PLL0_PLLCTL4, 0x02600004},
7271	{0, PMU1_PLL0_PLLCTL5, 0x00019AB1}
7272};
7273
7274static void
7275si_pmu_pllctrl_spurupdate(si_t *sih, osl_t *osh, chipcregs_t *cc, uint8 spuravoid,
7276	const pllctrl_spuravoid_t *pllctrl_spur, uint32 array_size)
7277{
7278	uint8 indx;
7279	for (indx = 0; indx < array_size; indx++) {
7280		if (pllctrl_spur[indx].spuravoid_mode == spuravoid) {
7281			W_REG(osh, PMUREG(sih, pllcontrol_addr), pllctrl_spur[indx].pllctrl_reg);
7282			W_REG(osh, PMUREG(sih, pllcontrol_data), pllctrl_spur[indx].pllctrl_regval);
7283		}
7284	}
7285}
7286
7287static void
7288si_pmu_spuravoid_pllupdate(si_t *sih, chipcregs_t *cc, osl_t *osh, uint8 spuravoid)
7289{
7290	uint32 tmp = 0;
7291	uint32 xtal_freq, reg_val, mxdiv, ndiv_int, ndiv_frac_int, part_mul;
7292	uint8 p1_div, p2_div, FCLkx;
7293	const pmu1_xtaltab0_t *params_tbl;
7294	uint32 *pllctrl_addr = PMUREG(sih, pllcontrol_addr);
7295	uint32 *pllctrl_data = PMUREG(sih, pllcontrol_data);
7296
7297	ASSERT(CHIPID(sih->chip) != BCM43143_CHIP_ID); /* LCN40 PHY */
7298
7299	switch (CHIPID(sih->chip)) {
7300	case BCM4324_CHIP_ID:
7301		/* If we get an invalid spurmode, then set the spur0 settings. */
7302		if (spuravoid > 2)
7303			spuravoid = 0;
7304
7305		si_pmu_pllctrl_spurupdate(sih, osh, cc, spuravoid, spuravoid_4324,
7306			ARRAYSIZE(spuravoid_4324));
7307
7308		tmp = PCTL_PLL_PLLCTL_UPD;
7309		break;
7310
7311	case BCM5357_CHIP_ID:   case BCM4749_CHIP_ID:
7312	case BCM43235_CHIP_ID:	case BCM43236_CHIP_ID:	case BCM43238_CHIP_ID:
7313	case BCM43237_CHIP_ID:
7314	case BCM43234_CHIP_ID:
7315	case BCM6362_CHIP_ID:
7316	case BCM53572_CHIP_ID:
7317
7318		if  ((CHIPID(sih->chip) == BCM6362_CHIP_ID) && (sih->chiprev == 0)) {
7319			/* 6362a0 (same clks as 4322[4-6]) */
7320			if (spuravoid == 1) {
7321				W_REG(osh, pllctrl_addr, PMU1_PLL0_PLLCTL0);
7322				W_REG(osh, pllctrl_data, 0x11500010);
7323				W_REG(osh, pllctrl_addr, PMU1_PLL0_PLLCTL1);
7324				W_REG(osh, pllctrl_data, 0x000C0C06);
7325				W_REG(osh, pllctrl_addr, PMU1_PLL0_PLLCTL2);
7326				W_REG(osh, pllctrl_data, 0x0F600a08);
7327				W_REG(osh, pllctrl_addr, PMU1_PLL0_PLLCTL3);
7328				W_REG(osh, pllctrl_data, 0x00000000);
7329				W_REG(osh, pllctrl_addr, PMU1_PLL0_PLLCTL4);
7330				W_REG(osh, pllctrl_data, 0x2001E920);
7331				W_REG(osh, pllctrl_addr, PMU1_PLL0_PLLCTL5);
7332				W_REG(osh, pllctrl_data, 0x88888815);
7333			} else {
7334				W_REG(osh, pllctrl_addr, PMU1_PLL0_PLLCTL0);
7335				W_REG(osh, pllctrl_data, 0x11100010);
7336				W_REG(osh, pllctrl_addr, PMU1_PLL0_PLLCTL1);
7337				W_REG(osh, pllctrl_data, 0x000c0c06);
7338				W_REG(osh, pllctrl_addr, PMU1_PLL0_PLLCTL2);
7339				W_REG(osh, pllctrl_data, 0x03000a08);
7340				W_REG(osh, pllctrl_addr, PMU1_PLL0_PLLCTL3);
7341				W_REG(osh, pllctrl_data, 0x00000000);
7342				W_REG(osh, pllctrl_addr, PMU1_PLL0_PLLCTL4);
7343				W_REG(osh, pllctrl_data, 0x200005c0);
7344				W_REG(osh, pllctrl_addr, PMU1_PLL0_PLLCTL5);
7345				W_REG(osh, pllctrl_data, 0x88888815);
7346			}
7347
7348		} else {
7349			/* BCM5357 needs to touch PLL1_PLLCTL[02], so offset PLL0_PLLCTL[02] by 6 */
7350			const uint8 phypll_offset = ((CHIPID(sih->chip) == BCM5357_CHIP_ID) ||
7351			                             (CHIPID(sih->chip) == BCM4749_CHIP_ID) ||
7352			                             (CHIPID(sih->chip) == BCM53572_CHIP_ID))
7353			                               ? 6 : 0;
7354			const uint8 bcm5357_bcm43236_p1div[] = {0x1, 0x5, 0x5};
7355			const uint8 bcm5357_bcm43236_ndiv[] = {0x30, 0xf6, 0xfc};
7356
7357			/* 5357[ab]0, 43236[ab]0, and 6362b0 */
7358			if (spuravoid > 2)
7359				spuravoid = 0;
7360
7361			/* RMW only the P1 divider */
7362			W_REG(osh, pllctrl_addr, PMU1_PLL0_PLLCTL0 + phypll_offset);
7363			tmp = R_REG(osh, pllctrl_data);
7364			tmp &= (~(PMU1_PLL0_PC0_P1DIV_MASK));
7365			tmp |= (bcm5357_bcm43236_p1div[spuravoid] << PMU1_PLL0_PC0_P1DIV_SHIFT);
7366			W_REG(osh, pllctrl_data, tmp);
7367
7368			/* RMW only the int feedback divider */
7369			W_REG(osh, pllctrl_addr, PMU1_PLL0_PLLCTL2 + phypll_offset);
7370			tmp = R_REG(osh, pllctrl_data);
7371			tmp &= ~(PMU1_PLL0_PC2_NDIV_INT_MASK);
7372			tmp |= (bcm5357_bcm43236_ndiv[spuravoid]) << PMU1_PLL0_PC2_NDIV_INT_SHIFT;
7373			W_REG(osh, pllctrl_data, tmp);
7374		}
7375
7376		tmp = 1 << 10;
7377		break;
7378
7379	case BCM4331_CHIP_ID:
7380	case BCM43431_CHIP_ID:
7381		if (ISSIM_ENAB(sih)) {
7382			if (spuravoid == 2) {
7383				W_REG(osh, pllctrl_addr, PMU1_PLL0_PLLCTL3);
7384				W_REG(osh, pllctrl_data, 0x00000002);
7385			} else if (spuravoid == 1) {
7386				W_REG(osh, pllctrl_addr, PMU1_PLL0_PLLCTL3);
7387				W_REG(osh, pllctrl_data, 0x00000001);
7388			} else {
7389				W_REG(osh, pllctrl_addr, PMU1_PLL0_PLLCTL3);
7390				W_REG(osh, pllctrl_data, 0x00000000);
7391			}
7392		} else {
7393			if (spuravoid == 2) {
7394				W_REG(osh, pllctrl_addr, PMU1_PLL0_PLLCTL0);
7395				W_REG(osh, pllctrl_data, 0x11500014);
7396				W_REG(osh, pllctrl_addr, PMU1_PLL0_PLLCTL2);
7397				W_REG(osh, pllctrl_data, 0x0FC00a08);
7398			} else if (spuravoid == 1) {
7399				W_REG(osh, pllctrl_addr, PMU1_PLL0_PLLCTL0);
7400				W_REG(osh, pllctrl_data, 0x11500014);
7401				W_REG(osh, pllctrl_addr, PMU1_PLL0_PLLCTL2);
7402				W_REG(osh, pllctrl_data, 0x0F600a08);
7403			} else {
7404				W_REG(osh, pllctrl_addr, PMU1_PLL0_PLLCTL0);
7405				W_REG(osh, pllctrl_data, 0x11100014);
7406				W_REG(osh, pllctrl_addr, PMU1_PLL0_PLLCTL2);
7407				W_REG(osh, pllctrl_data, 0x03000a08);
7408			}
7409		}
7410		tmp = 1 << 10;
7411		break;
7412
7413	case BCM43224_CHIP_ID:	case BCM43225_CHIP_ID:	case BCM43421_CHIP_ID:
7414	case BCM43226_CHIP_ID:
7415		if (spuravoid == 1) {
7416			W_REG(osh, pllctrl_addr, PMU1_PLL0_PLLCTL0);
7417			W_REG(osh, pllctrl_data, 0x11500010);
7418			W_REG(osh, pllctrl_addr, PMU1_PLL0_PLLCTL1);
7419			W_REG(osh, pllctrl_data, 0x000C0C06);
7420			W_REG(osh, pllctrl_addr, PMU1_PLL0_PLLCTL2);
7421			W_REG(osh, pllctrl_data, 0x0F600a08);
7422			W_REG(osh, pllctrl_addr, PMU1_PLL0_PLLCTL3);
7423			W_REG(osh, pllctrl_data, 0x00000000);
7424			W_REG(osh, pllctrl_addr, PMU1_PLL0_PLLCTL4);
7425			W_REG(osh, pllctrl_data, 0x2001E920);
7426			W_REG(osh, pllctrl_addr, PMU1_PLL0_PLLCTL5);
7427			W_REG(osh, pllctrl_data, 0x88888815);
7428		} else {
7429			W_REG(osh, pllctrl_addr, PMU1_PLL0_PLLCTL0);
7430			W_REG(osh, pllctrl_data, 0x11100010);
7431			W_REG(osh, pllctrl_addr, PMU1_PLL0_PLLCTL1);
7432			W_REG(osh, pllctrl_data, 0x000c0c06);
7433			W_REG(osh, pllctrl_addr, PMU1_PLL0_PLLCTL2);
7434			W_REG(osh, pllctrl_data, 0x03000a08);
7435			W_REG(osh, pllctrl_addr, PMU1_PLL0_PLLCTL3);
7436			W_REG(osh, pllctrl_data, 0x00000000);
7437			W_REG(osh, pllctrl_addr, PMU1_PLL0_PLLCTL4);
7438			W_REG(osh, pllctrl_data, 0x200005c0);
7439			W_REG(osh, pllctrl_addr, PMU1_PLL0_PLLCTL5);
7440			W_REG(osh, pllctrl_data, 0x88888815);
7441		}
7442		tmp = 1 << 10;
7443		break;
7444
7445	case BCM43222_CHIP_ID:	case BCM43111_CHIP_ID:	case BCM43112_CHIP_ID:
7446	case BCM43420_CHIP_ID:
7447		if (spuravoid == 1) {
7448			W_REG(osh, pllctrl_addr, PMU1_PLL0_PLLCTL0);
7449			W_REG(osh, pllctrl_data, 0x11500008);
7450			W_REG(osh, pllctrl_addr, PMU1_PLL0_PLLCTL1);
7451			W_REG(osh, pllctrl_data, 0x0C000C06);
7452			W_REG(osh, pllctrl_addr, PMU1_PLL0_PLLCTL2);
7453			W_REG(osh, pllctrl_data, 0x0F600a08);
7454			W_REG(osh, pllctrl_addr, PMU1_PLL0_PLLCTL3);
7455			W_REG(osh, pllctrl_data, 0x00000000);
7456			W_REG(osh, pllctrl_addr, PMU1_PLL0_PLLCTL4);
7457			W_REG(osh, pllctrl_data, 0x2001E920);
7458			W_REG(osh, pllctrl_addr, PMU1_PLL0_PLLCTL5);
7459			W_REG(osh, pllctrl_data, 0x88888815);
7460		} else {
7461			W_REG(osh, pllctrl_addr, PMU1_PLL0_PLLCTL0);
7462			W_REG(osh, pllctrl_data, 0x11100008);
7463			W_REG(osh, pllctrl_addr, PMU1_PLL0_PLLCTL1);
7464			W_REG(osh, pllctrl_data, 0x0c000c06);
7465			W_REG(osh, pllctrl_addr, PMU1_PLL0_PLLCTL2);
7466			W_REG(osh, pllctrl_data, 0x03000a08);
7467			W_REG(osh, pllctrl_addr, PMU1_PLL0_PLLCTL3);
7468			W_REG(osh, pllctrl_data, 0x00000000);
7469			W_REG(osh, pllctrl_addr, PMU1_PLL0_PLLCTL4);
7470			W_REG(osh, pllctrl_data, 0x200005c0);
7471			W_REG(osh, pllctrl_addr, PMU1_PLL0_PLLCTL5);
7472			W_REG(osh, pllctrl_data, 0x88888855);
7473		}
7474
7475		tmp = 1 << 10;
7476		break;
7477
7478	case BCM4716_CHIP_ID:
7479	case BCM4748_CHIP_ID:
7480	case BCM47162_CHIP_ID:
7481		if (spuravoid == 1) {
7482			W_REG(osh, pllctrl_addr, PMU1_PLL0_PLLCTL0);
7483			W_REG(osh, pllctrl_data, 0x11500060);
7484			W_REG(osh, pllctrl_addr, PMU1_PLL0_PLLCTL1);
7485			W_REG(osh, pllctrl_data, 0x080C0C06);
7486			W_REG(osh, pllctrl_addr, PMU1_PLL0_PLLCTL2);
7487			W_REG(osh, pllctrl_data, 0x0F600000);
7488			W_REG(osh, pllctrl_addr, PMU1_PLL0_PLLCTL3);
7489			W_REG(osh, pllctrl_data, 0x00000000);
7490			W_REG(osh, pllctrl_addr, PMU1_PLL0_PLLCTL4);
7491			W_REG(osh, pllctrl_data, 0x2001E924);
7492			W_REG(osh, pllctrl_addr, PMU1_PLL0_PLLCTL5);
7493			W_REG(osh, pllctrl_data, 0x88888815);
7494		} else {
7495			W_REG(osh, pllctrl_addr, PMU1_PLL0_PLLCTL0);
7496			W_REG(osh, pllctrl_data, 0x11100060);
7497			W_REG(osh, pllctrl_addr, PMU1_PLL0_PLLCTL1);
7498			W_REG(osh, pllctrl_data, 0x080c0c06);
7499			W_REG(osh, pllctrl_addr, PMU1_PLL0_PLLCTL2);
7500			W_REG(osh, pllctrl_data, 0x03000000);
7501			W_REG(osh, pllctrl_addr, PMU1_PLL0_PLLCTL3);
7502			W_REG(osh, pllctrl_data, 0x00000000);
7503			W_REG(osh, pllctrl_addr, PMU1_PLL0_PLLCTL4);
7504			W_REG(osh, pllctrl_data, 0x200005c0);
7505			W_REG(osh, pllctrl_addr, PMU1_PLL0_PLLCTL5);
7506			W_REG(osh, pllctrl_data, 0x88888815);
7507		}
7508
7509		tmp = 3 << 9;
7510		break;
7511
7512	case BCM4322_CHIP_ID:
7513	case BCM43221_CHIP_ID:
7514	case BCM43231_CHIP_ID:
7515	case BCM4342_CHIP_ID:
7516		W_REG(osh, pllctrl_addr, PMU1_PLL0_PLLCTL0);
7517		W_REG(osh, pllctrl_data, 0x11100070);
7518		W_REG(osh, pllctrl_addr, PMU1_PLL0_PLLCTL1);
7519		W_REG(osh, pllctrl_data, 0x1014140a);
7520		W_REG(osh, pllctrl_addr, PMU1_PLL0_PLLCTL5);
7521		W_REG(osh, pllctrl_data, 0x88888854);
7522
7523		if (spuravoid == 1) { /* spur_avoid ON, enable 41/82/164Mhz clock mode */
7524			W_REG(osh, pllctrl_addr, PMU1_PLL0_PLLCTL2);
7525			W_REG(osh, pllctrl_data, 0x05201828);
7526		} else { /* enable 40/80/160Mhz clock mode */
7527			W_REG(osh, pllctrl_addr, PMU1_PLL0_PLLCTL2);
7528			W_REG(osh, pllctrl_data, 0x05001828);
7529		}
7530
7531		tmp = 1 << 10;
7532		break;
7533	case BCM4319_CHIP_ID:
7534		W_REG(osh, pllctrl_addr, PMU1_PLL0_PLLCTL0);
7535		W_REG(osh, pllctrl_data, 0x11100070);
7536		W_REG(osh, pllctrl_addr, PMU1_PLL0_PLLCTL1);
7537		W_REG(osh, pllctrl_data, 0x1014140a);
7538		W_REG(osh, pllctrl_addr, PMU1_PLL0_PLLCTL5);
7539		W_REG(osh, pllctrl_data, 0x88888854);
7540
7541		if (spuravoid == 1) { /* spur_avoid ON, enable 41/82/164Mhz clock mode */
7542			W_REG(osh, pllctrl_addr, PMU1_PLL0_PLLCTL2);
7543			W_REG(osh, pllctrl_data, 0x05201828);
7544		} else { /* enable 40/80/160Mhz clock mode */
7545			W_REG(osh, pllctrl_addr, PMU1_PLL0_PLLCTL2);
7546			W_REG(osh, pllctrl_data, 0x05001828);
7547		}
7548		break;
7549	case BCM4336_CHIP_ID:
7550	case BCM43362_CHIP_ID:
7551	case BCM4330_CHIP_ID:
7552		xtal_freq = si_alp_clock(sih)/1000;
7553		/* Find the frequency in the table */
7554		for (params_tbl = si_pmu1_xtaltab0(sih);
7555			params_tbl != NULL && params_tbl->xf != 0; params_tbl++)
7556			if ((params_tbl->fref) == xtal_freq)
7557				break;
7558		/* Could not find it so assign a default value */
7559		if (params_tbl == NULL || params_tbl->xf == 0)
7560			params_tbl = si_pmu1_xtaldef0(sih);
7561		ASSERT(params_tbl != NULL && params_tbl->xf != 0);
7562
7563		/* FClkx = (P2/P1) * ((NDIV_INT + NDIV_FRAC/2^24)/MXDIV) * Fref
7564		    Fref  = XtalFreq
7565		    FCLkx = 82MHz for spur avoidance mode
7566				   80MHz for non-spur avoidance mode.
7567		*/
7568		xtal_freq = (uint32) params_tbl->fref/100;
7569		p1_div = params_tbl->p1div;
7570		p2_div = params_tbl->p2div;
7571		W_REG(osh, pllctrl_addr, PMU1_PLL0_PLLCTL1);
7572		reg_val =  R_REG(osh, pllctrl_data);
7573		mxdiv = (reg_val >> PMU1_PLL0_PC2_M6DIV_SHIFT) & PMU1_PLL0_PC2_M5DIV_MASK;
7574
7575		if (spuravoid == 1)
7576			FCLkx = 82;
7577		else
7578			FCLkx = 80;
7579
7580		part_mul = (p1_div / p2_div) * mxdiv;
7581		ndiv_int = (FCLkx * part_mul * 10)/ (xtal_freq);
7582		ndiv_frac_int = ((FCLkx * part_mul * 10) % (xtal_freq));
7583		ndiv_frac_int = ((ndiv_frac_int * 16777216) + (xtal_freq/2)) / (xtal_freq);
7584
7585		W_REG(osh, pllctrl_addr, PMU1_PLL0_PLLCTL2);
7586		reg_val =  R_REG(osh, pllctrl_data);
7587		W_REG(osh, pllctrl_data, ((reg_val & ~PMU1_PLL0_PC2_NDIV_INT_MASK)
7588					| (ndiv_int << PMU1_PLL0_PC2_NDIV_INT_SHIFT)));
7589		W_REG(osh, pllctrl_addr, PMU1_PLL0_PLLCTL3);
7590		W_REG(osh, pllctrl_data, ndiv_frac_int);
7591
7592		tmp = PCTL_PLL_PLLCTL_UPD;
7593		break;
7594
7595	case BCM43131_CHIP_ID:
7596	case BCM43217_CHIP_ID:
7597	case BCM43227_CHIP_ID:
7598	case BCM43228_CHIP_ID:
7599	case BCM43428_CHIP_ID:
7600		/* LCNXN */
7601		/* PLL Settings for spur avoidance on/off mode, no on2 support for 43228A0 */
7602		if (spuravoid == 1) {
7603			W_REG(osh, pllctrl_addr, PMU1_PLL0_PLLCTL0);
7604			W_REG(osh, pllctrl_data, 0x01100014);
7605			W_REG(osh, pllctrl_addr, PMU1_PLL0_PLLCTL1);
7606			W_REG(osh, pllctrl_data, 0x040C0C06);
7607			W_REG(osh, pllctrl_addr, PMU1_PLL0_PLLCTL2);
7608			W_REG(osh, pllctrl_data, 0x03140A08);
7609			W_REG(osh, pllctrl_addr, PMU1_PLL0_PLLCTL3);
7610			W_REG(osh, pllctrl_data, 0x00333333);
7611			W_REG(osh, pllctrl_addr, PMU1_PLL0_PLLCTL4);
7612			W_REG(osh, pllctrl_data, 0x202C2820);
7613			W_REG(osh, pllctrl_addr, PMU1_PLL0_PLLCTL5);
7614			W_REG(osh, pllctrl_data, 0x88888815);
7615		} else {
7616			W_REG(osh, pllctrl_addr, PMU1_PLL0_PLLCTL0);
7617			W_REG(osh, pllctrl_data, 0x11100014);
7618			W_REG(osh, pllctrl_addr, PMU1_PLL0_PLLCTL1);
7619			W_REG(osh, pllctrl_data, 0x040c0c06);
7620			W_REG(osh, pllctrl_addr, PMU1_PLL0_PLLCTL2);
7621			W_REG(osh, pllctrl_data, 0x03000a08);
7622			W_REG(osh, pllctrl_addr, PMU1_PLL0_PLLCTL3);
7623			W_REG(osh, pllctrl_data, 0x00000000);
7624			W_REG(osh, pllctrl_addr, PMU1_PLL0_PLLCTL4);
7625			W_REG(osh, pllctrl_data, 0x200005c0);
7626			W_REG(osh, pllctrl_addr, PMU1_PLL0_PLLCTL5);
7627			W_REG(osh, pllctrl_data, 0x88888815);
7628		}
7629		tmp = 1 << 10;
7630		break;
7631	case BCM4314_CHIP_ID:
7632	case BCM43142_CHIP_ID:
7633	case BCM43341_CHIP_ID:
7634	case BCM4334_CHIP_ID:
7635		{
7636			const pmu2_xtaltab0_t *xt;
7637			uint32 pll0;
7638
7639			xtal_freq = si_pmu_alp_clock(sih, osh)/1000;
7640			xt = (spuravoid == 1) ? pmu2_xtaltab0_adfll_492 : pmu2_xtaltab0_adfll_485;
7641
7642			for (; xt != NULL && xt->fref != 0; xt++) {
7643				if (xt->fref == xtal_freq) {
7644					W_REG(osh, pllctrl_addr, PMU15_PLL_PLLCTL0);
7645					pll0 = R_REG(osh, pllctrl_data);
7646					pll0 &= ~PMU15_PLL_PC0_FREQTGT_MASK;
7647					pll0 |= (xt->freq_tgt << PMU15_PLL_PC0_FREQTGT_SHIFT);
7648					W_REG(osh, pllctrl_data, pll0);
7649
7650					tmp = PCTL_PLL_PLLCTL_UPD;
7651					break;
7652				}
7653			}
7654		}
7655		break;
7656	case BCM4335_CHIP_ID:
7657		/* 4335 PLL ctrl Registers */
7658		/* PLL Settings for spur avoidance on/off mode,  support for 4335A0 */
7659		/* # spur_mode 0 VCO=963MHz
7660		# spur_mode 1 VCO=960MHz
7661		# spur_mode 2 VCO=961MHz
7662		# spur_mode 3 VCO=964MHz
7663		# spur_mode 4 VCO=962MHz
7664		# spur_mode 5 VCO=965MHz
7665		# spur_mode 6 VCO=966MHz
7666		# spur_mode 7 VCO=967MHz
7667		# spur_mode 8 VCO=968MHz
7668		# spur_mode 9 VCO=969MHz
7669		*/
7670		W_REG(osh, pllctrl_addr, PMU1_PLL0_PLLCTL3);
7671		switch (spuravoid) {
7672		case 0:
7673			W_REG(osh, pllctrl_data, 0x80BFA863);
7674			break;
7675		case 1:
7676			W_REG(osh, pllctrl_data, 0x80AB1F7D);
7677			break;
7678		case 2:
7679			W_REG(osh, pllctrl_data, 0x80b1f7c9);
7680			break;
7681		case 3:
7682			W_REG(osh, pllctrl_data, 0x80c680af);
7683			break;
7684		case 4:
7685			W_REG(osh, pllctrl_data, 0x80B8D016);
7686			break;
7687		case 5:
7688			W_REG(osh, pllctrl_data, 0x80CD58FC);
7689			break;
7690		case 6:
7691			W_REG(osh, pllctrl_data, 0x80D43149);
7692			break;
7693		case 7:
7694			W_REG(osh, pllctrl_data, 0x80DB0995);
7695			break;
7696		case 8:
7697			W_REG(osh, pllctrl_data, 0x80E1E1E2);
7698			break;
7699		case 9:
7700			W_REG(osh, pllctrl_data, 0x80E8BA2F);
7701			break;
7702		default:
7703			break;
7704		}
7705		tmp = PCTL_PLL_PLLCTL_UPD;
7706		break;
7707	case BCM4345_CHIP_ID:
7708		/* 4345 PLL ctrl Registers */
7709		xtal_freq = si_pmu_alp_clock(sih, osh) / 1000;
7710
7711		/* TODO - set PLLCTL registers (via set_PLL_control_regs), based on spuravoid */
7712
7713		break;
7714	default:
7715		PMU_ERROR(("%s: unknown spuravoidance settings for chip %s, not changing PLL\n",
7716		           __FUNCTION__, bcm_chipname(sih->chip, chn, 8)));
7717		break;
7718	}
7719
7720	tmp |= R_REG(osh, PMUREG(sih, pmucontrol));
7721	W_REG(osh, PMUREG(sih, pmucontrol), tmp);
7722} /* si_pmu_spuravoid_pllupdate */
7723
7724extern uint32
7725si_pmu_cal_fvco(si_t *sih, osl_t *osh)
7726{
7727	uint32 xf, ndiv_int, ndiv_frac, fvco, pll_reg, p1_div_scale;
7728	uint32 r_high, r_low, int_part, frac_part, rounding_const;
7729	uint8 p1_div;
7730	chipcregs_t *cc;
7731	uint origidx, intr_val;
7732
7733	/* Remember original core before switch to chipc */
7734	cc = (chipcregs_t *)si_switch_core(sih, CC_CORE_ID, &origidx, &intr_val);
7735	ASSERT(cc != NULL);
7736	BCM_REFERENCE(cc);
7737
7738	xf = si_pmu_alp_clock(sih, osh)/1000;
7739
7740	pll_reg = si_pmu_pllcontrol(sih, PMU1_PLL0_PLLCTL2, 0, 0);
7741
7742	p1_div = (pll_reg & PMU4335_PLL0_PC2_P1DIV_MASK) >>
7743			PMU4335_PLL0_PC2_P1DIV_SHIFT;
7744
7745	ndiv_int = (pll_reg & PMU4335_PLL0_PC2_NDIV_INT_MASK) >>
7746			PMU4335_PLL0_PC2_NDIV_INT_SHIFT;
7747
7748	pll_reg = si_pmu_pllcontrol(sih, PMU1_PLL0_PLLCTL3, 0, 0);
7749
7750	ndiv_frac = (pll_reg & PMU1_PLL0_PC3_NDIV_FRAC_MASK) >>
7751			PMU1_PLL0_PC3_NDIV_FRAC_SHIFT;
7752
7753	/* Actual expression is as below */
7754	/* fvco1 = (100 * (xf * 1/p1_div) * (ndiv_int + (ndiv_frac * 1/(1 << 24)))) */
7755	/* * 1/(1000 * 100); */
7756
7757	/* Representing 1/p1_div as a 12 bit number */
7758	/* Reason for the choice of 12: */
7759	/* ndiv_int is represented by 9 bits */
7760	/* so (ndiv_int << 24) needs 33 bits */
7761	/* xf needs 16 bits for the worst case of 52MHz clock */
7762	/* So (xf * (ndiv << 24)) needs atleast 49 bits */
7763	/* So remaining bits for uint64 : 64 - 49 = 15 bits */
7764	/* So, choosing 12 bits, with 3 bits of headroom */
7765	int_part = xf * ndiv_int;
7766
7767	rounding_const = 1 << (BBPLL_NDIV_FRAC_BITS - 1);
7768	bcm_uint64_multiple_add(&r_high, &r_low, ndiv_frac, xf, rounding_const);
7769	bcm_uint64_right_shift(&frac_part, r_high, r_low, BBPLL_NDIV_FRAC_BITS);
7770
7771	p1_div_scale = (1 << P1_DIV_SCALE_BITS) / p1_div;
7772	rounding_const = 1 << (P1_DIV_SCALE_BITS - 1);
7773
7774	bcm_uint64_multiple_add(&r_high, &r_low, (int_part + frac_part),
7775		p1_div_scale, rounding_const);
7776	bcm_uint64_right_shift(&fvco, r_high, r_low, P1_DIV_SCALE_BITS);
7777
7778	/* Return to original core */
7779	si_restore_core(sih, origidx, intr_val);
7780	return fvco;
7781} /* si_pmu_cal_fvco */
7782
7783/** Only called by N (MIMO) PHY */
7784void
7785si_pmu_gband_spurwar(si_t *sih, osl_t *osh)
7786{
7787	chipcregs_t *cc;
7788	uint origidx, intr_val;
7789	uint32 cc_clk_ctl_st;
7790	uint32 minmask, maxmask;
7791
7792	if ((CHIPID(sih->chip) == BCM43222_CHIP_ID) ||
7793		(CHIPID(sih->chip) == BCM43420_CHIP_ID)) {
7794		/* Remember original core before switch to chipc */
7795		cc = (chipcregs_t *)si_switch_core(sih, CC_CORE_ID, &origidx, &intr_val);
7796		ASSERT(cc != NULL);
7797
7798		/* Remove force HT and HT Avail Request from chipc core */
7799		cc_clk_ctl_st = R_REG(osh, &cc->clk_ctl_st);
7800		AND_REG(osh, &cc->clk_ctl_st, ~(CCS_FORCEHT | CCS_HTAREQ));
7801
7802		minmask = R_REG(osh, PMUREG(sih, min_res_mask));
7803		maxmask = R_REG(osh, PMUREG(sih, max_res_mask));
7804
7805		/* Make sure the PLL is off: clear bit 4 & 5 of min/max_res_mask */
7806		/* Have to remove HT Avail request before powering off PLL */
7807		AND_REG(osh, PMUREG(sih, min_res_mask),	~(PMURES_BIT(RES4322_HT_SI_AVAIL)));
7808		AND_REG(osh, PMUREG(sih, max_res_mask),	~(PMURES_BIT(RES4322_HT_SI_AVAIL)));
7809		SPINWAIT(R_REG(osh, &cc->clk_ctl_st) & CCS_HTAVAIL, PMU_MAX_TRANSITION_DLY);
7810		AND_REG(osh, PMUREG(sih, min_res_mask),	~(PMURES_BIT(RES4322_SI_PLL_ON)));
7811		AND_REG(osh, PMUREG(sih, max_res_mask),	~(PMURES_BIT(RES4322_SI_PLL_ON)));
7812		OSL_DELAY(150);
7813		ASSERT(!(R_REG(osh, &cc->clk_ctl_st) & CCS_HTAVAIL));
7814
7815		/* Change backplane clock speed from 96 MHz to 80 MHz */
7816		W_REG(osh, PMUREG(sih, pllcontrol_addr), PMU2_PLL_PLLCTL2);
7817		W_REG(osh, PMUREG(sih, pllcontrol_data), (R_REG(osh, PMUREG(sih, pllcontrol_data)) &
7818		                                  ~(PMU2_PLL_PC2_M6DIV_MASK)) |
7819		      (0xc << PMU2_PLL_PC2_M6DIV_SHIFT));
7820
7821		/* Reduce the driver strengths of the phyclk160, adcclk80, and phyck80
7822		 * clocks from 0x8 to 0x1
7823		 */
7824		W_REG(osh, PMUREG(sih, pllcontrol_addr), PMU2_PLL_PLLCTL5);
7825		W_REG(osh, PMUREG(sih, pllcontrol_data), (R_REG(osh, PMUREG(sih, pllcontrol_data)) &
7826		                                  ~(PMU2_PLL_PC5_CLKDRIVE_CH1_MASK |
7827		                                    PMU2_PLL_PC5_CLKDRIVE_CH2_MASK |
7828		                                    PMU2_PLL_PC5_CLKDRIVE_CH3_MASK |
7829		                                    PMU2_PLL_PC5_CLKDRIVE_CH4_MASK)) |
7830		      ((1 << PMU2_PLL_PC5_CLKDRIVE_CH1_SHIFT) |
7831		       (1 << PMU2_PLL_PC5_CLKDRIVE_CH2_SHIFT) |
7832		       (1 << PMU2_PLL_PC5_CLKDRIVE_CH3_SHIFT) |
7833		       (1 << PMU2_PLL_PC5_CLKDRIVE_CH4_SHIFT)));
7834
7835		W_REG(osh, PMUREG(sih, pmucontrol), R_REG(osh, PMUREG(sih, pmucontrol)) |
7836			PCTL_PLL_PLLCTL_UPD);
7837
7838		/* Restore min_res_mask and max_res_mask */
7839		OSL_DELAY(100);
7840		W_REG(osh, PMUREG(sih, max_res_mask), maxmask);
7841		OSL_DELAY(100);
7842		W_REG(osh, PMUREG(sih, min_res_mask), minmask);
7843		OSL_DELAY(100);
7844		/* Make sure the PLL is on. Spinwait until the HTAvail is True */
7845		SPINWAIT(!(R_REG(osh, &cc->clk_ctl_st) & CCS_HTAVAIL), PMU_MAX_TRANSITION_DLY);
7846		ASSERT((R_REG(osh, &cc->clk_ctl_st) & CCS_HTAVAIL));
7847
7848		/* Restore force HT and HT Avail Request on the chipc core */
7849		W_REG(osh, &cc->clk_ctl_st, cc_clk_ctl_st);
7850
7851		/* Return to original core */
7852		si_restore_core(sih, origidx, intr_val);
7853	}
7854} /* si_pmu_gband_spurwar */
7855
7856bool
7857si_pmu_is_otp_powered(si_t *sih, osl_t *osh)
7858{
7859	uint idx;
7860	chipcregs_t *cc;
7861	bool st;
7862	rsc_per_chip_t *rsc;		/* chip specific resource bit positions */
7863
7864	/* Remember original core before switch to chipc */
7865	idx = si_coreidx(sih);
7866	cc = si_setcoreidx(sih, SI_CC_IDX);
7867	ASSERT(cc != NULL);
7868
7869	si_pmu_wait_for_steady_state(sih, osh, cc);
7870
7871	switch (CHIPID(sih->chip)) {
7872	case BCM4322_CHIP_ID:
7873	case BCM43221_CHIP_ID:
7874	case BCM43231_CHIP_ID:
7875	case BCM4342_CHIP_ID:
7876	case BCM4325_CHIP_ID:
7877	case BCM4329_CHIP_ID:
7878	case BCM4315_CHIP_ID:
7879	case BCM4319_CHIP_ID:
7880	case BCM4336_CHIP_ID:
7881	case BCM43362_CHIP_ID:
7882	case BCM43239_CHIP_ID:
7883	case BCM4330_CHIP_ID:
7884	case BCM4314_CHIP_ID:
7885	case BCM43142_CHIP_ID:
7886	case BCM43143_CHIP_ID:
7887	case BCM43341_CHIP_ID:
7888	case BCM4334_CHIP_ID:
7889	case BCM4324_CHIP_ID:
7890	case BCM43242_CHIP_ID:
7891	case BCM43243_CHIP_ID:
7892	case BCM4335_CHIP_ID:
7893	case BCM4345_CHIP_ID:	/* same OTP PU as 4350 */
7894	case BCM4350_CHIP_ID:
7895	case BCM4354_CHIP_ID:
7896	case BCM4356_CHIP_ID:
7897	case BCM43556_CHIP_ID:
7898	case BCM43558_CHIP_ID:
7899	case BCM43566_CHIP_ID:
7900	case BCM43568_CHIP_ID:
7901	case BCM43569_CHIP_ID:
7902	case BCM43570_CHIP_ID:
7903	case BCM4360_CHIP_ID:
7904	case BCM43460_CHIP_ID:
7905	case BCM43526_CHIP_ID:
7906	case BCM4352_CHIP_ID:
7907		rsc = si_pmu_get_rsc_positions(sih);
7908		st = (R_REG(osh, PMUREG(sih, res_state)) & PMURES_BIT(rsc->otp_pu)) != 0;
7909		break;
7910
7911	/* These chip doesn't use PMU bit to power up/down OTP. OTP always on.
7912	 * Use OTP_INIT command to reset/refresh state.
7913	 */
7914	case BCM43222_CHIP_ID:	case BCM43111_CHIP_ID:	case BCM43112_CHIP_ID:
7915	case BCM43224_CHIP_ID:	case BCM43225_CHIP_ID:	case BCM43421_CHIP_ID:
7916	case BCM43236_CHIP_ID:	case BCM43235_CHIP_ID:	case BCM43238_CHIP_ID:
7917	case BCM43237_CHIP_ID:  case BCM43420_CHIP_ID:
7918	case BCM43234_CHIP_ID:
7919	case BCM4331_CHIP_ID:   case BCM43431_CHIP_ID:
7920	case BCM43602_CHIP_ID:
7921	case BCM43462_CHIP_ID:
7922		st = TRUE;
7923		break;
7924	default:
7925		st = TRUE;
7926		break;
7927	}
7928
7929	/* Return to original core */
7930	si_setcoreidx(sih, idx);
7931	return st;
7932} /* si_pmu_is_otp_powered */
7933
7934void
7935#if defined(WLTEST)
7936si_pmu_sprom_enable(si_t *sih, osl_t *osh, bool enable)
7937#else
7938BCMATTACHFN(si_pmu_sprom_enable)(si_t *sih, osl_t *osh, bool enable)
7939#endif
7940{
7941	switch (CHIPID(sih->chip)) {
7942	case BCM4315_CHIP_ID:
7943		if (CHIPREV(sih->chiprev) < 1)
7944			break;
7945		if (sih->chipst & CST4315_SPROM_SEL) {
7946			uint32 val;
7947			W_REG(osh, PMUREG(sih, chipcontrol_addr), 0);
7948			val = R_REG(osh, PMUREG(sih, chipcontrol_data));
7949			if (enable)
7950				val &= ~0x80000000;
7951			else
7952				val |= 0x80000000;
7953			W_REG(osh, PMUREG(sih, chipcontrol_data), val);
7954		}
7955		break;
7956	default:
7957		break;
7958	}
7959}
7960
7961bool
7962#if defined(WLTEST)
7963si_pmu_is_sprom_enabled(si_t *sih, osl_t *osh)
7964#else
7965BCMATTACHFN(si_pmu_is_sprom_enabled)(si_t *sih, osl_t *osh)
7966#endif
7967{
7968	bool enable = TRUE;
7969
7970	switch (CHIPID(sih->chip)) {
7971	case BCM4315_CHIP_ID:
7972		if (CHIPREV(sih->chiprev) < 1)
7973			break;
7974		if (!(sih->chipst & CST4315_SPROM_SEL))
7975			break;
7976		W_REG(osh, PMUREG(sih, chipcontrol_addr), 0);
7977		if (R_REG(osh, PMUREG(sih, chipcontrol_data)) & 0x80000000)
7978			enable = FALSE;
7979		break;
7980	default:
7981		break;
7982	}
7983	return enable;
7984}
7985
7986/**
7987 * Some chip/boards can be optionally fitted with an external 32Khz clock source for increased power
7988 * savings (due to more accurate sleep intervals).
7989 */
7990static void
7991BCMATTACHFN(si_pmu_set_lpoclk)(si_t *sih, osl_t *osh)
7992{
7993	uint32 ext_lpo_sel, int_lpo_sel, timeout = 0,
7994		ext_lpo_avail = 0, lpo_sel = 0;
7995	uint32 ext_lpo_isclock; /* On e.g. 43602a0, either x-tal or clock can be on LPO pins */
7996
7997	if (!(getintvar(NULL, "boardflags3")))
7998		return;
7999
8000	ext_lpo_sel = getintvar(NULL, "boardflags3") & BFL3_FORCE_EXT_LPO_SEL;
8001	int_lpo_sel = getintvar(NULL, "boardflags3") & BFL3_FORCE_INT_LPO_SEL;
8002	ext_lpo_isclock = getintvar(NULL, "boardflags3") & BFL3_EXT_LPO_ISCLOCK;
8003
8004	BCM_REFERENCE(ext_lpo_isclock);
8005
8006	if (ext_lpo_sel != 0) {
8007		switch (CHIPID(sih->chip)) {
8008		case BCM43602_CHIP_ID:
8009		case BCM43462_CHIP_ID:
8010			/* External LPO is POR default enabled */
8011			si_pmu_regcontrol(sih, CHIPCTRLREG2, PMU43602_CC2_XTAL32_SEL,
8012				ext_lpo_isclock ? 0 : PMU43602_CC2_XTAL32_SEL);
8013			break;
8014		default:
8015			/* Force External LPO Power Up */
8016			si_pmu_chipcontrol(sih, CHIPCTRLREG0, CC_EXT_LPO_PU, CC_EXT_LPO_PU);
8017			si_gci_chipcontrol(sih, CHIPCTRLREG6, GC_EXT_LPO_PU, GC_EXT_LPO_PU);
8018			break;
8019		}
8020
8021		ext_lpo_avail = R_REG(osh, PMUREG(sih, pmustatus)) & EXT_LPO_AVAIL;
8022		while (ext_lpo_avail == 0 && timeout < LPO_SEL_TIMEOUT) {
8023			OSL_DELAY(1000);
8024			ext_lpo_avail = R_REG(osh, PMUREG(sih, pmustatus)) & EXT_LPO_AVAIL;
8025			timeout++;
8026		}
8027
8028		if (timeout >= LPO_SEL_TIMEOUT) {
8029			PMU_ERROR(("External LPO is not available\n"));
8030		} else {
8031			/* External LPO is available, lets use (=select) it */
8032			OSL_DELAY(1000);
8033			timeout = 0;
8034
8035			switch (CHIPID(sih->chip)) {
8036			case BCM43602_CHIP_ID:
8037			case BCM43462_CHIP_ID:
8038				si_pmu_regcontrol(sih, CHIPCTRLREG2, PMU43602_CC2_FORCE_EXT_LPO,
8039					PMU43602_CC2_FORCE_EXT_LPO); /* switches to external LPO */
8040				break;
8041			default:
8042				/* Force External LPO Sel up */
8043				si_gci_chipcontrol(sih, CHIPCTRLREG6, EXT_LPO_SEL, EXT_LPO_SEL);
8044				/* Clear Force Internal LPO Sel */
8045				si_gci_chipcontrol(sih, CHIPCTRLREG6, INT_LPO_SEL, 0x0);
8046				OSL_DELAY(1000);
8047
8048				lpo_sel = R_REG(osh, PMUREG(sih, pmucontrol)) & LPO_SEL;
8049				while (lpo_sel != 0 && timeout < LPO_SEL_TIMEOUT) {
8050					OSL_DELAY(1000);
8051					lpo_sel = R_REG(osh, PMUREG(sih, pmucontrol)) & LPO_SEL;
8052					timeout++;
8053				}
8054			}
8055
8056			if (timeout >= LPO_SEL_TIMEOUT) {
8057				PMU_ERROR(("External LPO is not set\n"));
8058				/* Clear Force External LPO Sel */
8059				switch (CHIPID(sih->chip)) {
8060				case BCM43602_CHIP_ID:
8061				case BCM43462_CHIP_ID:
8062					si_pmu_regcontrol(sih, CHIPCTRLREG2,
8063						PMU43602_CC2_FORCE_EXT_LPO, 0);
8064					break;
8065				default:
8066					si_gci_chipcontrol(sih, CHIPCTRLREG6, EXT_LPO_SEL, 0x0);
8067					break;
8068				}
8069			} else {
8070				/* Clear Force Internal LPO Power Up */
8071				switch (CHIPID(sih->chip)) {
8072				case BCM43602_CHIP_ID:
8073				case BCM43462_CHIP_ID:
8074					break;
8075				default:
8076					si_pmu_chipcontrol(sih, CHIPCTRLREG0, CC_INT_LPO_PU, 0x0);
8077					si_gci_chipcontrol(sih, CHIPCTRLREG6, GC_INT_LPO_PU, 0x0);
8078					break;
8079				}
8080			} /* if (timeout) */
8081		} /* if (timeout) */
8082	} else if (int_lpo_sel != 0) {
8083		switch (CHIPID(sih->chip)) {
8084		case BCM43602_CHIP_ID:
8085		case BCM43462_CHIP_ID:
8086			break; /* do nothing, internal LPO is POR default powered and selected */
8087		default:
8088			/* Force Internal LPO Power Up */
8089			si_pmu_chipcontrol(sih, CHIPCTRLREG0, CC_INT_LPO_PU, CC_INT_LPO_PU);
8090			si_gci_chipcontrol(sih, CHIPCTRLREG6, GC_INT_LPO_PU, GC_INT_LPO_PU);
8091
8092			OSL_DELAY(1000);
8093
8094			/* Force Internal LPO Sel up */
8095			si_gci_chipcontrol(sih, CHIPCTRLREG6, INT_LPO_SEL, INT_LPO_SEL);
8096			/* Clear Force External LPO Sel */
8097			si_gci_chipcontrol(sih, CHIPCTRLREG6, EXT_LPO_SEL, 0x0);
8098
8099			OSL_DELAY(1000);
8100
8101			lpo_sel = R_REG(osh, PMUREG(sih, pmucontrol)) & LPO_SEL;
8102			timeout = 0;
8103			while (lpo_sel == 0 && timeout < LPO_SEL_TIMEOUT) {
8104				OSL_DELAY(1000);
8105				lpo_sel = R_REG(osh, PMUREG(sih, pmucontrol)) & LPO_SEL;
8106				timeout++;
8107			}
8108			if (timeout >= LPO_SEL_TIMEOUT) {
8109				PMU_ERROR(("Internal LPO is not set\n"));
8110				/* Clear Force Internal LPO Sel */
8111				si_gci_chipcontrol(sih, CHIPCTRLREG6, INT_LPO_SEL, 0x0);
8112			} else {
8113				/* Clear Force External LPO Power Up */
8114				si_pmu_chipcontrol(sih, CHIPCTRLREG0, CC_EXT_LPO_PU, 0x0);
8115				si_gci_chipcontrol(sih, CHIPCTRLREG6, GC_EXT_LPO_PU, 0x0);
8116			}
8117			break;
8118		}
8119	}
8120} /* si_pmu_set_lpoclk */
8121
8122/** initialize PMU chip controls and other chip level stuff */
8123void
8124BCMATTACHFN(si_pmu_chip_init)(si_t *sih, osl_t *osh)
8125{
8126	ASSERT(sih->cccaps & CC_CAP_PMU);
8127
8128	si_pmu_otp_chipcontrol(sih, osh);
8129
8130#ifdef CHIPC_UART_ALWAYS_ON
8131	si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, clk_ctl_st), CCS_FORCEALP, CCS_FORCEALP);
8132#endif /* CHIPC_UART_ALWAYS_ON */
8133
8134#ifndef CONFIG_XIP
8135	/* Gate off SPROM clock and chip select signals */
8136	si_pmu_sprom_enable(sih, osh, FALSE);
8137#endif
8138
8139	/* Misc. chip control, has nothing to do with PMU */
8140	switch (CHIPID(sih->chip)) {
8141	case BCM4315_CHIP_ID:
8142#ifdef BCMUSBDEV
8143		si_setcore(sih, PCMCIA_CORE_ID, 0);
8144		si_core_disable(sih, 0);
8145#endif
8146		break;
8147
8148	case BCM4324_CHIP_ID:
8149	case BCM43242_CHIP_ID:
8150	case BCM43243_CHIP_ID:
8151	{
8152#if defined(BCM4324A0) || defined(BCM4324A1)
8153		si_pmu_chipcontrol(sih, PMU_CHIPCTL1,
8154			(PMU4324_CC1_GPIO_CONF(-1) | PMU4324_CC1_ENABLE_UART),
8155			(PMU4324_CC1_GPIO_CONF(0) | PMU4324_CC1_ENABLE_UART));
8156		si_pmu_chipcontrol(sih, PMU_CHIPCTL2, PMU4324_CC2_SDIO_AOS_EN,
8157			PMU4324_CC2_SDIO_AOS_EN);
8158#endif
8159
8160#ifdef BCM4324B0
8161		si_pmu_chipcontrol(sih, PMU_CHIPCTL1,
8162		PMU4324_CC1_ENABLE_UART,
8163		0);
8164		si_pmu_chipcontrol(sih, PMU_CHIPCTL2,
8165		PMU4324_CC2_SDIO_AOS_EN,
8166		PMU4324_CC2_SDIO_AOS_EN);
8167#endif
8168
8169#if defined(BCM4324A1) || defined(BCM4324B0)
8170
8171		/* 4324 iPA Board hence muxing out PALDO_PU signal to O/p pin &
8172		 * muxing out actual RF_SW_CTRL7-6 signals to O/p pin
8173		 */
8174
8175		si_pmu_chipcontrol(sih, 4, 0x1f0000, 0x140000);
8176#endif
8177		/*
8178		 * Setting the pin mux to enable the GPIOs required for HSIC-OOB signals.
8179		 */
8180#if defined(BCM4324B1)
8181		si_pmu_chipcontrol(sih, PMU_CHIPCTL1, PMU4324_CC1_GPIO_CONF_MASK, 0x2);
8182#endif
8183		break;
8184	}
8185
8186	case BCM4336_CHIP_ID:
8187	case BCM43362_CHIP_ID:
8188	{
8189		uint32 mask, val = 0;
8190		uint16 clkreq_conf;
8191		mask = (1 << PMU_CC1_CLKREQ_TYPE_SHIFT);
8192
8193		clkreq_conf = (uint16)getintvar(NULL, rstr_clkreq_conf);
8194
8195		if (clkreq_conf & CLKREQ_TYPE_CONFIG_PUSHPULL)
8196			val =  (1 << PMU_CC1_CLKREQ_TYPE_SHIFT);
8197
8198		si_pmu_chipcontrol(sih, PMU_CHIPCTL0, mask, val);
8199		break;
8200	}
8201
8202#ifdef BCMQT
8203	case BCM4314_CHIP_ID:
8204	{
8205		uint32 tmp;
8206
8207
8208		W_REG(osh, PMUREG(sih, chipcontrol_addr), PMU_CHIPCTL3);
8209		tmp = R_REG(osh, PMUREG(sih, chipcontrol_data));
8210		tmp &= ~(1 << PMU_CC3_ENABLE_RF_SHIFT);
8211		tmp |= (1 << PMU_CC3_RF_DISABLE_IVALUE_SHIFT);
8212		W_REG(osh, PMUREG(sih, chipcontrol_data), tmp);
8213		break;
8214	}
8215#endif /* BCMQT */
8216
8217	case BCM4350_CHIP_ID:
8218	case BCM4354_CHIP_ID:
8219	case BCM4356_CHIP_ID:
8220	case BCM43556_CHIP_ID:
8221	case BCM43558_CHIP_ID:
8222	case BCM43566_CHIP_ID:
8223	case BCM43568_CHIP_ID:
8224	case BCM43569_CHIP_ID:
8225	case BCM43570_CHIP_ID:
8226	{
8227		uint32 val;
8228
8229		if (CST4350_IFC_MODE(sih->chipst) == CST4350_IFC_MODE_PCIE) {
8230			/* JIRA: SWWLAN-27305 initialize 4350 pmu control registers */
8231			si_pmu_chipcontrol(sih, PMU_CHIPCTL1,
8232				PMU_CC1_ENABLE_BBPLL_PWR_DOWN, PMU_CC1_ENABLE_BBPLL_PWR_DOWN);
8233			si_pmu_regcontrol(sih, 0, ~0, 1);
8234
8235			/* JIRA:SWWLAN-36186; HW4345-889 */
8236			si_pmu_chipcontrol(sih, PMU_CHIPCTL5, CC5_4350_PMU_EN_ASSERT_MASK,
8237				CC5_4350_PMU_EN_ASSERT_MASK);
8238
8239			/* JIRA: SWWLAN-27486 optimize power consumption when wireless is down */
8240			if ((CHIPID(sih->chip) == BCM4350_CHIP_ID) &&
8241				(sih->chiprev == 0)) { /* 4350A0 */
8242				val = PMU_CC2_FORCE_SUBCORE_PWR_SWITCH_ON |
8243				      PMU_CC2_FORCE_PHY_PWR_SWITCH_ON |
8244				      PMU_CC2_FORCE_VDDM_PWR_SWITCH_ON |
8245				      PMU_CC2_FORCE_MEMLPLDO_PWR_SWITCH_ON;
8246				si_pmu_chipcontrol(sih, PMU_CHIPCTL2, val, val);
8247
8248				val = PMU_CC6_ENABLE_CLKREQ_WAKEUP |
8249				      PMU_CC6_ENABLE_PMU_WAKEUP_ALP;
8250				si_pmu_chipcontrol(sih, PMU_CHIPCTL6, val, val);
8251			}
8252		}
8253		/* Set internal/external LPO */
8254		si_pmu_set_lpoclk(sih, osh);
8255		break;
8256	}
8257	case BCM4335_CHIP_ID:
8258	case BCM43602_CHIP_ID: /* fall through */
8259	case BCM43462_CHIP_ID: /* fall through */
8260		/* Set internal/external LPO */
8261		si_pmu_set_lpoclk(sih, osh);
8262		break;
8263	default:
8264		break;
8265	}
8266} /* si_pmu_chip_init */
8267
8268void
8269si_pmu_slow_clk_reinit(si_t *sih, osl_t *osh)
8270{
8271	chipcregs_t *cc;
8272	uint origidx;
8273	uint32 xtalfreq, mode;
8274
8275	/* PMU specific initializations */
8276	if (!PMUCTL_ENAB(sih))
8277		return;
8278	/* Remember original core before switch to chipc */
8279	origidx = si_coreidx(sih);
8280	cc = si_setcoreidx(sih, SI_CC_IDX);
8281	ASSERT(cc != NULL);
8282	if (cc == NULL)
8283		return;
8284
8285	xtalfreq = getintvar(NULL, rstr_xtalfreq);
8286	switch (CHIPID(sih->chip)) {
8287		case BCM43242_CHIP_ID:
8288		case BCM43243_CHIP_ID:
8289			xtalfreq = 37400;
8290			break;
8291		case BCM43143_CHIP_ID:
8292			xtalfreq = 20000;
8293			break;
8294		case BCM43602_CHIP_ID:
8295		case BCM43462_CHIP_ID:
8296			xtalfreq = 40000;
8297			break;
8298		case BCM4350_CHIP_ID:
8299		case BCM4354_CHIP_ID:
8300		case BCM4356_CHIP_ID:
8301		case BCM43556_CHIP_ID:
8302		case BCM43558_CHIP_ID:
8303		case BCM43566_CHIP_ID:
8304		case BCM43568_CHIP_ID:
8305		case BCM43569_CHIP_ID:
8306		case BCM43570_CHIP_ID:
8307			if (xtalfreq == 0) {
8308				mode = CST4350_IFC_MODE(sih->chipst);
8309				if ((mode == CST4350_IFC_MODE_USB20D) ||
8310				    (mode == CST4350_IFC_MODE_USB30D) ||
8311				    (mode == CST4350_IFC_MODE_USB30D_WL))
8312					xtalfreq = 40000;
8313				else {
8314					xtalfreq = 37400;
8315					if (mode == CST4350_IFC_MODE_HSIC20D ||
8316					    mode == CST4350_IFC_MODE_HSIC30D) {
8317						/* HSIC sprom_present_strap=1:40 mHz xtal */
8318						if (((CHIPREV(sih->chiprev) >= 3) ||
8319						     (CHIPID(sih->chip) == BCM4354_CHIP_ID) ||
8320						     (CHIPID(sih->chip) == BCM4356_CHIP_ID) ||
8321						     (CHIPID(sih->chip) == BCM43569_CHIP_ID) ||
8322						     (CHIPID(sih->chip) == BCM43570_CHIP_ID)) &&
8323						    CST4350_PKG_USB_40M(sih->chipst) &&
8324						    CST4350_PKG_USB(sih->chipst)) {
8325							xtalfreq = 40000;
8326						}
8327					}
8328				}
8329			}
8330			break;
8331		default:
8332			break;
8333	}
8334	/* If xtalfreq var not available, try to measure it */
8335	if (xtalfreq == 0)
8336		xtalfreq = si_pmu_measure_alpclk(sih, osh);
8337	si_pmu_enb_slow_clk(sih, osh, xtalfreq);
8338	/* Return to original core */
8339	si_setcoreidx(sih, origidx);
8340}
8341
8342/* 4345 Active Voltage supply settings */
8343#define OTP4345_AVS_STATUS_OFFSET 0x14 /* offset in OTP for AVS status register */
8344#define OTP4345_AVS_RO_OFFSET 0x18 /* offset in OTP for AVS Ring Oscillator value */
8345
8346#define AVS_STATUS_ENABLED_FLAG  0x1
8347#define AVS_STATUS_ABORT_FLAG    0x2
8348#define AVS_RO_OTP_MASK  0x1fff /* Only 13 bits of Ring Oscillator value are stored in OTP */
8349#define AVS_RO_MIN_COUNT  4800
8350#define AVS_RO_MAX_COUNT  8000
8351#define AVS_RO_IDEAL_COUNT   4800 /* Corresponds to 1.2V */
8352
8353
8354/** initialize PMU registers in case default values proved to be suboptimal */
8355void
8356BCMATTACHFN(si_pmu_swreg_init)(si_t *sih, osl_t *osh)
8357{
8358	uint16 cbuck_mv;
8359	int8 vreg_val;
8360
8361	ASSERT(sih->cccaps & CC_CAP_PMU);
8362
8363	switch (CHIPID(sih->chip)) {
8364	case BCM4325_CHIP_ID:
8365		if (CHIPREV(sih->chiprev) < 3)
8366			break;
8367		if (((sih->chipst & CST4325_PMUTOP_2B_MASK) >> CST4325_PMUTOP_2B_SHIFT) == 1) {
8368			/* Bump CLDO PWM output voltage to 1.25V */
8369			si_pmu_set_ldo_voltage(sih, osh, SET_LDO_VOLTAGE_CLDO_PWM, 0xf);
8370			/* Bump CLDO BURST output voltage to 1.25V */
8371			si_pmu_set_ldo_voltage(sih, osh, SET_LDO_VOLTAGE_CLDO_BURST, 0xf);
8372		}
8373		/* Bump CBUCK PWM output voltage to 1.5V */
8374		si_pmu_set_ldo_voltage(sih, osh, SET_LDO_VOLTAGE_CBUCK_PWM, 0xb);
8375		/* Bump CBUCK BURST output voltage to 1.5V */
8376		si_pmu_set_ldo_voltage(sih, osh, SET_LDO_VOLTAGE_CBUCK_BURST, 0xb);
8377		/* Bump LNLDO1 output voltage to 1.25V */
8378		si_pmu_set_ldo_voltage(sih, osh, SET_LDO_VOLTAGE_LNLDO1, 0x1);
8379		/* Select LNLDO2 output voltage to 2.5V */
8380		if (sih->boardflags & BFL_LNLDO2_2P5)
8381			si_pmu_set_ldo_voltage(sih, osh, SET_LDO_VOLTAGE_LNLDO2_SEL, 0x1);
8382		break;
8383	case BCM4315_CHIP_ID: {
8384		uint32 val;
8385		if (CHIPREV(sih->chiprev) != 2)
8386			break;
8387
8388		W_REG(osh, PMUREG(sih, regcontrol_addr), 4);
8389		val = R_REG(osh, PMUREG(sih, regcontrol_data));
8390		val |= (uint32)(1 << 16);
8391		W_REG(osh, PMUREG(sih, regcontrol_data), val);
8392		break;
8393	}
8394	case BCM4336_CHIP_ID:
8395		if (CHIPREV(sih->chiprev) < 2) {
8396			/* Reduce CLDO PWM output voltage to 1.2V */
8397			si_pmu_set_ldo_voltage(sih, osh, SET_LDO_VOLTAGE_CLDO_PWM, 0xe);
8398			/* Reduce CLDO BURST output voltage to 1.2V */
8399			si_pmu_set_ldo_voltage(sih, osh, SET_LDO_VOLTAGE_CLDO_BURST, 0xe);
8400			/* Reduce LNLDO1 output voltage to 1.2V */
8401			si_pmu_set_ldo_voltage(sih, osh, SET_LDO_VOLTAGE_LNLDO1, 0xe);
8402		}
8403		if (CHIPREV(sih->chiprev) == 2) {
8404			/* Reduce CBUCK PWM output voltage */
8405			si_pmu_set_ldo_voltage(sih, osh, SET_LDO_VOLTAGE_CBUCK_PWM, 0x16);
8406			/* Reduce CBUCK BURST output voltage */
8407			si_pmu_set_ldo_voltage(sih, osh, SET_LDO_VOLTAGE_CBUCK_BURST, 0x16);
8408			si_pmu_set_ldo_voltage(sih, osh, SET_LNLDO_PWERUP_LATCH_CTRL, 0x3);
8409		}
8410		if (CHIPREV(sih->chiprev) == 0)
8411			si_pmu_regcontrol(sih, 2, 0x400000, 0x400000);
8412
8413	case BCM43362_CHIP_ID:
8414	case BCM4330_CHIP_ID:
8415		cbuck_mv = (uint16)getintvar(NULL, rstr_cbuckout);
8416
8417		/* set default cbuck output to be 1.5V */
8418		if (!cbuck_mv)
8419			cbuck_mv = 1500;
8420		vreg_val = si_pmu_cbuckout_to_vreg_ctrl(sih, cbuck_mv);
8421		/* set vreg ctrl only if there is a mapping defined for vout to bit map */
8422		if (vreg_val >= 0) {
8423			si_pmu_set_ldo_voltage(sih, osh, SET_LDO_VOLTAGE_CBUCK_PWM, vreg_val);
8424			si_pmu_set_ldo_voltage(sih, osh, SET_LDO_VOLTAGE_CBUCK_BURST, vreg_val);
8425		}
8426		break;
8427	case BCM4314_CHIP_ID:
8428		if (CHIPREV(sih->chiprev) == 0) {
8429			/* Reduce LPLDO2 output voltage to 1.0V */
8430			si_pmu_set_ldo_voltage(sih, osh, SET_LDO_VOLTAGE_LDO2, 0);
8431		}
8432		break;
8433	case BCM43341_CHIP_ID:
8434	case BCM4334_CHIP_ID:
8435	{
8436		const char *cldo_val;
8437		uint32 cldo;
8438
8439		/* Clear BT/WL REG_ON pulldown resistor disable to reduce leakage */
8440		si_pmu_regcontrol(sih, PMU_VREG0_ADDR, (1 << PMU_VREG0_DISABLE_PULLD_BT_SHIFT) |
8441			(1 << PMU_VREG0_DISABLE_PULLD_WL_SHIFT), 0);
8442
8443		if (!CST4334_CHIPMODE_HSIC(sih->chipst))
8444			si_pmu_chipcontrol(sih, 2, CCTRL4334_HSIC_LDO_PU, CCTRL4334_HSIC_LDO_PU);
8445
8446		if ((cldo_val = getvar(NULL, rstr_cldo_ldo2)) != NULL) {
8447			/* Adjust LPLDO2 output voltage */
8448			cldo = (uint32)bcm_strtoul(cldo_val, NULL, 0);
8449			si_pmu_set_ldo_voltage(sih, osh, SET_LDO_VOLTAGE_LDO2, (uint8) cldo);
8450		}
8451#ifdef SRFAST
8452		else
8453			/* Reduce LPLDO2 output voltage to 1.0V by default for SRFAST */
8454			si_pmu_set_ldo_voltage(sih, osh, SET_LDO_VOLTAGE_LDO2, 0);
8455#endif
8456
8457		if ((cldo_val = getvar(NULL, rstr_cldo_pwm)) != NULL) {
8458			cldo = (uint32)bcm_strtoul(cldo_val, NULL, 0);
8459			si_pmu_set_ldo_voltage(sih, osh, SET_LDO_VOLTAGE_CLDO_PWM, (uint8) cldo);
8460		}
8461
8462		if ((cldo_val = getvar(NULL, rstr_force_pwm_cbuck)) != NULL) {
8463			cldo = (uint32)bcm_strtoul(cldo_val, NULL, 0);
8464
8465			pmu_corereg(sih, SI_CC_IDX, regcontrol_addr,
8466				~0, 0);
8467			pmu_corereg(sih, SI_CC_IDX, regcontrol_data,
8468				0x1 << 1, (cldo & 0x1) << 1);
8469		}
8470	}
8471		break;
8472	case BCM43143_CHIP_ID:
8473#ifndef BCM_BOOTLOADER
8474		/* Force CBUCK to PWM mode */
8475		si_pmu_regcontrol(sih, 0, 0x2, 0x2);
8476		/* Increase CBUCK output voltage to 1.4V */
8477		si_pmu_set_ldo_voltage(sih, osh, SET_LDO_VOLTAGE_CBUCK_PWM, 0x2);
8478		si_pmu_set_ldo_voltage(sih, osh, SET_LDO_VOLTAGE_CBUCK_BURST, 0x2);
8479		/* Decrease LNLDO output voltage to just under 1.2V */
8480		si_pmu_set_ldo_voltage(sih, osh, SET_LDO_VOLTAGE_LNLDO1, 0x7);
8481
8482		si_pmu_chipcontrol(sih, PMU_CHIPCTL0, PMU43143_XTAL_CORE_SIZE_MASK, 0x10);
8483#endif
8484		break;
8485	case BCM4354_CHIP_ID:
8486	case BCM4356_CHIP_ID:
8487	case BCM43569_CHIP_ID:
8488	case BCM43570_CHIP_ID:
8489		si_gci_chipcontrol(sih, 5, 0x3 << 29, 0x3 << 29);
8490		break;
8491	case BCM4350_CHIP_ID:
8492	case BCM43556_CHIP_ID:
8493	case BCM43558_CHIP_ID:
8494	case BCM43566_CHIP_ID:
8495	case BCM43568_CHIP_ID:
8496		/*
8497		 * HW4350-275: Chip wedge due to xtal startup issue when WL is in SR
8498		 *     and BT is out of reset
8499		 * WAR: Set both GCI bits 189 and 190
8500		 *   bit 29 (189): When set this will allow wl2clb_xtal_pu as the
8501		 *       mux select for xtal_coresize_pmos, nmos from WL side
8502		 *   bit 30 (190): When set bt_xtal_pu will be able to change the wl
8503		 *       which selects xtal core size between
8504		 *       normal and start up while wl is in reset.
8505		 */
8506		if (CHIPREV(sih->chiprev) == 3)
8507			si_gci_chipcontrol(sih, 5, 0x3 << 29, 0x3 << 29);
8508		break;
8509	case BCM43602_CHIP_ID:
8510	case BCM43462_CHIP_ID:
8511		/* adjust PA Vref to 2.80V */
8512		si_pmu_set_ldo_voltage(sih, osh, SET_LDO_VOLTAGE_PAREF, 0x0c);
8513		break;
8514	case BCM4345_CHIP_ID:
8515#if defined(DONGLEBUILD)
8516	{
8517		uint16 avs_ro_cnt = 0;
8518		uint16 avs_status = 0;
8519		uint32 gci_val = 0;
8520
8521		if (getintvar(NULL, rstr_avs_enab)) {
8522
8523			if (otp_read_word(sih, OTP4345_AVS_RO_OFFSET, &avs_status) != BCME_OK)
8524				break;
8525
8526			if ((avs_status & AVS_STATUS_ENABLED_FLAG) &&
8527			    !(avs_status & AVS_STATUS_ABORT_FLAG)) {
8528				if (otp_read_word(sih, OTP4345_AVS_RO_OFFSET,
8529				                  &avs_ro_cnt) != BCME_OK)
8530					break;
8531				avs_ro_cnt &= AVS_RO_OTP_MASK;
8532				avs_ro_cnt = LIMIT_TO_RANGE(avs_ro_cnt, AVS_RO_MIN_COUNT,
8533				                            AVS_RO_MAX_COUNT);
8534				gci_val = ((((AVS_RO_IDEAL_COUNT - avs_ro_cnt) * 71) / 10000)
8535				           & 0x1F) | CC4345_GCI_AVS_CTRL_ENAB;
8536				si_gci_chipcontrol(sih, CHIPCTRLREG3, CC4345_GCI_AVS_CTRL_MASK,
8537				                   gci_val << CC4345_GCI_AVS_CTRL_SHIFT);
8538			}
8539		}
8540	}
8541#endif
8542	break;
8543	default:
8544		break;
8545	}
8546	si_pmu_otp_regcontrol(sih, osh);
8547} /* si_pmu_swreg_init */
8548
8549void
8550si_pmu_radio_enable(si_t *sih, bool enable)
8551{
8552	ASSERT(sih->cccaps & CC_CAP_PMU);
8553
8554	switch (CHIPID(sih->chip)) {
8555	case BCM4325_CHIP_ID:
8556		if (sih->boardflags & BFL_FASTPWR)
8557			break;
8558
8559		if ((sih->boardflags & BFL_BUCKBOOST)) {
8560			pmu_corereg(sih, SI_CC_IDX, min_res_mask,
8561			           PMURES_BIT(RES4325_BUCK_BOOST_BURST),
8562			           enable ? PMURES_BIT(RES4325_BUCK_BOOST_BURST) : 0);
8563		}
8564
8565		if (enable) {
8566			OSL_DELAY(100 * 1000);
8567		}
8568		break;
8569	case BCM4319_CHIP_ID:
8570	case BCM4330_CHIP_ID:
8571	case BCM4336_CHIP_ID:
8572	case BCM43362_CHIP_ID:
8573	{
8574		uint32 wrap_reg, val;
8575		wrap_reg = si_wrapperreg(sih, AI_OOBSELOUTB74, 0, 0);
8576
8577		val = ((1 << OOB_SEL_OUTEN_B_5) | (1 << OOB_SEL_OUTEN_B_6));
8578		if (enable)
8579			wrap_reg |= val;
8580		else
8581			wrap_reg &= ~val;
8582		si_wrapperreg(sih, AI_OOBSELOUTB74, ~0, wrap_reg);
8583
8584		break;
8585	}
8586	default:
8587		break;
8588	}
8589} /* si_pmu_radio_enable */
8590
8591/** Wait for a particular clock level to be on the backplane */
8592uint32
8593si_pmu_waitforclk_on_backplane(si_t *sih, osl_t *osh, uint32 clk, uint32 delay_val)
8594{
8595	ASSERT(sih->cccaps & CC_CAP_PMU);
8596
8597	if (delay_val)
8598		SPINWAIT(((R_REG(osh, PMUREG(sih, pmustatus)) & clk) != clk), delay_val);
8599	return (R_REG(osh, PMUREG(sih, pmustatus)) & clk);
8600}
8601
8602/**
8603 * Measures the ALP clock frequency in KHz.  Returns 0 if not possible.
8604 * Possible only if PMU rev >= 10 and there is an external LPO 32768Hz crystal.
8605 */
8606
8607#define EXT_ILP_HZ 32768
8608
8609uint32
8610BCMATTACHFN(si_pmu_measure_alpclk)(si_t *sih, osl_t *osh)
8611{
8612	uint32 alp_khz;
8613	uint32 pmustat_lpo = 0;
8614
8615	if (sih->pmurev < 10)
8616		return 0;
8617
8618	ASSERT(sih->cccaps & CC_CAP_PMU);
8619	if ((CHIPID(sih->chip) == BCM4335_CHIP_ID) ||
8620		(CHIPID(sih->chip) == BCM4345_CHIP_ID) ||
8621		(CHIPID(sih->chip) == BCM43602_CHIP_ID) ||
8622		(CHIPID(sih->chip) == BCM43462_CHIP_ID) ||
8623		BCM4350_CHIP(sih->chip) ||
8624		0)
8625		pmustat_lpo = !(R_REG(osh, PMUREG(sih, pmucontrol)) & PCTL_LPO_SEL);
8626	else
8627		pmustat_lpo = R_REG(osh, PMUREG(sih, pmustatus)) & PST_EXTLPOAVAIL;
8628
8629	if (pmustat_lpo) {
8630		uint32 ilp_ctr, alp_hz;
8631
8632		/* Enable the reg to measure the freq, in case disabled before */
8633		W_REG(osh, PMUREG(sih, pmu_xtalfreq), 1U << PMU_XTALFREQ_REG_MEASURE_SHIFT);
8634
8635		/* Delay for well over 4 ILP clocks */
8636		OSL_DELAY(1000);
8637
8638		/* Read the latched number of ALP ticks per 4 ILP ticks */
8639		ilp_ctr = R_REG(osh, PMUREG(sih, pmu_xtalfreq)) & PMU_XTALFREQ_REG_ILPCTR_MASK;
8640
8641		/* Turn off the PMU_XTALFREQ_REG_MEASURE_SHIFT bit to save power */
8642		W_REG(osh, PMUREG(sih, pmu_xtalfreq), 0);
8643
8644		/* Calculate ALP frequency */
8645		alp_hz = (ilp_ctr * EXT_ILP_HZ) / 4;
8646
8647		/* Round to nearest 100KHz, and at the same time convert to KHz */
8648		alp_khz = (alp_hz + 50000) / 100000 * 100;
8649	} else
8650		alp_khz = 0;
8651	return alp_khz;
8652} /* si_pmu_measure_alpclk */
8653
8654void
8655si_pmu_set_4330_plldivs(si_t *sih, uint8 dacrate)
8656{
8657	uint32 FVCO = si_pmu1_pllfvco0(sih)/1000;	/* in [Mhz] */
8658	uint32 m1div, m2div, m3div, m4div, m5div, m6div;
8659	uint32 pllc1, pllc2;
8660
8661	m2div = m3div = m4div = m6div = FVCO/80;
8662
8663	m5div = FVCO/dacrate;
8664
8665	if (CST4330_CHIPMODE_SDIOD(sih->chipst))
8666		m1div = FVCO/80;
8667	else
8668		m1div = FVCO/90;
8669	pllc1 = (m1div << PMU1_PLL0_PC1_M1DIV_SHIFT) | (m2div << PMU1_PLL0_PC1_M2DIV_SHIFT) |
8670		(m3div << PMU1_PLL0_PC1_M3DIV_SHIFT) | (m4div << PMU1_PLL0_PC1_M4DIV_SHIFT);
8671	si_pmu_pllcontrol(sih, PMU1_PLL0_PLLCTL1, ~0, pllc1);
8672
8673	pllc2 = si_pmu_pllcontrol(sih, PMU1_PLL0_PLLCTL2, 0, 0);
8674	pllc2 &= ~(PMU1_PLL0_PC2_M5DIV_MASK | PMU1_PLL0_PC2_M6DIV_MASK);
8675	pllc2 |= ((m5div << PMU1_PLL0_PC2_M5DIV_SHIFT) | (m6div << PMU1_PLL0_PC2_M6DIV_SHIFT));
8676	si_pmu_pllcontrol(sih, PMU1_PLL0_PLLCTL2, ~0, pllc2);
8677} /* si_pmu_set_4330_plldivs */
8678
8679typedef struct cubkout2vreg {
8680	uint16 cbuck_mv;
8681	int8  vreg_val;
8682} cubkout2vreg_t;
8683
8684cubkout2vreg_t BCMATTACHDATA(cbuck2vreg_tbl)[] = {
8685	{1500,	0},
8686	{1800,	0x17}
8687};
8688
8689static int8
8690BCMATTACHFN(si_pmu_cbuckout_to_vreg_ctrl)(si_t *sih, uint16 cbuck_mv)
8691{
8692	uint32 i;
8693
8694	for (i = 0; i < ARRAYSIZE(cbuck2vreg_tbl); i++) {
8695		if (cbuck_mv == cbuck2vreg_tbl[i].cbuck_mv)
8696			return cbuck2vreg_tbl[i].vreg_val;
8697	}
8698	return -1;
8699}
8700
8701/** Update min/max resources after SR-ASM download to d11 txfifo */
8702void
8703si_pmu_res_minmax_update(si_t *sih, osl_t *osh)
8704{
8705	si_info_t *sii = SI_INFO(sih);
8706	uint32 min_mask = 0, max_mask = 0;
8707	chipcregs_t *cc;
8708	uint origidx, intr_val = 0;
8709
8710	/* Block ints and save current core */
8711	INTR_OFF(sii, intr_val);
8712	/* Remember original core before switch to chipc */
8713	origidx = si_coreidx(sih);
8714	cc = si_setcoreidx(sih, SI_CC_IDX);
8715	ASSERT(cc != NULL);
8716
8717	switch (CHIPID(sih->chip)) {
8718	case BCM4345_CHIP_ID:
8719	case BCM43602_CHIP_ID:
8720	case BCM43462_CHIP_ID:
8721	case BCM4350_CHIP_ID:
8722	case BCM4354_CHIP_ID:
8723	case BCM4356_CHIP_ID:
8724	case BCM43556_CHIP_ID:
8725	case BCM43558_CHIP_ID:
8726	case BCM43566_CHIP_ID:
8727	case BCM43568_CHIP_ID:
8728	case BCM43569_CHIP_ID:
8729	case BCM43570_CHIP_ID:
8730		si_pmu_res_masks(sih, &min_mask, &max_mask);
8731		max_mask = 0; /* Only care about min_mask for now */
8732		break;
8733	case BCM4335_CHIP_ID:
8734#if defined(SAVERESTORE)
8735		min_mask = PMURES_BIT(RES4335_LPLDO_PO);
8736#else
8737		min_mask = PMURES_BIT(RES4335_WL_CORE_RDY) | PMURES_BIT(RES4335_OTP_PU);
8738#endif
8739		break;
8740	default:
8741		break;
8742	}
8743
8744	if (min_mask) {
8745		/* Add min mask dependencies */
8746		min_mask |= si_pmu_res_deps(sih, osh, cc, min_mask, FALSE);
8747		W_REG(osh, PMUREG(sih, min_res_mask), min_mask);
8748	}
8749
8750	if (max_mask) {
8751		/* Add max mask dependencies */
8752		max_mask |= si_pmu_res_deps(sih, osh, cc, max_mask, FALSE);
8753		W_REG(osh, PMUREG(sih, max_res_mask), max_mask);
8754	}
8755
8756	si_pmu_wait_for_steady_state(sih, osh, cc);
8757
8758	/* Return to original core */
8759	si_setcoreidx(sih, origidx);
8760	INTR_RESTORE(sii, intr_val);
8761} /* si_pmu_res_minmax_update */
8762