arch: arm: Add Analog Devices SC5xx machine type

Add support for the SC5xx machine type from Analog Devices. This
includes support for the SC57x, SC58x, SC59x, and SC59x-64 SoCs, which
have many common features such as common ADI IP blocks, and SHARC DSP
cores. This commit introduces core functionality required for all boards
using an SC5xx SoC, such as:

- SPL configuration
- Required CPU hooks such as reset
- Boot ROM interaction to load the stage 2 bootloader in the reference
  configuration. Other options are possible but not officially supported
  at this time
- SoC-common configuration expected to be reused by all boards
- Early initialization for system clocks and DDR controller

Co-developed-by: Greg Malysa <greg.malysa@timesys.com>
Signed-off-by: Greg Malysa <greg.malysa@timesys.com>
Co-developed-by: Ian Roberts <ian.roberts@timesys.com>
Signed-off-by: Ian Roberts <ian.roberts@timesys.com>
Signed-off-by: Vasileios Bimpikas <vasileios.bimpikas@analog.com>
Signed-off-by: Utsav Agarwal <utsav.agarwal@analog.com>
Signed-off-by: Arturs Artamonovs <arturs.artamonovs@analog.com>
Signed-off-by: Nathan Barrett-Morrison <nathan.morrison@timesys.com>
diff --git a/arch/arm/mach-sc5xx/spl.c b/arch/arm/mach-sc5xx/spl.c
new file mode 100644
index 0000000..68e0310
--- /dev/null
+++ b/arch/arm/mach-sc5xx/spl.c
@@ -0,0 +1,102 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * (C) Copyright 2022 - Analog Devices, Inc.
+ *
+ * Written and/or maintained by Timesys Corporation
+ *
+ * Contact: Nathan Barrett-Morrison <nathan.morrison@timesys.com>
+ * Contact: Greg Malysa <greg.malysa@timesys.com>
+ */
+
+#include <spl.h>
+#include <asm/arch-adi/sc5xx/sc5xx.h>
+#include <asm/arch-adi/sc5xx/spl.h>
+#include "init/clkinit.h"
+#include "init/dmcinit.h"
+
+static bool adi_start_uboot_proper;
+
+static int adi_sf_default_bus = CONFIG_SF_DEFAULT_BUS;
+static int adi_sf_default_cs = CONFIG_SF_DEFAULT_CS;
+static int adi_sf_default_speed = CONFIG_SF_DEFAULT_SPEED;
+
+u32 bmode;
+
+int spl_start_uboot(void)
+{
+	return adi_start_uboot_proper;
+}
+
+unsigned int spl_spi_get_default_speed(void)
+{
+	return adi_sf_default_speed;
+}
+
+unsigned int spl_spi_get_default_bus(void)
+{
+	return adi_sf_default_bus;
+}
+
+unsigned int spl_spi_get_default_cs(void)
+{
+	return adi_sf_default_cs;
+}
+
+void board_boot_order(u32 *spl_boot_list)
+{
+	const char *bmodestring = sc5xx_get_boot_mode(&bmode);
+
+	printf("ADI Boot Mode: 0x%x (%s)\n", bmode, bmodestring);
+
+	/*
+	 * By default everything goes back to the bootrom, where we'll read table
+	 * parameters and ask for another image to be loaded
+	 */
+	spl_boot_list[0] = BOOT_DEVICE_BOOTROM;
+
+	if (bmode == 0) {
+		printf("SPL execution has completed.  Please load U-Boot Proper via JTAG");
+		while (1)
+			;
+	}
+}
+
+int32_t __weak adi_rom_boot_hook(struct ADI_ROM_BOOT_CONFIG *config, int32_t cause)
+{
+	return 0;
+}
+
+int board_return_to_bootrom(struct spl_image_info *spl_image,
+			    struct spl_boot_device *bootdev)
+{
+#if CONFIG_ADI_SPL_FORCE_BMODE != 0
+	// see above
+	if (bmode != 0 && bmode != 3)
+		bmode = CONFIG_ADI_SPL_FORCE_BMODE;
+#endif
+
+	if (bmode >= (ARRAY_SIZE(adi_rom_boot_args)))
+		bmode = 0;
+
+	adi_rom_boot((void *)adi_rom_boot_args[bmode].addr,
+		     adi_rom_boot_args[bmode].flags,
+		     0, &adi_rom_boot_hook,
+		     adi_rom_boot_args[bmode].cmd);
+	return 0;
+};
+
+void board_init_f(ulong dummy)
+{
+	int ret;
+
+	clks_init();
+	DMC_Config();
+	sc5xx_soc_init();
+
+	ret = spl_early_init();
+	if (ret)
+		panic("spl_early_init() failed\n");
+
+	preloader_console_init();
+}
+