]> git.karo-electronics.de Git - mv-sheeva.git/blob - drivers/staging/brcm80211/brcmsmac/aiutils.c
staging: brcm80211: renamed utility module related files
[mv-sheeva.git] / drivers / staging / brcm80211 / brcmsmac / aiutils.c
1 /*
2  * Copyright (c) 2010 Broadcom Corporation
3  *
4  * Permission to use, copy, modify, and/or distribute this software for any
5  * purpose with or without fee is hereby granted, provided that the above
6  * copyright notice and this permission notice appear in all copies.
7  *
8  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11  * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15  */
16
17 #include <linux/delay.h>
18 #include <linux/kernel.h>
19 #include <linux/string.h>
20 #include <bcmdefs.h>
21 #include <linux/module.h>
22 #include <linux/pci.h>
23 #include <brcmu_utils.h>
24 #include <aiutils.h>
25 #include <bcmsoc.h>
26 #include <chipcommon.h>
27 #include <bcmdevs.h>
28
29 /* ********** from siutils.c *********** */
30 #include <nicpci.h>
31 #include <bcmnvram.h>
32 #include <bcmsrom.h>
33 #include <wlc_pmu.h>
34
35 /* slow_clk_ctl */
36 #define SCC_SS_MASK             0x00000007      /* slow clock source mask */
37 #define SCC_SS_LPO              0x00000000      /* source of slow clock is LPO */
38 #define SCC_SS_XTAL             0x00000001      /* source of slow clock is crystal */
39 #define SCC_SS_PCI              0x00000002      /* source of slow clock is PCI */
40 #define SCC_LF                  0x00000200      /* LPOFreqSel, 1: 160Khz, 0: 32KHz */
41 #define SCC_LP                  0x00000400      /* LPOPowerDown, 1: LPO is disabled,
42                                                  * 0: LPO is enabled
43                                                  */
44 #define SCC_FS                  0x00000800      /* ForceSlowClk, 1: sb/cores running on slow clock,
45                                                  * 0: power logic control
46                                                  */
47 #define SCC_IP                  0x00001000      /* IgnorePllOffReq, 1/0: power logic ignores/honors
48                                                  * PLL clock disable requests from core
49                                                  */
50 #define SCC_XC                  0x00002000      /* XtalControlEn, 1/0: power logic does/doesn't
51                                                  * disable crystal when appropriate
52                                                  */
53 #define SCC_XP                  0x00004000      /* XtalPU (RO), 1/0: crystal running/disabled */
54 #define SCC_CD_MASK             0xffff0000      /* ClockDivider (SlowClk = 1/(4+divisor)) */
55 #define SCC_CD_SHIFT            16
56
57 /* system_clk_ctl */
58 #define SYCC_IE                 0x00000001      /* ILPen: Enable Idle Low Power */
59 #define SYCC_AE                 0x00000002      /* ALPen: Enable Active Low Power */
60 #define SYCC_FP                 0x00000004      /* ForcePLLOn */
61 #define SYCC_AR                 0x00000008      /* Force ALP (or HT if ALPen is not set */
62 #define SYCC_HR                 0x00000010      /* Force HT */
63 #define SYCC_CD_MASK            0xffff0000      /* ClkDiv  (ILP = 1/(4 * (divisor + 1)) */
64 #define SYCC_CD_SHIFT           16
65
66 #define CST4329_SPROM_OTP_SEL_MASK      0x00000003
67 #define CST4329_DEFCIS_SEL              0       /* OTP is powered up, use def. CIS, no SPROM */
68 #define CST4329_SPROM_SEL               1       /* OTP is powered up, SPROM is present */
69 #define CST4329_OTP_SEL                 2       /* OTP is powered up, no SPROM */
70 #define CST4329_OTP_PWRDN               3       /* OTP is powered down, SPROM is present */
71 #define CST4329_SPI_SDIO_MODE_MASK      0x00000004
72 #define CST4329_SPI_SDIO_MODE_SHIFT     2
73
74 /* 43224 chip-specific ChipControl register bits */
75 #define CCTRL43224_GPIO_TOGGLE          0x8000
76 #define CCTRL_43224A0_12MA_LED_DRIVE    0x00F000F0      /* 12 mA drive strength */
77 #define CCTRL_43224B0_12MA_LED_DRIVE    0xF0    /* 12 mA drive strength for later 43224s */
78
79 /* 43236 Chip specific ChipStatus register bits */
80 #define CST43236_SFLASH_MASK            0x00000040
81 #define CST43236_OTP_MASK               0x00000080
82 #define CST43236_HSIC_MASK              0x00000100      /* USB/HSIC */
83 #define CST43236_BP_CLK                 0x00000200      /* 120/96Mbps */
84 #define CST43236_BOOT_MASK              0x00001800
85 #define CST43236_BOOT_SHIFT             11
86 #define CST43236_BOOT_FROM_SRAM         0       /* boot from SRAM, ARM in reset */
87 #define CST43236_BOOT_FROM_ROM          1       /* boot from ROM */
88 #define CST43236_BOOT_FROM_FLASH        2       /* boot from FLASH */
89 #define CST43236_BOOT_FROM_INVALID      3
90
91 /* 4331 chip-specific ChipControl register bits */
92 #define CCTRL4331_BT_COEXIST            (1<<0)  /* 0 disable */
93 #define CCTRL4331_SECI                  (1<<1)  /* 0 SECI is disabled (JATG functional) */
94 #define CCTRL4331_EXT_LNA               (1<<2)  /* 0 disable */
95 #define CCTRL4331_SPROM_GPIO13_15       (1<<3)  /* sprom/gpio13-15 mux */
96 #define CCTRL4331_EXTPA_EN              (1<<4)  /* 0 ext pa disable, 1 ext pa enabled */
97 #define CCTRL4331_GPIOCLK_ON_SPROMCS    (1<<5)  /* set drive out GPIO_CLK on sprom_cs pin */
98 #define CCTRL4331_PCIE_MDIO_ON_SPROMCS  (1<<6)  /* use sprom_cs pin as PCIE mdio interface */
99 #define CCTRL4331_EXTPA_ON_GPIO2_5      (1<<7)  /* aband extpa will be at gpio2/5 and sprom_dout */
100 #define CCTRL4331_OVR_PIPEAUXCLKEN      (1<<8)  /* override core control on pipe_AuxClkEnable */
101 #define CCTRL4331_OVR_PIPEAUXPWRDOWN    (1<<9)  /* override core control on pipe_AuxPowerDown */
102 #define CCTRL4331_PCIE_AUXCLKEN         (1<<10) /* pcie_auxclkenable */
103 #define CCTRL4331_PCIE_PIPE_PLLDOWN     (1<<11) /* pcie_pipe_pllpowerdown */
104 #define CCTRL4331_BT_SHD0_ON_GPIO4      (1<<16) /* enable bt_shd0 at gpio4 */
105 #define CCTRL4331_BT_SHD1_ON_GPIO5      (1<<17) /* enable bt_shd1 at gpio5 */
106
107 /* 4331 Chip specific ChipStatus register bits */
108 #define CST4331_XTAL_FREQ               0x00000001      /* crystal frequency 20/40Mhz */
109 #define CST4331_SPROM_PRESENT           0x00000002
110 #define CST4331_OTP_PRESENT             0x00000004
111 #define CST4331_LDO_RF                  0x00000008
112 #define CST4331_LDO_PAR                 0x00000010
113
114 /* 4319 chip-specific ChipStatus register bits */
115 #define CST4319_SPI_CPULESSUSB          0x00000001
116 #define CST4319_SPI_CLK_POL             0x00000002
117 #define CST4319_SPI_CLK_PH              0x00000008
118 #define CST4319_SPROM_OTP_SEL_MASK      0x000000c0      /* gpio [7:6], SDIO CIS selection */
119 #define CST4319_SPROM_OTP_SEL_SHIFT     6
120 #define CST4319_DEFCIS_SEL              0x00000000      /* use default CIS, OTP is powered up */
121 #define CST4319_SPROM_SEL               0x00000040      /* use SPROM, OTP is powered up */
122 #define CST4319_OTP_SEL                 0x00000080      /* use OTP, OTP is powered up */
123 #define CST4319_OTP_PWRDN               0x000000c0      /* use SPROM, OTP is powered down */
124 #define CST4319_SDIO_USB_MODE           0x00000100      /* gpio [8], sdio/usb mode */
125 #define CST4319_REMAP_SEL_MASK          0x00000600
126 #define CST4319_ILPDIV_EN               0x00000800
127 #define CST4319_XTAL_PD_POL             0x00001000
128 #define CST4319_LPO_SEL                 0x00002000
129 #define CST4319_RES_INIT_MODE           0x0000c000
130 #define CST4319_PALDO_EXTPNP            0x00010000      /* PALDO is configured with external PNP */
131 #define CST4319_CBUCK_MODE_MASK         0x00060000
132 #define CST4319_CBUCK_MODE_BURST        0x00020000
133 #define CST4319_CBUCK_MODE_LPBURST      0x00060000
134 #define CST4319_RCAL_VALID              0x01000000
135 #define CST4319_RCAL_VALUE_MASK         0x3e000000
136 #define CST4319_RCAL_VALUE_SHIFT        25
137
138 /* 4336 chip-specific ChipStatus register bits */
139 #define CST4336_SPI_MODE_MASK           0x00000001
140 #define CST4336_SPROM_PRESENT           0x00000002
141 #define CST4336_OTP_PRESENT             0x00000004
142 #define CST4336_ARMREMAP_0              0x00000008
143 #define CST4336_ILPDIV_EN_MASK          0x00000010
144 #define CST4336_ILPDIV_EN_SHIFT         4
145 #define CST4336_XTAL_PD_POL_MASK        0x00000020
146 #define CST4336_XTAL_PD_POL_SHIFT       5
147 #define CST4336_LPO_SEL_MASK            0x00000040
148 #define CST4336_LPO_SEL_SHIFT           6
149 #define CST4336_RES_INIT_MODE_MASK      0x00000180
150 #define CST4336_RES_INIT_MODE_SHIFT     7
151 #define CST4336_CBUCK_MODE_MASK         0x00000600
152 #define CST4336_CBUCK_MODE_SHIFT        9
153
154 /* 4313 chip-specific ChipStatus register bits */
155 #define CST4313_SPROM_PRESENT                   1
156 #define CST4313_OTP_PRESENT                     2
157 #define CST4313_SPROM_OTP_SEL_MASK              0x00000002
158 #define CST4313_SPROM_OTP_SEL_SHIFT             0
159
160 /* 4313 Chip specific ChipControl register bits */
161 #define CCTRL_4313_12MA_LED_DRIVE    0x00000007 /* 12 mA drive strengh for later 4313 */
162
163 #define BCM47162_DMP() ((sih->chip == BCM47162_CHIP_ID) && \
164                 (sih->chiprev == 0) && \
165                 (sii->coreid[sii->curidx] == MIPS74K_CORE_ID))
166
167 /* EROM parsing */
168
169 static u32
170 get_erom_ent(struct si_pub *sih, u32 **eromptr, u32 mask, u32 match)
171 {
172         u32 ent;
173         uint inv = 0, nom = 0;
174
175         while (true) {
176                 ent = R_REG(*eromptr);
177                 (*eromptr)++;
178
179                 if (mask == 0)
180                         break;
181
182                 if ((ent & ER_VALID) == 0) {
183                         inv++;
184                         continue;
185                 }
186
187                 if (ent == (ER_END | ER_VALID))
188                         break;
189
190                 if ((ent & mask) == match)
191                         break;
192
193                 nom++;
194         }
195
196         SI_VMSG(("%s: Returning ent 0x%08x\n", __func__, ent));
197         if (inv + nom) {
198                 SI_VMSG(("  after %d invalid and %d non-matching entries\n",
199                          inv, nom));
200         }
201         return ent;
202 }
203
204 static u32
205 get_asd(struct si_pub *sih, u32 **eromptr, uint sp, uint ad, uint st,
206         u32 *addrl, u32 *addrh, u32 *sizel, u32 *sizeh)
207 {
208         u32 asd, sz, szd;
209
210         asd = get_erom_ent(sih, eromptr, ER_VALID, ER_VALID);
211         if (((asd & ER_TAG1) != ER_ADD) ||
212             (((asd & AD_SP_MASK) >> AD_SP_SHIFT) != sp) ||
213             ((asd & AD_ST_MASK) != st)) {
214                 /* This is not what we want, "push" it back */
215                 (*eromptr)--;
216                 return 0;
217         }
218         *addrl = asd & AD_ADDR_MASK;
219         if (asd & AD_AG32)
220                 *addrh = get_erom_ent(sih, eromptr, 0, 0);
221         else
222                 *addrh = 0;
223         *sizeh = 0;
224         sz = asd & AD_SZ_MASK;
225         if (sz == AD_SZ_SZD) {
226                 szd = get_erom_ent(sih, eromptr, 0, 0);
227                 *sizel = szd & SD_SZ_MASK;
228                 if (szd & SD_SG32)
229                         *sizeh = get_erom_ent(sih, eromptr, 0, 0);
230         } else
231                 *sizel = AD_SZ_BASE << (sz >> AD_SZ_SHIFT);
232
233         SI_VMSG(("  SP %d, ad %d: st = %d, 0x%08x_0x%08x @ 0x%08x_0x%08x\n",
234                  sp, ad, st, *sizeh, *sizel, *addrh, *addrl));
235
236         return asd;
237 }
238
239 static void ai_hwfixup(si_info_t *sii)
240 {
241 }
242
243 /* parse the enumeration rom to identify all cores */
244 void ai_scan(struct si_pub *sih, void *regs, uint devid)
245 {
246         si_info_t *sii = SI_INFO(sih);
247         chipcregs_t *cc = (chipcregs_t *) regs;
248         u32 erombase, *eromptr, *eromlim;
249
250         erombase = R_REG(&cc->eromptr);
251
252         switch (sih->bustype) {
253         case SI_BUS:
254                 eromptr = (u32 *) REG_MAP(erombase, SI_CORE_SIZE);
255                 break;
256
257         case PCI_BUS:
258                 /* Set wrappers address */
259                 sii->curwrap = (void *)((unsigned long)regs + SI_CORE_SIZE);
260
261                 /* Now point the window at the erom */
262                 pci_write_config_dword(sii->pbus, PCI_BAR0_WIN, erombase);
263                 eromptr = regs;
264                 break;
265
266         case SPI_BUS:
267         case SDIO_BUS:
268                 eromptr = (u32 *)(unsigned long)erombase;
269                 break;
270
271         default:
272                 SI_ERROR(("Don't know how to do AXI enumertion on bus %d\n",
273                           sih->bustype));
274                 return;
275         }
276         eromlim = eromptr + (ER_REMAPCONTROL / sizeof(u32));
277
278         SI_VMSG(("ai_scan: regs = 0x%p, erombase = 0x%08x, eromptr = 0x%p, eromlim = 0x%p\n", regs, erombase, eromptr, eromlim));
279         while (eromptr < eromlim) {
280                 u32 cia, cib, cid, mfg, crev, nmw, nsw, nmp, nsp;
281                 u32 mpd, asd, addrl, addrh, sizel, sizeh;
282                 u32 *base;
283                 uint i, j, idx;
284                 bool br;
285
286                 br = false;
287
288                 /* Grok a component */
289                 cia = get_erom_ent(sih, &eromptr, ER_TAG, ER_CI);
290                 if (cia == (ER_END | ER_VALID)) {
291                         SI_VMSG(("Found END of erom after %d cores\n",
292                                  sii->numcores));
293                         ai_hwfixup(sii);
294                         return;
295                 }
296                 base = eromptr - 1;
297                 cib = get_erom_ent(sih, &eromptr, 0, 0);
298
299                 if ((cib & ER_TAG) != ER_CI) {
300                         SI_ERROR(("CIA not followed by CIB\n"));
301                         goto error;
302                 }
303
304                 cid = (cia & CIA_CID_MASK) >> CIA_CID_SHIFT;
305                 mfg = (cia & CIA_MFG_MASK) >> CIA_MFG_SHIFT;
306                 crev = (cib & CIB_REV_MASK) >> CIB_REV_SHIFT;
307                 nmw = (cib & CIB_NMW_MASK) >> CIB_NMW_SHIFT;
308                 nsw = (cib & CIB_NSW_MASK) >> CIB_NSW_SHIFT;
309                 nmp = (cib & CIB_NMP_MASK) >> CIB_NMP_SHIFT;
310                 nsp = (cib & CIB_NSP_MASK) >> CIB_NSP_SHIFT;
311
312                 SI_VMSG(("Found component 0x%04x/0x%04x rev %d at erom addr 0x%p, with nmw = %d, " "nsw = %d, nmp = %d & nsp = %d\n", mfg, cid, crev, base, nmw, nsw, nmp, nsp));
313
314                 if (((mfg == MFGID_ARM) && (cid == DEF_AI_COMP)) || (nsp == 0))
315                         continue;
316                 if ((nmw + nsw == 0)) {
317                         /* A component which is not a core */
318                         if (cid == OOB_ROUTER_CORE_ID) {
319                                 asd = get_asd(sih, &eromptr, 0, 0, AD_ST_SLAVE,
320                                               &addrl, &addrh, &sizel, &sizeh);
321                                 if (asd != 0) {
322                                         sii->oob_router = addrl;
323                                 }
324                         }
325                         continue;
326                 }
327
328                 idx = sii->numcores;
329 /*              sii->eromptr[idx] = base; */
330                 sii->cia[idx] = cia;
331                 sii->cib[idx] = cib;
332                 sii->coreid[idx] = cid;
333
334                 for (i = 0; i < nmp; i++) {
335                         mpd = get_erom_ent(sih, &eromptr, ER_VALID, ER_VALID);
336                         if ((mpd & ER_TAG) != ER_MP) {
337                                 SI_ERROR(("Not enough MP entries for component 0x%x\n", cid));
338                                 goto error;
339                         }
340                         SI_VMSG(("  Master port %d, mp: %d id: %d\n", i,
341                                  (mpd & MPD_MP_MASK) >> MPD_MP_SHIFT,
342                                  (mpd & MPD_MUI_MASK) >> MPD_MUI_SHIFT));
343                 }
344
345                 /* First Slave Address Descriptor should be port 0:
346                  * the main register space for the core
347                  */
348                 asd =
349                     get_asd(sih, &eromptr, 0, 0, AD_ST_SLAVE, &addrl, &addrh,
350                             &sizel, &sizeh);
351                 if (asd == 0) {
352                         /* Try again to see if it is a bridge */
353                         asd =
354                             get_asd(sih, &eromptr, 0, 0, AD_ST_BRIDGE, &addrl,
355                                     &addrh, &sizel, &sizeh);
356                         if (asd != 0)
357                                 br = true;
358                         else if ((addrh != 0) || (sizeh != 0)
359                                  || (sizel != SI_CORE_SIZE)) {
360                                 SI_ERROR(("First Slave ASD for core 0x%04x malformed " "(0x%08x)\n", cid, asd));
361                                 goto error;
362                         }
363                 }
364                 sii->coresba[idx] = addrl;
365                 sii->coresba_size[idx] = sizel;
366                 /* Get any more ASDs in port 0 */
367                 j = 1;
368                 do {
369                         asd =
370                             get_asd(sih, &eromptr, 0, j, AD_ST_SLAVE, &addrl,
371                                     &addrh, &sizel, &sizeh);
372                         if ((asd != 0) && (j == 1) && (sizel == SI_CORE_SIZE)) {
373                                 sii->coresba2[idx] = addrl;
374                                 sii->coresba2_size[idx] = sizel;
375                         }
376                         j++;
377                 } while (asd != 0);
378
379                 /* Go through the ASDs for other slave ports */
380                 for (i = 1; i < nsp; i++) {
381                         j = 0;
382                         do {
383                                 asd =
384                                     get_asd(sih, &eromptr, i, j++, AD_ST_SLAVE,
385                                             &addrl, &addrh, &sizel, &sizeh);
386                         } while (asd != 0);
387                         if (j == 0) {
388                                 SI_ERROR((" SP %d has no address descriptors\n",
389                                           i));
390                                 goto error;
391                         }
392                 }
393
394                 /* Now get master wrappers */
395                 for (i = 0; i < nmw; i++) {
396                         asd =
397                             get_asd(sih, &eromptr, i, 0, AD_ST_MWRAP, &addrl,
398                                     &addrh, &sizel, &sizeh);
399                         if (asd == 0) {
400                                 SI_ERROR(("Missing descriptor for MW %d\n", i));
401                                 goto error;
402                         }
403                         if ((sizeh != 0) || (sizel != SI_CORE_SIZE)) {
404                                 SI_ERROR(("Master wrapper %d is not 4KB\n", i));
405                                 goto error;
406                         }
407                         if (i == 0)
408                                 sii->wrapba[idx] = addrl;
409                 }
410
411                 /* And finally slave wrappers */
412                 for (i = 0; i < nsw; i++) {
413                         uint fwp = (nsp == 1) ? 0 : 1;
414                         asd =
415                             get_asd(sih, &eromptr, fwp + i, 0, AD_ST_SWRAP,
416                                     &addrl, &addrh, &sizel, &sizeh);
417                         if (asd == 0) {
418                                 SI_ERROR(("Missing descriptor for SW %d\n", i));
419                                 goto error;
420                         }
421                         if ((sizeh != 0) || (sizel != SI_CORE_SIZE)) {
422                                 SI_ERROR(("Slave wrapper %d is not 4KB\n", i));
423                                 goto error;
424                         }
425                         if ((nmw == 0) && (i == 0))
426                                 sii->wrapba[idx] = addrl;
427                 }
428
429                 /* Don't record bridges */
430                 if (br)
431                         continue;
432
433                 /* Done with core */
434                 sii->numcores++;
435         }
436
437         SI_ERROR(("Reached end of erom without finding END"));
438
439  error:
440         sii->numcores = 0;
441         return;
442 }
443
444 /* This function changes the logical "focus" to the indicated core.
445  * Return the current core's virtual address.
446  */
447 void *ai_setcoreidx(struct si_pub *sih, uint coreidx)
448 {
449         si_info_t *sii = SI_INFO(sih);
450         u32 addr = sii->coresba[coreidx];
451         u32 wrap = sii->wrapba[coreidx];
452         void *regs;
453
454         if (coreidx >= sii->numcores)
455                 return NULL;
456
457         switch (sih->bustype) {
458         case SI_BUS:
459                 /* map new one */
460                 if (!sii->regs[coreidx]) {
461                         sii->regs[coreidx] = REG_MAP(addr, SI_CORE_SIZE);
462                 }
463                 sii->curmap = regs = sii->regs[coreidx];
464                 if (!sii->wrappers[coreidx]) {
465                         sii->wrappers[coreidx] = REG_MAP(wrap, SI_CORE_SIZE);
466                 }
467                 sii->curwrap = sii->wrappers[coreidx];
468                 break;
469
470         case PCI_BUS:
471                 /* point bar0 window */
472                 pci_write_config_dword(sii->pbus, PCI_BAR0_WIN, addr);
473                 regs = sii->curmap;
474                 /* point bar0 2nd 4KB window */
475                 pci_write_config_dword(sii->pbus, PCI_BAR0_WIN2, wrap);
476                 break;
477
478         case SPI_BUS:
479         case SDIO_BUS:
480                 sii->curmap = regs = (void *)(unsigned long)addr;
481                 sii->curwrap = (void *)(unsigned long)wrap;
482                 break;
483
484         default:
485                 regs = NULL;
486                 break;
487         }
488
489         sii->curmap = regs;
490         sii->curidx = coreidx;
491
492         return regs;
493 }
494
495 /* Return the number of address spaces in current core */
496 int ai_numaddrspaces(struct si_pub *sih)
497 {
498         return 2;
499 }
500
501 /* Return the address of the nth address space in the current core */
502 u32 ai_addrspace(struct si_pub *sih, uint asidx)
503 {
504         si_info_t *sii;
505         uint cidx;
506
507         sii = SI_INFO(sih);
508         cidx = sii->curidx;
509
510         if (asidx == 0)
511                 return sii->coresba[cidx];
512         else if (asidx == 1)
513                 return sii->coresba2[cidx];
514         else {
515                 SI_ERROR(("%s: Need to parse the erom again to find addr space %d\n", __func__, asidx));
516                 return 0;
517         }
518 }
519
520 /* Return the size of the nth address space in the current core */
521 u32 ai_addrspacesize(struct si_pub *sih, uint asidx)
522 {
523         si_info_t *sii;
524         uint cidx;
525
526         sii = SI_INFO(sih);
527         cidx = sii->curidx;
528
529         if (asidx == 0)
530                 return sii->coresba_size[cidx];
531         else if (asidx == 1)
532                 return sii->coresba2_size[cidx];
533         else {
534                 SI_ERROR(("%s: Need to parse the erom again to find addr space %d\n", __func__, asidx));
535                 return 0;
536         }
537 }
538
539 uint ai_flag(struct si_pub *sih)
540 {
541         si_info_t *sii;
542         aidmp_t *ai;
543
544         sii = SI_INFO(sih);
545         if (BCM47162_DMP()) {
546                 SI_ERROR(("%s: Attempting to read MIPS DMP registers on 47162a0", __func__));
547                 return sii->curidx;
548         }
549         ai = sii->curwrap;
550
551         return R_REG(&ai->oobselouta30) & 0x1f;
552 }
553
554 void ai_setint(struct si_pub *sih, int siflag)
555 {
556 }
557
558 uint ai_corevendor(struct si_pub *sih)
559 {
560         si_info_t *sii;
561         u32 cia;
562
563         sii = SI_INFO(sih);
564         cia = sii->cia[sii->curidx];
565         return (cia & CIA_MFG_MASK) >> CIA_MFG_SHIFT;
566 }
567
568 uint ai_corerev(struct si_pub *sih)
569 {
570         si_info_t *sii;
571         u32 cib;
572
573         sii = SI_INFO(sih);
574         cib = sii->cib[sii->curidx];
575         return (cib & CIB_REV_MASK) >> CIB_REV_SHIFT;
576 }
577
578 bool ai_iscoreup(struct si_pub *sih)
579 {
580         si_info_t *sii;
581         aidmp_t *ai;
582
583         sii = SI_INFO(sih);
584         ai = sii->curwrap;
585
586         return (((R_REG(&ai->ioctrl) & (SICF_FGC | SICF_CLOCK_EN)) ==
587                  SICF_CLOCK_EN)
588                 && ((R_REG(&ai->resetctrl) & AIRC_RESET) == 0));
589 }
590
591 void ai_core_cflags_wo(struct si_pub *sih, u32 mask, u32 val)
592 {
593         si_info_t *sii;
594         aidmp_t *ai;
595         u32 w;
596
597         sii = SI_INFO(sih);
598
599         if (BCM47162_DMP()) {
600                 SI_ERROR(("%s: Accessing MIPS DMP register (ioctrl) on 47162a0",
601                           __func__));
602                 return;
603         }
604
605         ai = sii->curwrap;
606
607         if (mask || val) {
608                 w = ((R_REG(&ai->ioctrl) & ~mask) | val);
609                 W_REG(&ai->ioctrl, w);
610         }
611 }
612
613 u32 ai_core_cflags(struct si_pub *sih, u32 mask, u32 val)
614 {
615         si_info_t *sii;
616         aidmp_t *ai;
617         u32 w;
618
619         sii = SI_INFO(sih);
620         if (BCM47162_DMP()) {
621                 SI_ERROR(("%s: Accessing MIPS DMP register (ioctrl) on 47162a0",
622                           __func__));
623                 return 0;
624         }
625
626         ai = sii->curwrap;
627
628         if (mask || val) {
629                 w = ((R_REG(&ai->ioctrl) & ~mask) | val);
630                 W_REG(&ai->ioctrl, w);
631         }
632
633         return R_REG(&ai->ioctrl);
634 }
635
636 u32 ai_core_sflags(struct si_pub *sih, u32 mask, u32 val)
637 {
638         si_info_t *sii;
639         aidmp_t *ai;
640         u32 w;
641
642         sii = SI_INFO(sih);
643         if (BCM47162_DMP()) {
644                 SI_ERROR(("%s: Accessing MIPS DMP register (iostatus) on 47162a0", __func__));
645                 return 0;
646         }
647
648         ai = sii->curwrap;
649
650         if (mask || val) {
651                 w = ((R_REG(&ai->iostatus) & ~mask) | val);
652                 W_REG(&ai->iostatus, w);
653         }
654
655         return R_REG(&ai->iostatus);
656 }
657
658 /* *************** from siutils.c ************** */
659 /* local prototypes */
660 static si_info_t *ai_doattach(si_info_t *sii, uint devid, void *regs,
661                               uint bustype, void *sdh, char **vars,
662                               uint *varsz);
663 static bool ai_buscore_prep(si_info_t *sii, uint bustype, uint devid,
664                             void *sdh);
665 static bool ai_buscore_setup(si_info_t *sii, chipcregs_t *cc, uint bustype,
666                              u32 savewin, uint *origidx, void *regs);
667 static void ai_nvram_process(si_info_t *sii, char *pvars);
668
669 /* dev path concatenation util */
670 static char *ai_devpathvar(struct si_pub *sih, char *var, int len,
671                            const char *name);
672 static bool _ai_clkctl_cc(si_info_t *sii, uint mode);
673 static bool ai_ispcie(si_info_t *sii);
674
675 /* global variable to indicate reservation/release of gpio's */
676 static u32 ai_gpioreservation;
677
678 /*
679  * Allocate a si handle.
680  * devid - pci device id (used to determine chip#)
681  * osh - opaque OS handle
682  * regs - virtual address of initial core registers
683  * bustype - pci/sb/sdio/etc
684  * vars - pointer to a pointer area for "environment" variables
685  * varsz - pointer to int to return the size of the vars
686  */
687 struct si_pub *ai_attach(uint devid, void *regs, uint bustype,
688                 void *sdh, char **vars, uint *varsz)
689 {
690         si_info_t *sii;
691
692         /* alloc si_info_t */
693         sii = kmalloc(sizeof(si_info_t), GFP_ATOMIC);
694         if (sii == NULL) {
695                 SI_ERROR(("si_attach: malloc failed!\n"));
696                 return NULL;
697         }
698
699         if (ai_doattach(sii, devid, regs, bustype, sdh, vars, varsz) ==
700             NULL) {
701                 kfree(sii);
702                 return NULL;
703         }
704         sii->vars = vars ? *vars : NULL;
705         sii->varsz = varsz ? *varsz : 0;
706
707         return (struct si_pub *) sii;
708 }
709
710 /* global kernel resource */
711 static si_info_t ksii;
712
713 static bool ai_buscore_prep(si_info_t *sii, uint bustype, uint devid,
714                             void *sdh)
715 {
716         /* kludge to enable the clock on the 4306 which lacks a slowclock */
717         if (bustype == PCI_BUS && !ai_ispcie(sii))
718                 ai_clkctl_xtal(&sii->pub, XTAL | PLL, ON);
719         return true;
720 }
721
722 static bool ai_buscore_setup(si_info_t *sii, chipcregs_t *cc, uint bustype,
723                              u32 savewin, uint *origidx, void *regs)
724 {
725         bool pci, pcie;
726         uint i;
727         uint pciidx, pcieidx, pcirev, pcierev;
728
729         cc = ai_setcoreidx(&sii->pub, SI_CC_IDX);
730
731         /* get chipcommon rev */
732         sii->pub.ccrev = (int)ai_corerev(&sii->pub);
733
734         /* get chipcommon chipstatus */
735         if (sii->pub.ccrev >= 11)
736                 sii->pub.chipst = R_REG(&cc->chipstatus);
737
738         /* get chipcommon capabilites */
739         sii->pub.cccaps = R_REG(&cc->capabilities);
740         /* get chipcommon extended capabilities */
741
742         if (sii->pub.ccrev >= 35)
743                 sii->pub.cccaps_ext = R_REG(&cc->capabilities_ext);
744
745         /* get pmu rev and caps */
746         if (sii->pub.cccaps & CC_CAP_PMU) {
747                 sii->pub.pmucaps = R_REG(&cc->pmucapabilities);
748                 sii->pub.pmurev = sii->pub.pmucaps & PCAP_REV_MASK;
749         }
750
751         /* figure out bus/orignal core idx */
752         sii->pub.buscoretype = NODEV_CORE_ID;
753         sii->pub.buscorerev = NOREV;
754         sii->pub.buscoreidx = BADIDX;
755
756         pci = pcie = false;
757         pcirev = pcierev = NOREV;
758         pciidx = pcieidx = BADIDX;
759
760         for (i = 0; i < sii->numcores; i++) {
761                 uint cid, crev;
762
763                 ai_setcoreidx(&sii->pub, i);
764                 cid = ai_coreid(&sii->pub);
765                 crev = ai_corerev(&sii->pub);
766
767                 /* Display cores found */
768                 SI_VMSG(("CORE[%d]: id 0x%x rev %d base 0x%x regs 0x%p\n",
769                          i, cid, crev, sii->coresba[i], sii->regs[i]));
770
771                 if (bustype == PCI_BUS) {
772                         if (cid == PCI_CORE_ID) {
773                                 pciidx = i;
774                                 pcirev = crev;
775                                 pci = true;
776                         } else if (cid == PCIE_CORE_ID) {
777                                 pcieidx = i;
778                                 pcierev = crev;
779                                 pcie = true;
780                         }
781                 }
782
783                 /* find the core idx before entering this func. */
784                 if ((savewin && (savewin == sii->coresba[i])) ||
785                     (regs == sii->regs[i]))
786                         *origidx = i;
787         }
788
789         if (pci && pcie) {
790                 if (ai_ispcie(sii))
791                         pci = false;
792                 else
793                         pcie = false;
794         }
795         if (pci) {
796                 sii->pub.buscoretype = PCI_CORE_ID;
797                 sii->pub.buscorerev = pcirev;
798                 sii->pub.buscoreidx = pciidx;
799         } else if (pcie) {
800                 sii->pub.buscoretype = PCIE_CORE_ID;
801                 sii->pub.buscorerev = pcierev;
802                 sii->pub.buscoreidx = pcieidx;
803         }
804
805         SI_VMSG(("Buscore id/type/rev %d/0x%x/%d\n", sii->pub.buscoreidx,
806                  sii->pub.buscoretype, sii->pub.buscorerev));
807
808         /* fixup necessary chip/core configurations */
809         if (sii->pub.bustype == PCI_BUS) {
810                 if (SI_FAST(sii)) {
811                         if (!sii->pch) {
812                                 sii->pch = (void *)pcicore_init(
813                                         &sii->pub, sii->pbus,
814                                         (void *)PCIEREGS(sii));
815                                 if (sii->pch == NULL)
816                                         return false;
817                         }
818                 }
819                 if (ai_pci_fixcfg(&sii->pub)) {
820                         SI_ERROR(("si_doattach: si_pci_fixcfg failed\n"));
821                         return false;
822                 }
823         }
824
825         /* return to the original core */
826         ai_setcoreidx(&sii->pub, *origidx);
827
828         return true;
829 }
830
831 static __used void ai_nvram_process(si_info_t *sii, char *pvars)
832 {
833         uint w = 0;
834
835         /* get boardtype and boardrev */
836         switch (sii->pub.bustype) {
837         case PCI_BUS:
838                 /* do a pci config read to get subsystem id and subvendor id */
839                 pci_read_config_dword(sii->pbus, PCI_SUBSYSTEM_VENDOR_ID, &w);
840                 /* Let nvram variables override subsystem Vend/ID */
841                 sii->pub.boardvendor = (u16)ai_getdevpathintvar(&sii->pub,
842                         "boardvendor");
843                 if (sii->pub.boardvendor == 0)
844                         sii->pub.boardvendor = w & 0xffff;
845                 else
846                         SI_ERROR(("Overriding boardvendor: 0x%x instead of "
847                                   "0x%x\n", sii->pub.boardvendor, w & 0xffff));
848                 sii->pub.boardtype = (u16)ai_getdevpathintvar(&sii->pub,
849                         "boardtype");
850                 if (sii->pub.boardtype == 0)
851                         sii->pub.boardtype = (w >> 16) & 0xffff;
852                 else
853                         SI_ERROR(("Overriding boardtype: 0x%x instead of 0x%x\n"
854                                   , sii->pub.boardtype, (w >> 16) & 0xffff));
855                 break;
856
857                 sii->pub.boardvendor = getintvar(pvars, "manfid");
858                 sii->pub.boardtype = getintvar(pvars, "prodid");
859                 break;
860
861         case SI_BUS:
862         case JTAG_BUS:
863                 sii->pub.boardvendor = PCI_VENDOR_ID_BROADCOM;
864                 sii->pub.boardtype = getintvar(pvars, "prodid");
865                 if (pvars == NULL || (sii->pub.boardtype == 0)) {
866                         sii->pub.boardtype = getintvar(NULL, "boardtype");
867                         if (sii->pub.boardtype == 0)
868                                 sii->pub.boardtype = 0xffff;
869                 }
870                 break;
871         }
872
873         if (sii->pub.boardtype == 0) {
874                 SI_ERROR(("si_doattach: unknown board type\n"));
875         }
876
877         sii->pub.boardflags = getintvar(pvars, "boardflags");
878 }
879
880 static si_info_t *ai_doattach(si_info_t *sii, uint devid,
881                               void *regs, uint bustype, void *pbus,
882                               char **vars, uint *varsz)
883 {
884         struct si_pub *sih = &sii->pub;
885         u32 w, savewin;
886         chipcregs_t *cc;
887         char *pvars = NULL;
888         uint socitype;
889         uint origidx;
890
891         memset((unsigned char *) sii, 0, sizeof(si_info_t));
892
893         savewin = 0;
894
895         sih->buscoreidx = BADIDX;
896
897         sii->curmap = regs;
898         sii->pbus = pbus;
899
900         /* check to see if we are a si core mimic'ing a pci core */
901         if (bustype == PCI_BUS) {
902                 pci_read_config_dword(sii->pbus, PCI_SPROM_CONTROL,  &w);
903                 if (w == 0xffffffff) {
904                         SI_ERROR(("%s: incoming bus is PCI but it's a lie, "
905                                 " switching to SI devid:0x%x\n",
906                                 __func__, devid));
907                         bustype = SI_BUS;
908                 }
909         }
910
911         /* find Chipcommon address */
912         if (bustype == PCI_BUS) {
913                 pci_read_config_dword(sii->pbus, PCI_BAR0_WIN, &savewin);
914                 if (!GOODCOREADDR(savewin, SI_ENUM_BASE))
915                         savewin = SI_ENUM_BASE;
916                 pci_write_config_dword(sii->pbus, PCI_BAR0_WIN,
917                                        SI_ENUM_BASE);
918                 cc = (chipcregs_t *) regs;
919         } else {
920                 cc = (chipcregs_t *) REG_MAP(SI_ENUM_BASE, SI_CORE_SIZE);
921         }
922
923         sih->bustype = bustype;
924
925         /* bus/core/clk setup for register access */
926         if (!ai_buscore_prep(sii, bustype, devid, pbus)) {
927                 SI_ERROR(("si_doattach: si_core_clk_prep failed %d\n",
928                           bustype));
929                 return NULL;
930         }
931
932         /*
933          * ChipID recognition.
934          *   We assume we can read chipid at offset 0 from the regs arg.
935          *   If we add other chiptypes (or if we need to support old sdio
936          *   hosts w/o chipcommon), some way of recognizing them needs to
937          *   be added here.
938          */
939         w = R_REG(&cc->chipid);
940         socitype = (w & CID_TYPE_MASK) >> CID_TYPE_SHIFT;
941         /* Might as wll fill in chip id rev & pkg */
942         sih->chip = w & CID_ID_MASK;
943         sih->chiprev = (w & CID_REV_MASK) >> CID_REV_SHIFT;
944         sih->chippkg = (w & CID_PKG_MASK) >> CID_PKG_SHIFT;
945
946         sih->issim = IS_SIM(sih->chippkg);
947
948         /* scan for cores */
949         if (socitype == SOCI_AI) {
950                 SI_MSG(("Found chip type AI (0x%08x)\n", w));
951                 /* pass chipc address instead of original core base */
952                 ai_scan(&sii->pub, (void *)cc, devid);
953         } else {
954                 SI_ERROR(("Found chip of unknown type (0x%08x)\n", w));
955                 return NULL;
956         }
957         /* no cores found, bail out */
958         if (sii->numcores == 0) {
959                 SI_ERROR(("si_doattach: could not find any cores\n"));
960                 return NULL;
961         }
962         /* bus/core/clk setup */
963         origidx = SI_CC_IDX;
964         if (!ai_buscore_setup(sii, cc, bustype, savewin, &origidx, regs)) {
965                 SI_ERROR(("si_doattach: si_buscore_setup failed\n"));
966                 goto exit;
967         }
968
969         /* assume current core is CC */
970         if ((sii->pub.ccrev == 0x25)
971             &&
972             ((sih->chip == BCM43236_CHIP_ID
973               || sih->chip == BCM43235_CHIP_ID
974               || sih->chip == BCM43238_CHIP_ID)
975              && (sii->pub.chiprev <= 2))) {
976
977                 if ((cc->chipstatus & CST43236_BP_CLK) != 0) {
978                         uint clkdiv;
979                         clkdiv = R_REG(&cc->clkdiv);
980                         /* otp_clk_div is even number, 120/14 < 9mhz */
981                         clkdiv = (clkdiv & ~CLKD_OTP) | (14 << CLKD_OTP_SHIFT);
982                         W_REG(&cc->clkdiv, clkdiv);
983                         SI_ERROR(("%s: set clkdiv to %x\n", __func__, clkdiv));
984                 }
985                 udelay(10);
986         }
987
988         /* Init nvram from flash if it exists */
989         nvram_init();
990
991         /* Init nvram from sprom/otp if they exist */
992         if (srom_var_init
993             (&sii->pub, bustype, regs, vars, varsz)) {
994                 SI_ERROR(("si_doattach: srom_var_init failed: bad srom\n"));
995                 goto exit;
996         }
997         pvars = vars ? *vars : NULL;
998         ai_nvram_process(sii, pvars);
999
1000         /* === NVRAM, clock is ready === */
1001         cc = (chipcregs_t *) ai_setcore(sih, CC_CORE_ID, 0);
1002         W_REG(&cc->gpiopullup, 0);
1003         W_REG(&cc->gpiopulldown, 0);
1004         ai_setcoreidx(sih, origidx);
1005
1006         /* PMU specific initializations */
1007         if (PMUCTL_ENAB(sih)) {
1008                 u32 xtalfreq;
1009                 si_pmu_init(sih);
1010                 si_pmu_chip_init(sih);
1011                 xtalfreq = getintvar(pvars, "xtalfreq");
1012                 /* If xtalfreq var not available, try to measure it */
1013                 if (xtalfreq == 0)
1014                         xtalfreq = si_pmu_measure_alpclk(sih);
1015                 si_pmu_pll_init(sih, xtalfreq);
1016                 si_pmu_res_init(sih);
1017                 si_pmu_swreg_init(sih);
1018         }
1019
1020         /* setup the GPIO based LED powersave register */
1021         w = getintvar(pvars, "leddc");
1022         if (w == 0)
1023                 w = DEFAULT_GPIOTIMERVAL;
1024         ai_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, gpiotimerval), ~0, w);
1025
1026         if (PCIE(sii)) {
1027                 pcicore_attach(sii->pch, pvars, SI_DOATTACH);
1028         }
1029
1030         if ((sih->chip == BCM43224_CHIP_ID) ||
1031             (sih->chip == BCM43421_CHIP_ID)) {
1032                 /*
1033                  * enable 12 mA drive strenth for 43224 and
1034                  * set chipControl register bit 15
1035                  */
1036                 if (sih->chiprev == 0) {
1037                         SI_MSG(("Applying 43224A0 WARs\n"));
1038                         ai_corereg(sih, SI_CC_IDX,
1039                                    offsetof(chipcregs_t, chipcontrol),
1040                                    CCTRL43224_GPIO_TOGGLE,
1041                                    CCTRL43224_GPIO_TOGGLE);
1042                         si_pmu_chipcontrol(sih, 0, CCTRL_43224A0_12MA_LED_DRIVE,
1043                                            CCTRL_43224A0_12MA_LED_DRIVE);
1044                 }
1045                 if (sih->chiprev >= 1) {
1046                         SI_MSG(("Applying 43224B0+ WARs\n"));
1047                         si_pmu_chipcontrol(sih, 0, CCTRL_43224B0_12MA_LED_DRIVE,
1048                                            CCTRL_43224B0_12MA_LED_DRIVE);
1049                 }
1050         }
1051
1052         if (sih->chip == BCM4313_CHIP_ID) {
1053                 /*
1054                  * enable 12 mA drive strenth for 4313 and
1055                  * set chipControl register bit 1
1056                  */
1057                 SI_MSG(("Applying 4313 WARs\n"));
1058                 si_pmu_chipcontrol(sih, 0, CCTRL_4313_12MA_LED_DRIVE,
1059                                    CCTRL_4313_12MA_LED_DRIVE);
1060         }
1061
1062         if (sih->chip == BCM4331_CHIP_ID) {
1063                 /* Enable Ext PA lines depending on chip package option */
1064                 ai_chipcontrl_epa4331(sih, true);
1065         }
1066
1067         return sii;
1068  exit:
1069         if (sih->bustype == PCI_BUS) {
1070                 if (sii->pch)
1071                         pcicore_deinit(sii->pch);
1072                 sii->pch = NULL;
1073         }
1074
1075         return NULL;
1076 }
1077
1078 /* may be called with core in reset */
1079 void ai_detach(struct si_pub *sih)
1080 {
1081         si_info_t *sii;
1082         uint idx;
1083
1084         struct si_pub *si_local = NULL;
1085         memcpy(&si_local, &sih, sizeof(struct si_pub **));
1086
1087         sii = SI_INFO(sih);
1088
1089         if (sii == NULL)
1090                 return;
1091
1092         if (sih->bustype == SI_BUS)
1093                 for (idx = 0; idx < SI_MAXCORES; idx++)
1094                         if (sii->regs[idx]) {
1095                                 iounmap(sii->regs[idx]);
1096                                 sii->regs[idx] = NULL;
1097                         }
1098
1099         nvram_exit();   /* free up nvram buffers */
1100
1101         if (sih->bustype == PCI_BUS) {
1102                 if (sii->pch)
1103                         pcicore_deinit(sii->pch);
1104                 sii->pch = NULL;
1105         }
1106
1107         if (sii != &ksii)
1108                 kfree(sii);
1109 }
1110
1111 /* register driver interrupt disabling and restoring callback functions */
1112 void
1113 ai_register_intr_callback(struct si_pub *sih, void *intrsoff_fn,
1114                           void *intrsrestore_fn,
1115                           void *intrsenabled_fn, void *intr_arg)
1116 {
1117         si_info_t *sii;
1118
1119         sii = SI_INFO(sih);
1120         sii->intr_arg = intr_arg;
1121         sii->intrsoff_fn = (si_intrsoff_t) intrsoff_fn;
1122         sii->intrsrestore_fn = (si_intrsrestore_t) intrsrestore_fn;
1123         sii->intrsenabled_fn = (si_intrsenabled_t) intrsenabled_fn;
1124         /* save current core id.  when this function called, the current core
1125          * must be the core which provides driver functions(il, et, wl, etc.)
1126          */
1127         sii->dev_coreid = sii->coreid[sii->curidx];
1128 }
1129
1130 void ai_deregister_intr_callback(struct si_pub *sih)
1131 {
1132         si_info_t *sii;
1133
1134         sii = SI_INFO(sih);
1135         sii->intrsoff_fn = NULL;
1136 }
1137
1138 uint ai_coreid(struct si_pub *sih)
1139 {
1140         si_info_t *sii;
1141
1142         sii = SI_INFO(sih);
1143         return sii->coreid[sii->curidx];
1144 }
1145
1146 uint ai_coreidx(struct si_pub *sih)
1147 {
1148         si_info_t *sii;
1149
1150         sii = SI_INFO(sih);
1151         return sii->curidx;
1152 }
1153
1154 bool ai_backplane64(struct si_pub *sih)
1155 {
1156         return (sih->cccaps & CC_CAP_BKPLN64) != 0;
1157 }
1158
1159 /* return index of coreid or BADIDX if not found */
1160 uint ai_findcoreidx(struct si_pub *sih, uint coreid, uint coreunit)
1161 {
1162         si_info_t *sii;
1163         uint found;
1164         uint i;
1165
1166         sii = SI_INFO(sih);
1167
1168         found = 0;
1169
1170         for (i = 0; i < sii->numcores; i++)
1171                 if (sii->coreid[i] == coreid) {
1172                         if (found == coreunit)
1173                                 return i;
1174                         found++;
1175                 }
1176
1177         return BADIDX;
1178 }
1179
1180 /*
1181  * This function changes logical "focus" to the indicated core;
1182  * must be called with interrupts off.
1183  * Moreover, callers should keep interrupts off during switching
1184  * out of and back to d11 core.
1185  */
1186 void *ai_setcore(struct si_pub *sih, uint coreid, uint coreunit)
1187 {
1188         uint idx;
1189
1190         idx = ai_findcoreidx(sih, coreid, coreunit);
1191         if (!GOODIDX(idx))
1192                 return NULL;
1193
1194         return ai_setcoreidx(sih, idx);
1195 }
1196
1197 /* Turn off interrupt as required by ai_setcore, before switch core */
1198 void *ai_switch_core(struct si_pub *sih, uint coreid, uint *origidx,
1199                      uint *intr_val)
1200 {
1201         void *cc;
1202         si_info_t *sii;
1203
1204         sii = SI_INFO(sih);
1205
1206         if (SI_FAST(sii)) {
1207                 /* Overloading the origidx variable to remember the coreid,
1208                  * this works because the core ids cannot be confused with
1209                  * core indices.
1210                  */
1211                 *origidx = coreid;
1212                 if (coreid == CC_CORE_ID)
1213                         return (void *)CCREGS_FAST(sii);
1214                 else if (coreid == sih->buscoretype)
1215                         return (void *)PCIEREGS(sii);
1216         }
1217         INTR_OFF(sii, *intr_val);
1218         *origidx = sii->curidx;
1219         cc = ai_setcore(sih, coreid, 0);
1220         return cc;
1221 }
1222
1223 /* restore coreidx and restore interrupt */
1224 void ai_restore_core(struct si_pub *sih, uint coreid, uint intr_val)
1225 {
1226         si_info_t *sii;
1227
1228         sii = SI_INFO(sih);
1229         if (SI_FAST(sii)
1230             && ((coreid == CC_CORE_ID) || (coreid == sih->buscoretype)))
1231                 return;
1232
1233         ai_setcoreidx(sih, coreid);
1234         INTR_RESTORE(sii, intr_val);
1235 }
1236
1237 void ai_write_wrapperreg(struct si_pub *sih, u32 offset, u32 val)
1238 {
1239         si_info_t *sii = SI_INFO(sih);
1240         u32 *w = (u32 *) sii->curwrap;
1241         W_REG(w + (offset / 4), val);
1242         return;
1243 }
1244
1245 /*
1246  * Switch to 'coreidx', issue a single arbitrary 32bit register mask&set
1247  * operation, switch back to the original core, and return the new value.
1248  *
1249  * When using the silicon backplane, no fiddling with interrupts or core
1250  * switches is needed.
1251  *
1252  * Also, when using pci/pcie, we can optimize away the core switching for pci
1253  * registers and (on newer pci cores) chipcommon registers.
1254  */
1255 uint ai_corereg(struct si_pub *sih, uint coreidx, uint regoff, uint mask,
1256                 uint val)
1257 {
1258         uint origidx = 0;
1259         u32 *r = NULL;
1260         uint w;
1261         uint intr_val = 0;
1262         bool fast = false;
1263         si_info_t *sii;
1264
1265         sii = SI_INFO(sih);
1266
1267         if (coreidx >= SI_MAXCORES)
1268                 return 0;
1269
1270         if (sih->bustype == SI_BUS) {
1271                 /* If internal bus, we can always get at everything */
1272                 fast = true;
1273                 /* map if does not exist */
1274                 if (!sii->regs[coreidx]) {
1275                         sii->regs[coreidx] = REG_MAP(sii->coresba[coreidx],
1276                                                      SI_CORE_SIZE);
1277                 }
1278                 r = (u32 *) ((unsigned char *) sii->regs[coreidx] + regoff);
1279         } else if (sih->bustype == PCI_BUS) {
1280                 /*
1281                  * If pci/pcie, we can get at pci/pcie regs
1282                  * and on newer cores to chipc
1283                  */
1284                 if ((sii->coreid[coreidx] == CC_CORE_ID) && SI_FAST(sii)) {
1285                         /* Chipc registers are mapped at 12KB */
1286
1287                         fast = true;
1288                         r = (u32 *) ((char *)sii->curmap +
1289                                         PCI_16KB0_CCREGS_OFFSET + regoff);
1290                 } else if (sii->pub.buscoreidx == coreidx) {
1291                         /*
1292                          * pci registers are at either in the last 2KB of
1293                          * an 8KB window or, in pcie and pci rev 13 at 8KB
1294                          */
1295                         fast = true;
1296                         if (SI_FAST(sii))
1297                                 r = (u32 *) ((char *)sii->curmap +
1298                                                 PCI_16KB0_PCIREGS_OFFSET +
1299                                                 regoff);
1300                         else
1301                                 r = (u32 *) ((char *)sii->curmap +
1302                                                 ((regoff >= SBCONFIGOFF) ?
1303                                                  PCI_BAR0_PCISBR_OFFSET :
1304                                                  PCI_BAR0_PCIREGS_OFFSET) +
1305                                                 regoff);
1306                 }
1307         }
1308
1309         if (!fast) {
1310                 INTR_OFF(sii, intr_val);
1311
1312                 /* save current core index */
1313                 origidx = ai_coreidx(&sii->pub);
1314
1315                 /* switch core */
1316                 r = (u32 *) ((unsigned char *) ai_setcoreidx(&sii->pub, coreidx)
1317                                 + regoff);
1318         }
1319
1320         /* mask and set */
1321         if (mask || val) {
1322                 w = (R_REG(r) & ~mask) | val;
1323                 W_REG(r, w);
1324         }
1325
1326         /* readback */
1327         w = R_REG(r);
1328
1329         if (!fast) {
1330                 /* restore core index */
1331                 if (origidx != coreidx)
1332                         ai_setcoreidx(&sii->pub, origidx);
1333
1334                 INTR_RESTORE(sii, intr_val);
1335         }
1336
1337         return w;
1338 }
1339
1340 void ai_core_disable(struct si_pub *sih, u32 bits)
1341 {
1342         si_info_t *sii;
1343         u32 dummy;
1344         aidmp_t *ai;
1345
1346         sii = SI_INFO(sih);
1347
1348         ai = sii->curwrap;
1349
1350         /* if core is already in reset, just return */
1351         if (R_REG(&ai->resetctrl) & AIRC_RESET)
1352                 return;
1353
1354         W_REG(&ai->ioctrl, bits);
1355         dummy = R_REG(&ai->ioctrl);
1356         udelay(10);
1357
1358         W_REG(&ai->resetctrl, AIRC_RESET);
1359         udelay(1);
1360 }
1361
1362 /* reset and re-enable a core
1363  * inputs:
1364  * bits - core specific bits that are set during and after reset sequence
1365  * resetbits - core specific bits that are set only during reset sequence
1366  */
1367 void ai_core_reset(struct si_pub *sih, u32 bits, u32 resetbits)
1368 {
1369         si_info_t *sii;
1370         aidmp_t *ai;
1371         u32 dummy;
1372
1373         sii = SI_INFO(sih);
1374         ai = sii->curwrap;
1375
1376         /*
1377          * Must do the disable sequence first to work
1378          * for arbitrary current core state.
1379          */
1380         ai_core_disable(sih, (bits | resetbits));
1381
1382         /*
1383          * Now do the initialization sequence.
1384          */
1385         W_REG(&ai->ioctrl, (bits | SICF_FGC | SICF_CLOCK_EN));
1386         dummy = R_REG(&ai->ioctrl);
1387         W_REG(&ai->resetctrl, 0);
1388         udelay(1);
1389
1390         W_REG(&ai->ioctrl, (bits | SICF_CLOCK_EN));
1391         dummy = R_REG(&ai->ioctrl);
1392         udelay(1);
1393 }
1394
1395 /* return the slow clock source - LPO, XTAL, or PCI */
1396 static uint ai_slowclk_src(si_info_t *sii)
1397 {
1398         chipcregs_t *cc;
1399         u32 val;
1400
1401         if (sii->pub.ccrev < 6) {
1402                 if (sii->pub.bustype == PCI_BUS) {
1403                         pci_read_config_dword(sii->pbus, PCI_GPIO_OUT,
1404                                               &val);
1405                         if (val & PCI_CFG_GPIO_SCS)
1406                                 return SCC_SS_PCI;
1407                 }
1408                 return SCC_SS_XTAL;
1409         } else if (sii->pub.ccrev < 10) {
1410                 cc = (chipcregs_t *) ai_setcoreidx(&sii->pub, sii->curidx);
1411                 return R_REG(&cc->slow_clk_ctl) & SCC_SS_MASK;
1412         } else                  /* Insta-clock */
1413                 return SCC_SS_XTAL;
1414 }
1415
1416 /*
1417 * return the ILP (slowclock) min or max frequency
1418 * precondition: we've established the chip has dynamic clk control
1419 */
1420 static uint ai_slowclk_freq(si_info_t *sii, bool max_freq, chipcregs_t *cc)
1421 {
1422         u32 slowclk;
1423         uint div;
1424
1425         slowclk = ai_slowclk_src(sii);
1426         if (sii->pub.ccrev < 6) {
1427                 if (slowclk == SCC_SS_PCI)
1428                         return max_freq ? (PCIMAXFREQ / 64)
1429                                 : (PCIMINFREQ / 64);
1430                 else
1431                         return max_freq ? (XTALMAXFREQ / 32)
1432                                 : (XTALMINFREQ / 32);
1433         } else if (sii->pub.ccrev < 10) {
1434                 div = 4 *
1435                     (((R_REG(&cc->slow_clk_ctl) & SCC_CD_MASK) >>
1436                       SCC_CD_SHIFT) + 1);
1437                 if (slowclk == SCC_SS_LPO)
1438                         return max_freq ? LPOMAXFREQ : LPOMINFREQ;
1439                 else if (slowclk == SCC_SS_XTAL)
1440                         return max_freq ? (XTALMAXFREQ / div)
1441                                 : (XTALMINFREQ / div);
1442                 else if (slowclk == SCC_SS_PCI)
1443                         return max_freq ? (PCIMAXFREQ / div)
1444                                 : (PCIMINFREQ / div);
1445         } else {
1446                 /* Chipc rev 10 is InstaClock */
1447                 div = R_REG(&cc->system_clk_ctl) >> SYCC_CD_SHIFT;
1448                 div = 4 * (div + 1);
1449                 return max_freq ? XTALMAXFREQ : (XTALMINFREQ / div);
1450         }
1451         return 0;
1452 }
1453
1454 static void ai_clkctl_setdelay(si_info_t *sii, void *chipcregs)
1455 {
1456         chipcregs_t *cc = (chipcregs_t *) chipcregs;
1457         uint slowmaxfreq, pll_delay, slowclk;
1458         uint pll_on_delay, fref_sel_delay;
1459
1460         pll_delay = PLL_DELAY;
1461
1462         /*
1463          * If the slow clock is not sourced by the xtal then
1464          * add the xtal_on_delay since the xtal will also be
1465          * powered down by dynamic clk control logic.
1466          */
1467
1468         slowclk = ai_slowclk_src(sii);
1469         if (slowclk != SCC_SS_XTAL)
1470                 pll_delay += XTAL_ON_DELAY;
1471
1472         /* Starting with 4318 it is ILP that is used for the delays */
1473         slowmaxfreq =
1474             ai_slowclk_freq(sii, (sii->pub.ccrev >= 10) ? false : true, cc);
1475
1476         pll_on_delay = ((slowmaxfreq * pll_delay) + 999999) / 1000000;
1477         fref_sel_delay = ((slowmaxfreq * FREF_DELAY) + 999999) / 1000000;
1478
1479         W_REG(&cc->pll_on_delay, pll_on_delay);
1480         W_REG(&cc->fref_sel_delay, fref_sel_delay);
1481 }
1482
1483 /* initialize power control delay registers */
1484 void ai_clkctl_init(struct si_pub *sih)
1485 {
1486         si_info_t *sii;
1487         uint origidx = 0;
1488         chipcregs_t *cc;
1489         bool fast;
1490
1491         if (!CCCTL_ENAB(sih))
1492                 return;
1493
1494         sii = SI_INFO(sih);
1495         fast = SI_FAST(sii);
1496         if (!fast) {
1497                 origidx = sii->curidx;
1498                 cc = (chipcregs_t *) ai_setcore(sih, CC_CORE_ID, 0);
1499                 if (cc == NULL)
1500                         return;
1501         } else {
1502                 cc = (chipcregs_t *) CCREGS_FAST(sii);
1503                 if (cc == NULL)
1504                         return;
1505         }
1506
1507         /* set all Instaclk chip ILP to 1 MHz */
1508         if (sih->ccrev >= 10)
1509                 SET_REG(&cc->system_clk_ctl, SYCC_CD_MASK,
1510                         (ILP_DIV_1MHZ << SYCC_CD_SHIFT));
1511
1512         ai_clkctl_setdelay(sii, (void *)cc);
1513
1514         if (!fast)
1515                 ai_setcoreidx(sih, origidx);
1516 }
1517
1518 /*
1519  * return the value suitable for writing to the
1520  * dot11 core FAST_PWRUP_DELAY register
1521  */
1522 u16 ai_clkctl_fast_pwrup_delay(struct si_pub *sih)
1523 {
1524         si_info_t *sii;
1525         uint origidx = 0;
1526         chipcregs_t *cc;
1527         uint slowminfreq;
1528         u16 fpdelay;
1529         uint intr_val = 0;
1530         bool fast;
1531
1532         sii = SI_INFO(sih);
1533         if (PMUCTL_ENAB(sih)) {
1534                 INTR_OFF(sii, intr_val);
1535                 fpdelay = si_pmu_fast_pwrup_delay(sih);
1536                 INTR_RESTORE(sii, intr_val);
1537                 return fpdelay;
1538         }
1539
1540         if (!CCCTL_ENAB(sih))
1541                 return 0;
1542
1543         fast = SI_FAST(sii);
1544         fpdelay = 0;
1545         if (!fast) {
1546                 origidx = sii->curidx;
1547                 INTR_OFF(sii, intr_val);
1548                 cc = (chipcregs_t *) ai_setcore(sih, CC_CORE_ID, 0);
1549                 if (cc == NULL)
1550                         goto done;
1551         } else {
1552                 cc = (chipcregs_t *) CCREGS_FAST(sii);
1553                 if (cc == NULL)
1554                         goto done;
1555         }
1556
1557         slowminfreq = ai_slowclk_freq(sii, false, cc);
1558         fpdelay = (((R_REG(&cc->pll_on_delay) + 2) * 1000000) +
1559                    (slowminfreq - 1)) / slowminfreq;
1560
1561  done:
1562         if (!fast) {
1563                 ai_setcoreidx(sih, origidx);
1564                 INTR_RESTORE(sii, intr_val);
1565         }
1566         return fpdelay;
1567 }
1568
1569 /* turn primary xtal and/or pll off/on */
1570 int ai_clkctl_xtal(struct si_pub *sih, uint what, bool on)
1571 {
1572         si_info_t *sii;
1573         u32 in, out, outen;
1574
1575         sii = SI_INFO(sih);
1576
1577         switch (sih->bustype) {
1578
1579         case PCI_BUS:
1580                 /* pcie core doesn't have any mapping to control the xtal pu */
1581                 if (PCIE(sii))
1582                         return -1;
1583
1584                 pci_read_config_dword(sii->pbus, PCI_GPIO_IN, &in);
1585                 pci_read_config_dword(sii->pbus, PCI_GPIO_OUT, &out);
1586                 pci_read_config_dword(sii->pbus, PCI_GPIO_OUTEN, &outen);
1587
1588                 /*
1589                  * Avoid glitching the clock if GPRS is already using it.
1590                  * We can't actually read the state of the PLLPD so we infer it
1591                  * by the value of XTAL_PU which *is* readable via gpioin.
1592                  */
1593                 if (on && (in & PCI_CFG_GPIO_XTAL))
1594                         return 0;
1595
1596                 if (what & XTAL)
1597                         outen |= PCI_CFG_GPIO_XTAL;
1598                 if (what & PLL)
1599                         outen |= PCI_CFG_GPIO_PLL;
1600
1601                 if (on) {
1602                         /* turn primary xtal on */
1603                         if (what & XTAL) {
1604                                 out |= PCI_CFG_GPIO_XTAL;
1605                                 if (what & PLL)
1606                                         out |= PCI_CFG_GPIO_PLL;
1607                                 pci_write_config_dword(sii->pbus,
1608                                                        PCI_GPIO_OUT, out);
1609                                 pci_write_config_dword(sii->pbus,
1610                                                        PCI_GPIO_OUTEN, outen);
1611                                 udelay(XTAL_ON_DELAY);
1612                         }
1613
1614                         /* turn pll on */
1615                         if (what & PLL) {
1616                                 out &= ~PCI_CFG_GPIO_PLL;
1617                                 pci_write_config_dword(sii->pbus,
1618                                                        PCI_GPIO_OUT, out);
1619                                 mdelay(2);
1620                         }
1621                 } else {
1622                         if (what & XTAL)
1623                                 out &= ~PCI_CFG_GPIO_XTAL;
1624                         if (what & PLL)
1625                                 out |= PCI_CFG_GPIO_PLL;
1626                         pci_write_config_dword(sii->pbus,
1627                                                PCI_GPIO_OUT, out);
1628                         pci_write_config_dword(sii->pbus,
1629                                                PCI_GPIO_OUTEN, outen);
1630                 }
1631
1632         default:
1633                 return -1;
1634         }
1635
1636         return 0;
1637 }
1638
1639 /*
1640  *  clock control policy function throught chipcommon
1641  *
1642  *    set dynamic clk control mode (forceslow, forcefast, dynamic)
1643  *    returns true if we are forcing fast clock
1644  *    this is a wrapper over the next internal function
1645  *      to allow flexible policy settings for outside caller
1646  */
1647 bool ai_clkctl_cc(struct si_pub *sih, uint mode)
1648 {
1649         si_info_t *sii;
1650
1651         sii = SI_INFO(sih);
1652
1653         /* chipcommon cores prior to rev6 don't support dynamic clock control */
1654         if (sih->ccrev < 6)
1655                 return false;
1656
1657         if (PCI_FORCEHT(sii))
1658                 return mode == CLK_FAST;
1659
1660         return _ai_clkctl_cc(sii, mode);
1661 }
1662
1663 /* clk control mechanism through chipcommon, no policy checking */
1664 static bool _ai_clkctl_cc(si_info_t *sii, uint mode)
1665 {
1666         uint origidx = 0;
1667         chipcregs_t *cc;
1668         u32 scc;
1669         uint intr_val = 0;
1670         bool fast = SI_FAST(sii);
1671
1672         /* chipcommon cores prior to rev6 don't support dynamic clock control */
1673         if (sii->pub.ccrev < 6)
1674                 return false;
1675
1676         if (!fast) {
1677                 INTR_OFF(sii, intr_val);
1678                 origidx = sii->curidx;
1679
1680                 if ((sii->pub.bustype == SI_BUS) &&
1681                     ai_setcore(&sii->pub, MIPS33_CORE_ID, 0) &&
1682                     (ai_corerev(&sii->pub) <= 7) && (sii->pub.ccrev >= 10))
1683                         goto done;
1684
1685                 cc = (chipcregs_t *) ai_setcore(&sii->pub, CC_CORE_ID, 0);
1686         } else {
1687                 cc = (chipcregs_t *) CCREGS_FAST(sii);
1688                 if (cc == NULL)
1689                         goto done;
1690         }
1691
1692         if (!CCCTL_ENAB(&sii->pub) && (sii->pub.ccrev < 20))
1693                 goto done;
1694
1695         switch (mode) {
1696         case CLK_FAST:          /* FORCEHT, fast (pll) clock */
1697                 if (sii->pub.ccrev < 10) {
1698                         /*
1699                          * don't forget to force xtal back
1700                          * on before we clear SCC_DYN_XTAL..
1701                          */
1702                         ai_clkctl_xtal(&sii->pub, XTAL, ON);
1703                         SET_REG(&cc->slow_clk_ctl,
1704                                 (SCC_XC | SCC_FS | SCC_IP), SCC_IP);
1705                 } else if (sii->pub.ccrev < 20) {
1706                         OR_REG(&cc->system_clk_ctl, SYCC_HR);
1707                 } else {
1708                         OR_REG(&cc->clk_ctl_st, CCS_FORCEHT);
1709                 }
1710
1711                 /* wait for the PLL */
1712                 if (PMUCTL_ENAB(&sii->pub)) {
1713                         u32 htavail = CCS_HTAVAIL;
1714                         SPINWAIT(((R_REG(&cc->clk_ctl_st) & htavail)
1715                                   == 0), PMU_MAX_TRANSITION_DLY);
1716                 } else {
1717                         udelay(PLL_DELAY);
1718                 }
1719                 break;
1720
1721         case CLK_DYNAMIC:       /* enable dynamic clock control */
1722                 if (sii->pub.ccrev < 10) {
1723                         scc = R_REG(&cc->slow_clk_ctl);
1724                         scc &= ~(SCC_FS | SCC_IP | SCC_XC);
1725                         if ((scc & SCC_SS_MASK) != SCC_SS_XTAL)
1726                                 scc |= SCC_XC;
1727                         W_REG(&cc->slow_clk_ctl, scc);
1728
1729                         /*
1730                          * for dynamic control, we have to
1731                          * release our xtal_pu "force on"
1732                          */
1733                         if (scc & SCC_XC)
1734                                 ai_clkctl_xtal(&sii->pub, XTAL, OFF);
1735                 } else if (sii->pub.ccrev < 20) {
1736                         /* Instaclock */
1737                         AND_REG(&cc->system_clk_ctl, ~SYCC_HR);
1738                 } else {
1739                         AND_REG(&cc->clk_ctl_st, ~CCS_FORCEHT);
1740                 }
1741                 break;
1742
1743         default:
1744                 break;
1745         }
1746
1747  done:
1748         if (!fast) {
1749                 ai_setcoreidx(&sii->pub, origidx);
1750                 INTR_RESTORE(sii, intr_val);
1751         }
1752         return mode == CLK_FAST;
1753 }
1754
1755 /* Build device path. Support SI, PCI, and JTAG for now. */
1756 int ai_devpath(struct si_pub *sih, char *path, int size)
1757 {
1758         int slen;
1759
1760         if (!path || size <= 0)
1761                 return -1;
1762
1763         switch (sih->bustype) {
1764         case SI_BUS:
1765         case JTAG_BUS:
1766                 slen = snprintf(path, (size_t) size, "sb/%u/", ai_coreidx(sih));
1767                 break;
1768         case PCI_BUS:
1769                 slen = snprintf(path, (size_t) size, "pci/%u/%u/",
1770                         ((struct pci_dev *)((SI_INFO(sih))->pbus))->bus->number,
1771                         PCI_SLOT(
1772                             ((struct pci_dev *)((SI_INFO(sih))->pbus))->devfn));
1773                 break;
1774
1775         default:
1776                 slen = -1;
1777                 break;
1778         }
1779
1780         if (slen < 0 || slen >= size) {
1781                 path[0] = '\0';
1782                 return -1;
1783         }
1784
1785         return 0;
1786 }
1787
1788 /* Get a variable, but only if it has a devpath prefix */
1789 char *ai_getdevpathvar(struct si_pub *sih, const char *name)
1790 {
1791         char varname[SI_DEVPATH_BUFSZ + 32];
1792
1793         ai_devpathvar(sih, varname, sizeof(varname), name);
1794
1795         return getvar(NULL, varname);
1796 }
1797
1798 /* Get a variable, but only if it has a devpath prefix */
1799 int ai_getdevpathintvar(struct si_pub *sih, const char *name)
1800 {
1801 #if defined(BCMBUSTYPE) && (BCMBUSTYPE == SI_BUS)
1802         return getintvar(NULL, name);
1803 #else
1804         char varname[SI_DEVPATH_BUFSZ + 32];
1805
1806         ai_devpathvar(sih, varname, sizeof(varname), name);
1807
1808         return getintvar(NULL, varname);
1809 #endif
1810 }
1811
1812 char *ai_getnvramflvar(struct si_pub *sih, const char *name)
1813 {
1814         return getvar(NULL, name);
1815 }
1816
1817 /* Concatenate the dev path with a varname into the given 'var' buffer
1818  * and return the 'var' pointer. Nothing is done to the arguments if
1819  * len == 0 or var is NULL, var is still returned. On overflow, the
1820  * first char will be set to '\0'.
1821  */
1822 static char *ai_devpathvar(struct si_pub *sih, char *var, int len,
1823                            const char *name)
1824 {
1825         uint path_len;
1826
1827         if (!var || len <= 0)
1828                 return var;
1829
1830         if (ai_devpath(sih, var, len) == 0) {
1831                 path_len = strlen(var);
1832
1833                 if (strlen(name) + 1 > (uint) (len - path_len))
1834                         var[0] = '\0';
1835                 else
1836                         strncpy(var + path_len, name, len - path_len - 1);
1837         }
1838
1839         return var;
1840 }
1841
1842 /* return true if PCIE capability exists in the pci config space */
1843 static __used bool ai_ispcie(si_info_t *sii)
1844 {
1845         u8 cap_ptr;
1846
1847         if (sii->pub.bustype != PCI_BUS)
1848                 return false;
1849
1850         cap_ptr =
1851             pcicore_find_pci_capability(sii->pbus, PCI_CAP_ID_EXP, NULL,
1852                                         NULL);
1853         if (!cap_ptr)
1854                 return false;
1855
1856         return true;
1857 }
1858
1859 bool ai_pci_war16165(struct si_pub *sih)
1860 {
1861         si_info_t *sii;
1862
1863         sii = SI_INFO(sih);
1864
1865         return PCI(sii) && (sih->buscorerev <= 10);
1866 }
1867
1868 void ai_pci_up(struct si_pub *sih)
1869 {
1870         si_info_t *sii;
1871
1872         sii = SI_INFO(sih);
1873
1874         /* if not pci bus, we're done */
1875         if (sih->bustype != PCI_BUS)
1876                 return;
1877
1878         if (PCI_FORCEHT(sii))
1879                 _ai_clkctl_cc(sii, CLK_FAST);
1880
1881         if (PCIE(sii))
1882                 pcicore_up(sii->pch, SI_PCIUP);
1883
1884 }
1885
1886 /* Unconfigure and/or apply various WARs when system is going to sleep mode */
1887 void ai_pci_sleep(struct si_pub *sih)
1888 {
1889         si_info_t *sii;
1890
1891         sii = SI_INFO(sih);
1892
1893         pcicore_sleep(sii->pch);
1894 }
1895
1896 /* Unconfigure and/or apply various WARs when going down */
1897 void ai_pci_down(struct si_pub *sih)
1898 {
1899         si_info_t *sii;
1900
1901         sii = SI_INFO(sih);
1902
1903         /* if not pci bus, we're done */
1904         if (sih->bustype != PCI_BUS)
1905                 return;
1906
1907         /* release FORCEHT since chip is going to "down" state */
1908         if (PCI_FORCEHT(sii))
1909                 _ai_clkctl_cc(sii, CLK_DYNAMIC);
1910
1911         pcicore_down(sii->pch, SI_PCIDOWN);
1912 }
1913
1914 /*
1915  * Configure the pci core for pci client (NIC) action
1916  * coremask is the bitvec of cores by index to be enabled.
1917  */
1918 void ai_pci_setup(struct si_pub *sih, uint coremask)
1919 {
1920         si_info_t *sii;
1921         void *regs = NULL;
1922         u32 siflag = 0, w;
1923         uint idx = 0;
1924
1925         sii = SI_INFO(sih);
1926
1927         if (sii->pub.bustype != PCI_BUS)
1928                 return;
1929
1930         if (PCI(sii)) {
1931                 /* get current core index */
1932                 idx = sii->curidx;
1933
1934                 /* we interrupt on this backplane flag number */
1935                 siflag = ai_flag(sih);
1936
1937                 /* switch over to pci core */
1938                 regs = ai_setcoreidx(sih, sii->pub.buscoreidx);
1939         }
1940
1941         /*
1942          * Enable sb->pci interrupts.  Assume
1943          * PCI rev 2.3 support was added in pci core rev 6 and things changed..
1944          */
1945         if (PCIE(sii) || (PCI(sii) && ((sii->pub.buscorerev) >= 6))) {
1946                 /* pci config write to set this core bit in PCIIntMask */
1947                 pci_read_config_dword(sii->pbus, PCI_INT_MASK, &w);
1948                 w |= (coremask << PCI_SBIM_SHIFT);
1949                 pci_write_config_dword(sii->pbus, PCI_INT_MASK, w);
1950         } else {
1951                 /* set sbintvec bit for our flag number */
1952                 ai_setint(sih, siflag);
1953         }
1954
1955         if (PCI(sii)) {
1956                 pcicore_pci_setup(sii->pch, regs);
1957
1958                 /* switch back to previous core */
1959                 ai_setcoreidx(sih, idx);
1960         }
1961 }
1962
1963 /*
1964  * Fixup SROMless PCI device's configuration.
1965  * The current core may be changed upon return.
1966  */
1967 int ai_pci_fixcfg(struct si_pub *sih)
1968 {
1969         uint origidx;
1970         void *regs = NULL;
1971
1972         si_info_t *sii = SI_INFO(sih);
1973
1974         /* Fixup PI in SROM shadow area to enable the correct PCI core access */
1975         /* save the current index */
1976         origidx = ai_coreidx(&sii->pub);
1977
1978         /* check 'pi' is correct and fix it if not */
1979         regs = ai_setcore(&sii->pub, sii->pub.buscoretype, 0);
1980         pcicore_fixcfg(sii->pch, regs);
1981
1982         /* restore the original index */
1983         ai_setcoreidx(&sii->pub, origidx);
1984
1985         pcicore_hwup(sii->pch);
1986         return 0;
1987 }
1988
1989 /* mask&set gpiocontrol bits */
1990 u32 ai_gpiocontrol(struct si_pub *sih, u32 mask, u32 val, u8 priority)
1991 {
1992         uint regoff;
1993
1994         regoff = 0;
1995
1996         /* gpios could be shared on router platforms
1997          * ignore reservation if it's high priority (e.g., test apps)
1998          */
1999         if ((priority != GPIO_HI_PRIORITY) &&
2000             (sih->bustype == SI_BUS) && (val || mask)) {
2001                 mask = priority ? (ai_gpioreservation & mask) :
2002                     ((ai_gpioreservation | mask) & ~(ai_gpioreservation));
2003                 val &= mask;
2004         }
2005
2006         regoff = offsetof(chipcregs_t, gpiocontrol);
2007         return ai_corereg(sih, SI_CC_IDX, regoff, mask, val);
2008 }
2009
2010 void ai_chipcontrl_epa4331(struct si_pub *sih, bool on)
2011 {
2012         si_info_t *sii;
2013         chipcregs_t *cc;
2014         uint origidx;
2015         u32 val;
2016
2017         sii = SI_INFO(sih);
2018         origidx = ai_coreidx(sih);
2019
2020         cc = (chipcregs_t *) ai_setcore(sih, CC_CORE_ID, 0);
2021
2022         val = R_REG(&cc->chipcontrol);
2023
2024         if (on) {
2025                 if (sih->chippkg == 9 || sih->chippkg == 0xb) {
2026                         /* Ext PA Controls for 4331 12x9 Package */
2027                         W_REG(&cc->chipcontrol, val |
2028                               (CCTRL4331_EXTPA_EN |
2029                                CCTRL4331_EXTPA_ON_GPIO2_5));
2030                 } else {
2031                         /* Ext PA Controls for 4331 12x12 Package */
2032                         W_REG(&cc->chipcontrol,
2033                               val | (CCTRL4331_EXTPA_EN));
2034                 }
2035         } else {
2036                 val &= ~(CCTRL4331_EXTPA_EN | CCTRL4331_EXTPA_ON_GPIO2_5);
2037                 W_REG(&cc->chipcontrol, val);
2038         }
2039
2040         ai_setcoreidx(sih, origidx);
2041 }
2042
2043 /* Enable BT-COEX & Ex-PA for 4313 */
2044 void ai_epa_4313war(struct si_pub *sih)
2045 {
2046         si_info_t *sii;
2047         chipcregs_t *cc;
2048         uint origidx;
2049
2050         sii = SI_INFO(sih);
2051         origidx = ai_coreidx(sih);
2052
2053         cc = (chipcregs_t *) ai_setcore(sih, CC_CORE_ID, 0);
2054
2055         /* EPA Fix */
2056         W_REG(&cc->gpiocontrol,
2057               R_REG(&cc->gpiocontrol) | GPIO_CTRL_EPA_EN_MASK);
2058
2059         ai_setcoreidx(sih, origidx);
2060 }
2061
2062 /* check if the device is removed */
2063 bool ai_deviceremoved(struct si_pub *sih)
2064 {
2065         u32 w;
2066         si_info_t *sii;
2067
2068         sii = SI_INFO(sih);
2069
2070         switch (sih->bustype) {
2071         case PCI_BUS:
2072                 pci_read_config_dword(sii->pbus, PCI_VENDOR_ID, &w);
2073                 if ((w & 0xFFFF) != PCI_VENDOR_ID_BROADCOM)
2074                         return true;
2075                 break;
2076         }
2077         return false;
2078 }
2079
2080 bool ai_is_sprom_available(struct si_pub *sih)
2081 {
2082         if (sih->ccrev >= 31) {
2083                 si_info_t *sii;
2084                 uint origidx;
2085                 chipcregs_t *cc;
2086                 u32 sromctrl;
2087
2088                 if ((sih->cccaps & CC_CAP_SROM) == 0)
2089                         return false;
2090
2091                 sii = SI_INFO(sih);
2092                 origidx = sii->curidx;
2093                 cc = ai_setcoreidx(sih, SI_CC_IDX);
2094                 sromctrl = R_REG(&cc->sromcontrol);
2095                 ai_setcoreidx(sih, origidx);
2096                 return sromctrl & SRC_PRESENT;
2097         }
2098
2099         switch (sih->chip) {
2100         case BCM4329_CHIP_ID:
2101                 return (sih->chipst & CST4329_SPROM_SEL) != 0;
2102         case BCM4319_CHIP_ID:
2103                 return (sih->chipst & CST4319_SPROM_SEL) != 0;
2104         case BCM4336_CHIP_ID:
2105                 return (sih->chipst & CST4336_SPROM_PRESENT) != 0;
2106         case BCM4330_CHIP_ID:
2107                 return (sih->chipst & CST4330_SPROM_PRESENT) != 0;
2108         case BCM4313_CHIP_ID:
2109                 return (sih->chipst & CST4313_SPROM_PRESENT) != 0;
2110         case BCM4331_CHIP_ID:
2111                 return (sih->chipst & CST4331_SPROM_PRESENT) != 0;
2112         default:
2113                 return true;
2114         }
2115 }
2116
2117 bool ai_is_otp_disabled(struct si_pub *sih)
2118 {
2119         switch (sih->chip) {
2120         case BCM4329_CHIP_ID:
2121                 return (sih->chipst & CST4329_SPROM_OTP_SEL_MASK) ==
2122                     CST4329_OTP_PWRDN;
2123         case BCM4319_CHIP_ID:
2124                 return (sih->chipst & CST4319_SPROM_OTP_SEL_MASK) ==
2125                     CST4319_OTP_PWRDN;
2126         case BCM4336_CHIP_ID:
2127                 return (sih->chipst & CST4336_OTP_PRESENT) == 0;
2128         case BCM4330_CHIP_ID:
2129                 return (sih->chipst & CST4330_OTP_PRESENT) == 0;
2130         case BCM4313_CHIP_ID:
2131                 return (sih->chipst & CST4313_OTP_PRESENT) == 0;
2132                 /* These chips always have their OTP on */
2133         case BCM43224_CHIP_ID:
2134         case BCM43225_CHIP_ID:
2135         case BCM43421_CHIP_ID:
2136         case BCM43235_CHIP_ID:
2137         case BCM43236_CHIP_ID:
2138         case BCM43238_CHIP_ID:
2139         case BCM4331_CHIP_ID:
2140         default:
2141                 return false;
2142         }
2143 }
2144
2145 bool ai_is_otp_powered(struct si_pub *sih)
2146 {
2147         if (PMUCTL_ENAB(sih))
2148                 return si_pmu_is_otp_powered(sih);
2149         return true;
2150 }
2151
2152 void ai_otp_power(struct si_pub *sih, bool on)
2153 {
2154         if (PMUCTL_ENAB(sih))
2155                 si_pmu_otp_power(sih, on);
2156         udelay(1000);
2157 }