diff options
| -rw-r--r-- | arch/arm/cpu/armv8/fsl-layerscape/fdt.c | 150 | ||||
| -rw-r--r-- | drivers/net/pfe_eth/pfe_firmware.c | 60 | 
2 files changed, 207 insertions, 3 deletions
| diff --git a/arch/arm/cpu/armv8/fsl-layerscape/fdt.c b/arch/arm/cpu/armv8/fsl-layerscape/fdt.c index 7f29aa4725a..f1624ff30ae 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 diff --git a/drivers/net/pfe_eth/pfe_firmware.c b/drivers/net/pfe_eth/pfe_firmware.c index eee70a2e73a..ac86e33c550 100644 --- a/drivers/net/pfe_eth/pfe_firmware.c +++ b/drivers/net/pfe_eth/pfe_firmware.c @@ -1,7 +1,7 @@  // SPDX-License-Identifier: GPL-2.0+  /*   * Copyright 2015-2016 Freescale Semiconductor, Inc. - * Copyright 2017 NXP + * Copyright 2017,2021 NXP   */  /* @@ -262,7 +262,8 @@ int pfe_firmware_init(void)  	uintptr_t pfe_img_addr = 0;  #endif  	int ret = 0; -	int fw_count; +	int fw_count, max_fw_count; +	const char *p;  	ret = pfe_spi_flash_init();  	if (ret) @@ -293,6 +294,61 @@ int pfe_firmware_init(void)  	}  #endif +	p = env_get("load_util"); +	if (!p) { +		max_fw_count = 2; +	} else { +		max_fw_count = simple_strtoul(p, NULL, 10); +		if (max_fw_count) +			max_fw_count = 3; +		else +			max_fw_count = 2; +	} + +	for (fw_count = 0; fw_count < max_fw_count; fw_count++) { +		switch (fw_count) { +		case 0: +			pfe_firmware_name = "class_slowpath"; +			break; +		case 1: +			pfe_firmware_name = "tmu_slowpath"; +			break; +		case 2: +			pfe_firmware_name = "util_slowpath"; +			break; +		} + +		if (pfe_get_fw(&raw_image_addr, &raw_image_size, +			       pfe_firmware_name)) { +			printf("%s firmware couldn't be found in FIT image\n", +			       pfe_firmware_name); +			break; +		} +		pfe_firmware = malloc(raw_image_size); +		if (!pfe_firmware) +			return -ENOMEM; +		memcpy((void *)pfe_firmware, (void *)raw_image_addr, +		       raw_image_size); + +		switch (fw_count) { +		case 0: +			env_set_addr("class_elf_firmware", pfe_firmware); +			env_set_addr("class_elf_size", (void *)raw_image_size); +			break; +		case 1: +			env_set_addr("tmu_elf_firmware", pfe_firmware); +			env_set_addr("tmu_elf_size", (void *)raw_image_size); +			break; +		case 2: +			env_set_addr("util_elf_firmware", pfe_firmware); +			env_set_addr("util_elf_size", (void *)raw_image_size); +			break; +		} +	} + +	raw_image_addr = NULL; +	pfe_firmware = NULL; +	raw_image_size = 0;  	for (fw_count = 0; fw_count < 2; fw_count++) {  		if (fw_count == 0)  			pfe_firmware_name = "class"; | 
