2 * Misc utility routines for accessing chip-specific features
3 * of the SiliconBackplane-based Broadcom chips.
5 * Copyright 2007, Broadcom Corporation
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.
33 #define SB_ERROR(args)
36 #define SB_MSG(args) printf args
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
);
45 typedef struct gpioh_item
{
48 gpio_handler_t handler
;
50 struct gpioh_item
*next
;
53 /* misc sb info needed by some of the routines */
54 typedef struct sb_info
{
56 struct sb_pub sb
; /* back plane public state (must be first field) */
58 void *osh
; /* osl os handle */
59 void *sdh
; /* bcmsdh handle */
61 void *curmap
; /* current regs va */
62 void *regs
[SB_MAXCORES
]; /* other regs va */
64 uint curidx
; /* current core index */
65 uint dev_coreid
; /* the core provides driver functions */
67 bool memseg
; /* flag to toggle MEM_SEG register */
69 uint gpioidx
; /* gpio control core index */
70 uint gpioid
; /* gpio control coretype */
72 uint numcores
; /* # discovered cores */
73 uint coreid
[SB_MAXCORES
]; /* id of each core */
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 */
80 uint8 pciecap_lcreg_offset
; /* PCIE capability LCreg offset in the config space */
83 bool pcie_war_ovr
; /* Override ASPM/Clkreq settings */
85 uint8 pmecap_offset
; /* PM Capability offset in the config space */
86 bool pmecap
; /* Capable of generating PME */
88 gpioh_item_t
*gpioh_head
; /* GPIO event handlers list */
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
,
109 static int sb_pcie_mdioread(sb_info_t
* si
, uint physmedia
, uint readdr
,
112 /* dev path concatenation util */
113 static char *sb_devpathvar(sb_t
* sbh
, char *var
, int len
, const char *name
);
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
);
123 /* delay needed between the mdio control/ mdiodata register data access */
124 #define PR28829_DELAY() OSL_DELAY(10)
126 /* size that can take bitfielddump */
127 #define BITFIELD_DUMP_SIZE 32
129 /* global variable to indicate reservation/release of gpio's */
130 static uint32 sb_gpioreservation
= 0;
132 /* global flag to prevent shared resources from being initialized multiple times in sb_attach() */
133 static bool sb_onetimeinit
= FALSE
;
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 */
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))
152 #define SONICS_2_2 (SBIDL_RV_2_2 >> SBIDL_RV_SHIFT)
153 #define SONICS_2_3 (SBIDL_RV_2_3 >> SBIDL_RV_SHIFT)
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)))
161 * Macros to disable/restore function core(D11, ENET, ILINE20, etc) interrupts before/
162 * after core switching to avoid invalid register accesss inside ISR.
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); }
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 */
179 #define ILP_DIV_5MHZ 0 /* ILP = 5 MHz */
180 #define ILP_DIV_1MHZ 4 /* ILP = 1 MHz */
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)))
187 #define PCIE_ASPMWARS(si) \
188 ((PCIE(si)) && ((si->sb.buscorerev >= 3) && (si->sb.buscorerev <= 5)))
190 /* GPIO Based LED powersave defines */
191 #define DEFAULT_GPIO_ONTIME 10 /* Default: 10% on */
192 #define DEFAULT_GPIO_OFFTIME 90 /* Default: 10% on */
194 #define DEFAULT_GPIOTIMERVAL ((DEFAULT_GPIO_ONTIME << GPIO_ONTIME_SHIFT) | DEFAULT_GPIO_OFFTIME)
196 static uint32
sb_read_sbreg(sb_info_t
* si
, volatile uint32
* sbr
)
199 uint32 val
, intr_val
= 0;
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
208 INTR_OFF(si
, intr_val
);
210 OSL_PCMCIA_WRITE_ATTR(si
->osh
, MEM_SEG
, &tmp
, 1);
211 sbr
= (volatile uint32
*)((uintptr
) sbr
& ~(1 << 11)); /* mask out bit 11 */
214 val
= R_REG(si
->osh
, sbr
);
218 OSL_PCMCIA_WRITE_ATTR(si
->osh
, MEM_SEG
, &tmp
, 1);
219 INTR_RESTORE(si
, intr_val
);
225 static void sb_write_sbreg(sb_info_t
* si
, volatile uint32
* sbr
, uint32 v
)
228 volatile uint32 dummy
;
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
238 INTR_OFF(si
, intr_val
);
240 OSL_PCMCIA_WRITE_ATTR(si
->osh
, MEM_SEG
, &tmp
, 1);
241 sbr
= (volatile uint32
*)((uintptr
) sbr
& ~(1 << 11)); /* mask out bit 11 */
244 if (BUSTYPE(si
->sb
.bustype
) == PCMCIA_BUS
) {
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));
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 */
259 W_REG(si
->osh
, sbr
, v
);
263 OSL_PCMCIA_WRITE_ATTR(si
->osh
, MEM_SEG
, &tmp
, 1);
264 INTR_RESTORE(si
, intr_val
);
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
277 sb_t
*sb_attach(uint devid
, osl_t
* osh
, void *regs
,
278 uint bustype
, void *sdh
, char **vars
,
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",
289 if (sb_doattach(si
, devid
, osh
, regs
, bustype
, sdh
, vars
, varsz
) ==
291 MFREE(osh
, si
, sizeof(sb_info_t
));
294 si
->vars
= vars
? *vars
: NULL
;
295 si
->varsz
= varsz
? *varsz
: 0;
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)
304 /* global kernel resource */
305 static sb_info_t ksi
;
307 /* generic kernel variant of sb_attach() */
308 sb_t
*BCMINITFN(sb_kattach
) (osl_t
* osh
) {
309 static bool ksi_attached
= FALSE
;
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
))) {
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
));
328 W_REG(osh
, scc
, val
);
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
)
340 #endif /* !BCMBUSTYPE || (BCMBUSTYPE == SB_BUS) */
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
) {
352 ASSERT(GOODREGS(regs
));
354 bzero((uchar
*) si
, sizeof(sb_info_t
));
355 si
->sb
.buscoreidx
= si
->gpioidx
= BADIDX
;
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
));
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
)));
376 /* need to set memseg flag for CF card first before any sb registers access */
377 if (BUSTYPE(si
->sb
.bustype
) == PCMCIA_BUS
)
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
);
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
);
391 /* initialize current core index value */
392 si
->curidx
= _sb_coreidx(si
);
394 if (si
->curidx
== BADIDX
) {
395 SB_ERROR(("sb_doattach: bad core index\n"));
399 /* get sonics backplane revision */
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
;
408 /* is core-0 a chipcommon core? */
410 cc
= (chipcregs_t
*) sb_setcoreidx(&si
->sb
, 0);
411 if (sb_coreid(&si
->sb
) != SB_CC
)
414 /* determine chip id and rev */
416 /* chip common core found! */
417 si
->sb
.chip
= R_REG(si
->osh
, &cc
->chipid
) & CID_ID_MASK
;
419 (R_REG(si
->osh
, &cc
->chipid
) & CID_REV_MASK
) >>
422 (R_REG(si
->osh
, &cc
->chipid
) & CID_PKG_MASK
) >>
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
);
433 /* get chipcommon rev */
434 si
->sb
.ccrev
= cc
? (int)sb_corerev(&si
->sb
) : NOREV
;
436 /* get chipcommon capabilites */
437 si
->sb
.cccaps
= cc
? R_REG(si
->osh
, &cc
->capabilities
) : 0;
439 /* determine numcores */
440 if (cc
&& ((si
->sb
.ccrev
== 4) || (si
->sb
.ccrev
>= 6)))
442 (R_REG(si
->osh
, &cc
->chipid
) & CID_CC_MASK
) >> CID_CC_SHIFT
;
444 si
->numcores
= sb_chip2numcores(si
->sb
.chip
);
446 /* return to original core */
447 sb_setcoreidx(&si
->sb
, origidx
);
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"));
461 /* Init nvram from sprom/otp if they exist */
463 (&si
->sb
, BUSTYPE(si
->sb
.bustype
), regs
, si
->osh
, vars
, varsz
)) {
464 SB_ERROR(("sb_doattach: srom_var_init failed: bad srom\n"));
467 pvars
= vars
? *vars
: NULL
;
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
);
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.
485 if (BUSTYPE(si
->sb
.bustype
) == PCMCIA_BUS
) {
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
,
491 si
->sb
.chiprev
= w
& 0xff;
496 if (BUSTYPE(si
->sb
.bustype
) == PCMCIA_BUS
) {
497 w
= getintvar(pvars
, "regwindowsz");
498 si
->memseg
= (w
<= CFTABLE_REGWIN_2K
) ? TRUE
: FALSE
;
500 /* gpio control core is required */
501 if (!GOODIDX(si
->gpioidx
)) {
502 SB_ERROR(("sb_doattach: gpio control core not found\n"));
506 /* get boardtype and boardrev */
507 switch (BUSTYPE(si
->sb
.bustype
)) {
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;
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;
521 SB_ERROR(("Overriding boardtype: 0x%x instead of 0x%x\n", si
->sb
.boardtype
, (w
>> 16) & 0xffff));
525 si
->sb
.boardvendor
= getintvar(pvars
, "manfid");
526 si
->sb
.boardtype
= getintvar(pvars
, "prodid");
531 si
->sb
.boardvendor
= VENDOR_BROADCOM
;
533 || ((si
->sb
.boardtype
= getintvar(pvars
, "prodid")) == 0))
534 if ((si
->sb
.boardtype
=
535 getintvar(NULL
, "boardtype")) == 0)
536 si
->sb
.boardtype
= 0xffff;
540 if (si
->sb
.boardtype
== 0) {
541 SB_ERROR(("sb_doattach: unknown board type\n"));
542 ASSERT(si
->sb
.boardtype
);
545 si
->sb
.boardflags
= getintvar(pvars
, "boardflags");
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
);
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") <=
561 || ((uint32
) getintvar(pvars
, "boardflags2") &
564 if (PCIE_ASPMWARS(si
)) {
565 sb_war43448_aspm((void *)si
);
566 sb_war42767_clkreq((void *)si
);
569 if (FORCEHT_WAR32414(si
)) {
570 si
->sb
.pr32414
= TRUE
;
571 sb_clkctl_init(&si
->sb
);
572 sb_war32414_forceHT(&si
->sb
, 1);
575 if (PCIE(si
) && ((si
->sb
.buscorerev
== 6) || (si
->sb
.buscorerev
== 7)))
576 si
->sb
.pr42780
= TRUE
;
578 if (PCIE_ASPMWARS(si
))
579 sb_pcieclkreq(&si
->sb
, 1, 0);
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));
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
);
595 /* clear any previous epidiag-induced target abort */
600 sb_onetimeinit
= TRUE
;
606 /* Enable/Disable clkreq for PCIE (4311B0/4321B1) */
607 void sb_war42780_clkreq(sb_t
* sbh
, bool clkreq
) {
612 /* Don't change clkreq value if serdespll war has not yet been applied */
613 if (!si
->pr42767_war
&& PCIE_ASPMWARS(si
))
616 sb_pcieclkreq(sbh
, 1, (int32
) clkreq
);
619 static void BCMINITFN(sb_war43448
) (sb_t
* sbh
) {
624 /* if not pcie bus, we're done */
625 if (!PCIE(si
) || !PCIE_ASPMWARS(si
))
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
);
634 static void BCMINITFN(sb_war43448_aspm
) (sb_t
* sbh
) {
636 uint16 val16
, *reg16
;
637 sbpcieregs_t
*pcieregs
;
642 /* if not pcie bus, we're done */
643 if (!PCIE(si
) || !PCIE_ASPMWARS(si
))
646 /* no ASPM stuff on QT or VSIM */
647 if (si
->sb
.chippkg
== HDLSIM_PKG_ID
|| si
->sb
.chippkg
== HWSIM_PKG_ID
)
650 pcieregs
= (sbpcieregs_t
*) sb_setcoreidx(sbh
, si
->sb
.buscoreidx
);
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
;
658 val16
&= ~SRSH_ASPM_ENB
;
659 W_REG(si
->osh
, reg16
, val16
);
661 w
= OSL_PCI_READ_CONFIG(si
->osh
, si
->pciecap_lcreg_offset
,
663 if (!si
->pcie_war_ovr
)
666 w
&= ~PCIE_ASPM_ENAB
;
667 OSL_PCI_WRITE_CONFIG(si
->osh
, si
->pciecap_lcreg_offset
, sizeof(uint32
),
671 static void BCMINITFN(sb_war32414_forceHT
) (sb_t
* sbh
, bool forceHT
) {
677 ASSERT(FORCEHT_WAR32414(si
));
681 sb_corereg(sbh
, SB_CC_IDX
, OFFSETOF(chipcregs_t
, system_clk_ctl
),
685 uint
sb_coreid(sb_t
* sbh
)
691 sb
= REGS2SB(si
->curmap
);
693 return ((R_SBREG(si
, &sb
->sbidhigh
) & SBIDH_CC_MASK
) >> SBIDH_CC_SHIFT
);
696 uint
sb_flag(sb_t
* sbh
)
702 sb
= REGS2SB(si
->curmap
);
704 return R_SBREG(si
, &sb
->sbtpsflag
) & SBTPS_NUM0_MASK
;
707 uint
sb_coreidx(sb_t
* sbh
)
715 static uint
_sb_coreidx(sb_info_t
* si
)
723 switch (BUSTYPE(si
->sb
.bustype
)) {
725 sb
= REGS2SB(si
->curmap
);
726 sbaddr
= sb_base(R_SBREG(si
, &sb
->sbadmatch0
));
731 OSL_PCI_READ_CONFIG(si
->osh
, PCI_BAR0_WIN
, sizeof(uint32
));
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;
748 sbaddr
= (uint32
) si
->curmap
;
756 if (!GOODCOREADDR(sbaddr
))
759 return ((sbaddr
- SB_ENUM_BASE
) / SB_CORE_SIZE
);
762 uint
sb_corevendor(sb_t
* sbh
)
768 sb
= REGS2SB(si
->curmap
);
770 return ((R_SBREG(si
, &sb
->sbidhigh
) & SBIDH_VC_MASK
) >> SBIDH_VC_SHIFT
);
773 uint
sb_corerev(sb_t
* sbh
)
780 sb
= REGS2SB(si
->curmap
);
781 sbidh
= R_SBREG(si
, &sb
->sbidhigh
);
783 return (SBCOREREV(sbidh
));
786 void *sb_osh(sb_t
* sbh
)
794 void sb_setosh(sb_t
* sbh
, osl_t
* osh
)
799 if (si
->osh
!= NULL
) {
800 SB_ERROR(("osh is already set....\n"));
806 /* set sbtmstatelow core-specific flags */
807 void sb_coreflags_wo(sb_t
* sbh
, uint32 mask
, uint32 val
)
814 sb
= REGS2SB(si
->curmap
);
816 ASSERT((val
& ~mask
) == 0);
819 w
= (R_SBREG(si
, &sb
->sbtmstatelow
) & ~mask
) | val
;
820 W_SBREG(si
, &sb
->sbtmstatelow
, w
);
823 /* set/clear sbtmstatelow core-specific flags */
824 uint32
sb_coreflags(sb_t
* sbh
, uint32 mask
, uint32 val
)
831 sb
= REGS2SB(si
->curmap
);
833 ASSERT((val
& ~mask
) == 0);
837 w
= (R_SBREG(si
, &sb
->sbtmstatelow
) & ~mask
) | val
;
838 W_SBREG(si
, &sb
->sbtmstatelow
, w
);
841 /* return the new value
842 * for write operation, the following readback ensures the completion of write opration.
844 return (R_SBREG(si
, &sb
->sbtmstatelow
));
847 /* set/clear sbtmstatehigh core-specific flags */
848 uint32
sb_coreflagshi(sb_t
* sbh
, uint32 mask
, uint32 val
)
855 sb
= REGS2SB(si
->curmap
);
857 ASSERT((val
& ~mask
) == 0);
858 ASSERT((mask
& ~SBTMH_FL_MASK
) == 0);
862 w
= (R_SBREG(si
, &sb
->sbtmstatehigh
) & ~mask
) | val
;
863 W_SBREG(si
, &sb
->sbtmstatehigh
, w
);
866 /* return the new value */
867 return (R_SBREG(si
, &sb
->sbtmstatehigh
));
870 /* Run bist on current core. Caller needs to take care of core-specific bist hazards */
871 int sb_corebist(sb_t
* sbh
)
879 sb
= REGS2SB(si
->curmap
);
881 sblo
= R_SBREG(si
, &sb
->sbtmstatelow
);
882 W_SBREG(si
, &sb
->sbtmstatelow
, (sblo
| SBTML_FGC
| SBTML_BE
));
884 SPINWAIT(((R_SBREG(si
, &sb
->sbtmstatehigh
) & SBTMH_BISTD
) == 0),
887 if (R_SBREG(si
, &sb
->sbtmstatehigh
) & SBTMH_BISTF
)
890 W_SBREG(si
, &sb
->sbtmstatelow
, sblo
);
895 bool sb_iscoreup(sb_t
* sbh
)
901 sb
= REGS2SB(si
->curmap
);
903 return ((R_SBREG(si
, &sb
->sbtmstatelow
) &
904 (SBTML_RESET
| SBTML_REJ_MASK
| SBTML_CLK
)) == SBTML_CLK
);
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.
911 * When using the silicon backplane, no fidleing with interrupts or core switches are needed.
913 * Also, when using pci/pcie, we can optimize away the core switching for pci registers
914 * and (on newer pci cores) chipcommon registers.
916 uint
sb_corereg(sb_t
* sbh
, uint coreidx
, uint regoff
, uint mask
, uint val
)
927 ASSERT(GOODIDX(coreidx
));
928 ASSERT(regoff
< SB_CORE_SIZE
);
929 ASSERT((val
& ~mask
) == 0);
932 if (BUSTYPE(si
->sb
.bustype
) == SB_BUS
) {
933 /* If internal bus, we can always get at everything */
935 /* map if does not exist */
936 if (!si
->regs
[coreidx
]) {
938 (void *)REG_MAP(si
->coresba
[coreidx
], SB_CORE_SIZE
);
939 ASSERT(GOODREGS(si
->regs
[coreidx
]));
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 */
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 */
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
958 if ((si
->sb
.buscoretype
== SB_PCIE
)
959 || (si
->sb
.buscorerev
>= 13))
960 r
= (uint32
*) ((char *)si
->curmap
+
961 PCI_16KB0_PCIREGS_OFFSET
+
964 r
= (uint32
*) ((char *)si
->curmap
+
965 ((regoff
>= SBCONFIGOFF
) ?
966 PCI_BAR0_PCISBR_OFFSET
:
967 PCI_BAR0_PCIREGS_OFFSET
)
974 INTR_OFF(si
, intr_val
);
976 /* save current core index */
977 origidx
= sb_coreidx(&si
->sb
);
980 r
= (uint32
*) ((uchar
*) sb_setcoreidx(&si
->sb
, coreidx
) +
987 if (regoff
>= SBCONFIGOFF
) {
988 w
= (R_SBREG(si
, r
) & ~mask
) | val
;
991 w
= (R_REG(si
->osh
, r
) & ~mask
) | val
;
992 W_REG(si
->osh
, r
, w
);
997 if (regoff
>= SBCONFIGOFF
)
1000 if ((si
->sb
.chip
== BCM5354_CHIP_ID
) &&
1001 (coreidx
== SB_CC_IDX
) &&
1002 (regoff
== OFFSETOF(chipcregs_t
, watchdog
))) {
1005 w
= R_REG(si
->osh
, r
);
1009 /* restore core index */
1010 if (origidx
!= coreidx
)
1011 sb_setcoreidx(&si
->sb
, origidx
);
1013 INTR_RESTORE(si
, intr_val
);
1019 #define DWORD_ALIGN(x) (x & ~(0x03))
1020 #define BYTE_POS(x) (x & 0x3)
1021 #define WORD_POS(x) (x & 0x1)
1023 #define BYTE_SHIFT(x) (8 * BYTE_POS(x))
1024 #define WORD_SHIFT(x) (16 * WORD_POS(x))
1026 #define BYTE_VAL(a, x) ((a >> BYTE_SHIFT(x)) & 0xFF)
1027 #define WORD_VAL(a, x) ((a >> WORD_SHIFT(x)) & 0xFFFF)
1029 #define read_pci_cfg_byte(a) \
1030 (BYTE_VAL(OSL_PCI_READ_CONFIG(si->osh, DWORD_ALIGN(a), 4), a) & 0xff)
1032 #define read_pci_cfg_word(a) \
1033 (WORD_VAL(OSL_PCI_READ_CONFIG(si->osh, DWORD_ALIGN(a), 4), a) & 0xffff)
1035 /* return cap_offset if requested capability exists in the PCI config space */
1037 sb_find_pci_capability(sb_info_t
* si
, uint8 req_cap_id
, uchar
* buf
,
1045 if (BUSTYPE(si
->sb
.bustype
) != PCI_BUS
)
1048 /* check for Header type 0 */
1049 byte_val
= read_pci_cfg_byte(PCI_CFG_HDR
);
1050 if ((byte_val
& 0x7f) != PCI_HEADER_NORMAL
)
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
))
1058 cap_ptr
= read_pci_cfg_byte(PCI_CFG_CAPPTR
);
1059 /* check if the capability pointer is 0x00 */
1060 if (cap_ptr
== 0x00)
1063 /* loop thr'u the capability list and see if the pcie capabilty exists */
1065 cap_id
= read_pci_cfg_byte(cap_ptr
);
1067 while (cap_id
!= req_cap_id
) {
1068 cap_ptr
= read_pci_cfg_byte((cap_ptr
+ 1));
1069 if (cap_ptr
== 0x00)
1071 cap_id
= read_pci_cfg_byte(cap_ptr
);
1073 if (cap_id
!= req_cap_id
) {
1076 /* found the caller requested capability */
1077 if ((buf
!= NULL
) && (buflen
!= NULL
)) {
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
;
1090 *buf
= read_pci_cfg_byte(cap_data
);
1099 uint8
sb_pcieclkreq(sb_t
* sbh
, uint32 mask
, uint32 val
)
1107 offset
= si
->pciecap_lcreg_offset
;
1111 reg_val
= OSL_PCI_READ_CONFIG(si
->osh
, offset
, sizeof(uint32
));
1115 reg_val
|= PCIE_CLKREQ_ENAB
;
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
));
1121 if (reg_val
& PCIE_CLKREQ_ENAB
)
1129 uint32
sb_pcielcreg(sb_t
* sbh
, uint32 mask
, uint32 val
)
1140 offset
= si
->pciecap_lcreg_offset
;
1146 OSL_PCI_WRITE_CONFIG(si
->osh
, offset
, sizeof(uint32
), val
);
1148 reg_val
= OSL_PCI_READ_CONFIG(si
->osh
, offset
, sizeof(uint32
));
1153 uint8
sb_pcieL1plldown(sb_t
* sbh
)
1164 if (!((si
->sb
.buscorerev
== 3) || (si
->sb
.buscorerev
== 4)))
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);
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
);
1177 SB_ERROR(("PCIEL1PLLDOWN: L0s is already disabled\n"));
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);
1184 sb_pcie_writereg((void *)(uintptr
) sbh
, (void *)PCIE_PCIEREGS
,
1185 PCIE_DLLP_PCIE11
, 0);
1187 sb_setcoreidx(sbh
, origidx
);
1188 INTR_RESTORE(si
, intr_val
);
1193 /* return TRUE if PCIE capability exists in the pci config space */
1194 static bool sb_ispcie(sb_info_t
* si
)
1198 cap_ptr
= sb_find_pci_capability(si
, PCI_CAP_PCIECAP_ID
, NULL
, NULL
);
1202 si
->pciecap_lcreg_offset
= cap_ptr
+ PCIE_CAP_LINKCTRL_OFFSET
;
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
)
1217 if (si
== NULL
|| !(PCI(si
) || PCIE(si
)))
1220 if (!si
->pmecap_offset
) {
1222 sb_find_pci_capability(si
, PCI_CAP_POWERMGMTCAP_ID
, NULL
,
1227 si
->pmecap_offset
= cap_ptr
;
1230 OSL_PCI_READ_CONFIG(si
->osh
, si
->pmecap_offset
,
1233 /* At least one state can generate PME */
1234 si
->pmecap
= (pmecap
& PME_CAP_PM_STATES
) != 0;
1237 return (si
->pmecap
);
1240 /* Enable PME generation and disable clkreq */
1241 void sb_pci_pmeen(sb_t
* sbh
)
1247 /* if not pmecapable return */
1248 if (!sb_pci_pmecap(sbh
))
1251 w
= OSL_PCI_READ_CONFIG(si
->osh
, si
->pmecap_offset
+ PME_CSR_OFFSET
,
1253 w
|= (PME_CSR_PME_EN
);
1254 OSL_PCI_WRITE_CONFIG(si
->osh
, si
->pmecap_offset
+ PME_CSR_OFFSET
,
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);
1266 /* Disable PME generation, clear the PME status bit if set and
1267 * return TRUE if PME status set
1269 bool sb_pci_pmeclr(sb_t
* sbh
)
1277 if (!sb_pci_pmecap(sbh
))
1280 w
= OSL_PCI_READ_CONFIG(si
->osh
, si
->pmecap_offset
+ PME_CSR_OFFSET
,
1283 SB_ERROR(("sb_pci_pmeclr PMECSR : 0x%x\n", w
));
1284 ret
= (w
& PME_CSR_PME_STAT
) == PME_CSR_PME_STAT
;
1286 /* PMESTAT is cleared by writing 1 to it */
1287 w
&= ~(PME_CSR_PME_EN
);
1289 OSL_PCI_WRITE_CONFIG(si
->osh
, si
->pmecap_offset
+ PME_CSR_OFFSET
,
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
);
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.
1317 static void BCMINITFN(sb_scan
) (sb_info_t
* si
) {
1330 /* numcores should already be set */
1331 ASSERT((si
->numcores
> 0) && (si
->numcores
<= SB_MAXCORES
));
1333 /* save current core index */
1334 origidx
= sb_coreidx(&si
->sb
);
1336 si
->sb
.buscorerev
= NOREV
;
1337 si
->sb
.buscoreidx
= BADIDX
;
1339 si
->gpioidx
= BADIDX
;
1342 pcirev
= pcierev
= NOREV
;
1343 pciidx
= pcieidx
= BADIDX
;
1345 for (i
= 0; i
< si
->numcores
; i
++) {
1346 sb_setcoreidx(&si
->sb
, i
);
1347 si
->coreid
[i
] = sb_coreid(&si
->sb
);
1349 if (si
->coreid
[i
] == SB_PCI
) {
1351 pcirev
= sb_corerev(&si
->sb
);
1353 } else if (si
->coreid
[i
] == SB_PCIE
) {
1355 pcierev
= sb_corerev(&si
->sb
);
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
;
1370 si
->sb
.buscoretype
= SB_PCI
;
1371 si
->sb
.buscorerev
= pcirev
;
1372 si
->sb
.buscoreidx
= pciidx
;
1374 si
->sb
.buscoretype
= SB_PCIE
;
1375 si
->sb
.buscorerev
= pcierev
;
1376 si
->sb
.buscoreidx
= pcieidx
;
1380 * Find the gpio "controlling core" type and index.
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)
1386 if (GOODIDX(sb_findcoreidx(sbh
, SB_CC
, 0))) {
1387 si
->gpioidx
= sb_findcoreidx(sbh
, SB_CC
, 0);
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
;
1396 ASSERT(si
->gpioidx
!= BADIDX
);
1398 /* return to original core index */
1399 sb_setcoreidx(&si
->sb
, origidx
);
1402 /* may be called with core in reset */
1403 void sb_detach(sb_t
* sbh
)
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
;
1419 #if !defined(BCMBUSTYPE) || (BCMBUSTYPE == SB_BUS)
1421 #endif /* !BCMBUSTYPE || (BCMBUSTYPE == SB_BUS) */
1422 MFREE(si
->osh
, si
, sizeof(sb_info_t
));
1426 /* convert chip number to number of i/o cores */
1427 static uint
BCMINITFN(sb_chip2numcores
) (uint chip
) {
1428 if (chip
== BCM4710_CHIP_ID
)
1430 if (chip
== BCM4402_CHIP_ID
)
1432 if (chip
== BCM4306_CHIP_ID
) /* < 4306c0 */
1434 if (chip
== BCM4704_CHIP_ID
)
1436 if (chip
== BCM5365_CHIP_ID
)
1438 if (chip
== SDIOH_FPGA_ID
)
1441 SB_ERROR(("sb_chip2numcores: unsupported chip 0x%x\n", chip
));
1446 /* return index of coreid or BADIDX if not found */
1447 uint
sb_findcoreidx(sb_t
* sbh
, uint coreid
, uint coreunit
)
1457 for (i
= 0; i
< si
->numcores
; i
++)
1458 if (si
->coreid
[i
] == coreid
) {
1459 if (found
== coreunit
)
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
1472 void *sb_setcoreidx(sb_t
* sbh
, uint coreidx
)
1480 if (coreidx
>= si
->numcores
)
1484 * If the user has provided an interrupt mask enabled function,
1485 * then assert interrupts are disabled before switching the core.
1487 ASSERT((si
->intrsenabled_fn
== NULL
)
1488 || !(*(si
)->intrsenabled_fn
) ((si
)->intr_arg
));
1490 sbaddr
= SB_ENUM_BASE
+ (coreidx
* SB_CORE_SIZE
);
1492 switch (BUSTYPE(si
->sb
.bustype
)) {
1495 if (!si
->regs
[coreidx
]) {
1497 (void *)REG_MAP(sbaddr
, SB_CORE_SIZE
);
1498 ASSERT(GOODREGS(si
->regs
[coreidx
]));
1500 si
->curmap
= si
->regs
[coreidx
];
1504 /* point bar0 window */
1505 OSL_PCI_WRITE_CONFIG(si
->osh
, PCI_BAR0_WIN
, 4, sbaddr
);
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);
1519 if (!si
->regs
[coreidx
]) {
1520 si
->regs
[coreidx
] = (void *)sbaddr
;
1521 ASSERT(GOODREGS(si
->regs
[coreidx
]));
1523 si
->curmap
= si
->regs
[coreidx
];
1525 #endif /* BCMJTAG */
1528 si
->curidx
= coreidx
;
1530 return (si
->curmap
);
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
1538 void *sb_setcore(sb_t
* sbh
, uint coreid
, uint coreunit
)
1542 idx
= sb_findcoreidx(sbh
, coreid
, coreunit
);
1546 return (sb_setcoreidx(sbh
, idx
));
1549 /* return chip number */
1550 uint
BCMINITFN(sb_chip
) (sb_t
* sbh
) {
1554 return (si
->sb
.chip
);
1557 /* return chip revision number */
1558 uint
BCMINITFN(sb_chiprev
) (sb_t
* sbh
) {
1562 return (si
->sb
.chiprev
);
1565 /* return chip common revision number */
1566 uint
BCMINITFN(sb_chipcrev
) (sb_t
* sbh
) {
1570 return (si
->sb
.ccrev
);
1573 /* return chip package option */
1574 uint
BCMINITFN(sb_chippkg
) (sb_t
* sbh
) {
1578 return (si
->sb
.chippkg
);
1581 /* return PCI core rev. */
1582 uint
BCMINITFN(sb_pcirev
) (sb_t
* sbh
) {
1586 return (si
->sb
.buscorerev
);
1589 bool BCMINITFN(sb_war16165
) (sb_t
* sbh
) {
1594 return (PCI(si
) && (si
->sb
.buscorerev
<= 10));
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);
1603 /* return PCMCIA core rev. */
1604 uint
BCMINITFN(sb_pcmciarev
) (sb_t
* sbh
) {
1608 return (si
->sb
.buscorerev
);
1611 /* return board vendor id */
1612 uint
BCMINITFN(sb_boardvendor
) (sb_t
* sbh
) {
1616 return (si
->sb
.boardvendor
);
1619 /* return boardtype */
1620 uint
BCMINITFN(sb_boardtype
) (sb_t
* sbh
) {
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");
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
;
1652 return (si
->sb
.boardtype
);
1655 /* return bus type of sbh device */
1656 uint
sb_bus(sb_t
* sbh
)
1661 return (si
->sb
.bustype
);
1664 /* return bus core type */
1665 uint
sb_buscoretype(sb_t
* sbh
)
1671 return (si
->sb
.buscoretype
);
1674 /* return bus core revision */
1675 uint
sb_buscorerev(sb_t
* sbh
)
1680 return (si
->sb
.buscorerev
);
1683 /* return list of found cores */
1684 uint
sb_corelist(sb_t
* sbh
, uint coreid
[])
1690 bcopy((uchar
*) si
->coreid
, (uchar
*) coreid
,
1691 (si
->numcores
* sizeof(uint
)));
1692 return (si
->numcores
);
1695 /* return current register mapping */
1696 void *sb_coreregs(sb_t
* sbh
)
1701 ASSERT(GOODREGS(si
->curmap
));
1703 return (si
->curmap
);
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
)
1712 uint i
, intr_val
= 0;
1713 void *corereg
= NULL
;
1715 INTR_OFF(si
, intr_val
);
1716 origidx
= sb_coreidx(&si
->sb
);
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
)));
1729 sb_setcoreidx(&si
->sb
, origidx
);
1730 INTR_RESTORE(si
, intr_val
);
1734 * Check if any inband, outband or timeout errors has happened and clear them.
1735 * Must be called with chip clk on !
1737 bool sb_taclear(sb_t
* sbh
)
1744 uint32 inband
= 0, serror
= 0, timeout
= 0;
1745 void *corereg
= NULL
;
1746 volatile uint32 imstate
, tmstate
;
1750 if (BUSTYPE(si
->sb
.bustype
) == PCI_BUS
) {
1751 volatile uint32 stcmd
;
1753 /* inband error is Target abort for PCI */
1755 OSL_PCI_READ_CONFIG(si
->osh
, PCI_CFG_CMD
, sizeof(uint32
));
1756 inband
= stcmd
& PCI_CFG_CMD_STAT_TA
;
1759 SB_ERROR(("inband:\n"));
1760 sb_viewall((void *)si
);
1762 OSL_PCI_WRITE_CONFIG(si
->osh
, PCI_CFG_CMD
,
1763 sizeof(uint32
), stcmd
);
1768 OSL_PCI_READ_CONFIG(si
->osh
, PCI_INT_STATUS
,
1770 serror
= stcmd
& PCI_SBIM_STATUS_SERR
;
1773 SB_ERROR(("serror:\n"));
1774 sb_viewall((void *)si
);
1777 OSL_PCI_WRITE_CONFIG(si
->osh
, PCI_INT_STATUS
,
1778 sizeof(uint32
), stcmd
);
1782 imstate
= sb_corereg(sbh
, si
->sb
.buscoreidx
,
1783 SBCONFIGOFF
+ OFFSETOF(sbconfig_t
,
1785 if ((imstate
!= 0xffffffff) && (imstate
& (SBIM_IBE
| SBIM_TO
))) {
1786 sb_corereg(sbh
, si
->sb
.buscoreidx
,
1787 SBCONFIGOFF
+ OFFSETOF(sbconfig_t
,
1789 (imstate
& ~(SBIM_IBE
| SBIM_TO
)));
1790 /* inband = imstate & SBIM_IBE; same as TA above */
1791 timeout
= imstate
& SBIM_TO
;
1794 SB_ERROR(("timeout:\n"));
1795 sb_viewall((void *)si
);
1801 /* dump errlog for sonics >= 2.3 */
1802 if (si
->sb
.sonicsrev
== SONICS_2_2
) ;
1804 uint32 imerrlog
, imerrloga
;
1806 sb_corereg(sbh
, si
->sb
.buscoreidx
,
1808 if (imerrlog
& SBTMEL_EC
) {
1810 sb_corereg(sbh
, si
->sb
.buscoreidx
,
1813 sb_corereg(sbh
, si
->sb
.buscoreidx
,
1815 SB_ERROR(("sb_taclear: ImErrLog 0x%x, ImErrLogA 0x%x\n", imerrlog
, imerrloga
));
1820 } else if (BUSTYPE(si
->sb
.bustype
) == PCMCIA_BUS
) {
1822 INTR_OFF(si
, intr_val
);
1823 origidx
= sb_coreidx(sbh
);
1825 corereg
= sb_setcore(sbh
, SB_PCMCIA
, 0);
1826 if (NULL
!= corereg
) {
1827 sb
= REGS2SB(corereg
);
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
;
1838 tmstate
= R_SBREG(si
, &sb
->sbtmstatehigh
);
1839 if ((tmstate
!= 0xffffffff)
1840 && (tmstate
& SBTMH_INT_STATUS
)) {
1845 OR_SBREG(si
, &sb
->sbtmstatelow
, SBTML_INT_ACK
);
1846 AND_SBREG(si
, &sb
->sbtmstatelow
,
1850 sb_setcoreidx(sbh
, origidx
);
1851 INTR_RESTORE(si
, intr_val
);
1855 if (inband
| timeout
| serror
) {
1857 SB_ERROR(("sb_taclear: inband 0x%x, serror 0x%x, timeout 0x%x!\n", inband
, serror
, timeout
));
1864 /* do buffered registers update */
1865 void sb_commit(sb_t
* sbh
)
1873 origidx
= si
->curidx
;
1874 ASSERT(GOODIDX(origidx
));
1876 INTR_OFF(si
, intr_val
);
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);
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);
1889 /* do the buffer registers update */
1890 W_REG(si
->osh
, &pciregs
->bcastaddr
, SB_COMMIT
);
1891 W_REG(si
->osh
, &pciregs
->bcastdata
, 0x0);
1895 /* restore core index */
1896 sb_setcoreidx(sbh
, origidx
);
1897 INTR_RESTORE(si
, intr_val
);
1900 /* reset and re-enable a core
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
1905 void sb_core_reset(sb_t
* sbh
, uint32 bits
, uint32 resetbits
)
1909 volatile uint32 dummy
;
1912 ASSERT(GOODREGS(si
->curmap
));
1913 sb
= REGS2SB(si
->curmap
);
1916 * Must do the disable sequence first to work for arbitrary current core state.
1918 sb_core_disable(sbh
, (bits
| resetbits
));
1921 * Now do the initialization sequence.
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
);
1930 if (R_SBREG(si
, &sb
->sbtmstatehigh
) & SBTMH_SERR
) {
1931 W_SBREG(si
, &sb
->sbtmstatehigh
, 0);
1933 if ((dummy
= R_SBREG(si
, &sb
->sbimstate
)) & (SBIM_IBE
| SBIM_TO
)) {
1934 AND_SBREG(si
, &sb
->sbimstate
, ~(SBIM_IBE
| SBIM_TO
));
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
);
1942 /* leave clock enabled */
1943 W_SBREG(si
, &sb
->sbtmstatelow
, (SBTML_CLK
| bits
));
1944 dummy
= R_SBREG(si
, &sb
->sbtmstatelow
);
1948 void sb_core_tofixup(sb_t
* sbh
)
1955 if ((BUSTYPE(si
->sb
.bustype
) != PCI_BUS
) || PCIE(si
) ||
1956 (PCI(si
) && (si
->sb
.buscorerev
>= 5)))
1959 ASSERT(GOODREGS(si
->curmap
));
1960 sb
= REGS2SB(si
->curmap
);
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);
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);
1972 SET_SBREG(si
, &sb
->sbimconfiglow
,
1973 (SBIMCL_RTO_MASK
| SBIMCL_STO_MASK
), 0);
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).
1986 * The routine uses the bus to decide who is the master:
1989 * PCI_BUS => pci or pcie
1990 * PCMCIA_BUS => pcmcia
1991 * SDIO_BUS => pcmcia
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.
1998 * Returns the timeout state before changing it or -1
2002 #define TO_MASK (SBIMCL_RTO_MASK | SBIMCL_STO_MASK)
2004 uint32
sb_set_initiator_to(sb_t
* sbh
, uint32 to
, uint idx
)
2009 uint32 tmp
, ret
= 0xffffffff;
2014 if ((to
& ~TO_MASK
) != 0)
2017 /* Figure out the master core */
2018 if (idx
== BADIDX
) {
2019 switch (BUSTYPE(si
->sb
.bustype
)) {
2021 idx
= si
->sb
.buscoreidx
;
2028 idx
= sb_findcoreidx(sbh
, SB_PCMCIA
, 0);
2031 if ((idx
= sb_findcoreidx(sbh
, SB_MIPS33
, 0)) == BADIDX
)
2032 idx
= sb_findcoreidx(sbh
, SB_MIPS
, 0);
2041 INTR_OFF(si
, intr_val
);
2042 origidx
= sb_coreidx(sbh
);
2044 sb
= REGS2SB(sb_setcoreidx(sbh
, idx
));
2046 tmp
= R_SBREG(si
, &sb
->sbimconfiglow
);
2047 ret
= tmp
& TO_MASK
;
2048 W_SBREG(si
, &sb
->sbimconfiglow
, (tmp
& ~TO_MASK
) | to
);
2051 sb_setcoreidx(sbh
, origidx
);
2052 INTR_RESTORE(si
, intr_val
);
2056 void sb_core_disable(sb_t
* sbh
, uint32 bits
)
2059 volatile uint32 dummy
;
2065 ASSERT(GOODREGS(si
->curmap
));
2066 sb
= REGS2SB(si
->curmap
);
2068 /* if core is already in reset, just return */
2069 if (R_SBREG(si
, &sb
->sbtmstatelow
) & SBTML_RESET
)
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
);
2076 rej
= (2 << SBTML_REJ_SHIFT
);
2078 /* if clocks are not enabled, put into reset and return */
2079 if ((R_SBREG(si
, &sb
->sbtmstatelow
) & SBTML_CLK
) == 0)
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
);
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__
));
2090 if (R_SBREG(si
, &sb
->sbidlow
) & SBIDL_INIT
) {
2091 OR_SBREG(si
, &sb
->sbimstate
, SBIM_RJ
);
2092 dummy
= R_SBREG(si
, &sb
->sbimstate
);
2094 SPINWAIT((R_SBREG(si
, &sb
->sbimstate
) & SBIM_BY
), 100000);
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
);
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
);
2108 /* leave reset and reject asserted */
2109 W_SBREG(si
, &sb
->sbtmstatelow
, (bits
| rej
| SBTML_RESET
));
2113 /* set chip watchdog reset timer to fire in 'ticks' backplane cycles */
2114 void sb_watchdog(sb_t
* sbh
, uint ticks
)
2116 sb_info_t
*si
= SB_INFO(sbh
);
2118 /* make sure we come up in fast clock mode; or if clearing, clear clock */
2120 sb_clkctl_clk(sbh
, CLK_FAST
);
2122 sb_clkctl_clk(sbh
, CLK_DYNAMIC
);
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
));
2130 switch (si
->gpioid
) {
2132 sb_corereg(sbh
, SB_CC_IDX
, OFFSETOF(chipcregs_t
, watchdog
), ~0,
2136 sb_corereg(sbh
, si
->gpioidx
, OFFSETOF(extifregs_t
, watchdog
),
2142 /* initialize the pcmcia core */
2143 void sb_pcmcia_init(sb_t
* sbh
)
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);
2157 void BCMINITFN(sb_pci_up
) (sb_t
* sbh
) {
2158 sb_info_t
*si
= SB_INFO(sbh
);
2159 if (si
->gpioid
== SB_EXTIF
)
2162 /* if not pci bus, we're done */
2163 if (BUSTYPE(si
->sb
.bustype
) != PCI_BUS
)
2166 if (FORCEHT_WAR32414(si
))
2167 sb_war32414_forceHT(sbh
, 1);
2169 if (PCIE_ASPMWARS(si
) || si
->sb
.pr42780
)
2170 sb_pcieclkreq(sbh
, 1, 0);
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));
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
)
2186 /* if not pci bus, we're done */
2187 if (!PCIE(si
) || !PCIE_ASPMWARS(si
))
2190 w
= OSL_PCI_READ_CONFIG(si
->osh
, si
->pciecap_lcreg_offset
,
2192 w
&= ~PCIE_CAP_LCREG_ASPML1
;
2193 OSL_PCI_WRITE_CONFIG(si
->osh
, si
->pciecap_lcreg_offset
, sizeof(uint32
),
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
)
2203 /* if not pci bus, we're done */
2204 if (BUSTYPE(si
->sb
.bustype
) != PCI_BUS
)
2207 if (FORCEHT_WAR32414(si
))
2208 sb_war32414_forceHT(sbh
, 0);
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);
2218 static void BCMINITFN(sb_war42767_clkreq
) (sb_t
* sbh
) {
2219 sbpcieregs_t
*pcieregs
;
2220 uint16 val16
, *reg16
;
2225 /* if not pcie bus, we're done */
2226 if (!PCIE(si
) || !PCIE_ASPMWARS(si
))
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
;
2237 si
->sb
.pr42780
= TRUE
;
2239 val16
&= ~SRSH_CLKREQ_ENB
;
2240 W_REG(si
->osh
, reg16
, val16
);
2243 static void BCMINITFN(sb_war42767
) (sb_t
* sbh
) {
2249 /* if not pcie bus, we're done */
2250 if (!PCIE(si
) || !PCIE_ASPMWARS(si
))
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
);
2261 * Configure the pci core for pci client (NIC) action
2262 * coremask is the bitvec of cores by index to be enabled.
2264 void BCMINITFN(sb_pci_setup
) (sb_t
* sbh
, uint coremask
) {
2267 sbpciregs_t
*pciregs
;
2274 /* if not pci bus, we're done */
2275 if (BUSTYPE(si
->sb
.bustype
) != PCI_BUS
)
2278 ASSERT(PCI(si
) || PCIE(si
));
2279 ASSERT(si
->sb
.buscoreidx
!= BADIDX
);
2281 /* get current core index */
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
;
2289 /* switch over to pci core */
2290 pciregs
= (sbpciregs_t
*) sb_setcoreidx(sbh
, si
->sb
.buscoreidx
);
2291 sb
= REGS2SB(pciregs
);
2294 * Enable sb->pci interrupts. Assume
2295 * PCI rev 2.3 support was added in pci core rev 6 and things changed..
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
);
2303 /* set sbintvec bit for our flag number */
2304 OR_SBREG(si
, &sb
->sbintvec
, (1 << sbflag
));
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);
2321 /* PCIE workarounds */
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
);
2328 sb_pcie_writereg((void *)(uintptr
) sbh
,
2329 (void *)(uintptr
) PCIE_PCIEREGS
,
2330 PCIE_TLP_WORKAROUNDSREG
, w
);
2333 if (si
->sb
.buscorerev
== 1) {
2334 w
= sb_pcie_readreg((void *)(uintptr
) sbh
,
2335 (void *)(uintptr
) PCIE_PCIEREGS
,
2338 sb_pcie_writereg((void *)(uintptr
) sbh
,
2339 (void *)(uintptr
) PCIE_PCIEREGS
,
2340 PCIE_DLLP_LCREG
, w
);
2343 if (si
->sb
.buscorerev
== 0)
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
);
2361 sb_war43448_aspm(sbh
);
2362 sb_war42767_clkreq(sbh
);
2366 /* switch back to previous core */
2367 sb_setcoreidx(sbh
, idx
);
2370 uint32
sb_base(uint32 admatch
)
2375 type
= admatch
& SBAM_TYPE_MASK
;
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
;
2393 uint32
sb_size(uint32 admatch
)
2398 type
= admatch
& SBAM_TYPE_MASK
;
2405 1 << (((admatch
& SBAM_ADINT0_MASK
) >> SBAM_ADINT0_SHIFT
) +
2407 } else if (type
== 1) {
2408 ASSERT(!(admatch
& SBAM_ADNEG
)); /* neg not supported */
2410 1 << (((admatch
& SBAM_ADINT1_MASK
) >> SBAM_ADINT1_SHIFT
) +
2412 } else if (type
== 2) {
2413 ASSERT(!(admatch
& SBAM_ADNEG
)); /* neg not supported */
2415 1 << (((admatch
& SBAM_ADINT2_MASK
) >> SBAM_ADINT2_SHIFT
) +
2422 /* return the core-type instantiation # of the current core */
2423 uint
sb_coreunit(sb_t
* sbh
)
2436 ASSERT(GOODREGS(si
->curmap
));
2437 coreid
= sb_coreid(sbh
);
2439 /* count the cores of our type */
2440 for (i
= 0; i
< idx
; i
++)
2441 if (si
->coreid
[i
] == coreid
)
2447 static uint32
BCMINITFN(factor6
) (uint32 x
) {
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
;
2470 n1
= n
& CN_N1_MASK
;
2471 n2
= (n
& CN_N2_MASK
) >> CN_N2_SHIFT
;
2473 if (pll_type
== PLL_TYPE6
) {
2474 if (m
& CC_T6_MMASK
)
2478 } else if ((pll_type
== PLL_TYPE1
) ||
2479 (pll_type
== PLL_TYPE3
) ||
2480 (pll_type
== PLL_TYPE4
) || (pll_type
== PLL_TYPE7
)) {
2483 } else if (pll_type
== PLL_TYPE2
) {
2486 ASSERT((n1
>= 2) && (n1
<= 7));
2487 ASSERT((n2
>= 5) && (n2
<= 23));
2488 } else if (pll_type
== PLL_TYPE5
) {
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
;
2496 clock
= CC_CLOCK_BASE1
* n1
* n2
;
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
;
2506 if ((pll_type
== PLL_TYPE1
) ||
2507 (pll_type
== PLL_TYPE3
) ||
2508 (pll_type
== PLL_TYPE4
) || (pll_type
== PLL_TYPE7
)) {
2510 if ((pll_type
== PLL_TYPE1
) || (pll_type
== PLL_TYPE3
))
2520 return (clock
/ m1
);
2522 return (clock
/ (m1
* m2
));
2524 return (clock
/ (m1
* m2
* m3
));
2526 return (clock
/ (m1
* m3
));
2531 ASSERT(pll_type
== PLL_TYPE2
);
2536 ASSERT((m1
>= 2) && (m1
<= 7));
2537 ASSERT((m2
>= 3) && (m2
<= 10));
2538 ASSERT((m3
>= 2) && (m3
<= 7));
2540 if ((mc
& CC_T2MC_M1BYP
) == 0)
2542 if ((mc
& CC_T2MC_M2BYP
) == 0)
2544 if ((mc
& CC_T2MC_M3BYP
) == 0)
2551 /* returns the current speed the SB is running at */
2552 uint32
BCMINITFN(sb_clock
) (sb_t
* sbh
) {
2558 uint32 cap
, pll_type
, rate
;
2563 pll_type
= PLL_TYPE1
;
2565 INTR_OFF(si
, intr_val
);
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))) {
2573 cap
= R_REG(si
->osh
, &cc
->capabilities
);
2575 if (cap
& CC_CAP_PMU
) {
2577 if (sb_chip(sbh
) == BCM5354_CHIP_ID
) {
2578 /* 5354 has a constant sb clock of 120MHz */
2582 if (sb_chip(sbh
) == BCM4328_CHIP_ID
) {
2589 pll_type
= cap
& CC_CAP_PLL_MASK
;
2590 if (pll_type
== PLL_NONE
) {
2591 INTR_RESTORE(si
, intr_val
);
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
);
2601 m
= R_REG(si
->osh
, &cc
->clockcontrol_sb
);
2603 INTR_RESTORE(si
, intr_val
);
2607 /* calculate rate */
2608 if (BCMINIT(sb_chip
) (sbh
) == 0x5365)
2611 rate
= sb_clock_rate(pll_type
, n
, m
);
2613 if (pll_type
== PLL_TYPE3
)
2618 /* switch back to previous core */
2619 sb_setcoreidx(sbh
, idx
);
2621 INTR_RESTORE(si
, intr_val
);
2626 uint32
BCMINITFN(sb_alp_clock
) (sb_t
* sbh
) {
2627 uint32 clock
= ALP_CLOCK
;
2629 if (sbh
->cccaps
& CC_CAP_PMU
)
2630 clock
= sb_pmu_alp_clock(sbh
, sb_osh(sbh
));
2635 /* change logical "focus" to the gpio core for optimized access */
2636 void *sb_gpiosetcore(sb_t
* sbh
)
2642 return (sb_setcoreidx(sbh
, si
->gpioidx
));
2645 /* mask&set gpiocontrol bits */
2646 uint32
sb_gpiocontrol(sb_t
* sbh
, uint32 mask
, uint32 val
, uint8 priority
)
2654 /* gpios could be shared on router platforms
2655 * ignore reservation if it's high priority (e.g., test apps)
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
));
2664 switch (si
->gpioid
) {
2666 regoff
= OFFSETOF(chipcregs_t
, gpiocontrol
);
2670 regoff
= OFFSETOF(sbpciregs_t
, gpiocontrol
);
2677 return (sb_corereg(sbh
, si
->gpioidx
, regoff
, mask
, val
));
2680 /* mask&set gpio output enable bits */
2681 uint32
sb_gpioouten(sb_t
* sbh
, uint32 mask
, uint32 val
, uint8 priority
)
2689 /* gpios could be shared on router platforms
2690 * ignore reservation if it's high priority (e.g., test apps)
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
));
2699 switch (si
->gpioid
) {
2701 regoff
= OFFSETOF(chipcregs_t
, gpioouten
);
2705 regoff
= OFFSETOF(sbpciregs_t
, gpioouten
);
2709 regoff
= OFFSETOF(extifregs_t
, gpio
[0].outen
);
2713 return (sb_corereg(sbh
, si
->gpioidx
, regoff
, mask
, val
));
2716 /* mask&set gpio output bits */
2717 uint32
sb_gpioout(sb_t
* sbh
, uint32 mask
, uint32 val
, uint8 priority
)
2725 /* gpios could be shared on router platforms
2726 * ignore reservation if it's high priority (e.g., test apps)
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
));
2735 switch (si
->gpioid
) {
2737 regoff
= OFFSETOF(chipcregs_t
, gpioout
);
2741 regoff
= OFFSETOF(sbpciregs_t
, gpioout
);
2745 regoff
= OFFSETOF(extifregs_t
, gpio
[0].out
);
2749 return (sb_corereg(sbh
, si
->gpioidx
, regoff
, mask
, val
));
2752 /* reserve one gpio */
2753 uint32
sb_gpioreserve(sb_t
* sbh
, uint32 gpio_bitmask
, uint8 priority
)
2759 /* only cores on SB_BUS share GPIO's and only applcation users need to
2760 * reserve/release GPIO
2762 if ((BUSTYPE(si
->sb
.bustype
) != SB_BUS
) || (!priority
)) {
2763 ASSERT((BUSTYPE(si
->sb
.bustype
) == SB_BUS
) && (priority
));
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)));
2773 /* already reserved */
2774 if (sb_gpioreservation
& gpio_bitmask
)
2776 /* set reservation */
2777 sb_gpioreservation
|= gpio_bitmask
;
2779 return sb_gpioreservation
;
2782 /* release one gpio */
2784 * releasing the gpio doesn't change the current value on the GPIO last write value
2785 * persists till some one overwrites it
2788 uint32
sb_gpiorelease(sb_t
* sbh
, uint32 gpio_bitmask
, uint8 priority
)
2794 /* only cores on SB_BUS share GPIO's and only applcation users need to
2795 * reserve/release GPIO
2797 if ((BUSTYPE(si
->sb
.bustype
) != SB_BUS
) || (!priority
)) {
2798 ASSERT((BUSTYPE(si
->sb
.bustype
) == SB_BUS
) && (priority
));
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)));
2808 /* already released */
2809 if (!(sb_gpioreservation
& gpio_bitmask
))
2812 /* clear reservation */
2813 sb_gpioreservation
&= ~gpio_bitmask
;
2815 return sb_gpioreservation
;
2818 /* return the current gpioin register value */
2819 uint32
sb_gpioin(sb_t
* sbh
)
2827 switch (si
->gpioid
) {
2829 regoff
= OFFSETOF(chipcregs_t
, gpioin
);
2833 regoff
= OFFSETOF(sbpciregs_t
, gpioin
);
2837 regoff
= OFFSETOF(extifregs_t
, gpioin
);
2841 return (sb_corereg(sbh
, si
->gpioidx
, regoff
, 0, 0));
2844 /* mask&set gpio interrupt polarity bits */
2845 uint32
sb_gpiointpolarity(sb_t
* sbh
, uint32 mask
, uint32 val
, uint8 priority
)
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
));
2860 switch (si
->gpioid
) {
2862 regoff
= OFFSETOF(chipcregs_t
, gpiointpolarity
);
2866 /* pci gpio implementation does not support interrupt polarity */
2871 regoff
= OFFSETOF(extifregs_t
, gpiointpolarity
);
2875 return (sb_corereg(sbh
, si
->gpioidx
, regoff
, mask
, val
));
2878 /* mask&set gpio interrupt mask bits */
2879 uint32
sb_gpiointmask(sb_t
* sbh
, uint32 mask
, uint32 val
, uint8 priority
)
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
));
2894 switch (si
->gpioid
) {
2896 regoff
= OFFSETOF(chipcregs_t
, gpiointmask
);
2900 /* pci gpio implementation does not support interrupt mask */
2905 regoff
= OFFSETOF(extifregs_t
, gpiointmask
);
2909 return (sb_corereg(sbh
, si
->gpioidx
, regoff
, mask
, val
));
2912 /* assign the gpio to an led */
2913 uint32
sb_gpioled(sb_t
* sbh
, uint32 mask
, uint32 val
)
2918 if (si
->sb
.ccrev
< 16)
2921 /* gpio led powersave reg */
2923 (sbh
, SB_CC_IDX
, OFFSETOF(chipcregs_t
, gpiotimeroutmask
), mask
,
2927 /* mask&set gpio timer val */
2928 uint32
sb_gpiotimerval(sb_t
* sbh
, uint32 mask
, uint32 gpiotimerval
)
2933 if (si
->sb
.ccrev
< 16)
2936 return (sb_corereg(sbh
, SB_CC_IDX
,
2937 OFFSETOF(chipcregs_t
, gpiotimerval
), mask
,
2941 uint32
sb_gpiopull(sb_t
* sbh
, bool updown
, uint32 mask
, uint32 val
)
2947 if (si
->sb
.ccrev
< 20)
2951 (updown
? OFFSETOF(chipcregs_t
, gpiopulldown
) :
2952 OFFSETOF(chipcregs_t
, gpiopullup
));
2953 return (sb_corereg(sbh
, SB_CC_IDX
, offs
, mask
, val
));
2956 uint32
sb_gpioevent(sb_t
* sbh
, uint regtype
, uint32 mask
, uint32 val
)
2962 if (si
->sb
.ccrev
< 11)
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
);
2974 return (sb_corereg(sbh
, SB_CC_IDX
, offs
, mask
, val
));
2977 void *BCMINITFN(sb_gpio_handler_register
) (sb_t
* sbh
, uint32 event
,
2978 bool level
, gpio_handler_t cb
,
2987 if (si
->sb
.ccrev
< 11)
2990 if ((gi
= MALLOC(si
->osh
, sizeof(gpioh_item_t
))) == NULL
)
2993 bzero(gi
, sizeof(gpioh_item_t
));
2999 gi
->next
= si
->gpioh_head
;
3000 si
->gpioh_head
= gi
;
3002 return (void *)(gi
);
3005 void BCMINITFN(sb_gpio_handler_unregister
) (sb_t
* sbh
, void *gpioh
) {
3007 gpioh_item_t
*p
, *n
;
3010 if (si
->sb
.ccrev
< 11)
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
));
3022 if ((void *)n
== gpioh
) {
3024 MFREE(si
->osh
, gpioh
, sizeof(gpioh_item_t
));
3032 ASSERT(0); /* Not found in list */
3035 void sb_gpio_handler_process(sb_t
* sbh
)
3040 uint32 level
= sb_gpioin(sbh
);
3041 uint32 edge
= sb_gpioevent(sbh
, GPIO_REGEVT
, 0, 0);
3044 for (h
= si
->gpioh_head
; h
!= NULL
; h
= h
->next
) {
3046 status
= (h
->level
? level
: edge
);
3048 if (status
& h
->event
)
3049 h
->handler(status
, h
->arg
);
3053 sb_gpioevent(sbh
, GPIO_REGEVT
, edge
, edge
); /* clear edge-trigger status */
3056 uint32
sb_gpio_int_enable(sb_t
* sbh
, bool enable
)
3062 if (si
->sb
.ccrev
< 11)
3065 offs
= OFFSETOF(chipcregs_t
, intmask
);
3067 (sbh
, SB_CC_IDX
, offs
, CI_GPIO
, (enable
? CI_GPIO
: 0)));
3071 void sb_dump(sb_t
* sbh
, struct bcmstrbuf
*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
);
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
);
3088 bcm_bprintf(b
, "forceHT %d ASPM overflowPR42780 %d pcie_polarity %d\n",
3089 si
->sb
.pr32414
, si
->sb
.pr42780
, si
->pcie_polarity
);
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");
3097 /* print interesting sbconfig registers */
3098 void sb_dumpregs(sb_t
* sbh
, struct bcmstrbuf
*b
)
3103 uint curidx
, i
, intr_val
= 0;
3106 origidx
= si
->curidx
;
3108 INTR_OFF(si
, intr_val
);
3109 curidx
= si
->curidx
;
3111 for (i
= 0; i
< si
->numcores
; i
++) {
3112 sb
= REGS2SB(sb_setcoreidx(sbh
, i
));
3114 bcm_bprintf(b
, "core 0x%x: \n", si
->coreid
[i
]);
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
,
3121 R_SBREG(si
, &sb
->sbidhigh
), R_SBREG(si
,
3123 R_SBREG(si
, &sb
->sbimconfiglow
), R_SBREG(si
,
3128 sb_setcoreidx(sbh
, origidx
);
3129 INTR_RESTORE(si
, intr_val
);
3132 void sb_view(sb_t
* sbh
)
3138 sb
= REGS2SB(si
->curmap
);
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)));
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
)));
3158 void sb_viewall(sb_t
* sbh
)
3165 curidx
= si
->curidx
;
3167 for (i
= 0; i
< si
->numcores
; i
++) {
3168 INTR_OFF(si
, intr_val
);
3169 sb_setcoreidx(sbh
, i
);
3171 INTR_RESTORE(si
, intr_val
);
3174 sb_setcoreidx(sbh
, curidx
);
3178 /* return the slow clock source - LPO, XTAL, or PCI */
3179 static uint
sb_slowclk_src(sb_info_t
* si
)
3183 ASSERT(sb_coreid(&si
->sb
) == SB_CC
);
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
);
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
);
3199 /* return the ILP (slowclock) min or max frequency */
3200 static uint
sb_slowclk_freq(sb_info_t
* si
, bool max_freq
)
3206 ASSERT(sb_coreid(&si
->sb
) == SB_CC
);
3208 cc
= (chipcregs_t
*) sb_setcoreidx(&si
->sb
, si
->curidx
);
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
);
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));
3219 return (max_freq
? (XTALMAXFREQ
/ 32)
3220 : (XTALMINFREQ
/ 32));
3221 } else if (si
->sb
.ccrev
< 10) {
3224 (((R_REG(si
->osh
, &cc
->slow_clk_ctl
) & SCC_CD_MASK
) >>
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
));
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
));
3246 static void BCMINITFN(sb_clkctl_setdelay
) (sb_info_t
* si
, void *chipcregs
) {
3248 uint slowmaxfreq
, pll_delay
, slowclk
;
3249 uint pll_on_delay
, fref_sel_delay
;
3251 pll_delay
= PLL_DELAY
;
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.
3257 slowclk
= sb_slowclk_src(si
);
3258 if (slowclk
!= SCC_SS_XTAL
)
3259 pll_delay
+= XTAL_ON_DELAY
;
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
);
3264 pll_on_delay
= ((slowmaxfreq
* pll_delay
) + 999999) / 1000000;
3265 fref_sel_delay
= ((slowmaxfreq
* FREF_DELAY
) + 999999) / 1000000;
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
);
3272 /* initialize power control delay registers */
3273 void BCMINITFN(sb_clkctl_init
) (sb_t
* sbh
) {
3280 origidx
= si
->curidx
;
3282 if ((cc
= (chipcregs_t
*) sb_setcore(sbh
, SB_CC
, 0)) == NULL
)
3285 if ((si
->sb
.chip
== BCM4321_CHIP_ID
) && (si
->sb
.chiprev
< 2))
3286 W_REG(si
->osh
, &cc
->chipcontrol
,
3288 0) ? CHIPCTRL_4321A0_DEFAULT
: CHIPCTRL_4321A1_DEFAULT
);
3290 if (!(R_REG(si
->osh
, &cc
->capabilities
) & CC_CAP_PWR_CTL
))
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
));
3298 sb_clkctl_setdelay(si
, (void *)(uintptr
) cc
);
3301 sb_setcoreidx(sbh
, origidx
);
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
) {
3315 origidx
= si
->curidx
;
3317 INTR_OFF(si
, intr_val
);
3319 if ((cc
= (chipcregs_t
*) sb_setcore(sbh
, SB_CC
, 0)) == NULL
)
3322 if (sbh
->cccaps
& CC_CAP_PMU
) {
3323 fpdelay
= sb_pmu_fast_pwrup_delay(sbh
, si
->osh
);
3327 if (!(sbh
->cccaps
& CC_CAP_PWR_CTL
))
3330 slowminfreq
= sb_slowclk_freq(si
, FALSE
);
3331 fpdelay
= (((R_REG(si
->osh
, &cc
->pll_on_delay
) + 2) * 1000000) +
3332 (slowminfreq
- 1)) / slowminfreq
;
3335 sb_setcoreidx(sbh
, origidx
);
3336 INTR_RESTORE(si
, intr_val
);
3340 /* turn primary xtal and/or pll off/on */
3341 int sb_clkctl_xtal(sb_t
* sbh
, uint what
, bool on
)
3344 uint32 in
, out
, outen
;
3348 switch (BUSTYPE(si
->sb
.bustype
)) {
3355 /* pcie core doesn't have any mapping to control the xtal pu */
3359 in
= OSL_PCI_READ_CONFIG(si
->osh
, PCI_GPIO_IN
, sizeof(uint32
));
3361 OSL_PCI_READ_CONFIG(si
->osh
, PCI_GPIO_OUT
, sizeof(uint32
));
3363 OSL_PCI_READ_CONFIG(si
->osh
, PCI_GPIO_OUTEN
,
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.
3371 if (on
&& (in
& PCI_CFG_GPIO_XTAL
))
3375 outen
|= PCI_CFG_GPIO_XTAL
;
3377 outen
|= PCI_CFG_GPIO_PLL
;
3380 /* turn primary xtal on */
3382 out
|= PCI_CFG_GPIO_XTAL
;
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
);
3394 out
&= ~PCI_CFG_GPIO_PLL
;
3395 OSL_PCI_WRITE_CONFIG(si
->osh
, PCI_GPIO_OUT
,
3396 sizeof(uint32
), out
);
3401 out
&= ~PCI_CFG_GPIO_XTAL
;
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
);
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
)
3429 /* chipcommon cores prior to rev6 don't support dynamic clock control */
3430 if (si
->sb
.ccrev
< 6)
3433 /* Chips with ccrev 10 are EOL and they don't have SYCC_HR which we use below */
3434 ASSERT(si
->sb
.ccrev
!= 10);
3436 INTR_OFF(si
, intr_val
);
3438 origidx
= si
->curidx
;
3440 if (sb_setcore(sbh
, SB_MIPS33
, 0) && (sb_corerev(&si
->sb
) <= 7) &&
3441 (BUSTYPE(si
->sb
.bustype
) == SB_BUS
) && (si
->sb
.ccrev
>= 10))
3444 if (FORCEHT_WAR32414(si
))
3447 cc
= (chipcregs_t
*) sb_setcore(sbh
, SB_CC
, 0);
3450 if (!(R_REG(si
->osh
, &cc
->capabilities
) & CC_CAP_PWR_CTL
)
3451 && (si
->sb
.ccrev
< 20))
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
);
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
);
3465 OR_REG(si
->osh
, &cc
->clk_ctl_st
, CCS_FORCEHT
);
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
);
3474 OSL_DELAY(PLL_DELAY
);
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
)
3484 W_REG(si
->osh
, &cc
->slow_clk_ctl
, scc
);
3486 /* for dynamic control, we have to release our xtal_pu "force on" */
3488 sb_clkctl_xtal(&si
->sb
, XTAL
, OFF
);
3489 } else if (si
->sb
.ccrev
< 20) {
3491 AND_REG(si
->osh
, &cc
->system_clk_ctl
, ~SYCC_HR
);
3493 AND_REG(si
->osh
, &cc
->clk_ctl_st
, ~CCS_FORCEHT
);
3502 sb_setcoreidx(sbh
, origidx
);
3503 INTR_RESTORE(si
, intr_val
);
3504 return (mode
== CLK_FAST
);
3507 /* register driver interrupt disabling and restoring callback functions */
3509 sb_register_intr_callback(sb_t
* sbh
, void *intrsoff_fn
,
3510 void *intrsrestore_fn
, void *intrsenabled_fn
,
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.)
3523 si
->dev_coreid
= si
->coreid
[si
->curidx
];
3526 void sb_deregister_intr_callback(sb_t
* sbh
)
3531 si
->intrsoff_fn
= NULL
;
3535 /* dump dynamic clock control related registers */
3536 void sb_clkctl_dump(sb_t
* sbh
, struct bcmstrbuf
*b
)
3545 INTR_OFF(si
, intr_val
);
3547 origidx
= si
->curidx
;
3549 if ((cc
= (chipcregs_t
*) sb_setcore(sbh
, SB_CC
, 0)) == NULL
) {
3550 INTR_RESTORE(si
, intr_val
);
3554 if (!(R_REG(si
->osh
, &cc
->capabilities
) & CC_CAP_PWR_CTL
))
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
);
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
,
3569 OSL_PCI_READ_CONFIG(si
->osh
, PCI_GPIO_OUTEN
,
3571 bcm_bprintf(b
, "\n");
3574 sb_setcoreidx(sbh
, origidx
);
3575 INTR_RESTORE(si
, intr_val
);
3579 uint16
BCMINITFN(sb_d11_devid
) (sb_t
* sbh
) {
3580 sb_info_t
*si
= SB_INFO(sbh
);
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
;
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) ;
3596 * no longer support wl0id, but keep the code
3597 * here for backward compatibility.
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
;
3605 device
= BCM4306_D11DUAL_ID
;
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
);
3624 /* Verify whether the function exists for the core */
3625 if (func
>= (uint
) (core
== SB_USB20H
? 2 : 1))
3628 /* Known vendor translations */
3629 switch (sb_corevendor(sbh
)) {
3631 vendor
= VENDOR_BROADCOM
;
3637 /* Determine class based on known core codes */
3640 class = PCI_CLASS_NET
;
3641 subclass
= PCI_NET_ETHER
;
3642 device
= BCM47XX_ILINE_ID
;
3645 class = PCI_CLASS_NET
;
3646 subclass
= PCI_NET_ETHER
;
3647 device
= BCM47XX_ENET_ID
;
3650 class = PCI_CLASS_NET
;
3651 subclass
= PCI_NET_ETHER
;
3652 device
= BCM47XX_GIGETH_ID
;
3656 class = PCI_CLASS_MEMORY
;
3657 subclass
= PCI_MEMORY_RAM
;
3658 device
= (uint16
) core
;
3662 class = PCI_CLASS_BRIDGE
;
3663 subclass
= PCI_BRIDGE_PCI
;
3664 device
= (uint16
) core
;
3665 header
= PCI_HEADER_BRIDGE
;
3669 class = PCI_CLASS_CPU
;
3670 subclass
= PCI_CPU_MIPS
;
3671 device
= (uint16
) core
;
3674 class = PCI_CLASS_COMM
;
3675 subclass
= PCI_COMM_MODEM
;
3676 device
= BCM47XX_V90_ID
;
3679 class = PCI_CLASS_SERIAL
;
3680 subclass
= PCI_SERIAL_USB
;
3681 progif
= 0x10; /* OHCI */
3682 device
= BCM47XX_USB_ID
;
3685 class = PCI_CLASS_SERIAL
;
3686 subclass
= PCI_SERIAL_USB
;
3687 progif
= 0x10; /* OHCI */
3688 device
= BCM47XX_USBH_ID
;
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 */
3698 class = PCI_CLASS_CRYPT
;
3699 subclass
= PCI_CRYPT_NETWORK
;
3700 device
= BCM47XX_IPSEC_ID
;
3703 class = PCI_CLASS_NET
;
3704 subclass
= PCI_NET_OTHER
;
3705 device
= BCM47XX_ROBO_ID
;
3709 class = PCI_CLASS_MEMORY
;
3710 subclass
= PCI_MEMORY_FLASH
;
3711 device
= (uint16
) core
;
3714 class = PCI_CLASS_XOR
;
3715 subclass
= PCI_XOR_QDMA
;
3716 device
= BCM47XX_SATAXOR_ID
;
3719 class = PCI_CLASS_DASDI
;
3720 subclass
= PCI_DASDI_IDE
;
3721 device
= BCM47XX_ATA100_ID
;
3724 class = PCI_CLASS_SERIAL
;
3725 subclass
= PCI_SERIAL_USB
;
3726 device
= BCM47XX_USBD_ID
;
3729 class = PCI_CLASS_SERIAL
;
3730 subclass
= PCI_SERIAL_USB
;
3731 device
= BCM47XX_USB20D_ID
;
3734 class = PCI_CLASS_NET
;
3735 subclass
= PCI_NET_OTHER
;
3736 device
= sb_d11_devid(sbh
);
3740 class = subclass
= progif
= 0xff;
3741 device
= (uint16
) core
;
3745 *pcivendor
= vendor
;
3746 *pcidevice
= device
;
3748 *pcisubclass
= subclass
;
3749 *pciprogif
= progif
;
3750 *pciheader
= header
;
3755 /* use the mdio interface to read from mdio slaves */
3757 sb_pcie_mdioread(sb_info_t
* si
, uint physmedia
, uint regaddr
, uint
* regval
)
3761 sbpcieregs_t
*pcieregs
;
3763 pcieregs
= (sbpcieregs_t
*) sb_setcoreidx(&si
->sb
, si
->sb
.buscoreidx
);
3766 /* enable mdio access to SERDES */
3767 W_REG(si
->osh
, (&pcieregs
->mdiocontrol
),
3768 MDIOCTL_PREAM_EN
| MDIOCTL_DIVISOR_VAL
);
3770 mdiodata
= MDIODATA_START
| MDIODATA_READ
|
3771 (physmedia
<< MDIODATA_DEVADDR_SHF
) |
3772 (regaddr
<< MDIODATA_REGADDR_SHF
) | MDIODATA_TA
;
3774 W_REG(si
->osh
, &pcieregs
->mdiodata
, mdiodata
);
3778 /* retry till the transaction is complete */
3780 if (R_REG(si
->osh
, &(pcieregs
->mdiocontrol
)) &
3781 MDIOCTL_ACCESS_DONE
) {
3784 (R_REG(si
->osh
, &(pcieregs
->mdiodata
)) &
3786 /* Disable mdio access to SERDES */
3787 W_REG(si
->osh
, (&pcieregs
->mdiocontrol
), 0);
3794 SB_ERROR(("sb_pcie_mdioread: timed out\n"));
3795 /* Disable mdio access to SERDES */
3796 W_REG(si
->osh
, (&pcieregs
->mdiocontrol
), 0);
3800 /* use the mdio interface to write to mdio slaves */
3802 sb_pcie_mdiowrite(sb_info_t
* si
, uint physmedia
, uint regaddr
, uint val
)
3806 sbpcieregs_t
*pcieregs
;
3808 pcieregs
= (sbpcieregs_t
*) sb_setcoreidx(&si
->sb
, si
->sb
.buscoreidx
);
3811 /* enable mdio access to SERDES */
3812 W_REG(si
->osh
, (&pcieregs
->mdiocontrol
),
3813 MDIOCTL_PREAM_EN
| MDIOCTL_DIVISOR_VAL
);
3815 mdiodata
= MDIODATA_START
| MDIODATA_WRITE
|
3816 (physmedia
<< MDIODATA_DEVADDR_SHF
) |
3817 (regaddr
<< MDIODATA_REGADDR_SHF
) | MDIODATA_TA
| val
;
3819 W_REG(si
->osh
, (&pcieregs
->mdiodata
), mdiodata
);
3823 /* retry till the transaction is complete */
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);
3835 SB_ERROR(("sb_pcie_mdiowrite: timed out\n"));
3836 /* Disable mdio access to SERDES */
3837 W_REG(si
->osh
, (&pcieregs
->mdiocontrol
), 0);
3842 /* indirect way to read pcie config regs */
3843 uint
sb_pcie_readreg(void *sb
, void *arg1
, uint offset
)
3847 uint retval
= 0xFFFFFFFF;
3848 sbpcieregs_t
*pcieregs
;
3855 pcieregs
= (sbpcieregs_t
*) sb_setcore(sbh
, SB_PCIE
, 0);
3858 addrtype
= (uint
) ((uintptr
) arg1
);
3860 case PCIE_CONFIGREGS
:
3861 W_REG(si
->osh
, (&pcieregs
->configaddr
), offset
);
3862 retval
= R_REG(si
->osh
, &(pcieregs
->configdata
));
3865 W_REG(si
->osh
, &(pcieregs
->pcieindaddr
), offset
);
3866 retval
= R_REG(si
->osh
, &(pcieregs
->pcieinddata
));
3875 /* indirect way to write pcie config/mdio/pciecore regs */
3876 uint
sb_pcie_writereg(sb_t
* sbh
, void *arg1
, uint offset
, uint val
)
3879 sbpcieregs_t
*pcieregs
;
3885 pcieregs
= (sbpcieregs_t
*) sb_setcore(sbh
, SB_PCIE
, 0);
3888 addrtype
= (uint
) ((uintptr
) arg1
);
3891 case PCIE_CONFIGREGS
:
3892 W_REG(si
->osh
, (&pcieregs
->configaddr
), offset
);
3893 W_REG(si
->osh
, (&pcieregs
->configdata
), val
);
3896 W_REG(si
->osh
, (&pcieregs
->pcieindaddr
), offset
);
3897 W_REG(si
->osh
, (&pcieregs
->pcieinddata
), val
);
3906 /* Build device path. Support SB, PCI, and JTAG for now. */
3907 int BCMINITFN(sb_devpath
) (sb_t
* sbh
, char *path
, int size
) {
3910 ASSERT(size
>= SB_DEVPATH_BUFSZ
);
3912 if (!path
|| size
<= 0)
3915 switch (BUSTYPE((SB_INFO(sbh
))->sb
.bustype
)) {
3918 slen
= snprintf(path
, (size_t) size
, "sb/%u/", sb_coreidx(sbh
));
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
));
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/");
3937 if (slen
< 0 || slen
>= size
) {
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];
3949 sb_devpathvar(sbh
, varname
, sizeof(varname
), name
);
3951 return (getvar(NULL
, varname
));
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];
3958 sb_devpathvar(sbh
, varname
, sizeof(varname
), name
);
3960 return (getintvar(NULL
, varname
));
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'.
3968 static char *BCMINITFN(sb_devpathvar
) (sb_t
* sbh
, char *var
, int len
,
3972 if (!var
|| len
<= 0)
3975 if (sb_devpath(sbh
, var
, len
) == 0) {
3976 path_len
= strlen(var
);
3978 if (strlen(name
) + 1 > (uint
) (len
- path_len
))
3981 strncpy(var
+ path_len
, name
, len
- path_len
- 1);
3988 * Fixup SROMless PCI device's configuration.
3989 * The current core may be changed upon return.
3991 static int sb_pci_fixcfg(sb_info_t
* si
)
3993 uint origidx
, pciidx
;
3994 sbpciregs_t
*pciregs
;
3995 sbpcieregs_t
*pcieregs
= NULL
;
3996 uint16 val16
, *reg16
;
3999 ASSERT(BUSTYPE(si
->sb
.bustype
) == PCI_BUS
);
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
);
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);
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);
4013 reg16
= &pciregs
->sprom
[SRSH_PI_OFFSET
];
4018 pciidx
= sb_coreidx(&si
->sb
);
4019 val16
= R_REG(si
->osh
, reg16
);
4020 if (((val16
& SRSH_PI_MASK
) >> SRSH_PI_SHIFT
) != (uint16
) pciidx
) {
4022 (uint16
) (pciidx
<< SRSH_PI_SHIFT
) | (val16
&
4024 W_REG(si
->osh
, reg16
, val16
);
4027 if (PCIE_ASPMWARS(si
)) {
4028 w
= sb_pcie_readreg((void *)(uintptr
) & si
->sb
,
4029 (void *)PCIE_PCIEREGS
, PCIE_PLP_STATUSREG
);
4031 /* Detect the current polarity at attach and force that polarity and
4032 * disable changing the polarity
4034 if ((w
& PCIE_PLP_POLARITYINV_STAT
) == 0) {
4035 si
->pcie_polarity
= (SERDES_RX_CTRL_FORCE
);
4037 si
->pcie_polarity
= (SERDES_RX_CTRL_FORCE
|
4038 SERDES_RX_CTRL_POLARITY
);
4041 w
= OSL_PCI_READ_CONFIG(si
->osh
, si
->pciecap_lcreg_offset
,
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
));
4051 sb_war43448(&si
->sb
);
4053 sb_war42767(&si
->sb
);
4057 /* restore the original index */
4058 sb_setcoreidx(&si
->sb
, origidx
);
4063 /* Return ADDR64 capability of the backplane */
4064 bool sb_backplane64(sb_t
* sbh
)
4069 return ((si
->sb
.cccaps
& CC_CAP_BKPLN64
) != 0);
4072 void sb_btcgpiowar(sb_t
* sbh
)
4080 /* Make sure that there is ChipCommon core present &&
4081 * UART_TX is strapped to 1
4083 if (!(si
->sb
.cccaps
& CC_CAP_UARTGPIO
))
4086 /* sb_corereg cannot be used as we have to guarantee 8-bit read/writes */
4087 INTR_OFF(si
, intr_val
);
4089 origidx
= sb_coreidx(sbh
);
4091 cc
= (chipcregs_t
*) sb_setcore(sbh
, SB_CC
, 0);
4094 W_REG(si
->osh
, &cc
->uart0mcr
, R_REG(si
->osh
, &cc
->uart0mcr
) | 0x04);
4096 /* restore the original index */
4097 sb_setcoreidx(sbh
, origidx
);
4099 INTR_RESTORE(si
, intr_val
);
4102 /* check if the device is removed */
4103 bool sb_deviceremoved(sb_t
* sbh
)
4110 switch (BUSTYPE(si
->sb
.bustype
)) {
4113 w
= OSL_PCI_READ_CONFIG(si
->osh
, PCI_CFG_VID
, sizeof(uint32
));
4114 if ((w
& 0xFFFF) != VENDOR_BROADCOM
)
4125 /* Return the RAM size of the SOCRAM core */
4126 uint32
BCMINITFN(sb_socram_size
) (sb_t
* sbh
) {
4131 sbsocramregs_t
*regs
;
4140 /* Block ints and save current core */
4141 INTR_OFF(si
, intr_val
);
4142 origidx
= sb_coreidx(sbh
);
4144 /* Switch to SOCRAM core */
4145 if (!(regs
= sb_setcore(sbh
, SB_SOCRAM
, 0)))
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
, ®s
->coreinfo
);
4154 /* Calculate size from coreinfo based on rev */
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
;
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
;
4166 memsize
= nb
* (1 << (bsz
+ SR_BSZ_BASE
));
4168 memsize
+= (1 << ((lss
- 1) + SR_BSZ_BASE
));
4170 /* Return to previous state and core */
4172 sb_core_disable(sbh
, 0);
4173 sb_setcoreidx(sbh
, origidx
);
4176 INTR_RESTORE(si
, intr_val
);