2 * Low-Level PCI and SI support for BCM47xx
4 * Copyright (C) 2011, Broadcom Corporation. All Rights Reserved.
6 * Permission to use, copy, modify, and/or distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
13 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
15 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
16 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 * $Id: hndpci.c 319422 2012-03-08 01:30:26Z $
30 #include <pcie_core.h>
31 #include <bcmendian.h>
38 /* For now we need some real Silicon Backplane utils */
39 #include "siutils_priv.h"
44 /* to free some function memory after boot */
49 /* Emulated configuration space */
52 uint size
[PCI_BAR_MAX
];
54 static pci_config_regs si_config_regs
[SI_MAXCORES
];
55 static si_bar_cfg_t si_bar_cfg
[SI_MAXCORES
];
57 /* Links to emulated and real PCI configuration spaces */
60 pci_config_regs
*emu
; /* emulated PCI config */
61 pci_config_regs
*pci
; /* real PCI config */
62 si_bar_cfg_t
*bar
; /* region sizes */
64 static si_pci_cfg_t si_pci_cfg
[SI_MAXCORES
][MAXFUNCS
];
66 /* Special emulated config space for non-existing device */
67 static pci_config_regs si_pci_null
= { 0xffff, 0xffff };
70 static uint16 pci_ban
[SI_MAXCORES
] = { 0 };
71 static uint pci_banned
= 0;
74 static bool cardbus
= FALSE
;
76 /* The OS's enumerated bus numbers for supported PCI/PCIe core units */
77 static uint pci_busid
[SI_PCI_MAXCORES
] = { 0, };
79 static uint32 pci_membase_cfg
[SI_PCI_MAXCORES
] = {
83 static uint32 pci_membase
[SI_PCI_MAXCORES
] = {
87 static uint32 pci_membase_1G
[SI_PCI_MAXCORES
] = {
91 /* Disable PCI host core */
92 static bool pci_disabled
[SI_PCI_MAXCORES
] = { FALSE
};
94 /* Host bridge slot #, default to 0 */
95 static uint8 pci_hbslot
= 0;
98 #define PCI_SLOTAD_MAP 16 /* SLOT<n> mapps to AD<n+16> */
99 #define PCI_HBSBCFG_REV 8 /* MIN corerev to access host bridge PCI cfg space from SB */
101 /* Functions for accessing external PCI configuration space, Assume one-hot slot wiring */
102 #define PCI_SLOT_MAX 16 /* Max. PCI Slots */
105 hndpci_set_busid(uint busid
)
108 for (i
= 0; i
< SI_PCI_MAXCORES
; i
++) {
109 if (pci_busid
[i
] == 0) {
110 pci_busid
[i
] = busid
;
111 printf("PCI/PCIe coreunit %d is set to bus %d.\n", i
, pci_busid
[i
]);
114 if (busid
== pci_busid
[i
])
120 hndpci_pci_coreunit(uint bus
)
124 for (i
= SI_PCI_MAXCORES
- 1; i
>= 0; i
--) {
125 if (pci_busid
[i
] && bus
>= pci_busid
[i
])
132 hndpci_is_hostbridge(uint bus
, uint dev
)
136 if (dev
!= pci_hbslot
)
139 for (i
= 0; i
< SI_PCI_MAXCORES
; i
++)
140 if (bus
== pci_busid
[i
])
146 uint32
hndpci_get_membase(uint bus
)
150 coreunit
= hndpci_pci_coreunit(bus
);
151 ASSERT(coreunit
>= 0);
152 ASSERT(pci_membase
[coreunit
]);
153 return pci_membase
[coreunit
];
157 config_cmd(si_t
*sih
, uint coreunit
, uint bus
, uint dev
, uint func
, uint off
)
161 uint32 addr
= 0, *sbtopci1
;
164 /* CardBusMode supports only one device */
165 if (cardbus
&& dev
> 1)
170 coreidx
= si_coreidx(sih
);
171 pci
= (sbpciregs_t
*)si_setcore(sih
, PCI_CORE_ID
, coreunit
);
174 sbtopci1
= &pci
->sbtopci1
;
178 pcie
= (sbpcieregs_t
*)si_setcore(sih
, PCIE_CORE_ID
, coreunit
);
180 /* Issue config commands only when the data link is up (atleast
181 * one external pcie device is present).
183 if (pcie
&& (dev
< 2) &&
184 (pcie_readreg(sih
, pcie
, PCIE_PCIEREGS
,
185 PCIE_DLLP_LSREG
) & PCIE_DLLP_LSREG_LINKUP
)) {
186 sbtopci1
= &pcie
->sbtopcie1
;
188 si_setcoreidx(sih
, coreidx
);
194 /* Type 0 transaction */
195 if (!hndpci_is_hostbridge(bus
, dev
)) {
196 /* Skip unwired slots */
197 if (dev
< PCI_SLOT_MAX
) {
198 /* Slide the PCI window to the appropriate slot */
202 win
= (SBTOPCI_CFG0
|
203 ((1 << (dev
+ PCI_SLOTAD_MAP
)) & SBTOPCI1_MASK
));
204 W_REG(osh
, sbtopci1
, win
);
205 addr
= (pci_membase_cfg
[coreunit
] |
206 ((1 << (dev
+ PCI_SLOTAD_MAP
)) & ~SBTOPCI1_MASK
) |
207 (func
<< PCICFG_FUN_SHIFT
) |
210 W_REG(osh
, sbtopci1
, SBTOPCI_CFG0
);
211 addr
= (pci_membase_cfg
[coreunit
] |
212 (dev
<< PCIECFG_SLOT_SHIFT
) |
213 (func
<< PCIECFG_FUN_SHIFT
) |
218 /* Type 1 transaction */
219 W_REG(osh
, sbtopci1
, SBTOPCI_CFG1
);
220 addr
= (pci_membase_cfg
[coreunit
] |
221 (pci
? PCI_CONFIG_ADDR(bus
, dev
, func
, (off
& ~3)) :
222 PCIE_CONFIG_ADDR((bus
- 1), dev
, func
, (off
& ~3))));
225 si_setcoreidx(sih
, coreidx
);
231 * Read host bridge PCI config registers from Silicon Backplane ( >= rev8 ).
233 * It returns TRUE to indicate that access to the host bridge's pci config
234 * from SI is ok, and values in 'addr' and 'val' are valid.
236 * It can only read registers at multiple of 4-bytes. Callers must pick up
237 * needed bytes from 'val' based on 'off' value. Value in 'addr' reflects
238 * the register address where value in 'val' is read.
241 si_pcihb_read_config(si_t
*sih
, uint coreunit
, uint bus
, uint dev
, uint func
,
242 uint off
, uint32
**addr
, uint32
*val
)
250 ASSERT(hndpci_is_hostbridge(bus
, dev
));
252 /* we support only two functions on device 0 */
258 /* read pci config when core rev >= 8 */
259 coreidx
= si_coreidx(sih
);
260 pci
= (sbpciregs_t
*)si_setcore(sih
, PCI_CORE_ID
, coreunit
);
262 if (si_corerev(sih
) >= PCI_HBSBCFG_REV
) {
263 *addr
= (uint32
*)&pci
->pcicfg
[func
][off
>> 2];
264 *val
= R_REG(osh
, *addr
);
270 /* read pcie config */
271 pcie
= (sbpcieregs_t
*)si_setcore(sih
, PCIE_CORE_ID
, coreunit
);
273 /* accesses to config registers with offsets >= 256
274 * requires indirect access.
277 *val
= pcie_readreg(sih
, pcie
, PCIE_CONFIGREGS
,
278 PCIE_CONFIG_INDADDR(func
, off
));
280 *addr
= (uint32
*)&pcie
->pciecfg
[func
][off
>> 2];
281 *val
= R_REG(osh
, *addr
);
287 si_setcoreidx(sih
, coreidx
);
293 extpci_read_config(si_t
*sih
, uint bus
, uint dev
, uint func
, uint off
, void *buf
, int len
)
295 uint32 addr
= 0, *reg
= NULL
, val
;
297 int coreunit
= hndpci_pci_coreunit(bus
);
303 * Set value to -1 when:
304 * flag 'pci_disabled' is true;
305 * value of 'addr' is zero;
309 if (pci_disabled
[coreunit
])
311 else if (hndpci_is_hostbridge(bus
, dev
)) {
312 if (!si_pcihb_read_config(sih
, coreunit
, bus
, dev
, func
, off
, ®
, &val
))
314 } else if (((addr
= config_cmd(sih
, coreunit
, bus
, dev
, func
, off
)) == 0) ||
315 ((reg
= (uint32
*)REG_MAP(addr
, len
)) == 0) ||
316 (BUSPROBE(val
, reg
) != 0)) {
317 PCI_MSG(("%s: Failed to read!\n", __FUNCTION__
));
321 PCI_MSG(("%s: 0x%x <= 0x%p(0x%x), len %d, off 0x%x, buf 0x%p\n",
322 __FUNCTION__
, val
, reg
, addr
, len
, off
, buf
));
324 val
>>= 8 * (off
& 3);
326 *((uint32
*)buf
) = val
;
328 *((uint16
*)buf
) = (uint16
) val
;
330 *((uint8
*)buf
) = (uint8
) val
;
341 extpci_write_config(si_t
*sih
, uint bus
, uint dev
, uint func
, uint off
, void *buf
, int len
)
344 uint32 addr
= 0, *reg
= NULL
, val
;
347 int coreunit
= hndpci_pci_coreunit(bus
);
355 * Ignore write attempt when:
356 * flag 'pci_disabled' is true;
357 * value of 'addr' is zero;
361 if (pci_disabled
[coreunit
])
363 if ((is_hostbridge
= hndpci_is_hostbridge(bus
, dev
))) {
364 if (!si_pcihb_read_config(sih
, coreunit
, bus
, dev
, func
, off
, ®
, &val
))
366 } else if (((addr
= config_cmd(sih
, coreunit
, bus
, dev
, func
, off
)) == 0) ||
367 ((reg
= (uint32
*)REG_MAP(addr
, len
)) == 0) ||
368 (BUSPROBE(val
, reg
) != 0)) {
369 PCI_MSG(("%s: Failed to write!\n", __FUNCTION__
));
374 val
= *((uint32
*)buf
);
376 val
&= ~(0xffff << (8 * (off
& 3)));
377 val
|= *((uint16
*)buf
) << (8 * (off
& 3));
378 } else if (len
== 1) {
379 val
&= ~(0xff << (8 * (off
& 3)));
380 val
|= *((uint8
*)buf
) << (8 * (off
& 3));
386 PCI_MSG(("%s: 0x%x => 0x%p\n", __FUNCTION__
, val
, reg
));
388 if (is_hostbridge
&& reg
== NULL
) {
392 coreidx
= si_coreidx(sih
);
394 /* read pcie config */
395 pcie
= (sbpcieregs_t
*)si_setcore(sih
, PCIE_CORE_ID
, coreunit
);
397 /* accesses to config registers with offsets >= 256
398 * requires indirect access.
400 pcie_writereg(sih
, pcie
, PCIE_CONFIGREGS
,
401 PCIE_CONFIG_INDADDR(func
, off
), val
);
403 si_setcoreidx(sih
, coreidx
);
405 W_REG(osh
, reg
, val
);
407 if ((CHIPID(sih
->chip
) == BCM4716_CHIP_ID
) ||
408 (CHIPID(sih
->chip
) == BCM4748_CHIP_ID
))
409 (void)R_REG(osh
, reg
);
421 * Must access emulated PCI configuration at these locations even when
422 * the real PCI config space exists and is accessible.
426 * PCI_CFG_PROGIF (0x09)
427 * PCI_CFG_SUBCL (0x0a)
428 * PCI_CFG_BASECL (0x0b)
433 #define FORCE_EMUCFG(off, len) \
434 ((off == PCI_CFG_VID) || (off == PCI_CFG_DID) || \
435 (off == PCI_CFG_PROGIF) || \
436 (off == PCI_CFG_SUBCL) || (off == PCI_CFG_BASECL) || \
437 (off == PCI_CFG_HDR) || \
438 (off == PCI_CFG_INT) || (off == PCI_CFG_PIN))
440 /* Sync the emulation registers and the real PCI config registers. */
442 si_pcid_read_config(si_t
*sih
, uint coreidx
, si_pci_cfg_t
*cfg
, uint off
, uint len
)
451 /* decide if real PCI config register access is necessary */
452 if (FORCE_EMUCFG(off
, len
))
457 /* access to the real pci config space only when the core is up */
458 oldidx
= si_coreidx(sih
);
459 si_setcoreidx(sih
, coreidx
);
460 if (si_iscoreup(sih
)) {
462 *(uint32
*)((ulong
)cfg
->emu
+ off
) =
463 htol32(R_REG(osh
, (uint32
*)((ulong
)cfg
->pci
+ off
)));
465 *(uint16
*)((ulong
)cfg
->emu
+ off
) =
466 htol16(R_REG(osh
, (uint16
*)((ulong
)cfg
->pci
+ off
)));
468 *(uint8
*)((ulong
)cfg
->emu
+ off
) =
469 R_REG(osh
, (uint8
*)((ulong
)cfg
->pci
+ off
));
471 si_setcoreidx(sih
, oldidx
);
475 si_pcid_write_config(si_t
*sih
, uint coreidx
, si_pci_cfg_t
*cfg
, uint off
, uint len
)
486 /* decide if real PCI config register access is necessary */
487 if (FORCE_EMUCFG(off
, len
))
490 /* access to the real pci config space only when the core is up */
491 oldidx
= si_coreidx(sih
);
492 si_setcoreidx(sih
, coreidx
);
493 if (si_iscoreup(sih
)) {
495 W_REG(osh
, (uint32
*)((ulong
)cfg
->pci
+ off
),
496 ltoh32(*(uint32
*)((ulong
)cfg
->emu
+ off
)));
498 W_REG(osh
, (uint16
*)((ulong
)cfg
->pci
+ off
),
499 ltoh16(*(uint16
*)((ulong
)cfg
->emu
+ off
)));
501 W_REG(osh
, (uint8
*)((ulong
)cfg
->pci
+ off
),
502 *(uint8
*)((ulong
)cfg
->emu
+ off
));
504 si_setcoreidx(sih
, oldidx
);
508 * Functions for accessing translated SI configuration space
511 si_read_config(si_t
*sih
, uint bus
, uint dev
, uint func
, uint off
, void *buf
, int len
)
513 pci_config_regs
*cfg
;
515 if (dev
>= SI_MAXCORES
|| func
>= MAXFUNCS
|| (off
+ len
) > sizeof(pci_config_regs
))
518 cfg
= si_pci_cfg
[dev
][func
].emu
;
520 ASSERT(ISALIGNED(off
, len
));
521 ASSERT(ISALIGNED(buf
, len
));
523 /* use special config space if the device does not exist */
526 /* sync emulation with real PCI config if necessary */
527 else if (si_pci_cfg
[dev
][func
].pci
)
528 si_pcid_read_config(sih
, dev
, &si_pci_cfg
[dev
][func
], off
, len
);
531 *((uint32
*)buf
) = ltoh32(*((uint32
*)((ulong
) cfg
+ off
)));
533 *((uint16
*)buf
) = ltoh16(*((uint16
*)((ulong
) cfg
+ off
)));
535 *((uint8
*)buf
) = *((uint8
*)((ulong
) cfg
+ off
));
543 si_write_config(si_t
*sih
, uint bus
, uint dev
, uint func
, uint off
, void *buf
, int len
)
547 pci_config_regs
*cfg
;
551 if (dev
>= SI_MAXCORES
|| func
>= MAXFUNCS
|| (off
+ len
) > sizeof(pci_config_regs
))
553 cfg
= si_pci_cfg
[dev
][func
].emu
;
557 ASSERT(ISALIGNED(off
, len
));
558 ASSERT(ISALIGNED(buf
, len
));
562 if (cfg
->header_type
== PCI_HEADER_BRIDGE
) {
564 if (off
== OFFSETOF(ppb_config_regs
, prim_bus
) && len
>= 2)
565 busid
= (*((uint16
*)buf
) & 0xff00) >> 8;
566 else if (off
== OFFSETOF(ppb_config_regs
, sec_bus
))
567 busid
= *((uint8
*)buf
);
569 hndpci_set_busid(busid
);
572 /* Emulate BAR sizing */
573 if (off
>= OFFSETOF(pci_config_regs
, base
[0]) &&
574 off
<= OFFSETOF(pci_config_regs
, base
[3]) &&
575 len
== 4 && *((uint32
*)buf
) == ~0) {
576 coreidx
= si_coreidx(sih
);
577 if ((regs
= si_setcoreidx(sih
, dev
))) {
578 bar
= si_pci_cfg
[dev
][func
].bar
;
579 /* Highest numbered address match register */
580 if (off
== OFFSETOF(pci_config_regs
, base
[0]))
581 cfg
->base
[0] = ~(bar
->size
[0] - 1);
582 else if (off
== OFFSETOF(pci_config_regs
, base
[1]) && bar
->n
>= 1)
583 cfg
->base
[1] = ~(bar
->size
[1] - 1);
584 else if (off
== OFFSETOF(pci_config_regs
, base
[2]) && bar
->n
>= 2)
585 cfg
->base
[2] = ~(bar
->size
[2] - 1);
586 else if (off
== OFFSETOF(pci_config_regs
, base
[3]) && bar
->n
>= 3)
587 cfg
->base
[3] = ~(bar
->size
[3] - 1);
589 si_setcoreidx(sih
, coreidx
);
591 *((uint32
*)((ulong
) cfg
+ off
)) = htol32(*((uint32
*)buf
));
593 *((uint16
*)((ulong
) cfg
+ off
)) = htol16(*((uint16
*)buf
));
595 *((uint8
*)((ulong
) cfg
+ off
)) = *((uint8
*)buf
);
599 /* sync emulation with real PCI config if necessary */
600 if (si_pci_cfg
[dev
][func
].pci
)
601 si_pcid_write_config(sih
, dev
, &si_pci_cfg
[dev
][func
], off
, len
);
607 hndpci_read_config(si_t
*sih
, uint bus
, uint dev
, uint func
, uint off
, void *buf
, int len
)
610 return si_read_config(sih
, bus
, dev
, func
, off
, buf
, len
);
612 return extpci_read_config(sih
, bus
, dev
, func
, off
, buf
, len
);
616 hndpci_write_config(si_t
*sih
, uint bus
, uint dev
, uint func
, uint off
, void *buf
, int len
)
619 return si_write_config(sih
, bus
, dev
, func
, off
, buf
, len
);
621 return extpci_write_config(sih
, bus
, dev
, func
, off
, buf
, len
);
625 hndpci_ban(uint16 core
)
627 if (pci_banned
< ARRAYSIZE(pci_ban
))
628 pci_ban
[pci_banned
++] = core
;
631 /* return cap_offset if requested capability exists in the PCI config space */
633 hndpci_find_pci_capability(si_t
*sih
, uint bus
, uint dev
, uint func
,
634 uint8 req_cap_id
, uchar
*buf
, uint32
*buflen
)
641 /* check for Header type 0 */
642 hndpci_read_config(sih
, bus
, dev
, func
, PCI_CFG_HDR
, &byte_val
, sizeof(uint8
));
643 if ((byte_val
& 0x7f) != PCI_HEADER_NORMAL
)
646 /* check if the capability pointer field exists */
647 hndpci_read_config(sih
, bus
, dev
, func
, PCI_CFG_STAT
, &byte_val
, sizeof(uint8
));
648 if (!(byte_val
& PCI_CAPPTR_PRESENT
))
651 /* check if the capability pointer is 0x00 */
652 hndpci_read_config(sih
, bus
, dev
, func
, PCI_CFG_CAPPTR
, &cap_ptr
, sizeof(uint8
));
656 /* loop thr'u the capability list and see if the requested capabilty exists */
657 hndpci_read_config(sih
, bus
, dev
, func
, cap_ptr
, &cap_id
, sizeof(uint8
));
658 while (cap_id
!= req_cap_id
) {
659 hndpci_read_config(sih
, bus
, dev
, func
, cap_ptr
+ 1, &cap_ptr
, sizeof(uint8
));
662 hndpci_read_config(sih
, bus
, dev
, func
, cap_ptr
, &cap_id
, sizeof(uint8
));
665 /* found the caller requested capability */
666 if ((buf
!= NULL
) && (buflen
!= NULL
)) {
675 /* copy the cpability data excluding cap ID and next ptr */
676 cap_data
= cap_ptr
+ 2;
677 if ((bufsize
+ cap_data
) > SZPCR
)
678 bufsize
= SZPCR
- cap_data
;
681 hndpci_read_config(sih
, bus
, dev
, func
, cap_data
, buf
, sizeof(uint8
));
692 * Initiliaze PCI core.
693 * Return 0 after a successful initialization.
694 * Otherwise return -1 to indicate there is no PCI core and
695 * return 1 to indicate PCI core is disabled.
698 BCMATTACHFN(hndpci_init_pci
)(si_t
*sih
, uint coreunit
)
700 uint chip
, chiprev
, chippkg
, host
;
703 sbpcieregs_t
*pcie
= NULL
;
711 chiprev
= sih
->chiprev
;
712 chippkg
= sih
->chippkg
;
716 pci
= (sbpciregs_t
*)si_setcore(sih
, PCI_CORE_ID
, coreunit
);
718 pcie
= (sbpcieregs_t
*)si_setcore(sih
, PCIE_CORE_ID
, coreunit
);
720 printf("PCI: no core\n");
721 pci_disabled
[coreunit
] = TRUE
;
726 if ((CHIPID(chip
) == BCM4706_CHIP_ID
) && (coreunit
== 1)) {
727 /* Check if PCIE 1 is disabled */
728 if (sih
->chipst
& CST4706_PCIE1_DISABLE
) {
729 pci_disabled
[coreunit
] = TRUE
;
731 PCI_MSG(("PCIE port %d is disabled\n", port
));
735 boardflags
= (uint32
)getintvar(NULL
, "boardflags");
738 * The NOPCI boardflag indicates we should not touch the PCI core,
739 * it may not be bonded out or the pins may be floating.
740 * The 200-pin BCM4712 package does not bond out PCI, and routers
741 * based on it did not use the boardflag.
743 if ((boardflags
& BFL_NOPCI
) ||
744 ((chip
== BCM4712_CHIP_ID
) &&
745 ((chippkg
== BCM4712SMALL_PKG_ID
) || (chippkg
== BCM4712MID_PKG_ID
)))) {
746 pci_disabled
[coreunit
] = TRUE
;
749 /* Enable the core */
750 si_core_reset(sih
, 0, 0);
752 /* Figure out if it is in host mode:
753 * In host mode, it returns 0, in client mode, this register access will trap
754 * Trap handler must be implemented to support this like hndrte_mips.c
756 host
= !BUSPROBE(val
, (pci
? &pci
->control
: &pcie
->control
));
762 /* Disable PCI interrupts in client mode */
765 /* Disable the PCI bridge in client mode */
766 hndpci_ban(pci
? PCI_CORE_ID
: PCIE_CORE_ID
);
768 /* Make sure the core is disabled */
769 si_core_disable(sih
, 0);
771 /* On 4716 (and other AXI chips?) make sure the slave wrapper
772 * is also put in reset.
774 if ((chip
== BCM4716_CHIP_ID
) || (chip
== BCM4748_CHIP_ID
) ||
775 (chip
== BCM4706_CHIP_ID
)) {
778 resetctrl
= (uint32
*)OSL_UNCACHED(SI_WRAP_BASE
+ (9 * SI_CORE_SIZE
) +
780 W_REG(osh
, resetctrl
, AIRC_RESET
);
783 printf("PCI: Disabled\n");
785 printf("PCI: Initializing host\n");
787 /* Disable PCI SBReqeustTimeout for BCM4785 rev. < 2 */
788 if (chip
== BCM4785_CHIP_ID
&& chiprev
< 2) {
790 sb
= (sbconfig_t
*)((ulong
) pci
+ SBCONFIGOFF
);
791 AND_REG(osh
, &sb
->sbimconfiglow
, ~0x00000070);
796 /* Reset the external PCI bus and enable the clock */
797 W_REG(osh
, &pci
->control
, 0x5); /* enable tristate drivers */
798 W_REG(osh
, &pci
->control
, 0xd); /* enable the PCI clock */
799 OSL_DELAY(150); /* delay > 100 us */
800 W_REG(osh
, &pci
->control
, 0xf); /* deassert PCI reset */
801 /* Use internal arbiter and park REQ/GRNT at external master 0
802 * We will set it later after the bus has been probed
804 W_REG(osh
, &pci
->arbcontrol
, PCI_INT_ARB
);
805 OSL_DELAY(1); /* delay 1 us */
807 printf("PCI: Reset RC\n");
809 W_REG(osh
, &pcie
->control
, PCIE_RST_OE
);
810 OSL_DELAY(50000); /* delay 50 ms */
811 W_REG(osh
, &pcie
->control
, PCIE_RST
| PCIE_RST_OE
);
814 /* Enable CardBusMode */
815 cardbus
= getintvar(NULL
, "cardbus") == 1;
817 printf("PCI: Enabling CardBus\n");
818 /* GPIO 1 resets the CardBus device on bcm94710ap */
819 si_gpioout(sih
, 1, 1, GPIO_DRV_PRIORITY
);
820 si_gpioouten(sih
, 1, 1, GPIO_DRV_PRIORITY
);
821 W_REG(osh
, &pci
->sprom
[0], R_REG(osh
, &pci
->sprom
[0]) | 0x400);
824 /* Host bridge slot # nvram overwrite */
825 if ((hbslot
= nvram_get("pcihbslot"))) {
826 pci_hbslot
= bcm_strtoul(hbslot
, NULL
, 0);
827 ASSERT(pci_hbslot
< PCI_MAX_DEVICES
);
830 bus
= pci_busid
[coreunit
] = coreunit
+ 1;
832 /* 64 MB I/O access window */
833 W_REG(osh
, &pci
->sbtopci0
, SBTOPCI_IO
);
834 /* 64 MB configuration access window */
835 W_REG(osh
, &pci
->sbtopci1
, SBTOPCI_CFG0
);
836 /* 1 GB memory access window */
837 W_REG(osh
, &pci
->sbtopci2
, SBTOPCI_MEM
| SI_PCI_DMA
);
839 uint8 cap_ptr
, root_ctrl
, root_cap
, dev
;
842 /* 64 MB I/O access window. On 4716, use
843 * sbtopcie0 to access the device registers. We
844 * can't use address match 2 (1 GB window) region
845 * as mips can't generate 64-bit address on the
848 if ((chip
== BCM4716_CHIP_ID
) || (chip
== BCM4748_CHIP_ID
))
849 W_REG(osh
, &pcie
->sbtopcie0
, SBTOPCIE_MEM
|
850 (pci_membase
[coreunit
] = SI_PCI_MEM
));
851 else if (chip
== BCM4706_CHIP_ID
) {
853 pci_membase
[coreunit
] = SI_PCI_MEM
;
854 pci_membase_1G
[coreunit
] = SI_PCIE_DMA_H32
;
855 } else if (coreunit
== 1) {
856 pci_membase_cfg
[coreunit
] = SI_PCI1_CFG
;
857 pci_membase
[coreunit
] = SI_PCI1_MEM
;
858 pci_membase_1G
[coreunit
] = SI_PCIE1_DMA_H32
;
860 W_REG(osh
, &pcie
->sbtopcie0
,
861 SBTOPCIE_MEM
| SBTOPCIE_PF
| SBTOPCIE_WR_BURST
|
862 pci_membase
[coreunit
]);
865 W_REG(osh
, &pcie
->sbtopcie0
, SBTOPCIE_IO
);
867 /* 64 MB configuration access window */
868 W_REG(osh
, &pcie
->sbtopcie1
, SBTOPCIE_CFG0
);
870 /* 1 GB memory access window */
871 W_REG(osh
, &pcie
->sbtopcie2
, SBTOPCIE_MEM
|
872 pci_membase_1G
[coreunit
]);
874 /* As per PCI Express Base Spec 1.1 we need to wait for
875 * at least 100 ms from the end of a reset (cold/warm/hot)
876 * before issuing configuration requests to PCI Express
881 /* If the root port is capable of returning Config Request
882 * Retry Status (CRS) Completion Status to software then
883 * enable the feature.
885 cap_ptr
= hndpci_find_pci_capability(sih
, bus
, pci_hbslot
, 0,
886 PCI_CAP_PCIECAP_ID
, NULL
, NULL
);
889 root_cap
= cap_ptr
+ OFFSETOF(pciconfig_cap_pcie
, root_cap
);
890 hndpci_read_config(sih
, bus
, pci_hbslot
, 0, root_cap
,
891 &val16
, sizeof(uint16
));
892 if (val16
& PCIE_RC_CRS_VISIBILITY
) {
893 /* Enable CRS software visibility */
894 root_ctrl
= cap_ptr
+ OFFSETOF(pciconfig_cap_pcie
, root_ctrl
);
895 val16
= PCIE_RC_CRS_EN
;
896 hndpci_write_config(sih
, bus
, pci_hbslot
, 0, root_ctrl
,
897 &val16
, sizeof(uint16
));
899 /* Initiate a configuration request to read the vendor id
900 * field of the device function's config space header after
901 * 100 ms wait time from the end of Reset. If the device is
902 * not done with its internal initialization, it must at
903 * least return a completion TLP, with a completion status
904 * of "Configuration Request Retry Status (CRS)". The root
905 * complex must complete the request to the host by returning
906 * a read-data value of 0001h for the Vendor ID field and
907 * all 1s for any additional bytes included in the request.
908 * Poll using the config reads for max wait time of 1 sec or
909 * until we receive the successful completion status. Repeat
910 * the procedure for all the devices.
912 for (dev
= pci_hbslot
+ 1; dev
< PCI_MAX_DEVICES
; dev
++) {
913 SPINWAIT((hndpci_read_config(sih
, bus
, dev
, 0,
914 PCI_CFG_VID
, &val16
, sizeof(val16
)),
915 (val16
== 0x1)), 1000000);
917 printf("PCI: Broken device in slot %d\n", dev
);
922 if ((chip
== BCM4706_CHIP_ID
) || (chip
== BCM4716_CHIP_ID
)) {
924 hndpci_read_config(sih
, bus
, pci_hbslot
, 0, PCI_CFG_DEVCTRL
,
925 &val16
, sizeof(val16
));
926 val16
|= (2 << 5); /* Max payload size of 512 */
927 val16
|= (2 << 12); /* MRRS 512 */
928 hndpci_write_config(sih
, bus
, pci_hbslot
, 0, PCI_CFG_DEVCTRL
,
929 &val16
, sizeof(val16
));
932 /* Enable PCI bridge BAR0 memory & master access */
933 val
= PCI_CMD_MASTER
| PCI_CMD_MEMORY
;
934 hndpci_write_config(sih
, bus
, pci_hbslot
, 0, PCI_CFG_CMD
, &val
, sizeof(val
));
936 /* Enable PCI interrupts */
938 W_REG(osh
, &pci
->intmask
, PCI_INTA
);
940 W_REG(osh
, &pcie
->intmask
, PCI_INTA
);
943 /* Reset busid to 0. Bus number will be assigned by OS later */
944 pci_busid
[coreunit
] = 0;
949 hndpci_arb_park(si_t
*sih
, uint parkid
)
955 pci
= (sbpciregs_t
*)si_setcore(sih
, PCI_CORE_ID
, 0);
956 if ((pci
== NULL
) || pci_disabled
[0]) {
957 /* Should not happen */
958 PCI_MSG(("%s: no PCI core\n", __FUNCTION__
));
962 pcirev
= si_corerev(sih
);
964 /* Nothing to do, not supported for these revs */
968 /* Get parkid from NVRAM */
969 if (parkid
== PCI_PARK_NVRAM
) {
970 parkid
= getintvar(NULL
, "parkid");
971 if (getvar(NULL
, "parkid") == NULL
)
972 /* Not present in NVRAM use defaults */
973 parkid
= (pcirev
>= 11) ? PCI11_PARKID_LAST
: PCI_PARKID_LAST
;
976 /* Check the parkid is valid, if not set it to default */
977 if (parkid
> ((pcirev
>= 11) ? PCI11_PARKID_LAST
: PCI_PARKID_LAST
)) {
978 printf("%s: Invalid parkid %d\n", __FUNCTION__
, parkid
);
979 parkid
= (pcirev
>= 11) ? PCI11_PARKID_LAST
: PCI_PARKID_LAST
;
982 /* Now set the parkid */
983 arb
= R_REG(si_osh(sih
), &pci
->arbcontrol
);
984 arb
&= ~PCI_PARKID_MASK
;
985 arb
|= parkid
<< PCI_PARKID_SHIFT
;
986 W_REG(si_osh(sih
), &pci
->arbcontrol
, arb
);
991 hndpci_deinit_pci(si_t
*sih
, uint coreunit
)
995 sbpcieregs_t
*pcie
= NULL
;
997 if (pci_disabled
[coreunit
])
1000 coreidx
= si_coreidx(sih
);
1001 pci
= (sbpciregs_t
*)si_setcore(sih
, PCI_CORE_ID
, coreunit
);
1003 pcie
= (sbpcieregs_t
*)si_setcore(sih
, PCIE_CORE_ID
, coreunit
);
1005 printf("PCI: no core\n");
1011 W_REG(si_osh(sih
), &pci
->control
, PCI_RST_OE
);
1013 W_REG(si_osh(sih
), &pcie
->control
, PCIE_RST_OE
);
1015 si_core_disable(sih
, 0);
1016 si_setcoreidx(sih
, coreidx
);
1021 * Deinitialize PCI cores
1024 hndpci_deinit(si_t
*sih
)
1028 for (coreunit
= 0; coreunit
< SI_PCI_MAXCORES
; coreunit
++)
1029 hndpci_deinit_pci(sih
, coreunit
);
1033 * Get the PCI region address and size information.
1036 BCMATTACHFN(hndpci_init_regions
)(si_t
*sih
, uint func
, pci_config_regs
*cfg
, si_bar_cfg_t
*bar
)
1038 bool issb
= sih
->socitype
== SOCI_SB
;
1041 if (si_coreid(sih
) == USB20H_CORE_ID
) {
1044 base
= htol32(si_addrspace(sih
, 0));
1046 base1
= base
+ 0x800; /* OHCI/EHCI */
1048 /* In AI chips EHCI is addrspace 0, OHCI is 1 */
1050 if (((CHIPID(sih
->chip
) == BCM5357_CHIP_ID
) ||
1051 (CHIPID(sih
->chip
) == BCM4749_CHIP_ID
)) &&
1052 CHIPREV(sih
->chiprev
) == 0)
1055 base
= htol32(si_addrspace(sih
, 1));
1059 cfg
->base
[0] = func
== 0 ? base
: base1
;
1060 bar
->size
[0] = issb
? 0x800 : 0x1000;
1062 bar
->n
= n
= si_numaddrspaces(sih
);
1063 for (i
= 0; i
< n
; i
++) {
1064 int size
= si_addrspacesize(sih
, i
);
1067 cfg
->base
[i
] = htol32(si_addrspace(sih
, i
));
1068 bar
->size
[i
] = size
;
1072 for (; i
< PCI_BAR_MAX
; i
++) {
1079 * Construct PCI config spaces for SB cores to be accessed as if they were PCI devices.
1082 BCMATTACHFN(hndpci_init_cores
)(si_t
*sih
)
1084 uint chiprev
, coreidx
, i
;
1085 pci_config_regs
*cfg
, *pci
;
1089 uint16 vendor
, device
;
1091 uint8
class, subclass
, progif
;
1096 chiprev
= sih
->chiprev
;
1097 coreidx
= si_coreidx(sih
);
1101 /* Scan the SI bus */
1102 bzero(si_config_regs
, sizeof(si_config_regs
));
1103 bzero(si_bar_cfg
, sizeof(si_bar_cfg
));
1104 bzero(si_pci_cfg
, sizeof(si_pci_cfg
));
1105 memset(&si_pci_null
, -1, sizeof(si_pci_null
));
1106 cfg
= si_config_regs
;
1108 for (dev
= 0; dev
< SI_MAXCORES
; dev
++) {
1109 /* Check if the core exists */
1110 if (!(regs
= si_setcoreidx(sih
, dev
)))
1113 /* Check if this core is banned */
1114 coreid
= si_coreid(sih
);
1115 for (i
= 0; i
< pci_banned
; i
++)
1116 if (coreid
== pci_ban
[i
])
1121 if (coreid
== USB20H_CORE_ID
) {
1122 if (((CHIPID(sih
->chip
) == BCM5357_CHIP_ID
) ||
1123 (CHIPID(sih
->chip
) == BCM4749_CHIP_ID
)) &&
1124 (sih
->chippkg
== BCM5357_PKG_ID
)) {
1125 printf("PCI: skip disabled USB20H\n");
1130 if ((CHIPID(sih
->chip
) == BCM4706_CHIP_ID
)) {
1131 if (coreid
== GMAC_CORE_ID
) {
1132 /* Only GMAC core 0 is used by 4706 */
1133 if (si_coreunit(sih
) > 0) {
1139 for (func
= 0; func
< MAXFUNCS
; ++func
) {
1140 /* Make sure we won't go beyond the limit */
1141 if (cfg
>= &si_config_regs
[SI_MAXCORES
]) {
1142 printf("PCI: too many emulated devices\n");
1146 /* Convert core id to pci id */
1147 if (si_corepciid(sih
, func
, &vendor
, &device
, &class, &subclass
,
1152 * Differentiate real PCI config from emulated.
1153 * non zero 'pci' indicate there is a real PCI config space
1157 case BCM47XX_GIGETH_ID
:
1158 pci
= (pci_config_regs
*)((uint32
)regs
+ 0x800);
1160 case BCM47XX_SATAXOR_ID
:
1161 pci
= (pci_config_regs
*)((uint32
)regs
+ 0x400);
1163 case BCM47XX_ATA100_ID
:
1164 pci
= (pci_config_regs
*)((uint32
)regs
+ 0x800);
1170 /* Supported translations */
1171 cfg
->vendor
= htol16(vendor
);
1172 cfg
->device
= htol16(device
);
1173 cfg
->rev_id
= chiprev
;
1174 cfg
->prog_if
= progif
;
1175 cfg
->sub_class
= subclass
;
1176 cfg
->base_class
= class;
1177 cfg
->header_type
= header
;
1178 hndpci_init_regions(sih
, func
, cfg
, bar
);
1179 /* Save core interrupt flag */
1180 cfg
->int_pin
= si_flag(sih
);
1181 /* Save core interrupt assignment */
1182 cfg
->int_line
= si_irq(sih
);
1183 /* Indicate there is no SROM */
1184 *((uint32
*)&cfg
->sprom_control
) = 0xffffffff;
1186 /* Point to the PCI config spaces */
1187 si_pci_cfg
[dev
][func
].emu
= cfg
;
1188 si_pci_cfg
[dev
][func
].pci
= pci
;
1189 si_pci_cfg
[dev
][func
].bar
= bar
;
1196 si_setcoreidx(sih
, coreidx
);
1200 * Initialize PCI core and construct PCI config spaces for SI cores.
1201 * Must propagate hndpci_init_pci() return value to the caller to let
1202 * them know the PCI core initialization status.
1205 BCMATTACHFN(hndpci_init
)(si_t
*sih
)
1207 int coreunit
, status
= 0;
1209 for (coreunit
= 0; coreunit
< SI_PCI_MAXCORES
; coreunit
++)
1210 status
|= hndpci_init_pci(sih
, coreunit
);
1211 hndpci_init_cores(sih
);