2 * Low-Level PCI and SI support for BCM47xx
4 * Copyright (C) 2010, 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,v 1.49.2.2 2010-11-16 21:44:41 Exp $
29 #include <pcie_core.h>
30 #include <bcmendian.h>
37 /* For now we need some real Silicon Backplane utils */
38 #include "siutils_priv.h"
42 #define PCI_MSG(args) printf args
47 /* to free some function memory after boot */
52 /* Emulated configuration space */
55 uint size
[PCI_BAR_MAX
];
57 static pci_config_regs si_config_regs
[SI_MAXCORES
];
58 static si_bar_cfg_t si_bar_cfg
[SI_MAXCORES
];
60 /* Links to emulated and real PCI configuration spaces */
63 pci_config_regs
*emu
; /* emulated PCI config */
64 pci_config_regs
*pci
; /* real PCI config */
65 si_bar_cfg_t
*bar
; /* region sizes */
67 static si_pci_cfg_t si_pci_cfg
[SI_MAXCORES
][MAXFUNCS
];
69 /* Special emulated config space for non-existing device */
70 static pci_config_regs si_pci_null
= { 0xffff, 0xffff };
73 static uint16 pci_ban
[SI_MAXCORES
] = { 0 };
74 static uint pci_banned
= 0;
77 static bool cardbus
= FALSE
;
79 /* The OS's enumerated bus numbers for supported PCI/PCIe core units */
80 static uint pci_busid
[SI_PCI_MAXCORES
] = { 0, };
82 static uint32 pci_membase_cfg
[SI_PCI_MAXCORES
] = {
86 static uint32 pci_membase
[SI_PCI_MAXCORES
] = {
90 static uint32 pci_membase_1G
[SI_PCI_MAXCORES
] = {
94 /* Disable PCI host core */
95 static bool pci_disabled
[SI_PCI_MAXCORES
] = { FALSE
};
97 /* Host bridge slot #, default to 0 */
98 static uint8 pci_hbslot
= 0;
100 /* Internal macros */
101 #define PCI_SLOTAD_MAP 16 /* SLOT<n> mapps to AD<n+16> */
102 #define PCI_HBSBCFG_REV 8 /* MIN corerev to access host bridge PCI cfg space from SB */
104 /* Functions for accessing external PCI configuration space, Assume one-hot slot wiring */
105 #define PCI_SLOT_MAX 16 /* Max. PCI Slots */
108 hndpci_set_busid(uint busid
)
111 for (i
= 0; i
< SI_PCI_MAXCORES
; i
++) {
112 if (pci_busid
[i
] == 0) {
113 pci_busid
[i
] = busid
;
114 printf("PCI/PCIe coreunit %d is set to bus %d.\n", i
, pci_busid
[i
]);
117 if (busid
== pci_busid
[i
])
123 hndpci_pci_coreunit(uint bus
)
127 for (i
= SI_PCI_MAXCORES
- 1; i
>= 0; i
--) {
128 if (pci_busid
[i
] && bus
>= pci_busid
[i
])
135 hndpci_is_hostbridge(uint bus
, uint dev
)
139 if (dev
!= pci_hbslot
)
142 for (i
= 0; i
< SI_PCI_MAXCORES
; i
++)
143 if (bus
== pci_busid
[i
])
149 uint32
hndpci_get_membase(uint bus
)
153 coreunit
= hndpci_pci_coreunit(bus
);
154 ASSERT(coreunit
>= 0);
155 ASSERT(pci_membase
[coreunit
]);
156 return pci_membase
[coreunit
];
160 config_cmd(si_t
*sih
, uint coreunit
, uint bus
, uint dev
, uint func
, uint off
)
164 uint32 addr
= 0, *sbtopci1
;
167 /* CardBusMode supports only one device */
168 if (cardbus
&& dev
> 1)
173 coreidx
= si_coreidx(sih
);
174 pci
= (sbpciregs_t
*)si_setcore(sih
, PCI_CORE_ID
, coreunit
);
177 sbtopci1
= &pci
->sbtopci1
;
181 pcie
= (sbpcieregs_t
*)si_setcore(sih
, PCIE_CORE_ID
, coreunit
);
183 /* Issue config commands only when the data link is up (atleast
184 * one external pcie device is present).
186 if (pcie
&& (dev
< 2) &&
187 (pcie_readreg(osh
, pcie
, PCIE_PCIEREGS
,
188 PCIE_DLLP_LSREG
) & PCIE_DLLP_LSREG_LINKUP
)) {
189 sbtopci1
= &pcie
->sbtopcie1
;
191 si_setcoreidx(sih
, coreidx
);
197 /* Type 0 transaction */
198 if (!hndpci_is_hostbridge(bus
, dev
)) {
199 /* Skip unwired slots */
200 if (dev
< PCI_SLOT_MAX
) {
201 /* Slide the PCI window to the appropriate slot */
205 win
= (SBTOPCI_CFG0
|
206 ((1 << (dev
+ PCI_SLOTAD_MAP
)) & SBTOPCI1_MASK
));
207 W_REG(osh
, sbtopci1
, win
);
208 addr
= (pci_membase_cfg
[coreunit
] |
209 ((1 << (dev
+ PCI_SLOTAD_MAP
)) & ~SBTOPCI1_MASK
) |
210 (func
<< PCICFG_FUN_SHIFT
) |
213 W_REG(osh
, sbtopci1
, SBTOPCI_CFG0
);
214 addr
= (pci_membase_cfg
[coreunit
] |
215 (dev
<< PCIECFG_SLOT_SHIFT
) |
216 (func
<< PCIECFG_FUN_SHIFT
) |
221 /* Type 1 transaction */
222 W_REG(osh
, sbtopci1
, SBTOPCI_CFG1
);
223 addr
= (pci_membase_cfg
[coreunit
] |
224 (pci
? PCI_CONFIG_ADDR(bus
, dev
, func
, (off
& ~3)) :
225 PCIE_CONFIG_ADDR((bus
- 1), dev
, func
, (off
& ~3))));
228 si_setcoreidx(sih
, coreidx
);
234 * Read host bridge PCI config registers from Silicon Backplane ( >= rev8 ).
236 * It returns TRUE to indicate that access to the host bridge's pci config
237 * from SI is ok, and values in 'addr' and 'val' are valid.
239 * It can only read registers at multiple of 4-bytes. Callers must pick up
240 * needed bytes from 'val' based on 'off' value. Value in 'addr' reflects
241 * the register address where value in 'val' is read.
244 si_pcihb_read_config(si_t
*sih
, uint coreunit
, uint bus
, uint dev
, uint func
,
245 uint off
, uint32
**addr
, uint32
*val
)
253 ASSERT(hndpci_is_hostbridge(bus
, dev
));
255 /* we support only two functions on device 0 */
261 /* read pci config when core rev >= 8 */
262 coreidx
= si_coreidx(sih
);
263 pci
= (sbpciregs_t
*)si_setcore(sih
, PCI_CORE_ID
, coreunit
);
265 if (si_corerev(sih
) >= PCI_HBSBCFG_REV
) {
266 *addr
= (uint32
*)&pci
->pcicfg
[func
][off
>> 2];
267 *val
= R_REG(osh
, *addr
);
273 /* read pcie config */
274 pcie
= (sbpcieregs_t
*)si_setcore(sih
, PCIE_CORE_ID
, coreunit
);
276 /* accesses to config registers with offsets >= 256
277 * requires indirect access.
280 *val
= pcie_readreg(osh
, pcie
, PCIE_CONFIGREGS
,
281 PCIE_CONFIG_INDADDR(func
, off
));
283 *addr
= (uint32
*)&pcie
->pciecfg
[func
][off
>> 2];
284 *val
= R_REG(osh
, *addr
);
290 si_setcoreidx(sih
, coreidx
);
296 extpci_read_config(si_t
*sih
, uint bus
, uint dev
, uint func
, uint off
, void *buf
, int len
)
298 uint32 addr
= 0, *reg
= NULL
, val
;
300 int coreunit
= hndpci_pci_coreunit(bus
);
306 * Set value to -1 when:
307 * flag 'pci_disabled' is true;
308 * value of 'addr' is zero;
312 if (pci_disabled
[coreunit
])
314 else if (hndpci_is_hostbridge(bus
, dev
)) {
315 if (!si_pcihb_read_config(sih
, coreunit
, bus
, dev
, func
, off
, ®
, &val
))
317 } else if (((addr
= config_cmd(sih
, coreunit
, bus
, dev
, func
, off
)) == 0) ||
318 ((reg
= (uint32
*)REG_MAP(addr
, len
)) == 0) ||
319 (BUSPROBE(val
, reg
) != 0)) {
320 PCI_MSG(("%s: Failed to read!\n", __FUNCTION__
));
324 PCI_MSG(("%s: 0x%x <= 0x%p(0x%x), len %d, off 0x%x, buf 0x%p\n",
325 __FUNCTION__
, val
, reg
, addr
, len
, off
, buf
));
327 val
>>= 8 * (off
& 3);
329 *((uint32
*)buf
) = val
;
331 *((uint16
*)buf
) = (uint16
) val
;
333 *((uint8
*)buf
) = (uint8
) val
;
344 extpci_write_config(si_t
*sih
, uint bus
, uint dev
, uint func
, uint off
, void *buf
, int len
)
347 uint32 addr
= 0, *reg
= NULL
, val
;
350 int coreunit
= hndpci_pci_coreunit(bus
);
358 * Ignore write attempt when:
359 * flag 'pci_disabled' is true;
360 * value of 'addr' is zero;
364 if (pci_disabled
[coreunit
])
366 if ((is_hostbridge
= hndpci_is_hostbridge(bus
, dev
))) {
367 if (!si_pcihb_read_config(sih
, coreunit
, bus
, dev
, func
, off
, ®
, &val
))
369 } else if (((addr
= config_cmd(sih
, coreunit
, bus
, dev
, func
, off
)) == 0) ||
370 ((reg
= (uint32
*)REG_MAP(addr
, len
)) == 0) ||
371 (BUSPROBE(val
, reg
) != 0)) {
372 PCI_MSG(("%s: Failed to write!\n", __FUNCTION__
));
377 val
= *((uint32
*)buf
);
379 val
&= ~(0xffff << (8 * (off
& 3)));
380 val
|= *((uint16
*)buf
) << (8 * (off
& 3));
381 } else if (len
== 1) {
382 val
&= ~(0xff << (8 * (off
& 3)));
383 val
|= *((uint8
*)buf
) << (8 * (off
& 3));
389 PCI_MSG(("%s: 0x%x => 0x%p\n", __FUNCTION__
, val
, reg
));
391 if (is_hostbridge
&& reg
== NULL
) {
395 coreidx
= si_coreidx(sih
);
397 /* read pcie config */
398 pcie
= (sbpcieregs_t
*)si_setcore(sih
, PCIE_CORE_ID
, coreunit
);
400 /* accesses to config registers with offsets >= 256
401 * requires indirect access.
403 pcie_writereg(osh
, pcie
, PCIE_CONFIGREGS
,
404 PCIE_CONFIG_INDADDR(func
, off
), val
);
406 si_setcoreidx(sih
, coreidx
);
408 W_REG(osh
, reg
, val
);
410 if ((CHIPID(sih
->chip
) == BCM4716_CHIP_ID
) ||
411 (CHIPID(sih
->chip
) == BCM4748_CHIP_ID
))
412 (void)R_REG(osh
, reg
);
424 * Must access emulated PCI configuration at these locations even when
425 * the real PCI config space exists and is accessible.
429 * PCI_CFG_PROGIF (0x09)
430 * PCI_CFG_SUBCL (0x0a)
431 * PCI_CFG_BASECL (0x0b)
436 #define FORCE_EMUCFG(off, len) \
437 ((off == PCI_CFG_VID) || (off == PCI_CFG_DID) || \
438 (off == PCI_CFG_PROGIF) || \
439 (off == PCI_CFG_SUBCL) || (off == PCI_CFG_BASECL) || \
440 (off == PCI_CFG_HDR) || \
441 (off == PCI_CFG_INT) || (off == PCI_CFG_PIN))
443 /* Sync the emulation registers and the real PCI config registers. */
445 si_pcid_read_config(si_t
*sih
, uint coreidx
, si_pci_cfg_t
*cfg
, uint off
, uint len
)
454 /* decide if real PCI config register access is necessary */
455 if (FORCE_EMUCFG(off
, len
))
460 /* access to the real pci config space only when the core is up */
461 oldidx
= si_coreidx(sih
);
462 si_setcoreidx(sih
, coreidx
);
463 if (si_iscoreup(sih
)) {
465 *(uint32
*)((ulong
)cfg
->emu
+ off
) =
466 htol32(R_REG(osh
, (uint32
*)((ulong
)cfg
->pci
+ off
)));
468 *(uint16
*)((ulong
)cfg
->emu
+ off
) =
469 htol16(R_REG(osh
, (uint16
*)((ulong
)cfg
->pci
+ off
)));
471 *(uint8
*)((ulong
)cfg
->emu
+ off
) =
472 R_REG(osh
, (uint8
*)((ulong
)cfg
->pci
+ off
));
474 si_setcoreidx(sih
, oldidx
);
478 si_pcid_write_config(si_t
*sih
, uint coreidx
, si_pci_cfg_t
*cfg
, uint off
, uint len
)
489 /* decide if real PCI config register access is necessary */
490 if (FORCE_EMUCFG(off
, len
))
493 /* access to the real pci config space only when the core is up */
494 oldidx
= si_coreidx(sih
);
495 si_setcoreidx(sih
, coreidx
);
496 if (si_iscoreup(sih
)) {
498 W_REG(osh
, (uint32
*)((ulong
)cfg
->pci
+ off
),
499 ltoh32(*(uint32
*)((ulong
)cfg
->emu
+ off
)));
501 W_REG(osh
, (uint16
*)((ulong
)cfg
->pci
+ off
),
502 ltoh16(*(uint16
*)((ulong
)cfg
->emu
+ off
)));
504 W_REG(osh
, (uint8
*)((ulong
)cfg
->pci
+ off
),
505 *(uint8
*)((ulong
)cfg
->emu
+ off
));
507 si_setcoreidx(sih
, oldidx
);
511 * Functions for accessing translated SI configuration space
514 si_read_config(si_t
*sih
, uint bus
, uint dev
, uint func
, uint off
, void *buf
, int len
)
516 pci_config_regs
*cfg
;
518 if (dev
>= SI_MAXCORES
|| func
>= MAXFUNCS
|| (off
+ len
) > sizeof(pci_config_regs
))
521 cfg
= si_pci_cfg
[dev
][func
].emu
;
523 ASSERT(ISALIGNED(off
, len
));
524 ASSERT(ISALIGNED((uintptr
)buf
, len
));
526 /* use special config space if the device does not exist */
529 /* sync emulation with real PCI config if necessary */
530 else if (si_pci_cfg
[dev
][func
].pci
)
531 si_pcid_read_config(sih
, dev
, &si_pci_cfg
[dev
][func
], off
, len
);
534 *((uint32
*)buf
) = ltoh32(*((uint32
*)((ulong
) cfg
+ off
)));
536 *((uint16
*)buf
) = ltoh16(*((uint16
*)((ulong
) cfg
+ off
)));
538 *((uint8
*)buf
) = *((uint8
*)((ulong
) cfg
+ off
));
546 si_write_config(si_t
*sih
, uint bus
, uint dev
, uint func
, uint off
, void *buf
, int len
)
550 pci_config_regs
*cfg
;
554 if (dev
>= SI_MAXCORES
|| func
>= MAXFUNCS
|| (off
+ len
) > sizeof(pci_config_regs
))
556 cfg
= si_pci_cfg
[dev
][func
].emu
;
560 ASSERT(ISALIGNED(off
, len
));
561 ASSERT(ISALIGNED((uintptr
)buf
, len
));
565 if (cfg
->header_type
== PCI_HEADER_BRIDGE
) {
567 if (off
== OFFSETOF(ppb_config_regs
, prim_bus
) && len
>= 2)
568 busid
= (*((uint16
*)buf
) & 0xff00) >> 8;
569 else if (off
== OFFSETOF(ppb_config_regs
, sec_bus
))
570 busid
= *((uint8
*)buf
);
572 hndpci_set_busid(busid
);
575 /* Emulate BAR sizing */
576 if (off
>= OFFSETOF(pci_config_regs
, base
[0]) &&
577 off
<= OFFSETOF(pci_config_regs
, base
[3]) &&
578 len
== 4 && *((uint32
*)buf
) == ~0) {
579 coreidx
= si_coreidx(sih
);
580 if ((regs
= si_setcoreidx(sih
, dev
))) {
581 bar
= si_pci_cfg
[dev
][func
].bar
;
582 /* Highest numbered address match register */
583 if (off
== OFFSETOF(pci_config_regs
, base
[0]))
584 cfg
->base
[0] = ~(bar
->size
[0] - 1);
585 else if (off
== OFFSETOF(pci_config_regs
, base
[1]) && bar
->n
>= 1)
586 cfg
->base
[1] = ~(bar
->size
[1] - 1);
587 else if (off
== OFFSETOF(pci_config_regs
, base
[2]) && bar
->n
>= 2)
588 cfg
->base
[2] = ~(bar
->size
[2] - 1);
589 else if (off
== OFFSETOF(pci_config_regs
, base
[3]) && bar
->n
>= 3)
590 cfg
->base
[3] = ~(bar
->size
[3] - 1);
592 si_setcoreidx(sih
, coreidx
);
594 *((uint32
*)((ulong
) cfg
+ off
)) = htol32(*((uint32
*)buf
));
596 *((uint16
*)((ulong
) cfg
+ off
)) = htol16(*((uint16
*)buf
));
598 *((uint8
*)((ulong
) cfg
+ off
)) = *((uint8
*)buf
);
602 /* sync emulation with real PCI config if necessary */
603 if (si_pci_cfg
[dev
][func
].pci
)
604 si_pcid_write_config(sih
, dev
, &si_pci_cfg
[dev
][func
], off
, len
);
610 hndpci_read_config(si_t
*sih
, uint bus
, uint dev
, uint func
, uint off
, void *buf
, int len
)
613 return si_read_config(sih
, bus
, dev
, func
, off
, buf
, len
);
615 return extpci_read_config(sih
, bus
, dev
, func
, off
, buf
, len
);
619 hndpci_write_config(si_t
*sih
, uint bus
, uint dev
, uint func
, uint off
, void *buf
, int len
)
622 return si_write_config(sih
, bus
, dev
, func
, off
, buf
, len
);
624 return extpci_write_config(sih
, bus
, dev
, func
, off
, buf
, len
);
628 hndpci_ban(uint16 core
)
630 if (pci_banned
< ARRAYSIZE(pci_ban
))
631 pci_ban
[pci_banned
++] = core
;
634 /* return cap_offset if requested capability exists in the PCI config space */
636 hndpci_find_pci_capability(si_t
*sih
, uint bus
, uint dev
, uint func
,
637 uint8 req_cap_id
, uchar
*buf
, uint32
*buflen
)
644 /* check for Header type 0 */
645 hndpci_read_config(sih
, bus
, dev
, func
, PCI_CFG_HDR
, &byte_val
, sizeof(uint8
));
646 if ((byte_val
& 0x7f) != PCI_HEADER_NORMAL
)
649 /* check if the capability pointer field exists */
650 hndpci_read_config(sih
, bus
, dev
, func
, PCI_CFG_STAT
, &byte_val
, sizeof(uint8
));
651 if (!(byte_val
& PCI_CAPPTR_PRESENT
))
654 /* check if the capability pointer is 0x00 */
655 hndpci_read_config(sih
, bus
, dev
, func
, PCI_CFG_CAPPTR
, &cap_ptr
, sizeof(uint8
));
659 /* loop thr'u the capability list and see if the requested capabilty exists */
660 hndpci_read_config(sih
, bus
, dev
, func
, cap_ptr
, &cap_id
, sizeof(uint8
));
661 while (cap_id
!= req_cap_id
) {
662 hndpci_read_config(sih
, bus
, dev
, func
, cap_ptr
+ 1, &cap_ptr
, sizeof(uint8
));
665 hndpci_read_config(sih
, bus
, dev
, func
, cap_ptr
, &cap_id
, sizeof(uint8
));
668 /* found the caller requested capability */
669 if ((buf
!= NULL
) && (buflen
!= NULL
)) {
678 /* copy the cpability data excluding cap ID and next ptr */
679 cap_data
= cap_ptr
+ 2;
680 if ((bufsize
+ cap_data
) > SZPCR
)
681 bufsize
= SZPCR
- cap_data
;
684 hndpci_read_config(sih
, bus
, dev
, func
, cap_data
, buf
, sizeof(uint8
));
695 * Initiliaze PCI core.
696 * Return 0 after a successful initialization.
697 * Otherwise return -1 to indicate there is no PCI core and
698 * return 1 to indicate PCI core is disabled.
701 BCMATTACHFN(hndpci_init_pci
)(si_t
*sih
, uint coreunit
)
703 uint chip
, chiprev
, chippkg
, host
;
706 sbpcieregs_t
*pcie
= NULL
;
714 chiprev
= sih
->chiprev
;
715 chippkg
= sih
->chippkg
;
719 pci
= (sbpciregs_t
*)si_setcore(sih
, PCI_CORE_ID
, coreunit
);
721 pcie
= (sbpcieregs_t
*)si_setcore(sih
, PCIE_CORE_ID
, coreunit
);
723 printf("PCI: no core\n");
724 pci_disabled
[coreunit
] = TRUE
;
729 if ((CHIPID(chip
) == BCM4706_CHIP_ID
) && (coreunit
== 1)) {
730 /* Check if PCIE 1 is disabled */
731 if (sih
->chipst
& CST4706_PCIE1_DISABLE
) {
732 pci_disabled
[coreunit
] = TRUE
;
734 PCI_MSG(("PCIE port %d is disabled\n", port
));
738 boardflags
= (uint32
)getintvar(NULL
, "boardflags");
741 * The NOPCI boardflag indicates we should not touch the PCI core,
742 * it may not be bonded out or the pins may be floating.
743 * The 200-pin BCM4712 package does not bond out PCI, and routers
744 * based on it did not use the boardflag.
746 if ((boardflags
& BFL_NOPCI
) ||
747 ((chip
== BCM4712_CHIP_ID
) &&
748 ((chippkg
== BCM4712SMALL_PKG_ID
) || (chippkg
== BCM4712MID_PKG_ID
)))) {
749 pci_disabled
[coreunit
] = TRUE
;
752 /* Enable the core */
753 si_core_reset(sih
, 0, 0);
755 /* Figure out if it is in host mode:
756 * In host mode, it returns 0, in client mode, this register access will trap
757 * Trap handler must be implemented to support this like hndrte_mips.c
759 host
= !BUSPROBE(val
, (pci
? &pci
->control
: &pcie
->control
));
765 /* Disable PCI interrupts in client mode */
768 /* Disable the PCI bridge in client mode */
769 hndpci_ban(pci
? PCI_CORE_ID
: PCIE_CORE_ID
);
771 /* Make sure the core is disabled */
772 si_core_disable(sih
, 0);
774 /* On 4716 (and other AXI chips?) make sure the slave wrapper
775 * is also put in reset.
777 if ((chip
== BCM4716_CHIP_ID
) || (chip
== BCM4748_CHIP_ID
) ||
778 (chip
== BCM4706_CHIP_ID
)) {
781 resetctrl
= (uint32
*)OSL_UNCACHED(SI_WRAP_BASE
+ (9 * SI_CORE_SIZE
) +
783 W_REG(osh
, resetctrl
, AIRC_RESET
);
786 printf("PCI: Disabled\n");
788 printf("PCI: Initializing host\n");
790 /* Disable PCI SBReqeustTimeout for BCM4785 rev. < 2 */
791 if (chip
== BCM4785_CHIP_ID
&& chiprev
< 2) {
793 sb
= (sbconfig_t
*)((ulong
) pci
+ SBCONFIGOFF
);
794 AND_REG(osh
, &sb
->sbimconfiglow
, ~0x00000070);
799 /* Reset the external PCI bus and enable the clock */
800 W_REG(osh
, &pci
->control
, 0x5); /* enable tristate drivers */
801 W_REG(osh
, &pci
->control
, 0xd); /* enable the PCI clock */
802 OSL_DELAY(150); /* delay > 100 us */
803 W_REG(osh
, &pci
->control
, 0xf); /* deassert PCI reset */
804 /* Use internal arbiter and park REQ/GRNT at external master 0
805 * We will set it later after the bus has been probed
807 W_REG(osh
, &pci
->arbcontrol
, PCI_INT_ARB
);
808 OSL_DELAY(1); /* delay 1 us */
810 printf("PCI: Reset RC\n");
812 W_REG(osh
, &pcie
->control
, PCIE_RST_OE
);
813 OSL_DELAY(50000); /* delay 50 ms *//* for 4706 reboot issue*/
814 W_REG(osh
, &pcie
->control
, PCIE_RST
| PCIE_RST_OE
);
817 /* Enable CardBusMode */
818 cardbus
= getintvar(NULL
, "cardbus") == 1;
820 printf("PCI: Enabling CardBus\n");
821 /* GPIO 1 resets the CardBus device on bcm94710ap */
822 si_gpioout(sih
, 1, 1, GPIO_DRV_PRIORITY
);
823 si_gpioouten(sih
, 1, 1, GPIO_DRV_PRIORITY
);
824 W_REG(osh
, &pci
->sprom
[0], R_REG(osh
, &pci
->sprom
[0]) | 0x400);
827 /* Host bridge slot # nvram overwrite */
828 if ((hbslot
= nvram_get("pcihbslot"))) {
829 pci_hbslot
= bcm_strtoul(hbslot
, NULL
, 0);
830 ASSERT(pci_hbslot
< PCI_MAX_DEVICES
);
833 bus
= pci_busid
[coreunit
] = coreunit
+ 1;
835 /* 64 MB I/O access window */
836 W_REG(osh
, &pci
->sbtopci0
, SBTOPCI_IO
);
837 /* 64 MB configuration access window */
838 W_REG(osh
, &pci
->sbtopci1
, SBTOPCI_CFG0
);
839 /* 1 GB memory access window */
840 W_REG(osh
, &pci
->sbtopci2
, SBTOPCI_MEM
| SI_PCI_DMA
);
842 uint8 cap_ptr
, root_ctrl
, root_cap
, dev
;
845 /* 64 MB I/O access window. On 4716, use
846 * sbtopcie0 to access the device registers. We
847 * can't use address match 2 (1 GB window) region
848 * as mips can't generate 64-bit address on the
851 if ((chip
== BCM4716_CHIP_ID
) || (chip
== BCM4748_CHIP_ID
))
852 W_REG(osh
, &pcie
->sbtopcie0
, SBTOPCIE_MEM
|
853 (pci_membase
[coreunit
] = SI_PCI_MEM
));
854 else if (chip
== BCM4706_CHIP_ID
) {
856 pci_membase
[coreunit
] = SI_PCI_MEM
;
857 pci_membase_1G
[coreunit
] = SI_PCIE_DMA_H32
;
858 } else if (coreunit
== 1) {
859 pci_membase_cfg
[coreunit
] = SI_PCI1_CFG
;
860 pci_membase
[coreunit
] = SI_PCI1_MEM
;
861 pci_membase_1G
[coreunit
] = SI_PCIE1_DMA_H32
;
863 W_REG(osh
, &pcie
->sbtopcie0
,
864 SBTOPCIE_MEM
| SBTOPCIE_PF
| SBTOPCIE_WR_BURST
|
865 pci_membase
[coreunit
]);
868 W_REG(osh
, &pcie
->sbtopcie0
, SBTOPCIE_IO
);
870 /* 64 MB configuration access window */
871 W_REG(osh
, &pcie
->sbtopcie1
, SBTOPCIE_CFG0
);
873 /* 1 GB memory access window */
874 W_REG(osh
, &pcie
->sbtopcie2
, SBTOPCIE_MEM
|
875 pci_membase_1G
[coreunit
]);
877 /* As per PCI Express Base Spec 1.1 we need to wait for
878 * at least 100 ms from the end of a reset (cold/warm/hot)
879 * before issuing configuration requests to PCI Express
884 /* If the root port is capable of returning Config Request
885 * Retry Status (CRS) Completion Status to software then
886 * enable the feature.
888 cap_ptr
= hndpci_find_pci_capability(sih
, bus
, pci_hbslot
, 0,
889 PCI_CAP_PCIECAP_ID
, NULL
, NULL
);
892 root_cap
= cap_ptr
+ OFFSETOF(pciconfig_cap_pcie
, root_cap
);
893 hndpci_read_config(sih
, bus
, pci_hbslot
, 0, root_cap
,
894 &val16
, sizeof(uint16
));
895 if (val16
& PCIE_RC_CRS_VISIBILITY
) {
896 /* Enable CRS software visibility */
897 root_ctrl
= cap_ptr
+ OFFSETOF(pciconfig_cap_pcie
, root_ctrl
);
898 val16
= PCIE_RC_CRS_EN
;
899 hndpci_write_config(sih
, bus
, pci_hbslot
, 0, root_ctrl
,
900 &val16
, sizeof(uint16
));
902 /* Initiate a configuration request to read the vendor id
903 * field of the device function's config space header after
904 * 100 ms wait time from the end of Reset. If the device is
905 * not done with its internal initialization, it must at
906 * least return a completion TLP, with a completion status
907 * of "Configuration Request Retry Status (CRS)". The root
908 * complex must complete the request to the host by returning
909 * a read-data value of 0001h for the Vendor ID field and
910 * all 1s for any additional bytes included in the request.
911 * Poll using the config reads for max wait time of 1 sec or
912 * until we receive the successful completion status. Repeat
913 * the procedure for all the devices.
915 for (dev
= pci_hbslot
+ 1; dev
< PCI_MAX_DEVICES
; dev
++) {
916 SPINWAIT((hndpci_read_config(sih
, bus
, dev
, 0,
917 PCI_CFG_VID
, &val16
, sizeof(val16
)),
918 (val16
== 0x1)), 1000000);
920 printf("PCI: Broken device in slot %d\n", dev
);
925 /* Enable PCI bridge BAR0 memory & master access */
926 val
= PCI_CMD_MASTER
| PCI_CMD_MEMORY
;
927 hndpci_write_config(sih
, bus
, pci_hbslot
, 0, PCI_CFG_CMD
, &val
, sizeof(val
));
929 /* Enable PCI interrupts */
931 W_REG(osh
, &pci
->intmask
, PCI_INTA
);
933 W_REG(osh
, &pcie
->intmask
, PCI_INTA
);
936 /* Reset busid to 0. Bus number will be assigned by OS later */
937 pci_busid
[coreunit
] = 0;
942 hndpci_arb_park(si_t
*sih
, uint parkid
)
948 pci
= (sbpciregs_t
*)si_setcore(sih
, PCI_CORE_ID
, 0);
949 if ((pci
== NULL
) || pci_disabled
[0]) {
950 /* Should not happen */
951 PCI_MSG(("%s: no PCI core\n", __FUNCTION__
));
955 pcirev
= si_corerev(sih
);
957 /* Nothing to do, not supported for these revs */
961 /* Get parkid from NVRAM */
962 if (parkid
== PCI_PARK_NVRAM
) {
963 parkid
= getintvar(NULL
, "parkid");
964 if (getvar(NULL
, "parkid") == NULL
)
965 /* Not present in NVRAM use defaults */
966 parkid
= (pcirev
>= 11) ? PCI11_PARKID_LAST
: PCI_PARKID_LAST
;
969 /* Check the parkid is valid, if not set it to default */
970 if (parkid
> ((pcirev
>= 11) ? PCI11_PARKID_LAST
: PCI_PARKID_LAST
)) {
971 printf("%s: Invalid parkid %d\n", __FUNCTION__
, parkid
);
972 parkid
= (pcirev
>= 11) ? PCI11_PARKID_LAST
: PCI_PARKID_LAST
;
975 /* Now set the parkid */
976 arb
= R_REG(si_osh(sih
), &pci
->arbcontrol
);
977 arb
&= ~PCI_PARKID_MASK
;
978 arb
|= parkid
<< PCI_PARKID_SHIFT
;
979 W_REG(si_osh(sih
), &pci
->arbcontrol
, arb
);
983 /*for 4706 reboot issue*/
985 hndpci_deinit_pci(si_t
*sih
, uint coreunit
)
989 sbpcieregs_t
*pcie
= NULL
;
991 if (pci_disabled
[coreunit
])
994 coreidx
= si_coreidx(sih
);
995 pci
= (sbpciregs_t
*)si_setcore(sih
, PCI_CORE_ID
, coreunit
);
997 pcie
= (sbpcieregs_t
*)si_setcore(sih
, PCIE_CORE_ID
, coreunit
);
999 printf("PCI: no core\n");
1005 W_REG(osh
, &pci
->control
, PCI_RST_OE
);
1007 W_REG(osh
, &pcie
->control
, PCIE_RST_OE
);
1009 si_core_disable(sih
, 0);
1010 si_setcoreidx(sih
, coreidx
);
1015 * * Deinitialize PCI(e) cores
1018 hndpci_deinit(si_t
*sih
)
1022 for (coreunit
= 0; coreunit
< SI_PCI_MAXCORES
; coreunit
++)
1023 hndpci_deinit_pci(sih
, coreunit
);
1026 * Get the PCI region address and size information.
1029 BCMATTACHFN(hndpci_init_regions
)(si_t
*sih
, uint func
, pci_config_regs
*cfg
, si_bar_cfg_t
*bar
)
1031 bool issb
= sih
->socitype
== SOCI_SB
;
1034 if (si_coreid(sih
) == USB20H_CORE_ID
) {
1037 base
= htol32(si_addrspace(sih
, 0));
1039 base1
= base
+ 0x800; /* OHCI/EHCI */
1041 /* In AI chips EHCI is addrspace 0, OHCI is 1 */
1043 if ((CHIPID(sih
->chip
) == BCM5357_CHIP_ID
||
1044 (CHIPID(sih
->chip
) == BCM4749_CHIP_ID
)) &&
1045 CHIPREV(sih
->chiprev
) == 0)
1048 base
= htol32(si_addrspace(sih
, 1));
1052 cfg
->base
[0] = func
== 0 ? base
: base1
;
1053 bar
->size
[0] = issb
? 0x800 : 0x1000;
1055 bar
->n
= n
= si_numaddrspaces(sih
);
1056 for (i
= 0; i
< n
; i
++) {
1057 int size
= si_addrspacesize(sih
, i
);
1060 cfg
->base
[i
] = htol32(si_addrspace(sih
, i
));
1061 bar
->size
[i
] = size
;
1065 for (; i
< PCI_BAR_MAX
; i
++) {
1072 * Construct PCI config spaces for SB cores to be accessed as if they were PCI devices.
1075 BCMATTACHFN(hndpci_init_cores
)(si_t
*sih
)
1077 uint chiprev
, coreidx
, i
;
1078 pci_config_regs
*cfg
, *pci
;
1082 uint16 vendor
, device
;
1084 uint8
class, subclass
, progif
;
1089 chiprev
= sih
->chiprev
;
1090 coreidx
= si_coreidx(sih
);
1094 /* Scan the SI bus */
1095 bzero(si_config_regs
, sizeof(si_config_regs
));
1096 bzero(si_bar_cfg
, sizeof(si_bar_cfg
));
1097 bzero(si_pci_cfg
, sizeof(si_pci_cfg
));
1098 memset(&si_pci_null
, -1, sizeof(si_pci_null
));
1099 cfg
= si_config_regs
;
1101 for (dev
= 0; dev
< SI_MAXCORES
; dev
++) {
1102 /* Check if the core exists */
1103 if (!(regs
= si_setcoreidx(sih
, dev
)))
1106 /* Check if this core is banned */
1107 coreid
= si_coreid(sih
);
1108 for (i
= 0; i
< pci_banned
; i
++)
1109 if (coreid
== pci_ban
[i
])
1114 if (coreid
== USB20H_CORE_ID
) {
1115 if (((CHIPID(sih
->chip
) == BCM5357_CHIP_ID
) ||
1116 (CHIPID(sih
->chip
) == BCM4749_CHIP_ID
)) &&
1117 (sih
->chippkg
== BCM5357_PKG_ID
)) {
1118 printf("PCI: skip disabled USB20H\n");
1123 if ((CHIPID(sih
->chip
) == BCM4706_CHIP_ID
)) {
1124 if (coreid
== GMAC_CORE_ID
) {
1125 /* Only GMAC core 0 is used by 4706 */
1126 if (si_coreunit(sih
) > 0) {
1132 for (func
= 0; func
< MAXFUNCS
; ++func
) {
1133 /* Make sure we won't go beyond the limit */
1134 if (cfg
>= &si_config_regs
[SI_MAXCORES
]) {
1135 printf("PCI: too many emulated devices\n");
1139 /* Convert core id to pci id */
1140 if (si_corepciid(sih
, func
, &vendor
, &device
, &class, &subclass
,
1145 * Differentiate real PCI config from emulated.
1146 * non zero 'pci' indicate there is a real PCI config space
1150 case BCM47XX_GIGETH_ID
:
1151 pci
= (pci_config_regs
*)((uint32
)regs
+ 0x800);
1153 case BCM47XX_SATAXOR_ID
:
1154 pci
= (pci_config_regs
*)((uint32
)regs
+ 0x400);
1156 case BCM47XX_ATA100_ID
:
1157 pci
= (pci_config_regs
*)((uint32
)regs
+ 0x800);
1163 /* Supported translations */
1164 cfg
->vendor
= htol16(vendor
);
1165 cfg
->device
= htol16(device
);
1166 cfg
->rev_id
= chiprev
;
1167 cfg
->prog_if
= progif
;
1168 cfg
->sub_class
= subclass
;
1169 cfg
->base_class
= class;
1170 cfg
->header_type
= header
;
1171 hndpci_init_regions(sih
, func
, cfg
, bar
);
1172 /* Save core interrupt flag */
1173 cfg
->int_pin
= si_flag(sih
);
1174 /* Save core interrupt assignment */
1175 cfg
->int_line
= si_irq(sih
);
1176 /* Indicate there is no SROM */
1177 *((uint32
*)&cfg
->sprom_control
) = 0xffffffff;
1179 /* Point to the PCI config spaces */
1180 si_pci_cfg
[dev
][func
].emu
= cfg
;
1181 si_pci_cfg
[dev
][func
].pci
= pci
;
1182 si_pci_cfg
[dev
][func
].bar
= bar
;
1189 si_setcoreidx(sih
, coreidx
);
1193 * Initialize PCI core and construct PCI config spaces for SI cores.
1194 * Must propagate hndpci_init_pci() return value to the caller to let
1195 * them know the PCI core initialization status.
1198 BCMATTACHFN(hndpci_init
)(si_t
*sih
)
1200 int coreunit
, status
= 0;
1202 for (coreunit
= 0; coreunit
< SI_PCI_MAXCORES
; coreunit
++)
1203 status
|= hndpci_init_pci(sih
, coreunit
);
1204 hndpci_init_cores(sih
);