}
 
        /*
-        * Ensure all outbound windows are disabled before proceeding with
-        * the MEM/IO ranges setups.
+        * Ensure all out/inbound windows are disabled before proceeding with
+        * the MEM/IO (dma-)ranges setups.
         */
        for (i = 0; i < pci->num_ob_windows; i++)
                dw_pcie_disable_atu(pci, PCIE_ATU_REGION_DIR_OB, i);
 
+       for (i = 0; i < pci->num_ib_windows; i++)
+               dw_pcie_disable_atu(pci, PCIE_ATU_REGION_DIR_IB, i);
+
        i = 0;
        resource_list_for_each_entry(entry, &pp->bridge->windows) {
                if (resource_type(entry->res) != IORESOURCE_MEM)
        }
 
        if (pci->num_ob_windows <= i)
-               dev_warn(pci->dev, "Resources exceed number of ATU entries (%d)\n",
+               dev_warn(pci->dev, "Ranges exceed outbound iATU size (%d)\n",
                         pci->num_ob_windows);
 
+       i = 0;
+       resource_list_for_each_entry(entry, &pp->bridge->dma_ranges) {
+               if (resource_type(entry->res) != IORESOURCE_MEM)
+                       continue;
+
+               if (pci->num_ib_windows <= i)
+                       break;
+
+               ret = dw_pcie_prog_inbound_atu(pci, i++, PCIE_ATU_TYPE_MEM,
+                                              entry->res->start,
+                                              entry->res->start - entry->offset,
+                                              resource_size(entry->res));
+               if (ret) {
+                       dev_err(pci->dev, "Failed to set DMA range %pr\n",
+                               entry->res);
+                       return ret;
+               }
+       }
+
+       if (pci->num_ib_windows <= i)
+               dev_warn(pci->dev, "Dma-ranges exceed inbound iATU size (%u)\n",
+                        pci->num_ib_windows);
+
        return 0;
 }
 
 
        dw_pcie_writel_atu(pci, PCIE_ATU_REGION_DIR_IB, index, reg, val);
 }
 
-int dw_pcie_prog_inbound_atu(struct dw_pcie *pci, u8 func_no, int index,
-                            int type, u64 cpu_addr, u8 bar)
+int dw_pcie_prog_inbound_atu(struct dw_pcie *pci, int index, int type,
+                            u64 cpu_addr, u64 pci_addr, u64 size)
+{
+       u64 limit_addr = pci_addr + size - 1;
+       u32 retries, val;
+
+       if ((limit_addr & ~pci->region_limit) != (pci_addr & ~pci->region_limit) ||
+           !IS_ALIGNED(cpu_addr, pci->region_align) ||
+           !IS_ALIGNED(pci_addr, pci->region_align) || !size) {
+               return -EINVAL;
+       }
+
+       dw_pcie_writel_atu_ib(pci, index, PCIE_ATU_LOWER_BASE,
+                             lower_32_bits(pci_addr));
+       dw_pcie_writel_atu_ib(pci, index, PCIE_ATU_UPPER_BASE,
+                             upper_32_bits(pci_addr));
+
+       dw_pcie_writel_atu_ib(pci, index, PCIE_ATU_LIMIT,
+                             lower_32_bits(limit_addr));
+       if (dw_pcie_ver_is_ge(pci, 460A))
+               dw_pcie_writel_atu_ib(pci, index, PCIE_ATU_UPPER_LIMIT,
+                                     upper_32_bits(limit_addr));
+
+       dw_pcie_writel_atu_ib(pci, index, PCIE_ATU_LOWER_TARGET,
+                             lower_32_bits(cpu_addr));
+       dw_pcie_writel_atu_ib(pci, index, PCIE_ATU_UPPER_TARGET,
+                             upper_32_bits(cpu_addr));
+
+       val = type;
+       if (upper_32_bits(limit_addr) > upper_32_bits(pci_addr) &&
+           dw_pcie_ver_is_ge(pci, 460A))
+               val |= PCIE_ATU_INCREASE_REGION_SIZE;
+       dw_pcie_writel_atu_ib(pci, index, PCIE_ATU_REGION_CTRL1, val);
+       dw_pcie_writel_atu_ib(pci, index, PCIE_ATU_REGION_CTRL2, PCIE_ATU_ENABLE);
+
+       /*
+        * Make sure ATU enable takes effect before any subsequent config
+        * and I/O accesses.
+        */
+       for (retries = 0; retries < LINK_WAIT_MAX_IATU_RETRIES; retries++) {
+               val = dw_pcie_readl_atu_ib(pci, index, PCIE_ATU_REGION_CTRL2);
+               if (val & PCIE_ATU_ENABLE)
+                       return 0;
+
+               mdelay(LINK_WAIT_IATU);
+       }
+
+       dev_err(pci->dev, "Inbound iATU is not being enabled\n");
+
+       return -ETIMEDOUT;
+}
+
+int dw_pcie_prog_ep_inbound_atu(struct dw_pcie *pci, u8 func_no, int index,
+                               int type, u64 cpu_addr, u8 bar)
 {
        u32 retries, val;
 
 
                              u64 cpu_addr, u64 pci_addr, u64 size);
 int dw_pcie_prog_ep_outbound_atu(struct dw_pcie *pci, u8 func_no, int index,
                                 int type, u64 cpu_addr, u64 pci_addr, u64 size);
-int dw_pcie_prog_inbound_atu(struct dw_pcie *pci, u8 func_no, int index,
-                            int type, u64 cpu_addr, u8 bar);
+int dw_pcie_prog_inbound_atu(struct dw_pcie *pci, int index, int type,
+                            u64 cpu_addr, u64 pci_addr, u64 size);
+int dw_pcie_prog_ep_inbound_atu(struct dw_pcie *pci, u8 func_no, int index,
+                               int type, u64 cpu_addr, u8 bar);
 void dw_pcie_disable_atu(struct dw_pcie *pci, u32 dir, int index);
 void dw_pcie_setup(struct dw_pcie *pci);
 void dw_pcie_iatu_detect(struct dw_pcie *pci);