diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms
index 6c6d11536b42ec6e878db8d355c17994c2500d7b..b9ea22ecddfcbff98486a314143e52934f26df44 100644
--- a/arch/arm64/Kconfig.platforms
+++ b/arch/arm64/Kconfig.platforms
@@ -292,6 +292,19 @@ config ARCH_ROCKCHIP
 	  This enables support for the ARMv8 based Rockchip chipsets,
 	  like the RK3368.
 
+config ARCH_SC59X_64
+	bool "ADI 64-bit SC59X Platforms"
+	select TIMER_OF
+	select GPIOLIB
+	select PINCTRL
+	select COMMON_CLK_ADI_SC598
+	select PINCTRL_ADSP
+	select ADI_ADSP_IRQ
+	select COUNTER
+	help
+		This enables support for Analog Devices Incorporated's
+		Family of ARM64 DSP processors
+
 config ARCH_SEATTLE
 	bool "AMD Seattle SoC Family"
 	help
diff --git a/drivers/soc/Makefile b/drivers/soc/Makefile
index fb2bd31387d070387fcf8a579f618dc2b25bdc69..af518539185563a96e37a2d42ad5535e7366c5fa 100644
--- a/drivers/soc/Makefile
+++ b/drivers/soc/Makefile
@@ -3,6 +3,7 @@
 # Makefile for the Linux Kernel SOC specific device drivers.
 #
 
+obj-$(CONFIG_ARCH_SC59X_64)	+= adi/
 obj-y				+= apple/
 obj-y				+= aspeed/
 obj-$(CONFIG_ARCH_AT91)		+= atmel/
diff --git a/drivers/soc/adi/Makefile b/drivers/soc/adi/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..113720192d462e833da69214ce91a7b84aec141b
--- /dev/null
+++ b/drivers/soc/adi/Makefile
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0
+
+# todo modularize; already depends on CONFIG_ARCH_SC59X_64 though
+
+obj-y += system.o
diff --git a/drivers/soc/adi/system.c b/drivers/soc/adi/system.c
new file mode 100644
index 0000000000000000000000000000000000000000..42cd157bc68af8819e2a2d2fc5be009b4753bd29
--- /dev/null
+++ b/drivers/soc/adi/system.c
@@ -0,0 +1,257 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2022-2024 - Analog Devices Inc.
+ */
+
+#include <linux/module.h>
+#include <linux/soc/adi/system_config.h>
+
+#define ADI_SYSREG_BITS(_id, _offset, _width, _shift) \
+	{ \
+		.id = ADI_SYSTEM_REG_##_id, \
+		.offset = _offset, \
+		.mask = GENMASK(_width-1, 0) << _shift, \
+		.shift = _shift, \
+		.is_bits = true, \
+	}
+
+#define ADI_SYSREG(_id, _offset) \
+	{ \
+		.id = ADI_SYSTEM_REG_##_id, \
+		.offset = _offset, \
+		.is_bits = false, \
+	}
+
+#define devm_regmap_init_adi_system_config(dev, config) \
+	__regmap_lockdep_wrapper(__devm_regmap_init_adi_system_config, \
+	#config, dev, config)
+
+struct adi_system_context {
+	/* underlying regmap_mmio */
+	struct regmap *regmap;
+	/* tree of register definitions by index */
+	struct radix_tree_root tree;
+	/* configuration we were created with */
+	struct adi_system_config *config;
+};
+
+/*
+ * Fields in PADS CFG0 at offset +0x04
+ */
+static struct adi_system_register adi_pads_regs[] = {
+	ADI_SYSREG_BITS(EMAC0_PTPCLK0, 0x04, 2, 0),
+	ADI_SYSREG_BITS(EMAC0_EMACRESET, 0x04, 1, 2),
+	ADI_SYSREG_BITS(EMAC0_PHYISEL, 0x04, 2, 3),
+	ADI_SYSREG_BITS(CNT0UDSEL, 0x04, 2, 6),
+	ADI_SYSREG_BITS(CNT0DGSEL, 0x04, 2, 7),
+	ADI_SYSREG_BITS(PUTMS, 0x04, 2, 16),
+	ADI_SYSREG_BITS(EMAC0_AUXIE, 0x04, 1, 17),
+	ADI_SYSREG_BITS(FAULT_DIS, 0x04, 1, 18),
+	ADI_SYSREG_BITS(EMAC0_ENDIANNESS, 0x04, 1, 19),
+	ADI_SYSREG_BITS(EMAC1_ENDIANNESS, 0x04, 1, 20),
+	ADI_SYSREG_BITS(MSHC_CCLK_DIV_EN, 0x04, 1, 22),
+	ADI_SYSREG(DAI0_IE, 0x90),
+	ADI_SYSREG(DAI1_IE, 0x94),
+};
+
+static struct adi_system_config adi_pads_config = {
+	.registers = adi_pads_regs,
+	.len = ARRAY_SIZE(adi_pads_regs),
+	.max_register = __ADI_SYSTEM_REG_COUNT,
+};
+
+static int regmap_system_read(void *context, unsigned int reg,
+		unsigned int *val)
+{
+	struct adi_system_context *ctx = context;
+	struct adi_system_register *sreg =
+		radix_tree_lookup(&ctx->tree, reg);
+	int ret;
+
+	if (!sreg)
+		return -EIO;
+
+	if (sreg->is_bits) {
+		uint32_t tmp;
+
+		ret = regmap_read(ctx->regmap, sreg->offset, &tmp);
+		if (ret)
+			return ret;
+
+		tmp = (tmp & sreg->mask) >> sreg->shift;
+		*val = tmp;
+		return 0;
+	}
+
+	return regmap_read(ctx->regmap, sreg->offset, val);
+}
+
+static int regmap_system_write(void *context, unsigned int reg,
+		unsigned int val)
+{
+	struct adi_system_context *ctx = context;
+	struct adi_system_register *sreg = radix_tree_lookup(&ctx->tree, reg);
+
+	if (!sreg)
+		return -EIO;
+
+	if (sreg->is_bits) {
+		return regmap_update_bits(ctx->regmap, sreg->offset,
+				sreg->mask,
+			(val << sreg->shift) & sreg->mask);
+	}
+
+	return regmap_write(ctx->regmap, sreg->offset, val);
+}
+
+static struct adi_system_context *create_context
+(struct adi_system_config *config)
+{
+	struct regmap *regmap = config->mmio_regmap;
+	struct adi_system_context *ctx;
+	size_t i;
+	int ret;
+
+	ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
+	if (!ctx)
+		return ERR_PTR(-ENOMEM);
+
+	ctx->regmap = regmap;
+	INIT_RADIX_TREE(&ctx->tree, GFP_KERNEL);
+
+	for (i = 0; i < config->len; ++i) {
+		struct adi_system_register *sreg = &config->registers[i];
+
+		ret = radix_tree_insert(&ctx->tree, sreg->id, sreg);
+		if (ret)
+			return ERR_PTR(ret);
+	}
+
+	config->config.max_register = config->max_register;
+	config->config.reg_bits = 8 * sizeof(uint32_t);
+	config->config.val_bits = 8 * sizeof(uint32_t);
+	config->config.reg_stride = 1;
+
+	return ctx;
+}
+
+static void regmap_system_free_context(void *context)
+{
+	struct adi_system_context *ctx = context;
+	unsigned int i;
+
+	for (i = 0; i < ctx->config->len; ++i)
+		radix_tree_delete(&ctx->tree,
+				ctx->config->registers[i].id);
+
+	kfree(ctx);
+}
+
+static const struct regmap_bus regmap_system_bus = {
+	.fast_io = true,
+	.reg_write = regmap_system_write,
+	.reg_read = regmap_system_read,
+	.free_context = regmap_system_free_context,
+	.val_format_endian_default = REGMAP_ENDIAN_LITTLE,
+};
+
+static struct regmap *__devm_regmap_init_adi_system_config(struct device *dev,
+	struct adi_system_config *config,
+	struct lock_class_key *lock_key, const char *lock_name)
+{
+	struct adi_system_context *ctx = create_context(config);
+
+	if (IS_ERR(ctx))
+		return ERR_PTR(PTR_ERR(ctx));
+
+	return __devm_regmap_init(dev, &regmap_system_bus, ctx,
+			&config->config,
+		lock_key, lock_name);
+}
+
+static DEFINE_SPINLOCK(adi_system_config_lock);
+static LIST_HEAD(adi_system_config_list);
+
+static int adi_system_config_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct adi_system_config *config = &adi_pads_config;
+	struct device_node *np = dev->of_node;
+	struct regmap *regmap_mmio;
+	struct regmap *regmap_system;
+	struct resource *res;
+	void __iomem *base;
+	unsigned long flags;
+
+	struct regmap_config mmio_config = {
+		.reg_bits = 8 * sizeof(uint32_t),
+		.val_bits = 8 * sizeof(uint32_t),
+		.reg_stride = sizeof(uint32_t),
+	};
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+
+	base = devm_ioremap(dev, res->start, resource_size(res));
+	if (IS_ERR(base))
+		return PTR_ERR(base);
+
+	mmio_config.name = dev_name(dev);
+	mmio_config.max_register = resource_size(res) - sizeof(uint32_t);
+
+	regmap_mmio = devm_regmap_init_mmio(dev, base, &mmio_config);
+	if (IS_ERR(regmap_mmio)) {
+		dev_err(dev, "mmio regmap initialization failed\n");
+		return PTR_ERR(regmap_mmio);
+	}
+
+	config->mmio_regmap = regmap_mmio;
+	regmap_system = devm_regmap_init_adi_system_config(dev, config);
+	if (IS_ERR(regmap_system)) {
+		dev_err(dev, "system config regmap initialization failed\n");
+		return PTR_ERR(regmap_system);
+	}
+
+	config->np = np;
+	config->system_regmap = regmap_system;
+	platform_set_drvdata(pdev, config);
+
+	spin_lock_irqsave(&adi_system_config_lock, flags);
+	list_add_tail(&config->list, &adi_system_config_list);
+	spin_unlock_irqrestore(&adi_system_config_lock, flags);
+	return 0;
+}
+
+static void adi_system_config_remove(struct platform_device *pdev)
+{
+	struct adi_system_config *config = platform_get_drvdata(pdev);
+	unsigned long flags;
+
+	spin_lock_irqsave(&adi_system_config_lock, flags);
+	list_del(&config->list);
+	spin_unlock_irqrestore(&adi_system_config_lock, flags);
+}
+
+/*
+ * PADs configuration registers are required to configure peripherals,
+ * and by extension the system. Hence the driver focuses on driving them while
+ * also setting up the remaining system.
+ */
+static const struct of_device_id pads_dt_ids[] = {
+	{ .compatible = "adi,pads-peripheral-config", },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, pads_dt_ids);
+
+static struct platform_driver pads_driver = {
+	.driver = {
+		.name = "adi-system-config",
+		.of_match_table = pads_dt_ids,
+	},
+	.probe = adi_system_config_probe,
+	.remove = adi_system_config_remove,
+};
+module_platform_driver(pads_driver);
+
+MODULE_AUTHOR("Greg Malysa <greg.malysa@timesys.com>");
+MODULE_DESCRIPTION("ADI ADSP PADS CFG-based System Configuration Driver");
+MODULE_LICENSE("GPL v2");
\ No newline at end of file
diff --git a/include/linux/soc/adi/adsp-gpio-port.h b/include/linux/soc/adi/adsp-gpio-port.h
new file mode 100644
index 0000000000000000000000000000000000000000..6466ded03ec6092149a2abfc56a305f9124ac695
--- /dev/null
+++ b/include/linux/soc/adi/adsp-gpio-port.h
@@ -0,0 +1,85 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright 2022-2024 - Analog Devices Inc.
+ */
+
+#ifndef GPIO_ADI_ADSP_PORT_H
+#define GPIO_ADI_ADSP_PORT_H
+
+#include <linux/gpio/driver.h>
+
+/* Number of GPIOs per port instance */
+#define ADSP_PORT_NGPIO 16
+
+/* PORT memory layout */
+#define ADSP_PORT_REG_FER		0x00
+#define ADSP_PORT_REG_FER_SET		0x04
+#define ADSP_PORT_REG_FER_CLEAR		0x08
+#define ADSP_PORT_REG_DATA		0x0c
+#define ADSP_PORT_REG_DATA_SET		0x10
+#define ADSP_PORT_REG_DATA_CLEAR	0x14
+#define ADSP_PORT_REG_DIR		0x18
+#define ADSP_PORT_REG_DIR_SET		0x1c
+#define ADSP_PORT_REG_DIR_CLEAR		0x20
+#define ADSP_PORT_REG_INEN		0x24
+#define ADSP_PORT_REG_INEN_SET		0x28
+#define ADSP_PORT_REG_INEN_CLEAR	0x2c
+#define ADSP_PORT_REG_PORT_MUX		0x30
+#define ADSP_PORT_REG_DATA_TGL		0x34
+#define ADSP_PORT_REG_POLAR		0x38
+#define ADSP_PORT_REG_POLAR_SET		0x3c
+#define ADSP_PORT_REG_POLAR_CLEAR	0x40
+#define ADSP_PORT_REG_LOCK		0x44
+#define ADSP_PORT_REG_TRIG_TGL		0x48
+
+/*
+ * One gpio instance per PORT instance in the hardware, provides the per-PORT
+ * interface to the hardware. Referenced in GPIO and PINCTRL drivers
+ */
+struct adsp_gpio_port {
+	struct device *dev;
+	void __iomem *regs;
+	struct gpio_chip gpio;
+	struct irq_domain *irq_domain;
+	uint32_t irq_offset;
+	uint32_t open_drain;
+	spinlock_t lock;
+};
+
+/* may need lock depending on register */
+static inline uint32_t __adsp_gpio_readl(struct adsp_gpio_port *port,
+				    size_t offset)
+{
+	return readl(port->regs + offset);
+}
+
+/* may need lock depending on register */
+static inline void __adsp_gpio_writel(struct adsp_gpio_port *port, uint32_t val,
+				      size_t offset)
+{
+	writel(val, port->regs + offset);
+}
+
+/* may need lock depending on register */
+static inline u16 __adsp_gpio_readw(struct adsp_gpio_port *port,
+				    size_t offset)
+{
+	return readw(port->regs + offset);
+}
+
+/* may need lock depending on register */
+static inline void __adsp_gpio_writew(struct adsp_gpio_port *port, u16 val,
+				      size_t offset)
+{
+	writew(val, port->regs + offset);
+}
+
+static inline struct adsp_gpio_port *to_adsp_gpio_port(struct gpio_chip
+						       *chip)
+{
+	return container_of(chip, struct adsp_gpio_port, gpio);
+}
+
+int adsp_attach_pint_to_gpio(struct adsp_gpio_port *port);
+
+#endif
diff --git a/include/linux/soc/adi/cpu.h b/include/linux/soc/adi/cpu.h
new file mode 100644
index 0000000000000000000000000000000000000000..0ddb30619b423ce70e9b8018ed6404cfd4ef6039
--- /dev/null
+++ b/include/linux/soc/adi/cpu.h
@@ -0,0 +1,107 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright 2022-2024 - Analog Devices Inc.
+ */
+
+#ifndef __MACH_CPU_H
+#define __MACH_CPU_H
+
+#define SYS_L2_START		0x20080000
+#define SYS_SRAM_BASE		(0x20080000 + SZ_16K)
+
+#define SYS_SRAM_SIZE		(SZ_16K + SZ_32K * 3)
+#define SYS_SRAM_ICC_SIZE	SZ_4K
+#define SYS_MMR_BASE		0x31000000
+#define SYS_MMR_SIZE		SZ_1M
+#define SYS_SMC_BANK1		0x44000000
+
+#define SC59X_GIC_PORT0		0x310B2000
+#define SC59X_GIC_PORT1		0x310B4000
+
+/*
+ * Timer Configuration Register Bits
+ */
+#define TIMER_EMU_RUN		0x8000
+#define TIMER_BPER_EN		0x4000
+#define TIMER_BWID_EN		0x2000
+#define TIMER_BDLY_EN		0x1000
+#define TIMER_OUT_DIS		0x0800
+#define TIMER_TIN_SEL		0x0400
+#define TIMER_CLK_SEL		0x0300
+#define TIMER_CLK_SCLK		0x0000
+#define TIMER_CLK_ALT_CLK0	0x0100
+#define TIMER_CLK_ALT_CLK1	0x0300
+#define TIMER_PULSE_HI		0x0080
+#define TIMER_SLAVE_TRIG	0x0040
+#define TIMER_IRQ_MODE		0x0030
+#define TIMER_IRQ_ACT_EDGE	0x0000
+#define TIMER_IRQ_DLY		0x0010
+#define TIMER_IRQ_WID_DLY	0x0020
+#define TIMER_IRQ_PER		0x0030
+#define TIMER_MODE		0x000f
+#define TIMER_MODE_WDOG_P	0x0008
+#define TIMER_MODE_WDOG_W	0x0009
+#define TIMER_MODE_PWM_CONT	0x000c
+#define TIMER_MODE_PWM		0x000d
+#define TIMER_MODE_WDTH		0x000a
+#define TIMER_MODE_WDTH_D	0x000b
+#define TIMER_MODE_EXT_CLK	0x000e
+#define TIMER_MODE_PININT	0x000f
+
+#define __BFP(m) u16 m; u16 __pad_##m
+
+struct gptimer3 {
+	__BFP(config);
+	uint32_t counter;
+	uint32_t period;
+	uint32_t width;
+	uint32_t delay;
+};
+
+struct sc5xx_gptimer {
+	int id;
+	int irq;
+	int reserved;
+	int int_enable;
+	void __iomem *io_base;
+	void __iomem *cgu0_ctl;
+	unsigned long isr_count;
+	struct platform_device *pdev;
+	struct list_head node;
+};
+
+struct gptimer3_group_regs {
+	__BFP(run);
+	__BFP(enable);
+	__BFP(disable);
+	__BFP(stop_cfg);
+	__BFP(stop_cfg_set);
+	__BFP(stop_cfg_clr);
+	__BFP(data_imsk);
+	__BFP(stat_imsk);
+	__BFP(tr_msk);
+	__BFP(tr_ie);
+	__BFP(data_ilat);
+	__BFP(stat_ilat);
+	__BFP(err_status);
+	__BFP(bcast_per);
+	__BFP(bcast_wid);
+	__BFP(bcast_dly);
+};
+
+/* The actual gptimer API */
+struct sc5xx_gptimer *gptimer_request(int id);
+int gptimer_free(struct sc5xx_gptimer *timer);
+void set_gptimer_pwidth(struct sc5xx_gptimer *timer, uint32_t width);
+void set_gptimer_period(struct sc5xx_gptimer *timer, uint32_t period);
+uint32_t get_gptimer_count(struct sc5xx_gptimer *timer);
+void set_gptimer_config(struct sc5xx_gptimer *timer, uint16_t config);
+void enable_gptimers(uint16_t mask);
+void disable_gptimers(uint16_t mask);
+void map_gptimers(void);
+uint16_t get_gptimer_status(void);
+void set_gptimer_status(uint16_t value);
+void set_spu_securep_msec(uint16_t n, bool msec);
+void platform_ipi_init(void);
+
+#endif				/* __MACH_CPU_H */
diff --git a/include/linux/soc/adi/rcu.h b/include/linux/soc/adi/rcu.h
new file mode 100644
index 0000000000000000000000000000000000000000..929989ff8f142609d5aecaffe0e8aa659875c47e
--- /dev/null
+++ b/include/linux/soc/adi/rcu.h
@@ -0,0 +1,55 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright 2022-2024 - Analog Devices Inc.
+ */
+
+#ifndef SOC_ADI_RCU_H
+#define SOC_ADI_RCU_H
+
+/* Register offsets */
+#define ADI_RCU_REG_CTL				0x00
+#define ADI_RCU_REG_STAT			0x04
+#define ADI_RCU_REG_CRCTL			0x08
+#define ADI_RCU_REG_CRSTAT			0x0c
+
+#ifdef CONFIG_ARCH_SC58X
+#define ADI_RCU_REG_SIDIS			0x10
+#define ADI_RCU_REG_SISTAT			0x14
+#define ADI_RCU_REG_SVECT_LCK			0x18
+#define ADI_RCU_REG_BCODE			0x1c
+#define ADI_RCU_REG_SVECT0			0x20
+#define ADI_RCU_REG_SVECT1			0x24
+#define ADI_RCU_REG_SVECT2			0x28
+#define ADI_RCU_REG_MSG				0x60
+#define ADI_RCU_REG_MSG_SET			0x64
+#define ADI_RCU_REG_MSG_CLR			0x68
+#else
+#define ADI_RCU_REG_SRRQSTAT			0x18
+#define ADI_RCU_REG_SIDIS			0x1c
+#define ADI_RCU_REG_SISTAT			0x20
+#define ADI_RCU_REG_BCODE			0x28
+#define ADI_RCU_REG_SVECT0			0x2c
+#define ADI_RCU_REG_SVECT1			0x30
+#define ADI_RCU_REG_SVECT2			0x34
+#define ADI_RCU_REG_MSG				0x6c
+#define ADI_RCU_REG_MSG_SET			0x70
+#define ADI_RCU_REG_MSG_CLR			0x74
+#endif
+
+
+/* Register bit definitions */
+#define ADI_RCU_CTL_SYSRST		BIT(0)
+
+/* Bit values for the RCU0_MSG register */
+#define RCU0_MSG_C0IDLE			0x00000100	/* Core 0 Idle */
+#define RCU0_MSG_C1IDLE			0x00000200	/* Core 1 Idle */
+#define RCU0_MSG_C2IDLE			0x00000400	/* Core 2 Idle */
+#define RCU0_MSG_CRR0			0x00001000	/* Core 0 reset request */
+#define RCU0_MSG_CRR1			0x00002000	/* Core 1 reset request */
+#define RCU0_MSG_CRR2			0x00004000	/* Core 2 reset request */
+#define RCU0_MSG_C1ACTIVATE		0x00080000	/* Core 1 Activated */
+#define RCU0_MSG_C2ACTIVATE		0x00100000	/* Core 2 Activated */
+
+struct adi_rcu;
+struct adi_sec;
+#endif
diff --git a/include/linux/soc/adi/sc59x.h b/include/linux/soc/adi/sc59x.h
new file mode 100644
index 0000000000000000000000000000000000000000..95655886478cda8cd6798a243781e39dc31baacf
--- /dev/null
+++ b/include/linux/soc/adi/sc59x.h
@@ -0,0 +1,147 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright 2022-2024 - Analog Devices Inc.
+ */
+
+#ifndef SOC_ADI_SC59X_H
+#define SOC_ADI_SC59X_H
+
+#define SC59x_SYSTEM_L2_VIRT_BASE	0xFF020000
+#define SC59x_SYSTEM_L2_SIZE		0x2C0000
+
+// General Purpose Timer Block Registers
+#define TIMER_GROUP			0x31018004
+
+// TIMER0
+#define TIMER0_CONFIG			0x31018060
+
+// CGU0
+#define REG_CGU0_CTL			0x3108D000	// CGU0 Control Register
+#define REG_CGU0_STAT			0x3108D008	// CGU0 Status Register
+#define REG_CGU0_DIV			0x3108D00C	// CGU0 Clocks Divisor Register
+
+// UART0
+#define UART0_REVID			0x31003000	// UART0 Revision ID Register
+
+// UART1
+#define UART1_REVID			0x31003400	// UART1 Revision ID Register
+
+// UART2
+#define UART2_REVID			0x31003800	// UART2 Revision ID Register
+
+// WDOG0
+#define REG_WDOG0_CTL			0x31008000	// WDOG0 Control Register
+
+// WDOG1
+#define REG_WDOG1_CTL			0x31008800	// WDOG1 Control Register
+
+// CRC0 MMR
+#define REG_CRC0_CTL			0x310A5000	// CRC0 Control Register
+#define REG_CRC0_DCNT			0x310A5004	// CRC0 Data Word Count Register
+#define REG_CRC0_FILLVAL		0x310A5018	// CRC0 Fill Value Register
+
+// DMA Channel Registers
+#define REG_DMA18_DSCPTR_NXT		0x310A7000	// DMA8 Pointer to Next Initial Descriptor
+#define REG_DMA8_CFG			0x310A7008	// DMA8 Configuration Register
+#define REG_DMA9_DSCPTR_NXT		0x310A7080	// DMA9 Pointer to Next Initial Descriptor
+#define REG_DMA9_CFG			0x310A7088	// DMA9 Configuration Register
+#define REG_DMA9_STAT			0x310A70B0	// DMA9 Status Register
+#define REG_DMA18_DSCPTR_NXT		0x310A7100	// DMA18 Pointer to Next Initial Descriptor
+#define REG_DMA18_CFG			0x310A7108	// DMA18 Configuration Register
+#define REG_DMA19_DSCPTR_NXT		0x310A7180	// DMA19 Pointer to Next Initial Descriptor
+#define REG_DMA19_CFG			0x310A7188	// DMA19 Configuration Register
+#define REG_DMA19_STAT			0x310A71B0	// DMA19 Status Register
+
+// L2CTL0
+#define L2CTL0_CTL			0x31080000	// L2CTL0 Control Register
+#define L2CTL0_STAT			0x31080010	// L2CTL0 Status Register
+#define L2CTL0_ERRADDR0			0x31080040	// L2CTL0 ECC Error Address 0 Register
+#define L2CTL0_ET0			0x31080080	// L2CTL0 Error Type 0 Register
+#define L2CTL0_EADDR0			0x31080084	// L2CTL0 Error Type 0 Address Register
+#define L2CTL0_ET1			0x31080088	// L2CTL0 Error Type 1 Register
+#define L2CTL0_EADDR1			0x3108008C	// L2CTL0 Error Type 1 Address Register
+
+// SEC Core Interface (SCI) Register Definitions
+#define SEC_COMMON_BASE			0x31089000
+#define SEC_SCI_BASE			0x31089440
+#define SEC_SSI_BASE			0x31089800
+
+#define SEC_SCI_OFF			0x00000040
+#define SEC_CCTL			0x00000000	// SEC Core Control Register n
+#define SEC_CSID			0x0000001C	// SEC Core IRQ Source ID Register n
+
+#define SEC_CCTL_EN			0x00000001	// SEC Core Control Register Enable bit
+
+// SEC Fault Management Interface (SFI) Register Definitions
+#define SEC_FCTL			0x00000010	// SEC Fault Control Register
+
+// SEC Global Register Definitions
+#define SEC_GCTL			0x00000000	// SEC Global Control Register
+#define SEC_RAISE			0x00000008	// SEC Global Raise Register
+#define SEC_END				0x0000000C	// SEC Global End Register
+
+// SEC_SCTL
+#define SEC_SCTL_CTG			0x0F000000	// Core Target Select
+
+// SEC Source Interface (SSI) Register Definitions
+#define SEC_SCTL0			0x00000000	// SEC Source Control Register n
+
+
+// SEC_SCTL
+#define SEC_SCTL_SRC_EN			0x00000004	// SEN: Enable
+#define SEC_SCTL_FAULT_EN		0x00000002	// FEN: Enable
+#define SEC_SCTL_INT_EN			0x00000001	// IEN: Enable
+
+
+// TRU0
+// 0x3108A000 + (0x4 * n)
+#define REG_TRU0_SSR160			0x3108A280	// TRU0 Slave Select Register
+#define REG_TRU0_SSR164			0x3108A290	// TRU0 Slave Select Register
+#define REG_TRU0_SSR168			0x3108A2A0	// TRU0 Slave Select Register
+#define REG_TRU0_MTR			0x3108A7E0	// TRU0 Master Trigger Register
+#define REG_TRU0_GCTL			0x3108A7F4	// TRU0 Global Control Register
+
+// Trigger Master Definitions
+#define TRGM_SOFT0			136	// Software-driven Trigger 3
+#define TRGM_SOFT1			137	// Software-driven Trigger 3
+#define TRGM_SOFT2			138	// Software-driven Trigger 4
+#define TRGM_SOFT3			139	// Software-driven Trigger 3
+#define TRGM_SOFT4			140	// Software-driven Trigger 4
+#define TRGM_SOFT5			141	// Software-driven Trigger 5
+
+// RCU0
+#define REG_RCU0_CTL			0x3108C000	// RCU0 Control Register
+#define REG_RCU0_STAT			0x3108C004	// RCU0 Status Register
+#define REG_RCU0_CRCTL			0x3108C008	// RCU0 Core Reset Control Register
+#define REG_RCU0_CRSTAT			0x3108C00C	// RCU0 Core Reset Status Register
+#define REG_RCU0_SIDIS			0x3108C01C	// RCU0 System Interface Disable Register
+#define REG_RCU0_SISTAT			0x3108C020	// RCU0 System Interface Status Register
+#define REG_RCU0_BCODE			0x3108C028	// RCU0 Boot Code Register
+#define REG_RCU0_MSG_SET		0x3108C070	// RCU0 Message Set Bits Register
+#define REG_RCU0_SVECT1			0x3108C030	// Software Vector Register 1
+#define REG_RCU0_SVECT2			0x3108C034	// Software Vector Register 2
+
+// SPU0
+#define REG_SPU0_CTL			0x3108B000	// SPU0 Control Register
+
+// LP0
+#define LP0_CTL				0x30FFE000	// LP0 Control Register
+
+// LP1
+#define LP1_CTL				0x30FFE100	// LP1 Control Register
+
+// PADS0
+#define REG_PADS0_BASE			0x31004600	// PADS Base Register
+#define REG_PADS0_PCFG0			0x31004604	// PADS0 Peripheral Configuration0 Register
+#define REG_PADS0_DAI0_IE		0x31004690	// PADS DAI0 IE Register
+#define REG_PADS0_DAI1_IE		0x31004694	// PADS DAI1 IE Register
+#define BITM_PADS_PCFG0_EMACRESET	0x00000004	// Reset Enable for RGMII
+#define ENUM_PADS_PCFG0_EMACPHY_MII	0x00000000	// EMACPHYISEL: MII Interface
+#define ENUM_PADS_PCFG0_EMACPHY_RGMII	0x00000008	// EMACPHYISEL: RGMII Interface
+#define ENUM_PADS_PCFG0_EMACPHY_RMII	0x00000010	// EMACPHYISEL: RMII Interface
+#define ENUM_PADS_PCFG0_EMAC0_RMII_CLK	0x00000000	// EMAC0: EMAC0_RMII CLK
+#define ENUM_PADS_PCFG0_EMAC0_SCLK1	0x00000001	// EMAC0: SCLK
+#define ENUM_PADS_PCFG0_EMAC0_EXT_CLK	0x00000002	// EMAC0: External Clock
+#define ENUM_PADS_PCFG0_EMAC0_SCLK3	0x00000003	// EMAC0: SCLK
+
+#endif
diff --git a/include/linux/soc/adi/system_config.h b/include/linux/soc/adi/system_config.h
new file mode 100644
index 0000000000000000000000000000000000000000..788d39f0c0d36f233a7b48ef4e2f0a3f4750f711
--- /dev/null
+++ b/include/linux/soc/adi/system_config.h
@@ -0,0 +1,65 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Implementation of adi_system_config, potential replacement for syscon that
+ * generalizes it to support arbitrary regmap registration and requires the
+ * driver to be initialized first
+ *
+ * Copyright 2022-2024 - Analog Devices Inc.
+ */
+
+#ifndef SOC_ADI_SYSTEM_CONFIG_H
+#define SOC_ADI_SYSTEM_CONFIG_H
+
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+struct adi_system_register {
+	uint32_t id;
+	uint32_t offset;
+	uint32_t mask;
+	uint8_t shift;
+	bool is_bits;
+};
+
+struct adi_system_config {
+	/* User configured */
+	struct adi_system_register *registers;
+	unsigned int max_register;
+	size_t len;
+
+	/* Internal data populated during usage */
+	struct regmap_config config;
+	struct regmap *mmio_regmap;
+	struct device_node *np;
+	struct list_head list;
+	struct regmap *system_regmap;
+};
+
+/*
+ * All possible system register IDs across all platforms supported by this
+ * driver.
+ */
+enum adi_system_reg_id {
+	ADI_SYSTEM_REG_EMAC0_PTPCLK0 = 0,
+	ADI_SYSTEM_REG_EMAC0_EMACRESET,
+	ADI_SYSTEM_REG_EMAC0_PHYISEL,
+	ADI_SYSTEM_REG_CNT0UDSEL,
+	ADI_SYSTEM_REG_CNT0DGSEL,
+	ADI_SYSTEM_REG_TWI0VSEL,
+	ADI_SYSTEM_REG_TWI1VSEL,
+	ADI_SYSTEM_REG_TWI2VSEL,
+	ADI_SYSTEM_REG_PUMSIDLC,
+	ADI_SYSTEM_REG_PUMSIHL,
+	ADI_SYSTEM_REG_PUTMS,
+	ADI_SYSTEM_REG_EMAC0_AUXIE,
+	ADI_SYSTEM_REG_FAULT_DIS,
+	ADI_SYSTEM_REG_EMAC0_ENDIANNESS,
+	ADI_SYSTEM_REG_EMAC1_ENDIANNESS,
+	ADI_SYSTEM_REG_MSHC_CCLK_DIV_EN,
+	ADI_SYSTEM_REG_DAI0_IE,
+	ADI_SYSTEM_REG_DAI1_IE,
+	__ADI_SYSTEM_REG_COUNT
+};
+
+#endif
