PCIe endpoint support for AMCC Yucca 440SPe board

Patch by Tirumala R Marri, 26 Aug 2006
This commit is contained in:
Stefan Roese 2006-08-29 08:05:15 +02:00
parent f5577aae4a
commit 2b393b0f0a
4 changed files with 494 additions and 42 deletions

View File

@ -2,6 +2,9 @@
Changes since U-Boot 1.1.4: Changes since U-Boot 1.1.4:
====================================================================== ======================================================================
* PCIe endpoint support for AMCC Yucca 440SPe board
Patch by Tirumala R Marri, 26 Aug 2006
* Improve DIMM detection for AMCC Yucca 440SPe board * Improve DIMM detection for AMCC Yucca 440SPe board
Improved the memory DIMM detection for the Yucca 440SPe board for Improved the memory DIMM detection for the Yucca 440SPe board for
the case where a memory DIMM is falsely detected as present. the case where a memory DIMM is falsely detected as present.

View File

@ -32,6 +32,10 @@
#include <asm-ppc/io.h> #include <asm-ppc/io.h>
#include "yucca.h" #include "yucca.h"
#include "../cpu/ppc4xx/440spe_pcie.h"
#undef PCIE_ENDPOINT
/* #define PCIE_ENDPOINT 1 */
void fpga_init (void); void fpga_init (void);
@ -1029,6 +1033,57 @@ void yucca_setup_pcie_fpga_rootpoint(int port)
out_be16((u16 *)FPGA_REG1C, reset_off | in_be16((u16 *)FPGA_REG1C)); out_be16((u16 *)FPGA_REG1C, reset_off | in_be16((u16 *)FPGA_REG1C));
} }
/*
* For the given slot, set endpoint mode, send power to the slot,
* turn on the green LED and turn off the yellow LED, enable the clock
* .In end point mode reset bit is read only.
*/
void yucca_setup_pcie_fpga_endpoint(int port)
{
u16 power, clock, green_led, yellow_led, reset_off, rootpoint, endpoint;
switch(port) {
case 0:
rootpoint = FPGA_REG1C_PE0_ROOTPOINT;
endpoint = 0;
power = FPGA_REG1A_PE0_PWRON;
green_led = FPGA_REG1A_PE0_GLED;
clock = FPGA_REG1A_PE0_REFCLK_ENABLE;
yellow_led = FPGA_REG1A_PE0_YLED;
reset_off = FPGA_REG1C_PE0_PERST;
break;
case 1:
rootpoint = 0;
endpoint = FPGA_REG1C_PE1_ENDPOINT;
power = FPGA_REG1A_PE1_PWRON;
green_led = FPGA_REG1A_PE1_GLED;
clock = FPGA_REG1A_PE1_REFCLK_ENABLE;
yellow_led = FPGA_REG1A_PE1_YLED;
reset_off = FPGA_REG1C_PE1_PERST;
break;
case 2:
rootpoint = 0;
endpoint = FPGA_REG1C_PE2_ENDPOINT;
power = FPGA_REG1A_PE2_PWRON;
green_led = FPGA_REG1A_PE2_GLED;
clock = FPGA_REG1A_PE2_REFCLK_ENABLE;
yellow_led = FPGA_REG1A_PE2_YLED;
reset_off = FPGA_REG1C_PE2_PERST;
break;
default:
return;
}
out_be16((u16 *)FPGA_REG1A,
~(power | clock | green_led) &
(yellow_led | in_be16((u16 *)FPGA_REG1A)));
out_be16((u16 *)FPGA_REG1C,
~(rootpoint | reset_off) &
(endpoint | in_be16((u16 *)FPGA_REG1C)));
}
static struct pci_controller pcie_hose[3] = {{0},{0},{0}}; static struct pci_controller pcie_hose[3] = {{0},{0},{0}};
@ -1048,9 +1103,13 @@ void pcie_setup_hoses(void)
if (!yucca_pcie_card_present(i)) if (!yucca_pcie_card_present(i))
continue; continue;
#ifdef PCIE_ENDPOINT
yucca_setup_pcie_fpga_endpoint(i);
if (ppc440spe_init_pcie_endport(i)) {
#else
yucca_setup_pcie_fpga_rootpoint(i); yucca_setup_pcie_fpga_rootpoint(i);
if (ppc440spe_init_pcie_rootport(i)) { if (ppc440spe_init_pcie_rootport(i)) {
#endif
printf("PCIE%d: initialization failed\n", i); printf("PCIE%d: initialization failed\n", i);
continue; continue;
} }
@ -1070,8 +1129,19 @@ void pcie_setup_hoses(void)
hose->region_count = 1; hose->region_count = 1;
pci_register_hose(hose); pci_register_hose(hose);
ppc440spe_setup_pcie(hose, i); #ifdef PCIE_ENDPOINT
ppc440spe_setup_pcie_endpoint(hose, i);
/*
* Reson for no scanning is endpoint can not generate
* upstream configuration accesses.
*/
#else
ppc440spe_setup_pcie_rootpoint(hose, i);
/*
* Config access can only go down stream
*/
hose->last_busno = pci_hose_scan(hose); hose->last_busno = pci_hose_scan(hose);
#endif
} }
} }
#endif /* defined(CONFIG_PCI) */ #endif /* defined(CONFIG_PCI) */

View File

@ -284,6 +284,40 @@ int ppc440spe_init_pcie(void)
return 0; return 0;
} }
/*
* Yucca board as End point and root point setup
* and
* testing inbound and out bound windows
*
* YUCCA board can be plugged into another yucca board or you can get PCI-E
* cable which can be used to setup loop back from one port to another port.
* Please rememeber that unless there is a endpoint plugged in to root port it
* will not initialize. It is the same in case of endpoint , unless there is
* root port attached it will not initialize.
*
* In this release of software all the PCI-E ports are configured as either
* endpoint or rootpoint.In future we will have support for selective ports
* setup as endpoint and root point in single board.
*
* Once your board came up as root point , you can verify by reading
* /proc/bus/pci/devices. Where you can see the configuration registers
* of end point device attached to the port.
*
* Enpoint cofiguration can be verified by connecting Yucca board to any
* host or another yucca board. Then try to scan the device. In case of
* linux use "lspci" or appripriate os command.
*
* How do I verify the inbound and out bound windows ?(yucca to yucca)
* in this configuration inbound and outbound windows are setup to access
* sram memroy area. SRAM is at 0x4 0000 0000 , on PLB bus. This address
* is mapped at 0x90000000. From u-boot prompt write data 0xb000 0000,
* This is waere your POM(PLB out bound memory window) mapped. then
* read the data from other yucca board's u-boot prompt at address
* 0x9000 0000(SRAM). Data should match.
* In case of inbound , write data to u-boot command prompt at 0xb000 0000
* which is mapped to 0x4 0000 0000. Now on rootpoint yucca u-boot prompt check
* data at 0x9000 0000(SRAM).Data should match.
*/
int ppc440spe_init_pcie_rootport(int port) int ppc440spe_init_pcie_rootport(int port)
{ {
static int core_init; static int core_init;
@ -362,9 +396,15 @@ int ppc440spe_init_pcie_rootport(int port)
mdelay(100); mdelay(100);
switch (port) { switch (port) {
case 0: val = SDR_READ(PESDR0_RCSSTS); break; case 0:
case 1: val = SDR_READ(PESDR1_RCSSTS); break; val = SDR_READ(PESDR0_RCSSTS);
case 2: val = SDR_READ(PESDR2_RCSSTS); break; break;
case 1:
val = SDR_READ(PESDR1_RCSSTS);
break;
case 2:
val = SDR_READ(PESDR2_RCSSTS);
break;
} }
if (val & (1 << 20)) { if (val & (1 << 20)) {
@ -376,8 +416,7 @@ int ppc440spe_init_pcie_rootport(int port)
* Verify link is up * Verify link is up
*/ */
val = 0; val = 0;
switch (port) switch (port) {
{
case 0: case 0:
val = SDR_READ(PESDR0_LOOP); val = SDR_READ(PESDR0_LOOP);
break; break;
@ -498,9 +537,223 @@ int ppc440spe_init_pcie_rootport(int port)
return 0; return 0;
} }
void ppc440spe_setup_pcie(struct pci_controller *hose, int port) int ppc440spe_init_pcie_endport(int port)
{
static int core_init;
volatile u32 val = 0;
int attempts;
if (!core_init) {
++core_init;
if (ppc440spe_init_pcie())
return -1;
}
/*
* Initialize various parts of the PCI Express core for our port:
*
* - Set as a end port and enable max width
* (PXIE0 -> X8, PCIE1 and PCIE2 -> X4).
* - Set up UTL configuration.
* - Increase SERDES drive strength to levels suggested by AMCC.
* - De-assert RSTPYN, RSTDL and RSTGU.
*
* NOTICE for revB chip: PESDRn_UTLSET2 is not set - we leave it with
* default setting 0x11310000. The register has new fields,
* PESDRn_UTLSET2[LKINE] in particular: clearing it leads to PCIE core
* hang.
*/
switch (port) {
case 0:
SDR_WRITE(PESDR0_DLPSET, 1 << 24 | PTYPE_LEGACY_ENDPOINT << 20 | LNKW_X8 << 12);
SDR_WRITE(PESDR0_UTLSET1, 0x20222222);
if (!ppc440spe_revB())
SDR_WRITE(PESDR0_UTLSET2, 0x11000000);
SDR_WRITE(PESDR0_HSSL0SET1, 0x35000000);
SDR_WRITE(PESDR0_HSSL1SET1, 0x35000000);
SDR_WRITE(PESDR0_HSSL2SET1, 0x35000000);
SDR_WRITE(PESDR0_HSSL3SET1, 0x35000000);
SDR_WRITE(PESDR0_HSSL4SET1, 0x35000000);
SDR_WRITE(PESDR0_HSSL5SET1, 0x35000000);
SDR_WRITE(PESDR0_HSSL6SET1, 0x35000000);
SDR_WRITE(PESDR0_HSSL7SET1, 0x35000000);
SDR_WRITE(PESDR0_RCSSET,
(SDR_READ(PESDR0_RCSSET) & ~(1 << 24 | 1 << 16)) | 1 << 12);
break;
case 1:
SDR_WRITE(PESDR1_DLPSET, 1 << 24 | PTYPE_LEGACY_ENDPOINT << 20 | LNKW_X4 << 12);
SDR_WRITE(PESDR1_UTLSET1, 0x20222222);
if (!ppc440spe_revB())
SDR_WRITE(PESDR1_UTLSET2, 0x11000000);
SDR_WRITE(PESDR1_HSSL0SET1, 0x35000000);
SDR_WRITE(PESDR1_HSSL1SET1, 0x35000000);
SDR_WRITE(PESDR1_HSSL2SET1, 0x35000000);
SDR_WRITE(PESDR1_HSSL3SET1, 0x35000000);
SDR_WRITE(PESDR1_RCSSET,
(SDR_READ(PESDR1_RCSSET) & ~(1 << 24 | 1 << 16)) | 1 << 12);
break;
case 2:
SDR_WRITE(PESDR2_DLPSET, 1 << 24 | PTYPE_LEGACY_ENDPOINT << 20 | LNKW_X4 << 12);
SDR_WRITE(PESDR2_UTLSET1, 0x20222222);
if (!ppc440spe_revB())
SDR_WRITE(PESDR2_UTLSET2, 0x11000000);
SDR_WRITE(PESDR2_HSSL0SET1, 0x35000000);
SDR_WRITE(PESDR2_HSSL1SET1, 0x35000000);
SDR_WRITE(PESDR2_HSSL2SET1, 0x35000000);
SDR_WRITE(PESDR2_HSSL3SET1, 0x35000000);
SDR_WRITE(PESDR2_RCSSET,
(SDR_READ(PESDR2_RCSSET) & ~(1 << 24 | 1 << 16)) | 1 << 12);
break;
}
/*
* Notice: the following delay has critical impact on device
* initialization - if too short (<50ms) the link doesn't get up.
*/
mdelay(100);
switch (port) {
case 0: val = SDR_READ(PESDR0_RCSSTS); break;
case 1: val = SDR_READ(PESDR1_RCSSTS); break;
case 2: val = SDR_READ(PESDR2_RCSSTS); break;
}
if (val & (1 << 20)) {
printf("PCIE%d: PGRST failed %08x\n", port, val);
return -1;
}
/*
* Verify link is up
*/
val = 0;
switch (port)
{
case 0:
val = SDR_READ(PESDR0_LOOP);
break;
case 1:
val = SDR_READ(PESDR1_LOOP);
break;
case 2:
val = SDR_READ(PESDR2_LOOP);
break;
}
if (!(val & 0x00001000)) {
printf("PCIE%d: link is not up.\n", port);
return -1;
}
/*
* Setup UTL registers - but only on revA!
* We use default settings for revB chip.
*/
if (!ppc440spe_revB())
ppc440spe_setup_utl(port);
/*
* We map PCI Express configuration access into the 512MB regions
*
* NOTICE: revB is very strict about PLB real addressess and ranges to
* be mapped for config space; it seems to only work with d_nnnn_nnnn
* range (hangs the core upon config transaction attempts when set
* otherwise) while revA uses c_nnnn_nnnn.
*
* For revA:
* PCIE0: 0xc_4000_0000
* PCIE1: 0xc_8000_0000
* PCIE2: 0xc_c000_0000
*
* For revB:
* PCIE0: 0xd_0000_0000
* PCIE1: 0xd_2000_0000
* PCIE2: 0xd_4000_0000
*/
switch (port) {
case 0:
if (ppc440spe_revB()) {
mtdcr(DCRN_PEGPL_CFGBAH(PCIE0), 0x0000000d);
mtdcr(DCRN_PEGPL_CFGBAL(PCIE0), 0x00000000);
} else {
/* revA */
mtdcr(DCRN_PEGPL_CFGBAH(PCIE0), 0x0000000c);
mtdcr(DCRN_PEGPL_CFGBAL(PCIE0), 0x40000000);
}
mtdcr(DCRN_PEGPL_CFGMSK(PCIE0), 0xe0000001); /* 512MB region, valid */
break;
case 1:
if (ppc440spe_revB()) {
mtdcr(DCRN_PEGPL_CFGBAH(PCIE1), 0x0000000d);
mtdcr(DCRN_PEGPL_CFGBAL(PCIE1), 0x20000000);
} else {
mtdcr(DCRN_PEGPL_CFGBAH(PCIE1), 0x0000000c);
mtdcr(DCRN_PEGPL_CFGBAL(PCIE1), 0x80000000);
}
mtdcr(DCRN_PEGPL_CFGMSK(PCIE1), 0xe0000001); /* 512MB region, valid */
break;
case 2:
if (ppc440spe_revB()) {
mtdcr(DCRN_PEGPL_CFGBAH(PCIE2), 0x0000000d);
mtdcr(DCRN_PEGPL_CFGBAL(PCIE2), 0x40000000);
} else {
mtdcr(DCRN_PEGPL_CFGBAH(PCIE2), 0x0000000c);
mtdcr(DCRN_PEGPL_CFGBAL(PCIE2), 0xc0000000);
}
mtdcr(DCRN_PEGPL_CFGMSK(PCIE2), 0xe0000001); /* 512MB region, valid */
break;
}
/*
* Check for VC0 active and assert RDY.
*/
attempts = 10;
switch (port) {
case 0:
while(!(SDR_READ(PESDR0_RCSSTS) & (1 << 16))) {
if (!(attempts--)) {
printf("PCIE0: VC0 not active\n");
return -1;
}
mdelay(1000);
}
SDR_WRITE(PESDR0_RCSSET, SDR_READ(PESDR0_RCSSET) | 1 << 20);
break;
case 1:
while(!(SDR_READ(PESDR1_RCSSTS) & (1 << 16))) {
if (!(attempts--)) {
printf("PCIE1: VC0 not active\n");
return -1;
}
mdelay(1000);
}
SDR_WRITE(PESDR1_RCSSET, SDR_READ(PESDR1_RCSSET) | 1 << 20);
break;
case 2:
while(!(SDR_READ(PESDR2_RCSSTS) & (1 << 16))) {
if (!(attempts--)) {
printf("PCIE2: VC0 not active\n");
return -1;
}
mdelay(1000);
}
SDR_WRITE(PESDR2_RCSSET, SDR_READ(PESDR2_RCSSET) | 1 << 20);
break;
}
mdelay(100);
return 0;
}
void ppc440spe_setup_pcie_rootpoint(struct pci_controller *hose, int port)
{ {
volatile void *mbase = NULL; volatile void *mbase = NULL;
volatile void *rmbase = NULL;
pci_set_ops(hose, pci_set_ops(hose,
pcie_read_config_byte, pcie_read_config_byte,
@ -513,14 +766,17 @@ void ppc440spe_setup_pcie(struct pci_controller *hose, int port)
switch (port) { switch (port) {
case 0: case 0:
mbase = (u32 *)CFG_PCIE0_XCFGBASE; mbase = (u32 *)CFG_PCIE0_XCFGBASE;
rmbase = (u32 *)CFG_PCIE0_CFGBASE;
hose->cfg_data = (u8 *)CFG_PCIE0_CFGBASE; hose->cfg_data = (u8 *)CFG_PCIE0_CFGBASE;
break; break;
case 1: case 1:
mbase = (u32 *)CFG_PCIE1_XCFGBASE; mbase = (u32 *)CFG_PCIE1_XCFGBASE;
rmbase = (u32 *)CFG_PCIE1_CFGBASE;
hose->cfg_data = (u8 *)CFG_PCIE1_CFGBASE; hose->cfg_data = (u8 *)CFG_PCIE1_CFGBASE;
break; break;
case 2: case 2:
mbase = (u32 *)CFG_PCIE2_XCFGBASE; mbase = (u32 *)CFG_PCIE2_XCFGBASE;
rmbase = (u32 *)CFG_PCIE2_CFGBASE;
hose->cfg_data = (u8 *)CFG_PCIE2_CFGBASE; hose->cfg_data = (u8 *)CFG_PCIE2_CFGBASE;
break; break;
} }
@ -528,14 +784,9 @@ void ppc440spe_setup_pcie(struct pci_controller *hose, int port)
/* /*
* Set bus numbers on our root port * Set bus numbers on our root port
*/ */
if (ppc440spe_revB()) {
out_8((u8 *)mbase + PCI_PRIMARY_BUS, 0); out_8((u8 *)mbase + PCI_PRIMARY_BUS, 0);
out_8((u8 *)mbase + PCI_SECONDARY_BUS, 1); out_8((u8 *)mbase + PCI_SECONDARY_BUS, 1);
out_8((u8 *)mbase + PCI_SUBORDINATE_BUS, 1); out_8((u8 *)mbase + PCI_SUBORDINATE_BUS, 1);
} else {
out_8((u8 *)mbase + PCI_PRIMARY_BUS, 0);
out_8((u8 *)mbase + PCI_SECONDARY_BUS, 0);
}
/* /*
* Set up outbound translation to hose->mem_space from PLB * Set up outbound translation to hose->mem_space from PLB
@ -544,8 +795,7 @@ void ppc440spe_setup_pcie(struct pci_controller *hose, int port)
* subregions and to enable the outbound translation. * subregions and to enable the outbound translation.
*/ */
out_le32(mbase + PECFG_POM0LAH, 0x00000000); out_le32(mbase + PECFG_POM0LAH, 0x00000000);
out_le32(mbase + PECFG_POM0LAL, (CFG_PCIE_MEMBASE + out_le32(mbase + PECFG_POM0LAL, 0x00000000);
port * CFG_PCIE_MEMSIZE));
switch (port) { switch (port) {
case 0: case 0:
@ -579,14 +829,134 @@ void ppc440spe_setup_pcie(struct pci_controller *hose, int port)
out_le32(mbase + PCI_BASE_ADDRESS_1, 0); out_le32(mbase + PCI_BASE_ADDRESS_1, 0);
out_le32(mbase + PECFG_BAR0HMPA, 0x7fffffc); out_le32(mbase + PECFG_BAR0HMPA, 0x7fffffc);
out_le32(mbase + PECFG_BAR0LMPA, 0); out_le32(mbase + PECFG_BAR0LMPA, 0);
out_le32(mbase + PECFG_PIM01SAH, 0xffff0000);
out_le32(mbase + PECFG_PIM01SAL, 0x00000000);
out_le32(mbase + PECFG_PIM0LAL, 0); out_le32(mbase + PECFG_PIM0LAL, 0);
out_le32(mbase + PECFG_PIM0LAH, 0); out_le32(mbase + PECFG_PIM0LAH, 0);
out_le32(mbase + PECFG_PIM1LAL, 0x00000000);
out_le32(mbase + PECFG_PIM1LAH, 0x00000004);
out_le32(mbase + PECFG_PIMEN, 0x1); out_le32(mbase + PECFG_PIMEN, 0x1);
/* Enable I/O, Mem, and Busmaster cycles */ /* Enable I/O, Mem, and Busmaster cycles */
out_le16((u16 *)(mbase + PCI_COMMAND), out_le16((u16 *)(mbase + PCI_COMMAND),
in_le16((u16 *)(mbase + PCI_COMMAND)) | in_le16((u16 *)(mbase + PCI_COMMAND)) |
PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER); PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
printf("PCIE:%d successfully set as rootpoint\n",port);
}
int ppc440spe_setup_pcie_endpoint(struct pci_controller *hose, int port)
{
volatile void *mbase = NULL;
int attempts = 0;
pci_set_ops(hose,
pcie_read_config_byte,
pcie_read_config_word,
pcie_read_config_dword,
pcie_write_config_byte,
pcie_write_config_word,
pcie_write_config_dword);
switch (port) {
case 0:
mbase = (u32 *)CFG_PCIE0_XCFGBASE;
hose->cfg_data = (u8 *)CFG_PCIE0_CFGBASE;
break;
case 1:
mbase = (u32 *)CFG_PCIE1_XCFGBASE;
hose->cfg_data = (u8 *)CFG_PCIE1_CFGBASE;
break;
case 2:
mbase = (u32 *)CFG_PCIE2_XCFGBASE;
hose->cfg_data = (u8 *)CFG_PCIE2_CFGBASE;
break;
}
/*
* Set up outbound translation to hose->mem_space from PLB
* addresses at an offset of 0xd_0000_0000. We set the low
* bits of the mask to 11 to turn off splitting into 8
* subregions and to enable the outbound translation.
*/
out_le32(mbase + PECFG_POM0LAH, 0x00001ff8);
out_le32(mbase + PECFG_POM0LAL, 0x00001000);
switch (port) {
case 0:
mtdcr(DCRN_PEGPL_OMR1BAH(PCIE0), 0x0000000d);
mtdcr(DCRN_PEGPL_OMR1BAL(PCIE0), CFG_PCIE_MEMBASE +
port * CFG_PCIE_MEMSIZE);
mtdcr(DCRN_PEGPL_OMR1MSKH(PCIE0), 0x7fffffff);
mtdcr(DCRN_PEGPL_OMR1MSKL(PCIE0),
~(CFG_PCIE_MEMSIZE - 1) | 3);
break;
case 1:
mtdcr(DCRN_PEGPL_OMR1BAH(PCIE1), 0x0000000d);
mtdcr(DCRN_PEGPL_OMR1BAL(PCIE1), (CFG_PCIE_MEMBASE +
port * CFG_PCIE_MEMSIZE));
mtdcr(DCRN_PEGPL_OMR1MSKH(PCIE1), 0x7fffffff);
mtdcr(DCRN_PEGPL_OMR1MSKL(PCIE1),
~(CFG_PCIE_MEMSIZE - 1) | 3);
break;
case 2:
mtdcr(DCRN_PEGPL_OMR1BAH(PCIE2), 0x0000000d);
mtdcr(DCRN_PEGPL_OMR1BAL(PCIE2), (CFG_PCIE_MEMBASE +
port * CFG_PCIE_MEMSIZE));
mtdcr(DCRN_PEGPL_OMR1MSKH(PCIE2), 0x7fffffff);
mtdcr(DCRN_PEGPL_OMR1MSKL(PCIE2),
~(CFG_PCIE_MEMSIZE - 1) | 3);
break;
}
/* Set up 16GB inbound memory window at 0 */
out_le32(mbase + PCI_BASE_ADDRESS_0, 0);
out_le32(mbase + PCI_BASE_ADDRESS_1, 0);
out_le32(mbase + PECFG_BAR0HMPA, 0x7fffffc);
out_le32(mbase + PECFG_BAR0LMPA, 0);
out_le32(mbase + PECFG_PIM0LAL, 0x00000000);
out_le32(mbase + PECFG_PIM0LAH, 0x00000004); /* pointing to SRAM */
out_le32(mbase + PECFG_PIMEN, 0x1);
/* Enable I/O, Mem, and Busmaster cycles */
out_le16((u16 *)(mbase + PCI_COMMAND),
in_le16((u16 *)(mbase + PCI_COMMAND)) |
PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
out_le16(mbase + 0x200,0xcaad); /* Setting vendor ID */
out_le16(mbase + 0x202,0xfeed); /* Setting device ID */
attempts = 10;
switch (port) {
case 0:
while (!(SDR_READ(PESDR0_RCSSTS) & (1 << 8))) {
if (!(attempts--)) {
printf("PCIE0: BMEN is not active\n");
return -1;
}
mdelay(1000);
}
break;
case 1:
while (!(SDR_READ(PESDR1_RCSSTS) & (1 << 8))) {
if (!(attempts--)) {
printf("PCIE1: BMEN is not active\n");
return -1;
}
mdelay(1000);
}
break;
case 2:
while (!(SDR_READ(PESDR2_RCSSTS) & (1 << 8))) {
if (!(attempts--)) {
printf("PCIE2: BMEN is not active\n");
return -1;
}
mdelay(1000);
}
break;
}
printf("PCIE:%d successfully set as endpoint\n",port);
return 0;
} }
#endif /* CONFIG_PCI */ #endif /* CONFIG_PCI */
#endif /* CONFIG_440SPE */ #endif /* CONFIG_440SPE */

View File

@ -139,9 +139,17 @@
*/ */
#define PECFG_BAR0LMPA 0x210 #define PECFG_BAR0LMPA 0x210
#define PECFG_BAR0HMPA 0x214 #define PECFG_BAR0HMPA 0x214
#define PECFG_BAR1MPA 0x218
#define PECFG_BAR2MPA 0x220
#define PECFG_PIMEN 0x33c #define PECFG_PIMEN 0x33c
#define PECFG_PIM0LAL 0x340 #define PECFG_PIM0LAL 0x340
#define PECFG_PIM0LAH 0x344 #define PECFG_PIM0LAH 0x344
#define PECFG_PIM1LAL 0x348
#define PECFG_PIM1LAH 0x34c
#define PECFG_PIM01SAL 0x350
#define PECFG_PIM01SAH 0x354
#define PECFG_POM0LAL 0x380 #define PECFG_POM0LAL 0x380
#define PECFG_POM0LAH 0x384 #define PECFG_POM0LAH 0x384
@ -156,7 +164,8 @@
int ppc440spe_init_pcie(void); int ppc440spe_init_pcie(void);
int ppc440spe_init_pcie_rootport(int port); int ppc440spe_init_pcie_rootport(int port);
void yucca_setup_pcie_fpga_rootpoint(int port); void yucca_setup_pcie_fpga_rootpoint(int port);
void ppc440spe_setup_pcie(struct pci_controller *hose, int port); void ppc440spe_setup_pcie_rootpoint(struct pci_controller *hose, int port);
int ppc440spe_setup_pcie_endpoint(struct pci_controller *hose, int port);
int yucca_pcie_card_present(int port); int yucca_pcie_card_present(int port);
int pcie_hose_scan(struct pci_controller *hose, int bus); int pcie_hose_scan(struct pci_controller *hose, int bus);
#endif /* __440SPE_PCIE_H */ #endif /* __440SPE_PCIE_H */