// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
/*
 * Copyright (C) 2019, STMicroelectronics - All Rights Reserved
 *
 * the st command stboard supports the STMicroelectronics board identification
 * saved in OTP 59.
 *
 * The ST product codification have several element
 * - "Commercial Product Name" (CPN): type of product board (DKX, EVX)
 *   associated to the board ID "MBxxxx"
 * - "Finished Good" or "Finish Good" (FG):
 *   effective content of the product without chip STM32MP1xx (LCD, Wifi,…)
 * - BOM: cost variant for same FG (for example, several provider of the same
 *   component)
 *
 * For example
 * - commercial product = STM32MP157C-EV1 for board MB1263
 * - Finished Good = EVA32MP157A1$AU1
 *
 * Both information are written on board and these information are also saved
 * in OTP59, with:
 * bit [31:16] (hex) => Board id, MBxxxx
 * bit [15:12] (dec) => Variant CPN (1....15)
 * bit [11:8]  (dec) => Revision board (index with A = 1, Z = 26)
 * bit [7:4]   (dec) => Variant FG : finished good index
 * bit [3:0]   (dec) => BOM (01, .... 255)
 *
 * and displayed with the format:
 *   Board: MB<Board> Var<VarCPN>.<VarFG> Rev.<Revision>-<BOM>
 */

#ifndef CONFIG_SPL_BUILD
#include <common.h>
#include <command.h>
#include <console.h>
#include <misc.h>
#include <dm/device.h>
#include <dm/uclass.h>

static bool check_stboard(u16 board)
{
	unsigned int i;
	/* list of supported ST boards */
	const u16 st_board_id[] = {
		0x1272,
		0x1263,
		0x1264,
		0x1298,
		0x1341,
		0x1497,
	};

	for (i = 0; i < ARRAY_SIZE(st_board_id); i++)
		if (board == st_board_id[i])
			return true;

	return false;
}

static void display_stboard(u32 otp)
{
	/* display board indentification with OPT coding */
	printf("Board: MB%04x Var%d.%d Rev.%c-%02d\n",
	       otp >> 16,
	       (otp >> 12) & 0xF,
	       (otp >> 4) & 0xF,
	       ((otp >> 8) & 0xF) - 1 + 'A',
	       otp & 0xF);
}

static int do_stboard(struct cmd_tbl *cmdtp, int flag, int argc,
		      char *const argv[])
{
	int ret;
	u32 otp, lock;
	u8 revision;
	unsigned long board, var_cpn, var_fg, bom;
	struct udevice *dev;
	int confirmed = argc == 7 && !strcmp(argv[1], "-y");

	argc -= 1 + confirmed;
	argv += 1 + confirmed;

	if (argc != 0 && argc != 5)
		return CMD_RET_USAGE;

	ret = uclass_get_device_by_driver(UCLASS_MISC,
					  DM_DRIVER_GET(stm32mp_bsec),
					  &dev);

	ret = misc_read(dev, STM32_BSEC_OTP(BSEC_OTP_BOARD),
			&otp, sizeof(otp));

	if (ret < 0) {
		puts("OTP read error");
		return CMD_RET_FAILURE;
	}

	ret = misc_read(dev, STM32_BSEC_LOCK(BSEC_OTP_BOARD),
			&lock, sizeof(lock));
	if (ret < 0) {
		puts("LOCK read error");
		return CMD_RET_FAILURE;
	}

	if (argc == 0) {
		if (!otp)
			puts("Board : OTP board FREE\n");
		else
			display_stboard(otp);
		printf("      OTP %d %s locked !\n", BSEC_OTP_BOARD,
		       lock == 1 ? "" : "NOT");
		return CMD_RET_SUCCESS;
	}

	if (otp) {
		display_stboard(otp);
		printf("ERROR: OTP board not FREE\n");
		return CMD_RET_FAILURE;
	}

	if (strict_strtoul(argv[0], 16, &board) < 0 ||
	    board == 0 || board > 0xFFFF) {
		printf("argument %d invalid: %s\n", 1, argv[0]);
		return CMD_RET_USAGE;
	}

	if (strict_strtoul(argv[1], 10, &var_cpn) < 0 ||
	    var_cpn == 0 || var_cpn > 15) {
		printf("argument %d invalid: %s\n", 2, argv[1]);
		return CMD_RET_USAGE;
	}

	revision = argv[2][0] - 'A' + 1;
	if (strlen(argv[2]) > 1 || revision == 0 || revision > 15) {
		printf("argument %d invalid: %s\n", 3, argv[2]);
		return CMD_RET_USAGE;
	}

	if (strict_strtoul(argv[3], 10, &var_fg) < 0 ||
	    var_fg > 15) {
		printf("argument %d invalid: %s\n", 4, argv[3]);
		return CMD_RET_USAGE;
	}

	if (strict_strtoul(argv[4], 10, &bom) < 0 ||
	    bom == 0 || bom > 15) {
		printf("argument %d invalid: %s\n", 4, argv[3]);
		return CMD_RET_USAGE;
	}

	/* st board indentification value */
	otp = (board << 16) | (var_cpn << 12) | (revision << 8) |
	      (var_fg << 4) | bom;
	display_stboard(otp);
	printf("=> OTP[%d] = %08X\n", BSEC_OTP_BOARD, otp);

	if (!check_stboard((u16)board)) {
		printf("Unknown board MB%04x\n", (u16)board);
		return CMD_RET_FAILURE;
	}
	if (!confirmed) {
		printf("Warning: Programming BOARD in OTP is irreversible!\n");
		printf("Really perform this OTP programming? <y/N>\n");

		if (!confirm_yesno()) {
			puts("BOARD programming aborted\n");
			return CMD_RET_FAILURE;
		}
	}

	ret = misc_write(dev, STM32_BSEC_OTP(BSEC_OTP_BOARD),
			 &otp, sizeof(otp));

	if (ret < 0) {
		puts("BOARD programming error\n");
		return CMD_RET_FAILURE;
	}

	/* write persistent lock */
	otp = 1;
	ret = misc_write(dev, STM32_BSEC_LOCK(BSEC_OTP_BOARD),
			 &otp, sizeof(otp));
	if (ret < 0) {
		puts("BOARD lock error\n");
		return CMD_RET_FAILURE;
	}

	puts("BOARD programming done\n");

	return CMD_RET_SUCCESS;
}

U_BOOT_CMD(stboard, 7, 0, do_stboard,
	   "read/write board reference in OTP",
	   "\n"
	   "  Print current board information\n"
	   "stboard [-y] <Board> <VarCPN> <Revision> <VarFG> <BOM>\n"
	   "  Write board information\n"
	   "  - Board: xxxx, example 1264 for MB1264\n"
	   "  - VarCPN: 1...15\n"
	   "  - Revision: A...O\n"
	   "  - VarFG: 0...15\n"
	   "  - BOM: 1...15\n");

#endif
