[U-Boot] [PATCH v5 2/2] armv8/fsl-layerscape: fdt: fixup LS1043A rev1 MSI node

Wenbin song wenbin.song at nxp.com
Thu Oct 27 10:53:27 CEST 2016


There are two types of msi node in kernel device tree, one is for
LS1043A rev1.1 silicon, the other is for rev1.0.

According to revision number, fixup the msi node.

Signed-off-by: Wenbin Song <wenbin.song at nxp.com>
Signed-off-by: Mingkai Hu <mingkai.hu at nxp.com>
---
Change in v5:
	Fixup the msi node used on rev1.0 when running on rev1.1.    	
---
 arch/arm/cpu/armv8/fsl-layerscape/Kconfig |   3 +
 arch/arm/cpu/armv8/fsl-layerscape/fdt.c   | 115 ++++++++++++++++++++++++++++++
 2 files changed, 118 insertions(+)

diff --git a/arch/arm/cpu/armv8/fsl-layerscape/Kconfig b/arch/arm/cpu/armv8/fsl-layerscape/Kconfig
index f415868..34ac867 100644
--- a/arch/arm/cpu/armv8/fsl-layerscape/Kconfig
+++ b/arch/arm/cpu/armv8/fsl-layerscape/Kconfig
@@ -139,4 +139,7 @@ config HAS_FEATURE_GIC4K_ALIGN
        bool
        default y if ARCH_LS1043A
 
+config HAS_FEATURE_ENHANCED_MSI
+       bool
+       default y if ARCH_LS1043A
 endmenu
diff --git a/arch/arm/cpu/armv8/fsl-layerscape/fdt.c b/arch/arm/cpu/armv8/fsl-layerscape/fdt.c
index e90adb0..5bac380 100644
--- a/arch/arm/cpu/armv8/fsl-layerscape/fdt.c
+++ b/arch/arm/cpu/armv8/fsl-layerscape/fdt.c
@@ -185,6 +185,118 @@ static void fdt_fixup_gic(void *blob)
 }
 #endif
 
+#ifdef CONFIG_HAS_FEATURE_ENHANCED_MSI
+static int _fdt_fixup_msi_subnode(void *blob, int offset, const char *name,
+				  int irq_0, int irq_1, int rev)
+{
+	int err, sub_offset, len;
+	u32 tmp[4][3];
+
+	sub_offset = fdt_subnode_offset(blob, offset, name);
+	if (offset < 0) {
+		printf("WARNING: fdt_subnode_offset can't find %s: %s\n",
+		       name, fdt_strerror(sub_offset));
+		return 0;
+	}
+
+	tmp[0][0] = cpu_to_fdt32(0x0);
+	tmp[0][1] = cpu_to_fdt32(irq_0);
+	tmp[0][2] = cpu_to_fdt32(0x4);
+
+	if (rev > REV1_0) {
+		tmp[1][0] = cpu_to_fdt32(0x0);
+		tmp[1][1] = cpu_to_fdt32(irq_1);
+		tmp[1][2] = cpu_to_fdt32(0x4);
+		tmp[2][0] = cpu_to_fdt32(0x0);
+		tmp[2][1] = cpu_to_fdt32(irq_1 + 1);
+		tmp[2][2] = cpu_to_fdt32(0x4);
+		tmp[3][0] = cpu_to_fdt32(0x0);
+		tmp[3][1] = cpu_to_fdt32(irq_1 + 2);
+		tmp[3][2] = cpu_to_fdt32(0x4);
+		len = sizeof(tmp);
+	} else {
+		len = sizeof(tmp[0]);
+	}
+
+	err = fdt_setprop(blob, sub_offset, "interrupts", tmp, len);
+	if (err < 0) {
+		printf("WARNING: fdt_setprop can't set %s from node %s: %s\n",
+		       "interrupts", name, fdt_strerror(err));
+		return 0;
+	}
+
+	return 1;
+}
+
+static int _fdt_fixup_pci_msi(void *blob, const char *name, int rev)
+{
+	int offset, len, err;
+	void *p;
+	int val;
+	u32 tmp[4][8];
+
+	offset = fdt_path_offset(blob, name);
+	if (offset < 0) {
+		printf("WARNING: fdt_path_offset can't find path %s: %s\n",
+		       name, fdt_strerror(offset));
+		return 0;
+	}
+
+	p = (char *)fdt_getprop(blob, offset, "interrupt-map", &len);
+	if (!p || len != sizeof(tmp)) {
+		printf("WARNING: fdt_getprop can't get %s from node %s\n",
+		       "interrupt-map", name);
+		return 0;
+	}
+
+	memcpy((char *)tmp, p, len);
+
+	val = fdt32_to_cpu(tmp[0][6]);
+	if (rev > REV1_0) {
+		tmp[1][6] = cpu_to_fdt32(val + 1);
+		tmp[2][6] = cpu_to_fdt32(val + 2);
+		tmp[3][6] = cpu_to_fdt32(val + 3);
+	} else {
+		tmp[1][6] = cpu_to_fdt32(val);
+		tmp[2][6] = cpu_to_fdt32(val);
+		tmp[3][6] = cpu_to_fdt32(val);
+	}
+
+	err = fdt_setprop(blob, offset, "interrupt-map", tmp, sizeof(tmp));
+	if (err < 0) {
+		printf("WARNING: fdt_setprop can't set %s from node %s: %s.\n",
+		       "interrupt-map", name, fdt_strerror(err));
+		return 0;
+	}
+	return 1;
+}
+
+/* Fixup msi to v1_0*/
+
+static void fdt_fixup_msi(void *blob)
+{
+	int nodeoffset;
+	struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
+	unsigned int rev;
+
+	rev = gur_in32(&gur->svr) & 0xff;
+
+	nodeoffset = fdt_path_offset(blob, "/soc/msi-controller");
+	if (nodeoffset < 0) {
+		printf("WARNING: fdt_path_offset can't find path %s: %s\n",
+		       "/soc/msi-controller", fdt_strerror(nodeoffset));
+		return;
+	}
+	_fdt_fixup_msi_subnode(blob, nodeoffset, "msi0 at 1571000", 116, 111, rev);
+	_fdt_fixup_msi_subnode(blob, nodeoffset, "msi1 at 1572000", 126, 121, rev);
+	_fdt_fixup_msi_subnode(blob, nodeoffset, "msi2 at 1573000", 160, 155, rev);
+
+	_fdt_fixup_pci_msi(blob, "/soc/pcie at 3400000", rev);
+	_fdt_fixup_pci_msi(blob, "/soc/pcie at 3500000", rev);
+	_fdt_fixup_pci_msi(blob, "/soc/pcie at 3600000", rev);
+}
+#endif
+
 void ft_cpu_setup(void *blob, bd_t *bd)
 {
 #ifdef CONFIG_FSL_LSCH2
@@ -232,4 +344,7 @@ void ft_cpu_setup(void *blob, bd_t *bd)
 #ifdef CONFIG_HAS_FEATURE_GIC4K_ALIGN
 	fdt_fixup_gic(blob);
 #endif
+#ifdef CONFIG_HAS_FEATURE_ENHANCED_MSI
+	fdt_fixup_msi(blob);
+#endif
 }
-- 
2.1.0.27.g96db324



More information about the U-Boot mailing list