[U-Boot] [PATCH 2/2] armv8/fsl-layerscape: fdt: add fixup for fman

Gong Qianyu Qianyu.Gong at nxp.com
Thu Jan 21 08:00:04 CET 2016


1.Add fixup for fman clock.
2.Add fdt_fixup_fman_firmware() to insert the Fman ucode firmware into
the device tree.

Signed-off-by: Gong Qianyu <Qianyu.Gong at nxp.com>
---
 arch/arm/cpu/armv8/fsl-layerscape/fdt.c | 121 ++++++++++++++++++++++++++++++++
 1 file changed, 121 insertions(+)

diff --git a/arch/arm/cpu/armv8/fsl-layerscape/fdt.c b/arch/arm/cpu/armv8/fsl-layerscape/fdt.c
index 2a3e621..c93aa18 100644
--- a/arch/arm/cpu/armv8/fsl-layerscape/fdt.c
+++ b/arch/arm/cpu/armv8/fsl-layerscape/fdt.c
@@ -19,6 +19,7 @@
 #ifdef CONFIG_MP
 #include <asm/arch/mp.h>
 #endif
+#include "../../../../../drivers/qe/qe.h"         /* For struct qe_firmware */
 
 int fdt_fixup_phy_connection(void *blob, int offset, phy_interface_t phyc)
 {
@@ -255,6 +256,120 @@ void fdt_fixup_qportals(void *blob)
 }
 #endif
 
+#ifdef CONFIG_SYS_DPAA_FMAN
+void fdt_fixup_fman_firmware(void *blob)
+{
+	int rc, fmnode, fwnode = -1;
+	uint32_t phandle;
+	struct qe_firmware *fmanfw;
+	const struct qe_header *hdr;
+	unsigned int length;
+	uint32_t crc;
+	const char *p;
+
+	/* The first Fman we find will contain the actual firmware. */
+	fmnode = fdt_node_offset_by_compatible(blob, -1, "fsl,fman");
+	if (fmnode < 0)
+		/* Exit silently if there are no Fman devices */
+		return;
+
+	/* If we already have a firmware node, then also exit silently. */
+	if (fdt_node_offset_by_compatible(blob, -1, "fsl,fman-firmware") > 0)
+		return;
+
+	/* If the environment variable is not set, then exit silently */
+	p = getenv("fman_ucode");
+	if (!p)
+		return;
+
+	fmanfw = (struct qe_firmware *)simple_strtoul(p, NULL, 16);
+	if (!fmanfw)
+		return;
+
+	hdr = &fmanfw->header;
+	length = fdt32_to_cpu(hdr->length);
+
+	/* Verify the firmware. */
+	if ((hdr->magic[0] != 'Q') || (hdr->magic[1] != 'E') ||
+	    (hdr->magic[2] != 'F')) {
+		printf("Data at %p is not an Fman firmware\n", fmanfw);
+		return;
+	}
+
+	if (length > CONFIG_SYS_QE_FMAN_FW_LENGTH) {
+		printf("Fman firmware at %p is too large (size=%u)\n",
+		       fmanfw, length);
+		return;
+	}
+
+	length -= sizeof(u32);	/* Subtract the size of the CRC */
+	crc = fdt32_to_cpu(*(u32 *)((void *)fmanfw + length));
+	if (crc != crc32_no_comp(0, (void *)fmanfw, length)) {
+		printf("Fman firmware at %p has invalid CRC\n", fmanfw);
+		return;
+	}
+
+	length += sizeof(u32);
+
+	/* Increase the size of the fdt to make room for the node. */
+	rc = fdt_increase_size(blob, length);
+	if (rc < 0) {
+		printf("Unable to make room for Fman firmware: %s\n",
+		       fdt_strerror(rc));
+		return;
+	}
+
+	/* Create the firmware node. */
+	fwnode = fdt_add_subnode(blob, fmnode, "fman-firmware");
+	if (fwnode < 0) {
+		char s[64];
+		fdt_get_path(blob, fmnode, s, sizeof(s));
+		printf("Could not add firmware node to %s: %s\n", s,
+		       fdt_strerror(fwnode));
+		return;
+	}
+	rc = fdt_setprop_string(blob, fwnode, "compatible",
+					"fsl,fman-firmware");
+	if (rc < 0) {
+		char s[64];
+		fdt_get_path(blob, fwnode, s, sizeof(s));
+		printf("Could not add compatible property to node %s: %s\n", s,
+		       fdt_strerror(rc));
+		return;
+	}
+	phandle = fdt_create_phandle(blob, fwnode);
+	if (!phandle) {
+		char s[64];
+		fdt_get_path(blob, fwnode, s, sizeof(s));
+		printf("Could not add phandle property to node %s: %s\n", s,
+		       fdt_strerror(rc));
+		return;
+	}
+	rc = fdt_setprop(blob, fwnode, "fsl,firmware", fmanfw, length);
+	if (rc < 0) {
+		char s[64];
+		fdt_get_path(blob, fwnode, s, sizeof(s));
+		printf("Could not add firmware property to node %s: %s\n", s,
+		       fdt_strerror(rc));
+		return;
+	}
+
+	/* Find all other Fman nodes and point them to the firmware node. */
+	while ((fmnode = fdt_node_offset_by_compatible(blob, fmnode,
+		"fsl,fman")) > 0) {
+		rc = fdt_setprop_cell(blob, fmnode, "fsl,firmware-phandle",
+				      phandle);
+		if (rc < 0) {
+			char s[64];
+			fdt_get_path(blob, fmnode, s, sizeof(s));
+			printf("Could not add pointer property to node %s: %s\n",
+			       s, fdt_strerror(rc));
+			return;
+		}
+	}
+}
+#endif
+
 void ft_cpu_setup(void *blob, bd_t *bd)
 {
 	struct sys_info sysinfo;
@@ -288,4 +403,10 @@ void ft_cpu_setup(void *blob, bd_t *bd)
 	do_fixup_by_compat_u32(blob, "fsl,qman",
 			       "clock-frequency", sysinfo.freq_qman, 1);
 #endif
+
+#ifdef CONFIG_SYS_DPAA_FMAN
+	do_fixup_by_compat_u32(blob, "fsl,fman",
+			       "clock-frequency", sysinfo.freq_fman[0], 1);
+	fdt_fixup_fman_firmware(blob);
+#endif
 }
-- 
2.1.0.27.g96db324



More information about the U-Boot mailing list