[U-Boot-Users] [PATCH] mpc83xx: Add MPC837x PCIE controller RC mode initialize code

Li Li r64360 at freescale.com
Wed Jan 2 12:07:25 CET 2008


 This patch is based on Dave Liu`s previously sent MPC837x patches.

 Initial the MPC837x PCIE controller.
 Note that configue address bit field is not compatible with PCIE spec 10a.
 So, the pci command output is not reliable.
 Just map 16M pci configure space which corresponding to a bus configure space at once.
 If want to access bus number other than 0. Need to remap the pci configure window by hand.

Signed-off-by: Tony Li <tony.li at freescale.com>
---
 Makefile                                  |   19 ++-
 board/freescale/mpc837xemds/Makefile      |    2 +-
 board/freescale/mpc837xemds/mpc837xemds.c |    3 +
 board/freescale/mpc837xemds/pci.c         |    3 +-
 board/freescale/mpc837xemds/pcie.c        |   95 ++++++++++
 cpu/mpc83xx/Makefile                      |    2 +-
 cpu/mpc83xx/pcie.c                        |  277 +++++++++++++++++++++++++++++
 doc/README.mpc837xemds                    |    6 +
 include/asm-ppc/immap_83xx.h              |  119 ++++++++++++-
 include/configs/MPC837XEMDS.h             |   23 +++-
 include/mpc83xx.h                         |   42 +++++
 include/pci.h                             |    4 +
 12 files changed, 583 insertions(+), 12 deletions(-)
 create mode 100644 board/freescale/mpc837xemds/pcie.c
 create mode 100644 cpu/mpc83xx/pcie.c

diff --git a/Makefile b/Makefile
index f8a038a..50da5cf 100644
--- a/Makefile
+++ b/Makefile
@@ -1831,13 +1831,28 @@ MPC8360EMDS_SLAVE_config:	unconfig
 	@$(MKCONFIG) -a MPC8360EMDS ppc mpc83xx mpc8360emds freescale
 
 MPC837XEMDS_config \
-MPC837XEMDS_HOST_config:	unconfig
+MPC837XEMDS_HOST_config \
+MPC837XEMDS_PCIE_config \
+MPC837XEMDS_PCIE_X2_config \
+MPC837XEMDS_HOST_PCIE_config \
+MPC837XEMDS_HOST_PCIE_X2_config:	unconfig
 	@mkdir -p $(obj)include
 	@echo "" >$(obj)include/config.h ; \
 	if [ "$(findstring _HOST_,$@)" ] ; then \
 		echo -n "... PCI HOST " ; \
 		echo "#define CONFIG_PCI" >>$(obj)include/config.h ; \
-	fi ;
+		echo "#define CONFIG_PQ_MDS_PIB" >>$(obj)include/config.h ; \
+	fi ; \
+	if [ "$(findstring _PCIE_,$@)" ] ; then\
+		echo -n "... PCIE "; \
+		echo "#define CONFIG_PCI" >>$(obj)include/config.h ; \
+		echo "#define CONFIG_PCIE" >>$(obj)include/config.h ; \
+	fi; \
+	if [ "$(findstring _PCIE_X2_,$@)" ] ; then\
+		echo -n "_X2 "; \
+		echo "#define CONFIG_PCIE_X2" >>$(obj)include/config.h ; \
+	fi;
+
 	@$(MKCONFIG) -a MPC837XEMDS ppc mpc83xx mpc837xemds freescale
 
 sbc8349_config:		unconfig
diff --git a/board/freescale/mpc837xemds/Makefile b/board/freescale/mpc837xemds/Makefile
index 3cffcfb..319ebc2 100644
--- a/board/freescale/mpc837xemds/Makefile
+++ b/board/freescale/mpc837xemds/Makefile
@@ -25,7 +25,7 @@ include $(TOPDIR)/config.mk
 
 LIB	= $(obj)lib$(BOARD).a
 
-COBJS	:= $(BOARD).o pci.o nand.o
+COBJS	:= $(BOARD).o pci.o pcie.o nand.o
 
 SRCS	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)
 OBJS	:= $(addprefix $(obj),$(COBJS))
diff --git a/board/freescale/mpc837xemds/mpc837xemds.c b/board/freescale/mpc837xemds/mpc837xemds.c
index 330e0e8..ff6f14a 100644
--- a/board/freescale/mpc837xemds/mpc837xemds.c
+++ b/board/freescale/mpc837xemds/mpc837xemds.c
@@ -48,6 +48,9 @@ int board_early_init_r(void)
 #ifdef CONFIG_PQ_MDS_PIB
 	pib_init();
 #endif
+#ifdef CONFIG_PCIE
+	pcie_init_board();
+#endif
 	return 0;
 }
 
diff --git a/board/freescale/mpc837xemds/pci.c b/board/freescale/mpc837xemds/pci.c
index ab90979..72e8dcc 100644
--- a/board/freescale/mpc837xemds/pci.c
+++ b/board/freescale/mpc837xemds/pci.c
@@ -59,7 +59,8 @@ void pci_init_board(void)
 	pci_law[1].ar = LBLAWAR_EN | LBLAWAR_1MB;
 
 	udelay(2000);
-
+#if defined(CONFIG_PQ_MDS_PIB)
 	mpc83xx_pci_init(1, reg, 0);
+#endif
 }
 #endif /* CONFIG_PCI */
diff --git a/board/freescale/mpc837xemds/pcie.c b/board/freescale/mpc837xemds/pcie.c
new file mode 100644
index 0000000..474f848
--- /dev/null
+++ b/board/freescale/mpc837xemds/pcie.c
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2007 Freescale Semiconductor, Inc.
+ * Tony Li <tony.li at freescale.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ */
+
+#include <asm/mmu.h>
+#include <asm/io.h>
+#include <common.h>
+#include <mpc83xx.h>
+#include <pci.h>
+#include <asm/fsl_serdes.h>
+
+#if defined(CONFIG_PCIE)
+static struct pci_region pci_regions_0[] = {
+	{
+		bus_start: CFG_PCIE1_MEM_BASE,
+		phys_start: CFG_PCIE1_MEM_PHYS,
+		size: CFG_PCIE1_MEM_SIZE,
+		flags: PCI_REGION_MEM
+	},
+	{
+		bus_start: CFG_PCIE1_IO_BASE,
+		phys_start: CFG_PCIE1_IO_PHYS,
+		size: CFG_PCIE1_IO_SIZE,
+		flags: PCI_REGION_IO
+	}
+};
+
+static struct pci_region pci_regions_1[] = {
+	{
+		bus_start: CFG_PCIE2_MEM_BASE,
+		phys_start: CFG_PCIE2_MEM_PHYS,
+		size: CFG_PCIE2_MEM_SIZE,
+		flags: PCI_REGION_MEM
+	},
+	{
+		bus_start: CFG_PCIE2_IO_BASE,
+		phys_start: CFG_PCIE2_IO_PHYS,
+		size: CFG_PCIE2_IO_SIZE,
+		flags: PCI_REGION_IO
+	}
+};
+
+void pcie_init_board(void)
+{
+	volatile immap_t *immr = (volatile immap_t *)CFG_IMMR;
+	volatile clk83xx_t *clk = (volatile clk83xx_t *)&immr->clk;
+	volatile sysconf83xx_t *sysconf = &immr->sysconf;
+	volatile serdes83xx_t *serdes = &immr->serdes[1];
+	volatile law83xx_t *pcie_law = sysconf->pcielaw;
+	struct pci_region *reg[] = { pci_regions_0, pci_regions_1 };
+	u8 val8 = 0;
+	u8 orig_i2c_bus = 0;
+
+	disable_addr_trans();
+
+#if defined(CONFIG_PCIE_X2)
+	fsl_serdes_init(serdes, FSL_SERDES_MODE_PEX_X2);
+#else
+	fsl_serdes_init(serdes, FSL_SERDES_MODE_PEX);
+#endif
+
+	/* Configure the clock for PCIE controller */
+	clk->sccr &= ~0x003C0000;
+	clk->sccr |= 0x00140000;
+
+	/* Deassert the resets in the control register */
+	sysconf->pecr1 = 0xE0008000;
+#if !defined(CONFIG_PCIE_X2)
+	sysconf->pecr2 = 0xE0008000;
+#endif
+	udelay(2000);
+
+	/* Configure PCI Express Local Access Windows */
+	pcie_law[0].bar = CFG_PCIE1_BASE & LAWBAR_BAR;
+	pcie_law[0].ar = LBLAWAR_EN | LBLAWAR_512MB;
+
+	pcie_law[1].bar = CFG_PCIE2_BASE & LAWBAR_BAR;
+	pcie_law[1].ar = LBLAWAR_EN | LBLAWAR_512MB;
+
+#if defined(CONFIG_PCIE_X2)
+	mpc83xx_pcie_init(1, reg, 0);
+#else
+	mpc83xx_pcie_init(2, reg, 0);
+#endif
+}
+#endif /* CONFIG_PCIE */
diff --git a/cpu/mpc83xx/Makefile b/cpu/mpc83xx/Makefile
index 2329970..a6be7f0 100644
--- a/cpu/mpc83xx/Makefile
+++ b/cpu/mpc83xx/Makefile
@@ -29,7 +29,7 @@ LIB	= $(obj)lib$(CPU).a
 
 START	= start.o
 COBJS	= traps.o cpu.o cpu_init.o speed.o interrupts.o \
-	  spd_sdram.o ecc.o qe_io.o pci.o
+	  spd_sdram.o ecc.o qe_io.o pci.o pcie.o
 
 SRCS	:= $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
 OBJS	:= $(addprefix $(obj),$(SOBJS) $(COBJS))
diff --git a/cpu/mpc83xx/pcie.c b/cpu/mpc83xx/pcie.c
new file mode 100644
index 0000000..92f31aa
--- /dev/null
+++ b/cpu/mpc83xx/pcie.c
@@ -0,0 +1,277 @@
+/*
+ * Copyright (C) 2007 Freescale Semiconductor, Inc.
+ *
+ * Author: Tony Li <tony.li at freescale.com>,
+ * Based on PCI initialization.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <pci.h>
+
+#include <asm/io.h>
+#include <mpc83xx.h>
+
+#ifdef CONFIG_83XX_GENERIC_PCIE
+#define PCIE_MAX_BUSES 2
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static struct pci_controller pcie_hose[PCIE_MAX_BUSES];
+static int pcie_num_buses;
+
+#define cfg_read(val, addr, type, op)	*val = op((type)(addr))
+#define cfg_write(val, addr, type, op)	op((type *)(addr), (val))
+
+#define PCIE_OP(rw, size, type, op)						\
+static int									\
+pcie_##rw##_config_##size(struct pci_controller *hose,				\
+			pci_dev_t dev, int offset, type val)			\
+{										\
+	u32 b, d, f;								\
+	if (hose->indirect_type == INDIRECT_TYPE_NO_PCIE_LINK)			\
+		return -1;							\
+	b = PCI_BUS(dev); d = PCI_DEV(dev) & 0x1f; f = PCI_FUNC(dev) & 0x7;	\
+	b = b - hose->first_busno;						\
+	dev = (b << 24) | (((d << 3) | f) << 16) | (offset & 0xfff);		\
+	cfg_##rw(val, (u32)hose->cfg_addr + (u32)dev, type, op);		\
+	return 0;								\
+}
+
+PCIE_OP(read, byte, u8 *, in_8)
+PCIE_OP(read, word, u16 *, in_le16)
+PCIE_OP(read, dword, u32 *, in_le32)
+PCIE_OP(write, byte, u8, out_8)
+PCIE_OP(write, word, u16, out_le16)
+PCIE_OP(write, dword, u32, out_le32)
+
+void pcie_setup_ops(struct pci_controller *hose, u32 cfg_addr)
+{
+	pci_set_ops(hose,
+			pcie_read_config_byte,
+			pcie_read_config_word,
+			pcie_read_config_dword,
+			pcie_write_config_byte,
+			pcie_write_config_word,
+			pcie_write_config_dword);
+
+	hose->cfg_addr = (unsigned long *)cfg_addr;
+}
+
+static void pcie_init_bus(int bus, struct pci_region *reg)
+{
+	volatile immap_t *immr = (volatile immap_t *)CFG_IMMR;
+	volatile pex83xx_t *pex = &immr->pciexp[bus];
+	volatile struct pex_outbound_window *out_win;
+	volatile struct pex_inbound_window *in_win;
+	struct pci_controller *hose = &pcie_hose[bus];
+	volatile void *hose_cfg_base;
+	static int max_bus = 0;
+	unsigned int ram_sz, barl, tar;
+	u16 reg16;
+	int i, j;
+
+	/* Enable pex csb bridge inbound & outbound transactions */
+	out_le32(&pex->bridge.pex_csb_ctrl,
+		in_le32(&pex->bridge.pex_csb_ctrl) | PEX_CSB_CTRL_OBPIOE |
+		PEX_CSB_CTRL_IBPIOE);
+	//	PEX_CSB_CTRL_IBPIOE | PEX_CSB_CTRL_WDMAE | PEX_CSB_CTRL_RDMAE);
+
+	/* Enable bridge outbound */
+	out_le32(&pex->bridge.pex_csb_obctrl, PEX_CSB_OBCTRL_PIOE |
+		PEX_CSB_OBCTRL_MEMWE | PEX_CSB_OBCTRL_IOWE |
+		PEX_CSB_OBCTRL_CFGWE);
+
+	out_win = &pex->bridge.pex_outbound_win[0];
+	if (bus) {
+		out_le32(&out_win->ar, PEX_OWAR_EN | PEX_OWAR_TYPE_CFG |
+			CFG_PCIE2_CFG_SIZE);
+		out_le32(&out_win->bar, CFG_PCIE2_CFG_BASE);
+	} else {
+		out_le32(&out_win->ar, PEX_OWAR_EN | PEX_OWAR_TYPE_CFG |
+			CFG_PCIE1_CFG_SIZE);
+		out_le32(&out_win->bar, CFG_PCIE1_CFG_BASE);
+	}
+	out_le32(&out_win->tarl, 0);
+	out_le32(&out_win->tarh, 0);
+
+	for (i = 0; i < 2; i++, reg++) {
+		u32 ar;
+		if (reg->size == 0)
+			break;
+
+		hose->regions[i] = *reg;
+		hose->region_count++;
+
+		out_win = &pex->bridge.pex_outbound_win[i + 1];
+		out_le32(&out_win->bar, reg->phys_start);
+		out_le32(&out_win->tarl, reg->bus_start);
+		out_le32(&out_win->tarh, 0);
+		ar = PEX_OWAR_EN | (reg->size & PEX_OWAR_SIZE);
+		if (reg->flags & PCI_REGION_IO)
+			ar |= PEX_OWAR_TYPE_IO;
+		else
+			ar |= PEX_OWAR_TYPE_MEM;
+		out_le32(&out_win->ar, ar);
+	}
+
+	out_le32(&pex->bridge.pex_csb_ibctrl, PEX_CSB_IBCTRL_PIOE);
+
+	ram_sz = gd->ram_size;
+	barl = 0;
+	tar = 0;
+	j = 0;
+	while (ram_sz > 0) {
+		in_win = &pex->bridge.pex_inbound_win[j];
+		out_le32(&in_win->barl, barl);
+		out_le32(&in_win->barh, 0x0);
+		out_le32(&in_win->tar, tar);
+		if (ram_sz >= 0x10000000) {
+			/* The maxium windows size is 256M */
+			out_le32(&in_win->ar, PEX_IWAR_EN | PEX_IWAR_NSOV |
+				PEX_IWAR_TYPE_PF | 0x0FFFF000);
+			barl += 0x10000000;
+			tar += 0x10000000;
+			ram_sz -= 0x10000000;
+		}
+		else {
+			/* The UM  is not clear here.
+			 * So, round up to even Mb boundary */
+
+			ram_sz = ram_sz >> 20 +
+					((ram_sz & 0xFFFFF) ? 1 : 0);
+			if (!(ram_sz % 2))
+				ram_sz -= 1;
+			out_le32(&in_win->ar, PEX_IWAR_EN | PEX_IWAR_NSOV |
+				PEX_IWAR_TYPE_PF | (ram_sz << 20) | 0xFF000);
+			ram_sz = 0;
+		}
+		j++;
+	}
+	i = hose->region_count++;
+	hose->regions[i].bus_start = 0;
+	hose->regions[i].phys_start = 0;
+	hose->regions[i].size = gd->ram_size;
+	hose->regions[i].flags = PCI_REGION_MEM | PCI_REGION_MEMORY;
+
+	in_win = &pex->bridge.pex_inbound_win[j];
+	out_le32(&in_win->barl, CFG_IMMR);
+	out_le32(&in_win->barh, 0);
+	out_le32(&in_win->tar, CFG_IMMR);
+	out_le32(&in_win->ar, PEX_IWAR_EN |
+		PEX_IWAR_TYPE_NO_PF | PEX_IWAR_SIZE_1M);
+
+	i = hose->region_count++;
+	hose->regions[i].bus_start = CFG_IMMR;
+	hose->regions[i].phys_start = CFG_IMMR;
+	hose->regions[i].size = 0x100000;
+	hose->regions[i].flags = PCI_REGION_MEM | PCI_REGION_MEMORY;
+
+	hose->first_busno = max_bus;
+	hose->last_busno = 0xff;
+
+	/* Enable the host virtual INTX interrupts */
+	out_le32(&pex->bridge.pex_int_axi_misc_enb,
+		in_le32(&pex->bridge.pex_int_axi_misc_enb) | 0x1E0);
+
+	pcie_setup_ops(hose, bus ? CFG_PCIE2_CFG_BASE : CFG_PCIE1_CFG_BASE);
+
+	pci_register_hose(hose);
+
+	/* Hose configure header is memory-mapped */
+	hose_cfg_base = (void *)pex;
+
+	get_clocks();
+	/* Configure the PCIE controller core clock ratio */
+	out_le32(hose_cfg_base + PEX_GCLK_RATIO,
+		(((bus ? gd->pciexp2_clk : gd->pciexp1_clk) / 1000000) * 16)
+		/ 333);
+	udelay(1000000);
+
+	/* Do Type 1 bridge configuration */
+	out_8(hose_cfg_base + PCI_PRIMARY_BUS, 0);
+	out_8(hose_cfg_base + PCI_SECONDARY_BUS, 1);
+	out_8(hose_cfg_base + PCI_SUBORDINATE_BUS, 255);
+
+	/*
+	 * Write to Command register
+	 */
+	reg16 = in_le16(hose_cfg_base + PCI_COMMAND);
+	reg16 |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY | PCI_COMMAND_IO |
+			PCI_COMMAND_SERR | PCI_COMMAND_PARITY;
+	out_le16(hose_cfg_base + PCI_COMMAND, reg16);
+
+	/*
+	 * Clear non-reserved bits in status register.
+	 */
+	out_le16(hose_cfg_base + PCI_STATUS, 0xffff);
+	out_8(hose_cfg_base + PCI_LATENCY_TIMER, 0x80);
+	out_8(hose_cfg_base + PCI_CACHE_LINE_SIZE, 0x08);
+
+	printf("PCIE%d: ", bus);
+
+	reg16 = in_le16(hose_cfg_base + PEX_LTSSM_STAT);
+	if (reg16 < 0x16) {
+		printf("No link\n");
+		hose->indirect_type = INDIRECT_TYPE_NO_PCIE_LINK;
+	} else {
+		printf("link\n");
+	}
+
+#ifdef CONFIG_PCI_SCAN_SHOW
+	printf("PCI:   Bus Dev VenId DevId Class Int\n");
+#endif
+
+	/*
+	 * Hose scan.
+	 */
+	hose->last_busno = pci_hose_scan(hose);
+	max_bus = hose->last_busno + 1;
+}
+
+/*
+ * The caller must have already set SCCR, SERDES and the PCIE_LAW BARs
+ * must have been set to cover all of the requested regions.
+ */
+void mpc83xx_pcie_init(int num_buses, struct pci_region **reg, int warmboot)
+{
+	int i;
+
+	if (num_buses > PCIE_MAX_BUSES) {
+		printf("%d PCI buses requsted, %d supported\n",
+			num_buses, PCIE_MAX_BUSES);
+
+		num_buses = PCIE_MAX_BUSES;
+	}
+
+	pcie_num_buses = num_buses;
+
+	/*
+	 * Release PCI RST Output signal.
+	 * Power on to RST high must be at least 100 ms as per PCI spec.
+	 * On warm boots only 1 ms is required.
+	 */
+	udelay(warmboot ? 1000 : 100000);
+
+	for (i = 0; i < num_buses; i++)
+		pcie_init_bus(i, reg[i]);
+}
+
+#endif /* CONFIG_83XX_GENERIC_PCIE */
diff --git a/doc/README.mpc837xemds b/doc/README.mpc837xemds
index 3f0cdf7..5650782 100644
--- a/doc/README.mpc837xemds
+++ b/doc/README.mpc837xemds
@@ -45,6 +45,12 @@ Freescale MPC837xEMDS Board
 	0x8000_0000	0x8fff_ffff	PCI MEM prefetch	256M
 	0x9000_0000	0x9fff_ffff	PCI MEM non-prefetch	256M
 	0xc000_0000	0xdfff_ffff	Empty			512M
+	0xa000_0000	0xafff_ffff	PCI Express 1 Mem	256M
+	0xb000_0000	0xb0ff_ffff	PCI Express 1 Config	16M
+	0xb100_0000	0xb17f_ffff	PCI Express 1 IO	8M
+	0xc000_0000	0xcfff_ffff	PCI Express 2 Mem	256M
+	0xd000_0000	0xd0ff_ffff	PCI Express 2 Config	16M
+	0xd100_0000	0xd17f_ffff	PCI Express 2 IO	8M
 	0xe000_0000	0xe00f_ffff	Int Mem Reg Space	1M
 	0xe010_0000	0xe02f_ffff	Empty			2M
 	0xe030_0000	0xe03f_ffff	PCI IO			1M
diff --git a/include/asm-ppc/immap_83xx.h b/include/asm-ppc/immap_83xx.h
index f011e48..3e863ad 100644
--- a/include/asm-ppc/immap_83xx.h
+++ b/include/asm-ppc/immap_83xx.h
@@ -50,21 +50,26 @@ typedef struct sysconf83xx {
 	law83xx_t lblaw[4];	/* LBIU local access window */
 	u8 res2[0x20];
 	law83xx_t pcilaw[2];	/* PCI local access window */
-	u8 res3[0x30];
+	u8 res3[0x10];
+	law83xx_t pcielaw[2];	/* PCI Express local access window */
+	u8 res4[0x10];
 	law83xx_t ddrlaw[2];	/* DDR local access window */
-	u8 res4[0x50];
+	u8 res5[0x50];
 	u32 sgprl;		/* System General Purpose Register Low */
 	u32 sgprh;		/* System General Purpose Register High */
 	u32 spridr;		/* System Part and Revision ID Register */
-	u8 res5[0x04];
+	u8 res6[0x04];
 	u32 spcr;		/* System Priority Configuration Register */
 	u32 sicrl;		/* System I/O Configuration Register Low */
 	u32 sicrh;		/* System I/O Configuration Register High */
-	u8 res6[0x0C];
+	u8 res7[0x0C];
 	u32 ddrcdr;		/* DDR Control Driver Register */
 	u32 ddrdsr;		/* DDR Debug Status Register */
 	u32 obir;		/* Output Buffer Impedance Register */
-	u8 res7[0xCC];
+	u8 res8[0xC];
+	u32 pecr1;		/* PCI Express control register 1 */
+	u32 pecr2;		/* PCI Express control register 2 */
+	u8 res9[0xB8];
 } sysconf83xx_t;
 
 /*
@@ -557,8 +562,110 @@ typedef struct security83xx {
 /*
  *  PCI Express
  */
+struct pex_inbound_window {
+	u32 ar;
+	u32 tar;
+	u32 barl;
+	u32 barh;
+};
+
+struct pex_outbound_window {
+	u32 ar;
+	u32 bar;
+	u32 tarl;
+	u32 tarh;
+};
+
+struct pex_csb_bridge {
+	u32 pex_csb_ver;
+	u32 pex_csb_cab;
+	u32 pex_csb_ctrl;
+	u8 res0[8];
+	u32 pex_dms_dstmr;
+	u8 res1[4];
+	u32 pex_cbs_stat;
+	u8 res2[0x20];
+	u32 pex_csb_obctrl;
+	u32 pex_csb_obstat;
+	u8 res3[0x98];
+	u32 pex_csb_ibctrl;
+	u32 pex_csb_ibstat;
+	u8 res4[0xb8];
+	u32 pex_wdma_ctrl;
+	u32 pex_wdma_addr;
+	u32 pex_wdma_stat;
+	u8 res5[0x94];
+	u32 pex_rdma_ctrl;
+	u32 pex_rdma_addr;
+	u32 pex_rdma_stat;
+	u8 res6[0xd4];
+	u32 pex_ombcr;
+	u32 pex_ombdr;
+	u8 res7[0x38];
+	u32 pex_imbcr;
+	u32 pex_imbdr;
+	u8 res8[0x38];
+	u32 pex_int_enb;
+	u32 pex_int_stat;
+	u32 pex_int_apio_vec1;
+	u32 pex_int_apio_vec2;
+	u8 res9[0x10];
+	u32 pex_int_ppio_vec1;
+	u32 pex_int_ppio_vec2;
+	u32 pex_int_wdma_vec1;
+	u32 pex_int_wdma_vec2;
+	u32 pex_int_rdma_vec1;
+	u32 pex_int_rdma_vec2;
+	u32 pex_int_misc_vec;
+	u8 res10[4];
+	u32 pex_int_axi_pio_enb;
+	u32 pex_int_axi_wdma_enb;
+	u32 pex_int_axi_rdma_enb;
+	u32 pex_int_axi_misc_enb;
+	u32 pex_int_axi_pio_stat;
+	u32 pex_int_axi_wdma_stat;
+	u32 pex_int_axi_rdma_stat;
+	u32 pex_int_axi_misc_stat;
+	u8 res11[0xa0];
+	struct pex_outbound_window pex_outbound_win[4];
+	u8 res12[0x100];
+	u32 pex_epiwtar0;
+	u32 pex_epiwtar1;
+	u32 pex_epiwtar2;
+	u32 pex_epiwtar3;
+	u8 res13[0x70];
+	struct pex_inbound_window pex_inbound_win[4];
+};
+
 typedef struct pex83xx {
-	u8 fixme[0x1000];
+	u8 pex_cfg_header[0x404];
+	u32 pex_ltssm_stat;
+	u8 res0[0x30];
+	u32 pex_ack_replay_timeout;
+	u8 res1[4];
+	u32 pex_gclk_ratio;
+	u8 res2[0xc];
+	u32 pex_pm_timer;
+	u32 pex_pme_timeout;
+	u8 res3[4];
+	u32 pex_aspm_req_timer;
+	u8 res4[0x18];
+	u32 pex_ssvid_update;
+	u8 res5[0x34];
+	u32 pex_cfg_ready;
+	u8 res6[0x24];
+	u32 pex_bar_sizel;
+	u8 res7[4];
+	u32 pex_bar_sel;
+	u8 res8[0x20];
+	u32 pex_bar_pf;
+	u8 res9[0x88];
+	u32 pex_pme_to_ack_tor;
+	u8 res10[0xc];
+	u32 pex_ss_intr_mask;
+	u8 res11[0x25c];
+	struct pex_csb_bridge bridge;
+	u8 res12[0x160];
 } pex83xx_t;
 
 /*
diff --git a/include/configs/MPC837XEMDS.h b/include/configs/MPC837XEMDS.h
index 219c9da..503db23 100644
--- a/include/configs/MPC837XEMDS.h
+++ b/include/configs/MPC837XEMDS.h
@@ -374,7 +374,7 @@
 
 #ifdef CONFIG_PCI
 #define CONFIG_83XX_GENERIC_PCI	1 /* Use generic PCI setup */
-#define CONFIG_PQ_MDS_PIB	1 /* PQ MDS Platform IO Board */
+#define CONFIG_83XX_GENERIC_PCIE	1 /* Use generic PCIE setup*/
 
 #define CONFIG_NET_MULTI
 #define CONFIG_PCI_PNP		/* do pci plug-and-play */
@@ -384,6 +384,27 @@
 #define CFG_PCI_SUBSYS_VENDORID 0x1957	/* Freescale */
 #endif /* CONFIG_PCI */
 
+/* PCIE address map */
+#define CFG_PCIE1_BASE		0xA0000000
+#define CFG_PCIE1_MEM_BASE	CFG_PCIE1_BASE
+#define CFG_PCIE1_MEM_PHYS	CFG_PCIE1_MEM_BASE
+#define CFG_PCIE1_MEM_SIZE	0x10000000
+#define CFG_PCIE1_CFG_BASE	(CFG_PCIE1_MEM_BASE + CFG_PCIE1_MEM_SIZE)
+#define CFG_PCIE1_CFG_SIZE	0x01000000
+#define CFG_PCIE1_IO_BASE	0x0
+#define CFG_PCIE1_IO_PHYS	(CFG_PCIE1_CFG_BASE + CFG_PCIE1_CFG_SIZE)
+#define CFG_PCIE1_IO_SIZE	0x00800000
+
+#define CFG_PCIE2_BASE		0xC0000000
+#define CFG_PCIE2_MEM_BASE	CFG_PCIE2_BASE
+#define CFG_PCIE2_MEM_PHYS	CFG_PCIE2_MEM_BASE
+#define CFG_PCIE2_MEM_SIZE	0x10000000
+#define CFG_PCIE2_CFG_BASE	(CFG_PCIE2_MEM_BASE + CFG_PCIE2_MEM_SIZE)
+#define CFG_PCIE2_CFG_SIZE	0x01000000
+#define CFG_PCIE2_IO_BASE	0x0
+#define CFG_PCIE2_IO_PHYS	(CFG_PCIE2_CFG_BASE + CFG_PCIE2_CFG_SIZE)
+#define CFG_PCIE2_IO_SIZE	0x00800000
+
 #ifndef CONFIG_NET_MULTI
 #define CONFIG_NET_MULTI	1
 #endif
diff --git a/include/mpc83xx.h b/include/mpc83xx.h
index 306c970..bad60fe 100644
--- a/include/mpc83xx.h
+++ b/include/mpc83xx.h
@@ -1409,6 +1409,48 @@
 #define DDRCDR_M_ODR		0x00000002
 #define DDRCDR_Q_DRN		0x00000001
 
+/* PCIE Bridge Register
+ */
+#define PEX_CSB_CTRL_OBPIOE	0x00000001
+#define PEX_CSB_CTRL_IBPIOE	0x00000002
+#define PEX_CSB_CTRL_WDMAE	0x00000004
+#define PEX_CSB_CTRL_RDMAE	0x00000008
+
+#define PEX_CSB_OBCTRL_PIOE	0x00000001
+#define PEX_CSB_OBCTRL_MEMWE	0x00000002
+#define PEX_CSB_OBCTRL_IOWE	0x00000004
+#define PEX_CSB_OBCTRL_CFGWE	0x00000008
+
+#define PEX_CSB_IBCTRL_PIOE	0x00000001
+
+#define PEX_OWAR_EN		0x00000001
+#define PEX_OWAR_TYPE_CFG	0x00000000
+#define PEX_OWAR_TYPE_IO	0x00000002
+#define PEX_OWAR_TYPE_MEM	0x00000004
+#define PEX_OWAR_RLXO		0x00000008
+#define PEX_OWAR_NANP		0x00000010
+#define PEX_OWAR_SIZE		0xFFFFF000
+
+#define PEX_IWAR_EN		0x00000001
+#define PEX_IWAR_TYPE_INT	0x00000000
+#define PEX_IWAR_TYPE_PF	0x00000004
+#define PEX_IWAR_TYPE_NO_PF	0x00000006
+#define PEX_IWAR_NSOV		0x00000008
+#define PEX_IWAR_NSNP		0x00000010
+#define PEX_IWAR_SIZE		0xFFFFF000
+#define PEX_IWAR_SIZE_1M	0x000FF000
+#define PEX_IWAR_SIZE_2M	0x001FF000
+#define PEX_IWAR_SIZE_4M	0x003FF000
+#define PEX_IWAR_SIZE_8M	0x007FF000
+#define PEX_IWAR_SIZE_16M	0x00FFF000
+#define PEX_IWAR_SIZE_32M	0x01FFF000
+#define PEX_IWAR_SIZE_64M	0x03FFF000
+#define PEX_IWAR_SIZE_128M	0x07FFF000
+#define PEX_IWAR_SIZE_256M	0x0FFFF000
+
+#define PEX_LTSSM_STAT		0x404
+#define PEX_GCLK_RATIO		0x440
+
 #ifndef __ASSEMBLY__
 struct pci_region;
 void mpc83xx_pci_init(int num_buses, struct pci_region **reg, int warmboot);
diff --git a/include/pci.h b/include/pci.h
index 8e5dacc..a0a84c9 100644
--- a/include/pci.h
+++ b/include/pci.h
@@ -374,6 +374,8 @@ extern void pci_cfgfunc_config_device(struct pci_controller* hose, pci_dev_t dev
 
 #define MAX_PCI_REGIONS		7
 
+#define INDIRECT_TYPE_NO_PCIE_LINK	1
+
 /*
  * Structure of a PCI controller (host bridge)
  */
@@ -386,6 +388,8 @@ struct pci_controller {
 	volatile unsigned int *cfg_addr;
 	volatile unsigned char *cfg_data;
 
+	int indirect_type;
+
 	struct pci_region regions[MAX_PCI_REGIONS];
 	int region_count;
 
-- 
1.5.3







More information about the U-Boot mailing list