/*
 * Copyright (c) 2016 Toradex, Inc.
 *
 * SPDX-License-Identifier:	GPL-2.0+
 */

#include <common.h>
#include "tdx-cfg-block.h"

#if defined(CONFIG_TARGET_APALIS_IMX6) || defined(CONFIG_TARGET_COLIBRI_IMX6)
#include <asm/arch/sys_proto.h>
#else
#define is_cpu_type(cpu) (0)
#endif
#if defined(CONFIG_CPU_PXA27X)
#include <asm/arch-pxa/pxa.h>
#else
#define cpu_is_pxa27x(cpu) (0)
#endif
#include <cli.h>
#include <console.h>
#include <flash.h>
#include <malloc.h>
#include <mmc.h>
#include <nand.h>

DECLARE_GLOBAL_DATA_PTR;

#define TAG_VALID	0xcf01
#define TAG_MAC		0x0000
#define TAG_HW		0x0008
#define TAG_INVALID	0xffff

#define TAG_FLAG_VALID	0x1

#if defined(CONFIG_TDX_CFG_BLOCK_IS_IN_MMC)
#define TDX_CFG_BLOCK_MAX_SIZE 512
#elif defined(CONFIG_TDX_CFG_BLOCK_IS_IN_NAND)
#define TDX_CFG_BLOCK_MAX_SIZE 64
#elif defined(CONFIG_TDX_CFG_BLOCK_IS_IN_NOR)
#define TDX_CFG_BLOCK_MAX_SIZE 64
#else
#error Toradex config block location not set
#endif

struct toradex_tag {
	u32 len:14;
	u32 flags:2;
	u32 id:16;
};

bool valid_cfgblock;
struct toradex_hw tdx_hw_tag;
struct toradex_eth_addr tdx_eth_addr;
u32 tdx_serial;

const char * const toradex_modules[] = {
	 [0] = "UNKNOWN MODULE",
	 [1] = "Colibri PXA270 312MHz",
	 [2] = "Colibri PXA270 520MHz",
	 [3] = "Colibri PXA320 806MHz",
	 [4] = "Colibri PXA300 208MHz",
	 [5] = "Colibri PXA310 624MHz",
	 [6] = "Colibri PXA320 806MHz IT",
	 [7] = "Colibri PXA300 208MHz XT",
	 [8] = "Colibri PXA270 312MHz",
	 [9] = "Colibri PXA270 520MHz",
	[10] = "Colibri VF50 128MB", /* not currently on sale */
	[11] = "Colibri VF61 256MB",
	[12] = "Colibri VF61 256MB IT",
	[13] = "Colibri VF50 128MB IT",
	[14] = "Colibri iMX6 Solo 256MB",
	[15] = "Colibri iMX6 DualLite 512MB",
	[16] = "Colibri iMX6 Solo 256MB IT",
	[17] = "Colibri iMX6 DualLite 512MB IT",
	[18] = "UNKNOWN MODULE",
	[19] = "UNKNOWN MODULE",
	[20] = "Colibri T20 256MB",
	[21] = "Colibri T20 512MB",
	[22] = "Colibri T20 512MB IT",
	[23] = "Colibri T30 1GB",
	[24] = "Colibri T20 256MB IT",
	[25] = "Apalis T30 2GB",
	[26] = "Apalis T30 1GB",
	[27] = "Apalis iMX6 Quad 1GB",
	[28] = "Apalis iMX6 Quad 2GB IT",
	[29] = "Apalis iMX6 Dual 512MB",
	[30] = "Colibri T30 1GB IT",
	[31] = "Apalis T30 1GB IT",
	[32] = "Colibri iMX7 Solo 256MB",
	[33] = "Colibri iMX7 Dual 512MB",
	[34] = "Apalis TK1 2GB",
	[35] = "Apalis iMX6 Dual 1GB IT",
};

#ifdef CONFIG_TDX_CFG_BLOCK_IS_IN_MMC
static int tdx_cfg_block_mmc_storage(u8 *config_block, int write)
{
	struct mmc *mmc;
	int dev = CONFIG_TDX_CFG_BLOCK_DEV;
	int offset = CONFIG_TDX_CFG_BLOCK_OFFSET;
	uint part = CONFIG_TDX_CFG_BLOCK_PART;
	uint blk_start;
	int ret = 0;

	/* Read production parameter config block from eMMC */
	mmc = find_mmc_device(dev);
	if (!mmc) {
		puts("No MMC card found\n");
		ret = -ENODEV;
		goto out;
	}
	if (part != mmc->block_dev.hwpart) {
		if (blk_select_hwpart_devnum(IF_TYPE_MMC, dev, part)) {
			puts("MMC partition switch failed\n");
			ret = -ENODEV;
			goto out;
		}
	}
	if (offset < 0)
		offset += mmc->capacity;
	blk_start = ALIGN(offset, mmc->write_bl_len) / mmc->write_bl_len;

	if (!write) {
		/* Careful reads a whole block of 512 bytes into config_block */
		if (blk_dread(mmc_get_blk_desc(mmc), blk_start, 1,
			      (unsigned char *)config_block) != 1) {
			ret = -EIO;
			goto out;
		}
		/* Flush cache after read */
		flush_cache((ulong)(unsigned char *)config_block, 512);
	} else {
		/* Just writing one 512 byte block */
		if (blk_dwrite(mmc_get_blk_desc(mmc), blk_start, 1,
			       (unsigned char *)config_block) != 1) {
			ret = -EIO;
			goto out;
		}
	}

out:
	/* Switch back to regular eMMC user partition */
	blk_select_hwpart_devnum(IF_TYPE_MMC, 0, 0);

	return ret;
}
#endif

#ifdef CONFIG_TDX_CFG_BLOCK_IS_IN_NAND
static int read_tdx_cfg_block_from_nand(unsigned char *config_block)
{
	size_t size = TDX_CFG_BLOCK_MAX_SIZE;

	/* Read production parameter config block from NAND page */
	return nand_read_skip_bad(nand_info[0], CONFIG_TDX_CFG_BLOCK_OFFSET,
			 &size, NULL, TDX_CFG_BLOCK_MAX_SIZE, config_block);
}

static int write_tdx_cfg_block_to_nand(unsigned char *config_block)
{
	size_t size = TDX_CFG_BLOCK_MAX_SIZE;

	/* Write production parameter config block to NAND page */
	return nand_write_skip_bad(nand_info[0], CONFIG_TDX_CFG_BLOCK_OFFSET,
				   &size, NULL, TDX_CFG_BLOCK_MAX_SIZE,
				   config_block, WITH_WR_VERIFY);
}
#endif

#ifdef CONFIG_TDX_CFG_BLOCK_IS_IN_NOR
static int read_tdx_cfg_block_from_nor(unsigned char *config_block)
{
	/* Read production parameter config block from NOR flash */
	memcpy(config_block, (void *)CONFIG_TDX_CFG_BLOCK_OFFSET,
	       TDX_CFG_BLOCK_MAX_SIZE);
	return 0;
}

static int write_tdx_cfg_block_to_nor(unsigned char *config_block)
{
	/* Write production parameter config block to NOR flash */
	return flash_write((void *)config_block, CONFIG_TDX_CFG_BLOCK_OFFSET,
			   TDX_CFG_BLOCK_MAX_SIZE);
}
#endif

int read_tdx_cfg_block(void)
{
	int ret = 0;
	u8 *config_block = NULL;
	struct toradex_tag *tag;
	size_t size = TDX_CFG_BLOCK_MAX_SIZE;
	int offset;

	/* Allocate RAM area for config block */
	config_block = memalign(ARCH_DMA_MINALIGN, size);
	if (!config_block) {
		printf("Not enough malloc space available!\n");
		return -ENOMEM;
	}

	memset(config_block, 0, size);

#if defined(CONFIG_TDX_CFG_BLOCK_IS_IN_MMC)
	ret = tdx_cfg_block_mmc_storage(config_block, 0);
#elif defined(CONFIG_TDX_CFG_BLOCK_IS_IN_NAND)
	ret = read_tdx_cfg_block_from_nand(config_block);
#elif defined(CONFIG_TDX_CFG_BLOCK_IS_IN_NOR)
	ret = read_tdx_cfg_block_from_nor(config_block);
#else
	ret = -EINVAL;
#endif
	if (ret)
		goto out;

	/* Expect a valid tag first */
	tag = (struct toradex_tag *)config_block;
	if (tag->flags != TAG_FLAG_VALID || tag->id != TAG_VALID) {
		valid_cfgblock = false;
		ret = -EINVAL;
		goto out;
	}
	valid_cfgblock = true;
	offset = 4;

	while (offset < TDX_CFG_BLOCK_MAX_SIZE) {
		tag = (struct toradex_tag *)(config_block + offset);
		offset += 4;
		if (tag->id == TAG_INVALID)
			break;

		if (tag->flags == TAG_FLAG_VALID) {
			switch (tag->id) {
			case TAG_MAC:
				memcpy(&tdx_eth_addr, config_block + offset,
				       6);

				/* NIC part of MAC address is serial number */
				tdx_serial = ntohl(tdx_eth_addr.nic) >> 8;
				break;
			case TAG_HW:
				memcpy(&tdx_hw_tag, config_block + offset, 8);
				break;
			}
		}

		/* Get to next tag according to current tags length */
		offset += tag->len * 4;
	}

	/* Cap product id to avoid issues with a yet unknown one */
	if (tdx_hw_tag.prodid > (sizeof(toradex_modules) /
				  sizeof(toradex_modules[0])))
		tdx_hw_tag.prodid = 0;

out:
	free(config_block);
	return ret;
}

static int get_cfgblock_interactive(void)
{
	char message[CONFIG_SYS_CBSIZE];
	char *soc;
	char it = 'n';
	int len;

	if (cpu_is_pxa27x())
		sprintf(message, "Is the module the 312 MHz version? [y/N] ");
	else
		sprintf(message, "Is the module an IT version? [y/N] ");

	len = cli_readline(message);
	it = console_buffer[0];

	soc = getenv("soc");
	if (!strcmp("mx6", soc)) {
#ifdef CONFIG_MACH_TYPE
		if (it == 'y' || it == 'Y')
			if (is_cpu_type(MXC_CPU_MX6Q))
				tdx_hw_tag.prodid = APALIS_IMX6Q_IT;
			else
				tdx_hw_tag.prodid = APALIS_IMX6D_IT;
		else
			if (is_cpu_type(MXC_CPU_MX6Q))
				tdx_hw_tag.prodid = APALIS_IMX6Q;
			else
				tdx_hw_tag.prodid = APALIS_IMX6D;
#else
		if (it == 'y' || it == 'Y')
			if (is_cpu_type(MXC_CPU_MX6DL))
				tdx_hw_tag.prodid = COLIBRI_IMX6DL_IT;
			else
				tdx_hw_tag.prodid = COLIBRI_IMX6S_IT;
		else
			if (is_cpu_type(MXC_CPU_MX6DL))
				tdx_hw_tag.prodid = COLIBRI_IMX6DL;
			else
				tdx_hw_tag.prodid = COLIBRI_IMX6S;
#endif /* CONFIG_MACH_TYPE */
	} else if (!strcmp("imx7d", soc)) {
		tdx_hw_tag.prodid = COLIBRI_IMX7D;
	} else if (!strcmp("imx7s", soc)) {
		tdx_hw_tag.prodid = COLIBRI_IMX7S;
	} else if (!strcmp("tegra20", soc)) {
		if (it == 'y' || it == 'Y')
			if (gd->ram_size == 0x10000000)
				tdx_hw_tag.prodid = COLIBRI_T20_256MB_IT;
			else
				tdx_hw_tag.prodid = COLIBRI_T20_512MB_IT;
		else
			if (gd->ram_size == 0x10000000)
				tdx_hw_tag.prodid = COLIBRI_T20_256MB;
			else
				tdx_hw_tag.prodid = COLIBRI_T20_512MB;
	} else if (cpu_is_pxa27x()) {
		if (it == 'y' || it == 'Y')
			tdx_hw_tag.prodid = COLIBRI_PXA270_312MHZ;
		else
			tdx_hw_tag.prodid = COLIBRI_PXA270_520MHZ;
#ifdef CONFIG_MACH_TYPE
	} else if (!strcmp("tegra30", soc)) {
		if (CONFIG_MACH_TYPE == MACH_TYPE_APALIS_T30) {
			if (it == 'y' || it == 'Y')
				tdx_hw_tag.prodid = APALIS_T30_IT;
			else
				if (gd->ram_size == 0x40000000)
					tdx_hw_tag.prodid = APALIS_T30_1GB;
				else
					tdx_hw_tag.prodid = APALIS_T30_2GB;
		} else {
			if (it == 'y' || it == 'Y')
				tdx_hw_tag.prodid = COLIBRI_T30_IT;
			else
				tdx_hw_tag.prodid = COLIBRI_T30;
		}
#endif /* CONFIG_MACH_TYPE */
	} else if (!strcmp("tegra124", soc)) {
		tdx_hw_tag.prodid = APALIS_TK1_2GB;
	} else if (!strcmp("vf500", soc)) {
		if (it == 'y' || it == 'Y')
			tdx_hw_tag.prodid = COLIBRI_VF50_IT;
		else
			tdx_hw_tag.prodid = COLIBRI_VF50;
	} else if (!strcmp("vf610", soc)) {
		if (it == 'y' || it == 'Y')
			tdx_hw_tag.prodid = COLIBRI_VF61_IT;
		else
			tdx_hw_tag.prodid = COLIBRI_VF61;
	} else {
		printf("Module type not detectable due to unknown SoC\n");
		return -1;
	}

	while (len < 4) {
		sprintf(message, "Enter the module version (e.g. V1.1B): V");
		len = cli_readline(message);
	}

	tdx_hw_tag.ver_major = console_buffer[0] - '0';
	tdx_hw_tag.ver_minor = console_buffer[2] - '0';
	tdx_hw_tag.ver_assembly = console_buffer[3] - 'A';

	if (cpu_is_pxa27x() && (tdx_hw_tag.ver_major == 1))
		tdx_hw_tag.prodid -= (COLIBRI_PXA270_312MHZ -
				       COLIBRI_PXA270_V1_312MHZ);

	while (len < 8) {
		sprintf(message, "Enter module serial number: ");
		len = cli_readline(message);
	}

	tdx_serial = simple_strtoul(console_buffer, NULL, 10);

	return 0;
}

static int get_cfgblock_barcode(char *barcode)
{
	if (strlen(barcode) < 16) {
		printf("Argument too short, barcode is 16 chars long\n");
		return -1;
	}

	/* Get hardware information from the first 8 digits */
	tdx_hw_tag.ver_major = barcode[4] - '0';
	tdx_hw_tag.ver_minor = barcode[5] - '0';
	tdx_hw_tag.ver_assembly = barcode[7] - '0';

	barcode[4] = '\0';
	tdx_hw_tag.prodid = simple_strtoul(barcode, NULL, 10);

	/* Parse second part of the barcode (serial number */
	barcode += 8;
	tdx_serial = simple_strtoul(barcode, NULL, 10);

	return 0;
}

static int do_cfgblock_create(cmd_tbl_t *cmdtp, int flag, int argc,
			      char * const argv[])
{
	u8 *config_block;
	struct toradex_tag *tag;
	size_t size = TDX_CFG_BLOCK_MAX_SIZE;
	int offset = 0;
	int ret = CMD_RET_SUCCESS;
	int err;

	/* Allocate RAM area for config block */
	config_block = memalign(ARCH_DMA_MINALIGN, size);
	if (!config_block) {
		printf("Not enough malloc space available!\n");
		return CMD_RET_FAILURE;
	}

	memset(config_block, 0xff, size);

	read_tdx_cfg_block();
	if (valid_cfgblock) {
#if defined(CONFIG_TDX_CFG_BLOCK_IS_IN_NAND)
		/*
		 * On NAND devices, recreation is only allowed if the page is
		 * empty (config block invalid...)
		 */
		printf("NAND erase block %d need to be erased before creating a Toradex config block\n",
		       CONFIG_TDX_CFG_BLOCK_OFFSET / nand_info[0]->erasesize);
		goto out;
#elif defined(CONFIG_TDX_CFG_BLOCK_IS_IN_NOR)
		/*
		 * On NOR devices, recreation is only allowed if the sector is
		 * empty and write protection is off (config block invalid...)
		 */
		printf("NOR sector at offset 0x%02x need to be erased and unprotected before creating a Toradex config block\n",
		       CONFIG_TDX_CFG_BLOCK_OFFSET);
		goto out;
#else
		char message[CONFIG_SYS_CBSIZE];
		sprintf(message,
			"A valid Toradex config block is present, still recreate? [y/N] ");

		if (!cli_readline(message))
			goto out;

		if (console_buffer[0] != 'y' && console_buffer[0] != 'Y')
			goto out;
#endif
	}

	/* Parse new Toradex config block data... */
	if (argc < 3)
		err = get_cfgblock_interactive();
	else
		err = get_cfgblock_barcode(argv[2]);

	if (err) {
		ret = CMD_RET_FAILURE;
		goto out;
	}

	/* Convert serial number to MAC address (the storage format) */
	tdx_eth_addr.oui = htonl(0x00142dUL << 8);
	tdx_eth_addr.nic = htonl(tdx_serial << 8);

	/* Valid Tag */
	tag = (struct toradex_tag *)config_block;
	tag->id = TAG_VALID;
	tag->flags = TAG_FLAG_VALID;
	tag->len = 0;
	offset += 4;

	/* Product Tag */
	tag = (struct toradex_tag *)(config_block + offset);
	tag->id = TAG_HW;
	tag->flags = TAG_FLAG_VALID;
	tag->len = 2;
	offset += 4;

	memcpy(config_block + offset, &tdx_hw_tag, 8);
	offset += 8;

	/* MAC Tag */
	tag = (struct toradex_tag *)(config_block + offset);
	tag->id = TAG_MAC;
	tag->flags = TAG_FLAG_VALID;
	tag->len = 2;
	offset += 4;

	memcpy(config_block + offset, &tdx_eth_addr, 6);
	offset += 6;
	memset(config_block + offset, 0, 32 - offset);

#if defined(CONFIG_TDX_CFG_BLOCK_IS_IN_MMC)
	err = tdx_cfg_block_mmc_storage(config_block, 1);
#elif defined(CONFIG_TDX_CFG_BLOCK_IS_IN_NAND)
	err = write_tdx_cfg_block_to_nand(config_block);
#elif defined(CONFIG_TDX_CFG_BLOCK_IS_IN_NOR)
	err = write_tdx_cfg_block_to_nor(config_block);
#else
	err = -EINVAL;
#endif
	if (err) {
		printf("Failed to write Toradex config block: %d\n", ret);
		ret = CMD_RET_FAILURE;
		goto out;
	}

	printf("Toradex config block successfully written\n");

out:
	free(config_block);
	return ret;
}

static int do_cfgblock(cmd_tbl_t *cmdtp, int flag, int argc,
		       char * const argv[])
{
	int ret;

	if (argc < 2)
		return CMD_RET_USAGE;

	if (!strcmp(argv[1], "create")) {
		return do_cfgblock_create(cmdtp, flag, argc, argv);
	} else if (!strcmp(argv[1], "reload")) {
		ret = read_tdx_cfg_block();
		if (ret) {
			printf("Failed to reload Toradex config block: %d\n",
			       ret);
			return CMD_RET_FAILURE;
		}
		return CMD_RET_SUCCESS;
	}

	return CMD_RET_USAGE;
}

U_BOOT_CMD(
	cfgblock, 3, 0, do_cfgblock,
	"Toradex config block handling commands",
	"create [barcode] - (Re-)create Toradex config block\n"
	"cfgblock reload - Reload Toradex config block from flash"
);
