net: wireless: add brcm80211 drivers
[pandora-kernel.git] / drivers / net / wireless / brcm80211 / brcmsmac / pmu.c
1 /*
2  * Copyright (c) 2011 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
17 #include <linux/delay.h>
18 #include <linux/io.h>
19
20 #include <brcm_hw_ids.h>
21 #include <chipcommon.h>
22 #include <brcmu_utils.h>
23 #include "pub.h"
24 #include "aiutils.h"
25 #include "pmu.h"
26
27 /*
28  * external LPO crystal frequency
29  */
30 #define EXT_ILP_HZ 32768
31
32 /*
33  * Duration for ILP clock frequency measurment in milliseconds
34  *
35  * remark: 1000 must be an integer multiple of this duration
36  */
37 #define ILP_CALC_DUR    10
38
39 /* Fields in pmucontrol */
40 #define PCTL_ILP_DIV_MASK       0xffff0000
41 #define PCTL_ILP_DIV_SHIFT      16
42 #define PCTL_PLL_PLLCTL_UPD     0x00000400      /* rev 2 */
43 #define PCTL_NOILP_ON_WAIT      0x00000200      /* rev 1 */
44 #define PCTL_HT_REQ_EN          0x00000100
45 #define PCTL_ALP_REQ_EN         0x00000080
46 #define PCTL_XTALFREQ_MASK      0x0000007c
47 #define PCTL_XTALFREQ_SHIFT     2
48 #define PCTL_ILP_DIV_EN         0x00000002
49 #define PCTL_LPO_SEL            0x00000001
50
51 /* ILP clock */
52 #define ILP_CLOCK               32000
53
54 /* ALP clock on pre-PMU chips */
55 #define ALP_CLOCK               20000000
56
57 /* pmustatus */
58 #define PST_EXTLPOAVAIL 0x0100
59 #define PST_WDRESET     0x0080
60 #define PST_INTPEND     0x0040
61 #define PST_SBCLKST     0x0030
62 #define PST_SBCLKST_ILP 0x0010
63 #define PST_SBCLKST_ALP 0x0020
64 #define PST_SBCLKST_HT  0x0030
65 #define PST_ALPAVAIL    0x0008
66 #define PST_HTAVAIL     0x0004
67 #define PST_RESINIT     0x0003
68
69 /* PMU resource bit position */
70 #define PMURES_BIT(bit) (1 << (bit))
71
72 /* PMU corerev and chip specific PLL controls.
73  * PMU<rev>_PLL<num>_XX where <rev> is PMU corerev and <num> is an arbitrary
74  * number to differentiate different PLLs controlled by the same PMU rev.
75  */
76 /* pllcontrol registers:
77  * ndiv_pwrdn, pwrdn_ch<x>, refcomp_pwrdn, dly_ch<x>,
78  * p1div, p2div, _bypass_sdmod
79  */
80 #define PMU1_PLL0_PLLCTL0               0
81 #define PMU1_PLL0_PLLCTL1               1
82 #define PMU1_PLL0_PLLCTL2               2
83 #define PMU1_PLL0_PLLCTL3               3
84 #define PMU1_PLL0_PLLCTL4               4
85 #define PMU1_PLL0_PLLCTL5               5
86
87 /* pmu XtalFreqRatio */
88 #define PMU_XTALFREQ_REG_ILPCTR_MASK    0x00001FFF
89 #define PMU_XTALFREQ_REG_MEASURE_MASK   0x80000000
90 #define PMU_XTALFREQ_REG_MEASURE_SHIFT  31
91
92 /* 4313 resources */
93 #define RES4313_BB_PU_RSRC              0
94 #define RES4313_ILP_REQ_RSRC            1
95 #define RES4313_XTAL_PU_RSRC            2
96 #define RES4313_ALP_AVAIL_RSRC          3
97 #define RES4313_RADIO_PU_RSRC           4
98 #define RES4313_BG_PU_RSRC              5
99 #define RES4313_VREG1P4_PU_RSRC         6
100 #define RES4313_AFE_PWRSW_RSRC          7
101 #define RES4313_RX_PWRSW_RSRC           8
102 #define RES4313_TX_PWRSW_RSRC           9
103 #define RES4313_BB_PWRSW_RSRC           10
104 #define RES4313_SYNTH_PWRSW_RSRC        11
105 #define RES4313_MISC_PWRSW_RSRC         12
106 #define RES4313_BB_PLL_PWRSW_RSRC       13
107 #define RES4313_HT_AVAIL_RSRC           14
108 #define RES4313_MACPHY_CLK_AVAIL_RSRC   15
109
110 /* Determine min/max rsrc masks. Value 0 leaves hardware at default. */
111 static void si_pmu_res_masks(struct si_pub *sih, u32 * pmin, u32 * pmax)
112 {
113         u32 min_mask = 0, max_mask = 0;
114         uint rsrcs;
115
116         /* # resources */
117         rsrcs = (sih->pmucaps & PCAP_RC_MASK) >> PCAP_RC_SHIFT;
118
119         /* determine min/max rsrc masks */
120         switch (sih->chip) {
121         case BCM43224_CHIP_ID:
122         case BCM43225_CHIP_ID:
123                 /* ??? */
124                 break;
125
126         case BCM4313_CHIP_ID:
127                 min_mask = PMURES_BIT(RES4313_BB_PU_RSRC) |
128                     PMURES_BIT(RES4313_XTAL_PU_RSRC) |
129                     PMURES_BIT(RES4313_ALP_AVAIL_RSRC) |
130                     PMURES_BIT(RES4313_BB_PLL_PWRSW_RSRC);
131                 max_mask = 0xffff;
132                 break;
133         default:
134                 break;
135         }
136
137         *pmin = min_mask;
138         *pmax = max_mask;
139 }
140
141 static void
142 si_pmu_spuravoid_pllupdate(struct si_pub *sih, struct chipcregs __iomem *cc,
143                            u8 spuravoid)
144 {
145         u32 tmp = 0;
146
147         switch (sih->chip) {
148         case BCM43224_CHIP_ID:
149         case BCM43225_CHIP_ID:
150                 if (spuravoid == 1) {
151                         W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0);
152                         W_REG(&cc->pllcontrol_data, 0x11500010);
153                         W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1);
154                         W_REG(&cc->pllcontrol_data, 0x000C0C06);
155                         W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2);
156                         W_REG(&cc->pllcontrol_data, 0x0F600a08);
157                         W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3);
158                         W_REG(&cc->pllcontrol_data, 0x00000000);
159                         W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4);
160                         W_REG(&cc->pllcontrol_data, 0x2001E920);
161                         W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5);
162                         W_REG(&cc->pllcontrol_data, 0x88888815);
163                 } else {
164                         W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0);
165                         W_REG(&cc->pllcontrol_data, 0x11100010);
166                         W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1);
167                         W_REG(&cc->pllcontrol_data, 0x000c0c06);
168                         W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2);
169                         W_REG(&cc->pllcontrol_data, 0x03000a08);
170                         W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3);
171                         W_REG(&cc->pllcontrol_data, 0x00000000);
172                         W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4);
173                         W_REG(&cc->pllcontrol_data, 0x200005c0);
174                         W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5);
175                         W_REG(&cc->pllcontrol_data, 0x88888815);
176                 }
177                 tmp = 1 << 10;
178                 break;
179
180                 W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0);
181                 W_REG(&cc->pllcontrol_data, 0x11100008);
182                 W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1);
183                 W_REG(&cc->pllcontrol_data, 0x0c000c06);
184                 W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2);
185                 W_REG(&cc->pllcontrol_data, 0x03000a08);
186                 W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3);
187                 W_REG(&cc->pllcontrol_data, 0x00000000);
188                 W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4);
189                 W_REG(&cc->pllcontrol_data, 0x200005c0);
190                 W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5);
191                 W_REG(&cc->pllcontrol_data, 0x88888855);
192
193                 tmp = 1 << 10;
194                 break;
195
196         default:
197                 /* bail out */
198                 return;
199         }
200
201         tmp |= R_REG(&cc->pmucontrol);
202         W_REG(&cc->pmucontrol, tmp);
203 }
204
205 u16 si_pmu_fast_pwrup_delay(struct si_pub *sih)
206 {
207         uint delay = PMU_MAX_TRANSITION_DLY;
208
209         switch (sih->chip) {
210         case BCM43224_CHIP_ID:
211         case BCM43225_CHIP_ID:
212         case BCM4313_CHIP_ID:
213                 delay = 3700;
214                 break;
215         default:
216                 break;
217         }
218
219         return (u16) delay;
220 }
221
222 void si_pmu_sprom_enable(struct si_pub *sih, bool enable)
223 {
224         struct chipcregs __iomem *cc;
225         uint origidx;
226
227         /* Remember original core before switch to chipc */
228         origidx = ai_coreidx(sih);
229         cc = ai_setcoreidx(sih, SI_CC_IDX);
230
231         /* Return to original core */
232         ai_setcoreidx(sih, origidx);
233 }
234
235 /* Read/write a chipcontrol reg */
236 u32 si_pmu_chipcontrol(struct si_pub *sih, uint reg, u32 mask, u32 val)
237 {
238         ai_corereg(sih, SI_CC_IDX, offsetof(struct chipcregs, chipcontrol_addr),
239                    ~0, reg);
240         return ai_corereg(sih, SI_CC_IDX,
241                           offsetof(struct chipcregs, chipcontrol_data), mask,
242                           val);
243 }
244
245 /* Read/write a regcontrol reg */
246 u32 si_pmu_regcontrol(struct si_pub *sih, uint reg, u32 mask, u32 val)
247 {
248         ai_corereg(sih, SI_CC_IDX, offsetof(struct chipcregs, regcontrol_addr),
249                    ~0, reg);
250         return ai_corereg(sih, SI_CC_IDX,
251                           offsetof(struct chipcregs, regcontrol_data), mask,
252                           val);
253 }
254
255 /* Read/write a pllcontrol reg */
256 u32 si_pmu_pllcontrol(struct si_pub *sih, uint reg, u32 mask, u32 val)
257 {
258         ai_corereg(sih, SI_CC_IDX, offsetof(struct chipcregs, pllcontrol_addr),
259                    ~0, reg);
260         return ai_corereg(sih, SI_CC_IDX,
261                           offsetof(struct chipcregs, pllcontrol_data), mask,
262                           val);
263 }
264
265 /* PMU PLL update */
266 void si_pmu_pllupd(struct si_pub *sih)
267 {
268         ai_corereg(sih, SI_CC_IDX, offsetof(struct chipcregs, pmucontrol),
269                    PCTL_PLL_PLLCTL_UPD, PCTL_PLL_PLLCTL_UPD);
270 }
271
272 /* query alp/xtal clock frequency */
273 u32 si_pmu_alp_clock(struct si_pub *sih)
274 {
275         u32 clock = ALP_CLOCK;
276
277         /* bail out with default */
278         if (!(sih->cccaps & CC_CAP_PMU))
279                 return clock;
280
281         switch (sih->chip) {
282         case BCM43224_CHIP_ID:
283         case BCM43225_CHIP_ID:
284         case BCM4313_CHIP_ID:
285                 /* always 20Mhz */
286                 clock = 20000 * 1000;
287                 break;
288         default:
289                 break;
290         }
291
292         return clock;
293 }
294
295 void si_pmu_spuravoid(struct si_pub *sih, u8 spuravoid)
296 {
297         struct chipcregs __iomem *cc;
298         uint origidx, intr_val;
299
300         /* Remember original core before switch to chipc */
301         cc = (struct chipcregs __iomem *)
302                         ai_switch_core(sih, CC_CORE_ID, &origidx, &intr_val);
303
304         /* update the pll changes */
305         si_pmu_spuravoid_pllupdate(sih, cc, spuravoid);
306
307         /* Return to original core */
308         ai_restore_core(sih, origidx, intr_val);
309 }
310
311 /* initialize PMU */
312 void si_pmu_init(struct si_pub *sih)
313 {
314         struct chipcregs __iomem *cc;
315         uint origidx;
316
317         /* Remember original core before switch to chipc */
318         origidx = ai_coreidx(sih);
319         cc = ai_setcoreidx(sih, SI_CC_IDX);
320
321         if (sih->pmurev == 1)
322                 AND_REG(&cc->pmucontrol, ~PCTL_NOILP_ON_WAIT);
323         else if (sih->pmurev >= 2)
324                 OR_REG(&cc->pmucontrol, PCTL_NOILP_ON_WAIT);
325
326         /* Return to original core */
327         ai_setcoreidx(sih, origidx);
328 }
329
330 /* initialize PMU chip controls and other chip level stuff */
331 void si_pmu_chip_init(struct si_pub *sih)
332 {
333         uint origidx;
334
335         /* Gate off SPROM clock and chip select signals */
336         si_pmu_sprom_enable(sih, false);
337
338         /* Remember original core */
339         origidx = ai_coreidx(sih);
340
341         /* Return to original core */
342         ai_setcoreidx(sih, origidx);
343 }
344
345 /* initialize PMU switch/regulators */
346 void si_pmu_swreg_init(struct si_pub *sih)
347 {
348 }
349
350 /* initialize PLL */
351 void si_pmu_pll_init(struct si_pub *sih, uint xtalfreq)
352 {
353         struct chipcregs __iomem *cc;
354         uint origidx;
355
356         /* Remember original core before switch to chipc */
357         origidx = ai_coreidx(sih);
358         cc = ai_setcoreidx(sih, SI_CC_IDX);
359
360         switch (sih->chip) {
361         case BCM4313_CHIP_ID:
362         case BCM43224_CHIP_ID:
363         case BCM43225_CHIP_ID:
364                 /* ??? */
365                 break;
366         default:
367                 break;
368         }
369
370         /* Return to original core */
371         ai_setcoreidx(sih, origidx);
372 }
373
374 /* initialize PMU resources */
375 void si_pmu_res_init(struct si_pub *sih)
376 {
377         struct chipcregs __iomem *cc;
378         uint origidx;
379         u32 min_mask = 0, max_mask = 0;
380
381         /* Remember original core before switch to chipc */
382         origidx = ai_coreidx(sih);
383         cc = ai_setcoreidx(sih, SI_CC_IDX);
384
385         /* Determine min/max rsrc masks */
386         si_pmu_res_masks(sih, &min_mask, &max_mask);
387
388         /* It is required to program max_mask first and then min_mask */
389
390         /* Program max resource mask */
391
392         if (max_mask)
393                 W_REG(&cc->max_res_mask, max_mask);
394
395         /* Program min resource mask */
396
397         if (min_mask)
398                 W_REG(&cc->min_res_mask, min_mask);
399
400         /* Add some delay; allow resources to come up and settle. */
401         mdelay(2);
402
403         /* Return to original core */
404         ai_setcoreidx(sih, origidx);
405 }
406
407 u32 si_pmu_measure_alpclk(struct si_pub *sih)
408 {
409         struct chipcregs __iomem *cc;
410         uint origidx;
411         u32 alp_khz;
412
413         if (sih->pmurev < 10)
414                 return 0;
415
416         /* Remember original core before switch to chipc */
417         origidx = ai_coreidx(sih);
418         cc = ai_setcoreidx(sih, SI_CC_IDX);
419
420         if (R_REG(&cc->pmustatus) & PST_EXTLPOAVAIL) {
421                 u32 ilp_ctr, alp_hz;
422
423                 /*
424                  * Enable the reg to measure the freq,
425                  * in case it was disabled before
426                  */
427                 W_REG(&cc->pmu_xtalfreq,
428                       1U << PMU_XTALFREQ_REG_MEASURE_SHIFT);
429
430                 /* Delay for well over 4 ILP clocks */
431                 udelay(1000);
432
433                 /* Read the latched number of ALP ticks per 4 ILP ticks */
434                 ilp_ctr =
435                     R_REG(&cc->pmu_xtalfreq) & PMU_XTALFREQ_REG_ILPCTR_MASK;
436
437                 /*
438                  * Turn off the PMU_XTALFREQ_REG_MEASURE_SHIFT
439                  * bit to save power
440                  */
441                 W_REG(&cc->pmu_xtalfreq, 0);
442
443                 /* Calculate ALP frequency */
444                 alp_hz = (ilp_ctr * EXT_ILP_HZ) / 4;
445
446                 /*
447                  * Round to nearest 100KHz, and at
448                  * the same time convert to KHz
449                  */
450                 alp_khz = (alp_hz + 50000) / 100000 * 100;
451         } else
452                 alp_khz = 0;
453
454         /* Return to original core */
455         ai_setcoreidx(sih, origidx);
456
457         return alp_khz;
458 }