// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright 2016 Freescale Semiconductor, Inc.
 */
#include <asm/io.h>
#include <env.h>
#include <fsl_qe.h>	/* For struct qe_firmware */

#ifdef CONFIG_SYS_DPAA_FMAN
/**
 * fdt_fixup_fman_firmware -- insert the Fman firmware into the device tree
 *
 * The binding for an Fman firmware node is documented in
 * Documentation/powerpc/dts-bindings/fsl/dpaa/fman.txt.  This node contains
 * the actual Fman firmware binary data.  The operating system is expected to
 * be able to parse the binary data to determine any attributes it needs.
 */
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 = env_get("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
