block: fix warning with calling smp_processor_id() in preemptible section
[pandora-kernel.git] / drivers / staging / brcm80211 / brcmsmac / wlc_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 #include <linux/kernel.h>
17 #include <linux/types.h>
18 #include <linux/delay.h>
19 #include <linux/io.h>
20
21 #include <bcmdevs.h>
22 #include <sbchipc.h>
23 #include <bcmutils.h>
24 #include <bcmnvram.h>
25 #include "wlc_pmu.h"
26
27 /*
28  * d11 slow to fast clock transition time in slow clock cycles
29  */
30 #define D11SCC_SLOW2FAST_TRANSITION     2
31
32 /*
33  * external LPO crystal frequency
34  */
35 #define EXT_ILP_HZ 32768
36
37 /*
38  * Duration for ILP clock frequency measurment in milliseconds
39  *
40  * remark: 1000 must be an integer multiple of this duration
41  */
42 #define ILP_CALC_DUR    10
43
44 /*
45  * FVCO frequency
46  */
47 #define FVCO_880        880000  /* 880MHz */
48 #define FVCO_1760       1760000 /* 1760MHz */
49 #define FVCO_1440       1440000 /* 1440MHz */
50 #define FVCO_960        960000  /* 960MHz */
51
52 /*
53  * PMU crystal table indices for 1440MHz fvco
54  */
55 #define PMU1_XTALTAB0_1440_12000K       0
56 #define PMU1_XTALTAB0_1440_13000K       1
57 #define PMU1_XTALTAB0_1440_14400K       2
58 #define PMU1_XTALTAB0_1440_15360K       3
59 #define PMU1_XTALTAB0_1440_16200K       4
60 #define PMU1_XTALTAB0_1440_16800K       5
61 #define PMU1_XTALTAB0_1440_19200K       6
62 #define PMU1_XTALTAB0_1440_19800K       7
63 #define PMU1_XTALTAB0_1440_20000K       8
64 #define PMU1_XTALTAB0_1440_25000K       9
65 #define PMU1_XTALTAB0_1440_26000K       10
66 #define PMU1_XTALTAB0_1440_30000K       11
67 #define PMU1_XTALTAB0_1440_37400K       12
68 #define PMU1_XTALTAB0_1440_38400K       13
69 #define PMU1_XTALTAB0_1440_40000K       14
70 #define PMU1_XTALTAB0_1440_48000K       15
71
72 /*
73  * PMU crystal table indices for 960MHz fvco
74  */
75 #define PMU1_XTALTAB0_960_12000K        0
76 #define PMU1_XTALTAB0_960_13000K        1
77 #define PMU1_XTALTAB0_960_14400K        2
78 #define PMU1_XTALTAB0_960_15360K        3
79 #define PMU1_XTALTAB0_960_16200K        4
80 #define PMU1_XTALTAB0_960_16800K        5
81 #define PMU1_XTALTAB0_960_19200K        6
82 #define PMU1_XTALTAB0_960_19800K        7
83 #define PMU1_XTALTAB0_960_20000K        8
84 #define PMU1_XTALTAB0_960_25000K        9
85 #define PMU1_XTALTAB0_960_26000K        10
86 #define PMU1_XTALTAB0_960_30000K        11
87 #define PMU1_XTALTAB0_960_37400K        12
88 #define PMU1_XTALTAB0_960_38400K        13
89 #define PMU1_XTALTAB0_960_40000K        14
90 #define PMU1_XTALTAB0_960_48000K        15
91
92 /*
93  * PMU crystal table indices for 880MHz fvco
94  */
95 #define PMU1_XTALTAB0_880_12000K        0
96 #define PMU1_XTALTAB0_880_13000K        1
97 #define PMU1_XTALTAB0_880_14400K        2
98 #define PMU1_XTALTAB0_880_15360K        3
99 #define PMU1_XTALTAB0_880_16200K        4
100 #define PMU1_XTALTAB0_880_16800K        5
101 #define PMU1_XTALTAB0_880_19200K        6
102 #define PMU1_XTALTAB0_880_19800K        7
103 #define PMU1_XTALTAB0_880_20000K        8
104 #define PMU1_XTALTAB0_880_24000K        9
105 #define PMU1_XTALTAB0_880_25000K        10
106 #define PMU1_XTALTAB0_880_26000K        11
107 #define PMU1_XTALTAB0_880_30000K        12
108 #define PMU1_XTALTAB0_880_37400K        13
109 #define PMU1_XTALTAB0_880_38400K        14
110 #define PMU1_XTALTAB0_880_40000K        15
111
112 /*
113  * crystal frequency values
114  */
115 #define XTAL_FREQ_24000MHZ              24000
116 #define XTAL_FREQ_30000MHZ              30000
117 #define XTAL_FREQ_37400MHZ              37400
118 #define XTAL_FREQ_48000MHZ              48000
119
120 /*
121  * Resource dependancies mask change action
122  *
123  * @RES_DEPEND_SET: Override the dependancies mask
124  * @RES_DEPEND_ADD: Add to the  dependancies mask
125  * @RES_DEPEND_REMOVE: Remove from the dependancies mask
126  */
127 #define RES_DEPEND_SET          0
128 #define RES_DEPEND_ADD          1
129 #define RES_DEPEND_REMOVE       -1
130
131 /* d11 slow to fast clock transition time in slow clock cycles */
132 #define D11SCC_SLOW2FAST_TRANSITION     2
133
134 /* Setup resource up/down timers */
135 typedef struct {
136         u8 resnum;
137         u16 updown;
138 } pmu_res_updown_t;
139
140 /* Change resource dependancies masks */
141 typedef struct {
142         u32 res_mask;   /* resources (chip specific) */
143         s8 action;              /* action */
144         u32 depend_mask;        /* changes to the dependancies mask */
145          bool(*filter) (si_t *sih);     /* action is taken when filter is NULL or return true */
146 } pmu_res_depend_t;
147
148 /* setup pll and query clock speed */
149 typedef struct {
150         u16 fref;
151         u8 xf;
152         u8 p1div;
153         u8 p2div;
154         u8 ndiv_int;
155         u32 ndiv_frac;
156 } pmu1_xtaltab0_t;
157
158 /*
159  * prototypes used in resource tables
160  */
161 static bool si_pmu_res_depfltr_bb(si_t *sih);
162 static bool si_pmu_res_depfltr_ncb(si_t *sih);
163 static bool si_pmu_res_depfltr_paldo(si_t *sih);
164 static bool si_pmu_res_depfltr_npaldo(si_t *sih);
165
166 static const pmu_res_updown_t bcm4328a0_res_updown[] = {
167         {
168         RES4328_EXT_SWITCHER_PWM, 0x0101}, {
169         RES4328_BB_SWITCHER_PWM, 0x1f01}, {
170         RES4328_BB_SWITCHER_BURST, 0x010f}, {
171         RES4328_BB_EXT_SWITCHER_BURST, 0x0101}, {
172         RES4328_ILP_REQUEST, 0x0202}, {
173         RES4328_RADIO_SWITCHER_PWM, 0x0f01}, {
174         RES4328_RADIO_SWITCHER_BURST, 0x0f01}, {
175         RES4328_ROM_SWITCH, 0x0101}, {
176         RES4328_PA_REF_LDO, 0x0f01}, {
177         RES4328_RADIO_LDO, 0x0f01}, {
178         RES4328_AFE_LDO, 0x0f01}, {
179         RES4328_PLL_LDO, 0x0f01}, {
180         RES4328_BG_FILTBYP, 0x0101}, {
181         RES4328_TX_FILTBYP, 0x0101}, {
182         RES4328_RX_FILTBYP, 0x0101}, {
183         RES4328_XTAL_PU, 0x0101}, {
184         RES4328_XTAL_EN, 0xa001}, {
185         RES4328_BB_PLL_FILTBYP, 0x0101}, {
186         RES4328_RF_PLL_FILTBYP, 0x0101}, {
187         RES4328_BB_PLL_PU, 0x0701}
188 };
189
190 static const pmu_res_depend_t bcm4328a0_res_depend[] = {
191         /* Adjust ILP request resource not to force ext/BB switchers into burst mode */
192         {
193         PMURES_BIT(RES4328_ILP_REQUEST),
194                     RES_DEPEND_SET,
195                     PMURES_BIT(RES4328_EXT_SWITCHER_PWM) |
196                     PMURES_BIT(RES4328_BB_SWITCHER_PWM), NULL}
197 };
198
199 static const pmu_res_updown_t bcm4325a0_res_updown_qt[] = {
200         {
201         RES4325_HT_AVAIL, 0x0300}, {
202         RES4325_BBPLL_PWRSW_PU, 0x0101}, {
203         RES4325_RFPLL_PWRSW_PU, 0x0101}, {
204         RES4325_ALP_AVAIL, 0x0100}, {
205         RES4325_XTAL_PU, 0x1000}, {
206         RES4325_LNLDO1_PU, 0x0800}, {
207         RES4325_CLDO_CBUCK_PWM, 0x0101}, {
208         RES4325_CBUCK_PWM, 0x0803}
209 };
210
211 static const pmu_res_updown_t bcm4325a0_res_updown[] = {
212         {
213         RES4325_XTAL_PU, 0x1501}
214 };
215
216 static const pmu_res_depend_t bcm4325a0_res_depend[] = {
217         /* Adjust OTP PU resource dependencies - remove BB BURST */
218         {
219         PMURES_BIT(RES4325_OTP_PU),
220                     RES_DEPEND_REMOVE,
221                     PMURES_BIT(RES4325_BUCK_BOOST_BURST), NULL},
222             /* Adjust ALP/HT Avail resource dependencies - bring up BB along if it is used. */
223         {
224         PMURES_BIT(RES4325_ALP_AVAIL) | PMURES_BIT(RES4325_HT_AVAIL),
225                     RES_DEPEND_ADD,
226                     PMURES_BIT(RES4325_BUCK_BOOST_BURST) |
227                     PMURES_BIT(RES4325_BUCK_BOOST_PWM), si_pmu_res_depfltr_bb},
228             /* Adjust HT Avail resource dependencies - bring up RF switches along with HT. */
229         {
230         PMURES_BIT(RES4325_HT_AVAIL),
231                     RES_DEPEND_ADD,
232                     PMURES_BIT(RES4325_RX_PWRSW_PU) |
233                     PMURES_BIT(RES4325_TX_PWRSW_PU) |
234                     PMURES_BIT(RES4325_LOGEN_PWRSW_PU) |
235                     PMURES_BIT(RES4325_AFE_PWRSW_PU), NULL},
236             /* Adjust ALL resource dependencies - remove CBUCK dependancies if it is not used. */
237         {
238         PMURES_BIT(RES4325_ILP_REQUEST) |
239                     PMURES_BIT(RES4325_ABUCK_BURST) |
240                     PMURES_BIT(RES4325_ABUCK_PWM) |
241                     PMURES_BIT(RES4325_LNLDO1_PU) |
242                     PMURES_BIT(RES4325C1_LNLDO2_PU) |
243                     PMURES_BIT(RES4325_XTAL_PU) |
244                     PMURES_BIT(RES4325_ALP_AVAIL) |
245                     PMURES_BIT(RES4325_RX_PWRSW_PU) |
246                     PMURES_BIT(RES4325_TX_PWRSW_PU) |
247                     PMURES_BIT(RES4325_RFPLL_PWRSW_PU) |
248                     PMURES_BIT(RES4325_LOGEN_PWRSW_PU) |
249                     PMURES_BIT(RES4325_AFE_PWRSW_PU) |
250                     PMURES_BIT(RES4325_BBPLL_PWRSW_PU) |
251                     PMURES_BIT(RES4325_HT_AVAIL), RES_DEPEND_REMOVE,
252                     PMURES_BIT(RES4325B0_CBUCK_LPOM) |
253                     PMURES_BIT(RES4325B0_CBUCK_BURST) |
254                     PMURES_BIT(RES4325B0_CBUCK_PWM), si_pmu_res_depfltr_ncb}
255 };
256
257 static const pmu_res_updown_t bcm4315a0_res_updown_qt[] = {
258         {
259         RES4315_HT_AVAIL, 0x0101}, {
260         RES4315_XTAL_PU, 0x0100}, {
261         RES4315_LNLDO1_PU, 0x0100}, {
262         RES4315_PALDO_PU, 0x0100}, {
263         RES4315_CLDO_PU, 0x0100}, {
264         RES4315_CBUCK_PWM, 0x0100}, {
265         RES4315_CBUCK_BURST, 0x0100}, {
266         RES4315_CBUCK_LPOM, 0x0100}
267 };
268
269 static const pmu_res_updown_t bcm4315a0_res_updown[] = {
270         {
271         RES4315_XTAL_PU, 0x2501}
272 };
273
274 static const pmu_res_depend_t bcm4315a0_res_depend[] = {
275         /* Adjust OTP PU resource dependencies - not need PALDO unless write */
276         {
277         PMURES_BIT(RES4315_OTP_PU),
278                     RES_DEPEND_REMOVE,
279                     PMURES_BIT(RES4315_PALDO_PU), si_pmu_res_depfltr_npaldo},
280             /* Adjust ALP/HT Avail resource dependencies - bring up PALDO along if it is used. */
281         {
282         PMURES_BIT(RES4315_ALP_AVAIL) | PMURES_BIT(RES4315_HT_AVAIL),
283                     RES_DEPEND_ADD,
284                     PMURES_BIT(RES4315_PALDO_PU), si_pmu_res_depfltr_paldo},
285             /* Adjust HT Avail resource dependencies - bring up RF switches along with HT. */
286         {
287         PMURES_BIT(RES4315_HT_AVAIL),
288                     RES_DEPEND_ADD,
289                     PMURES_BIT(RES4315_RX_PWRSW_PU) |
290                     PMURES_BIT(RES4315_TX_PWRSW_PU) |
291                     PMURES_BIT(RES4315_LOGEN_PWRSW_PU) |
292                     PMURES_BIT(RES4315_AFE_PWRSW_PU), NULL},
293             /* Adjust ALL resource dependencies - remove CBUCK dependancies if it is not used. */
294         {
295         PMURES_BIT(RES4315_CLDO_PU) | PMURES_BIT(RES4315_ILP_REQUEST) |
296                     PMURES_BIT(RES4315_LNLDO1_PU) |
297                     PMURES_BIT(RES4315_OTP_PU) |
298                     PMURES_BIT(RES4315_LNLDO2_PU) |
299                     PMURES_BIT(RES4315_XTAL_PU) |
300                     PMURES_BIT(RES4315_ALP_AVAIL) |
301                     PMURES_BIT(RES4315_RX_PWRSW_PU) |
302                     PMURES_BIT(RES4315_TX_PWRSW_PU) |
303                     PMURES_BIT(RES4315_RFPLL_PWRSW_PU) |
304                     PMURES_BIT(RES4315_LOGEN_PWRSW_PU) |
305                     PMURES_BIT(RES4315_AFE_PWRSW_PU) |
306                     PMURES_BIT(RES4315_BBPLL_PWRSW_PU) |
307                     PMURES_BIT(RES4315_HT_AVAIL), RES_DEPEND_REMOVE,
308                     PMURES_BIT(RES4315_CBUCK_LPOM) |
309                     PMURES_BIT(RES4315_CBUCK_BURST) |
310                     PMURES_BIT(RES4315_CBUCK_PWM), si_pmu_res_depfltr_ncb}
311 };
312
313         /* 4329 specific. needs to come back this issue later */
314 static const pmu_res_updown_t bcm4329_res_updown[] = {
315         {
316         RES4329_XTAL_PU, 0x1501}
317 };
318
319 static const pmu_res_depend_t bcm4329_res_depend[] = {
320         /* Adjust HT Avail resource dependencies */
321         {
322         PMURES_BIT(RES4329_HT_AVAIL),
323                     RES_DEPEND_ADD,
324                     PMURES_BIT(RES4329_CBUCK_LPOM) |
325                     PMURES_BIT(RES4329_CBUCK_BURST) |
326                     PMURES_BIT(RES4329_CBUCK_PWM) |
327                     PMURES_BIT(RES4329_CLDO_PU) |
328                     PMURES_BIT(RES4329_PALDO_PU) |
329                     PMURES_BIT(RES4329_LNLDO1_PU) |
330                     PMURES_BIT(RES4329_XTAL_PU) |
331                     PMURES_BIT(RES4329_ALP_AVAIL) |
332                     PMURES_BIT(RES4329_RX_PWRSW_PU) |
333                     PMURES_BIT(RES4329_TX_PWRSW_PU) |
334                     PMURES_BIT(RES4329_RFPLL_PWRSW_PU) |
335                     PMURES_BIT(RES4329_LOGEN_PWRSW_PU) |
336                     PMURES_BIT(RES4329_AFE_PWRSW_PU) |
337                     PMURES_BIT(RES4329_BBPLL_PWRSW_PU), NULL}
338 };
339
340 static const pmu_res_updown_t bcm4319a0_res_updown_qt[] = {
341         {
342         RES4319_HT_AVAIL, 0x0101}, {
343         RES4319_XTAL_PU, 0x0100}, {
344         RES4319_LNLDO1_PU, 0x0100}, {
345         RES4319_PALDO_PU, 0x0100}, {
346         RES4319_CLDO_PU, 0x0100}, {
347         RES4319_CBUCK_PWM, 0x0100}, {
348         RES4319_CBUCK_BURST, 0x0100}, {
349         RES4319_CBUCK_LPOM, 0x0100}
350 };
351
352 static const pmu_res_updown_t bcm4319a0_res_updown[] = {
353         {
354         RES4319_XTAL_PU, 0x3f01}
355 };
356
357 static const pmu_res_depend_t bcm4319a0_res_depend[] = {
358         /* Adjust OTP PU resource dependencies - not need PALDO unless write */
359         {
360         PMURES_BIT(RES4319_OTP_PU),
361                     RES_DEPEND_REMOVE,
362                     PMURES_BIT(RES4319_PALDO_PU), si_pmu_res_depfltr_npaldo},
363             /* Adjust HT Avail resource dependencies - bring up PALDO along if it is used. */
364         {
365         PMURES_BIT(RES4319_HT_AVAIL),
366                     RES_DEPEND_ADD,
367                     PMURES_BIT(RES4319_PALDO_PU), si_pmu_res_depfltr_paldo},
368             /* Adjust HT Avail resource dependencies - bring up RF switches along with HT. */
369         {
370         PMURES_BIT(RES4319_HT_AVAIL),
371                     RES_DEPEND_ADD,
372                     PMURES_BIT(RES4319_RX_PWRSW_PU) |
373                     PMURES_BIT(RES4319_TX_PWRSW_PU) |
374                     PMURES_BIT(RES4319_RFPLL_PWRSW_PU) |
375                     PMURES_BIT(RES4319_LOGEN_PWRSW_PU) |
376                     PMURES_BIT(RES4319_AFE_PWRSW_PU), NULL}
377 };
378
379 static const pmu_res_updown_t bcm4336a0_res_updown_qt[] = {
380         {
381         RES4336_HT_AVAIL, 0x0101}, {
382         RES4336_XTAL_PU, 0x0100}, {
383         RES4336_CLDO_PU, 0x0100}, {
384         RES4336_CBUCK_PWM, 0x0100}, {
385         RES4336_CBUCK_BURST, 0x0100}, {
386         RES4336_CBUCK_LPOM, 0x0100}
387 };
388
389 static const pmu_res_updown_t bcm4336a0_res_updown[] = {
390         {
391         RES4336_HT_AVAIL, 0x0D01}
392 };
393
394 static const pmu_res_depend_t bcm4336a0_res_depend[] = {
395         /* Just a dummy entry for now */
396         {
397         PMURES_BIT(RES4336_RSVD), RES_DEPEND_ADD, 0, NULL}
398 };
399
400 static const pmu_res_updown_t bcm4330a0_res_updown_qt[] = {
401         {
402         RES4330_HT_AVAIL, 0x0101}, {
403         RES4330_XTAL_PU, 0x0100}, {
404         RES4330_CLDO_PU, 0x0100}, {
405         RES4330_CBUCK_PWM, 0x0100}, {
406         RES4330_CBUCK_BURST, 0x0100}, {
407         RES4330_CBUCK_LPOM, 0x0100}
408 };
409
410 static const pmu_res_updown_t bcm4330a0_res_updown[] = {
411         {
412         RES4330_HT_AVAIL, 0x0e02}
413 };
414
415 static const pmu_res_depend_t bcm4330a0_res_depend[] = {
416         /* Just a dummy entry for now */
417         {
418         PMURES_BIT(RES4330_HT_AVAIL), RES_DEPEND_ADD, 0, NULL}
419 };
420
421 /* the following table is based on 1440Mhz fvco */
422 static const pmu1_xtaltab0_t pmu1_xtaltab0_1440[] = {
423         {
424         12000, 1, 1, 1, 0x78, 0x0}, {
425         13000, 2, 1, 1, 0x6E, 0xC4EC4E}, {
426         14400, 3, 1, 1, 0x64, 0x0}, {
427         15360, 4, 1, 1, 0x5D, 0xC00000}, {
428         16200, 5, 1, 1, 0x58, 0xE38E38}, {
429         16800, 6, 1, 1, 0x55, 0xB6DB6D}, {
430         19200, 7, 1, 1, 0x4B, 0}, {
431         19800, 8, 1, 1, 0x48, 0xBA2E8B}, {
432         20000, 9, 1, 1, 0x48, 0x0}, {
433         25000, 10, 1, 1, 0x39, 0x999999}, {
434         26000, 11, 1, 1, 0x37, 0x627627}, {
435         30000, 12, 1, 1, 0x30, 0x0}, {
436         37400, 13, 2, 1, 0x4D, 0x15E76}, {
437         38400, 13, 2, 1, 0x4B, 0x0}, {
438         40000, 14, 2, 1, 0x48, 0x0}, {
439         48000, 15, 2, 1, 0x3c, 0x0}, {
440         0, 0, 0, 0, 0, 0}
441 };
442
443 static const pmu1_xtaltab0_t pmu1_xtaltab0_960[] = {
444         {
445         12000, 1, 1, 1, 0x50, 0x0}, {
446         13000, 2, 1, 1, 0x49, 0xD89D89}, {
447         14400, 3, 1, 1, 0x42, 0xAAAAAA}, {
448         15360, 4, 1, 1, 0x3E, 0x800000}, {
449         16200, 5, 1, 1, 0x39, 0x425ED0}, {
450         16800, 6, 1, 1, 0x39, 0x249249}, {
451         19200, 7, 1, 1, 0x32, 0x0}, {
452         19800, 8, 1, 1, 0x30, 0x7C1F07}, {
453         20000, 9, 1, 1, 0x30, 0x0}, {
454         25000, 10, 1, 1, 0x26, 0x666666}, {
455         26000, 11, 1, 1, 0x24, 0xEC4EC4}, {
456         30000, 12, 1, 1, 0x20, 0x0}, {
457         37400, 13, 2, 1, 0x33, 0x563EF9}, {
458         38400, 14, 2, 1, 0x32, 0x0}, {
459         40000, 15, 2, 1, 0x30, 0x0}, {
460         48000, 16, 2, 1, 0x28, 0x0}, {
461         0, 0, 0, 0, 0, 0}
462 };
463
464 static const pmu1_xtaltab0_t pmu1_xtaltab0_880_4329[] = {
465         {
466         12000, 1, 3, 22, 0x9, 0xFFFFEF}, {
467         13000, 2, 1, 6, 0xb, 0x483483}, {
468         14400, 3, 1, 10, 0xa, 0x1C71C7}, {
469         15360, 4, 1, 5, 0xb, 0x755555}, {
470         16200, 5, 1, 10, 0x5, 0x6E9E06}, {
471         16800, 6, 1, 10, 0x5, 0x3Cf3Cf}, {
472         19200, 7, 1, 4, 0xb, 0x755555}, {
473         19800, 8, 1, 11, 0x4, 0xA57EB}, {
474         20000, 9, 1, 11, 0x4, 0x0}, {
475         24000, 10, 3, 11, 0xa, 0x0}, {
476         25000, 11, 5, 16, 0xb, 0x0}, {
477         26000, 12, 1, 1, 0x21, 0xD89D89}, {
478         30000, 13, 3, 8, 0xb, 0x0}, {
479         37400, 14, 3, 1, 0x46, 0x969696}, {
480         38400, 15, 1, 1, 0x16, 0xEAAAAA}, {
481         40000, 16, 1, 2, 0xb, 0}, {
482         0, 0, 0, 0, 0, 0}
483 };
484
485 /* the following table is based on 880Mhz fvco */
486 static const pmu1_xtaltab0_t pmu1_xtaltab0_880[] = {
487         {
488         12000, 1, 3, 22, 0x9, 0xFFFFEF}, {
489         13000, 2, 1, 6, 0xb, 0x483483}, {
490         14400, 3, 1, 10, 0xa, 0x1C71C7}, {
491         15360, 4, 1, 5, 0xb, 0x755555}, {
492         16200, 5, 1, 10, 0x5, 0x6E9E06}, {
493         16800, 6, 1, 10, 0x5, 0x3Cf3Cf}, {
494         19200, 7, 1, 4, 0xb, 0x755555}, {
495         19800, 8, 1, 11, 0x4, 0xA57EB}, {
496         20000, 9, 1, 11, 0x4, 0x0}, {
497         24000, 10, 3, 11, 0xa, 0x0}, {
498         25000, 11, 5, 16, 0xb, 0x0}, {
499         26000, 12, 1, 2, 0x10, 0xEC4EC4}, {
500         30000, 13, 3, 8, 0xb, 0x0}, {
501         33600, 14, 1, 2, 0xd, 0x186186}, {
502         38400, 15, 1, 2, 0xb, 0x755555}, {
503         40000, 16, 1, 2, 0xb, 0}, {
504         0, 0, 0, 0, 0, 0}
505 };
506
507 /* true if the power topology uses the buck boost to provide 3.3V to VDDIO_RF and WLAN PA */
508 static bool si_pmu_res_depfltr_bb(si_t *sih)
509 {
510         return (sih->boardflags & BFL_BUCKBOOST) != 0;
511 }
512
513 /* true if the power topology doesn't use the cbuck. Key on chiprev also if the chip is BCM4325. */
514 static bool si_pmu_res_depfltr_ncb(si_t *sih)
515 {
516
517         return (sih->boardflags & BFL_NOCBUCK) != 0;
518 }
519
520 /* true if the power topology uses the PALDO */
521 static bool si_pmu_res_depfltr_paldo(si_t *sih)
522 {
523         return (sih->boardflags & BFL_PALDO) != 0;
524 }
525
526 /* true if the power topology doesn't use the PALDO */
527 static bool si_pmu_res_depfltr_npaldo(si_t *sih)
528 {
529         return (sih->boardflags & BFL_PALDO) == 0;
530 }
531
532 /* Return dependancies (direct or all/indirect) for the given resources */
533 static u32
534 si_pmu_res_deps(si_t *sih, chipcregs_t *cc, u32 rsrcs,
535                 bool all)
536 {
537         u32 deps = 0;
538         u32 i;
539
540         for (i = 0; i <= PMURES_MAX_RESNUM; i++) {
541                 if (!(rsrcs & PMURES_BIT(i)))
542                         continue;
543                 W_REG(&cc->res_table_sel, i);
544                 deps |= R_REG(&cc->res_dep_mask);
545         }
546
547         return !all ? deps : (deps
548                               ? (deps |
549                                  si_pmu_res_deps(sih, cc, deps,
550                                                  true)) : 0);
551 }
552
553 /* Determine min/max rsrc masks. Value 0 leaves hardware at default. */
554 static void si_pmu_res_masks(si_t *sih, u32 * pmin, u32 * pmax)
555 {
556         u32 min_mask = 0, max_mask = 0;
557         uint rsrcs;
558         char *val;
559
560         /* # resources */
561         rsrcs = (sih->pmucaps & PCAP_RC_MASK) >> PCAP_RC_SHIFT;
562
563         /* determine min/max rsrc masks */
564         switch (sih->chip) {
565         case BCM43224_CHIP_ID:
566         case BCM43225_CHIP_ID:
567         case BCM43421_CHIP_ID:
568         case BCM43235_CHIP_ID:
569         case BCM43236_CHIP_ID:
570         case BCM43238_CHIP_ID:
571         case BCM4331_CHIP_ID:
572         case BCM6362_CHIP_ID:
573                 /* ??? */
574                 break;
575
576         case BCM4329_CHIP_ID:
577                 /* 4329 spedific issue. Needs to come back this issue later */
578                 /* Down to save the power. */
579                 min_mask =
580                     PMURES_BIT(RES4329_CBUCK_LPOM) |
581                     PMURES_BIT(RES4329_CLDO_PU);
582                 /* Allow (but don't require) PLL to turn on */
583                 max_mask = 0x3ff63e;
584                 break;
585         case BCM4319_CHIP_ID:
586                 /* We only need a few resources to be kept on all the time */
587                 min_mask = PMURES_BIT(RES4319_CBUCK_LPOM) |
588                     PMURES_BIT(RES4319_CLDO_PU);
589
590                 /* Allow everything else to be turned on upon requests */
591                 max_mask = ~(~0 << rsrcs);
592                 break;
593         case BCM4336_CHIP_ID:
594                 /* Down to save the power. */
595                 min_mask =
596                     PMURES_BIT(RES4336_CBUCK_LPOM) | PMURES_BIT(RES4336_CLDO_PU)
597                     | PMURES_BIT(RES4336_LDO3P3_PU) | PMURES_BIT(RES4336_OTP_PU)
598                     | PMURES_BIT(RES4336_DIS_INT_RESET_PD);
599                 /* Allow (but don't require) PLL to turn on */
600                 max_mask = 0x1ffffff;
601                 break;
602
603         case BCM4330_CHIP_ID:
604                 /* Down to save the power. */
605                 min_mask =
606                     PMURES_BIT(RES4330_CBUCK_LPOM) | PMURES_BIT(RES4330_CLDO_PU)
607                     | PMURES_BIT(RES4330_DIS_INT_RESET_PD) |
608                     PMURES_BIT(RES4330_LDO3P3_PU) | PMURES_BIT(RES4330_OTP_PU);
609                 /* Allow (but don't require) PLL to turn on */
610                 max_mask = 0xfffffff;
611                 break;
612
613         case BCM4313_CHIP_ID:
614                 min_mask = PMURES_BIT(RES4313_BB_PU_RSRC) |
615                     PMURES_BIT(RES4313_XTAL_PU_RSRC) |
616                     PMURES_BIT(RES4313_ALP_AVAIL_RSRC) |
617                     PMURES_BIT(RES4313_BB_PLL_PWRSW_RSRC);
618                 max_mask = 0xffff;
619                 break;
620         default:
621                 break;
622         }
623
624         /* Apply nvram override to min mask */
625         val = getvar(NULL, "rmin");
626         if (val != NULL) {
627                 min_mask = (u32) simple_strtoul(val, NULL, 0);
628         }
629         /* Apply nvram override to max mask */
630         val = getvar(NULL, "rmax");
631         if (val != NULL) {
632                 max_mask = (u32) simple_strtoul(val, NULL, 0);
633         }
634
635         *pmin = min_mask;
636         *pmax = max_mask;
637 }
638
639 /* Return up time in ILP cycles for the given resource. */
640 static uint
641 si_pmu_res_uptime(si_t *sih, chipcregs_t *cc, u8 rsrc) {
642         u32 deps;
643         uint up, i, dup, dmax;
644         u32 min_mask = 0, max_mask = 0;
645
646         /* uptime of resource 'rsrc' */
647         W_REG(&cc->res_table_sel, rsrc);
648         up = (R_REG(&cc->res_updn_timer) >> 8) & 0xff;
649
650         /* direct dependancies of resource 'rsrc' */
651         deps = si_pmu_res_deps(sih, cc, PMURES_BIT(rsrc), false);
652         for (i = 0; i <= PMURES_MAX_RESNUM; i++) {
653                 if (!(deps & PMURES_BIT(i)))
654                         continue;
655                 deps &= ~si_pmu_res_deps(sih, cc, PMURES_BIT(i), true);
656         }
657         si_pmu_res_masks(sih, &min_mask, &max_mask);
658         deps &= ~min_mask;
659
660         /* max uptime of direct dependancies */
661         dmax = 0;
662         for (i = 0; i <= PMURES_MAX_RESNUM; i++) {
663                 if (!(deps & PMURES_BIT(i)))
664                         continue;
665                 dup = si_pmu_res_uptime(sih, cc, (u8) i);
666                 if (dmax < dup)
667                         dmax = dup;
668         }
669
670         return up + dmax + PMURES_UP_TRANSITION;
671 }
672
673 static void
674 si_pmu_spuravoid_pllupdate(si_t *sih, chipcregs_t *cc, u8 spuravoid)
675 {
676         u32 tmp = 0;
677         u8 phypll_offset = 0;
678         u8 bcm5357_bcm43236_p1div[] = { 0x1, 0x5, 0x5 };
679         u8 bcm5357_bcm43236_ndiv[] = { 0x30, 0xf6, 0xfc };
680
681         switch (sih->chip) {
682         case BCM5357_CHIP_ID:
683         case BCM43235_CHIP_ID:
684         case BCM43236_CHIP_ID:
685         case BCM43238_CHIP_ID:
686
687                 /*
688                  * BCM5357 needs to touch PLL1_PLLCTL[02],
689                  * so offset PLL0_PLLCTL[02] by 6
690                  */
691                 phypll_offset = (sih->chip == BCM5357_CHIP_ID) ? 6 : 0;
692
693                 /* RMW only the P1 divider */
694                 W_REG(&cc->pllcontrol_addr,
695                       PMU1_PLL0_PLLCTL0 + phypll_offset);
696                 tmp = R_REG(&cc->pllcontrol_data);
697                 tmp &= (~(PMU1_PLL0_PC0_P1DIV_MASK));
698                 tmp |=
699                     (bcm5357_bcm43236_p1div[spuravoid] <<
700                      PMU1_PLL0_PC0_P1DIV_SHIFT);
701                 W_REG(&cc->pllcontrol_data, tmp);
702
703                 /* RMW only the int feedback divider */
704                 W_REG(&cc->pllcontrol_addr,
705                       PMU1_PLL0_PLLCTL2 + phypll_offset);
706                 tmp = R_REG(&cc->pllcontrol_data);
707                 tmp &= ~(PMU1_PLL0_PC2_NDIV_INT_MASK);
708                 tmp |=
709                     (bcm5357_bcm43236_ndiv[spuravoid]) <<
710                     PMU1_PLL0_PC2_NDIV_INT_SHIFT;
711                 W_REG(&cc->pllcontrol_data, tmp);
712
713                 tmp = 1 << 10;
714                 break;
715
716         case BCM4331_CHIP_ID:
717                 if (spuravoid == 2) {
718                         W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0);
719                         W_REG(&cc->pllcontrol_data, 0x11500014);
720                         W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2);
721                         W_REG(&cc->pllcontrol_data, 0x0FC00a08);
722                 } else if (spuravoid == 1) {
723                         W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0);
724                         W_REG(&cc->pllcontrol_data, 0x11500014);
725                         W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2);
726                         W_REG(&cc->pllcontrol_data, 0x0F600a08);
727                 } else {
728                         W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0);
729                         W_REG(&cc->pllcontrol_data, 0x11100014);
730                         W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2);
731                         W_REG(&cc->pllcontrol_data, 0x03000a08);
732                 }
733                 tmp = 1 << 10;
734                 break;
735
736         case BCM43224_CHIP_ID:
737         case BCM43225_CHIP_ID:
738         case BCM43421_CHIP_ID:
739         case BCM6362_CHIP_ID:
740                 if (spuravoid == 1) {
741                         W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0);
742                         W_REG(&cc->pllcontrol_data, 0x11500010);
743                         W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1);
744                         W_REG(&cc->pllcontrol_data, 0x000C0C06);
745                         W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2);
746                         W_REG(&cc->pllcontrol_data, 0x0F600a08);
747                         W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3);
748                         W_REG(&cc->pllcontrol_data, 0x00000000);
749                         W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4);
750                         W_REG(&cc->pllcontrol_data, 0x2001E920);
751                         W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5);
752                         W_REG(&cc->pllcontrol_data, 0x88888815);
753                 } else {
754                         W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0);
755                         W_REG(&cc->pllcontrol_data, 0x11100010);
756                         W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1);
757                         W_REG(&cc->pllcontrol_data, 0x000c0c06);
758                         W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2);
759                         W_REG(&cc->pllcontrol_data, 0x03000a08);
760                         W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3);
761                         W_REG(&cc->pllcontrol_data, 0x00000000);
762                         W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4);
763                         W_REG(&cc->pllcontrol_data, 0x200005c0);
764                         W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5);
765                         W_REG(&cc->pllcontrol_data, 0x88888815);
766                 }
767                 tmp = 1 << 10;
768                 break;
769
770                 W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0);
771                 W_REG(&cc->pllcontrol_data, 0x11100008);
772                 W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1);
773                 W_REG(&cc->pllcontrol_data, 0x0c000c06);
774                 W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2);
775                 W_REG(&cc->pllcontrol_data, 0x03000a08);
776                 W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3);
777                 W_REG(&cc->pllcontrol_data, 0x00000000);
778                 W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4);
779                 W_REG(&cc->pllcontrol_data, 0x200005c0);
780                 W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5);
781                 W_REG(&cc->pllcontrol_data, 0x88888855);
782
783                 tmp = 1 << 10;
784                 break;
785
786         case BCM4716_CHIP_ID:
787         case BCM4748_CHIP_ID:
788         case BCM47162_CHIP_ID:
789                 if (spuravoid == 1) {
790                         W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0);
791                         W_REG(&cc->pllcontrol_data, 0x11500060);
792                         W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1);
793                         W_REG(&cc->pllcontrol_data, 0x080C0C06);
794                         W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2);
795                         W_REG(&cc->pllcontrol_data, 0x0F600000);
796                         W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3);
797                         W_REG(&cc->pllcontrol_data, 0x00000000);
798                         W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4);
799                         W_REG(&cc->pllcontrol_data, 0x2001E924);
800                         W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5);
801                         W_REG(&cc->pllcontrol_data, 0x88888815);
802                 } else {
803                         W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0);
804                         W_REG(&cc->pllcontrol_data, 0x11100060);
805                         W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1);
806                         W_REG(&cc->pllcontrol_data, 0x080c0c06);
807                         W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2);
808                         W_REG(&cc->pllcontrol_data, 0x03000000);
809                         W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3);
810                         W_REG(&cc->pllcontrol_data, 0x00000000);
811                         W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4);
812                         W_REG(&cc->pllcontrol_data, 0x200005c0);
813                         W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5);
814                         W_REG(&cc->pllcontrol_data, 0x88888815);
815                 }
816
817                 tmp = 3 << 9;
818                 break;
819
820         case BCM4319_CHIP_ID:
821                 W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0);
822                 W_REG(&cc->pllcontrol_data, 0x11100070);
823                 W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1);
824                 W_REG(&cc->pllcontrol_data, 0x1014140a);
825                 W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5);
826                 W_REG(&cc->pllcontrol_data, 0x88888854);
827
828                 if (spuravoid == 1) {
829                         /* spur_avoid ON, so enable 41/82/164Mhz clock mode */
830                         W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2);
831                         W_REG(&cc->pllcontrol_data, 0x05201828);
832                 } else {
833                         /* enable 40/80/160Mhz clock mode */
834                         W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2);
835                         W_REG(&cc->pllcontrol_data, 0x05001828);
836                 }
837                 break;
838         case BCM4336_CHIP_ID:
839                 /* Looks like these are only for default xtal freq 26MHz */
840                 W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0);
841                 W_REG(&cc->pllcontrol_data, 0x02100020);
842
843                 W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1);
844                 W_REG(&cc->pllcontrol_data, 0x0C0C0C0C);
845
846                 W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2);
847                 W_REG(&cc->pllcontrol_data, 0x01240C0C);
848
849                 W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4);
850                 W_REG(&cc->pllcontrol_data, 0x202C2820);
851
852                 W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5);
853                 W_REG(&cc->pllcontrol_data, 0x88888825);
854
855                 W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3);
856                 if (spuravoid == 1)
857                         W_REG(&cc->pllcontrol_data, 0x00EC4EC4);
858                 else
859                         W_REG(&cc->pllcontrol_data, 0x00762762);
860
861                 tmp = PCTL_PLL_PLLCTL_UPD;
862                 break;
863
864         default:
865                 /* bail out */
866                 return;
867         }
868
869         tmp |= R_REG(&cc->pmucontrol);
870         W_REG(&cc->pmucontrol, tmp);
871 }
872
873 /* select default xtal frequency for each chip */
874 static const pmu1_xtaltab0_t *si_pmu1_xtaldef0(si_t *sih)
875 {
876         switch (sih->chip) {
877         case BCM4329_CHIP_ID:
878                 /* Default to 38400Khz */
879                 return &pmu1_xtaltab0_880_4329[PMU1_XTALTAB0_880_38400K];
880         case BCM4319_CHIP_ID:
881                 /* Default to 30000Khz */
882                 return &pmu1_xtaltab0_1440[PMU1_XTALTAB0_1440_30000K];
883         case BCM4336_CHIP_ID:
884                 /* Default to 26000Khz */
885                 return &pmu1_xtaltab0_960[PMU1_XTALTAB0_960_26000K];
886         case BCM4330_CHIP_ID:
887                 /* Default to 37400Khz */
888                 if (CST4330_CHIPMODE_SDIOD(sih->chipst))
889                         return &pmu1_xtaltab0_960[PMU1_XTALTAB0_960_37400K];
890                 else
891                         return &pmu1_xtaltab0_1440[PMU1_XTALTAB0_1440_37400K];
892         default:
893                 break;
894         }
895         return NULL;
896 }
897
898 /* select xtal table for each chip */
899 static const pmu1_xtaltab0_t *si_pmu1_xtaltab0(si_t *sih)
900 {
901         switch (sih->chip) {
902         case BCM4329_CHIP_ID:
903                 return pmu1_xtaltab0_880_4329;
904         case BCM4319_CHIP_ID:
905                 return pmu1_xtaltab0_1440;
906         case BCM4336_CHIP_ID:
907                 return pmu1_xtaltab0_960;
908         case BCM4330_CHIP_ID:
909                 if (CST4330_CHIPMODE_SDIOD(sih->chipst))
910                         return pmu1_xtaltab0_960;
911                 else
912                         return pmu1_xtaltab0_1440;
913         default:
914                 break;
915         }
916         return NULL;
917 }
918
919 /* query alp/xtal clock frequency */
920 static u32
921 si_pmu1_alpclk0(si_t *sih, chipcregs_t *cc)
922 {
923         const pmu1_xtaltab0_t *xt;
924         u32 xf;
925
926         /* Find the frequency in the table */
927         xf = (R_REG(&cc->pmucontrol) & PCTL_XTALFREQ_MASK) >>
928             PCTL_XTALFREQ_SHIFT;
929         for (xt = si_pmu1_xtaltab0(sih); xt != NULL && xt->fref != 0; xt++)
930                 if (xt->xf == xf)
931                         break;
932         /* Could not find it so assign a default value */
933         if (xt == NULL || xt->fref == 0)
934                 xt = si_pmu1_xtaldef0(sih);
935         return xt->fref * 1000;
936 }
937
938 /* select default pll fvco for each chip */
939 static u32 si_pmu1_pllfvco0(si_t *sih)
940 {
941         switch (sih->chip) {
942         case BCM4329_CHIP_ID:
943                 return FVCO_880;
944         case BCM4319_CHIP_ID:
945                 return FVCO_1440;
946         case BCM4336_CHIP_ID:
947                 return FVCO_960;
948         case BCM4330_CHIP_ID:
949                 if (CST4330_CHIPMODE_SDIOD(sih->chipst))
950                         return FVCO_960;
951                 else
952                         return FVCO_1440;
953         default:
954                 break;
955         }
956         return 0;
957 }
958
959 static void si_pmu_set_4330_plldivs(si_t *sih)
960 {
961         u32 FVCO = si_pmu1_pllfvco0(sih) / 1000;
962         u32 m1div, m2div, m3div, m4div, m5div, m6div;
963         u32 pllc1, pllc2;
964
965         m2div = m3div = m4div = m6div = FVCO / 80;
966         m5div = FVCO / 160;
967
968         if (CST4330_CHIPMODE_SDIOD(sih->chipst))
969                 m1div = FVCO / 80;
970         else
971                 m1div = FVCO / 90;
972         pllc1 =
973             (m1div << PMU1_PLL0_PC1_M1DIV_SHIFT) | (m2div <<
974                                                     PMU1_PLL0_PC1_M2DIV_SHIFT) |
975             (m3div << PMU1_PLL0_PC1_M3DIV_SHIFT) | (m4div <<
976                                                     PMU1_PLL0_PC1_M4DIV_SHIFT);
977         si_pmu_pllcontrol(sih, PMU1_PLL0_PLLCTL1, ~0, pllc1);
978
979         pllc2 = si_pmu_pllcontrol(sih, PMU1_PLL0_PLLCTL1, 0, 0);
980         pllc2 &= ~(PMU1_PLL0_PC2_M5DIV_MASK | PMU1_PLL0_PC2_M6DIV_MASK);
981         pllc2 |=
982             ((m5div << PMU1_PLL0_PC2_M5DIV_SHIFT) |
983              (m6div << PMU1_PLL0_PC2_M6DIV_SHIFT));
984         si_pmu_pllcontrol(sih, PMU1_PLL0_PLLCTL2, ~0, pllc2);
985 }
986
987 /* Set up PLL registers in the PMU as per the crystal speed.
988  * XtalFreq field in pmucontrol register being 0 indicates the PLL
989  * is not programmed and the h/w default is assumed to work, in which
990  * case the xtal frequency is unknown to the s/w so we need to call
991  * si_pmu1_xtaldef0() wherever it is needed to return a default value.
992  */
993 static void si_pmu1_pllinit0(si_t *sih, chipcregs_t *cc, u32 xtal)
994 {
995         const pmu1_xtaltab0_t *xt;
996         u32 tmp;
997         u32 buf_strength = 0;
998         u8 ndiv_mode = 1;
999
1000         /* Use h/w default PLL config */
1001         if (xtal == 0) {
1002                 return;
1003         }
1004
1005         /* Find the frequency in the table */
1006         for (xt = si_pmu1_xtaltab0(sih); xt != NULL && xt->fref != 0; xt++)
1007                 if (xt->fref == xtal)
1008                         break;
1009
1010         /* Check current PLL state, bail out if it has been programmed or
1011          * we don't know how to program it.
1012          */
1013         if (xt == NULL || xt->fref == 0) {
1014                 return;
1015         }
1016         /* for 4319 bootloader already programs the PLL but bootloader does not
1017          * program the PLL4 and PLL5. So Skip this check for 4319
1018          */
1019         if ((((R_REG(&cc->pmucontrol) & PCTL_XTALFREQ_MASK) >>
1020               PCTL_XTALFREQ_SHIFT) == xt->xf) &&
1021             !((sih->chip == BCM4319_CHIP_ID)
1022               || (sih->chip == BCM4330_CHIP_ID)))
1023                 return;
1024
1025         switch (sih->chip) {
1026         case BCM4329_CHIP_ID:
1027                 /* Change the BBPLL drive strength to 8 for all channels */
1028                 buf_strength = 0x888888;
1029                 AND_REG(&cc->min_res_mask,
1030                         ~(PMURES_BIT(RES4329_BBPLL_PWRSW_PU) |
1031                           PMURES_BIT(RES4329_HT_AVAIL)));
1032                 AND_REG(&cc->max_res_mask,
1033                         ~(PMURES_BIT(RES4329_BBPLL_PWRSW_PU) |
1034                           PMURES_BIT(RES4329_HT_AVAIL)));
1035                 SPINWAIT(R_REG(&cc->clk_ctl_st) & CCS_HTAVAIL,
1036                          PMU_MAX_TRANSITION_DLY);
1037                 W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4);
1038                 if (xt->fref == 38400)
1039                         tmp = 0x200024C0;
1040                 else if (xt->fref == 37400)
1041                         tmp = 0x20004500;
1042                 else if (xt->fref == 26000)
1043                         tmp = 0x200024C0;
1044                 else
1045                         tmp = 0x200005C0;       /* Chip Dflt Settings */
1046                 W_REG(&cc->pllcontrol_data, tmp);
1047                 W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5);
1048                 tmp =
1049                     R_REG(&cc->pllcontrol_data) & PMU1_PLL0_PC5_CLK_DRV_MASK;
1050                 if ((xt->fref == 38400) || (xt->fref == 37400)
1051                     || (xt->fref == 26000))
1052                         tmp |= 0x15;
1053                 else
1054                         tmp |= 0x25;    /* Chip Dflt Settings */
1055                 W_REG(&cc->pllcontrol_data, tmp);
1056                 break;
1057
1058         case BCM4319_CHIP_ID:
1059                 /* Change the BBPLL drive strength to 2 for all channels */
1060                 buf_strength = 0x222222;
1061
1062                 /* Make sure the PLL is off */
1063                 /* WAR65104: Disable the HT_AVAIL resource first and then
1064                  * after a delay (more than downtime for HT_AVAIL) remove the
1065                  * BBPLL resource; backplane clock moves to ALP from HT.
1066                  */
1067                 AND_REG(&cc->min_res_mask,
1068                         ~(PMURES_BIT(RES4319_HT_AVAIL)));
1069                 AND_REG(&cc->max_res_mask,
1070                         ~(PMURES_BIT(RES4319_HT_AVAIL)));
1071
1072                 udelay(100);
1073                 AND_REG(&cc->min_res_mask,
1074                         ~(PMURES_BIT(RES4319_BBPLL_PWRSW_PU)));
1075                 AND_REG(&cc->max_res_mask,
1076                         ~(PMURES_BIT(RES4319_BBPLL_PWRSW_PU)));
1077
1078                 udelay(100);
1079                 SPINWAIT(R_REG(&cc->clk_ctl_st) & CCS_HTAVAIL,
1080                          PMU_MAX_TRANSITION_DLY);
1081                 W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4);
1082                 tmp = 0x200005c0;
1083                 W_REG(&cc->pllcontrol_data, tmp);
1084                 break;
1085
1086         case BCM4336_CHIP_ID:
1087                 AND_REG(&cc->min_res_mask,
1088                         ~(PMURES_BIT(RES4336_HT_AVAIL) |
1089                           PMURES_BIT(RES4336_MACPHY_CLKAVAIL)));
1090                 AND_REG(&cc->max_res_mask,
1091                         ~(PMURES_BIT(RES4336_HT_AVAIL) |
1092                           PMURES_BIT(RES4336_MACPHY_CLKAVAIL)));
1093                 udelay(100);
1094                 SPINWAIT(R_REG(&cc->clk_ctl_st) & CCS_HTAVAIL,
1095                          PMU_MAX_TRANSITION_DLY);
1096                 break;
1097
1098         case BCM4330_CHIP_ID:
1099                 AND_REG(&cc->min_res_mask,
1100                         ~(PMURES_BIT(RES4330_HT_AVAIL) |
1101                           PMURES_BIT(RES4330_MACPHY_CLKAVAIL)));
1102                 AND_REG(&cc->max_res_mask,
1103                         ~(PMURES_BIT(RES4330_HT_AVAIL) |
1104                           PMURES_BIT(RES4330_MACPHY_CLKAVAIL)));
1105                 udelay(100);
1106                 SPINWAIT(R_REG(&cc->clk_ctl_st) & CCS_HTAVAIL,
1107                          PMU_MAX_TRANSITION_DLY);
1108                 break;
1109
1110         default:
1111                 break;
1112         }
1113
1114         /* Write p1div and p2div to pllcontrol[0] */
1115         W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0);
1116         tmp = R_REG(&cc->pllcontrol_data) &
1117             ~(PMU1_PLL0_PC0_P1DIV_MASK | PMU1_PLL0_PC0_P2DIV_MASK);
1118         tmp |=
1119             ((xt->
1120               p1div << PMU1_PLL0_PC0_P1DIV_SHIFT) & PMU1_PLL0_PC0_P1DIV_MASK) |
1121             ((xt->
1122               p2div << PMU1_PLL0_PC0_P2DIV_SHIFT) & PMU1_PLL0_PC0_P2DIV_MASK);
1123         W_REG(&cc->pllcontrol_data, tmp);
1124
1125         if ((sih->chip == BCM4330_CHIP_ID))
1126                 si_pmu_set_4330_plldivs(sih);
1127
1128         if ((sih->chip == BCM4329_CHIP_ID)
1129             && (sih->chiprev == 0)) {
1130
1131                 W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1);
1132                 tmp = R_REG(&cc->pllcontrol_data);
1133                 tmp = tmp & (~DOT11MAC_880MHZ_CLK_DIVISOR_MASK);
1134                 tmp = tmp | DOT11MAC_880MHZ_CLK_DIVISOR_VAL;
1135                 W_REG(&cc->pllcontrol_data, tmp);
1136         }
1137         if ((sih->chip == BCM4319_CHIP_ID) ||
1138             (sih->chip == BCM4336_CHIP_ID) ||
1139             (sih->chip == BCM4330_CHIP_ID))
1140                 ndiv_mode = PMU1_PLL0_PC2_NDIV_MODE_MFB;
1141         else
1142                 ndiv_mode = PMU1_PLL0_PC2_NDIV_MODE_MASH;
1143
1144         /* Write ndiv_int and ndiv_mode to pllcontrol[2] */
1145         W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2);
1146         tmp = R_REG(&cc->pllcontrol_data) &
1147             ~(PMU1_PLL0_PC2_NDIV_INT_MASK | PMU1_PLL0_PC2_NDIV_MODE_MASK);
1148         tmp |=
1149             ((xt->
1150               ndiv_int << PMU1_PLL0_PC2_NDIV_INT_SHIFT) &
1151              PMU1_PLL0_PC2_NDIV_INT_MASK) | ((ndiv_mode <<
1152                                               PMU1_PLL0_PC2_NDIV_MODE_SHIFT) &
1153                                              PMU1_PLL0_PC2_NDIV_MODE_MASK);
1154         W_REG(&cc->pllcontrol_data, tmp);
1155
1156         /* Write ndiv_frac to pllcontrol[3] */
1157         W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3);
1158         tmp = R_REG(&cc->pllcontrol_data) & ~PMU1_PLL0_PC3_NDIV_FRAC_MASK;
1159         tmp |= ((xt->ndiv_frac << PMU1_PLL0_PC3_NDIV_FRAC_SHIFT) &
1160                 PMU1_PLL0_PC3_NDIV_FRAC_MASK);
1161         W_REG(&cc->pllcontrol_data, tmp);
1162
1163         /* Write clock driving strength to pllcontrol[5] */
1164         if (buf_strength) {
1165                 W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5);
1166                 tmp =
1167                     R_REG(&cc->pllcontrol_data) & ~PMU1_PLL0_PC5_CLK_DRV_MASK;
1168                 tmp |= (buf_strength << PMU1_PLL0_PC5_CLK_DRV_SHIFT);
1169                 W_REG(&cc->pllcontrol_data, tmp);
1170         }
1171
1172         /* to operate the 4319 usb in 24MHz/48MHz; chipcontrol[2][84:83] needs
1173          * to be updated.
1174          */
1175         if ((sih->chip == BCM4319_CHIP_ID)
1176             && (xt->fref != XTAL_FREQ_30000MHZ)) {
1177                 W_REG(&cc->chipcontrol_addr, PMU1_PLL0_CHIPCTL2);
1178                 tmp =
1179                     R_REG(&cc->chipcontrol_data) & ~CCTL_4319USB_XTAL_SEL_MASK;
1180                 if (xt->fref == XTAL_FREQ_24000MHZ) {
1181                         tmp |=
1182                             (CCTL_4319USB_24MHZ_PLL_SEL <<
1183                              CCTL_4319USB_XTAL_SEL_SHIFT);
1184                 } else if (xt->fref == XTAL_FREQ_48000MHZ) {
1185                         tmp |=
1186                             (CCTL_4319USB_48MHZ_PLL_SEL <<
1187                              CCTL_4319USB_XTAL_SEL_SHIFT);
1188                 }
1189                 W_REG(&cc->chipcontrol_data, tmp);
1190         }
1191
1192         /* Flush deferred pll control registers writes */
1193         if (sih->pmurev >= 2)
1194                 OR_REG(&cc->pmucontrol, PCTL_PLL_PLLCTL_UPD);
1195
1196         /* Write XtalFreq. Set the divisor also. */
1197         tmp = R_REG(&cc->pmucontrol) &
1198             ~(PCTL_ILP_DIV_MASK | PCTL_XTALFREQ_MASK);
1199         tmp |= (((((xt->fref + 127) / 128) - 1) << PCTL_ILP_DIV_SHIFT) &
1200                 PCTL_ILP_DIV_MASK) |
1201             ((xt->xf << PCTL_XTALFREQ_SHIFT) & PCTL_XTALFREQ_MASK);
1202
1203         if ((sih->chip == BCM4329_CHIP_ID)
1204             && sih->chiprev == 0) {
1205                 /* clear the htstretch before clearing HTReqEn */
1206                 AND_REG(&cc->clkstretch, ~CSTRETCH_HT);
1207                 tmp &= ~PCTL_HT_REQ_EN;
1208         }
1209
1210         W_REG(&cc->pmucontrol, tmp);
1211 }
1212
1213 u32 si_pmu_ilp_clock(si_t *sih)
1214 {
1215         static u32 ilpcycles_per_sec;
1216
1217         if (ISSIM_ENAB(sih) || !PMUCTL_ENAB(sih))
1218                 return ILP_CLOCK;
1219
1220         if (ilpcycles_per_sec == 0) {
1221                 u32 start, end, delta;
1222                 u32 origidx = ai_coreidx(sih);
1223                 chipcregs_t *cc = ai_setcoreidx(sih, SI_CC_IDX);
1224                 start = R_REG(&cc->pmutimer);
1225                 mdelay(ILP_CALC_DUR);
1226                 end = R_REG(&cc->pmutimer);
1227                 delta = end - start;
1228                 ilpcycles_per_sec = delta * (1000 / ILP_CALC_DUR);
1229                 ai_setcoreidx(sih, origidx);
1230         }
1231
1232         return ilpcycles_per_sec;
1233 }
1234
1235 void si_pmu_set_ldo_voltage(si_t *sih, u8 ldo, u8 voltage)
1236 {
1237         u8 sr_cntl_shift = 0, rc_shift = 0, shift = 0, mask = 0;
1238         u8 addr = 0;
1239
1240         switch (sih->chip) {
1241         case BCM4336_CHIP_ID:
1242                 switch (ldo) {
1243                 case SET_LDO_VOLTAGE_CLDO_PWM:
1244                         addr = 4;
1245                         rc_shift = 1;
1246                         mask = 0xf;
1247                         break;
1248                 case SET_LDO_VOLTAGE_CLDO_BURST:
1249                         addr = 4;
1250                         rc_shift = 5;
1251                         mask = 0xf;
1252                         break;
1253                 case SET_LDO_VOLTAGE_LNLDO1:
1254                         addr = 4;
1255                         rc_shift = 17;
1256                         mask = 0xf;
1257                         break;
1258                 default:
1259                         return;
1260                 }
1261                 break;
1262         case BCM4330_CHIP_ID:
1263                 switch (ldo) {
1264                 case SET_LDO_VOLTAGE_CBUCK_PWM:
1265                         addr = 3;
1266                         rc_shift = 0;
1267                         mask = 0x1f;
1268                         break;
1269                 default:
1270                         return;
1271                 }
1272                 break;
1273         default:
1274                 return;
1275         }
1276
1277         shift = sr_cntl_shift + rc_shift;
1278
1279         ai_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, regcontrol_addr),
1280                    ~0, addr);
1281         ai_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, regcontrol_data),
1282                    mask << shift, (voltage & mask) << shift);
1283 }
1284
1285 u16 si_pmu_fast_pwrup_delay(si_t *sih)
1286 {
1287         uint delay = PMU_MAX_TRANSITION_DLY;
1288         chipcregs_t *cc;
1289         uint origidx;
1290 #ifdef BCMDBG
1291         char chn[8];
1292         chn[0] = 0;             /* to suppress compile error */
1293 #endif
1294
1295         /* Remember original core before switch to chipc */
1296         origidx = ai_coreidx(sih);
1297         cc = ai_setcoreidx(sih, SI_CC_IDX);
1298
1299         switch (sih->chip) {
1300         case BCM43224_CHIP_ID:
1301         case BCM43225_CHIP_ID:
1302         case BCM43421_CHIP_ID:
1303         case BCM43235_CHIP_ID:
1304         case BCM43236_CHIP_ID:
1305         case BCM43238_CHIP_ID:
1306         case BCM4331_CHIP_ID:
1307         case BCM6362_CHIP_ID:
1308         case BCM4313_CHIP_ID:
1309                 delay = ISSIM_ENAB(sih) ? 70 : 3700;
1310                 break;
1311         case BCM4329_CHIP_ID:
1312                 if (ISSIM_ENAB(sih))
1313                         delay = 70;
1314                 else {
1315                         u32 ilp = si_pmu_ilp_clock(sih);
1316                         delay =
1317                             (si_pmu_res_uptime(sih, cc, RES4329_HT_AVAIL) +
1318                              D11SCC_SLOW2FAST_TRANSITION) * ((1000000 + ilp -
1319                                                               1) / ilp);
1320                         delay = (11 * delay) / 10;
1321                 }
1322                 break;
1323         case BCM4319_CHIP_ID:
1324                 delay = ISSIM_ENAB(sih) ? 70 : 3700;
1325                 break;
1326         case BCM4336_CHIP_ID:
1327                 if (ISSIM_ENAB(sih))
1328                         delay = 70;
1329                 else {
1330                         u32 ilp = si_pmu_ilp_clock(sih);
1331                         delay =
1332                             (si_pmu_res_uptime(sih, cc, RES4336_HT_AVAIL) +
1333                              D11SCC_SLOW2FAST_TRANSITION) * ((1000000 + ilp -
1334                                                               1) / ilp);
1335                         delay = (11 * delay) / 10;
1336                 }
1337                 break;
1338         case BCM4330_CHIP_ID:
1339                 if (ISSIM_ENAB(sih))
1340                         delay = 70;
1341                 else {
1342                         u32 ilp = si_pmu_ilp_clock(sih);
1343                         delay =
1344                             (si_pmu_res_uptime(sih, cc, RES4330_HT_AVAIL) +
1345                              D11SCC_SLOW2FAST_TRANSITION) * ((1000000 + ilp -
1346                                                               1) / ilp);
1347                         delay = (11 * delay) / 10;
1348                 }
1349                 break;
1350         default:
1351                 break;
1352         }
1353         /* Return to original core */
1354         ai_setcoreidx(sih, origidx);
1355
1356         return (u16) delay;
1357 }
1358
1359 void si_pmu_sprom_enable(si_t *sih, bool enable)
1360 {
1361         chipcregs_t *cc;
1362         uint origidx;
1363
1364         /* Remember original core before switch to chipc */
1365         origidx = ai_coreidx(sih);
1366         cc = ai_setcoreidx(sih, SI_CC_IDX);
1367
1368         /* Return to original core */
1369         ai_setcoreidx(sih, origidx);
1370 }
1371
1372 /* Read/write a chipcontrol reg */
1373 u32 si_pmu_chipcontrol(si_t *sih, uint reg, u32 mask, u32 val)
1374 {
1375         ai_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, chipcontrol_addr), ~0,
1376                    reg);
1377         return ai_corereg(sih, SI_CC_IDX,
1378                           offsetof(chipcregs_t, chipcontrol_data), mask, val);
1379 }
1380
1381 /* Read/write a regcontrol reg */
1382 u32 si_pmu_regcontrol(si_t *sih, uint reg, u32 mask, u32 val)
1383 {
1384         ai_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, regcontrol_addr), ~0,
1385                    reg);
1386         return ai_corereg(sih, SI_CC_IDX,
1387                           offsetof(chipcregs_t, regcontrol_data), mask, val);
1388 }
1389
1390 /* Read/write a pllcontrol reg */
1391 u32 si_pmu_pllcontrol(si_t *sih, uint reg, u32 mask, u32 val)
1392 {
1393         ai_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, pllcontrol_addr), ~0,
1394                    reg);
1395         return ai_corereg(sih, SI_CC_IDX,
1396                           offsetof(chipcregs_t, pllcontrol_data), mask, val);
1397 }
1398
1399 /* PMU PLL update */
1400 void si_pmu_pllupd(si_t *sih)
1401 {
1402         ai_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, pmucontrol),
1403                    PCTL_PLL_PLLCTL_UPD, PCTL_PLL_PLLCTL_UPD);
1404 }
1405
1406 /* query alp/xtal clock frequency */
1407 u32 si_pmu_alp_clock(si_t *sih)
1408 {
1409         chipcregs_t *cc;
1410         uint origidx;
1411         u32 clock = ALP_CLOCK;
1412
1413         /* bail out with default */
1414         if (!PMUCTL_ENAB(sih))
1415                 return clock;
1416
1417         /* Remember original core before switch to chipc */
1418         origidx = ai_coreidx(sih);
1419         cc = ai_setcoreidx(sih, SI_CC_IDX);
1420
1421         switch (sih->chip) {
1422         case BCM43224_CHIP_ID:
1423         case BCM43225_CHIP_ID:
1424         case BCM43421_CHIP_ID:
1425         case BCM43235_CHIP_ID:
1426         case BCM43236_CHIP_ID:
1427         case BCM43238_CHIP_ID:
1428         case BCM4331_CHIP_ID:
1429         case BCM6362_CHIP_ID:
1430         case BCM4716_CHIP_ID:
1431         case BCM4748_CHIP_ID:
1432         case BCM47162_CHIP_ID:
1433         case BCM4313_CHIP_ID:
1434         case BCM5357_CHIP_ID:
1435                 /* always 20Mhz */
1436                 clock = 20000 * 1000;
1437                 break;
1438         case BCM4329_CHIP_ID:
1439         case BCM4319_CHIP_ID:
1440         case BCM4336_CHIP_ID:
1441         case BCM4330_CHIP_ID:
1442
1443                 clock = si_pmu1_alpclk0(sih, cc);
1444                 break;
1445         case BCM5356_CHIP_ID:
1446                 /* always 25Mhz */
1447                 clock = 25000 * 1000;
1448                 break;
1449         default:
1450                 break;
1451         }
1452
1453         /* Return to original core */
1454         ai_setcoreidx(sih, origidx);
1455         return clock;
1456 }
1457
1458 void si_pmu_spuravoid(si_t *sih, u8 spuravoid)
1459 {
1460         chipcregs_t *cc;
1461         uint origidx, intr_val;
1462         u32 tmp = 0;
1463
1464         /* Remember original core before switch to chipc */
1465         cc = (chipcregs_t *) ai_switch_core(sih, CC_CORE_ID, &origidx,
1466                                             &intr_val);
1467
1468         /* force the HT off  */
1469         if (sih->chip == BCM4336_CHIP_ID) {
1470                 tmp = R_REG(&cc->max_res_mask);
1471                 tmp &= ~RES4336_HT_AVAIL;
1472                 W_REG(&cc->max_res_mask, tmp);
1473                 /* wait for the ht to really go away */
1474                 SPINWAIT(((R_REG(&cc->clk_ctl_st) & CCS_HTAVAIL) == 0),
1475                          10000);
1476         }
1477
1478         /* update the pll changes */
1479         si_pmu_spuravoid_pllupdate(sih, cc, spuravoid);
1480
1481         /* enable HT back on  */
1482         if (sih->chip == BCM4336_CHIP_ID) {
1483                 tmp = R_REG(&cc->max_res_mask);
1484                 tmp |= RES4336_HT_AVAIL;
1485                 W_REG(&cc->max_res_mask, tmp);
1486         }
1487
1488         /* Return to original core */
1489         ai_restore_core(sih, origidx, intr_val);
1490 }
1491
1492 /* initialize PMU */
1493 void si_pmu_init(si_t *sih)
1494 {
1495         chipcregs_t *cc;
1496         uint origidx;
1497
1498         /* Remember original core before switch to chipc */
1499         origidx = ai_coreidx(sih);
1500         cc = ai_setcoreidx(sih, SI_CC_IDX);
1501
1502         if (sih->pmurev == 1)
1503                 AND_REG(&cc->pmucontrol, ~PCTL_NOILP_ON_WAIT);
1504         else if (sih->pmurev >= 2)
1505                 OR_REG(&cc->pmucontrol, PCTL_NOILP_ON_WAIT);
1506
1507         if ((sih->chip == BCM4329_CHIP_ID) && (sih->chiprev == 2)) {
1508                 /* Fix for 4329b0 bad LPOM state. */
1509                 W_REG(&cc->regcontrol_addr, 2);
1510                 OR_REG(&cc->regcontrol_data, 0x100);
1511
1512                 W_REG(&cc->regcontrol_addr, 3);
1513                 OR_REG(&cc->regcontrol_data, 0x4);
1514         }
1515
1516         /* Return to original core */
1517         ai_setcoreidx(sih, origidx);
1518 }
1519
1520 /* initialize PMU chip controls and other chip level stuff */
1521 void si_pmu_chip_init(si_t *sih)
1522 {
1523         uint origidx;
1524
1525         /* Gate off SPROM clock and chip select signals */
1526         si_pmu_sprom_enable(sih, false);
1527
1528         /* Remember original core */
1529         origidx = ai_coreidx(sih);
1530
1531         /* Return to original core */
1532         ai_setcoreidx(sih, origidx);
1533 }
1534
1535 /* initialize PMU switch/regulators */
1536 void si_pmu_swreg_init(si_t *sih)
1537 {
1538         switch (sih->chip) {
1539         case BCM4336_CHIP_ID:
1540                 /* Reduce CLDO PWM output voltage to 1.2V */
1541                 si_pmu_set_ldo_voltage(sih, SET_LDO_VOLTAGE_CLDO_PWM, 0xe);
1542                 /* Reduce CLDO BURST output voltage to 1.2V */
1543                 si_pmu_set_ldo_voltage(sih, SET_LDO_VOLTAGE_CLDO_BURST,
1544                                        0xe);
1545                 /* Reduce LNLDO1 output voltage to 1.2V */
1546                 si_pmu_set_ldo_voltage(sih, SET_LDO_VOLTAGE_LNLDO1, 0xe);
1547                 if (sih->chiprev == 0)
1548                         si_pmu_regcontrol(sih, 2, 0x400000, 0x400000);
1549                 break;
1550
1551         case BCM4330_CHIP_ID:
1552                 /* CBUCK Voltage is 1.8 by default and set that to 1.5 */
1553                 si_pmu_set_ldo_voltage(sih, SET_LDO_VOLTAGE_CBUCK_PWM, 0);
1554                 break;
1555         default:
1556                 break;
1557         }
1558 }
1559
1560 /* initialize PLL */
1561 void si_pmu_pll_init(si_t *sih, uint xtalfreq)
1562 {
1563         chipcregs_t *cc;
1564         uint origidx;
1565
1566         /* Remember original core before switch to chipc */
1567         origidx = ai_coreidx(sih);
1568         cc = ai_setcoreidx(sih, SI_CC_IDX);
1569
1570         switch (sih->chip) {
1571         case BCM4329_CHIP_ID:
1572                 if (xtalfreq == 0)
1573                         xtalfreq = 38400;
1574                 si_pmu1_pllinit0(sih, cc, xtalfreq);
1575                 break;
1576         case BCM4313_CHIP_ID:
1577         case BCM43224_CHIP_ID:
1578         case BCM43225_CHIP_ID:
1579         case BCM43421_CHIP_ID:
1580         case BCM43235_CHIP_ID:
1581         case BCM43236_CHIP_ID:
1582         case BCM43238_CHIP_ID:
1583         case BCM4331_CHIP_ID:
1584         case BCM6362_CHIP_ID:
1585                 /* ??? */
1586                 break;
1587         case BCM4319_CHIP_ID:
1588         case BCM4336_CHIP_ID:
1589         case BCM4330_CHIP_ID:
1590                 si_pmu1_pllinit0(sih, cc, xtalfreq);
1591                 break;
1592         default:
1593                 break;
1594         }
1595
1596         /* Return to original core */
1597         ai_setcoreidx(sih, origidx);
1598 }
1599
1600 /* initialize PMU resources */
1601 void si_pmu_res_init(si_t *sih)
1602 {
1603         chipcregs_t *cc;
1604         uint origidx;
1605         const pmu_res_updown_t *pmu_res_updown_table = NULL;
1606         uint pmu_res_updown_table_sz = 0;
1607         const pmu_res_depend_t *pmu_res_depend_table = NULL;
1608         uint pmu_res_depend_table_sz = 0;
1609         u32 min_mask = 0, max_mask = 0;
1610         char name[8], *val;
1611         uint i, rsrcs;
1612
1613         /* Remember original core before switch to chipc */
1614         origidx = ai_coreidx(sih);
1615         cc = ai_setcoreidx(sih, SI_CC_IDX);
1616
1617         switch (sih->chip) {
1618         case BCM4329_CHIP_ID:
1619                 /* Optimize resources up/down timers */
1620                 if (ISSIM_ENAB(sih)) {
1621                         pmu_res_updown_table = NULL;
1622                         pmu_res_updown_table_sz = 0;
1623                 } else {
1624                         pmu_res_updown_table = bcm4329_res_updown;
1625                         pmu_res_updown_table_sz =
1626                                 ARRAY_SIZE(bcm4329_res_updown);
1627                 }
1628                 /* Optimize resources dependencies */
1629                 pmu_res_depend_table = bcm4329_res_depend;
1630                 pmu_res_depend_table_sz = ARRAY_SIZE(bcm4329_res_depend);
1631                 break;
1632
1633         case BCM4319_CHIP_ID:
1634                 /* Optimize resources up/down timers */
1635                 if (ISSIM_ENAB(sih)) {
1636                         pmu_res_updown_table = bcm4319a0_res_updown_qt;
1637                         pmu_res_updown_table_sz =
1638                             ARRAY_SIZE(bcm4319a0_res_updown_qt);
1639                 } else {
1640                         pmu_res_updown_table = bcm4319a0_res_updown;
1641                         pmu_res_updown_table_sz =
1642                             ARRAY_SIZE(bcm4319a0_res_updown);
1643                 }
1644                 /* Optimize resources dependancies masks */
1645                 pmu_res_depend_table = bcm4319a0_res_depend;
1646                 pmu_res_depend_table_sz = ARRAY_SIZE(bcm4319a0_res_depend);
1647                 break;
1648
1649         case BCM4336_CHIP_ID:
1650                 /* Optimize resources up/down timers */
1651                 if (ISSIM_ENAB(sih)) {
1652                         pmu_res_updown_table = bcm4336a0_res_updown_qt;
1653                         pmu_res_updown_table_sz =
1654                             ARRAY_SIZE(bcm4336a0_res_updown_qt);
1655                 } else {
1656                         pmu_res_updown_table = bcm4336a0_res_updown;
1657                         pmu_res_updown_table_sz =
1658                             ARRAY_SIZE(bcm4336a0_res_updown);
1659                 }
1660                 /* Optimize resources dependancies masks */
1661                 pmu_res_depend_table = bcm4336a0_res_depend;
1662                 pmu_res_depend_table_sz = ARRAY_SIZE(bcm4336a0_res_depend);
1663                 break;
1664
1665         case BCM4330_CHIP_ID:
1666                 /* Optimize resources up/down timers */
1667                 if (ISSIM_ENAB(sih)) {
1668                         pmu_res_updown_table = bcm4330a0_res_updown_qt;
1669                         pmu_res_updown_table_sz =
1670                             ARRAY_SIZE(bcm4330a0_res_updown_qt);
1671                 } else {
1672                         pmu_res_updown_table = bcm4330a0_res_updown;
1673                         pmu_res_updown_table_sz =
1674                             ARRAY_SIZE(bcm4330a0_res_updown);
1675                 }
1676                 /* Optimize resources dependancies masks */
1677                 pmu_res_depend_table = bcm4330a0_res_depend;
1678                 pmu_res_depend_table_sz = ARRAY_SIZE(bcm4330a0_res_depend);
1679                 break;
1680
1681         default:
1682                 break;
1683         }
1684
1685         /* # resources */
1686         rsrcs = (sih->pmucaps & PCAP_RC_MASK) >> PCAP_RC_SHIFT;
1687
1688         /* Program up/down timers */
1689         while (pmu_res_updown_table_sz--) {
1690                 W_REG(&cc->res_table_sel,
1691                       pmu_res_updown_table[pmu_res_updown_table_sz].resnum);
1692                 W_REG(&cc->res_updn_timer,
1693                       pmu_res_updown_table[pmu_res_updown_table_sz].updown);
1694         }
1695         /* Apply nvram overrides to up/down timers */
1696         for (i = 0; i < rsrcs; i++) {
1697                 snprintf(name, sizeof(name), "r%dt", i);
1698                 val = getvar(NULL, name);
1699                 if (val == NULL)
1700                         continue;
1701                 W_REG(&cc->res_table_sel, (u32) i);
1702                 W_REG(&cc->res_updn_timer,
1703                       (u32) simple_strtoul(val, NULL, 0));
1704         }
1705
1706         /* Program resource dependencies table */
1707         while (pmu_res_depend_table_sz--) {
1708                 if (pmu_res_depend_table[pmu_res_depend_table_sz].filter != NULL
1709                     && !(pmu_res_depend_table[pmu_res_depend_table_sz].
1710                          filter) (sih))
1711                         continue;
1712                 for (i = 0; i < rsrcs; i++) {
1713                         if ((pmu_res_depend_table[pmu_res_depend_table_sz].
1714                              res_mask & PMURES_BIT(i)) == 0)
1715                                 continue;
1716                         W_REG(&cc->res_table_sel, i);
1717                         switch (pmu_res_depend_table[pmu_res_depend_table_sz].
1718                                 action) {
1719                         case RES_DEPEND_SET:
1720                                 W_REG(&cc->res_dep_mask,
1721                                       pmu_res_depend_table
1722                                       [pmu_res_depend_table_sz].depend_mask);
1723                                 break;
1724                         case RES_DEPEND_ADD:
1725                                 OR_REG(&cc->res_dep_mask,
1726                                        pmu_res_depend_table
1727                                        [pmu_res_depend_table_sz].depend_mask);
1728                                 break;
1729                         case RES_DEPEND_REMOVE:
1730                                 AND_REG(&cc->res_dep_mask,
1731                                         ~pmu_res_depend_table
1732                                         [pmu_res_depend_table_sz].depend_mask);
1733                                 break;
1734                         default:
1735                                 break;
1736                         }
1737                 }
1738         }
1739         /* Apply nvram overrides to dependancies masks */
1740         for (i = 0; i < rsrcs; i++) {
1741                 snprintf(name, sizeof(name), "r%dd", i);
1742                 val = getvar(NULL, name);
1743                 if (val == NULL)
1744                         continue;
1745                 W_REG(&cc->res_table_sel, (u32) i);
1746                 W_REG(&cc->res_dep_mask,
1747                       (u32) simple_strtoul(val, NULL, 0));
1748         }
1749
1750         /* Determine min/max rsrc masks */
1751         si_pmu_res_masks(sih, &min_mask, &max_mask);
1752
1753         /* It is required to program max_mask first and then min_mask */
1754
1755         /* Program max resource mask */
1756
1757         if (max_mask)
1758                 W_REG(&cc->max_res_mask, max_mask);
1759
1760         /* Program min resource mask */
1761
1762         if (min_mask)
1763                 W_REG(&cc->min_res_mask, min_mask);
1764
1765         /* Add some delay; allow resources to come up and settle. */
1766         mdelay(2);
1767
1768         /* Return to original core */
1769         ai_setcoreidx(sih, origidx);
1770 }
1771
1772 u32 si_pmu_measure_alpclk(si_t *sih)
1773 {
1774         chipcregs_t *cc;
1775         uint origidx;
1776         u32 alp_khz;
1777
1778         if (sih->pmurev < 10)
1779                 return 0;
1780
1781         /* Remember original core before switch to chipc */
1782         origidx = ai_coreidx(sih);
1783         cc = ai_setcoreidx(sih, SI_CC_IDX);
1784
1785         if (R_REG(&cc->pmustatus) & PST_EXTLPOAVAIL) {
1786                 u32 ilp_ctr, alp_hz;
1787
1788                 /*
1789                  * Enable the reg to measure the freq,
1790                  * in case it was disabled before
1791                  */
1792                 W_REG(&cc->pmu_xtalfreq,
1793                       1U << PMU_XTALFREQ_REG_MEASURE_SHIFT);
1794
1795                 /* Delay for well over 4 ILP clocks */
1796                 udelay(1000);
1797
1798                 /* Read the latched number of ALP ticks per 4 ILP ticks */
1799                 ilp_ctr =
1800                     R_REG(&cc->pmu_xtalfreq) & PMU_XTALFREQ_REG_ILPCTR_MASK;
1801
1802                 /*
1803                  * Turn off the PMU_XTALFREQ_REG_MEASURE_SHIFT
1804                  * bit to save power
1805                  */
1806                 W_REG(&cc->pmu_xtalfreq, 0);
1807
1808                 /* Calculate ALP frequency */
1809                 alp_hz = (ilp_ctr * EXT_ILP_HZ) / 4;
1810
1811                 /*
1812                  * Round to nearest 100KHz, and at
1813                  * the same time convert to KHz
1814                  */
1815                 alp_khz = (alp_hz + 50000) / 100000 * 100;
1816         } else
1817                 alp_khz = 0;
1818
1819         /* Return to original core */
1820         ai_setcoreidx(sih, origidx);
1821
1822         return alp_khz;
1823 }
1824
1825 bool si_pmu_is_otp_powered(si_t *sih)
1826 {
1827         uint idx;
1828         chipcregs_t *cc;
1829         bool st;
1830
1831         /* Remember original core before switch to chipc */
1832         idx = ai_coreidx(sih);
1833         cc = ai_setcoreidx(sih, SI_CC_IDX);
1834
1835         switch (sih->chip) {
1836         case BCM4329_CHIP_ID:
1837                 st = (R_REG(&cc->res_state) & PMURES_BIT(RES4329_OTP_PU))
1838                     != 0;
1839                 break;
1840         case BCM4319_CHIP_ID:
1841                 st = (R_REG(&cc->res_state) & PMURES_BIT(RES4319_OTP_PU))
1842                     != 0;
1843                 break;
1844         case BCM4336_CHIP_ID:
1845                 st = (R_REG(&cc->res_state) & PMURES_BIT(RES4336_OTP_PU))
1846                     != 0;
1847                 break;
1848         case BCM4330_CHIP_ID:
1849                 st = (R_REG(&cc->res_state) & PMURES_BIT(RES4330_OTP_PU))
1850                     != 0;
1851                 break;
1852
1853                 /* These chip doesn't use PMU bit to power up/down OTP. OTP always on.
1854                  * Use OTP_INIT command to reset/refresh state.
1855                  */
1856         case BCM43224_CHIP_ID:
1857         case BCM43225_CHIP_ID:
1858         case BCM43421_CHIP_ID:
1859         case BCM43236_CHIP_ID:
1860         case BCM43235_CHIP_ID:
1861         case BCM43238_CHIP_ID:
1862                 st = true;
1863                 break;
1864         default:
1865                 st = true;
1866                 break;
1867         }
1868
1869         /* Return to original core */
1870         ai_setcoreidx(sih, idx);
1871         return st;
1872 }
1873
1874 /* power up/down OTP through PMU resources */
1875 void si_pmu_otp_power(si_t *sih, bool on)
1876 {
1877         chipcregs_t *cc;
1878         uint origidx;
1879         u32 rsrcs = 0;  /* rsrcs to turn on/off OTP power */
1880
1881         /* Don't do anything if OTP is disabled */
1882         if (ai_is_otp_disabled(sih))
1883                 return;
1884
1885         /* Remember original core before switch to chipc */
1886         origidx = ai_coreidx(sih);
1887         cc = ai_setcoreidx(sih, SI_CC_IDX);
1888
1889         switch (sih->chip) {
1890         case BCM4329_CHIP_ID:
1891                 rsrcs = PMURES_BIT(RES4329_OTP_PU);
1892                 break;
1893         case BCM4319_CHIP_ID:
1894                 rsrcs = PMURES_BIT(RES4319_OTP_PU);
1895                 break;
1896         case BCM4336_CHIP_ID:
1897                 rsrcs = PMURES_BIT(RES4336_OTP_PU);
1898                 break;
1899         case BCM4330_CHIP_ID:
1900                 rsrcs = PMURES_BIT(RES4330_OTP_PU);
1901                 break;
1902         default:
1903                 break;
1904         }
1905
1906         if (rsrcs != 0) {
1907                 u32 otps;
1908
1909                 /* Figure out the dependancies (exclude min_res_mask) */
1910                 u32 deps = si_pmu_res_deps(sih, cc, rsrcs, true);
1911                 u32 min_mask = 0, max_mask = 0;
1912                 si_pmu_res_masks(sih, &min_mask, &max_mask);
1913                 deps &= ~min_mask;
1914                 /* Turn on/off the power */
1915                 if (on) {
1916                         OR_REG(&cc->min_res_mask, (rsrcs | deps));
1917                         SPINWAIT(!(R_REG(&cc->res_state) & rsrcs),
1918                                  PMU_MAX_TRANSITION_DLY);
1919                 } else {
1920                         AND_REG(&cc->min_res_mask, ~(rsrcs | deps));
1921                 }
1922
1923                 SPINWAIT((((otps = R_REG(&cc->otpstatus)) & OTPS_READY) !=
1924                           (on ? OTPS_READY : 0)), 100);
1925         }
1926
1927         /* Return to original core */
1928         ai_setcoreidx(sih, origidx);
1929 }