ppc4xx: 4xx_pcie: More general cleanup and 405EX PCIe support added
authorStefan Roese <sr@denx.de>
Fri, 5 Oct 2007 07:18:23 +0000 (09:18 +0200)
committerStefan Roese <sr@denx.de>
Wed, 31 Oct 2007 20:20:49 +0000 (21:20 +0100)
Signed-off-by: Stefan Roese <sr@denx.de>
cpu/ppc4xx/4xx_pcie.c
include/asm-ppc/4xx_pcie.h
include/configs/katmai.h
include/configs/yucca.h

index 7ac8ce0..d1ba890 100644 (file)
@@ -31,7 +31,8 @@
 #include <common.h>
 #include <pci.h>
 
-#if defined(CONFIG_440SPE) && defined(CONFIG_PCI)
+#if (defined(CONFIG_440SPE) || defined(CONFIG_405EX)) && \
+    defined(CONFIG_PCI)
 
 #include <asm/4xx_pcie.h>
 
@@ -55,8 +56,10 @@ static u8* pcie_get_base(struct pci_controller *hose, unsigned int devfn)
                        base = (u8*)CFG_PCIE0_XCFGBASE;
                if (hose->cfg_data == (u8*)CFG_PCIE1_CFGBASE)
                        base = (u8*)CFG_PCIE1_XCFGBASE;
+#if CFG_PCIE_NR_PORTS > 2
                if (hose->cfg_data == (u8*)CFG_PCIE2_CFGBASE)
                        base = (u8*)CFG_PCIE2_XCFGBASE;
+#endif
        }
 
        return base;
@@ -68,8 +71,10 @@ static void pcie_dmer_disable(void)
                mfdcr (DCRN_PEGPL_CFG(DCRN_PCIE0_BASE)) | GPL_DMER_MASK_DISA);
        mtdcr (DCRN_PEGPL_CFG(DCRN_PCIE1_BASE),
                mfdcr (DCRN_PEGPL_CFG(DCRN_PCIE1_BASE)) | GPL_DMER_MASK_DISA);
+#if CFG_PCIE_NR_PORTS > 2
        mtdcr (DCRN_PEGPL_CFG(DCRN_PCIE2_BASE),
                mfdcr (DCRN_PEGPL_CFG(DCRN_PCIE2_BASE)) | GPL_DMER_MASK_DISA);
+#endif
 }
 
 static void pcie_dmer_enable(void)
@@ -78,8 +83,10 @@ static void pcie_dmer_enable(void)
                mfdcr (DCRN_PEGPL_CFG(DCRN_PCIE0_BASE)) & ~GPL_DMER_MASK_DISA);
        mtdcr (DCRN_PEGPL_CFG (DCRN_PCIE1_BASE),
                mfdcr (DCRN_PEGPL_CFG(DCRN_PCIE1_BASE)) & ~GPL_DMER_MASK_DISA);
+#if CFG_PCIE_NR_PORTS > 2
        mtdcr (DCRN_PEGPL_CFG (DCRN_PCIE2_BASE),
                mfdcr (DCRN_PEGPL_CFG(DCRN_PCIE2_BASE)) & ~GPL_DMER_MASK_DISA);
+#endif
 }
 
 static int pcie_read_config(struct pci_controller *hose, unsigned int devfn,
@@ -120,6 +127,7 @@ static int pcie_read_config(struct pci_controller *hose, unsigned int devfn,
         */
        pcie_dmer_disable ();
 
+       debug("%s: cfg_data=%08x offset=%08x\n", __func__, hose->cfg_data, offset);
        switch (len) {
        case 1:
                *val = in_8(hose->cfg_data + offset);
@@ -227,6 +235,7 @@ int pcie_write_config_dword(struct pci_controller *hose,pci_dev_t dev,int offset
        return pcie_write_config(hose,(u32)dev,offset,3,(u32 )val);
 }
 
+#if defined(CONFIG_440SPE)
 static void ppc4xx_setup_utl(u32 port) {
 
        volatile void *utl_base = NULL;
@@ -371,6 +380,15 @@ int ppc4xx_init_pcie(void)
        }
        return 0;
 }
+#else
+int ppc4xx_init_pcie(void)
+{
+       /*
+        * Nothing to do on 405EX
+        */
+       return 0;
+}
+#endif
 
 /*
  * Board-specific pcie initialization
@@ -608,19 +626,21 @@ int ppc4xx_init_pcie_port(int port, int rootport)
                return -1;
        }
 
+#if defined(CONFIG_440SPE)
        /*
         * Setup UTL registers - but only on revA!
         * We use default settings for revB chip.
         */
        if (!ppc440spe_revB())
                ppc4xx_setup_utl(port);
+#endif
 
        /*
         * We map PCI Express configuration access into the 512MB regions
         */
        addr = ppc4xx_get_cfgaddr(port);
-       low = (u32)(addr & 0x00000000ffffffff);
-       high = (u32)(addr >> 32);
+       low = U64_TO_U32_LOW(addr);
+       high = U64_TO_U32_HIGH(addr);
 
        switch (port) {
        case 0:
@@ -633,11 +653,13 @@ int ppc4xx_init_pcie_port(int port, int rootport)
                mtdcr(DCRN_PEGPL_CFGBAL(PCIE1), low);
                mtdcr(DCRN_PEGPL_CFGMSK(PCIE1), 0xe0000001); /* 512MB region, valid */
                break;
+#if CFG_PCIE_NR_PORTS > 2
        case 2:
                mtdcr(DCRN_PEGPL_CFGBAH(PCIE2), high);
                mtdcr(DCRN_PEGPL_CFGBAL(PCIE2), low);
                mtdcr(DCRN_PEGPL_CFGMSK(PCIE2), 0xe0000001); /* 512MB region, valid */
                break;
+#endif
        }
 
        /*
@@ -692,11 +714,13 @@ void ppc4xx_setup_pcie_rootpoint(struct pci_controller *hose, int port)
                rmbase = (u32 *)CFG_PCIE1_CFGBASE;
                hose->cfg_data = (u8 *)CFG_PCIE1_CFGBASE;
                break;
+#if CFG_PCIE_NR_PORTS > 2
        case 2:
                mbase = (u32 *)CFG_PCIE2_XCFGBASE;
                rmbase = (u32 *)CFG_PCIE2_CFGBASE;
                hose->cfg_data = (u8 *)CFG_PCIE2_CFGBASE;
                break;
+#endif
        }
 
        /*
@@ -720,8 +744,8 @@ void ppc4xx_setup_pcie_rootpoint(struct pci_controller *hose, int port)
 
        switch (port) {
        case 0:
-               mtdcr(DCRN_PEGPL_OMR1BAH(PCIE0),  0x0000000d);
-               mtdcr(DCRN_PEGPL_OMR1BAL(PCIE0),  CFG_PCIE_MEMBASE +
+               mtdcr(DCRN_PEGPL_OMR1BAH(PCIE0), CFG_PCIE_ADDR_HIGH);
+               mtdcr(DCRN_PEGPL_OMR1BAL(PCIE0), CFG_PCIE_MEMBASE +
                      port * CFG_PCIE_MEMSIZE);
                mtdcr(DCRN_PEGPL_OMR1MSKH(PCIE0), 0x7fffffff);
                mtdcr(DCRN_PEGPL_OMR1MSKL(PCIE0),
@@ -733,8 +757,8 @@ void ppc4xx_setup_pcie_rootpoint(struct pci_controller *hose, int port)
                      mfdcr(DCRN_PEGPL_OMR1MSKL(PCIE0)));
                break;
        case 1:
-               mtdcr(DCRN_PEGPL_OMR1BAH(PCIE1),  0x0000000d);
-               mtdcr(DCRN_PEGPL_OMR1BAL(PCIE1),  CFG_PCIE_MEMBASE +
+               mtdcr(DCRN_PEGPL_OMR1BAH(PCIE1), CFG_PCIE_ADDR_HIGH);
+               mtdcr(DCRN_PEGPL_OMR1BAL(PCIE1), CFG_PCIE_MEMBASE +
                      port * CFG_PCIE_MEMSIZE);
                mtdcr(DCRN_PEGPL_OMR1MSKH(PCIE1), 0x7fffffff);
                mtdcr(DCRN_PEGPL_OMR1MSKL(PCIE1),
@@ -745,9 +769,10 @@ void ppc4xx_setup_pcie_rootpoint(struct pci_controller *hose, int port)
                      mfdcr(DCRN_PEGPL_OMR1MSKH(PCIE1)),
                      mfdcr(DCRN_PEGPL_OMR1MSKL(PCIE1)));
                break;
+#if CFG_PCIE_NR_PORTS > 2
        case 2:
-               mtdcr(DCRN_PEGPL_OMR1BAH(PCIE2),  0x0000000d);
-               mtdcr(DCRN_PEGPL_OMR1BAL(PCIE2),  CFG_PCIE_MEMBASE +
+               mtdcr(DCRN_PEGPL_OMR1BAH(PCIE2), CFG_PCIE_ADDR_HIGH);
+               mtdcr(DCRN_PEGPL_OMR1BAL(PCIE2), CFG_PCIE_MEMBASE +
                      port * CFG_PCIE_MEMSIZE);
                mtdcr(DCRN_PEGPL_OMR1MSKH(PCIE2), 0x7fffffff);
                mtdcr(DCRN_PEGPL_OMR1MSKL(PCIE2),
@@ -758,6 +783,7 @@ void ppc4xx_setup_pcie_rootpoint(struct pci_controller *hose, int port)
                      mfdcr(DCRN_PEGPL_OMR1MSKH(PCIE2)),
                      mfdcr(DCRN_PEGPL_OMR1MSKL(PCIE2)));
                break;
+#endif
        }
 
        /* Set up 16GB inbound memory window at 0 */
@@ -770,8 +796,8 @@ void ppc4xx_setup_pcie_rootpoint(struct pci_controller *hose, int port)
        out_le32(mbase + PECFG_PIM01SAL, 0x00000000);
        out_le32(mbase + PECFG_PIM0LAL, 0);
        out_le32(mbase + PECFG_PIM0LAH, 0);
-       out_le32(mbase + PECFG_PIM1LAL,  0x00000000);
-       out_le32(mbase + PECFG_PIM1LAH,  0x00000004);
+       out_le32(mbase + PECFG_PIM1LAL, 0x00000000);
+       out_le32(mbase + PECFG_PIM1LAH, 0x00000004);
        out_le32(mbase + PECFG_PIMEN, 0x1);
 
        /* Enable I/O, Mem, and Busmaster cycles */
@@ -780,23 +806,8 @@ void ppc4xx_setup_pcie_rootpoint(struct pci_controller *hose, int port)
                 PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
 
        /* Set Device and Vendor Id */
-       switch (port) {
-       case 0:
-               out_le16(mbase + 0x200, 0xaaa0);
-               out_le16(mbase + 0x202, 0xbed0);
-               break;
-       case 1:
-               out_le16(mbase + 0x200, 0xaaa1);
-               out_le16(mbase + 0x202, 0xbed1);
-               break;
-       case 2:
-               out_le16(mbase + 0x200, 0xaaa2);
-               out_le16(mbase + 0x202, 0xbed2);
-               break;
-       default:
-               out_le16(mbase + 0x200, 0xaaa3);
-               out_le16(mbase + 0x202, 0xbed3);
-       }
+       out_le16(mbase + 0x200, 0xaaa0 + port);
+       out_le16(mbase + 0x202, 0xbed0 + port);
 
        /* Set Class Code to PCI-PCI bridge and Revision Id to 1 */
        out_le32(mbase + 0x208, 0x06040001);
@@ -826,10 +837,12 @@ int ppc4xx_setup_pcie_endpoint(struct pci_controller *hose, int port)
                mbase = (u32 *)CFG_PCIE1_XCFGBASE;
                hose->cfg_data = (u8 *)CFG_PCIE1_CFGBASE;
                break;
+#if defined(CFG_PCIE2_CFGBASE)
        case 2:
                mbase = (u32 *)CFG_PCIE2_XCFGBASE;
                hose->cfg_data = (u8 *)CFG_PCIE2_CFGBASE;
                break;
+#endif
        }
 
        /*
@@ -843,29 +856,31 @@ int ppc4xx_setup_pcie_endpoint(struct pci_controller *hose, int port)
 
        switch (port) {
        case 0:
-               mtdcr(DCRN_PEGPL_OMR1BAH(PCIE0),  0x0000000d);
-               mtdcr(DCRN_PEGPL_OMR1BAL(PCIE0),  CFG_PCIE_MEMBASE +
+               mtdcr(DCRN_PEGPL_OMR1BAH(PCIE0), CFG_PCIE_ADDR_HIGH);
+               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 +
+               mtdcr(DCRN_PEGPL_OMR1BAH(PCIE1), CFG_PCIE_ADDR_HIGH);
+               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;
+#if CFG_PCIE_NR_PORTS > 2
        case 2:
-               mtdcr(DCRN_PEGPL_OMR1BAH(PCIE2),  0x0000000d);
-               mtdcr(DCRN_PEGPL_OMR1BAL(PCIE2),  CFG_PCIE_MEMBASE +
+               mtdcr(DCRN_PEGPL_OMR1BAH(PCIE2), CFG_PCIE_ADDR_HIGH);
+               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;
+#endif
        }
 
        /* Set up 16GB inbound memory window at 0 */
@@ -873,16 +888,16 @@ int ppc4xx_setup_pcie_endpoint(struct pci_controller *hose, int port)
        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_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);
 
        /* 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 */
+       out_le16(mbase + 0x200, 0xcaad);                /* Setting vendor ID */
+       out_le16(mbase + 0x202, 0xfeed);                /* Setting device ID */
 
        attempts = 10;
        while(!(SDR_READ(SDRN_PESDR_RCSSTS(port)) & (1 << 8))) {
@@ -893,7 +908,7 @@ int ppc4xx_setup_pcie_endpoint(struct pci_controller *hose, int port)
                mdelay(1000);
        }
 
-       printf("PCIE:%d successfully set as endpoint\n",port);
+       printf("PCIE:%d successfully set as endpoint\n", port);
 
        return 0;
 }
index 1bb8fc7..17ac57b 100644 (file)
 #define DCRN_SDR0_CFGDATA      0x00f
 
 #if defined(CONFIG_440SPE)
+#define CFG_PCIE_NR_PORTS      3
+
+#define CFG_PCIE_ADDR_HIGH     0x0000000d
+
 #define DCRN_PCIE0_BASE                0x100
 #define DCRN_PCIE1_BASE                0x120
 #define DCRN_PCIE2_BASE                0x140
+
+#define PCIE0_SDR              0x300
+#define PCIE1_SDR              0x340
+#define PCIE2_SDR              0x370
 #endif
 
 #if defined(CONFIG_405EX)
+#define CFG_PCIE_NR_PORTS      2
+
+#define CFG_PCIE_ADDR_HIGH     0x00000000
+
 #define        DCRN_PCIE0_BASE         0x040
 #define        DCRN_PCIE1_BASE         0x060
+
+#define PCIE0_SDR              0x400
+#define PCIE1_SDR              0x440
 #endif
 
 #define PCIE0                  DCRN_PCIE0_BASE
 #define PESDR0_PLLLCT2         0x03a1
 #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 GPL_DMER_MASK_DISA     0x02000000
 
+#define U64_TO_U32_LOW(val)    ((u32)((val) & 0x00000000ffffffffULL))
+#define U64_TO_U32_HIGH(val)   ((u32)((val) >> 32))
+
 int ppc4xx_init_pcie(void);
 int ppc4xx_init_pcie_rootport(int port);
 int ppc4xx_init_pcie_endport(int port);
@@ -260,7 +267,7 @@ static inline u32 sdr_base(int port)
                return PCIE0_SDR;
        case 1:
                return PCIE1_SDR;
-#if defined(PCIE2_SDR)
+#if CFG_PCIE_NR_PORTS > 2
        case 2:
                return PCIE2_SDR;
 #endif
index 03c3cb3..8a96327 100644 (file)
@@ -72,6 +72,9 @@
 #define CFG_PCIE1_XCFGBASE     0xc3001000
 #define CFG_PCIE2_XCFGBASE     0xc3002000
 
+/* base address of inbound PCIe window */
+#define CFG_PCIE_INBOUND_BASE  0x0000000400000000ULL
+
 /* System RAM mapped to PCI space */
 #define CONFIG_PCI_SYS_MEM_BUS CFG_SDRAM_BASE
 #define CONFIG_PCI_SYS_MEM_PHYS        CFG_SDRAM_BASE
index 6caf21b..ab7fb0a 100644 (file)
@@ -74,6 +74,9 @@
 #define CFG_PCIE1_XCFGBASE     0xc3001000
 #define CFG_PCIE2_XCFGBASE     0xc3002000
 
+/* base address of inbound PCIe window */
+#define CFG_PCIE_INBOUND_BASE  0x0000000400000000ULL
+
 /* System RAM mapped to PCI space */
 #define CONFIG_PCI_SYS_MEM_BUS CFG_SDRAM_BASE
 #define CONFIG_PCI_SYS_MEM_PHYS        CFG_SDRAM_BASE