Hi Michael,

On 11/27/2019 3:33 PM, Michael Walle wrote:
Hi Alex,

Am 2019-11-27 14:57, schrieb Alex Marginean:
Hardware comes out of reset with implicit values, but these are outside
the accepted range for Layerscape gen 3 chassis spec used on LS1028A.
Allocate different IDs and fix up Linux DT to use them.

Signed-off-by: Alex Marginean <[email protected]>
---
 arch/arm/cpu/armv8/fsl-layerscape/fdt.c       |   9 ++
 .../asm/arch-fsl-layerscape/stream_id_lsch3.h |   8 ++
 board/freescale/ls1028a/ls1028a.c             | 106 ++++++++++++++++++

Doh :( is there no other place where to put this fixup? That would mean I
have to replicate this code for our custom board and so does every board
which uses the LS1028A. Shouldn't this be in the SoC LS1028A architecture
specific code?

Yeah, you're right about that.
It should probably go into armv8/fsl-layerscape/icid.c or somewhere around there.
I'll send a v2.

Thanks!
Alex


 3 files changed, 123 insertions(+)

diff --git a/arch/arm/cpu/armv8/fsl-layerscape/fdt.c
b/arch/arm/cpu/armv8/fsl-layerscape/fdt.c
index e993209593..1e7e46e88a 100644
--- a/arch/arm/cpu/armv8/fsl-layerscape/fdt.c
+++ b/arch/arm/cpu/armv8/fsl-layerscape/fdt.c
@@ -421,6 +421,12 @@ static void fdt_disable_multimedia(void *blob,
unsigned int svr)
 }
 #endif

+#ifdef CONFIG_PCIE_ECAM_GENERIC
+__weak void fdt_fixup_ecam(void *blob)
+{
+}
+#endif
+
 void ft_cpu_setup(void *blob, bd_t *bd)
 {
     struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
@@ -485,4 +491,7 @@ void ft_cpu_setup(void *blob, bd_t *bd)
 #ifdef CONFIG_ARCH_LS1028A
     fdt_disable_multimedia(blob, svr);
 #endif
+#ifdef CONFIG_PCIE_ECAM_GENERIC
+    fdt_fixup_ecam(blob);
+#endif
 }
diff --git
a/arch/arm/include/asm/arch-fsl-layerscape/stream_id_lsch3.h
b/arch/arm/include/asm/arch-fsl-layerscape/stream_id_lsch3.h
index 94ea99a349..01d362d183 100644
--- a/arch/arm/include/asm/arch-fsl-layerscape/stream_id_lsch3.h
+++ b/arch/arm/include/asm/arch-fsl-layerscape/stream_id_lsch3.h
@@ -42,6 +42,10 @@
  *     -the MC is responsible for allocating and setting up 'isolation context   *      IDs (ICIDs) based on the allocated stream IDs for all DPAA2 devices.
  *
+ *  - ECAM (integrated PCI)
+ *     - U-Boot applies the value here to HW and does DT fix-up for both
+ *       'iommu-map' and 'msi-map'
+ *

mhh this is not entirely true, because it is the board code which
does the fixup, which may lead to some confusion. >
  * On Chasis-3 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:
@@ -98,6 +102,10 @@
 #define FSL_DPAA2_STREAM_ID_START    23
 #define FSL_DPAA2_STREAM_ID_END        63

+/* PCI IEPs, this overlaps DPAA2 but these two are exclusive at least
for now */
+#define FSL_ECAM_STREAM_ID_START    32
+#define FSL_ECAM_STREAM_ID_END        63
+
 #define FSL_SEC_STREAM_ID        64
 #define FSL_SEC_JR1_STREAM_ID        65
 #define FSL_SEC_JR2_STREAM_ID        66
diff --git a/board/freescale/ls1028a/ls1028a.c
b/board/freescale/ls1028a/ls1028a.c
index a9606b8865..1f5dc0d0b2 100644
--- a/board/freescale/ls1028a/ls1028a.c
+++ b/board/freescale/ls1028a/ls1028a.c
@@ -28,6 +28,52 @@

 DECLARE_GLOBAL_DATA_PTR;

+#ifdef CONFIG_PCIE_ECAM_GENERIC
+
+#define ECAM_IERB_BASE        0x1f0800000ULL
+#define ECAM_IERB_OFFSET_NA    -1
+#define ECAM_IERB_FUNC_CNT    ARRAY_SIZE(ierb_offset)
+/* cache related transaction attributes for PCIe functions */
+#define ECAM_IERB_MSICAR        (ECAM_IERB_BASE + 0xa400)
+#define ECAM_IERB_MSICAR_VALUE        0x30
+
+/* offset of IERB config register per PCI function */
+static int ierb_offset[] = {
+    0x0800,
+    0x1800,
+    0x2800,
+    0x3800,
+    0x4800,
+    0x5800,
+    0x6800,
+    ECAM_IERB_OFFSET_NA,
+    0x0804,
+    0x0808,
+    0x1804,
+    0x1808,
+};
+
+/*
+ * Use a custom function for LS1028A, for now this is the only SoC with IERB
+ * and we're currently considering reorganizing IERB for future SoCs.
+ */
+static void set_ecam_icids(void)
+{
+    int i;
+
+    out_le32(ECAM_IERB_MSICAR, ECAM_IERB_MSICAR_VALUE);
+
+    for (i = 0; i < ECAM_IERB_FUNC_CNT; i++) {
+        if (ierb_offset[i] == ECAM_IERB_OFFSET_NA)
+            continue;
+
+        out_le32(ECAM_IERB_BASE + ierb_offset[i],
+             FSL_ECAM_STREAM_ID_START + i);
+    }
+}
+
+#endif /* CONFIG_PCIE_ECAM_GENERIC */
+
 int config_board_mux(void)
 {
 #if defined(CONFIG_TARGET_LS1028AQDS) && defined(CONFIG_FSL_QIXIS)
@@ -88,6 +134,16 @@ int board_init(void)
 #endif

 #endif
+
+    /*
+     * ICIDs for other hardware blocks are set really early on, before MMU +     * is set up.  For integrated PCI we need access to IERB which is not
+     * part of CCSR, so we have to wait for MMU mappings to be applied
+     */
+#ifdef CONFIG_PCIE_ECAM_GENERIC
+    set_ecam_icids();
+#endif
+
     return 0;
 }

@@ -244,3 +300,53 @@ int checkboard(void)
     return 0;
 }
 #endif
+
+#ifdef CONFIG_PCIE_ECAM_GENERIC
+
+static int fdt_setprop_inplace_idx_u32(void *fdt, int nodeoffset,
+                       const char *name, uint32_t idx, u32 val)
+{
+    val = cpu_to_be32(val);
+    return fdt_setprop_inplace_namelen_partial(fdt, nodeoffset, name,
+                           strlen(name),
+                           idx * sizeof(val), &val,
+                           sizeof(val));
+}
+
+static int fdt_getprop_len(void *fdt, int nodeoffset, const char *name)
+{
+    int len;
+
+    if (fdt_getprop_namelen(fdt, nodeoffset, name, strlen(name), &len))
+        return len;
+
+    return 0;
+}
+
+void fdt_fixup_ecam(void *blob)
+{
+    int off;
+
+    off = fdt_node_offset_by_compatible(blob, 0, "pci-host-ecam-generic");
+    if (off < 0) {
+        debug("ECAM node not found\n");
+        return;
+    }
+
+    if (fdt_getprop_len(blob, off, "msi-map") != 16 ||
+        fdt_getprop_len(blob, off, "iommu-map") != 16) {
+        log_err("invalid msi/iommu-map propertly size in ECAM node\n");
+        return;
+    }
+
+    fdt_setprop_inplace_idx_u32(blob, off, "msi-map", 2,
+                    FSL_ECAM_STREAM_ID_START);
+    fdt_setprop_inplace_idx_u32(blob, off, "msi-map", 3,
+                    ECAM_IERB_FUNC_CNT);
+
+    fdt_setprop_inplace_idx_u32(blob, off, "iommu-map", 2,
+                    FSL_ECAM_STREAM_ID_START);
+    fdt_setprop_inplace_idx_u32(blob, off, "iommu-map", 3,
+                    ECAM_IERB_FUNC_CNT);
+}
+#endif /* CONFIG_PCIE_ECAM_GENERIC */

-michael
_______________________________________________
U-Boot mailing list
[email protected]
https://lists.denx.de/listinfo/u-boot
_______________________________________________
U-Boot mailing list
[email protected]
https://lists.denx.de/listinfo/u-boot

Reply via email to