// 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 <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(cmd_tbl_t *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_GET_DRIVER(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
