2 * Misc utility routines for accessing chip-specific features
3 * of the SiliconBackplane-based Broadcom chips.
5 * Copyright 2004, 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.
29 #define SB_ERROR(args)
31 typedef uint32 (*sb_intrsoff_t)(void *intr_arg);
32 typedef void (*sb_intrsrestore_t)(void *intr_arg, uint32 arg);
33 typedef bool (*sb_intrsenabled_t)(void *intr_arg);
35 /* misc sb info needed by some of the routines */
36 typedef struct sb_info {
37 uint chip; /* chip number */
38 uint chiprev; /* chip revision */
39 uint chippkg; /* chip package option */
40 uint boardtype; /* board type */
41 uint boardvendor; /* board vendor id */
42 uint bus; /* what bus type we are going through */
44 void *osh; /* osl os handle */
45 void *sdh; /* bcmsdh handle */
47 void *curmap; /* current regs va */
48 void *regs[SB_MAXCORES]; /* other regs va */
50 uint curidx; /* current core index */
51 uint dev_coreid; /* the core provides driver functions */
52 uint pciidx; /* pci core index */
53 uint pcirev; /* pci core rev */
55 uint pcmciaidx; /* pcmcia core index */
56 uint pcmciarev; /* pcmcia core rev */
57 bool memseg; /* flag to toggle MEM_SEG register */
59 uint ccrev; /* chipc core rev */
61 uint gpioidx; /* gpio control core index */
62 uint gpioid; /* gpio control coretype */
64 uint numcores; /* # discovered cores */
65 uint coreid[SB_MAXCORES]; /* id of each core */
67 void *intr_arg; /* interrupt callback function arg */
68 sb_intrsoff_t intrsoff_fn; /* function turns chip interrupts off */
69 sb_intrsrestore_t intrsrestore_fn; /* function restore chip interrupts */
70 sb_intrsenabled_t intrsenabled_fn; /* function to check if chip interrupts are enabled */
73 /* local prototypes */
74 static void* sb_doattach(sb_info_t *si, uint devid, void *osh, void *regs, uint bustype, void *sdh, char **vars, int *varsz);
75 static void sb_scan(sb_info_t *si);
76 static uint sb_corereg(void *sbh, uint coreidx, uint regoff, uint mask, uint val);
77 static uint _sb_coreidx(void *sbh);
78 static uint sb_findcoreidx(void *sbh, uint coreid, uint coreunit);
79 static uint sb_pcidev2chip(uint pcidev);
80 static uint sb_chip2numcores(uint chip);
82 #define SB_INFO(sbh) (sb_info_t*)sbh
83 #define SET_SBREG(sbh, r, mask, val) W_SBREG((sbh), (r), ((R_SBREG((sbh), (r)) & ~(mask)) | (val)))
84 #define GOODCOREADDR(x) (((x) >= SB_ENUM_BASE) && ((x) <= SB_ENUM_LIM) && ISALIGNED((x), SB_CORE_SIZE))
85 #define GOODREGS(regs) (regs && ISALIGNED(regs, SB_CORE_SIZE))
86 #define REGS2SB(va) (sbconfig_t*) ((uint)(va) + SBCONFIGOFF)
87 #define GOODIDX(idx) (((uint)idx) < SB_MAXCORES)
88 #define BADIDX (SB_MAXCORES+1)
90 #define R_SBREG(sbh, sbr) sb_read_sbreg((sbh), (sbr))
91 #define W_SBREG(sbh, sbr, v) sb_write_sbreg((sbh), (sbr), (v))
92 #define AND_SBREG(sbh, sbr, v) W_SBREG((sbh), (sbr), (R_SBREG((sbh), (sbr)) & (v)))
93 #define OR_SBREG(sbh, sbr, v) W_SBREG((sbh), (sbr), (R_SBREG((sbh), (sbr)) | (v)))
96 * Macros to disable/restore function core(D11, ENET, ILINE20, etc) interrupts before/
97 * after core switching to avoid invalid register accesss inside ISR.
99 #define INTR_OFF(si, intr_val) \
100 if ((si)->intrsoff_fn && (si)->coreid[(si)->curidx] == (si)->dev_coreid) { \
101 intr_val = (*(si)->intrsoff_fn)((si)->intr_arg); }
102 #define INTR_RESTORE(si, intr_val) \
103 if ((si)->intrsrestore_fn && (si)->coreid[(si)->curidx] == (si)->dev_coreid) { \
104 (*(si)->intrsrestore_fn)((si)->intr_arg, intr_val); }
106 /* power control defines */
107 #define LPOMINFREQ 25000 /* low power oscillator min */
108 #define LPOMAXFREQ 43000 /* low power oscillator max */
109 #define XTALMINFREQ 19800000 /* 20mhz - 1% */
110 #define XTALMAXFREQ 20200000 /* 20mhz + 1% */
111 #define PCIMINFREQ 25000000 /* 25mhz */
112 #define PCIMAXFREQ 34000000 /* 33mhz + fudge */
113 #define SCC_DEF_DIV 0 /* default slow clock divider */
115 #define XTAL_ON_DELAY 1000 /* Xtal power on delay in us */
117 #define SCC_LOW2FAST_LIMIT 5000 /* turn on fast clock time, in unit of ms */
121 sb_read_sbreg(void *sbh, volatile uint32 *sbr)
125 uint32 val, intr_val = 0;
130 * compact flash only has 11 bits address, while we needs 12 bits address.
131 * MEM_SEG will be OR'd with other 11 bits address in hardware,
132 * so we program MEM_SEG with 12th bit when necessary(access sb regsiters).
133 * For normal PCMCIA bus(CFTable_regwinsz > 2k), do nothing special
136 INTR_OFF(si, intr_val);
138 OSL_PCMCIA_WRITE_ATTR(si->osh, MEM_SEG, &tmp, 1);
139 sbr = (uint32 *) (((uint32) sbr) & ~(1 << 11)); /* mask out bit 11*/
146 OSL_PCMCIA_WRITE_ATTR(si->osh, MEM_SEG, &tmp, 1);
147 INTR_RESTORE(si, intr_val);
154 sb_write_sbreg(void *sbh, volatile uint32 *sbr, uint32 v)
158 volatile uint32 dummy;
164 * compact flash only has 11 bits address, while we needs 12 bits address.
165 * MEM_SEG will be OR'd with other 11 bits address in hardware,
166 * so we program MEM_SEG with 12th bit when necessary(access sb regsiters).
167 * For normal PCMCIA bus(CFTable_regwinsz > 2k), do nothing special
170 INTR_OFF(si, intr_val);
172 OSL_PCMCIA_WRITE_ATTR(si->osh, MEM_SEG, &tmp, 1);
173 sbr = (uint32 *) (((uint32) sbr) & ~(1 << 11)); /* mask out bit 11*/
176 if (si->bus == PCMCIA_BUS) {
179 W_REG((volatile uint16 *)((uint32)sbr + 2), (uint16)((v >> 16) & 0xffff));
181 W_REG((volatile uint16 *)sbr, (uint16)(v & 0xffff));
184 W_REG((volatile uint16 *)sbr, (uint16)(v & 0xffff));
186 W_REG((volatile uint16 *)((uint32)sbr + 2), (uint16)((v >> 16) & 0xffff));
193 OSL_PCMCIA_WRITE_ATTR(si->osh, MEM_SEG, &tmp, 1);
194 INTR_RESTORE(si, intr_val);
199 * Allocate a sb handle.
200 * devid - pci device id (used to determine chip#)
201 * osh - opaque OS handle
202 * regs - virtual address of initial core registers
203 * bustype - pci/pcmcia/sb/sdio/etc
204 * vars - pointer to a pointer area for "environment" variables
205 * varsz - pointer to int to return the size of the vars
208 sb_attach(uint devid, void *osh, void *regs, uint bustype, void *sdh, char **vars, int *varsz)
212 /* alloc sb_info_t */
213 if ((si = MALLOC(sizeof (sb_info_t))) == NULL) {
214 SB_ERROR(("sb_attach: malloc failed!\n"));
218 return (sb_doattach(si, devid, osh, regs, bustype, sdh, vars, varsz));
221 /* global kernel resource */
222 static sb_info_t ksi;
224 /* generic kernel variant of sb_attach() */
232 if (ksi.curmap == NULL) {
235 regs = (uint32 *)REG_MAP(SB_ENUM_BASE, SB_CORE_SIZE);
236 cid = R_REG((uint32 *)regs);
237 if (((cid & (CID_ID_MASK | CID_PKG_MASK)) == 0x00104712) &&
238 ((cid & CID_REV_MASK) <= 0x00020000)) {
241 scc = (uint32 *)((uint32)regs + OFFSETOF(chipcregs_t, slow_clk_ctl));
243 SB_ERROR((" initial scc = 0x%x\n", val));
248 sb_doattach(&ksi, BCM4710_DEVICE_ID, NULL, (void*)regs,
249 SB_BUS, NULL, &unused, &varsz);
256 sb_doattach(sb_info_t *si, uint devid, void *osh, void *regs, uint bustype, void *sdh, char **vars, int *varsz)
262 ASSERT(GOODREGS(regs));
264 bzero((uchar*)si, sizeof (sb_info_t));
266 si->pciidx = si->gpioidx = BADIDX;
272 /* check to see if we are a sb core mimic'ing a pci core */
273 if (bustype == PCI_BUS) {
274 if (OSL_PCI_READ_CONFIG(osh, PCI_SPROM_CONTROL, sizeof (uint32)) == 0xffffffff)
282 if (si->bus == PCMCIA_BUS)
283 /* need to set memseg flag for CF card first before any sb registers access,
284 * such as the access inside sb_scan. the card type is detected and memseg
285 * flag is reassigned later after srom_var_init. there should be no effect
286 * for PCMCIA cards even though the memseg flag is set
290 /* kludge to enable the clock on the 4306 which lacks a slowclock */
291 if (si->bus == PCI_BUS)
292 sb_pwrctl_xtal((void*)si, XTAL|PLL, ON);
294 /* initialize current core index value */
295 si->curidx = _sb_coreidx((void*)si);
296 if (si->curidx == BADIDX)
299 /* keep and reuse the initial register mapping */
300 origidx = si->curidx;
301 if (si->bus == SB_BUS)
302 si->regs[origidx] = regs;
304 /* is core-0 a chipcommon core? */
306 cc = (chipcregs_t*) sb_setcoreidx((void*)si, 0);
307 if (sb_coreid((void*)si) != SB_CC)
310 /* determine chip id and rev */
312 /* chip common core found! */
313 si->chip = R_REG(&cc->chipid) & CID_ID_MASK;
314 si->chiprev = (R_REG(&cc->chipid) & CID_REV_MASK) >> CID_REV_SHIFT;
315 si->chippkg = (R_REG(&cc->chipid) & CID_PKG_MASK) >> CID_PKG_SHIFT;
317 /* The only pcmcia chip without a chipcommon core is a 4301 */
318 if (si->bus == PCMCIA_BUS)
319 devid = BCM4301_DEVICE_ID;
321 /* no chip common core -- must convert device id to chip id */
322 if ((si->chip = sb_pcidev2chip(devid)) == 0) {
323 SB_ERROR(("sb_attach: unrecognized device id 0x%04x\n", devid));
328 /* get chipcommon rev */
329 si->ccrev = cc? sb_corerev((void*)si) : 0;
331 /* determine numcores */
332 if ((si->ccrev == 4) || (si->ccrev >= 6))
333 si->numcores = (R_REG(&cc->chipid) & CID_CC_MASK) >> CID_CC_SHIFT;
335 si->numcores = sb_chip2numcores(si->chip);
337 /* return to original core */
338 sb_setcoreidx((void*)si, origidx);
346 /* initialize the vars after sb_scan so that the core rev. information
347 * collected by sb_scan is available for the srom_var_init.
349 if (srom_var_init(si, si->bus, si->curmap, osh, vars, varsz)) {
350 SB_ERROR(("sb_attach: srom_var_init failed\n"));
356 * The chip revision number is hardwired into all
357 * of the pci function config rev fields and is
358 * independent from the individual core revision numbers.
359 * For example, the "A0" silicon of each chip is chip rev 0.
360 * For PCMCIA we get it from the CIS instead.
362 if (si->bus == PCMCIA_BUS) {
364 si->chiprev = getintvar(*vars, "chiprev");
365 } else if (si->bus == PCI_BUS) {
366 w = OSL_PCI_READ_CONFIG(osh, PCI_CFG_REV, sizeof (uint32));
367 si->chiprev = w & 0xff;
372 if (si->bus == PCMCIA_BUS) {
373 w = getintvar(*vars, "regwindowsz");
374 si->memseg = (w <= CFTABLE_REGWIN_2K) ? TRUE : FALSE;
377 /* pci core is required */
378 if (!GOODIDX(si->pciidx)) {
379 SB_ERROR(("sb_attach: pci core not found\n"));
383 /* gpio control core is required */
384 if (!GOODIDX(si->gpioidx)) {
385 SB_ERROR(("sb_attach: gpio control core not found\n"));
389 /* get boardtype and boardrev */
392 /* do a pci config read to get subsystem id and subvendor id */
393 w = OSL_PCI_READ_CONFIG(osh, PCI_CFG_SVID, sizeof (uint32));
394 si->boardvendor = w & 0xffff;
395 si->boardtype = (w >> 16) & 0xffff;
400 si->boardvendor = getintvar(*vars, "manfid");
401 si->boardtype = getintvar(*vars, "prodid");
405 si->boardvendor = VENDOR_BROADCOM;
406 si->boardtype = 0xffff;
410 if (si->boardtype == 0) {
411 SB_ERROR(("sb_attach: unknown board type\n"));
412 ASSERT(si->boardtype);
415 /* clear any previous epidiag-induced target abort */
416 sb_taclear((void*)si);
421 MFREE(si, sizeof (sb_info_t));
432 sb = REGS2SB(si->curmap);
434 return ((R_SBREG(sbh, &(sb)->sbidhigh) & SBIDH_CC_MASK) >> SBIDH_CC_SHIFT);
438 sb_coreidx(void *sbh)
446 /* return current index of core */
448 _sb_coreidx(void *sbh)
459 sb = REGS2SB(si->curmap);
460 sbaddr = sb_base(R_SBREG(sbh, &sb->sbadmatch0));
464 sbaddr = OSL_PCI_READ_CONFIG(si->osh, PCI_BAR0_WIN, sizeof (uint32));
470 OSL_PCMCIA_READ_ATTR(si->osh, PCMCIA_ADDR0, &tmp, 1);
471 sbaddr = (uint)tmp << 12;
472 OSL_PCMCIA_READ_ATTR(si->osh, PCMCIA_ADDR1, &tmp, 1);
473 sbaddr |= (uint)tmp << 16;
474 OSL_PCMCIA_READ_ATTR(si->osh, PCMCIA_ADDR2, &tmp, 1);
475 sbaddr |= (uint)tmp << 24;
482 if (!GOODCOREADDR(sbaddr))
485 return ((sbaddr - SB_ENUM_BASE) / SB_CORE_SIZE);
489 sb_corevendor(void *sbh)
495 sb = REGS2SB(si->curmap);
497 return ((R_SBREG(sbh, &(sb)->sbidhigh) & SBIDH_VC_MASK) >> SBIDH_VC_SHIFT);
501 sb_corerev(void *sbh)
507 sb = REGS2SB(si->curmap);
509 return (R_SBREG(sbh, &(sb)->sbidhigh) & SBIDH_RC_MASK);
512 #define SBTML_ALLOW (SBTML_PE | SBTML_FGC | SBTML_FL_MASK)
514 /* set/clear sbtmstatelow core-specific flags */
516 sb_coreflags(void *sbh, uint32 mask, uint32 val)
523 sb = REGS2SB(si->curmap);
525 ASSERT((val & ~mask) == 0);
526 ASSERT((mask & ~SBTML_ALLOW) == 0);
530 w = (R_SBREG(sbh, &sb->sbtmstatelow) & ~mask) | val;
531 W_SBREG(sbh, &sb->sbtmstatelow, w);
534 /* return the new value */
535 return (R_SBREG(sbh, &sb->sbtmstatelow) & SBTML_ALLOW);
538 /* set/clear sbtmstatehigh core-specific flags */
540 sb_coreflagshi(void *sbh, uint32 mask, uint32 val)
547 sb = REGS2SB(si->curmap);
549 ASSERT((val & ~mask) == 0);
550 ASSERT((mask & ~SBTMH_FL_MASK) == 0);
554 w = (R_SBREG(sbh, &sb->sbtmstatehigh) & ~mask) | val;
555 W_SBREG(sbh, &sb->sbtmstatehigh, w);
558 /* return the new value */
559 return (R_SBREG(sbh, &sb->sbtmstatehigh) & SBTMH_FL_MASK);
563 sb_iscoreup(void *sbh)
569 sb = REGS2SB(si->curmap);
571 return ((R_SBREG(sbh, &(sb)->sbtmstatelow) & (SBTML_RESET | SBTML_REJ | SBTML_CLK)) == SBTML_CLK);
575 * Switch to 'coreidx', issue a single arbitrary 32bit register mask&set operation,
576 * switch back to the original core, and return the new value.
579 sb_corereg(void *sbh, uint coreidx, uint regoff, uint mask, uint val)
587 ASSERT(GOODIDX(coreidx));
588 ASSERT(regoff < SB_CORE_SIZE);
589 ASSERT((val & ~mask) == 0);
593 INTR_OFF(si, intr_val);
595 /* save current core index */
596 origidx = sb_coreidx(sbh);
599 r = (uint32*) ((uint) sb_setcoreidx(sbh, coreidx) + regoff);
603 if (regoff >= SBCONFIGOFF) {
604 w = (R_SBREG(sbh, r) & ~mask) | val;
607 w = (R_REG(r) & ~mask) | val;
613 if (regoff >= SBCONFIGOFF)
618 /* restore core index */
619 if (origidx != coreidx)
620 sb_setcoreidx(sbh, origidx);
622 INTR_RESTORE(si, intr_val);
626 /* scan the sb enumerated space to identify all cores */
628 sb_scan(sb_info_t *si)
636 /* numcores should already be set */
637 ASSERT((si->numcores > 0) && (si->numcores <= SB_MAXCORES));
639 /* save current core index */
640 origidx = sb_coreidx(sbh);
642 si->pciidx = si->gpioidx = BADIDX;
644 for (i = 0; i < si->numcores; i++) {
645 sb_setcoreidx(sbh, i);
646 si->coreid[i] = sb_coreid(sbh);
648 if (si->coreid[i] == SB_PCI) {
650 si->pcirev = sb_corerev(sbh);
652 } else if (si->coreid[i] == SB_PCMCIA) {
654 si->pcmciarev = sb_corerev(sbh);
659 * Find the gpio "controlling core" type and index.
661 * - if there's a chip common core - use that
662 * - else if there's a pci core (rev >= 2) - use that
663 * - else there had better be an extif core (4710 only)
665 if (GOODIDX(sb_findcoreidx(sbh, SB_CC, 0))) {
666 si->gpioidx = sb_findcoreidx(sbh, SB_CC, 0);
668 } else if (GOODIDX(si->pciidx) && (si->pcirev >= 2)) {
669 si->gpioidx = si->pciidx;
671 } else if (sb_findcoreidx(sbh, SB_EXTIF, 0)) {
672 si->gpioidx = sb_findcoreidx(sbh, SB_EXTIF, 0);
673 si->gpioid = SB_EXTIF;
676 /* return to original core index */
677 sb_setcoreidx(sbh, origidx);
680 /* may be called with core in reset */
692 if (si->bus == SB_BUS)
693 for (idx = 0; idx < SB_MAXCORES; idx++)
695 REG_UNMAP(si->regs[idx]);
696 si->regs[idx] = NULL;
699 MFREE(si, sizeof (sb_info_t));
702 /* use pci dev id to determine chip id for chips not having a chipcommon core */
704 sb_pcidev2chip(uint pcidev)
706 if ((pcidev >= BCM4710_DEVICE_ID) && (pcidev <= BCM47XX_USB_ID))
707 return (BCM4710_DEVICE_ID);
708 if ((pcidev >= BCM4610_DEVICE_ID) && (pcidev <= BCM4610_USB_ID))
709 return (BCM4610_DEVICE_ID);
710 if ((pcidev >= BCM4402_DEVICE_ID) && (pcidev <= BCM4402_V90_ID))
711 return (BCM4402_DEVICE_ID);
712 if ((pcidev >= BCM4307_V90_ID) && (pcidev <= BCM4307_D11B_ID))
713 return (BCM4307_DEVICE_ID);
714 if (pcidev == BCM4301_DEVICE_ID)
715 return (BCM4301_DEVICE_ID);
720 /* convert chip number to number of i/o cores */
722 sb_chip2numcores(uint chip)
730 if ((chip == 0x4307) || (chip == 0x4301))
734 if (chip == 0x4306) /* < 4306c0 */
741 SB_ERROR(("sb_chip2numcores: unsupported chip 0x%x\n", chip));
746 /* return index of coreid or BADIDX if not found */
748 sb_findcoreidx(void *sbh, uint coreid, uint coreunit)
757 for (i = 0; i < si->numcores; i++)
758 if (si->coreid[i] == coreid) {
759 if (found == coreunit)
768 * this function changes logical "focus" to the indiciated core,
769 * must be called with interrupt off.
770 * Moreover, callers should keep interrupts off during switching out of and back to d11 core
773 sb_setcoreidx(void *sbh, uint coreidx)
781 if (coreidx >= si->numcores)
785 * If the user has provided an interrupt mask enabled function,
786 * then assert interrupts are disabled before switching the core.
788 ASSERT((si->intrsenabled_fn == NULL) || !(*(si)->intrsenabled_fn)((si)->intr_arg));
790 sbaddr = SB_ENUM_BASE + (coreidx * SB_CORE_SIZE);
795 if (!si->regs[coreidx]) {
796 si->regs[coreidx] = (void*)REG_MAP(sbaddr, SB_CORE_SIZE);
797 ASSERT(GOODREGS(si->regs[coreidx]));
799 si->curmap = si->regs[coreidx];
803 /* point bar0 window */
804 OSL_PCI_WRITE_CONFIG(si->osh, PCI_BAR0_WIN, 4, sbaddr);
808 tmp = (sbaddr >> 12) & 0x0f;
809 OSL_PCMCIA_WRITE_ATTR(si->osh, PCMCIA_ADDR0, &tmp, 1);
810 tmp = (sbaddr >> 16) & 0xff;
811 OSL_PCMCIA_WRITE_ATTR(si->osh, PCMCIA_ADDR1, &tmp, 1);
812 tmp = (sbaddr >> 24) & 0xff;
813 OSL_PCMCIA_WRITE_ATTR(si->osh, PCMCIA_ADDR2, &tmp, 1);
817 si->curidx = coreidx;
823 * this function changes logical "focus" to the indiciated core,
824 * must be called with interrupt off.
825 * Moreover, callers should keep interrupts off during switching out of and back to d11 core
828 sb_setcore(void *sbh, uint coreid, uint coreunit)
835 idx = sb_findcoreidx(sbh, coreid, coreunit);
839 return (sb_setcoreidx(sbh, idx));
842 /* return chip number */
852 /* return chip revision number */
854 sb_chiprev(void *sbh)
859 return (si->chiprev);
862 /* return chip common revision number */
864 sb_chipcrev(void *sbh)
872 /* return chip package option */
874 sb_chippkg(void *sbh)
879 return (si->chippkg);
882 /* return PCI core rev. */
892 /* return PCMCIA core rev. */
894 sb_pcmciarev(void *sbh)
899 return (si->pcmciarev);
902 /* return board vendor id */
904 sb_boardvendor(void *sbh)
909 return (si->boardvendor);
912 /* return boardtype */
914 sb_boardtype(void *sbh)
921 if (si->bus == SB_BUS && si->boardtype == 0xffff) {
922 /* boardtype format is a hex string */
923 si->boardtype = getintvar(NULL, "boardtype");
925 /* backward compatibility for older boardtype string format */
926 if ((si->boardtype == 0) && (var = getvar(NULL, "boardtype"))) {
927 if (!strcmp(var, "bcm94710dev"))
928 si->boardtype = BCM94710D_BOARD;
929 else if (!strcmp(var, "bcm94710ap"))
930 si->boardtype = BCM94710AP_BOARD;
931 else if (!strcmp(var, "bcm94310u"))
932 si->boardtype = BCM94310U_BOARD;
933 else if (!strcmp(var, "bu4711"))
934 si->boardtype = BU4711_BOARD;
935 else if (!strcmp(var, "bu4710"))
936 si->boardtype = BU4710_BOARD;
937 else if (!strcmp(var, "bcm94702mn"))
938 si->boardtype = BCM94702MN_BOARD;
939 else if (!strcmp(var, "bcm94710r1"))
940 si->boardtype = BCM94710R1_BOARD;
941 else if (!strcmp(var, "bcm94710r4"))
942 si->boardtype = BCM94710R4_BOARD;
943 else if (!strcmp(var, "bcm94702cpci"))
944 si->boardtype = BCM94702CPCI_BOARD;
945 else if (!strcmp(var, "bcm95380_rr"))
946 si->boardtype = BCM95380RR_BOARD;
950 return (si->boardtype);
953 /* return board bus style */
955 sb_boardstyle(void *sbh)
962 if (si->bus == PCMCIA_BUS)
963 return (BOARDSTYLE_PCMCIA);
965 if (si->bus == SB_BUS)
966 return (BOARDSTYLE_SOC);
970 if (OSL_PCI_READ_CONFIG(si->osh, PCI_CFG_CIS, sizeof (uint32)) != 0)
971 return (BOARDSTYLE_CARDBUS);
973 if ((srom_read(si->bus, si->curmap, si->osh, (SPROM_SIZE - 1) * 2, 2, &w) == 0) &&
975 return (BOARDSTYLE_CARDBUS);
977 return (BOARDSTYLE_PCI);
980 /* return boolean if sbh device is in pci hostmode or client mode */
990 /* return list of found cores */
992 sb_corelist(void *sbh, uint coreid[])
998 bcopy((uchar*)si->coreid, (uchar*)coreid, (si->numcores * sizeof (uint)));
999 return (si->numcores);
1002 /* return current register mapping */
1004 sb_coreregs(void *sbh)
1009 ASSERT(GOODREGS(si->curmap));
1011 return (si->curmap);
1014 /* traverse all cores to find and clear source of serror */
1016 sb_serr_clear(void *sbh)
1021 uint i, intr_val = 0;
1022 void * corereg = NULL;
1026 INTR_OFF(si, intr_val);
1027 origidx = sb_coreidx(sbh);
1029 for (i = 0; i < si->numcores; i++) {
1030 corereg = sb_setcoreidx(sbh, i);
1031 if (NULL != corereg) {
1032 sb = REGS2SB(corereg);
1033 if ((si->chip == BCM4317_DEVICE_ID) && (si->chiprev == 0)) {
1034 W_SBREG(sbh, &sb->sbtmstatehigh, 0);
1036 if ((R_SBREG(sbh, &sb->sbtmstatehigh)) & SBTMH_SERR) {
1037 AND_SBREG(sbh, &sb->sbtmstatehigh, ~SBTMH_SERR);
1038 SB_ERROR(("sb_serr_clear: SError at core 0x%x\n", sb_coreid(sbh)));
1044 sb_setcoreidx(sbh, origidx);
1045 INTR_RESTORE(si, intr_val);
1048 /* check if any inband, outband or timeout errors has happened and clear them */
1049 /* !! must be called with chip clk on */
1051 sb_taclear(void *sbh)
1058 uint32 inband = 0, serror = 0, timeout = 0;
1059 void *corereg = NULL;
1060 volatile uint32 imstate, tmstate;
1064 if (si->bus == PCI_BUS) {
1065 volatile uint32 stcmd;
1067 /* inband error is Target abort for PCI */
1068 stcmd = OSL_PCI_READ_CONFIG(si->osh, PCI_CFG_CMD, sizeof(uint32));
1069 inband = stcmd & PCI_CFG_CMD_STAT_TA;
1071 OSL_PCI_WRITE_CONFIG(si->osh, PCI_CFG_CMD, sizeof(uint32), stcmd);
1074 stcmd = OSL_PCI_READ_CONFIG(si->osh, PCI_INT_STATUS, sizeof(uint32));
1075 serror = stcmd & PCI_SBIM_STATUS_SERR;
1078 OSL_PCI_WRITE_CONFIG(si->osh, PCI_INT_STATUS, sizeof(uint32), stcmd);
1082 imstate = sb_corereg(sbh, si->pciidx, SBCONFIGOFF + OFFSETOF(sbconfig_t, sbimstate), 0, 0);
1083 if ((imstate != 0xffffffff) && (imstate & (SBIM_IBE | SBIM_TO))) {
1084 sb_corereg(sbh, si->pciidx, SBCONFIGOFF + OFFSETOF(sbconfig_t, sbimstate), ~0,
1085 (imstate & ~(SBIM_IBE | SBIM_TO)));
1086 /* inband = imstate & SBIM_IBE; same as TA above */
1087 timeout = imstate & SBIM_TO;
1090 } else if (si->bus == PCMCIA_BUS) {
1092 INTR_OFF(si, intr_val);
1093 origidx = sb_coreidx(sbh);
1095 corereg = sb_setcore(sbh, SB_PCMCIA, 0);
1096 if (NULL != corereg) {
1097 sb = REGS2SB(corereg);
1099 imstate = R_SBREG(sbh, &sb->sbimstate);
1100 /* handle surprise removal */
1101 if ((imstate != 0xffffffff) && (imstate & (SBIM_IBE | SBIM_TO))) {
1102 AND_SBREG(sbh, &sb->sbimstate, ~(SBIM_IBE | SBIM_TO));
1103 inband = imstate & SBIM_IBE;
1104 timeout = imstate & SBIM_TO;
1106 tmstate = R_SBREG(sbh, &sb->sbtmstatehigh);
1107 if ((tmstate != 0xffffffff) && (tmstate & SBTMH_INT_STATUS)) {
1112 OR_SBREG(sbh, &sb->sbtmstatelow, SBTML_INT_ACK);
1113 AND_SBREG(sbh, &sb->sbtmstatelow, ~SBTML_INT_ACK);
1116 sb_setcoreidx(sbh, origidx);
1117 INTR_RESTORE(si, intr_val);
1119 } else if (si->bus == SDIO_BUS) {
1121 INTR_OFF(si, intr_val);
1122 origidx = sb_coreidx(sbh);
1124 corereg = sb_setcore(sbh, SB_PCMCIA, 0);
1125 if (NULL != corereg) {
1126 sb = REGS2SB(corereg);
1128 imstate = R_SBREG(sbh, &sb->sbimstate);
1129 if ((imstate != 0xffffffff) && (imstate & (SBIM_IBE | SBIM_TO))) {
1130 AND_SBREG(sbh, &sb->sbimstate, ~(SBIM_IBE | SBIM_TO));
1131 /* inband = imstate & SBIM_IBE; cmd error */
1132 timeout = imstate & SBIM_TO;
1134 tmstate = R_SBREG(sbh, &sb->sbtmstatehigh);
1135 if ((tmstate != 0xffffffff) && (tmstate & SBTMH_INT_STATUS)) {
1138 OR_SBREG(sbh, &sb->sbtmstatelow, SBTML_INT_ACK);
1139 AND_SBREG(sbh, &sb->sbtmstatelow, ~SBTML_INT_ACK);
1143 sb_setcoreidx(sbh, origidx);
1144 INTR_RESTORE(si, intr_val);
1147 if ((inband | timeout | serror) != 0) {
1149 SB_ERROR(("sb_taclear: inband 0x%x, serror 0x%x, timeout 0x%x!\n", inband, serror, timeout));
1155 /* do buffered registers update */
1157 sb_commit(void *sbh)
1160 sbpciregs_t *pciregs;
1166 origidx = si->curidx;
1167 ASSERT(GOODIDX(origidx));
1169 INTR_OFF(si, intr_val);
1170 /* switch over to pci core */
1171 pciregs = (sbpciregs_t*) sb_setcore(sbh, SB_PCI, 0);
1173 /* do the buffer registers update */
1174 W_REG(&pciregs->bcastaddr, SB_COMMIT);
1175 W_REG(&pciregs->bcastdata, 0x0);
1177 /* restore core index */
1178 sb_setcoreidx(sbh, origidx);
1179 INTR_RESTORE(si, intr_val);
1182 /* reset and re-enable a core */
1184 sb_core_reset(void *sbh, uint32 bits)
1188 volatile uint32 dummy;
1191 ASSERT(GOODREGS(si->curmap));
1192 sb = REGS2SB(si->curmap);
1195 * Must do the disable sequence first to work for arbitrary current core state.
1197 sb_core_disable(sbh, bits);
1200 * Now do the initialization sequence.
1203 /* set reset while enabling the clock and forcing them on throughout the core */
1204 W_SBREG(sbh, &sb->sbtmstatelow, (SBTML_FGC | SBTML_CLK | SBTML_RESET | bits));
1205 dummy = R_SBREG(sbh, &sb->sbtmstatelow);
1207 if (sb_coreid(sbh) == SB_ILINE100) {
1213 if (R_SBREG(sbh, &sb->sbtmstatehigh) & SBTMH_SERR) {
1214 W_SBREG(sbh, &sb->sbtmstatehigh, 0);
1216 if ((dummy = R_SBREG(sbh, &sb->sbimstate)) & (SBIM_IBE | SBIM_TO)) {
1217 AND_SBREG(sbh, &sb->sbimstate, ~(SBIM_IBE | SBIM_TO));
1220 /* clear reset and allow it to propagate throughout the core */
1221 W_SBREG(sbh, &sb->sbtmstatelow, (SBTML_FGC | SBTML_CLK | bits));
1222 dummy = R_SBREG(sbh, &sb->sbtmstatelow);
1225 /* leave clock enabled */
1226 W_SBREG(sbh, &sb->sbtmstatelow, (SBTML_CLK | bits));
1227 dummy = R_SBREG(sbh, &sb->sbtmstatelow);
1232 sb_core_tofixup(void *sbh)
1239 if (si->pcirev >= 5)
1242 ASSERT(GOODREGS(si->curmap));
1243 sb = REGS2SB(si->curmap);
1245 if (si->bus == SB_BUS) {
1246 SET_SBREG(sbh, &sb->sbimconfiglow,
1247 SBIMCL_RTO_MASK | SBIMCL_STO_MASK,
1248 (0x5 << SBIMCL_RTO_SHIFT) | 0x3);
1250 if (sb_coreid(sbh) == SB_PCI) {
1251 SET_SBREG(sbh, &sb->sbimconfiglow,
1252 SBIMCL_RTO_MASK | SBIMCL_STO_MASK,
1253 (0x3 << SBIMCL_RTO_SHIFT) | 0x2);
1255 SET_SBREG(sbh, &sb->sbimconfiglow, (SBIMCL_RTO_MASK | SBIMCL_STO_MASK), 0);
1263 sb_core_disable(void *sbh, uint32 bits)
1266 volatile uint32 dummy;
1271 ASSERT(GOODREGS(si->curmap));
1272 sb = REGS2SB(si->curmap);
1274 /* must return if core is already in reset */
1275 if (R_SBREG(sbh, &sb->sbtmstatelow) & SBTML_RESET)
1278 /* put into reset and return if clocks are not enabled */
1279 if ((R_SBREG(sbh, &sb->sbtmstatelow) & SBTML_CLK) == 0)
1282 /* set the reject bit */
1283 W_SBREG(sbh, &sb->sbtmstatelow, (SBTML_CLK | SBTML_REJ));
1285 /* spin until reject is set */
1286 while ((R_SBREG(sbh, &sb->sbtmstatelow) & SBTML_REJ) == 0)
1289 /* spin until sbtmstatehigh.busy is clear */
1290 while (R_SBREG(sbh, &sb->sbtmstatehigh) & SBTMH_BUSY)
1293 /* set reset and reject while enabling the clocks */
1294 W_SBREG(sbh, &sb->sbtmstatelow, (bits | SBTML_FGC | SBTML_CLK | SBTML_REJ | SBTML_RESET));
1295 dummy = R_SBREG(sbh, &sb->sbtmstatelow);
1299 /* leave reset and reject asserted */
1300 W_SBREG(sbh, &sb->sbtmstatelow, (bits | SBTML_REJ | SBTML_RESET));
1305 sb_watchdog(void *sbh, uint ticks)
1307 sb_info_t *si = SB_INFO(sbh);
1310 switch (si->gpioid) {
1312 sb_corereg(sbh, si->gpioidx, OFFSETOF(chipcregs_t, watchdog), ~0, ticks);
1315 sb_corereg(sbh, si->gpioidx, OFFSETOF(extifregs_t, watchdog), ~0, ticks);
1320 /* initialize the pcmcia core */
1322 sb_pcmcia_init(void *sbh)
1329 /* enable d11 mac interrupts */
1330 if (si->chip == BCM4301_DEVICE_ID) {
1331 /* Have to use FCR2 in 4301 */
1332 OSL_PCMCIA_READ_ATTR(si->osh, PCMCIA_FCR2 + PCMCIA_COR, &cor, 1);
1333 cor |= COR_IRQEN | COR_FUNEN;
1334 OSL_PCMCIA_WRITE_ATTR(si->osh, PCMCIA_FCR2 + PCMCIA_COR, &cor, 1);
1336 OSL_PCMCIA_READ_ATTR(si->osh, PCMCIA_FCR0 + PCMCIA_COR, &cor, 1);
1337 cor |= COR_IRQEN | COR_FUNEN;
1338 OSL_PCMCIA_WRITE_ATTR(si->osh, PCMCIA_FCR0 + PCMCIA_COR, &cor, 1);
1345 * Configure the pci core for pci client (NIC) action
1346 * and get appropriate dma offset value.
1347 * coremask is the bitvec of cores by index to be enabled.
1350 sb_pci_setup(void *sbh, uint32 *dmaoffset, uint coremask)
1354 sbpciregs_t *pciregs;
1364 /* if not pci bus, we're done */
1365 if (si->bus != PCI_BUS)
1370 /* get current core index */
1373 /* we interrupt on this backplane flag number */
1374 ASSERT(GOODREGS(si->curmap));
1375 sb = REGS2SB(si->curmap);
1376 sbflag = R_SBREG(sbh, &sb->sbtpsflag) & SBTPS_NUM0_MASK;
1378 /* switch over to pci core */
1379 pciregs = (sbpciregs_t*) sb_setcoreidx(sbh, si->pciidx);
1380 sb = REGS2SB(pciregs);
1383 * Enable sb->pci interrupts. Assume
1384 * PCI rev 2.3 support was added in pci core rev 6 and things changed..
1386 if (si->pcirev < 6) {
1387 /* set sbintvec bit for our flag number */
1388 OR_SBREG(sbh, &sb->sbintvec, (1 << sbflag));
1390 /* pci config write to set this core bit in PCIIntMask */
1391 w = OSL_PCI_READ_CONFIG(si->osh, PCI_INT_MASK, sizeof(uint32));
1392 w |= (coremask << PCI_SBIM_SHIFT);
1393 OSL_PCI_WRITE_CONFIG(si->osh, PCI_INT_MASK, sizeof(uint32), w);
1396 /* enable prefetch and bursts for sonics-to-pci translation 2 */
1397 OR_REG(&pciregs->sbtopci2, (SBTOPCI_PREF|SBTOPCI_BURST));
1399 if (si->pcirev < 5) {
1400 SET_SBREG(sbh, &sb->sbimconfiglow, SBIMCL_RTO_MASK | SBIMCL_STO_MASK,
1401 (0x3 << SBIMCL_RTO_SHIFT) | 0x2);
1405 /* switch back to previous core */
1406 sb_setcoreidx(sbh, idx);
1408 /* use large sb pci dma window */
1410 *dmaoffset = SB_PCI_DMA;
1414 sb_base(uint32 admatch)
1419 type = admatch & SBAM_TYPE_MASK;
1425 base = admatch & SBAM_BASE0_MASK;
1426 } else if (type == 1) {
1427 ASSERT(!(admatch & SBAM_ADNEG)); /* neg not supported */
1428 base = admatch & SBAM_BASE1_MASK;
1429 } else if (type == 2) {
1430 ASSERT(!(admatch & SBAM_ADNEG)); /* neg not supported */
1431 base = admatch & SBAM_BASE2_MASK;
1438 sb_size(uint32 admatch)
1443 type = admatch & SBAM_TYPE_MASK;
1449 size = 1 << (((admatch & SBAM_ADINT0_MASK) >> SBAM_ADINT0_SHIFT) + 1);
1450 } else if (type == 1) {
1451 ASSERT(!(admatch & SBAM_ADNEG)); /* neg not supported */
1452 size = 1 << (((admatch & SBAM_ADINT1_MASK) >> SBAM_ADINT1_SHIFT) + 1);
1453 } else if (type == 2) {
1454 ASSERT(!(admatch & SBAM_ADNEG)); /* neg not supported */
1455 size = 1 << (((admatch & SBAM_ADINT2_MASK) >> SBAM_ADINT2_SHIFT) + 1);
1461 /* return the core-type instantiation # of the current core */
1463 sb_coreunit(void *sbh)
1476 ASSERT(GOODREGS(si->curmap));
1477 coreid = sb_coreid(sbh);
1479 /* count the cores of our type */
1480 for (i = 0; i < idx; i++)
1481 if (si->coreid[i] == coreid)
1487 static INLINE uint32
1491 case CC_F6_2: return 2;
1492 case CC_F6_3: return 3;
1493 case CC_F6_4: return 4;
1494 case CC_F6_5: return 5;
1495 case CC_F6_6: return 6;
1496 case CC_F6_7: return 7;
1501 /* calculate the speed the SB would run at given a set of clockcontrol values */
1503 sb_clock_rate(uint32 pll_type, uint32 n, uint32 m)
1505 uint32 n1, n2, clock, m1, m2, m3, mc;
1507 n1 = n & CN_N1_MASK;
1508 n2 = (n & CN_N2_MASK) >> CN_N2_SHIFT;
1510 if ((pll_type == PLL_TYPE1) || (pll_type == PLL_TYPE4)) {
1513 } else if (pll_type == PLL_TYPE2) {
1516 ASSERT((n1 >= 2) && (n1 <= 7));
1517 ASSERT((n2 >= 5) && (n2 <= 23));
1518 } else if (pll_type == PLL_TYPE3) {
1521 ASSERT((pll_type >= PLL_TYPE1) && (pll_type <= PLL_TYPE4));
1523 clock = CC_CLOCK_BASE * n1 * n2;
1528 m1 = m & CC_M1_MASK;
1529 m2 = (m & CC_M2_MASK) >> CC_M2_SHIFT;
1530 m3 = (m & CC_M3_MASK) >> CC_M3_SHIFT;
1531 mc = (m & CC_MC_MASK) >> CC_MC_SHIFT;
1533 if ((pll_type == PLL_TYPE1) || (pll_type == PLL_TYPE4)) {
1535 if (pll_type == PLL_TYPE1)
1542 case CC_MC_BYPASS: return (clock);
1543 case CC_MC_M1: return (clock / m1);
1544 case CC_MC_M1M2: return (clock / (m1 * m2));
1545 case CC_MC_M1M2M3: return (clock / (m1 * m2 * m3));
1546 case CC_MC_M1M3: return (clock / (m1 * m3));
1547 default: return (0);
1550 ASSERT(pll_type == PLL_TYPE2);
1555 ASSERT((m1 >= 2) && (m1 <= 7));
1556 ASSERT((m2 >= 3) && (m2 <= 10));
1557 ASSERT((m3 >= 2) && (m3 <= 7));
1559 if ((mc & CC_T2MC_M1BYP) == 0)
1561 if ((mc & CC_T2MC_M2BYP) == 0)
1563 if ((mc & CC_T2MC_M3BYP) == 0)
1570 /* returns the current speed the SB is running at */
1579 uint32 pll_type, rate;
1584 pll_type = PLL_TYPE1;
1586 INTR_OFF(si, intr_val);
1588 /* switch to extif or chipc core */
1589 if ((eir = (extifregs_t *) sb_setcore(sbh, SB_EXTIF, 0))) {
1590 n = R_REG(&eir->clockcontrol_n);
1591 m = R_REG(&eir->clockcontrol_sb);
1592 } else if ((cc = (chipcregs_t *) sb_setcore(sbh, SB_CC, 0))) {
1593 pll_type = R_REG(&cc->capabilities) & CAP_PLL_MASK;
1594 n = R_REG(&cc->clockcontrol_n);
1595 m = R_REG(&cc->clockcontrol_sb);
1597 INTR_RESTORE(si, intr_val);
1601 /* calculate rate */
1602 rate = sb_clock_rate(pll_type, n, m);
1604 /* switch back to previous core */
1605 sb_setcoreidx(sbh, idx);
1607 INTR_RESTORE(si, intr_val);
1612 /* change logical "focus" to the gpio core for optimized access */
1614 sb_gpiosetcore(void *sbh)
1620 return (sb_setcoreidx(sbh, si->gpioidx));
1623 /* mask&set gpiocontrol bits */
1625 sb_gpiocontrol(void *sbh, uint32 mask, uint32 val)
1633 switch (si->gpioid) {
1635 regoff = OFFSETOF(chipcregs_t, gpiocontrol);
1639 regoff = OFFSETOF(sbpciregs_t, gpiocontrol);
1646 return (sb_corereg(sbh, si->gpioidx, regoff, mask, val));
1649 /* mask&set gpio output enable bits */
1651 sb_gpioouten(void *sbh, uint32 mask, uint32 val)
1659 switch (si->gpioid) {
1661 regoff = OFFSETOF(chipcregs_t, gpioouten);
1665 regoff = OFFSETOF(sbpciregs_t, gpioouten);
1669 regoff = OFFSETOF(extifregs_t, gpio[0].outen);
1673 return (sb_corereg(sbh, si->gpioidx, regoff, mask, val));
1676 /* mask&set gpio output bits */
1678 sb_gpioout(void *sbh, uint32 mask, uint32 val)
1686 switch (si->gpioid) {
1688 regoff = OFFSETOF(chipcregs_t, gpioout);
1692 regoff = OFFSETOF(sbpciregs_t, gpioout);
1696 regoff = OFFSETOF(extifregs_t, gpio[0].out);
1700 return (sb_corereg(sbh, si->gpioidx, regoff, mask, val));
1703 /* return the current gpioin register value */
1705 sb_gpioin(void *sbh)
1713 switch (si->gpioid) {
1715 regoff = OFFSETOF(chipcregs_t, gpioin);
1719 regoff = OFFSETOF(sbpciregs_t, gpioin);
1723 regoff = OFFSETOF(extifregs_t, gpioin);
1727 return (sb_corereg(sbh, si->gpioidx, regoff, 0, 0));
1730 /* mask&set gpio interrupt polarity bits */
1732 sb_gpiointpolarity(void *sbh, uint32 mask, uint32 val)
1740 switch (si->gpioid) {
1742 regoff = OFFSETOF(chipcregs_t, gpiointpolarity);
1746 /* pci gpio implementation does not support interrupt polarity */
1751 regoff = OFFSETOF(extifregs_t, gpiointpolarity);
1755 return (sb_corereg(sbh, si->gpioidx, regoff, mask, val));
1758 /* mask&set gpio interrupt mask bits */
1760 sb_gpiointmask(void *sbh, uint32 mask, uint32 val)
1768 switch (si->gpioid) {
1770 regoff = OFFSETOF(chipcregs_t, gpiointmask);
1774 /* pci gpio implementation does not support interrupt mask */
1779 regoff = OFFSETOF(extifregs_t, gpiointmask);
1783 return (sb_corereg(sbh, si->gpioidx, regoff, mask, val));
1788 * Return the slow clock source.
1789 * Three sources of SLOW CLOCK: LPO, Xtal, PCI
1792 sb_slowclk_src(void *sbh)
1800 ASSERT(sb_coreid(sbh) == SB_CC);
1802 if (si->ccrev < 6) {
1804 case PCMCIA_BUS: return (SCC_SS_XTAL);
1806 v = OSL_PCI_READ_CONFIG(si->osh, PCI_GPIO_OUT, sizeof (uint32));
1807 if (v & PCI_CFG_GPIO_SCS)
1808 return (SCC_SS_PCI);
1810 return (SCC_SS_XTAL);
1811 default: return (SCC_SS_XTAL);
1813 } else if (si->ccrev < 10) {
1814 cc = (chipcregs_t*) sb_setcoreidx(sbh, si->curidx);
1815 v = R_REG(&cc->slow_clk_ctl) & SCC_SS_MASK;
1818 return (SCC_SS_XTAL);
1823 * Return the slowclock min or max frequency.
1824 * Three sources of SLOW CLOCK:
1825 * 1. On Chip LPO - 32khz or 160khz
1826 * 2. On Chip Xtal OSC - 20mhz/4*(divider+1)
1827 * 3. External PCI clock - 66mhz/4*(divider+1)
1830 sb_slowclk_freq(void *sbh, bool max)
1839 ASSERT(sb_coreid(sbh) == SB_CC);
1841 cc = (chipcregs_t*) sb_setcoreidx(sbh, si->curidx);
1843 /* shouldn't be here unless we've established the chip has dynamic power control */
1844 ASSERT(R_REG(&cc->capabilities) & CAP_PWR_CTL);
1846 slowclk = sb_slowclk_src(sbh);
1847 if (si->ccrev < 6) {
1848 if (slowclk == SCC_SS_PCI)
1849 return (max? (PCIMAXFREQ/64) : (PCIMINFREQ/64));
1851 return (max? (XTALMAXFREQ/32) : (XTALMINFREQ/32));
1852 } else if (si->ccrev < 10) {
1853 div = 4 * (((R_REG(&cc->slow_clk_ctl) & SCC_CD_MASK) >> SCC_CD_SHF) + 1);
1854 if (slowclk == SCC_SS_LPO)
1855 return (max? LPOMAXFREQ : LPOMINFREQ);
1856 else if (slowclk == SCC_SS_XTAL)
1857 return (max? (XTALMAXFREQ/div) : (XTALMINFREQ/div));
1858 else if (slowclk == SCC_SS_PCI)
1859 return (max? (PCIMAXFREQ/div) : (PCIMINFREQ/div));
1863 /* Chipc rev 10 is InstaClock */
1864 div = R_REG(&cc->system_clk_ctl) >> SYCC_CD_SHF;
1865 div = 4 * (div + 1);
1866 return (max ? XTALMAXFREQ : (XTALMINFREQ/div));
1872 sb_pwrctl_setdelay(void *sbh, void *chipcregs)
1875 uint slowmaxfreq, pll_delay, slowclk;
1876 uint pll_on_delay, fref_sel_delay;
1878 pll_delay = PLL_DELAY;
1880 /* If the slow clock is not sourced by the xtal then add the xtal_on_delay
1881 * since the xtal will also be powered down by dynamic power control logic.
1883 slowclk = sb_slowclk_src(sbh);
1884 if (slowclk != SCC_SS_XTAL)
1885 pll_delay += XTAL_ON_DELAY;
1887 slowmaxfreq = sb_slowclk_freq(sbh, TRUE);
1889 pll_on_delay = ((slowmaxfreq * pll_delay) + 999999) / 1000000;
1890 fref_sel_delay = ((slowmaxfreq * FREF_DELAY) + 999999) / 1000000;
1892 cc = (chipcregs_t *)chipcregs;
1893 W_REG(&cc->pll_on_delay, pll_on_delay);
1894 W_REG(&cc->fref_sel_delay, fref_sel_delay);
1897 /* set or get slow clock divider */
1899 sb_pwrctl_slowclk(void *sbh, bool set, uint *div)
1909 /* chipcommon cores prior to rev6 don't support slowclkcontrol */
1913 /* chipcommon cores rev10 are a whole new ball game */
1914 if (si->ccrev >= 10)
1917 if (set && ((*div % 4) || (*div < 4)))
1920 INTR_OFF(si, intr_val);
1921 origidx = si->curidx;
1922 cc = (chipcregs_t*) sb_setcore(sbh, SB_CC, 0);
1925 if (!(R_REG(&cc->capabilities) & CAP_PWR_CTL)) {
1931 SET_REG(&cc->slow_clk_ctl, SCC_CD_MASK, ((*div / 4 - 1) << SCC_CD_SHF));
1932 sb_pwrctl_setdelay(sbh, (void *)cc);
1934 *div = 4 * (((R_REG(&cc->slow_clk_ctl) & SCC_CD_MASK) >> SCC_CD_SHF) + 1);
1937 sb_setcoreidx(sbh, origidx);
1938 INTR_RESTORE(si, intr_val);
1942 /* initialize power control delay registers */
1944 sb_pwrctl_init(void *sbh)
1952 if (si->bus == SB_BUS)
1955 origidx = si->curidx;
1957 if ((cc = (chipcregs_t*) sb_setcore(sbh, SB_CC, 0)) == NULL)
1960 if (!(R_REG(&cc->capabilities) & CAP_PWR_CTL))
1963 /* 4317pc does not work with SlowClock less than 5Mhz */
1964 if (si->bus == PCMCIA_BUS) {
1965 if ((si->ccrev >= 6) && (si->ccrev < 10))
1966 SET_REG(&cc->slow_clk_ctl, SCC_CD_MASK, (SCC_DEF_DIV << SCC_CD_SHF));
1969 sb_pwrctl_setdelay(sbh, (void *)cc);
1972 sb_setcoreidx(sbh, origidx);
1975 /* return the value suitable for writing to the dot11 core FAST_PWRUP_DELAY register */
1977 sb_pwrctl_fast_pwrup_delay(void *sbh)
1988 origidx = si->curidx;
1990 if (si->bus == SB_BUS)
1993 INTR_OFF(si, intr_val);
1995 if ((cc = (chipcregs_t*) sb_setcore(sbh, SB_CC, 0)) == NULL)
1998 if (!(R_REG(&cc->capabilities) & CAP_PWR_CTL))
2001 slowminfreq = sb_slowclk_freq(sbh, FALSE);
2002 fpdelay = (((R_REG(&cc->pll_on_delay) + 2) * 1000000) + (slowminfreq - 1)) / slowminfreq;
2005 sb_setcoreidx(sbh, origidx);
2006 INTR_RESTORE(si, intr_val);
2010 /* turn primary xtal and/or pll off/on */
2012 sb_pwrctl_xtal(void *sbh, uint what, bool on)
2015 uint32 in, out, outen;
2028 in = OSL_PCI_READ_CONFIG(si->osh, PCI_GPIO_IN, sizeof (uint32));
2029 out = OSL_PCI_READ_CONFIG(si->osh, PCI_GPIO_OUT, sizeof (uint32));
2030 outen = OSL_PCI_READ_CONFIG(si->osh, PCI_GPIO_OUTEN, sizeof (uint32));
2033 * We can't actually read the state of the PLLPD so we infer it
2034 * by the value of XTAL_PU which *is* readable via gpioin.
2036 if (on && (in & PCI_CFG_GPIO_XTAL))
2040 outen |= PCI_CFG_GPIO_XTAL;
2042 outen |= PCI_CFG_GPIO_PLL;
2045 /* turn primary xtal on */
2047 out |= PCI_CFG_GPIO_XTAL;
2049 out |= PCI_CFG_GPIO_PLL;
2050 OSL_PCI_WRITE_CONFIG(si->osh, PCI_GPIO_OUT, sizeof (uint32), out);
2051 OSL_PCI_WRITE_CONFIG(si->osh, PCI_GPIO_OUTEN, sizeof (uint32), outen);
2052 OSL_DELAY(XTAL_ON_DELAY);
2057 out &= ~PCI_CFG_GPIO_PLL;
2058 OSL_PCI_WRITE_CONFIG(si->osh, PCI_GPIO_OUT, sizeof (uint32), out);
2063 out &= ~PCI_CFG_GPIO_XTAL;
2065 out |= PCI_CFG_GPIO_PLL;
2066 OSL_PCI_WRITE_CONFIG(si->osh, PCI_GPIO_OUT, sizeof (uint32), out);
2067 OSL_PCI_WRITE_CONFIG(si->osh, PCI_GPIO_OUTEN, sizeof (uint32), outen);
2077 /* set dynamic power control mode (forceslow, forcefast, dynamic) */
2078 /* returns true if ignore pll off is set and false if it is not */
2080 sb_pwrctl_clk(void *sbh, uint mode)
2086 bool forcefastclk=FALSE;
2091 /* chipcommon cores prior to rev6 don't support slowclkcontrol */
2095 /* chipcommon cores rev10 are a whole new ball game */
2096 if (si->ccrev >= 10)
2099 INTR_OFF(si, intr_val);
2101 origidx = si->curidx;
2103 cc = (chipcregs_t*) sb_setcore(sbh, SB_CC, 0);
2106 if (!(R_REG(&cc->capabilities) & CAP_PWR_CTL))
2110 case CLK_FAST: /* force fast (pll) clock */
2111 /* don't forget to force xtal back on before we clear SCC_DYN_XTAL.. */
2112 sb_pwrctl_xtal(sbh, XTAL, ON);
2114 SET_REG(&cc->slow_clk_ctl, (SCC_XC | SCC_FS | SCC_IP), SCC_IP);
2117 case CLK_SLOW: /* force slow clock */
2118 if ((si->bus == SDIO_BUS) || (si->bus == PCMCIA_BUS))
2122 OR_REG(&cc->slow_clk_ctl, SCC_FS);
2125 case CLK_DYNAMIC: /* enable dynamic power control */
2126 scc = R_REG(&cc->slow_clk_ctl);
2127 scc &= ~(SCC_FS | SCC_IP | SCC_XC);
2128 if ((scc & SCC_SS_MASK) != SCC_SS_XTAL)
2130 W_REG(&cc->slow_clk_ctl, scc);
2132 /* for dynamic control, we have to release our xtal_pu "force on" */
2134 sb_pwrctl_xtal(sbh, XTAL, OFF);
2138 /* Is the h/w forcing the use of the fast clk */
2139 forcefastclk = (bool)((R_REG(&cc->slow_clk_ctl) & SCC_IP) == SCC_IP);
2142 sb_setcoreidx(sbh, origidx);
2143 INTR_RESTORE(si, intr_val);
2144 return (forcefastclk);
2147 /* register driver interrupt disabling and restoring callback functions */
2149 sb_register_intr_callback(void *sbh, void *intrsoff_fn, void *intrsrestore_fn, void *intrsenabled_fn, void *intr_arg)
2154 si->intr_arg = intr_arg;
2155 si->intrsoff_fn = (sb_intrsoff_t)intrsoff_fn;
2156 si->intrsrestore_fn = (sb_intrsrestore_t)intrsrestore_fn;
2157 si->intrsenabled_fn = (sb_intrsenabled_t)intrsenabled_fn;
2158 /* save current core id. when this function called, the current core
2159 * must be the core which provides driver functions(il, et, wl, etc.)
2161 si->dev_coreid = si->coreid[si->curidx];