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