1/*
2 * Misc utility routines for accessing PMU corerev specific features
3 * of the SiliconBackplane-based Broadcom chips.
4 *
5 * Copyright 2007, Broadcom Corporation
6 * All Rights Reserved.
7 *
8 * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
9 * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
10 * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
11 * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
12 * $Id: hndpmu.c,v 1.1.1.1 2008/10/15 03:31:34 james26_jang Exp $
13 */
14
15#include <typedefs.h>
16#include <bcmdefs.h>
17#include <osl.h>
18#include <bcmutils.h>
19#include <sbutils.h>
20#include <bcmdevs.h>
21#include <sbconfig.h>
22#include <sbchipc.h>
23#include <hndpmu.h>
24
25/* debug/trace */
26#define	PMU_ERROR(args)
27
28#define	PMU_MSG(args)
29
30/* PMU & control */
31/* PMU rev 0 pll control for BCM4328 and BCM5354 */
32static void sb_pmu0_pllinit0(sb_t *sbh, osl_t *osh, chipcregs_t *cc, uint32 xtal);
33static uint32 sb_pmu0_alpclk0(sb_t *sbh, osl_t *osh, chipcregs_t *cc);
34static uint32 sb_pmu0_cpuclk0(sb_t *sbh, osl_t *osh, chipcregs_t *cc);
35
36#if defined(BCM4325) || defined(BCM4312)
37/* PMU rev 0 pll control for BCM4325 BCM4329 */
38static void sb_pmu1_pllinit0(sb_t *sbh, osl_t *osh, chipcregs_t *cc, uint32 xtal);
39static uint32 sb_pmu1_cpuclk0(sb_t *sbh, osl_t *osh, chipcregs_t *cc);
40static uint32 sb_pmu1_alpclk0(sb_t *sbh, osl_t *osh, chipcregs_t *cc);
41#endif
42
43/* Setup switcher voltage */
44void
45BCMINITFN(sb_pmu_set_switcher_voltage)(sb_t *sbh, osl_t *osh,
46                                       uint8 bb_voltage, uint8 rf_voltage)
47{
48	chipcregs_t *cc;
49	uint origidx;
50
51	ASSERT(sbh->cccaps & CC_CAP_PMU);
52
53	/* Remember original core before switch to chipc */
54	origidx = sb_coreidx(sbh);
55	cc = sb_setcore(sbh, SB_CC, 0);
56	ASSERT(cc);
57
58	W_REG(osh, &cc->regcontrol_addr, 0x01);
59	W_REG(osh, &cc->regcontrol_data, (uint32)(bb_voltage & 0x1f) << 22);
60
61	W_REG(osh, &cc->regcontrol_addr, 0x00);
62	W_REG(osh, &cc->regcontrol_data, (uint32)(rf_voltage & 0x1f) << 14);
63
64	/* Return to original core */
65	sb_setcoreidx(sbh, origidx);
66}
67
68void
69sb_pmu_set_ldo_voltage(sb_t *sbh, osl_t *osh, uint8 ldo, uint8 voltage)
70{
71	uint8 sr_cntl_shift, rc_shift, shift, mask;
72	uint32 addr;
73
74	ASSERT(sbh->cccaps & CC_CAP_PMU);
75
76	switch (sbh->chip) {
77		case BCM4328_CHIP_ID:
78		case BCM5354_CHIP_ID:
79			switch (ldo) {
80				case SET_LDO_VOLTAGE_LDO1:
81					addr = 2;
82					sr_cntl_shift = 8;
83					rc_shift = 17;
84					mask = 0xf;
85					break;
86				case SET_LDO_VOLTAGE_LDO2:
87					addr = 3;
88					sr_cntl_shift = 0;
89					rc_shift = 1;
90					mask = 0xf;
91					break;
92				case SET_LDO_VOLTAGE_LDO3:
93					addr = 3;
94					sr_cntl_shift = 0;
95					rc_shift = 9;
96					mask = 0xf;
97					break;
98				case SET_LDO_VOLTAGE_PAREF:
99					addr = 3;
100					sr_cntl_shift = 0;
101					rc_shift = 17;
102					mask = 0x3f;
103					break;
104				default:
105					ASSERT(FALSE);
106					return;
107			}
108			break;
109#if defined(BCM4312)
110		case BCM4312_CHIP_ID:
111			switch (ldo) {
112				case SET_LDO_VOLTAGE_PAREF:
113					addr = 0;
114					sr_cntl_shift = 0;
115					rc_shift = 21;
116					mask = 0x3f;
117					break;
118				default:
119					ASSERT(FALSE);
120					return;
121			}
122			break;
123#endif	/* defined(BCM4312) */
124		default:
125			ASSERT(FALSE);
126			return;
127	}
128
129	shift = sr_cntl_shift + rc_shift;
130
131	sb_corereg(sbh, SB_CC_IDX, OFFSETOF(chipcregs_t, regcontrol_addr),
132		~0, addr);
133	sb_corereg(sbh, SB_CC_IDX, OFFSETOF(chipcregs_t, regcontrol_data),
134		mask << shift, (voltage & mask) << shift);
135}
136
137void
138sb_pmu_paref_ldo_enable(sb_t *sbh, osl_t *osh, bool enable)
139{
140	uint ldo = 0;
141
142	ASSERT(sbh->cccaps & CC_CAP_PMU);
143
144	switch (sbh->chip) {
145#if defined(BCM4328)
146	case BCM4328_CHIP_ID:
147		ldo = RES4328_PA_REF_LDO;
148		break;
149#endif /* defined(BCM4328) */
150	case BCM5354_CHIP_ID:
151		ldo = RES5354_PA_REF_LDO;
152		break;
153#if defined(BCM4312)
154	case BCM4312_CHIP_ID:
155		ldo = RES4312_PA_REF_LDO;
156		break;
157#endif /* defined(BCM4312) */
158	default:
159		return;
160	}
161
162	sb_corereg(sbh, SB_CC_IDX, OFFSETOF(chipcregs_t, min_res_mask),
163	           PMURES_BIT(ldo), enable ? PMURES_BIT(ldo) : 0);
164}
165
166uint16
167BCMINITFN(sb_pmu_fast_pwrup_delay)(sb_t *sbh, osl_t *osh)
168{
169	uint16 delay = PMU_MAX_TRANSITION_DLY;
170
171	ASSERT(sbh->cccaps & CC_CAP_PMU);
172
173	switch (sbh->chip) {
174#if defined(BCM4328)
175	case BCM4328_CHIP_ID:
176		delay = 7000;
177		break;
178#endif	/* BCM4328 */
179
180#if defined(BCM4325) || defined(BCM4312)
181	case BCM4325_CHIP_ID:
182	case BCM4312_CHIP_ID:
183#ifdef BCMQT
184		delay = 70;
185#else
186		delay = 2800;
187#endif
188		break;
189#endif	/* BCM4325 || BCM4312 */
190
191	default:
192		PMU_MSG(("No PMU fast power up delay specified "
193			"for chip %x rev %d, using default %d us\n",
194			sbh->chip, sbh->chiprev, delay));
195		break;
196	}
197
198	return delay;
199}
200
201uint32
202BCMINITFN(sb_pmu_force_ilp)(sb_t *sbh, osl_t *osh, bool force)
203{
204	chipcregs_t *cc;
205	uint origidx;
206	uint32 oldpmucontrol;
207
208	ASSERT(sbh->cccaps & CC_CAP_PMU);
209
210	/* Remember original core before switch to chipc */
211	origidx = sb_coreidx(sbh);
212	cc = sb_setcore(sbh, SB_CC, 0);
213	ASSERT(cc);
214
215	oldpmucontrol = R_REG(osh, &cc->pmucontrol);
216	if (force)
217		W_REG(osh, &cc->pmucontrol, oldpmucontrol &
218			~(PCTL_HT_REQ_EN | PCTL_ALP_REQ_EN));
219	else
220		W_REG(osh, &cc->pmucontrol, oldpmucontrol |
221			(PCTL_HT_REQ_EN | PCTL_ALP_REQ_EN));
222
223	/* Return to original core */
224	sb_setcoreidx(sbh, origidx);
225
226	return oldpmucontrol;
227}
228
229/* Setup min/max resources and up/down timers */
230typedef struct {
231	uint8 resnum;
232	uint16 updown;
233} pmu_res_updown_t;
234
235typedef struct {
236	uint8 resnum;
237	int8 action;	/* 0 - set, 1 - add, -1 - remove */
238	uint32 depend_mask;
239} pmu_res_depend_t;
240
241#if defined(BCM4328)
242static const pmu_res_updown_t BCMINITDATA(bcm4328a0_res_updown)[] = {
243	{ RES4328_EXT_SWITCHER_PWM, 0x0101 },
244	{ RES4328_BB_SWITCHER_PWM, 0x1f01 },
245	{ RES4328_BB_SWITCHER_BURST, 0x010f },
246	{ RES4328_BB_EXT_SWITCHER_BURST, 0x0101 },
247	{ RES4328_ILP_REQUEST, 0x0202 },
248	{ RES4328_RADIO_SWITCHER_PWM, 0x0f01 },
249	{ RES4328_RADIO_SWITCHER_BURST, 0x0f01 },
250	{ RES4328_ROM_SWITCH, 0x0101 },
251	{ RES4328_PA_REF_LDO, 0x0f01 },
252	{ RES4328_RADIO_LDO, 0x0f01 },
253	{ RES4328_AFE_LDO, 0x0f01 },
254	{ RES4328_PLL_LDO, 0x0f01 },
255	{ RES4328_BG_FILTBYP, 0x0101 },
256	{ RES4328_TX_FILTBYP, 0x0101 },
257	{ RES4328_RX_FILTBYP, 0x0101 },
258	{ RES4328_XTAL_PU, 0x0101 },
259	{ RES4328_XTAL_EN, 0xa001 },
260	{ RES4328_BB_PLL_FILTBYP, 0x0101 },
261	{ RES4328_RF_PLL_FILTBYP, 0x0101 },
262	{ RES4328_BB_PLL_PU, 0x0701 }
263};
264
265static const pmu_res_depend_t BCMINITDATA(bcm4328a0_res_depend)[] = {
266	/* Adjust ILP request resource not to force ext/BB switchers into burst mode */
267	{
268		RES4328_ILP_REQUEST, 0,
269		PMURES_BIT(RES4328_EXT_SWITCHER_PWM) |
270		PMURES_BIT(RES4328_BB_SWITCHER_PWM)
271	}
272};
273#endif	/* BCM4328 */
274
275#if defined(BCM4325)
276#ifdef BCMQT	    /* for power save on slow QT/small beacon interval */
277static const pmu_res_updown_t BCMINITDATA(bcm4325a0_res_updown_qt)[] = {
278	{ RES4325_HT_AVAIL, 0x0300 },
279	{ RES4325_BBPLL_PWRSW_PU, 0x0101 },
280	{ RES4325_RFPLL_PWRSW_PU, 0x0101 },
281	{ RES4325_ALP_AVAIL, 0x0100 },
282	{ RES4325_XTAL_PU, 0x1000 },
283	{ RES4325_LNLDO1_PU, 0x0800 },
284	{ RES4325_CLDO_CBUCK_PWM, 0x0101 },
285	{ RES4325_CBUCK_PWM, 0x0803 }
286};
287#else
288static const pmu_res_updown_t BCMINITDATA(bcm4325a0_res_updown)[] = {
289	{ RES4325_XTAL_PU, 0x1501 }
290};
291#endif	/* !BCMQT */
292
293static const pmu_res_depend_t BCMINITDATA(bcm4325a0_res_depend)[] = {
294	/* Adjust HT Avail resource dependencies */
295	{
296		RES4325_HT_AVAIL, 1,
297		PMURES_BIT(RES4325_RX_PWRSW_PU) | PMURES_BIT(RES4325_TX_PWRSW_PU) |
298		PMURES_BIT(RES4325_LOGEN_PWRSW_PU) | PMURES_BIT(RES4325_AFE_PWRSW_PU)
299	}
300};
301#endif	/* BCM4325 */
302
303void
304BCMINITFN(sb_pmu_res_init)(sb_t *sbh, osl_t *osh)
305{
306	chipcregs_t *cc;
307	uint origidx;
308	const pmu_res_updown_t *pmu_res_updown_table = NULL;
309	int pmu_res_updown_table_sz = 0;
310	const pmu_res_depend_t *pmu_res_depend_table = NULL;
311	int pmu_res_depend_table_sz = 0;
312	uint32 min_mask = 0, max_mask = 0;
313
314	ASSERT(sbh->cccaps & CC_CAP_PMU);
315
316	/* Remember original core before switch to chipc */
317	origidx = sb_coreidx(sbh);
318	cc = sb_setcore(sbh, SB_CC, 0);
319	ASSERT(cc);
320
321	switch (sbh->chip) {
322#if defined(BCM4328)
323	case BCM4328_CHIP_ID:
324		/* Down to ILP request excluding ROM */
325		min_mask = PMURES_BIT(RES4328_EXT_SWITCHER_PWM) |
326		        PMURES_BIT(RES4328_BB_SWITCHER_PWM) |
327		        PMURES_BIT(RES4328_XTAL_EN);
328		/* Allow (but don't require) PLL to turn on */
329		max_mask = 0xfffff;
330		pmu_res_updown_table = bcm4328a0_res_updown;
331		pmu_res_updown_table_sz = ARRAYSIZE(bcm4328a0_res_updown);
332		pmu_res_depend_table = bcm4328a0_res_depend;
333		pmu_res_depend_table_sz = ARRAYSIZE(bcm4328a0_res_depend);
334		break;
335#endif	/* BCM4328 */
336#if defined(BCM4312)
337	case BCM4312_CHIP_ID:
338		/* keep default
339		 * min_mask = 0xcbb; max_mask = 0x7ffff;
340		 * pmu_res_updown_table_sz = 0;
341		 * pmu_res_depend_table_sz = 0;
342		 */
343		break;
344#endif	/* BCM4312 */
345	case BCM5354_CHIP_ID:
346		/* Allow (but don't require) PLL to turn on */
347		max_mask = 0xfffff;
348		break;
349
350#if defined(BCM4325)
351	case BCM4325_CHIP_ID:
352		/* Leave OTP powered up and power it down later. */
353		min_mask =
354		        PMURES_BIT(RES4325_CBUCK_BURST) |
355		        PMURES_BIT(RES4325_LNLDO2_PU);
356		if (((sbh->chipst & CST4325_PMUTOP_2B_MASK) >>
357		     CST4325_PMUTOP_2B_SHIFT) == 1)
358			min_mask |= PMURES_BIT(RES4325_CLDO_CBUCK_BURST);
359		/* Allow (but don't require) PLL to turn on */
360		max_mask = 0x3fffff;
361#ifdef BCMQT
362		pmu_res_updown_table = bcm4325a0_res_updown_qt;
363		pmu_res_updown_table_sz = ARRAYSIZE(bcm4325a0_res_updown_qt);
364#else
365		pmu_res_updown_table = bcm4325a0_res_updown;
366		pmu_res_updown_table_sz = ARRAYSIZE(bcm4325a0_res_updown);
367		pmu_res_depend_table = bcm4325a0_res_depend;
368		pmu_res_depend_table_sz = ARRAYSIZE(bcm4325a0_res_depend);
369#endif
370		break;
371#endif	/* BCM4325 */
372
373	default:
374		break;
375	}
376
377	/* Program up/down timers */
378	while (pmu_res_updown_table_sz--) {
379		ASSERT(pmu_res_updown_table);
380		W_REG(osh, &cc->res_table_sel,
381			pmu_res_updown_table[pmu_res_updown_table_sz].resnum);
382		W_REG(osh, &cc->res_updn_timer,
383			pmu_res_updown_table[pmu_res_updown_table_sz].updown);
384	}
385
386	/* Program resource dependencies table */
387	while (pmu_res_depend_table_sz--) {
388		ASSERT(pmu_res_depend_table);
389		W_REG(osh, &cc->res_table_sel,
390			pmu_res_depend_table[pmu_res_depend_table_sz].resnum);
391		switch (pmu_res_depend_table[pmu_res_depend_table_sz].action) {
392		case 0:
393			W_REG(osh, &cc->res_dep_mask,
394				pmu_res_depend_table[pmu_res_depend_table_sz].depend_mask);
395			break;
396		case 1:
397			OR_REG(osh, &cc->res_dep_mask,
398				pmu_res_depend_table[pmu_res_depend_table_sz].depend_mask);
399			break;
400		case -1:
401			AND_REG(osh, &cc->res_dep_mask,
402				~pmu_res_depend_table[pmu_res_depend_table_sz].depend_mask);
403			break;
404		default:
405			ASSERT(0);
406			break;
407		}
408	}
409
410	/* program min resource mask */
411	if (min_mask) {
412		PMU_MSG(("Changing min_res_mask to 0x%x\n", min_mask));
413		W_REG(osh, &cc->min_res_mask, min_mask);
414	}
415	/* program max resource mask */
416	if (max_mask) {
417		PMU_MSG(("Changing max_res_mask to 0x%x\n", max_mask));
418		W_REG(osh, &cc->max_res_mask, max_mask);
419	}
420
421	/* Return to original core */
422	sb_setcoreidx(sbh, origidx);
423}
424
425/* setup pll and query clock speed */
426typedef struct {
427	uint16	freq;
428	uint8	xf;
429	uint8	wbint;
430	uint32	wbfrac;
431} pmu0_xtaltab0_t;
432
433/* the following table is based on 880Mhz Fvco */
434#define PMU0_PLL0_FVCO	880000	/* Fvco 880Mhz */
435static const pmu0_xtaltab0_t BCMINITDATA(pmu0_xtaltab0)[] = {
436	{ 12000,	1,	73,	349525 },
437	{ 13000,	2,	67,	725937 },
438	{ 14400,	3,	61,	116508 },
439	{ 15360,	4,	57,	305834 },
440	{ 16200,	5,	54,	336579 },
441	{ 16800,	6,	52,	399457 },
442	{ 19200,	7,	45,	873813 },
443	{ 19800,	8,	44,	466033 },
444	{ 20000,	9,	44,	0 },
445	{ 25000,	10,	70,	419430 },
446	{ 26000,	11,	67,	725937 },
447	{ 30000,	12,	58,	699050 },
448	{ 38400,	13,	45,	873813 },
449	{ 40000,	14,	45,	0 },
450	{ 0,		0,	0,	0 }
451};
452
453#ifdef BCMUSBDEV
454#define	PMU0_XTAL0_DEFAULT	11
455#else
456#define PMU0_XTAL0_DEFAULT	8
457#endif
458
459#if defined(BCM4328)
460#ifdef BCMUSBDEV
461/*
462 * Set new backplane PLL clock frequency
463 */
464static void
465BCMINITFN(sb_pmu0_sbclk4328)(sb_t *sbh, int freq)
466{
467	uint32 tmp, oldmax, oldmin, origidx;
468	chipcregs_t *cc;
469
470	/* Remember original core before switch to chipc */
471	origidx = sb_coreidx(sbh);
472	cc = sb_setcore(sbh, SB_CC, 0);
473	ASSERT(cc);
474
475	/* Set new backplane PLL clock */
476	W_REG(osh, &cc->pllcontrol_addr, PMU0_PLL0_PLLCTL0);
477	tmp = R_REG(osh, &cc->pllcontrol_data);
478	tmp &= ~(PMU0_PLL0_PC0_DIV_ARM_MASK);
479	tmp |= freq << PMU0_PLL0_PC0_DIV_ARM_SHIFT;
480	W_REG(osh, &cc->pllcontrol_data, tmp);
481
482	/* Power cycle BB_PLL_PU by disabling/enabling it to take on new freq */
483	/* Disable PLL */
484	oldmin = R_REG(osh, &cc->min_res_mask);
485	oldmax = R_REG(osh, &cc->max_res_mask);
486	W_REG(osh, &cc->min_res_mask, oldmin & ~PMURES_BIT(RES4328_BB_PLL_PU));
487	W_REG(osh, &cc->max_res_mask, oldmax & ~PMURES_BIT(RES4328_BB_PLL_PU));
488
489	/* It takes over several hundred usec to re-enable the PLL since the
490	 * sequencer state machines run on ILP clock. Set delay at 450us to be safe.
491	 *
492	 * Be sure PLL is powered down first before re-enabling it.
493	 */
494
495	OSL_DELAY(PLL_DELAY);
496	SPINWAIT((R_REG(osh, &cc->res_state) & PMURES_BIT(RES4328_BB_PLL_PU)), PLL_DELAY*3);
497
498	if (R_REG(osh, &cc->res_state) & PMURES_BIT(RES4328_BB_PLL_PU)) {
499		/* If BB_PLL not powered down yet, new backplane PLL clock
500		 *  may not take effect.
501		 *
502		 * Still early during bootup so no serial output here.
503		 */
504		PMU_ERROR(("Fatal: BB_PLL not power down yet!\n"));
505		ASSERT(!(R_REG(osh, &cc->res_state) & PMURES_BIT(RES4328_BB_PLL_PU)));
506	}
507
508	/* Enable PLL */
509	W_REG(osh, &cc->max_res_mask, oldmax);
510
511	/* Return to original core */
512	sb_setcoreidx(sbh, origidx);
513}
514#endif /* BCMUSBDEV */
515#endif /* BCM4328 */
516
517/* Set up PLL registers in the PMU as per the crystal speed.
518 * Uses xtalfreq variable, or passed-in default.
519 */
520static void
521BCMINITFN(sb_pmu0_pllinit0)(sb_t *sbh, osl_t *osh, chipcregs_t *cc, uint32 xtal)
522{
523	uint32 tmp;
524	const pmu0_xtaltab0_t *xt;
525
526	if ((sb_chip(sbh) == BCM5354_CHIP_ID) && (xtal == 0)) {
527		/* 5354 has xtal freq of 25MHz */
528		xtal = 25000;
529	}
530
531	/* Find the frequency in the table */
532	for (xt = pmu0_xtaltab0; xt->freq; xt ++)
533		if (xt->freq == xtal)
534			break;
535	if (xt->freq == 0)
536		xt = &pmu0_xtaltab0[PMU0_XTAL0_DEFAULT];
537
538	PMU_MSG(("XTAL %d (%d)\n", xtal, xt->xf));
539
540	/* Check current PLL state */
541	tmp = (R_REG(osh, &cc->pmucontrol) & PCTL_XTALFREQ_MASK) >>
542	        PCTL_XTALFREQ_SHIFT;
543	if (tmp == xt->xf) {
544		PMU_MSG(("PLL already programmed for %d.%d MHz\n",
545			(xt->freq / 1000), (xt->freq % 1000)));
546
547#if defined(BCM4328)
548#ifdef BCMUSBDEV
549		if (sbh->chip == BCM4328_CHIP_ID)
550			sb_pmu0_sbclk4328(sbh, PMU0_PLL0_PC0_DIV_ARM_88MHZ);
551#endif
552#endif	/* BCM4328 */
553		return;
554	}
555
556	if (tmp) {
557		PMU_MSG(("Reprogramming PLL for %d.%d MHz (was %d.%dMHz)\n",
558		         (xt->freq / 1000), (xt->freq % 1000),
559		         (pmu0_xtaltab0[tmp-1].freq / 1000), (pmu0_xtaltab0[tmp-1].freq % 1000)));
560	} else {
561		PMU_MSG(("Programming PLL for %d.%d MHz\n", (xt->freq / 1000),
562		         (xt->freq % 1000)));
563	}
564
565	/* Make sure the PLL is off */
566	switch (sbh->chip) {
567#if defined(BCM4328)
568	case BCM4328_CHIP_ID:
569		AND_REG(osh, &cc->min_res_mask, ~PMURES_BIT(RES4328_BB_PLL_PU));
570		AND_REG(osh, &cc->max_res_mask, ~PMURES_BIT(RES4328_BB_PLL_PU));
571		break;
572#endif
573	case BCM5354_CHIP_ID:
574		AND_REG(osh, &cc->min_res_mask, ~PMURES_BIT(RES5354_BB_PLL_PU));
575		AND_REG(osh, &cc->max_res_mask, ~PMURES_BIT(RES5354_BB_PLL_PU));
576		break;
577	default:
578		ASSERT(0);
579	}
580	SPINWAIT(R_REG(osh, &cc->clk_ctl_st) & CCS0_HTAVAIL,
581	         PMU_MAX_TRANSITION_DLY);
582	ASSERT(!(R_REG(osh, &cc->clk_ctl_st) & CCS0_HTAVAIL));
583
584	PMU_MSG(("Done masking\n"));
585
586	/* Write PDIV in pllcontrol[0] */
587	W_REG(osh, &cc->pllcontrol_addr, PMU0_PLL0_PLLCTL0);
588	tmp = R_REG(osh, &cc->pllcontrol_data);
589	if (xt->freq >= PMU0_PLL0_PC0_PDIV_FREQ)
590		tmp |= PMU0_PLL0_PC0_PDIV_MASK;
591	else
592		tmp &= ~PMU0_PLL0_PC0_PDIV_MASK;
593	W_REG(osh, &cc->pllcontrol_data, tmp);
594
595	/* Write WILD in pllcontrol[1] */
596	W_REG(osh, &cc->pllcontrol_addr, PMU0_PLL0_PLLCTL1);
597	tmp = R_REG(osh, &cc->pllcontrol_data);
598	tmp = ((tmp & ~(PMU0_PLL0_PC1_WILD_INT_MASK | PMU0_PLL0_PC1_WILD_FRAC_MASK)) |
599	       (((xt->wbint << PMU0_PLL0_PC1_WILD_INT_SHIFT) &
600	         PMU0_PLL0_PC1_WILD_INT_MASK) |
601	        ((xt->wbfrac << PMU0_PLL0_PC1_WILD_FRAC_SHIFT) &
602	         PMU0_PLL0_PC1_WILD_FRAC_MASK)));
603	if (xt->wbfrac == 0)
604		tmp |= PMU0_PLL0_PC1_STOP_MOD;
605	else
606		tmp &= ~PMU0_PLL0_PC1_STOP_MOD;
607	W_REG(osh, &cc->pllcontrol_data, tmp);
608
609	/* Write WILD in pllcontrol[2] */
610	W_REG(osh, &cc->pllcontrol_addr, PMU0_PLL0_PLLCTL2);
611	tmp = R_REG(osh, &cc->pllcontrol_data);
612	tmp = ((tmp & ~PMU0_PLL0_PC2_WILD_INT_MASK) |
613	       ((xt->wbint >> PMU0_PLL0_PC2_WILD_INT_SHIFT) &
614	        PMU0_PLL0_PC2_WILD_INT_MASK));
615	W_REG(osh, &cc->pllcontrol_data, tmp);
616
617	PMU_MSG(("Done pll\n"));
618
619	/* Write XtalFreq. Set the divisor also. */
620	tmp = R_REG(osh, &cc->pmucontrol);
621	tmp = ((tmp & ~PCTL_ILP_DIV_MASK) |
622	       (((((xt->freq + 127) / 128) - 1) << PCTL_ILP_DIV_SHIFT) &
623	        PCTL_ILP_DIV_MASK));
624	tmp = ((tmp & ~PCTL_XTALFREQ_MASK) |
625	       ((xt->xf << PCTL_XTALFREQ_SHIFT) & PCTL_XTALFREQ_MASK));
626	W_REG(osh, &cc->pmucontrol, tmp);
627}
628
629static uint32
630BCMINITFN(sb_pmu0_alpclk0)(sb_t *sbh, osl_t *osh, chipcregs_t *cc)
631{
632	const pmu0_xtaltab0_t *xt;
633	uint32 xf;
634
635	/* Find the frequency in the table */
636	xf = (R_REG(osh, &cc->pmucontrol) & PCTL_XTALFREQ_MASK) >>
637	        PCTL_XTALFREQ_SHIFT;
638	for (xt = pmu0_xtaltab0; xt->freq; xt++)
639		if (xt->xf == xf)
640			break;
641	if (xt->freq == 0)
642		xt = &pmu0_xtaltab0[PMU0_XTAL0_DEFAULT];
643
644	return xt->freq * 1000;
645}
646
647static uint32
648BCMINITFN(sb_pmu0_cpuclk0)(sb_t *sbh, osl_t *osh, chipcregs_t *cc)
649{
650	const pmu0_xtaltab0_t *xt;
651	uint32 xf, tmp, divarm;
652
653	if (sb_chip(sbh) == BCM5354_CHIP_ID) {
654		/* 5354 gets sb clock of 120MHz from main pll */
655		//return 120000000;
656		return 100000000;
657	}
658
659	/* Find the xtal frequency in the table */
660	xf = (R_REG(osh, &cc->pmucontrol) & PCTL_XTALFREQ_MASK) >>
661	        PCTL_XTALFREQ_SHIFT;
662	for (xt = pmu0_xtaltab0; xt->freq; xt++)
663		if (xt->xf == xf)
664			break;
665	if (xt->freq == 0)
666		xt = &pmu0_xtaltab0[PMU0_XTAL0_DEFAULT];
667
668	/* Read divarm from pllcontrol[0] */
669	W_REG(osh, &cc->pllcontrol_addr, PMU0_PLL0_PLLCTL0);
670	tmp = R_REG(osh, &cc->pllcontrol_data);
671	divarm = (tmp & PMU0_PLL0_PC0_DIV_ARM_MASK) >> PMU0_PLL0_PC0_DIV_ARM_SHIFT;
672
673
674	/* Return ARM/SB clock */
675	return PMU0_PLL0_FVCO / (divarm + PMU0_PLL0_PC0_DIV_ARM_BASE) * 1000;
676}
677
678/* PMU corerev 1 pll programming for BCM4325 */
679#if defined(BCM4325) || defined(BCM4312)
680/* setup pll and query clock speed */
681typedef struct {
682	uint16	fref;
683	uint8	xf;
684	uint8	p1div;
685	uint8	p2div;
686	uint8	ndiv_int;
687	uint32	ndiv_frac;
688} pmu1_xtaltab0_t;
689
690/* the following table is based on 880Mhz Fvco */
691#define PMU1_PLL0_FVCO	880000	/* Fvco 880Mhz */
692static const pmu1_xtaltab0_t BCMINITDATA(pmu1_xtaltab0)[] = {
693	{12000,	1,	3,	22,	0x9,	0xFFFFEF},
694	{13000,	2,	1,	6,	0xb,	0x483483},
695	{14400,	3,	1,	10,	0xa,	0x1C71C7},
696	{15360,	4,	1,	5,	0xb,	0x755555},
697	{16200,	5,	1,	10,	0x5,	0x6E9E06},
698	{16800,	6,	1,	10,	0x5,	0x3Cf3Cf},
699	{19200,	7,	1,	9,	0x5,	0x17B425},
700	{19800,	8,	1,	11,	0x4,	0xA57EB},
701	{20000,	9,	1,	11,	0x4,	0x0},
702	{24000,	10,	3,	11,	0xa,	0x0},
703	{25000,	11,	5,	16,	0xb,	0x0},
704	{26000,	12,	1,	2,	0x10,	0xEC4EC4},
705	{30000,	13,	3,	8,	0xb,	0x0},
706	{38400,	14,	1,	5,	0x4,	0x955555},
707	{40000,	15,	1,	2,	0xb,	0},
708	{0,	0,	0,	0,	0,	0}
709};
710
711/* Default to 15360Khz crystal */
712#define PMU1_XTAL0_DEFAULT	3
713
714static uint32
715BCMINITFN(sb_pmu1_alpclk0)(sb_t *sbh, osl_t *osh, chipcregs_t *cc)
716{
717	const pmu1_xtaltab0_t *xt;
718	uint32 xf;
719
720	/* Find the frequency in the table */
721	xf = (R_REG(osh, &cc->pmucontrol) & PCTL_XTALFREQ_MASK) >>
722	        PCTL_XTALFREQ_SHIFT;
723	for (xt = pmu1_xtaltab0; xt->fref; xt++)
724		if (xt->xf == xf)
725			break;
726	if (xt->fref == 0)
727		xt = &pmu1_xtaltab0[PMU1_XTAL0_DEFAULT];
728
729	return xt->fref * 1000;
730}
731
732/* Set up PLL registers in the PMU as per the crystal speed.
733 * Uses xtalfreq variable, or passed-in default.
734 */
735static void
736BCMINITFN(sb_pmu1_pllinit0)(sb_t *sbh, osl_t *osh, chipcregs_t *cc, uint32 xtal)
737{
738	const pmu1_xtaltab0_t *xt;
739	uint32 tmp;
740	uint32 buf_strength = 0;
741
742	/* 4312: assume default works */
743	if (sbh->chip == BCM4312_CHIP_ID)
744		return;
745
746	/* Find the frequency in the table */
747	for (xt = pmu1_xtaltab0; xt->fref; xt++)
748		if (xt->fref == xtal)
749			break;
750	if (xt->fref == 0)
751		xt = &pmu1_xtaltab0[PMU1_XTAL0_DEFAULT];
752
753	PMU_MSG(("XTAL %d (%d)\n", xtal, xt->xf));
754
755	/* Check current PLL state */
756	if (((R_REG(osh, &cc->pmucontrol) & PCTL_XTALFREQ_MASK) >>
757	     PCTL_XTALFREQ_SHIFT) == xt->xf) {
758		PMU_MSG(("PLL already programmed for %d.%d MHz\n",
759			(xt->fref / 1000), (xt->fref % 1000)));
760		return;
761	}
762
763	PMU_MSG(("Programming PLL for %d.%d MHz\n", (xt->fref / 1000),
764	         (xt->fref % 1000)));
765
766	/* Make sure the PLL is off */
767	switch (sbh->chip) {
768#if defined(BCM4325)
769	case BCM4325_CHIP_ID:
770		AND_REG(osh, &cc->min_res_mask,
771		        ~(PMURES_BIT(RES4325_BBPLL_PWRSW_PU) | PMURES_BIT(RES4325_HT_AVAIL)));
772		AND_REG(osh, &cc->max_res_mask,
773		        ~(PMURES_BIT(RES4325_BBPLL_PWRSW_PU) | PMURES_BIT(RES4325_HT_AVAIL)));
774
775		/* Change the BBPLL drive strength to 2 for all channels */
776		buf_strength = 0x222222;
777		break;
778#endif
779	default:
780		ASSERT(0);
781	}
782	SPINWAIT(R_REG(osh, &cc->clk_ctl_st) & CCS_HTAVAIL, PMU_MAX_TRANSITION_DLY);
783	ASSERT(!(R_REG(osh, &cc->clk_ctl_st) & CCS_HTAVAIL));
784
785	PMU_MSG(("Done masking\n"));
786
787	/* Write p1div and p2div to pllcontrol[0] */
788	W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0);
789	tmp = R_REG(osh, &cc->pllcontrol_data) &
790	        ~(PMU1_PLL0_PC0_P1DIV_MASK | PMU1_PLL0_PC0_P2DIV_MASK);
791	tmp |= ((xt->p1div << PMU1_PLL0_PC0_P1DIV_SHIFT) & PMU1_PLL0_PC0_P1DIV_MASK) |
792	        ((xt->p2div << PMU1_PLL0_PC0_P2DIV_SHIFT) & PMU1_PLL0_PC0_P2DIV_MASK);
793	W_REG(osh, &cc->pllcontrol_data, tmp);
794
795	/* Write ndiv_int and ndiv_mode to pllcontrol[2] */
796	W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2);
797	tmp = R_REG(osh, &cc->pllcontrol_data) &
798	        ~(PMU1_PLL0_PC2_NDIV_INT_MASK | PMU1_PLL0_PC2_NDIV_MODE_MASK);
799	tmp |= ((xt->ndiv_int << PMU1_PLL0_PC2_NDIV_INT_SHIFT) & PMU1_PLL0_PC2_NDIV_INT_MASK) |
800	        ((1 << PMU1_PLL0_PC2_NDIV_MODE_SHIFT) & PMU1_PLL0_PC2_NDIV_MODE_MASK);
801	W_REG(osh, &cc->pllcontrol_data, tmp);
802
803	/* Write ndiv_frac to pllcontrol[3] */
804	W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3);
805	tmp = R_REG(osh, &cc->pllcontrol_data) & ~PMU1_PLL0_PC3_NDIV_FRAC_MASK;
806	tmp |= ((xt->ndiv_frac << PMU1_PLL0_PC3_NDIV_FRAC_SHIFT) &
807	        PMU1_PLL0_PC3_NDIV_FRAC_MASK);
808	W_REG(osh, &cc->pllcontrol_data, tmp);
809
810	if (buf_strength) {
811		PMU_MSG(("Adjusting PLL buffer drive strength: %x\n", buf_strength));
812
813		W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5);
814		tmp = R_REG(osh, &cc->pllcontrol_data) & ~PMU1_PLL0_PC5_CLK_DRV_MASK;
815		tmp |= (buf_strength << PMU1_PLL0_PC5_CLK_DRV_SHIFT);
816		W_REG(osh, &cc->pllcontrol_data, tmp);
817	}
818
819	PMU_MSG(("Done pll\n"));
820
821	/* Write XtalFreq. Set the divisor also. */
822	tmp = R_REG(osh, &cc->pmucontrol) &
823	        ~(PCTL_ILP_DIV_MASK | PCTL_XTALFREQ_MASK);
824	tmp |= (((((xt->fref + 127) / 128) - 1) << PCTL_ILP_DIV_SHIFT) &
825	        PCTL_ILP_DIV_MASK) |
826	       ((xt->xf << PCTL_XTALFREQ_SHIFT) & PCTL_XTALFREQ_MASK);
827	W_REG(osh, &cc->pmucontrol, tmp);
828}
829
830
831static uint32
832BCMINITFN(sb_pmu1_cpuclk0)(sb_t *sbh, osl_t *osh, chipcregs_t *cc)
833{
834	const pmu1_xtaltab0_t *xt;
835	uint32 xf, tmp, m1div;
836
837	/* Find the xtal frequency in the table */
838	xf = (R_REG(osh, &cc->pmucontrol) & PCTL_XTALFREQ_MASK) >>
839	        PCTL_XTALFREQ_SHIFT;
840	for (xt = pmu1_xtaltab0; xt->fref; xt++)
841		if (xt->xf == xf)
842			break;
843	if (xt->fref == 0)
844		xt = &pmu1_xtaltab0[PMU1_XTAL0_DEFAULT];
845
846	/* Read m1div from pllcontrol[1] */
847	W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1);
848	tmp = R_REG(osh, &cc->pllcontrol_data);
849	m1div = (tmp & PMU1_PLL0_PC1_M1DIV_MASK) >> PMU1_PLL0_PC1_M1DIV_SHIFT;
850
851
852	/* Return ARM/SB clock */
853	return PMU1_PLL0_FVCO / m1div * 1000;
854}
855#endif
856
857void
858BCMINITFN(sb_pmu_pll_init)(sb_t *sbh, osl_t *osh, uint xtalfreq)
859{
860	chipcregs_t *cc;
861	uint origidx;
862
863	ASSERT(sbh->cccaps & CC_CAP_PMU);
864
865	/* Remember original core before switch to chipc */
866	origidx = sb_coreidx(sbh);
867	cc = sb_setcore(sbh, SB_CC, 0);
868	ASSERT(cc);
869
870	switch (sbh->chip) {
871#if defined(BCM4328)
872	case BCM4328_CHIP_ID:
873		sb_pmu0_pllinit0(sbh, osh, cc, xtalfreq);
874		break;
875#endif
876	case BCM5354_CHIP_ID:
877		sb_pmu0_pllinit0(sbh, osh, cc, xtalfreq);
878		break;
879#if defined(BCM4325)
880	case BCM4325_CHIP_ID:
881		sb_pmu1_pllinit0(sbh, osh, cc, xtalfreq);
882		break;
883#endif
884#if defined(BCM4312)
885	case BCM4312_CHIP_ID:
886		sb_pmu1_pllinit0(sbh, osh, cc, xtalfreq);
887		break;
888#endif
889	default:
890		PMU_MSG(("No PLL init done for chip %x rev %d pmurev %d\n",
891		         sbh->chip, sbh->chiprev, sbh->pmurev));
892		break;
893	}
894
895	/* Return to original core */
896	sb_setcoreidx(sbh, origidx);
897}
898
899uint32
900BCMINITFN(sb_pmu_alp_clock)(sb_t *sbh, osl_t *osh)
901{
902	chipcregs_t *cc;
903	uint origidx;
904	uint32 clock = ALP_CLOCK;
905
906	ASSERT(sbh->cccaps & CC_CAP_PMU);
907
908	/* Remember original core before switch to chipc */
909	origidx = sb_coreidx(sbh);
910	cc = sb_setcore(sbh, SB_CC, 0);
911	ASSERT(cc);
912
913	switch (sbh->chip) {
914#if defined(BCM4328)
915	case BCM4328_CHIP_ID:
916		clock = sb_pmu0_alpclk0(sbh, osh, cc);
917		break;
918#endif
919	case BCM5354_CHIP_ID:
920		clock = sb_pmu0_alpclk0(sbh, osh, cc);
921		break;
922#if defined(BCM4325)
923	case BCM4325_CHIP_ID:
924		clock = sb_pmu1_alpclk0(sbh, osh, cc);
925		break;
926#endif
927#if defined(BCM4312)
928	case BCM4312_CHIP_ID:
929		clock = sb_pmu1_alpclk0(sbh, osh, cc);
930		/* always 20Mhz */
931		clock = 20000 * 1000;
932		break;
933#endif
934	default:
935		PMU_MSG(("No ALP clock specified "
936			"for chip %x rev %d pmurev %d, using default %d Hz\n",
937			sbh->chip, sbh->chiprev, sbh->pmurev, clock));
938		break;
939	}
940
941	/* Return to original core */
942	sb_setcoreidx(sbh, origidx);
943	return clock;
944}
945
946uint
947BCMINITFN(sb_pmu_cpu_clock)(sb_t *sbh, osl_t *osh)
948{
949	chipcregs_t *cc;
950	uint origidx;
951	uint32 clock = HT_CLOCK;
952
953	ASSERT(sbh->cccaps & CC_CAP_PMU);
954
955	/* Remember original core before switch to chipc */
956	origidx = sb_coreidx(sbh);
957	cc = sb_setcore(sbh, SB_CC, 0);
958	ASSERT(cc);
959
960	switch (sbh->chip) {
961#if defined(BCM4328)
962	case BCM4328_CHIP_ID:
963		clock = sb_pmu0_cpuclk0(sbh, osh, cc);
964		break;
965#endif
966	case BCM5354_CHIP_ID:
967		clock = sb_pmu0_cpuclk0(sbh, osh, cc);
968		break;
969#if defined(BCM4325)
970	case BCM4325_CHIP_ID:
971		clock = sb_pmu1_cpuclk0(sbh, osh, cc);
972		break;
973#endif
974#if defined(BCM4312)
975	case BCM4312_CHIP_ID:
976		clock = sb_pmu1_cpuclk0(sbh, osh, cc);
977		break;
978#endif
979	default:
980		PMU_MSG(("No CPU clock specified "
981			"for chip %x rev %d pmurev %d, using default %d Hz\n",
982			sbh->chip, sbh->chiprev, sbh->pmurev, clock));
983		break;
984	}
985
986	/* Return to original core */
987	sb_setcoreidx(sbh, origidx);
988	return clock;
989}
990
991void
992BCMINITFN(sb_pmu_init)(sb_t *sbh, osl_t *osh)
993{
994	chipcregs_t *cc;
995	uint origidx;
996
997	ASSERT(sbh->cccaps & CC_CAP_PMU);
998
999	/* Remember original core before switch to chipc */
1000	origidx = sb_coreidx(sbh);
1001	cc = sb_setcore(sbh, SB_CC, 0);
1002	ASSERT(cc);
1003
1004	if (sbh->pmurev >= 1) {
1005#if defined(BCM4325)
1006		if (sbh->chip == BCM4325_CHIP_ID && sbh->chiprev <= 1)
1007			AND_REG(osh, &cc->pmucontrol, ~PCTL_NOILP_ON_WAIT);
1008		else
1009#endif	/* BCM4325 */
1010			OR_REG(osh, &cc->pmucontrol, PCTL_NOILP_ON_WAIT);
1011	}
1012
1013	/* Return to original core */
1014	sb_setcoreidx(sbh, origidx);
1015}
1016
1017void
1018BCMINITFN(sb_pmu_otp_power)(sb_t *sbh, osl_t *osh, bool on)
1019{
1020	chipcregs_t *cc;
1021	uint origidx;
1022
1023	ASSERT(sbh->cccaps & CC_CAP_PMU);
1024
1025	/* Remember original core before switch to chipc */
1026	origidx = sb_coreidx(sbh);
1027	cc = sb_setcore(sbh, SB_CC, 0);
1028	ASSERT(cc);
1029
1030	switch (sbh->chip) {
1031#if defined(BCM4325)
1032	case BCM4325_CHIP_ID:
1033		if (on) {
1034			OR_REG(osh, &cc->min_res_mask, PMURES_BIT(RES4325_LNLDO2_PU));
1035			if (sbh->boardflags & BFL_BUCKBOOST)
1036				AND_REG(osh, &cc->min_res_mask,
1037					~PMURES_BIT(RES4325_BUCK_BOOST_PWM));
1038			OSL_DELAY(500);
1039		}
1040		else {
1041			if (sbh->boardflags & BFL_BUCKBOOST)
1042				OR_REG(osh, &cc->min_res_mask, PMURES_BIT(RES4325_BUCK_BOOST_PWM));
1043			AND_REG(osh, &cc->min_res_mask, ~PMURES_BIT(RES4325_LNLDO2_PU));
1044		}
1045		break;
1046#endif	/* BCM4325 */
1047	default:
1048		break;
1049	}
1050
1051	/* Return to original core */
1052	sb_setcoreidx(sbh, origidx);
1053}
1054
1055void
1056sb_pmu_rcal(sb_t *sbh, osl_t *osh)
1057{
1058	chipcregs_t *cc;
1059	uint origidx;
1060
1061	ASSERT(sbh->cccaps & CC_CAP_PMU);
1062
1063	/* Remember original core before switch to chipc */
1064	origidx = sb_coreidx(sbh);
1065	cc = sb_setcore(sbh, SB_CC, 0);
1066	ASSERT(cc);
1067
1068	switch (sbh->chip) {
1069#if defined(BCM4325)
1070	case BCM4325_CHIP_ID:
1071		{
1072		uint8 rcal_code;
1073		uint32 val;
1074
1075		/* Kick RCal */
1076		W_REG(osh, &cc->chipcontrol_addr, 1);
1077		AND_REG(osh, &cc->chipcontrol_data, ~0x04);
1078		OR_REG(osh, &cc->chipcontrol_data, 0x04);
1079
1080		/* Wait for completion */
1081		SPINWAIT(0 == (R_REG(osh, &cc->chipstatus) & 0x08), 10 * 1000 * 1000);
1082		ASSERT(R_REG(osh, &cc->chipstatus) & 0x08);
1083
1084		/* Drop the LSB to convert from 5 bit code to 4 bit code */
1085		rcal_code =  (uint8)(R_REG(osh, &cc->chipstatus) >> 5) & 0x0f;
1086		PMU_MSG(("RCal completed, status 0x%x, code 0x%x\n",
1087			R_REG(osh, &cc->chipstatus), rcal_code));
1088
1089		/* Write RCal code into pmu_vreg_ctrl[32:29] */
1090		W_REG(osh, &cc->regcontrol_addr, 0);
1091		val = R_REG(osh, &cc->regcontrol_data) & ~((uint32)0x07 << 29);
1092		val |= (uint32)(rcal_code & 0x07) << 29;
1093		W_REG(osh, &cc->regcontrol_data, val);
1094		W_REG(osh, &cc->regcontrol_addr, 1);
1095		val = R_REG(osh, &cc->regcontrol_data) & ~(uint32)0x01;
1096		val |= (uint32)((rcal_code >> 3) & 0x01);
1097		W_REG(osh, &cc->regcontrol_data, val);
1098
1099		/* Write RCal code into pmu_chip_ctrl[33:30] */
1100		W_REG(osh, &cc->chipcontrol_addr, 0);
1101		val = R_REG(osh, &cc->chipcontrol_data) & ~((uint32)0x03 << 30);
1102		val |= (uint32)(rcal_code & 0x03) << 30;
1103		W_REG(osh, &cc->chipcontrol_data, val);
1104		W_REG(osh, &cc->chipcontrol_addr, 1);
1105		val = R_REG(osh, &cc->chipcontrol_data) & ~(uint32)0x03;
1106		val |= (uint32)((rcal_code >> 2) & 0x03);
1107		W_REG(osh, &cc->chipcontrol_data, val);
1108
1109		/* Set override in pmu_chip_ctrl[29] */
1110		W_REG(osh, &cc->chipcontrol_addr, 0);
1111		OR_REG(osh, &cc->chipcontrol_data, (0x01 << 29));
1112
1113		/* Power off RCal block */
1114		W_REG(osh, &cc->chipcontrol_addr, 1);
1115		AND_REG(osh, &cc->chipcontrol_data, ~0x04);
1116
1117		break;
1118		}
1119#endif	/* BCM4325 */
1120	default:
1121		break;
1122	}
1123
1124	/* Return to original core */
1125	sb_setcoreidx(sbh, origidx);
1126}
1127