Commit b9e8078b authored by Wolfgang Grandegger's avatar Wolfgang Grandegger Committed by Andrew Fleming-AFLEMING
Browse files

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: default avatarThomas Waehner <thomas.waehner@tqs.de>
Signed-off-by: default avatarWolfgang Grandegger <wg@grandegger.com>
parent 1287e0c5
......@@ -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);
......@@ -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);
......@@ -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)
......
......@@ -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 */
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment