@@ -9,6 +9,7 @@
#include <linux/align.h>
#include <linux/bitfield.h>
#include <linux/of.h>
+#include <linux/of_address.h>
#include <linux/platform_device.h>
#include "pcie-designware.h"
@@ -279,11 +280,12 @@ static int dw_pcie_ep_set_bar(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
static int dw_pcie_find_index(struct dw_pcie_ep *ep, phys_addr_t addr,
u32 *atu_index)
{
+ phys_addr_t parent_bus_addr = addr - ep->phys_base + ep->parent_bus_addr;
u32 index;
struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
for (index = 0; index < pci->num_ob_windows; index++) {
- if (ep->outbound_addr[index] != addr)
+ if (ep->outbound_addr[index] != parent_bus_addr)
continue;
*atu_index = index;
return 0;
@@ -333,7 +335,7 @@ static int dw_pcie_ep_map_addr(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
atu.func_no = func_no;
atu.type = PCIE_ATU_TYPE_MEM;
- atu.parent_bus_addr = addr;
+ atu.parent_bus_addr = addr - ep->phys_base + ep->parent_bus_addr;
atu.pci_addr = pci_addr;
atu.size = size;
ret = dw_pcie_ep_outbound_atu(ep, &atu);
@@ -901,6 +903,7 @@ int dw_pcie_ep_init(struct dw_pcie_ep *ep)
struct device *dev = pci->dev;
struct platform_device *pdev = to_platform_device(dev);
struct device_node *np = dev->of_node;
+ int index;
INIT_LIST_HEAD(&ep->func_list);
@@ -913,6 +916,20 @@ int dw_pcie_ep_init(struct dw_pcie_ep *ep)
return -EINVAL;
ep->phys_base = res->start;
+ ep->parent_bus_addr = ep->phys_base;
+
+ if (pci->use_parent_dt_ranges) {
+ index = of_property_match_string(np, "reg-names", "addr_space");
+ if (index < 0)
+ return -EINVAL;
+
+ /*
+ * Get the untranslated bus address from devicetree to use it
+ * as the iATU CPU address in dw_pcie_ep_map_addr().
+ */
+ of_property_read_reg(np, index, &ep->parent_bus_addr, NULL);
+ }
+
ep->addr_size = resource_size(res);
if (ep->ops->pre_init)
@@ -413,6 +413,7 @@ struct dw_pcie_ep {
struct list_head func_list;
const struct dw_pcie_ep_ops *ops;
phys_addr_t phys_base;
+ u64 parent_bus_addr;
size_t addr_size;
size_t page_size;
u8 bar_to_atu[PCI_STD_NUM_BARS];