From: Arturs Artamonovs <arturs.artamonovs@xxxxxxxxxx> Add ADSP-SC598 platform. Signed-off-by: Arturs Artamonovs <Arturs.Artamonovs@xxxxxxxxxx> Co-developed-by: Utsav Agarwal <Utsav.Agarwal@xxxxxxxxxx> Signed-off-by: Utsav Agarwal <Utsav.Agarwal@xxxxxxxxxx> Co-developed-by: Nathan Barrett-Morrison <nathan.morrison@xxxxxxxxxxx> Signed-off-by: Nathan Barrett-Morrison <nathan.morrison@xxxxxxxxxxx> Co-developed-by: Greg Malysa <greg.malysa@xxxxxxxxxxx> Signed-off-by: Greg Malysa <greg.malysa@xxxxxxxxxxx> --- 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 + 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, ®map_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@xxxxxxxxxxx>"); +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 -- 2.25.1