mirror of
https://github.com/Stichting-MINIX-Research-Foundation/u-boot.git
synced 2025-09-09 20:18:54 -04:00
ppc4xx: Make 440SPe PCIe code more generic to use on different 4xx PPCs (3)
(3) This patch introduces macros like SDRN_PESDR_DLPSET(port) to access the SDR registers of the PCIe ports. This makes the overall design clearer, since it removed a lot of switch statements which are not needed anymore. Also, the functions ppc4xx_init_pcie_rootport() and ppc4xx_init_pcie_entport() are merged into a single function ppc4xx_init_pcie_port(), since most of the code was duplicated. This makes maintainance and porting to other 4xx platforms easier. Signed-off-by: Stefan Roese <sr@denx.de>
This commit is contained in:
parent
026f711068
commit
03d344bb6a
@ -368,11 +368,167 @@ int ppc4xx_init_pcie(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Yucca board as End point and root point setup
|
* Board-specific pcie initialization
|
||||||
|
* Platform code can reimplement ppc4xx_init_pcie_port_hw() if needed
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initialize various parts of the PCI Express core for our port:
|
||||||
|
*
|
||||||
|
* - Set as a root 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 440SPE 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.
|
||||||
|
*/
|
||||||
|
#if defined(CONFIG_440SPE)
|
||||||
|
int __ppc4xx_init_pcie_port_hw(int port, int rootport)
|
||||||
|
{
|
||||||
|
u32 val = 1 << 24;
|
||||||
|
u32 utlset1;
|
||||||
|
|
||||||
|
if (rootport) {
|
||||||
|
val = PTYPE_ROOT_PORT << 20;
|
||||||
|
utlset1 = 0x21222222;
|
||||||
|
} else {
|
||||||
|
val = PTYPE_LEGACY_ENDPOINT << 20;
|
||||||
|
utlset1 = 0x20222222;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (port == 0)
|
||||||
|
val |= LNKW_X8 << 12;
|
||||||
|
else
|
||||||
|
val |= LNKW_X4 << 12;
|
||||||
|
|
||||||
|
SDR_WRITE(SDRN_PESDR_DLPSET(port), val);
|
||||||
|
SDR_WRITE(SDRN_PESDR_UTLSET1(port), utlset1);
|
||||||
|
if (!ppc440spe_revB())
|
||||||
|
SDR_WRITE(SDRN_PESDR_UTLSET2(port), 0x11000000);
|
||||||
|
SDR_WRITE(SDRN_PESDR_HSSL0SET1(port), 0x35000000);
|
||||||
|
SDR_WRITE(SDRN_PESDR_HSSL1SET1(port), 0x35000000);
|
||||||
|
SDR_WRITE(SDRN_PESDR_HSSL2SET1(port), 0x35000000);
|
||||||
|
SDR_WRITE(SDRN_PESDR_HSSL3SET1(port), 0x35000000);
|
||||||
|
if (port == 0) {
|
||||||
|
SDR_WRITE(PESDR0_HSSL4SET1, 0x35000000);
|
||||||
|
SDR_WRITE(PESDR0_HSSL5SET1, 0x35000000);
|
||||||
|
SDR_WRITE(PESDR0_HSSL6SET1, 0x35000000);
|
||||||
|
SDR_WRITE(PESDR0_HSSL7SET1, 0x35000000);
|
||||||
|
}
|
||||||
|
SDR_WRITE(SDRN_PESDR_RCSSET(port), (SDR_READ(SDRN_PESDR_RCSSET(port)) &
|
||||||
|
~(1 << 24 | 1 << 16)) | 1 << 12);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_440SPE */
|
||||||
|
|
||||||
|
#if defined(CONFIG_405EX)
|
||||||
|
int __ppc4xx_init_pcie_port_hw(int port, int rootport)
|
||||||
|
{
|
||||||
|
u32 val;
|
||||||
|
|
||||||
|
if (rootport)
|
||||||
|
val = 0x00401000;
|
||||||
|
else
|
||||||
|
val = 0x00101000;
|
||||||
|
|
||||||
|
SDR_WRITE(SDRN_PESDR_DLPSET(port), val);
|
||||||
|
SDR_WRITE(SDRN_PESDR_UTLSET1(port), 0x20222222);
|
||||||
|
SDR_WRITE(SDRN_PESDR_UTLSET2(port), 0x01110000);
|
||||||
|
SDR_WRITE(SDRN_PESDR_PHYSET1(port), 0x720F0000);
|
||||||
|
SDR_WRITE(SDRN_PESDR_PHYSET2(port), 0x70600003);
|
||||||
|
|
||||||
|
/* Assert the PE0_PHY reset */
|
||||||
|
SDR_WRITE(SDRN_PESDR_RCSSET(port), 0x01010000);
|
||||||
|
udelay(1000);
|
||||||
|
|
||||||
|
/* deassert the PE0_hotreset */
|
||||||
|
SDR_WRITE(SDRN_PESDR_RCSSET(port), 0x01101000);
|
||||||
|
|
||||||
|
/* poll for phy !reset */
|
||||||
|
while (!(SDR_READ(SDRN_PESDR_PHYSTA(port)) & 0x00001000))
|
||||||
|
;
|
||||||
|
|
||||||
|
/* deassert the PE0_gpl_utl_reset */
|
||||||
|
SDR_WRITE(SDRN_PESDR_RCSSET(port), 0x00101000);
|
||||||
|
|
||||||
|
if (port == 0)
|
||||||
|
mtdcr(DCRN_PEGPL_CFG(PCIE0), 0x10000000); /* guarded on */
|
||||||
|
else
|
||||||
|
mtdcr(DCRN_PEGPL_CFG(PCIE1), 0x10000000); /* guarded on */
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_405EX */
|
||||||
|
|
||||||
|
int ppc4xx_init_pcie_port_hw(int port, int rootport)
|
||||||
|
__attribute__((weak, alias("__ppc4xx_init_pcie_port_hw")));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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
|
||||||
|
*
|
||||||
|
* For 405EX:
|
||||||
|
* PCIE0: 0xa000_0000
|
||||||
|
* PCIE1: 0xc000_0000
|
||||||
|
*/
|
||||||
|
static inline u64 ppc4xx_get_cfgaddr(int port)
|
||||||
|
{
|
||||||
|
#if defined(CONFIG_405EX)
|
||||||
|
if (port == 0)
|
||||||
|
return (u64)CFG_PCIE0_CFGBASE;
|
||||||
|
else
|
||||||
|
return (u64)CFG_PCIE1_CFGBASE;
|
||||||
|
#endif
|
||||||
|
#if defined(CONFIG_440SPE)
|
||||||
|
if (ppc440spe_revB()) {
|
||||||
|
switch (port) {
|
||||||
|
default: /* to satisfy compiler */
|
||||||
|
case 0:
|
||||||
|
return 0x0000000d00000000ULL;
|
||||||
|
case 1:
|
||||||
|
return 0x0000000d20000000ULL;
|
||||||
|
case 2:
|
||||||
|
return 0x0000000d40000000ULL;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
switch (port) {
|
||||||
|
default: /* to satisfy compiler */
|
||||||
|
case 0:
|
||||||
|
return 0x0000000c40000000ULL;
|
||||||
|
case 1:
|
||||||
|
return 0x0000000c80000000ULL;
|
||||||
|
case 2:
|
||||||
|
return 0x0000000cc0000000ULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 4xx boards as end point and root point setup
|
||||||
* and
|
* and
|
||||||
* testing inbound and out bound windows
|
* testing inbound and out bound windows
|
||||||
*
|
*
|
||||||
* YUCCA board can be plugged into another yucca board or you can get PCI-E
|
* 4xx boards can be plugged into another 4xx boards or you can get PCI-E
|
||||||
* cable which can be used to setup loop back from one port to another port.
|
* 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
|
* 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
|
* will not initialize. It is the same in case of endpoint , unless there is
|
||||||
@ -386,26 +542,28 @@ int ppc4xx_init_pcie(void)
|
|||||||
* /proc/bus/pci/devices. Where you can see the configuration registers
|
* /proc/bus/pci/devices. Where you can see the configuration registers
|
||||||
* of end point device attached to the port.
|
* of end point device attached to the port.
|
||||||
*
|
*
|
||||||
* Enpoint cofiguration can be verified by connecting Yucca board to any
|
* Enpoint cofiguration can be verified by connecting 4xx board to any
|
||||||
* host or another yucca board. Then try to scan the device. In case of
|
* host or another 4xx board. Then try to scan the device. In case of
|
||||||
* linux use "lspci" or appripriate os command.
|
* linux use "lspci" or appripriate os command.
|
||||||
*
|
*
|
||||||
* How do I verify the inbound and out bound windows ?(yucca to yucca)
|
* How do I verify the inbound and out bound windows ? (4xx to 4xx)
|
||||||
* in this configuration inbound and outbound windows are setup to access
|
* 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
|
* 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,
|
* is mapped at 0x90000000. From u-boot prompt write data 0xb000 0000,
|
||||||
* This is waere your POM(PLB out bound memory window) mapped. then
|
* 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
|
* read the data from other 4xx board's u-boot prompt at address
|
||||||
* 0x9000 0000(SRAM). Data should match.
|
* 0x9000 0000(SRAM). Data should match.
|
||||||
* In case of inbound , write data to u-boot command prompt at 0xb000 0000
|
* 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
|
* which is mapped to 0x4 0000 0000. Now on rootpoint yucca u-boot prompt check
|
||||||
* data at 0x9000 0000(SRAM).Data should match.
|
* data at 0x9000 0000(SRAM).Data should match.
|
||||||
*/
|
*/
|
||||||
int ppc4xx_init_pcie_rootport(int port)
|
int ppc4xx_init_pcie_port(int port, int rootport)
|
||||||
{
|
{
|
||||||
static int core_init;
|
static int core_init;
|
||||||
volatile u32 val = 0;
|
volatile u32 val = 0;
|
||||||
int attempts;
|
int attempts;
|
||||||
|
u64 addr;
|
||||||
|
u32 low, high;
|
||||||
|
|
||||||
if (!core_init) {
|
if (!core_init) {
|
||||||
++core_init;
|
++core_init;
|
||||||
@ -414,82 +572,17 @@ int ppc4xx_init_pcie_rootport(int port)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initialize various parts of the PCI Express core for our port:
|
* Initialize various parts of the PCI Express core for our port
|
||||||
*
|
|
||||||
* - Set as a root 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) {
|
ppc4xx_init_pcie_port_hw(port, rootport);
|
||||||
case 0:
|
|
||||||
SDR_WRITE(PESDR0_DLPSET, 1 << 24 | PTYPE_ROOT_PORT << 20 | LNKW_X8 << 12);
|
|
||||||
|
|
||||||
SDR_WRITE(PESDR0_UTLSET1, 0x21222222);
|
|
||||||
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_ROOT_PORT << 20 | LNKW_X4 << 12);
|
|
||||||
SDR_WRITE(PESDR1_UTLSET1, 0x21222222);
|
|
||||||
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_ROOT_PORT << 20 | LNKW_X4 << 12);
|
|
||||||
SDR_WRITE(PESDR2_UTLSET1, 0x21222222);
|
|
||||||
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
|
* Notice: the following delay has critical impact on device
|
||||||
* initialization - if too short (<50ms) the link doesn't get up.
|
* initialization - if too short (<50ms) the link doesn't get up.
|
||||||
*/
|
*/
|
||||||
mdelay(100);
|
mdelay(100);
|
||||||
|
|
||||||
switch (port) {
|
val = SDR_READ(SDRN_PESDR_RCSSTS(sdr_base(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)) {
|
if (val & (1 << 20)) {
|
||||||
printf("PCIE%d: PGRST failed %08x\n", port, val);
|
printf("PCIE%d: PGRST failed %08x\n", port, val);
|
||||||
return -1;
|
return -1;
|
||||||
@ -498,18 +591,7 @@ int ppc4xx_init_pcie_rootport(int port)
|
|||||||
/*
|
/*
|
||||||
* Verify link is up
|
* Verify link is up
|
||||||
*/
|
*/
|
||||||
val = 0;
|
val = SDR_READ(SDRN_PESDR_LOOP(sdr_base(port)));
|
||||||
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)) {
|
if (!(val & 0x00001000)) {
|
||||||
printf("PCIE%d: link is not up.\n", port);
|
printf("PCIE%d: link is not up.\n", port);
|
||||||
return -1;
|
return -1;
|
||||||
@ -524,55 +606,25 @@ int ppc4xx_init_pcie_rootport(int port)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* We map PCI Express configuration access into the 512MB regions
|
* 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
|
|
||||||
*/
|
*/
|
||||||
|
addr = ppc4xx_get_cfgaddr(port);
|
||||||
|
low = (u32)(addr & 0x00000000ffffffff);
|
||||||
|
high = (u32)(addr >> 32);
|
||||||
|
|
||||||
switch (port) {
|
switch (port) {
|
||||||
case 0:
|
case 0:
|
||||||
if (ppc440spe_revB()) {
|
mtdcr(DCRN_PEGPL_CFGBAH(PCIE0), high);
|
||||||
mtdcr(DCRN_PEGPL_CFGBAH(PCIE0), 0x0000000d);
|
mtdcr(DCRN_PEGPL_CFGBAL(PCIE0), low);
|
||||||
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 */
|
mtdcr(DCRN_PEGPL_CFGMSK(PCIE0), 0xe0000001); /* 512MB region, valid */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
if (ppc440spe_revB()) {
|
mtdcr(DCRN_PEGPL_CFGBAH(PCIE1), high);
|
||||||
mtdcr(DCRN_PEGPL_CFGBAH(PCIE1), 0x0000000d);
|
mtdcr(DCRN_PEGPL_CFGBAL(PCIE1), low);
|
||||||
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 */
|
mtdcr(DCRN_PEGPL_CFGMSK(PCIE1), 0xe0000001); /* 512MB region, valid */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 2:
|
case 2:
|
||||||
if (ppc440spe_revB()) {
|
mtdcr(DCRN_PEGPL_CFGBAH(PCIE2), high);
|
||||||
mtdcr(DCRN_PEGPL_CFGBAH(PCIE2), 0x0000000d);
|
mtdcr(DCRN_PEGPL_CFGBAL(PCIE2), low);
|
||||||
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 */
|
mtdcr(DCRN_PEGPL_CFGMSK(PCIE2), 0xe0000001); /* 512MB region, valid */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -581,256 +633,28 @@ int ppc4xx_init_pcie_rootport(int port)
|
|||||||
* Check for VC0 active and assert RDY.
|
* Check for VC0 active and assert RDY.
|
||||||
*/
|
*/
|
||||||
attempts = 10;
|
attempts = 10;
|
||||||
switch (port) {
|
while(!(SDR_READ(SDRN_PESDR_RCSSTS(sdr_base(port))) & (1 << 16))) {
|
||||||
case 0:
|
if (!(attempts--)) {
|
||||||
while(!(SDR_READ(PESDR0_RCSSTS) & (1 << 16))) {
|
printf("PCIE%d: VC0 not active\n", port);
|
||||||
if (!(attempts--)) {
|
return -1;
|
||||||
printf("PCIE0: VC0 not active\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
mdelay(1000);
|
|
||||||
}
|
}
|
||||||
SDR_WRITE(PESDR0_RCSSET, SDR_READ(PESDR0_RCSSET) | 1 << 20);
|
mdelay(1000);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
SDR_WRITE(SDRN_PESDR_RCSSET(sdr_base(port)),
|
||||||
|
SDR_READ(SDRN_PESDR_RCSSET(sdr_base(port))) | 1 << 20);
|
||||||
mdelay(100);
|
mdelay(100);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int ppc4xx_init_pcie_rootport(int port)
|
||||||
|
{
|
||||||
|
return ppc4xx_init_pcie_port(port, 1);
|
||||||
|
}
|
||||||
|
|
||||||
int ppc4xx_init_pcie_endport(int port)
|
int ppc4xx_init_pcie_endport(int port)
|
||||||
{
|
{
|
||||||
static int core_init;
|
return ppc4xx_init_pcie_port(port, 0);
|
||||||
volatile u32 val = 0;
|
|
||||||
int attempts;
|
|
||||||
|
|
||||||
if (!core_init) {
|
|
||||||
++core_init;
|
|
||||||
if (ppc4xx_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())
|
|
||||||
ppc4xx_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 ppc4xx_setup_pcie_rootpoint(struct pci_controller *hose, int port)
|
void ppc4xx_setup_pcie_rootpoint(struct pci_controller *hose, int port)
|
||||||
@ -839,12 +663,12 @@ void ppc4xx_setup_pcie_rootpoint(struct pci_controller *hose, int port)
|
|||||||
volatile void *rmbase = NULL;
|
volatile void *rmbase = NULL;
|
||||||
|
|
||||||
pci_set_ops(hose,
|
pci_set_ops(hose,
|
||||||
pcie_read_config_byte,
|
pcie_read_config_byte,
|
||||||
pcie_read_config_word,
|
pcie_read_config_word,
|
||||||
pcie_read_config_dword,
|
pcie_read_config_dword,
|
||||||
pcie_write_config_byte,
|
pcie_write_config_byte,
|
||||||
pcie_write_config_word,
|
pcie_write_config_word,
|
||||||
pcie_write_config_dword);
|
pcie_write_config_dword);
|
||||||
|
|
||||||
switch (port) {
|
switch (port) {
|
||||||
case 0:
|
case 0:
|
||||||
@ -884,26 +708,26 @@ void ppc4xx_setup_pcie_rootpoint(struct pci_controller *hose, int port)
|
|||||||
case 0:
|
case 0:
|
||||||
mtdcr(DCRN_PEGPL_OMR1BAH(PCIE0), 0x0000000d);
|
mtdcr(DCRN_PEGPL_OMR1BAH(PCIE0), 0x0000000d);
|
||||||
mtdcr(DCRN_PEGPL_OMR1BAL(PCIE0), CFG_PCIE_MEMBASE +
|
mtdcr(DCRN_PEGPL_OMR1BAL(PCIE0), CFG_PCIE_MEMBASE +
|
||||||
port * CFG_PCIE_MEMSIZE);
|
port * CFG_PCIE_MEMSIZE);
|
||||||
mtdcr(DCRN_PEGPL_OMR1MSKH(PCIE0), 0x7fffffff);
|
mtdcr(DCRN_PEGPL_OMR1MSKH(PCIE0), 0x7fffffff);
|
||||||
mtdcr(DCRN_PEGPL_OMR1MSKL(PCIE0),
|
mtdcr(DCRN_PEGPL_OMR1MSKL(PCIE0),
|
||||||
~(CFG_PCIE_MEMSIZE - 1) | 3);
|
~(CFG_PCIE_MEMSIZE - 1) | 3);
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
mtdcr(DCRN_PEGPL_OMR1BAH(PCIE1), 0x0000000d);
|
mtdcr(DCRN_PEGPL_OMR1BAH(PCIE1), 0x0000000d);
|
||||||
mtdcr(DCRN_PEGPL_OMR1BAL(PCIE1), (CFG_PCIE_MEMBASE +
|
mtdcr(DCRN_PEGPL_OMR1BAL(PCIE1), CFG_PCIE_MEMBASE +
|
||||||
port * CFG_PCIE_MEMSIZE));
|
port * CFG_PCIE_MEMSIZE);
|
||||||
mtdcr(DCRN_PEGPL_OMR1MSKH(PCIE1), 0x7fffffff);
|
mtdcr(DCRN_PEGPL_OMR1MSKH(PCIE1), 0x7fffffff);
|
||||||
mtdcr(DCRN_PEGPL_OMR1MSKL(PCIE1),
|
mtdcr(DCRN_PEGPL_OMR1MSKL(PCIE1),
|
||||||
~(CFG_PCIE_MEMSIZE - 1) | 3);
|
~(CFG_PCIE_MEMSIZE - 1) | 3);
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
mtdcr(DCRN_PEGPL_OMR1BAH(PCIE2), 0x0000000d);
|
mtdcr(DCRN_PEGPL_OMR1BAH(PCIE2), 0x0000000d);
|
||||||
mtdcr(DCRN_PEGPL_OMR1BAL(PCIE2), (CFG_PCIE_MEMBASE +
|
mtdcr(DCRN_PEGPL_OMR1BAL(PCIE2), CFG_PCIE_MEMBASE +
|
||||||
port * CFG_PCIE_MEMSIZE));
|
port * CFG_PCIE_MEMSIZE);
|
||||||
mtdcr(DCRN_PEGPL_OMR1MSKH(PCIE2), 0x7fffffff);
|
mtdcr(DCRN_PEGPL_OMR1MSKH(PCIE2), 0x7fffffff);
|
||||||
mtdcr(DCRN_PEGPL_OMR1MSKL(PCIE2),
|
mtdcr(DCRN_PEGPL_OMR1MSKL(PCIE2),
|
||||||
~(CFG_PCIE_MEMSIZE - 1) | 3);
|
~(CFG_PCIE_MEMSIZE - 1) | 3);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -925,7 +749,6 @@ void ppc4xx_setup_pcie_rootpoint(struct pci_controller *hose, int port)
|
|||||||
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);
|
|
||||||
|
|
||||||
/* Set Device and Vendor Id */
|
/* Set Device and Vendor Id */
|
||||||
switch (port) {
|
switch (port) {
|
||||||
@ -949,6 +772,7 @@ void ppc4xx_setup_pcie_rootpoint(struct pci_controller *hose, int port)
|
|||||||
/* Set Class Code to PCI-PCI bridge and Revision Id to 1 */
|
/* Set Class Code to PCI-PCI bridge and Revision Id to 1 */
|
||||||
out_le32(mbase + 0x208, 0x06040001);
|
out_le32(mbase + 0x208, 0x06040001);
|
||||||
|
|
||||||
|
printf("PCIE:%d successfully set as rootpoint\n", port);
|
||||||
}
|
}
|
||||||
|
|
||||||
int ppc4xx_setup_pcie_endpoint(struct pci_controller *hose, int port)
|
int ppc4xx_setup_pcie_endpoint(struct pci_controller *hose, int port)
|
||||||
@ -992,26 +816,26 @@ int ppc4xx_setup_pcie_endpoint(struct pci_controller *hose, int port)
|
|||||||
case 0:
|
case 0:
|
||||||
mtdcr(DCRN_PEGPL_OMR1BAH(PCIE0), 0x0000000d);
|
mtdcr(DCRN_PEGPL_OMR1BAH(PCIE0), 0x0000000d);
|
||||||
mtdcr(DCRN_PEGPL_OMR1BAL(PCIE0), CFG_PCIE_MEMBASE +
|
mtdcr(DCRN_PEGPL_OMR1BAL(PCIE0), CFG_PCIE_MEMBASE +
|
||||||
port * CFG_PCIE_MEMSIZE);
|
port * CFG_PCIE_MEMSIZE);
|
||||||
mtdcr(DCRN_PEGPL_OMR1MSKH(PCIE0), 0x7fffffff);
|
mtdcr(DCRN_PEGPL_OMR1MSKH(PCIE0), 0x7fffffff);
|
||||||
mtdcr(DCRN_PEGPL_OMR1MSKL(PCIE0),
|
mtdcr(DCRN_PEGPL_OMR1MSKL(PCIE0),
|
||||||
~(CFG_PCIE_MEMSIZE - 1) | 3);
|
~(CFG_PCIE_MEMSIZE - 1) | 3);
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
mtdcr(DCRN_PEGPL_OMR1BAH(PCIE1), 0x0000000d);
|
mtdcr(DCRN_PEGPL_OMR1BAH(PCIE1), 0x0000000d);
|
||||||
mtdcr(DCRN_PEGPL_OMR1BAL(PCIE1), (CFG_PCIE_MEMBASE +
|
mtdcr(DCRN_PEGPL_OMR1BAL(PCIE1), CFG_PCIE_MEMBASE +
|
||||||
port * CFG_PCIE_MEMSIZE));
|
port * CFG_PCIE_MEMSIZE);
|
||||||
mtdcr(DCRN_PEGPL_OMR1MSKH(PCIE1), 0x7fffffff);
|
mtdcr(DCRN_PEGPL_OMR1MSKH(PCIE1), 0x7fffffff);
|
||||||
mtdcr(DCRN_PEGPL_OMR1MSKL(PCIE1),
|
mtdcr(DCRN_PEGPL_OMR1MSKL(PCIE1),
|
||||||
~(CFG_PCIE_MEMSIZE - 1) | 3);
|
~(CFG_PCIE_MEMSIZE - 1) | 3);
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
mtdcr(DCRN_PEGPL_OMR1BAH(PCIE2), 0x0000000d);
|
mtdcr(DCRN_PEGPL_OMR1BAH(PCIE2), 0x0000000d);
|
||||||
mtdcr(DCRN_PEGPL_OMR1BAL(PCIE2), (CFG_PCIE_MEMBASE +
|
mtdcr(DCRN_PEGPL_OMR1BAL(PCIE2), CFG_PCIE_MEMBASE +
|
||||||
port * CFG_PCIE_MEMSIZE));
|
port * CFG_PCIE_MEMSIZE);
|
||||||
mtdcr(DCRN_PEGPL_OMR1MSKH(PCIE2), 0x7fffffff);
|
mtdcr(DCRN_PEGPL_OMR1MSKH(PCIE2), 0x7fffffff);
|
||||||
mtdcr(DCRN_PEGPL_OMR1MSKL(PCIE2),
|
mtdcr(DCRN_PEGPL_OMR1MSKL(PCIE2),
|
||||||
~(CFG_PCIE_MEMSIZE - 1) | 3);
|
~(CFG_PCIE_MEMSIZE - 1) | 3);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1026,40 +850,20 @@ int ppc4xx_setup_pcie_endpoint(struct pci_controller *hose, int port)
|
|||||||
|
|
||||||
/* 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);
|
||||||
out_le16(mbase + 0x200,0xcaad); /* Setting vendor ID */
|
out_le16(mbase + 0x200,0xcaad); /* Setting vendor ID */
|
||||||
out_le16(mbase + 0x202,0xfeed); /* Setting device ID */
|
out_le16(mbase + 0x202,0xfeed); /* Setting device ID */
|
||||||
|
|
||||||
attempts = 10;
|
attempts = 10;
|
||||||
switch (port) {
|
while(!(SDR_READ(SDRN_PESDR_RCSSTS(sdr_base(port))) & (1 << 8))) {
|
||||||
case 0:
|
if (!(attempts--)) {
|
||||||
while (!(SDR_READ(PESDR0_RCSSTS) & (1 << 8))) {
|
printf("PCIE%d: BME not active\n", port);
|
||||||
if (!(attempts--)) {
|
return -1;
|
||||||
printf("PCIE0: BMEN is not active\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
mdelay(1000);
|
|
||||||
}
|
}
|
||||||
break;
|
mdelay(1000);
|
||||||
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);
|
printf("PCIE:%d successfully set as endpoint\n",port);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -12,14 +12,20 @@
|
|||||||
#ifndef __4XX_PCIE_H
|
#ifndef __4XX_PCIE_H
|
||||||
#define __4XX_PCIE_H
|
#define __4XX_PCIE_H
|
||||||
|
|
||||||
#define mdelay(n) ({unsigned long __ms=(n); while (__ms--) udelay(1000);})
|
|
||||||
|
|
||||||
#define DCRN_SDR0_CFGADDR 0x00e
|
#define DCRN_SDR0_CFGADDR 0x00e
|
||||||
#define DCRN_SDR0_CFGDATA 0x00f
|
#define DCRN_SDR0_CFGDATA 0x00f
|
||||||
|
|
||||||
|
#if defined(CONFIG_440SPE)
|
||||||
#define DCRN_PCIE0_BASE 0x100
|
#define DCRN_PCIE0_BASE 0x100
|
||||||
#define DCRN_PCIE1_BASE 0x120
|
#define DCRN_PCIE1_BASE 0x120
|
||||||
#define DCRN_PCIE2_BASE 0x140
|
#define DCRN_PCIE2_BASE 0x140
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(CONFIG_405EX)
|
||||||
|
#define DCRN_PCIE0_BASE 0x040
|
||||||
|
#define DCRN_PCIE1_BASE 0x060
|
||||||
|
#endif
|
||||||
|
|
||||||
#define PCIE0 DCRN_PCIE0_BASE
|
#define PCIE0 DCRN_PCIE0_BASE
|
||||||
#define PCIE1 DCRN_PCIE1_BASE
|
#define PCIE1 DCRN_PCIE1_BASE
|
||||||
#define PCIE2 DCRN_PCIE2_BASE
|
#define PCIE2 DCRN_PCIE2_BASE
|
||||||
@ -47,6 +53,39 @@
|
|||||||
#define PESDR0_PLLLCT2 0x03a1
|
#define PESDR0_PLLLCT2 0x03a1
|
||||||
#define PESDR0_PLLLCT3 0x03a2
|
#define PESDR0_PLLLCT3 0x03a2
|
||||||
|
|
||||||
|
#if defined(CONFIG_440SPE)
|
||||||
|
#define PCIE0_SDR 0x300
|
||||||
|
#define PCIE1_SDR 0x340
|
||||||
|
#define PCIE2_SDR 0x370
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(CONFIG_405EX)
|
||||||
|
#define PCIE0_SDR 0x400
|
||||||
|
#define PCIE1_SDR 0x440
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* common regs, at least for 405EX and 440SPe */
|
||||||
|
#define SDRN_PESDR_UTLSET1(n) (sdr_base(n) + 0x00)
|
||||||
|
#define SDRN_PESDR_UTLSET2(n) (sdr_base(n) + 0x01)
|
||||||
|
#define SDRN_PESDR_DLPSET(n) (sdr_base(n) + 0x02)
|
||||||
|
#define SDRN_PESDR_LOOP(n) (sdr_base(n) + 0x03)
|
||||||
|
#define SDRN_PESDR_RCSSET(n) (sdr_base(n) + 0x04)
|
||||||
|
#define SDRN_PESDR_RCSSTS(n) (sdr_base(n) + 0x05)
|
||||||
|
|
||||||
|
#if defined(CONFIG_440SPE)
|
||||||
|
#define SDRN_PESDR_HSSL0SET1(n) (sdr_base(n) + 0x06)
|
||||||
|
#define SDRN_PESDR_HSSL0SET2(n) (sdr_base(n) + 0x07)
|
||||||
|
#define SDRN_PESDR_HSSL0STS(n) (sdr_base(n) + 0x08)
|
||||||
|
#define SDRN_PESDR_HSSL1SET1(n) (sdr_base(n) + 0x09)
|
||||||
|
#define SDRN_PESDR_HSSL1SET2(n) (sdr_base(n) + 0x0a)
|
||||||
|
#define SDRN_PESDR_HSSL1STS(n) (sdr_base(n) + 0x0b)
|
||||||
|
#define SDRN_PESDR_HSSL2SET1(n) (sdr_base(n) + 0x0c)
|
||||||
|
#define SDRN_PESDR_HSSL2SET2(n) (sdr_base(n) + 0x0d)
|
||||||
|
#define SDRN_PESDR_HSSL2STS(n) (sdr_base(n) + 0x0e)
|
||||||
|
#define SDRN_PESDR_HSSL3SET1(n) (sdr_base(n) + 0x0f)
|
||||||
|
#define SDRN_PESDR_HSSL3SET2(n) (sdr_base(n) + 0x10)
|
||||||
|
#define SDRN_PESDR_HSSL3STS(n) (sdr_base(n) + 0x11)
|
||||||
|
|
||||||
#define PESDR0_UTLSET1 0x0300
|
#define PESDR0_UTLSET1 0x0300
|
||||||
#define PESDR0_UTLSET2 0x0301
|
#define PESDR0_UTLSET2 0x0301
|
||||||
#define PESDR0_DLPSET 0x0302
|
#define PESDR0_DLPSET 0x0302
|
||||||
@ -123,6 +162,40 @@
|
|||||||
#define PESDR2_HSSCTLSET 0x0382
|
#define PESDR2_HSSCTLSET 0x0382
|
||||||
#define PESDR2_LANE_ABCD 0x0383
|
#define PESDR2_LANE_ABCD 0x0383
|
||||||
|
|
||||||
|
#elif defined(CONFIG_405EX)
|
||||||
|
|
||||||
|
#define SDRN_PESDR_PHYSET1(n) (sdr_base(n) + 0x06)
|
||||||
|
#define SDRN_PESDR_PHYSET2(n) (sdr_base(n) + 0x07)
|
||||||
|
#define SDRN_PESDR_BIST(n) (sdr_base(n) + 0x08)
|
||||||
|
#define SDRN_PESDR_LPB(n) (sdr_base(n) + 0x0b)
|
||||||
|
#define SDRN_PESDR_PHYSTA(n) (sdr_base(n) + 0x0c)
|
||||||
|
|
||||||
|
#define PESDR0_UTLSET1 0x0400
|
||||||
|
#define PESDR0_UTLSET2 0x0401
|
||||||
|
#define PESDR0_DLPSET 0x0402
|
||||||
|
#define PESDR0_LOOP 0x0403
|
||||||
|
#define PESDR0_RCSSET 0x0404
|
||||||
|
#define PESDR0_RCSSTS 0x0405
|
||||||
|
#define PESDR0_PHYSET1 0x0406
|
||||||
|
#define PESDR0_PHYSET2 0x0407
|
||||||
|
#define PESDR0_BIST 0x0408
|
||||||
|
#define PESDR0_LPB 0x040B
|
||||||
|
#define PESDR0_PHYSTA 0x040C
|
||||||
|
|
||||||
|
#define PESDR1_UTLSET1 0x0440
|
||||||
|
#define PESDR1_UTLSET2 0x0441
|
||||||
|
#define PESDR1_DLPSET 0x0442
|
||||||
|
#define PESDR1_LOOP 0x0443
|
||||||
|
#define PESDR1_RCSSET 0x0444
|
||||||
|
#define PESDR1_RCSSTS 0x0445
|
||||||
|
#define PESDR1_PHYSET1 0x0446
|
||||||
|
#define PESDR1_PHYSET2 0x0447
|
||||||
|
#define PESDR1_BIST 0x0448
|
||||||
|
#define PESDR1_LPB 0x044B
|
||||||
|
#define PESDR1_PHYSTA 0x044C
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* UTL register offsets
|
* UTL register offsets
|
||||||
*/
|
*/
|
||||||
@ -166,8 +239,32 @@
|
|||||||
|
|
||||||
int ppc4xx_init_pcie(void);
|
int ppc4xx_init_pcie(void);
|
||||||
int ppc4xx_init_pcie_rootport(int port);
|
int ppc4xx_init_pcie_rootport(int port);
|
||||||
|
int ppc4xx_init_pcie_endport(int port);
|
||||||
void ppc4xx_setup_pcie_rootpoint(struct pci_controller *hose, int port);
|
void ppc4xx_setup_pcie_rootpoint(struct pci_controller *hose, int port);
|
||||||
int ppc4xx_setup_pcie_endpoint(struct pci_controller *hose, int port);
|
int ppc4xx_setup_pcie_endpoint(struct pci_controller *hose, int port);
|
||||||
int pcie_hose_scan(struct pci_controller *hose, int bus);
|
int pcie_hose_scan(struct pci_controller *hose, int bus);
|
||||||
|
|
||||||
|
static inline void mdelay(int n)
|
||||||
|
{
|
||||||
|
u32 ms = n;
|
||||||
|
|
||||||
|
while (ms--)
|
||||||
|
udelay(1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline u32 sdr_base(int port)
|
||||||
|
{
|
||||||
|
switch (port) {
|
||||||
|
default: /* to satisfy compiler */
|
||||||
|
case 0:
|
||||||
|
return PCIE0_SDR;
|
||||||
|
case 1:
|
||||||
|
return PCIE1_SDR;
|
||||||
|
#if defined(PCIE2_SDR)
|
||||||
|
case 2:
|
||||||
|
return PCIE2_SDR;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* __4XX_PCIE_H */
|
#endif /* __4XX_PCIE_H */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user