2 * Copyright 2016 Freescale Semiconductor, Inc.
4 * SPDX-License-Identifier: GPL-2.0+
7 #include <fsl_qe.h> /* For struct qe_firmware */
9 #ifdef CONFIG_SYS_DPAA_FMAN
11 * fdt_fixup_fman_firmware -- insert the Fman firmware into the device tree
13 * The binding for an Fman firmware node is documented in
14 * Documentation/powerpc/dts-bindings/fsl/dpaa/fman.txt. This node contains
15 * the actual Fman firmware binary data. The operating system is expected to
16 * be able to parse the binary data to determine any attributes it needs.
18 void fdt_fixup_fman_firmware(void *blob
)
20 int rc
, fmnode
, fwnode
= -1;
22 struct qe_firmware
*fmanfw
;
23 const struct qe_header
*hdr
;
28 /* The first Fman we find will contain the actual firmware. */
29 fmnode
= fdt_node_offset_by_compatible(blob
, -1, "fsl,fman");
31 /* Exit silently if there are no Fman devices */
34 /* If we already have a firmware node, then also exit silently. */
35 if (fdt_node_offset_by_compatible(blob
, -1, "fsl,fman-firmware") > 0)
38 /* If the environment variable is not set, then exit silently */
39 p
= env_get("fman_ucode");
43 fmanfw
= (struct qe_firmware
*)simple_strtoul(p
, NULL
, 16);
47 hdr
= &fmanfw
->header
;
48 length
= fdt32_to_cpu(hdr
->length
);
50 /* Verify the firmware. */
51 if ((hdr
->magic
[0] != 'Q') || (hdr
->magic
[1] != 'E') ||
52 (hdr
->magic
[2] != 'F')) {
53 printf("Data at %p is not an Fman firmware\n", fmanfw
);
57 if (length
> CONFIG_SYS_QE_FMAN_FW_LENGTH
) {
58 printf("Fman firmware at %p is too large (size=%u)\n",
63 length
-= sizeof(u32
); /* Subtract the size of the CRC */
64 crc
= fdt32_to_cpu(*(u32
*)((void *)fmanfw
+ length
));
65 if (crc
!= crc32_no_comp(0, (void *)fmanfw
, length
)) {
66 printf("Fman firmware at %p has invalid CRC\n", fmanfw
);
70 length
+= sizeof(u32
);
72 /* Increase the size of the fdt to make room for the node. */
73 rc
= fdt_increase_size(blob
, length
);
75 printf("Unable to make room for Fman firmware: %s\n",
80 /* Create the firmware node. */
81 fwnode
= fdt_add_subnode(blob
, fmnode
, "fman-firmware");
84 fdt_get_path(blob
, fmnode
, s
, sizeof(s
));
85 printf("Could not add firmware node to %s: %s\n", s
,
86 fdt_strerror(fwnode
));
89 rc
= fdt_setprop_string(blob
, fwnode
, "compatible",
93 fdt_get_path(blob
, fwnode
, s
, sizeof(s
));
94 printf("Could not add compatible property to node %s: %s\n", s
,
98 phandle
= fdt_create_phandle(blob
, fwnode
);
101 fdt_get_path(blob
, fwnode
, s
, sizeof(s
));
102 printf("Could not add phandle property to node %s: %s\n", s
,
106 rc
= fdt_setprop(blob
, fwnode
, "fsl,firmware", fmanfw
, length
);
109 fdt_get_path(blob
, fwnode
, s
, sizeof(s
));
110 printf("Could not add firmware property to node %s: %s\n", s
,
115 /* Find all other Fman nodes and point them to the firmware node. */
116 while ((fmnode
= fdt_node_offset_by_compatible(blob
, fmnode
,
118 rc
= fdt_setprop_cell(blob
, fmnode
, "fsl,firmware-phandle",
122 fdt_get_path(blob
, fmnode
, s
, sizeof(s
));
123 printf("Could not add pointer property to node %s: %s\n",
124 s
, fdt_strerror(rc
));