[PATCH 3/3] pci: pci_mvebu: Define an IO region as well

Phil Sutter phil at nwl.cc
Sun Jan 3 23:06:46 CET 2021


Configure an IO region and window for PNP identical to how MEM region is
set up. Linux does this only if the DT defines a pcie-io-aperture
property for the SOC, but since all supported boards do this should not
be needed.

Signed-off-by: Phil Sutter <phil at nwl.cc>
---
 drivers/pci/pci_mvebu.c | 28 +++++++++++++++++++++++++++-
 1 file changed, 27 insertions(+), 1 deletion(-)

diff --git a/drivers/pci/pci_mvebu.c b/drivers/pci/pci_mvebu.c
index c9afe7515014d..9528e7c40ecfe 100644
--- a/drivers/pci/pci_mvebu.c
+++ b/drivers/pci/pci_mvebu.c
@@ -73,6 +73,7 @@ struct mvebu_pcie {
 	void __iomem *membase;
 	struct resource mem;
 	void __iomem *iobase;
+	struct resource io;
 	u32 port;
 	u32 lane;
 	int devfn;
@@ -81,6 +82,8 @@ struct mvebu_pcie {
 	char name[16];
 	unsigned int mem_target;
 	unsigned int mem_attr;
+	unsigned int io_target;
+	unsigned int io_attr;
 };
 
 /*
@@ -90,6 +93,7 @@ struct mvebu_pcie {
  */
 static void __iomem *mvebu_pcie_membase = (void __iomem *)MBUS_PCI_MEM_BASE;
 #define PCIE_MEM_SIZE	(128 << 20)
+static void __iomem *mvebu_pcie_iobase = (void __iomem *)MBUS_PCI_IO_BASE;
 
 static inline bool mvebu_pcie_link_up(struct mvebu_pcie *pcie)
 {
@@ -306,12 +310,24 @@ static int mvebu_pcie_probe(struct udevice *dev)
 		       (u32)pcie->mem.start, PCIE_MEM_SIZE);
 	}
 
+	pcie->io.start = (u32)mvebu_pcie_iobase;
+	pcie->io.end = pcie->io.start + MBUS_PCI_IO_SIZE - 1;
+	mvebu_pcie_iobase += MBUS_PCI_IO_SIZE;
+
+	if (mvebu_mbus_add_window_by_id(pcie->io_target, pcie->io_attr,
+					(phys_addr_t)pcie->io.start,
+					MBUS_PCI_IO_SIZE)) {
+		printf("PCIe unable to add mbus window for IO at %08x+%08x\n",
+		       (u32)pcie->io.start, MBUS_PCI_IO_SIZE);
+	}
+
 	/* Setup windows and configure host bridge */
 	mvebu_pcie_setup_wins(pcie);
 
 	/* Master + slave enable. */
 	reg = readl(pcie->base + PCIE_CMD_OFF);
 	reg |= PCI_COMMAND_MEMORY;
+	reg |= PCI_COMMAND_IO;
 	reg |= PCI_COMMAND_MASTER;
 	reg |= BIT(10);		/* disable interrupts */
 	writel(reg, pcie->base + PCIE_CMD_OFF);
@@ -323,7 +339,9 @@ static int mvebu_pcie_probe(struct udevice *dev)
 		       0, 0,
 		       gd->ram_size,
 		       PCI_REGION_MEM | PCI_REGION_SYS_MEMORY);
-	hose->region_count = 2;
+	pci_set_region(hose->regions + 2, pcie->io.start,
+		       pcie->io.start, MBUS_PCI_IO_SIZE, PCI_REGION_IO);
+	hose->region_count = 3;
 
 	/* Set BAR0 to internal registers */
 	writel(SOC_REGS_PHY_BASE, pcie->base + PCIE_BAR_LO_OFF(0));
@@ -442,6 +460,14 @@ static int mvebu_pcie_ofdata_to_platdata(struct udevice *dev)
 		goto err;
 	}
 
+	ret = mvebu_get_tgt_attr(dev_ofnode(dev->parent), pcie->devfn,
+				 IORESOURCE_IO,
+				 &pcie->io_target, &pcie->io_attr);
+	if (ret < 0) {
+		printf("%s: cannot get tgt/attr for IO window\n", pcie->name);
+		goto err;
+	}
+
 	/* Parse PCIe controller register base from DT */
 	ret = mvebu_pcie_port_parse_dt(dev_ofnode(dev), pcie);
 	if (ret < 0)
-- 
2.30.0



More information about the U-Boot mailing list