2 * Low-Level PCI and SI support for BCM47xx
4 * Copyright (C) 2009, Broadcom Corporation
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: hndpci.c,v 1.36.2.8 2009/06/16 22:41:34 Exp $
23 #include <pcie_core.h>
24 #include <bcmendian.h>
30 /* For now we need some real Silicon Backplane utils */
31 #include "siutils_priv.h"
35 #define PCI_MSG(args) printf args
40 /* to free some function memory after boot */
45 /* Emulated configuration space */
48 uint size
[PCI_BAR_MAX
];
50 static pci_config_regs si_config_regs
[SI_MAXCORES
];
51 static si_bar_cfg_t si_bar_cfg
[SI_MAXCORES
];
53 /* Links to emulated and real PCI configuration spaces */
56 pci_config_regs
*emu
; /* emulated PCI config */
57 pci_config_regs
*pci
; /* real PCI config */
58 si_bar_cfg_t
*bar
; /* region sizes */
60 static si_pci_cfg_t si_pci_cfg
[SI_MAXCORES
][MAXFUNCS
];
62 /* Special emulated config space for non-existing device */
63 static pci_config_regs si_pci_null
= { 0xffff, 0xffff };
66 static uint16 pci_ban
[SI_MAXCORES
] = { 0 };
67 static uint pci_banned
= 0;
70 static bool cardbus
= FALSE
;
72 /* Disable PCI host core */
73 static bool pci_disabled
= FALSE
;
75 /* Host bridge slot #, default to 0 */
76 static uint8 pci_hbslot
= 0;
79 #define PCI_SLOTAD_MAP 16 /* SLOT<n> mapps to AD<n+16> */
80 #define PCI_HBSBCFG_REV 8 /* MIN corerev to access host bridge PCI cfg space from SB */
82 /* Functions for accessing external PCI configuration space, Assume one-hot slot wiring */
83 #define PCI_SLOT_MAX 16 /* Max. PCI Slots */
86 config_cmd(si_t
*sih
, uint bus
, uint dev
, uint func
, uint off
)
90 uint32 addr
= 0, *sbtopci1
;
93 /* CardBusMode supports only one device */
94 if (cardbus
&& dev
> 1)
99 coreidx
= si_coreidx(sih
);
100 pci
= (sbpciregs_t
*)si_setcore(sih
, PCI_CORE_ID
, 0);
103 sbtopci1
= &pci
->sbtopci1
;
107 pcie
= (sbpcieregs_t
*)si_setcore(sih
, PCIE_CORE_ID
, 0);
109 /* Issue config commands only when the data link is up (atleast
110 * one external pcie device is present).
112 if (pcie
&& (dev
< 2) &&
113 (pcie_readreg(osh
, pcie
, PCIE_PCIEREGS
,
114 PCIE_DLLP_LSREG
) & PCIE_DLLP_LSREG_LINKUP
)) {
115 sbtopci1
= &pcie
->sbtopcie1
;
117 si_setcoreidx(sih
, coreidx
);
123 /* Type 0 transaction */
125 /* Skip unwired slots */
126 if (dev
< PCI_SLOT_MAX
) {
127 /* Slide the PCI window to the appropriate slot */
131 win
= (SBTOPCI_CFG0
|
132 ((1 << (dev
+ PCI_SLOTAD_MAP
)) & SBTOPCI1_MASK
));
133 W_REG(osh
, sbtopci1
, win
);
135 ((1 << (dev
+ PCI_SLOTAD_MAP
)) & ~SBTOPCI1_MASK
) |
136 (func
<< PCICFG_FUN_SHIFT
) |
139 W_REG(osh
, sbtopci1
, SBTOPCI_CFG0
);
141 (dev
<< PCIECFG_SLOT_SHIFT
) |
142 (func
<< PCIECFG_FUN_SHIFT
) |
147 /* Type 1 transaction */
148 W_REG(osh
, sbtopci1
, SBTOPCI_CFG1
);
150 (pci
? PCI_CONFIG_ADDR(bus
, dev
, func
, (off
& ~3)) :
151 PCIE_CONFIG_ADDR((bus
- 1), dev
, func
, (off
& ~3))));
154 si_setcoreidx(sih
, coreidx
);
160 * Read host bridge PCI config registers from Silicon Backplane ( >= rev8 ).
162 * It returns TRUE to indicate that access to the host bridge's pci config
163 * from SI is ok, and values in 'addr' and 'val' are valid.
165 * It can only read registers at multiple of 4-bytes. Callers must pick up
166 * needed bytes from 'val' based on 'off' value. Value in 'addr' reflects
167 * the register address where value in 'val' is read.
170 si_pcihb_read_config(si_t
*sih
, uint bus
, uint dev
, uint func
, uint off
, uint32
**addr
,
180 ASSERT(dev
== pci_hbslot
);
182 /* we support only two functions on device 0 */
188 /* read pci config when core rev >= 8 */
189 coreidx
= si_coreidx(sih
);
190 pci
= (sbpciregs_t
*)si_setcore(sih
, PCI_CORE_ID
, 0);
192 if (si_corerev(sih
) >= PCI_HBSBCFG_REV
) {
193 *addr
= (uint32
*)&pci
->pcicfg
[func
][off
>> 2];
194 *val
= R_REG(osh
, *addr
);
200 /* read pcie config */
201 pcie
= (sbpcieregs_t
*)si_setcore(sih
, PCIE_CORE_ID
, 0);
203 /* accesses to config registers with offsets >= 256
204 * requires indirect access.
207 *val
= pcie_readreg(osh
, pcie
, PCIE_CONFIGREGS
,
208 PCIE_CONFIG_INDADDR(func
, off
));
210 *addr
= (uint32
*)&pcie
->pciecfg
[func
][off
>> 2];
211 *val
= R_REG(osh
, *addr
);
217 si_setcoreidx(sih
, coreidx
);
223 extpci_read_config(si_t
*sih
, uint bus
, uint dev
, uint func
, uint off
, void *buf
, int len
)
225 uint32 addr
= 0, *reg
= NULL
, val
;
229 * Set value to -1 when:
230 * flag 'pci_disabled' is true;
231 * value of 'addr' is zero;
237 else if (bus
== 1 && dev
== pci_hbslot
) {
238 if (!si_pcihb_read_config(sih
, bus
, dev
, func
, off
, ®
, &val
))
240 } else if (((addr
= config_cmd(sih
, bus
, dev
, func
, off
)) == 0) ||
241 ((reg
= (uint32
*)REG_MAP(addr
, len
)) == 0) ||
242 (BUSPROBE(val
, reg
) != 0)) {
243 PCI_MSG(("%s: Failed to read!\n", __FUNCTION__
));
247 PCI_MSG(("%s: 0x%x <= 0x%p(0x%x), len %d, off 0x%x, buf 0x%p\n",
248 __FUNCTION__
, val
, reg
, addr
, len
, off
, buf
));
250 val
>>= 8 * (off
& 3);
252 *((uint32
*)buf
) = val
;
254 *((uint16
*)buf
) = (uint16
) val
;
256 *((uint8
*)buf
) = (uint8
) val
;
267 extpci_write_config(si_t
*sih
, uint bus
, uint dev
, uint func
, uint off
, void *buf
, int len
)
270 uint32 addr
= 0, *reg
= NULL
, val
;
276 * Ignore write attempt when:
277 * flag 'pci_disabled' is true;
278 * value of 'addr' is zero;
284 else if (bus
== 1 && dev
== pci_hbslot
) {
285 if (!si_pcihb_read_config(sih
, bus
, dev
, func
, off
, ®
, &val
))
287 } else if (((addr
= config_cmd(sih
, bus
, dev
, func
, off
)) == 0) ||
288 ((reg
= (uint32
*)REG_MAP(addr
, len
)) == 0) ||
289 (BUSPROBE(val
, reg
) != 0)) {
290 PCI_MSG(("%s: Failed to write!\n", __FUNCTION__
));
295 val
= *((uint32
*)buf
);
297 val
&= ~(0xffff << (8 * (off
& 3)));
298 val
|= *((uint16
*)buf
) << (8 * (off
& 3));
299 } else if (len
== 1) {
300 val
&= ~(0xff << (8 * (off
& 3)));
301 val
|= *((uint8
*)buf
) << (8 * (off
& 3));
307 PCI_MSG(("%s: 0x%x => 0x%p\n", __FUNCTION__
, val
, reg
));
309 if (bus
== 1 && dev
== pci_hbslot
&& reg
== NULL
) {
313 coreidx
= si_coreidx(sih
);
315 /* read pcie config */
316 pcie
= (sbpcieregs_t
*)si_setcore(sih
, PCIE_CORE_ID
, 0);
318 /* accesses to config registers with offsets >= 256
319 * requires indirect access.
321 pcie_writereg(osh
, pcie
, PCIE_CONFIGREGS
,
322 PCIE_CONFIG_INDADDR(func
, off
), val
);
324 si_setcoreidx(sih
, coreidx
);
326 W_REG(osh
, reg
, val
);
328 if ((sih
->chip
== BCM4716_CHIP_ID
) || (sih
->chip
== BCM4748_CHIP_ID
))
329 (void)R_REG(osh
, reg
);
340 * Must access emulated PCI configuration at these locations even when
341 * the real PCI config space exists and is accessible.
345 * PCI_CFG_PROGIF (0x09)
346 * PCI_CFG_SUBCL (0x0a)
347 * PCI_CFG_BASECL (0x0b)
352 #define FORCE_EMUCFG(off, len) \
353 ((off == PCI_CFG_VID) || (off == PCI_CFG_DID) || \
354 (off == PCI_CFG_PROGIF) || \
355 (off == PCI_CFG_SUBCL) || (off == PCI_CFG_BASECL) || \
356 (off == PCI_CFG_HDR) || \
357 (off == PCI_CFG_INT) || (off == PCI_CFG_PIN))
359 /* Sync the emulation registers and the real PCI config registers. */
361 si_pcid_read_config(si_t
*sih
, uint coreidx
, si_pci_cfg_t
*cfg
, uint off
, uint len
)
370 /* decide if real PCI config register access is necessary */
371 if (FORCE_EMUCFG(off
, len
))
376 /* access to the real pci config space only when the core is up */
377 oldidx
= si_coreidx(sih
);
378 si_setcoreidx(sih
, coreidx
);
379 if (si_iscoreup(sih
)) {
381 *(uint32
*)((ulong
)cfg
->emu
+ off
) =
382 htol32(R_REG(osh
, (uint32
*)((ulong
)cfg
->pci
+ off
)));
384 *(uint16
*)((ulong
)cfg
->emu
+ off
) =
385 htol16(R_REG(osh
, (uint16
*)((ulong
)cfg
->pci
+ off
)));
387 *(uint8
*)((ulong
)cfg
->emu
+ off
) =
388 R_REG(osh
, (uint8
*)((ulong
)cfg
->pci
+ off
));
390 si_setcoreidx(sih
, oldidx
);
394 si_pcid_write_config(si_t
*sih
, uint coreidx
, si_pci_cfg_t
*cfg
, uint off
, uint len
)
405 /* decide if real PCI config register access is necessary */
406 if (FORCE_EMUCFG(off
, len
))
409 /* access to the real pci config space only when the core is up */
410 oldidx
= si_coreidx(sih
);
411 si_setcoreidx(sih
, coreidx
);
412 if (si_iscoreup(sih
)) {
414 W_REG(osh
, (uint32
*)((ulong
)cfg
->pci
+ off
),
415 ltoh32(*(uint32
*)((ulong
)cfg
->emu
+ off
)));
417 W_REG(osh
, (uint16
*)((ulong
)cfg
->pci
+ off
),
418 ltoh16(*(uint16
*)((ulong
)cfg
->emu
+ off
)));
420 W_REG(osh
, (uint8
*)((ulong
)cfg
->pci
+ off
),
421 *(uint8
*)((ulong
)cfg
->emu
+ off
));
423 si_setcoreidx(sih
, oldidx
);
427 * Functions for accessing translated SI configuration space
430 si_read_config(si_t
*sih
, uint bus
, uint dev
, uint func
, uint off
, void *buf
, int len
)
432 pci_config_regs
*cfg
;
434 if (dev
>= SI_MAXCORES
|| func
>= MAXFUNCS
|| (off
+ len
) > sizeof(pci_config_regs
))
437 cfg
= si_pci_cfg
[dev
][func
].emu
;
439 ASSERT(ISALIGNED(off
, len
));
440 ASSERT(ISALIGNED((uintptr
)buf
, len
));
442 /* use special config space if the device does not exist */
445 /* sync emulation with real PCI config if necessary */
446 else if (si_pci_cfg
[dev
][func
].pci
)
447 si_pcid_read_config(sih
, dev
, &si_pci_cfg
[dev
][func
], off
, len
);
450 *((uint32
*)buf
) = ltoh32(*((uint32
*)((ulong
) cfg
+ off
)));
452 *((uint16
*)buf
) = ltoh16(*((uint16
*)((ulong
) cfg
+ off
)));
454 *((uint8
*)buf
) = *((uint8
*)((ulong
) cfg
+ off
));
462 si_write_config(si_t
*sih
, uint bus
, uint dev
, uint func
, uint off
, void *buf
, int len
)
466 pci_config_regs
*cfg
;
470 if (dev
>= SI_MAXCORES
|| func
>= MAXFUNCS
|| (off
+ len
) > sizeof(pci_config_regs
))
472 cfg
= si_pci_cfg
[dev
][func
].emu
;
476 ASSERT(ISALIGNED(off
, len
));
477 ASSERT(ISALIGNED((uintptr
)buf
, len
));
481 /* Emulate BAR sizing */
482 if (off
>= OFFSETOF(pci_config_regs
, base
[0]) &&
483 off
<= OFFSETOF(pci_config_regs
, base
[3]) &&
484 len
== 4 && *((uint32
*)buf
) == ~0) {
485 coreidx
= si_coreidx(sih
);
486 if ((regs
= si_setcoreidx(sih
, dev
))) {
487 bar
= si_pci_cfg
[dev
][func
].bar
;
488 /* Highest numbered address match register */
489 if (off
== OFFSETOF(pci_config_regs
, base
[0]))
490 cfg
->base
[0] = ~(bar
->size
[0] - 1);
491 else if (off
== OFFSETOF(pci_config_regs
, base
[1]) && bar
->n
>= 1)
492 cfg
->base
[1] = ~(bar
->size
[1] - 1);
493 else if (off
== OFFSETOF(pci_config_regs
, base
[2]) && bar
->n
>= 2)
494 cfg
->base
[2] = ~(bar
->size
[2] - 1);
495 else if (off
== OFFSETOF(pci_config_regs
, base
[3]) && bar
->n
>= 3)
496 cfg
->base
[3] = ~(bar
->size
[3] - 1);
498 si_setcoreidx(sih
, coreidx
);
500 *((uint32
*)((ulong
) cfg
+ off
)) = htol32(*((uint32
*)buf
));
502 *((uint16
*)((ulong
) cfg
+ off
)) = htol16(*((uint16
*)buf
));
504 *((uint8
*)((ulong
) cfg
+ off
)) = *((uint8
*)buf
);
508 /* sync emulation with real PCI config if necessary */
509 if (si_pci_cfg
[dev
][func
].pci
)
510 si_pcid_write_config(sih
, dev
, &si_pci_cfg
[dev
][func
], off
, len
);
516 hndpci_read_config(si_t
*sih
, uint bus
, uint dev
, uint func
, uint off
, void *buf
, int len
)
519 return si_read_config(sih
, bus
, dev
, func
, off
, buf
, len
);
521 return extpci_read_config(sih
, bus
, dev
, func
, off
, buf
, len
);
525 hndpci_write_config(si_t
*sih
, uint bus
, uint dev
, uint func
, uint off
, void *buf
, int len
)
528 return si_write_config(sih
, bus
, dev
, func
, off
, buf
, len
);
530 return extpci_write_config(sih
, bus
, dev
, func
, off
, buf
, len
);
534 hndpci_ban(uint16 core
)
536 if (pci_banned
< ARRAYSIZE(pci_ban
))
537 pci_ban
[pci_banned
++] = core
;
540 /* return cap_offset if requested capability exists in the PCI config space */
542 hndpci_find_pci_capability(si_t
*sih
, uint bus
, uint dev
, uint func
,
543 uint8 req_cap_id
, uchar
*buf
, uint32
*buflen
)
550 /* check for Header type 0 */
551 hndpci_read_config(sih
, bus
, dev
, func
, PCI_CFG_HDR
, &byte_val
, sizeof(uint8
));
552 if ((byte_val
& 0x7f) != PCI_HEADER_NORMAL
)
555 /* check if the capability pointer field exists */
556 hndpci_read_config(sih
, bus
, dev
, func
, PCI_CFG_STAT
, &byte_val
, sizeof(uint8
));
557 if (!(byte_val
& PCI_CAPPTR_PRESENT
))
560 /* check if the capability pointer is 0x00 */
561 hndpci_read_config(sih
, bus
, dev
, func
, PCI_CFG_CAPPTR
, &cap_ptr
, sizeof(uint8
));
565 /* loop thr'u the capability list and see if the requested capabilty exists */
566 hndpci_read_config(sih
, bus
, dev
, func
, cap_ptr
, &cap_id
, sizeof(uint8
));
567 while (cap_id
!= req_cap_id
) {
568 hndpci_read_config(sih
, bus
, dev
, func
, cap_ptr
+ 1, &cap_ptr
, sizeof(uint8
));
571 hndpci_read_config(sih
, bus
, dev
, func
, cap_ptr
, &cap_id
, sizeof(uint8
));
574 /* found the caller requested capability */
575 if ((buf
!= NULL
) && (buflen
!= NULL
)) {
584 /* copy the cpability data excluding cap ID and next ptr */
585 cap_data
= cap_ptr
+ 2;
586 if ((bufsize
+ cap_data
) > SZPCR
)
587 bufsize
= SZPCR
- cap_data
;
590 hndpci_read_config(sih
, bus
, dev
, func
, cap_data
, buf
, sizeof(uint8
));
601 * Initiliaze PCI core.
602 * Return 0 after a successful initialization.
603 * Otherwise return -1 to indicate there is no PCI core and
604 * return 1 to indicate PCI core is disabled.
607 hndpci_init_pci(si_t
*sih
)
609 uint chip
, chiprev
, chippkg
, host
;
612 sbpcieregs_t
*pcie
= NULL
;
619 chiprev
= sih
->chiprev
;
620 chippkg
= sih
->chippkg
;
624 pci
= (sbpciregs_t
*)si_setcore(sih
, PCI_CORE_ID
, 0);
626 pcie
= (sbpcieregs_t
*)si_setcore(sih
, PCIE_CORE_ID
, 0);
628 printf("PCI: no core\n");
634 boardflags
= (uint32
)getintvar(NULL
, "boardflags");
637 * The NOPCI boardflag indicates we should not touch the PCI core,
638 * it may not be bonded out or the pins may be floating.
639 * The 200-pin BCM4712 package does not bond out PCI, and routers
640 * based on it did not use the boardflag.
642 if ((boardflags
& BFL_NOPCI
) ||
643 ((chip
== BCM4712_CHIP_ID
) &&
644 ((chippkg
== BCM4712SMALL_PKG_ID
) || (chippkg
== BCM4712MID_PKG_ID
)))) {
648 /* Enable the core */
649 si_core_reset(sih
, 0, 0);
651 /* Figure out if it is in host mode */
652 host
= !BUSPROBE(val
, (pci
? &pci
->control
: &pcie
->control
));
658 /* Disable PCI interrupts in client mode */
661 /* Disable the PCI bridge in client mode */
662 hndpci_ban(PCI_CORE_ID
);
664 /* Make sure the core is disabled */
665 si_core_disable(sih
, 0);
667 /* On 4716 (and other AXI chips?) make sure the slave wrapper
668 * is also put in reset.
670 if ((chip
== BCM4716_CHIP_ID
) || (chip
== BCM4748_CHIP_ID
)) {
673 resetctrl
= (uint32
*)OSL_UNCACHED(SI_WRAP_BASE
+ (9 * SI_CORE_SIZE
) +
675 W_REG(osh
, resetctrl
, AIRC_RESET
);
678 printf("PCI: Disabled\n");
680 printf("PCI: Initializing host\n");
682 /* Disable PCI SBReqeustTimeout for BCM4785 rev. < 2 */
683 if (chip
== BCM4785_CHIP_ID
&& chiprev
< 2) {
685 sb
= (sbconfig_t
*)((ulong
) pci
+ SBCONFIGOFF
);
686 AND_REG(osh
, &sb
->sbimconfiglow
, ~0x00000070);
691 /* Reset the external PCI bus and enable the clock */
692 W_REG(osh
, &pci
->control
, 0x5); /* enable tristate drivers */
693 W_REG(osh
, &pci
->control
, 0xd); /* enable the PCI clock */
694 OSL_DELAY(150); /* delay > 100 us */
695 W_REG(osh
, &pci
->control
, 0xf); /* deassert PCI reset */
696 /* Use internal arbiter and park REQ/GRNT at external master 0
697 * We will set it later after the bus has been probed
699 W_REG(osh
, &pci
->arbcontrol
, PCI_INT_ARB
);
700 OSL_DELAY(1); /* delay 1 us */
702 printf("PCI: Reset RC\n");
704 W_REG(osh
, &pcie
->control
, PCIE_RST_OE
);
705 OSL_DELAY(1000); /* delay 1 ms */
706 W_REG(osh
, &pcie
->control
, PCIE_RST
| PCIE_RST_OE
);
709 /* Enable CardBusMode */
710 cardbus
= getintvar(NULL
, "cardbus") == 1;
712 printf("PCI: Enabling CardBus\n");
713 /* GPIO 1 resets the CardBus device on bcm94710ap */
714 si_gpioout(sih
, 1, 1, GPIO_DRV_PRIORITY
);
715 si_gpioouten(sih
, 1, 1, GPIO_DRV_PRIORITY
);
716 W_REG(osh
, &pci
->sprom
[0], R_REG(osh
, &pci
->sprom
[0]) | 0x400);
719 /* Host bridge slot # nvram overwrite */
720 if ((hbslot
= nvram_get("pcihbslot"))) {
721 pci_hbslot
= bcm_strtoul(hbslot
, NULL
, 0);
722 ASSERT(pci_hbslot
< PCI_MAX_DEVICES
);
726 /* 64 MB I/O access window */
727 W_REG(osh
, &pci
->sbtopci0
, SBTOPCI_IO
);
728 /* 64 MB configuration access window */
729 W_REG(osh
, &pci
->sbtopci1
, SBTOPCI_CFG0
);
730 /* 1 GB memory access window */
731 W_REG(osh
, &pci
->sbtopci2
, SBTOPCI_MEM
| SI_PCI_DMA
);
733 uint8 cap_ptr
, root_ctrl
, root_cap
, dev
;
736 /* 64 MB I/O access window. On 4716, use
737 * sbtopcie0 to access the device registers. We
738 * can't use address match 2 (1 GB window) region
739 * as mips can't generate 64-bit address on the
742 if ((chip
== BCM4716_CHIP_ID
) || (chip
== BCM4748_CHIP_ID
))
743 W_REG(osh
, &pcie
->sbtopcie0
, SBTOPCIE_MEM
| SI_PCI_MEM
);
745 W_REG(osh
, &pcie
->sbtopcie0
, SBTOPCIE_IO
);
747 /* 64 MB configuration access window */
748 W_REG(osh
, &pcie
->sbtopcie1
, SBTOPCIE_CFG0
);
750 /* 1 GB memory access window */
751 W_REG(osh
, &pcie
->sbtopcie2
, SBTOPCIE_MEM
| SI_PCI_DMA
);
753 /* As per PCI Express Base Spec 1.1 we need to wait for
754 * at least 100 ms from the end of a reset (cold/warm/hot)
755 * before issuing configuration requests to PCI Express
760 /* If the root port is capable of returning Config Request
761 * Retry Status (CRS) Completion Status to software then
762 * enable the feature.
764 cap_ptr
= hndpci_find_pci_capability(sih
, 1, pci_hbslot
, 0,
765 PCI_CAP_PCIECAP_ID
, NULL
, NULL
);
768 root_cap
= cap_ptr
+ OFFSETOF(pciconfig_cap_pcie
, root_cap
);
769 hndpci_read_config(sih
, 1, pci_hbslot
, 0, root_cap
,
770 &val16
, sizeof(uint16
));
771 if (val16
& PCIE_RC_CRS_VISIBILITY
) {
772 /* Enable CRS software visibility */
773 root_ctrl
= cap_ptr
+ OFFSETOF(pciconfig_cap_pcie
, root_ctrl
);
774 val16
= PCIE_RC_CRS_EN
;
775 hndpci_write_config(sih
, 1, pci_hbslot
, 0, root_ctrl
,
776 &val16
, sizeof(uint16
));
778 /* Initiate a configuration request to read the vendor id
779 * field of the device function's config space header after
780 * 100 ms wait time from the end of Reset. If the device is
781 * not done with its internal initialization, it must at
782 * least return a completion TLP, with a completion status
783 * of "Configuration Request Retry Status (CRS)". The root
784 * complex must complete the request to the host by returning
785 * a read-data value of 0001h for the Vendor ID field and
786 * all 1s for any additional bytes included in the request.
787 * Poll using the config reads for max wait time of 1 sec or
788 * until we receive the successful completion status. Repeat
789 * the procedure for all the devices.
791 for (dev
= pci_hbslot
+ 1; dev
< PCI_MAX_DEVICES
; dev
++) {
792 SPINWAIT((hndpci_read_config(sih
, 1, dev
, 0,
793 PCI_CFG_VID
, &val16
, sizeof(val16
)),
794 (val16
== 0x1)), 1000000);
796 printf("PCI: Broken device in slot %d\n", dev
);
801 /* Enable PCI bridge BAR0 memory & master access */
802 val
= PCI_CMD_MASTER
| PCI_CMD_MEMORY
;
803 hndpci_write_config(sih
, 1, pci_hbslot
, 0, PCI_CFG_CMD
, &val
, sizeof(val
));
805 /* Enable PCI interrupts */
807 W_REG(osh
, &pci
->intmask
, PCI_INTA
);
809 W_REG(osh
, &pcie
->intmask
, PCI_INTA
);
816 hndpci_arb_park(si_t
*sih
, uint parkid
)
822 pci
= (sbpciregs_t
*)si_setcore(sih
, PCI_CORE_ID
, 0);
823 if ((pci
== NULL
) || pci_disabled
) {
824 /* Should not happen */
825 PCI_MSG(("%s: no PCI core\n", __FUNCTION__
));
829 pcirev
= si_corerev(sih
);
831 /* Nothing to do, not supported for these revs */
835 /* Get parkid from NVRAM */
836 if (parkid
== PCI_PARK_NVRAM
) {
837 parkid
= getintvar(NULL
, "parkid");
838 if (getvar(NULL
, "parkid") == NULL
)
839 /* Not present in NVRAM use defaults */
840 parkid
= (pcirev
>= 11) ? PCI11_PARKID_LAST
: PCI_PARKID_LAST
;
843 /* Check the parkid is valid, if not set it to default */
844 if (parkid
> ((pcirev
>= 11) ? PCI11_PARKID_LAST
: PCI_PARKID_LAST
)) {
845 printf("%s: Invalid parkid %d\n", __FUNCTION__
, parkid
);
846 parkid
= (pcirev
>= 11) ? PCI11_PARKID_LAST
: PCI_PARKID_LAST
;
849 /* Now set the parkid */
850 arb
= R_REG(si_osh(sih
), &pci
->arbcontrol
);
851 arb
&= ~PCI_PARKID_MASK
;
852 arb
|= parkid
<< PCI_PARKID_SHIFT
;
853 W_REG(si_osh(sih
), &pci
->arbcontrol
, arb
);
858 * Get the PCI region address and size information.
861 hndpci_init_regions(si_t
*sih
, uint func
, pci_config_regs
*cfg
, si_bar_cfg_t
*bar
)
863 bool issb
= sih
->socitype
== SOCI_SB
;
866 if (si_coreid(sih
) == USB20H_CORE_ID
) {
869 base
= htol32(si_addrspace(sih
, 0));
871 base1
= base
+ 0x800; /* OHCI/EHCI */
873 /* In AI chips EHCI is addrspace 0, OHCI is 1 */
875 base
= htol32(si_addrspace(sih
, 1));
879 cfg
->base
[0] = func
== 0 ? base
: base1
;
880 bar
->size
[0] = issb
? 0x800 : 0x1000;
882 bar
->n
= n
= si_numaddrspaces(sih
);
883 for (i
= 0; i
< n
; i
++) {
884 int size
= si_addrspacesize(sih
, i
);
887 cfg
->base
[i
] = htol32(si_addrspace(sih
, i
));
892 for (; i
< PCI_BAR_MAX
; i
++) {
899 * Construct PCI config spaces for SB cores to be accessed as if they were PCI devices.
902 hndpci_init_cores(si_t
*sih
)
904 uint chiprev
, coreidx
, i
;
905 pci_config_regs
*cfg
, *pci
;
909 uint16 vendor
, device
;
911 uint8
class, subclass
, progif
;
916 chiprev
= sih
->chiprev
;
917 coreidx
= si_coreidx(sih
);
921 /* Scan the SI bus */
922 bzero(si_config_regs
, sizeof(si_config_regs
));
923 bzero(si_bar_cfg
, sizeof(si_bar_cfg
));
924 bzero(si_pci_cfg
, sizeof(si_pci_cfg
));
925 memset(&si_pci_null
, -1, sizeof(si_pci_null
));
926 cfg
= si_config_regs
;
928 for (dev
= 0; dev
< SI_MAXCORES
; dev
++) {
929 /* Check if the core exists */
930 if (!(regs
= si_setcoreidx(sih
, dev
)))
933 /* Check if this core is banned */
934 coreid
= si_coreid(sih
);
935 for (i
= 0; i
< pci_banned
; i
++)
936 if (coreid
== pci_ban
[i
])
941 for (func
= 0; func
< MAXFUNCS
; ++func
) {
942 /* Make sure we won't go beyond the limit */
943 if (cfg
>= &si_config_regs
[SI_MAXCORES
]) {
944 printf("PCI: too many emulated devices\n");
948 /* Convert core id to pci id */
949 if (si_corepciid(sih
, func
, &vendor
, &device
, &class, &subclass
,
954 * Differentiate real PCI config from emulated.
955 * non zero 'pci' indicate there is a real PCI config space
959 case BCM47XX_GIGETH_ID
:
960 pci
= (pci_config_regs
*)((uint32
)regs
+ 0x800);
962 case BCM47XX_SATAXOR_ID
:
963 pci
= (pci_config_regs
*)((uint32
)regs
+ 0x400);
965 case BCM47XX_ATA100_ID
:
966 pci
= (pci_config_regs
*)((uint32
)regs
+ 0x800);
972 /* Supported translations */
973 cfg
->vendor
= htol16(vendor
);
974 cfg
->device
= htol16(device
);
975 cfg
->rev_id
= chiprev
;
976 cfg
->prog_if
= progif
;
977 cfg
->sub_class
= subclass
;
978 cfg
->base_class
= class;
979 cfg
->header_type
= header
;
980 hndpci_init_regions(sih
, func
, cfg
, bar
);
981 /* Save core interrupt flag */
982 cfg
->int_pin
= si_flag(sih
);
983 /* Save core interrupt assignment */
984 cfg
->int_line
= si_irq(sih
);
985 /* Indicate there is no SROM */
986 *((uint32
*)&cfg
->sprom_control
) = 0xffffffff;
988 /* Point to the PCI config spaces */
989 si_pci_cfg
[dev
][func
].emu
= cfg
;
990 si_pci_cfg
[dev
][func
].pci
= pci
;
991 si_pci_cfg
[dev
][func
].bar
= bar
;
998 si_setcoreidx(sih
, coreidx
);
1002 * Initialize PCI core and construct PCI config spaces for SI cores.
1003 * Must propagate hndpci_init_pci() return value to the caller to let
1004 * them know the PCI core initialization status.
1007 hndpci_init(si_t
*sih
)
1009 int status
= hndpci_init_pci(sih
);
1010 hndpci_init_cores(sih
);