Skip to contentSkip to conversation

armv8: ls2080a: remove obsolete stream ID partitioning support

PATCH RESEND Superseded Stuart Yoder 2 participants 8 messages Mar 9, 2016 1 message not in the archive

Subsystems (2)

v5 of 6 Superseded Latest is v6 →

lore
Share & tools
lore

A message that is not in the archive (sent off-list or not yet received): [email protected]

#1 lore raw

PATCH RESEND v5 1/7 armv8: ls2080a: remove obsolete stream ID partitioning support

From: Stuart Yoder <[email protected]>

Remove stream ID partitioning support that has been made obsolete by upstream device tree bindings that specify how representing how PCI requester IDs are mapped to MSI specifiers and SMMU stream IDs.

---
-v5: no change

 arch/arm/cpu/armv8/fsl-layerscape/fdt.c |  113 -------------------------------
 drivers/pci/pcie_layerscape.c           |   70 -------------------
 2 files changed, 183 deletions(-)
arch/arm/cpu/armv8/fsl-layerscape/fdt.c +0 -113
index 4e4861d..7a64f41 100644
@@ -70,115 +70,6 @@ void ft_fixup_cpu(void *blob)
 }
 #endif
 
-/*
- * the burden is on the the caller to not request a count
- * exceeding the bounds of the stream_ids[] array
- */
-void alloc_stream_ids(int start_id, int count, u32 *stream_ids, int max_cnt)
-{
-	int i;
-
-	if (count > max_cnt) {
-		printf("\n%s: ERROR: max per-device stream ID count exceed\n",
-		       __func__);
-		return;
-	}
-
-	for (i = 0; i < count; i++)
-		stream_ids[i] = start_id++;
-}
-
-/*
- * This function updates the mmu-masters property on the SMMU
- * node as per the SMMU binding-- phandle and list of stream IDs
- * for each MMU master.
- */
-void append_mmu_masters(void *blob, const char *smmu_path,
-			const char *master_name, u32 *stream_ids, int count)
-{
-	u32 phandle;
-	int smmu_nodeoffset;
-	int master_nodeoffset;
-	int i;
-
-	/* get phandle of mmu master device */
-	master_nodeoffset = fdt_path_offset(blob, master_name);
-	if (master_nodeoffset < 0) {
-		printf("\n%s: ERROR: master not found\n", __func__);
-		return;
-	}
-	phandle = fdt_get_phandle(blob, master_nodeoffset);
-	if (!phandle) { /* if master has no phandle, create one */
-		phandle = fdt_create_phandle(blob, master_nodeoffset);
-		if (!phandle) {
-			printf("\n%s: ERROR: unable to create phandle\n",
-			       __func__);
-			return;
-		}
-	}
-
-	/* append it to mmu-masters */
-	smmu_nodeoffset = fdt_path_offset(blob, smmu_path);
-	if (fdt_appendprop_u32(blob, smmu_nodeoffset, "mmu-masters",
-			       phandle) < 0) {
-		printf("\n%s: ERROR: unable to update SMMU node\n", __func__);
-		return;
-	}
-
-	/* for each stream ID, append to mmu-masters */
-	for (i = 0; i < count; i++) {
-		fdt_appendprop_u32(blob, smmu_nodeoffset, "mmu-masters",
-				   stream_ids[i]);
-	}
-
-	/* fix up #stream-id-cells with stream ID count */
-	if (fdt_setprop_u32(blob, master_nodeoffset, "#stream-id-cells",
-			    count) < 0)
-		printf("\n%s: ERROR: unable to update #stream-id-cells\n",
-		       __func__);
-}
-
-
-/*
- * The info below summarizes how streamID partitioning works
- * for ls2080a and how it is conveyed to the OS via the device tree.
- *
- *  -non-PCI legacy, platform devices (USB, SD/MMC, SATA, DMA)
- *     -all legacy devices get a unique ICID assigned and programmed in
- *      their AMQR registers by u-boot
- *     -u-boot updates the hardware device tree with streamID properties
- *      for each platform/legacy device (smmu-masters property)
- *
- *  -PCIe
- *     -for each PCI controller that is active (as per RCW settings),
- *      u-boot will allocate a range of ICID and convey that to Linux via
- *      the device tree (smmu-masters property)
- *
- *  -DPAA2
- *     -u-boot will allocate a range of ICIDs to be used by the Management
- *      Complex for containers and will set these values in the MC DPC image.
- *     -the MC is responsible for allocating and setting up ICIDs
- *      for all DPAA2 devices.
- *
- */
-#ifdef CONFIG_FSL_LSCH3
-static void fdt_fixup_smmu(void *blob)
-{
-	int nodeoffset;
-
-	nodeoffset = fdt_path_offset(blob, "/iommu at 5000000");
-	if (nodeoffset < 0) {
-		printf("\n%s: WARNING: no SMMU node found\n", __func__);
-		return;
-	}
-
-	/* fixup for all PCI controllers */
-#ifdef CONFIG_PCI
-	fdt_fixup_smmu_pcie(blob);
-#endif
-}
-#endif
-
 void ft_cpu_setup(void *blob, bd_t *bd)
 {
 #ifdef CONFIG_MP
@@ -200,8 +91,4 @@ void ft_cpu_setup(void *blob, bd_t *bd)
 #ifdef CONFIG_FSL_ESDHC
 	fdt_fixup_esdhc(blob, bd);
 #endif
-
-#ifdef CONFIG_FSL_LSCH3
-	fdt_fixup_smmu(blob);
-#endif
 }
drivers/pci/pcie_layerscape.c +0 -70

73 lines not on this page · raw message

Signature · 1 line
1.7.9.5
#2 lore raw

PATCH RESEND v5 2/7 armv8: ls2080a: update stream ID partitioning info

In reply to a message not in the archive

From: Stuart Yoder <[email protected]>

-update comments around how stream IDs are partitioned

-stream IDs allocated to PCI are no longer divided up by
controller, but are instead a contiguous range

---
-v5: no change

 .../asm/arch-fsl-layerscape/ls2080a_stream_id.h    |   55 ++++++++++++--------
 1 file changed, 34 insertions(+), 21 deletions(-)
arch/arm/include/asm/arch-fsl-layerscape/ls2080a_stream_id.h +34 -21
index 954104b..ee28323 100644
@@ -7,28 +7,48 @@
 #ifndef __FSL_STREAM_ID_H
 #define __FSL_STREAM_ID_H
 
-/* Stream IDs on ls2080a devices are not hardwired and are
+/*
+ * Stream IDs on ls2080a devices are not hardwired and are
  * programmed by sw.  There are a limited number of stream IDs
  * available, and the partitioning of them is scenario dependent.
  * This header defines the partitioning between legacy, PCI,
  * and DPAA2 devices.
  *
- * This partitiong can be customized in this file depending
- * on the specific hardware config-- e.g. perhaps not all
- * PEX controllers are in use.
+ * This partitioning can be customized in this file depending
+ * on the specific hardware config:
+ *
+ *  -non-PCI legacy, platform devices (USB, SD/MMC, SATA, DMA)
+ *     -all legacy devices get a unique stream ID assigned and programmed in
+ *      their AMQR registers by u-boot
+ *
+ *  -PCIe
+ *     -there is a range of stream IDs set aside for PCI in this
+ *      file.  U-boot will scan the PCI bus and for each device discovered:
+ *         -allocate a streamID
+ *         -set a PEXn LUT table entry mapping 'requester ID' to 'stream ID'
+ *         -set a msi-map entry in the PEXn controller node in the
+ *          device tree (see Documentation/devicetree/bindings/pci/pci-msi.txt
+ *          for more info on the msi-map definition)
  *
- * On LS2080 stream IDs are programmed in AMQ registers (32-bits) for
+ *  -DPAA2
+ *     -u-boot will allocate a range of stream IDs to be used by the Management
+ *      Complex for containers and will set these values in the MC DPC image.
+ *     -the MC is responsible for allocating and setting up 'isolation context
+ *      IDs (ICIDs) based on the allocated stream IDs for all DPAA2 devices.
+ *
+ * On ls2080a SoCs stream IDs are programmed in AMQ registers (32-bits) for
  * each of the different bus masters.  The relationship between
  * the AMQ registers and stream IDs is defined in the table below:
  *          AMQ bit    streamID bit
  *      ---------------------------
- *           PL[18]         9
- *          BMT[17]         8
- *           VA[16]         7
- *             [15]         -
- *         ICID[14:7]       -
- *         ICID[6:0]        6-0
+ *           PL[18]         9        // privilege bit
+ *          BMT[17]         8        // bypass translation
+ *           VA[16]         7        // reserved
+ *             [15]         -        // unused
+ *         ICID[14:7]       -        // unused
+ *         ICID[6:0]        6-0      // isolation context id
  *     ----------------------------
+ *
  */
 
 #define AMQ_PL_MASK			(0x1 << 18)   /* priviledge bit */
@@ -46,16 +66,9 @@
 #define FSL_SATA2_STREAM_ID		5
 #define FSL_DMA_STREAM_ID		6
 
-/* PCI - programmed in PEXn_LUT by OS */
-/*   4 IDs per controller */
-#define FSL_PEX1_STREAM_ID_START	7
-#define FSL_PEX1_STREAM_ID_END		10
-#define FSL_PEX2_STREAM_ID_START	11
-#define FSL_PEX2_STREAM_ID_END		14
-#define FSL_PEX3_STREAM_ID_START	15
-#define FSL_PEX3_STREAM_ID_END		18
-#define FSL_PEX4_STREAM_ID_START	19
-#define FSL_PEX4_STREAM_ID_END		22
+/* PCI - programmed in PEXn_LUT */
+#define FSL_PEX_STREAM_ID_START		7
+#define FSL_PEX_STREAM_ID_END		22
 
 /* DPAA2 - set in MC DPC and alloced by MC */
 #define FSL_DPAA2_STREAM_ID_START	23
Signature · 1 line
1.7.9.5
#3 lore raw

PATCH RESEND v5 4/7 pci/layerscape: add support for LUT

In reply to a message not in the archive

From: Stuart Yoder <[email protected]>

The per-PCI controller LUT (Look-Up-Table) is a 32-entry table that maps PCI requester IDs (bus/dev/fun) to a stream ID.

This patch implements infrastructure to enable LUT initialization:
-define registers offsets
-add an index to 'struct ls_pcie' to track next available slot in LUT -add function to allocate the next available entry index -add function to program a LUT entry

---
-v5: check CONFIG_FSL_LSCH3 instead of SoC specific defines

 .../include/asm/arch-fsl-layerscape/immap_lsch3.h  |    4 +++
 drivers/pci/pcie_layerscape.c                      |   30 ++++++++++++++++++++
 2 files changed, 34 insertions(+)
arch/arm/include/asm/arch-fsl-layerscape/immap_lsch3.h +4 -0
index 91f3ce8..d04e336 100644
@@ -86,6 +86,10 @@
 #define PCIE_LUT_BASE				0x80000
 #define PCIE_LUT_LCTRL0				0x7F8
 #define PCIE_LUT_DBG				0x7FC
+#define PCIE_LUT_UDR(n)         (0x800 + (n) * 8)
+#define PCIE_LUT_LDR(n)         (0x804 + (n) * 8)
+#define PCIE_LUT_ENABLE         (1 << 31)
+#define PCIE_LUT_ENTRY_COUNT    32
 
 /* Device Configuration */
 #define DCFG_BASE		0x01e00000
drivers/pci/pcie_layerscape.c +30 -0
index bb29222..5cc6855 100644
@@ -93,6 +93,7 @@ struct ls_pcie {
 	void __iomem *dbi;
 	void __iomem *va_cfg0;
 	void __iomem *va_cfg1;
+	int next_lut_index;
 	struct pci_controller hose;
 };
 
@@ -482,6 +483,34 @@ static void ls_pcie_setup_ep(struct ls_pcie *pcie, struct ls_pcie_info *info)
 	}
 }
 
+#ifdef CONFIG_FSL_LSCH3
+/*
+ * Return next available LUT index.
+ */
+static int ls_pcie_next_lut_index(struct ls_pcie *pcie)
+{
+	if (pcie->next_lut_index < PCIE_LUT_ENTRY_COUNT)
+		return pcie->next_lut_index++;
+	else
+		return -1;  /* LUT is full */
+}
+
+/*
+ * Program a single LUT entry
+ */
+static void ls_pcie_lut_set_mapping(struct ls_pcie *pcie, int index, u32 devid,
+			     u32 streamid)
+{
+	void __iomem *lut;
+
+	lut = pcie->dbi + PCIE_LUT_BASE;
+
+	/* leave mask as all zeroes, want to match all bits */
+	writel((devid << 16), lut + PCIE_LUT_UDR(index));
+	writel(streamid | PCIE_LUT_ENABLE, lut + PCIE_LUT_LDR(index));
+}
+#endif
+
 int ls_pcie_init_ctrl(int busno, enum srds_prtcl dev, struct ls_pcie_info *info)
 {
 	struct ls_pcie *pcie;
@@ -513,6 +542,7 @@ int ls_pcie_init_ctrl(int busno, enum srds_prtcl dev, struct ls_pcie_info *info)
 	pcie->va_cfg1 = map_physmem(info->cfg1_phys,
 				    info->cfg1_size,
 				    MAP_NOCACHE);
+	pcie->next_lut_index = 0;
 
 	/* outbound memory */
 	pci_set_region(&hose->regions[0],
Signature · 1 line
1.7.9.5
#4 lore raw

PATCH RESEND v5 4/7 pci/layerscape: add support for LUT

Quoted 83 lines · Stuart Yoder

From: Stuart Yoder <[email protected]>

The per-PCI controller LUT (Look-Up-Table) is a 32-entry table that maps PCI requester IDs (bus/dev/fun) to a stream ID.

This patch implements infrastructure to enable LUT initialization:
-define registers offsets
-add an index to 'struct ls_pcie' to track next available slot in LUT -add function to allocate the next available entry index -add function to program a LUT entry

---

(quoted diff) +0 -1
-v5: check CONFIG_FSL_LSCH3 instead of SoC specific defines
 
 .../include/asm/arch-fsl-layerscape/immap_lsch3.h  |    4 +++
 drivers/pci/pcie_layerscape.c                      |   30 ++++++++++++++++++++
 2 files changed, 34 insertions(+)
arch/arm/include/asm/arch-fsl-layerscape/immap_lsch3.h +4 -0
index 91f3ce8..d04e336 100644
@@ -86,6 +86,10 @@
 #define PCIE_LUT_BASE				0x80000
 #define PCIE_LUT_LCTRL0				0x7F8
 #define PCIE_LUT_DBG				0x7FC
+#define PCIE_LUT_UDR(n)         (0x800 + (n) * 8)
+#define PCIE_LUT_LDR(n)         (0x804 + (n) * 8)
+#define PCIE_LUT_ENABLE         (1 << 31)
+#define PCIE_LUT_ENTRY_COUNT    32
 
 /* Device Configuration */
 #define DCFG_BASE		0x01e00000
drivers/pci/pcie_layerscape.c +29 -0
index bb29222..5cc6855 100644
@@ -93,6 +93,7 @@ struct ls_pcie {
 	void __iomem *dbi;
 	void __iomem *va_cfg0;
 	void __iomem *va_cfg1;
+	int next_lut_index;
 	struct pci_controller hose;
 };
 
@@ -482,6 +483,34 @@ static void ls_pcie_setup_ep(struct ls_pcie *pcie, struct ls_pcie_info *info)
 	}
 }
 
+#ifdef CONFIG_FSL_LSCH3
+/*
+ * Return next available LUT index.
+ */
+static int ls_pcie_next_lut_index(struct ls_pcie *pcie)
+{
+	if (pcie->next_lut_index < PCIE_LUT_ENTRY_COUNT)
+		return pcie->next_lut_index++;
+	else
+		return -1;  /* LUT is full */
+}
+
+/*
+ * Program a single LUT entry
+ */
+static void ls_pcie_lut_set_mapping(struct ls_pcie *pcie, int index, u32 devid,
+			     u32 streamid)
+{
+	void __iomem *lut;
+
+	lut = pcie->dbi + PCIE_LUT_BASE;
+
+	/* leave mask as all zeroes, want to match all bits */
+	writel((devid << 16), lut + PCIE_LUT_UDR(index));
+	writel(streamid | PCIE_LUT_ENABLE, lut + PCIE_LUT_LDR(index));
+}
+#endif
+
 int ls_pcie_init_ctrl(int busno, enum srds_prtcl dev, struct ls_pcie_info *info)
 {
 	struct ls_pcie *pcie;

drivers/pci/pcie_layerscape.c int ls_pcie_init_ctrl(int busno, enum srds_prtcl dev, struct ls_pcie_info *info) · line 548

Quoted 7 lines
drivers/pci/pcie_layerscape.c +1 -0
@@ -513,6 +542,7 @@ int ls_pcie_init_ctrl(int busno, enum srds_prtcl dev, struct ls_pcie_info *info)
 	pcie->va_cfg1 = map_physmem(info->cfg1_phys,
 				    info->cfg1_size,
 				    MAP_NOCACHE);
+	pcie->next_lut_index = 0;
 
 	/* outbound memory */
 	pci_set_region(&hose->regions[0],

Stuart,

This patch breaks git bisect. Please rearrange your changes.
warning: ?ls_pcie_next_lut_index? defined but not used [-Wunused-function] static int ls_pcie_next_lut_index(struct ls_pcie *pcie)

            ^
 warning: ?ls_pcie_lut_set_mapping? defined but not used [-Wunused-function]
 static void ls_pcie_lut_set_mapping(struct ls_pcie *pcie, int index, u32 devid,
             ^

York

#5 lore raw

PATCH RESEND v5 4/7 pci/layerscape: add support for LUT

Quoted 106 lines

-----Original Message-----
From: york sun
Sent: Wednesday, March 09, 2016 12:01 PM
To: Stuart Yoder <[email protected]>; u-boot at lists.denx.de
Cc: Prabhakar Kushwaha <[email protected]>; Yang-Leo Li <[email protected]>
Subject: Re: [RESEND PATCH 4/7 v5] pci/layerscape: add support for LUT

Review

Quoted 20 lines · Stuart Yoder

From: Stuart Yoder <[email protected]>

The per-PCI controller LUT (Look-Up-Table) is a 32-entry table that maps PCI requester IDs (bus/dev/fun) to a stream ID.

This patch implements infrastructure to enable LUT initialization:
-define registers offsets
-add an index to 'struct ls_pcie' to track next available slot in LUT -add function to allocate the next available entry index -add function to program a LUT entry

---

(quoted diff) +0 -1
-v5: check CONFIG_FSL_LSCH3 instead of SoC specific defines
 
 .../include/asm/arch-fsl-layerscape/immap_lsch3.h  |    4 +++
 drivers/pci/pcie_layerscape.c                      |   30 ++++++++++++++++++++
 2 files changed, 34 insertions(+)
(quoted diff) +0 -0

b/arch/arm/include/asm/arch-fsl-layerscape/immap_lsch3.h

drivers/pci/pcie_layerscape.c static void ls_pcie_setup_ep(struct ls_pcie *pcie, struct

Quoted 27 lines

index 91f3ce8..d04e336 100644

arch/arm/include/asm/arch-fsl-layerscape/immap_lsch3.h +4 -0
@@ -86,6 +86,10 @@
 #define PCIE_LUT_BASE				0x80000
 #define PCIE_LUT_LCTRL0				0x7F8
 #define PCIE_LUT_DBG				0x7FC
+#define PCIE_LUT_UDR(n)         (0x800 + (n) * 8)
+#define PCIE_LUT_LDR(n)         (0x804 + (n) * 8)
+#define PCIE_LUT_ENABLE         (1 << 31)
+#define PCIE_LUT_ENTRY_COUNT    32
 
 /* Device Configuration */
 #define DCFG_BASE		0x01e00000
drivers/pci/pcie_layerscape.c +1 -0
index bb29222..5cc6855 100644
@@ -93,6 +93,7 @@ struct ls_pcie {
 	void __iomem *dbi;
 	void __iomem *va_cfg0;
 	void __iomem *va_cfg1;
+	int next_lut_index;
 	struct pci_controller hose;
 };
 
@@ -482,6 +483,34 @@ static void ls_pcie_setup_ep(struct ls_pcie *pcie, struct

ls_pcie_info *info)

drivers/pci/pcie_layerscape.c int ls_pcie_init_ctrl(int busno, enum srds_prtcl dev, struct

Quoted 35 lines
drivers/pci/pcie_layerscape.c +28 -0
 	}
 }
 
+#ifdef CONFIG_FSL_LSCH3
+/*
+ * Return next available LUT index.
+ */
+static int ls_pcie_next_lut_index(struct ls_pcie *pcie)
+{
+	if (pcie->next_lut_index < PCIE_LUT_ENTRY_COUNT)
+		return pcie->next_lut_index++;
+	else
+		return -1;  /* LUT is full */
+}
+
+/*
+ * Program a single LUT entry
+ */
+static void ls_pcie_lut_set_mapping(struct ls_pcie *pcie, int index, u32 devid,
+			     u32 streamid)
+{
+	void __iomem *lut;
+
+	lut = pcie->dbi + PCIE_LUT_BASE;
+
+	/* leave mask as all zeroes, want to match all bits */
+	writel((devid << 16), lut + PCIE_LUT_UDR(index));
+	writel(streamid | PCIE_LUT_ENABLE, lut + PCIE_LUT_LDR(index));
+}
+#endif
+
 int ls_pcie_init_ctrl(int busno, enum srds_prtcl dev, struct ls_pcie_info *info)
 {
 	struct ls_pcie *pcie;
@@ -513,6 +542,7 @@ int ls_pcie_init_ctrl(int busno, enum srds_prtcl dev, struct

ls_pcie_info *info)

drivers/pci/pcie_layerscape.c int ls_pcie_init_ctrl(int busno, enum srds_prtcl dev, struct ls_pcie_info *info) · line 548

Quoted 8 lines
drivers/pci/pcie_layerscape.c +1 -0
 	pcie->va_cfg1 = map_physmem(info->cfg1_phys,
 				    info->cfg1_size,
 				    MAP_NOCACHE);
+	pcie->next_lut_index = 0;
 
 	/* outbound memory */
 	pci_set_region(&hose->regions[0],

Stuart,

Quoted 7 lines

This patch breaks git bisect. Please rearrange your changes.
warning: 'ls_pcie_next_lut_index' defined but not used [-Wunused-function] static int ls_pcie_next_lut_index(struct ls_pcie *pcie)

            ^
 warning: 'ls_pcie_lut_set_mapping' defined but not used [-Wunused-function]
 static void ls_pcie_lut_set_mapping(struct ls_pcie *pcie, int index, u32 devid,
             ^

Ugh...will fix.

Stuart

#6 lore raw

PATCH RESEND v5 5/7 pci/layerscape: add stream ID allocator

In reply to a message not in the archive

From: Stuart Yoder <[email protected]>

add a function to return the next available stream ID for PCI

---
-v5: no change

 drivers/pci/pcie_layerscape.c |   11 +++++++++++
 1 file changed, 11 insertions(+)
drivers/pci/pcie_layerscape.c +11 -0
index 5cc6855..f3bf689 100644
@@ -509,6 +509,17 @@ static void ls_pcie_lut_set_mapping(struct ls_pcie *pcie, int index, u32 devid,
 	writel((devid << 16), lut + PCIE_LUT_UDR(index));
 	writel(streamid | PCIE_LUT_ENABLE, lut + PCIE_LUT_LDR(index));
 }
+
+/* returns the next available streamid */
+static u32 ls_pcie_next_streamid(void)
+{
+	static int next_stream_id = FSL_PEX_STREAM_ID_START;
+
+	if (next_stream_id > FSL_PEX_STREAM_ID_END)
+		return 0xffffffff;
+
+	return next_stream_id++;
+}
 #endif
 
 int ls_pcie_init_ctrl(int busno, enum srds_prtcl dev, struct ls_pcie_info *info)
Signature · 1 line
1.7.9.5
#7 lore raw

PATCH RESEND v5 6/7 pci/layerscape: fdt: function to set msi-map entries

In reply to a message not in the archive

From: Stuart Yoder <[email protected]>

msi-map properties are used to tell an OS how PCI requester IDs are mapped to ARM SMMU stream IDs. This patch defines a function to append a single msi-map entry to a given PCI controller device tree node.

---
-v5: no change

 drivers/pci/pcie_layerscape.c |   42 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 42 insertions(+)
drivers/pci/pcie_layerscape.c +42 -0
index f3bf689..73af423 100644
@@ -520,6 +520,48 @@ static u32 ls_pcie_next_streamid(void)
 
 	return next_stream_id++;
 }
+
+/*
+ * An msi-map is a property to be added to the pci controller
+ * node.  It is a table, where each entry consists of 4 fields
+ * e.g.:
+ *
+ *      msi-map = <[devid] [phandle-to-msi-ctrl] [stream-id] [count]
+ *                 [devid] [phandle-to-msi-ctrl] [stream-id] [count]>;
+ */
+static void fdt_pcie_set_msi_map_entry(void *blob, struct ls_pcie *pcie,
+				       u32 devid, u32 streamid)
+{
+	char pcie_path[19];
+	u32 *prop;
+	u32 phandle;
+	int nodeoffset;
+
+	/* find pci controller node */
+	snprintf(pcie_path, sizeof(pcie_path), "/soc/pcie@%llx",
+		 (u64)pcie->dbi);
+	nodeoffset = fdt_path_offset(blob, pcie_path);
+	if (nodeoffset < 0) {
+		printf("\n%s: ERROR: unable to update PCIe node: %s\n",
+		       __func__, pcie_path);
+		return;
+	}
+
+	/* get phandle to MSI controller */
+	prop = (u32 *)fdt_getprop(blob, nodeoffset, "msi-parent", 0);
+	if (prop == NULL) {
+		printf("\n%s: ERROR: missing msi-parent: %s\n", __func__,
+		       pcie_path);
+		return;
+	}
+	phandle = be32_to_cpu(*prop);
+
+	/* set one msi-map row */
+	fdt_appendprop_u32(blob, nodeoffset, "msi-map", devid);
+	fdt_appendprop_u32(blob, nodeoffset, "msi-map", phandle);
+	fdt_appendprop_u32(blob, nodeoffset, "msi-map", streamid);
+	fdt_appendprop_u32(blob, nodeoffset, "msi-map", 1);
+}
 #endif
 
 int ls_pcie_init_ctrl(int busno, enum srds_prtcl dev, struct ls_pcie_info *info)
Signature · 1 line
1.7.9.5
#8 lore raw

PATCH RESEND v5 7/7 pci/layerscape: set LUT and msi-map for discovered PCI devices

In reply to a message not in the archive

From: Stuart Yoder <[email protected]>

for all PCI devices discovered in a system:
-allocate a LUT (look-up-table) entry in that PCI controller -allocate a stream ID for the device
-program and enable a LUT entry (maps PCI requester id to stream ID) -set the msi-map property on the controller reflecting the
LUT mapping

basic bus scanning loop/logic was taken from drivers/pci/pci.c pci_hose_scan_bus().

---
-v5: no change

 drivers/pci/pcie_layerscape.c |   64 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 64 insertions(+)
drivers/pci/pcie_layerscape.c +64 -0
index 73af423..0450483 100644
@@ -562,6 +562,66 @@ static void fdt_pcie_set_msi_map_entry(void *blob, struct ls_pcie *pcie,
 	fdt_appendprop_u32(blob, nodeoffset, "msi-map", streamid);
 	fdt_appendprop_u32(blob, nodeoffset, "msi-map", 1);
 }
+
+static void fdt_fixup_pcie(void *blob)
+{
+	unsigned int found_multi = 0;
+	unsigned char header_type;
+	int index;
+	u32 streamid;
+	pci_dev_t dev;
+	int bus;
+	unsigned short id;
+	struct pci_controller *hose;
+	struct ls_pcie *pcie;
+	int i;
+
+	for (i = 0, hose = pci_get_hose_head(); hose; hose = hose->next, i++) {
+		pcie = hose->priv_data;
+		for (bus = hose->first_busno; bus <= hose->last_busno; bus++) {
+
+			for (dev =  PCI_BDF(bus, 0, 0);
+			     dev <  PCI_BDF(bus, PCI_MAX_PCI_DEVICES - 1,
+					    PCI_MAX_PCI_FUNCTIONS - 1);
+			     dev += PCI_BDF(0, 0, 1)) {
+
+				if (PCI_FUNC(dev) && !found_multi)
+					continue;
+
+				pci_read_config_word(dev, PCI_VENDOR_ID, &id);
+
+				pci_read_config_byte(dev, PCI_HEADER_TYPE,
+						     &header_type);
+
+				if ((id == 0xFFFF) || (id == 0x0000))
+					continue;
+
+				if (!PCI_FUNC(dev))
+					found_multi = header_type & 0x80;
+
+				streamid = ls_pcie_next_streamid();
+				if (streamid == 0xffffffff) {
+					printf("ERROR: no stream ids free\n");
+					continue;
+				}
+
+				index = ls_pcie_next_lut_index(pcie);
+				if (index < 0) {
+					printf("ERROR: no LUT indexes free\n");
+					continue;
+				}
+
+				/* map PCI b.d.f to streamID in LUT */
+				ls_pcie_lut_set_mapping(pcie, index, dev >> 8,
+							streamid);
+
+				/* update msi-map in device tree */
+				fdt_pcie_set_msi_map_entry(blob, pcie, dev >> 8,
+							   streamid);
+			}
+		}
+	}
+}
 #endif
 
 int ls_pcie_init_ctrl(int busno, enum srds_prtcl dev, struct ls_pcie_info *info)
@@ -740,6 +800,10 @@ void ft_pci_setup(void *blob, bd_t *bd)
 	#ifdef CONFIG_PCIE4
 	ft_pcie_ls_setup(blob, FSL_PCIE_COMPAT, CONFIG_SYS_PCIE4_ADDR, PCIE4);
 	#endif
+
+	#if defined(CONFIG_LS2080A) || defined(CONFIG_LS2085A)
+	fdt_fixup_pcie(blob);
+	#endif
 }
 
 #else
Signature · 1 line
1.7.9.5