Merge branch 'upstream-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid
[platform/adaptation/renesas_rcar/renesas_kernel.git] / drivers / bcma / driver_chipcommon_pmu.c
1 /*
2  * Broadcom specific AMBA
3  * ChipCommon Power Management Unit driver
4  *
5  * Copyright 2009, Michael Buesch <m@bues.ch>
6  * Copyright 2007, 2011, Broadcom Corporation
7  * Copyright 2011, 2012, Hauke Mehrtens <hauke@hauke-m.de>
8  *
9  * Licensed under the GNU/GPL. See COPYING for details.
10  */
11
12 #include "bcma_private.h"
13 #include <linux/export.h>
14 #include <linux/bcma/bcma.h>
15
16 static u32 bcma_chipco_pll_read(struct bcma_drv_cc *cc, u32 offset)
17 {
18         bcma_cc_write32(cc, BCMA_CC_PLLCTL_ADDR, offset);
19         bcma_cc_read32(cc, BCMA_CC_PLLCTL_ADDR);
20         return bcma_cc_read32(cc, BCMA_CC_PLLCTL_DATA);
21 }
22
23 void bcma_chipco_pll_write(struct bcma_drv_cc *cc, u32 offset, u32 value)
24 {
25         bcma_cc_write32(cc, BCMA_CC_PLLCTL_ADDR, offset);
26         bcma_cc_read32(cc, BCMA_CC_PLLCTL_ADDR);
27         bcma_cc_write32(cc, BCMA_CC_PLLCTL_DATA, value);
28 }
29 EXPORT_SYMBOL_GPL(bcma_chipco_pll_write);
30
31 void bcma_chipco_pll_maskset(struct bcma_drv_cc *cc, u32 offset, u32 mask,
32                              u32 set)
33 {
34         bcma_cc_write32(cc, BCMA_CC_PLLCTL_ADDR, offset);
35         bcma_cc_read32(cc, BCMA_CC_PLLCTL_ADDR);
36         bcma_cc_maskset32(cc, BCMA_CC_PLLCTL_DATA, mask, set);
37 }
38 EXPORT_SYMBOL_GPL(bcma_chipco_pll_maskset);
39
40 void bcma_chipco_chipctl_maskset(struct bcma_drv_cc *cc,
41                                  u32 offset, u32 mask, u32 set)
42 {
43         bcma_cc_write32(cc, BCMA_CC_CHIPCTL_ADDR, offset);
44         bcma_cc_read32(cc, BCMA_CC_CHIPCTL_ADDR);
45         bcma_cc_maskset32(cc, BCMA_CC_CHIPCTL_DATA, mask, set);
46 }
47 EXPORT_SYMBOL_GPL(bcma_chipco_chipctl_maskset);
48
49 void bcma_chipco_regctl_maskset(struct bcma_drv_cc *cc, u32 offset, u32 mask,
50                                 u32 set)
51 {
52         bcma_cc_write32(cc, BCMA_CC_REGCTL_ADDR, offset);
53         bcma_cc_read32(cc, BCMA_CC_REGCTL_ADDR);
54         bcma_cc_maskset32(cc, BCMA_CC_REGCTL_DATA, mask, set);
55 }
56 EXPORT_SYMBOL_GPL(bcma_chipco_regctl_maskset);
57
58 static void bcma_pmu_resources_init(struct bcma_drv_cc *cc)
59 {
60         struct bcma_bus *bus = cc->core->bus;
61         u32 min_msk = 0, max_msk = 0;
62
63         switch (bus->chipinfo.id) {
64         case BCMA_CHIP_ID_BCM4313:
65                 min_msk = 0x200D;
66                 max_msk = 0xFFFF;
67                 break;
68         default:
69                 bcma_debug(bus, "PMU resource config unknown or not needed for device 0x%04X\n",
70                            bus->chipinfo.id);
71         }
72
73         /* Set the resource masks. */
74         if (min_msk)
75                 bcma_cc_write32(cc, BCMA_CC_PMU_MINRES_MSK, min_msk);
76         if (max_msk)
77                 bcma_cc_write32(cc, BCMA_CC_PMU_MAXRES_MSK, max_msk);
78
79         /* Add some delay; allow resources to come up and settle. */
80         mdelay(2);
81 }
82
83 /* Disable to allow reading SPROM. Don't know the adventages of enabling it. */
84 void bcma_chipco_bcm4331_ext_pa_lines_ctl(struct bcma_drv_cc *cc, bool enable)
85 {
86         struct bcma_bus *bus = cc->core->bus;
87         u32 val;
88
89         val = bcma_cc_read32(cc, BCMA_CC_CHIPCTL);
90         if (enable) {
91                 val |= BCMA_CHIPCTL_4331_EXTPA_EN;
92                 if (bus->chipinfo.pkg == 9 || bus->chipinfo.pkg == 11)
93                         val |= BCMA_CHIPCTL_4331_EXTPA_ON_GPIO2_5;
94                 else if (bus->chipinfo.rev > 0)
95                         val |= BCMA_CHIPCTL_4331_EXTPA_EN2;
96         } else {
97                 val &= ~BCMA_CHIPCTL_4331_EXTPA_EN;
98                 val &= ~BCMA_CHIPCTL_4331_EXTPA_EN2;
99                 val &= ~BCMA_CHIPCTL_4331_EXTPA_ON_GPIO2_5;
100         }
101         bcma_cc_write32(cc, BCMA_CC_CHIPCTL, val);
102 }
103
104 void bcma_pmu_workarounds(struct bcma_drv_cc *cc)
105 {
106         struct bcma_bus *bus = cc->core->bus;
107
108         switch (bus->chipinfo.id) {
109         case BCMA_CHIP_ID_BCM4313:
110                 /* enable 12 mA drive strenth for 4313 and set chipControl
111                    register bit 1 */
112                 bcma_chipco_chipctl_maskset(cc, 0,
113                                             ~BCMA_CCTRL_4313_12MA_LED_DRIVE,
114                                             BCMA_CCTRL_4313_12MA_LED_DRIVE);
115                 break;
116         case BCMA_CHIP_ID_BCM4331:
117         case BCMA_CHIP_ID_BCM43431:
118                 /* Ext PA lines must be enabled for tx on BCM4331 */
119                 bcma_chipco_bcm4331_ext_pa_lines_ctl(cc, true);
120                 break;
121         case BCMA_CHIP_ID_BCM43224:
122         case BCMA_CHIP_ID_BCM43421:
123                 /* enable 12 mA drive strenth for 43224 and set chipControl
124                    register bit 15 */
125                 if (bus->chipinfo.rev == 0) {
126                         bcma_cc_maskset32(cc, BCMA_CC_CHIPCTL,
127                                           ~BCMA_CCTRL_43224_GPIO_TOGGLE,
128                                           BCMA_CCTRL_43224_GPIO_TOGGLE);
129                         bcma_chipco_chipctl_maskset(cc, 0,
130                                                     ~BCMA_CCTRL_43224A0_12MA_LED_DRIVE,
131                                                     BCMA_CCTRL_43224A0_12MA_LED_DRIVE);
132                 } else {
133                         bcma_chipco_chipctl_maskset(cc, 0,
134                                                     ~BCMA_CCTRL_43224B0_12MA_LED_DRIVE,
135                                                     BCMA_CCTRL_43224B0_12MA_LED_DRIVE);
136                 }
137                 break;
138         default:
139                 bcma_debug(bus, "Workarounds unknown or not needed for device 0x%04X\n",
140                            bus->chipinfo.id);
141         }
142 }
143
144 void bcma_pmu_init(struct bcma_drv_cc *cc)
145 {
146         u32 pmucap;
147
148         pmucap = bcma_cc_read32(cc, BCMA_CC_PMU_CAP);
149         cc->pmu.rev = (pmucap & BCMA_CC_PMU_CAP_REVISION);
150
151         bcma_debug(cc->core->bus, "Found rev %u PMU (capabilities 0x%08X)\n",
152                    cc->pmu.rev, pmucap);
153
154         if (cc->pmu.rev == 1)
155                 bcma_cc_mask32(cc, BCMA_CC_PMU_CTL,
156                               ~BCMA_CC_PMU_CTL_NOILPONW);
157         else
158                 bcma_cc_set32(cc, BCMA_CC_PMU_CTL,
159                              BCMA_CC_PMU_CTL_NOILPONW);
160
161         bcma_pmu_resources_init(cc);
162         bcma_pmu_workarounds(cc);
163 }
164
165 u32 bcma_pmu_alp_clock(struct bcma_drv_cc *cc)
166 {
167         struct bcma_bus *bus = cc->core->bus;
168
169         switch (bus->chipinfo.id) {
170         case BCMA_CHIP_ID_BCM4716:
171         case BCMA_CHIP_ID_BCM4748:
172         case BCMA_CHIP_ID_BCM47162:
173         case BCMA_CHIP_ID_BCM4313:
174         case BCMA_CHIP_ID_BCM5357:
175         case BCMA_CHIP_ID_BCM4749:
176         case BCMA_CHIP_ID_BCM53572:
177                 /* always 20Mhz */
178                 return 20000 * 1000;
179         case BCMA_CHIP_ID_BCM5356:
180         case BCMA_CHIP_ID_BCM4706:
181                 /* always 25Mhz */
182                 return 25000 * 1000;
183         default:
184                 bcma_warn(bus, "No ALP clock specified for %04X device, pmu rev. %d, using default %d Hz\n",
185                           bus->chipinfo.id, cc->pmu.rev, BCMA_CC_PMU_ALP_CLOCK);
186         }
187         return BCMA_CC_PMU_ALP_CLOCK;
188 }
189
190 /* Find the output of the "m" pll divider given pll controls that start with
191  * pllreg "pll0" i.e. 12 for main 6 for phy, 0 for misc.
192  */
193 static u32 bcma_pmu_clock(struct bcma_drv_cc *cc, u32 pll0, u32 m)
194 {
195         u32 tmp, div, ndiv, p1, p2, fc;
196         struct bcma_bus *bus = cc->core->bus;
197
198         BUG_ON((pll0 & 3) || (pll0 > BCMA_CC_PMU4716_MAINPLL_PLL0));
199
200         BUG_ON(!m || m > 4);
201
202         if (bus->chipinfo.id == BCMA_CHIP_ID_BCM5357 ||
203             bus->chipinfo.id == BCMA_CHIP_ID_BCM4749) {
204                 /* Detect failure in clock setting */
205                 tmp = bcma_cc_read32(cc, BCMA_CC_CHIPSTAT);
206                 if (tmp & 0x40000)
207                         return 133 * 1000000;
208         }
209
210         tmp = bcma_chipco_pll_read(cc, pll0 + BCMA_CC_PPL_P1P2_OFF);
211         p1 = (tmp & BCMA_CC_PPL_P1_MASK) >> BCMA_CC_PPL_P1_SHIFT;
212         p2 = (tmp & BCMA_CC_PPL_P2_MASK) >> BCMA_CC_PPL_P2_SHIFT;
213
214         tmp = bcma_chipco_pll_read(cc, pll0 + BCMA_CC_PPL_M14_OFF);
215         div = (tmp >> ((m - 1) * BCMA_CC_PPL_MDIV_WIDTH)) &
216                 BCMA_CC_PPL_MDIV_MASK;
217
218         tmp = bcma_chipco_pll_read(cc, pll0 + BCMA_CC_PPL_NM5_OFF);
219         ndiv = (tmp & BCMA_CC_PPL_NDIV_MASK) >> BCMA_CC_PPL_NDIV_SHIFT;
220
221         /* Do calculation in Mhz */
222         fc = bcma_pmu_alp_clock(cc) / 1000000;
223         fc = (p1 * ndiv * fc) / p2;
224
225         /* Return clock in Hertz */
226         return (fc / div) * 1000000;
227 }
228
229 static u32 bcma_pmu_clock_bcm4706(struct bcma_drv_cc *cc, u32 pll0, u32 m)
230 {
231         u32 tmp, ndiv, p1div, p2div;
232         u32 clock;
233
234         BUG_ON(!m || m > 4);
235
236         /* Get N, P1 and P2 dividers to determine CPU clock */
237         tmp = bcma_chipco_pll_read(cc, pll0 + BCMA_CC_PMU6_4706_PROCPLL_OFF);
238         ndiv = (tmp & BCMA_CC_PMU6_4706_PROC_NDIV_INT_MASK)
239                 >> BCMA_CC_PMU6_4706_PROC_NDIV_INT_SHIFT;
240         p1div = (tmp & BCMA_CC_PMU6_4706_PROC_P1DIV_MASK)
241                 >> BCMA_CC_PMU6_4706_PROC_P1DIV_SHIFT;
242         p2div = (tmp & BCMA_CC_PMU6_4706_PROC_P2DIV_MASK)
243                 >> BCMA_CC_PMU6_4706_PROC_P2DIV_SHIFT;
244
245         tmp = bcma_cc_read32(cc, BCMA_CC_CHIPSTAT);
246         if (tmp & BCMA_CC_CHIPST_4706_PKG_OPTION)
247                 /* Low cost bonding: Fixed reference clock 25MHz and m = 4 */
248                 clock = (25000000 / 4) * ndiv * p2div / p1div;
249         else
250                 /* Fixed reference clock 25MHz and m = 2 */
251                 clock = (25000000 / 2) * ndiv * p2div / p1div;
252
253         if (m == BCMA_CC_PMU5_MAINPLL_SSB)
254                 clock = clock / 4;
255
256         return clock;
257 }
258
259 /* query bus clock frequency for PMU-enabled chipcommon */
260 u32 bcma_pmu_get_clockcontrol(struct bcma_drv_cc *cc)
261 {
262         struct bcma_bus *bus = cc->core->bus;
263
264         switch (bus->chipinfo.id) {
265         case BCMA_CHIP_ID_BCM4716:
266         case BCMA_CHIP_ID_BCM4748:
267         case BCMA_CHIP_ID_BCM47162:
268                 return bcma_pmu_clock(cc, BCMA_CC_PMU4716_MAINPLL_PLL0,
269                                       BCMA_CC_PMU5_MAINPLL_SSB);
270         case BCMA_CHIP_ID_BCM5356:
271                 return bcma_pmu_clock(cc, BCMA_CC_PMU5356_MAINPLL_PLL0,
272                                       BCMA_CC_PMU5_MAINPLL_SSB);
273         case BCMA_CHIP_ID_BCM5357:
274         case BCMA_CHIP_ID_BCM4749:
275                 return bcma_pmu_clock(cc, BCMA_CC_PMU5357_MAINPLL_PLL0,
276                                       BCMA_CC_PMU5_MAINPLL_SSB);
277         case BCMA_CHIP_ID_BCM4706:
278                 return bcma_pmu_clock_bcm4706(cc, BCMA_CC_PMU4706_MAINPLL_PLL0,
279                                               BCMA_CC_PMU5_MAINPLL_SSB);
280         case BCMA_CHIP_ID_BCM53572:
281                 return 75000000;
282         default:
283                 bcma_warn(bus, "No backplane clock specified for %04X device, pmu rev. %d, using default %d Hz\n",
284                           bus->chipinfo.id, cc->pmu.rev, BCMA_CC_PMU_HT_CLOCK);
285         }
286         return BCMA_CC_PMU_HT_CLOCK;
287 }
288
289 /* query cpu clock frequency for PMU-enabled chipcommon */
290 u32 bcma_pmu_get_clockcpu(struct bcma_drv_cc *cc)
291 {
292         struct bcma_bus *bus = cc->core->bus;
293
294         if (bus->chipinfo.id == BCMA_CHIP_ID_BCM53572)
295                 return 300000000;
296
297         if (cc->pmu.rev >= 5) {
298                 u32 pll;
299                 switch (bus->chipinfo.id) {
300                 case BCMA_CHIP_ID_BCM4706:
301                         return bcma_pmu_clock_bcm4706(cc,
302                                                 BCMA_CC_PMU4706_MAINPLL_PLL0,
303                                                 BCMA_CC_PMU5_MAINPLL_CPU);
304                 case BCMA_CHIP_ID_BCM5356:
305                         pll = BCMA_CC_PMU5356_MAINPLL_PLL0;
306                         break;
307                 case BCMA_CHIP_ID_BCM5357:
308                 case BCMA_CHIP_ID_BCM4749:
309                         pll = BCMA_CC_PMU5357_MAINPLL_PLL0;
310                         break;
311                 default:
312                         pll = BCMA_CC_PMU4716_MAINPLL_PLL0;
313                         break;
314                 }
315
316                 return bcma_pmu_clock(cc, pll, BCMA_CC_PMU5_MAINPLL_CPU);
317         }
318
319         return bcma_pmu_get_clockcontrol(cc);
320 }
321
322 static void bcma_pmu_spuravoid_pll_write(struct bcma_drv_cc *cc, u32 offset,
323                                          u32 value)
324 {
325         bcma_cc_write32(cc, BCMA_CC_PLLCTL_ADDR, offset);
326         bcma_cc_write32(cc, BCMA_CC_PLLCTL_DATA, value);
327 }
328
329 void bcma_pmu_spuravoid_pllupdate(struct bcma_drv_cc *cc, int spuravoid)
330 {
331         u32 tmp = 0;
332         u8 phypll_offset = 0;
333         u8 bcm5357_bcm43236_p1div[] = {0x1, 0x5, 0x5};
334         u8 bcm5357_bcm43236_ndiv[] = {0x30, 0xf6, 0xfc};
335         struct bcma_bus *bus = cc->core->bus;
336
337         switch (bus->chipinfo.id) {
338         case BCMA_CHIP_ID_BCM5357:
339         case BCMA_CHIP_ID_BCM4749:
340         case BCMA_CHIP_ID_BCM53572:
341                 /* 5357[ab]0, 43236[ab]0, and 6362b0 */
342
343                 /* BCM5357 needs to touch PLL1_PLLCTL[02],
344                    so offset PLL0_PLLCTL[02] by 6 */
345                 phypll_offset = (bus->chipinfo.id == BCMA_CHIP_ID_BCM5357 ||
346                        bus->chipinfo.id == BCMA_CHIP_ID_BCM4749 ||
347                        bus->chipinfo.id == BCMA_CHIP_ID_BCM53572) ? 6 : 0;
348
349                 /* RMW only the P1 divider */
350                 bcma_cc_write32(cc, BCMA_CC_PLLCTL_ADDR,
351                                 BCMA_CC_PMU_PLL_CTL0 + phypll_offset);
352                 tmp = bcma_cc_read32(cc, BCMA_CC_PLLCTL_DATA);
353                 tmp &= (~(BCMA_CC_PMU1_PLL0_PC0_P1DIV_MASK));
354                 tmp |= (bcm5357_bcm43236_p1div[spuravoid] << BCMA_CC_PMU1_PLL0_PC0_P1DIV_SHIFT);
355                 bcma_cc_write32(cc, BCMA_CC_PLLCTL_DATA, tmp);
356
357                 /* RMW only the int feedback divider */
358                 bcma_cc_write32(cc, BCMA_CC_PLLCTL_ADDR,
359                                 BCMA_CC_PMU_PLL_CTL2 + phypll_offset);
360                 tmp = bcma_cc_read32(cc, BCMA_CC_PLLCTL_DATA);
361                 tmp &= ~(BCMA_CC_PMU1_PLL0_PC2_NDIV_INT_MASK);
362                 tmp |= (bcm5357_bcm43236_ndiv[spuravoid]) << BCMA_CC_PMU1_PLL0_PC2_NDIV_INT_SHIFT;
363                 bcma_cc_write32(cc, BCMA_CC_PLLCTL_DATA, tmp);
364
365                 tmp = 1 << 10;
366                 break;
367
368         case BCMA_CHIP_ID_BCM4331:
369         case BCMA_CHIP_ID_BCM43431:
370                 if (spuravoid == 2) {
371                         bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL0,
372                                                      0x11500014);
373                         bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL2,
374                                                      0x0FC00a08);
375                 } else if (spuravoid == 1) {
376                         bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL0,
377                                                      0x11500014);
378                         bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL2,
379                                                      0x0F600a08);
380                 } else {
381                         bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL0,
382                                                      0x11100014);
383                         bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL2,
384                                                      0x03000a08);
385                 }
386                 tmp = 1 << 10;
387                 break;
388
389         case BCMA_CHIP_ID_BCM43224:
390         case BCMA_CHIP_ID_BCM43225:
391         case BCMA_CHIP_ID_BCM43421:
392                 if (spuravoid == 1) {
393                         bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL0,
394                                                      0x11500010);
395                         bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL1,
396                                                      0x000C0C06);
397                         bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL2,
398                                                      0x0F600a08);
399                         bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL3,
400                                                      0x00000000);
401                         bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL4,
402                                                      0x2001E920);
403                         bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL5,
404                                                      0x88888815);
405                 } else {
406                         bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL0,
407                                                      0x11100010);
408                         bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL1,
409                                                      0x000c0c06);
410                         bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL2,
411                                                      0x03000a08);
412                         bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL3,
413                                                      0x00000000);
414                         bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL4,
415                                                      0x200005c0);
416                         bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL5,
417                                                      0x88888815);
418                 }
419                 tmp = 1 << 10;
420                 break;
421
422         case BCMA_CHIP_ID_BCM4716:
423         case BCMA_CHIP_ID_BCM4748:
424         case BCMA_CHIP_ID_BCM47162:
425                 if (spuravoid == 1) {
426                         bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL0,
427                                                      0x11500060);
428                         bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL1,
429                                                      0x080C0C06);
430                         bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL2,
431                                                      0x0F600000);
432                         bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL3,
433                                                      0x00000000);
434                         bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL4,
435                                                      0x2001E924);
436                         bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL5,
437                                                      0x88888815);
438                 } else {
439                         bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL0,
440                                                      0x11100060);
441                         bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL1,
442                                                      0x080c0c06);
443                         bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL2,
444                                                      0x03000000);
445                         bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL3,
446                                                      0x00000000);
447                         bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL4,
448                                                      0x200005c0);
449                         bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL5,
450                                                      0x88888815);
451                 }
452
453                 tmp = 3 << 9;
454                 break;
455
456         case BCMA_CHIP_ID_BCM43227:
457         case BCMA_CHIP_ID_BCM43228:
458         case BCMA_CHIP_ID_BCM43428:
459                 /* LCNXN */
460                 /* PLL Settings for spur avoidance on/off mode,
461                    no on2 support for 43228A0 */
462                 if (spuravoid == 1) {
463                         bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL0,
464                                                      0x01100014);
465                         bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL1,
466                                                      0x040C0C06);
467                         bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL2,
468                                                      0x03140A08);
469                         bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL3,
470                                                      0x00333333);
471                         bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL4,
472                                                      0x202C2820);
473                         bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL5,
474                                                      0x88888815);
475                 } else {
476                         bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL0,
477                                                      0x11100014);
478                         bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL1,
479                                                      0x040c0c06);
480                         bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL2,
481                                                      0x03000a08);
482                         bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL3,
483                                                      0x00000000);
484                         bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL4,
485                                                      0x200005c0);
486                         bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL5,
487                                                      0x88888815);
488                 }
489                 tmp = 1 << 10;
490                 break;
491         default:
492                 bcma_err(bus, "Unknown spuravoidance settings for chip 0x%04X, not changing PLL\n",
493                          bus->chipinfo.id);
494                 break;
495         }
496
497         tmp |= bcma_cc_read32(cc, BCMA_CC_PMU_CTL);
498         bcma_cc_write32(cc, BCMA_CC_PMU_CTL, tmp);
499 }
500 EXPORT_SYMBOL_GPL(bcma_pmu_spuravoid_pllupdate);