* [PATCH 0/8] Add Tenstorrent Atlantis Clock/Reset Controller
@ 2026-01-15 23:41 Anirudh Srinivasan
2026-01-15 23:42 ` [PATCH 1/8] dt-bindings: soc: tenstorrent: Add tenstorrent,atlantis-syscon Anirudh Srinivasan
` (7 more replies)
0 siblings, 8 replies; 29+ messages in thread
From: Anirudh Srinivasan @ 2026-01-15 23:41 UTC (permalink / raw)
To: Drew Fustini, Joel Stanley, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Michael Turquette, Stephen Boyd, Anirudh Srinivasan,
Philipp Zabel
Cc: linux-riscv, devicetree, linux-kernel, linux-clk, joel, fustini,
mpe, mpe, npiggin, agross, agross
This series adds support for a Syscon block in the upcoming Tenstorrent
Atlantis SoC that covers clocks and resets. This block is instantiated
multiple times in the SoC. The current series covers the "RCPU" syscon
block that controls clocks and resets for most low speed IO interfaces
found in the chip.
Signed-off-by: Anirudh Srinivasan <asrinivasan@oss.tenstorrent.com>
---
Anirudh Srinivasan (8):
dt-bindings: soc: tenstorrent: Add tenstorrent,atlantis-syscon
soc: tenstorrent: Add header with Atlantis syscon register offsets
clk: tenstorrent: Add Atlantis clock controller driver
dt-bindings: soc: tenstorrent: Add atlantis resets
soc: tenstorrent: Add rcpu syscon reset register definitions
soc: tenstorrent: Add auxiliary device definitions for Atlantis
reset: tenstorrent: Add reset controller for Atlantis
clk: tenstorrent: Add reset controller to Atlantis clock controller probe
.../tenstorrent/tenstorrent,atlantis-syscon.yaml | 63 ++
MAINTAINERS | 5 +
drivers/clk/Kconfig | 1 +
drivers/clk/Makefile | 1 +
drivers/clk/tenstorrent/Kconfig | 14 +
drivers/clk/tenstorrent/Makefile | 3 +
drivers/clk/tenstorrent/atlantis-ccu.c | 991 +++++++++++++++++++++
drivers/reset/Kconfig | 11 +
drivers/reset/Makefile | 1 +
drivers/reset/reset-tenstorrent-atlantis.c | 164 ++++
.../clock/tenstorrent,atlantis-syscon.h | 101 +++
include/soc/tenstorrent/atlantis-syscon.h | 53 ++
12 files changed, 1408 insertions(+)
---
base-commit: 9448598b22c50c8a5bb77a9103e2d49f134c9578
change-id: 20260112-atlantis-clocks-f090c190b86d
Best regards,
--
Anirudh Srinivasan <asrinivasan@oss.tenstorrent.com>
^ permalink raw reply [flat|nested] 29+ messages in thread
* [PATCH 1/8] dt-bindings: soc: tenstorrent: Add tenstorrent,atlantis-syscon
2026-01-15 23:41 [PATCH 0/8] Add Tenstorrent Atlantis Clock/Reset Controller Anirudh Srinivasan
@ 2026-01-15 23:42 ` Anirudh Srinivasan
2026-01-16 3:18 ` Rob Herring (Arm)
` (2 more replies)
2026-01-15 23:42 ` [PATCH 2/8] soc: tenstorrent: Add header with Atlantis syscon register offsets Anirudh Srinivasan
` (6 subsequent siblings)
7 siblings, 3 replies; 29+ messages in thread
From: Anirudh Srinivasan @ 2026-01-15 23:42 UTC (permalink / raw)
To: Drew Fustini, Joel Stanley, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Michael Turquette, Stephen Boyd, Anirudh Srinivasan,
Philipp Zabel
Cc: linux-riscv, devicetree, linux-kernel, linux-clk, joel, fustini,
mpe, mpe, npiggin, agross, agross
Document bindings for Tenstorrent Atlantis syscon that manages clocks
and resets. This syscon block is instantiated 4 times in the SoC.
This commit documents the clocks from the RCPU syscon block.
Signed-off-by: Anirudh Srinivasan <asrinivasan@oss.tenstorrent.com>
---
.../tenstorrent/tenstorrent,atlantis-syscon.yaml | 58 +++++++++++++++++++
MAINTAINERS | 2 +
.../clock/tenstorrent,atlantis-syscon.h | 67 ++++++++++++++++++++++
3 files changed, 127 insertions(+)
diff --git a/Documentation/devicetree/bindings/soc/tenstorrent/tenstorrent,atlantis-syscon.yaml b/Documentation/devicetree/bindings/soc/tenstorrent/tenstorrent,atlantis-syscon.yaml
new file mode 100644
index 000000000000..3915d78dfeda
--- /dev/null
+++ b/Documentation/devicetree/bindings/soc/tenstorrent/tenstorrent,atlantis-syscon.yaml
@@ -0,0 +1,58 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/soc/tenstorrent/tenstorrent,atlantis-syscon.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Tenstorrent Atlantis SoC System Controller
+
+maintainers:
+ - Anirudh Srinivasan <asrinivasan@oss.tenstorrent.com>
+
+description:
+ System controller found in Tenstorrent Atlantis SoC, which is capable of
+ clock and reset functions.
+
+ RCPU syscon controls clocks and resets for low speed IO interfaces on chip
+
+properties:
+ compatible:
+ enum:
+ - tenstorrent,atlantis-syscon-rcpu
+
+ reg:
+ maxItems: 1
+
+ clocks:
+ maxItems: 1
+
+ "#clock-cells":
+ const: 1
+ description:
+ See <dt-bindings/clock/tenstorrent,atlantis-syscon.h> for valid indices.
+
+required:
+ - compatible
+ - reg
+ - clocks
+ - "#clock-cells"
+
+additionalProperties: false
+
+examples:
+ - |
+ clocks {
+ osc_24m: clock-24m {
+ compatible = "fixed-clock";
+ clock-frequency = <24000000>;
+ clock-output-names = "osc_24m";
+ #clock-cells = <0>;
+ };
+ };
+
+ syscon_rcpu: system-controller@a8000000 {
+ compatible = "tenstorrent,atlantis-sycon-rcpu";
+ reg = <0x0 0xa8000000 0x0 0x10000>;
+ clocks = <&osc_24m>;
+ #clock-cells = <1>;
+ };
diff --git a/MAINTAINERS b/MAINTAINERS
index dc731d37c8fe..19a98b1fa456 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -22535,7 +22535,9 @@ L: linux-riscv@lists.infradead.org
S: Maintained
T: git https://github.com/tenstorrent/linux.git
F: Documentation/devicetree/bindings/riscv/tenstorrent.yaml
+F: Documentation/devicetree/bindings/soc/tenstorrent/tenstorrent,atlantis-syscon.yaml
F: arch/riscv/boot/dts/tenstorrent/
+F: include/dt-bindings/clock/tenstorrent,atlantis-syscon.h
RISC-V THEAD SoC SUPPORT
M: Drew Fustini <fustini@kernel.org>
diff --git a/include/dt-bindings/clock/tenstorrent,atlantis-syscon.h b/include/dt-bindings/clock/tenstorrent,atlantis-syscon.h
new file mode 100644
index 000000000000..a8518319642a
--- /dev/null
+++ b/include/dt-bindings/clock/tenstorrent,atlantis-syscon.h
@@ -0,0 +1,67 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+/*
+ * Copyright (c) 2026 Tenstorrent
+ */
+
+#ifndef _DT_BINDINGS_ATLANTIS_SYSCON_H
+#define _DT_BINDINGS_ATLANTIS_SYSCON_H
+
+/*
+ * RCPU Domain Clock IDs
+ */
+#define CLK_RCPU_PLL 0
+#define CLK_RCPU_ROOT 1
+#define CLK_RCPU_DIV2 2
+#define CLK_RCPU_DIV4 3
+#define CLK_RCPU_RTC 4
+#define CLK_SMNDMA0_ACLK 5
+#define CLK_SMNDMA1_ACLK 6
+#define CLK_WDT0_PCLK 7
+#define CLK_WDT1_PCLK 8
+#define CLK_TIMER_PCLK 9
+#define CLK_PVTC_PCLK 10
+#define CLK_PMU_PCLK 11
+#define CLK_MAILBOX_HCLK 12
+#define CLK_SEC_SPACC_HCLK 13
+#define CLK_SEC_OTP_HCLK 14
+#define CLK_TRNG_PCLK 15
+#define CLK_SEC_CRC_HCLK 16
+#define CLK_SMN_HCLK 17
+#define CLK_AHB0_HCLK 18
+#define CLK_SMN_PCLK 19
+#define CLK_SMN_CLK 20
+#define CLK_SCRATCHPAD_CLK 21
+#define CLK_RCPU_CORE_CLK 22
+#define CLK_RCPU_ROM_CLK 23
+#define CLK_OTP_LOAD_CLK 24
+#define CLK_NOC_PLL 25
+#define CLK_NOCC_CLK 26
+#define CLK_NOCC_DIV2 27
+#define CLK_NOCC_DIV4 28
+#define CLK_NOCC_RTC 29
+#define CLK_NOCC_CAN 30
+#define CLK_QSPI_SCLK 31
+#define CLK_QSPI_HCLK 32
+#define CLK_I2C0_PCLK 33
+#define CLK_I2C1_PCLK 34
+#define CLK_I2C2_PCLK 35
+#define CLK_I2C3_PCLK 36
+#define CLK_I2C4_PCLK 37
+#define CLK_UART0_PCLK 38
+#define CLK_UART1_PCLK 39
+#define CLK_UART2_PCLK 40
+#define CLK_UART3_PCLK 41
+#define CLK_UART4_PCLK 42
+#define CLK_SPI0_PCLK 43
+#define CLK_SPI1_PCLK 44
+#define CLK_SPI2_PCLK 45
+#define CLK_SPI3_PCLK 46
+#define CLK_GPIO_PCLK 47
+#define CLK_CAN0_HCLK 48
+#define CLK_CAN0_CLK 49
+#define CLK_CAN1_HCLK 50
+#define CLK_CAN1_CLK 51
+#define CLK_CAN0_TIMER_CLK 52
+#define CLK_CAN1_TIMER_CLK 53
+
+#endif /* _DT_BINDINGS_ATLANTIS_SYSCON_H */
--
2.43.0
^ permalink raw reply related [flat|nested] 29+ messages in thread
* [PATCH 2/8] soc: tenstorrent: Add header with Atlantis syscon register offsets
2026-01-15 23:41 [PATCH 0/8] Add Tenstorrent Atlantis Clock/Reset Controller Anirudh Srinivasan
2026-01-15 23:42 ` [PATCH 1/8] dt-bindings: soc: tenstorrent: Add tenstorrent,atlantis-syscon Anirudh Srinivasan
@ 2026-01-15 23:42 ` Anirudh Srinivasan
2026-01-16 9:06 ` Krzysztof Kozlowski
2026-01-15 23:42 ` [PATCH 3/8] clk: tenstorrent: Add Atlantis clock controller driver Anirudh Srinivasan
` (5 subsequent siblings)
7 siblings, 1 reply; 29+ messages in thread
From: Anirudh Srinivasan @ 2026-01-15 23:42 UTC (permalink / raw)
To: Drew Fustini, Joel Stanley, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Michael Turquette, Stephen Boyd, Anirudh Srinivasan,
Philipp Zabel
Cc: linux-riscv, devicetree, linux-kernel, linux-clk, joel, fustini,
mpe, mpe, npiggin, agross, agross
Document register offsets used for controlling clocks in Atlantis
Signed-off-by: Anirudh Srinivasan <asrinivasan@oss.tenstorrent.com>
---
MAINTAINERS | 1 +
include/soc/tenstorrent/atlantis-syscon.h | 38 +++++++++++++++++++++++++++++++
2 files changed, 39 insertions(+)
diff --git a/MAINTAINERS b/MAINTAINERS
index 19a98b1fa456..4a2017d647b0 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -22538,6 +22538,7 @@ F: Documentation/devicetree/bindings/riscv/tenstorrent.yaml
F: Documentation/devicetree/bindings/soc/tenstorrent/tenstorrent,atlantis-syscon.yaml
F: arch/riscv/boot/dts/tenstorrent/
F: include/dt-bindings/clock/tenstorrent,atlantis-syscon.h
+F: include/soc/tenstorrent/
RISC-V THEAD SoC SUPPORT
M: Drew Fustini <fustini@kernel.org>
diff --git a/include/soc/tenstorrent/atlantis-syscon.h b/include/soc/tenstorrent/atlantis-syscon.h
new file mode 100644
index 000000000000..b15dabfb42b5
--- /dev/null
+++ b/include/soc/tenstorrent/atlantis-syscon.h
@@ -0,0 +1,38 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2026 Tenstorrent
+ */
+#ifndef __SOC_ATLANTIS_SYSCON_H__
+#define __SOC_ATLANTIS_SYSCON_H__
+
+#include <linux/bits.h>
+#include <linux/types.h>
+
+/* RCPU Clock Register Offsets */
+#define RCPU_PLL_CFG_REG 0x0000
+#define RCPU_NOCC_PLL_CFG_REG 0x0004
+#define RCPU_NOCC_CLK_CFG_REG 0x0008
+#define RCPU_DIV_CFG_REG 0x000C
+#define RCPU_BLK_CG_REG 0x0014
+#define LSIO_BLK_CG_REG 0x0018
+#define PLL_RCPU_EN_REG 0x11c
+#define PLL_NOCC_EN_REG 0x120
+#define BUS_CG_REG 0x01FC
+
+/* PLL Bit Definitions */
+#define PLL_CFG_EN_BIT BIT(0)
+#define PLL_CFG_BYPASS_BIT BIT(1)
+#define PLL_CFG_REFDIV_MASK GENMASK(7, 2)
+#define PLL_CFG_REFDIV_SHIFT 2
+#define PLL_CFG_POSTDIV1_MASK GENMASK(10, 8)
+#define PLL_CFG_POSTDIV1_SHIFT 8
+#define PLL_CFG_POSTDIV2_MASK GENMASK(13, 11)
+#define PLL_CFG_POSTDIV2_SHIFT 11
+#define PLL_CFG_FBDIV_MASK GENMASK(25, 14)
+#define PLL_CFG_FBDIV_SHIFT 14
+#define PLL_CFG_LKDT_BIT BIT(30)
+#define PLL_CFG_LOCK_BIT BIT(31)
+#define PLL_LOCK_TIMEOUT_US 1000
+#define PLL_BYPASS_WAIT_US 500
+
+#endif
--
2.43.0
^ permalink raw reply related [flat|nested] 29+ messages in thread
* [PATCH 3/8] clk: tenstorrent: Add Atlantis clock controller driver
2026-01-15 23:41 [PATCH 0/8] Add Tenstorrent Atlantis Clock/Reset Controller Anirudh Srinivasan
2026-01-15 23:42 ` [PATCH 1/8] dt-bindings: soc: tenstorrent: Add tenstorrent,atlantis-syscon Anirudh Srinivasan
2026-01-15 23:42 ` [PATCH 2/8] soc: tenstorrent: Add header with Atlantis syscon register offsets Anirudh Srinivasan
@ 2026-01-15 23:42 ` Anirudh Srinivasan
2026-01-16 2:05 ` Brian Masney
2026-01-16 11:56 ` kernel test robot
2026-01-15 23:42 ` [PATCH 4/8] dt-bindings: soc: tenstorrent: Add atlantis resets Anirudh Srinivasan
` (4 subsequent siblings)
7 siblings, 2 replies; 29+ messages in thread
From: Anirudh Srinivasan @ 2026-01-15 23:42 UTC (permalink / raw)
To: Drew Fustini, Joel Stanley, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Michael Turquette, Stephen Boyd, Anirudh Srinivasan,
Philipp Zabel
Cc: linux-riscv, devicetree, linux-kernel, linux-clk, joel, fustini,
mpe, mpe, npiggin, agross, agross
Add driver for syscon block in Tenstorrent Atlantis SoC. This version of
the driver coves clocks from RCPU syscon.
5 types of clocks generated by this controller: PLLs (PLLs
with bypass functionality and an additional Gate clk at output), Shared
Gates (Multiple Gate clks that share an enable bit), standard Muxes,
Dividers and Gates. All clocks are derived from a 24 Mhz oscillator.
Signed-off-by: Anirudh Srinivasan <asrinivasan@oss.tenstorrent.com>
---
MAINTAINERS | 1 +
drivers/clk/Kconfig | 1 +
drivers/clk/Makefile | 1 +
drivers/clk/tenstorrent/Kconfig | 14 +
drivers/clk/tenstorrent/Makefile | 3 +
drivers/clk/tenstorrent/atlantis-ccu.c | 932 +++++++++++++++++++++++++++++++++
6 files changed, 952 insertions(+)
diff --git a/MAINTAINERS b/MAINTAINERS
index 4a2017d647b0..93d941d2886b 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -22537,6 +22537,7 @@ T: git https://github.com/tenstorrent/linux.git
F: Documentation/devicetree/bindings/riscv/tenstorrent.yaml
F: Documentation/devicetree/bindings/soc/tenstorrent/tenstorrent,atlantis-syscon.yaml
F: arch/riscv/boot/dts/tenstorrent/
+F: drivers/clk/tenstorrent/
F: include/dt-bindings/clock/tenstorrent,atlantis-syscon.h
F: include/soc/tenstorrent/
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index 3a1611008e48..643084887257 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -542,6 +542,7 @@ source "drivers/clk/starfive/Kconfig"
source "drivers/clk/sunxi/Kconfig"
source "drivers/clk/sunxi-ng/Kconfig"
source "drivers/clk/tegra/Kconfig"
+source "drivers/clk/tenstorrent/Kconfig"
source "drivers/clk/thead/Kconfig"
source "drivers/clk/stm32/Kconfig"
source "drivers/clk/ti/Kconfig"
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index 61ec08404442..f88c116d315f 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -156,6 +156,7 @@ obj-y += starfive/
obj-$(CONFIG_ARCH_SUNXI) += sunxi/
obj-y += sunxi-ng/
obj-$(CONFIG_ARCH_TEGRA) += tegra/
+obj-y += tenstorrent/
obj-$(CONFIG_ARCH_THEAD) += thead/
obj-y += ti/
obj-$(CONFIG_CLK_UNIPHIER) += uniphier/
diff --git a/drivers/clk/tenstorrent/Kconfig b/drivers/clk/tenstorrent/Kconfig
new file mode 100644
index 000000000000..6bcef9e4feb4
--- /dev/null
+++ b/drivers/clk/tenstorrent/Kconfig
@@ -0,0 +1,14 @@
+# SPDX-License-Identifier: GPL-2.0-only
+
+config TENSTORRENT_ATLANTIS_CCU
+ tristate "Support for Tenstorrent Atlantis Clock Controllers"
+ depends on ARCH_TENSTORRENT || COMPILE_TEST
+ default ARCH_TENSTORRENT
+ select REGMAP_MMIO
+ select AUXILIARY_BUS
+ select MFD_SYSCON
+ help
+ Say yes here to support the different clock
+ controllers found in the Tenstorrent Atlantis SoC.
+ This includes the clocks from the RCPU, HSIO, MMIO
+ and PCIE domain.
diff --git a/drivers/clk/tenstorrent/Makefile b/drivers/clk/tenstorrent/Makefile
new file mode 100644
index 000000000000..cc4fc01df75b
--- /dev/null
+++ b/drivers/clk/tenstorrent/Makefile
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0
+
+obj-$(CONFIG_TENSTORRENT_ATLANTIS_CCU) += atlantis-ccu.o
diff --git a/drivers/clk/tenstorrent/atlantis-ccu.c b/drivers/clk/tenstorrent/atlantis-ccu.c
new file mode 100644
index 000000000000..f3a2ea49a82e
--- /dev/null
+++ b/drivers/clk/tenstorrent/atlantis-ccu.c
@@ -0,0 +1,932 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2026 Tenstorrent
+ */
+
+#include <linux/array_size.h>
+#include <linux/auxiliary_bus.h>
+#include <linux/clk-provider.h>
+#include <linux/delay.h>
+#include <linux/idr.h>
+#include <linux/mfd/syscon.h>
+#include <linux/minmax.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+#include <soc/tenstorrent/atlantis-syscon.h>
+
+#include <dt-bindings/clock/tenstorrent,atlantis-syscon.h>
+#include <linux/regmap.h>
+#include <linux/clk-provider.h>
+#include <linux/math.h>
+#include <linux/bitfield.h>
+
+enum atlantis_clk_type {
+ ATLANTIS_CLK_PLL,
+ ATLANTIS_CLK_MUX,
+ ATLANTIS_CLK_DIVIDER,
+ ATLANTIS_CLK_GATE,
+ ATLANTIS_CLK_GATE_SHARED,
+ ATLANTIS_CLK_FIXED_FACTOR,
+};
+
+struct atlantis_clk_common {
+ int clkid;
+ enum atlantis_clk_type clk_type;
+ struct regmap *regmap;
+ struct clk_hw hw;
+};
+
+#define hw_to_atlantis_clk_common(_hw) \
+ container_of((_hw), struct atlantis_clk_common, hw)
+
+struct atlantis_clk_mux_config {
+ u8 shift;
+ u8 width;
+ u32 reg_offset;
+};
+
+struct atlantis_clk_mux {
+ struct atlantis_clk_common common;
+ struct atlantis_clk_mux_config config;
+};
+
+struct atlantis_clk_gate_config {
+ u32 reg_offset;
+ u32 enable;
+};
+
+struct atlantis_clk_gate {
+ struct atlantis_clk_common common;
+ struct atlantis_clk_gate_config config;
+};
+
+struct atlantis_clk_divider_config {
+ u8 shift;
+ u8 width;
+ u32 flags;
+ u32 reg_offset;
+};
+
+struct atlantis_clk_divider {
+ struct atlantis_clk_common common;
+ struct atlantis_clk_divider_config config;
+};
+
+struct atlantis_clk_pll_config {
+ u32 tbl_num;
+ u32 reg_offset;
+ u32 en_reg_offset;
+ u32 cg_reg_offset;
+ u32 cg_reg_enable;
+};
+
+/* Models a PLL with Bypass Functionality and Enable Bit + a Gate Clock at it's output */
+struct atlantis_clk_pll {
+ struct atlantis_clk_common common;
+ struct atlantis_clk_pll_config config;
+};
+
+struct atlantis_clk_gate_shared_config {
+ u32 reg_offset;
+ u32 enable;
+ unsigned int *share_count;
+ spinlock_t *refcount_lock;
+};
+
+struct atlantis_clk_gate_shared {
+ struct atlantis_clk_common common;
+ struct atlantis_clk_gate_shared_config config;
+};
+
+struct atlantis_clk_fixed_factor_config {
+ unsigned int mult;
+ unsigned int div;
+};
+
+struct atlantis_clk_fixed_factor {
+ struct atlantis_clk_fixed_factor_config config;
+ struct atlantis_clk_common common;
+};
+
+static inline struct atlantis_clk_mux *hw_to_atlantis_clk_mux(struct clk_hw *hw)
+{
+ struct atlantis_clk_common *common = hw_to_atlantis_clk_common(hw);
+
+ return container_of(common, struct atlantis_clk_mux, common);
+}
+
+static inline struct atlantis_clk_gate *
+hw_to_atlantis_clk_gate(struct clk_hw *hw)
+{
+ struct atlantis_clk_common *common = hw_to_atlantis_clk_common(hw);
+
+ return container_of(common, struct atlantis_clk_gate, common);
+}
+
+static inline struct atlantis_clk_divider *
+hw_to_atlantis_clk_divider(struct clk_hw *hw)
+{
+ struct atlantis_clk_common *common = hw_to_atlantis_clk_common(hw);
+
+ return container_of(common, struct atlantis_clk_divider, common);
+}
+
+static inline struct atlantis_clk_pll *hw_to_atlantis_pll(struct clk_hw *hw)
+{
+ struct atlantis_clk_common *common = hw_to_atlantis_clk_common(hw);
+
+ return container_of(common, struct atlantis_clk_pll, common);
+}
+
+static inline struct atlantis_clk_gate_shared *
+hw_to_atlantis_clk_gate_shared(struct clk_hw *hw)
+{
+ struct atlantis_clk_common *common = hw_to_atlantis_clk_common(hw);
+
+ return container_of(common, struct atlantis_clk_gate_shared, common);
+}
+
+static inline struct atlantis_clk_fixed_factor *
+hw_to_atlantis_clk_fixed_factor(struct clk_hw *hw)
+{
+ struct atlantis_clk_common *common = hw_to_atlantis_clk_common(hw);
+
+ return container_of(common, struct atlantis_clk_fixed_factor, common);
+}
+
+static int atlantis_clk_pll_is_enabled(struct clk_hw *hw)
+{
+ struct atlantis_clk_pll *pll = hw_to_atlantis_pll(hw);
+ u32 val, en_val, cg_val;
+
+ regmap_read(pll->common.regmap, pll->config.reg_offset, &val);
+ regmap_read(pll->common.regmap, pll->config.en_reg_offset, &en_val);
+ regmap_read(pll->common.regmap, pll->config.cg_reg_offset, &cg_val);
+
+ /* Check if PLL is powered on, locked and Gate clk is enabled */
+ return !!(en_val & PLL_CFG_EN_BIT) && !!(val & PLL_CFG_LOCK_BIT) &&
+ !!(cg_val && pll->config.cg_reg_enable);
+}
+
+static int atlantis_clk_pll_enable(struct clk_hw *hw)
+{
+ struct atlantis_clk_pll *pll = hw_to_atlantis_pll(hw);
+ u32 val, en_val, cg_val;
+ int ret;
+
+ regmap_read(pll->common.regmap, pll->config.reg_offset, &val);
+ regmap_read(pll->common.regmap, pll->config.en_reg_offset, &en_val);
+ regmap_read(pll->common.regmap, pll->config.cg_reg_offset, &cg_val);
+
+ /* Check if PLL is already enabled, locked and Gate clk is enabled */
+ if ((en_val & PLL_CFG_EN_BIT) && (val & PLL_CFG_LOCK_BIT) &&
+ (cg_val && pll->config.cg_reg_enable) &&
+ !(val & PLL_CFG_BYPASS_BIT)) {
+ return 0;
+ }
+
+ /* Step 1: Set bypass mode first */
+ regmap_update_bits(pll->common.regmap, pll->config.reg_offset,
+ PLL_CFG_BYPASS_BIT, PLL_CFG_BYPASS_BIT);
+
+ /* Step 2: Enable PLL (clear then set power bit) */
+ regmap_update_bits(pll->common.regmap, pll->config.en_reg_offset,
+ PLL_CFG_EN_BIT, 0);
+
+ regmap_update_bits(pll->common.regmap, pll->config.en_reg_offset,
+ PLL_CFG_EN_BIT, PLL_CFG_EN_BIT);
+
+ /* Step 3: Wait for PLL lock */
+ ret = regmap_read_poll_timeout(pll->common.regmap,
+ pll->config.reg_offset, val,
+ val & PLL_CFG_LOCK_BIT, 10,
+ PLL_BYPASS_WAIT_US);
+ if (ret) {
+ pr_err("PLL failed to lock within timeout\n");
+ return ret;
+ }
+
+ /* Step 4: Switch from bypass to PLL output */
+ regmap_update_bits(pll->common.regmap, pll->config.reg_offset,
+ PLL_CFG_BYPASS_BIT, 0);
+
+ /* Enable Gate clk at PLL Output */
+ return regmap_update_bits(pll->common.regmap, pll->config.cg_reg_offset,
+ pll->config.cg_reg_enable,
+ pll->config.cg_reg_enable);
+}
+
+static void atlantis_clk_pll_disable(struct clk_hw *hw)
+{
+ struct atlantis_clk_pll *pll = hw_to_atlantis_pll(hw);
+
+ /* Step 1: Switch to bypass mode before disabling */
+ regmap_update_bits(pll->common.regmap, pll->config.reg_offset,
+ PLL_CFG_BYPASS_BIT, PLL_CFG_BYPASS_BIT);
+ /* Step 2: Power down PLL */
+ regmap_update_bits(pll->common.regmap, pll->config.en_reg_offset,
+ PLL_CFG_EN_BIT, 0);
+}
+
+static unsigned long atlantis_clk_pll_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ struct atlantis_clk_pll *pll = hw_to_atlantis_pll(hw);
+
+ u32 val, refdiv, fbdiv, postdiv1, postdiv2;
+ u64 fout;
+
+ regmap_read(pll->common.regmap, pll->config.reg_offset, &val);
+
+ if (val & PLL_CFG_BYPASS_BIT)
+ return parent_rate;
+
+ refdiv = FIELD_GET(PLL_CFG_REFDIV_MASK, val);
+ fbdiv = FIELD_GET(PLL_CFG_FBDIV_MASK, val);
+ postdiv1 = FIELD_GET(PLL_CFG_POSTDIV1_MASK, val);
+ postdiv2 = FIELD_GET(PLL_CFG_POSTDIV2_MASK, val);
+
+ if (!refdiv)
+ refdiv = 1;
+ if (!postdiv1)
+ postdiv1 = 1;
+ if (!postdiv2)
+ postdiv2 = 1;
+ if (!fbdiv)
+ return 0;
+
+ fout = div64_u64((u64)parent_rate * fbdiv,
+ refdiv * postdiv1 * postdiv2);
+
+ return fout;
+}
+
+const struct clk_ops atlantis_clk_pll_ops = {
+ .enable = atlantis_clk_pll_enable,
+ .disable = atlantis_clk_pll_disable,
+ .recalc_rate = atlantis_clk_pll_recalc_rate,
+ .is_enabled = atlantis_clk_pll_is_enabled,
+};
+
+static int atlantis_clk_gate_shared_enable(struct clk_hw *hw)
+{
+ struct atlantis_clk_gate_shared *gate =
+ hw_to_atlantis_clk_gate_shared(hw);
+ bool need_enable;
+ u32 reg;
+
+ scoped_guard(spinlock_irqsave, gate->config.refcount_lock)
+ {
+ need_enable = (*gate->config.share_count)++ == 0;
+ if (need_enable) {
+ regmap_read(gate->common.regmap,
+ gate->config.reg_offset, ®);
+ reg |= gate->config.enable;
+ regmap_write(gate->common.regmap,
+ gate->config.reg_offset, reg);
+ }
+ }
+
+ if (need_enable) {
+ regmap_read(gate->common.regmap, gate->config.reg_offset, ®);
+
+ if (!(reg & gate->config.enable)) {
+ pr_warn("%s: gate enable %d failed to enable\n",
+ clk_hw_get_name(hw), gate->config.enable);
+ return -EIO;
+ }
+ }
+
+ return 0;
+}
+
+static void atlantis_clk_gate_shared_disable(struct clk_hw *hw)
+{
+ struct atlantis_clk_gate_shared *gate =
+ hw_to_atlantis_clk_gate_shared(hw);
+ u32 reg;
+
+ scoped_guard(spinlock_irqsave, gate->config.refcount_lock)
+ {
+ if (WARN_ON(*gate->config.share_count == 0))
+ return;
+ if (--(*gate->config.share_count) > 0)
+ return;
+
+ regmap_read(gate->common.regmap, gate->config.reg_offset, ®);
+ reg &= ~gate->config.enable;
+ regmap_write(gate->common.regmap, gate->config.reg_offset, reg);
+ }
+}
+
+static int atlantis_clk_gate_shared_is_enabled(struct clk_hw *hw)
+{
+ struct atlantis_clk_gate_shared *gate =
+ hw_to_atlantis_clk_gate_shared(hw);
+ u32 reg;
+
+ regmap_read(gate->common.regmap, gate->config.reg_offset, ®);
+
+ return !!(reg & gate->config.enable);
+}
+
+static void atlantis_clk_gate_shared_disable_unused(struct clk_hw *hw)
+{
+ struct atlantis_clk_gate_shared *gate =
+ hw_to_atlantis_clk_gate_shared(hw);
+
+ u32 reg;
+
+ scoped_guard(spinlock_irqsave, gate->config.refcount_lock)
+ {
+ if (*gate->config.share_count == 0) {
+ regmap_read(gate->common.regmap,
+ gate->config.reg_offset, ®);
+ reg &= ~gate->config.enable;
+ regmap_write(gate->common.regmap,
+ gate->config.reg_offset, reg);
+ }
+ }
+}
+
+const struct clk_ops atlantis_clk_gate_shared_ops = {
+ .enable = atlantis_clk_gate_shared_enable,
+ .disable = atlantis_clk_gate_shared_disable,
+ .disable_unused = atlantis_clk_gate_shared_disable_unused,
+ .is_enabled = atlantis_clk_gate_shared_is_enabled,
+};
+
+#define ATLANTIS_PLL_CONFIG(_reg_offset, _en_reg_offset, _cg_reg_offset, \
+ _cg_reg_enable) \
+ { \
+ .reg_offset = (_reg_offset), \
+ .en_reg_offset = (_en_reg_offset), \
+ .cg_reg_offset = (_cg_reg_offset), \
+ .cg_reg_enable = (_cg_reg_enable), \
+ }
+
+#define ATLANTIS_PLL_DEFINE(_clkid, _name, _parent, _reg_offset, \
+ _en_reg_offset, _cg_reg_offset, _cg_reg_enable, \
+ _flags) \
+ static struct atlantis_clk_pll _name = { \
+ .config = ATLANTIS_PLL_CONFIG(_reg_offset, _en_reg_offset, \
+ _cg_reg_offset, _cg_reg_enable), \
+ .common = { .clkid = _clkid, \
+ .clk_type = ATLANTIS_CLK_PLL, \
+ .hw.init = CLK_HW_INIT_PARENTS_DATA( \
+ #_name, _parent, &atlantis_clk_pll_ops, \
+ _flags) }, \
+ }
+#define ATLANTIS_MUX_CONFIG(_shift, _width, _reg_offset) \
+ { \
+ .shift = _shift, .width = _width, .reg_offset = _reg_offset \
+ }
+
+#define ATLANTIS_MUX_DEFINE(_clkid, _name, _parents, _reg_offset, _shift, \
+ _width, _flags) \
+ static struct atlantis_clk_mux _name = { \
+ .config = ATLANTIS_MUX_CONFIG(_shift, _width, _reg_offset), \
+ .common = { .clkid = _clkid, \
+ .clk_type = ATLANTIS_CLK_MUX, \
+ .hw.init = CLK_HW_INIT_PARENTS_DATA( \
+ #_name, _parents, &clk_mux_ops, _flags) } \
+ }
+
+#define ATLANTIS_DIVIDER_CONFIG(_shift, _width, _flags, _reg_offset) \
+ { \
+ .shift = _shift, .width = _width, .flags = _flags, \
+ .reg_offset = _reg_offset \
+ }
+
+#define ATLANTIS_DIVIDER_DEFINE(_clkid, _name, _parent, _reg_offset, _shift, \
+ _width, _divflags, _flags) \
+ static struct atlantis_clk_divider _name = { \
+ .config = ATLANTIS_DIVIDER_CONFIG(_shift, _width, _divflags, \
+ _reg_offset), \
+ .common = { .clkid = _clkid, \
+ .clk_type = ATLANTIS_CLK_DIVIDER, \
+ .hw.init = \
+ CLK_HW_INIT_HW(#_name, &_parent.common.hw, \
+ &clk_divider_ops, _flags) } \
+ }
+#define ATLANTIS_GATE_CONFIG(_enable, _reg_offset) \
+ { \
+ .enable = _enable, .reg_offset = _reg_offset \
+ }
+
+#define ATLANTIS_GATE_DEFINE(_clkid, _name, _parent, _reg_offset, _enable, \
+ _flags) \
+ static struct atlantis_clk_gate _name = { \
+ .config = ATLANTIS_GATE_CONFIG(_enable, _reg_offset), \
+ .common = { .clkid = _clkid, \
+ .clk_type = ATLANTIS_CLK_GATE, \
+ .hw.init = CLK_HW_INIT_HW(#_name, \
+ &_parent.common.hw, \
+ &clk_gate_ops, _flags) } \
+ }
+#define ATLANTIS_GATE_SHARED_CONFIG(_reg_offset, _enable, _share_count) \
+ { \
+ .reg_offset = _reg_offset, .enable = _enable, \
+ .share_count = _share_count \
+ }
+#define ATLANTIS_GATE_SHARED_DEFINE(_clkid, _name, _parent, _reg_offset, \
+ _enable, _share_count, _flags) \
+ static struct atlantis_clk_gate_shared _name = { \
+ .config = ATLANTIS_GATE_SHARED_CONFIG(_reg_offset, _enable, \
+ _share_count), \
+ .common = { .clkid = _clkid, \
+ .clk_type = ATLANTIS_CLK_GATE_SHARED, \
+ .hw.init = CLK_HW_INIT_HW( \
+ #_name, &_parent.common.hw, \
+ &atlantis_clk_gate_shared_ops, _flags) } \
+ }
+#define ATLANTIS_CLK_FIXED_FACTOR_DEFINE(_clkid, _name, _parent, _mult, _div, \
+ _flags) \
+ static struct atlantis_clk_fixed_factor _name = { \
+ .config = { .mult = _mult, .div = _div }, \
+ .common = { .clkid = _clkid, \
+ .clk_type = ATLANTIS_CLK_FIXED_FACTOR, \
+ .hw.init = CLK_HW_INIT_HW( \
+ #_name, &_parent.common.hw, \
+ &clk_fixed_factor_ops, _flags) } \
+ }
+static void atlantis_ccu_lock(void *_lock)
+{
+ spinlock_t *lock = _lock;
+
+ spin_lock(lock);
+}
+
+static void atlantis_ccu_unlock(void *_lock)
+{
+ spinlock_t *lock = _lock;
+
+ spin_unlock(lock);
+}
+
+static DEFINE_SPINLOCK(lock); /* Lock for Regmap accesses */
+static DEFINE_SPINLOCK(refcount_lock); /* Lock for refcount value accesses */
+
+static const struct regmap_config atlantis_ccu_regmap_config = {
+ .reg_bits = 32,
+ .reg_stride = 4,
+ .val_bits = 32,
+ .max_register = 0xFFFC,
+ .cache_type = REGCACHE_NONE,
+ .lock = atlantis_ccu_lock,
+ .unlock = atlantis_ccu_unlock,
+ .lock_arg = &lock,
+};
+struct atlantis_ccu {
+ struct device *dev;
+
+ struct regmap *regmap;
+ void __iomem *base;
+
+ struct clk_hw_onecell_data *clk_data;
+};
+
+struct atlantis_ccu_data {
+ struct clk_hw **hws;
+ size_t num;
+};
+
+static const struct clk_parent_data osc_24m_clk[] = {
+ { .index = 0 },
+};
+
+ATLANTIS_PLL_DEFINE(CLK_RCPU_PLL, rcpu_pll_clk, osc_24m_clk, RCPU_PLL_CFG_REG,
+ PLL_RCPU_EN_REG, BUS_CG_REG, BIT(7),
+ CLK_SET_RATE_NO_REPARENT | CLK_SET_RATE_UNGATE |
+ CLK_IS_CRITICAL);
+
+static const struct clk_parent_data rcpu_root_parents[] = {
+ { .index = 0 },
+ { .hw = &rcpu_pll_clk.common.hw },
+};
+
+ATLANTIS_MUX_DEFINE(CLK_RCPU_ROOT, rcpu_root_mux, rcpu_root_parents,
+ RCPU_DIV_CFG_REG, 0, 1, CLK_SET_RATE_NO_REPARENT);
+
+ATLANTIS_DIVIDER_DEFINE(CLK_RCPU_DIV2, rcpu_div2_clk, rcpu_root_mux,
+ RCPU_DIV_CFG_REG, 2, 4, 0, 0);
+ATLANTIS_DIVIDER_DEFINE(CLK_RCPU_DIV4, rcpu_div4_clk, rcpu_root_mux,
+ RCPU_DIV_CFG_REG, 7, 4, 0, 0);
+ATLANTIS_DIVIDER_DEFINE(CLK_RCPU_RTC, rcpu_rtc_clk, rcpu_div4_clk,
+ RCPU_DIV_CFG_REG, 12, 6, 0, 0);
+
+ATLANTIS_GATE_DEFINE(CLK_SMNDMA0_ACLK, smndma0_aclk, rcpu_div2_clk,
+ RCPU_BLK_CG_REG, BIT(0), 0);
+ATLANTIS_GATE_DEFINE(CLK_SMNDMA1_ACLK, smndma1_aclk, rcpu_div2_clk,
+ RCPU_BLK_CG_REG, BIT(1), 0);
+ATLANTIS_GATE_DEFINE(CLK_WDT0_PCLK, wdt0_pclk, rcpu_div4_clk, RCPU_BLK_CG_REG,
+ BIT(2), 0);
+ATLANTIS_GATE_DEFINE(CLK_WDT1_PCLK, wdt1_pclk, rcpu_div4_clk, RCPU_BLK_CG_REG,
+ BIT(3), 0);
+ATLANTIS_GATE_DEFINE(CLK_TIMER_PCLK, timer_pclk, rcpu_div4_clk, RCPU_BLK_CG_REG,
+ BIT(4), 0);
+ATLANTIS_GATE_DEFINE(CLK_PVTC_PCLK, pvtc_pclk, rcpu_div4_clk, RCPU_BLK_CG_REG,
+ BIT(12), 0);
+ATLANTIS_GATE_DEFINE(CLK_PMU_PCLK, pmu_pclk, rcpu_div4_clk, RCPU_BLK_CG_REG,
+ BIT(13), 0);
+ATLANTIS_GATE_DEFINE(CLK_MAILBOX_HCLK, mb_hclk, rcpu_div2_clk, RCPU_BLK_CG_REG,
+ BIT(14), 0);
+ATLANTIS_GATE_DEFINE(CLK_SEC_SPACC_HCLK, sec_spacc_hclk, rcpu_div2_clk,
+ RCPU_BLK_CG_REG, BIT(26), 0);
+ATLANTIS_GATE_DEFINE(CLK_SEC_OTP_HCLK, sec_otp_hclk, rcpu_div2_clk,
+ RCPU_BLK_CG_REG, BIT(28), 0);
+ATLANTIS_GATE_DEFINE(CLK_TRNG_PCLK, trng_pclk, rcpu_div4_clk, RCPU_BLK_CG_REG,
+ BIT(29), 0);
+ATLANTIS_GATE_DEFINE(CLK_SEC_CRC_HCLK, sec_crc_hclk, rcpu_div2_clk,
+ RCPU_BLK_CG_REG, BIT(30), 0);
+
+ATLANTIS_CLK_FIXED_FACTOR_DEFINE(CLK_SMN_HCLK, rcpu_smn_hclk, rcpu_div2_clk, 1,
+ 1, 0);
+ATLANTIS_CLK_FIXED_FACTOR_DEFINE(CLK_AHB0_HCLK, rcpu_ahb0_hclk, rcpu_div2_clk,
+ 1, 1, 0);
+
+ATLANTIS_CLK_FIXED_FACTOR_DEFINE(CLK_SMN_PCLK, rcpu_smn_pclk, rcpu_div4_clk, 1,
+ 1, 0);
+
+ATLANTIS_CLK_FIXED_FACTOR_DEFINE(CLK_SMN_CLK, rcpu_smn_clk, rcpu_root_mux, 1, 1,
+ 0);
+ATLANTIS_CLK_FIXED_FACTOR_DEFINE(CLK_SCRATCHPAD_CLK, rcpu_scratchpad_aclk,
+ rcpu_root_mux, 1, 1, 0);
+ATLANTIS_CLK_FIXED_FACTOR_DEFINE(CLK_RCPU_CORE_CLK, rcpu_core_clk,
+ rcpu_root_mux, 1, 1, 0);
+ATLANTIS_CLK_FIXED_FACTOR_DEFINE(CLK_RCPU_ROM_CLK, rcpu_rom_aclk, rcpu_root_mux,
+ 1, 1, 0);
+
+static struct atlantis_clk_fixed_factor
+ otp_load_clk = { .config = { .mult = 1, .div = 1 },
+ .common = {
+ .clkid = CLK_OTP_LOAD_CLK,
+ .clk_type = ATLANTIS_CLK_FIXED_FACTOR,
+ .hw.init = CLK_HW_INIT_PARENTS_DATA(
+ "otp_load_clk", osc_24m_clk,
+ &clk_fixed_factor_ops,
+ CLK_SET_RATE_NO_REPARENT),
+ } };
+
+ATLANTIS_PLL_DEFINE(CLK_NOC_PLL, nocc_pll_clk, osc_24m_clk,
+ RCPU_NOCC_PLL_CFG_REG, PLL_NOCC_EN_REG, BUS_CG_REG, BIT(0),
+ CLK_SET_RATE_NO_REPARENT | CLK_SET_RATE_UNGATE |
+ CLK_IS_CRITICAL);
+
+static const struct clk_parent_data nocc_mux_parents[] = {
+ { .index = 0 },
+ { .hw = &nocc_pll_clk.common.hw },
+};
+
+ATLANTIS_MUX_DEFINE(CLK_NOCC_CLK, nocc_clk_mux, nocc_mux_parents,
+ RCPU_NOCC_CLK_CFG_REG, 0, 1, CLK_SET_RATE_NO_REPARENT);
+
+ATLANTIS_DIVIDER_DEFINE(CLK_NOCC_DIV2, nocc_div2_clk, nocc_clk_mux,
+ RCPU_NOCC_CLK_CFG_REG, 1, 4, 0, 0);
+ATLANTIS_DIVIDER_DEFINE(CLK_NOCC_DIV4, nocc_div4_clk, nocc_clk_mux,
+ RCPU_NOCC_CLK_CFG_REG, 5, 4, 0, 0);
+ATLANTIS_DIVIDER_DEFINE(CLK_NOCC_RTC, nocc_rtc_clk, nocc_div4_clk,
+ RCPU_NOCC_CLK_CFG_REG, 9, 6, 0, 0);
+ATLANTIS_DIVIDER_DEFINE(CLK_NOCC_CAN, nocc_can_div, nocc_clk_mux,
+ RCPU_NOCC_CLK_CFG_REG, 15, 4, 0, 0);
+
+static unsigned int refcnt_qspi;
+ATLANTIS_GATE_SHARED_DEFINE(CLK_QSPI_SCLK, qspi_sclk, nocc_clk_mux,
+ LSIO_BLK_CG_REG, BIT(0), &refcnt_qspi, 0);
+ATLANTIS_GATE_SHARED_DEFINE(CLK_QSPI_HCLK, qspi_hclk, nocc_div2_clk,
+ LSIO_BLK_CG_REG, BIT(0), &refcnt_qspi, 0);
+ATLANTIS_GATE_DEFINE(CLK_I2C0_PCLK, i2c0_pclk, nocc_div4_clk, LSIO_BLK_CG_REG,
+ BIT(1), 0);
+ATLANTIS_GATE_DEFINE(CLK_I2C1_PCLK, i2c1_pclk, nocc_div4_clk, LSIO_BLK_CG_REG,
+ BIT(2), 0);
+ATLANTIS_GATE_DEFINE(CLK_I2C2_PCLK, i2c2_pclk, nocc_div4_clk, LSIO_BLK_CG_REG,
+ BIT(3), 0);
+ATLANTIS_GATE_DEFINE(CLK_I2C3_PCLK, i2c3_pclk, nocc_div4_clk, LSIO_BLK_CG_REG,
+ BIT(4), 0);
+ATLANTIS_GATE_DEFINE(CLK_I2C4_PCLK, i2c4_pclk, nocc_div4_clk, LSIO_BLK_CG_REG,
+ BIT(5), 0);
+
+ATLANTIS_GATE_DEFINE(CLK_UART0_PCLK, uart0_pclk, nocc_div4_clk, LSIO_BLK_CG_REG,
+ BIT(6), 0);
+ATLANTIS_GATE_DEFINE(CLK_UART1_PCLK, uart1_pclk, nocc_div4_clk, LSIO_BLK_CG_REG,
+ BIT(7), 0);
+ATLANTIS_GATE_DEFINE(CLK_UART2_PCLK, uart2_pclk, nocc_div4_clk, LSIO_BLK_CG_REG,
+ BIT(8), 0);
+ATLANTIS_GATE_DEFINE(CLK_UART3_PCLK, uart3_pclk, nocc_div4_clk, LSIO_BLK_CG_REG,
+ BIT(9), 0);
+ATLANTIS_GATE_DEFINE(CLK_UART4_PCLK, uart4_pclk, nocc_div4_clk, LSIO_BLK_CG_REG,
+ BIT(10), 0);
+ATLANTIS_GATE_DEFINE(CLK_SPI0_PCLK, spi0_pclk, nocc_div4_clk, LSIO_BLK_CG_REG,
+ BIT(11), 0);
+ATLANTIS_GATE_DEFINE(CLK_SPI1_PCLK, spi1_pclk, nocc_div4_clk, LSIO_BLK_CG_REG,
+ BIT(12), 0);
+ATLANTIS_GATE_DEFINE(CLK_SPI2_PCLK, spi2_pclk, nocc_div4_clk, LSIO_BLK_CG_REG,
+ BIT(13), 0);
+ATLANTIS_GATE_DEFINE(CLK_SPI3_PCLK, spi3_pclk, nocc_div4_clk, LSIO_BLK_CG_REG,
+ BIT(14), 0);
+ATLANTIS_GATE_DEFINE(CLK_GPIO_PCLK, gpio_pclk, nocc_div4_clk, LSIO_BLK_CG_REG,
+ BIT(15), 0);
+
+static unsigned int refcnt_can0;
+ATLANTIS_GATE_SHARED_DEFINE(CLK_CAN0_HCLK, can0_hclk, nocc_div2_clk,
+ LSIO_BLK_CG_REG, BIT(17), &refcnt_can0, 0);
+ATLANTIS_GATE_SHARED_DEFINE(CLK_CAN0_CLK, can0_clk, nocc_can_div,
+ LSIO_BLK_CG_REG, BIT(17), &refcnt_can0, 0);
+
+static unsigned int refcnt_can1;
+ATLANTIS_GATE_SHARED_DEFINE(CLK_CAN1_HCLK, can1_hclk, nocc_div2_clk,
+ LSIO_BLK_CG_REG, BIT(18), &refcnt_can1, 0);
+ATLANTIS_GATE_SHARED_DEFINE(CLK_CAN1_CLK, can1_clk, nocc_can_div,
+ LSIO_BLK_CG_REG, BIT(18), &refcnt_can1, 0);
+
+ATLANTIS_CLK_FIXED_FACTOR_DEFINE(CLK_CAN0_TIMER_CLK, can0_timer_clk,
+ nocc_rtc_clk, 1, 1, 0);
+ATLANTIS_CLK_FIXED_FACTOR_DEFINE(CLK_CAN1_TIMER_CLK, can1_timer_clk,
+ nocc_rtc_clk, 1, 1, 0);
+
+static struct clk_hw *atlantis_rcpu_clks[] = {
+ [CLK_RCPU_PLL] = &rcpu_pll_clk.common.hw,
+ [CLK_RCPU_ROOT] = &rcpu_root_mux.common.hw,
+ [CLK_RCPU_DIV2] = &rcpu_div2_clk.common.hw,
+ [CLK_RCPU_DIV4] = &rcpu_div4_clk.common.hw,
+ [CLK_RCPU_RTC] = &rcpu_rtc_clk.common.hw,
+ [CLK_SMNDMA0_ACLK] = &smndma0_aclk.common.hw,
+ [CLK_SMNDMA1_ACLK] = &smndma1_aclk.common.hw,
+ [CLK_WDT0_PCLK] = &wdt0_pclk.common.hw,
+ [CLK_WDT1_PCLK] = &wdt1_pclk.common.hw,
+ [CLK_TIMER_PCLK] = &timer_pclk.common.hw,
+ [CLK_PVTC_PCLK] = &pvtc_pclk.common.hw,
+ [CLK_PMU_PCLK] = &pmu_pclk.common.hw,
+ [CLK_MAILBOX_HCLK] = &mb_hclk.common.hw,
+ [CLK_SEC_SPACC_HCLK] = &sec_spacc_hclk.common.hw,
+ [CLK_SEC_OTP_HCLK] = &sec_otp_hclk.common.hw,
+ [CLK_TRNG_PCLK] = &trng_pclk.common.hw,
+ [CLK_SEC_CRC_HCLK] = &sec_crc_hclk.common.hw,
+ [CLK_SMN_HCLK] = &rcpu_smn_hclk.common.hw,
+ [CLK_AHB0_HCLK] = &rcpu_ahb0_hclk.common.hw,
+ [CLK_SMN_PCLK] = &rcpu_smn_pclk.common.hw,
+ [CLK_SMN_CLK] = &rcpu_smn_clk.common.hw,
+ [CLK_SCRATCHPAD_CLK] = &rcpu_scratchpad_aclk.common.hw,
+ [CLK_RCPU_CORE_CLK] = &rcpu_core_clk.common.hw,
+ [CLK_RCPU_ROM_CLK] = &rcpu_rom_aclk.common.hw,
+ [CLK_OTP_LOAD_CLK] = &otp_load_clk.common.hw,
+ [CLK_NOC_PLL] = &nocc_pll_clk.common.hw,
+ [CLK_NOCC_CLK] = &nocc_clk_mux.common.hw,
+ [CLK_NOCC_DIV2] = &nocc_div2_clk.common.hw,
+ [CLK_NOCC_DIV4] = &nocc_div4_clk.common.hw,
+ [CLK_NOCC_RTC] = &nocc_rtc_clk.common.hw,
+ [CLK_NOCC_CAN] = &nocc_can_div.common.hw,
+ [CLK_QSPI_SCLK] = &qspi_sclk.common.hw,
+ [CLK_QSPI_HCLK] = &qspi_hclk.common.hw,
+ [CLK_I2C0_PCLK] = &i2c0_pclk.common.hw,
+ [CLK_I2C1_PCLK] = &i2c1_pclk.common.hw,
+ [CLK_I2C2_PCLK] = &i2c2_pclk.common.hw,
+ [CLK_I2C3_PCLK] = &i2c3_pclk.common.hw,
+ [CLK_I2C4_PCLK] = &i2c4_pclk.common.hw,
+ [CLK_UART0_PCLK] = &uart0_pclk.common.hw,
+ [CLK_UART1_PCLK] = &uart1_pclk.common.hw,
+ [CLK_UART2_PCLK] = &uart2_pclk.common.hw,
+ [CLK_UART3_PCLK] = &uart3_pclk.common.hw,
+ [CLK_UART4_PCLK] = &uart4_pclk.common.hw,
+ [CLK_SPI0_PCLK] = &spi0_pclk.common.hw,
+ [CLK_SPI1_PCLK] = &spi1_pclk.common.hw,
+ [CLK_SPI2_PCLK] = &spi2_pclk.common.hw,
+ [CLK_SPI3_PCLK] = &spi3_pclk.common.hw,
+ [CLK_GPIO_PCLK] = &gpio_pclk.common.hw,
+ [CLK_CAN0_HCLK] = &can0_hclk.common.hw,
+ [CLK_CAN0_CLK] = &can0_clk.common.hw,
+ [CLK_CAN1_HCLK] = &can1_hclk.common.hw,
+ [CLK_CAN1_CLK] = &can1_clk.common.hw,
+ [CLK_CAN0_TIMER_CLK] = &can0_timer_clk.common.hw,
+ [CLK_CAN1_TIMER_CLK] = &can1_timer_clk.common.hw,
+};
+
+static const struct atlantis_ccu_data atlantis_ccu_rcpu_data = {
+ .hws = atlantis_rcpu_clks,
+ .num = ARRAY_SIZE(atlantis_rcpu_clks),
+};
+
+static int atlantis_ccu_clocks_register(struct device *dev,
+ struct atlantis_ccu *ccu,
+ const struct atlantis_ccu_data *data)
+{
+ struct regmap *regmap = ccu->regmap;
+ struct clk_hw_onecell_data *clk_data;
+ int i, ret;
+ size_t num_clks = data->num;
+
+ clk_data = devm_kzalloc(dev, struct_size(clk_data, hws, data->num),
+ GFP_KERNEL);
+ if (!clk_data)
+ return -ENOMEM;
+
+ ccu->clk_data = clk_data;
+
+ for (i = 0; i < data->num; i++) {
+ struct clk_hw *hw = data->hws[i];
+ const char *name = hw->init->name;
+ struct atlantis_clk_common *common =
+ hw_to_atlantis_clk_common(hw);
+ common->regmap = regmap;
+
+ /* Fixup missing handle to parent for gates/muxes/dividers */
+ if (hw->init->parent_hws && hw->init->num_parents == 1) {
+ const struct atlantis_clk_common *parent =
+ hw_to_atlantis_clk_common(
+ hw->init->parent_hws[0]);
+ hw->init->parent_hws[0] = clk_data->hws[parent->clkid];
+ }
+
+ switch (common->clk_type) {
+ case ATLANTIS_CLK_MUX:
+ struct atlantis_clk_mux *mux =
+ hw_to_atlantis_clk_mux(hw);
+
+ hw = devm_clk_hw_register_mux_parent_data_table(
+ ccu->dev, name, hw->init->parent_data,
+ hw->init->num_parents, hw->init->flags,
+ ccu->base + mux->config.reg_offset,
+ mux->config.shift, mux->config.width, 0, NULL,
+ &lock);
+
+ if (IS_ERR(hw)) {
+ dev_err(dev, "Cannot register clock %d - %s\n",
+ i, name);
+ return ret;
+ }
+
+ if (data == &atlantis_ccu_rcpu_data) {
+ switch (common->clkid) {
+ case CLK_RCPU_ROOT:
+ ret = clk_hw_set_parent(
+ hw,
+ clk_data->hws[CLK_RCPU_PLL]);
+ if (ret)
+ dev_err(ccu->dev,
+ "Failed to set RCPU ROOT MUX parent: %d\n",
+ ret);
+ break;
+ case CLK_NOCC_CLK:
+ ret = clk_hw_set_parent(
+ hw, clk_data->hws[CLK_NOC_PLL]);
+ if (ret)
+ dev_err(ccu->dev,
+ "Failed to set NOCC Mux parent: %d\n",
+ ret);
+ break;
+ }
+ }
+ break;
+ case ATLANTIS_CLK_DIVIDER:
+ struct atlantis_clk_divider *div =
+ hw_to_atlantis_clk_divider(hw);
+
+ hw = devm_clk_hw_register_divider_parent_hw(
+ ccu->dev, name, common->hw.init->parent_hws[0],
+ div->common.hw.init->flags,
+ ccu->base + div->config.reg_offset,
+ div->config.shift, div->config.width,
+ div->config.flags, &lock);
+
+ if (IS_ERR(hw)) {
+ dev_err(dev, "Cannot register clock %d - %s\n",
+ i, name);
+ return ret;
+ }
+
+ break;
+ case ATLANTIS_CLK_GATE:
+ struct atlantis_clk_gate *gate =
+ hw_to_atlantis_clk_gate(hw);
+
+ hw = devm_clk_hw_register_gate_parent_hw(
+ ccu->dev, name, common->hw.init->parent_hws[0],
+ hw->init->flags,
+ ccu->base + gate->config.reg_offset,
+ ffs(gate->config.enable) - 1, 0, &lock);
+
+ if (IS_ERR(hw)) {
+ dev_err(dev, "Cannot register clock %d - %s\n",
+ i, name);
+ return ret;
+ }
+
+ break;
+ case ATLANTIS_CLK_FIXED_FACTOR:
+ struct atlantis_clk_fixed_factor *factor =
+ hw_to_atlantis_clk_fixed_factor(hw);
+
+ if (hw->init->parent_data) {
+ hw = devm_clk_hw_register_fixed_factor_index(
+ dev, name,
+ hw->init->parent_data[0].index,
+ hw->init->flags, factor->config.mult,
+ factor->config.div);
+ } else {
+ hw = devm_clk_hw_register_fixed_factor_parent_hw(
+ dev, name, hw->init->parent_hws[0],
+ hw->init->flags, factor->config.mult,
+ factor->config.div);
+ }
+ if (IS_ERR(hw)) {
+ dev_err(dev, "Cannot register clock %d - %s\n",
+ i, name);
+ return ret;
+ }
+ break;
+ case ATLANTIS_CLK_GATE_SHARED:
+ struct atlantis_clk_gate_shared *gate_shared =
+ hw_to_atlantis_clk_gate_shared(hw);
+ gate_shared->config.refcount_lock = &refcount_lock;
+
+ ret = devm_clk_hw_register(dev, hw);
+
+ if (ret) {
+ dev_err(dev, "Cannot register clock %d - %s\n",
+ i, name);
+ return ret;
+ }
+
+ break;
+ default:
+
+ ret = devm_clk_hw_register(dev, hw);
+
+ if (ret) {
+ dev_err(dev, "Cannot register clock %d - %s\n",
+ i, name);
+ return ret;
+ }
+
+ break;
+ }
+ clk_data->hws[common->clkid] = hw;
+ }
+
+ clk_data->num = num_clks;
+
+ ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, clk_data);
+ if (ret)
+ dev_err(dev, "failed to add clock hardware provider (%d)\n",
+ ret);
+
+ return ret;
+}
+
+static int atlantis_ccu_probe(struct platform_device *pdev)
+{
+ const struct atlantis_ccu_data *data;
+ struct device *dev = &pdev->dev;
+ int ret;
+
+ struct atlantis_ccu *ccu = devm_kzalloc(dev, sizeof(*ccu), GFP_KERNEL);
+
+ if (!ccu)
+ return -ENOMEM;
+
+ ccu->dev = dev;
+
+ ccu->base = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(ccu->base))
+ return dev_err_probe(dev, PTR_ERR(ccu->base),
+ "Failed to map registers\n");
+
+ ccu->regmap = devm_regmap_init_mmio(dev, ccu->base,
+ &atlantis_ccu_regmap_config);
+ if (IS_ERR(ccu->regmap))
+ return dev_err_probe(dev, PTR_ERR(ccu->regmap),
+ "Failed to init regmap\n");
+
+ data = of_device_get_match_data(dev);
+
+ ret = atlantis_ccu_clocks_register(dev, ccu, data);
+ if (ret)
+ return dev_err_probe(dev, ret, "failed to register clocks\n");
+
+ return 0;
+}
+
+static const struct of_device_id atlantis_ccu_of_match[] = {
+ {
+ .compatible = "tenstorrent,atlantis-syscon-rcpu",
+ .data = &atlantis_ccu_rcpu_data,
+ },
+ {}
+
+};
+MODULE_DEVICE_TABLE(of, atlantis_ccu_of_match);
+
+static struct platform_driver atlantis_ccu_driver = {
+ .probe = atlantis_ccu_probe,
+ .driver = {
+ .name = "atlantis-ccu",
+ .of_match_table = atlantis_ccu_of_match,
+ },
+};
+module_platform_driver(atlantis_ccu_driver);
+
+MODULE_DESCRIPTION("Tenstorrent Atlantis Clock Controller Driver");
+MODULE_AUTHOR("Anirudh Srinivasan <asrinivasan@oss.tenstorrent.com>");
+MODULE_LICENSE("GPL");
--
2.43.0
^ permalink raw reply related [flat|nested] 29+ messages in thread
* [PATCH 4/8] dt-bindings: soc: tenstorrent: Add atlantis resets
2026-01-15 23:41 [PATCH 0/8] Add Tenstorrent Atlantis Clock/Reset Controller Anirudh Srinivasan
` (2 preceding siblings ...)
2026-01-15 23:42 ` [PATCH 3/8] clk: tenstorrent: Add Atlantis clock controller driver Anirudh Srinivasan
@ 2026-01-15 23:42 ` Anirudh Srinivasan
2026-01-16 9:02 ` Krzysztof Kozlowski
2026-01-15 23:42 ` [PATCH 5/8] soc: tenstorrent: Add rcpu syscon reset register definitions Anirudh Srinivasan
` (3 subsequent siblings)
7 siblings, 1 reply; 29+ messages in thread
From: Anirudh Srinivasan @ 2026-01-15 23:42 UTC (permalink / raw)
To: Drew Fustini, Joel Stanley, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Michael Turquette, Stephen Boyd, Anirudh Srinivasan,
Philipp Zabel
Cc: linux-riscv, devicetree, linux-kernel, linux-clk, joel, fustini,
mpe, mpe, npiggin, agross, agross
Document resets from RCPU syscon for atlantis.
Signed-off-by: Anirudh Srinivasan <asrinivasan@oss.tenstorrent.com>
---
.../tenstorrent/tenstorrent,atlantis-syscon.yaml | 5 ++++
.../clock/tenstorrent,atlantis-syscon.h | 34 ++++++++++++++++++++++
2 files changed, 39 insertions(+)
diff --git a/Documentation/devicetree/bindings/soc/tenstorrent/tenstorrent,atlantis-syscon.yaml b/Documentation/devicetree/bindings/soc/tenstorrent/tenstorrent,atlantis-syscon.yaml
index 3915d78dfeda..7e9c8d85ba9e 100644
--- a/Documentation/devicetree/bindings/soc/tenstorrent/tenstorrent,atlantis-syscon.yaml
+++ b/Documentation/devicetree/bindings/soc/tenstorrent/tenstorrent,atlantis-syscon.yaml
@@ -31,11 +31,15 @@ properties:
description:
See <dt-bindings/clock/tenstorrent,atlantis-syscon.h> for valid indices.
+ "#reset-cells":
+ const: 1
+
required:
- compatible
- reg
- clocks
- "#clock-cells"
+ - "#reset-cells"
additionalProperties: false
@@ -55,4 +59,5 @@ examples:
reg = <0x0 0xa8000000 0x0 0x10000>;
clocks = <&osc_24m>;
#clock-cells = <1>;
+ #reset-cells = <1>;
};
diff --git a/include/dt-bindings/clock/tenstorrent,atlantis-syscon.h b/include/dt-bindings/clock/tenstorrent,atlantis-syscon.h
index a8518319642a..ac6afc95b224 100644
--- a/include/dt-bindings/clock/tenstorrent,atlantis-syscon.h
+++ b/include/dt-bindings/clock/tenstorrent,atlantis-syscon.h
@@ -64,4 +64,38 @@
#define CLK_CAN0_TIMER_CLK 52
#define CLK_CAN1_TIMER_CLK 53
+/* RCPU domain reset */
+#define RST_SMNDMA0 0
+#define RST_SMNDMA1 1
+#define RST_WDT0 2
+#define RST_WDT1 3
+#define RST_TMR 4
+#define RST_PVTC 5
+#define RST_PMU 6
+#define RST_MAILBOX 7
+#define RST_SPACC 8
+#define RST_OTP 9
+#define RST_TRNG 10
+#define RST_CRC 11
+#define RST_QSPI 12
+#define RST_I2C0 13
+#define RST_I2C1 14
+#define RST_I2C2 15
+#define RST_I2C3 16
+#define RST_I2C4 17
+#define RST_UART0 18
+#define RST_UART1 19
+#define RST_UART2 20
+#define RST_UART3 21
+#define RST_UART4 22
+#define RST_SPI0 23
+#define RST_SPI1 24
+#define RST_SPI2 25
+#define RST_SPI3 26
+#define RST_GPIO 27
+#define RST_CAN0 28
+#define RST_CAN1 29
+#define RST_I2S0 30
+#define RST_I2S1 31
+
#endif /* _DT_BINDINGS_ATLANTIS_SYSCON_H */
--
2.43.0
^ permalink raw reply related [flat|nested] 29+ messages in thread
* [PATCH 5/8] soc: tenstorrent: Add rcpu syscon reset register definitions
2026-01-15 23:41 [PATCH 0/8] Add Tenstorrent Atlantis Clock/Reset Controller Anirudh Srinivasan
` (3 preceding siblings ...)
2026-01-15 23:42 ` [PATCH 4/8] dt-bindings: soc: tenstorrent: Add atlantis resets Anirudh Srinivasan
@ 2026-01-15 23:42 ` Anirudh Srinivasan
2026-01-16 9:06 ` Krzysztof Kozlowski
2026-01-15 23:42 ` [PATCH 6/8] soc: tenstorrent: Add auxiliary device definitions for Atlantis Anirudh Srinivasan
` (2 subsequent siblings)
7 siblings, 1 reply; 29+ messages in thread
From: Anirudh Srinivasan @ 2026-01-15 23:42 UTC (permalink / raw)
To: Drew Fustini, Joel Stanley, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Michael Turquette, Stephen Boyd, Anirudh Srinivasan,
Philipp Zabel
Cc: linux-riscv, devicetree, linux-kernel, linux-clk, joel, fustini,
mpe, mpe, npiggin, agross, agross
Document register offsets used for resets in Atlantis
Signed-off-by: Anirudh Srinivasan <asrinivasan@oss.tenstorrent.com>
---
include/soc/tenstorrent/atlantis-syscon.h | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/include/soc/tenstorrent/atlantis-syscon.h b/include/soc/tenstorrent/atlantis-syscon.h
index b15dabfb42b5..f1dc6ad33c6d 100644
--- a/include/soc/tenstorrent/atlantis-syscon.h
+++ b/include/soc/tenstorrent/atlantis-syscon.h
@@ -19,6 +19,13 @@
#define PLL_NOCC_EN_REG 0x120
#define BUS_CG_REG 0x01FC
+/* RCPU Reset Register Offsets */
+#define RCPU_BLK_RST_REG 0x1c
+#define LSIO_BLK_RST_REG 0x20
+#define HSIO_BLK_RST_REG 0x0c
+#define PCIE_SUBS_RST_REG 0x00
+#define MM_RSTN_REG 0x14
+
/* PLL Bit Definitions */
#define PLL_CFG_EN_BIT BIT(0)
#define PLL_CFG_BYPASS_BIT BIT(1)
--
2.43.0
^ permalink raw reply related [flat|nested] 29+ messages in thread
* [PATCH 6/8] soc: tenstorrent: Add auxiliary device definitions for Atlantis
2026-01-15 23:41 [PATCH 0/8] Add Tenstorrent Atlantis Clock/Reset Controller Anirudh Srinivasan
` (4 preceding siblings ...)
2026-01-15 23:42 ` [PATCH 5/8] soc: tenstorrent: Add rcpu syscon reset register definitions Anirudh Srinivasan
@ 2026-01-15 23:42 ` Anirudh Srinivasan
2026-01-16 9:07 ` Krzysztof Kozlowski
2026-01-15 23:42 ` [PATCH 7/8] reset: tenstorrent: Add reset controller " Anirudh Srinivasan
2026-01-15 23:42 ` [PATCH 8/8] clk: tenstorrent: Add reset controller to Atlantis clock controller probe Anirudh Srinivasan
7 siblings, 1 reply; 29+ messages in thread
From: Anirudh Srinivasan @ 2026-01-15 23:42 UTC (permalink / raw)
To: Drew Fustini, Joel Stanley, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Michael Turquette, Stephen Boyd, Anirudh Srinivasan,
Philipp Zabel
Cc: linux-riscv, devicetree, linux-kernel, linux-clk, joel, fustini,
mpe, mpe, npiggin, agross, agross
Reset shares the same registers as the Clock Controller, so it is
implemented as an auxiliary device of the Clock Controller.
This commit adds the auxiliary device definitions needed for this.
Signed-off-by: Anirudh Srinivasan <asrinivasan@oss.tenstorrent.com>
---
include/soc/tenstorrent/atlantis-syscon.h | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/include/soc/tenstorrent/atlantis-syscon.h b/include/soc/tenstorrent/atlantis-syscon.h
index f1dc6ad33c6d..972a9b7da596 100644
--- a/include/soc/tenstorrent/atlantis-syscon.h
+++ b/include/soc/tenstorrent/atlantis-syscon.h
@@ -8,6 +8,14 @@
#include <linux/bits.h>
#include <linux/types.h>
+struct atlantis_ccu_adev {
+ struct auxiliary_device adev;
+ struct regmap *regmap;
+};
+
+#define to_atlantis_ccu_adev(_adev) \
+ container_of((_adev), struct atlantis_ccu_adev, adev)
+
/* RCPU Clock Register Offsets */
#define RCPU_PLL_CFG_REG 0x0000
#define RCPU_NOCC_PLL_CFG_REG 0x0004
--
2.43.0
^ permalink raw reply related [flat|nested] 29+ messages in thread
* [PATCH 7/8] reset: tenstorrent: Add reset controller for Atlantis
2026-01-15 23:41 [PATCH 0/8] Add Tenstorrent Atlantis Clock/Reset Controller Anirudh Srinivasan
` (5 preceding siblings ...)
2026-01-15 23:42 ` [PATCH 6/8] soc: tenstorrent: Add auxiliary device definitions for Atlantis Anirudh Srinivasan
@ 2026-01-15 23:42 ` Anirudh Srinivasan
2026-01-15 23:42 ` [PATCH 8/8] clk: tenstorrent: Add reset controller to Atlantis clock controller probe Anirudh Srinivasan
7 siblings, 0 replies; 29+ messages in thread
From: Anirudh Srinivasan @ 2026-01-15 23:42 UTC (permalink / raw)
To: Drew Fustini, Joel Stanley, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Michael Turquette, Stephen Boyd, Anirudh Srinivasan,
Philipp Zabel
Cc: linux-riscv, devicetree, linux-kernel, linux-clk, joel, fustini,
mpe, mpe, npiggin, agross, agross
Implement reset controller as an auxiliary device of the clock
controller, sharing the same regmap interface. This version of the
driver covers resets from the RCPU syscon.
Signed-off-by: Anirudh Srinivasan <asrinivasan@oss.tenstorrent.com>
---
MAINTAINERS | 1 +
drivers/reset/Kconfig | 11 ++
drivers/reset/Makefile | 1 +
drivers/reset/reset-tenstorrent-atlantis.c | 164 +++++++++++++++++++++++++++++
4 files changed, 177 insertions(+)
diff --git a/MAINTAINERS b/MAINTAINERS
index 93d941d2886b..31c3e5bcb32d 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -22538,6 +22538,7 @@ F: Documentation/devicetree/bindings/riscv/tenstorrent.yaml
F: Documentation/devicetree/bindings/soc/tenstorrent/tenstorrent,atlantis-syscon.yaml
F: arch/riscv/boot/dts/tenstorrent/
F: drivers/clk/tenstorrent/
+F: drivers/reset/reset-tenstorrent-atlantis.c
F: include/dt-bindings/clock/tenstorrent,atlantis-syscon.h
F: include/soc/tenstorrent/
diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig
index 6e5d6deffa7d..cade77717492 100644
--- a/drivers/reset/Kconfig
+++ b/drivers/reset/Kconfig
@@ -324,6 +324,17 @@ config RESET_SUNXI
help
This enables the reset driver for Allwinner SoCs.
+config RESET_TENSTORRENT_ATLANTIS
+ tristate "Tenstorrent atlantis reset driver"
+ depends on ARCH_TENSTORRENT || COMPILE_TEST
+ select AUXILIARY_BUS
+ default ARCH_TENSTORRENT
+ help
+ This enables the driver for the reset controller
+ present in the Tenstorrent Atlantis SoC.
+ Enable this option to be able to use hardware
+ resets on Atalantis based systems.
+
config RESET_TH1520
tristate "T-HEAD TH1520 reset controller"
depends on ARCH_THEAD || COMPILE_TEST
diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile
index 9c3e484dfd81..a31959da0a88 100644
--- a/drivers/reset/Makefile
+++ b/drivers/reset/Makefile
@@ -41,6 +41,7 @@ obj-$(CONFIG_RESET_SOCFPGA) += reset-socfpga.o
obj-$(CONFIG_RESET_SPACEMIT) += reset-spacemit.o
obj-$(CONFIG_RESET_SUNPLUS) += reset-sunplus.o
obj-$(CONFIG_RESET_SUNXI) += reset-sunxi.o
+obj-$(CONFIG_RESET_TENSTORRENT_ATLANTIS) += reset-tenstorrent-atlantis.o
obj-$(CONFIG_RESET_TH1520) += reset-th1520.o
obj-$(CONFIG_RESET_TI_SCI) += reset-ti-sci.o
obj-$(CONFIG_RESET_TI_SYSCON) += reset-ti-syscon.o
diff --git a/drivers/reset/reset-tenstorrent-atlantis.c b/drivers/reset/reset-tenstorrent-atlantis.c
new file mode 100644
index 000000000000..b1e934a5b054
--- /dev/null
+++ b/drivers/reset/reset-tenstorrent-atlantis.c
@@ -0,0 +1,164 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2026 Tenstorrent
+ */
+
+#include <linux/auxiliary_bus.h>
+#include <linux/device.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/module.h>
+#include <linux/reset-controller.h>
+#include <linux/regmap.h>
+
+#include <soc/tenstorrent/atlantis-syscon.h>
+#include <dt-bindings/clock/tenstorrent,atlantis-syscon.h>
+
+struct atlantis_reset_data {
+ u8 bit;
+ u16 reg;
+ bool active_low;
+};
+
+struct atlantis_reset_controller_data {
+ const struct atlantis_reset_data *reset_data;
+ size_t count;
+};
+
+struct atlantis_reset_controller {
+ struct reset_controller_dev rcdev;
+ const struct atlantis_reset_controller_data *data;
+ struct regmap *regmap;
+};
+
+#define to_atlantis_reset_controller(_rcdev) \
+ container_of((_rcdev), struct atlantis_reset_controller, rcdev)
+
+#define RESET_DATA(_reg, _bit, _active_low) \
+ { \
+ .bit = _bit, .reg = _reg, .active_low = _active_low, \
+ }
+
+static const struct atlantis_reset_data atlantis_rcpu_resets[] = {
+ [RST_SMNDMA0] = RESET_DATA(RCPU_BLK_RST_REG, 0, true),
+ [RST_SMNDMA1] = RESET_DATA(RCPU_BLK_RST_REG, 1, true),
+ [RST_WDT0] = RESET_DATA(RCPU_BLK_RST_REG, 2, true),
+ [RST_WDT1] = RESET_DATA(RCPU_BLK_RST_REG, 3, true),
+ [RST_TMR] = RESET_DATA(RCPU_BLK_RST_REG, 4, true),
+ [RST_PVTC] = RESET_DATA(RCPU_BLK_RST_REG, 12, true),
+ [RST_PMU] = RESET_DATA(RCPU_BLK_RST_REG, 13, true),
+ [RST_MAILBOX] = RESET_DATA(RCPU_BLK_RST_REG, 14, true),
+ [RST_SPACC] = RESET_DATA(RCPU_BLK_RST_REG, 26, true),
+ [RST_OTP] = RESET_DATA(RCPU_BLK_RST_REG, 28, true),
+ [RST_TRNG] = RESET_DATA(RCPU_BLK_RST_REG, 29, true),
+ [RST_CRC] = RESET_DATA(RCPU_BLK_RST_REG, 30, true),
+
+ [RST_QSPI] = RESET_DATA(LSIO_BLK_RST_REG, 0, true),
+ [RST_I2C0] = RESET_DATA(LSIO_BLK_RST_REG, 1, true),
+ [RST_I2C1] = RESET_DATA(LSIO_BLK_RST_REG, 2, true),
+ [RST_I2C2] = RESET_DATA(LSIO_BLK_RST_REG, 3, true),
+ [RST_I2C3] = RESET_DATA(LSIO_BLK_RST_REG, 4, true),
+ [RST_I2C4] = RESET_DATA(LSIO_BLK_RST_REG, 5, true),
+ [RST_UART0] = RESET_DATA(LSIO_BLK_RST_REG, 6, true),
+ [RST_UART1] = RESET_DATA(LSIO_BLK_RST_REG, 7, true),
+ [RST_UART2] = RESET_DATA(LSIO_BLK_RST_REG, 8, true),
+ [RST_UART3] = RESET_DATA(LSIO_BLK_RST_REG, 9, true),
+ [RST_UART4] = RESET_DATA(LSIO_BLK_RST_REG, 10, true),
+ [RST_SPI0] = RESET_DATA(LSIO_BLK_RST_REG, 11, true),
+ [RST_SPI1] = RESET_DATA(LSIO_BLK_RST_REG, 12, true),
+ [RST_SPI2] = RESET_DATA(LSIO_BLK_RST_REG, 13, true),
+ [RST_SPI3] = RESET_DATA(LSIO_BLK_RST_REG, 14, true),
+ [RST_GPIO] = RESET_DATA(LSIO_BLK_RST_REG, 15, true),
+ [RST_CAN0] = RESET_DATA(LSIO_BLK_RST_REG, 17, true),
+ [RST_CAN1] = RESET_DATA(LSIO_BLK_RST_REG, 18, true),
+ [RST_I2S0] = RESET_DATA(LSIO_BLK_RST_REG, 19, true),
+ [RST_I2S1] = RESET_DATA(LSIO_BLK_RST_REG, 20, true),
+
+};
+
+static const struct atlantis_reset_controller_data atlantis_rcpu_reset_data = {
+ .reset_data = atlantis_rcpu_resets,
+ .count = ARRAY_SIZE(atlantis_rcpu_resets),
+};
+
+static int atlantis_reset_update(struct reset_controller_dev *rcdev,
+ unsigned long id, bool assert)
+{
+ unsigned int val;
+ struct atlantis_reset_controller *rst =
+ to_atlantis_reset_controller(rcdev);
+ const struct atlantis_reset_data *data = &rst->data->reset_data[id];
+ unsigned int mask = BIT(data->bit);
+ struct regmap *regmap = rst->regmap;
+
+ if (data->active_low ^ assert)
+ val = mask;
+ else
+ val = ~mask;
+
+ return regmap_update_bits(regmap, data->reg, mask, val);
+}
+
+static int atlantis_reset_assert(struct reset_controller_dev *rcdev,
+ unsigned long id)
+{
+ return atlantis_reset_update(rcdev, id, true);
+}
+
+static int atlantis_reset_deassert(struct reset_controller_dev *rcdev,
+ unsigned long id)
+{
+ return atlantis_reset_update(rcdev, id, false);
+}
+
+static const struct reset_control_ops atlantis_reset_control_ops = {
+ .assert = atlantis_reset_assert,
+ .deassert = atlantis_reset_deassert,
+};
+
+static int
+atlantis_reset_controller_register(struct device *dev,
+ struct atlantis_reset_controller *controller)
+{
+ struct reset_controller_dev *rcdev = &controller->rcdev;
+
+ rcdev->ops = &atlantis_reset_control_ops;
+ rcdev->owner = THIS_MODULE;
+ rcdev->of_node = dev->of_node;
+ rcdev->nr_resets = controller->data->count;
+
+ return devm_reset_controller_register(dev, &controller->rcdev);
+}
+static int atlantis_reset_probe(struct auxiliary_device *adev,
+ const struct auxiliary_device_id *id)
+{
+ struct atlantis_ccu_adev *rdev = to_atlantis_ccu_adev(adev);
+ struct atlantis_reset_controller *controller;
+ struct device *dev = &adev->dev;
+
+ controller = devm_kzalloc(dev, sizeof(*controller), GFP_KERNEL);
+ if (!controller)
+ return -ENOMEM;
+ controller->data =
+ (const struct atlantis_reset_controller_data *)id->driver_data;
+ controller->regmap = rdev->regmap;
+
+ return atlantis_reset_controller_register(dev, controller);
+}
+
+static const struct auxiliary_device_id atlantis_reset_ids[] = {
+ { .name = "atlantis_ccu.rcpu-reset",
+ .driver_data = (kernel_ulong_t)&atlantis_rcpu_reset_data },
+ {},
+};
+MODULE_DEVICE_TABLE(auxiliary, atlantis_reset_ids);
+
+static struct auxiliary_driver atlantis_reset_driver = {
+ .probe = atlantis_reset_probe,
+ .id_table = atlantis_reset_ids,
+};
+module_auxiliary_driver(atlantis_reset_driver);
+
+MODULE_AUTHOR("Anirudh Srinivasan <asrinivasan@oss.tenstorrent.com>");
+MODULE_DESCRIPTION("Atlantis reset controller driver");
+MODULE_LICENSE("GPL");
--
2.43.0
^ permalink raw reply related [flat|nested] 29+ messages in thread
* [PATCH 8/8] clk: tenstorrent: Add reset controller to Atlantis clock controller probe
2026-01-15 23:41 [PATCH 0/8] Add Tenstorrent Atlantis Clock/Reset Controller Anirudh Srinivasan
` (6 preceding siblings ...)
2026-01-15 23:42 ` [PATCH 7/8] reset: tenstorrent: Add reset controller " Anirudh Srinivasan
@ 2026-01-15 23:42 ` Anirudh Srinivasan
2026-01-16 9:08 ` Krzysztof Kozlowski
7 siblings, 1 reply; 29+ messages in thread
From: Anirudh Srinivasan @ 2026-01-15 23:42 UTC (permalink / raw)
To: Drew Fustini, Joel Stanley, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Michael Turquette, Stephen Boyd, Anirudh Srinivasan,
Philipp Zabel
Cc: linux-riscv, devicetree, linux-kernel, linux-clk, joel, fustini,
mpe, mpe, npiggin, agross, agross
Create a reset auxiliary device during probe of clock controller
Signed-off-by: Anirudh Srinivasan <asrinivasan@oss.tenstorrent.com>
---
drivers/clk/tenstorrent/atlantis-ccu.c | 59 ++++++++++++++++++++++++++++++++++
1 file changed, 59 insertions(+)
diff --git a/drivers/clk/tenstorrent/atlantis-ccu.c b/drivers/clk/tenstorrent/atlantis-ccu.c
index f3a2ea49a82e..e4f56018907f 100644
--- a/drivers/clk/tenstorrent/atlantis-ccu.c
+++ b/drivers/clk/tenstorrent/atlantis-ccu.c
@@ -491,6 +491,7 @@ struct atlantis_ccu {
struct atlantis_ccu_data {
struct clk_hw **hws;
size_t num;
+ const char *reset_name;
};
static const struct clk_parent_data osc_24m_clk[] = {
@@ -706,6 +707,7 @@ static struct clk_hw *atlantis_rcpu_clks[] = {
static const struct atlantis_ccu_data atlantis_ccu_rcpu_data = {
.hws = atlantis_rcpu_clks,
.num = ARRAY_SIZE(atlantis_rcpu_clks),
+ .reset_name = "rcpu-reset"
};
static int atlantis_ccu_clocks_register(struct device *dev,
@@ -875,6 +877,59 @@ static int atlantis_ccu_clocks_register(struct device *dev,
return ret;
}
+static void atlantis_cadev_release(struct device *dev)
+{
+ struct auxiliary_device *adev = to_auxiliary_dev(dev);
+
+ kfree(to_atlantis_ccu_adev(adev));
+}
+
+static void atlantis_adev_unregister(void *data)
+{
+ struct auxiliary_device *adev = data;
+
+ auxiliary_device_delete(adev);
+ auxiliary_device_uninit(adev);
+}
+
+static int atlantis_ccu_adev_register(struct device *dev,
+ struct atlantis_ccu *ccu,
+ const struct atlantis_ccu_data *data,
+ const char *adev_name)
+{
+ struct atlantis_ccu_adev *cadev;
+ struct auxiliary_device *adev;
+ int ret;
+
+ cadev = kzalloc(sizeof(*cadev), GFP_KERNEL);
+ if (!cadev)
+ return -ENOMEM;
+
+ cadev->regmap = ccu->regmap;
+
+ adev = &cadev->adev;
+ adev->name = adev_name;
+ adev->dev.parent = dev;
+ adev->dev.release = atlantis_cadev_release;
+ adev->dev.of_node = dev->of_node;
+
+ ret = auxiliary_device_init(adev);
+ if (ret)
+ goto err_free_cadev;
+
+ ret = auxiliary_device_add(adev);
+ if (ret) {
+ auxiliary_device_uninit(adev);
+ return ret;
+ }
+
+ return devm_add_action_or_reset(dev, atlantis_adev_unregister, adev);
+
+err_free_cadev:
+ kfree(cadev);
+
+ return ret;
+}
static int atlantis_ccu_probe(struct platform_device *pdev)
{
const struct atlantis_ccu_data *data;
@@ -905,6 +960,10 @@ static int atlantis_ccu_probe(struct platform_device *pdev)
if (ret)
return dev_err_probe(dev, ret, "failed to register clocks\n");
+ ret = atlantis_ccu_adev_register(dev, ccu, data, data->reset_name);
+ if (ret)
+ return dev_err_probe(dev, ret, "failed to register resets\n");
+
return 0;
}
--
2.43.0
^ permalink raw reply related [flat|nested] 29+ messages in thread
* Re: [PATCH 3/8] clk: tenstorrent: Add Atlantis clock controller driver
2026-01-15 23:42 ` [PATCH 3/8] clk: tenstorrent: Add Atlantis clock controller driver Anirudh Srinivasan
@ 2026-01-16 2:05 ` Brian Masney
2026-01-16 9:00 ` Krzysztof Kozlowski
2026-01-16 20:46 ` Anirudh Srinivasan
2026-01-16 11:56 ` kernel test robot
1 sibling, 2 replies; 29+ messages in thread
From: Brian Masney @ 2026-01-16 2:05 UTC (permalink / raw)
To: Anirudh Srinivasan
Cc: Drew Fustini, Joel Stanley, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Michael Turquette, Stephen Boyd, Philipp Zabel,
linux-riscv, devicetree, linux-kernel, linux-clk, joel, fustini,
mpe, mpe, npiggin, agross, agross
Hi Anirudh,
Thanks for the patch!
On Thu, Jan 15, 2026 at 05:42:02PM -0600, Anirudh Srinivasan wrote:
> Add driver for syscon block in Tenstorrent Atlantis SoC. This version of
> the driver coves clocks from RCPU syscon.
>
> 5 types of clocks generated by this controller: PLLs (PLLs
> with bypass functionality and an additional Gate clk at output), Shared
> Gates (Multiple Gate clks that share an enable bit), standard Muxes,
> Dividers and Gates. All clocks are derived from a 24 Mhz oscillator.
>
> Signed-off-by: Anirudh Srinivasan <asrinivasan@oss.tenstorrent.com>
> ---
> diff --git a/drivers/clk/tenstorrent/atlantis-ccu.c b/drivers/clk/tenstorrent/atlantis-ccu.c
> new file mode 100644
> index 000000000000..f3a2ea49a82e
> --- /dev/null
> +++ b/drivers/clk/tenstorrent/atlantis-ccu.c
> @@ -0,0 +1,932 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Copyright (c) 2026 Tenstorrent
> + */
> +
> +#include <linux/array_size.h>
> +#include <linux/auxiliary_bus.h>
> +#include <linux/clk-provider.h>
> +#include <linux/delay.h>
> +#include <linux/idr.h>
> +#include <linux/mfd/syscon.h>
> +#include <linux/minmax.h>
> +#include <linux/module.h>
> +#include <linux/platform_device.h>
> +#include <linux/slab.h>
> +
> +#include <soc/tenstorrent/atlantis-syscon.h>
> +
> +#include <dt-bindings/clock/tenstorrent,atlantis-syscon.h>
> +#include <linux/regmap.h>
> +#include <linux/clk-provider.h>
> +#include <linux/math.h>
> +#include <linux/bitfield.h>
Please sort the headers. clk-provider.h is listed twice. Remove the
unnecessary newlines.
> +static void atlantis_ccu_lock(void *_lock)
> +{
> + spinlock_t *lock = _lock;
> +
> + spin_lock(lock);
> +}
> +
> +static void atlantis_ccu_unlock(void *_lock)
> +{
> + spinlock_t *lock = _lock;
> +
> + spin_unlock(lock);
> +}
Are these abstractions really needed? Why not just call spin_lock/unlock
directly?
> +static int atlantis_ccu_clocks_register(struct device *dev,
> + struct atlantis_ccu *ccu,
> + const struct atlantis_ccu_data *data)
> +{
> + struct regmap *regmap = ccu->regmap;
> + struct clk_hw_onecell_data *clk_data;
> + int i, ret;
> + size_t num_clks = data->num;
> +
> + clk_data = devm_kzalloc(dev, struct_size(clk_data, hws, data->num),
> + GFP_KERNEL);
> + if (!clk_data)
> + return -ENOMEM;
> +
> + ccu->clk_data = clk_data;
> +
> + for (i = 0; i < data->num; i++) {
> + struct clk_hw *hw = data->hws[i];
> + const char *name = hw->init->name;
> + struct atlantis_clk_common *common =
> + hw_to_atlantis_clk_common(hw);
> + common->regmap = regmap;
> +
> + /* Fixup missing handle to parent for gates/muxes/dividers */
> + if (hw->init->parent_hws && hw->init->num_parents == 1) {
> + const struct atlantis_clk_common *parent =
> + hw_to_atlantis_clk_common(
> + hw->init->parent_hws[0]);
> + hw->init->parent_hws[0] = clk_data->hws[parent->clkid];
> + }
> +
> + switch (common->clk_type) {
> + case ATLANTIS_CLK_MUX:
> + struct atlantis_clk_mux *mux =
> + hw_to_atlantis_clk_mux(hw);
> +
> + hw = devm_clk_hw_register_mux_parent_data_table(
> + ccu->dev, name, hw->init->parent_data,
> + hw->init->num_parents, hw->init->flags,
> + ccu->base + mux->config.reg_offset,
> + mux->config.shift, mux->config.width, 0, NULL,
> + &lock);
> +
> + if (IS_ERR(hw)) {
> + dev_err(dev, "Cannot register clock %d - %s\n",
> + i, name);
> + return ret;
return PTR_ERR(hw);
> + }
> +
> + if (data == &atlantis_ccu_rcpu_data) {
> + switch (common->clkid) {
> + case CLK_RCPU_ROOT:
> + ret = clk_hw_set_parent(
> + hw,
> + clk_data->hws[CLK_RCPU_PLL]);
Should the parent be defined in device tree instead of statically in the
driver? devm_of_clk_add_hw_provider() is called below, and it calls
of_clk_set_defaults(), which will allow the use of the
assigned-clock-parents and assigned-clocks properties.
> + if (ret)
> + dev_err(ccu->dev,
> + "Failed to set RCPU ROOT MUX parent: %d\n",
> + ret);
> + break;
> + case CLK_NOCC_CLK:
> + ret = clk_hw_set_parent(
> + hw, clk_data->hws[CLK_NOC_PLL]);
> + if (ret)
> + dev_err(ccu->dev,
> + "Failed to set NOCC Mux parent: %d\n",
> + ret);
> + break;
> + }
> + }
> + break;
> + case ATLANTIS_CLK_DIVIDER:
> + struct atlantis_clk_divider *div =
> + hw_to_atlantis_clk_divider(hw);
> +
> + hw = devm_clk_hw_register_divider_parent_hw(
> + ccu->dev, name, common->hw.init->parent_hws[0],
> + div->common.hw.init->flags,
> + ccu->base + div->config.reg_offset,
> + div->config.shift, div->config.width,
> + div->config.flags, &lock);
> +
> + if (IS_ERR(hw)) {
> + dev_err(dev, "Cannot register clock %d - %s\n",
> + i, name);
> + return ret;
> + }
> +
> + break;
> + case ATLANTIS_CLK_GATE:
> + struct atlantis_clk_gate *gate =
> + hw_to_atlantis_clk_gate(hw);
> +
> + hw = devm_clk_hw_register_gate_parent_hw(
> + ccu->dev, name, common->hw.init->parent_hws[0],
> + hw->init->flags,
> + ccu->base + gate->config.reg_offset,
> + ffs(gate->config.enable) - 1, 0, &lock);
> +
> + if (IS_ERR(hw)) {
> + dev_err(dev, "Cannot register clock %d - %s\n",
> + i, name);
> + return ret;
return PTR_ERR(hw);
> + }
> +
> + break;
> + case ATLANTIS_CLK_FIXED_FACTOR:
> + struct atlantis_clk_fixed_factor *factor =
> + hw_to_atlantis_clk_fixed_factor(hw);
> +
> + if (hw->init->parent_data) {
> + hw = devm_clk_hw_register_fixed_factor_index(
> + dev, name,
> + hw->init->parent_data[0].index,
> + hw->init->flags, factor->config.mult,
> + factor->config.div);
> + } else {
> + hw = devm_clk_hw_register_fixed_factor_parent_hw(
> + dev, name, hw->init->parent_hws[0],
> + hw->init->flags, factor->config.mult,
> + factor->config.div);
> + }
> + if (IS_ERR(hw)) {
> + dev_err(dev, "Cannot register clock %d - %s\n",
> + i, name);
> + return ret;
return PTR_ERR(hw);
> + }
> + break;
> + case ATLANTIS_CLK_GATE_SHARED:
> + struct atlantis_clk_gate_shared *gate_shared =
> + hw_to_atlantis_clk_gate_shared(hw);
> + gate_shared->config.refcount_lock = &refcount_lock;
> +
> + ret = devm_clk_hw_register(dev, hw);
> +
Unnecessary newline
> + if (ret) {
> + dev_err(dev, "Cannot register clock %d - %s\n",
> + i, name);
> + return ret;
> + }
> +
> + break;
> + default:
> +
> + ret = devm_clk_hw_register(dev, hw);
> +
Unnecessary newline
Brian
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH 1/8] dt-bindings: soc: tenstorrent: Add tenstorrent,atlantis-syscon
2026-01-15 23:42 ` [PATCH 1/8] dt-bindings: soc: tenstorrent: Add tenstorrent,atlantis-syscon Anirudh Srinivasan
@ 2026-01-16 3:18 ` Rob Herring (Arm)
2026-01-16 4:03 ` Rob Herring
2026-01-16 9:04 ` Krzysztof Kozlowski
2 siblings, 0 replies; 29+ messages in thread
From: Rob Herring (Arm) @ 2026-01-16 3:18 UTC (permalink / raw)
To: Anirudh Srinivasan
Cc: Michael Turquette, mpe, linux-clk, Philipp Zabel, mpe,
linux-riscv, devicetree, Krzysztof Kozlowski, Stephen Boyd,
Drew Fustini, linux-kernel, agross, npiggin, agross, joel,
fustini, Conor Dooley, Joel Stanley
On Thu, 15 Jan 2026 17:42:00 -0600, Anirudh Srinivasan wrote:
> Document bindings for Tenstorrent Atlantis syscon that manages clocks
> and resets. This syscon block is instantiated 4 times in the SoC.
> This commit documents the clocks from the RCPU syscon block.
>
> Signed-off-by: Anirudh Srinivasan <asrinivasan@oss.tenstorrent.com>
> ---
> .../tenstorrent/tenstorrent,atlantis-syscon.yaml | 58 +++++++++++++++++++
> MAINTAINERS | 2 +
> .../clock/tenstorrent,atlantis-syscon.h | 67 ++++++++++++++++++++++
> 3 files changed, 127 insertions(+)
>
My bot found errors running 'make dt_binding_check' on your patch:
yamllint warnings/errors:
dtschema/dtc warnings/errors:
Documentation/devicetree/bindings/soc/tenstorrent/tenstorrent,atlantis-syscon.example.dtb: /example-0/system-controller@a8000000: failed to match any schema with compatible: ['tenstorrent,atlantis-sycon-rcpu']
doc reference errors (make refcheckdocs):
See https://patchwork.kernel.org/project/devicetree/patch/20260115-atlantis-clocks-v1-1-7356e671f28b@oss.tenstorrent.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] 29+ messages in thread
* Re: [PATCH 1/8] dt-bindings: soc: tenstorrent: Add tenstorrent,atlantis-syscon
2026-01-15 23:42 ` [PATCH 1/8] dt-bindings: soc: tenstorrent: Add tenstorrent,atlantis-syscon Anirudh Srinivasan
2026-01-16 3:18 ` Rob Herring (Arm)
@ 2026-01-16 4:03 ` Rob Herring
2026-01-16 21:48 ` Anirudh Srinivasan
2026-01-16 9:04 ` Krzysztof Kozlowski
2 siblings, 1 reply; 29+ messages in thread
From: Rob Herring @ 2026-01-16 4:03 UTC (permalink / raw)
To: Anirudh Srinivasan
Cc: Drew Fustini, Joel Stanley, Krzysztof Kozlowski, Conor Dooley,
Michael Turquette, Stephen Boyd, Philipp Zabel, linux-riscv,
devicetree, linux-kernel, linux-clk, joel, fustini, mpe, mpe,
npiggin, agross, agross
On Thu, Jan 15, 2026 at 05:42:00PM -0600, Anirudh Srinivasan wrote:
> Document bindings for Tenstorrent Atlantis syscon that manages clocks
> and resets. This syscon block is instantiated 4 times in the SoC.
> This commit documents the clocks from the RCPU syscon block.
>
> Signed-off-by: Anirudh Srinivasan <asrinivasan@oss.tenstorrent.com>
> ---
> .../tenstorrent/tenstorrent,atlantis-syscon.yaml | 58 +++++++++++++++++++
Filename should match compatible.
> MAINTAINERS | 2 +
> .../clock/tenstorrent,atlantis-syscon.h | 67 ++++++++++++++++++++++
> 3 files changed, 127 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/soc/tenstorrent/tenstorrent,atlantis-syscon.yaml b/Documentation/devicetree/bindings/soc/tenstorrent/tenstorrent,atlantis-syscon.yaml
> new file mode 100644
> index 000000000000..3915d78dfeda
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/soc/tenstorrent/tenstorrent,atlantis-syscon.yaml
> @@ -0,0 +1,58 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/soc/tenstorrent/tenstorrent,atlantis-syscon.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Tenstorrent Atlantis SoC System Controller
> +
> +maintainers:
> + - Anirudh Srinivasan <asrinivasan@oss.tenstorrent.com>
> +
> +description:
> + System controller found in Tenstorrent Atlantis SoC, which is capable of
> + clock and reset functions.
> +
> + RCPU syscon controls clocks and resets for low speed IO interfaces on chip
> +
> +properties:
> + compatible:
> + enum:
> + - tenstorrent,atlantis-syscon-rcpu
If "RCPU" is what the h/w block is called and sufficient to identify it,
then drop the "syscon-" part.
> +
> + reg:
> + maxItems: 1
> +
> + clocks:
> + maxItems: 1
> +
> + "#clock-cells":
> + const: 1
> + description:
> + See <dt-bindings/clock/tenstorrent,atlantis-syscon.h> for valid indices.
Be consistent with the compatible string for the file name.
> +
> +required:
> + - compatible
> + - reg
> + - clocks
> + - "#clock-cells"
> +
> +additionalProperties: false
> +
> +examples:
> + - |
> + clocks {
> + osc_24m: clock-24m {
> + compatible = "fixed-clock";
> + clock-frequency = <24000000>;
> + clock-output-names = "osc_24m";
> + #clock-cells = <0>;
> + };
> + };
Drop this node. Not relevant to the example.
> +
> + syscon_rcpu: system-controller@a8000000 {
> + compatible = "tenstorrent,atlantis-sycon-rcpu";
> + reg = <0x0 0xa8000000 0x0 0x10000>;
> + clocks = <&osc_24m>;
> + #clock-cells = <1>;
> + };
> diff --git a/MAINTAINERS b/MAINTAINERS
> index dc731d37c8fe..19a98b1fa456 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -22535,7 +22535,9 @@ L: linux-riscv@lists.infradead.org
> S: Maintained
> T: git https://github.com/tenstorrent/linux.git
> F: Documentation/devicetree/bindings/riscv/tenstorrent.yaml
> +F: Documentation/devicetree/bindings/soc/tenstorrent/tenstorrent,atlantis-syscon.yaml
> F: arch/riscv/boot/dts/tenstorrent/
> +F: include/dt-bindings/clock/tenstorrent,atlantis-syscon.h
>
> RISC-V THEAD SoC SUPPORT
> M: Drew Fustini <fustini@kernel.org>
> diff --git a/include/dt-bindings/clock/tenstorrent,atlantis-syscon.h b/include/dt-bindings/clock/tenstorrent,atlantis-syscon.h
> new file mode 100644
> index 000000000000..a8518319642a
> --- /dev/null
> +++ b/include/dt-bindings/clock/tenstorrent,atlantis-syscon.h
> @@ -0,0 +1,67 @@
> +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
> +/*
> + * Copyright (c) 2026 Tenstorrent
> + */
> +
> +#ifndef _DT_BINDINGS_ATLANTIS_SYSCON_H
> +#define _DT_BINDINGS_ATLANTIS_SYSCON_H
> +
> +/*
> + * RCPU Domain Clock IDs
> + */
> +#define CLK_RCPU_PLL 0
> +#define CLK_RCPU_ROOT 1
> +#define CLK_RCPU_DIV2 2
> +#define CLK_RCPU_DIV4 3
> +#define CLK_RCPU_RTC 4
> +#define CLK_SMNDMA0_ACLK 5
> +#define CLK_SMNDMA1_ACLK 6
> +#define CLK_WDT0_PCLK 7
> +#define CLK_WDT1_PCLK 8
> +#define CLK_TIMER_PCLK 9
> +#define CLK_PVTC_PCLK 10
> +#define CLK_PMU_PCLK 11
> +#define CLK_MAILBOX_HCLK 12
> +#define CLK_SEC_SPACC_HCLK 13
> +#define CLK_SEC_OTP_HCLK 14
> +#define CLK_TRNG_PCLK 15
> +#define CLK_SEC_CRC_HCLK 16
> +#define CLK_SMN_HCLK 17
> +#define CLK_AHB0_HCLK 18
> +#define CLK_SMN_PCLK 19
> +#define CLK_SMN_CLK 20
> +#define CLK_SCRATCHPAD_CLK 21
> +#define CLK_RCPU_CORE_CLK 22
> +#define CLK_RCPU_ROM_CLK 23
> +#define CLK_OTP_LOAD_CLK 24
> +#define CLK_NOC_PLL 25
> +#define CLK_NOCC_CLK 26
> +#define CLK_NOCC_DIV2 27
> +#define CLK_NOCC_DIV4 28
> +#define CLK_NOCC_RTC 29
> +#define CLK_NOCC_CAN 30
> +#define CLK_QSPI_SCLK 31
> +#define CLK_QSPI_HCLK 32
> +#define CLK_I2C0_PCLK 33
> +#define CLK_I2C1_PCLK 34
> +#define CLK_I2C2_PCLK 35
> +#define CLK_I2C3_PCLK 36
> +#define CLK_I2C4_PCLK 37
> +#define CLK_UART0_PCLK 38
> +#define CLK_UART1_PCLK 39
> +#define CLK_UART2_PCLK 40
> +#define CLK_UART3_PCLK 41
> +#define CLK_UART4_PCLK 42
> +#define CLK_SPI0_PCLK 43
> +#define CLK_SPI1_PCLK 44
> +#define CLK_SPI2_PCLK 45
> +#define CLK_SPI3_PCLK 46
> +#define CLK_GPIO_PCLK 47
> +#define CLK_CAN0_HCLK 48
> +#define CLK_CAN0_CLK 49
> +#define CLK_CAN1_HCLK 50
> +#define CLK_CAN1_CLK 51
> +#define CLK_CAN0_TIMER_CLK 52
> +#define CLK_CAN1_TIMER_CLK 53
> +
> +#endif /* _DT_BINDINGS_ATLANTIS_SYSCON_H */
>
> --
> 2.43.0
>
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH 3/8] clk: tenstorrent: Add Atlantis clock controller driver
2026-01-16 2:05 ` Brian Masney
@ 2026-01-16 9:00 ` Krzysztof Kozlowski
2026-01-16 20:32 ` Anirudh Srinivasan
2026-01-16 20:46 ` Anirudh Srinivasan
1 sibling, 1 reply; 29+ messages in thread
From: Krzysztof Kozlowski @ 2026-01-16 9:00 UTC (permalink / raw)
To: Brian Masney
Cc: Anirudh Srinivasan, Drew Fustini, Joel Stanley, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Michael Turquette,
Stephen Boyd, Philipp Zabel, linux-riscv, devicetree,
linux-kernel, linux-clk, joel, fustini, mpe, mpe, npiggin, agross,
agross
On Thu, Jan 15, 2026 at 09:05:35PM -0500, Brian Masney wrote:
>
> > +static void atlantis_ccu_lock(void *_lock)
> > +{
> > + spinlock_t *lock = _lock;
> > +
> > + spin_lock(lock);
> > +}
> > +
> > +static void atlantis_ccu_unlock(void *_lock)
> > +{
> > + spinlock_t *lock = _lock;
> > +
> > + spin_unlock(lock);
> > +}
>
> Are these abstractions really needed? Why not just call spin_lock/unlock
> directly?
They are actually harmful - make code less readable and introduce very
poor (lose) API accepting whatever pointer... This is exactly code which
should notbe here.
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH 4/8] dt-bindings: soc: tenstorrent: Add atlantis resets
2026-01-15 23:42 ` [PATCH 4/8] dt-bindings: soc: tenstorrent: Add atlantis resets Anirudh Srinivasan
@ 2026-01-16 9:02 ` Krzysztof Kozlowski
2026-01-16 9:03 ` Krzysztof Kozlowski
0 siblings, 1 reply; 29+ messages in thread
From: Krzysztof Kozlowski @ 2026-01-16 9:02 UTC (permalink / raw)
To: Anirudh Srinivasan
Cc: Drew Fustini, Joel Stanley, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Michael Turquette, Stephen Boyd, Philipp Zabel,
linux-riscv, devicetree, linux-kernel, linux-clk, joel, fustini,
mpe, mpe, npiggin, agross, agross
On Thu, Jan 15, 2026 at 05:42:03PM -0600, Anirudh Srinivasan wrote:
> Document resets from RCPU syscon for atlantis.
>
> Signed-off-by: Anirudh Srinivasan <asrinivasan@oss.tenstorrent.com>
> ---
> .../tenstorrent/tenstorrent,atlantis-syscon.yaml | 5 ++++
> .../clock/tenstorrent,atlantis-syscon.h | 34 ++++++++++++++++++++++
> 2 files changed, 39 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/soc/tenstorrent/tenstorrent,atlantis-syscon.yaml b/Documentation/devicetree/bindings/soc/tenstorrent/tenstorrent,atlantis-syscon.yaml
> index 3915d78dfeda..7e9c8d85ba9e 100644
> --- a/Documentation/devicetree/bindings/soc/tenstorrent/tenstorrent,atlantis-syscon.yaml
> +++ b/Documentation/devicetree/bindings/soc/tenstorrent/tenstorrent,atlantis-syscon.yaml
There is no such file in linux-next.
> @@ -31,11 +31,15 @@ properties:
> description:
> See <dt-bindings/clock/tenstorrent,atlantis-syscon.h> for valid indices.
>
> + "#reset-cells":
> + const: 1
> +
> required:
> - compatible
> - reg
> - clocks
> - "#clock-cells"
> + - "#reset-cells"
Why aren't you posting COMPLETE bindings on first posting? This is now
ABI break for no good reasons - you knew your device has resets.
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH 4/8] dt-bindings: soc: tenstorrent: Add atlantis resets
2026-01-16 9:02 ` Krzysztof Kozlowski
@ 2026-01-16 9:03 ` Krzysztof Kozlowski
2026-01-16 21:25 ` Anirudh Srinivasan
0 siblings, 1 reply; 29+ messages in thread
From: Krzysztof Kozlowski @ 2026-01-16 9:03 UTC (permalink / raw)
To: Anirudh Srinivasan
Cc: Drew Fustini, Joel Stanley, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Michael Turquette, Stephen Boyd, Philipp Zabel,
linux-riscv, devicetree, linux-kernel, linux-clk, joel, fustini,
mpe, mpe, npiggin, agross, agross
On 16/01/2026 10:02, Krzysztof Kozlowski wrote:
> On Thu, Jan 15, 2026 at 05:42:03PM -0600, Anirudh Srinivasan wrote:
>> Document resets from RCPU syscon for atlantis.
>>
>> Signed-off-by: Anirudh Srinivasan <asrinivasan@oss.tenstorrent.com>
>> ---
>> .../tenstorrent/tenstorrent,atlantis-syscon.yaml | 5 ++++
>> .../clock/tenstorrent,atlantis-syscon.h | 34 ++++++++++++++++++++++
>> 2 files changed, 39 insertions(+)
>>
>> diff --git a/Documentation/devicetree/bindings/soc/tenstorrent/tenstorrent,atlantis-syscon.yaml b/Documentation/devicetree/bindings/soc/tenstorrent/tenstorrent,atlantis-syscon.yaml
>> index 3915d78dfeda..7e9c8d85ba9e 100644
>> --- a/Documentation/devicetree/bindings/soc/tenstorrent/tenstorrent,atlantis-syscon.yaml
>> +++ b/Documentation/devicetree/bindings/soc/tenstorrent/tenstorrent,atlantis-syscon.yaml
>
> There is no such file in linux-next.
Ah, because you just added it in other patch. Then obviously this must
be squashed. Why would you post an incomplete patch and fix it up
immediately?
Please read writing bindings document - it covers this case.
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH 1/8] dt-bindings: soc: tenstorrent: Add tenstorrent,atlantis-syscon
2026-01-15 23:42 ` [PATCH 1/8] dt-bindings: soc: tenstorrent: Add tenstorrent,atlantis-syscon Anirudh Srinivasan
2026-01-16 3:18 ` Rob Herring (Arm)
2026-01-16 4:03 ` Rob Herring
@ 2026-01-16 9:04 ` Krzysztof Kozlowski
2026-01-16 21:47 ` Anirudh Srinivasan
2 siblings, 1 reply; 29+ messages in thread
From: Krzysztof Kozlowski @ 2026-01-16 9:04 UTC (permalink / raw)
To: Anirudh Srinivasan
Cc: Drew Fustini, Joel Stanley, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Michael Turquette, Stephen Boyd, Philipp Zabel,
linux-riscv, devicetree, linux-kernel, linux-clk, joel, fustini,
mpe, mpe, npiggin, agross, agross
On Thu, Jan 15, 2026 at 05:42:00PM -0600, Anirudh Srinivasan wrote:
> Document bindings for Tenstorrent Atlantis syscon that manages clocks
> and resets. This syscon block is instantiated 4 times in the SoC.
> This commit documents the clocks from the RCPU syscon block.
>
> Signed-off-by: Anirudh Srinivasan <asrinivasan@oss.tenstorrent.com>
> ---
> .../tenstorrent/tenstorrent,atlantis-syscon.yaml | 58 +++++++++++++++++++
> MAINTAINERS | 2 +
> .../clock/tenstorrent,atlantis-syscon.h | 67 ++++++++++++++++++++++
> 3 files changed, 127 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/soc/tenstorrent/tenstorrent,atlantis-syscon.yaml b/Documentation/devicetree/bindings/soc/tenstorrent/tenstorrent,atlantis-syscon.yaml
> new file mode 100644
> index 000000000000..3915d78dfeda
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/soc/tenstorrent/tenstorrent,atlantis-syscon.yaml
> @@ -0,0 +1,58 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/soc/tenstorrent/tenstorrent,atlantis-syscon.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Tenstorrent Atlantis SoC System Controller
> +
> +maintainers:
> + - Anirudh Srinivasan <asrinivasan@oss.tenstorrent.com>
> +
> +description:
> + System controller found in Tenstorrent Atlantis SoC, which is capable of
> + clock and reset functions.
> +
> + RCPU syscon controls clocks and resets for low speed IO interfaces on chip
So not really a system controller, but maybe a clock controller - place
it there. Otherwise HERE you explain the rest of the functions of this.
You should post complete bindings, complete description of your
hardware.
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH 2/8] soc: tenstorrent: Add header with Atlantis syscon register offsets
2026-01-15 23:42 ` [PATCH 2/8] soc: tenstorrent: Add header with Atlantis syscon register offsets Anirudh Srinivasan
@ 2026-01-16 9:06 ` Krzysztof Kozlowski
2026-01-16 21:34 ` Anirudh Srinivasan
0 siblings, 1 reply; 29+ messages in thread
From: Krzysztof Kozlowski @ 2026-01-16 9:06 UTC (permalink / raw)
To: Anirudh Srinivasan
Cc: Drew Fustini, Joel Stanley, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Michael Turquette, Stephen Boyd, Philipp Zabel,
linux-riscv, devicetree, linux-kernel, linux-clk, joel, fustini,
mpe, mpe, npiggin, agross, agross
On Thu, Jan 15, 2026 at 05:42:01PM -0600, Anirudh Srinivasan wrote:
> Document register offsets used for controlling clocks in Atlantis
>
> Signed-off-by: Anirudh Srinivasan <asrinivasan@oss.tenstorrent.com>
> ---
> MAINTAINERS | 1 +
> include/soc/tenstorrent/atlantis-syscon.h | 38 +++++++++++++++++++++++++++++++
> 2 files changed, 39 insertions(+)
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 19a98b1fa456..4a2017d647b0 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -22538,6 +22538,7 @@ F: Documentation/devicetree/bindings/riscv/tenstorrent.yaml
> F: Documentation/devicetree/bindings/soc/tenstorrent/tenstorrent,atlantis-syscon.yaml
> F: arch/riscv/boot/dts/tenstorrent/
> F: include/dt-bindings/clock/tenstorrent,atlantis-syscon.h
> +F: include/soc/tenstorrent/
>
> RISC-V THEAD SoC SUPPORT
> M: Drew Fustini <fustini@kernel.org>
> diff --git a/include/soc/tenstorrent/atlantis-syscon.h b/include/soc/tenstorrent/atlantis-syscon.h
> new file mode 100644
> index 000000000000..b15dabfb42b5
> --- /dev/null
> +++ b/include/soc/tenstorrent/atlantis-syscon.h
There is no user of this. Split your work in logical patches. Adding
unused header is not a meaningful logical split because it is unused.
> @@ -0,0 +1,38 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +/*
> + * Copyright (c) 2026 Tenstorrent
> + */
> +#ifndef __SOC_ATLANTIS_SYSCON_H__
> +#define __SOC_ATLANTIS_SYSCON_H__
> +
> +#include <linux/bits.h>
> +#include <linux/types.h>
> +
> +/* RCPU Clock Register Offsets */
> +#define RCPU_PLL_CFG_REG 0x0000
> +#define RCPU_NOCC_PLL_CFG_REG 0x0004
> +#define RCPU_NOCC_CLK_CFG_REG 0x0008
> +#define RCPU_DIV_CFG_REG 0x000C
> +#define RCPU_BLK_CG_REG 0x0014
> +#define LSIO_BLK_CG_REG 0x0018
> +#define PLL_RCPU_EN_REG 0x11c
> +#define PLL_NOCC_EN_REG 0x120
> +#define BUS_CG_REG 0x01FC
Completely unreadable: missing any sort of reasonable indent between
values.
Why do you need to doicument register values and provide them to all
kernel drivers?
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH 5/8] soc: tenstorrent: Add rcpu syscon reset register definitions
2026-01-15 23:42 ` [PATCH 5/8] soc: tenstorrent: Add rcpu syscon reset register definitions Anirudh Srinivasan
@ 2026-01-16 9:06 ` Krzysztof Kozlowski
0 siblings, 0 replies; 29+ messages in thread
From: Krzysztof Kozlowski @ 2026-01-16 9:06 UTC (permalink / raw)
To: Anirudh Srinivasan
Cc: Drew Fustini, Joel Stanley, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Michael Turquette, Stephen Boyd, Philipp Zabel,
linux-riscv, devicetree, linux-kernel, linux-clk, joel, fustini,
mpe, mpe, npiggin, agross, agross
On Thu, Jan 15, 2026 at 05:42:04PM -0600, Anirudh Srinivasan wrote:
> Document register offsets used for resets in Atlantis
>
> Signed-off-by: Anirudh Srinivasan <asrinivasan@oss.tenstorrent.com>
> ---
> include/soc/tenstorrent/atlantis-syscon.h | 7 +++++++
You just added this file!
This is not only meaningless split but actually hindering review.
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH 6/8] soc: tenstorrent: Add auxiliary device definitions for Atlantis
2026-01-15 23:42 ` [PATCH 6/8] soc: tenstorrent: Add auxiliary device definitions for Atlantis Anirudh Srinivasan
@ 2026-01-16 9:07 ` Krzysztof Kozlowski
0 siblings, 0 replies; 29+ messages in thread
From: Krzysztof Kozlowski @ 2026-01-16 9:07 UTC (permalink / raw)
To: Anirudh Srinivasan
Cc: Drew Fustini, Joel Stanley, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Michael Turquette, Stephen Boyd, Philipp Zabel,
linux-riscv, devicetree, linux-kernel, linux-clk, joel, fustini,
mpe, mpe, npiggin, agross, agross
On Thu, Jan 15, 2026 at 05:42:05PM -0600, Anirudh Srinivasan wrote:
> Reset shares the same registers as the Clock Controller, so it is
> implemented as an auxiliary device of the Clock Controller.
>
> This commit adds the auxiliary device definitions needed for this.
>
> Signed-off-by: Anirudh Srinivasan <asrinivasan@oss.tenstorrent.com>
> ---
> include/soc/tenstorrent/atlantis-syscon.h | 8 ++++++++
> 1 file changed, 8 insertions(+)
>
> diff --git a/include/soc/tenstorrent/atlantis-syscon.h b/include/soc/tenstorrent/atlantis-syscon.h
> index f1dc6ad33c6d..972a9b7da596 100644
> --- a/include/soc/tenstorrent/atlantis-syscon.h
> +++ b/include/soc/tenstorrent/atlantis-syscon.h
> @@ -8,6 +8,14 @@
> #include <linux/bits.h>
> #include <linux/types.h>
>
> +struct atlantis_ccu_adev {
> + struct auxiliary_device adev;
> + struct regmap *regmap;
> +};
Completely pointless. You do not have any user of this.
Adding a few unused lines is not a logical change to the kernel. Why not
adding it member by member like one patch for empty struct, then second
patch for struct with adev, then third patch adding regmap?
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH 8/8] clk: tenstorrent: Add reset controller to Atlantis clock controller probe
2026-01-15 23:42 ` [PATCH 8/8] clk: tenstorrent: Add reset controller to Atlantis clock controller probe Anirudh Srinivasan
@ 2026-01-16 9:08 ` Krzysztof Kozlowski
2026-01-16 21:30 ` Anirudh Srinivasan
0 siblings, 1 reply; 29+ messages in thread
From: Krzysztof Kozlowski @ 2026-01-16 9:08 UTC (permalink / raw)
To: Anirudh Srinivasan
Cc: Drew Fustini, Joel Stanley, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Michael Turquette, Stephen Boyd, Philipp Zabel,
linux-riscv, devicetree, linux-kernel, linux-clk, joel, fustini,
mpe, mpe, npiggin, agross, agross
On Thu, Jan 15, 2026 at 05:42:07PM -0600, Anirudh Srinivasan wrote:
> Create a reset auxiliary device during probe of clock controller
>
> Signed-off-by: Anirudh Srinivasan <asrinivasan@oss.tenstorrent.com>
> ---
> drivers/clk/tenstorrent/atlantis-ccu.c | 59 ++++++++++++++++++++++++++++++++++
> 1 file changed, 59 insertions(+)
>
> diff --git a/drivers/clk/tenstorrent/atlantis-ccu.c b/drivers/clk/tenstorrent/atlantis-ccu.c
> index f3a2ea49a82e..e4f56018907f 100644
> --- a/drivers/clk/tenstorrent/atlantis-ccu.c
> +++ b/drivers/clk/tenstorrent/atlantis-ccu.c
> @@ -491,6 +491,7 @@ struct atlantis_ccu {
> struct atlantis_ccu_data {
> struct clk_hw **hws;
> size_t num;
> + const char *reset_name;
You just added this file! Why are you adding incomplete or even buggy
code which immediately you fix?
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH 3/8] clk: tenstorrent: Add Atlantis clock controller driver
2026-01-15 23:42 ` [PATCH 3/8] clk: tenstorrent: Add Atlantis clock controller driver Anirudh Srinivasan
2026-01-16 2:05 ` Brian Masney
@ 2026-01-16 11:56 ` kernel test robot
1 sibling, 0 replies; 29+ messages in thread
From: kernel test robot @ 2026-01-16 11:56 UTC (permalink / raw)
To: Anirudh Srinivasan, Drew Fustini, Joel Stanley, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Michael Turquette,
Stephen Boyd, Philipp Zabel
Cc: oe-kbuild-all, linux-riscv, devicetree, linux-kernel, linux-clk,
joel, fustini, mpe, mpe, npiggin, agross, agross
Hi Anirudh,
kernel test robot noticed the following build errors:
[auto build test ERROR on 9448598b22c50c8a5bb77a9103e2d49f134c9578]
url: https://github.com/intel-lab-lkp/linux/commits/Anirudh-Srinivasan/dt-bindings-soc-tenstorrent-Add-tenstorrent-atlantis-syscon/20260116-074618
base: 9448598b22c50c8a5bb77a9103e2d49f134c9578
patch link: https://lore.kernel.org/r/20260115-atlantis-clocks-v1-3-7356e671f28b%40oss.tenstorrent.com
patch subject: [PATCH 3/8] clk: tenstorrent: Add Atlantis clock controller driver
config: s390-randconfig-r132-20260116 (https://download.01.org/0day-ci/archive/20260116/202601161951.u4TyUnmn-lkp@intel.com/config)
compiler: s390-linux-gcc (GCC) 10.5.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260116/202601161951.u4TyUnmn-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/202601161951.u4TyUnmn-lkp@intel.com/
All errors (new ones prefixed by >>):
drivers/clk/tenstorrent/atlantis-ccu.c: In function 'atlantis_ccu_clocks_register':
>> drivers/clk/tenstorrent/atlantis-ccu.c:744:4: error: a label can only be part of a statement and a declaration is not a statement
744 | struct atlantis_clk_mux *mux =
| ^~~~~~
drivers/clk/tenstorrent/atlantis-ccu.c:783:4: error: a label can only be part of a statement and a declaration is not a statement
783 | struct atlantis_clk_divider *div =
| ^~~~~~
drivers/clk/tenstorrent/atlantis-ccu.c:801:4: error: a label can only be part of a statement and a declaration is not a statement
801 | struct atlantis_clk_gate *gate =
| ^~~~~~
drivers/clk/tenstorrent/atlantis-ccu.c:818:4: error: a label can only be part of a statement and a declaration is not a statement
818 | struct atlantis_clk_fixed_factor *factor =
| ^~~~~~
drivers/clk/tenstorrent/atlantis-ccu.c:840:4: error: a label can only be part of a statement and a declaration is not a statement
840 | struct atlantis_clk_gate_shared *gate_shared =
| ^~~~~~
vim +744 drivers/clk/tenstorrent/atlantis-ccu.c
710
711 static int atlantis_ccu_clocks_register(struct device *dev,
712 struct atlantis_ccu *ccu,
713 const struct atlantis_ccu_data *data)
714 {
715 struct regmap *regmap = ccu->regmap;
716 struct clk_hw_onecell_data *clk_data;
717 int i, ret;
718 size_t num_clks = data->num;
719
720 clk_data = devm_kzalloc(dev, struct_size(clk_data, hws, data->num),
721 GFP_KERNEL);
722 if (!clk_data)
723 return -ENOMEM;
724
725 ccu->clk_data = clk_data;
726
727 for (i = 0; i < data->num; i++) {
728 struct clk_hw *hw = data->hws[i];
729 const char *name = hw->init->name;
730 struct atlantis_clk_common *common =
731 hw_to_atlantis_clk_common(hw);
732 common->regmap = regmap;
733
734 /* Fixup missing handle to parent for gates/muxes/dividers */
735 if (hw->init->parent_hws && hw->init->num_parents == 1) {
736 const struct atlantis_clk_common *parent =
737 hw_to_atlantis_clk_common(
738 hw->init->parent_hws[0]);
739 hw->init->parent_hws[0] = clk_data->hws[parent->clkid];
740 }
741
742 switch (common->clk_type) {
743 case ATLANTIS_CLK_MUX:
> 744 struct atlantis_clk_mux *mux =
745 hw_to_atlantis_clk_mux(hw);
746
747 hw = devm_clk_hw_register_mux_parent_data_table(
748 ccu->dev, name, hw->init->parent_data,
749 hw->init->num_parents, hw->init->flags,
750 ccu->base + mux->config.reg_offset,
751 mux->config.shift, mux->config.width, 0, NULL,
752 &lock);
753
754 if (IS_ERR(hw)) {
755 dev_err(dev, "Cannot register clock %d - %s\n",
756 i, name);
757 return ret;
758 }
759
760 if (data == &atlantis_ccu_rcpu_data) {
761 switch (common->clkid) {
762 case CLK_RCPU_ROOT:
763 ret = clk_hw_set_parent(
764 hw,
765 clk_data->hws[CLK_RCPU_PLL]);
766 if (ret)
767 dev_err(ccu->dev,
768 "Failed to set RCPU ROOT MUX parent: %d\n",
769 ret);
770 break;
771 case CLK_NOCC_CLK:
772 ret = clk_hw_set_parent(
773 hw, clk_data->hws[CLK_NOC_PLL]);
774 if (ret)
775 dev_err(ccu->dev,
776 "Failed to set NOCC Mux parent: %d\n",
777 ret);
778 break;
779 }
780 }
781 break;
782 case ATLANTIS_CLK_DIVIDER:
783 struct atlantis_clk_divider *div =
784 hw_to_atlantis_clk_divider(hw);
785
786 hw = devm_clk_hw_register_divider_parent_hw(
787 ccu->dev, name, common->hw.init->parent_hws[0],
788 div->common.hw.init->flags,
789 ccu->base + div->config.reg_offset,
790 div->config.shift, div->config.width,
791 div->config.flags, &lock);
792
793 if (IS_ERR(hw)) {
794 dev_err(dev, "Cannot register clock %d - %s\n",
795 i, name);
796 return ret;
797 }
798
799 break;
800 case ATLANTIS_CLK_GATE:
801 struct atlantis_clk_gate *gate =
802 hw_to_atlantis_clk_gate(hw);
803
804 hw = devm_clk_hw_register_gate_parent_hw(
805 ccu->dev, name, common->hw.init->parent_hws[0],
806 hw->init->flags,
807 ccu->base + gate->config.reg_offset,
808 ffs(gate->config.enable) - 1, 0, &lock);
809
810 if (IS_ERR(hw)) {
811 dev_err(dev, "Cannot register clock %d - %s\n",
812 i, name);
813 return ret;
814 }
815
816 break;
817 case ATLANTIS_CLK_FIXED_FACTOR:
818 struct atlantis_clk_fixed_factor *factor =
819 hw_to_atlantis_clk_fixed_factor(hw);
820
821 if (hw->init->parent_data) {
822 hw = devm_clk_hw_register_fixed_factor_index(
823 dev, name,
824 hw->init->parent_data[0].index,
825 hw->init->flags, factor->config.mult,
826 factor->config.div);
827 } else {
828 hw = devm_clk_hw_register_fixed_factor_parent_hw(
829 dev, name, hw->init->parent_hws[0],
830 hw->init->flags, factor->config.mult,
831 factor->config.div);
832 }
833 if (IS_ERR(hw)) {
834 dev_err(dev, "Cannot register clock %d - %s\n",
835 i, name);
836 return ret;
837 }
838 break;
839 case ATLANTIS_CLK_GATE_SHARED:
840 struct atlantis_clk_gate_shared *gate_shared =
841 hw_to_atlantis_clk_gate_shared(hw);
842 gate_shared->config.refcount_lock = &refcount_lock;
843
844 ret = devm_clk_hw_register(dev, hw);
845
846 if (ret) {
847 dev_err(dev, "Cannot register clock %d - %s\n",
848 i, name);
849 return ret;
850 }
851
852 break;
853 default:
854
855 ret = devm_clk_hw_register(dev, hw);
856
857 if (ret) {
858 dev_err(dev, "Cannot register clock %d - %s\n",
859 i, name);
860 return ret;
861 }
862
863 break;
864 }
865 clk_data->hws[common->clkid] = hw;
866 }
867
868 clk_data->num = num_clks;
869
870 ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, clk_data);
871 if (ret)
872 dev_err(dev, "failed to add clock hardware provider (%d)\n",
873 ret);
874
875 return ret;
876 }
877
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH 3/8] clk: tenstorrent: Add Atlantis clock controller driver
2026-01-16 9:00 ` Krzysztof Kozlowski
@ 2026-01-16 20:32 ` Anirudh Srinivasan
0 siblings, 0 replies; 29+ messages in thread
From: Anirudh Srinivasan @ 2026-01-16 20:32 UTC (permalink / raw)
To: Krzysztof Kozlowski, Brian Masney
Cc: Drew Fustini, Joel Stanley, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Michael Turquette, Stephen Boyd, Philipp Zabel,
linux-riscv, devicetree, linux-kernel, linux-clk, joel, fustini,
mpe, mpe, npiggin, agross, agross
Hello Brian and Krzysztof,
On Fri, Jan 16, 2026 at 3:00 AM Krzysztof Kozlowski <krzk@kernel.org> wrote:
>
> On Thu, Jan 15, 2026 at 09:05:35PM -0500, Brian Masney wrote:
> >
> > Are these abstractions really needed? Why not just call spin_lock/unlock
> > directly?
>
> They are actually harmful - make code less readable and introduce very
> poor (lose) API accepting whatever pointer... This is exactly code which
> should notbe here.
Some of the clocks use a regmap for register accesses, while the
others use the devm_clk_hw_register_xxx functions which require a
pointer to the control register and a lock. My above implementation
sets the regmap's lock and ensures that the same lock is used across
both types of clocks.
I tried setting the regmap_lock/unlock functions to
spin_lock/spin_unlock like you suggested Brian, but that throws a
compile time error
error: initialization of 'void (*)(void *)' from incompatible pointer
type 'void (*)(spinlock_t *)' {aka 'void (*)(struct spinlock *)'}
[-Wincompatible-pointer-types]
This pattern is used by other drivers when they want to override the
regmap's lock [1] [2] [3]. Should I be doing this in a different
manner? Please let me know.
[1] https://elixir.bootlin.com/linux/v6.18.5/source/drivers/soc/sunxi/sunxi_sram.c#L338
[2] https://elixir.bootlin.com/linux/v6.18.5/source/drivers/mfd/atc260x-core.c#L47
[3] https://elixir.bootlin.com/linux/v6.18.5/source/drivers/net/ethernet/microchip/encx24j600-regmap.c#L46
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH 3/8] clk: tenstorrent: Add Atlantis clock controller driver
2026-01-16 2:05 ` Brian Masney
2026-01-16 9:00 ` Krzysztof Kozlowski
@ 2026-01-16 20:46 ` Anirudh Srinivasan
1 sibling, 0 replies; 29+ messages in thread
From: Anirudh Srinivasan @ 2026-01-16 20:46 UTC (permalink / raw)
To: Brian Masney
Cc: Drew Fustini, Joel Stanley, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Michael Turquette, Stephen Boyd, Philipp Zabel,
linux-riscv, devicetree, linux-kernel, linux-clk, joel, fustini,
mpe, mpe, npiggin, agross, agross
Hi Brian,
On Thu, Jan 15, 2026 at 8:05 PM Brian Masney <bmasney@redhat.com> wrote:
>
> Hi Anirudh,
>
> Thanks for the patch!
>
> Please sort the headers. clk-provider.h is listed twice. Remove the
> unnecessary newlines.
>
Understood, will fix this, the newlines and add the return PTR_ERR(hw)
statements.
>
> Should the parent be defined in device tree instead of statically in the
> driver? devm_of_clk_add_hw_provider() is called below, and it calls
> of_clk_set_defaults(), which will allow the use of the
> assigned-clock-parents and assigned-clocks properties.
Yes, you are right. I will switch it over to this.
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH 4/8] dt-bindings: soc: tenstorrent: Add atlantis resets
2026-01-16 9:03 ` Krzysztof Kozlowski
@ 2026-01-16 21:25 ` Anirudh Srinivasan
2026-01-17 10:50 ` Krzysztof Kozlowski
0 siblings, 1 reply; 29+ messages in thread
From: Anirudh Srinivasan @ 2026-01-16 21:25 UTC (permalink / raw)
To: Krzysztof Kozlowski
Cc: Drew Fustini, Joel Stanley, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Michael Turquette, Stephen Boyd, Philipp Zabel,
linux-riscv, devicetree, linux-kernel, linux-clk, joel, fustini,
mpe, mpe, npiggin, agross, agross
Hi Krzysztof,
On Fri, Jan 16, 2026 at 3:03 AM Krzysztof Kozlowski <krzk@kernel.org> wrote:
>
> On 16/01/2026 10:02, Krzysztof Kozlowski wrote:
> Ah, because you just added it in other patch. Then obviously this must
> be squashed. Why would you post an incomplete patch and fix it up
> immediately?
>
> Please read writing bindings document - it covers this case.
> Why aren't you posting COMPLETE bindings on first posting? This is now
> ABI break for no good reasons - you knew your device has resets.
I will squash down the commits so that there is just one commit with bindings.
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH 8/8] clk: tenstorrent: Add reset controller to Atlantis clock controller probe
2026-01-16 9:08 ` Krzysztof Kozlowski
@ 2026-01-16 21:30 ` Anirudh Srinivasan
0 siblings, 0 replies; 29+ messages in thread
From: Anirudh Srinivasan @ 2026-01-16 21:30 UTC (permalink / raw)
To: Krzysztof Kozlowski
Cc: Drew Fustini, Joel Stanley, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Michael Turquette, Stephen Boyd, Philipp Zabel,
linux-riscv, devicetree, linux-kernel, linux-clk, joel, fustini,
mpe, mpe, npiggin, agross, agross
Hi Krzysztof,
On Fri, Jan 16, 2026 at 3:08 AM Krzysztof Kozlowski <krzk@kernel.org> wrote:
>
> Completely pointless. You do not have any user of this.
>
> Adding a few unused lines is not a logical change to the kernel. Why not
> adding it member by member like one patch for empty struct, then second
> patch for struct with adev, then third patch adding regmap?
>
>
> You just added this file! Why are you adding incomplete or even buggy
> code which immediately you fix?
Regarding your comments from patches 5, 6 and 8, I will clean up the
patches that add the auxdev and reset controller so that there are no
more unnecessary commits.
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH 2/8] soc: tenstorrent: Add header with Atlantis syscon register offsets
2026-01-16 9:06 ` Krzysztof Kozlowski
@ 2026-01-16 21:34 ` Anirudh Srinivasan
0 siblings, 0 replies; 29+ messages in thread
From: Anirudh Srinivasan @ 2026-01-16 21:34 UTC (permalink / raw)
To: Krzysztof Kozlowski
Cc: Drew Fustini, Joel Stanley, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Michael Turquette, Stephen Boyd, Philipp Zabel,
linux-riscv, devicetree, linux-kernel, linux-clk, joel, fustini,
mpe, mpe, npiggin, agross, agross
Hi Krzysztof,
On Fri, Jan 16, 2026 at 3:06 AM Krzysztof Kozlowski <krzk@kernel.org> wrote:
>
>
> There is no user of this. Split your work in logical patches. Adding
> unused header is not a meaningful logical split because it is unused.
Understood
>
> Completely unreadable: missing any sort of reasonable indent between
> values.
I had formatted these with clang-format, but it doesn't look good. I
can make it a bit better.
>
> Why do you need to doicument register values and provide them to all
> kernel drivers?
(Including the subsequent commits), these registers documented in this
file are shared across the clock and reset controller, so they're
added here (soc/tenstorrent).
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH 1/8] dt-bindings: soc: tenstorrent: Add tenstorrent,atlantis-syscon
2026-01-16 9:04 ` Krzysztof Kozlowski
@ 2026-01-16 21:47 ` Anirudh Srinivasan
0 siblings, 0 replies; 29+ messages in thread
From: Anirudh Srinivasan @ 2026-01-16 21:47 UTC (permalink / raw)
To: Krzysztof Kozlowski
Cc: Drew Fustini, Rob Herring, Joel Stanley, Krzysztof Kozlowski,
Conor Dooley, Michael Turquette, Stephen Boyd, Philipp Zabel,
linux-riscv, devicetree, linux-kernel, linux-clk, joel, fustini,
mpe, mpe, npiggin, agross, agross
Hi Krzysztof,
On Fri, Jan 16, 2026 at 3:04 AM Krzysztof Kozlowski <krzk@kernel.org> wrote:
> So not really a system controller, but maybe a clock controller - place
> it there. Otherwise HERE you explain the rest of the functions of this.
>
> You should post complete bindings, complete description of your
> hardware.
Understood. This block does both clock and reset. I will add the
complete description of this block to the bindings in a single commit.
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH 1/8] dt-bindings: soc: tenstorrent: Add tenstorrent,atlantis-syscon
2026-01-16 4:03 ` Rob Herring
@ 2026-01-16 21:48 ` Anirudh Srinivasan
0 siblings, 0 replies; 29+ messages in thread
From: Anirudh Srinivasan @ 2026-01-16 21:48 UTC (permalink / raw)
To: Rob Herring
Cc: Drew Fustini, Joel Stanley, Krzysztof Kozlowski, Conor Dooley,
Michael Turquette, Stephen Boyd, Philipp Zabel, linux-riscv,
devicetree, linux-kernel, linux-clk, joel, fustini, mpe, mpe,
npiggin, agross, agross
Hi Rob,
On Thu, Jan 15, 2026 at 10:03 PM Rob Herring <robh@kernel.org> wrote:
Seems like there was a small typo in the example (sycon instead of
syscon) and your bot caught that. I'll fix that.
> > .../tenstorrent/tenstorrent,atlantis-syscon.yaml | 58 +++++++++++++++++++
>
> Filename should match compatible.
>
> If "RCPU" is what the h/w block is called and sufficient to identify it,
> then drop the "syscon-" part.
This hw block has control registers for clock and reset for the SoC.
This block is instantiated multiple times, with each instantiation
controlling clocks/resets from a different subsystem. I originally
planned to add these later on, so you'd have 4 different compatibles
like "tenstorrent,atlantis-syscon-{rcpu,hsio,pcie,mm}".
Instead, I guess I should add all 4 in right now (the clock driver
patches don't support all currently).
Is the current file name okay for that
(tenstorrent,atlantis-syscon.h)? I based this off the spacemit-k1
clock/reset controller [1], so it would look very similar to that.
> > + "#clock-cells":
> > + const: 1
> > + description:
> > + See <dt-bindings/clock/tenstorrent,atlantis-syscon.h> for valid indices.
>
> Be consistent with the compatible string for the file name.
I will squash down the dt-bindings patches in this series into one
that adds both the clock-cells and reset-cells to this entry. For the
clock/reset indices, should I just use a single file (say
dt-bindings/soc/tenstorrent,atlantis-syscon.h) or separate files for
clock and reset?
> > + clocks {
> > + osc_24m: clock-24m {
> > + compatible = "fixed-clock";
> > + clock-frequency = <24000000>;
> > + clock-output-names = "osc_24m";
> > + #clock-cells = <0>;
> > + };
> > + };
>
> Drop this node. Not relevant to the example.
Understood
[1] https://elixir.bootlin.com/linux/v6.18.2/source/Documentation/devicetree/bindings/soc/spacemit/spacemit,k1-syscon.yaml
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH 4/8] dt-bindings: soc: tenstorrent: Add atlantis resets
2026-01-16 21:25 ` Anirudh Srinivasan
@ 2026-01-17 10:50 ` Krzysztof Kozlowski
0 siblings, 0 replies; 29+ messages in thread
From: Krzysztof Kozlowski @ 2026-01-17 10:50 UTC (permalink / raw)
To: Anirudh Srinivasan
Cc: Drew Fustini, Joel Stanley, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Michael Turquette, Stephen Boyd, Philipp Zabel,
linux-riscv, devicetree, linux-kernel, linux-clk, joel, fustini,
mpe, mpe, npiggin, agross, agross
On 16/01/2026 22:25, Anirudh Srinivasan wrote:
> Hi Krzysztof,
>
> On Fri, Jan 16, 2026 at 3:03 AM Krzysztof Kozlowski <krzk@kernel.org> wrote:
>>
>> On 16/01/2026 10:02, Krzysztof Kozlowski wrote:
>> Ah, because you just added it in other patch. Then obviously this must
>> be squashed. Why would you post an incomplete patch and fix it up
>> immediately?
>>
>> Please read writing bindings document - it covers this case.
>> Why aren't you posting COMPLETE bindings on first posting? This is now
>> ABI break for no good reasons - you knew your device has resets.
>
> I will squash down the commits so that there is just one commit with bindings.
I completely miss what is the context here. What did I reply to? With 50
replies per day I am not tracking what is what here. Provide reasonable
amount of context.
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 29+ messages in thread
end of thread, other threads:[~2026-01-17 10:50 UTC | newest]
Thread overview: 29+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-01-15 23:41 [PATCH 0/8] Add Tenstorrent Atlantis Clock/Reset Controller Anirudh Srinivasan
2026-01-15 23:42 ` [PATCH 1/8] dt-bindings: soc: tenstorrent: Add tenstorrent,atlantis-syscon Anirudh Srinivasan
2026-01-16 3:18 ` Rob Herring (Arm)
2026-01-16 4:03 ` Rob Herring
2026-01-16 21:48 ` Anirudh Srinivasan
2026-01-16 9:04 ` Krzysztof Kozlowski
2026-01-16 21:47 ` Anirudh Srinivasan
2026-01-15 23:42 ` [PATCH 2/8] soc: tenstorrent: Add header with Atlantis syscon register offsets Anirudh Srinivasan
2026-01-16 9:06 ` Krzysztof Kozlowski
2026-01-16 21:34 ` Anirudh Srinivasan
2026-01-15 23:42 ` [PATCH 3/8] clk: tenstorrent: Add Atlantis clock controller driver Anirudh Srinivasan
2026-01-16 2:05 ` Brian Masney
2026-01-16 9:00 ` Krzysztof Kozlowski
2026-01-16 20:32 ` Anirudh Srinivasan
2026-01-16 20:46 ` Anirudh Srinivasan
2026-01-16 11:56 ` kernel test robot
2026-01-15 23:42 ` [PATCH 4/8] dt-bindings: soc: tenstorrent: Add atlantis resets Anirudh Srinivasan
2026-01-16 9:02 ` Krzysztof Kozlowski
2026-01-16 9:03 ` Krzysztof Kozlowski
2026-01-16 21:25 ` Anirudh Srinivasan
2026-01-17 10:50 ` Krzysztof Kozlowski
2026-01-15 23:42 ` [PATCH 5/8] soc: tenstorrent: Add rcpu syscon reset register definitions Anirudh Srinivasan
2026-01-16 9:06 ` Krzysztof Kozlowski
2026-01-15 23:42 ` [PATCH 6/8] soc: tenstorrent: Add auxiliary device definitions for Atlantis Anirudh Srinivasan
2026-01-16 9:07 ` Krzysztof Kozlowski
2026-01-15 23:42 ` [PATCH 7/8] reset: tenstorrent: Add reset controller " Anirudh Srinivasan
2026-01-15 23:42 ` [PATCH 8/8] clk: tenstorrent: Add reset controller to Atlantis clock controller probe Anirudh Srinivasan
2026-01-16 9:08 ` Krzysztof Kozlowski
2026-01-16 21:30 ` Anirudh Srinivasan
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox