ppc4xx: 4xx_pcie: More general cleanup and 405EX PCIe support added

Signed-off-by: Stefan Roese <sr@denx.de>
diff --git a/cpu/ppc4xx/4xx_pcie.c b/cpu/ppc4xx/4xx_pcie.c
index 7ac8ce0..d1ba890 100644
--- a/cpu/ppc4xx/4xx_pcie.c
+++ b/cpu/ppc4xx/4xx_pcie.c
@@ -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 @@
 			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 @@
 		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 @@
 		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 @@
 	 */
 	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 @@
 	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 @@
 	}
 	return 0;
 }
+#else
+int ppc4xx_init_pcie(void)
+{
+	/*
+	 * Nothing to do on 405EX
+	 */
+	return 0;
+}
+#endif
 
 /*
  * Board-specific pcie initialization
@@ -608,19 +626,21 @@
 		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 @@
 		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 @@
 		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 @@
 
 	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 @@
 		      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 @@
 		      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 @@
 		      mfdcr(DCRN_PEGPL_OMR1MSKH(PCIE2)),
 		      mfdcr(DCRN_PEGPL_OMR1MSKL(PCIE2)));
 		break;
+#endif
 	}
 
 	/* Set up 16GB inbound memory window at 0 */
@@ -770,8 +796,8 @@
 	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 @@
 		 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 @@
 		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 @@
 
 	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 @@
 	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 @@
 		mdelay(1000);
 	}
 
-	printf("PCIE:%d successfully set as endpoint\n",port);
+	printf("PCIE:%d successfully set as endpoint\n", port);
 
 	return 0;
 }
diff --git a/include/asm-ppc/4xx_pcie.h b/include/asm-ppc/4xx_pcie.h
index 1bb8fc7..17ac57b 100644
--- a/include/asm-ppc/4xx_pcie.h
+++ b/include/asm-ppc/4xx_pcie.h
@@ -16,14 +16,29 @@
 #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
@@ -53,17 +68,6 @@
 #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)
@@ -237,6 +241,9 @@
 
 #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 @@
 		return PCIE0_SDR;
 	case 1:
 		return PCIE1_SDR;
-#if defined(PCIE2_SDR)
+#if CFG_PCIE_NR_PORTS > 2
 	case 2:
 		return PCIE2_SDR;
 #endif
diff --git a/include/configs/katmai.h b/include/configs/katmai.h
index 03c3cb3..8a96327 100644
--- a/include/configs/katmai.h
+++ b/include/configs/katmai.h
@@ -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
diff --git a/include/configs/yucca.h b/include/configs/yucca.h
index 6caf21b..ab7fb0a 100644
--- a/include/configs/yucca.h
+++ b/include/configs/yucca.h
@@ -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