summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWolfgang Grandegger <wg@grandegger.com>2008-06-05 13:12:08 +0200
committerAndrew Fleming-AFLEMING <afleming@freescale.com>2008-06-11 00:05:01 -0500
commitb9e8078bb3f3c48111a7081e27279938c3a445e1 (patch)
tree3013fbb38a59c2c0590496485b57623317ce0b98
parent1287e0c55a2ee2c575ac9ce8e4302cd4085be876 (diff)
TQM8548: PCI express support
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@tqs.de> Signed-off-by: Wolfgang Grandegger <wg@grandegger.com>
-rw-r--r--board/tqc/tqm85xx/law.c15
-rw-r--r--board/tqc/tqm85xx/tlb.c30
-rw-r--r--board/tqc/tqm85xx/tqm85xx.c205
-rw-r--r--include/configs/TQM85xx.h35
4 files changed, 249 insertions, 36 deletions
diff --git a/board/tqc/tqm85xx/law.c b/board/tqc/tqm85xx/law.c
index ad35464e47..bec1ed5089 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 dc362012d8..7c4b9a1f47 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 f96cec3e62..f1c2e58edd 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 a02d0018e3..21551304ca 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 */