[U-Boot-Users] [PATCH v2 10/12] TQM8548: PCI express support

Wolfgang Grandegegr wg at grandegger.com
Thu Jun 5 13:12:08 CEST 2008


From: Wolfgang Grandegger <wg at grandegger.com>

This patch adds support for PCI express cards. The board support
now uses common FSL PCI init code, for both, PCI and PCIe on all
TQM85xx modules.

Signed-off-by: Thomas Waehner <thomas.waehner at tqs.de>
Signed-off-by: Wolfgang Grandegger <wg at grandegger.com>
---
 board/tqc/tqm85xx/law.c     |   15 +++-
 board/tqc/tqm85xx/tlb.c     |   30 ++++++
 board/tqc/tqm85xx/tqm85xx.c |  205 ++++++++++++++++++++++++++++++++++++-------
 include/configs/TQM85xx.h   |   35 +++++++-
 4 files changed, 249 insertions(+), 36 deletions(-)

diff --git a/board/tqc/tqm85xx/law.c b/board/tqc/tqm85xx/law.c
index ad35464..bec1ed5 100644
--- a/board/tqc/tqm85xx/law.c
+++ b/board/tqc/tqm85xx/law.c
@@ -32,11 +32,11 @@
  *
  * 0x0000_0000	   0x7fff_ffff	   DDR			   2G
  * 0x8000_0000	   0x9fff_ffff	   PCI1 MEM		   512M
- * 0xc000_0000	   0xdfff_ffff	   RapidIO		   512M
+ * 0xc000_0000	   0xdfff_ffff	   RapidIO or PCI express  512M
  * 0xe000_0000	   0xe000_ffff	   CCSR			   1M
  * 0xe200_0000	   0xe2ff_ffff	   PCI1 IO		   16M
  * 0xe300_0000	   0xe3ff_ffff	   CAN			   16M
- * 0xf800_0000	   0xf80f_ffff	   BCSR			   1M
+ * 0xef00_0000	   0xefff_ffff     PCI express IO          16M
  * 0xfe00_0000	   0xffff_ffff	   FLASH (boot bank)	   32M
  *
  * Notes:
@@ -49,10 +49,17 @@ struct law_entry law_table[] = {
 	SET_LAW_ENTRY (2, CFG_PCI1_MEM_PHYS, LAW_SIZE_512M, LAW_TRGT_IF_PCI),
 	SET_LAW_ENTRY (3, CFG_LBC_FLASH_BASE, LAW_SIZE_128M, LAW_TRGT_IF_LBC),
 	SET_LAW_ENTRY (4, CFG_PCI1_IO_PHYS, LAW_SIZE_16M, LAW_TRGT_IF_PCI),
-	SET_LAW_ENTRY (5, CFG_RIO_MEM_BASE, LAWAR_SIZE_512M, LAW_TRGT_IF_RIO),
+#ifdef CONFIG_PCIE1
+	SET_LAW_ENTRY (5, CFG_PCIE1_MEM_BASE, LAW_SIZE_512M, LAW_TRGT_IF_PCIE_1),
+#else /* !CONFIG_PCIE1 */
+	SET_LAW_ENTRY (5, CFG_RIO_MEM_BASE, LAW_SIZE_512M, LAW_TRGT_IF_RIO),
+#endif /* CONFIG_PCIE1 */
 #ifdef CONFIG_CAN_DRIVER
-	SET_LAW_ENTRY (6, CFG_CAN_BASE, LAWAR_SIZE_16M, LAW_TRGT_IF_LBC),
+	SET_LAW_ENTRY (6, CFG_CAN_BASE, LAW_SIZE_16M, LAW_TRGT_IF_LBC),
 #endif /* CONFIG_CAN_DRIVER */
+#ifdef CONFIG_PCIE1
+	SET_LAW_ENTRY (7, CFG_PCIE1_IO_BASE, LAW_SIZE_16M, LAW_TRGT_IF_PCIE_1),
+#endif /* CONFIG_PCIE */
 };
 
 int num_law_entries = ARRAY_SIZE (law_table);
diff --git a/board/tqc/tqm85xx/tlb.c b/board/tqc/tqm85xx/tlb.c
index dc36201..7c4b9a1 100644
--- a/board/tqc/tqm85xx/tlb.c
+++ b/board/tqc/tqm85xx/tlb.c
@@ -74,6 +74,24 @@ struct fsl_e_tlb_entry tlb_table[] = {
 		       MAS3_SX | MAS3_SW | MAS3_SR, MAS2_I | MAS2_G,
 		       0, 3, BOOKE_PAGESZ_256M, 1),
 
+#ifdef CONFIG_PCIE1
+	/*
+	 * TLB 4:	256M	Non-cacheable, guarded
+	 * 0xc0000000	256M	PCI express MEM First half
+	 */
+	SET_TLB_ENTRY (1, CFG_PCIE1_MEM_BASE, CFG_PCIE1_MEM_BASE,
+		       MAS3_SX | MAS3_SW | MAS3_SR, MAS2_I | MAS2_G,
+		       0, 4, BOOKE_PAGESZ_256M, 1),
+
+	/*
+	 * TLB 5:	256M	Non-cacheable, guarded
+	 * 0xd0000000	256M	PCI express MEM Second half
+	 */
+	SET_TLB_ENTRY (1, CFG_PCIE1_MEM_BASE + 0x10000000,
+		       CFG_PCIE1_MEM_BASE + 0x10000000,
+		       MAS3_SX | MAS3_SW | MAS3_SR, MAS2_I | MAS2_G,
+		       0, 5, BOOKE_PAGESZ_256M, 1),
+#else /* !CONFIG_PCIE */
 	/*
 	 * TLB 4:	256M	Non-cacheable, guarded
 	 * 0xc0000000	256M	Rapid IO MEM First half
@@ -90,6 +108,7 @@ struct fsl_e_tlb_entry tlb_table[] = {
 		       CFG_RIO_MEM_BASE + 0x10000000,
 		       MAS3_SX | MAS3_SW | MAS3_SR, MAS2_I | MAS2_G,
 		       0, 5, BOOKE_PAGESZ_256M, 1),
+#endif /* CONFIG_PCIE */
 
 	/*
 	 * TLB 6:	 64M	Non-cacheable, guarded
@@ -116,6 +135,17 @@ struct fsl_e_tlb_entry tlb_table[] = {
 		       CFG_DDR_SDRAM_BASE + 0x10000000,
 		       MAS3_SX | MAS3_SW | MAS3_SR, MAS2_I | MAS2_G,
 		       0, 8, BOOKE_PAGESZ_256M, 1),
+
+#ifdef CONFIG_PCIE1
+	/*
+	 * TLB 9:	 16M	Non-cacheable, guarded
+	 * 0xef000000	 16M	PCI express IO
+	 */
+	SET_TLB_ENTRY (1, CFG_PCIE1_IO_BASE, CFG_PCIE1_IO_BASE,
+		       MAS3_SX | MAS3_SW | MAS3_SR, MAS2_I | MAS2_G,
+		       0, 9, BOOKE_PAGESZ_16M, 1),
+#endif /* CONFIG_PCIE */
+
 };
 
 int num_tlb_entries = ARRAY_SIZE (tlb_table);
diff --git a/board/tqc/tqm85xx/tqm85xx.c b/board/tqc/tqm85xx/tqm85xx.c
index f96cec3..f1c2e58 100644
--- a/board/tqc/tqm85xx/tqm85xx.c
+++ b/board/tqc/tqm85xx/tqm85xx.c
@@ -36,6 +36,7 @@
 #include <pci.h>
 #include <asm/processor.h>
 #include <asm/immap_85xx.h>
+#include <asm/immap_fsl_pci.h>
 #include <asm/io.h>
 #include <ioports.h>
 #include <flash.h>
@@ -257,13 +258,6 @@ int checkboard (void)
 	}
 	putc ('\n');
 
-#ifdef CONFIG_PCI
-	printf ("PCI1:  32 bit, %d MHz (compiled)\n",
-		CONFIG_SYS_CLK_FREQ / 1000000);
-#else
-	printf ("PCI1:  disabled\n");
-#endif
-
 	/*
 	 * Initialize local bus.
 	 */
@@ -537,38 +531,180 @@ void local_bus_init (void)
 #endif /* CONFIG_CAN_DRIVER */
 }
 
-#if defined(CONFIG_PCI)
 /*
  * Initialize PCI Devices, report devices found.
  */
+static int first_free_busno;
 
-#ifndef CONFIG_PCI_PNP
-static struct pci_config_table pci_mpc85xxads_config_table[] = {
-	{PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
-	 PCI_IDSEL_NUMBER, PCI_ANY_ID,
-	 pci_cfgfunc_config_device, {PCI_ENET0_IOADDR,
-				     PCI_ENET0_MEMADDR,
-				     PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER}},
-	{}
-};
-#endif
+#if defined(CONFIG_PCI) || defined(CONFIG_PCI1)
+static struct pci_controller pci1_hose;
+#endif /* CONFIG_PCI || CONFIG_PCI1 */
 
-static struct pci_controller hose = {
-#ifndef CONFIG_PCI_PNP
-      config_table:pci_mpc85xxads_config_table,
+#ifdef CONFIG_PCIE1
+static struct pci_controller pcie1_hose;
+#endif /* CONFIG_PCIE1 */
+
+static inline void init_pci1(void)
+{
+	volatile ccsr_gur_t *gur = (void *)(CFG_MPC85xx_GUTS_ADDR);
+#if defined(CONFIG_PCI) || defined(CONFIG_PCI1)
+	uint host_agent = (gur->porbmsr & MPC85xx_PORBMSR_HA) >> 16;
+	volatile ccsr_fsl_pci_t *pci = (ccsr_fsl_pci_t *)CFG_PCI1_ADDR;
+	extern void fsl_pci_init(struct pci_controller *hose);
+	struct pci_controller *hose = &pci1_hose;
+
+	/* PORDEVSR[15] */
+	uint pci_32 = gur->pordevsr & MPC85xx_PORDEVSR_PCI1_PCI32;
+	/* PORDEVSR[14] */
+	uint pci_arb = gur->pordevsr & MPC85xx_PORDEVSR_PCI1_ARB;
+	/* PORPLLSR[16] */
+	uint pci_clk_sel = gur->porpllsr & MPC85xx_PORDEVSR_PCI1_SPD;
+
+	uint pci_agent = (host_agent == 3) || (host_agent == 4 ) ||
+		(host_agent == 6);
+
+	uint pci_speed = CONFIG_SYS_CLK_FREQ;	/* PCI PSPEED in [4:5] */
+
+	if (!(gur->devdisr & MPC85xx_DEVDISR_PCI1)) {
+		printf ("PCI1:  %d bit, %s MHz, %s, %s, %s\n",
+			(pci_32) ? 32 : 64,
+			(pci_speed == 33333333) ? "33" :
+			(pci_speed == 66666666) ? "66" : "unknown",
+			pci_clk_sel ? "sync" : "async",
+			pci_agent ? "agent" : "host",
+			pci_arb ? "arbiter" : "external-arbiter");
+
+
+		/* inbound */
+		pci_set_region (hose->regions + 0,
+				CFG_PCI_MEMORY_BUS,
+				CFG_PCI_MEMORY_PHYS,
+				CFG_PCI_MEMORY_SIZE,
+				PCI_REGION_MEM | PCI_REGION_MEMORY);
+
+
+		/* outbound memory */
+		pci_set_region (hose->regions + 1,
+				CFG_PCI1_MEM_BASE,
+				CFG_PCI1_MEM_PHYS,
+				CFG_PCI1_MEM_SIZE,
+				PCI_REGION_MEM);
+
+		/* outbound io */
+		pci_set_region (hose->regions + 2,
+				CFG_PCI1_IO_BASE,
+				CFG_PCI1_IO_PHYS,
+				CFG_PCI1_IO_SIZE,
+				PCI_REGION_IO);
+
+		hose->region_count = 3;
+
+		hose->first_busno = first_free_busno;
+		pci_setup_indirect (hose, (int)&pci->cfg_addr,
+				    (int)&pci->cfg_data);
+
+		fsl_pci_init (hose);
+
+		printf ("       PCI on bus %02x..%02x\n",
+			hose->first_busno, hose->last_busno);
+
+		first_free_busno = hose->last_busno + 1;
+#ifdef CONFIG_PCIX_CHECK
+		if (!(gur->pordevsr & PORDEVSR_PCI)) {
+			ushort reg16 =
+				PCI_X_CMD_MAX_SPLIT | PCI_X_CMD_MAX_READ |
+				PCI_X_CMD_ERO | PCI_X_CMD_DPERR_E;
+			uint dev = PCI_BDF(hose->first_busno, 0, 0);
+
+			/* PCI-X init */
+			if (CONFIG_SYS_CLK_FREQ < 66000000)
+				puts ("PCI-X will only work at 66 MHz\n");
+
+			pci_hose_write_config_word (hose, dev, PCIX_COMMAND,
+						    reg16);
+		}
 #endif
-};
+	} else {
+		puts ("PCI1:  disabled\n");
+	}
+#else /* !(CONFIG_PCI || CONFIG_PCI1) */
+	gur->devdisr |= MPC85xx_DEVDISR_PCI1; /* disable */
+#endif /* CONFIG_PCI || CONFIG_PCI1) */
+}
+
+static inline void init_pcie1(void)
+{
+	volatile ccsr_gur_t *gur = (void *)(CFG_MPC85xx_GUTS_ADDR);
+#ifdef CONFIG_PCIE1
+	uint io_sel = (gur->pordevsr & MPC85xx_PORDEVSR_IO_SEL) >> 19;
+	uint host_agent = (gur->porbmsr & MPC85xx_PORBMSR_HA) >> 16;
+	volatile ccsr_fsl_pci_t *pci = (ccsr_fsl_pci_t *)CFG_PCIE1_ADDR;
+	extern void fsl_pci_init(struct pci_controller *hose);
+	struct pci_controller *hose = &pcie1_hose;
+	int pcie_ep =  (host_agent == 0) || (host_agent == 2 ) ||
+		(host_agent == 3);
+
+	int pcie_configured  = io_sel >= 1;
+
+	if (pcie_configured && !(gur->devdisr & MPC85xx_DEVDISR_PCIE)){
+		printf ("PCIe:  %s, base address %x",
+			pcie_ep ? "End point" : "Root complex", (uint)pci);
+
+		if (pci->pme_msg_det) {
+			pci->pme_msg_det = 0xffffffff;
+			debug (", with errors. Clearing. Now 0x%08x",
+			       pci->pme_msg_det);
+		}
+		puts ("\n");
 
-#endif /* CONFIG_PCI */
+		/* inbound */
+		pci_set_region (hose->regions + 0,
+				CFG_PCI_MEMORY_BUS,
+				CFG_PCI_MEMORY_PHYS,
+				CFG_PCI_MEMORY_SIZE,
+				PCI_REGION_MEM | PCI_REGION_MEMORY);
+
+		/* outbound memory */
+		pci_set_region (hose->regions + 1,
+				CFG_PCIE1_MEM_BASE,
+				CFG_PCIE1_MEM_PHYS,
+				CFG_PCIE1_MEM_SIZE,
+				PCI_REGION_MEM);
+
+		/* outbound io */
+		pci_set_region (hose->regions + 2,
+				CFG_PCIE1_IO_BASE,
+				CFG_PCIE1_IO_PHYS,
+				CFG_PCIE1_IO_SIZE,
+				PCI_REGION_IO);
+
+		hose->region_count = 3;
+
+		hose->first_busno = first_free_busno;
+		pci_setup_indirect(hose, (int)&pci->cfg_addr,
+				   (int)&pci->cfg_data);
+
+		fsl_pci_init (hose);
+		printf ("       PCIe on bus %02x..%02x\n",
+			hose->first_busno, hose->last_busno);
+
+		first_free_busno = hose->last_busno + 1;
+
+	} else {
+		printf ("PCIe:  disabled\n");
+	}
+#else /* !CONFIG_PCIE1 */
+	gur->devdisr |= MPC85xx_DEVDISR_PCIE; /* disable */
+#endif /* CONFIG_PCIE1 */
+}
 
 void pci_init_board (void)
 {
-#ifdef CONFIG_PCI
-	pci_mpc85xx_init (&hose);
-#endif /* CONFIG_PCI */
+	init_pci1();
+	init_pcie1();
 }
 
-#if defined(CONFIG_OF_BOARD_SETUP)
+#ifdef CONFIG_OF_BOARD_SETUP
 void ft_board_setup (void *blob, bd_t *bd)
 {
 	int node, tmp[2];
@@ -579,16 +715,23 @@ void ft_board_setup (void *blob, bd_t *bd)
 	node = fdt_path_offset (blob, "/aliases");
 	tmp[0] = 0;
 	if (node >= 0) {
-#ifdef CONFIG_PCI
+#if defined(CONFIG_PCI) || defined(CONFIG_PCI1)
 		path = fdt_getprop (blob, node, "pci0", NULL);
 		if (path) {
-			tmp[1] = hose.last_busno - hose.first_busno;
+			tmp[1] = pci1_hose.last_busno - pci1_hose.first_busno;
 			do_fixup_by_path (blob, path, "bus-range", &tmp, 8, 1);
 		}
-#endif
+#endif /* CONFIG_PCI || CONFIG_PCI1 */
+#ifdef CONFIG_PCIE1
+		path = fdt_getprop (blob, node, "pci1", NULL);
+		if (path) {
+			tmp[1] = pcie1_hose.last_busno - pcie1_hose.first_busno;
+			do_fixup_by_path (blob, path, "bus-range", &tmp, 8, 1);
+		}
+#endif /* CONFIG_PCIE1 */
 	}
 }
-#endif
+#endif /* CONFIG_OF_BOARD_SETUP */
 
 #ifdef CONFIG_BOARD_EARLY_INIT_R
 int board_early_init_r (void)
diff --git a/include/configs/TQM85xx.h b/include/configs/TQM85xx.h
index a02d001..2155130 100644
--- a/include/configs/TQM85xx.h
+++ b/include/configs/TQM85xx.h
@@ -42,6 +42,14 @@
 #define CONFIG_MPC85xx		1	/* MPC8540/60/55/41		*/
 
 #define CONFIG_PCI
+#define CONFIG_FSL_PCI_INIT	1	/* Use common FSL init code	*/
+#define CONFIG_PCIX_CHECK		/* PCIX olny works at 66 MHz	*/
+#ifdef CONFIG_TQM8548
+#define CONFIG_PCI1
+#define CONFIG_PCIE1
+#define CONFIG_FSL_PCIE_RESET	1	/* need PCIe reset errata	*/
+#endif
+
 #define CONFIG_TSEC_ENET		/* tsec ethernet support	*/
 
 #define CONFIG_MISC_INIT_R	1	/* Call misc_init_r		*/
@@ -97,6 +105,10 @@
 #define CFG_CCSRBAR_PHYS	CFG_CCSRBAR	/* physical addr of CCSRBAR */
 #define CFG_IMMR		CFG_CCSRBAR	/* PQII uses CFG_IMMR	*/
 
+#define CFG_PCI1_ADDR		(CFG_CCSRBAR + 0x8000)
+#define CFG_PCI2_ADDR		(CFG_CCSRBAR + 0x9000)
+#define CFG_PCIE1_ADDR		(CFG_CCSRBAR + 0xa000)
+
 /*
  * DDR Setup
  */
@@ -282,10 +294,12 @@
 #define CFG_DTT_LOW_TEMP	-30
 #define CFG_DTT_HYSTERESIS	3
 
+#ifndef CONFIG_PCIE1
 /* RapidIO MMU */
 #define CFG_RIO_MEM_BASE	0xc0000000	/* base address		*/
 #define CFG_RIO_MEM_PHYS	CFG_RIO_MEM_BASE
-#define CFG_RIO_MEM_SIZE	0x20000000	/* 128M			*/
+#define CFG_RIO_MEM_SIZE	0x20000000	/* 512M			*/
+#endif /* CONFIG_PCIE1 */
 
 /*
  * General PCI
@@ -298,6 +312,25 @@
 #define CFG_PCI1_IO_PHYS	CFG_PCI1_IO_BASE
 #define CFG_PCI1_IO_SIZE	0x1000000	/*  16M			*/
 
+/* PCI view of System Memory */
+#define CFG_PCI_MEMORY_BUS	0x00000000
+#define CFG_PCI_MEMORY_PHYS	0x00000000
+#define CFG_PCI_MEMORY_SIZE	0x80000000
+
+#ifdef CONFIG_PCIE1
+/*
+ * General PCI express
+ * Addresses are mapped 1-1.
+ */
+#define CFG_PCIE1_MEM_BASE	0xc0000000
+#define CFG_PCIE1_MEM_PHYS	CFG_PCIE1_MEM_BASE
+#define CFG_PCIE1_MEM_SIZE	0x20000000      /* 512M                 */
+#define CFG_PCIE1_IO_BASE	0xef000000
+#define CFG_PCIE1_IO_PHYS	CFG_PCIE1_IO_BASE
+#define CFG_PCIE1_IO_SIZE	0x1000000       /* 16M                  */
+
+#endif /* CONFIG_PCIE1 */
+
 #if defined(CONFIG_PCI)
 
 #define CONFIG_PCI_PNP			/* do pci plug-and-play		*/
-- 
1.5.4.2





More information about the U-Boot mailing list