📄 sb_pci_machdep.c
字号:
/* ********************************************************************* * Broadcom Common Firmware Environment (CFE) * * Broadcom Silicon Backplane PCI support File: sb_pci_machdep.c * * Author: Ed Satterthwaite * ********************************************************************* * * Copyright 2003,2004 * Broadcom Corporation. All rights reserved. * * This software is furnished under license and may be used and * copied only in accordance with the following terms and * conditions. Subject to these conditions, you may download, * copy, install, use, modify and distribute modified or unmodified * copies of this software in source and/or binary form. No title * or ownership is transferred hereby. * * 1) Any source code used, modified or distributed must reproduce * and retain this copyright notice and list of conditions * as they appear in the source file. * * 2) No right is granted to use any trade name, trademark, or * logo of Broadcom Corporation. The "Broadcom Corporation" * name may not be used to endorse or promote products derived * from this software without the prior written permission of * Broadcom Corporation. * * 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT * SHALL BROADCOM BE LIABLE FOR ANY DAMAGES WHATSOEVER, AND IN * PARTICULAR, BROADCOM SHALL NOT BE LIABLE FOR DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR * TORT (INCLUDING NEGLIGENCE OR OTHERWISE), EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGE. ********************************************************************* *//* * Silicon Backplane machine-specific functions for PCI autoconfiguration. */#include "cfe.h"#include "sb_bp.h"#include "sb_pci.h"#include "sb_utils.h"#include "pcivar.h"#include "pci_internal.h"#include "pcireg.h"#include "lib_try.h"extern int _pciverbose;const cons_t pci_optnames[] = { {"verbose", PCI_FLG_VERBOSE}, {NULL, 0}};/* Templates for bus attributes. */static const struct pci_bus init_pci_bus = { 0, /* minimum grant */ 255, /* maximum latency */ 0, /* devsel time = unknown */ 0, /* configure fast back-to-back */ 0, /* we don't prefetch */ 0, /* configure 66 MHz */ 0, /* we don't support 64 bits */ 4000000, /* bandwidth: in 0.25us cycles / sec */ 0, /* initially no devices on bus */};#define MAXBUS 10static struct pci_bus _pci_bus[MAXBUS];static int _pci_nbus = 0;#define PCI_MAKE_TAG(b,d,f) \ (((b) << 16) | ((d) << 11) | ((f) << 8))/* Access functions (XXX use (upgraded?) lib_physio) */#define PTR_TO_PHYS(x) (PHYSADDR((uintptr_t)(x)))#define PHYS_TO_PTR(a) ((uint8_t *)UNCADDR(a))/* PCI "enumeration" space */#define READCSR(x) \ (*(volatile uint32_t *)PHYS_TO_PTR(SB_PCI_BASE+(x)))#define WRITECSR(x,v) \ (*(volatile uint32_t *)PHYS_TO_PTR(SB_PCI_BASE+(x)) = (v))/* PCI spaces mapped by the core in Host mode. */#define SB_PCI_CFG_BASE 0x0C000000#define SB_PCI_MEM_BASE 0x08000000#define CFG_ADDR(x) ((x) | SB_PCI_CFG_BASE)#define MEM_ADDR(x) ((x) | SB_PCI_MEM_BASE)#define READCFG(x) (*(volatile uint32_t *)PHYS_TO_PTR(CFG_ADDR(x)))#define WRITECFG(x,v) (*(volatile uint32_t *)PHYS_TO_PTR(CFG_ADDR(x)) = (v))/* The following should return the index of the last usable bus port. */intpci_maxport (void){ return PCI_HOST_PORTS - 1;}/* The following must either fail or return the next sequential bus number to make secondary/subordinate numbering work correctly. */intpci_nextbus (int port){ int bus = _pci_nbus; if (bus >= MAXBUS) return -1; _pci_nbus++; return bus;} intpci_maxbus (int port){ return _pci_nbus - 1;}struct pci_bus *pci_businfo (int port, int bus){ return (bus < _pci_nbus ? &_pci_bus[bus] : NULL);}/* * PCI address resources. * NB: initial limits for address allocation are assumed to be aligned * appropriately for PCI bridges (4K boundaries for I/O, 1M for memory). * * The standard Silicon Backplane address map provides two * configurable PCI regions in host mode. Thus it is not possible to * provide memory, i/o and configuration space simultaneously. For * now, i/o space is not implemented. */pcireg_tpci_minmemaddr (int port){ return SB_PCI_MEM_BASE;}pcireg_tpci_maxmemaddr (int port){ return SB_PCI_MEM_BASE + 0x04000000;}pcireg_tpci_minioaddr (int port){ return 0x00000000;}pcireg_tpci_maxioaddr (int port){ return 0x00000000;}/* The PCI core (a host bridge in Host mode) */#define SB_PCI_BRIDGE (PCI_MAKE_TAG(0,0,0))/* Called to initialise the host bridge at the beginning of time. */static voidphb_init (void){ pcireg_t csr; /* stop the servicing of any further PCI */ pci_conf_write(SB_PCI_BRIDGE, PCI_COMMAND_STATUS_REG, 0); cfe_usleep(100); /* Set up the BARs (BAR0 for cores, BAR1 for SDRAM) */#ifdef SB_CHIPC_BASE pci_conf_write(SB_PCI_BRIDGE, PCI_PCIBAR0WINDOW_REG, SB_CHIPC_BASE);#else pci_conf_write(SB_PCI_BRIDGE, PCI_PCIBAR0WINDOW_REG, SB_EXTIF_BASE);#endif pci_conf_write(SB_PCI_BRIDGE, PCI_MAPREG(0), 0x10000000); pci_conf_write(SB_PCI_BRIDGE, PCI_PCIBAR1WINDOW_REG, 0x00000000); pci_conf_write(SB_PCI_BRIDGE, PCI_MAPREG(1), 0x00000000); /* enable bridge to PCI and PCI memory accesses, including write-invalidate, plus error handling */ csr = PCI_COMMAND_MASTER_ENABLE | PCI_COMMAND_MEM_ENABLE | PCI_COMMAND_INVALIDATE_ENABLE | PCI_COMMAND_SERR_ENABLE | PCI_COMMAND_PARITY_ENABLE; pci_conf_write(SB_PCI_BRIDGE, PCI_COMMAND_STATUS_REG, csr); /* clear errors */ csr = pci_conf_read(SB_PCI_BRIDGE, PCI_COMMAND_STATUS_REG); csr |= PCI_STATUS_PARITY_ERROR | PCI_STATUS_SYSTEM_ERROR | PCI_STATUS_MASTER_ABORT | PCI_STATUS_MASTER_TARGET_ABORT | PCI_STATUS_TARGET_TARGET_ABORT | PCI_STATUS_PARITY_DETECT; pci_conf_write(SB_PCI_BRIDGE, PCI_COMMAND_STATUS_REG, csr); (void)pci_conf_read(SB_PCI_BRIDGE, PCI_ID_REG); /* push */}#ifndef PCI_CLOCK#define PCI_CLOCK 33000000#endifintpci_hwinit (int port, pci_flags_t flags){ uint32_t ctrl; uint32_t cpu_clock; int i; /* Enable PCI clock and release reset */ ctrl = M_PCICTL_OE | M_PCICTL_CE; /* enable the tristate drivers */ WRITECSR(R_PCI_CONTROL, ctrl); ctrl |= M_PCICTL_CO; /* enable the PCI clock */ WRITECSR(R_PCI_CONTROL, ctrl); cfe_usleep(100); /* delay 100 us */ ctrl |= M_PCICTL_RO; /* release reset */ WRITECSR(R_PCI_CONTROL, ctrl); /* Set PCI clock frequency */ cpu_clock = sb_clock(); sb_setclock(cpu_clock, PCI_CLOCK); /* Enable the internal arbiter. PARK_LAST apparently locks the bus when there is no response. */ WRITECSR(R_PCI_ARB_CONTROL, M_PCIARB_IA); /* Map the PCI memory window transparently. */ WRITECSR(R_SB_TO_PCI_TRANSLATION0, (SB_PCI_MEM_BASE & M_SBXLAT_UA) | M_SBXLAT_PE | M_SBXLAT_WB | V_SBXLAT_AT(K_AT_RW)); _pci_bus[_pci_nbus] = init_pci_bus; _pci_bus[_pci_nbus].port = port; _pci_nbus++; for (i = _pci_nbus; i < MAXBUS; i++) _pci_bus[i] = init_pci_bus; cfe_sleep(CFE_HZ/2); /* let devices initialize */ phb_init(); /* Allow the standard PCI interrupts. */ WRITECSR(R_INT_MASK, M_PCIINT_PA | M_PCIINT_PB); return 0;}/* Called to update the host bridge after we've scanned each PCI device and know what is possible. */voidpci_hwreinit (int port, pci_flags_t flags){}/* The following functions provide for device-specific setup required during configuration. There is nothing host-specific about them, and it would be better to do the packaging and registration in a more modular way. *//* Dispatch functions for device pre- and post-configuration hooks. *//* Called for each hostbridge, to discover and scan secondary buses */voidpci_businit_hostbridge (pcitag_t tag, pci_flags_t flags){}/* Called for each function prior to assigning PCI resources. */intpci_device_preset (pcitag_t tag)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -