Patchwork [U-Boot,5/6] powerpc/p5040ds: add per pci endpoint liodn offset list

login
register
mail settings
Submitter Timur Tabi
Date Oct. 1, 2012, 2:06 p.m.
Message ID <1349100403-10728-5-git-send-email-timur@freescale.com>
Download mbox | patch
Permalink /patch/188299/
State Superseded
Delegated to: Andy Fleming
Headers show

Comments

Timur Tabi - Oct. 1, 2012, 2:06 p.m.
From: Laurentiu Tudor <Laurentiu.Tudor@freescale.com>

Add a new device tree property named "fsl,liodn-offset-list"
holding a list of per pci endpoint permitted liodn offsets.
This property is useful in virtualization scenarios
that implement per pci endpoint partitioning.
The final liodn of a partitioned pci endpoint is
calculated by the hardware, by adding these offsets
to pci controller's base liodn, stored in the
"fsl,liodn" property of its node.
The liodn offsets are interleaved to get better cache
utilization. As an example, given 3 pci controllers,
the following liodns are generated for the pci endpoints:
    pci0: 193 256 259 262 265 268 271 274 277
    pci1: 194 257 260 263 266 269 272 275 278
    pci2: 195 258 261 264 267 270 273 276 279

Signed-off-by: Laurentiu Tudor <Laurentiu.Tudor@freescale.com>
---
 arch/powerpc/cpu/mpc85xx/liodn.c |   52 ++++++++++++++++++++++++++++++++++++++
 1 files changed, 52 insertions(+), 0 deletions(-)

Patch

diff --git a/arch/powerpc/cpu/mpc85xx/liodn.c b/arch/powerpc/cpu/mpc85xx/liodn.c
index 11881c9..97d6904 100644
--- a/arch/powerpc/cpu/mpc85xx/liodn.c
+++ b/arch/powerpc/cpu/mpc85xx/liodn.c
@@ -248,6 +248,56 @@  static void fdt_fixup_srio_liodn(void *blob, struct srio_liodn_id_table *tbl)
 	}
 }
 
+#define CONFIG_SYS_MAX_PCI_EPS		8
+#define CONFIG_SYS_PCI_EP_LIODN_START	256
+
+static void fdt_fixup_pci_liodn_offsets(void *fdt, const char *compat)
+{
+	int off, pci_idx = 0, pci_cnt = 0, i, rc;
+	const uint32_t *base_liodn;
+	uint32_t liodn_offs[CONFIG_SYS_MAX_PCI_EPS + 1] = { 0 };
+
+	/*
+	 * Count the number of pci nodes.
+	 * It's needed later when the interleaved liodn offsets are generated.
+	 */
+	off = fdt_node_offset_by_compatible(fdt, -1, compat);
+	while (off != -FDT_ERR_NOTFOUND) {
+		pci_cnt++;
+		off = fdt_node_offset_by_compatible(fdt, off, compat);
+	}
+
+	for (off = fdt_node_offset_by_compatible(fdt, -1, compat);
+	     off != -FDT_ERR_NOTFOUND;
+	     off = fdt_node_offset_by_compatible(fdt, off, compat)) {
+		base_liodn = fdt_getprop(fdt, off, "fsl,liodn", &rc);
+		if (!base_liodn) {
+			char path[64];
+
+			if (fdt_get_path(fdt, off, path, sizeof(path)) < 0)
+				strcpy(path, "(unknown)");
+			printf("WARNING Could not get liodn of node %s: %s\n",
+			       path, fdt_strerror(rc));
+			continue;
+		}
+		for (i = 0; i < CONFIG_SYS_MAX_PCI_EPS; i++)
+			liodn_offs[i + 1] = CONFIG_SYS_PCI_EP_LIODN_START +
+					i * pci_cnt + pci_idx - *base_liodn;
+		rc = fdt_setprop(fdt, off, "fsl,liodn-offset-list",
+				 liodn_offs, sizeof(liodn_offs));
+		if (rc) {
+			char path[64];
+
+			if (fdt_get_path(fdt, off, path, sizeof(path)) < 0)
+				strcpy(path, "(unknown)");
+			printf("WARNING Unable to set fsl,liodn-offset-list for "
+			       "node %s: %s\n", path, fdt_strerror(rc));
+			continue;
+		}
+		pci_idx++;
+	}
+}
+
 static void fdt_fixup_liodn_tbl(void *blob, struct liodn_id_table *tbl, int sz)
 {
 	int i;
@@ -295,4 +345,6 @@  void fdt_fixup_liodn(void *blob)
 #ifdef CONFIG_SYS_DPAA_RMAN
 	fdt_fixup_liodn_tbl(blob, rman_liodn_tbl, rman_liodn_tbl_sz);
 #endif
+
+	fdt_fixup_pci_liodn_offsets(blob, "fsl,qoriq-pcie-v2.4");
 }