U-Boot Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: "Pali Rohár" <pali@kernel.org>
To: "Stefan Roese" <sr@denx.de>, "Dirk Eibach" <dirk.eibach@gdsys.cc>,
	"Mario Six" <mario.six@gdsys.cc>,
	"Marek Behún" <marek.behun@nic.cz>,
	"Chris Packham" <judge.packham@gmail.com>
Cc: u-boot@lists.denx.de
Subject: [PATCH u-boot-marvell 3/9] pci: pci_mvebu: Fix PCIe MEM and IO resources assignment and mbus mapping
Date: Tue, 21 Dec 2021 12:20:13 +0100	[thread overview]
Message-ID: <20211221112019.15088-4-pali@kernel.org> (raw)
In-Reply-To: <20211221112019.15088-1-pali@kernel.org>

Do not call pci_set_region() for resources which were not properly mapped.
This prevents U-Boot to access unmapped memory space.

Update MBUS_PCI_MEM_SIZE and MBUS_PCI_IO_SIZE macros to cover all PCIe MEM
and IO ranges. Previously these macros covered only address ranges for the
first PCIe port. Between MBUS_PCI_IO_BASE and MBUS_PCI_MEM_BASE there is
space for six 128 MB long address ranges. So set MBUS_PCI_MEM_SIZE to value
of 6*128 MB. Similarly set MBUS_PCI_IO_SIZE to 6*64 KB.

Function resource_size() returns zero when start address is 0 and end
address is -1. So set invalid resources to these values to indicate that
resource has no mapping.

Split global PCIe MEM and IO resources (defined by MBUS_PCI_*_* macros)
into PCIe ports in mvebu_pcie_bind() function which allocates per-port
based struct mvebu_pcie, instead of using global state variables
mvebu_pcie_membase and mvebu_pcie_iobase. This makes pci_mvebu.c driver
independent of global static variables (which store the state of
allocation) and allows to bind and unbind the driver more times.

Signed-off-by: Pali Rohár <pali@kernel.org>
Signed-off-by: Marek Behún <marek.behun@nic.cz>
---
 arch/arm/mach-mvebu/include/mach/cpu.h |  5 +-
 drivers/pci/pci_mvebu.c                | 84 ++++++++++++++++++--------
 2 files changed, 62 insertions(+), 27 deletions(-)

diff --git a/arch/arm/mach-mvebu/include/mach/cpu.h b/arch/arm/mach-mvebu/include/mach/cpu.h
index a7a62c7e7d53..b99d86a87a03 100644
--- a/arch/arm/mach-mvebu/include/mach/cpu.h
+++ b/arch/arm/mach-mvebu/include/mach/cpu.h
@@ -74,10 +74,11 @@ enum {
 /*
  * Default Device Address MAP BAR values
  */
+#define MBUS_PCI_MAX_PORTS	6
 #define MBUS_PCI_MEM_BASE	MVEBU_SDRAM_SIZE_MAX
-#define MBUS_PCI_MEM_SIZE	(128 << 20)
+#define MBUS_PCI_MEM_SIZE	((MBUS_PCI_MAX_PORTS * 128) << 20)
 #define MBUS_PCI_IO_BASE	0xF1100000
-#define MBUS_PCI_IO_SIZE	(64 << 10)
+#define MBUS_PCI_IO_SIZE	((MBUS_PCI_MAX_PORTS * 64) << 10)
 #define MBUS_SPI_BASE		0xF4000000
 #define MBUS_SPI_SIZE		(8 << 20)
 #define MBUS_DFX_BASE		0xF6000000
diff --git a/drivers/pci/pci_mvebu.c b/drivers/pci/pci_mvebu.c
index 9248cbc294ce..eaaa6cbe326d 100644
--- a/drivers/pci/pci_mvebu.c
+++ b/drivers/pci/pci_mvebu.c
@@ -25,6 +25,7 @@
 #include <linux/errno.h>
 #include <linux/ioport.h>
 #include <linux/mbus.h>
+#include <linux/sizes.h>
 
 /* PCIe unit register offsets */
 #define SELECT(x, n)			((x >> n) & 1UL)
@@ -89,14 +90,6 @@ struct mvebu_pcie {
 	u32 cfgcache[(0x3c - 0x10) / 4];
 };
 
-/*
- * MVEBU PCIe controller needs MEMORY and I/O BARs to be mapped
- * into SoCs address space. Each controller will map 128M of MEM
- * and 64K of I/O space when registered.
- */
-static void __iomem *mvebu_pcie_membase = (void __iomem *)MBUS_PCI_MEM_BASE;
-static void __iomem *mvebu_pcie_iobase = (void __iomem *)MBUS_PCI_IO_BASE;
-
 static inline bool mvebu_pcie_link_up(struct mvebu_pcie *pcie)
 {
 	u32 val;
@@ -442,26 +435,24 @@ static int mvebu_pcie_probe(struct udevice *dev)
 	mvebu_pcie_set_local_bus_nr(pcie, 0);
 	mvebu_pcie_set_local_dev_nr(pcie, 1);
 
-	pcie->mem.start = (u32)mvebu_pcie_membase;
-	pcie->mem.end = pcie->mem.start + MBUS_PCI_MEM_SIZE - 1;
-	mvebu_pcie_membase += MBUS_PCI_MEM_SIZE;
-
-	if (mvebu_mbus_add_window_by_id(pcie->mem_target, pcie->mem_attr,
+	if (resource_size(&pcie->mem) &&
+	    mvebu_mbus_add_window_by_id(pcie->mem_target, pcie->mem_attr,
 					(phys_addr_t)pcie->mem.start,
 					resource_size(&pcie->mem))) {
 		printf("PCIe unable to add mbus window for mem at %08x+%08x\n",
 		       (u32)pcie->mem.start, (unsigned)resource_size(&pcie->mem));
+		pcie->mem.start = 0;
+		pcie->mem.end = -1;
 	}
 
-	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,
+	if (resource_size(&pcie->io) &&
+	    mvebu_mbus_add_window_by_id(pcie->io_target, pcie->io_attr,
 					(phys_addr_t)pcie->io.start,
 					resource_size(&pcie->io))) {
 		printf("PCIe unable to add mbus window for IO at %08x+%08x\n",
 		       (u32)pcie->io.start, (unsigned)resource_size(&pcie->io));
+		pcie->io.start = 0;
+		pcie->io.end = -1;
 	}
 
 	/* Setup windows and configure host bridge */
@@ -470,13 +461,23 @@ static int mvebu_pcie_probe(struct udevice *dev)
 	/* PCI memory space */
 	pci_set_region(hose->regions + 0, pcie->mem.start,
 		       pcie->mem.start, resource_size(&pcie->mem), PCI_REGION_MEM);
-	pci_set_region(hose->regions + 1,
-		       0, 0,
-		       gd->ram_size,
-		       PCI_REGION_MEM | PCI_REGION_SYS_MEMORY);
-	pci_set_region(hose->regions + 2, pcie->io.start,
-		       pcie->io.start, resource_size(&pcie->io), PCI_REGION_IO);
-	hose->region_count = 3;
+	hose->region_count = 1;
+
+	if (resource_size(&pcie->mem)) {
+		pci_set_region(hose->regions + hose->region_count,
+			       pcie->mem.start, pcie->mem.start,
+			       resource_size(&pcie->mem),
+			       PCI_REGION_MEM);
+		hose->region_count++;
+	}
+
+	if (resource_size(&pcie->io)) {
+		pci_set_region(hose->regions + hose->region_count,
+			       pcie->io.start, pcie->io.start,
+			       resource_size(&pcie->io),
+			       PCI_REGION_IO);
+		hose->region_count++;
+	}
 
 	/* PCI Bridge support 32-bit I/O and 64-bit prefetch mem addressing */
 	pcie->cfgcache[(PCI_IO_BASE - 0x10) / 4] =
@@ -637,6 +638,8 @@ static int mvebu_pcie_bind(struct udevice *parent)
 	struct mvebu_pcie *pcie;
 	struct uclass_driver *drv;
 	struct udevice *dev;
+	struct resource mem;
+	struct resource io;
 	ofnode subnode;
 
 	/* Lookup pci driver */
@@ -646,6 +649,11 @@ static int mvebu_pcie_bind(struct udevice *parent)
 		return -ENOENT;
 	}
 
+	mem.start = MBUS_PCI_MEM_BASE;
+	mem.end = MBUS_PCI_MEM_BASE + MBUS_PCI_MEM_SIZE - 1;
+	io.start = MBUS_PCI_IO_BASE;
+	io.end = MBUS_PCI_IO_BASE + MBUS_PCI_IO_SIZE - 1;
+
 	ofnode_for_each_subnode(subnode, dev_ofnode(parent)) {
 		if (!ofnode_is_available(subnode))
 			continue;
@@ -654,6 +662,32 @@ static int mvebu_pcie_bind(struct udevice *parent)
 		if (!pcie)
 			return -ENOMEM;
 
+		/*
+		 * MVEBU PCIe controller needs MEMORY and I/O BARs to be mapped
+		 * into SoCs address space. Each controller will map 128M of MEM
+		 * and 64K of I/O space when registered.
+		 */
+
+		if (resource_size(&mem) >= SZ_128M) {
+			pcie->mem.start = mem.start;
+			pcie->mem.end = mem.start + SZ_128M - 1;
+			mem.start += SZ_128M;
+		} else {
+			printf("PCIe unable to assign mbus window for mem\n");
+			pcie->mem.start = 0;
+			pcie->mem.end = -1;
+		}
+
+		if (resource_size(&io) >= SZ_64K) {
+			pcie->io.start = io.start;
+			pcie->io.end = io.start + SZ_64K - 1;
+			io.start += SZ_64K;
+		} else {
+			printf("PCIe unable to assign mbus window for io\n");
+			pcie->io.start = 0;
+			pcie->io.end = -1;
+		}
+
 		/* Create child device UCLASS_PCI and bind it */
 		device_bind(parent, &pcie_mvebu_drv, pcie->name, pcie, subnode,
 			    &dev);
-- 
2.20.1


  parent reply	other threads:[~2021-12-21 11:21 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-12-21 11:20 [PATCH u-boot-marvell 0/9] mvebu: Move PCIe code from serdes to PCIe driver Pali Rohár
2021-12-21 11:20 ` [PATCH u-boot-marvell 1/9] arm: mvebu: Convert board_pex_config() to CONFIG_SPL_BOARD_INIT Pali Rohár
2021-12-21 11:20 ` [PATCH u-boot-marvell 2/9] board: gdsys: a38x: Enable PCIe link 2 in spl_board_init() Pali Rohár
2021-12-21 11:20 ` Pali Rohár [this message]
2021-12-21 11:20 ` [PATCH u-boot-marvell 4/9] pci: pci_mvebu: Inline mvebu_pcie_port_parse_dt() function Pali Rohár
2021-12-21 11:20 ` [PATCH u-boot-marvell 5/9] pci: pci_mvebu: Remove dependency on SOC_REGS_PHY_BASE macro Pali Rohár
2021-12-21 11:20 ` [PATCH u-boot-marvell 6/9] pci: pci_mvebu: Split initialization of PCIe ports into 3 phases Pali Rohár
2021-12-21 11:20 ` [PATCH u-boot-marvell 7/9] pci: pci_mvebu: Wait 100ms for Link Up in mvebu_pcie_probe() Pali Rohár
2021-12-21 11:20 ` [PATCH u-boot-marvell 8/9] arm: mvebu: Implement simple mvebu-reset driver for enabling/disabling PCIe ports Pali Rohár
2021-12-21 11:20 ` [PATCH u-boot-marvell 9/9] arm: mvebu: a38x: serdes: Move non-serdes PCIe code to pci_mvebu.c Pali Rohár
2022-01-04 22:08 ` [PATCH u-boot-marvell 0/9] mvebu: Move PCIe code from serdes to PCIe driver Pali Rohár
2022-01-14 15:33 ` Stefan Roese

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20211221112019.15088-4-pali@kernel.org \
    --to=pali@kernel.org \
    --cc=dirk.eibach@gdsys.cc \
    --cc=judge.packham@gmail.com \
    --cc=marek.behun@nic.cz \
    --cc=mario.six@gdsys.cc \
    --cc=sr@denx.de \
    --cc=u-boot@lists.denx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox