// 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>
#include <asm/global_data.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 (nand) {
		mtd = get_mtd_device_nm("nand0");
		if (!IS_ERR_OR_NULL(mtd)) {
			const char *mtd_tee = CONFIG_MTDPARTS_NAND0_TEE;
			board_set_mtdparts("nand0", ids, parts,
					   CONFIG_MTDPARTS_NAND0_BOOT,
					   !nor && tee ? mtd_tee : NULL,
					   "-(UBI)");
			put_mtd_device(mtd);
		}
	}

	if (spinand) {
		mtd = get_mtd_device_nm("spi-nand0");
		if (!IS_ERR_OR_NULL(mtd)) {
			const char *mtd_tee = CONFIG_MTDPARTS_SPINAND0_TEE;
			board_set_mtdparts("spi-nand0", ids, parts,
					   CONFIG_MTDPARTS_SPINAND0_BOOT,
					   !nor && tee ? mtd_tee : NULL,
					   "-(UBI)");
			put_mtd_device(mtd);
		}
	}

	if (nor) {
		if (!uclass_get_device(UCLASS_SPI_FLASH, 0, &dev)) {
			const char *mtd_tee = CONFIG_MTDPARTS_NOR0_TEE;
			board_set_mtdparts("nor0", ids, parts,
					   CONFIG_MTDPARTS_NOR0_BOOT,
					   tee ? mtd_tee : NULL,
					   "-(nor_user)");
		}
	}

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