From b9e8078bb3f3c48111a7081e27279938c3a445e1 Mon Sep 17 00:00:00 2001 From: Wolfgang Grandegger Date: Thu, 5 Jun 2008 13:12:08 +0200 Subject: 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 Signed-off-by: Wolfgang Grandegger --- board/tqc/tqm85xx/law.c | 15 +++- board/tqc/tqm85xx/tlb.c | 30 +++++++ board/tqc/tqm85xx/tqm85xx.c | 205 +++++++++++++++++++++++++++++++++++++------- 3 files changed, 215 insertions(+), 35 deletions(-) (limited to 'board/tqc/tqm85xx') 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 #include #include +#include #include #include #include @@ -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) -- cgit v1.1