summaryrefslogtreecommitdiff
path: root/arch/arm/cpu/armv8/fsl-layerscape/fdt.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/cpu/armv8/fsl-layerscape/fdt.c')
-rw-r--r--arch/arm/cpu/armv8/fsl-layerscape/fdt.c150
1 files changed, 149 insertions, 1 deletions
diff --git a/arch/arm/cpu/armv8/fsl-layerscape/fdt.c b/arch/arm/cpu/armv8/fsl-layerscape/fdt.c
index 7f29aa4725..f1624ff30a 100644
--- a/arch/arm/cpu/armv8/fsl-layerscape/fdt.c
+++ b/arch/arm/cpu/armv8/fsl-layerscape/fdt.c
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright 2014-2015 Freescale Semiconductor, Inc.
- * Copyright 2020 NXP
+ * Copyright 2020-2021 NXP
*/
#include <common.h>
@@ -478,6 +478,151 @@ static bool crypto_is_disabled(unsigned int svr)
return false;
}
+#ifdef CONFIG_FSL_PFE
+void pfe_set_firmware_in_fdt(void *blob, int pfenode, void *pfw, char *pename,
+ unsigned int len)
+{
+ int rc, fwnode;
+ unsigned int phandle;
+ char subnode_str[32], prop_str[32], phandle_str[32], s[64];
+
+ sprintf(subnode_str, "pfe-%s-firmware", pename);
+ sprintf(prop_str, "fsl,pfe-%s-firmware", pename);
+ sprintf(phandle_str, "fsl,%s-firmware", pename);
+
+ /*Add PE FW to fdt.*/
+ /* Increase the size of the fdt to make room for the node. */
+ rc = fdt_increase_size(blob, len);
+ if (rc < 0) {
+ printf("Unable to make room for %s firmware: %s\n", pename,
+ fdt_strerror(rc));
+ return;
+ }
+
+ /* Create the firmware node. */
+ fwnode = fdt_add_subnode(blob, pfenode, subnode_str);
+ if (fwnode < 0) {
+ fdt_get_path(blob, pfenode, 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", prop_str);
+ if (rc < 0) {
+ fdt_get_path(blob, fwnode, s, sizeof(s));
+ printf("Could not add compatible property to node %s: %s\n", s,
+ fdt_strerror(rc));
+ return;
+ }
+
+ rc = fdt_setprop_u32(blob, fwnode, "length", len);
+ if (rc < 0) {
+ fdt_get_path(blob, fwnode, s, sizeof(s));
+ printf("Could not add compatible property to node %s: %s\n", s,
+ fdt_strerror(rc));
+ return;
+ }
+
+ /*create phandle and set the property*/
+ phandle = fdt_create_phandle(blob, fwnode);
+ if (!phandle) {
+ 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, phandle_str, pfw, len);
+ if (rc < 0) {
+ fdt_get_path(blob, fwnode, s, sizeof(s));
+ printf("Could not add firmware property to node %s: %s\n", s,
+ fdt_strerror(rc));
+ return;
+ }
+}
+
+void fdt_fixup_pfe_firmware(void *blob)
+{
+ int pfenode;
+ unsigned int len_class = 0, len_tmu = 0, len_util = 0;
+ const char *p;
+ void *pclassfw, *ptmufw, *putilfw;
+
+ /* The first PFE we find, will contain the actual firmware. */
+ pfenode = fdt_node_offset_by_compatible(blob, -1, "fsl,pfe");
+ if (pfenode < 0)
+ /* Exit silently if there are no PFE devices */
+ return;
+
+ /* If we already have a firmware node, then also exit silently. */
+ if (fdt_node_offset_by_compatible(blob, -1,
+ "fsl,pfe-class-firmware") > 0)
+ return;
+
+ /* If the environment variable is not set, then exit silently */
+ p = env_get("class_elf_firmware");
+ if (!p)
+ return;
+
+ pclassfw = (void *)simple_strtoul(p, NULL, 16);
+ if (!pclassfw)
+ return;
+
+ p = env_get("class_elf_size");
+ if (!p)
+ return;
+ len_class = simple_strtoul(p, NULL, 16);
+
+ /* If the environment variable is not set, then exit silently */
+ p = env_get("tmu_elf_firmware");
+ if (!p)
+ return;
+
+ ptmufw = (void *)simple_strtoul(p, NULL, 16);
+ if (!ptmufw)
+ return;
+
+ p = env_get("tmu_elf_size");
+ if (!p)
+ return;
+ len_tmu = simple_strtoul(p, NULL, 16);
+
+ if (len_class == 0 || len_tmu == 0) {
+ printf("PFE FW corrupted. CLASS FW size %d, TMU FW size %d\n",
+ len_class, len_tmu);
+ return;
+ }
+
+ /*Add CLASS FW to fdt.*/
+ pfe_set_firmware_in_fdt(blob, pfenode, pclassfw, "class", len_class);
+
+ /*Add TMU FW to fdt.*/
+ pfe_set_firmware_in_fdt(blob, pfenode, ptmufw, "tmu", len_tmu);
+
+ /* Util PE firmware is handled separately as it is not a usual case*/
+ p = env_get("util_elf_firmware");
+ if (!p)
+ return;
+
+ putilfw = (void *)simple_strtoul(p, NULL, 16);
+ if (!putilfw)
+ return;
+
+ p = env_get("util_elf_size");
+ if (!p)
+ return;
+ len_util = simple_strtoul(p, NULL, 16);
+
+ if (len_util) {
+ printf("PFE Util PE firmware is not added to FDT.\n");
+ return;
+ }
+
+ pfe_set_firmware_in_fdt(blob, pfenode, putilfw, "util", len_util);
+}
+#endif
+
void ft_cpu_setup(void *blob, struct bd_info *bd)
{
struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
@@ -534,6 +679,9 @@ void ft_cpu_setup(void *blob, struct bd_info *bd)
#ifdef CONFIG_SYS_DPAA_FMAN
fdt_fixup_fman_firmware(blob);
#endif
+#ifdef CONFIG_FSL_PFE
+ fdt_fixup_pfe_firmware(blob);
+#endif
#ifndef CONFIG_ARCH_LS1012A
fsl_fdt_disable_usb(blob);
#endif