diff options
author | Joel Sherrill <joel.sherrill@OARcorp.com> | 2009-05-04 20:06:43 +0000 |
---|---|---|
committer | Joel Sherrill <joel.sherrill@OARcorp.com> | 2009-05-04 20:06:43 +0000 |
commit | d7196bfd6696be61880fff7db8ca4de044c30748 (patch) | |
tree | 8c4a921d1cadc7dfec6bb91d1613fd8461f3528a /c/src/lib/libbsp/powerpc/mvme5500/pci/pci.c | |
parent | e1be2b30ad3b43c28cba087614a6ebca6356445e (diff) |
2009-04-20 Kate Feng <feng1@bnl.gov>
1396/bsps
* pci/pci.c : Updated it to be consistent with the original pci.c
* written by Eric Valette. There is no change in its function.
* irq/irq_init.c : set defaultIrq->next_handler to be 0
* for BSP_SHARED_HANDLER_SUPPORT.
* network/if_1GHz/if_wm.c : fixed some bugs in the 1GHz driver.
* irq/BSP_irq.c : added supports for shared IRQ.
* pci/pci_interface.c : Enabled PCI "Read", "Read Line", and
"Read Multiple"
* Agressive Prefetch to improve the performance of the PCI based
* applications (e.g. 1GHz NIC).
* irq/BSP_irq.c : Replaced the irq/irq.c, and used GT_GPP_Value
* register to monitor the cause of the level sensitive interrupts.
* This unique solution solves various bugs in the 1GHz network drivers
* Fixed bugs in compute_pic_masks_from_prio()
Diffstat (limited to 'c/src/lib/libbsp/powerpc/mvme5500/pci/pci.c')
-rw-r--r-- | c/src/lib/libbsp/powerpc/mvme5500/pci/pci.c | 263 |
1 files changed, 130 insertions, 133 deletions
diff --git a/c/src/lib/libbsp/powerpc/mvme5500/pci/pci.c b/c/src/lib/libbsp/powerpc/mvme5500/pci/pci.c index 729c8a0640..db372e98d6 100644 --- a/c/src/lib/libbsp/powerpc/mvme5500/pci/pci.c +++ b/c/src/lib/libbsp/powerpc/mvme5500/pci/pci.c @@ -16,26 +16,28 @@ * pci.c,v 1.2 2002/05/14 17:10:16 joel Exp * * Copyright 2004, Brookhaven National Laboratory and - * Shuchen K. Feng, <feng1@bnl.gov>, 2004 - * - modified and added support for MVME5500 board - * - added 2nd PCI support for the mvme5500/GT64260 PCI bridge - * - added bus support for the expansion of PMCSpan, thanks to - * Peter Dufault (dufault@hda.com) for inputs. + * Shuchen K. Feng, <feng1@bnl.gov>, 2004, 2008 + * + * - to be consistent with the original pci.c written by Eric Valette + * - added 2nd PCI support for discovery based PCI bridge (e.g. mvme5500/mvme6100) + * - added bus support for the expansion of PMCSpan as per request by Peter */ #define PCI_MAIN #include <libcpu/io.h> #include <rtems/bspIo.h> /* printk */ +#include <bsp/irq.h> #include <bsp/pci.h> #include <bsp/gtreg.h> #include <bsp/gtpcireg.h> +#include <bsp.h> #include <stdio.h> #include <string.h> #define PCI_DEBUG 0 -#define PCI_PRINT 0 +#define PCI_PRINT 1 /* allow for overriding these definitions */ #ifndef PCI_CONFIG_ADDR @@ -56,17 +58,31 @@ #define PCI_MULTI_FUNCTION 0x80 #define HOSTBRIDGET_ERROR 0xf0000000 -/* define a shortcut */ -#define pci BSP_pci_configuration +#define GT64x60_PCI_CONFIG_ADDR GT64x60_REG_BASE + PCI_CONFIG_ADDR +#define GT64x60_PCI_CONFIG_DATA GT64x60_REG_BASE + PCI_CONFIG_DATA + +#define GT64x60_PCI1_CONFIG_ADDR GT64x60_REG_BASE + PCI1_CONFIG_ADDR +#define GT64x60_PCI1_CONFIG_DATA GT64x60_REG_BASE + PCI1_CONFIG_DATA + +static int numPCIDevs=0; +static DiscoveryChipVersion BSP_sysControllerVersion = 0; +static BSP_VMEchipTypes BSP_VMEinterface = 0; +static pci_config BSP_pci[2]={ + {(volatile unsigned char*) (GT64x60_PCI_CONFIG_ADDR), + (volatile unsigned char*) (GT64x60_PCI_CONFIG_DATA), + 0 /* defined at BSP_pci_configuration */}, + {(volatile unsigned char*) (GT64x60_PCI1_CONFIG_ADDR), + (volatile unsigned char*) (GT64x60_PCI1_CONFIG_DATA), + 0 /* defined at BSP_pci_configuration */} +}; -static int numPCIDevs=0; extern void pci_interface(); /* Pack RegNum,FuncNum,DevNum,BusNum,and ConfigEnable for * PCI Configuration Address Register */ #define pciConfigPack(bus,dev,func,offset)\ -(((func&7)<<8)|((dev&0x1f )<<11)|(( bus&0xff)<<16)|(offset&0xfc))|0x80000000 +((offset&~3)<<24)|(PCI_DEVFN(dev,func)<<16)|(bus<<8)|0x80 /* * Bit encode for PCI_CONFIG_HEADER_TYPE register @@ -75,44 +91,36 @@ unsigned char ucMaxPCIBus=0; /* Please note that PCI0 and PCI1 does not correlate with the busNum 0 and 1. */ -static int direct_pci_read_config_byte(unsigned char bus,unsigned char dev,unsigned char func, +static int indirect_pci_read_config_byte(unsigned char bus,unsigned char dev,unsigned char func, unsigned char offset,unsigned char *val) { - volatile unsigned char *config_addr, *config_data; + int n=0; if (bus>= BSP_MAX_PCI_BUS_ON_PCI0) { bus-=BSP_MAX_PCI_BUS_ON_PCI0; - config_addr = (volatile unsigned char*) PCI1_CONFIG_ADDR; - config_data = (volatile unsigned char*) PCI1_CONFIG_DATA; - } - else { - config_addr = pci.pci_config_addr; - config_data = pci.pci_config_data; + n=1; } + *val = 0xff; if (offset & ~0xff) return PCIBIOS_BAD_REGISTER_NUMBER; #if 0 - printk("addr %x, data %x, pack %x \n", config_addr, - config_data,pciConfigPack(bus,dev,func,offset)); + printk("addr %x, data %x, pack %x \n", BSP_pci[n].pci_config_addr), + BSP_pci[n].config_data,pciConfigPack(bus,dev,func,offset)); #endif - outl(pciConfigPack(bus,dev,func,offset),config_addr); - *val = inb(config_data + (offset&3)); + + out_be32(BSP_pci[n].pci_config_addr, pciConfigPack(bus,dev,func,offset)); + *val = in_8(BSP_pci[n].pci_config_data + (offset&3)); return PCIBIOS_SUCCESSFUL; } -static int direct_pci_read_config_word(unsigned char bus, unsigned char dev, +static int indirect_pci_read_config_word(unsigned char bus, unsigned char dev, unsigned char func, unsigned char offset, unsigned short *val) { - volatile unsigned char *config_addr, *config_data; + int n=0; if (bus>= BSP_MAX_PCI_BUS_ON_PCI0) { bus-=BSP_MAX_PCI_BUS_ON_PCI0; - config_addr = (volatile unsigned char*) PCI1_CONFIG_ADDR; - config_data = (volatile unsigned char*) PCI1_CONFIG_DATA; - } - else { - config_addr = (volatile unsigned char*) pci.pci_config_addr; - config_data = (volatile unsigned char*) pci.pci_config_data; + n=1; } *val = 0xffff; @@ -121,123 +129,101 @@ unsigned char func, unsigned char offset, unsigned short *val) printk("addr %x, data %x, pack %x \n", config_addr, config_data,pciConfigPack(bus,dev,func,offset)); #endif - outl(pciConfigPack(bus,dev,func,offset),config_addr); - *val = inw(config_data + (offset&2)); + out_be32(BSP_pci[n].pci_config_addr, pciConfigPack(bus,dev,func,offset)); + *val = in_le16(BSP_pci[n].pci_config_data + (offset&2)); return PCIBIOS_SUCCESSFUL; } -static int direct_pci_read_config_dword(unsigned char bus, unsigned char dev, +static int indirect_pci_read_config_dword(unsigned char bus, unsigned char dev, unsigned char func, unsigned char offset, unsigned int *val) { - volatile unsigned char *config_addr, *config_data; + int n=0; if (bus>= BSP_MAX_PCI_BUS_ON_PCI0) { bus-=BSP_MAX_PCI_BUS_ON_PCI0; - config_addr = (volatile unsigned char*) PCI1_CONFIG_ADDR; - config_data = (volatile unsigned char*) PCI1_CONFIG_DATA; - } - else { - config_addr = (volatile unsigned char*) pci.pci_config_addr; - config_data = (volatile unsigned char*) pci.pci_config_data; + n=1; } *val = 0xffffffff; if ((offset&3)|| (offset & ~0xff)) return PCIBIOS_BAD_REGISTER_NUMBER; -#if 0 - printk("addr %x, data %x, pack %x \n", config_addr, - pci.pci_config_data,pciConfigPack(bus,dev,func,offset)); -#endif - outl(pciConfigPack(bus,dev,func,offset),config_addr); - *val = inl(config_data); + + out_be32(BSP_pci[n].pci_config_addr, pciConfigPack(bus,dev,func,offset)); + *val = in_le32(BSP_pci[n].pci_config_data); return PCIBIOS_SUCCESSFUL; } -static int direct_pci_write_config_byte(unsigned char bus, unsigned char dev,unsigned char func, unsigned char offset, unsigned char val) +static int indirect_pci_write_config_byte(unsigned char bus, unsigned char dev,unsigned char func, unsigned char offset, unsigned char val) { - volatile unsigned char *config_addr, *config_data; + int n=0; if (bus>= BSP_MAX_PCI_BUS_ON_PCI0) { bus-=BSP_MAX_PCI_BUS_ON_PCI0; - config_addr = (volatile unsigned char*) PCI1_CONFIG_ADDR; - config_data = (volatile unsigned char*) PCI1_CONFIG_DATA; - } - else { - config_addr = pci.pci_config_addr; - config_data = pci.pci_config_data; + n=1; } if (offset & ~0xff) return PCIBIOS_BAD_REGISTER_NUMBER; -#if 0 - printk("addr %x, data %x, pack %x \n", config_addr, - config_data,pciConfigPack(bus,dev,func,offset)); -#endif - outl(pciConfigPack(bus,dev,func,offset), config_addr); - outb(val, config_data + (offset&3)); + out_be32(BSP_pci[n].pci_config_addr, pciConfigPack(bus,dev,func,offset)); + out_8(BSP_pci[n].pci_config_data + (offset&3), val); return PCIBIOS_SUCCESSFUL; } -static int direct_pci_write_config_word(unsigned char bus, unsigned char dev,unsigned char func, unsigned char offset, unsigned short val) +static int indirect_pci_write_config_word(unsigned char bus, unsigned char dev,unsigned char func, unsigned char offset, unsigned short val) { - volatile unsigned char *config_addr, *config_data; + int n=0; if (bus>= BSP_MAX_PCI_BUS_ON_PCI0) { bus-=BSP_MAX_PCI_BUS_ON_PCI0; - config_addr = (volatile unsigned char*) PCI1_CONFIG_ADDR; - config_data = (volatile unsigned char*) PCI1_CONFIG_DATA; - } - else { - config_addr = (volatile unsigned char*) pci.pci_config_addr; - config_data = (volatile unsigned char*) pci.pci_config_data; + n=1; } if ((offset&1)|| (offset & ~0xff)) return PCIBIOS_BAD_REGISTER_NUMBER; -#if 0 - printk("addr %x, data %x, pack %x \n", config_addr, - config_data,pciConfigPack(bus,dev,func,offset)); -#endif - outl(pciConfigPack(bus,dev,func,offset),config_addr); - outw(val, config_data + (offset&3)); + + out_be32(BSP_pci[n].pci_config_addr, pciConfigPack(bus,dev,func,offset)); + out_le16(BSP_pci[n].pci_config_data + (offset&3), val); return PCIBIOS_SUCCESSFUL; } -static int direct_pci_write_config_dword(unsigned char bus,unsigned char dev,unsigned char func, unsigned char offset, unsigned int val) +static int indirect_pci_write_config_dword(unsigned char bus,unsigned char dev,unsigned char func, unsigned char offset, unsigned int val) { - volatile unsigned char *config_addr, *config_data; + int n=0; if (bus>= BSP_MAX_PCI_BUS_ON_PCI0) { bus-=BSP_MAX_PCI_BUS_ON_PCI0; - config_addr = (volatile unsigned char *) PCI1_CONFIG_ADDR; - config_data = (volatile unsigned char *) PCI1_CONFIG_DATA; - } - else { - config_addr = (volatile unsigned char*) pci.pci_config_addr; - config_data = (volatile unsigned char*) pci.pci_config_data; + n=1; } if ((offset&3)|| (offset & ~0xff)) return PCIBIOS_BAD_REGISTER_NUMBER; -#if 0 - printk("addr %x, data %x, pack %x \n", config_addr, - config_data,pciConfigPack(bus,dev,func,offset)); -#endif - outl(pciConfigPack(bus,dev,func,offset),config_addr); - outl(val,config_data); + + out_be32(BSP_pci[n].pci_config_addr, pciConfigPack(bus,dev,func,offset)); + out_le32(BSP_pci[n].pci_config_data, val); return PCIBIOS_SUCCESSFUL; } -const pci_config_access_functions pci_direct_functions = { - direct_pci_read_config_byte, - direct_pci_read_config_word, - direct_pci_read_config_dword, - direct_pci_write_config_byte, - direct_pci_write_config_word, - direct_pci_write_config_dword +const pci_config_access_functions pci_indirect_functions = { + indirect_pci_read_config_byte, + indirect_pci_read_config_word, + indirect_pci_read_config_dword, + indirect_pci_write_config_byte, + indirect_pci_write_config_word, + indirect_pci_write_config_dword }; -pci_config BSP_pci_configuration = {(volatile unsigned char*) PCI_CONFIG_ADDR, - (volatile unsigned char*)PCI_CONFIG_DATA, - &pci_direct_functions}; +pci_config BSP_pci_configuration = { + (volatile unsigned char*) (GT64x60_PCI_CONFIG_ADDR), + (volatile unsigned char*) (GT64x60_PCI_CONFIG_DATA), + &pci_indirect_functions}; + +DiscoveryChipVersion BSP_getDiscoveryChipVersion() +{ + return(BSP_sysControllerVersion); +} + +BSP_VMEchipTypes BSP_getVMEchipType() +{ + return(BSP_VMEinterface); +} /* * This routine determines the maximum bus number in the system. @@ -248,12 +234,12 @@ pci_config BSP_pci_configuration = {(volatile unsigned char*) PCI_CONFIG_ADDR, int pci_initialize() { int deviceFound; - unsigned char ucBusNumber, ucSlotNumber, ucFnNumber, ucNumFuncs; - unsigned int ulHeader; - unsigned int pcidata, ulClass, ulDeviceID; + unsigned char ucBusNumber, ucSlotNumber, ucFnNumber, ucNumFuncs, data8; + uint32_t ulHeader, ulClass, ulDeviceID; +#if PCI_DEBUG + uint32_t pcidata; +#endif - pci_interface(); - /* * Scan PCI0 and PCI1 buses */ @@ -279,12 +265,36 @@ int pci_initialize() if (!deviceFound) deviceFound=1; switch(ulDeviceID) { case (PCI_VENDOR_ID_MARVELL+(PCI_DEVICE_ID_MARVELL_GT6426xAB<<16)): + pci_read_config_byte(0,0,0,PCI_REVISION_ID, &data8); + switch(data8) { + case 0x10: + BSP_sysControllerVersion = GT64260A; +#if PCI_PRINT + printk("Marvell GT64260A (Discovery I) hostbridge detected at bus%d slot%d\n", + ucBusNumber,ucSlotNumber); +#endif + break; + case 0x20: + BSP_sysControllerVersion = GT64260B; +#if PCI_PRINT + printk("Marvell GT64260B (Discovery I) hostbridge detected at bus%d slot%d\n", + ucBusNumber,ucSlotNumber); +#endif + break; + default: + printk("Undefined revsion of GT64260 chip\n"); + break; + } + break; + case (PCI_VENDOR_ID_MARVELL+(PCI_DEVICE_ID_MARVELL_GT64360<<16)): + BSP_sysControllerVersion = MV64360; #if PCI_PRINT - printk("Marvell GT6426xA/B hostbridge detected at bus%d slot%d\n", + printk("Marvell GT64360 (Discovery II) hostbridge detected at bus%d slot%d\n", ucBusNumber,ucSlotNumber); #endif break; case (PCI_VENDOR_ID_PLX2+(PCI_DEVICE_ID_PLX2_PCI6154_HB2<<16)): + BSP_VMEinterface = UNIVERSE2; #if PCI_PRINT printk("PLX PCI6154 PCI-PCI bridge detected at bus%d slot%d\n", ucBusNumber,ucSlotNumber); @@ -296,6 +306,13 @@ int pci_initialize() ucBusNumber,ucSlotNumber); #endif break; + case (PCI_VENDOR_ID_TUNDRA+(PCI_DEVICE_ID_TUNDRA_TSI148<<16)): + BSP_VMEinterface = TSI148; +#if PCI_PRINT + printk("TUNDRA Tsi148 PCI/X-VME bridge detected at bus%d slot%d\n", + ucBusNumber,ucSlotNumber); +#endif + break; case (PCI_VENDOR_ID_INTEL+(PCI_DEVICE_INTEL_82544EI_COPPER<<16)): #if PCI_PRINT printk("INTEL 82544EI COPPER network controller detected at bus%d slot%d\n", @@ -303,14 +320,21 @@ int pci_initialize() #endif break; case (PCI_VENDOR_ID_DEC+(PCI_DEVICE_ID_DEC_21150<<16)): - #if PCI_PRINT +#if PCI_PRINT printk("DEC21150 PCI-PCI bridge detected at bus%d slot%d\n", ucBusNumber,ucSlotNumber); #endif break; default : +#if PCI_PRINT printk("BSP unlisted vendor, Bus%d Slot%d DeviceID 0x%x \n", ucBusNumber,ucSlotNumber, ulDeviceID); +#endif + /* Kate Feng : device not supported by BSP needs to remap the IRQ line on mvme5500/mvme6100 */ + pci_read_config_byte(ucBusNumber,ucSlotNumber,0,PCI_INTERRUPT_LINE,&data8); + if (data8 < BSP_GPP_IRQ_LOWEST_OFFSET) pci_write_config_byte(ucBusNumber, + ucSlotNumber,0,PCI_INTERRUPT_LINE,BSP_GPP_IRQ_LOWEST_OFFSET+data8); + break; } @@ -403,34 +427,6 @@ int pci_initialize() #endif } - - pci_read_config_dword(ucBusNumber, - ucSlotNumber, - 0, - PCI_COMMAND, - &pcidata); -#if PCI_DEBUG - printk("MOTLoad command staus 0x%x, ", pcidata); -#endif - /* Clear the error on the host bridge */ - if ( (ucBusNumber==0) && (ucSlotNumber==0)) - pcidata |= PCI_STATUS_CLRERR_MASK; - /* Enable bus,I/O and memory master access. */ - pcidata |= (PCI_COMMAND_MASTER|PCI_COMMAND_IO|PCI_COMMAND_MEMORY); - pci_write_config_dword(ucBusNumber, - ucSlotNumber, - 0, - PCI_COMMAND, - pcidata); - - pci_read_config_dword(ucBusNumber, - ucSlotNumber, - 0, - PCI_COMMAND, - &pcidata); -#if PCI_DEBUG - printk("Now command/staus 0x%x\n", pcidata); -#endif } if (deviceFound) ucMaxPCIBus++; } /* for (ucBusNumber=0; ucBusNumber<BSP_MAX_PCI_BUS; ... */ @@ -438,6 +434,7 @@ int pci_initialize() printk("number of PCI buses: %d, numPCIDevs %d\n", pci_bus_count(), numPCIDevs); #endif + pci_interface(BSP_sysControllerVersion); return(0); } |