+
+#ifndef CONFIG_SYS_PCI_MEMORY_BUS
+#define CONFIG_SYS_PCI_MEMORY_BUS 0
+#endif
+
+#ifndef CONFIG_SYS_PCI_MEMORY_PHYS
+#define CONFIG_SYS_PCI_MEMORY_PHYS 0
+#endif
+
+#if defined(CONFIG_SYS_PCI_64BIT) && !defined(CONFIG_SYS_PCI64_MEMORY_BUS)
+#define CONFIG_SYS_PCI64_MEMORY_BUS (64ull*1024*1024*1024)
+#endif
+
+/* Setup one inbound ATMU window.
+ *
+ * We let the caller decide what the window size should be
+ */
+static void set_inbound_window(volatile pit_t *pi,
+ struct pci_region *r,
+ u64 size)
+{
+ u32 sz = (__ilog2_u64(size) - 1);
+ u32 flag = PIWAR_EN | PIWAR_LOCAL |
+ PIWAR_READ_SNOOP | PIWAR_WRITE_SNOOP;
+
+ out_be32(&pi->pitar, r->phys_start >> 12);
+ out_be32(&pi->piwbar, r->bus_start >> 12);
+#ifdef CONFIG_SYS_PCI_64BIT
+ out_be32(&pi->piwbear, r->bus_start >> 44);
+#else
+ out_be32(&pi->piwbear, 0);
+#endif
+ if (r->flags & PCI_REGION_PREFETCH)
+ flag |= PIWAR_PF;
+ out_be32(&pi->piwar, flag | sz);
+}
+
+int fsl_setup_hose(struct pci_controller *hose, unsigned long addr)
+{
+ volatile ccsr_fsl_pci_t *pci = (ccsr_fsl_pci_t *) addr;
+
+ pci_setup_indirect(hose, (u32)&pci->cfg_addr, (u32)&pci->cfg_data);
+
+ return fsl_is_pci_agent(hose);
+}
+
+static int fsl_pci_setup_inbound_windows(struct pci_controller *hose,
+ u64 out_lo, u8 pcie_cap,
+ volatile pit_t *pi)
+{
+ struct pci_region *r = hose->regions + hose->region_count;
+ u64 sz = min((u64)gd->ram_size, (1ull << 32));
+
+ phys_addr_t phys_start = CONFIG_SYS_PCI_MEMORY_PHYS;
+ pci_addr_t bus_start = CONFIG_SYS_PCI_MEMORY_BUS;
+ pci_size_t pci_sz;
+
+ /* we have no space available for inbound memory mapping */
+ if (bus_start > out_lo) {
+ printf ("no space for inbound mapping of memory\n");
+ return 0;
+ }
+
+ /* limit size */
+ if ((bus_start + sz) > out_lo) {
+ sz = out_lo - bus_start;
+ debug ("limiting size to %llx\n", sz);
+ }
+
+ pci_sz = 1ull << __ilog2_u64(sz);
+ /*
+ * we can overlap inbound/outbound windows on PCI-E since RX & TX
+ * links a separate
+ */
+ if ((pcie_cap == PCI_CAP_ID_EXP) && (pci_sz < sz)) {
+ debug ("R0 bus_start: %llx phys_start: %llx size: %llx\n",
+ (u64)bus_start, (u64)phys_start, (u64)sz);
+ pci_set_region(r, bus_start, phys_start, sz,
+ PCI_REGION_MEM | PCI_REGION_SYS_MEMORY |
+ PCI_REGION_PREFETCH);
+
+ /* if we aren't an exact power of two match, pci_sz is smaller
+ * round it up to the next power of two. We report the actual
+ * size to pci region tracking.
+ */
+ if (pci_sz != sz)
+ sz = 2ull << __ilog2_u64(sz);
+
+ set_inbound_window(pi--, r++, sz);
+ sz = 0; /* make sure we dont set the R2 window */
+ } else {
+ debug ("R0 bus_start: %llx phys_start: %llx size: %llx\n",
+ (u64)bus_start, (u64)phys_start, (u64)pci_sz);
+ pci_set_region(r, bus_start, phys_start, pci_sz,
+ PCI_REGION_MEM | PCI_REGION_SYS_MEMORY |
+ PCI_REGION_PREFETCH);
+ set_inbound_window(pi--, r++, pci_sz);
+
+ sz -= pci_sz;
+ bus_start += pci_sz;
+ phys_start += pci_sz;
+
+ pci_sz = 1ull << __ilog2_u64(sz);
+ if (sz) {
+ debug ("R1 bus_start: %llx phys_start: %llx size: %llx\n",
+ (u64)bus_start, (u64)phys_start, (u64)pci_sz);
+ pci_set_region(r, bus_start, phys_start, pci_sz,
+ PCI_REGION_MEM | PCI_REGION_SYS_MEMORY |
+ PCI_REGION_PREFETCH);
+ set_inbound_window(pi--, r++, pci_sz);
+ sz -= pci_sz;
+ bus_start += pci_sz;
+ phys_start += pci_sz;
+ }
+ }
+
+#if defined(CONFIG_PHYS_64BIT) && defined(CONFIG_SYS_PCI_64BIT)
+ /*
+ * On 64-bit capable systems, set up a mapping for all of DRAM
+ * in high pci address space.
+ */
+ pci_sz = 1ull << __ilog2_u64(gd->ram_size);
+ /* round up to the next largest power of two */
+ if (gd->ram_size > pci_sz)
+ pci_sz = 1ull << (__ilog2_u64(gd->ram_size) + 1);
+ debug ("R64 bus_start: %llx phys_start: %llx size: %llx\n",
+ (u64)CONFIG_SYS_PCI64_MEMORY_BUS,
+ (u64)CONFIG_SYS_PCI_MEMORY_PHYS,
+ (u64)pci_sz);
+ pci_set_region(r,
+ CONFIG_SYS_PCI64_MEMORY_BUS,
+ CONFIG_SYS_PCI_MEMORY_PHYS,
+ pci_sz,
+ PCI_REGION_MEM | PCI_REGION_SYS_MEMORY |
+ PCI_REGION_PREFETCH);
+ set_inbound_window(pi--, r++, pci_sz);
+#else
+ pci_sz = 1ull << __ilog2_u64(sz);
+ if (sz) {
+ debug ("R2 bus_start: %llx phys_start: %llx size: %llx\n",
+ (u64)bus_start, (u64)phys_start, (u64)pci_sz);
+ pci_set_region(r, bus_start, phys_start, pci_sz,
+ PCI_REGION_MEM | PCI_REGION_SYS_MEMORY |
+ PCI_REGION_PREFETCH);
+ sz -= pci_sz;
+ bus_start += pci_sz;
+ phys_start += pci_sz;
+ set_inbound_window(pi--, r++, pci_sz);
+ }
+#endif
+
+#ifdef CONFIG_PHYS_64BIT
+ if (sz && (((u64)gd->ram_size) < (1ull << 32)))
+ printf("Was not able to map all of memory via "
+ "inbound windows -- %lld remaining\n", sz);
+#endif
+
+ hose->region_count = r - hose->regions;
+
+ return 1;
+}
+
+void fsl_pci_init(struct pci_controller *hose, u32 cfg_addr, u32 cfg_data)