ppc4xx: Add PCIe endpoint support on Kilauea (405EX)
authorStefan Roese <sr@denx.de>
Thu, 18 Oct 2007 05:39:38 +0000 (07:39 +0200)
committerStefan Roese <sr@denx.de>
Wed, 31 Oct 2007 20:20:50 +0000 (21:20 +0100)
This patch adds endpoint support for the AMCC Kilauea eval board. It can
be tested by connecting a reworked PCIe cable (only 1x lane singles
connected) to another root-complex.

In this test setup, a 64MB inbound window is configured at BAR0 which maps
to 0 on the PLB side. So accessing this BAR0 from the root-complex will
access the first 64MB of the SDRAM on the PPC side.

Signed-off-by: Stefan Roese <sr@denx.de>
cpu/ppc4xx/4xx_pcie.c
include/asm-ppc/4xx_pcie.h

index 9ab358857ad590a761f8965e48eb9549528b84ac..da179f9c3a81daf482e4bbc8f49d76498bf07b07 100644 (file)
@@ -474,12 +474,6 @@ int __ppc4xx_init_pcie_port_hw(int port, int rootport)
 {
        u32 val;
 
-       /*
-        * test-only:
-        * This needs some testing and perhaps changes for
-        * endpoint configuration. Probably no PHY reset at all, etc.
-        * sr, 2007-10-03
-        */
        if (rootport)
                val = 0x00401000;
        else
@@ -496,7 +490,10 @@ int __ppc4xx_init_pcie_port_hw(int port, int rootport)
        udelay(1000);
 
        /* deassert the PE0_hotreset */
-       SDR_WRITE(SDRN_PESDR_RCSSET(port), 0x01101000);
+       if (is_end_point(port))
+               SDR_WRITE(SDRN_PESDR_RCSSET(port), 0x01111000);
+       else
+               SDR_WRITE(SDRN_PESDR_RCSSET(port), 0x01101000);
 
        /* poll for phy !reset */
        while (!(SDR_READ(SDRN_PESDR_PHYSTA(port)) & 0x00001000))
@@ -903,11 +900,22 @@ int ppc4xx_setup_pcie_endpoint(struct pci_controller *hose, int port)
 #endif
        }
 
-       /* Set up 16GB inbound memory window at 0 */
+       /* Set up 64MB 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_PIM01SAH, 0xffffffff);
+       out_le32(mbase + PECFG_PIM01SAL, 0xfc000000);
+
+       /* Setup BAR0 */
+       out_le32(mbase + PECFG_BAR0HMPA, 0x7fffffff);
+       out_le32(mbase + PECFG_BAR0LMPA, 0xfc000000 | PCI_BASE_ADDRESS_MEM_TYPE_64);
+
+       /* Disable BAR1 & BAR2 */
+       out_le32(mbase + PECFG_BAR1MPA, 0);
+       out_le32(mbase + PECFG_BAR2HMPA, 0);
+       out_le32(mbase + PECFG_BAR2LMPA, 0);
+
        out_le32(mbase + PECFG_PIM0LAL, U64_TO_U32_LOW(CFG_PCIE_INBOUND_BASE));
        out_le32(mbase + PECFG_PIM0LAH, U64_TO_U32_HIGH(CFG_PCIE_INBOUND_BASE));
        out_le32(mbase + PECFG_PIMEN, 0x1);
@@ -919,6 +927,9 @@ int ppc4xx_setup_pcie_endpoint(struct pci_controller *hose, int port)
        out_le16(mbase + 0x200, 0xcaad);                /* Setting vendor ID */
        out_le16(mbase + 0x202, 0xfeed);                /* Setting device ID */
 
+       /* Set Class Code to Processor/PPC */
+       out_le32(mbase + 0x208, 0x0b200001);
+
        attempts = 10;
        while(!(SDR_READ(SDRN_PESDR_RCSSTS(port)) & (1 << 8))) {
                if (!(attempts--)) {
index 1830c6a8efd57fa80fbeb253859e7afca6f1fe86..ffe07706a31aa28106d6a99ad38e5428155fc2b3 100644 (file)
 #define PECFG_BAR0LMPA         0x210
 #define PECFG_BAR0HMPA         0x214
 #define PECFG_BAR1MPA          0x218
-#define PECFG_BAR2MPA          0x220
+#define PECFG_BAR2LMPA         0x220
+#define PECFG_BAR2HMPA         0x224
 
 #define PECFG_PIMEN            0x33c
 #define PECFG_PIM0LAL          0x340
@@ -259,9 +260,13 @@ int pcie_hose_scan(struct pci_controller *hose, int bus);
  */
 static inline int is_end_point(int port)
 {
-       static char s[10], *tk;
+       char s[10], *tk;
+       char *pcie_mode = getenv("pcie_mode");
 
-       strcpy(s, getenv("pcie_mode"));
+       if (pcie_mode == NULL)
+               return 0;
+
+       strcpy(s, pcie_mode);
        tk = strtok(s, ":");
 
        switch (port) {