* [PATCH 01/21] arm64: Add ADI ADSP-SC598 SoC
2024-09-12 18:24 [PATCH 00/21] Adding support of ADI ARMv8 ADSP-SC598 SoC Arturs Artamonovs via B4 Relay
@ 2024-09-12 18:24 ` Arturs Artamonovs via B4 Relay
2024-09-13 8:16 ` Arnd Bergmann
` (2 more replies)
2024-09-12 18:24 ` [PATCH 02/21] reset: Add driver for ADI ADSP-SC5xx reset controller Arturs Artamonovs via B4 Relay
` (22 subsequent siblings)
23 siblings, 3 replies; 65+ messages in thread
From: Arturs Artamonovs via B4 Relay @ 2024-09-12 18:24 UTC (permalink / raw)
To: Catalin Marinas, Will Deacon, Greg Malysa, Philipp Zabel,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Utsav Agarwal,
Michael Turquette, Stephen Boyd, Linus Walleij,
Bartosz Golaszewski, Thomas Gleixner, Andi Shyti,
Greg Kroah-Hartman, Jiri Slaby, Arnd Bergmann, Olof Johansson,
soc
Cc: linux-arm-kernel, linux-kernel, devicetree, linux-clk, linux-gpio,
linux-i2c, linux-serial, Arturs Artamonovs, adsp-linux,
Arturs Artamonovs, Nathan Barrett-Morrison
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
+
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@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
--
2.25.1
^ permalink raw reply related [flat|nested] 65+ messages in thread
* Re: [PATCH 01/21] arm64: Add ADI ADSP-SC598 SoC
2024-09-12 18:24 ` [PATCH 01/21] arm64: Add ADI " Arturs Artamonovs via B4 Relay
@ 2024-09-13 8:16 ` Arnd Bergmann
2024-09-13 9:54 ` Artamonovs, Arturs
2024-09-14 17:15 ` Markus Elfring
2024-09-16 6:42 ` Krzysztof Kozlowski
2 siblings, 1 reply; 65+ messages in thread
From: Arnd Bergmann @ 2024-09-13 8:16 UTC (permalink / raw)
To: arturs.artamonovs, Catalin Marinas, Will Deacon, Greg Malysa,
Philipp Zabel, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Utsav Agarwal, Michael Turquette, Stephen Boyd, Linus Walleij,
Bartosz Golaszewski, Thomas Gleixner, Andi Shyti,
Greg Kroah-Hartman, Jiri Slaby, Olof Johansson, soc
Cc: linux-arm-kernel, linux-kernel, devicetree, linux-clk,
open list:GPIO SUBSYSTEM, linux-i2c, linux-serial, adsp-linux,
Nathan Barrett-Morrison
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
^ permalink raw reply [flat|nested] 65+ messages in thread
* RE: [PATCH 01/21] arm64: Add ADI ADSP-SC598 SoC
2024-09-13 8:16 ` Arnd Bergmann
@ 2024-09-13 9:54 ` Artamonovs, Arturs
0 siblings, 0 replies; 65+ messages in thread
From: Artamonovs, Arturs @ 2024-09-13 9:54 UTC (permalink / raw)
To: Arnd Bergmann, Catalin Marinas, Will Deacon, Greg Malysa,
Philipp Zabel, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Agarwal, Utsav, Michael Turquette, Stephen Boyd, Linus Walleij,
Bartosz Golaszewski, Thomas Gleixner, Andi Shyti,
Greg Kroah-Hartman, Jiri Slaby, Olof Johansson, 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-i2c@vger.kernel.org, linux-serial@vger.kernel.org,
Linux Factory, Nathan Barrett-Morrison
> -----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
^ permalink raw reply [flat|nested] 65+ messages in thread
* Re: [PATCH 01/21] arm64: Add ADI ADSP-SC598 SoC
2024-09-12 18:24 ` [PATCH 01/21] arm64: Add ADI " Arturs Artamonovs via B4 Relay
2024-09-13 8:16 ` Arnd Bergmann
@ 2024-09-14 17:15 ` Markus Elfring
2024-09-14 17:56 ` Greg Kroah-Hartman
2024-09-16 6:42 ` Krzysztof Kozlowski
2 siblings, 1 reply; 65+ messages in thread
From: Markus Elfring @ 2024-09-14 17:15 UTC (permalink / raw)
To: Arturs Artamonovs, Greg Malysa, Nathan Barrett-Morrison,
Utsav Agarwal, linux-arm-kernel, linux-clk, linux-gpio, linux-i2c,
linux-serial, devicetree, soc, Andi Shyti, Arnd Bergmann,
Bartosz Golaszewski, Catalin Marinas, Conor Dooley,
Greg Kroah-Hartman, Jiri Slaby, Krzysztof Kozlowski,
Linus Walleij, Michael Turquette, Olof Johansson, Philipp Zabel,
Rob Herring, Stephen Boyd, Thomas Gleixner, Will Deacon
Cc: LKML, adsp-linux
…
> +++ 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
^ permalink raw reply [flat|nested] 65+ messages in thread
* Re: [PATCH 01/21] arm64: Add ADI ADSP-SC598 SoC
2024-09-14 17:15 ` Markus Elfring
@ 2024-09-14 17:56 ` Greg Kroah-Hartman
0 siblings, 0 replies; 65+ messages in thread
From: Greg Kroah-Hartman @ 2024-09-14 17:56 UTC (permalink / raw)
To: Markus Elfring
Cc: Arturs Artamonovs, Greg Malysa, Nathan Barrett-Morrison,
Utsav Agarwal, linux-arm-kernel, linux-clk, linux-gpio, linux-i2c,
linux-serial, devicetree, soc, Andi Shyti, Arnd Bergmann,
Bartosz Golaszewski, Catalin Marinas, Conor Dooley, Jiri Slaby,
Krzysztof Kozlowski, Linus Walleij, Michael Turquette,
Olof Johansson, Philipp Zabel, Rob Herring, Stephen Boyd,
Thomas Gleixner, Will Deacon, LKML, adsp-linux
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
^ permalink raw reply [flat|nested] 65+ messages in thread
* Re: [PATCH 01/21] arm64: Add ADI ADSP-SC598 SoC
2024-09-12 18:24 ` [PATCH 01/21] arm64: Add ADI " Arturs Artamonovs via B4 Relay
2024-09-13 8:16 ` Arnd Bergmann
2024-09-14 17:15 ` Markus Elfring
@ 2024-09-16 6:42 ` Krzysztof Kozlowski
2 siblings, 0 replies; 65+ messages in thread
From: Krzysztof Kozlowski @ 2024-09-16 6:42 UTC (permalink / raw)
To: arturs.artamonovs, Catalin Marinas, Will Deacon, Greg Malysa,
Philipp Zabel, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Utsav Agarwal, Michael Turquette, Stephen Boyd, Linus Walleij,
Bartosz Golaszewski, Thomas Gleixner, Andi Shyti,
Greg Kroah-Hartman, Jiri Slaby, Arnd Bergmann, Olof Johansson,
soc
Cc: linux-arm-kernel, linux-kernel, devicetree, linux-clk, linux-gpio,
linux-i2c, linux-serial, adsp-linux, Nathan Barrett-Morrison
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, ®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@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
^ permalink raw reply [flat|nested] 65+ messages in thread
* [PATCH 02/21] reset: Add driver for ADI ADSP-SC5xx reset controller
2024-09-12 18:24 [PATCH 00/21] Adding support of ADI ARMv8 ADSP-SC598 SoC Arturs Artamonovs via B4 Relay
2024-09-12 18:24 ` [PATCH 01/21] arm64: Add ADI " Arturs Artamonovs via B4 Relay
@ 2024-09-12 18:24 ` Arturs Artamonovs via B4 Relay
2024-09-13 7:22 ` Arnd Bergmann
2024-09-12 18:24 ` [PATCH 03/21] dt-bindigs: arm64: adi,sc598 bindings Arturs Artamonovs via B4 Relay
` (21 subsequent siblings)
23 siblings, 1 reply; 65+ messages in thread
From: Arturs Artamonovs via B4 Relay @ 2024-09-12 18:24 UTC (permalink / raw)
To: Catalin Marinas, Will Deacon, Greg Malysa, Philipp Zabel,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Utsav Agarwal,
Michael Turquette, Stephen Boyd, Linus Walleij,
Bartosz Golaszewski, Thomas Gleixner, Andi Shyti,
Greg Kroah-Hartman, Jiri Slaby, Arnd Bergmann, Olof Johansson,
soc
Cc: linux-arm-kernel, linux-kernel, devicetree, linux-clk, linux-gpio,
linux-i2c, linux-serial, Arturs Artamonovs, adsp-linux,
Arturs Artamonovs, Nathan Barrett-Morrison
From: Arturs Artamonovs <arturs.artamonovs@analog.com>
Adding support for ADI ADSP reset controller. This driver allows
trigger a software reset.
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>
---
drivers/reset/Makefile | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile
index 27b0bbdfcc044ba58de9df09725ddef7b601c3ea..4d9e83b7ab38287336175d3804f9d2d4d2894595 100644
--- a/drivers/reset/Makefile
+++ b/drivers/reset/Makefile
@@ -4,6 +4,7 @@ obj-y += hisilicon/
obj-y += starfive/
obj-y += sti/
obj-y += tegra/
+obj-$(CONFIG_RESET_SC5XX) += reset-sc5xx.o
obj-$(CONFIG_RESET_A10SR) += reset-a10sr.o
obj-$(CONFIG_RESET_ATH79) += reset-ath79.o
obj-$(CONFIG_RESET_AXS10X) += reset-axs10x.o
--
2.25.1
^ permalink raw reply related [flat|nested] 65+ messages in thread
* Re: [PATCH 02/21] reset: Add driver for ADI ADSP-SC5xx reset controller
2024-09-12 18:24 ` [PATCH 02/21] reset: Add driver for ADI ADSP-SC5xx reset controller Arturs Artamonovs via B4 Relay
@ 2024-09-13 7:22 ` Arnd Bergmann
0 siblings, 0 replies; 65+ messages in thread
From: Arnd Bergmann @ 2024-09-13 7:22 UTC (permalink / raw)
To: arturs.artamonovs, Catalin Marinas, Will Deacon, Greg Malysa,
Philipp Zabel, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Utsav Agarwal, Michael Turquette, Stephen Boyd, Linus Walleij,
Bartosz Golaszewski, Thomas Gleixner, Andi Shyti,
Greg Kroah-Hartman, Jiri Slaby, Olof Johansson, soc
Cc: linux-arm-kernel, linux-kernel, devicetree, linux-clk,
open list:GPIO SUBSYSTEM, linux-i2c, linux-serial, adsp-linux,
Nathan Barrett-Morrison
On Thu, Sep 12, 2024, at 18:24, Arturs Artamonovs via B4 Relay wrote:
> From: Arturs Artamonovs <arturs.artamonovs@analog.com>
>
> Adding support for ADI ADSP reset controller. This driver allows
> trigger a software reset.
>
> 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>
> ---
> drivers/reset/Makefile | 1 +
> 1 file changed, 1 insertion(+)
It looks like you accidentally dropped the actual driver during
a rebase, this is only the Makefile change.
Arnd
^ permalink raw reply [flat|nested] 65+ messages in thread
* [PATCH 03/21] dt-bindigs: arm64: adi,sc598 bindings
2024-09-12 18:24 [PATCH 00/21] Adding support of ADI ARMv8 ADSP-SC598 SoC Arturs Artamonovs via B4 Relay
2024-09-12 18:24 ` [PATCH 01/21] arm64: Add ADI " Arturs Artamonovs via B4 Relay
2024-09-12 18:24 ` [PATCH 02/21] reset: Add driver for ADI ADSP-SC5xx reset controller Arturs Artamonovs via B4 Relay
@ 2024-09-12 18:24 ` Arturs Artamonovs via B4 Relay
2024-09-13 22:05 ` Rob Herring
2024-09-16 6:44 ` Krzysztof Kozlowski
2024-09-12 18:24 ` [PATCH 04/21] dt-bindings: arm64: adi,sc598: Add ADSP-SC598 SoC bindings Arturs Artamonovs via B4 Relay
` (20 subsequent siblings)
23 siblings, 2 replies; 65+ messages in thread
From: Arturs Artamonovs via B4 Relay @ 2024-09-12 18:24 UTC (permalink / raw)
To: Catalin Marinas, Will Deacon, Greg Malysa, Philipp Zabel,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Utsav Agarwal,
Michael Turquette, Stephen Boyd, Linus Walleij,
Bartosz Golaszewski, Thomas Gleixner, Andi Shyti,
Greg Kroah-Hartman, Jiri Slaby, Arnd Bergmann, Olof Johansson,
soc
Cc: linux-arm-kernel, linux-kernel, devicetree, linux-clk, linux-gpio,
linux-i2c, linux-serial, Arturs Artamonovs, adsp-linux,
Arturs Artamonovs, Nathan Barrett-Morrison
From: Arturs Artamonovs <arturs.artamonovs@analog.com>
Bindigs for ADI ADSP-SC5xx reset controller
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>
---
.../bindings/soc/adi/adi,reset-controller.yaml | 38 ++++++++++++++++++++++
1 file changed, 38 insertions(+)
diff --git a/Documentation/devicetree/bindings/soc/adi/adi,reset-controller.yaml b/Documentation/devicetree/bindings/soc/adi/adi,reset-controller.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..7a6df1cfb709d818d5e3dbcd202938d6aaaaaa9b
--- /dev/null
+++ b/Documentation/devicetree/bindings/soc/adi/adi,reset-controller.yaml
@@ -0,0 +1,38 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/soc/adi/adi,reset-controller.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Analog Devices Reset Controller for SC5XX processor family
+
+maintainers:
+ - Arturs Artamonovs <arturs.artamonovs@analog.com>
+ - Utsav Agarwal <Utsav.Agarwal@analog.com>
+
+description: |
+ SHARC and ARM core reset control unit for starting/stopping/resetting
+ processors
+
+properties:
+ compatible:
+ enum:
+ - adi,reset-controller
+
+ reg:
+ maxItems: 1
+
+required:
+ - compatible
+ - reg
+
+additionalProperties: false
+
+examples:
+ - |
+ rcu: rcu@3108c000 {
+ compatible = "adi,reset-controller";
+ reg = <0x3108c000 0x1000>;
+ status = "okay";
+ };
+
--
2.25.1
^ permalink raw reply related [flat|nested] 65+ messages in thread
* Re: [PATCH 03/21] dt-bindigs: arm64: adi,sc598 bindings
2024-09-12 18:24 ` [PATCH 03/21] dt-bindigs: arm64: adi,sc598 bindings Arturs Artamonovs via B4 Relay
@ 2024-09-13 22:05 ` Rob Herring
2024-09-16 6:44 ` Krzysztof Kozlowski
1 sibling, 0 replies; 65+ messages in thread
From: Rob Herring @ 2024-09-13 22:05 UTC (permalink / raw)
To: Arturs Artamonovs
Cc: Catalin Marinas, Will Deacon, Greg Malysa, Philipp Zabel,
Krzysztof Kozlowski, Conor Dooley, Utsav Agarwal,
Michael Turquette, Stephen Boyd, Linus Walleij,
Bartosz Golaszewski, Thomas Gleixner, Andi Shyti,
Greg Kroah-Hartman, Jiri Slaby, Arnd Bergmann, Olof Johansson,
soc, linux-arm-kernel, linux-kernel, devicetree, linux-clk,
linux-gpio, linux-i2c, linux-serial, adsp-linux,
Nathan Barrett-Morrison
On Thu, Sep 12, 2024 at 07:24:48PM +0100, Arturs Artamonovs wrote:
> Bindigs for ADI ADSP-SC5xx reset controller
Typo. Here and the subject. Please write complete sentences.
>
> 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>
> ---
> .../bindings/soc/adi/adi,reset-controller.yaml | 38 ++++++++++++++++++++++
> 1 file changed, 38 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/soc/adi/adi,reset-controller.yaml b/Documentation/devicetree/bindings/soc/adi/adi,reset-controller.yaml
> new file mode 100644
> index 0000000000000000000000000000000000000000..7a6df1cfb709d818d5e3dbcd202938d6aaaaaa9b
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/soc/adi/adi,reset-controller.yaml
> @@ -0,0 +1,38 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/soc/adi/adi,reset-controller.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Analog Devices Reset Controller for SC5XX processor family
> +
> +maintainers:
> + - Arturs Artamonovs <arturs.artamonovs@analog.com>
> + - Utsav Agarwal <Utsav.Agarwal@analog.com>
> +
> +description: |
Don't need '|'
> + SHARC and ARM core reset control unit for starting/stopping/resetting
> + processors
Complete sentences for top-level description.
> +
> +properties:
> + compatible:
> + enum:
> + - adi,reset-controller
Too generic.
> +
> + reg:
> + maxItems: 1
> +
> +required:
> + - compatible
> + - reg
> +
> +additionalProperties: false
> +
> +examples:
> + - |
> + rcu: rcu@3108c000 {
> + compatible = "adi,reset-controller";
> + reg = <0x3108c000 0x1000>;
> + status = "okay";
Don't need status in examples.
Shouldn't a reset controller use the reset binding (i.e. #reset-cells)?
All you patches seem to have similar issues, so I'm not going to comment
on all of them. Please read the documentation in
Documentation/devicetree/bindings/. It doesn't seem like you have.
Rob
^ permalink raw reply [flat|nested] 65+ messages in thread
* Re: [PATCH 03/21] dt-bindigs: arm64: adi,sc598 bindings
2024-09-12 18:24 ` [PATCH 03/21] dt-bindigs: arm64: adi,sc598 bindings Arturs Artamonovs via B4 Relay
2024-09-13 22:05 ` Rob Herring
@ 2024-09-16 6:44 ` Krzysztof Kozlowski
1 sibling, 0 replies; 65+ messages in thread
From: Krzysztof Kozlowski @ 2024-09-16 6:44 UTC (permalink / raw)
To: arturs.artamonovs, Catalin Marinas, Will Deacon, Greg Malysa,
Philipp Zabel, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Utsav Agarwal, Michael Turquette, Stephen Boyd, Linus Walleij,
Bartosz Golaszewski, Thomas Gleixner, Andi Shyti,
Greg Kroah-Hartman, Jiri Slaby, Arnd Bergmann, Olof Johansson,
soc
Cc: linux-arm-kernel, linux-kernel, devicetree, linux-clk, linux-gpio,
linux-i2c, linux-serial, adsp-linux, Nathan Barrett-Morrison
On 12/09/2024 20:24, Arturs Artamonovs via B4 Relay wrote:
> From: Arturs Artamonovs <arturs.artamonovs@analog.com>
>
> Bindigs for ADI ADSP-SC5xx reset controller
Please use subject prefixes matching the subsystem. You can get them for
example with `git log --oneline -- DIRECTORY_OR_FILE` on the directory
your patch is touching. For bindings, the preferred subjects are
explained here:
https://www.kernel.org/doc/html/latest/devicetree/bindings/submitting-patches.html#i-for-patch-submitters
It is dt-bindings: soc: adi:... if it was in soc.
>
> 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>
> ---
> .../bindings/soc/adi/adi,reset-controller.yaml | 38 ++++++++++++++++++++++
> 1 file changed, 38 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/soc/adi/adi,reset-controller.yaml b/Documentation/devicetree/bindings/soc/adi/adi,reset-controller.yaml
Nope, don't just dump stuff to soc. This is reset controller so goes to
reset.
> new file mode 100644
> index 0000000000000000000000000000000000000000..7a6df1cfb709d818d5e3dbcd202938d6aaaaaa9b
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/soc/adi/adi,reset-controller.yaml
> @@ -0,0 +1,38 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/soc/adi/adi,reset-controller.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Analog Devices Reset Controller for SC5XX processor family
> +
> +maintainers:
> + - Arturs Artamonovs <arturs.artamonovs@analog.com>
> + - Utsav Agarwal <Utsav.Agarwal@analog.com>
> +
> +description: |
> + SHARC and ARM core reset control unit for starting/stopping/resetting
> + processors
> +
> +properties:
> + compatible:
> + enum:
> + - adi,reset-controller
> +
> + reg:
> + maxItems: 1
> +
> +required:
> + - compatible
> + - reg
> +
> +additionalProperties: false
> +
> +examples:
> + - |
> + rcu: rcu@3108c000 {
Drop unused label.
> + compatible = "adi,reset-controller";
> + reg = <0x3108c000 0x1000>;
> + status = "okay";
Drop
> + };
> +
>
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 65+ messages in thread
* [PATCH 04/21] dt-bindings: arm64: adi,sc598: Add ADSP-SC598 SoC bindings
2024-09-12 18:24 [PATCH 00/21] Adding support of ADI ARMv8 ADSP-SC598 SoC Arturs Artamonovs via B4 Relay
` (2 preceding siblings ...)
2024-09-12 18:24 ` [PATCH 03/21] dt-bindigs: arm64: adi,sc598 bindings Arturs Artamonovs via B4 Relay
@ 2024-09-12 18:24 ` Arturs Artamonovs via B4 Relay
2024-09-16 6:45 ` Krzysztof Kozlowski
2024-09-12 18:24 ` [PATCH 05/21] clock:Add driver for ADI ADSP-SC5xx PLL Arturs Artamonovs via B4 Relay
` (19 subsequent siblings)
23 siblings, 1 reply; 65+ messages in thread
From: Arturs Artamonovs via B4 Relay @ 2024-09-12 18:24 UTC (permalink / raw)
To: Catalin Marinas, Will Deacon, Greg Malysa, Philipp Zabel,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Utsav Agarwal,
Michael Turquette, Stephen Boyd, Linus Walleij,
Bartosz Golaszewski, Thomas Gleixner, Andi Shyti,
Greg Kroah-Hartman, Jiri Slaby, Arnd Bergmann, Olof Johansson,
soc
Cc: linux-arm-kernel, linux-kernel, devicetree, linux-clk, linux-gpio,
linux-i2c, linux-serial, Arturs Artamonovs, adsp-linux,
Arturs Artamonovs, Nathan Barrett-Morrison
From: Arturs Artamonovs <arturs.artamonovs@analog.com>
add SoC ADSP-SC5xx
Signed-off-by: Arturs Artamonovs <Arturs.Artamonovs@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>
---
.../devicetree/bindings/arm/analog/adi,sc5xx.yaml | 24 ++++++++++++++++++++++
1 file changed, 24 insertions(+)
diff --git a/Documentation/devicetree/bindings/arm/analog/adi,sc5xx.yaml b/Documentation/devicetree/bindings/arm/analog/adi,sc5xx.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..fc37242b32b9ca9b82fd5b3e0288642e8c4fd9f0
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/analog/adi,sc5xx.yaml
@@ -0,0 +1,24 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/arm/analog/adi,sc5xx.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Analog Devices SC59X 64-Bit ARM-based Processor Families
+
+maintainers:
+ - Arturs Artamonovs <arturs.artamonovs@analog.com>
+ - Utsav Agarwal <Utsav.Agarwal@analog.com>
+
+properties:
+ $nodename:
+ const: '/'
+ compatible:
+ description: SC59X 64-Bit Boards
+ items:
+ - enum:
+ - adi,sc598-som-ezkit # Analog Devices SC598 EZKit
+ - adi,sc598-som-ezlite # Analog Devices SC598 EZLite
+ - const: adi,sc59x-64
+
+additionalProperties: true
--
2.25.1
^ permalink raw reply related [flat|nested] 65+ messages in thread
* Re: [PATCH 04/21] dt-bindings: arm64: adi,sc598: Add ADSP-SC598 SoC bindings
2024-09-12 18:24 ` [PATCH 04/21] dt-bindings: arm64: adi,sc598: Add ADSP-SC598 SoC bindings Arturs Artamonovs via B4 Relay
@ 2024-09-16 6:45 ` Krzysztof Kozlowski
0 siblings, 0 replies; 65+ messages in thread
From: Krzysztof Kozlowski @ 2024-09-16 6:45 UTC (permalink / raw)
To: arturs.artamonovs, Catalin Marinas, Will Deacon, Greg Malysa,
Philipp Zabel, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Utsav Agarwal, Michael Turquette, Stephen Boyd, Linus Walleij,
Bartosz Golaszewski, Thomas Gleixner, Andi Shyti,
Greg Kroah-Hartman, Jiri Slaby, Arnd Bergmann, Olof Johansson,
soc
Cc: linux-arm-kernel, linux-kernel, devicetree, linux-clk, linux-gpio,
linux-i2c, linux-serial, adsp-linux, Nathan Barrett-Morrison
On 12/09/2024 20:24, Arturs Artamonovs via B4 Relay wrote:
> From: Arturs Artamonovs <arturs.artamonovs@analog.com>
>
> add SoC ADSP-SC5xx
>
> Signed-off-by: Arturs Artamonovs <Arturs.Artamonovs@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>
> ---
> .../devicetree/bindings/arm/analog/adi,sc5xx.yaml | 24 ++++++++++++++++++++++
There is no arm64 prefix above. Fix subject.
A nit, subject: drop second/last, redundant "bindings". The
"dt-bindings" prefix is already stating that these are bindings.
See also:
https://elixir.bootlin.com/linux/v6.7-rc8/source/Documentation/devicetree/bindings/submitting-patches.rst#L18
> 1 file changed, 24 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/arm/analog/adi,sc5xx.yaml b/Documentation/devicetree/bindings/arm/analog/adi,sc5xx.yaml
> new file mode 100644
> index 0000000000000000000000000000000000000000..fc37242b32b9ca9b82fd5b3e0288642e8c4fd9f0
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/arm/analog/adi,sc5xx.yaml
> @@ -0,0 +1,24 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/arm/analog/adi,sc5xx.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Analog Devices SC59X 64-Bit ARM-based Processor Families
> +
> +maintainers:
> + - Arturs Artamonovs <arturs.artamonovs@analog.com>
> + - Utsav Agarwal <Utsav.Agarwal@analog.com>
> +
> +properties:
> + $nodename:
> + const: '/'
> + compatible:
> + description: SC59X 64-Bit Boards
> + items:
> + - enum:
> + - adi,sc598-som-ezkit # Analog Devices SC598 EZKit
> + - adi,sc598-som-ezlite # Analog Devices SC598 EZLite
> + - const: adi,sc59x-64
sc59x is incorrect. Enum above says sc598. Define what is the SoC here.
You cannot have compatible for families.
> +
> +additionalProperties: true
>
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 65+ messages in thread
* [PATCH 05/21] clock:Add driver for ADI ADSP-SC5xx PLL
2024-09-12 18:24 [PATCH 00/21] Adding support of ADI ARMv8 ADSP-SC598 SoC Arturs Artamonovs via B4 Relay
` (3 preceding siblings ...)
2024-09-12 18:24 ` [PATCH 04/21] dt-bindings: arm64: adi,sc598: Add ADSP-SC598 SoC bindings Arturs Artamonovs via B4 Relay
@ 2024-09-12 18:24 ` Arturs Artamonovs via B4 Relay
2024-09-13 7:27 ` Arnd Bergmann
2024-09-16 6:46 ` Krzysztof Kozlowski
2024-09-12 18:24 ` [PATCH 06/21] include: dt-binding: clock: add adi clock header file Arturs Artamonovs via B4 Relay
` (18 subsequent siblings)
23 siblings, 2 replies; 65+ messages in thread
From: Arturs Artamonovs via B4 Relay @ 2024-09-12 18:24 UTC (permalink / raw)
To: Catalin Marinas, Will Deacon, Greg Malysa, Philipp Zabel,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Utsav Agarwal,
Michael Turquette, Stephen Boyd, Linus Walleij,
Bartosz Golaszewski, Thomas Gleixner, Andi Shyti,
Greg Kroah-Hartman, Jiri Slaby, Arnd Bergmann, Olof Johansson,
soc
Cc: linux-arm-kernel, linux-kernel, devicetree, linux-clk, linux-gpio,
linux-i2c, linux-serial, Arturs Artamonovs, adsp-linux,
Arturs Artamonovs, Nathan Barrett-Morrison
From: Arturs Artamonovs <arturs.artamonovs@analog.com>
Implements clock tree, no dynamic pll rate change.
Signed-off-by: Arturs Artamonovs <Arturs.Artamonovs@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>
---
drivers/clk/adi/clk-adi-pll.c | 151 ++++++++++++++++++++++++++++++++++++++++++
drivers/clk/adi/clk.h | 99 +++++++++++++++++++++++++++
2 files changed, 250 insertions(+)
diff --git a/drivers/clk/adi/clk-adi-pll.c b/drivers/clk/adi/clk-adi-pll.c
new file mode 100644
index 0000000000000000000000000000000000000000..39fcc78b3170c0aa5962af5268f499082efb3686
--- /dev/null
+++ b/drivers/clk/adi/clk-adi-pll.c
@@ -0,0 +1,151 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * CGU PLL driver for ADI SC59X processors
+ *
+ * Copyright 2022-2024 - Analog Devices Inc.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <linux/device.h>
+
+#include "clk.h"
+
+struct clk_sc5xx_cgu_pll {
+ struct clk_hw hw;
+ void __iomem *base;
+ spinlock_t *lock;
+ int prepared;
+ u32 mask;
+ u32 msel;
+ u32 m_offset;
+ u8 shift;
+};
+
+struct clk_sc5xx_cgu_pll *to_clk_sc5xx_cgu_pll(struct clk_hw *hw)
+{
+ return container_of(hw, struct clk_sc5xx_cgu_pll, hw);
+}
+
+static long sc5xx_cgu_pll_round_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long *parent_rate)
+{
+ struct clk_sc5xx_cgu_pll *pll = to_clk_sc5xx_cgu_pll(hw);
+ unsigned long m, m2, new_rate, nr2, prate2;
+ unsigned long prate = *parent_rate;
+ struct clk_hw *parent_hw;
+ int parent_inc;
+
+ parent_hw = clk_hw_get_parent(hw);
+
+ m = rate / prate;
+
+ if (m > pll->msel) {
+ /* cannot scale this far, need bigger input */
+ parent_inc = m / pll->msel;
+ prate = clk_hw_round_rate(parent_hw, prate * (parent_inc + 1));
+ } else if (m == 0) {
+ pr_err("%s: Cannot use VCO to reduce parent clock rate, requested %lu, clamping to %lu\n",
+ __func__, rate, prate);
+ return prate;
+ }
+
+ new_rate = prate * m;
+
+ if (new_rate != rate) {
+ /*
+ * Check if we could get an integer match by halving parent rate since we
+ * know at least about the DF bit before the VCO, although we don't know
+ * if we're already using it or not
+ */
+ prate2 = clk_hw_round_rate(parent_hw, prate / 2);
+ m2 = rate / prate2;
+ nr2 = prate * m2;
+ if (m2 <= pll->msel && nr2 == rate) {
+ m = m2;
+ new_rate = nr2;
+ prate = prate2;
+ }
+ }
+
+ *parent_rate = prate;
+ return new_rate;
+}
+
+static unsigned long sc5xx_cgu_pll_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ struct clk_sc5xx_cgu_pll *pll = to_clk_sc5xx_cgu_pll(hw);
+ u32 reg = readl(pll->base);
+ u32 m = ((reg & pll->mask) >> pll->shift) + pll->m_offset;
+
+ if (m == 0)
+ m = pll->msel;
+
+ return parent_rate * m;
+
+}
+
+static int sc5xx_cgu_pll_set_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long parent_rate)
+{
+ struct clk_sc5xx_cgu_pll *pll = to_clk_sc5xx_cgu_pll(hw);
+ u32 m;
+
+ m = (rate / parent_rate) - pll->m_offset;
+
+ if (m >= pll->msel)
+ m = 0;
+
+ /* reminder for implementation: lock around read/modify to control reg */
+ pr_err("%s: set_rate not permitted yet, but we would write %d to m\n", __func__,
+ m);
+ return -ENOENT;
+}
+
+static const struct clk_ops clk_sc5xx_cgu_pll_ops = {
+ .recalc_rate = sc5xx_cgu_pll_recalc_rate,
+ .round_rate = sc5xx_cgu_pll_round_rate,
+ .set_rate = sc5xx_cgu_pll_set_rate,
+};
+
+struct clk *sc5xx_cgu_pll(const char *name, const char *parent_name,
+ void __iomem *base, u8 shift, u8 width, u32 m_offset,
+ spinlock_t *lock)
+{
+ struct clk_sc5xx_cgu_pll *pll;
+ struct clk *clk;
+ struct clk_init_data init;
+
+ pll = kzalloc(sizeof(*pll), GFP_KERNEL);
+ if (!pll)
+ return ERR_PTR(-ENOMEM);
+
+ init.name = name;
+ init.flags = CLK_SET_RATE_PARENT;
+ init.parent_names = &parent_name;
+ init.num_parents = 1;
+ init.ops = &clk_sc5xx_cgu_pll_ops;
+
+ pll->base = base;
+ pll->hw.init = &init;
+ pll->lock = lock;
+ pll->shift = shift;
+ pll->mask = GENMASK(width-1, 0) << shift;
+ pll->msel = pll->mask + 1;
+ pll->m_offset = m_offset;
+
+ clk = clk_register(NULL, &pll->hw);
+ if (IS_ERR(clk)) {
+ pr_err("%s: Failed to register, code %lu\n", __func__,
+ PTR_ERR(clk));
+ }
+
+ return clk;
+}
+
+MODULE_DESCRIPTION("Analog Devices CLock PLL driver");
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Greg Malysa <greg.malysa@timesys.com>");
+
diff --git a/drivers/clk/adi/clk.h b/drivers/clk/adi/clk.h
new file mode 100644
index 0000000000000000000000000000000000000000..e17aa719c2170149a6a1a60dd4390a29f06e7296
--- /dev/null
+++ b/drivers/clk/adi/clk.h
@@ -0,0 +1,99 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Clock support for ADI processors
+ *
+ * Copyright 2022-2024 - Analog Devices Inc.
+ */
+
+#ifndef CLK_ADI_CLK_H
+#define CLK_ADI_CLK_H
+
+#include <linux/clk.h>
+
+#define CGU_CTL 0x00
+#define CGU_PLLCTL 0x04
+#define CGU_STAT 0x08
+#define CGU_DIV 0x0C
+#define CGU_CLKOUTSEL 0x10
+#define CGU_OSCWDCTL 0x14
+#define CGU_TSCTL 0x18
+#define CGU_TSVALUE0 0x1C
+#define CGU_TSVALUE1 0x20
+#define CGU_TSCOUNT0 0x24
+#define CGU_TSCOUNT1 0x28
+#define CGU_CCBF_DIS 0x2C
+#define CGU_CCBF_STAT 0x30
+#define CGU_SCBF_DIS 0x38
+#define CGU_SCBF_STAT 0x3C
+#define CGU_DIVEX 0x40
+#define CGU_REVID 0x48
+
+#define CDU_CFG0 0x00
+#define CDU_CFG1 0x04
+#define CDU_CFG2 0x08
+#define CDU_CFG3 0x0C
+#define CDU_CFG4 0x10
+#define CDU_CFG5 0x14
+#define CDU_CFG6 0x18
+#define CDU_CFG7 0x1C
+#define CDU_CFG8 0x20
+#define CDU_CFG9 0x24
+#define CDU_CFG10 0x28
+#define CDU_CFG11 0x2C
+#define CDU_CFG12 0x30
+#define CDU_CFG13 0x34
+#define CDU_CFG14 0x38
+
+#define PLL3_OFFSET 0x2c
+
+#define CDU_CLKINSEL 0x44
+
+#define CGU_MSEL_SHIFT 8
+#define CGU_MSEL_WIDTH 7
+
+#define PLL3_MSEL_SHIFT 4
+#define PLL3_MSEL_WIDTH 7
+
+#define CDU_MUX_SIZE 4
+#define CDU_MUX_SHIFT 1
+#define CDU_MUX_WIDTH 2
+#define CDU_EN_BIT 0
+
+struct clk_sc5xx_cgu_pll *to_clk_sc5xx_cgu_pll(struct clk_hw *hw);
+
+struct clk *sc5xx_cgu_pll(const char *name, const char *parent_name,
+ void __iomem *base, u8 shift, u8 width, u32 m_offset, spinlock_t *lock);
+
+/**
+ * All CDU clock muxes are the same size
+ */
+static inline struct clk *cdu_mux(const char *name, void __iomem *reg,
+ const char * const *parents, spinlock_t *cdu_lock)
+{
+ return clk_register_mux(NULL, name, parents, CDU_MUX_SIZE,
+ CLK_SET_RATE_PARENT, reg, CDU_MUX_SHIFT, CDU_MUX_WIDTH, 0,
+ cdu_lock);
+}
+
+static inline struct clk *cgu_divider(const char *name, const char *parent,
+ void __iomem *reg, u8 shift, u8 width, u8 extra_flags, spinlock_t *cdu_lock)
+{
+ return clk_register_divider(NULL, name, parent, CLK_SET_RATE_PARENT,
+ reg, shift, width, CLK_DIVIDER_MAX_AT_ZERO | extra_flags, cdu_lock);
+}
+
+static inline struct clk *cdu_gate(const char *name, const char *parent,
+ void __iomem *reg, u32 flags, spinlock_t *cdu_lock)
+{
+ return clk_register_gate(NULL, name, parent, CLK_SET_RATE_PARENT | flags,
+ reg, CDU_EN_BIT, 0, cdu_lock);
+}
+
+static inline struct clk *cgu_gate(const char *name, const char *parent,
+ void __iomem *reg, u8 bit, spinlock_t *cdu_lock)
+{
+ return clk_register_gate(NULL, name, parent, CLK_SET_RATE_PARENT, reg, bit,
+ CLK_GATE_SET_TO_DISABLE, cdu_lock);
+}
+
+#endif
--
2.25.1
^ permalink raw reply related [flat|nested] 65+ messages in thread
* Re: [PATCH 05/21] clock:Add driver for ADI ADSP-SC5xx PLL
2024-09-12 18:24 ` [PATCH 05/21] clock:Add driver for ADI ADSP-SC5xx PLL Arturs Artamonovs via B4 Relay
@ 2024-09-13 7:27 ` Arnd Bergmann
2024-09-16 6:46 ` Krzysztof Kozlowski
1 sibling, 0 replies; 65+ messages in thread
From: Arnd Bergmann @ 2024-09-13 7:27 UTC (permalink / raw)
To: arturs.artamonovs, Catalin Marinas, Will Deacon, Greg Malysa,
Philipp Zabel, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Utsav Agarwal, Michael Turquette, Stephen Boyd, Linus Walleij,
Bartosz Golaszewski, Thomas Gleixner, Andi Shyti,
Greg Kroah-Hartman, Jiri Slaby, Olof Johansson, soc
Cc: linux-arm-kernel, linux-kernel, devicetree, linux-clk,
open list:GPIO SUBSYSTEM, linux-i2c, linux-serial, adsp-linux,
Nathan Barrett-Morrison
On Thu, Sep 12, 2024, at 18:24, Arturs Artamonovs via B4 Relay wrote:
> From: Arturs Artamonovs <arturs.artamonovs@analog.com>
>
> Implements clock tree, no dynamic pll rate change.
This could use a little more detail.
> drivers/clk/adi/clk-adi-pll.c | 151 ++++++++++++++++++++++++++++++++++++++++++
> drivers/clk/adi/clk.h | 99 +++++++++++++++++++++++++++
> 2 files changed, 250 insertions(+)
The header is only used in one file, to it's better to move all
the contents into the driver itself.
> +struct clk_sc5xx_cgu_pll *to_clk_sc5xx_cgu_pll(struct clk_hw *hw);
> +
> +struct clk *sc5xx_cgu_pll(const char *name, const char *parent_name,
> + void __iomem *base, u8 shift, u8 width, u32 m_offset, spinlock_t
> *lock);
Do these need to be global symbols? It's generally better to make
all functions 'static' unless they need to be called from another file.
Arnd
^ permalink raw reply [flat|nested] 65+ messages in thread
* Re: [PATCH 05/21] clock:Add driver for ADI ADSP-SC5xx PLL
2024-09-12 18:24 ` [PATCH 05/21] clock:Add driver for ADI ADSP-SC5xx PLL Arturs Artamonovs via B4 Relay
2024-09-13 7:27 ` Arnd Bergmann
@ 2024-09-16 6:46 ` Krzysztof Kozlowski
1 sibling, 0 replies; 65+ messages in thread
From: Krzysztof Kozlowski @ 2024-09-16 6:46 UTC (permalink / raw)
To: arturs.artamonovs, Catalin Marinas, Will Deacon, Greg Malysa,
Philipp Zabel, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Utsav Agarwal, Michael Turquette, Stephen Boyd, Linus Walleij,
Bartosz Golaszewski, Thomas Gleixner, Andi Shyti,
Greg Kroah-Hartman, Jiri Slaby, Arnd Bergmann, Olof Johansson,
soc
Cc: linux-arm-kernel, linux-kernel, devicetree, linux-clk, linux-gpio,
linux-i2c, linux-serial, adsp-linux, Nathan Barrett-Morrison
On 12/09/2024 20:24, Arturs Artamonovs via B4 Relay wrote:
> From: Arturs Artamonovs <arturs.artamonovs@analog.com>
>
> Implements clock tree, no dynamic pll rate change.
>
> Signed-off-by: Arturs Artamonovs <Arturs.Artamonovs@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>
> ---
> drivers/clk/adi/clk-adi-pll.c | 151 ++++++++++++++++++++++++++++++++++++++++++
> drivers/clk/adi/clk.h | 99 +++++++++++++++++++++++++++
> 2 files changed, 250 insertions(+)
How do you even build this code? Never built, so never tested?
> +struct clk *sc5xx_cgu_pll(const char *name, const char *parent_name,
> + void __iomem *base, u8 shift, u8 width, u32 m_offset,
> + spinlock_t *lock)
> +{
> + struct clk_sc5xx_cgu_pll *pll;
> + struct clk *clk;
> + struct clk_init_data init;
> +
> + pll = kzalloc(sizeof(*pll), GFP_KERNEL);
> + if (!pll)
> + return ERR_PTR(-ENOMEM);
> +
> + init.name = name;
> + init.flags = CLK_SET_RATE_PARENT;
> + init.parent_names = &parent_name;
> + init.num_parents = 1;
> + init.ops = &clk_sc5xx_cgu_pll_ops;
> +
> + pll->base = base;
> + pll->hw.init = &init;
> + pll->lock = lock;
> + pll->shift = shift;
> + pll->mask = GENMASK(width-1, 0) << shift;
> + pll->msel = pll->mask + 1;
> + pll->m_offset = m_offset;
> +
> + clk = clk_register(NULL, &pll->hw);
> + if (IS_ERR(clk)) {
> + pr_err("%s: Failed to register, code %lu\n", __func__,
> + PTR_ERR(clk));
> + }
> +
> + return clk;
> +}
> +
> +MODULE_DESCRIPTION("Analog Devices CLock PLL driver");
> +MODULE_LICENSE("GPL v2");
> +MODULE_AUTHOR("Greg Malysa <greg.malysa@timesys.com>");
> +
Multiple patches have messy blank line handling...
> diff --git a/drivers/clk/adi/clk.h b/drivers/clk/adi/clk.h
> new file mode 100644
> index 0000000000000000000000000000000000000000..e17aa719c2170149a6a1a60dd4390a29f06e7296
> --- /dev/null
> +++ b/drivers/clk/adi/clk.h
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 65+ messages in thread
* [PATCH 06/21] include: dt-binding: clock: add adi clock header file
2024-09-12 18:24 [PATCH 00/21] Adding support of ADI ARMv8 ADSP-SC598 SoC Arturs Artamonovs via B4 Relay
` (4 preceding siblings ...)
2024-09-12 18:24 ` [PATCH 05/21] clock:Add driver for ADI ADSP-SC5xx PLL Arturs Artamonovs via B4 Relay
@ 2024-09-12 18:24 ` Arturs Artamonovs via B4 Relay
2024-09-13 7:35 ` Arnd Bergmann
` (2 more replies)
2024-09-12 18:24 ` [PATCH 07/21] clock: Add driver for ADI ADSP-SC5xx clock Arturs Artamonovs via B4 Relay
` (17 subsequent siblings)
23 siblings, 3 replies; 65+ messages in thread
From: Arturs Artamonovs via B4 Relay @ 2024-09-12 18:24 UTC (permalink / raw)
To: Catalin Marinas, Will Deacon, Greg Malysa, Philipp Zabel,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Utsav Agarwal,
Michael Turquette, Stephen Boyd, Linus Walleij,
Bartosz Golaszewski, Thomas Gleixner, Andi Shyti,
Greg Kroah-Hartman, Jiri Slaby, Arnd Bergmann, Olof Johansson,
soc
Cc: linux-arm-kernel, linux-kernel, devicetree, linux-clk, linux-gpio,
linux-i2c, linux-serial, Arturs Artamonovs, adsp-linux,
Arturs Artamonovs, Nathan Barrett-Morrison
From: Arturs Artamonovs <arturs.artamonovs@analog.com>
Add adi clock driver header file
Signed-off-by: Arturs Artamonovs <Arturs.Artamonovs@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>
---
include/dt-bindings/clock/adi-sc5xx-clock.h | 93 +++++++++++++++++++++++++++++
1 file changed, 93 insertions(+)
diff --git a/include/dt-bindings/clock/adi-sc5xx-clock.h b/include/dt-bindings/clock/adi-sc5xx-clock.h
new file mode 100644
index 0000000000000000000000000000000000000000..723c11dc44f9741cff49dc2cb6c5232022abf00c
--- /dev/null
+++ b/include/dt-bindings/clock/adi-sc5xx-clock.h
@@ -0,0 +1,93 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * ADSP SC5xx clock device tree bindings
+ *
+ * Copyright 2022-2024 - Analog Devices Inc.
+ */
+
+#ifndef DT_BINDINGS_CLOCK_ADI_SC5XX_CLOCK_H
+#define DT_BINDINGS_CLOCK_ADI_SC5XX_CLOCK_H
+
+#define ADSP_SC598_CLK_DUMMY 0
+#define ADSP_SC598_CLK_SYS_CLKIN0 1
+#define ADSP_SC598_CLK_SYS_CLKIN1 2
+#define ADSP_SC598_CLK_CGU0_PLL_IN 3
+#define ADSP_SC598_CLK_CGU0_VCO_OUT 4
+#define ADSP_SC598_CLK_CGU0_PLLCLK 5
+#define ADSP_SC598_CLK_CGU1_IN 6
+#define ADSP_SC598_CLK_CGU1_PLL_IN 7
+#define ADSP_SC598_CLK_CGU1_VCO_OUT 8
+#define ADSP_SC598_CLK_CGU1_PLLCLK 9
+#define ADSP_SC598_CLK_CGU0_CDIV 10
+#define ADSP_SC598_CLK_CGU0_SYSCLK 11
+#define ADSP_SC598_CLK_CGU0_DDIV 12
+#define ADSP_SC598_CLK_CGU0_ODIV 13
+#define ADSP_SC598_CLK_CGU0_S0SELDIV 14
+#define ADSP_SC598_CLK_CGU0_S1SELDIV 15
+#define ADSP_SC598_CLK_CGU0_S1SELEXDIV 16
+#define ADSP_SC598_CLK_CGU0_S1SEL 17
+#define ADSP_SC598_CLK_CGU1_CDIV 18
+#define ADSP_SC598_CLK_CGU1_SYSCLK 19
+#define ADSP_SC598_CLK_CGU1_DDIV 20
+#define ADSP_SC598_CLK_CGU1_ODIV 21
+#define ADSP_SC598_CLK_CGU1_S0SELDIV 22
+#define ADSP_SC598_CLK_CGU1_S1SELDIV 23
+#define ADSP_SC598_CLK_CGU1_S0SELEXDIV 24
+#define ADSP_SC598_CLK_CGU1_S1SELEXDIV 25
+#define ADSP_SC598_CLK_CGU1_S0SEL 26
+#define ADSP_SC598_CLK_CGU1_S1SEL 27
+#define ADSP_SC598_CLK_CGU0_CCLK2 28
+#define ADSP_SC598_CLK_CGU0_CCLK0 29
+#define ADSP_SC598_CLK_CGU0_OCLK 30
+#define ADSP_SC598_CLK_CGU0_DCLK 31
+#define ADSP_SC598_CLK_CGU0_SCLK1 32
+#define ADSP_SC598_CLK_CGU0_SCLK0 33
+#define ADSP_SC598_CLK_CGU1_CCLK0 34
+#define ADSP_SC598_CLK_CGU1_OCLK 35
+#define ADSP_SC598_CLK_CGU1_DCLK 36
+#define ADSP_SC598_CLK_CGU1_SCLK1 37
+#define ADSP_SC598_CLK_CGU1_SCLK0 38
+#define ADSP_SC598_CLK_CGU1_CCLK2 39
+#define ADSP_SC598_CLK_DCLK0_HALF 40
+#define ADSP_SC598_CLK_DCLK1_HALF 41
+#define ADSP_SC598_CLK_CGU1_SCLK1_HALF 42
+#define ADSP_SC598_CLK_SHARC0_SEL 43
+#define ADSP_SC598_CLK_SHARC1_SEL 44
+#define ADSP_SC598_CLK_ARM_SEL 45
+#define ADSP_SC598_CLK_CDU_DDR_SEL 46
+#define ADSP_SC598_CLK_CAN_SEL 47
+#define ADSP_SC598_CLK_SPDIF_SEL 48
+#define ADSP_SC598_CLK_SPI_SEL 49
+#define ADSP_SC598_CLK_GIGE_SEL 50
+#define ADSP_SC598_CLK_LP_SEL 51
+#define ADSP_SC598_CLK_LP_DDR_SEL 52
+#define ADSP_SC598_CLK_OSPI_REFCLK_SEL 53
+#define ADSP_SC598_CLK_TRACE_SEL 54
+#define ADSP_SC598_CLK_EMMC_SEL 55
+#define ADSP_SC598_CLK_EMMC_TIMER_QMC_SEL 56
+#define ADSP_SC598_CLK_SHARC0 57
+#define ADSP_SC598_CLK_SHARC1 58
+#define ADSP_SC598_CLK_ARM 59
+#define ADSP_SC598_CLK_CDU_DDR 60
+#define ADSP_SC598_CLK_CAN 61
+#define ADSP_SC598_CLK_SPDIF 62
+#define ADSP_SC598_CLK_SPI 63
+#define ADSP_SC598_CLK_GIGE 64
+#define ADSP_SC598_CLK_LP 65
+#define ADSP_SC598_CLK_LP_DDR 66
+#define ADSP_SC598_CLK_OSPI_REFCLK 67
+#define ADSP_SC598_CLK_TRACE 68
+#define ADSP_SC598_CLK_EMMC 69
+#define ADSP_SC598_CLK_EMMC_TIMER_QMC 70
+#define ADSP_SC598_CLK_3PLL_PLL_IN 71
+#define ADSP_SC598_CLK_3PLL_VCO_OUT 72
+#define ADSP_SC598_CLK_3PLL_PLLCLK 73
+#define ADSP_SC598_CLK_3PLL_DDIV 74
+#define ADSP_SC598_CLK_DDR_SEL 75
+#define ADSP_SC598_CLK_DDR 76
+#define ADSP_SC598_CLK_CGU0_VCO_2_OUT 77
+#define ADSP_SC598_CLK_CGU1_VCO_2_OUT 78
+#define ADSP_SC598_CLK_3PLL_VCO_2_OUT 79
+#define ADSP_SC598_CLK_END 80
+
+#endif
--
2.25.1
^ permalink raw reply related [flat|nested] 65+ messages in thread
* Re: [PATCH 06/21] include: dt-binding: clock: add adi clock header file
2024-09-12 18:24 ` [PATCH 06/21] include: dt-binding: clock: add adi clock header file Arturs Artamonovs via B4 Relay
@ 2024-09-13 7:35 ` Arnd Bergmann
2024-09-16 6:47 ` Krzysztof Kozlowski
2024-09-16 6:48 ` Krzysztof Kozlowski
2 siblings, 0 replies; 65+ messages in thread
From: Arnd Bergmann @ 2024-09-13 7:35 UTC (permalink / raw)
To: arturs.artamonovs, Catalin Marinas, Will Deacon, Greg Malysa,
Philipp Zabel, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Utsav Agarwal, Michael Turquette, Stephen Boyd, Linus Walleij,
Bartosz Golaszewski, Thomas Gleixner, Andi Shyti,
Greg Kroah-Hartman, Jiri Slaby, Olof Johansson, soc
Cc: linux-arm-kernel, linux-kernel, devicetree, linux-clk,
open list:GPIO SUBSYSTEM, linux-i2c, linux-serial, adsp-linux,
Nathan Barrett-Morrison
On Thu, Sep 12, 2024, at 18:24, Arturs Artamonovs via B4 Relay wrote:
> From: Arturs Artamonovs <arturs.artamonovs@analog.com>
>
> Add adi clock driver header file
Are you sure this is necessary? If the clk controller follows
a logical structure, it's usually easier to identify individual
clks by the way the hardware is laid out.
> +#ifndef DT_BINDINGS_CLOCK_ADI_SC5XX_CLOCK_H
> +#define DT_BINDINGS_CLOCK_ADI_SC5XX_CLOCK_H
> +
> +#define ADSP_SC598_CLK_DUMMY 0
> +#define ADSP_SC598_CLK_SYS_CLKIN0 1
> +#define ADSP_SC598_CLK_SYS_CLKIN1 2
> +#define ADSP_SC598_CLK_CGU0_PLL_IN 3
> +#define ADSP_SC598_CLK_CGU0_VCO_OUT 4
Unlike the DT compatible strings, these #defines don't have
to be specific to a particular SoC, you could just reuse them
for a family of chips even if they each use a slightly different
subset. Maybe name them "ADSP_CLK_*" or "ADSP_SC5XX_CLK_*"?
> +#define ADSP_SC598_CLK_END 80
This should not be part of the binding, in particular you
probably want to be able to extend this in order to support
additional chips.
Arnd
^ permalink raw reply [flat|nested] 65+ messages in thread
* Re: [PATCH 06/21] include: dt-binding: clock: add adi clock header file
2024-09-12 18:24 ` [PATCH 06/21] include: dt-binding: clock: add adi clock header file Arturs Artamonovs via B4 Relay
2024-09-13 7:35 ` Arnd Bergmann
@ 2024-09-16 6:47 ` Krzysztof Kozlowski
2024-09-16 6:48 ` Krzysztof Kozlowski
2 siblings, 0 replies; 65+ messages in thread
From: Krzysztof Kozlowski @ 2024-09-16 6:47 UTC (permalink / raw)
To: arturs.artamonovs, Catalin Marinas, Will Deacon, Greg Malysa,
Philipp Zabel, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Utsav Agarwal, Michael Turquette, Stephen Boyd, Linus Walleij,
Bartosz Golaszewski, Thomas Gleixner, Andi Shyti,
Greg Kroah-Hartman, Jiri Slaby, Arnd Bergmann, Olof Johansson,
soc
Cc: linux-arm-kernel, linux-kernel, devicetree, linux-clk, linux-gpio,
linux-i2c, linux-serial, adsp-linux, Nathan Barrett-Morrison
On 12/09/2024 20:24, Arturs Artamonovs via B4 Relay wrote:
> From: Arturs Artamonovs <arturs.artamonovs@analog.com>
>
> Add adi clock driver header file
Useless on its own. This must be part of bindings patch.
Please use subject prefixes matching the subsystem. You can get them for
example with `git log --oneline -- DIRECTORY_OR_FILE` on the directory
your patch is touching. For bindings, the preferred subjects are
explained here:
https://www.kernel.org/doc/html/latest/devicetree/bindings/submitting-patches.html#i-for-patch-submitters
>
> Signed-off-by: Arturs Artamonovs <Arturs.Artamonovs@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>
> ---
> include/dt-bindings/clock/adi-sc5xx-clock.h | 93 +++++++++++++++++++++++++++++
> 1 file changed, 93 insertions(+)
>
> diff --git a/include/dt-bindings/clock/adi-sc5xx-clock.h b/include/dt-bindings/clock/adi-sc5xx-clock.h
> new file mode 100644
> index 0000000000000000000000000000000000000000..723c11dc44f9741cff49dc2cb6c5232022abf00c
> --- /dev/null
> +++ b/include/dt-bindings/clock/adi-sc5xx-clock.h
> @@ -0,0 +1,93 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * ADSP SC5xx clock device tree bindings
> + *
> + * Copyright 2022-2024 - Analog Devices Inc.
> + */
> +
> +#ifndef DT_BINDINGS_CLOCK_ADI_SC5XX_CLOCK_H
> +#define DT_BINDINGS_CLOCK_ADI_SC5XX_CLOCK_H
> +
> +#define ADSP_SC598_CLK_DUMMY 0
> +#define ADSP_SC598_CLK_SYS_CLKIN0 1
> +#define ADSP_SC598_CLK_SYS_CLKIN1 2
> +#define ADSP_SC598_CLK_CGU0_PLL_IN 3
> +#define ADSP_SC598_CLK_CGU0_VCO_OUT 4
> +#define ADSP_SC598_CLK_CGU0_PLLCLK 5
That's quite unreadable code. Indent after define name.
> +#define ADSP_SC598_CLK_CGU1_IN 6
> +#define ADSP_SC598_CLK_CGU1_PLL_IN 7
> +#define ADSP_SC598_CLK_CGU1_VCO_OUT 8
> +#define ADSP_SC598_CLK_CGU1_PLLCLK 9
> +#define ADSP_SC598_CLK_CGU0_CDIV 10
> +#define ADSP_SC598_CLK_CGU0_SYSCLK 11
> +#define ADSP_SC598_CLK_CGU0_DDIV 12
> +#define ADSP_SC598_CLK_CGU0_ODIV 13
> +#define ADSP_SC598_CLK_CGU0_S0SELDIV 14
> +#define ADSP_SC598_CLK_CGU0_S1SELDIV 15
> +#define ADSP_SC598_CLK_CGU0_S1SELEXDIV 16
> +#define ADSP_SC598_CLK_CGU0_S1SEL 17
> +#define ADSP_SC598_CLK_CGU1_CDIV 18
> +#define ADSP_SC598_CLK_CGU1_SYSCLK 19
> +#define ADSP_SC598_CLK_CGU1_DDIV 20
> +#define ADSP_SC598_CLK_CGU1_ODIV 21
> +#define ADSP_SC598_CLK_CGU1_S0SELDIV 22
> +#define ADSP_SC598_CLK_CGU1_S1SELDIV 23
> +#define ADSP_SC598_CLK_CGU1_S0SELEXDIV 24
> +#define ADSP_SC598_CLK_CGU1_S1SELEXDIV 25
> +#define ADSP_SC598_CLK_CGU1_S0SEL 26
> +#define ADSP_SC598_CLK_CGU1_S1SEL 27
> +#define ADSP_SC598_CLK_CGU0_CCLK2 28
> +#define ADSP_SC598_CLK_CGU0_CCLK0 29
> +#define ADSP_SC598_CLK_CGU0_OCLK 30
> +#define ADSP_SC598_CLK_CGU0_DCLK 31
> +#define ADSP_SC598_CLK_CGU0_SCLK1 32
> +#define ADSP_SC598_CLK_CGU0_SCLK0 33
> +#define ADSP_SC598_CLK_CGU1_CCLK0 34
> +#define ADSP_SC598_CLK_CGU1_OCLK 35
> +#define ADSP_SC598_CLK_CGU1_DCLK 36
> +#define ADSP_SC598_CLK_CGU1_SCLK1 37
> +#define ADSP_SC598_CLK_CGU1_SCLK0 38
> +#define ADSP_SC598_CLK_CGU1_CCLK2 39
> +#define ADSP_SC598_CLK_DCLK0_HALF 40
> +#define ADSP_SC598_CLK_DCLK1_HALF 41
> +#define ADSP_SC598_CLK_CGU1_SCLK1_HALF 42
> +#define ADSP_SC598_CLK_SHARC0_SEL 43
> +#define ADSP_SC598_CLK_SHARC1_SEL 44
> +#define ADSP_SC598_CLK_ARM_SEL 45
> +#define ADSP_SC598_CLK_CDU_DDR_SEL 46
> +#define ADSP_SC598_CLK_CAN_SEL 47
> +#define ADSP_SC598_CLK_SPDIF_SEL 48
> +#define ADSP_SC598_CLK_SPI_SEL 49
> +#define ADSP_SC598_CLK_GIGE_SEL 50
> +#define ADSP_SC598_CLK_LP_SEL 51
> +#define ADSP_SC598_CLK_LP_DDR_SEL 52
> +#define ADSP_SC598_CLK_OSPI_REFCLK_SEL 53
> +#define ADSP_SC598_CLK_TRACE_SEL 54
> +#define ADSP_SC598_CLK_EMMC_SEL 55
> +#define ADSP_SC598_CLK_EMMC_TIMER_QMC_SEL 56
> +#define ADSP_SC598_CLK_SHARC0 57
> +#define ADSP_SC598_CLK_SHARC1 58
> +#define ADSP_SC598_CLK_ARM 59
> +#define ADSP_SC598_CLK_CDU_DDR 60
> +#define ADSP_SC598_CLK_CAN 61
> +#define ADSP_SC598_CLK_SPDIF 62
> +#define ADSP_SC598_CLK_SPI 63
> +#define ADSP_SC598_CLK_GIGE 64
> +#define ADSP_SC598_CLK_LP 65
> +#define ADSP_SC598_CLK_LP_DDR 66
> +#define ADSP_SC598_CLK_OSPI_REFCLK 67
> +#define ADSP_SC598_CLK_TRACE 68
> +#define ADSP_SC598_CLK_EMMC 69
> +#define ADSP_SC598_CLK_EMMC_TIMER_QMC 70
> +#define ADSP_SC598_CLK_3PLL_PLL_IN 71
> +#define ADSP_SC598_CLK_3PLL_VCO_OUT 72
> +#define ADSP_SC598_CLK_3PLL_PLLCLK 73
> +#define ADSP_SC598_CLK_3PLL_DDIV 74
> +#define ADSP_SC598_CLK_DDR_SEL 75
> +#define ADSP_SC598_CLK_DDR 76
> +#define ADSP_SC598_CLK_CGU0_VCO_2_OUT 77
> +#define ADSP_SC598_CLK_CGU1_VCO_2_OUT 78
> +#define ADSP_SC598_CLK_3PLL_VCO_2_OUT 79
> +#define ADSP_SC598_CLK_END 80
Drop this one. Not a binding.
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 65+ messages in thread
* Re: [PATCH 06/21] include: dt-binding: clock: add adi clock header file
2024-09-12 18:24 ` [PATCH 06/21] include: dt-binding: clock: add adi clock header file Arturs Artamonovs via B4 Relay
2024-09-13 7:35 ` Arnd Bergmann
2024-09-16 6:47 ` Krzysztof Kozlowski
@ 2024-09-16 6:48 ` Krzysztof Kozlowski
2 siblings, 0 replies; 65+ messages in thread
From: Krzysztof Kozlowski @ 2024-09-16 6:48 UTC (permalink / raw)
To: arturs.artamonovs, Catalin Marinas, Will Deacon, Greg Malysa,
Philipp Zabel, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Utsav Agarwal, Michael Turquette, Stephen Boyd, Linus Walleij,
Bartosz Golaszewski, Thomas Gleixner, Andi Shyti,
Greg Kroah-Hartman, Jiri Slaby, Arnd Bergmann, Olof Johansson,
soc
Cc: linux-arm-kernel, linux-kernel, devicetree, linux-clk, linux-gpio,
linux-i2c, linux-serial, adsp-linux, Nathan Barrett-Morrison
On 12/09/2024 20:24, Arturs Artamonovs via B4 Relay wrote:
> From: Arturs Artamonovs <arturs.artamonovs@analog.com>
>
> Add adi clock driver header file
>
> Signed-off-by: Arturs Artamonovs <Arturs.Artamonovs@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>
> ---
> include/dt-bindings/clock/adi-sc5xx-clock.h | 93 +++++++++++++++++++++++++++++
Also, filename as compatible, which would be easily visible if you
organized the patches correctly.
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 65+ messages in thread
* [PATCH 07/21] clock: Add driver for ADI ADSP-SC5xx clock
2024-09-12 18:24 [PATCH 00/21] Adding support of ADI ARMv8 ADSP-SC598 SoC Arturs Artamonovs via B4 Relay
` (5 preceding siblings ...)
2024-09-12 18:24 ` [PATCH 06/21] include: dt-binding: clock: add adi clock header file Arturs Artamonovs via B4 Relay
@ 2024-09-12 18:24 ` Arturs Artamonovs via B4 Relay
2024-09-14 14:18 ` kernel test robot
2024-09-12 18:24 ` [PATCH 08/21] dt-bindings: clock: adi,sc5xx-clocks: add bindings Arturs Artamonovs via B4 Relay
` (16 subsequent siblings)
23 siblings, 1 reply; 65+ messages in thread
From: Arturs Artamonovs via B4 Relay @ 2024-09-12 18:24 UTC (permalink / raw)
To: Catalin Marinas, Will Deacon, Greg Malysa, Philipp Zabel,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Utsav Agarwal,
Michael Turquette, Stephen Boyd, Linus Walleij,
Bartosz Golaszewski, Thomas Gleixner, Andi Shyti,
Greg Kroah-Hartman, Jiri Slaby, Arnd Bergmann, Olof Johansson,
soc
Cc: linux-arm-kernel, linux-kernel, devicetree, linux-clk, linux-gpio,
linux-i2c, linux-serial, Arturs Artamonovs, adsp-linux,
Arturs Artamonovs, Nathan Barrett-Morrison
From: Arturs Artamonovs <arturs.artamonovs@analog.com>
Add ADSP-SC5xx clock driver
Signed-off-by: Arturs Artamonovs <Arturs.Artamonovs@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>
---
drivers/clk/Kconfig | 9 ++
drivers/clk/Makefile | 1 +
drivers/clk/adi/Makefile | 4 +
drivers/clk/adi/clk-adi-sc598.c | 329 ++++++++++++++++++++++++++++++++++++++++
4 files changed, 343 insertions(+)
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index 983ef4f36d8c4387556d6b5d32f01dd4afa815a3..a3a076294c285d820f1c6922b872ff73174192c0 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -42,6 +42,15 @@ config COMMON_CLK_WM831X
source "drivers/clk/versatile/Kconfig"
+config COMMON_CLK_ADI_SC598
+ bool "Clock driver for ADI SC598 SoCs"
+ depends on OF && ARCH_SC59X_64
+ help
+ This driver supports the system clocks on Analog Devices SC598-series
+ SoCs. It includes CGU and CDU clocks and supports gating unused clocks.
+ Modifying PLL configuration is not supported; that must be done prior
+ to booting the kernel. Clock dividers after the PLLs may be configured.
+
config CLK_HSDK
bool "PLL Driver for HSDK platform"
depends on ARC_SOC_HSDK || COMPILE_TEST
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index f793a16cad40bfff0d06989179e5401d7f3e69cc..9f48f81b9285ab19027cc287e62547a3c1332517 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -84,6 +84,7 @@ obj-$(CONFIG_COMMON_CLK_XGENE) += clk-xgene.o
# please keep this section sorted lexicographically by directory path name
obj-y += actions/
+obj-y += adi/
obj-y += analogbits/
obj-$(CONFIG_COMMON_CLK_AT91) += at91/
obj-$(CONFIG_ARCH_ARTPEC) += axis/
diff --git a/drivers/clk/adi/Makefile b/drivers/clk/adi/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..2a83dff54adaddd81f3f33bd962fe6302e14a8a7
--- /dev/null
+++ b/drivers/clk/adi/Makefile
@@ -0,0 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
+#SC598
+obj-$(CONFIG_COMMON_CLK_ADI_SC598) += clk-adi-pll.o
+obj-$(CONFIG_COMMON_CLK_ADI_SC598) += clk-adi-sc598.o
diff --git a/drivers/clk/adi/clk-adi-sc598.c b/drivers/clk/adi/clk-adi-sc598.c
new file mode 100644
index 0000000000000000000000000000000000000000..9d0b01b813a0aa44bbeb35bb4deaa3b38ca90834
--- /dev/null
+++ b/drivers/clk/adi/clk-adi-sc598.c
@@ -0,0 +1,329 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Clock support for ADI processor
+ *
+ * Copyright 2022-2024 - Analog Devices Inc.
+ */
+
+#include <dt-bindings/clock/adi-sc5xx-clock.h>
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/module.h>
+#include <linux/of_address.h>
+
+#include "clk.h"
+
+struct clk_core {
+ const char *name;
+ const struct clk_ops *ops;
+ struct clk_hw *hw;
+ struct module *owner;
+ struct device *dev;
+ struct hlist_node rpm_node;
+ struct device_node *of_node;
+ struct clk_core *parent;
+ struct clk_parent_map *parents;
+ u8 num_parents;
+ u8 new_parent_index;
+ unsigned long rate;
+ unsigned long req_rate;
+ unsigned long new_rate;
+ struct clk_core *new_parent;
+ struct clk_core *new_child;
+ unsigned long flags;
+ bool orphan;
+ bool rpm_enabled;
+ unsigned int enable_count;
+ unsigned int prepare_count;
+ unsigned int protect_count;
+ unsigned long min_rate;
+ unsigned long max_rate;
+ unsigned long accuracy;
+ int phase;
+ struct clk_duty duty;
+ struct hlist_head children;
+ struct hlist_node child_node;
+ struct hlist_head clks;
+ unsigned int notifier_count;
+#ifdef CONFIG_DEBUG_FS
+ struct dentry *dentry;
+ struct hlist_node debug_node;
+#endif
+ struct kref ref;
+};
+
+struct clk {
+ struct clk_core *core;
+ struct device *dev;
+ const char *dev_id;
+ const char *con_id;
+ unsigned long min_rate;
+ unsigned long max_rate;
+ unsigned int exclusive_count;
+ struct hlist_node clks_node;
+};
+
+static DEFINE_SPINLOCK(cdu_lock);
+
+static struct clk *clks[ADSP_SC598_CLK_END];
+static struct clk_onecell_data clk_data;
+
+static const char * const cgu1_in_sels[] = {"sys_clkin0", "sys_clkin1"};
+static const char * const cgu0_s1sels[] = {"cgu0_s1seldiv", "cgu0_s1selexdiv"};
+static const char * const cgu1_s0sels[] = {"cgu1_s0seldiv", "cgu1_s0selexdiv"};
+static const char * const cgu1_s1sels[] = {"cgu1_s1seldiv", "cgu1_s1selexdiv"};
+static const char * const sharc0_sels[] = {"cclk0_0", "dummy", "dummy", "dummy"};
+static const char * const sharc1_sels[] = {"cclk0_0", "dummy", "dummy", "dummy"};
+static const char * const arm_sels[] = {"dummy", "dummy", "cclk2_0", "cclk2_1"};
+static const char * const cdu_ddr_sels[] = {"dclk_0", "dclk_1", "dummy", "dummy"};
+static const char * const can_sels[] = {"dummy", "oclk_1", "dummy", "dummy"};
+static const char * const spdif_sels[] = {"sclk1_0", "dummy", "dummy", "dummy"};
+static const char * const spi_sels[] = {"sclk0_0", "oclk_0", "dummy", "dummy"};
+static const char * const gige_sels[] = {"sclk0_0", "sclk0_1", "dummy", "dummy"};
+static const char * const lp_sels[] = {"oclk_0", "sclk0_0", "cclk0_1", "dummy"};
+static const char * const lp_ddr_sels[] = {"oclk_0", "dclk_0", "sysclk_1", "dummy"};
+static const char * const ospi_refclk_sels[] = {"sysclk_0", "sclk0_0", "sclk1_1", "dummy"};
+static const char * const trace_sels[] = {"sclk0_0", "dummy", "dummy", "dummy"};
+static const char * const emmc_sels[] = {"oclk_0", "sclk0_1", "dclk_0_half", "dclk_1_half"};
+static const char * const emmc_timer_sels[] = {"dummy", "sclk1_1_half", "dummy", "dummy"};
+
+static const char * const ddr_sels[] = {"cdu_ddr", "3pll_ddiv"};
+
+static void sc598_clock_setup(struct device_node *np)
+{
+ void __iomem *cgu0;
+ void __iomem *cgu1;
+ void __iomem *cdu;
+ void __iomem *pll3;
+ int i;
+
+ cgu0 = of_iomap(np, 0);
+ if (IS_ERR(cgu0)) {
+ pr_err("Unable to remap CGU0 address (resource 0)\n");
+ return;
+ }
+
+ cgu1 = of_iomap(np, 1);
+ if (IS_ERR(cgu1)) {
+ pr_err("Unable to remap CGU1 address (resource 1)\n");
+ return;
+ }
+
+ cdu = of_iomap(np, 2);
+ if (IS_ERR(cdu)) {
+ pr_err("Unable to remap CDU address (resource 2)\n");
+ return;
+ }
+
+ pll3 = of_iomap(np, 3);
+ if (IS_ERR(pll3)) {
+ pr_err("Unable to remap PLL3 control register (resource 3)\n");
+ return;
+ }
+
+ // We only access this one register for pll3
+ pll3 = pll3 + PLL3_OFFSET;
+
+ // Input clock configuration
+ clks[ADSP_SC598_CLK_DUMMY] = clk_register_fixed_rate(NULL, "dummy", NULL, 0, 0);
+ clks[ADSP_SC598_CLK_SYS_CLKIN0] = of_clk_get_by_name(np, "sys_clkin0");
+ clks[ADSP_SC598_CLK_SYS_CLKIN1] = of_clk_get_by_name(np, "sys_clkin1");
+ clks[ADSP_SC598_CLK_CGU1_IN] = clk_register_mux(NULL, "cgu1_in_sel",
+ cgu1_in_sels, 2, CLK_SET_RATE_PARENT, cdu + CDU_CLKINSEL, 0, 1, 0,
+ &cdu_lock);
+
+ // 3rd pll reuses cgu1 clk in selection, feeds directly into 3pll df
+ // changing the cgu1 in sel mux will affect 3pll so reuse the same clocks
+
+ // CGU configuration and internal clocks
+ clks[ADSP_SC598_CLK_CGU0_PLL_IN] = clk_register_divider(NULL, "cgu0_df",
+ "sys_clkin0", CLK_SET_RATE_PARENT, cgu0 + CGU_CTL, 0, 1, 0, &cdu_lock);
+ clks[ADSP_SC598_CLK_CGU1_PLL_IN] = clk_register_divider(NULL, "cgu1_df",
+ "cgu1_in_sel", CLK_SET_RATE_PARENT, cgu1 + CGU_CTL, 0, 1, 0, &cdu_lock);
+ clks[ADSP_SC598_CLK_3PLL_PLL_IN] = clk_register_divider(NULL, "3pll_df",
+ "cgu1_in_sel", CLK_SET_RATE_PARENT, pll3, 3, 1, 0, &cdu_lock);
+
+ // VCO output inside PLL
+ clks[ADSP_SC598_CLK_CGU0_VCO_OUT] = sc5xx_cgu_pll("cgu0_vco_msel", "cgu0_df",
+ cgu0 + CGU_CTL, CGU_MSEL_SHIFT, CGU_MSEL_WIDTH, 0, &cdu_lock);
+ clks[ADSP_SC598_CLK_CGU1_VCO_OUT] = sc5xx_cgu_pll("cgu1_vco_msel", "cgu1_df",
+ cgu1 + CGU_CTL, CGU_MSEL_SHIFT, CGU_MSEL_WIDTH, 0, &cdu_lock);
+ clks[ADSP_SC598_CLK_3PLL_VCO_OUT] = sc5xx_cgu_pll("3pll_vco_msel", "3pll_df",
+ pll3, PLL3_MSEL_SHIFT, PLL3_MSEL_WIDTH, 1, &cdu_lock);
+
+ //MSEL constant factor
+ clks[ADSP_SC598_CLK_CGU0_VCO_2_OUT] = clk_register_fixed_factor(NULL,
+ "cgu0_vco", "cgu0_vco_msel", CLK_SET_RATE_PARENT, 2, 1);
+ clks[ADSP_SC598_CLK_CGU1_VCO_2_OUT] = clk_register_fixed_factor(NULL,
+ "cgu1_vco", "cgu0_vco_msel", CLK_SET_RATE_PARENT, 2, 1);
+ clks[ADSP_SC598_CLK_3PLL_VCO_2_OUT] = clk_register_fixed_factor(NULL,
+ "3pll_vco", "cgu0_vco_msel", CLK_SET_RATE_PARENT, 2, 1);
+
+ // Final PLL output
+ clks[ADSP_SC598_CLK_CGU0_PLLCLK] = clk_register_fixed_factor(NULL,
+ "cgu0_pllclk", "cgu0_vco", CLK_SET_RATE_PARENT, 1, 2);
+ clks[ADSP_SC598_CLK_CGU1_PLLCLK] = clk_register_fixed_factor(NULL,
+ "cgu1_pllclk", "cgu1_vco", CLK_SET_RATE_PARENT, 1, 2);
+ clks[ADSP_SC598_CLK_3PLL_PLLCLK] = clk_register_fixed_factor(NULL,
+ "3pll_pllclk", "3pll_vco", CLK_SET_RATE_PARENT, 1, 2);
+
+ // Dividers from pll output
+ clks[ADSP_SC598_CLK_CGU0_CDIV] = cgu_divider("cgu0_cdiv", "cgu0_pllclk",
+ cgu0 + CGU_DIV, 0, 5, 0, &cdu_lock);
+ clks[ADSP_SC598_CLK_CGU0_SYSCLK] = cgu_divider("sysclk_0", "cgu0_pllclk",
+ cgu0 + CGU_DIV, 8, 5, 0, &cdu_lock);
+ clks[ADSP_SC598_CLK_CGU0_DDIV] = cgu_divider("cgu0_ddiv", "cgu0_pllclk",
+ cgu0 + CGU_DIV, 16, 5, 0, &cdu_lock);
+ clks[ADSP_SC598_CLK_CGU0_ODIV] = cgu_divider("cgu0_odiv", "cgu0_pllclk",
+ cgu0 + CGU_DIV, 22, 7, 0, &cdu_lock);
+ clks[ADSP_SC598_CLK_CGU0_S0SELDIV] = cgu_divider("cgu0_s0seldiv",
+ "sysclk_0", cgu0 + CGU_DIV, 5, 3, 0, &cdu_lock);
+ clks[ADSP_SC598_CLK_CGU0_S1SELDIV] = cgu_divider("cgu0_s1seldiv",
+ "sysclk_0", cgu0 + CGU_DIV, 13, 3, 0, &cdu_lock);
+ clks[ADSP_SC598_CLK_CGU0_S1SELEXDIV] = cgu_divider("cgu0_s1selexdiv",
+ "cgu0_pllclk", cgu0 + CGU_DIVEX, 16, 8, 0, &cdu_lock);
+ clks[ADSP_SC598_CLK_CGU0_S1SEL] = clk_register_mux(NULL, "cgu0_sclk1sel",
+ cgu0_s1sels, 2, CLK_SET_RATE_PARENT, cgu0 + CGU_CTL, 17, 1, 0, &cdu_lock);
+ clks[ADSP_SC598_CLK_CGU0_CCLK2] = clk_register_fixed_factor(NULL,
+ "cclk2_0", "cgu0_vco", CLK_SET_RATE_PARENT, 1, 3);
+
+ clks[ADSP_SC598_CLK_CGU1_CDIV] = cgu_divider("cgu1_cdiv", "cgu1_pllclk",
+ cgu1 + CGU_DIV, 0, 5, 0, &cdu_lock);
+ clks[ADSP_SC598_CLK_CGU1_SYSCLK] = cgu_divider("sysclk_1", "cgu1_pllclk",
+ cgu1 + CGU_DIV, 8, 5, 0, &cdu_lock);
+ clks[ADSP_SC598_CLK_CGU1_DDIV] = cgu_divider("cgu1_ddiv", "cgu1_pllclk",
+ cgu1 + CGU_DIV, 16, 5, 0, &cdu_lock);
+ clks[ADSP_SC598_CLK_CGU1_ODIV] = cgu_divider("cgu1_odiv", "cgu1_pllclk",
+ cgu1 + CGU_DIV, 22, 7, 0, &cdu_lock);
+ clks[ADSP_SC598_CLK_CGU1_S0SELDIV] = cgu_divider("cgu1_s0seldiv",
+ "sysclk_1", cgu1 + CGU_DIV, 5, 3, 0, &cdu_lock);
+ clks[ADSP_SC598_CLK_CGU1_S1SELDIV] = cgu_divider("cgu1_s1seldiv",
+ "sysclk_1", cgu1 + CGU_DIV, 13, 3, 0, &cdu_lock);
+ clks[ADSP_SC598_CLK_CGU1_S0SELEXDIV] = cgu_divider("cgu1_s0selexdiv",
+ "cgu1_pllclk", cgu1 + CGU_DIVEX, 0, 8, 0, &cdu_lock);
+ clks[ADSP_SC598_CLK_CGU1_S1SELEXDIV] = cgu_divider("cgu1_s1selexdiv",
+ "cgu1_pllclk", cgu1 + CGU_DIVEX, 16, 8, 0, &cdu_lock);
+ clks[ADSP_SC598_CLK_CGU1_S0SEL] = clk_register_mux(NULL, "cgu1_sclk0sel",
+ cgu1_s0sels, 2, CLK_SET_RATE_PARENT, cgu1 + CGU_CTL, 16, 1, 0, &cdu_lock);
+ clks[ADSP_SC598_CLK_CGU1_S1SEL] = clk_register_mux(NULL, "cgu1_sclk1sel",
+ cgu1_s1sels, 2, CLK_SET_RATE_PARENT, cgu1 + CGU_CTL, 17, 1, 0, &cdu_lock);
+ clks[ADSP_SC598_CLK_CGU1_CCLK2] = clk_register_fixed_factor(NULL,
+ "cclk2_1", "cgu1_vco", CLK_SET_RATE_PARENT, 1, 3);
+
+ clks[ADSP_SC598_CLK_3PLL_DDIV] = clk_register_divider(NULL, "3pll_ddiv",
+ "3pll_pllclk", CLK_SET_RATE_PARENT, pll3, 12, 5, 0, &cdu_lock);
+
+ // Gates to enable CGU outputs
+ clks[ADSP_SC598_CLK_CGU0_CCLK0] = cgu_gate("cclk0_0", "cgu0_cdiv",
+ cgu0 + CGU_CCBF_DIS, 0, &cdu_lock);
+ clks[ADSP_SC598_CLK_CGU0_OCLK] = cgu_gate("oclk_0", "cgu0_odiv",
+ cgu0 + CGU_SCBF_DIS, 3, &cdu_lock);
+ clks[ADSP_SC598_CLK_CGU0_DCLK] = cgu_gate("dclk_0", "cgu0_ddiv",
+ cgu0 + CGU_SCBF_DIS, 2, &cdu_lock);
+ clks[ADSP_SC598_CLK_CGU0_SCLK1] = cgu_gate("sclk1_0", "cgu0_sclk1sel",
+ cgu0 + CGU_SCBF_DIS, 1, &cdu_lock);
+ clks[ADSP_SC598_CLK_CGU0_SCLK0] = cgu_gate("sclk0_0", "cgu0_s0seldiv",
+ cgu0 + CGU_SCBF_DIS, 0, &cdu_lock);
+
+ clks[ADSP_SC598_CLK_CGU1_CCLK0] = cgu_gate("cclk0_1", "cgu1_cdiv",
+ cgu1 + CGU_CCBF_DIS, 0, &cdu_lock);
+ clks[ADSP_SC598_CLK_CGU1_OCLK] = cgu_gate("oclk_1", "cgu1_odiv",
+ cgu1 + CGU_SCBF_DIS, 3, &cdu_lock);
+ clks[ADSP_SC598_CLK_CGU1_DCLK] = cgu_gate("dclk_1", "cgu1_ddiv",
+ cgu1 + CGU_SCBF_DIS, 2, &cdu_lock);
+ clks[ADSP_SC598_CLK_CGU1_SCLK1] = cgu_gate("sclk1_1", "cgu1_sclk1sel",
+ cgu1 + CGU_SCBF_DIS, 1, &cdu_lock);
+ clks[ADSP_SC598_CLK_CGU1_SCLK0] = cgu_gate("sclk0_1", "cgu1_sclk0sel",
+ cgu1 + CGU_SCBF_DIS, 0, &cdu_lock);
+
+ // Extra half rate clocks generated in the CDU
+ clks[ADSP_SC598_CLK_DCLK0_HALF] = clk_register_fixed_factor(NULL, "dclk_0_half",
+ "dclk_0", CLK_SET_RATE_PARENT, 1, 2);
+ clks[ADSP_SC598_CLK_DCLK1_HALF] = clk_register_fixed_factor(NULL, "dclk_1_half",
+ "dclk_1", CLK_SET_RATE_PARENT, 1, 2);
+ clks[ADSP_SC598_CLK_CGU1_SCLK1_HALF] = clk_register_fixed_factor(NULL,
+ "sclk1_1_half", "sclk1_1", CLK_SET_RATE_PARENT, 1, 2);
+
+ // CDU output muxes
+ clks[ADSP_SC598_CLK_SHARC0_SEL] = cdu_mux("sharc0_sel", cdu + CDU_CFG0,
+ sharc0_sels, &cdu_lock);
+ clks[ADSP_SC598_CLK_SHARC1_SEL] = cdu_mux("sharc1_sel", cdu + CDU_CFG1,
+ sharc1_sels, &cdu_lock);
+ clks[ADSP_SC598_CLK_ARM_SEL] = cdu_mux("arm_sel", cdu + CDU_CFG2,
+ arm_sels, &cdu_lock);
+ clks[ADSP_SC598_CLK_CDU_DDR_SEL] = cdu_mux("cdu_ddr_sel", cdu + CDU_CFG3,
+ cdu_ddr_sels, &cdu_lock);
+ clks[ADSP_SC598_CLK_CAN_SEL] = cdu_mux("can_sel", cdu + CDU_CFG4,
+ can_sels, &cdu_lock);
+ clks[ADSP_SC598_CLK_SPDIF_SEL] = cdu_mux("spdif_sel", cdu + CDU_CFG5,
+ spdif_sels, &cdu_lock);
+ clks[ADSP_SC598_CLK_SPI_SEL] = cdu_mux("spi_sel", cdu + CDU_CFG6,
+ spi_sels, &cdu_lock);
+ clks[ADSP_SC598_CLK_GIGE_SEL] = cdu_mux("gige_sel", cdu + CDU_CFG7,
+ gige_sels, &cdu_lock);
+ clks[ADSP_SC598_CLK_LP_SEL] = cdu_mux("lp_sel", cdu + CDU_CFG8, lp_sels,
+ &cdu_lock);
+ clks[ADSP_SC598_CLK_LP_DDR_SEL] = cdu_mux("lp_ddr_sel", cdu + CDU_CFG9,
+ lp_ddr_sels, &cdu_lock);
+ clks[ADSP_SC598_CLK_OSPI_REFCLK_SEL] = cdu_mux("ospi_refclk_sel",
+ cdu + CDU_CFG10, ospi_refclk_sels, &cdu_lock);
+ clks[ADSP_SC598_CLK_TRACE_SEL] = cdu_mux("trace_sel", cdu + CDU_CFG12,
+ trace_sels, &cdu_lock);
+ clks[ADSP_SC598_CLK_EMMC_SEL] = cdu_mux("emmc_sel", cdu + CDU_CFG13,
+ emmc_sels, &cdu_lock);
+ clks[ADSP_SC598_CLK_EMMC_TIMER_QMC_SEL] = cdu_mux("emmc_timer_qmc_sel",
+ cdu + CDU_CFG14, emmc_timer_sels, &cdu_lock);
+
+ // CDU output enable gates
+ clks[ADSP_SC598_CLK_SHARC0] = cdu_gate("sharc0", "sharc0_sel",
+ cdu + CDU_CFG0, CLK_IS_CRITICAL, &cdu_lock);
+ clks[ADSP_SC598_CLK_SHARC1] = cdu_gate("sharc1", "sharc1_sel",
+ cdu + CDU_CFG1, CLK_IS_CRITICAL, &cdu_lock);
+ clks[ADSP_SC598_CLK_ARM] = cdu_gate("arm", "arm_sel", cdu + CDU_CFG2,
+ CLK_IS_CRITICAL, &cdu_lock);
+ clks[ADSP_SC598_CLK_CDU_DDR] = cdu_gate("cdu_ddr", "cdu_ddr_sel",
+ cdu + CDU_CFG3, 0, &cdu_lock);
+ clks[ADSP_SC598_CLK_CAN] = cdu_gate("can", "can_sel", cdu + CDU_CFG4, 0,
+ &cdu_lock);
+ clks[ADSP_SC598_CLK_SPDIF] = cdu_gate("spdif", "spdif_sel", cdu + CDU_CFG5,
+ 0, &cdu_lock);
+ clks[ADSP_SC598_CLK_SPI] = cdu_gate("spi", "spi_sel", cdu + CDU_CFG6, 0,
+ &cdu_lock);
+ clks[ADSP_SC598_CLK_GIGE] = cdu_gate("gige", "gige_sel", cdu + CDU_CFG7, 0,
+ &cdu_lock);
+ clks[ADSP_SC598_CLK_LP] = cdu_gate("lp", "lp_sel", cdu + CDU_CFG8, 0, &cdu_lock);
+ clks[ADSP_SC598_CLK_LP_DDR] = cdu_gate("lp_ddr", "lp_ddr_sel",
+ cdu + CDU_CFG9, 0, &cdu_lock);
+ clks[ADSP_SC598_CLK_OSPI_REFCLK] = cdu_gate("ospi_refclk", "ospi_refclk_sel",
+ cdu + CDU_CFG10, 0, &cdu_lock);
+ clks[ADSP_SC598_CLK_TRACE] = cdu_gate("trace", "trace_sel", cdu + CDU_CFG12,
+ 0, &cdu_lock);
+ clks[ADSP_SC598_CLK_EMMC] = cdu_gate("emmc", "emmc_sel", cdu + CDU_CFG13, 0,
+ &cdu_lock);
+ clks[ADSP_SC598_CLK_EMMC_TIMER_QMC] = cdu_gate("emmc_timer_qmc",
+ "emmc_timer_qmc_sel", cdu + CDU_CFG14, 0, &cdu_lock);
+
+ // Dedicated DDR output mux
+ clks[ADSP_SC598_CLK_DDR] = clk_register_mux(NULL, "ddr", ddr_sels, 2,
+ CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, pll3, 11, 1, 0, &cdu_lock);
+
+ for (i = 0; i < ARRAY_SIZE(clks); i++) {
+ if (IS_ERR(clks[i])) {
+ pr_err("Zynq clk %d: register failed with %ld\n",
+ i, PTR_ERR(clks[i]));
+ BUG();
+ }
+ }
+
+ clk_data.clks = clks;
+ clk_data.clk_num = ARRAY_SIZE(clks);
+ of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
+}
+
+CLK_OF_DECLARE(sc598_clocks, "adi,sc598-clocks", sc598_clock_setup);
+
+MODULE_AUTHOR("Greg Malysa <greg.malysa@timesys.com>");
+MODULE_DESCRIPTION("Analog Devices Clock driver");
+MODULE_LICENSE("GPL v2");
\ No newline at end of file
--
2.25.1
^ permalink raw reply related [flat|nested] 65+ messages in thread
* Re: [PATCH 07/21] clock: Add driver for ADI ADSP-SC5xx clock
2024-09-12 18:24 ` [PATCH 07/21] clock: Add driver for ADI ADSP-SC5xx clock Arturs Artamonovs via B4 Relay
@ 2024-09-14 14:18 ` kernel test robot
0 siblings, 0 replies; 65+ messages in thread
From: kernel test robot @ 2024-09-14 14:18 UTC (permalink / raw)
To: Arturs Artamonovs via B4 Relay, Catalin Marinas, Will Deacon,
Greg Malysa, Philipp Zabel, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Utsav Agarwal, Michael Turquette, Stephen Boyd,
Linus Walleij, Bartosz Golaszewski, Thomas Gleixner, Andi Shyti,
Greg Kroah-Hartman, Jiri Slaby, Arnd Bergmann, Olof Johansson,
soc
Cc: oe-kbuild-all, linux-arm-kernel, linux-kernel, devicetree,
linux-clk, linux-gpio, linux-i2c, linux-serial, Arturs Artamonovs,
adsp-linux, Nathan Barrett-Morrison
Hi Arturs,
kernel test robot noticed the following build warnings:
[auto build test WARNING on da3ea35007d0af457a0afc87e84fddaebc4e0b63]
url: https://github.com/intel-lab-lkp/linux/commits/Arturs-Artamonovs-via-B4-Relay/arm64-Add-ADI-ADSP-SC598-SoC/20240913-022308
base: da3ea35007d0af457a0afc87e84fddaebc4e0b63
patch link: https://lore.kernel.org/r/20240912-test-v1-7-458fa57c8ccf%40analog.com
patch subject: [PATCH 07/21] clock: Add driver for ADI ADSP-SC5xx clock
compiler: clang version 18.1.8 (https://github.com/llvm/llvm-project 3b5b5c1ec4a3095ab096dd780e84d7ab81f3d7ff)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202409142102.LvuMEIro-lkp@intel.com/
includecheck warnings: (new ones prefixed by >>)
>> drivers/clk/adi/clk-adi-sc598.c: linux/clk.h is included more than once.
vim +9 drivers/clk/adi/clk-adi-sc598.c
> 9 #include <linux/clk.h>
10 #include <linux/clk-provider.h>
> 11 #include <linux/clk.h>
12 #include <linux/err.h>
13 #include <linux/module.h>
14 #include <linux/of_address.h>
15
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 65+ messages in thread
* [PATCH 08/21] dt-bindings: clock: adi,sc5xx-clocks: add bindings
2024-09-12 18:24 [PATCH 00/21] Adding support of ADI ARMv8 ADSP-SC598 SoC Arturs Artamonovs via B4 Relay
` (6 preceding siblings ...)
2024-09-12 18:24 ` [PATCH 07/21] clock: Add driver for ADI ADSP-SC5xx clock Arturs Artamonovs via B4 Relay
@ 2024-09-12 18:24 ` Arturs Artamonovs via B4 Relay
2024-09-13 22:06 ` Rob Herring
2024-09-12 18:24 ` [PATCH 09/21] gpio: add driver for ADI ADSP-SC5xx platform Arturs Artamonovs via B4 Relay
` (15 subsequent siblings)
23 siblings, 1 reply; 65+ messages in thread
From: Arturs Artamonovs via B4 Relay @ 2024-09-12 18:24 UTC (permalink / raw)
To: Catalin Marinas, Will Deacon, Greg Malysa, Philipp Zabel,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Utsav Agarwal,
Michael Turquette, Stephen Boyd, Linus Walleij,
Bartosz Golaszewski, Thomas Gleixner, Andi Shyti,
Greg Kroah-Hartman, Jiri Slaby, Arnd Bergmann, Olof Johansson,
soc
Cc: linux-arm-kernel, linux-kernel, devicetree, linux-clk, linux-gpio,
linux-i2c, linux-serial, Arturs Artamonovs, adsp-linux,
Arturs Artamonovs, Nathan Barrett-Morrison
From: Arturs Artamonovs <arturs.artamonovs@analog.com>
Add ADSP-SC5xx clock bindings.
Signed-off-by: Arturs Artamonovs <Arturs.Artamonovs@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>
---
.../bindings/clock/adi,sc5xx-clocks.yaml | 65 ++++++++++++++++++++++
1 file changed, 65 insertions(+)
diff --git a/Documentation/devicetree/bindings/clock/adi,sc5xx-clocks.yaml b/Documentation/devicetree/bindings/clock/adi,sc5xx-clocks.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..a092ebdefdcf89a635cdcf1073921efd28a38386
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/adi,sc5xx-clocks.yaml
@@ -0,0 +1,65 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/adi,sc5xx-clocks.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Clock Tree Drivers for Analog Devices ADSP-SC5XX Processors
+
+maintainers:
+ - Arturs Artamonovs <arturs.artamonovs@analog.com>
+ - Utsav Agarwal <Utsav.Agarwal@analog.com>
+
+description: |
+ These drivers read in the processors CDU (clock distribution unit)
+ and CGU (clock generation unit) values to determine various clock
+ rates
+
+properties:
+ compatible:
+ enum:
+ - adi,sc598-clocks # 64-Bit SC598 processor
+
+ '#clock-cells':
+ const: 1
+
+ reg:
+ minItems: 3
+ maxItems: 4
+
+ clocks:
+ description:
+ Specifies the CLKIN0 and CLKIN1 reference clock(s) from which the
+ output frequencies are derived via CDU+CGU
+ minItems: 2
+ maxItems: 2
+
+ clock-names:
+ description:
+ String reference names for CLKIN0 and CLKIN1
+ minItems: 2
+ maxItems: 2
+
+required:
+ - compatible
+ - reg
+ - clocks
+ - '#clock-cells'
+ - clock-names
+
+additionalProperties: false
+
+examples:
+ - |
+ clk3: clocks@3108d000 {
+ compatible = "adi,sc598-clocks";
+ reg = <0x3108d000 0x1000>,
+ <0x3108e000 0x1000>,
+ <0x3108f000 0x1000>,
+ <0x310a9000 0x1000>;
+ #clock-cells = <1>;
+ clocks = <&sys_clkin0>, <&sys_clkin1>;
+ clock-names = "sys_clkin0", "sys_clkin1";
+ status = "okay";
+ };
+
--
2.25.1
^ permalink raw reply related [flat|nested] 65+ messages in thread
* Re: [PATCH 08/21] dt-bindings: clock: adi,sc5xx-clocks: add bindings
2024-09-12 18:24 ` [PATCH 08/21] dt-bindings: clock: adi,sc5xx-clocks: add bindings Arturs Artamonovs via B4 Relay
@ 2024-09-13 22:06 ` Rob Herring
0 siblings, 0 replies; 65+ messages in thread
From: Rob Herring @ 2024-09-13 22:06 UTC (permalink / raw)
To: Arturs Artamonovs
Cc: Catalin Marinas, Will Deacon, Greg Malysa, Philipp Zabel,
Krzysztof Kozlowski, Conor Dooley, Utsav Agarwal,
Michael Turquette, Stephen Boyd, Linus Walleij,
Bartosz Golaszewski, Thomas Gleixner, Andi Shyti,
Greg Kroah-Hartman, Jiri Slaby, Arnd Bergmann, Olof Johansson,
soc, linux-arm-kernel, linux-kernel, devicetree, linux-clk,
linux-gpio, linux-i2c, linux-serial, adsp-linux,
Nathan Barrett-Morrison
On Thu, Sep 12, 2024 at 07:24:53PM +0100, Arturs Artamonovs wrote:
> Add ADSP-SC5xx clock bindings.
>
> Signed-off-by: Arturs Artamonovs <Arturs.Artamonovs@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>
> ---
> .../bindings/clock/adi,sc5xx-clocks.yaml | 65 ++++++++++++++++++++++
> 1 file changed, 65 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/clock/adi,sc5xx-clocks.yaml b/Documentation/devicetree/bindings/clock/adi,sc5xx-clocks.yaml
> new file mode 100644
> index 0000000000000000000000000000000000000000..a092ebdefdcf89a635cdcf1073921efd28a38386
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/clock/adi,sc5xx-clocks.yaml
> @@ -0,0 +1,65 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/clock/adi,sc5xx-clocks.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Clock Tree Drivers for Analog Devices ADSP-SC5XX Processors
> +
> +maintainers:
> + - Arturs Artamonovs <arturs.artamonovs@analog.com>
> + - Utsav Agarwal <Utsav.Agarwal@analog.com>
> +
> +description: |
> + These drivers read in the processors CDU (clock distribution unit)
> + and CGU (clock generation unit) values to determine various clock
> + rates
That sounds like 2 h/w blocks, not 1. If so, the bindings should reflect
that even if you want 1 driver to handle both.
Rob
^ permalink raw reply [flat|nested] 65+ messages in thread
* [PATCH 09/21] gpio: add driver for ADI ADSP-SC5xx platform
2024-09-12 18:24 [PATCH 00/21] Adding support of ADI ARMv8 ADSP-SC598 SoC Arturs Artamonovs via B4 Relay
` (7 preceding siblings ...)
2024-09-12 18:24 ` [PATCH 08/21] dt-bindings: clock: adi,sc5xx-clocks: add bindings Arturs Artamonovs via B4 Relay
@ 2024-09-12 18:24 ` Arturs Artamonovs via B4 Relay
2024-09-13 7:38 ` Arnd Bergmann
` (3 more replies)
2024-09-12 18:24 ` [PATCH 10/21] dt-bindings: gpio: adi,adsp-port-gpio: add bindings Arturs Artamonovs via B4 Relay
` (14 subsequent siblings)
23 siblings, 4 replies; 65+ messages in thread
From: Arturs Artamonovs via B4 Relay @ 2024-09-12 18:24 UTC (permalink / raw)
To: Catalin Marinas, Will Deacon, Greg Malysa, Philipp Zabel,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Utsav Agarwal,
Michael Turquette, Stephen Boyd, Linus Walleij,
Bartosz Golaszewski, Thomas Gleixner, Andi Shyti,
Greg Kroah-Hartman, Jiri Slaby, Arnd Bergmann, Olof Johansson,
soc
Cc: linux-arm-kernel, linux-kernel, devicetree, linux-clk, linux-gpio,
linux-i2c, linux-serial, Arturs Artamonovs, adsp-linux,
Arturs Artamonovs, Nathan Barrett-Morrison
From: Arturs Artamonovs <arturs.artamonovs@analog.com>
Add ADSP-SC5xx GPIO driver.
- Support all GPIO ports
- Each gpio support seperate PINT interrupt controller
Signed-off-by: Arturs Artamonovs <Arturs.Artamonovs@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>
---
drivers/gpio/Kconfig | 8 +++
drivers/gpio/Makefile | 1 +
drivers/gpio/gpio-adi-adsp-port.c | 145 ++++++++++++++++++++++++++++++++++++++
3 files changed, 154 insertions(+)
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 58f43bcced7c1f29fad5960771817f500ef67ce1..b02693f5b4cec95a59f19aa1bacf7ed72236865a 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -147,6 +147,14 @@ config GPIO_74XX_MMIO
8 bits: 74244 (Input), 74273 (Output)
16 bits: 741624 (Input), 7416374 (Output)
+config GPIO_ADI_ADSP_PORT
+ bool "ADI ADSP PORT GPIO driver"
+ depends on OF_GPIO
+ select GPIO_GENERIC
+ help
+ Say Y to enable the ADSP PORT-based GPIO driver for Analog Devices
+ ADSP chips.
+
config GPIO_ALTERA
tristate "Altera GPIO"
depends on OF_GPIO
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 64dd6d9d730d5a22564821df71375113e31fe057..fb02c7807a674c8a38d1128e6a25bb7c7f1f4aab 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -24,6 +24,7 @@ obj-$(CONFIG_GPIO_104_IDI_48) += gpio-104-idi-48.o
obj-$(CONFIG_GPIO_104_IDIO_16) += gpio-104-idio-16.o
obj-$(CONFIG_GPIO_74X164) += gpio-74x164.o
obj-$(CONFIG_GPIO_74XX_MMIO) += gpio-74xx-mmio.o
+obj-$(CONFIG_GPIO_ADI_ADSP_PORT) += gpio-adi-adsp-port.o
obj-$(CONFIG_GPIO_ADNP) += gpio-adnp.o
obj-$(CONFIG_GPIO_ADP5520) += gpio-adp5520.o
obj-$(CONFIG_GPIO_AGGREGATOR) += gpio-aggregator.o
diff --git a/drivers/gpio/gpio-adi-adsp-port.c b/drivers/gpio/gpio-adi-adsp-port.c
new file mode 100644
index 0000000000000000000000000000000000000000..a7a1867495bbdd121cda9b99991865a035dfa117
--- /dev/null
+++ b/drivers/gpio/gpio-adi-adsp-port.c
@@ -0,0 +1,145 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * ADSP PORT gpio driver
+ *
+ * (C) Copyright 2022-2024 - Analog Devices, Inc.
+ */
+
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/soc/adi/adsp-gpio-port.h>
+#include "gpiolib.h"
+
+static int adsp_gpio_direction_input(struct gpio_chip *chip, unsigned int offset)
+{
+ struct adsp_gpio_port *port = to_adsp_gpio_port(chip);
+
+ __adsp_gpio_writew(port, BIT(offset), ADSP_PORT_REG_DIR_CLEAR);
+ __adsp_gpio_writew(port, BIT(offset), ADSP_PORT_REG_INEN_SET);
+ return 0;
+}
+
+static int adsp_gpio_direction_output(struct gpio_chip *chip, unsigned int offset,
+ int value)
+{
+ struct adsp_gpio_port *port = to_adsp_gpio_port(chip);
+
+ /*
+ * For open drain ports, they've already been configured by pinctrl and
+ * we should not modify their output characteristics
+ */
+ if (port->open_drain & BIT(offset))
+ return 0;
+
+ __adsp_gpio_writew(port, BIT(offset), ADSP_PORT_REG_INEN_CLEAR);
+
+ if (value)
+ __adsp_gpio_writew(port, BIT(offset), ADSP_PORT_REG_DATA_SET);
+ else
+ __adsp_gpio_writew(port, BIT(offset), ADSP_PORT_REG_DATA_CLEAR);
+
+ __adsp_gpio_writew(port, BIT(offset), ADSP_PORT_REG_DIR_SET);
+ return 0;
+}
+
+static void adsp_gpio_set_value(struct gpio_chip *chip, unsigned int offset, int value)
+{
+ struct adsp_gpio_port *port = to_adsp_gpio_port(chip);
+
+ /*
+ * For open drain ports, set as input if driving a 1, set as output
+ * if driving a 0
+ */
+ if (port->open_drain & BIT(offset)) {
+ if (value) {
+ __adsp_gpio_writew(port, BIT(offset), ADSP_PORT_REG_DIR_CLEAR);
+ __adsp_gpio_writew(port, BIT(offset), ADSP_PORT_REG_INEN_SET);
+ } else {
+ __adsp_gpio_writew(port, BIT(offset), ADSP_PORT_REG_INEN_CLEAR);
+ __adsp_gpio_writew(port, BIT(offset), ADSP_PORT_REG_DATA_CLEAR);
+ __adsp_gpio_writew(port, BIT(offset), ADSP_PORT_REG_DIR_SET);
+ }
+ } else {
+ if (value)
+ __adsp_gpio_writew(port, BIT(offset), ADSP_PORT_REG_DATA_SET);
+ else
+ __adsp_gpio_writew(port, BIT(offset), ADSP_PORT_REG_DATA_CLEAR);
+ }
+}
+
+static int adsp_gpio_get_value(struct gpio_chip *chip, unsigned int offset)
+{
+ struct adsp_gpio_port *port = to_adsp_gpio_port(chip);
+
+ return !!(__adsp_gpio_readw(port, ADSP_PORT_REG_DATA) & BIT(offset));
+}
+
+static int adsp_gpio_to_irq(struct gpio_chip *chip, unsigned int offset)
+{
+ struct adsp_gpio_port *port = to_adsp_gpio_port(chip);
+ irq_hw_number_t irq = offset + port->irq_offset;
+ int map = irq_find_mapping(port->irq_domain, irq);
+
+ if (map)
+ return map;
+
+ return irq_create_mapping(port->irq_domain, irq);
+}
+
+static int adsp_gpio_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct adsp_gpio_port *gpio;
+ int ret;
+
+ gpio = devm_kzalloc(dev, sizeof(*gpio), GFP_KERNEL);
+ if (!gpio)
+ return -ENOMEM;
+
+ gpio->regs = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(gpio->regs))
+ return PTR_ERR(gpio->regs);
+
+ gpio->dev = dev;
+
+ ret = adsp_attach_pint_to_gpio(gpio);
+ if (ret)
+ dev_err_probe(gpio->dev, ret, "error attaching interupt to gpio pin\n");
+
+ spin_lock_init(&gpio->lock);
+
+ gpio->gpio.label = "adsp-gpio";
+ gpio->gpio.direction_input = adsp_gpio_direction_input;
+ gpio->gpio.direction_output = adsp_gpio_direction_output;
+ gpio->gpio.get = adsp_gpio_get_value;
+ gpio->gpio.set = adsp_gpio_set_value;
+ gpio->gpio.to_irq = adsp_gpio_to_irq;
+ gpio->gpio.request = gpiochip_generic_request;
+ gpio->gpio.free = gpiochip_generic_free;
+ gpio->gpio.ngpio = ADSP_PORT_NGPIO;
+ gpio->gpio.parent = dev;
+ gpio->gpio.base = -1;
+ return devm_gpiochip_add_data(dev, &gpio->gpio, gpio);
+}
+
+static const struct of_device_id adsp_gpio_of_match[] = {
+ { .compatible = "adi,adsp-port-gpio", },
+ { },
+};
+MODULE_DEVICE_TABLE(of, adsp_gpio_of_match);
+
+static struct platform_driver adsp_gpio_driver = {
+ .driver = {
+ .name = "adsp-port-gpio",
+ .of_match_table = adsp_gpio_of_match,
+ },
+ .probe = adsp_gpio_probe,
+};
+
+module_platform_driver(adsp_gpio_driver);
+
+MODULE_AUTHOR("Greg Malysa <greg.malysa@timesys.com>");
+MODULE_DESCRIPTION("Analog Devices GPIO driver");
+MODULE_LICENSE("GPL v2");
\ No newline at end of file
--
2.25.1
^ permalink raw reply related [flat|nested] 65+ messages in thread
* Re: [PATCH 09/21] gpio: add driver for ADI ADSP-SC5xx platform
2024-09-12 18:24 ` [PATCH 09/21] gpio: add driver for ADI ADSP-SC5xx platform Arturs Artamonovs via B4 Relay
@ 2024-09-13 7:38 ` Arnd Bergmann
2024-09-14 14:29 ` kernel test robot
` (2 subsequent siblings)
3 siblings, 0 replies; 65+ messages in thread
From: Arnd Bergmann @ 2024-09-13 7:38 UTC (permalink / raw)
To: arturs.artamonovs, Catalin Marinas, Will Deacon, Greg Malysa,
Philipp Zabel, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Utsav Agarwal, Michael Turquette, Stephen Boyd, Linus Walleij,
Bartosz Golaszewski, Thomas Gleixner, Andi Shyti,
Greg Kroah-Hartman, Jiri Slaby, Olof Johansson, soc
Cc: linux-arm-kernel, linux-kernel, devicetree, linux-clk,
open list:GPIO SUBSYSTEM, linux-i2c, linux-serial, adsp-linux,
Nathan Barrett-Morrison
On Thu, Sep 12, 2024, at 18:24, Arturs Artamonovs via B4 Relay wrote:
> +
> +#include <linux/device.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/platform_device.h>
> +#include <linux/soc/adi/adsp-gpio-port.h>
> +#include "gpiolib.h"
> +
> +static int adsp_gpio_direction_input(struct gpio_chip *chip, unsigned
> int offset)
> +{
> + struct adsp_gpio_port *port = to_adsp_gpio_port(chip);
> +
> + __adsp_gpio_writew(port, BIT(offset), ADSP_PORT_REG_DIR_CLEAR);
> + __adsp_gpio_writew(port, BIT(offset), ADSP_PORT_REG_INEN_SET);
> + return 0;
What is the purpose of these __adsp_gpio_writew() in a global header?
Can't those be moved into this file directly?
> \ No newline at end of file
Whitespace damage?
Arnd
^ permalink raw reply [flat|nested] 65+ messages in thread
* Re: [PATCH 09/21] gpio: add driver for ADI ADSP-SC5xx platform
2024-09-12 18:24 ` [PATCH 09/21] gpio: add driver for ADI ADSP-SC5xx platform Arturs Artamonovs via B4 Relay
2024-09-13 7:38 ` Arnd Bergmann
@ 2024-09-14 14:29 ` kernel test robot
2024-09-16 6:50 ` Krzysztof Kozlowski
2024-10-01 12:44 ` Linus Walleij
3 siblings, 0 replies; 65+ messages in thread
From: kernel test robot @ 2024-09-14 14:29 UTC (permalink / raw)
To: Arturs Artamonovs via B4 Relay, Catalin Marinas, Will Deacon,
Greg Malysa, Philipp Zabel, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Utsav Agarwal, Michael Turquette, Stephen Boyd,
Linus Walleij, Bartosz Golaszewski, Thomas Gleixner, Andi Shyti,
Greg Kroah-Hartman, Jiri Slaby, Arnd Bergmann, Olof Johansson,
soc
Cc: oe-kbuild-all, linux-arm-kernel, linux-kernel, devicetree,
linux-clk, linux-gpio, linux-i2c, linux-serial, Arturs Artamonovs,
adsp-linux, Nathan Barrett-Morrison
Hi Arturs,
kernel test robot noticed the following build errors:
[auto build test ERROR on da3ea35007d0af457a0afc87e84fddaebc4e0b63]
url: https://github.com/intel-lab-lkp/linux/commits/Arturs-Artamonovs-via-B4-Relay/arm64-Add-ADI-ADSP-SC598-SoC/20240913-022308
base: da3ea35007d0af457a0afc87e84fddaebc4e0b63
patch link: https://lore.kernel.org/r/20240912-test-v1-9-458fa57c8ccf%40analog.com
patch subject: [PATCH 09/21] gpio: add driver for ADI ADSP-SC5xx platform
config: arm64-randconfig-r071-20240914 (https://download.01.org/0day-ci/archive/20240914/202409142215.olyOwnPE-lkp@intel.com/config)
compiler: aarch64-linux-gcc (GCC) 14.1.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240914/202409142215.olyOwnPE-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202409142215.olyOwnPE-lkp@intel.com/
All errors (new ones prefixed by >>):
aarch64-linux-ld: Unexpected GOT/PLT entries detected!
aarch64-linux-ld: Unexpected run-time procedure linkages detected!
aarch64-linux-ld: drivers/gpio/gpio-adi-adsp-port.o: in function `adsp_gpio_probe':
>> gpio-adi-adsp-port.c:(.text+0x1cc): undefined reference to `adsp_attach_pint_to_gpio'
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 65+ messages in thread
* Re: [PATCH 09/21] gpio: add driver for ADI ADSP-SC5xx platform
2024-09-12 18:24 ` [PATCH 09/21] gpio: add driver for ADI ADSP-SC5xx platform Arturs Artamonovs via B4 Relay
2024-09-13 7:38 ` Arnd Bergmann
2024-09-14 14:29 ` kernel test robot
@ 2024-09-16 6:50 ` Krzysztof Kozlowski
2024-10-01 12:44 ` Linus Walleij
3 siblings, 0 replies; 65+ messages in thread
From: Krzysztof Kozlowski @ 2024-09-16 6:50 UTC (permalink / raw)
To: arturs.artamonovs, Catalin Marinas, Will Deacon, Greg Malysa,
Philipp Zabel, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Utsav Agarwal, Michael Turquette, Stephen Boyd, Linus Walleij,
Bartosz Golaszewski, Thomas Gleixner, Andi Shyti,
Greg Kroah-Hartman, Jiri Slaby, Arnd Bergmann, Olof Johansson,
soc
Cc: linux-arm-kernel, linux-kernel, devicetree, linux-clk, linux-gpio,
linux-i2c, linux-serial, adsp-linux, Nathan Barrett-Morrison
On 12/09/2024 20:24, Arturs Artamonovs via B4 Relay wrote:
> From: Arturs Artamonovs <arturs.artamonovs@analog.com>
>
> Add ADSP-SC5xx GPIO driver.
> - Support all GPIO ports
> - Each gpio support seperate PINT interrupt controller
>
> Signed-off-by: Arturs Artamonovs <Arturs.Artamonovs@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>
Your SoB chain is odd. Author is Greg, but Greg is not the first person
in the chain? And no final SoB? This is really odd and not correct. I am
not sure what you even want to say here.
...
> +
> +module_platform_driver(adsp_gpio_driver);
> +
> +MODULE_AUTHOR("Greg Malysa <greg.malysa@timesys.com>");
> +MODULE_DESCRIPTION("Analog Devices GPIO driver");
> +MODULE_LICENSE("GPL v2");
> \ No newline at end of file
Please review all your patches before sending for such stuff.
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 65+ messages in thread
* Re: [PATCH 09/21] gpio: add driver for ADI ADSP-SC5xx platform
2024-09-12 18:24 ` [PATCH 09/21] gpio: add driver for ADI ADSP-SC5xx platform Arturs Artamonovs via B4 Relay
` (2 preceding siblings ...)
2024-09-16 6:50 ` Krzysztof Kozlowski
@ 2024-10-01 12:44 ` Linus Walleij
2024-10-01 14:29 ` Artamonovs, Arturs
2024-10-01 21:57 ` Greg Malysa
3 siblings, 2 replies; 65+ messages in thread
From: Linus Walleij @ 2024-10-01 12:44 UTC (permalink / raw)
To: arturs.artamonovs
Cc: Catalin Marinas, Will Deacon, Greg Malysa, Philipp Zabel,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Utsav Agarwal,
Michael Turquette, Stephen Boyd, Bartosz Golaszewski,
Thomas Gleixner, Andi Shyti, Greg Kroah-Hartman, Jiri Slaby,
Arnd Bergmann, Olof Johansson, soc, linux-arm-kernel,
linux-kernel, devicetree, linux-clk, linux-gpio, linux-i2c,
linux-serial, adsp-linux, Nathan Barrett-Morrison
Hi Arturs,
thanks for your patch!
On Thu, Sep 12, 2024 at 8:20 PM Arturs Artamonovs via B4 Relay
<devnull+arturs.artamonovs.analog.com@kernel.org> wrote:
> From: Arturs Artamonovs <arturs.artamonovs@analog.com>
>
> Add ADSP-SC5xx GPIO driver.
> - Support all GPIO ports
> - Each gpio support seperate PINT interrupt controller
>
> Signed-off-by: Arturs Artamonovs <Arturs.Artamonovs@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>
(...)
> +config GPIO_ADI_ADSP_PORT
> + bool "ADI ADSP PORT GPIO driver"
> + depends on OF_GPIO
> + select GPIO_GENERIC
If you select this then you need to use it in the idiomatic way.
+#include <linux/soc/adi/adsp-gpio-port.h>
Drop this, just bring the contents into this file all register defines
etc.
+#include "gpiolib.h"
No way, do this:
#include <linux/gpio/driver.h>
> +static int adsp_gpio_direction_input(struct gpio_chip *chip, unsigned int offset)
> +{
> + struct adsp_gpio_port *port = to_adsp_gpio_port(chip);
> +
> + __adsp_gpio_writew(port, BIT(offset), ADSP_PORT_REG_DIR_CLEAR);
Ah these __adsp_gpio_writew/readw things are too idiomatic. Just
use the base and common writew() please.
> + __adsp_gpio_writew(port, BIT(offset), ADSP_PORT_REG_INEN_SET);
Interrupt enable in the direction function? No thanks, poke the
interrupt registers in your irqchip if you make one (you currently
do not) in this case I'd say just disable all interrupts in probe()
using something like writew(base + ADSP_PORT_REG_INEN_SET, 0xffff)
and be done with it.
> +static int adsp_gpio_get_value(struct gpio_chip *chip, unsigned int offset)
> +{
> + struct adsp_gpio_port *port = to_adsp_gpio_port(chip);
> +
> + return !!(__adsp_gpio_readw(port, ADSP_PORT_REG_DATA) & BIT(offset));
> +}
This becomes a reimplemenation of generic GPIO.
> +static int adsp_gpio_to_irq(struct gpio_chip *chip, unsigned int offset)
> +{
> + struct adsp_gpio_port *port = to_adsp_gpio_port(chip);
> + irq_hw_number_t irq = offset + port->irq_offset;
> + int map = irq_find_mapping(port->irq_domain, irq);
> +
> + if (map)
> + return map;
> +
> + return irq_create_mapping(port->irq_domain, irq);
> +}
This irqdomain in the "port" looks weird.
Implement the irqchip in the GPIO driver instead.
If the domain *has* to be external to the GPIO driver then
you need to use hierarchical irqdomains.
> +static int adsp_gpio_probe(struct platform_device *pdev)
> +{
> + struct device *dev = &pdev->dev;
> + struct adsp_gpio_port *gpio;
> + int ret;
> +
> + gpio = devm_kzalloc(dev, sizeof(*gpio), GFP_KERNEL);
> + if (!gpio)
> + return -ENOMEM;
> +
> + gpio->regs = devm_platform_ioremap_resource(pdev, 0);
> + if (IS_ERR(gpio->regs))
> + return PTR_ERR(gpio->regs);
So you have gpio->regs which is the base.
> + gpio->dev = dev;
> +
> + ret = adsp_attach_pint_to_gpio(gpio);
> + if (ret)
> + dev_err_probe(gpio->dev, ret, "error attaching interupt to gpio pin\n");
> +
> + spin_lock_init(&gpio->lock);
> +
> + gpio->gpio.label = "adsp-gpio";
> + gpio->gpio.direction_input = adsp_gpio_direction_input;
> + gpio->gpio.direction_output = adsp_gpio_direction_output;
> + gpio->gpio.get = adsp_gpio_get_value;
> + gpio->gpio.set = adsp_gpio_set_value;
> + gpio->gpio.to_irq = adsp_gpio_to_irq;
> + gpio->gpio.request = gpiochip_generic_request;
> + gpio->gpio.free = gpiochip_generic_free;
> + gpio->gpio.ngpio = ADSP_PORT_NGPIO;
> + gpio->gpio.parent = dev;
> + gpio->gpio.base = -1;
> + return devm_gpiochip_add_data(dev, &gpio->gpio, gpio);
Look in e.g. drivers/gpio/gpio-ftgpio010.c for an example of
how to use generic GPIO (with an irqchip!). It will be something like:
ret = bgpio_init(&g->gc, dev, 2,
gpio->regs + ADSP_PORT_REG_DATA,
gpio->regs + ADSP_PORT_REG_DATA_SET,
gpio->regs + ADSP_PORT_REG_DATA_CLEAR,
gpio->regs + ADSP_PORT_REG_DIR_SET,
gpio->regs + ADSP_PORT_REG_DIR_CLEAR,
0);
if (ret) {
dev_err(dev, "unable to init generic GPIO\n");
goto dis_clk;
}
g->gc.label = dev_name(dev);
g->gc.base = -1;
g->gc.parent = dev;
g->gc.owner = THIS_MODULE;
/* ngpio is set by bgpio_init() */
You can augment the generic driver instance with an extra config function
to set the special open drain bits.
Yours,
Linus Walleij
^ permalink raw reply [flat|nested] 65+ messages in thread
* RE: [PATCH 09/21] gpio: add driver for ADI ADSP-SC5xx platform
2024-10-01 12:44 ` Linus Walleij
@ 2024-10-01 14:29 ` Artamonovs, Arturs
2024-10-01 21:57 ` Greg Malysa
1 sibling, 0 replies; 65+ messages in thread
From: Artamonovs, Arturs @ 2024-10-01 14:29 UTC (permalink / raw)
To: Linus Walleij
Cc: Catalin Marinas, Will Deacon, Greg Malysa, Philipp Zabel,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Agarwal, Utsav,
Michael Turquette, Stephen Boyd, Bartosz Golaszewski,
Thomas Gleixner, Andi Shyti, Greg Kroah-Hartman, Jiri Slaby,
Arnd Bergmann, Olof Johansson, soc@kernel.org,
linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org, devicetree@vger.kernel.org,
linux-clk@vger.kernel.org, linux-gpio@vger.kernel.org,
linux-i2c@vger.kernel.org, linux-serial@vger.kernel.org,
Linux Factory, Nathan Barrett-Morrison
Thanks for feedback Linus, will address that in next patch version
> -----Original Message-----
> From: Linus Walleij <linus.walleij@linaro.org>
> Sent: Tuesday, October 1, 2024 1:45 PM
> To: Artamonovs, Arturs <Arturs.Artamonovs@analog.com>
> Cc: 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>; 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>;
> Arnd Bergmann <arnd@arndb.de>; Olof Johansson <olof@lixom.net>;
> soc@kernel.org; linux-arm-kernel@lists.infradead.org; linux-
> kernel@vger.kernel.org; devicetree@vger.kernel.org; linux-clk@vger.kernel.org;
> 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 09/21] gpio: add driver for ADI ADSP-SC5xx platform
>
> [External]
>
> Hi Arturs,
>
> thanks for your patch!
>
> On Thu, Sep 12, 2024 at 8:20 PM Arturs Artamonovs via B4 Relay
> <devnull+arturs.artamonovs.analog.com@kernel.org> wrote:
>
> > From: Arturs Artamonovs <arturs.artamonovs@analog.com>
> >
> > Add ADSP-SC5xx GPIO driver.
> > - Support all GPIO ports
> > - Each gpio support seperate PINT interrupt controller
> >
> > Signed-off-by: Arturs Artamonovs <Arturs.Artamonovs@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>
>
> (...)
>
> > +config GPIO_ADI_ADSP_PORT
> > + bool "ADI ADSP PORT GPIO driver"
> > + depends on OF_GPIO
> > + select GPIO_GENERIC
>
> If you select this then you need to use it in the idiomatic way.
>
> +#include <linux/soc/adi/adsp-gpio-port.h>
>
> Drop this, just bring the contents into this file all register defines
> etc.
>
> +#include "gpiolib.h"
>
> No way, do this:
> #include <linux/gpio/driver.h>
>
> > +static int adsp_gpio_direction_input(struct gpio_chip *chip, unsigned int offset)
> > +{
> > + struct adsp_gpio_port *port = to_adsp_gpio_port(chip);
> > +
> > + __adsp_gpio_writew(port, BIT(offset), ADSP_PORT_REG_DIR_CLEAR);
>
> Ah these __adsp_gpio_writew/readw things are too idiomatic. Just
> use the base and common writew() please.
>
> > + __adsp_gpio_writew(port, BIT(offset), ADSP_PORT_REG_INEN_SET);
>
> Interrupt enable in the direction function? No thanks, poke the
> interrupt registers in your irqchip if you make one (you currently
> do not) in this case I'd say just disable all interrupts in probe()
> using something like writew(base + ADSP_PORT_REG_INEN_SET, 0xffff)
> and be done with it.
>
> > +static int adsp_gpio_get_value(struct gpio_chip *chip, unsigned int offset)
> > +{
> > + struct adsp_gpio_port *port = to_adsp_gpio_port(chip);
> > +
> > + return !!(__adsp_gpio_readw(port, ADSP_PORT_REG_DATA) & BIT(offset));
> > +}
>
> This becomes a reimplemenation of generic GPIO.
>
> > +static int adsp_gpio_to_irq(struct gpio_chip *chip, unsigned int offset)
> > +{
> > + struct adsp_gpio_port *port = to_adsp_gpio_port(chip);
> > + irq_hw_number_t irq = offset + port->irq_offset;
> > + int map = irq_find_mapping(port->irq_domain, irq);
> > +
> > + if (map)
> > + return map;
> > +
> > + return irq_create_mapping(port->irq_domain, irq);
> > +}
>
> This irqdomain in the "port" looks weird.
>
> Implement the irqchip in the GPIO driver instead.
>
> If the domain *has* to be external to the GPIO driver then
> you need to use hierarchical irqdomains.
>
> > +static int adsp_gpio_probe(struct platform_device *pdev)
> > +{
> > + struct device *dev = &pdev->dev;
> > + struct adsp_gpio_port *gpio;
> > + int ret;
> > +
> > + gpio = devm_kzalloc(dev, sizeof(*gpio), GFP_KERNEL);
> > + if (!gpio)
> > + return -ENOMEM;
> > +
> > + gpio->regs = devm_platform_ioremap_resource(pdev, 0);
> > + if (IS_ERR(gpio->regs))
> > + return PTR_ERR(gpio->regs);
>
> So you have gpio->regs which is the base.
>
> > + gpio->dev = dev;
> > +
> > + ret = adsp_attach_pint_to_gpio(gpio);
> > + if (ret)
> > + dev_err_probe(gpio->dev, ret, "error attaching interupt to gpio
> pin\n");
> > +
> > + spin_lock_init(&gpio->lock);
> > +
> > + gpio->gpio.label = "adsp-gpio";
> > + gpio->gpio.direction_input = adsp_gpio_direction_input;
> > + gpio->gpio.direction_output = adsp_gpio_direction_output;
> > + gpio->gpio.get = adsp_gpio_get_value;
> > + gpio->gpio.set = adsp_gpio_set_value;
> > + gpio->gpio.to_irq = adsp_gpio_to_irq;
> > + gpio->gpio.request = gpiochip_generic_request;
> > + gpio->gpio.free = gpiochip_generic_free;
> > + gpio->gpio.ngpio = ADSP_PORT_NGPIO;
> > + gpio->gpio.parent = dev;
> > + gpio->gpio.base = -1;
> > + return devm_gpiochip_add_data(dev, &gpio->gpio, gpio);
>
> Look in e.g. drivers/gpio/gpio-ftgpio010.c for an example of
> how to use generic GPIO (with an irqchip!). It will be something like:
>
> ret = bgpio_init(&g->gc, dev, 2,
> gpio->regs + ADSP_PORT_REG_DATA,
> gpio->regs + ADSP_PORT_REG_DATA_SET,
> gpio->regs + ADSP_PORT_REG_DATA_CLEAR,
> gpio->regs + ADSP_PORT_REG_DIR_SET,
> gpio->regs + ADSP_PORT_REG_DIR_CLEAR,
> 0);
> if (ret) {
> dev_err(dev, "unable to init generic GPIO\n");
> goto dis_clk;
> }
> g->gc.label = dev_name(dev);
> g->gc.base = -1;
> g->gc.parent = dev;
> g->gc.owner = THIS_MODULE;
> /* ngpio is set by bgpio_init() */
>
> You can augment the generic driver instance with an extra config function
> to set the special open drain bits.
>
> Yours,
> Linus Walleij
^ permalink raw reply [flat|nested] 65+ messages in thread
* Re: [PATCH 09/21] gpio: add driver for ADI ADSP-SC5xx platform
2024-10-01 12:44 ` Linus Walleij
2024-10-01 14:29 ` Artamonovs, Arturs
@ 2024-10-01 21:57 ` Greg Malysa
2024-10-02 13:53 ` Linus Walleij
1 sibling, 1 reply; 65+ messages in thread
From: Greg Malysa @ 2024-10-01 21:57 UTC (permalink / raw)
To: Linus Walleij
Cc: arturs.artamonovs, Catalin Marinas, Will Deacon, Philipp Zabel,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Utsav Agarwal,
Michael Turquette, Stephen Boyd, Bartosz Golaszewski,
Thomas Gleixner, Andi Shyti, Greg Kroah-Hartman, Jiri Slaby,
Arnd Bergmann, Olof Johansson, soc, linux-arm-kernel,
linux-kernel, devicetree, linux-clk, linux-gpio, linux-i2c,
linux-serial, adsp-linux, Nathan Barrett-Morrison
Hi Linus,
Thanks for the review.
> > + __adsp_gpio_writew(port, BIT(offset), ADSP_PORT_REG_INEN_SET);
>
> Interrupt enable in the direction function? No thanks, poke the
> interrupt registers in your irqchip if you make one (you currently
> do not) in this case I'd say just disable all interrupts in probe()
> using something like writew(base + ADSP_PORT_REG_INEN_SET, 0xffff)
> and be done with it.
>
This will come up next time too so I wanted to mention that INEN here
means "input enable." The PORT design has two registers for
controlling pin direction, one to enable/disable output drivers (DIR)
and one to enable input drivers (INEN) to be able to read the pin
state from the gpio data register. If I recall the bare metal
reference code toggled both but we can review if setting INEN for all
pins and leaving it is acceptable as well to simplify things.
Thanks,
Greg
--
Greg Malysa
Timesys Corporation
^ permalink raw reply [flat|nested] 65+ messages in thread
* Re: [PATCH 09/21] gpio: add driver for ADI ADSP-SC5xx platform
2024-10-01 21:57 ` Greg Malysa
@ 2024-10-02 13:53 ` Linus Walleij
0 siblings, 0 replies; 65+ messages in thread
From: Linus Walleij @ 2024-10-02 13:53 UTC (permalink / raw)
To: Greg Malysa
Cc: arturs.artamonovs, Catalin Marinas, Will Deacon, Philipp Zabel,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Utsav Agarwal,
Michael Turquette, Stephen Boyd, Bartosz Golaszewski,
Thomas Gleixner, Andi Shyti, Greg Kroah-Hartman, Jiri Slaby,
Arnd Bergmann, Olof Johansson, soc, linux-arm-kernel,
linux-kernel, devicetree, linux-clk, linux-gpio, linux-i2c,
linux-serial, adsp-linux, Nathan Barrett-Morrison
On Tue, Oct 1, 2024 at 11:58 PM Greg Malysa <greg.malysa@timesys.com> wrote:
> > Interrupt enable in the direction function? No thanks, poke the
> > interrupt registers in your irqchip if you make one (you currently
> > do not) in this case I'd say just disable all interrupts in probe()
> > using something like writew(base + ADSP_PORT_REG_INEN_SET, 0xffff)
> > and be done with it.
> >
>
> This will come up next time too so I wanted to mention that INEN here
> means "input enable." The PORT design has two registers for
> controlling pin direction, one to enable/disable output drivers (DIR)
> and one to enable input drivers (INEN) to be able to read the pin
> state from the gpio data register. If I recall the bare metal
> reference code toggled both but we can review if setting INEN for all
> pins and leaving it is acceptable as well to simplify things.
Aha so that's what it means!
Yeah play around with it and see what you can come up with.
Perhaps you need to override the input/output enable
callbacks with local versions rather than the gpio-mmio
ones to set all bits. (This is possible to do after
bgpio_init() but before adding the gpio_chip if necessary.)
Yours,
Linus Walleij
^ permalink raw reply [flat|nested] 65+ messages in thread
* [PATCH 10/21] dt-bindings: gpio: adi,adsp-port-gpio: add bindings
2024-09-12 18:24 [PATCH 00/21] Adding support of ADI ARMv8 ADSP-SC598 SoC Arturs Artamonovs via B4 Relay
` (8 preceding siblings ...)
2024-09-12 18:24 ` [PATCH 09/21] gpio: add driver for ADI ADSP-SC5xx platform Arturs Artamonovs via B4 Relay
@ 2024-09-12 18:24 ` Arturs Artamonovs via B4 Relay
2024-09-16 6:53 ` Krzysztof Kozlowski
2024-09-12 18:24 ` [PATCH 11/21] irqchip: Add irqchip for ADI ADSP-SC5xx platform Arturs Artamonovs via B4 Relay
` (13 subsequent siblings)
23 siblings, 1 reply; 65+ messages in thread
From: Arturs Artamonovs via B4 Relay @ 2024-09-12 18:24 UTC (permalink / raw)
To: Catalin Marinas, Will Deacon, Greg Malysa, Philipp Zabel,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Utsav Agarwal,
Michael Turquette, Stephen Boyd, Linus Walleij,
Bartosz Golaszewski, Thomas Gleixner, Andi Shyti,
Greg Kroah-Hartman, Jiri Slaby, Arnd Bergmann, Olof Johansson,
soc
Cc: linux-arm-kernel, linux-kernel, devicetree, linux-clk, linux-gpio,
linux-i2c, linux-serial, Arturs Artamonovs, adsp-linux,
Arturs Artamonovs, Nathan Barrett-Morrison
From: Arturs Artamonovs <arturs.artamonovs@analog.com>
Add ADSP-SC5xx GPIO driver bindings.
Signed-off-by: Arturs Artamonovs <Arturs.Artamonovs@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>
---
.../bindings/gpio/adi,adsp-port-gpio.yaml | 69 ++++++++++++++++++++++
1 file changed, 69 insertions(+)
diff --git a/Documentation/devicetree/bindings/gpio/adi,adsp-port-gpio.yaml b/Documentation/devicetree/bindings/gpio/adi,adsp-port-gpio.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..3d7899ce759193296ce787d09d742824277f37f8
--- /dev/null
+++ b/Documentation/devicetree/bindings/gpio/adi,adsp-port-gpio.yaml
@@ -0,0 +1,69 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/gpio/adi,adsp-port-gpio.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Analog Devices GPIO Port Driver for SC5XX-family processors
+
+maintainers:
+ - Arturs Artamonovs <arturs.artamonovs@analog.com>
+ - Utsav Agarwal <Utsav.Agarwal@analog.com>
+
+description: |
+ Analog Devices GPIO Port Driver for SC5XX-family processors
+
+properties:
+ compatible:
+ enum:
+ - adi,adsp-port-gpio
+
+ gpio-controller: true
+
+ "#gpio-cells":
+ const: 2
+
+ gpio-ranges:
+ description: Associated pinmux controller and the GPIO range values
+
+ adi,pint:
+ $ref: /schemas/types.yaml#/definitions/phandle-array
+ description: Associated pin interrupt controller driver
+ items:
+ - items:
+ - description: phandle to pin interrupt controller driver
+ - description: interrupt value
+
+ reg:
+ description: PORT GPIO control registers
+
+required:
+ - compatible
+ - reg
+ - "#gpio-cells"
+ - gpio-controller
+ - gpio-ranges
+ - adi,pint
+
+additionalProperties: false
+
+examples:
+ - |
+ gpa: gport@31004000 {
+ compatible = "adi,adsp-port-gpio";
+ gpio-controller;
+ #gpio-cells = <2>;
+ reg = <0x31004000 0x7F>;
+ gpio-ranges = <&pinctrl0 0 0 16>;
+ adi,pint = <&pint0 1>;
+ };
+
+ gpb: gport@31004080 {
+ compatible = "adi,adsp-port-gpio";
+ gpio-controller;
+ #gpio-cells = <2>;
+ reg = <0x31004080 0x7F>;
+ gpio-ranges = <&pinctrl0 0 16 16>;
+ adi,pint = <&pint0 0>;
+ };
+...
--
2.25.1
^ permalink raw reply related [flat|nested] 65+ messages in thread
* Re: [PATCH 10/21] dt-bindings: gpio: adi,adsp-port-gpio: add bindings
2024-09-12 18:24 ` [PATCH 10/21] dt-bindings: gpio: adi,adsp-port-gpio: add bindings Arturs Artamonovs via B4 Relay
@ 2024-09-16 6:53 ` Krzysztof Kozlowski
0 siblings, 0 replies; 65+ messages in thread
From: Krzysztof Kozlowski @ 2024-09-16 6:53 UTC (permalink / raw)
To: arturs.artamonovs, Catalin Marinas, Will Deacon, Greg Malysa,
Philipp Zabel, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Utsav Agarwal, Michael Turquette, Stephen Boyd, Linus Walleij,
Bartosz Golaszewski, Thomas Gleixner, Andi Shyti,
Greg Kroah-Hartman, Jiri Slaby, Arnd Bergmann, Olof Johansson,
soc
Cc: linux-arm-kernel, linux-kernel, devicetree, linux-clk, linux-gpio,
linux-i2c, linux-serial, adsp-linux, Nathan Barrett-Morrison
On 12/09/2024 20:24, Arturs Artamonovs via B4 Relay wrote:
> From: Arturs Artamonovs <arturs.artamonovs@analog.com>
>
> Add ADSP-SC5xx GPIO driver bindings.
>
> Signed-off-by: Arturs Artamonovs <Arturs.Artamonovs@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>
> ---
> .../bindings/gpio/adi,adsp-port-gpio.yaml | 69 ++++++++++++++++++++++
> 1 file changed, 69 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/gpio/adi,adsp-port-gpio.yaml b/Documentation/devicetree/bindings/gpio/adi,adsp-port-gpio.yaml
> new file mode 100644
> index 0000000000000000000000000000000000000000..3d7899ce759193296ce787d09d742824277f37f8
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/gpio/adi,adsp-port-gpio.yaml
> @@ -0,0 +1,69 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/gpio/adi,adsp-port-gpio.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Analog Devices GPIO Port Driver for SC5XX-family processors
> +
> +maintainers:
> + - Arturs Artamonovs <arturs.artamonovs@analog.com>
> + - Utsav Agarwal <Utsav.Agarwal@analog.com>
> +
> +description: |
Do not need '|' unless you need to preserve formatting.
All review comments apply to all your patches.
> + Analog Devices GPIO Port Driver for SC5XX-family processors
> +
> +properties:
> + compatible:
> + enum:
> + - adi,adsp-port-gpio
No, this *must* be SoC-specific compatible. If you are unsure, just look
at any other SoC (of course nothing ancient).
> +
> + gpio-controller: true
> +
> + "#gpio-cells":
> + const: 2
> +
> + gpio-ranges:
> + description: Associated pinmux controller and the GPIO range values
That's useless comment. Just true, or min/maxItems
> +
> + adi,pint:
> + $ref: /schemas/types.yaml#/definitions/phandle-array
> + description: Associated pin interrupt controller driver
> + items:
> + - items:
> + - description: phandle to pin interrupt controller driver
> + - description: interrupt value
Hm? No, why would you put it here? And why this is not just interrupts
property?
> +
> + reg:
> + description: PORT GPIO control registers
Reg goes after compatible
> +
> +required:
> + - compatible
> + - reg
Look, here order is correct.
> + - "#gpio-cells"
> + - gpio-controller
> + - gpio-ranges
> + - adi,pint
> +
> +additionalProperties: false
> +
> +examples:
> + - |
> + gpa: gport@31004000 {
Node names should be generic. See also an explanation and list of
examples (not exhaustive) in DT specification:
https://devicetree-specification.readthedocs.io/en/latest/chapter2-devicetree-basics.html#generic-names-recommendation
Drop unused label.
> + compatible = "adi,adsp-port-gpio";
> + gpio-controller;
> + #gpio-cells = <2>;
> + reg = <0x31004000 0x7F>;
It is ALWAYS lowercase hex. This applies (just like all other comments)
to all your DT-related code.
> + gpio-ranges = <&pinctrl0 0 0 16>;
> + adi,pint = <&pint0 1>;
Just one example. Drop the one below.
> + };
> +
> + gpb: gport@31004080 {
> + compatible = "adi,adsp-port-gpio";
> + gpio-controller;
> + #gpio-cells = <2>;
> + reg = <0x31004080 0x7F>;
> + gpio-ranges = <&pinctrl0 0 16 16>;
> + adi,pint = <&pint0 0>;
> + };
> +...
>
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 65+ messages in thread
* [PATCH 11/21] irqchip: Add irqchip for ADI ADSP-SC5xx platform
2024-09-12 18:24 [PATCH 00/21] Adding support of ADI ARMv8 ADSP-SC598 SoC Arturs Artamonovs via B4 Relay
` (9 preceding siblings ...)
2024-09-12 18:24 ` [PATCH 10/21] dt-bindings: gpio: adi,adsp-port-gpio: add bindings Arturs Artamonovs via B4 Relay
@ 2024-09-12 18:24 ` Arturs Artamonovs via B4 Relay
2024-09-13 20:40 ` kernel test robot
` (2 more replies)
2024-09-12 18:24 ` [PATCH 12/21] dt-bindings: irqchip: adi,adsp-pint: add binding Arturs Artamonovs via B4 Relay
` (12 subsequent siblings)
23 siblings, 3 replies; 65+ messages in thread
From: Arturs Artamonovs via B4 Relay @ 2024-09-12 18:24 UTC (permalink / raw)
To: Catalin Marinas, Will Deacon, Greg Malysa, Philipp Zabel,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Utsav Agarwal,
Michael Turquette, Stephen Boyd, Linus Walleij,
Bartosz Golaszewski, Thomas Gleixner, Andi Shyti,
Greg Kroah-Hartman, Jiri Slaby, Arnd Bergmann, Olof Johansson,
soc
Cc: linux-arm-kernel, linux-kernel, devicetree, linux-clk, linux-gpio,
linux-i2c, linux-serial, Arturs Artamonovs, adsp-linux,
Arturs Artamonovs, Nathan Barrett-Morrison
From: Arturs Artamonovs <arturs.artamonovs@analog.com>
Support seting extra indepdendent interrupt on pin activity.
Signed-off-by: Arturs Artamonovs <Arturs.Artamonovs@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>
---
drivers/irqchip/Kconfig | 9 ++
drivers/irqchip/Makefile | 2 +
drivers/irqchip/irq-adi-adsp.c | 310 +++++++++++++++++++++++++++++++++++++++++
3 files changed, 321 insertions(+)
diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
index d078bdc48c38f13af9a129974f3b637dfee0e40f..1bc8f1bd45b3d2f69d2d0e6c8fa01b17b12ce241 100644
--- a/drivers/irqchip/Kconfig
+++ b/drivers/irqchip/Kconfig
@@ -91,6 +91,15 @@ config ALPINE_MSI
select PCI_MSI
select GENERIC_IRQ_CHIP
+config ADI_ADSP_IRQ
+ bool "ADI PORT PINT Driver"
+ depends on OF
+ depends on (ARCH_SC59X_64 || ARCH_SC59X)
+ select IRQ_DOMAIN
+ help
+ Say Y to enable the PORT-based PINT interrupt controller for
+ Analog Devices ADSP devices.
+
config AL_FIC
bool "Amazon's Annapurna Labs Fabric Interrupt Controller"
depends on OF
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index 15635812b2d6605a2dd3bb0e5fb3170ab2cb0f77..258a188676fd97e713f3cebe16e3d563add095f3 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -1,6 +1,8 @@
# SPDX-License-Identifier: GPL-2.0
obj-$(CONFIG_IRQCHIP) += irqchip.o
+
+obj-$(CONFIG_ADI_ADSP_IRQ) += irq-adi-adsp.o
obj-$(CONFIG_AL_FIC) += irq-al-fic.o
obj-$(CONFIG_ALPINE_MSI) += irq-alpine-msi.o
obj-$(CONFIG_ATH79) += irq-ath79-cpu.o
diff --git a/drivers/irqchip/irq-adi-adsp.c b/drivers/irqchip/irq-adi-adsp.c
new file mode 100644
index 0000000000000000000000000000000000000000..75e10575ca80216b8baf5cb8daf1f62efae5f23b
--- /dev/null
+++ b/drivers/irqchip/irq-adi-adsp.c
@@ -0,0 +1,310 @@
+// SPDX-License-Identifier: GPL-2.0
+/**
+ * ADSP PINT PORT driver.
+ *
+ * The default mapping is used for all PINTs, refer to the HRM to identify
+ * PORT mapping to PINTs. For example, PINT0 has PORT B (0-15) and PORT A
+ * (16-31).
+ *
+ * Copyright (C) 2022-2024, Analog Devices, Inc.
+ */
+
+#include <linux/bitops.h>
+#include <linux/irq.h>
+#include <linux/irqchip/chained_irq.h>
+#include <linux/irqdesc.h>
+#include <linux/irqdomain.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_irq.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/soc/adi/adsp-gpio-port.h>
+
+#define ADSP_PINT_IRQS 32
+
+/* Register offsets in a single PINT */
+#define ADSP_PINT_REG_MASK_SET 0x00
+#define ADSP_PINT_REG_MASK_CLEAR 0x04
+#define ADSP_PINT_REG_REQUEST 0x08
+#define ADSP_PINT_REG_ASSIGN 0x0c
+#define ADSP_PINT_REG_EDGE_SET 0x10
+#define ADSP_PINT_REG_EDGE_CLEAR 0x14
+#define ADSP_PINT_REG_INVERT_SET 0x18
+#define ADSP_PINT_REG_INVERT_CLEAR 0x1c
+#define ADSP_PINT_REG_PINSTATE 0x20
+#define ADSP_PINT_REG_LATCH 0x24
+
+struct adsp_pint {
+ struct irq_chip chip;
+ void __iomem *regs;
+ struct irq_domain *domain;
+ unsigned int irq;
+};
+
+static struct adsp_pint *to_adsp_pint(struct irq_chip *chip)
+{
+ return container_of(chip, struct adsp_pint, chip);
+}
+
+/**
+ * Each gpio device should be connected to one of the two valid pints with an
+ * indicator of which half it is connected to:
+ *
+ * pint0 {
+ * ...
+ * };
+ * gpa {
+ * adi,pint = <&pint0 1>;
+ * };
+ * gpb {
+ * adi,pint = <&pint0 0>;
+ * };
+ *
+ * This relies on the default configuration of the hardware, which we do not
+ * expose an interface to change.
+ */
+int adsp_attach_pint_to_gpio(struct adsp_gpio_port *port)
+{
+ struct platform_device *pint_pdev;
+ struct device_node *pint_node;
+ struct adsp_pint *pint;
+ struct of_phandle_args args;
+ int ret;
+
+ ret = of_parse_phandle_with_fixed_args(port->dev->of_node, "adi,pint", 1, 0,
+ &args);
+ if (ret) {
+ dev_err(port->dev, "Missing or invalid adi,pint connection for %pOFn; "
+ "attach a pint instance with one argument for port assignment\n",
+ port->dev->of_node);
+ return ret;
+ }
+
+ pint_node = args.np;
+
+ pint_pdev = of_find_device_by_node(pint_node);
+ if (!pint_pdev) {
+ ret = -EPROBE_DEFER;
+ goto cleanup;
+ }
+
+ pint = dev_get_drvdata(&pint_pdev->dev);
+ if (!pint) {
+ ret = -EPROBE_DEFER;
+ goto cleanup;
+ }
+
+ port->irq_domain = pint->domain;
+
+ if (args.args[0])
+ port->irq_offset = 16;
+ else
+ port->irq_offset = 0;
+
+cleanup:
+ of_node_put(pint_node);
+ return ret;
+}
+
+static void adsp_pint_dispatch_irq(struct irq_desc *desc)
+{
+ struct irq_chip *chip = irq_desc_get_chip(desc);
+ struct adsp_pint *pint = to_adsp_pint(chip);
+ unsigned int type = irqd_get_trigger_type(&desc->irq_data);
+ u32 pos = BIT(desc->irq_data.hwirq);
+
+ /* for both edge interrupt, toggle invert bit to catch next edge */
+ if (type == IRQ_TYPE_EDGE_BOTH) {
+ u32 invert = readl(pint->regs + ADSP_PINT_REG_INVERT_SET) & pos;
+
+ if (invert)
+ writel(pos, pint->regs + ADSP_PINT_REG_INVERT_CLEAR);
+ else
+ writel(pos, pint->regs + ADSP_PINT_REG_INVERT_SET);
+ }
+
+ writel(pos, pint->regs + ADSP_PINT_REG_REQUEST);
+
+ /* either edge is set */
+ if (type & IRQ_TYPE_EDGE_BOTH)
+ handle_edge_irq(desc);
+ else
+ handle_level_irq(desc);
+}
+
+static int adsp_pint_irq_map(struct irq_domain *domain, unsigned int irq,
+ irq_hw_number_t hwirq)
+{
+ struct adsp_pint *pint = domain->host_data;
+
+ irq_set_chip_data(irq, pint);
+ irq_set_chip_and_handler(irq, &pint->chip, adsp_pint_dispatch_irq);
+ return 0;
+}
+
+static const struct irq_domain_ops adsp_irq_domain_ops = {
+ .map = adsp_pint_irq_map,
+ .xlate = irq_domain_xlate_onecell,
+};
+
+/**
+ * This handles the GIC interrupt associated with this PINT being activated.
+ * It chains the interrupt associated with a particular pin
+ */
+static void adsp_pint_irq_handler(struct irq_desc *desc)
+{
+ struct adsp_pint *pint = irq_desc_get_handler_data(desc);
+ struct irq_chip *chip = irq_desc_get_chip(desc);
+ unsigned long req;
+ int pos;
+
+ chained_irq_enter(chip, desc);
+
+ req = readl(pint->regs + ADSP_PINT_REG_REQUEST);
+
+ for_each_set_bit(pos, &req, 32) {
+ unsigned int virq = irq_find_mapping(pint->domain, pos);
+
+ if (virq)
+ generic_handle_irq(virq);
+ }
+
+ chained_irq_exit(chip, desc);
+}
+
+static void adsp_pint_irq_ack(struct irq_data *d)
+{
+ /* this is required for edge type irqs unconditionally */
+}
+
+static void adsp_pint_irq_mask(struct irq_data *d)
+{
+ struct adsp_pint *pint = irq_data_get_irq_chip_data(d);
+
+ writel(BIT(d->hwirq), pint->regs + ADSP_PINT_REG_MASK_CLEAR);
+}
+
+static void adsp_pint_irq_unmask(struct irq_data *d)
+{
+ struct adsp_pint *pint = irq_data_get_irq_chip_data(d);
+
+ writel(BIT(d->hwirq), pint->regs + ADSP_PINT_REG_MASK_SET);
+}
+
+static int adsp_pint_irq_set_type(struct irq_data *d, unsigned int type)
+{
+ struct adsp_pint *pint = irq_data_get_irq_chip_data(d);
+ unsigned int pos = BIT(d->hwirq);
+
+ switch (type) {
+ case IRQ_TYPE_PROBE:
+ type = IRQ_TYPE_EDGE_BOTH;
+ fallthrough;
+ case IRQ_TYPE_EDGE_BOTH:
+ /* start by looking for rising edge */
+ writel(pos, pint->regs + ADSP_PINT_REG_INVERT_CLEAR);
+ writel(pos, pint->regs + ADSP_PINT_REG_EDGE_SET);
+ return 0;
+
+ case IRQ_TYPE_EDGE_FALLING:
+ writel(pos, pint->regs + ADSP_PINT_REG_INVERT_SET);
+ writel(pos, pint->regs + ADSP_PINT_REG_EDGE_SET);
+ return 0;
+
+ case IRQ_TYPE_EDGE_RISING:
+ writel(pos, pint->regs + ADSP_PINT_REG_INVERT_CLEAR);
+ writel(pos, pint->regs + ADSP_PINT_REG_EDGE_SET);
+ return 0;
+
+ case IRQ_TYPE_LEVEL_HIGH:
+ writel(pos, pint->regs + ADSP_PINT_REG_INVERT_CLEAR);
+ writel(pos, pint->regs + ADSP_PINT_REG_EDGE_CLEAR);
+ return 0;
+
+ case IRQ_TYPE_LEVEL_LOW:
+ writel(pos, pint->regs + ADSP_PINT_REG_INVERT_SET);
+ writel(pos, pint->regs + ADSP_PINT_REG_EDGE_CLEAR);
+ return 0;
+
+ default:
+ return -EINVAL;
+ }
+
+}
+
+static int adsp_pint_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct device_node *np = dev->of_node;
+ struct adsp_pint *pint;
+
+ pint = devm_kzalloc(dev, sizeof(*pint), GFP_KERNEL);
+ if (!pint)
+ return -ENOMEM;
+
+ pint->regs = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(pint->regs))
+ return PTR_ERR(pint->regs);
+
+ pint->chip.name = "adsp-pint";
+ pint->chip.irq_ack = adsp_pint_irq_ack;
+ pint->chip.irq_mask = adsp_pint_irq_mask;
+ pint->chip.irq_unmask = adsp_pint_irq_unmask;
+ pint->chip.irq_set_type = adsp_pint_irq_set_type;
+ // @todo potentially only SEC supports wake options, not gic
+
+ // @todo determine if we actually need a raw spinlock
+
+ pint->domain = irq_domain_add_linear(np, ADSP_PINT_IRQS,
+ &adsp_irq_domain_ops, pint);
+ if (!pint->domain) {
+ dev_err(dev, "Could not create irq domain\n");
+ return -EINVAL;
+ }
+
+ pint->irq = platform_get_irq(pdev, 0);
+ if (!pint->irq) {
+ dev_err(dev, "Could not find parent interrupt for port\n");
+ return -EINVAL;
+ }
+
+ irq_set_chained_handler_and_data(pint->irq, adsp_pint_irq_handler, pint);
+ platform_set_drvdata(pdev, pint);
+
+ return 0;
+}
+
+static void adsp_pint_remove(struct platform_device *pdev)
+{
+ struct adsp_pint *pint = platform_get_drvdata(pdev);
+
+ irq_set_chained_handler_and_data(pint->irq, NULL, NULL);
+ irq_domain_remove(pint->domain);
+}
+
+static const struct of_device_id adsp_pint_of_match[] = {
+ { .compatible = "adi,adsp-pint" },
+ { }
+};
+MODULE_DEVICE_TABLE(of, adsp_pint_of_match);
+
+static struct platform_driver adsp_pint_driver = {
+ .driver = {
+ .name = "adsp-port-pint",
+ .of_match_table = adsp_pint_of_match,
+ },
+ .probe = adsp_pint_probe,
+ .remove = adsp_pint_remove,
+};
+
+static int __init adsp_pint_init(void)
+{
+ return platform_driver_register(&adsp_pint_driver);
+}
+
+arch_initcall(adsp_pint_init);
+
+MODULE_DESCRIPTION("Analog Devices IRQChip driver");
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Greg Malysa <greg.malysa@timesys.com>");
\ No newline at end of file
--
2.25.1
^ permalink raw reply related [flat|nested] 65+ messages in thread
* Re: [PATCH 11/21] irqchip: Add irqchip for ADI ADSP-SC5xx platform
2024-09-12 18:24 ` [PATCH 11/21] irqchip: Add irqchip for ADI ADSP-SC5xx platform Arturs Artamonovs via B4 Relay
@ 2024-09-13 20:40 ` kernel test robot
2024-09-16 6:56 ` Krzysztof Kozlowski
2024-10-02 10:29 ` Thomas Gleixner
2 siblings, 0 replies; 65+ messages in thread
From: kernel test robot @ 2024-09-13 20:40 UTC (permalink / raw)
To: Arturs Artamonovs via B4 Relay, Catalin Marinas, Will Deacon,
Greg Malysa, Philipp Zabel, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Utsav Agarwal, Michael Turquette, Stephen Boyd,
Linus Walleij, Bartosz Golaszewski, Thomas Gleixner, Andi Shyti,
Greg Kroah-Hartman, Jiri Slaby, Arnd Bergmann, Olof Johansson,
soc
Cc: llvm, oe-kbuild-all, linux-arm-kernel, linux-kernel, devicetree,
linux-clk, linux-gpio, linux-i2c, linux-serial, Arturs Artamonovs,
adsp-linux, Nathan Barrett-Morrison
Hi Arturs,
kernel test robot noticed the following build warnings:
[auto build test WARNING on da3ea35007d0af457a0afc87e84fddaebc4e0b63]
url: https://github.com/intel-lab-lkp/linux/commits/Arturs-Artamonovs-via-B4-Relay/arm64-Add-ADI-ADSP-SC598-SoC/20240913-022308
base: da3ea35007d0af457a0afc87e84fddaebc4e0b63
patch link: https://lore.kernel.org/r/20240912-test-v1-11-458fa57c8ccf%40analog.com
patch subject: [PATCH 11/21] irqchip: Add irqchip for ADI ADSP-SC5xx platform
config: arm64-allmodconfig (https://download.01.org/0day-ci/archive/20240914/202409140451.t2a9fck6-lkp@intel.com/config)
compiler: clang version 20.0.0git (https://github.com/llvm/llvm-project bf684034844c660b778f0eba103582f582b710c9)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240914/202409140451.t2a9fck6-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202409140451.t2a9fck6-lkp@intel.com/
All warnings (new ones prefixed by >>):
>> drivers/irqchip/irq-adi-adsp.c:3: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
* ADSP PINT PORT driver.
drivers/irqchip/irq-adi-adsp.c:51: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
* Each gpio device should be connected to one of the two valid pints with an
drivers/irqchip/irq-adi-adsp.c:152: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
* This handles the GIC interrupt associated with this PINT being activated.
vim +3 drivers/irqchip/irq-adi-adsp.c
> 3 * ADSP PINT PORT driver.
4 *
5 * The default mapping is used for all PINTs, refer to the HRM to identify
6 * PORT mapping to PINTs. For example, PINT0 has PORT B (0-15) and PORT A
7 * (16-31).
8 *
9 * Copyright (C) 2022-2024, Analog Devices, Inc.
10 */
11
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 65+ messages in thread
* Re: [PATCH 11/21] irqchip: Add irqchip for ADI ADSP-SC5xx platform
2024-09-12 18:24 ` [PATCH 11/21] irqchip: Add irqchip for ADI ADSP-SC5xx platform Arturs Artamonovs via B4 Relay
2024-09-13 20:40 ` kernel test robot
@ 2024-09-16 6:56 ` Krzysztof Kozlowski
2024-10-02 10:29 ` Thomas Gleixner
2 siblings, 0 replies; 65+ messages in thread
From: Krzysztof Kozlowski @ 2024-09-16 6:56 UTC (permalink / raw)
To: arturs.artamonovs, Catalin Marinas, Will Deacon, Greg Malysa,
Philipp Zabel, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Utsav Agarwal, Michael Turquette, Stephen Boyd, Linus Walleij,
Bartosz Golaszewski, Thomas Gleixner, Andi Shyti,
Greg Kroah-Hartman, Jiri Slaby, Arnd Bergmann, Olof Johansson,
soc
Cc: linux-arm-kernel, linux-kernel, devicetree, linux-clk, linux-gpio,
linux-i2c, linux-serial, adsp-linux, Nathan Barrett-Morrison
On 12/09/2024 20:24, Arturs Artamonovs via B4 Relay wrote:
> From: Arturs Artamonovs <arturs.artamonovs@analog.com>
>
> Support seting extra indepdendent interrupt on pin activity.
>
> Signed-off-by: Arturs Artamonovs <Arturs.Artamonovs@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>
> ---
> drivers/irqchip/Kconfig | 9 ++
> drivers/irqchip/Makefile | 2 +
> drivers/irqchip/irq-adi-adsp.c | 310 +++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 321 insertions(+)
>
> diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
> index d078bdc48c38f13af9a129974f3b637dfee0e40f..1bc8f1bd45b3d2f69d2d0e6c8fa01b17b12ce241 100644
> --- a/drivers/irqchip/Kconfig
> +++ b/drivers/irqchip/Kconfig
> @@ -91,6 +91,15 @@ config ALPINE_MSI
> select PCI_MSI
> select GENERIC_IRQ_CHIP
>
> +config ADI_ADSP_IRQ
> + bool "ADI PORT PINT Driver"
What is "PORT"?
What is "PINT"?
> + depends on OF
> + depends on (ARCH_SC59X_64 || ARCH_SC59X)
Missing compile test.
> + select IRQ_DOMAIN
> + help
> + Say Y to enable the PORT-based PINT interrupt controller for
Expand acronyms here.
> + Analog Devices ADSP devices.
> +
> config AL_FIC
> bool "Amazon's Annapurna Labs Fabric Interrupt Controller"
> depends on OF
> diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
> index 15635812b2d6605a2dd3bb0e5fb3170ab2cb0f77..258a188676fd97e713f3cebe16e3d563add095f3 100644
> --- a/drivers/irqchip/Makefile
> +++ b/drivers/irqchip/Makefile
> @@ -1,6 +1,8 @@
> # SPDX-License-Identifier: GPL-2.0
> obj-$(CONFIG_IRQCHIP) += irqchip.o
>
> +
Why?
> +obj-$(CONFIG_ADI_ADSP_IRQ) += irq-adi-adsp.o
> obj-$(CONFIG_AL_FIC) += irq-al-fic.o
> obj-$(CONFIG_ALPINE_MSI) += irq-alpine-msi.o
...
> +
> +static int adsp_pint_irq_set_type(struct irq_data *d, unsigned int type)
> +{
> + struct adsp_pint *pint = irq_data_get_irq_chip_data(d);
> + unsigned int pos = BIT(d->hwirq);
> +
> + switch (type) {
> + case IRQ_TYPE_PROBE:
> + type = IRQ_TYPE_EDGE_BOTH;
> + fallthrough;
> + case IRQ_TYPE_EDGE_BOTH:
> + /* start by looking for rising edge */
> + writel(pos, pint->regs + ADSP_PINT_REG_INVERT_CLEAR);
> + writel(pos, pint->regs + ADSP_PINT_REG_EDGE_SET);
> + return 0;
> +
> + case IRQ_TYPE_EDGE_FALLING:
> + writel(pos, pint->regs + ADSP_PINT_REG_INVERT_SET);
> + writel(pos, pint->regs + ADSP_PINT_REG_EDGE_SET);
> + return 0;
> +
> + case IRQ_TYPE_EDGE_RISING:
> + writel(pos, pint->regs + ADSP_PINT_REG_INVERT_CLEAR);
> + writel(pos, pint->regs + ADSP_PINT_REG_EDGE_SET);
> + return 0;
> +
> + case IRQ_TYPE_LEVEL_HIGH:
> + writel(pos, pint->regs + ADSP_PINT_REG_INVERT_CLEAR);
> + writel(pos, pint->regs + ADSP_PINT_REG_EDGE_CLEAR);
> + return 0;
> +
> + case IRQ_TYPE_LEVEL_LOW:
> + writel(pos, pint->regs + ADSP_PINT_REG_INVERT_SET);
> + writel(pos, pint->regs + ADSP_PINT_REG_EDGE_CLEAR);
> + return 0;
> +
> + default:
> + return -EINVAL;
> + }
> +
Fix blank line issues everywhere.
> +}
> +
> +static int adsp_pint_probe(struct platform_device *pdev)
> +{
> + struct device *dev = &pdev->dev;
> + struct device_node *np = dev->of_node;
> + struct adsp_pint *pint;
> +
> + pint = devm_kzalloc(dev, sizeof(*pint), GFP_KERNEL);
> + if (!pint)
> + return -ENOMEM;
> +
> + pint->regs = devm_platform_ioremap_resource(pdev, 0);
> + if (IS_ERR(pint->regs))
> + return PTR_ERR(pint->regs);
> +
> + pint->chip.name = "adsp-pint";
> + pint->chip.irq_ack = adsp_pint_irq_ack;
> + pint->chip.irq_mask = adsp_pint_irq_mask;
> + pint->chip.irq_unmask = adsp_pint_irq_unmask;
> + pint->chip.irq_set_type = adsp_pint_irq_set_type;
> + // @todo potentially only SEC supports wake options, not gic
> +
> + // @todo determine if we actually need a raw spinlock
> +
> + pint->domain = irq_domain_add_linear(np, ADSP_PINT_IRQS,
> + &adsp_irq_domain_ops, pint);
> + if (!pint->domain) {
> + dev_err(dev, "Could not create irq domain\n");
> + return -EINVAL;
> + }
> +
> + pint->irq = platform_get_irq(pdev, 0);
> + if (!pint->irq) {
That's a bug, technically. Read the doc. Why -EINVAL is a valid interrupt?
> + dev_err(dev, "Could not find parent interrupt for port\n");
> + return -EINVAL;
> + }
> +
> + irq_set_chained_handler_and_data(pint->irq, adsp_pint_irq_handler, pint);
> + platform_set_drvdata(pdev, pint);
> +
> + return 0;
> +}
> +
> +static void adsp_pint_remove(struct platform_device *pdev)
> +{
> + struct adsp_pint *pint = platform_get_drvdata(pdev);
> +
> + irq_set_chained_handler_and_data(pint->irq, NULL, NULL);
> + irq_domain_remove(pint->domain);
> +}
> +
> +static const struct of_device_id adsp_pint_of_match[] = {
> + { .compatible = "adi,adsp-pint" },
> + { }
> +};
> +MODULE_DEVICE_TABLE(of, adsp_pint_of_match);
> +
> +static struct platform_driver adsp_pint_driver = {
> + .driver = {
> + .name = "adsp-port-pint",
Bindings are always before the users.
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 65+ messages in thread
* Re: [PATCH 11/21] irqchip: Add irqchip for ADI ADSP-SC5xx platform
2024-09-12 18:24 ` [PATCH 11/21] irqchip: Add irqchip for ADI ADSP-SC5xx platform Arturs Artamonovs via B4 Relay
2024-09-13 20:40 ` kernel test robot
2024-09-16 6:56 ` Krzysztof Kozlowski
@ 2024-10-02 10:29 ` Thomas Gleixner
2 siblings, 0 replies; 65+ messages in thread
From: Thomas Gleixner @ 2024-10-02 10:29 UTC (permalink / raw)
To: Arturs Artamonovs via B4 Relay, Catalin Marinas, Will Deacon,
Greg Malysa, Philipp Zabel, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Utsav Agarwal, Michael Turquette, Stephen Boyd,
Linus Walleij, Bartosz Golaszewski, Andi Shyti,
Greg Kroah-Hartman, Jiri Slaby, Arnd Bergmann, Olof Johansson,
soc
Cc: linux-arm-kernel, linux-kernel, devicetree, linux-clk, linux-gpio,
linux-i2c, linux-serial, Arturs Artamonovs, adsp-linux,
Arturs Artamonovs, Nathan Barrett-Morrison
On Thu, Sep 12 2024 at 19:24, Arturs Artamonovs via wrote:
> From: Arturs Artamonovs <arturs.artamonovs@analog.com>
>
> Support seting extra indepdendent interrupt on pin activity.
So the subject says it adds a new interrupt chip. Now the changelog
mumbles about support of something extra.
Please describe your changes properly and explain what this is
about. Also spell check your change log.
> +struct adsp_pint {
> + struct irq_chip chip;
> + void __iomem *regs;
> + struct irq_domain *domain;
> + unsigned int irq;
https://www.kernel.org/doc/html/latest/process/maintainer-tip.html#struct-declarations-and-initializers
And please read and follow the rest of that document too.
> + * This relies on the default configuration of the hardware, which we do not
> + * expose an interface to change.
> + */
> +int adsp_attach_pint_to_gpio(struct adsp_gpio_port *port)
Where is this function declared and where is it used?
> +static void adsp_pint_dispatch_irq(struct irq_desc *desc)
> +{
> + struct irq_chip *chip = irq_desc_get_chip(desc);
> + struct adsp_pint *pint = to_adsp_pint(chip);
> + unsigned int type = irqd_get_trigger_type(&desc->irq_data);
> + u32 pos = BIT(desc->irq_data.hwirq);
> +
> + /* for both edge interrupt, toggle invert bit to catch next edge */
> + if (type == IRQ_TYPE_EDGE_BOTH) {
> + u32 invert = readl(pint->regs + ADSP_PINT_REG_INVERT_SET) & pos;
> +
> + if (invert)
> + writel(pos, pint->regs + ADSP_PINT_REG_INVERT_CLEAR);
> + else
> + writel(pos, pint->regs + ADSP_PINT_REG_INVERT_SET);
What protects pint->regs against concurrent modifications?
> +static void adsp_pint_irq_mask(struct irq_data *d)
> +{
> + struct adsp_pint *pint = irq_data_get_irq_chip_data(d);
> +
> + writel(BIT(d->hwirq), pint->regs + ADSP_PINT_REG_MASK_CLEAR);
Same question.
> +static int adsp_pint_probe(struct platform_device *pdev)
> +{
> + struct device *dev = &pdev->dev;
> + struct device_node *np = dev->of_node;
> + struct adsp_pint *pint;
> +
> + pint = devm_kzalloc(dev, sizeof(*pint), GFP_KERNEL);
> + if (!pint)
> + return -ENOMEM;
> +
> + pint->regs = devm_platform_ioremap_resource(pdev, 0);
> + if (IS_ERR(pint->regs))
> + return PTR_ERR(pint->regs);
> +
> + pint->chip.name = "adsp-pint";
> + pint->chip.irq_ack = adsp_pint_irq_ack;
> + pint->chip.irq_mask = adsp_pint_irq_mask;
> + pint->chip.irq_unmask = adsp_pint_irq_unmask;
> + pint->chip.irq_set_type = adsp_pint_irq_set_type;
> + // @todo potentially only SEC supports wake options, not gic
> +
> + // @todo determine if we actually need a raw spinlock
This should have been determined before posting, no?
> + pint->domain = irq_domain_add_linear(np, ADSP_PINT_IRQS,
> + &adsp_irq_domain_ops, pint);
devm_irq_domain_instantiate()
> + if (!pint->domain) {
> + dev_err(dev, "Could not create irq domain\n");
> + return -EINVAL;
> + }
> +
> + pint->irq = platform_get_irq(pdev, 0);
> + if (!pint->irq) {
> + dev_err(dev, "Could not find parent interrupt for port\n");
> + return -EINVAL;
Then this would not leak the interrupt domain. Also why is this not
checked _before_ instantiating the domain?
> +static int __init adsp_pint_init(void)
> +{
> + return platform_driver_register(&adsp_pint_driver);
> +}
> +
Pointless new line
> +arch_initcall(adsp_pint_init);
> +
> +MODULE_DESCRIPTION("Analog Devices IRQChip driver");
> +MODULE_LICENSE("GPL v2");
> +MODULE_AUTHOR("Greg Malysa <greg.malysa@timesys.com>");
> \ No newline at end of file
This message has a meaning, no?
Thanks,
tglx
^ permalink raw reply [flat|nested] 65+ messages in thread
* [PATCH 12/21] dt-bindings: irqchip: adi,adsp-pint: add binding
2024-09-12 18:24 [PATCH 00/21] Adding support of ADI ARMv8 ADSP-SC598 SoC Arturs Artamonovs via B4 Relay
` (10 preceding siblings ...)
2024-09-12 18:24 ` [PATCH 11/21] irqchip: Add irqchip for ADI ADSP-SC5xx platform Arturs Artamonovs via B4 Relay
@ 2024-09-12 18:24 ` Arturs Artamonovs via B4 Relay
2024-09-16 6:57 ` Krzysztof Kozlowski
2024-09-12 18:24 ` [PATCH 13/21] pinctrl: Add drivers for ADI ADSP-SC5xx platform Arturs Artamonovs via B4 Relay
` (11 subsequent siblings)
23 siblings, 1 reply; 65+ messages in thread
From: Arturs Artamonovs via B4 Relay @ 2024-09-12 18:24 UTC (permalink / raw)
To: Catalin Marinas, Will Deacon, Greg Malysa, Philipp Zabel,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Utsav Agarwal,
Michael Turquette, Stephen Boyd, Linus Walleij,
Bartosz Golaszewski, Thomas Gleixner, Andi Shyti,
Greg Kroah-Hartman, Jiri Slaby, Arnd Bergmann, Olof Johansson,
soc
Cc: linux-arm-kernel, linux-kernel, devicetree, linux-clk, linux-gpio,
linux-i2c, linux-serial, Arturs Artamonovs, adsp-linux,
Arturs Artamonovs, Nathan Barrett-Morrison
From: Arturs Artamonovs <arturs.artamonovs@analog.com>
Signed-off-by: Arturs Artamonovs <Arturs.Artamonovs@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>
---
.../interrupt-controller/adi,adsp-pint.yaml | 51 ++++++++++++++++++++++
1 file changed, 51 insertions(+)
diff --git a/Documentation/devicetree/bindings/interrupt-controller/adi,adsp-pint.yaml b/Documentation/devicetree/bindings/interrupt-controller/adi,adsp-pint.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..b5ecf0cf1d2ceb580f45467ffe1550ae3280d1a3
--- /dev/null
+++ b/Documentation/devicetree/bindings/interrupt-controller/adi,adsp-pint.yaml
@@ -0,0 +1,51 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/interrupt-controller/adi,adsp-pint.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Analog Devices Port Pin Interrupt for SC5XX-family processors
+
+maintainers:
+ - Arturs Artamonovs <arturs.artamonovs@analog.com>
+ - Utsav Agarwal <Utsav.Agarwal@analog.com>
+
+description: |
+ Analog Devices Port Pin Interrupt driver for SC5XX-family processors
+
+properties:
+ compatible:
+ enum:
+ - adi,adsp-pint
+
+ reg:
+ maxItems: 1
+
+ interrupts:
+ maxItems: 1
+
+required:
+ - compatible
+ - reg
+ - interrupts
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/interrupt-controller/arm-gic.h>
+ #include <dt-bindings/interrupt-controller/irq.h>
+ #include <dt-bindings/clock/adi-sc5xx-clock.h>
+
+ pint0: pint@31005000 {
+ compatible = "adi,adsp-pint";
+ reg = <0x31005000 0xFF>;
+ interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ pint1: pint@31005100 {
+ compatible = "adi,adsp-pint";
+ reg = <0x31005100 0xFF>;
+ interrupts = <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>;
+ };
+...
--
2.25.1
^ permalink raw reply related [flat|nested] 65+ messages in thread
* Re: [PATCH 12/21] dt-bindings: irqchip: adi,adsp-pint: add binding
2024-09-12 18:24 ` [PATCH 12/21] dt-bindings: irqchip: adi,adsp-pint: add binding Arturs Artamonovs via B4 Relay
@ 2024-09-16 6:57 ` Krzysztof Kozlowski
0 siblings, 0 replies; 65+ messages in thread
From: Krzysztof Kozlowski @ 2024-09-16 6:57 UTC (permalink / raw)
To: arturs.artamonovs, Catalin Marinas, Will Deacon, Greg Malysa,
Philipp Zabel, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Utsav Agarwal, Michael Turquette, Stephen Boyd, Linus Walleij,
Bartosz Golaszewski, Thomas Gleixner, Andi Shyti,
Greg Kroah-Hartman, Jiri Slaby, Arnd Bergmann, Olof Johansson,
soc
Cc: linux-arm-kernel, linux-kernel, devicetree, linux-clk, linux-gpio,
linux-i2c, linux-serial, adsp-linux, Nathan Barrett-Morrison
On 12/09/2024 20:24, Arturs Artamonovs via B4 Relay wrote:
> From: Arturs Artamonovs <arturs.artamonovs@analog.com>
>
You must always run checkpatch. We cannot take empty commit msgs, for
obvious reasons.
A nit, subject: drop second/last, redundant "bindings". The
"dt-bindings" prefix is already stating that these are bindings.
See also:
https://elixir.bootlin.com/linux/v6.7-rc8/source/Documentation/devicetree/bindings/submitting-patches.rst#L18
Instead describe the hardware.
> Signed-off-by: Arturs Artamonovs <Arturs.Artamonovs@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>
> ---
> .../interrupt-controller/adi,adsp-pint.yaml | 51 ++++++++++++++++++++++
> 1 file changed, 51 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/interrupt-controller/adi,adsp-pint.yaml b/Documentation/devicetree/bindings/interrupt-controller/adi,adsp-pint.yaml
> new file mode 100644
> index 0000000000000000000000000000000000000000..b5ecf0cf1d2ceb580f45467ffe1550ae3280d1a3
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/interrupt-controller/adi,adsp-pint.yaml
> @@ -0,0 +1,51 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/interrupt-controller/adi,adsp-pint.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Analog Devices Port Pin Interrupt for SC5XX-family processors
> +
> +maintainers:
> + - Arturs Artamonovs <arturs.artamonovs@analog.com>
> + - Utsav Agarwal <Utsav.Agarwal@analog.com>
> +
> +description: |
> + Analog Devices Port Pin Interrupt driver for SC5XX-family processors
> +
> +properties:
> + compatible:
> + enum:
> + - adi,adsp-pint
All previous comments apply.
> +
> + reg:
> + maxItems: 1
> +
> + interrupts:
> + maxItems: 1
> +
> +required:
> + - compatible
> + - reg
> + - interrupts
> +
> +additionalProperties: false
> +
> +examples:
> + - |
> + #include <dt-bindings/interrupt-controller/arm-gic.h>
> + #include <dt-bindings/interrupt-controller/irq.h>
> + #include <dt-bindings/clock/adi-sc5xx-clock.h>
Where do you user it?
> +
> + pint0: pint@31005000 {
> + compatible = "adi,adsp-pint";
> + reg = <0x31005000 0xFF>;
> + interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>;
> + };
> +
All previous comments apply.
> + pint1: pint@31005100 {
> + compatible = "adi,adsp-pint";
> + reg = <0x31005100 0xFF>;
> + interrupts = <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>;
> + };
> +...
>
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 65+ messages in thread
* [PATCH 13/21] pinctrl: Add drivers for ADI ADSP-SC5xx platform
2024-09-12 18:24 [PATCH 00/21] Adding support of ADI ARMv8 ADSP-SC598 SoC Arturs Artamonovs via B4 Relay
` (11 preceding siblings ...)
2024-09-12 18:24 ` [PATCH 12/21] dt-bindings: irqchip: adi,adsp-pint: add binding Arturs Artamonovs via B4 Relay
@ 2024-09-12 18:24 ` Arturs Artamonovs via B4 Relay
2024-09-14 2:55 ` kernel test robot
2024-09-12 18:24 ` [PATCH 14/21] dt-bindings: pinctrl: adi,adsp-pinctrl: add bindings Arturs Artamonovs via B4 Relay
` (10 subsequent siblings)
23 siblings, 1 reply; 65+ messages in thread
From: Arturs Artamonovs via B4 Relay @ 2024-09-12 18:24 UTC (permalink / raw)
To: Catalin Marinas, Will Deacon, Greg Malysa, Philipp Zabel,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Utsav Agarwal,
Michael Turquette, Stephen Boyd, Linus Walleij,
Bartosz Golaszewski, Thomas Gleixner, Andi Shyti,
Greg Kroah-Hartman, Jiri Slaby, Arnd Bergmann, Olof Johansson,
soc
Cc: linux-arm-kernel, linux-kernel, devicetree, linux-clk, linux-gpio,
linux-i2c, linux-serial, Arturs Artamonovs, adsp-linux,
Arturs Artamonovs, Nathan Barrett-Morrison
From: Arturs Artamonovs <arturs.artamonovs@analog.com>
Add ADSP-SC5xx pinctrler:
- Support switching GPIO pin functions.
Signed-off-by: Arturs Artamonovs <Arturs.Artamonovs@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>
---
drivers/pinctrl/Kconfig | 12 +
drivers/pinctrl/Makefile | 1 +
drivers/pinctrl/pinctrl-adsp.c | 919 +++++++++++++++++++++++++++++++++++++++++
3 files changed, 932 insertions(+)
diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
index 7e4f93a3bc7ac9bcafc92ddb795569d7cca6474d..ffc0946c5b416c29803e195016867aee8f09afe1 100644
--- a/drivers/pinctrl/Kconfig
+++ b/drivers/pinctrl/Kconfig
@@ -31,6 +31,18 @@ config DEBUG_PINCTRL
help
Say Y here to add some extra checks and diagnostics to PINCTRL calls.
+config PINCTRL_ADSP
+ bool "ADSP-SC5XX pinctrl driver"
+ depends on ARCH_SC59X_64
+ depends on OF
+ select PINMUX
+ select GPIOLIB
+ select GENERIC_PINCONF
+ help
+ Say Y here to enable the ADSP-SC5XX pinctrl driver. This is required for
+ correct peripheral functionality on the SoC.
+
+
config PINCTRL_AMD
bool "AMD GPIO pin control"
depends on HAS_IOMEM
diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile
index cc809669405ab6c6905fe0b2380f91b211a2d470..6b340bf0ee8c0267cbbdee3d14db605a340433c6 100644
--- a/drivers/pinctrl/Makefile
+++ b/drivers/pinctrl/Makefile
@@ -9,6 +9,7 @@ obj-$(CONFIG_PINCONF) += pinconf.o
obj-$(CONFIG_GENERIC_PINCONF) += pinconf-generic.o
obj-$(CONFIG_OF) += devicetree.o
+obj-$(CONFIG_PINCTRL_ADSP) += pinctrl-adsp.o
obj-$(CONFIG_PINCTRL_AMD) += pinctrl-amd.o
obj-$(CONFIG_PINCTRL_APPLE_GPIO) += pinctrl-apple-gpio.o
obj-$(CONFIG_PINCTRL_ARTPEC6) += pinctrl-artpec6.o
diff --git a/drivers/pinctrl/pinctrl-adsp.c b/drivers/pinctrl/pinctrl-adsp.c
new file mode 100644
index 0000000000000000000000000000000000000000..ce86e579e5601203a446c09b5b5f7f60aba6d02a
--- /dev/null
+++ b/drivers/pinctrl/pinctrl-adsp.c
@@ -0,0 +1,919 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Analog Devices ADSP family pinctrl driver.
+ *
+ * Copyright 2022-2024 - Analog Devices Inc.
+ */
+
+#include <linux/of.h>
+#include <linux/pinctrl/pinconf.h>
+#include <linux/pinctrl/pinmux.h>
+#include <linux/platform_device.h>
+#include <linux/printk.h>
+#include <linux/soc/adi/adsp-gpio-port.h>
+
+#include "core.h"
+#include "pinconf.h"
+#include "pinctrl-utils.h"
+
+/* Convert from pinmux constants in device tree to actual settings */
+#define ADSP_PINMUX_PIN(p) ((p & 0xffffff00) >> 8)
+#define ADSP_PINMUX_FUNC(p) (p & 0xff)
+
+/* Details of the PORT_MUX register */
+#define ADSP_PORT_PORT_MUX_BITS 2
+#define ADSP_PORT_PORT_MUX_MASK GENMASK(1, 0)
+
+/* Number of pin alternate functions, see pin_functions array */
+#define ADSP_NUMBER_OF_PIN_FUNCTIONS ARRAY_SIZE(pin_functions)
+
+/* Information for drive strength registers */
+#define ADSP_PADS_DS_BITS 3
+#define ADSP_PADS_DS_PINS_PER_REG 8
+#define ADSP_PADS_DS_HIGH 2
+#define ADSP_PADS_DS_LOW 1
+
+/* Information for pull up/pull down enable registers */
+#define ADSP_PADS_PUD_PINS_PER_REG 16
+
+#define ADSP_PADS_REG_PCFG0 0x04
+#define ADSP_PADS_REG_PCFG1 0x08
+/* Convert from pin number (e.g. 0-143) to drive strength register offset */
+#define ADSP_PADS_PORTx_DS(p) (0x0c + 0x04*(p/ADSP_PADS_DS_PINS_PER_REG))
+#define ADSP_PADS_NONPORTS_DS 0x50
+/* Convert from pin number to pull up enable register offset */
+#define ADSP_PADS_PORTx_PUE(p) (0x98 + 0x04*(p/ADSP_PADS_PUD_PINS_PER_REG))
+/* Convert from pin number to pull down enable register offset */
+#define ADSP_PADS_PORTx_PDE(p) (0xc4 + 0x04*(p/ADSP_PADS_PUD_PINS_PER_REG))
+
+/* Non GPIO PORT drive strength settings */
+#define ADSP_NONPORTS_DS_CKOUT 0
+#define ADSP_NONPORTS_DS_RESOUTB 1
+#define ADSP_NONPORTS_DS_FAULTB 2
+#define ADSP_NONPORTS_DS_LP1CK 3
+#define ADSP_NONPORTS_DS_LP0CK 4
+#define ADSP_NONPORTS_DS_OSPI 5
+
+/* DAI pad configuration offsets */
+#define ADSP_PADS_REG_DAI0_0_DS 0x78
+#define ADSP_PADS_REG_DAI0_1_DS 0x7c
+#define ADSP_PADS_REG_DAI1_0_DS 0x80
+#define ADSP_PADS_REG_DAI1_1_DS 0x84
+
+#define ADSP_PADS_REG_DAI0_PUE 0xbc
+#define ADSP_PADS_REG_DAI1_PUE 0xc0
+#define ADSP_PADS_REG_DAI0_PDE 0xfc
+#define ADSP_PADS_REG_DAI1_PDE 0x100
+
+/*
+ * Represents a function setting for pins, controls the mux modes essentially
+ */
+struct adsp_pin_function {
+ const char *name;
+ /* 0 for gpio, 1-4 for alt functions 0-3 */
+ uint8_t mode;
+};
+
+/*
+ * Available pin function settings in the pin mux for GPIO-associated pins
+ */
+static const struct adsp_pin_function pin_functions[] = {
+ {
+ .name = "gpio",
+ .mode = 0,
+ }, {
+ .name = "alt0",
+ .mode = 1,
+ }, {
+ .name = "alt1",
+ .mode = 2,
+ }, {
+ .name = "alt2",
+ .mode = 3,
+ }, {
+ .name = "alt3",
+ .mode = 4,
+ }
+};
+
+/*
+ * One pinctrl instance per chip, unifies the interface to the port mux and pad
+ * conf registers in the PORT instances
+ * @todo pads registers should be routed through system configuration abstraction
+ * to remove the need for feature testing/listing "missing" registers here
+ */
+struct adsp_pinctrl {
+ struct device *dev;
+ struct pinctrl_dev *pin_dev;
+ void __iomem *regs;
+ const char **group_names;
+ unsigned int *pins;
+ spinlock_t lock;
+ size_t num_ports;
+ uint32_t *pin_counts;
+ uint32_t total_pins;
+
+ /* Are the drive strength registers missing on this part? */
+ bool ds_missing;
+
+ /* Are the pull up/down enable registers missing on this part? */
+ bool pude_missing;
+};
+
+/*
+ * Custom pinconf properties
+ */
+#define ADSP_PIN_CONFIG_TRU_TOGGLE (PIN_CONFIG_END+1)
+
+static const struct pinconf_generic_params adsp_custom_bindings[] = {
+ /* Configure this pin as a toggle pin which flip each time a trigger event
+ * is received by the pin controller from the TRU
+ */
+ {"adi,tru-toggle", ADSP_PIN_CONFIG_TRU_TOGGLE, 0}
+};
+
+static const struct pin_config_item adsp_conf_items[] = {
+ PCONFDUMP(ADSP_PIN_CONFIG_TRU_TOGGLE, "tru-toggle", NULL, false),
+};
+
+/* does not need lock */
+static void adsp_set_pin_gpio(struct adsp_gpio_port *port, unsigned int offset, bool gpio)
+{
+ if (gpio)
+ __adsp_gpio_writew(port, BIT(offset), ADSP_PORT_REG_FER_CLEAR);
+ else
+ __adsp_gpio_writew(port, BIT(offset), ADSP_PORT_REG_FER_SET);
+}
+
+/*
+ * Configure a pin either for gpio or an alternate function
+ */
+static void adsp_portmux_setup(struct adsp_gpio_port *port, unsigned int offset,
+ const struct adsp_pin_function *func)
+{
+ if (func->mode == 0) {
+ adsp_set_pin_gpio(port, offset, true);
+ } else {
+ unsigned long flags;
+ u32 val;
+ u32 f = (func->mode - 1) & ADSP_PORT_PORT_MUX_MASK;
+
+ spin_lock_irqsave(&port->lock, flags);
+
+ val = __adsp_gpio_readl(port, ADSP_PORT_REG_PORT_MUX);
+ val &= ~(ADSP_PORT_PORT_MUX_MASK << (ADSP_PORT_PORT_MUX_BITS * offset));
+ val |= f << (ADSP_PORT_PORT_MUX_BITS * offset);
+ __adsp_gpio_writel(port, val, ADSP_PORT_REG_PORT_MUX);
+
+ spin_unlock_irqrestore(&port->lock, flags);
+
+ adsp_set_pin_gpio(port, offset, false);
+ }
+}
+
+/* pin control operations */
+static int adsp_pinctrl_get_groups_count(struct pinctrl_dev *pctldev)
+{
+ struct adsp_pinctrl *adsp_pinctrl = pinctrl_dev_get_drvdata(pctldev);
+
+ return adsp_pinctrl->total_pins;
+}
+
+static const char *adsp_pinctrl_get_group_name(struct pinctrl_dev *pctldev,
+ unsigned int selector)
+{
+ struct adsp_pinctrl *adsp_pinctrl = pinctrl_dev_get_drvdata(pctldev);
+
+ return adsp_pinctrl->group_names[selector];
+}
+
+static int adsp_pinctrl_get_group_pins(struct pinctrl_dev *pctldev, unsigned int selector,
+ const unsigned int **pins, unsigned int *num_pins)
+{
+ struct adsp_pinctrl *adsp_pinctrl = pinctrl_dev_get_drvdata(pctldev);
+ *pins = &adsp_pinctrl->pins[selector];
+ *num_pins = 1;
+ return 0;
+}
+
+static int adsp_pinctrl_dt_subnode_to_map(struct pinctrl_dev *pctldev,
+ struct device_node *np, struct pinctrl_map **map, unsigned int *reserved_maps,
+ unsigned int *num_maps)
+{
+ struct adsp_pinctrl *adsp_pinctrl = pinctrl_dev_get_drvdata(pctldev);
+ //struct property *prop;
+ const char *group;
+ unsigned long *configs;
+ unsigned int num_configs, num_pins;
+ unsigned int reserve = 0;
+ //uint32_t pinmux;
+ //const __be32 *p;
+ u32 array[2];
+ int sz, i;
+ int ret;
+
+ num_pins = of_property_count_u32_elems(np, "pinmux");
+ if (num_pins <= 0) {
+ dev_err(adsp_pinctrl->dev, "Must have at least one `pinmux` entry in %pOFn.\n",
+ np);
+ return -EINVAL;
+ }
+
+ ret = pinconf_generic_parse_dt_config(np, pctldev, &configs, &num_configs);
+ if (ret)
+ return ret;
+
+ /* One configuration for the whole group, potentially */
+ reserve = num_pins;
+ if (num_configs)
+ reserve = reserve * 2;
+
+ ret = pinctrl_utils_reserve_map(pctldev, map, reserved_maps, num_maps, reserve);
+ if (ret)
+ goto exit;
+
+ sz = of_property_read_variable_u32_array(np, "pinmux", array, 2, 2);
+ sz = (sz == -EINVAL) ? 0 : sz; /* Missing property is OK */
+ if (sz < 0)
+ return dev_err_probe(adsp_pinctrl->dev, sz, "invalid pinmux\n");
+
+
+ for (i = 0; i < sz; i += 2) {
+ u32 pin = array[i];
+ u32 func = array[i + 1];
+
+ if (func >= ADSP_NUMBER_OF_PIN_FUNCTIONS) {
+ dev_err(adsp_pinctrl->dev,
+ "Function number %d is not available for pin %d in %pOFn.n\n",
+ func, pin, np);
+ goto exit;
+ }
+
+ group = adsp_pinctrl->group_names[pin];
+ ret = pinctrl_utils_add_map_mux(pctldev, map, reserved_maps, num_maps,
+ group, pin_functions[func].name);
+ if (ret)
+ goto exit;
+
+ if (num_configs) {
+ ret = pinctrl_utils_add_map_configs(pctldev, map, reserved_maps, num_maps,
+ group, configs, num_configs, PIN_MAP_TYPE_CONFIGS_GROUP);
+ if (ret)
+ goto exit;
+ }
+ }
+
+ ret = 0;
+exit:
+ kfree(configs);
+ return ret;
+}
+
+/**
+ * Handle device tree structures like:
+ *
+ * pinctrl_uart0_hwflow: uart0_hwflow_pins {
+ * pins_rxtx_ {
+ * pinmux = <1>, <2>;
+ * some-padconf-flag;
+ * };
+ * pins_hwflow {
+ * pinmux = <3>, <4>;
+ * some-other-padconf-flag;
+ * };
+ * };
+ *
+ * where &pinctrl_uart0_hwflow is passed as an entry in pinctrl-0 on uart driver and
+ * enables all sub-pins at once
+ */
+static int adsp_pinctrl_dt_node_to_map(struct pinctrl_dev *pctldev,
+ struct device_node *np, struct pinctrl_map **map, unsigned int *num_maps)
+{
+ unsigned int reserved_maps;
+ struct device_node *child_np;
+ int ret;
+
+ reserved_maps = 0;
+ *map = NULL;
+ *num_maps = 0;
+
+ for_each_child_of_node(np, child_np) {
+ ret = adsp_pinctrl_dt_subnode_to_map(pctldev, child_np, map,
+ &reserved_maps, num_maps);
+ if (ret < 0)
+ goto exit;
+ }
+ return 0;
+
+exit:
+ pinctrl_utils_free_map(pctldev, *map, *num_maps);
+ return ret;
+}
+
+static const struct pinctrl_ops adsp_pctlops = {
+ .get_groups_count = adsp_pinctrl_get_groups_count,
+ .get_group_name = adsp_pinctrl_get_group_name,
+ .get_group_pins = adsp_pinctrl_get_group_pins,
+ .dt_node_to_map = adsp_pinctrl_dt_node_to_map,
+ .dt_free_map = pinconf_generic_dt_free_map,
+};
+
+/* pin mux operations */
+static int adsp_pinmux_get_functions_count(struct pinctrl_dev *pctldev)
+{
+ return ADSP_NUMBER_OF_PIN_FUNCTIONS;
+}
+
+static const char *adsp_pinmux_get_function_name(struct pinctrl_dev *pctldev,
+ unsigned int selector)
+{
+ return pin_functions[selector].name;
+}
+
+static int adsp_pinmux_get_function_groups(struct pinctrl_dev *pctldev,
+ unsigned int selector, const char * const **groups, unsigned * const num_groups)
+{
+ struct adsp_pinctrl *adsp_pinctrl = pinctrl_dev_get_drvdata(pctldev);
+
+ *groups = adsp_pinctrl->group_names;
+ *num_groups = adsp_pinctrl->total_pins;
+ return 0;
+}
+
+/* Each group is exactly 1 pin and group id == pin id */
+static int adsp_pinmux_set_mux(struct pinctrl_dev *pctldev, unsigned int func,
+ unsigned int group)
+{
+ struct adsp_gpio_port *port;
+ struct pinctrl_gpio_range *range;
+ u32 offset;
+
+ range = pinctrl_find_gpio_range_from_pin(pctldev, group);
+ if (!range || !range->gc)
+ return -EPROBE_DEFER;
+
+ offset = group - range->pin_base;
+
+ port = to_adsp_gpio_port(range->gc);
+ adsp_portmux_setup(port, offset, &pin_functions[func]);
+
+ return 0;
+}
+
+static int adsp_pinmux_request_gpio(struct pinctrl_dev *pctldev,
+ struct pinctrl_gpio_range *range, unsigned int pin)
+{
+ struct adsp_gpio_port *port = to_adsp_gpio_port(range->gc);
+ u32 offset = pin - range->pin_base;
+
+ adsp_set_pin_gpio(port, offset, true);
+ return 0;
+}
+
+static void adsp_pinmux_release_gpio(struct pinctrl_dev *pctldev,
+ struct pinctrl_gpio_range *range, unsigned int pin)
+{
+ struct adsp_gpio_port *port = to_adsp_gpio_port(range->gc);
+ u32 offset = pin - range->pin_base;
+
+ adsp_set_pin_gpio(port, offset, false);
+}
+
+static const struct pinmux_ops adsp_pmxops = {
+ .get_functions_count = adsp_pinmux_get_functions_count,
+ .get_function_name = adsp_pinmux_get_function_name,
+ .get_function_groups = adsp_pinmux_get_function_groups,
+ .set_mux = adsp_pinmux_set_mux,
+ .gpio_request_enable = adsp_pinmux_request_gpio,
+ .gpio_disable_free = adsp_pinmux_release_gpio,
+};
+
+/* pin configuration operations */
+static bool __adsp_pinconf_is_pue(struct adsp_pinctrl *p, unsigned int pin)
+{
+ u32 offset = ADSP_PADS_PORTx_PUE(pin);
+ u32 val, bit;
+
+ if (p->pude_missing)
+ return 0;
+
+ val = readl(p->regs + offset);
+ bit = BIT(pin & (ADSP_PADS_PUD_PINS_PER_REG-1));
+ return !!(val & bit);
+}
+
+static bool __adsp_pinconf_is_pde(struct adsp_pinctrl *p, unsigned int pin)
+{
+ u32 offset = ADSP_PADS_PORTx_PDE(pin);
+ u32 val, bit;
+
+ if (p->pude_missing)
+ return 0;
+
+ val = readl(p->regs + offset);
+ bit = BIT(pin & (ADSP_PADS_PUD_PINS_PER_REG-1));
+ return !!(val & bit);
+}
+
+static u32 __adsp_pinconf_get_ds(struct adsp_pinctrl *p, unsigned int pin)
+{
+ u32 offset = ADSP_PADS_PORTx_DS(pin);
+ u32 val, shift, mask;
+
+ if (p->ds_missing)
+ return 0;
+
+ val = readl(p->regs + offset);
+ shift = (pin & (ADSP_PADS_DS_PINS_PER_REG-1)) * ADSP_PADS_DS_BITS;
+ mask = GENMASK(ADSP_PADS_DS_BITS-1, 0) << shift;
+ val = val & mask;
+
+ if (val == ADSP_PADS_DS_HIGH)
+ return 1;
+ return 0;
+}
+
+/* seems we return -EINVAL for disabled static option, -ENOTSUPP for not supported,
+ * and otherwise the argument is included in config
+ */
+static int adsp_pinconf_get(struct pinctrl_dev *pctldev, unsigned int pin,
+ unsigned long *config)
+{
+ struct adsp_pinctrl *adsp_pinctrl = pinctrl_dev_get_drvdata(pctldev);
+ struct pinctrl_gpio_range *range;
+ struct adsp_gpio_port *port;
+ u32 offset, val;
+ u32 param = pinconf_to_config_param(*config);
+ u32 arg = 0;
+
+ switch (param) {
+ case PIN_CONFIG_BIAS_DISABLE:
+ if (__adsp_pinconf_is_pue(adsp_pinctrl, pin) ||
+ __adsp_pinconf_is_pde(adsp_pinctrl, pin))
+ return -EINVAL;
+ break;
+ case PIN_CONFIG_BIAS_PULL_DOWN:
+ if (!__adsp_pinconf_is_pde(adsp_pinctrl, pin))
+ return -EINVAL;
+ break;
+ case PIN_CONFIG_BIAS_PULL_UP:
+ if (!__adsp_pinconf_is_pue(adsp_pinctrl, pin))
+ return -EINVAL;
+ break;
+ case PIN_CONFIG_DRIVE_STRENGTH:
+ arg = __adsp_pinconf_get_ds(adsp_pinctrl, pin);
+ break;
+ case PIN_CONFIG_DRIVE_OPEN_DRAIN:
+ range = pinctrl_find_gpio_range_from_pin_nolock(pctldev, pin);
+ offset = pin - range->pin_base;
+ port = to_adsp_gpio_port(range->gc);
+
+ if (!(port->open_drain & BIT(offset)))
+ return -EINVAL;
+ break;
+ case PIN_CONFIG_DRIVE_PUSH_PULL:
+ range = pinctrl_find_gpio_range_from_pin_nolock(pctldev, pin);
+ offset = pin - range->pin_base;
+ port = to_adsp_gpio_port(range->gc);
+
+ if (port->open_drain & BIT(offset))
+ return -EINVAL;
+ break;
+ case ADSP_PIN_CONFIG_TRU_TOGGLE:
+ range = pinctrl_find_gpio_range_from_pin_nolock(pctldev, pin);
+ offset = pin - range->pin_base;
+ port = to_adsp_gpio_port(range->gc);
+
+ val = __adsp_gpio_readl(port, ADSP_PORT_REG_TRIG_TGL);
+ if (!(val & BIT(offset)))
+ return -EINVAL;
+ break;
+ default:
+ return -EOPNOTSUPP;
+ }
+
+ *config = pinconf_to_config_packed(param, arg);
+
+ return 0;
+}
+
+static void __adsp_pinconf_pue(struct adsp_pinctrl *p, unsigned int pin, bool state)
+{
+ u32 offset = ADSP_PADS_PORTx_PUE(pin);
+ u32 val, bit;
+
+ if (p->pude_missing) {
+ dev_warn(p->dev,
+ "Pull Up Enable is not supported by this PADS HW (tried to set PUE for pin %d)\n",
+ pin);
+ return;
+ }
+
+ val = readl(p->regs + offset);
+ bit = BIT(pin & (ADSP_PADS_PUD_PINS_PER_REG-1));
+
+ if (state)
+ writel(val | bit, p->regs + offset);
+ else
+ writel(val & ~bit, p->regs + offset);
+}
+
+static void __adsp_pinconf_pde(struct adsp_pinctrl *p, unsigned int pin, bool state)
+{
+ u32 offset = ADSP_PADS_PORTx_PDE(pin);
+ u32 val, bit;
+
+ if (p->pude_missing) {
+ dev_warn(p->dev,
+ "Pull Down Enable is not supported by this PADS HW (tried to set PDE for pin %d)\n",
+ pin);
+ return;
+ }
+
+ val = readl(p->regs + offset);
+ bit = BIT(pin & (ADSP_PADS_PUD_PINS_PER_REG-1));
+
+ if (state)
+ writel(val | bit, p->regs + offset);
+ else
+ writel(val & ~bit, p->regs + offset);
+}
+
+static void __adsp_pinconf_ds(struct adsp_pinctrl *p, unsigned int pin, bool high)
+{
+ u32 offset = ADSP_PADS_PORTx_DS(pin);
+ u32 val, shift, mask;
+
+ if (p->ds_missing) {
+ dev_warn(p->dev,
+ "Drive strength is not supported by this PADS HW (tried to set drive strength for pin %d)\n",
+ pin);
+ return;
+ }
+
+ val = readl(p->regs + offset);
+ shift = (pin & (ADSP_PADS_DS_PINS_PER_REG-1)) * ADSP_PADS_DS_BITS;
+ mask = GENMASK(ADSP_PADS_DS_BITS-1, 0) << shift;
+ val = val & ~mask;
+
+ if (high)
+ writel(val | (ADSP_PADS_DS_HIGH << shift), p->regs + offset);
+ else
+ writel(val | (ADSP_PADS_DS_LOW << shift), p->regs + offset);
+}
+
+static int adsp_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
+ unsigned long *config, unsigned int num_configs)
+{
+ struct adsp_pinctrl *adsp_pinctrl = pinctrl_dev_get_drvdata(pctldev);
+ struct pinctrl_gpio_range *range;
+ struct adsp_gpio_port *port;
+ u32 param, arg, val;
+ u32 offset;
+ int cfg;
+ int ret = 0;
+ unsigned long flags;
+
+ spin_lock_irqsave(&adsp_pinctrl->lock, flags);
+
+ for (cfg = 0; cfg < num_configs; ++cfg) {
+ param = pinconf_to_config_param(config[cfg]);
+ arg = pinconf_to_config_argument(config[cfg]);
+
+ switch (param) {
+ case PIN_CONFIG_BIAS_DISABLE:
+ __adsp_pinconf_pue(adsp_pinctrl, pin, false);
+ __adsp_pinconf_pde(adsp_pinctrl, pin, false);
+ break;
+ case PIN_CONFIG_BIAS_PULL_DOWN:
+ __adsp_pinconf_pde(adsp_pinctrl, pin, !!arg);
+ break;
+ case PIN_CONFIG_BIAS_PULL_UP:
+ __adsp_pinconf_pue(adsp_pinctrl, pin, !!arg);
+ break;
+ case PIN_CONFIG_DRIVE_STRENGTH:
+ /* This only supports high/low-speed drive strength (see HRM)
+ * so assume any positive value means we would like high-speed strength
+ */
+ __adsp_pinconf_ds(adsp_pinctrl, pin, !!arg);
+ break;
+ case PIN_CONFIG_DRIVE_OPEN_DRAIN:
+ range = pinctrl_find_gpio_range_from_pin(pctldev, pin);
+ offset = pin - range->pin_base;
+ port = to_adsp_gpio_port(range->gc);
+
+ spin_lock(&port->lock);
+ val = __adsp_gpio_readw(port, ADSP_PORT_REG_DATA);
+ val &= BIT(offset);
+
+ if (val) {
+ /* open drain with value of 1 => configure as input */
+ __adsp_gpio_writew(port, BIT(offset), ADSP_PORT_REG_DIR_CLEAR);
+ __adsp_gpio_writew(port, BIT(offset), ADSP_PORT_REG_INEN_SET);
+ } else {
+ /* open drain with value of 0 => configure as output, drive 0 */
+ __adsp_gpio_writew(port, BIT(offset), ADSP_PORT_REG_INEN_CLEAR);
+ __adsp_gpio_writew(port, BIT(offset), ADSP_PORT_REG_DATA_CLEAR);
+ __adsp_gpio_writew(port, BIT(offset), ADSP_PORT_REG_DIR_SET);
+ }
+
+ port->open_drain |= BIT(offset);
+ spin_unlock(&port->lock);
+ break;
+ case PIN_CONFIG_DRIVE_PUSH_PULL:
+ range = pinctrl_find_gpio_range_from_pin(pctldev, pin);
+ offset = pin - range->pin_base;
+ port = to_adsp_gpio_port(range->gc);
+
+ spin_lock(&port->lock);
+
+ /*
+ * by default make the pin an input when exiting open drain mode;
+ * user can correct later with GPIO in/out configuration
+ */
+ if (port->open_drain & BIT(offset)) {
+ port->open_drain &= ~BIT(offset);
+ __adsp_gpio_writew(port, BIT(offset), ADSP_PORT_REG_DIR_CLEAR);
+ __adsp_gpio_writew(port, BIT(offset), ADSP_PORT_REG_INEN_SET);
+ }
+
+ spin_unlock(&port->lock);
+ break;
+ case ADSP_PIN_CONFIG_TRU_TOGGLE:
+ range = pinctrl_find_gpio_range_from_pin(pctldev, pin);
+ offset = pin - range->pin_base;
+ port = to_adsp_gpio_port(range->gc);
+
+ spin_lock(&port->lock);
+ val = __adsp_gpio_readl(port, ADSP_PORT_REG_TRIG_TGL);
+ val |= BIT(offset);
+ __adsp_gpio_writel(port, val, ADSP_PORT_REG_TRIG_TGL);
+ spin_unlock(&port->lock);
+ break;
+ default:
+ ret = -EOPNOTSUPP;
+ goto end;
+ }
+ }
+
+end:
+ spin_unlock_irqrestore(&adsp_pinctrl->lock, flags);
+ return ret;
+}
+
+/* Config for all pins must match or we have an error regarding group structure */
+static int adsp_pinconf_group_get(struct pinctrl_dev *pctldev, unsigned int group,
+ unsigned long *config)
+{
+ const unsigned int *pins;
+ unsigned int npins, i;
+ unsigned long first;
+ int ret;
+
+ ret = adsp_pinctrl_get_group_pins(pctldev, group, &pins, &npins);
+ if (ret)
+ return ret;
+
+ for (i = 0; i < npins; ++i) {
+ ret = adsp_pinconf_get(pctldev, pins[i], config);
+ if (ret)
+ return ret;
+
+ if (i == 0)
+ first = *config;
+
+ if (first != *config)
+ return -EOPNOTSUPP;
+ }
+
+ return 0;
+}
+
+static int adsp_pinconf_group_set(struct pinctrl_dev *pctldev, unsigned int group,
+ unsigned long *configs, unsigned int num_configs)
+{
+ const unsigned int *pins;
+ unsigned int npins, i;
+ int ret;
+
+ ret = adsp_pinctrl_get_group_pins(pctldev, group, &pins, &npins);
+ if (ret)
+ return ret;
+
+ for (i = 0; i < npins; ++i) {
+ ret = adsp_pinconf_set(pctldev, pins[i], configs, num_configs);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
+static const struct pinconf_ops adsp_confops = {
+ .is_generic = true,
+ .pin_config_get = adsp_pinconf_get,
+ .pin_config_set = adsp_pinconf_set,
+ .pin_config_group_get = adsp_pinconf_group_get,
+ .pin_config_group_set = adsp_pinconf_group_set,
+#ifdef CONFIG_DEBUG_FS
+ .pin_config_config_dbg_show = pinconf_generic_dump_config,
+#endif
+};
+
+/*
+ * We want to make one group per pin so that we can refer to the pins by group
+ * later on when mux assignments are made
+ */
+static int adsp_pinctrl_init_groups(struct adsp_pinctrl *adsp_pinctrl,
+ struct pinctrl_desc *desc)
+{
+ struct device *dev = adsp_pinctrl->dev;
+ struct pinctrl_pin_desc *all_pins;
+ size_t port, pin;
+ unsigned int i, pin_total;
+ int num_ports;
+ int ret;
+
+ num_ports = of_property_count_u32_elems(dev->of_node, "adi,port-sizes");
+
+ if (num_ports < 0)
+ return num_ports;
+
+ if (num_ports == 0) {
+ dev_err(dev, "pinctrl missing `adi,port-sizes` port size definition\n");
+ return -ENOENT;
+ }
+
+ adsp_pinctrl->num_ports = num_ports;
+
+ adsp_pinctrl->pin_counts = devm_kcalloc(dev, sizeof(*adsp_pinctrl->pin_counts),
+ num_ports, GFP_KERNEL);
+ if (!adsp_pinctrl->pin_counts)
+ return -ENOMEM;
+
+ ret = of_property_read_u32_array(dev->of_node, "adi,port-sizes",
+ adsp_pinctrl->pin_counts, num_ports);
+ if (ret)
+ return ret;
+
+ pin_total = 0;
+
+ for (i = 0; i < num_ports; ++i)
+ pin_total += adsp_pinctrl->pin_counts[i];
+
+ adsp_pinctrl->total_pins = pin_total;
+
+ all_pins = devm_kcalloc(dev, sizeof(*all_pins), adsp_pinctrl->total_pins,
+ GFP_KERNEL);
+
+ adsp_pinctrl->pins = devm_kcalloc(dev, sizeof(adsp_pinctrl->pins),
+ adsp_pinctrl->total_pins, GFP_KERNEL);
+ if (!adsp_pinctrl->pins)
+ return -ENOMEM;
+
+ adsp_pinctrl->group_names = devm_kcalloc(dev, sizeof(*adsp_pinctrl->group_names),
+ adsp_pinctrl->total_pins, GFP_KERNEL);
+ if (!adsp_pinctrl->group_names)
+ return -ENOMEM;
+
+ i = 0;
+ for (port = 0; port < adsp_pinctrl->num_ports; ++port) {
+ for (pin = 0; pin < adsp_pinctrl->pin_counts[port]; ++pin) {
+ adsp_pinctrl->group_names[i] = devm_kasprintf(dev, GFP_KERNEL,
+ "p%c%zu", (char) ('A' + port), pin);
+ adsp_pinctrl->pins[i] = i;
+
+ all_pins[i].name = adsp_pinctrl->group_names[i];
+ all_pins[i].number = i;
+ i += 1;
+ }
+ }
+
+ desc->pins = all_pins;
+ desc->npins = adsp_pinctrl->total_pins;
+
+ return 0;
+}
+
+static void adsp_set_nongpio_ds(struct adsp_pinctrl *p, int type, bool high)
+{
+ u32 val = readl(p->regs + ADSP_PADS_NONPORTS_DS);
+ u32 shift = ADSP_PADS_DS_BITS * type;
+ u32 mask = GENMASK(ADSP_PADS_DS_BITS-1, 0) << shift;
+
+ val = val & ~mask;
+
+ if (high)
+ writel(val | (ADSP_PADS_DS_HIGH << shift), p->regs + ADSP_PADS_NONPORTS_DS);
+ else
+ writel(val | (ADSP_PADS_DS_LOW << shift), p->regs + ADSP_PADS_NONPORTS_DS);
+}
+
+static int adsp_pinctrl_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct device_node *np = dev->of_node;
+ struct adsp_pinctrl *adsp_pinctrl;
+ struct pinctrl_desc *pnctrl_desc;
+ struct resource *res;
+ u32 val;
+ int ret;
+
+ adsp_pinctrl = devm_kzalloc(dev, sizeof(*adsp_pinctrl), GFP_KERNEL);
+ if (!adsp_pinctrl)
+ return -ENOMEM;
+
+ adsp_pinctrl->dev = dev;
+ pnctrl_desc = devm_kzalloc(dev, sizeof(*pnctrl_desc), GFP_KERNEL);
+ if (!pnctrl_desc)
+ return -ENOMEM;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ adsp_pinctrl->regs = devm_ioremap_resource(dev, res);
+ if (IS_ERR(adsp_pinctrl->regs))
+ return PTR_ERR(adsp_pinctrl->regs);
+
+ /* Different features are available in different hw revisions; no way to read this
+ * from an ID register so the missing features need to be specified in dts
+ */
+ adsp_pinctrl->ds_missing = of_property_read_bool(np, "adi,no-drive-strength");
+ adsp_pinctrl->pude_missing = of_property_read_bool(np, "adi,no-pull-up-down");
+
+ /* Only if requested, adjust non-port drive strengths */
+ ret = of_property_read_u32(np, "adi,clkout-drive-strength", &val);
+ if (!ret)
+ adsp_set_nongpio_ds(adsp_pinctrl, ADSP_NONPORTS_DS_CKOUT, !!val);
+
+ ret = of_property_read_u32(np, "adi,resoutb-drive-strength", &val);
+ if (!ret)
+ adsp_set_nongpio_ds(adsp_pinctrl, ADSP_NONPORTS_DS_RESOUTB, !!val);
+
+ ret = of_property_read_u32(np, "adi,faultb-drive-strength", &val);
+ if (!ret)
+ adsp_set_nongpio_ds(adsp_pinctrl, ADSP_NONPORTS_DS_FAULTB, !!val);
+
+ ret = of_property_read_u32(np, "adi,lp1ck-drive-strength", &val);
+ if (!ret)
+ adsp_set_nongpio_ds(adsp_pinctrl, ADSP_NONPORTS_DS_LP1CK, !!val);
+
+ ret = of_property_read_u32(np, "adi,lp0ck-drive-strength", &val);
+ if (!ret)
+ adsp_set_nongpio_ds(adsp_pinctrl, ADSP_NONPORTS_DS_LP0CK, !!val);
+
+ ret = of_property_read_u32(np, "adi,ospi-drive-strength", &val);
+ if (!ret)
+ adsp_set_nongpio_ds(adsp_pinctrl, ADSP_NONPORTS_DS_OSPI, !!val);
+
+ pnctrl_desc->name = dev_name(dev);
+ pnctrl_desc->pctlops = &adsp_pctlops;
+ pnctrl_desc->confops = &adsp_confops;
+ pnctrl_desc->pmxops = &adsp_pmxops;
+ pnctrl_desc->owner = THIS_MODULE;
+ pnctrl_desc->num_custom_params = ARRAY_SIZE(adsp_custom_bindings);
+ pnctrl_desc->custom_params = adsp_custom_bindings;
+ pnctrl_desc->custom_conf_items = adsp_conf_items;
+
+ spin_lock_init(&adsp_pinctrl->lock);
+ ret = adsp_pinctrl_init_groups(adsp_pinctrl, pnctrl_desc);
+ if (ret)
+ return ret;
+
+ ret = devm_pinctrl_register_and_init(dev, pnctrl_desc, adsp_pinctrl,
+ &adsp_pinctrl->pin_dev);
+ if (ret)
+ return ret;
+
+ platform_set_drvdata(pdev, adsp_pinctrl);
+ ret = pinctrl_enable(adsp_pinctrl->pin_dev);
+ return ret;
+}
+
+static const struct of_device_id adsp_pinctrl_of_match[] = {
+ { .compatible = "adi,adsp-pinctrl", },
+ { },
+};
+MODULE_DEVICE_TABLE(of, adsp_pinctrl_of_match);
+
+static struct platform_driver adsp_pinctrl_driver = {
+ .driver = {
+ .name = "adsp-pinctrl",
+ .of_match_table = adsp_pinctrl_of_match,
+ .suppress_bind_attrs = true,
+ },
+ .probe = adsp_pinctrl_probe,
+};
+
+static int __init adsp_pinctrl_init(void)
+{
+ return platform_driver_register(&adsp_pinctrl_driver);
+}
+
+/*
+ * We want the pinctrl driver to be available at arch init time not at the
+ * later device init time
+ */
+arch_initcall(adsp_pinctrl_init);
+
+MODULE_AUTHOR("Greg Malysa <greg.malysa@timesys.com>");
+MODULE_DESCRIPTION("Analog Devices Pinctrl driver");
+MODULE_LICENSE("GPL v2");
\ No newline at end of file
--
2.25.1
^ permalink raw reply related [flat|nested] 65+ messages in thread
* Re: [PATCH 13/21] pinctrl: Add drivers for ADI ADSP-SC5xx platform
2024-09-12 18:24 ` [PATCH 13/21] pinctrl: Add drivers for ADI ADSP-SC5xx platform Arturs Artamonovs via B4 Relay
@ 2024-09-14 2:55 ` kernel test robot
0 siblings, 0 replies; 65+ messages in thread
From: kernel test robot @ 2024-09-14 2:55 UTC (permalink / raw)
To: Arturs Artamonovs via B4 Relay, Catalin Marinas, Will Deacon,
Greg Malysa, Philipp Zabel, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Utsav Agarwal, Michael Turquette, Stephen Boyd,
Linus Walleij, Bartosz Golaszewski, Thomas Gleixner, Andi Shyti,
Greg Kroah-Hartman, Jiri Slaby, Arnd Bergmann, Olof Johansson,
soc
Cc: llvm, oe-kbuild-all, linux-arm-kernel, linux-kernel, devicetree,
linux-clk, linux-gpio, linux-i2c, linux-serial, Arturs Artamonovs,
adsp-linux, Nathan Barrett-Morrison
Hi Arturs,
kernel test robot noticed the following build warnings:
[auto build test WARNING on da3ea35007d0af457a0afc87e84fddaebc4e0b63]
url: https://github.com/intel-lab-lkp/linux/commits/Arturs-Artamonovs-via-B4-Relay/arm64-Add-ADI-ADSP-SC598-SoC/20240913-022308
base: da3ea35007d0af457a0afc87e84fddaebc4e0b63
patch link: https://lore.kernel.org/r/20240912-test-v1-13-458fa57c8ccf%40analog.com
patch subject: [PATCH 13/21] pinctrl: Add drivers for ADI ADSP-SC5xx platform
config: arm64-allmodconfig (https://download.01.org/0day-ci/archive/20240914/202409141049.53oom3zJ-lkp@intel.com/config)
compiler: clang version 20.0.0git (https://github.com/llvm/llvm-project bf684034844c660b778f0eba103582f582b710c9)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240914/202409141049.53oom3zJ-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202409141049.53oom3zJ-lkp@intel.com/
All warnings (new ones prefixed by >>):
>> drivers/pinctrl/pinctrl-adsp.c:291: warning: Function parameter or struct member 'pctldev' not described in 'adsp_pinctrl_dt_node_to_map'
>> drivers/pinctrl/pinctrl-adsp.c:291: warning: Function parameter or struct member 'np' not described in 'adsp_pinctrl_dt_node_to_map'
>> drivers/pinctrl/pinctrl-adsp.c:291: warning: Function parameter or struct member 'map' not described in 'adsp_pinctrl_dt_node_to_map'
>> drivers/pinctrl/pinctrl-adsp.c:291: warning: Function parameter or struct member 'num_maps' not described in 'adsp_pinctrl_dt_node_to_map'
>> drivers/pinctrl/pinctrl-adsp.c:291: warning: expecting prototype for Handle device tree structures like(). Prototype was for adsp_pinctrl_dt_node_to_map() instead
vim +291 drivers/pinctrl/pinctrl-adsp.c
271
272 /**
273 * Handle device tree structures like:
274 *
275 * pinctrl_uart0_hwflow: uart0_hwflow_pins {
276 * pins_rxtx_ {
277 * pinmux = <1>, <2>;
278 * some-padconf-flag;
279 * };
280 * pins_hwflow {
281 * pinmux = <3>, <4>;
282 * some-other-padconf-flag;
283 * };
284 * };
285 *
286 * where &pinctrl_uart0_hwflow is passed as an entry in pinctrl-0 on uart driver and
287 * enables all sub-pins at once
288 */
289 static int adsp_pinctrl_dt_node_to_map(struct pinctrl_dev *pctldev,
290 struct device_node *np, struct pinctrl_map **map, unsigned int *num_maps)
> 291 {
292 unsigned int reserved_maps;
293 struct device_node *child_np;
294 int ret;
295
296 reserved_maps = 0;
297 *map = NULL;
298 *num_maps = 0;
299
300 for_each_child_of_node(np, child_np) {
301 ret = adsp_pinctrl_dt_subnode_to_map(pctldev, child_np, map,
302 &reserved_maps, num_maps);
303 if (ret < 0)
304 goto exit;
305 }
306 return 0;
307
308 exit:
309 pinctrl_utils_free_map(pctldev, *map, *num_maps);
310 return ret;
311 }
312
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 65+ messages in thread
* [PATCH 14/21] dt-bindings: pinctrl: adi,adsp-pinctrl: add bindings
2024-09-12 18:24 [PATCH 00/21] Adding support of ADI ARMv8 ADSP-SC598 SoC Arturs Artamonovs via B4 Relay
` (12 preceding siblings ...)
2024-09-12 18:24 ` [PATCH 13/21] pinctrl: Add drivers for ADI ADSP-SC5xx platform Arturs Artamonovs via B4 Relay
@ 2024-09-12 18:24 ` Arturs Artamonovs via B4 Relay
2024-09-13 22:09 ` Rob Herring
2024-09-12 18:25 ` [PATCH 15/21] i2c: Add driver for ADI ADSP-SC5xx platforms Arturs Artamonovs via B4 Relay
` (9 subsequent siblings)
23 siblings, 1 reply; 65+ messages in thread
From: Arturs Artamonovs via B4 Relay @ 2024-09-12 18:24 UTC (permalink / raw)
To: Catalin Marinas, Will Deacon, Greg Malysa, Philipp Zabel,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Utsav Agarwal,
Michael Turquette, Stephen Boyd, Linus Walleij,
Bartosz Golaszewski, Thomas Gleixner, Andi Shyti,
Greg Kroah-Hartman, Jiri Slaby, Arnd Bergmann, Olof Johansson,
soc
Cc: linux-arm-kernel, linux-kernel, devicetree, linux-clk, linux-gpio,
linux-i2c, linux-serial, Arturs Artamonovs, adsp-linux,
Arturs Artamonovs, Nathan Barrett-Morrison
From: Arturs Artamonovs <arturs.artamonovs@analog.com>
Add PINCTRL driver bindings.
Signed-off-by: Arturs Artamonovs <Arturs.Artamonovs@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>
---
.../bindings/pinctrl/adi,adsp-pinctrl.yaml | 83 ++++++++++++++++++++++
include/dt-bindings/pinctrl/adi-adsp.h | 19 +++++
2 files changed, 102 insertions(+)
diff --git a/Documentation/devicetree/bindings/pinctrl/adi,adsp-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/adi,adsp-pinctrl.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..073442b4f680bf536f631b4c17a1d3195c2233d6
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/adi,adsp-pinctrl.yaml
@@ -0,0 +1,83 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pinctrl/adi,adsp-pinctrl.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Analog Devices Pinmuxing Control for SC5XX Processor Family
+
+maintainers:
+ - Arturs Artamonovs <arturs.artamonovs@analog.com>
+ - Utsav Agarwal <Utsav.Agarwal@analog.com>
+
+description: |
+ Pinmuxing Control Driver for Configuring Processor Pins/Pads
+
+properties:
+ compatible:
+ enum:
+ - adi,adsp-pinctrl
+
+ "#address-cells":
+ const: 1
+
+ "#size-cells":
+ const: 1
+
+ reg:
+ maxItems: 1
+
+ "adi,port-sizes":
+ $ref: /schemas/types.yaml#/definitions/uint32-array
+ maxItems: 9
+ description: Space delimited integer list denoting number of pins per port
+ Ports A-I exist, so this is up to 9 items long
+
+ "adi,no-drive-strength":
+ type: boolean
+ description: Indicate missing drive strength registers
+
+ "adi,no-pull-up-down":
+ type: boolean
+ description: Indicate missing pull up/down enable registers
+
+patternProperties:
+ '-pins$':
+ type: object
+ additionalProperties: false
+
+ properties:
+ pins:
+ type: object
+ description: |
+ A pinctrl node should contain a pin property, specifying the actual
+ pins to use.
+
+ properties:
+ pinmux:
+ $ref: /schemas/types.yaml#/definitions/uint32-array
+ description: |
+ pinmux is used to specify which of the available functionalities
+ for a given pin are actually used.
+
+ additionalProperties: false
+
+required:
+ - compatible
+ - "#address-cells"
+ - "#size-cells"
+ - reg
+ - "adi,port-sizes"
+
+additionalProperties: false
+
+examples:
+ - |
+ pinctrl0: pinctrl@31004600 {
+ compatible = "adi,adsp-pinctrl";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x31004600 0x400>;
+ adi,port-sizes = <16 16 16 16 16 16 16 16 7>;
+ };
+
diff --git a/include/dt-bindings/pinctrl/adi-adsp.h b/include/dt-bindings/pinctrl/adi-adsp.h
new file mode 100644
index 0000000000000000000000000000000000000000..dc5b86a0d9190acdd242a6ba4972c3aac7a61821
--- /dev/null
+++ b/include/dt-bindings/pinctrl/adi-adsp.h
@@ -0,0 +1,19 @@
+/* SPDX-License-Identifier: GPL-2.0*/
+/*
+ * Macros for populating pinmux properties on the pincontroller
+ *
+ * Copyright 2022-2024 - Analog Devices Inc.
+ */
+
+#ifndef DT_BINDINGS_PINCTRL_ADI_ADSP_H
+#define DT_BINDINGS_PINCTRL_ADI_ADSP_H
+
+#define ADI_ADSP_PINFUNC_GPIO 0
+#define ADI_ADSP_PINFUNC_ALT0 1
+#define ADI_ADSP_PINFUNC_ALT1 2
+#define ADI_ADSP_PINFUNC_ALT2 3
+#define ADI_ADSP_PINFUNC_ALT3 4
+
+#define ADI_ADSP_PINMUX(port, pin, func) ((((port - 'A')*16 + pin) << 8) + func)
+
+#endif
--
2.25.1
^ permalink raw reply related [flat|nested] 65+ messages in thread
* Re: [PATCH 14/21] dt-bindings: pinctrl: adi,adsp-pinctrl: add bindings
2024-09-12 18:24 ` [PATCH 14/21] dt-bindings: pinctrl: adi,adsp-pinctrl: add bindings Arturs Artamonovs via B4 Relay
@ 2024-09-13 22:09 ` Rob Herring
0 siblings, 0 replies; 65+ messages in thread
From: Rob Herring @ 2024-09-13 22:09 UTC (permalink / raw)
To: Arturs Artamonovs
Cc: Catalin Marinas, Will Deacon, Greg Malysa, Philipp Zabel,
Krzysztof Kozlowski, Conor Dooley, Utsav Agarwal,
Michael Turquette, Stephen Boyd, Linus Walleij,
Bartosz Golaszewski, Thomas Gleixner, Andi Shyti,
Greg Kroah-Hartman, Jiri Slaby, Arnd Bergmann, Olof Johansson,
soc, linux-arm-kernel, linux-kernel, devicetree, linux-clk,
linux-gpio, linux-i2c, linux-serial, adsp-linux,
Nathan Barrett-Morrison
On Thu, Sep 12, 2024 at 07:24:59PM +0100, Arturs Artamonovs wrote:
> Add PINCTRL driver bindings.
>
> Signed-off-by: Arturs Artamonovs <Arturs.Artamonovs@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>
> ---
> .../bindings/pinctrl/adi,adsp-pinctrl.yaml | 83 ++++++++++++++++++++++
> include/dt-bindings/pinctrl/adi-adsp.h | 19 +++++
> 2 files changed, 102 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/pinctrl/adi,adsp-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/adi,adsp-pinctrl.yaml
> new file mode 100644
> index 0000000000000000000000000000000000000000..073442b4f680bf536f631b4c17a1d3195c2233d6
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/pinctrl/adi,adsp-pinctrl.yaml
> @@ -0,0 +1,83 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/pinctrl/adi,adsp-pinctrl.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Analog Devices Pinmuxing Control for SC5XX Processor Family
> +
> +maintainers:
> + - Arturs Artamonovs <arturs.artamonovs@analog.com>
> + - Utsav Agarwal <Utsav.Agarwal@analog.com>
> +
> +description: |
> + Pinmuxing Control Driver for Configuring Processor Pins/Pads
> +
> +properties:
> + compatible:
> + enum:
> + - adi,adsp-pinctrl
> +
> + "#address-cells":
> + const: 1
> +
> + "#size-cells":
> + const: 1
> +
> + reg:
> + maxItems: 1
> +
> + "adi,port-sizes":
Don't need quotes.
> + $ref: /schemas/types.yaml#/definitions/uint32-array
> + maxItems: 9
> + description: Space delimited integer list denoting number of pins per port
> + Ports A-I exist, so this is up to 9 items long
No constraints on the entries?
> +
> + "adi,no-drive-strength":
> + type: boolean
> + description: Indicate missing drive strength registers
> +
> + "adi,no-pull-up-down":
> + type: boolean
> + description: Indicate missing pull up/down enable registers
> +
> +patternProperties:
> + '-pins$':
> + type: object
> + additionalProperties: false
> +
> + properties:
> + pins:
> + type: object
> + description: |
> + A pinctrl node should contain a pin property, specifying the actual
> + pins to use.
> +
> + properties:
> + pinmux:
> + $ref: /schemas/types.yaml#/definitions/uint32-array
> + description: |
> + pinmux is used to specify which of the available functionalities
> + for a given pin are actually used.
> +
> + additionalProperties: false
> +
> +required:
> + - compatible
> + - "#address-cells"
> + - "#size-cells"
> + - reg
> + - "adi,port-sizes"
> +
> +additionalProperties: false
> +
> +examples:
> + - |
> + pinctrl0: pinctrl@31004600 {
> + compatible = "adi,adsp-pinctrl";
> + #address-cells = <1>;
> + #size-cells = <1>;
> + reg = <0x31004600 0x400>;
> + adi,port-sizes = <16 16 16 16 16 16 16 16 7>;
> + };
> +
> diff --git a/include/dt-bindings/pinctrl/adi-adsp.h b/include/dt-bindings/pinctrl/adi-adsp.h
> new file mode 100644
> index 0000000000000000000000000000000000000000..dc5b86a0d9190acdd242a6ba4972c3aac7a61821
> --- /dev/null
> +++ b/include/dt-bindings/pinctrl/adi-adsp.h
> @@ -0,0 +1,19 @@
> +/* SPDX-License-Identifier: GPL-2.0*/
Missing space ^
New bindings should be dual licensed.
> +/*
> + * Macros for populating pinmux properties on the pincontroller
> + *
> + * Copyright 2022-2024 - Analog Devices Inc.
> + */
> +
> +#ifndef DT_BINDINGS_PINCTRL_ADI_ADSP_H
> +#define DT_BINDINGS_PINCTRL_ADI_ADSP_H
> +
> +#define ADI_ADSP_PINFUNC_GPIO 0
> +#define ADI_ADSP_PINFUNC_ALT0 1
> +#define ADI_ADSP_PINFUNC_ALT1 2
> +#define ADI_ADSP_PINFUNC_ALT2 3
> +#define ADI_ADSP_PINFUNC_ALT3 4
> +
> +#define ADI_ADSP_PINMUX(port, pin, func) ((((port - 'A')*16 + pin) << 8) + func)
> +
> +#endif
>
> --
> 2.25.1
>
^ permalink raw reply [flat|nested] 65+ messages in thread
* [PATCH 15/21] i2c: Add driver for ADI ADSP-SC5xx platforms
2024-09-12 18:24 [PATCH 00/21] Adding support of ADI ARMv8 ADSP-SC598 SoC Arturs Artamonovs via B4 Relay
` (13 preceding siblings ...)
2024-09-12 18:24 ` [PATCH 14/21] dt-bindings: pinctrl: adi,adsp-pinctrl: add bindings Arturs Artamonovs via B4 Relay
@ 2024-09-12 18:25 ` Arturs Artamonovs via B4 Relay
2024-09-13 7:59 ` Arnd Bergmann
2024-09-16 7:13 ` Krzysztof Kozlowski
2024-09-12 18:25 ` [PATCH 16/21] dt-bindings: i2c: add i2c/twi driver documentation Arturs Artamonovs via B4 Relay
` (8 subsequent siblings)
23 siblings, 2 replies; 65+ messages in thread
From: Arturs Artamonovs via B4 Relay @ 2024-09-12 18:25 UTC (permalink / raw)
To: Catalin Marinas, Will Deacon, Greg Malysa, Philipp Zabel,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Utsav Agarwal,
Michael Turquette, Stephen Boyd, Linus Walleij,
Bartosz Golaszewski, Thomas Gleixner, Andi Shyti,
Greg Kroah-Hartman, Jiri Slaby, Arnd Bergmann, Olof Johansson,
soc
Cc: linux-arm-kernel, linux-kernel, devicetree, linux-clk, linux-gpio,
linux-i2c, linux-serial, Arturs Artamonovs, adsp-linux,
Arturs Artamonovs, Nathan Barrett-Morrison
From: Arturs Artamonovs <arturs.artamonovs@analog.com>
Add support for I2C on SC5xx
Signed-off-by: Arturs Artamonovs <Arturs.Artamonovs@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>
---
drivers/i2c/busses/Kconfig | 17 +
drivers/i2c/busses/Makefile | 1 +
drivers/i2c/busses/i2c-adi-twi.c | 940 +++++++++++++++++++++++++++++++++++++++
3 files changed, 958 insertions(+)
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
index a22f9125322a723b31925fd86b26ef0b8d3b8a19..f672a2c715ca15ece74ee694596318976da88dfd 100644
--- a/drivers/i2c/busses/Kconfig
+++ b/drivers/i2c/busses/Kconfig
@@ -518,6 +518,23 @@ config I2C_BRCMSTB
If you do not need I2C interface, say N.
+config I2C_ADI_TWI
+ tristate "ADI TWI I2C support"
+ depends on ARCH_SC59X_64 || ARCH_SC59X
+ help
+ This is the I2C bus driver for ADI on-chip TWI interface.
+
+ This driver can also be built as a module. If so, the module
+ will be called i2c-adi-twi.
+
+config I2C_ADI_TWI_CLK_KHZ
+ int "ADI TWI I2C clock (kHz)"
+ depends on I2C_ADI_TWI
+ range 21 400
+ default 50
+ help
+ The unit of the TWI clock is kHz.
+
config I2C_CADENCE
tristate "Cadence I2C Controller"
depends on ARCH_ZYNQ || ARM64 || XTENSA || RISCV || COMPILE_TEST
diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile
index 78d0561339e5beadcb810196be1139a4248469b4..421d637cfbc91af5a69895e76a255b2ef47f4081 100644
--- a/drivers/i2c/busses/Makefile
+++ b/drivers/i2c/busses/Makefile
@@ -48,6 +48,7 @@ obj-$(CONFIG_I2C_AU1550) += i2c-au1550.o
obj-$(CONFIG_I2C_AXXIA) += i2c-axxia.o
obj-$(CONFIG_I2C_BCM2835) += i2c-bcm2835.o
obj-$(CONFIG_I2C_BCM_IPROC) += i2c-bcm-iproc.o
+obj-$(CONFIG_I2C_ADI_TWI) += i2c-adi-twi.o
obj-$(CONFIG_I2C_CADENCE) += i2c-cadence.o
obj-$(CONFIG_I2C_CBUS_GPIO) += i2c-cbus-gpio.o
obj-$(CONFIG_I2C_CPM) += i2c-cpm.o
diff --git a/drivers/i2c/busses/i2c-adi-twi.c b/drivers/i2c/busses/i2c-adi-twi.c
new file mode 100644
index 0000000000000000000000000000000000000000..4af3991f5fc8709df196f58816ed7a96fd1dac2d
--- /dev/null
+++ b/drivers/i2c/busses/i2c-adi-twi.c
@@ -0,0 +1,940 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * ADI On-Chip Two Wire Interface Driver
+ *
+ * Copyright 2022-2024 - Analog Devices Inc.
+ */
+
+#include <linux/module.h>
+#include <linux/i2c.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/of_device.h>
+#include <linux/clk.h>
+
+
+/* TWI_PRESCALE Masks */
+#define TWI_ENA 0x0080 /* TWI Enable */
+
+/* TWI_MASTER_CTL Masks */
+#define MEN 0x0001 /* Master Mode Enable */
+#define MDIR 0x0004 /* Master Transmit Direction (RX/TX*) */
+#define FAST 0x0008 /* Use Fast Mode Timing Specs */
+#define STOP 0x0010 /* Issue Stop Condition */
+#define RSTART 0x0020 /* Repeat Start or Stop* At End Of Transfer */
+#define SDAOVR 0x4000 /* Serial Data Override */
+#define SCLOVR 0x8000 /* Serial Clock Override */
+
+/* TWI_MASTER_STAT Masks */
+#define LOSTARB 0x0002 /* Lost Arbitration Indicator (Xfer Aborted) */
+#define ANAK 0x0004 /* Address Not Acknowledged */
+#define DNAK 0x0008 /* Data Not Acknowledged */
+#define BUFRDERR 0x0010 /* Buffer Read Error */
+#define BUFWRERR 0x0020 /* Buffer Write Error */
+#define SDASEN 0x0040 /* Serial Data Sense */
+#define BUSBUSY 0x0100 /* Bus Busy Indicator */
+
+/* TWI_INT_SRC and TWI_INT_ENABLE Masks */
+#define MCOMP 0x0010 /* Master Transfer Complete */
+#define MERR 0x0020 /* Master Transfer Error */
+#define XMTSERV 0x0040 /* Transmit FIFO Service */
+#define RCVSERV 0x0080 /* Receive FIFO Service */
+
+/* TWI_FIFO_STAT Masks */
+#define XMTSTAT 0x0003 /* Transmit FIFO Status */
+#define XMT_FULL 0x0003 /* Transmit FIFO Full (2 Bytes To Write) */
+#define RCVSTAT 0x000C /* Receive FIFO Status */
+
+/* SMBus mode*/
+#define TWI_I2C_MODE_STANDARD 1
+#define TWI_I2C_MODE_STANDARDSUB 2
+#define TWI_I2C_MODE_COMBINED 3
+#define TWI_I2C_MODE_REPEAT 4
+
+/*
+ * ADI twi registers layout
+ */
+struct adi_twi_regs {
+ u16 clkdiv;
+ u16 dummy1;
+ u16 control;
+ u16 dummy2;
+ u16 slave_ctl;
+ u16 dummy3;
+ u16 slave_stat;
+ u16 dummy4;
+ u16 slave_addr;
+ u16 dummy5;
+ u16 master_ctl;
+ u16 dummy6;
+ u16 master_stat;
+ u16 dummy7;
+ u16 master_addr;
+ u16 dummy8;
+ u16 int_stat;
+ u16 dummy9;
+ u16 int_mask;
+ u16 dummy10;
+ u16 fifo_ctl;
+ u16 dummy11;
+ u16 fifo_stat;
+ u16 dummy12;
+ u32 __pad[20];
+ u16 xmt_data8;
+ u16 dummy13;
+ u16 xmt_data16;
+ u16 dummy14;
+ u16 rcv_data8;
+ u16 dummy15;
+ u16 rcv_data16;
+ u16 dummy16;
+};
+
+struct adi_twi_iface {
+ int irq;
+ spinlock_t lock;
+ char read_write;
+ u8 command;
+ u8 *transPtr;
+ int readNum;
+ int writeNum;
+ int cur_mode;
+ int manual_stop;
+ int result;
+ unsigned int twi_clk;
+ struct i2c_adapter adap;
+ struct completion complete;
+ struct i2c_msg *pmsg;
+ int msg_num;
+ int cur_msg;
+ u16 saved_clkdiv;
+ u16 saved_control;
+ struct adi_twi_regs __iomem *regs_base;
+ struct clk *sclk;
+};
+
+static void adi_twi_handle_interrupt(struct adi_twi_iface *iface,
+ unsigned short twi_int_status,
+ bool polling)
+{
+ u16 writeValue;
+ unsigned short mast_stat = ioread16(&iface->regs_base->master_stat);
+
+ if (twi_int_status & XMTSERV) {
+ if (iface->writeNum <= 0) {
+ /* start receive immediately after complete sending in
+ * combine mode.
+ */
+ if (iface->cur_mode == TWI_I2C_MODE_COMBINED) {
+ writeValue = ioread16(&iface->regs_base->master_ctl) | MDIR;
+ iowrite16(writeValue, &iface->regs_base->master_ctl);
+ } else if (iface->manual_stop) {
+ writeValue = ioread16(&iface->regs_base->master_ctl) | STOP;
+ iowrite16(writeValue, &iface->regs_base->master_ctl);
+ } else if (iface->cur_mode == TWI_I2C_MODE_REPEAT &&
+ iface->cur_msg + 1 < iface->msg_num) {
+
+ if (iface->pmsg[iface->cur_msg + 1].flags & I2C_M_RD) {
+ writeValue = ioread16(&iface->regs_base->master_ctl)
+ | MDIR;
+ iowrite16(writeValue, &iface->regs_base->master_ctl);
+ } else {
+ writeValue = ioread16(&iface->regs_base->master_ctl)
+ & ~MDIR;
+ iowrite16(writeValue, &iface->regs_base->master_ctl);
+ }
+
+ }
+ }
+ /* Transmit next data */
+ while (iface->writeNum > 0 &&
+ (ioread16(&iface->regs_base->fifo_stat) & XMTSTAT) != XMT_FULL) {
+ iowrite16(*(iface->transPtr++), &iface->regs_base->xmt_data8);
+ iface->writeNum--;
+ }
+ }
+ if (twi_int_status & RCVSERV) {
+ while (iface->readNum > 0 &&
+ (ioread16(&iface->regs_base->fifo_stat) & RCVSTAT)) {
+ /* Receive next data */
+ *(iface->transPtr) = ioread16(&iface->regs_base->rcv_data8);
+ if (iface->cur_mode == TWI_I2C_MODE_COMBINED) {
+ /* Change combine mode into sub mode after
+ * read first data.
+ */
+ iface->cur_mode = TWI_I2C_MODE_STANDARDSUB;
+ /* Get read number from first byte in block
+ * combine mode.
+ */
+ if (iface->readNum == 1 && iface->manual_stop)
+ iface->readNum = *iface->transPtr + 1;
+ }
+ iface->transPtr++;
+ iface->readNum--;
+ }
+
+ if (iface->readNum == 0) {
+ if (iface->manual_stop) {
+ /* Temporary workaround to avoid possible bus stall -
+ * Flush FIFO before issuing the STOP condition
+ */
+ ioread16(&iface->regs_base->rcv_data16);
+ writeValue = ioread16(&iface->regs_base->master_ctl) | STOP;
+ iowrite16(writeValue, &iface->regs_base->master_ctl);
+ } else if (iface->cur_mode == TWI_I2C_MODE_REPEAT &&
+ iface->cur_msg + 1 < iface->msg_num) {
+ if (iface->pmsg[iface->cur_msg + 1].flags & I2C_M_RD) {
+ writeValue = ioread16(&iface->regs_base->master_ctl) |
+ MDIR;
+ iowrite16(writeValue, &iface->regs_base->master_ctl);
+ } else {
+ writeValue = ioread16(&iface->regs_base->master_ctl) &
+ ~MDIR;
+ iowrite16(writeValue, &iface->regs_base->master_ctl);
+ }
+ }
+ }
+ }
+ if (twi_int_status & MERR) {
+ iowrite16(0, &iface->regs_base->int_mask);
+ iowrite16(0x3e, &iface->regs_base->master_stat);
+ iowrite16(0, &iface->regs_base->master_ctl);
+ iface->result = -EIO;
+
+ if (mast_stat & LOSTARB)
+ dev_dbg(&iface->adap.dev, "Lost Arbitration\n");
+ if (mast_stat & ANAK)
+ dev_dbg(&iface->adap.dev, "Address Not Acknowledged\n");
+ if (mast_stat & DNAK)
+ dev_dbg(&iface->adap.dev, "Data Not Acknowledged\n");
+ if (mast_stat & BUFRDERR)
+ dev_dbg(&iface->adap.dev, "Buffer Read Error\n");
+ if (mast_stat & BUFWRERR)
+ dev_dbg(&iface->adap.dev, "Buffer Write Error\n");
+
+ /* Faulty slave devices, may drive SDA low after a transfer
+ * finishes. To release the bus this code generates up to 9
+ * extra clocks until SDA is released.
+ */
+
+ if (ioread16(&iface->regs_base->master_stat) & SDASEN) {
+ int cnt = 9;
+
+ do {
+ iowrite16(SCLOVR, &iface->regs_base->master_ctl);
+ udelay(6);
+ iowrite16(0, &iface->regs_base->master_ctl);
+ udelay(6);
+ } while ((ioread16(&iface->regs_base->master_stat) & SDASEN) && cnt--);
+
+ iowrite16(SDAOVR | SCLOVR, &iface->regs_base->master_ctl);
+ udelay(6);
+ iowrite16(SDAOVR, &iface->regs_base->master_ctl);
+ udelay(6);
+ iowrite16(0, &iface->regs_base->master_ctl);
+ }
+
+ /* If it is a quick transfer, only address without data,
+ * not an err, return 1.
+ */
+ if (iface->cur_mode == TWI_I2C_MODE_STANDARD &&
+ iface->transPtr == NULL &&
+ (twi_int_status & MCOMP) && (mast_stat & DNAK))
+ iface->result = 1;
+
+ if (!polling)
+ complete(&iface->complete);
+ return;
+ }
+ if (twi_int_status & MCOMP) {
+ if (twi_int_status & (XMTSERV | RCVSERV) &&
+ (ioread16(&iface->regs_base->master_ctl) & MEN) == 0 &&
+ (iface->cur_mode == TWI_I2C_MODE_REPEAT ||
+ iface->cur_mode == TWI_I2C_MODE_COMBINED)) {
+ iface->result = -1;
+ iowrite16(0, &iface->regs_base->int_mask);
+ iowrite16(0, &iface->regs_base->master_ctl);
+ } else if (iface->cur_mode == TWI_I2C_MODE_COMBINED) {
+ if (iface->readNum == 0) {
+ /* set the read number to 1 and ask for manual
+ * stop in block combine mode
+ */
+ iface->readNum = 1;
+ iface->manual_stop = 1;
+ writeValue = ioread16(&iface->regs_base->master_ctl) | (0xff << 6);
+ iowrite16(writeValue, &iface->regs_base->master_ctl);
+ } else {
+ /* set the readd number in other
+ * combine mode.
+ */
+ writeValue = (ioread16(&iface->regs_base->master_ctl)
+ & (~(0xff << 6))) | (iface->readNum << 6);
+ iowrite16(writeValue, &iface->regs_base->master_ctl);
+ }
+ /* remove restart bit and enable master receive */
+ writeValue = ioread16(&iface->regs_base->master_ctl) & ~RSTART;
+ iowrite16(writeValue, &iface->regs_base->master_ctl);
+ } else if (iface->cur_mode == TWI_I2C_MODE_REPEAT &&
+ iface->cur_msg + 1 < iface->msg_num) {
+ iface->cur_msg++;
+ iface->transPtr = iface->pmsg[iface->cur_msg].buf;
+ iface->writeNum = iface->readNum =
+ iface->pmsg[iface->cur_msg].len;
+ /* Set Transmit device address */
+ iowrite16(iface->pmsg[iface->cur_msg].addr, &iface->regs_base->master_addr);
+ if (iface->pmsg[iface->cur_msg].flags & I2C_M_RD)
+ iface->read_write = I2C_SMBUS_READ;
+ else {
+ iface->read_write = I2C_SMBUS_WRITE;
+ /* Transmit first data */
+ if (iface->writeNum > 0) {
+ iowrite16(*(iface->transPtr++),
+ &iface->regs_base->xmt_data8);
+ iface->writeNum--;
+ }
+ }
+
+ if (iface->pmsg[iface->cur_msg].len <= 255) {
+ writeValue = (ioread16(&iface->regs_base->master_ctl)
+ & (~(0xff << 6)))
+ | (iface->pmsg[iface->cur_msg].len << 6);
+ iowrite16(writeValue, &iface->regs_base->master_ctl);
+ iface->manual_stop = 0;
+ } else {
+ writeValue = (ioread16(&iface->regs_base->master_ctl)
+ | (0xff << 6));
+ iowrite16(writeValue, &iface->regs_base->master_ctl);
+ iface->manual_stop = 1;
+ }
+
+ /* remove restart bit before last message */
+ if (iface->cur_msg + 1 == iface->msg_num) {
+ writeValue = ioread16(&iface->regs_base->master_ctl) & ~RSTART;
+ iowrite16(writeValue, &iface->regs_base->master_ctl);
+ }
+
+ } else {
+ iface->result = 1;
+ iowrite16(0, &iface->regs_base->int_mask);
+ iowrite16(0, &iface->regs_base->master_ctl);
+ }
+ if (!polling)
+ complete(&iface->complete);
+ }
+}
+
+/* Interrupt handler */
+static irqreturn_t adi_twi_handle_all_interrupts(struct adi_twi_iface *iface,
+ bool polling)
+{
+ irqreturn_t handled = IRQ_NONE;
+ unsigned short twi_int_status;
+
+ while (1) {
+ twi_int_status = ioread16(&iface->regs_base->int_stat);
+ if (!twi_int_status)
+ return handled;
+ /* Clear interrupt status */
+ iowrite16(twi_int_status, &iface->regs_base->int_stat);
+ adi_twi_handle_interrupt(iface, twi_int_status, polling);
+ handled = IRQ_HANDLED;
+ }
+}
+
+static irqreturn_t adi_twi_interrupt_entry(int irq, void *dev_id)
+{
+ struct adi_twi_iface *iface = dev_id;
+ unsigned long flags;
+ irqreturn_t handled;
+
+ spin_lock_irqsave(&iface->lock, flags);
+ handled = adi_twi_handle_all_interrupts(iface, false);
+ spin_unlock_irqrestore(&iface->lock, flags);
+ return handled;
+}
+
+/*
+ * One i2c master transfer
+ */
+static int adi_twi_do_master_xfer(struct i2c_adapter *adap,
+ struct i2c_msg *msgs, int num, bool polling)
+{
+ struct adi_twi_iface *iface = adap->algo_data;
+ struct i2c_msg *pmsg;
+ int rc = 0;
+ u16 writeValue;
+
+ if (!(ioread16(&iface->regs_base->control) & TWI_ENA))
+ return -ENXIO;
+
+ if (ioread16(&iface->regs_base->master_stat) & BUSBUSY)
+ return -EAGAIN;
+
+ iface->pmsg = msgs;
+ iface->msg_num = num;
+ iface->cur_msg = 0;
+
+ pmsg = &msgs[0];
+ if (pmsg->flags & I2C_M_TEN) {
+ dev_err(&adap->dev, "10 bits addr not supported!\n");
+ return -EINVAL;
+ }
+
+ if (iface->msg_num > 1)
+ iface->cur_mode = TWI_I2C_MODE_REPEAT;
+ iface->manual_stop = 0;
+ iface->transPtr = pmsg->buf;
+ iface->writeNum = iface->readNum = pmsg->len;
+ iface->result = 0;
+ if (!polling)
+ init_completion(&(iface->complete));
+ /* Set Transmit device address */
+ iowrite16(pmsg->addr, &iface->regs_base->master_addr);
+
+ /* FIFO Initiation. Data in FIFO should be
+ * discarded before start a new operation.
+ */
+ iowrite16(0x3, &iface->regs_base->fifo_ctl);
+ iowrite16(0, &iface->regs_base->fifo_ctl);
+
+ if (pmsg->flags & I2C_M_RD)
+ iface->read_write = I2C_SMBUS_READ;
+ else {
+ iface->read_write = I2C_SMBUS_WRITE;
+ /* Transmit first data */
+ if (iface->writeNum > 0) {
+ iowrite16(*(iface->transPtr++), &iface->regs_base->xmt_data8);
+ iface->writeNum--;
+ }
+ }
+
+ /* clear int stat */
+ iowrite16(MERR | MCOMP | XMTSERV | RCVSERV, &iface->regs_base->int_stat);
+
+ /* Interrupt mask . Enable XMT, RCV interrupt */
+ iowrite16(MCOMP | MERR | RCVSERV | XMTSERV, &iface->regs_base->int_mask);
+
+ if (pmsg->len <= 255)
+ iowrite16(pmsg->len << 6, &iface->regs_base->master_ctl);
+ else {
+ iowrite16(0xff << 6, &iface->regs_base->master_ctl);
+ iface->manual_stop = 1;
+ }
+
+ /* Master enable */
+ writeValue = ioread16(&iface->regs_base->master_ctl) |
+ MEN |
+ ((iface->msg_num > 1) ? RSTART : 0) |
+ ((iface->read_write == I2C_SMBUS_READ) ? MDIR : 0) |
+ ((iface->twi_clk > 100) ? FAST : 0);
+
+ iowrite16(writeValue, &iface->regs_base->master_ctl);
+
+ if (polling) {
+ int timeout = 50000;
+
+ for (;;) {
+ irqreturn_t handled = adi_twi_handle_all_interrupts(
+ iface, true);
+ if (handled == IRQ_HANDLED && iface->result)
+ break;
+ if (--timeout == 0) {
+ iface->result = -1;
+ dev_err(&adap->dev, "master polling timeout");
+ break;
+ }
+ }
+ } else { /* interrupt driven */
+ while (!iface->result) {
+ if (!wait_for_completion_timeout(&iface->complete,
+ adap->timeout)) {
+ iface->result = -1;
+ dev_err(&adap->dev, "master transfer timeout");
+ }
+ }
+ }
+
+ if (iface->result == 1)
+ rc = iface->cur_msg + 1;
+ else
+ rc = iface->result;
+
+ return rc;
+}
+
+/*
+ * Generic i2c master transfer entrypoint
+ */
+static int adi_twi_master_xfer(struct i2c_adapter *adap,
+ struct i2c_msg *msgs, int num)
+{
+ return adi_twi_do_master_xfer(adap, msgs, num, false);
+}
+
+static int adi_twi_master_xfer_atomic(struct i2c_adapter *adap,
+ struct i2c_msg *msgs, int num)
+{
+ return adi_twi_do_master_xfer(adap, msgs, num, true);
+}
+
+/*
+ * One I2C SMBus transfer
+ */
+static int adi_twi_do_smbus_xfer(struct i2c_adapter *adap, u16 addr,
+ unsigned short flags, char read_write,
+ u8 command, int size, union i2c_smbus_data *data,
+ bool polling)
+{
+ struct adi_twi_iface *iface = adap->algo_data;
+ int rc = 0;
+ u16 writeValue;
+
+ if (!(ioread16(&iface->regs_base->control) & TWI_ENA))
+ return -ENXIO;
+
+ if (ioread16(&iface->regs_base->master_stat) & BUSBUSY)
+ return -EAGAIN;
+
+ iface->writeNum = 0;
+ iface->readNum = 0;
+
+ /* Prepare datas & select mode */
+ switch (size) {
+ case I2C_SMBUS_QUICK:
+ iface->transPtr = NULL;
+ iface->cur_mode = TWI_I2C_MODE_STANDARD;
+ break;
+ case I2C_SMBUS_BYTE:
+ if (data == NULL)
+ iface->transPtr = NULL;
+ else {
+ if (read_write == I2C_SMBUS_READ)
+ iface->readNum = 1;
+ else
+ iface->writeNum = 1;
+ iface->transPtr = &data->byte;
+ }
+ iface->cur_mode = TWI_I2C_MODE_STANDARD;
+ break;
+ case I2C_SMBUS_BYTE_DATA:
+ if (read_write == I2C_SMBUS_READ) {
+ iface->readNum = 1;
+ iface->cur_mode = TWI_I2C_MODE_COMBINED;
+ } else {
+ iface->writeNum = 1;
+ iface->cur_mode = TWI_I2C_MODE_STANDARDSUB;
+ }
+ iface->transPtr = &data->byte;
+ break;
+ case I2C_SMBUS_WORD_DATA:
+ if (read_write == I2C_SMBUS_READ) {
+ iface->readNum = 2;
+ iface->cur_mode = TWI_I2C_MODE_COMBINED;
+ } else {
+ iface->writeNum = 2;
+ iface->cur_mode = TWI_I2C_MODE_STANDARDSUB;
+ }
+ iface->transPtr = (u8 *)&data->word;
+ break;
+ case I2C_SMBUS_PROC_CALL:
+ iface->writeNum = 2;
+ iface->readNum = 2;
+ iface->cur_mode = TWI_I2C_MODE_COMBINED;
+ iface->transPtr = (u8 *)&data->word;
+ break;
+ case I2C_SMBUS_BLOCK_DATA:
+ if (read_write == I2C_SMBUS_READ) {
+ iface->readNum = 0;
+ iface->cur_mode = TWI_I2C_MODE_COMBINED;
+ } else {
+ iface->writeNum = data->block[0] + 1;
+ iface->cur_mode = TWI_I2C_MODE_STANDARDSUB;
+ }
+ iface->transPtr = data->block;
+ break;
+ case I2C_SMBUS_I2C_BLOCK_DATA:
+ if (read_write == I2C_SMBUS_READ) {
+ iface->readNum = data->block[0];
+ iface->cur_mode = TWI_I2C_MODE_COMBINED;
+ } else {
+ iface->writeNum = data->block[0];
+ iface->cur_mode = TWI_I2C_MODE_STANDARDSUB;
+ }
+ iface->transPtr = (u8 *)&data->block[1];
+ break;
+ default:
+ return -1;
+ }
+
+ iface->result = 0;
+ iface->manual_stop = 0;
+ iface->read_write = read_write;
+ iface->command = command;
+ if (!polling)
+ init_completion(&(iface->complete));
+
+ /* FIFO Initiation. Data in FIFO should be discarded before
+ * start a new operation.
+ */
+ iowrite16(0x3, &iface->regs_base->fifo_ctl);
+ iowrite16(0, &iface->regs_base->fifo_ctl);
+
+ /* clear int stat */
+ iowrite16(MERR | MCOMP | XMTSERV | RCVSERV, &iface->regs_base->int_stat);
+
+ /* Set Transmit device address */
+ iowrite16(addr, &iface->regs_base->master_addr);
+
+ switch (iface->cur_mode) {
+ case TWI_I2C_MODE_STANDARDSUB:
+ iowrite16(iface->command, &iface->regs_base->xmt_data8);
+
+ writeValue = MCOMP | MERR;
+ if (iface->read_write == I2C_SMBUS_READ)
+ writeValue |= RCVSERV;
+ else
+ writeValue |= XMTSERV;
+
+ iowrite16(writeValue, &iface->regs_base->int_mask);
+
+ if (iface->writeNum + 1 <= 255)
+ iowrite16((iface->writeNum + 1) << 6, &iface->regs_base->master_ctl);
+ else {
+ iowrite16(0xff << 6, &iface->regs_base->master_ctl);
+ iface->manual_stop = 1;
+ }
+ /* Master enable */
+ writeValue = ioread16(&iface->regs_base->master_ctl) | MEN;
+ if (iface->twi_clk > 100)
+ writeValue |= FAST;
+ iowrite16(writeValue, &iface->regs_base->master_ctl);
+ break;
+ case TWI_I2C_MODE_COMBINED:
+ iowrite16(iface->command, &iface->regs_base->xmt_data8);
+ iowrite16(MCOMP | MERR | RCVSERV | XMTSERV, &iface->regs_base->int_mask);
+
+ if (iface->writeNum > 0)
+ iowrite16((iface->writeNum + 1) << 6, &iface->regs_base->master_ctl);
+ else
+ iowrite16(0x1 << 6, &iface->regs_base->master_ctl);
+ /* Master enable */
+ writeValue = ioread16(&iface->regs_base->master_ctl) | MEN | RSTART;
+ if (iface->twi_clk > 100)
+ writeValue |= FAST;
+ iowrite16(writeValue, &iface->regs_base->master_ctl);
+ break;
+ default:
+ iowrite16(0, &iface->regs_base->master_ctl);
+ if (size != I2C_SMBUS_QUICK) {
+ /* Don't access xmit data register when this is a
+ * read operation.
+ */
+ if (iface->read_write != I2C_SMBUS_READ) {
+ if (iface->writeNum > 0) {
+ iowrite16(*(iface->transPtr++),
+ &iface->regs_base->xmt_data8);
+ if (iface->writeNum <= 255)
+ iowrite16(iface->writeNum << 6,
+ &iface->regs_base->master_ctl);
+ else {
+ iowrite16(0xff << 6, &iface->regs_base->master_ctl);
+ iface->manual_stop = 1;
+ }
+ iface->writeNum--;
+ } else {
+ iowrite16(iface->command, &iface->regs_base->xmt_data8);
+ iowrite16(1 << 6, &iface->regs_base->master_ctl);
+ }
+ } else {
+ if (iface->readNum > 0 && iface->readNum <= 255)
+ iowrite16(iface->readNum << 6,
+ &iface->regs_base->master_ctl);
+ else if (iface->readNum > 255) {
+ iowrite16(0xff << 6, &iface->regs_base->master_ctl);
+ iface->manual_stop = 1;
+ } else
+ break;
+ }
+ }
+ writeValue = MCOMP | MERR;
+ if (iface->read_write == I2C_SMBUS_READ)
+ writeValue |= RCVSERV;
+ else
+ writeValue |= XMTSERV;
+ iowrite16(writeValue, &iface->regs_base->int_mask);
+
+ /* Master enable */
+ writeValue = ioread16(&iface->regs_base->master_ctl) | MEN |
+ ((iface->read_write == I2C_SMBUS_READ) ? MDIR : 0) |
+ ((iface->twi_clk > 100) ? FAST : 0);
+ iowrite16(writeValue, &iface->regs_base->master_ctl);
+ break;
+ }
+
+ if (polling) {
+ int timeout = 50000;
+
+ for (;;) {
+ irqreturn_t handled = adi_twi_handle_all_interrupts(
+ iface, true);
+ if (handled == IRQ_HANDLED && iface->result)
+ break;
+ if (--timeout == 0) {
+ iface->result = -1;
+ dev_err(&adap->dev, "smbus polling timeout");
+ break;
+ }
+ }
+ } else { /* interrupt driven */
+ while (!iface->result) {
+ if (!wait_for_completion_timeout(&iface->complete,
+ adap->timeout)) {
+ iface->result = -1;
+ dev_err(&adap->dev, "smbus transfer timeout");
+ }
+ }
+ }
+
+ rc = (iface->result >= 0) ? 0 : -1;
+
+ return rc;
+}
+
+/*
+ * Generic I2C SMBus transfer entrypoint
+ */
+static int adi_twi_smbus_xfer(struct i2c_adapter *adap, u16 addr,
+ unsigned short flags, char read_write,
+ u8 command, int size, union i2c_smbus_data *data)
+{
+ return adi_twi_do_smbus_xfer(adap, addr, flags,
+ read_write, command, size, data, false);
+}
+
+static int adi_twi_smbus_xfer_atomic(struct i2c_adapter *adap, u16 addr,
+ unsigned short flags, char read_write,
+ u8 command, int size, union i2c_smbus_data *data)
+{
+ return adi_twi_do_smbus_xfer(adap, addr, flags,
+ read_write, command, size, data, true);
+}
+
+/*
+ * Return what the adapter supports
+ */
+static u32 adi_twi_functionality(struct i2c_adapter *adap)
+{
+ return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
+ I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA |
+ I2C_FUNC_SMBUS_BLOCK_DATA | I2C_FUNC_SMBUS_PROC_CALL |
+ I2C_FUNC_I2C | I2C_FUNC_SMBUS_I2C_BLOCK;
+}
+
+static const struct i2c_algorithm adi_twi_algorithm = {
+ .master_xfer = adi_twi_master_xfer,
+ .master_xfer_atomic = adi_twi_master_xfer_atomic,
+ .smbus_xfer = adi_twi_smbus_xfer,
+ .smbus_xfer_atomic = adi_twi_smbus_xfer_atomic,
+ .functionality = adi_twi_functionality,
+};
+
+#ifdef CONFIG_PM_SLEEP
+static int i2c_adi_twi_suspend(struct device *dev)
+{
+ struct adi_twi_iface *iface = dev_get_drvdata(dev);
+
+ iface->saved_clkdiv = ioread16(&iface->regs_base->clkdiv);
+ iface->saved_control = ioread16(&iface->regs_base->control);
+
+ free_irq(iface->irq, iface);
+
+ /* Disable TWI */
+ iowrite16(iface->saved_control & ~TWI_ENA, &iface->regs_base->control);
+
+ return 0;
+}
+
+static int i2c_adi_twi_resume(struct device *dev)
+{
+ struct adi_twi_iface *iface = dev_get_drvdata(dev);
+
+ int rc = request_irq(iface->irq, adi_twi_interrupt_entry,
+ 0, to_platform_device(dev)->name, iface);
+ if (rc) {
+ dev_err(dev, "Can't get IRQ %d !\n", iface->irq);
+ return -ENODEV;
+ }
+
+ /* Resume TWI interface clock as specified */
+ iowrite16(iface->saved_clkdiv, &iface->regs_base->clkdiv);
+
+ /* Resume TWI */
+ iowrite16(iface->saved_control, &iface->regs_base->control);
+
+ return 0;
+}
+
+static SIMPLE_DEV_PM_OPS(i2c_adi_twi_pm,
+ i2c_adi_twi_suspend, i2c_adi_twi_resume);
+#define I2C_ADI_TWI_PM_OPS (&i2c_adi_twi_pm)
+#else
+#define I2C_ADI_TWI_PM_OPS NULL
+#endif
+
+#ifdef CONFIG_OF
+static const struct of_device_id adi_twi_of_match[] = {
+ {
+ .compatible = "adi,twi",
+ },
+ {},
+};
+MODULE_DEVICE_TABLE(of, adi_twi_of_match);
+#endif
+
+static int i2c_adi_twi_probe(struct platform_device *pdev)
+{
+ struct adi_twi_iface *iface;
+ struct i2c_adapter *p_adap;
+ struct resource *res;
+ const struct of_device_id *match;
+ struct device_node *node = pdev->dev.of_node;
+ int rc;
+ unsigned int clkhilow;
+ u16 writeValue;
+
+ iface = devm_kzalloc(&pdev->dev, sizeof(*iface), GFP_KERNEL);
+ if (!iface)
+ return -ENOMEM;
+
+ spin_lock_init(&(iface->lock));
+
+ match = of_match_device(of_match_ptr(adi_twi_of_match), &pdev->dev);
+ if (match) {
+ if (of_property_read_u32(node, "clock-khz",
+ &iface->twi_clk))
+ iface->twi_clk = 50;
+ } else
+ iface->twi_clk = CONFIG_I2C_ADI_TWI_CLK_KHZ;
+
+ iface->sclk = devm_clk_get(&pdev->dev, "sclk0");
+ if (IS_ERR(iface->sclk)) {
+ if (PTR_ERR(iface->sclk) != -EPROBE_DEFER)
+ dev_err(&pdev->dev, "Missing i2c clock\n");
+ return PTR_ERR(iface->sclk);
+ }
+
+ /* Find and map our resources */
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (res == NULL) {
+ dev_err(&pdev->dev, "Cannot get IORESOURCE_MEM\n");
+ return -ENOENT;
+ }
+
+ iface->regs_base = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(iface->regs_base)) {
+ dev_err(&pdev->dev, "Cannot map IO\n");
+ return PTR_ERR(iface->regs_base);
+ }
+
+ iface->irq = platform_get_irq(pdev, 0);
+ if (iface->irq < 0) {
+ dev_err(&pdev->dev, "No IRQ specified\n");
+ return -ENOENT;
+ }
+
+ p_adap = &iface->adap;
+ p_adap->nr = pdev->id;
+ strscpy(p_adap->name, pdev->name, sizeof(p_adap->name));
+ p_adap->algo = &adi_twi_algorithm;
+ p_adap->algo_data = iface;
+ p_adap->class = I2C_CLASS_DEPRECATED;
+ p_adap->dev.parent = &pdev->dev;
+ p_adap->dev.of_node = node;
+ p_adap->timeout = 5 * HZ;
+ p_adap->retries = 3;
+
+ rc = devm_request_irq(&pdev->dev, iface->irq, adi_twi_interrupt_entry,
+ 0, pdev->name, iface);
+ if (rc) {
+ dev_err(&pdev->dev, "Can't get IRQ %d !\n", iface->irq);
+ rc = -ENODEV;
+ goto out_error;
+ }
+
+ /* Set TWI internal clock as 10MHz */
+ clk_prepare_enable(iface->sclk);
+ if (rc) {
+ dev_err(&pdev->dev, "Could not enable sclk\n");
+ goto out_error;
+ }
+
+ writeValue = ((clk_get_rate(iface->sclk) / 1000 / 1000 + 5) / 10) & 0x7F;
+ iowrite16(writeValue, &iface->regs_base->control);
+
+ /*
+ * We will not end up with a CLKDIV=0 because no one will specify
+ * 20kHz SCL or less in Kconfig now. (5 * 1000 / 20 = 250)
+ */
+ clkhilow = ((10 * 1000 / iface->twi_clk) + 1) / 2;
+
+ /* Set Twi interface clock as specified */
+ writeValue = (clkhilow << 8) | clkhilow;
+ iowrite16(writeValue, &iface->regs_base->clkdiv);
+
+ /* Enable TWI */
+ writeValue = ioread16(&iface->regs_base->control) | TWI_ENA;
+ iowrite16(writeValue, &iface->regs_base->control);
+
+ rc = i2c_add_numbered_adapter(p_adap);
+ if (rc < 0)
+ goto disable_clk;
+
+ platform_set_drvdata(pdev, iface);
+
+ dev_info(&pdev->dev, "ADI on-chip I2C TWI Controller, regs_base@%p\n",
+ iface->regs_base);
+
+ return 0;
+
+disable_clk:
+ clk_disable_unprepare(iface->sclk);
+
+out_error:
+ return rc;
+}
+
+static void i2c_adi_twi_remove(struct platform_device *pdev)
+{
+ struct adi_twi_iface *iface = platform_get_drvdata(pdev);
+
+ clk_disable_unprepare(iface->sclk);
+ i2c_del_adapter(&(iface->adap));
+}
+
+static struct platform_driver i2c_adi_twi_driver = {
+ .probe = i2c_adi_twi_probe,
+ .remove = i2c_adi_twi_remove,
+ .driver = {
+ .name = "i2c-adi-twi",
+ .pm = I2C_ADI_TWI_PM_OPS,
+ .of_match_table = of_match_ptr(adi_twi_of_match),
+ },
+};
+
+static int __init i2c_adi_twi_init(void)
+{
+ return platform_driver_register(&i2c_adi_twi_driver);
+}
+
+static void __exit i2c_adi_twi_exit(void)
+{
+ platform_driver_unregister(&i2c_adi_twi_driver);
+}
+
+subsys_initcall(i2c_adi_twi_init);
+module_exit(i2c_adi_twi_exit);
+
+MODULE_AUTHOR("Bryan Wu, Sonic Zhang");
+MODULE_DESCRIPTION("ADI on-chip I2C TWI Controller Driver");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:i2c-adi-twi");
\ No newline at end of file
--
2.25.1
^ permalink raw reply related [flat|nested] 65+ messages in thread
* Re: [PATCH 15/21] i2c: Add driver for ADI ADSP-SC5xx platforms
2024-09-12 18:25 ` [PATCH 15/21] i2c: Add driver for ADI ADSP-SC5xx platforms Arturs Artamonovs via B4 Relay
@ 2024-09-13 7:59 ` Arnd Bergmann
2024-09-16 7:13 ` Krzysztof Kozlowski
1 sibling, 0 replies; 65+ messages in thread
From: Arnd Bergmann @ 2024-09-13 7:59 UTC (permalink / raw)
To: arturs.artamonovs, Catalin Marinas, Will Deacon, Greg Malysa,
Philipp Zabel, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Utsav Agarwal, Michael Turquette, Stephen Boyd, Linus Walleij,
Bartosz Golaszewski, Thomas Gleixner, Andi Shyti,
Greg Kroah-Hartman, Jiri Slaby, Olof Johansson, soc
Cc: linux-arm-kernel, linux-kernel, devicetree, linux-clk,
open list:GPIO SUBSYSTEM, linux-i2c, linux-serial, adsp-linux,
Nathan Barrett-Morrison
On Thu, Sep 12, 2024, at 18:25, Arturs Artamonovs via B4 Relay wrote:
> +
> +config I2C_ADI_TWI_CLK_KHZ
> + int "ADI TWI I2C clock (kHz)"
> + depends on I2C_ADI_TWI
> + range 21 400
> + default 50
> + help
> + The unit of the TWI clock is kHz.
This does not look like something that should be a compile-time
option, the kernel needs to be able to run on different
configurations.
> +
> +static void adi_twi_handle_interrupt(struct adi_twi_iface *iface,
> + unsigned short twi_int_status,
> + bool polling)
> +{
> + u16 writeValue;
> + unsigned short mast_stat = ioread16(&iface->regs_base->master_stat);
It's a bit unusual to use ioread16()/iowrite16() instead of the
normal readw()/writew().
> + } else if (iface->cur_mode == TWI_I2C_MODE_REPEAT &&
> + iface->cur_msg + 1 < iface->msg_num) {
> +
> + if (iface->pmsg[iface->cur_msg + 1].flags & I2C_M_RD) {
> + writeValue = ioread16(&iface->regs_base->master_ctl)
> + | MDIR;
> + iowrite16(writeValue, &iface->regs_base->master_ctl);
> + } else {
> + writeValue = ioread16(&iface->regs_base->master_ctl)
> + & ~MDIR;
> + iowrite16(writeValue, &iface->regs_base->master_ctl);
The use of a structure instead of register offset macros makes
these lines rather long, especially at five levels of indentation.
Maybe this can be restructured for readability.
> + if (ioread16(&iface->regs_base->master_stat) & SDASEN) {
> + int cnt = 9;
> +
> + do {
> + iowrite16(SCLOVR, &iface->regs_base->master_ctl);
> + udelay(6);
> + iowrite16(0, &iface->regs_base->master_ctl);
> + udelay(6);
> + } while ((ioread16(&iface->regs_base->master_stat) & SDASEN)
Since writes on device mappings are posted, the delay between
the two iowrite16() is not really meaningful, unless you add
another ioread16() or readw() before the delay. Mapping these
with ioremap_np() should also work.
> + iowrite16(SDAOVR | SCLOVR, &iface->regs_base->master_ctl);
> + udelay(6);
> + iowrite16(SDAOVR, &iface->regs_base->master_ctl);
> + udelay(6);
> + iowrite16(0, &iface->regs_base->master_ctl);
> + }
Same here.
> +/* Interrupt handler */
> +static irqreturn_t adi_twi_handle_all_interrupts(struct adi_twi_iface
> *iface,
> + bool polling)
> +{
> + irqreturn_t handled = IRQ_NONE;
> + unsigned short twi_int_status;
> +
> + while (1) {
> + twi_int_status = ioread16(&iface->regs_base->int_stat);
> + if (!twi_int_status)
> + return handled;
> + /* Clear interrupt status */
> + iowrite16(twi_int_status, &iface->regs_base->int_stat);
> + adi_twi_handle_interrupt(iface, twi_int_status, polling);
> + handled = IRQ_HANDLED;
> + }
> +}
> +
> +static irqreturn_t adi_twi_interrupt_entry(int irq, void *dev_id)
> +{
> + struct adi_twi_iface *iface = dev_id;
> + unsigned long flags;
> + irqreturn_t handled;
> +
> + spin_lock_irqsave(&iface->lock, flags);
> + handled = adi_twi_handle_all_interrupts(iface, false);
> + spin_unlock_irqrestore(&iface->lock, flags);
> + return handled;
> +}
Interrupt handlers are called with IRQs disabled, so no
need to turn them off again.
> +static SIMPLE_DEV_PM_OPS(i2c_adi_twi_pm,
> + i2c_adi_twi_suspend, i2c_adi_twi_resume);
> +#define I2C_ADI_TWI_PM_OPS (&i2c_adi_twi_pm)
> +#else
> +#define I2C_ADI_TWI_PM_OPS NULL
> +#endif
Please convert to DEFINE_SIMPLE_DEV_PM_OPS() and remove the
#ifdef.
> +#ifdef CONFIG_OF
> +static const struct of_device_id adi_twi_of_match[] = {
> + {
> + .compatible = "adi,twi",
> + },
> + {},
> +};
> +MODULE_DEVICE_TABLE(of, adi_twi_of_match);
> +#endif
No need to optimize for non-CONFIG_OF builds, we don't
support traditional board files on arm64.
> + match = of_match_device(of_match_ptr(adi_twi_of_match), &pdev->dev);
This of_match_ptr() and the second one later should also
get removed then.
> \ No newline at end of file
>
Whitespace damage.
Arnd
^ permalink raw reply [flat|nested] 65+ messages in thread
* Re: [PATCH 15/21] i2c: Add driver for ADI ADSP-SC5xx platforms
2024-09-12 18:25 ` [PATCH 15/21] i2c: Add driver for ADI ADSP-SC5xx platforms Arturs Artamonovs via B4 Relay
2024-09-13 7:59 ` Arnd Bergmann
@ 2024-09-16 7:13 ` Krzysztof Kozlowski
1 sibling, 0 replies; 65+ messages in thread
From: Krzysztof Kozlowski @ 2024-09-16 7:13 UTC (permalink / raw)
To: arturs.artamonovs, Catalin Marinas, Will Deacon, Greg Malysa,
Philipp Zabel, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Utsav Agarwal, Michael Turquette, Stephen Boyd, Linus Walleij,
Bartosz Golaszewski, Thomas Gleixner, Andi Shyti,
Greg Kroah-Hartman, Jiri Slaby, Arnd Bergmann, Olof Johansson,
soc
Cc: linux-arm-kernel, linux-kernel, devicetree, linux-clk, linux-gpio,
linux-i2c, linux-serial, adsp-linux, Nathan Barrett-Morrison
On 12/09/2024 20:25, Arturs Artamonovs via B4 Relay wrote:
> From: Arturs Artamonovs <arturs.artamonovs@analog.com>
>
> Add support for I2C on SC5xx
>
> Signed-off-by: Arturs Artamonovs <Arturs.Artamonovs@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>
As in all patches - chain looks wrong.
> ---
> drivers/i2c/busses/Kconfig | 17 +
> drivers/i2c/busses/Makefile | 1 +
> drivers/i2c/busses/i2c-adi-twi.c | 940 +++++++++++++++++++++++++++++++++++++++
> 3 files changed, 958 insertions(+)
> +static SIMPLE_DEV_PM_OPS(i2c_adi_twi_pm,
> + i2c_adi_twi_suspend, i2c_adi_twi_resume);
> +#define I2C_ADI_TWI_PM_OPS (&i2c_adi_twi_pm)
> +#else
> +#define I2C_ADI_TWI_PM_OPS NULL
> +#endif
> +
> +#ifdef CONFIG_OF
Drop
> +static const struct of_device_id adi_twi_of_match[] = {
> + {
> + .compatible = "adi,twi",
> + },
> + {},
> +};
> +MODULE_DEVICE_TABLE(of, adi_twi_of_match);
> +#endif
> +
> +static int i2c_adi_twi_probe(struct platform_device *pdev)
> +{
> + struct adi_twi_iface *iface;
> + struct i2c_adapter *p_adap;
> + struct resource *res;
> + const struct of_device_id *match;
> + struct device_node *node = pdev->dev.of_node;
> + int rc;
> + unsigned int clkhilow;
> + u16 writeValue;
> +
> + iface = devm_kzalloc(&pdev->dev, sizeof(*iface), GFP_KERNEL);
> + if (!iface)
> + return -ENOMEM;
> +
> + spin_lock_init(&(iface->lock));
> +
> + match = of_match_device(of_match_ptr(adi_twi_of_match), &pdev->dev);
Drop of_mathc_ptr
> + if (match) {
> + if (of_property_read_u32(node, "clock-khz",
Uh? I really do not get what is this.
> + &iface->twi_clk))
Really odd alignment.
> + iface->twi_clk = 50;
> + } else
> + iface->twi_clk = CONFIG_I2C_ADI_TWI_CLK_KHZ;
> +
> + iface->sclk = devm_clk_get(&pdev->dev, "sclk0");
> + if (IS_ERR(iface->sclk)) {
> + if (PTR_ERR(iface->sclk) != -EPROBE_DEFER)
> + dev_err(&pdev->dev, "Missing i2c clock\n");
Eh... there is nowhere such code. Please work with upstream code, not
downstream. When writing drivers take UPSTREAM driver as template.
Whatever you have in downstream is not a good to send to us.
Syntax is return dev_err_probe.
> + return PTR_ERR(iface->sclk);
> + }
> +
> + /* Find and map our resources */
> + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> + if (res == NULL) {
> + dev_err(&pdev->dev, "Cannot get IORESOURCE_MEM\n");
> + return -ENOENT;
> + }
> +
> + iface->regs_base = devm_ioremap_resource(&pdev->dev, res);
Combine these two calls with proper helper.
> + if (IS_ERR(iface->regs_base)) {
> + dev_err(&pdev->dev, "Cannot map IO\n");
> + return PTR_ERR(iface->regs_base);
> + }
> +
> + iface->irq = platform_get_irq(pdev, 0);
> + if (iface->irq < 0) {
Here you have correct, other patch has a bug. That makes me wonder about
consistency of this code. There are several other hints that people
wrote it with quite different coding style.
> + dev_err(&pdev->dev, "No IRQ specified\n");
> + return -ENOENT;
No. return the error. Anyway, that's never a correct errno. Read
description of this errno: no such file. This is not a file you are
getting here.
This comment applies to all your code.
> + }
> +
> + p_adap = &iface->adap;
> + p_adap->nr = pdev->id;
> + strscpy(p_adap->name, pdev->name, sizeof(p_adap->name));
> + p_adap->algo = &adi_twi_algorithm;
> + p_adap->algo_data = iface;
> + p_adap->class = I2C_CLASS_DEPRECATED;
> + p_adap->dev.parent = &pdev->dev;
> + p_adap->dev.of_node = node;
> + p_adap->timeout = 5 * HZ;
> + p_adap->retries = 3;
> +
> + rc = devm_request_irq(&pdev->dev, iface->irq, adi_twi_interrupt_entry,
> + 0, pdev->name, iface);
> + if (rc) {
> + dev_err(&pdev->dev, "Can't get IRQ %d !\n", iface->irq);
> + rc = -ENODEV;
???
Sorry, this driver is in really poor shape.
> + goto out_error;
> + }
> +
> + /* Set TWI internal clock as 10MHz */
> + clk_prepare_enable(iface->sclk);
> + if (rc) {
> + dev_err(&pdev->dev, "Could not enable sclk\n");
> + goto out_error;
return
> + }
> +
> + writeValue = ((clk_get_rate(iface->sclk) / 1000 / 1000 + 5) / 10) & 0x7F;
No camelCase. Please follow Linux coding style.
> + iowrite16(writeValue, &iface->regs_base->control);
> +
> + /*
> + * We will not end up with a CLKDIV=0 because no one will specify
> + * 20kHz SCL or less in Kconfig now. (5 * 1000 / 20 = 250)
> + */
> + clkhilow = ((10 * 1000 / iface->twi_clk) + 1) / 2;
> +
> + /* Set Twi interface clock as specified */
> + writeValue = (clkhilow << 8) | clkhilow;
> + iowrite16(writeValue, &iface->regs_base->clkdiv);
> +
> + /* Enable TWI */
> + writeValue = ioread16(&iface->regs_base->control) | TWI_ENA;
> + iowrite16(writeValue, &iface->regs_base->control);
> +
> + rc = i2c_add_numbered_adapter(p_adap);
> + if (rc < 0)
> + goto disable_clk;
> +
> + platform_set_drvdata(pdev, iface);
> +
> + dev_info(&pdev->dev, "ADI on-chip I2C TWI Controller, regs_base@%p\n",
> + iface->regs_base);
Drop. Driver should be silent on success.
> +
> + return 0;
> +
> +disable_clk:
> + clk_disable_unprepare(iface->sclk);
devm_clk_get_enabled
> +
> +out_error:
Drop
> + return rc;
> +}
> +
> +static void i2c_adi_twi_remove(struct platform_device *pdev)
> +{
> + struct adi_twi_iface *iface = platform_get_drvdata(pdev);
> +
> + clk_disable_unprepare(iface->sclk);
> + i2c_del_adapter(&(iface->adap));
> +}
> +
> +static struct platform_driver i2c_adi_twi_driver = {
> + .probe = i2c_adi_twi_probe,
> + .remove = i2c_adi_twi_remove,
> + .driver = {
> + .name = "i2c-adi-twi",
> + .pm = I2C_ADI_TWI_PM_OPS,
> + .of_match_table = of_match_ptr(adi_twi_of_match),
Drop of_match_ptr. None of your other code has it, right? This should
make you wonder.
> + },
> +};
> +
> +static int __init i2c_adi_twi_init(void)
> +{
> + return platform_driver_register(&i2c_adi_twi_driver);
> +}
> +
> +static void __exit i2c_adi_twi_exit(void)
> +{
> + platform_driver_unregister(&i2c_adi_twi_driver);
> +}
> +
> +subsys_initcall(i2c_adi_twi_init);
No, i2c driver can be just module platform driver.
> +module_exit(i2c_adi_twi_exit);
> +
> +MODULE_AUTHOR("Bryan Wu, Sonic Zhang");
> +MODULE_DESCRIPTION("ADI on-chip I2C TWI Controller Driver");
> +MODULE_LICENSE("GPL v2");
> +MODULE_ALIAS("platform:i2c-adi-twi");
You should not need MODULE_ALIAS() in normal cases. If you need it,
usually it means your device ID table is wrong (e.g. misses either
entries or MODULE_DEVICE_TABLE()). MODULE_ALIAS() is not a substitute
for incomplete ID table.
> \ No newline at end of file
>
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 65+ messages in thread
* [PATCH 16/21] dt-bindings: i2c: add i2c/twi driver documentation
2024-09-12 18:24 [PATCH 00/21] Adding support of ADI ARMv8 ADSP-SC598 SoC Arturs Artamonovs via B4 Relay
` (14 preceding siblings ...)
2024-09-12 18:25 ` [PATCH 15/21] i2c: Add driver for ADI ADSP-SC5xx platforms Arturs Artamonovs via B4 Relay
@ 2024-09-12 18:25 ` Arturs Artamonovs via B4 Relay
2024-09-13 7:24 ` Arnd Bergmann
2024-09-12 18:25 ` [PATCH 17/21] serial: adi,uart: Add driver for ADI ADSP-SC5xx Arturs Artamonovs via B4 Relay
` (7 subsequent siblings)
23 siblings, 1 reply; 65+ messages in thread
From: Arturs Artamonovs via B4 Relay @ 2024-09-12 18:25 UTC (permalink / raw)
To: Catalin Marinas, Will Deacon, Greg Malysa, Philipp Zabel,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Utsav Agarwal,
Michael Turquette, Stephen Boyd, Linus Walleij,
Bartosz Golaszewski, Thomas Gleixner, Andi Shyti,
Greg Kroah-Hartman, Jiri Slaby, Arnd Bergmann, Olof Johansson,
soc
Cc: linux-arm-kernel, linux-kernel, devicetree, linux-clk, linux-gpio,
linux-i2c, linux-serial, Arturs Artamonovs, adsp-linux,
Arturs Artamonovs, Nathan Barrett-Morrison
From: Arturs Artamonovs <arturs.artamonovs@analog.com>
Add I2C driver bindings.
Signed-off-by: Arturs Artamonovs <Arturs.Artamonovs@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>
---
Documentation/devicetree/bindings/i2c/adi,twi.yaml | 71 ++++++++++++++++++++++
1 file changed, 71 insertions(+)
diff --git a/Documentation/devicetree/bindings/i2c/adi,twi.yaml b/Documentation/devicetree/bindings/i2c/adi,twi.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..e935b09066cf806c89a796fdd5fe73ee0b644432
--- /dev/null
+++ b/Documentation/devicetree/bindings/i2c/adi,twi.yaml
@@ -0,0 +1,71 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/i2c/adi,twi.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Analog Devices I2C Peripheral for SC5XX Processor Family
+
+maintainers:
+ - Arturs Artamonovs <arturs.artamonovs@analog.com>
+ - Utsav Agarwal <Utsav.Agarwal@analog.com>
+
+description: |
+ Analog Devices I2C Peripheral driver for SC5XX Processor Family
+
+properties:
+ compatible:
+ enum:
+ - adi,twi
+
+ "#address-cells":
+ const: 1
+
+ "#size-cells":
+ const: 0
+
+ reg:
+ maxItems: 1
+
+ interrupts:
+ maxItems: 1
+
+ clock-khz:
+ $ref: /schemas/types.yaml#/definitions/uint32
+
+ clocks:
+ maxItems: 1
+
+ clock-names:
+ maxItems: 1
+
+required:
+ - compatible
+ - "#address-cells"
+ - "#size-cells"
+ - reg
+ - interrupts
+ - clock-khz
+ - clocks
+ - clock-names
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/interrupt-controller/arm-gic.h>
+ #include <dt-bindings/interrupt-controller/irq.h>
+ #include <dt-bindings/clock/adi-sc5xx-clock.h>
+
+ i2c0: twi@31001400 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "adi,twi";
+ reg = <0x31001400 0xFF>;
+ interrupts = <GIC_SPI 150 IRQ_TYPE_LEVEL_HIGH>;
+ clock-khz = <100>;
+ clocks = <&clk ADSP_SC598_CLK_CGU0_SCLK0>;
+ clock-names = "sclk0";
+ status = "disabled";
+ };
+
--
2.25.1
^ permalink raw reply related [flat|nested] 65+ messages in thread
* Re: [PATCH 16/21] dt-bindings: i2c: add i2c/twi driver documentation
2024-09-12 18:25 ` [PATCH 16/21] dt-bindings: i2c: add i2c/twi driver documentation Arturs Artamonovs via B4 Relay
@ 2024-09-13 7:24 ` Arnd Bergmann
0 siblings, 0 replies; 65+ messages in thread
From: Arnd Bergmann @ 2024-09-13 7:24 UTC (permalink / raw)
To: arturs.artamonovs, Catalin Marinas, Will Deacon, Greg Malysa,
Philipp Zabel, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Utsav Agarwal, Michael Turquette, Stephen Boyd, Linus Walleij,
Bartosz Golaszewski, Thomas Gleixner, Andi Shyti,
Greg Kroah-Hartman, Jiri Slaby, Olof Johansson, soc
Cc: linux-arm-kernel, linux-kernel, devicetree, linux-clk,
open list:GPIO SUBSYSTEM, linux-i2c, linux-serial, adsp-linux,
Nathan Barrett-Morrison
On Thu, Sep 12, 2024, at 18:25, Arturs Artamonovs via B4 Relay wrote:
> +
> +properties:
> + compatible:
> + enum:
> + - adi,twi
> +
The "adi,twi" string is not specific enough to identify a particular
implementation, the name should either include the version of the
IP block that was used in each chip, or (if that is not public
knowledge) the identifier of the chip it was integrated in.
Arnd
^ permalink raw reply [flat|nested] 65+ messages in thread
* [PATCH 17/21] serial: adi,uart: Add driver for ADI ADSP-SC5xx
2024-09-12 18:24 [PATCH 00/21] Adding support of ADI ARMv8 ADSP-SC598 SoC Arturs Artamonovs via B4 Relay
` (15 preceding siblings ...)
2024-09-12 18:25 ` [PATCH 16/21] dt-bindings: i2c: add i2c/twi driver documentation Arturs Artamonovs via B4 Relay
@ 2024-09-12 18:25 ` Arturs Artamonovs via B4 Relay
2024-09-12 18:25 ` [PATCH 18/21] dt-bindings: serial: adi,uart4: add adi,uart4 driver documentation Arturs Artamonovs via B4 Relay
` (6 subsequent siblings)
23 siblings, 0 replies; 65+ messages in thread
From: Arturs Artamonovs via B4 Relay @ 2024-09-12 18:25 UTC (permalink / raw)
To: Catalin Marinas, Will Deacon, Greg Malysa, Philipp Zabel,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Utsav Agarwal,
Michael Turquette, Stephen Boyd, Linus Walleij,
Bartosz Golaszewski, Thomas Gleixner, Andi Shyti,
Greg Kroah-Hartman, Jiri Slaby, Arnd Bergmann, Olof Johansson,
soc
Cc: linux-arm-kernel, linux-kernel, devicetree, linux-clk, linux-gpio,
linux-i2c, linux-serial, Arturs Artamonovs, adsp-linux,
Arturs Artamonovs, Nathan Barrett-Morrison
From: Arturs Artamonovs <arturs.artamonovs@analog.com>
Adding UART driver,supports all ADSP-SC5xx SoC family
- Support FIFO mode
- Support earlyprintk
- Support Enable Divide By One support, for higher clock resolutions.
Signed-off-by: Arturs Artamonovs <Arturs.Artamonovs@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>
---
drivers/tty/serial/Kconfig | 19 +-
drivers/tty/serial/Makefile | 1 +
drivers/tty/serial/adi_uart.c | 1045 ++++++++++++++++++++++++++++++++++++++
include/uapi/linux/serial_core.h | 3 +
4 files changed, 1067 insertions(+), 1 deletion(-)
diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig
index 28e4beeabf8f373fc76e09ea7d1c9d55a66f4964..1d1d8fc808969c721d5931127d9294fb17d9c249 100644
--- a/drivers/tty/serial/Kconfig
+++ b/drivers/tty/serial/Kconfig
@@ -471,6 +471,23 @@ config SERIAL_SA1100_CONSOLE
your boot loader (lilo or loadlin) about how to pass options to the
kernel at boot time.)
+config SERIAL_ADI_UART
+ tristate "ADI uart serial port support"
+ depends on ARCH_SC59X = y || ARCH_SC59X_64 = y
+ select SERIAL_CORE
+ select SERIAL_CORE_CONSOLE
+ help
+ Add support for the built-in adi uart driver.
+
+config SERIAL_ADI_UART_CONSOLE
+ bool "Console on ADI uart serial port"
+ depends on SERIAL_ADI_UART
+ default y
+ select SERIAL_CORE_CONSOLE
+ help
+ If you have enabled the ADI UART serial port, you can
+ make it the console by answering Y to this option.
+
config SERIAL_IMX
tristate "IMX serial port support"
depends on ARCH_MXC || COMPILE_TEST
@@ -771,7 +788,7 @@ config SERIAL_CPM
depends on CPM2 || CPM1
select SERIAL_CORE
help
- This driver supports the SCC and SMC serial ports on Motorola
+ This driver supports the SCC and SMC serial ports on Motorola
embedded PowerPC that contain a CPM1 (8xx) or CPM2 (8xxx)
config SERIAL_CPM_CONSOLE
diff --git a/drivers/tty/serial/Makefile b/drivers/tty/serial/Makefile
index 6ff74f0a9530c4f6e058a848f74084f3b63a730a..9d4920b51b55af70c285d9bcaef53cc01a69b898 100644
--- a/drivers/tty/serial/Makefile
+++ b/drivers/tty/serial/Makefile
@@ -49,6 +49,7 @@ obj-$(CONFIG_SERIAL_JSM) += jsm/
obj-$(CONFIG_SERIAL_LANTIQ) += lantiq.o
obj-$(CONFIG_SERIAL_LITEUART) += liteuart.o
obj-$(CONFIG_SERIAL_HS_LPC32XX) += lpc32xx_hs.o
+obj-$(CONFIG_SERIAL_ADI_UART) += adi_uart.o
obj-$(CONFIG_SERIAL_MAX3100) += max3100.o
obj-$(CONFIG_SERIAL_MAX310X) += max310x.o
obj-$(CONFIG_SERIAL_MCF) += mcf.o
diff --git a/drivers/tty/serial/adi_uart.c b/drivers/tty/serial/adi_uart.c
new file mode 100644
index 0000000000000000000000000000000000000000..dfbc7dcfd6169a299d4b1580e56f5ba0a3d8cc12
--- /dev/null
+++ b/drivers/tty/serial/adi_uart.c
@@ -0,0 +1,1045 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * ADI On-Chip Two Wire Interface Driver
+ *
+ * Copyright 2022-2024 - Analog Devices Inc.
+ */
+
+#include <linux/circ_buf.h>
+#include <linux/clk.h>
+#include <linux/dmaengine.h>
+#include <linux/gpio.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/serial_core.h>
+#include <linux/tty_flip.h>
+
+#if defined(CONFIG_SERIAL_ADI_UART_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
+#define SUPPORT_SYSRQ
+#endif
+
+#define DRIVER_NAME "adi-uart"
+
+struct adi_uart_serial_port {
+ struct uart_port port;
+ struct device *dev;
+ unsigned int old_status;
+ int tx_irq;
+ int rx_irq;
+ int status_irq;
+ unsigned int lsr;
+ unsigned int hwflow_mode;
+ struct gpio_desc *hwflow_en_pin;
+ bool hwflow_en;
+ /* Use enable-divide-by-one in divisor? */
+ bool edbo;
+ struct clk *clk;
+};
+
+#define ADI_UART_NO_HWFLOW 0
+#define ADI_UART_HWFLOW_PERI 1
+
+#define ADI_UART_NR_PORTS 4
+static struct adi_uart_serial_port *adi_uart_serial_ports[ADI_UART_NR_PORTS];
+
+/* UART_CTL Masks */
+#define UCEN 0x1 /* Enable UARTx Clocks */
+#define LOOP_ENA 0x2 /* Loopback Mode Enable */
+#define UMOD_MDB 0x10 /* Enable MDB Mode */
+#define UMOD_IRDA 0x20 /* Enable IrDA Mode */
+#define UMOD_MASK 0x30 /* Uart Mode Mask */
+#define WLS(x) (((x-5) & 0x03) << 8) /* Word Length Select */
+#define WLS_MASK 0x300 /* Word length Select Mask */
+#define WLS_OFFSET 8 /* Word length Select Offset */
+#define STB 0x1000 /* Stop Bits */
+#define STBH 0x2000 /* Half Stop Bits */
+#define PEN 0x4000 /* Parity Enable */
+#define EPS 0x8000 /* Even Parity Select */
+#define STP 0x10000 /* Stick Parity */
+#define FPE 0x20000 /* Force Parity Error On Transmit */
+#define FFE 0x40000 /* Force Framing Error On Transmit */
+#define SB 0x80000 /* Set Break */
+#define LCR_MASK (SB | STP | EPS | PEN | STB | WLS_MASK)
+#define FCPOL 0x400000 /* Flow Control Pin Polarity */
+#define RPOLC 0x800000 /* IrDA RX Polarity Change */
+#define TPOLC 0x1000000 /* IrDA TX Polarity Change */
+#define MRTS 0x2000000 /* Manual Request To Send */
+#define XOFF 0x4000000 /* Transmitter Off */
+#define ARTS 0x8000000 /* Automatic Request To Send */
+#define ACTS 0x10000000 /* Automatic Clear To Send */
+#define RFIT 0x20000000 /* Receive FIFO IRQ Threshold */
+#define RFRT 0x40000000 /* Receive FIFO RTS Threshold */
+
+/* UART_STAT Masks */
+#define DR 0x01 /* Data Ready */
+#define OE 0x02 /* Overrun Error */
+#define PE 0x04 /* Parity Error */
+#define FE 0x08 /* Framing Error */
+#define BI 0x10 /* Break Interrupt */
+#define THRE 0x20 /* THR Empty */
+#define TEMT 0x80 /* TSR and UART_THR Empty */
+#define TFI 0x100 /* Transmission Finished Indicator */
+
+#define ASTKY 0x200 /* Address Sticky */
+#define ADDR 0x400 /* Address bit status */
+#define RO 0x800 /* Reception Ongoing */
+#define SCTS 0x1000 /* Sticky CTS */
+#define CTS 0x10000 /* Clear To Send */
+#define RFCS 0x20000 /* Receive FIFO Count Status */
+
+/* UART_CLOCK Masks */
+#define EDBO 0x80000000 /* Enable Devide by One */
+
+/* UART_IER Masks */
+#define ERBFI 0x01 /* Enable Receive Buffer Full Interrupt */
+#define ETBEI 0x02 /* Enable Transmit Buffer Empty Interrupt */
+#define ELSI 0x04 /* Enable RX Status Interrupt */
+#define EDSSI 0x08 /* Enable Modem Status Interrupt */
+#define EDTPTI 0x10 /* Enable DMA Transmit PIRQ Interrupt */
+#define ETFI 0x20 /* Enable Transmission Finished Interrupt */
+#define ERFCI 0x40 /* Enable Receive FIFO Count Interrupt */
+
+# define OFFSET_REDIV 0x00 /* Version ID Register */
+# define OFFSET_CTL 0x04 /* Control Register */
+# define OFFSET_STAT 0x08 /* Status Register */
+# define OFFSET_SCR 0x0C /* SCR Scratch Register */
+# define OFFSET_CLK 0x10 /* Clock Rate Register */
+# define OFFSET_IER 0x14 /* Interrupt Enable Register */
+# define OFFSET_IER_SET 0x18 /* Set Interrupt Enable Register */
+# define OFFSET_IER_CLEAR 0x1C /* Clear Interrupt Enable Register */
+# define OFFSET_RBR 0x20 /* Receive Buffer register */
+# define OFFSET_THR 0x24 /* Transmit Holding register */
+
+#define UART_GET_CHAR(p) readl(p->port.membase + OFFSET_RBR)
+#define UART_GET_CLK(p) readl(p->port.membase + OFFSET_CLK)
+#define UART_GET_CTL(p) readl(p->port.membase + OFFSET_CTL)
+#define UART_GET_GCTL(p) UART_GET_CTL(p)
+#define UART_GET_LCR(p) UART_GET_CTL(p)
+#define UART_GET_MCR(p) UART_GET_CTL(p)
+#define UART_GET_STAT(p) readl(p->port.membase + OFFSET_STAT)
+#define UART_GET_MSR(p) UART_GET_STAT(p)
+
+#define UART_PUT_CHAR(p, v) writel(v, p->port.membase + OFFSET_THR)
+#define UART_PUT_CLK(p, v) writel(v, p->port.membase + OFFSET_CLK)
+#define UART_PUT_CTL(p, v) writel(v, p->port.membase + OFFSET_CTL)
+#define UART_PUT_GCTL(p, v) UART_PUT_CTL(p, v)
+#define UART_PUT_LCR(p, v) UART_PUT_CTL(p, v)
+#define UART_PUT_MCR(p, v) UART_PUT_CTL(p, v)
+#define UART_PUT_STAT(p, v) writel(v, p->port.membase + OFFSET_STAT)
+
+#define UART_CLEAR_IER(p, v) writel(v, p->port.membase + OFFSET_IER_CLEAR)
+#define UART_GET_IER(p) readl(p->port.membase + OFFSET_IER)
+#define UART_SET_IER(p, v) writel(v, p->port.membase + OFFSET_IER_SET)
+
+#define UART_CLEAR_LSR(p) UART_PUT_STAT(p, -1)
+#define UART_GET_LSR(p) UART_GET_STAT(p)
+#define UART_PUT_LSR(p, v) UART_PUT_STAT(p, v)
+
+/* This handles hard CTS/RTS */
+#define UART_CLEAR_SCTS(p) UART_PUT_STAT(p, SCTS)
+#define UART_GET_CTS(x) (UART_GET_MSR(x) & CTS)
+#define UART_DISABLE_RTS(x) UART_PUT_MCR(x, UART_GET_MCR(x) & ~(ARTS | MRTS))
+#define UART_ENABLE_RTS(x) UART_PUT_MCR(x, UART_GET_MCR(x) | MRTS | ARTS)
+#define UART_ENABLE_INTS(x, v) UART_SET_IER(x, v)
+#define UART_DISABLE_INTS(x) UART_CLEAR_IER(x, 0xF)
+
+#define DMA_RX_XCOUNT 512
+#define DMA_RX_YCOUNT (PAGE_SIZE / DMA_RX_XCOUNT)
+
+#define DMA_RX_FLUSH_JIFFIES (msecs_to_jiffies(50))
+
+
+static void adi_uart_serial_tx_chars(struct adi_uart_serial_port *uart);
+static void adi_uart_serial_reset_irda(struct uart_port *port);
+
+
+static struct adi_uart_serial_port *to_adi_serial_port(struct uart_port *port)
+{
+ return container_of(port, struct adi_uart_serial_port, port);
+}
+
+static unsigned int adi_uart_serial_get_mctrl(struct uart_port *port)
+{
+ struct adi_uart_serial_port *uart = to_adi_serial_port(port);
+
+ if (!uart->hwflow_mode || !uart->hwflow_en)
+ return TIOCM_CTS | TIOCM_DSR | TIOCM_CAR;
+
+ /* CTS PIN is negative assertive. */
+ if (UART_GET_CTS(uart))
+ return TIOCM_CTS | TIOCM_DSR | TIOCM_CAR;
+ else
+ return TIOCM_DSR | TIOCM_CAR;
+}
+
+static void adi_uart_serial_set_mctrl(struct uart_port *port,
+ unsigned int mctrl)
+{
+ struct adi_uart_serial_port *uart = to_adi_serial_port(port);
+
+ if (!uart->hwflow_mode || !uart->hwflow_en)
+ return;
+
+ /* RTS PIN is negative assertive. */
+ if (mctrl & TIOCM_RTS)
+ UART_ENABLE_RTS(uart);
+ else
+ UART_DISABLE_RTS(uart);
+}
+
+/*
+ * Handle any change of modem status signal.
+ */
+static irqreturn_t adi_uart_serial_mctrl_cts_int(int irq, void *dev_id)
+{
+ struct adi_uart_serial_port *uart = dev_id;
+ unsigned int status = adi_uart_serial_get_mctrl(&uart->port);
+ struct tty_struct *tty = uart->port.state->port.tty;
+
+ if (uart->hwflow_mode == ADI_UART_HWFLOW_PERI) {
+ UART_CLEAR_SCTS(uart);
+ if (tty->hw_stopped) {
+ if (status) {
+ tty->hw_stopped = 0;
+ uart_write_wakeup(&uart->port);
+ }
+ } else {
+ if (!status)
+ tty->hw_stopped = 1;
+ }
+ }
+
+ uart_handle_cts_change(&uart->port, status & TIOCM_CTS);
+
+ return IRQ_HANDLED;
+}
+
+/*
+ * interrupts are disabled on entry
+ */
+static void adi_uart_serial_stop_tx(struct uart_port *port)
+{
+ struct adi_uart_serial_port *uart = to_adi_serial_port(port);
+
+ while (!(UART_GET_LSR(uart) & TEMT))
+ cpu_relax();
+
+ UART_PUT_LSR(uart, TFI);
+ UART_CLEAR_IER(uart, ETBEI);
+}
+
+/*
+ * port is locked and interrupts are disabled
+ */
+static void adi_uart_serial_start_tx(struct uart_port *port)
+{
+ struct adi_uart_serial_port *uart = to_adi_serial_port(port);
+ struct tty_struct *tty = uart->port.state->port.tty;
+
+ /*
+ * To avoid losting RX interrupt, we reset IR function
+ * before sending data.
+ */
+ if (tty->termios.c_line == N_IRDA)
+ adi_uart_serial_reset_irda(port);
+
+ UART_SET_IER(uart, ETBEI);
+ adi_uart_serial_tx_chars(uart);
+}
+
+/*
+ * Interrupts are enabled
+ */
+static void adi_uart_serial_stop_rx(struct uart_port *port)
+{
+ struct adi_uart_serial_port *uart = to_adi_serial_port(port);
+
+ UART_CLEAR_IER(uart, ERBFI);
+}
+
+/*
+ * Set the modem control timer to fire immediately.
+ */
+static void adi_uart_serial_enable_ms(struct uart_port *port)
+{
+}
+
+static void adi_uart_serial_rx_chars(struct adi_uart_serial_port *uart)
+{
+ unsigned int status, ch, flg;
+
+ status = UART_GET_LSR(uart);
+ UART_CLEAR_LSR(uart);
+
+ ch = UART_GET_CHAR(uart);
+ uart->port.icount.rx++;
+
+ if (status & BI) {
+ uart->port.icount.brk++;
+ if (uart_handle_break(&uart->port))
+ goto ignore_char;
+ status &= ~(PE | FE);
+ }
+ if (status & PE)
+ uart->port.icount.parity++;
+ if (status & OE)
+ uart->port.icount.overrun++;
+ if (status & FE)
+ uart->port.icount.frame++;
+
+ status &= uart->port.read_status_mask;
+
+ if (status & BI)
+ flg = TTY_BREAK;
+ else if (status & PE)
+ flg = TTY_PARITY;
+ else if (status & FE)
+ flg = TTY_FRAME;
+ else
+ flg = TTY_NORMAL;
+
+ if (uart_handle_sysrq_char(&uart->port, ch))
+ goto ignore_char;
+
+ uart_insert_char(&uart->port, status, OE, ch, flg);
+
+ ignore_char:
+ tty_flip_buffer_push(&uart->port.state->port);
+}
+
+static void adi_uart_serial_tx_chars(struct adi_uart_serial_port *uart)
+{
+ struct tty_port *tport = &uart->port.state->port;
+ unsigned char c;
+
+ if (kfifo_is_empty(&tport->xmit_fifo) || uart_tx_stopped(&uart->port)) {
+ /* Clear TFI bit */
+ UART_PUT_LSR(uart, TFI);
+ /* Anomaly notes:
+ * 05000215 - we always clear ETBEI within last UART TX
+ * interrupt to end a string. It is always set
+ * when start a new tx.
+ */
+ UART_CLEAR_IER(uart, ETBEI);
+ return;
+ }
+
+ if (uart->port.x_char) {
+ UART_PUT_CHAR(uart, uart->port.x_char);
+ uart->port.icount.tx++;
+ uart->port.x_char = 0;
+ }
+
+ if (UART_GET_LSR(uart) & THRE) {
+ /* pop data from fifo */
+ if (kfifo_get(&tport->xmit_fifo, &c)) {
+ UART_PUT_CHAR(uart, c);
+ uart->port.icount.tx++;
+ }
+ }
+
+ if (kfifo_len(&tport->xmit_fifo) < WAKEUP_CHARS)
+ uart_write_wakeup(&uart->port);
+}
+
+static irqreturn_t adi_uart_serial_rx_int(int irq, void *dev_id)
+{
+ struct adi_uart_serial_port *uart = dev_id;
+
+ while (UART_GET_LSR(uart) & DR)
+ adi_uart_serial_rx_chars(uart);
+
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t adi_uart_serial_tx_int(int irq, void *dev_id)
+{
+ struct adi_uart_serial_port *uart = dev_id;
+
+ spin_lock(&uart->port.lock);
+ if (UART_GET_LSR(uart) & THRE)
+ adi_uart_serial_tx_chars(uart);
+ spin_unlock(&uart->port.lock);
+
+ return IRQ_HANDLED;
+}
+
+/*
+ * Return TIOCSER_TEMT when transmitter is not busy.
+ */
+static unsigned int adi_uart_serial_tx_empty(struct uart_port *port)
+{
+ struct adi_uart_serial_port *uart = to_adi_serial_port(port);
+ unsigned int lsr;
+
+ lsr = UART_GET_LSR(uart);
+ if (lsr & TEMT)
+ return TIOCSER_TEMT;
+ else
+ return 0;
+}
+
+static void adi_uart_serial_break_ctl(struct uart_port *port, int break_state)
+{
+ struct adi_uart_serial_port *uart = to_adi_serial_port(port);
+ u32 lcr = UART_GET_LCR(uart);
+
+ if (break_state)
+ lcr |= SB;
+ else
+ lcr &= ~SB;
+ UART_PUT_LCR(uart, lcr);
+}
+
+static int adi_uart_serial_startup(struct uart_port *port)
+{
+ struct adi_uart_serial_port *uart = to_adi_serial_port(port);
+ int ret;
+
+ ret = clk_prepare_enable(uart->clk);
+ if (ret)
+ return ret;
+
+ if (uart->hwflow_mode == ADI_UART_HWFLOW_PERI) {
+ /* CTS RTS PINs are negative assertive. */
+ UART_PUT_MCR(uart, UART_GET_MCR(uart) | ACTS);
+ UART_SET_IER(uart, EDSSI);
+ }
+
+ UART_SET_IER(uart, ERBFI);
+ return 0;
+}
+
+static void adi_uart_serial_shutdown(struct uart_port *port)
+{
+ struct adi_uart_serial_port *uart = to_adi_serial_port(port);
+
+ dev_dbg(uart->dev, "in serial_shutdown\n");
+
+ clk_disable_unprepare(uart->clk);
+}
+
+static void adi_uart_serial_set_termios(struct uart_port *port,
+ struct ktermios *termios, const struct ktermios *old)
+{
+ struct adi_uart_serial_port *uart = to_adi_serial_port(port);
+ unsigned long flags;
+ unsigned int baud, quot;
+ unsigned int ier, lcr = 0;
+ unsigned long timeout;
+
+ if (uart->hwflow_mode == ADI_UART_HWFLOW_PERI)
+ termios->c_cflag |= CRTSCTS;
+
+ switch (termios->c_cflag & CSIZE) {
+ case CS8:
+ lcr = WLS(8);
+ break;
+ case CS7:
+ lcr = WLS(7);
+ break;
+ case CS6:
+ lcr = WLS(6);
+ break;
+ case CS5:
+ lcr = WLS(5);
+ break;
+ default:
+ dev_err(port->dev, "%s: word length not supported\n",
+ __func__);
+ }
+
+ if (termios->c_cflag & CSTOPB)
+ lcr |= STB;
+ if (termios->c_cflag & PARENB)
+ lcr |= PEN;
+ if (!(termios->c_cflag & PARODD))
+ lcr |= EPS;
+ if (termios->c_cflag & CMSPAR)
+ lcr |= STP;
+ if (termios->c_cflag & CRTSCTS)
+ uart->hwflow_en = true;
+ else
+ uart->hwflow_en = false;
+
+ spin_lock_irqsave(&uart->port.lock, flags);
+
+ port->read_status_mask = OE;
+ if (termios->c_iflag & INPCK)
+ port->read_status_mask |= (FE | PE);
+ if (termios->c_iflag & (BRKINT | PARMRK))
+ port->read_status_mask |= BI;
+
+ /*
+ * Characters to ignore
+ */
+ port->ignore_status_mask = 0;
+ if (termios->c_iflag & IGNPAR)
+ port->ignore_status_mask |= FE | PE;
+ if (termios->c_iflag & IGNBRK) {
+ port->ignore_status_mask |= BI;
+ /*
+ * If we're ignoring parity and break indicators,
+ * ignore overruns too (for real raw support).
+ */
+ if (termios->c_iflag & IGNPAR)
+ port->ignore_status_mask |= OE;
+ }
+
+ /*
+ * uart_get_divisor has a hardcoded /16 factor that will cause integer
+ * round off errors if we're in divide-by-one mode
+ */
+ if (uart->edbo) {
+ baud = uart_get_baud_rate(port, termios, old, 0,
+ port->uartclk);
+ quot = EDBO | DIV_ROUND_CLOSEST(port->uartclk, baud);
+ } else {
+ baud = uart_get_baud_rate(port, termios, old, 0,
+ port->uartclk/16);
+ quot = uart_get_divisor(port, baud);
+ }
+
+ /* Wait till the transfer buffer is empty */
+ timeout = jiffies + msecs_to_jiffies(10);
+ while (UART_GET_GCTL(uart) & UCEN && !(UART_GET_LSR(uart) & TEMT))
+ if (time_after(jiffies, timeout)) {
+ dev_warn(port->dev,
+ "timeout waiting for TX buffer empty\n");
+ break;
+ }
+
+ /* Wait till the transfer buffer is empty */
+ timeout = jiffies + msecs_to_jiffies(10);
+ while (UART_GET_GCTL(uart) & UCEN && !(UART_GET_LSR(uart) & TEMT))
+ if (time_after(jiffies, timeout)) {
+ dev_warn(port->dev,
+ "timeout waiting for TX buffer empty\n");
+ break;
+ }
+
+ /* Disable UART */
+ ier = UART_GET_IER(uart);
+ UART_PUT_GCTL(uart, UART_GET_GCTL(uart) & ~UCEN);
+ UART_DISABLE_INTS(uart);
+
+ UART_PUT_CLK(uart, quot);
+
+ UART_PUT_LCR(uart, (UART_GET_LCR(uart) & ~LCR_MASK) | lcr);
+
+ /* Enable UART */
+ UART_ENABLE_INTS(uart, ier);
+ UART_PUT_GCTL(uart, UART_GET_GCTL(uart) | UCEN);
+
+ /* Port speed changed, update the per-port timeout. */
+ uart_update_timeout(port, termios->c_cflag, baud);
+
+ spin_unlock_irqrestore(&uart->port.lock, flags);
+}
+
+static const char *adi_uart_serial_type(struct uart_port *port)
+{
+ struct adi_uart_serial_port *uart = to_adi_serial_port(port);
+
+ return uart->port.type == PORT_BFIN ? "ADI-UART" : NULL;
+}
+
+/*
+ * Release the memory region(s) being used by 'port'.
+ */
+static void adi_uart_serial_release_port(struct uart_port *port)
+{
+}
+
+/*
+ * Request the memory region(s) being used by 'port'.
+ */
+static int adi_uart_serial_request_port(struct uart_port *port)
+{
+ return 0;
+}
+
+/*
+ * Configure/autoconfigure the port.
+ */
+static void adi_uart_serial_config_port(struct uart_port *port, int flags)
+{
+ struct adi_uart_serial_port *uart = to_adi_serial_port(port);
+
+ if (flags & UART_CONFIG_TYPE &&
+ adi_uart_serial_request_port(&uart->port) == 0)
+ uart->port.type = PORT_BFIN;
+}
+
+/*
+ * Verify the new serial_struct (for TIOCSSERIAL).
+ * The only change we allow are to the flags and type, and
+ * even then only between PORT_BFIN and PORT_UNKNOWN
+ */
+static int
+adi_uart_serial_verify_port(struct uart_port *port, struct serial_struct *ser)
+{
+ return 0;
+}
+
+/*
+ * Enable the IrDA function if tty->ldisc.num is N_IRDA.
+ * In other cases, disable IrDA function.
+ */
+static void adi_uart_serial_set_ldisc(struct uart_port *port,
+ struct ktermios *termios)
+{
+ struct adi_uart_serial_port *uart = to_adi_serial_port(port);
+ unsigned int val;
+
+ switch (termios->c_line) {
+ case N_IRDA:
+ val = UART_GET_GCTL(uart);
+ val |= (UMOD_IRDA | RPOLC);
+ UART_PUT_GCTL(uart, val);
+ break;
+ default:
+ val = UART_GET_GCTL(uart);
+ val &= ~(UMOD_MASK | RPOLC);
+ UART_PUT_GCTL(uart, val);
+ }
+}
+
+static void adi_uart_serial_reset_irda(struct uart_port *port)
+{
+ struct adi_uart_serial_port *uart = to_adi_serial_port(port);
+ unsigned int val;
+
+ val = UART_GET_GCTL(uart);
+ val &= ~(UMOD_MASK | RPOLC);
+ UART_PUT_GCTL(uart, val);
+ val |= (UMOD_IRDA | RPOLC);
+ UART_PUT_GCTL(uart, val);
+}
+
+#ifdef CONFIG_CONSOLE_POLL
+static void adi_uart_serial_poll_put_char(struct uart_port *port,
+ unsigned char chr)
+{
+ struct adi_uart_serial_port *uart = to_adi_serial_port(port);
+
+ while (!(UART_GET_LSR(uart) & THRE))
+ cpu_relax();
+
+ UART_PUT_CHAR(uart, (unsigned char)chr);
+}
+
+static int adi_uart_serial_poll_get_char(struct uart_port *port)
+{
+ struct adi_uart_serial_port *uart = to_adi_serial_port(port);
+ unsigned char chr;
+
+ while (!(UART_GET_LSR(uart) & DR))
+ cpu_relax();
+
+ chr = UART_GET_CHAR(uart);
+
+ return chr;
+}
+#endif
+
+
+static const struct uart_ops adi_uart_serial_pops = {
+ .tx_empty = adi_uart_serial_tx_empty,
+ .set_mctrl = adi_uart_serial_set_mctrl,
+ .get_mctrl = adi_uart_serial_get_mctrl,
+ .stop_tx = adi_uart_serial_stop_tx,
+ .start_tx = adi_uart_serial_start_tx,
+ .stop_rx = adi_uart_serial_stop_rx,
+ .enable_ms = adi_uart_serial_enable_ms,
+ .break_ctl = adi_uart_serial_break_ctl,
+ .startup = adi_uart_serial_startup,
+ .shutdown = adi_uart_serial_shutdown,
+ .set_termios = adi_uart_serial_set_termios,
+ .set_ldisc = adi_uart_serial_set_ldisc,
+ .type = adi_uart_serial_type,
+ .release_port = adi_uart_serial_release_port,
+ .request_port = adi_uart_serial_request_port,
+ .config_port = adi_uart_serial_config_port,
+ .verify_port = adi_uart_serial_verify_port,
+#ifdef CONFIG_CONSOLE_POLL
+ .poll_put_char = adi_uart_serial_poll_put_char,
+ .poll_get_char = adi_uart_serial_poll_get_char,
+#endif
+};
+
+#ifdef CONFIG_SERIAL_ADI_UART_CONSOLE
+static void adi_uart_serial_console_putchar(struct uart_port *port,
+ unsigned char ch)
+{
+ struct adi_uart_serial_port *uart = to_adi_serial_port(port);
+
+ while (!(UART_GET_LSR(uart) & THRE))
+ barrier();
+ UART_PUT_CHAR(uart, ch);
+}
+
+static void __init
+adi_uart_serial_console_get_options(struct adi_uart_serial_port *uart,
+ int *baud, int *parity, int *bits)
+{
+ unsigned int status;
+
+ status = UART_GET_IER(uart) & (ERBFI | ETBEI);
+ if (status == (ERBFI | ETBEI)) {
+ /* ok, the port was enabled */
+ u32 lcr, clk;
+
+ lcr = UART_GET_LCR(uart);
+
+ *parity = 'n';
+ if (lcr & PEN) {
+ if (lcr & EPS)
+ *parity = 'e';
+ else
+ *parity = 'o';
+ }
+ *bits = ((lcr & WLS_MASK) >> WLS_OFFSET) + 5;
+
+ clk = UART_GET_CLK(uart);
+
+ /* Only the lowest 16 bits are the divisor */
+ if (clk & EDBO)
+ *baud = uart->port.uartclk / (clk & 0xffff);
+ else
+ *baud = uart->port.uartclk / (16*clk);
+ }
+ pr_debug("%s:baud = %d, parity = %c, bits= %d\n", __func__,
+ *baud, *parity, *bits);
+}
+
+static void
+adi_uart_serial_console_write(struct console *co, const char *s,
+ unsigned int count)
+{
+ struct adi_uart_serial_port *uart = adi_uart_serial_ports[co->index];
+ unsigned long flags;
+
+ spin_lock_irqsave(&uart->port.lock, flags);
+ uart_console_write(&uart->port, s, count,
+ adi_uart_serial_console_putchar);
+ spin_unlock_irqrestore(&uart->port.lock, flags);
+
+}
+
+static int __init
+adi_uart_serial_console_setup(struct console *co, char *options)
+{
+ struct adi_uart_serial_port *uart;
+ int baud = 115200;
+ int bits = 8;
+ int parity = 'n';
+ int flow = 'n';
+
+ /*
+ * Check whether an invalid uart number has been specified, and
+ * if so, search for the first available port that does have
+ * console support.
+ */
+ if (co->index < 0 || co->index >= ADI_UART_NR_PORTS)
+ return -ENODEV;
+
+ uart = adi_uart_serial_ports[co->index];
+ if (!uart)
+ return -ENODEV;
+
+ if (uart->hwflow_mode == ADI_UART_HWFLOW_PERI)
+ flow = 'r';
+
+ if (options)
+ uart_parse_options(options, &baud, &parity, &bits, &flow);
+ else
+ adi_uart_serial_console_get_options(uart, &baud, &parity,
+ &bits);
+
+ return uart_set_options(&uart->port, co, baud, parity, bits, flow);
+}
+
+static struct uart_driver adi_uart_serial_reg;
+
+static struct console adi_uart_serial_console = {
+ .name = "ttySC",
+ .write = adi_uart_serial_console_write,
+ .device = uart_console_device,
+ .setup = adi_uart_serial_console_setup,
+ .flags = CON_PRINTBUFFER,
+ .index = -1,
+ .data = &adi_uart_serial_reg,
+};
+
+
+#define ADI_SERIAL_UART_CONSOLE (&adi_uart_serial_console)
+#else
+#define ADI_SERIAL_UART_CONSOLE NULL
+#endif
+
+static struct uart_driver adi_uart_serial_reg = {
+ .owner = THIS_MODULE,
+ .driver_name = DRIVER_NAME,
+ .dev_name = "ttySC",
+ .major = TTY_MAJOR,
+#ifdef CONFIG_ARCH_SC59X_64
+ // Other serial drivers are using 64 --
+ // Can probably disable in the future and set this back to 64
+ .minor = 74,
+#else
+ .minor = 64,
+#endif
+ .nr = ADI_UART_NR_PORTS,
+ .cons = ADI_SERIAL_UART_CONSOLE,
+};
+
+static int adi_uart_serial_suspend(struct platform_device *pdev,
+ pm_message_t state)
+{
+ struct adi_uart_serial_port *uart = platform_get_drvdata(pdev);
+
+ clk_disable(uart->clk);
+ return uart_suspend_port(&adi_uart_serial_reg, &uart->port);
+}
+
+static int adi_uart_serial_resume(struct platform_device *pdev)
+{
+ struct adi_uart_serial_port *uart = platform_get_drvdata(pdev);
+ int ret;
+
+ ret = clk_enable(uart->clk);
+ if (ret)
+ return ret;
+
+ return uart_resume_port(&adi_uart_serial_reg, &uart->port);
+}
+
+static int adi_uart_serial_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct device_node *np = dev->of_node;
+ struct adi_uart_serial_port *uart = NULL;
+ int ret = 0;
+ int uartid;
+ dev_info(dev, "Serial probe\n");
+
+ uartid = of_alias_get_id(np, "serial");
+
+ if (uartid < 0) {
+ dev_err(&pdev->dev, "failed to get alias/pdev id, errno %d\n",
+ uartid);
+ ret = -ENODEV;
+ return ret;
+ }
+
+ if (adi_uart_serial_ports[uartid] == NULL) {
+ uart = kzalloc(sizeof(*uart), GFP_KERNEL);
+ if (!uart)
+ return -ENOMEM;
+
+ adi_uart_serial_ports[uartid] = uart;
+ uart->dev = &pdev->dev;
+
+ uart->clk = devm_clk_get(dev, "sclk0");
+ if (IS_ERR(uart->clk))
+ return -ENODEV;
+
+ spin_lock_init(&uart->port.lock);
+ uart->port.uartclk = clk_get_rate(uart->clk);
+ uart->port.fifosize = 8;
+ uart->port.ops = &adi_uart_serial_pops;
+ uart->port.line = uartid;
+ uart->port.iotype = UPIO_MEM;
+ uart->port.flags = UPF_BOOT_AUTOCONF;
+
+ uart->port.membase = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(uart->port.membase))
+ return PTR_ERR(uart->port.membase);
+
+ uart->tx_irq = platform_get_irq_byname(pdev, "tx");
+ uart->rx_irq = platform_get_irq_byname(pdev, "rx");
+ uart->status_irq =
+ platform_get_irq_byname(pdev, "status");
+ uart->port.irq = uart->rx_irq;//
+ ret = devm_request_threaded_irq(dev, uart->rx_irq,
+ adi_uart_serial_rx_int, NULL, 0, "ADI UART RX",
+ uart);
+ if (ret) {
+ dev_err(dev, "Unable to attach UART RX int\n");
+ return ret;
+ }
+
+ ret = devm_request_threaded_irq(dev, uart->tx_irq,
+ adi_uart_serial_tx_int, NULL, 0, "ADI UART TX",
+ uart);
+ if (ret) {
+ dev_err(dev, "Unable to attach UART TX int\n");
+ return ret;
+ }
+
+ /* adi,uart-has-rtscts is deprecated */
+ if (of_property_read_bool(np, "uart-has-rtscts") ||
+ of_property_read_bool(np, "adi,uart-has-rtscts")) {
+ uart->hwflow_mode = ADI_UART_HWFLOW_PERI;
+ ret = devm_request_threaded_irq(dev, uart->status_irq,
+ adi_uart_serial_mctrl_cts_int, NULL, 0,
+ "ADI UART Modem Status",
+ uart);
+ if (ret) {
+ uart->hwflow_mode = ADI_UART_NO_HWFLOW;
+ dev_info(dev,
+ "Unable to attach UART Modem Status int.\n");
+ }
+ } else
+ uart->hwflow_mode = ADI_UART_NO_HWFLOW;
+
+ uart->edbo = false;
+ if (of_property_read_bool(np, "adi,use-edbo"))
+ uart->edbo = true;
+
+ if (uart->hwflow_mode == ADI_UART_HWFLOW_PERI) {
+ uart->hwflow_en_pin = devm_gpiod_get(dev, "hwflow-en",
+ GPIOD_OUT_HIGH);
+ if (IS_ERR(uart->hwflow_en_pin)) {
+ dev_err(dev,
+ "hwflow-en required in peripheral hwflow mode\n");
+ return PTR_ERR(uart->hwflow_en_pin);
+ }
+ }
+ }
+
+ uart = adi_uart_serial_ports[uartid];
+ uart->port.dev = &pdev->dev;
+ dev_set_drvdata(&pdev->dev, uart);
+
+ ret = uart_add_one_port(&adi_uart_serial_reg, &uart->port);
+ if (!ret)
+ return 0;
+
+ if (uart) {
+ adi_uart_serial_ports[uartid] = NULL;
+ kfree(uart);
+ }
+
+ return ret;
+}
+
+static void adi_uart_serial_remove(struct platform_device *pdev)
+{
+ struct adi_uart_serial_port *uart = platform_get_drvdata(pdev);
+
+ dev_set_drvdata(&pdev->dev, NULL);
+
+ if (uart) {
+ uart_remove_one_port(&adi_uart_serial_reg, &uart->port);
+ adi_uart_serial_ports[uart->port.line] = NULL;
+ kfree(uart);
+ }
+}
+
+static const struct of_device_id adi_uart_dt_match[] = {
+ { .compatible = "adi,uart"},
+ {},
+};
+MODULE_DEVICE_TABLE(of, adi_uart_dt_match);
+
+static struct platform_driver adi_uart_serial_driver = {
+ .probe = adi_uart_serial_probe,
+ .remove = adi_uart_serial_remove,
+ .suspend = adi_uart_serial_suspend,
+ .resume = adi_uart_serial_resume,
+ .driver = {
+ .name = DRIVER_NAME,
+ .owner = THIS_MODULE,
+ .of_match_table = adi_uart_dt_match,
+ },
+};
+
+static int __init adi_uart_serial_init(void)
+{
+ int ret;
+
+ pr_info("ADI serial driver\n");
+
+ ret = uart_register_driver(&adi_uart_serial_reg);
+ if (ret) {
+ pr_err("failed to register %s:%d\n",
+ adi_uart_serial_reg.driver_name, ret);
+ }
+
+ ret = platform_driver_register(&adi_uart_serial_driver);
+ if (ret) {
+ pr_err("fail to register ADI uart\n");
+ uart_unregister_driver(&adi_uart_serial_reg);
+ }
+
+ return ret;
+}
+
+static void __exit adi_uart_serial_exit(void)
+{
+ platform_driver_unregister(&adi_uart_serial_driver);
+ uart_unregister_driver(&adi_uart_serial_reg);
+}
+
+module_init(adi_uart_serial_init);
+module_exit(adi_uart_serial_exit);
+
+/* Early Console Support */
+static inline u32 adi_uart_read(struct uart_port *port, u32 off)
+{
+ return readl(port->membase + off);
+}
+
+static inline void adi_uart_write(struct uart_port *port, u32 val,
+ u32 off)
+{
+ writel(val, port->membase + off);
+}
+
+
+static void adi_uart_wait_bit_set(struct uart_port *port, unsigned int offset,
+ u32 bit)
+{
+ while (!(adi_uart_read(port, offset) & bit))
+ cpu_relax();
+}
+
+
+static void adi_uart_console_putchar(struct uart_port *port, unsigned char ch)
+{
+ /* wait for the hardware fifo to clear up */
+ adi_uart_wait_bit_set(port, OFFSET_STAT, THRE);
+
+ /* queue the character for transmission */
+ adi_uart_write(port, ch, OFFSET_THR);
+}
+
+
+static void adi_uart_early_write(struct console *con, const char *s,
+ unsigned int n)
+{
+ struct earlycon_device *dev = con->data;
+
+ uart_console_write(&dev->port, s, n, adi_uart_console_putchar);
+}
+
+
+static int __init adi_uart_early_console_setup(struct earlycon_device *device,
+ const char *opt)
+{
+ if (!device->port.membase)
+ return -ENODEV;
+
+ device->con->write = adi_uart_early_write;
+ return 0;
+}
+
+EARLYCON_DECLARE(adi_uart, adi_uart_early_console_setup);
+
+MODULE_AUTHOR("Sonic Zhang, Aubrey Li");
+MODULE_DESCRIPTION("Blackfin/ADSP generic serial port driver");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS_CHARDEV_MAJOR(BFIN_SERIAL_MAJOR);
\ No newline at end of file
diff --git a/include/uapi/linux/serial_core.h b/include/uapi/linux/serial_core.h
index 9c007a106330b90b92cbcf60a9ac806b290d6d44..ce3c50dfa5cacd09eb30e93e408c2d92992ac755 100644
--- a/include/uapi/linux/serial_core.h
+++ b/include/uapi/linux/serial_core.h
@@ -109,6 +109,9 @@
/* Xilinx uartlite */
#define PORT_UARTLITE 74
+/* Blackfin */
+#define PORT_BFIN 75
+
/* Broadcom BCM7271 UART */
#define PORT_BCM7271 76
--
2.25.1
^ permalink raw reply related [flat|nested] 65+ messages in thread
* [PATCH 18/21] dt-bindings: serial: adi,uart4: add adi,uart4 driver documentation
2024-09-12 18:24 [PATCH 00/21] Adding support of ADI ARMv8 ADSP-SC598 SoC Arturs Artamonovs via B4 Relay
` (16 preceding siblings ...)
2024-09-12 18:25 ` [PATCH 17/21] serial: adi,uart: Add driver for ADI ADSP-SC5xx Arturs Artamonovs via B4 Relay
@ 2024-09-12 18:25 ` Arturs Artamonovs via B4 Relay
2024-09-12 20:02 ` Rob Herring (Arm)
2024-09-13 14:06 ` Rob Herring
2024-09-12 18:25 ` [PATCH 19/21] arm64: dts: adi: sc598: add device tree Arturs Artamonovs via B4 Relay
` (5 subsequent siblings)
23 siblings, 2 replies; 65+ messages in thread
From: Arturs Artamonovs via B4 Relay @ 2024-09-12 18:25 UTC (permalink / raw)
To: Catalin Marinas, Will Deacon, Greg Malysa, Philipp Zabel,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Utsav Agarwal,
Michael Turquette, Stephen Boyd, Linus Walleij,
Bartosz Golaszewski, Thomas Gleixner, Andi Shyti,
Greg Kroah-Hartman, Jiri Slaby, Arnd Bergmann, Olof Johansson,
soc
Cc: linux-arm-kernel, linux-kernel, devicetree, linux-clk, linux-gpio,
linux-i2c, linux-serial, Arturs Artamonovs, adsp-linux,
Arturs Artamonovs, Nathan Barrett-Morrison
From: Arturs Artamonovs <arturs.artamonovs@analog.com>
Add serial driver bindings.
Signed-off-by: Arturs Artamonovs <Arturs.Artamonovs@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>
---
.../devicetree/bindings/serial/adi,uart.yaml | 85 ++++++++++++++++++++++
1 file changed, 85 insertions(+)
diff --git a/Documentation/devicetree/bindings/serial/adi,uart.yaml b/Documentation/devicetree/bindings/serial/adi,uart.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..de58059efa7e21acaa5b7f4984ffadca18f7f53a
--- /dev/null
+++ b/Documentation/devicetree/bindings/serial/adi,uart.yaml
@@ -0,0 +1,85 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/serial/adi,uart4.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Analog Devices UART Driver for SC5XX-family processors
+
+maintainers:
+ - Arturs Artamonovs <arturs.artamonovs@analog.com>
+ - Utsav Agarwal <Utsav.Agarwal@analog.com>
+
+description: |
+ Analog Devices UART Driver for SC59X-family processors
+
+properties:
+ compatible:
+ enum:
+ - adi,uart
+
+ reg:
+ maxItems: 1
+
+ dmas:
+ maxItems: 2
+ minItems: 2
+ description: TX and RX DMA cluster numbers
+
+ dma-names:
+ maxItems: 2
+ minItems: 2
+ description: DMA channel names (tx and rx)
+
+ clocks:
+ maxItems: 1
+ description: Clock being used for UART
+
+ clock-names:
+ maxItems: 1
+ description: Clock name (sclk0)
+
+ interrupt-names:
+ minItems: 3
+ maxItems: 3
+ description: Interrupt names (tx + rx + status)
+
+ interrupts:
+ minItems: 3
+ maxItems: 3
+ description: GIC interrupt numbers
+
+ adi,use-edbo:
+ type: boolean
+ description: Enable divide by one in divisor
+
+required:
+ - compatible
+ - reg
+ - clocks
+ - clock-names
+ - interrupt-names
+ - interrupts
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/interrupt-controller/arm-gic.h>
+ #include <dt-bindings/interrupt-controller/irq.h>
+ #include <dt-bindings/clock/adi-sc5xx-clock.h>
+
+ uart0: uart@31003000 {
+ compatible = "adi,uart";
+ reg = <0x31003000 0x40>;
+ clocks = <&clk ADSP_SC598_CLK_CGU0_SCLK0>;
+ clock-names = "sclk0";
+ interrupt-parent = <&gic>;
+ interrupt-names = "tx", "rx", "status";
+ interrupts = <GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 139 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>;
+ adi,use-edbo;
+ status = "disabled";
+ };
+
--
2.25.1
^ permalink raw reply related [flat|nested] 65+ messages in thread
* Re: [PATCH 18/21] dt-bindings: serial: adi,uart4: add adi,uart4 driver documentation
2024-09-12 18:25 ` [PATCH 18/21] dt-bindings: serial: adi,uart4: add adi,uart4 driver documentation Arturs Artamonovs via B4 Relay
@ 2024-09-12 20:02 ` Rob Herring (Arm)
2024-09-13 14:06 ` Rob Herring
1 sibling, 0 replies; 65+ messages in thread
From: Rob Herring (Arm) @ 2024-09-12 20:02 UTC (permalink / raw)
To: Arturs Artamonovs
Cc: Arturs Artamonovs, soc, adsp-linux, Olof Johansson,
Catalin Marinas, Andi Shyti, Greg Malysa, Linus Walleij,
linux-arm-kernel, linux-i2c, Krzysztof Kozlowski, Will Deacon,
linux-serial, Arnd Bergmann, Thomas Gleixner, linux-gpio,
Greg Kroah-Hartman, Michael Turquette, linux-clk, Stephen Boyd,
Conor Dooley, Nathan Barrett-Morrison, Bartosz Golaszewski,
linux-kernel, devicetree, Philipp Zabel, Utsav Agarwal,
Jiri Slaby
On Thu, 12 Sep 2024 19:25:03 +0100, Arturs Artamonovs wrote:
> Add serial driver bindings.
>
> Signed-off-by: Arturs Artamonovs <Arturs.Artamonovs@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>
> ---
> .../devicetree/bindings/serial/adi,uart.yaml | 85 ++++++++++++++++++++++
> 1 file changed, 85 insertions(+)
>
My bot found errors running 'make dt_binding_check' on your patch:
yamllint warnings/errors:
dtschema/dtc warnings/errors:
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/serial/adi,uart.yaml: $id: Cannot determine base path from $id, relative path/filename doesn't match actual path or filename
$id: http://devicetree.org/schemas/serial/adi,uart4.yaml
file: /builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/serial/adi,uart.yaml
doc reference errors (make refcheckdocs):
See https://patchwork.ozlabs.org/project/devicetree-bindings/patch/20240912-test-v1-18-458fa57c8ccf@analog.com
The base for the series is generally the latest rc1. A different dependency
should be noted in *this* patch.
If you already ran 'make dt_binding_check' and didn't see the above
error(s), then make sure 'yamllint' is installed and dt-schema is up to
date:
pip3 install dtschema --upgrade
Please check and re-submit after running the above command yourself. Note
that DT_SCHEMA_FILES can be set to your schema file to speed up checking
your schema. However, it must be unset to test all examples with your schema.
^ permalink raw reply [flat|nested] 65+ messages in thread
* Re: [PATCH 18/21] dt-bindings: serial: adi,uart4: add adi,uart4 driver documentation
2024-09-12 18:25 ` [PATCH 18/21] dt-bindings: serial: adi,uart4: add adi,uart4 driver documentation Arturs Artamonovs via B4 Relay
2024-09-12 20:02 ` Rob Herring (Arm)
@ 2024-09-13 14:06 ` Rob Herring
1 sibling, 0 replies; 65+ messages in thread
From: Rob Herring @ 2024-09-13 14:06 UTC (permalink / raw)
To: Arturs Artamonovs
Cc: Catalin Marinas, Will Deacon, Greg Malysa, Philipp Zabel,
Krzysztof Kozlowski, Conor Dooley, Utsav Agarwal,
Michael Turquette, Stephen Boyd, Linus Walleij,
Bartosz Golaszewski, Thomas Gleixner, Andi Shyti,
Greg Kroah-Hartman, Jiri Slaby, Arnd Bergmann, Olof Johansson,
soc, linux-arm-kernel, linux-kernel, devicetree, linux-clk,
linux-gpio, linux-i2c, linux-serial, adsp-linux,
Nathan Barrett-Morrison
On Thu, Sep 12, 2024 at 07:25:03PM +0100, Arturs Artamonovs wrote:
> Add serial driver bindings.
Don''t need 'documentation' in the the subject. That's redundant with
'dt-bindings'.
>
> Signed-off-by: Arturs Artamonovs <Arturs.Artamonovs@analog.com>
Your S-o-b goes last since you are sending the patch.
> Signed-off-by: Utsav Agarwal <Utsav.Agarwal@analog.com>
Not clear what Utsav's role was. Needs Co-developed-by?
> 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>
> ---
> .../devicetree/bindings/serial/adi,uart.yaml | 85 ++++++++++++++++++++++
> 1 file changed, 85 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/serial/adi,uart.yaml b/Documentation/devicetree/bindings/serial/adi,uart.yaml
> new file mode 100644
> index 0000000000000000000000000000000000000000..de58059efa7e21acaa5b7f4984ffadca18f7f53a
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/serial/adi,uart.yaml
> @@ -0,0 +1,85 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/serial/adi,uart4.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Analog Devices UART Driver for SC5XX-family processors
Bindings aren't a driver.
> +
> +maintainers:
> + - Arturs Artamonovs <arturs.artamonovs@analog.com>
> + - Utsav Agarwal <Utsav.Agarwal@analog.com>
> +
> +description: |
Don't need '|'.
> + Analog Devices UART Driver for SC59X-family processors
> +
> +properties:
> + compatible:
> + enum:
> + - adi,uart
Only 1 UART implementation for all of Analog Devices ever.
compatibles should be specific to SoC.
> +
> + reg:
> + maxItems: 1
> +
> + dmas:
> + maxItems: 2
> + minItems: 2
> + description: TX and RX DMA cluster numbers
> +
> + dma-names:
> + maxItems: 2
> + minItems: 2
> + description: DMA channel names (tx and rx)
Names need to be constraints, not freeform text. Plenty of examples to
look at...
> +
> + clocks:
> + maxItems: 1
> + description: Clock being used for UART
That's obvious. Drop description or say something unique to this device.
> +
> + clock-names:
> + maxItems: 1
> + description: Clock name (sclk0)
> +
> + interrupt-names:
> + minItems: 3
> + maxItems: 3
> + description: Interrupt names (tx + rx + status)
> +
> + interrupts:
> + minItems: 3
> + maxItems: 3
> + description: GIC interrupt numbers
> +
> + adi,use-edbo:
> + type: boolean
> + description: Enable divide by one in divisor
Versus divide by ???
> +
> +required:
> + - compatible
> + - reg
> + - clocks
> + - clock-names
> + - interrupt-names
> + - interrupts
> +
> +additionalProperties: false
> +
> +examples:
> + - |
> + #include <dt-bindings/interrupt-controller/arm-gic.h>
> + #include <dt-bindings/interrupt-controller/irq.h>
> + #include <dt-bindings/clock/adi-sc5xx-clock.h>
> +
> + uart0: uart@31003000 {
serial@...
Drop unused labels.
> + compatible = "adi,uart";
> + reg = <0x31003000 0x40>;
> + clocks = <&clk ADSP_SC598_CLK_CGU0_SCLK0>;
> + clock-names = "sclk0";
> + interrupt-parent = <&gic>;
> + interrupt-names = "tx", "rx", "status";
> + interrupts = <GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>,
> + <GIC_SPI 139 IRQ_TYPE_LEVEL_HIGH>,
> + <GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>;
> + adi,use-edbo;
> + status = "disabled";
Examples should be enabled. Drop.
> + };
> +
>
> --
> 2.25.1
>
^ permalink raw reply [flat|nested] 65+ messages in thread
* [PATCH 19/21] arm64: dts: adi: sc598: add device tree
2024-09-12 18:24 [PATCH 00/21] Adding support of ADI ARMv8 ADSP-SC598 SoC Arturs Artamonovs via B4 Relay
` (17 preceding siblings ...)
2024-09-12 18:25 ` [PATCH 18/21] dt-bindings: serial: adi,uart4: add adi,uart4 driver documentation Arturs Artamonovs via B4 Relay
@ 2024-09-12 18:25 ` Arturs Artamonovs via B4 Relay
2024-09-13 8:05 ` Arnd Bergmann
2024-09-16 7:04 ` Krzysztof Kozlowski
2024-09-12 18:25 ` [PATCH 20/21] arm64: defconfig: sc598 add minimal changes Arturs Artamonovs via B4 Relay
` (4 subsequent siblings)
23 siblings, 2 replies; 65+ messages in thread
From: Arturs Artamonovs via B4 Relay @ 2024-09-12 18:25 UTC (permalink / raw)
To: Catalin Marinas, Will Deacon, Greg Malysa, Philipp Zabel,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Utsav Agarwal,
Michael Turquette, Stephen Boyd, Linus Walleij,
Bartosz Golaszewski, Thomas Gleixner, Andi Shyti,
Greg Kroah-Hartman, Jiri Slaby, Arnd Bergmann, Olof Johansson,
soc
Cc: linux-arm-kernel, linux-kernel, devicetree, linux-clk, linux-gpio,
linux-i2c, linux-serial, Arturs Artamonovs, adsp-linux,
Arturs Artamonovs, Nathan Barrett-Morrison
From: Arturs Artamonovs <arturs.artamonovs@analog.com>
Add ADI SC598-EZKIT device tree.
Support UART console as output.
Signed-off-by: Arturs Artamonovs <Arturs.Artamonovs@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/boot/dts/Makefile | 1 +
arch/arm64/boot/dts/adi/Makefile | 2 +
arch/arm64/boot/dts/adi/sc598-som-ezkit.dts | 14 ++
arch/arm64/boot/dts/adi/sc598-som.dtsi | 58 +++++
arch/arm64/boot/dts/adi/sc59x-64.dtsi | 367 ++++++++++++++++++++++++++++
5 files changed, 442 insertions(+)
diff --git a/arch/arm64/boot/dts/Makefile b/arch/arm64/boot/dts/Makefile
index 21cd3a87f385309c3a655a67a3bee5f0abed7545..9b3996a8e01d8e7d264c44c075d7a50ee350ba44 100644
--- a/arch/arm64/boot/dts/Makefile
+++ b/arch/arm64/boot/dts/Makefile
@@ -1,5 +1,6 @@
# SPDX-License-Identifier: GPL-2.0
subdir-y += actions
+subdir-y += adi
subdir-y += airoha
subdir-y += allwinner
subdir-y += altera
diff --git a/arch/arm64/boot/dts/adi/Makefile b/arch/arm64/boot/dts/adi/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..1bf54bc97095e1ea3577953d379746fbc0ea02a9
--- /dev/null
+++ b/arch/arm64/boot/dts/adi/Makefile
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0
+dtb-$(CONFIG_ARCH_SC59X_64) += sc598-som-ezkit.dtb
diff --git a/arch/arm64/boot/dts/adi/sc598-som-ezkit.dts b/arch/arm64/boot/dts/adi/sc598-som-ezkit.dts
new file mode 100644
index 0000000000000000000000000000000000000000..a8db6d5ea764f917faa6839d3d4f0b5217b927b8
--- /dev/null
+++ b/arch/arm64/boot/dts/adi/sc598-som-ezkit.dts
@@ -0,0 +1,14 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright 2021-2024 - Analog Devices Inc.
+ * Author: Nathan Barrett-Morrison <nathan.morrison@timesys.com>
+ */
+
+/dts-v1/;
+
+#include "sc598-som.dtsi"
+
+/ {
+ model = "ADI 64-bit SC598 SOM EZ Kit";
+ compatible = "adi,sc598-som-ezkit", "adi,sc59x-64";
+};
diff --git a/arch/arm64/boot/dts/adi/sc598-som.dtsi b/arch/arm64/boot/dts/adi/sc598-som.dtsi
new file mode 100644
index 0000000000000000000000000000000000000000..3b90f367db1a24de1e1dddc4db3c219736c5b90f
--- /dev/null
+++ b/arch/arm64/boot/dts/adi/sc598-som.dtsi
@@ -0,0 +1,58 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright 2021-2024 - Analog Devices Inc.
+ * Author: Nathan Barrett-Morrison <nathan.morrison@timesys.com>
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/pinctrl/adi-adsp.h>
+#include "sc59x-64.dtsi"
+
+/ {
+ chosen {
+ stdout-path = &uart1;
+ bootargs = "earlycon=adi_uart,0x31003000 console=ttySC0,115200 mem=224M";
+ };
+
+ memory@90000000 {
+ device_type = "memory";
+ reg = <0x90000000 0x0e000000>;
+ };
+
+ memory@20040000 {
+ device_type = "memory";
+ reg = <0x20040000 0x40000>;
+ };
+
+ scb: scb-bus {
+ sec: sec@31089000 {
+ adi,sharc-cores = <2>;
+ };
+ };
+
+};
+
+&uart0 {
+ pinctrl-0 = <&uart0_default>;
+ pinctrl-names = "default";
+ status = "okay";
+};
+
+&i2c0 {
+ status = "okay";
+};
+
+&i2c1 {
+ status = "disabled";
+};
+
+&pinctrl0 {
+ uart0_default: uart0-default-pins {
+ pins {
+ pinmux = <ADI_ADSP_PINMUX('A', 6, ADI_ADSP_PINFUNC_ALT1)>,
+ <ADI_ADSP_PINMUX('A', 7, ADI_ADSP_PINFUNC_ALT1)>;
+ };
+ };
+};
diff --git a/arch/arm64/boot/dts/adi/sc59x-64.dtsi b/arch/arm64/boot/dts/adi/sc59x-64.dtsi
new file mode 100644
index 0000000000000000000000000000000000000000..4a9aa08b4acb0936c97e683562e05da063a4e193
--- /dev/null
+++ b/arch/arm64/boot/dts/adi/sc59x-64.dtsi
@@ -0,0 +1,367 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright 2021-2024 - Analog Devices Inc.
+ * Author: Nathan Barrett-Morrison <nathan.morrison@timesys.com>
+ */
+
+#include <dt-bindings/clock/adi-sc5xx-clock.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
+/ {
+ model = "ADI 64-bit SC59X";
+ compatible = "adi,sc59x-64";
+
+ interrupt-parent = <&gic>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ chosen { };
+
+ aliases {
+ serial0 = &uart0;
+ serial2 = &uart2;
+ serial3 = &uart3;
+ };
+
+ cpus {
+ #address-cells = <0x2>;
+ #size-cells = <0x0>;
+
+ cpu0: cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a55";
+ reg = <0x0 0x0>;
+ enable-method = "spin-table";
+ cpu-release-addr = <0x0 0xdeadbeef>;
+ clocks = <&clk ADSP_SC598_CLK_ARM>, <&clk ADSP_SC598_CLK_DDR>;
+ };
+ };
+
+ pmu {
+ compatible = "arm,armv8-pmuv3";
+ interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-parent = <&gic>;
+ };
+
+ gic: interrupt-controller@31200000 {
+ compatible = "arm,gic-v3";
+ #interrupt-cells = <3>;
+ interrupt-controller;
+ reg = <0x31200000 0x40000>, /* GIC Dist */
+ <0x31240000 0x40000>; /* GICR */
+ };
+
+ timer {
+ compatible = "arm,armv8-timer";
+ interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>, /* Physical Secure */
+ <GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>, /* Physical Non-Secure */
+ <GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>, /* Virtual */
+ <GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>; /* Hypervisor */
+ };
+
+ clocks {
+ sys_clkin0: oscillator@1 {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <25000000>;
+ clock-output-names = "sys_clkin0";
+ };
+
+ sys_clkin1: oscillator@2 {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <25000000>;
+ clock-output-names = "sys_clkin1";
+ };
+ };
+
+ clk: clocks@3108d000 {
+ compatible = "adi,sc598-clocks";
+ reg = <0x3108d000 0x1000>,
+ <0x3108e000 0x1000>,
+ <0x3108f000 0x1000>,
+ <0x310a9000 0x1000>;
+ #clock-cells = <1>;
+ clocks = <&sys_clkin0>, <&sys_clkin1>;
+ clock-names = "sys_clkin0", "sys_clkin1";
+ status = "okay";
+ };
+
+ scb: scb-bus {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ rcu: rcu@3108c000 {
+ compatible = "adi,reset-controller";
+ reg = <0x3108c000 0x1000>;
+ status = "okay";
+ };
+
+ sec: sec@31089000 {
+ compatible = "adi,system-event-controller";
+ reg = <0x31089000 0x1000>;
+ adi,rcu = <&rcu>;
+ status = "okay";
+ };
+
+ uart0: uart@31003000 {
+ compatible = "adi,uart";
+ reg = <0x31003000 0x40>;
+ clocks = <&clk ADSP_SC598_CLK_CGU0_SCLK0>;
+ clock-names = "sclk0";
+ interrupt-parent = <&gic>;
+ interrupt-names = "tx", "rx", "status";
+ interrupts = <GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 139 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>;
+ adi,use-edbo;
+ status = "disabled";
+ };
+
+ uart1: uart@31003400 {
+ compatible = "adi,uart";
+ reg = <0x31003400 0x40>;
+ clocks = <&clk ADSP_SC598_CLK_CGU0_SCLK0>;
+ clock-names = "sclk0";
+ interrupt-parent = <&gic>;
+ interrupt-names = "tx", "rx", "status";
+ interrupts = <GIC_SPI 141 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 142 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH>;
+ adi,use-edbo;
+ status = "disabled";
+ };
+
+ uart2: uart@31003800 {
+ compatible = "adi,uart";
+ reg = <0x31003800 0x40>;
+ clocks = <&clk ADSP_SC598_CLK_CGU0_SCLK0>;
+ clock-names = "sclk0";
+ interrupt-parent = <&gic>;
+ interrupt-names = "tx", "rx", "status";
+ interrupts = <GIC_SPI 144 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 145 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 146 IRQ_TYPE_LEVEL_HIGH>;
+ adi,use-edbo;
+ status = "disabled";
+ };
+
+ uart3: uart@31003c00 {
+ compatible = "adi,uart";
+ reg = <0x31003C00 0x40>;
+ clocks = <&clk ADSP_SC598_CLK_CGU0_SCLK0>;
+ clock-names = "sclk0";
+ interrupt-parent = <&gic>;
+ interrupt-names = "tx", "rx", "status";
+ interrupts = <GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH>;
+ adi,use-edbo;
+ status = "disabled";
+ };
+
+ i2c0: twi@31001400 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "adi,twi";
+ reg = <0x31001400 0xFF>;
+ interrupts = <GIC_SPI 150 IRQ_TYPE_LEVEL_HIGH>;
+ clock-khz = <100>;
+ clocks = <&clk ADSP_SC598_CLK_CGU0_SCLK0>;
+ clock-names = "sclk0";
+ status = "disabled";
+ };
+
+ i2c1: twi@31001500 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "adi,twi";
+ reg = <0x31001500 0xFF>;
+ interrupts = <GIC_SPI 151 IRQ_TYPE_LEVEL_HIGH>;
+ clock-khz = <100>;
+ clocks = <&clk ADSP_SC598_CLK_CGU0_SCLK0>;
+ clock-names = "sclk0";
+ status = "disabled";
+ };
+
+ i2c3: twi@31001000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "adi,twi";
+ reg = <0x31001000 0xFF>;
+ interrupts = <GIC_SPI 153 IRQ_TYPE_LEVEL_HIGH>;
+ clock-khz = <100>;
+ clocks = <&clk ADSP_SC598_CLK_CGU0_SCLK0>;
+ clock-names = "sclk0";
+ status = "disabled";
+ };
+
+ i2c4: twi@31001100 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "adi,twi";
+ reg = <0x31001100 0xFF>;
+ interrupts = <GIC_SPI 154 IRQ_TYPE_LEVEL_HIGH>;
+ clock-khz = <100>;
+ clocks = <&clk ADSP_SC598_CLK_CGU0_SCLK0>;
+ clock-names = "sclk0";
+ status = "disabled";
+ };
+
+ i2c5: twi@31001200 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "adi,twi";
+ reg = <0x31001200 0xFF>;
+ interrupts = <GIC_SPI 155 IRQ_TYPE_LEVEL_HIGH>;
+ clock-khz = <100>;
+ clocks = <&clk ADSP_SC598_CLK_CGU0_SCLK0>;
+ clock-names = "sclk0";
+ status = "disabled";
+ };
+
+ pinctrl0: pinctrl@31004600 {
+ compatible = "adi,adsp-pinctrl";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x31004600 0x400>;
+ adi,port-sizes = <16 16 16 16 16 16 16 16 7>;
+ };
+
+ pint0: pint@31005000 {
+ compatible = "adi,adsp-pint";
+ reg = <0x31005000 0xFF>;
+ interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ pint1: pint@31005100 {
+ compatible = "adi,adsp-pint";
+ reg = <0x31005100 0xFF>;
+ interrupts = <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ pint2: pint@31005200 {
+ compatible = "adi,adsp-pint";
+ reg = <0x31005200 0xFF>;
+ interrupts = <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ pint3: pint@31005300 {
+ compatible = "adi,adsp-pint";
+ reg = <0x31005300 0xFF>;
+ interrupts = <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ pint4: pint@31005400 {
+ compatible = "adi,adsp-pint";
+ reg = <0x31005400 0xFF>;
+ interrupts = <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ pint5: pint@31005500 {
+ compatible = "adi,adsp-pint";
+ reg = <0x31005500 0xFF>;
+ interrupts = <GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ pint6: pint@31005600 {
+ compatible = "adi,adsp-pint";
+ reg = <0x31005600 0xFF>;
+ interrupts = <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ pint7: pint@31005700 {
+ compatible = "adi,adsp-pint";
+ reg = <0x31005700 0xFF>;
+ interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ gpa: gport@31004000 {
+ compatible = "adi,adsp-port-gpio";
+ gpio-controller;
+ #gpio-cells = <2>;
+ reg = <0x31004000 0x7F>;
+ gpio-ranges = <&pinctrl0 0 0 16>;
+ adi,pint = <&pint0 1>;
+ status = "okay";
+ };
+
+ gpb: gport@31004080 {
+ compatible = "adi,adsp-port-gpio";
+ gpio-controller;
+ #gpio-cells = <2>;
+ reg = <0x31004080 0x7F>;
+ gpio-ranges = <&pinctrl0 0 16 16>;
+ adi,pint = <&pint0 0>;
+ status = "okay";
+ };
+
+ gpc: gport@31004100 {
+ compatible = "adi,adsp-port-gpio";
+ gpio-controller;
+ #gpio-cells = <2>;
+ reg = <0x31004100 0x7F>;
+ gpio-ranges = <&pinctrl0 0 32 16>;
+ adi,pint = <&pint2 1>;
+ status = "okay";
+ };
+
+ gpd: gport@31004180 {
+ compatible = "adi,adsp-port-gpio";
+ gpio-controller;
+ #gpio-cells = <2>;
+ reg = <0x31004180 0x7F>;
+ gpio-ranges = <&pinctrl0 0 48 16>;
+ adi,pint = <&pint2 0>;
+ };
+
+ gpe: gport@31004200 {
+ compatible = "adi,adsp-port-gpio";
+ gpio-controller;
+ #gpio-cells = <2>;
+ reg = <0x31004200 0x7F>;
+ gpio-ranges = <&pinctrl0 0 64 16>;
+ adi,pint = <&pint4 1>;
+ };
+
+ gpf: gport@31004280 {
+ compatible = "adi,adsp-port-gpio";
+ gpio-controller;
+ #gpio-cells = <2>;
+ reg = <0x31004280 0x7F>;
+ gpio-ranges = <&pinctrl0 0 80 16>;
+ adi,pint = <&pint4 0>;
+ };
+
+ gpg: gport@31004300 {
+ compatible = "adi,adsp-port-gpio";
+ gpio-controller;
+ #gpio-cells = <2>;
+ reg = <0x31004300 0x7F>;
+ gpio-ranges = <&pinctrl0 0 96 16>;
+ adi,pint = <&pint6 1>;
+ };
+
+ gph: gport@31004380 {
+ compatible = "adi,adsp-port-gpio";
+ gpio-controller;
+ #gpio-cells = <2>;
+ reg = <0x31004380 0x7F>;
+ gpio-ranges = <&pinctrl0 0 112 16>;
+ adi,pint = <&pint6 0>;
+ };
+
+ gpi: gport@31004400 {
+ compatible = "adi,adsp-port-gpio";
+ gpio-controller;
+ #gpio-cells = <2>;
+ reg = <0x31004400 0x7F>;
+ gpio-ranges = <&pinctrl0 0 128 7>;
+ adi,pint = <&pint7 1>;
+ };
+
+ };
+};
--
2.25.1
^ permalink raw reply related [flat|nested] 65+ messages in thread
* Re: [PATCH 19/21] arm64: dts: adi: sc598: add device tree
2024-09-12 18:25 ` [PATCH 19/21] arm64: dts: adi: sc598: add device tree Arturs Artamonovs via B4 Relay
@ 2024-09-13 8:05 ` Arnd Bergmann
2024-09-16 7:04 ` Krzysztof Kozlowski
1 sibling, 0 replies; 65+ messages in thread
From: Arnd Bergmann @ 2024-09-13 8:05 UTC (permalink / raw)
To: arturs.artamonovs, Catalin Marinas, Will Deacon, Greg Malysa,
Philipp Zabel, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Utsav Agarwal, Michael Turquette, Stephen Boyd, Linus Walleij,
Bartosz Golaszewski, Thomas Gleixner, Andi Shyti,
Greg Kroah-Hartman, Jiri Slaby, Olof Johansson, soc
Cc: linux-arm-kernel, linux-kernel, devicetree, linux-clk,
open list:GPIO SUBSYSTEM, linux-i2c, linux-serial, adsp-linux,
Nathan Barrett-Morrison
On Thu, Sep 12, 2024, at 18:25, Arturs Artamonovs via B4 Relay wrote:
> +/ {
> + chosen {
> + stdout-path = &uart1;
> + bootargs = "earlycon=adi_uart,0x31003000 console=ttySC0,115200
> mem=224M";
> + };
You should not need the mem= and earlycon= arguments, as that data
is already part of the stdout-path property and the memory node.
> + aliases {
> + serial0 = &uart0;
> + serial2 = &uart2;
> + serial3 = &uart3;
> + };
The aliases are board specific, please only list the ones
that are actually enabled and wired on on a particular
board, and make the aliases match the labels on the board
rather than the internal components of hte chip.
> + cpus {
> + #address-cells = <0x2>;
> + #size-cells = <0x0>;
> +
> + cpu0: cpu@0 {
> + device_type = "cpu";
> + compatible = "arm,cortex-a55";
> + reg = <0x0 0x0>;
> + enable-method = "spin-table";
> + cpu-release-addr = <0x0 0xdeadbeef>;
Is that the actual address? It looks like some placeholder
that should not have been here.
Arnd
^ permalink raw reply [flat|nested] 65+ messages in thread
* Re: [PATCH 19/21] arm64: dts: adi: sc598: add device tree
2024-09-12 18:25 ` [PATCH 19/21] arm64: dts: adi: sc598: add device tree Arturs Artamonovs via B4 Relay
2024-09-13 8:05 ` Arnd Bergmann
@ 2024-09-16 7:04 ` Krzysztof Kozlowski
1 sibling, 0 replies; 65+ messages in thread
From: Krzysztof Kozlowski @ 2024-09-16 7:04 UTC (permalink / raw)
To: arturs.artamonovs, Catalin Marinas, Will Deacon, Greg Malysa,
Philipp Zabel, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Utsav Agarwal, Michael Turquette, Stephen Boyd, Linus Walleij,
Bartosz Golaszewski, Thomas Gleixner, Andi Shyti,
Greg Kroah-Hartman, Jiri Slaby, Arnd Bergmann, Olof Johansson,
soc
Cc: linux-arm-kernel, linux-kernel, devicetree, linux-clk, linux-gpio,
linux-i2c, linux-serial, adsp-linux, Nathan Barrett-Morrison
On 12/09/2024 20:25, Arturs Artamonovs via B4 Relay wrote:
> From: Arturs Artamonovs <arturs.artamonovs@analog.com>
>
> Add ADI SC598-EZKIT device tree.
> Support UART console as output.
>
> Signed-off-by: Arturs Artamonovs <Arturs.Artamonovs@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/boot/dts/Makefile | 1 +
> arch/arm64/boot/dts/adi/Makefile | 2 +
> arch/arm64/boot/dts/adi/sc598-som-ezkit.dts | 14 ++
> arch/arm64/boot/dts/adi/sc598-som.dtsi | 58 +++++
> arch/arm64/boot/dts/adi/sc59x-64.dtsi | 367 ++++++++++++++++++++++++++++
> 5 files changed, 442 insertions(+)
>
> diff --git a/arch/arm64/boot/dts/Makefile b/arch/arm64/boot/dts/Makefile
> index 21cd3a87f385309c3a655a67a3bee5f0abed7545..9b3996a8e01d8e7d264c44c075d7a50ee350ba44 100644
> --- a/arch/arm64/boot/dts/Makefile
> +++ b/arch/arm64/boot/dts/Makefile
> @@ -1,5 +1,6 @@
> # SPDX-License-Identifier: GPL-2.0
> subdir-y += actions
> +subdir-y += adi
> subdir-y += airoha
> subdir-y += allwinner
> subdir-y += altera
> diff --git a/arch/arm64/boot/dts/adi/Makefile b/arch/arm64/boot/dts/adi/Makefile
> new file mode 100644
> index 0000000000000000000000000000000000000000..1bf54bc97095e1ea3577953d379746fbc0ea02a9
> --- /dev/null
> +++ b/arch/arm64/boot/dts/adi/Makefile
> @@ -0,0 +1,2 @@
> +# SPDX-License-Identifier: GPL-2.0
> +dtb-$(CONFIG_ARCH_SC59X_64) += sc598-som-ezkit.dtb
> diff --git a/arch/arm64/boot/dts/adi/sc598-som-ezkit.dts b/arch/arm64/boot/dts/adi/sc598-som-ezkit.dts
> new file mode 100644
> index 0000000000000000000000000000000000000000..a8db6d5ea764f917faa6839d3d4f0b5217b927b8
> --- /dev/null
> +++ b/arch/arm64/boot/dts/adi/sc598-som-ezkit.dts
> @@ -0,0 +1,14 @@
> +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
> +/*
> + * Copyright 2021-2024 - Analog Devices Inc.
> + * Author: Nathan Barrett-Morrison <nathan.morrison@timesys.com>
> + */
> +
> +/dts-v1/;
> +
> +#include "sc598-som.dtsi"
> +
> +/ {
> + model = "ADI 64-bit SC598 SOM EZ Kit";
> + compatible = "adi,sc598-som-ezkit", "adi,sc59x-64";
Where is adi,sc598-som-ezlite?
> +};
> diff --git a/arch/arm64/boot/dts/adi/sc598-som.dtsi b/arch/arm64/boot/dts/adi/sc598-som.dtsi
> new file mode 100644
> index 0000000000000000000000000000000000000000..3b90f367db1a24de1e1dddc4db3c219736c5b90f
> --- /dev/null
> +++ b/arch/arm64/boot/dts/adi/sc598-som.dtsi
> @@ -0,0 +1,58 @@
> +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
> +/*
> + * Copyright 2021-2024 - Analog Devices Inc.
> + * Author: Nathan Barrett-Morrison <nathan.morrison@timesys.com>
> + */
> +
> +/dts-v1/;
> +
> +#include <dt-bindings/gpio/gpio.h>
> +#include <dt-bindings/pinctrl/adi-adsp.h>
> +#include "sc59x-64.dtsi"
> +
> +/ {
> + chosen {
> + stdout-path = &uart1;
> + bootargs = "earlycon=adi_uart,0x31003000 console=ttySC0,115200 mem=224M";
Drop entire bootargs. Look how other SoCs do it, if you need port speed.
> + };
> +
> + memory@90000000 {
> + device_type = "memory";
> + reg = <0x90000000 0x0e000000>;
> + };
> +
> + memory@20040000 {
> + device_type = "memory";
> + reg = <0x20040000 0x40000>;
> + };
> +
> + scb: scb-bus {
What is this?
> + sec: sec@31089000 {
And this?
> + adi,sharc-cores = <2>;
> + };
> + };
Drop entire node.
> +
Fix redundant blank lines.
> +};
> +
> +&uart0 {
> + pinctrl-0 = <&uart0_default>;
> + pinctrl-names = "default";
> + status = "okay";
> +};
> +
> +&i2c0 {
> + status = "okay";
> +};
> +
> +&i2c1 {
> + status = "disabled";
> +};
> +
> +&pinctrl0 {
> + uart0_default: uart0-default-pins {
> + pins {
> + pinmux = <ADI_ADSP_PINMUX('A', 6, ADI_ADSP_PINFUNC_ALT1)>,
> + <ADI_ADSP_PINMUX('A', 7, ADI_ADSP_PINFUNC_ALT1)>;
> + };
> + };
> +};
> diff --git a/arch/arm64/boot/dts/adi/sc59x-64.dtsi b/arch/arm64/boot/dts/adi/sc59x-64.dtsi
> new file mode 100644
> index 0000000000000000000000000000000000000000..4a9aa08b4acb0936c97e683562e05da063a4e193
> --- /dev/null
> +++ b/arch/arm64/boot/dts/adi/sc59x-64.dtsi
> @@ -0,0 +1,367 @@
> +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
> +/*
> + * Copyright 2021-2024 - Analog Devices Inc.
> + * Author: Nathan Barrett-Morrison <nathan.morrison@timesys.com>
> + */
> +
> +#include <dt-bindings/clock/adi-sc5xx-clock.h>
> +#include <dt-bindings/interrupt-controller/arm-gic.h>
> +#include <dt-bindings/interrupt-controller/irq.h>
> +
> +/ {
> + model = "ADI 64-bit SC59X";
> + compatible = "adi,sc59x-64";
> +
> + interrupt-parent = <&gic>;
> + #address-cells = <1>;
> + #size-cells = <1>;
> +
> + chosen { };
Drop
> +
> + aliases {
> + serial0 = &uart0;
> + serial2 = &uart2;
> + serial3 = &uart3;
> + };
Drop or move to board DTS. Not a property of the SoC.
> +
> + cpus {
> + #address-cells = <0x2>;
> + #size-cells = <0x0>;
> +
> + cpu0: cpu@0 {
> + device_type = "cpu";
> + compatible = "arm,cortex-a55";
> + reg = <0x0 0x0>;
> + enable-method = "spin-table";
> + cpu-release-addr = <0x0 0xdeadbeef>;
> + clocks = <&clk ADSP_SC598_CLK_ARM>, <&clk ADSP_SC598_CLK_DDR>;
> + };
> + };
> +
> + pmu {
Order nodes alphabetically. See DTS coding style.
> + compatible = "arm,armv8-pmuv3";
> + interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_HIGH>;
> + interrupt-parent = <&gic>;
> + };
> +
> + gic: interrupt-controller@31200000 {
This cannot be outside of SoC. See writing-bindings and DTS coding style.
> + compatible = "arm,gic-v3";
> + #interrupt-cells = <3>;
> + interrupt-controller;
> + reg = <0x31200000 0x40000>, /* GIC Dist */
> + <0x31240000 0x40000>; /* GICR */
> + };
> +
> + timer {
> + compatible = "arm,armv8-timer";
> + interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>, /* Physical Secure */
> + <GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>, /* Physical Non-Secure */
> + <GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>, /* Virtual */
> + <GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>; /* Hypervisor */
> + };
> +
> + clocks {
> + sys_clkin0: oscillator@1 {
There is no way you tested it. It's obvious W=1 warning.
> + compatible = "fixed-clock";
> + #clock-cells = <0>;
> + clock-frequency = <25000000>;
> + clock-output-names = "sys_clkin0";
> + };
> +
> + sys_clkin1: oscillator@2 {
How are these properties of the SoC? Where are they located physically?
See DTS coding style.
> + compatible = "fixed-clock";
> + #clock-cells = <0>;
> + clock-frequency = <25000000>;
> + clock-output-names = "sys_clkin1";
> + };
> + };
> +
> + clk: clocks@3108d000 {
> + compatible = "adi,sc598-clocks";
> + reg = <0x3108d000 0x1000>,
> + <0x3108e000 0x1000>,
> + <0x3108f000 0x1000>,
> + <0x310a9000 0x1000>;
> + #clock-cells = <1>;
> + clocks = <&sys_clkin0>, <&sys_clkin1>;
> + clock-names = "sys_clkin0", "sys_clkin1";
> + status = "okay";
Drop... everywhere.
> + };
> +
> + scb: scb-bus {
What is scb-bus?
See DTS coding style or any other SoC. This is supposed to be just sco@
with proper unit address.
> + compatible = "simple-bus";
> + #address-cells = <1>;
> + #size-cells = <1>;
> + ranges;
> +
> + rcu: rcu@3108c000 {
> + compatible = "adi,reset-controller";
> + reg = <0x3108c000 0x1000>;
> + status = "okay";
Oh...
> + };
> +
> + sec: sec@31089000 {
Random order of nodes? See DTS coding style.
> + compatible = "adi,system-event-controller";
> + reg = <0x31089000 0x1000>;
> + adi,rcu = <&rcu>;
> + status = "okay";
> + };
> +
> + uart0: uart@31003000 {
Never tested.
It does not look like you tested the DTS against bindings. Please run
`make dtbs_check W=1` (see
Documentation/devicetree/bindings/writing-schema.rst or
https://www.linaro.org/blog/tips-and-tricks-for-validating-devicetree-sources-with-the-devicetree-schema/
for instructions).
> + compatible = "adi,uart";
> + reg = <0x31003000 0x40>;
> + clocks = <&clk ADSP_SC598_CLK_CGU0_SCLK0>;
> + clock-names = "sclk0";
> + interrupt-parent = <&gic>;
> + interrupt-names = "tx", "rx", "status";
> + interrupts = <GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>,
> + <GIC_SPI 139 IRQ_TYPE_LEVEL_HIGH>,
> + <GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>;
> + adi,use-edbo;
> + status = "disabled";
> + };
> +
> + uart1: uart@31003400 {
> + compatible = "adi,uart";
> + reg = <0x31003400 0x40>;
> + clocks = <&clk ADSP_SC598_CLK_CGU0_SCLK0>;
> + clock-names = "sclk0";
> + interrupt-parent = <&gic>;
> + interrupt-names = "tx", "rx", "status";
> + interrupts = <GIC_SPI 141 IRQ_TYPE_LEVEL_HIGH>,
> + <GIC_SPI 142 IRQ_TYPE_LEVEL_HIGH>,
> + <GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH>;
> + adi,use-edbo;
> + status = "disabled";
> + };
> +
> + uart2: uart@31003800 {
> + compatible = "adi,uart";
> + reg = <0x31003800 0x40>;
> + clocks = <&clk ADSP_SC598_CLK_CGU0_SCLK0>;
> + clock-names = "sclk0";
> + interrupt-parent = <&gic>;
> + interrupt-names = "tx", "rx", "status";
> + interrupts = <GIC_SPI 144 IRQ_TYPE_LEVEL_HIGH>,
> + <GIC_SPI 145 IRQ_TYPE_LEVEL_HIGH>,
> + <GIC_SPI 146 IRQ_TYPE_LEVEL_HIGH>;
> + adi,use-edbo;
> + status = "disabled";
> + };
> +
> + uart3: uart@31003c00 {
> + compatible = "adi,uart";
> + reg = <0x31003C00 0x40>;
> + clocks = <&clk ADSP_SC598_CLK_CGU0_SCLK0>;
> + clock-names = "sclk0";
> + interrupt-parent = <&gic>;
> + interrupt-names = "tx", "rx", "status";
> + interrupts = <GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH>,
> + <GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>,
> + <GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH>;
> + adi,use-edbo;
> + status = "disabled";
> + };
> +
> + i2c0: twi@31001400 {
Node names should be generic. See also an explanation and list of
examples (not exhaustive) in DT specification:
https://devicetree-specification.readthedocs.io/en/latest/chapter2-devicetree-basics.html#generic-names-recommendation
Completely wrong order of properties. Please follow DTS coding style.
> + #address-cells = <1>;
> + #size-cells = <0>;
> + compatible = "adi,twi";
You cannot have generic compatibles in the SoC.
> + reg = <0x31001400 0xFF>;
I already commented on lower case hex.
> + interrupts = <GIC_SPI 150 IRQ_TYPE_LEVEL_HIGH>;
> + clock-khz = <100>;
> + clocks = <&clk ADSP_SC598_CLK_CGU0_SCLK0>;
> + clock-names = "sclk0";
> + status = "disabled";
> + };
> +
> + i2c1: twi@31001500 {
> + #address-cells = <1>;
> + #size-cells = <0>;
> + compatible = "adi,twi";
> + reg = <0x31001500 0xFF>;
> + interrupts = <GIC_SPI 151 IRQ_TYPE_LEVEL_HIGH>;
> + clock-khz = <100>;
> + clocks = <&clk ADSP_SC598_CLK_CGU0_SCLK0>;
> + clock-names = "sclk0";
> + status = "disabled";
> + };
> +
> + i2c3: twi@31001000 {
> + #address-cells = <1>;
> + #size-cells = <0>;
> + compatible = "adi,twi";
> + reg = <0x31001000 0xFF>;
> + interrupts = <GIC_SPI 153 IRQ_TYPE_LEVEL_HIGH>;
> + clock-khz = <100>;
> + clocks = <&clk ADSP_SC598_CLK_CGU0_SCLK0>;
> + clock-names = "sclk0";
> + status = "disabled";
> + };
> +
> + i2c4: twi@31001100 {
> + #address-cells = <1>;
> + #size-cells = <0>;
> + compatible = "adi,twi";
> + reg = <0x31001100 0xFF>;
> + interrupts = <GIC_SPI 154 IRQ_TYPE_LEVEL_HIGH>;
> + clock-khz = <100>;
> + clocks = <&clk ADSP_SC598_CLK_CGU0_SCLK0>;
> + clock-names = "sclk0";
> + status = "disabled";
> + };
> +
> + i2c5: twi@31001200 {
> + #address-cells = <1>;
> + #size-cells = <0>;
> + compatible = "adi,twi";
> + reg = <0x31001200 0xFF>;
> + interrupts = <GIC_SPI 155 IRQ_TYPE_LEVEL_HIGH>;
> + clock-khz = <100>;
> + clocks = <&clk ADSP_SC598_CLK_CGU0_SCLK0>;
> + clock-names = "sclk0";
> + status = "disabled";
> + };
> +
> + pinctrl0: pinctrl@31004600 {
> + compatible = "adi,adsp-pinctrl";
> + #address-cells = <1>;
> + #size-cells = <1>;
> + reg = <0x31004600 0x400>;
> + adi,port-sizes = <16 16 16 16 16 16 16 16 7>;
> + };
> +
> + pint0: pint@31005000 {
> + compatible = "adi,adsp-pint";
> + reg = <0x31005000 0xFF>;
> + interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>;
> + };
> +
> + pint1: pint@31005100 {
> + compatible = "adi,adsp-pint";
> + reg = <0x31005100 0xFF>;
> + interrupts = <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>;
> + };
> +
> + pint2: pint@31005200 {
Node names should be generic. See also an explanation and list of
examples (not exhaustive) in DT specification:
https://devicetree-specification.readthedocs.io/en/latest/chapter2-devicetree-basics.html#generic-names-recommendation
> + compatible = "adi,adsp-pint";
> + reg = <0x31005200 0xFF>;
> + interrupts = <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>;
> + };
> +
> + pint3: pint@31005300 {
> + compatible = "adi,adsp-pint";
> + reg = <0x31005300 0xFF>;
> + interrupts = <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>;
> + };
> +
> + pint4: pint@31005400 {
> + compatible = "adi,adsp-pint";
> + reg = <0x31005400 0xFF>;
> + interrupts = <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>;
> + };
> +
> + pint5: pint@31005500 {
> + compatible = "adi,adsp-pint";
> + reg = <0x31005500 0xFF>;
> + interrupts = <GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>;
> + };
> +
> + pint6: pint@31005600 {
> + compatible = "adi,adsp-pint";
> + reg = <0x31005600 0xFF>;
> + interrupts = <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>;
> + };
> +
> + pint7: pint@31005700 {
> + compatible = "adi,adsp-pint";
> + reg = <0x31005700 0xFF>;
> + interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>;
> + };
> +
> + gpa: gport@31004000 {
Node names should be generic. See also an explanation and list of
examples (not exhaustive) in DT specification:
https://devicetree-specification.readthedocs.io/en/latest/chapter2-devicetree-basics.html#generic-names-recommendation
> + compatible = "adi,adsp-port-gpio";
> + gpio-controller;
> + #gpio-cells = <2>;
> + reg = <0x31004000 0x7F>;
> + gpio-ranges = <&pinctrl0 0 0 16>;
> + adi,pint = <&pint0 1>;
> + status = "okay";
> + };
> +
> + gpb: gport@31004080 {
> + compatible = "adi,adsp-port-gpio";
> + gpio-controller;
> + #gpio-cells = <2>;
> + reg = <0x31004080 0x7F>;
> + gpio-ranges = <&pinctrl0 0 16 16>;
> + adi,pint = <&pint0 0>;
> + status = "okay";
> + };
> +
> + gpc: gport@31004100 {
> + compatible = "adi,adsp-port-gpio";
> + gpio-controller;
> + #gpio-cells = <2>;
> + reg = <0x31004100 0x7F>;
> + gpio-ranges = <&pinctrl0 0 32 16>;
> + adi,pint = <&pint2 1>;
> + status = "okay";
> + };
> +
> + gpd: gport@31004180 {
> + compatible = "adi,adsp-port-gpio";
> + gpio-controller;
> + #gpio-cells = <2>;
> + reg = <0x31004180 0x7F>;
> + gpio-ranges = <&pinctrl0 0 48 16>;
> + adi,pint = <&pint2 0>;
> + };
> +
> + gpe: gport@31004200 {
> + compatible = "adi,adsp-port-gpio";
> + gpio-controller;
> + #gpio-cells = <2>;
> + reg = <0x31004200 0x7F>;
> + gpio-ranges = <&pinctrl0 0 64 16>;
> + adi,pint = <&pint4 1>;
> + };
> +
> + gpf: gport@31004280 {
> + compatible = "adi,adsp-port-gpio";
> + gpio-controller;
> + #gpio-cells = <2>;
> + reg = <0x31004280 0x7F>;
> + gpio-ranges = <&pinctrl0 0 80 16>;
> + adi,pint = <&pint4 0>;
> + };
> +
> + gpg: gport@31004300 {
> + compatible = "adi,adsp-port-gpio";
> + gpio-controller;
> + #gpio-cells = <2>;
> + reg = <0x31004300 0x7F>;
> + gpio-ranges = <&pinctrl0 0 96 16>;
> + adi,pint = <&pint6 1>;
> + };
> +
> + gph: gport@31004380 {
> + compatible = "adi,adsp-port-gpio";
> + gpio-controller;
> + #gpio-cells = <2>;
> + reg = <0x31004380 0x7F>;
> + gpio-ranges = <&pinctrl0 0 112 16>;
> + adi,pint = <&pint6 0>;
> + };
> +
> + gpi: gport@31004400 {
> + compatible = "adi,adsp-port-gpio";
> + gpio-controller;
> + #gpio-cells = <2>;
> + reg = <0x31004400 0x7F>;
> + gpio-ranges = <&pinctrl0 0 128 7>;
> + adi,pint = <&pint7 1>;
> + };
> +
All your patches have such sloppy blank lines here and there.
> + };
> +};
>
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 65+ messages in thread
* [PATCH 20/21] arm64: defconfig: sc598 add minimal changes
2024-09-12 18:24 [PATCH 00/21] Adding support of ADI ARMv8 ADSP-SC598 SoC Arturs Artamonovs via B4 Relay
` (18 preceding siblings ...)
2024-09-12 18:25 ` [PATCH 19/21] arm64: dts: adi: sc598: add device tree Arturs Artamonovs via B4 Relay
@ 2024-09-12 18:25 ` Arturs Artamonovs via B4 Relay
2024-09-13 7:44 ` Arnd Bergmann
2024-09-16 6:58 ` Krzysztof Kozlowski
2024-09-12 18:25 ` [PATCH 21/21] MAINTAINERS: add adi sc5xx maintainers Arturs Artamonovs via B4 Relay
` (3 subsequent siblings)
23 siblings, 2 replies; 65+ messages in thread
From: Arturs Artamonovs via B4 Relay @ 2024-09-12 18:25 UTC (permalink / raw)
To: Catalin Marinas, Will Deacon, Greg Malysa, Philipp Zabel,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Utsav Agarwal,
Michael Turquette, Stephen Boyd, Linus Walleij,
Bartosz Golaszewski, Thomas Gleixner, Andi Shyti,
Greg Kroah-Hartman, Jiri Slaby, Arnd Bergmann, Olof Johansson,
soc
Cc: linux-arm-kernel, linux-kernel, devicetree, linux-clk, linux-gpio,
linux-i2c, linux-serial, Arturs Artamonovs, adsp-linux,
Arturs Artamonovs, Nathan Barrett-Morrison
From: Arturs Artamonovs <arturs.artamonovs@analog.com>
Add ADSP-SC598 defconfig
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/configs/defconfig | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index 362df939026383a26ee23485d1ec25b252b90d5d..7801dd7d7d65bc504dc6e2945f92f261f2911115 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -67,6 +67,7 @@ CONFIG_ARCH_SEATTLE=y
CONFIG_ARCH_INTEL_SOCFPGA=y
CONFIG_ARCH_STM32=y
CONFIG_ARCH_SYNQUACER=y
+CONFIG_ARCH_SC59X_64=y
CONFIG_ARCH_TEGRA=y
CONFIG_ARCH_TESLA_FSD=y
CONFIG_ARCH_SPRD=y
@@ -473,6 +474,7 @@ CONFIG_SERIAL_8250_OMAP=y
CONFIG_SERIAL_8250_MT6577=y
CONFIG_SERIAL_8250_UNIPHIER=y
CONFIG_SERIAL_OF_PLATFORM=y
+CONFIG_SERIAL_ADI_UART=y
CONFIG_SERIAL_AMBA_PL011=y
CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
CONFIG_SERIAL_MESON=y
@@ -513,6 +515,7 @@ CONFIG_TCG_TIS_I2C_CR50=m
CONFIG_TCG_TIS_I2C_INFINEON=y
CONFIG_I2C_CHARDEV=y
CONFIG_I2C_MUX=y
+CONFIG_I2C_ADI_TWI=y
CONFIG_I2C_MUX_PCA954x=y
CONFIG_I2C_BCM2835=m
CONFIG_I2C_CADENCE=m
@@ -539,6 +542,7 @@ CONFIG_I2C_UNIPHIER_F=y
CONFIG_I2C_RCAR=y
CONFIG_I2C_CROS_EC_TUNNEL=y
CONFIG_SPI=y
+CONFIG_SPI_ADI=y
CONFIG_SPI_ARMADA_3700=y
CONFIG_SPI_BCM2835=m
CONFIG_SPI_BCM2835AUX=m
@@ -637,6 +641,7 @@ CONFIG_PINCTRL_SM8450_LPASS_LPI=m
CONFIG_PINCTRL_SC8280XP_LPASS_LPI=m
CONFIG_PINCTRL_SM8550_LPASS_LPI=m
CONFIG_PINCTRL_SM8650_LPASS_LPI=m
+CONFIG_GPIO_ADI_ADSP_PORT=y
CONFIG_GPIO_ALTERA=m
CONFIG_GPIO_DAVINCI=y
CONFIG_GPIO_DWAPB=y
@@ -1512,6 +1517,7 @@ CONFIG_RESET_QCOM_AOSS=y
CONFIG_RESET_QCOM_PDC=m
CONFIG_RESET_RZG2L_USBPHY_CTRL=y
CONFIG_RESET_TI_SCI=y
+CONFIG_RESET_SC5XX=y
CONFIG_PHY_XGENE=y
CONFIG_PHY_CAN_TRANSCEIVER=m
CONFIG_PHY_SUN4I_USB=y
--
2.25.1
^ permalink raw reply related [flat|nested] 65+ messages in thread
* Re: [PATCH 20/21] arm64: defconfig: sc598 add minimal changes
2024-09-12 18:25 ` [PATCH 20/21] arm64: defconfig: sc598 add minimal changes Arturs Artamonovs via B4 Relay
@ 2024-09-13 7:44 ` Arnd Bergmann
2024-09-16 6:58 ` Krzysztof Kozlowski
1 sibling, 0 replies; 65+ messages in thread
From: Arnd Bergmann @ 2024-09-13 7:44 UTC (permalink / raw)
To: arturs.artamonovs, Catalin Marinas, Will Deacon, Greg Malysa,
Philipp Zabel, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Utsav Agarwal, Michael Turquette, Stephen Boyd, Linus Walleij,
Bartosz Golaszewski, Thomas Gleixner, Andi Shyti,
Greg Kroah-Hartman, Jiri Slaby, Olof Johansson, soc
Cc: linux-arm-kernel, linux-kernel, devicetree, linux-clk,
open list:GPIO SUBSYSTEM, linux-i2c, linux-serial, adsp-linux,
Nathan Barrett-Morrison
On Thu, Sep 12, 2024, at 18:25, Arturs Artamonovs via B4 Relay wrote:
> From: Arturs Artamonovs <arturs.artamonovs@analog.com>
>
> Add ADSP-SC598 defconfig
>
> @@ -513,6 +515,7 @@ CONFIG_TCG_TIS_I2C_CR50=m
> CONFIG_TCG_TIS_I2C_INFINEON=y
> CONFIG_I2C_CHARDEV=y
> CONFIG_I2C_MUX=y
> +CONFIG_I2C_ADI_TWI=y
> CONFIG_I2C_MUX_PCA954x=y
> CONFIG_I2C_BCM2835=m
> CONFIG_I2C_CADENCE=m
> @@ -539,6 +542,7 @@ CONFIG_I2C_UNIPHIER_F=y
> CONFIG_I2C_RCAR=y
> CONFIG_I2C_CROS_EC_TUNNEL=y
> CONFIG_SPI=y
> +CONFIG_SPI_ADI=y
> CONFIG_SPI_ARMADA_3700=y
> CONFIG_SPI_BCM2835=m
> CONFIG_SPI_BCM2835AUX=m
These are usually not required for booting and should be
made loadable modules if possible.
Arnd
^ permalink raw reply [flat|nested] 65+ messages in thread
* Re: [PATCH 20/21] arm64: defconfig: sc598 add minimal changes
2024-09-12 18:25 ` [PATCH 20/21] arm64: defconfig: sc598 add minimal changes Arturs Artamonovs via B4 Relay
2024-09-13 7:44 ` Arnd Bergmann
@ 2024-09-16 6:58 ` Krzysztof Kozlowski
1 sibling, 0 replies; 65+ messages in thread
From: Krzysztof Kozlowski @ 2024-09-16 6:58 UTC (permalink / raw)
To: arturs.artamonovs, Catalin Marinas, Will Deacon, Greg Malysa,
Philipp Zabel, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Utsav Agarwal, Michael Turquette, Stephen Boyd, Linus Walleij,
Bartosz Golaszewski, Thomas Gleixner, Andi Shyti,
Greg Kroah-Hartman, Jiri Slaby, Arnd Bergmann, Olof Johansson,
soc
Cc: linux-arm-kernel, linux-kernel, devicetree, linux-clk, linux-gpio,
linux-i2c, linux-serial, adsp-linux, Nathan Barrett-Morrison
On 12/09/2024 20:25, Arturs Artamonovs via B4 Relay wrote:
> From: Arturs Artamonovs <arturs.artamonovs@analog.com>
>
> Add ADSP-SC598 defconfig
That's neither true nor helpful. Say more about hardware. That's a
defconfig for all platforms, not only yours.
>
> 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>
4 people contributed to simple defconfig? How?
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 65+ messages in thread
* [PATCH 21/21] MAINTAINERS: add adi sc5xx maintainers
2024-09-12 18:24 [PATCH 00/21] Adding support of ADI ARMv8 ADSP-SC598 SoC Arturs Artamonovs via B4 Relay
` (19 preceding siblings ...)
2024-09-12 18:25 ` [PATCH 20/21] arm64: defconfig: sc598 add minimal changes Arturs Artamonovs via B4 Relay
@ 2024-09-12 18:25 ` Arturs Artamonovs via B4 Relay
2024-09-12 21:04 ` [PATCH 00/21] Adding support of ADI ARMv8 ADSP-SC598 SoC Rob Herring (Arm)
` (2 subsequent siblings)
23 siblings, 0 replies; 65+ messages in thread
From: Arturs Artamonovs via B4 Relay @ 2024-09-12 18:25 UTC (permalink / raw)
To: Catalin Marinas, Will Deacon, Greg Malysa, Philipp Zabel,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Utsav Agarwal,
Michael Turquette, Stephen Boyd, Linus Walleij,
Bartosz Golaszewski, Thomas Gleixner, Andi Shyti,
Greg Kroah-Hartman, Jiri Slaby, Arnd Bergmann, Olof Johansson,
soc
Cc: linux-arm-kernel, linux-kernel, devicetree, linux-clk, linux-gpio,
linux-i2c, linux-serial, Arturs Artamonovs, adsp-linux,
Arturs Artamonovs
From: Arturs Artamonovs <arturs.artamonovs@analog.com>
Add ADSP-SC598 maitaniners
Signed-off-by: Arturs Artamonovs <Arturs.Artamonovs@analog.com>
---
MAINTAINERS | 22 ++++++++++++++++++++++
1 file changed, 22 insertions(+)
diff --git a/MAINTAINERS b/MAINTAINERS
index 10430778c998b57944c1a6c5f07d676127e47faa..a838a5392321602034755fafed720f68d3798c0b 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1934,6 +1934,28 @@ S: Odd Fixes
F: arch/arm/boot/dts/airoha/
F: arch/arm64/boot/dts/airoha/
+ARM/ADI SoC Support
+M: Arturs Artamonovs <arturs.artamonovs@analog.com>
+M: Greg Malysa <greg.malysa@timesys.com>
+S: Maintained
+F: Documentation/devicetree/bindings/arm/analog/adi,sc5xx.yaml
+F: Documentation/devicetree/bindings/clock/adi,sc5xx-clocks.yaml
+F: Documentation/devicetree/bindings/gpio/adi,adsp-port-gpio.yaml
+F: Documentation/devicetree/bindings/i2c/adi,twi.yaml
+F: Documentation/devicetree/bindings/interrupt-controller/adi,adsp-pint.yaml
+F: Documentation/devicetree/bindings/pinctrl/adi,adsp-pinctrl.yaml
+F: Documentation/devicetree/bindings/serial/adi,uart.yaml
+F: Documentation/devicetree/bindings/serial/adi,uart.yaml
+F: Documentation/devicetree/bindings/soc/adi/*
+F: arch/arm64/boot/dts/adi/*
+F: drivers/clk/adi/*
+F: drivers/gpio/gpio-adi-adsp-port.c
+F: drivers/i2c/busses/i2c-adi-twi.c
+F: drivers/irqchip/irq-adi-adsp.c
+F: drivers/soc/adi/*
+F: drivers/tty/serial/adi_uart.c
+
+
ARM/Allwinner SoC Clock Support
M: Emilio López <emilio@elopez.com.ar>
S: Maintained
--
2.25.1
^ permalink raw reply related [flat|nested] 65+ messages in thread
* Re: [PATCH 00/21] Adding support of ADI ARMv8 ADSP-SC598 SoC.
2024-09-12 18:24 [PATCH 00/21] Adding support of ADI ARMv8 ADSP-SC598 SoC Arturs Artamonovs via B4 Relay
` (20 preceding siblings ...)
2024-09-12 18:25 ` [PATCH 21/21] MAINTAINERS: add adi sc5xx maintainers Arturs Artamonovs via B4 Relay
@ 2024-09-12 21:04 ` Rob Herring (Arm)
2024-09-16 6:57 ` Krzysztof Kozlowski
2024-09-13 8:20 ` Arnd Bergmann
2024-09-16 9:05 ` Krzysztof Kozlowski
23 siblings, 1 reply; 65+ messages in thread
From: Rob Herring (Arm) @ 2024-09-12 21:04 UTC (permalink / raw)
To: Arturs Artamonovs
Cc: Olof Johansson, devicetree, Jiri Slaby, Catalin Marinas,
Michael Turquette, Thomas Gleixner, Greg Kroah-Hartman, soc,
linux-clk, linux-serial, Andi Shyti, Arturs Artamonovs,
linux-arm-kernel, linux-i2c, Greg Malysa, Will Deacon,
Philipp Zabel, Nathan Barrett-Morrison, Linus Walleij,
Arnd Bergmann, Utsav Agarwal, Bartosz Golaszewski, linux-kernel,
Krzysztof Kozlowski, adsp-linux, Conor Dooley, linux-gpio,
Stephen Boyd
On Thu, 12 Sep 2024 19:24:45 +0100, Arturs Artamonovs wrote:
> This set of patches based on ADI fork of Linux Kerenl that support family of ADSP-SC5xx
> SoC's and used by customers for some time . Patch series contains minimal set
> of changes to add ADSP-SC598 support to upstream kernel. This series include
> UART,I2C,IRQCHIP,RCU drivers and device-tree to be able boot on EV-SC598-SOM
> board into serial shell and able to reset the board. Current SOM board
> requires I2C expander to enable UART output.
>
> UART,I2C and PINCTRL drivers are based on old Blackfin drivers with
> ADSP-SC5xx related bug fixes and improvments.
>
> Signed-off-by: Arturs Artamonovs <arturs.artamonovs@analog.com>
> ---
> Arturs Artamonovs (21):
> arm64: Add ADI ADSP-SC598 SoC
> reset: Add driver for ADI ADSP-SC5xx reset controller
> dt-bindigs: arm64: adi,sc598 bindings
> dt-bindings: arm64: adi,sc598: Add ADSP-SC598 SoC bindings
> clock:Add driver for ADI ADSP-SC5xx PLL
> include: dt-binding: clock: add adi clock header file
> clock: Add driver for ADI ADSP-SC5xx clock
> dt-bindings: clock: adi,sc5xx-clocks: add bindings
> gpio: add driver for ADI ADSP-SC5xx platform
> dt-bindings: gpio: adi,adsp-port-gpio: add bindings
> irqchip: Add irqchip for ADI ADSP-SC5xx platform
> dt-bindings: irqchip: adi,adsp-pint: add binding
> pinctrl: Add drivers for ADI ADSP-SC5xx platform
> dt-bindings: pinctrl: adi,adsp-pinctrl: add bindings
> i2c: Add driver for ADI ADSP-SC5xx platforms
> dt-bindings: i2c: add i2c/twi driver documentation
> serial: adi,uart: Add driver for ADI ADSP-SC5xx
> dt-bindings: serial: adi,uart4: add adi,uart4 driver documentation
> arm64: dts: adi: sc598: add device tree
> arm64: defconfig: sc598 add minimal changes
> MAINTAINERS: add adi sc5xx maintainers
>
> .../devicetree/bindings/arm/analog/adi,sc5xx.yaml | 24 +
> .../bindings/clock/adi,sc5xx-clocks.yaml | 65 ++
> .../bindings/gpio/adi,adsp-port-gpio.yaml | 69 ++
> Documentation/devicetree/bindings/i2c/adi,twi.yaml | 71 ++
> .../interrupt-controller/adi,adsp-pint.yaml | 51 +
> .../bindings/pinctrl/adi,adsp-pinctrl.yaml | 83 ++
> .../devicetree/bindings/serial/adi,uart.yaml | 85 ++
> .../bindings/soc/adi/adi,reset-controller.yaml | 38 +
> MAINTAINERS | 22 +
> arch/arm64/Kconfig.platforms | 13 +
> arch/arm64/boot/dts/Makefile | 1 +
> arch/arm64/boot/dts/adi/Makefile | 2 +
> arch/arm64/boot/dts/adi/sc598-som-ezkit.dts | 14 +
> arch/arm64/boot/dts/adi/sc598-som.dtsi | 58 ++
> arch/arm64/boot/dts/adi/sc59x-64.dtsi | 367 +++++++
> arch/arm64/configs/defconfig | 6 +
> drivers/clk/Kconfig | 9 +
> drivers/clk/Makefile | 1 +
> drivers/clk/adi/Makefile | 4 +
> drivers/clk/adi/clk-adi-pll.c | 151 +++
> drivers/clk/adi/clk-adi-sc598.c | 329 ++++++
> drivers/clk/adi/clk.h | 99 ++
> drivers/gpio/Kconfig | 8 +
> drivers/gpio/Makefile | 1 +
> drivers/gpio/gpio-adi-adsp-port.c | 145 +++
> drivers/i2c/busses/Kconfig | 17 +
> drivers/i2c/busses/Makefile | 1 +
> drivers/i2c/busses/i2c-adi-twi.c | 940 ++++++++++++++++++
> drivers/irqchip/Kconfig | 9 +
> drivers/irqchip/Makefile | 2 +
> drivers/irqchip/irq-adi-adsp.c | 310 ++++++
> drivers/pinctrl/Kconfig | 12 +
> drivers/pinctrl/Makefile | 1 +
> drivers/pinctrl/pinctrl-adsp.c | 919 +++++++++++++++++
> drivers/reset/Makefile | 1 +
> drivers/soc/Makefile | 1 +
> drivers/soc/adi/Makefile | 5 +
> drivers/soc/adi/system.c | 257 +++++
> drivers/tty/serial/Kconfig | 19 +-
> drivers/tty/serial/Makefile | 1 +
> drivers/tty/serial/adi_uart.c | 1045 ++++++++++++++++++++
> include/dt-bindings/clock/adi-sc5xx-clock.h | 93 ++
> include/dt-bindings/pinctrl/adi-adsp.h | 19 +
> 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 ++
> include/uapi/linux/serial_core.h | 3 +
> 49 files changed, 5829 insertions(+), 1 deletion(-)
> ---
> base-commit: da3ea35007d0af457a0afc87e84fddaebc4e0b63
> change-id: 20240909-test-8ec5f76fe6d2
>
> Best regards,
> --
> Arturs Artamonovs <arturs.artamonovs@analog.com>
>
>
>
My bot found new DTB warnings on the .dts files added or changed in this
series.
Some warnings may be from an existing SoC .dtsi. Or perhaps the warnings
are fixed by another series. Ultimately, it is up to the platform
maintainer whether these warnings are acceptable or not. No need to reply
unless the platform maintainer has comments.
If you already ran DT checks and didn't see these error(s), then
make sure dt-schema is up to date:
pip3 install dtschema --upgrade
New warnings running 'make CHECK_DTBS=y adi/sc598-som-ezkit.dtb' for 20240912-test-v1-0-458fa57c8ccf@analog.com:
arch/arm64/boot/dts/adi/sc598-som-ezkit.dtb: /scb-bus/sec@31089000: failed to match any schema with compatible: ['adi,system-event-controller']
^ permalink raw reply [flat|nested] 65+ messages in thread
* Re: [PATCH 00/21] Adding support of ADI ARMv8 ADSP-SC598 SoC.
2024-09-12 21:04 ` [PATCH 00/21] Adding support of ADI ARMv8 ADSP-SC598 SoC Rob Herring (Arm)
@ 2024-09-16 6:57 ` Krzysztof Kozlowski
0 siblings, 0 replies; 65+ messages in thread
From: Krzysztof Kozlowski @ 2024-09-16 6:57 UTC (permalink / raw)
To: Rob Herring (Arm), Arturs Artamonovs
Cc: Olof Johansson, devicetree, Jiri Slaby, Catalin Marinas,
Michael Turquette, Thomas Gleixner, Greg Kroah-Hartman, soc,
linux-clk, linux-serial, Andi Shyti, linux-arm-kernel, linux-i2c,
Greg Malysa, Will Deacon, Philipp Zabel, Nathan Barrett-Morrison,
Linus Walleij, Arnd Bergmann, Utsav Agarwal, Bartosz Golaszewski,
linux-kernel, Krzysztof Kozlowski, adsp-linux, Conor Dooley,
linux-gpio, Stephen Boyd
On 12/09/2024 23:04, Rob Herring (Arm) wrote:
>
> On Thu, 12 Sep 2024 19:24:45 +0100, Arturs Artamonovs wrote:
>> This set of patches based on ADI fork of Linux Kerenl that support family of ADSP-SC5xx
>> SoC's and used by customers for some time . Patch series contains minimal set
>> of changes to add ADSP-SC598 support to upstream kernel. This series include
>> UART,I2C,IRQCHIP,RCU drivers and device-tree to be able boot on EV-SC598-SOM
>> board into serial shell and able to reset the board. Current SOM board
>> requires I2C expander to enable UART output.
>>
>> UART,I2C and PINCTRL drivers are based on old Blackfin drivers with
>> ADSP-SC5xx related bug fixes and improvments.
>>
>> Signed-off-by: Arturs Artamonovs <arturs.artamonovs@analog.com>
>> ---
>> Arturs Artamonovs (21):
>> arm64: Add ADI ADSP-SC598 SoC
>> reset: Add driver for ADI ADSP-SC5xx reset controller
>> dt-bindigs: arm64: adi,sc598 bindings
>> dt-bindings: arm64: adi,sc598: Add ADSP-SC598 SoC bindings
>> clock:Add driver for ADI ADSP-SC5xx PLL
>> include: dt-binding: clock: add adi clock header file
>> clock: Add driver for ADI ADSP-SC5xx clock
>> dt-bindings: clock: adi,sc5xx-clocks: add bindings
>> gpio: add driver for ADI ADSP-SC5xx platform
>> dt-bindings: gpio: adi,adsp-port-gpio: add bindings
>> irqchip: Add irqchip for ADI ADSP-SC5xx platform
>> dt-bindings: irqchip: adi,adsp-pint: add binding
>> pinctrl: Add drivers for ADI ADSP-SC5xx platform
>> dt-bindings: pinctrl: adi,adsp-pinctrl: add bindings
>> i2c: Add driver for ADI ADSP-SC5xx platforms
>> dt-bindings: i2c: add i2c/twi driver documentation
>> serial: adi,uart: Add driver for ADI ADSP-SC5xx
>> dt-bindings: serial: adi,uart4: add adi,uart4 driver documentation
>> arm64: dts: adi: sc598: add device tree
>> arm64: defconfig: sc598 add minimal changes
>> MAINTAINERS: add adi sc5xx maintainers
>>
>> .../devicetree/bindings/arm/analog/adi,sc5xx.yaml | 24 +
>> .../bindings/clock/adi,sc5xx-clocks.yaml | 65 ++
>> .../bindings/gpio/adi,adsp-port-gpio.yaml | 69 ++
>> Documentation/devicetree/bindings/i2c/adi,twi.yaml | 71 ++
>> .../interrupt-controller/adi,adsp-pint.yaml | 51 +
>> .../bindings/pinctrl/adi,adsp-pinctrl.yaml | 83 ++
>> .../devicetree/bindings/serial/adi,uart.yaml | 85 ++
>> .../bindings/soc/adi/adi,reset-controller.yaml | 38 +
>> MAINTAINERS | 22 +
>> arch/arm64/Kconfig.platforms | 13 +
>> arch/arm64/boot/dts/Makefile | 1 +
>> arch/arm64/boot/dts/adi/Makefile | 2 +
>> arch/arm64/boot/dts/adi/sc598-som-ezkit.dts | 14 +
>> arch/arm64/boot/dts/adi/sc598-som.dtsi | 58 ++
>> arch/arm64/boot/dts/adi/sc59x-64.dtsi | 367 +++++++
>> arch/arm64/configs/defconfig | 6 +
>> drivers/clk/Kconfig | 9 +
>> drivers/clk/Makefile | 1 +
>> drivers/clk/adi/Makefile | 4 +
>> drivers/clk/adi/clk-adi-pll.c | 151 +++
>> drivers/clk/adi/clk-adi-sc598.c | 329 ++++++
>> drivers/clk/adi/clk.h | 99 ++
>> drivers/gpio/Kconfig | 8 +
>> drivers/gpio/Makefile | 1 +
>> drivers/gpio/gpio-adi-adsp-port.c | 145 +++
>> drivers/i2c/busses/Kconfig | 17 +
>> drivers/i2c/busses/Makefile | 1 +
>> drivers/i2c/busses/i2c-adi-twi.c | 940 ++++++++++++++++++
>> drivers/irqchip/Kconfig | 9 +
>> drivers/irqchip/Makefile | 2 +
>> drivers/irqchip/irq-adi-adsp.c | 310 ++++++
>> drivers/pinctrl/Kconfig | 12 +
>> drivers/pinctrl/Makefile | 1 +
>> drivers/pinctrl/pinctrl-adsp.c | 919 +++++++++++++++++
>> drivers/reset/Makefile | 1 +
>> drivers/soc/Makefile | 1 +
>> drivers/soc/adi/Makefile | 5 +
>> drivers/soc/adi/system.c | 257 +++++
>> drivers/tty/serial/Kconfig | 19 +-
>> drivers/tty/serial/Makefile | 1 +
>> drivers/tty/serial/adi_uart.c | 1045 ++++++++++++++++++++
>> include/dt-bindings/clock/adi-sc5xx-clock.h | 93 ++
>> include/dt-bindings/pinctrl/adi-adsp.h | 19 +
>> 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 ++
>> include/uapi/linux/serial_core.h | 3 +
>> 49 files changed, 5829 insertions(+), 1 deletion(-)
>> ---
>> base-commit: da3ea35007d0af457a0afc87e84fddaebc4e0b63
>> change-id: 20240909-test-8ec5f76fe6d2
>>
>> Best regards,
>> --
>> Arturs Artamonovs <arturs.artamonovs@analog.com>
>>
>>
>>
>
>
> My bot found new DTB warnings on the .dts files added or changed in this
> series.
>
> Some warnings may be from an existing SoC .dtsi. Or perhaps the warnings
> are fixed by another series. Ultimately, it is up to the platform
> maintainer whether these warnings are acceptable or not. No need to reply
> unless the platform maintainer has comments.
>
> If you already ran DT checks and didn't see these error(s), then
> make sure dt-schema is up to date:
>
> pip3 install dtschema --upgrade
>
>
> New warnings running 'make CHECK_DTBS=y adi/sc598-som-ezkit.dtb' for 20240912-test-v1-0-458fa57c8ccf@analog.com:
>
> arch/arm64/boot/dts/adi/sc598-som-ezkit.dtb: /scb-bus/sec@31089000: failed to match any schema with compatible: ['adi,system-event-controller']
This must be addressed and fixed.
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 65+ messages in thread
* Re: [PATCH 00/21] Adding support of ADI ARMv8 ADSP-SC598 SoC.
2024-09-12 18:24 [PATCH 00/21] Adding support of ADI ARMv8 ADSP-SC598 SoC Arturs Artamonovs via B4 Relay
` (21 preceding siblings ...)
2024-09-12 21:04 ` [PATCH 00/21] Adding support of ADI ARMv8 ADSP-SC598 SoC Rob Herring (Arm)
@ 2024-09-13 8:20 ` Arnd Bergmann
2024-09-16 9:05 ` Krzysztof Kozlowski
23 siblings, 0 replies; 65+ messages in thread
From: Arnd Bergmann @ 2024-09-13 8:20 UTC (permalink / raw)
To: arturs.artamonovs, Catalin Marinas, Will Deacon, Greg Malysa,
Philipp Zabel, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Utsav Agarwal, Michael Turquette, Stephen Boyd, Linus Walleij,
Bartosz Golaszewski, Thomas Gleixner, Andi Shyti,
Greg Kroah-Hartman, Jiri Slaby, Olof Johansson, soc
Cc: linux-arm-kernel, linux-kernel, devicetree, linux-clk,
open list:GPIO SUBSYSTEM, linux-i2c, linux-serial, adsp-linux,
Nathan Barrett-Morrison
On Thu, Sep 12, 2024, at 18:24, Arturs Artamonovs via B4 Relay wrote:
> This set of patches based on ADI fork of Linux Kerenl that support
> family of ADSP-SC5xx
> SoC's and used by customers for some time . Patch series contains
> minimal set
> of changes to add ADSP-SC598 support to upstream kernel. This series
> include
> UART,I2C,IRQCHIP,RCU drivers and device-tree to be able boot on
> EV-SC598-SOM
> board into serial shell and able to reset the board. Current SOM board
> requires I2C expander to enable UART output.
>
> UART,I2C and PINCTRL drivers are based on old Blackfin drivers with
> ADSP-SC5xx related bug fixes and improvments.
>
> Signed-off-by: Arturs Artamonovs <arturs.artamonovs@analog.com>
Hi Arturs,
Thanks for your submission. I've done a first pass of a review
now, but the drivers will all need a more detailed review from
the subsystem maintainers as well.
For the drivers/soc and include/linux/soc portions, I need
to do second review round when you have added a description
about what these are used for, ideally I would hope that most
of those can disappear from the final series when the required
bits are moved into other drivers.
I commented on one of the bindings about the compatible
string, but later saw that the same issue is present in all
of the bindings, which each need a more specific identifier
for a particular piece of hardware they are compatible with.
Arnd
^ permalink raw reply [flat|nested] 65+ messages in thread
* Re: [PATCH 00/21] Adding support of ADI ARMv8 ADSP-SC598 SoC.
2024-09-12 18:24 [PATCH 00/21] Adding support of ADI ARMv8 ADSP-SC598 SoC Arturs Artamonovs via B4 Relay
` (22 preceding siblings ...)
2024-09-13 8:20 ` Arnd Bergmann
@ 2024-09-16 9:05 ` Krzysztof Kozlowski
23 siblings, 0 replies; 65+ messages in thread
From: Krzysztof Kozlowski @ 2024-09-16 9:05 UTC (permalink / raw)
To: arturs.artamonovs, Catalin Marinas, Will Deacon, Greg Malysa,
Philipp Zabel, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Utsav Agarwal, Michael Turquette, Stephen Boyd, Linus Walleij,
Bartosz Golaszewski, Thomas Gleixner, Andi Shyti,
Greg Kroah-Hartman, Jiri Slaby, Arnd Bergmann, Olof Johansson,
soc
Cc: linux-arm-kernel, linux-kernel, devicetree, linux-clk, linux-gpio,
linux-i2c, linux-serial, adsp-linux, Nathan Barrett-Morrison
On 12/09/2024 20:24, Arturs Artamonovs via B4 Relay wrote:
> This set of patches based on ADI fork of Linux Kerenl that support family of ADSP-SC5xx
> SoC's and used by customers for some time . Patch series contains minimal set
> of changes to add ADSP-SC598 support to upstream kernel. This series include
> UART,I2C,IRQCHIP,RCU drivers and device-tree to be able boot on EV-SC598-SOM
> board into serial shell and able to reset the board. Current SOM board
> requires I2C expander to enable UART output.
>
> UART,I2C and PINCTRL drivers are based on old Blackfin drivers with
> ADSP-SC5xx related bug fixes and improvments.
>
> Signed-off-by: Arturs Artamonovs <arturs.artamonovs@analog.com>
> ---
For new platform, be sure you have 0 warnings:
1. Please run standard kernel tools for static analysis, like
coccinelle, smatch and sparse, and fix reported warnings.
2. Also check for warnings when building with W=1. Most of these
commands (checks or W=1 build) can build specific targets, like some
directory, to narrow the scope to only your code. The code here looks
like it needs a fix. Feel free to get in touch if the warning is not clear.
3. Fix all compile test warning reported by LKP and check for common
configs, regardless of reports.
4. Please run `make dtbs_check W=1` (see
Documentation/devicetree/bindings/writing-schema.rst or
https://www.linaro.org/blog/tips-and-tricks-for-validating-devicetree-sources-with-the-devicetree-schema/
for instructions).
5. Please run scripts/checkpatch.pl and fix reported warnings. Then
please run `scripts/checkpatch.pl --strict` and (probably) fix more
warnings. Some warnings can be ignored, especially from --strict run.
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 65+ messages in thread