// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
/*
 * Copyright (C) 2020, STMicroelectronics - All Rights Reserved
 */

#include <common.h>
#include <blk.h>
#include <dfu.h>
#include <env.h>
#include <memalign.h>
#include <misc.h>
#include <mtd.h>
#include <mtd_node.h>
#include <asm/arch/stm32prog.h>

#define DFU_ALT_BUF_LEN SZ_1K

static void board_get_alt_info_mmc(struct udevice *dev, char *buf)
{
	disk_partition_t info;
	int p, len, devnum;
	bool first = true;
	const char *name;
	struct mmc *mmc;
	struct blk_desc *desc;

	mmc = mmc_get_mmc_dev(dev);
	if (!mmc)
		return;

	if (mmc_init(mmc))
		return;

	desc = mmc_get_blk_desc(mmc);
	if (!desc)
		return;

	name = blk_get_if_type_name(desc->if_type);
	devnum = desc->devnum;
	len = strlen(buf);

	if (buf[0] != '\0')
		len += snprintf(buf + len,
				DFU_ALT_BUF_LEN - len, "&");
	len += snprintf(buf + len, DFU_ALT_BUF_LEN - len,
			 "%s %d=", name, devnum);

	if (IS_MMC(mmc) && mmc->capacity_boot) {
		len += snprintf(buf + len, DFU_ALT_BUF_LEN - len,
				"%s%d_boot1 raw 0x0 0x%llx mmcpart 1;",
				name, devnum, mmc->capacity_boot);
		len += snprintf(buf + len, DFU_ALT_BUF_LEN - len,
				"%s%d_boot2 raw 0x0 0x%llx mmcpart 2",
				name, devnum, mmc->capacity_boot);
		first = false;
	}

	for (p = 1; p < MAX_SEARCH_PARTITIONS; p++) {
		if (part_get_info(desc, p, &info))
			continue;
		if (!first)
			len += snprintf(buf + len, DFU_ALT_BUF_LEN - len, ";");
		first = false;
		len += snprintf(buf + len, DFU_ALT_BUF_LEN - len,
				"%s%d_%s part %d %d",
				name, devnum, info.name, devnum, p);
	}
}

static void board_get_alt_info_mtd(struct mtd_info *mtd, char *buf)
{
	struct mtd_info *part;
	bool first = true;
	const char *name;
	int len, partnum = 0;

	name = mtd->name;
	len = strlen(buf);

	if (buf[0] != '\0')
		len += snprintf(buf + len, DFU_ALT_BUF_LEN - len, "&");
	len += snprintf(buf + len, DFU_ALT_BUF_LEN - len,
			"mtd %s=", name);

	len += snprintf(buf + len, DFU_ALT_BUF_LEN - len,
			"%s raw 0x0 0x%llx ",
			name, mtd->size);

	list_for_each_entry(part, &mtd->partitions, node) {
		partnum++;
		if (!first)
			len += snprintf(buf + len, DFU_ALT_BUF_LEN - len, ";");
		first = false;

		len += snprintf(buf + len, DFU_ALT_BUF_LEN - len,
				"%s_%s part %d",
				name, part->name, partnum);
	}
}

void set_dfu_alt_info(char *interface, char *devstr)
{
	struct udevice *dev;
	struct mtd_info *mtd;

	ALLOC_CACHE_ALIGN_BUFFER(char, buf, DFU_ALT_BUF_LEN);

	if (env_get("dfu_alt_info"))
		return;

	memset(buf, 0, sizeof(buf));

	snprintf(buf, DFU_ALT_BUF_LEN,
		 "ram 0=%s", CONFIG_DFU_ALT_RAM0);

	if (!uclass_get_device(UCLASS_MMC, 0, &dev))
		board_get_alt_info_mmc(dev, buf);

	if (!uclass_get_device(UCLASS_MMC, 1, &dev))
		board_get_alt_info_mmc(dev, buf);

	if (CONFIG_IS_ENABLED(MTD)) {
		/* probe all MTD devices */
		mtd_probe_devices();

		/* probe SPI flash device on a bus */
		if (!uclass_get_device(UCLASS_SPI_FLASH, 0, &dev)) {
			mtd = get_mtd_device_nm("nor0");
			if (!IS_ERR_OR_NULL(mtd))
				board_get_alt_info_mtd(mtd, buf);
		}

		mtd = get_mtd_device_nm("nand0");
		if (!IS_ERR_OR_NULL(mtd))
			board_get_alt_info_mtd(mtd, buf);

		mtd = get_mtd_device_nm("spi-nand0");
		if (!IS_ERR_OR_NULL(mtd))
			board_get_alt_info_mtd(mtd, buf);
	}

#ifdef CONFIG_DFU_VIRT
	strncat(buf, "&virt 0=OTP", DFU_ALT_BUF_LEN);

	if (IS_ENABLED(CONFIG_PMIC_STPMIC1))
		strncat(buf, "&virt 1=PMIC", DFU_ALT_BUF_LEN);
#endif

	env_set("dfu_alt_info", buf);
	puts("DFU alt info setting: done\n");
}

#if CONFIG_IS_ENABLED(DFU_VIRT)
#include <dfu.h>
#include <power/stpmic1.h>

static int dfu_otp_read(u64 offset, u8 *buffer, long *size)
{
	struct udevice *dev;
	int ret;

	ret = uclass_get_device_by_driver(UCLASS_MISC,
					  DM_GET_DRIVER(stm32mp_bsec),
					  &dev);
	if (ret)
		return ret;

	ret = misc_read(dev, offset + STM32_BSEC_OTP_OFFSET, buffer, *size);
	if (ret >= 0) {
		*size = ret;
		ret = 0;
	}

	return 0;
}

static int dfu_pmic_read(u64 offset, u8 *buffer, long *size)
{
	int ret;
#ifdef CONFIG_PMIC_STPMIC1
	struct udevice *dev;

	ret = uclass_get_device_by_driver(UCLASS_MISC,
					  DM_GET_DRIVER(stpmic1_nvm),
					  &dev);
	if (ret)
		return ret;

	ret = misc_read(dev, 0xF8 + offset, buffer, *size);
	if (ret >= 0) {
		*size = ret;
		ret = 0;
	}
	if (ret == -EACCES) {
		*size = 0;
		ret = 0;
	}
#else
	pr_err("PMIC update not supported");
	ret = -EOPNOTSUPP;
#endif

	return ret;
}

int dfu_read_medium_virt(struct dfu_entity *dfu, u64 offset,
			 void *buf, long *len)
{
	switch (dfu->data.virt.dev_num) {
	case 0x0:
		return dfu_otp_read(offset, buf, len);
	case 0x1:
		return dfu_pmic_read(offset, buf, len);
	}

	if (CONFIG_IS_ENABLED(CMD_STM32PROG) &&
	    dfu->data.virt.dev_num >= STM32PROG_VIRT_FIRST_DEV_NUM)
		return stm32prog_read_medium_virt(dfu, offset, buf, len);

	*len = 0;
	return 0;
}

int dfu_write_medium_virt(struct dfu_entity *dfu, u64 offset,
			  void *buf, long *len)
{
	if (CONFIG_IS_ENABLED(CMD_STM32PROG) &&
	    dfu->data.virt.dev_num >= STM32PROG_VIRT_FIRST_DEV_NUM)
		return stm32prog_write_medium_virt(dfu, offset, buf, len);

	return -EOPNOTSUPP;
}

int __weak dfu_get_medium_size_virt(struct dfu_entity *dfu, u64 *size)
{
	if (CONFIG_IS_ENABLED(CMD_STM32PROG) &&
	    dfu->data.virt.dev_num >= STM32PROG_VIRT_FIRST_DEV_NUM)
		return stm32prog_get_medium_size_virt(dfu, size);

	*size = SZ_1K;

	return 0;
}

#endif
