Commit 63c83f1f authored by Bjorn Helgaas's avatar Bjorn Helgaas
Browse files

Merge branch 'pci/controller/dwc-cpu-addr-fixup'

- Ioremap() msg_res region using res->start (the CPU address), not the ATU
  'cpu_addr', which will be replaced with the ATU input address (which may
  not be the CPU address) (Frank Li)

- Rename struct dw_pcie_ob_atu_cfg.cpu_addr to 'parent_bus_addr' (Frank Li)

- Call devm_pci_alloc_host_bridge() early in dw_pcie_host_init() to keep
  devicetree-related code together (Frank Li)

- Consolidate devicetree handling in dw_pcie_host_get_resources() (Bjorn
  Helgaas)

- Add dw_pcie_parent_bus_offset() to look up the parent bus address of a
  specified 'reg' property and return the offset from the CPU physical
  address (Frank Li)

- Add cross-checking with .cpu_addr_fixup() and debug logging to
  dw_pcie_parent_bus_offset() (Frank Li)

- Use devicetree 'reg[config]' via dw_pcie_parent_bus_offset() to derive
  CPU -> ATU addr offset for host controller (Frank Li)

- Call epc_create() early in dw_pcie_ep_init() to keep devicetree-related
  code together (Bjorn Helgaas)

- Consolidate devicetree handling in dw_pcie_ep_get_resources() (Bjorn
  Helgaas)

- Use devicetree 'reg[addr_space]' via dw_pcie_parent_bus_offset() to
  derive CPU -> ATU addr offset for endpoint controller (Frank Li)

- Update dw_pcie_find_index() to remove assumption that ATU input address
  is non-zero (Frank Li)

- Apply struct dw_pcie.parent_bus_offset in ATU users to remove use of
  .cpu_addr_fixup() when programming ATU (Frank Li)

- Remove imx_pcie_cpu_addr_fixup() since dwc core can now derive the ATU
  input address (using parent_bus_offset) from devicetree (Frank Li)

- Remove intel_pcie_cpu_addr() since dwc core can now derive the ATU input
  address (using parent_bus_offset) from devicetree (Frank Li)

* pci/controller/dwc-cpu-addr-fixup:
  PCI: intel-gw: Remove intel_pcie_cpu_addr()
  PCI: imx6: Remove imx_pcie_cpu_addr_fixup()
  PCI: dwc: Use parent_bus_offset to remove need for .cpu_addr_fixup()
  PCI: dwc: ep: Ensure proper iteration over outbound map windows
  PCI: dwc: ep: Use devicetree 'reg[addr_space]' to derive CPU -> ATU addr offset
  PCI: dwc: ep: Consolidate devicetree handling in dw_pcie_ep_get_resources()
  PCI: dwc: ep: Call epc_create() early in dw_pcie_ep_init()
  PCI: dwc: Use devicetree 'reg[config]' to derive CPU -> ATU addr offset
  PCI: dwc: Add dw_pcie_parent_bus_offset() checking and debug
  PCI: dwc: Add dw_pcie_parent_bus_offset()
  PCI: dwc: Consolidate devicetree handling in dw_pcie_host_get_resources()
  PCI: dwc: Call devm_pci_alloc_host_bridge() early in dw_pcie_host_init()
  PCI: dwc: Rename cpu_addr to parent_bus_addr for ATU configuration
  PCI: dwc: Use resource start as ioremap() input in dw_pcie_pme_turn_off()

# Conflicts:
#	drivers/pci/controller/dwc/pcie-designware.c
#	drivers/pci/controller/dwc/pcie-designware.h
parents 79e08f8d 07ae413e
Loading
Loading
Loading
Loading
+1 −17
Original line number Diff line number Diff line
@@ -1214,22 +1214,6 @@ static void imx_pcie_host_exit(struct dw_pcie_rp *pp)
		regulator_disable(imx_pcie->vpcie);
}

static u64 imx_pcie_cpu_addr_fixup(struct dw_pcie *pcie, u64 cpu_addr)
{
	struct imx_pcie *imx_pcie = to_imx_pcie(pcie);
	struct dw_pcie_rp *pp = &pcie->pp;
	struct resource_entry *entry;

	if (!(imx_pcie->drvdata->flags & IMX_PCIE_FLAG_CPU_ADDR_FIXUP))
		return cpu_addr;

	entry = resource_list_first_type(&pp->bridge->windows, IORESOURCE_MEM);
	if (!entry)
		return cpu_addr;

	return cpu_addr - entry->offset;
}

/*
 * In old DWC implementations, PCIE_ATU_INHIBIT_PAYLOAD in iATU Ctrl2
 * register is reserved, so the generic DWC implementation of sending the
@@ -1260,7 +1244,6 @@ static const struct dw_pcie_host_ops imx_pcie_host_dw_pme_ops = {
static const struct dw_pcie_ops dw_pcie_ops = {
	.start_link = imx_pcie_start_link,
	.stop_link = imx_pcie_stop_link,
	.cpu_addr_fixup = imx_pcie_cpu_addr_fixup,
};

static void imx_pcie_ep_init(struct dw_pcie_ep *ep)
@@ -1631,6 +1614,7 @@ static int imx_pcie_probe(struct platform_device *pdev)
	if (ret)
		return ret;

	pci->use_parent_dt_ranges = true;
	if (imx_pcie->drvdata->mode == DW_PCIE_EP_TYPE) {
		ret = imx_add_pcie_ep(imx_pcie, pdev);
		if (ret < 0)
+48 −26
Original line number Diff line number Diff line
@@ -167,7 +167,7 @@ static int dw_pcie_ep_write_header(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
}

static int dw_pcie_ep_inbound_atu(struct dw_pcie_ep *ep, u8 func_no, int type,
				  dma_addr_t cpu_addr, enum pci_barno bar,
				  dma_addr_t parent_bus_addr, enum pci_barno bar,
				  size_t size)
{
	int ret;
@@ -185,7 +185,7 @@ static int dw_pcie_ep_inbound_atu(struct dw_pcie_ep *ep, u8 func_no, int type,
	}

	ret = dw_pcie_prog_ep_inbound_atu(pci, func_no, free_win, type,
					  cpu_addr, bar, size);
					  parent_bus_addr, bar, size);
	if (ret < 0) {
		dev_err(pci->dev, "Failed to program IB window\n");
		return ret;
@@ -220,7 +220,7 @@ static int dw_pcie_ep_outbound_atu(struct dw_pcie_ep *ep,
		return ret;

	set_bit(free_win, ep->ob_window_map);
	ep->outbound_addr[free_win] = atu->cpu_addr;
	ep->outbound_addr[free_win] = atu->parent_bus_addr;

	return 0;
}
@@ -451,7 +451,7 @@ static int dw_pcie_find_index(struct dw_pcie_ep *ep, phys_addr_t addr,
	u32 index;
	struct dw_pcie *pci = to_dw_pcie_from_ep(ep);

	for (index = 0; index < pci->num_ob_windows; index++) {
	for_each_set_bit(index, ep->ob_window_map, pci->num_ob_windows) {
		if (ep->outbound_addr[index] != addr)
			continue;
		*atu_index = index;
@@ -483,7 +483,8 @@ static void dw_pcie_ep_unmap_addr(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
	struct dw_pcie_ep *ep = epc_get_drvdata(epc);
	struct dw_pcie *pci = to_dw_pcie_from_ep(ep);

	ret = dw_pcie_find_index(ep, addr, &atu_index);
	ret = dw_pcie_find_index(ep, addr - pci->parent_bus_offset,
				 &atu_index);
	if (ret < 0)
		return;

@@ -502,7 +503,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.cpu_addr = addr;
	atu.parent_bus_addr = addr - pci->parent_bus_offset;
	atu.pci_addr = pci_addr;
	atu.size = size;
	ret = dw_pcie_ep_outbound_atu(ep, &atu);
@@ -1060,26 +1061,15 @@ void dw_pcie_ep_linkdown(struct dw_pcie_ep *ep)
}
EXPORT_SYMBOL_GPL(dw_pcie_ep_linkdown);

/**
 * dw_pcie_ep_init - Initialize the endpoint device
 * @ep: DWC EP device
 *
 * Initialize the endpoint device. Allocate resources and create the EPC
 * device with the endpoint framework.
 *
 * Return: 0 if success, errno otherwise.
 */
int dw_pcie_ep_init(struct dw_pcie_ep *ep)
static int dw_pcie_ep_get_resources(struct dw_pcie_ep *ep)
{
	int ret;
	struct resource *res;
	struct pci_epc *epc;
	struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
	struct device *dev = pci->dev;
	struct platform_device *pdev = to_platform_device(dev);
	struct device_node *np = dev->of_node;

	INIT_LIST_HEAD(&ep->func_list);
	struct pci_epc *epc = ep->epc;
	struct resource *res;
	int ret;

	ret = dw_pcie_get_resources(pci);
	if (ret)
@@ -1092,8 +1082,37 @@ int dw_pcie_ep_init(struct dw_pcie_ep *ep)
	ep->phys_base = res->start;
	ep->addr_size = resource_size(res);

	if (ep->ops->pre_init)
		ep->ops->pre_init(ep);
	/*
	 * artpec6_pcie_cpu_addr_fixup() uses ep->phys_base, so call
	 * dw_pcie_parent_bus_offset() after setting ep->phys_base.
	 */
	pci->parent_bus_offset = dw_pcie_parent_bus_offset(pci, "addr_space",
							   ep->phys_base);

	ret = of_property_read_u8(np, "max-functions", &epc->max_functions);
	if (ret < 0)
		epc->max_functions = 1;

	return 0;
}

/**
 * dw_pcie_ep_init - Initialize the endpoint device
 * @ep: DWC EP device
 *
 * Initialize the endpoint device. Allocate resources and create the EPC
 * device with the endpoint framework.
 *
 * Return: 0 if success, errno otherwise.
 */
int dw_pcie_ep_init(struct dw_pcie_ep *ep)
{
	int ret;
	struct pci_epc *epc;
	struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
	struct device *dev = pci->dev;

	INIT_LIST_HEAD(&ep->func_list);

	epc = devm_pci_epc_create(dev, &epc_ops);
	if (IS_ERR(epc)) {
@@ -1104,9 +1123,12 @@ int dw_pcie_ep_init(struct dw_pcie_ep *ep)
	ep->epc = epc;
	epc_set_drvdata(epc, ep);

	ret = of_property_read_u8(np, "max-functions", &epc->max_functions);
	if (ret < 0)
		epc->max_functions = 1;
	ret = dw_pcie_ep_get_resources(ep);
	if (ret)
		return ret;

	if (ep->ops->pre_init)
		ep->ops->pre_init(ep);

	ret = pci_epc_mem_init(epc, ep->phys_base, ep->addr_size,
			       ep->page_size);
+38 −19
Original line number Diff line number Diff line
@@ -418,19 +418,15 @@ static void dw_pcie_host_request_msg_tlp_res(struct dw_pcie_rp *pp)
	}
}

int dw_pcie_host_init(struct dw_pcie_rp *pp)
static int dw_pcie_host_get_resources(struct dw_pcie_rp *pp)
{
	struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
	struct device *dev = pci->dev;
	struct device_node *np = dev->of_node;
	struct platform_device *pdev = to_platform_device(dev);
	struct resource_entry *win;
	struct pci_host_bridge *bridge;
	struct resource *res;
	int ret;

	raw_spin_lock_init(&pp->lock);

	ret = dw_pcie_get_resources(pci);
	if (ret)
		return ret;
@@ -448,20 +444,43 @@ int dw_pcie_host_init(struct dw_pcie_rp *pp)
	if (IS_ERR(pp->va_cfg0_base))
		return PTR_ERR(pp->va_cfg0_base);

	bridge = devm_pci_alloc_host_bridge(dev, 0);
	if (!bridge)
		return -ENOMEM;

	pp->bridge = bridge;

	/* Get the I/O range from DT */
	win = resource_list_first_type(&bridge->windows, IORESOURCE_IO);
	win = resource_list_first_type(&pp->bridge->windows, IORESOURCE_IO);
	if (win) {
		pp->io_size = resource_size(win->res);
		pp->io_bus_addr = win->res->start - win->offset;
		pp->io_base = pci_pio_to_address(win->res->start);
	}

	/*
	 * visconti_pcie_cpu_addr_fixup() uses pp->io_base, so we have to
	 * call dw_pcie_parent_bus_offset() after setting pp->io_base.
	 */
	pci->parent_bus_offset = dw_pcie_parent_bus_offset(pci, "config",
							   pp->cfg0_base);
	return 0;
}

int dw_pcie_host_init(struct dw_pcie_rp *pp)
{
	struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
	struct device *dev = pci->dev;
	struct device_node *np = dev->of_node;
	struct pci_host_bridge *bridge;
	int ret;

	raw_spin_lock_init(&pp->lock);

	bridge = devm_pci_alloc_host_bridge(dev, 0);
	if (!bridge)
		return -ENOMEM;

	pp->bridge = bridge;

	ret = dw_pcie_host_get_resources(pp);
	if (ret)
		return ret;

	/* Set default bus ops */
	bridge->ops = &dw_pcie_ops;
	bridge->child_ops = &dw_child_pcie_ops;
@@ -620,7 +639,7 @@ static void __iomem *dw_pcie_other_conf_map_bus(struct pci_bus *bus,
		type = PCIE_ATU_TYPE_CFG1;

	atu.type = type;
	atu.cpu_addr = pp->cfg0_base;
	atu.parent_bus_addr = pp->cfg0_base - pci->parent_bus_offset;
	atu.pci_addr = busdev;
	atu.size = pp->cfg0_size;

@@ -645,7 +664,7 @@ static int dw_pcie_rd_other_conf(struct pci_bus *bus, unsigned int devfn,

	if (pp->cfg0_io_shared) {
		atu.type = PCIE_ATU_TYPE_IO;
		atu.cpu_addr = pp->io_base;
		atu.parent_bus_addr = pp->io_base - pci->parent_bus_offset;
		atu.pci_addr = pp->io_bus_addr;
		atu.size = pp->io_size;

@@ -671,7 +690,7 @@ static int dw_pcie_wr_other_conf(struct pci_bus *bus, unsigned int devfn,

	if (pp->cfg0_io_shared) {
		atu.type = PCIE_ATU_TYPE_IO;
		atu.cpu_addr = pp->io_base;
		atu.parent_bus_addr = pp->io_base - pci->parent_bus_offset;
		atu.pci_addr = pp->io_bus_addr;
		atu.size = pp->io_size;

@@ -740,7 +759,7 @@ static int dw_pcie_iatu_setup(struct dw_pcie_rp *pp)

		atu.index = i;
		atu.type = PCIE_ATU_TYPE_MEM;
		atu.cpu_addr = entry->res->start;
		atu.parent_bus_addr = entry->res->start - pci->parent_bus_offset;
		atu.pci_addr = entry->res->start - entry->offset;

		/* Adjust iATU size if MSG TLP region was allocated before */
@@ -762,7 +781,7 @@ static int dw_pcie_iatu_setup(struct dw_pcie_rp *pp)
		if (pci->num_ob_windows > ++i) {
			atu.index = i;
			atu.type = PCIE_ATU_TYPE_IO;
			atu.cpu_addr = pp->io_base;
			atu.parent_bus_addr = pp->io_base - pci->parent_bus_offset;
			atu.pci_addr = pp->io_bus_addr;
			atu.size = pp->io_size;

@@ -906,13 +925,13 @@ static int dw_pcie_pme_turn_off(struct dw_pcie *pci)
	atu.size = resource_size(pci->pp.msg_res);
	atu.index = pci->pp.msg_atu_index;

	atu.cpu_addr = pci->pp.msg_res->start;
	atu.parent_bus_addr = pci->pp.msg_res->start - pci->parent_bus_offset;

	ret = dw_pcie_prog_outbound_atu(pci, &atu);
	if (ret)
		return ret;

	mem = ioremap(atu.cpu_addr, pci->region_align);
	mem = ioremap(pci->pp.msg_res->start, pci->region_align);
	if (!mem)
		return -ENOMEM;

+77 −19
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@
#include <linux/gpio/consumer.h>
#include <linux/ioport.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/pcie-dwc.h>
#include <linux/platform_device.h>
#include <linux/sizes.h>
@@ -516,25 +517,22 @@ static inline u32 dw_pcie_enable_ecrc(u32 val)
int dw_pcie_prog_outbound_atu(struct dw_pcie *pci,
			      const struct dw_pcie_ob_atu_cfg *atu)
{
	u64 cpu_addr = atu->cpu_addr;
	u64 parent_bus_addr = atu->parent_bus_addr;
	u32 retries, val;
	u64 limit_addr;

	if (pci->ops && pci->ops->cpu_addr_fixup)
		cpu_addr = pci->ops->cpu_addr_fixup(pci, cpu_addr);
	limit_addr = parent_bus_addr + atu->size - 1;

	limit_addr = cpu_addr + atu->size - 1;

	if ((limit_addr & ~pci->region_limit) != (cpu_addr & ~pci->region_limit) ||
	    !IS_ALIGNED(cpu_addr, pci->region_align) ||
	if ((limit_addr & ~pci->region_limit) != (parent_bus_addr & ~pci->region_limit) ||
	    !IS_ALIGNED(parent_bus_addr, pci->region_align) ||
	    !IS_ALIGNED(atu->pci_addr, pci->region_align) || !atu->size) {
		return -EINVAL;
	}

	dw_pcie_writel_atu_ob(pci, atu->index, PCIE_ATU_LOWER_BASE,
			      lower_32_bits(cpu_addr));
			      lower_32_bits(parent_bus_addr));
	dw_pcie_writel_atu_ob(pci, atu->index, PCIE_ATU_UPPER_BASE,
			      upper_32_bits(cpu_addr));
			      upper_32_bits(parent_bus_addr));

	dw_pcie_writel_atu_ob(pci, atu->index, PCIE_ATU_LIMIT,
			      lower_32_bits(limit_addr));
@@ -548,7 +546,7 @@ int dw_pcie_prog_outbound_atu(struct dw_pcie *pci,
			      upper_32_bits(atu->pci_addr));

	val = atu->type | atu->routing | PCIE_ATU_FUNC_NUM(atu->func_no);
	if (upper_32_bits(limit_addr) > upper_32_bits(cpu_addr) &&
	if (upper_32_bits(limit_addr) > upper_32_bits(parent_bus_addr) &&
	    dw_pcie_ver_is_ge(pci, 460A))
		val |= PCIE_ATU_INCREASE_REGION_SIZE;
	if (dw_pcie_ver_is(pci, 490A))
@@ -591,13 +589,13 @@ static inline void dw_pcie_writel_atu_ib(struct dw_pcie *pci, u32 index, u32 reg
}

int dw_pcie_prog_inbound_atu(struct dw_pcie *pci, int index, int type,
			     u64 cpu_addr, u64 pci_addr, u64 size)
			     u64 parent_bus_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(parent_bus_addr, pci->region_align) ||
	    !IS_ALIGNED(pci_addr, pci->region_align) || !size) {
		return -EINVAL;
	}
@@ -614,9 +612,9 @@ int dw_pcie_prog_inbound_atu(struct dw_pcie *pci, int index, int type,
				      upper_32_bits(limit_addr));

	dw_pcie_writel_atu_ib(pci, index, PCIE_ATU_LOWER_TARGET,
			      lower_32_bits(cpu_addr));
			      lower_32_bits(parent_bus_addr));
	dw_pcie_writel_atu_ib(pci, index, PCIE_ATU_UPPER_TARGET,
			      upper_32_bits(cpu_addr));
			      upper_32_bits(parent_bus_addr));

	val = type;
	if (upper_32_bits(limit_addr) > upper_32_bits(pci_addr) &&
@@ -643,18 +641,18 @@ int dw_pcie_prog_inbound_atu(struct dw_pcie *pci, int index, int type,
}

int dw_pcie_prog_ep_inbound_atu(struct dw_pcie *pci, u8 func_no, int index,
				int type, u64 cpu_addr, u8 bar, size_t size)
				int type, u64 parent_bus_addr, u8 bar, size_t size)
{
	u32 retries, val;

	if (!IS_ALIGNED(cpu_addr, pci->region_align) ||
	    !IS_ALIGNED(cpu_addr, size))
	if (!IS_ALIGNED(parent_bus_addr, pci->region_align) ||
	    !IS_ALIGNED(parent_bus_addr, size))
		return -EINVAL;

	dw_pcie_writel_atu_ib(pci, index, PCIE_ATU_LOWER_TARGET,
			      lower_32_bits(cpu_addr));
			      lower_32_bits(parent_bus_addr));
	dw_pcie_writel_atu_ib(pci, index, PCIE_ATU_UPPER_TARGET,
			      upper_32_bits(cpu_addr));
			      upper_32_bits(parent_bus_addr));

	dw_pcie_writel_atu_ib(pci, index, PCIE_ATU_REGION_CTRL1, type |
			      PCIE_ATU_FUNC_NUM(func_no));
@@ -1151,3 +1149,63 @@ void dw_pcie_setup(struct dw_pcie *pci)

	dw_pcie_link_set_max_link_width(pci, pci->num_lanes);
}

resource_size_t dw_pcie_parent_bus_offset(struct dw_pcie *pci,
					  const char *reg_name,
					  resource_size_t cpu_phys_addr)
{
	struct device *dev = pci->dev;
	struct device_node *np = dev->of_node;
	int index;
	u64 reg_addr, fixup_addr;
	u64 (*fixup)(struct dw_pcie *pcie, u64 cpu_addr);

	/* Look up reg_name address on parent bus */
	index = of_property_match_string(np, "reg-names", reg_name);

	if (index < 0) {
		dev_err(dev, "No %s in devicetree \"reg\" property\n", reg_name);
		return 0;
	}

	of_property_read_reg(np, index, &reg_addr, NULL);

	fixup = pci->ops ? pci->ops->cpu_addr_fixup : NULL;
	if (fixup) {
		fixup_addr = fixup(pci, cpu_phys_addr);
		if (reg_addr == fixup_addr) {
			dev_info(dev, "%s reg[%d] %#010llx == %#010llx == fixup(cpu %#010llx); %ps is redundant with this devicetree\n",
				 reg_name, index, reg_addr, fixup_addr,
				 (unsigned long long) cpu_phys_addr, fixup);
		} else {
			dev_warn(dev, "%s reg[%d] %#010llx != %#010llx == fixup(cpu %#010llx); devicetree is broken\n",
				 reg_name, index, reg_addr, fixup_addr,
				 (unsigned long long) cpu_phys_addr);
			reg_addr = fixup_addr;
		}

		return cpu_phys_addr - reg_addr;
	}

	if (pci->use_parent_dt_ranges) {

		/*
		 * This platform once had a fixup, presumably because it
		 * translates between CPU and PCI controller addresses.
		 * Log a note if devicetree didn't describe a translation.
		 */
		if (reg_addr == cpu_phys_addr)
			dev_info(dev, "%s reg[%d] %#010llx == cpu %#010llx\n; no fixup was ever needed for this devicetree\n",
				 reg_name, index, reg_addr,
				 (unsigned long long) cpu_phys_addr);
	} else {
		if (reg_addr != cpu_phys_addr) {
			dev_warn(dev, "%s reg[%d] %#010llx != cpu %#010llx; no fixup and devicetree \"ranges\" is broken, assuming no translation\n",
				 reg_name, index, reg_addr,
				 (unsigned long long) cpu_phys_addr);
			return 0;
		}
	}

	return cpu_phys_addr - reg_addr;
}
+21 −3
Original line number Diff line number Diff line
@@ -374,7 +374,7 @@ struct dw_pcie_ob_atu_cfg {
	u8 func_no;
	u8 code;
	u8 routing;
	u64 cpu_addr;
	u64 parent_bus_addr;
	u64 pci_addr;
	u64 size;
};
@@ -481,6 +481,7 @@ struct dw_pcie {
	void __iomem		*atu_base;
	resource_size_t		atu_phys_addr;
	size_t			atu_size;
	resource_size_t		parent_bus_offset;
	u32			num_ib_windows;
	u32			num_ob_windows;
	u32			region_align;
@@ -502,6 +503,19 @@ struct dw_pcie {
	struct gpio_desc		*pe_rst;
	bool			suspended;
	struct debugfs_info	*debugfs;

	/*
	 * If iATU input addresses are offset from CPU physical addresses,
	 * we previously required .cpu_addr_fixup() to convert them.  We
	 * now rely on the devicetree instead.  If .cpu_addr_fixup()
	 * exists, we compare its results with devicetree.
	 *
	 * If .cpu_addr_fixup() does not exist, we assume the offset is
	 * zero and warn if devicetree claims otherwise.  If we know all
	 * devicetrees correctly describe the offset, set
	 * use_parent_dt_ranges to true to avoid this warning.
	 */
	bool			use_parent_dt_ranges;
};

#define to_dw_pcie_from_pp(port) container_of((port), struct dw_pcie, pp)
@@ -529,14 +543,18 @@ int dw_pcie_wait_for_link(struct dw_pcie *pci);
int dw_pcie_prog_outbound_atu(struct dw_pcie *pci,
			      const struct dw_pcie_ob_atu_cfg *atu);
int dw_pcie_prog_inbound_atu(struct dw_pcie *pci, int index, int type,
			     u64 cpu_addr, u64 pci_addr, u64 size);
			     u64 parent_bus_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, size_t size);
				int type, u64 parent_bus_addr,
				u8 bar, size_t size);
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);
int dw_pcie_edma_detect(struct dw_pcie *pci);
void dw_pcie_edma_remove(struct dw_pcie *pci);
resource_size_t dw_pcie_parent_bus_offset(struct dw_pcie *pci,
					  const char *reg_name,
					  resource_size_t cpu_phy_addr);

static inline void dw_pcie_writel_dbi(struct dw_pcie *pci, u32 reg, u32 val)
{
Loading