1 /*
2  * Copyright (c) 2010 Broadcom Corporation
3  *
4  * Permission to use, copy, modify, and/or distribute this software for any
5  * purpose with or without fee is hereby granted, provided that the above
6  * copyright notice and this permission notice appear in all copies.
7  *
8  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11  * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15  */
16 #include <linux/delay.h>
17 #include <linux/kernel.h>
18 #include <linux/string.h>
19 #include <linux/module.h>
20 #include <linux/pci.h>
21 #include <bcmdefs.h>
22 #include <bcmutils.h>
23 #include <siutils.h>
24 #include <bcmdevs.h>
25 #include <hndsoc.h>
26 #include <sbchipc.h>
27 #include <hndpmu.h>
28 #include "siutils_priv.h"
29 
30 #define	PMU_ERROR(args)
31 
32 #ifdef BCMDBG
33 #define	PMU_MSG(args)	printk args
34 
35 /* debug-only definitions */
36 /* #define BCMDBG_FORCEHT */
37 /* #define CHIPC_UART_ALWAYS_ON */
38 #else
39 #define	PMU_MSG(args)
40 #endif				/* BCMDBG */
41 
42 /* To check in verbose debugging messages not intended
43  * to be on except on private builds.
44  */
45 #define	PMU_NONE(args)
46 
47 /* PLL controls/clocks */
48 static void si_pmu1_pllinit0(si_t *sih, chipcregs_t *cc, u32 xtal);
49 static u32 si_pmu1_cpuclk0(si_t *sih, chipcregs_t *cc);
50 static u32 si_pmu1_alpclk0(si_t *sih, chipcregs_t *cc);
51 
52 /* PMU resources */
53 static bool si_pmu_res_depfltr_bb(si_t *sih);
54 static bool si_pmu_res_depfltr_ncb(si_t *sih);
55 static bool si_pmu_res_depfltr_paldo(si_t *sih);
56 static bool si_pmu_res_depfltr_npaldo(si_t *sih);
57 static u32 si_pmu_res_deps(si_t *sih, chipcregs_t *cc, u32 rsrcs, bool all);
58 static uint si_pmu_res_uptime(si_t *sih, chipcregs_t *cc, u8 rsrc);
59 static void si_pmu_res_masks(si_t *sih, u32 * pmin, u32 * pmax);
60 static void si_pmu_spuravoid_pllupdate(si_t *sih, chipcregs_t *cc,
61 				       u8 spuravoid);
62 
63 static void si_pmu_set_4330_plldivs(si_t *sih);
64 
65 /* FVCO frequency */
66 #define FVCO_880	880000	/* 880MHz */
67 #define FVCO_1760	1760000	/* 1760MHz */
68 #define FVCO_1440	1440000	/* 1440MHz */
69 #define FVCO_960	960000	/* 960MHz */
70 
71 /* Read/write a chipcontrol reg */
si_pmu_chipcontrol(si_t * sih,uint reg,u32 mask,u32 val)72 u32 si_pmu_chipcontrol(si_t *sih, uint reg, u32 mask, u32 val)
73 {
74 	si_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, chipcontrol_addr), ~0,
75 		   reg);
76 	return si_corereg(sih, SI_CC_IDX,
77 			  offsetof(chipcregs_t, chipcontrol_data), mask, val);
78 }
79 
80 /* Read/write a regcontrol reg */
si_pmu_regcontrol(si_t * sih,uint reg,u32 mask,u32 val)81 u32 si_pmu_regcontrol(si_t *sih, uint reg, u32 mask, u32 val)
82 {
83 	si_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, regcontrol_addr), ~0,
84 		   reg);
85 	return si_corereg(sih, SI_CC_IDX,
86 			  offsetof(chipcregs_t, regcontrol_data), mask, val);
87 }
88 
89 /* Read/write a pllcontrol reg */
si_pmu_pllcontrol(si_t * sih,uint reg,u32 mask,u32 val)90 u32 si_pmu_pllcontrol(si_t *sih, uint reg, u32 mask, u32 val)
91 {
92 	si_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, pllcontrol_addr), ~0,
93 		   reg);
94 	return si_corereg(sih, SI_CC_IDX,
95 			  offsetof(chipcregs_t, pllcontrol_data), mask, val);
96 }
97 
98 /* PMU PLL update */
si_pmu_pllupd(si_t * sih)99 void si_pmu_pllupd(si_t *sih)
100 {
101 	si_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, pmucontrol),
102 		   PCTL_PLL_PLLCTL_UPD, PCTL_PLL_PLLCTL_UPD);
103 }
104 
105 /* Setup switcher voltage */
si_pmu_set_switcher_voltage(si_t * sih,u8 bb_voltage,u8 rf_voltage)106 void si_pmu_set_switcher_voltage(si_t *sih, u8 bb_voltage, u8 rf_voltage)
107 {
108 	chipcregs_t *cc;
109 	uint origidx;
110 
111 	ASSERT(sih->cccaps & CC_CAP_PMU);
112 
113 	/* Remember original core before switch to chipc */
114 	origidx = si_coreidx(sih);
115 	cc = si_setcoreidx(sih, SI_CC_IDX);
116 	ASSERT(cc != NULL);
117 
118 	W_REG(&cc->regcontrol_addr, 0x01);
119 	W_REG(&cc->regcontrol_data, (u32) (bb_voltage & 0x1f) << 22);
120 
121 	W_REG(&cc->regcontrol_addr, 0x00);
122 	W_REG(&cc->regcontrol_data, (u32) (rf_voltage & 0x1f) << 14);
123 
124 	/* Return to original core */
125 	si_setcoreidx(sih, origidx);
126 }
127 
si_pmu_set_ldo_voltage(si_t * sih,u8 ldo,u8 voltage)128 void si_pmu_set_ldo_voltage(si_t *sih, u8 ldo, u8 voltage)
129 {
130 	u8 sr_cntl_shift = 0, rc_shift = 0, shift = 0, mask = 0;
131 	u8 addr = 0;
132 
133 	ASSERT(sih->cccaps & CC_CAP_PMU);
134 
135 	switch (sih->chip) {
136 	case BCM4336_CHIP_ID:
137 		switch (ldo) {
138 		case SET_LDO_VOLTAGE_CLDO_PWM:
139 			addr = 4;
140 			rc_shift = 1;
141 			mask = 0xf;
142 			break;
143 		case SET_LDO_VOLTAGE_CLDO_BURST:
144 			addr = 4;
145 			rc_shift = 5;
146 			mask = 0xf;
147 			break;
148 		case SET_LDO_VOLTAGE_LNLDO1:
149 			addr = 4;
150 			rc_shift = 17;
151 			mask = 0xf;
152 			break;
153 		default:
154 			ASSERT(false);
155 			return;
156 		}
157 		break;
158 	case BCM4330_CHIP_ID:
159 		switch (ldo) {
160 		case SET_LDO_VOLTAGE_CBUCK_PWM:
161 			addr = 3;
162 			rc_shift = 0;
163 			mask = 0x1f;
164 			break;
165 		default:
166 			ASSERT(false);
167 			break;
168 		}
169 		break;
170 	default:
171 		ASSERT(false);
172 		return;
173 	}
174 
175 	shift = sr_cntl_shift + rc_shift;
176 
177 	si_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, regcontrol_addr),
178 		   ~0, addr);
179 	si_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, regcontrol_data),
180 		   mask << shift, (voltage & mask) << shift);
181 }
182 
183 /* d11 slow to fast clock transition time in slow clock cycles */
184 #define D11SCC_SLOW2FAST_TRANSITION	2
185 
si_pmu_fast_pwrup_delay(si_t * sih)186 u16 si_pmu_fast_pwrup_delay(si_t *sih)
187 {
188 	uint delay = PMU_MAX_TRANSITION_DLY;
189 	chipcregs_t *cc;
190 	uint origidx;
191 #ifdef BCMDBG
192 	char chn[8];
193 	chn[0] = 0;		/* to suppress compile error */
194 #endif
195 
196 	ASSERT(sih->cccaps & CC_CAP_PMU);
197 
198 	/* Remember original core before switch to chipc */
199 	origidx = si_coreidx(sih);
200 	cc = si_setcoreidx(sih, SI_CC_IDX);
201 	ASSERT(cc != NULL);
202 
203 	switch (sih->chip) {
204 	case BCM43224_CHIP_ID:
205 	case BCM43225_CHIP_ID:
206 	case BCM43421_CHIP_ID:
207 	case BCM43235_CHIP_ID:
208 	case BCM43236_CHIP_ID:
209 	case BCM43238_CHIP_ID:
210 	case BCM4331_CHIP_ID:
211 	case BCM6362_CHIP_ID:
212 	case BCM4313_CHIP_ID:
213 		delay = ISSIM_ENAB(sih) ? 70 : 3700;
214 		break;
215 	case BCM4329_CHIP_ID:
216 		if (ISSIM_ENAB(sih))
217 			delay = 70;
218 		else {
219 			u32 ilp = si_ilp_clock(sih);
220 			delay =
221 			    (si_pmu_res_uptime(sih, cc, RES4329_HT_AVAIL) +
222 			     D11SCC_SLOW2FAST_TRANSITION) * ((1000000 + ilp -
223 							      1) / ilp);
224 			delay = (11 * delay) / 10;
225 		}
226 		break;
227 	case BCM4319_CHIP_ID:
228 		delay = ISSIM_ENAB(sih) ? 70 : 3700;
229 		break;
230 	case BCM4336_CHIP_ID:
231 		if (ISSIM_ENAB(sih))
232 			delay = 70;
233 		else {
234 			u32 ilp = si_ilp_clock(sih);
235 			delay =
236 			    (si_pmu_res_uptime(sih, cc, RES4336_HT_AVAIL) +
237 			     D11SCC_SLOW2FAST_TRANSITION) * ((1000000 + ilp -
238 							      1) / ilp);
239 			delay = (11 * delay) / 10;
240 		}
241 		break;
242 	case BCM4330_CHIP_ID:
243 		if (ISSIM_ENAB(sih))
244 			delay = 70;
245 		else {
246 			u32 ilp = si_ilp_clock(sih);
247 			delay =
248 			    (si_pmu_res_uptime(sih, cc, RES4330_HT_AVAIL) +
249 			     D11SCC_SLOW2FAST_TRANSITION) * ((1000000 + ilp -
250 							      1) / ilp);
251 			delay = (11 * delay) / 10;
252 		}
253 		break;
254 	default:
255 		break;
256 	}
257 	/* Return to original core */
258 	si_setcoreidx(sih, origidx);
259 
260 	return (u16) delay;
261 }
262 
si_pmu_force_ilp(si_t * sih,bool force)263 u32 si_pmu_force_ilp(si_t *sih, bool force)
264 {
265 	chipcregs_t *cc;
266 	uint origidx;
267 	u32 oldpmucontrol;
268 
269 	ASSERT(sih->cccaps & CC_CAP_PMU);
270 
271 	/* Remember original core before switch to chipc */
272 	origidx = si_coreidx(sih);
273 	cc = si_setcoreidx(sih, SI_CC_IDX);
274 	ASSERT(cc != NULL);
275 
276 	oldpmucontrol = R_REG(&cc->pmucontrol);
277 	if (force)
278 		W_REG(&cc->pmucontrol, oldpmucontrol &
279 		      ~(PCTL_HT_REQ_EN | PCTL_ALP_REQ_EN));
280 	else
281 		W_REG(&cc->pmucontrol, oldpmucontrol |
282 		      (PCTL_HT_REQ_EN | PCTL_ALP_REQ_EN));
283 
284 	/* Return to original core */
285 	si_setcoreidx(sih, origidx);
286 
287 	return oldpmucontrol;
288 }
289 
290 /* Setup resource up/down timers */
291 typedef struct {
292 	u8 resnum;
293 	u16 updown;
294 } pmu_res_updown_t;
295 
296 /* Change resource dependancies masks */
297 typedef struct {
298 	u32 res_mask;	/* resources (chip specific) */
299 	s8 action;		/* action */
300 	u32 depend_mask;	/* changes to the dependancies mask */
301 	 bool(*filter) (si_t *sih);	/* action is taken when filter is NULL or return true */
302 } pmu_res_depend_t;
303 
304 /* Resource dependancies mask change action */
305 #define RES_DEPEND_SET		0	/* Override the dependancies mask */
306 #define RES_DEPEND_ADD		1	/* Add to the  dependancies mask */
307 #define RES_DEPEND_REMOVE	-1	/* Remove from the dependancies mask */
308 
309 static const pmu_res_updown_t bcm4328a0_res_updown[] = {
310 	{
311 	RES4328_EXT_SWITCHER_PWM, 0x0101}, {
312 	RES4328_BB_SWITCHER_PWM, 0x1f01}, {
313 	RES4328_BB_SWITCHER_BURST, 0x010f}, {
314 	RES4328_BB_EXT_SWITCHER_BURST, 0x0101}, {
315 	RES4328_ILP_REQUEST, 0x0202}, {
316 	RES4328_RADIO_SWITCHER_PWM, 0x0f01}, {
317 	RES4328_RADIO_SWITCHER_BURST, 0x0f01}, {
318 	RES4328_ROM_SWITCH, 0x0101}, {
319 	RES4328_PA_REF_LDO, 0x0f01}, {
320 	RES4328_RADIO_LDO, 0x0f01}, {
321 	RES4328_AFE_LDO, 0x0f01}, {
322 	RES4328_PLL_LDO, 0x0f01}, {
323 	RES4328_BG_FILTBYP, 0x0101}, {
324 	RES4328_TX_FILTBYP, 0x0101}, {
325 	RES4328_RX_FILTBYP, 0x0101}, {
326 	RES4328_XTAL_PU, 0x0101}, {
327 	RES4328_XTAL_EN, 0xa001}, {
328 	RES4328_BB_PLL_FILTBYP, 0x0101}, {
329 	RES4328_RF_PLL_FILTBYP, 0x0101}, {
330 	RES4328_BB_PLL_PU, 0x0701}
331 };
332 
333 static const pmu_res_depend_t bcm4328a0_res_depend[] = {
334 	/* Adjust ILP request resource not to force ext/BB switchers into burst mode */
335 	{
336 	PMURES_BIT(RES4328_ILP_REQUEST),
337 		    RES_DEPEND_SET,
338 		    PMURES_BIT(RES4328_EXT_SWITCHER_PWM) |
339 		    PMURES_BIT(RES4328_BB_SWITCHER_PWM), NULL}
340 };
341 
342 static const pmu_res_updown_t bcm4325a0_res_updown_qt[] = {
343 	{
344 	RES4325_HT_AVAIL, 0x0300}, {
345 	RES4325_BBPLL_PWRSW_PU, 0x0101}, {
346 	RES4325_RFPLL_PWRSW_PU, 0x0101}, {
347 	RES4325_ALP_AVAIL, 0x0100}, {
348 	RES4325_XTAL_PU, 0x1000}, {
349 	RES4325_LNLDO1_PU, 0x0800}, {
350 	RES4325_CLDO_CBUCK_PWM, 0x0101}, {
351 	RES4325_CBUCK_PWM, 0x0803}
352 };
353 
354 static const pmu_res_updown_t bcm4325a0_res_updown[] = {
355 	{
356 	RES4325_XTAL_PU, 0x1501}
357 };
358 
359 static const pmu_res_depend_t bcm4325a0_res_depend[] = {
360 	/* Adjust OTP PU resource dependencies - remove BB BURST */
361 	{
362 	PMURES_BIT(RES4325_OTP_PU),
363 		    RES_DEPEND_REMOVE,
364 		    PMURES_BIT(RES4325_BUCK_BOOST_BURST), NULL},
365 	    /* Adjust ALP/HT Avail resource dependencies - bring up BB along if it is used. */
366 	{
367 	PMURES_BIT(RES4325_ALP_AVAIL) | PMURES_BIT(RES4325_HT_AVAIL),
368 		    RES_DEPEND_ADD,
369 		    PMURES_BIT(RES4325_BUCK_BOOST_BURST) |
370 		    PMURES_BIT(RES4325_BUCK_BOOST_PWM), si_pmu_res_depfltr_bb},
371 	    /* Adjust HT Avail resource dependencies - bring up RF switches along with HT. */
372 	{
373 	PMURES_BIT(RES4325_HT_AVAIL),
374 		    RES_DEPEND_ADD,
375 		    PMURES_BIT(RES4325_RX_PWRSW_PU) |
376 		    PMURES_BIT(RES4325_TX_PWRSW_PU) |
377 		    PMURES_BIT(RES4325_LOGEN_PWRSW_PU) |
378 		    PMURES_BIT(RES4325_AFE_PWRSW_PU), NULL},
379 	    /* Adjust ALL resource dependencies - remove CBUCK dependancies if it is not used. */
380 	{
381 	PMURES_BIT(RES4325_ILP_REQUEST) |
382 		    PMURES_BIT(RES4325_ABUCK_BURST) |
383 		    PMURES_BIT(RES4325_ABUCK_PWM) |
384 		    PMURES_BIT(RES4325_LNLDO1_PU) |
385 		    PMURES_BIT(RES4325C1_LNLDO2_PU) |
386 		    PMURES_BIT(RES4325_XTAL_PU) |
387 		    PMURES_BIT(RES4325_ALP_AVAIL) |
388 		    PMURES_BIT(RES4325_RX_PWRSW_PU) |
389 		    PMURES_BIT(RES4325_TX_PWRSW_PU) |
390 		    PMURES_BIT(RES4325_RFPLL_PWRSW_PU) |
391 		    PMURES_BIT(RES4325_LOGEN_PWRSW_PU) |
392 		    PMURES_BIT(RES4325_AFE_PWRSW_PU) |
393 		    PMURES_BIT(RES4325_BBPLL_PWRSW_PU) |
394 		    PMURES_BIT(RES4325_HT_AVAIL), RES_DEPEND_REMOVE,
395 		    PMURES_BIT(RES4325B0_CBUCK_LPOM) |
396 		    PMURES_BIT(RES4325B0_CBUCK_BURST) |
397 		    PMURES_BIT(RES4325B0_CBUCK_PWM), si_pmu_res_depfltr_ncb}
398 };
399 
400 static const pmu_res_updown_t bcm4315a0_res_updown_qt[] = {
401 	{
402 	RES4315_HT_AVAIL, 0x0101}, {
403 	RES4315_XTAL_PU, 0x0100}, {
404 	RES4315_LNLDO1_PU, 0x0100}, {
405 	RES4315_PALDO_PU, 0x0100}, {
406 	RES4315_CLDO_PU, 0x0100}, {
407 	RES4315_CBUCK_PWM, 0x0100}, {
408 	RES4315_CBUCK_BURST, 0x0100}, {
409 	RES4315_CBUCK_LPOM, 0x0100}
410 };
411 
412 static const pmu_res_updown_t bcm4315a0_res_updown[] = {
413 	{
414 	RES4315_XTAL_PU, 0x2501}
415 };
416 
417 static const pmu_res_depend_t bcm4315a0_res_depend[] = {
418 	/* Adjust OTP PU resource dependencies - not need PALDO unless write */
419 	{
420 	PMURES_BIT(RES4315_OTP_PU),
421 		    RES_DEPEND_REMOVE,
422 		    PMURES_BIT(RES4315_PALDO_PU), si_pmu_res_depfltr_npaldo},
423 	    /* Adjust ALP/HT Avail resource dependencies - bring up PALDO along if it is used. */
424 	{
425 	PMURES_BIT(RES4315_ALP_AVAIL) | PMURES_BIT(RES4315_HT_AVAIL),
426 		    RES_DEPEND_ADD,
427 		    PMURES_BIT(RES4315_PALDO_PU), si_pmu_res_depfltr_paldo},
428 	    /* Adjust HT Avail resource dependencies - bring up RF switches along with HT. */
429 	{
430 	PMURES_BIT(RES4315_HT_AVAIL),
431 		    RES_DEPEND_ADD,
432 		    PMURES_BIT(RES4315_RX_PWRSW_PU) |
433 		    PMURES_BIT(RES4315_TX_PWRSW_PU) |
434 		    PMURES_BIT(RES4315_LOGEN_PWRSW_PU) |
435 		    PMURES_BIT(RES4315_AFE_PWRSW_PU), NULL},
436 	    /* Adjust ALL resource dependencies - remove CBUCK dependancies if it is not used. */
437 	{
438 	PMURES_BIT(RES4315_CLDO_PU) | PMURES_BIT(RES4315_ILP_REQUEST) |
439 		    PMURES_BIT(RES4315_LNLDO1_PU) |
440 		    PMURES_BIT(RES4315_OTP_PU) |
441 		    PMURES_BIT(RES4315_LNLDO2_PU) |
442 		    PMURES_BIT(RES4315_XTAL_PU) |
443 		    PMURES_BIT(RES4315_ALP_AVAIL) |
444 		    PMURES_BIT(RES4315_RX_PWRSW_PU) |
445 		    PMURES_BIT(RES4315_TX_PWRSW_PU) |
446 		    PMURES_BIT(RES4315_RFPLL_PWRSW_PU) |
447 		    PMURES_BIT(RES4315_LOGEN_PWRSW_PU) |
448 		    PMURES_BIT(RES4315_AFE_PWRSW_PU) |
449 		    PMURES_BIT(RES4315_BBPLL_PWRSW_PU) |
450 		    PMURES_BIT(RES4315_HT_AVAIL), RES_DEPEND_REMOVE,
451 		    PMURES_BIT(RES4315_CBUCK_LPOM) |
452 		    PMURES_BIT(RES4315_CBUCK_BURST) |
453 		    PMURES_BIT(RES4315_CBUCK_PWM), si_pmu_res_depfltr_ncb}
454 };
455 
456 	/* 4329 specific. needs to come back this issue later */
457 static const pmu_res_updown_t bcm4329_res_updown[] = {
458 	{
459 	RES4329_XTAL_PU, 0x1501}
460 };
461 
462 static const pmu_res_depend_t bcm4329_res_depend[] = {
463 	/* Adjust HT Avail resource dependencies */
464 	{
465 	PMURES_BIT(RES4329_HT_AVAIL),
466 		    RES_DEPEND_ADD,
467 		    PMURES_BIT(RES4329_CBUCK_LPOM) |
468 		    PMURES_BIT(RES4329_CBUCK_BURST) |
469 		    PMURES_BIT(RES4329_CBUCK_PWM) |
470 		    PMURES_BIT(RES4329_CLDO_PU) |
471 		    PMURES_BIT(RES4329_PALDO_PU) |
472 		    PMURES_BIT(RES4329_LNLDO1_PU) |
473 		    PMURES_BIT(RES4329_XTAL_PU) |
474 		    PMURES_BIT(RES4329_ALP_AVAIL) |
475 		    PMURES_BIT(RES4329_RX_PWRSW_PU) |
476 		    PMURES_BIT(RES4329_TX_PWRSW_PU) |
477 		    PMURES_BIT(RES4329_RFPLL_PWRSW_PU) |
478 		    PMURES_BIT(RES4329_LOGEN_PWRSW_PU) |
479 		    PMURES_BIT(RES4329_AFE_PWRSW_PU) |
480 		    PMURES_BIT(RES4329_BBPLL_PWRSW_PU), NULL}
481 };
482 
483 static const pmu_res_updown_t bcm4319a0_res_updown_qt[] = {
484 	{
485 	RES4319_HT_AVAIL, 0x0101}, {
486 	RES4319_XTAL_PU, 0x0100}, {
487 	RES4319_LNLDO1_PU, 0x0100}, {
488 	RES4319_PALDO_PU, 0x0100}, {
489 	RES4319_CLDO_PU, 0x0100}, {
490 	RES4319_CBUCK_PWM, 0x0100}, {
491 	RES4319_CBUCK_BURST, 0x0100}, {
492 	RES4319_CBUCK_LPOM, 0x0100}
493 };
494 
495 static const pmu_res_updown_t bcm4319a0_res_updown[] = {
496 	{
497 	RES4319_XTAL_PU, 0x3f01}
498 };
499 
500 static const pmu_res_depend_t bcm4319a0_res_depend[] = {
501 	/* Adjust OTP PU resource dependencies - not need PALDO unless write */
502 	{
503 	PMURES_BIT(RES4319_OTP_PU),
504 		    RES_DEPEND_REMOVE,
505 		    PMURES_BIT(RES4319_PALDO_PU), si_pmu_res_depfltr_npaldo},
506 	    /* Adjust HT Avail resource dependencies - bring up PALDO along if it is used. */
507 	{
508 	PMURES_BIT(RES4319_HT_AVAIL),
509 		    RES_DEPEND_ADD,
510 		    PMURES_BIT(RES4319_PALDO_PU), si_pmu_res_depfltr_paldo},
511 	    /* Adjust HT Avail resource dependencies - bring up RF switches along with HT. */
512 	{
513 	PMURES_BIT(RES4319_HT_AVAIL),
514 		    RES_DEPEND_ADD,
515 		    PMURES_BIT(RES4319_RX_PWRSW_PU) |
516 		    PMURES_BIT(RES4319_TX_PWRSW_PU) |
517 		    PMURES_BIT(RES4319_RFPLL_PWRSW_PU) |
518 		    PMURES_BIT(RES4319_LOGEN_PWRSW_PU) |
519 		    PMURES_BIT(RES4319_AFE_PWRSW_PU), NULL}
520 };
521 
522 static const pmu_res_updown_t bcm4336a0_res_updown_qt[] = {
523 	{
524 	RES4336_HT_AVAIL, 0x0101}, {
525 	RES4336_XTAL_PU, 0x0100}, {
526 	RES4336_CLDO_PU, 0x0100}, {
527 	RES4336_CBUCK_PWM, 0x0100}, {
528 	RES4336_CBUCK_BURST, 0x0100}, {
529 	RES4336_CBUCK_LPOM, 0x0100}
530 };
531 
532 static const pmu_res_updown_t bcm4336a0_res_updown[] = {
533 	{
534 	RES4336_HT_AVAIL, 0x0D01}
535 };
536 
537 static const pmu_res_depend_t bcm4336a0_res_depend[] = {
538 	/* Just a dummy entry for now */
539 	{
540 	PMURES_BIT(RES4336_RSVD), RES_DEPEND_ADD, 0, NULL}
541 };
542 
543 static const pmu_res_updown_t bcm4330a0_res_updown_qt[] = {
544 	{
545 	RES4330_HT_AVAIL, 0x0101}, {
546 	RES4330_XTAL_PU, 0x0100}, {
547 	RES4330_CLDO_PU, 0x0100}, {
548 	RES4330_CBUCK_PWM, 0x0100}, {
549 	RES4330_CBUCK_BURST, 0x0100}, {
550 	RES4330_CBUCK_LPOM, 0x0100}
551 };
552 
553 static const pmu_res_updown_t bcm4330a0_res_updown[] = {
554 	{
555 	RES4330_HT_AVAIL, 0x0e02}
556 };
557 
558 static const pmu_res_depend_t bcm4330a0_res_depend[] = {
559 	/* Just a dummy entry for now */
560 	{
561 	PMURES_BIT(RES4330_HT_AVAIL), RES_DEPEND_ADD, 0, NULL}
562 };
563 
564 /* true if the power topology uses the buck boost to provide 3.3V to VDDIO_RF and WLAN PA */
si_pmu_res_depfltr_bb(si_t * sih)565 static bool si_pmu_res_depfltr_bb(si_t *sih)
566 {
567 	return (sih->boardflags & BFL_BUCKBOOST) != 0;
568 }
569 
570 /* true if the power topology doesn't use the cbuck. Key on chiprev also if the chip is BCM4325. */
si_pmu_res_depfltr_ncb(si_t * sih)571 static bool si_pmu_res_depfltr_ncb(si_t *sih)
572 {
573 
574 	return (sih->boardflags & BFL_NOCBUCK) != 0;
575 }
576 
577 /* true if the power topology uses the PALDO */
si_pmu_res_depfltr_paldo(si_t * sih)578 static bool si_pmu_res_depfltr_paldo(si_t *sih)
579 {
580 	return (sih->boardflags & BFL_PALDO) != 0;
581 }
582 
583 /* true if the power topology doesn't use the PALDO */
si_pmu_res_depfltr_npaldo(si_t * sih)584 static bool si_pmu_res_depfltr_npaldo(si_t *sih)
585 {
586 	return (sih->boardflags & BFL_PALDO) == 0;
587 }
588 
589 #define BCM94325_BBVDDIOSD_BOARDS(sih) (sih->boardtype == BCM94325DEVBU_BOARD || \
590 					sih->boardtype == BCM94325BGABU_BOARD)
591 
592 /* Determine min/max rsrc masks. Value 0 leaves hardware at default. */
si_pmu_res_masks(si_t * sih,u32 * pmin,u32 * pmax)593 static void si_pmu_res_masks(si_t *sih, u32 * pmin, u32 * pmax)
594 {
595 	u32 min_mask = 0, max_mask = 0;
596 	uint rsrcs;
597 	char *val;
598 
599 	/* # resources */
600 	rsrcs = (sih->pmucaps & PCAP_RC_MASK) >> PCAP_RC_SHIFT;
601 
602 	/* determine min/max rsrc masks */
603 	switch (sih->chip) {
604 	case BCM43224_CHIP_ID:
605 	case BCM43225_CHIP_ID:
606 	case BCM43421_CHIP_ID:
607 	case BCM43235_CHIP_ID:
608 	case BCM43236_CHIP_ID:
609 	case BCM43238_CHIP_ID:
610 	case BCM4331_CHIP_ID:
611 	case BCM6362_CHIP_ID:
612 		/* ??? */
613 		break;
614 
615 	case BCM4329_CHIP_ID:
616 		/* 4329 spedific issue. Needs to come back this issue later */
617 		/* Down to save the power. */
618 		min_mask =
619 		    PMURES_BIT(RES4329_CBUCK_LPOM) |
620 		    PMURES_BIT(RES4329_CLDO_PU);
621 		/* Allow (but don't require) PLL to turn on */
622 		max_mask = 0x3ff63e;
623 		break;
624 	case BCM4319_CHIP_ID:
625 		/* We only need a few resources to be kept on all the time */
626 		min_mask = PMURES_BIT(RES4319_CBUCK_LPOM) |
627 		    PMURES_BIT(RES4319_CLDO_PU);
628 
629 		/* Allow everything else to be turned on upon requests */
630 		max_mask = ~(~0 << rsrcs);
631 		break;
632 	case BCM4336_CHIP_ID:
633 		/* Down to save the power. */
634 		min_mask =
635 		    PMURES_BIT(RES4336_CBUCK_LPOM) | PMURES_BIT(RES4336_CLDO_PU)
636 		    | PMURES_BIT(RES4336_LDO3P3_PU) | PMURES_BIT(RES4336_OTP_PU)
637 		    | PMURES_BIT(RES4336_DIS_INT_RESET_PD);
638 		/* Allow (but don't require) PLL to turn on */
639 		max_mask = 0x1ffffff;
640 		break;
641 
642 	case BCM4330_CHIP_ID:
643 		/* Down to save the power. */
644 		min_mask =
645 		    PMURES_BIT(RES4330_CBUCK_LPOM) | PMURES_BIT(RES4330_CLDO_PU)
646 		    | PMURES_BIT(RES4330_DIS_INT_RESET_PD) |
647 		    PMURES_BIT(RES4330_LDO3P3_PU) | PMURES_BIT(RES4330_OTP_PU);
648 		/* Allow (but don't require) PLL to turn on */
649 		max_mask = 0xfffffff;
650 		break;
651 
652 	case BCM4313_CHIP_ID:
653 		min_mask = PMURES_BIT(RES4313_BB_PU_RSRC) |
654 		    PMURES_BIT(RES4313_XTAL_PU_RSRC) |
655 		    PMURES_BIT(RES4313_ALP_AVAIL_RSRC) |
656 		    PMURES_BIT(RES4313_BB_PLL_PWRSW_RSRC);
657 		max_mask = 0xffff;
658 		break;
659 	default:
660 		break;
661 	}
662 
663 	/* Apply nvram override to min mask */
664 	val = getvar(NULL, "rmin");
665 	if (val != NULL) {
666 		PMU_MSG(("Applying rmin=%s to min_mask\n", val));
667 		min_mask = (u32) simple_strtoul(val, NULL, 0);
668 	}
669 	/* Apply nvram override to max mask */
670 	val = getvar(NULL, "rmax");
671 	if (val != NULL) {
672 		PMU_MSG(("Applying rmax=%s to max_mask\n", val));
673 		max_mask = (u32) simple_strtoul(val, NULL, 0);
674 	}
675 
676 	*pmin = min_mask;
677 	*pmax = max_mask;
678 }
679 
680 /* initialize PMU resources */
si_pmu_res_init(si_t * sih)681 void si_pmu_res_init(si_t *sih)
682 {
683 	chipcregs_t *cc;
684 	uint origidx;
685 	const pmu_res_updown_t *pmu_res_updown_table = NULL;
686 	uint pmu_res_updown_table_sz = 0;
687 	const pmu_res_depend_t *pmu_res_depend_table = NULL;
688 	uint pmu_res_depend_table_sz = 0;
689 	u32 min_mask = 0, max_mask = 0;
690 	char name[8], *val;
691 	uint i, rsrcs;
692 
693 	ASSERT(sih->cccaps & CC_CAP_PMU);
694 
695 	/* Remember original core before switch to chipc */
696 	origidx = si_coreidx(sih);
697 	cc = si_setcoreidx(sih, SI_CC_IDX);
698 	ASSERT(cc != NULL);
699 
700 	switch (sih->chip) {
701 	case BCM4329_CHIP_ID:
702 		/* Optimize resources up/down timers */
703 		if (ISSIM_ENAB(sih)) {
704 			pmu_res_updown_table = NULL;
705 			pmu_res_updown_table_sz = 0;
706 		} else {
707 			pmu_res_updown_table = bcm4329_res_updown;
708 			pmu_res_updown_table_sz = ARRAY_SIZE(bcm4329_res_updown);
709 		}
710 		/* Optimize resources dependencies */
711 		pmu_res_depend_table = bcm4329_res_depend;
712 		pmu_res_depend_table_sz = ARRAY_SIZE(bcm4329_res_depend);
713 		break;
714 
715 	case BCM4319_CHIP_ID:
716 		/* Optimize resources up/down timers */
717 		if (ISSIM_ENAB(sih)) {
718 			pmu_res_updown_table = bcm4319a0_res_updown_qt;
719 			pmu_res_updown_table_sz =
720 			    ARRAY_SIZE(bcm4319a0_res_updown_qt);
721 		} else {
722 			pmu_res_updown_table = bcm4319a0_res_updown;
723 			pmu_res_updown_table_sz =
724 			    ARRAY_SIZE(bcm4319a0_res_updown);
725 		}
726 		/* Optimize resources dependancies masks */
727 		pmu_res_depend_table = bcm4319a0_res_depend;
728 		pmu_res_depend_table_sz = ARRAY_SIZE(bcm4319a0_res_depend);
729 		break;
730 
731 	case BCM4336_CHIP_ID:
732 		/* Optimize resources up/down timers */
733 		if (ISSIM_ENAB(sih)) {
734 			pmu_res_updown_table = bcm4336a0_res_updown_qt;
735 			pmu_res_updown_table_sz =
736 			    ARRAY_SIZE(bcm4336a0_res_updown_qt);
737 		} else {
738 			pmu_res_updown_table = bcm4336a0_res_updown;
739 			pmu_res_updown_table_sz =
740 			    ARRAY_SIZE(bcm4336a0_res_updown);
741 		}
742 		/* Optimize resources dependancies masks */
743 		pmu_res_depend_table = bcm4336a0_res_depend;
744 		pmu_res_depend_table_sz = ARRAY_SIZE(bcm4336a0_res_depend);
745 		break;
746 
747 	case BCM4330_CHIP_ID:
748 		/* Optimize resources up/down timers */
749 		if (ISSIM_ENAB(sih)) {
750 			pmu_res_updown_table = bcm4330a0_res_updown_qt;
751 			pmu_res_updown_table_sz =
752 			    ARRAY_SIZE(bcm4330a0_res_updown_qt);
753 		} else {
754 			pmu_res_updown_table = bcm4330a0_res_updown;
755 			pmu_res_updown_table_sz =
756 			    ARRAY_SIZE(bcm4330a0_res_updown);
757 		}
758 		/* Optimize resources dependancies masks */
759 		pmu_res_depend_table = bcm4330a0_res_depend;
760 		pmu_res_depend_table_sz = ARRAY_SIZE(bcm4330a0_res_depend);
761 		break;
762 
763 	default:
764 		break;
765 	}
766 
767 	/* # resources */
768 	rsrcs = (sih->pmucaps & PCAP_RC_MASK) >> PCAP_RC_SHIFT;
769 
770 	/* Program up/down timers */
771 	while (pmu_res_updown_table_sz--) {
772 		ASSERT(pmu_res_updown_table != NULL);
773 		PMU_MSG(("Changing rsrc %d res_updn_timer to 0x%x\n",
774 			 pmu_res_updown_table[pmu_res_updown_table_sz].resnum,
775 			 pmu_res_updown_table[pmu_res_updown_table_sz].updown));
776 		W_REG(&cc->res_table_sel,
777 		      pmu_res_updown_table[pmu_res_updown_table_sz].resnum);
778 		W_REG(&cc->res_updn_timer,
779 		      pmu_res_updown_table[pmu_res_updown_table_sz].updown);
780 	}
781 	/* Apply nvram overrides to up/down timers */
782 	for (i = 0; i < rsrcs; i++) {
783 		snprintf(name, sizeof(name), "r%dt", i);
784 		val = getvar(NULL, name);
785 		if (val == NULL)
786 			continue;
787 		PMU_MSG(("Applying %s=%s to rsrc %d res_updn_timer\n", name,
788 			 val, i));
789 		W_REG(&cc->res_table_sel, (u32) i);
790 		W_REG(&cc->res_updn_timer,
791 		      (u32) simple_strtoul(val, NULL, 0));
792 	}
793 
794 	/* Program resource dependencies table */
795 	while (pmu_res_depend_table_sz--) {
796 		ASSERT(pmu_res_depend_table != NULL);
797 		if (pmu_res_depend_table[pmu_res_depend_table_sz].filter != NULL
798 		    && !(pmu_res_depend_table[pmu_res_depend_table_sz].
799 			 filter) (sih))
800 			continue;
801 		for (i = 0; i < rsrcs; i++) {
802 			if ((pmu_res_depend_table[pmu_res_depend_table_sz].
803 			     res_mask & PMURES_BIT(i)) == 0)
804 				continue;
805 			W_REG(&cc->res_table_sel, i);
806 			switch (pmu_res_depend_table[pmu_res_depend_table_sz].
807 				action) {
808 			case RES_DEPEND_SET:
809 				PMU_MSG(("Changing rsrc %d res_dep_mask to 0x%x\n", i, pmu_res_depend_table[pmu_res_depend_table_sz].depend_mask));
810 				W_REG(&cc->res_dep_mask,
811 				      pmu_res_depend_table
812 				      [pmu_res_depend_table_sz].depend_mask);
813 				break;
814 			case RES_DEPEND_ADD:
815 				PMU_MSG(("Adding 0x%x to rsrc %d res_dep_mask\n", pmu_res_depend_table[pmu_res_depend_table_sz].depend_mask, i));
816 				OR_REG(&cc->res_dep_mask,
817 				       pmu_res_depend_table
818 				       [pmu_res_depend_table_sz].depend_mask);
819 				break;
820 			case RES_DEPEND_REMOVE:
821 				PMU_MSG(("Removing 0x%x from rsrc %d res_dep_mask\n", pmu_res_depend_table[pmu_res_depend_table_sz].depend_mask, i));
822 				AND_REG(&cc->res_dep_mask,
823 					~pmu_res_depend_table
824 					[pmu_res_depend_table_sz].depend_mask);
825 				break;
826 			default:
827 				ASSERT(0);
828 				break;
829 			}
830 		}
831 	}
832 	/* Apply nvram overrides to dependancies masks */
833 	for (i = 0; i < rsrcs; i++) {
834 		snprintf(name, sizeof(name), "r%dd", i);
835 		val = getvar(NULL, name);
836 		if (val == NULL)
837 			continue;
838 		PMU_MSG(("Applying %s=%s to rsrc %d res_dep_mask\n", name, val,
839 			 i));
840 		W_REG(&cc->res_table_sel, (u32) i);
841 		W_REG(&cc->res_dep_mask,
842 		      (u32) simple_strtoul(val, NULL, 0));
843 	}
844 
845 	/* Determine min/max rsrc masks */
846 	si_pmu_res_masks(sih, &min_mask, &max_mask);
847 
848 	/* It is required to program max_mask first and then min_mask */
849 
850 	/* Program max resource mask */
851 
852 	if (max_mask) {
853 		PMU_MSG(("Changing max_res_mask to 0x%x\n", max_mask));
854 		W_REG(&cc->max_res_mask, max_mask);
855 	}
856 
857 	/* Program min resource mask */
858 
859 	if (min_mask) {
860 		PMU_MSG(("Changing min_res_mask to 0x%x\n", min_mask));
861 		W_REG(&cc->min_res_mask, min_mask);
862 	}
863 
864 	/* Add some delay; allow resources to come up and settle. */
865 	mdelay(2);
866 
867 	/* Return to original core */
868 	si_setcoreidx(sih, origidx);
869 }
870 
871 /* setup pll and query clock speed */
872 typedef struct {
873 	u16 freq;
874 	u8 xf;
875 	u8 wbint;
876 	u32 wbfrac;
877 } pmu0_xtaltab0_t;
878 
879 /* the following table is based on 880Mhz fvco */
880 static const pmu0_xtaltab0_t pmu0_xtaltab0[] = {
881 	{
882 	12000, 1, 73, 349525}, {
883 	13000, 2, 67, 725937}, {
884 	14400, 3, 61, 116508}, {
885 	15360, 4, 57, 305834}, {
886 	16200, 5, 54, 336579}, {
887 	16800, 6, 52, 399457}, {
888 	19200, 7, 45, 873813}, {
889 	19800, 8, 44, 466033}, {
890 	20000, 9, 44, 0}, {
891 	25000, 10, 70, 419430}, {
892 	26000, 11, 67, 725937}, {
893 	30000, 12, 58, 699050}, {
894 	38400, 13, 45, 873813}, {
895 	40000, 14, 45, 0}, {
896 	0, 0, 0, 0}
897 };
898 
899 #define PMU0_XTAL0_DEFAULT	8
900 
901 /* setup pll and query clock speed */
902 typedef struct {
903 	u16 fref;
904 	u8 xf;
905 	u8 p1div;
906 	u8 p2div;
907 	u8 ndiv_int;
908 	u32 ndiv_frac;
909 } pmu1_xtaltab0_t;
910 
911 static const pmu1_xtaltab0_t pmu1_xtaltab0_880_4329[] = {
912 	{
913 	12000, 1, 3, 22, 0x9, 0xFFFFEF}, {
914 	13000, 2, 1, 6, 0xb, 0x483483}, {
915 	14400, 3, 1, 10, 0xa, 0x1C71C7}, {
916 	15360, 4, 1, 5, 0xb, 0x755555}, {
917 	16200, 5, 1, 10, 0x5, 0x6E9E06}, {
918 	16800, 6, 1, 10, 0x5, 0x3Cf3Cf}, {
919 	19200, 7, 1, 4, 0xb, 0x755555}, {
920 	19800, 8, 1, 11, 0x4, 0xA57EB}, {
921 	20000, 9, 1, 11, 0x4, 0x0}, {
922 	24000, 10, 3, 11, 0xa, 0x0}, {
923 	25000, 11, 5, 16, 0xb, 0x0}, {
924 	26000, 12, 1, 1, 0x21, 0xD89D89}, {
925 	30000, 13, 3, 8, 0xb, 0x0}, {
926 	37400, 14, 3, 1, 0x46, 0x969696}, {
927 	38400, 15, 1, 1, 0x16, 0xEAAAAA}, {
928 	40000, 16, 1, 2, 0xb, 0}, {
929 	0, 0, 0, 0, 0, 0}
930 };
931 
932 /* the following table is based on 880Mhz fvco */
933 static const pmu1_xtaltab0_t pmu1_xtaltab0_880[] = {
934 	{
935 	12000, 1, 3, 22, 0x9, 0xFFFFEF}, {
936 	13000, 2, 1, 6, 0xb, 0x483483}, {
937 	14400, 3, 1, 10, 0xa, 0x1C71C7}, {
938 	15360, 4, 1, 5, 0xb, 0x755555}, {
939 	16200, 5, 1, 10, 0x5, 0x6E9E06}, {
940 	16800, 6, 1, 10, 0x5, 0x3Cf3Cf}, {
941 	19200, 7, 1, 4, 0xb, 0x755555}, {
942 	19800, 8, 1, 11, 0x4, 0xA57EB}, {
943 	20000, 9, 1, 11, 0x4, 0x0}, {
944 	24000, 10, 3, 11, 0xa, 0x0}, {
945 	25000, 11, 5, 16, 0xb, 0x0}, {
946 	26000, 12, 1, 2, 0x10, 0xEC4EC4}, {
947 	30000, 13, 3, 8, 0xb, 0x0}, {
948 	33600, 14, 1, 2, 0xd, 0x186186}, {
949 	38400, 15, 1, 2, 0xb, 0x755555}, {
950 	40000, 16, 1, 2, 0xb, 0}, {
951 	0, 0, 0, 0, 0, 0}
952 };
953 
954 #define PMU1_XTALTAB0_880_12000K	0
955 #define PMU1_XTALTAB0_880_13000K	1
956 #define PMU1_XTALTAB0_880_14400K	2
957 #define PMU1_XTALTAB0_880_15360K	3
958 #define PMU1_XTALTAB0_880_16200K	4
959 #define PMU1_XTALTAB0_880_16800K	5
960 #define PMU1_XTALTAB0_880_19200K	6
961 #define PMU1_XTALTAB0_880_19800K	7
962 #define PMU1_XTALTAB0_880_20000K	8
963 #define PMU1_XTALTAB0_880_24000K	9
964 #define PMU1_XTALTAB0_880_25000K	10
965 #define PMU1_XTALTAB0_880_26000K	11
966 #define PMU1_XTALTAB0_880_30000K	12
967 #define PMU1_XTALTAB0_880_37400K	13
968 #define PMU1_XTALTAB0_880_38400K	14
969 #define PMU1_XTALTAB0_880_40000K	15
970 
971 /* the following table is based on 1760Mhz fvco */
972 static const pmu1_xtaltab0_t pmu1_xtaltab0_1760[] = {
973 	{
974 	12000, 1, 3, 44, 0x9, 0xFFFFEF}, {
975 	13000, 2, 1, 12, 0xb, 0x483483}, {
976 	14400, 3, 1, 20, 0xa, 0x1C71C7}, {
977 	15360, 4, 1, 10, 0xb, 0x755555}, {
978 	16200, 5, 1, 20, 0x5, 0x6E9E06}, {
979 	16800, 6, 1, 20, 0x5, 0x3Cf3Cf}, {
980 	19200, 7, 1, 18, 0x5, 0x17B425}, {
981 	19800, 8, 1, 22, 0x4, 0xA57EB}, {
982 	20000, 9, 1, 22, 0x4, 0x0}, {
983 	24000, 10, 3, 22, 0xa, 0x0}, {
984 	25000, 11, 5, 32, 0xb, 0x0}, {
985 	26000, 12, 1, 4, 0x10, 0xEC4EC4}, {
986 	30000, 13, 3, 16, 0xb, 0x0}, {
987 	38400, 14, 1, 10, 0x4, 0x955555}, {
988 	40000, 15, 1, 4, 0xb, 0}, {
989 	0, 0, 0, 0, 0, 0}
990 };
991 
992 /* table index */
993 #define PMU1_XTALTAB0_1760_12000K	0
994 #define PMU1_XTALTAB0_1760_13000K	1
995 #define PMU1_XTALTAB0_1760_14400K	2
996 #define PMU1_XTALTAB0_1760_15360K	3
997 #define PMU1_XTALTAB0_1760_16200K	4
998 #define PMU1_XTALTAB0_1760_16800K	5
999 #define PMU1_XTALTAB0_1760_19200K	6
1000 #define PMU1_XTALTAB0_1760_19800K	7
1001 #define PMU1_XTALTAB0_1760_20000K	8
1002 #define PMU1_XTALTAB0_1760_24000K	9
1003 #define PMU1_XTALTAB0_1760_25000K	10
1004 #define PMU1_XTALTAB0_1760_26000K	11
1005 #define PMU1_XTALTAB0_1760_30000K	12
1006 #define PMU1_XTALTAB0_1760_38400K	13
1007 #define PMU1_XTALTAB0_1760_40000K	14
1008 
1009 /* the following table is based on 1440Mhz fvco */
1010 static const pmu1_xtaltab0_t pmu1_xtaltab0_1440[] = {
1011 	{
1012 	12000, 1, 1, 1, 0x78, 0x0}, {
1013 	13000, 2, 1, 1, 0x6E, 0xC4EC4E}, {
1014 	14400, 3, 1, 1, 0x64, 0x0}, {
1015 	15360, 4, 1, 1, 0x5D, 0xC00000}, {
1016 	16200, 5, 1, 1, 0x58, 0xE38E38}, {
1017 	16800, 6, 1, 1, 0x55, 0xB6DB6D}, {
1018 	19200, 7, 1, 1, 0x4B, 0}, {
1019 	19800, 8, 1, 1, 0x48, 0xBA2E8B}, {
1020 	20000, 9, 1, 1, 0x48, 0x0}, {
1021 	25000, 10, 1, 1, 0x39, 0x999999}, {
1022 	26000, 11, 1, 1, 0x37, 0x627627}, {
1023 	30000, 12, 1, 1, 0x30, 0x0}, {
1024 	37400, 13, 2, 1, 0x4D, 0x15E76}, {
1025 	38400, 13, 2, 1, 0x4B, 0x0}, {
1026 	40000, 14, 2, 1, 0x48, 0x0}, {
1027 	48000, 15, 2, 1, 0x3c, 0x0}, {
1028 	0, 0, 0, 0, 0, 0}
1029 };
1030 
1031 /* table index */
1032 #define PMU1_XTALTAB0_1440_12000K	0
1033 #define PMU1_XTALTAB0_1440_13000K	1
1034 #define PMU1_XTALTAB0_1440_14400K	2
1035 #define PMU1_XTALTAB0_1440_15360K	3
1036 #define PMU1_XTALTAB0_1440_16200K	4
1037 #define PMU1_XTALTAB0_1440_16800K	5
1038 #define PMU1_XTALTAB0_1440_19200K	6
1039 #define PMU1_XTALTAB0_1440_19800K	7
1040 #define PMU1_XTALTAB0_1440_20000K	8
1041 #define PMU1_XTALTAB0_1440_25000K	9
1042 #define PMU1_XTALTAB0_1440_26000K	10
1043 #define PMU1_XTALTAB0_1440_30000K	11
1044 #define PMU1_XTALTAB0_1440_37400K	12
1045 #define PMU1_XTALTAB0_1440_38400K	13
1046 #define PMU1_XTALTAB0_1440_40000K	14
1047 #define PMU1_XTALTAB0_1440_48000K	15
1048 
1049 #define XTAL_FREQ_24000MHZ		24000
1050 #define XTAL_FREQ_30000MHZ		30000
1051 #define XTAL_FREQ_37400MHZ		37400
1052 #define XTAL_FREQ_48000MHZ		48000
1053 
1054 static const pmu1_xtaltab0_t pmu1_xtaltab0_960[] = {
1055 	{
1056 	12000, 1, 1, 1, 0x50, 0x0}, {
1057 	13000, 2, 1, 1, 0x49, 0xD89D89}, {
1058 	14400, 3, 1, 1, 0x42, 0xAAAAAA}, {
1059 	15360, 4, 1, 1, 0x3E, 0x800000}, {
1060 	16200, 5, 1, 1, 0x39, 0x425ED0}, {
1061 	16800, 6, 1, 1, 0x39, 0x249249}, {
1062 	19200, 7, 1, 1, 0x32, 0x0}, {
1063 	19800, 8, 1, 1, 0x30, 0x7C1F07}, {
1064 	20000, 9, 1, 1, 0x30, 0x0}, {
1065 	25000, 10, 1, 1, 0x26, 0x666666}, {
1066 	26000, 11, 1, 1, 0x24, 0xEC4EC4}, {
1067 	30000, 12, 1, 1, 0x20, 0x0}, {
1068 	37400, 13, 2, 1, 0x33, 0x563EF9}, {
1069 	38400, 14, 2, 1, 0x32, 0x0}, {
1070 	40000, 15, 2, 1, 0x30, 0x0}, {
1071 	48000, 16, 2, 1, 0x28, 0x0}, {
1072 	0, 0, 0, 0, 0, 0}
1073 };
1074 
1075 /* table index */
1076 #define PMU1_XTALTAB0_960_12000K	0
1077 #define PMU1_XTALTAB0_960_13000K	1
1078 #define PMU1_XTALTAB0_960_14400K	2
1079 #define PMU1_XTALTAB0_960_15360K	3
1080 #define PMU1_XTALTAB0_960_16200K	4
1081 #define PMU1_XTALTAB0_960_16800K	5
1082 #define PMU1_XTALTAB0_960_19200K	6
1083 #define PMU1_XTALTAB0_960_19800K	7
1084 #define PMU1_XTALTAB0_960_20000K	8
1085 #define PMU1_XTALTAB0_960_25000K	9
1086 #define PMU1_XTALTAB0_960_26000K	10
1087 #define PMU1_XTALTAB0_960_30000K	11
1088 #define PMU1_XTALTAB0_960_37400K	12
1089 #define PMU1_XTALTAB0_960_38400K	13
1090 #define PMU1_XTALTAB0_960_40000K	14
1091 #define PMU1_XTALTAB0_960_48000K	15
1092 
1093 /* select xtal table for each chip */
si_pmu1_xtaltab0(si_t * sih)1094 static const pmu1_xtaltab0_t *si_pmu1_xtaltab0(si_t *sih)
1095 {
1096 #ifdef BCMDBG
1097 	char chn[8];
1098 #endif
1099 	switch (sih->chip) {
1100 	case BCM4329_CHIP_ID:
1101 		return pmu1_xtaltab0_880_4329;
1102 	case BCM4319_CHIP_ID:
1103 		return pmu1_xtaltab0_1440;
1104 	case BCM4336_CHIP_ID:
1105 		return pmu1_xtaltab0_960;
1106 	case BCM4330_CHIP_ID:
1107 		if (CST4330_CHIPMODE_SDIOD(sih->chipst))
1108 			return pmu1_xtaltab0_960;
1109 		else
1110 			return pmu1_xtaltab0_1440;
1111 	default:
1112 		PMU_MSG(("si_pmu1_xtaltab0: Unknown chipid %s\n",
1113 			 bcm_chipname(sih->chip, chn, 8)));
1114 		break;
1115 	}
1116 	ASSERT(0);
1117 	return NULL;
1118 }
1119 
1120 /* select default xtal frequency for each chip */
si_pmu1_xtaldef0(si_t * sih)1121 static const pmu1_xtaltab0_t *si_pmu1_xtaldef0(si_t *sih)
1122 {
1123 #ifdef BCMDBG
1124 	char chn[8];
1125 #endif
1126 
1127 	switch (sih->chip) {
1128 	case BCM4329_CHIP_ID:
1129 		/* Default to 38400Khz */
1130 		return &pmu1_xtaltab0_880_4329[PMU1_XTALTAB0_880_38400K];
1131 	case BCM4319_CHIP_ID:
1132 		/* Default to 30000Khz */
1133 		return &pmu1_xtaltab0_1440[PMU1_XTALTAB0_1440_30000K];
1134 	case BCM4336_CHIP_ID:
1135 		/* Default to 26000Khz */
1136 		return &pmu1_xtaltab0_960[PMU1_XTALTAB0_960_26000K];
1137 	case BCM4330_CHIP_ID:
1138 		/* Default to 37400Khz */
1139 		if (CST4330_CHIPMODE_SDIOD(sih->chipst))
1140 			return &pmu1_xtaltab0_960[PMU1_XTALTAB0_960_37400K];
1141 		else
1142 			return &pmu1_xtaltab0_1440[PMU1_XTALTAB0_1440_37400K];
1143 	default:
1144 		PMU_MSG(("si_pmu1_xtaldef0: Unknown chipid %s\n",
1145 			 bcm_chipname(sih->chip, chn, 8)));
1146 		break;
1147 	}
1148 	ASSERT(0);
1149 	return NULL;
1150 }
1151 
1152 /* select default pll fvco for each chip */
si_pmu1_pllfvco0(si_t * sih)1153 static u32 si_pmu1_pllfvco0(si_t *sih)
1154 {
1155 #ifdef BCMDBG
1156 	char chn[8];
1157 #endif
1158 
1159 	switch (sih->chip) {
1160 	case BCM4329_CHIP_ID:
1161 		return FVCO_880;
1162 	case BCM4319_CHIP_ID:
1163 		return FVCO_1440;
1164 	case BCM4336_CHIP_ID:
1165 		return FVCO_960;
1166 	case BCM4330_CHIP_ID:
1167 		if (CST4330_CHIPMODE_SDIOD(sih->chipst))
1168 			return FVCO_960;
1169 		else
1170 			return FVCO_1440;
1171 	default:
1172 		PMU_MSG(("si_pmu1_pllfvco0: Unknown chipid %s\n",
1173 			 bcm_chipname(sih->chip, chn, 8)));
1174 		break;
1175 	}
1176 	ASSERT(0);
1177 	return 0;
1178 }
1179 
1180 /* query alp/xtal clock frequency */
1181 static u32
si_pmu1_alpclk0(si_t * sih,chipcregs_t * cc)1182 si_pmu1_alpclk0(si_t *sih, chipcregs_t *cc)
1183 {
1184 	const pmu1_xtaltab0_t *xt;
1185 	u32 xf;
1186 
1187 	/* Find the frequency in the table */
1188 	xf = (R_REG(&cc->pmucontrol) & PCTL_XTALFREQ_MASK) >>
1189 	    PCTL_XTALFREQ_SHIFT;
1190 	for (xt = si_pmu1_xtaltab0(sih); xt != NULL && xt->fref != 0; xt++)
1191 		if (xt->xf == xf)
1192 			break;
1193 	/* Could not find it so assign a default value */
1194 	if (xt == NULL || xt->fref == 0)
1195 		xt = si_pmu1_xtaldef0(sih);
1196 	ASSERT(xt != NULL && xt->fref != 0);
1197 
1198 	return xt->fref * 1000;
1199 }
1200 
1201 /* Set up PLL registers in the PMU as per the crystal speed.
1202  * XtalFreq field in pmucontrol register being 0 indicates the PLL
1203  * is not programmed and the h/w default is assumed to work, in which
1204  * case the xtal frequency is unknown to the s/w so we need to call
1205  * si_pmu1_xtaldef0() wherever it is needed to return a default value.
1206  */
si_pmu1_pllinit0(si_t * sih,chipcregs_t * cc,u32 xtal)1207 static void si_pmu1_pllinit0(si_t *sih, chipcregs_t *cc, u32 xtal)
1208 {
1209 	const pmu1_xtaltab0_t *xt;
1210 	u32 tmp;
1211 	u32 buf_strength = 0;
1212 	u8 ndiv_mode = 1;
1213 
1214 	/* Use h/w default PLL config */
1215 	if (xtal == 0) {
1216 		PMU_MSG(("Unspecified xtal frequency, skip PLL configuration\n"));
1217 		return;
1218 	}
1219 
1220 	/* Find the frequency in the table */
1221 	for (xt = si_pmu1_xtaltab0(sih); xt != NULL && xt->fref != 0; xt++)
1222 		if (xt->fref == xtal)
1223 			break;
1224 
1225 	/* Check current PLL state, bail out if it has been programmed or
1226 	 * we don't know how to program it.
1227 	 */
1228 	if (xt == NULL || xt->fref == 0) {
1229 		PMU_MSG(("Unsupported xtal frequency %d.%d MHz, skip PLL configuration\n", xtal / 1000, xtal % 1000));
1230 		return;
1231 	}
1232 	/*  for 4319 bootloader already programs the PLL but bootloader does not program the
1233 	   PLL4 and PLL5. So Skip this check for 4319
1234 	 */
1235 	if ((((R_REG(&cc->pmucontrol) & PCTL_XTALFREQ_MASK) >>
1236 	      PCTL_XTALFREQ_SHIFT) == xt->xf) &&
1237 	    !((sih->chip == BCM4319_CHIP_ID)
1238 	      || (sih->chip == BCM4330_CHIP_ID))) {
1239 		PMU_MSG(("PLL already programmed for %d.%d MHz\n",
1240 			 xt->fref / 1000, xt->fref % 1000));
1241 		return;
1242 	}
1243 
1244 	PMU_MSG(("XTAL %d.%d MHz (%d)\n", xtal / 1000, xtal % 1000, xt->xf));
1245 	PMU_MSG(("Programming PLL for %d.%d MHz\n", xt->fref / 1000,
1246 		 xt->fref % 1000));
1247 
1248 	switch (sih->chip) {
1249 	case BCM4329_CHIP_ID:
1250 		/* Change the BBPLL drive strength to 8 for all channels */
1251 		buf_strength = 0x888888;
1252 		AND_REG(&cc->min_res_mask,
1253 			~(PMURES_BIT(RES4329_BBPLL_PWRSW_PU) |
1254 			  PMURES_BIT(RES4329_HT_AVAIL)));
1255 		AND_REG(&cc->max_res_mask,
1256 			~(PMURES_BIT(RES4329_BBPLL_PWRSW_PU) |
1257 			  PMURES_BIT(RES4329_HT_AVAIL)));
1258 		SPINWAIT(R_REG(&cc->clk_ctl_st) & CCS_HTAVAIL,
1259 			 PMU_MAX_TRANSITION_DLY);
1260 		ASSERT(!(R_REG(&cc->clk_ctl_st) & CCS_HTAVAIL));
1261 		W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4);
1262 		if (xt->fref == 38400)
1263 			tmp = 0x200024C0;
1264 		else if (xt->fref == 37400)
1265 			tmp = 0x20004500;
1266 		else if (xt->fref == 26000)
1267 			tmp = 0x200024C0;
1268 		else
1269 			tmp = 0x200005C0;	/* Chip Dflt Settings */
1270 		W_REG(&cc->pllcontrol_data, tmp);
1271 		W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5);
1272 		tmp =
1273 		    R_REG(&cc->pllcontrol_data) & PMU1_PLL0_PC5_CLK_DRV_MASK;
1274 		if ((xt->fref == 38400) || (xt->fref == 37400)
1275 		    || (xt->fref == 26000))
1276 			tmp |= 0x15;
1277 		else
1278 			tmp |= 0x25;	/* Chip Dflt Settings */
1279 		W_REG(&cc->pllcontrol_data, tmp);
1280 		break;
1281 
1282 	case BCM4319_CHIP_ID:
1283 		/* Change the BBPLL drive strength to 2 for all channels */
1284 		buf_strength = 0x222222;
1285 
1286 		/* Make sure the PLL is off */
1287 		/* WAR65104: Disable the HT_AVAIL resource first and then
1288 		 * after a delay (more than downtime for HT_AVAIL) remove the
1289 		 * BBPLL resource; backplane clock moves to ALP from HT.
1290 		 */
1291 		AND_REG(&cc->min_res_mask,
1292 			~(PMURES_BIT(RES4319_HT_AVAIL)));
1293 		AND_REG(&cc->max_res_mask,
1294 			~(PMURES_BIT(RES4319_HT_AVAIL)));
1295 
1296 		udelay(100);
1297 		AND_REG(&cc->min_res_mask,
1298 			~(PMURES_BIT(RES4319_BBPLL_PWRSW_PU)));
1299 		AND_REG(&cc->max_res_mask,
1300 			~(PMURES_BIT(RES4319_BBPLL_PWRSW_PU)));
1301 
1302 		udelay(100);
1303 		SPINWAIT(R_REG(&cc->clk_ctl_st) & CCS_HTAVAIL,
1304 			 PMU_MAX_TRANSITION_DLY);
1305 		ASSERT(!(R_REG(&cc->clk_ctl_st) & CCS_HTAVAIL));
1306 		W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4);
1307 		tmp = 0x200005c0;
1308 		W_REG(&cc->pllcontrol_data, tmp);
1309 		break;
1310 
1311 	case BCM4336_CHIP_ID:
1312 		AND_REG(&cc->min_res_mask,
1313 			~(PMURES_BIT(RES4336_HT_AVAIL) |
1314 			  PMURES_BIT(RES4336_MACPHY_CLKAVAIL)));
1315 		AND_REG(&cc->max_res_mask,
1316 			~(PMURES_BIT(RES4336_HT_AVAIL) |
1317 			  PMURES_BIT(RES4336_MACPHY_CLKAVAIL)));
1318 		udelay(100);
1319 		SPINWAIT(R_REG(&cc->clk_ctl_st) & CCS_HTAVAIL,
1320 			 PMU_MAX_TRANSITION_DLY);
1321 		ASSERT(!(R_REG(&cc->clk_ctl_st) & CCS_HTAVAIL));
1322 		break;
1323 
1324 	case BCM4330_CHIP_ID:
1325 		AND_REG(&cc->min_res_mask,
1326 			~(PMURES_BIT(RES4330_HT_AVAIL) |
1327 			  PMURES_BIT(RES4330_MACPHY_CLKAVAIL)));
1328 		AND_REG(&cc->max_res_mask,
1329 			~(PMURES_BIT(RES4330_HT_AVAIL) |
1330 			  PMURES_BIT(RES4330_MACPHY_CLKAVAIL)));
1331 		udelay(100);
1332 		SPINWAIT(R_REG(&cc->clk_ctl_st) & CCS_HTAVAIL,
1333 			 PMU_MAX_TRANSITION_DLY);
1334 		ASSERT(!(R_REG(&cc->clk_ctl_st) & CCS_HTAVAIL));
1335 		break;
1336 
1337 	default:
1338 		ASSERT(0);
1339 	}
1340 
1341 	PMU_MSG(("Done masking\n"));
1342 
1343 	/* Write p1div and p2div to pllcontrol[0] */
1344 	W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0);
1345 	tmp = R_REG(&cc->pllcontrol_data) &
1346 	    ~(PMU1_PLL0_PC0_P1DIV_MASK | PMU1_PLL0_PC0_P2DIV_MASK);
1347 	tmp |=
1348 	    ((xt->
1349 	      p1div << PMU1_PLL0_PC0_P1DIV_SHIFT) & PMU1_PLL0_PC0_P1DIV_MASK) |
1350 	    ((xt->
1351 	      p2div << PMU1_PLL0_PC0_P2DIV_SHIFT) & PMU1_PLL0_PC0_P2DIV_MASK);
1352 	W_REG(&cc->pllcontrol_data, tmp);
1353 
1354 	if ((sih->chip == BCM4330_CHIP_ID))
1355 		si_pmu_set_4330_plldivs(sih);
1356 
1357 	if ((sih->chip == BCM4329_CHIP_ID)
1358 	    && (sih->chiprev == 0)) {
1359 
1360 		W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1);
1361 		tmp = R_REG(&cc->pllcontrol_data);
1362 		tmp = tmp & (~DOT11MAC_880MHZ_CLK_DIVISOR_MASK);
1363 		tmp = tmp | DOT11MAC_880MHZ_CLK_DIVISOR_VAL;
1364 		W_REG(&cc->pllcontrol_data, tmp);
1365 	}
1366 	if ((sih->chip == BCM4319_CHIP_ID) ||
1367 	    (sih->chip == BCM4336_CHIP_ID) ||
1368 	    (sih->chip == BCM4330_CHIP_ID))
1369 		ndiv_mode = PMU1_PLL0_PC2_NDIV_MODE_MFB;
1370 	else
1371 		ndiv_mode = PMU1_PLL0_PC2_NDIV_MODE_MASH;
1372 
1373 	/* Write ndiv_int and ndiv_mode to pllcontrol[2] */
1374 	W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2);
1375 	tmp = R_REG(&cc->pllcontrol_data) &
1376 	    ~(PMU1_PLL0_PC2_NDIV_INT_MASK | PMU1_PLL0_PC2_NDIV_MODE_MASK);
1377 	tmp |=
1378 	    ((xt->
1379 	      ndiv_int << PMU1_PLL0_PC2_NDIV_INT_SHIFT) &
1380 	     PMU1_PLL0_PC2_NDIV_INT_MASK) | ((ndiv_mode <<
1381 					      PMU1_PLL0_PC2_NDIV_MODE_SHIFT) &
1382 					     PMU1_PLL0_PC2_NDIV_MODE_MASK);
1383 	W_REG(&cc->pllcontrol_data, tmp);
1384 
1385 	/* Write ndiv_frac to pllcontrol[3] */
1386 	W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3);
1387 	tmp = R_REG(&cc->pllcontrol_data) & ~PMU1_PLL0_PC3_NDIV_FRAC_MASK;
1388 	tmp |= ((xt->ndiv_frac << PMU1_PLL0_PC3_NDIV_FRAC_SHIFT) &
1389 		PMU1_PLL0_PC3_NDIV_FRAC_MASK);
1390 	W_REG(&cc->pllcontrol_data, tmp);
1391 
1392 	/* Write clock driving strength to pllcontrol[5] */
1393 	if (buf_strength) {
1394 		PMU_MSG(("Adjusting PLL buffer drive strength: %x\n",
1395 			 buf_strength));
1396 
1397 		W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5);
1398 		tmp =
1399 		    R_REG(&cc->pllcontrol_data) & ~PMU1_PLL0_PC5_CLK_DRV_MASK;
1400 		tmp |= (buf_strength << PMU1_PLL0_PC5_CLK_DRV_SHIFT);
1401 		W_REG(&cc->pllcontrol_data, tmp);
1402 	}
1403 
1404 	PMU_MSG(("Done pll\n"));
1405 
1406 	/* to operate the 4319 usb in 24MHz/48MHz; chipcontrol[2][84:83] needs
1407 	 * to be updated.
1408 	 */
1409 	if ((sih->chip == BCM4319_CHIP_ID)
1410 	    && (xt->fref != XTAL_FREQ_30000MHZ)) {
1411 		W_REG(&cc->chipcontrol_addr, PMU1_PLL0_CHIPCTL2);
1412 		tmp =
1413 		    R_REG(&cc->chipcontrol_data) & ~CCTL_4319USB_XTAL_SEL_MASK;
1414 		if (xt->fref == XTAL_FREQ_24000MHZ) {
1415 			tmp |=
1416 			    (CCTL_4319USB_24MHZ_PLL_SEL <<
1417 			     CCTL_4319USB_XTAL_SEL_SHIFT);
1418 		} else if (xt->fref == XTAL_FREQ_48000MHZ) {
1419 			tmp |=
1420 			    (CCTL_4319USB_48MHZ_PLL_SEL <<
1421 			     CCTL_4319USB_XTAL_SEL_SHIFT);
1422 		}
1423 		W_REG(&cc->chipcontrol_data, tmp);
1424 	}
1425 
1426 	/* Flush deferred pll control registers writes */
1427 	if (sih->pmurev >= 2)
1428 		OR_REG(&cc->pmucontrol, PCTL_PLL_PLLCTL_UPD);
1429 
1430 	/* Write XtalFreq. Set the divisor also. */
1431 	tmp = R_REG(&cc->pmucontrol) &
1432 	    ~(PCTL_ILP_DIV_MASK | PCTL_XTALFREQ_MASK);
1433 	tmp |= (((((xt->fref + 127) / 128) - 1) << PCTL_ILP_DIV_SHIFT) &
1434 		PCTL_ILP_DIV_MASK) |
1435 	    ((xt->xf << PCTL_XTALFREQ_SHIFT) & PCTL_XTALFREQ_MASK);
1436 
1437 	if ((sih->chip == BCM4329_CHIP_ID)
1438 	    && sih->chiprev == 0) {
1439 		/* clear the htstretch before clearing HTReqEn */
1440 		AND_REG(&cc->clkstretch, ~CSTRETCH_HT);
1441 		tmp &= ~PCTL_HT_REQ_EN;
1442 	}
1443 
1444 	W_REG(&cc->pmucontrol, tmp);
1445 }
1446 
1447 /* query the CPU clock frequency */
1448 static u32
si_pmu1_cpuclk0(si_t * sih,chipcregs_t * cc)1449 si_pmu1_cpuclk0(si_t *sih, chipcregs_t *cc)
1450 {
1451 	u32 tmp, m1div;
1452 #ifdef BCMDBG
1453 	u32 ndiv_int, ndiv_frac, p2div, p1div, fvco;
1454 	u32 fref;
1455 #endif
1456 	u32 FVCO = si_pmu1_pllfvco0(sih);
1457 
1458 	/* Read m1div from pllcontrol[1] */
1459 	W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1);
1460 	tmp = R_REG(&cc->pllcontrol_data);
1461 	m1div = (tmp & PMU1_PLL0_PC1_M1DIV_MASK) >> PMU1_PLL0_PC1_M1DIV_SHIFT;
1462 
1463 #ifdef BCMDBG
1464 	/* Read p2div/p1div from pllcontrol[0] */
1465 	W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0);
1466 	tmp = R_REG(&cc->pllcontrol_data);
1467 	p2div = (tmp & PMU1_PLL0_PC0_P2DIV_MASK) >> PMU1_PLL0_PC0_P2DIV_SHIFT;
1468 	p1div = (tmp & PMU1_PLL0_PC0_P1DIV_MASK) >> PMU1_PLL0_PC0_P1DIV_SHIFT;
1469 
1470 	/* Calculate fvco based on xtal freq and ndiv and pdiv */
1471 	W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2);
1472 	tmp = R_REG(&cc->pllcontrol_data);
1473 	ndiv_int =
1474 	    (tmp & PMU1_PLL0_PC2_NDIV_INT_MASK) >> PMU1_PLL0_PC2_NDIV_INT_SHIFT;
1475 
1476 	W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3);
1477 	tmp = R_REG(&cc->pllcontrol_data);
1478 	ndiv_frac =
1479 	    (tmp & PMU1_PLL0_PC3_NDIV_FRAC_MASK) >>
1480 	    PMU1_PLL0_PC3_NDIV_FRAC_SHIFT;
1481 
1482 	fref = si_pmu1_alpclk0(sih, cc) / 1000;
1483 
1484 	fvco = (fref * ndiv_int) << 8;
1485 	fvco += (fref * (ndiv_frac >> 12)) >> 4;
1486 	fvco += (fref * (ndiv_frac & 0xfff)) >> 12;
1487 	fvco >>= 8;
1488 	fvco *= p2div;
1489 	fvco /= p1div;
1490 	fvco /= 1000;
1491 	fvco *= 1000;
1492 
1493 	PMU_MSG(("si_pmu1_cpuclk0: ndiv_int %u ndiv_frac %u p2div %u p1div %u fvco %u\n", ndiv_int, ndiv_frac, p2div, p1div, fvco));
1494 
1495 	FVCO = fvco;
1496 #endif				/* BCMDBG */
1497 
1498 	/* Return ARM/SB clock */
1499 	return FVCO / m1div * 1000;
1500 }
1501 
1502 /* initialize PLL */
si_pmu_pll_init(si_t * sih,uint xtalfreq)1503 void si_pmu_pll_init(si_t *sih, uint xtalfreq)
1504 {
1505 	chipcregs_t *cc;
1506 	uint origidx;
1507 #ifdef BCMDBG
1508 	char chn[8];
1509 #endif
1510 
1511 	ASSERT(sih->cccaps & CC_CAP_PMU);
1512 
1513 	/* Remember original core before switch to chipc */
1514 	origidx = si_coreidx(sih);
1515 	cc = si_setcoreidx(sih, SI_CC_IDX);
1516 	ASSERT(cc != NULL);
1517 
1518 	switch (sih->chip) {
1519 	case BCM4329_CHIP_ID:
1520 		if (xtalfreq == 0)
1521 			xtalfreq = 38400;
1522 		si_pmu1_pllinit0(sih, cc, xtalfreq);
1523 		break;
1524 	case BCM4313_CHIP_ID:
1525 	case BCM43224_CHIP_ID:
1526 	case BCM43225_CHIP_ID:
1527 	case BCM43421_CHIP_ID:
1528 	case BCM43235_CHIP_ID:
1529 	case BCM43236_CHIP_ID:
1530 	case BCM43238_CHIP_ID:
1531 	case BCM4331_CHIP_ID:
1532 	case BCM6362_CHIP_ID:
1533 		/* ??? */
1534 		break;
1535 	case BCM4319_CHIP_ID:
1536 	case BCM4336_CHIP_ID:
1537 	case BCM4330_CHIP_ID:
1538 		si_pmu1_pllinit0(sih, cc, xtalfreq);
1539 		break;
1540 	default:
1541 		PMU_MSG(("No PLL init done for chip %s rev %d pmurev %d\n",
1542 			 bcm_chipname(sih->chip, chn, 8), sih->chiprev,
1543 			 sih->pmurev));
1544 		break;
1545 	}
1546 
1547 #ifdef BCMDBG_FORCEHT
1548 	OR_REG(&cc->clk_ctl_st, CCS_FORCEHT);
1549 #endif
1550 
1551 	/* Return to original core */
1552 	si_setcoreidx(sih, origidx);
1553 }
1554 
1555 /* query alp/xtal clock frequency */
si_pmu_alp_clock(si_t * sih)1556 u32 si_pmu_alp_clock(si_t *sih)
1557 {
1558 	chipcregs_t *cc;
1559 	uint origidx;
1560 	u32 clock = ALP_CLOCK;
1561 #ifdef BCMDBG
1562 	char chn[8];
1563 #endif
1564 
1565 	ASSERT(sih->cccaps & CC_CAP_PMU);
1566 
1567 	/* Remember original core before switch to chipc */
1568 	origidx = si_coreidx(sih);
1569 	cc = si_setcoreidx(sih, SI_CC_IDX);
1570 	ASSERT(cc != NULL);
1571 
1572 	switch (sih->chip) {
1573 	case BCM43224_CHIP_ID:
1574 	case BCM43225_CHIP_ID:
1575 	case BCM43421_CHIP_ID:
1576 	case BCM43235_CHIP_ID:
1577 	case BCM43236_CHIP_ID:
1578 	case BCM43238_CHIP_ID:
1579 	case BCM4331_CHIP_ID:
1580 	case BCM6362_CHIP_ID:
1581 	case BCM4716_CHIP_ID:
1582 	case BCM4748_CHIP_ID:
1583 	case BCM47162_CHIP_ID:
1584 	case BCM4313_CHIP_ID:
1585 	case BCM5357_CHIP_ID:
1586 		/* always 20Mhz */
1587 		clock = 20000 * 1000;
1588 		break;
1589 	case BCM4329_CHIP_ID:
1590 	case BCM4319_CHIP_ID:
1591 	case BCM4336_CHIP_ID:
1592 	case BCM4330_CHIP_ID:
1593 
1594 		clock = si_pmu1_alpclk0(sih, cc);
1595 		break;
1596 	case BCM5356_CHIP_ID:
1597 		/* always 25Mhz */
1598 		clock = 25000 * 1000;
1599 		break;
1600 	default:
1601 		PMU_MSG(("No ALP clock specified "
1602 			 "for chip %s rev %d pmurev %d, using default %d Hz\n",
1603 			 bcm_chipname(sih->chip, chn, 8), sih->chiprev,
1604 			 sih->pmurev, clock));
1605 		break;
1606 	}
1607 
1608 	/* Return to original core */
1609 	si_setcoreidx(sih, origidx);
1610 	return clock;
1611 }
1612 
1613 /* Find the output of the "m" pll divider given pll controls that start with
1614  * pllreg "pll0" i.e. 12 for main 6 for phy, 0 for misc.
1615  */
1616 static u32
si_pmu5_clock(si_t * sih,chipcregs_t * cc,uint pll0,uint m)1617 si_pmu5_clock(si_t *sih, chipcregs_t *cc, uint pll0, uint m) {
1618 	u32 tmp, div, ndiv, p1, p2, fc;
1619 
1620 	if ((pll0 & 3) || (pll0 > PMU4716_MAINPLL_PLL0)) {
1621 		PMU_ERROR(("%s: Bad pll0: %d\n", __func__, pll0));
1622 		return 0;
1623 	}
1624 
1625 	/* Strictly there is an m5 divider, but I'm not sure we use it */
1626 	if ((m == 0) || (m > 4)) {
1627 		PMU_ERROR(("%s: Bad m divider: %d\n", __func__, m));
1628 		return 0;
1629 	}
1630 
1631 	if (sih->chip == BCM5357_CHIP_ID) {
1632 		/* Detect failure in clock setting */
1633 		if ((R_REG(&cc->chipstatus) & 0x40000) != 0)
1634 			return 133 * 1000000;
1635 	}
1636 
1637 	W_REG(&cc->pllcontrol_addr, pll0 + PMU5_PLL_P1P2_OFF);
1638 	(void)R_REG(&cc->pllcontrol_addr);
1639 	tmp = R_REG(&cc->pllcontrol_data);
1640 	p1 = (tmp & PMU5_PLL_P1_MASK) >> PMU5_PLL_P1_SHIFT;
1641 	p2 = (tmp & PMU5_PLL_P2_MASK) >> PMU5_PLL_P2_SHIFT;
1642 
1643 	W_REG(&cc->pllcontrol_addr, pll0 + PMU5_PLL_M14_OFF);
1644 	(void)R_REG(&cc->pllcontrol_addr);
1645 	tmp = R_REG(&cc->pllcontrol_data);
1646 	div = (tmp >> ((m - 1) * PMU5_PLL_MDIV_WIDTH)) & PMU5_PLL_MDIV_MASK;
1647 
1648 	W_REG(&cc->pllcontrol_addr, pll0 + PMU5_PLL_NM5_OFF);
1649 	(void)R_REG(&cc->pllcontrol_addr);
1650 	tmp = R_REG(&cc->pllcontrol_data);
1651 	ndiv = (tmp & PMU5_PLL_NDIV_MASK) >> PMU5_PLL_NDIV_SHIFT;
1652 
1653 	/* Do calculation in Mhz */
1654 	fc = si_pmu_alp_clock(sih) / 1000000;
1655 	fc = (p1 * ndiv * fc) / p2;
1656 
1657 	PMU_NONE(("%s: p1=%d, p2=%d, ndiv=%d(0x%x), m%d=%d; fc=%d, clock=%d\n",
1658 		  __func__, p1, p2, ndiv, ndiv, m, div, fc, fc / div));
1659 
1660 	/* Return clock in Hertz */
1661 	return (fc / div) * 1000000;
1662 }
1663 
1664 /* query backplane clock frequency */
1665 /* For designs that feed the same clock to both backplane
1666  * and CPU just return the CPU clock speed.
1667  */
si_pmu_si_clock(si_t * sih)1668 u32 si_pmu_si_clock(si_t *sih)
1669 {
1670 	chipcregs_t *cc;
1671 	uint origidx;
1672 	u32 clock = HT_CLOCK;
1673 #ifdef BCMDBG
1674 	char chn[8];
1675 #endif
1676 
1677 	ASSERT(sih->cccaps & CC_CAP_PMU);
1678 
1679 	/* Remember original core before switch to chipc */
1680 	origidx = si_coreidx(sih);
1681 	cc = si_setcoreidx(sih, SI_CC_IDX);
1682 	ASSERT(cc != NULL);
1683 
1684 	switch (sih->chip) {
1685 	case BCM43224_CHIP_ID:
1686 	case BCM43225_CHIP_ID:
1687 	case BCM43421_CHIP_ID:
1688 	case BCM4331_CHIP_ID:
1689 	case BCM6362_CHIP_ID:
1690 		/* 96MHz backplane clock */
1691 		clock = 96000 * 1000;
1692 		break;
1693 	case BCM4716_CHIP_ID:
1694 	case BCM4748_CHIP_ID:
1695 	case BCM47162_CHIP_ID:
1696 		clock =
1697 		    si_pmu5_clock(sih, cc, PMU4716_MAINPLL_PLL0,
1698 				  PMU5_MAINPLL_SI);
1699 		break;
1700 	case BCM4329_CHIP_ID:
1701 		if (sih->chiprev == 0)
1702 			clock = 38400 * 1000;
1703 		else
1704 			clock = si_pmu1_cpuclk0(sih, cc);
1705 		break;
1706 	case BCM4319_CHIP_ID:
1707 	case BCM4336_CHIP_ID:
1708 	case BCM4330_CHIP_ID:
1709 		clock = si_pmu1_cpuclk0(sih, cc);
1710 		break;
1711 	case BCM4313_CHIP_ID:
1712 		/* 80MHz backplane clock */
1713 		clock = 80000 * 1000;
1714 		break;
1715 	case BCM43235_CHIP_ID:
1716 	case BCM43236_CHIP_ID:
1717 	case BCM43238_CHIP_ID:
1718 		clock =
1719 		    (cc->chipstatus & CST43236_BP_CLK) ? (120000 *
1720 							  1000) : (96000 *
1721 								   1000);
1722 		break;
1723 	case BCM5356_CHIP_ID:
1724 		clock =
1725 		    si_pmu5_clock(sih, cc, PMU5356_MAINPLL_PLL0,
1726 				  PMU5_MAINPLL_SI);
1727 		break;
1728 	case BCM5357_CHIP_ID:
1729 		clock =
1730 		    si_pmu5_clock(sih, cc, PMU5357_MAINPLL_PLL0,
1731 				  PMU5_MAINPLL_SI);
1732 		break;
1733 	default:
1734 		PMU_MSG(("No backplane clock specified "
1735 			 "for chip %s rev %d pmurev %d, using default %d Hz\n",
1736 			 bcm_chipname(sih->chip, chn, 8), sih->chiprev,
1737 			 sih->pmurev, clock));
1738 		break;
1739 	}
1740 
1741 	/* Return to original core */
1742 	si_setcoreidx(sih, origidx);
1743 	return clock;
1744 }
1745 
1746 /* query CPU clock frequency */
si_pmu_cpu_clock(si_t * sih)1747 u32 si_pmu_cpu_clock(si_t *sih)
1748 {
1749 	chipcregs_t *cc;
1750 	uint origidx;
1751 	u32 clock;
1752 
1753 	ASSERT(sih->cccaps & CC_CAP_PMU);
1754 
1755 	if ((sih->pmurev >= 5) &&
1756 	    !((sih->chip == BCM4329_CHIP_ID) ||
1757 	      (sih->chip == BCM4319_CHIP_ID) ||
1758 	      (sih->chip == BCM43236_CHIP_ID) ||
1759 	      (sih->chip == BCM4336_CHIP_ID) ||
1760 	      (sih->chip == BCM4330_CHIP_ID))) {
1761 		uint pll;
1762 
1763 		switch (sih->chip) {
1764 		case BCM5356_CHIP_ID:
1765 			pll = PMU5356_MAINPLL_PLL0;
1766 			break;
1767 		case BCM5357_CHIP_ID:
1768 			pll = PMU5357_MAINPLL_PLL0;
1769 			break;
1770 		default:
1771 			pll = PMU4716_MAINPLL_PLL0;
1772 			break;
1773 		}
1774 
1775 		/* Remember original core before switch to chipc */
1776 		origidx = si_coreidx(sih);
1777 		cc = si_setcoreidx(sih, SI_CC_IDX);
1778 		ASSERT(cc != NULL);
1779 
1780 		clock = si_pmu5_clock(sih, cc, pll, PMU5_MAINPLL_CPU);
1781 
1782 		/* Return to original core */
1783 		si_setcoreidx(sih, origidx);
1784 	} else
1785 		clock = si_pmu_si_clock(sih);
1786 
1787 	return clock;
1788 }
1789 
1790 /* query memory clock frequency */
si_pmu_mem_clock(si_t * sih)1791 u32 si_pmu_mem_clock(si_t *sih)
1792 {
1793 	chipcregs_t *cc;
1794 	uint origidx;
1795 	u32 clock;
1796 
1797 	ASSERT(sih->cccaps & CC_CAP_PMU);
1798 
1799 	if ((sih->pmurev >= 5) &&
1800 	    !((sih->chip == BCM4329_CHIP_ID) ||
1801 	      (sih->chip == BCM4319_CHIP_ID) ||
1802 	      (sih->chip == BCM4330_CHIP_ID) ||
1803 	      (sih->chip == BCM4336_CHIP_ID) ||
1804 	      (sih->chip == BCM43236_CHIP_ID))) {
1805 		uint pll;
1806 
1807 		switch (sih->chip) {
1808 		case BCM5356_CHIP_ID:
1809 			pll = PMU5356_MAINPLL_PLL0;
1810 			break;
1811 		case BCM5357_CHIP_ID:
1812 			pll = PMU5357_MAINPLL_PLL0;
1813 			break;
1814 		default:
1815 			pll = PMU4716_MAINPLL_PLL0;
1816 			break;
1817 		}
1818 
1819 		/* Remember original core before switch to chipc */
1820 		origidx = si_coreidx(sih);
1821 		cc = si_setcoreidx(sih, SI_CC_IDX);
1822 		ASSERT(cc != NULL);
1823 
1824 		clock = si_pmu5_clock(sih, cc, pll, PMU5_MAINPLL_MEM);
1825 
1826 		/* Return to original core */
1827 		si_setcoreidx(sih, origidx);
1828 	} else {
1829 		clock = si_pmu_si_clock(sih);
1830 	}
1831 
1832 	return clock;
1833 }
1834 
1835 /* Measure ILP clock frequency */
1836 #define ILP_CALC_DUR	10	/* ms, make sure 1000 can be divided by it. */
1837 
1838 static u32 ilpcycles_per_sec;
1839 
si_pmu_ilp_clock(si_t * sih)1840 u32 si_pmu_ilp_clock(si_t *sih)
1841 {
1842 	if (ISSIM_ENAB(sih))
1843 		return ILP_CLOCK;
1844 
1845 	if (ilpcycles_per_sec == 0) {
1846 		u32 start, end, delta;
1847 		u32 origidx = si_coreidx(sih);
1848 		chipcregs_t *cc = si_setcoreidx(sih, SI_CC_IDX);
1849 		ASSERT(cc != NULL);
1850 		start = R_REG(&cc->pmutimer);
1851 		mdelay(ILP_CALC_DUR);
1852 		end = R_REG(&cc->pmutimer);
1853 		delta = end - start;
1854 		ilpcycles_per_sec = delta * (1000 / ILP_CALC_DUR);
1855 		si_setcoreidx(sih, origidx);
1856 	}
1857 
1858 	return ilpcycles_per_sec;
1859 }
1860 
1861 /* SDIO Pad drive strength to select value mappings */
1862 typedef struct {
1863 	u8 strength;		/* Pad Drive Strength in mA */
1864 	u8 sel;		/* Chip-specific select value */
1865 } sdiod_drive_str_t;
1866 
1867 /* SDIO Drive Strength to sel value table for PMU Rev 1 */
1868 static const sdiod_drive_str_t sdiod_drive_strength_tab1[] = {
1869 	{
1870 	4, 0x2}, {
1871 	2, 0x3}, {
1872 	1, 0x0}, {
1873 	0, 0x0}
1874 	};
1875 
1876 /* SDIO Drive Strength to sel value table for PMU Rev 2, 3 */
1877 static const sdiod_drive_str_t sdiod_drive_strength_tab2[] = {
1878 	{
1879 	12, 0x7}, {
1880 	10, 0x6}, {
1881 	8, 0x5}, {
1882 	6, 0x4}, {
1883 	4, 0x2}, {
1884 	2, 0x1}, {
1885 	0, 0x0}
1886 	};
1887 
1888 /* SDIO Drive Strength to sel value table for PMU Rev 8 (1.8V) */
1889 static const sdiod_drive_str_t sdiod_drive_strength_tab3[] = {
1890 	{
1891 	32, 0x7}, {
1892 	26, 0x6}, {
1893 	22, 0x5}, {
1894 	16, 0x4}, {
1895 	12, 0x3}, {
1896 	8, 0x2}, {
1897 	4, 0x1}, {
1898 	0, 0x0}
1899 	};
1900 
1901 #define SDIOD_DRVSTR_KEY(chip, pmu)	(((chip) << 16) | (pmu))
1902 
1903 void
si_sdiod_drive_strength_init(si_t * sih,u32 drivestrength)1904 si_sdiod_drive_strength_init(si_t *sih, u32 drivestrength) {
1905 	chipcregs_t *cc;
1906 	uint origidx, intr_val = 0;
1907 	sdiod_drive_str_t *str_tab = NULL;
1908 	u32 str_mask = 0;
1909 	u32 str_shift = 0;
1910 #ifdef BCMDBG
1911 	char chn[8];
1912 #endif
1913 
1914 	if (!(sih->cccaps & CC_CAP_PMU)) {
1915 		return;
1916 	}
1917 
1918 	/* Remember original core before switch to chipc */
1919 	cc = (chipcregs_t *) si_switch_core(sih, CC_CORE_ID, &origidx,
1920 					    &intr_val);
1921 
1922 	switch (SDIOD_DRVSTR_KEY(sih->chip, sih->pmurev)) {
1923 	case SDIOD_DRVSTR_KEY(BCM4325_CHIP_ID, 1):
1924 		str_tab = (sdiod_drive_str_t *)&sdiod_drive_strength_tab1;
1925 		str_mask = 0x30000000;
1926 		str_shift = 28;
1927 		break;
1928 	case SDIOD_DRVSTR_KEY(BCM4325_CHIP_ID, 2):
1929 	case SDIOD_DRVSTR_KEY(BCM4325_CHIP_ID, 3):
1930 		str_tab = (sdiod_drive_str_t *)&sdiod_drive_strength_tab2;
1931 		str_mask = 0x00003800;
1932 		str_shift = 11;
1933 		break;
1934 	case SDIOD_DRVSTR_KEY(BCM4336_CHIP_ID, 8):
1935 		str_tab = (sdiod_drive_str_t *) &sdiod_drive_strength_tab3;
1936 		str_mask = 0x00003800;
1937 		str_shift = 11;
1938 		break;
1939 
1940 	default:
1941 		PMU_MSG(("No SDIO Drive strength init done for chip %s rev %d pmurev %d\n", bcm_chipname(sih->chip, chn, 8), sih->chiprev, sih->pmurev));
1942 
1943 		break;
1944 	}
1945 
1946 	if (str_tab != NULL) {
1947 		u32 drivestrength_sel = 0;
1948 		u32 cc_data_temp;
1949 		int i;
1950 
1951 		for (i = 0; str_tab[i].strength != 0; i++) {
1952 			if (drivestrength >= str_tab[i].strength) {
1953 				drivestrength_sel = str_tab[i].sel;
1954 				break;
1955 			}
1956 		}
1957 
1958 		W_REG(&cc->chipcontrol_addr, 1);
1959 		cc_data_temp = R_REG(&cc->chipcontrol_data);
1960 		cc_data_temp &= ~str_mask;
1961 		drivestrength_sel <<= str_shift;
1962 		cc_data_temp |= drivestrength_sel;
1963 		W_REG(&cc->chipcontrol_data, cc_data_temp);
1964 
1965 		PMU_MSG(("SDIO: %dmA drive strength selected, set to 0x%08x\n",
1966 			 drivestrength, cc_data_temp));
1967 	}
1968 
1969 	/* Return to original core */
1970 	si_restore_core(sih, origidx, intr_val);
1971 }
1972 
1973 /* initialize PMU */
si_pmu_init(si_t * sih)1974 void si_pmu_init(si_t *sih)
1975 {
1976 	chipcregs_t *cc;
1977 	uint origidx;
1978 
1979 	ASSERT(sih->cccaps & CC_CAP_PMU);
1980 
1981 	/* Remember original core before switch to chipc */
1982 	origidx = si_coreidx(sih);
1983 	cc = si_setcoreidx(sih, SI_CC_IDX);
1984 	ASSERT(cc != NULL);
1985 
1986 	if (sih->pmurev == 1)
1987 		AND_REG(&cc->pmucontrol, ~PCTL_NOILP_ON_WAIT);
1988 	else if (sih->pmurev >= 2)
1989 		OR_REG(&cc->pmucontrol, PCTL_NOILP_ON_WAIT);
1990 
1991 	if ((sih->chip == BCM4329_CHIP_ID) && (sih->chiprev == 2)) {
1992 		/* Fix for 4329b0 bad LPOM state. */
1993 		W_REG(&cc->regcontrol_addr, 2);
1994 		OR_REG(&cc->regcontrol_data, 0x100);
1995 
1996 		W_REG(&cc->regcontrol_addr, 3);
1997 		OR_REG(&cc->regcontrol_data, 0x4);
1998 	}
1999 
2000 	/* Return to original core */
2001 	si_setcoreidx(sih, origidx);
2002 }
2003 
2004 /* Return up time in ILP cycles for the given resource. */
2005 static uint
si_pmu_res_uptime(si_t * sih,chipcregs_t * cc,u8 rsrc)2006 si_pmu_res_uptime(si_t *sih, chipcregs_t *cc, u8 rsrc) {
2007 	u32 deps;
2008 	uint up, i, dup, dmax;
2009 	u32 min_mask = 0, max_mask = 0;
2010 
2011 	/* uptime of resource 'rsrc' */
2012 	W_REG(&cc->res_table_sel, rsrc);
2013 	up = (R_REG(&cc->res_updn_timer) >> 8) & 0xff;
2014 
2015 	/* direct dependancies of resource 'rsrc' */
2016 	deps = si_pmu_res_deps(sih, cc, PMURES_BIT(rsrc), false);
2017 	for (i = 0; i <= PMURES_MAX_RESNUM; i++) {
2018 		if (!(deps & PMURES_BIT(i)))
2019 			continue;
2020 		deps &= ~si_pmu_res_deps(sih, cc, PMURES_BIT(i), true);
2021 	}
2022 	si_pmu_res_masks(sih, &min_mask, &max_mask);
2023 	deps &= ~min_mask;
2024 
2025 	/* max uptime of direct dependancies */
2026 	dmax = 0;
2027 	for (i = 0; i <= PMURES_MAX_RESNUM; i++) {
2028 		if (!(deps & PMURES_BIT(i)))
2029 			continue;
2030 		dup = si_pmu_res_uptime(sih, cc, (u8) i);
2031 		if (dmax < dup)
2032 			dmax = dup;
2033 	}
2034 
2035 	PMU_MSG(("si_pmu_res_uptime: rsrc %u uptime %u(deps 0x%08x uptime %u)\n", rsrc, up, deps, dmax));
2036 
2037 	return up + dmax + PMURES_UP_TRANSITION;
2038 }
2039 
2040 /* Return dependancies (direct or all/indirect) for the given resources */
2041 static u32
si_pmu_res_deps(si_t * sih,chipcregs_t * cc,u32 rsrcs,bool all)2042 si_pmu_res_deps(si_t *sih, chipcregs_t *cc, u32 rsrcs,
2043 		bool all)
2044 {
2045 	u32 deps = 0;
2046 	u32 i;
2047 
2048 	for (i = 0; i <= PMURES_MAX_RESNUM; i++) {
2049 		if (!(rsrcs & PMURES_BIT(i)))
2050 			continue;
2051 		W_REG(&cc->res_table_sel, i);
2052 		deps |= R_REG(&cc->res_dep_mask);
2053 	}
2054 
2055 	return !all ? deps : (deps
2056 			      ? (deps |
2057 				 si_pmu_res_deps(sih, cc, deps,
2058 						 true)) : 0);
2059 }
2060 
2061 /* power up/down OTP through PMU resources */
si_pmu_otp_power(si_t * sih,bool on)2062 void si_pmu_otp_power(si_t *sih, bool on)
2063 {
2064 	chipcregs_t *cc;
2065 	uint origidx;
2066 	u32 rsrcs = 0;	/* rsrcs to turn on/off OTP power */
2067 
2068 	ASSERT(sih->cccaps & CC_CAP_PMU);
2069 
2070 	/* Don't do anything if OTP is disabled */
2071 	if (si_is_otp_disabled(sih)) {
2072 		PMU_MSG(("si_pmu_otp_power: OTP is disabled\n"));
2073 		return;
2074 	}
2075 
2076 	/* Remember original core before switch to chipc */
2077 	origidx = si_coreidx(sih);
2078 	cc = si_setcoreidx(sih, SI_CC_IDX);
2079 	ASSERT(cc != NULL);
2080 
2081 	switch (sih->chip) {
2082 	case BCM4329_CHIP_ID:
2083 		rsrcs = PMURES_BIT(RES4329_OTP_PU);
2084 		break;
2085 	case BCM4319_CHIP_ID:
2086 		rsrcs = PMURES_BIT(RES4319_OTP_PU);
2087 		break;
2088 	case BCM4336_CHIP_ID:
2089 		rsrcs = PMURES_BIT(RES4336_OTP_PU);
2090 		break;
2091 	case BCM4330_CHIP_ID:
2092 		rsrcs = PMURES_BIT(RES4330_OTP_PU);
2093 		break;
2094 	default:
2095 		break;
2096 	}
2097 
2098 	if (rsrcs != 0) {
2099 		u32 otps;
2100 
2101 		/* Figure out the dependancies (exclude min_res_mask) */
2102 		u32 deps = si_pmu_res_deps(sih, cc, rsrcs, true);
2103 		u32 min_mask = 0, max_mask = 0;
2104 		si_pmu_res_masks(sih, &min_mask, &max_mask);
2105 		deps &= ~min_mask;
2106 		/* Turn on/off the power */
2107 		if (on) {
2108 			PMU_MSG(("Adding rsrc 0x%x to min_res_mask\n",
2109 				 rsrcs | deps));
2110 			OR_REG(&cc->min_res_mask, (rsrcs | deps));
2111 			SPINWAIT(!(R_REG(&cc->res_state) & rsrcs),
2112 				 PMU_MAX_TRANSITION_DLY);
2113 			ASSERT(R_REG(&cc->res_state) & rsrcs);
2114 		} else {
2115 			PMU_MSG(("Removing rsrc 0x%x from min_res_mask\n",
2116 				 rsrcs | deps));
2117 			AND_REG(&cc->min_res_mask, ~(rsrcs | deps));
2118 		}
2119 
2120 		SPINWAIT((((otps = R_REG(&cc->otpstatus)) & OTPS_READY) !=
2121 			  (on ? OTPS_READY : 0)), 100);
2122 		ASSERT((otps & OTPS_READY) == (on ? OTPS_READY : 0));
2123 		if ((otps & OTPS_READY) != (on ? OTPS_READY : 0))
2124 			PMU_MSG(("OTP ready bit not %s after wait\n",
2125 				 (on ? "ON" : "OFF")));
2126 	}
2127 
2128 	/* Return to original core */
2129 	si_setcoreidx(sih, origidx);
2130 }
2131 
si_pmu_rcal(si_t * sih)2132 void si_pmu_rcal(si_t *sih)
2133 {
2134 	chipcregs_t *cc;
2135 	uint origidx;
2136 
2137 	ASSERT(sih->cccaps & CC_CAP_PMU);
2138 
2139 	/* Remember original core before switch to chipc */
2140 	origidx = si_coreidx(sih);
2141 	cc = si_setcoreidx(sih, SI_CC_IDX);
2142 	ASSERT(cc != NULL);
2143 
2144 	switch (sih->chip) {
2145 	case BCM4329_CHIP_ID:{
2146 			u8 rcal_code;
2147 			u32 val;
2148 
2149 			/* Kick RCal */
2150 			W_REG(&cc->chipcontrol_addr, 1);
2151 
2152 			/* Power Down RCAL Block */
2153 			AND_REG(&cc->chipcontrol_data, ~0x04);
2154 
2155 			/* Power Up RCAL block */
2156 			OR_REG(&cc->chipcontrol_data, 0x04);
2157 
2158 			/* Wait for completion */
2159 			SPINWAIT(0 == (R_REG(&cc->chipstatus) & 0x08),
2160 				 10 * 1000 * 1000);
2161 			ASSERT(R_REG(&cc->chipstatus) & 0x08);
2162 
2163 			/* Drop the LSB to convert from 5 bit code to 4 bit code */
2164 			rcal_code =
2165 			    (u8) (R_REG(&cc->chipstatus) >> 5) & 0x0f;
2166 
2167 			PMU_MSG(("RCal completed, status 0x%x, code 0x%x\n",
2168 				 R_REG(&cc->chipstatus), rcal_code));
2169 
2170 			/* Write RCal code into pmu_vreg_ctrl[32:29] */
2171 			W_REG(&cc->regcontrol_addr, 0);
2172 			val =
2173 			    R_REG(&cc->regcontrol_data) & ~((u32) 0x07 << 29);
2174 			val |= (u32) (rcal_code & 0x07) << 29;
2175 			W_REG(&cc->regcontrol_data, val);
2176 			W_REG(&cc->regcontrol_addr, 1);
2177 			val = R_REG(&cc->regcontrol_data) & ~(u32) 0x01;
2178 			val |= (u32) ((rcal_code >> 3) & 0x01);
2179 			W_REG(&cc->regcontrol_data, val);
2180 
2181 			/* Write RCal code into pmu_chip_ctrl[33:30] */
2182 			W_REG(&cc->chipcontrol_addr, 0);
2183 			val =
2184 			    R_REG(&cc->chipcontrol_data) & ~((u32) 0x03 << 30);
2185 			val |= (u32) (rcal_code & 0x03) << 30;
2186 			W_REG(&cc->chipcontrol_data, val);
2187 			W_REG(&cc->chipcontrol_addr, 1);
2188 			val =
2189 			    R_REG(&cc->chipcontrol_data) & ~(u32) 0x03;
2190 			val |= (u32) ((rcal_code >> 2) & 0x03);
2191 			W_REG(&cc->chipcontrol_data, val);
2192 
2193 			/* Set override in pmu_chip_ctrl[29] */
2194 			W_REG(&cc->chipcontrol_addr, 0);
2195 			OR_REG(&cc->chipcontrol_data, (0x01 << 29));
2196 
2197 			/* Power off RCal block */
2198 			W_REG(&cc->chipcontrol_addr, 1);
2199 			AND_REG(&cc->chipcontrol_data, ~0x04);
2200 
2201 			break;
2202 		}
2203 	default:
2204 		break;
2205 	}
2206 
2207 	/* Return to original core */
2208 	si_setcoreidx(sih, origidx);
2209 }
2210 
si_pmu_spuravoid(si_t * sih,u8 spuravoid)2211 void si_pmu_spuravoid(si_t *sih, u8 spuravoid)
2212 {
2213 	chipcregs_t *cc;
2214 	uint origidx, intr_val;
2215 	u32 tmp = 0;
2216 
2217 	/* Remember original core before switch to chipc */
2218 	cc = (chipcregs_t *) si_switch_core(sih, CC_CORE_ID, &origidx,
2219 					    &intr_val);
2220 	ASSERT(cc != NULL);
2221 
2222 	/* force the HT off  */
2223 	if (sih->chip == BCM4336_CHIP_ID) {
2224 		tmp = R_REG(&cc->max_res_mask);
2225 		tmp &= ~RES4336_HT_AVAIL;
2226 		W_REG(&cc->max_res_mask, tmp);
2227 		/* wait for the ht to really go away */
2228 		SPINWAIT(((R_REG(&cc->clk_ctl_st) & CCS_HTAVAIL) == 0),
2229 			 10000);
2230 		ASSERT((R_REG(&cc->clk_ctl_st) & CCS_HTAVAIL) == 0);
2231 	}
2232 
2233 	/* update the pll changes */
2234 	si_pmu_spuravoid_pllupdate(sih, cc, spuravoid);
2235 
2236 	/* enable HT back on  */
2237 	if (sih->chip == BCM4336_CHIP_ID) {
2238 		tmp = R_REG(&cc->max_res_mask);
2239 		tmp |= RES4336_HT_AVAIL;
2240 		W_REG(&cc->max_res_mask, tmp);
2241 	}
2242 
2243 	/* Return to original core */
2244 	si_restore_core(sih, origidx, intr_val);
2245 }
2246 
2247 static void
si_pmu_spuravoid_pllupdate(si_t * sih,chipcregs_t * cc,u8 spuravoid)2248 si_pmu_spuravoid_pllupdate(si_t *sih, chipcregs_t *cc, u8 spuravoid)
2249 {
2250 	u32 tmp = 0;
2251 	u8 phypll_offset = 0;
2252 	u8 bcm5357_bcm43236_p1div[] = { 0x1, 0x5, 0x5 };
2253 	u8 bcm5357_bcm43236_ndiv[] = { 0x30, 0xf6, 0xfc };
2254 
2255 	switch (sih->chip) {
2256 	case BCM5357_CHIP_ID:
2257 	case BCM43235_CHIP_ID:
2258 	case BCM43236_CHIP_ID:
2259 	case BCM43238_CHIP_ID:
2260 
2261 		/* BCM5357 needs to touch PLL1_PLLCTL[02], so offset PLL0_PLLCTL[02] by 6 */
2262 		phypll_offset = (sih->chip == BCM5357_CHIP_ID) ? 6 : 0;
2263 
2264 		/* RMW only the P1 divider */
2265 		W_REG(&cc->pllcontrol_addr,
2266 		      PMU1_PLL0_PLLCTL0 + phypll_offset);
2267 		tmp = R_REG(&cc->pllcontrol_data);
2268 		tmp &= (~(PMU1_PLL0_PC0_P1DIV_MASK));
2269 		tmp |=
2270 		    (bcm5357_bcm43236_p1div[spuravoid] <<
2271 		     PMU1_PLL0_PC0_P1DIV_SHIFT);
2272 		W_REG(&cc->pllcontrol_data, tmp);
2273 
2274 		/* RMW only the int feedback divider */
2275 		W_REG(&cc->pllcontrol_addr,
2276 		      PMU1_PLL0_PLLCTL2 + phypll_offset);
2277 		tmp = R_REG(&cc->pllcontrol_data);
2278 		tmp &= ~(PMU1_PLL0_PC2_NDIV_INT_MASK);
2279 		tmp |=
2280 		    (bcm5357_bcm43236_ndiv[spuravoid]) <<
2281 		    PMU1_PLL0_PC2_NDIV_INT_SHIFT;
2282 		W_REG(&cc->pllcontrol_data, tmp);
2283 
2284 		tmp = 1 << 10;
2285 		break;
2286 
2287 	case BCM4331_CHIP_ID:
2288 		if (spuravoid == 2) {
2289 			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0);
2290 			W_REG(&cc->pllcontrol_data, 0x11500014);
2291 			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2);
2292 			W_REG(&cc->pllcontrol_data, 0x0FC00a08);
2293 		} else if (spuravoid == 1) {
2294 			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0);
2295 			W_REG(&cc->pllcontrol_data, 0x11500014);
2296 			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2);
2297 			W_REG(&cc->pllcontrol_data, 0x0F600a08);
2298 		} else {
2299 			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0);
2300 			W_REG(&cc->pllcontrol_data, 0x11100014);
2301 			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2);
2302 			W_REG(&cc->pllcontrol_data, 0x03000a08);
2303 		}
2304 		tmp = 1 << 10;
2305 		break;
2306 
2307 	case BCM43224_CHIP_ID:
2308 	case BCM43225_CHIP_ID:
2309 	case BCM43421_CHIP_ID:
2310 	case BCM6362_CHIP_ID:
2311 		if (spuravoid == 1) {
2312 			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0);
2313 			W_REG(&cc->pllcontrol_data, 0x11500010);
2314 			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1);
2315 			W_REG(&cc->pllcontrol_data, 0x000C0C06);
2316 			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2);
2317 			W_REG(&cc->pllcontrol_data, 0x0F600a08);
2318 			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3);
2319 			W_REG(&cc->pllcontrol_data, 0x00000000);
2320 			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4);
2321 			W_REG(&cc->pllcontrol_data, 0x2001E920);
2322 			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5);
2323 			W_REG(&cc->pllcontrol_data, 0x88888815);
2324 		} else {
2325 			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0);
2326 			W_REG(&cc->pllcontrol_data, 0x11100010);
2327 			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1);
2328 			W_REG(&cc->pllcontrol_data, 0x000c0c06);
2329 			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2);
2330 			W_REG(&cc->pllcontrol_data, 0x03000a08);
2331 			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3);
2332 			W_REG(&cc->pllcontrol_data, 0x00000000);
2333 			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4);
2334 			W_REG(&cc->pllcontrol_data, 0x200005c0);
2335 			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5);
2336 			W_REG(&cc->pllcontrol_data, 0x88888815);
2337 		}
2338 		tmp = 1 << 10;
2339 		break;
2340 
2341 		W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0);
2342 		W_REG(&cc->pllcontrol_data, 0x11100008);
2343 		W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1);
2344 		W_REG(&cc->pllcontrol_data, 0x0c000c06);
2345 		W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2);
2346 		W_REG(&cc->pllcontrol_data, 0x03000a08);
2347 		W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3);
2348 		W_REG(&cc->pllcontrol_data, 0x00000000);
2349 		W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4);
2350 		W_REG(&cc->pllcontrol_data, 0x200005c0);
2351 		W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5);
2352 		W_REG(&cc->pllcontrol_data, 0x88888855);
2353 
2354 		tmp = 1 << 10;
2355 		break;
2356 
2357 	case BCM4716_CHIP_ID:
2358 	case BCM4748_CHIP_ID:
2359 	case BCM47162_CHIP_ID:
2360 		if (spuravoid == 1) {
2361 			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0);
2362 			W_REG(&cc->pllcontrol_data, 0x11500060);
2363 			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1);
2364 			W_REG(&cc->pllcontrol_data, 0x080C0C06);
2365 			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2);
2366 			W_REG(&cc->pllcontrol_data, 0x0F600000);
2367 			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3);
2368 			W_REG(&cc->pllcontrol_data, 0x00000000);
2369 			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4);
2370 			W_REG(&cc->pllcontrol_data, 0x2001E924);
2371 			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5);
2372 			W_REG(&cc->pllcontrol_data, 0x88888815);
2373 		} else {
2374 			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0);
2375 			W_REG(&cc->pllcontrol_data, 0x11100060);
2376 			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1);
2377 			W_REG(&cc->pllcontrol_data, 0x080c0c06);
2378 			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2);
2379 			W_REG(&cc->pllcontrol_data, 0x03000000);
2380 			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3);
2381 			W_REG(&cc->pllcontrol_data, 0x00000000);
2382 			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4);
2383 			W_REG(&cc->pllcontrol_data, 0x200005c0);
2384 			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5);
2385 			W_REG(&cc->pllcontrol_data, 0x88888815);
2386 		}
2387 
2388 		tmp = 3 << 9;
2389 		break;
2390 
2391 	case BCM4319_CHIP_ID:
2392 		W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0);
2393 		W_REG(&cc->pllcontrol_data, 0x11100070);
2394 		W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1);
2395 		W_REG(&cc->pllcontrol_data, 0x1014140a);
2396 		W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5);
2397 		W_REG(&cc->pllcontrol_data, 0x88888854);
2398 
2399 		if (spuravoid == 1) {	/* spur_avoid ON, enable 41/82/164Mhz clock mode */
2400 			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2);
2401 			W_REG(&cc->pllcontrol_data, 0x05201828);
2402 		} else {	/* enable 40/80/160Mhz clock mode */
2403 			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2);
2404 			W_REG(&cc->pllcontrol_data, 0x05001828);
2405 		}
2406 		break;
2407 	case BCM4336_CHIP_ID:
2408 		/* Looks like these are only for default xtal freq 26MHz */
2409 		W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0);
2410 		W_REG(&cc->pllcontrol_data, 0x02100020);
2411 
2412 		W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1);
2413 		W_REG(&cc->pllcontrol_data, 0x0C0C0C0C);
2414 
2415 		W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2);
2416 		W_REG(&cc->pllcontrol_data, 0x01240C0C);
2417 
2418 		W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4);
2419 		W_REG(&cc->pllcontrol_data, 0x202C2820);
2420 
2421 		W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5);
2422 		W_REG(&cc->pllcontrol_data, 0x88888825);
2423 
2424 		W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3);
2425 		if (spuravoid == 1) {
2426 			W_REG(&cc->pllcontrol_data, 0x00EC4EC4);
2427 		} else {
2428 			W_REG(&cc->pllcontrol_data, 0x00762762);
2429 		}
2430 
2431 		tmp = PCTL_PLL_PLLCTL_UPD;
2432 		break;
2433 
2434 	default:
2435 		PMU_ERROR(("%s: unknown spuravoidance settings for chip %s, not changing PLL\n", __func__, bcm_chipname(sih->chip, chn, 8)));
2436 		break;
2437 	}
2438 
2439 	tmp |= R_REG(&cc->pmucontrol);
2440 	W_REG(&cc->pmucontrol, tmp);
2441 }
2442 
si_pmu_is_otp_powered(si_t * sih)2443 bool si_pmu_is_otp_powered(si_t *sih)
2444 {
2445 	uint idx;
2446 	chipcregs_t *cc;
2447 	bool st;
2448 
2449 	/* Remember original core before switch to chipc */
2450 	idx = si_coreidx(sih);
2451 	cc = si_setcoreidx(sih, SI_CC_IDX);
2452 	ASSERT(cc != NULL);
2453 
2454 	switch (sih->chip) {
2455 	case BCM4329_CHIP_ID:
2456 		st = (R_REG(&cc->res_state) & PMURES_BIT(RES4329_OTP_PU))
2457 		    != 0;
2458 		break;
2459 	case BCM4319_CHIP_ID:
2460 		st = (R_REG(&cc->res_state) & PMURES_BIT(RES4319_OTP_PU))
2461 		    != 0;
2462 		break;
2463 	case BCM4336_CHIP_ID:
2464 		st = (R_REG(&cc->res_state) & PMURES_BIT(RES4336_OTP_PU))
2465 		    != 0;
2466 		break;
2467 	case BCM4330_CHIP_ID:
2468 		st = (R_REG(&cc->res_state) & PMURES_BIT(RES4330_OTP_PU))
2469 		    != 0;
2470 		break;
2471 
2472 		/* These chip doesn't use PMU bit to power up/down OTP. OTP always on.
2473 		 * Use OTP_INIT command to reset/refresh state.
2474 		 */
2475 	case BCM43224_CHIP_ID:
2476 	case BCM43225_CHIP_ID:
2477 	case BCM43421_CHIP_ID:
2478 	case BCM43236_CHIP_ID:
2479 	case BCM43235_CHIP_ID:
2480 	case BCM43238_CHIP_ID:
2481 		st = true;
2482 		break;
2483 	default:
2484 		st = true;
2485 		break;
2486 	}
2487 
2488 	/* Return to original core */
2489 	si_setcoreidx(sih, idx);
2490 	return st;
2491 }
2492 
si_pmu_sprom_enable(si_t * sih,bool enable)2493 void si_pmu_sprom_enable(si_t *sih, bool enable)
2494 {
2495 	chipcregs_t *cc;
2496 	uint origidx;
2497 
2498 	/* Remember original core before switch to chipc */
2499 	origidx = si_coreidx(sih);
2500 	cc = si_setcoreidx(sih, SI_CC_IDX);
2501 	ASSERT(cc != NULL);
2502 
2503 	/* Return to original core */
2504 	si_setcoreidx(sih, origidx);
2505 }
2506 
2507 /* initialize PMU chip controls and other chip level stuff */
si_pmu_chip_init(si_t * sih)2508 void si_pmu_chip_init(si_t *sih)
2509 {
2510 	uint origidx;
2511 
2512 	ASSERT(sih->cccaps & CC_CAP_PMU);
2513 
2514 #ifdef CHIPC_UART_ALWAYS_ON
2515 	si_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, clk_ctl_st),
2516 		   CCS_FORCEALP, CCS_FORCEALP);
2517 #endif				/* CHIPC_UART_ALWAYS_ON */
2518 
2519 	/* Gate off SPROM clock and chip select signals */
2520 	si_pmu_sprom_enable(sih, false);
2521 
2522 	/* Remember original core */
2523 	origidx = si_coreidx(sih);
2524 
2525 	/* Return to original core */
2526 	si_setcoreidx(sih, origidx);
2527 }
2528 
2529 /* initialize PMU switch/regulators */
si_pmu_swreg_init(si_t * sih)2530 void si_pmu_swreg_init(si_t *sih)
2531 {
2532 	ASSERT(sih->cccaps & CC_CAP_PMU);
2533 
2534 	switch (sih->chip) {
2535 	case BCM4336_CHIP_ID:
2536 		/* Reduce CLDO PWM output voltage to 1.2V */
2537 		si_pmu_set_ldo_voltage(sih, SET_LDO_VOLTAGE_CLDO_PWM, 0xe);
2538 		/* Reduce CLDO BURST output voltage to 1.2V */
2539 		si_pmu_set_ldo_voltage(sih, SET_LDO_VOLTAGE_CLDO_BURST,
2540 				       0xe);
2541 		/* Reduce LNLDO1 output voltage to 1.2V */
2542 		si_pmu_set_ldo_voltage(sih, SET_LDO_VOLTAGE_LNLDO1, 0xe);
2543 		if (sih->chiprev == 0)
2544 			si_pmu_regcontrol(sih, 2, 0x400000, 0x400000);
2545 		break;
2546 
2547 	case BCM4330_CHIP_ID:
2548 		/* CBUCK Voltage is 1.8 by default and set that to 1.5 */
2549 		si_pmu_set_ldo_voltage(sih, SET_LDO_VOLTAGE_CBUCK_PWM, 0);
2550 		break;
2551 	default:
2552 		break;
2553 	}
2554 }
2555 
si_pmu_radio_enable(si_t * sih,bool enable)2556 void si_pmu_radio_enable(si_t *sih, bool enable)
2557 {
2558 	ASSERT(sih->cccaps & CC_CAP_PMU);
2559 
2560 	switch (sih->chip) {
2561 	case BCM4319_CHIP_ID:
2562 		if (enable)
2563 			si_write_wrapperreg(sih, AI_OOBSELOUTB74,
2564 					    (u32) 0x868584);
2565 		else
2566 			si_write_wrapperreg(sih, AI_OOBSELOUTB74,
2567 					    (u32) 0x060584);
2568 		break;
2569 	}
2570 }
2571 
2572 /* Wait for a particular clock level to be on the backplane */
2573 u32
si_pmu_waitforclk_on_backplane(si_t * sih,u32 clk,u32 delay)2574 si_pmu_waitforclk_on_backplane(si_t *sih, u32 clk, u32 delay)
2575 {
2576 	chipcregs_t *cc;
2577 	uint origidx;
2578 
2579 	ASSERT(sih->cccaps & CC_CAP_PMU);
2580 
2581 	/* Remember original core before switch to chipc */
2582 	origidx = si_coreidx(sih);
2583 	cc = si_setcoreidx(sih, SI_CC_IDX);
2584 	ASSERT(cc != NULL);
2585 
2586 	if (delay)
2587 		SPINWAIT(((R_REG(&cc->pmustatus) & clk) != clk), delay);
2588 
2589 	/* Return to original core */
2590 	si_setcoreidx(sih, origidx);
2591 
2592 	return R_REG(&cc->pmustatus) & clk;
2593 }
2594 
2595 /*
2596  * Measures the ALP clock frequency in KHz.  Returns 0 if not possible.
2597  * Possible only if PMU rev >= 10 and there is an external LPO 32768Hz crystal.
2598  */
2599 
2600 #define EXT_ILP_HZ 32768
2601 
si_pmu_measure_alpclk(si_t * sih)2602 u32 si_pmu_measure_alpclk(si_t *sih)
2603 {
2604 	chipcregs_t *cc;
2605 	uint origidx;
2606 	u32 alp_khz;
2607 
2608 	if (sih->pmurev < 10)
2609 		return 0;
2610 
2611 	ASSERT(sih->cccaps & CC_CAP_PMU);
2612 
2613 	/* Remember original core before switch to chipc */
2614 	origidx = si_coreidx(sih);
2615 	cc = si_setcoreidx(sih, SI_CC_IDX);
2616 	ASSERT(cc != NULL);
2617 
2618 	if (R_REG(&cc->pmustatus) & PST_EXTLPOAVAIL) {
2619 		u32 ilp_ctr, alp_hz;
2620 
2621 		/* Enable the reg to measure the freq, in case disabled before */
2622 		W_REG(&cc->pmu_xtalfreq,
2623 		      1U << PMU_XTALFREQ_REG_MEASURE_SHIFT);
2624 
2625 		/* Delay for well over 4 ILP clocks */
2626 		udelay(1000);
2627 
2628 		/* Read the latched number of ALP ticks per 4 ILP ticks */
2629 		ilp_ctr =
2630 		    R_REG(&cc->pmu_xtalfreq) & PMU_XTALFREQ_REG_ILPCTR_MASK;
2631 
2632 		/* Turn off the PMU_XTALFREQ_REG_MEASURE_SHIFT bit to save power */
2633 		W_REG(&cc->pmu_xtalfreq, 0);
2634 
2635 		/* Calculate ALP frequency */
2636 		alp_hz = (ilp_ctr * EXT_ILP_HZ) / 4;
2637 
2638 		/* Round to nearest 100KHz, and at the same time convert to KHz */
2639 		alp_khz = (alp_hz + 50000) / 100000 * 100;
2640 	} else
2641 		alp_khz = 0;
2642 
2643 	/* Return to original core */
2644 	si_setcoreidx(sih, origidx);
2645 
2646 	return alp_khz;
2647 }
2648 
si_pmu_set_4330_plldivs(si_t * sih)2649 static void si_pmu_set_4330_plldivs(si_t *sih)
2650 {
2651 	u32 FVCO = si_pmu1_pllfvco0(sih) / 1000;
2652 	u32 m1div, m2div, m3div, m4div, m5div, m6div;
2653 	u32 pllc1, pllc2;
2654 
2655 	m2div = m3div = m4div = m6div = FVCO / 80;
2656 	m5div = FVCO / 160;
2657 
2658 	if (CST4330_CHIPMODE_SDIOD(sih->chipst))
2659 		m1div = FVCO / 80;
2660 	else
2661 		m1div = FVCO / 90;
2662 	pllc1 =
2663 	    (m1div << PMU1_PLL0_PC1_M1DIV_SHIFT) | (m2div <<
2664 						    PMU1_PLL0_PC1_M2DIV_SHIFT) |
2665 	    (m3div << PMU1_PLL0_PC1_M3DIV_SHIFT) | (m4div <<
2666 						    PMU1_PLL0_PC1_M4DIV_SHIFT);
2667 	si_pmu_pllcontrol(sih, PMU1_PLL0_PLLCTL1, ~0, pllc1);
2668 
2669 	pllc2 = si_pmu_pllcontrol(sih, PMU1_PLL0_PLLCTL1, 0, 0);
2670 	pllc2 &= ~(PMU1_PLL0_PC2_M5DIV_MASK | PMU1_PLL0_PC2_M6DIV_MASK);
2671 	pllc2 |=
2672 	    ((m5div << PMU1_PLL0_PC2_M5DIV_SHIFT) |
2673 	     (m6div << PMU1_PLL0_PC2_M6DIV_SHIFT));
2674 	si_pmu_pllcontrol(sih, PMU1_PLL0_PLLCTL2, ~0, pllc2);
2675 }
2676