Changes for kernel and Busybox
[tomato.git] / release / src / shared / hndpci.c
blobc0e70c8bb5bc9e0b049f7e3088a37abb06ce01d3
1 /*
2 * Low-Level PCI and SB support for BCM47xx
4 * Copyright 2007, Broadcom Corporation
5 * All Rights Reserved.
6 *
7 * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
8 * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
9 * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
10 * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
12 * $Id$
15 #include <typedefs.h>
16 #include <osl.h>
17 #include <pcicfg.h>
18 #include <bcmdevs.h>
19 #include <sbconfig.h>
20 #include <bcmutils.h>
21 #include <sbutils.h>
22 #include <sbpci.h>
23 #include <bcmendian.h>
24 #include <bcmnvram.h>
25 #include <hndcpu.h>
26 #include <hndmips.h>
27 #include <hndpci.h>
29 /* debug/trace */
30 #ifdef BCMDBG_PCI
31 #define PCI_MSG(args) printf args
32 #else
33 #define PCI_MSG(args)
34 #endif /* BCMDBG_PCI */
36 /* Can free sbpci_init() memory after boot */
37 #ifndef linux
38 #define __init
39 #endif /* linux */
41 /* Emulated configuration space */
42 typedef struct {
43 int n;
44 uint size0;
45 uint size1;
46 uint size2;
47 uint size3;
48 } sb_bar_cfg_t;
49 static pci_config_regs sb_config_regs[SB_MAXCORES];
50 static sb_bar_cfg_t sb_bar_cfg[SB_MAXCORES];
52 /* Links to emulated and real PCI configuration spaces */
53 #define MAXFUNCS 2
54 typedef struct {
55 pci_config_regs *emu; /* emulated PCI config */
56 pci_config_regs *pci; /* real PCI config */
57 sb_bar_cfg_t *bar; /* region sizes */
58 } sb_pci_cfg_t;
59 static sb_pci_cfg_t sb_pci_cfg[SB_MAXCORES][MAXFUNCS];
61 /* Special emulated config space for non-existing device */
62 static pci_config_regs sb_pci_null = { 0xffff, 0xffff };
64 /* Banned cores */
65 static uint16 pci_ban[SB_MAXCORES] = { 0 };
66 static uint pci_banned = 0;
68 /* CardBus mode */
69 static bool cardbus = FALSE;
71 /* Disable PCI host core */
72 static bool pci_disabled = FALSE;
74 /* Host bridge slot #, default to 0 */
75 static uint8 pci_hbslot = 0;
77 /* Internal macros */
78 #define PCI_SLOTAD_MAP 16 /* SLOT<n> mapps to AD<n+16> */
79 #define PCI_HBSBCFG_REV 8 /* MIN. core rev. required to
80 * access host bridge PCI cfg space
81 * from SB
85 * Functions for accessing external PCI configuration space
88 /* Assume one-hot slot wiring */
89 #define PCI_SLOT_MAX 16 /* Max. PCI Slots */
91 static uint32
92 config_cmd(sb_t *sbh, uint bus, uint dev, uint func, uint off)
94 uint coreidx;
95 sbpciregs_t *regs;
96 uint32 addr = 0;
97 osl_t *osh;
99 /* CardBusMode supports only one device */
100 if (cardbus && dev > 1)
101 return 0;
103 osh = sb_osh(sbh);
105 coreidx = sb_coreidx(sbh);
106 regs = (sbpciregs_t *) sb_setcore(sbh, SB_PCI, 0);
108 /* Type 0 transaction */
109 if (bus == 1) {
110 /* Skip unwired slots */
111 if (dev < PCI_SLOT_MAX) {
112 uint32 win;
114 /* Slide the PCI window to the appropriate slot */
115 win = (SBTOPCI_CFG0 | ((1 << (dev + PCI_SLOTAD_MAP)) & SBTOPCI1_MASK));
116 W_REG(osh, &regs->sbtopci1, win);
117 addr = SB_PCI_CFG |
118 ((1 << (dev + PCI_SLOTAD_MAP)) & ~SBTOPCI1_MASK) |
119 (func << PCICFG_FUN_SHIFT) |
120 (off & ~3);
122 } else {
123 /* Type 1 transaction */
124 W_REG(osh, &regs->sbtopci1, SBTOPCI_CFG1);
125 addr = SB_PCI_CFG |
126 (bus << PCICFG_BUS_SHIFT) |
127 (dev << PCICFG_SLOT_SHIFT) |
128 (func << PCICFG_FUN_SHIFT) |
129 (off & ~3);
132 sb_setcoreidx(sbh, coreidx);
134 return addr;
138 * Read host bridge PCI config registers from Silicon Backplane (>=rev8).
140 * It returns TRUE to indicate that access to the host bridge's pci config
141 * from SB is ok, and values in 'addr' and 'val' are valid.
143 * It can only read registers at multiple of 4-bytes. Callers must pick up
144 * needed bytes from 'val' based on 'off' value. Value in 'addr' reflects
145 * the register address where value in 'val' is read.
147 static bool
148 sb_pcihb_read_config(sb_t *sbh, uint bus, uint dev, uint func, uint off,
149 uint32 **addr, uint32 *val)
151 sbpciregs_t *regs;
152 osl_t *osh;
153 uint coreidx;
154 bool ret = FALSE;
156 /* sanity check */
157 ASSERT(bus == 1);
158 ASSERT(dev == pci_hbslot);
159 ASSERT(func == 0);
161 osh = sb_osh(sbh);
163 /* read pci config when core rev >= 8 */
164 coreidx = sb_coreidx(sbh);
165 regs = (sbpciregs_t *)sb_setcore(sbh, SB_PCI, 0);
166 if (regs && sb_corerev(sbh) >= PCI_HBSBCFG_REV) {
167 *addr = (uint32 *)&regs->pcicfg[func][off >> 2];
168 *val = R_REG(osh, *addr);
169 ret = TRUE;
171 sb_setcoreidx(sbh, coreidx);
173 return ret;
177 extpci_read_config(sb_t *sbh, uint bus, uint dev, uint func, uint off, void *buf, int len)
179 uint32 addr = 0, *reg = NULL, val;
180 int ret = 0;
183 * Set value to -1 when:
184 * flag 'pci_disabled' is true;
185 * value of 'addr' is zero;
186 * REG_MAP() fails;
187 * BUSPROBE() fails;
189 if (pci_disabled)
190 val = 0xffffffff;
191 else if (bus == 1 && dev == pci_hbslot && func == 0 &&
192 sb_pcihb_read_config(sbh, bus, dev, func, off, &reg, &val))
194 else if (((addr = config_cmd(sbh, bus, dev, func, off)) == 0) ||
195 ((reg = (uint32 *)REG_MAP(addr, len)) == 0) ||
196 (BUSPROBE(val, reg) != 0)) {
197 PCI_MSG(("%s: Failed to read!\n", __FUNCTION__));
198 val = 0xffffffff;
201 PCI_MSG(("%s: 0x%x <= 0x%p(0x%x), len %d, off 0x%x, buf 0x%p\n",
202 __FUNCTION__, val, reg, addr, len, off, buf));
204 val >>= 8 * (off & 3);
205 if (len == 4)
206 *((uint32 *) buf) = val;
207 else if (len == 2)
208 *((uint16 *) buf) = (uint16) val;
209 else if (len == 1)
210 *((uint8 *) buf) = (uint8) val;
211 else
212 ret = -1;
214 if (reg && addr)
215 REG_UNMAP(reg);
217 return ret;
221 extpci_write_config(sb_t *sbh, uint bus, uint dev, uint func, uint off, void *buf, int len)
223 osl_t *osh;
224 uint32 addr = 0, *reg = NULL, val;
225 int ret = 0;
227 osh = sb_osh(sbh);
230 * Ignore write attempt when:
231 * flag 'pci_disabled' is true;
232 * value of 'addr' is zero;
233 * REG_MAP() fails;
234 * BUSPROBE() fails;
236 if (pci_disabled)
237 return 0;
238 else if (bus == 1 && dev == pci_hbslot && func == 0 &&
239 sb_pcihb_read_config(sbh, bus, dev, func, off, &reg, &val))
241 else if (((addr = config_cmd(sbh, bus, dev, func, off)) == 0) ||
242 ((reg = (uint32 *) REG_MAP(addr, len)) == 0) ||
243 (BUSPROBE(val, reg) != 0)) {
244 PCI_MSG(("%s: Failed to write!\n", __FUNCTION__));
245 goto done;
248 if (len == 4)
249 val = *((uint32 *) buf);
250 else if (len == 2) {
251 val &= ~(0xffff << (8 * (off & 3)));
252 val |= *((uint16 *) buf) << (8 * (off & 3));
253 } else if (len == 1) {
254 val &= ~(0xff << (8 * (off & 3)));
255 val |= *((uint8 *) buf) << (8 * (off & 3));
256 } else {
257 ret = -1;
258 goto done;
261 PCI_MSG(("%s: 0x%x => 0x%p\n", __FUNCTION__, val, reg));
263 W_REG(osh, reg, val);
265 done:
266 if (reg && addr)
267 REG_UNMAP(reg);
269 return ret;
273 * Must access emulated PCI configuration at these locations even when
274 * the real PCI config space exists and is accessible.
276 * PCI_CFG_VID (0x00)
277 * PCI_CFG_DID (0x02)
278 * PCI_CFG_PROGIF (0x09)
279 * PCI_CFG_SUBCL (0x0a)
280 * PCI_CFG_BASECL (0x0b)
281 * PCI_CFG_HDR (0x0e)
282 * PCI_CFG_INT (0x3c)
283 * PCI_CFG_PIN (0x3d)
285 #define FORCE_EMUCFG(off, len) \
286 ((off == PCI_CFG_VID) || (off == PCI_CFG_DID) || \
287 (off == PCI_CFG_PROGIF) || \
288 (off == PCI_CFG_SUBCL) || (off == PCI_CFG_BASECL) || \
289 (off == PCI_CFG_HDR) || \
290 (off == PCI_CFG_INT) || (off == PCI_CFG_PIN))
292 /* Sync the emulation registers and the real PCI config registers. */
293 static void
294 sb_pcid_read_config(sb_t *sbh, uint coreidx, sb_pci_cfg_t *cfg,
295 uint off, uint len)
297 osl_t *osh;
298 uint oldidx;
300 ASSERT(cfg);
301 ASSERT(cfg->emu);
302 ASSERT(cfg->pci);
304 /* decide if real PCI config register access is necessary */
305 if (FORCE_EMUCFG(off, len))
306 return;
308 osh = sb_osh(sbh);
310 /* access to the real pci config space only when the core is up */
311 oldidx = sb_coreidx(sbh);
312 sb_setcoreidx(sbh, coreidx);
313 if (sb_iscoreup(sbh)) {
314 if (len == 4)
315 *(uint32 *)((ulong)cfg->emu + off) =
316 htol32(R_REG(osh, (uint32 *)((ulong)cfg->pci + off)));
317 else if (len == 2)
318 *(uint16 *)((ulong)cfg->emu + off) =
319 htol16(R_REG(osh, (uint16 *)((ulong)cfg->pci + off)));
320 else if (len == 1)
321 *(uint8 *)((ulong)cfg->emu + off) =
322 R_REG(osh, (uint8 *)((ulong)cfg->pci + off));
324 sb_setcoreidx(sbh, oldidx);
327 static void
328 sb_pcid_write_config(sb_t *sbh, uint coreidx, sb_pci_cfg_t *cfg,
329 uint off, uint len)
331 osl_t *osh;
332 uint oldidx;
334 ASSERT(cfg);
335 ASSERT(cfg->emu);
336 ASSERT(cfg->pci);
338 osh = sb_osh(sbh);
340 /* decide if real PCI config register access is necessary */
341 if (FORCE_EMUCFG(off, len))
342 return;
344 /* access to the real pci config space only when the core is up */
345 oldidx = sb_coreidx(sbh);
346 sb_setcoreidx(sbh, coreidx);
347 if (sb_iscoreup(sbh)) {
348 if (len == 4)
349 W_REG(osh, (uint32 *)((ulong)cfg->pci + off),
350 ltoh32(*(uint32 *)((ulong)cfg->emu + off)));
351 else if (len == 2)
352 W_REG(osh, (uint16 *)((ulong)cfg->pci + off),
353 ltoh16(*(uint16 *)((ulong)cfg->emu + off)));
354 else if (len == 1)
355 W_REG(osh, (uint8 *)((ulong)cfg->pci + off),
356 *(uint8 *)((ulong)cfg->emu + off));
358 sb_setcoreidx(sbh, oldidx);
362 * Functions for accessing translated SB configuration space
364 static int
365 sb_read_config(sb_t *sbh, uint bus, uint dev, uint func, uint off, void *buf, int len)
367 pci_config_regs *cfg;
369 if (dev >= SB_MAXCORES || func >= MAXFUNCS || (off + len) > sizeof(pci_config_regs))
370 return -1;
371 cfg = sb_pci_cfg[dev][func].emu;
373 ASSERT(ISALIGNED(off, len));
374 ASSERT(ISALIGNED((uintptr)buf, len));
376 /* use special config space if the device does not exist */
377 if (!cfg)
378 cfg = &sb_pci_null;
379 /* sync emulation with real PCI config if necessary */
380 else if (sb_pci_cfg[dev][func].pci)
381 sb_pcid_read_config(sbh, dev, &sb_pci_cfg[dev][func], off, len);
383 if (len == 4)
384 *((uint32 *) buf) = ltoh32(*((uint32 *)((ulong) cfg + off)));
385 else if (len == 2)
386 *((uint16 *) buf) = ltoh16(*((uint16 *)((ulong) cfg + off)));
387 else if (len == 1)
388 *((uint8 *) buf) = *((uint8 *)((ulong) cfg + off));
389 else
390 return -1;
392 return 0;
395 static int
396 sb_write_config(sb_t *sbh, uint bus, uint dev, uint func, uint off, void *buf, int len)
398 uint coreidx;
399 void *regs;
400 pci_config_regs *cfg;
401 osl_t *osh;
402 sb_bar_cfg_t *bar;
404 if (dev >= SB_MAXCORES || func >= MAXFUNCS || (off + len) > sizeof(pci_config_regs))
405 return -1;
406 cfg = sb_pci_cfg[dev][func].emu;
407 if (!cfg)
408 return -1;
410 ASSERT(ISALIGNED(off, len));
411 ASSERT(ISALIGNED((uintptr)buf, len));
413 osh = sb_osh(sbh);
415 /* Emulate BAR sizing */
416 if (off >= OFFSETOF(pci_config_regs, base[0]) &&
417 off <= OFFSETOF(pci_config_regs, base[3]) &&
418 len == 4 && *((uint32 *) buf) == ~0) {
419 coreidx = sb_coreidx(sbh);
420 if ((regs = sb_setcoreidx(sbh, dev))) {
421 bar = sb_pci_cfg[dev][func].bar;
422 /* Highest numbered address match register */
423 if (off == OFFSETOF(pci_config_regs, base[0]))
424 cfg->base[0] = ~(bar->size0 - 1);
425 else if (off == OFFSETOF(pci_config_regs, base[1]) && bar->n >= 1)
426 cfg->base[1] = ~(bar->size1 - 1);
427 else if (off == OFFSETOF(pci_config_regs, base[2]) && bar->n >= 2)
428 cfg->base[2] = ~(bar->size2 - 1);
429 else if (off == OFFSETOF(pci_config_regs, base[3]) && bar->n >= 3)
430 cfg->base[3] = ~(bar->size3 - 1);
432 sb_setcoreidx(sbh, coreidx);
433 } else if (len == 4)
434 *((uint32 *)((ulong) cfg + off)) = htol32(*((uint32 *) buf));
435 else if (len == 2)
436 *((uint16 *)((ulong) cfg + off)) = htol16(*((uint16 *) buf));
437 else if (len == 1)
438 *((uint8 *)((ulong) cfg + off)) = *((uint8 *) buf);
439 else
440 return -1;
442 /* sync emulation with real PCI config if necessary */
443 if (sb_pci_cfg[dev][func].pci)
444 sb_pcid_write_config(sbh, dev, &sb_pci_cfg[dev][func], off, len);
446 return 0;
450 sbpci_read_config(sb_t *sbh, uint bus, uint dev, uint func, uint off, void *buf, int len)
452 if (bus == 0)
453 return sb_read_config(sbh, bus, dev, func, off, buf, len);
454 else
455 return extpci_read_config(sbh, bus, dev, func, off, buf, len);
459 sbpci_write_config(sb_t *sbh, uint bus, uint dev, uint func, uint off, void *buf, int len)
461 if (bus == 0)
462 return sb_write_config(sbh, bus, dev, func, off, buf, len);
463 else
464 return extpci_write_config(sbh, bus, dev, func, off, buf, len);
467 void
468 sbpci_ban(uint16 core)
470 if (pci_banned < ARRAYSIZE(pci_ban))
471 pci_ban[pci_banned++] = core;
475 * Initiliaze PCI core. Return 0 after a successful initialization.
476 * Otherwise return -1 to indicate there is no PCI core and return 1
477 * to indicate PCI core is disabled.
479 int __init
480 sbpci_init_pci(sb_t *sbh)
482 uint chip, chiprev, chippkg, host;
483 uint32 boardflags;
484 sbpciregs_t *pci;
485 sbconfig_t *sb;
486 uint32 val;
487 int ret = 0;
488 char *hbslot;
489 osl_t *osh;
491 chip = sb_chip(sbh);
492 chiprev = sb_chiprev(sbh);
493 chippkg = sb_chippkg(sbh);
495 osh = sb_osh(sbh);
497 if (!(pci = (sbpciregs_t *) sb_setcore(sbh, SB_PCI, 0))) {
498 printf("PCI: no core\n");
499 pci_disabled = TRUE;
500 return -1;
502 sb = (sbconfig_t *)((ulong) pci + SBCONFIGOFF);
504 boardflags = (uint32) getintvar(NULL, "boardflags");
507 * The 200-pin BCM4712 package does not bond out PCI. Even when
508 * PCI is bonded out, some boards may leave the pins
509 * floating.
511 if (((chip == BCM4712_CHIP_ID) &&
512 ((chippkg == BCM4712SMALL_PKG_ID) ||
513 (chippkg == BCM4712MID_PKG_ID))) ||
514 (boardflags & BFL_NOPCI))
515 pci_disabled = TRUE;
517 /* Enable the core */
518 sb_core_reset(sbh, 0, 0);
521 * If the PCI core should not be touched (disabled, not bonded
522 * out, or pins floating), do not even attempt to access core
523 * registers. Otherwise, try to determine if it is in host
524 * mode.
526 if (pci_disabled)
527 host = 0;
528 else
529 host = !BUSPROBE(val, &pci->control);
531 if (!host) {
532 ret = 1;
534 /* Disable PCI interrupts in client mode */
535 W_REG(osh, &sb->sbintvec, 0);
537 /* Disable the PCI bridge in client mode */
538 sbpci_ban(SB_PCI);
539 sb_core_disable(sbh, 0);
541 printf("PCI: Disabled\n");
542 } else {
543 printf("PCI: Initializing host\n");
545 /* Disable PCI SBReqeustTimeout for BCM4785 rev. < 2 */
546 if (chip == BCM4785_CHIP_ID && chiprev < 2) {
547 AND_REG(osh, &sb->sbimconfiglow, ~0x00000070);
548 sb_commit(sbh);
551 /* Reset the external PCI bus and enable the clock */
552 W_REG(osh, &pci->control, 0x5); /* enable the tristate drivers */
553 W_REG(osh, &pci->control, 0xd); /* enable the PCI clock */
554 OSL_DELAY(150); /* delay > 100 us */
555 W_REG(osh, &pci->control, 0xf); /* deassert PCI reset */
556 /* Use internal arbiter and park REQ/GRNT at external master 0
557 * We will set it later after the bus has been probed
559 W_REG(osh, &pci->arbcontrol, PCI_INT_ARB);
560 OSL_DELAY(1); /* delay 1 us */
562 /* Enable CardBusMode */
563 cardbus = getintvar(NULL, "cardbus") == 1;
564 if (cardbus) {
565 printf("PCI: Enabling CardBus\n");
566 /* GPIO 1 resets the CardBus device on bcm94710ap */
567 sb_gpioout(sbh, 1, 1, GPIO_DRV_PRIORITY);
568 sb_gpioouten(sbh, 1, 1, GPIO_DRV_PRIORITY);
569 W_REG(osh, &pci->sprom[0], R_REG(osh, &pci->sprom[0]) | 0x400);
572 /* 64 MB I/O access window */
573 W_REG(osh, &pci->sbtopci0, SBTOPCI_IO);
574 /* 64 MB configuration access window */
575 W_REG(osh, &pci->sbtopci1, SBTOPCI_CFG0);
576 /* 1 GB memory access window */
577 W_REG(osh, &pci->sbtopci2, SBTOPCI_MEM | SB_PCI_DMA);
579 /* Host bridge slot # nvram overwrite */
580 if ((hbslot = nvram_get("pcihbslot"))) {
581 pci_hbslot = bcm_strtoul(hbslot, NULL, 0);
582 ASSERT(pci_hbslot < PCI_MAX_DEVICES);
585 /* Enable PCI bridge BAR0 prefetch and burst */
586 val = 6;
587 sbpci_write_config(sbh, 1, pci_hbslot, 0, PCI_CFG_CMD, &val, sizeof(val));
589 /* Enable PCI interrupts */
590 W_REG(osh, &pci->intmask, PCI_INTA);
593 return ret;
596 void
597 sbpci_arb_park(sb_t *sbh, uint parkid)
599 sbpciregs_t *pci;
600 uint pcirev;
601 uint32 arb;
603 if (!(pci = (sbpciregs_t *) sb_setcore(sbh, SB_PCI, 0))) {
604 /* Should not happen */
605 printf("%s: no PCI core\n", __FUNCTION__);
606 return;
609 pcirev = sb_corerev(sbh);
611 /* Nothing to do, not supported for these revs */
612 if (pcirev < 8)
613 return;
615 /* Get parkid from NVRAM */
616 if (parkid == PCI_PARK_NVRAM) {
617 parkid = getintvar(NULL, "parkid");
618 if (getvar(NULL, "parkid") == NULL)
619 /* Not present in NVRAM use defaults */
620 parkid = (pcirev >= 11) ? PCI11_PARKID_LAST : PCI_PARKID_LAST;
623 /* Check the parkid is valid, if not set it to default */
624 if (parkid > ((pcirev >= 11) ? PCI11_PARKID_LAST : PCI_PARKID_LAST)) {
625 printf("%s: Invalid parkid %d\n", __FUNCTION__, parkid);
626 parkid = (pcirev >= 11) ? PCI11_PARKID_LAST : PCI_PARKID_LAST;
629 /* Now set the parkid */
630 arb = R_REG(sb_osh(sbh), &pci->arbcontrol);
631 arb &= ~PCI_PARKID_MASK;
632 arb |= parkid << PCI_PARKID_SHIFT;
633 W_REG(sb_osh(sbh), &pci->arbcontrol, arb);
634 OSL_DELAY(1);
638 * Get the PCI region address and size information.
640 static void __init
641 sbpci_init_regions(sb_t *sbh, uint func, pci_config_regs *cfg, sb_bar_cfg_t *bar)
643 osl_t *osh;
644 uint16 coreid;
645 void *regs;
646 sbconfig_t *sb;
647 uint32 base;
649 osh = sb_osh(sbh);
650 coreid = sb_coreid(sbh);
651 regs = sb_coreregs(sbh);
652 sb = (sbconfig_t *)((ulong) regs + SBCONFIGOFF);
654 switch (coreid) {
655 case SB_USB20H:
656 base = htol32(sb_base(R_REG(osh, &sb->sbadmatch0)));
658 cfg->base[0] = func == 0 ? base : base + 0x800; /* OHCI/EHCI */
659 cfg->base[1] = 0;
660 cfg->base[2] = 0;
661 cfg->base[3] = 0;
662 cfg->base[4] = 0;
663 cfg->base[5] = 0;
664 bar->n = 1;
665 bar->size0 = func == 0 ? 0x200 : 0x100; /* OHCI/EHCI */
666 bar->size1 = 0;
667 bar->size2 = 0;
668 bar->size3 = 0;
669 break;
670 default:
671 cfg->base[0] = htol32(sb_base(R_REG(osh, &sb->sbadmatch0)));
672 cfg->base[1] = htol32(sb_base(R_REG(osh, &sb->sbadmatch1)));
673 cfg->base[2] = htol32(sb_base(R_REG(osh, &sb->sbadmatch2)));
674 cfg->base[3] = htol32(sb_base(R_REG(osh, &sb->sbadmatch3)));
675 cfg->base[4] = 0;
676 cfg->base[5] = 0;
677 bar->n = (R_REG(osh, &sb->sbidlow) & SBIDL_AR_MASK) >> SBIDL_AR_SHIFT;
678 bar->size0 = sb_size(R_REG(osh, &sb->sbadmatch0));
679 bar->size1 = sb_size(R_REG(osh, &sb->sbadmatch1));
680 bar->size2 = sb_size(R_REG(osh, &sb->sbadmatch2));
681 bar->size3 = sb_size(R_REG(osh, &sb->sbadmatch3));
682 break;
687 * Construct PCI config spaces for SB cores so that they
688 * can be accessed as if they were PCI devices.
690 void __init
691 sbpci_init_cores(sb_t *sbh)
693 uint chiprev, coreidx, i;
694 sbconfig_t *sb;
695 pci_config_regs *cfg, *pci;
696 sb_bar_cfg_t *bar;
697 void *regs;
698 osl_t *osh;
699 uint16 vendor, device;
700 uint16 coreid;
701 uint8 class, subclass, progif;
702 uint dev;
703 uint8 header;
704 uint func;
706 chiprev = sb_chiprev(sbh);
707 coreidx = sb_coreidx(sbh);
709 osh = sb_osh(sbh);
711 /* Scan the SB bus */
712 bzero(sb_config_regs, sizeof(sb_config_regs));
713 bzero(sb_bar_cfg, sizeof(sb_bar_cfg));
714 bzero(sb_pci_cfg, sizeof(sb_pci_cfg));
715 memset(&sb_pci_null, -1, sizeof(sb_pci_null));
716 cfg = sb_config_regs;
717 bar = sb_bar_cfg;
718 for (dev = 0; dev < SB_MAXCORES; dev ++) {
719 /* Check if the core exists */
720 if (!(regs = sb_setcoreidx(sbh, dev)))
721 continue;
722 sb = (sbconfig_t *)((ulong) regs + SBCONFIGOFF);
724 /* Check if this core is banned */
725 coreid = sb_coreid(sbh);
726 for (i = 0; i < pci_banned; i++)
727 if (coreid == pci_ban[i])
728 break;
729 if (i < pci_banned)
730 continue;
732 for (func = 0; func < MAXFUNCS; ++func) {
733 /* Make sure we won't go beyond the limit */
734 if (cfg >= &sb_config_regs[SB_MAXCORES]) {
735 printf("PCI: too many emulated devices\n");
736 goto done;
739 /* Convert core id to pci id */
740 if (sb_corepciid(sbh, func, &vendor, &device, &class, &subclass,
741 &progif, &header))
742 continue;
745 * Differentiate real PCI config from emulated.
746 * non zero 'pci' indicate there is a real PCI config space
747 * for this device.
749 switch (device) {
750 case BCM47XX_GIGETH_ID:
751 pci = (pci_config_regs *)((uint32)regs + 0x800);
752 break;
753 case BCM47XX_SATAXOR_ID:
754 pci = (pci_config_regs *)((uint32)regs + 0x400);
755 break;
756 case BCM47XX_ATA100_ID:
757 pci = (pci_config_regs *)((uint32)regs + 0x800);
758 break;
759 default:
760 pci = NULL;
761 break;
763 /* Supported translations */
764 cfg->vendor = htol16(vendor);
765 cfg->device = htol16(device);
766 cfg->rev_id = chiprev;
767 cfg->prog_if = progif;
768 cfg->sub_class = subclass;
769 cfg->base_class = class;
770 cfg->header_type = header;
771 sbpci_init_regions(sbh, func, cfg, bar);
772 /* Save core interrupt flag */
773 cfg->int_pin = R_REG(osh, &sb->sbtpsflag) & SBTPS_NUM0_MASK;
774 /* Save core interrupt assignment */
775 cfg->int_line = sb_irq(sbh);
776 /* Indicate there is no SROM */
777 *((uint32 *) &cfg->sprom_control) = 0xffffffff;
779 /* Point to the PCI config spaces */
780 sb_pci_cfg[dev][func].emu = cfg;
781 sb_pci_cfg[dev][func].pci = pci;
782 sb_pci_cfg[dev][func].bar = bar;
783 cfg ++;
784 bar ++;
788 done:
789 sb_setcoreidx(sbh, coreidx);
793 * Initialize PCI core and construct PCI config spaces for SB cores.
794 * Must propagate sbpci_init_pci() return value to the caller to let
795 * them know the PCI core initialization status.
797 int __init
798 sbpci_init(sb_t *sbh)
800 int status = sbpci_init_pci(sbh);
801 sbpci_init_cores(sbh);
802 return status;