// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright (c) 2024 Linaro Ltd.
 * Author: Sam Protsenko <semen.protsenko@linaro.org>
 *
 * Firmware loading code.
 */

#include <part.h>
#include <linux/arm-smccc.h>
#include "fw.h"

#define EMMC_IFACE		"mmc"
#define EMMC_DEV_NUM		0

/* LDFW constants */
#define LDFW_PART_NAME		"ldfw"
#define LDFW_NWD_ADDR		0x88000000
#define LDFW_MAGIC		0x10adab1e
#define SMC_CMD_LOAD_LDFW	-0x500
#define SDM_HW_RESET_STATUS	0x1230
#define SDM_SW_RESET_STATUS	0x1231
#define SB_ERROR_PREFIX		0xfdaa0000

struct ldfw_header {
	u32 magic;
	u32 size;
	u32 init_entry;
	u32 entry_point;
	u32 suspend_entry;
	u32 resume_entry;
	u32 start_smc_id;
	u32 version;
	u32 set_runtime_entry;
	u32 reserved[3];
	char fw_name[16];
};

static int read_fw(const char *part_name, void *buf)
{
	struct blk_desc *blk_desc;
	struct disk_partition part;
	unsigned long cnt;
	int part_num;

	blk_desc = blk_get_dev(EMMC_IFACE, EMMC_DEV_NUM);
	if (!blk_desc) {
		debug("%s: Can't get eMMC device\n", __func__);
		return -ENODEV;
	}

	part_num = part_get_info_by_name(blk_desc, part_name, &part);
	if (part_num < 0) {
		debug("%s: Can't get LDWF partition\n", __func__);
		return -ENOENT;
	}

	cnt = blk_dread(blk_desc, part.start, part.size, buf);
	if (cnt != part.size) {
		debug("%s: Can't read LDFW partition\n", __func__);
		return -EIO;
	}

	return 0;
}

int load_ldfw(void)
{
	const phys_addr_t addr = (phys_addr_t)LDFW_NWD_ADDR;
	struct ldfw_header *hdr;
	struct arm_smccc_res res;
	void *buf = (void *)addr;
	u64 size = 0;
	int err, i;

	/* Load LDFW from the block device partition into RAM buffer */
	err = read_fw(LDFW_PART_NAME, buf);
	if (err)
		return err;

	/* Validate LDFW by magic number in its header */
	hdr = buf;
	if (hdr->magic != LDFW_MAGIC) {
		debug("%s: Wrong LDFW magic; is LDFW flashed?\n", __func__);
		return -EINVAL;
	}

	/* Calculate actual total size of all LDFW blobs */
	for (i = 0; hdr->magic == LDFW_MAGIC; ++i) {
#ifdef DEBUG
		char name[17] = { 0 };

		strncpy(name, hdr->fw_name, 16);
		debug("%s: ldfw #%d: version = 0x%x, name = %s\n", __func__, i,
		      hdr->version, name);
#endif

		size += (u64)hdr->size;
		hdr = (struct ldfw_header *)((u64)hdr + (u64)hdr->size);
	}
	debug("%s: The whole size of all LDFWs: 0x%llx\n", __func__, size);

	/* Load LDFW firmware to SWD (Secure World) memory via EL3 monitor */
	arm_smccc_smc(SMC_CMD_LOAD_LDFW, addr, size, 0, 0, 0, 0, 0, &res);
	err = (int)res.a0;
	if (err == -1 || err == SDM_HW_RESET_STATUS) {
		debug("%s: Can't load LDFW in dump_gpr state\n", __func__);
		return -EIO;
	} else if (err == SDM_SW_RESET_STATUS) {
		debug("%s: Can't load LDFW in kernel panic (SW RESET) state\n",
		      __func__);
		return -EIO;
	} else if (err < 0 && (err & 0xffff0000) == SB_ERROR_PREFIX) {
		debug("%s: LDFW signature is corrupted! ret=0x%x\n", __func__,
		      (u32)err);
		return -EIO;
	} else if (err == 0) {
		debug("%s: No LDFW is inited\n", __func__);
		return -EIO;
	}

#ifdef DEBUG
	u32 tried = res.a0 & 0xffff;
	u32 failed = (res.a0 >> 16) & 0xffff;

	debug("%s: %d/%d LDFWs have been loaded successfully\n", __func__,
	      tried - failed, tried);
#endif

	return 0;
}
