Devicetree
 help / color / mirror / Atom feed
* [PATCH v6 06/10] clk: realtek: Add support for mux clock
From: Yu-Chun Lin @ 2026-04-02  7:39 UTC (permalink / raw)
  To: mturquette, sboyd, robh, krzk+dt, conor+dt, p.zabel, cylee12,
	afaerber, jyanchou
  Cc: devicetree, linux-clk, linux-kernel, linux-arm-kernel,
	linux-realtek-soc, james.tai, cy.huang, stanley_chang,
	eleanor.lin
In-Reply-To: <20260402073957.2742459-1-eleanor.lin@realtek.com>

From: Cheng-Yu Lee <cylee12@realtek.com>

Add a simple regmap-based clk_ops implementation for Realtek mux clocks.

The implementation supports parent selection and rate determination through
regmap-backed register access.

Signed-off-by: Cheng-Yu Lee <cylee12@realtek.com>
Co-developed-by: Yu-Chun Lin <eleanor.lin@realtek.com>
Signed-off-by: Yu-Chun Lin <eleanor.lin@realtek.com>
---
Changes in v6:
- Add the headers used in c file to follow the "Include What You Use" principle.
---
 drivers/clk/realtek/Makefile         |  1 +
 drivers/clk/realtek/clk-regmap-mux.c | 48 ++++++++++++++++++++++++++++
 drivers/clk/realtek/clk-regmap-mux.h | 43 +++++++++++++++++++++++++
 3 files changed, 92 insertions(+)
 create mode 100644 drivers/clk/realtek/clk-regmap-mux.c
 create mode 100644 drivers/clk/realtek/clk-regmap-mux.h

diff --git a/drivers/clk/realtek/Makefile b/drivers/clk/realtek/Makefile
index 74375f8127ac..f90dc57fcfdb 100644
--- a/drivers/clk/realtek/Makefile
+++ b/drivers/clk/realtek/Makefile
@@ -5,4 +5,5 @@ clk-rtk-y += common.o
 
 clk-rtk-y += clk-pll.o
 clk-rtk-y += clk-regmap-gate.o
+clk-rtk-y += clk-regmap-mux.o
 clk-rtk-y += freq_table.o
diff --git a/drivers/clk/realtek/clk-regmap-mux.c b/drivers/clk/realtek/clk-regmap-mux.c
new file mode 100644
index 000000000000..068b056d61f0
--- /dev/null
+++ b/drivers/clk/realtek/clk-regmap-mux.c
@@ -0,0 +1,48 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2017 Realtek Semiconductor Corporation
+ * Author: Cheng-Yu Lee <cylee12@realtek.com>
+ */
+
+#include <linux/regmap.h>
+#include <linux/clk-provider.h>
+#include "clk-regmap-mux.h"
+
+static u8 clk_regmap_mux_get_parent(struct clk_hw *hw)
+{
+	struct clk_regmap_mux *clkm = to_clk_regmap_mux(hw);
+	int num_parents = clk_hw_get_num_parents(hw);
+	u32 val;
+	int ret;
+
+	ret = regmap_read(clkm->clkr.regmap, clkm->mux_ofs, &val);
+	if (ret)
+		return 0;
+
+	val = val >> clkm->shift & clkm->mask;
+
+	if (val >= num_parents)
+		return 0;
+
+	return val;
+}
+
+static int clk_regmap_mux_set_parent(struct clk_hw *hw, u8 index)
+{
+	struct clk_regmap_mux *clkm = to_clk_regmap_mux(hw);
+
+	return regmap_update_bits(clkm->clkr.regmap, clkm->mux_ofs,
+				  clkm->mask << clkm->shift, index << clkm->shift);
+}
+
+const struct clk_ops rtk_clk_regmap_mux_ops = {
+	.set_parent = clk_regmap_mux_set_parent,
+	.get_parent = clk_regmap_mux_get_parent,
+	.determine_rate = __clk_mux_determine_rate,
+};
+EXPORT_SYMBOL_NS_GPL(rtk_clk_regmap_mux_ops, "REALTEK_CLK");
+
+const struct clk_ops rtk_clk_regmap_mux_ro_ops = {
+	.get_parent = clk_regmap_mux_get_parent,
+};
+EXPORT_SYMBOL_NS_GPL(rtk_clk_regmap_mux_ro_ops, "REALTEK_CLK");
diff --git a/drivers/clk/realtek/clk-regmap-mux.h b/drivers/clk/realtek/clk-regmap-mux.h
new file mode 100644
index 000000000000..cf7ab6a0604c
--- /dev/null
+++ b/drivers/clk/realtek/clk-regmap-mux.h
@@ -0,0 +1,43 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2017 Realtek Semiconductor Corporation
+ * Author: Cheng-Yu Lee <cylee12@realtek.com>
+ */
+
+#ifndef __CLK_REALTEK_CLK_REGMAP_MUX_H
+#define __CLK_REALTEK_CLK_REGMAP_MUX_H
+
+#include "common.h"
+
+struct clk_regmap_mux {
+	struct clk_regmap clkr;
+	int mux_ofs;
+	unsigned int mask;
+	unsigned int shift;
+};
+
+#define __clk_regmap_mux_hw(_p) __clk_regmap_hw(&(_p)->clkr)
+
+#define __CLK_REGMAP_MUX(_name, _parents, _ops, _flags, _ofs, _sft, _mask)   \
+	struct clk_regmap_mux _name = {                                      \
+		.clkr.hw.init =                                              \
+			CLK_HW_INIT_PARENTS(#_name, _parents, _ops, _flags), \
+		.mux_ofs = _ofs,                                             \
+		.shift = _sft,                                               \
+		.mask = _mask,                                               \
+	}
+
+#define CLK_REGMAP_MUX(_name, _parents, _flags, _ofs, _sft, _mask)           \
+	__CLK_REGMAP_MUX(_name, _parents, &rtk_clk_regmap_mux_ops, _flags, _ofs, \
+			 _sft, _mask)
+
+static inline struct clk_regmap_mux *to_clk_regmap_mux(struct clk_hw *hw)
+{
+	struct clk_regmap *clkr = to_clk_regmap(hw);
+
+	return container_of(clkr, struct clk_regmap_mux, clkr);
+}
+
+extern const struct clk_ops rtk_clk_regmap_mux_ops;
+
+#endif /* __CLK_REALTEK_CLK_REGMAP_MUX_H */
-- 
2.34.1


^ permalink raw reply related

* [PATCH v6 05/10] clk: realtek: Add support for gate clock
From: Yu-Chun Lin @ 2026-04-02  7:39 UTC (permalink / raw)
  To: mturquette, sboyd, robh, krzk+dt, conor+dt, p.zabel, cylee12,
	afaerber, jyanchou
  Cc: devicetree, linux-clk, linux-kernel, linux-arm-kernel,
	linux-realtek-soc, james.tai, cy.huang, stanley_chang,
	eleanor.lin
In-Reply-To: <20260402073957.2742459-1-eleanor.lin@realtek.com>

From: Cheng-Yu Lee <cylee12@realtek.com>

Introduce clk_regmap_gate_ops supporting enable, disable, is_enabled, and
disable_unused for standard regmap gate clocks.

Add clk_regmap_gate_ro_ops as a read-only variant exposing only is_enabled.

Signed-off-by: Cheng-Yu Lee <cylee12@realtek.com>
Co-developed-by: Yu-Chun Lin <eleanor.lin@realtek.com>
Signed-off-by: Yu-Chun Lin <eleanor.lin@realtek.com>
---
Changes in v6:
- Add the headers used in c file to follow the "Include What You Use" principle.
---
 drivers/clk/realtek/Makefile          |  2 +
 drivers/clk/realtek/clk-regmap-gate.c | 69 +++++++++++++++++++++++++++
 drivers/clk/realtek/clk-regmap-gate.h | 65 +++++++++++++++++++++++++
 3 files changed, 136 insertions(+)
 create mode 100644 drivers/clk/realtek/clk-regmap-gate.c
 create mode 100644 drivers/clk/realtek/clk-regmap-gate.h

diff --git a/drivers/clk/realtek/Makefile b/drivers/clk/realtek/Makefile
index a89ad77993e9..74375f8127ac 100644
--- a/drivers/clk/realtek/Makefile
+++ b/drivers/clk/realtek/Makefile
@@ -2,5 +2,7 @@
 obj-$(CONFIG_RTK_CLK_COMMON) += clk-rtk.o
 
 clk-rtk-y += common.o
+
 clk-rtk-y += clk-pll.o
+clk-rtk-y += clk-regmap-gate.o
 clk-rtk-y += freq_table.o
diff --git a/drivers/clk/realtek/clk-regmap-gate.c b/drivers/clk/realtek/clk-regmap-gate.c
new file mode 100644
index 000000000000..8738d6c6f8dd
--- /dev/null
+++ b/drivers/clk/realtek/clk-regmap-gate.c
@@ -0,0 +1,69 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2017 Realtek Semiconductor Corporation
+ * Author: Cheng-Yu Lee <cylee12@realtek.com>
+ */
+
+#include <linux/regmap.h>
+#include <linux/bits.h>
+#include "clk-regmap-gate.h"
+#include <linux/clk-provider.h>
+
+static int clk_regmap_gate_enable(struct clk_hw *hw)
+{
+	struct clk_regmap_gate *clkg = to_clk_regmap_gate(hw);
+	unsigned int mask;
+	unsigned int val;
+
+	mask = BIT(clkg->bit_idx);
+	val = BIT(clkg->bit_idx);
+
+	if (clkg->write_en) {
+		mask |= BIT(clkg->bit_idx + 1);
+		val |= BIT(clkg->bit_idx + 1);
+	}
+
+	return regmap_update_bits(clkg->clkr.regmap, clkg->gate_ofs, mask, val);
+}
+
+static void clk_regmap_gate_disable(struct clk_hw *hw)
+{
+	struct clk_regmap_gate *clkg = to_clk_regmap_gate(hw);
+	unsigned int mask;
+	unsigned int val;
+
+	mask = BIT(clkg->bit_idx);
+	val = 0;
+
+	if (clkg->write_en) {
+		mask |= BIT(clkg->bit_idx + 1);
+		val |= BIT(clkg->bit_idx + 1);
+	}
+
+	regmap_update_bits(clkg->clkr.regmap, clkg->gate_ofs, mask, val);
+}
+
+static int clk_regmap_gate_is_enabled(struct clk_hw *hw)
+{
+	struct clk_regmap_gate *clkg = to_clk_regmap_gate(hw);
+	int ret;
+	u32 val;
+
+	ret = regmap_read(clkg->clkr.regmap, clkg->gate_ofs, &val);
+	if (ret < 0)
+		return ret;
+
+	return !!(val & BIT(clkg->bit_idx));
+}
+
+const struct clk_ops rtk_clk_regmap_gate_ops = {
+	.enable     = clk_regmap_gate_enable,
+	.disable    = clk_regmap_gate_disable,
+	.is_enabled = clk_regmap_gate_is_enabled,
+};
+EXPORT_SYMBOL_NS_GPL(rtk_clk_regmap_gate_ops, "REALTEK_CLK");
+
+const struct clk_ops rtk_clk_regmap_gate_ro_ops = {
+	.is_enabled = clk_regmap_gate_is_enabled,
+};
+EXPORT_SYMBOL_NS_GPL(rtk_clk_regmap_gate_ro_ops, "REALTEK_CLK");
diff --git a/drivers/clk/realtek/clk-regmap-gate.h b/drivers/clk/realtek/clk-regmap-gate.h
new file mode 100644
index 000000000000..b93357bd5a0d
--- /dev/null
+++ b/drivers/clk/realtek/clk-regmap-gate.h
@@ -0,0 +1,65 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2017 Realtek Semiconductor Corporation
+ * Author: Cheng-Yu Lee <cylee12@realtek.com>
+ */
+
+#ifndef __CLK_REALTEK_CLK_REGMAP_GATE_H
+#define __CLK_REALTEK_CLK_REGMAP_GATE_H
+
+#include "common.h"
+
+struct clk_regmap_gate {
+	struct clk_regmap clkr;
+	int gate_ofs;
+	u8 bit_idx;
+	u32 write_en : 1;
+};
+
+#define __clk_regmap_gate_hw(_p) __clk_regmap_hw(&(_p)->clkr)
+
+#define __CLK_REGMAP_GATE(_name, _parent, _ops, _flags, _ofs, _bit_idx,     \
+			  _write_en)                                        \
+	struct clk_regmap_gate _name = {                                    \
+		.clkr.hw.init = CLK_HW_INIT(#_name, _parent, _ops, _flags), \
+		.gate_ofs = _ofs,                                           \
+		.bit_idx = _bit_idx,                                        \
+		.write_en = _write_en,                                      \
+	}
+
+#define CLK_REGMAP_GATE(_name, _parent, _flags, _ofs, _bit_idx, _write_en)    \
+	__CLK_REGMAP_GATE(_name, _parent, &rtk_clk_regmap_gate_ops, _flags, _ofs, \
+			  _bit_idx, _write_en)
+
+#define CLK_REGMAP_GATE_RO(_name, _parent, _flags, _ofs, _bit_idx, _write_en) \
+	__CLK_REGMAP_GATE(_name, _parent, &rtk_clk_regmap_gate_ro_ops, _flags,    \
+			  _ofs, _bit_idx, _write_en)
+
+#define __CLK_REGMAP_GATE_NO_PARENT(_name, _ops, _flags, _ofs, _bit_idx,     \
+				    _write_en)                               \
+	struct clk_regmap_gate _name = {                                     \
+		.clkr.hw.init = CLK_HW_INIT_NO_PARENT(#_name, _ops, _flags), \
+		.gate_ofs = _ofs,                                            \
+		.bit_idx = _bit_idx,                                         \
+		.write_en = _write_en,                                       \
+	}
+
+#define CLK_REGMAP_GATE_NO_PARENT(_name, _flags, _ofs, _bit_idx, _write_en)    \
+	__CLK_REGMAP_GATE_NO_PARENT(_name, &rtk_clk_regmap_gate_ops, _flags, _ofs, \
+				    _bit_idx, _write_en)
+
+#define CLK_REGMAP_GATE_NO_PARENT_RO(_name, _flags, _ofs, _bit_idx, _write_en) \
+	__CLK_REGMAP_GATE_NO_PARENT(_name, &rtk_clk_regmap_gate_ro_ops, _flags,    \
+				    _ofs, _bit_idx, _write_en)
+
+static inline struct clk_regmap_gate *to_clk_regmap_gate(struct clk_hw *hw)
+{
+	struct clk_regmap *clkr = to_clk_regmap(hw);
+
+	return container_of(clkr, struct clk_regmap_gate, clkr);
+}
+
+extern const struct clk_ops rtk_clk_regmap_gate_ops;
+extern const struct clk_ops rtk_clk_regmap_gate_ro_ops;
+
+#endif /* __CLK_REALTEK_CLK_REGMAP_GATE_H */
-- 
2.34.1


^ permalink raw reply related

* [PATCH v6 02/10] reset: Add Realtek basic reset support
From: Yu-Chun Lin @ 2026-04-02  7:39 UTC (permalink / raw)
  To: mturquette, sboyd, robh, krzk+dt, conor+dt, p.zabel, cylee12,
	afaerber, jyanchou
  Cc: devicetree, linux-clk, linux-kernel, linux-arm-kernel,
	linux-realtek-soc, james.tai, cy.huang, stanley_chang,
	eleanor.lin
In-Reply-To: <20260402073957.2742459-1-eleanor.lin@realtek.com>

From: Cheng-Yu Lee <cylee12@realtek.com>

Define the reset operations backed by a regmap-based register interface
and prepare the reset controller to be registered through the reset
framework.

Since the reset controllers on Realtek SoCs often share the same register
space with the clock controllers, this common framework is designed to
extract the regmap and device tree node from the parent device
(e.g., an auxiliary device parent).

Signed-off-by: Cheng-Yu Lee <cylee12@realtek.com>
Co-developed-by: Yu-Chun Lin <eleanor.lin@realtek.com>
Signed-off-by: Yu-Chun Lin <eleanor.lin@realtek.com>
---
Changes in v6:
- Remove the global header include/linux/reset/realtek.h and use a local common.h
instead.
- Extract regmap and of_node directly from the parent device.
- Remove struct rtk_reset_initdata. Now, pass struct rtk_reset_data directly when
calling rtk_reset_controller_add().
---
 MAINTAINERS                    |  1 +
 drivers/reset/Kconfig          |  1 +
 drivers/reset/Makefile         |  1 +
 drivers/reset/realtek/Kconfig  |  3 ++
 drivers/reset/realtek/Makefile |  2 +
 drivers/reset/realtek/common.c | 85 ++++++++++++++++++++++++++++++++++
 drivers/reset/realtek/common.h | 29 ++++++++++++
 7 files changed, 122 insertions(+)
 create mode 100644 drivers/reset/realtek/Kconfig
 create mode 100644 drivers/reset/realtek/Makefile
 create mode 100644 drivers/reset/realtek/common.c
 create mode 100644 drivers/reset/realtek/common.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 07e73bf621b0..8f355896583b 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -22240,6 +22240,7 @@ L:	devicetree@vger.kernel.org
 L:	linux-clk@vger.kernel.org
 S:	Supported
 F:	Documentation/devicetree/bindings/clock/realtek*
+F:	drivers/reset/realtek/*
 F:	include/dt-bindings/clock/realtek*
 F:	include/dt-bindings/reset/realtek*
 
diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig
index 7ce151f6a7e4..03be1931f264 100644
--- a/drivers/reset/Kconfig
+++ b/drivers/reset/Kconfig
@@ -398,6 +398,7 @@ config RESET_ZYNQMP
 
 source "drivers/reset/amlogic/Kconfig"
 source "drivers/reset/hisilicon/Kconfig"
+source "drivers/reset/realtek/Kconfig"
 source "drivers/reset/spacemit/Kconfig"
 source "drivers/reset/starfive/Kconfig"
 source "drivers/reset/sti/Kconfig"
diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile
index fc0cc99f8514..4407d1630070 100644
--- a/drivers/reset/Makefile
+++ b/drivers/reset/Makefile
@@ -2,6 +2,7 @@
 obj-y += core.o
 obj-y += amlogic/
 obj-y += hisilicon/
+obj-y += realtek/
 obj-y += spacemit/
 obj-y += starfive/
 obj-y += sti/
diff --git a/drivers/reset/realtek/Kconfig b/drivers/reset/realtek/Kconfig
new file mode 100644
index 000000000000..99a14d355803
--- /dev/null
+++ b/drivers/reset/realtek/Kconfig
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0-only
+config RESET_RTK_COMMON
+	bool
diff --git a/drivers/reset/realtek/Makefile b/drivers/reset/realtek/Makefile
new file mode 100644
index 000000000000..b59a3f7f2453
--- /dev/null
+++ b/drivers/reset/realtek/Makefile
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0-only
+obj-$(CONFIG_RESET_RTK_COMMON) += common.o
diff --git a/drivers/reset/realtek/common.c b/drivers/reset/realtek/common.c
new file mode 100644
index 000000000000..ea7ff27117e7
--- /dev/null
+++ b/drivers/reset/realtek/common.c
@@ -0,0 +1,85 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2019 Realtek Semiconductor Corporation
+ */
+
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/regmap.h>
+#include "common.h"
+
+static inline struct rtk_reset_data *to_rtk_reset_controller(struct reset_controller_dev *r)
+{
+	return container_of(r, struct rtk_reset_data, rcdev);
+}
+
+static inline struct rtk_reset_desc *rtk_reset_get_desc(struct rtk_reset_data *data,
+							unsigned long idx)
+{
+	return &data->descs[idx];
+}
+
+static int rtk_reset_assert(struct reset_controller_dev *rcdev,
+			    unsigned long idx)
+{
+	struct rtk_reset_data *data = to_rtk_reset_controller(rcdev);
+	struct rtk_reset_desc *desc = rtk_reset_get_desc(data, idx);
+	u32 mask = desc->write_en ? (0x3 << desc->bit) : BIT(desc->bit);
+	u32 val  = desc->write_en ? (0x2 << desc->bit) : 0;
+
+	return regmap_update_bits(data->regmap, desc->ofs, mask, val);
+}
+
+static int rtk_reset_deassert(struct reset_controller_dev *rcdev,
+			      unsigned long idx)
+{
+	struct rtk_reset_data *data = to_rtk_reset_controller(rcdev);
+	struct rtk_reset_desc *desc = rtk_reset_get_desc(data, idx);
+	u32 mask = desc->write_en ? (0x3 << desc->bit) : BIT(desc->bit);
+	u32 val  = mask;
+
+	return regmap_update_bits(data->regmap, desc->ofs, mask, val);
+}
+
+static int rtk_reset_status(struct reset_controller_dev *rcdev,
+			    unsigned long idx)
+{
+	struct rtk_reset_data *data = to_rtk_reset_controller(rcdev);
+	struct rtk_reset_desc *desc = rtk_reset_get_desc(data, idx);
+	u32 val;
+	int ret;
+
+	ret = regmap_read(data->regmap, desc->ofs, &val);
+	if (ret)
+		return ret;
+
+	return !((val >> desc->bit) & 1);
+}
+
+static const struct reset_control_ops rtk_reset_ops = {
+	.assert   = rtk_reset_assert,
+	.deassert = rtk_reset_deassert,
+	.status   = rtk_reset_status,
+};
+
+/* The caller must initialize data->rcdev.nr_resets and data->descs before
+ * calling rtk_reset_controller_add().
+ */
+int rtk_reset_controller_add(struct device *dev,
+			     struct rtk_reset_data *data)
+{
+	struct device *parent = dev->parent;
+
+	data->regmap = dev_get_regmap(parent, NULL);
+	if (!data->regmap)
+		return -ENODEV;
+
+	data->rcdev.owner     = THIS_MODULE;
+	data->rcdev.ops       = &rtk_reset_ops;
+	data->rcdev.dev       = dev;
+	data->rcdev.of_node   = parent->of_node;
+
+	return devm_reset_controller_register(dev, &data->rcdev);
+}
+EXPORT_SYMBOL_NS_GPL(rtk_reset_controller_add, "REALTEK_RESET");
diff --git a/drivers/reset/realtek/common.h b/drivers/reset/realtek/common.h
new file mode 100644
index 000000000000..ed69bca458de
--- /dev/null
+++ b/drivers/reset/realtek/common.h
@@ -0,0 +1,29 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2026 Realtek Semiconductor Corporation
+ * Author: Yu-Chun Lin <eleanor.lin@realtek.com>
+ */
+
+#ifndef __RESET_REALTEK_COMMON_H
+#define __RESET_REALTEK_COMMON_H
+
+#include <linux/reset-controller.h>
+
+struct regmap;
+
+struct rtk_reset_desc {
+	u32 ofs;
+	u32 bit;
+	bool write_en;
+};
+
+struct rtk_reset_data {
+	struct reset_controller_dev rcdev;
+	struct rtk_reset_desc *descs;
+	struct regmap *regmap;
+};
+
+int rtk_reset_controller_add(struct device *dev,
+			     struct rtk_reset_data *initdata);
+
+#endif /* __RESET_REALTEK_COMMON_H */
-- 
2.34.1


^ permalink raw reply related

* [PATCH v6 00/10] clk: realtek: Add RTD1625 clock support
From: Yu-Chun Lin @ 2026-04-02  7:39 UTC (permalink / raw)
  To: mturquette, sboyd, robh, krzk+dt, conor+dt, p.zabel, cylee12,
	afaerber, jyanchou
  Cc: devicetree, linux-clk, linux-kernel, linux-arm-kernel,
	linux-realtek-soc, james.tai, cy.huang, stanley_chang,
	eleanor.lin

Hello,

This patch series adds clock support for Realtek's RTD1625 platform.
The series includes:
1. Device Tree: Add clock controller nodes.
2. Infrastructure: reset controller, basic clocks, PLLs, gate clocks, mux
clocks, and MMC-tuned PLLs.
3. Platform drivers: two clock controller drivers for RTD1625-CRT and
RTD1625-ISO.

Best regards,
Yu-Chun Lin
---
Changes in v6:
General:
- Add the headers used in c file to follow the "Include What You Use" principle.
- Move dts patch to patch 10.

Patch 1:
- Add 'clocks' property.
- Add reviewed-by tag from Krzysztof.
- Add Cheng-Yu Lee as maintainer in the binding file.
- Add 'clocks' property.
- Add include/dt-bindings/reset/realtek,rtd1625.h to the MAINTAINERS file.

Patch 2:
- Remove the global header include/linux/reset/realtek.h and use a local common.h
instead.
- Extract regmap and of_node directly from the parent device.
- Remove struct rtk_reset_initdata. Now, when the caller uses
rtk_reset_controller_add(), directly passes struct rtk_reset_data.

Patch 3:
- Replace direct reset controller initialization with auxiliary device creation.
- Add aux_name parameter to rtk_clk_probe() to register the reset auxiliary device.
- Simplify rtk_clk_desc because reset data is handled entirely by the auxiliary reset driver.
- In Kconfig, change "depends on RESET_CONTROLLER" to "select RESET_CONTROLLER"
- Remove unused includes headers and added <linux/auxiliary_bus.h>.

Patch 6 and 7:
- Move to_clk_pll() from clk-pll.h to clk-pll.c to limit its scope.

Patch 7:
- Change offset type from int to unsigned int.

Patch 8 and 9:
- Move struct rtk_reset_desc arrays from the clock driver to the dedicated reset driver.
- Implement and register a dedicated reset auxiliary driver.

Patch 10:
- Add 'clocks' property.

Cheng-Yu Lee (6):
  reset: Add Realtek basic reset support
  clk: realtek: Introduce a common probe()
  clk: realtek: Add support for phase locked loops (PLLs)
  clk: realtek: Add support for gate clock
  clk: realtek: Add support for mux clock
  clk: realtek: Add support for MMC-tuned PLL clocks

Yu-Chun Lin (4):
  dt-bindings: clock: Add Realtek RTD1625 Clock & Reset Controller
  clk: realtek: Add RTD1625-CRT clock controller driver
  clk: realtek: Add RTD1625-ISO clock controller driver
  arm64: dts: realtek: Add clock support for RTD1625

 .../bindings/clock/realtek,rtd1625-clk.yaml   |  58 ++
 MAINTAINERS                                   |  20 +
 arch/arm64/boot/dts/realtek/kent.dtsi         |  33 +
 drivers/clk/Kconfig                           |   1 +
 drivers/clk/Makefile                          |   1 +
 drivers/clk/realtek/Kconfig                   |  44 +
 drivers/clk/realtek/Makefile                  |  13 +
 drivers/clk/realtek/clk-pll-mmc.c             | 410 +++++++++
 drivers/clk/realtek/clk-pll.c                 | 164 ++++
 drivers/clk/realtek/clk-pll.h                 |  55 ++
 drivers/clk/realtek/clk-regmap-gate.c         |  69 ++
 drivers/clk/realtek/clk-regmap-gate.h         |  65 ++
 drivers/clk/realtek/clk-regmap-mux.c          |  48 ++
 drivers/clk/realtek/clk-regmap-mux.h          |  43 +
 drivers/clk/realtek/clk-rtd1625-crt.c         | 779 ++++++++++++++++++
 drivers/clk/realtek/clk-rtd1625-iso.c         | 144 ++++
 drivers/clk/realtek/common.c                  |  67 ++
 drivers/clk/realtek/common.h                  |  37 +
 drivers/clk/realtek/freq_table.c              |  36 +
 drivers/clk/realtek/freq_table.h              |  21 +
 drivers/reset/Kconfig                         |   1 +
 drivers/reset/Makefile                        |   1 +
 drivers/reset/realtek/Kconfig                 |   5 +
 drivers/reset/realtek/Makefile                |   2 +
 drivers/reset/realtek/common.c                |  85 ++
 drivers/reset/realtek/common.h                |  29 +
 drivers/reset/realtek/reset-rtd1625-crt.c     | 186 +++++
 drivers/reset/realtek/reset-rtd1625-iso.c     |  96 +++
 .../dt-bindings/clock/realtek,rtd1625-clk.h   | 164 ++++
 include/dt-bindings/reset/realtek,rtd1625.h   | 171 ++++
 30 files changed, 2848 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/realtek,rtd1625-clk.yaml
 create mode 100644 drivers/clk/realtek/Kconfig
 create mode 100644 drivers/clk/realtek/Makefile
 create mode 100644 drivers/clk/realtek/clk-pll-mmc.c
 create mode 100644 drivers/clk/realtek/clk-pll.c
 create mode 100644 drivers/clk/realtek/clk-pll.h
 create mode 100644 drivers/clk/realtek/clk-regmap-gate.c
 create mode 100644 drivers/clk/realtek/clk-regmap-gate.h
 create mode 100644 drivers/clk/realtek/clk-regmap-mux.c
 create mode 100644 drivers/clk/realtek/clk-regmap-mux.h
 create mode 100644 drivers/clk/realtek/clk-rtd1625-crt.c
 create mode 100644 drivers/clk/realtek/clk-rtd1625-iso.c
 create mode 100644 drivers/clk/realtek/common.c
 create mode 100644 drivers/clk/realtek/common.h
 create mode 100644 drivers/clk/realtek/freq_table.c
 create mode 100644 drivers/clk/realtek/freq_table.h
 create mode 100644 drivers/reset/realtek/Kconfig
 create mode 100644 drivers/reset/realtek/Makefile
 create mode 100644 drivers/reset/realtek/common.c
 create mode 100644 drivers/reset/realtek/common.h
 create mode 100644 drivers/reset/realtek/reset-rtd1625-crt.c
 create mode 100644 drivers/reset/realtek/reset-rtd1625-iso.c
 create mode 100644 include/dt-bindings/clock/realtek,rtd1625-clk.h
 create mode 100644 include/dt-bindings/reset/realtek,rtd1625.h

-- 
2.34.1


^ permalink raw reply

* [PATCH v6 09/10] clk: realtek: Add RTD1625-ISO clock controller driver
From: Yu-Chun Lin @ 2026-04-02  7:39 UTC (permalink / raw)
  To: mturquette, sboyd, robh, krzk+dt, conor+dt, p.zabel, cylee12,
	afaerber, jyanchou
  Cc: devicetree, linux-clk, linux-kernel, linux-arm-kernel,
	linux-realtek-soc, james.tai, cy.huang, stanley_chang,
	eleanor.lin
In-Reply-To: <20260402073957.2742459-1-eleanor.lin@realtek.com>

From: Cheng-Yu Lee <cylee12@realtek.com>

Add support for the ISO (Isolation) domain clock controller on the Realtek
RTD1625 SoC. This controller manages clocks in the always-on power domain,
ensuring essential services remain functional even when the main system
power is gated.

Since the reset controller shares the same register space with the ISO
clock controller, it is instantiated as an auxiliary device by the core
clock driver. This patch also includes the corresponding auxiliary reset
driver to handle the ISO domain resets.

Signed-off-by: Cheng-Yu Lee <cylee12@realtek.com>
Co-developed-by: Yu-Chun Lin <eleanor.lin@realtek.com>
Signed-off-by: Yu-Chun Lin <eleanor.lin@realtek.com>
---
Changes in v6:
- Add the headers used in c file to follow the "Include What You Use" principle.
- Move struct rtk_reset_desc arrays from the clock driver to the dedicated reset driver.
- Implement and register a dedicated reset auxiliary driver.
---
 drivers/clk/realtek/Makefile              |   1 +
 drivers/clk/realtek/clk-rtd1625-iso.c     | 144 ++++++++++++++++++++++
 drivers/reset/realtek/Makefile            |   2 +-
 drivers/reset/realtek/reset-rtd1625-iso.c |  96 +++++++++++++++
 4 files changed, 242 insertions(+), 1 deletion(-)
 create mode 100644 drivers/clk/realtek/clk-rtd1625-iso.c
 create mode 100644 drivers/reset/realtek/reset-rtd1625-iso.c

diff --git a/drivers/clk/realtek/Makefile b/drivers/clk/realtek/Makefile
index c992f97dfbc7..1680435e1e0f 100644
--- a/drivers/clk/realtek/Makefile
+++ b/drivers/clk/realtek/Makefile
@@ -10,3 +10,4 @@ clk-rtk-y += freq_table.o
 
 clk-rtk-$(CONFIG_RTK_CLK_PLL_MMC) += clk-pll-mmc.o
 obj-$(CONFIG_COMMON_CLK_RTD1625) += clk-rtd1625-crt.o
+obj-$(CONFIG_COMMON_CLK_RTD1625) += clk-rtd1625-iso.o
diff --git a/drivers/clk/realtek/clk-rtd1625-iso.c b/drivers/clk/realtek/clk-rtd1625-iso.c
new file mode 100644
index 000000000000..027a131363f9
--- /dev/null
+++ b/drivers/clk/realtek/clk-rtd1625-iso.c
@@ -0,0 +1,144 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2024 Realtek Semiconductor Corporation
+ * Author: Cheng-Yu Lee <cylee12@realtek.com>
+ */
+
+#include <dt-bindings/clock/realtek,rtd1625-clk.h>
+#include <linux/array_size.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include "clk-regmap-gate.h"
+
+#define RTD1625_ISO_CLK_MAX	19
+#define RTD1625_ISO_RSTN_MAX	29
+#define RTD1625_ISO_S_CLK_MAX	5
+#define RTD1625_ISO_S_RSTN_MAX	5
+
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_usb_p4, 0, 0x4, 0, 0);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_usb_p3, 0, 0x4, 1, 0);
+static CLK_REGMAP_GATE(clk_en_misc_cec0, "clk_en_misc", 0, 0x4, 2, 0);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_cbusrx_sys, 0, 0x4, 3, 0);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_cbustx_sys, 0, 0x4, 4, 0);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_cbus_sys, 0, 0x4, 5, 0);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_cbus_osc, 0, 0x4, 6, 0);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_i2c0, 0, 0x4, 9, 0);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_i2c1, 0, 0x4, 10, 0);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_etn_250m, 0, 0x4, 11, 0);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_etn_sys, 0, 0x4, 12, 0);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_usb_drd, 0, 0x4, 13, 0);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_usb_host, 0, 0x4, 14, 0);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_usb_u3_host, 0, 0x4, 15, 0);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_usb, 0, 0x4, 16, 0);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_vtc, 0, 0x4, 17, 0);
+static CLK_REGMAP_GATE(clk_en_misc_vfd, "clk_en_misc", 0, 0x4, 18, 0);
+
+static struct clk_regmap *rtd1625_clk_regmap_list[] = {
+	&clk_en_usb_p4.clkr,
+	&clk_en_usb_p3.clkr,
+	&clk_en_misc_cec0.clkr,
+	&clk_en_cbusrx_sys.clkr,
+	&clk_en_cbustx_sys.clkr,
+	&clk_en_cbus_sys.clkr,
+	&clk_en_cbus_osc.clkr,
+	&clk_en_i2c0.clkr,
+	&clk_en_i2c1.clkr,
+	&clk_en_etn_250m.clkr,
+	&clk_en_etn_sys.clkr,
+	&clk_en_usb_drd.clkr,
+	&clk_en_usb_host.clkr,
+	&clk_en_usb_u3_host.clkr,
+	&clk_en_usb.clkr,
+	&clk_en_vtc.clkr,
+	&clk_en_misc_vfd.clkr,
+};
+
+static struct clk_hw_onecell_data rtd1625_iso_clk_data = {
+	.num = RTD1625_ISO_CLK_MAX,
+	.hws = {
+		[RTD1625_ISO_CLK_EN_USB_P4]      = &__clk_regmap_gate_hw(&clk_en_usb_p4),
+		[RTD1625_ISO_CLK_EN_USB_P3]      = &__clk_regmap_gate_hw(&clk_en_usb_p3),
+		[RTD1625_ISO_CLK_EN_MISC_CEC0]   = &__clk_regmap_gate_hw(&clk_en_misc_cec0),
+		[RTD1625_ISO_CLK_EN_CBUSRX_SYS]  = &__clk_regmap_gate_hw(&clk_en_cbusrx_sys),
+		[RTD1625_ISO_CLK_EN_CBUSTX_SYS]  = &__clk_regmap_gate_hw(&clk_en_cbustx_sys),
+		[RTD1625_ISO_CLK_EN_CBUS_SYS]    = &__clk_regmap_gate_hw(&clk_en_cbus_sys),
+		[RTD1625_ISO_CLK_EN_CBUS_OSC]    = &__clk_regmap_gate_hw(&clk_en_cbus_osc),
+		[RTD1625_ISO_CLK_EN_I2C0]        = &__clk_regmap_gate_hw(&clk_en_i2c0),
+		[RTD1625_ISO_CLK_EN_I2C1]        = &__clk_regmap_gate_hw(&clk_en_i2c1),
+		[RTD1625_ISO_CLK_EN_ETN_250M]    = &__clk_regmap_gate_hw(&clk_en_etn_250m),
+		[RTD1625_ISO_CLK_EN_ETN_SYS]     = &__clk_regmap_gate_hw(&clk_en_etn_sys),
+		[RTD1625_ISO_CLK_EN_USB_DRD]     = &__clk_regmap_gate_hw(&clk_en_usb_drd),
+		[RTD1625_ISO_CLK_EN_USB_HOST]    = &__clk_regmap_gate_hw(&clk_en_usb_host),
+		[RTD1625_ISO_CLK_EN_USB_U3_HOST] = &__clk_regmap_gate_hw(&clk_en_usb_u3_host),
+		[RTD1625_ISO_CLK_EN_USB]         = &__clk_regmap_gate_hw(&clk_en_usb),
+		[RTD1625_ISO_CLK_EN_VTC]         = &__clk_regmap_gate_hw(&clk_en_vtc),
+		[RTD1625_ISO_CLK_EN_MISC_VFD]    = &__clk_regmap_gate_hw(&clk_en_misc_vfd),
+		[RTD1625_ISO_CLK_MAX] = NULL,
+	},
+};
+
+static const struct rtk_clk_desc rtd1625_iso_desc = {
+	.clk_data = &rtd1625_iso_clk_data,
+	.clks     = rtd1625_clk_regmap_list,
+	.num_clks = ARRAY_SIZE(rtd1625_clk_regmap_list),
+};
+
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_irda, 0, 0x4, 6, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_ur10, 0, 0x4, 8, 1);
+
+static struct clk_regmap *rtd1625_iso_s_clk_regmap_list[] = {
+	&clk_en_irda.clkr,
+	&clk_en_ur10.clkr,
+};
+
+static struct clk_hw_onecell_data rtd1625_iso_s_clk_data = {
+	.num = RTD1625_ISO_S_CLK_MAX,
+	.hws = {
+		[RTD1625_ISO_S_CLK_EN_IRDA] = &__clk_regmap_gate_hw(&clk_en_irda),
+		[RTD1625_ISO_S_CLK_EN_UR10] = &__clk_regmap_gate_hw(&clk_en_ur10),
+		[RTD1625_ISO_S_CLK_MAX] = NULL,
+	},
+};
+
+static const struct rtk_clk_desc rtd1625_iso_s_desc = {
+	.clk_data = &rtd1625_iso_s_clk_data,
+	.clks     = rtd1625_iso_s_clk_regmap_list,
+	.num_clks = ARRAY_SIZE(rtd1625_iso_s_clk_regmap_list),
+};
+
+static int rtd1625_iso_probe(struct platform_device *pdev)
+{
+	const struct rtk_clk_desc *desc;
+
+	desc = of_device_get_match_data(&pdev->dev);
+	if (!desc)
+		return -EINVAL;
+	return rtk_clk_probe(pdev, desc, "iso_rst");
+}
+
+static const struct of_device_id rtd1625_iso_match[] = {
+	{.compatible = "realtek,rtd1625-iso-clk", .data = &rtd1625_iso_desc},
+	{.compatible = "realtek,rtd1625-iso-s-clk", .data = &rtd1625_iso_s_desc},
+	{ /* sentinel */ }
+};
+
+static struct platform_driver rtd1625_iso_driver = {
+	.probe = rtd1625_iso_probe,
+	.driver = {
+		.name = "rtk-rtd1625-iso-clk",
+		.of_match_table = rtd1625_iso_match,
+	},
+};
+
+static int __init rtd1625_iso_init(void)
+{
+	return platform_driver_register(&rtd1625_iso_driver);
+}
+subsys_initcall(rtd1625_iso_init);
+
+MODULE_DESCRIPTION("Realtek RTD1625 ISO Controller Driver");
+MODULE_AUTHOR("Cheng-Yu Lee <cylee12@realtek.com>");
+MODULE_LICENSE("GPL");
+MODULE_IMPORT_NS("REALTEK_CLK");
diff --git a/drivers/reset/realtek/Makefile b/drivers/reset/realtek/Makefile
index 8ca1fa939f10..26b3ddc75ada 100644
--- a/drivers/reset/realtek/Makefile
+++ b/drivers/reset/realtek/Makefile
@@ -1,2 +1,2 @@
 # SPDX-License-Identifier: GPL-2.0-only
-obj-$(CONFIG_RESET_RTK_COMMON) += common.o reset-rtd1625-crt.o
+obj-$(CONFIG_RESET_RTK_COMMON) += common.o reset-rtd1625-crt.o reset-rtd1625-iso.o
diff --git a/drivers/reset/realtek/reset-rtd1625-iso.c b/drivers/reset/realtek/reset-rtd1625-iso.c
new file mode 100644
index 000000000000..f2a0478382ae
--- /dev/null
+++ b/drivers/reset/realtek/reset-rtd1625-iso.c
@@ -0,0 +1,96 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2026 Realtek Semiconductor Corporation
+ */
+
+#include <dt-bindings/reset/realtek,rtd1625.h>
+#include <linux/auxiliary_bus.h>
+#include <linux/device.h>
+#include <linux/errno.h>
+#include <linux/of.h>
+#include <linux/slab.h>
+#include "common.h"
+
+#define RTD1625_ISO_RSTN_MAX	29
+#define RTD1625_ISO_S_RSTN_MAX	5
+
+static struct rtk_reset_desc rtd1625_iso_reset_descs[] = {
+	[RTD1625_ISO_RSTN_VFD]                 = { .ofs = 0x88, .bit = 0 },
+	[RTD1625_ISO_RSTN_CEC0]                = { .ofs = 0x88, .bit = 2 },
+	[RTD1625_ISO_RSTN_CEC1]                = { .ofs = 0x88, .bit = 3 },
+	[RTD1625_ISO_RSTN_CBUSTX]              = { .ofs = 0x88, .bit = 5 },
+	[RTD1625_ISO_RSTN_CBUSRX]              = { .ofs = 0x88, .bit = 6 },
+	[RTD1625_ISO_RSTN_USB3_PHY2_XTAL_POW]  = { .ofs = 0x88, .bit = 7 },
+	[RTD1625_ISO_RSTN_UR0]                 = { .ofs = 0x88, .bit = 8 },
+	[RTD1625_ISO_RSTN_GMAC]                = { .ofs = 0x88, .bit = 9 },
+	[RTD1625_ISO_RSTN_GPHY]                = { .ofs = 0x88, .bit = 10 },
+	[RTD1625_ISO_RSTN_I2C_0]               = { .ofs = 0x88, .bit = 11 },
+	[RTD1625_ISO_RSTN_I2C_1]               = { .ofs = 0x88, .bit = 12 },
+	[RTD1625_ISO_RSTN_CBUS]                = { .ofs = 0x88, .bit = 13 },
+	[RTD1625_ISO_RSTN_USB_DRD]             = { .ofs = 0x88, .bit = 14 },
+	[RTD1625_ISO_RSTN_USB_HOST]            = { .ofs = 0x88, .bit = 15 },
+	[RTD1625_ISO_RSTN_USB_PHY_0]           = { .ofs = 0x88, .bit = 16 },
+	[RTD1625_ISO_RSTN_USB_PHY_1]           = { .ofs = 0x88, .bit = 17 },
+	[RTD1625_ISO_RSTN_USB_PHY_2]           = { .ofs = 0x88, .bit = 18 },
+	[RTD1625_ISO_RSTN_USB]                 = { .ofs = 0x88, .bit = 19 },
+	[RTD1625_ISO_RSTN_TYPE_C]              = { .ofs = 0x88, .bit = 20 },
+	[RTD1625_ISO_RSTN_USB_U3_HOST]         = { .ofs = 0x88, .bit = 21 },
+	[RTD1625_ISO_RSTN_USB3_PHY0_POW]       = { .ofs = 0x88, .bit = 22 },
+	[RTD1625_ISO_RSTN_USB3_P0_MDIO]        = { .ofs = 0x88, .bit = 23 },
+	[RTD1625_ISO_RSTN_USB3_PHY1_POW]       = { .ofs = 0x88, .bit = 24 },
+	[RTD1625_ISO_RSTN_USB3_P1_MDIO]        = { .ofs = 0x88, .bit = 25 },
+	[RTD1625_ISO_RSTN_VTC]                 = { .ofs = 0x88, .bit = 26 },
+	[RTD1625_ISO_RSTN_USB3_PHY2_POW]       = { .ofs = 0x88, .bit = 27 },
+	[RTD1625_ISO_RSTN_USB3_P2_MDIO]        = { .ofs = 0x88, .bit = 28 },
+	[RTD1625_ISO_RSTN_USB_PHY_3]           = { .ofs = 0x88, .bit = 29 },
+	[RTD1625_ISO_RSTN_USB_PHY_4]           = { .ofs = 0x88, .bit = 30 },
+};
+
+static struct rtk_reset_desc rtd1625_iso_s_reset_descs[] = {
+	[RTD1625_ISO_S_RSTN_ISOM_MIS] = { .ofs = 0x310, .bit = 0, .write_en = 1 },
+	[RTD1625_ISO_S_RSTN_GPIOM]    = { .ofs = 0x310, .bit = 2, .write_en = 1 },
+	[RTD1625_ISO_S_RSTN_TIMER7]   = { .ofs = 0x310, .bit = 4, .write_en = 1 },
+	[RTD1625_ISO_S_RSTN_IRDA]     = { .ofs = 0x310, .bit = 6, .write_en = 1 },
+	[RTD1625_ISO_S_RSTN_UR10]     = { .ofs = 0x310, .bit = 8, .write_en = 1 },
+};
+
+static int rtd1625_iso_reset_probe(struct auxiliary_device *adev,
+				   const struct auxiliary_device_id *id)
+{
+	struct device *dev = &adev->dev;
+	struct device *parent = dev->parent;
+	struct rtk_reset_data *data;
+
+	data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
+	if (!data)
+		return -ENOMEM;
+
+	if (of_device_is_compatible(parent->of_node, "realtek,rtd1625-iso-s-clk")) {
+		data->descs           = rtd1625_iso_s_reset_descs;
+		data->rcdev.nr_resets = RTD1625_ISO_S_RSTN_MAX;
+	} else {
+		data->descs           = rtd1625_iso_reset_descs;
+		data->rcdev.nr_resets = RTD1625_ISO_RSTN_MAX;
+	}
+	return rtk_reset_controller_add(dev, data);
+}
+
+static const struct auxiliary_device_id rtd1625_iso_reset_ids[] = {
+	{
+		.name = "clk_rtk.iso_rst",
+	},
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(auxiliary, rtd1625_iso_reset_ids);
+
+static struct auxiliary_driver rtd1625_iso_driver = {
+	.probe = rtd1625_iso_reset_probe,
+	.id_table = rtd1625_iso_reset_ids,
+	.driver = {
+		.name = "rtd1625-iso-reset",
+	},
+};
+module_auxiliary_driver(rtd1625_iso_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_IMPORT_NS("REALTEK_RESET");
-- 
2.34.1


^ permalink raw reply related

* [PATCH v6 03/10] clk: realtek: Introduce a common probe()
From: Yu-Chun Lin @ 2026-04-02  7:39 UTC (permalink / raw)
  To: mturquette, sboyd, robh, krzk+dt, conor+dt, p.zabel, cylee12,
	afaerber, jyanchou
  Cc: devicetree, linux-clk, linux-kernel, linux-arm-kernel,
	linux-realtek-soc, james.tai, cy.huang, stanley_chang,
	eleanor.lin
In-Reply-To: <20260402073957.2742459-1-eleanor.lin@realtek.com>

From: Cheng-Yu Lee <cylee12@realtek.com>

Add rtk_clk_probe() to set up the shared regmap, register clock hardware,
and add the clock provider.

Additionally, if the "#reset-cells" property is present in the device tree,
it creates and registers an auxiliary device using the provided aux_name.
This allows the dedicated reset driver to bind to this device, enabling
both clock and reset drivers to share the same regmap.

Signed-off-by: Cheng-Yu Lee <cylee12@realtek.com>
Co-developed-by: Yu-Chun Lin <eleanor.lin@realtek.com>
Signed-off-by: Yu-Chun Lin <eleanor.lin@realtek.com>
---
Changes in v6:
- Replace direct reset controller initialization with auxiliary device creation.
- Add aux_name parameter to rtk_clk_probe() to register the reset auxiliary device.
- Simplify rtk_clk_desc because reset data is handled entirely by the auxiliary reset driver.
- In Kconfig, change "depends on RESET_CONTROLLER" to "select RESET_CONTROLLER"
- Remove unused includes headers and added <linux/auxiliary_bus.h>.
---
 MAINTAINERS                  |  1 +
 drivers/clk/Kconfig          |  1 +
 drivers/clk/Makefile         |  1 +
 drivers/clk/realtek/Kconfig  | 28 +++++++++++++++
 drivers/clk/realtek/Makefile |  4 +++
 drivers/clk/realtek/common.c | 67 ++++++++++++++++++++++++++++++++++++
 drivers/clk/realtek/common.h | 37 ++++++++++++++++++++
 7 files changed, 139 insertions(+)
 create mode 100644 drivers/clk/realtek/Kconfig
 create mode 100644 drivers/clk/realtek/Makefile
 create mode 100644 drivers/clk/realtek/common.c
 create mode 100644 drivers/clk/realtek/common.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 8f355896583b..8318156a02b5 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -22240,6 +22240,7 @@ L:	devicetree@vger.kernel.org
 L:	linux-clk@vger.kernel.org
 S:	Supported
 F:	Documentation/devicetree/bindings/clock/realtek*
+F:	drivers/clk/realtek/*
 F:	drivers/reset/realtek/*
 F:	include/dt-bindings/clock/realtek*
 F:	include/dt-bindings/reset/realtek*
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index 3d803b4cf5c1..d60f6415b0a3 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -519,6 +519,7 @@ source "drivers/clk/nuvoton/Kconfig"
 source "drivers/clk/pistachio/Kconfig"
 source "drivers/clk/qcom/Kconfig"
 source "drivers/clk/ralink/Kconfig"
+source "drivers/clk/realtek/Kconfig"
 source "drivers/clk/renesas/Kconfig"
 source "drivers/clk/rockchip/Kconfig"
 source "drivers/clk/samsung/Kconfig"
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index f7bce3951a30..69b84d1e7bcc 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -140,6 +140,7 @@ obj-$(CONFIG_COMMON_CLK_PISTACHIO)	+= pistachio/
 obj-$(CONFIG_COMMON_CLK_PXA)		+= pxa/
 obj-$(CONFIG_COMMON_CLK_QCOM)		+= qcom/
 obj-y					+= ralink/
+obj-$(CONFIG_COMMON_CLK_REALTEK)	+= realtek/
 obj-y					+= renesas/
 obj-$(CONFIG_ARCH_ROCKCHIP)		+= rockchip/
 obj-$(CONFIG_COMMON_CLK_SAMSUNG)	+= samsung/
diff --git a/drivers/clk/realtek/Kconfig b/drivers/clk/realtek/Kconfig
new file mode 100644
index 000000000000..bc47d3f1c452
--- /dev/null
+++ b/drivers/clk/realtek/Kconfig
@@ -0,0 +1,28 @@
+# SPDX-License-Identifier: GPL-2.0-only
+config COMMON_CLK_REALTEK
+	bool "Clock driver for Realtek SoCs"
+	depends on ARCH_REALTEK || COMPILE_TEST
+	default ARCH_REALTEK
+	help
+	  Enable the common clock framework infrastructure for Realtek
+	  system-on-chip platforms.
+
+	  This provides the base support required by individual Realtek
+	  clock controller drivers to expose clocks to peripheral devices.
+
+	  If you have a Realtek-based platform, say Y.
+
+if COMMON_CLK_REALTEK
+
+config RTK_CLK_COMMON
+	tristate "Realtek Clock Common"
+	select RESET_CONTROLLER
+	select RESET_RTK_COMMON
+	help
+	  Common helper code shared by Realtek clock controller drivers.
+
+	  This provides utility functions and data structures used by
+	  multiple Realtek clock implementations, and include integration
+	  with reset controllers where required.
+
+endif
diff --git a/drivers/clk/realtek/Makefile b/drivers/clk/realtek/Makefile
new file mode 100644
index 000000000000..377ec776ee47
--- /dev/null
+++ b/drivers/clk/realtek/Makefile
@@ -0,0 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0-only
+obj-$(CONFIG_RTK_CLK_COMMON) += clk-rtk.o
+
+clk-rtk-y += common.o
diff --git a/drivers/clk/realtek/common.c b/drivers/clk/realtek/common.c
new file mode 100644
index 000000000000..c5aea15a3714
--- /dev/null
+++ b/drivers/clk/realtek/common.c
@@ -0,0 +1,67 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2019 Realtek Semiconductor Corporation
+ * Author: Cheng-Yu Lee <cylee12@realtek.com>
+ */
+
+#include <linux/auxiliary_bus.h>
+#include <linux/device.h>
+#include <linux/mfd/syscon.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include "common.h"
+
+static int rtk_reset_controller_register(struct device *dev, const char *aux_name)
+{
+	struct auxiliary_device *adev;
+
+	if (!of_property_present(dev->of_node, "#reset-cells"))
+		return 0;
+
+	adev = devm_auxiliary_device_create(dev, aux_name, NULL);
+
+	if (IS_ERR(adev))
+		return PTR_ERR(adev);
+	return 0;
+}
+
+int rtk_clk_probe(struct platform_device *pdev, const struct rtk_clk_desc *desc,
+		  const char *aux_name)
+{
+	int i, ret;
+	struct regmap *regmap;
+	struct device *dev = &pdev->dev;
+
+	regmap = device_node_to_regmap(pdev->dev.of_node);
+	if (IS_ERR(regmap))
+		return dev_err_probe(dev, PTR_ERR(regmap), "failed to get regmap\n");
+
+	for (i = 0; i < desc->num_clks; i++)
+		desc->clks[i]->regmap = regmap;
+
+	for (i = 0; i < desc->clk_data->num; i++) {
+		struct clk_hw *hw = desc->clk_data->hws[i];
+
+		if (!hw)
+			continue;
+
+		ret = devm_clk_hw_register(dev, hw);
+
+		if (ret) {
+			dev_warn(dev, "failed to register hw of clk%d: %d\n", i,
+				 ret);
+			desc->clk_data->hws[i] = NULL;
+		}
+	}
+
+	ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get,
+					  desc->clk_data);
+	if (ret)
+		return dev_err_probe(dev, ret, "failed to add clock provider\n");
+
+	return rtk_reset_controller_register(dev, aux_name);
+}
+EXPORT_SYMBOL_NS_GPL(rtk_clk_probe, "REALTEK_CLK");
+
+MODULE_DESCRIPTION("Realtek clock infrastructure");
+MODULE_LICENSE("GPL");
diff --git a/drivers/clk/realtek/common.h b/drivers/clk/realtek/common.h
new file mode 100644
index 000000000000..93a746d9bbf0
--- /dev/null
+++ b/drivers/clk/realtek/common.h
@@ -0,0 +1,37 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2016-2019 Realtek Semiconductor Corporation
+ * Author: Cheng-Yu Lee <cylee12@realtek.com>
+ */
+
+#ifndef __CLK_REALTEK_COMMON_H
+#define __CLK_REALTEK_COMMON_H
+
+#include <linux/clk-provider.h>
+
+#define __clk_regmap_hw(_p) ((_p)->hw)
+
+struct device;
+struct platform_device;
+struct regmap;
+
+struct clk_regmap {
+	struct clk_hw hw;
+	struct regmap *regmap;
+};
+
+struct rtk_clk_desc {
+	struct clk_hw_onecell_data *clk_data;
+	struct clk_regmap **clks;
+	size_t num_clks;
+};
+
+static inline struct clk_regmap *to_clk_regmap(struct clk_hw *hw)
+{
+	return container_of(hw, struct clk_regmap, hw);
+}
+
+int rtk_clk_probe(struct platform_device *pdev, const struct rtk_clk_desc *desc,
+		  const char *aux_name);
+
+#endif /* __CLK_REALTEK_COMMON_H */
-- 
2.34.1


^ permalink raw reply related

* [PATCH v6 04/10] clk: realtek: Add support for phase locked loops (PLLs)
From: Yu-Chun Lin @ 2026-04-02  7:39 UTC (permalink / raw)
  To: mturquette, sboyd, robh, krzk+dt, conor+dt, p.zabel, cylee12,
	afaerber, jyanchou
  Cc: devicetree, linux-clk, linux-kernel, linux-arm-kernel,
	linux-realtek-soc, james.tai, cy.huang, stanley_chang,
	eleanor.lin
In-Reply-To: <20260402073957.2742459-1-eleanor.lin@realtek.com>

From: Cheng-Yu Lee <cylee12@realtek.com>

Provide a full set of PLL operations for programmable PLLs and a read-only
variant for fixed or hardware-managed PLLs.

Signed-off-by: Cheng-Yu Lee <cylee12@realtek.com>
Co-developed-by: Yu-Chun Lin <eleanor.lin@realtek.com>
Signed-off-by: Yu-Chun Lin <eleanor.lin@realtek.com>
---
Changes in v6:
- Add the headers used in c file to follow the "Include What You Use" principle.
- Move to_clk_pll() from clk-pll.h to clk-pll.c to limit its scope.
---
 drivers/clk/realtek/Makefile     |   2 +
 drivers/clk/realtek/clk-pll.c    | 164 +++++++++++++++++++++++++++++++
 drivers/clk/realtek/clk-pll.h    |  42 ++++++++
 drivers/clk/realtek/freq_table.c |  36 +++++++
 drivers/clk/realtek/freq_table.h |  21 ++++
 5 files changed, 265 insertions(+)
 create mode 100644 drivers/clk/realtek/clk-pll.c
 create mode 100644 drivers/clk/realtek/clk-pll.h
 create mode 100644 drivers/clk/realtek/freq_table.c
 create mode 100644 drivers/clk/realtek/freq_table.h

diff --git a/drivers/clk/realtek/Makefile b/drivers/clk/realtek/Makefile
index 377ec776ee47..a89ad77993e9 100644
--- a/drivers/clk/realtek/Makefile
+++ b/drivers/clk/realtek/Makefile
@@ -2,3 +2,5 @@
 obj-$(CONFIG_RTK_CLK_COMMON) += clk-rtk.o
 
 clk-rtk-y += common.o
+clk-rtk-y += clk-pll.o
+clk-rtk-y += freq_table.o
diff --git a/drivers/clk/realtek/clk-pll.c b/drivers/clk/realtek/clk-pll.c
new file mode 100644
index 000000000000..44730b22a94c
--- /dev/null
+++ b/drivers/clk/realtek/clk-pll.c
@@ -0,0 +1,164 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2024 Realtek Semiconductor Corporation
+ * Author: Cheng-Yu Lee <cylee12@realtek.com>
+ */
+
+#include <linux/regmap.h>
+#include "clk-pll.h"
+
+#define TIMEOUT 2000
+
+static inline struct clk_pll *to_clk_pll(struct clk_hw *hw)
+{
+	struct clk_regmap *clkr = to_clk_regmap(hw);
+
+	return container_of(clkr, struct clk_pll, clkr);
+}
+
+static int wait_freq_ready(struct clk_pll *clkp)
+{
+	u32 pollval;
+
+	if (!clkp->freq_ready_valid)
+		return 0;
+
+	return regmap_read_poll_timeout_atomic(clkp->clkr.regmap, clkp->freq_ready_reg, pollval,
+						(pollval & clkp->freq_ready_mask)
+						== clkp->freq_ready_val, 0, TIMEOUT);
+}
+
+static bool is_power_on(struct clk_pll *clkp)
+{
+	u32 val;
+
+	if (!clkp->power_reg)
+		return true;
+
+	if (regmap_read(clkp->clkr.regmap, clkp->power_reg, &val))
+		return true;
+
+	return (val & clkp->power_mask) == clkp->power_val_on;
+}
+
+static void clk_pll_disable(struct clk_hw *hw)
+{
+	struct clk_pll *clkp = to_clk_pll(hw);
+
+	if (!clkp->seq_power_off)
+		return;
+
+	regmap_multi_reg_write(clkp->clkr.regmap, clkp->seq_power_off,
+			       clkp->num_seq_power_off);
+}
+
+static int clk_pll_is_enabled(struct clk_hw *hw)
+{
+	struct clk_pll *clkp = to_clk_pll(hw);
+
+	return is_power_on(clkp);
+}
+
+static int clk_pll_determine_rate(struct clk_hw *hw,
+				  struct clk_rate_request *req)
+{
+	struct clk_pll *clkp = to_clk_pll(hw);
+	const struct freq_table *ftblv = NULL;
+
+	ftblv = ftbl_find_by_rate(clkp->freq_tbl, req->rate);
+	if (!ftblv)
+		return -EINVAL;
+
+	req->rate = ftblv->rate;
+	return 0;
+}
+
+static unsigned long clk_pll_recalc_rate(struct clk_hw *hw,
+					 unsigned long parent_rate)
+{
+	struct clk_pll *clkp = to_clk_pll(hw);
+	const struct freq_table *fv;
+	u32 freq_val;
+
+	if (regmap_read(clkp->clkr.regmap, clkp->freq_reg, &freq_val))
+		return 0;
+
+	freq_val &= clkp->freq_mask;
+
+	fv = ftbl_find_by_val_with_mask(clkp->freq_tbl, clkp->freq_mask,
+					freq_val);
+	return fv ? fv->rate : 0;
+}
+
+static int clk_pll_set_rate(struct clk_hw *hw, unsigned long rate,
+			    unsigned long parent_rate)
+{
+	struct clk_pll *clkp = to_clk_pll(hw);
+	const struct freq_table *fv;
+	int ret;
+
+	fv = ftbl_find_by_rate(clkp->freq_tbl, rate);
+	if (!fv || fv->rate != rate)
+		return -EINVAL;
+
+	if (clkp->seq_pre_set_freq) {
+		ret = regmap_multi_reg_write(clkp->clkr.regmap, clkp->seq_pre_set_freq,
+					     clkp->num_seq_pre_set_freq);
+		if (ret)
+			return ret;
+	}
+
+	ret = regmap_update_bits(clkp->clkr.regmap, clkp->freq_reg,
+				 clkp->freq_mask, fv->val);
+	if (ret)
+		return ret;
+
+	if (clkp->seq_post_set_freq) {
+		ret = regmap_multi_reg_write(clkp->clkr.regmap, clkp->seq_post_set_freq,
+					     clkp->num_seq_post_set_freq);
+		if (ret)
+			return ret;
+	}
+
+	if (is_power_on(clkp)) {
+		ret = wait_freq_ready(clkp);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
+static int clk_pll_enable(struct clk_hw *hw)
+{
+	struct clk_pll *clkp = to_clk_pll(hw);
+	int ret;
+
+	if (!clkp->seq_power_on)
+		return 0;
+
+	if (is_power_on(clkp))
+		return 0;
+
+	ret = regmap_multi_reg_write(clkp->clkr.regmap, clkp->seq_power_on,
+				     clkp->num_seq_power_on);
+	if (ret)
+		return ret;
+
+	return wait_freq_ready(clkp);
+}
+
+const struct clk_ops rtk_clk_pll_ops = {
+	.enable         = clk_pll_enable,
+	.disable        = clk_pll_disable,
+	.is_enabled     = clk_pll_is_enabled,
+	.recalc_rate    = clk_pll_recalc_rate,
+	.determine_rate = clk_pll_determine_rate,
+	.set_rate       = clk_pll_set_rate,
+};
+EXPORT_SYMBOL_NS_GPL(rtk_clk_pll_ops, "REALTEK_CLK");
+
+const struct clk_ops rtk_clk_pll_ro_ops = {
+	.recalc_rate = clk_pll_recalc_rate,
+};
+EXPORT_SYMBOL_NS_GPL(rtk_clk_pll_ro_ops, "REALTEK_CLK");
diff --git a/drivers/clk/realtek/clk-pll.h b/drivers/clk/realtek/clk-pll.h
new file mode 100644
index 000000000000..00884585a242
--- /dev/null
+++ b/drivers/clk/realtek/clk-pll.h
@@ -0,0 +1,42 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2017-2019 Realtek Semiconductor Corporation
+ * Author: Cheng-Yu Lee <cylee12@realtek.com>
+ */
+
+#ifndef __CLK_REALTEK_CLK_PLL_H
+#define __CLK_REALTEK_CLK_PLL_H
+
+#include "common.h"
+#include "freq_table.h"
+
+struct reg_sequence;
+
+struct clk_pll {
+	struct clk_regmap clkr;
+	const struct reg_sequence *seq_power_on;
+	u32 num_seq_power_on;
+	const struct reg_sequence *seq_power_off;
+	u32 num_seq_power_off;
+	const struct reg_sequence *seq_pre_set_freq;
+	u32 num_seq_pre_set_freq;
+	const struct reg_sequence *seq_post_set_freq;
+	u32 num_seq_post_set_freq;
+	const struct freq_table *freq_tbl;
+	u32 freq_reg;
+	u32 freq_mask;
+	u32 freq_ready_valid;
+	u32 freq_ready_mask;
+	u32 freq_ready_reg;
+	u32 freq_ready_val;
+	u32 power_reg;
+	u32 power_mask;
+	u32 power_val_on;
+};
+
+#define __clk_pll_hw(_ptr)  __clk_regmap_hw(&(_ptr)->clkr)
+
+extern const struct clk_ops rtk_clk_pll_ops;
+extern const struct clk_ops rtk_clk_pll_ro_ops;
+
+#endif /* __CLK_REALTEK_CLK_PLL_H */
diff --git a/drivers/clk/realtek/freq_table.c b/drivers/clk/realtek/freq_table.c
new file mode 100644
index 000000000000..272a10e75a54
--- /dev/null
+++ b/drivers/clk/realtek/freq_table.c
@@ -0,0 +1,36 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include <linux/bitops.h>
+#include "freq_table.h"
+
+const struct freq_table *ftbl_find_by_rate(const struct freq_table *ftbl,
+					   unsigned long rate)
+{
+	unsigned long best_rate = 0;
+	const struct freq_table *best = NULL;
+
+	for (; !IS_FREQ_TABLE_END(ftbl); ftbl++) {
+		if (ftbl->rate == rate)
+			return ftbl;
+
+		if (ftbl->rate > rate)
+			continue;
+
+		if (ftbl->rate > best_rate) {
+			best_rate = ftbl->rate;
+			best = ftbl;
+		}
+	}
+
+	return best;
+}
+
+const struct freq_table *
+ftbl_find_by_val_with_mask(const struct freq_table *ftbl, u32 mask, u32 value)
+{
+	for (; !IS_FREQ_TABLE_END(ftbl); ftbl++) {
+		if ((ftbl->val & mask) == (value & mask))
+			return ftbl;
+	}
+	return NULL;
+};
diff --git a/drivers/clk/realtek/freq_table.h b/drivers/clk/realtek/freq_table.h
new file mode 100644
index 000000000000..6d9116651105
--- /dev/null
+++ b/drivers/clk/realtek/freq_table.h
@@ -0,0 +1,21 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+struct freq_table {
+	u32 val;
+	unsigned long rate;
+};
+
+/* ofs check */
+#define CLK_OFS_INVALID        -1
+#define CLK_OFS_IS_VALID(_ofs) ((_ofs) != CLK_OFS_INVALID)
+
+#define FREQ_TABLE_END    \
+	{                 \
+		.rate = 0 \
+	}
+#define IS_FREQ_TABLE_END(_f) ((_f)->rate == 0)
+
+const struct freq_table *ftbl_find_by_rate(const struct freq_table *ftbl,
+					   unsigned long rate);
+const struct freq_table *
+ftbl_find_by_val_with_mask(const struct freq_table *ftbl, u32 mask, u32 value);
-- 
2.34.1


^ permalink raw reply related

* [PATCH v6 10/10] arm64: dts: realtek: Add clock support for RTD1625
From: Yu-Chun Lin @ 2026-04-02  7:39 UTC (permalink / raw)
  To: mturquette, sboyd, robh, krzk+dt, conor+dt, p.zabel, cylee12,
	afaerber, jyanchou
  Cc: devicetree, linux-clk, linux-kernel, linux-arm-kernel,
	linux-realtek-soc, james.tai, cy.huang, stanley_chang,
	eleanor.lin
In-Reply-To: <20260402073957.2742459-1-eleanor.lin@realtek.com>

Add the clock controller nodes and osc27m fixed clock for the
Realtek RTD1625 SoC.

Signed-off-by: Yu-Chun Lin <eleanor.lin@realtek.com>
---
 arch/arm64/boot/dts/realtek/kent.dtsi | 33 +++++++++++++++++++++++++++
 1 file changed, 33 insertions(+)

diff --git a/arch/arm64/boot/dts/realtek/kent.dtsi b/arch/arm64/boot/dts/realtek/kent.dtsi
index ae006ce24420..4722337a143d 100644
--- a/arch/arm64/boot/dts/realtek/kent.dtsi
+++ b/arch/arm64/boot/dts/realtek/kent.dtsi
@@ -26,6 +26,15 @@ timer {
 			     <GIC_PPI  9 IRQ_TYPE_LEVEL_HIGH>;
 	};
 
+	clocks {
+		osc27m: osc {
+			compatible = "fixed-clock";
+			clock-frequency = <27000000>;
+			clock-output-names = "osc27m";
+			#clock-cells = <0>;
+		};
+	};
+
 	cpus {
 		#address-cells = <1>;
 		#size-cells = <0>;
@@ -141,6 +150,14 @@ rbus: bus@98000000 {
 			#address-cells = <1>;
 			#size-cells = <1>;
 
+			cc: clock-controller@0 {
+				compatible = "realtek,rtd1625-crt-clk";
+				reg = <0x0 0x900>;
+				clocks = <&osc27m>;
+				#clock-cells = <1>;
+				#reset-cells = <1>;
+			};
+
 			uart0: serial@7800 {
 				compatible = "snps,dw-apb-uart";
 				reg = <0x7800 0x100>;
@@ -150,6 +167,22 @@ uart0: serial@7800 {
 				reg-shift = <2>;
 				status = "disabled";
 			};
+
+			ic: clock-controller@7088 {
+				compatible = "realtek,rtd1625-iso-clk";
+				reg = <0x7088 0x8>;
+				clocks = <&osc27m>;
+				#clock-cells = <1>;
+				#reset-cells = <1>;
+			};
+
+			iso_s_cc: clock-controller@146310 {
+				compatible = "realtek,rtd1625-iso-s-clk";
+				reg = <0x146310 0x8>;
+				clocks = <&osc27m>;
+				#clock-cells = <1>;
+				#reset-cells = <1>;
+			};
 		};
 
 		gic: interrupt-controller@ff100000 {
-- 
2.34.1


^ permalink raw reply related

* [PATCH v6 07/10] clk: realtek: Add support for MMC-tuned PLL clocks
From: Yu-Chun Lin @ 2026-04-02  7:39 UTC (permalink / raw)
  To: mturquette, sboyd, robh, krzk+dt, conor+dt, p.zabel, cylee12,
	afaerber, jyanchou
  Cc: devicetree, linux-clk, linux-kernel, linux-arm-kernel,
	linux-realtek-soc, james.tai, cy.huang, stanley_chang,
	eleanor.lin
In-Reply-To: <20260402073957.2742459-1-eleanor.lin@realtek.com>

From: Cheng-Yu Lee <cylee12@realtek.com>

Add clk_pll_mmc_ops for enable/disable, prepare, rate control, and status
operations on MMC PLL clocks.

Also add clk_pll_mmc_phase_ops to support phase get/set operations.

Signed-off-by: Cheng-Yu Lee <cylee12@realtek.com>
Co-developed-by: Jyan Chou <jyanchou@realtek.com>
Signed-off-by: Jyan Chou <jyanchou@realtek.com>
Co-developed-by: Yu-Chun Lin <eleanor.lin@realtek.com>
Signed-off-by: Yu-Chun Lin <eleanor.lin@realtek.com>
---
Changes in v6:
- Add the headers used in c file to follow the "Include What You Use" principle.
- Move to_clk_pll_mmc() from clk-pll.h to clk-pll-mmc.c to limit its scope.
- Change offset type from int to unsigned int.
---
 MAINTAINERS                       |   8 +
 drivers/clk/realtek/Kconfig       |   3 +
 drivers/clk/realtek/Makefile      |   2 +
 drivers/clk/realtek/clk-pll-mmc.c | 410 ++++++++++++++++++++++++++++++
 drivers/clk/realtek/clk-pll.h     |  13 +
 5 files changed, 436 insertions(+)
 create mode 100644 drivers/clk/realtek/clk-pll-mmc.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 8318156a02b5..4b28af4b26b5 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -22245,6 +22245,14 @@ F:	drivers/reset/realtek/*
 F:	include/dt-bindings/clock/realtek*
 F:	include/dt-bindings/reset/realtek*
 
+REALTEK SOC PLL CLOCK FOR MMC SUPPORT
+M:	Cheng-Yu Lee <cylee12@realtek.com>
+M:	Jyan Chou <jyanchou@realtek.com>
+M:	Yu-Chun Lin <eleanor.lin@realtek.com>
+L:	linux-clk@vger.kernel.org
+S:	Supported
+F:	drivers/clk/realtek/clk-pll-mmc.c
+
 REALTEK SPI-NAND
 M:	Chris Packham <chris.packham@alliedtelesis.co.nz>
 S:	Maintained
diff --git a/drivers/clk/realtek/Kconfig b/drivers/clk/realtek/Kconfig
index bc47d3f1c452..b31a31e57b3a 100644
--- a/drivers/clk/realtek/Kconfig
+++ b/drivers/clk/realtek/Kconfig
@@ -25,4 +25,7 @@ config RTK_CLK_COMMON
 	  multiple Realtek clock implementations, and include integration
 	  with reset controllers where required.
 
+config RTK_CLK_PLL_MMC
+	bool
+
 endif
diff --git a/drivers/clk/realtek/Makefile b/drivers/clk/realtek/Makefile
index f90dc57fcfdb..fd7d777902c8 100644
--- a/drivers/clk/realtek/Makefile
+++ b/drivers/clk/realtek/Makefile
@@ -7,3 +7,5 @@ clk-rtk-y += clk-pll.o
 clk-rtk-y += clk-regmap-gate.o
 clk-rtk-y += clk-regmap-mux.o
 clk-rtk-y += freq_table.o
+
+clk-rtk-$(CONFIG_RTK_CLK_PLL_MMC) += clk-pll-mmc.o
diff --git a/drivers/clk/realtek/clk-pll-mmc.c b/drivers/clk/realtek/clk-pll-mmc.c
new file mode 100644
index 000000000000..d28c7027d3f0
--- /dev/null
+++ b/drivers/clk/realtek/clk-pll-mmc.c
@@ -0,0 +1,410 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2021 Realtek Semiconductor Corporation
+ * Author: Cheng-Yu Lee <cylee12@realtek.com>
+ */
+
+#include <linux/bits.h>
+#include <linux/module.h>
+#include <linux/regmap.h>
+#include "clk-pll.h"
+
+#define PLL_EMMC1_OFFSET           0x0
+#define PLL_EMMC2_OFFSET           0x4
+#define PLL_EMMC3_OFFSET           0x8
+#define PLL_EMMC4_OFFSET           0xc
+#define PLL_SSC_DIG_EMMC1_OFFSET   0x0
+#define PLL_SSC_DIG_EMMC3_OFFSET   0xc
+#define PLL_SSC_DIG_EMMC4_OFFSET   0x10
+
+#define PLL_MMC_SSC_DIV_N_VAL      0x1b
+
+#define PLL_PHRT0_MASK             BIT(1)
+#define PLL_PHSEL_MASK             GENMASK(4, 0)
+#define PLL_SSCPLL_RS_MASK         GENMASK(12, 10)
+#define PLL_SSCPLL_ICP_MASK        GENMASK(9, 5)
+#define PLL_SSC_DIV_EXT_F_MASK     GENMASK(25, 13)
+#define PLL_PI_IBSELH_MASK         GENMASK(28, 27)
+#define PLL_SSC_DIV_N_MASK         GENMASK(23, 16)
+#define PLL_NCODE_SSC_EMMC_MASK    GENMASK(20, 13)
+#define PLL_FCODE_SSC_EMMC_MASK    GENMASK(12, 0)
+#define PLL_GRAN_EST_EM_MC_MASK    GENMASK(20, 0)
+#define PLL_EN_SSC_EMMC_MASK       BIT(0)
+#define PLL_FLAG_INITAL_EMMC_MASK  BIT(1)
+
+#define PLL_PHRT0_SHIFT            1
+#define PLL_SSCPLL_RS_SHIFT        10
+#define PLL_SSCPLL_ICP_SHIFT       5
+#define PLL_SSC_DIV_EXT_F_SHIFT    13
+#define PLL_PI_IBSELH_SHIFT        27
+#define PLL_SSC_DIV_N_SHIFT        16
+#define PLL_NCODE_SSC_EMMC_SHIFT   13
+#define PLL_FLAG_INITAL_EMMC_SHIFT 8
+
+#define CYCLE_DEGREES              360
+#define PHASE_STEPS                32
+#define PHASE_SCALE_FACTOR         1125
+
+static inline struct clk_pll_mmc *to_clk_pll_mmc(struct clk_hw *hw)
+{
+	struct clk_regmap *clkr = to_clk_regmap(hw);
+
+	return container_of(clkr, struct clk_pll_mmc, clkr);
+}
+
+static inline int get_phrt0(struct clk_pll_mmc *clkm, u32 *val)
+{
+	u32 reg;
+	int ret;
+
+	ret = regmap_read(clkm->clkr.regmap, clkm->pll_ofs + PLL_EMMC1_OFFSET, &reg);
+	if (ret)
+		return ret;
+
+	*val = (reg >> PLL_PHRT0_SHIFT) & PLL_PHRT0_MASK;
+	return 0;
+}
+
+static inline int set_phrt0(struct clk_pll_mmc *clkm, u32 val)
+{
+	return regmap_update_bits(clkm->clkr.regmap, clkm->pll_ofs + PLL_EMMC1_OFFSET,
+				  PLL_PHRT0_MASK, val << PLL_PHRT0_SHIFT);
+}
+
+static inline int get_phsel(struct clk_pll_mmc *clkm, int id, u32 *val)
+{
+	int ret;
+	u32 raw_val;
+	u32 sft = id ? 8 : 3;
+
+	ret = regmap_read(clkm->clkr.regmap, clkm->pll_ofs + PLL_EMMC1_OFFSET, &raw_val);
+	if (ret)
+		return ret;
+
+	*val = (raw_val >> sft) & PLL_PHSEL_MASK;
+	return 0;
+}
+
+static inline int set_phsel(struct clk_pll_mmc *clkm, int id, u32 val)
+{
+	u32 sft = id ? 8 : 3;
+
+	return regmap_update_bits(clkm->clkr.regmap, clkm->pll_ofs + PLL_EMMC1_OFFSET,
+				  PLL_PHSEL_MASK << sft, val << sft);
+}
+
+static inline int set_sscpll_rs(struct clk_pll_mmc *clkm, u32 val)
+{
+	return regmap_update_bits(clkm->clkr.regmap, clkm->pll_ofs + PLL_EMMC2_OFFSET,
+				  PLL_SSCPLL_RS_MASK, val << PLL_SSCPLL_RS_SHIFT);
+}
+
+static inline int set_sscpll_icp(struct clk_pll_mmc *clkm, u32 val)
+{
+	return regmap_update_bits(clkm->clkr.regmap, clkm->pll_ofs + PLL_EMMC2_OFFSET,
+				  PLL_SSCPLL_ICP_MASK, val << PLL_SSCPLL_ICP_SHIFT);
+}
+
+static inline int get_ssc_div_ext_f(struct clk_pll_mmc *clkm, u32 *val)
+{
+	u32 raw_val;
+	int ret;
+
+	ret = regmap_read(clkm->clkr.regmap, clkm->pll_ofs + PLL_EMMC2_OFFSET, &raw_val);
+	if (ret)
+		return ret;
+
+	*val = (raw_val & PLL_SSC_DIV_EXT_F_MASK) >> PLL_SSC_DIV_EXT_F_SHIFT;
+	return 0;
+}
+
+static inline int set_ssc_div_ext_f(struct clk_pll_mmc *clkm, u32 val)
+{
+	return regmap_update_bits(clkm->clkr.regmap, clkm->pll_ofs + PLL_EMMC2_OFFSET,
+				  PLL_SSC_DIV_EXT_F_MASK,
+				  val << PLL_SSC_DIV_EXT_F_SHIFT);
+}
+
+static inline int set_pi_ibselh(struct clk_pll_mmc *clkm, u32 val)
+{
+	return regmap_update_bits(clkm->clkr.regmap, clkm->pll_ofs + PLL_EMMC2_OFFSET,
+				  PLL_PI_IBSELH_MASK, val << PLL_PI_IBSELH_SHIFT);
+}
+
+static inline int set_ssc_div_n(struct clk_pll_mmc *clkm, u32 val)
+{
+	return regmap_update_bits(clkm->clkr.regmap, clkm->pll_ofs + PLL_EMMC3_OFFSET,
+				  PLL_SSC_DIV_N_MASK, val << PLL_SSC_DIV_N_SHIFT);
+}
+
+static inline int get_ssc_div_n(struct clk_pll_mmc *clkm, u32 *val)
+{
+	int ret;
+	u32 raw_val;
+
+	ret = regmap_read(clkm->clkr.regmap, clkm->pll_ofs + PLL_EMMC3_OFFSET, &raw_val);
+	if (ret)
+		return ret;
+
+	*val = (raw_val & PLL_SSC_DIV_N_MASK) >> PLL_SSC_DIV_N_SHIFT;
+	return 0;
+}
+
+static inline int set_pow_ctl(struct clk_pll_mmc *clkm, u32 val)
+{
+	return regmap_write(clkm->clkr.regmap, clkm->pll_ofs + PLL_EMMC4_OFFSET, val);
+}
+
+static inline int get_pow_ctl(struct clk_pll_mmc *clkm, u32 *val)
+{
+	int ret;
+	u32 raw_val;
+
+	ret = regmap_read(clkm->clkr.regmap, clkm->pll_ofs + PLL_EMMC4_OFFSET, &raw_val);
+	if (ret)
+		return ret;
+
+	*val = raw_val;
+
+	return 0;
+}
+
+static int clk_pll_mmc_phase_set_phase(struct clk_hw *hw, int degrees)
+{
+	struct clk_hw *hwp = clk_hw_get_parent(hw);
+	struct clk_pll_mmc *clkm;
+	int phase_id;
+	int ret;
+	u32 val;
+
+	if (!hwp)
+		return -ENOENT;
+
+	clkm = to_clk_pll_mmc(hwp);
+	phase_id = (hw - &clkm->phase0_hw) ? 1 : 0;
+	val = DIV_ROUND_CLOSEST(degrees * 100, PHASE_SCALE_FACTOR);
+	ret = set_phsel(clkm, phase_id, val);
+	if (ret)
+		return ret;
+
+	usleep_range(10, 20);
+	return 0;
+}
+
+static int clk_pll_mmc_phase_get_phase(struct clk_hw *hw)
+{
+	struct clk_hw *hwp;
+	struct clk_pll_mmc *clkm;
+	int phase_id;
+	int ret;
+	u32 val;
+
+	hwp = clk_hw_get_parent(hw);
+	if (!hwp)
+		return -ENOENT;
+
+	clkm = to_clk_pll_mmc(hwp);
+	phase_id = (hw - &clkm->phase0_hw) ? 1 : 0;
+	ret = get_phsel(clkm, phase_id, &val);
+	if (ret)
+		return ret;
+
+	val = DIV_ROUND_CLOSEST(val * CYCLE_DEGREES, PHASE_STEPS);
+
+	return val;
+}
+
+const struct clk_ops rtk_clk_pll_mmc_phase_ops = {
+	.set_phase = clk_pll_mmc_phase_set_phase,
+	.get_phase = clk_pll_mmc_phase_get_phase,
+};
+EXPORT_SYMBOL_NS_GPL(rtk_clk_pll_mmc_phase_ops, "REALTEK_CLK");
+
+static int clk_pll_mmc_prepare(struct clk_hw *hw)
+{
+	struct clk_pll_mmc *clkm = to_clk_pll_mmc(hw);
+
+	return set_pow_ctl(clkm, 7);
+}
+
+static void clk_pll_mmc_unprepare(struct clk_hw *hw)
+{
+	struct clk_pll_mmc *clkm = to_clk_pll_mmc(hw);
+
+	set_pow_ctl(clkm, 0);
+}
+
+static int clk_pll_mmc_is_prepared(struct clk_hw *hw)
+{
+	struct clk_pll_mmc *clkm = to_clk_pll_mmc(hw);
+	u32 val;
+	int ret;
+
+	ret = get_pow_ctl(clkm, &val);
+	if (ret)
+		return 1;
+
+	return val != 0x0;
+}
+
+static int clk_pll_mmc_enable(struct clk_hw *hw)
+{
+	struct clk_pll_mmc *clkm = to_clk_pll_mmc(hw);
+	int ret;
+
+	ret = set_phrt0(clkm, 1);
+	if (ret)
+		return ret;
+
+	udelay(10);
+	return 0;
+}
+
+static void clk_pll_mmc_disable(struct clk_hw *hw)
+{
+	struct clk_pll_mmc *clkm = to_clk_pll_mmc(hw);
+
+	set_phrt0(clkm, 0);
+	udelay(10);
+}
+
+static int clk_pll_mmc_is_enabled(struct clk_hw *hw)
+{
+	struct clk_pll_mmc *clkm = to_clk_pll_mmc(hw);
+	u32 val;
+	int ret;
+
+	ret = get_phrt0(clkm, &val);
+	if (ret)
+		return 1;
+
+	return val == 0x1;
+}
+
+static unsigned long clk_pll_mmc_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
+{
+	struct clk_pll_mmc *clkm = to_clk_pll_mmc(hw);
+	u32 val, ext_f;
+	int ret;
+
+	ret = get_ssc_div_n(clkm, &val);
+	if (ret)
+		return ret;
+
+	ret = get_ssc_div_ext_f(clkm, &ext_f);
+	if (ret)
+		return ret;
+
+	return parent_rate / 4 * (val + 2) + (parent_rate / 4 * ext_f) / 8192;
+}
+
+static int clk_pll_mmc_determine_rate(struct clk_hw *hw, struct clk_rate_request *req)
+{
+	u32 val = DIV_ROUND_CLOSEST(req->rate * 4, req->best_parent_rate);
+
+	req->rate = req->best_parent_rate * val / 4;
+	return 0;
+}
+
+static int clk_pll_mmc_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long parent_rate)
+{
+	struct clk_pll_mmc *clkm = to_clk_pll_mmc(hw);
+	u32 val = PLL_MMC_SSC_DIV_N_VAL;
+	int ret;
+
+	ret = regmap_update_bits(clkm->clkr.regmap,
+				 clkm->ssc_dig_ofs + PLL_SSC_DIG_EMMC1_OFFSET,
+				 PLL_FLAG_INITAL_EMMC_MASK, 0x0 << PLL_FLAG_INITAL_EMMC_SHIFT);
+	if (ret)
+		return ret;
+
+	ret = set_ssc_div_n(clkm, val);
+	if (ret)
+		return ret;
+
+	ret = set_ssc_div_ext_f(clkm, 1517);
+	if (ret)
+		return ret;
+
+	switch (val) {
+	case 31 ... 46:
+		ret |= set_pi_ibselh(clkm, 3);
+		ret |= set_sscpll_rs(clkm, 3);
+		ret |= set_sscpll_icp(clkm, 2);
+		break;
+
+	case 20 ... 30:
+		ret |= set_pi_ibselh(clkm, 2);
+		ret |= set_sscpll_rs(clkm, 3);
+		ret |= set_sscpll_icp(clkm, 1);
+		break;
+
+	case 10 ... 19:
+		ret |= set_pi_ibselh(clkm, 1);
+		ret |= set_sscpll_rs(clkm, 2);
+		ret |= set_sscpll_icp(clkm, 1);
+		break;
+
+	case 5 ... 9:
+		ret |= set_pi_ibselh(clkm, 0);
+		ret |= set_sscpll_rs(clkm, 2);
+		ret |= set_sscpll_icp(clkm, 0);
+		break;
+	}
+	if (ret)
+		return ret;
+
+	ret = regmap_update_bits(clkm->clkr.regmap,
+				 clkm->ssc_dig_ofs + PLL_SSC_DIG_EMMC3_OFFSET,
+				 PLL_NCODE_SSC_EMMC_MASK,
+				 27 << PLL_NCODE_SSC_EMMC_SHIFT);
+	if (ret)
+		return ret;
+
+	ret = regmap_update_bits(clkm->clkr.regmap,
+				 clkm->ssc_dig_ofs + PLL_SSC_DIG_EMMC3_OFFSET,
+				 PLL_FCODE_SSC_EMMC_MASK, 321);
+	if (ret)
+		return ret;
+
+	ret = regmap_update_bits(clkm->clkr.regmap,
+				 clkm->ssc_dig_ofs + PLL_SSC_DIG_EMMC4_OFFSET,
+				 PLL_GRAN_EST_EM_MC_MASK, 5985);
+	if (ret)
+		return ret;
+
+	ret = regmap_update_bits(clkm->clkr.regmap,
+				 clkm->ssc_dig_ofs + PLL_SSC_DIG_EMMC1_OFFSET,
+				 PLL_EN_SSC_EMMC_MASK, 0x1);
+	if (ret)
+		return ret;
+
+	ret = regmap_update_bits(clkm->clkr.regmap,
+				 clkm->ssc_dig_ofs + PLL_SSC_DIG_EMMC1_OFFSET,
+				 PLL_EN_SSC_EMMC_MASK, 0x0);
+	if (ret)
+		return ret;
+
+	ret = regmap_update_bits(clkm->clkr.regmap,
+				 clkm->ssc_dig_ofs + PLL_SSC_DIG_EMMC1_OFFSET,
+				 PLL_FLAG_INITAL_EMMC_MASK,
+				 0x1 << PLL_FLAG_INITAL_EMMC_SHIFT);
+	if (ret)
+		return ret;
+
+	usleep_range(10, 20);
+	return 0;
+}
+
+const struct clk_ops rtk_clk_pll_mmc_ops = {
+	.prepare          = clk_pll_mmc_prepare,
+	.unprepare        = clk_pll_mmc_unprepare,
+	.is_prepared      = clk_pll_mmc_is_prepared,
+	.enable           = clk_pll_mmc_enable,
+	.disable          = clk_pll_mmc_disable,
+	.is_enabled       = clk_pll_mmc_is_enabled,
+	.recalc_rate      = clk_pll_mmc_recalc_rate,
+	.determine_rate   = clk_pll_mmc_determine_rate,
+	.set_rate         = clk_pll_mmc_set_rate,
+};
+EXPORT_SYMBOL_NS_GPL(rtk_clk_pll_mmc_ops, "REALTEK_CLK");
diff --git a/drivers/clk/realtek/clk-pll.h b/drivers/clk/realtek/clk-pll.h
index 00884585a242..033c982e1eb1 100644
--- a/drivers/clk/realtek/clk-pll.h
+++ b/drivers/clk/realtek/clk-pll.h
@@ -39,4 +39,17 @@ struct clk_pll {
 extern const struct clk_ops rtk_clk_pll_ops;
 extern const struct clk_ops rtk_clk_pll_ro_ops;
 
+struct clk_pll_mmc {
+	struct clk_regmap clkr;
+	unsigned int pll_ofs;
+	unsigned int ssc_dig_ofs;
+	struct clk_hw phase0_hw;
+	struct clk_hw phase1_hw;
+};
+
+#define __clk_pll_mmc_hw(_ptr)  __clk_regmap_hw(&(_ptr)->clkr)
+
+extern const struct clk_ops rtk_clk_pll_mmc_ops;
+extern const struct clk_ops rtk_clk_pll_mmc_phase_ops;
+
 #endif /* __CLK_REALTEK_CLK_PLL_H */
-- 
2.34.1


^ permalink raw reply related

* [PATCH v6 01/10] dt-bindings: clock: Add Realtek RTD1625 Clock & Reset Controller
From: Yu-Chun Lin @ 2026-04-02  7:39 UTC (permalink / raw)
  To: mturquette, sboyd, robh, krzk+dt, conor+dt, p.zabel, cylee12,
	afaerber, jyanchou
  Cc: devicetree, linux-clk, linux-kernel, linux-arm-kernel,
	linux-realtek-soc, james.tai, cy.huang, stanley_chang,
	eleanor.lin, Krzysztof Kozlowski
In-Reply-To: <20260402073957.2742459-1-eleanor.lin@realtek.com>

Add DT binding schema for Realtek RTD1625 clock and reset controller

Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
Co-developed-by: Cheng-Yu Lee <cylee12@realtek.com>
Signed-off-by: Cheng-Yu Lee <cylee12@realtek.com>
Signed-off-by: Yu-Chun Lin <eleanor.lin@realtek.com>
---
Changes in v6:
- Add reviewed-by tag from Krzysztof.
- Add Cheng-Yu Lee as maintainer in the binding file.
- Add 'clocks' property.
- Add include/dt-bindings/reset/realtek,rtd1625.h to the MAINTAINERS file.
---
 .../bindings/clock/realtek,rtd1625-clk.yaml   |  58 ++++++
 MAINTAINERS                                   |  10 +
 .../dt-bindings/clock/realtek,rtd1625-clk.h   | 164 +++++++++++++++++
 include/dt-bindings/reset/realtek,rtd1625.h   | 171 ++++++++++++++++++
 4 files changed, 403 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/realtek,rtd1625-clk.yaml
 create mode 100644 include/dt-bindings/clock/realtek,rtd1625-clk.h
 create mode 100644 include/dt-bindings/reset/realtek,rtd1625.h

diff --git a/Documentation/devicetree/bindings/clock/realtek,rtd1625-clk.yaml b/Documentation/devicetree/bindings/clock/realtek,rtd1625-clk.yaml
new file mode 100644
index 000000000000..1aceef31e148
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/realtek,rtd1625-clk.yaml
@@ -0,0 +1,58 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/realtek,rtd1625-clk.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Realtek RTD1625 Clock & Reset Controller
+
+maintainers:
+  - Cheng-Yu Lee <cylee12@realtek.com>
+  - Yu-Chun Lin <eleanor.lin@realtek.com>
+
+description: |
+  The Realtek RTD1625 Clock Controller manages and distributes clock
+  signals to various controllers and implements a Reset Controller for the
+  SoC peripherals.
+
+  Clocks and resets are referenced by unique identifiers, which are defined as
+  preprocessor macros in include/dt-bindings/clock/realtek,rtd1625-clk.h and
+  include/dt-bindings/reset/realtek,rtd1625.h.
+
+properties:
+  compatible:
+    enum:
+      - realtek,rtd1625-crt-clk
+      - realtek,rtd1625-iso-clk
+      - realtek,rtd1625-iso-s-clk
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+  "#clock-cells":
+    const: 1
+
+  "#reset-cells":
+    const: 1
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - "#clock-cells"
+  - "#reset-cells"
+
+additionalProperties: false
+
+examples:
+  - |
+    clock-controller@98000000 {
+      compatible = "realtek,rtd1625-crt-clk";
+      reg = <0x98000000 0x1000>;
+      clocks = <&osc27m>;
+      #clock-cells = <1>;
+      #reset-cells = <1>;
+    };
diff --git a/MAINTAINERS b/MAINTAINERS
index c3fe46d7c4bc..07e73bf621b0 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -22233,6 +22233,16 @@ S:	Maintained
 F:	Documentation/devicetree/bindings/net/dsa/realtek.yaml
 F:	drivers/net/dsa/realtek/*
 
+REALTEK SOC CLOCK AND RESET DRIVERS
+M:	Cheng-Yu Lee <cylee12@realtek.com>
+M:	Yu-Chun Lin <eleanor.lin@realtek.com>
+L:	devicetree@vger.kernel.org
+L:	linux-clk@vger.kernel.org
+S:	Supported
+F:	Documentation/devicetree/bindings/clock/realtek*
+F:	include/dt-bindings/clock/realtek*
+F:	include/dt-bindings/reset/realtek*
+
 REALTEK SPI-NAND
 M:	Chris Packham <chris.packham@alliedtelesis.co.nz>
 S:	Maintained
diff --git a/include/dt-bindings/clock/realtek,rtd1625-clk.h b/include/dt-bindings/clock/realtek,rtd1625-clk.h
new file mode 100644
index 000000000000..61ca652d6880
--- /dev/null
+++ b/include/dt-bindings/clock/realtek,rtd1625-clk.h
@@ -0,0 +1,164 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+/*
+ * Copyright (C) 2025 Realtek Semiconductor Corp.
+ */
+#ifndef __DT_BINDINGS_RTK_CLOCK_RTD1625_H
+#define __DT_BINDINGS_RTK_CLOCK_RTD1625_H
+
+#define RTD1625_CRT_CLK_EN_MISC           0
+#define RTD1625_CRT_CLK_EN_PCIE0          1
+#define RTD1625_CRT_CLK_EN_DIP            2
+#define RTD1625_CRT_CLK_EN_GSPI           3
+#define RTD1625_CRT_CLK_EN_ISO_MISC       5
+#define RTD1625_CRT_CLK_EN_SDS            6
+#define RTD1625_CRT_CLK_EN_HDMI           7
+#define RTD1625_CRT_CLK_EN_GPU            9
+#define RTD1625_CRT_CLK_EN_VE1            10
+#define RTD1625_CRT_CLK_EN_VE2            11
+#define RTD1625_CRT_CLK_EN_MD             18
+#define RTD1625_CRT_CLK_EN_TP             19
+#define RTD1625_CRT_CLK_EN_RCIC           20
+#define RTD1625_CRT_CLK_EN_NF             21
+#define RTD1625_CRT_CLK_EN_EMMC           22
+#define RTD1625_CRT_CLK_EN_SD             23
+#define RTD1625_CRT_CLK_EN_SDIO_IP        24
+#define RTD1625_CRT_CLK_EN_MIPI_CSI       25
+#define RTD1625_CRT_CLK_EN_EMMC_IP        26
+#define RTD1625_CRT_CLK_EN_SDIO           27
+#define RTD1625_CRT_CLK_EN_SD_IP          28
+#define RTD1625_CRT_CLK_EN_TPB            30
+#define RTD1625_CRT_CLK_EN_MISC_SC1       31
+#define RTD1625_CRT_CLK_EN_MISC_I2C_3     32
+#define RTD1625_CRT_CLK_EN_ACPU           33
+#define RTD1625_CRT_CLK_EN_JPEG           34
+#define RTD1625_CRT_CLK_EN_MISC_SC0       37
+#define RTD1625_CRT_CLK_EN_HDMIRX         45
+#define RTD1625_CRT_CLK_EN_HSE            46
+#define RTD1625_CRT_CLK_EN_FAN            49
+#define RTD1625_CRT_CLK_EN_SATA_WRAP_SYS  52
+#define RTD1625_CRT_CLK_EN_SATA_WRAP_SYSH 53
+#define RTD1625_CRT_CLK_EN_SATA_MAC_SYSH  54
+#define RTD1625_CRT_CLK_EN_R2RDSC         55
+#define RTD1625_CRT_CLK_EN_TPC            56
+#define RTD1625_CRT_CLK_EN_PCIE1          57
+#define RTD1625_CRT_CLK_EN_MISC_I2C_4     58
+#define RTD1625_CRT_CLK_EN_MISC_I2C_5     59
+#define RTD1625_CRT_CLK_EN_TSIO           60
+#define RTD1625_CRT_CLK_EN_VE4            61
+#define RTD1625_CRT_CLK_EN_EDP            62
+#define RTD1625_CRT_CLK_EN_TSIO_TRX       63
+#define RTD1625_CRT_CLK_EN_PCIE2          64
+#define RTD1625_CRT_CLK_EN_EARC           66
+#define RTD1625_CRT_CLK_EN_LITE           67
+#define RTD1625_CRT_CLK_EN_MIPI_DSI       68
+#define RTD1625_CRT_CLK_EN_NPUPP          69
+#define RTD1625_CRT_CLK_EN_NPU            70
+#define RTD1625_CRT_CLK_EN_AUCPU0         71
+#define RTD1625_CRT_CLK_EN_AUCPU1         72
+#define RTD1625_CRT_CLK_EN_NSRAM          73
+#define RTD1625_CRT_CLK_EN_HDMITOP        74
+#define RTD1625_CRT_CLK_EN_AUCPU_ISO_NPU  76
+#define RTD1625_CRT_CLK_EN_KEYLADDER      77
+#define RTD1625_CRT_CLK_EN_IFCP_KLM       78
+#define RTD1625_CRT_CLK_EN_IFCP           79
+#define RTD1625_CRT_CLK_EN_MDL_GENPW      80
+#define RTD1625_CRT_CLK_EN_MDL_CHIP       81
+#define RTD1625_CRT_CLK_EN_MDL_IP         82
+#define RTD1625_CRT_CLK_EN_MDLM2M         83
+#define RTD1625_CRT_CLK_EN_MDL_XTAL       84
+#define RTD1625_CRT_CLK_EN_TEST_MUX       85
+#define RTD1625_CRT_CLK_EN_DLA            86
+#define RTD1625_CRT_CLK_EN_TPCW           88
+#define RTD1625_CRT_CLK_EN_GPU_TS_SRC     89
+#define RTD1625_CRT_CLK_EN_VI             91
+#define RTD1625_CRT_CLK_EN_LVDS1          92
+#define RTD1625_CRT_CLK_EN_LVDS2          93
+#define RTD1625_CRT_CLK_EN_AUCPU          94
+#define RTD1625_CRT_CLK_EN_UR1            96
+#define RTD1625_CRT_CLK_EN_UR2            97
+#define RTD1625_CRT_CLK_EN_UR3            98
+#define RTD1625_CRT_CLK_EN_UR4            99
+#define RTD1625_CRT_CLK_EN_UR5            100
+#define RTD1625_CRT_CLK_EN_UR6            101
+#define RTD1625_CRT_CLK_EN_UR7            102
+#define RTD1625_CRT_CLK_EN_UR8            103
+#define RTD1625_CRT_CLK_EN_UR9            104
+#define RTD1625_CRT_CLK_EN_UR_TOP         105
+#define RTD1625_CRT_CLK_EN_MISC_I2C_7     110
+#define RTD1625_CRT_CLK_EN_MISC_I2C_6     111
+#define RTD1625_CRT_CLK_EN_SPI0           112
+#define RTD1625_CRT_CLK_EN_SPI1           113
+#define RTD1625_CRT_CLK_EN_SPI2           114
+#define RTD1625_CRT_CLK_EN_LSADC0         120
+#define RTD1625_CRT_CLK_EN_LSADC1         121
+#define RTD1625_CRT_CLK_EN_ISOMIS_DMA     122
+#define RTD1625_CRT_CLK_EN_DPTX           124
+#define RTD1625_CRT_CLK_EN_NPU_MIPI_CSI   125
+#define RTD1625_CRT_CLK_EN_EDPTX          126
+#define RTD1625_CRT_CLK_HIFI              128
+#define RTD1625_CRT_CLK_NPU_MIPI_CSI      129
+#define RTD1625_CRT_CLK_NPU               130
+#define RTD1625_CRT_CLK_NPU_SYSH          132
+#define RTD1625_CRT_CLK_HIFI_SCPU         133
+#define RTD1625_CRT_CLK_GPU               134
+#define RTD1625_CRT_CLK_GPU2D             135
+#define RTD1625_CRT_CLK_MIPI_DSI_PCLK     136
+#define RTD1625_CRT_CLK_VE1               137
+#define RTD1625_CRT_CLK_VE2               138
+#define RTD1625_CRT_CLK_VE4               139
+#define RTD1625_CRT_CLK_SYS               141
+#define RTD1625_CRT_CLK_SYSH              142
+#define RTD1625_CRT_PLL_SDIO_REF          145
+#define RTD1625_CRT_PLL_CR_REF            146
+#define RTD1625_CRT_PLL_EMMC_REF          147
+#define RTD1625_CRT_CLK_MIS_SC0           148
+#define RTD1625_CRT_CLK_MIS_SC1           149
+#define RTD1625_CRT_PLL_SCPU              150
+#define RTD1625_CRT_PLL_VE1               151
+#define RTD1625_CRT_PLL_DDSA              152
+#define RTD1625_CRT_PLL_PSAUDA1           153
+#define RTD1625_CRT_PLL_PSAUDA2           154
+#define RTD1625_CRT_PLL_BUS               155
+#define RTD1625_CRT_PLL_SDIO              156
+#define RTD1625_CRT_PLL_SDIO_VP0          157
+#define RTD1625_CRT_PLL_SDIO_VP1          158
+#define RTD1625_CRT_PLL_DCSB              159
+#define RTD1625_CRT_PLL_GPU               160
+#define RTD1625_CRT_PLL_NPU               161
+#define RTD1625_CRT_PLL_VE2               162
+#define RTD1625_CRT_PLL_HIFI              163
+#define RTD1625_CRT_PLL_SD                164
+#define RTD1625_CRT_PLL_SD_VP0            165
+#define RTD1625_CRT_PLL_SD_VP1            166
+#define RTD1625_CRT_PLL_EMMC              167
+#define RTD1625_CRT_PLL_EMMC_VP0          168
+#define RTD1625_CRT_PLL_EMMC_VP1          169
+#define RTD1625_CRT_PLL_ACPU              170
+#define RTD1625_CRT_CLK_DET               171
+
+#define RTD1625_ISO_CLK_EN_USB_P4         0
+#define RTD1625_ISO_CLK_EN_USB_P3         1
+#define RTD1625_ISO_CLK_EN_MISC_CEC0      2
+#define RTD1625_ISO_CLK_EN_CBUSRX_SYS     3
+#define RTD1625_ISO_CLK_EN_CBUSTX_SYS     4
+#define RTD1625_ISO_CLK_EN_CBUS_SYS       5
+#define RTD1625_ISO_CLK_EN_CBUS_OSC       6
+#define RTD1625_ISO_CLK_EN_MISC_UR0       8
+#define RTD1625_ISO_CLK_EN_I2C0           9
+#define RTD1625_ISO_CLK_EN_I2C1           10
+#define RTD1625_ISO_CLK_EN_ETN_250M       11
+#define RTD1625_ISO_CLK_EN_ETN_SYS        12
+#define RTD1625_ISO_CLK_EN_USB_DRD        13
+#define RTD1625_ISO_CLK_EN_USB_HOST       14
+#define RTD1625_ISO_CLK_EN_USB_U3_HOST    15
+#define RTD1625_ISO_CLK_EN_USB            16
+#define RTD1625_ISO_CLK_EN_VTC            17
+#define RTD1625_ISO_CLK_EN_MISC_VFD       18
+
+#define RTD1625_ISO_S_CLK_EN_ISOM_MIS     0
+#define RTD1625_ISO_S_CLK_EN_ISOM_GPIOM   1
+#define RTD1625_ISO_S_CLK_EN_TIMER7       2
+#define RTD1625_ISO_S_CLK_EN_IRDA         3
+#define RTD1625_ISO_S_CLK_EN_UR10         4
+
+#endif /* __DT_BINDINGS_RTK_CLOCK_RTD1625_H */
diff --git a/include/dt-bindings/reset/realtek,rtd1625.h b/include/dt-bindings/reset/realtek,rtd1625.h
new file mode 100644
index 000000000000..31e7fa66ef31
--- /dev/null
+++ b/include/dt-bindings/reset/realtek,rtd1625.h
@@ -0,0 +1,171 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+/*
+ * Copyright (C)		2025 Realtek Semiconductor Corp.
+ */
+
+#ifndef __DT_BINDINGS_RTK_RESET_RTD1625_H
+#define __DT_BINDINGS_RTK_RESET_RTD1625_H
+
+#define RTD1625_CRT_RSTN_MISC			0
+#define RTD1625_CRT_RSTN_DIP			1
+#define RTD1625_CRT_RSTN_GSPI			2
+#define RTD1625_CRT_RSTN_SDS			3
+#define RTD1625_CRT_RSTN_SDS_REG		4
+#define RTD1625_CRT_RSTN_SDS_PHY		5
+#define RTD1625_CRT_RSTN_GPU2D			6
+#define RTD1625_CRT_RSTN_DC_PHY			7
+#define RTD1625_CRT_RSTN_DCPHY_CRT		8
+#define RTD1625_CRT_RSTN_LSADC			9
+#define RTD1625_CRT_RSTN_SE			10
+#define RTD1625_CRT_RSTN_DLA			11
+#define RTD1625_CRT_RSTN_JPEG			12
+#define RTD1625_CRT_RSTN_SD			13
+#define RTD1625_CRT_RSTN_SDIO			14
+#define RTD1625_CRT_RSTN_PCR_CNT		15
+#define RTD1625_CRT_RSTN_PCIE0_STITCH		16
+#define RTD1625_CRT_RSTN_PCIE0_PHY		17
+#define RTD1625_CRT_RSTN_PCIE0			18
+#define RTD1625_CRT_RSTN_PCIE0_CORE		19
+#define RTD1625_CRT_RSTN_PCIE0_POWER		20
+#define RTD1625_CRT_RSTN_PCIE0_NONSTICH		21
+#define RTD1625_CRT_RSTN_PCIE0_PHY_MDIO		22
+#define RTD1625_CRT_RSTN_PCIE0_SGMII_MDIO	23
+#define RTD1625_CRT_RSTN_VO2			24
+#define RTD1625_CRT_RSTN_MISC_SC0		25
+#define RTD1625_CRT_RSTN_MD			26
+#define RTD1625_CRT_RSTN_LVDS1			27
+#define RTD1625_CRT_RSTN_LVDS2			28
+#define RTD1625_CRT_RSTN_MISC_SC1		29
+#define RTD1625_CRT_RSTN_I2C_3			30
+#define RTD1625_CRT_RSTN_FAN			31
+#define RTD1625_CRT_RSTN_TVE			32
+#define RTD1625_CRT_RSTN_AIO			33
+#define RTD1625_CRT_RSTN_VO			34
+#define RTD1625_CRT_RSTN_MIPI_CSI		35
+#define RTD1625_CRT_RSTN_HDMIRX			36
+#define RTD1625_CRT_RSTN_HDMIRX_WRAP		37
+#define RTD1625_CRT_RSTN_HDMI			38
+#define RTD1625_CRT_RSTN_DISP			39
+#define RTD1625_CRT_RSTN_SATA_PHY_POW1		40
+#define RTD1625_CRT_RSTN_SATA_PHY_POW0		41
+#define RTD1625_CRT_RSTN_SATA_MDIO1		42
+#define RTD1625_CRT_RSTN_SATA_MDIO0		43
+#define RTD1625_CRT_RSTN_SATA_WRAP		44
+#define RTD1625_CRT_RSTN_SATA_MAC_P1		45
+#define RTD1625_CRT_RSTN_SATA_MAC_P0		46
+#define RTD1625_CRT_RSTN_SATA_MAC_COM		47
+#define RTD1625_CRT_RSTN_PCIE1_STITCH		48
+#define RTD1625_CRT_RSTN_PCIE1_PHY		49
+#define RTD1625_CRT_RSTN_PCIE1			50
+#define RTD1625_CRT_RSTN_PCIE1_CORE		51
+#define RTD1625_CRT_RSTN_PCIE1_POWER		52
+#define RTD1625_CRT_RSTN_PCIE1_NONSTICH		53
+#define RTD1625_CRT_RSTN_PCIE1_PHY_MDIO		54
+#define RTD1625_CRT_RSTN_HDMITOP		55
+#define RTD1625_CRT_RSTN_I2C_4			56
+#define RTD1625_CRT_RSTN_I2C_5			57
+#define RTD1625_CRT_RSTN_TSIO			58
+#define RTD1625_CRT_RSTN_VI			59
+#define RTD1625_CRT_RSTN_EDP			60
+#define RTD1625_CRT_RSTN_VE1_MMU		61
+#define RTD1625_CRT_RSTN_VE1_MMU_FUNC		62
+#define RTD1625_CRT_RSTN_HSE_MMU		63
+#define RTD1625_CRT_RSTN_HSE_MMU_FUNC		64
+#define RTD1625_CRT_RSTN_MDLM2M			65
+#define RTD1625_CRT_RSTN_ISO_GSPI		66
+#define RTD1625_CRT_RSTN_SOFT_NPU		67
+#define RTD1625_CRT_RSTN_SPI2EMMC		68
+#define RTD1625_CRT_RSTN_EARC			69
+#define RTD1625_CRT_RSTN_VE1			70
+#define RTD1625_CRT_RSTN_PCIE2_STITCH		71
+#define RTD1625_CRT_RSTN_PCIE2_PHY		72
+#define RTD1625_CRT_RSTN_PCIE2			73
+#define RTD1625_CRT_RSTN_PCIE2_CORE		74
+#define RTD1625_CRT_RSTN_PCIE2_POWER		75
+#define RTD1625_CRT_RSTN_PCIE2_NONSTICH		76
+#define RTD1625_CRT_RSTN_PCIE2_PHY_MDIO		77
+#define RTD1625_CRT_RSTN_DCPHY_UMCTL2		78
+#define RTD1625_CRT_RSTN_MIPI_DSI		79
+#define RTD1625_CRT_RSTN_HIFM			80
+#define RTD1625_CRT_RSTN_NSRAM			81
+#define RTD1625_CRT_RSTN_AUCPU0_REG		82
+#define RTD1625_CRT_RSTN_MDL_GENPW		83
+#define RTD1625_CRT_RSTN_MDL_CHIP		84
+#define RTD1625_CRT_RSTN_MDL_IP			85
+#define RTD1625_CRT_RSTN_TEST_MUX		86
+#define RTD1625_CRT_RSTN_ISO_BIST		87
+#define RTD1625_CRT_RSTN_MAIN_BIST		88
+#define RTD1625_CRT_RSTN_MAIN2_BIST		89
+#define RTD1625_CRT_RSTN_VE1_BIST		90
+#define RTD1625_CRT_RSTN_VE2_BIST		91
+#define RTD1625_CRT_RSTN_DCPHY_BIST		92
+#define RTD1625_CRT_RSTN_GPU_BIST		93
+#define RTD1625_CRT_RSTN_DISP_BIST		94
+#define RTD1625_CRT_RSTN_NPU_BIST		95
+#define RTD1625_CRT_RSTN_CAS_BIST		96
+#define RTD1625_CRT_RSTN_VE4_BIST		97
+#define RTD1625_CRT_RSTN_EMMC			98
+#define RTD1625_CRT_RSTN_GPU			99
+#define RTD1625_CRT_RSTN_VE2			100
+#define RTD1625_CRT_RSTN_UR1			101
+#define RTD1625_CRT_RSTN_UR2			102
+#define RTD1625_CRT_RSTN_UR3			103
+#define RTD1625_CRT_RSTN_UR4			104
+#define RTD1625_CRT_RSTN_UR5			105
+#define RTD1625_CRT_RSTN_UR6			106
+#define RTD1625_CRT_RSTN_UR7			107
+#define RTD1625_CRT_RSTN_UR8			108
+#define RTD1625_CRT_RSTN_UR9			109
+#define RTD1625_CRT_RSTN_UR_TOP			110
+#define RTD1625_CRT_RSTN_I2C_7			111
+#define RTD1625_CRT_RSTN_I2C_6			112
+#define RTD1625_CRT_RSTN_SPI0			113
+#define RTD1625_CRT_RSTN_SPI1			114
+#define RTD1625_CRT_RSTN_SPI2			115
+#define RTD1625_CRT_RSTN_LSADC0			116
+#define RTD1625_CRT_RSTN_LSADC1			117
+#define RTD1625_CRT_RSTN_ISOMIS_DMA		118
+#define RTD1625_CRT_RSTN_AUDIO_ADC		119
+#define RTD1625_CRT_RSTN_DPTX			120
+#define RTD1625_CRT_RSTN_AUCPU1_REG		121
+#define RTD1625_CRT_RSTN_EDPTX			122
+
+/* ISO reset */
+#define RTD1625_ISO_RSTN_VFD			0
+#define RTD1625_ISO_RSTN_CEC0			1
+#define RTD1625_ISO_RSTN_CEC1			2
+#define RTD1625_ISO_RSTN_CBUSTX			3
+#define RTD1625_ISO_RSTN_CBUSRX			4
+#define RTD1625_ISO_RSTN_USB3_PHY2_XTAL_POW	5
+#define RTD1625_ISO_RSTN_UR0			6
+#define RTD1625_ISO_RSTN_GMAC			7
+#define RTD1625_ISO_RSTN_GPHY			8
+#define RTD1625_ISO_RSTN_I2C_0			9
+#define RTD1625_ISO_RSTN_I2C_1			10
+#define RTD1625_ISO_RSTN_CBUS			11
+#define RTD1625_ISO_RSTN_USB_DRD		12
+#define RTD1625_ISO_RSTN_USB_HOST		13
+#define RTD1625_ISO_RSTN_USB_PHY_0		14
+#define RTD1625_ISO_RSTN_USB_PHY_1		15
+#define RTD1625_ISO_RSTN_USB_PHY_2		16
+#define RTD1625_ISO_RSTN_USB			17
+#define RTD1625_ISO_RSTN_TYPE_C			18
+#define RTD1625_ISO_RSTN_USB_U3_HOST		19
+#define RTD1625_ISO_RSTN_USB3_PHY0_POW		20
+#define RTD1625_ISO_RSTN_USB3_P0_MDIO		21
+#define RTD1625_ISO_RSTN_USB3_PHY1_POW		22
+#define RTD1625_ISO_RSTN_USB3_P1_MDIO		23
+#define RTD1625_ISO_RSTN_VTC			24
+#define RTD1625_ISO_RSTN_USB3_PHY2_POW		25
+#define RTD1625_ISO_RSTN_USB3_P2_MDIO		26
+#define RTD1625_ISO_RSTN_USB_PHY_3		27
+#define RTD1625_ISO_RSTN_USB_PHY_4		28
+
+/* ISO_S reset */
+#define RTD1625_ISO_S_RSTN_ISOM_MIS		0
+#define RTD1625_ISO_S_RSTN_GPIOM		1
+#define RTD1625_ISO_S_RSTN_TIMER7		2
+#define RTD1625_ISO_S_RSTN_IRDA			3
+#define RTD1625_ISO_S_RSTN_UR10			4
+
+#endif /* __DT_BINDINGS_RTK_RESET_RTD1625_H */
-- 
2.34.1


^ permalink raw reply related

* [PATCH v6 08/10] clk: realtek: Add RTD1625-CRT clock controller driver
From: Yu-Chun Lin @ 2026-04-02  7:39 UTC (permalink / raw)
  To: mturquette, sboyd, robh, krzk+dt, conor+dt, p.zabel, cylee12,
	afaerber, jyanchou
  Cc: devicetree, linux-clk, linux-kernel, linux-arm-kernel,
	linux-realtek-soc, james.tai, cy.huang, stanley_chang,
	eleanor.lin
In-Reply-To: <20260402073957.2742459-1-eleanor.lin@realtek.com>

From: Cheng-Yu Lee <cylee12@realtek.com>

Add support for the CRT (Clock, Reset, and Test) domain clock controller
on the Realtek RTD1625 SoC. This driver provides essential clock sources
(including PLLs), gating, and multiplexing functionalities for the
platform's peripherals.

Since the reset controller shares the same register space with the CRT
clock controller, it is instantiated as an auxiliary device by the core
clock driver. This patch also includes the corresponding auxiliary reset
driver to handle the CRT domain resets.

Signed-off-by: Cheng-Yu Lee <cylee12@realtek.com>
Co-developed-by: Yu-Chun Lin <eleanor.lin@realtek.com>
Signed-off-by: Yu-Chun Lin <eleanor.lin@realtek.com>
---
Changes in v6:
- Add the headers used in c file to follow the "Include What You Use" principle.
- Move struct rtk_reset_desc array from the clock driver to the dedicated reset driver.
- Implement and register a dedicated reset auxiliary driver.
---
 drivers/clk/realtek/Kconfig               |  13 +
 drivers/clk/realtek/Makefile              |   1 +
 drivers/clk/realtek/clk-rtd1625-crt.c     | 779 ++++++++++++++++++++++
 drivers/reset/realtek/Kconfig             |   2 +
 drivers/reset/realtek/Makefile            |   2 +-
 drivers/reset/realtek/reset-rtd1625-crt.c | 186 ++++++
 6 files changed, 982 insertions(+), 1 deletion(-)
 create mode 100644 drivers/clk/realtek/clk-rtd1625-crt.c
 create mode 100644 drivers/reset/realtek/reset-rtd1625-crt.c

diff --git a/drivers/clk/realtek/Kconfig b/drivers/clk/realtek/Kconfig
index b31a31e57b3a..6a213cfd66bc 100644
--- a/drivers/clk/realtek/Kconfig
+++ b/drivers/clk/realtek/Kconfig
@@ -28,4 +28,17 @@ config RTK_CLK_COMMON
 config RTK_CLK_PLL_MMC
 	bool
 
+config COMMON_CLK_RTD1625
+	tristate "RTD1625 Clock Controller"
+	select RTK_CLK_COMMON
+	select RTK_CLK_PLL_MMC
+	help
+	  Support for the clock controller on Realtek RTD1625 SoCs.
+
+	  This driver provides clock sources, gating, multiplexing, and
+	  reset control for peripherals on the RTD1625 platform.
+
+	  Say Y here if your system is based on the RTD1625 and you need
+	  its peripheral devices to function.
+
 endif
diff --git a/drivers/clk/realtek/Makefile b/drivers/clk/realtek/Makefile
index fd7d777902c8..c992f97dfbc7 100644
--- a/drivers/clk/realtek/Makefile
+++ b/drivers/clk/realtek/Makefile
@@ -9,3 +9,4 @@ clk-rtk-y += clk-regmap-mux.o
 clk-rtk-y += freq_table.o
 
 clk-rtk-$(CONFIG_RTK_CLK_PLL_MMC) += clk-pll-mmc.o
+obj-$(CONFIG_COMMON_CLK_RTD1625) += clk-rtd1625-crt.o
diff --git a/drivers/clk/realtek/clk-rtd1625-crt.c b/drivers/clk/realtek/clk-rtd1625-crt.c
new file mode 100644
index 000000000000..fcb8b08722c8
--- /dev/null
+++ b/drivers/clk/realtek/clk-rtd1625-crt.c
@@ -0,0 +1,779 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2022 Realtek Semiconductor Corporation
+ * Author: Cheng-Yu Lee <cylee12@realtek.com>
+ */
+
+#include <dt-bindings/clock/realtek,rtd1625-clk.h>
+#include <linux/array_size.h>
+#include <linux/bits.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include "clk-pll.h"
+#include "clk-regmap-gate.h"
+#include "clk-regmap-mux.h"
+
+#define RTD1625_CRT_CLK_MAX	172
+#define RTD1625_CRT_RSTN_MAX	123
+
+#define RTD1625_REG_PLL_ACPU1			0x10c
+#define RTD1625_REG_PLL_ACPU2			0x110
+#define RTD1625_REG_PLL_SSC_DIG_ACPU0		0x5c0
+#define RTD1625_REG_PLL_SSC_DIG_ACPU1		0x5c4
+#define RTD1625_REG_PLL_SSC_DIG_ACPU2		0x5c8
+#define RTD1625_REG_PLL_SSC_DIG_ACPU_DBG2	0x5dc
+
+#define RTD1625_REG_PLL_VE1_1			0x114
+#define RTD1625_REG_PLL_VE1_2			0x118
+#define RTD1625_REG_PLL_SSC_DIG_VE1_0		0x580
+#define RTD1625_REG_PLL_SSC_DIG_VE1_1		0x584
+#define RTD1625_REG_PLL_SSC_DIG_VE1_2		0x588
+#define RTD1625_REG_PLL_SSC_DIG_VE1_DBG2	0x59c
+
+#define RTD1625_REG_PLL_GPU1			0x1c0
+#define RTD1625_REG_PLL_GPU2			0x1c4
+#define RTD1625_REG_PLL_SSC_DIG_GPU0		0x5a0
+#define RTD1625_REG_PLL_SSC_DIG_GPU1		0x5a4
+#define RTD1625_REG_PLL_SSC_DIG_GPU2		0x5a8
+#define RTD1625_REG_PLL_SSC_DIG_GPU_DBG2	0x5bc
+
+#define RTD1625_REG_PLL_NPU1			0x1c8
+#define RTD1625_REG_PLL_NPU2			0x1cc
+#define RTD1625_REG_PLL_SSC_DIG_NPU0		0x800
+#define RTD1625_REG_PLL_SSC_DIG_NPU1		0x804
+#define RTD1625_REG_PLL_SSC_DIG_NPU2		0x808
+#define RTD1625_REG_PLL_SSC_DIG_NPU_DBG2	0x81c
+
+#define RTD1625_REG_PLL_VE2_1			0x1d0
+#define RTD1625_REG_PLL_VE2_2			0x1d4
+#define RTD1625_REG_PLL_SSC_DIG_VE2_0		0x5e0
+#define RTD1625_REG_PLL_SSC_DIG_VE2_1		0x5e4
+#define RTD1625_REG_PLL_SSC_DIG_VE2_2		0x5e8
+#define RTD1625_REG_PLL_SSC_DIG_VE2_DBG2	0x5fc
+
+#define RTD1625_REG_PLL_HIFI1			0x1d8
+#define RTD1625_REG_PLL_HIFI2			0x1dc
+#define RTD1625_REG_PLL_SSC_DIG_HIFI0		0x6e0
+#define RTD1625_REG_PLL_SSC_DIG_HIFI1		0x6e4
+#define RTD1625_REG_PLL_SSC_DIG_HIFI2		0x6e8
+#define RTD1625_REG_PLL_SSC_DIG_HIFI_DBG2	0x6fc
+
+#define RTD1625_REG_PLL_BUS1	0x524
+
+#define RTD1625_REG_PLL_SSC_DIG_DDSA1	0x564
+
+#define RTD1625_REG_PLL_SSC_DIG_DCSB1	0x544
+
+static const char * const clk_gpu_parents[] = {"pll_gpu", "clk_sys"};
+static CLK_REGMAP_MUX(clk_gpu, clk_gpu_parents, CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
+		      0x28, 12, 0x1);
+static const char * const clk_ve_parents[] = {"pll_vo", "clk_sysh", "pll_ve1", "pll_ve2"};
+static CLK_REGMAP_MUX(clk_ve1, clk_ve_parents, CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
+		      0x4c, 0, 0x3);
+static CLK_REGMAP_MUX(clk_ve2, clk_ve_parents, CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
+		      0x4c, 3, 0x3);
+static CLK_REGMAP_MUX(clk_ve4, clk_ve_parents, CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
+		      0x4c, 6, 0x3);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_misc, CLK_IS_CRITICAL, 0x50, 0, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_pcie0, 0, 0x50, 2, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_gspi, 0, 0x50, 6, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_iso_misc, 0, 0x50, 10, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_sds, 0, 0x50, 12, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_hdmi, 0, 0x50, 14, 1);
+static CLK_REGMAP_GATE(clk_en_gpu, "clk_gpu", CLK_SET_RATE_PARENT, 0x50, 18, 1);
+static CLK_REGMAP_GATE(clk_en_ve1, "clk_ve1", CLK_SET_RATE_PARENT, 0x50, 20, 1);
+static CLK_REGMAP_GATE(clk_en_ve2, "clk_ve2", CLK_SET_RATE_PARENT, 0x50, 22, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_se, 0, 0x50, 30, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_md, 0, 0x54, 4, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_tp, CLK_IS_CRITICAL, 0x54, 6, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_rcic, 0, 0x54, 8, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_nf, 0, 0x54, 10, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_emmc, 0, 0x54, 12, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_sd, 0, 0x54, 14, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_sdio_ip, 0, 0x54, 16, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_mipi_csi, 0, 0x54, 18, 1);
+static CLK_REGMAP_GATE(clk_en_emmc_ip, "pll_emmc", CLK_SET_RATE_PARENT, 0x54, 20, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_sdio, 0, 0x54, 22, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_sd_ip, 0, 0x54, 24, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_tpb, 0, 0x54, 28, 1);
+static CLK_REGMAP_GATE(clk_en_misc_sc1, "clk_en_misc", 0, 0x54, 30, 1);
+static CLK_REGMAP_GATE(clk_en_misc_i2c_3, "clk_en_misc", 0, 0x58, 0, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_jpeg, 0, 0x58, 4, 1);
+static CLK_REGMAP_GATE(clk_en_acpu, "pll_acpu", CLK_SET_RATE_PARENT,
+		       0x58, 6, 1);
+static CLK_REGMAP_GATE(clk_en_misc_sc0, "clk_en_misc", 0, 0x58, 10, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_hdmirx, 0, 0x58, 26, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_hse, CLK_IS_CRITICAL, 0x58, 28, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_fan, 0, 0x5c, 2, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_sata_wrap_sys, 0, 0x5c, 8, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_sata_wrap_sysh, 0, 0x5c, 10, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_sata_mac_sysh, 0, 0x5c, 12, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_r2rdsc, 0, 0x5c, 14, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_pcie1, 0, 0x5c, 18, 1);
+static CLK_REGMAP_GATE(clk_en_misc_i2c_4, "clk_en_misc", 0, 0x5c, 20, 1);
+static CLK_REGMAP_GATE(clk_en_misc_i2c_5, "clk_en_misc", 0, 0x5c, 22, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_tsio, 0, 0x5c, 24, 1);
+static CLK_REGMAP_GATE(clk_en_ve4, "clk_ve4", CLK_SET_RATE_PARENT,
+		       0x5c, 26, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_edp, 0, 0x5c, 28, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_tsio_trx, 0, 0x5c, 30, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_pcie2, 0, 0x8c, 0, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_earc, 0, 0x8c, 4, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_lite, 0, 0x8c, 6, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_mipi_dsi, 0, 0x8c, 8, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_npupp, 0, 0x8c, 10, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_npu, 0, 0x8c, 12, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_aucpu0, 0, 0x8c, 14, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_aucpu1, 0, 0x8c, 16, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_nsram, 0, 0x8c, 18, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_hdmitop, 0, 0x8c, 20, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_aucpu_iso_npu, 0, 0x8c, 24, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_keyladder, 0, 0x8c, 26, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_ifcp_klm, 0, 0x8c, 28, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_ifcp, 0, 0x8c, 30, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_mdl_genpw, 0, 0xb0, 0, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_mdl_chip, 0, 0xb0, 2, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_mdl_ip, 0, 0xb0, 4, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_mdlm2m, 0, 0xb0, 6, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_mdl_xtal, 0, 0xb0, 8, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_test_mux, 0, 0xb0, 10, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_dla, 0, 0xb0, 12, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_tpcw, 0, 0xb0, 16, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_gpu_ts_src, 0, 0xb0, 18, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_vi, 0, 0xb0, 22, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_lvds1, 0, 0xb0, 24, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_lvds2, 0, 0xb0, 26, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_aucpu, 0, 0xb0, 28, 1);
+static CLK_REGMAP_GATE(clk_en_ur1, "clk_en_ur_top", 0, 0x884, 0, 1);
+static CLK_REGMAP_GATE(clk_en_ur2, "clk_en_ur_top", 0, 0x884, 2, 1);
+static CLK_REGMAP_GATE(clk_en_ur3, "clk_en_ur_top", 0, 0x884, 4, 1);
+static CLK_REGMAP_GATE(clk_en_ur4, "clk_en_ur_top", 0, 0x884, 6, 1);
+static CLK_REGMAP_GATE(clk_en_ur5, "clk_en_ur_top", 0, 0x884, 8, 1);
+static CLK_REGMAP_GATE(clk_en_ur6, "clk_en_ur_top", 0, 0x884, 10, 1);
+static CLK_REGMAP_GATE(clk_en_ur7, "clk_en_ur_top", 0, 0x884, 12, 1);
+static CLK_REGMAP_GATE(clk_en_ur8, "clk_en_ur_top", 0, 0x884, 14, 1);
+static CLK_REGMAP_GATE(clk_en_ur9, "clk_en_ur_top", 0, 0x884, 16, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_ur_top, CLK_IS_CRITICAL, 0x884, 18, 1);
+static CLK_REGMAP_GATE(clk_en_misc_i2c_7, "clk_en_misc", 0, 0x884, 28, 1);
+static CLK_REGMAP_GATE(clk_en_misc_i2c_6, "clk_en_misc", 0, 0x884, 30, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_spi0, 0, 0x894, 0, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_spi1, 0, 0x894, 2, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_spi2, 0, 0x894, 4, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_lsadc0, 0, 0x894, 16, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_lsadc1, 0, 0x894, 18, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_isomis_dma, 0, 0x894, 20, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_dptx, 0, 0x894, 24, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_npu_mipi_csi, 0, 0x894, 26, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_edptx, 0, 0x894, 28, 1);
+
+#define FREQ_NF_MASK       0x7ffff
+#define FREQ_NF(_r, _nf)   {.rate = _r, .val = (_nf),}
+
+static const struct freq_table acpu_tbl[] = {
+	FREQ_NF(513000000, 0x11000),
+	FREQ_TABLE_END
+};
+
+static const struct freq_table ve_tbl[] = {
+	FREQ_NF(553500000, 0x12800),
+	FREQ_NF(661500000, 0x16800),
+	FREQ_NF(688500000, 0x17800),
+	FREQ_TABLE_END
+};
+
+static const struct freq_table bus_tbl[] = {
+	FREQ_NF(513000000, 0x11000),
+	FREQ_NF(540000000, 0x12000),
+	FREQ_NF(553500000, 0x12800),
+	FREQ_TABLE_END
+};
+
+static const struct freq_table ddsa_tbl[] = {
+	FREQ_NF(432000000, 0xe000),
+	FREQ_TABLE_END
+};
+
+static const struct freq_table gpu_tbl[] = {
+	FREQ_NF(405000000, 0xd000),
+	FREQ_NF(540000000, 0x12000),
+	FREQ_NF(661500000, 0x16800),
+	FREQ_NF(729000000, 0x19000),
+	FREQ_NF(810000000, 0x1c000),
+	FREQ_NF(850500000, 0x1d800),
+	FREQ_TABLE_END
+};
+
+static const struct freq_table hifi_tbl[] = {
+	FREQ_NF(756000000, 0x1a000),
+	FREQ_NF(810000000, 0x1c000),
+	FREQ_TABLE_END
+};
+
+static const struct freq_table npu_tbl[] = {
+	FREQ_NF(661500000, 0x16800),
+	FREQ_NF(729000000, 0x19000),
+	FREQ_NF(810000000, 0x1c000),
+	FREQ_TABLE_END
+};
+
+static const struct reg_sequence pll_acpu_seq_power_on[] = {
+	{RTD1625_REG_PLL_ACPU2,         0x5},
+	{RTD1625_REG_PLL_ACPU2,         0x7},
+	{RTD1625_REG_PLL_ACPU1,         0x54000},
+	{RTD1625_REG_PLL_SSC_DIG_ACPU2, 0x1e1f8e},
+	{RTD1625_REG_PLL_SSC_DIG_ACPU0, 0x4},
+	{RTD1625_REG_PLL_SSC_DIG_ACPU0, 0x5, 200},
+	{RTD1625_REG_PLL_ACPU2,         0x3},
+};
+
+static const struct reg_sequence pll_acpu_seq_power_off[] = {
+	{RTD1625_REG_PLL_ACPU2,         0x4},
+};
+
+static const struct reg_sequence pll_acpu_seq_pre_set_freq[] = {
+	{RTD1625_REG_PLL_SSC_DIG_ACPU0, 0x4},
+};
+
+static const struct reg_sequence pll_acpu_seq_post_set_freq[] = {
+	{RTD1625_REG_PLL_SSC_DIG_ACPU0, 0x5},
+};
+
+static struct clk_pll pll_acpu = {
+	.clkr.hw.init = CLK_HW_INIT("pll_acpu", "osc27m", &rtk_clk_pll_ops, CLK_GET_RATE_NOCACHE),
+	.seq_power_on          = pll_acpu_seq_power_on,
+	.num_seq_power_on      = ARRAY_SIZE(pll_acpu_seq_power_on),
+	.seq_power_off         = pll_acpu_seq_power_off,
+	.num_seq_power_off     = ARRAY_SIZE(pll_acpu_seq_power_off),
+	.seq_pre_set_freq      = pll_acpu_seq_pre_set_freq,
+	.num_seq_pre_set_freq  = ARRAY_SIZE(pll_acpu_seq_pre_set_freq),
+	.seq_post_set_freq     = pll_acpu_seq_post_set_freq,
+	.num_seq_post_set_freq = ARRAY_SIZE(pll_acpu_seq_post_set_freq),
+	.freq_reg              = RTD1625_REG_PLL_SSC_DIG_ACPU1,
+	.freq_tbl              = acpu_tbl,
+	.freq_mask             = FREQ_NF_MASK,
+	.freq_ready_reg        = RTD1625_REG_PLL_SSC_DIG_ACPU_DBG2,
+	.freq_ready_mask       = BIT(20),
+	.freq_ready_val        = BIT(20),
+	.power_reg             = RTD1625_REG_PLL_ACPU2,
+	.power_mask            = 0x7,
+	.power_val_on          = 0x3,
+};
+
+static const struct reg_sequence pll_ve1_seq_power_on[] = {
+	{RTD1625_REG_PLL_VE1_2,         0x5},
+	{RTD1625_REG_PLL_VE1_2,         0x7},
+	{RTD1625_REG_PLL_VE1_1,         0x54000},
+	{RTD1625_REG_PLL_SSC_DIG_VE1_0, 0x4},
+	{RTD1625_REG_PLL_SSC_DIG_VE1_0, 0x5, 200},
+	{RTD1625_REG_PLL_VE1_2,         0x3},
+};
+
+static const struct reg_sequence pll_ve1_seq_power_off[] = {
+	{RTD1625_REG_PLL_VE1_2,         0x4},
+};
+
+static const struct reg_sequence pll_ve1_seq_pre_set_freq[] = {
+	{RTD1625_REG_PLL_SSC_DIG_VE1_0, 0x4},
+};
+
+static const struct reg_sequence pll_ve1_seq_post_set_freq[] = {
+	{RTD1625_REG_PLL_SSC_DIG_VE1_0, 0x5},
+};
+
+static struct clk_pll pll_ve1 = {
+	.clkr.hw.init = CLK_HW_INIT("pll_ve1", "osc27m", &rtk_clk_pll_ops, CLK_GET_RATE_NOCACHE),
+	.seq_power_on          = pll_ve1_seq_power_on,
+	.num_seq_power_on      = ARRAY_SIZE(pll_ve1_seq_power_on),
+	.seq_power_off         = pll_ve1_seq_power_off,
+	.num_seq_power_off     = ARRAY_SIZE(pll_ve1_seq_power_off),
+	.seq_pre_set_freq      = pll_ve1_seq_pre_set_freq,
+	.num_seq_pre_set_freq  = ARRAY_SIZE(pll_ve1_seq_pre_set_freq),
+	.seq_post_set_freq     = pll_ve1_seq_post_set_freq,
+	.num_seq_post_set_freq = ARRAY_SIZE(pll_ve1_seq_post_set_freq),
+	.freq_reg              = RTD1625_REG_PLL_SSC_DIG_VE1_1,
+	.freq_tbl              = ve_tbl,
+	.freq_mask             = FREQ_NF_MASK,
+	.freq_ready_reg        = RTD1625_REG_PLL_SSC_DIG_VE1_DBG2,
+	.freq_ready_mask       = BIT(20),
+	.freq_ready_val        = BIT(20),
+	.power_reg             = RTD1625_REG_PLL_VE1_2,
+	.power_mask            = 0x7,
+	.power_val_on          = 0x3,
+};
+
+static struct clk_pll pll_ddsa = {
+	.clkr.hw.init = CLK_HW_INIT("pll_ddsa", "osc27m", &rtk_clk_pll_ro_ops,
+				    CLK_GET_RATE_NOCACHE),
+	.freq_reg     = RTD1625_REG_PLL_SSC_DIG_DDSA1,
+	.freq_tbl     = ddsa_tbl,
+	.freq_mask    = FREQ_NF_MASK,
+};
+
+static struct clk_pll pll_bus = {
+	.clkr.hw.init = CLK_HW_INIT("pll_bus", "osc27m", &rtk_clk_pll_ro_ops, CLK_GET_RATE_NOCACHE),
+	.freq_reg     = RTD1625_REG_PLL_BUS1,
+	.freq_tbl     = bus_tbl,
+	.freq_mask    = FREQ_NF_MASK,
+};
+
+static CLK_FIXED_FACTOR(clk_sys, "clk_sys", "pll_bus", 2, 1, 0);
+
+static struct clk_pll pll_dcsb = {
+	.clkr.hw.init = CLK_HW_INIT("pll_dcsb", "osc27m", &rtk_clk_pll_ro_ops,
+				    CLK_GET_RATE_NOCACHE),
+	.freq_reg     = RTD1625_REG_PLL_SSC_DIG_DCSB1,
+	.freq_tbl     = bus_tbl,
+	.freq_mask    = FREQ_NF_MASK,
+};
+
+static CLK_FIXED_FACTOR(clk_sysh, "clk_sysh", "pll_dcsb", 1, 1, 0);
+
+static const struct reg_sequence pll_gpu_seq_power_on[] = {
+	{RTD1625_REG_PLL_GPU2,         0x5},
+	{RTD1625_REG_PLL_GPU2,         0x7},
+	{RTD1625_REG_PLL_GPU1,         0x54000},
+	{RTD1625_REG_PLL_SSC_DIG_GPU0, 0x4},
+	{RTD1625_REG_PLL_SSC_DIG_GPU0, 0x5, 200},
+	{RTD1625_REG_PLL_GPU2,         0x3},
+};
+
+static const struct reg_sequence pll_gpu_seq_power_off[] = {
+	{RTD1625_REG_PLL_GPU2,         0x4},
+};
+
+static const struct reg_sequence pll_gpu_seq_pre_set_freq[] = {
+	{RTD1625_REG_PLL_SSC_DIG_GPU0, 0x4},
+};
+
+static const struct reg_sequence pll_gpu_seq_post_set_freq[] = {
+	{RTD1625_REG_PLL_SSC_DIG_GPU0, 0x5},
+};
+
+static struct clk_pll pll_gpu = {
+	.clkr.hw.init = CLK_HW_INIT("pll_gpu", "osc27m", &rtk_clk_pll_ops, CLK_GET_RATE_NOCACHE),
+	.seq_power_on          = pll_gpu_seq_power_on,
+	.num_seq_power_on      = ARRAY_SIZE(pll_gpu_seq_power_on),
+	.seq_power_off         = pll_gpu_seq_power_off,
+	.num_seq_power_off     = ARRAY_SIZE(pll_gpu_seq_power_off),
+	.seq_pre_set_freq      = pll_gpu_seq_pre_set_freq,
+	.num_seq_pre_set_freq  = ARRAY_SIZE(pll_gpu_seq_pre_set_freq),
+	.seq_post_set_freq     = pll_gpu_seq_post_set_freq,
+	.num_seq_post_set_freq = ARRAY_SIZE(pll_gpu_seq_post_set_freq),
+	.freq_reg              = RTD1625_REG_PLL_SSC_DIG_GPU1,
+	.freq_tbl              = gpu_tbl,
+	.freq_mask             = FREQ_NF_MASK,
+	.freq_ready_reg        = RTD1625_REG_PLL_SSC_DIG_GPU_DBG2,
+	.freq_ready_mask       = BIT(20),
+	.freq_ready_val        = BIT(20),
+	.power_reg             = RTD1625_REG_PLL_GPU2,
+	.power_mask            = 0x7,
+	.power_val_on          = 0x3,
+};
+
+static const struct reg_sequence pll_npu_seq_power_on[] = {
+	{RTD1625_REG_PLL_NPU2,         0x5},
+	{RTD1625_REG_PLL_NPU2,         0x7},
+	{RTD1625_REG_PLL_NPU1,         0x54000},
+	{RTD1625_REG_PLL_SSC_DIG_NPU0, 0x4},
+	{RTD1625_REG_PLL_SSC_DIG_NPU0, 0x5, 200},
+	{RTD1625_REG_PLL_NPU2,         0x3},
+};
+
+static const struct reg_sequence pll_npu_seq_power_off[] = {
+	{RTD1625_REG_PLL_NPU2,         0x4},
+	{RTD1625_REG_PLL_NPU1,         0x54010},
+};
+
+static const struct reg_sequence pll_npu_seq_pre_set_freq[] = {
+	{RTD1625_REG_PLL_SSC_DIG_NPU0, 0x4},
+};
+
+static const struct reg_sequence pll_npu_seq_post_set_freq[] = {
+	{RTD1625_REG_PLL_SSC_DIG_NPU0, 0x5},
+};
+
+static struct clk_pll pll_npu = {
+	.clkr.hw.init = CLK_HW_INIT("pll_npu", "osc27m", &rtk_clk_pll_ops, CLK_GET_RATE_NOCACHE),
+	.seq_power_on          = pll_npu_seq_power_on,
+	.num_seq_power_on      = ARRAY_SIZE(pll_npu_seq_power_on),
+	.seq_power_off         = pll_npu_seq_power_off,
+	.num_seq_power_off     = ARRAY_SIZE(pll_npu_seq_power_off),
+	.seq_pre_set_freq      = pll_npu_seq_pre_set_freq,
+	.num_seq_pre_set_freq  = ARRAY_SIZE(pll_npu_seq_pre_set_freq),
+	.seq_post_set_freq     = pll_npu_seq_post_set_freq,
+	.num_seq_post_set_freq = ARRAY_SIZE(pll_npu_seq_post_set_freq),
+	.freq_reg              = RTD1625_REG_PLL_SSC_DIG_NPU1,
+	.freq_tbl              = npu_tbl,
+	.freq_mask             = FREQ_NF_MASK,
+	.freq_ready_reg        = RTD1625_REG_PLL_SSC_DIG_NPU_DBG2,
+	.freq_ready_mask       = BIT(20),
+	.freq_ready_val        = BIT(20),
+	.power_reg             = RTD1625_REG_PLL_NPU2,
+	.power_mask            = 0x7,
+	.power_val_on          = 0x3,
+};
+
+static CLK_FIXED_FACTOR(clk_npu, "clk_npu", "pll_npu", 1, 1, CLK_SET_RATE_PARENT);
+static CLK_FIXED_FACTOR(clk_npu_mipi_csi, "clk_npu_mipi_csi", "pll_npu", 1, 1,
+			CLK_SET_RATE_PARENT);
+
+static const struct reg_sequence pll_ve2_seq_power_on[] = {
+	{RTD1625_REG_PLL_VE2_2,         0x5},
+	{RTD1625_REG_PLL_VE2_2,         0x7},
+	{RTD1625_REG_PLL_VE2_1,         0x54000},
+	{RTD1625_REG_PLL_SSC_DIG_VE2_0, 0x4},
+	{RTD1625_REG_PLL_SSC_DIG_VE2_0, 0x5, 200},
+	{RTD1625_REG_PLL_VE2_2,         0x3},
+};
+
+static const struct reg_sequence pll_ve2_seq_power_off[] = {
+	{RTD1625_REG_PLL_VE2_2,         0x4},
+};
+
+static const struct reg_sequence pll_ve2_seq_pre_set_freq[] = {
+	{RTD1625_REG_PLL_SSC_DIG_VE2_0, 0x4},
+};
+
+static const struct reg_sequence pll_ve2_seq_post_set_freq[] = {
+	{RTD1625_REG_PLL_SSC_DIG_VE2_0, 0x5},
+};
+
+static struct clk_pll pll_ve2 = {
+	.clkr.hw.init = CLK_HW_INIT("pll_ve2", "osc27m", &rtk_clk_pll_ops, CLK_GET_RATE_NOCACHE),
+	.seq_power_on          = pll_ve2_seq_power_on,
+	.num_seq_power_on      = ARRAY_SIZE(pll_ve2_seq_power_on),
+	.seq_power_off         = pll_ve2_seq_power_off,
+	.num_seq_power_off     = ARRAY_SIZE(pll_ve2_seq_power_off),
+	.seq_pre_set_freq      = pll_ve2_seq_pre_set_freq,
+	.num_seq_pre_set_freq  = ARRAY_SIZE(pll_ve2_seq_pre_set_freq),
+	.seq_post_set_freq     = pll_ve2_seq_post_set_freq,
+	.num_seq_post_set_freq = ARRAY_SIZE(pll_ve2_seq_post_set_freq),
+	.freq_reg              = RTD1625_REG_PLL_SSC_DIG_VE2_1,
+	.freq_tbl              = ve_tbl,
+	.freq_mask             = FREQ_NF_MASK,
+	.freq_ready_reg        = RTD1625_REG_PLL_SSC_DIG_VE2_DBG2,
+	.freq_ready_mask       = BIT(20),
+	.freq_ready_val        = BIT(20),
+	.power_reg             = RTD1625_REG_PLL_VE2_2,
+	.power_mask            = 0x7,
+	.power_val_on          = 0x3,
+};
+
+static const struct reg_sequence pll_hifi_seq_power_on[] = {
+	{RTD1625_REG_PLL_HIFI2,         0x5},
+	{RTD1625_REG_PLL_HIFI2,         0x7},
+	{RTD1625_REG_PLL_HIFI1,         0x54000},
+	{RTD1625_REG_PLL_SSC_DIG_HIFI0, 0x4},
+	{RTD1625_REG_PLL_SSC_DIG_HIFI0, 0x5, 200},
+	{RTD1625_REG_PLL_HIFI2,         0x3},
+};
+
+static const struct reg_sequence pll_hifi_seq_power_off[] = {
+	{RTD1625_REG_PLL_HIFI2,         0x4},
+};
+
+static const struct reg_sequence pll_hifi_seq_pre_set_freq[] = {
+	{RTD1625_REG_PLL_SSC_DIG_HIFI0, 0x4},
+};
+
+static const struct reg_sequence pll_hifi_seq_post_set_freq[] = {
+	{RTD1625_REG_PLL_SSC_DIG_HIFI0, 0x5},
+};
+
+static struct clk_pll pll_hifi = {
+	.clkr.hw.init = CLK_HW_INIT("pll_hifi", "osc27m", &rtk_clk_pll_ops, CLK_GET_RATE_NOCACHE),
+	.seq_power_on          = pll_hifi_seq_power_on,
+	.num_seq_power_on      = ARRAY_SIZE(pll_hifi_seq_power_on),
+	.seq_power_off         = pll_hifi_seq_power_off,
+	.num_seq_power_off     = ARRAY_SIZE(pll_hifi_seq_power_off),
+	.seq_pre_set_freq      = pll_hifi_seq_pre_set_freq,
+	.num_seq_pre_set_freq  = ARRAY_SIZE(pll_hifi_seq_pre_set_freq),
+	.seq_post_set_freq     = pll_hifi_seq_post_set_freq,
+	.num_seq_post_set_freq = ARRAY_SIZE(pll_hifi_seq_post_set_freq),
+	.freq_reg              = RTD1625_REG_PLL_SSC_DIG_HIFI1,
+	.freq_tbl              = hifi_tbl,
+	.freq_mask             = FREQ_NF_MASK,
+	.freq_ready_reg        = RTD1625_REG_PLL_SSC_DIG_HIFI_DBG2,
+	.freq_ready_mask       = BIT(20),
+	.freq_ready_val        = BIT(20),
+	.power_reg             = RTD1625_REG_PLL_HIFI2,
+	.power_mask            = 0x7,
+	.power_val_on          = 0x3,
+};
+
+static CLK_FIXED_FACTOR(pll_emmc_ref, "pll_emmc_ref", "osc27m", 1, 1, 0);
+
+static struct clk_pll_mmc pll_emmc = {
+	.pll_ofs        = 0x1f0,
+	.ssc_dig_ofs    = 0x6b0,
+	.clkr.hw.init   = CLK_HW_INIT("pll_emmc", "pll_emmc_ref", &rtk_clk_pll_mmc_ops, 0),
+	.phase0_hw.init = CLK_HW_INIT("pll_emmc_vp0", "pll_emmc", &rtk_clk_pll_mmc_phase_ops, 0),
+	.phase1_hw.init = CLK_HW_INIT("pll_emmc_vp1", "pll_emmc", &rtk_clk_pll_mmc_phase_ops, 0),
+};
+
+static struct clk_regmap *rtd1625_crt_regmap_clks[] = {
+	&clk_en_misc.clkr,
+	&clk_en_pcie0.clkr,
+	&clk_en_gspi.clkr,
+	&clk_en_iso_misc.clkr,
+	&clk_en_sds.clkr,
+	&clk_en_hdmi.clkr,
+	&clk_en_gpu.clkr,
+	&clk_en_ve1.clkr,
+	&clk_en_ve2.clkr,
+	&clk_en_se.clkr,
+	&clk_en_md.clkr,
+	&clk_en_tp.clkr,
+	&clk_en_rcic.clkr,
+	&clk_en_nf.clkr,
+	&clk_en_emmc.clkr,
+	&clk_en_sd.clkr,
+	&clk_en_sdio_ip.clkr,
+	&clk_en_mipi_csi.clkr,
+	&clk_en_emmc_ip.clkr,
+	&clk_en_sdio.clkr,
+	&clk_en_sd_ip.clkr,
+	&clk_en_tpb.clkr,
+	&clk_en_misc_sc1.clkr,
+	&clk_en_misc_i2c_3.clkr,
+	&clk_en_jpeg.clkr,
+	&clk_en_acpu.clkr,
+	&clk_en_misc_sc0.clkr,
+	&clk_en_hdmirx.clkr,
+	&clk_en_hse.clkr,
+	&clk_en_fan.clkr,
+	&clk_en_sata_wrap_sys.clkr,
+	&clk_en_sata_wrap_sysh.clkr,
+	&clk_en_sata_mac_sysh.clkr,
+	&clk_en_r2rdsc.clkr,
+	&clk_en_pcie1.clkr,
+	&clk_en_misc_i2c_4.clkr,
+	&clk_en_misc_i2c_5.clkr,
+	&clk_en_tsio.clkr,
+	&clk_en_ve4.clkr,
+	&clk_en_edp.clkr,
+	&clk_en_tsio_trx.clkr,
+	&clk_en_pcie2.clkr,
+	&clk_en_earc.clkr,
+	&clk_en_lite.clkr,
+	&clk_en_mipi_dsi.clkr,
+	&clk_en_npupp.clkr,
+	&clk_en_npu.clkr,
+	&clk_en_aucpu0.clkr,
+	&clk_en_aucpu1.clkr,
+	&clk_en_nsram.clkr,
+	&clk_en_hdmitop.clkr,
+	&clk_en_aucpu_iso_npu.clkr,
+	&clk_en_keyladder.clkr,
+	&clk_en_ifcp_klm.clkr,
+	&clk_en_ifcp.clkr,
+	&clk_en_mdl_genpw.clkr,
+	&clk_en_mdl_chip.clkr,
+	&clk_en_mdl_ip.clkr,
+	&clk_en_mdlm2m.clkr,
+	&clk_en_mdl_xtal.clkr,
+	&clk_en_test_mux.clkr,
+	&clk_en_dla.clkr,
+	&clk_en_tpcw.clkr,
+	&clk_en_gpu_ts_src.clkr,
+	&clk_en_vi.clkr,
+	&clk_en_lvds1.clkr,
+	&clk_en_lvds2.clkr,
+	&clk_en_aucpu.clkr,
+	&clk_en_ur1.clkr,
+	&clk_en_ur2.clkr,
+	&clk_en_ur3.clkr,
+	&clk_en_ur4.clkr,
+	&clk_en_ur5.clkr,
+	&clk_en_ur6.clkr,
+	&clk_en_ur7.clkr,
+	&clk_en_ur8.clkr,
+	&clk_en_ur9.clkr,
+	&clk_en_ur_top.clkr,
+	&clk_en_misc_i2c_7.clkr,
+	&clk_en_misc_i2c_6.clkr,
+	&clk_en_spi0.clkr,
+	&clk_en_spi1.clkr,
+	&clk_en_spi2.clkr,
+	&clk_en_lsadc0.clkr,
+	&clk_en_lsadc1.clkr,
+	&clk_en_isomis_dma.clkr,
+	&clk_en_dptx.clkr,
+	&clk_en_npu_mipi_csi.clkr,
+	&clk_en_edptx.clkr,
+	&clk_gpu.clkr,
+	&clk_ve1.clkr,
+	&clk_ve2.clkr,
+	&clk_ve4.clkr,
+	&pll_ve1.clkr,
+	&pll_ddsa.clkr,
+	&pll_bus.clkr,
+	&pll_dcsb.clkr,
+	&pll_gpu.clkr,
+	&pll_npu.clkr,
+	&pll_ve2.clkr,
+	&pll_hifi.clkr,
+	&pll_emmc.clkr,
+	&pll_acpu.clkr,
+};
+
+static struct clk_hw_onecell_data rtd1625_crt_hw_data = {
+	.num = RTD1625_CRT_CLK_MAX,
+	.hws = {
+		[RTD1625_CRT_CLK_EN_MISC]     = &__clk_regmap_gate_hw(&clk_en_misc),
+		[RTD1625_CRT_CLK_EN_PCIE0]    = &__clk_regmap_gate_hw(&clk_en_pcie0),
+		[RTD1625_CRT_CLK_EN_GSPI]     = &__clk_regmap_gate_hw(&clk_en_gspi),
+		[RTD1625_CRT_CLK_EN_ISO_MISC] = &__clk_regmap_gate_hw(&clk_en_iso_misc),
+		[RTD1625_CRT_CLK_EN_SDS]      = &__clk_regmap_gate_hw(&clk_en_sds),
+		[RTD1625_CRT_CLK_EN_HDMI]     = &__clk_regmap_gate_hw(&clk_en_hdmi),
+		[RTD1625_CRT_CLK_EN_GPU]      = &__clk_regmap_gate_hw(&clk_en_gpu),
+		[RTD1625_CRT_CLK_EN_VE1]      = &__clk_regmap_gate_hw(&clk_en_ve1),
+		[RTD1625_CRT_CLK_EN_VE2]      = &__clk_regmap_gate_hw(&clk_en_ve2),
+		[RTD1625_CRT_CLK_EN_MD]       = &__clk_regmap_gate_hw(&clk_en_md),
+		[RTD1625_CRT_CLK_EN_TP]       = &__clk_regmap_gate_hw(&clk_en_tp),
+		[RTD1625_CRT_CLK_EN_RCIC]     = &__clk_regmap_gate_hw(&clk_en_rcic),
+		[RTD1625_CRT_CLK_EN_NF]       = &__clk_regmap_gate_hw(&clk_en_nf),
+		[RTD1625_CRT_CLK_EN_EMMC]     = &__clk_regmap_gate_hw(&clk_en_emmc),
+		[RTD1625_CRT_CLK_EN_SD]       = &__clk_regmap_gate_hw(&clk_en_sd),
+		[RTD1625_CRT_CLK_EN_SDIO_IP]  = &__clk_regmap_gate_hw(&clk_en_sdio_ip),
+		[RTD1625_CRT_CLK_EN_MIPI_CSI] = &__clk_regmap_gate_hw(&clk_en_mipi_csi),
+		[RTD1625_CRT_CLK_EN_EMMC_IP]  = &__clk_regmap_gate_hw(&clk_en_emmc_ip),
+		[RTD1625_CRT_CLK_EN_SDIO]     = &__clk_regmap_gate_hw(&clk_en_sdio),
+		[RTD1625_CRT_CLK_EN_SD_IP]    = &__clk_regmap_gate_hw(&clk_en_sd_ip),
+		[RTD1625_CRT_CLK_EN_TPB]      = &__clk_regmap_gate_hw(&clk_en_tpb),
+		[RTD1625_CRT_CLK_EN_MISC_SC1] = &__clk_regmap_gate_hw(&clk_en_misc_sc1),
+		[RTD1625_CRT_CLK_EN_MISC_I2C_3] = &__clk_regmap_gate_hw(&clk_en_misc_i2c_3),
+		[RTD1625_CRT_CLK_EN_ACPU]     = &__clk_regmap_gate_hw(&clk_en_acpu),
+		[RTD1625_CRT_CLK_EN_JPEG]     = &__clk_regmap_gate_hw(&clk_en_jpeg),
+		[RTD1625_CRT_CLK_EN_MISC_SC0] = &__clk_regmap_gate_hw(&clk_en_misc_sc0),
+		[RTD1625_CRT_CLK_EN_HDMIRX]   = &__clk_regmap_gate_hw(&clk_en_hdmirx),
+		[RTD1625_CRT_CLK_EN_HSE]      = &__clk_regmap_gate_hw(&clk_en_hse),
+		[RTD1625_CRT_CLK_EN_FAN]      = &__clk_regmap_gate_hw(&clk_en_fan),
+		[RTD1625_CRT_CLK_EN_SATA_WRAP_SYS] = &__clk_regmap_gate_hw(&clk_en_sata_wrap_sys),
+		[RTD1625_CRT_CLK_EN_SATA_WRAP_SYSH] = &__clk_regmap_gate_hw(&clk_en_sata_wrap_sysh),
+		[RTD1625_CRT_CLK_EN_SATA_MAC_SYSH] = &__clk_regmap_gate_hw(&clk_en_sata_mac_sysh),
+		[RTD1625_CRT_CLK_EN_R2RDSC]   = &__clk_regmap_gate_hw(&clk_en_r2rdsc),
+		[RTD1625_CRT_CLK_EN_PCIE1]    = &__clk_regmap_gate_hw(&clk_en_pcie1),
+		[RTD1625_CRT_CLK_EN_MISC_I2C_4] = &__clk_regmap_gate_hw(&clk_en_misc_i2c_4),
+		[RTD1625_CRT_CLK_EN_MISC_I2C_5] = &__clk_regmap_gate_hw(&clk_en_misc_i2c_5),
+		[RTD1625_CRT_CLK_EN_TSIO]     = &__clk_regmap_gate_hw(&clk_en_tsio),
+		[RTD1625_CRT_CLK_EN_VE4]      = &__clk_regmap_gate_hw(&clk_en_ve4),
+		[RTD1625_CRT_CLK_EN_EDP]      = &__clk_regmap_gate_hw(&clk_en_edp),
+		[RTD1625_CRT_CLK_EN_TSIO_TRX] = &__clk_regmap_gate_hw(&clk_en_tsio_trx),
+		[RTD1625_CRT_CLK_EN_PCIE2]    = &__clk_regmap_gate_hw(&clk_en_pcie2),
+		[RTD1625_CRT_CLK_EN_EARC]     = &__clk_regmap_gate_hw(&clk_en_earc),
+		[RTD1625_CRT_CLK_EN_LITE]     = &__clk_regmap_gate_hw(&clk_en_lite),
+		[RTD1625_CRT_CLK_EN_MIPI_DSI] = &__clk_regmap_gate_hw(&clk_en_mipi_dsi),
+		[RTD1625_CRT_CLK_EN_NPUPP]    = &__clk_regmap_gate_hw(&clk_en_npupp),
+		[RTD1625_CRT_CLK_EN_NPU]      = &__clk_regmap_gate_hw(&clk_en_npu),
+		[RTD1625_CRT_CLK_EN_AUCPU0]   = &__clk_regmap_gate_hw(&clk_en_aucpu0),
+		[RTD1625_CRT_CLK_EN_AUCPU1]   = &__clk_regmap_gate_hw(&clk_en_aucpu1),
+		[RTD1625_CRT_CLK_EN_NSRAM]    = &__clk_regmap_gate_hw(&clk_en_nsram),
+		[RTD1625_CRT_CLK_EN_HDMITOP]  = &__clk_regmap_gate_hw(&clk_en_hdmitop),
+		[RTD1625_CRT_CLK_EN_AUCPU_ISO_NPU] = &__clk_regmap_gate_hw(&clk_en_aucpu_iso_npu),
+		[RTD1625_CRT_CLK_EN_KEYLADDER] = &__clk_regmap_gate_hw(&clk_en_keyladder),
+		[RTD1625_CRT_CLK_EN_IFCP_KLM]  = &__clk_regmap_gate_hw(&clk_en_ifcp_klm),
+		[RTD1625_CRT_CLK_EN_IFCP]      = &__clk_regmap_gate_hw(&clk_en_ifcp),
+		[RTD1625_CRT_CLK_EN_MDL_GENPW] = &__clk_regmap_gate_hw(&clk_en_mdl_genpw),
+		[RTD1625_CRT_CLK_EN_MDL_CHIP]  = &__clk_regmap_gate_hw(&clk_en_mdl_chip),
+		[RTD1625_CRT_CLK_EN_MDL_IP]    = &__clk_regmap_gate_hw(&clk_en_mdl_ip),
+		[RTD1625_CRT_CLK_EN_MDLM2M]    = &__clk_regmap_gate_hw(&clk_en_mdlm2m),
+		[RTD1625_CRT_CLK_EN_MDL_XTAL]  = &__clk_regmap_gate_hw(&clk_en_mdl_xtal),
+		[RTD1625_CRT_CLK_EN_TEST_MUX]  = &__clk_regmap_gate_hw(&clk_en_test_mux),
+		[RTD1625_CRT_CLK_EN_DLA]       = &__clk_regmap_gate_hw(&clk_en_dla),
+		[RTD1625_CRT_CLK_EN_TPCW]      = &__clk_regmap_gate_hw(&clk_en_tpcw),
+		[RTD1625_CRT_CLK_EN_GPU_TS_SRC] = &__clk_regmap_gate_hw(&clk_en_gpu_ts_src),
+		[RTD1625_CRT_CLK_EN_VI]        = &__clk_regmap_gate_hw(&clk_en_vi),
+		[RTD1625_CRT_CLK_EN_LVDS1]     = &__clk_regmap_gate_hw(&clk_en_lvds1),
+		[RTD1625_CRT_CLK_EN_LVDS2]     = &__clk_regmap_gate_hw(&clk_en_lvds2),
+		[RTD1625_CRT_CLK_EN_AUCPU]     = &__clk_regmap_gate_hw(&clk_en_aucpu),
+		[RTD1625_CRT_CLK_EN_UR1]       = &__clk_regmap_gate_hw(&clk_en_ur1),
+		[RTD1625_CRT_CLK_EN_UR2]       = &__clk_regmap_gate_hw(&clk_en_ur2),
+		[RTD1625_CRT_CLK_EN_UR3]       = &__clk_regmap_gate_hw(&clk_en_ur3),
+		[RTD1625_CRT_CLK_EN_UR4]       = &__clk_regmap_gate_hw(&clk_en_ur4),
+		[RTD1625_CRT_CLK_EN_UR5]       = &__clk_regmap_gate_hw(&clk_en_ur5),
+		[RTD1625_CRT_CLK_EN_UR6]       = &__clk_regmap_gate_hw(&clk_en_ur6),
+		[RTD1625_CRT_CLK_EN_UR7]       = &__clk_regmap_gate_hw(&clk_en_ur7),
+		[RTD1625_CRT_CLK_EN_UR8]       = &__clk_regmap_gate_hw(&clk_en_ur8),
+		[RTD1625_CRT_CLK_EN_UR9]       = &__clk_regmap_gate_hw(&clk_en_ur9),
+		[RTD1625_CRT_CLK_EN_UR_TOP]    = &__clk_regmap_gate_hw(&clk_en_ur_top),
+		[RTD1625_CRT_CLK_EN_MISC_I2C_7] = &__clk_regmap_gate_hw(&clk_en_misc_i2c_7),
+		[RTD1625_CRT_CLK_EN_MISC_I2C_6] = &__clk_regmap_gate_hw(&clk_en_misc_i2c_6),
+		[RTD1625_CRT_CLK_EN_SPI0]      = &__clk_regmap_gate_hw(&clk_en_spi0),
+		[RTD1625_CRT_CLK_EN_SPI1]      = &__clk_regmap_gate_hw(&clk_en_spi1),
+		[RTD1625_CRT_CLK_EN_SPI2]      = &__clk_regmap_gate_hw(&clk_en_spi2),
+		[RTD1625_CRT_CLK_EN_LSADC0]    = &__clk_regmap_gate_hw(&clk_en_lsadc0),
+		[RTD1625_CRT_CLK_EN_LSADC1]    = &__clk_regmap_gate_hw(&clk_en_lsadc1),
+		[RTD1625_CRT_CLK_EN_ISOMIS_DMA] = &__clk_regmap_gate_hw(&clk_en_isomis_dma),
+		[RTD1625_CRT_CLK_EN_DPTX]      = &__clk_regmap_gate_hw(&clk_en_dptx),
+		[RTD1625_CRT_CLK_EN_NPU_MIPI_CSI] = &__clk_regmap_gate_hw(&clk_en_npu_mipi_csi),
+		[RTD1625_CRT_CLK_EN_EDPTX] = &__clk_regmap_gate_hw(&clk_en_edptx),
+		[RTD1625_CRT_CLK_GPU]          = &__clk_regmap_mux_hw(&clk_gpu),
+		[RTD1625_CRT_CLK_VE1]          = &__clk_regmap_mux_hw(&clk_ve1),
+		[RTD1625_CRT_CLK_VE2]          = &__clk_regmap_mux_hw(&clk_ve2),
+		[RTD1625_CRT_CLK_VE4]          = &__clk_regmap_mux_hw(&clk_ve4),
+		[RTD1625_CRT_PLL_VE1]          = &__clk_pll_hw(&pll_ve1),
+		[RTD1625_CRT_PLL_DDSA]         = &__clk_pll_hw(&pll_ddsa),
+		[RTD1625_CRT_PLL_BUS]          = &__clk_pll_hw(&pll_bus),
+		[RTD1625_CRT_CLK_SYS]          = &clk_sys.hw,
+		[RTD1625_CRT_PLL_DCSB]         = &__clk_pll_hw(&pll_dcsb),
+		[RTD1625_CRT_CLK_SYSH]         = &clk_sysh.hw,
+		[RTD1625_CRT_PLL_GPU]          = &__clk_pll_hw(&pll_gpu),
+		[RTD1625_CRT_PLL_NPU]          = &__clk_pll_hw(&pll_npu),
+		[RTD1625_CRT_PLL_VE2]          = &__clk_pll_hw(&pll_ve2),
+		[RTD1625_CRT_PLL_HIFI]         = &__clk_pll_hw(&pll_hifi),
+		[RTD1625_CRT_PLL_EMMC_REF]     = &pll_emmc_ref.hw,
+		[RTD1625_CRT_PLL_EMMC]         = &__clk_pll_mmc_hw(&pll_emmc),
+		[RTD1625_CRT_PLL_EMMC_VP0]     = &pll_emmc.phase0_hw,
+		[RTD1625_CRT_PLL_EMMC_VP1]     = &pll_emmc.phase1_hw,
+		[RTD1625_CRT_PLL_ACPU]         = &__clk_pll_hw(&pll_acpu),
+		[RTD1625_CRT_CLK_NPU]          = &clk_npu.hw,
+		[RTD1625_CRT_CLK_NPU_MIPI_CSI] = &clk_npu_mipi_csi.hw,
+
+		[RTD1625_CRT_CLK_MAX]          = NULL,
+	},
+};
+
+static const struct rtk_clk_desc rtd1625_crt_desc = {
+	.clk_data        = &rtd1625_crt_hw_data,
+	.clks            = rtd1625_crt_regmap_clks,
+	.num_clks        = ARRAY_SIZE(rtd1625_crt_regmap_clks),
+};
+
+static int rtd1625_crt_probe(struct platform_device *pdev)
+{
+	const struct rtk_clk_desc *desc;
+
+	desc = of_device_get_match_data(&pdev->dev);
+	if (!desc)
+		return -EINVAL;
+
+	return rtk_clk_probe(pdev, desc, "crt_rst");
+}
+
+static const struct of_device_id rtd1625_crt_match[] = {
+	{.compatible = "realtek,rtd1625-crt-clk", .data = &rtd1625_crt_desc,},
+	{/* sentinel */}
+};
+
+static struct platform_driver rtd1625_crt_driver = {
+	.probe = rtd1625_crt_probe,
+	.driver = {
+		.name = "rtk-rtd1625-crt-clk",
+		.of_match_table = rtd1625_crt_match,
+	},
+};
+
+static int __init rtd1625_crt_init(void)
+{
+	return platform_driver_register(&rtd1625_crt_driver);
+}
+subsys_initcall(rtd1625_crt_init);
+
+MODULE_DESCRIPTION("Reatek RTD1625 CRT Controller Driver");
+MODULE_AUTHOR("Cheng-Yu Lee <cylee12@realtek.com>");
+MODULE_LICENSE("GPL");
+MODULE_IMPORT_NS("REALTEK_CLK");
diff --git a/drivers/reset/realtek/Kconfig b/drivers/reset/realtek/Kconfig
index 99a14d355803..a44c7834191c 100644
--- a/drivers/reset/realtek/Kconfig
+++ b/drivers/reset/realtek/Kconfig
@@ -1,3 +1,5 @@
 # SPDX-License-Identifier: GPL-2.0-only
 config RESET_RTK_COMMON
 	bool
+	select AUXILIARY_BUS
+	default COMMON_CLK_RTD1625
diff --git a/drivers/reset/realtek/Makefile b/drivers/reset/realtek/Makefile
index b59a3f7f2453..8ca1fa939f10 100644
--- a/drivers/reset/realtek/Makefile
+++ b/drivers/reset/realtek/Makefile
@@ -1,2 +1,2 @@
 # SPDX-License-Identifier: GPL-2.0-only
-obj-$(CONFIG_RESET_RTK_COMMON) += common.o
+obj-$(CONFIG_RESET_RTK_COMMON) += common.o reset-rtd1625-crt.o
diff --git a/drivers/reset/realtek/reset-rtd1625-crt.c b/drivers/reset/realtek/reset-rtd1625-crt.c
new file mode 100644
index 000000000000..ebb15bb68885
--- /dev/null
+++ b/drivers/reset/realtek/reset-rtd1625-crt.c
@@ -0,0 +1,186 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2026 Realtek Semiconductor Corporation
+ */
+
+#include <dt-bindings/reset/realtek,rtd1625.h>
+#include <linux/auxiliary_bus.h>
+#include <linux/device.h>
+#include <linux/errno.h>
+#include <linux/slab.h>
+#include "common.h"
+
+#define RTD1625_CRT_RSTN_MAX	123
+
+static struct rtk_reset_desc rtd1625_crt_reset_descs[] = {
+	/* Bank 0: offset 0x0 */
+	[RTD1625_CRT_RSTN_MISC]         = { .ofs = 0x0, .bit = 0,  .write_en = 1 },
+	[RTD1625_CRT_RSTN_DIP]          = { .ofs = 0x0, .bit = 2,  .write_en = 1 },
+	[RTD1625_CRT_RSTN_GSPI]         = { .ofs = 0x0, .bit = 4,  .write_en = 1 },
+	[RTD1625_CRT_RSTN_SDS]          = { .ofs = 0x0, .bit = 6,  .write_en = 1 },
+	[RTD1625_CRT_RSTN_SDS_REG]      = { .ofs = 0x0, .bit = 8,  .write_en = 1 },
+	[RTD1625_CRT_RSTN_SDS_PHY]      = { .ofs = 0x0, .bit = 10, .write_en = 1 },
+	[RTD1625_CRT_RSTN_GPU2D]        = { .ofs = 0x0, .bit = 12, .write_en = 1 },
+	[RTD1625_CRT_RSTN_DC_PHY]       = { .ofs = 0x0, .bit = 22, .write_en = 1 },
+	[RTD1625_CRT_RSTN_DCPHY_CRT]    = { .ofs = 0x0, .bit = 24, .write_en = 1 },
+	[RTD1625_CRT_RSTN_LSADC]        = { .ofs = 0x0, .bit = 26, .write_en = 1 },
+	[RTD1625_CRT_RSTN_SE]           = { .ofs = 0x0, .bit = 28, .write_en = 1 },
+	[RTD1625_CRT_RSTN_DLA]          = { .ofs = 0x0, .bit = 30, .write_en = 1 },
+	/* Bank 1: offset 0x4 */
+	[RTD1625_CRT_RSTN_JPEG]         = { .ofs = 0x4, .bit = 0,  .write_en = 1 },
+	[RTD1625_CRT_RSTN_SD]           = { .ofs = 0x4, .bit = 2,  .write_en = 1 },
+	[RTD1625_CRT_RSTN_SDIO]         = { .ofs = 0x4, .bit = 6,  .write_en = 1 },
+	[RTD1625_CRT_RSTN_PCR_CNT]      = { .ofs = 0x4, .bit = 8,  .write_en = 1 },
+	[RTD1625_CRT_RSTN_PCIE0_STITCH] = { .ofs = 0x4, .bit = 10, .write_en = 1 },
+	[RTD1625_CRT_RSTN_PCIE0_PHY]    = { .ofs = 0x4, .bit = 12, .write_en = 1 },
+	[RTD1625_CRT_RSTN_PCIE0]        = { .ofs = 0x4, .bit = 14, .write_en = 1 },
+	[RTD1625_CRT_RSTN_PCIE0_CORE]   = { .ofs = 0x4, .bit = 16, .write_en = 1 },
+	[RTD1625_CRT_RSTN_PCIE0_POWER]  = { .ofs = 0x4, .bit = 18, .write_en = 1 },
+	[RTD1625_CRT_RSTN_PCIE0_NONSTICH] = { .ofs = 0x4, .bit = 20, .write_en = 1 },
+	[RTD1625_CRT_RSTN_PCIE0_PHY_MDIO] = { .ofs = 0x4, .bit = 22, .write_en = 1 },
+	[RTD1625_CRT_RSTN_PCIE0_SGMII_MDIO] = { .ofs = 0x4, .bit = 24, .write_en = 1 },
+	[RTD1625_CRT_RSTN_VO2]          = { .ofs = 0x4, .bit = 28, .write_en = 1 },
+	[RTD1625_CRT_RSTN_MISC_SC0]     = { .ofs = 0x4, .bit = 30, .write_en = 1 },
+	/* Bank 2: offset 0x8 */
+	[RTD1625_CRT_RSTN_MD]           = { .ofs = 0x8, .bit = 4,  .write_en = 1 },
+	[RTD1625_CRT_RSTN_LVDS1]        = { .ofs = 0x8, .bit = 6,  .write_en = 1 },
+	[RTD1625_CRT_RSTN_LVDS2]        = { .ofs = 0x8, .bit = 8,  .write_en = 1 },
+	[RTD1625_CRT_RSTN_MISC_SC1]     = { .ofs = 0x8, .bit = 10, .write_en = 1 },
+	[RTD1625_CRT_RSTN_I2C_3]        = { .ofs = 0x8, .bit = 12, .write_en = 1 },
+	[RTD1625_CRT_RSTN_FAN]          = { .ofs = 0x8, .bit = 14, .write_en = 1 },
+	[RTD1625_CRT_RSTN_TVE]          = { .ofs = 0x8, .bit = 16, .write_en = 1 },
+	[RTD1625_CRT_RSTN_AIO]          = { .ofs = 0x8, .bit = 18, .write_en = 1 },
+	[RTD1625_CRT_RSTN_VO]           = { .ofs = 0x8, .bit = 20, .write_en = 1 },
+	[RTD1625_CRT_RSTN_MIPI_CSI]     = { .ofs = 0x8, .bit = 22, .write_en = 1 },
+	[RTD1625_CRT_RSTN_HDMIRX]       = { .ofs = 0x8, .bit = 24, .write_en = 1 },
+	[RTD1625_CRT_RSTN_HDMIRX_WRAP]  = { .ofs = 0x8, .bit = 26, .write_en = 1 },
+	[RTD1625_CRT_RSTN_HDMI]         = { .ofs = 0x8, .bit = 28, .write_en = 1 },
+	[RTD1625_CRT_RSTN_DISP]         = { .ofs = 0x8, .bit = 30, .write_en = 1 },
+	/* Bank 3: offset 0xc */
+	[RTD1625_CRT_RSTN_SATA_PHY_POW1] = { .ofs = 0xc, .bit = 0,  .write_en = 1 },
+	[RTD1625_CRT_RSTN_SATA_PHY_POW0] = { .ofs = 0xc, .bit = 2,  .write_en = 1 },
+	[RTD1625_CRT_RSTN_SATA_MDIO1]   = { .ofs = 0xc, .bit = 4,  .write_en = 1 },
+	[RTD1625_CRT_RSTN_SATA_MDIO0]   = { .ofs = 0xc, .bit = 6,  .write_en = 1 },
+	[RTD1625_CRT_RSTN_SATA_WRAP]    = { .ofs = 0xc, .bit = 8,  .write_en = 1 },
+	[RTD1625_CRT_RSTN_SATA_MAC_P1]  = { .ofs = 0xc, .bit = 10, .write_en = 1 },
+	[RTD1625_CRT_RSTN_SATA_MAC_P0]  = { .ofs = 0xc, .bit = 12, .write_en = 1 },
+	[RTD1625_CRT_RSTN_SATA_MAC_COM] = { .ofs = 0xc, .bit = 14, .write_en = 1 },
+	[RTD1625_CRT_RSTN_PCIE1_STITCH] = { .ofs = 0xc, .bit = 16, .write_en = 1 },
+	[RTD1625_CRT_RSTN_PCIE1_PHY]     = { .ofs = 0xc, .bit = 18, .write_en = 1 },
+	[RTD1625_CRT_RSTN_PCIE1]         = { .ofs = 0xc, .bit = 20, .write_en = 1 },
+	[RTD1625_CRT_RSTN_PCIE1_CORE]   = { .ofs = 0xc, .bit = 22, .write_en = 1 },
+	[RTD1625_CRT_RSTN_PCIE1_POWER]  = { .ofs = 0xc, .bit = 24, .write_en = 1 },
+	[RTD1625_CRT_RSTN_PCIE1_NONSTICH] = { .ofs = 0xc, .bit = 26, .write_en = 1 },
+	[RTD1625_CRT_RSTN_PCIE1_PHY_MDIO] = { .ofs = 0xc, .bit = 28, .write_en = 1 },
+	[RTD1625_CRT_RSTN_HDMITOP]      = { .ofs = 0xc, .bit = 30, .write_en = 1 },
+	/* Bank 4: offset 0x68 */
+	[RTD1625_CRT_RSTN_I2C_4]        = { .ofs = 0x68, .bit = 2,  .write_en = 1 },
+	[RTD1625_CRT_RSTN_I2C_5]        = { .ofs = 0x68, .bit = 4,  .write_en = 1 },
+	[RTD1625_CRT_RSTN_TSIO]         = { .ofs = 0x68, .bit = 6,  .write_en = 1 },
+	[RTD1625_CRT_RSTN_VI]           = { .ofs = 0x68, .bit = 8,  .write_en = 1 },
+	[RTD1625_CRT_RSTN_EDP]          = { .ofs = 0x68, .bit = 10, .write_en = 1 },
+	[RTD1625_CRT_RSTN_VE1_MMU]      = { .ofs = 0x68, .bit = 12, .write_en = 1 },
+	[RTD1625_CRT_RSTN_VE1_MMU_FUNC] = { .ofs = 0x68, .bit = 14, .write_en = 1 },
+	[RTD1625_CRT_RSTN_HSE_MMU]      = { .ofs = 0x68, .bit = 16, .write_en = 1 },
+	[RTD1625_CRT_RSTN_HSE_MMU_FUNC] = { .ofs = 0x68, .bit = 18, .write_en = 1 },
+	[RTD1625_CRT_RSTN_MDLM2M]       = { .ofs = 0x68, .bit = 20, .write_en = 1 },
+	[RTD1625_CRT_RSTN_ISO_GSPI]     = { .ofs = 0x68, .bit = 22, .write_en = 1 },
+	[RTD1625_CRT_RSTN_SOFT_NPU]     = { .ofs = 0x68, .bit = 24, .write_en = 1 },
+	[RTD1625_CRT_RSTN_SPI2EMMC]     = { .ofs = 0x68, .bit = 26, .write_en = 1 },
+	[RTD1625_CRT_RSTN_EARC]         = { .ofs = 0x68, .bit = 28, .write_en = 1 },
+	[RTD1625_CRT_RSTN_VE1]          = { .ofs = 0x68, .bit = 30, .write_en = 1 },
+	/* Bank 5: offset 0x90 */
+	[RTD1625_CRT_RSTN_PCIE2_STITCH]  = { .ofs = 0x90, .bit = 0,  .write_en = 1 },
+	[RTD1625_CRT_RSTN_PCIE2_PHY]    = { .ofs = 0x90, .bit = 2,  .write_en = 1 },
+	[RTD1625_CRT_RSTN_PCIE2]        = { .ofs = 0x90, .bit = 4,  .write_en = 1 },
+	[RTD1625_CRT_RSTN_PCIE2_CORE]   = { .ofs = 0x90, .bit = 6,  .write_en = 1 },
+	[RTD1625_CRT_RSTN_PCIE2_POWER]  = { .ofs = 0x90, .bit = 8,  .write_en = 1 },
+	[RTD1625_CRT_RSTN_PCIE2_NONSTICH] = { .ofs = 0x90, .bit = 10, .write_en = 1 },
+	[RTD1625_CRT_RSTN_PCIE2_PHY_MDIO] = { .ofs = 0x90, .bit = 12, .write_en = 1 },
+	[RTD1625_CRT_RSTN_DCPHY_UMCTL2] = { .ofs = 0x90, .bit = 14, .write_en = 1 },
+	[RTD1625_CRT_RSTN_MIPI_DSI]     = { .ofs = 0x90, .bit = 16, .write_en = 1 },
+	[RTD1625_CRT_RSTN_HIFM]         = { .ofs = 0x90, .bit = 18, .write_en = 1 },
+	[RTD1625_CRT_RSTN_NSRAM]        = { .ofs = 0x90, .bit = 20, .write_en = 1 },
+	[RTD1625_CRT_RSTN_AUCPU0_REG]   = { .ofs = 0x90, .bit = 22, .write_en = 1 },
+	[RTD1625_CRT_RSTN_MDL_GENPW]    = { .ofs = 0x90, .bit = 24, .write_en = 1 },
+	[RTD1625_CRT_RSTN_MDL_CHIP]     = { .ofs = 0x90, .bit = 26, .write_en = 1 },
+	[RTD1625_CRT_RSTN_MDL_IP]       = { .ofs = 0x90, .bit = 28, .write_en = 1 },
+	[RTD1625_CRT_RSTN_TEST_MUX]     = { .ofs = 0x90, .bit = 30, .write_en = 1 },
+	/* Bank 6: offset 0xb8 */
+	[RTD1625_CRT_RSTN_ISO_BIST]     = { .ofs = 0xb8, .bit = 0,  .write_en = 1 },
+	[RTD1625_CRT_RSTN_MAIN_BIST]    = { .ofs = 0xb8, .bit = 2,  .write_en = 1 },
+	[RTD1625_CRT_RSTN_MAIN2_BIST]   = { .ofs = 0xb8, .bit = 4,  .write_en = 1 },
+	[RTD1625_CRT_RSTN_VE1_BIST]     = { .ofs = 0xb8, .bit = 6,  .write_en = 1 },
+	[RTD1625_CRT_RSTN_VE2_BIST]     = { .ofs = 0xb8, .bit = 8,  .write_en = 1 },
+	[RTD1625_CRT_RSTN_DCPHY_BIST]   = { .ofs = 0xb8, .bit = 10, .write_en = 1 },
+	[RTD1625_CRT_RSTN_GPU_BIST]     = { .ofs = 0xb8, .bit = 12, .write_en = 1 },
+	[RTD1625_CRT_RSTN_DISP_BIST]    = { .ofs = 0xb8, .bit = 14, .write_en = 1 },
+	[RTD1625_CRT_RSTN_NPU_BIST]     = { .ofs = 0xb8, .bit = 16, .write_en = 1 },
+	[RTD1625_CRT_RSTN_CAS_BIST]     = { .ofs = 0xb8, .bit = 18, .write_en = 1 },
+	[RTD1625_CRT_RSTN_VE4_BIST]     = { .ofs = 0xb8, .bit = 20, .write_en = 1 },
+	/* Bank 7: offset 0x454 (DUMMY0, no write_en) */
+	[RTD1625_CRT_RSTN_EMMC]         = { .ofs = 0x454, .bit = 0 },
+	/* Bank 8: offset 0x458 (DUMMY1, no write_en) */
+	[RTD1625_CRT_RSTN_GPU]          = { .ofs = 0x458, .bit = 0 },
+	/* Bank 9: offset 0x464 (DUMMY4, no write_en) */
+	[RTD1625_CRT_RSTN_VE2]          = { .ofs = 0x464, .bit = 0 },
+	/* Bank 10: offset 0x880 */
+	[RTD1625_CRT_RSTN_UR1]          = { .ofs = 0x880, .bit = 0,  .write_en = 1 },
+	[RTD1625_CRT_RSTN_UR2]          = { .ofs = 0x880, .bit = 2,  .write_en = 1 },
+	[RTD1625_CRT_RSTN_UR3]          = { .ofs = 0x880, .bit = 4,  .write_en = 1 },
+	[RTD1625_CRT_RSTN_UR4]          = { .ofs = 0x880, .bit = 6,  .write_en = 1 },
+	[RTD1625_CRT_RSTN_UR5]          = { .ofs = 0x880, .bit = 8,  .write_en = 1 },
+	[RTD1625_CRT_RSTN_UR6]          = { .ofs = 0x880, .bit = 10, .write_en = 1 },
+	[RTD1625_CRT_RSTN_UR7]          = { .ofs = 0x880, .bit = 12, .write_en = 1 },
+	[RTD1625_CRT_RSTN_UR8]          = { .ofs = 0x880, .bit = 14, .write_en = 1 },
+	[RTD1625_CRT_RSTN_UR9]          = { .ofs = 0x880, .bit = 16, .write_en = 1 },
+	[RTD1625_CRT_RSTN_UR_TOP]       = { .ofs = 0x880, .bit = 18, .write_en = 1 },
+	[RTD1625_CRT_RSTN_I2C_7]        = { .ofs = 0x880, .bit = 28, .write_en = 1 },
+	[RTD1625_CRT_RSTN_I2C_6]        = { .ofs = 0x880, .bit = 30, .write_en = 1 },
+	/* Bank 11: offset 0x890 */
+	[RTD1625_CRT_RSTN_SPI0]         = { .ofs = 0x890, .bit = 0,  .write_en = 1 },
+	[RTD1625_CRT_RSTN_SPI1]         = { .ofs = 0x890, .bit = 2,  .write_en = 1 },
+	[RTD1625_CRT_RSTN_SPI2]         = { .ofs = 0x890, .bit = 4,  .write_en = 1 },
+	[RTD1625_CRT_RSTN_LSADC0]       = { .ofs = 0x890, .bit = 16, .write_en = 1 },
+	[RTD1625_CRT_RSTN_LSADC1]       = { .ofs = 0x890, .bit = 18, .write_en = 1 },
+	[RTD1625_CRT_RSTN_ISOMIS_DMA]   = { .ofs = 0x890, .bit = 20, .write_en = 1 },
+	[RTD1625_CRT_RSTN_AUDIO_ADC]    = { .ofs = 0x890, .bit = 22, .write_en = 1 },
+	[RTD1625_CRT_RSTN_DPTX]         = { .ofs = 0x890, .bit = 24, .write_en = 1 },
+	[RTD1625_CRT_RSTN_AUCPU1_REG]   = { .ofs = 0x890, .bit = 26, .write_en = 1 },
+	[RTD1625_CRT_RSTN_EDPTX]        = { .ofs = 0x890, .bit = 28, .write_en = 1 },
+};
+
+static int rtd1625_crt_reset_probe(struct auxiliary_device *adev,
+				   const struct auxiliary_device_id *id)
+{
+	struct device *dev = &adev->dev;
+	struct rtk_reset_data *data;
+
+	data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
+	if (!data)
+		return -ENOMEM;
+
+	data->descs           = rtd1625_crt_reset_descs;
+	data->rcdev.nr_resets = RTD1625_CRT_RSTN_MAX;
+	return rtk_reset_controller_add(dev, data);
+}
+
+static const struct auxiliary_device_id rtd1625_crt_reset_ids[] = {
+	{
+		.name = "clk_rtk.crt_rst",
+	},
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(auxiliary, rtd1625_crt_reset_ids);
+
+static struct auxiliary_driver rtd1625_crt_driver = {
+	.probe    = rtd1625_crt_reset_probe,
+	.id_table = rtd1625_crt_reset_ids,
+	.driver = {
+		.name = "rtd1625-crt-reset",
+	},
+};
+module_auxiliary_driver(rtd1625_crt_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_IMPORT_NS("REALTEK_RESET");
-- 
2.34.1


^ permalink raw reply related

* Re: [PATCH v2 1/2] dt-bindings: hwmon/pmbus: Add Infineon XDP720
From: Krzysztof Kozlowski @ 2026-04-02  7:44 UTC (permalink / raw)
  To: ASHISH YADAV
  Cc: Guenter Roeck, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	linux-hwmon, devicetree, linux-kernel, Ashish Yadav
In-Reply-To: <20260401104550.115715-2-Ashish.Yadav@infineon.com>

On Wed, Apr 01, 2026 at 04:15:49PM +0530, ASHISH YADAV wrote:
> From: Ashish Yadav <ashish.yadav@infineon.com>
> 
> Add documentation for the device tree binding of the XDP720 eFuse.
> 
> Signed-off-by: Ashish Yadav <ashish.yadav@infineon.com>
> ---
> This patch introduces a YAML schema describing the required and optional
> properties for the XDP720 eFuse device node. It includes details on the
> compatible string, register mapping, and rimon-micro-ohms(RIMON).
> 
> The RIMON resistance is installed between the Imon pin and the ground
> reference.

Why are you adding second commit msg? Hardware description goes to
commit msg. Redundant parts go to /dev/null.


> ---
>  .../bindings/hwmon/pmbus/infineon,xdp720.yaml | 51 +++++++++++++++++++
>  1 file changed, 51 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/hwmon/pmbus/infineon,xdp720.yaml
> 
> diff --git a/Documentation/devicetree/bindings/hwmon/pmbus/infineon,xdp720.yaml b/Documentation/devicetree/bindings/hwmon/pmbus/infineon,xdp720.yaml
> new file mode 100644
> index 000000000000..bbde8ff92ae9
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/hwmon/pmbus/infineon,xdp720.yaml
> @@ -0,0 +1,51 @@
> +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +
> +$id: http://devicetree.org/schemas/hwmon/pmbus/infineon,xdp720.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Infineon XDP720 Digital eFuse Controller
> +
> +maintainers:
> +  - Ashish Yadav <ashish.yadav@infineon.com>
> +
> +description: |
> +  The XDP720 is an eFuse with integrated current sensor and digital
> +  controller. It provides accurate system telemetry (V, I, P, T) and
> +  reports analog current at the IMON pin for post-processing.
> +
> +  Datasheet:
> +     https://www.infineon.com/assets/row/public/documents/24/49/infineon-xdp720-001-datasheet-en.pdf
> +
> +properties:
> +  compatible:
> +    enum:
> +      - infineon,xdp720
> +
> +  reg:
> +    maxItems: 1
> +
> +  infineon,rimon-micro-ohms:
> +    description: |

Do not need '|' unless you need to preserve formatting.

> +      The value of the RIMON resistor, in micro ohms, required to enable
> +      the system overcurrent protection.
> +

Missing supply

> +required:
> +  - compatible
> +  - reg

Here as well, most likely.

Best regards,
Krzysztof


^ permalink raw reply

* Re: [PATCH v2 05/10] drm/bridge: dw-hdmi: document the output_port field
From: Luca Ceresoli @ 2026-04-02  7:46 UTC (permalink / raw)
  To: Damon Ding, Marek Vasut, Stefan Agner, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter,
	Frank Li, Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam,
	Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
	Jonas Karlman, Jernej Skrabec, Liu Ying, Rob Herring,
	Saravana Kannan
  Cc: Kory Maincent (TI.com), Hervé Codina, Hui Pu, Ian Ray,
	Thomas Petazzoni, dri-devel, imx, linux-arm-kernel, linux-kernel,
	devicetree, Adam Ford, Alexander Stein, Christopher Obbard,
	Daniel Scally, Emanuele Ghidoli, Fabio Estevam, Francesco Dolcini,
	Frieder Schrempf, Gilles Talis, Goran Rađenović,
	Heiko Schocher, Josua Mayer, Kieran Bingham, Marco Felsch,
	Martyn Welch, Oleksij Rempel, Peng Fan, Richard Hu, Shengjiu Wang,
	Stefan Eichenberger, Vitor Soares
In-Reply-To: <cd0acf08-de24-4fec-a4de-0cd5b1eeeb28@rock-chips.com>

Hello Damon,

On Tue Mar 31, 2026 at 9:21 AM CEST, Damon Ding wrote:
> On 3/31/2026 3:25 AM, Luca Ceresoli wrote:
>> The meaning of this flag may not be obvious at first sight.
>>
>> Reviewed-by: Liu Ying <victor.liu@nxp.com>
>> Tested-by: Martyn Welch <martyn.welch@collabora.com>
>> Tested-by: Alexander Stein <alexander.stein@ew.tq-group.com> # TQMa8MPxL/MBa8MPxL
>> Signed-off-by: Luca Ceresoli <luca.ceresoli@bootlin.com>

Thanks for looking at this series!

>> @@ -126,6 +126,12 @@ struct dw_hdmi_phy_ops {
>>   struct dw_hdmi_plat_data {
>>   	struct regmap *regm;
>>
>> +	/*
>> +	 * The HDMI output port number must be 1 if the port is described
>> +	 * in the device tree. 0 if the device tree does not describe the
>> +	 * next component (legacy mode, i.e. without
>> +	 * DRM_BRIDGE_ATTACH_NO_CONNECTOR flag when attaching bridge).
>> +	 */
>>   	unsigned int output_port;
>>
>>   	unsigned long input_bus_encoding;
>>
>
> Tested-by: Damon Ding <damon.ding@rock-chips.com> (on rk3399)

Uhm, I'm not sure what can be tested in a patch only adding a comment. Did
you mean 'Reviewed-by' maybe?

Also, I _think_ the best syntax for a comment would be using a '#', not
parentheses, so that would be

| Tested-by: Damon Ding <damon.ding@rock-chips.com> # on rk3399

This is the recommended syntax for the 'Cc: stable' lines [0], at
least. Additionally b4 keeps comments with the '#' as those in [1], while
is discards the ones in parentheses.

[0] https://docs.kernel.org/process/stable-kernel-rules.html
[1] https://lore.kernel.org/all/2948177.mvXUDI8C0e@steina-w/

Luca

--
Luca Ceresoli, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com

^ permalink raw reply

* RE: Re: [PATCH v2 1/2] dt-bindings: gpu: mali-valhall-csf: Document i.MX952 support
From: Guangliu Ding @ 2026-04-02  7:48 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Daniel Almeida, Alice Ryhl, Boris Brezillon, Steven Price,
	Liviu Dudau, David Airlie, Simona Vetter, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Frank Li, Sascha Hauer,
	Pengutronix Kernel Team, Fabio Estevam,
	dri-devel@lists.freedesktop.org, devicetree@vger.kernel.org,
	linux-kernel@vger.kernel.org, imx@lists.linux.dev,
	linux-arm-kernel@lists.infradead.org
In-Reply-To: <20260402-axiomatic-ludicrous-panther-7a96d2@quoll>

> On Wed, Apr 01, 2026 at 06:19:12PM +0800, Guangliu Ding wrote:
> > The GPU instance used on NXP i.MX952 is the Mali‑G310, document
> > support for this variant.
> >
> > A hardware GPU auto clock‑gating mechanism has been introduced,
> > enabling GPUMIX to automatically manage the GPU clock. This improves
> > overall response time.
> >
> > Signed-off-by: Guangliu Ding <guangliu.ding@nxp.com>
> > ---
> >  Documentation/devicetree/bindings/gpu/arm,mali-valhall-csf.yaml | 1 +
> >  1 file changed, 1 insertion(+)
> 
> Why are you sending next version when the discussion is happening?
> 

I will drop this thread and raise v3 version with final fix. Sorry for inconvenience.

> Best regards,
> Krzysztof


^ permalink raw reply

* Re: [PATCH v2] ASoC: codecs: wcd937x: Add conditional regulator control for wcd937x
From: Krzysztof Kozlowski @ 2026-04-02  7:50 UTC (permalink / raw)
  To: Karthik S
  Cc: Srinivas Kandagatla, Liam Girdwood, Mark Brown, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Jaroslav Kysela, Takashi Iwai,
	linux-sound, linux-arm-msm, devicetree, linux-kernel
In-Reply-To: <CAPg2bp0DeOcQB-=VJDC5SSiFLLFL6PBPJUBHXSOP9EJZA3+bqw@mail.gmail.com>

On 02/04/2026 09:34, Karthik S wrote:
> hi Krzysztof,
> 
> Sorry for the absence of changelog, i updated the dt-binding property
> description to indicate that the power supplies for some boards such as the
> IA MEZZ is on always-on-rails, please let me know if details are sufficient
> or need to expand more on it.

Don't top post. You simply ignored the comments. Respond inline to them
and do not send new versions.

Best regards,
Krzysztof

^ permalink raw reply

* Re: [PATCH v2 1/4] dt-bindings: sound: Add ti,tas675x
From: Krzysztof Kozlowski @ 2026-04-02  7:53 UTC (permalink / raw)
  To: Sen Wang
  Cc: linux-sound, broonie, lgirdwood, robh, krzk+dt, conor+dt,
	devicetree, perex, tiwai, shenghao-ding, kevin-lu, baojun.xu,
	niranjan.hy, l-badrinarayanan, devarsht, v-singh1, linux-kernel
In-Reply-To: <20260401223239.1638881-2-sen@ti.com>

On Wed, Apr 01, 2026 at 05:28:42PM -0500, Sen Wang wrote:
> Add device tree binding for the Texas Instruments TAS675x family
> of four-channel Class-D audio amplifiers with integrated DSP.
> 
> Signed-off-by: Sen Wang <sen@ti.com>

Please use subject prefixes matching the subsystem. You can get them for
example with 'git log --oneline -- DIRECTORY_OR_FILE' on the directory
your patch is touching. For bindings, the preferred subjects are
explained here:
https://www.kernel.org/doc/html/latest/devicetree/bindings/submitting-patches.html#i-for-patch-submitters

> ---
>  .../devicetree/bindings/sound/ti,tas675x.yaml | 278 ++++++++++++++++++

Filename matching compatible, one of them.

>  1 file changed, 278 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/sound/ti,tas675x.yaml
> 
> diff --git a/Documentation/devicetree/bindings/sound/ti,tas675x.yaml b/Documentation/devicetree/bindings/sound/ti,tas675x.yaml
> new file mode 100644
> index 000000000000..23e4cc77b4ae
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/sound/ti,tas675x.yaml
> @@ -0,0 +1,278 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/sound/ti,tas675x.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Texas Instruments TAS675x Audio Amplifier
> +
> +maintainers:
> +  - Sen Wang <sen@ti.com>
> +
> +description: |

Do not need '|' unless you need to preserve formatting.

> +  The TAS675x family (TAS6754, TAS67524) are four-channel, digital-input,

And devices are not compatible?

> +  automotive Class-D audio amplifiers with load diagnostics and an integrated
> +  DSP for audio processing.
> +
> +allOf:
> +  - $ref: dai-common.yaml#
> +
> +properties:
> +  compatible:
> +    enum:
> +      - ti,tas6754
> +      - ti,tas67524

Keep alphanumerical order (not natural).

> +
> +  reg:
> +    maxItems: 1
> +
> +  '#sound-dai-cells':
> +    const: 1
> +    description: |
> +      The device exposes three DAIs, selected by index.
> +        0 - Standard Audio Path (Playback)
> +        1 - Low-Latency Playback Path (Playback)
> +        2 - Sensory Feedback (Capture - Vpredict and Isense)
> +      By default, all four channels of each DAI are active. Runtime
> +      reconfiguration is available through DAPM widgets.
> +
> +  interrupts:
> +    maxItems: 1
> +    description:
> +      Active-low falling-edge interrupt from the FAULT pin. When provided,
> +      the driver uses IRQ-driven fault reporting instead of polling.
> +
> +  pd-gpios:

Use names from gpio-consumer-common

> +    maxItems: 1
> +    description:
> +      GPIO connected to the power-down (PD#) pin, active low. Controls the
> +      internal digital circuitry power state. When asserted the device enters
> +      full power-down mode and all register state is lost. Can be omitted if
> +      PD pin is hardwired or externally controlled.
> +
> +  stby-gpios:
> +    maxItems: 1
> +    description:
> +      GPIO connected to the standby (STBY#) pin, active low. Controls the
> +      analog power stage. When asserted the device enters Deep Sleep mode
> +      but remains I2C-accessible with registers retained. Can be omitted if
> +      STBY pin is tied to PD or hardwired.
> +
> +  dvdd-supply:
> +    description:
> +      Digital logic supply (1.62 V to 3.6 V). All three supply rails must
> +      be within their recommended operating ranges before the PD pin is
> +      released.
> +
> +  pvdd-supply:
> +    description:
> +      Output FET power supply (4.5 V to 19 V). All three supply rails must
> +      be within their recommended operating ranges before the PD pin is
> +      released.
> +
> +  vbat-supply:
> +    description:
> +      Battery supply for the Class-D output stage (4.5 V to 19 V). Optional
> +      when PVDD and VBAT are connected to the same supply rail. When absent,
> +      VBAT is assumed hardwired to PVDD.
> +
> +  ti,fast-boot:
> +    type: boolean
> +    description:
> +      Skip DC load diagnostic sweep at power-on to reduce boot latency.
> +      Automatic diagnostics after fault conditions remain enabled. Hardware
> +      overcurrent protection is always active.
> +
> +  ti,audio-slot-no:
> +    $ref: /schemas/types.yaml#/definitions/uint32
> +    description:
> +      TDM slot offset for the standard audio playback path via SDIN1. A value
> +      of 4 maps to slot 4. If omitted, slot assignment is derived from the
> +      tx_mask provided via set_tdm_slot(). Without either property, no slot
> +      mapping is configured.
> +
> +  ti,llp-slot-no:
> +    $ref: /schemas/types.yaml#/definitions/uint32
> +    description:
> +      TDM slot offset for the low-latency playback path via SDIN1. If omitted,
> +      slot assignment is derived from the tx_mask provided via set_tdm_slot().
> +      Without either property, no slot mapping is configured. Disabled outside
> +      of LLP mode, and only relevant for TDM formats.
> +
> +  ti,vpredict-slot-no:
> +    $ref: /schemas/types.yaml#/definitions/uint32
> +    description: |
> +      In TDM mode, enables Vpredict output and assigns its starting slot;
> +      four consecutive slots carry Vpredict Ch1-4 on SDOUT1. May coexist
> +      with ti,isense-slot-no using separate non-overlapping slots.
> +
> +      In I2S mode, enables Vpredict output on SDOUT1 (Ch1/Ch2) and SDOUT2
> +      (Ch3/Ch4). The slot value is unused. Requires a GPIO configured as
> +      sdout2 for Ch3/Ch4; without it only Ch1/Ch2 are output. Mutually
> +      exclusive with ti,isense-slot-no; if both are set, Vpredict takes
> +      priority.
> +
> +      Irrelevant in Left-J and Right-J modes.
> +
> +  ti,isense-slot-no:
> +    $ref: /schemas/types.yaml#/definitions/uint32
> +    description: |
> +      In TDM mode, enables Isense output and assigns its starting slot;
> +      four consecutive slots carry Isense Ch1-4 on SDOUT1. May coexist
> +      with ti,vpredict-slot-no using separate non-overlapping slots.
> +
> +      In I2S mode, enables Isense output on SDOUT1 (Ch1/Ch2) and SDOUT2
> +      (Ch3/Ch4). The slot value is unused. Requires a GPIO configured as
> +      sdout2 for Ch3/Ch4; without it only Ch1/Ch2 are output. Mutually
> +      exclusive with ti,vpredict-slot-no; Vpredict takes priority if both
> +      are set.
> +
> +      Irrelevant in Left-J and Right-J modes.
> +
> +  ti,gpio1-function:
> +    $ref: /schemas/types.yaml#/definitions/string
> +    description: |

Do not need '|' unless you need to preserve formatting.

> +      Function for the GPIO_1 pin. When omitted, GPIO_1 remains in its
> +      power-on default state.

Best regards,
Krzysztof


^ permalink raw reply

* Re: [PATCH v2 2/4] ASoC: codecs: Add TAS675x quad-channel audio amplifier driver
From: Krzysztof Kozlowski @ 2026-04-02  7:54 UTC (permalink / raw)
  To: Sen Wang
  Cc: linux-sound, broonie, lgirdwood, robh, krzk+dt, conor+dt,
	devicetree, perex, tiwai, shenghao-ding, kevin-lu, baojun.xu,
	niranjan.hy, l-badrinarayanan, devarsht, v-singh1, linux-kernel
In-Reply-To: <20260401223239.1638881-3-sen@ti.com>

On Wed, Apr 01, 2026 at 05:28:43PM -0500, Sen Wang wrote:
> +
> +static const struct dev_pm_ops tas675x_pm_ops = {
> +	SYSTEM_SLEEP_PM_OPS(tas675x_system_suspend, tas675x_system_resume)
> +	RUNTIME_PM_OPS(tas675x_runtime_suspend, tas675x_runtime_resume, NULL)
> +};
> +
> +static const struct of_device_id tas675x_of_match[] = {
> +	{ .compatible = "ti,tas6754",  .data = (void *)TAS6754 },
> +	{ .compatible = "ti,tas67524", .data = (void *)TAS6754 },

I did not look detailed, but this ^^^

> +	{ }
> +};
> +MODULE_DEVICE_TABLE(of, tas675x_of_match);
> +
> +static const struct i2c_device_id tas675x_i2c_id[] = {
> +	{ "tas6754",  TAS6754 },
> +	{ "tas67524", TAS6754 },

... and this ^^^ clearly states devices are compatible, unlike your
binding is stating

> +	{ }

Best regards,
Krzysztof


^ permalink raw reply

* Re: [PATCH v2 1/2] dt-bindings: rng: mtk-rng: add SMC-based TRNG variants
From: Krzysztof Kozlowski @ 2026-04-02  7:57 UTC (permalink / raw)
  To: Daniel Golle
  Cc: Olivia Mackall, Herbert Xu, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Matthias Brugger, AngeloGioacchino Del Regno,
	Sean Wang, linux-crypto, devicetree, linux-kernel,
	linux-arm-kernel, linux-mediatek
In-Reply-To: <0a951e34b7030e514091d6c0922c5982ae349221.1775090165.git.daniel@makrotopia.org>

On Thu, Apr 02, 2026 at 01:37:02AM +0100, Daniel Golle wrote:
> Add compatible strings for MediaTek SoCs where the hardware random number
> generator is accessed via a vendor-defined Secure Monitor Call (SMC)
> rather than direct MMIO register access:
> 
>   - mediatek,mt7981-rng
>   - mediatek,mt7987-rng
>   - mediatek,mt7988-rng
> 
> These variants require no reg, clocks, or clock-names properties since
> the RNG hardware is managed by ARM Trusted Firmware-A.
> 
> Relax the $nodename pattern to also allow 'rng' in addition to the
> existing 'rng@...' pattern.
> 
> Add a second example showing the minimal SMC variant binding.
> 
> Signed-off-by: Daniel Golle <daniel@makrotopia.org>
> ---
> v2: express compatibilities with fallback
> 
>  .../devicetree/bindings/rng/mtk-rng.yaml      | 28 ++++++++++++++++---
>  1 file changed, 24 insertions(+), 4 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/rng/mtk-rng.yaml b/Documentation/devicetree/bindings/rng/mtk-rng.yaml
> index 7e8dc62e5d3a6..34648b53d14c6 100644
> --- a/Documentation/devicetree/bindings/rng/mtk-rng.yaml
> +++ b/Documentation/devicetree/bindings/rng/mtk-rng.yaml
> @@ -11,12 +11,13 @@ maintainers:
>  
>  properties:
>    $nodename:
> -    pattern: "^rng@[0-9a-f]+$"
> +    pattern: "^rng(@[0-9a-f]+)?$"
>  
>    compatible:
>      oneOf:
>        - enum:
>            - mediatek,mt7623-rng
> +          - mediatek,mt7981-rng
>        - items:
>            - enum:
>                - mediatek,mt7622-rng
> @@ -25,6 +26,11 @@ properties:
>                - mediatek,mt8365-rng
>                - mediatek,mt8516-rng
>            - const: mediatek,mt7623-rng
> +      - items:
> +          - enum:
> +              - mediatek,mt7987-rng
> +              - mediatek,mt7988-rng
> +          - const: mediatek,mt7981-rng
>  
>    reg:
>      maxItems: 1
> @@ -38,9 +44,19 @@ properties:
>  
>  required:
>    - compatible
> -  - reg
> -  - clocks
> -  - clock-names
> +
> +allOf:
> +  - if:
> +      properties:
> +        compatible:
> +          not:

As requested last time - drop

> +            contains:
> +              const: mediatek,mt7981-rng
> +    then:

missing constraints for mediatek,mt7981-rng. So does it have IO space
and clocks or not?

> +      required:
> +        - reg
> +        - clocks
> +        - clock-names
>  
>  additionalProperties: false
>  
> @@ -53,3 +69,7 @@ examples:
>              clocks = <&infracfg CLK_INFRA_TRNG>;
>              clock-names = "rng";
>      };
> +  - |
> +    rng {
> +            compatible = "mediatek,mt7981-rng";

No improvements.

Also, make the example complete since binding claims you have clocks and
reg.

I am not sure it should be even same file, but if you are making it same
file, then make it correct.

Best regards,
Krzysztof


^ permalink raw reply

* Re: [PATCH v11 2/4] crypto: spacc - Add SPAcc ahash support
From: Pavitrakumar Managutte @ 2026-04-02  8:00 UTC (permalink / raw)
  To: Herbert Xu
  Cc: linux-crypto, linux-kernel, devicetree, robh, conor+dt,
	Ruud.Derwig, manjunath.hadli, adityak, navami.telsang, bhoomikak
In-Reply-To: <acZL65nbtfMCPHhq@gondor.apana.org.au>

Hi Herbert,
   As per your inputs, I've replaced the do_shash switch to use
lib/crypto single-shot calls for SHA-1, SHA-224, SHA-256, SHA-384,
SHA-512, and MD5.

However, SM3 does not have a single-shot library API in lib/crypto yet
— include/crypto/sm3.h exposes sm3_init() and sm3_block_generic(),
with no sm3()/sm3_update()/sm3_final() equivalents.

For now, I've retained do_shash only for the SM3 case. Would this be
acceptable, or would you prefer a different approach?


Code snippet below for your reference
============== snip start ================

 switch (salg->mode->id) {
 case CRYPTO_MODE_HMAC_SHA224:
         sha224(key, keylen, tctx->ipad);
         break;

 case CRYPTO_MODE_HMAC_SHA256:
         sha256(key, keylen, tctx->ipad);
         break;

 case CRYPTO_MODE_HMAC_SHA384:
         sha384(key, keylen, tctx->ipad);
         break;

 case CRYPTO_MODE_HMAC_SHA512:
         sha512(key, keylen, tctx->ipad);
         break;

 case CRYPTO_MODE_HMAC_MD5:
         md5(key, keylen, tctx->ipad);
         break;

 case CRYPTO_MODE_HMAC_SHA1:
         sha1(key, keylen, tctx->ipad);
         break;

 case CRYPTO_MODE_HMAC_SM3:
         rc = do_shash(salg->dev, "sm3", tctx->ipad, key,
                 keylen);
         if (rc < 0) {
                 dev_err(salg->dev,
                         "ERR: %d computing shash for sm3\n", rc);
                 return -EIO;
         }
         break;

 default:
         return -EINVAL;
 }

============== snip end ================

Warm Regards,
PK



On Fri, Mar 27, 2026 at 2:50 PM Herbert Xu <herbert@gondor.apana.org.au> wrote:
>
> On Wed, Mar 18, 2026 at 12:48:06PM +0530, Pavitrakumar Managutte wrote:
> >
> > +             switch (salg->mode->id) {
> > +             case CRYPTO_MODE_HMAC_SHA224:
> > +                     rc = do_shash(salg->dev, "sha224", tctx->ipad, key,
> > +                                   keylen);
> > +                     break;
>
> Since you're doing a giant switch statement anyway, please convert
> this to use lib/crypto instead of shash.
>
> Thanks,
> --
> Email: Herbert Xu <herbert@gondor.apana.org.au>
> Home Page: http://gondor.apana.org.au/~herbert/
> PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt

^ permalink raw reply

* Re: [PATCH v2 3/3] arm64: dts: exynos850: Add ap2apm mailbox
From: Krzysztof Kozlowski @ 2026-04-02  8:01 UTC (permalink / raw)
  To: Alexey Klimov
  Cc: Sylwester Nawrocki, Chanwoo Choi, Alim Akhtar, Sam Protsenko,
	Michael Turquette, Stephen Boyd, Rob Herring, Conor Dooley,
	Tudor Ambarus, Jassi Brar, Krzysztof Kozlowski, Peter Griffin,
	linux-samsung-soc, linux-arm-kernel, linux-clk, devicetree,
	linux-kernel
In-Reply-To: <20260402-exynos850-ap2apm-mailbox-v2-3-ca5ffdff99d4@linaro.org>

On Thu, Apr 02, 2026 at 03:20:16AM +0100, Alexey Klimov wrote:
> Add mailbox node that describes AP-to-APM mailbox, that can be
> used for communicating with APM co-processor on Exynos850 SoCs.
> 
> Signed-off-by: Alexey Klimov <alexey.klimov@linaro.org>
> ---
>  arch/arm64/boot/dts/exynos/exynos850.dtsi | 9 +++++++++

What DTS is doing in the middle of the patchset? If there is going to be
resend, then fix the order. If the order is intended, then most likely
NAK but I need somewhere explanation (but I really do not see the need
for it).

Please read submitting patches (both documents).

Best regards,
Krzysztof


^ permalink raw reply

* Re: [PATCH v2 2/3] mailbox: exynos: Add support for Exynos850 mailbox
From: Krzysztof Kozlowski @ 2026-04-02  8:11 UTC (permalink / raw)
  To: Alexey Klimov
  Cc: Sylwester Nawrocki, Chanwoo Choi, Alim Akhtar, Sam Protsenko,
	Michael Turquette, Stephen Boyd, Rob Herring, Conor Dooley,
	Tudor Ambarus, Jassi Brar, Krzysztof Kozlowski, Peter Griffin,
	linux-samsung-soc, linux-arm-kernel, linux-clk, devicetree,
	linux-kernel
In-Reply-To: <20260402-exynos850-ap2apm-mailbox-v2-2-ca5ffdff99d4@linaro.org>

On Thu, Apr 02, 2026 at 03:20:15AM +0100, Alexey Klimov wrote:
> Exynos850-based platforms support ACPM and has similar workflow
> of communicating with ACPM via mailbox, however mailbox controller
> registers are located at different offsets and writes/reads could be
> different. To distinguish between such different behaviours,
> the registers offsets for Exynos850 and the platform-specific data
> structs are introduced and configuration is described in such structs
> for gs101 and exynos850 based SoCs. Probe routine now selects the
> corresponding platform-specific data via device_get_match_data().
> 
> Signed-off-by: Alexey Klimov <alexey.klimov@linaro.org>
> ---
>  drivers/mailbox/exynos-mailbox.c | 67 ++++++++++++++++++++++++++++++++++++++--
>  1 file changed, 64 insertions(+), 3 deletions(-)

Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>

Best regards,
Krzysztof


^ permalink raw reply

* [PATCH v9 00/13] ASoC: qcom: q6dsp: few fixes and enhancements
From: Srinivas Kandagatla @ 2026-04-02  8:11 UTC (permalink / raw)
  To: broonie, robh, krzk+dt, conor+dt
  Cc: mohammad.rafi.shaik, linux-sound, lgirdwood, perex, tiwai, johan,
	dmitry.baryshkov, konrad.dybcio, linux-arm-msm, devicetree,
	linux-kernel, srini, val, mailingradian, Srinivas Kandagatla

This patchset contains few fixes for the bugs hit during testing with
Monza EVK platform
- around array out of bounds access on dai ids which keep extending but
  the drivers seems to have hardcoded some numbers, fix this and clean
the mess up
- fix few issues discovered while trying to shut down dsp.
- flooding rpmsg with write requests due to not resetting queue pointer,
  fix this resetting the pointer in trigger stop.
- possible multiple graph opens which can result in open failures.

Apart from this few new enhancements to the dsp side
- add new LPI MI2S and senary dai entries
- handle pipewire and Displayport issues by moving graph start to
  trigger level, which should fix outstanding pipewire and DP issues on
Qualcomm SoCs.
- remove some unnessary loops in hot path
- support early memory map on DSP.

Tested this on top of linux-next on VENTUNO-Q platform.

Thanks,
Srini

Changes since v8:
	- move "ASoC: qcom: common: validate cpu dai id during parsing"
	  patch before using the max define.
Changes since v7:
	- improve error handling
	- remove unused variable.
	- add comments about bi-directional dais
	- in q6apm use of_platform_depopulate instead of devm variant to
	  make sure that devices are removed before component is
unregistered 

Changes since v6:
	- improve error handing and add a missing assignment.

Changes since v5:
	- moved to using pcm_new/_free as rebased with linux-next
	- fixed typo in q6apm_dai_pcm_free
	- added changes from Val to q6afe_port_get_from_id
Changes since v4:
	- sob order changed for co-dev patch.
	- update range check in common.c

Changes since v3:
	- squashed 2 dt-bindings patches as suggested at review
	- updated yaml to reflect the new port supported

Changes since v2:
	- removed non-dt header update in bindings patch.
	- removed some leftover debug statements
	- updated function to void where it did not make sense to
	  return anything.

Changes since v1:
	- removed LPASS MAX PORT define from bindings
	- added few fixes found while testing dsp shutdown usecase on
	  Monaco.
	- replaced tab with space
	- added port range check in place at runtime to catch array out
	  of bounds in future.

Mohammad Rafi Shaik (1):
  ASoC: qcom: q6dsp: Add Senary MI2S audio interface support

Srinivas Kandagatla (12):
  ASoC: qcom: q6apm: move component registration to unmanaged version
  ASoC: qcom: q6apm: remove child devices when apm is removed
  ASoC: qcom: qdsp6: topology: check widget type before accessing data
  ASoC: qcom: q6apm-lpass-dai: Fix multiple graph opens
  ASoC: qcom: q6apm-dai: reset queue ptr on trigger stop
  ASoC: dt-bindings: qcom: add LPASS LPI MI2S dai ids
  ASoC: qcom: common: validate cpu dai id during parsing
  ASoC: qcom: qdsp6: lpass-ports: add support for LPASS LPI MI2S dais
  ASoC: qcom: qdapm-lpass-dai: correct the error message
  ASoC: qcom: q6apm-lpass-dai: move graph start to trigger
  ASoC: qcom: qdsp6: remove search for module iid in hot path
  ASoC: qcom: q6apm: Add support for early buffer mapping on DSP

 .../sound/qcom,q6dsp-lpass-ports.yaml         |   5 +-
 .../sound/qcom,q6dsp-lpass-ports.h            |  12 ++
 sound/soc/qcom/common.c                       |   6 +
 sound/soc/qcom/common.h                       |   3 +
 sound/soc/qcom/lpass.h                        |   3 +-
 sound/soc/qcom/qdsp6/audioreach.c             |  60 ------
 sound/soc/qcom/qdsp6/audioreach.h             |   5 +-
 sound/soc/qcom/qdsp6/q6afe-dai.c              |   6 +
 sound/soc/qcom/qdsp6/q6afe.c                  |   8 +
 sound/soc/qcom/qdsp6/q6afe.h                  |   3 +-
 sound/soc/qcom/qdsp6/q6apm-dai.c              | 113 +++++++++--
 sound/soc/qcom/qdsp6/q6apm-lpass-dais.c       |  48 +++--
 sound/soc/qcom/qdsp6/q6apm.c                  | 182 ++++++++++++------
 sound/soc/qcom/qdsp6/q6apm.h                  |  20 +-
 sound/soc/qcom/qdsp6/q6dsp-lpass-ports.c      |  76 ++++++++
 sound/soc/qcom/qdsp6/topology.c               |   8 +-
 16 files changed, 390 insertions(+), 168 deletions(-)

-- 
2.47.3


^ permalink raw reply

* [PATCH v9 01/13] ASoC: qcom: q6apm: move component registration to unmanaged version
From: Srinivas Kandagatla @ 2026-04-02  8:11 UTC (permalink / raw)
  To: broonie, robh, krzk+dt, conor+dt
  Cc: mohammad.rafi.shaik, linux-sound, lgirdwood, perex, tiwai, johan,
	dmitry.baryshkov, konrad.dybcio, linux-arm-msm, devicetree,
	linux-kernel, srini, val, mailingradian, Srinivas Kandagatla,
	Stable
In-Reply-To: <20260402081118.348071-1-srinivas.kandagatla@oss.qualcomm.com>

q6apm component registers dais dynamically from ASoC toplology, which
are allocated using device managed version apis. Allocating both
component and dynamic dais using managed version could lead to incorrect
free ordering, dai will be freed while component still holding references
to it.

Fix this issue by moving component to unmanged version so
that the dai pointers are only freeded after the component is removed.

==================================================================
BUG: KASAN: slab-use-after-free in snd_soc_del_component_unlocked+0x3d4/0x400 [snd_soc_core]
Read of size 8 at addr ffff00084493a6e8 by task kworker/u48:0/3426
Tainted: [W]=WARN
Hardware name: LENOVO 21N2ZC5PUS/21N2ZC5PUS, BIOS N42ET57W (1.31 ) 08/08/2024
Workqueue: pdr_notifier_wq pdr_notifier_work [pdr_interface]
Call trace:
 show_stack+0x28/0x7c (C)
 dump_stack_lvl+0x60/0x80
 print_report+0x160/0x4b4
 kasan_report+0xac/0xfc
 __asan_report_load8_noabort+0x20/0x34
 snd_soc_del_component_unlocked+0x3d4/0x400 [snd_soc_core]
 snd_soc_unregister_component_by_driver+0x50/0x88 [snd_soc_core]
 devm_component_release+0x30/0x5c [snd_soc_core]
 devres_release_all+0x13c/0x210
 device_unbind_cleanup+0x20/0x190
 device_release_driver_internal+0x350/0x468
 device_release_driver+0x18/0x30
 bus_remove_device+0x1a0/0x35c
 device_del+0x314/0x7f0
 device_unregister+0x20/0xbc
 apr_remove_device+0x5c/0x7c [apr]
 device_for_each_child+0xd8/0x160
 apr_pd_status+0x7c/0xa8 [apr]
 pdr_notifier_work+0x114/0x240 [pdr_interface]
 process_one_work+0x500/0xb70
 worker_thread+0x630/0xfb0
 kthread+0x370/0x6c0
 ret_from_fork+0x10/0x20

Allocated by task 77:
 kasan_save_stack+0x40/0x68
 kasan_save_track+0x20/0x40
 kasan_save_alloc_info+0x44/0x58
 __kasan_kmalloc+0xbc/0xdc
 __kmalloc_node_track_caller_noprof+0x1f4/0x620
 devm_kmalloc+0x7c/0x1c8
 snd_soc_register_dai+0x50/0x4f0 [snd_soc_core]
 soc_tplg_pcm_elems_load+0x55c/0x1eb8 [snd_soc_core]
 snd_soc_tplg_component_load+0x4f8/0xb60 [snd_soc_core]
 audioreach_tplg_init+0x124/0x1fc [snd_q6apm]
 q6apm_audio_probe+0x10/0x1c [snd_q6apm]
 snd_soc_component_probe+0x5c/0x118 [snd_soc_core]
 soc_probe_component+0x44c/0xaf0 [snd_soc_core]
 snd_soc_bind_card+0xad0/0x2370 [snd_soc_core]
 snd_soc_register_card+0x3b0/0x4c0 [snd_soc_core]
 devm_snd_soc_register_card+0x50/0xc8 [snd_soc_core]
 x1e80100_platform_probe+0x208/0x368 [snd_soc_x1e80100]
 platform_probe+0xc0/0x188
 really_probe+0x188/0x804
 __driver_probe_device+0x158/0x358
 driver_probe_device+0x60/0x190
 __device_attach_driver+0x16c/0x2a8
 bus_for_each_drv+0x100/0x194
 __device_attach+0x174/0x380
 device_initial_probe+0x14/0x20
 bus_probe_device+0x124/0x154
 deferred_probe_work_func+0x140/0x220
 process_one_work+0x500/0xb70
 worker_thread+0x630/0xfb0
 kthread+0x370/0x6c0
 ret_from_fork+0x10/0x20

Freed by task 3426:
 kasan_save_stack+0x40/0x68
 kasan_save_track+0x20/0x40
 __kasan_save_free_info+0x4c/0x80
 __kasan_slab_free+0x78/0xa0
 kfree+0x100/0x4a4
 devres_release_all+0x144/0x210
 device_unbind_cleanup+0x20/0x190
 device_release_driver_internal+0x350/0x468
 device_release_driver+0x18/0x30
 bus_remove_device+0x1a0/0x35c
 device_del+0x314/0x7f0
 device_unregister+0x20/0xbc
 apr_remove_device+0x5c/0x7c [apr]
 device_for_each_child+0xd8/0x160
 apr_pd_status+0x7c/0xa8 [apr]
 pdr_notifier_work+0x114/0x240 [pdr_interface]
 process_one_work+0x500/0xb70
 worker_thread+0x630/0xfb0
 kthread+0x370/0x6c0
 ret_from_fork+0x10/0x20

Fixes: 5477518b8a0e ("ASoC: qdsp6: audioreach: add q6apm support")
Cc: <Stable@vger.kernel.org>
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@oss.qualcomm.com>
---
 sound/soc/qcom/qdsp6/q6apm.c | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/sound/soc/qcom/qdsp6/q6apm.c b/sound/soc/qcom/qdsp6/q6apm.c
index 970b08c89bb3..069048db5367 100644
--- a/sound/soc/qcom/qdsp6/q6apm.c
+++ b/sound/soc/qcom/qdsp6/q6apm.c
@@ -747,13 +747,22 @@ static int apm_probe(gpr_device_t *gdev)
 
 	q6apm_get_apm_state(apm);
 
-	ret = devm_snd_soc_register_component(dev, &q6apm_audio_component, NULL, 0);
+	ret = snd_soc_register_component(dev, &q6apm_audio_component, NULL, 0);
 	if (ret < 0) {
 		dev_err(dev, "failed to register q6apm: %d\n", ret);
 		return ret;
 	}
 
-	return of_platform_populate(dev->of_node, NULL, NULL, dev);
+	ret = of_platform_populate(dev->of_node, NULL, NULL, dev);
+	if (ret)
+		snd_soc_unregister_component(dev);
+
+	return ret;
+}
+
+static void apm_remove(gpr_device_t *gdev)
+{
+	snd_soc_unregister_component(&gdev->dev);
 }
 
 struct audioreach_module *q6apm_find_module_by_mid(struct q6apm_graph *graph, uint32_t mid)
@@ -820,6 +829,7 @@ MODULE_DEVICE_TABLE(of, apm_device_id);
 
 static gpr_driver_t apm_driver = {
 	.probe = apm_probe,
+	.remove = apm_remove,
 	.gpr_callback = apm_callback,
 	.driver = {
 		.name = "qcom-apm",
-- 
2.47.3


^ permalink raw reply related

* [PATCH v9 02/13] ASoC: qcom: q6apm: remove child devices when apm is removed
From: Srinivas Kandagatla @ 2026-04-02  8:11 UTC (permalink / raw)
  To: broonie, robh, krzk+dt, conor+dt
  Cc: mohammad.rafi.shaik, linux-sound, lgirdwood, perex, tiwai, johan,
	dmitry.baryshkov, konrad.dybcio, linux-arm-msm, devicetree,
	linux-kernel, srini, val, mailingradian, Srinivas Kandagatla,
	Stable
In-Reply-To: <20260402081118.348071-1-srinivas.kandagatla@oss.qualcomm.com>

looks like q6apm driver does not remove the child driver q6apm-dai and
q6apm-bedais when the this driver is removed.

Fix this by depopulating them in remove callback.

With this change when the dsp is shutdown all the devices associated with
q6apm will now be removed.

Fixes: 5477518b8a0e ("ASoC: qdsp6: audioreach: add q6apm support")
Cc: <Stable@vger.kernel.org>
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@oss.qualcomm.com>
---
 sound/soc/qcom/qdsp6/q6apm.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/sound/soc/qcom/qdsp6/q6apm.c b/sound/soc/qcom/qdsp6/q6apm.c
index 069048db5367..2dc525c8be42 100644
--- a/sound/soc/qcom/qdsp6/q6apm.c
+++ b/sound/soc/qcom/qdsp6/q6apm.c
@@ -762,6 +762,7 @@ static int apm_probe(gpr_device_t *gdev)
 
 static void apm_remove(gpr_device_t *gdev)
 {
+	of_platform_depopulate(&gdev->dev);
 	snd_soc_unregister_component(&gdev->dev);
 }
 
-- 
2.47.3


^ permalink raw reply related

* [PATCH v9 03/13] ASoC: qcom: qdsp6: topology: check widget type before accessing data
From: Srinivas Kandagatla @ 2026-04-02  8:11 UTC (permalink / raw)
  To: broonie, robh, krzk+dt, conor+dt
  Cc: mohammad.rafi.shaik, linux-sound, lgirdwood, perex, tiwai, johan,
	dmitry.baryshkov, konrad.dybcio, linux-arm-msm, devicetree,
	linux-kernel, srini, val, mailingradian, Srinivas Kandagatla
In-Reply-To: <20260402081118.348071-1-srinivas.kandagatla@oss.qualcomm.com>

Check widget type before accessing the private data, as this could a
virtual widget which is no associated with a dsp graph, container and
module. Accessing witout check could lead to incorrect memory access.

Fixes: 36ad9bf1d93d ("ASoC: qdsp6: audioreach: add topology support")
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@oss.qualcomm.com>
---
 sound/soc/qcom/qdsp6/topology.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/sound/soc/qcom/qdsp6/topology.c b/sound/soc/qcom/qdsp6/topology.c
index e732fac9b8ca..1f69fba6de26 100644
--- a/sound/soc/qcom/qdsp6/topology.c
+++ b/sound/soc/qcom/qdsp6/topology.c
@@ -952,9 +952,6 @@ static int audioreach_widget_unload(struct snd_soc_component *scomp,
 	struct audioreach_container *cont;
 	struct audioreach_module *mod;
 
-	mod = dobj->private;
-	cont = mod->container;
-
 	if (w->id == snd_soc_dapm_mixer) {
 		/* virtual widget */
 		struct snd_ar_control *scontrol = dobj->private;
@@ -963,6 +960,11 @@ static int audioreach_widget_unload(struct snd_soc_component *scomp,
 		kfree(scontrol);
 		return 0;
 	}
+	mod = dobj->private;
+	if (!mod)
+		return 0;
+
+	cont = mod->container;
 
 	mutex_lock(&apm->lock);
 	idr_remove(&apm->modules_idr, mod->instance_id);
-- 
2.47.3


^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox