summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libbsp/powerpc/mvme5500/pci/pci.c
diff options
context:
space:
mode:
Diffstat (limited to 'c/src/lib/libbsp/powerpc/mvme5500/pci/pci.c')
-rw-r--r--c/src/lib/libbsp/powerpc/mvme5500/pci/pci.c260
1 files changed, 115 insertions, 145 deletions
diff --git a/c/src/lib/libbsp/powerpc/mvme5500/pci/pci.c b/c/src/lib/libbsp/powerpc/mvme5500/pci/pci.c
index 5a129aea84..0bc243cfa0 100644
--- a/c/src/lib/libbsp/powerpc/mvme5500/pci/pci.c
+++ b/c/src/lib/libbsp/powerpc/mvme5500/pci/pci.c
@@ -13,29 +13,31 @@
* found in the file LICENSE in this distribution or at
* http://www.rtems.com/rtems/license.html.
*
- * 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.
+ * pci.c,v 1.2 2002/05/14 17:10:16 joel Exp
*
- * $Id$
+ * Copyright 2004, 2008 Brookhaven National Laboratory and
+ * Shuchen K. Feng, <feng1@bnl.gov>
+ *
+ * - 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(void);
/* 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(void)
+{
+ return(BSP_sysControllerVersion);
+}
+
+BSP_VMEchipTypes BSP_getVMEchipType(void)
+{
+ 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(void)
{
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,38 +265,49 @@ int pci_initialize(void)
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 GT6426xA/B hostbridge detected at bus%d slot%d\n",
+ printk("Marvell GT64260A (Discovery I) hostbridge detected at bus%d slot%d\n",
ucBusNumber,ucSlotNumber);
#endif
- break;
- case (PCI_VENDOR_ID_PLX2+(PCI_DEVICE_ID_PLX2_PCI6154_HB2<<16)):
+ break;
+ case 0x20:
+ BSP_sysControllerVersion = GT64260B;
#if PCI_PRINT
- printk("PLX PCI6154 PCI-PCI bridge detected at bus%d slot%d\n",
+ printk("Marvell GT64260B (Discovery I) hostbridge detected at bus%d slot%d\n",
ucBusNumber,ucSlotNumber);
#endif
- break;
+ break;
+ default:
+ printk("Undefined revsion of GT64260 chip\n");
+ break;
+ }
+ break;
case PCI_VENDOR_ID_TUNDRA:
#if PCI_PRINT
printk("TUNDRA PCI-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",
- ucBusNumber,ucSlotNumber);
-#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 +400,6 @@ int pci_initialize(void)
#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 +407,7 @@ int pci_initialize(void)
printk("number of PCI buses: %d, numPCIDevs %d\n",
pci_bus_count(), numPCIDevs);
#endif
+ pci_interface();
return(0);
}