Add command to configure the board ID

The board id is written to OTP byte address 512

Change-Id: If46463e8b4394c15ee4086aa0a19bc1e426b2a6d
diff --git a/commands/otp_key.c b/commands/otp_key.c
index cf89599..09cce55 100644
--- a/commands/otp_key.c
+++ b/commands/otp_key.c
@@ -29,6 +29,7 @@
 #include <fcntl.h>
 #include <fs.h>
 #include <malloc.h>
+#include <board_id.h>
 
 #define OTP_KEY_SIZE_BYTES	256
 #define OTP_KEY_SIZE_BITS	(OTP_KEY_SIZE_BYTES * 8)
@@ -375,3 +376,51 @@
 	.usage		= "print OTP config bytes",
 	BAREBOX_CMD_HELP(cmd_print_otp_config_help)
 BAREBOX_CMD_END
+
+static int do_set_otp_board_id(struct command *cmdtp, int argc,
+				char *argv[]) {
+	int board_id;
+	uint32_t board_id_otp;
+	uint8_t bit_array[32];
+
+	if (argc != 2)
+		return COMMAND_ERROR_USAGE;
+
+	board_id = simple_strtoul(argv[1], NULL, 0);
+
+	/* Writing the board ID is irreversible, verify the provided board ID
+	   matches the GPIO configuration */
+	if (board_id != get_board_id_gpio()) {
+		printf("Given board ID does not match GPIO board ID: %d\n",
+			get_board_id_gpio());
+		return 1;
+	}
+
+	if (board_id == OPTIMUS_BOARD_ID) {
+		board_id_otp = OPTIMUS_BOARD_ID_OTP;
+	} else if (board_id == SIDESWIPE_BOARD_ID) {
+		board_id_otp = SIDESWIPE_BOARD_ID_OTP;
+	} else if (board_id == SPACECAST_BOARD_ID) {
+		board_id_otp = SPACECAST_BOARD_ID_OTP;
+	} else {
+		printf("Unsupported board: %d\n", board_id);
+		return 1;
+	}
+
+	/* Write the key id to the OTP. */
+	_convert_to_bit_array((uint8_t *)&board_id_otp, 4, bit_array);
+	otp_write(OTP_OFFSET_BOARD_ID, bit_array, 32);
+
+	return 0;
+}
+
+static const __maybe_unused char cmd_set_otp_board_id_help[] =
+"Usage: set_otp_board_id <id>\n"
+"Set the board id in the OTP.\n"
+"WARNING: This cannot be undone!\n";
+
+BAREBOX_CMD_START(set_board_id)
+	.cmd		= do_set_otp_board_id,
+	.usage		= "set the device id in the OTP",
+	BAREBOX_CMD_HELP(cmd_set_otp_board_id_help)
+BAREBOX_CMD_END
diff --git a/include/board_id.h b/include/board_id.h
index c243042..ce36517 100644
--- a/include/board_id.h
+++ b/include/board_id.h
@@ -5,6 +5,10 @@
 #define SIDESWIPE_BOARD_ID	1
 #define SPACECAST_BOARD_ID	2
 
+#define OPTIMUS_BOARD_ID_OTP	(1 << OPTIMUS_BOARD_ID)
+#define SIDESWIPE_BOARD_ID_OTP	(1 << SIDESWIPE_BOARD_ID)
+#define SPACECAST_BOARD_ID_OTP	(1 << SPACECAST_BOARD_ID)
+
 int get_board_id(void);
 int get_board_id_gpio(void);
 
diff --git a/include/c2k_otp.h b/include/c2k_otp.h
index 8ee00c6..6f564dd 100644
--- a/include/c2k_otp.h
+++ b/include/c2k_otp.h
@@ -3,6 +3,9 @@
 
 #include <common.h>
 
+/* OTP addresses holding the the board id */
+#define OTP_OFFSET_BOARD_ID	(512 * 8) /* 32-bit / 4 bytes */
+
 int otp_read(u32 s_addr, u8 *read_data, int size) ;
 int otp_write(u32 offset, u8 *prog_data, int size);
 int otp_lock(void);