xref: /OK3568_Linux_fs/external/rkwifibt/drivers/bcmdhd/hndpmu.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /*
2  * Misc utility routines for accessing PMU corerev specific features
3  * of the SiliconBackplane-based Broadcom chips.
4  *
5  * Copyright (C) 2020, Broadcom.
6  *
7  *      Unless you and Broadcom execute a separate written software license
8  * agreement governing use of this software, this software is licensed to you
9  * under the terms of the GNU General Public License version 2 (the "GPL"),
10  * available at http://www.broadcom.com/licenses/GPLv2.php, with the
11  * following added to such license:
12  *
13  *      As a special exception, the copyright holders of this software give you
14  * permission to link this software with independent modules, and to copy and
15  * distribute the resulting executable under terms of your choice, provided that
16  * you also meet, for each linked independent module, the terms and conditions of
17  * the license of that module.  An independent module is a module which is not
18  * derived from this software.  The special exception does not apply to any
19  * modifications of the software.
20  *
21  *
22  * <<Broadcom-WL-IPTag/Dual:>>
23  */
24 
25 /**
26  * @file
27  * Note: this file contains PLL/FLL related functions. A chip can contain multiple PLLs/FLLs.
28  * However, in the context of this file the baseband ('BB') PLL/FLL is referred to.
29  *
30  * Throughout this code, the prefixes 'pmu1_' and 'pmu2_' are used.
31  * They refer to different revisions of the PMU (which is at revision 18 @ Apr 25, 2012)
32  * pmu1_ marks the transition from PLL to ADFLL (Digital Frequency Locked Loop). It supports
33  * fractional frequency generation. pmu2_ does not support fractional frequency generation.
34  */
35 
36 #include <typedefs.h>
37 #include <bcmdefs.h>
38 #include <osl.h>
39 #include <bcmutils.h>
40 #include <siutils.h>
41 #include <bcmdevs.h>
42 #include <hndsoc.h>
43 #include <sbchipc.h>
44 #include <hndchipc.h>
45 #include <hndpmu.h>
46 #if defined DONGLEBUILD
47 #include <hndcpu.h>
48 #ifdef __arm__
49 #include <hndarm.h>
50 #endif
51 #endif /* DONGLEBUILD */
52 #if !defined(BCMDONGLEHOST)
53 #include <bcm_math.h>
54 #include <bcmotp.h>
55 #ifdef BCM_OTP_API
56 #include <bcm_otp_api.h>
57 #endif /* BCM_OTP_API */
58 #endif /* !BCMDONGLEHOST */
59 #if !defined(BCMDONGLEHOST)
60 #include <saverestore.h>
61 #endif
62 #include <hndlhl.h>
63 #include <sbgci.h>
64 #ifdef EVENT_LOG_COMPILE
65 #include <event_log.h>
66 #endif
67 #include <sbgci.h>
68 #include <lpflags.h>
69 
70 #include "siutils_priv.h"
71 
72 #ifdef BCM_AVS
73 #include <bcm_avs.h>
74 #endif
75 
76 #if defined(EVENT_LOG_COMPILE) && defined(BCMDBG_ERR) && defined(ERR_USE_EVENT_LOG)
77 #if defined(ERR_USE_EVENT_LOG_RA)
78 #define PMU_ERROR(args) EVENT_LOG_RA(EVENT_LOG_TAG_PMU_ERROR, args)
79 #else
80 #define PMU_ERROR(args) EVENT_LOG_COMPACT_CAST_PAREN_ARGS(EVENT_LOG_TAG_PMU_ERROR, args)
81 #endif /* ERR_USE_EVENT_LOG_RA */
82 #elif defined(BCMDBG_ERR)
83 #define	PMU_ERROR(args)	printf args
84 #else
85 #define	PMU_ERROR(args)
86 #endif	/* defined(BCMDBG_ERR) && defined(ERR_USE_EVENT_LOG) */
87 
88 #ifdef BCMDBG
89 //#define BCMDBG_PMU
90 #endif
91 
92 #ifdef BCMDBG_PMU
93 #define	PMU_MSG(args)	printf args
94 #else
95 #define	PMU_MSG(args)
96 #endif	/* BCMDBG_MPU */
97 
98 /* To check in verbose debugging messages not intended
99  * to be on except on private builds.
100  */
101 #define	PMU_NONE(args)
102 #define flags_shift	14
103 
104 /** contains resource bit positions for a specific chip */
105 struct rsc_per_chip {
106 	uint8 ht_avail;
107 	uint8 macphy_clkavail;
108 	uint8 ht_start;
109 	uint8 otp_pu;
110 	uint8 macphy_aux_clkavail;
111 	uint8 macphy_scan_clkavail;
112 	uint8 cb_ready;
113 	uint8 dig_ready;
114 };
115 
116 typedef struct rsc_per_chip rsc_per_chip_t;
117 
118 #if defined(BCMPMU_STATS) && !defined(BCMPMU_STATS_DISABLED)
119 bool	_pmustatsenab = TRUE;
120 #else
121 bool	_pmustatsenab = FALSE;
122 #endif /* BCMPMU_STATS */
123 
124 /* 1MHz lpo enable */
125 /* PLEASE USE THIS MACRO IN ATTACH PATH ONLY! */
126 #if defined(BCM_FASTLPO) && !defined(BCM_FASTLPO_DISABLED)
127 	#define FASTLPO_ENAB()	(TRUE)
128 #else
129 	#define FASTLPO_ENAB()	(FALSE)
130 #endif
131 
132 /* Disable the power optimization feature */
133 bool	_bcm_pwr_opt_dis = FALSE;
134 
135 #ifdef BCMSRTOPOFF
136 bool _srtopoff_enab = FALSE;
137 #endif
138 
139 pmuregs_t *hnd_pmur = NULL;  /* PMU core regs */
140 
141 #if !defined(BCMDONGLEHOST)
142 static void si_pmu_chipcontrol_xtal_settings_4369(si_t *sih);
143 static void si_pmu_chipcontrol_xtal_settings_4362(si_t *sih);
144 static void si_pmu_chipcontrol_xtal_settings_4378(si_t *sih);
145 
146 /* PLL controls/clocks */
147 static void si_pmu1_pllinit1(si_t *sih, osl_t *osh, pmuregs_t *pmu, uint32 xtal);
148 static void si_pmu_pll_off(si_t *sih, osl_t *osh, pmuregs_t *pmu, uint32 *min_mask,
149 	uint32 *max_mask, uint32 *clk_ctl_st);
150 static void si_pmu_pll_on(si_t *sih, osl_t *osh, pmuregs_t *pmu, uint32 min_mask,
151 	uint32 max_mask, uint32 clk_ctl_st);
152 static void si_pmu_otp_pllcontrol(si_t *sih, osl_t *osh);
153 static void si_pmu_otp_vreg_control(si_t *sih, osl_t *osh);
154 static void si_pmu_otp_chipcontrol(si_t *sih, osl_t *osh);
155 static uint32 si_pmu_def_alp_clock(si_t *sih, osl_t *osh);
156 static bool si_pmu_update_pllcontrol(si_t *sih, osl_t *osh, uint32 xtal, bool update_required);
157 static uint32 si_pmu_htclk_mask(si_t *sih);
158 
159 static uint32 si_pmu1_cpuclk0(si_t *sih, osl_t *osh, pmuregs_t *pmu);
160 static uint32 si_pmu1_alpclk0(si_t *sih, osl_t *osh, pmuregs_t *pmu);
161 
162 static uint32 si_pmu1_cpuclk0_pll2(si_t *sih);
163 
164 /* PMU resources */
165 static uint32 si_pmu_res_deps(si_t *sih, osl_t *osh, pmuregs_t *pmu, uint32 rsrcs, bool all);
166 static uint si_pmu_res_uptime(si_t *sih, osl_t *osh, pmuregs_t *pmu,
167 	uint8 rsrc, bool pmu_fast_trans_en);
168 static void si_pmu_res_masks(si_t *sih, uint32 *pmin, uint32 *pmax);
169 
170 uint32 si_pmu_get_pmutime_diff(si_t *sih, osl_t *osh, pmuregs_t *pmu, uint32 *prev);
171 bool si_pmu_wait_for_res_pending(si_t *sih, osl_t *osh, pmuregs_t *pmu, uint usec,
172 	bool cond, uint32 *elapsed_time);
173 
174 #ifdef __ARM_ARCH_7A__
175 static uint32 si_pmu_mem_ca7clock(si_t *sih, osl_t *osh);
176 #endif
177 
178 static uint8 fastlpo_dis_get(void);
179 static uint8 fastlpo_pcie_dis_get(void);
180 
181 static uint32 si_pmu_bpclk_4387(si_t *sih);
182 
183 static int si_pmu_openloop_cal_43012(si_t *sih, uint16 currtemp);
184 
185 static uint32 si_pmu_pll6val_armclk_calc(osl_t *osh, pmuregs_t *pmu, uint32 armclk, uint32 xtal,
186 		bool write);
187 static bool si_pmu_armpll_write_required(si_t *sih, uint32 xtal);
188 
189 uint8 si_pmu_pll28nm_calc_ndiv(uint32 fvco, uint32 xtal, uint32 *ndiv_int, uint32 *ndiv_frac);
190 
191 void si_pmu_armpll_freq_upd(si_t *sih, uint8 p1div, uint32 ndiv_int, uint32 ndiv_frac);
192 void si_pmu_bbpll_freq_upd(si_t *sih, uint8 p1div, uint32 ndiv_int, uint32 ndiv_frac);
193 void si_pmu_armpll_chmdiv_upd(si_t *sih, uint32 ch0_mdiv, uint32 ch1_mdiv);
194 
195 #ifdef BCM_LDO3P3_SOFTSTART
196 static int si_pmu_ldo3p3_soft_start_get(si_t *sih, osl_t *osh, uint32 bt_or_wl, int *res);
197 static int si_pmu_ldo3p3_soft_start_set(si_t *sih, osl_t *osh, uint32 bt_or_wl, uint32 slew_rate);
198 #endif /* BCM_LDO3P3_SOFTSTART */
199 #ifdef XTAL_BIAS_FROM_OTP
200 static void si_pmu_chipcontrol_xtal_bias_from_otp(si_t *sih, uint8* flag, uint8* val);
201 #ifndef BCM_OTP_API
202 static void si_pmu_chipcontrol_xtal_bias_cal_done_offsets(si_t *sih, uint16* wrd_offset,
203 		uint8* wrd_shift, uint8* wrd_mask);
204 static void si_pmu_chipcontrol_xtal_bias_val_offsets(si_t *sih, uint16* wrd_offset,
205 		uint8* wrd_shift, uint8* wrd_mask);
206 #endif /* !BCM_OTP_API */
207 #endif /* XTAL_BIAS_FROM_OTP */
208 
209 /* PMU timer ticks once in 32uS */
210 #define PMU_US_STEPS (32)
211 
212 void *g_si_pmutmr_lock_arg = NULL;
213 si_pmu_callback_t g_si_pmutmr_lock_cb = NULL, g_si_pmutmr_unlock_cb = NULL;
214 
215 /* FVCO frequency in [KHz] */
216 #define FVCO_640	640000  /**< 640MHz */
217 #define FVCO_880	880000	/**< 880MHz */
218 #define FVCO_1760	1760000	/**< 1760MHz */
219 #define FVCO_1440	1440000	/**< 1440MHz */
220 #define FVCO_960	960000	/**< 960MHz */
221 #define FVCO_960p1	960100  /**< 960.1MHz */
222 #define FVCO_960010	960010	/**< 960.0098MHz */
223 #define FVCO_961	961000	/**< 961MHz */
224 #define FVCO_960p5	960500	/**< 960.5MHz */
225 #define FVCO_963	963000	/**< 963MHz */
226 #define FVCO_963p01	963010  /**< 963.01MHz */
227 #define FVCO_1000	1000000	/**< 1000MHz */
228 #define FVCO_1600	1600000	/**< 1600MHz */
229 #define FVCO_1920	1920000	/**< 1920MHz */
230 #define FVCO_1938	1938000 /* 1938MHz */
231 #define FVCO_385	385000  /**< 385MHz */
232 #define FVCO_400	400000  /**< 400MHz */
233 #define FVCO_720	720000  /**< 720MHz */
234 #define FVCO_2880	2880000	/**< 2880 MHz */
235 #define FVCO_2946	2946000	/**< 2946 MHz */
236 #define FVCO_3000	3000000	/**< 3000 MHz */
237 #define FVCO_3200	3200000	/**< 3200 MHz */
238 #define FVCO_1002p8	1002823 /**< 1002.823MHz */
239 
240 /* defines to make the code more readable */
241 /* But 0 is a valid resource number! */
242 #define NO_SUCH_RESOURCE	0	/**< means: chip does not have such a PMU resource */
243 
244 /* uses these defines instead of 'magic' values when writing to register pllcontrol_addr */
245 #define PMU_PLL_CTRL_REG0	0
246 #define PMU_PLL_CTRL_REG1	1
247 #define PMU_PLL_CTRL_REG2	2
248 #define PMU_PLL_CTRL_REG3	3
249 #define PMU_PLL_CTRL_REG4	4
250 #define PMU_PLL_CTRL_REG5	5
251 #define PMU_PLL_CTRL_REG6	6
252 #define PMU_PLL_CTRL_REG7	7
253 #define PMU_PLL_CTRL_REG8	8
254 #define PMU_PLL_CTRL_REG9	9
255 #define PMU_PLL_CTRL_REG10	10
256 #define PMU_PLL_CTRL_REG11	11
257 #define PMU_PLL_CTRL_REG12	12
258 #define PMU_PLL_CTRL_REG13	13
259 #define PMU_PLL_CTRL_REG14	14
260 #define PMU_PLL_CTRL_REG15	15
261 
262 #ifndef BCM_OTP_API
263 #define OTP_XTAL_BIAS_CAL_DONE_4378_WRD_OFFSET 743
264 #define OTP_XTAL_BIAS_CAL_DONE_4378_WRD_SHIFT  8
265 #define OTP_XTAL_BIAS_CAL_DONE_4378_WRD_MASK   0x1
266 
267 #define OTP_XTAL_BIAS_VAL_4378_WRD_OFFSET 743
268 #define OTP_XTAL_BIAS_VAL_4378_WRD_SHIFT  0
269 #define OTP_XTAL_BIAS_VAL_4378_WRD_MASK   0xFF
270 #endif /* !BCM_OTP_API */
271 
272 /* changes the drive strength of gpio_12 and gpio_14 from 0x3 to 0x01 */
273 #define GPIO_DRIVE_4378_MASK	0x3Fu
274 #define GPIO_DRIVE_4378_VAL	0x09u
275 
276 /**
277  * The chip has one or more PLLs/FLLs (e.g. baseband PLL, USB PHY PLL). The settings of each PLL are
278  * contained within one or more 'PLL control' registers. Since the PLL hardware requires that
279  * changes for one PLL are committed at once, the PMU has a provision for 'updating' all PLL control
280  * registers at once.
281  *
282  * When software wants to change the any PLL parameters, it withdraws requests for that PLL clock,
283  * updates the PLL control registers being careful not to alter any control signals for the other
284  * PLLs, and then writes a 1 to PMUCtl.PllCtnlUpdate to commit the changes. Best usage model would
285  * be bring PLL down then update the PLL control register.
286  */
287 void
si_pmu_pllupd(si_t * sih)288 si_pmu_pllupd(si_t *sih)
289 {
290 	pmu_corereg(sih, SI_CC_IDX, pmucontrol,
291 	           PCTL_PLL_PLLCTL_UPD, PCTL_PLL_PLLCTL_UPD);
292 }
293 
294 /* 4360_OTP_PU is used for 4352, not a typo */
295 static rsc_per_chip_t rsc_4352 =  {NO_SUCH_RESOURCE,  NO_SUCH_RESOURCE,
296 		NO_SUCH_RESOURCE,  RES4360_OTP_PU, NO_SUCH_RESOURCE,
297 		NO_SUCH_RESOURCE, NO_SUCH_RESOURCE, NO_SUCH_RESOURCE};
298 static rsc_per_chip_t rsc_4360 =  {RES4360_HT_AVAIL,  NO_SUCH_RESOURCE,
299 		NO_SUCH_RESOURCE,  RES4360_OTP_PU, NO_SUCH_RESOURCE,
300 		NO_SUCH_RESOURCE, NO_SUCH_RESOURCE, NO_SUCH_RESOURCE};
301 static rsc_per_chip_t rsc_43602 = {RES43602_HT_AVAIL, RES43602_MACPHY_CLKAVAIL,
302 		RES43602_HT_START, NO_SUCH_RESOURCE, NO_SUCH_RESOURCE,
303 		NO_SUCH_RESOURCE, NO_SUCH_RESOURCE, NO_SUCH_RESOURCE};
304 static rsc_per_chip_t rsc_43012 = {RES43012_HT_AVAIL, RES43012_MACPHY_CLK_AVAIL,
305 		RES43012_HT_START, RES43012_OTP_PU, NO_SUCH_RESOURCE,
306 		NO_SUCH_RESOURCE, NO_SUCH_RESOURCE, NO_SUCH_RESOURCE};
307 /* As per the chip team OTP doesn't have the resource in 4369 */
308 static rsc_per_chip_t rsc_4369 = {RES4369_HT_AVAIL, RES4369_MACPHY_MAIN_CLK_AVAIL,
309 		RES4369_HT_AVAIL, NO_SUCH_RESOURCE, RES4369_MACPHY_AUX_CLK_AVAIL,
310 		NO_SUCH_RESOURCE, NO_SUCH_RESOURCE, RES4369_DIG_CORE_RDY};
311 static rsc_per_chip_t rsc_4378 = {RES4378_HT_AVAIL, RES4378_MACPHY_MAIN_CLK_AVAIL,
312 		RES4378_HT_AVAIL, RES4378_PMU_SLEEP, RES4378_MACPHY_AUX_CLK_AVAIL,
313 		NO_SUCH_RESOURCE, RES4378_CORE_RDY_CB, RES4378_CORE_RDY_DIG};
314 static rsc_per_chip_t rsc_4387 = {RES4387_HT_AVAIL, RES4387_MACPHY_CLK_MAIN,
315 		RES4387_HT_AVAIL, RES4387_PMU_SLEEP, RES4387_MACPHY_CLK_AUX,
316 		RES4387_MACPHY_CLK_SCAN, RES4387_CORE_RDY_CB, RES4387_CORE_RDY_DIG};
317 static rsc_per_chip_t rsc_4388 = {RES4388_HT_AVAIL, RES4388_MACPHY_CLK_MAIN,
318 		RES4388_HT_AVAIL, RES4388_PMU_LP, RES4388_MACPHY_CLK_AUX,
319 		RES4388_MACPHY_CLK_SCAN, RES4388_CORE_RDY_CB, RES4388_CORE_RDY_DIG};
320 static rsc_per_chip_t rsc_4389 = {RES4389_HT_AVAIL, RES4389_MACPHY_CLK_MAIN,
321 		RES4389_HT_AVAIL, RES4389_PMU_LP, RES4389_MACPHY_CLK_AUX,
322 		RES4389_MACPHY_CLK_SCAN, RES4389_CORE_RDY_CB, RES4389_CORE_RDY_DIG};
323 static rsc_per_chip_t rsc_4397 = {RES4397_HT_AVAIL, RES4397_MACPHY_CLK_MAIN,
324 		RES4397_HT_AVAIL, RES4397_PMU_LP, RES4397_MACPHY_CLK_AUX,
325 		RES4397_MACPHY_CLK_SCAN, RES4397_CORE_RDY_CB, RES4397_CORE_RDY_DIG};
326 
327 static rsc_per_chip_t rsc_4362 = {RES4362_HT_AVAIL, RES4362_MACPHY_MAIN_CLK_AVAIL,
328 		RES4362_HT_AVAIL, /* macphy aux clk */
329 		NO_SUCH_RESOURCE, NO_SUCH_RESOURCE, NO_SUCH_RESOURCE, NO_SUCH_RESOURCE,
330 		RES4362_DIG_CORE_RDY};
331 
332 /**
333 * For each chip, location of resource bits (e.g., ht bit) in resource mask registers may differ.
334 * This function abstracts the bit position of commonly used resources, thus making the rest of the
335 * code in hndpmu.c cleaner.
336 */
BCMRAMFN(si_pmu_get_rsc_positions)337 static rsc_per_chip_t* BCMRAMFN(si_pmu_get_rsc_positions)(si_t *sih)
338 {
339 	rsc_per_chip_t *rsc = NULL;
340 
341 	switch (CHIPID(sih->chip)) {
342 	case BCM4352_CHIP_ID:
343 	case BCM43526_CHIP_ID:	/* usb variant of 4352 */
344 		rsc = &rsc_4352;
345 		break;
346 	case BCM4360_CHIP_ID:
347 	case BCM43460_CHIP_ID:
348 		rsc = &rsc_4360;
349 		break;
350 	CASE_BCM43602_CHIP:
351 		rsc = &rsc_43602;
352 		break;
353 	case BCM43012_CHIP_ID:
354 	case BCM43013_CHIP_ID:
355 	case BCM43014_CHIP_ID:
356 		rsc = &rsc_43012;
357 		break;
358 	case BCM4369_CHIP_GRPID:
359 		rsc = &rsc_4369;
360 		break;
361 	case BCM4362_CHIP_GRPID:
362 		rsc = &rsc_4362;
363 		break;
364 	case BCM4376_CHIP_GRPID:
365 	case BCM4378_CHIP_GRPID:
366 		rsc = &rsc_4378;
367 		break;
368 	case BCM4385_CHIP_GRPID:
369 	case BCM4387_CHIP_GRPID:
370 		rsc = &rsc_4387;
371 		break;
372 	case BCM4388_CHIP_GRPID:
373 		rsc = &rsc_4388;
374 		break;
375 	case BCM4389_CHIP_GRPID:
376 		rsc = &rsc_4389;
377 		break;
378 	case BCM4397_CHIP_GRPID:
379 		rsc = &rsc_4397;
380 		break;
381 	default:
382 		ASSERT(0);
383 		break;
384 	}
385 
386 	return rsc;
387 }; /* si_pmu_get_rsc_positions */
388 
389 static const char BCMATTACHDATA(rstr_pllD)[] = "pll%d";
390 static const char BCMATTACHDATA(rstr_regD)[] = "reg%d";
391 static const char BCMATTACHDATA(rstr_chipcD)[] = "chipc%d";
392 static const char BCMATTACHDATA(rstr_rDt)[] = "r%dt";
393 static const char BCMATTACHDATA(rstr_rDd)[] = "r%dd";
394 static const char BCMATTACHDATA(rstr_Invalid_Unsupported_xtal_value_D)[] =
395 	"Invalid/Unsupported xtal value %d";
396 static const char BCMATTACHDATA(rstr_xtalfreq)[] = "xtalfreq";
397 #if defined(SAVERESTORE) && defined(LDO3P3_MIN_RES_MASK)
398 static const char BCMATTACHDATA(rstr_ldo_prot)[] = "ldo_prot";
399 #endif /* SAVERESTORE && LDO3P3_MIN_RES_MASK */
400 static const char BCMATTACHDATA(rstr_btldo3p3pu)[] = "btldopu";
401 #if defined(BCM_FASTLPO_PMU) && !defined(BCM_FASTLPO_PMU_DISABLED)
402 static const char BCMATTACHDATA(rstr_fastlpo_dis)[] = "fastlpo_dis";
403 #endif /* BCM_FASTLPO_PMU */
404 static const char BCMATTACHDATA(rstr_fastlpo_pcie_dis)[] = "fastlpo_pcie_dis";
405 static const char BCMATTACHDATA(rstr_memlpldo_volt)[] = "memlpldo_volt";
406 static const char BCMATTACHDATA(rstr_lpldo_volt)[] = "lpldo_volt";
407 static const char BCMATTACHDATA(rstr_dyn_clksw_en)[] = "dyn_clksw_en";
408 static const char BCMATTACHDATA(rstr_abuck_volt)[] = "abuck_volt";
409 static const char BCMATTACHDATA(rstr_cbuck_volt)[] = "cbuck_volt";
410 static const char BCMATTACHDATA(rstr_csrtune)[] = "csr_tune";
411 
412 /* The check for OTP parameters for the PLL control registers is done and if found the
413  * registers are updated accordingly.
414  */
415 
416 /**
417  * As a hardware bug workaround, OTP can contain variables in the form 'pll%d=%d'.
418  * If these variables are present, the corresponding PLL control register(s) are
419  * overwritten, but not yet 'updated'.
420  */
421 static void
BCMATTACHFN(si_pmu_otp_pllcontrol)422 BCMATTACHFN(si_pmu_otp_pllcontrol)(si_t *sih, osl_t *osh)
423 {
424 	char name[16];
425 	const char *otp_val;
426 	uint8 i;
427 	uint32 val;
428 	uint8 pll_ctrlcnt = 0;
429 
430 	if (FWSIGN_ENAB()) {
431 		return;
432 	}
433 
434 	if (PMUREV(sih->pmurev) >= 5) {
435 		pll_ctrlcnt = (sih->pmucaps & PCAP5_PC_MASK) >> PCAP5_PC_SHIFT;
436 	} else {
437 		pll_ctrlcnt = (sih->pmucaps & PCAP_PC_MASK) >> PCAP_PC_SHIFT;
438 	}
439 
440 	for (i = 0; i < pll_ctrlcnt; i++) {
441 		snprintf(name, sizeof(name), rstr_pllD, i);
442 		if ((otp_val = getvar(NULL, name)) == NULL)
443 			continue;
444 
445 		val = (uint32)bcm_strtoul(otp_val, NULL, 0);
446 		si_pmu_pllcontrol(sih, i, ~0, val);
447 	}
448 }
449 
450 /**
451  * The check for OTP parameters for the Voltage Regulator registers is done and if found the
452  * registers are updated accordingly.
453  */
454 static void
BCMATTACHFN(si_pmu_otp_vreg_control)455 BCMATTACHFN(si_pmu_otp_vreg_control)(si_t *sih, osl_t *osh)
456 {
457 	char name[16];
458 	const char *otp_val;
459 	uint8 i;
460 	uint32 val;
461 	uint8 vreg_ctrlcnt = 0;
462 
463 	if (FWSIGN_ENAB()) {
464 		return;
465 	}
466 
467 	if (PMUREV(sih->pmurev) >= 5) {
468 		vreg_ctrlcnt = (sih->pmucaps & PCAP5_VC_MASK) >> PCAP5_VC_SHIFT;
469 	} else {
470 		vreg_ctrlcnt = (sih->pmucaps & PCAP_VC_MASK) >> PCAP_VC_SHIFT;
471 	}
472 
473 	for (i = 0; i < vreg_ctrlcnt; i++) {
474 		snprintf(name, sizeof(name), rstr_regD, i);
475 		if ((otp_val = getvar(NULL, name)) == NULL)
476 			continue;
477 
478 		val = (uint32)bcm_strtoul(otp_val, NULL, 0);
479 		si_pmu_vreg_control(sih, i, ~0, val);
480 	}
481 }
482 
483 /**
484  * The check for OTP parameters for the chip control registers is done and if found the
485  * registers are updated accordingly.
486  */
487 static void
BCMATTACHFN(si_pmu_otp_chipcontrol)488 BCMATTACHFN(si_pmu_otp_chipcontrol)(si_t *sih, osl_t *osh)
489 {
490 	uint32 val, cc_ctrlcnt, i;
491 	char name[16];
492 	const char *otp_val;
493 
494 	if (FWSIGN_ENAB()) {
495 		return;
496 	}
497 	if (PMUREV(sih->pmurev) >= 5) {
498 		cc_ctrlcnt = (sih->pmucaps & PCAP5_CC_MASK) >> PCAP5_CC_SHIFT;
499 	} else {
500 		cc_ctrlcnt = (sih->pmucaps & PCAP_CC_MASK) >> PCAP_CC_SHIFT;
501 	}
502 
503 	for (i = 0; i < cc_ctrlcnt; i++) {
504 		snprintf(name, sizeof(name), rstr_chipcD, i);
505 		if ((otp_val = getvar(NULL, name)) == NULL)
506 			continue;
507 
508 		val = (uint32)bcm_strtoul(otp_val, NULL, 0);
509 		si_pmu_chipcontrol(sih, i, 0xFFFFFFFF, val); /* writes to PMU chipctrl reg 'i' */
510 	}
511 }
512 
513 /**
514  * A chip contains one or more LDOs (Low Drop Out regulators). During chip bringup, it can turn out
515  * that the default (POR) voltage of a regulator is not right or optimal.
516  * This function is called only by si_pmu_swreg_init() for specific chips
517  */
518 void
si_pmu_set_ldo_voltage(si_t * sih,osl_t * osh,uint8 ldo,uint8 voltage)519 si_pmu_set_ldo_voltage(si_t *sih, osl_t *osh, uint8 ldo, uint8 voltage)
520 {
521 	uint8 sr_cntl_shift = 0, rc_shift = 0, shift = 0, mask = 0;
522 	uint8 addr = 0;
523 	uint8 do_reg2 = 0, rshift2 = 0, rc_shift2 = 0, mask2 = 0, addr2 = 0;
524 
525 	BCM_REFERENCE(osh);
526 
527 	ASSERT(sih->cccaps & CC_CAP_PMU);
528 
529 	switch (CHIPID(sih->chip)) {
530 	case BCM4360_CHIP_ID:
531 	case BCM43460_CHIP_ID:
532 	case BCM4352_CHIP_ID:
533 	case BCM43526_CHIP_ID:
534 		switch (ldo) {
535 		case  SET_LDO_VOLTAGE_PAREF:
536 			addr = 1;
537 			rc_shift = 0;
538 			mask = 0xf;
539 			break;
540 		default:
541 			ASSERT(FALSE);
542 			break;
543 		}
544 		break;
545 	CASE_BCM43602_CHIP:
546 		switch (ldo) {
547 		case  SET_LDO_VOLTAGE_PAREF:
548 			addr = 0;
549 			rc_shift = 29;
550 			mask = 0x7;
551 			do_reg2 = 1;
552 			addr2 = 1;
553 			rshift2 = 3;
554 			mask2 = 0x8;
555 			break;
556 		default:
557 			ASSERT(FALSE);
558 			break;
559 		}
560 		break;
561 	default:
562 		ASSERT(FALSE);
563 		return;
564 	}
565 
566 	shift = sr_cntl_shift + rc_shift;
567 
568 	pmu_corereg(sih, SI_CC_IDX, regcontrol_addr, /* PMU VREG register */
569 		~0, addr);
570 	pmu_corereg(sih, SI_CC_IDX, regcontrol_data,
571 		mask << shift, (voltage & mask) << shift);
572 	if (do_reg2) {
573 		/* rshift2 - right shift moves mask2 to bit 0, rc_shift2 - left shift in reg */
574 		si_pmu_vreg_control(sih, addr2, (mask2 >> rshift2) << rc_shift2,
575 			((voltage & mask2) >> rshift2) << rc_shift2);
576 	}
577 } /* si_pmu_set_ldo_voltage */
578 
579 /* d11 slow to fast clock transition time in slow clock cycles */
580 #define D11SCC_SLOW2FAST_TRANSITION	2
581 
582 /* For legacy chips only, will be discarded eventually */
583 static uint16
BCMINITFN(si_pmu_fast_pwrup_delay_legacy)584 BCMINITFN(si_pmu_fast_pwrup_delay_legacy)(si_t *sih, osl_t *osh, pmuregs_t *pmu)
585 {
586 	uint pmudelay = PMU_MAX_TRANSITION_DLY;
587 	uint32 ilp;			/* ILP clock frequency in [Hz] */
588 	rsc_per_chip_t *rsc;		/* chip specific resource bit positions */
589 
590 	/* Should be calculated based on the PMU updown/depend tables */
591 	switch (CHIPID(sih->chip)) {
592 	case BCM43460_CHIP_ID:
593 	case BCM43526_CHIP_ID:
594 		pmudelay = 3700;
595 		break;
596 	case BCM4360_CHIP_ID:
597 	case BCM4352_CHIP_ID:
598 		if (CHIPREV(sih->chiprev) < 4) {
599 			pmudelay = 1500;
600 		} else {
601 			pmudelay = 3000;
602 		}
603 		break;
604 	case BCM43012_CHIP_ID:
605 	case BCM43013_CHIP_ID:
606 	case BCM43014_CHIP_ID:
607 		pmudelay = 1500; /* In micro seconds for 43012 chip */
608 		break;
609 	CASE_BCM43602_CHIP:
610 		rsc = si_pmu_get_rsc_positions(sih);
611 		/* Retrieve time by reading it out of the hardware */
612 		ilp = si_ilp_clock(sih);
613 		if (ilp != 0) {
614 			pmudelay = (si_pmu_res_uptime(sih, osh, pmu, rsc->macphy_clkavail, FALSE) +
615 				D11SCC_SLOW2FAST_TRANSITION) * ((1000000 + ilp - 1) / ilp);
616 			pmudelay = (11 * pmudelay) / 10;
617 		}
618 		break;
619 	case BCM4362_CHIP_GRPID:
620 		rsc = si_pmu_get_rsc_positions(sih);
621 		/* Retrieve time by reading it out of the hardware */
622 		ilp = si_ilp_clock(sih);
623 		if (ilp != 0) {
624 			pmudelay = si_pmu_res_uptime(sih, osh, pmu, rsc->ht_avail, FALSE) +
625 				D11SCC_SLOW2FAST_TRANSITION;
626 			pmudelay = (11 * pmudelay) / 10;
627 			/* With PWR SW optimization, Need to add this addtional
628 			time to fast power up delay to avoid beacon loss
629 			*/
630 			pmudelay += 600;
631 		}
632 		break;
633 	default:
634 		break;
635 	}
636 
637 	return (uint16)pmudelay;
638 } /* si_pmu_fast_pwrup_delay_legacy */
639 
640 /**
641  * d11 core has a 'fastpwrup_dly' register that must be written to.
642  * This function returns d11 slow to fast clock transition time in [us] units.
643  * It does not write to the d11 core.
644  */
645 uint16
BCMINITFN(si_pmu_fast_pwrup_delay)646 BCMINITFN(si_pmu_fast_pwrup_delay)(si_t *sih, osl_t *osh)
647 {
648 	uint pmudelay = PMU_MAX_TRANSITION_DLY;
649 	pmuregs_t *pmu;
650 	uint origidx;
651 	rsc_per_chip_t *rsc;		/* chip specific resource bit positions */
652 	uint macunit;
653 	bool pmu_fast_trans_en;
654 
655 	ASSERT(sih->cccaps & CC_CAP_PMU);
656 
657 	if (ISSIM_ENAB(sih)) {
658 		pmudelay = 1000;
659 		goto exit;
660 	}
661 
662 	macunit = si_coreunit(sih);
663 
664 	origidx = si_coreidx(sih);
665 	/* Still support 43602 so need AOB check,
666 	 * 43602 is the only non-AOB chip supported now
667 	 */
668 	if (AOB_ENAB(sih)) {
669 		pmu = si_setcore(sih, PMU_CORE_ID, 0);
670 	} else {
671 		pmu = si_setcoreidx(sih, SI_CC_IDX);
672 	}
673 	ASSERT(pmu != NULL);
674 
675 	pmu_fast_trans_en = (R_REG(osh, &pmu->pmucontrol_ext) & PCTL_EXT_FAST_TRANS_ENAB) ?
676 		TRUE : FALSE;
677 
678 	rsc = si_pmu_get_rsc_positions(sih);
679 
680 	switch (CHIPID(sih->chip)) {
681 	case BCM4369_CHIP_GRPID:
682 	case BCM4376_CHIP_GRPID:
683 	case BCM4378_CHIP_GRPID:
684 	case BCM4385_CHIP_GRPID:
685 		if (macunit == 0) {
686 			pmudelay = si_pmu_res_uptime(sih, osh, pmu,
687 				rsc->macphy_clkavail, pmu_fast_trans_en);
688 		} else if (macunit == 1) {
689 			pmudelay = si_pmu_res_uptime(sih, osh, pmu,
690 				rsc->macphy_aux_clkavail, pmu_fast_trans_en);
691 		} else {
692 			ASSERT(0);
693 		}
694 		break;
695 	case BCM4387_CHIP_GRPID:
696 	case BCM4388_CHIP_GRPID:
697 	case BCM4389_CHIP_GRPID:
698 	case BCM4397_CHIP_GRPID:
699 		if (macunit == 0) {
700 			pmudelay = si_pmu_res_uptime(sih, osh, pmu,
701 				rsc->macphy_clkavail, pmu_fast_trans_en);
702 		} else if (macunit == 1) {
703 			pmudelay = si_pmu_res_uptime(sih, osh, pmu,
704 				rsc->macphy_aux_clkavail, pmu_fast_trans_en);
705 		} else if (macunit == 2) {
706 			pmudelay = si_pmu_res_uptime(sih, osh, pmu,
707 				rsc->macphy_scan_clkavail, pmu_fast_trans_en);
708 		} else {
709 			ASSERT(0);
710 		}
711 		break;
712 
713 	default:
714 		pmudelay = si_pmu_fast_pwrup_delay_legacy(sih, osh, pmu);
715 		break;
716 	}
717 
718 	/* Return to original core */
719 	si_setcoreidx(sih, origidx);
720 
721 exit:
722 	return (uint16)pmudelay;
723 } /* si_pmu_fast_pwrup_delay */
724 
725 /*
726  * Get fast pwrup delay for given resource
727  */
728 static uint
BCMINITFN(si_pmu_fast_pwrup_delay_rsrc)729 BCMINITFN(si_pmu_fast_pwrup_delay_rsrc)(si_t *sih, osl_t *osh, uint8 rsrc)
730 {
731 	uint pmudelay = PMU_MAX_TRANSITION_DLY;
732 	pmuregs_t *pmu = NULL;
733 	bool pmu_fast_trans_en = TRUE;
734 	uint origidx;
735 
736 	origidx = si_coreidx(sih);
737 	pmu = si_setcore(sih, PMU_CORE_ID, 0);
738 	ASSERT(pmu != NULL);
739 
740 	pmu_fast_trans_en = (R_REG(osh, &pmu->pmucontrol_ext) & PCTL_EXT_FAST_TRANS_ENAB) ?
741 		TRUE : FALSE;
742 
743 	pmudelay = si_pmu_res_uptime(sih, osh, pmu, rsrc, pmu_fast_trans_en);
744 
745 	/* Return to original core */
746 	si_setcoreidx(sih, origidx);
747 
748 	return pmudelay;
749 }
750 
751 /*
752  * Get fast pwrup delay for given DIG_READY resource
753  */
754 uint
BCMINITFN(si_pmu_fast_pwrup_delay_dig)755 BCMINITFN(si_pmu_fast_pwrup_delay_dig)(si_t *sih, osl_t *osh)
756 {
757 	uint delay = 0;
758 	rsc_per_chip_t *rsc = si_pmu_get_rsc_positions(sih);
759 	ASSERT(rsc);
760 
761 	if (rsc) {
762 		delay = si_pmu_fast_pwrup_delay_rsrc(sih, osh, rsc->dig_ready);
763 	}
764 	return delay;
765 }
766 
767 /*
768  * During chip bringup, it can turn out that the 'hard wired' PMU dependencies are not fully
769  * correct, or that up/down time values can be optimized. The following data structures and arrays
770  * deal with that.
771  */
772 
773 /* Setup resource up/down timers */
774 typedef struct {
775 	uint8 resnum;
776 	uint32 updown;
777 } pmu_res_updown_t;
778 
779 #define PMU_RES_SUBSTATE_SHIFT		8
780 
781 /* Setup resource substate transition timer value */
782 typedef struct {
783 	uint8 resnum;
784 	uint8 substate;
785 	uint32 tmr;
786 } pmu_res_subst_trans_tmr_t;
787 
788 /* Change resource dependencies masks */
789 typedef struct {
790 	uint32 res_mask;		/* resources (chip specific) */
791 	int8 action;			/* action, e.g. RES_DEPEND_SET */
792 	uint32 depend_mask;		/* changes to the dependencies mask */
793 	bool (*filter)(si_t *sih);	/* action is taken when filter is NULL or return TRUE */
794 } pmu_res_depend_t;
795 
796 /* Resource dependencies mask change action */
797 #define RES_DEPEND_SET		0	/* Override the dependencies mask */
798 #define RES_DEPEND_ADD		1	/* Add to the  dependencies mask */
799 #define RES_DEPEND_REMOVE	-1	/* Remove from the dependencies mask */
800 
801 /* Using a safe SAVE_RESTORE up/down time, it will get updated after openloop cal */
802 static const pmu_res_updown_t BCMATTACHDATA(bcm43012a0_res_updown_ds0)[] = {
803 	{RES43012_MEMLPLDO_PU,		0x00200020},
804 	{RES43012_PMU_SLEEP,		0x00a600a6},
805 	{RES43012_FAST_LPO,		0x00D20000},
806 	{RES43012_BTLPO_3P3,		0x007D0000},
807 	{RES43012_SR_POK,		0x00c80000},
808 	{RES43012_DUMMY_PWRSW,		0x01400000},
809 	{RES43012_DUMMY_LDO3P3,		0x00000000},
810 	{RES43012_DUMMY_BT_LDO3P3,	0x00000000},
811 	{RES43012_DUMMY_RADIO,		0x00000000},
812 	{RES43012_VDDB_VDDRET,		0x0020000a},
813 	{RES43012_HV_LDO3P3,		0x002C0000},
814 	{RES43012_XTAL_PU,		0x04000000},
815 	{RES43012_SR_CLK_START,		0x00080000},
816 	{RES43012_XTAL_STABLE,		0x00000000},
817 	{RES43012_FCBS,			0x00000000},
818 	{RES43012_CBUCK_MODE,		0x00000000},
819 	{RES43012_CORE_READY,		0x00000000},
820 	{RES43012_ILP_REQ,		0x00000000},
821 	{RES43012_ALP_AVAIL,		0x00280008},
822 	{RES43012_RADIOLDO_1P8,		0x00220000},
823 	{RES43012_MINI_PMU,		0x00220000},
824 	{RES43012_SR_SAVE_RESTORE,	0x02600260},
825 	{RES43012_PHY_PWRSW,		0x00800005},
826 	{RES43012_VDDB_CLDO,		0x0020000a},
827 	{RES43012_SUBCORE_PWRSW,	0x0060000a},
828 	{RES43012_SR_SLEEP,		0x00000000},
829 	{RES43012_HT_START,		0x00A00000},
830 	{RES43012_HT_AVAIL,		0x00000000},
831 	{RES43012_MACPHY_CLK_AVAIL,	0x00000000},
832 };
833 
834 static const pmu_res_updown_t BCMATTACHDATA(bcm4360_res_updown)[] = {
835 	{RES4360_BBPLLPWRSW_PU,		0x00200001}
836 };
837 
838 static const pmu_res_updown_t BCMATTACHDATA(bcm43602_res_updown)[] = {
839 	{RES43602_SR_SAVE_RESTORE,	0x00190019},
840 	{RES43602_XTAL_PU,		0x00280002},
841 	{RES43602_RFLDO_PU,		0x00430005}
842 };
843 
844 static pmu_res_depend_t BCMATTACHDATA(bcm43012a0_res_depend_ds0)[] = {
845 	{0, 0, 0, NULL}
846 };
847 
848 static pmu_res_depend_t BCMATTACHDATA(bcm43602_res_depend)[] = {
849 	/* JIRA HW43602-131 : PCIe SERDES dependency problem */
850 	{
851 		PMURES_BIT(RES43602_SR_SUBCORE_PWRSW) | PMURES_BIT(RES43602_SR_CLK_STABLE) |
852 		PMURES_BIT(RES43602_SR_SAVE_RESTORE)  | PMURES_BIT(RES43602_SR_SLEEP) |
853 		PMURES_BIT(RES43602_LQ_START) | PMURES_BIT(RES43602_LQ_AVAIL) |
854 		PMURES_BIT(RES43602_WL_CORE_RDY) | PMURES_BIT(RES43602_ILP_REQ) |
855 		PMURES_BIT(RES43602_ALP_AVAIL) | PMURES_BIT(RES43602_RFLDO_PU) |
856 		PMURES_BIT(RES43602_HT_START) | PMURES_BIT(RES43602_HT_AVAIL) |
857 		PMURES_BIT(RES43602_MACPHY_CLKAVAIL),
858 		RES_DEPEND_ADD,
859 		PMURES_BIT(RES43602_SERDES_PU),
860 		NULL
861 	},
862 	/* set rsrc  7, 8, 9, 12, 13, 14 & 17 add (1<<10 | 1<<4 )] */
863 	{
864 		PMURES_BIT(RES43602_SR_CLK_START) | PMURES_BIT(RES43602_SR_PHY_PWRSW) |
865 		PMURES_BIT(RES43602_SR_SUBCORE_PWRSW) | PMURES_BIT(RES43602_SR_CLK_STABLE) |
866 		PMURES_BIT(RES43602_SR_SAVE_RESTORE) | PMURES_BIT(RES43602_SR_SLEEP) |
867 		PMURES_BIT(RES43602_WL_CORE_RDY),
868 		RES_DEPEND_ADD,
869 		PMURES_BIT(RES43602_XTALLDO_PU) | PMURES_BIT(RES43602_XTAL_PU),
870 		NULL
871 	},
872 	/* set rsrc 11 add (1<<13 | 1<<12 | 1<<9 | 1<<8 | 1<<7 )] */
873 	{
874 		PMURES_BIT(RES43602_PERST_OVR),
875 		RES_DEPEND_ADD,
876 		PMURES_BIT(RES43602_SR_CLK_START) | PMURES_BIT(RES43602_SR_PHY_PWRSW) |
877 		PMURES_BIT(RES43602_SR_SUBCORE_PWRSW) | PMURES_BIT(RES43602_SR_CLK_STABLE) |
878 		PMURES_BIT(RES43602_SR_SAVE_RESTORE),
879 		NULL
880 	},
881 	/* set rsrc 19, 21, 22, 23 & 24 remove ~(1<<16 | 1<<15 )] */
882 	{
883 		PMURES_BIT(RES43602_ALP_AVAIL) | PMURES_BIT(RES43602_RFLDO_PU) |
884 		PMURES_BIT(RES43602_HT_START) | PMURES_BIT(RES43602_HT_AVAIL) |
885 		PMURES_BIT(RES43602_MACPHY_CLKAVAIL),
886 		RES_DEPEND_REMOVE,
887 		PMURES_BIT(RES43602_LQ_START) | PMURES_BIT(RES43602_LQ_AVAIL),
888 		NULL
889 	}
890 };
891 
892 #ifndef BCM_BOOTLOADER
893 /** switch off LPLDO for 12x12 package because it can cause a problem when chip is reset */
894 static const pmu_res_depend_t BCMATTACHDATA(bcm43602_12x12_res_depend)[] = {
895 	/* set rsrc 19, 21, 22, 23 & 24 remove ~(1<<16 | 1<<15 )] */
896 	{	/* resources no longer dependent on resource that is going to be removed */
897 		PMURES_BIT(RES43602_LPLDO_PU)        | PMURES_BIT(RES43602_REGULATOR)        |
898 		PMURES_BIT(RES43602_PMU_SLEEP)       | PMURES_BIT(RES43602_RSVD_3)           |
899 		PMURES_BIT(RES43602_XTALLDO_PU)      | PMURES_BIT(RES43602_SERDES_PU)        |
900 		PMURES_BIT(RES43602_BBPLL_PWRSW_PU)  | PMURES_BIT(RES43602_SR_CLK_START)     |
901 		PMURES_BIT(RES43602_SR_PHY_PWRSW)    | PMURES_BIT(RES43602_SR_SUBCORE_PWRSW) |
902 		PMURES_BIT(RES43602_XTAL_PU)         | PMURES_BIT(RES43602_PERST_OVR)        |
903 		PMURES_BIT(RES43602_SR_CLK_STABLE)   | PMURES_BIT(RES43602_SR_SAVE_RESTORE)  |
904 		PMURES_BIT(RES43602_SR_SLEEP)        | PMURES_BIT(RES43602_LQ_START)         |
905 		PMURES_BIT(RES43602_LQ_AVAIL)        | PMURES_BIT(RES43602_WL_CORE_RDY)      |
906 		PMURES_BIT(RES43602_ILP_REQ)         | PMURES_BIT(RES43602_ALP_AVAIL)        |
907 		PMURES_BIT(RES43602_RADIO_PU)        | PMURES_BIT(RES43602_RFLDO_PU)         |
908 		PMURES_BIT(RES43602_HT_START)        | PMURES_BIT(RES43602_HT_AVAIL)         |
909 		PMURES_BIT(RES43602_MACPHY_CLKAVAIL) | PMURES_BIT(RES43602_PARLDO_PU)        |
910 		PMURES_BIT(RES43602_RSVD_26),
911 		RES_DEPEND_REMOVE,
912 		/* resource that is going to be removed */
913 		PMURES_BIT(RES43602_LPLDO_PU),
914 		NULL
915 	}
916 };
917 
918 static const pmu_res_depend_t BCMATTACHDATA(bcm43602_res_pciewar)[] = {
919 	{
920 		PMURES_BIT(RES43602_PERST_OVR),
921 		RES_DEPEND_ADD,
922 		PMURES_BIT(RES43602_REGULATOR) |
923 		PMURES_BIT(RES43602_PMU_SLEEP) |
924 		PMURES_BIT(RES43602_XTALLDO_PU) |
925 		PMURES_BIT(RES43602_XTAL_PU) |
926 		PMURES_BIT(RES43602_RADIO_PU),
927 		NULL
928 	},
929 	{
930 		PMURES_BIT(RES43602_WL_CORE_RDY),
931 		RES_DEPEND_ADD,
932 		PMURES_BIT(RES43602_PERST_OVR),
933 		NULL
934 	},
935 	{
936 		PMURES_BIT(RES43602_LQ_START),
937 		RES_DEPEND_ADD,
938 		PMURES_BIT(RES43602_PERST_OVR),
939 		NULL
940 	},
941 	{
942 		PMURES_BIT(RES43602_LQ_AVAIL),
943 		RES_DEPEND_ADD,
944 		PMURES_BIT(RES43602_PERST_OVR),
945 		NULL
946 	},
947 	{
948 		PMURES_BIT(RES43602_ALP_AVAIL),
949 		RES_DEPEND_ADD,
950 		PMURES_BIT(RES43602_PERST_OVR),
951 		NULL
952 	},
953 	{
954 		PMURES_BIT(RES43602_HT_START),
955 		RES_DEPEND_ADD,
956 		PMURES_BIT(RES43602_PERST_OVR),
957 		NULL
958 	},
959 	{
960 		PMURES_BIT(RES43602_HT_AVAIL),
961 		RES_DEPEND_ADD,
962 		PMURES_BIT(RES43602_PERST_OVR),
963 		NULL
964 	},
965 	{
966 		PMURES_BIT(RES43602_MACPHY_CLKAVAIL),
967 		RES_DEPEND_ADD,
968 		PMURES_BIT(RES43602_PERST_OVR),
969 		NULL
970 	}
971 };
972 #endif /* BCM_BOOTLOADER */
973 
974 static const pmu_res_updown_t BCMATTACHDATA(bcm4360B1_res_updown)[] = {
975 	/* Need to change elements here, should get default values for this - 4360B1 */
976 	{RES4360_XTAL_PU,               0x00430002}, /* Changed for 4360B1 */
977 };
978 
979 static pmu_res_depend_t BCMATTACHDATA(bcm4369a0_res_depend)[] = {
980 	{PMURES_BIT(RES4369_DUMMY),			RES_DEPEND_SET, 0x00000000, NULL},
981 	{PMURES_BIT(RES4369_ABUCK),			RES_DEPEND_SET, 0x00000005, NULL},
982 	{PMURES_BIT(RES4369_PMU_SLEEP),			RES_DEPEND_SET, 0x00000001, NULL},
983 	{PMURES_BIT(RES4369_MISCLDO),			RES_DEPEND_SET, 0x00000007, NULL},
984 	{PMURES_BIT(RES4369_LDO3P3),			RES_DEPEND_SET, 0x00000001, NULL},
985 	{PMURES_BIT(RES4369_FAST_LPO_AVAIL),		RES_DEPEND_SET, 0x00000005, NULL},
986 	{PMURES_BIT(RES4369_XTAL_PU),			RES_DEPEND_SET, 0x00000007, NULL},
987 	{PMURES_BIT(RES4369_XTAL_STABLE),		RES_DEPEND_SET, 0x00000047, NULL},
988 	{PMURES_BIT(RES4369_PWRSW_DIG),			RES_DEPEND_SET, 0x060000cf, NULL},
989 	{PMURES_BIT(RES4369_SR_DIG),			RES_DEPEND_SET, 0x060001cf, NULL},
990 	{PMURES_BIT(RES4369_SLEEP_DIG),			RES_DEPEND_SET, 0x060003cf, NULL},
991 	{PMURES_BIT(RES4369_PWRSW_AUX),			RES_DEPEND_SET, 0x040000cf, NULL},
992 	{PMURES_BIT(RES4369_SR_AUX),			RES_DEPEND_SET, 0x040008cf, NULL},
993 	{PMURES_BIT(RES4369_SLEEP_AUX),			RES_DEPEND_SET, 0x040018cf, NULL},
994 	{PMURES_BIT(RES4369_PWRSW_MAIN),		RES_DEPEND_SET, 0x040000cf, NULL},
995 	{PMURES_BIT(RES4369_SR_MAIN),			RES_DEPEND_SET, 0x040040cf, NULL},
996 	{PMURES_BIT(RES4369_SLEEP_MAIN),		RES_DEPEND_SET, 0x0400c0cf, NULL},
997 	{PMURES_BIT(RES4369_DIG_CORE_RDY),		RES_DEPEND_SET, 0x060007cf, NULL},
998 	{PMURES_BIT(RES4369_CORE_RDY_AUX),		RES_DEPEND_SET, 0x040038cf, NULL},
999 	{PMURES_BIT(RES4369_ALP_AVAIL),			RES_DEPEND_SET, 0x060207cf, NULL},
1000 	{PMURES_BIT(RES4369_RADIO_AUX_PU),		RES_DEPEND_SET, 0x040438df, NULL},
1001 	{PMURES_BIT(RES4369_MINIPMU_AUX_PU),		RES_DEPEND_SET, 0x041438df, NULL},
1002 	{PMURES_BIT(RES4369_CORE_RDY_MAIN),		RES_DEPEND_SET, 0x0401c0cf, NULL},
1003 	{PMURES_BIT(RES4369_RADIO_MAIN_PU),		RES_DEPEND_SET, 0x0441c0df, NULL},
1004 	{PMURES_BIT(RES4369_MINIPMU_MAIN_PU),		RES_DEPEND_SET, 0x04c1c0df, NULL},
1005 	{PMURES_BIT(RES4369_PCIE_EP_PU),		RES_DEPEND_SET, 0x040000cf, NULL},
1006 	{PMURES_BIT(RES4369_COLD_START_WAIT),		RES_DEPEND_SET, 0x0000000f, NULL},
1007 	{PMURES_BIT(RES4369_ARMHTAVAIL),		RES_DEPEND_SET, 0x060a07cf, NULL},
1008 	{PMURES_BIT(RES4369_HT_AVAIL),			RES_DEPEND_SET, 0x060a07cf, NULL},
1009 	{PMURES_BIT(RES4369_MACPHY_AUX_CLK_AVAIL),	RES_DEPEND_SET, 0x163e3fdf, NULL},
1010 	{PMURES_BIT(RES4369_MACPHY_MAIN_CLK_AVAIL),	RES_DEPEND_SET, 0x17cbc7df, NULL},
1011 };
1012 
1013 static pmu_res_depend_t BCMATTACHDATA(bcm4369a0_res_depend_fastlpo_pcie)[] = {
1014 	{PMURES_BIT(RES4369_DUMMY),			RES_DEPEND_SET, 0x00000000, NULL},
1015 	{PMURES_BIT(RES4369_ABUCK),			RES_DEPEND_SET, 0x00000005, NULL},
1016 	{PMURES_BIT(RES4369_PMU_SLEEP),			RES_DEPEND_SET, 0x00000001, NULL},
1017 	{PMURES_BIT(RES4369_MISCLDO),			RES_DEPEND_SET, 0x00000007, NULL},
1018 	{PMURES_BIT(RES4369_LDO3P3),			RES_DEPEND_SET, 0x00000001, NULL},
1019 	{PMURES_BIT(RES4369_FAST_LPO_AVAIL),		RES_DEPEND_SET, 0x00000005, NULL},
1020 	{PMURES_BIT(RES4369_XTAL_PU),			RES_DEPEND_SET, 0x00000007, NULL},
1021 	{PMURES_BIT(RES4369_XTAL_STABLE),		RES_DEPEND_SET, 0x00000047, NULL},
1022 	{PMURES_BIT(RES4369_PWRSW_DIG),                 RES_DEPEND_SET, 0x060000ef, NULL},
1023 	{PMURES_BIT(RES4369_SR_DIG),                    RES_DEPEND_SET, 0x060001ef, NULL},
1024 	{PMURES_BIT(RES4369_SLEEP_DIG),                 RES_DEPEND_SET, 0x060003ef, NULL},
1025 	{PMURES_BIT(RES4369_PWRSW_AUX),                 RES_DEPEND_SET, 0x040000ef, NULL},
1026 	{PMURES_BIT(RES4369_SR_AUX),                    RES_DEPEND_SET, 0x040008ef, NULL},
1027 	{PMURES_BIT(RES4369_SLEEP_AUX),                 RES_DEPEND_SET, 0x040018ef, NULL},
1028 	{PMURES_BIT(RES4369_PWRSW_MAIN),                RES_DEPEND_SET, 0x040000ef, NULL},
1029 	{PMURES_BIT(RES4369_SR_MAIN),                   RES_DEPEND_SET, 0x040040ef, NULL},
1030 	{PMURES_BIT(RES4369_SLEEP_MAIN),                RES_DEPEND_SET, 0x0400c0ef, NULL},
1031 	{PMURES_BIT(RES4369_DIG_CORE_RDY),              RES_DEPEND_SET, 0x060007ef, NULL},
1032 	{PMURES_BIT(RES4369_CORE_RDY_AUX),              RES_DEPEND_SET, 0x040038ef, NULL},
1033 	{PMURES_BIT(RES4369_ALP_AVAIL),                 RES_DEPEND_SET, 0x060207ef, NULL},
1034 	{PMURES_BIT(RES4369_RADIO_AUX_PU),              RES_DEPEND_SET, 0x040438ff, NULL},
1035 	{PMURES_BIT(RES4369_MINIPMU_AUX_PU),            RES_DEPEND_SET, 0x041438ff, NULL},
1036 	{PMURES_BIT(RES4369_CORE_RDY_MAIN),             RES_DEPEND_SET, 0x0401c0ef, NULL},
1037 	{PMURES_BIT(RES4369_RADIO_MAIN_PU),             RES_DEPEND_SET, 0x0441c0ff, NULL},
1038 	{PMURES_BIT(RES4369_MINIPMU_MAIN_PU),           RES_DEPEND_SET, 0x04c1c0ff, NULL},
1039 	{PMURES_BIT(RES4369_PCIE_EP_PU),                RES_DEPEND_SET, 0x0400002f, NULL},
1040 	{PMURES_BIT(RES4369_COLD_START_WAIT),           RES_DEPEND_SET, 0x0000002f, NULL},
1041 	{PMURES_BIT(RES4369_ARMHTAVAIL),                RES_DEPEND_SET, 0x060a07ef, NULL},
1042 	{PMURES_BIT(RES4369_HT_AVAIL),                  RES_DEPEND_SET, 0x060a07ef, NULL},
1043 	{PMURES_BIT(RES4369_MACPHY_AUX_CLK_AVAIL),      RES_DEPEND_SET, 0x163e3fff, NULL},
1044 	{PMURES_BIT(RES4369_MACPHY_MAIN_CLK_AVAIL),     RES_DEPEND_SET, 0x17cbc7ff, NULL},
1045 };
1046 
1047 static const pmu_res_updown_t BCMATTACHDATA(bcm4369a0_res_updown)[] = {
1048 	{RES4369_DUMMY,                 0x00220022},
1049 	{RES4369_ABUCK,                 0x00c80022},
1050 	{RES4369_PMU_SLEEP,             0x00c80022},
1051 	{RES4369_MISCLDO,               0x00bd0022},
1052 	{RES4369_LDO3P3,                0x00bd0022},
1053 	{RES4369_FAST_LPO_AVAIL,        0x01500022},
1054 	{RES4369_XTAL_PU,               0x07d00022},
1055 	{RES4369_XTAL_STABLE,           0x00220022},
1056 	{RES4369_PWRSW_DIG,             0x02100087},
1057 	{RES4369_SR_DIG,                0x02000200},
1058 	{RES4369_SLEEP_DIG,             0x00220022},
1059 	{RES4369_PWRSW_AUX,             0x03900087},
1060 	{RES4369_SR_AUX,                0x01cc01cc},
1061 	{RES4369_SLEEP_AUX,             0x00220022},
1062 	{RES4369_PWRSW_MAIN,            0x03900087},
1063 	{RES4369_SR_MAIN,               0x02000200},
1064 	{RES4369_SLEEP_MAIN,            0x00220022},
1065 	{RES4369_DIG_CORE_RDY,          0x00220044},
1066 	{RES4369_CORE_RDY_AUX,          0x00220044},
1067 	{RES4369_ALP_AVAIL,             0x00220044},
1068 	{RES4369_RADIO_AUX_PU,          0x006e0022},
1069 	{RES4369_MINIPMU_AUX_PU,        0x00460022},
1070 	{RES4369_CORE_RDY_MAIN,         0x00220022},
1071 	{RES4369_RADIO_MAIN_PU,         0x006e0022},
1072 	{RES4369_MINIPMU_MAIN_PU,       0x00460022},
1073 	{RES4369_PCIE_EP_PU,            0x02100087},
1074 	{RES4369_COLD_START_WAIT,       0x00220022},
1075 	{RES4369_ARMHTAVAIL,            0x00a80022},
1076 	{RES4369_HT_AVAIL,              RES4369_HTAVAIL_VAL},
1077 	{RES4369_MACPHY_AUX_CLK_AVAIL,  0x00640022},
1078 	{RES4369_MACPHY_MAIN_CLK_AVAIL, 0x00640022},
1079 };
1080 
1081 static const pmu_res_updown_t BCMATTACHDATA(bcm4369a0_res_updown_fastlpo_pmu)[] = {
1082 	{RES4369_DUMMY,                 0x00220022},
1083 	{RES4369_ABUCK,                 0x00c80022},
1084 	{RES4369_PMU_SLEEP,             0x00c80022},
1085 	{RES4369_MISCLDO,               0x00bd0022},
1086 	{RES4369_LDO3P3,                0x00bd0022},
1087 	{RES4369_FAST_LPO_AVAIL,        0x01500022},
1088 	{RES4369_XTAL_PU,               0x07d00022},
1089 	{RES4369_XTAL_STABLE,           0x00220022},
1090 	{RES4369_PWRSW_DIG,             0x02100087},
1091 	{RES4369_SR_DIG,                0x02000200},
1092 	{RES4369_SLEEP_DIG,             0x00220022},
1093 	{RES4369_PWRSW_AUX,             0x03900087},
1094 	{RES4369_SR_AUX,                0x01cc01cc},
1095 	{RES4369_SLEEP_AUX,             0x00220022},
1096 	{RES4369_PWRSW_MAIN,            0x03900087},
1097 	{RES4369_SR_MAIN,               0x02000200},
1098 	{RES4369_SLEEP_MAIN,            0x00220022},
1099 	{RES4369_DIG_CORE_RDY,          0x00220044},
1100 	{RES4369_CORE_RDY_AUX,          0x00220044},
1101 	{RES4369_ALP_AVAIL,             0x00220044},
1102 	{RES4369_RADIO_AUX_PU,          0x006e0022},
1103 	{RES4369_MINIPMU_AUX_PU,        0x00460022},
1104 	{RES4369_CORE_RDY_MAIN,         0x00220022},
1105 	{RES4369_RADIO_MAIN_PU,         0x006e0022},
1106 	{RES4369_MINIPMU_MAIN_PU,       0x00460022},
1107 	{RES4369_PCIE_EP_PU,            0x01200087},
1108 	{RES4369_COLD_START_WAIT,       0x00220022},
1109 	{RES4369_ARMHTAVAIL,            0x00a80022},
1110 	{RES4369_HT_AVAIL,              RES4369_HTAVAIL_VAL},
1111 	{RES4369_MACPHY_AUX_CLK_AVAIL,  0x00640022},
1112 	{RES4369_MACPHY_MAIN_CLK_AVAIL, 0x00640022},
1113 };
1114 
1115 static const pmu_res_updown_t BCMATTACHDATA(bcm4369b0_res_updown)[] = {
1116 	{RES4369_DUMMY,                 0x00220022},
1117 	{RES4369_ABUCK,                 0x00c80022},
1118 	{RES4369_PMU_SLEEP,             0x00c80022},
1119 	{RES4369_MISCLDO,               0x00bd0022},
1120 	{RES4369_LDO3P3,                0x01ad0022},
1121 	{RES4369_FAST_LPO_AVAIL,        0x01500022},
1122 	{RES4369_XTAL_PU,               0x05dc0022},
1123 	{RES4369_XTAL_STABLE,           0x00220022},
1124 	{RES4369_PWRSW_DIG,             0x02100087},
1125 	{RES4369_SR_DIG,                0x00A000A0},
1126 	{RES4369_SLEEP_DIG,             0x00220022},
1127 	{RES4369_PWRSW_AUX,             0x03900087},
1128 	{RES4369_SR_AUX,                0x01400140},
1129 	{RES4369_SLEEP_AUX,             0x00220022},
1130 	{RES4369_PWRSW_MAIN,            0x03900087},
1131 	{RES4369_SR_MAIN,               0x01A001A0},
1132 	{RES4369_SLEEP_MAIN,            0x00220022},
1133 	{RES4369_DIG_CORE_RDY,          0x00220044},
1134 	{RES4369_CORE_RDY_AUX,          0x00220044},
1135 	{RES4369_ALP_AVAIL,             0x00220044},
1136 	{RES4369_RADIO_AUX_PU,          0x006e0022},
1137 	{RES4369_MINIPMU_AUX_PU,        0x00460022},
1138 	{RES4369_CORE_RDY_MAIN,         0x00220022},
1139 	{RES4369_RADIO_MAIN_PU,         0x006e0022},
1140 	{RES4369_MINIPMU_MAIN_PU,       0x00460022},
1141 	{RES4369_PCIE_EP_PU,            0x02100087},
1142 	{RES4369_COLD_START_WAIT,       0x00220022},
1143 	{RES4369_ARMHTAVAIL,            0x00a80022},
1144 	{RES4369_HT_AVAIL,              RES4369_HTAVAIL_VAL},
1145 	{RES4369_MACPHY_AUX_CLK_AVAIL,  0x00640022},
1146 	{RES4369_MACPHY_MAIN_CLK_AVAIL, 0x00640022},
1147 };
1148 
1149 static const pmu_res_updown_t BCMATTACHDATA(bcm4369b0_res_updown_fastlpo_pmu)[] = {
1150 	{RES4369_DUMMY,                 0x00220022},
1151 	{RES4369_ABUCK,                 0x00c80022},
1152 	{RES4369_PMU_SLEEP,             0x00c80022},
1153 	{RES4369_MISCLDO,               0x00bd0022},
1154 	{RES4369_LDO3P3,                0x01ad0022},
1155 	{RES4369_FAST_LPO_AVAIL,        0x01500022},
1156 	{RES4369_XTAL_PU,               0x05dc0022},
1157 	{RES4369_XTAL_STABLE,           0x00220022},
1158 	{RES4369_PWRSW_DIG,             0x02100087},
1159 	{RES4369_SR_DIG,                0x02000200},
1160 	{RES4369_SLEEP_DIG,             0x00220022},
1161 	{RES4369_PWRSW_AUX,             0x03900087},
1162 	{RES4369_SR_AUX,                0x01cc01cc},
1163 	{RES4369_SLEEP_AUX,             0x00220022},
1164 	{RES4369_PWRSW_MAIN,            0x03900087},
1165 	{RES4369_SR_MAIN,               0x02000200},
1166 	{RES4369_SLEEP_MAIN,            0x00220022},
1167 	{RES4369_DIG_CORE_RDY,          0x00220044},
1168 	{RES4369_CORE_RDY_AUX,          0x00220044},
1169 	{RES4369_ALP_AVAIL,             0x00220044},
1170 	{RES4369_RADIO_AUX_PU,          0x006e0022},
1171 	{RES4369_MINIPMU_AUX_PU,        0x00460022},
1172 	{RES4369_CORE_RDY_MAIN,         0x00220022},
1173 	{RES4369_RADIO_MAIN_PU,         0x006e0022},
1174 	{RES4369_MINIPMU_MAIN_PU,       0x00460022},
1175 	{RES4369_PCIE_EP_PU,            0x01200087},
1176 	{RES4369_COLD_START_WAIT,       0x00220022},
1177 	{RES4369_ARMHTAVAIL,            0x00a80022},
1178 	{RES4369_HT_AVAIL,              RES4369_HTAVAIL_VAL},
1179 	{RES4369_MACPHY_AUX_CLK_AVAIL,  0x00640022},
1180 	{RES4369_MACPHY_MAIN_CLK_AVAIL, 0x00640022},
1181 };
1182 
1183 static pmu_res_depend_t BCMATTACHDATA(bcm4362_res_depend)[] = {
1184 	{PMURES_BIT(RES4362_DUMMY),                 RES_DEPEND_SET, 0x00000000, NULL},
1185 	{PMURES_BIT(RES4362_ABUCK),                 RES_DEPEND_SET, 0x00000005, NULL},
1186 	{PMURES_BIT(RES4362_PMU_SLEEP),             RES_DEPEND_SET, 0x00000001, NULL},
1187 	{PMURES_BIT(RES4362_MISCLDO_PU),            RES_DEPEND_SET, 0x00000007, NULL},
1188 	{PMURES_BIT(RES4362_LDO3P3_PU),             RES_DEPEND_SET, 0x00000005, NULL},
1189 	{PMURES_BIT(RES4362_FAST_LPO_AVAIL),        RES_DEPEND_SET, 0x00000005, NULL},
1190 	{PMURES_BIT(RES4362_XTAL_PU),               RES_DEPEND_SET, 0x00000007, NULL},
1191 	{PMURES_BIT(RES4362_XTAL_STABLE),           RES_DEPEND_SET, 0x00000047, NULL},
1192 	{PMURES_BIT(RES4362_PWRSW_DIG),             RES_DEPEND_SET, 0x060000cf, NULL},
1193 	{PMURES_BIT(RES4362_SR_DIG),                RES_DEPEND_SET, 0x060001cf, NULL},
1194 	{PMURES_BIT(RES4362_SLEEP_DIG),             RES_DEPEND_SET, 0x060003cf, NULL},
1195 	{PMURES_BIT(RES4362_PWRSW_AUX),             RES_DEPEND_SET, 0x040000cf, NULL},
1196 	{PMURES_BIT(RES4362_SR_AUX),                RES_DEPEND_SET, 0x040008cf, NULL},
1197 	{PMURES_BIT(RES4362_SLEEP_AUX),             RES_DEPEND_SET, 0x040018cf, NULL},
1198 	{PMURES_BIT(RES4362_PWRSW_MAIN),            RES_DEPEND_SET, 0x040000cf, NULL},
1199 	{PMURES_BIT(RES4362_SR_MAIN),               RES_DEPEND_SET, 0x040040cf, NULL},
1200 	{PMURES_BIT(RES4362_SLEEP_MAIN),            RES_DEPEND_SET, 0x0400c0cf, NULL},
1201 	{PMURES_BIT(RES4362_DIG_CORE_RDY),          RES_DEPEND_SET, 0x060007cf, NULL},
1202 	{PMURES_BIT(RES4362_CORE_RDY_AUX),          RES_DEPEND_SET, 0x040038cf, NULL},
1203 	{PMURES_BIT(RES4362_ALP_AVAIL),             RES_DEPEND_SET, 0x060207cf, NULL},
1204 	{PMURES_BIT(RES4362_RADIO_AUX_PU),          RES_DEPEND_SET, 0x040438df, NULL},
1205 	{PMURES_BIT(RES4362_MINIPMU_AUX_PU),        RES_DEPEND_SET, 0x041438df, NULL},
1206 	{PMURES_BIT(RES4362_CORE_RDY_MAIN),         RES_DEPEND_SET, 0x0401c0cf, NULL},
1207 	{PMURES_BIT(RES4362_RADIO_MAIN_PU),         RES_DEPEND_SET, 0x0441c0df, NULL},
1208 	{PMURES_BIT(RES4362_MINIPMU_MAIN_PU),       RES_DEPEND_SET, 0x04c1c0df, NULL},
1209 	{PMURES_BIT(RES4362_PCIE_EP_PU),            RES_DEPEND_SET, 0x040000cf, NULL},
1210 	{PMURES_BIT(RES4362_COLD_START_WAIT),       RES_DEPEND_SET, 0x0000000f, NULL},
1211 	{PMURES_BIT(RES4362_ARMHTAVAIL),            RES_DEPEND_SET, 0x060a07cf, NULL},
1212 	{PMURES_BIT(RES4362_HT_AVAIL),              RES_DEPEND_SET, 0x060a07cf, NULL},
1213 	{PMURES_BIT(RES4362_MACPHY_AUX_CLK_AVAIL),  RES_DEPEND_SET, 0x163e3fdf, NULL},
1214 	{PMURES_BIT(RES4362_MACPHY_MAIN_CLK_AVAIL), RES_DEPEND_SET, 0x17cbc7df, NULL},
1215 };
1216 
1217 static const pmu_res_updown_t BCMATTACHDATA(bcm4362_res_updown)[] = {
1218 	{RES4362_DUMMY,                 0x00220022},
1219 	{RES4362_ABUCK,                 0x00c80022},
1220 	{RES4362_PMU_SLEEP,             0x00c80022},
1221 	{RES4362_MISCLDO_PU,            0x00bd0022},
1222 	{RES4362_LDO3P3_PU,             0x01ad0022},
1223 	{RES4362_FAST_LPO_AVAIL,        0x01500022},
1224 	{RES4362_XTAL_PU,               0x05dc0022},
1225 	{RES4362_XTAL_STABLE,           0x00220022},
1226 	{RES4362_PWRSW_DIG,             0x009000ca},
1227 	{RES4362_SR_DIG,                0x00A000A0},
1228 	{RES4362_SLEEP_DIG,             0x00220022},
1229 	{RES4362_PWRSW_AUX,             0x039000ca},
1230 	{RES4362_SR_AUX,                0x01400140},
1231 	{RES4362_SLEEP_AUX,             0x00220022},
1232 	{RES4362_PWRSW_MAIN,            0x039000ca},
1233 	{RES4362_SR_MAIN,               0x01a001a0},
1234 	{RES4362_SLEEP_MAIN,            0x00220022},
1235 	{RES4362_DIG_CORE_RDY,          0x00220044},
1236 	{RES4362_CORE_RDY_AUX,          0x00220044},
1237 	{RES4362_ALP_AVAIL,             0x00220044},
1238 	{RES4362_RADIO_AUX_PU,          0x006e0022},
1239 	{RES4362_MINIPMU_AUX_PU,        0x00460022},
1240 	{RES4362_CORE_RDY_MAIN,         0x00220022},
1241 	{RES4362_RADIO_MAIN_PU,         0x006e0022},
1242 	{RES4362_MINIPMU_MAIN_PU,       0x00460022},
1243 	{RES4362_PCIE_EP_PU,            0x009000ca},
1244 	{RES4362_COLD_START_WAIT,       0x00220022},
1245 	{RES4362_ARMHTAVAIL,            0x00a80022},
1246 	{RES4362_HT_AVAIL,              0x00a80022},
1247 	{RES4362_MACPHY_AUX_CLK_AVAIL,  0x00640022},
1248 	{RES4362_MACPHY_MAIN_CLK_AVAIL, 0x00640022},
1249 };
1250 
1251 static const pmu_res_updown_t BCMATTACHDATA(bcm4378b0_res_updown)[] = {
1252 	{RES4378_ABUCK,			0x00c80022},
1253 	{RES4378_PMU_SLEEP,		0x011c0022},
1254 	{RES4378_MISC_LDO,		0x00c80022},
1255 	{RES4378_XTAL_PU,		0x05dc0022},
1256 	{RES4378_SR_DIG,		0x00700070},
1257 	{RES4378_SR_AUX,		0x01800180},
1258 	{RES4378_SR_MAIN,		0x01a001a0},
1259 	{RES4378_RADIO_AUX_PU,		0x006e0022},
1260 	{RES4378_MINIPMU_AUX_PU,	0x00460022},
1261 	{RES4378_RADIO_MAIN_PU,		0x006e0022},
1262 	{RES4378_MINIPMU_MAIN_PU,	0x00460022},
1263 	{RES4378_CORE_RDY_CB,		0x00220022},
1264 #ifdef BCMPCIE_TREFUP_HW_SUPPORT
1265 	{RES4378_PWRSW_CB,              0x015e00ca},
1266 #endif
1267 	{RES4378_MACPHY_AUX_CLK_AVAIL,	0x00640022},
1268 	{RES4378_MACPHY_MAIN_CLK_AVAIL,	0x00640022},
1269 };
1270 
1271 static pmu_res_depend_t BCMATTACHDATA(bcm4378b0_res_depend)[] = {
1272 	{PMURES_BIT(RES4378_ABUCK),			RES_DEPEND_SET, 0x00000005, NULL},
1273 	{PMURES_BIT(RES4378_PMU_SLEEP),			RES_DEPEND_SET, 0x00000001, NULL},
1274 	{PMURES_BIT(RES4378_MISC_LDO),			RES_DEPEND_SET, 0x00000007, NULL},
1275 	{PMURES_BIT(RES4378_LDO3P3_PU),			RES_DEPEND_SET, 0x00000001, NULL},
1276 	{PMURES_BIT(RES4378_FAST_LPO_AVAIL),		RES_DEPEND_SET, 0x00000005, NULL},
1277 	{PMURES_BIT(RES4378_XTAL_PU),			RES_DEPEND_SET, 0x00000007, NULL},
1278 	{PMURES_BIT(RES4378_XTAL_STABLE),		RES_DEPEND_SET, 0x00000047, NULL},
1279 	{PMURES_BIT(RES4378_PWRSW_DIG),			RES_DEPEND_SET, 0x060000ef, NULL},
1280 	{PMURES_BIT(RES4378_SR_DIG),			RES_DEPEND_SET, 0x060001ef, NULL},
1281 	{PMURES_BIT(RES4378_SLEEP_DIG),			RES_DEPEND_SET, 0x060003ef, NULL},
1282 	{PMURES_BIT(RES4378_PWRSW_AUX),			RES_DEPEND_SET, 0x060000ef, NULL},
1283 	{PMURES_BIT(RES4378_SR_AUX),			RES_DEPEND_SET, 0x060008ef, NULL},
1284 	{PMURES_BIT(RES4378_SLEEP_AUX),			RES_DEPEND_SET, 0x060018ef, NULL},
1285 	{PMURES_BIT(RES4378_PWRSW_MAIN),		RES_DEPEND_SET, 0x060000ef, NULL},
1286 	{PMURES_BIT(RES4378_SR_MAIN),			RES_DEPEND_SET, 0x060040ef, NULL},
1287 	{PMURES_BIT(RES4378_SLEEP_MAIN),		RES_DEPEND_SET, 0x0600c0ef, NULL},
1288 	{PMURES_BIT(RES4378_CORE_RDY_DIG),		RES_DEPEND_SET, 0x060007ef, NULL},
1289 	{PMURES_BIT(RES4378_CORE_RDY_AUX),		RES_DEPEND_SET, 0x06023fef, NULL},
1290 	{PMURES_BIT(RES4378_ALP_AVAIL),			RES_DEPEND_SET, 0x000000c7, NULL},
1291 	{PMURES_BIT(RES4378_RADIO_AUX_PU),		RES_DEPEND_SET, 0x06063fff, NULL},
1292 	{PMURES_BIT(RES4378_MINIPMU_AUX_PU),		RES_DEPEND_SET, 0x06163fff, NULL},
1293 	{PMURES_BIT(RES4378_CORE_RDY_MAIN),		RES_DEPEND_SET, 0x0603c7ef, NULL},
1294 	{PMURES_BIT(RES4378_RADIO_MAIN_PU),		RES_DEPEND_SET, 0x0643c7ff, NULL},
1295 	{PMURES_BIT(RES4378_MINIPMU_MAIN_PU),		RES_DEPEND_SET, 0x06c3c7ff, NULL},
1296 #ifdef BCMPCIE_TREFUP_HW_SUPPORT
1297 	{PMURES_BIT(RES4378_CORE_RDY_CB),		RES_DEPEND_SET, 0x0400002f, NULL},
1298 #else
1299 	{PMURES_BIT(RES4378_CORE_RDY_CB),		RES_DEPEND_SET, 0x040000ef, NULL},
1300 #endif
1301 	{PMURES_BIT(RES4378_PWRSW_CB),			RES_DEPEND_SET, 0x0000002f, NULL},
1302 	{PMURES_BIT(RES4378_ARMHTAVAIL),		RES_DEPEND_SET, 0x000800c7, NULL},
1303 	{PMURES_BIT(RES4378_HT_AVAIL),			RES_DEPEND_SET, 0x000800c7, NULL},
1304 	{PMURES_BIT(RES4378_MACPHY_AUX_CLK_AVAIL),	RES_DEPEND_SET, 0x163e3fff, NULL},
1305 	{PMURES_BIT(RES4378_MACPHY_MAIN_CLK_AVAIL),	RES_DEPEND_SET, 0x17cbc7ff, NULL},
1306 };
1307 
1308 static const pmu_res_updown_t BCMATTACHDATA(bcm4387b0_res_updown_qt)[] = {
1309 	{RES4387_XTAL_PU,		0x012c0033},
1310 	{RES4387_PWRSW_DIG,		0x38993899},
1311 	{RES4387_PWRSW_AUX,		0x38993899},
1312 	{RES4387_PWRSW_SCAN,		0x38993899},
1313 	{RES4387_PWRSW_MAIN,		0x38993899},
1314 	{RES4387_CORE_RDY_CB,		0x00960033},
1315 };
1316 
1317 static const pmu_res_subst_trans_tmr_t BCMATTACHDATA(bcm4387b0_res_subst_trans_tmr_qt)[] = {
1318 	{RES4387_PWRSW_DIG,		0, 0x38993800},
1319 	{RES4387_PWRSW_DIG,		1, 0x36000600},
1320 	{RES4387_PWRSW_DIG,		2, 0x01000002},
1321 
1322 	{RES4387_PWRSW_AUX,		0, 0x38993800},
1323 	{RES4387_PWRSW_AUX,		1, 0x36000600},
1324 	{RES4387_PWRSW_AUX,		2, 0x01000002},
1325 
1326 	{RES4387_PWRSW_SCAN,		0, 0x38993800},
1327 	{RES4387_PWRSW_SCAN,		1, 0x36000600},
1328 	{RES4387_PWRSW_SCAN,		2, 0x01000002},
1329 
1330 	{RES4387_PWRSW_MAIN,		0, 0x38993800},
1331 	{RES4387_PWRSW_MAIN,		1, 0x36000600},
1332 	{RES4387_PWRSW_MAIN,		2, 0x01000002},
1333 };
1334 
1335 static const pmu_res_updown_t BCMATTACHDATA(bcm4387b0_res_updown)[] = {
1336 	{RES4387_PMU_SLEEP,		0x00960022},
1337 	{RES4387_MISC_LDO,		0x00320022},
1338 	{RES4387_XTAL_HQ,		0x00210021},
1339 	{RES4387_XTAL_PU,		0x03e80033},
1340 	{RES4387_PWRSW_DIG,		0x04b002bc},
1341 	{RES4387_PWRSW_AUX,		0x060e03bc},
1342 	{RES4387_PWRSW_SCAN,		0x060e03bc},
1343 	{RES4387_PWRSW_MAIN,		0x060e03bc},
1344 	{RES4387_CORE_RDY_CB,		0x000a0033},
1345 	{RES4387_PWRSW_CB,		0x006400ca},
1346 };
1347 
1348 static const pmu_res_subst_trans_tmr_t BCMATTACHDATA(bcm4387b0_res_subst_trans_tmr)[] = {
1349 	{RES4387_PWRSW_DIG,		0, 0x04b002bc},
1350 	{RES4387_PWRSW_DIG,		1, 0x02500210},
1351 	{RES4387_PWRSW_DIG,		2, 0x00a00010},
1352 
1353 	{RES4387_PWRSW_AUX,		0, 0x060e03ac},
1354 	{RES4387_PWRSW_AUX,		1, 0x028a0134},
1355 	{RES4387_PWRSW_AUX,		2, 0x00320002},
1356 
1357 	{RES4387_PWRSW_MAIN,		0, 0x060e03b2},
1358 	{RES4387_PWRSW_MAIN,		1, 0x028a0134},
1359 	{RES4387_PWRSW_MAIN,		2, 0x00320002},
1360 
1361 	{RES4387_PWRSW_SCAN,		0, 0x060e03b2},
1362 	{RES4387_PWRSW_SCAN,		1, 0x028a0134},
1363 	{RES4387_PWRSW_SCAN,		2, 0x00320002},
1364 };
1365 
1366 static pmu_res_depend_t BCMATTACHDATA(bcm4387b0_res_depend)[] = {
1367 	{PMURES_BIT(RES4387_DUMMY),			RES_DEPEND_SET,  0x0, NULL},
1368 	{PMURES_BIT(RES4387_RESERVED_1),		RES_DEPEND_SET,  0x0, NULL},
1369 	{PMURES_BIT(RES4387_PMU_SLEEP),			RES_DEPEND_SET,  0x1, NULL},
1370 	{PMURES_BIT(RES4387_MISC_LDO),			RES_DEPEND_SET,  0x5, NULL},
1371 	{PMURES_BIT(RES4387_RESERVED_4),		RES_DEPEND_SET,  0x0, NULL},
1372 	{PMURES_BIT(RES4387_XTAL_HQ),			RES_DEPEND_SET,  0xc5, NULL},
1373 	{PMURES_BIT(RES4387_XTAL_PU),			RES_DEPEND_SET,  0x5, NULL},
1374 	{PMURES_BIT(RES4387_XTAL_STABLE),		RES_DEPEND_SET,  0x45, NULL},
1375 	{PMURES_BIT(RES4387_PWRSW_DIG),			RES_DEPEND_SET,  0x060000CD, NULL},
1376 	{PMURES_BIT(RES4387_CORE_RDY_BTMAIN),		RES_DEPEND_SET,  0xCD, NULL},
1377 	{PMURES_BIT(RES4387_CORE_RDY_BTSC),		RES_DEPEND_SET,  0xC5, NULL},
1378 	{PMURES_BIT(RES4387_PWRSW_AUX),			RES_DEPEND_SET,  0xCD, NULL},
1379 	{PMURES_BIT(RES4387_PWRSW_SCAN),		RES_DEPEND_SET,  0xCD, NULL},
1380 	{PMURES_BIT(RES4387_CORE_RDY_SCAN),		RES_DEPEND_SET,  0x060010CD, NULL},
1381 	{PMURES_BIT(RES4387_PWRSW_MAIN),		RES_DEPEND_SET,  0xCD, NULL},
1382 	{PMURES_BIT(RES4387_RESERVED_15),		RES_DEPEND_SET,  0x0, NULL},
1383 	{PMURES_BIT(RES4387_RESERVED_16),		RES_DEPEND_SET,  0x0, NULL},
1384 	{PMURES_BIT(RES4387_CORE_RDY_DIG),		RES_DEPEND_SET,  0x060001CD, NULL},
1385 	{PMURES_BIT(RES4387_CORE_RDY_AUX),		RES_DEPEND_SET,  0x060209CD, NULL},
1386 	{PMURES_BIT(RES4387_ALP_AVAIL),			RES_DEPEND_SET,  0xC5, NULL},
1387 	{PMURES_BIT(RES4387_RADIO_PU_AUX),		RES_DEPEND_SET,  0x060609CD, NULL},
1388 	{PMURES_BIT(RES4387_RADIO_PU_SCAN),		RES_DEPEND_SET,  0x060030CD, NULL},
1389 	{PMURES_BIT(RES4387_CORE_RDY_MAIN),		RES_DEPEND_SET,  0x060241CD, NULL},
1390 	{PMURES_BIT(RES4387_RADIO_PU_MAIN),		RES_DEPEND_SET,  0x064241CD, NULL},
1391 	{PMURES_BIT(RES4387_MACPHY_CLK_SCAN),		RES_DEPEND_SET,  0x162830CD, NULL},
1392 	{PMURES_BIT(RES4387_CORE_RDY_CB),		RES_DEPEND_SET,  0x0400000D, NULL},
1393 	{PMURES_BIT(RES4387_PWRSW_CB),			RES_DEPEND_SET,  0x0000000D, NULL},
1394 	{PMURES_BIT(RES4387_ARMCLK_AVAIL),		RES_DEPEND_SET,  0x000800CD, NULL},
1395 	{PMURES_BIT(RES4387_HT_AVAIL),			RES_DEPEND_SET,  0x000800CD, NULL},
1396 	{PMURES_BIT(RES4387_MACPHY_CLK_AUX),		RES_DEPEND_SET,  0x161E09ED, NULL},
1397 	{PMURES_BIT(RES4387_MACPHY_CLK_MAIN),		RES_DEPEND_SET,  0x16CA41ED, NULL},
1398 };
1399 
1400 static const pmu_res_updown_t BCMATTACHDATA(bcm4387c0_res_updown_topoff)[] = {
1401 	{RES4387_PMU_SLEEP,		0x02000022},
1402 	{RES4387_MISC_LDO,		0x00320022},
1403 	{RES4387_SERDES_AFE_RET,	0x00010001},
1404 	{RES4387_XTAL_HQ,		0x00210021},
1405 	{RES4387_XTAL_PU,		0x03e80033},
1406 	{RES4387_PWRSW_DIG,	        0x00d20102},
1407 	{RES4387_PWRSW_AUX,	        0x01c201e2},
1408 	{RES4387_PWRSW_SCAN,	        0x01020122},
1409 	{RES4387_PWRSW_MAIN,	        0x02220242},
1410 	{RES4387_CORE_RDY_CB,		0x000a0033},
1411 	{RES4387_PWRSW_CB,		0x006400ca},
1412 };
1413 
1414 static const pmu_res_updown_t BCMATTACHDATA(bcm4387c0_res_updown)[] = {
1415 #ifdef BCM_PMU_FLL_PU_MANAGE
1416 	{RES4387_FAST_LPO_AVAIL,	0x00960001},
1417 #endif
1418 	{RES4387_PMU_SLEEP,		0x00960022},
1419 	{RES4387_MISC_LDO,		0x00320022},
1420 	{RES4387_XTAL_HQ,		0x00210021},
1421 	{RES4387_XTAL_PU,		0x03e80033},
1422 	{RES4387_PWRSW_DIG,	        0x01320172},
1423 	{RES4387_PWRSW_AUX,	        0x01c201e2},
1424 	{RES4387_PWRSW_SCAN,	        0x019201b2},
1425 	{RES4387_PWRSW_MAIN,	        0x02220242},
1426 	{RES4387_CORE_RDY_CB,		0x000a0033},
1427 	{RES4387_PWRSW_CB,		0x006400ca},
1428 };
1429 
1430 static const pmu_res_subst_trans_tmr_t BCMATTACHDATA(bcm4387c0_res_subst_trans_tmr)[] = {
1431 	{RES4387_PWRSW_DIG,		0, 0x01320142},
1432 	{RES4387_PWRSW_DIG,		1, 0x00e2005a},
1433 	{RES4387_PWRSW_DIG,		2, 0x00c20052},
1434 	{RES4387_PWRSW_DIG,		3, 0x00020002},
1435 
1436 	{RES4387_PWRSW_AUX,		0, 0x01c201b2},
1437 	{RES4387_PWRSW_AUX,		1, 0x0172005a},
1438 	{RES4387_PWRSW_AUX,		2, 0x01520052},
1439 	{RES4387_PWRSW_AUX,		3, 0x00020002},
1440 
1441 	{RES4387_PWRSW_MAIN,		0, 0x02220212},
1442 	{RES4387_PWRSW_MAIN,		1, 0x01d2005a},
1443 	{RES4387_PWRSW_MAIN,		2, 0x01b20052},
1444 	{RES4387_PWRSW_MAIN,		3, 0x00020002},
1445 
1446 	{RES4387_PWRSW_SCAN,		0, 0x01920182},
1447 	{RES4387_PWRSW_SCAN,		1, 0x0142005a},
1448 	{RES4387_PWRSW_SCAN,		2, 0x01220052},
1449 	{RES4387_PWRSW_SCAN,		3, 0x00020002},
1450 };
1451 
1452 static pmu_res_depend_t BCMATTACHDATA(bcm4387c0_res_depend)[] = {
1453 	{PMURES_BIT(RES4387_DUMMY),			RES_DEPEND_SET,  0x0, NULL},
1454 	{PMURES_BIT(RES4387_FAST_LPO_AVAIL),		RES_DEPEND_SET,  0x0, NULL},
1455 	{PMURES_BIT(RES4387_PMU_LP),			RES_DEPEND_SET,  0x1, NULL},
1456 	{PMURES_BIT(RES4387_MISC_LDO),			RES_DEPEND_SET,  0x5, NULL},
1457 	{PMURES_BIT(RES4387_SERDES_AFE_RET),		RES_DEPEND_SET,  0xD, NULL},
1458 	{PMURES_BIT(RES4387_XTAL_HQ),			RES_DEPEND_SET,  0xC5, NULL},
1459 	{PMURES_BIT(RES4387_XTAL_PU),			RES_DEPEND_SET,  0x5, NULL},
1460 	{PMURES_BIT(RES4387_XTAL_STABLE),		RES_DEPEND_SET,  0x45, NULL},
1461 	{PMURES_BIT(RES4387_PWRSW_DIG),			RES_DEPEND_SET,  0x060000DD, NULL},
1462 	{PMURES_BIT(RES4387_CORE_RDY_BTMAIN),		RES_DEPEND_SET,  0xCD, NULL},
1463 	{PMURES_BIT(RES4387_CORE_RDY_BTSC),		RES_DEPEND_SET,  0xC5, NULL},
1464 	{PMURES_BIT(RES4387_PWRSW_AUX),			RES_DEPEND_SET,  0xCD, NULL},
1465 	{PMURES_BIT(RES4387_PWRSW_SCAN),		RES_DEPEND_SET,  0xCD, NULL},
1466 	{PMURES_BIT(RES4387_CORE_RDY_SCAN),		RES_DEPEND_SET,  0x060010DD, NULL},
1467 	{PMURES_BIT(RES4387_PWRSW_MAIN),		RES_DEPEND_SET,  0xCD, NULL},
1468 	{PMURES_BIT(RES4387_XTAL_PM_CLK),		RES_DEPEND_SET,  0xC5, NULL},
1469 	{PMURES_BIT(RES4387_RESERVED_16),		RES_DEPEND_SET,  0x0, NULL},
1470 	{PMURES_BIT(RES4387_CORE_RDY_DIG),		RES_DEPEND_SET,  0x060001DD, NULL},
1471 	{PMURES_BIT(RES4387_CORE_RDY_AUX),		RES_DEPEND_SET,  0x060209DD, NULL},
1472 	{PMURES_BIT(RES4387_ALP_AVAIL),			RES_DEPEND_SET,  0x80C5, NULL},
1473 	{PMURES_BIT(RES4387_RADIO_PU_AUX),		RES_DEPEND_SET,  0x060609DD, NULL},
1474 	{PMURES_BIT(RES4387_RADIO_PU_SCAN),		RES_DEPEND_SET,  0x060030DD, NULL},
1475 	{PMURES_BIT(RES4387_CORE_RDY_MAIN),		RES_DEPEND_SET,  0x060241DD, NULL},
1476 	{PMURES_BIT(RES4387_RADIO_PU_MAIN),		RES_DEPEND_SET,  0x064241DD, NULL},
1477 	{PMURES_BIT(RES4387_MACPHY_CLK_SCAN),		RES_DEPEND_SET,  0x1628B0DD, NULL},
1478 	{PMURES_BIT(RES4387_CORE_RDY_CB),		RES_DEPEND_SET,  0x0400001D, NULL},
1479 	{PMURES_BIT(RES4387_PWRSW_CB),			RES_DEPEND_SET,  0x0000001D, NULL},
1480 	{PMURES_BIT(RES4387_ARMCLK_AVAIL),		RES_DEPEND_SET,  0x000880CD, NULL},
1481 	{PMURES_BIT(RES4387_HT_AVAIL),			RES_DEPEND_SET,  0x000880CD, NULL},
1482 	{PMURES_BIT(RES4387_MACPHY_CLK_AUX),		RES_DEPEND_SET,  0x161E89FD, NULL},
1483 	{PMURES_BIT(RES4387_MACPHY_CLK_MAIN),		RES_DEPEND_SET,  0x16CAC1FD, NULL},
1484 };
1485 
1486 static const pmu_res_updown_t BCMATTACHDATA(bcm4388a0_res_updown_qt)[] = {
1487 	{RES4388_XTAL_PU,	0x012c0033},
1488 	{RES4388_PWRSW_DIG,	0x38993899},
1489 	{RES4388_PWRSW_AUX,	0x38993899},
1490 	{RES4388_PWRSW_SCAN,	0x38993899},
1491 	{RES4388_PWRSW_MAIN,	0x38993899},
1492 	{RES4388_CORE_RDY_CB,	0x00960033},
1493 };
1494 
1495 static const pmu_res_subst_trans_tmr_t BCMATTACHDATA(bcm4388a0_res_subst_trans_tmr_qt)[] = {
1496 	{RES4388_PWRSW_DIG,	0, 0x38993800},
1497 	{RES4388_PWRSW_DIG,	1, 0x36c00600},
1498 	{RES4388_PWRSW_DIG,	2, 0x360005a0},
1499 	{RES4388_PWRSW_DIG,	3, 0x01000002},
1500 
1501 	{RES4388_PWRSW_AUX,	0, 0x38993800},
1502 	{RES4388_PWRSW_AUX,	1, 0x36c00600},
1503 	{RES4388_PWRSW_AUX,	2, 0x360005a0},
1504 	{RES4388_PWRSW_AUX,	3, 0x01000002},
1505 
1506 	{RES4388_PWRSW_MAIN,	0, 0x38993800},
1507 	{RES4388_PWRSW_MAIN,	1, 0x36c00600},
1508 	{RES4388_PWRSW_MAIN,	2, 0x360005a0},
1509 	{RES4388_PWRSW_MAIN,	3, 0x01000002},
1510 
1511 	{RES4388_PWRSW_SCAN,	0, 0x38993800},
1512 	{RES4388_PWRSW_SCAN,	1, 0x33c00600},
1513 	{RES4388_PWRSW_SCAN,	2, 0x330005a0},
1514 	{RES4388_PWRSW_SCAN,	3, 0x01000002},
1515 };
1516 
1517 static const pmu_res_updown_t BCMATTACHDATA(bcm4388a0_res_updown)[] = {
1518 #ifdef BCM_PMU_FLL_PU_MANAGE
1519 	{RES4388_FAST_LPO_AVAIL,	0x00960001},
1520 #endif /* BCM_PMU_FLL_PU_MANAGE */
1521 	{RES4388_PMU_LP,		0x00960022},
1522 	{RES4388_MISC_LDO,		0x00320022},
1523 	{RES4388_XTAL_HQ,		0x00210021},
1524 	{RES4388_XTAL_PU,		0x03e80033},
1525 	{RES4388_PWRSW_DIG,		0x042c0349},
1526 	{RES4388_PWRSW_AUX,		0x0740046a},
1527 	{RES4388_PWRSW_SCAN,		0x03c802e8},
1528 	{RES4388_PWRSW_MAIN,		0x08080532},
1529 	{RES4388_CORE_RDY_CB,		0x000a0033},
1530 	{RES4388_PWRSW_CB,		0x006400ca},
1531 	{RES4388_MACPHY_CLK_MAIN,	0x00860022},
1532 };
1533 
1534 static const pmu_res_subst_trans_tmr_t BCMATTACHDATA(bcm4388a0_res_subst_trans_tmr)[] = {
1535 	{RES4388_PWRSW_DIG,	0, 0x0428033c},
1536 	{RES4388_PWRSW_DIG,	1, 0x028c0210},
1537 	{RES4388_PWRSW_DIG,	2, 0x01cc01b0},
1538 	{RES4388_PWRSW_DIG,	3, 0x00a00010},
1539 
1540 	{RES4388_PWRSW_AUX,	0, 0x0740045a},
1541 	{RES4388_PWRSW_AUX,	1, 0x03580202},
1542 	{RES4388_PWRSW_AUX,	2, 0x02f801a2},
1543 	{RES4388_PWRSW_AUX,	3, 0x00a00002},
1544 
1545 	{RES4388_PWRSW_MAIN,	0, 0x08080522},
1546 	{RES4388_PWRSW_MAIN,	1, 0x04200202},
1547 	{RES4388_PWRSW_MAIN,	2, 0x03c001a2},
1548 	{RES4388_PWRSW_MAIN,	3, 0x00a00002},
1549 
1550 	{RES4388_PWRSW_SCAN,	0, 0x03c402d8},
1551 	{RES4388_PWRSW_SCAN,	1, 0x02280210},
1552 	{RES4388_PWRSW_SCAN,	2, 0x016801b0},
1553 	{RES4388_PWRSW_SCAN,	3, 0x00a00010},
1554 };
1555 
1556 static pmu_res_depend_t BCMATTACHDATA(bcm4388a0_res_depend)[] = {
1557 	{PMURES_BIT(RES4388_DUMMY),		RES_DEPEND_SET, 0x00000000, NULL},
1558 	{PMURES_BIT(RES4388_FAST_LPO_AVAIL),	RES_DEPEND_SET, 0x00000000, NULL},
1559 	{PMURES_BIT(RES4388_PMU_LP),		RES_DEPEND_SET, 0x00000001, NULL},
1560 	{PMURES_BIT(RES4388_MISC_LDO),		RES_DEPEND_SET, 0x00000005, NULL},
1561 	{PMURES_BIT(RES4388_SERDES_AFE_RET),	RES_DEPEND_SET, 0x0000000d, NULL},
1562 	{PMURES_BIT(RES4388_XTAL_HQ),		RES_DEPEND_SET, 0x000000c5, NULL},
1563 	{PMURES_BIT(RES4388_XTAL_PU),		RES_DEPEND_SET, 0x00000005, NULL},
1564 	{PMURES_BIT(RES4388_XTAL_STABLE),	RES_DEPEND_SET, 0x00000045, NULL},
1565 	{PMURES_BIT(RES4388_PWRSW_DIG),		RES_DEPEND_SET, 0x060000dd, NULL},
1566 	{PMURES_BIT(RES4388_BTMC_TOP_RDY),	RES_DEPEND_SET, 0x000000cd, NULL},
1567 	{PMURES_BIT(RES4388_BTSC_TOP_RDY),	RES_DEPEND_SET, 0x000000c5, NULL},
1568 	{PMURES_BIT(RES4388_PWRSW_AUX),		RES_DEPEND_SET, 0x000000cd, NULL},
1569 	{PMURES_BIT(RES4388_PWRSW_SCAN),	RES_DEPEND_SET, 0x000000cd, NULL},
1570 	{PMURES_BIT(RES4388_CORE_RDY_SCAN),	RES_DEPEND_SET, 0x060211dd, NULL},
1571 	{PMURES_BIT(RES4388_PWRSW_MAIN),	RES_DEPEND_SET, 0x000000cd, NULL},
1572 	{PMURES_BIT(RES4388_RESERVED_15),	RES_DEPEND_SET, 0x00000000, NULL},
1573 	{PMURES_BIT(RES4388_RESERVED_16),	RES_DEPEND_SET, 0x00000000, NULL},
1574 	{PMURES_BIT(RES4388_CORE_RDY_DIG),	RES_DEPEND_SET, 0x060001dd, NULL},
1575 	{PMURES_BIT(RES4388_CORE_RDY_AUX),	RES_DEPEND_SET, 0x060209dd, NULL},
1576 	{PMURES_BIT(RES4388_ALP_AVAIL),		RES_DEPEND_SET, 0x000000c5, NULL},
1577 	{PMURES_BIT(RES4388_RADIO_PU_AUX),	RES_DEPEND_SET, 0x060609dd, NULL},
1578 	{PMURES_BIT(RES4388_RADIO_PU_SCAN),	RES_DEPEND_SET, 0x060231dd, NULL},
1579 	{PMURES_BIT(RES4388_CORE_RDY_MAIN),	RES_DEPEND_SET, 0x060241dd, NULL},
1580 	{PMURES_BIT(RES4388_RADIO_PU_MAIN),	RES_DEPEND_SET, 0x064241dd, NULL},
1581 	{PMURES_BIT(RES4388_MACPHY_CLK_SCAN),	RES_DEPEND_SET, 0x162a31fd, NULL},
1582 	{PMURES_BIT(RES4388_CORE_RDY_CB),	RES_DEPEND_SET, 0x040000dd, NULL},
1583 	{PMURES_BIT(RES4388_PWRSW_CB),		RES_DEPEND_SET, 0x000000dd, NULL},
1584 	{PMURES_BIT(RES4388_ARMCLKAVAIL),	RES_DEPEND_SET, 0x000800cd, NULL},
1585 	{PMURES_BIT(RES4388_HT_AVAIL),		RES_DEPEND_SET, 0x000800cd, NULL},
1586 	{PMURES_BIT(RES4388_MACPHY_CLK_AUX),	RES_DEPEND_SET, 0x161e09fd, NULL},
1587 	{PMURES_BIT(RES4388_MACPHY_CLK_MAIN),	RES_DEPEND_SET, 0x16ca41fd, NULL},
1588 };
1589 
1590 static const pmu_res_updown_t BCMATTACHDATA(bcm4389b0_res_updown_qt)[] = {
1591 	{RES4389_XTAL_PU,	0x012c0033},
1592 	{RES4389_PWRSW_DIG,	0x38993899},
1593 	{RES4389_PWRSW_AUX,	0x38993899},
1594 	{RES4389_PWRSW_SCAN,	0x38993899},
1595 	{RES4389_PWRSW_MAIN,	0x38993899},
1596 	{RES4389_CORE_RDY_CB,	0x00960033},
1597 };
1598 
1599 static const pmu_res_subst_trans_tmr_t BCMATTACHDATA(bcm4389b0_res_subst_trans_tmr_qt)[] = {
1600 	{RES4389_PWRSW_DIG,	0, 0x38993800},
1601 	{RES4389_PWRSW_DIG,	1, 0x36c00600},
1602 	{RES4389_PWRSW_DIG,	2, 0x360005a0},
1603 	{RES4389_PWRSW_DIG,	3, 0x01000002},
1604 
1605 	{RES4389_PWRSW_AUX,	0, 0x38993800},
1606 	{RES4389_PWRSW_AUX,	1, 0x36c00600},
1607 	{RES4389_PWRSW_AUX,	2, 0x360005a0},
1608 	{RES4389_PWRSW_AUX,	3, 0x01000002},
1609 
1610 	{RES4389_PWRSW_MAIN,	0, 0x38993800},
1611 	{RES4389_PWRSW_MAIN,	1, 0x36c00600},
1612 	{RES4389_PWRSW_MAIN,	2, 0x360005a0},
1613 	{RES4389_PWRSW_MAIN,	3, 0x01000002},
1614 
1615 	{RES4389_PWRSW_SCAN,	0, 0x38993800},
1616 	{RES4389_PWRSW_SCAN,	1, 0x33c00600},
1617 	{RES4389_PWRSW_SCAN,	2, 0x330005a0},
1618 	{RES4389_PWRSW_SCAN,	3, 0x01000002},
1619 };
1620 
1621 static const pmu_res_updown_t BCMATTACHDATA(bcm4389b0_res_updown)[] = {
1622 #ifdef BCM_PMU_FLL_PU_MANAGE
1623 	{RES4389_FAST_LPO_AVAIL,	0x001e0001},
1624 #endif /* BCM_PMU_FLL_PU_MANAGE */
1625 	{RES4389_PMU_LP,		0x00960022},
1626 	{RES4389_MISC_LDO,		0x00320022},
1627 	{RES4389_XTAL_HQ,		0x00210021},
1628 	{RES4389_XTAL_PU,		0x03e80033},
1629 	{RES4389_PWRSW_DIG,		0x042c0349},
1630 	{RES4389_PWRSW_AUX,		0x0740046a},
1631 	{RES4389_PWRSW_SCAN,		0x03c802e8},
1632 	{RES4389_PWRSW_MAIN,		0x08080532},
1633 	{RES4389_CORE_RDY_CB,		0x000a0033},
1634 	{RES4389_PWRSW_CB,		0x006400ca},
1635 	{RES4389_MACPHY_CLK_MAIN,	0x00860022},
1636 };
1637 
1638 static const pmu_res_subst_trans_tmr_t BCMATTACHDATA(bcm4389b0_res_subst_trans_tmr)[] = {
1639 	{RES4389_PWRSW_DIG,	0, 0x0428033c},
1640 	{RES4389_PWRSW_DIG,	1, 0x028c0210},
1641 	{RES4389_PWRSW_DIG,	2, 0x01cc01b0},
1642 	{RES4389_PWRSW_DIG,	3, 0x00a00010},
1643 
1644 	{RES4389_PWRSW_AUX,	0, 0x0740045a},
1645 	{RES4389_PWRSW_AUX,	1, 0x03580202},
1646 	{RES4389_PWRSW_AUX,	2, 0x02f801a2},
1647 	{RES4389_PWRSW_AUX,	3, 0x00a00002},
1648 
1649 	{RES4389_PWRSW_MAIN,	0, 0x08080522},
1650 	{RES4389_PWRSW_MAIN,	1, 0x04200202},
1651 	{RES4389_PWRSW_MAIN,	2, 0x03c001a2},
1652 	{RES4389_PWRSW_MAIN,	3, 0x00a00002},
1653 
1654 	{RES4389_PWRSW_SCAN,	0, 0x03c402d8},
1655 	{RES4389_PWRSW_SCAN,	1, 0x02280210},
1656 	{RES4389_PWRSW_SCAN,	2, 0x016801b0},
1657 	{RES4389_PWRSW_SCAN,	3, 0x00a00010},
1658 };
1659 
1660 static pmu_res_depend_t BCMATTACHDATA(bcm4389b0_res_depend)[] = {
1661 	{PMURES_BIT(RES4389_DUMMY),		RES_DEPEND_SET, 0x00000000, NULL},
1662 	{PMURES_BIT(RES4389_FAST_LPO_AVAIL),	RES_DEPEND_SET, 0x00000000, NULL},
1663 	{PMURES_BIT(RES4389_PMU_LP),		RES_DEPEND_SET, 0x00000001, NULL},
1664 	{PMURES_BIT(RES4389_MISC_LDO),		RES_DEPEND_SET, 0x00000005, NULL},
1665 	{PMURES_BIT(RES4389_SERDES_AFE_RET),	RES_DEPEND_SET, 0x0000000d, NULL},
1666 	{PMURES_BIT(RES4389_XTAL_HQ),		RES_DEPEND_SET, 0x000000c5, NULL},
1667 	{PMURES_BIT(RES4389_XTAL_PU),		RES_DEPEND_SET, 0x00000005, NULL},
1668 	{PMURES_BIT(RES4389_XTAL_STABLE),	RES_DEPEND_SET, 0x00000045, NULL},
1669 	{PMURES_BIT(RES4389_PWRSW_DIG),		RES_DEPEND_SET, 0x060000dd, NULL},
1670 	{PMURES_BIT(RES4389_BTMC_TOP_RDY),	RES_DEPEND_SET, 0x000000cd, NULL},
1671 	{PMURES_BIT(RES4389_BTSC_TOP_RDY),	RES_DEPEND_SET, 0x000000c5, NULL},
1672 	{PMURES_BIT(RES4389_PWRSW_AUX),		RES_DEPEND_SET, 0x000000cd, NULL},
1673 	{PMURES_BIT(RES4389_PWRSW_SCAN),	RES_DEPEND_SET, 0x000000cd, NULL},
1674 	{PMURES_BIT(RES4389_CORE_RDY_SCAN),	RES_DEPEND_SET, 0x060211dd, NULL},
1675 	{PMURES_BIT(RES4389_PWRSW_MAIN),	RES_DEPEND_SET, 0x000000cd, NULL},
1676 	{PMURES_BIT(RES4389_RESERVED_15),	RES_DEPEND_SET, 0x00000000, NULL},
1677 	{PMURES_BIT(RES4389_RESERVED_16),	RES_DEPEND_SET, 0x00000000, NULL},
1678 	{PMURES_BIT(RES4389_CORE_RDY_DIG),	RES_DEPEND_SET, 0x060001dd, NULL},
1679 	{PMURES_BIT(RES4389_CORE_RDY_AUX),	RES_DEPEND_SET, 0x060209dd, NULL},
1680 	{PMURES_BIT(RES4389_ALP_AVAIL),		RES_DEPEND_SET, 0x000000c5, NULL},
1681 	{PMURES_BIT(RES4389_RADIO_PU_AUX),	RES_DEPEND_SET, 0x060609dd, NULL},
1682 	{PMURES_BIT(RES4389_RADIO_PU_SCAN),	RES_DEPEND_SET, 0x060231dd, NULL},
1683 	{PMURES_BIT(RES4389_CORE_RDY_MAIN),	RES_DEPEND_SET, 0x060241dd, NULL},
1684 	{PMURES_BIT(RES4389_RADIO_PU_MAIN),	RES_DEPEND_SET, 0x064241dd, NULL},
1685 	{PMURES_BIT(RES4389_MACPHY_CLK_SCAN),	RES_DEPEND_SET, 0x162a31fd, NULL},
1686 	{PMURES_BIT(RES4389_CORE_RDY_CB),	RES_DEPEND_SET, 0x040000dd, NULL},
1687 	{PMURES_BIT(RES4389_PWRSW_CB),		RES_DEPEND_SET, 0x000000dd, NULL},
1688 	{PMURES_BIT(RES4389_ARMCLKAVAIL),	RES_DEPEND_SET, 0x000800cd, NULL},
1689 	{PMURES_BIT(RES4389_HT_AVAIL),		RES_DEPEND_SET, 0x000800cd, NULL},
1690 	{PMURES_BIT(RES4389_MACPHY_CLK_AUX),	RES_DEPEND_SET, 0x161e09fd, NULL},
1691 	{PMURES_BIT(RES4389_MACPHY_CLK_MAIN),	RES_DEPEND_SET, 0x16ca41fd, NULL},
1692 };
1693 
1694 /** To enable avb timer clock feature */
si_pmu_avbtimer_enable(si_t * sih,osl_t * osh,bool set_flag)1695 void si_pmu_avbtimer_enable(si_t *sih, osl_t *osh, bool set_flag)
1696 {
1697 	uint32 min_mask = 0, max_mask = 0;
1698 	pmuregs_t *pmu;
1699 	uint origidx;
1700 
1701 	/* Remember original core before switch to chipc/pmu */
1702 	origidx = si_coreidx(sih);
1703 	if (AOB_ENAB(sih)) {
1704 		pmu = si_setcore(sih, PMU_CORE_ID, 0);
1705 	} else {
1706 		pmu = si_setcoreidx(sih, SI_CC_IDX);
1707 	}
1708 	ASSERT(pmu != NULL);
1709 
1710 	if ((CHIPID(sih->chip) == BCM4360_CHIP_ID || CHIPID(sih->chip) == BCM43460_CHIP_ID) &&
1711 		CHIPREV(sih->chiprev) >= 0x3) {
1712 		int cst_ht = CST4360_RSRC_INIT_MODE(sih->chipst) & 0x1;
1713 		if (cst_ht == 0) {
1714 			/* Enable the AVB timers for proxd feature */
1715 			min_mask = R_REG(osh, &pmu->min_res_mask);
1716 			max_mask = R_REG(osh, &pmu->max_res_mask);
1717 			if (set_flag) {
1718 				max_mask |= PMURES_BIT(RES4360_AVB_PLL_PWRSW_PU);
1719 				max_mask |= PMURES_BIT(RES4360_PCIE_TL_CLK_AVAIL);
1720 				min_mask |= PMURES_BIT(RES4360_AVB_PLL_PWRSW_PU);
1721 				min_mask |= PMURES_BIT(RES4360_PCIE_TL_CLK_AVAIL);
1722 				W_REG(osh, &pmu->min_res_mask, min_mask);
1723 				W_REG(osh, &pmu->max_res_mask, max_mask);
1724 			} else {
1725 				AND_REG(osh, &pmu->min_res_mask,
1726 					~PMURES_BIT(RES4360_AVB_PLL_PWRSW_PU));
1727 				AND_REG(osh, &pmu->min_res_mask,
1728 					~PMURES_BIT(RES4360_PCIE_TL_CLK_AVAIL));
1729 				AND_REG(osh, &pmu->max_res_mask,
1730 					~PMURES_BIT(RES4360_AVB_PLL_PWRSW_PU));
1731 				AND_REG(osh, &pmu->max_res_mask,
1732 					~PMURES_BIT(RES4360_PCIE_TL_CLK_AVAIL));
1733 			}
1734 			/* Need to wait 100 millisecond for the uptime */
1735 			OSL_DELAY(100);
1736 		}
1737 	}
1738 
1739 	/* Return to original core */
1740 	si_setcoreidx(sih, origidx);
1741 }
1742 
1743 /**
1744  * Determines min/max rsrc masks. Normally hardware contains these masks, and software reads the
1745  * masks from hardware. Note that masks are sometimes dependent on chip straps.
1746  */
1747 static void
si_pmu_res_masks(si_t * sih,uint32 * pmin,uint32 * pmax)1748 si_pmu_res_masks(si_t *sih, uint32 *pmin, uint32 *pmax)
1749 {
1750 	uint32 min_mask = 0, max_mask = 0;
1751 
1752 	/* determine min/max rsrc masks */
1753 	switch (CHIPID(sih->chip)) {
1754 	case BCM4360_CHIP_ID:
1755 	case BCM4352_CHIP_ID:
1756 		if (CHIPREV(sih->chiprev) >= 0x4) {
1757 			min_mask = 0x103;
1758 		}
1759 		/* Continue - Don't break */
1760 	case BCM43460_CHIP_ID:
1761 	case BCM43526_CHIP_ID:
1762 		if (CHIPREV(sih->chiprev) >= 0x3) {
1763 			/* PR 110203 */
1764 			int cst_ht = CST4360_RSRC_INIT_MODE(sih->chipst) & 0x1;
1765 			if (cst_ht == 0)
1766 				max_mask = 0x1ff;
1767 		}
1768 		break;
1769 
1770 	CASE_BCM43602_CHIP:
1771 		/* as a bare minimum, have ALP clock running */
1772 		min_mask = PMURES_BIT(RES43602_LPLDO_PU)  | PMURES_BIT(RES43602_REGULATOR)      |
1773 			PMURES_BIT(RES43602_PMU_SLEEP)    | PMURES_BIT(RES43602_XTALLDO_PU)     |
1774 			PMURES_BIT(RES43602_SERDES_PU)    | PMURES_BIT(RES43602_BBPLL_PWRSW_PU) |
1775 			PMURES_BIT(RES43602_SR_CLK_START) | PMURES_BIT(RES43602_SR_PHY_PWRSW)   |
1776 			PMURES_BIT(RES43602_SR_SUBCORE_PWRSW) | PMURES_BIT(RES43602_XTAL_PU)    |
1777 			PMURES_BIT(RES43602_PERST_OVR)    | PMURES_BIT(RES43602_SR_CLK_STABLE)  |
1778 			PMURES_BIT(RES43602_SR_SAVE_RESTORE) | PMURES_BIT(RES43602_SR_SLEEP)    |
1779 			PMURES_BIT(RES43602_LQ_START)     | PMURES_BIT(RES43602_LQ_AVAIL)       |
1780 			PMURES_BIT(RES43602_WL_CORE_RDY)  |
1781 			PMURES_BIT(RES43602_ALP_AVAIL);
1782 
1783 		if (sih->chippkg == BCM43602_12x12_PKG_ID) /* LPLDO WAR */
1784 			min_mask &= ~PMURES_BIT(RES43602_LPLDO_PU);
1785 
1786 		max_mask = (1<<3) | min_mask          | PMURES_BIT(RES43602_RADIO_PU)        |
1787 			PMURES_BIT(RES43602_RFLDO_PU) | PMURES_BIT(RES43602_HT_START)        |
1788 			PMURES_BIT(RES43602_HT_AVAIL) | PMURES_BIT(RES43602_MACPHY_CLKAVAIL);
1789 
1790 #if defined(SAVERESTORE)
1791 		/* min_mask is updated after SR code is downloaded to txfifo */
1792 		if (SR_ENAB() && sr_isenab(sih)) {
1793 			ASSERT(sih->chippkg != BCM43602_12x12_PKG_ID);
1794 			min_mask = PMURES_BIT(RES43602_LPLDO_PU);
1795 		}
1796 #endif /* SAVERESTORE */
1797 		break;
1798 
1799 	case BCM43012_CHIP_ID:
1800 	case BCM43013_CHIP_ID:
1801 	case BCM43014_CHIP_ID:
1802 		/* Set the bits for all resources in the max mask except for the SR Engine */
1803 		max_mask = 0x7FFFFFFF;
1804 		break;
1805 	case BCM4369_CHIP_GRPID:
1806 		min_mask = 0x64fffff;
1807 #if defined(SAVERESTORE)
1808 		if (SR_ENAB() && sr_isenab(sih)) {
1809 			if (si_get_nvram_rfldo3p3_war(sih)) {
1810 				min_mask = 0x0000011;
1811 			} else {
1812 				min_mask = 0x0000001;
1813 			}
1814 		}
1815 #endif /* SAVERESTORE */
1816 		max_mask = 0x7FFFFFFF;
1817 		break;
1818 	case BCM4376_CHIP_GRPID:
1819 	case BCM4378_CHIP_GRPID:
1820 		min_mask = 0x064fffff;
1821 #if defined(SAVERESTORE)
1822 		if (SR_ENAB()) {
1823 			if (!sr_isenab(sih)) {
1824 				min_mask = 0x064fffff;
1825 			} else {
1826 				min_mask = PMURES_BIT(RES4378_DUMMY);
1827 			}
1828 		}
1829 #endif /* SAVERESTORE */
1830 		max_mask = 0x7FFFFFFF;
1831 		break;
1832 	case BCM4385_CHIP_GRPID:
1833 	case BCM4387_CHIP_GRPID:
1834 		min_mask = 0x64fffff;
1835 #if defined(SAVERESTORE)
1836 		if (SR_ENAB()) {
1837 			if (sr_isenab(sih)) {
1838 				min_mask = PMURES_BIT(RES4387_DUMMY);
1839 			} else {
1840 				min_mask = pmu_corereg(sih, SI_CC_IDX, min_res_mask, 0, 0);
1841 				if (PMU_FLL_PU_ENAB()) {
1842 					min_mask |= PMURES_BIT(RES4387_FAST_LPO_AVAIL) |
1843 						PMURES_BIT(RES4387_PMU_LP);
1844 				}
1845 			}
1846 		}
1847 #endif /* SAVERESTORE */
1848 
1849 		max_mask = 0x7FFFFFFF;
1850 		break;
1851 
1852 	case BCM4388_CHIP_GRPID:
1853 		min_mask = 0x64fffff;
1854 #if defined(SAVERESTORE)
1855 		if (SR_ENAB()) {
1856 			if (sr_isenab(sih)) {
1857 				min_mask = PMURES_BIT(RES4388_DUMMY);
1858 			} else {
1859 				min_mask = pmu_corereg(sih, SI_CC_IDX, min_res_mask, 0, 0);
1860 				if (PMU_FLL_PU_ENAB()) {
1861 					min_mask |= PMURES_BIT(RES4388_FAST_LPO_AVAIL) |
1862 						PMURES_BIT(RES4388_PMU_LP);
1863 				}
1864 			}
1865 		}
1866 #endif /* SAVERESTORE */
1867 		max_mask = 0x7FFFFFFF;
1868 		break;
1869 
1870 	case BCM4389_CHIP_GRPID:
1871 		/*
1872 		 * check later if this can be replaced with chip default value read from
1873 		 * PMU register - min_res_mask and remove the code in SR_ENAB() portion
1874 		 */
1875 		min_mask = 0x64fffff;
1876 #if defined(SAVERESTORE)
1877 		if (SR_ENAB()) {
1878 			if (sr_isenab(sih)) {
1879 				min_mask = PMURES_BIT(RES4389_DUMMY);
1880 			} else {
1881 				min_mask = pmu_corereg(sih, SI_CC_IDX, min_res_mask, 0, 0);
1882 				if (PMU_FLL_PU_ENAB()) {
1883 					min_mask |= PMURES_BIT(RES4389_FAST_LPO_AVAIL) |
1884 						PMURES_BIT(RES4389_PMU_LP);
1885 				}
1886 			}
1887 		}
1888 #endif /* SAVERESTORE */
1889 		max_mask = 0x7FFFFFFF;
1890 		break;
1891 
1892 	case BCM4397_CHIP_GRPID:
1893 		min_mask = 0x64fffff;
1894 		max_mask = 0x7FFFFFFF;
1895 	break;
1896 
1897 	case BCM4362_CHIP_GRPID:
1898 		min_mask = 0x64fffff;
1899 #if defined(SAVERESTORE)
1900 		if (SR_ENAB() && sr_isenab(sih)) {
1901 			min_mask = (PMURES_BIT(RES4362_DUMMY));
1902 		}
1903 #endif /* SAVERESTORE */
1904 		max_mask = 0x7FFFFFFF;
1905 		break;
1906 
1907 	default:
1908 		PMU_ERROR(("MIN and MAX mask is not programmed\n"));
1909 		break;
1910 	}
1911 
1912 	if (!FWSIGN_ENAB()) {
1913 		/* nvram override */
1914 		si_nvram_res_masks(sih, &min_mask, &max_mask);
1915 	}
1916 
1917 	*pmin = min_mask;
1918 	*pmax = max_mask;
1919 } /* si_pmu_res_masks */
1920 
1921 /**
1922  * resource dependencies can change because of the host interface
1923  * selected, to work around an issue, or for more optimal power
1924  * savings after tape out
1925  */
1926 #ifdef DUAL_PMU_SEQUENCE
1927 static void
si_pmu_resdeptbl_upd(si_t * sih,osl_t * osh,pmuregs_t * pmu,const pmu_res_depend_t * restable,uint tablesz)1928 si_pmu_resdeptbl_upd(si_t *sih, osl_t *osh, pmuregs_t *pmu,
1929 	const pmu_res_depend_t *restable, uint tablesz)
1930 #else
1931 static void
1932 BCMATTACHFN(si_pmu_resdeptbl_upd)(si_t *sih, osl_t *osh, pmuregs_t *pmu,
1933 	const pmu_res_depend_t *restable, uint tablesz)
1934 #endif /* DUAL_PMU_SEQUENCE */
1935 {
1936 	uint i, rsrcs;
1937 
1938 	if (tablesz == 0)
1939 		return;
1940 
1941 	ASSERT(restable != NULL);
1942 
1943 	rsrcs = (sih->pmucaps & PCAP_RC_MASK) >> PCAP_RC_SHIFT;
1944 	/* Program resource dependencies table */
1945 	while (tablesz--) {
1946 		if (restable[tablesz].filter != NULL &&
1947 		    !(restable[tablesz].filter)(sih))
1948 			continue;
1949 		for (i = 0; i < rsrcs; i ++) {
1950 			if ((restable[tablesz].res_mask &
1951 			     PMURES_BIT(i)) == 0)
1952 				continue;
1953 			W_REG(osh, &pmu->res_table_sel, i);
1954 			switch (restable[tablesz].action) {
1955 				case RES_DEPEND_SET:
1956 					PMU_MSG(("Changing rsrc %d res_dep_mask to 0x%x\n", i,
1957 						restable[tablesz].depend_mask));
1958 					W_REG(osh, &pmu->res_dep_mask,
1959 					      restable[tablesz].depend_mask);
1960 					break;
1961 				case RES_DEPEND_ADD:
1962 					PMU_MSG(("Adding 0x%x to rsrc %d res_dep_mask\n",
1963 						restable[tablesz].depend_mask, i));
1964 					OR_REG(osh, &pmu->res_dep_mask,
1965 					       restable[tablesz].depend_mask);
1966 					break;
1967 				case RES_DEPEND_REMOVE:
1968 					PMU_MSG(("Removing 0x%x from rsrc %d res_dep_mask\n",
1969 						restable[tablesz].depend_mask, i));
1970 					AND_REG(osh, &pmu->res_dep_mask,
1971 						~restable[tablesz].depend_mask);
1972 					break;
1973 				default:
1974 					ASSERT(0);
1975 					break;
1976 			}
1977 		}
1978 	}
1979 } /* si_pmu_resdeptbl_upd */
1980 
1981 static void
BCMATTACHFN(si_pmu_dep_table_fll_pu_fixup)1982 BCMATTACHFN(si_pmu_dep_table_fll_pu_fixup)(si_t *sih, osl_t *osh,
1983 	pmu_res_depend_t *pmu_res_depend_table, uint pmu_res_depend_table_sz)
1984 {
1985 	uint i;
1986 
1987 	if (!PMU_FLL_PU_ENAB()) {
1988 		return;
1989 	}
1990 
1991 	switch (CHIPID(sih->chip)) {
1992 	case BCM4387_CHIP_GRPID:
1993 		for (i = 0; i < pmu_res_depend_table_sz; i ++) {
1994 			if (pmu_res_depend_table[i].res_mask ==
1995 				PMURES_BIT(RES4387_FAST_LPO_AVAIL)) {
1996 				pmu_res_depend_table[i].depend_mask = PMURES_BIT(RES4387_DUMMY) |
1997 					PMURES_BIT(RES4387_PMU_LP);
1998 			} else if ((pmu_res_depend_table[i].res_mask !=
1999 					PMURES_BIT(RES4387_DUMMY)) &&
2000 				(pmu_res_depend_table[i].res_mask !=
2001 					PMURES_BIT(RES4387_PMU_LP)) &&
2002 				(pmu_res_depend_table[i].res_mask !=
2003 					PMURES_BIT(RES4387_RESERVED_16))) {
2004 				pmu_res_depend_table[i].depend_mask |=
2005 					PMURES_BIT(RES4387_FAST_LPO_AVAIL);
2006 			}
2007 		}
2008 		break;
2009 	case BCM4388_CHIP_GRPID:
2010 		for (i = 0; i < pmu_res_depend_table_sz; i ++) {
2011 			if (pmu_res_depend_table[i].res_mask ==
2012 				PMURES_BIT(RES4388_FAST_LPO_AVAIL)) {
2013 				pmu_res_depend_table[i].depend_mask = PMURES_BIT(RES4388_DUMMY) |
2014 					PMURES_BIT(RES4388_PMU_LP);
2015 			} else if ((pmu_res_depend_table[i].res_mask !=
2016 					PMURES_BIT(RES4388_DUMMY)) &&
2017 				(pmu_res_depend_table[i].res_mask !=
2018 					PMURES_BIT(RES4388_PMU_LP)) &&
2019 				(pmu_res_depend_table[i].res_mask !=
2020 					PMURES_BIT(RES4388_RESERVED_15)) &&
2021 				(pmu_res_depend_table[i].res_mask !=
2022 					PMURES_BIT(RES4388_RESERVED_16))) {
2023 				pmu_res_depend_table[i].depend_mask |=
2024 					PMURES_BIT(RES4388_FAST_LPO_AVAIL);
2025 			}
2026 		}
2027 		break;
2028 	case BCM4389_CHIP_GRPID:
2029 		for (i = 0; i < pmu_res_depend_table_sz; i ++) {
2030 			if (pmu_res_depend_table[i].res_mask ==
2031 				PMURES_BIT(RES4389_FAST_LPO_AVAIL)) {
2032 				pmu_res_depend_table[i].depend_mask = PMURES_BIT(RES4389_DUMMY) |
2033 					PMURES_BIT(RES4389_PMU_LP);
2034 			} else if ((pmu_res_depend_table[i].res_mask !=
2035 					PMURES_BIT(RES4389_DUMMY)) &&
2036 				(pmu_res_depend_table[i].res_mask !=
2037 					PMURES_BIT(RES4389_PMU_LP)) &&
2038 				(pmu_res_depend_table[i].res_mask !=
2039 					PMURES_BIT(RES4389_RESERVED_16))) {
2040 				pmu_res_depend_table[i].depend_mask |=
2041 					PMURES_BIT(RES4389_FAST_LPO_AVAIL);
2042 			}
2043 		}
2044 		break;
2045 	default:
2046 		PMU_MSG(("si_pmu_dep_table_fll_pu_fixup: unsupported chip!\n"));
2047 		ASSERT(0);
2048 		break;
2049 	}
2050 }
2051 
2052 /** Initialize PMU hardware resources. */
2053 void
BCMATTACHFN(si_pmu_res_init)2054 BCMATTACHFN(si_pmu_res_init)(si_t *sih, osl_t *osh)
2055 {
2056 	pmuregs_t *pmu;
2057 	uint origidx;
2058 	const pmu_res_updown_t *pmu_res_updown_table = NULL;
2059 	uint pmu_res_updown_table_sz = 0;
2060 	const pmu_res_subst_trans_tmr_t *pmu_res_subst_trans_tmr_table = NULL;
2061 	uint pmu_res_subst_trans_tmr_table_sz = 0;
2062 	pmu_res_depend_t *pmu_res_depend_table = NULL;
2063 	uint pmu_res_depend_table_sz = 0;
2064 #ifndef BCM_BOOTLOADER
2065 	const pmu_res_depend_t *pmu_res_depend_pciewar_table[2] = {NULL, NULL};
2066 	uint pmu_res_depend_pciewar_table_sz[2] = {0, 0};
2067 #endif /* BCM_BOOTLOADER */
2068 	uint32 min_mask = 0, max_mask = 0;
2069 	char name[8];
2070 	const char *val;
2071 	uint i, rsrcs;
2072 	uint8   fastlpo_dis = fastlpo_dis_get();
2073 	uint8   fastlpo_pcie_dis = fastlpo_pcie_dis_get();
2074 
2075 	ASSERT(sih->cccaps & CC_CAP_PMU);
2076 
2077 	/* Remember original core before switch to chipc/pmu */
2078 	origidx = si_coreidx(sih);
2079 	if (AOB_ENAB(sih)) {
2080 		pmu = si_setcore(sih, PMU_CORE_ID, 0);
2081 	} else {
2082 		pmu = si_setcoreidx(sih, SI_CC_IDX);
2083 	}
2084 	ASSERT(pmu != NULL);
2085 
2086 	/*
2087 	 * Hardware contains the resource updown and dependency tables. Only if a chip has a
2088 	 * hardware problem, software tables can be used to override hardware tables.
2089 	 */
2090 	switch (CHIPID(sih->chip)) {
2091 	case BCM4360_CHIP_ID:
2092 	case BCM4352_CHIP_ID:
2093 		if (CHIPREV(sih->chiprev) < 4) {
2094 			pmu_res_updown_table = bcm4360_res_updown;
2095 			pmu_res_updown_table_sz = ARRAYSIZE(bcm4360_res_updown);
2096 		} else {
2097 			/* FOR 4360B1 */
2098 			pmu_res_updown_table = bcm4360B1_res_updown;
2099 			pmu_res_updown_table_sz = ARRAYSIZE(bcm4360B1_res_updown);
2100 		}
2101 		break;
2102 	CASE_BCM43602_CHIP:
2103 		pmu_res_updown_table = bcm43602_res_updown;
2104 		pmu_res_updown_table_sz = ARRAYSIZE(bcm43602_res_updown);
2105 		pmu_res_depend_table = bcm43602_res_depend;
2106 		pmu_res_depend_table_sz = ARRAYSIZE(bcm43602_res_depend);
2107 #ifndef BCM_BOOTLOADER
2108 		pmu_res_depend_pciewar_table[0] = bcm43602_res_pciewar;
2109 		pmu_res_depend_pciewar_table_sz[0] = ARRAYSIZE(bcm43602_res_pciewar);
2110 		if (sih->chippkg == BCM43602_12x12_PKG_ID) { /* LPLDO WAR */
2111 			pmu_res_depend_pciewar_table[1] = bcm43602_12x12_res_depend;
2112 			pmu_res_depend_pciewar_table_sz[1] = ARRAYSIZE(bcm43602_12x12_res_depend);
2113 		}
2114 #endif /* !BCM_BOOTLOADER */
2115 		break;
2116 	case BCM43012_CHIP_ID:
2117 	case BCM43013_CHIP_ID:
2118 	case BCM43014_CHIP_ID:
2119 		pmu_res_updown_table = bcm43012a0_res_updown_ds0;
2120 		pmu_res_updown_table_sz = ARRAYSIZE(bcm43012a0_res_updown_ds0);
2121 		pmu_res_depend_table = bcm43012a0_res_depend_ds0;
2122 		pmu_res_depend_table_sz = ARRAYSIZE(bcm43012a0_res_depend_ds0);
2123 		break;
2124 	case BCM4369_CHIP_GRPID:
2125 		/* fastlpo_dis is override for PMU1M, updown times are updated accordingly
2126 		 * if PMU 1M is enabled only Resource Up/Down times are changed
2127 		 * Also the Up/Down times are different for A0 and B0
2128 		 */
2129 		if (fastlpo_dis) {
2130 			/* Only Resource Up/Down times are different b/w A0 and B0 */
2131 			if (CHIPREV(sih->chiprev) == 0) {
2132 				pmu_res_updown_table = bcm4369a0_res_updown;
2133 				pmu_res_updown_table_sz = ARRAYSIZE(bcm4369a0_res_updown);
2134 			} else {
2135 				pmu_res_updown_table = bcm4369b0_res_updown;
2136 				pmu_res_updown_table_sz = ARRAYSIZE(bcm4369b0_res_updown);
2137 			}
2138 		} else {
2139 			if (fastlpo_pcie_dis) {
2140 				PMU_ERROR(("INVALID: PCIE 1MHz disabled but PMU 1MHz enabled\n"));
2141 				ASSERT(0);
2142 			}
2143 			/* Only Resource Up/Down times are different b/w A0 and B0 */
2144 			if (CHIPREV(sih->chiprev) == 0) {
2145 				pmu_res_updown_table = bcm4369a0_res_updown_fastlpo_pmu;
2146 				pmu_res_updown_table_sz =
2147 					ARRAYSIZE(bcm4369a0_res_updown_fastlpo_pmu);
2148 			} else {
2149 				pmu_res_updown_table = bcm4369b0_res_updown_fastlpo_pmu;
2150 				pmu_res_updown_table_sz =
2151 					ARRAYSIZE(bcm4369b0_res_updown_fastlpo_pmu);
2152 			}
2153 		}
2154 
2155 		/* fastlpo_pcie_dis is override for PCIE1M, resource dependencies are updated
2156 		 * if pcie 1M is enabled resource dependency are different
2157 		 * for A0 and B0  chiprev there is no resource dependency change
2158 		 */
2159 		if (fastlpo_pcie_dis) {
2160 			pmu_res_depend_table = bcm4369a0_res_depend;
2161 			pmu_res_depend_table_sz = ARRAYSIZE(bcm4369a0_res_depend);
2162 		} else {
2163 			pmu_res_depend_table = bcm4369a0_res_depend_fastlpo_pcie;
2164 			pmu_res_depend_table_sz = ARRAYSIZE(bcm4369a0_res_depend_fastlpo_pcie);
2165 		}
2166 		break;
2167 
2168 	case BCM4362_CHIP_GRPID:
2169 		pmu_res_updown_table = bcm4362_res_updown;
2170 		pmu_res_updown_table_sz = ARRAYSIZE(bcm4362_res_updown);
2171 
2172 		GCI_REG_NEW(sih, bt_smem_control1, (0xFF<<16), 0);
2173 
2174 		si_pmu_chipcontrol(sih, PMU_CHIPCTL14,
2175 			(PMU_CC14_MAIN_VDDB2VDDRET_UP_DLY_MASK |
2176 			PMU_CC14_MAIN_VDDB2VDD_UP_DLY_MASK |
2177 			PMU_CC14_AUX_VDDB2VDDRET_UP_DLY_MASK |
2178 			PMU_CC14_AUX_VDDB2VDD_UP_DLY_MASK |
2179 			PMU_CC14_PCIE_VDDB2VDDRET_UP_DLY_MASK |
2180 			PMU_CC14_PCIE_VDDB2VDD_UP_DLY_MASK), 0);
2181 
2182 		si_pmu_chipcontrol(sih, PMU_CHIPCTL15,
2183 			(PMU_CC15_PCIE_VDDB_CURRENT_LIMIT_DELAY_MASK |
2184 			PMU_CC15_PCIE_VDDB_FORCE_RPS_PWROK_DELAY_MASK), 0);
2185 
2186 		si_pmu_chipcontrol(sih, PMU_CHIPCTL10,
2187 			(PMU_CC10_PCIE_RESET0_CNT_SLOW_MASK |
2188 			PMU_CC10_PCIE_RESET1_CNT_SLOW_MASK), 0);
2189 
2190 		GCI_REG_NEW(sih, bt_smem_control0, (0xF<<16), 0);
2191 		GCI_REG_NEW(sih, bt_smem_control0, (0xF<<24), 0);
2192 
2193 		pmu_res_depend_table = bcm4362_res_depend;
2194 		pmu_res_depend_table_sz = ARRAYSIZE(bcm4362_res_depend);
2195 		break;
2196 
2197 	case BCM4376_CHIP_GRPID:
2198 	case BCM4378_CHIP_GRPID:
2199 		if (SR_ENAB()) {
2200 			pmu_res_updown_table = bcm4378b0_res_updown;
2201 			pmu_res_updown_table_sz = ARRAYSIZE(bcm4378b0_res_updown);
2202 			pmu_res_depend_table = bcm4378b0_res_depend;
2203 			pmu_res_depend_table_sz = ARRAYSIZE(bcm4378b0_res_depend);
2204 		}
2205 		break;
2206 
2207 	case BCM4385_CHIP_GRPID:
2208 	case BCM4387_CHIP_GRPID:
2209 		if (SR_ENAB()) {
2210 			if (ISSIM_ENAB(sih)) {
2211 				if (PMUREV(sih->pmurev) == 39) {
2212 					pmu_res_updown_table = bcm4387c0_res_updown;
2213 					pmu_res_updown_table_sz =
2214 						ARRAYSIZE(bcm4387c0_res_updown);
2215 
2216 					pmu_res_subst_trans_tmr_table =
2217 						bcm4387c0_res_subst_trans_tmr;
2218 					pmu_res_subst_trans_tmr_table_sz =
2219 						ARRAYSIZE(bcm4387c0_res_subst_trans_tmr);
2220 
2221 					pmu_res_depend_table = bcm4387c0_res_depend;
2222 					pmu_res_depend_table_sz = ARRAYSIZE(bcm4387c0_res_depend);
2223 				} else {
2224 					pmu_res_updown_table = bcm4387b0_res_updown_qt;
2225 					pmu_res_updown_table_sz =
2226 						ARRAYSIZE(bcm4387b0_res_updown_qt);
2227 
2228 					pmu_res_subst_trans_tmr_table =
2229 						bcm4387b0_res_subst_trans_tmr_qt;
2230 					pmu_res_subst_trans_tmr_table_sz =
2231 						ARRAYSIZE(bcm4387b0_res_subst_trans_tmr_qt);
2232 
2233 					pmu_res_depend_table = bcm4387b0_res_depend;
2234 					pmu_res_depend_table_sz = ARRAYSIZE(bcm4387b0_res_depend);
2235 				}
2236 			} else {
2237 				if (PMUREV(sih->pmurev) == 39) {
2238 					if (BCMSRTOPOFF_ENAB()) {
2239 						pmu_res_updown_table = bcm4387c0_res_updown_topoff;
2240 						pmu_res_updown_table_sz =
2241 							ARRAYSIZE(bcm4387c0_res_updown_topoff);
2242 					} else {
2243 						pmu_res_updown_table = bcm4387c0_res_updown;
2244 						pmu_res_updown_table_sz =
2245 							ARRAYSIZE(bcm4387c0_res_updown);
2246 					}
2247 
2248 					pmu_res_subst_trans_tmr_table =
2249 						bcm4387c0_res_subst_trans_tmr;
2250 					pmu_res_subst_trans_tmr_table_sz =
2251 						ARRAYSIZE(bcm4387c0_res_subst_trans_tmr);
2252 
2253 					pmu_res_depend_table = bcm4387c0_res_depend;
2254 					pmu_res_depend_table_sz = ARRAYSIZE(bcm4387c0_res_depend);
2255 
2256 					if (PMU_FLL_PU_ENAB()) {
2257 						si_pmu_dep_table_fll_pu_fixup(sih, osh,
2258 							pmu_res_depend_table,
2259 							pmu_res_depend_table_sz);
2260 					}
2261 				} else {
2262 					pmu_res_updown_table = bcm4387b0_res_updown;
2263 					pmu_res_updown_table_sz = ARRAYSIZE(bcm4387b0_res_updown);
2264 
2265 					pmu_res_subst_trans_tmr_table =
2266 						bcm4387b0_res_subst_trans_tmr;
2267 					pmu_res_subst_trans_tmr_table_sz =
2268 						ARRAYSIZE(bcm4387b0_res_subst_trans_tmr);
2269 
2270 					pmu_res_depend_table = bcm4387b0_res_depend;
2271 					pmu_res_depend_table_sz = ARRAYSIZE(bcm4387b0_res_depend);
2272 				}
2273 			}
2274 		}
2275 		break;
2276 
2277 	case BCM4388_CHIP_GRPID:
2278 		if (SR_ENAB()) {
2279 			if (ISSIM_ENAB(sih)) {
2280 				pmu_res_updown_table = bcm4388a0_res_updown_qt;
2281 				pmu_res_updown_table_sz = ARRAYSIZE(bcm4388a0_res_updown_qt);
2282 
2283 				pmu_res_subst_trans_tmr_table = bcm4388a0_res_subst_trans_tmr_qt;
2284 				pmu_res_subst_trans_tmr_table_sz =
2285 					ARRAYSIZE(bcm4388a0_res_subst_trans_tmr_qt);
2286 			} else {
2287 				pmu_res_updown_table = bcm4388a0_res_updown;
2288 				pmu_res_updown_table_sz = ARRAYSIZE(bcm4388a0_res_updown);
2289 
2290 				pmu_res_subst_trans_tmr_table = bcm4388a0_res_subst_trans_tmr;
2291 				pmu_res_subst_trans_tmr_table_sz =
2292 					ARRAYSIZE(bcm4388a0_res_subst_trans_tmr);
2293 			}
2294 
2295 			pmu_res_depend_table = bcm4388a0_res_depend;
2296 			pmu_res_depend_table_sz = ARRAYSIZE(bcm4388a0_res_depend);
2297 
2298 			if (PMU_FLL_PU_ENAB()) {
2299 				si_pmu_dep_table_fll_pu_fixup(sih, osh,
2300 					pmu_res_depend_table,
2301 					pmu_res_depend_table_sz);
2302 			}
2303 		}
2304 		break;
2305 
2306 	case BCM4389_CHIP_GRPID:
2307 		if (SR_ENAB()) {
2308 			if (ISSIM_ENAB(sih)) {
2309 				pmu_res_updown_table = bcm4389b0_res_updown_qt;
2310 				pmu_res_updown_table_sz = ARRAYSIZE(bcm4389b0_res_updown_qt);
2311 
2312 				pmu_res_subst_trans_tmr_table = bcm4389b0_res_subst_trans_tmr_qt;
2313 				pmu_res_subst_trans_tmr_table_sz =
2314 					ARRAYSIZE(bcm4389b0_res_subst_trans_tmr_qt);
2315 			} else {
2316 				pmu_res_updown_table = bcm4389b0_res_updown;
2317 				pmu_res_updown_table_sz = ARRAYSIZE(bcm4389b0_res_updown);
2318 
2319 				pmu_res_subst_trans_tmr_table = bcm4389b0_res_subst_trans_tmr;
2320 				pmu_res_subst_trans_tmr_table_sz =
2321 					ARRAYSIZE(bcm4389b0_res_subst_trans_tmr);
2322 			}
2323 
2324 			pmu_res_depend_table = bcm4389b0_res_depend;
2325 			pmu_res_depend_table_sz = ARRAYSIZE(bcm4389b0_res_depend);
2326 			if (PMU_FLL_PU_ENAB()) {
2327 				si_pmu_dep_table_fll_pu_fixup(sih, osh,
2328 					pmu_res_depend_table, pmu_res_depend_table_sz);
2329 			}
2330 		}
2331 		break;
2332 
2333 	default:
2334 		break;
2335 	}
2336 
2337 	/* Program up/down timers */
2338 	while (pmu_res_updown_table_sz--) {
2339 		ASSERT(pmu_res_updown_table != NULL);
2340 		PMU_MSG(("Changing rsrc %d res_updn_timer to 0x%x\n",
2341 		         pmu_res_updown_table[pmu_res_updown_table_sz].resnum,
2342 		         pmu_res_updown_table[pmu_res_updown_table_sz].updown));
2343 		W_REG(osh, &pmu->res_table_sel,
2344 		      pmu_res_updown_table[pmu_res_updown_table_sz].resnum);
2345 		W_REG(osh, &pmu->res_updn_timer,
2346 		      pmu_res_updown_table[pmu_res_updown_table_sz].updown);
2347 	}
2348 
2349 	if (!FWSIGN_ENAB()) {
2350 		/* # resources */
2351 		rsrcs = (sih->pmucaps & PCAP_RC_MASK) >> PCAP_RC_SHIFT;
2352 
2353 		/* Apply nvram overrides to up/down timers */
2354 		for (i = 0; i < rsrcs; i ++) {
2355 			uint32 r_val;
2356 			snprintf(name, sizeof(name), rstr_rDt, i);
2357 			if ((val = getvar(NULL, name)) == NULL)
2358 				continue;
2359 			r_val = (uint32)bcm_strtoul(val, NULL, 0);
2360 			/* PMUrev = 13, pmu resource updown times are 12 bits(0:11 DT, 16:27 UT) */
2361 			/* OLD values are 8 bits for UT/DT, handle the old nvram format */
2362 			if (PMUREV(sih->pmurev) >= 13) {
2363 				if (r_val < (1 << 16)) {
2364 					uint16 up_time = (r_val >> 8) & 0xFF;
2365 					r_val &= 0xFF;
2366 					r_val |= (up_time << 16);
2367 				}
2368 			}
2369 			PMU_MSG(("Applying %s=%s to rsrc %d res_updn_timer\n", name, val, i));
2370 			W_REG(osh, &pmu->res_table_sel, (uint32)i);
2371 			W_REG(osh, &pmu->res_updn_timer, r_val);
2372 		}
2373 	}
2374 
2375 	/* Program Rsrc Substate Transition Timer */
2376 	while (pmu_res_subst_trans_tmr_table_sz --) {
2377 		ASSERT(pmu_res_subst_trans_tmr_table != NULL);
2378 		PMU_MSG(("Changing rsrc %d substate %d res_subst_trans_timer to 0x%x\n",
2379 			pmu_res_subst_trans_tmr_table[pmu_res_subst_trans_tmr_table_sz].resnum,
2380 			pmu_res_subst_trans_tmr_table[pmu_res_subst_trans_tmr_table_sz].substate,
2381 			pmu_res_subst_trans_tmr_table[pmu_res_subst_trans_tmr_table_sz].tmr));
2382 		W_REG(osh, &pmu->res_table_sel,
2383 			pmu_res_subst_trans_tmr_table[pmu_res_subst_trans_tmr_table_sz].resnum |
2384 			(pmu_res_subst_trans_tmr_table[pmu_res_subst_trans_tmr_table_sz].substate
2385 			<< PMU_RES_SUBSTATE_SHIFT));
2386 		W_REG(osh, &pmu->rsrc_substate_trans_tmr,
2387 			pmu_res_subst_trans_tmr_table[pmu_res_subst_trans_tmr_table_sz].tmr);
2388 	}
2389 
2390 	/* Program resource dependencies table */
2391 	si_pmu_resdeptbl_upd(sih, osh, pmu, pmu_res_depend_table, pmu_res_depend_table_sz);
2392 
2393 	if (!FWSIGN_ENAB()) {
2394 		/* Apply nvram overrides to dependencies masks */
2395 		for (i = 0; i < rsrcs; i ++) {
2396 			snprintf(name, sizeof(name), rstr_rDd, i);
2397 			if ((val = getvar(NULL, name)) == NULL)
2398 				continue;
2399 			PMU_MSG(("Applying %s=%s to rsrc %d res_dep_mask\n", name, val, i));
2400 			W_REG(osh, &pmu->res_table_sel, (uint32)i);
2401 			W_REG(osh, &pmu->res_dep_mask, (uint32)bcm_strtoul(val, NULL, 0));
2402 		}
2403 	}
2404 
2405 #if !defined(BCM_BOOTLOADER)
2406 	/* Initial any chip interface dependent PMU rsrc by looking at the
2407 	 * chipstatus register to figure the selected interface
2408 	 */
2409 	/* this should be a general change to cover all the chips.
2410 	 * this also should validate the build where the dongle is
2411 	 * built for SDIO but downloaded on PCIE dev
2412 	 */
2413 	if (BUSTYPE(sih->bustype) == PCI_BUS || BUSTYPE(sih->bustype) == SI_BUS) {
2414 		bool is_pciedev = BCM43602_CHIP(sih->chip);
2415 
2416 		for (i = 0; i < ARRAYSIZE(pmu_res_depend_pciewar_table); i++) {
2417 			if (is_pciedev && pmu_res_depend_pciewar_table[i] &&
2418 			    pmu_res_depend_pciewar_table_sz[i]) {
2419 				si_pmu_resdeptbl_upd(sih, osh, pmu,
2420 					pmu_res_depend_pciewar_table[i],
2421 					pmu_res_depend_pciewar_table_sz[i]);
2422 			}
2423 		}
2424 	}
2425 #endif /* !BCM_BOOTLOADER */
2426 	/* Determine min/max rsrc masks */
2427 	si_pmu_res_masks(sih, &min_mask, &max_mask);
2428 	/* Add min mask dependencies */
2429 	min_mask |= si_pmu_res_deps(sih, osh, pmu, min_mask, FALSE);
2430 
2431 #ifdef BCM_BOOTLOADER
2432 	/* Apply nvram override to max mask */
2433 	if ((val = getvar(NULL, "brmax")) != NULL) {
2434 		PMU_MSG(("Applying brmax=%s to max_res_mask\n", val));
2435 		max_mask = (uint32)bcm_strtoul(val, NULL, 0);
2436 	}
2437 
2438 	/* Apply nvram override to min mask */
2439 	if ((val = getvar(NULL, "brmin")) != NULL) {
2440 		PMU_MSG(("Applying brmin=%s to min_res_mask\n", val));
2441 		min_mask = (uint32)bcm_strtoul(val, NULL, 0);
2442 	}
2443 #endif /* BCM_BOOTLOADER */
2444 
2445 	/* apply new PLL setting if is ALP strap (need to close out
2446 	 * if possible apply if is HT strap)
2447 	 */
2448 	if (((CHIPID(sih->chip) == BCM4360_CHIP_ID) || (CHIPID(sih->chip) == BCM4352_CHIP_ID)) &&
2449 	    (CHIPREV(sih->chiprev) < 4) &&
2450 	    ((CST4360_RSRC_INIT_MODE(sih->chipst) & 1) == 0)) {
2451 		/* BBPLL */
2452 		si_pmu_pllcontrol(sih, PMU_PLL_CTRL_REG6, ~0, 0x09048562);
2453 		/* AVB PLL */
2454 		si_pmu_pllcontrol(sih, PMU_PLL_CTRL_REG14, ~0, 0x09048562);
2455 		si_pmu_pllupd(sih);
2456 	} else if (((CHIPID(sih->chip) == BCM4360_CHIP_ID) ||
2457 		(CHIPID(sih->chip) == BCM4352_CHIP_ID)) &&
2458 		(CHIPREV(sih->chiprev) >= 4) &&
2459 		((CST4360_RSRC_INIT_MODE(sih->chipst) & 1) == 0)) {
2460 		/* Changes for 4360B1 */
2461 
2462 		/* Enable REFCLK bit 11 */
2463 		si_pmu_chipcontrol(sih, PMU_CHIPCTL1, 0x800, 0x800);
2464 
2465 		/* BBPLL */
2466 		si_pmu_pllcontrol(sih, PMU_PLL_CTRL_REG6, ~0, 0x080004e2);
2467 		si_pmu_pllcontrol(sih, PMU_PLL_CTRL_REG7, ~0, 0xE);
2468 		/* AVB PLL */
2469 		si_pmu_pllcontrol(sih, PMU_PLL_CTRL_REG14, ~0, 0x080004e2);
2470 		si_pmu_pllcontrol(sih, PMU_PLL_CTRL_REG15, ~0, 0xE);
2471 		si_pmu_pllupd(sih);
2472 	}
2473 	/* disable PLL open loop operation */
2474 	si_pll_closeloop(sih);
2475 
2476 	if (max_mask) {
2477 		/* Ensure there is no bit set in min_mask which is not set in max_mask */
2478 		max_mask |= min_mask;
2479 
2480 		/* First set the bits which change from 0 to 1 in max, then update the
2481 		 * min_mask register and then reset the bits which change from 1 to 0
2482 		 * in max. This is required as the bit in MAX should never go to 0 when
2483 		 * the corresponding bit in min is still 1. Similarly the bit in min cannot
2484 		 * be 1 when the corresponding bit in max is still 0.
2485 		 */
2486 		OR_REG(osh, &pmu->max_res_mask, max_mask);
2487 	} else {
2488 		/* First set the bits which change from 0 to 1 in max, then update the
2489 		 * min_mask register and then reset the bits which change from 1 to 0
2490 		 * in max. This is required as the bit in MAX should never go to 0 when
2491 		 * the corresponding bit in min is still 1. Similarly the bit in min cannot
2492 		 * be 1 when the corresponding bit in max is still 0.
2493 		 */
2494 		if (min_mask)
2495 			OR_REG(osh, &pmu->max_res_mask, min_mask);
2496 	}
2497 
2498 	/* Program min resource mask */
2499 	if (min_mask) {
2500 		PMU_MSG(("Changing min_res_mask to 0x%x\n", min_mask));
2501 		W_REG(osh, &pmu->min_res_mask, min_mask);
2502 	}
2503 
2504 	/* Program max resource mask */
2505 	if (max_mask) {
2506 		PMU_MSG(("Changing max_res_mask to 0x%x\n", max_mask));
2507 		W_REG(osh, &pmu->max_res_mask, max_mask);
2508 	}
2509 #if defined(SAVERESTORE) && defined(LDO3P3_MIN_RES_MASK)
2510 	if (SR_ENAB()) {
2511 		/* Set the default state for LDO3P3 protection */
2512 		if (getintvar(NULL, rstr_ldo_prot) == 1) {
2513 			si_pmu_min_res_ldo3p3_set(sih, osh, TRUE);
2514 		}
2515 	}
2516 #endif /* SAVERESTORE && LDO3P3_MIN_RES_MASK */
2517 
2518 	/* request htavail thru pcie core */
2519 	if (((CHIPID(sih->chip) == BCM4360_CHIP_ID) || (CHIPID(sih->chip) == BCM4352_CHIP_ID)) &&
2520 	    (BUSTYPE(sih->bustype) == PCI_BUS) &&
2521 	    (CHIPREV(sih->chiprev) < 4)) {
2522 		uint32 pcie_clk_ctl_st;
2523 
2524 		pcie_clk_ctl_st = si_corereg(sih, 3, 0x1e0, 0, 0);
2525 		si_corereg(sih, 3, 0x1e0, ~0, (pcie_clk_ctl_st | CCS_HTAREQ));
2526 	}
2527 
2528 	si_pmu_wait_for_steady_state(sih, osh, pmu);
2529 	/* Add some delay; allow resources to come up and settle. */
2530 	OSL_DELAY(2000);
2531 
2532 	/* Return to original core */
2533 	si_setcoreidx(sih, origidx);
2534 } /* si_pmu_res_init */
2535 
2536 /* setup pll and query clock speed */
2537 typedef struct {
2538 	uint16	fref;	/* x-tal frequency in [hz] */
2539 	uint8	xf;	/* x-tal index as contained in PMU control reg, see PMU programmers guide */
2540 	uint8	p1div;
2541 	uint8	p2div;
2542 	uint8	ndiv_int;
2543 	uint32	ndiv_frac;
2544 } pmu1_xtaltab0_t;
2545 
2546 /* 'xf' values corresponding to the 'xf' definition in the PMU control register */
2547 /* unclear why this enum contains '_640_' since the PMU prog guide says nothing about that */
2548 enum xtaltab0_640 {
2549 	XTALTAB0_640_12000K = 1,
2550 	XTALTAB0_640_13000K,
2551 	XTALTAB0_640_14400K,
2552 	XTALTAB0_640_15360K,
2553 	XTALTAB0_640_16200K,
2554 	XTALTAB0_640_16800K,
2555 	XTALTAB0_640_19200K,
2556 	XTALTAB0_640_19800K,
2557 	XTALTAB0_640_20000K,
2558 	XTALTAB0_640_24000K, /* warning: unknown in PMU programmers guide. seems incorrect. */
2559 	XTALTAB0_640_25000K,
2560 	XTALTAB0_640_26000K,
2561 	XTALTAB0_640_30000K,
2562 	XTALTAB0_640_33600K, /* warning: unknown in PMU programmers guide. seems incorrect. */
2563 	XTALTAB0_640_37400K,
2564 	XTALTAB0_640_38400K, /* warning: unknown in PMU programmers guide. seems incorrect. */
2565 	XTALTAB0_640_40000K,
2566 	XTALTAB0_640_48000K, /* warning: unknown in PMU programmers guide. seems incorrect. */
2567 	XTALTAB0_640_52000K
2568 };
2569 
2570 /* the following table is based on 880Mhz fvco */
2571 static const pmu1_xtaltab0_t BCMINITDATA(pmu1_xtaltab0_880)[] = {
2572 	{12000,	1,	3,	22,	0x9,	0xFFFFEF},
2573 	{13000,	2,	1,	6,	0xb,	0x483483},
2574 	{14400,	3,	1,	10,	0xa,	0x1C71C7},
2575 	{15360,	4,	1,	5,	0xb,	0x755555},
2576 	{16200,	5,	1,	10,	0x5,	0x6E9E06},
2577 	{16800,	6,	1,	10,	0x5,	0x3Cf3Cf},
2578 	{19200,	7,	1,	4,	0xb,	0x755555},
2579 	{19800,	8,	1,	11,	0x4,	0xA57EB},
2580 	{20000,	9,	1,	11,	0x4,	0x0},
2581 	{24000,	10,	3,	11,	0xa,	0x0},
2582 	{25000,	11,	5,	16,	0xb,	0x0},
2583 	{26000,	12,	1,	2,	0x10,	0xEC4EC4},
2584 	{30000,	13,	3,	8,	0xb,	0x0},
2585 	{33600,	14,	1,	2,	0xd,	0x186186},
2586 	{38400,	15,	1,	2,	0xb,	0x755555},
2587 	{40000,	16,	1,	2,	0xb,	0},
2588 	{0,	0,	0,	0,	0,	0}
2589 };
2590 
2591 /* indices into pmu1_xtaltab0_880[] */
2592 #define PMU1_XTALTAB0_880_12000K	0
2593 #define PMU1_XTALTAB0_880_13000K	1
2594 #define PMU1_XTALTAB0_880_14400K	2
2595 #define PMU1_XTALTAB0_880_15360K	3
2596 #define PMU1_XTALTAB0_880_16200K	4
2597 #define PMU1_XTALTAB0_880_16800K	5
2598 #define PMU1_XTALTAB0_880_19200K	6
2599 #define PMU1_XTALTAB0_880_19800K	7
2600 #define PMU1_XTALTAB0_880_20000K	8
2601 #define PMU1_XTALTAB0_880_24000K	9
2602 #define PMU1_XTALTAB0_880_25000K	10
2603 #define PMU1_XTALTAB0_880_26000K	11
2604 #define PMU1_XTALTAB0_880_30000K	12
2605 #define PMU1_XTALTAB0_880_37400K	13
2606 #define PMU1_XTALTAB0_880_38400K	14
2607 #define PMU1_XTALTAB0_880_40000K	15
2608 
2609 /* the following table is based on 1760Mhz fvco */
2610 static const pmu1_xtaltab0_t BCMINITDATA(pmu1_xtaltab0_1760)[] = {
2611 	{12000,	1,	3,	44,	0x9,	0xFFFFEF},
2612 	{13000,	2,	1,	12,	0xb,	0x483483},
2613 	{14400,	3,	1,	20,	0xa,	0x1C71C7},
2614 	{15360,	4,	1,	10,	0xb,	0x755555},
2615 	{16200,	5,	1,	20,	0x5,	0x6E9E06},
2616 	{16800,	6,	1,	20,	0x5,	0x3Cf3Cf},
2617 	{19200,	7,	1,	18,	0x5,	0x17B425},
2618 	{19800,	8,	1,	22,	0x4,	0xA57EB},
2619 	{20000,	9,	1,	22,	0x4,	0x0},
2620 	{24000,	10,	3,	22,	0xa,	0x0},
2621 	{25000,	11,	5,	32,	0xb,	0x0},
2622 	{26000,	12,	1,	4,	0x10,	0xEC4EC4},
2623 	{30000,	13,	3,	16,	0xb,	0x0},
2624 	{38400,	14,	1,	10,	0x4,	0x955555},
2625 	{40000,	15,	1,	4,	0xb,	0},
2626 	{0,	0,	0,	0,	0,	0}
2627 };
2628 
2629 #define XTAL_FREQ_24000MHZ		24000
2630 #define XTAL_FREQ_29985MHZ		29985
2631 #define XTAL_FREQ_30000MHZ		30000
2632 #define XTAL_FREQ_37400MHZ		37400
2633 #define XTAL_FREQ_48000MHZ		48000
2634 #define XTAL_FREQ_59970MHZ		59970
2635 
2636 /* 'xf' values corresponding to the 'xf' definition in the PMU control register */
2637 /* unclear why this enum contains '_960_' since the PMU prog guide says nothing about that */
2638 enum xtaltab0_960 {
2639 	XTALTAB0_960_12000K = 1,
2640 	XTALTAB0_960_13000K,
2641 	XTALTAB0_960_14400K,
2642 	XTALTAB0_960_15360K,
2643 	XTALTAB0_960_16200K,
2644 	XTALTAB0_960_16800K,
2645 	XTALTAB0_960_19200K,
2646 	XTALTAB0_960_19800K,
2647 	XTALTAB0_960_20000K,
2648 	XTALTAB0_960_24000K, /* warning: unknown in PMU programmers guide. seems incorrect. */
2649 	XTALTAB0_960_25000K,
2650 	XTALTAB0_960_26000K,
2651 	XTALTAB0_960_30000K,
2652 	XTALTAB0_960_33600K, /* warning: unknown in PMU programmers guide. seems incorrect. */
2653 	XTALTAB0_960_37400K,
2654 	XTALTAB0_960_38400K, /* warning: unknown in PMU programmers guide. seems incorrect. */
2655 	XTALTAB0_960_40000K,
2656 	XTALTAB0_960_48000K, /* warning: unknown in PMU programmers guide. seems incorrect. */
2657 	XTALTAB0_960_52000K,
2658 	XTALTAB0_960_59970K
2659 };
2660 
2661 /**
2662  * given an x-tal frequency, this table specifies the PLL params to use to generate a 960Mhz output
2663  * clock. This output clock feeds the clock divider network. The defines of the form
2664  * PMU1_XTALTAB0_960_* index into this array.
2665  */
2666 static const pmu1_xtaltab0_t BCMINITDATA(pmu1_xtaltab0_960)[] = {
2667 /*	fref      xf     p1div   p2div  ndiv_int  ndiv_frac */
2668 	{12000,   1,       1,      1,     0x50,   0x0     }, /* array index 0 */
2669 	{13000,   2,       1,      1,     0x49,   0xD89D89},
2670 	{14400,   3,       1,      1,     0x42,   0xAAAAAA},
2671 	{15360,   4,       1,      1,     0x3E,   0x800000},
2672 	{16200,   5,       1,      1,     0x3B,   0x425ED0},
2673 	{16800,   6,       1,      1,     0x39,   0x249249},
2674 	{19200,   7,       1,      1,     0x32,   0x0     },
2675 	{19800,   8,       1,      1,     0x30,   0x7C1F07},
2676 	{20000,   9,       1,      1,     0x30,   0x0     },
2677 	{24000,   10,      1,      1,     0x28,   0x0     },
2678 	{25000,   11,      1,      1,     0x26,   0x666666}, /* array index 10 */
2679 	{26000,   12,      1,      1,     0x24,   0xEC4EC4},
2680 	{30000,   13,      1,      1,     0x20,   0x0     },
2681 	{33600,   14,      1,      1,     0x1C,   0x924924},
2682 	{37400,   15,      2,      1,     0x33,   0x563EF9},
2683 	{38400,   16,      2,      1,     0x32,   0x0	  },
2684 	{40000,   17,      2,      1,     0x30,   0x0     },
2685 	{48000,   18,      2,      1,     0x28,   0x0     },
2686 	{52000,   19,      2,      1,     0x24,   0xEC4EC4}, /* array index 18 */
2687 	{59970,   20,      0,      0,     0,      0       },
2688 	/* TBD: will separate 59970 for 4387B0 for new pll scheme */
2689 	{0,	      0,       0,      0,     0,      0	      }
2690 };
2691 
2692 static const pmu1_xtaltab0_t BCMINITDATA(pmu1_xtaltab0_4369_963)[] = {
2693 /*	fref      xf     p1div   NA  ndiv_int  ndiv_frac */
2694 	{12000,   1,       1,      1,     0x50,   0x40000}, /* array index 0 */
2695 	{13000,   2,       1,      1,     0x4A,   0x13B14},
2696 	{14400,   3,       1,      1,     0x42,   0xE0000},
2697 	{15360,   4,       1,      1,     0x3E,   0xB2000},
2698 	{16200,   5,       1,      1,     0x3B,   0x71C72},
2699 	{16800,   6,       1,      1,     0x39,   0x52492},
2700 	{19200,   7,       1,      1,     0x32,   0x28000},
2701 	{19800,   8,       1,      1,     0x30,   0xA2E8C},
2702 	{20000,   9,       1,      1,     0x30,   0x26666},
2703 	{24000,   10,      1,      1,     0x28,   0x20000},
2704 	{25000,   11,      1,      1,     0x26,   0x851EC}, /* array index 10 */
2705 	{26000,   12,      1,      1,     0x25,   0x09D8A},
2706 	{30000,   13,      1,      1,     0x20,   0x1999A},
2707 	{33600,   14,      1,      1,     0x1C,   0xA9249},
2708 	{37400,   15,      1,      1,     0x19,   0xBFA86},
2709 	{38400,   16,      1,      1,     0x19,   0x14000},
2710 	{40000,   17,      1,      1,     0x18,   0x13333},
2711 	{48000,   18,      1,      1,     0x14,   0x10000},
2712 	{52000,   19,      1,      1,     0x12,   0x84EC5}, /* array index 18 */
2713 	{0,	      0,       0,      0,     0,      0	     }
2714 };
2715 
2716 static const pmu1_xtaltab0_t BCMINITDATA(pmu1_xtaltab0_4362_963)[] = {
2717 /*	fref      xf     p1div   NA  ndiv_int  ndiv_frac */
2718 	{12000,   1,       1,      1,     0x50,   0x40000}, /* array index 0 */
2719 	{13000,   2,       1,      1,     0x4A,   0x13B14},
2720 	{14400,   3,       1,      1,     0x42,   0xE0000},
2721 	{15360,   4,       1,      1,     0x3E,   0xB2000},
2722 	{16200,   5,       1,      1,     0x3B,   0x71C72},
2723 	{16800,   6,       1,      1,     0x39,   0x52492},
2724 	{19200,   7,       1,      1,     0x32,   0x28000},
2725 	{19800,   8,       1,      1,     0x30,   0xA2E8C},
2726 	{20000,   9,       1,      1,     0x30,   0x26666},
2727 	{24000,   10,      1,      1,     0x28,   0x20000},
2728 	{25000,   11,      1,      1,     0x26,   0x851EC}, /* array index 10 */
2729 	{26000,   12,      1,      1,     0x25,   0x09D8A},
2730 	{30000,   13,      1,      1,     0x20,   0x1999A},
2731 	{33600,   14,      1,      1,     0x1C,   0xA9249},
2732 	{37400,   15,      1,      1,     0x19,   0xBFA86},
2733 	{38400,   16,      1,      1,     0x19,   0x14000},
2734 	{40000,   17,      1,      1,     0x18,   0x13333},
2735 	{48000,   18,      1,      1,     0x14,   0x10000},
2736 	{52000,   19,      1,      1,     0x12,   0x84EC5}, /* array index 18 */
2737 	{0,	      0,       0,      0,     0,      0	     }
2738 };
2739 
2740 /* Indices into array pmu1_xtaltab0_960[]. Keep array and these defines synchronized. */
2741 #define PMU1_XTALTAB0_960_12000K	0
2742 #define PMU1_XTALTAB0_960_13000K	1
2743 #define PMU1_XTALTAB0_960_14400K	2
2744 #define PMU1_XTALTAB0_960_15360K	3
2745 #define PMU1_XTALTAB0_960_16200K	4
2746 #define PMU1_XTALTAB0_960_16800K	5
2747 #define PMU1_XTALTAB0_960_19200K	6
2748 #define PMU1_XTALTAB0_960_19800K	7
2749 #define PMU1_XTALTAB0_960_20000K	8
2750 #define PMU1_XTALTAB0_960_24000K	9
2751 #define PMU1_XTALTAB0_960_25000K	10
2752 #define PMU1_XTALTAB0_960_26000K	11
2753 #define PMU1_XTALTAB0_960_30000K	12
2754 #define PMU1_XTALTAB0_960_33600K	13
2755 #define PMU1_XTALTAB0_960_37400K	14
2756 #define PMU1_XTALTAB0_960_38400K	15
2757 #define PMU1_XTALTAB0_960_40000K	16
2758 #define PMU1_XTALTAB0_960_48000K	17
2759 #define PMU1_XTALTAB0_960_52000K	18
2760 #define PMU1_XTALTAB0_960_59970K	19
2761 
2762 #define PMU15_XTALTAB0_12000K	0
2763 #define PMU15_XTALTAB0_20000K	1
2764 #define PMU15_XTALTAB0_26000K	2
2765 #define PMU15_XTALTAB0_37400K	3
2766 #define PMU15_XTALTAB0_52000K	4
2767 #define PMU15_XTALTAB0_END	5
2768 
2769 /* For having the pllcontrol data (info)
2770  * The table with the values of the registers will have one - one mapping.
2771  */
2772 typedef struct {
2773 	uint16	clock;	/**< x-tal frequency in [KHz] */
2774 	uint8	mode;	/**< spur mode */
2775 	uint8	xf;	/**< corresponds with xf bitfield in PMU control register */
2776 } pllctrl_data_t;
2777 
2778 /*  *****************************  tables for 43012a0 *********************** */
2779 
2780 /**
2781  * PLL control register table giving info about the xtal supported for 43012
2782  * There should be a one to one mapping between pmu1_pllctrl_tab_43012_960mhz[] and this table.
2783  */
2784 static const pllctrl_data_t(pmu1_xtaltab0_43012)[] = {
2785 /*       clock  mode xf */
2786 	{37400, 0,   XTALTAB0_960_37400K},
2787 	{37400,	100, XTALTAB0_960_37400K},
2788 	{26000, 0,   XTALTAB0_960_26000K},
2789 	{24000, 0,   XTALTAB0_960_24000K}
2790 };
2791 
2792 /*
2793 There should be a one to one mapping between pmu1_pllctrl_tab_43012_640mhz[]
2794 * and this table. PLL control5 register is related to HSIC which is not supported in 43012
2795 * Use a safe DCO code=56 by default, Across PVT openloop VCO Max=320MHz, Min=100
2796 * Mhz
2797 */
2798 #ifdef BCMQT
2799 static const uint32 (pmu1_pllctrl_tab_43012_1600mhz)[] = {
2800 /* Fvco is taken as 160.1 */
2801 /*	 PLL 0	     PLL 1	 PLL 2	     PLL 3	 PLL 4	     PLL 5		  */
2802 	0x072fe811, 0x00800000, 0x00000000, 0x038051e8, 0x00000000, 0x00000000,
2803 	0x0e5fd422, 0x00800000,	0x00000000, 0x000011e8,	0x00000000, 0x00000000
2804 };
2805 #else
2806 static const uint32 (pmu1_pllctrl_tab_43012_1600mhz)[] = {
2807 /* Fvco is taken as 160.1 */
2808 /*	 PLL 0	     PLL 1	 PLL 2	     PLL 3	 PLL 4  */
2809 	0x07df2411, 0x00800000, 0x00000000, 0x038051e8, 0x00000000,
2810 	0x0e5fd422, 0x00800000, 0x00000000, 0x000011e8, 0x00000000,
2811 	0x1d89dc12, 0x00800000, 0x00000000, 0x06d04de8, 0x00000000,
2812 	0x072fe828, 0x00800000, 0x00000000, 0x06d04de8, 0x00000000
2813 };
2814 #endif /* BCMQT */
2815 /*  ************************  tables for 43012a0 END *********************** */
2816 
2817 /*  *****************************  tables for 4369a0 *********************** */
2818 /* should get real value from hardware guys */
2819 /**
2820  * PLL control register table giving info about the xtal supported for 4369
2821  * There should be a one to one mapping between pmu1_pllctrl_tab_4369_960mhz[] and this table.
2822  * Even though macro suggests XTALTAB0_960_37400K --> BBPLL VCO is set to 963MHz
2823  */
2824 static const pllctrl_data_t BCMATTACHDATA(pmu1_xtaltab0_4369)[] = {
2825 /*       clock  mode xf */
2826 	{37400, 0,   XTALTAB0_960_37400K}
2827 };
2828 
2829 /**
2830  * PLL control register table giving info about the xtal supported for 4369.
2831  * There should be a one to one mapping between pmu1_pllctrl_tab_4369_963mhz[] and this table.
2832  */
2833 
2834 /* For 4369, 960.1MHz BBPLL freq is chosen to avoid the spurs
2835 * freq table : pll1 : fvco 960.1M, pll2 for arm : 400 MHz
2836 */
2837 #define PMU_PLL3_4369B0_DEFAULT	0x006ABF86
2838 static const uint32	BCMATTACHDATA(pmu1_pllctrl_tab_4369_960p1mhz)[] = {
2839 /* Default values for unused registers 4-7 as sw loop execution will go for 8 times */
2840 /* Fvco is taken as 963M */
2841 /*	PLL 0  PLL 1   PLL 2   PLL 3   PLL 4   PLL 5  PLL 6  PLL 7   PLL 8   PLL 9   PLL 10 */
2842 	0x15000000, 0x06050603, 0x01910806, PMU_PLL3_4369B0_DEFAULT,
2843 	0x00000000, 0x32800000, 0xC7AE00A9, 0x40800000,
2844 	0x00000000, 0x00000000, 0x00000000
2845 };
2846 
2847 /*  ************************  tables for 4369a0 END *********************** */
2848 
2849 /*  *****************************  tables for 4362a0 *********************** */
2850 /* should get real value from hardware guys */
2851 /**
2852  * PLL control register table giving info about the xtal supported for 4362
2853  * There should be a one to one mapping between pmu1_pllctrl_tab_4362_960mhz[] and this table.
2854  * Even though macro suggests XTALTAB0_960_37400K --> BBPLL VCO is set to 963MHz
2855  */
2856 static const pllctrl_data_t BCMATTACHDATA(pmu1_xtaltab0_4362)[] = {
2857 /*       clock  mode xf */
2858 	{37400, 0,   XTALTAB0_960_37400K}
2859 };
2860 
2861 /* For 4362, 960.1MHz BBPLL freq is chosen to avoid the spurs
2862 * freq table : pll1 : fvco 960.1M, pll2 for arm : 400 MHz
2863 */
2864 /* This freq actually around 960.123 */
2865 #define PMU_PLL3_4362A0_DEFAULT	0x006ABF86
2866 
2867 static const uint32	BCMATTACHDATA(pmu1_pllctrl_tab_4362_960p1mhz)[] = {
2868 /* Default values for unused registers 4-7 as sw loop execution will go for 8 times */
2869 /* Fvco is taken as 963M */
2870 /*	PLL 0  PLL 1   PLL 2   PLL 3   PLL 4   PLL 5  PLL 6  PLL 7   PLL 8   PLL 9   PLL 10 */
2871 	0x15000000, 0x06050603, 0x01910806, PMU_PLL3_4362A0_DEFAULT,
2872 	0x00000000, 0x32800000, 0xC7AE00A9, 0x40800000,
2873 	0x00000000, 0x00000000, 0x00000000
2874 };
2875 
2876 /*  ************************  tables for 4362a0 END *********************** */
2877 
2878 /*  *****************************  tables for 4389 *********************** */
2879 static const pllctrl_data_t BCMATTACHDATA(pmu1_xtaltab0_4389)[] = {
2880 /*       clock               mode xf */
2881 	{XTAL_FREQ_59970MHZ, 0,   XTALTAB0_960_59970K}
2882 };
2883 
2884 static const uint32 BCMATTACHDATA(pmu1_pllctrl_tab_4389_963mhz)[] = {
2885 /* Default values for all registers */
2886 /* Fvco (BBPLL) is taken as 963M */
2887 /*	PLL 0  PLL 1   PLL 2   PLL 3   PLL 4   PLL 5  PLL 6  PLL 7   PLL 8   PLL 9   PLL 10 */
2888 	0x29d00000, 0x30100c03, 0x00240c06, 0x597ff060,
2889 	0x00000000, 0x00000800, 0x00321d3a, 0x000551ff,
2890 	0x00000000, 0x10000000, 0x00000000
2891 };
2892 
2893 /*  ************************  tables for 4389 END *********************** */
2894 
2895 /** returns a table that instructs how to program the BBPLL for a particular xtal frequency */
2896 static const pmu1_xtaltab0_t *
BCMPOSTTRAPFN(si_pmu1_xtaltab0)2897 BCMPOSTTRAPFN(si_pmu1_xtaltab0)(si_t *sih)
2898 {
2899 #ifdef BCMDBG_PMU
2900 	char chn[8];
2901 #endif
2902 	switch (CHIPID(sih->chip)) {
2903 	case BCM4360_CHIP_ID:
2904 	case BCM43460_CHIP_ID:
2905 	case BCM4352_CHIP_ID:
2906 	case BCM43526_CHIP_ID:
2907 	CASE_BCM43602_CHIP:
2908 	case BCM43012_CHIP_ID:
2909 	case BCM43013_CHIP_ID:
2910 	case BCM43014_CHIP_ID:
2911 		return pmu1_xtaltab0_960;
2912 	case BCM4369_CHIP_GRPID:
2913 		return pmu1_xtaltab0_4369_963;
2914 	case BCM4362_CHIP_GRPID:
2915 		return pmu1_xtaltab0_4362_963;
2916 	case BCM4376_CHIP_GRPID:
2917 	case BCM4378_CHIP_GRPID:
2918 	case BCM4385_CHIP_GRPID:
2919 	case BCM4387_CHIP_GRPID:
2920 	case BCM4388_CHIP_GRPID:
2921 	case BCM4389_CHIP_GRPID:
2922 	case BCM4397_CHIP_GRPID:
2923 		return pmu1_xtaltab0_960;
2924 	default:
2925 		PMU_MSG(("si_pmu1_xtaltab0: Unknown chipid %s\n", bcm_chipname(sih->chip, chn, 8)));
2926 		break;
2927 	}
2928 	ASSERT(0);
2929 	return NULL;
2930 } /* si_pmu1_xtaltab0 */
2931 
2932 /** returns chip specific PLL settings for default xtal frequency and VCO output frequency */
2933 static const pmu1_xtaltab0_t *
BCMPOSTTRAPFN(si_pmu1_xtaldef0)2934 BCMPOSTTRAPFN(si_pmu1_xtaldef0)(si_t *sih)
2935 {
2936 #ifdef BCMDBG_PMU
2937 	char chn[8];
2938 #endif
2939 
2940 	switch (CHIPID(sih->chip)) {
2941 	case BCM4360_CHIP_ID:
2942 	case BCM4352_CHIP_ID:
2943 	case BCM43460_CHIP_ID:
2944 	case BCM43526_CHIP_ID:
2945 	case BCM43012_CHIP_ID:
2946 	case BCM43013_CHIP_ID:
2947 		/* Default to 37400Khz */
2948 		return &pmu1_xtaltab0_960[PMU1_XTALTAB0_960_37400K];
2949 	case BCM43014_CHIP_ID:
2950 		/* Default to 24000Khz */
2951 		return &pmu1_xtaltab0_960[PMU1_XTALTAB0_960_24000K];
2952 	CASE_BCM43602_CHIP:
2953 		return &pmu1_xtaltab0_960[PMU1_XTALTAB0_960_40000K];
2954 
2955 	case BCM4376_CHIP_GRPID:
2956 	case BCM4378_CHIP_GRPID:
2957 		return &pmu1_xtaltab0_960[PMU1_XTALTAB0_960_37400K];
2958 	case BCM4385_CHIP_GRPID:
2959 	case BCM4387_CHIP_GRPID:
2960 	case BCM4388_CHIP_GRPID:
2961 	case BCM4389_CHIP_GRPID:
2962 	case BCM4397_CHIP_GRPID:
2963 		return &pmu1_xtaltab0_960[PMU1_XTALTAB0_960_59970K];
2964 	case BCM4369_CHIP_GRPID:
2965 		return &pmu1_xtaltab0_4369_963[PMU1_XTALTAB0_960_37400K];
2966 	case BCM4362_CHIP_GRPID:
2967 		return &pmu1_xtaltab0_4362_963[PMU1_XTALTAB0_960_37400K];
2968 	default:
2969 		PMU_MSG(("si_pmu1_xtaldef0: Unknown chipid %s\n", bcm_chipname(sih->chip, chn, 8)));
2970 		break;
2971 	}
2972 	ASSERT(0);
2973 	return NULL;
2974 } /* si_pmu1_xtaldef0 */
2975 
2976 static uint32 fvco_4360 = 0;
2977 
2978 /**
2979  * store the val on init, then if func is called during normal operation
2980  * don't touch core regs anymore
2981  */
2982 static uint32
BCMPOSTTRAPFN(si_pmu_pll1_fvco_4360)2983 BCMPOSTTRAPFN(si_pmu_pll1_fvco_4360)(si_t *sih, osl_t *osh)
2984 {
2985 	uint32 xf, ndiv_int, ndiv_frac, fvco, pll_reg, p1_div_scale;
2986 	uint32 r_high, r_low, int_part, frac_part, rounding_const;
2987 	uint8 p1_div;
2988 	uint origidx = 0;
2989 	bcm_int_bitmask_t intr_val;
2990 
2991 	if (fvco_4360) {
2992 		printf("si_pmu_pll1_fvco_4360:attempt to query fvco during normal operation\n");
2993 		/* this will insure that the func is called only once upon init */
2994 		return fvco_4360;
2995 	}
2996 
2997 	/* Remember original core before switch to chipc */
2998 	si_switch_core(sih, CC_CORE_ID, &origidx, &intr_val);
2999 
3000 	xf = si_pmu_alp_clock(sih, osh)/1000;
3001 
3002 	/* pll reg 10 , p1div, ndif_mode, ndiv_int */
3003 	pll_reg = si_pmu_pllcontrol(sih, PMU_PLL_CTRL_REG10, 0, 0);
3004 	p1_div = pll_reg & 0xf;
3005 	ndiv_int = (pll_reg >> 7)  & 0x1f;
3006 
3007 	/* pllctrl11 */
3008 	pll_reg = si_pmu_pllcontrol(sih, PMU_PLL_CTRL_REG11, 0, 0);
3009 	ndiv_frac = pll_reg & 0xfffff;
3010 
3011 	int_part = xf * ndiv_int;
3012 
3013 	rounding_const = 1 << (BBPLL_NDIV_FRAC_BITS - 1);
3014 	math_uint64_multiple_add(&r_high, &r_low, ndiv_frac, xf, rounding_const);
3015 	math_uint64_right_shift(&frac_part, r_high, r_low, BBPLL_NDIV_FRAC_BITS);
3016 
3017 	if (!p1_div) {
3018 		PMU_ERROR(("p1_div calc returned 0! [%d]\n", __LINE__));
3019 		ROMMABLE_ASSERT(0);
3020 	}
3021 
3022 	if (p1_div == 0) {
3023 		ASSERT(p1_div != 0);
3024 		p1_div_scale = 0;
3025 	} else
3026 
3027 	p1_div_scale = (1 << P1_DIV_SCALE_BITS) / p1_div;
3028 	rounding_const = 1 << (P1_DIV_SCALE_BITS - 1);
3029 
3030 	math_uint64_multiple_add(&r_high, &r_low, (int_part + frac_part),
3031 		p1_div_scale, rounding_const);
3032 	math_uint64_right_shift(&fvco, r_high, r_low, P1_DIV_SCALE_BITS);
3033 
3034 	/* Return to original core */
3035 	si_restore_core(sih, origidx, &intr_val);
3036 
3037 	fvco_4360 = fvco;
3038 	return fvco;
3039 } /* si_pmu_pll1_fvco_4360 */
3040 
3041 /**
3042  * Specific to 43012 and calculate the FVCO frequency from XTAL freq
3043  *  Returns the FCVO frequency in [khz] units
3044  */
3045 static uint32
BCMPOSTTRAPFN(si_pmu_pll1_fvco_43012)3046 BCMPOSTTRAPFN(si_pmu_pll1_fvco_43012)(si_t *sih, osl_t *osh)
3047 {
3048 	uint32 xf, ndiv_int, ndiv_frac, fvco, pll_reg, p1_div_scale;
3049 	uint32 r_high, r_low, int_part, frac_part, rounding_const;
3050 	uint8 p_div;
3051 	chipcregs_t *cc;
3052 	uint origidx = 0;
3053 	bcm_int_bitmask_t intr_val;
3054 
3055 	/* Remember original core before switch to chipc */
3056 	cc = (chipcregs_t *)si_switch_core(sih, CC_CORE_ID, &origidx, &intr_val);
3057 	ASSERT(cc != NULL);
3058 	BCM_REFERENCE(cc);
3059 
3060 	xf = si_pmu_alp_clock(sih, osh)/1000;
3061 
3062 	pll_reg = si_pmu_pllcontrol(sih, PMU_PLL_CTRL_REG0, 0, 0);
3063 
3064 	ndiv_int = (pll_reg & PMU43012_PLL0_PC0_NDIV_INT_MASK) >>
3065 			PMU43012_PLL0_PC0_NDIV_INT_SHIFT;
3066 
3067 	ndiv_frac = (pll_reg & PMU43012_PLL0_PC0_NDIV_FRAC_MASK) >>
3068 			PMU43012_PLL0_PC0_NDIV_FRAC_SHIFT;
3069 
3070 	pll_reg = si_pmu_pllcontrol(sih, PMU_PLL_CTRL_REG3, 0, 0);
3071 
3072 	p_div = (pll_reg & PMU43012_PLL0_PC3_PDIV_MASK) >>
3073 			PMU43012_PLL0_PC3_PDIV_SHIFT;
3074 
3075 	/* If the p_div value read from PLL control register is zero,
3076 	* then return default FVCO value instead of computing the FVCO frequency
3077 	* using XTAL frequency
3078 	*/
3079 	if (!p_div) {
3080 		PMU_ERROR(("pll control register read failed [%d]\n", __LINE__));
3081 		ROMMABLE_ASSERT(0);
3082 		fvco = 0;
3083 		goto done;
3084 	}
3085 	/* Actual expression is as below */
3086 	/* fvco1 = ((xf * (1/p1_div)) * (ndiv_int + (ndiv_frac /(1 << 20)))); */
3087 
3088 	int_part = xf * ndiv_int;
3089 	rounding_const = 1 << (PMU43012_PLL_NDIV_FRAC_BITS - 1);
3090 	math_uint64_multiple_add(&r_high, &r_low, ndiv_frac, xf, rounding_const);
3091 	math_uint64_right_shift(&frac_part, r_high, r_low, PMU43012_PLL_NDIV_FRAC_BITS);
3092 
3093 	p1_div_scale = (1 << PMU43012_PLL_P_DIV_SCALE_BITS) / p_div;
3094 	rounding_const = 1 << (PMU43012_PLL_P_DIV_SCALE_BITS - 1);
3095 
3096 	math_uint64_multiple_add(&r_high, &r_low, (int_part + frac_part),
3097 		p1_div_scale, rounding_const);
3098 	math_uint64_right_shift(&fvco, r_high, r_low, PMU43012_PLL_P_DIV_SCALE_BITS);
3099 
3100 done:
3101 	/* Return to original core */
3102 	si_restore_core(sih, origidx, &intr_val);
3103 	return fvco;
3104 } /* si_pmu_pll1_fvco_43012 */
3105 
3106 /** returns chip specific default BaseBand pll fvco frequency in [khz] units */
3107 static uint32
BCMPOSTTRAPFN(si_pmu1_pllfvco0)3108 BCMPOSTTRAPFN(si_pmu1_pllfvco0)(si_t *sih)
3109 {
3110 #ifdef BCMDBG_PMU
3111 	char chn[8];
3112 #endif
3113 
3114 	switch (CHIPID(sih->chip)) {
3115 	case BCM4352_CHIP_ID:
3116 	case BCM43526_CHIP_ID:
3117 		return FVCO_960;
3118 
3119 	CASE_BCM43602_CHIP:
3120 		return FVCO_960;
3121 	case BCM4360_CHIP_ID:
3122 	case BCM43460_CHIP_ID:
3123 	{
3124 		osl_t *osh;
3125 		osh = si_osh(sih);
3126 		return si_pmu_pll1_fvco_4360(sih, osh);
3127 	}
3128 	case BCM43012_CHIP_ID:
3129 	case BCM43013_CHIP_ID:
3130 	case BCM43014_CHIP_ID:
3131 	{
3132 		osl_t *osh;
3133 		osh = si_osh(sih);
3134 		return si_pmu_pll1_fvco_43012(sih, osh);
3135 	}
3136 	case BCM4369_CHIP_GRPID:
3137 		return FVCO_960p1;
3138 	case BCM4362_CHIP_GRPID:
3139 		return FVCO_960p1;
3140 	case BCM4376_CHIP_GRPID:
3141 	case BCM4378_CHIP_GRPID:
3142 		return FVCO_960p1;
3143 	case BCM4385_CHIP_GRPID:
3144 	case BCM4387_CHIP_GRPID:
3145 	case BCM4388_CHIP_GRPID:
3146 	case BCM4389_CHIP_GRPID:
3147 	case BCM4397_CHIP_GRPID:
3148 		return FVCO_963p01;
3149 	default:
3150 		PMU_MSG(("si_pmu1_pllfvco0: Unknown chipid %s\n", bcm_chipname(sih->chip, chn, 8)));
3151 		break;
3152 	}
3153 	ASSERT(0);
3154 	return 0;
3155 } /* si_pmu1_pllfvco0 */
3156 
3157 /**
3158  * returns chip specific default pll fvco frequency in [khz] units
3159  */
3160 static uint32
BCMPOSTTRAPFN(si_pmu1_pllfvco0_pll2)3161 BCMPOSTTRAPFN(si_pmu1_pllfvco0_pll2)(si_t *sih)
3162 {
3163 #ifdef BCMDBG_PMU
3164 	char chn[8];
3165 #endif
3166 
3167 	switch (CHIPID(sih->chip)) {
3168 	case BCM4369_CHIP_GRPID:
3169 	case BCM4362_CHIP_GRPID:
3170 	case BCM4388_CHIP_GRPID:
3171 	case BCM4397_CHIP_GRPID:
3172 		return si_get_armpllclkfreq(sih) * 1000;
3173 	case BCM4389_CHIP_GRPID:
3174 		return SI_INFO(sih)->armpllclkfreq ? si_get_armpllclkfreq(sih) * 1000 : FVCO_1002p8;
3175 	case BCM4376_CHIP_GRPID:
3176 	case BCM4378_CHIP_GRPID:
3177 	case BCM4385_CHIP_GRPID:
3178 	case BCM4387_CHIP_GRPID:
3179 		return FVCO_400;
3180 	default:
3181 		PMU_MSG(("si_pmu1_pllfvco0_pll2 : Unknown chipid %s\n",
3182 				bcm_chipname(sih->chip, chn, 8)));
3183 		ASSERT(0);
3184 		break;
3185 	}
3186 	return 0;
3187 } /* si_pmu1_pllfvco0_pll2 */
3188 
3189 /** query alp/xtal clock frequency */
3190 static uint32
BCMPOSTTRAPFN(si_pmu1_alpclk0)3191 BCMPOSTTRAPFN(si_pmu1_alpclk0)(si_t *sih, osl_t *osh, pmuregs_t *pmu)
3192 {
3193 	const pmu1_xtaltab0_t *xt;
3194 	uint32 xf;
3195 	uint8 xtdiv = 1;
3196 
3197 	BCM_REFERENCE(sih);
3198 
3199 	/* Find the frequency in the table */
3200 	xf = (R_REG(osh, &pmu->pmucontrol) & PCTL_XTALFREQ_MASK) >>
3201 	        PCTL_XTALFREQ_SHIFT;
3202 	for (xt = si_pmu1_xtaltab0(sih); xt != NULL && xt->fref != 0; xt ++)
3203 		if (xt->xf == xf)
3204 			break;
3205 	/* Could not find it so assign a default value */
3206 	if (xt == NULL || xt->fref == 0)
3207 		xt = si_pmu1_xtaldef0(sih);
3208 	ASSERT(xt != NULL && xt->fref != 0);
3209 
3210 	switch (CHIPID(sih->chip))
3211 	{
3212 		case BCM4385_CHIP_GRPID:
3213 		case BCM4387_CHIP_GRPID:
3214 		case BCM4388_CHIP_GRPID:
3215 		case BCM4389_CHIP_GRPID:
3216 		case BCM4397_CHIP_GRPID:
3217 			/* xtalfreq for 4378B0 is 59.97 MHz and
3218 			 * but ALP clk is xtal / 2 (29.985 MHz) by default.
3219 			 */
3220 			xtdiv = 2;
3221 			break;
3222 		default:
3223 			break;
3224 	}
3225 
3226 	return (xt->fref * 1000) / xtdiv;
3227 }
3228 
3229 /**
3230  * Before the PLL is switched off, the HT clocks need to be deactivated, and reactivated
3231  * when the PLL is switched on again.
3232  * This function returns the chip specific HT clock resources (HT and MACPHY clocks).
3233  */
3234 static uint32
si_pmu_htclk_mask(si_t * sih)3235 si_pmu_htclk_mask(si_t *sih)
3236 {
3237 	/* chip specific bit position of various resources */
3238 	rsc_per_chip_t *rsc = si_pmu_get_rsc_positions(sih);
3239 
3240 	uint32 ht_req = (PMURES_BIT(rsc->ht_avail) | PMURES_BIT(rsc->macphy_clkavail));
3241 
3242 	switch (CHIPID(sih->chip))
3243 	{
3244 		CASE_BCM43602_CHIP:
3245 		case BCM43012_CHIP_ID:
3246 		case BCM43013_CHIP_ID:
3247 		case BCM43014_CHIP_ID:
3248 		case BCM4369_CHIP_GRPID:
3249 		case BCM4362_CHIP_GRPID:
3250 		case BCM4376_CHIP_GRPID:
3251 		case BCM4378_CHIP_GRPID:
3252 		case BCM4385_CHIP_GRPID:
3253 		case BCM4387_CHIP_GRPID:
3254 		case BCM4388_CHIP_GRPID:
3255 		case BCM4389_CHIP_GRPID:
3256 		case BCM4397_CHIP_GRPID:
3257 			ht_req |= PMURES_BIT(rsc->ht_start);
3258 			break;
3259 		default:
3260 			ASSERT(0);
3261 			break;
3262 	}
3263 
3264 	return ht_req;
3265 } /* si_pmu_htclk_mask */
3266 
3267 /** returns ALP frequency in [Hz] */
3268 static uint32
BCMATTACHFN(si_pmu_def_alp_clock)3269 BCMATTACHFN(si_pmu_def_alp_clock)(si_t *sih, osl_t *osh)
3270 {
3271 	uint32 clock = ALP_CLOCK;
3272 
3273 	BCM_REFERENCE(osh);
3274 
3275 	switch (CHIPID(sih->chip)) {
3276 	case BCM43012_CHIP_ID:
3277 	case BCM43013_CHIP_ID:
3278 	case BCM43014_CHIP_ID:
3279 	case BCM4369_CHIP_GRPID:
3280 	case BCM4362_CHIP_GRPID:
3281 	case BCM4376_CHIP_GRPID:
3282 	case BCM4378_CHIP_GRPID:
3283 	case BCM4385_CHIP_GRPID:
3284 	case BCM4387_CHIP_GRPID:
3285 	case BCM4388_CHIP_GRPID:
3286 	case BCM4389_CHIP_GRPID:
3287 	case BCM4397_CHIP_GRPID:
3288 
3289 #ifdef UNRELEASEDCHIP
3290 #endif
3291 
3292 		clock = 37400*1000;
3293 		break;
3294 	CASE_BCM43602_CHIP:
3295 		clock = 40000 * 1000;
3296 		break;
3297 	}
3298 
3299 	return clock;
3300 }
3301 
3302 /**
3303  * The BBPLL register set needs to be reprogrammed because the x-tal frequency is not known at
3304  * compile time, or a different spur mode is selected. This function writes appropriate values into
3305  * the BBPLL registers. It returns the 'xf', corresponding to the 'xf' bitfield in the PMU control
3306  * register.
3307  *     'xtal'             : xtal frequency in [KHz]
3308  *     'pllctrlreg_update': contains info on what entries to use in 'pllctrlreg_val' for the given
3309  *                          x-tal frequency and spur mode
3310  *     'pllctrlreg_val'   : contains a superset of the BBPLL values to write
3311  *
3312  * Note: if pmu is NULL, this function returns xf, without programming PLL registers.
3313  * This function is only called for pmu1_ type chips, perhaps we should rename it.
3314  */
3315 static uint8
si_pmu_pllctrlreg_update(si_t * sih,osl_t * osh,pmuregs_t * pmu,uint32 xtal,uint8 spur_mode,const pllctrl_data_t * pllctrlreg_update,uint32 array_size,const uint32 * pllctrlreg_val)3316 si_pmu_pllctrlreg_update(si_t *sih, osl_t *osh, pmuregs_t *pmu, uint32 xtal,
3317             uint8 spur_mode, const pllctrl_data_t *pllctrlreg_update, uint32 array_size,
3318             const uint32 *pllctrlreg_val)
3319 {
3320 	uint8 indx, reg_offset, xf = 0;
3321 	uint8 pll_ctrlcnt = 0;
3322 
3323 	ASSERT(pllctrlreg_update);
3324 
3325 	if (PMUREV(sih->pmurev) >= 5) {
3326 		pll_ctrlcnt = (sih->pmucaps & PCAP5_PC_MASK) >> PCAP5_PC_SHIFT;
3327 	} else {
3328 		pll_ctrlcnt = (sih->pmucaps & PCAP_PC_MASK) >> PCAP_PC_SHIFT;
3329 	}
3330 
3331 	/* Program the PLL control register if the xtal value matches with the table entry value */
3332 	for (indx = 0; indx < array_size; indx++) {
3333 		/* If the entry does not match the xtal and spur_mode just continue the loop */
3334 		if (!((pllctrlreg_update[indx].clock == (uint16)xtal) &&
3335 			(pllctrlreg_update[indx].mode == spur_mode)))
3336 			continue;
3337 		/*
3338 		 * Don't program the PLL registers if register base is NULL.
3339 		 * If NULL just return the xref.
3340 		 */
3341 		if (pmu) {
3342 			for (reg_offset = 0; reg_offset < pll_ctrlcnt; reg_offset++) {
3343 				si_pmu_pllcontrol(sih, reg_offset, ~0,
3344 					pllctrlreg_val[indx*pll_ctrlcnt + reg_offset]);
3345 			}
3346 
3347 			/* for 4369, arm clk cycle can be set from nvram - default is 400 MHz */
3348 			if ((BCM4369_CHIP(sih->chip) || BCM4362_CHIP(sih->chip)) &&
3349 				(pll_ctrlcnt > PMU1_PLL0_PLLCTL6)) {
3350 				si_pmu_pll6val_armclk_calc(osh, pmu,
3351 					si_get_armpllclkfreq(sih), xtal, TRUE);
3352 			}
3353 		}
3354 		xf = pllctrlreg_update[indx].xf;
3355 		break;
3356 	}
3357 	return xf;
3358 } /* si_pmu_pllctrlreg_update */
3359 
3360 /*
3361  * Calculate p1div, ndiv_int, ndiv_frac for clock ratio.
3362  * Input: fvco, xtal
3363  * Output: ndiv_int, ndiv_frac
3364  * Returns: p1div
3365  *
3366  */
3367 uint8
si_pmu_pll28nm_calc_ndiv(uint32 fvco,uint32 xtal,uint32 * ndiv_int,uint32 * ndiv_frac)3368 si_pmu_pll28nm_calc_ndiv(uint32 fvco, uint32 xtal, uint32 *ndiv_int, uint32 *ndiv_frac)
3369 {
3370 	uint8 p1div;
3371 	uint32 temp_high, temp_low;
3372 	ASSERT(xtal <= 0xFFFFFFFF / 1000);
3373 	p1div = 1 + (uint8) ((xtal * 1000) / 54000000UL);
3374 	*ndiv_int = (fvco * p1div) / xtal;
3375 	/* nfrac = 20 */
3376 	/* ndiv_frac = (uint32) (((uint64) (fvco * p1div - xtal * ndiv_int) * (1 << 20)) / xtal) */
3377 	math_uint64_multiple_add(&temp_high, &temp_low, fvco * p1div - xtal * (*ndiv_int), 1 << 20,
3378 		0);
3379 	math_uint64_divide(ndiv_frac, temp_high, temp_low, xtal);
3380 	return p1div;
3381 }
3382 
3383 void
si_pmu_armpll_freq_upd(si_t * sih,uint8 p1div,uint32 ndiv_int,uint32 ndiv_frac)3384 si_pmu_armpll_freq_upd(si_t *sih, uint8 p1div, uint32 ndiv_int, uint32 ndiv_frac)
3385 {
3386 	switch (CHIPID(sih->chip)) {
3387 	case BCM4388_CHIP_GRPID:
3388 		si_pmu_pllcontrol(sih, PMU_PLL_CTRL_REG6, PMU4388_ARMPLL_I_NDIV_INT_MASK,
3389 			ndiv_int << PMU4388_ARMPLL_I_NDIV_INT_SHIFT);
3390 		si_pmu_pllupd(sih);
3391 		break;
3392 	case BCM4389_CHIP_GRPID:
3393 		si_pmu_pllcontrol(sih, PMU_PLL_CTRL_REG6, PMU4389_ARMPLL_I_NDIV_INT_MASK,
3394 			ndiv_int << PMU4389_ARMPLL_I_NDIV_INT_SHIFT);
3395 		si_pmu_pllupd(sih);
3396 		break;
3397 	case BCM4369_CHIP_GRPID:
3398 		si_pmu_pllcontrol(sih, PMU_PLL_CTRL_REG5, PMU4369_PLL1_PC5_P1DIV_MASK,
3399 			((p1div >> PMU4369_P1DIV_LO_SHIFT) << PMU4369_PLL1_PC5_P1DIV_SHIFT));
3400 		si_pmu_pllcontrol(sih, PMU_PLL_CTRL_REG6, PMU4369_PLL1_PC6_P1DIV_MASK,
3401 			(p1div >> PMU4369_P1DIV_HI_SHIFT));
3402 		si_pmu_pllcontrol(sih, PMU_PLL_CTRL_REG6, PMU4369_PLL1_PC6_NDIV_INT_MASK,
3403 			ndiv_int << PMU4369_PLL1_PC6_NDIV_INT_SHIFT);
3404 		si_pmu_pllcontrol(sih, PMU_PLL_CTRL_REG6, PMU4369_PLL1_PC6_NDIV_FRAC_MASK,
3405 			ndiv_frac << PMU4369_PLL1_PC6_NDIV_FRAC_SHIFT);
3406 		si_pmu_pllupd(sih);
3407 		break;
3408 	case BCM4362_CHIP_GRPID:
3409 		/* 4362/69 PLL definitions are same. so reusing definitions */
3410 		si_pmu_pllcontrol(sih, PMU_PLL_CTRL_REG5, PMU4369_PLL1_PC5_P1DIV_MASK,
3411 			((p1div >> PMU4369_P1DIV_LO_SHIFT) << PMU4369_PLL1_PC5_P1DIV_SHIFT));
3412 		si_pmu_pllcontrol(sih, PMU_PLL_CTRL_REG6, PMU4369_PLL1_PC6_P1DIV_MASK,
3413 			(p1div >> PMU4369_P1DIV_HI_SHIFT));
3414 		si_pmu_pllcontrol(sih, PMU_PLL_CTRL_REG6, PMU4369_PLL1_PC6_NDIV_INT_MASK,
3415 			ndiv_int << PMU4369_PLL1_PC6_NDIV_INT_SHIFT);
3416 		si_pmu_pllcontrol(sih, PMU_PLL_CTRL_REG6, PMU4369_PLL1_PC6_NDIV_FRAC_MASK,
3417 			ndiv_frac << PMU4369_PLL1_PC6_NDIV_FRAC_SHIFT);
3418 		si_pmu_pllupd(sih);
3419 		break;
3420 	default:
3421 		ASSERT(0);
3422 		break;
3423 	}
3424 }
3425 
3426 void
si_pmu_bbpll_freq_upd(si_t * sih,uint8 p1div,uint32 ndiv_int,uint32 ndiv_frac)3427 si_pmu_bbpll_freq_upd(si_t *sih, uint8 p1div, uint32 ndiv_int, uint32 ndiv_frac)
3428 {
3429 	switch (CHIPID(sih->chip)) {
3430 	case BCM4369_CHIP_GRPID:
3431 	case BCM4362_CHIP_GRPID:
3432 		/* PLL Control 2 Register are the same for 4368, 4369 */
3433 		si_pmu_pllcontrol(sih, PMU_PLL_CTRL_REG2, PMU4369_PLL0_PC2_PDIV_MASK, p1div);
3434 		si_pmu_pllcontrol(sih, PMU_PLL_CTRL_REG2, PMU4369_PLL0_PC2_NDIV_INT_MASK,
3435 			ndiv_int << PMU4369_PLL0_PC2_NDIV_INT_SHIFT);
3436 		si_pmu_pllcontrol(sih, PMU_PLL_CTRL_REG2, PMU4369_PLL0_PC3_NDIV_FRAC_MASK,
3437 			ndiv_frac << PMU4369_PLL0_PC3_NDIV_FRAC_SHIFT);
3438 		si_pmu_pllupd(sih);
3439 		break;
3440 	default:
3441 		ASSERT(0);
3442 		break;
3443 	}
3444 }
3445 
3446 void
si_pmu_armpll_chmdiv_upd(si_t * sih,uint32 ch0_mdiv,uint32 ch1_mdiv)3447 si_pmu_armpll_chmdiv_upd(si_t *sih, uint32 ch0_mdiv, uint32 ch1_mdiv)
3448 {
3449 	switch (CHIPID(sih->chip)) {
3450 	default:
3451 		ASSERT(0);
3452 		break;
3453 	}
3454 }
3455 
3456 static bool
si_pmu_armpll_write_required(si_t * sih,uint32 xtal)3457 si_pmu_armpll_write_required(si_t *sih, uint32 xtal)
3458 {
3459 	uint32 def_xtal = 0;
3460 	uint32 def_armclk_mhz = 0;
3461 	uint32 armclk_mhz = si_get_armpllclkfreq(sih);
3462 
3463 	switch (CHIPID(sih->chip)) {
3464 	case BCM4369_CHIP_GRPID:
3465 		def_xtal = XTAL_FREQ_37400MHZ;
3466 		def_armclk_mhz = ARMPLL_FREQ_400MHZ;
3467 		break;
3468 	case BCM4388_CHIP_GRPID:
3469 		def_xtal = XTAL_FREQ_59970MHZ;
3470 		def_armclk_mhz = ARMPLL_FREQ_1000MHZ;
3471 		break;
3472 	case BCM4389_CHIP_GRPID:
3473 		def_xtal = XTAL_FREQ_59970MHZ;
3474 		def_armclk_mhz = ARMPLL_FREQ_1000MHZ;
3475 		break;
3476 	default:
3477 		break;
3478 	}
3479 
3480 	/*
3481 	 * If programmed xtalfreq is same as xtal, no need to enable pll write. Check for
3482 	 * armclk and xtalfreq instead of comparing calculated value and pll register value.
3483 	 */
3484 	return (((armclk_mhz == def_armclk_mhz) && (xtal == def_xtal)) ? FALSE : TRUE);
3485 }
3486 
3487 /**
3488  * Chip-specific overrides to PLLCONTROL registers during init. If certain conditions (dependent on
3489  * x-tal frequency and current ALP frequency) are met, an update of the PLL is required.
3490  *
3491  * This takes less precedence over OTP PLLCONTROL overrides.
3492  * If update_required=FALSE, it returns TRUE if a update is about to occur.
3493  * No write happens.
3494  *
3495  * Return value: TRUE if the BBPLL registers 'update' field should be written by the caller.
3496  *
3497  * This function is only called for pmu1_ type chips, perhaps we should rename it.
3498  */
3499 static bool
BCMATTACHFN(si_pmu_update_pllcontrol)3500 BCMATTACHFN(si_pmu_update_pllcontrol)(si_t *sih, osl_t *osh, uint32 xtal, bool update_required)
3501 {
3502 	pmuregs_t *pmu;
3503 	uint origidx;
3504 	bool write_en = FALSE;
3505 	uint8 xf = 0;
3506 	const pmu1_xtaltab0_t *xt;
3507 	uint32 tmp;
3508 	const pllctrl_data_t *pllctrlreg_update = NULL;
3509 	uint32 array_size = 0;
3510 	/* points at a set of PLL register values to write for a given x-tal frequency: */
3511 	const uint32 *pllctrlreg_val = NULL;
3512 	uint8 ndiv_mode = PMU1_PLL0_PC2_NDIV_MODE_MASH;
3513 	uint32 xtalfreq = 0;
3514 	uint32 ndiv_int;
3515 	uint32 ndiv_frac;
3516 	uint8 pdiv;
3517 
3518 	BCM_REFERENCE(ndiv_int);
3519 	BCM_REFERENCE(ndiv_frac);
3520 	BCM_REFERENCE(pdiv);
3521 	/* If there is OTP or NVRAM entry for xtalfreq, program the
3522 	 * PLL control register even if it is default xtal.
3523 	 */
3524 	xtalfreq = getintvar(NULL, rstr_xtalfreq);
3525 	/* CASE1 */
3526 	if (xtalfreq) {
3527 		write_en = TRUE;
3528 		xtal = xtalfreq;
3529 	} else {
3530 		/* There is NO OTP value */
3531 		if (xtal) {
3532 			/* CASE2: If the xtal value was calculated, program the PLL control
3533 			 * registers only if it is not default xtal value.
3534 			 */
3535 			if (xtal != (si_pmu_def_alp_clock(sih, osh)/1000))
3536 				write_en = TRUE;
3537 		} else {
3538 			/* CASE3: If the xtal obtained is "0", ie., clock is not measured, then
3539 			 * leave the PLL control register as it is but program the xf in
3540 			 * pmucontrol register with the default xtal value.
3541 			 */
3542 			xtal = si_pmu_def_alp_clock(sih, osh)/1000;
3543 		}
3544 	}
3545 
3546 	switch (CHIPID(sih->chip)) {
3547 	case BCM43012_CHIP_ID:
3548 	case BCM43013_CHIP_ID:
3549 	case BCM43014_CHIP_ID:
3550 		pllctrlreg_update = pmu1_xtaltab0_43012;
3551 		array_size = ARRAYSIZE(pmu1_xtaltab0_43012);
3552 		pllctrlreg_val = pmu1_pllctrl_tab_43012_1600mhz;
3553 		break;
3554 	case BCM4369_CHIP_GRPID:
3555 		pllctrlreg_update = pmu1_xtaltab0_4369;
3556 		array_size = ARRAYSIZE(pmu1_xtaltab0_4369);
3557 		pllctrlreg_val = pmu1_pllctrl_tab_4369_960p1mhz;
3558 		/* default pll programming be true, later based on need disable it */
3559 		write_en = TRUE;
3560 		break;
3561 	case BCM4362_CHIP_GRPID:
3562 		pllctrlreg_update = pmu1_xtaltab0_4362;
3563 		array_size = ARRAYSIZE(pmu1_xtaltab0_4362);
3564 		pllctrlreg_val = pmu1_pllctrl_tab_4362_960p1mhz;
3565 		/* default pll programming be true, later based on need disable it */
3566 		write_en = TRUE;
3567 		break;
3568 	case BCM4376_CHIP_GRPID:
3569 	case BCM4378_CHIP_GRPID:
3570 	case BCM4385_CHIP_GRPID:
3571 	case BCM4387_CHIP_GRPID:
3572 		/* TBD : bypass PLL programming, So use chip default values */
3573 		pllctrlreg_update = NULL;
3574 		array_size = 0;
3575 		pllctrlreg_val = NULL;
3576 		write_en = FALSE;
3577 		break;
3578 	case BCM4388_CHIP_GRPID:
3579 		/* TBD : bypass PLL programming, So use chip default values */
3580 		pllctrlreg_update = NULL;
3581 		array_size = 0;
3582 		pllctrlreg_val = NULL;
3583 		write_en = FALSE;
3584 		break;
3585 	case BCM4389_CHIP_GRPID:
3586 		pllctrlreg_update = pmu1_xtaltab0_4389;
3587 		array_size = ARRAYSIZE(pmu1_xtaltab0_4389);
3588 		pllctrlreg_val = pmu1_pllctrl_tab_4389_963mhz;
3589 		break;
3590 	CASE_BCM43602_CHIP:
3591 		/*
3592 		 * 43602 has only 1 x-tal value, possibly insert case when an other BBPLL
3593 		 * frequency than 960Mhz is required (e.g., for spur avoidance)
3594 		 */
3595 		 /* fall through */
3596 	default:
3597 		/* write_en is FALSE in this case. So returns from the function */
3598 		write_en = FALSE;
3599 		break;
3600 	}
3601 
3602 	/* Remember original core before switch to chipc/pmu */
3603 	origidx = si_coreidx(sih);
3604 	if (AOB_ENAB(sih)) {
3605 		pmu = si_setcore(sih, PMU_CORE_ID, 0);
3606 	} else {
3607 		pmu = si_setcoreidx(sih, SI_CC_IDX);
3608 	}
3609 	ASSERT(pmu != NULL);
3610 
3611 	/* Check if the table has PLL control register values for the requested xtal */
3612 	if (!update_required && pllctrlreg_update) {
3613 		/* Here the chipcommon register base is passed as NULL, so that we just get
3614 		 * the xf for the xtal being programmed but don't program the registers now
3615 		 * as the PLL is not yet turned OFF.
3616 		 */
3617 		xf = si_pmu_pllctrlreg_update(sih, osh, NULL, xtal, 0, pllctrlreg_update,
3618 			array_size, pllctrlreg_val);
3619 
3620 		/* Program the PLL based on the xtal value. */
3621 		if (xf != 0) {
3622 			/* Write XtalFreq. Set the divisor also. */
3623 			tmp = R_REG(osh, &pmu->pmucontrol) &
3624 				~(PCTL_ILP_DIV_MASK | PCTL_XTALFREQ_MASK);
3625 			tmp |= (((((xtal + 127) / 128) - 1) << PCTL_ILP_DIV_SHIFT) &
3626 				PCTL_ILP_DIV_MASK) |
3627 				((xf << PCTL_XTALFREQ_SHIFT) & PCTL_XTALFREQ_MASK);
3628 			W_REG(osh, &pmu->pmucontrol, tmp);
3629 		} else {
3630 			write_en = FALSE;
3631 			if (!FWSIGN_ENAB()) {
3632 				printf(rstr_Invalid_Unsupported_xtal_value_D, xtal);
3633 			}
3634 		}
3635 
3636 		write_en = si_pmu_armpll_write_required(sih, xtal);
3637 	}
3638 
3639 	/* If its a check sequence or if there is nothing to write, return here */
3640 	if ((update_required == FALSE) || (write_en == FALSE)) {
3641 		goto exit;
3642 	}
3643 
3644 	/* Update the PLL control register based on the xtal used. */
3645 	if (pllctrlreg_val) {
3646 		si_pmu_pllctrlreg_update(sih, osh, pmu, xtal, 0, pllctrlreg_update, array_size,
3647 			pllctrlreg_val);
3648 	}
3649 
3650 	/* Chip specific changes to PLL Control registers is done here. */
3651 	switch (CHIPID(sih->chip)) {
3652 	case BCM4388_CHIP_ID: {
3653 		uint32 armclk_mhz = si_get_armpllclkfreq(sih);
3654 		uint32 vco_freq = (armclk_mhz * PMU4388_APLL_PDIV * 1000);
3655 
3656 		ASSERT(vco_freq <= FVCO_3200);
3657 
3658 		/*
3659 		 * ndiv_init = Fvco / Frefeff
3660 		 * Frefeff = Fref / pdiv
3661 		 * Fref = xtal / 2
3662 		 * pdiv = 3
3663 		 *
3664 		 * ndiv_init = ((Fvco * pdiv * 1000000) / ((xtal * 1000) / 2)
3665 		 */
3666 		ndiv_int = (vco_freq / (xtal / 2));
3667 		si_pmu_armpll_freq_upd(sih, 0, ndiv_int, 0);
3668 		break;
3669 	}
3670 
3671 	case BCM4389_CHIP_ID: {
3672 		uint32 armclk_mhz = si_get_armpllclkfreq(sih);
3673 		uint32 vco_freq = (armclk_mhz * PMU4389_APLL_PDIV * 1000);
3674 
3675 		ASSERT(vco_freq <= FVCO_3200);
3676 
3677 		/*
3678 		 * ndiv_init = Fvco / Frefeff
3679 		 * Frefeff = Fref / pdiv
3680 		 * Fref = xtal / 2
3681 		 * pdiv = 3
3682 		 *
3683 		 * ndiv_init = ((Fvco * pdiv * 1000000) / ((xtal * 1000) / 2)
3684 		 */
3685 		ndiv_int = (vco_freq / (xtal / 2));
3686 		si_pmu_armpll_freq_upd(sih, 0, ndiv_int, 0);
3687 		break;
3688 	}
3689 
3690 	default:
3691 		break;
3692 	}
3693 
3694 	/* Program the PLL based on the xtal value. */
3695 	if (xtal != 0) {
3696 		/* Find the frequency in the table */
3697 		for (xt = si_pmu1_xtaltab0(sih); xt != NULL && xt->fref != 0; xt ++)
3698 			if (xt->fref == xtal) {
3699 				break;
3700 			}
3701 
3702 		/* Check current PLL state, bail out if it has been programmed or
3703 		 * we don't know how to program it. But we might still have some programming
3704 		 * like changing the ARM clock, etc. So cannot return from here.
3705 		 */
3706 		if (xt == NULL || xt->fref == 0) {
3707 			goto exit;
3708 		}
3709 
3710 		/* If the PLL is already programmed exit from here. */
3711 		if (((R_REG(osh, &pmu->pmucontrol) &
3712 			PCTL_XTALFREQ_MASK) >> PCTL_XTALFREQ_SHIFT) == xt->xf) {
3713 			goto exit;
3714 		}
3715 
3716 		PMU_MSG(("XTAL %d.%d MHz (%d)\n", xtal / 1000, xtal % 1000, xt->xf));
3717 		PMU_MSG(("Programming PLL for %d.%d MHz\n", xt->fref / 1000, xt->fref % 1000));
3718 
3719 		if (BCM4389_CHIP(sih->chip)) {
3720 			/* Write ndiv_int to pllcontrol[6] */
3721 			tmp = ((xt->ndiv_int << PMU4389_ARMPLL_I_NDIV_INT_SHIFT)
3722 				& PMU4389_ARMPLL_I_NDIV_INT_MASK);
3723 			si_pmu_pllcontrol(sih, PMU_PLL_CTRL_REG6,
3724 				(PMU4389_ARMPLL_I_NDIV_INT_MASK), tmp);
3725 		} else if (BCM4388_CHIP(sih->chip)) {
3726 			/* Write ndiv_int to pllcontrol[6] */
3727 			tmp = ((xt->ndiv_int << PMU4388_ARMPLL_I_NDIV_INT_SHIFT)
3728 				& PMU4388_ARMPLL_I_NDIV_INT_MASK);
3729 			si_pmu_pllcontrol(sih, PMU_PLL_CTRL_REG6,
3730 				(PMU4388_ARMPLL_I_NDIV_INT_MASK), tmp);
3731 		} else if (BCM4369_CHIP(sih->chip) ||
3732 				BCM4362_CHIP(sih->chip) ||
3733 				FALSE) {
3734 			/* Write pdiv (Actually it is mapped to p1div in the struct)
3735 			 to pllcontrol[2]
3736 			 */
3737 			tmp = ((xt->p1div << PMU4369_PLL0_PC2_PDIV_SHIFT) &
3738 				PMU4369_PLL0_PC2_PDIV_MASK);
3739 			si_pmu_pllcontrol(sih, PMU_PLL_CTRL_REG2,
3740 				(PMU4369_PLL0_PC2_PDIV_MASK), tmp);
3741 
3742 			/* Write ndiv_int to pllcontrol[2] */
3743 			tmp = ((xt->ndiv_int << PMU4369_PLL0_PC2_NDIV_INT_SHIFT)
3744 					& PMU4369_PLL0_PC2_NDIV_INT_MASK);
3745 			si_pmu_pllcontrol(sih, PMU_PLL_CTRL_REG2,
3746 				(PMU4369_PLL0_PC2_NDIV_INT_MASK), tmp);
3747 
3748 			/* Write ndiv_frac to pllcontrol[3] */
3749 			tmp = ((xt->ndiv_frac << PMU4369_PLL0_PC3_NDIV_FRAC_SHIFT) &
3750 				PMU4369_PLL0_PC3_NDIV_FRAC_MASK);
3751 			si_pmu_pllcontrol(sih, PMU_PLL_CTRL_REG3,
3752 				PMU4369_PLL0_PC3_NDIV_FRAC_MASK, tmp);
3753 		} else {
3754 			/* Write p1div and p2div to pllcontrol[0] */
3755 			tmp = ((xt->p1div << PMU1_PLL0_PC0_P1DIV_SHIFT) &
3756 				PMU1_PLL0_PC0_P1DIV_MASK) |
3757 				((xt->p2div << PMU1_PLL0_PC0_P2DIV_SHIFT) &
3758 				PMU1_PLL0_PC0_P2DIV_MASK);
3759 			si_pmu_pllcontrol(sih, PMU_PLL_CTRL_REG0,
3760 				(PMU1_PLL0_PC0_P1DIV_MASK | PMU1_PLL0_PC0_P2DIV_MASK), tmp);
3761 
3762 			/* Write ndiv_int and ndiv_mode to pllcontrol[2] */
3763 			tmp = ((xt->ndiv_int << PMU1_PLL0_PC2_NDIV_INT_SHIFT)
3764 					& PMU1_PLL0_PC2_NDIV_INT_MASK) |
3765 					((ndiv_mode << PMU1_PLL0_PC2_NDIV_MODE_SHIFT)
3766 					& PMU1_PLL0_PC2_NDIV_MODE_MASK);
3767 			si_pmu_pllcontrol(sih, PMU_PLL_CTRL_REG2,
3768 				(PMU1_PLL0_PC2_NDIV_INT_MASK | PMU1_PLL0_PC2_NDIV_MODE_MASK), tmp);
3769 			/* Write ndiv_frac to pllcontrol[3] */
3770 			tmp = ((xt->ndiv_frac << PMU1_PLL0_PC3_NDIV_FRAC_SHIFT) &
3771 				PMU1_PLL0_PC3_NDIV_FRAC_MASK);
3772 			si_pmu_pllcontrol(sih, PMU_PLL_CTRL_REG3,
3773 				PMU1_PLL0_PC3_NDIV_FRAC_MASK, tmp);
3774 		}
3775 
3776 		/* Write XtalFreq. Set the divisor also. */
3777 		tmp = R_REG(osh, &pmu->pmucontrol) &
3778 			~(PCTL_ILP_DIV_MASK | PCTL_XTALFREQ_MASK);
3779 		tmp |= (((((xt->fref + 127) / 128) - 1) << PCTL_ILP_DIV_SHIFT) &
3780 			PCTL_ILP_DIV_MASK) |
3781 			((xt->xf << PCTL_XTALFREQ_SHIFT) & PCTL_XTALFREQ_MASK);
3782 		W_REG(osh, &pmu->pmucontrol, tmp);
3783 	}
3784 
3785 exit:
3786 	/* Return to original core */
3787 	si_setcoreidx(sih, origidx);
3788 
3789 	return write_en;
3790 } /* si_pmu_update_pllcontrol */
3791 
3792 /* returns current value of PMUTimer.
3793 	also taking care of PR88659 by multiple reads.
3794 */
3795 uint32
BCMPOSTTRAPFN(si_pmu_get_pmutimer)3796 BCMPOSTTRAPFN(si_pmu_get_pmutimer)(si_t *sih)
3797 {
3798 	osl_t *osh = si_osh(sih);
3799 	pmuregs_t *pmu;
3800 	uint origidx;
3801 	uint32 start;
3802 	BCM_REFERENCE(sih);
3803 
3804 	origidx = si_coreidx(sih);
3805 	if (AOB_ENAB(sih)) {
3806 		pmu = si_setcore(sih, PMU_CORE_ID, 0);
3807 	} else {
3808 		pmu = si_setcoreidx(sih, SI_CC_IDX);
3809 	}
3810 	ASSERT(pmu != NULL);
3811 
3812 	start = R_REG(osh, &pmu->pmutimer);
3813 	if (start != R_REG(osh, &pmu->pmutimer))
3814 		start = R_REG(osh, &pmu->pmutimer);
3815 
3816 	si_setcoreidx(sih, origidx);
3817 
3818 	return (start);
3819 }
3820 
3821 /* Get current pmu time API */
3822 uint32
si_cur_pmu_time(si_t * sih)3823 si_cur_pmu_time(si_t *sih)
3824 {
3825 	uint origidx;
3826 	uint32 pmu_time;
3827 
3828 	/* Remember original core before switch to chipc/pmu */
3829 	origidx = si_coreidx(sih);
3830 
3831 	pmu_time = si_pmu_get_pmutimer(sih);
3832 
3833 	/* Return to original core */
3834 	si_setcoreidx(sih, origidx);
3835 	return (pmu_time);
3836 }
3837 
3838 /**
3839  * returns
3840  * a) diff between a 'prev' value of pmu timer and current value
3841  * b) the current pmutime value in 'prev'
3842  *  So, 'prev' is an IO parameter.
3843  */
3844 uint32
BCMPOSTTRAPFN(si_pmu_get_pmutime_diff)3845 BCMPOSTTRAPFN(si_pmu_get_pmutime_diff)(si_t *sih, osl_t *osh, pmuregs_t *pmu, uint32 *prev)
3846 {
3847 	uint32 pmutime_diff = 0, pmutime_val = 0;
3848 	uint32 prev_val = *prev;
3849 	BCM_REFERENCE(osh);
3850 	BCM_REFERENCE(pmu);
3851 	/* read current value */
3852 	pmutime_val = si_pmu_get_pmutimer(sih);
3853 	/* diff btween prev and current value, take on wraparound case as well. */
3854 	pmutime_diff = (pmutime_val >= prev_val) ?
3855 		(pmutime_val - prev_val) :
3856 		(~prev_val + pmutime_val + 1);
3857 	*prev = pmutime_val;
3858 	return pmutime_diff;
3859 }
3860 
3861 /**
3862  * wait for usec for the res_pending register to change.
3863  * NOTE: usec SHOULD be > 32uS
3864  * if cond = TRUE, res_pending will be read until it becomes == 0;
3865  * If cond = FALSE, res_pending will be read until it becomes != 0;
3866  * returns TRUE if timedout.
3867  * returns elapsed time in this loop in elapsed_time
3868  */
3869 bool
BCMPOSTTRAPFN(si_pmu_wait_for_res_pending)3870 BCMPOSTTRAPFN(si_pmu_wait_for_res_pending)(si_t *sih, osl_t *osh, pmuregs_t *pmu, uint usec,
3871 	bool cond, uint32 *elapsed_time)
3872 {
3873 	/* add 32uSec more */
3874 	uint countdown = usec;
3875 	uint32 pmutime_prev = 0, pmutime_elapsed = 0, res_pend;
3876 	bool pending = FALSE;
3877 
3878 	/* store current time */
3879 	pmutime_prev = si_pmu_get_pmutimer(sih);
3880 	while (1) {
3881 		res_pend = R_REG(osh, &pmu->res_pending);
3882 
3883 		/* based on the condition, check */
3884 		if (cond == TRUE) {
3885 			if (res_pend == 0) break;
3886 		} else {
3887 			if (res_pend != 0) break;
3888 		}
3889 
3890 		/* if required time over */
3891 		if ((pmutime_elapsed * PMU_US_STEPS) >= countdown) {
3892 			/* timeout. so return as still pending */
3893 			pending = TRUE;
3894 			break;
3895 		}
3896 
3897 		/* get elapsed time after adding diff between prev and current
3898 		* pmutimer value
3899 		*/
3900 		pmutime_elapsed += si_pmu_get_pmutime_diff(sih, osh, pmu, &pmutime_prev);
3901 	}
3902 
3903 	*elapsed_time = pmutime_elapsed * PMU_US_STEPS;
3904 	return pending;
3905 } /* si_pmu_wait_for_res_pending */
3906 
3907 /**
3908  *	The algorithm for pending check is that,
3909  *	step1: 	wait till (res_pending !=0) OR pmu_max_trans_timeout.
3910  *			if max_trans_timeout, flag error and exit.
3911  *			wait for 1 ILP clk [64uS] based on pmu timer,
3912  *			polling to see if res_pending again goes high.
3913  *			if res_pending again goes high, go back to step1.
3914  *	Note: res_pending is checked repeatedly because, in between switching
3915  *	of dependent
3916  *	resources, res_pending resets to 0 for a short duration of time before
3917  *	it becomes 1 again.
3918  *	Note: return 0 is GOOD, 1 is BAD [mainly timeout].
3919  */
3920 int
BCMPOSTTRAPFN(si_pmu_wait_for_steady_state)3921 BCMPOSTTRAPFN(si_pmu_wait_for_steady_state)(si_t *sih, osl_t *osh, pmuregs_t *pmu)
3922 {
3923 	si_info_t *sii = SI_INFO(sih);
3924 	int stat = 0;
3925 	bool timedout = FALSE;
3926 	uint32 elapsed = 0, pmutime_total_elapsed = 0;
3927 	uint32 pmutime_prev;
3928 
3929 	sii->res_pend_count = 0;
3930 
3931 	pmutime_prev = si_pmu_get_pmutimer(sih);
3932 
3933 	while (1) {
3934 		/* wait until all resources are settled down [till res_pending becomes 0] */
3935 		timedout = si_pmu_wait_for_res_pending(sih, osh, pmu,
3936 			PMU_MAX_TRANSITION_DLY, TRUE, &elapsed);
3937 
3938 		sii->res_state[sii->res_pend_count].low_time =
3939 			si_pmu_get_pmutime_diff(sih, osh, pmu, &pmutime_prev);
3940 		sii->res_state[sii->res_pend_count].low = R_REG(osh, &pmu->res_pending);
3941 
3942 		if (timedout) {
3943 			stat = 1;
3944 			break;
3945 		}
3946 
3947 		pmutime_total_elapsed += elapsed;
3948 		/* wait to check if any resource comes back to non-zero indicating
3949 		* that it pends again. The res_pending goes 0 for 1 ILP clock before
3950 		* getting set for next resource in the sequence , so if res_pending
3951 		* is 0 for more than 1 ILP clk it means nothing is pending
3952 		* to indicate some pending dependency.
3953 		*/
3954 		pmutime_prev = R_REG(osh, &pmu->pmutimer);
3955 		timedout = si_pmu_wait_for_res_pending(sih, osh, pmu,
3956 			64, FALSE, &elapsed);
3957 
3958 		pmutime_total_elapsed += elapsed;
3959 
3960 		sii->res_state[sii->res_pend_count].high_time =
3961 			si_pmu_get_pmutime_diff(sih, osh, pmu, &pmutime_prev);
3962 		sii->res_state[sii->res_pend_count].high = R_REG(osh, &pmu->res_pending);
3963 
3964 		/* Here, we can also check timedout, but we make sure that,
3965 		* we read the res_pending again.
3966 		*/
3967 
3968 		if (timedout) {
3969 			stat = 0;
3970 			break;
3971 		}
3972 
3973 		/* Total wait time for all the waits above added should be
3974 		* less than  PMU_MAX_TRANSITION_DLY
3975 		*/
3976 		if (pmutime_total_elapsed >= PMU_MAX_TRANSITION_DLY) {
3977 			/* timeout. so return as still pending */
3978 			stat = 1;
3979 			break;
3980 		}
3981 
3982 		sii->res_pend_count++;
3983 		sii->res_pend_count %= RES_PEND_STATS_COUNT;
3984 		pmutime_prev = R_REG(osh, &pmu->pmutimer);
3985 	}
3986 	return stat;
3987 } /* si_pmu_wait_for_steady_state */
3988 
3989 static uint32
si_pmu_pll_delay_43012(si_t * sih,uint32 delay_us,uint32 poll)3990 si_pmu_pll_delay_43012(si_t *sih, uint32 delay_us, uint32 poll)
3991 {
3992 	uint32 delay = 0;
3993 
3994 	/* In case of NIC builds, we can use OSL_DELAY() for 1 us delay. But in case of DONGLE
3995 	 * builds, we can't rely on the OSL_DELAY() as it is internally relying on HT clock and
3996 	 * we are calling this function when ALP clock is present.
3997 	 */
3998 #if defined(DONGLEBUILD)
3999 	uint32 initial, current;
4000 
4001 	initial = get_arm_cyclecount();
4002 	while (delay < delay_us) {
4003 		if (poll == 1) {
4004 			if (si_gci_chipstatus(sih, GCI_CHIPSTATUS_07) &
4005 					GCI43012_CHIPSTATUS_07_BBPLL_LOCK_MASK) {
4006 				goto exit;
4007 			}
4008 		}
4009 		current = get_arm_cyclecount();
4010 		delay = ((current - initial) * 1000) / si_xtalfreq(sih);
4011 	}
4012 #else
4013 	for (delay = 0; delay < delay_us; delay++) {
4014 		if (poll == 1) {
4015 			if (si_gci_chipstatus(sih, GCI_CHIPSTATUS_07) &
4016 					GCI43012_CHIPSTATUS_07_BBPLL_LOCK_MASK) {
4017 				goto exit;
4018 			}
4019 		}
4020 		OSL_DELAY(1);
4021 	}
4022 #endif /* BCMDONGLEHOST */
4023 
4024 	if (poll == 1) {
4025 		PMU_ERROR(("si_pmu_pll_delay_43012: PLL not locked!"));
4026 		ASSERT(0);
4027 	}
4028 exit:
4029 	return delay;
4030 }
4031 
4032 static void
si_pmu_pll_on_43012(si_t * sih,osl_t * osh,pmuregs_t * pmu,bool openloop_cal)4033 si_pmu_pll_on_43012(si_t *sih, osl_t *osh, pmuregs_t *pmu, bool openloop_cal)
4034 {
4035 	uint32 rsrc_ht, total_time = 0;
4036 
4037 	si_pmu_chipcontrol(sih, PMU_CHIPCTL4, PMUCCTL04_43012_FORCE_BBPLL_PWROFF, 0);
4038 	total_time += si_pmu_pll_delay_43012(sih, 2, 0);
4039 	si_pmu_chipcontrol(sih, PMU_CHIPCTL4, PMUCCTL04_43012_FORCE_BBPLL_ISOONHIGH |
4040 			PMUCCTL04_43012_FORCE_BBPLL_PWRDN, 0);
4041 	total_time += si_pmu_pll_delay_43012(sih, 2, 0);
4042 	si_pmu_chipcontrol(sih, PMU_CHIPCTL4, PMUCCTL04_43012_FORCE_BBPLL_ARESET, 0);
4043 
4044 	rsrc_ht = R_REG(osh, &pmu->res_state) &
4045 			((1 << RES43012_HT_AVAIL) | (1 << RES43012_HT_START));
4046 
4047 	if (rsrc_ht)
4048 	{
4049 		/* Wait for PLL to lock in close-loop */
4050 		total_time += si_pmu_pll_delay_43012(sih, 200, 1);
4051 	}
4052 	else {
4053 		/* Wait for 1 us for the open-loop clock to start */
4054 		total_time += si_pmu_pll_delay_43012(sih, 1, 0);
4055 	}
4056 
4057 	if (!openloop_cal) {
4058 		/* Allow clk to be used if its not calibration */
4059 		si_pmu_chipcontrol(sih, PMU_CHIPCTL4, PMUCCTL04_43012_FORCE_BBPLL_DRESET, 0);
4060 		total_time += si_pmu_pll_delay_43012(sih, 1, 0);
4061 		si_pmu_chipcontrol(sih, PMU_CHIPCTL4, PMUCCTL04_43012_DISABLE_LQ_AVAIL, 0);
4062 		si_pmu_chipcontrol(sih, PMU_CHIPCTL4, PMUCCTL04_43012_DISABLE_HT_AVAIL, 0);
4063 	}
4064 
4065 	PMU_MSG(("si_pmu_pll_on_43012: time taken: %d us\n", total_time));
4066 }
4067 
4068 static void
si_pmu_pll_off_43012(si_t * sih,osl_t * osh,pmuregs_t * pmu)4069 si_pmu_pll_off_43012(si_t *sih, osl_t *osh, pmuregs_t *pmu)
4070 {
4071 	uint32 total_time = 0;
4072 	BCM_REFERENCE(osh);
4073 	BCM_REFERENCE(pmu);
4074 	si_pmu_chipcontrol(sih, PMU_CHIPCTL4,
4075 			PMUCCTL04_43012_DISABLE_LQ_AVAIL | PMUCCTL04_43012_DISABLE_HT_AVAIL,
4076 			PMUCCTL04_43012_DISABLE_LQ_AVAIL | PMUCCTL04_43012_DISABLE_HT_AVAIL);
4077 	total_time += si_pmu_pll_delay_43012(sih, 1, 0);
4078 
4079 	si_pmu_chipcontrol(sih, PMU_CHIPCTL4,
4080 			(PMUCCTL04_43012_FORCE_BBPLL_ARESET | PMUCCTL04_43012_FORCE_BBPLL_DRESET |
4081 			PMUCCTL04_43012_FORCE_BBPLL_PWRDN |PMUCCTL04_43012_FORCE_BBPLL_ISOONHIGH),
4082 			(PMUCCTL04_43012_FORCE_BBPLL_ARESET | PMUCCTL04_43012_FORCE_BBPLL_DRESET |
4083 			PMUCCTL04_43012_FORCE_BBPLL_PWRDN |PMUCCTL04_43012_FORCE_BBPLL_ISOONHIGH));
4084 	total_time += si_pmu_pll_delay_43012(sih, 1, 0);
4085 
4086 	si_pmu_chipcontrol(sih, PMU_CHIPCTL4,
4087 			PMUCCTL04_43012_FORCE_BBPLL_PWROFF,
4088 			PMUCCTL04_43012_FORCE_BBPLL_PWROFF);
4089 
4090 	PMU_MSG(("si_pmu_pll_off_43012: time taken: %d us\n", total_time));
4091 }
4092 
4093 /** Turn Off the PLL - Required before setting the PLL registers */
4094 static void
si_pmu_pll_off(si_t * sih,osl_t * osh,pmuregs_t * pmu,uint32 * min_mask,uint32 * max_mask,uint32 * clk_ctl_st)4095 si_pmu_pll_off(si_t *sih, osl_t *osh, pmuregs_t *pmu, uint32 *min_mask,
4096 	uint32 *max_mask, uint32 *clk_ctl_st)
4097 {
4098 	uint32 ht_req;
4099 
4100 	/* Save the original register values */
4101 	*min_mask = R_REG(osh, &pmu->min_res_mask);
4102 	*max_mask = R_REG(osh, &pmu->max_res_mask);
4103 	*clk_ctl_st = si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, clk_ctl_st), 0, 0);
4104 
4105 	ht_req = si_pmu_htclk_mask(sih);
4106 	if (ht_req == 0)
4107 		return;
4108 
4109 	if ((CHIPID(sih->chip) == BCM43012_CHIP_ID) ||
4110 		(CHIPID(sih->chip) == BCM43013_CHIP_ID) ||
4111 		(CHIPID(sih->chip) == BCM43014_CHIP_ID) ||
4112 		(BCM4369_CHIP(sih->chip)) ||
4113 		(BCM4362_CHIP(sih->chip)) ||
4114 		(BCM4376_CHIP(sih->chip)) ||
4115 		(BCM4378_CHIP(sih->chip)) ||
4116 		(BCM4385_CHIP(sih->chip)) ||
4117 		(BCM4387_CHIP(sih->chip)) ||
4118 		(BCM4388_CHIP(sih->chip)) ||
4119 		(BCM4389_CHIP(sih->chip)) ||
4120 		BCM43602_CHIP(sih->chip) ||
4121 		0) {
4122 		/*
4123 		* If HT_AVAIL is not set, wait to see if any resources are availing HT.
4124 		*/
4125 		if (((si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, clk_ctl_st), 0, 0)
4126 			& CCS_HTAVAIL) != CCS_HTAVAIL))
4127 			si_pmu_wait_for_steady_state(sih, osh, pmu);
4128 	} else {
4129 		OR_REG(osh,  &pmu->max_res_mask, ht_req);
4130 		/* wait for HT to be ready before taking the HT away...HT could be coming up... */
4131 		SPINWAIT(((si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, clk_ctl_st), 0, 0)
4132 			& CCS_HTAVAIL) != CCS_HTAVAIL), PMU_MAX_TRANSITION_DLY);
4133 		ASSERT((si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, clk_ctl_st), 0, 0)
4134 			& CCS_HTAVAIL));
4135 	}
4136 
4137 	if ((CHIPID(sih->chip) == BCM43012_CHIP_ID) ||
4138 		(CHIPID(sih->chip) == BCM43013_CHIP_ID) ||
4139 		(CHIPID(sih->chip) == BCM43014_CHIP_ID)) {
4140 		si_pmu_pll_off_43012(sih, osh, pmu);
4141 	} else {
4142 		AND_REG(osh, &pmu->min_res_mask, ~ht_req);
4143 		AND_REG(osh, &pmu->max_res_mask, ~ht_req);
4144 
4145 		SPINWAIT(((si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, clk_ctl_st), 0, 0)
4146 			& CCS_HTAVAIL) == CCS_HTAVAIL), PMU_MAX_TRANSITION_DLY);
4147 		ASSERT(!(si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, clk_ctl_st), 0, 0)
4148 			& CCS_HTAVAIL));
4149 		OSL_DELAY(100);
4150 	}
4151 } /* si_pmu_pll_off */
4152 
4153 /* below function are for BBPLL parallel purpose */
4154 /** Turn Off the PLL - Required before setting the PLL registers */
4155 void
si_pmu_pll_off_PARR(si_t * sih,osl_t * osh,uint32 * min_mask,uint32 * max_mask,uint32 * clk_ctl_st)4156 si_pmu_pll_off_PARR(si_t *sih, osl_t *osh, uint32 *min_mask,
4157 uint32 *max_mask, uint32 *clk_ctl_st)
4158 {
4159 	pmuregs_t *pmu;
4160 	uint origidx;
4161 	bcm_int_bitmask_t intr_val;
4162 	uint32 ht_req;
4163 
4164 	/* Block ints and save current core */
4165 	si_introff(sih, &intr_val);
4166 	origidx = si_coreidx(sih);
4167 	if (AOB_ENAB(sih)) {
4168 		pmu = si_setcore(sih, PMU_CORE_ID, 0);
4169 	} else {
4170 		pmu = si_setcoreidx(sih, SI_CC_IDX);
4171 	}
4172 	ASSERT(pmu != NULL);
4173 
4174 	/* Save the original register values */
4175 	*min_mask = R_REG(osh, &pmu->min_res_mask);
4176 	*max_mask = R_REG(osh, &pmu->max_res_mask);
4177 	*clk_ctl_st = si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, clk_ctl_st), 0, 0);
4178 	ht_req = si_pmu_htclk_mask(sih);
4179 	if (ht_req == 0) {
4180 		/* Return to original core */
4181 		si_setcoreidx(sih, origidx);
4182 		si_intrrestore(sih, &intr_val);
4183 		return;
4184 	}
4185 
4186 	if ((CHIPID(sih->chip) == BCM43012_CHIP_ID) ||
4187 		(CHIPID(sih->chip) == BCM43013_CHIP_ID) ||
4188 		(CHIPID(sih->chip) == BCM43014_CHIP_ID) ||
4189 		(BCM4369_CHIP(sih->chip)) ||
4190 		(BCM4362_CHIP(sih->chip)) ||
4191 		(BCM4376_CHIP(sih->chip)) ||
4192 		(BCM4378_CHIP(sih->chip)) ||
4193 		(BCM4385_CHIP(sih->chip)) ||
4194 		(BCM4387_CHIP(sih->chip)) ||
4195 		(BCM4388_CHIP(sih->chip)) ||
4196 		(BCM4389_CHIP(sih->chip)) ||
4197 		(BCM4397_CHIP(sih->chip)) ||
4198 		(BCM43602_CHIP(sih->chip)) ||
4199 		0) {
4200 		/*
4201 		* If HT_AVAIL is not set, wait to see if any resources are availing HT.
4202 		*/
4203 		if (((si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, clk_ctl_st), 0, 0)
4204 			& CCS_HTAVAIL)
4205 			!= CCS_HTAVAIL))
4206 			si_pmu_wait_for_steady_state(sih, osh, pmu);
4207 	} else {
4208 		OR_REG(osh, &pmu->max_res_mask, ht_req);
4209 		/* wait for HT to be ready before taking the HT away...HT could be coming up... */
4210 		SPINWAIT(((si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, clk_ctl_st), 0, 0)
4211 			& CCS_HTAVAIL) != CCS_HTAVAIL), PMU_MAX_TRANSITION_DLY);
4212 		ASSERT((si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, clk_ctl_st), 0, 0)
4213 			& CCS_HTAVAIL));
4214 	}
4215 
4216 	AND_REG(osh, &pmu->min_res_mask, ~ht_req);
4217 	AND_REG(osh, &pmu->max_res_mask, ~ht_req);
4218 
4219 	/* Return to original core */
4220 	si_setcoreidx(sih, origidx);
4221 	si_intrrestore(sih, &intr_val);
4222 } /* si_pmu_pll_off_PARR */
4223 
4224 /** Turn ON/restore the PLL based on the mask received */
4225 static void
si_pmu_pll_on(si_t * sih,osl_t * osh,pmuregs_t * pmu,uint32 min_mask_mask,uint32 max_mask_mask,uint32 clk_ctl_st_mask)4226 si_pmu_pll_on(si_t *sih, osl_t *osh, pmuregs_t *pmu, uint32 min_mask_mask,
4227 	uint32 max_mask_mask, uint32 clk_ctl_st_mask)
4228 {
4229 	uint32 ht_req;
4230 
4231 	ht_req = si_pmu_htclk_mask(sih);
4232 	if (ht_req == 0)
4233 		return;
4234 
4235 	max_mask_mask &= ht_req;
4236 	min_mask_mask &= ht_req;
4237 
4238 	if (max_mask_mask != 0)
4239 		OR_REG(osh, &pmu->max_res_mask, max_mask_mask);
4240 
4241 	if (min_mask_mask != 0)
4242 		OR_REG(osh, &pmu->min_res_mask, min_mask_mask);
4243 
4244 	if (clk_ctl_st_mask & CCS_HTAVAIL) {
4245 		/* Wait for HT_AVAIL to come back */
4246 		SPINWAIT(((si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, clk_ctl_st), 0, 0)
4247 			& CCS_HTAVAIL) != CCS_HTAVAIL), PMU_MAX_TRANSITION_DLY);
4248 		ASSERT((si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, clk_ctl_st), 0, 0)
4249 		& CCS_HTAVAIL));
4250 	}
4251 
4252 	if ((CHIPID(sih->chip) == BCM43012_CHIP_ID) ||
4253 		(CHIPID(sih->chip) == BCM43013_CHIP_ID) ||
4254 		(CHIPID(sih->chip) == BCM43014_CHIP_ID)) {
4255 		si_pmu_pll_on_43012(sih, osh, pmu, 0);
4256 	}
4257 }
4258 
4259 /**
4260  * Set up PLL registers in the PMU as per the (optional) OTP values, or, if no OTP values are
4261  * present, optionally update with POR override values contained in firmware. Enables the BBPLL
4262  * when done.
4263  */
4264 static void
BCMATTACHFN(si_pmu1_pllinit1)4265 BCMATTACHFN(si_pmu1_pllinit1)(si_t *sih, osl_t *osh, pmuregs_t *pmu, uint32 xtal)
4266 {
4267 	char name[16];
4268 	const char *otp_val;
4269 	uint8 i, otp_entry_found = FALSE;
4270 	uint32 pll_ctrlcnt;
4271 	uint32 min_mask = 0, max_mask = 0, clk_ctl_st = 0;
4272 #if defined(BTOVERPCIE) && !defined(BTOVERPCIE_DISABLED)
4273 	uint32 otpval = 0, regval = 0;
4274 #endif /* defined(BTOVERPCIE) && !defined(BTOVERPCIE_DISABLED) */
4275 
4276 	if (!FWSIGN_ENAB()) {
4277 		if (PMUREV(sih->pmurev) >= 5) {
4278 			pll_ctrlcnt = (sih->pmucaps & PCAP5_PC_MASK) >> PCAP5_PC_SHIFT;
4279 		} else {
4280 			pll_ctrlcnt = (sih->pmucaps & PCAP_PC_MASK) >> PCAP_PC_SHIFT;
4281 		}
4282 
4283 		/* Check if there is any otp enter for PLLcontrol registers */
4284 		for (i = 0; i < pll_ctrlcnt; i++) {
4285 			snprintf(name, sizeof(name), rstr_pllD, i);
4286 			if ((otp_val = getvar(NULL, name)) == NULL)
4287 				continue;
4288 
4289 			/* If OTP entry is found for PLL register, then turn off the PLL
4290 			 * and set the status of the OTP entry accordingly.
4291 			 */
4292 			otp_entry_found = TRUE;
4293 			break;
4294 		}
4295 	}
4296 
4297 	/* If no OTP parameter is found and no chip-specific updates are needed, return. */
4298 	if ((otp_entry_found == FALSE) &&
4299 		(si_pmu_update_pllcontrol(sih, osh, xtal, FALSE) == FALSE)) {
4300 #if defined(BTOVERPCIE) && !defined(BTOVERPCIE_DISABLED)
4301 		/*
4302 		 * For 4369/4362 PLL3 could be prorammed by BT, check the value is default and not
4303 		 * overrided by BT
4304 		 */
4305 		if ((BCM4369_CHIP(sih->chip) || BCM4362_CHIP(sih->chip)) &&
4306 			(regval = si_pmu_pllcontrol(sih, 3, 0, 0)) != PMU_PLL3_4369B0_DEFAULT) {
4307 			PMU_ERROR(("Default PLL3 value 0x%x is not same as programmed"
4308 						"value 0x%x\n", PMU_PLL3_4369B0_DEFAULT, regval));
4309 			hnd_gcisem_set_err(GCI_PLL_LOCK_SEM);
4310 			return;
4311 		}
4312 
4313 		/* Update SW_READY bit indicating WLAN is ready and verified PLL3 */
4314 		si_gci_output(sih, GCI_ECI_SW1(GCI_WLAN_IP_ID), GCI_SWREADY, GCI_SWREADY);
4315 #endif /* defined(BTOVERPCIE) && !defined(BTOVERPCIE_DISABLED) */
4316 		return;
4317 	}
4318 
4319 #if defined(BTOVERPCIE) && !defined(BTOVERPCIE_DISABLED)
4320 	if ((hnd_gcisem_acquire(GCI_PLL_LOCK_SEM, TRUE, GCI_PLL_LOCK_SEM_TIMEOUT) != BCME_OK)) {
4321 		PMU_ERROR(("Failed to get GCI PLL Lock semaphore...\n"));
4322 		hnd_gcisem_set_err(GCI_PLL_LOCK_SEM);
4323 		return;
4324 	}
4325 
4326 	/* Skip BB PLL programming if BT has already done it, which is indicated by SW_READY bit */
4327 	if (si_gci_input(sih, GCI_ECI_SW1(GCI_BT_IP_ID)) & GCI_SWREADY) {
4328 		PMU_MSG(("PLL is already programmed\n"));
4329 
4330 		/* Program ARM PLL only if xtalfreq(pllctrl6) programmed is different from xtal */
4331 		if (si_pmu_update_pllcontrol(sih, osh, xtal, FALSE)) {
4332 			/* Make sure PLL is off */
4333 			si_pmu_pll_off(sih, osh, pmu, &min_mask, &max_mask, &clk_ctl_st);
4334 
4335 			/* for 4369, arm clk cycle can be set from nvram - default is 400 MHz */
4336 			if ((BCM4369_CHIP(sih->chip) || BCM4362_CHIP(sih->chip)) &&
4337 				(pll_ctrlcnt > PMU1_PLL0_PLLCTL6)) {
4338 				PMU_MSG(("Programming ARM CLK\n"));
4339 				si_pmu_pll6val_armclk_calc(osh, pmu,
4340 					si_get_armpllclkfreq(sih), xtal, TRUE);
4341 			}
4342 
4343 			/* Flush ('update') the deferred pll control registers writes */
4344 			if (PMUREV(sih->pmurev) >= 2)
4345 				OR_REG(osh, &pmu->pmucontrol, PCTL_PLL_PLLCTL_UPD);
4346 
4347 			/* Restore back the register values. This ensures PLL remains on if it
4348 			 * was originally on and remains off if it was originally off.
4349 			 */
4350 			si_pmu_pll_on(sih, osh, pmu, min_mask, max_mask, clk_ctl_st);
4351 		}
4352 
4353 		snprintf(name, sizeof(name), rstr_pllD, 3);
4354 		if ((otp_val = getvar(NULL, name)) != NULL) {
4355 			otpval = (uint32)bcm_strtoul(otp_val, NULL, 0);
4356 			if ((regval = si_pmu_pllcontrol(sih, 3, 0, 0)) != otpval) {
4357 				PMU_ERROR(("PLL3 programming value 0x%x is not same as programmed"
4358 					"value 0x%x\n", otpval, regval));
4359 				hnd_gcisem_set_err(GCI_PLL_LOCK_SEM);
4360 			}
4361 		}
4362 		goto done;
4363 	}
4364 #endif /* defined(BTOVERPCIE) && !defined(BTOVERPCIE_DISABLED) */
4365 
4366 	/* Make sure PLL is off */
4367 	si_pmu_pll_off(sih, osh, pmu, &min_mask, &max_mask, &clk_ctl_st);
4368 
4369 	/* Update any chip-specific PLL registers. Does not write PLL 'update' bit yet. */
4370 	si_pmu_update_pllcontrol(sih, osh, xtal, TRUE);
4371 
4372 	/* Update the PLL register if there is a OTP entry for PLL registers */
4373 	si_pmu_otp_pllcontrol(sih, osh);
4374 
4375 	/* Flush ('update') the deferred pll control registers writes */
4376 	if (PMUREV(sih->pmurev) >= 2)
4377 		OR_REG(osh, &pmu->pmucontrol, PCTL_PLL_PLLCTL_UPD);
4378 
4379 	/* Restore back the register values. This ensures PLL remains on if it
4380 	 * was originally on and remains off if it was originally off.
4381 	 */
4382 	si_pmu_pll_on(sih, osh, pmu, min_mask, max_mask, clk_ctl_st);
4383 
4384 	if ((CHIPID(sih->chip) == BCM43012_CHIP_ID) ||
4385 		(CHIPID(sih->chip) == BCM43013_CHIP_ID) ||
4386 		(CHIPID(sih->chip) == BCM43014_CHIP_ID)) {
4387 		uint32 origidx;
4388 		/* PMU clock stretch to be decreased to 8 for HT and ALP
4389 		* to reduce DS0 current during high traffic
4390 		*/
4391 		W_REG(osh, &pmu->clkstretch, CSTRETCH_REDUCE_8);
4392 
4393 		/* SDIOD to request for ALP
4394 		* to reduce DS0 current during high traffic
4395 		*/
4396 		origidx = si_coreidx(sih);
4397 		si_setcore(sih, SDIOD_CORE_ID, 0);
4398 		/* Clear the Bit 8 for ALP REQUEST change */
4399 		si_wrapperreg(sih, AI_OOBSELOUTB30, (AI_OOBSEL_MASK << AI_OOBSEL_1_SHIFT),
4400 			OOB_B_ALP_REQUEST << AI_OOBSEL_1_SHIFT);
4401 		si_setcoreidx(sih, origidx);
4402 	}
4403 
4404 #if defined(BTOVERPCIE) && !defined(BTOVERPCIE_DISABLED)
4405 done:
4406 	/* Update SW_READY bit indicating WLAN is done programming PLL registers */
4407 	si_gci_output(sih, GCI_ECI_SW1(GCI_WLAN_IP_ID), GCI_SWREADY, GCI_SWREADY);
4408 	if ((hnd_gcisem_release(GCI_PLL_LOCK_SEM) != BCME_OK)) {
4409 		PMU_ERROR(("Failed to release GCI PLL Lock semaphore...\n"));
4410 		hnd_gcisem_set_err(GCI_PLL_LOCK_SEM);
4411 	}
4412 #endif /* defined(BTOVERPCIE) && !defined(BTOVERPCIE_DISABLED) */
4413 } /* si_pmu1_pllinit1 */
4414 
4415 #if defined(EDV)
4416 /* returns backplane clk programmed in pll cntl 1 */
4417 /* WHY NOT JUST CALL si_pmu_si_clock()? */
si_pmu_get_backplaneclkspeed(si_t * sih)4418 uint32 si_pmu_get_backplaneclkspeed(si_t *sih)
4419 {
4420 	uint32 FVCO;
4421 	uint32 tmp, mdiv = 1;
4422 
4423 	switch (CHIPID(sih->chip)) {
4424 	case BCM4385_CHIP_GRPID:
4425 	case BCM4387_CHIP_GRPID:
4426 	case BCM4388_CHIP_GRPID:
4427 	case BCM4389_CHIP_GRPID:
4428 	case BCM4397_CHIP_GRPID:
4429 		return si_pmu_bpclk_4387(sih);
4430 	default:
4431 		break;
4432 	}
4433 
4434 	FVCO =  si_pmu1_pllfvco0(sih);
4435 
4436 	switch (CHIPID(sih->chip)) {
4437 	case BCM4369_CHIP_GRPID:
4438 	case BCM4376_CHIP_GRPID:
4439 	case BCM4378_CHIP_GRPID:
4440 		tmp = si_pmu_pllcontrol(sih, PMU_PLL_CTRL_REG1, 0, 0);
4441 		mdiv = (tmp & PMU1_PLL0_PC1_M4DIV_MASK) >> PMU1_PLL0_PC1_M4DIV_SHIFT;
4442 		break;
4443 	default:
4444 		ASSERT(FALSE);
4445 		break;
4446 	}
4447 	return FVCO / mdiv * 1000u;
4448 }
4449 
4450 /* Update backplane clock speed */
4451 void
si_pmu_update_backplane_clock(si_t * sih,osl_t * osh,uint reg,uint32 mask,uint32 val)4452 si_pmu_update_backplane_clock(si_t *sih, osl_t *osh, uint reg, uint32 mask, uint32 val)
4453 {
4454 
4455 	pmuregs_t *pmu;
4456 	uint origidx;
4457 	uint32 max_mask = 0, min_mask = 0, clk_ctl_st = 0;
4458 
4459 	/* Remember original core before switch to chipc/pmu */
4460 	origidx = si_coreidx(sih);
4461 
4462 	if (AOB_ENAB(sih)) {
4463 		pmu = si_setcore(sih, PMU_CORE_ID, 0);
4464 	} else {
4465 		pmu = si_setcoreidx(sih, SI_CC_IDX);
4466 	}
4467 
4468 	ASSERT(pmu != NULL);
4469 
4470 	/* Make sure PLL is off */
4471 	si_pmu_pll_off(sih, osh, pmu, &min_mask, &max_mask, &clk_ctl_st);
4472 
4473 	si_pmu_pllcontrol(sih, reg, mask, val);
4474 
4475 	/* Flush ('update') the deferred pll control registers writes */
4476 	if (PMUREV(sih->pmurev) >= 2)
4477 		OR_REG(osh, &pmu->pmucontrol, PCTL_PLL_PLLCTL_UPD);
4478 
4479 	/* Restore back the register values. This ensures PLL remains on if it
4480 	 * was originally on and remains off if it was originally off.
4481 	 */
4482 	si_pmu_pll_on(sih, osh, pmu, min_mask, max_mask, clk_ctl_st);
4483 	si_setcoreidx(sih, origidx);
4484 }
4485 #endif /* si_pmu_update_backplane_clock */
4486 
4487 /**
4488  * returns the backplane clock frequency.
4489  * Does this by determining current Fvco and the setting of the
4490  * clock divider that leads up to the backplane. Returns value in [Hz] units.
4491  */
4492 static uint32
BCMPOSTTRAPFN(si_pmu_bpclk_4387)4493 BCMPOSTTRAPFN(si_pmu_bpclk_4387)(si_t *sih)
4494 {
4495 	uint32 tmp, mdiv;
4496 	uint32 FVCO;	/* in [khz] units */
4497 
4498 	FVCO = si_pmu1_pllfvco0(sih);
4499 
4500 	tmp = si_pmu_pllcontrol(sih, PMU_PLL_CTRL_REG2, 0, 0);
4501 	mdiv = (tmp & PMU4387_PLL0_PC2_ICH3_MDIV_MASK);
4502 	ASSERT(mdiv != 0);
4503 
4504 	return FVCO / mdiv * 1000;
4505 }
4506 
4507 /**
4508  * returns the CPU clock frequency. Does this by determining current Fvco and the setting of the
4509  * clock divider that leads up to the ARM. Returns value in [Hz] units.
4510  */
4511 static uint32
BCMPOSTTRAPFN(si_pmu1_cpuclk0)4512 BCMPOSTTRAPFN(si_pmu1_cpuclk0)(si_t *sih, osl_t *osh, pmuregs_t *pmu)
4513 {
4514 	uint32 tmp, mdiv = 1;
4515 #ifdef BCMDBG
4516 	uint32 ndiv_int, ndiv_frac, p2div, p1div, fvco;
4517 	uint32 fref;
4518 #endif
4519 #ifdef BCMDBG_PMU
4520 	char chn[8];
4521 #endif
4522 	uint32 FVCO;	/* in [khz] units */
4523 
4524 	FVCO = si_pmu1_pllfvco0(sih);
4525 
4526 	if (BCM43602_CHIP(sih->chip) &&
4527 #ifdef DONGLEBUILD
4528 #ifdef __arm__
4529 	    (si_arm_clockratio(sih, 0) == 1) &&
4530 #endif
4531 #endif /* DONGLEBUILD */
4532 		TRUE) {
4533 		/* CR4 running on backplane_clk */
4534 		return si_pmu_si_clock(sih, osh);	/* in [hz] units */
4535 	}
4536 
4537 	switch (CHIPID(sih->chip)) {
4538 	case BCM4360_CHIP_ID:
4539 	case BCM43460_CHIP_ID:
4540 	case BCM43526_CHIP_ID:
4541 	case BCM4352_CHIP_ID:
4542 		/* Read m6div from pllcontrol[5] */
4543 		tmp = si_pmu_pllcontrol(sih, PMU_PLL_CTRL_REG5, 0, 0);
4544 		mdiv = (tmp & PMU1_PLL0_PC2_M6DIV_MASK) >> PMU1_PLL0_PC2_M6DIV_SHIFT;
4545 		break;
4546 #ifdef DONGLEBUILD
4547 	CASE_BCM43602_CHIP:
4548 #ifdef __arm__
4549 		ASSERT(si_arm_clockratio(sih, 0) == 2);
4550 #endif
4551 		/* CR4 running on armcr4_clk (Ch5). Read 'bbpll_i_m5div' from pllctl[5] */
4552 		tmp = si_pmu_pllcontrol(sih, PMU_PLL_CTRL_REG5, 0, 0);
4553 		mdiv = (tmp & PMU1_PLL0_PC2_M5DIV_MASK) >> PMU1_PLL0_PC2_M5DIV_SHIFT;
4554 		break;
4555 	case BCM43012_CHIP_ID:
4556 	case BCM43013_CHIP_ID:
4557 	case BCM43014_CHIP_ID:
4558 		/* mdiv is not supported for 43012 and FVCO frequency should be divided by 2 */
4559 		mdiv = 2;
4560 		break;
4561 #endif /* DONGLEBUILD */
4562 
4563 	case BCM4369_CHIP_GRPID:
4564 		tmp = si_pmu_pllcontrol(sih, PMU_PLL_CTRL_REG1, 0, 0);
4565 		mdiv = (tmp & PMU1_PLL0_PC1_M4DIV_MASK) >> PMU1_PLL0_PC1_M4DIV_SHIFT;
4566 		break;
4567 	case BCM4362_CHIP_GRPID:
4568 		tmp = si_pmu_pllcontrol(sih, PMU_PLL_CTRL_REG1, 0, 0);
4569 		mdiv = (tmp & PMU1_PLL0_PC1_M4DIV_MASK) >> PMU1_PLL0_PC1_M4DIV_SHIFT;
4570 		break;
4571 
4572 	case BCM4376_CHIP_GRPID:
4573 	case BCM4378_CHIP_GRPID:
4574 		tmp = si_pmu_pllcontrol(sih, PMU_PLL_CTRL_REG1, 0, 0);
4575 		mdiv = (tmp & PMU1_PLL0_PC1_M4DIV_MASK) >> PMU1_PLL0_PC1_M4DIV_SHIFT;
4576 		break;
4577 
4578 	default:
4579 		PMU_MSG(("si_pmu1_cpuclk0: Unknown chipid %s\n", bcm_chipname(sih->chip, chn, 8)));
4580 		ASSERT(0);
4581 		break;
4582 	}
4583 
4584 	ASSERT(mdiv != 0);
4585 
4586 #ifdef BCMDBG
4587 	/* Read p2div/p1div from pllcontrol[0] */
4588 	tmp = si_pmu_pllcontrol(sih, PMU_PLL_CTRL_REG0, 0, 0);
4589 	p2div = (tmp & PMU1_PLL0_PC0_P2DIV_MASK) >> PMU1_PLL0_PC0_P2DIV_SHIFT;
4590 	p1div = (tmp & PMU1_PLL0_PC0_P1DIV_MASK) >> PMU1_PLL0_PC0_P1DIV_SHIFT;
4591 
4592 	/* Calculate fvco based on xtal freq and ndiv and pdiv */
4593 	tmp = PMU1_PLL0_PLLCTL2;
4594 
4595 	tmp = si_pmu_pllcontrol(sih, tmp, 0, 0);
4596 
4597 	if (BCM4362_CHIP(sih->chip) ||
4598 		BCM4369_CHIP(sih->chip)) {
4599 		p2div = 1;
4600 		p1div = (tmp & PMU4369_PLL0_PC2_PDIV_MASK) >> PMU4369_PLL0_PC2_PDIV_SHIFT;
4601 		ndiv_int = (tmp & PMU4369_PLL0_PC2_NDIV_INT_MASK) >>
4602 					PMU4369_PLL0_PC2_NDIV_INT_SHIFT;
4603 	} else if (BCM4378_CHIP(sih->chip) || BCM4376_CHIP(sih->chip)) {
4604 		p2div = 1;
4605 		p1div = (tmp & PMU4378_PLL0_PC2_P1DIV_MASK) >> PMU4378_PLL0_PC2_P1DIV_SHIFT;
4606 		ndiv_int = (tmp & PMU4378_PLL0_PC2_NDIV_INT_MASK) >>
4607 					PMU4378_PLL0_PC2_NDIV_INT_SHIFT;
4608 	} else {
4609 		ndiv_int = (tmp & PMU1_PLL0_PC2_NDIV_INT_MASK) >> PMU1_PLL0_PC2_NDIV_INT_SHIFT;
4610 	}
4611 
4612 	ASSERT(p1div != 0);
4613 
4614 	tmp = PMU1_PLL0_PLLCTL3;
4615 
4616 	tmp = si_pmu_pllcontrol(sih, tmp, 0, 0);
4617 
4618 	if (BCM4369_CHIP(sih->chip) || BCM4362_CHIP(sih->chip) ||
4619 	    BCM4376_CHIP(sih->chip) ||
4620 	    BCM4378_CHIP(sih->chip) ||
4621 	    FALSE) {
4622 			ndiv_frac =
4623 				(tmp & PMU4369_PLL0_PC3_NDIV_FRAC_MASK) >>
4624 				PMU4369_PLL0_PC3_NDIV_FRAC_SHIFT;
4625 		fref = si_pmu1_alpclk0(sih, osh, pmu) / 1000; /* [KHz] */
4626 
4627 		fvco = (fref * ndiv_int) << 8;
4628 		fvco += (fref * ((ndiv_frac & 0xfffff) >> 4)) >> 8;
4629 		fvco >>= 8;
4630 		fvco *= p1div;
4631 		fvco /= 1000;
4632 		fvco *= 1000;
4633 	} else {
4634 		ndiv_frac =
4635 			(tmp & PMU1_PLL0_PC3_NDIV_FRAC_MASK) >> PMU1_PLL0_PC3_NDIV_FRAC_SHIFT;
4636 
4637 		fref = si_pmu1_alpclk0(sih, osh, pmu) / 1000;
4638 
4639 		fvco = (fref * ndiv_int) << 8;
4640 		fvco += (fref * (ndiv_frac >> 12)) >> 4;
4641 		fvco += (fref * (ndiv_frac & 0xfff)) >> 12;
4642 		fvco >>= 8;
4643 		fvco *= p2div;
4644 		fvco /= p1div;
4645 		fvco /= 1000;
4646 		fvco *= 1000;
4647 	}
4648 
4649 	PMU_MSG(("si_pmu1_cpuclk0: ndiv_int %u ndiv_frac %u p2div %u p1div %u fvco %u\n",
4650 	         ndiv_int, ndiv_frac, p2div, p1div, fvco));
4651 
4652 	FVCO = fvco;
4653 #endif	/* BCMDBG */
4654 
4655 	return FVCO / mdiv * 1000; /* Return CPU clock in [Hz] */
4656 } /* si_pmu1_cpuclk0 */
4657 
4658 /**
4659  * BCM4369/4378/4387 specific function returning the CPU clock frequency.
4660  * Does this by determining current Fvco and the setting of the clock divider that leads up to
4661  * the ARM.
4662  * Returns value in [Hz] units.
4663  */
4664 static uint32
BCMPOSTTRAPFN(si_pmu1_cpuclk0_pll2)4665 BCMPOSTTRAPFN(si_pmu1_cpuclk0_pll2)(si_t *sih)
4666 {
4667 	uint32 FVCO = si_pmu1_pllfvco0_pll2(sih);	/* in [khz] units */
4668 
4669 	/* Return ARM/SB clock */
4670 	return FVCO * 1000;
4671 } /* si_pmu1_cpuclk0_pll2 */
4672 
4673 /**
4674  * Returns the MAC clock frequency. Called when e.g. MAC clk frequency has to change because of
4675  * interference mitigation.
4676  */
4677 uint32
si_mac_clk(si_t * sih,osl_t * osh)4678 si_mac_clk(si_t *sih, osl_t *osh)
4679 {
4680 	uint8 mdiv2 = 0;
4681 	uint32 mac_clk = 0;
4682 	chipcregs_t *cc;
4683 	uint origidx;
4684 	bcm_int_bitmask_t intr_val;
4685 #ifdef BCMDBG_PMU
4686 	char chn[8];
4687 #endif
4688 
4689 	uint32 FVCO = si_pmu1_pllfvco0(sih);	/* in [khz] units */
4690 
4691 	BCM_REFERENCE(osh);
4692 
4693 	/* Remember original core before switch to chipc */
4694 	cc = (chipcregs_t *)si_switch_core(sih, CC_CORE_ID, &origidx, &intr_val);
4695 	ASSERT(cc != NULL);
4696 	BCM_REFERENCE(cc);
4697 
4698 	switch (CHIPID(sih->chip)) {
4699 	case BCM43012_CHIP_ID:
4700 	case BCM43013_CHIP_ID:
4701 	case BCM43014_CHIP_ID:
4702 		mdiv2 = 2;
4703 		mac_clk = FVCO / mdiv2;
4704 		break;
4705 	default:
4706 		PMU_MSG(("si_mac_clk: Unknown chipid %s\n",
4707 			bcm_chipname(CHIPID(sih->chip), chn, 8)));
4708 		ASSERT(0);
4709 		break;
4710 	}
4711 
4712 	/* Return to original core */
4713 	si_restore_core(sih, origidx, &intr_val);
4714 
4715 	return mac_clk;
4716 } /* si_mac_clk */
4717 
4718 /* 4387 pll MAC channel divisor - for ftm */
4719 static uint32
si_pmu_macdiv_4387(si_t * sih)4720 si_pmu_macdiv_4387(si_t *sih)
4721 {
4722 	uint32 tmp, mdiv;
4723 
4724 	/* TODO: when it's needed return different MAC clock freq.
4725 	 * for different MAC/slice!
4726 	 */
4727 	tmp = si_pmu_pllcontrol(sih, PMU_PLL_CTRL_REG1, 0, 0);
4728 	mdiv = (tmp & PMU4387_PLL0_PC1_ICH2_MDIV_MASK) >> PMU4387_PLL0_PC1_ICH2_MDIV_SHIFT;
4729 	ASSERT(mdiv != 0);
4730 
4731 	return mdiv;
4732 }
4733 
4734 /** Get chip's FVCO and PLLCTRL1 register value */
4735 int
si_pmu_fvco_macdiv(si_t * sih,uint32 * fvco,uint32 * div)4736 si_pmu_fvco_macdiv(si_t *sih, uint32 *fvco, uint32 *div)
4737 {
4738 	chipcregs_t *cc;
4739 	uint origidx;
4740 	bcm_int_bitmask_t intr_val;
4741 	int err = BCME_OK;
4742 #ifdef BCMDBG_PMU
4743 	char chn[8];
4744 #endif
4745 
4746 	if (fvco)
4747 		*fvco = si_pmu1_pllfvco0(sih)/1000;
4748 
4749 	/* Remember original core before switch to chipc */
4750 	cc = (chipcregs_t *)si_switch_core(sih, CC_CORE_ID, &origidx, &intr_val);
4751 	ASSERT(cc != NULL);
4752 	BCM_REFERENCE(cc);
4753 
4754 	switch (CHIPID(sih->chip)) {
4755 	case BCM4360_CHIP_ID:
4756 	case BCM43460_CHIP_ID:
4757 		if (div)
4758 			*div = si_pmu_pllcontrol(sih, PMU_PLL_CTRL_REG12, 0, 0) &
4759 				PMU1_PLL0_PC1_M1DIV_MASK;
4760 		break;
4761 
4762 	case BCM43602_CHIP_ID:
4763 		if (div) {
4764 			*div = (si_pmu_pllcontrol(sih, PMU_PLL_CTRL_REG4, 0, 0) &
4765 				PMU1_PLL0_PC1_M3DIV_MASK) >> PMU1_PLL0_PC1_M3DIV_SHIFT;
4766 		}
4767 		break;
4768 	case BCM4369_CHIP_GRPID:
4769 	case BCM4362_CHIP_GRPID:
4770 		if (div) {
4771 			*div = (si_pmu_pllcontrol(sih, PMU1_PLL0_PLLCTL1, 0, 0)
4772 				& PMU1_PLL0_PC1_M4DIV_MASK) >> PMU1_PLL0_PC1_M4DIV_SHIFT;
4773 		}
4774 		break;
4775 	case BCM43012_CHIP_ID:
4776 	case BCM43013_CHIP_ID:
4777 	case BCM43014_CHIP_ID:
4778 		 /* mDIV is not supported for 43012 & divisor value is always 2 */
4779 		if (div)
4780 			*div = 2;
4781 		break;
4782 	case BCM4376_CHIP_GRPID:
4783 	case BCM4378_CHIP_GRPID:
4784 		if (div) {
4785 			*div = (si_pmu_pllcontrol(sih, PMU1_PLL0_PLLCTL1, 0, 0)
4786 				& PMU1_PLL0_PC1_M4DIV_MASK) >> PMU1_PLL0_PC1_M4DIV_SHIFT;
4787 		}
4788 		break;
4789 	case BCM4385_CHIP_GRPID:
4790 	case BCM4387_CHIP_GRPID:
4791 	case BCM4389_CHIP_GRPID:
4792 	case BCM4388_CHIP_GRPID:
4793 		if (div) {
4794 			*div = si_pmu_macdiv_4387(sih);
4795 		}
4796 		break;
4797 	default:
4798 		PMU_MSG(("si_mac_clk: Unknown chipid %s\n", bcm_chipname(sih->chip, chn, 8)));
4799 		err = BCME_ERROR;
4800 	}
4801 
4802 	/* Return to original core */
4803 	si_restore_core(sih, origidx, &intr_val);
4804 
4805 	return err;
4806 }
4807 
4808 /** Return TRUE if scan retention memory's sleep/pm signal was asserted */
4809 bool
BCMPOSTTRAPFN(si_pmu_reset_ret_sleep_log)4810 BCMPOSTTRAPFN(si_pmu_reset_ret_sleep_log)(si_t *sih, osl_t *osh)
4811 {
4812 	pmuregs_t *pmu;
4813 	uint origidx;
4814 	uint32 ret_ctl;
4815 	bool was_sleep = FALSE;
4816 
4817 	/* Remember original core before switch to chipc */
4818 	origidx = si_coreidx(sih);
4819 	if (AOB_ENAB(sih)) {
4820 		pmu = si_setcore(sih, PMU_CORE_ID, 0);
4821 	} else {
4822 		pmu = si_setcoreidx(sih, SI_CC_IDX);
4823 	}
4824 	ASSERT(pmu != NULL);
4825 
4826 	ret_ctl = R_REG(osh, &pmu->retention_ctl);
4827 	if (ret_ctl & RCTL_MEM_RET_SLEEP_LOG_MASK) {
4828 		W_REG(osh, &pmu->retention_ctl, ret_ctl);
4829 		was_sleep = TRUE;
4830 	}
4831 
4832 	/* Return to original core */
4833 	si_setcoreidx(sih, origidx);
4834 
4835 	return was_sleep;
4836 }
4837 
4838 /** Return TRUE if pmu rsrc XTAL_PU was de-asserted */
4839 bool
BCMPOSTTRAPFN(si_pmu_reset_chip_sleep_log)4840 BCMPOSTTRAPFN(si_pmu_reset_chip_sleep_log)(si_t *sih, osl_t *osh)
4841 {
4842 	pmuregs_t *pmu;
4843 	uint origidx;
4844 	bool was_sleep = FALSE;
4845 
4846 	/* Remember original core before switch to chipc */
4847 	origidx = si_coreidx(sih);
4848 	if (AOB_ENAB(sih)) {
4849 		pmu = si_setcore(sih, PMU_CORE_ID, 0);
4850 	} else {
4851 		pmu = si_setcoreidx(sih, SI_CC_IDX);
4852 	}
4853 	ASSERT(pmu != NULL);
4854 
4855 	if (PMUREV(sih->pmurev) >= 36) {
4856 		uint32 pmu_int_sts = R_REG(osh, &pmu->pmuintstatus);
4857 		if (pmu_int_sts & PMU_INT_STAT_RSRC_EVENT_INT0_MASK) {
4858 			/* write 1 to clear the status */
4859 			W_REG(osh, &pmu->pmuintstatus, PMU_INT_STAT_RSRC_EVENT_INT0_MASK);
4860 			was_sleep = TRUE;
4861 		}
4862 	} else {
4863 		was_sleep = si_pmu_reset_ret_sleep_log(sih, osh);
4864 	}
4865 
4866 	/* Return to original core */
4867 	si_setcoreidx(sih, origidx);
4868 
4869 	return was_sleep;
4870 }
4871 
4872 /* For 43602a0 MCH2/MCH5 boards: power up PA Reference LDO */
4873 void
si_pmu_switch_on_PARLDO(si_t * sih,osl_t * osh)4874 si_pmu_switch_on_PARLDO(si_t *sih, osl_t *osh)
4875 {
4876 	uint32 mask;
4877 	pmuregs_t *pmu;
4878 	uint origidx;
4879 
4880 	/* Remember original core before switch to chipc/pmu */
4881 	origidx = si_coreidx(sih);
4882 	if (AOB_ENAB(sih)) {
4883 		pmu = si_setcore(sih, PMU_CORE_ID, 0);
4884 	} else {
4885 		pmu = si_setcoreidx(sih, SI_CC_IDX);
4886 	}
4887 	ASSERT(pmu != NULL);
4888 
4889 	switch (CHIPID(sih->chip)) {
4890 	CASE_BCM43602_CHIP:
4891 		mask = R_REG(osh, &pmu->min_res_mask) | PMURES_BIT(RES43602_PARLDO_PU);
4892 		W_REG(osh, &pmu->min_res_mask, mask);
4893 		mask = R_REG(osh, &pmu->max_res_mask) | PMURES_BIT(RES43602_PARLDO_PU);
4894 		W_REG(osh, &pmu->max_res_mask, mask);
4895 		break;
4896 	default:
4897 		break;
4898 	}
4899 	/* Return to original core */
4900 	si_setcoreidx(sih, origidx);
4901 }
4902 
4903 /* For 43602a0 MCH2/MCH5 boards: power off PA Reference LDO */
4904 void
si_pmu_switch_off_PARLDO(si_t * sih,osl_t * osh)4905 si_pmu_switch_off_PARLDO(si_t *sih, osl_t *osh)
4906 {
4907 	uint32 mask;
4908 	pmuregs_t *pmu;
4909 	uint origidx;
4910 
4911 	/* Remember original core before switch to chipc/pmu */
4912 	origidx = si_coreidx(sih);
4913 	if (AOB_ENAB(sih)) {
4914 		pmu = si_setcore(sih, PMU_CORE_ID, 0);
4915 	} else {
4916 		pmu = si_setcoreidx(sih, SI_CC_IDX);
4917 	}
4918 	ASSERT(pmu != NULL);
4919 
4920 	switch (CHIPID(sih->chip)) {
4921 	case BCM43602_CHIP_ID:
4922 	case BCM43462_CHIP_ID:
4923 		mask = R_REG(osh, &pmu->min_res_mask) & ~PMURES_BIT(RES43602_PARLDO_PU);
4924 		W_REG(osh, &pmu->min_res_mask, mask);
4925 		mask = R_REG(osh, &pmu->max_res_mask) & ~PMURES_BIT(RES43602_PARLDO_PU);
4926 		W_REG(osh, &pmu->max_res_mask, mask);
4927 		break;
4928 	default:
4929 		break;
4930 	}
4931 	/* Return to original core */
4932 	si_setcoreidx(sih, origidx);
4933 }
4934 
4935 /**
4936  * Change VCO frequency (slightly), e.g. to avoid PHY errors due to spurs.
4937  */
4938 static void
BCMATTACHFN(si_set_bb_vcofreq_frac)4939 BCMATTACHFN(si_set_bb_vcofreq_frac)(si_t *sih, osl_t *osh, int vcofreq, int frac, int xtalfreq)
4940 {
4941 	uint32 vcofreq_withfrac, p1div, ndiv_int, fraca, ndiv_mode, reg;
4942 	/* shifts / masks for PMU PLL control register #2 : */
4943 	uint32 ndiv_int_shift, ndiv_mode_shift, p1div_shift, pllctrl2_mask;
4944 	/* shifts / masks for PMU PLL control register #3 : */
4945 	uint32 pllctrl3_mask;
4946 	BCM_REFERENCE(osh);
4947 
4948 	if ((CHIPID(sih->chip) == BCM4360_CHIP_ID) ||
4949 	    (CHIPID(sih->chip) == BCM43460_CHIP_ID) ||
4950 	    (CHIPID(sih->chip) == BCM43526_CHIP_ID) ||
4951 	    (CHIPID(sih->chip) == BCM4352_CHIP_ID) ||
4952 	    BCM43602_CHIP(sih->chip)) {
4953 		if (si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, clk_ctl_st), 0, 0)
4954 			& CCS_HTAVAIL) {
4955 			PMU_MSG(("HTAVAIL is set, so not updating BBPLL Frequency \n"));
4956 			return;
4957 		}
4958 
4959 		ndiv_int_shift = 7;
4960 		ndiv_mode_shift = 4;
4961 		p1div_shift = 0;
4962 		pllctrl2_mask = 0xffffffff;
4963 		pllctrl3_mask = 0xffffffff;
4964 	} else {
4965 		/* put more chips here */
4966 		PMU_ERROR(("si_set_bb_vcofreq_frac: only work on 4360, 4352\n"));
4967 		return;
4968 	}
4969 
4970 	vcofreq_withfrac = vcofreq * 10000 + frac;
4971 	p1div = 0x1;
4972 	ndiv_int = vcofreq / xtalfreq;
4973 	ndiv_mode = (vcofreq_withfrac % (xtalfreq * 10000)) ? 3 : 0;
4974 	PMU_ERROR(("ChangeVCO => vco:%d, xtalF:%d, frac: %d, ndivMode: %d, ndivint: %d\n",
4975 		vcofreq, xtalfreq, frac, ndiv_mode, ndiv_int));
4976 
4977 	reg = (ndiv_int << ndiv_int_shift) |
4978 	      (ndiv_mode << ndiv_mode_shift) |
4979 	      (p1div << p1div_shift);
4980 	PMU_ERROR(("Data written into the PLL_CNTRL_ADDR2: %08x\n", reg));
4981 	si_pmu_pllcontrol(sih, PMU_PLL_CTRL_REG2, pllctrl2_mask, reg);
4982 
4983 	if (ndiv_mode) {
4984 		/* frac = (vcofreq_withfrac % (xtalfreq * 10000)) * 2^24) / (xtalfreq * 10000) */
4985 		uint32 r1, r0;
4986 		math_uint64_multiple_add(
4987 			&r1, &r0, vcofreq_withfrac % (xtalfreq * 10000), 1 << 24, 0);
4988 		math_uint64_divide(&fraca, r1, r0, xtalfreq * 10000);
4989 		PMU_ERROR(("Data written into the PLL_CNTRL_ADDR3 (Fractional): %08x\n", fraca));
4990 		si_pmu_pllcontrol(sih, PMU_PLL_CTRL_REG3, pllctrl3_mask, fraca);
4991 	}
4992 
4993 	si_pmu_pllupd(sih);
4994 } /* si_set_bb_vcofreq_frac */
4995 
4996 /**
4997  * given x-tal frequency, returns BaseBand vcofreq with fraction in 100Hz
4998  * @param   xtalfreq In [Mhz] units.
4999  * @return           In [100Hz] units.
5000  */
5001 uint32
si_pmu_get_bb_vcofreq(si_t * sih,osl_t * osh,int xtalfreq)5002 si_pmu_get_bb_vcofreq(si_t *sih, osl_t *osh, int xtalfreq)
5003 {
5004 	uint32  ndiv_int,	/* 9 bits integer divider */
5005 		ndiv_mode,
5006 		frac = 0,	/* 24 bits fractional divider */
5007 		p1div;		/* predivider: divides x-tal freq */
5008 	uint32 xtal1, vcofrac = 0, vcofreq;
5009 	uint32 r1, r0, reg;
5010 
5011 	BCM_REFERENCE(osh);
5012 
5013 	if ((CHIPID(sih->chip) == BCM4360_CHIP_ID) ||
5014 	    (CHIPID(sih->chip) == BCM43460_CHIP_ID) ||
5015 	    (CHIPID(sih->chip) == BCM43526_CHIP_ID) ||
5016 	    (CHIPID(sih->chip) == BCM4352_CHIP_ID) ||
5017 	    BCM43602_CHIP(sih->chip)) {
5018 		reg = si_pmu_pllcontrol(sih, PMU_PLL_CTRL_REG2, 0, 0);
5019 		ndiv_int = reg >> 7;
5020 		ndiv_mode = (reg >> 4) & 7;
5021 		p1div = 1; /* do not divide x-tal frequency */
5022 
5023 		if (ndiv_mode)
5024 			frac = si_pmu_pllcontrol(sih, PMU_PLL_CTRL_REG3, 0, 0);
5025 	} else if ((BCM4369_CHIP(sih->chip) &&
5026 			CST4369_CHIPMODE_PCIE(sih->chipst)) ||
5027 			BCM4376_CHIP(sih->chip) ||
5028 			BCM4378_CHIP(sih->chip) ||
5029 			(BCM4362_CHIP(sih->chip) &&
5030 			CST4362_CHIPMODE_PCIE(sih->chipst))) {
5031 		reg = si_pmu_pllcontrol(sih, PMU_PLL_CTRL_REG2, 0, 0);
5032 		ndiv_int = reg >> 20;
5033 		p1div = (reg >> 16) & 0xf;
5034 		frac = si_pmu_pllcontrol(sih, PMU_PLL_CTRL_REG3, 0, 0) & 0x00fffff;
5035 		ndiv_mode = 1;
5036 	} else {
5037 		/* put more chips here */
5038 		PMU_ERROR(("si_pmu_get_bb_vcofreq: only work on 4360, 4352, 4369, 4378\n"));
5039 		ASSERT(FALSE);
5040 		return 0;
5041 	}
5042 
5043 	xtal1 = 10000 * xtalfreq / p1div;		/* in [100Hz] units */
5044 
5045 	if (ndiv_mode) {
5046 		/* vcofreq fraction = (xtal1 * frac + (1 << 23)) / (1 << 24);
5047 		 * handle overflow
5048 		 */
5049 		math_uint64_multiple_add(&r1, &r0, xtal1, frac, 1 << 23);
5050 		vcofrac = (r1 << 8) | (r0 >> 24);
5051 	}
5052 
5053 	if (ndiv_int == 0) {
5054 		ASSERT(0);
5055 		return 0;
5056 	}
5057 
5058 	if ((int)xtal1 > (int)((0xffffffff - vcofrac) / ndiv_int)) {
5059 		PMU_ERROR(("si_pmu_get_bb_vcofreq: xtalfreq is too big, %d\n", xtalfreq));
5060 		return 0;
5061 	}
5062 
5063 	vcofreq = xtal1 * ndiv_int + vcofrac;
5064 	return vcofreq;
5065 } /* si_pmu_get_bb_vcofreq */
5066 
5067 /** Enable PMU 1Mhz clock */
5068 static void
si_pmu_enb_slow_clk(si_t * sih,osl_t * osh,uint32 xtalfreq)5069 si_pmu_enb_slow_clk(si_t *sih, osl_t *osh, uint32 xtalfreq)
5070 {
5071 	uint32 val;
5072 	pmuregs_t *pmu;
5073 	uint origidx;
5074 
5075 	if (PMUREV(sih->pmurev) < 24) {
5076 		PMU_ERROR(("si_pmu_enb_slow_clk: Not supported %d\n", PMUREV(sih->pmurev)));
5077 		return;
5078 	}
5079 
5080 	/* Remember original core before switch to chipc/pmu */
5081 	origidx = si_coreidx(sih);
5082 	if (AOB_ENAB(sih)) {
5083 		pmu = si_setcore(sih, PMU_CORE_ID, 0);
5084 	} else {
5085 		pmu = si_setcoreidx(sih, SI_CC_IDX);
5086 	}
5087 	ASSERT(pmu != NULL);
5088 
5089 	/* twiki PmuRev30, OneMhzToggleEn:31, AlpPeriod[23:0] */
5090 	if (PMUREV(sih->pmurev) >= 38) {
5091 		/* Use AlpPeriod[23:0] only chip default value for PmuRev >= 38 chips
5092 		 *  eg. ROUND(POWER(2,26) / (55.970 / 2 MHz) for 4387/4385, etc
5093 		 */
5094 		val = R_REG(osh, &pmu->slowclkperiod) | PMU30_ALPCLK_ONEMHZ_ENAB;
5095 	} else {
5096 		if (PMUREV(sih->pmurev) >= 30) {
5097 			/* AlpPeriod = ROUND(POWER(2,26)/ALP_CLK_FREQ_IN_MHz,0) */
5098 			/* Calculation will be accurate for only one decimal of xtal (like 37.4),
5099 			* and will not be accurate for more than one decimal
5100 			* of xtal freq (like 37.43)
5101 			* Also no rounding is done on final result
5102 			*/
5103 			ROMMABLE_ASSERT((xtalfreq/100)*100 == xtalfreq);
5104 			val = (((1 << 26)*10)/(xtalfreq/100));
5105 			/* set the 32 bit to enable OneMhzToggle
5106 			* -usec wide toggle signal will be generated
5107 			*/
5108 			val |= PMU30_ALPCLK_ONEMHZ_ENAB;
5109 		} else { /* twiki PmuRev24, OneMhzToggleEn:16, AlpPeriod[15:0] */
5110 			if (xtalfreq == 37400) {
5111 				val = 0x101B6;
5112 			} else if (xtalfreq == 40000) {
5113 				val = 0x10199;
5114 			} else {
5115 				PMU_ERROR(("si_pmu_enb_slow_clk: xtalfreq is not supported, %d\n",
5116 					xtalfreq));
5117 				/* Return to original core */
5118 				si_setcoreidx(sih, origidx);
5119 				return;
5120 			}
5121 		}
5122 	}
5123 
5124 	W_REG(osh, &pmu->slowclkperiod, val);
5125 
5126 	/* Return to original core */
5127 	si_setcoreidx(sih, origidx);
5128 }
5129 
5130 /**
5131  * Initializes PLL given an x-tal frequency.
5132  * Calls si_pmuX_pllinitY() type of functions, where the reasoning behind 'X' and 'Y' is historical
5133  * rather than logical.
5134  *
5135  * xtalfreq : x-tal frequency in [KHz]
5136  */
5137 void
BCMATTACHFN(si_pmu_pll_init)5138 BCMATTACHFN(si_pmu_pll_init)(si_t *sih, osl_t *osh, uint xtalfreq)
5139 {
5140 	pmuregs_t *pmu;
5141 	uint origidx;
5142 #ifdef BCMDBG_PMU
5143 	char chn[8];
5144 #endif
5145 	BCM_REFERENCE(pmu1_xtaltab0_880);
5146 	BCM_REFERENCE(pmu1_xtaltab0_1760);
5147 
5148 	ASSERT(sih->cccaps & CC_CAP_PMU);
5149 
5150 	/* Remember original core before switch to chipc/pmu */
5151 	origidx = si_coreidx(sih);
5152 	if (AOB_ENAB(sih)) {
5153 		pmu = si_setcore(sih, PMU_CORE_ID, 0);
5154 	} else {
5155 		pmu = si_setcoreidx(sih, SI_CC_IDX);
5156 	}
5157 	ASSERT(pmu != NULL);
5158 
5159 	switch (CHIPID(sih->chip)) {
5160 	case BCM4360_CHIP_ID:
5161 	case BCM43460_CHIP_ID:
5162 	case BCM4352_CHIP_ID: {
5163 		if (CHIPREV(sih->chiprev) > 2)
5164 			si_set_bb_vcofreq_frac(sih, osh, 960, 98, 40);
5165 		break;
5166 	}
5167 	CASE_BCM43602_CHIP:
5168 		si_set_bb_vcofreq_frac(sih, osh, 960, 98, 40);
5169 		break;
5170 	case BCM43012_CHIP_ID:
5171 	case BCM43013_CHIP_ID:
5172 	case BCM43014_CHIP_ID:
5173 	case BCM4369_CHIP_GRPID:
5174 	case BCM4362_CHIP_GRPID:
5175 	case BCM4376_CHIP_GRPID:
5176 	case BCM4378_CHIP_GRPID:
5177 	case BCM4385_CHIP_GRPID:
5178 	case BCM4387_CHIP_GRPID:
5179 	case BCM4388_CHIP_GRPID:
5180 	case BCM4389_CHIP_GRPID:
5181 		si_pmu1_pllinit1(sih, osh, pmu, xtalfreq); /* nvram PLL overrides + enables PLL */
5182 		break;
5183 	default:
5184 		PMU_MSG(("No PLL init done for chip %s rev %d pmurev %d\n",
5185 		         bcm_chipname(
5186 			 CHIPID(sih->chip), chn, 8), CHIPREV(sih->chiprev), PMUREV(sih->pmurev)));
5187 		break;
5188 	}
5189 
5190 #ifdef BCMDBG_FORCEHT
5191 	si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, clk_ctl_st), CCS_FORCEHT, CCS_FORCEHT)
5192 #endif
5193 
5194 	si_pmu_enb_slow_clk(sih, osh, xtalfreq);
5195 
5196 	/* Return to original core */
5197 	si_setcoreidx(sih, origidx);
5198 } /* si_pmu_pll_init */
5199 
5200 /** get alp clock frequency in [Hz] units */
5201 uint32
BCMPOSTTRAPFN(si_pmu_alp_clock)5202 BCMPOSTTRAPFN(si_pmu_alp_clock)(si_t *sih, osl_t *osh)
5203 {
5204 	pmuregs_t *pmu;
5205 	uint origidx;
5206 	uint32 clock = ALP_CLOCK;
5207 #ifdef BCMDBG_PMU
5208 	char chn[8];
5209 #endif
5210 
5211 	ASSERT(sih->cccaps & CC_CAP_PMU);
5212 
5213 	/* Remember original core before switch to chipc/pmu */
5214 	origidx = si_coreidx(sih);
5215 	if (AOB_ENAB(sih)) {
5216 		pmu = si_setcore(sih, PMU_CORE_ID, 0);
5217 	} else {
5218 		pmu = si_setcoreidx(sih, SI_CC_IDX);
5219 	}
5220 	ASSERT(pmu != NULL);
5221 
5222 	switch (CHIPID(sih->chip)) {
5223 	case BCM4360_CHIP_ID:
5224 	case BCM43460_CHIP_ID:
5225 	case BCM4352_CHIP_ID:
5226 	case BCM43526_CHIP_ID:
5227 		if (sih->chipst & CST4360_XTAL_40MZ)
5228 			clock = 40000 * 1000;
5229 		else
5230 			clock = 20000 * 1000;
5231 		break;
5232 
5233 	CASE_BCM43602_CHIP:
5234 		/* always 40Mhz */
5235 		clock = 40000 * 1000;
5236 		break;
5237 	case BCM43012_CHIP_ID:
5238 	case BCM43013_CHIP_ID:
5239 	case BCM43014_CHIP_ID:
5240 #ifndef BCMSDIOLITE
5241 	case BCM4369_CHIP_GRPID:
5242 #endif /* BCMSDIOLITE */
5243 	case BCM4362_CHIP_GRPID:
5244 	case BCM4376_CHIP_GRPID:
5245 	case BCM4378_CHIP_GRPID:
5246 	case BCM4385_CHIP_GRPID:
5247 	case BCM4387_CHIP_GRPID:
5248 	case BCM4388_CHIP_GRPID:
5249 	case BCM4389_CHIP_GRPID:
5250 	case BCM4397_CHIP_GRPID:
5251 		clock = si_pmu1_alpclk0(sih, osh, pmu);
5252 		break;
5253 #ifdef BCMSDIOLITE
5254 	case BCM4369_CHIP_ID:
5255 		/* always 25Mhz */
5256 		clock = 25000 * 1000;
5257 		break;
5258 #endif /* BCMSDIOLITE */
5259 	default:
5260 		PMU_MSG(("No ALP clock specified "
5261 			"for chip %s rev %d pmurev %d, using default %d Hz\n",
5262 			bcm_chipname(
5263 			CHIPID(sih->chip), chn, 8), CHIPREV(sih->chiprev),
5264 			PMUREV(sih->pmurev), clock));
5265 		break;
5266 	}
5267 
5268 	/* Return to original core */
5269 	si_setcoreidx(sih, origidx);
5270 
5271 	return clock; /* in [Hz] units */
5272 } /* si_pmu_alp_clock */
5273 
5274 /**
5275  * Find the output of the "m" pll divider given pll controls that start with
5276  * pllreg "pll0" i.e. 12 for main 6 for phy, 0 for misc.
5277  */
5278 static uint32
BCMPOSTTRAPFN(si_pmu5_clock)5279 BCMPOSTTRAPFN(si_pmu5_clock)(si_t *sih, osl_t *osh, pmuregs_t *pmu, uint pll0, uint m)
5280 {
5281 	uint32 tmp, div, ndiv, p1, p2, fc;
5282 
5283 	if ((pll0 & 3) || (pll0 > PMU4716_MAINPLL_PLL0)) {
5284 		PMU_ERROR(("si_pmu5_clock: Bad pll0: %d\n", pll0));
5285 		return 0;
5286 	}
5287 
5288 	/* Strictly there is an m5 divider, but I'm not sure we use it */
5289 	if ((m == 0) || (m > 4)) {
5290 		PMU_ERROR(("si_pmu5_clock: Bad m divider: %d\n", m));
5291 		return 0;
5292 	}
5293 
5294 	W_REG(osh, &pmu->pllcontrol_addr, pll0 + PMU5_PLL_P1P2_OFF);
5295 	(void)R_REG(osh, &pmu->pllcontrol_addr);
5296 	tmp = R_REG(osh, &pmu->pllcontrol_data);
5297 	p1 = (tmp & PMU5_PLL_P1_MASK) >> PMU5_PLL_P1_SHIFT;
5298 	p2 = (tmp & PMU5_PLL_P2_MASK) >> PMU5_PLL_P2_SHIFT;
5299 
5300 	W_REG(osh, &pmu->pllcontrol_addr, pll0 + PMU5_PLL_M14_OFF);
5301 	(void)R_REG(osh, &pmu->pllcontrol_addr);
5302 	tmp = R_REG(osh, &pmu->pllcontrol_data);
5303 	div = (tmp >> ((m - 1) * PMU5_PLL_MDIV_WIDTH)) & PMU5_PLL_MDIV_MASK;
5304 
5305 	W_REG(osh, &pmu->pllcontrol_addr, pll0 + PMU5_PLL_NM5_OFF);
5306 	(void)R_REG(osh, &pmu->pllcontrol_addr);
5307 	tmp = R_REG(osh, &pmu->pllcontrol_data);
5308 	ndiv = (tmp & PMU5_PLL_NDIV_MASK) >> PMU5_PLL_NDIV_SHIFT;
5309 
5310 	/* Do calculation in Mhz */
5311 	fc = si_pmu_alp_clock(sih, osh) / 1000000;
5312 	fc = (p1 * ndiv * fc) / p2;
5313 
5314 	PMU_NONE(("si_pmu5_clock: p1=%d, p2=%d, ndiv=%d(0x%x), m%d=%d; fc=%d, clock=%d\n",
5315 	          p1, p2, ndiv, ndiv, m, div, fc, fc / div));
5316 
5317 	/* Return clock in Hertz */
5318 	return ((fc / div) * 1000000);
5319 } /* si_pmu5_clock */
5320 
5321 /**
5322  * Get backplane clock frequency, returns a value in [hz] units.
5323  * For designs that feed the same clock to both backplane and CPU just return the CPU clock speed.
5324  */
5325 uint32
BCMPOSTTRAPFN(si_pmu_si_clock)5326 BCMPOSTTRAPFN(si_pmu_si_clock)(si_t *sih, osl_t *osh)
5327 {
5328 	pmuregs_t *pmu;
5329 	uint origidx;
5330 	uint32 clock = HT_CLOCK;	/* in [hz] units */
5331 #ifdef BCMDBG_PMU
5332 	char chn[8];
5333 #endif
5334 
5335 	ASSERT(sih->cccaps & CC_CAP_PMU);
5336 
5337 	/* Remember original core before switch to chipc/pmu */
5338 	origidx = si_coreidx(sih);
5339 	if (AOB_ENAB(sih)) {
5340 		pmu = si_setcore(sih, PMU_CORE_ID, 0);
5341 	} else {
5342 		pmu = si_setcoreidx(sih, SI_CC_IDX);
5343 	}
5344 	ASSERT(pmu != NULL);
5345 
5346 	switch (CHIPID(sih->chip)) {
5347 	case BCM4360_CHIP_ID:
5348 	case BCM43460_CHIP_ID:
5349 	case BCM43526_CHIP_ID:
5350 	case BCM4352_CHIP_ID:
5351 	case BCM43012_CHIP_ID:
5352 	case BCM43013_CHIP_ID:
5353 	case BCM43014_CHIP_ID:
5354 		clock = si_pmu1_cpuclk0(sih, osh, pmu);
5355 		break;
5356 
5357 	CASE_BCM43602_CHIP: {
5358 			uint32 mdiv;
5359 			/* Ch3 is connected to backplane_clk. Read 'bbpll_i_m3div' from pllctl[4] */
5360 			mdiv = si_pmu_pllcontrol(sih, PMU_PLL_CTRL_REG4, 0, 0);
5361 			mdiv = (mdiv & PMU1_PLL0_PC1_M3DIV_MASK) >> PMU1_PLL0_PC1_M3DIV_SHIFT;
5362 			ASSERT(mdiv != 0);
5363 			clock = si_pmu1_pllfvco0(sih) / mdiv * 1000;
5364 			break;
5365 		}
5366 
5367 	case BCM4369_CHIP_GRPID:
5368 	case BCM4362_CHIP_GRPID:
5369 	case BCM4376_CHIP_GRPID:
5370 	case BCM4378_CHIP_GRPID:
5371 		clock = si_pmu1_cpuclk0(sih, osh, pmu);
5372 		break;
5373 
5374 	case BCM4385_CHIP_GRPID:
5375 	case BCM4387_CHIP_GRPID:
5376 	case BCM4388_CHIP_GRPID:
5377 	case BCM4389_CHIP_GRPID:
5378 	case BCM4397_CHIP_GRPID:
5379 		clock = si_pmu_bpclk_4387(sih);
5380 		break;
5381 
5382 	default:
5383 		PMU_MSG(("No backplane clock specified "
5384 			"for chip %s rev %d pmurev %d, using default %d Hz\n",
5385 			bcm_chipname(
5386 			CHIPID(sih->chip), chn, 8), CHIPREV(sih->chiprev),
5387 			PMUREV(sih->pmurev), clock));
5388 		break;
5389 	}
5390 
5391 	/* Return to original core */
5392 	si_setcoreidx(sih, origidx);
5393 
5394 	return clock;
5395 } /* si_pmu_si_clock */
5396 
5397 /** returns CPU clock frequency in [hz] units */
5398 uint32
BCMPOSTTRAPFN(si_pmu_cpu_clock)5399 BCMPOSTTRAPFN(si_pmu_cpu_clock)(si_t *sih, osl_t *osh)
5400 {
5401 	pmuregs_t *pmu;
5402 	uint origidx;
5403 	uint32 clock;	/* in [hz] units */
5404 
5405 	uint32 tmp;
5406 	uint32 armclk_offcnt, armclk_oncnt;
5407 
5408 	ASSERT(sih->cccaps & CC_CAP_PMU);
5409 
5410 	/* Remember original core before switch to chipc/pmu */
5411 	origidx = si_coreidx(sih);
5412 	if (AOB_ENAB(sih)) {
5413 		pmu = si_setcore(sih, PMU_CORE_ID, 0);
5414 	} else {
5415 		pmu = si_setcoreidx(sih, SI_CC_IDX);
5416 	}
5417 	ASSERT(pmu != NULL);
5418 
5419 	if (BCM4369_CHIP(sih->chip) ||
5420 		BCM4376_CHIP(sih->chip) ||
5421 		BCM4378_CHIP(sih->chip) ||
5422 		BCM4385_CHIP(sih->chip) ||
5423 		BCM4387_CHIP(sih->chip) ||
5424 		BCM4388_CHIP(sih->chip) ||
5425 		BCM4389_CHIP(sih->chip) ||
5426 		BCM4397_CHIP(sih->chip) ||
5427 		BCM4362_CHIP(sih->chip)) {
5428 		clock = si_pmu1_cpuclk0_pll2(sih); /* for chips with separate CPU PLL */
5429 	} else if ((PMUREV(sih->pmurev) >= 5) &&
5430 		!((CHIPID(sih->chip) == BCM4360_CHIP_ID) ||
5431 		(CHIPID(sih->chip) == BCM4352_CHIP_ID) ||
5432 		(CHIPID(sih->chip) == BCM43526_CHIP_ID) ||
5433 		(CHIPID(sih->chip) == BCM43460_CHIP_ID) ||
5434 		(CHIPID(sih->chip) == BCM43012_CHIP_ID) ||
5435 		(CHIPID(sih->chip) == BCM43013_CHIP_ID) ||
5436 		(CHIPID(sih->chip) == BCM43014_CHIP_ID) ||
5437 		0)) {
5438 		uint pll = PMU4716_MAINPLL_PLL0;
5439 
5440 		if (BCM43602_CHIP(sih->chip)) {
5441 			clock = si_pmu1_cpuclk0(sih, osh, pmu);
5442 		} else {
5443 			clock = si_pmu5_clock(sih, osh, pmu, pll, PMU5_MAINPLL_CPU);
5444 		}
5445 	} else {
5446 		clock = si_pmu_si_clock(sih, osh);
5447 	}
5448 
5449 	if ((CHIPID(sih->chip) == BCM43012_CHIP_ID) ||
5450 		(CHIPID(sih->chip) == BCM43013_CHIP_ID) ||
5451 		(CHIPID(sih->chip) == BCM43014_CHIP_ID)) {
5452 		/* Fout = (on_count + 1) * Fin/(on_count + 1 + off_count)
5453 		* ARM clock using Fast divider calculation
5454 		* Fin = FVCO/2
5455 		*/
5456 		tmp = si_pmu_chipcontrol(sih, PMU1_PLL0_CHIPCTL1, 0, 0);
5457 		armclk_offcnt =
5458 			(tmp & CCTL_43012_ARM_OFFCOUNT_MASK) >> CCTL_43012_ARM_OFFCOUNT_SHIFT;
5459 		armclk_oncnt =
5460 			(tmp & CCTL_43012_ARM_ONCOUNT_MASK) >> CCTL_43012_ARM_ONCOUNT_SHIFT;
5461 		clock = (armclk_oncnt + 1) * clock/(armclk_oncnt + 1 + armclk_offcnt);
5462 	}
5463 
5464 	/* Return to original core */
5465 	si_setcoreidx(sih, origidx);
5466 	return clock;
5467 } /* si_pmu_cpu_clock */
5468 
5469 #ifdef __ARM_ARCH_7A__
5470 static uint32
si_pmu_mem_ca7clock(si_t * sih,osl_t * osh)5471 si_pmu_mem_ca7clock(si_t *sih, osl_t *osh)
5472 {
5473 	uint32 clock = 0;
5474 	int8 mdiv = 1;
5475 	uint idx = si_coreidx(sih);
5476 	bool fastclk;
5477 	ca7regs_t *regs = si_setcore(sih, ARMCA7_CORE_ID, 0);
5478 
5479 	if (regs == NULL) {
5480 		goto end;
5481 	}
5482 
5483 	fastclk = ((R_REG(osh, ARMREG(regs, clk_ctl_st)) & CCS_ARMFASTCLOCKREQ) != 0);
5484 
5485 	if (fastclk) {
5486 		uint32 fvco = si_pmu_pll28nm_fvco(sih);
5487 		if (si_corerev(sih) >= 7) {
5488 			mdiv = (R_REG(osh, ARMREG(regs, corecontrol)) & ACC_CLOCKRATIO_MASK) >>
5489 				ACC_CLOCKRATIO_SHIFT;
5490 		} else {
5491 			ASSERT(0);
5492 		}
5493 
5494 		if (mdiv == 0) {
5495 			ASSERT(0);
5496 			clock = 0;
5497 		} else {
5498 			clock = (fvco / mdiv);
5499 		}
5500 	} else {
5501 		clock = si_pmu_si_clock(sih, osh);
5502 	}
5503 
5504 end:
5505 	si_setcoreidx(sih, idx);
5506 	return clock;
5507 
5508 }
5509 #endif /* __ARM_ARCH_7A__ */
5510 
5511 /** get memory clock frequency, which is the same as the HT clock for newer chips. Returns [Hz]. */
5512 uint32
BCMINITFN(si_pmu_mem_clock)5513 BCMINITFN(si_pmu_mem_clock)(si_t *sih, osl_t *osh)
5514 {
5515 	pmuregs_t *pmu;
5516 	uint origidx;
5517 	uint32 clock;
5518 
5519 	ASSERT(sih->cccaps & CC_CAP_PMU);
5520 
5521 	/* Remember original core before switch to chipc/pmu */
5522 	origidx = si_coreidx(sih);
5523 	if (AOB_ENAB(sih)) {
5524 		pmu = si_setcore(sih, PMU_CORE_ID, 0);
5525 	} else {
5526 		pmu = si_setcoreidx(sih, SI_CC_IDX);
5527 	}
5528 	ASSERT(pmu != NULL);
5529 
5530 	if ((PMUREV(sih->pmurev) >= 5) &&
5531 		!((BCM4369_CHIP(sih->chip)) ||
5532 		(BCM4362_CHIP(sih->chip)) ||
5533 		BCM43602_CHIP(sih->chip) ||
5534 		(CHIPID(sih->chip) == BCM43012_CHIP_ID) ||
5535 		(CHIPID(sih->chip) == BCM43013_CHIP_ID) ||
5536 		(CHIPID(sih->chip) == BCM43014_CHIP_ID) ||
5537 		BCM4376_CHIP(sih->chip) ||
5538 		BCM4378_CHIP(sih->chip) ||
5539 		BCM4387_CHIP(sih->chip) ||
5540 		BCM4388_CHIP(sih->chip) ||
5541 		BCM4389_CHIP(sih->chip) ||
5542 		BCM4397_CHIP(sih->chip) ||
5543 		0)) {
5544 		uint pll = PMU4716_MAINPLL_PLL0;
5545 
5546 		clock = si_pmu5_clock(sih, osh, pmu, pll, PMU5_MAINPLL_MEM);
5547 	} else {
5548 #ifdef __ARM_ARCH_7A__
5549 		clock = si_pmu_mem_ca7clock(sih, osh);
5550 #else /* !__ARM_ARCH_7A__ */
5551 		clock = si_pmu_si_clock(sih, osh); /* mem clk same as backplane clk */
5552 #endif /* __ARM_ARCH_7A__ */
5553 	}
5554 	/* Return to original core */
5555 	si_setcoreidx(sih, origidx);
5556 	return clock;
5557 } /* si_pmu_mem_clock */
5558 
5559 /*
5560  * ilpcycles per sec are now calculated during CPU init in a new way
5561  * for better accuracy.  We set it here for compatability.
5562  *
5563  * On platforms that do not do this we resort to the old way.
5564  */
5565 
5566 #define ILP_CALC_DUR	10	/* ms, make sure 1000 can be divided by it. */
5567 
5568 static uint32 ilpcycles_per_sec = 0;
5569 
5570 void
BCMPOSTTRAPFN(si_pmu_ilp_clock_set)5571 BCMPOSTTRAPFN(si_pmu_ilp_clock_set)(uint32 cycles_per_sec)
5572 {
5573 	ilpcycles_per_sec = cycles_per_sec;
5574 }
5575 
5576 /**
5577  * Measure ILP clock frequency. Returns a value in [Hz] units.
5578  *
5579  * The variable ilpcycles_per_sec is used to store the ILP clock speed. The value
5580  * is calculated when the function is called the first time and then cached.
5581  * The change in PMU timer count is measured across a delay of ILP_CALC_DUR msec.
5582  * Before the first time the function is called, one must make sure the HT clock is
5583  * turned on and used to feed the CPU and that OSL_DELAY() is calibrated.
5584  */
5585 uint32
BCMINITFN(si_pmu_ilp_clock)5586 BCMINITFN(si_pmu_ilp_clock)(si_t *sih, osl_t *osh)
5587 {
5588 	if (ISSIM_ENAB(sih))
5589 		return ILP_CLOCK;
5590 
5591 	if (ilpcycles_per_sec == 0) {
5592 		uint32 start, end, delta;
5593 		pmuregs_t *pmu;
5594 		uint origidx = si_coreidx(sih);
5595 
5596 		if (AOB_ENAB(sih)) {
5597 			pmu = si_setcore(sih, PMU_CORE_ID, 0);
5598 		} else {
5599 			pmu = si_setcoreidx(sih, SI_CC_IDX);
5600 		}
5601 		ASSERT(pmu != NULL);
5602 		start = R_REG(osh, &pmu->pmutimer);
5603 		/* PR88659: verify pmutimer reads */
5604 		if (start != R_REG(osh, &pmu->pmutimer))
5605 			start = R_REG(osh, &pmu->pmutimer);
5606 		OSL_DELAY(ILP_CALC_DUR * 1000);
5607 		end = R_REG(osh, &pmu->pmutimer);
5608 		if (end != R_REG(osh, &pmu->pmutimer))
5609 			end = R_REG(osh, &pmu->pmutimer);
5610 		delta = end - start;
5611 		ilpcycles_per_sec = delta * (1000 / ILP_CALC_DUR);
5612 		/* Return to original core */
5613 		si_setcoreidx(sih, origidx);
5614 	}
5615 
5616 	ASSERT(ilpcycles_per_sec != 0);
5617 	return ilpcycles_per_sec;
5618 }
5619 #endif /* !defined(BCMDONGLEHOST) */
5620 
5621 /**
5622  * Reads/writes a chipcontrol reg. Performes core switching if required, at function exit the
5623  * original core is restored. Depending on chip type, read/writes to chipcontrol regs in CC core
5624  * (older chips) or to chipcontrol regs in PMU core (later chips).
5625  */
5626 uint32
BCMPOSTTRAPFN(si_pmu_chipcontrol)5627 BCMPOSTTRAPFN(si_pmu_chipcontrol)(si_t *sih, uint reg, uint32 mask, uint32 val)
5628 {
5629 	pmu_corereg(sih, SI_CC_IDX, chipcontrol_addr, ~0, reg);
5630 	return pmu_corereg(sih, SI_CC_IDX, chipcontrol_data, mask, val);
5631 }
5632 
5633 /**
5634  * Reads/writes a voltage regulator (vreg) register. Performes core switching if required, at
5635  * function exit the original core is restored. Depending on chip type, writes to regulator regs
5636  * in CC core (older chips) or to regulator regs in PMU core (later chips).
5637  */
5638 uint32
BCMPOSTTRAPFN(si_pmu_vreg_control)5639 BCMPOSTTRAPFN(si_pmu_vreg_control)(si_t *sih, uint reg, uint32 mask, uint32 val)
5640 {
5641 	pmu_corereg(sih, SI_CC_IDX, regcontrol_addr, ~0, reg);
5642 	return pmu_corereg(sih, SI_CC_IDX, regcontrol_data, mask, val);
5643 }
5644 
5645 /**
5646  * Reads/writes a PLL control register. Performes core switching if required, at function exit the
5647  * original core is restored. Depending on chip type, writes to PLL control regs in CC core (older
5648  * chips) or to PLL control regs in PMU core (later chips).
5649  */
5650 uint32
BCMPOSTTRAPFN(si_pmu_pllcontrol)5651 BCMPOSTTRAPFN(si_pmu_pllcontrol)(si_t *sih, uint reg, uint32 mask, uint32 val)
5652 {
5653 	pmu_corereg(sih, SI_CC_IDX, pllcontrol_addr, ~0, reg);
5654 	return pmu_corereg(sih, SI_CC_IDX, pllcontrol_data, mask, val);
5655 }
5656 
5657 /**
5658  * Balance between stable SDIO operation and power consumption is achieved using this function.
5659  * Note that each drive strength table is for a specific VDDIO of the SDIO pads, ideally this
5660  * function should read the VDDIO itself to select the correct table. For now it has been solved
5661  * with the 'BCM_SDIO_VDDIO' preprocessor constant.
5662  *
5663  * 'drivestrength': desired pad drive strength in mA. Drive strength of 0 requests tri-state (if
5664  *		    hardware supports this), if no hw support drive strength is not programmed.
5665  */
5666 void
BCMINITFN(si_sdiod_drive_strength_init)5667 BCMINITFN(si_sdiod_drive_strength_init)(si_t *sih, osl_t *osh, uint32 drivestrength)
5668 {
5669 	/*
5670 	 * Note:
5671 	 * This function used to set the SDIO drive strength via PMU_CHIPCTL1 for the
5672 	 * 43143, 4330, 4334, 4336, 43362 chips.  These chips are now no longer supported, so
5673 	 * the code has been deleted.
5674 	 * Newer chips have the SDIO drive strength setting via a GCI Chip Control register,
5675 	 * but the bit definitions are chip-specific.  We are keeping this function available
5676 	 * (accessed via DHD 'sdiod_drive' IOVar) in case these newer chips need to provide access.
5677 	 */
5678 	UNUSED_PARAMETER(sih);
5679 	UNUSED_PARAMETER(osh);
5680 	UNUSED_PARAMETER(drivestrength);
5681 }
5682 
5683 #if !defined(BCMDONGLEHOST)
5684 /** initialize PMU */
5685 void
BCMATTACHFN(si_pmu_init)5686 BCMATTACHFN(si_pmu_init)(si_t *sih, osl_t *osh)
5687 {
5688 	pmuregs_t *pmu;
5689 	uint origidx;
5690 
5691 	ASSERT(sih->cccaps & CC_CAP_PMU);
5692 
5693 	/* Remember original core before switch to chipc/pmu */
5694 	origidx = si_coreidx(sih);
5695 	if (AOB_ENAB(sih)) {
5696 		pmu = si_setcore(sih, PMU_CORE_ID, 0);
5697 	} else {
5698 		pmu = si_setcoreidx(sih, SI_CC_IDX);
5699 	}
5700 	ASSERT(pmu != NULL);
5701 
5702 #if defined(BT_WLAN_REG_ON_WAR)
5703 	si_pmu_reg_on_war_ext_wake_perst_clear(sih);
5704 	si_pmu_reg_on_war_ext_wake_perst_set(sih);
5705 #endif /* BT_WLAN_REG_ON_WAR */
5706 
5707 	/* Feature is added in PMU rev. 1 but doesn't work until rev. 2 */
5708 	if (PMUREV(sih->pmurev) == 1)
5709 		AND_REG(osh, &pmu->pmucontrol, ~PCTL_NOILP_ON_WAIT);
5710 	else if (PMUREV(sih->pmurev) >= 2)
5711 		OR_REG(osh, &pmu->pmucontrol, PCTL_NOILP_ON_WAIT);
5712 
5713 	/* Changes from PMU revision 26 are not included in revision 27 */
5714 	if ((PMUREV(sih->pmurev) >= 26) && (PMUREV(sih->pmurev) != 27)) {
5715 		uint32 val = PMU_INTC_ALP_REQ | PMU_INTC_HT_REQ | PMU_INTC_HQ_REQ;
5716 		pmu_corereg(sih, SI_CC_IDX, pmuintctrl0, val, val);
5717 
5718 		val = RSRC_INTR_MASK_TIMER_INT_0;
5719 		pmu_corereg(sih, SI_CC_IDX, pmuintmask0, val, val);
5720 		(void)pmu_corereg(sih, SI_CC_IDX, pmuintmask0, 0, 0);
5721 	}
5722 
5723 	/* Return to original core */
5724 	si_setcoreidx(sih, origidx);
5725 }
5726 
5727 uint32
si_pmu_rsrc_macphy_clk_deps(si_t * sih,osl_t * osh,int macunit)5728 si_pmu_rsrc_macphy_clk_deps(si_t *sih, osl_t *osh, int macunit)
5729 {
5730 	uint32 deps = 0;
5731 	rsc_per_chip_t *rsc;
5732 	uint origidx;
5733 	pmuregs_t *pmu = NULL;
5734 	uint8 rsc_num;
5735 
5736 	/* Remember original core before switch to chipc/pmu */
5737 	origidx = si_coreidx(sih);
5738 	if (AOB_ENAB(sih)) {
5739 		pmu = si_setcore(sih, PMU_CORE_ID, 0);
5740 	} else {
5741 		pmu = si_setcoreidx(sih, SI_CC_IDX);
5742 	}
5743 
5744 	ASSERT(pmu != NULL);
5745 
5746 	rsc = si_pmu_get_rsc_positions(sih);
5747 	if (macunit == 0) {
5748 		rsc_num = rsc->macphy_clkavail;
5749 	} else if (macunit == 1) {
5750 		rsc_num = rsc->macphy_aux_clkavail;
5751 	} else if (macunit == 2) {
5752 		rsc_num = rsc->macphy_scan_clkavail;
5753 	} else {
5754 		PMU_ERROR(("si_pmu_rsrc_macphy_clk_deps: slice %d is not supported\n", macunit));
5755 		rsc_num = NO_SUCH_RESOURCE;	/* to satisfy the compiler */
5756 		ASSERT(0);
5757 	}
5758 	deps = si_pmu_res_deps(sih, osh, pmu, PMURES_BIT(rsc_num), TRUE);
5759 	deps |= PMURES_BIT(rsc_num);
5760 
5761 	/* Return to original core */
5762 	si_setcoreidx(sih, origidx);
5763 
5764 	return deps;
5765 }
5766 
5767 void
si_pmu_set_mac_rsrc_req_sc(si_t * sih,osl_t * osh)5768 si_pmu_set_mac_rsrc_req_sc(si_t *sih, osl_t *osh)
5769 {
5770 	uint32 deps = 0;
5771 	rsc_per_chip_t *rsc;
5772 	uint origidx;
5773 	pmuregs_t *pmu = NULL;
5774 	uint32 rsrc = 0;
5775 
5776 	/* Remember original core before switch to chipc/pmu */
5777 	origidx = si_coreidx(sih);
5778 	pmu = si_setcore(sih, PMU_CORE_ID, 0);
5779 	ASSERT(pmu != NULL);
5780 
5781 	rsc = si_pmu_get_rsc_positions(sih);
5782 
5783 	rsrc = (PMURES_BIT(rsc->macphy_scan_clkavail) |
5784 		PMURES_BIT(rsc->dig_ready));
5785 
5786 	deps = si_pmu_res_deps(sih, osh, pmu, rsrc, TRUE);
5787 	deps |= rsrc;
5788 
5789 	W_REG(osh, &pmu->mac_res_req_timer2, PMU32_MAC_SCAN_RSRC_REQ_TIMER);
5790 	W_REG(osh, &pmu->mac_res_req_mask2, deps);
5791 
5792 	/* Return to original core */
5793 	si_setcoreidx(sih, origidx);
5794 }
5795 
5796 uint32
BCMATTACHFN(si_pmu_rsrc_ht_avail_clk_deps)5797 BCMATTACHFN(si_pmu_rsrc_ht_avail_clk_deps)(si_t *sih, osl_t *osh)
5798 {
5799 	uint32 deps;
5800 	rsc_per_chip_t *rsc;
5801 	uint origidx;
5802 	pmuregs_t *pmu = NULL;
5803 
5804 	/* Remember original core before switch to chipc/pmu */
5805 	origidx = si_coreidx(sih);
5806 	if (AOB_ENAB(sih)) {
5807 		pmu = si_setcore(sih, PMU_CORE_ID, 0);
5808 	} else {
5809 		pmu = si_setcoreidx(sih, SI_CC_IDX);
5810 	}
5811 
5812 	ASSERT(pmu != NULL);
5813 
5814 	rsc = si_pmu_get_rsc_positions(sih);
5815 	deps = si_pmu_res_deps(sih, osh, pmu, PMURES_BIT(rsc->ht_avail), FALSE);
5816 	deps |= PMURES_BIT(rsc->ht_avail);
5817 
5818 	/* Return to original core */
5819 	si_setcoreidx(sih, origidx);
5820 
5821 	return deps;
5822 }
5823 
5824 uint32
BCMATTACHFN(si_pmu_rsrc_cb_ready_deps)5825 BCMATTACHFN(si_pmu_rsrc_cb_ready_deps)(si_t *sih, osl_t *osh)
5826 {
5827 	uint32 deps;
5828 	rsc_per_chip_t *rsc;
5829 	uint origidx;
5830 	pmuregs_t *pmu = NULL;
5831 
5832 	/* Remember original core before switch to chipc/pmu */
5833 	origidx = si_coreidx(sih);
5834 	if (AOB_ENAB(sih)) {
5835 		pmu = si_setcore(sih, PMU_CORE_ID, 0);
5836 	} else {
5837 		pmu = si_setcoreidx(sih, SI_CC_IDX);
5838 	}
5839 
5840 	ASSERT(pmu != NULL);
5841 
5842 	rsc = si_pmu_get_rsc_positions(sih);
5843 	if (rsc->cb_ready == NO_SUCH_RESOURCE) {
5844 		deps = 0;
5845 	} else {
5846 		deps = si_pmu_res_deps(sih, osh, pmu, PMURES_BIT(rsc->cb_ready), FALSE);
5847 		deps |= PMURES_BIT(rsc->cb_ready);
5848 	}
5849 
5850 	/* Return to original core */
5851 	si_setcoreidx(sih, origidx);
5852 
5853 	return deps;
5854 }
5855 
5856 void
si_pmu_set_mac_rsrc_req(si_t * sih,int macunit)5857 si_pmu_set_mac_rsrc_req(si_t *sih, int macunit)
5858 {
5859 	pmuregs_t *pmu;
5860 	uint origidx;
5861 	osl_t *osh = si_osh(sih);
5862 
5863 	/* Remember original core before switch to chipc/pmu */
5864 	origidx = si_coreidx(sih);
5865 	if (AOB_ENAB(sih)) {
5866 		pmu = si_setcore(sih, PMU_CORE_ID, 0);
5867 	} else {
5868 		pmu = si_setcoreidx(sih, SI_CC_IDX);
5869 	}
5870 	ASSERT(pmu != NULL);
5871 
5872 	if (macunit == 0) {
5873 		W_REG(osh, &pmu->mac_res_req_timer, PMU32_MAC_MAIN_RSRC_REQ_TIMER);
5874 		W_REG(osh, &pmu->mac_res_req_mask, si_pmu_rsrc_macphy_clk_deps(sih, osh, macunit));
5875 	} else if (macunit == 1) {
5876 		W_REG(osh, &pmu->mac_res_req_timer1, PMU32_MAC_AUX_RSRC_REQ_TIMER);
5877 		W_REG(osh, &pmu->mac_res_req_mask1, si_pmu_rsrc_macphy_clk_deps(sih, osh, macunit));
5878 	} else if (macunit == 2) {
5879 		W_REG(osh, &pmu->mac_res_req_timer2, PMU32_MAC_SCAN_RSRC_REQ_TIMER);
5880 		W_REG(osh, &pmu->mac_res_req_mask2, si_pmu_rsrc_macphy_clk_deps(sih, osh, macunit));
5881 	}
5882 
5883 	/* Return to original core */
5884 	si_setcoreidx(sih, origidx);
5885 }
5886 
5887 /**
5888  * Return worst case up time in [ILP cycles] for the given resource.
5889  *
5890  * Example use case: the d11 core needs to be programmed with the max time it
5891  * takes to make the HT clock available.
5892  *
5893  * need to check circular dependancies and prevent dead recursion.
5894  */
5895 static uint
BCMINITFN(si_pmu_res_uptime)5896 BCMINITFN(si_pmu_res_uptime)(si_t *sih, osl_t *osh,
5897 	pmuregs_t *pmu, uint8 rsrc, bool pmu_fast_trans_en)
5898 {
5899 	uint32 deps;
5900 	uint uptime, i, dup, dmax, uptrans, ret;
5901 	uint32 min_mask = 0;
5902 #ifndef SR_DEBUG
5903 	uint32 max_mask = 0;
5904 #endif /* SR_DEBUG */
5905 
5906 	/* uptime of resource 'rsrc' */
5907 	W_REG(osh, &pmu->res_table_sel, rsrc);
5908 	if (PMUREV(sih->pmurev) >= 30)
5909 		uptime = (R_REG(osh, &pmu->res_updn_timer) >> 16) & 0x7fff;
5910 	else if (PMUREV(sih->pmurev) >= 13)
5911 		uptime = (R_REG(osh, &pmu->res_updn_timer) >> 16) & 0x3ff;
5912 	else
5913 		uptime = (R_REG(osh, &pmu->res_updn_timer) >> 8) & 0xff;
5914 
5915 	/* direct dependencies of resource 'rsrc' */
5916 	deps = si_pmu_res_deps(sih, osh, pmu, PMURES_BIT(rsrc), FALSE);
5917 	for (i = 0; i <= PMURES_MAX_RESNUM; i ++) {
5918 		if (!(deps & PMURES_BIT(i)))
5919 			continue;
5920 		deps &= ~si_pmu_res_deps(sih, osh, pmu, PMURES_BIT(i), TRUE);
5921 	}
5922 #ifndef SR_DEBUG
5923 	si_pmu_res_masks(sih, &min_mask, &max_mask);
5924 #else
5925 	/* Recalculate fast pwr up delay if min res mask/max res mask has changed */
5926 	min_mask = R_REG(osh, &pmu->min_res_mask);
5927 #endif /* SR_DEBUG */
5928 	deps &= ~min_mask;
5929 
5930 	/* max uptime of direct dependencies */
5931 	dmax = 0;
5932 	for (i = 0; i <= PMURES_MAX_RESNUM; i ++) {
5933 		if (!(deps & PMURES_BIT(i)))
5934 			continue;
5935 		dup = si_pmu_res_uptime(sih, osh, pmu, (uint8)i, pmu_fast_trans_en);
5936 		if (dmax < dup)
5937 			dmax = dup;
5938 	}
5939 
5940 	PMU_MSG(("si_pmu_res_uptime: rsrc %u uptime %u(deps 0x%08x uptime %u)\n",
5941 	         rsrc, uptime, deps, dmax));
5942 
5943 	uptrans = pmu_fast_trans_en ? 0 : PMURES_UP_TRANSITION;
5944 	ret = uptime + dmax + uptrans;
5945 	return ret;
5946 }
5947 
5948 /* Return dependencies (direct or all/indirect) for the given resources */
5949 /* need to check circular dependencies and prevent dead recursion */
5950 static uint32
si_pmu_res_deps(si_t * sih,osl_t * osh,pmuregs_t * pmu,uint32 rsrcs,bool all)5951 si_pmu_res_deps(si_t *sih, osl_t *osh, pmuregs_t *pmu, uint32 rsrcs, bool all)
5952 {
5953 	uint32 deps = 0;
5954 	uint32 i;
5955 
5956 	for (i = 0; i <= PMURES_MAX_RESNUM; i ++) {
5957 		if (!(rsrcs & PMURES_BIT(i)))
5958 			continue;
5959 		W_REG(osh, &pmu->res_table_sel, i);
5960 		deps |= R_REG(osh, &pmu->res_dep_mask);
5961 	}
5962 
5963 	return !all ? deps : (deps ? (deps | si_pmu_res_deps(sih, osh, pmu, deps, TRUE)) : 0);
5964 }
5965 
5966 static bool
si_pmu_otp_is_ready(si_t * sih)5967 si_pmu_otp_is_ready(si_t *sih)
5968 {
5969 	uint32 otps = 0u;
5970 
5971 	if (AOB_ENAB(sih)) {
5972 		otps = si_corereg(sih, si_findcoreidx(sih, GCI_CORE_ID, 0u),
5973 			OFFSETOF(gciregs_t, otpstatus), 0u, 0u);
5974 	} else {
5975 		otps = si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, otpstatus), 0u, 0u);
5976 	}
5977 	return !!(otps & OTPS_READY);
5978 }
5979 
5980 static bool
si_pmu_otp_is_ready_and_wait(si_t * sih,bool on)5981 si_pmu_otp_is_ready_and_wait(si_t *sih, bool on)
5982 {
5983 	SPINWAIT((si_pmu_otp_is_ready(sih) != on), 3000u);
5984 
5985 	if (si_pmu_otp_is_ready(sih) != on) {
5986 		PMU_ERROR(("OTP ready bit not %s after wait\n", (on ? "Set" : "Clear")));
5987 		OSL_SYS_HALT();
5988 	}
5989 
5990 	return si_pmu_otp_is_ready(sih) == on;
5991 }
5992 
5993 /**
5994  * OTP is powered down/up as a means of resetting it, or for saving current when OTP is unused.
5995  * OTP is powered up/down through PMU resources.
5996  * OTP will turn OFF only if its not in the dependency of any "higher" rsrc in min_res_mask
5997  */
5998 void
si_pmu_otp_power(si_t * sih,osl_t * osh,bool on,uint32 * min_res_mask)5999 si_pmu_otp_power(si_t *sih, osl_t *osh, bool on, uint32* min_res_mask)
6000 {
6001 	pmuregs_t *pmu;
6002 	uint origidx;
6003 	uint32 rsrcs = 0;	/* rsrcs to turn on/off OTP power */
6004 	rsc_per_chip_t *rsc;	/* chip specific resource bit positions */
6005 
6006 	ASSERT(sih->cccaps & CC_CAP_PMU);
6007 
6008 	/* Don't do anything if OTP is disabled */
6009 	if (si_is_otp_disabled(sih)) {
6010 		PMU_MSG(("si_pmu_otp_power: OTP is disabled\n"));
6011 		return;
6012 	}
6013 
6014 	/* Remember original core before switch to chipc/pmu */
6015 	origidx = si_coreidx(sih);
6016 	if (AOB_ENAB(sih)) {
6017 		pmu = si_setcore(sih, PMU_CORE_ID, 0);
6018 	} else {
6019 		pmu = si_setcoreidx(sih, SI_CC_IDX);
6020 	}
6021 	ASSERT(pmu != NULL);
6022 
6023 	/*
6024 	 * OTP can't be power cycled by toggling OTP_PU for always on OTP chips. For now
6025 	 * corerev 45 is the only one that has always on OTP.
6026 	 * Instead, the chipc register OTPCtrl1 (Offset 0xF4) bit 25 (forceOTPpwrDis) is used.
6027 	 * Please refer to http://hwnbu-twiki.broadcom.com/bin/view/Mwgroup/ChipcommonRev45
6028 	 */
6029 	if (CCREV(sih->ccrev) == 45) {
6030 		uint32 otpctrl1;
6031 		otpctrl1 = si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, otpcontrol1), 0, 0);
6032 		if (on)
6033 			otpctrl1 &= ~OTPC_FORCE_PWR_OFF;
6034 		else
6035 			otpctrl1 |= OTPC_FORCE_PWR_OFF;
6036 		si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, otpcontrol1), ~0, otpctrl1);
6037 		/* Return to original core */
6038 		si_setcoreidx(sih, origidx);
6039 		return;
6040 	}
6041 
6042 	switch (CHIPID(sih->chip)) {
6043 	case BCM43012_CHIP_ID:
6044 	case BCM43013_CHIP_ID:
6045 	case BCM43014_CHIP_ID:
6046 	case BCM4360_CHIP_ID:
6047 	case BCM43460_CHIP_ID:
6048 	case BCM4352_CHIP_ID:
6049 	case BCM43526_CHIP_ID:
6050 	case BCM4376_CHIP_GRPID:
6051 	case BCM4385_CHIP_GRPID:
6052 
6053 #ifdef UNRELEASEDCHIP
6054 #endif
6055 
6056 		rsc = si_pmu_get_rsc_positions(sih);
6057 		rsrcs = PMURES_BIT(rsc->otp_pu);
6058 		break;
6059 	case BCM4378_CHIP_GRPID:
6060 	case BCM4387_CHIP_GRPID:
6061 	case BCM4388_CHIP_GRPID:
6062 	case BCM4389_CHIP_GRPID:
6063 	case BCM4397_CHIP_GRPID:
6064 		si_gci_direct(sih, GCI_OFFSETOF(sih, otpcontrol), OTPC_FORCE_OTP_PWR_DIS,
6065 			on ? 0u : OTPC_FORCE_OTP_PWR_DIS);
6066 		if (!si_pmu_otp_is_ready_and_wait(sih, on)) {
6067 			PMU_MSG(("OTP ready bit not %s after wait\n", (on ? "ON" : "OFF")));
6068 		}
6069 		break;
6070 	default:
6071 		break;
6072 	}
6073 
6074 	if (rsrcs != 0) {
6075 		bool on_check = FALSE; /* Stores otp_ready state */
6076 		uint32 min_mask = 0;
6077 
6078 		/* Turn on/off the power */
6079 		if (on) {
6080 			min_mask = R_REG(osh, &pmu->min_res_mask);
6081 			*min_res_mask = min_mask;
6082 
6083 			min_mask |= rsrcs;
6084 			min_mask |= si_pmu_res_deps(sih, osh, pmu, min_mask, TRUE);
6085 			on_check = TRUE;
6086 			/* Assuming max rsc mask defines OTP_PU, so not programming max */
6087 			PMU_MSG(("Adding rsrc 0x%x to min_res_mask\n", min_mask));
6088 			W_REG(osh, &pmu->min_res_mask, min_mask);
6089 			si_pmu_wait_for_steady_state(sih, osh, pmu);
6090 			OSL_DELAY(1000);
6091 			SPINWAIT(!(R_REG(osh, &pmu->res_state) & rsrcs),
6092 				PMU_MAX_TRANSITION_DLY);
6093 			ASSERT(R_REG(osh, &pmu->res_state) & rsrcs);
6094 		} else {
6095 			/*
6096 			 * Restore back the min_res_mask,
6097 			 * but keep OTP powered off if allowed by dependencies
6098 			 */
6099 			if (*min_res_mask)
6100 				min_mask = *min_res_mask;
6101 			else
6102 				min_mask = R_REG(osh, &pmu->min_res_mask);
6103 
6104 			min_mask &= ~rsrcs;
6105 			/*
6106 			 * OTP rsrc can be cleared only if its not
6107 			 * in the dependency of any "higher" rsrc in min_res_mask
6108 			 */
6109 			min_mask |= si_pmu_res_deps(sih, osh, pmu, min_mask, TRUE);
6110 			on_check = ((min_mask & rsrcs) != 0);
6111 
6112 			PMU_MSG(("Removing rsrc 0x%x from min_res_mask\n", min_mask));
6113 			W_REG(osh, &pmu->min_res_mask, min_mask);
6114 			si_pmu_wait_for_steady_state(sih, osh, pmu);
6115 		}
6116 
6117 		if (!si_pmu_otp_is_ready_and_wait(sih, on_check)) {
6118 			PMU_MSG(("OTP ready bit not %s after wait\n", (on_check ? "ON" : "OFF")));
6119 		}
6120 #ifdef NOT_YET
6121 		/*
6122 		 * FIXME: Temporarily disabling OTPS_READY ASSERT check. Right now ASSERT in
6123 		 * ROM is enabled only for 4389B0/C0. Therefore this change anyway will not
6124 		 * affect other chips. Once the correct spin-wait value is updated by the
6125 		 * HW team, then this ASSERT will be enabled back.
6126 		 */
6127 		ASSERT(si_pmu_otp_is_ready(sih) == on_check);
6128 #endif /* NOT_YET */
6129 	}
6130 
6131 	/* Return to original core */
6132 	si_setcoreidx(sih, origidx);
6133 } /* si_pmu_otp_power */
6134 
6135 void
si_pmu_spuravoid(si_t * sih,osl_t * osh,uint8 spuravoid)6136 si_pmu_spuravoid(si_t *sih, osl_t *osh, uint8 spuravoid)
6137 {
6138 	uint origidx;
6139 	bcm_int_bitmask_t intr_val;
6140 
6141 	/* Block ints and save current core */
6142 	si_introff(sih, &intr_val);
6143 	origidx = si_coreidx(sih);
6144 
6145 	/* Return to original core */
6146 	si_setcoreidx(sih, origidx);
6147 	si_intrrestore(sih, &intr_val);
6148 } /* si_pmu_spuravoid */
6149 
6150 /* below function are only for BBPLL parallel purpose */
6151 /* For having the pllcontrol data values for spuravoid */
6152 typedef struct {
6153 	uint8	spuravoid_mode;
6154 	uint8	pllctrl_reg;
6155 	uint32	pllctrl_regval;
6156 } pllctrl_spuravoid_t;
6157 
6158 uint32
si_pmu_pll28nm_fvco(si_t * sih)6159 si_pmu_pll28nm_fvco(si_t *sih)
6160 {
6161 	uint32 r_high, r_low, r;
6162 	uint32 xf = si_alp_clock(sih);
6163 	/* PLL registers for 4368 */
6164 	uint32 pllreg5 = si_pmu_pllcontrol(sih, PMU_PLL_CTRL_REG5, 0, 0);
6165 	uint32 pllreg4 = si_pmu_pllcontrol(sih, PMU_PLL_CTRL_REG4, 0, 0);
6166 	/* p1div has lower 2 bits in pll4 and high 2 bits in pll5  */
6167 	uint8 p1div_lo = (pllreg4 & PMU4368_PLL1_PC4_P1DIV_MASK) >> PMU4368_PLL1_PC4_P1DIV_SHIFT;
6168 	uint8 p1div_hi = (pllreg5 & PMU4368_PLL1_PC5_P1DIV_MASK) >> PMU4368_PLL1_PC5_P1DIV_SHIFT;
6169 	uint8 p1div = (p1div_hi << PMU4368_P1DIV_HI_SHIFT) | (p1div_lo << PMU4368_P1DIV_LO_SHIFT);
6170 	uint32 ndiv_int = (pllreg5 & PMU4368_PLL1_PC5_NDIV_INT_MASK) >>
6171 		PMU4368_PLL1_PC5_NDIV_INT_SHIFT;
6172 	uint32 ndiv_frac = (pllreg5 & PMU4368_PLL1_PC5_NDIV_FRAC_MASK) >>
6173 		PMU4368_PLL1_PC5_NDIV_FRAC_SHIFT;
6174 
6175 	if (ISSIM_ENAB(sih)) {
6176 		/* PLL CTRL registers are meaningless under QT, return the pre-configured freq */
6177 		return (FVCO_720 * 1000);
6178 	} else if (p1div == 0) {
6179 		/* PLL register read fails, return 0 so caller can retry */
6180 		PMU_ERROR(("p1div is invalid\n"));
6181 		return 0;
6182 	}
6183 
6184 	/* Calculate xf * ( ndiv_frac / (1 << 20) + ndiv_int) / p1div)
6185 	 * To reduce the inaccuracy in division,
6186 	 * Covert to (xf * ndiv_frac / (1 << 20) + xf * ndiv_int) / p1div
6187 	 */
6188 	math_uint64_multiple_add(&r_high, &r_low, xf, ndiv_frac, 0);
6189 	/* Make sure the caclulated 64 bits number is in the safe rage (with in 52 bits),
6190 	 * so we have a valid 32 bits result after divided by 1<<20
6191 	 */
6192 	ASSERT((r_high & 0xFFE00000) == 0);
6193 	math_uint64_right_shift(&r, r_high, r_low, 20);
6194 
6195 	return (r + ndiv_int * xf) / p1div;
6196 }
6197 
6198 bool
si_pmu_is_otp_powered(si_t * sih,osl_t * osh)6199 si_pmu_is_otp_powered(si_t *sih, osl_t *osh)
6200 {
6201 	uint idx;
6202 	pmuregs_t *pmu;
6203 	bool st;
6204 	rsc_per_chip_t *rsc;		/* chip specific resource bit positions */
6205 
6206 	/* Remember original core before switch to chipc/pmu */
6207 	idx = si_coreidx(sih);
6208 	if (AOB_ENAB(sih)) {
6209 		pmu = si_setcore(sih, PMU_CORE_ID, 0);
6210 	} else {
6211 		pmu = si_setcoreidx(sih, SI_CC_IDX);
6212 	}
6213 	ASSERT(pmu != NULL);
6214 
6215 	si_pmu_wait_for_steady_state(sih, osh, pmu);
6216 
6217 	switch (CHIPID(sih->chip)) {
6218 	case BCM43012_CHIP_ID:
6219 	case BCM43013_CHIP_ID:
6220 	case BCM43014_CHIP_ID:
6221 	case BCM4360_CHIP_ID:
6222 	case BCM43460_CHIP_ID:
6223 	case BCM43526_CHIP_ID:
6224 	case BCM4352_CHIP_ID:
6225 	case BCM4369_CHIP_GRPID:
6226 	case BCM4362_CHIP_GRPID:
6227 	case BCM4376_CHIP_GRPID:
6228 	case BCM4385_CHIP_GRPID:
6229 		rsc = si_pmu_get_rsc_positions(sih);
6230 		st = (R_REG(osh, &pmu->res_state) & PMURES_BIT(rsc->otp_pu)) != 0;
6231 		break;
6232 	case BCM4378_CHIP_GRPID:
6233 	case BCM4387_CHIP_GRPID:
6234 	case BCM4388_CHIP_GRPID:
6235 	case BCM4389_CHIP_GRPID:
6236 	case BCM4397_CHIP_GRPID:
6237 		st = (!(si_gci_direct(sih, GCI_OFFSETOF(sih, otpcontrol), 0u, 0u) &
6238 			OTPC_FORCE_OTP_PWR_DIS)) && si_pmu_otp_is_ready_and_wait(sih, TRUE);
6239 		break;
6240 	default:
6241 		st = TRUE;
6242 		break;
6243 	}
6244 
6245 	/* Return to original core */
6246 	si_setcoreidx(sih, idx);
6247 	return st;
6248 } /* si_pmu_is_otp_powered */
6249 
6250 /**
6251  * Some chip/boards can be optionally fitted with an external 32Khz clock source for increased power
6252  * savings (due to more accurate sleep intervals).
6253  */
6254 static void
BCMATTACHFN(si_pmu_set_lpoclk)6255 BCMATTACHFN(si_pmu_set_lpoclk)(si_t *sih, osl_t *osh)
6256 {
6257 	uint32 ext_lpo_sel, int_lpo_sel, timeout = 0,
6258 		ext_lpo_avail = 0, lpo_sel = 0;
6259 	uint32 ext_lpo_isclock; /* On e.g. 43602a0, either x-tal or clock can be on LPO pins */
6260 	pmuregs_t *pmu;
6261 	uint origidx;
6262 
6263 	if (!(getintvar(NULL, "boardflags3")))
6264 		return;
6265 
6266 	/* Remember original core before switch to chipc/pmu */
6267 	origidx = si_coreidx(sih);
6268 	if (AOB_ENAB(sih)) {
6269 		pmu = si_setcore(sih, PMU_CORE_ID, 0);
6270 	} else {
6271 		pmu = si_setcoreidx(sih, SI_CC_IDX);
6272 	}
6273 	ASSERT(pmu != NULL);
6274 
6275 	ext_lpo_sel = getintvar(NULL, "boardflags3") & BFL3_FORCE_EXT_LPO_SEL;
6276 	int_lpo_sel = getintvar(NULL, "boardflags3") & BFL3_FORCE_INT_LPO_SEL;
6277 	ext_lpo_isclock = getintvar(NULL, "boardflags3") & BFL3_EXT_LPO_ISCLOCK;
6278 
6279 	BCM_REFERENCE(ext_lpo_isclock);
6280 
6281 	if (ext_lpo_sel != 0) {
6282 		switch (CHIPID(sih->chip)) {
6283 		CASE_BCM43602_CHIP:
6284 			/* External LPO is POR default enabled */
6285 			si_pmu_chipcontrol(sih, PMU_CHIPCTL2, PMU43602_CC2_XTAL32_SEL,
6286 				ext_lpo_isclock ? 0 : PMU43602_CC2_XTAL32_SEL);
6287 			break;
6288 		default:
6289 			/* Force External LPO Power Up */
6290 			si_pmu_chipcontrol(sih, PMU_CHIPCTL0, CC_EXT_LPO_PU, CC_EXT_LPO_PU);
6291 			si_gci_chipcontrol(sih, CHIPCTRLREG6, GC_EXT_LPO_PU, GC_EXT_LPO_PU);
6292 			break;
6293 		}
6294 
6295 		ext_lpo_avail = R_REG(osh, &pmu->pmustatus) & EXT_LPO_AVAIL;
6296 		while (ext_lpo_avail == 0 && timeout < LPO_SEL_TIMEOUT) {
6297 			OSL_DELAY(1000);
6298 			ext_lpo_avail = R_REG(osh, &pmu->pmustatus) & EXT_LPO_AVAIL;
6299 			timeout++;
6300 		}
6301 
6302 		if (timeout >= LPO_SEL_TIMEOUT) {
6303 			PMU_ERROR(("External LPO is not available\n"));
6304 		} else {
6305 			/* External LPO is available, lets use (=select) it */
6306 			OSL_DELAY(1000);
6307 			timeout = 0;
6308 
6309 			switch (CHIPID(sih->chip)) {
6310 			CASE_BCM43602_CHIP:
6311 				si_pmu_chipcontrol(sih, PMU_CHIPCTL2, PMU43602_CC2_FORCE_EXT_LPO,
6312 					PMU43602_CC2_FORCE_EXT_LPO); /* switches to external LPO */
6313 				break;
6314 			default:
6315 				/* Force External LPO Sel up */
6316 				si_gci_chipcontrol(sih, CHIPCTRLREG6, EXT_LPO_SEL, EXT_LPO_SEL);
6317 				/* Clear Force Internal LPO Sel */
6318 				si_gci_chipcontrol(sih, CHIPCTRLREG6, INT_LPO_SEL, 0x0);
6319 				OSL_DELAY(1000);
6320 
6321 				lpo_sel = R_REG(osh, &pmu->pmucontrol) & LPO_SEL;
6322 				while (lpo_sel != 0 && timeout < LPO_SEL_TIMEOUT) {
6323 					OSL_DELAY(1000);
6324 					lpo_sel = R_REG(osh, &pmu->pmucontrol) & LPO_SEL;
6325 					timeout++;
6326 				}
6327 			}
6328 
6329 			if (timeout >= LPO_SEL_TIMEOUT) {
6330 				PMU_ERROR(("External LPO is not set\n"));
6331 				/* Clear Force External LPO Sel */
6332 				switch (CHIPID(sih->chip)) {
6333 				CASE_BCM43602_CHIP:
6334 					si_pmu_chipcontrol(sih, PMU_CHIPCTL2,
6335 						PMU43602_CC2_FORCE_EXT_LPO, 0);
6336 					break;
6337 				default:
6338 					si_gci_chipcontrol(sih, CHIPCTRLREG6, EXT_LPO_SEL, 0x0);
6339 					break;
6340 				}
6341 			} else {
6342 				/* Clear Force Internal LPO Power Up */
6343 				switch (CHIPID(sih->chip)) {
6344 				CASE_BCM43602_CHIP:
6345 					break;
6346 				default:
6347 					si_pmu_chipcontrol(sih, PMU_CHIPCTL0, CC_INT_LPO_PU, 0x0);
6348 					si_gci_chipcontrol(sih, CHIPCTRLREG6, GC_INT_LPO_PU, 0x0);
6349 					break;
6350 				}
6351 			} /* if (timeout) */
6352 		} /* if (timeout) */
6353 	} else if (int_lpo_sel != 0) {
6354 		switch (CHIPID(sih->chip)) {
6355 		CASE_BCM43602_CHIP:
6356 			break; /* do nothing, internal LPO is POR default powered and selected */
6357 		default:
6358 			/* Force Internal LPO Power Up */
6359 			si_pmu_chipcontrol(sih, PMU_CHIPCTL0, CC_INT_LPO_PU, CC_INT_LPO_PU);
6360 			si_gci_chipcontrol(sih, CHIPCTRLREG6, GC_INT_LPO_PU, GC_INT_LPO_PU);
6361 
6362 			OSL_DELAY(1000);
6363 
6364 			/* Force Internal LPO Sel up */
6365 			si_gci_chipcontrol(sih, CHIPCTRLREG6, INT_LPO_SEL, INT_LPO_SEL);
6366 			/* Clear Force External LPO Sel */
6367 			si_gci_chipcontrol(sih, CHIPCTRLREG6, EXT_LPO_SEL, 0x0);
6368 
6369 			OSL_DELAY(1000);
6370 
6371 			lpo_sel = R_REG(osh, &pmu->pmucontrol) & LPO_SEL;
6372 			timeout = 0;
6373 			while (lpo_sel == 0 && timeout < LPO_SEL_TIMEOUT) {
6374 				OSL_DELAY(1000);
6375 				lpo_sel = R_REG(osh, &pmu->pmucontrol) & LPO_SEL;
6376 				timeout++;
6377 			}
6378 			if (timeout >= LPO_SEL_TIMEOUT) {
6379 				PMU_ERROR(("Internal LPO is not set\n"));
6380 				/* Clear Force Internal LPO Sel */
6381 				si_gci_chipcontrol(sih, CHIPCTRLREG6, INT_LPO_SEL, 0x0);
6382 			} else {
6383 				/* Clear Force External LPO Power Up */
6384 				si_pmu_chipcontrol(sih, PMU_CHIPCTL0, CC_EXT_LPO_PU, 0x0);
6385 				si_gci_chipcontrol(sih, CHIPCTRLREG6, GC_EXT_LPO_PU, 0x0);
6386 			}
6387 			break;
6388 		}
6389 		if ((PMUREV(sih->pmurev) >= 33)) {
6390 			/* Enabling FAST_SEQ */
6391 			PMU_REG(sih, pmucontrol_ext, PCTL_EXT_FASTSEQ_ENAB, PCTL_EXT_FASTSEQ_ENAB);
6392 		}
6393 	}
6394 
6395 	/* Return to original core */
6396 	si_setcoreidx(sih, origidx);
6397 } /* si_pmu_set_lpoclk */
6398 
6399 static int
si_pmu_fast_lpo_locked(si_t * sih,osl_t * osh)6400 si_pmu_fast_lpo_locked(si_t *sih, osl_t *osh)
6401 {
6402 	int lock = 0;
6403 	switch (CHIPID(sih->chip)) {
6404 	case BCM43012_CHIP_ID:
6405 	case BCM43013_CHIP_ID:
6406 	case BCM43014_CHIP_ID:
6407 		lock = CHIPC_REG(sih, chipstatus, 0, 0) & CST43012_FLL_LOCK;
6408 		break;
6409 	case BCM4369_CHIP_GRPID:
6410 	case BCM4376_CHIP_GRPID:
6411 	case BCM4378_CHIP_GRPID:
6412 		lock = si_gci_chipstatus(sih, GCI_CHIPSTATUS_13) & GCI_CS_4369_FLL1MHZ_LOCK_MASK;
6413 		break;
6414 	case BCM4385_CHIP_GRPID:
6415 	case BCM4387_CHIP_GRPID:
6416 	case BCM4388_CHIP_GRPID:
6417 	case BCM4389_CHIP_GRPID:
6418 	case BCM4397_CHIP_GRPID:
6419 		lock = si_gci_chipstatus(sih, GCI_CHIPSTATUS_15) & GCI_CS_4387_FLL1MHZ_LOCK_MASK;
6420 		break;
6421 	default:
6422 		PMU_MSG(("si_pmu_fast_lpo_locked: LPO enable: unsupported chip!\n"));
6423 	}
6424 	return lock ? 1 : 0;
6425 }
6426 
6427 /* Turn ON FAST LPO FLL (1MHz) */
6428 static void
BCMATTACHFN(si_pmu_fast_lpo_enable)6429 BCMATTACHFN(si_pmu_fast_lpo_enable)(si_t *sih, osl_t *osh)
6430 {
6431 	int i = 0, lock = 0;
6432 
6433 	BCM_REFERENCE(i);
6434 	BCM_REFERENCE(lock);
6435 
6436 	switch (CHIPID(sih->chip)) {
6437 	case BCM43012_CHIP_ID:
6438 	case BCM43013_CHIP_ID:
6439 	case BCM43014_CHIP_ID:
6440 		PMU_REG(sih, pmucontrol_ext, PCTL_EXT_FASTLPO_ENAB, PCTL_EXT_FASTLPO_ENAB);
6441 		lock = CHIPC_REG(sih, chipstatus, 0, 0) & CST43012_FLL_LOCK;
6442 
6443 		for (i = 0; ((i <= 30) && (!lock)); i++)
6444 		{
6445 			lock = CHIPC_REG(sih, chipstatus, 0, 0) & CST43012_FLL_LOCK;
6446 			OSL_DELAY(10);
6447 		}
6448 
6449 		PMU_MSG(("si_pmu_fast_lpo_enable: duration: %d\n", i*10));
6450 
6451 		if (!lock) {
6452 			PMU_MSG(("si_pmu_fast_lpo_enable: FLL lock not present!"));
6453 			ROMMABLE_ASSERT(0);
6454 		}
6455 
6456 		/* Now switch to using FAST LPO clk */
6457 		PMU_REG(sih, pmucontrol_ext, PCTL_EXT_FASTLPO_SWENAB, PCTL_EXT_FASTLPO_SWENAB);
6458 		break;
6459 	case BCM4369_CHIP_GRPID:
6460 	case BCM4376_CHIP_GRPID:
6461 	case BCM4378_CHIP_GRPID:
6462 	case BCM4385_CHIP_GRPID:
6463 	case BCM4387_CHIP_GRPID:
6464 	case BCM4388_CHIP_GRPID:
6465 	case BCM4389_CHIP_GRPID:
6466 	case BCM4397_CHIP_GRPID:
6467 	{
6468 		uint8	fastlpo_dis = fastlpo_dis_get();
6469 		uint8	fastlpo_pcie_dis = fastlpo_pcie_dis_get();
6470 
6471 		if (!fastlpo_dis || !fastlpo_pcie_dis) {
6472 			/* LHL rev 6 in 4387 requires this bit to be set first */
6473 			if ((LHLREV(sih->lhlrev) >= 6) && !PMU_FLL_PU_ENAB()) {
6474 				LHL_REG(sih, lhl_top_pwrseq_ctl_adr,
6475 				        LHL_PWRSEQCTL_PMU_LPLDO_PD, LHL_PWRSEQCTL_WL_FLLPU_EN);
6476 			}
6477 
6478 			PMU_REG(sih, pmucontrol_ext, PCTL_EXT_FASTLPO_ENAB, PCTL_EXT_FASTLPO_ENAB);
6479 
6480 			lock = si_pmu_fast_lpo_locked(sih, osh);
6481 			for (i = 0; ((i < 300) && (!lock)); i++) {
6482 				lock = si_pmu_fast_lpo_locked(sih, osh);
6483 				OSL_DELAY(10);
6484 			}
6485 			ASSERT(lock);
6486 		}
6487 
6488 		if (!fastlpo_dis) {
6489 			/* Now switch to using FAST LPO clk */
6490 			PMU_REG(sih, pmucontrol_ext,
6491 				PCTL_EXT_FASTLPO_SWENAB, PCTL_EXT_FASTLPO_SWENAB);
6492 
6493 			OSL_DELAY(1000);
6494 			PMU_MSG(("pmu fast lpo enabled\n"));
6495 		}
6496 		break;
6497 	}
6498 	default:
6499 		PMU_MSG(("si_pmu_fast_lpo_enable: LPO enable: unsupported chip!\n"));
6500 	}
6501 }
6502 
6503 /* Turn ON FAST LPO FLL (1MHz) for PCIE */
6504 bool
BCMATTACHFN(si_pmu_fast_lpo_enable_pcie)6505 BCMATTACHFN(si_pmu_fast_lpo_enable_pcie)(si_t *sih)
6506 {
6507 	if (!FASTLPO_ENAB()) {
6508 		return FALSE;
6509 	}
6510 
6511 	switch (CHIPID(sih->chip)) {
6512 	case BCM4369_CHIP_GRPID:
6513 	case BCM4376_CHIP_GRPID:
6514 	case BCM4378_CHIP_GRPID:
6515 	case BCM4385_CHIP_GRPID:
6516 	case BCM4387_CHIP_GRPID:
6517 	case BCM4388_CHIP_GRPID:
6518 	case BCM4389_CHIP_GRPID:
6519 	case BCM4397_CHIP_GRPID:
6520 	{
6521 		uint8	fastlpo_pcie_dis = fastlpo_pcie_dis_get();
6522 
6523 		if (!fastlpo_pcie_dis) {
6524 			PMU_REG(sih, pmucontrol_ext,
6525 				PCTL_EXT_FASTLPO_PCIE_SWENAB, PCTL_EXT_FASTLPO_PCIE_SWENAB);
6526 			OSL_DELAY(1000);
6527 			PMU_MSG(("pcie fast lpo enabled\n"));
6528 			return TRUE;
6529 		}
6530 		break;
6531 	}
6532 	default:
6533 		PMU_MSG(("si_pmu_fast_lpo_enable_pcie: LPO enable: unsupported chip!\n"));
6534 	}
6535 
6536 	return FALSE;
6537 }
6538 
6539 /* Turn ON FAST LPO FLL (1MHz) for PMU */
6540 bool
BCMATTACHFN(si_pmu_fast_lpo_enable_pmu)6541 BCMATTACHFN(si_pmu_fast_lpo_enable_pmu)(si_t *sih)
6542 {
6543 	if (!FASTLPO_ENAB()) {
6544 		return FALSE;
6545 	}
6546 
6547 	switch (CHIPID(sih->chip)) {
6548 	case BCM4369_CHIP_GRPID:
6549 	case BCM4376_CHIP_GRPID:
6550 	case BCM4378_CHIP_GRPID:
6551 	case BCM4385_CHIP_GRPID:
6552 	case BCM4387_CHIP_GRPID:
6553 	case BCM4388_CHIP_GRPID:
6554 	case BCM4389_CHIP_GRPID:
6555 	case BCM4397_CHIP_GRPID:
6556 	{
6557 		uint8	fastlpo_dis = fastlpo_dis_get();
6558 
6559 		if (!fastlpo_dis) {
6560 			PMU_MSG(("pmu fast lpo enabled\n"));
6561 			return TRUE;
6562 		}
6563 		break;
6564 	}
6565 	default:
6566 		PMU_MSG(("si_pmu_fast_lpo_enable_pmu: LPO enable: unsupported chip!\n"));
6567 	}
6568 
6569 	return FALSE;
6570 }
6571 
6572 static uint8
BCMATTACHFN(fastlpo_dis_get)6573 BCMATTACHFN(fastlpo_dis_get)(void)
6574 {
6575 	uint8 fastlpo_dis = 1;
6576 
6577 #if defined(BCM_FASTLPO_PMU) && !defined(BCM_FASTLPO_PMU_DISABLED)
6578 	if (FASTLPO_ENAB()) {
6579 		fastlpo_dis = 0;
6580 		if (getvar(NULL, rstr_fastlpo_dis) != NULL) {
6581 			fastlpo_dis = (uint8)getintvar(NULL, rstr_fastlpo_dis);
6582 		}
6583 	}
6584 #endif  /* BCM_FASTLPO_PMU */
6585 	return fastlpo_dis;
6586 }
6587 
6588 static uint8
BCMATTACHFN(fastlpo_pcie_dis_get)6589 BCMATTACHFN(fastlpo_pcie_dis_get)(void)
6590 {
6591 	uint8 fastlpo_pcie_dis = 1;
6592 
6593 	if (FASTLPO_ENAB()) {
6594 		fastlpo_pcie_dis = 0;
6595 		if (getvar(NULL, rstr_fastlpo_pcie_dis) != NULL) {
6596 			fastlpo_pcie_dis = (uint8)getintvar(NULL, rstr_fastlpo_pcie_dis);
6597 		}
6598 	}
6599 	return fastlpo_pcie_dis;
6600 }
6601 
6602 static void
BCMATTACHFN(si_pmu_fll_preload_enable)6603 BCMATTACHFN(si_pmu_fll_preload_enable)(si_t *sih)
6604 {
6605 	if (!PMU_FLL_PU_ENAB()) {
6606 		return;
6607 	}
6608 
6609 	switch (CHIPID(sih->chip)) {
6610 	case BCM4387_CHIP_GRPID:
6611 	case BCM4388_CHIP_GRPID:
6612 	case BCM4389_CHIP_GRPID:
6613 	{
6614 		uint32 fll_dac_out;
6615 
6616 		fll_dac_out = (si_gci_chipstatus(sih, GCI_CHIPSTATUS_15) &
6617 			GCI_CS_4387_FLL1MHZ_DAC_OUT_MASK)
6618 			>> GCI_CS_4387_FLL1MHZ_DAC_OUT_SHIFT;
6619 
6620 		LHL_REG(sih, lhl_wl_hw_ctl_adr[1],
6621 			LHL_1MHZ_FLL_DAC_EXT_MASK,
6622 			(fll_dac_out) << LHL_1MHZ_FLL_DAC_EXT_SHIFT);
6623 		LHL_REG(sih, lhl_wl_hw_ctl_adr[1],
6624 			LHL_1MHZ_FLL_PRELOAD_MASK,
6625 			LHL_1MHZ_FLL_PRELOAD_MASK);
6626 		break;
6627 	}
6628 	default:
6629 		PMU_MSG(("si_pmu_fll_preload_enable: unsupported chip!\n"));
6630 		ASSERT(0);
6631 		break;
6632 	}
6633 }
6634 
6635 /* LV sleep mode summary:
6636  * LV mode is where both ABUCK and CBUCK are programmed to low voltages during
6637  * sleep, and VMUX selects ABUCK as VDDOUT_AON. LPLDO needs to power off.
6638  * With ASR ON, LPLDO OFF
6639  */
6640 #if defined(SAVERESTORE)
6641 static void
BCMATTACHFN(si_set_lv_sleep_mode_pmu)6642 BCMATTACHFN(si_set_lv_sleep_mode_pmu)(si_t *sih, osl_t *osh)
6643 {
6644 	/* jtag_udr_write USER_REG9W jtag_serdes_pic_enable 1 */
6645 	if (BCM4369_CHIP(sih->chip) && (CHIPREV(sih->chiprev) == 0)) {
6646 		si_pmu_chipcontrol(sih, PMU_CHIPCTL4, PMU_CC4_4369_AUX_PD_MEMLPLDO2VDDB_ON, 0);
6647 
6648 		//JTAG_SEL override. When this bit is set, jtag_sel 0, Required for JTAG writes
6649 		/* Temporarily we are disabling this as it is not required..
6650 		si_gci_chipcontrol(sih, CC_GCI_CHIPCTRL_06, 0x10, 0x10);
6651 		jtag_setbit_128(sih, 9, 103, 1);
6652 		si_gci_chipcontrol(sih, CC_GCI_CHIPCTRL_06, 0x10, 0x0);
6653 		*/
6654 
6655 	}
6656 
6657 	/* Program pmu VREG resgiter for Resouce based ABUCK and CBUCK modes
6658 	 *      cbuck rsrc 0 - PWM and abuck rsrc 0 - Auto, rsrc 1 - PWM
6659 	 */
6660 	si_pmu_vreg_control(sih, PMU_VREG_16, PMU_4369_VREG16_RSRC0_CBUCK_MODE_MASK,
6661 		0x3u << PMU_4369_VREG16_RSRC0_CBUCK_MODE_SHIFT);
6662 	si_pmu_vreg_control(sih, PMU_VREG_16, PMU_4369_VREG16_RSRC0_ABUCK_MODE_MASK,
6663 		0x3u << PMU_4369_VREG16_RSRC0_ABUCK_MODE_SHIFT);
6664 	si_pmu_vreg_control(sih, PMU_VREG_16, PMU_4369_VREG16_RSRC1_ABUCK_MODE_MASK,
6665 		0x3u << PMU_4369_VREG16_RSRC1_ABUCK_MODE_SHIFT);
6666 	si_pmu_vreg_control(sih, PMU_VREG_16, PMU_4369_VREG16_RSRC2_ABUCK_MODE_MASK,
6667 		0x3u << PMU_4369_VREG16_RSRC2_ABUCK_MODE_SHIFT);
6668 
6669 	/* asr voltage adjust PWM - 0.8V */
6670 	si_pmu_vreg_control(sih, PMU_VREG_8, PMU_4369_VREG8_ASR_OVADJ_LPPFM_MASK,
6671 		0x10u << PMU_4369_VREG8_ASR_OVADJ_LPPFM_SHIFT);
6672 
6673 	/* Enable rsrc_en_asr_msk[0] and msk[1] */
6674 	si_pmu_vreg_control(sih, PMU_VREG_13, PMU_4369_VREG13_RSRC_EN0_ASR_MASK,
6675 		0x1u << PMU_4369_VREG13_RSRC_EN0_ASR_SHIFT);
6676 	si_pmu_vreg_control(sih, PMU_VREG_13, PMU_4369_VREG13_RSRC_EN1_ASR_MASK,
6677 		0x1u << PMU_4369_VREG13_RSRC_EN1_ASR_SHIFT);
6678 	si_pmu_vreg_control(sih, PMU_VREG_13, PMU_4369_VREG13_RSRC_EN2_ASR_MASK,
6679 		0x1u << PMU_4369_VREG13_RSRC_EN2_ASR_SHIFT);
6680 
6681 	si_pmu_vreg_control(sih, PMU_VREG_14, PMU_4369_VREG14_RSRC_EN_CSR_MASK0_MASK,
6682 		0x1u << PMU_4369_VREG14_RSRC_EN_CSR_MASK0_SHIFT);
6683 
6684 	/* disable force_hp_mode and enable wl_pmu_lv_mod */
6685 	si_pmu_vreg_control(sih, PMU_VREG_7,
6686 		(PMU_4369_VREG_7_WL_PMU_LV_MODE_MASK | PMU_4369_VREG_7_WL_PMU_LP_MODE_MASK |
6687 		PMU_4369_VREG_7_PMU_FORCE_HP_MODE_MASK), PMU_4369_VREG_7_WL_PMU_LV_MODE_MASK);
6688 
6689 	/* Enable MISCLDO only for A0, MEMLPLDO_adj -0.7V, Disable LPLDO power up */
6690 	/* For 4387, should not disable because this is PU when analog PMU is out of sleep
6691 	 * and bypass when in sleep mode
6692 	 */
6693 	if (!(BCM4389_CHIP(sih->chip) || BCM4388_CHIP(sih->chip) || BCM4397_CHIP(sih->chip) ||
6694 		BCM4387_CHIP(sih->chip))) {
6695 		si_pmu_vreg_control(sih, PMU_VREG_5, PMU_4369_VREG_5_MISCLDO_POWER_UP_MASK,
6696 			((CHIPREV(sih->chiprev) == 0) ? 1 : 0) <<
6697 			  PMU_4369_VREG_5_MISCLDO_POWER_UP_SHIFT);
6698 	}
6699 	si_pmu_vreg_control(sih, PMU_VREG_5, PMU_4369_VREG_5_LPLDO_POWER_UP_MASK, 0x0u);
6700 	si_pmu_vreg_control(sih, PMU_VREG_5, PMU_4369_VREG_5_MEMLPLDO_OP_VLT_ADJ_CTRL_MASK,
6701 		0xDu << PMU_4369_VREG_5_MEMLPLDO_OP_VLT_ADJ_CTRL_SHIFT);
6702 	si_pmu_vreg_control(sih, PMU_VREG_5, PMU_4369_VREG_5_LPLDO_OP_VLT_ADJ_CTRL_MASK,
6703 		0xFu << PMU_4369_VREG_5_LPLDO_OP_VLT_ADJ_CTRL_SHIFT);
6704 
6705 	/* Enabale MEMLPLDO ( to enable 0x08)and BTLDO is enabled. At sleep RFLDO is disabled */
6706 	si_pmu_vreg_control(sih, PMU_VREG_6, PMU_4369_VREG_6_MEMLPLDO_POWER_UP_MASK,
6707 		0x1u << PMU_4369_VREG_6_MEMLPLDO_POWER_UP_SHIFT);
6708 
6709 	/* Program PMU chip cntrl register to control
6710 	 *     cbuck2vddb_pwrsw_force_on =1 and memlpldo2vddb_pwrsw_force_off = 1
6711 	 *     cbuck2ret_pwrsw_force_on = 1 and memlpldo2vddb_pwrsw_force_off = 1
6712 	 *     set d11_2x2_bw80_cbuck2vddb_pwrsw_force_on and
6713 	 *     d11_2x2_bw20_cbuck2vddb_pwrsw_force_on cbuck2ret_pwrsw on 4 cores
6714 	 */
6715 	si_pmu_chipcontrol(sih, PMU_CHIPCTL4,
6716 		(PMU_CC4_4369_MAIN_PD_CBUCK2VDDB_ON | PMU_CC4_4369_MAIN_PD_CBUCK2VDDRET_ON |
6717 		PMU_CC4_4369_MAIN_PD_MEMLPLDO2VDDB_ON | PMU_CC4_4369_MAIN_PD_MEMLPDLO2VDDRET_ON),
6718 		(PMU_CC4_4369_MAIN_PD_CBUCK2VDDB_ON | PMU_CC4_4369_MAIN_PD_CBUCK2VDDRET_ON));
6719 	si_pmu_chipcontrol(sih, PMU_CHIPCTL4,
6720 		(PMU_CC4_4369_AUX_PD_CBUCK2VDDB_ON | PMU_CC4_4369_AUX_PD_CBUCK2VDDRET_ON |
6721 		PMU_CC4_4369_AUX_PD_MEMLPLDO2VDDB_ON | PMU_CC4_4369_AUX_PD_MEMLPLDO2VDDRET_ON),
6722 		(PMU_CC4_4369_AUX_PD_CBUCK2VDDB_ON | PMU_CC4_4369_AUX_PD_CBUCK2VDDRET_ON));
6723 
6724 	/* set subcore_cbuck2vddb_pwrsw_force_on */
6725 	si_pmu_chipcontrol(sih, PMU_CHIPCTL5,
6726 		(PMU_CC5_4369_SUBCORE_CBUCK2VDDB_ON | PMU_CC5_4369_SUBCORE_CBUCK2VDDRET_ON |
6727 		PMU_CC5_4369_SUBCORE_MEMLPLDO2VDDB_ON | PMU_CC5_4369_SUBCORE_MEMLPLDO2VDDRET_ON),
6728 		(PMU_CC5_4369_SUBCORE_CBUCK2VDDB_ON | PMU_CC5_4369_SUBCORE_CBUCK2VDDRET_ON));
6729 
6730 	/* Set subcore_memlpldo2vddb_pwrsw_force_off, d11_2x2_bw80_memlpldo2vddb_pwrsw_force_off
6731 	 * and d11_2x2_bw20_memlpldo2vddb_pwrsw_force_off
6732 	 * Set subcore_memlpldo2vddret_pwrsw_force_off,d11_2x2_bw80_memlpldo2vddret_pwrsw_force_off
6733 	 * and d11_2x2_bw20_memlpldo2vddret_pwrsw_force_off
6734 	 */
6735 	si_pmu_chipcontrol(sih, PMU_CHIPCTL13,
6736 		(PMU_CC13_SUBCORE_CBUCK2VDDB_OFF | PMU_CC13_SUBCORE_CBUCK2VDDRET_OFF |
6737 		PMU_CC13_SUBCORE_MEMLPLDO2VDDB_OFF | PMU_CC13_SUBCORE_MEMLPLDO2VDDRET_OFF),
6738 		(PMU_CC13_SUBCORE_MEMLPLDO2VDDB_OFF | PMU_CC13_SUBCORE_MEMLPLDO2VDDRET_OFF));
6739 	si_pmu_chipcontrol(sih, PMU_CHIPCTL13,
6740 		(PMU_CC13_MAIN_CBUCK2VDDB_OFF | PMU_CC13_MAIN_CBUCK2VDDRET_OFF |
6741 		PMU_CC13_MAIN_MEMLPLDO2VDDB_OFF | PMU_CC13_MAIN_MEMLPLDO2VDDRET_OFF),
6742 		(PMU_CC13_MAIN_MEMLPLDO2VDDB_OFF | PMU_CC13_MAIN_MEMLPLDO2VDDRET_OFF));
6743 	si_pmu_chipcontrol(sih, PMU_CHIPCTL13,
6744 		(PMU_CC13_AUX_CBUCK2VDDB_OFF | PMU_CC13_AUX_CBUCK2VDDRET_OFF |
6745 		PMU_CC13_AUX_MEMLPLDO2VDDB_OFF | PMU_CC13_AUX_MEMLPLDO2VDDRET_OFF),
6746 		(PMU_CC13_AUX_MEMLPLDO2VDDB_OFF | PMU_CC13_AUX_MEMLPLDO2VDDRET_OFF));
6747 
6748 	/* PCIE retention mode enable */
6749 	si_pmu_chipcontrol(sih, PMU_CHIPCTL6,
6750 		PMU_CC6_ENABLE_PCIE_RETENTION, PMU_CC6_ENABLE_PCIE_RETENTION);
6751 }
6752 
6753 static void
BCMATTACHFN(si_set_lv_sleep_mode_4369)6754 BCMATTACHFN(si_set_lv_sleep_mode_4369)(si_t *sih, osl_t *osh)
6755 {
6756 	si_set_lv_sleep_mode_pmu(sih, osh);
6757 
6758 	si_set_lv_sleep_mode_lhl_config_4369(sih);
6759 
6760 	/* Enable PMU interrupts */
6761 	CHIPC_REG(sih, intmask, (1u << 4u), (1u << 4u));
6762 }
6763 
si_set_abuck_mode_4362(si_t * sih,uint8 mode)6764 void si_set_abuck_mode_4362(si_t *sih, uint8 mode)
6765 {
6766 
6767 	if (mode < 2 || mode > 4) {
6768 		ASSERT(0);
6769 		return;
6770 	}
6771 
6772 	si_pmu_vreg_control(sih, PMU_VREG_16, PMU_4362_VREG16_RSRC0_ABUCK_MODE_MASK,
6773 		mode << PMU_4362_VREG16_RSRC0_ABUCK_MODE_SHIFT);
6774 	si_pmu_vreg_control(sih, PMU_VREG_16, PMU_4362_VREG16_RSRC1_ABUCK_MODE_MASK,
6775 		mode << PMU_4362_VREG16_RSRC1_ABUCK_MODE_SHIFT);
6776 	si_pmu_vreg_control(sih, PMU_VREG_16, PMU_4362_VREG16_RSRC2_ABUCK_MODE_MASK,
6777 		mode << PMU_4362_VREG16_RSRC2_ABUCK_MODE_SHIFT);
6778 }
6779 
6780 static void
BCMATTACHFN(si_set_lv_sleep_mode_4378)6781 BCMATTACHFN(si_set_lv_sleep_mode_4378)(si_t *sih, osl_t *osh)
6782 {
6783 	si_set_lv_sleep_mode_pmu(sih, osh);
6784 
6785 	si_set_lv_sleep_mode_lhl_config_4378(sih);
6786 }
6787 
6788 static void
BCMATTACHFN(si_set_lv_sleep_mode_pmu_4387)6789 BCMATTACHFN(si_set_lv_sleep_mode_pmu_4387)(si_t *sih, osl_t *osh)
6790 {
6791 	/* Program pmu VREG resgiter for Resouce based ABUCK and CBUCK modes
6792 	 *      cbuck rsrc 0 - PWM and abuck rsrc 0 - Auto, rsrc 1 - PWM
6793 	 */
6794 	si_pmu_vreg_control(sih, PMU_VREG_16, PMU_4369_VREG16_RSRC1_ABUCK_MODE_MASK,
6795 		0x2u << PMU_4369_VREG16_RSRC1_ABUCK_MODE_SHIFT);
6796 
6797 	/* asr voltage adjust PWM - 0.8V */
6798 	si_pmu_vreg_control(sih, PMU_VREG_8, PMU_4369_VREG8_ASR_OVADJ_LPPFM_MASK,
6799 		0x10u << PMU_4369_VREG8_ASR_OVADJ_LPPFM_SHIFT);
6800 
6801 	/* Enable rsrc_en_asr_msk[0] and msk[1] */
6802 	si_pmu_vreg_control(sih, PMU_VREG_13, PMU_4369_VREG13_RSRC_EN0_ASR_MASK,
6803 		0x1u << PMU_4369_VREG13_RSRC_EN0_ASR_SHIFT);
6804 	si_pmu_vreg_control(sih, PMU_VREG_13, PMU_4369_VREG13_RSRC_EN1_ASR_MASK,
6805 		0x1u << PMU_4369_VREG13_RSRC_EN1_ASR_SHIFT);
6806 	si_pmu_vreg_control(sih, PMU_VREG_13, PMU_4369_VREG13_RSRC_EN2_ASR_MASK,
6807 		0x1u << PMU_4369_VREG13_RSRC_EN2_ASR_SHIFT);
6808 
6809 	si_pmu_vreg_control(sih, PMU_VREG_14, PMU_4369_VREG14_RSRC_EN_CSR_MASK0_MASK,
6810 		0x1u << PMU_4369_VREG14_RSRC_EN_CSR_MASK0_SHIFT);
6811 
6812 	/* disable force_hp_mode and enable wl_pmu_lv_mod */
6813 	si_pmu_vreg_control(sih, PMU_VREG_7,
6814 		(PMU_4369_VREG_7_WL_PMU_LV_MODE_MASK | PMU_4369_VREG_7_WL_PMU_LP_MODE_MASK |
6815 		PMU_4369_VREG_7_PMU_FORCE_HP_MODE_MASK), PMU_4369_VREG_7_WL_PMU_LV_MODE_MASK);
6816 
6817 	/* Enabale MEMLPLDO ( to enable 0x08)and BTLDO is enabled. At sleep RFLDO is disabled */
6818 	si_pmu_vreg_control(sih, PMU_VREG_6, PMU_4369_VREG_6_MEMLPLDO_POWER_UP_MASK,
6819 		0x1u << PMU_4369_VREG_6_MEMLPLDO_POWER_UP_SHIFT);
6820 
6821 	/* For 4387C0, we don't need memlpldo2vddret_on nor cldo2vddb_on.
6822 	 * We just need to clear the memlpldo2vddb_forceoff to turn on all the memlpldo2vddb pwrsw
6823 	 */
6824 	if (PMUREV(sih->pmurev) < 39) {
6825 		/* Program PMU chip cntrl register to control
6826 		 *     cbuck2vddb_pwrsw_force_on =1 and memlpldo2vddb_pwrsw_force_off = 1
6827 		 *     cbuck2ret_pwrsw_force_on = 1 and memlpldo2vddb_pwrsw_force_off = 1
6828 		 *     set d11_2x2_bw80_cbuck2vddb_pwrsw_force_on and
6829 		 *     d11_2x2_bw20_cbuck2vddb_pwrsw_force_on cbuck2ret_pwrsw on 4 cores
6830 		 */
6831 		si_pmu_chipcontrol(sih, PMU_CHIPCTL4,
6832 			(PMU_CC4_4369_MAIN_PD_CBUCK2VDDB_ON | PMU_CC4_4369_MAIN_PD_CBUCK2VDDRET_ON |
6833 			PMU_CC4_4369_MAIN_PD_MEMLPLDO2VDDB_ON |
6834 			PMU_CC4_4369_MAIN_PD_MEMLPDLO2VDDRET_ON),
6835 			(PMU_CC4_4369_MAIN_PD_CBUCK2VDDB_ON |
6836 			PMU_CC4_4369_MAIN_PD_CBUCK2VDDRET_ON));
6837 		si_pmu_chipcontrol(sih, PMU_CHIPCTL4,
6838 			(PMU_CC4_4369_AUX_PD_CBUCK2VDDB_ON | PMU_CC4_4369_AUX_PD_CBUCK2VDDRET_ON |
6839 			PMU_CC4_4369_AUX_PD_MEMLPLDO2VDDB_ON |
6840 			PMU_CC4_4369_AUX_PD_MEMLPLDO2VDDRET_ON),
6841 			(PMU_CC4_4369_AUX_PD_CBUCK2VDDB_ON | PMU_CC4_4369_AUX_PD_CBUCK2VDDRET_ON));
6842 
6843 		/* set subcore_cbuck2vddb_pwrsw_force_on */
6844 		si_pmu_chipcontrol(sih, PMU_CHIPCTL5,
6845 			(PMU_CC5_4369_SUBCORE_CBUCK2VDDB_ON | PMU_CC5_4369_SUBCORE_CBUCK2VDDRET_ON |
6846 			PMU_CC5_4369_SUBCORE_MEMLPLDO2VDDB_ON |
6847 			PMU_CC5_4369_SUBCORE_MEMLPLDO2VDDRET_ON),
6848 			(PMU_CC5_4369_SUBCORE_CBUCK2VDDB_ON |
6849 			PMU_CC5_4369_SUBCORE_CBUCK2VDDRET_ON));
6850 
6851 		/* Set subcore_memlpldo2vddb_pwrsw_force_off,
6852 		 * d11_2x2_bw80_memlpldo2vddb_pwrsw_force_off
6853 		 * and d11_2x2_bw20_memlpldo2vddb_pwrsw_force_off
6854 		 * Set subcore_memlpldo2vddret_pwrsw_force_off,
6855 		 * d11_2x2_bw80_memlpldo2vddret_pwrsw_force_off
6856 		 * and d11_2x2_bw20_memlpldo2vddret_pwrsw_force_off
6857 		 */
6858 		si_pmu_chipcontrol(sih, PMU_CHIPCTL13,
6859 			(PMU_CC13_SUBCORE_CBUCK2VDDB_OFF | PMU_CC13_SUBCORE_CBUCK2VDDRET_OFF |
6860 			PMU_CC13_SUBCORE_MEMLPLDO2VDDB_OFF | PMU_CC13_SUBCORE_MEMLPLDO2VDDRET_OFF),
6861 			(PMU_CC13_SUBCORE_MEMLPLDO2VDDB_OFF |
6862 			PMU_CC13_SUBCORE_MEMLPLDO2VDDRET_OFF));
6863 		si_pmu_chipcontrol(sih, PMU_CHIPCTL13,
6864 			(PMU_CC13_MAIN_CBUCK2VDDB_OFF | PMU_CC13_MAIN_CBUCK2VDDRET_OFF |
6865 			PMU_CC13_MAIN_MEMLPLDO2VDDB_OFF | PMU_CC13_MAIN_MEMLPLDO2VDDRET_OFF),
6866 			(PMU_CC13_MAIN_MEMLPLDO2VDDB_OFF | PMU_CC13_MAIN_MEMLPLDO2VDDRET_OFF));
6867 		si_pmu_chipcontrol(sih, PMU_CHIPCTL13,
6868 			(PMU_CC13_AUX_CBUCK2VDDB_OFF | PMU_CC13_AUX_CBUCK2VDDRET_OFF |
6869 			PMU_CC13_AUX_MEMLPLDO2VDDB_OFF | PMU_CC13_AUX_MEMLPLDO2VDDRET_OFF),
6870 			(PMU_CC13_AUX_MEMLPLDO2VDDB_OFF | PMU_CC13_AUX_MEMLPLDO2VDDRET_OFF));
6871 		si_pmu_chipcontrol(sih, PMU_CHIPCTL4,
6872 			PMU_CC4_4369_AUX_PD_MEMLPLDO2VDDRET_ON,
6873 			PMU_CC4_4369_AUX_PD_MEMLPLDO2VDDRET_ON);
6874 		si_pmu_chipcontrol(sih, PMU_CHIPCTL5,
6875 			PMU_CC5_4369_SUBCORE_MEMLPLDO2VDDRET_ON,
6876 			PMU_CC5_4369_SUBCORE_MEMLPLDO2VDDRET_ON),
6877 		si_pmu_chipcontrol(sih, PMU_CHIPCTL13,
6878 			PMU_CC13_SUBCORE_MEMLPLDO2VDDB_OFF |
6879 			PMU_CC13_SUBCORE_MEMLPLDO2VDDRET_OFF |
6880 			PMU_CC13_MAIN_MEMLPLDO2VDDB_OFF |
6881 			PMU_CC13_MAIN_MEMLPLDO2VDDRET_OFF |
6882 			PMU_CC13_AUX_MEMLPLDO2VDDB_OFF |
6883 			PMU_CC13_AUX_MEMLPLDO2VDDRET_OFF |
6884 			PMU_CC13_CMN_MEMLPLDO2VDDRET_ON,
6885 			PMU_CC13_SUBCORE_MEMLPLDO2VDDB_OFF |
6886 			PMU_CC13_MAIN_MEMLPLDO2VDDB_OFF |
6887 			PMU_CC13_MAIN_MEMLPLDO2VDDRET_OFF |
6888 			PMU_CC13_AUX_MEMLPLDO2VDDB_OFF |
6889 			PMU_CC13_CMN_MEMLPLDO2VDDRET_ON);
6890 		si_pmu_chipcontrol(sih, PMU_CHIPCTL17,
6891 			PMU_CC17_SCAN_MEMLPLDO2VDDRET_ON |
6892 			PMU_CC17_SCAN_CBUCK2VDDB_ON |
6893 			PMU_CC17_SCAN_MEMLPLDO2VDDRET_OFF,
6894 			PMU_CC17_SCAN_MEMLPLDO2VDDRET_ON |
6895 			PMU_CC17_SCAN_CBUCK2VDDB_ON);
6896 	} else {
6897 		si_pmu_chipcontrol(sih, PMU_CHIPCTL13,
6898 			PMU_CC13_CMN_MEMLPLDO2VDDRET_ON |
6899 			PMU_CC13_AUX_MEMLPLDO2VDDB_OFF |
6900 			PMU_CC13_MAIN_MEMLPLDO2VDDB_OFF |
6901 			PMU_CC13_SUBCORE_MEMLPLDO2VDDB_OFF,
6902 			PMU_CC13_CMN_MEMLPLDO2VDDRET_ON);
6903 		si_pmu_chipcontrol(sih, PMU_CHIPCTL17,
6904 			PMU_CC17_SCAN_MEMLPLDO2VDDB_OFF, 0);
6905 	}
6906 
6907 	/* PCIE retention mode enable */
6908 	si_pmu_chipcontrol(sih, PMU_CHIPCTL6,
6909 		PMU_CC6_ENABLE_PCIE_RETENTION, PMU_CC6_ENABLE_PCIE_RETENTION);
6910 
6911 	/* H/W JIRA http://jira.broadcom.com/browse/HW4387-825
6912 	 * B0 only, the h/w bug is fixed in C0
6913 	 */
6914 	if (PMUREV(sih->pmurev) == 38) {
6915 		si_pmu_vreg_control(sih, PMU_VREG_14,
6916 			PMU_VREG14_RSRC_EN_ASR_PWM_PFM_MASK,
6917 			PMU_VREG14_RSRC_EN_ASR_PWM_PFM_MASK);
6918 	}
6919 
6920 	/* WAR for jira HW4387-922 */
6921 	si_pmu_vreg_control(sih, PMU_VREG_1,
6922 		PMU_4387_VREG1_CSR_OVERI_DIS_MASK,
6923 		PMU_4387_VREG1_CSR_OVERI_DIS_MASK);
6924 
6925 	/* Clear Misc_LDO override */
6926 	si_pmu_vreg_control(sih, PMU_VREG_5, VREG5_4387_MISCLDO_PU_MASK, 0);
6927 
6928 	si_pmu_vreg_control(sih, PMU_VREG_8,
6929 		PMU_4387_VREG8_ASR_OVERI_DIS_MASK,
6930 		PMU_4387_VREG8_ASR_OVERI_DIS_MASK);
6931 
6932 	if (BCMSRTOPOFF_ENAB()) {
6933 		si_pmu_vreg_control(sih, PMU_VREG_6,
6934 			PMU_4387_VREG6_WL_PMU_LV_MODE_MASK, 0);
6935 
6936 		/* Clear memldo_pu bit as 4387 doesn't plan to use MEMLDO */
6937 		si_pmu_vreg_control(sih, PMU_VREG_6,
6938 			PMU_4387_VREG6_MEMLDO_PU_MASK, 0);
6939 	} else {
6940 		si_pmu_vreg_control(sih, PMU_VREG_6,
6941 			PMU_4387_VREG6_WL_PMU_LV_MODE_MASK,
6942 			PMU_4387_VREG6_WL_PMU_LV_MODE_MASK);
6943 	}
6944 }
6945 
6946 static void
BCMATTACHFN(si_set_lv_sleep_mode_4387)6947 BCMATTACHFN(si_set_lv_sleep_mode_4387)(si_t *sih, osl_t *osh)
6948 {
6949 	si_set_lv_sleep_mode_pmu_4387(sih, osh);
6950 	si_set_lv_sleep_mode_lhl_config_4387(sih);
6951 }
6952 
6953 static void
BCMATTACHFN(si_set_lv_sleep_mode_4389)6954 BCMATTACHFN(si_set_lv_sleep_mode_4389)(si_t *sih, osl_t *osh)
6955 {
6956 	si_set_lv_sleep_mode_pmu(sih, osh);
6957 
6958 	si_pmu_chipcontrol(sih, PMU_CHIPCTL4,
6959 		PMU_CC4_4387_MAIN_PD_CBUCK2VDDRET_ON |
6960 		PMU_CC4_4387_AUX_PD_CBUCK2VDDRET_ON,
6961 		0);
6962 	si_pmu_chipcontrol(sih, PMU_CHIPCTL5,
6963 		PMU_CC5_4387_SUBCORE_CBUCK2VDDRET_ON,
6964 		0);
6965 	si_pmu_chipcontrol(sih, PMU_CHIPCTL6,
6966 		PMU_CC6_RX4_CLK_SEQ_SELECT_MASK,
6967 		0);
6968 	/* Disable lq_clk - HW4387-254 */
6969 	si_pmu_chipcontrol(sih, PMU_CHIPCTL12,
6970 		PMU_CC12_DISABLE_LQ_CLK_ON,
6971 		PMU_CC12_DISABLE_LQ_CLK_ON);
6972 	si_pmu_chipcontrol(sih, PMU_CHIPCTL13,
6973 		PMU_CC13_SUBCORE_MEMLPLDO2VDDRET_OFF |
6974 		PMU_CC13_MAIN_MEMLPLDO2VDDRET_OFF |
6975 		PMU_CC13_AUX_MEMLPLDO2VDDRET_OFF,
6976 		0);
6977 
6978 #ifdef NOT_YET
6979 	/* FIXME: this setting is causing the load switch from CSR to ASR */
6980 	si_pmu_chipcontrol(sih, PMU_CHIPCTL13,
6981 		PMU_CC13_SUBCORE_MEMLPLDO2VDDB_OFF |
6982 		PMU_CC13_SUBCORE_MEMLPLDO2VDDRET_OFF |
6983 		PMU_CC13_MAIN_MEMLPLDO2VDDB_OFF |
6984 		PMU_CC13_MAIN_MEMLPLDO2VDDRET_OFF |
6985 		PMU_CC13_AUX_MEMLPLDO2VDDB_OFF |
6986 		PMU_CC13_AUX_MEMLPLDO2VDDRET_OFF |
6987 		PMU_CC13_CMN_MEMLPLDO2VDDRET_ON, 0);
6988 #endif /* NOT_YET */
6989 
6990 	si_pmu_chipcontrol(sih, PMU_CHIPCTL17,
6991 		PMU_CC17_SCAN_MEMLPLDO2VDDRET_ON |
6992 		PMU_CC17_SCAN_CBUCK2VDDB_ON |
6993 		PMU_CC17_SCAN_MEMLPLDO2VDDRET_OFF,
6994 		PMU_CC17_SCAN_MEMLPLDO2VDDRET_ON |
6995 		PMU_CC17_SCAN_CBUCK2VDDB_ON);
6996 
6997 	si_set_lv_sleep_mode_lhl_config_4389(sih);
6998 
6999 	si_pmu_vreg_control(sih, PMU_VREG_6,
7000 		(PMU_4389_VREG6_WL_PMU_LV_MODE_MASK | PMU_4389_VREG6_MEMLDO_PU_MASK),
7001 		PMU_4389_VREG6_WL_PMU_LV_MODE_MASK);
7002 
7003 	/* SW WAR for 4389B0(rev 01) issue - HW4387-922. 4389C0(rev 02) already has HW fix */
7004 	if (CHIPREV(sih->chiprev) == 1) {
7005 		si_pmu_vreg_control(sih, PMU_VREG_1,
7006 			PMU_4387_VREG1_CSR_OVERI_DIS_MASK,
7007 			PMU_4387_VREG1_CSR_OVERI_DIS_MASK);
7008 
7009 		si_pmu_vreg_control(sih, PMU_VREG_8,
7010 			PMU_4387_VREG8_ASR_OVERI_DIS_MASK,
7011 			PMU_4387_VREG8_ASR_OVERI_DIS_MASK);
7012 	}
7013 }
7014 
7015 static void
BCMATTACHFN(si_set_lv_sleep_mode_4362)7016 BCMATTACHFN(si_set_lv_sleep_mode_4362)(si_t *sih, osl_t *osh)
7017 {
7018 	/* Program pmu VREG resgiter for Resouce based ABUCK and CBUCK modes
7019 	 *      cbuck rsrc 0 - PWM and abuck rsrc 0 - Auto, rsrc 1 - PWM
7020 	 */
7021 	si_pmu_vreg_control(sih, PMU_VREG_16, PMU_4362_VREG16_RSRC0_CBUCK_MODE_MASK,
7022 		0x3u << PMU_4362_VREG16_RSRC0_CBUCK_MODE_SHIFT);
7023 
7024 	si_set_abuck_mode_4362(sih, 0x3u);
7025 
7026 	/* asr voltage adjust PWM - 0.8V */
7027 	si_pmu_vreg_control(sih, PMU_VREG_8, PMU_4362_VREG8_ASR_OVADJ_LPPFM_MASK,
7028 		0x10u << PMU_4362_VREG8_ASR_OVADJ_LPPFM_SHIFT);
7029 
7030 	/* Enable rsrc_en_asr_msk[0] and msk[1] */
7031 	si_pmu_vreg_control(sih, PMU_VREG_13, PMU_4362_VREG13_RSRC_EN0_ASR_MASK,
7032 		0x1u << PMU_4362_VREG13_RSRC_EN0_ASR_SHIFT);
7033 	si_pmu_vreg_control(sih, PMU_VREG_13, PMU_4362_VREG13_RSRC_EN1_ASR_MASK,
7034 		0x1u << PMU_4362_VREG13_RSRC_EN1_ASR_SHIFT);
7035 	si_pmu_vreg_control(sih, PMU_VREG_13, PMU_4362_VREG13_RSRC_EN2_ASR_MASK,
7036 		0x1u << PMU_4362_VREG13_RSRC_EN2_ASR_SHIFT);
7037 
7038 	si_pmu_vreg_control(sih, PMU_VREG_14, PMU_4362_VREG14_RSRC_EN_CSR_MASK0_MASK,
7039 		0x1u << PMU_4362_VREG14_RSRC_EN_CSR_MASK0_SHIFT);
7040 
7041 	/* disable force_hp_mode and enable wl_pmu_lv_mod */
7042 	si_pmu_vreg_control(sih, PMU_VREG_7,
7043 		(PMU_4362_VREG_7_WL_PMU_LV_MODE_MASK | PMU_4362_VREG_7_WL_PMU_LP_MODE_MASK |
7044 		PMU_4362_VREG_7_PMU_FORCE_HP_MODE_MASK), PMU_4362_VREG_7_WL_PMU_LV_MODE_MASK);
7045 
7046 	/* Enable MISCLDO, MEMLPLDO_adj -0.7V, Disable LPLDO power up */
7047 	si_pmu_vreg_control(sih, PMU_VREG_5, PMU_4362_VREG_5_MISCLDO_POWER_UP_MASK,
7048 		0x1u << PMU_4362_VREG_5_MISCLDO_POWER_UP_SHIFT);
7049 	si_pmu_vreg_control(sih, PMU_VREG_5, PMU_4362_VREG_5_LPLDO_POWER_UP_MASK, 0x0u);
7050 	si_pmu_vreg_control(sih, PMU_VREG_5, PMU_4362_VREG_5_MEMLPLDO_OP_VLT_ADJ_CTRL_MASK,
7051 		0xBu << PMU_4362_VREG_5_MEMLPLDO_OP_VLT_ADJ_CTRL_SHIFT);
7052 
7053 	/* Enabale MEMLPLDO ( to enable 0x08)and BTLDO is enabled. At sleep RFLDO is disabled */
7054 	si_pmu_vreg_control(sih, PMU_VREG_6, PMU_4362_VREG_6_MEMLPLDO_POWER_UP_MASK,
7055 		0x1u << PMU_4362_VREG_6_MEMLPLDO_POWER_UP_SHIFT);
7056 
7057 	/* Program PMU chip cntrl register to control
7058 	 *     cbuck2vddb_pwrsw_force_on =1 and memlpldo2vddb_pwrsw_force_off = 1
7059 	 *     cbuck2ret_pwrsw_force_on = 1 and memlpldo2vddb_pwrsw_force_off = 1
7060 	 *     set d11_2x2_bw80_cbuck2vddb_pwrsw_force_on and
7061 	 *     d11_2x2_bw20_cbuck2vddb_pwrsw_force_on cbuck2ret_pwrsw on 4 cores
7062 	 */
7063 	si_pmu_chipcontrol(sih, PMU_CHIPCTL4,
7064 		(PMU_CC4_4362_PD_CBUCK2VDDB_ON | PMU_CC4_4362_PD_CBUCK2VDDRET_ON |
7065 		PMU_CC4_4362_PD_MEMLPLDO2VDDB_ON | PMU_CC4_4362_PD_MEMLPDLO2VDDRET_ON),
7066 		(PMU_CC4_4362_PD_CBUCK2VDDB_ON | PMU_CC4_4362_PD_CBUCK2VDDRET_ON));
7067 
7068 	/* set subcore_cbuck2vddb_pwrsw_force_on */
7069 	si_pmu_chipcontrol(sih, PMU_CHIPCTL5,
7070 		(PMU_CC5_4362_SUBCORE_CBUCK2VDDB_ON | PMU_CC5_4362_SUBCORE_CBUCK2VDDRET_ON |
7071 		PMU_CC5_4362_SUBCORE_MEMLPLDO2VDDB_ON | PMU_CC5_4362_SUBCORE_MEMLPLDO2VDDRET_ON),
7072 		(PMU_CC5_4362_SUBCORE_CBUCK2VDDB_ON | PMU_CC5_4362_SUBCORE_CBUCK2VDDRET_ON));
7073 
7074 	/* Set subcore_memlpldo2vddb_pwrsw_force_off, d11_2x2_bw80_memlpldo2vddb_pwrsw_force_off
7075 	 * and d11_2x2_bw20_memlpldo2vddb_pwrsw_force_off
7076 	 * Set subcore_memlpldo2vddret_pwrsw_force_off,d11_2x2_bw80_memlpldo2vddret_pwrsw_force_off
7077 	 * and d11_2x2_bw20_memlpldo2vddret_pwrsw_force_off
7078 	 */
7079 	si_pmu_chipcontrol(sih, PMU_CHIPCTL13,
7080 		(PMU_CC13_SUBCORE_CBUCK2VDDB_OFF | PMU_CC13_SUBCORE_CBUCK2VDDRET_OFF |
7081 		PMU_CC13_SUBCORE_MEMLPLDO2VDDB_OFF | PMU_CC13_SUBCORE_MEMLPLDO2VDDRET_OFF),
7082 		(PMU_CC13_SUBCORE_MEMLPLDO2VDDB_OFF | PMU_CC13_SUBCORE_MEMLPLDO2VDDRET_OFF));
7083 	si_pmu_chipcontrol(sih, PMU_CHIPCTL13,
7084 		(PMU_CC13_MAIN_CBUCK2VDDB_OFF | PMU_CC13_MAIN_CBUCK2VDDB_OFF |
7085 		PMU_CC13_MAIN_MEMLPLDO2VDDB_OFF | PMU_CC13_MAIN_MEMLPLDO2VDDRET_OFF),
7086 		(PMU_CC13_MAIN_MEMLPLDO2VDDB_OFF | PMU_CC13_MAIN_MEMLPLDO2VDDRET_OFF));
7087 
7088 	/* PCIE retention mode enable */
7089 	si_pmu_chipcontrol(sih, PMU_CHIPCTL6,
7090 		PMU_CC6_ENABLE_PCIE_RETENTION, PMU_CC6_ENABLE_PCIE_RETENTION);
7091 
7092 	si_set_lv_sleep_mode_lhl_config_4362(sih);
7093 
7094 	/* Enable PMU interrupts */
7095 	CHIPC_REG(sih, intmask, (1u << 4u), (1u << 4u));
7096 }
7097 
7098 void
BCMATTACHFN(si_pmu_fis_setup)7099 BCMATTACHFN(si_pmu_fis_setup)(si_t *sih)
7100 {
7101 	uint origidx;
7102 	pmuregs_t *pmu;
7103 	int val;
7104 	osl_t *osh = si_osh(sih);
7105 
7106 	origidx = si_coreidx(sih);
7107 	if (AOB_ENAB(sih)) {
7108 		pmu = si_setcore(sih, PMU_CORE_ID, 0);
7109 	} else {
7110 		pmu = si_setcoreidx(sih, SI_CC_IDX);
7111 	}
7112 	ASSERT(pmu != NULL);
7113 
7114 	switch (CHIPID(sih->chip)) {
7115 	case BCM4376_CHIP_GRPID:
7116 	case BCM4378_CHIP_GRPID:
7117 		val = R_REG(osh, &pmu->max_res_mask);
7118 		W_REG(osh, &pmu->fis_start_min_res_mask, val);
7119 
7120 		val = R_REG(osh, &pmu->min_res_mask);
7121 		W_REG(osh, &pmu->fis_min_res_mask, val);
7122 
7123 		W_REG(osh, &pmu->fis_ctrl_status,
7124 			(PMU_FIS_DN_TIMER_VAL_4378 << PMU_FIS_DN_TIMER_VAL_SHIFT)
7125 			& PMU_FIS_DN_TIMER_VAL_MASK);
7126 		break;
7127 	case BCM4388_CHIP_GRPID:
7128 		val = R_REG(osh, &pmu->max_res_mask);
7129 		W_REG(osh, &pmu->fis_start_min_res_mask, val);
7130 
7131 		val = R_REG(osh, &pmu->min_res_mask);
7132 		W_REG(osh, &pmu->fis_min_res_mask, val);
7133 
7134 		W_REG(osh, &pmu->fis_ctrl_status,
7135 			((PMU_FIS_DN_TIMER_VAL_4388 << PMU_FIS_DN_TIMER_VAL_SHIFT)
7136 			 & PMU_FIS_DN_TIMER_VAL_MASK) | PMU_FIS_PCIE_SAVE_EN_VALUE);
7137 		break;
7138 	case BCM4389_CHIP_GRPID:
7139 		val = R_REG(osh, &pmu->max_res_mask);
7140 		W_REG(osh, &pmu->fis_start_min_res_mask, val);
7141 
7142 		val = R_REG(osh, &pmu->min_res_mask);
7143 		W_REG(osh, &pmu->fis_min_res_mask, val);
7144 
7145 		W_REG(osh, &pmu->fis_ctrl_status,
7146 			((PMU_FIS_DN_TIMER_VAL_4389 << PMU_FIS_DN_TIMER_VAL_SHIFT)
7147 			 & PMU_FIS_DN_TIMER_VAL_MASK) | PMU_FIS_PCIE_SAVE_EN_VALUE);
7148 		break;
7149 
7150 	default:
7151 		break;
7152 	}
7153 	si_setcoreidx(sih, origidx);
7154 }
7155 #endif /* defined(SAVERESTORE) */
7156 
7157 /*
7158  * Enable: Dynamic Clk Switching
7159  * Disable: Mirrored Mode
7160  * use nvram to enable
7161  */
7162 static void
BCMATTACHFN(si_pmu_dynamic_clk_switch_enab)7163 BCMATTACHFN(si_pmu_dynamic_clk_switch_enab)(si_t *sih)
7164 {
7165 	if (PMUREV(sih->pmurev) >= 36) {
7166 		if (getintvar(NULL, rstr_dyn_clksw_en)) {
7167 			PMU_REG(sih, pmucontrol_ext,
7168 				PCTL_EXT_REQ_MIRROR_ENAB, 0);
7169 			si_pmu_chipcontrol(sih, PMU_CHIPCTL2,
7170 				CC2_4378_USE_WLAN_BP_CLK_ON_REQ_MASK |
7171 				CC2_4378_USE_CMN_BP_CLK_ON_REQ_MASK,
7172 				0);
7173 		}
7174 	}
7175 }
7176 
7177 /* use pmu rsrc XTAL_PU to count deep sleep of chip */
7178 static void
BCMATTACHFN(si_pmu_enb_slp_cnt_on_rsrc)7179 BCMATTACHFN(si_pmu_enb_slp_cnt_on_rsrc)(si_t *sih, osl_t *osh)
7180 {
7181 	uint origidx;
7182 	pmuregs_t *pmu;
7183 	uint32 rsrc_slp = 0xffffffff;
7184 
7185 	origidx = si_coreidx(sih);
7186 	if (AOB_ENAB(sih)) {
7187 		pmu = si_setcore(sih, PMU_CORE_ID, 0);
7188 	} else {
7189 		pmu = si_setcoreidx(sih, SI_CC_IDX);
7190 	}
7191 	ASSERT(pmu != NULL);
7192 
7193 	switch (CHIPID(sih->chip)) {
7194 
7195 	case BCM4376_CHIP_GRPID:
7196 	case BCM4378_CHIP_GRPID:
7197 		rsrc_slp = RES4378_XTAL_PU;
7198 		break;
7199 
7200 	case BCM4385_CHIP_GRPID:
7201 	case BCM4387_CHIP_GRPID:
7202 		rsrc_slp = RES4387_XTAL_PU;
7203 		break;
7204 
7205 	case BCM4388_CHIP_GRPID:
7206 	case BCM4389_CHIP_GRPID:
7207 	case BCM4397_CHIP_GRPID:
7208 		rsrc_slp = RES4389_XTAL_PU;
7209 		break;
7210 
7211 	default:
7212 		break;
7213 	}
7214 
7215 	if (rsrc_slp != 0xffffffff) {
7216 		W_REG(osh, &pmu->rsrc_event0, PMURES_BIT(rsrc_slp));
7217 	}
7218 
7219 	si_setcoreidx(sih, origidx);
7220 }
7221 
7222 #define MISC_LDO_STEPPING_DELAY	(150u)	/* 150 us, includes 50us additional margin */
7223 
7224 /** initialize PMU chip controls and other chip level stuff */
7225 void
BCMATTACHFN(si_pmu_chip_init)7226 BCMATTACHFN(si_pmu_chip_init)(si_t *sih, osl_t *osh)
7227 {
7228 	ASSERT(sih->cccaps & CC_CAP_PMU);
7229 	if (AOB_ENAB(sih)) {
7230 		if (hnd_pmur == NULL) {
7231 			uint coreidx = si_coreidx(sih);
7232 			hnd_pmur = si_setcore(sih, PMU_CORE_ID, 0);
7233 			ASSERT(hnd_pmur != NULL);
7234 			/* Restore to CC */
7235 			si_setcoreidx(sih, coreidx);
7236 		}
7237 	}
7238 
7239 	si_pmu_otp_chipcontrol(sih, osh);
7240 
7241 #ifdef CHIPC_UART_ALWAYS_ON
7242 	si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, clk_ctl_st), CCS_FORCEALP, CCS_FORCEALP);
7243 #endif /* CHIPC_UART_ALWAYS_ON */
7244 
7245 	si_pmu_enb_slp_cnt_on_rsrc(sih, osh);
7246 
7247 	/* Misc. chip control, has nothing to do with PMU */
7248 	switch (CHIPID(sih->chip)) {
7249 
7250 	case BCM43012_CHIP_ID:
7251 	case BCM43013_CHIP_ID:
7252 	case BCM43014_CHIP_ID:
7253 	{
7254 #ifdef USE_LHL_TIMER
7255 		si_pmu_chipcontrol(sih, PMU_CHIPCTL2, PMUCCTL02_43012_LHL_TIMER_SELECT,
7256 			PMUCCTL02_43012_LHL_TIMER_SELECT);
7257 #else
7258 		si_pmu_chipcontrol(sih, PMU_CHIPCTL2, PMUCCTL02_43012_LHL_TIMER_SELECT, 0);
7259 #endif /* USE_LHL_TIMER */
7260 
7261 		si_pmu_chipcontrol(sih, PMU_CHIPCTL2, PMUCCTL02_43012_RFLDO3P3_PU_FORCE_ON, 0);
7262 		si_pmu_chipcontrol(sih, PMU_CHIPCTL4, PMUCCTL14_43012_DISABLE_LQ_AVAIL, 0);
7263 
7264 		PMU_REG_NEW(sih, extwakemask0,
7265 				PMU_EXT_WAKE_MASK_0_SDIO, PMU_EXT_WAKE_MASK_0_SDIO);
7266 		PMU_REG_NEW(sih, extwakereqmask[0], ~0, si_pmu_rsrc_ht_avail_clk_deps(sih, osh));
7267 
7268 		if (sih->lpflags & LPFLAGS_SI_FORCE_PWM_WHEN_RADIO_ON) {
7269 			/* Force PWM when Radio ON */
7270 			/* 2G_Listen/2G_RX/2G_TX/5G_Listen/5G_RX/5G_TX = PWM */
7271 			si_pmu_vreg_control(sih, PMU_VREG_8,
7272 				PMU_43012_VREG8_DYNAMIC_CBUCK_MODE_MASK,
7273 				PMU_43012_VREG8_DYNAMIC_CBUCK_MODE0);
7274 			si_pmu_vreg_control(sih, PMU_VREG_9,
7275 				PMU_43012_VREG9_DYNAMIC_CBUCK_MODE_MASK,
7276 				PMU_43012_VREG9_DYNAMIC_CBUCK_MODE0);
7277 		}
7278 		else {
7279 			/* LPPFM opt setting for ePA */
7280 			si_pmu_chipcontrol(sih, PMU_CHIPCTL16, PMU_CC16_CLK4M_DIS, 1);
7281 			si_pmu_chipcontrol(sih, PMU_CHIPCTL16, PMU_CC16_FF_ZERO_ADJ, 4);
7282 			/* 2G_Listen/2G_RX = LPPFM, 2G_TX/5G_Listen/5G_RX/5G_TX = PWM */
7283 			si_pmu_vreg_control(sih, PMU_VREG_8,
7284 				PMU_43012_VREG8_DYNAMIC_CBUCK_MODE_MASK,
7285 				PMU_43012_VREG8_DYNAMIC_CBUCK_MODE1);
7286 			si_pmu_vreg_control(sih, PMU_VREG_9,
7287 				PMU_43012_VREG9_DYNAMIC_CBUCK_MODE_MASK,
7288 				PMU_43012_VREG9_DYNAMIC_CBUCK_MODE1);
7289 		}
7290 		/* Set external LPO */
7291 		si_lhl_set_lpoclk(sih, osh, LHL_LPO_AUTO);
7292 
7293 		/* Enabling WL2CDIG sleep */
7294 		si_pmu_chipcontrol(sih, PMU_CHIPCTL2, PMUCCTL02_43012_WL2CDIG_I_PMU_SLEEP_ENAB,
7295 			PMUCCTL02_43012_WL2CDIG_I_PMU_SLEEP_ENAB);
7296 
7297 		si_pmu_chipcontrol(sih, PMU_CHIPCTL9,
7298 			PMUCCTL09_43012_XTAL_CORESIZE_BIAS_ADJ_STARTUP_MASK,
7299 			PMUCCTL09_43012_XTAL_CORESIZE_BIAS_ADJ_STARTUP_VAL <<
7300 				PMUCCTL09_43012_XTAL_CORESIZE_BIAS_ADJ_STARTUP_SHIFT);
7301 
7302 		/* Setting MemLPLDO voltage to 0.74 */
7303 		si_pmu_vreg_control(sih, PMU_VREG_6, VREG6_43012_MEMLPLDO_ADJ_MASK,
7304 			0x8 << VREG6_43012_MEMLPLDO_ADJ_SHIFT);
7305 
7306 		/* Setting LPLDO voltage to 0.8 */
7307 		si_pmu_vreg_control(sih, PMU_VREG_6, VREG6_43012_LPLDO_ADJ_MASK,
7308 			0xB << VREG6_43012_LPLDO_ADJ_SHIFT);
7309 
7310 		/* Turn off power switch 1P8 in sleep */
7311 		si_pmu_vreg_control(sih, PMU_VREG_7, VREG7_43012_PWRSW_1P8_PU_MASK, 0);
7312 
7313 		/* Enable PMU sleep mode0 (DS0-PS0) */
7314 		LHL_REG(sih, lhl_top_pwrseq_ctl_adr, ~0, PMU_SLEEP_MODE_0);
7315 
7316 		si_pmu_fast_lpo_enable(sih, osh);
7317 
7318 		/* Enable the 'power kill' (power off selected retention memories) */
7319 		GCI_REG_NEW(sih, bt_smem_control0, GCI_BT_SMEM_CTRL0_SUBCORE_ENABLE_PKILL,
7320 			GCI_BT_SMEM_CTRL0_SUBCORE_ENABLE_PKILL);
7321 
7322 		break;
7323 	}
7324 	case BCM4362_CHIP_GRPID:
7325 	{
7326 		pmuregs_t *pmu = si_setcore(sih, PMU_CORE_ID, 0);
7327 		uint32 lpo = LHL_LPO_AUTO;
7328 		uint32 lhl_tmr_sel = 0;
7329 
7330 		/* DMAHANG WAR:SWWLAN:171729
7331 		 * Stretch the ALP and HT clocks after de-asserting
7332 		 * the request. During the RX frame transfer from RXFIFO to
7333 		 * DP FIFO, in certain cases the clock is getting de-asserted
7334 		 * by ucode as it does not have visibility beyond BM
7335 		 */
7336 		W_REG(osh, &pmu->clkstretch, 0x0fff0fff);
7337 
7338 #ifdef USE_LHL_TIMER
7339 		lhl_tmr_sel = PMU_CC13_LHL_TIMER_SELECT;
7340 #endif /* USE_LHL_TIMER */
7341 		si_pmu_chipcontrol(sih, PMU_CHIPCTL13, PMU_CC13_LHL_TIMER_SELECT, lhl_tmr_sel);
7342 
7343 		if (R_REG(osh, &pmu->pmustatus) & PST_EXTLPOAVAIL) {
7344 			lpo = LHL_EXT_LPO_ENAB;
7345 		}
7346 
7347 		if (!ISSIM_ENAB(sih)) {
7348 			si_lhl_set_lpoclk(sih, osh, lpo);
7349 		}
7350 
7351 		if (getintvar(NULL, rstr_btldo3p3pu)) {
7352 			si_pmu_regcontrol(sih, 4,
7353 				PMU_28NM_VREG4_WL_LDO_CNTL_EN,
7354 				PMU_28NM_VREG4_WL_LDO_CNTL_EN);
7355 			si_pmu_regcontrol(sih, 6,
7356 				PMU_28NM_VREG6_BTLDO3P3_PU,
7357 				PMU_28NM_VREG6_BTLDO3P3_PU);
7358 		}
7359 
7360 		/* write the XTAL preferred startup/normal A0/B0 revision */
7361 		si_pmu_chipcontrol_xtal_settings_4362(sih);
7362 
7363 		si_pmu_chipcontrol(sih, PMU_CHIPCTL6,
7364 			(PMU_CC6_ENABLE_CLKREQ_WAKEUP | PMU_CC6_ENABLE_PCIE_RETENTION),
7365 			(PMU_CC6_ENABLE_CLKREQ_WAKEUP | PMU_CC6_ENABLE_PCIE_RETENTION));
7366 
7367 		si_pmu_vreg_control(sih, PMU_VREG_8, PMU_4362_VREG8_ASR_OVADJ_LPPFM_MASK,
7368 			0x02u << PMU_4362_VREG8_ASR_OVADJ_LPPFM_SHIFT);
7369 		si_pmu_vreg_control(sih, PMU_VREG_8, PMU_4362_VREG8_ASR_OVADJ_PFM_MASK,
7370 			0x02u << PMU_4362_VREG8_ASR_OVADJ_PFM_SHIFT);
7371 		si_pmu_vreg_control(sih, PMU_VREG_8, PMU_4362_VREG8_ASR_OVADJ_PWM_MASK,
7372 			0x02u << PMU_4362_VREG8_ASR_OVADJ_PWM_SHIFT);
7373 #if defined(SAVERESTORE)
7374 		if (SR_ENAB()) {
7375 			si_set_lv_sleep_mode_4362(sih, osh);
7376 		}
7377 #endif /* SAVERESTORE */
7378 
7379 		si_pmu_fast_lpo_enable(sih, osh);
7380 		if ((PMUREV(sih->pmurev) >= 33) && FASTLPO_ENAB()) {
7381 			/* Enabling FAST_SEQ */
7382 			uint8	fastlpo_dis = fastlpo_dis_get();
7383 			uint8	fastlpo_pcie_dis = fastlpo_pcie_dis_get();
7384 			if (!fastlpo_dis || !fastlpo_pcie_dis) {
7385 				PMU_REG(sih, pmucontrol_ext, PCTL_EXT_FASTSEQ_ENAB,
7386 					PCTL_EXT_FASTSEQ_ENAB);
7387 			}
7388 		}
7389 
7390 		break;
7391 	}
7392 
7393 	case BCM4369_CHIP_GRPID:
7394 	{
7395 		pmuregs_t *pmu = si_setcore(sih, PMU_CORE_ID, 0);
7396 		uint32 lpo = LHL_LPO_AUTO;
7397 		uint32 lhl_tmr_sel = 0;
7398 
7399 		/* DMAHANG WAR:SWWLAN:171729
7400 		 * Stretch the ALP and HT clocks after de-asserting
7401 		 * the request. During the RX frame transfer from RXFIFO to
7402 		 * DP FIFO, in certain cases the clock is getting de-asserted
7403 		 * by ucode as it does not have visibility beyond BM
7404 		 */
7405 #ifndef ATE_BUILD
7406 		W_REG(osh, &pmu->clkstretch, 0x0fff0fff);
7407 #endif
7408 
7409 #ifdef USE_LHL_TIMER
7410 		lhl_tmr_sel = PMU_CC13_4369_LHL_TIMER_SELECT;
7411 #endif
7412 		si_pmu_chipcontrol(sih, PMU_CHIPCTL13, PMU_CC13_4369_LHL_TIMER_SELECT, lhl_tmr_sel);
7413 
7414 		if (R_REG(osh, &pmu->pmustatus) & PST_EXTLPOAVAIL) {
7415 			lpo = LHL_EXT_LPO_ENAB;
7416 		}
7417 
7418 		if (!ISSIM_ENAB(sih)) {
7419 			si_lhl_set_lpoclk(sih, osh, lpo);
7420 		}
7421 
7422 		if (getintvar(NULL, rstr_btldo3p3pu)) {
7423 			si_pmu_regcontrol(sih, 4,
7424 				PMU_28NM_VREG4_WL_LDO_CNTL_EN,
7425 				PMU_28NM_VREG4_WL_LDO_CNTL_EN);
7426 			si_pmu_regcontrol(sih, 6,
7427 				PMU_28NM_VREG6_BTLDO3P3_PU,
7428 				PMU_28NM_VREG6_BTLDO3P3_PU);
7429 		}
7430 
7431 		/* write the XTAL preferred startup/normal A0/B0 revision */
7432 		si_pmu_chipcontrol_xtal_settings_4369(sih);
7433 
7434 		si_pmu_chipcontrol(sih, PMU_CHIPCTL6,
7435 			(PMU_CC6_ENABLE_CLKREQ_WAKEUP | PMU_CC6_ENABLE_PCIE_RETENTION),
7436 			(PMU_CC6_ENABLE_CLKREQ_WAKEUP | PMU_CC6_ENABLE_PCIE_RETENTION));
7437 
7438 		/* write the PWRSW CLK start/stop delay only for A0 revision */
7439 		if (CHIPREV(sih->chiprev) == 0) {
7440 			si_pmu_chipcontrol(sih, PMU_CHIPCTL1, PMU_CC1_PWRSW_CLKSTRSTP_DELAY_MASK,
7441 				PMU_CC1_PWRSW_CLKSTRSTP_DELAY);
7442 		}
7443 
7444 #if defined(SAVERESTORE)
7445 		if (SR_ENAB()) {
7446 			si_set_lv_sleep_mode_4369(sih, osh);
7447 		}
7448 #endif /* SAVERESTORE */
7449 
7450 		si_pmu_fast_lpo_enable(sih, osh);
7451 #ifdef BCM_LDO3P3_SOFTSTART
7452 		if (CHIPID(sih->chip) != BCM4377_CHIP_ID) {
7453 			si_pmu_ldo3p3_soft_start_wl_set(sih, osh, 3);
7454 		}
7455 #endif
7456 		if ((PMUREV(sih->pmurev) >= 33) && FASTLPO_ENAB()) {
7457 			/* Enabling FAST_SEQ */
7458 			uint8	fastlpo_dis = fastlpo_dis_get();
7459 			uint8	fastlpo_pcie_dis = fastlpo_pcie_dis_get();
7460 			if (!fastlpo_dis || !fastlpo_pcie_dis) {
7461 				PMU_REG(sih, pmucontrol_ext, PCTL_EXT_FASTSEQ_ENAB,
7462 					PCTL_EXT_FASTSEQ_ENAB);
7463 			}
7464 		}
7465 
7466 		break;
7467 	}
7468 
7469 	CASE_BCM43602_CHIP: /* fall through */
7470 		/* Set internal/external LPO */
7471 		si_pmu_set_lpoclk(sih, osh);
7472 		break;
7473 
7474 	case BCM4376_CHIP_GRPID:
7475 	case BCM4378_CHIP_GRPID:
7476 	{
7477 		pmuregs_t *pmu = si_setcore(sih, PMU_CORE_ID, 0);
7478 		uint32 lpo = LHL_LPO_AUTO;
7479 		uint32 lhl_tmr_sel = 0;
7480 
7481 #ifdef USE_LHL_TIMER
7482 		lhl_tmr_sel = PMU_CC13_4378_LHL_TIMER_SELECT;
7483 #endif
7484 		si_pmu_chipcontrol(sih, PMU_CHIPCTL13, PMU_CC13_4378_LHL_TIMER_SELECT, lhl_tmr_sel);
7485 
7486 		if (R_REG(osh, &pmu->pmustatus) & PST_EXTLPOAVAIL) {
7487 			lpo = LHL_EXT_LPO_ENAB;
7488 		}
7489 
7490 		if (!ISSIM_ENAB(sih)) {
7491 			si_lhl_set_lpoclk(sih, osh, lpo);
7492 		}
7493 
7494 		/* JIRA: SWWLAN-228979
7495 		 * BT LDO is required for Aux 2G Tx only. Keep powerd down until Aux is up
7496 		 */
7497 		si_pmu_bt_ldo_pu(sih, FALSE);
7498 
7499 		/* Updating xtal pmu registers to combat slow powerup issue */
7500 		si_pmu_chipcontrol_xtal_settings_4378(sih);
7501 
7502 		if (LHL_IS_PSMODE_1(sih)) {
7503 			si_gci_chipcontrol(sih, CC_GCI_CHIPCTRL_07,
7504 				((1 << GCI_CC7_AAON_BYPASS_PWRSW_SEL) |
7505 				(1 << GCI_CC7_AAON_BYPASS_PWRSW_SEQ_ON)),
7506 				0);
7507 		}
7508 
7509 		si_lhl_setup(sih, osh);
7510 
7511 		/* Setting MemLPLDO voltage */
7512 		if (getvar(NULL, rstr_memlpldo_volt) != NULL) {
7513 			int memlpldo_volt = getintvar(NULL, rstr_memlpldo_volt);
7514 
7515 			if (memlpldo_volt >= PMU_VREG5_LPLDO_VOLT_0_90 &&
7516 				memlpldo_volt <= PMU_VREG5_LPLDO_VOLT_0_88) {
7517 				si_pmu_regcontrol(sih, PMU_VREG_5, VREG5_4378_MEMLPLDO_ADJ_MASK,
7518 					memlpldo_volt << VREG5_4378_MEMLPLDO_ADJ_SHIFT);
7519 			} else {
7520 				PMU_MSG(("Invalid memlpldo value: %d\n", memlpldo_volt));
7521 			}
7522 		}
7523 
7524 		/* Setting LPLDO voltage */
7525 		if (getvar(NULL, rstr_lpldo_volt) != NULL) {
7526 			int lpldo_volt = getintvar(NULL, rstr_lpldo_volt);
7527 
7528 			if (lpldo_volt >= PMU_VREG5_LPLDO_VOLT_0_90 &&
7529 				lpldo_volt <= PMU_VREG5_LPLDO_VOLT_0_88) {
7530 				si_pmu_regcontrol(sih, PMU_VREG_5, VREG5_4378_LPLDO_ADJ_MASK,
7531 					lpldo_volt << VREG5_4378_LPLDO_ADJ_SHIFT);
7532 			} else {
7533 				PMU_MSG(("Invalid lpldo value: %d\n", lpldo_volt));
7534 			}
7535 		}
7536 
7537 		/* Enable fast LPO */
7538 		si_pmu_fast_lpo_enable(sih, osh);
7539 
7540 #if defined(SAVERESTORE)
7541 		if (SR_ENAB()) {
7542 			si_set_lv_sleep_mode_4378(sih, osh);
7543 		}
7544 #endif /* SAVERESTORE */
7545 
7546 		si_pmu_dynamic_clk_switch_enab(sih);
7547 
7548 		if (CHIPID(sih->chip) == BCM4378_CHIP_GRPID) {
7549 			si_pmu_vreg_control(sih, PMU_VREG_0,
7550 				VREG0_4378_CSR_VOLT_ADJ_PWM_MASK |
7551 				VREG0_4378_CSR_VOLT_ADJ_PFM_MASK |
7552 				VREG0_4378_CSR_VOLT_ADJ_LP_PFM_MASK |
7553 				VREG0_4378_CSR_OUT_VOLT_TRIM_ADJ_MASK,
7554 				(CSR_VOLT_ADJ_PWM_4378 << VREG0_4378_CSR_VOLT_ADJ_PWM_SHIFT) |
7555 				(CSR_VOLT_ADJ_PFM_4378 << VREG0_4378_CSR_VOLT_ADJ_PFM_SHIFT) |
7556 				(CSR_VOLT_ADJ_LP_PFM_4378 << VREG0_4378_CSR_VOLT_ADJ_LP_PFM_SHIFT) |
7557 				(CSR_OUT_VOLT_TRIM_ADJ_4378 <<
7558 					VREG0_4378_CSR_OUT_VOLT_TRIM_ADJ_SHIFT));
7559 #ifdef BCM_LDO3P3_SOFTSTART
7560 			si_pmu_ldo3p3_soft_start_wl_set(sih, osh, 0x03u);
7561 			si_pmu_ldo3p3_soft_start_bt_set(sih, osh, 0x03u);
7562 #endif
7563 		} else {
7564 			/* 4368 */
7565 			int nvcsr;
7566 			if ((nvcsr = getintvar(NULL, rstr_csrtune))) {
7567 				si_pmu_vreg_control(sih, PMU_VREG_0,
7568 					VREG0_4378_CSR_VOLT_ADJ_PWM_MASK |
7569 					VREG0_4378_CSR_VOLT_ADJ_PFM_MASK |
7570 					VREG0_4378_CSR_VOLT_ADJ_LP_PFM_MASK,
7571 					(nvcsr << VREG0_4378_CSR_VOLT_ADJ_PWM_SHIFT) |
7572 					(nvcsr << VREG0_4378_CSR_VOLT_ADJ_PFM_SHIFT) |
7573 					(nvcsr << VREG0_4378_CSR_VOLT_ADJ_LP_PFM_SHIFT));
7574 			}
7575 		}
7576 	}
7577 		break;
7578 
7579 	case BCM4385_CHIP_GRPID:
7580 	case BCM4387_CHIP_GRPID:
7581 	{
7582 		pmuregs_t *pmu = si_setcore(sih, PMU_CORE_ID, 0);
7583 		uint32 lpo = LHL_LPO_AUTO;
7584 		uint32 lhl_tmr_sel = 0;
7585 		uint32 abuck_volt, cbuck_volt;
7586 		uint32 min_mask;
7587 		uint32 misc_ldo_volt, curr_misc_ldo_volt, i;
7588 
7589 #ifdef DONGLEBUILD
7590 		si_set_arm_clkfreq_high(sih);
7591 #endif
7592 
7593 		if (PMU_FLL_PU_ENAB()) {
7594 			min_mask = R_REG(osh, &pmu->min_res_mask) |
7595 				PMURES_BIT(RES4387_FAST_LPO_AVAIL) |
7596 				PMURES_BIT(RES4387_PMU_LP);
7597 			W_REG(osh, &pmu->min_res_mask, min_mask);
7598 		}
7599 
7600 #ifdef USE_LHL_TIMER
7601 		lhl_tmr_sel = PMU_CC13_4387_LHL_TIMER_SELECT;
7602 #endif
7603 		si_pmu_chipcontrol(sih, PMU_CHIPCTL13, PMU_CC13_4387_LHL_TIMER_SELECT, lhl_tmr_sel);
7604 
7605 #if defined(SAVERESTORE)
7606 		if (SR_ENAB()) {
7607 			si_set_lv_sleep_mode_4387(sih, osh);
7608 		}
7609 #endif /* SAVERESTORE */
7610 
7611 		if (R_REG(osh, &pmu->pmustatus) & PST_EXTLPOAVAIL) {
7612 			lpo = LHL_EXT_LPO_ENAB;
7613 		}
7614 
7615 		if (!ISSIM_ENAB(sih)) {
7616 			si_lhl_set_lpoclk(sih, osh, lpo);
7617 		}
7618 
7619 		if (getintvar(NULL, rstr_btldo3p3pu)) {
7620 			si_pmu_regcontrol(sih, 4,
7621 				PMU_28NM_VREG4_WL_LDO_CNTL_EN,
7622 				PMU_28NM_VREG4_WL_LDO_CNTL_EN);
7623 			si_pmu_regcontrol(sih, 6,
7624 				PMU_4387_VREG6_BTLDO3P3_PU,
7625 				PMU_4387_VREG6_BTLDO3P3_PU);
7626 		}
7627 
7628 		if (LHL_IS_PSMODE_1(sih)) {
7629 			si_gci_chipcontrol(sih, CC_GCI_CHIPCTRL_07,
7630 				((1 << GCI_CC7_AAON_BYPASS_PWRSW_SEL) |
7631 				(1 << GCI_CC7_AAON_BYPASS_PWRSW_SEQ_ON)),
7632 				0);
7633 		}
7634 
7635 		si_lhl_setup(sih, osh);
7636 
7637 		/* Setting MemLPLDO voltage */
7638 		if (getvar(NULL, rstr_memlpldo_volt) != NULL) {
7639 			int memlpldo_volt = getintvar(NULL, rstr_memlpldo_volt);
7640 
7641 			if (memlpldo_volt >= PMU_VREG5_LPLDO_VOLT_0_90 &&
7642 				memlpldo_volt <= PMU_VREG5_LPLDO_VOLT_0_88) {
7643 				si_pmu_regcontrol(sih, PMU_VREG_5, VREG5_4387_MEMLPLDO_ADJ_MASK,
7644 					memlpldo_volt << VREG5_4387_MEMLPLDO_ADJ_SHIFT);
7645 			} else {
7646 				PMU_MSG(("Invalid memlpldo value: %d\n", memlpldo_volt));
7647 			}
7648 		}
7649 
7650 		/* Setting LPLDO voltage */
7651 		if (getvar(NULL, rstr_lpldo_volt) != NULL) {
7652 			int lpldo_volt = getintvar(NULL, rstr_lpldo_volt);
7653 
7654 			if (lpldo_volt >= PMU_VREG5_LPLDO_VOLT_0_90 &&
7655 				lpldo_volt <= PMU_VREG5_LPLDO_VOLT_0_88) {
7656 				si_pmu_regcontrol(sih, PMU_VREG_5, VREG5_4387_LPLDO_ADJ_MASK,
7657 					lpldo_volt << VREG5_4387_LPLDO_ADJ_SHIFT);
7658 			} else {
7659 				PMU_MSG(("Invalid lpldo value: %d\n", lpldo_volt));
7660 			}
7661 		}
7662 
7663 		/* Setting misc ldo voltage to 0.85625V but need stepping up */
7664 		curr_misc_ldo_volt = (si_pmu_regcontrol(sih, PMU_VREG_5, 0, 0) &
7665 			VREG5_4387_MISC_LDO_ADJ_MASK) >> VREG5_4387_MISC_LDO_ADJ_SHIFT;
7666 
7667 		/* Only after POR, chip default is 0.8V */
7668 		if (curr_misc_ldo_volt == PMU_VREG5_MISC_LDO_VOLT_0p800) {
7669 			misc_ldo_volt = PMU_VREG5_MISC_LDO_VOLT_0p856;  /* 0.85625V */
7670 
7671 			for (i = PMU_VREG5_MISC_LDO_VOLT_0p818; i <= misc_ldo_volt; i ++) {
7672 				si_pmu_regcontrol(sih, PMU_VREG_5, VREG5_4387_MISC_LDO_ADJ_MASK,
7673 					i << VREG5_4387_MISC_LDO_ADJ_SHIFT);
7674 				OSL_DELAY(MISC_LDO_STEPPING_DELAY);
7675 			}
7676 		}
7677 
7678 		/* Enable fast LPO */
7679 		si_pmu_fast_lpo_enable(sih, osh);
7680 
7681 		if (PMU_FLL_PU_ENAB()) {
7682 			/* Wait until fast LPO is stable */
7683 			OSL_DELAY(500u);
7684 			si_pmu_fll_preload_enable(sih);
7685 		}
7686 
7687 		si_pmu_dynamic_clk_switch_enab(sih);
7688 
7689 		/* HQ settings */
7690 		si_gci_chipcontrol(sih, CC_GCI_CHIPCTRL_25,
7691 			0xFFFFFFFF, XTAL_HQ_SETTING_4387);
7692 
7693 		/* LQ settings */
7694 		si_gci_chipcontrol(sih, CC_GCI_CHIPCTRL_26,
7695 			0xFFFFFFFF, XTAL_LQ_SETTING_4387);
7696 
7697 		/* Enable Radiodig Clk Gating */
7698 		si_pmu_chipcontrol(sih, PMU_CHIPCTL13, PMU_CC13_4387_ENAB_RADIO_REG_CLK, 0);
7699 
7700 		/* Set up HW based switch-off of select BBPLL channels when SCAN-only mode
7701 		 *
7702 		 * Assign bbpll_ch_control_grp_pd_trigger_mask = {gci_chip_cntrl[559:554],
7703 		 * gci_chip_cntrl[543:522], 1'b0, gci_chip_cntrl[521], 1'b0};
7704 		 */
7705 		si_gci_chipcontrol(sih, CC_GCI_CHIPCTRL_16,
7706 			CC_GCI_16_BBPLL_CH_CTRL_GRP_PD_TRIG_1_MASK |
7707 			CC_GCI_16_BBPLL_CH_CTRL_GRP_PD_TRIG_24_3_MASK,
7708 			(((GRP_PD_TRIGGER_MASK_4387 >> 1) & 0x1) <<	/* bit 1 */
7709 			CC_GCI_16_BBPLL_CH_CTRL_GRP_PD_TRIG_1_SHIFT) |
7710 			(((GRP_PD_TRIGGER_MASK_4387 >> 3) & 0x3FFFFF) << /* bit 24:3 */
7711 			CC_GCI_16_BBPLL_CH_CTRL_GRP_PD_TRIG_24_3_SHIFT));
7712 
7713 		si_gci_chipcontrol(sih, CC_GCI_CHIPCTRL_17,
7714 			CC_GCI_17_BBPLL_CH_CTRL_GRP_PD_TRIG_30_25_MASK |
7715 			CC_GCI_17_BBPLL_CH_CTRL_EN_MASK,
7716 			(((GRP_PD_TRIGGER_MASK_4387 >> 25) & 0x3F) <<	/* bits 30:25 */
7717 			CC_GCI_17_BBPLL_CH_CTRL_GRP_PD_TRIG_30_25_SHIFT) |
7718 			CC_GCI_17_BBPLL_CH_CTRL_EN_MASK);
7719 
7720 		si_gci_chipcontrol(sih, CC_GCI_CHIPCTRL_20,
7721 			CC_GCI_20_BBPLL_CH_CTRL_GRP_MASK,
7722 			(GRP_PD_MASK_4387 << CC_GCI_20_BBPLL_CH_CTRL_GRP_SHIFT));
7723 
7724 		if (CHIPID(sih->chip) == BCM4397_CHIP_GRPID) {
7725 			/* For Phy Reg Access configure IHRP access */
7726 			si_gci_chipcontrol(sih, CC_GCI_CHIPCTRL_28,
7727 				GCI_CC28_IHRP_SEL_MASK,
7728 				0u << GCI_CC28_IHRP_SEL_SHIFT);
7729 		}
7730 
7731 		if (getvar(NULL, rstr_abuck_volt) != NULL) {
7732 			abuck_volt = getintvar(NULL, rstr_abuck_volt);
7733 		} else {
7734 			abuck_volt = ABUCK_VOLT_SW_DEFAULT_4387;
7735 		}
7736 
7737 		if (CHIPID(sih->chip) == BCM4397_CHIP_GRPID) {
7738 			/* For Phy Reg Access configure IHRP access */
7739 			si_gci_chipcontrol(sih, CC_GCI_CHIPCTRL_28,
7740 				GCI_CC28_IHRP_SEL_MASK,
7741 				0u << GCI_CC28_IHRP_SEL_SHIFT);
7742 		}
7743 
7744 		/* For 4397, PMU has only 11 Regulator Registers */
7745 		if (sih->chip != BCM4397_CHIP_ID) {
7746 			si_pmu_vreg_control(sih, PMU_VREG_13,
7747 				PMU_VREG13_ASR_OVADJ_PWM_MASK,
7748 				abuck_volt << PMU_VREG13_ASR_OVADJ_PWM_SHIFT);
7749 		}
7750 		if (BCM_PWR_OPT_ENAB()) {
7751 			if (getvar(NULL, rstr_cbuck_volt) != NULL) {
7752 				cbuck_volt = getintvar(NULL, rstr_cbuck_volt);
7753 			} else {
7754 				cbuck_volt = CBUCK_VOLT_SW_DEFAULT_4387;
7755 			}
7756 
7757 			si_pmu_vreg_control(sih, PMU_VREG_0,
7758 				VREG0_4378_CSR_VOLT_ADJ_PWM_MASK,
7759 				cbuck_volt << VREG0_4378_CSR_VOLT_ADJ_PWM_SHIFT);
7760 		}
7761 
7762 		PMU_REG(sih, pmucontrol_ext, PCTL_EXT_FAST_TRANS_ENAB, PCTL_EXT_FAST_TRANS_ENAB);
7763 
7764 		if (si_hib_ext_wakeup_isenab(sih)) {
7765 			/* pull up common BP */
7766 			int rsrc_num = RES4387_CORE_RDY_CB;
7767 			uint32 deps = PMURES_BIT(rsrc_num) |
7768 				si_pmu_res_deps(sih, osh, pmu, PMURES_BIT(rsrc_num), TRUE);
7769 			W_REG(osh, &pmu->extwakereqmask[0], deps);
7770 		}
7771 
7772 		si_pmu_chipcontrol(sih, PMU_CHIPCTL17,
7773 			PMU_CC17_SCAN_DIG_SR_CLK_MASK,
7774 			SCAN_DIG_SR_CLK_40_MHZ << PMU_CC17_SCAN_DIG_SR_CLK_SHIFT);
7775 	}
7776 		break;
7777 
7778 	case BCM4388_CHIP_GRPID:
7779 	case BCM4389_CHIP_GRPID:
7780 	case BCM4397_CHIP_GRPID:
7781 	{
7782 		pmuregs_t *pmu = si_setcore(sih, PMU_CORE_ID, 0);
7783 		uint32 lpo = LHL_LPO_AUTO;
7784 		uint32 lhl_tmr_sel = 0;
7785 		uint32 abuck_volt, cbuck_volt;
7786 		uint32 min_mask;
7787 
7788 		if (PMU_FLL_PU_ENAB()) {
7789 			min_mask = R_REG(osh, &pmu->min_res_mask) |
7790 				PMURES_BIT(RES4389_FAST_LPO_AVAIL) |
7791 				PMURES_BIT(RES4389_PMU_LP);
7792 			W_REG(osh, &pmu->min_res_mask, min_mask);
7793 		}
7794 
7795 #ifdef USE_LHL_TIMER
7796 		lhl_tmr_sel = PMU_CC13_4387_LHL_TIMER_SELECT;
7797 #endif
7798 		si_pmu_chipcontrol(sih, PMU_CHIPCTL13, PMU_CC13_4387_LHL_TIMER_SELECT, lhl_tmr_sel);
7799 
7800 #if defined(SAVERESTORE)
7801 		if (SR_ENAB()) {
7802 			si_set_lv_sleep_mode_4389(sih, osh);
7803 		}
7804 #endif /* SAVERESTORE */
7805 		/* SET CB2WL Intr PWR Request irrespective of Default value */
7806 		si_pmu_chipcontrol(sih, PMU_CHIPCTL2, PMU_CC2_CB2WL_INTR_PWRREQ_EN,
7807 				PMU_CC2_CB2WL_INTR_PWRREQ_EN);
7808 
7809 		if (R_REG(osh, &pmu->pmustatus) & PST_EXTLPOAVAIL) {
7810 			lpo = LHL_EXT_LPO_ENAB;
7811 		}
7812 
7813 		if (!ISSIM_ENAB(sih)) {
7814 			si_lhl_set_lpoclk(sih, osh, lpo);
7815 		}
7816 
7817 		if (getintvar(NULL, rstr_btldo3p3pu)) {
7818 			si_pmu_regcontrol(sih, 4,
7819 				PMU_28NM_VREG4_WL_LDO_CNTL_EN,
7820 				PMU_28NM_VREG4_WL_LDO_CNTL_EN);
7821 			si_pmu_regcontrol(sih, 6,
7822 				PMU_4387_VREG6_BTLDO3P3_PU,
7823 				PMU_4387_VREG6_BTLDO3P3_PU);
7824 		}
7825 
7826 		if (LHL_IS_PSMODE_1(sih)) {
7827 			si_gci_chipcontrol(sih, CC_GCI_CHIPCTRL_07,
7828 				((1 << GCI_CC7_AAON_BYPASS_PWRSW_SEL) |
7829 				(1 << GCI_CC7_AAON_BYPASS_PWRSW_SEQ_ON)),
7830 				0);
7831 		}
7832 
7833 		si_lhl_setup(sih, osh);
7834 
7835 		/* Setting MemLPLDO voltage */
7836 		if (getvar(NULL, rstr_memlpldo_volt) != NULL) {
7837 			int memlpldo_volt = getintvar(NULL, rstr_memlpldo_volt);
7838 
7839 			if (memlpldo_volt >= PMU_VREG5_LPLDO_VOLT_0_90 &&
7840 				memlpldo_volt <= PMU_VREG5_LPLDO_VOLT_0_88) {
7841 				si_pmu_regcontrol(sih, PMU_VREG_5, VREG5_4387_MEMLPLDO_ADJ_MASK,
7842 					memlpldo_volt << VREG5_4387_MEMLPLDO_ADJ_SHIFT);
7843 			} else {
7844 				PMU_MSG(("Invalid memlpldo value: %d\n", memlpldo_volt));
7845 			}
7846 		}
7847 
7848 		/* Setting LPLDO voltage */
7849 		if (getvar(NULL, rstr_lpldo_volt) != NULL) {
7850 			int lpldo_volt = getintvar(NULL, rstr_lpldo_volt);
7851 
7852 			if (lpldo_volt >= PMU_VREG5_LPLDO_VOLT_0_90 &&
7853 				lpldo_volt <= PMU_VREG5_LPLDO_VOLT_0_88) {
7854 				si_pmu_regcontrol(sih, PMU_VREG_5, VREG5_4387_LPLDO_ADJ_MASK,
7855 					lpldo_volt << VREG5_4387_LPLDO_ADJ_SHIFT);
7856 			} else {
7857 				PMU_MSG(("Invalid lpldo value: %d\n", lpldo_volt));
7858 			}
7859 		}
7860 
7861 		/* Enable fast LPO */
7862 		si_pmu_fast_lpo_enable(sih, osh);
7863 
7864 		if (PMU_FLL_PU_ENAB()) {
7865 			/* Wait until fast LPO is stable */
7866 			OSL_DELAY(500u);
7867 			si_pmu_fll_preload_enable(sih);
7868 		}
7869 
7870 		si_pmu_dynamic_clk_switch_enab(sih);
7871 
7872 		/* HQ settings */
7873 		si_gci_chipcontrol(sih, CC_GCI_CHIPCTRL_25,
7874 			0xFFFFFFFF, XTAL_HQ_SETTING_4387);
7875 
7876 		/* LQ settings */
7877 		si_gci_chipcontrol(sih, CC_GCI_CHIPCTRL_26,
7878 			0xFFFFFFFF, XTAL_LQ_SETTING_4387);
7879 
7880 		/* Enable Radiodig Clk Gating */
7881 		si_pmu_chipcontrol(sih, PMU_CHIPCTL13, PMU_CC13_4387_ENAB_RADIO_REG_CLK, 0);
7882 
7883 		/* Set up HW based switch-off of select BBPLL channels when SCAN-only mode
7884 		 *
7885 		 * Assign bbpll_ch_control_grp_pd_trigger_mask = {gci_chip_cntrl[559:554],
7886 		 * gci_chip_cntrl[543:522], 1'b0, gci_chip_cntrl[521], 1'b0};
7887 		 */
7888 		si_gci_chipcontrol(sih, CC_GCI_CHIPCTRL_16,
7889 			CC_GCI_16_BBPLL_CH_CTRL_GRP_PD_TRIG_1_MASK |
7890 			CC_GCI_16_BBPLL_CH_CTRL_GRP_PD_TRIG_24_3_MASK,
7891 			(((GRP_PD_TRIGGER_MASK_4387 >> 1) & 0x1) <<	/* bit 1 */
7892 			CC_GCI_16_BBPLL_CH_CTRL_GRP_PD_TRIG_1_SHIFT) |
7893 			(((GRP_PD_TRIGGER_MASK_4387 >> 3) & 0x3FFFFF) << /* bit 24:3 */
7894 			CC_GCI_16_BBPLL_CH_CTRL_GRP_PD_TRIG_24_3_SHIFT));
7895 
7896 		si_gci_chipcontrol(sih, CC_GCI_CHIPCTRL_17,
7897 			CC_GCI_17_BBPLL_CH_CTRL_GRP_PD_TRIG_30_25_MASK |
7898 			CC_GCI_17_BBPLL_CH_CTRL_EN_MASK,
7899 			(((GRP_PD_TRIGGER_MASK_4387 >> 25) & 0x3F) <<	/* bits 30:25 */
7900 			CC_GCI_17_BBPLL_CH_CTRL_GRP_PD_TRIG_30_25_SHIFT) |
7901 			CC_GCI_17_BBPLL_CH_CTRL_EN_MASK);
7902 
7903 		si_gci_chipcontrol(sih, CC_GCI_CHIPCTRL_20,
7904 			CC_GCI_20_BBPLL_CH_CTRL_GRP_MASK,
7905 			(GRP_PD_MASK_4387 << CC_GCI_20_BBPLL_CH_CTRL_GRP_SHIFT));
7906 
7907 		if (getvar(NULL, rstr_abuck_volt) != NULL) {
7908 			abuck_volt = getintvar(NULL, rstr_abuck_volt);
7909 		} else {
7910 			abuck_volt = ABUCK_VOLT_SW_DEFAULT_4387;
7911 		}
7912 
7913 		if (CHIPID(sih->chip) == BCM4397_CHIP_GRPID) {
7914 			/* For Phy Reg Access configure IHRP access */
7915 			si_gci_chipcontrol(sih, CC_GCI_CHIPCTRL_28,
7916 				GCI_CC28_IHRP_SEL_MASK,
7917 				0u << GCI_CC28_IHRP_SEL_SHIFT);
7918 		}
7919 
7920 		/* For 4397, PMU has only 11 Regulator Registers */
7921 		if (sih->chip != BCM4397_CHIP_ID) {
7922 			si_pmu_vreg_control(sih, PMU_VREG_13,
7923 				PMU_VREG13_ASR_OVADJ_PWM_MASK,
7924 				abuck_volt << PMU_VREG13_ASR_OVADJ_PWM_SHIFT);
7925 		}
7926 
7927 		if (BCM_PWR_OPT_ENAB()) {
7928 			if (getvar(NULL, rstr_cbuck_volt) != NULL) {
7929 				cbuck_volt = getintvar(NULL, rstr_cbuck_volt);
7930 			} else {
7931 				cbuck_volt = CBUCK_VOLT_SW_DEFAULT_4387;
7932 			}
7933 
7934 			si_pmu_vreg_control(sih, PMU_VREG_0,
7935 				VREG0_4378_CSR_VOLT_ADJ_PWM_MASK,
7936 				cbuck_volt << VREG0_4378_CSR_VOLT_ADJ_PWM_SHIFT);
7937 		}
7938 
7939 		PMU_REG(sih, pmucontrol_ext, PCTL_EXT_FAST_TRANS_ENAB, PCTL_EXT_FAST_TRANS_ENAB);
7940 
7941 		if (PMUREV(sih->pmurev) == 39) {
7942 			si_gci_chipcontrol(sih, CC_GCI_CHIPCTRL_04,
7943 				CC_GCI_04_4387C0_XTAL_PM_CLK,
7944 				CC_GCI_04_4387C0_XTAL_PM_CLK);
7945 		}
7946 	}
7947 		break;
7948 
7949 	default:
7950 		break;
7951 	}
7952 } /* si_pmu_chip_init */
7953 
7954 /** Reference: http://confluence.broadcom.com/display/WLAN/Open+loop+Calibration+Sequence */
7955 int
si_pmu_openloop_cal(si_t * sih,uint16 currtemp)7956 si_pmu_openloop_cal(si_t *sih, uint16 currtemp)
7957 {
7958 	int err = BCME_OK;
7959 	switch (CHIPID(sih->chip)) {
7960 	case BCM43012_CHIP_ID:
7961 	case BCM43013_CHIP_ID:
7962 	case BCM43014_CHIP_ID:
7963 		err = si_pmu_openloop_cal_43012(sih, currtemp);
7964 		break;
7965 
7966 	default:
7967 		PMU_MSG(("si_pmu_openloop_cal: chip not supported!\n"));
7968 		break;
7969 	}
7970 	return err;
7971 }
7972 
7973 static int
si_pmu_openloop_cal_43012(si_t * sih,uint16 currtemp)7974 si_pmu_openloop_cal_43012(si_t *sih, uint16 currtemp)
7975 {
7976 	int32 a1 = -27, a2 = -15, b1 = 18704, b2 = 7531, a3, y1, y2, b3, y3;
7977 	int32 xtal, array_size = 0, dco_code = 0, origidx = 0, pll_reg = 0, err;
7978 	bcm_int_bitmask_t intr_val;
7979 	pmuregs_t *pmu = NULL;
7980 	const pllctrl_data_t *pllctrlreg_update;
7981 	const uint32 *pllctrlreg_val;
7982 	osl_t *osh = si_osh(sih);
7983 	uint32 final_dco_code = si_get_openloop_dco_code(sih);
7984 
7985 	xtal = si_xtalfreq(sih);
7986 	err = BCME_OK;
7987 
7988 	origidx = si_coreidx(sih);
7989 	pmu = si_setcore(sih, PMU_CORE_ID, 0);
7990 	if (!pmu) {
7991 		PMU_MSG(("si_pmu_openloop_cal_43012: NULL pmu pointer \n"));
7992 		err = BCME_ERROR;
7993 		goto done;
7994 	}
7995 
7996 	if (final_dco_code == 0) {
7997 		currtemp = (currtemp == 0)?-1: currtemp;
7998 
7999 		SPINWAIT(((si_corereg(sih, SI_CC_IDX,
8000 			OFFSETOF(chipcregs_t, clk_ctl_st), 0, 0)
8001 			& CCS_HTAVAIL) != CCS_HTAVAIL), PMU_MAX_TRANSITION_DLY);
8002 		ASSERT((si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, clk_ctl_st), 0, 0)
8003 			& CCS_HTAVAIL));
8004 
8005 		/* Stop using PLL clks, by programming the disable_ht_avail */
8006 		/* and disable_lq_avail in the pmu chip control bit */
8007 		/* Turn Off PLL */
8008 		si_pmu_pll_off_43012(sih, osh, pmu);
8009 
8010 		/* Program PLL for 320MHz VCO */
8011 		pllctrlreg_update = pmu1_xtaltab0_43012;
8012 		array_size = ARRAYSIZE(pmu1_xtaltab0_43012);
8013 		pllctrlreg_val = pmu1_pllctrl_tab_43012_1600mhz;
8014 		si_pmu_pllctrlreg_update(sih, osh, pmu, xtal, 100,
8015 			pllctrlreg_update, array_size, pllctrlreg_val);
8016 
8017 		/* Update PLL control register */
8018 		/* Set the Update bit (bit 10) in PMU for PLL registers */
8019 		OR_REG(osh, &pmu->pmucontrol, PCTL_PLL_PLLCTL_UPD);
8020 
8021 		/* Turn PLL ON but ensure that force_bbpll_dreset */
8022 		/* bit is set , so that PLL 320Mhz clocks cannot be consumed */
8023 		si_pmu_pll_on_43012(sih, osh, pmu, 1);
8024 
8025 		/* Settings to get dco_code on PLL test outputs and then read */
8026 		/* from gci chip status */
8027 		pll_reg = si_pmu_pllcontrol(sih, PMU_PLL_CTRL_REG1, 0, 0);
8028 		pll_reg = (pll_reg & (~0x3C000)) | (0x4<<14);
8029 		si_pmu_pllcontrol(sih, PMU_PLL_CTRL_REG1, ~0, pll_reg);
8030 		OR_REG(osh, &pmu->pmucontrol, PCTL_PLL_PLLCTL_UPD);
8031 
8032 		pll_reg = pll_reg | (1<<17);
8033 		si_pmu_pllcontrol(sih, PMU_PLL_CTRL_REG1, ~0, pll_reg);
8034 		OR_REG(osh, &pmu->pmucontrol, PCTL_PLL_PLLCTL_UPD);
8035 
8036 		/* Get the DCO code from GCI CHIP STATUS Register 7 , bits 27 downto 16 */
8037 		dco_code = (si_gci_chipstatus(sih, GCI_CHIPSTATUS_07));
8038 		dco_code = ((dco_code & 0x0FFF0000) >> 16);
8039 		dco_code = (dco_code  >> 4);
8040 
8041 		/* The DCO code obtained above and the temperature */
8042 		/* sensed at this time will give us the DCO code */
8043 		/* that needs to be programmed to ensure VCO does not crosses 160 MHz at 125C */
8044 		y1 = ((a1 * currtemp) + b1);
8045 		y2 = ((a2 * currtemp) + b2);
8046 		dco_code = (dco_code * 100);
8047 		b3 = b1 + (((b2-b1)/(y2 - y1)) * (dco_code - y1));
8048 		if (b3 > dco_code) {
8049 			a3 = (b3 - dco_code) / currtemp;
8050 			y3 = b3 - (a3 * 125);
8051 		}
8052 		else {
8053 			 a3 = (dco_code - b3) / currtemp;
8054 			 y3 = b3 + (a3 * 125);
8055 		}
8056 		y3 = (y3/100);
8057 		PMU_MSG(("DCO_CODE = %d\n", y3));
8058 
8059 		/* Turning ON PLL at 160.1 MHz for Normal Operation */
8060 		si_pmu_pll_off_43012(sih, osh, pmu);
8061 		pllctrlreg_update = pmu1_xtaltab0_43012;
8062 		array_size = ARRAYSIZE(pmu1_xtaltab0_43012);
8063 		pllctrlreg_val = pmu1_pllctrl_tab_43012_1600mhz;
8064 		si_pmu_pllctrlreg_update(sih, osh, pmu, xtal, 0,
8065 			pllctrlreg_update, array_size, pllctrlreg_val);
8066 
8067 		/* Update PLL control register */
8068 		/* Set the Update bit (bit 10) in PMU for PLL registers */
8069 		OR_REG(osh, &pmu->pmucontrol, PCTL_PLL_PLLCTL_UPD);
8070 
8071 		si_pmu_pll_on_43012(sih, osh, pmu, 0);
8072 		y3 = (y3 << 4);
8073 		final_dco_code = y3;
8074 		PMU_MSG(("openloop_dco_code = %x\n", final_dco_code));
8075 	}
8076 
8077 	pll_reg = si_pmu_pllcontrol(sih, PMU_PLL_CTRL_REG3, 0, 0);
8078 	y3 = (pll_reg >> 16) & 0xFFF;
8079 
8080 	if (final_dco_code != (uint32)y3) {
8081 
8082 		/* Program the DCO code to bits 27 */
8083 		/* downto 16 of the PLL control 3 register */
8084 		si_pmu_pllcontrol(sih, PMU_PLL_CTRL_REG3,
8085 			0x0FFF0000, (final_dco_code << 16));
8086 
8087 		/* Enable Extra post divison for Open Loop */
8088 		/* by writing 1 to bit 14 of above register */
8089 		si_pmu_pllcontrol(sih, PMU_PLL_CTRL_REG3, 0x00004000, (1<<14));
8090 
8091 		/* Update PLL control register */
8092 		/* Set the Update bit (bit 10) in PMU for PLL registers */
8093 		OR_REG(osh, &pmu->pmucontrol, PCTL_PLL_PLLCTL_UPD);
8094 		/* After cal openloop VCO Max=320MHz, Min=240Mhz (with extra margin */
8095 		/* 230-220MHz). Update SAVE_RESTORE up/down times accordingly */
8096 		W_REG(osh, &pmu->res_table_sel,	RES43012_SR_SAVE_RESTORE);
8097 		W_REG(osh, &pmu->res_updn_timer, 0x01800180);
8098 	}
8099 
8100 	si_restore_core(sih, origidx, &intr_val);
8101 	si_set_openloop_dco_code(sih, final_dco_code);
8102 done:
8103 	return err;
8104 }
8105 
8106 void
si_pmu_slow_clk_reinit(si_t * sih,osl_t * osh)8107 si_pmu_slow_clk_reinit(si_t *sih, osl_t *osh)
8108 {
8109 #if !defined(BCMDONGLEHOST)
8110 	chipcregs_t *cc;
8111 	uint origidx;
8112 	uint32 xtalfreq;
8113 
8114 	/* PMU specific initializations */
8115 	if (!PMUCTL_ENAB(sih))
8116 		return;
8117 	/* Remember original core before switch to chipc */
8118 	origidx = si_coreidx(sih);
8119 	cc = si_setcoreidx(sih, SI_CC_IDX);
8120 	ASSERT(cc != NULL);
8121 	if (cc == NULL)
8122 		return;
8123 
8124 	xtalfreq = getintvar(NULL, rstr_xtalfreq);
8125 	/*
8126 	 * workaround for chips that don't support external LPO, thus ALP clock
8127 	 * can not be measured accurately:
8128 	 */
8129 	switch (CHIPID(sih->chip)) {
8130 		CASE_BCM43602_CHIP:
8131 			xtalfreq = XTAL_FREQ_54MHZ;
8132 			break;
8133 		default:
8134 			break;
8135 	}
8136 	/* If xtalfreq var not available, try to measure it */
8137 	if (xtalfreq == 0)
8138 		xtalfreq = si_pmu_measure_alpclk(sih, osh);
8139 	si_pmu_enb_slow_clk(sih, osh, xtalfreq);
8140 	/* Return to original core */
8141 	si_setcoreidx(sih, origidx);
8142 #endif /* !BCMDONGLEHOST */
8143 }
8144 
8145 /** initialize PMU registers in case default values proved to be suboptimal */
8146 void
BCMATTACHFN(si_pmu_swreg_init)8147 BCMATTACHFN(si_pmu_swreg_init)(si_t *sih, osl_t *osh)
8148 {
8149 	ASSERT(sih->cccaps & CC_CAP_PMU);
8150 
8151 	switch (CHIPID(sih->chip)) {
8152 	CASE_BCM43602_CHIP:
8153 		/* adjust PA Vref to 2.80V */
8154 		si_pmu_set_ldo_voltage(sih, osh, SET_LDO_VOLTAGE_PAREF, 0x0c);
8155 		break;
8156 	case BCM4378_CHIP_GRPID:
8157 		si_gci_chipcontrol(sih, CC_GCI_CHIPCTRL_04, GPIO_DRIVE_4378_MASK,
8158 			GPIO_DRIVE_4378_VAL);
8159 		/* fall through */
8160 	case BCM4376_CHIP_GRPID:
8161 	case BCM4385_CHIP_GRPID:
8162 	case BCM4387_CHIP_GRPID:
8163 #ifdef BCM_AVS
8164 		if (BCM_AVS_ENAB()) {
8165 			si_pmu_set_avs(sih);
8166 		}
8167 #endif
8168 		break;
8169 	default:
8170 		break;
8171 	}
8172 	si_pmu_otp_vreg_control(sih, osh);
8173 } /* si_pmu_swreg_init */
8174 
8175 /** Wait for a particular clock level to be on the backplane */
8176 uint32
si_pmu_waitforclk_on_backplane(si_t * sih,osl_t * osh,uint32 clk,uint32 delay_val)8177 si_pmu_waitforclk_on_backplane(si_t *sih, osl_t *osh, uint32 clk, uint32 delay_val)
8178 {
8179 	pmuregs_t *pmu;
8180 	uint origidx;
8181 	uint32 val;
8182 
8183 	ASSERT(sih->cccaps & CC_CAP_PMU);
8184 	/* Remember original core before switch to chipc/pmu */
8185 	origidx = si_coreidx(sih);
8186 	if (AOB_ENAB(sih)) {
8187 		pmu = si_setcore(sih, PMU_CORE_ID, 0);
8188 	} else {
8189 		pmu = si_setcoreidx(sih, SI_CC_IDX);
8190 	}
8191 	ASSERT(pmu != NULL);
8192 
8193 	if (delay_val)
8194 		SPINWAIT(((R_REG(osh, &pmu->pmustatus) & clk) != clk), delay_val);
8195 	val = R_REG(osh, &pmu->pmustatus) & clk;
8196 
8197 	/* Return to original core */
8198 	si_setcoreidx(sih, origidx);
8199 	return (val);
8200 }
8201 
8202 #define EXT_ILP_HZ 32768
8203 
8204 /**
8205  * Measures the ALP clock frequency in KHz.  Returns 0 if not possible.
8206  * Possible only if PMU rev >= 10 and there is an external LPO 32768Hz crystal.
8207  */
8208 uint32
BCMATTACHFN(si_pmu_measure_alpclk)8209 BCMATTACHFN(si_pmu_measure_alpclk)(si_t *sih, osl_t *osh)
8210 {
8211 	uint32 alp_khz;
8212 	uint32 pmustat_lpo = 0;
8213 	pmuregs_t *pmu;
8214 	uint origidx;
8215 
8216 	if (PMUREV(sih->pmurev) < 10)
8217 		return 0;
8218 
8219 	ASSERT(sih->cccaps & CC_CAP_PMU);
8220 
8221 	/* Remember original core before switch to chipc/pmu */
8222 	origidx = si_coreidx(sih);
8223 	if (AOB_ENAB(sih)) {
8224 		pmu = si_setcore(sih, PMU_CORE_ID, 0);
8225 	} else {
8226 		pmu = si_setcoreidx(sih, SI_CC_IDX);
8227 	}
8228 	ASSERT(pmu != NULL);
8229 
8230 	if ((CHIPID(sih->chip) == BCM43012_CHIP_ID) ||
8231 		(CHIPID(sih->chip) == BCM43013_CHIP_ID) ||
8232 		(CHIPID(sih->chip) == BCM43014_CHIP_ID) ||
8233 		(PMUREV(sih->pmurev) >= 22))
8234 		pmustat_lpo = !(R_REG(osh, &pmu->pmucontrol) & PCTL_LPO_SEL);
8235 	else
8236 		pmustat_lpo = R_REG(osh, &pmu->pmustatus) & PST_EXTLPOAVAIL;
8237 
8238 	if (pmustat_lpo) {
8239 		uint32 ilp_ctr, alp_hz;
8240 
8241 		/* Enable the reg to measure the freq, in case disabled before */
8242 		W_REG(osh, &pmu->pmu_xtalfreq, 1U << PMU_XTALFREQ_REG_MEASURE_SHIFT);
8243 
8244 		/* Delay for well over 4 ILP clocks */
8245 		OSL_DELAY(1000);
8246 
8247 		/* Read the latched number of ALP ticks per 4 ILP ticks */
8248 		ilp_ctr = R_REG(osh, &pmu->pmu_xtalfreq) & PMU_XTALFREQ_REG_ILPCTR_MASK;
8249 
8250 		/* Turn off the PMU_XTALFREQ_REG_MEASURE_SHIFT bit to save power */
8251 		W_REG(osh, &pmu->pmu_xtalfreq, 0);
8252 
8253 		/* Calculate ALP frequency */
8254 		alp_hz = (ilp_ctr * EXT_ILP_HZ) / 4;
8255 
8256 		/* Round to nearest 100KHz, and at the same time convert to KHz */
8257 		alp_khz = (alp_hz + 50000) / 100000 * 100;
8258 	} else
8259 		alp_khz = 0;
8260 
8261 	/* Return to original core */
8262 	si_setcoreidx(sih, origidx);
8263 
8264 	return alp_khz;
8265 } /* si_pmu_measure_alpclk */
8266 
8267 /** Update min/max resources after SR-ASM download to d11 txfifo */
8268 void
si_pmu_res_minmax_update(si_t * sih,osl_t * osh)8269 si_pmu_res_minmax_update(si_t *sih, osl_t *osh)
8270 {
8271 	uint32 min_mask = 0, max_mask = 0;
8272 	pmuregs_t *pmu;
8273 	uint origidx;
8274 	bcm_int_bitmask_t intr_val;
8275 
8276 	/* Block ints and save current core */
8277 	si_introff(sih, &intr_val);
8278 	/* Remember original core before switch to chipc/pmu */
8279 	origidx = si_coreidx(sih);
8280 	if (AOB_ENAB(sih)) {
8281 		pmu = si_setcore(sih, PMU_CORE_ID, 0);
8282 	} else {
8283 		pmu = si_setcoreidx(sih, SI_CC_IDX);
8284 	}
8285 	ASSERT(pmu != NULL);
8286 
8287 	switch (CHIPID(sih->chip)) {
8288 	CASE_BCM43602_CHIP:
8289 		max_mask = 0; /* Only care about min_mask for now */
8290 		break;
8291 	case BCM43012_CHIP_ID:
8292 	case BCM43013_CHIP_ID:
8293 	case BCM43014_CHIP_ID:
8294 		min_mask = RES43012_PMU_SLEEP;
8295 		break;
8296 	case BCM4369_CHIP_GRPID:
8297 	case BCM4362_CHIP_GRPID:
8298 	case BCM4376_CHIP_GRPID:
8299 	case BCM4378_CHIP_GRPID:
8300 	case BCM4385_CHIP_GRPID:
8301 	case BCM4387_CHIP_GRPID:
8302 	case BCM4388_CHIP_GRPID:
8303 	case BCM4389_CHIP_GRPID:
8304 	case BCM4397_CHIP_GRPID:
8305 		si_pmu_res_masks(sih, &min_mask, &max_mask);
8306 		max_mask = 0; /* Don't need to update max */
8307 		break;
8308 	default:
8309 		break;
8310 	}
8311 	if (min_mask) {
8312 		/* Add min mask dependencies */
8313 		min_mask |= si_pmu_res_deps(sih, osh, pmu, min_mask, FALSE);
8314 		W_REG(osh, &pmu->min_res_mask, min_mask);
8315 	}
8316 	if (max_mask) {
8317 		max_mask |= si_pmu_res_deps(sih, osh, pmu, max_mask, FALSE);
8318 		W_REG(osh, &pmu->max_res_mask, max_mask);
8319 	}
8320 
8321 	si_pmu_wait_for_steady_state(sih, osh, pmu);
8322 
8323 	/* Return to original core */
8324 	si_setcoreidx(sih, origidx);
8325 	si_intrrestore(sih, &intr_val);
8326 } /* si_pmu_res_minmax_update */
8327 
8328 #ifdef DONGLEBUILD
8329 
8330 #define PMUCAP_DUMP_TAG_SIZE_BYTES	4
8331 
8332 /* Move the below definitions to .ro_ontrap section so they
8333  * won't be reused when reusing rodata section after trap.
8334  */
8335 static const uint32 BCMPOST_TRAP_RODATA(chipc_regs_to_dump)[] = {
8336 	OFFSETOF(chipcregs_t, clk_ctl_st),
8337 	OFFSETOF(chipcregs_t, powerctl)
8338 };
8339 
8340 static const uint BCMPOST_TRAP_RODATA(pmuregsdump)[] = {
8341 		OFFSETOF(pmuregs_t, pmucontrol),
8342 		OFFSETOF(pmuregs_t, pmucapabilities),
8343 		OFFSETOF(pmuregs_t, pmustatus),
8344 		OFFSETOF(pmuregs_t, res_state),
8345 		OFFSETOF(pmuregs_t, res_pending),
8346 		OFFSETOF(pmuregs_t, pmutimer),
8347 		OFFSETOF(pmuregs_t, min_res_mask),
8348 		OFFSETOF(pmuregs_t, max_res_mask),
8349 		OFFSETOF(pmuregs_t, clkstretch),
8350 		OFFSETOF(pmuregs_t, res_req_timer),
8351 		OFFSETOF(pmuregs_t, res_req_mask),
8352 		OFFSETOF(pmuregs_t, mac_res_req_timer),
8353 		OFFSETOF(pmuregs_t, mac_res_req_mask),
8354 		OFFSETOF(pmuregs_t, pmuintmask0),
8355 		OFFSETOF(pmuregs_t, pmuintstatus),
8356 		OFFSETOF(pmuregs_t, pmuintctrl0),
8357 		OFFSETOF(pmuregs_t, extwakeupstatus),
8358 		OFFSETOF(pmuregs_t, extwakemask0)
8359 };
8360 
8361 static const uint BCMPOST_TRAP_RODATA(pmuregsdump_mac_res1)[] = {
8362 		OFFSETOF(pmuregs_t, mac_res_req_timer1),
8363 		OFFSETOF(pmuregs_t, mac_res_req_mask1)
8364 };
8365 
8366 static const uint BCMPOST_TRAP_RODATA(pmuregsdump_mac_res2)[] = {
8367 		OFFSETOF(pmuregs_t, mac_res_req_timer2),
8368 		OFFSETOF(pmuregs_t, mac_res_req_mask2)
8369 };
8370 
8371 static const uint BCMPOST_TRAP_RODATA(pmuregsdump_pmu_int1)[] = {
8372 		OFFSETOF(pmuregs_t, pmuintmask1),
8373 		OFFSETOF(pmuregs_t, pmuintctrl1)
8374 };
8375 
8376 /* Pointer to location in ROdata where PMU registers are stored.
8377  * It is good to avoid re-reading PMU registers as: 1. reading regs is slow
8378  * 2. As part of trap, these registers are dumped to RO data section anyway.
8379  * so why not read directly from ROdata section and send to host?
8380  * these registers will be dumped n RODATA first and then hnd_minidump_pmuegs_dump()
8381  * will pick these up. For it to pick these up, it
8382  * needs to know where they are stored.
8383  */
8384 /* Length of the reg dump containing address, value pair */
8385 #define SI_PMU_REG_DUMP_BASE_SIZE      (ARRAYSIZE(pmuregsdump) * 2u * sizeof(uint32))
8386 #define SI_PMU_REG_DUMP_MACRSRC1_SIZE  (ARRAYSIZE(pmuregsdump_mac_res1) * 2u * sizeof(uint32))
8387 #define SI_PMU_REG_DUMP_MACRSRC2_SIZE  (ARRAYSIZE(pmuregsdump_mac_res2) * 2u * sizeof(uint32))
8388 #define SI_PMU_REG_DUMP_INTRCV1_SIZE   (ARRAYSIZE(pmuregsdump_pmu_int1) * 2u * sizeof(uint32))
8389 
8390 static uint32 *rodata_pmuregdump_ptr = NULL;
8391 
8392 /** size of the buffer needed to store the PMU register dump specifically PMU indirect registers */
8393 uint32
BCMATTACHFN(si_pmu_dump_buf_size_pmucap)8394 BCMATTACHFN(si_pmu_dump_buf_size_pmucap)(si_t *sih)
8395 {
8396 	uint32 buf_size = 0;
8397 	uint32 pmu_size = 0;
8398 	uint32 cnt;
8399 
8400 	if (PMUREV(sih->pmurev) < 5)
8401 		return 0;
8402 
8403 	/* pmu resources resource mask and resource updown */
8404 	cnt = (sih->pmucaps & PCAP_RC_MASK) >> PCAP_RC_SHIFT;
8405 	if (cnt) {
8406 		buf_size += (cnt * 2 * sizeof(uint32)) + PMUCAP_DUMP_TAG_SIZE_BYTES;
8407 	}
8408 	/* pll controls */
8409 	cnt = (sih->pmucaps & PCAP5_PC_MASK) >> PCAP5_PC_SHIFT;
8410 	if (cnt) {
8411 		buf_size += (cnt * sizeof(uint32)) + PMUCAP_DUMP_TAG_SIZE_BYTES;
8412 	}
8413 
8414 	/* voltage controls */
8415 	cnt = (sih->pmucaps & PCAP5_VC_MASK) >> PCAP5_VC_SHIFT;
8416 	if (cnt) {
8417 		buf_size += (cnt * sizeof(uint32)) + PMUCAP_DUMP_TAG_SIZE_BYTES;
8418 	}
8419 
8420 	/* chip controls */
8421 	cnt = (sih->pmucaps & PCAP5_CC_MASK) >> PCAP5_CC_SHIFT;
8422 	if (cnt) {
8423 		buf_size += (cnt * sizeof(uint32)) + PMUCAP_DUMP_TAG_SIZE_BYTES;
8424 	}
8425 
8426 	/* include chip common regsiters from the list */
8427 	/* cnt indicates how many registers, tag_id 0 will say these are address/value */
8428 	if (ARRAYSIZE(chipc_regs_to_dump)) {
8429 		buf_size += PMUCAP_DUMP_TAG_SIZE_BYTES;
8430 		/* address/value pairs */
8431 		buf_size += sizeof(chipc_regs_to_dump);
8432 		buf_size += sizeof(chipc_regs_to_dump);
8433 	}
8434 
8435 	/* include PMU regsiters from the list 'pmuregsdumpXX' */
8436 	if ((PMUREV(sih->pmurev) > 27) && ARRAYSIZE(pmuregsdump) != 0) {
8437 		uint8 rsrc_cnt = si_pmu_get_mac_rsrc_req_tmr_cnt(sih);
8438 		buf_size += PMUCAP_DUMP_TAG_SIZE_BYTES;
8439 		pmu_size += sizeof(pmuregsdump);
8440 		if (ARRAYSIZE(pmuregsdump_mac_res1) != 0 && rsrc_cnt > 1) {
8441 			buf_size += PMUCAP_DUMP_TAG_SIZE_BYTES;
8442 			pmu_size += sizeof(pmuregsdump_mac_res1);
8443 		}
8444 		if (ARRAYSIZE(pmuregsdump_mac_res2) != 0 && rsrc_cnt > 2) {
8445 			buf_size += PMUCAP_DUMP_TAG_SIZE_BYTES;
8446 			pmu_size += sizeof(pmuregsdump_mac_res2);
8447 		}
8448 		if (ARRAYSIZE(pmuregsdump_pmu_int1) != 0 &&
8449 			si_pmu_get_pmu_interrupt_rcv_cnt(sih) > 1) {
8450 			buf_size += PMUCAP_DUMP_TAG_SIZE_BYTES;
8451 			pmu_size += sizeof(pmuregsdump_pmu_int1);
8452 		}
8453 		/* address/value pairs */
8454 		buf_size += (pmu_size << 1);
8455 	}
8456 
8457 	return buf_size;
8458 }
8459 
8460 /**
8461  * routine to dump the registers into the user specified buffer
8462  * needed to store the PMU register dump specifically PMU indirect registers
8463  * format is sets of count, base regiser, register values
8464 */
8465 uint32
BCMPOSTTRAPFN(si_pmu_dump_pmucap_binary)8466 BCMPOSTTRAPFN(si_pmu_dump_pmucap_binary)(si_t *sih, uchar *p)
8467 {
8468 	uint32 cnt, i;
8469 	osl_t *osh;
8470 	pmuregs_t *pmu;
8471 	uint origidx;
8472 	uint mac_res_cnt;
8473 	uint pmu_int_rcv_cnt;
8474 	uint32 pmu_totalsize = 0;
8475 
8476 	uint32 *p32 = (uint32 *)p;
8477 
8478 	if (PMUREV(sih->pmurev) < 5)
8479 		return 0;
8480 
8481 	origidx = si_coreidx(sih);
8482 
8483 	if (AOB_ENAB(sih)) {
8484 		pmu = si_setcore(sih, PMU_CORE_ID, 0);
8485 	}
8486 	else {
8487 		pmu = si_setcoreidx(sih, SI_CC_IDX);
8488 	}
8489 	ASSERT(pmu != NULL);
8490 
8491 	osh = si_osh(sih);
8492 
8493 	cnt = (sih->pmucaps & PCAP_RC_MASK) >> PCAP_RC_SHIFT;
8494 	if (cnt) {
8495 		*p32++ = (cnt << 16 | RSRCTABLEADDR);
8496 		for (i = 0; i < cnt; i++) {
8497 			W_REG(osh, &pmu->res_table_sel, i);
8498 			*p32++ = R_REG(osh, &pmu->res_dep_mask);
8499 			*p32++ = R_REG(osh, &pmu->res_updn_timer);
8500 		}
8501 	}
8502 
8503 	cnt = (sih->pmucaps & PCAP5_PC_MASK) >> PCAP5_PC_SHIFT;
8504 	if (cnt) {
8505 		*p32++ = (cnt << 16 | PMU_PLL_CONTROL_ADDR);
8506 		for (i = 0; i < cnt; i++) {
8507 			*p32++ = si_pmu_pllcontrol(sih, i, 0, 0);
8508 		}
8509 	}
8510 
8511 	cnt = (sih->pmucaps & PCAP5_VC_MASK) >> PCAP5_VC_SHIFT;
8512 	if (cnt) {
8513 		*p32++ = (cnt << 16 | PMU_REG_CONTROL_ADDR);
8514 		for (i = 0; i < cnt; i++) {
8515 			*p32++ = si_pmu_vreg_control(sih, i, 0, 0);
8516 		}
8517 	}
8518 	cnt = (sih->pmucaps & PCAP5_CC_MASK) >> PCAP5_CC_SHIFT;
8519 	if (cnt) {
8520 		*p32++ = (cnt << 16 | CC_CHIPCTL_ADDR);
8521 		for (i = 0; i < cnt; i++) {
8522 			*p32++ = si_pmu_chipcontrol(sih, i, 0, 0);
8523 		}
8524 	}
8525 	if (ARRAYSIZE(chipc_regs_to_dump)) {
8526 		uint32 *addr;
8527 		*p32++ = (ARRAYSIZE(chipc_regs_to_dump) << 16 | 0);
8528 		for (i = 0; i < ARRAYSIZE(chipc_regs_to_dump); i++) {
8529 			addr = (uint32 *)(SI_ENUM_BASE(sih) + chipc_regs_to_dump[i]);
8530 			*p32++ = (uint32)addr;
8531 			*p32++ = R_REG(osh, addr);
8532 		}
8533 	}
8534 
8535 	if ((PMUREV(sih->pmurev) > 27)) {
8536 		volatile uint32 *addr;
8537 		*p32++ = (ARRAYSIZE(pmuregsdump) << 16 | 1);
8538 		for (i = 0; i < ARRAYSIZE(pmuregsdump); i++) {
8539 			addr = (volatile uint32*)((volatile char*)pmu + pmuregsdump[i]);
8540 			*p32++ = (uint32)addr;
8541 			*p32++ = R_REG(osh, addr);
8542 		}
8543 		pmu_totalsize += (ARRAYSIZE(pmuregsdump));
8544 		mac_res_cnt = si_pmu_get_mac_rsrc_req_tmr_cnt(sih);
8545 		if (mac_res_cnt > 1) {
8546 			*p32++ = (ARRAYSIZE(pmuregsdump_mac_res1) << 16 | 1);
8547 			for (i = 0; i < ARRAYSIZE(pmuregsdump_mac_res1); i++) {
8548 				addr = (volatile uint32*)((volatile char*)pmu +
8549 						pmuregsdump_mac_res1[i]);
8550 				*p32++ = (uint32)addr;
8551 				*p32++ = R_REG(osh, addr);
8552 			}
8553 			pmu_totalsize += (ARRAYSIZE(pmuregsdump_mac_res1));
8554 		}
8555 		if (mac_res_cnt > 2) {
8556 			*p32++ = (ARRAYSIZE(pmuregsdump_mac_res2) << 16 | 1);
8557 			for (i = 0; i < ARRAYSIZE(pmuregsdump_mac_res2); i++) {
8558 				addr = (volatile uint32*)((volatile char*)pmu +
8559 						pmuregsdump_mac_res2[i]);
8560 				*p32++ = (uint32)addr;
8561 				*p32++ = R_REG(osh, addr);
8562 			}
8563 			pmu_totalsize += (ARRAYSIZE(pmuregsdump_mac_res2));
8564 		}
8565 		pmu_int_rcv_cnt = si_pmu_get_pmu_interrupt_rcv_cnt(sih);
8566 		if (pmu_int_rcv_cnt > 1) {
8567 			*p32++ = (ARRAYSIZE(pmuregsdump_pmu_int1) << 16 | 1);
8568 			for (i = 0; i < ARRAYSIZE(pmuregsdump_pmu_int1); i++) {
8569 				addr = (volatile uint32*)((volatile char*)pmu +
8570 						pmuregsdump_pmu_int1[i]);
8571 				*p32++ = (uint32)addr;
8572 				*p32++ = R_REG(osh, addr);
8573 			}
8574 			pmu_totalsize += (ARRAYSIZE(pmuregsdump_pmu_int1));
8575 		}
8576 		/* Mark the location where these registers are dumped  to avoid a re-read in
8577 		 * trap context.
8578 		 */
8579 		rodata_pmuregdump_ptr = (p32 - (2 * pmu_totalsize));
8580 	}
8581 
8582 	/* Return to original core */
8583 	si_setcoreidx(sih, origidx);
8584 	return 1;
8585 } /* si_pmu_dump_pmucap_binary */
8586 
8587 #endif /* DONGLEBUILD */
8588 /**
8589  * Function to enable the min_mask with specified resources along with its dependencies.
8590  * Also it can be used for bringing back to the default value of the device.
8591  */
8592 int
si_pmu_min_res_set(si_t * sih,osl_t * osh,uint min_mask,bool set)8593 si_pmu_min_res_set(si_t *sih, osl_t *osh, uint min_mask, bool set)
8594 {
8595 	uint32 min_res, max_res;
8596 	uint origidx;
8597 	bcm_int_bitmask_t intr_val;
8598 	pmuregs_t *pmu;
8599 
8600 	/* Block ints and save current core */
8601 	si_introff(sih, &intr_val);
8602 
8603 	/* Remember original core before switch to chipc */
8604 	origidx = si_coreidx(sih);
8605 	if (AOB_ENAB(sih)) {
8606 		pmu = si_setcore(sih, PMU_CORE_ID, 0);
8607 	} else {
8608 		pmu = si_setcoreidx(sih, SI_CC_IDX);
8609 	}
8610 	ASSERT(pmu != NULL);
8611 
8612 	si_pmu_res_masks(sih, &min_res, &max_res);
8613 	min_mask |= si_pmu_res_deps(sih, osh, pmu, min_mask, TRUE);
8614 
8615 	/*
8616 	 * If set is enabled, the resources specified in the min_mask is brought up. If not set,
8617 	 * go to the default min_resource of the device.
8618 	 */
8619 	if (set) {
8620 		OR_REG(osh, &pmu->min_res_mask, min_mask);
8621 	} else {
8622 		min_mask &= ~min_res;
8623 		AND_REG(osh, &pmu->min_res_mask, ~min_mask);
8624 	}
8625 
8626 	si_pmu_wait_for_steady_state(sih, osh, pmu);
8627 
8628 	/* Return to original core */
8629 	si_setcoreidx(sih, origidx);
8630 	si_intrrestore(sih, &intr_val);
8631 
8632 	return min_mask;
8633 }
8634 
8635 void
si_pmu_bt_ldo_pu(si_t * sih,bool up)8636 si_pmu_bt_ldo_pu(si_t *sih, bool up)
8637 {
8638 	si_pmu_regcontrol(sih, PMU_VREG_6, PMU_28NM_VREG6_BTLDO3P3_PU,
8639 		(up == TRUE) ? PMU_28NM_VREG6_BTLDO3P3_PU : 0x00);
8640 }
8641 
8642 #ifdef BCM_LDO3P3_SOFTSTART
si_pmu_ldo3p3_soft_start_wl_get(si_t * sih,osl_t * osh,int * res)8643 int si_pmu_ldo3p3_soft_start_wl_get(si_t *sih, osl_t *osh, int *res)
8644 {
8645 	uint32 bt_or_wl = 0u;
8646 	return si_pmu_ldo3p3_soft_start_get(sih, osh, bt_or_wl, res);
8647 }
8648 
si_pmu_ldo3p3_soft_start_bt_get(si_t * sih,osl_t * osh,int * res)8649 int si_pmu_ldo3p3_soft_start_bt_get(si_t *sih, osl_t *osh, int *res)
8650 {
8651 	uint32 bt_or_wl = 1u;
8652 	return si_pmu_ldo3p3_soft_start_get(sih, osh, bt_or_wl, res);
8653 }
8654 
8655 static int
si_pmu_soft_start_params(si_t * sih,uint32 bt_or_wl,uint * en_reg,uint32 * en_shift,uint32 * en_mask,uint32 * en_val,uint * val_reg,uint32 * val_shift,uint32 * val_mask)8656 si_pmu_soft_start_params(si_t *sih, uint32 bt_or_wl, uint *en_reg, uint32 *en_shift,
8657 	uint32 *en_mask, uint32 *en_val, uint *val_reg, uint32 *val_shift, uint32 *val_mask)
8658 {
8659 	switch (CHIPID(sih->chip)) {
8660 		case BCM4369_CHIP_GRPID:
8661 			*en_reg = SOFT_START_EN_REG_4369;
8662 			*en_shift = SOFT_START_EN_SHIFT_4369(bt_or_wl);
8663 			*en_mask = SOFT_START_EN_MASK_4369;
8664 			*en_val = SOFT_START_EN_VALUE_4369;
8665 			*val_reg = SLEW_RATE_VALUE_REG_4369;
8666 			*val_shift = SLEW_RATE_SHIFT_4369(bt_or_wl);
8667 			*val_mask = SLEW_RATE_MASK_4369;
8668 			break;
8669 		case BCM4376_CHIP_GRPID:
8670 		case BCM4378_CHIP_GRPID:
8671 			*en_reg = SOFT_START_EN_REG_4378;
8672 			*en_shift = SOFT_START_EN_SHIFT_4378(bt_or_wl);
8673 			*en_mask = SOFT_START_EN_MASK_4378;
8674 			*en_val = SOFT_START_EN_VALUE_4378;
8675 			*val_reg = SLEW_RATE_VALUE_REG_4378;
8676 			*val_shift = SLEW_RATE_SHIFT_4378(bt_or_wl);
8677 			*val_mask = SLEW_RATE_MASK_4378;
8678 			if (BCM4378_CHIP(sih->chip) && PMUREV(sih->pmurev) == 37) {
8679 				*en_val = SOFT_START_EN_VALUE_4378_REV37;
8680 			}
8681 			break;
8682 		case BCM4387_CHIP_GRPID:
8683 			if (bt_or_wl == 0) {
8684 				return BCME_UNSUPPORTED;
8685 			}
8686 			*en_reg = SOFT_START_EN_REG_4387;
8687 			*en_shift = SOFT_START_EN_SHIFT_4387(bt_or_wl);
8688 			*en_mask = SOFT_START_EN_MASK_4387;
8689 			*en_val = SOFT_START_EN_VALUE_4387;
8690 			*val_reg = SLEW_RATE_VALUE_REG_4387;
8691 			*val_shift = SLEW_RATE_SHIFT_4387(bt_or_wl);
8692 			*val_mask = SLEW_RATE_MASK_4387;
8693 			break;
8694 		default:
8695 			/* Add support */
8696 			ASSERT(0);
8697 			break;
8698 	}
8699 	return BCME_OK;
8700 }
8701 
si_pmu_ldo3p3_soft_start_get(si_t * sih,osl_t * osh,uint32 bt_or_wl,int * res)8702 static int si_pmu_ldo3p3_soft_start_get(si_t *sih, osl_t *osh, uint32 bt_or_wl, int *res)
8703 {
8704 	uint en_reg = 0, val_reg = 0;
8705 	uint32 en_shift = 0, en_mask = 0, en_val = 0, val_shift = 0, val_mask = 0;
8706 	uint32 soft_start_en, slew_rate;
8707 	int ret = si_pmu_soft_start_params(sih, bt_or_wl, &en_reg, &en_shift, &en_mask, &en_val,
8708 		&val_reg, &val_shift, &val_mask);
8709 
8710 	if (BCME_OK != ret) {
8711 		return ret;
8712 	}
8713 	soft_start_en = (si_pmu_vreg_control(sih, en_reg, 0, 0) >> en_shift);
8714 	soft_start_en &= en_mask;
8715 	if (en_val == 0u) {
8716 		soft_start_en = !soft_start_en;
8717 	}
8718 	if (soft_start_en) {
8719 		slew_rate = (si_pmu_vreg_control(sih, val_reg, 0, 0) >> val_shift);
8720 		slew_rate &= val_mask;
8721 		*res = slew_rate;
8722 	} else {
8723 		*res =  -1;
8724 	}
8725 	return BCME_OK;
8726 }
8727 
si_pmu_ldo3p3_soft_start_wl_set(si_t * sih,osl_t * osh,uint32 slew_rate)8728 int si_pmu_ldo3p3_soft_start_wl_set(si_t *sih, osl_t *osh, uint32 slew_rate)
8729 {
8730 	uint32 bt_or_wl = 0u;
8731 	return si_pmu_ldo3p3_soft_start_set(sih, osh, bt_or_wl, slew_rate);
8732 }
8733 
si_pmu_ldo3p3_soft_start_bt_set(si_t * sih,osl_t * osh,uint32 slew_rate)8734 int si_pmu_ldo3p3_soft_start_bt_set(si_t *sih, osl_t *osh, uint32 slew_rate)
8735 {
8736 	uint32 bt_or_wl = 1u;
8737 	return si_pmu_ldo3p3_soft_start_set(sih, osh, bt_or_wl, slew_rate);
8738 }
8739 
si_pmu_ldo3p3_soft_start_set(si_t * sih,osl_t * osh,uint32 bt_or_wl,uint32 slew_rate)8740 static int si_pmu_ldo3p3_soft_start_set(si_t *sih, osl_t *osh, uint32 bt_or_wl, uint32 slew_rate)
8741 {
8742 	uint en_reg = 0, val_reg = 0;
8743 	uint32 en_shift = 0, en_mask = 0, en_val = 0, val_shift = 0, val_mask = 0;
8744 	int ret = si_pmu_soft_start_params(sih, bt_or_wl, &en_reg, &en_shift, &en_mask, &en_val,
8745 		&val_reg, &val_shift, &val_mask);
8746 	uint32 dis_val = en_val ? 0u : 1u;
8747 
8748 	if (BCME_OK != ret) {
8749 		return ret;
8750 	}
8751 
8752 	if (slew_rate != (uint32)(~0u)) {
8753 
8754 		/* Without disabling soft start bit
8755 		 * programming a new slew rate value
8756 		 * doesn't take effect
8757 		 */
8758 
8759 		/* Disable soft start */
8760 		si_pmu_vreg_control(sih, en_reg, (en_mask << en_shift), (dis_val << en_shift));
8761 
8762 		/* Program Slew rate */
8763 		si_pmu_vreg_control(sih, val_reg, (val_mask << val_shift),
8764 			((slew_rate & val_mask) << val_shift));
8765 
8766 		/* Enable Soft start */
8767 		si_pmu_vreg_control(sih, en_reg, (en_mask << en_shift), (en_val << en_shift));
8768 	} else {
8769 		/* Slew rate value of 0xFFFF is used as a special value
8770 		 * to disable/reset soft start feature
8771 		 */
8772 
8773 		/* Disable soft start */
8774 		si_pmu_vreg_control(sih, en_reg, (en_mask << en_shift), (dis_val << en_shift));
8775 
8776 		/* Set slew rate value to zero */
8777 		si_pmu_vreg_control(sih, val_reg, (val_mask << val_shift), 0u);
8778 	}
8779 	return BCME_OK;
8780 }
8781 #endif /* BCM_LDO3P3_SOFTSTART */
8782 
8783 #ifdef LDO3P3_MIN_RES_MASK
8784 static bool ldo3p3_min_res_enabled = FALSE;
8785 /** Set ldo 3.3V mask in the min resources mask register */
8786 int
si_pmu_min_res_ldo3p3_set(si_t * sih,osl_t * osh,bool on)8787 si_pmu_min_res_ldo3p3_set(si_t *sih, osl_t *osh, bool on)
8788 {
8789 	uint32 min_mask = 0;
8790 	uint coreidx = si_findcoreidx(sih, GCI_CORE_ID, 0);
8791 
8792 	switch (CHIPID(sih->chip)) {
8793 		case BCM4369_CHIP_GRPID:
8794 		case BCM4362_CHIP_GRPID:
8795 			min_mask = PMURES_BIT(RES4369_LDO3P3_PU);
8796 			if (on) {
8797 				si_corereg(sih, coreidx, LHL_REG_OFF(lhl_lp_main_ctl1_adr),
8798 						BCM_MASK32(23, 0), 0x9E9F9F);
8799 			} else {
8800 				si_corereg(sih, coreidx, LHL_REG_OFF(lhl_lp_main_ctl1_adr),
8801 						BCM_MASK32(23, 0), 0x9E9F97);
8802 			}
8803 			break;
8804 		case BCM4376_CHIP_GRPID:
8805 		case BCM4378_CHIP_GRPID:
8806 			min_mask = PMURES_BIT(RES4378_LDO3P3_PU);
8807 			break;
8808 		default:
8809 			return BCME_UNSUPPORTED;
8810 	}
8811 
8812 	si_pmu_min_res_set(sih, osh, min_mask, on);
8813 	ldo3p3_min_res_enabled = on;
8814 
8815 	return BCME_OK;
8816 }
8817 
8818 int
si_pmu_min_res_ldo3p3_get(si_t * sih,osl_t * osh,int * res)8819 si_pmu_min_res_ldo3p3_get(si_t *sih, osl_t *osh, int *res)
8820 {
8821 	*res = (int)ldo3p3_min_res_enabled;
8822 	return BCME_OK;
8823 }
8824 #endif /* LDO3P3_MIN_RES_MASK */
8825 int
si_pmu_min_res_otp_pu_set(si_t * sih,osl_t * osh,bool on)8826 si_pmu_min_res_otp_pu_set(si_t *sih, osl_t *osh, bool on)
8827 {
8828 	uint32 min_mask = 0;
8829 	rsc_per_chip_t *rsc;
8830 
8831 	rsc = si_pmu_get_rsc_positions(sih);
8832 	if (rsc) {
8833 		min_mask = PMURES_BIT(rsc->otp_pu);
8834 	} else {
8835 		return BCME_UNSUPPORTED;
8836 	}
8837 	si_pmu_min_res_set(sih, osh, min_mask, on);
8838 	return BCME_OK;
8839 }
8840 #endif /* !defined(BCMDONGLEHOST) */
8841 
8842 uint32
BCMPOSTTRAPFN(si_pmu_wake_bit_offset)8843 BCMPOSTTRAPFN(si_pmu_wake_bit_offset)(si_t *sih)
8844 {
8845 	uint32 wakebit;
8846 
8847 	switch (CHIPID(sih->chip)) {
8848 	case BCM4369_CHIP_GRPID:
8849 		wakebit = PMU_CC2_GCI2_WAKE;
8850 		break;
8851 	case BCM4376_CHIP_GRPID:
8852 	case BCM4378_CHIP_GRPID:
8853 		wakebit = CC2_4378_GCI2WAKE_MASK;
8854 		break;
8855 	case BCM4385_CHIP_GRPID:
8856 	case BCM4387_CHIP_GRPID:
8857 		wakebit = CC2_4387_GCI2WAKE_MASK;
8858 		break;
8859 	case BCM4388_CHIP_GRPID:
8860 	case BCM4389_CHIP_GRPID:
8861 	case BCM4397_CHIP_GRPID:
8862 		wakebit = CC2_4389_GCI2WAKE_MASK;
8863 		break;
8864 	default:
8865 		wakebit = 0;
8866 		ASSERT(0);
8867 		break;
8868 	}
8869 
8870 	return wakebit;
8871 }
8872 
8873 #ifdef ATE_BUILD
hnd_pmu_clr_int_sts_req_active(osl_t * hnd_osh,si_t * sih)8874 void hnd_pmu_clr_int_sts_req_active(osl_t *hnd_osh, si_t *sih)
8875 {
8876 	uint32 res_req_timer;
8877 	pmuregs_t *pmu;
8878 	if (AOB_ENAB(sih)) {
8879 		pmu = si_setcore(sih, PMU_CORE_ID, 0);
8880 	} else {
8881 		pmu = si_setcoreidx(sih, SI_CC_IDX);
8882 	}
8883 	ASSERT(pmu != NULL);
8884 	W_REG(hnd_osh, &pmu->pmuintstatus,
8885 		RSRC_INTR_MASK_TIMER_INT_0);
8886 	(void)R_REG(hnd_osh, &pmu->pmuintstatus);
8887 	res_req_timer = R_REG(hnd_osh, &pmu->res_req_timer);
8888 	W_REG(hnd_osh, &pmu->res_req_timer,
8889 			res_req_timer & ~(PRRT_REQ_ACTIVE << flags_shift));
8890 	(void)R_REG(hnd_osh, &pmu->res_req_timer);
8891 }
8892 #endif /* ATE_BUILD */
8893 
si_pmu_set_min_res_mask(si_t * sih,osl_t * osh,uint min_res_mask)8894 void si_pmu_set_min_res_mask(si_t *sih, osl_t *osh, uint min_res_mask)
8895 {
8896 	pmuregs_t *pmu;
8897 	uint origidx;
8898 
8899 	/* Remember original core before switch to chipc/pmu */
8900 	origidx = si_coreidx(sih);
8901 	if (AOB_ENAB(sih)) {
8902 		pmu = si_setcore(sih, PMU_CORE_ID, 0);
8903 	}
8904 	else {
8905 		pmu = si_setcoreidx(sih, SI_CC_IDX);
8906 	}
8907 	ASSERT(pmu != NULL);
8908 
8909 	W_REG(osh, &pmu->min_res_mask, min_res_mask);
8910 	OSL_DELAY(100);
8911 
8912 	/* Return to original core */
8913 	si_setcoreidx(sih, origidx);
8914 }
8915 
8916 bool
si_pmu_cap_fast_lpo(si_t * sih)8917 si_pmu_cap_fast_lpo(si_t *sih)
8918 {
8919 	return (PMU_REG(sih, core_cap_ext, 0, 0) & PCAP_EXT_USE_MUXED_ILP_CLK_MASK) ? TRUE : FALSE;
8920 }
8921 
8922 int
si_pmu_fast_lpo_disable(si_t * sih)8923 si_pmu_fast_lpo_disable(si_t *sih)
8924 {
8925 	if (!si_pmu_cap_fast_lpo(sih)) {
8926 		PMU_ERROR(("si_pmu_fast_lpo_disable: No Fast LPO capability\n"));
8927 		return BCME_ERROR;
8928 	}
8929 
8930 	PMU_REG(sih, pmucontrol_ext,
8931 		PCTL_EXT_FASTLPO_ENAB |
8932 		PCTL_EXT_FASTLPO_SWENAB |
8933 		PCTL_EXT_FASTLPO_PCIE_SWENAB,
8934 		0);
8935 	OSL_DELAY(1000);
8936 	return BCME_OK;
8937 }
8938 
8939 /*
8940 * 4389B0/C0 - WL and BT turn on WAR,
8941 * set below bits in PMU chip control 6
8942 * - global bit[195] / bit[3] - enable legacy pmu_wakeup to make
8943 * domain 1 (WL) power request
8944 * - global bit[206] / bit[14] - perst_wake_en
8945 */
8946 void
si_pmu_dmn1_perst_wakeup(si_t * sih,bool set)8947 si_pmu_dmn1_perst_wakeup(si_t *sih, bool set)
8948 {
8949 	if (PMUREV(sih->pmurev) == 40) {
8950 		if (set) {
8951 			si_pmu_chipcontrol(sih, PMU_CHIPCTL6,
8952 				(PMU_CC6_ENABLE_DMN1_WAKEUP |
8953 				PMU_CC6_ENABLE_PMU_WAKEUP_PERST),
8954 				(PMU_CC6_ENABLE_DMN1_WAKEUP |
8955 				PMU_CC6_ENABLE_PMU_WAKEUP_PERST));
8956 		} else {
8957 			si_pmu_chipcontrol(sih, PMU_CHIPCTL6,
8958 				(PMU_CC6_ENABLE_DMN1_WAKEUP |
8959 				PMU_CC6_ENABLE_PMU_WAKEUP_PERST),
8960 				0);
8961 		}
8962 	}
8963 }
8964 
8965 #if !defined(BCMDONGLEHOST)
8966 
8967 /* write :
8968  *   TRUE - Programs the PLLCTRL6 with xtal and returns value written in pllctrl6 register.
8969  *   FALSE - returns 0 if xtal programming is same as pllctrl6 register else retruns value of
8970  *   pllctrl6 val. This will not program any register.
8971  */
8972 static uint32
si_pmu_pll6val_armclk_calc(osl_t * osh,pmuregs_t * pmu,uint32 armclk,uint32 xtal,bool write)8973 si_pmu_pll6val_armclk_calc(osl_t *osh, pmuregs_t *pmu, uint32 armclk, uint32 xtal, bool write)
8974 {
8975 	uint32 q, r;
8976 	uint32 xtal_scale;
8977 	uint32 pll6val;
8978 	if (armclk == 0 || xtal == 0) {
8979 		PMU_ERROR((" si_pmu_pll6val_armclk_calc: invalid armclk = %d or xtal = %d\n",
8980 			armclk, xtal));
8981 		return 0;
8982 	}
8983 	q = (armclk * 1000 * PMU4369_PLL6VAL_P1DIV) / xtal;
8984 	xtal_scale = xtal / 100;
8985 	r = ((armclk * 10 * PMU4369_PLL6VAL_P1DIV * PMU4369_PLL6VAL_PRE_SCALE) / xtal_scale) -
8986 		(q * PMU4369_PLL6VAL_PRE_SCALE);
8987 	r *= PMU4369_PLL6VAL_POST_SCALE;
8988 
8989 	pll6val = (r << PMU4369_PLL1_PC6_NDIV_FRAC_SHIFT) |
8990 		(q << PMU4369_PLL1_PC6_NDIV_INT_SHIFT) | PMU4369_PLL6VAL_P1DIV_BIT3_2;
8991 
8992 	PMU_MSG(("si_pmu_pll6val_armclk_calc, armclk %d, xtal %d, q %d, r 0x%8x, pll6val 0x%8x\n",
8993 		armclk, xtal, q, r, pll6val));
8994 
8995 	if (write) {
8996 		W_REG(osh, &pmu->pllcontrol_addr, PMU1_PLL0_PLLCTL6);
8997 		W_REG(osh, &pmu->pllcontrol_data, pll6val);
8998 	} else {
8999 		W_REG(osh, &pmu->pllcontrol_addr, PMU1_PLL0_PLLCTL6);
9000 		if (pll6val == R_REG(osh, &pmu->pllcontrol_data))
9001 			return 0;
9002 	}
9003 
9004 	return pll6val;
9005 }
9006 
9007 static void
BCMATTACHFN(si_pmu_chipcontrol_xtal_settings_4369)9008 BCMATTACHFN(si_pmu_chipcontrol_xtal_settings_4369)(si_t *sih)
9009 {
9010 
9011 /* 4369 XTAL Bias settings */
9012 /*
9013 	Reg name		startup		Normal
9014 	xtal_bias_adj		0xFF		0x1A
9015 	xtal_coresize_nmos	0x3f		0x3f
9016 	xtal_coresize_pmos	0x3f		0x3f
9017 	xtal_sel_bias_res	0x2		0x6
9018 	xt_res_bypass		0x0		0x1
9019 */
9020 	uint32 u32Val;
9021 	uint32 u32Mask;
9022 	u32Val = (PMU_CC0_4369B0_XTALCORESIZE_BIAS_ADJ_NORMAL_VAL |
9023 		PMU_CC0_4369_XTAL_RES_BYPASS_NORMAL_VAL);
9024 
9025 	u32Mask = (PMU_CC0_4369_XTALCORESIZE_BIAS_ADJ_NORMAL_MASK |
9026 		PMU_CC0_4369_XTAL_RES_BYPASS_NORMAL_MASK);
9027 
9028 	si_pmu_chipcontrol(sih, PMU_CHIPCTL0, u32Mask, u32Val);
9029 
9030 	u32Val = (PMU_CC2_4369_XTALCORESIZE_BIAS_ADJ_NORMAL_VAL);
9031 	u32Mask = (PMU_CC2_4369_XTALCORESIZE_BIAS_ADJ_NORMAL_MASK);
9032 	si_pmu_chipcontrol(sih, PMU_CHIPCTL2, u32Mask, u32Val);
9033 
9034 	u32Val = (PMU_CC3_4369_XTALCORESIZE_PMOS_NORMAL_VAL |
9035 		PMU_CC3_4369_XTALCORESIZE_NMOS_NORMAL_VAL |
9036 		PMU_CC3_4369_XTALSEL_BIAS_RES_NORMAL_VAL);
9037 
9038 	u32Mask = (PMU_CC3_4369_XTALCORESIZE_PMOS_NORMAL_MASK |
9039 		PMU_CC3_4369_XTALCORESIZE_NMOS_NORMAL_MASK |
9040 		PMU_CC3_4369_XTALSEL_BIAS_RES_NORMAL_MASK);
9041 
9042 	si_pmu_chipcontrol(sih, PMU_CHIPCTL3, u32Mask, u32Val);
9043 
9044 }
9045 
9046 static void
BCMATTACHFN(si_pmu_chipcontrol_xtal_settings_4362)9047 BCMATTACHFN(si_pmu_chipcontrol_xtal_settings_4362)(si_t *sih)
9048 {
9049 	/* 4369 XTAL Bias settings */
9050 	/*
9051 		Reg name		startup		Normal
9052 		xtal_bias_adj		0xFF		0x1A
9053 		xtal_coresize_nmos	0x3f		0x3f
9054 		xtal_coresize_pmos	0x3f		0x3f
9055 		xtal_sel_bias_res	0x2		0x6
9056 		xt_res_bypass		0x0		0x1
9057 	*/
9058 	uint32 u32Val;
9059 	uint32 u32Mask;
9060 	u32Val = (PMU_CC0_4362_XTALCORESIZE_BIAS_ADJ_NORMAL_VAL |
9061 		PMU_CC0_4362_XTAL_RES_BYPASS_NORMAL_VAL);
9062 
9063 	u32Mask = (PMU_CC0_4362_XTALCORESIZE_BIAS_ADJ_NORMAL_MASK |
9064 		PMU_CC0_4362_XTAL_RES_BYPASS_NORMAL_MASK);
9065 
9066 	si_pmu_chipcontrol(sih, PMU_CHIPCTL0, u32Mask, u32Val);
9067 
9068 	u32Val = (PMU_CC2_4362_XTALCORESIZE_BIAS_ADJ_NORMAL_VAL);
9069 	u32Mask = (PMU_CC2_4362_XTALCORESIZE_BIAS_ADJ_NORMAL_MASK);
9070 	si_pmu_chipcontrol(sih, PMU_CHIPCTL2, u32Mask, u32Val);
9071 
9072 	u32Val = (PMU_CC3_4362_XTALCORESIZE_PMOS_NORMAL_VAL |
9073 		PMU_CC3_4362_XTALCORESIZE_NMOS_NORMAL_VAL |
9074 		PMU_CC3_4362_XTALSEL_BIAS_RES_NORMAL_VAL);
9075 
9076 	u32Mask = (PMU_CC3_4362_XTALCORESIZE_PMOS_NORMAL_MASK |
9077 		PMU_CC3_4362_XTALCORESIZE_NMOS_NORMAL_MASK |
9078 		PMU_CC3_4362_XTALSEL_BIAS_RES_NORMAL_MASK);
9079 
9080 	si_pmu_chipcontrol(sih, PMU_CHIPCTL3, u32Mask, u32Val);
9081 
9082 }
9083 
9084 /* 4378 based on 4369 XTAL Bias settings
9085  *	Reg name		startup		Normal
9086  *	xtal_bias_adj		0xFF		0x1A
9087  *	xtal_coresize_nmos	0x3f		0x3f
9088  *	xtal_coresize_pmos	0x3f		0x3f
9089  *	xtal_sel_bias_res	0x2		0x2
9090  *	xt_res_bypass		0x0		0x2
9091  */
9092 static void
BCMATTACHFN(si_pmu_chipcontrol_xtal_settings_4378)9093 BCMATTACHFN(si_pmu_chipcontrol_xtal_settings_4378)(si_t *sih)
9094 {
9095 	uint32 u32Val;
9096 	uint32 u32Mask;
9097 	uint16 xtal_bias_adj;
9098 	uint8 xtal_bias_adj_otp = 0, xtal_bias_cal_otp_done = 0;
9099 
9100 #ifdef XTAL_BIAS_FROM_OTP
9101 	/* Read xtal bias cal done bit and xtal biase from OTP */
9102 	si_pmu_chipcontrol_xtal_bias_from_otp(sih, &xtal_bias_cal_otp_done, &xtal_bias_adj_otp);
9103 #endif /* XTAL_BIAS_FROM_OTP */
9104 
9105 	/*
9106 	 * If xtal_bias_cal_done flag is read as non zero, write the xtal biase in PMU control
9107 	 * register from OTP otherwise write the default value of 0x1a.
9108 	 */
9109 	xtal_bias_adj = (uint16)xtal_bias_adj_otp;
9110 	xtal_bias_adj = xtal_bias_cal_otp_done != 0 ? (xtal_bias_adj << 6) :
9111 		PMU_CC0_4378_XTALCORESIZE_BIAS_ADJ_NORMAL_VAL;
9112 
9113 	u32Val = (xtal_bias_adj | PMU_CC0_4378_XTAL_RES_BYPASS_NORMAL_VAL);
9114 
9115 	u32Mask = (PMU_CC0_4378_XTALCORESIZE_BIAS_ADJ_NORMAL_MASK |
9116 		PMU_CC0_4378_XTAL_RES_BYPASS_NORMAL_MASK);
9117 
9118 	si_pmu_chipcontrol(sih, PMU_CHIPCTL0, u32Mask, u32Val);
9119 
9120 	u32Val = (PMU_CC2_4378_XTALCORESIZE_BIAS_ADJ_NORMAL_VAL);
9121 	u32Mask = (PMU_CC2_4378_XTALCORESIZE_BIAS_ADJ_NORMAL_MASK);
9122 	si_pmu_chipcontrol(sih, PMU_CHIPCTL2, u32Mask, u32Val);
9123 
9124 	u32Val = (PMU_CC3_4378_XTALCORESIZE_PMOS_NORMAL_VAL |
9125 		PMU_CC3_4378_XTALCORESIZE_NMOS_NORMAL_VAL |
9126 		PMU_CC3_4378_XTALSEL_BIAS_RES_NORMAL_VAL);
9127 
9128 	u32Mask = (PMU_CC3_4378_XTALCORESIZE_PMOS_NORMAL_MASK |
9129 		PMU_CC3_4378_XTALCORESIZE_NMOS_NORMAL_MASK |
9130 		PMU_CC3_4378_XTALSEL_BIAS_RES_NORMAL_MASK);
9131 
9132 	si_pmu_chipcontrol(sih, PMU_CHIPCTL3, u32Mask, u32Val);
9133 
9134 }
9135 
9136 #ifdef XTAL_BIAS_FROM_OTP
9137 static void
BCMATTACHFN(si_pmu_chipcontrol_xtal_bias_from_otp)9138 BCMATTACHFN(si_pmu_chipcontrol_xtal_bias_from_otp)(si_t *sih, uint8* flag, uint8* val)
9139 {
9140 	uint8 xtal_bias_adj = 0, xtal_bias_cal_otp_done = 0;
9141 #ifndef BCM_OTP_API
9142 	uint16 datum, offset;
9143 	uint8 shift, mask;
9144 #endif /* !BCM_OTP_API */
9145 
9146 	/* Read the XTAL BIAS CAL value from OTP.
9147 	 * 1) Read the xtal cal done bit and the xtal biase value from OTP.
9148 	 * 2) OTP memory is zero by default, so the chips which aren't OTP programmed will read a
9149 	 *   '0' for xtal_bias_cal_otp_done.
9150 	*/
9151 #ifdef BCM_OTP_API
9152 	otp_read_8b_field(sih, BCM_OTP_FLD_XTAL_BIAS_FLAG, &xtal_bias_cal_otp_done);
9153 	if (xtal_bias_cal_otp_done) {
9154 		otp_read_8b_field(sih, BCM_OTP_FLD_XTAL_BIAS_ADJ, &xtal_bias_adj);
9155 	}
9156 #else
9157 	si_pmu_chipcontrol_xtal_bias_cal_done_offsets(sih, &offset, &shift, &mask);
9158 	if (!otp_read_word(sih, offset, &datum)) {
9159 		xtal_bias_cal_otp_done = ((datum >> shift) & mask);
9160 	}
9161 
9162 	si_pmu_chipcontrol_xtal_bias_val_offsets(sih, &offset, &shift, &mask);
9163 	if (xtal_bias_cal_otp_done && (!otp_read_word(sih, offset, &datum)))
9164 	{
9165 		xtal_bias_adj = ((datum >> shift) & mask);
9166 	}
9167 #endif /* BCM_OTP_API */
9168 	*flag = xtal_bias_cal_otp_done;
9169 	*val = xtal_bias_adj;
9170 }
9171 
9172 #ifndef BCM_OTP_API
9173 static void
BCMATTACHFN(si_pmu_chipcontrol_xtal_bias_cal_done_offsets)9174 BCMATTACHFN(si_pmu_chipcontrol_xtal_bias_cal_done_offsets)(si_t *sih, uint16* wrd_offset,
9175 		uint8* wrd_shift, uint8* wrd_mask)
9176 {
9177 	/* Offset is 16 bit aligned address, shift is the starting bit position of the value
9178 	 * mask defines the bitwidth of the value. Each value in the array is for one of the
9179 	 * cores.
9180 	 */
9181 	/* XTAL BIAS CAL done                 11896 */
9182 	switch (CHIPID(sih->chip)) {
9183 		case BCM4376_CHIP_GRPID:
9184 		case BCM4378_CHIP_GRPID:
9185 			*wrd_offset = OTP_XTAL_BIAS_CAL_DONE_4378_WRD_OFFSET;
9186 			*wrd_shift  = OTP_XTAL_BIAS_CAL_DONE_4378_WRD_SHIFT;
9187 			*wrd_mask   = OTP_XTAL_BIAS_CAL_DONE_4378_WRD_MASK;
9188 			break;
9189 		default:
9190 			ASSERT(0);
9191 			break;
9192 	}
9193 }
9194 
9195 static void
BCMATTACHFN(si_pmu_chipcontrol_xtal_bias_val_offsets)9196 BCMATTACHFN(si_pmu_chipcontrol_xtal_bias_val_offsets)(si_t *sih, uint16* wrd_offset,
9197 		uint8* wrd_shift, uint8* wrd_mask)
9198 {
9199 	/* Offset is 16 bit aligned address, shift is the starting bit position of the value
9200 	 * mask defines the bitwidth of the value. Each value in the array is for one of the
9201 	 * cores.
9202 	 */
9203 	/* XTAL BIAS value                    11888 */
9204 	switch (CHIPID(sih->chip)) {
9205 		case BCM4376_CHIP_GRPID:
9206 		case BCM4378_CHIP_GRPID:
9207 			*wrd_offset = OTP_XTAL_BIAS_VAL_4378_WRD_OFFSET;
9208 			*wrd_shift  = OTP_XTAL_BIAS_VAL_4378_WRD_SHIFT;
9209 			*wrd_mask   = OTP_XTAL_BIAS_VAL_4378_WRD_MASK;
9210 			break;
9211 		default:
9212 			ASSERT(0);
9213 			break;
9214 	}
9215 }
9216 #endif /* !BCM_OTP_API */
9217 #endif /* XTAL_BIAS_FROM_OTP */
9218 
9219 #endif /* !BCMDONGLEHOST */
9220 
9221 #ifdef BCMPMU_STATS
9222 /*
9223  * 8 pmu statistics timer default map
9224  *
9225  * for CORE_RDY_AUX measure, set as below for timer 6 and 7 instead of CORE_RDY_MAIN.
9226  *	//core-n active duration : pmu_rsrc_state(CORE_RDY_AUX)
9227  *	{ SRC_CORE_RDY_AUX, FALSE, TRUE, LEVEL_HIGH},
9228  *	//core-n active duration : pmu_rsrc_state(CORE_RDY_AUX)
9229  *	{ SRC_CORE_RDY_AUX, FALSE, TRUE, EDGE_RISE}
9230  */
9231 static pmu_stats_timer_t pmustatstimer[] = {
9232 	{ SRC_LINK_IN_L12, FALSE, TRUE, PMU_STATS_LEVEL_HIGH},	//link_in_l12
9233 	{ SRC_LINK_IN_L23, FALSE, TRUE, PMU_STATS_LEVEL_HIGH},	//link_in_l23
9234 	{ SRC_PM_ST_IN_D0, FALSE, TRUE, PMU_STATS_LEVEL_HIGH},	//pm_st_in_d0
9235 	{ SRC_PM_ST_IN_D3, FALSE, TRUE, PMU_STATS_LEVEL_HIGH},	//pm_st_in_d3
9236 	//deep-sleep duration : pmu_rsrc_state(XTAL_PU)
9237 	{ SRC_XTAL_PU, FALSE, TRUE, PMU_STATS_LEVEL_LOW},
9238 	//deep-sleep entry count : pmu_rsrc_state(XTAL_PU)
9239 	{ SRC_XTAL_PU, FALSE, TRUE, PMU_STATS_EDGE_FALL},
9240 	//core-n active duration : pmu_rsrc_state(CORE_RDY_MAIN)
9241 	{ SRC_CORE_RDY_MAIN, FALSE, TRUE, PMU_STATS_LEVEL_HIGH},
9242 	//core-n active duration : pmu_rsrc_state(CORE_RDY_MAIN)
9243 	{ SRC_CORE_RDY_MAIN, FALSE, TRUE, PMU_STATS_EDGE_RISE}
9244 };
9245 
9246 static void
si_pmustatstimer_update(osl_t * osh,pmuregs_t * pmu,uint8 timerid)9247 si_pmustatstimer_update(osl_t *osh, pmuregs_t *pmu, uint8 timerid)
9248 {
9249 	uint32 stats_timer_ctrl;
9250 
9251 	W_REG(osh, &pmu->pmu_statstimer_addr, timerid);
9252 	stats_timer_ctrl =
9253 		((pmustatstimer[timerid].src_num << PMU_ST_SRC_SHIFT) &
9254 			PMU_ST_SRC_MASK) |
9255 		((pmustatstimer[timerid].cnt_mode << PMU_ST_CNT_MODE_SHIFT) &
9256 			PMU_ST_CNT_MODE_MASK) |
9257 		((pmustatstimer[timerid].enable << PMU_ST_EN_SHIFT) & PMU_ST_EN_MASK) |
9258 		((pmustatstimer[timerid].int_enable << PMU_ST_INT_EN_SHIFT) & PMU_ST_INT_EN_MASK);
9259 	W_REG(osh, &pmu->pmu_statstimer_ctrl, stats_timer_ctrl);
9260 	W_REG(osh, &pmu->pmu_statstimer_N, 0);
9261 }
9262 
9263 void
si_pmustatstimer_int_enable(si_t * sih)9264 si_pmustatstimer_int_enable(si_t *sih)
9265 {
9266 	pmuregs_t *pmu;
9267 	uint origidx;
9268 	osl_t *osh = si_osh(sih);
9269 
9270 	/* Remember original core before switch to chipc/pmu */
9271 	origidx = si_coreidx(sih);
9272 	if (AOB_ENAB(sih)) {
9273 		pmu = si_setcore(sih, PMU_CORE_ID, 0);
9274 	} else {
9275 		pmu = si_setcoreidx(sih, SI_CC_IDX);
9276 	}
9277 	ASSERT(pmu != NULL);
9278 
9279 	OR_REG(osh, &pmu->pmuintmask0, PMU_INT_STAT_TIMER_INT_MASK);
9280 
9281 	/* Return to original core */
9282 	si_setcoreidx(sih, origidx);
9283 }
9284 
9285 void
si_pmustatstimer_int_disable(si_t * sih)9286 si_pmustatstimer_int_disable(si_t *sih)
9287 {
9288 	pmuregs_t *pmu;
9289 	uint origidx;
9290 	osl_t *osh = si_osh(sih);
9291 
9292 	/* Remember original core before switch to chipc/pmu */
9293 	origidx = si_coreidx(sih);
9294 	if (AOB_ENAB(sih)) {
9295 		pmu = si_setcore(sih, PMU_CORE_ID, 0);
9296 	} else {
9297 		pmu = si_setcoreidx(sih, SI_CC_IDX);
9298 	}
9299 	ASSERT(pmu != NULL);
9300 
9301 	AND_REG(osh, &pmu->pmuintmask0, ~PMU_INT_STAT_TIMER_INT_MASK);
9302 
9303 	/* Return to original core */
9304 	si_setcoreidx(sih, origidx);
9305 }
9306 
9307 void
si_pmustatstimer_init(si_t * sih)9308 si_pmustatstimer_init(si_t *sih)
9309 {
9310 	pmuregs_t *pmu;
9311 	uint origidx;
9312 	osl_t *osh = si_osh(sih);
9313 	uint32 core_cap_ext;
9314 	uint8 max_stats_timer_num;
9315 	int8 i;
9316 
9317 	/* Remember original core before switch to chipc/pmu */
9318 	origidx = si_coreidx(sih);
9319 	if (AOB_ENAB(sih)) {
9320 		pmu = si_setcore(sih, PMU_CORE_ID, 0);
9321 	} else {
9322 		pmu = si_setcoreidx(sih, SI_CC_IDX);
9323 	}
9324 	ASSERT(pmu != NULL);
9325 
9326 	core_cap_ext = R_REG(osh, &pmu->core_cap_ext);
9327 
9328 	max_stats_timer_num = ((core_cap_ext & PCAP_EXT_ST_NUM_MASK) >> PCAP_EXT_ST_NUM_SHIFT) + 1;
9329 
9330 	for (i = 0; i < max_stats_timer_num; i++) {
9331 		si_pmustatstimer_update(osh, pmu, i);
9332 	}
9333 
9334 	OR_REG(osh, &pmu->pmuintmask0, PMU_INT_STAT_TIMER_INT_MASK);
9335 
9336 	/* Return to original core */
9337 	si_setcoreidx(sih, origidx);
9338 }
9339 
9340 void
si_pmustatstimer_dump(si_t * sih)9341 si_pmustatstimer_dump(si_t *sih)
9342 {
9343 	pmuregs_t *pmu;
9344 	uint origidx;
9345 	osl_t *osh = si_osh(sih);
9346 	uint32 core_cap_ext, pmucapabilities, AlpPeriod, ILPPeriod, pmuintmask0, pmuintstatus;
9347 	uint8 max_stats_timer_num, max_stats_timer_src_num;
9348 	uint32 stat_timer_ctrl, stat_timer_N;
9349 	uint8 i;
9350 	uint32 current_time_ms = OSL_SYSUPTIME();
9351 
9352 	/* Remember original core before switch to chipc/pmu */
9353 	origidx = si_coreidx(sih);
9354 	if (AOB_ENAB(sih)) {
9355 		pmu = si_setcore(sih, PMU_CORE_ID, 0);
9356 	} else {
9357 		pmu = si_setcoreidx(sih, SI_CC_IDX);
9358 	}
9359 	ASSERT(pmu != NULL);
9360 
9361 	pmucapabilities = R_REG(osh, &pmu->pmucapabilities);
9362 	core_cap_ext = R_REG(osh, &pmu->core_cap_ext);
9363 	AlpPeriod = R_REG(osh, &pmu->slowclkperiod);
9364 	ILPPeriod = R_REG(osh, &pmu->ILPPeriod);
9365 
9366 	max_stats_timer_num = ((core_cap_ext & PCAP_EXT_ST_NUM_MASK) >>
9367 		PCAP_EXT_ST_NUM_SHIFT) + 1;
9368 	max_stats_timer_src_num = ((core_cap_ext & PCAP_EXT_ST_SRC_NUM_MASK) >>
9369 		PCAP_EXT_ST_SRC_NUM_SHIFT) + 1;
9370 
9371 	pmuintstatus = R_REG(osh, &pmu->pmuintstatus);
9372 	pmuintmask0 = R_REG(osh, &pmu->pmuintmask0);
9373 
9374 	PMU_ERROR(("si_pmustatstimer_dump : TIME %d\n", current_time_ms));
9375 
9376 	PMU_ERROR(("\tMAX Timer Num %d, MAX Source Num %d\n",
9377 		max_stats_timer_num, max_stats_timer_src_num));
9378 	PMU_ERROR(("\tpmucapabilities 0x%8x, core_cap_ext 0x%8x, AlpPeriod 0x%8x, ILPPeriod 0x%8x, "
9379 		"pmuintmask0 0x%8x, pmuintstatus 0x%8x, pmurev %d\n",
9380 		pmucapabilities, core_cap_ext, AlpPeriod, ILPPeriod,
9381 		pmuintmask0, pmuintstatus, PMUREV(sih->pmurev)));
9382 
9383 	for (i = 0; i < max_stats_timer_num; i++) {
9384 		W_REG(osh, &pmu->pmu_statstimer_addr, i);
9385 		stat_timer_ctrl = R_REG(osh, &pmu->pmu_statstimer_ctrl);
9386 		stat_timer_N = R_REG(osh, &pmu->pmu_statstimer_N);
9387 		PMU_ERROR(("\t Timer %d : control 0x%8x, %d\n",
9388 			i, stat_timer_ctrl, stat_timer_N));
9389 	}
9390 
9391 	/* Return to original core */
9392 	si_setcoreidx(sih, origidx);
9393 }
9394 
9395 void
si_pmustatstimer_start(si_t * sih,uint8 timerid)9396 si_pmustatstimer_start(si_t *sih, uint8 timerid)
9397 {
9398 	pmuregs_t *pmu;
9399 	uint origidx;
9400 	osl_t *osh = si_osh(sih);
9401 
9402 	/* Remember original core before switch to chipc/pmu */
9403 	origidx = si_coreidx(sih);
9404 	if (AOB_ENAB(sih)) {
9405 		pmu = si_setcore(sih, PMU_CORE_ID, 0);
9406 	} else {
9407 		pmu = si_setcoreidx(sih, SI_CC_IDX);
9408 	}
9409 	ASSERT(pmu != NULL);
9410 
9411 	pmustatstimer[timerid].enable = TRUE;
9412 
9413 	W_REG(osh, &pmu->pmu_statstimer_addr, timerid);
9414 	OR_REG(osh, &pmu->pmu_statstimer_ctrl, PMU_ST_ENAB << PMU_ST_EN_SHIFT);
9415 
9416 	/* Return to original core */
9417 	si_setcoreidx(sih, origidx);
9418 }
9419 
9420 void
si_pmustatstimer_stop(si_t * sih,uint8 timerid)9421 si_pmustatstimer_stop(si_t *sih, uint8 timerid)
9422 {
9423 	pmuregs_t *pmu;
9424 	uint origidx;
9425 	osl_t *osh = si_osh(sih);
9426 
9427 	/* Remember original core before switch to chipc/pmu */
9428 	origidx = si_coreidx(sih);
9429 	if (AOB_ENAB(sih)) {
9430 		pmu = si_setcore(sih, PMU_CORE_ID, 0);
9431 	} else {
9432 		pmu = si_setcoreidx(sih, SI_CC_IDX);
9433 	}
9434 	ASSERT(pmu != NULL);
9435 
9436 	pmustatstimer[timerid].enable = FALSE;
9437 
9438 	W_REG(osh, &pmu->pmu_statstimer_addr, timerid);
9439 	AND_REG(osh, &pmu->pmu_statstimer_ctrl, ~(PMU_ST_ENAB << PMU_ST_EN_SHIFT));
9440 
9441 	/* Return to original core */
9442 	si_setcoreidx(sih, origidx);
9443 }
9444 
9445 void
si_pmustatstimer_clear(si_t * sih,uint8 timerid)9446 si_pmustatstimer_clear(si_t *sih, uint8 timerid)
9447 {
9448 	pmuregs_t *pmu;
9449 	uint origidx;
9450 	osl_t *osh = si_osh(sih);
9451 
9452 	/* Remember original core before switch to chipc/pmu */
9453 	origidx = si_coreidx(sih);
9454 	if (AOB_ENAB(sih)) {
9455 		pmu = si_setcore(sih, PMU_CORE_ID, 0);
9456 	} else {
9457 		pmu = si_setcoreidx(sih, SI_CC_IDX);
9458 	}
9459 	ASSERT(pmu != NULL);
9460 
9461 	W_REG(osh, &pmu->pmu_statstimer_addr, timerid);
9462 	W_REG(osh, &pmu->pmu_statstimer_N, 0);
9463 
9464 	/* Return to original core */
9465 	si_setcoreidx(sih, origidx);
9466 }
9467 
9468 void
si_pmustatstimer_clear_overflow(si_t * sih)9469 si_pmustatstimer_clear_overflow(si_t *sih)
9470 {
9471 	uint8 i;
9472 	uint32 core_cap_ext;
9473 	uint8 max_stats_timer_num;
9474 	uint32 timerN;
9475 	pmuregs_t *pmu;
9476 	uint origidx;
9477 	osl_t *osh = si_osh(sih);
9478 
9479 	/* Remember original core before switch to chipc/pmu */
9480 	origidx = si_coreidx(sih);
9481 	if (AOB_ENAB(sih)) {
9482 		pmu = si_setcore(sih, PMU_CORE_ID, 0);
9483 	} else {
9484 		pmu = si_setcoreidx(sih, SI_CC_IDX);
9485 	}
9486 	ASSERT(pmu != NULL);
9487 
9488 	core_cap_ext = R_REG(osh, &pmu->core_cap_ext);
9489 	max_stats_timer_num = ((core_cap_ext & PCAP_EXT_ST_NUM_MASK) >> PCAP_EXT_ST_NUM_SHIFT) + 1;
9490 
9491 	for (i = 0; i < max_stats_timer_num; i++) {
9492 		W_REG(osh, &pmu->pmu_statstimer_addr, i);
9493 		timerN = R_REG(osh, &pmu->pmu_statstimer_N);
9494 		if (timerN == 0xFFFFFFFF) {
9495 			PMU_ERROR(("pmustatstimer overflow clear - timerid : %d\n", i));
9496 			si_pmustatstimer_clear(sih, i);
9497 		}
9498 	}
9499 
9500 	/* Return to original core */
9501 	si_setcoreidx(sih, origidx);
9502 }
9503 
9504 uint32
si_pmustatstimer_read(si_t * sih,uint8 timerid)9505 si_pmustatstimer_read(si_t *sih, uint8 timerid)
9506 {
9507 	pmuregs_t *pmu;
9508 	uint origidx;
9509 	osl_t *osh = si_osh(sih);
9510 	uint32 stats_timer_N;
9511 
9512 	/* Remember original core before switch to chipc/pmu */
9513 	origidx = si_coreidx(sih);
9514 	if (AOB_ENAB(sih)) {
9515 		pmu = si_setcore(sih, PMU_CORE_ID, 0);
9516 	} else {
9517 		pmu = si_setcoreidx(sih, SI_CC_IDX);
9518 	}
9519 	ASSERT(pmu != NULL);
9520 
9521 	W_REG(osh, &pmu->pmu_statstimer_addr, timerid);
9522 	stats_timer_N = R_REG(osh, &pmu->pmu_statstimer_N);
9523 
9524 	/* Return to original core */
9525 	si_setcoreidx(sih, origidx);
9526 
9527 	return stats_timer_N;
9528 }
9529 
9530 void
si_pmustatstimer_cfg_src_num(si_t * sih,uint8 src_num,uint8 timerid)9531 si_pmustatstimer_cfg_src_num(si_t *sih, uint8 src_num, uint8 timerid)
9532 {
9533 	pmuregs_t *pmu;
9534 	uint origidx;
9535 	osl_t *osh = si_osh(sih);
9536 
9537 	/* Remember original core before switch to chipc/pmu */
9538 	origidx = si_coreidx(sih);
9539 	if (AOB_ENAB(sih)) {
9540 		pmu = si_setcore(sih, PMU_CORE_ID, 0);
9541 	} else {
9542 		pmu = si_setcoreidx(sih, SI_CC_IDX);
9543 	}
9544 	ASSERT(pmu != NULL);
9545 
9546 	pmustatstimer[timerid].src_num = src_num;
9547 	si_pmustatstimer_update(osh, pmu, timerid);
9548 
9549 	/* Return to original core */
9550 	si_setcoreidx(sih, origidx);
9551 }
9552 
9553 void
si_pmustatstimer_cfg_cnt_mode(si_t * sih,uint8 cnt_mode,uint8 timerid)9554 si_pmustatstimer_cfg_cnt_mode(si_t *sih, uint8 cnt_mode, uint8 timerid)
9555 {
9556 	pmuregs_t *pmu;
9557 	uint origidx;
9558 	osl_t *osh = si_osh(sih);
9559 
9560 	/* Remember original core before switch to chipc/pmu */
9561 	origidx = si_coreidx(sih);
9562 	if (AOB_ENAB(sih)) {
9563 		pmu = si_setcore(sih, PMU_CORE_ID, 0);
9564 	} else {
9565 		pmu = si_setcoreidx(sih, SI_CC_IDX);
9566 	}
9567 	ASSERT(pmu != NULL);
9568 
9569 	pmustatstimer[timerid].cnt_mode = cnt_mode;
9570 	si_pmustatstimer_update(osh, pmu, timerid);
9571 
9572 	/* Return to original core */
9573 	si_setcoreidx(sih, origidx);
9574 }
9575 #endif /* BCMPMU_STATS */
9576 
9577 #ifdef DONGLEBUILD
9578 /* Note this could be called from trap context !!
9579  * So observe caution. Do NOT ASSERT() in this function
9580  * len parameter is dual purpose - On input it is length of the
9581  * buffer provided. On output it is the amount of data written in
9582  * bytes.
9583  */
9584 /* This includes address data pair
9585  * Note presence of arg2. arg2 could further define what subset of information
9586  * needs to be dumped. Some external entities such as SMD could optionally pass
9587  * arg2 to define subset of information needed
9588  */
9589 int
BCMPOSTTRAPFN(si_pmu_regs_in_rodata_dump)9590 BCMPOSTTRAPFN(si_pmu_regs_in_rodata_dump)(void *sih, void *arg2,
9591 	uint32 *bufptr, uint16 *len)
9592 {
9593 	int rc = BCME_OK;
9594 	uint16 totalsize = SI_PMU_REG_DUMP_BASE_SIZE;
9595 
9596 	if ((bufptr == NULL) || (len == NULL)) {
9597 		rc = BCME_NOMEM;
9598 		goto fail;
9599 	}
9600 
9601 	/* Are PMU registers available in rodata? If not, bail out
9602 	 * Avoid re-read. If data is not there, then there could have been
9603 	 * an error in reading these regs.
9604 	 */
9605 	if (rodata_pmuregdump_ptr == NULL) {
9606 		rc = BCME_ERROR;
9607 		goto fail;
9608 	}
9609 
9610 	if (si_pmu_get_mac_rsrc_req_tmr_cnt(sih) > 1) {
9611 		totalsize += SI_PMU_REG_DUMP_MACRSRC1_SIZE;
9612 	}
9613 	if (si_pmu_get_mac_rsrc_req_tmr_cnt(sih) > 2) {
9614 		totalsize += SI_PMU_REG_DUMP_MACRSRC2_SIZE;
9615 	}
9616 	if (si_pmu_get_pmu_interrupt_rcv_cnt(sih) > 1) {
9617 		totalsize += SI_PMU_REG_DUMP_INTRCV1_SIZE;
9618 	}
9619 
9620 	/* Make sure there is enough space for address value pair */
9621 	if (len && *len < totalsize) {
9622 		rc = BCME_BUFTOOSHORT;
9623 		goto fail;
9624 	}
9625 
9626 	/* Write registers to supplied buffer */
9627 	/* Note that rodata_pmuregdump_size needs to be
9628 	 * a multiple of a word size
9629 	 */
9630 	memcpy((uint8*)bufptr, rodata_pmuregdump_ptr, totalsize);
9631 
9632 	*len = totalsize;
9633 fail:
9634 	return rc;
9635 
9636 }
9637 #endif /* DONGLEBUILD */
9638 
9639 /* query the # of mac resource request timers */
9640 uint
BCMPOSTTRAPFN(si_pmu_get_mac_rsrc_req_tmr_cnt)9641 BCMPOSTTRAPFN(si_pmu_get_mac_rsrc_req_tmr_cnt)(si_t *sih)
9642 {
9643 	if (PMUREV(sih->pmurev) >= 26) {
9644 		uint32 core_cap_ext = PMU_REG(sih, core_cap_ext, 0, 0);
9645 		uint mac_rsrc_cnt =
9646 		        ((core_cap_ext & PCAP_EXT_MAC_RSRC_REQ_TMR_CNT_MASK) >>
9647 		         PCAP_EXT_MAC_RSRC_REQ_TMR_CNT_SHIFT) + 1;
9648 		return mac_rsrc_cnt;
9649 	}
9650 
9651 	return si_numd11coreunits(sih);
9652 }
9653 
9654 /* query the # of pmu interrupt recevier */
9655 uint
BCMPOSTTRAPFN(si_pmu_get_pmu_interrupt_rcv_cnt)9656 BCMPOSTTRAPFN(si_pmu_get_pmu_interrupt_rcv_cnt)(si_t *sih)
9657 {
9658 	if (PMUREV(sih->pmurev) >= 26) {
9659 		uint32 core_cap_ext = PMU_REG(sih, core_cap_ext, 0, 0);
9660 		uint pmu_intr_rcvr_cnt =
9661 		        ((core_cap_ext & PCAP_EXT_PMU_INTR_RCVR_CNT_MASK) >>
9662 		         PCAP_EXT_PMU_INTR_RCVR_CNT_SHIFT) + 1;
9663 		return pmu_intr_rcvr_cnt;
9664 	}
9665 
9666 	return si_numd11coreunits(sih);
9667 }
9668 
9669 #ifdef DONGLEBUILD
9670 int
si_pmu_mem_pwr_off(si_t * sih,int core_idx)9671 si_pmu_mem_pwr_off(si_t *sih, int core_idx)
9672 {
9673 	int ret = BCME_OK;
9674 
9675 	if (si_setcore(sih, D11_CORE_ID, core_idx) == NULL) {
9676 		/* core_idx doesn't exsist */
9677 		return BCME_BADOPTION;
9678 	}
9679 
9680 	switch (CHIPID(sih->chip)) {
9681 	case BCM4385_CHIP_GRPID:
9682 	case BCM4387_CHIP_GRPID:
9683 		if (core_idx == 0) {
9684 			si_pmu_chipcontrol(sih, PMU_CHIPCTL4,
9685 				(PMU_CC4_4387_MAIN_PD_CBUCK2VDDB_ON |
9686 				PMU_CC4_4387_MAIN_PD_CBUCK2VDDRET_ON |
9687 				PMU_CC4_4387_MAIN_PD_MEMLPLDO2VDDB_ON |
9688 				PMU_CC4_4387_MAIN_PD_MEMLPDLO2VDDRET_ON),
9689 				0);
9690 
9691 			si_pmu_chipcontrol(sih, PMU_CHIPCTL13,
9692 				(PMU_CC13_MAIN_CBUCK2VDDB_OFF |
9693 				PMU_CC13_MAIN_CBUCK2VDDRET_OFF |
9694 				PMU_CC13_MAIN_MEMLPLDO2VDDB_OFF |
9695 				PMU_CC13_MAIN_MEMLPLDO2VDDRET_OFF),
9696 				(PMU_CC13_MAIN_CBUCK2VDDB_OFF |
9697 				PMU_CC13_MAIN_CBUCK2VDDRET_OFF |
9698 				PMU_CC13_MAIN_MEMLPLDO2VDDB_OFF |
9699 				PMU_CC13_MAIN_MEMLPLDO2VDDRET_OFF));
9700 
9701 			/* LQ settings */
9702 			si_gci_chipcontrol(sih, CC_GCI_CHIPCTRL_25,
9703 				0xFFFFFFFF, XTAL_LQ_SETTING_4387);
9704 		} else if (core_idx == 1) {
9705 			si_pmu_chipcontrol(sih, PMU_CHIPCTL4,
9706 				(PMU_CC4_4387_AUX_PD_CBUCK2VDDB_ON |
9707 				PMU_CC4_4387_AUX_PD_CBUCK2VDDRET_ON |
9708 				PMU_CC4_4387_AUX_PD_MEMLPLDO2VDDB_ON |
9709 				PMU_CC4_4387_AUX_PD_MEMLPLDO2VDDRET_ON),
9710 				0);
9711 
9712 			si_pmu_chipcontrol(sih, PMU_CHIPCTL13,
9713 				(PMU_CC13_AUX_CBUCK2VDDB_OFF |
9714 				PMU_CC13_AUX_CBUCK2VDDRET_OFF |
9715 				PMU_CC13_AUX_MEMLPLDO2VDDB_OFF |
9716 				PMU_CC13_AUX_MEMLPLDO2VDDRET_OFF),
9717 				(PMU_CC13_AUX_CBUCK2VDDB_OFF |
9718 				PMU_CC13_AUX_CBUCK2VDDRET_OFF |
9719 				PMU_CC13_AUX_MEMLPLDO2VDDB_OFF |
9720 				PMU_CC13_AUX_MEMLPLDO2VDDRET_OFF));
9721 		} else if (core_idx == 2) {
9722 			si_pmu_chipcontrol(sih, PMU_CHIPCTL17,
9723 				(PMU_CC17_SCAN_CBUCK2VDDB_ON |
9724 				PMU_CC17_SCAN_MEMLPLDO2VDDB_ON |
9725 				PMU_CC17_SCAN_MEMLPLDO2VDDRET_ON),
9726 				0);
9727 			si_pmu_chipcontrol(sih, PMU_CHIPCTL17,
9728 				(PMU_CC17_SCAN_CBUCK2VDDB_OFF |
9729 				PMU_CC17_SCAN_MEMLPLDO2VDDB_OFF |
9730 				PMU_CC17_SCAN_MEMLPLDO2VDDRET_OFF),
9731 				(PMU_CC17_SCAN_CBUCK2VDDB_OFF |
9732 				PMU_CC17_SCAN_MEMLPLDO2VDDB_OFF |
9733 				PMU_CC17_SCAN_MEMLPLDO2VDDRET_OFF));
9734 		}
9735 		break;
9736 
9737 	default:
9738 		ret = BCME_UNSUPPORTED;
9739 		break;
9740 	}
9741 
9742 	return ret;
9743 }
9744 
9745 int
BCMPOSTTRAPFN(si_pmu_mem_pwr_on)9746 BCMPOSTTRAPFN(si_pmu_mem_pwr_on)(si_t *sih)
9747 {
9748 	int ret = BCME_OK;
9749 
9750 	switch (CHIPID(sih->chip)) {
9751 	case BCM4385_CHIP_GRPID:
9752 	case BCM4387_CHIP_GRPID:
9753 		si_pmu_chipcontrol(sih, PMU_CHIPCTL13,
9754 			(PMU_CC13_MAIN_CBUCK2VDDB_OFF |
9755 			PMU_CC13_MAIN_CBUCK2VDDRET_OFF |
9756 			PMU_CC13_MAIN_MEMLPLDO2VDDB_OFF |
9757 			PMU_CC13_MAIN_MEMLPLDO2VDDRET_OFF),
9758 			PMU_CC13_MAIN_MEMLPLDO2VDDRET_OFF);
9759 		si_pmu_chipcontrol(sih, PMU_CHIPCTL13,
9760 			(PMU_CC13_AUX_CBUCK2VDDB_OFF |
9761 			PMU_CC13_AUX_CBUCK2VDDRET_OFF |
9762 			PMU_CC13_AUX_MEMLPLDO2VDDB_OFF |
9763 			PMU_CC13_AUX_MEMLPLDO2VDDRET_OFF),
9764 			PMU_CC13_AUX_MEMLPLDO2VDDRET_OFF);
9765 		si_pmu_chipcontrol(sih, PMU_CHIPCTL17,
9766 			(PMU_CC17_SCAN_CBUCK2VDDB_OFF |
9767 			PMU_CC17_SCAN_MEMLPLDO2VDDB_OFF |
9768 			PMU_CC17_SCAN_MEMLPLDO2VDDRET_OFF),
9769 			PMU_CC17_SCAN_MEMLPLDO2VDDRET_OFF);
9770 
9771 		/* HQ settings */
9772 		si_gci_chipcontrol(sih, CC_GCI_CHIPCTRL_25,
9773 			0xFFFFFFFF, XTAL_HQ_SETTING_4387);
9774 	break;
9775 
9776 	default:
9777 		ret = BCME_UNSUPPORTED;
9778 		break;
9779 	}
9780 
9781 	return ret;
9782 }
9783 
9784 void
BCMPOSTTRAPFN(si_pmu_disable_intr_pwrreq)9785 BCMPOSTTRAPFN(si_pmu_disable_intr_pwrreq)(si_t *sih)
9786 {
9787 	if (MULTIBP_CAP(sih)) {
9788 		switch (CHIPID(sih->chip)) {
9789 		case BCM4376_CHIP_GRPID:
9790 		case BCM4378_CHIP_GRPID:
9791 		case BCM4385_CHIP_GRPID:
9792 		case BCM4387_CHIP_GRPID:
9793 		case BCM4388_CHIP_GRPID:
9794 		case BCM4389_CHIP_GRPID:
9795 		case BCM4397_CHIP_GRPID:
9796 			si_pmu_chipcontrol(sih, PMU_CHIPCTL2, PMU_CC2_CB2WL_INTR_PWRREQ_EN, 0);
9797 			si_pmu_chipcontrol(sih, PMU_CHIPCTL6, PMU_CC6_ENABLE_DMN1_WAKEUP, 0);
9798 			break;
9799 		default:
9800 			PMU_ERROR(("si_pmu_disable_intr_pwrreq: add support for this chip!\n"));
9801 			OSL_SYS_HALT();
9802 			break;
9803 		}
9804 	}
9805 }
9806 
9807 void
BCMPOSTTRAPFN(si_pmu_clear_intmask)9808 BCMPOSTTRAPFN(si_pmu_clear_intmask)(si_t *sih)
9809 {
9810 	pmuregs_t *pmu;
9811 	uint origidx;
9812 	osl_t *osh = si_osh(sih);
9813 	uint pmu_intr_recvr_cnt;
9814 
9815 	/* Remember original core before switch to chipc/pmu */
9816 	origidx = si_coreidx(sih);
9817 	if (AOB_ENAB(sih)) {
9818 		pmu = si_setcore(sih, PMU_CORE_ID, 0);
9819 	} else {
9820 		pmu = si_setcoreidx(sih, SI_CC_IDX);
9821 	}
9822 
9823 	ASSERT(pmu != NULL);
9824 	W_REG(osh, &pmu->pmuintmask0, 0);
9825 
9826 	pmu_intr_recvr_cnt = ((R_REG(osh, &pmu->core_cap_ext) & PCAP_EXT_PMU_INTR_RCVR_CNT_MASK)
9827 			>> PCAP_EXT_PMU_INTR_RCVR_CNT_SHIFT) + 1;
9828 
9829 	if (pmu_intr_recvr_cnt > 1) {
9830 		W_REG(osh, &pmu->pmuintmask1, 0);
9831 	}
9832 
9833 	/* Return to original core */
9834 	si_setcoreidx(sih, origidx);
9835 }
9836 #endif /* DONGLEBUILD */
9837 
9838 int
si_pmu_res_state_pwrsw_main_wait(si_t * sih)9839 si_pmu_res_state_pwrsw_main_wait(si_t *sih)
9840 {
9841 	int ret = BCME_OK;
9842 
9843 	switch (CHIPID(sih->chip)) {
9844 	case BCM4387_CHIP_GRPID:
9845 		if (PMU_REG(sih, res_state, 0, 0) & PMURES_BIT(RES4387_PWRSW_MAIN)) {
9846 			SPINWAIT((PMU_REG(sih, res_state, 0, 0) &
9847 				PMURES_BIT(RES4387_PWRSW_MAIN)), 10000);
9848 			OSL_DELAY(1000);
9849 		}
9850 		ret = (PMU_REG(sih, res_state, 0, 0) & PMURES_BIT(RES4387_PWRSW_MAIN)) ?
9851 			BCME_ERROR : BCME_OK;
9852 		break;
9853 	default:
9854 		PMU_ERROR(("si_pmu_res_state_pwrsw_main_wait: add support for this chip!\n"));
9855 		OSL_SYS_HALT();
9856 		break;
9857 	}
9858 
9859 	return ret;
9860 }
9861 
9862 int
si_pmu_lvm_csr_update(si_t * sih,bool lvm)9863 si_pmu_lvm_csr_update(si_t *sih, bool lvm)
9864 {
9865 
9866 #ifdef BCMDVFS
9867 	if (BCMDVFS_ENAB() && si_dvfs_enable_status(sih)) {
9868 		uint32 ndv_volt = lvm ? DVFS_VOLTAGE_NDV : DVFS_VOLTAGE_NDV_NON_LVM;
9869 		si_dvfs_set_ndv_voltage(sih, ndv_volt);
9870 	} else
9871 #endif /* BCMDVFS */
9872 	{
9873 		uint32 cbuck_volt = lvm ? CBUCK_VOLT_SW_DEFAULT_4387 : CBUCK_VOLT_NON_LVM;
9874 		si_pmu_vreg_control(sih, PMU_VREG_0,
9875 			VREG0_4378_CSR_VOLT_ADJ_PWM_MASK,
9876 			cbuck_volt << VREG0_4378_CSR_VOLT_ADJ_PWM_SHIFT);
9877 	}
9878 	return BCME_OK;
9879 }
9880 
9881 #if defined(BT_WLAN_REG_ON_WAR)
9882 void
si_pmu_reg_on_war_ext_wake_perst_set(si_t * sih)9883 si_pmu_reg_on_war_ext_wake_perst_set(si_t *sih)
9884 {
9885 	uint origidx = si_coreidx(sih);
9886 	pmuregs_t *pmu = si_setcore(sih, PMU_CORE_ID, 0);
9887 	osl_t *osh = si_osh(sih);
9888 
9889 	if (PMUREV(sih->pmurev) == 40) {
9890 		/*
9891 		 * set PCIEPerstReq (bit-5) as a wake-up source in
9892 		 * ExtWakeMask0 (0x760) register
9893 		 */
9894 		W_REG(osh, &pmu->extwakemask0, PMU_EXT_WAKE_MASK_0_PCIE_PERST);
9895 
9896 		/*
9897 		 * configure the wakemask as "common backplane" resources to
9898 		 * be up during wake-up in ExtWakeReqMask0 (0x770) register
9899 		 */
9900 		W_REG(osh, &pmu->extwakereqmask[0], REG_ON_WAR_PMU_EXT_WAKE_REQ_MASK0_VAL);
9901 	}
9902 
9903 	si_setcoreidx(sih, origidx);
9904 }
9905 
9906 void
si_pmu_reg_on_war_ext_wake_perst_clear(si_t * sih)9907 si_pmu_reg_on_war_ext_wake_perst_clear(si_t *sih)
9908 {
9909 	uint32 val = 0;
9910 	uint origidx = si_coreidx(sih);
9911 	pmuregs_t *pmu = si_setcore(sih, PMU_CORE_ID, 0);
9912 	osl_t *osh = si_osh(sih);
9913 
9914 	if (PMUREV(sih->pmurev) == 40) {
9915 		/* clear all set bits in ExtWakeupStatus (0x744) register */
9916 		val = R_REG(osh, &pmu->extwakeupstatus);
9917 		W_REG(osh, &pmu->extwakeupstatus, val);
9918 	}
9919 
9920 	si_setcoreidx(sih, origidx);
9921 }
9922 #endif /* BT_WLAN_REG_ON_WAR */
9923 
9924 void
si_pmu_res_state_wait(si_t * sih,uint rsrc)9925 si_pmu_res_state_wait(si_t *sih, uint rsrc)
9926 {
9927 	SPINWAIT(!(PMU_REG(sih, res_state, 0, 0) & PMURES_BIT(rsrc)), PMU_MAX_TRANSITION_DLY);
9928 	ASSERT(PMU_REG(sih, res_state, 0, 0) & PMURES_BIT(rsrc));
9929 }
9930