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

#include <common.h>
#include <dfu.h>
#include <dm.h>
#include <env.h>
#include <env_internal.h>
#include <log.h>
#include <mtd.h>
#include <mtd_node.h>
#include <tee.h>
#include <asm/arch/stm32prog.h>
#include <asm/arch/sys_proto.h>

#define MTDPARTS_LEN		256
#define MTDIDS_LEN		128

/*
 * Get a global data pointer
 */
DECLARE_GLOBAL_DATA_PTR;

/**
 * update the variables "mtdids" and "mtdparts" with boot, tee and user strings
 */
static void board_set_mtdparts(const char *dev,
			       char *mtdids,
			       char *mtdparts,
			       const char *boot,
			       const char *tee,
			       const char *user)
{
	/* mtdids: "<dev>=<dev>, ...." */
	if (mtdids[0] != '\0')
		strcat(mtdids, ",");
	strcat(mtdids, dev);
	strcat(mtdids, "=");
	strcat(mtdids, dev);

	/* mtdparts: "mtdparts=<dev>:<mtdparts_<dev>>;..." */
	if (mtdparts[0] != '\0')
		strncat(mtdparts, ";", MTDPARTS_LEN);
	else
		strcat(mtdparts, "mtdparts=");

	strncat(mtdparts, dev, MTDPARTS_LEN);
	strncat(mtdparts, ":", MTDPARTS_LEN);

	if (boot) {
		strncat(mtdparts, boot, MTDPARTS_LEN);
		strncat(mtdparts, ",", MTDPARTS_LEN);
	}

	if (tee) {
		strncat(mtdparts, tee, MTDPARTS_LEN);
		strncat(mtdparts, ",", MTDPARTS_LEN);
	}

	strncat(mtdparts, user, MTDPARTS_LEN);
}

void board_mtdparts_default(const char **mtdids, const char **mtdparts)
{
	struct mtd_info *mtd;
	struct udevice *dev;
	static char parts[3 * MTDPARTS_LEN + 1];
	static char ids[MTDIDS_LEN + 1];
	static bool mtd_initialized;
	bool tee, nor, nand, spinand, serial;

	if (mtd_initialized) {
		*mtdids = ids;
		*mtdparts = parts;
		return;
	}

	tee = false;
	nor = false;
	nand = false;
	spinand = false;
	serial = false;

	switch (get_bootmode() & TAMP_BOOT_DEVICE_MASK) {
	case BOOT_SERIAL_UART:
	case BOOT_SERIAL_USB:
		serial = true;
		if (CONFIG_IS_ENABLED(CMD_STM32PROG)) {
			tee = stm32prog_get_tee_partitions();
			nor = stm32prog_get_fsbl_nor();
		}
		nand = true;
		spinand = true;
		break;
	case BOOT_FLASH_NAND:
		nand = true;
		break;
	case BOOT_FLASH_SPINAND:
		spinand = true;
		break;
	case BOOT_FLASH_NOR:
		nor = true;
		break;
	default:
		break;
	}

	if (!serial && CONFIG_IS_ENABLED(OPTEE) &&
	    tee_find_device(NULL, NULL, NULL, NULL))
		tee = true;

	memset(parts, 0, sizeof(parts));
	memset(ids, 0, sizeof(ids));

	/* probe all MTD devices */
	for (uclass_first_device(UCLASS_MTD, &dev);
	     dev;
	     uclass_next_device(&dev)) {
		log_debug("mtd device = %s\n", dev->name);
	}

	if (nor || nand) {
		mtd = get_mtd_device_nm("nand0");
		if (!IS_ERR_OR_NULL(mtd)) {
			const char *mtd_boot = CONFIG_MTDPARTS_NAND0_BOOT;
			const char *mtd_tee = CONFIG_MTDPARTS_NAND0_TEE;

			board_set_mtdparts("nand0", ids, parts,
					   !nor ? mtd_boot : NULL,
					   !nor && tee ? mtd_tee : NULL,
					   "-(UBI)");
			put_mtd_device(mtd);
		}
	}

	if (nor || spinand) {
		mtd = get_mtd_device_nm("spi-nand0");
		if (!IS_ERR_OR_NULL(mtd)) {
			const char *mtd_boot = CONFIG_MTDPARTS_SPINAND0_BOOT;
			const char *mtd_tee = CONFIG_MTDPARTS_SPINAND0_TEE;

			board_set_mtdparts("spi-nand0", ids, parts,
					   !nor ? mtd_boot : NULL,
					   !nor && tee ? mtd_tee : NULL,
					   "-(UBI)");
			put_mtd_device(mtd);
		}
	}

	if (nor) {
		if (!uclass_get_device(UCLASS_SPI_FLASH, 0, &dev)) {
			const char *mtd_boot = CONFIG_MTDPARTS_NOR0_BOOT;
			const char *mtd_tee = CONFIG_MTDPARTS_NOR0_TEE;

			board_set_mtdparts("nor0", ids, parts,
					   mtd_boot,
					   tee ? mtd_tee : NULL,
					   "-(nor_user)");
		}
	}

	mtd_initialized = true;
	*mtdids = ids;
	*mtdparts = parts;
	log_debug("mtdids=%s & mtdparts=%s\n", ids, parts);
}
