ARC: HSDK-4xD: add initial board support

Add initial HSDK-4xD board support.
The ARC HS4x/HS4xD Development Kit includes a multicore ARC HS4xD-based
chip that integrates a wide range of interfaces including Ethernet,
HDMI, WiFi, Bluetooth, USB, SDIO, I2C, SPI, UART, I2S, ADC, PWM and
GPIO, as well as a Think Silicon GPU.

Signed-off-by: Eugeniy Paltsev <Eugeniy.Paltsev@synopsys.com>
Signed-off-by: Alexey Brodkin <abrodkin@synopsys.com>
diff --git a/board/synopsys/hsdk/Kconfig b/board/synopsys/hsdk/Kconfig
index e8c00a6..5e23b32 100644
--- a/board/synopsys/hsdk/Kconfig
+++ b/board/synopsys/hsdk/Kconfig
@@ -9,4 +9,21 @@
 config SYS_CONFIG_NAME
 	default "hsdk"
 
+choice
+	prompt "HSDK board type"
+	default BOARD_HSDK
+
+config BOARD_HSDK
+	bool "ARC HS Development Kit"
+	help
+	  ARC HS Development Kit based on quard core ARC HS38 processor
+
+config BOARD_HSDK_4XD
+	bool "ARC HS4x/HS4xD Development Kit"
+	help
+	  ARC HS4x/HS4xD Development Kit based on quard core ARC HS48/HS47D
+	  processor
+
+endchoice
+
 endif
diff --git a/board/synopsys/hsdk/MAINTAINERS b/board/synopsys/hsdk/MAINTAINERS
index e22bd1e..d385951 100644
--- a/board/synopsys/hsdk/MAINTAINERS
+++ b/board/synopsys/hsdk/MAINTAINERS
@@ -1,5 +1,6 @@
-HSDK BOARD
+HSDK BOARDs
 M:	Eugeniy Paltsev <paltsev@synopsys.com>
 S:	Maintained
 F:	board/synopsys/hsdk/
 F:	configs/hsdk_defconfig
+F:	configs/hsdk_4xd_defconfig
diff --git a/board/synopsys/hsdk/config.mk b/board/synopsys/hsdk/config.mk
index 5ae22fa..1d01ef5 100644
--- a/board/synopsys/hsdk/config.mk
+++ b/board/synopsys/hsdk/config.mk
@@ -2,9 +2,17 @@
 #
 # Copyright (C) 2018 Synopsys, Inc. All rights reserved.
 
+ifdef CONFIG_BOARD_HSDK
 PLATFORM_CPPFLAGS += -mcpu=hs38_linux -mlittle-endian -matomic -mll64 \
                      -mdiv-rem -mswap -mnorm -mmpy-option=9 -mbarrel-shifter \
                      -mfpu=fpud_all
+endif
+
+ifdef CONFIG_BOARD_HSDK_4XD
+PLATFORM_CPPFLAGS += -mcpu=hs4x_rel31 -mlittle-endian -matomic -mll64 \
+                     -mdiv-rem -mswap -mnorm -mmpy-option=9 -mbarrel-shifter \
+                     -mfpu=fpud_all
+endif
 
 bsp-generate: u-boot u-boot.bin
 	$(Q)python3 $(srctree)/board/$(BOARDDIR)/headerize-hsdk.py \
diff --git a/board/synopsys/hsdk/hsdk.c b/board/synopsys/hsdk/hsdk.c
index 67a29e3..771f7bb 100644
--- a/board/synopsys/hsdk/hsdk.c
+++ b/board/synopsys/hsdk/hsdk.c
@@ -154,6 +154,56 @@
 	{}
 };
 
+enum board_type {
+	T_BOARD_NONE,
+	T_BOARD_HSDK,
+	T_BOARD_HSDK_4XD
+};
+
+static inline enum board_type get_board_type_runtime(void)
+{
+	u32 arc_id = read_aux_reg(ARC_AUX_IDENTITY) & 0xFF;
+
+	if (arc_id == 0x52)
+		return T_BOARD_HSDK;
+	else if (arc_id == 0x54)
+		return T_BOARD_HSDK_4XD;
+	else
+		return T_BOARD_NONE;
+}
+
+static inline enum board_type get_board_type_config(void)
+{
+	if (IS_ENABLED(CONFIG_BOARD_HSDK))
+		return T_BOARD_HSDK;
+	else if (IS_ENABLED(CONFIG_BOARD_HSDK_4XD))
+		return T_BOARD_HSDK_4XD;
+	else
+		return T_BOARD_NONE;
+}
+
+static bool is_board_match_runtime(enum board_type type_req)
+{
+	return get_board_type_runtime() == type_req;
+}
+
+static const char * board_name(enum board_type type)
+{
+	switch (type) {
+		case T_BOARD_HSDK:
+			return "ARC HS Development Kit";
+		case T_BOARD_HSDK_4XD:
+			return "ARC HS4x/HS4xD Development Kit";
+		default:
+			return "?";
+	}
+}
+
+static bool board_mismatch(void)
+{
+	return get_board_type_config() != get_board_type_runtime();
+}
+
 static void sync_cross_cpu_data(void)
 {
 	u32 value;
@@ -221,7 +271,9 @@
 
 	flush_dcache_all();
 	write_aux_reg(ARC_AUX_NON_VOLATILE_LIMIT, val);
-	write_aux_reg(AUX_AUX_CACHE_LIMIT, val);
+	/* AUX_AUX_CACHE_LIMIT reg is missing starting from HS48 */
+	if (is_board_match_runtime(T_BOARD_HSDK))
+		write_aux_reg(AUX_AUX_CACHE_LIMIT, val);
 	flush_n_invalidate_dcache_all();
 }
 
@@ -758,6 +810,11 @@
 {
 	int ret;
 
+	if (board_mismatch()) {
+		printf("ERR: U-boot is not configured for this board!\n");
+		return CMD_RET_FAILURE;
+	}
+
 	/*
 	 * Check for 'halt' parameter. 'halt' = enter halt-mode just before
 	 * starting the application; can be used for debug.
@@ -798,6 +855,11 @@
 	static bool done = false;
 	int ret;
 
+	if (board_mismatch()) {
+		printf("ERR: U-boot is not configured for this board!\n");
+		return CMD_RET_FAILURE;
+	}
+
 	/* hsdk_init can be run only once */
 	if (done) {
 		printf("HSDK HW is already initialized! Please reset the board if you want to change the configuration.\n");
@@ -1031,6 +1093,11 @@
 
 int checkboard(void)
 {
-	puts("Board: Synopsys ARC HS Development Kit\n");
+	printf("Board: Synopsys %s\n", board_name(get_board_type_runtime()));
+
+	if (board_mismatch())
+		printf("WARN: U-boot is configured NOT for this board but for %s!\n",
+		       board_name(get_board_type_config()));
+
 	return 0;
 };