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