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