244a1324f67d20677ce05607ca0cef8ef5bcd045
[openwrt.git] / target / linux / brcm-2.4 / files / arch / mips / bcm947xx / sbutils.c
1 /*
2  * Misc utility routines for accessing chip-specific features
3  * of the SiliconBackplane-based Broadcom chips.
4  *
5  * Copyright 2007, Broadcom Corporation
6  * All Rights Reserved.
7  * 
8  * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
9  * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
10  * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
11  * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
12  * $Id$
13  */
14
15 #include <typedefs.h>
16 #include <bcmdefs.h>
17 #include <osl.h>
18 #include <sbutils.h>
19 #include <bcmdevs.h>
20 #include <sbconfig.h>
21 #include <sbchipc.h>
22 #include <sbextif.h>
23 #include <sbpci.h>
24 #include <sbpcie.h>
25 #include <pcicfg.h>
26 #include <sbpcmcia.h>
27 #include <sbsocram.h>
28 #include <bcmnvram.h>
29 #include <bcmsrom.h>
30 #include <hndpmu.h>
31
32 /* debug/trace */
33 #define SB_ERROR(args)
34
35 #ifdef BCMDBG
36 #define SB_MSG(args)    printf args
37 #else
38 #define SB_MSG(args)
39 #endif /* BCMDBG */
40
41 typedef uint32(*sb_intrsoff_t) (void *intr_arg);
42 typedef void (*sb_intrsrestore_t) (void *intr_arg, uint32 arg);
43 typedef bool(*sb_intrsenabled_t) (void *intr_arg);
44
45 typedef struct gpioh_item {
46         void *arg;
47         bool level;
48         gpio_handler_t handler;
49         uint32 event;
50         struct gpioh_item *next;
51 } gpioh_item_t;
52
53 /* misc sb info needed by some of the routines */
54 typedef struct sb_info {
55
56         struct sb_pub sb;       /* back plane public state (must be first field) */
57
58         void *osh;              /* osl os handle */
59         void *sdh;              /* bcmsdh handle */
60
61         void *curmap;           /* current regs va */
62         void *regs[SB_MAXCORES];        /* other regs va */
63
64         uint curidx;            /* current core index */
65         uint dev_coreid;        /* the core provides driver functions */
66
67         bool memseg;            /* flag to toggle MEM_SEG register */
68
69         uint gpioidx;           /* gpio control core index */
70         uint gpioid;            /* gpio control coretype */
71
72         uint numcores;          /* # discovered cores */
73         uint coreid[SB_MAXCORES];       /* id of each core */
74
75         void *intr_arg;         /* interrupt callback function arg */
76         sb_intrsoff_t intrsoff_fn;      /* turns chip interrupts off */
77         sb_intrsrestore_t intrsrestore_fn;      /* restore chip interrupts */
78         sb_intrsenabled_t intrsenabled_fn;      /* check if interrupts are enabled */
79
80         uint8 pciecap_lcreg_offset;     /* PCIE capability LCreg offset in the config space */
81         bool pr42767_war;
82         uint8 pcie_polarity;
83         bool pcie_war_ovr;      /* Override ASPM/Clkreq settings */
84
85         uint8 pmecap_offset;    /* PM Capability offset in the config space */
86         bool pmecap;            /* Capable of generating PME */
87
88         gpioh_item_t *gpioh_head;       /* GPIO event handlers list */
89
90         char *vars;
91         uint varsz;
92 } sb_info_t;
93
94 /* local prototypes */
95 static sb_info_t *sb_doattach(sb_info_t * si, uint devid, osl_t * osh,
96                               void *regs, uint bustype, void *sdh,
97                               char **vars, uint * varsz);
98 static void sb_scan(sb_info_t * si);
99 static uint _sb_coreidx(sb_info_t * si);
100 static uint sb_pcidev2chip(uint pcidev);
101 static uint sb_chip2numcores(uint chip);
102 static bool sb_ispcie(sb_info_t * si);
103 static uint8 sb_find_pci_capability(sb_info_t * si, uint8 req_cap_id,
104                                     uchar * buf, uint32 * buflen);
105 static int sb_pci_fixcfg(sb_info_t * si);
106 /* routines to access mdio slave device registers */
107 static int sb_pcie_mdiowrite(sb_info_t * si, uint physmedia, uint readdr,
108                              uint val);
109 static int sb_pcie_mdioread(sb_info_t * si, uint physmedia, uint readdr,
110                             uint * ret_val);
111
112 /* dev path concatenation util */
113 static char *sb_devpathvar(sb_t * sbh, char *var, int len, const char *name);
114
115 /* WARs */
116 static void sb_war43448(sb_t * sbh);
117 static void sb_war43448_aspm(sb_t * sbh);
118 static void sb_war32414_forceHT(sb_t * sbh, bool forceHT);
119 static void sb_war30841(sb_info_t * si);
120 static void sb_war42767(sb_t * sbh);
121 static void sb_war42767_clkreq(sb_t * sbh);
122
123 /* delay needed between the mdio control/ mdiodata register data access */
124 #define PR28829_DELAY() OSL_DELAY(10)
125
126 /* size that can take bitfielddump */
127 #define BITFIELD_DUMP_SIZE  32
128
129 /* global variable to indicate reservation/release of gpio's */
130 static uint32 sb_gpioreservation = 0;
131
132 /* global flag to prevent shared resources from being initialized multiple times in sb_attach() */
133 static bool sb_onetimeinit = FALSE;
134
135 #define SB_INFO(sbh)    (sb_info_t*)(uintptr)sbh
136 #define SET_SBREG(si, r, mask, val)     \
137                 W_SBREG((si), (r), ((R_SBREG((si), (r)) & ~(mask)) | (val)))
138 #define GOODCOREADDR(x) (((x) >= SB_ENUM_BASE) && ((x) <= SB_ENUM_LIM) && \
139                 ISALIGNED((x), SB_CORE_SIZE))
140 #define GOODREGS(regs)  ((regs) && ISALIGNED((uintptr)(regs), SB_CORE_SIZE))
141 #define REGS2SB(va)     (sbconfig_t*) ((int8*)(va) + SBCONFIGOFF)
142 #define BADCOREADDR     0
143 #define GOODIDX(idx)    (((uint)idx) < SB_MAXCORES)
144 #define BADIDX          (SB_MAXCORES+1)
145 #define NOREV           -1      /* Invalid rev */
146
147 #define PCI(si)         ((BUSTYPE(si->sb.bustype) == PCI_BUS) && (si->sb.buscoretype == SB_PCI))
148 #define PCIE(si)        ((BUSTYPE(si->sb.bustype) == PCI_BUS) && (si->sb.buscoretype == SB_PCIE))
149 #define PCMCIA(si)      ((BUSTYPE(si->sb.bustype) == PCMCIA_BUS) && (si->memseg == TRUE))
150
151 /* sonicsrev */
152 #define SONICS_2_2      (SBIDL_RV_2_2 >> SBIDL_RV_SHIFT)
153 #define SONICS_2_3      (SBIDL_RV_2_3 >> SBIDL_RV_SHIFT)
154
155 #define R_SBREG(si, sbr)        sb_read_sbreg((si), (sbr))
156 #define W_SBREG(si, sbr, v)     sb_write_sbreg((si), (sbr), (v))
157 #define AND_SBREG(si, sbr, v)   W_SBREG((si), (sbr), (R_SBREG((si), (sbr)) & (v)))
158 #define OR_SBREG(si, sbr, v)    W_SBREG((si), (sbr), (R_SBREG((si), (sbr)) | (v)))
159
160 /*
161  * Macros to disable/restore function core(D11, ENET, ILINE20, etc) interrupts before/
162  * after core switching to avoid invalid register accesss inside ISR.
163  */
164 #define INTR_OFF(si, intr_val) \
165         if ((si)->intrsoff_fn && (si)->coreid[(si)->curidx] == (si)->dev_coreid) {      \
166                 intr_val = (*(si)->intrsoff_fn)((si)->intr_arg); }
167 #define INTR_RESTORE(si, intr_val) \
168         if ((si)->intrsrestore_fn && (si)->coreid[(si)->curidx] == (si)->dev_coreid) {  \
169                 (*(si)->intrsrestore_fn)((si)->intr_arg, intr_val); }
170
171 /* dynamic clock control defines */
172 #define LPOMINFREQ              25000   /* low power oscillator min */
173 #define LPOMAXFREQ              43000   /* low power oscillator max */
174 #define XTALMINFREQ             19800000        /* 20 MHz - 1% */
175 #define XTALMAXFREQ             20200000        /* 20 MHz + 1% */
176 #define PCIMINFREQ              25000000        /* 25 MHz */
177 #define PCIMAXFREQ              34000000        /* 33 MHz + fudge */
178
179 #define ILP_DIV_5MHZ            0       /* ILP = 5 MHz */
180 #define ILP_DIV_1MHZ            4       /* ILP = 1 MHz */
181
182 /* force HT war check */
183 #define FORCEHT_WAR32414(si)    \
184         (((PCIE(si)) && (si->sb.chip == BCM4311_CHIP_ID) && ((si->sb.chiprev <= 1))) || \
185         ((PCI(si) || PCIE(si)) && (si->sb.chip == BCM4321_CHIP_ID) && (si->sb.chiprev <= 3)))
186
187 #define PCIE_ASPMWARS(si)       \
188         ((PCIE(si)) && ((si->sb.buscorerev >= 3) && (si->sb.buscorerev <= 5)))
189
190 /* GPIO Based LED powersave defines */
191 #define DEFAULT_GPIO_ONTIME     10      /* Default: 10% on */
192 #define DEFAULT_GPIO_OFFTIME    90      /* Default: 10% on */
193
194 #define DEFAULT_GPIOTIMERVAL  ((DEFAULT_GPIO_ONTIME << GPIO_ONTIME_SHIFT) | DEFAULT_GPIO_OFFTIME)
195
196 static uint32 sb_read_sbreg(sb_info_t * si, volatile uint32 * sbr)
197 {
198         uint8 tmp;
199         uint32 val, intr_val = 0;
200
201         /*
202          * compact flash only has 11 bits address, while we needs 12 bits address.
203          * MEM_SEG will be OR'd with other 11 bits address in hardware,
204          * so we program MEM_SEG with 12th bit when necessary(access sb regsiters).
205          * For normal PCMCIA bus(CFTable_regwinsz > 2k), do nothing special
206          */
207         if (PCMCIA(si)) {
208                 INTR_OFF(si, intr_val);
209                 tmp = 1;
210                 OSL_PCMCIA_WRITE_ATTR(si->osh, MEM_SEG, &tmp, 1);
211                 sbr = (volatile uint32 *)((uintptr) sbr & ~(1 << 11));  /* mask out bit 11 */
212         }
213
214         val = R_REG(si->osh, sbr);
215
216         if (PCMCIA(si)) {
217                 tmp = 0;
218                 OSL_PCMCIA_WRITE_ATTR(si->osh, MEM_SEG, &tmp, 1);
219                 INTR_RESTORE(si, intr_val);
220         }
221
222         return (val);
223 }
224
225 static void sb_write_sbreg(sb_info_t * si, volatile uint32 * sbr, uint32 v)
226 {
227         uint8 tmp;
228         volatile uint32 dummy;
229         uint32 intr_val = 0;
230
231         /*
232          * compact flash only has 11 bits address, while we needs 12 bits address.
233          * MEM_SEG will be OR'd with other 11 bits address in hardware,
234          * so we program MEM_SEG with 12th bit when necessary(access sb regsiters).
235          * For normal PCMCIA bus(CFTable_regwinsz > 2k), do nothing special
236          */
237         if (PCMCIA(si)) {
238                 INTR_OFF(si, intr_val);
239                 tmp = 1;
240                 OSL_PCMCIA_WRITE_ATTR(si->osh, MEM_SEG, &tmp, 1);
241                 sbr = (volatile uint32 *)((uintptr) sbr & ~(1 << 11));  /* mask out bit 11 */
242         }
243
244         if (BUSTYPE(si->sb.bustype) == PCMCIA_BUS) {
245 #ifdef IL_BIGENDIAN
246                 dummy = R_REG(si->osh, sbr);
247                 W_REG(si->osh, ((volatile uint16 *)sbr + 1),
248                       (uint16) ((v >> 16) & 0xffff));
249                 dummy = R_REG(si->osh, sbr);
250                 W_REG(si->osh, (volatile uint16 *)sbr, (uint16) (v & 0xffff));
251 #else
252                 dummy = R_REG(si->osh, sbr);
253                 W_REG(si->osh, (volatile uint16 *)sbr, (uint16) (v & 0xffff));
254                 dummy = R_REG(si->osh, sbr);
255                 W_REG(si->osh, ((volatile uint16 *)sbr + 1),
256                       (uint16) ((v >> 16) & 0xffff));
257 #endif /* IL_BIGENDIAN */
258         } else
259                 W_REG(si->osh, sbr, v);
260
261         if (PCMCIA(si)) {
262                 tmp = 0;
263                 OSL_PCMCIA_WRITE_ATTR(si->osh, MEM_SEG, &tmp, 1);
264                 INTR_RESTORE(si, intr_val);
265         }
266 }
267
268 /*
269  * Allocate a sb handle.
270  * devid - pci device id (used to determine chip#)
271  * osh - opaque OS handle
272  * regs - virtual address of initial core registers
273  * bustype - pci/pcmcia/sb/sdio/etc
274  * vars - pointer to a pointer area for "environment" variables
275  * varsz - pointer to int to return the size of the vars
276  */
277 sb_t *sb_attach(uint devid, osl_t * osh, void *regs,
278                             uint bustype, void *sdh, char **vars,
279                             uint * varsz) {
280         sb_info_t *si;
281
282         /* alloc sb_info_t */
283         if ((si = MALLOC(osh, sizeof(sb_info_t))) == NULL) {
284                 SB_ERROR(("sb_attach: malloc failed! malloced %d bytes\n",
285                           MALLOCED(osh)));
286                 return (NULL);
287         }
288
289         if (sb_doattach(si, devid, osh, regs, bustype, sdh, vars, varsz) ==
290             NULL) {
291                 MFREE(osh, si, sizeof(sb_info_t));
292                 return (NULL);
293         }
294         si->vars = vars ? *vars : NULL;
295         si->varsz = varsz ? *varsz : 0;
296
297         return (sb_t *) si;
298 }
299
300 /* Using sb_kattach depends on SB_BUS support, either implicit  */
301 /* no limiting BCMBUSTYPE value) or explicit (value is SB_BUS). */
302 #if !defined(BCMBUSTYPE) || (BCMBUSTYPE == SB_BUS)
303
304 /* global kernel resource */
305 static sb_info_t ksi;
306
307 /* generic kernel variant of sb_attach() */
308 sb_t *BCMINITFN(sb_kattach) (osl_t * osh) {
309         static bool ksi_attached = FALSE;
310         uint32 *regs;
311
312         if (!ksi_attached) {
313                 uint32 cid;
314
315                 regs = (uint32 *) REG_MAP(SB_ENUM_BASE, SB_CORE_SIZE);
316                 cid = R_REG(osh, (uint32 *) regs);
317                 if (((cid & CID_ID_MASK) == BCM4712_CHIP_ID) &&
318                     ((cid & CID_PKG_MASK) != BCM4712LARGE_PKG_ID) &&
319                     ((cid & CID_REV_MASK) <= (3 << CID_REV_SHIFT))) {
320                         uint32 *scc, val;
321
322                         scc =
323                             (uint32 *) ((uchar *) regs +
324                                         OFFSETOF(chipcregs_t, slow_clk_ctl));
325                         val = R_REG(osh, scc);
326                         SB_ERROR(("    initial scc = 0x%x\n", val));
327                         val |= SCC_SS_XTAL;
328                         W_REG(osh, scc, val);
329                 }
330
331                 if (sb_doattach(&ksi, BCM4710_DEVICE_ID, osh, (void *)regs, SB_BUS, NULL,
332                                 osh != SB_OSH ? &ksi.vars : NULL,
333                                 osh != SB_OSH ? &ksi.varsz : NULL) == NULL)
334                         return NULL;
335                 ksi_attached = TRUE;
336         }
337
338         return &ksi.sb;
339 }
340 #endif /* !BCMBUSTYPE || (BCMBUSTYPE == SB_BUS) */
341
342 static sb_info_t *BCMINITFN(sb_doattach) (sb_info_t * si, uint devid,
343                                           osl_t * osh, void *regs,
344                                           uint bustype, void *sdh,
345                                           char **vars, uint * varsz) {
346         uint origidx;
347         chipcregs_t *cc;
348         sbconfig_t *sb;
349         uint32 w;
350         char *pvars;
351
352         ASSERT(GOODREGS(regs));
353
354         bzero((uchar *) si, sizeof(sb_info_t));
355         si->sb.buscoreidx = si->gpioidx = BADIDX;
356
357         si->curmap = regs;
358         si->sdh = sdh;
359         si->osh = osh;
360
361         /* check to see if we are a sb core mimic'ing a pci core */
362         if (bustype == PCI_BUS) {
363                 if (OSL_PCI_READ_CONFIG
364                     (si->osh, PCI_SPROM_CONTROL,
365                      sizeof(uint32)) == 0xffffffff) {
366                         SB_ERROR(("%s: incoming bus is PCI but it's a lie, switching to SB " "devid:0x%x\n", __FUNCTION__, devid));
367                         bustype = SB_BUS;
368                 }
369         }
370         si->sb.bustype = bustype;
371         if (si->sb.bustype != BUSTYPE(si->sb.bustype)) {
372                 SB_ERROR(("sb_doattach: bus type %d does not match configured bus type %d\n", si->sb.bustype, BUSTYPE(si->sb.bustype)));
373                 return NULL;
374         }
375
376         /* need to set memseg flag for CF card first before any sb registers access */
377         if (BUSTYPE(si->sb.bustype) == PCMCIA_BUS)
378                 si->memseg = TRUE;
379
380         /* kludge to enable the clock on the 4306 which lacks a slowclock */
381         if (BUSTYPE(si->sb.bustype) == PCI_BUS && !sb_ispcie(si))
382                 sb_clkctl_xtal(&si->sb, XTAL | PLL, ON);
383
384         if (BUSTYPE(si->sb.bustype) == PCI_BUS) {
385                 w = OSL_PCI_READ_CONFIG(si->osh, PCI_BAR0_WIN, sizeof(uint32));
386                 if (!GOODCOREADDR(w))
387                         OSL_PCI_WRITE_CONFIG(si->osh, PCI_BAR0_WIN,
388                                              sizeof(uint32), SB_ENUM_BASE);
389         }
390
391         /* initialize current core index value */
392         si->curidx = _sb_coreidx(si);
393
394         if (si->curidx == BADIDX) {
395                 SB_ERROR(("sb_doattach: bad core index\n"));
396                 return NULL;
397         }
398
399         /* get sonics backplane revision */
400         sb = REGS2SB(regs);
401         si->sb.sonicsrev =
402             (R_SBREG(si, &sb->sbidlow) & SBIDL_RV_MASK) >> SBIDL_RV_SHIFT;
403         /* keep and reuse the initial register mapping */
404         origidx = si->curidx;
405         if (BUSTYPE(si->sb.bustype) == SB_BUS)
406                 si->regs[origidx] = regs;
407
408         /* is core-0 a chipcommon core? */
409         si->numcores = 1;
410         cc = (chipcregs_t *) sb_setcoreidx(&si->sb, 0);
411         if (sb_coreid(&si->sb) != SB_CC)
412                 cc = NULL;
413
414         /* determine chip id and rev */
415         if (cc) {
416                 /* chip common core found! */
417                 si->sb.chip = R_REG(si->osh, &cc->chipid) & CID_ID_MASK;
418                 si->sb.chiprev =
419                     (R_REG(si->osh, &cc->chipid) & CID_REV_MASK) >>
420                     CID_REV_SHIFT;
421                 si->sb.chippkg =
422                     (R_REG(si->osh, &cc->chipid) & CID_PKG_MASK) >>
423                     CID_PKG_SHIFT;
424         } else {
425                 /* no chip common core -- must convert device id to chip id */
426                 if ((si->sb.chip = sb_pcidev2chip(devid)) == 0) {
427                         SB_ERROR(("sb_doattach: unrecognized device id 0x%04x\n", devid));
428                         sb_setcoreidx(&si->sb, origidx);
429                         return NULL;
430                 }
431         }
432
433         /* get chipcommon rev */
434         si->sb.ccrev = cc ? (int)sb_corerev(&si->sb) : NOREV;
435
436         /* get chipcommon capabilites */
437         si->sb.cccaps = cc ? R_REG(si->osh, &cc->capabilities) : 0;
438
439         /* determine numcores */
440         if (cc && ((si->sb.ccrev == 4) || (si->sb.ccrev >= 6)))
441                 si->numcores =
442                     (R_REG(si->osh, &cc->chipid) & CID_CC_MASK) >> CID_CC_SHIFT;
443         else
444                 si->numcores = sb_chip2numcores(si->sb.chip);
445
446         /* return to original core */
447         sb_setcoreidx(&si->sb, origidx);
448
449         /* sanity checks */
450         ASSERT(si->sb.chip);
451
452         /* scan for cores */
453         sb_scan(si);
454
455         /* fixup necessary chip/core configurations */
456         if (BUSTYPE(si->sb.bustype) == PCI_BUS && sb_pci_fixcfg(si)) {
457                 SB_ERROR(("sb_doattach: sb_pci_fixcfg failed\n"));
458                 return NULL;
459         }
460
461         /* Init nvram from sprom/otp if they exist */
462         if (srom_var_init
463             (&si->sb, BUSTYPE(si->sb.bustype), regs, si->osh, vars, varsz)) {
464                 SB_ERROR(("sb_doattach: srom_var_init failed: bad srom\n"));
465                 return (NULL);
466         }
467         pvars = vars ? *vars : NULL;
468
469         /* PMU specific initializations */
470         if ((si->sb.cccaps & CC_CAP_PMU) && !sb_onetimeinit) {
471                 sb_pmu_init(&si->sb, si->osh);
472                 /* Find out Crystal frequency and init PLL */
473                 sb_pmu_pll_init(&si->sb, si->osh, getintvar(pvars, "xtalfreq"));
474                 /* Initialize PMU resources (up/dn timers, dep masks, etc.) */
475                 sb_pmu_res_init(&si->sb, si->osh);
476         }
477         if (cc == NULL) {
478                 /*
479                  * The chip revision number is hardwired into all
480                  * of the pci function config rev fields and is
481                  * independent from the individual core revision numbers.
482                  * For example, the "A0" silicon of each chip is chip rev 0.
483                  * For PCMCIA we get it from the CIS instead.
484                  */
485                 if (BUSTYPE(si->sb.bustype) == PCMCIA_BUS) {
486                         ASSERT(vars);
487                         si->sb.chiprev = getintvar(*vars, "chiprev");
488                 } else if (BUSTYPE(si->sb.bustype) == PCI_BUS) {
489                         w = OSL_PCI_READ_CONFIG(si->osh, PCI_CFG_REV,
490                                                 sizeof(uint32));
491                         si->sb.chiprev = w & 0xff;
492                 } else
493                         si->sb.chiprev = 0;
494         }
495
496         if (BUSTYPE(si->sb.bustype) == PCMCIA_BUS) {
497                 w = getintvar(pvars, "regwindowsz");
498                 si->memseg = (w <= CFTABLE_REGWIN_2K) ? TRUE : FALSE;
499         }
500         /* gpio control core is required */
501         if (!GOODIDX(si->gpioidx)) {
502                 SB_ERROR(("sb_doattach: gpio control core not found\n"));
503                 return NULL;
504         }
505
506         /* get boardtype and boardrev */
507         switch (BUSTYPE(si->sb.bustype)) {
508         case PCI_BUS:
509                 /* do a pci config read to get subsystem id and subvendor id */
510                 w = OSL_PCI_READ_CONFIG(si->osh, PCI_CFG_SVID, sizeof(uint32));
511                 /* Let nvram variables override subsystem Vend/ID */
512                 if ((si->sb.boardvendor =
513                      (uint16) sb_getdevpathintvar(&si->sb, "boardvendor")) == 0)
514                         si->sb.boardvendor = w & 0xffff;
515                 else
516                         SB_ERROR(("Overriding boardvendor: 0x%x instead of 0x%x\n", si->sb.boardvendor, w & 0xffff));
517                 if ((si->sb.boardtype =
518                      (uint16) sb_getdevpathintvar(&si->sb, "boardtype")) == 0)
519                         si->sb.boardtype = (w >> 16) & 0xffff;
520                 else
521                         SB_ERROR(("Overriding boardtype: 0x%x instead of 0x%x\n", si->sb.boardtype, (w >> 16) & 0xffff));
522                 break;
523
524         case PCMCIA_BUS:
525                 si->sb.boardvendor = getintvar(pvars, "manfid");
526                 si->sb.boardtype = getintvar(pvars, "prodid");
527                 break;
528
529         case SB_BUS:
530         case JTAG_BUS:
531                 si->sb.boardvendor = VENDOR_BROADCOM;
532                 if (pvars == NULL
533                     || ((si->sb.boardtype = getintvar(pvars, "prodid")) == 0))
534                         if ((si->sb.boardtype =
535                              getintvar(NULL, "boardtype")) == 0)
536                                 si->sb.boardtype = 0xffff;
537                 break;
538         }
539
540         if (si->sb.boardtype == 0) {
541                 SB_ERROR(("sb_doattach: unknown board type\n"));
542                 ASSERT(si->sb.boardtype);
543         }
544
545         si->sb.boardflags = getintvar(pvars, "boardflags");
546
547         /* setup the GPIO based LED powersave register */
548         if (si->sb.ccrev >= 16) {
549                 if ((pvars == NULL) || ((w = getintvar(pvars, "leddc")) == 0))
550                         w = DEFAULT_GPIOTIMERVAL;
551                 sb_corereg(&si->sb, SB_CC_IDX,
552                            OFFSETOF(chipcregs_t, gpiotimerval), ~0, w);
553         }
554
555         /* Determine if this board needs override */
556         if (PCIE(si) && (si->sb.chip == BCM4321_CHIP_ID))
557                 si->pcie_war_ovr = ((si->sb.boardvendor == VENDOR_APPLE) &&
558                                     ((uint8) getintvar(pvars, "sromrev") == 4)
559                                     && ((uint8) getintvar(pvars, "boardrev") <=
560                                         0x71))
561                     || ((uint32) getintvar(pvars, "boardflags2") &
562                         BFL2_PCIEWAR_OVR);
563
564         if (PCIE_ASPMWARS(si)) {
565                 sb_war43448_aspm((void *)si);
566                 sb_war42767_clkreq((void *)si);
567         }
568
569         if (FORCEHT_WAR32414(si)) {
570                 si->sb.pr32414 = TRUE;
571                 sb_clkctl_init(&si->sb);
572                 sb_war32414_forceHT(&si->sb, 1);
573         }
574
575         if (PCIE(si) && ((si->sb.buscorerev == 6) || (si->sb.buscorerev == 7)))
576                 si->sb.pr42780 = TRUE;
577
578         if (PCIE_ASPMWARS(si))
579                 sb_pcieclkreq(&si->sb, 1, 0);
580
581         if (PCIE(si) &&
582             (((si->sb.chip == BCM4311_CHIP_ID) && (si->sb.chiprev == 2)) ||
583              ((si->sb.chip == BCM4312_CHIP_ID) && (si->sb.chiprev == 0))))
584                 sb_set_initiator_to(&si->sb, 0x3,
585                                     sb_findcoreidx(&si->sb, SB_D11, 0));
586
587         /* Disable gpiopullup and gpiopulldown */
588         if (!sb_onetimeinit && si->sb.ccrev >= 20) {
589                 cc = (chipcregs_t *) sb_setcore(&si->sb, SB_CC, 0);
590                 W_REG(osh, &cc->gpiopullup, 0);
591                 W_REG(osh, &cc->gpiopulldown, 0);
592                 sb_setcoreidx(&si->sb, origidx);
593         }
594 #ifdef BCMDBG
595         /* clear any previous epidiag-induced target abort */
596         sb_taclear(&si->sb);
597 #endif /* BCMDBG */
598
599 #ifdef HNDRTE
600         sb_onetimeinit = TRUE;
601 #endif
602
603         return (si);
604 }
605
606 /* Enable/Disable clkreq for PCIE (4311B0/4321B1) */
607 void sb_war42780_clkreq(sb_t * sbh, bool clkreq) {
608         sb_info_t *si;
609
610         si = SB_INFO(sbh);
611
612         /* Don't change clkreq value if serdespll war has not yet been applied */
613         if (!si->pr42767_war && PCIE_ASPMWARS(si))
614                 return;
615
616         sb_pcieclkreq(sbh, 1, (int32) clkreq);
617 }
618
619 static void BCMINITFN(sb_war43448) (sb_t * sbh) {
620         sb_info_t *si;
621
622         si = SB_INFO(sbh);
623
624         /* if not pcie bus, we're done */
625         if (!PCIE(si) || !PCIE_ASPMWARS(si))
626                 return;
627
628         /* Restore the polarity */
629         if (si->pcie_polarity != 0)
630                 sb_pcie_mdiowrite((void *)(uintptr) & si->sb, MDIODATA_DEV_RX,
631                                   SERDES_RX_CTRL, si->pcie_polarity);
632 }
633
634 static void BCMINITFN(sb_war43448_aspm) (sb_t * sbh) {
635         uint32 w;
636         uint16 val16, *reg16;
637         sbpcieregs_t *pcieregs;
638         sb_info_t *si;
639
640         si = SB_INFO(sbh);
641
642         /* if not pcie bus, we're done */
643         if (!PCIE(si) || !PCIE_ASPMWARS(si))
644                 return;
645
646         /* no ASPM stuff on QT or VSIM */
647         if (si->sb.chippkg == HDLSIM_PKG_ID || si->sb.chippkg == HWSIM_PKG_ID)
648                 return;
649
650         pcieregs = (sbpcieregs_t *) sb_setcoreidx(sbh, si->sb.buscoreidx);
651
652         /* Enable ASPM in the shadow SROM and Link control */
653         reg16 = &pcieregs->sprom[SRSH_ASPM_OFFSET];
654         val16 = R_REG(si->osh, reg16);
655         if (!si->pcie_war_ovr)
656                 val16 |= SRSH_ASPM_ENB;
657         else
658                 val16 &= ~SRSH_ASPM_ENB;
659         W_REG(si->osh, reg16, val16);
660
661         w = OSL_PCI_READ_CONFIG(si->osh, si->pciecap_lcreg_offset,
662                                 sizeof(uint32));
663         if (!si->pcie_war_ovr)
664                 w |= PCIE_ASPM_ENAB;
665         else
666                 w &= ~PCIE_ASPM_ENAB;
667         OSL_PCI_WRITE_CONFIG(si->osh, si->pciecap_lcreg_offset, sizeof(uint32),
668                              w);
669 }
670
671 static void BCMINITFN(sb_war32414_forceHT) (sb_t * sbh, bool forceHT) {
672         sb_info_t *si;
673         uint32 val = 0;
674
675         si = SB_INFO(sbh);
676
677         ASSERT(FORCEHT_WAR32414(si));
678
679         if (forceHT)
680                 val = SYCC_HR;
681         sb_corereg(sbh, SB_CC_IDX, OFFSETOF(chipcregs_t, system_clk_ctl),
682                    SYCC_HR, val);
683 }
684
685 uint sb_coreid(sb_t * sbh)
686 {
687         sb_info_t *si;
688         sbconfig_t *sb;
689
690         si = SB_INFO(sbh);
691         sb = REGS2SB(si->curmap);
692
693         return ((R_SBREG(si, &sb->sbidhigh) & SBIDH_CC_MASK) >> SBIDH_CC_SHIFT);
694 }
695
696 uint sb_flag(sb_t * sbh)
697 {
698         sb_info_t *si;
699         sbconfig_t *sb;
700
701         si = SB_INFO(sbh);
702         sb = REGS2SB(si->curmap);
703
704         return R_SBREG(si, &sb->sbtpsflag) & SBTPS_NUM0_MASK;
705 }
706
707 uint sb_coreidx(sb_t * sbh)
708 {
709         sb_info_t *si;
710
711         si = SB_INFO(sbh);
712         return (si->curidx);
713 }
714
715 static uint _sb_coreidx(sb_info_t * si)
716 {
717
718         sbconfig_t *sb;
719         uint32 sbaddr = 0;
720
721         ASSERT(si);
722
723         switch (BUSTYPE(si->sb.bustype)) {
724         case SB_BUS:
725                 sb = REGS2SB(si->curmap);
726                 sbaddr = sb_base(R_SBREG(si, &sb->sbadmatch0));
727                 break;
728
729         case PCI_BUS:
730                 sbaddr =
731                     OSL_PCI_READ_CONFIG(si->osh, PCI_BAR0_WIN, sizeof(uint32));
732                 break;
733
734         case PCMCIA_BUS:{
735                         uint8 tmp = 0;
736
737                         OSL_PCMCIA_READ_ATTR(si->osh, PCMCIA_ADDR0, &tmp, 1);
738                         sbaddr = (uint) tmp << 12;
739                         OSL_PCMCIA_READ_ATTR(si->osh, PCMCIA_ADDR1, &tmp, 1);
740                         sbaddr |= (uint) tmp << 16;
741                         OSL_PCMCIA_READ_ATTR(si->osh, PCMCIA_ADDR2, &tmp, 1);
742                         sbaddr |= (uint) tmp << 24;
743                         break;
744                 }
745
746 #ifdef BCMJTAG
747         case JTAG_BUS:
748                 sbaddr = (uint32) si->curmap;
749                 break;
750 #endif /* BCMJTAG */
751
752         default:
753                 ASSERT(0);
754         }
755
756         if (!GOODCOREADDR(sbaddr))
757                 return BADIDX;
758
759         return ((sbaddr - SB_ENUM_BASE) / SB_CORE_SIZE);
760 }
761
762 uint sb_corevendor(sb_t * sbh)
763 {
764         sb_info_t *si;
765         sbconfig_t *sb;
766
767         si = SB_INFO(sbh);
768         sb = REGS2SB(si->curmap);
769
770         return ((R_SBREG(si, &sb->sbidhigh) & SBIDH_VC_MASK) >> SBIDH_VC_SHIFT);
771 }
772
773 uint sb_corerev(sb_t * sbh)
774 {
775         sb_info_t *si;
776         sbconfig_t *sb;
777         uint sbidh;
778
779         si = SB_INFO(sbh);
780         sb = REGS2SB(si->curmap);
781         sbidh = R_SBREG(si, &sb->sbidhigh);
782
783         return (SBCOREREV(sbidh));
784 }
785
786 void *sb_osh(sb_t * sbh)
787 {
788         sb_info_t *si;
789
790         si = SB_INFO(sbh);
791         return si->osh;
792 }
793
794 void sb_setosh(sb_t * sbh, osl_t * osh)
795 {
796         sb_info_t *si;
797
798         si = SB_INFO(sbh);
799         if (si->osh != NULL) {
800                 SB_ERROR(("osh is already set....\n"));
801                 ASSERT(!si->osh);
802         }
803         si->osh = osh;
804 }
805
806 /* set sbtmstatelow core-specific flags */
807 void sb_coreflags_wo(sb_t * sbh, uint32 mask, uint32 val)
808 {
809         sb_info_t *si;
810         sbconfig_t *sb;
811         uint32 w;
812
813         si = SB_INFO(sbh);
814         sb = REGS2SB(si->curmap);
815
816         ASSERT((val & ~mask) == 0);
817
818         /* mask and set */
819         w = (R_SBREG(si, &sb->sbtmstatelow) & ~mask) | val;
820         W_SBREG(si, &sb->sbtmstatelow, w);
821 }
822
823 /* set/clear sbtmstatelow core-specific flags */
824 uint32 sb_coreflags(sb_t * sbh, uint32 mask, uint32 val)
825 {
826         sb_info_t *si;
827         sbconfig_t *sb;
828         uint32 w;
829
830         si = SB_INFO(sbh);
831         sb = REGS2SB(si->curmap);
832
833         ASSERT((val & ~mask) == 0);
834
835         /* mask and set */
836         if (mask || val) {
837                 w = (R_SBREG(si, &sb->sbtmstatelow) & ~mask) | val;
838                 W_SBREG(si, &sb->sbtmstatelow, w);
839         }
840
841         /* return the new value
842          * for write operation, the following readback ensures the completion of write opration.
843          */
844         return (R_SBREG(si, &sb->sbtmstatelow));
845 }
846
847 /* set/clear sbtmstatehigh core-specific flags */
848 uint32 sb_coreflagshi(sb_t * sbh, uint32 mask, uint32 val)
849 {
850         sb_info_t *si;
851         sbconfig_t *sb;
852         uint32 w;
853
854         si = SB_INFO(sbh);
855         sb = REGS2SB(si->curmap);
856
857         ASSERT((val & ~mask) == 0);
858         ASSERT((mask & ~SBTMH_FL_MASK) == 0);
859
860         /* mask and set */
861         if (mask || val) {
862                 w = (R_SBREG(si, &sb->sbtmstatehigh) & ~mask) | val;
863                 W_SBREG(si, &sb->sbtmstatehigh, w);
864         }
865
866         /* return the new value */
867         return (R_SBREG(si, &sb->sbtmstatehigh));
868 }
869
870 /* Run bist on current core. Caller needs to take care of core-specific bist hazards */
871 int sb_corebist(sb_t * sbh)
872 {
873         uint32 sblo;
874         sb_info_t *si;
875         sbconfig_t *sb;
876         int result = 0;
877
878         si = SB_INFO(sbh);
879         sb = REGS2SB(si->curmap);
880
881         sblo = R_SBREG(si, &sb->sbtmstatelow);
882         W_SBREG(si, &sb->sbtmstatelow, (sblo | SBTML_FGC | SBTML_BE));
883
884         SPINWAIT(((R_SBREG(si, &sb->sbtmstatehigh) & SBTMH_BISTD) == 0),
885                  100000);
886
887         if (R_SBREG(si, &sb->sbtmstatehigh) & SBTMH_BISTF)
888                 result = -1;
889
890         W_SBREG(si, &sb->sbtmstatelow, sblo);
891
892         return result;
893 }
894
895 bool sb_iscoreup(sb_t * sbh)
896 {
897         sb_info_t *si;
898         sbconfig_t *sb;
899
900         si = SB_INFO(sbh);
901         sb = REGS2SB(si->curmap);
902
903         return ((R_SBREG(si, &sb->sbtmstatelow) &
904                  (SBTML_RESET | SBTML_REJ_MASK | SBTML_CLK)) == SBTML_CLK);
905 }
906
907 /*
908  * Switch to 'coreidx', issue a single arbitrary 32bit register mask&set operation,
909  * switch back to the original core, and return the new value.
910  *
911  * When using the silicon backplane, no fidleing with interrupts or core switches are needed.
912  *
913  * Also, when using pci/pcie, we can optimize away the core switching for pci registers
914  * and (on newer pci cores) chipcommon registers.
915  */
916 uint sb_corereg(sb_t * sbh, uint coreidx, uint regoff, uint mask, uint val)
917 {
918         uint origidx = 0;
919         uint32 *r = NULL;
920         uint w;
921         uint intr_val = 0;
922         bool fast = FALSE;
923         sb_info_t *si;
924
925         si = SB_INFO(sbh);
926
927         ASSERT(GOODIDX(coreidx));
928         ASSERT(regoff < SB_CORE_SIZE);
929         ASSERT((val & ~mask) == 0);
930
931 #if 0
932         if (BUSTYPE(si->sb.bustype) == SB_BUS) {
933                 /* If internal bus, we can always get at everything */
934                 fast = TRUE;
935                 /* map if does not exist */
936                 if (!si->regs[coreidx]) {
937                         si->regs[coreidx] =
938                             (void *)REG_MAP(si->coresba[coreidx], SB_CORE_SIZE);
939                         ASSERT(GOODREGS(si->regs[coreidx]));
940                 }
941                 r = (uint32 *) ((uchar *) si->regs[coreidx] + regoff);
942         } else if (BUSTYPE(si->sb.bustype) == PCI_BUS) {
943                 /* If pci/pcie, we can get at pci/pcie regs and on newer cores to chipc */
944
945                 if ((si->coreid[coreidx] == SB_CC) &&
946                     ((si->sb.buscoretype == SB_PCIE)
947                      || (si->sb.buscorerev >= 13))) {
948                         /* Chipc registers are mapped at 12KB */
949
950                         fast = TRUE;
951                         r = (uint32 *) ((char *)si->curmap +
952                                         PCI_16KB0_CCREGS_OFFSET + regoff);
953                 } else if (si->sb.buscoreidx == coreidx) {
954                         /* pci registers are at either in the last 2KB of an 8KB window
955                          * or, in pcie and pci rev 13 at 8KB
956                          */
957                         fast = TRUE;
958                         if ((si->sb.buscoretype == SB_PCIE)
959                             || (si->sb.buscorerev >= 13))
960                                 r = (uint32 *) ((char *)si->curmap +
961                                                 PCI_16KB0_PCIREGS_OFFSET +
962                                                 regoff);
963                         else
964                                 r = (uint32 *) ((char *)si->curmap +
965                                                 ((regoff >= SBCONFIGOFF) ?
966                                                  PCI_BAR0_PCISBR_OFFSET :
967                                                  PCI_BAR0_PCIREGS_OFFSET)
968                                                 + regoff);
969                 }
970         }
971 #endif
972
973         if (!fast) {
974                 INTR_OFF(si, intr_val);
975
976                 /* save current core index */
977                 origidx = sb_coreidx(&si->sb);
978
979                 /* switch core */
980                 r = (uint32 *) ((uchar *) sb_setcoreidx(&si->sb, coreidx) +
981                                 regoff);
982         }
983         ASSERT(r);
984
985         /* mask and set */
986         if (mask || val) {
987                 if (regoff >= SBCONFIGOFF) {
988                         w = (R_SBREG(si, r) & ~mask) | val;
989                         W_SBREG(si, r, w);
990                 } else {
991                         w = (R_REG(si->osh, r) & ~mask) | val;
992                         W_REG(si->osh, r, w);
993                 }
994         }
995
996         /* readback */
997         if (regoff >= SBCONFIGOFF)
998                 w = R_SBREG(si, r);
999         else {
1000                 if ((si->sb.chip == BCM5354_CHIP_ID) &&
1001                     (coreidx == SB_CC_IDX) &&
1002                     (regoff == OFFSETOF(chipcregs_t, watchdog))) {
1003                         w = val;
1004                 } else
1005                         w = R_REG(si->osh, r);
1006         }
1007
1008         if (!fast) {
1009                 /* restore core index */
1010                 if (origidx != coreidx)
1011                         sb_setcoreidx(&si->sb, origidx);
1012
1013                 INTR_RESTORE(si, intr_val);
1014         }
1015
1016         return (w);
1017 }
1018
1019 #define DWORD_ALIGN(x)  (x & ~(0x03))
1020 #define BYTE_POS(x) (x & 0x3)
1021 #define WORD_POS(x) (x & 0x1)
1022
1023 #define BYTE_SHIFT(x)  (8 * BYTE_POS(x))
1024 #define WORD_SHIFT(x)  (16 * WORD_POS(x))
1025
1026 #define BYTE_VAL(a, x) ((a >> BYTE_SHIFT(x)) & 0xFF)
1027 #define WORD_VAL(a, x) ((a >> WORD_SHIFT(x)) & 0xFFFF)
1028
1029 #define read_pci_cfg_byte(a) \
1030         (BYTE_VAL(OSL_PCI_READ_CONFIG(si->osh, DWORD_ALIGN(a), 4), a) & 0xff)
1031
1032 #define read_pci_cfg_word(a) \
1033         (WORD_VAL(OSL_PCI_READ_CONFIG(si->osh, DWORD_ALIGN(a), 4), a) & 0xffff)
1034
1035 /* return cap_offset if requested capability exists in the PCI config space */
1036 static uint8
1037 sb_find_pci_capability(sb_info_t * si, uint8 req_cap_id, uchar * buf,
1038                        uint32 * buflen)
1039 {
1040         uint8 cap_id;
1041         uint8 cap_ptr = 0;
1042         uint32 bufsize;
1043         uint8 byte_val;
1044
1045         if (BUSTYPE(si->sb.bustype) != PCI_BUS)
1046                 goto end;
1047
1048         /* check for Header type 0 */
1049         byte_val = read_pci_cfg_byte(PCI_CFG_HDR);
1050         if ((byte_val & 0x7f) != PCI_HEADER_NORMAL)
1051                 goto end;
1052
1053         /* check if the capability pointer field exists */
1054         byte_val = read_pci_cfg_byte(PCI_CFG_STAT);
1055         if (!(byte_val & PCI_CAPPTR_PRESENT))
1056                 goto end;
1057
1058         cap_ptr = read_pci_cfg_byte(PCI_CFG_CAPPTR);
1059         /* check if the capability pointer is 0x00 */
1060         if (cap_ptr == 0x00)
1061                 goto end;
1062
1063         /* loop thr'u the capability list and see if the pcie capabilty exists */
1064
1065         cap_id = read_pci_cfg_byte(cap_ptr);
1066
1067         while (cap_id != req_cap_id) {
1068                 cap_ptr = read_pci_cfg_byte((cap_ptr + 1));
1069                 if (cap_ptr == 0x00)
1070                         break;
1071                 cap_id = read_pci_cfg_byte(cap_ptr);
1072         }
1073         if (cap_id != req_cap_id) {
1074                 goto end;
1075         }
1076         /* found the caller requested capability */
1077         if ((buf != NULL) && (buflen != NULL)) {
1078                 uint8 cap_data;
1079
1080                 bufsize = *buflen;
1081                 if (!bufsize)
1082                         goto end;
1083                 *buflen = 0;
1084                 /* copy the cpability data excluding cap ID and next ptr */
1085                 cap_data = cap_ptr + 2;
1086                 if ((bufsize + cap_data) > SZPCR)
1087                         bufsize = SZPCR - cap_data;
1088                 *buflen = bufsize;
1089                 while (bufsize--) {
1090                         *buf = read_pci_cfg_byte(cap_data);
1091                         cap_data++;
1092                         buf++;
1093                 }
1094         }
1095       end:
1096         return cap_ptr;
1097 }
1098
1099 uint8 sb_pcieclkreq(sb_t * sbh, uint32 mask, uint32 val)
1100 {
1101         sb_info_t *si;
1102         uint32 reg_val;
1103         uint8 offset;
1104
1105         si = SB_INFO(sbh);
1106
1107         offset = si->pciecap_lcreg_offset;
1108         if (!offset)
1109                 return 0;
1110
1111         reg_val = OSL_PCI_READ_CONFIG(si->osh, offset, sizeof(uint32));
1112         /* set operation */
1113         if (mask) {
1114                 if (val)
1115                         reg_val |= PCIE_CLKREQ_ENAB;
1116                 else
1117                         reg_val &= ~PCIE_CLKREQ_ENAB;
1118                 OSL_PCI_WRITE_CONFIG(si->osh, offset, sizeof(uint32), reg_val);
1119                 reg_val = OSL_PCI_READ_CONFIG(si->osh, offset, sizeof(uint32));
1120         }
1121         if (reg_val & PCIE_CLKREQ_ENAB)
1122                 return 1;
1123         else
1124                 return 0;
1125 }
1126
1127 #ifdef BCMDBG
1128
1129 uint32 sb_pcielcreg(sb_t * sbh, uint32 mask, uint32 val)
1130 {
1131         sb_info_t *si;
1132         uint32 reg_val;
1133         uint8 offset;
1134
1135         si = SB_INFO(sbh);
1136
1137         if (!PCIE(si))
1138                 return 0;
1139
1140         offset = si->pciecap_lcreg_offset;
1141         if (!offset)
1142                 return 0;
1143
1144         /* set operation */
1145         if (mask)
1146                 OSL_PCI_WRITE_CONFIG(si->osh, offset, sizeof(uint32), val);
1147
1148         reg_val = OSL_PCI_READ_CONFIG(si->osh, offset, sizeof(uint32));
1149
1150         return reg_val;
1151 }
1152
1153 uint8 sb_pcieL1plldown(sb_t * sbh)
1154 {
1155         sb_info_t *si;
1156         uint intr_val = 0;
1157         uint origidx;
1158         uint32 reg_val;
1159
1160         si = SB_INFO(sbh);
1161
1162         if (!PCIE(si))
1163                 return 0;
1164         if (!((si->sb.buscorerev == 3) || (si->sb.buscorerev == 4)))
1165                 return 0;
1166
1167         if (!sb_pcieclkreq((void *)(uintptr) sbh, 0, 0)) {
1168                 SB_ERROR(("PCIEL1PLLDOWN requires Clkreq be enabled, so enable it\n"));
1169                 sb_pcieclkreq((void *)(uintptr) sbh, 1, 1);
1170         }
1171         reg_val = sb_pcielcreg((void *)(uintptr) sbh, 0, 0);
1172         if (reg_val & PCIE_CAP_LCREG_ASPML0s) {
1173                 SB_ERROR(("PCIEL1PLLDOWN requires L0s to be disabled\n"));
1174                 reg_val &= ~PCIE_CAP_LCREG_ASPML0s;
1175                 sb_pcielcreg((void *)(uintptr) sbh, 1, reg_val);
1176         } else
1177                 SB_ERROR(("PCIEL1PLLDOWN: L0s is already disabled\n"));
1178
1179         /* turnoff intrs, change core, set original back, turn on intrs back on  */
1180         origidx = si->curidx;
1181         INTR_OFF(si, intr_val);
1182         sb_setcore(sbh, SB_PCIE, 0);
1183
1184         sb_pcie_writereg((void *)(uintptr) sbh, (void *)PCIE_PCIEREGS,
1185                          PCIE_DLLP_PCIE11, 0);
1186
1187         sb_setcoreidx(sbh, origidx);
1188         INTR_RESTORE(si, intr_val);
1189         return 1;
1190 }
1191 #endif /* BCMDBG */
1192
1193 /* return TRUE if PCIE capability exists in the pci config space */
1194 static bool sb_ispcie(sb_info_t * si)
1195 {
1196         uint8 cap_ptr;
1197
1198         cap_ptr = sb_find_pci_capability(si, PCI_CAP_PCIECAP_ID, NULL, NULL);
1199         if (!cap_ptr)
1200                 return FALSE;
1201
1202         si->pciecap_lcreg_offset = cap_ptr + PCIE_CAP_LINKCTRL_OFFSET;
1203
1204         return TRUE;
1205 }
1206
1207 /* Wake-on-wireless-LAN (WOWL) support functions */
1208 /* return TRUE if PM capability exists in the pci config space */
1209 bool sb_pci_pmecap(sb_t * sbh)
1210 {
1211         uint8 cap_ptr;
1212         uint32 pmecap;
1213         sb_info_t *si;
1214
1215         si = SB_INFO(sbh);
1216
1217         if (si == NULL || !(PCI(si) || PCIE(si)))
1218                 return FALSE;
1219
1220         if (!si->pmecap_offset) {
1221                 cap_ptr =
1222                     sb_find_pci_capability(si, PCI_CAP_POWERMGMTCAP_ID, NULL,
1223                                            NULL);
1224                 if (!cap_ptr)
1225                         return FALSE;
1226
1227                 si->pmecap_offset = cap_ptr;
1228
1229                 pmecap =
1230                     OSL_PCI_READ_CONFIG(si->osh, si->pmecap_offset,
1231                                         sizeof(uint32));
1232
1233                 /* At least one state can generate PME */
1234                 si->pmecap = (pmecap & PME_CAP_PM_STATES) != 0;
1235         }
1236
1237         return (si->pmecap);
1238 }
1239
1240 /* Enable PME generation and disable clkreq */
1241 void sb_pci_pmeen(sb_t * sbh)
1242 {
1243         sb_info_t *si;
1244         uint32 w;
1245         si = SB_INFO(sbh);
1246
1247         /* if not pmecapable return */
1248         if (!sb_pci_pmecap(sbh))
1249                 return;
1250
1251         w = OSL_PCI_READ_CONFIG(si->osh, si->pmecap_offset + PME_CSR_OFFSET,
1252                                 sizeof(uint32));
1253         w |= (PME_CSR_PME_EN);
1254         OSL_PCI_WRITE_CONFIG(si->osh, si->pmecap_offset + PME_CSR_OFFSET,
1255                              sizeof(uint32), w);
1256
1257         /* Disable clkreq */
1258         if (si->pr42767_war) {
1259                 sb_pcieclkreq(sbh, 1, 0);
1260                 si->pr42767_war = FALSE;
1261         } else if (si->sb.pr42780) {
1262                 sb_pcieclkreq(sbh, 1, 1);
1263         }
1264 }
1265
1266 /* Disable PME generation, clear the PME status bit if set and
1267  * return TRUE if PME status set
1268  */
1269 bool sb_pci_pmeclr(sb_t * sbh)
1270 {
1271         sb_info_t *si;
1272         uint32 w;
1273         bool ret = FALSE;
1274
1275         si = SB_INFO(sbh);
1276
1277         if (!sb_pci_pmecap(sbh))
1278                 return ret;
1279
1280         w = OSL_PCI_READ_CONFIG(si->osh, si->pmecap_offset + PME_CSR_OFFSET,
1281                                 sizeof(uint32));
1282
1283         SB_ERROR(("sb_pci_pmeclr PMECSR : 0x%x\n", w));
1284         ret = (w & PME_CSR_PME_STAT) == PME_CSR_PME_STAT;
1285
1286         /* PMESTAT is cleared by writing 1 to it */
1287         w &= ~(PME_CSR_PME_EN);
1288
1289         OSL_PCI_WRITE_CONFIG(si->osh, si->pmecap_offset + PME_CSR_OFFSET,
1290                              sizeof(uint32), w);
1291
1292         return ret;
1293 }
1294
1295 /* use pci dev id to determine chip id for chips not having a chipcommon core */
1296 static uint BCMINITFN(sb_pcidev2chip) (uint pcidev) {
1297         if ((pcidev >= BCM4710_DEVICE_ID) && (pcidev <= BCM47XX_USB_ID))
1298                 return (BCM4710_CHIP_ID);
1299         if ((pcidev >= BCM4402_ENET_ID) && (pcidev <= BCM4402_V90_ID))
1300                 return (BCM4402_CHIP_ID);
1301         if (pcidev == BCM4401_ENET_ID)
1302                 return (BCM4402_CHIP_ID);
1303         if (pcidev == SDIOH_FPGA_ID)
1304                 return (SDIOH_FPGA_ID);
1305
1306         return (0);
1307 }
1308
1309 /* Scan the enumeration space to find all cores starting from the given
1310  * bus 'sbba'. Append coreid and other info to the lists in 'si'. 'sba'
1311  * is the default core address at chip POR time and 'regs' is the virtual
1312  * address that the default core is mapped at. 'ncores' is the number of
1313  * cores expected on bus 'sbba'. It returns the total number of cores
1314  * starting from bus 'sbba', inclusive.
1315  */
1316
1317 static void BCMINITFN(sb_scan) (sb_info_t * si) {
1318         sb_t *sbh;
1319         uint origidx;
1320         uint i;
1321         bool pci;
1322         bool pcie;
1323         uint pciidx;
1324         uint pcieidx;
1325         uint pcirev;
1326         uint pcierev;
1327
1328         sbh = (sb_t *) si;
1329
1330         /* numcores should already be set */
1331         ASSERT((si->numcores > 0) && (si->numcores <= SB_MAXCORES));
1332
1333         /* save current core index */
1334         origidx = sb_coreidx(&si->sb);
1335
1336         si->sb.buscorerev = NOREV;
1337         si->sb.buscoreidx = BADIDX;
1338
1339         si->gpioidx = BADIDX;
1340
1341         pci = pcie = FALSE;
1342         pcirev = pcierev = NOREV;
1343         pciidx = pcieidx = BADIDX;
1344
1345         for (i = 0; i < si->numcores; i++) {
1346                 sb_setcoreidx(&si->sb, i);
1347                 si->coreid[i] = sb_coreid(&si->sb);
1348
1349                 if (si->coreid[i] == SB_PCI) {
1350                         pciidx = i;
1351                         pcirev = sb_corerev(&si->sb);
1352                         pci = TRUE;
1353                 } else if (si->coreid[i] == SB_PCIE) {
1354                         pcieidx = i;
1355                         pcierev = sb_corerev(&si->sb);
1356                         pcie = TRUE;
1357                 } else if (si->coreid[i] == SB_PCMCIA) {
1358                         si->sb.buscorerev = sb_corerev(&si->sb);
1359                         si->sb.buscoretype = si->coreid[i];
1360                         si->sb.buscoreidx = i;
1361                 }
1362         }
1363         if (pci && pcie) {
1364                 if (sb_ispcie(si))
1365                         pci = FALSE;
1366                 else
1367                         pcie = FALSE;
1368         }
1369         if (pci) {
1370                 si->sb.buscoretype = SB_PCI;
1371                 si->sb.buscorerev = pcirev;
1372                 si->sb.buscoreidx = pciidx;
1373         } else if (pcie) {
1374                 si->sb.buscoretype = SB_PCIE;
1375                 si->sb.buscorerev = pcierev;
1376                 si->sb.buscoreidx = pcieidx;
1377         }
1378
1379         /*
1380          * Find the gpio "controlling core" type and index.
1381          * Precedence:
1382          * - if there's a chip common core - use that
1383          * - else if there's a pci core (rev >= 2) - use that
1384          * - else there had better be an extif core (4710 only)
1385          */
1386         if (GOODIDX(sb_findcoreidx(sbh, SB_CC, 0))) {
1387                 si->gpioidx = sb_findcoreidx(sbh, SB_CC, 0);
1388                 si->gpioid = SB_CC;
1389         } else if (PCI(si) && (si->sb.buscorerev >= 2)) {
1390                 si->gpioidx = si->sb.buscoreidx;
1391                 si->gpioid = SB_PCI;
1392         } else if (sb_findcoreidx(sbh, SB_EXTIF, 0)) {
1393                 si->gpioidx = sb_findcoreidx(sbh, SB_EXTIF, 0);
1394                 si->gpioid = SB_EXTIF;
1395         } else
1396                 ASSERT(si->gpioidx != BADIDX);
1397
1398         /* return to original core index */
1399         sb_setcoreidx(&si->sb, origidx);
1400 }
1401
1402 /* may be called with core in reset */
1403 void sb_detach(sb_t * sbh)
1404 {
1405         sb_info_t *si;
1406         uint idx;
1407
1408         si = SB_INFO(sbh);
1409
1410         if (si == NULL)
1411                 return;
1412
1413         if (BUSTYPE(si->sb.bustype) == SB_BUS)
1414                 for (idx = 0; idx < SB_MAXCORES; idx++)
1415                         if (si->regs[idx]) {
1416                                 REG_UNMAP(si->regs[idx]);
1417                                 si->regs[idx] = NULL;
1418                         }
1419 #if !defined(BCMBUSTYPE) || (BCMBUSTYPE == SB_BUS)
1420         if (si != &ksi)
1421 #endif /* !BCMBUSTYPE || (BCMBUSTYPE == SB_BUS) */
1422                 MFREE(si->osh, si, sizeof(sb_info_t));
1423 }
1424
1425
1426 /* convert chip number to number of i/o cores */
1427 static uint BCMINITFN(sb_chip2numcores) (uint chip) {
1428         if (chip == BCM4710_CHIP_ID)
1429                 return (9);
1430         if (chip == BCM4402_CHIP_ID)
1431                 return (3);
1432         if (chip == BCM4306_CHIP_ID)    /* < 4306c0 */
1433                 return (6);
1434         if (chip == BCM4704_CHIP_ID)
1435                 return (9);
1436         if (chip == BCM5365_CHIP_ID)
1437                 return (7);
1438         if (chip == SDIOH_FPGA_ID)
1439                 return (2);
1440
1441         SB_ERROR(("sb_chip2numcores: unsupported chip 0x%x\n", chip));
1442         ASSERT(0);
1443         return (1);
1444 }
1445
1446 /* return index of coreid or BADIDX if not found */
1447 uint sb_findcoreidx(sb_t * sbh, uint coreid, uint coreunit)
1448 {
1449         sb_info_t *si;
1450         uint found;
1451         uint i;
1452
1453         si = SB_INFO(sbh);
1454
1455         found = 0;
1456
1457         for (i = 0; i < si->numcores; i++)
1458                 if (si->coreid[i] == coreid) {
1459                         if (found == coreunit)
1460                                 return (i);
1461                         found++;
1462                 }
1463
1464         return (BADIDX);
1465 }
1466
1467 /* 
1468  * this function changes logical "focus" to the indiciated core,
1469  * must be called with interrupt off.
1470  * Moreover, callers should keep interrupts off during switching out of and back to d11 core
1471  */
1472 void *sb_setcoreidx(sb_t * sbh, uint coreidx)
1473 {
1474         sb_info_t *si;
1475         uint32 sbaddr;
1476         uint8 tmp;
1477
1478         si = SB_INFO(sbh);
1479
1480         if (coreidx >= si->numcores)
1481                 return (NULL);
1482
1483         /*
1484          * If the user has provided an interrupt mask enabled function,
1485          * then assert interrupts are disabled before switching the core.
1486          */
1487         ASSERT((si->intrsenabled_fn == NULL)
1488                || !(*(si)->intrsenabled_fn) ((si)->intr_arg));
1489
1490         sbaddr = SB_ENUM_BASE + (coreidx * SB_CORE_SIZE);
1491
1492         switch (BUSTYPE(si->sb.bustype)) {
1493         case SB_BUS:
1494                 /* map new one */
1495                 if (!si->regs[coreidx]) {
1496                         si->regs[coreidx] =
1497                             (void *)REG_MAP(sbaddr, SB_CORE_SIZE);
1498                         ASSERT(GOODREGS(si->regs[coreidx]));
1499                 }
1500                 si->curmap = si->regs[coreidx];
1501                 break;
1502
1503         case PCI_BUS:
1504                 /* point bar0 window */
1505                 OSL_PCI_WRITE_CONFIG(si->osh, PCI_BAR0_WIN, 4, sbaddr);
1506                 break;
1507
1508         case PCMCIA_BUS:
1509                 tmp = (sbaddr >> 12) & 0x0f;
1510                 OSL_PCMCIA_WRITE_ATTR(si->osh, PCMCIA_ADDR0, &tmp, 1);
1511                 tmp = (sbaddr >> 16) & 0xff;
1512                 OSL_PCMCIA_WRITE_ATTR(si->osh, PCMCIA_ADDR1, &tmp, 1);
1513                 tmp = (sbaddr >> 24) & 0xff;
1514                 OSL_PCMCIA_WRITE_ATTR(si->osh, PCMCIA_ADDR2, &tmp, 1);
1515                 break;
1516 #ifdef BCMJTAG
1517         case JTAG_BUS:
1518                 /* map new one */
1519                 if (!si->regs[coreidx]) {
1520                         si->regs[coreidx] = (void *)sbaddr;
1521                         ASSERT(GOODREGS(si->regs[coreidx]));
1522                 }
1523                 si->curmap = si->regs[coreidx];
1524                 break;
1525 #endif /* BCMJTAG */
1526         }
1527
1528         si->curidx = coreidx;
1529
1530         return (si->curmap);
1531 }
1532
1533 /* 
1534  * this function changes logical "focus" to the indiciated core,
1535  * must be called with interrupt off.
1536  * Moreover, callers should keep interrupts off during switching out of and back to d11 core
1537  */
1538 void *sb_setcore(sb_t * sbh, uint coreid, uint coreunit)
1539 {
1540         uint idx;
1541
1542         idx = sb_findcoreidx(sbh, coreid, coreunit);
1543         if (!GOODIDX(idx))
1544                 return (NULL);
1545
1546         return (sb_setcoreidx(sbh, idx));
1547 }
1548
1549 /* return chip number */
1550 uint BCMINITFN(sb_chip) (sb_t * sbh) {
1551         sb_info_t *si;
1552
1553         si = SB_INFO(sbh);
1554         return (si->sb.chip);
1555 }
1556
1557 /* return chip revision number */
1558 uint BCMINITFN(sb_chiprev) (sb_t * sbh) {
1559         sb_info_t *si;
1560
1561         si = SB_INFO(sbh);
1562         return (si->sb.chiprev);
1563 }
1564
1565 /* return chip common revision number */
1566 uint BCMINITFN(sb_chipcrev) (sb_t * sbh) {
1567         sb_info_t *si;
1568
1569         si = SB_INFO(sbh);
1570         return (si->sb.ccrev);
1571 }
1572
1573 /* return chip package option */
1574 uint BCMINITFN(sb_chippkg) (sb_t * sbh) {
1575         sb_info_t *si;
1576
1577         si = SB_INFO(sbh);
1578         return (si->sb.chippkg);
1579 }
1580
1581 /* return PCI core rev. */
1582 uint BCMINITFN(sb_pcirev) (sb_t * sbh) {
1583         sb_info_t *si;
1584
1585         si = SB_INFO(sbh);
1586         return (si->sb.buscorerev);
1587 }
1588
1589 bool BCMINITFN(sb_war16165) (sb_t * sbh) {
1590         sb_info_t *si;
1591
1592         si = SB_INFO(sbh);
1593
1594         return (PCI(si) && (si->sb.buscorerev <= 10));
1595 }
1596
1597 static void BCMINITFN(sb_war30841) (sb_info_t * si) {
1598         sb_pcie_mdiowrite(si, MDIODATA_DEV_RX, SERDES_RX_TIMER1, 0x8128);
1599         sb_pcie_mdiowrite(si, MDIODATA_DEV_RX, SERDES_RX_CDR, 0x0100);
1600         sb_pcie_mdiowrite(si, MDIODATA_DEV_RX, SERDES_RX_CDRBW, 0x1466);
1601 }
1602
1603 /* return PCMCIA core rev. */
1604 uint BCMINITFN(sb_pcmciarev) (sb_t * sbh) {
1605         sb_info_t *si;
1606
1607         si = SB_INFO(sbh);
1608         return (si->sb.buscorerev);
1609 }
1610
1611 /* return board vendor id */
1612 uint BCMINITFN(sb_boardvendor) (sb_t * sbh) {
1613         sb_info_t *si;
1614
1615         si = SB_INFO(sbh);
1616         return (si->sb.boardvendor);
1617 }
1618
1619 /* return boardtype */
1620 uint BCMINITFN(sb_boardtype) (sb_t * sbh) {
1621         sb_info_t *si;
1622         char *var;
1623
1624         si = SB_INFO(sbh);
1625
1626         if (BUSTYPE(si->sb.bustype) == SB_BUS && si->sb.boardtype == 0xffff) {
1627                 /* boardtype format is a hex string */
1628                 si->sb.boardtype = getintvar(NULL, "boardtype");
1629
1630                 /* backward compatibility for older boardtype string format */
1631                 if ((si->sb.boardtype == 0)
1632                     && (var = getvar(NULL, "boardtype"))) {
1633                         if (!strcmp(var, "bcm94710dev"))
1634                                 si->sb.boardtype = BCM94710D_BOARD;
1635                         else if (!strcmp(var, "bcm94710ap"))
1636                                 si->sb.boardtype = BCM94710AP_BOARD;
1637                         else if (!strcmp(var, "bu4710"))
1638                                 si->sb.boardtype = BU4710_BOARD;
1639                         else if (!strcmp(var, "bcm94702mn"))
1640                                 si->sb.boardtype = BCM94702MN_BOARD;
1641                         else if (!strcmp(var, "bcm94710r1"))
1642                                 si->sb.boardtype = BCM94710R1_BOARD;
1643                         else if (!strcmp(var, "bcm94710r4"))
1644                                 si->sb.boardtype = BCM94710R4_BOARD;
1645                         else if (!strcmp(var, "bcm94702cpci"))
1646                                 si->sb.boardtype = BCM94702CPCI_BOARD;
1647                         else if (!strcmp(var, "bcm95380_rr"))
1648                                 si->sb.boardtype = BCM95380RR_BOARD;
1649                 }
1650         }
1651
1652         return (si->sb.boardtype);
1653 }
1654
1655 /* return bus type of sbh device */
1656 uint sb_bus(sb_t * sbh)
1657 {
1658         sb_info_t *si;
1659
1660         si = SB_INFO(sbh);
1661         return (si->sb.bustype);
1662 }
1663
1664 /* return bus core type */
1665 uint sb_buscoretype(sb_t * sbh)
1666 {
1667         sb_info_t *si;
1668
1669         si = SB_INFO(sbh);
1670
1671         return (si->sb.buscoretype);
1672 }
1673
1674 /* return bus core revision */
1675 uint sb_buscorerev(sb_t * sbh)
1676 {
1677         sb_info_t *si;
1678         si = SB_INFO(sbh);
1679
1680         return (si->sb.buscorerev);
1681 }
1682
1683 /* return list of found cores */
1684 uint sb_corelist(sb_t * sbh, uint coreid[])
1685 {
1686         sb_info_t *si;
1687
1688         si = SB_INFO(sbh);
1689
1690         bcopy((uchar *) si->coreid, (uchar *) coreid,
1691               (si->numcores * sizeof(uint)));
1692         return (si->numcores);
1693 }
1694
1695 /* return current register mapping */
1696 void *sb_coreregs(sb_t * sbh)
1697 {
1698         sb_info_t *si;
1699
1700         si = SB_INFO(sbh);
1701         ASSERT(GOODREGS(si->curmap));
1702
1703         return (si->curmap);
1704 }
1705
1706 #if defined(BCMDBG_ASSERT)
1707 /* traverse all cores to find and clear source of serror */
1708 static void sb_serr_clear(sb_info_t * si)
1709 {
1710         sbconfig_t *sb;
1711         uint origidx;
1712         uint i, intr_val = 0;
1713         void *corereg = NULL;
1714
1715         INTR_OFF(si, intr_val);
1716         origidx = sb_coreidx(&si->sb);
1717
1718         for (i = 0; i < si->numcores; i++) {
1719                 corereg = sb_setcoreidx(&si->sb, i);
1720                 if (NULL != corereg) {
1721                         sb = REGS2SB(corereg);
1722                         if ((R_SBREG(si, &sb->sbtmstatehigh)) & SBTMH_SERR) {
1723                                 AND_SBREG(si, &sb->sbtmstatehigh, ~SBTMH_SERR);
1724                                 SB_ERROR(("sb_serr_clear: SError at core 0x%x\n", sb_coreid(&si->sb)));
1725                         }
1726                 }
1727         }
1728
1729         sb_setcoreidx(&si->sb, origidx);
1730         INTR_RESTORE(si, intr_val);
1731 }
1732
1733 /*
1734  * Check if any inband, outband or timeout errors has happened and clear them.
1735  * Must be called with chip clk on !
1736  */
1737 bool sb_taclear(sb_t * sbh)
1738 {
1739         sb_info_t *si;
1740         sbconfig_t *sb;
1741         uint origidx;
1742         uint intr_val = 0;
1743         bool rc = FALSE;
1744         uint32 inband = 0, serror = 0, timeout = 0;
1745         void *corereg = NULL;
1746         volatile uint32 imstate, tmstate;
1747
1748         si = SB_INFO(sbh);
1749
1750         if (BUSTYPE(si->sb.bustype) == PCI_BUS) {
1751                 volatile uint32 stcmd;
1752
1753                 /* inband error is Target abort for PCI */
1754                 stcmd =
1755                     OSL_PCI_READ_CONFIG(si->osh, PCI_CFG_CMD, sizeof(uint32));
1756                 inband = stcmd & PCI_CFG_CMD_STAT_TA;
1757                 if (inband) {
1758 #ifdef BCMDBG
1759                         SB_ERROR(("inband:\n"));
1760                         sb_viewall((void *)si);
1761 #endif
1762                         OSL_PCI_WRITE_CONFIG(si->osh, PCI_CFG_CMD,
1763                                              sizeof(uint32), stcmd);
1764                 }
1765
1766                 /* serror */
1767                 stcmd =
1768                     OSL_PCI_READ_CONFIG(si->osh, PCI_INT_STATUS,
1769                                         sizeof(uint32));
1770                 serror = stcmd & PCI_SBIM_STATUS_SERR;
1771                 if (serror) {
1772 #ifdef BCMDBG
1773                         SB_ERROR(("serror:\n"));
1774                         sb_viewall((void *)si);
1775 #endif
1776                         sb_serr_clear(si);
1777                         OSL_PCI_WRITE_CONFIG(si->osh, PCI_INT_STATUS,
1778                                              sizeof(uint32), stcmd);
1779                 }
1780
1781                 /* timeout */
1782                 imstate = sb_corereg(sbh, si->sb.buscoreidx,
1783                                      SBCONFIGOFF + OFFSETOF(sbconfig_t,
1784                                                             sbimstate), 0, 0);
1785                 if ((imstate != 0xffffffff) && (imstate & (SBIM_IBE | SBIM_TO))) {
1786                         sb_corereg(sbh, si->sb.buscoreidx,
1787                                    SBCONFIGOFF + OFFSETOF(sbconfig_t,
1788                                                           sbimstate), ~0,
1789                                    (imstate & ~(SBIM_IBE | SBIM_TO)));
1790                         /* inband = imstate & SBIM_IBE; same as TA above */
1791                         timeout = imstate & SBIM_TO;
1792                         if (timeout) {
1793 #ifdef BCMDBG
1794                                 SB_ERROR(("timeout:\n"));
1795                                 sb_viewall((void *)si);
1796 #endif
1797                         }
1798                 }
1799
1800                 if (inband) {
1801                         /* dump errlog for sonics >= 2.3 */
1802                         if (si->sb.sonicsrev == SONICS_2_2) ;
1803                         else {
1804                                 uint32 imerrlog, imerrloga;
1805                                 imerrlog =
1806                                     sb_corereg(sbh, si->sb.buscoreidx,
1807                                                SBIMERRLOG, 0, 0);
1808                                 if (imerrlog & SBTMEL_EC) {
1809                                         imerrloga =
1810                                             sb_corereg(sbh, si->sb.buscoreidx,
1811                                                        SBIMERRLOGA, 0, 0);
1812                                         /* clear errlog */
1813                                         sb_corereg(sbh, si->sb.buscoreidx,
1814                                                    SBIMERRLOG, ~0, 0);
1815                                         SB_ERROR(("sb_taclear: ImErrLog 0x%x, ImErrLogA 0x%x\n", imerrlog, imerrloga));
1816                                 }
1817                         }
1818                 }
1819
1820         } else if (BUSTYPE(si->sb.bustype) == PCMCIA_BUS) {
1821
1822                 INTR_OFF(si, intr_val);
1823                 origidx = sb_coreidx(sbh);
1824
1825                 corereg = sb_setcore(sbh, SB_PCMCIA, 0);
1826                 if (NULL != corereg) {
1827                         sb = REGS2SB(corereg);
1828
1829                         imstate = R_SBREG(si, &sb->sbimstate);
1830                         /* handle surprise removal */
1831                         if ((imstate != 0xffffffff)
1832                             && (imstate & (SBIM_IBE | SBIM_TO))) {
1833                                 AND_SBREG(si, &sb->sbimstate,
1834                                           ~(SBIM_IBE | SBIM_TO));
1835                                 inband = imstate & SBIM_IBE;
1836                                 timeout = imstate & SBIM_TO;
1837                         }
1838                         tmstate = R_SBREG(si, &sb->sbtmstatehigh);
1839                         if ((tmstate != 0xffffffff)
1840                             && (tmstate & SBTMH_INT_STATUS)) {
1841                                 if (!inband) {
1842                                         serror = 1;
1843                                         sb_serr_clear(si);
1844                                 }
1845                                 OR_SBREG(si, &sb->sbtmstatelow, SBTML_INT_ACK);
1846                                 AND_SBREG(si, &sb->sbtmstatelow,
1847                                           ~SBTML_INT_ACK);
1848                         }
1849                 }
1850                 sb_setcoreidx(sbh, origidx);
1851                 INTR_RESTORE(si, intr_val);
1852
1853         }
1854
1855         if (inband | timeout | serror) {
1856                 rc = TRUE;
1857                 SB_ERROR(("sb_taclear: inband 0x%x, serror 0x%x, timeout 0x%x!\n", inband, serror, timeout));
1858         }
1859
1860         return (rc);
1861 }
1862 #endif /* BCMDBG */
1863
1864 /* do buffered registers update */
1865 void sb_commit(sb_t * sbh)
1866 {
1867         sb_info_t *si;
1868         uint origidx;
1869         uint intr_val = 0;
1870
1871         si = SB_INFO(sbh);
1872
1873         origidx = si->curidx;
1874         ASSERT(GOODIDX(origidx));
1875
1876         INTR_OFF(si, intr_val);
1877
1878         /* switch over to chipcommon core if there is one, else use pci */
1879         if (si->sb.ccrev != NOREV) {
1880                 chipcregs_t *ccregs = (chipcregs_t *) sb_setcore(sbh, SB_CC, 0);
1881
1882                 /* do the buffer registers update */
1883                 W_REG(si->osh, &ccregs->broadcastaddress, SB_COMMIT);
1884                 W_REG(si->osh, &ccregs->broadcastdata, 0x0);
1885         } else if (PCI(si)) {
1886                 sbpciregs_t *pciregs =
1887                     (sbpciregs_t *) sb_setcore(sbh, SB_PCI, 0);
1888
1889                 /* do the buffer registers update */
1890                 W_REG(si->osh, &pciregs->bcastaddr, SB_COMMIT);
1891                 W_REG(si->osh, &pciregs->bcastdata, 0x0);
1892         } else
1893                 ASSERT(0);
1894
1895         /* restore core index */
1896         sb_setcoreidx(sbh, origidx);
1897         INTR_RESTORE(si, intr_val);
1898 }
1899
1900 /* reset and re-enable a core
1901  * inputs:
1902  * bits - core specific bits that are set during and after reset sequence
1903  * resetbits - core specific bits that are set only during reset sequence
1904  */
1905 void sb_core_reset(sb_t * sbh, uint32 bits, uint32 resetbits)
1906 {
1907         sb_info_t *si;
1908         sbconfig_t *sb;
1909         volatile uint32 dummy;
1910
1911         si = SB_INFO(sbh);
1912         ASSERT(GOODREGS(si->curmap));
1913         sb = REGS2SB(si->curmap);
1914
1915         /*
1916          * Must do the disable sequence first to work for arbitrary current core state.
1917          */
1918         sb_core_disable(sbh, (bits | resetbits));
1919
1920         /*
1921          * Now do the initialization sequence.
1922          */
1923
1924         /* set reset while enabling the clock and forcing them on throughout the core */
1925         W_SBREG(si, &sb->sbtmstatelow,
1926                 (SBTML_FGC | SBTML_CLK | SBTML_RESET | bits | resetbits));
1927         dummy = R_SBREG(si, &sb->sbtmstatelow);
1928         OSL_DELAY(1);
1929
1930         if (R_SBREG(si, &sb->sbtmstatehigh) & SBTMH_SERR) {
1931                 W_SBREG(si, &sb->sbtmstatehigh, 0);
1932         }
1933         if ((dummy = R_SBREG(si, &sb->sbimstate)) & (SBIM_IBE | SBIM_TO)) {
1934                 AND_SBREG(si, &sb->sbimstate, ~(SBIM_IBE | SBIM_TO));
1935         }
1936
1937         /* clear reset and allow it to propagate throughout the core */
1938         W_SBREG(si, &sb->sbtmstatelow, (SBTML_FGC | SBTML_CLK | bits));
1939         dummy = R_SBREG(si, &sb->sbtmstatelow);
1940         OSL_DELAY(1);
1941
1942         /* leave clock enabled */
1943         W_SBREG(si, &sb->sbtmstatelow, (SBTML_CLK | bits));
1944         dummy = R_SBREG(si, &sb->sbtmstatelow);
1945         OSL_DELAY(1);
1946 }
1947
1948 void sb_core_tofixup(sb_t * sbh)
1949 {
1950         sb_info_t *si;
1951         sbconfig_t *sb;
1952
1953         si = SB_INFO(sbh);
1954
1955         if ((BUSTYPE(si->sb.bustype) != PCI_BUS) || PCIE(si) ||
1956             (PCI(si) && (si->sb.buscorerev >= 5)))
1957                 return;
1958
1959         ASSERT(GOODREGS(si->curmap));
1960         sb = REGS2SB(si->curmap);
1961
1962         if (BUSTYPE(si->sb.bustype) == SB_BUS) {
1963                 SET_SBREG(si, &sb->sbimconfiglow,
1964                           SBIMCL_RTO_MASK | SBIMCL_STO_MASK,
1965                           (0x5 << SBIMCL_RTO_SHIFT) | 0x3);
1966         } else {
1967                 if (sb_coreid(sbh) == SB_PCI) {
1968                         SET_SBREG(si, &sb->sbimconfiglow,
1969                                   SBIMCL_RTO_MASK | SBIMCL_STO_MASK,
1970                                   (0x3 << SBIMCL_RTO_SHIFT) | 0x2);
1971                 } else {
1972                         SET_SBREG(si, &sb->sbimconfiglow,
1973                                   (SBIMCL_RTO_MASK | SBIMCL_STO_MASK), 0);
1974                 }
1975         }
1976
1977         sb_commit(sbh);
1978 }
1979
1980 /*
1981  * Set the initiator timeout for the "master core".
1982  * The master core is defined to be the core in control
1983  * of the chip and so it issues accesses to non-memory
1984  * locations (Because of dma *any* core can access memeory).
1985  *
1986  * The routine uses the bus to decide who is the master:
1987  *      SB_BUS => mips
1988  *      JTAG_BUS => chipc
1989  *      PCI_BUS => pci or pcie
1990  *      PCMCIA_BUS => pcmcia
1991  *      SDIO_BUS => pcmcia
1992  *
1993  * This routine exists so callers can disable initiator
1994  * timeouts so accesses to very slow devices like otp
1995  * won't cause an abort. The routine allows arbitrary
1996  * settings of the service and request timeouts, though.
1997  *
1998  * Returns the timeout state before changing it or -1
1999  * on error.
2000  */
2001
2002 #define TO_MASK (SBIMCL_RTO_MASK | SBIMCL_STO_MASK)
2003
2004 uint32 sb_set_initiator_to(sb_t * sbh, uint32 to, uint idx)
2005 {
2006         sb_info_t *si;
2007         uint origidx;
2008         uint intr_val = 0;
2009         uint32 tmp, ret = 0xffffffff;
2010         sbconfig_t *sb;
2011
2012         si = SB_INFO(sbh);
2013
2014         if ((to & ~TO_MASK) != 0)
2015                 return ret;
2016
2017         /* Figure out the master core */
2018         if (idx == BADIDX) {
2019                 switch (BUSTYPE(si->sb.bustype)) {
2020                 case PCI_BUS:
2021                         idx = si->sb.buscoreidx;
2022                         break;
2023                 case JTAG_BUS:
2024                         idx = SB_CC_IDX;
2025                         break;
2026                 case PCMCIA_BUS:
2027                 case SDIO_BUS:
2028                         idx = sb_findcoreidx(sbh, SB_PCMCIA, 0);
2029                         break;
2030                 case SB_BUS:
2031                         if ((idx = sb_findcoreidx(sbh, SB_MIPS33, 0)) == BADIDX)
2032                                 idx = sb_findcoreidx(sbh, SB_MIPS, 0);
2033                         break;
2034                 default:
2035                         ASSERT(0);
2036                 }
2037                 if (idx == BADIDX)
2038                         return ret;
2039         }
2040
2041         INTR_OFF(si, intr_val);
2042         origidx = sb_coreidx(sbh);
2043
2044         sb = REGS2SB(sb_setcoreidx(sbh, idx));
2045
2046         tmp = R_SBREG(si, &sb->sbimconfiglow);
2047         ret = tmp & TO_MASK;
2048         W_SBREG(si, &sb->sbimconfiglow, (tmp & ~TO_MASK) | to);
2049
2050         sb_commit(sbh);
2051         sb_setcoreidx(sbh, origidx);
2052         INTR_RESTORE(si, intr_val);
2053         return ret;
2054 }
2055
2056 void sb_core_disable(sb_t * sbh, uint32 bits)
2057 {
2058         sb_info_t *si;
2059         volatile uint32 dummy;
2060         uint32 rej;
2061         sbconfig_t *sb;
2062
2063         si = SB_INFO(sbh);
2064
2065         ASSERT(GOODREGS(si->curmap));
2066         sb = REGS2SB(si->curmap);
2067
2068         /* if core is already in reset, just return */
2069         if (R_SBREG(si, &sb->sbtmstatelow) & SBTML_RESET)
2070                 return;
2071
2072         /* reject value changed between sonics 2.2 and 2.3 */
2073         if (si->sb.sonicsrev == SONICS_2_2)
2074                 rej = (1 << SBTML_REJ_SHIFT);
2075         else
2076                 rej = (2 << SBTML_REJ_SHIFT);
2077
2078         /* if clocks are not enabled, put into reset and return */
2079         if ((R_SBREG(si, &sb->sbtmstatelow) & SBTML_CLK) == 0)
2080                 goto disable;
2081
2082         /* set target reject and spin until busy is clear (preserve core-specific bits) */
2083         OR_SBREG(si, &sb->sbtmstatelow, rej);
2084         dummy = R_SBREG(si, &sb->sbtmstatelow);
2085         OSL_DELAY(1);
2086         SPINWAIT((R_SBREG(si, &sb->sbtmstatehigh) & SBTMH_BUSY), 100000);
2087         if (R_SBREG(si, &sb->sbtmstatehigh) & SBTMH_BUSY)
2088                 SB_ERROR(("%s: target state still busy\n", __FUNCTION__));
2089
2090         if (R_SBREG(si, &sb->sbidlow) & SBIDL_INIT) {
2091                 OR_SBREG(si, &sb->sbimstate, SBIM_RJ);
2092                 dummy = R_SBREG(si, &sb->sbimstate);
2093                 OSL_DELAY(1);
2094                 SPINWAIT((R_SBREG(si, &sb->sbimstate) & SBIM_BY), 100000);
2095         }
2096
2097         /* set reset and reject while enabling the clocks */
2098         W_SBREG(si, &sb->sbtmstatelow,
2099                 (bits | SBTML_FGC | SBTML_CLK | rej | SBTML_RESET));
2100         dummy = R_SBREG(si, &sb->sbtmstatelow);
2101         OSL_DELAY(10);
2102
2103         /* don't forget to clear the initiator reject bit */
2104         if (R_SBREG(si, &sb->sbidlow) & SBIDL_INIT)
2105                 AND_SBREG(si, &sb->sbimstate, ~SBIM_RJ);
2106
2107       disable:
2108         /* leave reset and reject asserted */
2109         W_SBREG(si, &sb->sbtmstatelow, (bits | rej | SBTML_RESET));
2110         OSL_DELAY(1);
2111 }
2112
2113 /* set chip watchdog reset timer to fire in 'ticks' backplane cycles */
2114 void sb_watchdog(sb_t * sbh, uint ticks)
2115 {
2116         sb_info_t *si = SB_INFO(sbh);
2117
2118         /* make sure we come up in fast clock mode; or if clearing, clear clock */
2119         if (ticks)
2120                 sb_clkctl_clk(sbh, CLK_FAST);
2121         else
2122                 sb_clkctl_clk(sbh, CLK_DYNAMIC);
2123
2124         if (sbh->chip == BCM4328_CHIP_ID && ticks != 0)
2125                 sb_corereg(sbh, SB_CC_IDX, OFFSETOF(chipcregs_t, min_res_mask),
2126                            PMURES_BIT(RES4328_ROM_SWITCH),
2127                            PMURES_BIT(RES4328_ROM_SWITCH));
2128
2129         /* instant NMI */
2130         switch (si->gpioid) {
2131         case SB_CC:
2132                 sb_corereg(sbh, SB_CC_IDX, OFFSETOF(chipcregs_t, watchdog), ~0,
2133                            ticks);
2134                 break;
2135         case SB_EXTIF:
2136                 sb_corereg(sbh, si->gpioidx, OFFSETOF(extifregs_t, watchdog),
2137                            ~0, ticks);
2138                 break;
2139         }
2140 }
2141
2142 /* initialize the pcmcia core */
2143 void sb_pcmcia_init(sb_t * sbh)
2144 {
2145         sb_info_t *si;
2146         uint8 cor = 0;
2147
2148         si = SB_INFO(sbh);
2149
2150         /* enable d11 mac interrupts */
2151         OSL_PCMCIA_READ_ATTR(si->osh, PCMCIA_FCR0 + PCMCIA_COR, &cor, 1);
2152         cor |= COR_IRQEN | COR_FUNEN;
2153         OSL_PCMCIA_WRITE_ATTR(si->osh, PCMCIA_FCR0 + PCMCIA_COR, &cor, 1);
2154
2155 }
2156
2157 void BCMINITFN(sb_pci_up) (sb_t * sbh) {
2158         sb_info_t *si = SB_INFO(sbh);
2159         if (si->gpioid == SB_EXTIF)
2160                 return;
2161
2162         /* if not pci bus, we're done */
2163         if (BUSTYPE(si->sb.bustype) != PCI_BUS)
2164                 return;
2165
2166         if (FORCEHT_WAR32414(si))
2167                 sb_war32414_forceHT(sbh, 1);
2168
2169         if (PCIE_ASPMWARS(si) || si->sb.pr42780)
2170                 sb_pcieclkreq(sbh, 1, 0);
2171
2172         if (PCIE(si) &&
2173             (((si->sb.chip == BCM4311_CHIP_ID) && (si->sb.chiprev == 2)) ||
2174              ((si->sb.chip == BCM4312_CHIP_ID) && (si->sb.chiprev == 0))))
2175                 sb_set_initiator_to((void *)si, 0x3,
2176                                     sb_findcoreidx((void *)si, SB_D11, 0));
2177 }
2178
2179 /* Unconfigure and/or apply various WARs when system is going to sleep mode */
2180 void BCMUNINITFN(sb_pci_sleep) (sb_t * sbh) {
2181         sb_info_t *si = SB_INFO(sbh);
2182         if (si->gpioid == SB_EXTIF)
2183                 return;
2184         uint32 w;
2185
2186         /* if not pci bus, we're done */
2187         if (!PCIE(si) || !PCIE_ASPMWARS(si))
2188                 return;
2189
2190         w = OSL_PCI_READ_CONFIG(si->osh, si->pciecap_lcreg_offset,
2191                                 sizeof(uint32));
2192         w &= ~PCIE_CAP_LCREG_ASPML1;
2193         OSL_PCI_WRITE_CONFIG(si->osh, si->pciecap_lcreg_offset, sizeof(uint32),
2194                              w);
2195 }
2196
2197 /* Unconfigure and/or apply various WARs when going down */
2198 void BCMINITFN(sb_pci_down) (sb_t * sbh) {
2199         sb_info_t *si = SB_INFO(sbh);
2200         if (si->gpioid == SB_EXTIF)
2201                 return;
2202
2203         /* if not pci bus, we're done */
2204         if (BUSTYPE(si->sb.bustype) != PCI_BUS)
2205                 return;
2206
2207         if (FORCEHT_WAR32414(si))
2208                 sb_war32414_forceHT(sbh, 0);
2209
2210         if (si->pr42767_war) {
2211                 sb_pcieclkreq(sbh, 1, 1);
2212                 si->pr42767_war = FALSE;
2213         } else if (si->sb.pr42780) {
2214                 sb_pcieclkreq(sbh, 1, 1);
2215         }
2216 }
2217
2218 static void BCMINITFN(sb_war42767_clkreq) (sb_t * sbh) {
2219         sbpcieregs_t *pcieregs;
2220         uint16 val16, *reg16;
2221         sb_info_t *si;
2222
2223         si = SB_INFO(sbh);
2224
2225         /* if not pcie bus, we're done */
2226         if (!PCIE(si) || !PCIE_ASPMWARS(si))
2227                 return;
2228
2229         pcieregs = (sbpcieregs_t *) sb_setcoreidx(sbh, si->sb.buscoreidx);
2230         reg16 = &pcieregs->sprom[SRSH_CLKREQ_OFFSET];
2231         val16 = R_REG(si->osh, reg16);
2232         /* if clockreq is not advertized advertize it */
2233         if (!si->pcie_war_ovr) {
2234                 val16 |= SRSH_CLKREQ_ENB;
2235                 si->pr42767_war = TRUE;
2236
2237                 si->sb.pr42780 = TRUE;
2238         } else
2239                 val16 &= ~SRSH_CLKREQ_ENB;
2240         W_REG(si->osh, reg16, val16);
2241 }
2242
2243 static void BCMINITFN(sb_war42767) (sb_t * sbh) {
2244         uint32 w = 0;
2245         sb_info_t *si;
2246
2247         si = SB_INFO(sbh);
2248
2249         /* if not pcie bus, we're done */
2250         if (!PCIE(si) || !PCIE_ASPMWARS(si))
2251                 return;
2252
2253         sb_pcie_mdioread(si, MDIODATA_DEV_PLL, SERDES_PLL_CTRL, &w);
2254         if (w & PLL_CTRL_FREQDET_EN) {
2255                 w &= ~PLL_CTRL_FREQDET_EN;
2256                 sb_pcie_mdiowrite(si, MDIODATA_DEV_PLL, SERDES_PLL_CTRL, w);
2257         }
2258 }
2259
2260 /*
2261  * Configure the pci core for pci client (NIC) action
2262  * coremask is the bitvec of cores by index to be enabled.
2263  */
2264 void BCMINITFN(sb_pci_setup) (sb_t * sbh, uint coremask) {
2265         sb_info_t *si;
2266         sbconfig_t *sb;
2267         sbpciregs_t *pciregs;
2268         uint32 sbflag;
2269         uint32 w;
2270         uint idx;
2271
2272         si = SB_INFO(sbh);
2273
2274         /* if not pci bus, we're done */
2275         if (BUSTYPE(si->sb.bustype) != PCI_BUS)
2276                 return;
2277
2278         ASSERT(PCI(si) || PCIE(si));
2279         ASSERT(si->sb.buscoreidx != BADIDX);
2280
2281         /* get current core index */
2282         idx = si->curidx;
2283
2284         /* we interrupt on this backplane flag number */
2285         ASSERT(GOODREGS(si->curmap));
2286         sb = REGS2SB(si->curmap);
2287         sbflag = R_SBREG(si, &sb->sbtpsflag) & SBTPS_NUM0_MASK;
2288
2289         /* switch over to pci core */
2290         pciregs = (sbpciregs_t *) sb_setcoreidx(sbh, si->sb.buscoreidx);
2291         sb = REGS2SB(pciregs);
2292
2293         /*
2294          * Enable sb->pci interrupts.  Assume
2295          * PCI rev 2.3 support was added in pci core rev 6 and things changed..
2296          */
2297         if (PCIE(si) || (PCI(si) && ((si->sb.buscorerev) >= 6))) {
2298                 /* pci config write to set this core bit in PCIIntMask */
2299                 w = OSL_PCI_READ_CONFIG(si->osh, PCI_INT_MASK, sizeof(uint32));
2300                 w |= (coremask << PCI_SBIM_SHIFT);
2301                 OSL_PCI_WRITE_CONFIG(si->osh, PCI_INT_MASK, sizeof(uint32), w);
2302         } else {
2303                 /* set sbintvec bit for our flag number */
2304                 OR_SBREG(si, &sb->sbintvec, (1 << sbflag));
2305         }
2306
2307         if (PCI(si)) {
2308                 OR_REG(si->osh, &pciregs->sbtopci2,
2309                        (SBTOPCI_PREF | SBTOPCI_BURST));
2310                 if (si->sb.buscorerev >= 11)
2311                         OR_REG(si->osh, &pciregs->sbtopci2,
2312                                SBTOPCI_RC_READMULTI);
2313                 if (si->sb.buscorerev < 5) {
2314                         SET_SBREG(si, &sb->sbimconfiglow,
2315                                   SBIMCL_RTO_MASK | SBIMCL_STO_MASK,
2316                                   (0x3 << SBIMCL_RTO_SHIFT) | 0x2);
2317                         sb_commit(sbh);
2318                 }
2319         }
2320
2321         /* PCIE workarounds */
2322         if (PCIE(si)) {
2323                 if ((si->sb.buscorerev == 0) || (si->sb.buscorerev == 1)) {
2324                         w = sb_pcie_readreg((void *)(uintptr) sbh,
2325                                             (void *)(uintptr) PCIE_PCIEREGS,
2326                                             PCIE_TLP_WORKAROUNDSREG);
2327                         w |= 0x8;
2328                         sb_pcie_writereg((void *)(uintptr) sbh,
2329                                          (void *)(uintptr) PCIE_PCIEREGS,
2330                                          PCIE_TLP_WORKAROUNDSREG, w);
2331                 }
2332
2333                 if (si->sb.buscorerev == 1) {
2334                         w = sb_pcie_readreg((void *)(uintptr) sbh,
2335                                             (void *)(uintptr) PCIE_PCIEREGS,
2336                                             PCIE_DLLP_LCREG);
2337                         w |= (0x40);
2338                         sb_pcie_writereg((void *)(uintptr) sbh,
2339                                          (void *)(uintptr) PCIE_PCIEREGS,
2340                                          PCIE_DLLP_LCREG, w);
2341                 }
2342
2343                 if (si->sb.buscorerev == 0)
2344                         sb_war30841(si);
2345
2346                 if ((si->sb.buscorerev >= 3) && (si->sb.buscorerev <= 5)) {
2347                         w = sb_pcie_readreg((void *)(uintptr) sbh,
2348                                             (void *)(uintptr) PCIE_PCIEREGS,
2349                                             PCIE_DLLP_PMTHRESHREG);
2350                         w &= ~(PCIE_L1THRESHOLDTIME_MASK);
2351                         w |= (PCIE_L1THRESHOLD_WARVAL <<
2352                               PCIE_L1THRESHOLDTIME_SHIFT);
2353                         sb_pcie_writereg((void *)(uintptr) sbh,
2354                                          (void *)(uintptr) PCIE_PCIEREGS,
2355                                          PCIE_DLLP_PMTHRESHREG, w);
2356
2357                         sb_war43448(sbh);
2358
2359                         sb_war42767(sbh);
2360
2361                         sb_war43448_aspm(sbh);
2362                         sb_war42767_clkreq(sbh);
2363                 }
2364         }
2365
2366         /* switch back to previous core */
2367         sb_setcoreidx(sbh, idx);
2368 }
2369
2370 uint32 sb_base(uint32 admatch)
2371 {
2372         uint32 base;
2373         uint type;
2374
2375         type = admatch & SBAM_TYPE_MASK;
2376         ASSERT(type < 3);
2377
2378         base = 0;
2379
2380         if (type == 0) {
2381                 base = admatch & SBAM_BASE0_MASK;
2382         } else if (type == 1) {
2383                 ASSERT(!(admatch & SBAM_ADNEG));        /* neg not supported */
2384                 base = admatch & SBAM_BASE1_MASK;
2385         } else if (type == 2) {
2386                 ASSERT(!(admatch & SBAM_ADNEG));        /* neg not supported */
2387                 base = admatch & SBAM_BASE2_MASK;
2388         }
2389
2390         return (base);
2391 }
2392
2393 uint32 sb_size(uint32 admatch)
2394 {
2395         uint32 size;
2396         uint type;
2397
2398         type = admatch & SBAM_TYPE_MASK;
2399         ASSERT(type < 3);
2400
2401         size = 0;
2402
2403         if (type == 0) {
2404                 size =
2405                     1 << (((admatch & SBAM_ADINT0_MASK) >> SBAM_ADINT0_SHIFT) +
2406                           1);
2407         } else if (type == 1) {
2408                 ASSERT(!(admatch & SBAM_ADNEG));        /* neg not supported */
2409                 size =
2410                     1 << (((admatch & SBAM_ADINT1_MASK) >> SBAM_ADINT1_SHIFT) +
2411                           1);
2412         } else if (type == 2) {
2413                 ASSERT(!(admatch & SBAM_ADNEG));        /* neg not supported */
2414                 size =
2415                     1 << (((admatch & SBAM_ADINT2_MASK) >> SBAM_ADINT2_SHIFT) +
2416                           1);
2417         }
2418
2419         return (size);
2420 }
2421
2422 /* return the core-type instantiation # of the current core */
2423 uint sb_coreunit(sb_t * sbh)
2424 {
2425         sb_info_t *si;
2426         uint idx;
2427         uint coreid;
2428         uint coreunit;
2429         uint i;
2430
2431         si = SB_INFO(sbh);
2432         coreunit = 0;
2433
2434         idx = si->curidx;
2435
2436         ASSERT(GOODREGS(si->curmap));
2437         coreid = sb_coreid(sbh);
2438
2439         /* count the cores of our type */
2440         for (i = 0; i < idx; i++)
2441                 if (si->coreid[i] == coreid)
2442                         coreunit++;
2443
2444         return (coreunit);
2445 }
2446
2447 static uint32 BCMINITFN(factor6) (uint32 x) {
2448         switch (x) {
2449         case CC_F6_2:
2450                 return 2;
2451         case CC_F6_3:
2452                 return 3;
2453         case CC_F6_4:
2454                 return 4;
2455         case CC_F6_5:
2456                 return 5;
2457         case CC_F6_6:
2458                 return 6;
2459         case CC_F6_7:
2460                 return 7;
2461         default:
2462                 return 0;
2463         }
2464 }
2465
2466 /* calculate the speed the SB would run at given a set of clockcontrol values */
2467 uint32 BCMINITFN(sb_clock_rate) (uint32 pll_type, uint32 n, uint32 m) {
2468         uint32 n1, n2, clock, m1, m2, m3, mc;
2469
2470         n1 = n & CN_N1_MASK;
2471         n2 = (n & CN_N2_MASK) >> CN_N2_SHIFT;
2472
2473         if (pll_type == PLL_TYPE6) {
2474                 if (m & CC_T6_MMASK)
2475                         return CC_T6_M1;
2476                 else
2477                         return CC_T6_M0;
2478         } else if ((pll_type == PLL_TYPE1) ||
2479                    (pll_type == PLL_TYPE3) ||
2480                    (pll_type == PLL_TYPE4) || (pll_type == PLL_TYPE7)) {
2481                 n1 = factor6(n1);
2482                 n2 += CC_F5_BIAS;
2483         } else if (pll_type == PLL_TYPE2) {
2484                 n1 += CC_T2_BIAS;
2485                 n2 += CC_T2_BIAS;
2486                 ASSERT((n1 >= 2) && (n1 <= 7));
2487                 ASSERT((n2 >= 5) && (n2 <= 23));
2488         } else if (pll_type == PLL_TYPE5) {
2489                 return (100000000);
2490         } else
2491                 ASSERT(0);
2492         /* PLL types 3 and 7 use BASE2 (25Mhz) */
2493         if ((pll_type == PLL_TYPE3) || (pll_type == PLL_TYPE7)) {
2494                 clock = CC_CLOCK_BASE2 * n1 * n2;
2495         } else
2496                 clock = CC_CLOCK_BASE1 * n1 * n2;
2497
2498         if (clock == 0)
2499                 return 0;
2500
2501         m1 = m & CC_M1_MASK;
2502         m2 = (m & CC_M2_MASK) >> CC_M2_SHIFT;
2503         m3 = (m & CC_M3_MASK) >> CC_M3_SHIFT;
2504         mc = (m & CC_MC_MASK) >> CC_MC_SHIFT;
2505
2506         if ((pll_type == PLL_TYPE1) ||
2507             (pll_type == PLL_TYPE3) ||
2508             (pll_type == PLL_TYPE4) || (pll_type == PLL_TYPE7)) {
2509                 m1 = factor6(m1);
2510                 if ((pll_type == PLL_TYPE1) || (pll_type == PLL_TYPE3))
2511                         m2 += CC_F5_BIAS;
2512                 else
2513                         m2 = factor6(m2);
2514                 m3 = factor6(m3);
2515
2516                 switch (mc) {
2517                 case CC_MC_BYPASS:
2518                         return (clock);
2519                 case CC_MC_M1:
2520                         return (clock / m1);
2521                 case CC_MC_M1M2:
2522                         return (clock / (m1 * m2));
2523                 case CC_MC_M1M2M3:
2524                         return (clock / (m1 * m2 * m3));
2525                 case CC_MC_M1M3:
2526                         return (clock / (m1 * m3));
2527                 default:
2528                         return (0);
2529                 }
2530         } else {
2531                 ASSERT(pll_type == PLL_TYPE2);
2532
2533                 m1 += CC_T2_BIAS;
2534                 m2 += CC_T2M2_BIAS;
2535                 m3 += CC_T2_BIAS;
2536                 ASSERT((m1 >= 2) && (m1 <= 7));
2537                 ASSERT((m2 >= 3) && (m2 <= 10));
2538                 ASSERT((m3 >= 2) && (m3 <= 7));
2539
2540                 if ((mc & CC_T2MC_M1BYP) == 0)
2541                         clock /= m1;
2542                 if ((mc & CC_T2MC_M2BYP) == 0)
2543                         clock /= m2;
2544                 if ((mc & CC_T2MC_M3BYP) == 0)
2545                         clock /= m3;
2546
2547                 return (clock);
2548         }
2549 }
2550
2551 /* returns the current speed the SB is running at */
2552 uint32 BCMINITFN(sb_clock) (sb_t * sbh) {
2553         sb_info_t *si;
2554         extifregs_t *eir;
2555         chipcregs_t *cc;
2556         uint32 n, m;
2557         uint idx;
2558         uint32 cap, pll_type, rate;
2559         uint intr_val = 0;
2560
2561         si = SB_INFO(sbh);
2562         idx = si->curidx;
2563         pll_type = PLL_TYPE1;
2564
2565         INTR_OFF(si, intr_val);
2566
2567         /* switch to extif or chipc core */
2568         if ((eir = (extifregs_t *) sb_setcore(sbh, SB_EXTIF, 0))) {
2569                 n = R_REG(si->osh, &eir->clockcontrol_n);
2570                 m = R_REG(si->osh, &eir->clockcontrol_sb);
2571         } else if ((cc = (chipcregs_t *) sb_setcore(sbh, SB_CC, 0))) {
2572
2573                 cap = R_REG(si->osh, &cc->capabilities);
2574
2575                 if (cap & CC_CAP_PMU) {
2576
2577                         if (sb_chip(sbh) == BCM5354_CHIP_ID) {
2578                                 /* 5354 has a constant sb clock of 120MHz */
2579                                 rate = 120000000;
2580                                 goto end;
2581                         } else
2582                         if (sb_chip(sbh) == BCM4328_CHIP_ID) {
2583                                 rate = 80000000;
2584                                 goto end;
2585                         } else
2586                                 ASSERT(0);
2587                 }
2588
2589                 pll_type = cap & CC_CAP_PLL_MASK;
2590                 if (pll_type == PLL_NONE) {
2591                         INTR_RESTORE(si, intr_val);
2592                         return 80000000;
2593                 }
2594                 n = R_REG(si->osh, &cc->clockcontrol_n);
2595                 if (pll_type == PLL_TYPE6)
2596                         m = R_REG(si->osh, &cc->clockcontrol_m3);
2597                 else if (pll_type == PLL_TYPE3
2598                          && !(BCMINIT(sb_chip) (sbh) == 0x5365))
2599                         m = R_REG(si->osh, &cc->clockcontrol_m2);
2600                 else
2601                         m = R_REG(si->osh, &cc->clockcontrol_sb);
2602         } else {
2603                 INTR_RESTORE(si, intr_val);
2604                 return 0;
2605         }
2606
2607         /* calculate rate */
2608         if (BCMINIT(sb_chip) (sbh) == 0x5365)
2609                 rate = 100000000;
2610         else {
2611                 rate = sb_clock_rate(pll_type, n, m);
2612
2613                 if (pll_type == PLL_TYPE3)
2614                         rate = rate / 2;
2615         }
2616
2617       end:
2618         /* switch back to previous core */
2619         sb_setcoreidx(sbh, idx);
2620
2621         INTR_RESTORE(si, intr_val);
2622
2623         return rate;
2624 }
2625
2626 uint32 BCMINITFN(sb_alp_clock) (sb_t * sbh) {
2627         uint32 clock = ALP_CLOCK;
2628
2629         if (sbh->cccaps & CC_CAP_PMU)
2630                 clock = sb_pmu_alp_clock(sbh, sb_osh(sbh));
2631
2632         return clock;
2633 }
2634
2635 /* change logical "focus" to the gpio core for optimized access */
2636 void *sb_gpiosetcore(sb_t * sbh)
2637 {
2638         sb_info_t *si;
2639
2640         si = SB_INFO(sbh);
2641
2642         return (sb_setcoreidx(sbh, si->gpioidx));
2643 }
2644
2645 /* mask&set gpiocontrol bits */
2646 uint32 sb_gpiocontrol(sb_t * sbh, uint32 mask, uint32 val, uint8 priority)
2647 {
2648         sb_info_t *si;
2649         uint regoff;
2650
2651         si = SB_INFO(sbh);
2652         regoff = 0;
2653
2654         /* gpios could be shared on router platforms
2655          * ignore reservation if it's high priority (e.g., test apps)
2656          */
2657         if ((priority != GPIO_HI_PRIORITY) &&
2658             (BUSTYPE(si->sb.bustype) == SB_BUS) && (val || mask)) {
2659                 mask = priority ? (sb_gpioreservation & mask) :
2660                     ((sb_gpioreservation | mask) & ~(sb_gpioreservation));
2661                 val &= mask;
2662         }
2663
2664         switch (si->gpioid) {
2665         case SB_CC:
2666                 regoff = OFFSETOF(chipcregs_t, gpiocontrol);
2667                 break;
2668
2669         case SB_PCI:
2670                 regoff = OFFSETOF(sbpciregs_t, gpiocontrol);
2671                 break;
2672
2673         case SB_EXTIF:
2674                 return (0);
2675         }
2676
2677         return (sb_corereg(sbh, si->gpioidx, regoff, mask, val));
2678 }
2679
2680 /* mask&set gpio output enable bits */
2681 uint32 sb_gpioouten(sb_t * sbh, uint32 mask, uint32 val, uint8 priority)
2682 {
2683         sb_info_t *si;
2684         uint regoff;
2685
2686         si = SB_INFO(sbh);
2687         regoff = 0;
2688
2689         /* gpios could be shared on router platforms
2690          * ignore reservation if it's high priority (e.g., test apps)
2691          */
2692         if ((priority != GPIO_HI_PRIORITY) &&
2693             (BUSTYPE(si->sb.bustype) == SB_BUS) && (val || mask)) {
2694                 mask = priority ? (sb_gpioreservation & mask) :
2695                     ((sb_gpioreservation | mask) & ~(sb_gpioreservation));
2696                 val &= mask;
2697         }
2698
2699         switch (si->gpioid) {
2700         case SB_CC:
2701                 regoff = OFFSETOF(chipcregs_t, gpioouten);
2702                 break;
2703
2704         case SB_PCI:
2705                 regoff = OFFSETOF(sbpciregs_t, gpioouten);
2706                 break;
2707
2708         case SB_EXTIF:
2709                 regoff = OFFSETOF(extifregs_t, gpio[0].outen);
2710                 break;
2711         }
2712
2713         return (sb_corereg(sbh, si->gpioidx, regoff, mask, val));
2714 }
2715
2716 /* mask&set gpio output bits */
2717 uint32 sb_gpioout(sb_t * sbh, uint32 mask, uint32 val, uint8 priority)
2718 {
2719         sb_info_t *si;
2720         uint regoff;
2721
2722         si = SB_INFO(sbh);
2723         regoff = 0;
2724
2725         /* gpios could be shared on router platforms
2726          * ignore reservation if it's high priority (e.g., test apps)
2727          */
2728         if ((priority != GPIO_HI_PRIORITY) &&
2729             (BUSTYPE(si->sb.bustype) == SB_BUS) && (val || mask)) {
2730                 mask = priority ? (sb_gpioreservation & mask) :
2731                     ((sb_gpioreservation | mask) & ~(sb_gpioreservation));
2732                 val &= mask;
2733         }
2734
2735         switch (si->gpioid) {
2736         case SB_CC:
2737                 regoff = OFFSETOF(chipcregs_t, gpioout);
2738                 break;
2739
2740         case SB_PCI:
2741                 regoff = OFFSETOF(sbpciregs_t, gpioout);
2742                 break;
2743
2744         case SB_EXTIF:
2745                 regoff = OFFSETOF(extifregs_t, gpio[0].out);
2746                 break;
2747         }
2748
2749         return (sb_corereg(sbh, si->gpioidx, regoff, mask, val));
2750 }
2751
2752 /* reserve one gpio */
2753 uint32 sb_gpioreserve(sb_t * sbh, uint32 gpio_bitmask, uint8 priority)
2754 {
2755         sb_info_t *si;
2756
2757         si = SB_INFO(sbh);
2758
2759         /* only cores on SB_BUS share GPIO's and only applcation users need to
2760          * reserve/release GPIO
2761          */
2762         if ((BUSTYPE(si->sb.bustype) != SB_BUS) || (!priority)) {
2763                 ASSERT((BUSTYPE(si->sb.bustype) == SB_BUS) && (priority));
2764                 return -1;
2765         }
2766         /* make sure only one bit is set */
2767         if ((!gpio_bitmask) || ((gpio_bitmask) & (gpio_bitmask - 1))) {
2768                 ASSERT((gpio_bitmask)
2769                        && !((gpio_bitmask) & (gpio_bitmask - 1)));
2770                 return -1;
2771         }
2772
2773         /* already reserved */
2774         if (sb_gpioreservation & gpio_bitmask)
2775                 return -1;
2776         /* set reservation */
2777         sb_gpioreservation |= gpio_bitmask;
2778
2779         return sb_gpioreservation;
2780 }
2781
2782 /* release one gpio */
2783 /* 
2784  * releasing the gpio doesn't change the current value on the GPIO last write value
2785  * persists till some one overwrites it
2786 */
2787
2788 uint32 sb_gpiorelease(sb_t * sbh, uint32 gpio_bitmask, uint8 priority)
2789 {
2790         sb_info_t *si;
2791
2792         si = SB_INFO(sbh);
2793
2794         /* only cores on SB_BUS share GPIO's and only applcation users need to
2795          * reserve/release GPIO
2796          */
2797         if ((BUSTYPE(si->sb.bustype) != SB_BUS) || (!priority)) {
2798                 ASSERT((BUSTYPE(si->sb.bustype) == SB_BUS) && (priority));
2799                 return -1;
2800         }
2801         /* make sure only one bit is set */
2802         if ((!gpio_bitmask) || ((gpio_bitmask) & (gpio_bitmask - 1))) {
2803                 ASSERT((gpio_bitmask)
2804                        && !((gpio_bitmask) & (gpio_bitmask - 1)));
2805                 return -1;
2806         }
2807
2808         /* already released */
2809         if (!(sb_gpioreservation & gpio_bitmask))
2810                 return -1;
2811
2812         /* clear reservation */
2813         sb_gpioreservation &= ~gpio_bitmask;
2814
2815         return sb_gpioreservation;
2816 }
2817
2818 /* return the current gpioin register value */
2819 uint32 sb_gpioin(sb_t * sbh)
2820 {
2821         sb_info_t *si;
2822         uint regoff;
2823
2824         si = SB_INFO(sbh);
2825         regoff = 0;
2826
2827         switch (si->gpioid) {
2828         case SB_CC:
2829                 regoff = OFFSETOF(chipcregs_t, gpioin);
2830                 break;
2831
2832         case SB_PCI:
2833                 regoff = OFFSETOF(sbpciregs_t, gpioin);
2834                 break;
2835
2836         case SB_EXTIF:
2837                 regoff = OFFSETOF(extifregs_t, gpioin);
2838                 break;
2839         }
2840
2841         return (sb_corereg(sbh, si->gpioidx, regoff, 0, 0));
2842 }
2843
2844 /* mask&set gpio interrupt polarity bits */
2845 uint32 sb_gpiointpolarity(sb_t * sbh, uint32 mask, uint32 val, uint8 priority)
2846 {
2847         sb_info_t *si;
2848         uint regoff;
2849
2850         si = SB_INFO(sbh);
2851         regoff = 0;
2852
2853         /* gpios could be shared on router platforms */
2854         if ((BUSTYPE(si->sb.bustype) == SB_BUS) && (val || mask)) {
2855                 mask = priority ? (sb_gpioreservation & mask) :
2856                     ((sb_gpioreservation | mask) & ~(sb_gpioreservation));
2857                 val &= mask;
2858         }
2859
2860         switch (si->gpioid) {
2861         case SB_CC:
2862                 regoff = OFFSETOF(chipcregs_t, gpiointpolarity);
2863                 break;
2864
2865         case SB_PCI:
2866                 /* pci gpio implementation does not support interrupt polarity */
2867                 ASSERT(0);
2868                 break;
2869
2870         case SB_EXTIF:
2871                 regoff = OFFSETOF(extifregs_t, gpiointpolarity);
2872                 break;
2873         }
2874
2875         return (sb_corereg(sbh, si->gpioidx, regoff, mask, val));
2876 }
2877
2878 /* mask&set gpio interrupt mask bits */
2879 uint32 sb_gpiointmask(sb_t * sbh, uint32 mask, uint32 val, uint8 priority)
2880 {
2881         sb_info_t *si;
2882         uint regoff;
2883
2884         si = SB_INFO(sbh);
2885         regoff = 0;
2886
2887         /* gpios could be shared on router platforms */
2888         if ((BUSTYPE(si->sb.bustype) == SB_BUS) && (val || mask)) {
2889                 mask = priority ? (sb_gpioreservation & mask) :
2890                     ((sb_gpioreservation | mask) & ~(sb_gpioreservation));
2891                 val &= mask;
2892         }
2893
2894         switch (si->gpioid) {
2895         case SB_CC:
2896                 regoff = OFFSETOF(chipcregs_t, gpiointmask);
2897                 break;
2898
2899         case SB_PCI:
2900                 /* pci gpio implementation does not support interrupt mask */
2901                 ASSERT(0);
2902                 break;
2903
2904         case SB_EXTIF:
2905                 regoff = OFFSETOF(extifregs_t, gpiointmask);
2906                 break;
2907         }
2908
2909         return (sb_corereg(sbh, si->gpioidx, regoff, mask, val));
2910 }
2911
2912 /* assign the gpio to an led */
2913 uint32 sb_gpioled(sb_t * sbh, uint32 mask, uint32 val)
2914 {
2915         sb_info_t *si;
2916
2917         si = SB_INFO(sbh);
2918         if (si->sb.ccrev < 16)
2919                 return -1;
2920
2921         /* gpio led powersave reg */
2922         return (sb_corereg
2923                 (sbh, SB_CC_IDX, OFFSETOF(chipcregs_t, gpiotimeroutmask), mask,
2924                  val));
2925 }
2926
2927 /* mask&set gpio timer val */
2928 uint32 sb_gpiotimerval(sb_t * sbh, uint32 mask, uint32 gpiotimerval)
2929 {
2930         sb_info_t *si;
2931         si = SB_INFO(sbh);
2932
2933         if (si->sb.ccrev < 16)
2934                 return -1;
2935
2936         return (sb_corereg(sbh, SB_CC_IDX,
2937                            OFFSETOF(chipcregs_t, gpiotimerval), mask,
2938                            gpiotimerval));
2939 }
2940
2941 uint32 sb_gpiopull(sb_t * sbh, bool updown, uint32 mask, uint32 val)
2942 {
2943         sb_info_t *si;
2944         uint offs;
2945
2946         si = SB_INFO(sbh);
2947         if (si->sb.ccrev < 20)
2948                 return -1;
2949
2950         offs =
2951             (updown ? OFFSETOF(chipcregs_t, gpiopulldown) :
2952              OFFSETOF(chipcregs_t, gpiopullup));
2953         return (sb_corereg(sbh, SB_CC_IDX, offs, mask, val));
2954 }
2955
2956 uint32 sb_gpioevent(sb_t * sbh, uint regtype, uint32 mask, uint32 val)
2957 {
2958         sb_info_t *si;
2959         uint offs;
2960
2961         si = SB_INFO(sbh);
2962         if (si->sb.ccrev < 11)
2963                 return -1;
2964
2965         if (regtype == GPIO_REGEVT)
2966                 offs = OFFSETOF(chipcregs_t, gpioevent);
2967         else if (regtype == GPIO_REGEVT_INTMSK)
2968                 offs = OFFSETOF(chipcregs_t, gpioeventintmask);
2969         else if (regtype == GPIO_REGEVT_INTPOL)
2970                 offs = OFFSETOF(chipcregs_t, gpioeventintpolarity);
2971         else
2972                 return -1;
2973
2974         return (sb_corereg(sbh, SB_CC_IDX, offs, mask, val));
2975 }
2976
2977 void *BCMINITFN(sb_gpio_handler_register) (sb_t * sbh, uint32 event,
2978                                            bool level, gpio_handler_t cb,
2979                                            void *arg) {
2980         sb_info_t *si;
2981         gpioh_item_t *gi;
2982
2983         ASSERT(event);
2984         ASSERT(cb);
2985
2986         si = SB_INFO(sbh);
2987         if (si->sb.ccrev < 11)
2988                 return NULL;
2989
2990         if ((gi = MALLOC(si->osh, sizeof(gpioh_item_t))) == NULL)
2991                 return NULL;
2992
2993         bzero(gi, sizeof(gpioh_item_t));
2994         gi->event = event;
2995         gi->handler = cb;
2996         gi->arg = arg;
2997         gi->level = level;
2998
2999         gi->next = si->gpioh_head;
3000         si->gpioh_head = gi;
3001
3002         return (void *)(gi);
3003 }
3004
3005 void BCMINITFN(sb_gpio_handler_unregister) (sb_t * sbh, void *gpioh) {
3006         sb_info_t *si;
3007         gpioh_item_t *p, *n;
3008
3009         si = SB_INFO(sbh);
3010         if (si->sb.ccrev < 11)
3011                 return;
3012
3013         ASSERT(si->gpioh_head);
3014         if ((void *)si->gpioh_head == gpioh) {
3015                 si->gpioh_head = si->gpioh_head->next;
3016                 MFREE(si->osh, gpioh, sizeof(gpioh_item_t));
3017                 return;
3018         } else {
3019                 p = si->gpioh_head;
3020                 n = p->next;
3021                 while (n) {
3022                         if ((void *)n == gpioh) {
3023                                 p->next = n->next;
3024                                 MFREE(si->osh, gpioh, sizeof(gpioh_item_t));
3025                                 return;
3026                         }
3027                         p = n;
3028                         n = n->next;
3029                 }
3030         }
3031
3032         ASSERT(0);              /* Not found in list */
3033 }
3034
3035 void sb_gpio_handler_process(sb_t * sbh)
3036 {
3037         sb_info_t *si;
3038         gpioh_item_t *h;
3039         uint32 status;
3040         uint32 level = sb_gpioin(sbh);
3041         uint32 edge = sb_gpioevent(sbh, GPIO_REGEVT, 0, 0);
3042
3043         si = SB_INFO(sbh);
3044         for (h = si->gpioh_head; h != NULL; h = h->next) {
3045                 if (h->handler) {
3046                         status = (h->level ? level : edge);
3047
3048                         if (status & h->event)
3049                                 h->handler(status, h->arg);
3050                 }
3051         }
3052
3053         sb_gpioevent(sbh, GPIO_REGEVT, edge, edge);     /* clear edge-trigger status */
3054 }
3055
3056 uint32 sb_gpio_int_enable(sb_t * sbh, bool enable)
3057 {
3058         sb_info_t *si;
3059         uint offs;
3060
3061         si = SB_INFO(sbh);
3062         if (si->sb.ccrev < 11)
3063                 return -1;
3064
3065         offs = OFFSETOF(chipcregs_t, intmask);
3066         return (sb_corereg
3067                 (sbh, SB_CC_IDX, offs, CI_GPIO, (enable ? CI_GPIO : 0)));
3068 }
3069
3070 #ifdef BCMDBG
3071 void sb_dump(sb_t * sbh, struct bcmstrbuf *b)
3072 {
3073         sb_info_t *si;
3074         uint i;
3075
3076         si = SB_INFO(sbh);
3077
3078         bcm_bprintf(b,
3079                     "si %p chip 0x%x chiprev 0x%x boardtype 0x%x boardvendor 0x%x bus %d\n",
3080                     si, si->sb.chip, si->sb.chiprev, si->sb.boardtype,
3081                     si->sb.boardvendor, si->sb.bustype);
3082         bcm_bprintf(b, "osh %p curmap %p\n", si->osh, si->curmap);
3083         bcm_bprintf(b,
3084                     "sonicsrev %d ccrev %d buscoretype 0x%x buscorerev %d curidx %d\n",
3085                     si->sb.sonicsrev, si->sb.ccrev, si->sb.buscoretype,
3086                     si->sb.buscorerev, si->curidx);
3087
3088         bcm_bprintf(b, "forceHT %d ASPM overflowPR42780 %d pcie_polarity %d\n",
3089                     si->sb.pr32414, si->sb.pr42780, si->pcie_polarity);
3090
3091         bcm_bprintf(b, "cores:  ");
3092         for (i = 0; i < si->numcores; i++)
3093                 bcm_bprintf(b, "0x%x ", si->coreid[i]);
3094         bcm_bprintf(b, "\n");
3095 }
3096
3097 /* print interesting sbconfig registers */
3098 void sb_dumpregs(sb_t * sbh, struct bcmstrbuf *b)
3099 {
3100         sb_info_t *si;
3101         sbconfig_t *sb;
3102         uint origidx;
3103         uint curidx, i, intr_val = 0;
3104
3105         si = SB_INFO(sbh);
3106         origidx = si->curidx;
3107
3108         INTR_OFF(si, intr_val);
3109         curidx = si->curidx;
3110
3111         for (i = 0; i < si->numcores; i++) {
3112                 sb = REGS2SB(sb_setcoreidx(sbh, i));
3113
3114                 bcm_bprintf(b, "core 0x%x: \n", si->coreid[i]);
3115                 bcm_bprintf(b,
3116                             "sbtmstatelow 0x%x sbtmstatehigh 0x%x sbidhigh 0x%x "
3117                             "sbimstate 0x%x\n sbimconfiglow 0x%x sbimconfighigh 0x%x\n",
3118                             R_SBREG(si, &sb->sbtmstatelow), R_SBREG(si,
3119                                                                     &sb->
3120                                                                     sbtmstatehigh),
3121                             R_SBREG(si, &sb->sbidhigh), R_SBREG(si,
3122                                                                 &sb->sbimstate),
3123                             R_SBREG(si, &sb->sbimconfiglow), R_SBREG(si,
3124                                                                      &sb->
3125                                                                      sbimconfighigh));
3126         }
3127
3128         sb_setcoreidx(sbh, origidx);
3129         INTR_RESTORE(si, intr_val);
3130 }
3131
3132 void sb_view(sb_t * sbh)
3133 {
3134         sb_info_t *si;
3135         sbconfig_t *sb;
3136
3137         si = SB_INFO(sbh);
3138         sb = REGS2SB(si->curmap);
3139
3140         if (si->sb.sonicsrev > SONICS_2_2)
3141                 SB_ERROR(("sbimerrlog 0x%x sbimerrloga 0x%x\n",
3142                           sb_corereg(sbh, sb_coreidx(&si->sb), SBIMERRLOG, 0,
3143                                      0), sb_corereg(sbh, sb_coreidx(&si->sb),
3144                                                     SBIMERRLOGA, 0, 0)));
3145
3146         SB_ERROR(("sbipsflag 0x%x sbtpsflag 0x%x sbtmerrloga 0x%x sbtmerrlog 0x%x\n", R_SBREG(si, &sb->sbipsflag), R_SBREG(si, &sb->sbtpsflag), R_SBREG(si, &sb->sbtmerrloga), R_SBREG(si, &sb->sbtmerrlog)));
3147         SB_ERROR(("sbadmatch3 0x%x sbadmatch2 0x%x sbadmatch1 0x%x\n",
3148                   R_SBREG(si, &sb->sbadmatch3), R_SBREG(si, &sb->sbadmatch2),
3149                   R_SBREG(si, &sb->sbadmatch1)));
3150         SB_ERROR(("sbimstate 0x%x sbintvec 0x%x sbtmstatelow 0x%x sbtmstatehigh 0x%x\n", R_SBREG(si, &sb->sbimstate), R_SBREG(si, &sb->sbintvec), R_SBREG(si, &sb->sbtmstatelow), R_SBREG(si, &sb->sbtmstatehigh)));
3151         SB_ERROR(("sbbwa0 0x%x sbimconfiglow 0x%x sbimconfighigh 0x%x sbadmatch0 0x%x\n", R_SBREG(si, &sb->sbbwa0), R_SBREG(si, &sb->sbimconfiglow), R_SBREG(si, &sb->sbimconfighigh), R_SBREG(si, &sb->sbadmatch0)));
3152         SB_ERROR(("sbtmconfiglow 0x%x sbtmconfighigh 0x%x sbbconfig 0x%x sbbstate 0x%x\n", R_SBREG(si, &sb->sbtmconfiglow), R_SBREG(si, &sb->sbtmconfighigh), R_SBREG(si, &sb->sbbconfig), R_SBREG(si, &sb->sbbstate)));
3153         SB_ERROR(("sbactcnfg 0x%x sbflagst 0x%x sbidlow 0x%x sbidhigh 0x%x\n",
3154                   R_SBREG(si, &sb->sbactcnfg), R_SBREG(si, &sb->sbflagst),
3155                   R_SBREG(si, &sb->sbidlow), R_SBREG(si, &sb->sbidhigh)));
3156 }
3157
3158 void sb_viewall(sb_t * sbh)
3159 {
3160         sb_info_t *si;
3161         uint curidx, i;
3162         uint intr_val = 0;
3163
3164         si = SB_INFO(sbh);
3165         curidx = si->curidx;
3166
3167         for (i = 0; i < si->numcores; i++) {
3168                 INTR_OFF(si, intr_val);
3169                 sb_setcoreidx(sbh, i);
3170                 sb_view(sbh);
3171                 INTR_RESTORE(si, intr_val);
3172         }
3173
3174         sb_setcoreidx(sbh, curidx);
3175 }
3176 #endif /* BCMDBG */
3177
3178 /* return the slow clock source - LPO, XTAL, or PCI */
3179 static uint sb_slowclk_src(sb_info_t * si)
3180 {
3181         chipcregs_t *cc;
3182
3183         ASSERT(sb_coreid(&si->sb) == SB_CC);
3184
3185         if (si->sb.ccrev < 6) {
3186                 if ((BUSTYPE(si->sb.bustype) == PCI_BUS) &&
3187                     (OSL_PCI_READ_CONFIG(si->osh, PCI_GPIO_OUT, sizeof(uint32))
3188                      & PCI_CFG_GPIO_SCS))
3189                         return (SCC_SS_PCI);
3190                 else
3191                         return (SCC_SS_XTAL);
3192         } else if (si->sb.ccrev < 10) {
3193                 cc = (chipcregs_t *) sb_setcoreidx(&si->sb, si->curidx);
3194                 return (R_REG(si->osh, &cc->slow_clk_ctl) & SCC_SS_MASK);
3195         } else                  /* Insta-clock */
3196                 return (SCC_SS_XTAL);
3197 }
3198
3199 /* return the ILP (slowclock) min or max frequency */
3200 static uint sb_slowclk_freq(sb_info_t * si, bool max_freq)
3201 {
3202         chipcregs_t *cc;
3203         uint32 slowclk;
3204         uint div;
3205
3206         ASSERT(sb_coreid(&si->sb) == SB_CC);
3207
3208         cc = (chipcregs_t *) sb_setcoreidx(&si->sb, si->curidx);
3209
3210         /* shouldn't be here unless we've established the chip has dynamic clk control */
3211         ASSERT(R_REG(si->osh, &cc->capabilities) & CC_CAP_PWR_CTL);
3212
3213         slowclk = sb_slowclk_src(si);
3214         if (si->sb.ccrev < 6) {
3215                 if (slowclk == SCC_SS_PCI)
3216                         return (max_freq ? (PCIMAXFREQ / 64)
3217                                 : (PCIMINFREQ / 64));
3218                 else
3219                         return (max_freq ? (XTALMAXFREQ / 32)
3220                                 : (XTALMINFREQ / 32));
3221         } else if (si->sb.ccrev < 10) {
3222                 div =
3223                     4 *
3224                     (((R_REG(si->osh, &cc->slow_clk_ctl) & SCC_CD_MASK) >>
3225                       SCC_CD_SHIFT)
3226                      + 1);
3227                 if (slowclk == SCC_SS_LPO)
3228                         return (max_freq ? LPOMAXFREQ : LPOMINFREQ);
3229                 else if (slowclk == SCC_SS_XTAL)
3230                         return (max_freq ? (XTALMAXFREQ / div)
3231                                 : (XTALMINFREQ / div));
3232                 else if (slowclk == SCC_SS_PCI)
3233                         return (max_freq ? (PCIMAXFREQ / div)
3234                                 : (PCIMINFREQ / div));
3235                 else
3236                         ASSERT(0);
3237         } else {
3238                 /* Chipc rev 10 is InstaClock */
3239                 div = R_REG(si->osh, &cc->system_clk_ctl) >> SYCC_CD_SHIFT;
3240                 div = 4 * (div + 1);
3241                 return (max_freq ? XTALMAXFREQ : (XTALMINFREQ / div));
3242         }
3243         return (0);
3244 }
3245
3246 static void BCMINITFN(sb_clkctl_setdelay) (sb_info_t * si, void *chipcregs) {
3247         chipcregs_t *cc;
3248         uint slowmaxfreq, pll_delay, slowclk;
3249         uint pll_on_delay, fref_sel_delay;
3250
3251         pll_delay = PLL_DELAY;
3252
3253         /* If the slow clock is not sourced by the xtal then add the xtal_on_delay
3254          * since the xtal will also be powered down by dynamic clk control logic.
3255          */
3256
3257         slowclk = sb_slowclk_src(si);
3258         if (slowclk != SCC_SS_XTAL)
3259                 pll_delay += XTAL_ON_DELAY;
3260
3261         /* Starting with 4318 it is ILP that is used for the delays */
3262         slowmaxfreq = sb_slowclk_freq(si, (si->sb.ccrev >= 10) ? FALSE : TRUE);
3263
3264         pll_on_delay = ((slowmaxfreq * pll_delay) + 999999) / 1000000;
3265         fref_sel_delay = ((slowmaxfreq * FREF_DELAY) + 999999) / 1000000;
3266
3267         cc = (chipcregs_t *) chipcregs;
3268         W_REG(si->osh, &cc->pll_on_delay, pll_on_delay);
3269         W_REG(si->osh, &cc->fref_sel_delay, fref_sel_delay);
3270 }
3271
3272 /* initialize power control delay registers */
3273 void BCMINITFN(sb_clkctl_init) (sb_t * sbh) {
3274         sb_info_t *si;
3275         uint origidx;
3276         chipcregs_t *cc;
3277
3278         si = SB_INFO(sbh);
3279
3280         origidx = si->curidx;
3281
3282         if ((cc = (chipcregs_t *) sb_setcore(sbh, SB_CC, 0)) == NULL)
3283                 return;
3284
3285         if ((si->sb.chip == BCM4321_CHIP_ID) && (si->sb.chiprev < 2))
3286                 W_REG(si->osh, &cc->chipcontrol,
3287                       (si->sb.chiprev ==
3288                        0) ? CHIPCTRL_4321A0_DEFAULT : CHIPCTRL_4321A1_DEFAULT);
3289
3290         if (!(R_REG(si->osh, &cc->capabilities) & CC_CAP_PWR_CTL))
3291                 goto done;
3292
3293         /* set all Instaclk chip ILP to 1 MHz */
3294         if (si->sb.ccrev >= 10)
3295                 SET_REG(si->osh, &cc->system_clk_ctl, SYCC_CD_MASK,
3296                         (ILP_DIV_1MHZ << SYCC_CD_SHIFT));
3297
3298         sb_clkctl_setdelay(si, (void *)(uintptr) cc);
3299
3300       done:
3301         sb_setcoreidx(sbh, origidx);
3302 }
3303
3304 /* return the value suitable for writing to the dot11 core FAST_PWRUP_DELAY register */
3305 uint16 BCMINITFN(sb_clkctl_fast_pwrup_delay) (sb_t * sbh) {
3306         sb_info_t *si;
3307         uint origidx;
3308         chipcregs_t *cc;
3309         uint slowminfreq;
3310         uint16 fpdelay;
3311         uint intr_val = 0;
3312
3313         si = SB_INFO(sbh);
3314         fpdelay = 0;
3315         origidx = si->curidx;
3316
3317         INTR_OFF(si, intr_val);
3318
3319         if ((cc = (chipcregs_t *) sb_setcore(sbh, SB_CC, 0)) == NULL)
3320                 goto done;
3321
3322         if (sbh->cccaps & CC_CAP_PMU) {
3323                 fpdelay = sb_pmu_fast_pwrup_delay(sbh, si->osh);
3324                 goto done;
3325         }
3326
3327         if (!(sbh->cccaps & CC_CAP_PWR_CTL))
3328                 goto done;
3329
3330         slowminfreq = sb_slowclk_freq(si, FALSE);
3331         fpdelay = (((R_REG(si->osh, &cc->pll_on_delay) + 2) * 1000000) +
3332                    (slowminfreq - 1)) / slowminfreq;
3333
3334       done:
3335         sb_setcoreidx(sbh, origidx);
3336         INTR_RESTORE(si, intr_val);
3337         return (fpdelay);
3338 }
3339
3340 /* turn primary xtal and/or pll off/on */
3341 int sb_clkctl_xtal(sb_t * sbh, uint what, bool on)
3342 {
3343         sb_info_t *si;
3344         uint32 in, out, outen;
3345
3346         si = SB_INFO(sbh);
3347
3348         switch (BUSTYPE(si->sb.bustype)) {
3349
3350         case PCMCIA_BUS:
3351                 return (0);
3352
3353         case PCI_BUS:
3354
3355                 /* pcie core doesn't have any mapping to control the xtal pu */
3356                 if (PCIE(si))
3357                         return -1;
3358
3359                 in = OSL_PCI_READ_CONFIG(si->osh, PCI_GPIO_IN, sizeof(uint32));
3360                 out =
3361                     OSL_PCI_READ_CONFIG(si->osh, PCI_GPIO_OUT, sizeof(uint32));
3362                 outen =
3363                     OSL_PCI_READ_CONFIG(si->osh, PCI_GPIO_OUTEN,
3364                                         sizeof(uint32));
3365
3366                 /*
3367                  * Avoid glitching the clock if GPRS is already using it.
3368                  * We can't actually read the state of the PLLPD so we infer it
3369                  * by the value of XTAL_PU which *is* readable via gpioin.
3370                  */
3371                 if (on && (in & PCI_CFG_GPIO_XTAL))
3372                         return (0);
3373
3374                 if (what & XTAL)
3375                         outen |= PCI_CFG_GPIO_XTAL;
3376                 if (what & PLL)
3377                         outen |= PCI_CFG_GPIO_PLL;
3378
3379                 if (on) {
3380                         /* turn primary xtal on */
3381                         if (what & XTAL) {
3382                                 out |= PCI_CFG_GPIO_XTAL;
3383                                 if (what & PLL)
3384                                         out |= PCI_CFG_GPIO_PLL;
3385                                 OSL_PCI_WRITE_CONFIG(si->osh, PCI_GPIO_OUT,
3386                                                      sizeof(uint32), out);
3387                                 OSL_PCI_WRITE_CONFIG(si->osh, PCI_GPIO_OUTEN,
3388                                                      sizeof(uint32), outen);
3389                                 OSL_DELAY(XTAL_ON_DELAY);
3390                         }
3391
3392                         /* turn pll on */
3393                         if (what & PLL) {
3394                                 out &= ~PCI_CFG_GPIO_PLL;
3395                                 OSL_PCI_WRITE_CONFIG(si->osh, PCI_GPIO_OUT,
3396                                                      sizeof(uint32), out);
3397                                 OSL_DELAY(2000);
3398                         }
3399                 } else {
3400                         if (what & XTAL)
3401                                 out &= ~PCI_CFG_GPIO_XTAL;
3402                         if (what & PLL)
3403                                 out |= PCI_CFG_GPIO_PLL;
3404                         OSL_PCI_WRITE_CONFIG(si->osh, PCI_GPIO_OUT,
3405                                              sizeof(uint32), out);
3406                         OSL_PCI_WRITE_CONFIG(si->osh, PCI_GPIO_OUTEN,
3407                                              sizeof(uint32), outen);
3408                 }
3409
3410         default:
3411                 return (-1);
3412         }
3413
3414         return (0);
3415 }
3416
3417 /* set dynamic clk control mode (forceslow, forcefast, dynamic) */
3418 /*   returns true if we are forcing fast clock */
3419 bool sb_clkctl_clk(sb_t * sbh, uint mode)
3420 {
3421         sb_info_t *si;
3422         uint origidx;
3423         chipcregs_t *cc;
3424         uint32 scc;
3425         uint intr_val = 0;
3426
3427         si = SB_INFO(sbh);
3428
3429         /* chipcommon cores prior to rev6 don't support dynamic clock control */
3430         if (si->sb.ccrev < 6)
3431                 return (FALSE);
3432
3433         /* Chips with ccrev 10 are EOL and they don't have SYCC_HR which we use below */
3434         ASSERT(si->sb.ccrev != 10);
3435
3436         INTR_OFF(si, intr_val);
3437
3438         origidx = si->curidx;
3439
3440         if (sb_setcore(sbh, SB_MIPS33, 0) && (sb_corerev(&si->sb) <= 7) &&
3441             (BUSTYPE(si->sb.bustype) == SB_BUS) && (si->sb.ccrev >= 10))
3442                 goto done;
3443
3444         if (FORCEHT_WAR32414(si))
3445                 goto done;
3446
3447         cc = (chipcregs_t *) sb_setcore(sbh, SB_CC, 0);
3448         ASSERT(cc != NULL);
3449
3450         if (!(R_REG(si->osh, &cc->capabilities) & CC_CAP_PWR_CTL)
3451             && (si->sb.ccrev < 20))
3452                 goto done;
3453
3454         switch (mode) {
3455         case CLK_FAST:          /* force fast (pll) clock */
3456                 if (si->sb.ccrev < 10) {
3457                         /* don't forget to force xtal back on before we clear SCC_DYN_XTAL.. */
3458                         sb_clkctl_xtal(&si->sb, XTAL, ON);
3459
3460                         SET_REG(si->osh, &cc->slow_clk_ctl,
3461                                 (SCC_XC | SCC_FS | SCC_IP), SCC_IP);
3462                 } else if (si->sb.ccrev < 20) {
3463                         OR_REG(si->osh, &cc->system_clk_ctl, SYCC_HR);
3464                 } else {
3465                         OR_REG(si->osh, &cc->clk_ctl_st, CCS_FORCEHT);
3466                 }
3467
3468                 /* wait for the PLL */
3469                 if (R_REG(si->osh, &cc->capabilities) & CC_CAP_PMU) {
3470                         SPINWAIT(((R_REG(si->osh, &cc->clk_ctl_st) &
3471                                    CCS_HTAVAIL) == 0), PMU_MAX_TRANSITION_DLY);
3472                         ASSERT(R_REG(si->osh, &cc->clk_ctl_st) & CCS_HTAVAIL);
3473                 } else {
3474                         OSL_DELAY(PLL_DELAY);
3475                 }
3476                 break;
3477
3478         case CLK_DYNAMIC:       /* enable dynamic clock control */
3479                 if (si->sb.ccrev < 10) {
3480                         scc = R_REG(si->osh, &cc->slow_clk_ctl);
3481                         scc &= ~(SCC_FS | SCC_IP | SCC_XC);
3482                         if ((scc & SCC_SS_MASK) != SCC_SS_XTAL)
3483                                 scc |= SCC_XC;
3484                         W_REG(si->osh, &cc->slow_clk_ctl, scc);
3485
3486                         /* for dynamic control, we have to release our xtal_pu "force on" */
3487                         if (scc & SCC_XC)
3488                                 sb_clkctl_xtal(&si->sb, XTAL, OFF);
3489                 } else if (si->sb.ccrev < 20) {
3490                         /* Instaclock */
3491                         AND_REG(si->osh, &cc->system_clk_ctl, ~SYCC_HR);
3492                 } else {
3493                         AND_REG(si->osh, &cc->clk_ctl_st, ~CCS_FORCEHT);
3494                 }
3495                 break;
3496
3497         default:
3498                 ASSERT(0);
3499         }
3500
3501       done:
3502         sb_setcoreidx(sbh, origidx);
3503         INTR_RESTORE(si, intr_val);
3504         return (mode == CLK_FAST);
3505 }
3506
3507 /* register driver interrupt disabling and restoring callback functions */
3508 void
3509 sb_register_intr_callback(sb_t * sbh, void *intrsoff_fn,
3510                           void *intrsrestore_fn, void *intrsenabled_fn,
3511                           void *intr_arg)
3512 {
3513         sb_info_t *si;
3514
3515         si = SB_INFO(sbh);
3516         si->intr_arg = intr_arg;
3517         si->intrsoff_fn = (sb_intrsoff_t) intrsoff_fn;
3518         si->intrsrestore_fn = (sb_intrsrestore_t) intrsrestore_fn;
3519         si->intrsenabled_fn = (sb_intrsenabled_t) intrsenabled_fn;
3520         /* save current core id.  when this function called, the current core
3521          * must be the core which provides driver functions(il, et, wl, etc.)
3522          */
3523         si->dev_coreid = si->coreid[si->curidx];
3524 }
3525
3526 void sb_deregister_intr_callback(sb_t * sbh)
3527 {
3528         sb_info_t *si;
3529
3530         si = SB_INFO(sbh);
3531         si->intrsoff_fn = NULL;
3532 }
3533
3534 #ifdef BCMDBG
3535 /* dump dynamic clock control related registers */
3536 void sb_clkctl_dump(sb_t * sbh, struct bcmstrbuf *b)
3537 {
3538         sb_info_t *si;
3539         chipcregs_t *cc;
3540         uint origidx;
3541         uint intr_val = 0;
3542
3543         si = SB_INFO(sbh);
3544
3545         INTR_OFF(si, intr_val);
3546
3547         origidx = si->curidx;
3548
3549         if ((cc = (chipcregs_t *) sb_setcore(sbh, SB_CC, 0)) == NULL) {
3550                 INTR_RESTORE(si, intr_val);
3551                 return;
3552         }
3553
3554         if (!(R_REG(si->osh, &cc->capabilities) & CC_CAP_PWR_CTL))
3555                 goto done;
3556
3557         bcm_bprintf(b, "pll_on_delay 0x%x fref_sel_delay 0x%x ",
3558                     cc->pll_on_delay, cc->fref_sel_delay);
3559         if ((si->sb.ccrev >= 6) && (si->sb.ccrev < 10))
3560                 bcm_bprintf(b, "slow_clk_ctl 0x%x ", cc->slow_clk_ctl);
3561         if (si->sb.ccrev >= 10) {
3562                 bcm_bprintf(b, "system_clk_ctl 0x%x ", cc->system_clk_ctl);
3563                 bcm_bprintf(b, "clkstatestretch 0x%x ", cc->clkstatestretch);
3564         }
3565         if (BUSTYPE(si->sb.bustype) == PCI_BUS)
3566                 bcm_bprintf(b, "gpioout 0x%x gpioouten 0x%x ",
3567                             OSL_PCI_READ_CONFIG(si->osh, PCI_GPIO_OUT,
3568                                                 sizeof(uint32)),
3569                             OSL_PCI_READ_CONFIG(si->osh, PCI_GPIO_OUTEN,
3570                                                 sizeof(uint32)));
3571         bcm_bprintf(b, "\n");
3572
3573       done:
3574         sb_setcoreidx(sbh, origidx);
3575         INTR_RESTORE(si, intr_val);
3576 }
3577 #endif /* BCMDBG */
3578
3579 uint16 BCMINITFN(sb_d11_devid) (sb_t * sbh) {
3580         sb_info_t *si = SB_INFO(sbh);
3581         uint16 device;
3582
3583 #if defined(BCM4328)
3584         /* Fix device id for dual band BCM4328 */
3585         if (sbh->chip == BCM4328_CHIP_ID &&
3586             (sbh->chippkg == BCM4328USBDUAL_PKG_ID
3587              || sbh->chippkg == BCM4328SDIODUAL_PKG_ID))
3588                 device = BCM4328_D11DUAL_ID;
3589         else
3590 #endif /* BCM4328 */
3591                 /* Let an nvram variable with devpath override devid */
3592         if ((device = (uint16) sb_getdevpathintvar(sbh, "devid")) != 0) ;
3593         /* Get devid from OTP/SPROM depending on where the SROM is read */
3594         else if ((device = (uint16) getintvar(si->vars, "devid")) != 0) ;
3595         /*
3596          * no longer support wl0id, but keep the code
3597          * here for backward compatibility.
3598          */
3599         else if ((device = (uint16) getintvar(si->vars, "wl0id")) != 0) ;
3600         /* Chip specific conversion */
3601         else if (sbh->chip == BCM4712_CHIP_ID) {
3602                 if (sbh->chippkg == BCM4712SMALL_PKG_ID)
3603                         device = BCM4306_D11G_ID;
3604                 else
3605                         device = BCM4306_D11DUAL_ID;
3606         }
3607         /* ignore it */
3608         else
3609                 device = 0xffff;
3610
3611         return device;
3612 }
3613
3614 int
3615 BCMINITFN(sb_corepciid) (sb_t * sbh, uint func, uint16 * pcivendor,
3616                          uint16 * pcidevice, uint8 * pciclass,
3617                          uint8 * pcisubclass, uint8 * pciprogif,
3618                          uint8 * pciheader) {
3619         uint16 vendor = 0xffff, device = 0xffff;
3620         uint8 class, subclass, progif = 0;
3621         uint8 header = PCI_HEADER_NORMAL;
3622         uint32 core = sb_coreid(sbh);
3623
3624         /* Verify whether the function exists for the core */
3625         if (func >= (uint) (core == SB_USB20H ? 2 : 1))
3626                 return -1;
3627
3628         /* Known vendor translations */
3629         switch (sb_corevendor(sbh)) {
3630         case SB_VEND_BCM:
3631                 vendor = VENDOR_BROADCOM;
3632                 break;
3633         default:
3634                 return -1;
3635         }
3636
3637         /* Determine class based on known core codes */
3638         switch (core) {
3639         case SB_ILINE20:
3640                 class = PCI_CLASS_NET;
3641                 subclass = PCI_NET_ETHER;
3642                 device = BCM47XX_ILINE_ID;
3643                 break;
3644         case SB_ENET:
3645                 class = PCI_CLASS_NET;
3646                 subclass = PCI_NET_ETHER;
3647                 device = BCM47XX_ENET_ID;
3648                 break;
3649         case SB_GIGETH:
3650                 class = PCI_CLASS_NET;
3651                 subclass = PCI_NET_ETHER;
3652                 device = BCM47XX_GIGETH_ID;
3653                 break;
3654         case SB_SDRAM:
3655         case SB_MEMC:
3656                 class = PCI_CLASS_MEMORY;
3657                 subclass = PCI_MEMORY_RAM;
3658                 device = (uint16) core;
3659                 break;
3660         case SB_PCI:
3661         case SB_PCIE:
3662                 class = PCI_CLASS_BRIDGE;
3663                 subclass = PCI_BRIDGE_PCI;
3664                 device = (uint16) core;
3665                 header = PCI_HEADER_BRIDGE;
3666                 break;
3667         case SB_MIPS:
3668         case SB_MIPS33:
3669                 class = PCI_CLASS_CPU;
3670                 subclass = PCI_CPU_MIPS;
3671                 device = (uint16) core;
3672                 break;
3673         case SB_CODEC:
3674                 class = PCI_CLASS_COMM;
3675                 subclass = PCI_COMM_MODEM;
3676                 device = BCM47XX_V90_ID;
3677                 break;
3678         case SB_USB:
3679                 class = PCI_CLASS_SERIAL;
3680                 subclass = PCI_SERIAL_USB;
3681                 progif = 0x10;  /* OHCI */
3682                 device = BCM47XX_USB_ID;
3683                 break;
3684         case SB_USB11H:
3685                 class = PCI_CLASS_SERIAL;
3686                 subclass = PCI_SERIAL_USB;
3687                 progif = 0x10;  /* OHCI */
3688                 device = BCM47XX_USBH_ID;
3689                 break;
3690         case SB_USB20H:
3691                 class = PCI_CLASS_SERIAL;
3692                 subclass = PCI_SERIAL_USB;
3693                 progif = func == 0 ? 0x10 : 0x20;       /* OHCI/EHCI */
3694                 device = BCM47XX_USB20H_ID;
3695                 header = 0x80;  /* multifunction */
3696                 break;
3697         case SB_IPSEC:
3698                 class = PCI_CLASS_CRYPT;
3699                 subclass = PCI_CRYPT_NETWORK;
3700                 device = BCM47XX_IPSEC_ID;
3701                 break;
3702         case SB_ROBO:
3703                 class = PCI_CLASS_NET;
3704                 subclass = PCI_NET_OTHER;
3705                 device = BCM47XX_ROBO_ID;
3706                 break;
3707         case SB_EXTIF:
3708         case SB_CC:
3709                 class = PCI_CLASS_MEMORY;
3710                 subclass = PCI_MEMORY_FLASH;
3711                 device = (uint16) core;
3712                 break;
3713         case SB_SATAXOR:
3714                 class = PCI_CLASS_XOR;
3715                 subclass = PCI_XOR_QDMA;
3716                 device = BCM47XX_SATAXOR_ID;
3717                 break;
3718         case SB_ATA100:
3719                 class = PCI_CLASS_DASDI;
3720                 subclass = PCI_DASDI_IDE;
3721                 device = BCM47XX_ATA100_ID;
3722                 break;
3723         case SB_USB11D:
3724                 class = PCI_CLASS_SERIAL;
3725                 subclass = PCI_SERIAL_USB;
3726                 device = BCM47XX_USBD_ID;
3727                 break;
3728         case SB_USB20D:
3729                 class = PCI_CLASS_SERIAL;
3730                 subclass = PCI_SERIAL_USB;
3731                 device = BCM47XX_USB20D_ID;
3732                 break;
3733         case SB_D11:
3734                 class = PCI_CLASS_NET;
3735                 subclass = PCI_NET_OTHER;
3736                 device = sb_d11_devid(sbh);
3737                 break;
3738
3739         default:
3740                 class = subclass = progif = 0xff;
3741                 device = (uint16) core;
3742                 break;
3743         }
3744
3745         *pcivendor = vendor;
3746         *pcidevice = device;
3747         *pciclass = class;
3748         *pcisubclass = subclass;
3749         *pciprogif = progif;
3750         *pciheader = header;
3751
3752         return 0;
3753 }
3754
3755 /* use the mdio interface to read from mdio slaves */
3756 static int
3757 sb_pcie_mdioread(sb_info_t * si, uint physmedia, uint regaddr, uint * regval)
3758 {
3759         uint mdiodata;
3760         uint i = 0;
3761         sbpcieregs_t *pcieregs;
3762
3763         pcieregs = (sbpcieregs_t *) sb_setcoreidx(&si->sb, si->sb.buscoreidx);
3764         ASSERT(pcieregs);
3765
3766         /* enable mdio access to SERDES */
3767         W_REG(si->osh, (&pcieregs->mdiocontrol),
3768               MDIOCTL_PREAM_EN | MDIOCTL_DIVISOR_VAL);
3769
3770         mdiodata = MDIODATA_START | MDIODATA_READ |
3771             (physmedia << MDIODATA_DEVADDR_SHF) |
3772             (regaddr << MDIODATA_REGADDR_SHF) | MDIODATA_TA;
3773
3774         W_REG(si->osh, &pcieregs->mdiodata, mdiodata);
3775
3776         PR28829_DELAY();
3777
3778         /* retry till the transaction is complete */
3779         while (i < 10) {
3780                 if (R_REG(si->osh, &(pcieregs->mdiocontrol)) &
3781                     MDIOCTL_ACCESS_DONE) {
3782                         PR28829_DELAY();
3783                         *regval =
3784                             (R_REG(si->osh, &(pcieregs->mdiodata)) &
3785                              MDIODATA_MASK);
3786                         /* Disable mdio access to SERDES */
3787                         W_REG(si->osh, (&pcieregs->mdiocontrol), 0);
3788                         return 0;
3789                 }
3790                 OSL_DELAY(1000);
3791                 i++;
3792         }
3793
3794         SB_ERROR(("sb_pcie_mdioread: timed out\n"));
3795         /* Disable mdio access to SERDES */
3796         W_REG(si->osh, (&pcieregs->mdiocontrol), 0);
3797         return 1;
3798 }
3799
3800 /* use the mdio interface to write to mdio slaves */
3801 static int
3802 sb_pcie_mdiowrite(sb_info_t * si, uint physmedia, uint regaddr, uint val)
3803 {
3804         uint mdiodata;
3805         uint i = 0;
3806         sbpcieregs_t *pcieregs;
3807
3808         pcieregs = (sbpcieregs_t *) sb_setcoreidx(&si->sb, si->sb.buscoreidx);
3809         ASSERT(pcieregs);
3810
3811         /* enable mdio access to SERDES */
3812         W_REG(si->osh, (&pcieregs->mdiocontrol),
3813               MDIOCTL_PREAM_EN | MDIOCTL_DIVISOR_VAL);
3814
3815         mdiodata = MDIODATA_START | MDIODATA_WRITE |
3816             (physmedia << MDIODATA_DEVADDR_SHF) |
3817             (regaddr << MDIODATA_REGADDR_SHF) | MDIODATA_TA | val;
3818
3819         W_REG(si->osh, (&pcieregs->mdiodata), mdiodata);
3820
3821         PR28829_DELAY();
3822
3823         /* retry till the transaction is complete */
3824         while (i < 10) {
3825                 if (R_REG(si->osh, &(pcieregs->mdiocontrol)) &
3826                     MDIOCTL_ACCESS_DONE) {
3827                         /* Disable mdio access to SERDES */
3828                         W_REG(si->osh, (&pcieregs->mdiocontrol), 0);
3829                         return 0;
3830                 }
3831                 OSL_DELAY(1000);
3832                 i++;
3833         }
3834
3835         SB_ERROR(("sb_pcie_mdiowrite: timed out\n"));
3836         /* Disable mdio access to SERDES */
3837         W_REG(si->osh, (&pcieregs->mdiocontrol), 0);
3838         return 1;
3839
3840 }
3841
3842 /* indirect way to read pcie config regs */
3843 uint sb_pcie_readreg(void *sb, void *arg1, uint offset)
3844 {
3845         sb_info_t *si;
3846         sb_t *sbh;
3847         uint retval = 0xFFFFFFFF;
3848         sbpcieregs_t *pcieregs;
3849         uint addrtype;
3850
3851         sbh = (sb_t *) sb;
3852         si = SB_INFO(sbh);
3853         ASSERT(PCIE(si));
3854
3855         pcieregs = (sbpcieregs_t *) sb_setcore(sbh, SB_PCIE, 0);
3856         ASSERT(pcieregs);
3857
3858         addrtype = (uint) ((uintptr) arg1);
3859         switch (addrtype) {
3860         case PCIE_CONFIGREGS:
3861                 W_REG(si->osh, (&pcieregs->configaddr), offset);
3862                 retval = R_REG(si->osh, &(pcieregs->configdata));
3863                 break;
3864         case PCIE_PCIEREGS:
3865                 W_REG(si->osh, &(pcieregs->pcieindaddr), offset);
3866                 retval = R_REG(si->osh, &(pcieregs->pcieinddata));
3867                 break;
3868         default:
3869                 ASSERT(0);
3870                 break;
3871         }
3872         return retval;
3873 }
3874
3875 /* indirect way to write pcie config/mdio/pciecore regs */
3876 uint sb_pcie_writereg(sb_t * sbh, void *arg1, uint offset, uint val)
3877 {
3878         sb_info_t *si;
3879         sbpcieregs_t *pcieregs;
3880         uint addrtype;
3881
3882         si = SB_INFO(sbh);
3883         ASSERT(PCIE(si));
3884
3885         pcieregs = (sbpcieregs_t *) sb_setcore(sbh, SB_PCIE, 0);
3886         ASSERT(pcieregs);
3887
3888         addrtype = (uint) ((uintptr) arg1);
3889
3890         switch (addrtype) {
3891         case PCIE_CONFIGREGS:
3892                 W_REG(si->osh, (&pcieregs->configaddr), offset);
3893                 W_REG(si->osh, (&pcieregs->configdata), val);
3894                 break;
3895         case PCIE_PCIEREGS:
3896                 W_REG(si->osh, (&pcieregs->pcieindaddr), offset);
3897                 W_REG(si->osh, (&pcieregs->pcieinddata), val);
3898                 break;
3899         default:
3900                 ASSERT(0);
3901                 break;
3902         }
3903         return 0;
3904 }
3905
3906 /* Build device path. Support SB, PCI, and JTAG for now. */
3907 int BCMINITFN(sb_devpath) (sb_t * sbh, char *path, int size) {
3908         int slen;
3909         ASSERT(path);
3910         ASSERT(size >= SB_DEVPATH_BUFSZ);
3911
3912         if (!path || size <= 0)
3913                 return -1;
3914
3915         switch (BUSTYPE((SB_INFO(sbh))->sb.bustype)) {
3916         case SB_BUS:
3917         case JTAG_BUS:
3918                 slen = snprintf(path, (size_t) size, "sb/%u/", sb_coreidx(sbh));
3919                 break;
3920         case PCI_BUS:
3921                 ASSERT((SB_INFO(sbh))->osh);
3922                 slen = snprintf(path, (size_t) size, "pci/%u/%u/",
3923                                 OSL_PCI_BUS((SB_INFO(sbh))->osh),
3924                                 OSL_PCI_SLOT((SB_INFO(sbh))->osh));
3925                 break;
3926         case PCMCIA_BUS:
3927                 SB_ERROR(("sb_devpath: OSL_PCMCIA_BUS() not implemented, bus 1 assumed\n"));
3928                 SB_ERROR(("sb_devpath: OSL_PCMCIA_SLOT() not implemented, slot 1 assumed\n"));
3929                 slen = snprintf(path, (size_t) size, "pc/1/1/");
3930                 break;
3931         default:
3932                 slen = -1;
3933                 ASSERT(0);
3934                 break;
3935         }
3936
3937         if (slen < 0 || slen >= size) {
3938                 path[0] = '\0';
3939                 return -1;
3940         }
3941
3942         return 0;
3943 }
3944
3945 /* Get a variable, but only if it has a devpath prefix */
3946 char *BCMINITFN(sb_getdevpathvar) (sb_t * sbh, const char *name) {
3947         char varname[SB_DEVPATH_BUFSZ + 32];
3948
3949         sb_devpathvar(sbh, varname, sizeof(varname), name);
3950
3951         return (getvar(NULL, varname));
3952 }
3953
3954 /* Get a variable, but only if it has a devpath prefix */
3955 int BCMINITFN(sb_getdevpathintvar) (sb_t * sbh, const char *name) {
3956         char varname[SB_DEVPATH_BUFSZ + 32];
3957
3958         sb_devpathvar(sbh, varname, sizeof(varname), name);
3959
3960         return (getintvar(NULL, varname));
3961 }
3962
3963 /* Concatenate the dev path with a varname into the given 'var' buffer
3964  * and return the 'var' pointer.
3965  * Nothing is done to the arguments if len == 0 or var is NULL, var is still returned.
3966  * On overflow, the first char will be set to '\0'.
3967  */
3968 static char *BCMINITFN(sb_devpathvar) (sb_t * sbh, char *var, int len,
3969                                        const char *name) {
3970         uint path_len;
3971
3972         if (!var || len <= 0)
3973                 return var;
3974
3975         if (sb_devpath(sbh, var, len) == 0) {
3976                 path_len = strlen(var);
3977
3978                 if (strlen(name) + 1 > (uint) (len - path_len))
3979                         var[0] = '\0';
3980                 else
3981                         strncpy(var + path_len, name, len - path_len - 1);
3982         }
3983
3984         return var;
3985 }
3986
3987 /*
3988  * Fixup SROMless PCI device's configuration.
3989  * The current core may be changed upon return.
3990  */
3991 static int sb_pci_fixcfg(sb_info_t * si)
3992 {
3993         uint origidx, pciidx;
3994         sbpciregs_t *pciregs;
3995         sbpcieregs_t *pcieregs = NULL;
3996         uint16 val16, *reg16;
3997         uint32 w;
3998
3999         ASSERT(BUSTYPE(si->sb.bustype) == PCI_BUS);
4000
4001         /* Fixup PI in SROM shadow area to enable the correct PCI core access */
4002         /* save the current index */
4003         origidx = sb_coreidx(&si->sb);
4004
4005         /* check 'pi' is correct and fix it if not */
4006         if (si->sb.buscoretype == SB_PCIE) {
4007                 pcieregs = (sbpcieregs_t *) sb_setcore(&si->sb, SB_PCIE, 0);
4008                 ASSERT(pcieregs);
4009                 reg16 = &pcieregs->sprom[SRSH_PI_OFFSET];
4010         } else if (si->sb.buscoretype == SB_PCI) {
4011                 pciregs = (sbpciregs_t *) sb_setcore(&si->sb, SB_PCI, 0);
4012                 ASSERT(pciregs);
4013                 reg16 = &pciregs->sprom[SRSH_PI_OFFSET];
4014         } else {
4015                 ASSERT(0);
4016                 return -1;
4017         }
4018         pciidx = sb_coreidx(&si->sb);
4019         val16 = R_REG(si->osh, reg16);
4020         if (((val16 & SRSH_PI_MASK) >> SRSH_PI_SHIFT) != (uint16) pciidx) {
4021                 val16 =
4022                     (uint16) (pciidx << SRSH_PI_SHIFT) | (val16 &
4023                                                           ~SRSH_PI_MASK);
4024                 W_REG(si->osh, reg16, val16);
4025         }
4026
4027         if (PCIE_ASPMWARS(si)) {
4028                 w = sb_pcie_readreg((void *)(uintptr) & si->sb,
4029                                     (void *)PCIE_PCIEREGS, PCIE_PLP_STATUSREG);
4030
4031                 /* Detect the current polarity at attach and force that polarity and
4032                  * disable changing the polarity
4033                  */
4034                 if ((w & PCIE_PLP_POLARITYINV_STAT) == 0) {
4035                         si->pcie_polarity = (SERDES_RX_CTRL_FORCE);
4036                 } else {
4037                         si->pcie_polarity = (SERDES_RX_CTRL_FORCE |
4038                                              SERDES_RX_CTRL_POLARITY);
4039                 }
4040
4041                 w = OSL_PCI_READ_CONFIG(si->osh, si->pciecap_lcreg_offset,
4042                                         sizeof(uint32));
4043                 if (w & PCIE_CLKREQ_ENAB) {
4044                         reg16 = &pcieregs->sprom[SRSH_CLKREQ_OFFSET];
4045                         val16 = R_REG(si->osh, reg16);
4046                         /* if clockreq is not advertized clkreq should not be enabled */
4047                         if (!(val16 & SRSH_CLKREQ_ENB))
4048                                 SB_ERROR(("WARNING: CLK REQ enabled already  0x%x\n", w));
4049                 }
4050
4051                 sb_war43448(&si->sb);
4052
4053                 sb_war42767(&si->sb);
4054
4055         }
4056
4057         /* restore the original index */
4058         sb_setcoreidx(&si->sb, origidx);
4059
4060         return 0;
4061 }
4062
4063 /* Return ADDR64 capability of the backplane */
4064 bool sb_backplane64(sb_t * sbh)
4065 {
4066         sb_info_t *si;
4067
4068         si = SB_INFO(sbh);
4069         return ((si->sb.cccaps & CC_CAP_BKPLN64) != 0);
4070 }
4071
4072 void sb_btcgpiowar(sb_t * sbh)
4073 {
4074         sb_info_t *si;
4075         uint origidx;
4076         uint intr_val = 0;
4077         chipcregs_t *cc;
4078         si = SB_INFO(sbh);
4079
4080         /* Make sure that there is ChipCommon core present &&
4081          * UART_TX is strapped to 1
4082          */
4083         if (!(si->sb.cccaps & CC_CAP_UARTGPIO))
4084                 return;
4085
4086         /* sb_corereg cannot be used as we have to guarantee 8-bit read/writes */
4087         INTR_OFF(si, intr_val);
4088
4089         origidx = sb_coreidx(sbh);
4090
4091         cc = (chipcregs_t *) sb_setcore(sbh, SB_CC, 0);
4092         ASSERT(cc);
4093
4094         W_REG(si->osh, &cc->uart0mcr, R_REG(si->osh, &cc->uart0mcr) | 0x04);
4095
4096         /* restore the original index */
4097         sb_setcoreidx(sbh, origidx);
4098
4099         INTR_RESTORE(si, intr_val);
4100 }
4101
4102 /* check if the device is removed */
4103 bool sb_deviceremoved(sb_t * sbh)
4104 {
4105         uint32 w;
4106         sb_info_t *si;
4107
4108         si = SB_INFO(sbh);
4109
4110         switch (BUSTYPE(si->sb.bustype)) {
4111         case PCI_BUS:
4112                 ASSERT(si->osh);
4113                 w = OSL_PCI_READ_CONFIG(si->osh, PCI_CFG_VID, sizeof(uint32));
4114                 if ((w & 0xFFFF) != VENDOR_BROADCOM)
4115                         return TRUE;
4116                 else
4117                         return FALSE;
4118         default:
4119                 return FALSE;
4120         }
4121         return FALSE;
4122 }
4123
4124 #if 0
4125 /* Return the RAM size of the SOCRAM core */
4126 uint32 BCMINITFN(sb_socram_size) (sb_t * sbh) {
4127         sb_info_t *si;
4128         uint origidx;
4129         uint intr_val = 0;
4130
4131         sbsocramregs_t *regs;
4132         bool wasup;
4133         uint corerev;
4134         uint32 coreinfo;
4135         uint memsize = 0;
4136
4137         si = SB_INFO(sbh);
4138         ASSERT(si);
4139
4140         /* Block ints and save current core */
4141         INTR_OFF(si, intr_val);
4142         origidx = sb_coreidx(sbh);
4143
4144         /* Switch to SOCRAM core */
4145         if (!(regs = sb_setcore(sbh, SB_SOCRAM, 0)))
4146                 goto done;
4147
4148         /* Get info for determining size */
4149         if (!(wasup = sb_iscoreup(sbh)))
4150                 sb_core_reset(sbh, 0, 0);
4151         corerev = sb_corerev(sbh);
4152         coreinfo = R_REG(si->osh, &regs->coreinfo);
4153
4154         /* Calculate size from coreinfo based on rev */
4155         if (corerev == 0)
4156                 memsize = 1 << (16 + (coreinfo & SRCI_MS0_MASK));
4157         else if (corerev < 3) {
4158                 memsize = 1 << (SR_BSZ_BASE + (coreinfo & SRCI_SRBSZ_MASK));
4159                 memsize *= (coreinfo & SRCI_SRNB_MASK) >> SRCI_SRNB_SHIFT;
4160         } else {
4161                 uint nb = (coreinfo & SRCI_SRNB_MASK) >> SRCI_SRNB_SHIFT;
4162                 uint bsz = (coreinfo & SRCI_SRBSZ_MASK);
4163                 uint lss = (coreinfo & SRCI_LSS_MASK) >> SRCI_LSS_SHIFT;
4164                 if (lss != 0)
4165                         nb--;
4166                 memsize = nb * (1 << (bsz + SR_BSZ_BASE));
4167                 if (lss != 0)
4168                         memsize += (1 << ((lss - 1) + SR_BSZ_BASE));
4169         }
4170         /* Return to previous state and core */
4171         if (!wasup)
4172                 sb_core_disable(sbh, 0);
4173         sb_setcoreidx(sbh, origidx);
4174
4175       done:
4176         INTR_RESTORE(si, intr_val);
4177         return memsize;
4178 }
4179
4180 #endif