diff mbox series

[01/21] arm64: Add ADI ADSP-SC598 SoC

Message ID 20240912-test-v1-1-458fa57c8ccf@analog.com
State New
Headers show
Series Adding support of ADI ARMv8 ADSP-SC598 SoC. | expand

Commit Message

Arturs Artamonovs via B4 Relay Sept. 12, 2024, 6:24 p.m. UTC
From: Arturs Artamonovs <arturs.artamonovs@analog.com>

Add ADSP-SC598 platform.

Signed-off-by: Arturs Artamonovs <Arturs.Artamonovs@analog.com>
Co-developed-by: Utsav Agarwal <Utsav.Agarwal@analog.com>
Signed-off-by: Utsav Agarwal <Utsav.Agarwal@analog.com>
Co-developed-by: Nathan Barrett-Morrison <nathan.morrison@timesys.com>
Signed-off-by: Nathan Barrett-Morrison <nathan.morrison@timesys.com>
Co-developed-by: Greg Malysa <greg.malysa@timesys.com>
Signed-off-by: Greg Malysa <greg.malysa@timesys.com>
---
 arch/arm64/Kconfig.platforms           |  13 ++
 drivers/soc/Makefile                   |   1 +
 drivers/soc/adi/Makefile               |   5 +
 drivers/soc/adi/system.c               | 257 +++++++++++++++++++++++++++++++++
 include/linux/soc/adi/adsp-gpio-port.h |  85 +++++++++++
 include/linux/soc/adi/cpu.h            | 107 ++++++++++++++
 include/linux/soc/adi/rcu.h            |  55 +++++++
 include/linux/soc/adi/sc59x.h          | 147 +++++++++++++++++++
 include/linux/soc/adi/system_config.h  |  65 +++++++++
 9 files changed, 735 insertions(+)

Comments

Arnd Bergmann Sept. 13, 2024, 8:16 a.m. UTC | #1
On Thu, Sep 12, 2024, at 18:24, Arturs Artamonovs via B4 Relay wrote:
> From: Arturs Artamonovs <arturs.artamonovs@analog.com>
>
> Add ADSP-SC598 platform.
>

> --- 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

You can remove the 'select' statements above and just
make your drivers 'default ARCH_SC59X_64'.

It may also help to pick a more generic name for the platform
in case someone wants to add support for SC57x/SC58x later,
assuming these use some of the same drivers,.

The Kconfig change can normally go into the same patch
as the MAINTAINERS file update, but should be separate
from any of the drivers.

> --- /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

I'm confused about the purpose of this driver. Please
split this out into a separate patch and add a detailed
description of how it is actually being used, since it
does not interact with any of the normal subsystems.


> diff --git a/include/linux/soc/adi/adsp-gpio-port.h 
> b/include/linux/soc/adi/adsp-gpio-port.h

> --- /dev/null
> +++ b/include/linux/soc/adi/cpu.h

> --- /dev/null
> +++ b/include/linux/soc/adi/rcu.h
> @@ -0,0 +1,55 @@

> diff --git a/include/linux/soc/adi/sc59x.h 
> b/include/linux/soc/adi/sc59x.h

> --- /dev/null
> +++ b/include/linux/soc/adi/sc59x.h

I don't see these files being included in the driver you add
here, maybe they got added by accident here?

       Arnd
Artamonovs, Arturs Sept. 13, 2024, 9:54 a.m. UTC | #2
> -----Original Message-----
> From: Arnd Bergmann <arnd@arndb.de>
> Sent: Friday, September 13, 2024 9:16 AM
> To: Artamonovs, Arturs <Arturs.Artamonovs@analog.com>; Catalin Marinas
> <catalin.marinas@arm.com>; Will Deacon <will@kernel.org>; Greg Malysa
> <greg.malysa@timesys.com>; Philipp Zabel <p.zabel@pengutronix.de>; Rob
> Herring <robh@kernel.org>; Krzysztof Kozlowski <krzk+dt@kernel.org>; Conor
> Dooley <conor+dt@kernel.org>; Agarwal, Utsav <Utsav.Agarwal@analog.com>;
> Michael Turquette <mturquette@baylibre.com>; Stephen Boyd
> <sboyd@kernel.org>; Linus Walleij <linus.walleij@linaro.org>; Bartosz
> Golaszewski <brgl@bgdev.pl>; Thomas Gleixner <tglx@linutronix.de>; Andi Shyti
> <andi.shyti@kernel.org>; Greg Kroah-Hartman <gregkh@linuxfoundation.org>;
> Jiri Slaby <jirislaby@kernel.org>; Olof Johansson <olof@lixom.net>;
> soc@kernel.org
> Cc: linux-arm-kernel@lists.infradead.org; linux-kernel@vger.kernel.org;
> devicetree@vger.kernel.org; linux-clk@vger.kernel.org; open list:GPIO
> SUBSYSTEM <linux-gpio@vger.kernel.org>; linux-i2c@vger.kernel.org; linux-
> serial@vger.kernel.org; Linux Factory <adsp-linux@analog.com>; Nathan Barrett-
> Morrison <nathan.morrison@timesys.com>
> Subject: Re: [PATCH 01/21] arm64: Add ADI ADSP-SC598 SoC
> 
> [External]
> 
> On Thu, Sep 12, 2024, at 18:24, Arturs Artamonovs via B4 Relay wrote:
> > From: Arturs Artamonovs <arturs.artamonovs@analog.com>
> >
> > Add ADSP-SC598 platform.
> >
> 
> > --- 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
> 
> You can remove the 'select' statements above and just
> make your drivers 'default ARCH_SC59X_64'.
> 
> It may also help to pick a more generic name for the platform
> in case someone wants to add support for SC57x/SC58x later,
> assuming these use some of the same drivers,.
> 
> The Kconfig change can normally go into the same patch
> as the MAINTAINERS file update, but should be separate
> from any of the drivers.
> 

Hi, yes future plan is too add other platforms  like
SC57x/SC58x and SC594. Drivers are compatible. 

> > --- /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
> 
> I'm confused about the purpose of this driver. Please
> split this out into a separate patch and add a detailed
> description of how it is actually being used, since it
> does not interact with any of the normal subsystems.
> 

Hi, yes we cleaned this driver as much as possible, will
make effort to remove it. 

> > diff --git a/include/linux/soc/adi/adsp-gpio-port.h
> > b/include/linux/soc/adi/adsp-gpio-port.h
> 
> > --- /dev/null
> > +++ b/include/linux/soc/adi/cpu.h
> 
> > --- /dev/null
> > +++ b/include/linux/soc/adi/rcu.h
> > @@ -0,0 +1,55 @@
> 
> > diff --git a/include/linux/soc/adi/sc59x.h
> > b/include/linux/soc/adi/sc59x.h
> 
> > --- /dev/null
> > +++ b/include/linux/soc/adi/sc59x.h
> 
> I don't see these files being included in the driver you add
> here, maybe they got added by accident here?
> 

Should be used in reset driver its removed during rebase, will fix that 
In next series. 

>        Arnd
Markus Elfring Sept. 14, 2024, 5:15 p.m. UTC | #3
> +++ b/drivers/soc/adi/system.c
> @@ -0,0 +1,257 @@> +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);
> +}
…

Under which circumstances would you become interested to apply a statement
like “guard(spinlock_irqsave)(&adi_system_config_lock);”?
https://elixir.bootlin.com/linux/v6.11-rc7/source/include/linux/spinlock.h#L572

Regards,
Markus
gregkh@linuxfoundation.org Sept. 14, 2024, 5:56 p.m. UTC | #4
On Sat, Sep 14, 2024 at 07:15:08PM +0200, Markus Elfring wrote:
> …
> > +++ b/drivers/soc/adi/system.c
> > @@ -0,0 +1,257 @@
> …
> > +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);
> > +}
> …
> 
> Under which circumstances would you become interested to apply a statement
> like “guard(spinlock_irqsave)(&adi_system_config_lock);”?
> https://elixir.bootlin.com/linux/v6.11-rc7/source/include/linux/spinlock.h#L572
> 
> Regards,
> Markus
> 


Hi,

This is the semi-friendly patch-bot of Greg Kroah-Hartman.

Markus, you seem to have sent a nonsensical or otherwise pointless
review comment to a patch submission on a Linux kernel developer mailing
list.  I strongly suggest that you not do this anymore.  Please do not
bother developers who are actively working to produce patches and
features with comments that, in the end, are a waste of time.

Patch submitter, please ignore Markus's suggestion; you do not need to
follow it at all.  The person/bot/AI that sent it is being ignored by
almost all Linux kernel maintainers for having a persistent pattern of
behavior of producing distracting and pointless commentary, and
inability to adapt to feedback.  Please feel free to also ignore emails
from them.

thanks,

greg k-h's patch email bot
Krzysztof Kozlowski Sept. 16, 2024, 6:42 a.m. UTC | #5
On 12/09/2024 20:24, Arturs Artamonovs via B4 Relay wrote:
> From: Arturs Artamonovs <arturs.artamonovs@analog.com>
> 
> Add ADSP-SC598 platform.
> 
> Signed-off-by: Arturs Artamonovs <Arturs.Artamonovs@analog.com>
> Co-developed-by: Utsav Agarwal <Utsav.Agarwal@analog.com>
> Signed-off-by: Utsav Agarwal <Utsav.Agarwal@analog.com>
> Co-developed-by: Nathan Barrett-Morrison <nathan.morrison@timesys.com>
> Signed-off-by: Nathan Barrett-Morrison <nathan.morrison@timesys.com>
> Co-developed-by: Greg Malysa <greg.malysa@timesys.com>
> Signed-off-by: Greg Malysa <greg.malysa@timesys.com>
> ---
>  arch/arm64/Kconfig.platforms           |  13 ++
>  drivers/soc/Makefile                   |   1 +
>  drivers/soc/adi/Makefile               |   5 +
>  drivers/soc/adi/system.c               | 257 +++++++++++++++++++++++++++++++++
>  include/linux/soc/adi/adsp-gpio-port.h |  85 +++++++++++
>  include/linux/soc/adi/cpu.h            | 107 ++++++++++++++
>  include/linux/soc/adi/rcu.h            |  55 +++++++
>  include/linux/soc/adi/sc59x.h          | 147 +++++++++++++++++++
>  include/linux/soc/adi/system_config.h  |  65 +++++++++
>  9 files changed, 735 insertions(+)
> 
> 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

Messed indentation.

> +


> +
> +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)

That's wrong wrapping. Wrapping happens after return type in such cases.

> +{
> +	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

You need to fix such errors.

> 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

Hm? No, you cannot have GPIO driver in linux/soc...

> +
> +/* 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 */

What does it mean?

> +static inline void __adsp_gpio_writel(struct adsp_gpio_port *port, uint32_t val,
> +				      size_t offset)
> +{
> +	writel(val, port->regs + offset);

Not useful wrapper. Makes code bigger.


> +}
> +
> +/* 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

That's not an accurate header guard.

> +
> +#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);

All these do not exist.


Best regards,
Krzysztof
diff mbox series

Patch

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