]> git.karo-electronics.de Git - mv-sheeva.git/blob - drivers/staging/brcm80211/brcmsmac/aiutils.c
43320b480e4246b36b4bb062c7d23f62eb5e3584
[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 <bcmutils.h>
24 #include <aiutils.h>
25 #include <bcmsoc.h>
26 #include <sbchipc.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(si_t *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(si_t *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(si_t *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(si_t *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(si_t *sih)
497 {
498         return 2;
499 }
500
501 /* Return the address of the nth address space in the current core */
502 u32 ai_addrspace(si_t *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(si_t *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(si_t *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(si_t *sih, int siflag)
555 {
556 }
557
558 uint ai_corevendor(si_t *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(si_t *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(si_t *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(si_t *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(si_t *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(si_t *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(si_t *sih, char *var, int len, const char *name);
671 static bool _ai_clkctl_cc(si_info_t *sii, uint mode);
672 static bool ai_ispcie(si_info_t *sii);
673
674 /* global variable to indicate reservation/release of gpio's */
675 static u32 ai_gpioreservation;
676
677 /*
678  * Allocate a si handle.
679  * devid - pci device id (used to determine chip#)
680  * osh - opaque OS handle
681  * regs - virtual address of initial core registers
682  * bustype - pci/sb/sdio/etc
683  * vars - pointer to a pointer area for "environment" variables
684  * varsz - pointer to int to return the size of the vars
685  */
686 si_t *ai_attach(uint devid, void *regs, uint bustype,
687                 void *sdh, char **vars, uint *varsz)
688 {
689         si_info_t *sii;
690
691         /* alloc si_info_t */
692         sii = kmalloc(sizeof(si_info_t), GFP_ATOMIC);
693         if (sii == NULL) {
694                 SI_ERROR(("si_attach: malloc failed!\n"));
695                 return NULL;
696         }
697
698         if (ai_doattach(sii, devid, regs, bustype, sdh, vars, varsz) ==
699             NULL) {
700                 kfree(sii);
701                 return NULL;
702         }
703         sii->vars = vars ? *vars : NULL;
704         sii->varsz = varsz ? *varsz : 0;
705
706         return (si_t *) sii;
707 }
708
709 /* global kernel resource */
710 static si_info_t ksii;
711
712 static bool ai_buscore_prep(si_info_t *sii, uint bustype, uint devid,
713                             void *sdh)
714 {
715         /* kludge to enable the clock on the 4306 which lacks a slowclock */
716         if (bustype == PCI_BUS && !ai_ispcie(sii))
717                 ai_clkctl_xtal(&sii->pub, XTAL | PLL, ON);
718         return true;
719 }
720
721 static bool ai_buscore_setup(si_info_t *sii, chipcregs_t *cc, uint bustype,
722                              u32 savewin, uint *origidx, void *regs)
723 {
724         bool pci, pcie;
725         uint i;
726         uint pciidx, pcieidx, pcirev, pcierev;
727
728         cc = ai_setcoreidx(&sii->pub, SI_CC_IDX);
729
730         /* get chipcommon rev */
731         sii->pub.ccrev = (int)ai_corerev(&sii->pub);
732
733         /* get chipcommon chipstatus */
734         if (sii->pub.ccrev >= 11)
735                 sii->pub.chipst = R_REG(&cc->chipstatus);
736
737         /* get chipcommon capabilites */
738         sii->pub.cccaps = R_REG(&cc->capabilities);
739         /* get chipcommon extended capabilities */
740
741         if (sii->pub.ccrev >= 35)
742                 sii->pub.cccaps_ext = R_REG(&cc->capabilities_ext);
743
744         /* get pmu rev and caps */
745         if (sii->pub.cccaps & CC_CAP_PMU) {
746                 sii->pub.pmucaps = R_REG(&cc->pmucapabilities);
747                 sii->pub.pmurev = sii->pub.pmucaps & PCAP_REV_MASK;
748         }
749
750         /* figure out bus/orignal core idx */
751         sii->pub.buscoretype = NODEV_CORE_ID;
752         sii->pub.buscorerev = NOREV;
753         sii->pub.buscoreidx = BADIDX;
754
755         pci = pcie = false;
756         pcirev = pcierev = NOREV;
757         pciidx = pcieidx = BADIDX;
758
759         for (i = 0; i < sii->numcores; i++) {
760                 uint cid, crev;
761
762                 ai_setcoreidx(&sii->pub, i);
763                 cid = ai_coreid(&sii->pub);
764                 crev = ai_corerev(&sii->pub);
765
766                 /* Display cores found */
767                 SI_VMSG(("CORE[%d]: id 0x%x rev %d base 0x%x regs 0x%p\n",
768                          i, cid, crev, sii->coresba[i], sii->regs[i]));
769
770                 if (bustype == PCI_BUS) {
771                         if (cid == PCI_CORE_ID) {
772                                 pciidx = i;
773                                 pcirev = crev;
774                                 pci = true;
775                         } else if (cid == PCIE_CORE_ID) {
776                                 pcieidx = i;
777                                 pcierev = crev;
778                                 pcie = true;
779                         }
780                 }
781
782                 /* find the core idx before entering this func. */
783                 if ((savewin && (savewin == sii->coresba[i])) ||
784                     (regs == sii->regs[i]))
785                         *origidx = i;
786         }
787
788         if (pci && pcie) {
789                 if (ai_ispcie(sii))
790                         pci = false;
791                 else
792                         pcie = false;
793         }
794         if (pci) {
795                 sii->pub.buscoretype = PCI_CORE_ID;
796                 sii->pub.buscorerev = pcirev;
797                 sii->pub.buscoreidx = pciidx;
798         } else if (pcie) {
799                 sii->pub.buscoretype = PCIE_CORE_ID;
800                 sii->pub.buscorerev = pcierev;
801                 sii->pub.buscoreidx = pcieidx;
802         }
803
804         SI_VMSG(("Buscore id/type/rev %d/0x%x/%d\n", sii->pub.buscoreidx,
805                  sii->pub.buscoretype, sii->pub.buscorerev));
806
807         /* fixup necessary chip/core configurations */
808         if (sii->pub.bustype == PCI_BUS) {
809                 if (SI_FAST(sii)) {
810                         if (!sii->pch) {
811                                 sii->pch = (void *)pcicore_init(
812                                         &sii->pub, sii->pbus,
813                                         (void *)PCIEREGS(sii));
814                                 if (sii->pch == NULL)
815                                         return false;
816                         }
817                 }
818                 if (ai_pci_fixcfg(&sii->pub)) {
819                         SI_ERROR(("si_doattach: si_pci_fixcfg failed\n"));
820                         return false;
821                 }
822         }
823
824         /* return to the original core */
825         ai_setcoreidx(&sii->pub, *origidx);
826
827         return true;
828 }
829
830 static __used void ai_nvram_process(si_info_t *sii, char *pvars)
831 {
832         uint w = 0;
833
834         /* get boardtype and boardrev */
835         switch (sii->pub.bustype) {
836         case PCI_BUS:
837                 /* do a pci config read to get subsystem id and subvendor id */
838                 pci_read_config_dword(sii->pbus, PCI_SUBSYSTEM_VENDOR_ID, &w);
839                 /* Let nvram variables override subsystem Vend/ID */
840                 sii->pub.boardvendor = (u16)ai_getdevpathintvar(&sii->pub,
841                         "boardvendor");
842                 if (sii->pub.boardvendor == 0)
843                         sii->pub.boardvendor = w & 0xffff;
844                 else
845                         SI_ERROR(("Overriding boardvendor: 0x%x instead of "
846                                   "0x%x\n", sii->pub.boardvendor, w & 0xffff));
847                 sii->pub.boardtype = (u16)ai_getdevpathintvar(&sii->pub,
848                         "boardtype");
849                 if (sii->pub.boardtype == 0)
850                         sii->pub.boardtype = (w >> 16) & 0xffff;
851                 else
852                         SI_ERROR(("Overriding boardtype: 0x%x instead of 0x%x\n"
853                                   , sii->pub.boardtype, (w >> 16) & 0xffff));
854                 break;
855
856                 sii->pub.boardvendor = getintvar(pvars, "manfid");
857                 sii->pub.boardtype = getintvar(pvars, "prodid");
858                 break;
859
860         case SI_BUS:
861         case JTAG_BUS:
862                 sii->pub.boardvendor = PCI_VENDOR_ID_BROADCOM;
863                 sii->pub.boardtype = getintvar(pvars, "prodid");
864                 if (pvars == NULL || (sii->pub.boardtype == 0)) {
865                         sii->pub.boardtype = getintvar(NULL, "boardtype");
866                         if (sii->pub.boardtype == 0)
867                                 sii->pub.boardtype = 0xffff;
868                 }
869                 break;
870         }
871
872         if (sii->pub.boardtype == 0) {
873                 SI_ERROR(("si_doattach: unknown board type\n"));
874         }
875
876         sii->pub.boardflags = getintvar(pvars, "boardflags");
877 }
878
879 static si_info_t *ai_doattach(si_info_t *sii, uint devid,
880                               void *regs, uint bustype, void *pbus,
881                               char **vars, uint *varsz)
882 {
883         struct si_pub *sih = &sii->pub;
884         u32 w, savewin;
885         chipcregs_t *cc;
886         char *pvars = NULL;
887         uint socitype;
888         uint origidx;
889
890         memset((unsigned char *) sii, 0, sizeof(si_info_t));
891
892         savewin = 0;
893
894         sih->buscoreidx = BADIDX;
895
896         sii->curmap = regs;
897         sii->pbus = pbus;
898
899         /* check to see if we are a si core mimic'ing a pci core */
900         if (bustype == PCI_BUS) {
901                 pci_read_config_dword(sii->pbus, PCI_SPROM_CONTROL,  &w);
902                 if (w == 0xffffffff) {
903                         SI_ERROR(("%s: incoming bus is PCI but it's a lie, "
904                                 " switching to SI devid:0x%x\n",
905                                 __func__, devid));
906                         bustype = SI_BUS;
907                 }
908         }
909
910         /* find Chipcommon address */
911         if (bustype == PCI_BUS) {
912                 pci_read_config_dword(sii->pbus, PCI_BAR0_WIN, &savewin);
913                 if (!GOODCOREADDR(savewin, SI_ENUM_BASE))
914                         savewin = SI_ENUM_BASE;
915                 pci_write_config_dword(sii->pbus, PCI_BAR0_WIN,
916                                        SI_ENUM_BASE);
917                 cc = (chipcregs_t *) regs;
918         } else {
919                 cc = (chipcregs_t *) REG_MAP(SI_ENUM_BASE, SI_CORE_SIZE);
920         }
921
922         sih->bustype = bustype;
923
924         /* bus/core/clk setup for register access */
925         if (!ai_buscore_prep(sii, bustype, devid, pbus)) {
926                 SI_ERROR(("si_doattach: si_core_clk_prep failed %d\n",
927                           bustype));
928                 return NULL;
929         }
930
931         /*
932          * ChipID recognition.
933          *   We assume we can read chipid at offset 0 from the regs arg.
934          *   If we add other chiptypes (or if we need to support old sdio
935          *   hosts w/o chipcommon), some way of recognizing them needs to
936          *   be added here.
937          */
938         w = R_REG(&cc->chipid);
939         socitype = (w & CID_TYPE_MASK) >> CID_TYPE_SHIFT;
940         /* Might as wll fill in chip id rev & pkg */
941         sih->chip = w & CID_ID_MASK;
942         sih->chiprev = (w & CID_REV_MASK) >> CID_REV_SHIFT;
943         sih->chippkg = (w & CID_PKG_MASK) >> CID_PKG_SHIFT;
944
945         sih->issim = IS_SIM(sih->chippkg);
946
947         /* scan for cores */
948         if (socitype == SOCI_AI) {
949                 SI_MSG(("Found chip type AI (0x%08x)\n", w));
950                 /* pass chipc address instead of original core base */
951                 ai_scan(&sii->pub, (void *)cc, devid);
952         } else {
953                 SI_ERROR(("Found chip of unknown type (0x%08x)\n", w));
954                 return NULL;
955         }
956         /* no cores found, bail out */
957         if (sii->numcores == 0) {
958                 SI_ERROR(("si_doattach: could not find any cores\n"));
959                 return NULL;
960         }
961         /* bus/core/clk setup */
962         origidx = SI_CC_IDX;
963         if (!ai_buscore_setup(sii, cc, bustype, savewin, &origidx, regs)) {
964                 SI_ERROR(("si_doattach: si_buscore_setup failed\n"));
965                 goto exit;
966         }
967
968         /* assume current core is CC */
969         if ((sii->pub.ccrev == 0x25)
970             &&
971             ((sih->chip == BCM43236_CHIP_ID
972               || sih->chip == BCM43235_CHIP_ID
973               || sih->chip == BCM43238_CHIP_ID)
974              && (sii->pub.chiprev <= 2))) {
975
976                 if ((cc->chipstatus & CST43236_BP_CLK) != 0) {
977                         uint clkdiv;
978                         clkdiv = R_REG(&cc->clkdiv);
979                         /* otp_clk_div is even number, 120/14 < 9mhz */
980                         clkdiv = (clkdiv & ~CLKD_OTP) | (14 << CLKD_OTP_SHIFT);
981                         W_REG(&cc->clkdiv, clkdiv);
982                         SI_ERROR(("%s: set clkdiv to %x\n", __func__, clkdiv));
983                 }
984                 udelay(10);
985         }
986
987         /* Init nvram from flash if it exists */
988         nvram_init();
989
990         /* Init nvram from sprom/otp if they exist */
991         if (srom_var_init
992             (&sii->pub, bustype, regs, vars, varsz)) {
993                 SI_ERROR(("si_doattach: srom_var_init failed: bad srom\n"));
994                 goto exit;
995         }
996         pvars = vars ? *vars : NULL;
997         ai_nvram_process(sii, pvars);
998
999         /* === NVRAM, clock is ready === */
1000         cc = (chipcregs_t *) ai_setcore(sih, CC_CORE_ID, 0);
1001         W_REG(&cc->gpiopullup, 0);
1002         W_REG(&cc->gpiopulldown, 0);
1003         ai_setcoreidx(sih, origidx);
1004
1005         /* PMU specific initializations */
1006         if (PMUCTL_ENAB(sih)) {
1007                 u32 xtalfreq;
1008                 si_pmu_init(sih);
1009                 si_pmu_chip_init(sih);
1010                 xtalfreq = getintvar(pvars, "xtalfreq");
1011                 /* If xtalfreq var not available, try to measure it */
1012                 if (xtalfreq == 0)
1013                         xtalfreq = si_pmu_measure_alpclk(sih);
1014                 si_pmu_pll_init(sih, xtalfreq);
1015                 si_pmu_res_init(sih);
1016                 si_pmu_swreg_init(sih);
1017         }
1018
1019         /* setup the GPIO based LED powersave register */
1020         w = getintvar(pvars, "leddc");
1021         if (w == 0)
1022                 w = DEFAULT_GPIOTIMERVAL;
1023         ai_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, gpiotimerval), ~0, w);
1024
1025         if (PCIE(sii)) {
1026                 pcicore_attach(sii->pch, pvars, SI_DOATTACH);
1027         }
1028
1029         if ((sih->chip == BCM43224_CHIP_ID) ||
1030             (sih->chip == BCM43421_CHIP_ID)) {
1031                 /*
1032                  * enable 12 mA drive strenth for 43224 and
1033                  * set chipControl register bit 15
1034                  */
1035                 if (sih->chiprev == 0) {
1036                         SI_MSG(("Applying 43224A0 WARs\n"));
1037                         ai_corereg(sih, SI_CC_IDX,
1038                                    offsetof(chipcregs_t, chipcontrol),
1039                                    CCTRL43224_GPIO_TOGGLE,
1040                                    CCTRL43224_GPIO_TOGGLE);
1041                         si_pmu_chipcontrol(sih, 0, CCTRL_43224A0_12MA_LED_DRIVE,
1042                                            CCTRL_43224A0_12MA_LED_DRIVE);
1043                 }
1044                 if (sih->chiprev >= 1) {
1045                         SI_MSG(("Applying 43224B0+ WARs\n"));
1046                         si_pmu_chipcontrol(sih, 0, CCTRL_43224B0_12MA_LED_DRIVE,
1047                                            CCTRL_43224B0_12MA_LED_DRIVE);
1048                 }
1049         }
1050
1051         if (sih->chip == BCM4313_CHIP_ID) {
1052                 /*
1053                  * enable 12 mA drive strenth for 4313 and
1054                  * set chipControl register bit 1
1055                  */
1056                 SI_MSG(("Applying 4313 WARs\n"));
1057                 si_pmu_chipcontrol(sih, 0, CCTRL_4313_12MA_LED_DRIVE,
1058                                    CCTRL_4313_12MA_LED_DRIVE);
1059         }
1060
1061         if (sih->chip == BCM4331_CHIP_ID) {
1062                 /* Enable Ext PA lines depending on chip package option */
1063                 ai_chipcontrl_epa4331(sih, true);
1064         }
1065
1066         return sii;
1067  exit:
1068         if (sih->bustype == PCI_BUS) {
1069                 if (sii->pch)
1070                         pcicore_deinit(sii->pch);
1071                 sii->pch = NULL;
1072         }
1073
1074         return NULL;
1075 }
1076
1077 /* may be called with core in reset */
1078 void ai_detach(si_t *sih)
1079 {
1080         si_info_t *sii;
1081         uint idx;
1082
1083         struct si_pub *si_local = NULL;
1084         bcopy(&sih, &si_local, sizeof(si_t **));
1085
1086         sii = SI_INFO(sih);
1087
1088         if (sii == NULL)
1089                 return;
1090
1091         if (sih->bustype == SI_BUS)
1092                 for (idx = 0; idx < SI_MAXCORES; idx++)
1093                         if (sii->regs[idx]) {
1094                                 iounmap(sii->regs[idx]);
1095                                 sii->regs[idx] = NULL;
1096                         }
1097
1098         nvram_exit();   /* free up nvram buffers */
1099
1100         if (sih->bustype == PCI_BUS) {
1101                 if (sii->pch)
1102                         pcicore_deinit(sii->pch);
1103                 sii->pch = NULL;
1104         }
1105
1106         if (sii != &ksii)
1107                 kfree(sii);
1108 }
1109
1110 /* register driver interrupt disabling and restoring callback functions */
1111 void
1112 ai_register_intr_callback(si_t *sih, void *intrsoff_fn, void *intrsrestore_fn,
1113                           void *intrsenabled_fn, void *intr_arg)
1114 {
1115         si_info_t *sii;
1116
1117         sii = SI_INFO(sih);
1118         sii->intr_arg = intr_arg;
1119         sii->intrsoff_fn = (si_intrsoff_t) intrsoff_fn;
1120         sii->intrsrestore_fn = (si_intrsrestore_t) intrsrestore_fn;
1121         sii->intrsenabled_fn = (si_intrsenabled_t) intrsenabled_fn;
1122         /* save current core id.  when this function called, the current core
1123          * must be the core which provides driver functions(il, et, wl, etc.)
1124          */
1125         sii->dev_coreid = sii->coreid[sii->curidx];
1126 }
1127
1128 void ai_deregister_intr_callback(si_t *sih)
1129 {
1130         si_info_t *sii;
1131
1132         sii = SI_INFO(sih);
1133         sii->intrsoff_fn = NULL;
1134 }
1135
1136 uint ai_coreid(si_t *sih)
1137 {
1138         si_info_t *sii;
1139
1140         sii = SI_INFO(sih);
1141         return sii->coreid[sii->curidx];
1142 }
1143
1144 uint ai_coreidx(si_t *sih)
1145 {
1146         si_info_t *sii;
1147
1148         sii = SI_INFO(sih);
1149         return sii->curidx;
1150 }
1151
1152 bool ai_backplane64(si_t *sih)
1153 {
1154         return (sih->cccaps & CC_CAP_BKPLN64) != 0;
1155 }
1156
1157 /* return index of coreid or BADIDX if not found */
1158 uint ai_findcoreidx(si_t *sih, uint coreid, uint coreunit)
1159 {
1160         si_info_t *sii;
1161         uint found;
1162         uint i;
1163
1164         sii = SI_INFO(sih);
1165
1166         found = 0;
1167
1168         for (i = 0; i < sii->numcores; i++)
1169                 if (sii->coreid[i] == coreid) {
1170                         if (found == coreunit)
1171                                 return i;
1172                         found++;
1173                 }
1174
1175         return BADIDX;
1176 }
1177
1178 /*
1179  * This function changes logical "focus" to the indicated core;
1180  * must be called with interrupts off.
1181  * Moreover, callers should keep interrupts off during switching
1182  * out of and back to d11 core.
1183  */
1184 void *ai_setcore(si_t *sih, uint coreid, uint coreunit)
1185 {
1186         uint idx;
1187
1188         idx = ai_findcoreidx(sih, coreid, coreunit);
1189         if (!GOODIDX(idx))
1190                 return NULL;
1191
1192         return ai_setcoreidx(sih, idx);
1193 }
1194
1195 /* Turn off interrupt as required by ai_setcore, before switch core */
1196 void *ai_switch_core(si_t *sih, uint coreid, uint *origidx, uint *intr_val)
1197 {
1198         void *cc;
1199         si_info_t *sii;
1200
1201         sii = SI_INFO(sih);
1202
1203         if (SI_FAST(sii)) {
1204                 /* Overloading the origidx variable to remember the coreid,
1205                  * this works because the core ids cannot be confused with
1206                  * core indices.
1207                  */
1208                 *origidx = coreid;
1209                 if (coreid == CC_CORE_ID)
1210                         return (void *)CCREGS_FAST(sii);
1211                 else if (coreid == sih->buscoretype)
1212                         return (void *)PCIEREGS(sii);
1213         }
1214         INTR_OFF(sii, *intr_val);
1215         *origidx = sii->curidx;
1216         cc = ai_setcore(sih, coreid, 0);
1217         return cc;
1218 }
1219
1220 /* restore coreidx and restore interrupt */
1221 void ai_restore_core(si_t *sih, uint coreid, uint intr_val)
1222 {
1223         si_info_t *sii;
1224
1225         sii = SI_INFO(sih);
1226         if (SI_FAST(sii)
1227             && ((coreid == CC_CORE_ID) || (coreid == sih->buscoretype)))
1228                 return;
1229
1230         ai_setcoreidx(sih, coreid);
1231         INTR_RESTORE(sii, intr_val);
1232 }
1233
1234 void ai_write_wrapperreg(si_t *sih, u32 offset, u32 val)
1235 {
1236         si_info_t *sii = SI_INFO(sih);
1237         u32 *w = (u32 *) sii->curwrap;
1238         W_REG(w + (offset / 4), val);
1239         return;
1240 }
1241
1242 /*
1243  * Switch to 'coreidx', issue a single arbitrary 32bit register mask&set
1244  * operation, switch back to the original core, and return the new value.
1245  *
1246  * When using the silicon backplane, no fiddling with interrupts or core
1247  * switches is needed.
1248  *
1249  * Also, when using pci/pcie, we can optimize away the core switching for pci
1250  * registers and (on newer pci cores) chipcommon registers.
1251  */
1252 uint ai_corereg(si_t *sih, uint coreidx, uint regoff, uint mask, uint val)
1253 {
1254         uint origidx = 0;
1255         u32 *r = NULL;
1256         uint w;
1257         uint intr_val = 0;
1258         bool fast = false;
1259         si_info_t *sii;
1260
1261         sii = SI_INFO(sih);
1262
1263         if (coreidx >= SI_MAXCORES)
1264                 return 0;
1265
1266         if (sih->bustype == SI_BUS) {
1267                 /* If internal bus, we can always get at everything */
1268                 fast = true;
1269                 /* map if does not exist */
1270                 if (!sii->regs[coreidx]) {
1271                         sii->regs[coreidx] = REG_MAP(sii->coresba[coreidx],
1272                                                      SI_CORE_SIZE);
1273                 }
1274                 r = (u32 *) ((unsigned char *) sii->regs[coreidx] + regoff);
1275         } else if (sih->bustype == PCI_BUS) {
1276                 /*
1277                  * If pci/pcie, we can get at pci/pcie regs
1278                  * and on newer cores to chipc
1279                  */
1280                 if ((sii->coreid[coreidx] == CC_CORE_ID) && SI_FAST(sii)) {
1281                         /* Chipc registers are mapped at 12KB */
1282
1283                         fast = true;
1284                         r = (u32 *) ((char *)sii->curmap +
1285                                         PCI_16KB0_CCREGS_OFFSET + regoff);
1286                 } else if (sii->pub.buscoreidx == coreidx) {
1287                         /*
1288                          * pci registers are at either in the last 2KB of
1289                          * an 8KB window or, in pcie and pci rev 13 at 8KB
1290                          */
1291                         fast = true;
1292                         if (SI_FAST(sii))
1293                                 r = (u32 *) ((char *)sii->curmap +
1294                                                 PCI_16KB0_PCIREGS_OFFSET +
1295                                                 regoff);
1296                         else
1297                                 r = (u32 *) ((char *)sii->curmap +
1298                                                 ((regoff >= SBCONFIGOFF) ?
1299                                                  PCI_BAR0_PCISBR_OFFSET :
1300                                                  PCI_BAR0_PCIREGS_OFFSET) +
1301                                                 regoff);
1302                 }
1303         }
1304
1305         if (!fast) {
1306                 INTR_OFF(sii, intr_val);
1307
1308                 /* save current core index */
1309                 origidx = ai_coreidx(&sii->pub);
1310
1311                 /* switch core */
1312                 r = (u32 *) ((unsigned char *) ai_setcoreidx(&sii->pub, coreidx)
1313                                 + regoff);
1314         }
1315
1316         /* mask and set */
1317         if (mask || val) {
1318                 w = (R_REG(r) & ~mask) | val;
1319                 W_REG(r, w);
1320         }
1321
1322         /* readback */
1323         w = R_REG(r);
1324
1325         if (!fast) {
1326                 /* restore core index */
1327                 if (origidx != coreidx)
1328                         ai_setcoreidx(&sii->pub, origidx);
1329
1330                 INTR_RESTORE(sii, intr_val);
1331         }
1332
1333         return w;
1334 }
1335
1336 void ai_core_disable(si_t *sih, u32 bits)
1337 {
1338         si_info_t *sii;
1339         u32 dummy;
1340         aidmp_t *ai;
1341
1342         sii = SI_INFO(sih);
1343
1344         ai = sii->curwrap;
1345
1346         /* if core is already in reset, just return */
1347         if (R_REG(&ai->resetctrl) & AIRC_RESET)
1348                 return;
1349
1350         W_REG(&ai->ioctrl, bits);
1351         dummy = R_REG(&ai->ioctrl);
1352         udelay(10);
1353
1354         W_REG(&ai->resetctrl, AIRC_RESET);
1355         udelay(1);
1356 }
1357
1358 /* reset and re-enable a core
1359  * inputs:
1360  * bits - core specific bits that are set during and after reset sequence
1361  * resetbits - core specific bits that are set only during reset sequence
1362  */
1363 void ai_core_reset(si_t *sih, u32 bits, u32 resetbits)
1364 {
1365         si_info_t *sii;
1366         aidmp_t *ai;
1367         u32 dummy;
1368
1369         sii = SI_INFO(sih);
1370         ai = sii->curwrap;
1371
1372         /*
1373          * Must do the disable sequence first to work
1374          * for arbitrary current core state.
1375          */
1376         ai_core_disable(sih, (bits | resetbits));
1377
1378         /*
1379          * Now do the initialization sequence.
1380          */
1381         W_REG(&ai->ioctrl, (bits | SICF_FGC | SICF_CLOCK_EN));
1382         dummy = R_REG(&ai->ioctrl);
1383         W_REG(&ai->resetctrl, 0);
1384         udelay(1);
1385
1386         W_REG(&ai->ioctrl, (bits | SICF_CLOCK_EN));
1387         dummy = R_REG(&ai->ioctrl);
1388         udelay(1);
1389 }
1390
1391 /* return the slow clock source - LPO, XTAL, or PCI */
1392 static uint ai_slowclk_src(si_info_t *sii)
1393 {
1394         chipcregs_t *cc;
1395         u32 val;
1396
1397         if (sii->pub.ccrev < 6) {
1398                 if (sii->pub.bustype == PCI_BUS) {
1399                         pci_read_config_dword(sii->pbus, PCI_GPIO_OUT,
1400                                               &val);
1401                         if (val & PCI_CFG_GPIO_SCS)
1402                                 return SCC_SS_PCI;
1403                 }
1404                 return SCC_SS_XTAL;
1405         } else if (sii->pub.ccrev < 10) {
1406                 cc = (chipcregs_t *) ai_setcoreidx(&sii->pub, sii->curidx);
1407                 return R_REG(&cc->slow_clk_ctl) & SCC_SS_MASK;
1408         } else                  /* Insta-clock */
1409                 return SCC_SS_XTAL;
1410 }
1411
1412 /*
1413 * return the ILP (slowclock) min or max frequency
1414 * precondition: we've established the chip has dynamic clk control
1415 */
1416 static uint ai_slowclk_freq(si_info_t *sii, bool max_freq, chipcregs_t *cc)
1417 {
1418         u32 slowclk;
1419         uint div;
1420
1421         slowclk = ai_slowclk_src(sii);
1422         if (sii->pub.ccrev < 6) {
1423                 if (slowclk == SCC_SS_PCI)
1424                         return max_freq ? (PCIMAXFREQ / 64)
1425                                 : (PCIMINFREQ / 64);
1426                 else
1427                         return max_freq ? (XTALMAXFREQ / 32)
1428                                 : (XTALMINFREQ / 32);
1429         } else if (sii->pub.ccrev < 10) {
1430                 div = 4 *
1431                     (((R_REG(&cc->slow_clk_ctl) & SCC_CD_MASK) >>
1432                       SCC_CD_SHIFT) + 1);
1433                 if (slowclk == SCC_SS_LPO)
1434                         return max_freq ? LPOMAXFREQ : LPOMINFREQ;
1435                 else if (slowclk == SCC_SS_XTAL)
1436                         return max_freq ? (XTALMAXFREQ / div)
1437                                 : (XTALMINFREQ / div);
1438                 else if (slowclk == SCC_SS_PCI)
1439                         return max_freq ? (PCIMAXFREQ / div)
1440                                 : (PCIMINFREQ / div);
1441         } else {
1442                 /* Chipc rev 10 is InstaClock */
1443                 div = R_REG(&cc->system_clk_ctl) >> SYCC_CD_SHIFT;
1444                 div = 4 * (div + 1);
1445                 return max_freq ? XTALMAXFREQ : (XTALMINFREQ / div);
1446         }
1447         return 0;
1448 }
1449
1450 static void ai_clkctl_setdelay(si_info_t *sii, void *chipcregs)
1451 {
1452         chipcregs_t *cc = (chipcregs_t *) chipcregs;
1453         uint slowmaxfreq, pll_delay, slowclk;
1454         uint pll_on_delay, fref_sel_delay;
1455
1456         pll_delay = PLL_DELAY;
1457
1458         /*
1459          * If the slow clock is not sourced by the xtal then
1460          * add the xtal_on_delay since the xtal will also be
1461          * powered down by dynamic clk control logic.
1462          */
1463
1464         slowclk = ai_slowclk_src(sii);
1465         if (slowclk != SCC_SS_XTAL)
1466                 pll_delay += XTAL_ON_DELAY;
1467
1468         /* Starting with 4318 it is ILP that is used for the delays */
1469         slowmaxfreq =
1470             ai_slowclk_freq(sii, (sii->pub.ccrev >= 10) ? false : true, cc);
1471
1472         pll_on_delay = ((slowmaxfreq * pll_delay) + 999999) / 1000000;
1473         fref_sel_delay = ((slowmaxfreq * FREF_DELAY) + 999999) / 1000000;
1474
1475         W_REG(&cc->pll_on_delay, pll_on_delay);
1476         W_REG(&cc->fref_sel_delay, fref_sel_delay);
1477 }
1478
1479 /* initialize power control delay registers */
1480 void ai_clkctl_init(si_t *sih)
1481 {
1482         si_info_t *sii;
1483         uint origidx = 0;
1484         chipcregs_t *cc;
1485         bool fast;
1486
1487         if (!CCCTL_ENAB(sih))
1488                 return;
1489
1490         sii = SI_INFO(sih);
1491         fast = SI_FAST(sii);
1492         if (!fast) {
1493                 origidx = sii->curidx;
1494                 cc = (chipcregs_t *) ai_setcore(sih, CC_CORE_ID, 0);
1495                 if (cc == NULL)
1496                         return;
1497         } else {
1498                 cc = (chipcregs_t *) CCREGS_FAST(sii);
1499                 if (cc == NULL)
1500                         return;
1501         }
1502
1503         /* set all Instaclk chip ILP to 1 MHz */
1504         if (sih->ccrev >= 10)
1505                 SET_REG(&cc->system_clk_ctl, SYCC_CD_MASK,
1506                         (ILP_DIV_1MHZ << SYCC_CD_SHIFT));
1507
1508         ai_clkctl_setdelay(sii, (void *)cc);
1509
1510         if (!fast)
1511                 ai_setcoreidx(sih, origidx);
1512 }
1513
1514 /*
1515  * return the value suitable for writing to the
1516  * dot11 core FAST_PWRUP_DELAY register
1517  */
1518 u16 ai_clkctl_fast_pwrup_delay(si_t *sih)
1519 {
1520         si_info_t *sii;
1521         uint origidx = 0;
1522         chipcregs_t *cc;
1523         uint slowminfreq;
1524         u16 fpdelay;
1525         uint intr_val = 0;
1526         bool fast;
1527
1528         sii = SI_INFO(sih);
1529         if (PMUCTL_ENAB(sih)) {
1530                 INTR_OFF(sii, intr_val);
1531                 fpdelay = si_pmu_fast_pwrup_delay(sih);
1532                 INTR_RESTORE(sii, intr_val);
1533                 return fpdelay;
1534         }
1535
1536         if (!CCCTL_ENAB(sih))
1537                 return 0;
1538
1539         fast = SI_FAST(sii);
1540         fpdelay = 0;
1541         if (!fast) {
1542                 origidx = sii->curidx;
1543                 INTR_OFF(sii, intr_val);
1544                 cc = (chipcregs_t *) ai_setcore(sih, CC_CORE_ID, 0);
1545                 if (cc == NULL)
1546                         goto done;
1547         } else {
1548                 cc = (chipcregs_t *) CCREGS_FAST(sii);
1549                 if (cc == NULL)
1550                         goto done;
1551         }
1552
1553         slowminfreq = ai_slowclk_freq(sii, false, cc);
1554         fpdelay = (((R_REG(&cc->pll_on_delay) + 2) * 1000000) +
1555                    (slowminfreq - 1)) / slowminfreq;
1556
1557  done:
1558         if (!fast) {
1559                 ai_setcoreidx(sih, origidx);
1560                 INTR_RESTORE(sii, intr_val);
1561         }
1562         return fpdelay;
1563 }
1564
1565 /* turn primary xtal and/or pll off/on */
1566 int ai_clkctl_xtal(si_t *sih, uint what, bool on)
1567 {
1568         si_info_t *sii;
1569         u32 in, out, outen;
1570
1571         sii = SI_INFO(sih);
1572
1573         switch (sih->bustype) {
1574
1575         case PCI_BUS:
1576                 /* pcie core doesn't have any mapping to control the xtal pu */
1577                 if (PCIE(sii))
1578                         return -1;
1579
1580                 pci_read_config_dword(sii->pbus, PCI_GPIO_IN, &in);
1581                 pci_read_config_dword(sii->pbus, PCI_GPIO_OUT, &out);
1582                 pci_read_config_dword(sii->pbus, PCI_GPIO_OUTEN, &outen);
1583
1584                 /*
1585                  * Avoid glitching the clock if GPRS is already using it.
1586                  * We can't actually read the state of the PLLPD so we infer it
1587                  * by the value of XTAL_PU which *is* readable via gpioin.
1588                  */
1589                 if (on && (in & PCI_CFG_GPIO_XTAL))
1590                         return 0;
1591
1592                 if (what & XTAL)
1593                         outen |= PCI_CFG_GPIO_XTAL;
1594                 if (what & PLL)
1595                         outen |= PCI_CFG_GPIO_PLL;
1596
1597                 if (on) {
1598                         /* turn primary xtal on */
1599                         if (what & XTAL) {
1600                                 out |= PCI_CFG_GPIO_XTAL;
1601                                 if (what & PLL)
1602                                         out |= PCI_CFG_GPIO_PLL;
1603                                 pci_write_config_dword(sii->pbus,
1604                                                        PCI_GPIO_OUT, out);
1605                                 pci_write_config_dword(sii->pbus,
1606                                                        PCI_GPIO_OUTEN, outen);
1607                                 udelay(XTAL_ON_DELAY);
1608                         }
1609
1610                         /* turn pll on */
1611                         if (what & PLL) {
1612                                 out &= ~PCI_CFG_GPIO_PLL;
1613                                 pci_write_config_dword(sii->pbus,
1614                                                        PCI_GPIO_OUT, out);
1615                                 mdelay(2);
1616                         }
1617                 } else {
1618                         if (what & XTAL)
1619                                 out &= ~PCI_CFG_GPIO_XTAL;
1620                         if (what & PLL)
1621                                 out |= PCI_CFG_GPIO_PLL;
1622                         pci_write_config_dword(sii->pbus,
1623                                                PCI_GPIO_OUT, out);
1624                         pci_write_config_dword(sii->pbus,
1625                                                PCI_GPIO_OUTEN, outen);
1626                 }
1627
1628         default:
1629                 return -1;
1630         }
1631
1632         return 0;
1633 }
1634
1635 /*
1636  *  clock control policy function throught chipcommon
1637  *
1638  *    set dynamic clk control mode (forceslow, forcefast, dynamic)
1639  *    returns true if we are forcing fast clock
1640  *    this is a wrapper over the next internal function
1641  *      to allow flexible policy settings for outside caller
1642  */
1643 bool ai_clkctl_cc(si_t *sih, uint mode)
1644 {
1645         si_info_t *sii;
1646
1647         sii = SI_INFO(sih);
1648
1649         /* chipcommon cores prior to rev6 don't support dynamic clock control */
1650         if (sih->ccrev < 6)
1651                 return false;
1652
1653         if (PCI_FORCEHT(sii))
1654                 return mode == CLK_FAST;
1655
1656         return _ai_clkctl_cc(sii, mode);
1657 }
1658
1659 /* clk control mechanism through chipcommon, no policy checking */
1660 static bool _ai_clkctl_cc(si_info_t *sii, uint mode)
1661 {
1662         uint origidx = 0;
1663         chipcregs_t *cc;
1664         u32 scc;
1665         uint intr_val = 0;
1666         bool fast = SI_FAST(sii);
1667
1668         /* chipcommon cores prior to rev6 don't support dynamic clock control */
1669         if (sii->pub.ccrev < 6)
1670                 return false;
1671
1672         if (!fast) {
1673                 INTR_OFF(sii, intr_val);
1674                 origidx = sii->curidx;
1675
1676                 if ((sii->pub.bustype == SI_BUS) &&
1677                     ai_setcore(&sii->pub, MIPS33_CORE_ID, 0) &&
1678                     (ai_corerev(&sii->pub) <= 7) && (sii->pub.ccrev >= 10))
1679                         goto done;
1680
1681                 cc = (chipcregs_t *) ai_setcore(&sii->pub, CC_CORE_ID, 0);
1682         } else {
1683                 cc = (chipcregs_t *) CCREGS_FAST(sii);
1684                 if (cc == NULL)
1685                         goto done;
1686         }
1687
1688         if (!CCCTL_ENAB(&sii->pub) && (sii->pub.ccrev < 20))
1689                 goto done;
1690
1691         switch (mode) {
1692         case CLK_FAST:          /* FORCEHT, fast (pll) clock */
1693                 if (sii->pub.ccrev < 10) {
1694                         /*
1695                          * don't forget to force xtal back
1696                          * on before we clear SCC_DYN_XTAL..
1697                          */
1698                         ai_clkctl_xtal(&sii->pub, XTAL, ON);
1699                         SET_REG(&cc->slow_clk_ctl,
1700                                 (SCC_XC | SCC_FS | SCC_IP), SCC_IP);
1701                 } else if (sii->pub.ccrev < 20) {
1702                         OR_REG(&cc->system_clk_ctl, SYCC_HR);
1703                 } else {
1704                         OR_REG(&cc->clk_ctl_st, CCS_FORCEHT);
1705                 }
1706
1707                 /* wait for the PLL */
1708                 if (PMUCTL_ENAB(&sii->pub)) {
1709                         u32 htavail = CCS_HTAVAIL;
1710                         SPINWAIT(((R_REG(&cc->clk_ctl_st) & htavail)
1711                                   == 0), PMU_MAX_TRANSITION_DLY);
1712                 } else {
1713                         udelay(PLL_DELAY);
1714                 }
1715                 break;
1716
1717         case CLK_DYNAMIC:       /* enable dynamic clock control */
1718                 if (sii->pub.ccrev < 10) {
1719                         scc = R_REG(&cc->slow_clk_ctl);
1720                         scc &= ~(SCC_FS | SCC_IP | SCC_XC);
1721                         if ((scc & SCC_SS_MASK) != SCC_SS_XTAL)
1722                                 scc |= SCC_XC;
1723                         W_REG(&cc->slow_clk_ctl, scc);
1724
1725                         /*
1726                          * for dynamic control, we have to
1727                          * release our xtal_pu "force on"
1728                          */
1729                         if (scc & SCC_XC)
1730                                 ai_clkctl_xtal(&sii->pub, XTAL, OFF);
1731                 } else if (sii->pub.ccrev < 20) {
1732                         /* Instaclock */
1733                         AND_REG(&cc->system_clk_ctl, ~SYCC_HR);
1734                 } else {
1735                         AND_REG(&cc->clk_ctl_st, ~CCS_FORCEHT);
1736                 }
1737                 break;
1738
1739         default:
1740                 break;
1741         }
1742
1743  done:
1744         if (!fast) {
1745                 ai_setcoreidx(&sii->pub, origidx);
1746                 INTR_RESTORE(sii, intr_val);
1747         }
1748         return mode == CLK_FAST;
1749 }
1750
1751 /* Build device path. Support SI, PCI, and JTAG for now. */
1752 int ai_devpath(si_t *sih, char *path, int size)
1753 {
1754         int slen;
1755
1756         if (!path || size <= 0)
1757                 return -1;
1758
1759         switch (sih->bustype) {
1760         case SI_BUS:
1761         case JTAG_BUS:
1762                 slen = snprintf(path, (size_t) size, "sb/%u/", ai_coreidx(sih));
1763                 break;
1764         case PCI_BUS:
1765                 slen = snprintf(path, (size_t) size, "pci/%u/%u/",
1766                         ((struct pci_dev *)((SI_INFO(sih))->pbus))->bus->number,
1767                         PCI_SLOT(
1768                             ((struct pci_dev *)((SI_INFO(sih))->pbus))->devfn));
1769                 break;
1770
1771         default:
1772                 slen = -1;
1773                 break;
1774         }
1775
1776         if (slen < 0 || slen >= size) {
1777                 path[0] = '\0';
1778                 return -1;
1779         }
1780
1781         return 0;
1782 }
1783
1784 /* Get a variable, but only if it has a devpath prefix */
1785 char *ai_getdevpathvar(si_t *sih, const char *name)
1786 {
1787         char varname[SI_DEVPATH_BUFSZ + 32];
1788
1789         ai_devpathvar(sih, varname, sizeof(varname), name);
1790
1791         return getvar(NULL, varname);
1792 }
1793
1794 /* Get a variable, but only if it has a devpath prefix */
1795 int ai_getdevpathintvar(si_t *sih, const char *name)
1796 {
1797 #if defined(BCMBUSTYPE) && (BCMBUSTYPE == SI_BUS)
1798         return getintvar(NULL, name);
1799 #else
1800         char varname[SI_DEVPATH_BUFSZ + 32];
1801
1802         ai_devpathvar(sih, varname, sizeof(varname), name);
1803
1804         return getintvar(NULL, varname);
1805 #endif
1806 }
1807
1808 char *ai_getnvramflvar(si_t *sih, const char *name)
1809 {
1810         return getvar(NULL, name);
1811 }
1812
1813 /* Concatenate the dev path with a varname into the given 'var' buffer
1814  * and return the 'var' pointer. Nothing is done to the arguments if
1815  * len == 0 or var is NULL, var is still returned. On overflow, the
1816  * first char will be set to '\0'.
1817  */
1818 static char *ai_devpathvar(si_t *sih, char *var, int len, const char *name)
1819 {
1820         uint path_len;
1821
1822         if (!var || len <= 0)
1823                 return var;
1824
1825         if (ai_devpath(sih, var, len) == 0) {
1826                 path_len = strlen(var);
1827
1828                 if (strlen(name) + 1 > (uint) (len - path_len))
1829                         var[0] = '\0';
1830                 else
1831                         strncpy(var + path_len, name, len - path_len - 1);
1832         }
1833
1834         return var;
1835 }
1836
1837 /* return true if PCIE capability exists in the pci config space */
1838 static __used bool ai_ispcie(si_info_t *sii)
1839 {
1840         u8 cap_ptr;
1841
1842         if (sii->pub.bustype != PCI_BUS)
1843                 return false;
1844
1845         cap_ptr =
1846             pcicore_find_pci_capability(sii->pbus, PCI_CAP_ID_EXP, NULL,
1847                                         NULL);
1848         if (!cap_ptr)
1849                 return false;
1850
1851         return true;
1852 }
1853
1854 bool ai_pci_war16165(si_t *sih)
1855 {
1856         si_info_t *sii;
1857
1858         sii = SI_INFO(sih);
1859
1860         return PCI(sii) && (sih->buscorerev <= 10);
1861 }
1862
1863 void ai_pci_up(si_t *sih)
1864 {
1865         si_info_t *sii;
1866
1867         sii = SI_INFO(sih);
1868
1869         /* if not pci bus, we're done */
1870         if (sih->bustype != PCI_BUS)
1871                 return;
1872
1873         if (PCI_FORCEHT(sii))
1874                 _ai_clkctl_cc(sii, CLK_FAST);
1875
1876         if (PCIE(sii))
1877                 pcicore_up(sii->pch, SI_PCIUP);
1878
1879 }
1880
1881 /* Unconfigure and/or apply various WARs when system is going to sleep mode */
1882 void ai_pci_sleep(si_t *sih)
1883 {
1884         si_info_t *sii;
1885
1886         sii = SI_INFO(sih);
1887
1888         pcicore_sleep(sii->pch);
1889 }
1890
1891 /* Unconfigure and/or apply various WARs when going down */
1892 void ai_pci_down(si_t *sih)
1893 {
1894         si_info_t *sii;
1895
1896         sii = SI_INFO(sih);
1897
1898         /* if not pci bus, we're done */
1899         if (sih->bustype != PCI_BUS)
1900                 return;
1901
1902         /* release FORCEHT since chip is going to "down" state */
1903         if (PCI_FORCEHT(sii))
1904                 _ai_clkctl_cc(sii, CLK_DYNAMIC);
1905
1906         pcicore_down(sii->pch, SI_PCIDOWN);
1907 }
1908
1909 /*
1910  * Configure the pci core for pci client (NIC) action
1911  * coremask is the bitvec of cores by index to be enabled.
1912  */
1913 void ai_pci_setup(si_t *sih, uint coremask)
1914 {
1915         si_info_t *sii;
1916         void *regs = NULL;
1917         u32 siflag = 0, w;
1918         uint idx = 0;
1919
1920         sii = SI_INFO(sih);
1921
1922         if (sii->pub.bustype != PCI_BUS)
1923                 return;
1924
1925         if (PCI(sii)) {
1926                 /* get current core index */
1927                 idx = sii->curidx;
1928
1929                 /* we interrupt on this backplane flag number */
1930                 siflag = ai_flag(sih);
1931
1932                 /* switch over to pci core */
1933                 regs = ai_setcoreidx(sih, sii->pub.buscoreidx);
1934         }
1935
1936         /*
1937          * Enable sb->pci interrupts.  Assume
1938          * PCI rev 2.3 support was added in pci core rev 6 and things changed..
1939          */
1940         if (PCIE(sii) || (PCI(sii) && ((sii->pub.buscorerev) >= 6))) {
1941                 /* pci config write to set this core bit in PCIIntMask */
1942                 pci_read_config_dword(sii->pbus, PCI_INT_MASK, &w);
1943                 w |= (coremask << PCI_SBIM_SHIFT);
1944                 pci_write_config_dword(sii->pbus, PCI_INT_MASK, w);
1945         } else {
1946                 /* set sbintvec bit for our flag number */
1947                 ai_setint(sih, siflag);
1948         }
1949
1950         if (PCI(sii)) {
1951                 pcicore_pci_setup(sii->pch, regs);
1952
1953                 /* switch back to previous core */
1954                 ai_setcoreidx(sih, idx);
1955         }
1956 }
1957
1958 /*
1959  * Fixup SROMless PCI device's configuration.
1960  * The current core may be changed upon return.
1961  */
1962 int ai_pci_fixcfg(si_t *sih)
1963 {
1964         uint origidx;
1965         void *regs = NULL;
1966
1967         si_info_t *sii = SI_INFO(sih);
1968
1969         /* Fixup PI in SROM shadow area to enable the correct PCI core access */
1970         /* save the current index */
1971         origidx = ai_coreidx(&sii->pub);
1972
1973         /* check 'pi' is correct and fix it if not */
1974         regs = ai_setcore(&sii->pub, sii->pub.buscoretype, 0);
1975         pcicore_fixcfg(sii->pch, regs);
1976
1977         /* restore the original index */
1978         ai_setcoreidx(&sii->pub, origidx);
1979
1980         pcicore_hwup(sii->pch);
1981         return 0;
1982 }
1983
1984 /* mask&set gpiocontrol bits */
1985 u32 ai_gpiocontrol(si_t *sih, u32 mask, u32 val, u8 priority)
1986 {
1987         uint regoff;
1988
1989         regoff = 0;
1990
1991         /* gpios could be shared on router platforms
1992          * ignore reservation if it's high priority (e.g., test apps)
1993          */
1994         if ((priority != GPIO_HI_PRIORITY) &&
1995             (sih->bustype == SI_BUS) && (val || mask)) {
1996                 mask = priority ? (ai_gpioreservation & mask) :
1997                     ((ai_gpioreservation | mask) & ~(ai_gpioreservation));
1998                 val &= mask;
1999         }
2000
2001         regoff = offsetof(chipcregs_t, gpiocontrol);
2002         return ai_corereg(sih, SI_CC_IDX, regoff, mask, val);
2003 }
2004
2005 void ai_chipcontrl_epa4331(si_t *sih, bool on)
2006 {
2007         si_info_t *sii;
2008         chipcregs_t *cc;
2009         uint origidx;
2010         u32 val;
2011
2012         sii = SI_INFO(sih);
2013         origidx = ai_coreidx(sih);
2014
2015         cc = (chipcregs_t *) ai_setcore(sih, CC_CORE_ID, 0);
2016
2017         val = R_REG(&cc->chipcontrol);
2018
2019         if (on) {
2020                 if (sih->chippkg == 9 || sih->chippkg == 0xb) {
2021                         /* Ext PA Controls for 4331 12x9 Package */
2022                         W_REG(&cc->chipcontrol, val |
2023                               (CCTRL4331_EXTPA_EN |
2024                                CCTRL4331_EXTPA_ON_GPIO2_5));
2025                 } else {
2026                         /* Ext PA Controls for 4331 12x12 Package */
2027                         W_REG(&cc->chipcontrol,
2028                               val | (CCTRL4331_EXTPA_EN));
2029                 }
2030         } else {
2031                 val &= ~(CCTRL4331_EXTPA_EN | CCTRL4331_EXTPA_ON_GPIO2_5);
2032                 W_REG(&cc->chipcontrol, val);
2033         }
2034
2035         ai_setcoreidx(sih, origidx);
2036 }
2037
2038 /* Enable BT-COEX & Ex-PA for 4313 */
2039 void ai_epa_4313war(si_t *sih)
2040 {
2041         si_info_t *sii;
2042         chipcregs_t *cc;
2043         uint origidx;
2044
2045         sii = SI_INFO(sih);
2046         origidx = ai_coreidx(sih);
2047
2048         cc = (chipcregs_t *) ai_setcore(sih, CC_CORE_ID, 0);
2049
2050         /* EPA Fix */
2051         W_REG(&cc->gpiocontrol,
2052               R_REG(&cc->gpiocontrol) | GPIO_CTRL_EPA_EN_MASK);
2053
2054         ai_setcoreidx(sih, origidx);
2055 }
2056
2057 /* check if the device is removed */
2058 bool ai_deviceremoved(si_t *sih)
2059 {
2060         u32 w;
2061         si_info_t *sii;
2062
2063         sii = SI_INFO(sih);
2064
2065         switch (sih->bustype) {
2066         case PCI_BUS:
2067                 pci_read_config_dword(sii->pbus, PCI_VENDOR_ID, &w);
2068                 if ((w & 0xFFFF) != PCI_VENDOR_ID_BROADCOM)
2069                         return true;
2070                 break;
2071         }
2072         return false;
2073 }
2074
2075 bool ai_is_sprom_available(si_t *sih)
2076 {
2077         if (sih->ccrev >= 31) {
2078                 si_info_t *sii;
2079                 uint origidx;
2080                 chipcregs_t *cc;
2081                 u32 sromctrl;
2082
2083                 if ((sih->cccaps & CC_CAP_SROM) == 0)
2084                         return false;
2085
2086                 sii = SI_INFO(sih);
2087                 origidx = sii->curidx;
2088                 cc = ai_setcoreidx(sih, SI_CC_IDX);
2089                 sromctrl = R_REG(&cc->sromcontrol);
2090                 ai_setcoreidx(sih, origidx);
2091                 return sromctrl & SRC_PRESENT;
2092         }
2093
2094         switch (sih->chip) {
2095         case BCM4329_CHIP_ID:
2096                 return (sih->chipst & CST4329_SPROM_SEL) != 0;
2097         case BCM4319_CHIP_ID:
2098                 return (sih->chipst & CST4319_SPROM_SEL) != 0;
2099         case BCM4336_CHIP_ID:
2100                 return (sih->chipst & CST4336_SPROM_PRESENT) != 0;
2101         case BCM4330_CHIP_ID:
2102                 return (sih->chipst & CST4330_SPROM_PRESENT) != 0;
2103         case BCM4313_CHIP_ID:
2104                 return (sih->chipst & CST4313_SPROM_PRESENT) != 0;
2105         case BCM4331_CHIP_ID:
2106                 return (sih->chipst & CST4331_SPROM_PRESENT) != 0;
2107         default:
2108                 return true;
2109         }
2110 }
2111
2112 bool ai_is_otp_disabled(si_t *sih)
2113 {
2114         switch (sih->chip) {
2115         case BCM4329_CHIP_ID:
2116                 return (sih->chipst & CST4329_SPROM_OTP_SEL_MASK) ==
2117                     CST4329_OTP_PWRDN;
2118         case BCM4319_CHIP_ID:
2119                 return (sih->chipst & CST4319_SPROM_OTP_SEL_MASK) ==
2120                     CST4319_OTP_PWRDN;
2121         case BCM4336_CHIP_ID:
2122                 return (sih->chipst & CST4336_OTP_PRESENT) == 0;
2123         case BCM4330_CHIP_ID:
2124                 return (sih->chipst & CST4330_OTP_PRESENT) == 0;
2125         case BCM4313_CHIP_ID:
2126                 return (sih->chipst & CST4313_OTP_PRESENT) == 0;
2127                 /* These chips always have their OTP on */
2128         case BCM43224_CHIP_ID:
2129         case BCM43225_CHIP_ID:
2130         case BCM43421_CHIP_ID:
2131         case BCM43235_CHIP_ID:
2132         case BCM43236_CHIP_ID:
2133         case BCM43238_CHIP_ID:
2134         case BCM4331_CHIP_ID:
2135         default:
2136                 return false;
2137         }
2138 }
2139
2140 bool ai_is_otp_powered(si_t *sih)
2141 {
2142         if (PMUCTL_ENAB(sih))
2143                 return si_pmu_is_otp_powered(sih);
2144         return true;
2145 }
2146
2147 void ai_otp_power(si_t *sih, bool on)
2148 {
2149         if (PMUCTL_ENAB(sih))
2150                 si_pmu_otp_power(sih, on);
2151         udelay(1000);
2152 }