summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG49
-rw-r--r--README17
-rw-r--r--board/mpc8349ads/Makefile2
-rw-r--r--board/mpc8349ads/mpc8349ads.c41
-rw-r--r--board/mpc8349ads/pci.c380
-rw-r--r--common/cmd_bootm.c16
-rw-r--r--common/ft_build.c49
-rw-r--r--cpu/mpc83xx/cpu.c38
-rw-r--r--drivers/pci.c1
-rw-r--r--drivers/pci_auto.c58
-rw-r--r--drivers/pci_indirect.c16
-rw-r--r--include/asm-ppc/mpc8349_pci.h1
-rw-r--r--include/configs/MPC8349ADS.h24
-rw-r--r--include/configs/stxxtc.h2
-rw-r--r--include/ft_build.h4
-rw-r--r--include/pci.h4
16 files changed, 622 insertions, 80 deletions
diff --git a/CHANGELOG b/CHANGELOG
index 7494c67..5a1ef9f 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -11,6 +11,52 @@ Changes since U-Boot 1.1.4:
* Fixed defines for MPC83xx SICRL register to match current specs
Patch by Kumar Gala, 23 Jan 2006
+* Fixed PCI indirect config ops to handle multiple PCI controllers
+ We need to adjust the bus number we are trying to access based
+ on which PCI controller its on
+ Patch by Kumar Gala 12 Jan 2006
+
+* Add helper function for generic flat device tree fixups for mpc83xx
+ Patch by Kumar Gala 11 Jan 2006
+
+* Add support for passing initrd information via flat device tree
+ Patch by Kumar Gala 11 Jan 2006
+
+* Added OF_STDOUT_PATH and OF_SOC
+
+ OF_STDOUT_PATH specifies the path to the device the kernel can use
+ for console output
+
+ OF_SOC specifies the proper name of the SOC node if one exists.
+ Patch by Kumar Gala 11 Jan 2006
+
+* Allow board code to fixup the flat device tree before booting a
+ kernel
+ Patch by Kumar Gala 11 Jan 2006
+
+* Added CONFIG_ options for bd_t and env in flat dev tree
+
+ CONFIG_OF_HAS_BD_T will put a copy of the bd_t
+ into the resulting flat device tree.
+
+ CONFIG_OF_HAS_UBOOT_ENV will copy the environment
+ variables from u-boot into the flat device tree
+
+ Patch by Kumar Gala 11 Jan 2006
+
+* Report back PCI bus when doing table based device config
+ Patch by Kumar Gala 11 Jan 2006
+
+* Added support for PCI prefetchable region and BARs
+ If a host controller sets up a region as prefetchable and
+ a device's BAR denotes it as prefetchable, allocate the
+ BAR into the prefetch region.
+
+ If a BAR is prefetchable and no prefetchable region has
+ been setup by the controller we fall back to allocating
+ the BAR into the normally memory region.
+ Patch by Kumar Gala 11 Jan 2006
+
* Only disable the MPC83xx watchdog if its enabled out of reset.
If its disabled out of reset SW can later enable it if so desired
Patch by Kumar Gala, 11 Jan 2006
@@ -24,6 +70,9 @@ Changes since U-Boot 1.1.4:
* Make System IO Config Registers board configurable on MPC83xx
Patch by Kumar Gala, 11 Jan 2006
+* Added PCI support for MPC8349ADS board
+ Patch by Kumar Gala 11 Jan 2006
+
* Add support for 28F256J3A flah (=> 64 MB) on PM520 board
* Fix compiler problem with at91rm9200dk board.
diff --git a/README b/README
index 6f61008..ecaef9e 100644
--- a/README
+++ b/README
@@ -411,7 +411,24 @@ The following options need to be configured:
The maximum size of the constructed OF tree.
OF_CPU - The proper name of the cpus node.
+ OF_SOC - The proper name of the soc node.
OF_TBCLK - The timebase frequency.
+ OF_STDOUT_PATH - The path to the console device
+
+ CONFIG_OF_HAS_BD_T
+
+ The resulting flat device tree will have a copy of the bd_t.
+ Space should be pre-allocated in the dts for the bd_t.
+
+ CONFIG_OF_HAS_UBOOT_ENV
+
+ The resulting flat device tree will have a copy of u-boot's
+ environment variables
+
+ CONFIG_OF_BOARD_SETUP
+
+ Board code has addition modification that it wants to make
+ to the flat device tree before handing it off to the kernel
- Serial Ports:
CFG_PL010_SERIAL
diff --git a/board/mpc8349ads/Makefile b/board/mpc8349ads/Makefile
index 4327b0d..f865f9c 100644
--- a/board/mpc8349ads/Makefile
+++ b/board/mpc8349ads/Makefile
@@ -24,7 +24,7 @@ include $(TOPDIR)/config.mk
LIB = lib$(BOARD).a
-OBJS := $(BOARD).o
+OBJS := $(BOARD).o pci.o
$(LIB): $(OBJS) $(SOBJS)
$(AR) crv $@ $(OBJS)
diff --git a/board/mpc8349ads/mpc8349ads.c b/board/mpc8349ads/mpc8349ads.c
index da8d3d7..505acbc 100644
--- a/board/mpc8349ads/mpc8349ads.c
+++ b/board/mpc8349ads/mpc8349ads.c
@@ -147,47 +147,6 @@ int checkboard (void)
return 0;
}
-#if defined(CONFIG_PCI)
-/*
- * Initialize PCI Devices, report devices found
- */
-#ifndef CONFIG_PCI_PNP
-static struct pci_config_table pci_mpc83xxads_config_table[] = {
- {PCI_ANY_ID,PCI_ANY_ID,PCI_ANY_ID,PCI_ANY_ID,
- pci_cfgfunc_config_device, {PCI_ENET0_IOADDR,
- PCI_ENET0_MEMADDR,
- PCI_COMMON_MEMORY | PCI_COMMAND_MASTER
- } },
- {}
-}
-#endif
-
-
-volatile static struct pci_controller hose[] = {
- {
-#ifndef CONFIG_PCI_PNP
- config_table:pci_mpc83xxads_config_table,
-#endif
- },
- {
-#ifndef CONFIG_PCI_PNP
- config_table:pci_mpc83xxads_config_table,
-#endif
- }
-};
-#endif /* CONFIG_PCI */
-
-
-void
-pci_init_board(void)
-{
-#ifdef CONFIG_PCI
- extern void pci_mpc83xx_init(volatile struct pci_controller *hose);
-
- pci_mpc83xx_init(hose);
-#endif /* CONFIG_PCI */
-}
-
/*
* if MPC8349ADS is soldered with SDRAM
*/
diff --git a/board/mpc8349ads/pci.c b/board/mpc8349ads/pci.c
new file mode 100644
index 0000000..6cafbaa
--- /dev/null
+++ b/board/mpc8349ads/pci.c
@@ -0,0 +1,380 @@
+/*
+ * 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 <asm/mmu.h>
+#include <common.h>
+#include <asm/global_data.h>
+#include <pci.h>
+#include <asm/mpc8349_pci.h>
+#include <i2c.h>
+
+#ifdef CONFIG_PCI
+
+/* System RAM mapped to PCI space */
+#define CONFIG_PCI_SYS_MEM_BUS CFG_SDRAM_BASE
+#define CONFIG_PCI_SYS_MEM_PHYS CFG_SDRAM_BASE
+
+#ifndef CONFIG_PCI_PNP
+static struct pci_config_table pci_mpc83xxads_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
+
+static struct pci_controller pci_hose[] = {
+ {
+#ifndef CONFIG_PCI_PNP
+ config_table:pci_mpc83xxads_config_table,
+#endif
+ },
+ {
+#ifndef CONFIG_PCI_PNP
+ config_table:pci_mpc83xxads_config_table,
+#endif
+ }
+};
+
+/**************************************************************************
+ *
+ * pib_init() -- initialize the PCA9555PW IO expander on the PIB board
+ *
+ */
+void
+pib_init(void)
+{
+ u8 val8;
+ /*
+ * Assign PIB PMC slot to desired PCI bus
+ */
+ mpc8349_i2c = (i2c_t*)(CFG_IMMRBAR + CFG_I2C2_OFFSET);
+ i2c_init(CFG_I2C_SPEED, CFG_I2C_SLAVE);
+
+ val8 = 0;
+ i2c_write(0x23, 0x6, 1, &val8, 1);
+ i2c_write(0x23, 0x7, 1, &val8, 1);
+ val8 = 0xff;
+ i2c_write(0x23, 0x2, 1, &val8, 1);
+ i2c_write(0x23, 0x3, 1, &val8, 1);
+
+ val8 = 0;
+ i2c_write(0x26, 0x6, 1, &val8, 1);
+ val8 = 0x34;
+ i2c_write(0x26, 0x7, 1, &val8, 1);
+#if defined(PCI_64BIT)
+ val8 = 0xf4; /* PMC2:PCI1/64-bit */
+#elif defined(PCI_ALL_PCI1)
+ val8 = 0xf3; /* PMC1:PCI1 PMC2:PCI1 PMC3:PCI1 */
+#elif defined(PCI_ONE_PCI1)
+ val8 = 0xf9; /* PMC1:PCI1 PMC2:PCI2 PMC3:PCI2 */
+#else
+ val8 = 0xf5; /* PMC1:PCI1 PMC2:PCI1 PMC3:PCI2 */
+#endif
+ i2c_write(0x26, 0x2, 1, &val8, 1);
+ val8 = 0xff;
+ i2c_write(0x26, 0x3, 1, &val8, 1);
+ val8 = 0;
+ i2c_write(0x27, 0x6, 1, &val8, 1);
+ i2c_write(0x27, 0x7, 1, &val8, 1);
+ val8 = 0xff;
+ i2c_write(0x27, 0x2, 1, &val8, 1);
+ val8 = 0xef;
+ i2c_write(0x27, 0x3, 1, &val8, 1);
+ asm("eieio");
+
+#if defined(PCI_64BIT)
+ printf("PCI1: 64-bit on PMC2\n");
+#elif defined(PCI_ALL_PCI1)
+ printf("PCI1: 32-bit on PMC1, PMC2, PMC3\n");
+#elif defined(PCI_ONE_PCI1)
+ printf("PCI1: 32-bit on PMC1\n");
+ printf("PCI2: 32-bit on PMC2, PMC3\n");
+#else
+ printf("PCI1: 32-bit on PMC1, PMC2\n");
+ printf("PCI2: 32-bit on PMC3\n");
+#endif
+}
+
+/**************************************************************************
+ * pci_init_board()
+ *
+ * NOTICE: PCI2 is not currently supported
+ *
+ */
+void
+pci_init_board(void)
+{
+ DECLARE_GLOBAL_DATA_PTR;
+ volatile immap_t * immr;
+ volatile clk8349_t * clk;
+ volatile law8349_t * pci_law;
+ volatile pot8349_t * pci_pot;
+ volatile pcictrl8349_t * pci_ctrl;
+ volatile pciconf8349_t * pci_conf;
+ u16 reg16;
+ u32 reg32;
+ u32 dev;
+ struct pci_controller * hose;
+
+ immr = (immap_t *)CFG_IMMRBAR;
+ clk = (clk8349_t *)&immr->clk;
+ pci_law = immr->sysconf.pcilaw;
+ pci_pot = immr->ios.pot;
+ pci_ctrl = immr->pci_ctrl;
+ pci_conf = immr->pci_conf;
+
+ hose = &pci_hose[0];
+
+ pib_init();
+
+ /*
+ * Configure PCI controller and PCI_CLK_OUTPUT both in 66M mode
+ */
+
+ reg32 = clk->occr;
+ udelay(2000);
+ clk->occr = 0xff000000;
+ udelay(2000);
+
+ /*
+ * Release PCI RST Output signal
+ */
+ pci_ctrl[0].gcr = 0;
+ udelay(2000);
+ pci_ctrl[0].gcr = 1;
+
+#ifdef CONFIG_MPC83XX_PCI2
+ pci_ctrl[1].gcr = 0;
+ udelay(2000);
+ pci_ctrl[1].gcr = 1;
+#endif
+
+ /* We need to wait at least a 1sec based on PCI specs */
+ {
+ int i;
+
+ for (i = 0; i < 1000; ++i)
+ udelay (1000);
+ }
+
+ /*
+ * Configure PCI Local Access Windows
+ */
+ pci_law[0].bar = CFG_PCI1_MEM_PHYS & LAWBAR_BAR;
+ pci_law[0].ar = LAWAR_EN | LAWAR_SIZE_1G;
+
+ pci_law[1].bar = CFG_PCI1_IO_PHYS & LAWBAR_BAR;
+ pci_law[1].ar = LAWAR_EN | LAWAR_SIZE_32M;
+
+ /*
+ * Configure PCI Outbound Translation Windows
+ */
+
+ /* PCI1 mem space - prefetch */
+ pci_pot[0].potar = (CFG_PCI1_MEM_BASE >> 12) & POTAR_TA_MASK;
+ pci_pot[0].pobar = (CFG_PCI1_MEM_PHYS >> 12) & POBAR_BA_MASK;
+ pci_pot[0].pocmr = POCMR_EN | POCMR_PREFETCH_EN | (POCMR_CM_256M & POCMR_CM_MASK);
+
+ /* PCI1 IO space */
+ pci_pot[1].potar = (CFG_PCI1_IO_BASE >> 12) & POTAR_TA_MASK;
+ pci_pot[1].pobar = (CFG_PCI1_IO_PHYS >> 12) & POBAR_BA_MASK;
+ pci_pot[1].pocmr = POCMR_EN | POCMR_IO | (POCMR_CM_1M & POCMR_CM_MASK);
+
+ /* PCI1 mmio - non-prefetch mem space */
+ pci_pot[2].potar = (CFG_PCI1_MMIO_BASE >> 12) & POTAR_TA_MASK;
+ pci_pot[2].pobar = (CFG_PCI1_MMIO_PHYS >> 12) & POBAR_BA_MASK;
+ pci_pot[2].pocmr = POCMR_EN | (POCMR_CM_256M & POCMR_CM_MASK);
+
+ /*
+ * Configure PCI Inbound Translation Windows
+ */
+
+ /* we need RAM mapped to PCI space for the devices to
+ * access main memory */
+ pci_ctrl[0].pitar1 = 0x0;
+ pci_ctrl[0].pibar1 = 0x0;
+ pci_ctrl[0].piebar1 = 0x0;
+ pci_ctrl[0].piwar1 = PIWAR_EN | PIWAR_PF | PIWAR_RTT_SNOOP | PIWAR_WTT_SNOOP | (__ilog2(gd->ram_size) - 1);
+
+ hose->first_busno = 0;
+ hose->last_busno = 0xff;
+
+ /* PCI memory prefetch space */
+ pci_set_region(hose->regions + 0,
+ CFG_PCI1_MEM_BASE,
+ CFG_PCI1_MEM_PHYS,
+ CFG_PCI1_MEM_SIZE,
+ PCI_REGION_MEM|PCI_REGION_PREFETCH);
+
+ /* PCI memory space */
+ pci_set_region(hose->regions + 1,
+ CFG_PCI1_MMIO_BASE,
+ CFG_PCI1_MMIO_PHYS,
+ CFG_PCI1_MMIO_SIZE,
+ PCI_REGION_MEM);
+
+ /* PCI IO space */
+ pci_set_region(hose->regions + 2,
+ CFG_PCI1_IO_BASE,
+ CFG_PCI1_IO_PHYS,
+ CFG_PCI1_IO_SIZE,
+ PCI_REGION_IO);
+
+ /* System memory space */
+ pci_set_region(hose->regions + 3,
+ CONFIG_PCI_SYS_MEM_BUS,
+ CONFIG_PCI_SYS_MEM_PHYS,
+ gd->ram_size,
+ PCI_REGION_MEM | PCI_REGION_MEMORY);
+
+ hose->region_count = 4;
+
+ pci_setup_indirect(hose,
+ (CFG_IMMRBAR+0x8300),
+ (CFG_IMMRBAR+0x8304));
+
+ pci_register_hose(hose);
+
+ /*
+ * Write to Command register
+ */
+ reg16 = 0xff;
+ dev = PCI_BDF(hose->first_busno, 0, 0);
+ pci_hose_read_config_word (hose, dev, PCI_COMMAND, &reg16);
+ reg16 |= PCI_COMMAND_SERR | PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
+ pci_hose_write_config_word(hose, dev, PCI_COMMAND, reg16);
+
+ /*
+ * Clear non-reserved bits in status register.
+ */
+ pci_hose_write_config_word(hose, dev, PCI_STATUS, 0xffff);
+ pci_hose_write_config_byte(hose, dev, PCI_LATENCY_TIMER, 0x80);
+ pci_hose_write_config_byte(hose, dev, PCI_CACHE_LINE_SIZE, 0x08);
+
+#ifdef CONFIG_PCI_SCAN_SHOW
+ printf("PCI: Bus Dev VenId DevId Class Int\n");
+#endif
+ /*
+ * Hose scan.
+ */
+ hose->last_busno = pci_hose_scan(hose);
+
+#ifdef CONFIG_MPC83XX_PCI2
+ hose = &pci_hose[1];
+
+ /*
+ * Configure PCI Outbound Translation Windows
+ */
+
+ /* PCI2 mem space - prefetch */
+ pci_pot[3].potar = (CFG_PCI2_MEM_BASE >> 12) & POTAR_TA_MASK;
+ pci_pot[3].pobar = (CFG_PCI2_MEM_PHYS >> 12) & POBAR_BA_MASK;
+ pci_pot[3].pocmr = POCMR_EN | POCMR_PCI2 | POCMR_PREFETCH_EN | (POCMR_CM_256M & POCMR_CM_MASK);
+
+ /* PCI2 IO space */
+ pci_pot[4].potar = (CFG_PCI2_IO_BASE >> 12) & POTAR_TA_MASK;
+ pci_pot[4].pobar = (CFG_PCI2_IO_PHYS >> 12) & POBAR_BA_MASK;
+ pci_pot[4].pocmr = POCMR_EN | POCMR_PCI2 | POCMR_IO | (POCMR_CM_1M & POCMR_CM_MASK);
+
+ /* PCI2 mmio - non-prefetch mem space */
+ pci_pot[5].potar = (CFG_PCI2_MMIO_BASE >> 12) & POTAR_TA_MASK;
+ pci_pot[5].pobar = (CFG_PCI2_MMIO_PHYS >> 12) & POBAR_BA_MASK;
+ pci_pot[5].pocmr = POCMR_EN | POCMR_PCI2 | (POCMR_CM_256M & POCMR_CM_MASK);
+
+ /*
+ * Configure PCI Inbound Translation Windows
+ */
+
+ /* we need RAM mapped to PCI space for the devices to
+ * access main memory */
+ pci_ctrl[1].pitar1 = 0x0;
+ pci_ctrl[1].pibar1 = 0x0;
+ pci_ctrl[1].piebar1 = 0x0;
+ pci_ctrl[1].piwar1 = PIWAR_EN | PIWAR_PF | PIWAR_RTT_SNOOP | PIWAR_WTT_SNOOP | (__ilog2(gd->ram_size) - 1);
+
+ hose->first_busno = pci_hose[0].last_busno + 1;
+ hose->last_busno = 0xff;
+
+ /* PCI memory prefetch space */
+ pci_set_region(hose->regions + 0,
+ CFG_PCI2_MEM_BASE,
+ CFG_PCI2_MEM_PHYS,
+ CFG_PCI2_MEM_SIZE,
+ PCI_REGION_MEM|PCI_REGION_PREFETCH);
+
+ /* PCI memory space */
+ pci_set_region(hose->regions + 1,
+ CFG_PCI2_MMIO_BASE,
+ CFG_PCI2_MMIO_PHYS,
+ CFG_PCI2_MMIO_SIZE,
+ PCI_REGION_MEM);
+
+ /* PCI IO space */
+ pci_set_region(hose->regions + 2,
+ CFG_PCI2_IO_BASE,
+ CFG_PCI2_IO_PHYS,
+ CFG_PCI2_IO_SIZE,
+ PCI_REGION_IO);
+
+ /* System memory space */
+ pci_set_region(hose->regions + 3,
+ CONFIG_PCI_SYS_MEM_BUS,
+ CONFIG_PCI_SYS_MEM_PHYS,
+ gd->ram_size,
+ PCI_REGION_MEM | PCI_REGION_MEMORY);
+
+ hose->region_count = 4;
+
+ pci_setup_indirect(hose,
+ (CFG_IMMRBAR+0x8380),
+ (CFG_IMMRBAR+0x8384));
+
+ pci_register_hose(hose);
+
+ /*
+ * Write to Command register
+ */
+ reg16 = 0xff;
+ dev = PCI_BDF(hose->first_busno, 0, 0);
+ pci_hose_read_config_word (hose, dev, PCI_COMMAND, &reg16);
+ reg16 |= PCI_COMMAND_SERR | PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
+ pci_hose_write_config_word(hose, dev, PCI_COMMAND, reg16);
+
+ /*
+ * Clear non-reserved bits in status register.
+ */
+ pci_hose_write_config_word(hose, dev, PCI_STATUS, 0xffff);
+ pci_hose_write_config_byte(hose, dev, PCI_LATENCY_TIMER, 0x80);
+ pci_hose_write_config_byte(hose, dev, PCI_CACHE_LINE_SIZE, 0x08);
+
+ /*
+ * Hose scan.
+ */
+ hose->last_busno = pci_hose_scan(hose);
+#endif
+
+}
+#endif /* CONFIG_PCI */
diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c
index 8599a49..9562dbe 100644
--- a/common/cmd_bootm.c
+++ b/common/cmd_bootm.c
@@ -819,7 +819,7 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag,
(*kernel) (kbd, initrd_start, initrd_end, cmd_start, cmd_end);
#else
- ft_setup(of_flat_tree, OF_FLAT_TREE_MAX_SIZE, kbd);
+ ft_setup(of_flat_tree, OF_FLAT_TREE_MAX_SIZE, kbd, initrd_start, initrd_end);
/* ft_dump_blob(of_flat_tree); */
#if defined(CFG_INIT_RAM_LOCK) && !defined(CONFIG_E500)
@@ -828,12 +828,16 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag,
/*
* Linux Kernel Parameters:
* r3: ptr to OF flat tree, followed by the board info data
- * r4: initrd_start or 0 if no initrd
- * r5: initrd_end - unused if r4 is 0
- * r6: Start of command line string
- * r7: End of command line string
+ * r4: physical pointer to the kernel itself
+ * r5: NULL
+ * r6: NULL
+ * r7: NULL
*/
- (*kernel) ((bd_t *)of_flat_tree, initrd_start, initrd_end, cmd_start, cmd_end);
+ if (getenv("disable_of") != NULL)
+ (*kernel) ((bd_t *)of_flat_tree, initrd_start, initrd_end,
+ cmd_start, cmd_end);
+ else
+ (*kernel) ((bd_t *)of_flat_tree, (ulong)kernel, 0, 0, 0);
#endif
}
diff --git a/common/ft_build.c b/common/ft_build.c
index 65a274f..9e9c906 100644
--- a/common/ft_build.c
+++ b/common/ft_build.c
@@ -163,7 +163,7 @@ void ft_add_rsvmap(struct ft_cxt *cxt, u64 physaddr, u64 size)
((u64 *) cxt->pres)[0] = cpu_to_be64(physaddr); /* phys = 0, size = 0, terminate */
((u64 *) cxt->pres)[1] = cpu_to_be64(size);
- cxt->pres += 18; /* advance */
+ cxt->pres += 16; /* advance */
((u64 *) cxt->pres)[0] = 0; /* phys = 0, size = 0, terminate */
((u64 *) cxt->pres)[1] = 0;
@@ -529,6 +529,7 @@ extern uchar(*env_get_char) (int);
#define BDM(x) { .name = #x, .offset = offsetof(bd_t, bi_ ##x ) }
+#ifdef CONFIG_OF_HAS_BD_T
static const struct {
const char *name;
int offset;
@@ -574,19 +575,24 @@ static const struct {
#endif
BDM(baudrate),
};
+#endif
-void ft_setup(void *blob, int size, bd_t * bd)
+void ft_setup(void *blob, int size, bd_t * bd, ulong initrd_start, ulong initrd_end)
{
- DECLARE_GLOBAL_DATA_PTR;
- u8 *end;
u32 *p;
int len;
struct ft_cxt cxt;
- int i, k, nxt;
- static char tmpenv[256];
- char *s, *lval, *rval;
ulong clock;
- uint32_t v;
+#if defined(CONFIG_OF_HAS_UBOOT_ENV)
+ int k, nxt;
+#endif
+#if defined(CONFIG_OF_HAS_BD_T)
+ u8 *end;
+#endif
+#if defined(CONFIG_OF_HAS_UBOOT_ENV) || defined(CONFIG_OF_HAS_BD_T)
+ int i;
+ static char tmpenv[256];
+#endif
/* disable OF tree; booting old kernel */
if (getenv("disable_of") != NULL) {
@@ -596,7 +602,8 @@ void ft_setup(void *blob, int size, bd_t * bd)
ft_begin(&cxt, blob, size);
- /* fs_add_rsvmap not used */
+ if (initrd_start && initrd_end)
+ ft_add_rsvmap(&cxt, initrd_start, initrd_end - initrd_start + 1);
ft_begin_tree(&cxt);
@@ -610,9 +617,12 @@ void ft_setup(void *blob, int size, bd_t * bd)
/* back into root */
ft_backtrack_node(&cxt);
+#ifdef CONFIG_OF_HAS_UBOOT_ENV
ft_begin_node(&cxt, "u-boot-env");
for (i = 0; env_get_char(i) != '\0'; i = nxt + 1) {
+ char *s, *lval, *rval;
+
for (nxt = i; env_get_char(nxt) != '\0'; ++nxt) ;
s = tmpenv;
for (k = i; k < nxt && s < &tmpenv[sizeof(tmpenv) - 1]; ++k)
@@ -629,12 +639,20 @@ void ft_setup(void *blob, int size, bd_t * bd)
}
ft_end_node(&cxt);
+#endif
ft_begin_node(&cxt, "chosen");
ft_prop_str(&cxt, "name", "chosen");
ft_prop_str(&cxt, "bootargs", getenv("bootargs"));
ft_prop_int(&cxt, "linux,platform", 0x600); /* what is this? */
+ if (initrd_start && initrd_end) {
+ ft_prop_int(&cxt, "linux,initrd-start", initrd_start);
+ ft_prop_int(&cxt, "linux,initrd-end", initrd_end);
+ }
+#ifdef OF_STDOUT_PATH
+ ft_prop_str(&cxt, "linux,stdout-path", OF_STDOUT_PATH);
+#endif
ft_end_node(&cxt);
@@ -647,14 +665,19 @@ void ft_setup(void *blob, int size, bd_t * bd)
ft_dump_blob(blob);
*/
+#ifdef CONFIG_OF_HAS_BD_T
/* paste the bd_t at the end of the flat tree */
end = (char *)blob +
be32_to_cpu(((struct boot_param_header *)blob)->totalsize);
memcpy(end, bd, sizeof(*bd));
+#endif
#ifdef CONFIG_PPC
+#ifdef CONFIG_OF_HAS_BD_T
for (i = 0; i < sizeof(bd_map)/sizeof(bd_map[0]); i++) {
+ uint32_t v;
+
sprintf(tmpenv, "/bd_t/%s", bd_map[i].name);
v = *(uint32_t *)((char *)bd + bd_map[i].offset);
@@ -670,6 +693,7 @@ void ft_setup(void *blob, int size, bd_t * bd)
p = ft_get_prop(blob, "/bd_t/ethspeed", &len);
if (p != NULL)
*p = cpu_to_be32((uint32_t) bd->bi_ethspeed);
+#endif
clock = bd->bi_intfreq;
p = ft_get_prop(blob, "/cpus/" OF_CPU "/clock-frequency", &len);
@@ -680,11 +704,14 @@ void ft_setup(void *blob, int size, bd_t * bd)
clock = OF_TBCLK;
p = ft_get_prop(blob, "/cpus/" OF_CPU "/timebase-frequency", &len);
if (p != NULL)
- *p = cpu_to_be32(OF_TBCLK);
+ *p = cpu_to_be32(clock);
#endif
-
#endif /* __powerpc__ */
+#ifdef CONFIG_OF_BOARD_SETUP
+ ft_board_setup(blob, bd);
+#endif
+
/*
printf("final OF-tree\n");
ft_dump_blob(blob);
diff --git a/cpu/mpc83xx/cpu.c b/cpu/mpc83xx/cpu.c
index 8c9b515..e49e4fe 100644
--- a/cpu/mpc83xx/cpu.c
+++ b/cpu/mpc83xx/cpu.c
@@ -35,6 +35,7 @@
#include <watchdog.h>
#include <command.h>
#include <mpc83xx.h>
+#include <ft_build.h>
#include <asm/processor.h>
@@ -151,3 +152,40 @@ void watchdog_reset (void)
hang(); /* FIXME: implement watchdog_reset()? */
}
#endif /* CONFIG_WATCHDOG */
+
+#if defined(CONFIG_OF_FLAT_TREE)
+void
+ft_cpu_setup(void *blob, bd_t *bd)
+{
+ u32 *p;
+ int len;
+ ulong clock;
+
+ clock = bd->bi_busfreq;
+ p = ft_get_prop(blob, "/cpus/" OF_CPU "/bus-frequency", &len);
+ if (p != NULL)
+ *p = cpu_to_be32(clock);
+
+ p = ft_get_prop(blob, "/" OF_SOC "/bus-frequency", &len);
+ if (p != NULL)
+ *p = cpu_to_be32(clock);
+
+ p = ft_get_prop(blob, "/" OF_SOC "/serial@4500/clock-frequency", &len);
+ if (p != NULL)
+ *p = cpu_to_be32(clock);
+
+ p = ft_get_prop(blob, "/" OF_SOC "/serial@4600/clock-frequency", &len);
+ if (p != NULL)
+ *p = cpu_to_be32(clock);
+
+#ifdef CONFIG_MPC83XX_TSEC1
+ p = ft_get_prop(blob, "/" OF_SOC "/ethernet@24000/address", &len);
+ memcpy(p, bd->bi_enetaddr, 6);
+#endif
+
+#ifdef CONFIG_MPC83XX_TSEC2
+ p = ft_get_prop(blob, "/" OF_SOC "/ethernet@25000/address", &len);
+ memcpy(p, bd->bi_enet1addr, 6);
+#endif
+}
+#endif
diff --git a/drivers/pci.c b/drivers/pci.c
index 5360030..3c24b99 100644
--- a/drivers/pci.c
+++ b/drivers/pci.c
@@ -459,6 +459,7 @@ int pci_hose_scan_bus(struct pci_controller *hose, int bus)
PCI_BUS(dev), PCI_DEV(dev), PCI_FUNC(dev));
if (cfg) {
cfg->config_device(hose, dev, cfg);
+ sub_bus = max(sub_bus, hose->current_busno);
#ifdef CONFIG_PCI_PNP
} else {
int n = pciauto_config_device(hose, dev);
diff --git a/drivers/pci_auto.c b/drivers/pci_auto.c
index 3302457..15f7432 100644
--- a/drivers/pci_auto.c
+++ b/drivers/pci_auto.c
@@ -77,6 +77,7 @@ int pciauto_region_allocate(struct pci_region* res, unsigned int size, unsigned
void pciauto_setup_device(struct pci_controller *hose,
pci_dev_t dev, int bars_num,
struct pci_region *mem,
+ struct pci_region *prefetch,
struct pci_region *io)
{
unsigned int bar_value, bar_response, bar_size;
@@ -111,7 +112,10 @@ void pciauto_setup_device(struct pci_controller *hose,
found_mem64 = 1;
bar_size = ~(bar_response & PCI_BASE_ADDRESS_MEM_MASK) + 1;
- bar_res = mem;
+ if (prefetch && (bar_response & PCI_BASE_ADDRESS_MEM_PREFETCH))
+ bar_res = prefetch;
+ else
+ bar_res = mem;
DEBUGF("PCI Autoconfig: BAR %d, Mem, size=0x%x, ", bar_nr, bar_size);
}
@@ -148,6 +152,7 @@ static void pciauto_prescan_setup_bridge(struct pci_controller *hose,
pci_dev_t dev, int sub_bus)
{
struct pci_region *pci_mem = hose->pci_mem;
+ struct pci_region *pci_prefetch = hose->pci_prefetch;
struct pci_region *pci_io = hose->pci_io;
unsigned int cmdstat;
@@ -169,6 +174,21 @@ static void pciauto_prescan_setup_bridge(struct pci_controller *hose,
cmdstat |= PCI_COMMAND_MEMORY;
}
+ if (pci_prefetch) {
+ /* Round memory allocator to 1MB boundary */
+ pciauto_region_align(pci_prefetch, 0x100000);
+
+ /* Set up memory and I/O filter limits, assume 32-bit I/O space */
+ pci_hose_write_config_word(hose, dev, PCI_PREF_MEMORY_BASE,
+ (pci_prefetch->bus_lower & 0xfff00000) >> 16);
+
+ cmdstat |= PCI_COMMAND_MEMORY;
+ } else {
+ /* We don't support prefetchable memory for now, so disable */
+ pci_hose_write_config_word(hose, dev, PCI_PREF_MEMORY_BASE, 0x1000);
+ pci_hose_write_config_word(hose, dev, PCI_PREF_MEMORY_LIMIT, 0x1000);
+ }
+
if (pci_io) {
/* Round I/O allocator to 4KB boundary */
pciauto_region_align(pci_io, 0x1000);
@@ -181,10 +201,6 @@ static void pciauto_prescan_setup_bridge(struct pci_controller *hose,
cmdstat |= PCI_COMMAND_IO;
}
- /* We don't support prefetchable memory for now, so disable */
- pci_hose_write_config_word(hose, dev, PCI_PREF_MEMORY_BASE, 0x1000);
- pci_hose_write_config_word(hose, dev, PCI_PREF_MEMORY_LIMIT, 0x1000);
-
/* Enable memory and I/O accesses, enable bus master */
pci_hose_write_config_dword(hose, dev, PCI_COMMAND, cmdstat | PCI_COMMAND_MASTER);
}
@@ -193,6 +209,7 @@ static void pciauto_postscan_setup_bridge(struct pci_controller *hose,
pci_dev_t dev, int sub_bus)
{
struct pci_region *pci_mem = hose->pci_mem;
+ struct pci_region *pci_prefetch = hose->pci_prefetch;
struct pci_region *pci_io = hose->pci_io;
/* Configure bus number registers */
@@ -206,6 +223,14 @@ static void pciauto_postscan_setup_bridge(struct pci_controller *hose,
(pci_mem->bus_lower-1) >> 16);
}
+ if (pci_prefetch) {
+ /* Round memory allocator to 1MB boundary */
+ pciauto_region_align(pci_prefetch, 0x100000);
+
+ pci_hose_write_config_word(hose, dev, PCI_PREF_MEMORY_LIMIT,
+ (pci_prefetch->bus_lower-1) >> 16);
+ }
+
if (pci_io) {
/* Round I/O allocator to 4KB boundary */
pciauto_region_align(pci_io, 0x1000);
@@ -239,6 +264,11 @@ void pciauto_config_init(struct pci_controller *hose)
hose->pci_mem->size < hose->regions[i].size)
hose->pci_mem = hose->regions + i;
break;
+ case (PCI_REGION_MEM | PCI_REGION_PREFETCH):
+ if (!hose->pci_prefetch ||
+ hose->pci_prefetch->size < hose->regions[i].size)
+ hose->pci_prefetch = hose->regions + i;
+ break;
}
}
@@ -251,6 +281,14 @@ void pciauto_config_init(struct pci_controller *hose)
hose->pci_mem->bus_start + hose->pci_mem->size - 1);
}
+ if (hose->pci_prefetch) {
+ pciauto_region_init(hose->pci_prefetch);
+
+ DEBUGF("PCI Autoconfig: Prefetchable Memory region: [%lx-%lx]\n",
+ hose->pci_prefetch->bus_start,
+ hose->pci_prefetch->bus_start + hose->pci_prefetch->size - 1);
+ }
+
if (hose->pci_io) {
pciauto_region_init(hose->pci_io);
@@ -275,7 +313,7 @@ int pciauto_config_device(struct pci_controller *hose, pci_dev_t dev)
switch(class) {
case PCI_CLASS_BRIDGE_PCI:
hose->current_busno++;
- pciauto_setup_device(hose, dev, 2, hose->pci_mem, hose->pci_io);
+ pciauto_setup_device(hose, dev, 2, hose->pci_mem, hose->pci_prefetch, hose->pci_io);
DEBUGF("PCI Autoconfig: Found P2P bridge, device %d\n", PCI_DEV(dev));
@@ -301,12 +339,12 @@ int pciauto_config_device(struct pci_controller *hose, pci_dev_t dev)
return sub_bus;
}
- pciauto_setup_device(hose, dev, 6, hose->pci_mem, hose->pci_io);
+ pciauto_setup_device(hose, dev, 6, hose->pci_mem, hose->pci_prefetch, hose->pci_io);
break;
case PCI_CLASS_BRIDGE_CARDBUS:
/* just do a minimal setup of the bridge, let the OS take care of the rest */
- pciauto_setup_device(hose, dev, 0, hose->pci_mem, hose->pci_io);
+ pciauto_setup_device(hose, dev, 0, hose->pci_mem, hose->pci_prefetch, hose->pci_io);
DEBUGF("PCI Autoconfig: Found P2CardBus bridge, device %d\n", PCI_DEV(dev));
@@ -328,11 +366,11 @@ int pciauto_config_device(struct pci_controller *hose, pci_dev_t dev)
* the PIMMR window to be allocated (BAR0 - 1MB size)
*/
DEBUGF("PCI Autoconfig: Broken bridge found, only minimal config\n");
- pciauto_setup_device(hose, dev, 0, hose->pci_mem, hose->pci_io);
+ pciauto_setup_device(hose, dev, 0, hose->pci_mem, hose->pci_prefetch, hose->pci_io);
break;
#endif
default:
- pciauto_setup_device(hose, dev, 6, hose->pci_mem, hose->pci_io);
+ pciauto_setup_device(hose, dev, 6, hose->pci_mem, hose->pci_prefetch, hose->pci_io);
break;
}
diff --git a/drivers/pci_indirect.c b/drivers/pci_indirect.c
index e8f19f5..f0c4a1c 100644
--- a/drivers/pci_indirect.c
+++ b/drivers/pci_indirect.c
@@ -36,6 +36,10 @@ static int \
indirect_##rw##_config_##size(struct pci_controller *hose, \
pci_dev_t dev, int offset, type val) \
{ \
+ u32 b, d,f; \
+ b = PCI_BUS(dev); d = PCI_DEV(dev); f = PCI_FUNC(dev); \
+ b = b - hose->first_busno; \
+ dev = PCI_BDF(b, d, f); \
out_le32(hose->cfg_addr, dev | (offset & 0xfc) | 0x80000000); \
sync(); \
cfg_##rw(val, hose->cfg_data + (offset & mask), type, op); \
@@ -47,6 +51,10 @@ static int \
indirect_##rw##_config_##size(struct pci_controller *hose, \
pci_dev_t dev, int offset, type val) \
{ \
+ u32 b, d,f; \
+ b = PCI_BUS(dev); d = PCI_DEV(dev); f = PCI_FUNC(dev); \
+ b = b - hose->first_busno; \
+ dev = PCI_BDF(b, d, f); \
*(hose->cfg_addr) = dev | (offset & 0xfc) | 0x80000000; \
sync(); \
cfg_##rw(val, hose->cfg_data + (offset & mask), type, op); \
@@ -58,6 +66,10 @@ static int \
indirect_##rw##_config_##size(struct pci_controller *hose, \
pci_dev_t dev, int offset, type val) \
{ \
+ u32 b, d,f; \
+ b = PCI_BUS(dev); d = PCI_DEV(dev); f = PCI_FUNC(dev); \
+ b = b - hose->first_busno; \
+ dev = PCI_BDF(b, d, f); \
if (PCI_BUS(dev) > 0) \
out_le32(hose->cfg_addr, dev | (offset & 0xfc) | 0x80000001); \
else \
@@ -71,6 +83,10 @@ static int \
indirect_##rw##_config_##size(struct pci_controller *hose, \
pci_dev_t dev, int offset, type val) \
{ \
+ u32 b, d,f; \
+ b = PCI_BUS(dev); d = PCI_DEV(dev); f = PCI_FUNC(dev); \
+ b = b - hose->first_busno; \
+ dev = PCI_BDF(b, d, f); \
out_le32(hose->cfg_addr, dev | (offset & 0xfc) | 0x80000000); \
cfg_##rw(val, hose->cfg_data + (offset & mask), type, op); \
return 0; \
diff --git a/include/asm-ppc/mpc8349_pci.h b/include/asm-ppc/mpc8349_pci.h
index 48255a3..7a1adba 100644
--- a/include/asm-ppc/mpc8349_pci.h
+++ b/include/asm-ppc/mpc8349_pci.h
@@ -77,6 +77,7 @@
#define POCMR_ENABLE 0x80000000
#define POCMR_PCI_IO 0x40000000
#define POCMR_PREFETCH_EN 0x20000000
+#define POCMR_PCI2 0x10000000
/* Soft PCI reset */
diff --git a/include/configs/MPC8349ADS.h b/include/configs/MPC8349ADS.h
index ef2e532..1e9a1f7 100644
--- a/include/configs/MPC8349ADS.h
+++ b/include/configs/MPC8349ADS.h
@@ -41,9 +41,8 @@
#define CONFIG_MPC8349 1 /* MPC8349 specific */
#define CONFIG_MPC8349ADS 1 /* MPC8349ADS board specific */
-/* FIXME: Real PCI support will come in a follow-up update. */
-#undef CONFIG_PCI
-
+#define CONFIG_PCI
+#undef CONFIG_MPC83XX_PCI2 /* support for 2nd PCI controller */
#define CONFIG_TSEC_ENET /* tsec ethernet support */
#define CONFIG_ENV_OVERWRITE
@@ -324,19 +323,26 @@
* General PCI
* Addresses are mapped 1-1.
*/
+
#define CFG_PCI1_MEM_BASE 0x80000000
#define CFG_PCI1_MEM_PHYS CFG_PCI1_MEM_BASE
-#define CFG_PCI1_MEM_SIZE 0x20000000 /* 512M */
+#define CFG_PCI1_MEM_SIZE 0x10000000 /* 256M */
+#define CFG_PCI1_MMIO_BASE 0x90000000
+#define CFG_PCI1_MMIO_PHYS CFG_PCI1_MMIO_BASE
+#define CFG_PCI1_MMIO_SIZE 0x10000000 /* 256M */
#define CFG_PCI1_IO_BASE 0x00000000
#define CFG_PCI1_IO_PHYS 0xe2000000
-#define CFG_PCI1_IO_SIZE 0x1000000 /* 16M */
+#define CFG_PCI1_IO_SIZE 0x00100000 /* 1M */
-#define CFG_PCI2_MEM_BASE 0xA0000000
+#define CFG_PCI2_MEM_BASE 0xa0000000
#define CFG_PCI2_MEM_PHYS CFG_PCI2_MEM_BASE
-#define CFG_PCI2_MEM_SIZE 0x20000000 /* 512M */
+#define CFG_PCI2_MEM_SIZE 0x10000000 /* 256M */
+#define CFG_PCI2_MMIO_BASE 0xb0000000
+#define CFG_PCI2_MMIO_PHYS CFG_PCI2_MMIO_BASE
+#define CFG_PCI2_MMIO_SIZE 0x10000000 /* 256M */
#define CFG_PCI2_IO_BASE 0x00000000
-#define CFG_PCI2_IO_PHYS 0xe3000000
-#define CFG_PCI2_IO_SIZE 0x1000000 /* 16M */
+#define CFG_PCI2_IO_PHYS 0xe2100000
+#define CFG_PCI2_IO_SIZE 0x00100000 /* 1M */
#if defined(CONFIG_PCI)
#define PCI_ALL_PCI1
diff --git a/include/configs/stxxtc.h b/include/configs/stxxtc.h
index 3ffe6b2..be6c36c 100644
--- a/include/configs/stxxtc.h
+++ b/include/configs/stxxtc.h
@@ -584,5 +584,7 @@ typedef unsigned int led_id_t;
#define OF_CPU "PowerPC,MPC870@0"
#define OF_TBCLK (MPC8XX_HZ / 16)
+#define CONFIG_OF_HAS_BD_T 1
+#define CONFIG_OF_HAS_UBOOT_ENV 1
#endif /* __CONFIG_H */
diff --git a/include/ft_build.h b/include/ft_build.h
index 9104b1a..47ca575 100644
--- a/include/ft_build.h
+++ b/include/ft_build.h
@@ -57,10 +57,12 @@ void ft_prop_int(struct ft_cxt *cxt, const char *name, int val);
void ft_begin(struct ft_cxt *cxt, void *blob, int max_size);
void ft_add_rsvmap(struct ft_cxt *cxt, u64 physaddr, u64 size);
-void ft_setup(void *blob, int size, bd_t * bd);
+void ft_setup(void *blob, int size, bd_t * bd, ulong initrd_start, ulong initrd_end);
void ft_dump_blob(const void *bphp);
void ft_merge_blob(struct ft_cxt *cxt, void *blob);
void *ft_get_prop(void *bphp, const char *propname, int *szp);
+void ft_board_setup(void *blob, bd_t *bd);
+
#endif
diff --git a/include/pci.h b/include/pci.h
index 8f19997..f78a769 100644
--- a/include/pci.h
+++ b/include/pci.h
@@ -309,6 +309,7 @@ struct pci_region {
#define PCI_REGION_MEM 0x00000000 /* PCI memory space */
#define PCI_REGION_IO 0x00000001 /* PCI IO space */
#define PCI_REGION_TYPE 0x00000001
+#define PCI_REGION_PREFETCH 0x00000008 /* prefetchable PCI memory */
#define PCI_REGION_MEMORY 0x00000100 /* System memory */
#define PCI_REGION_RO 0x00000200 /* Read-only memory */
@@ -386,7 +387,7 @@ struct pci_controller {
int (*write_dword)(struct pci_controller*, pci_dev_t, int where, u32);
/* Used by auto config */
- struct pci_region *pci_mem, *pci_io;
+ struct pci_region *pci_mem, *pci_io, *pci_prefetch;
/* Used by ppc405 autoconfig*/
struct pci_region *pci_fb;
@@ -472,6 +473,7 @@ extern int pciauto_region_allocate(struct pci_region* res, unsigned int size, un
extern void pciauto_setup_device(struct pci_controller *hose,
pci_dev_t dev, int bars_num,
struct pci_region *mem,
+ struct pci_region *prefetch,
struct pci_region *io);
int pciauto_config_device(struct pci_controller *hose, pci_dev_t dev);