* [PATCH v3 1/2] dt-bindings: clock: Add Amlogic A9 AO clock controller
From: Jian Hu via B4 Relay @ 2026-06-10 8:23 UTC (permalink / raw)
To: Neil Armstrong, Jerome Brunet, Michael Turquette, Stephen Boyd,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Xianwei Zhao,
Kevin Hilman, Martin Blumenstingl
Cc: linux-amlogic, linux-clk, devicetree, linux-kernel,
linux-arm-kernel, Jian Hu, Conor Dooley
In-Reply-To: <20260610-a9_aoclk-v3-0-b7592d6c31e2@amlogic.com>
From: Jian Hu <jian.hu@amlogic.com>
Add the Always-On clock controller dt-bindings for the Amlogic A9
SoC family.
Acked-by: Conor Dooley <conor.dooley@microchip.com>
Signed-off-by: Jian Hu <jian.hu@amlogic.com>
---
.../bindings/clock/amlogic,a9-aoclkc.yaml | 76 ++++++++++++++++++++++
include/dt-bindings/clock/amlogic,a9-aoclkc.h | 76 ++++++++++++++++++++++
2 files changed, 152 insertions(+)
diff --git a/Documentation/devicetree/bindings/clock/amlogic,a9-aoclkc.yaml b/Documentation/devicetree/bindings/clock/amlogic,a9-aoclkc.yaml
new file mode 100644
index 000000000000..1fa9b3a32fbb
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/amlogic,a9-aoclkc.yaml
@@ -0,0 +1,76 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+# Copyright (C) 2026 Amlogic, Inc. All rights reserved
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/amlogic,a9-aoclkc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Amlogic A9 Series Always-On Clock Controller
+
+maintainers:
+ - Neil Armstrong <neil.armstrong@linaro.org>
+ - Jerome Brunet <jbrunet@baylibre.com>
+ - Jian Hu <jian.hu@amlogic.com>
+ - Xianwei Zhao <xianwei.zhao@amlogic.com>
+
+properties:
+ compatible:
+ const: amlogic,a9-aoclkc
+
+ reg:
+ maxItems: 1
+
+ '#clock-cells':
+ const: 1
+
+ clocks:
+ minItems: 5
+ items:
+ - description: input oscillator
+ - description: input fclk div 3
+ - description: input fclk div 4
+ - description: input fclk div 5
+ - description: input sys clk
+ - description: external fixed 32k (optional)
+
+ clock-names:
+ minItems: 5
+ items:
+ - const: xtal
+ - const: fdiv3
+ - const: fdiv4
+ - const: fdiv5
+ - const: sys
+ - const: ext_32k
+
+required:
+ - compatible
+ - reg
+ - '#clock-cells'
+ - clocks
+ - clock-names
+
+additionalProperties: false
+
+examples:
+ - |
+ soc {
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ clock-controller@0 {
+ compatible = "amlogic,a9-aoclkc";
+ reg = <0x0 0x0 0x0 0x58>;
+ #clock-cells = <1>;
+ clocks = <&xtal>,
+ <&scmi_clk 14>,
+ <&scmi_clk 16>,
+ <&scmi_clk 18>,
+ <&scmi_clk 21>;
+ clock-names = "xtal",
+ "fdiv3",
+ "fdiv4",
+ "fdiv5",
+ "sys";
+ };
+ };
diff --git a/include/dt-bindings/clock/amlogic,a9-aoclkc.h b/include/dt-bindings/clock/amlogic,a9-aoclkc.h
new file mode 100644
index 000000000000..a7d704d4b58e
--- /dev/null
+++ b/include/dt-bindings/clock/amlogic,a9-aoclkc.h
@@ -0,0 +1,76 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+/*
+ * Copyright (C) 2026 Amlogic, Inc. All rights reserved.
+ */
+
+#ifndef __AMLOGIC_A9_AO_CLKC_H
+#define __AMLOGIC_A9_AO_CLKC_H
+
+#define CLKID_AO_XTAL_IN 0
+#define CLKID_AO_XTAL 1
+#define CLKID_AO_SYS 2
+#define CLKID_AO_SYS_I3C 3
+#define CLKID_AO_SYS_RTC_REG 4
+#define CLKID_AO_SYS_CLKTREE 5
+#define CLKID_AO_SYS_RST_CTRL 6
+#define CLKID_AO_SYS_PAD 7
+#define CLKID_AO_SYS_RTC_DIG 8
+#define CLKID_AO_SYS_IRQ 9
+#define CLKID_AO_SYS_PWRCTRL 10
+#define CLKID_AO_SYS_PWM_A 11
+#define CLKID_AO_SYS_PWM_B 12
+#define CLKID_AO_SYS_PWM_C 13
+#define CLKID_AO_SYS_PWM_D 14
+#define CLKID_AO_SYS_PWM_E 15
+#define CLKID_AO_SYS_PWM_F 16
+#define CLKID_AO_SYS_PWM_G 17
+#define CLKID_AO_SYS_I2C_A 18
+#define CLKID_AO_SYS_I2C_B 19
+#define CLKID_AO_SYS_I2C_C 20
+#define CLKID_AO_SYS_I2C_D 21
+#define CLKID_AO_SYS_SED 22
+#define CLKID_AO_SYS_IR_CTRL 23
+#define CLKID_AO_SYS_UART_B 24
+#define CLKID_AO_SYS_UART_C 25
+#define CLKID_AO_SYS_UART_D 26
+#define CLKID_AO_SYS_UART_E 27
+#define CLKID_AO_SYS_SPISG_0 28
+#define CLKID_AO_SYS_RTC_SECURE 29
+#define CLKID_AO_SYS_CEC 30
+#define CLKID_AO_SYS_AOCPU 31
+#define CLKID_AO_SYS_SRAM 32
+#define CLKID_AO_SYS_SPISG_1 33
+#define CLKID_AO_SYS_SPISG_2 34
+#define CLKID_AO_PWM_A_SEL 35
+#define CLKID_AO_PWM_A_DIV 36
+#define CLKID_AO_PWM_A 37
+#define CLKID_AO_PWM_B_SEL 38
+#define CLKID_AO_PWM_B_DIV 39
+#define CLKID_AO_PWM_B 40
+#define CLKID_AO_PWM_C_SEL 41
+#define CLKID_AO_PWM_C_DIV 42
+#define CLKID_AO_PWM_C 43
+#define CLKID_AO_PWM_D_SEL 44
+#define CLKID_AO_PWM_D_DIV 45
+#define CLKID_AO_PWM_D 46
+#define CLKID_AO_PWM_E_SEL 47
+#define CLKID_AO_PWM_E_DIV 48
+#define CLKID_AO_PWM_E 49
+#define CLKID_AO_PWM_F_SEL 50
+#define CLKID_AO_PWM_F_DIV 51
+#define CLKID_AO_PWM_F 52
+#define CLKID_AO_PWM_G_SEL 53
+#define CLKID_AO_PWM_G_DIV 54
+#define CLKID_AO_PWM_G 55
+#define CLKID_AO_RTC_DUALDIV_IN 56
+#define CLKID_AO_RTC_DUALDIV_DIV 57
+#define CLKID_AO_RTC_DUALDIV_SEL 58
+#define CLKID_AO_RTC_DUALDIV 59
+#define CLKID_AO_RTC 60
+#define CLKID_AO_CEC_DUALDIV_IN 61
+#define CLKID_AO_CEC_DUALDIV_DIV 62
+#define CLKID_AO_CEC_DUALDIV_SEL 63
+#define CLKID_AO_CEC_DUALDIV 64
+#define CLKID_AO_CEC 65
+
+#endif /* __AMLOGIC_A9_AO_CLKC_H */
--
2.47.1
^ permalink raw reply related
* [PATCH v3 2/2] clk: amlogic: Add A9 AO clock controller driver
From: Jian Hu via B4 Relay @ 2026-06-10 8:23 UTC (permalink / raw)
To: Neil Armstrong, Jerome Brunet, Michael Turquette, Stephen Boyd,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Xianwei Zhao,
Kevin Hilman, Martin Blumenstingl
Cc: linux-amlogic, linux-clk, devicetree, linux-kernel,
linux-arm-kernel, Jian Hu
In-Reply-To: <20260610-a9_aoclk-v3-0-b7592d6c31e2@amlogic.com>
From: Jian Hu <jian.hu@amlogic.com>
Add the Always-on clock controller driver for the Amlogic A9 SoC family.
Signed-off-by: Jian Hu <jian.hu@amlogic.com>
---
drivers/clk/meson/Kconfig | 13 ++
drivers/clk/meson/Makefile | 1 +
drivers/clk/meson/a9-aoclk.c | 431 +++++++++++++++++++++++++++++++++++++++++++
3 files changed, 445 insertions(+)
diff --git a/drivers/clk/meson/Kconfig b/drivers/clk/meson/Kconfig
index cf8cf3f9e4ee..b71299898197 100644
--- a/drivers/clk/meson/Kconfig
+++ b/drivers/clk/meson/Kconfig
@@ -132,6 +132,19 @@ config COMMON_CLK_A1_PERIPHERALS
device, A1 SoC Family. Say Y if you want A1 Peripherals clock
controller to work.
+config COMMON_CLK_A9_AO
+ tristate "Amlogic A9 SoC AO clock controller support"
+ depends on ARM64 || COMPILE_TEST
+ default ARCH_MESON
+ select COMMON_CLK_MESON_REGMAP
+ select COMMON_CLK_MESON_CLKC_UTILS
+ select COMMON_CLK_MESON_DUALDIV
+ imply COMMON_CLK_SCMI
+ help
+ Support for the AO clock controller on Amlogic A311Y3 based
+ device, AKA A9.
+ Say Y if you want A9 AO clock controller to work.
+
config COMMON_CLK_C3_PLL
tristate "Amlogic C3 PLL clock controller"
depends on ARM64
diff --git a/drivers/clk/meson/Makefile b/drivers/clk/meson/Makefile
index c6719694a242..f89d027c282c 100644
--- a/drivers/clk/meson/Makefile
+++ b/drivers/clk/meson/Makefile
@@ -19,6 +19,7 @@ obj-$(CONFIG_COMMON_CLK_AXG) += axg.o axg-aoclk.o
obj-$(CONFIG_COMMON_CLK_AXG_AUDIO) += axg-audio.o
obj-$(CONFIG_COMMON_CLK_A1_PLL) += a1-pll.o
obj-$(CONFIG_COMMON_CLK_A1_PERIPHERALS) += a1-peripherals.o
+obj-$(CONFIG_COMMON_CLK_A9_AO) += a9-aoclk.o
obj-$(CONFIG_COMMON_CLK_C3_PLL) += c3-pll.o
obj-$(CONFIG_COMMON_CLK_C3_PERIPHERALS) += c3-peripherals.o
obj-$(CONFIG_COMMON_CLK_GXBB) += gxbb.o gxbb-aoclk.o
diff --git a/drivers/clk/meson/a9-aoclk.c b/drivers/clk/meson/a9-aoclk.c
new file mode 100644
index 000000000000..dd9fd8d24702
--- /dev/null
+++ b/drivers/clk/meson/a9-aoclk.c
@@ -0,0 +1,431 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR MIT)
+/*
+ * Copyright (C) 2026 Amlogic, Inc. All rights reserved
+ */
+
+#include <dt-bindings/clock/amlogic,a9-aoclkc.h>
+#include <linux/clk-provider.h>
+#include <linux/platform_device.h>
+#include "clk-regmap.h"
+#include "clk-dualdiv.h"
+#include "meson-clkc-utils.h"
+
+#define AO_OSCIN_CTRL 0x00
+#define AO_SYS_CLK0 0x04
+#define AO_PWM_CLK_A_CTRL 0x1c
+#define AO_PWM_CLK_B_CTRL 0x20
+#define AO_PWM_CLK_C_CTRL 0x24
+#define AO_PWM_CLK_D_CTRL 0x28
+#define AO_PWM_CLK_E_CTRL 0x2c
+#define AO_PWM_CLK_F_CTRL 0x30
+#define AO_PWM_CLK_G_CTRL 0x34
+#define AO_CEC_CTRL0 0x38
+#define AO_CEC_CTRL1 0x3c
+#define AO_RTC_BY_OSCIN_CTRL0 0x50
+#define AO_RTC_BY_OSCIN_CTRL1 0x54
+
+#define A9_COMP_SEL(_name, _reg, _shift, _mask, _pdata) \
+ MESON_COMP_SEL(a9_ao_, _name, _reg, _shift, _mask, _pdata, NULL, 0, 0)
+
+#define A9_COMP_DIV(_name, _reg, _shift, _width) \
+ MESON_COMP_DIV(a9_ao_, _name, _reg, _shift, _width, 0, CLK_SET_RATE_PARENT)
+
+#define A9_COMP_GATE(_name, _reg, _bit) \
+ MESON_COMP_GATE(a9_ao_, _name, _reg, _bit, CLK_SET_RATE_PARENT)
+
+static struct clk_regmap a9_ao_xtal_in = {
+ .data = &(struct clk_regmap_gate_data){
+ .offset = AO_OSCIN_CTRL,
+ .bit_idx = 3,
+ },
+ .hw.init = &(struct clk_init_data) {
+ .name = "ao_xtal_in",
+ .ops = &clk_regmap_gate_ops,
+ .parent_data = &(const struct clk_parent_data) {
+ .fw_name = "xtal",
+ },
+ .num_parents = 1,
+ /*
+ * ao_sys can select different clock sources. One possible clock path is:
+ * ao_xtal_in->ao_xtal->ao_sys-> ao sys gate clocks
+ *
+ * ao_xtal_in is in the parent chain of AO sys gate clocks.
+ * Since some downstream clocks are marked CLK_IS_CRITICAL,
+ * ao_xtal_in must remain enabled and is therefore marked
+ * CLK_IS_CRITICAL as well.
+ */
+ .flags = CLK_IS_CRITICAL,
+ },
+};
+
+static struct clk_regmap a9_ao_xtal = {
+ .data = &(struct clk_regmap_mux_data) {
+ .offset = AO_OSCIN_CTRL,
+ .mask = 0x1,
+ .shift = 0,
+ },
+ /* ext_32k is from external PAD, do not automatically reparent */
+ .hw.init = CLK_HW_INIT_PARENTS_DATA("ao_xtal",
+ ((const struct clk_parent_data []) {
+ { .hw = &a9_ao_xtal_in.hw },
+ { .fw_name = "ext_32k" }
+ }), &clk_regmap_mux_ops, CLK_SET_RATE_NO_REPARENT),
+};
+
+static struct clk_regmap a9_ao_sys = {
+ .data = &(struct clk_regmap_mux_data) {
+ .offset = AO_OSCIN_CTRL,
+ .mask = 0x1,
+ .shift = 1,
+ },
+ .hw.init = CLK_HW_INIT_PARENTS_DATA("ao_sys",
+ ((const struct clk_parent_data []) {
+ { .hw = &a9_ao_xtal.hw },
+ { .fw_name = "sys" }
+ }), &clk_regmap_mux_ops, 0),
+};
+
+static const struct clk_parent_data a9_ao_pclk_parents = { .hw = &a9_ao_sys.hw };
+
+#define A9_AO_PCLK(_name, _bit, _flags) \
+ MESON_PCLK(a9_ao_sys_##_name, AO_SYS_CLK0, _bit, \
+ &a9_ao_pclk_parents, _flags)
+
+/*
+ * A9 integrates a low-power microprocessor (Always-on CPU: AOCPU). Some AO sys
+ * clocks control the AOCPU modules. Mark the AOCPU-related clocks with
+ * CLK_IS_CRITICAL to avoid them being disabled and impacting AOCPU functionality.
+ * AOCPU-related clocks list:
+ * - clktree
+ * - rst_ctrl
+ * - pad
+ * - irq
+ * - pwrctrl
+ * - aocpu
+ * - sram
+ */
+static A9_AO_PCLK(i3c, 0, 0);
+static A9_AO_PCLK(rtc_reg, 1, 0);
+static A9_AO_PCLK(clktree, 2, CLK_IS_CRITICAL);
+static A9_AO_PCLK(rst_ctrl, 3, CLK_IS_CRITICAL);
+static A9_AO_PCLK(pad, 4, CLK_IS_CRITICAL);
+static A9_AO_PCLK(rtc_dig, 5, 0);
+static A9_AO_PCLK(irq, 6, CLK_IS_CRITICAL);
+static A9_AO_PCLK(pwrctrl, 7, CLK_IS_CRITICAL);
+static A9_AO_PCLK(pwm_a, 8, 0);
+static A9_AO_PCLK(pwm_b, 9, 0);
+static A9_AO_PCLK(pwm_c, 10, 0);
+static A9_AO_PCLK(pwm_d, 11, 0);
+static A9_AO_PCLK(pwm_e, 12, 0);
+static A9_AO_PCLK(pwm_f, 13, 0);
+static A9_AO_PCLK(pwm_g, 14, 0);
+static A9_AO_PCLK(i2c_a, 15, 0);
+static A9_AO_PCLK(i2c_b, 16, 0);
+static A9_AO_PCLK(i2c_c, 17, 0);
+static A9_AO_PCLK(i2c_d, 18, 0);
+static A9_AO_PCLK(sed, 19, 0);
+static A9_AO_PCLK(ir_ctrl, 20, 0);
+static A9_AO_PCLK(uart_b, 21, 0);
+static A9_AO_PCLK(uart_c, 22, 0);
+static A9_AO_PCLK(uart_d, 23, 0);
+static A9_AO_PCLK(uart_e, 24, 0);
+static A9_AO_PCLK(spisg_0, 25, 0);
+static A9_AO_PCLK(rtc_secure, 26, 0);
+static A9_AO_PCLK(cec, 27, 0);
+static A9_AO_PCLK(aocpu, 28, CLK_IS_CRITICAL);
+static A9_AO_PCLK(sram, 29, CLK_IS_CRITICAL);
+static A9_AO_PCLK(spisg_1, 30, 0);
+static A9_AO_PCLK(spisg_2, 31, 0);
+
+static const struct clk_parent_data a9_ao_pwm_parents[] = {
+ { .hw = &a9_ao_xtal.hw },
+ { .fw_name = "fdiv5", },
+ { .fw_name = "fdiv4", },
+ { .fw_name = "fdiv3", }
+};
+
+static A9_COMP_SEL(pwm_a, AO_PWM_CLK_A_CTRL, 9, 0x7, a9_ao_pwm_parents);
+static A9_COMP_DIV(pwm_a, AO_PWM_CLK_A_CTRL, 0, 8);
+static A9_COMP_GATE(pwm_a, AO_PWM_CLK_A_CTRL, 8);
+
+static A9_COMP_SEL(pwm_b, AO_PWM_CLK_B_CTRL, 9, 0x7, a9_ao_pwm_parents);
+static A9_COMP_DIV(pwm_b, AO_PWM_CLK_B_CTRL, 0, 8);
+static A9_COMP_GATE(pwm_b, AO_PWM_CLK_B_CTRL, 8);
+
+static A9_COMP_SEL(pwm_c, AO_PWM_CLK_C_CTRL, 9, 0x7, a9_ao_pwm_parents);
+static A9_COMP_DIV(pwm_c, AO_PWM_CLK_C_CTRL, 0, 8);
+static A9_COMP_GATE(pwm_c, AO_PWM_CLK_C_CTRL, 8);
+
+static A9_COMP_SEL(pwm_d, AO_PWM_CLK_D_CTRL, 9, 0x7, a9_ao_pwm_parents);
+static A9_COMP_DIV(pwm_d, AO_PWM_CLK_D_CTRL, 0, 8);
+static A9_COMP_GATE(pwm_d, AO_PWM_CLK_D_CTRL, 8);
+
+static A9_COMP_SEL(pwm_e, AO_PWM_CLK_E_CTRL, 9, 0x7, a9_ao_pwm_parents);
+static A9_COMP_DIV(pwm_e, AO_PWM_CLK_E_CTRL, 0, 8);
+static A9_COMP_GATE(pwm_e, AO_PWM_CLK_E_CTRL, 8);
+
+static A9_COMP_SEL(pwm_f, AO_PWM_CLK_F_CTRL, 9, 0x7, a9_ao_pwm_parents);
+static A9_COMP_DIV(pwm_f, AO_PWM_CLK_F_CTRL, 0, 8);
+static A9_COMP_GATE(pwm_f, AO_PWM_CLK_F_CTRL, 8);
+
+static A9_COMP_SEL(pwm_g, AO_PWM_CLK_G_CTRL, 9, 0x7, a9_ao_pwm_parents);
+static A9_COMP_DIV(pwm_g, AO_PWM_CLK_G_CTRL, 0, 8);
+static A9_COMP_GATE(pwm_g, AO_PWM_CLK_G_CTRL, 8);
+
+static struct clk_regmap a9_ao_rtc_dualdiv_in = {
+ .data = &(struct clk_regmap_gate_data){
+ .offset = AO_RTC_BY_OSCIN_CTRL0,
+ .bit_idx = 31,
+ },
+ .hw.init = CLK_HW_INIT_HW("ao_rtc_dualdiv_in", &a9_ao_xtal.hw,
+ &clk_regmap_gate_ops, 0),
+};
+
+static const struct meson_clk_dualdiv_param a9_ao_dualdiv_table[] = {
+ { 733, 732, 8, 11, 1 },
+ { /* sentinel */ }
+};
+
+static struct clk_regmap a9_ao_rtc_dualdiv_div = {
+ .data = &(struct meson_clk_dualdiv_data){
+ .n1 = {
+ .reg_off = AO_RTC_BY_OSCIN_CTRL0,
+ .shift = 0,
+ .width = 12,
+ },
+ .n2 = {
+ .reg_off = AO_RTC_BY_OSCIN_CTRL0,
+ .shift = 12,
+ .width = 12,
+ },
+ .m1 = {
+ .reg_off = AO_RTC_BY_OSCIN_CTRL1,
+ .shift = 0,
+ .width = 12,
+ },
+ .m2 = {
+ .reg_off = AO_RTC_BY_OSCIN_CTRL1,
+ .shift = 12,
+ .width = 12,
+ },
+ .dual = {
+ .reg_off = AO_RTC_BY_OSCIN_CTRL0,
+ .shift = 28,
+ .width = 1,
+ },
+ .table = a9_ao_dualdiv_table,
+ },
+ .hw.init = CLK_HW_INIT_HW("a9_ao_rtc_dualdiv_div", &a9_ao_rtc_dualdiv_in.hw,
+ &meson_clk_dualdiv_ops, 0),
+};
+
+static struct clk_regmap a9_ao_rtc_dualdiv_sel = {
+ .data = &(struct clk_regmap_mux_data) {
+ .offset = AO_RTC_BY_OSCIN_CTRL1,
+ .mask = 0x1,
+ .shift = 24,
+ },
+ .hw.init = CLK_HW_INIT_PARENTS_HW("ao_rtc_dualdiv_sel",
+ ((const struct clk_hw *[]) {
+ &a9_ao_rtc_dualdiv_div.hw,
+ &a9_ao_rtc_dualdiv_in.hw,
+ }), &clk_regmap_mux_ops, CLK_SET_RATE_PARENT),
+};
+
+static struct clk_regmap a9_ao_rtc_dualdiv = {
+ .data = &(struct clk_regmap_gate_data){
+ .offset = AO_RTC_BY_OSCIN_CTRL0,
+ .bit_idx = 30,
+ },
+ .hw.init = CLK_HW_INIT_HW("ao_rtc_dualdiv", &a9_ao_rtc_dualdiv_sel.hw,
+ &clk_regmap_gate_ops, CLK_SET_RATE_PARENT),
+};
+
+static struct clk_regmap a9_ao_rtc = {
+ .data = &(struct clk_regmap_mux_data) {
+ .offset = AO_RTC_BY_OSCIN_CTRL1,
+ .mask = 0x1,
+ .shift = 30,
+ },
+ .hw.init = CLK_HW_INIT_PARENTS_HW("ao_rtc",
+ ((const struct clk_hw *[]) {
+ &a9_ao_xtal.hw,
+ &a9_ao_rtc_dualdiv.hw,
+ }), &clk_regmap_mux_ops, CLK_SET_RATE_PARENT),
+};
+
+static struct clk_regmap a9_ao_cec_dualdiv_in = {
+ .data = &(struct clk_regmap_gate_data){
+ .offset = AO_CEC_CTRL0,
+ .bit_idx = 31,
+ },
+ .hw.init = CLK_HW_INIT_HW("ao_cec_dualdiv_in", &a9_ao_xtal.hw,
+ &clk_regmap_gate_ops, 0),
+};
+
+static struct clk_regmap a9_ao_cec_dualdiv_div = {
+ .data = &(struct meson_clk_dualdiv_data){
+ .n1 = {
+ .reg_off = AO_CEC_CTRL0,
+ .shift = 0,
+ .width = 12,
+ },
+ .n2 = {
+ .reg_off = AO_CEC_CTRL0,
+ .shift = 12,
+ .width = 12,
+ },
+ .m1 = {
+ .reg_off = AO_CEC_CTRL1,
+ .shift = 0,
+ .width = 12,
+ },
+ .m2 = {
+ .reg_off = AO_CEC_CTRL1,
+ .shift = 12,
+ .width = 12,
+ },
+ .dual = {
+ .reg_off = AO_CEC_CTRL0,
+ .shift = 28,
+ .width = 1,
+ },
+ .table = a9_ao_dualdiv_table,
+ },
+ .hw.init = CLK_HW_INIT_HW("ao_cec_dualdiv_div", &a9_ao_cec_dualdiv_in.hw,
+ &meson_clk_dualdiv_ops, 0),
+};
+
+static struct clk_regmap a9_ao_cec_dualdiv_sel = {
+ .data = &(struct clk_regmap_mux_data) {
+ .offset = AO_CEC_CTRL1,
+ .mask = 0x1,
+ .shift = 24,
+ },
+ .hw.init = CLK_HW_INIT_PARENTS_HW("ao_cec_dualdiv_sel",
+ ((const struct clk_hw *[]) {
+ &a9_ao_cec_dualdiv_div.hw,
+ &a9_ao_cec_dualdiv_in.hw,
+ }), &clk_regmap_mux_ops, CLK_SET_RATE_PARENT),
+};
+
+static struct clk_regmap a9_ao_cec_dualdiv = {
+ .data = &(struct clk_regmap_gate_data){
+ .offset = AO_CEC_CTRL0,
+ .bit_idx = 30,
+ },
+ .hw.init = CLK_HW_INIT_HW("ao_cec_dualdiv", &a9_ao_cec_dualdiv_sel.hw,
+ &clk_regmap_gate_ops, CLK_SET_RATE_PARENT),
+};
+
+static struct clk_regmap a9_ao_cec = {
+ .data = &(struct clk_regmap_mux_data) {
+ .offset = AO_CEC_CTRL1,
+ .mask = 0x1,
+ .shift = 30,
+ },
+ .hw.init = CLK_HW_INIT_PARENTS_HW("ao_cec",
+ ((const struct clk_hw *[]) {
+ &a9_ao_cec_dualdiv.hw,
+ &a9_ao_rtc.hw,
+ }), &clk_regmap_mux_ops, CLK_SET_RATE_PARENT),
+};
+
+static struct clk_hw *a9_ao_hw_clks[] = {
+ [CLKID_AO_XTAL_IN] = &a9_ao_xtal_in.hw,
+ [CLKID_AO_XTAL] = &a9_ao_xtal.hw,
+ [CLKID_AO_SYS] = &a9_ao_sys.hw,
+ [CLKID_AO_SYS_I3C] = &a9_ao_sys_i3c.hw,
+ [CLKID_AO_SYS_RTC_REG] = &a9_ao_sys_rtc_reg.hw,
+ [CLKID_AO_SYS_CLKTREE] = &a9_ao_sys_clktree.hw,
+ [CLKID_AO_SYS_RST_CTRL] = &a9_ao_sys_rst_ctrl.hw,
+ [CLKID_AO_SYS_PAD] = &a9_ao_sys_pad.hw,
+ [CLKID_AO_SYS_RTC_DIG] = &a9_ao_sys_rtc_dig.hw,
+ [CLKID_AO_SYS_IRQ] = &a9_ao_sys_irq.hw,
+ [CLKID_AO_SYS_PWRCTRL] = &a9_ao_sys_pwrctrl.hw,
+ [CLKID_AO_SYS_PWM_A] = &a9_ao_sys_pwm_a.hw,
+ [CLKID_AO_SYS_PWM_B] = &a9_ao_sys_pwm_b.hw,
+ [CLKID_AO_SYS_PWM_C] = &a9_ao_sys_pwm_c.hw,
+ [CLKID_AO_SYS_PWM_D] = &a9_ao_sys_pwm_d.hw,
+ [CLKID_AO_SYS_PWM_E] = &a9_ao_sys_pwm_e.hw,
+ [CLKID_AO_SYS_PWM_F] = &a9_ao_sys_pwm_f.hw,
+ [CLKID_AO_SYS_PWM_G] = &a9_ao_sys_pwm_g.hw,
+ [CLKID_AO_SYS_I2C_A] = &a9_ao_sys_i2c_a.hw,
+ [CLKID_AO_SYS_I2C_B] = &a9_ao_sys_i2c_b.hw,
+ [CLKID_AO_SYS_I2C_C] = &a9_ao_sys_i2c_c.hw,
+ [CLKID_AO_SYS_I2C_D] = &a9_ao_sys_i2c_d.hw,
+ [CLKID_AO_SYS_SED] = &a9_ao_sys_sed.hw,
+ [CLKID_AO_SYS_IR_CTRL] = &a9_ao_sys_ir_ctrl.hw,
+ [CLKID_AO_SYS_UART_B] = &a9_ao_sys_uart_b.hw,
+ [CLKID_AO_SYS_UART_C] = &a9_ao_sys_uart_c.hw,
+ [CLKID_AO_SYS_UART_D] = &a9_ao_sys_uart_d.hw,
+ [CLKID_AO_SYS_UART_E] = &a9_ao_sys_uart_e.hw,
+ [CLKID_AO_SYS_SPISG_0] = &a9_ao_sys_spisg_0.hw,
+ [CLKID_AO_SYS_RTC_SECURE] = &a9_ao_sys_rtc_secure.hw,
+ [CLKID_AO_SYS_CEC] = &a9_ao_sys_cec.hw,
+ [CLKID_AO_SYS_AOCPU] = &a9_ao_sys_aocpu.hw,
+ [CLKID_AO_SYS_SRAM] = &a9_ao_sys_sram.hw,
+ [CLKID_AO_SYS_SPISG_1] = &a9_ao_sys_spisg_1.hw,
+ [CLKID_AO_SYS_SPISG_2] = &a9_ao_sys_spisg_2.hw,
+ [CLKID_AO_PWM_A_SEL] = &a9_ao_pwm_a_sel.hw,
+ [CLKID_AO_PWM_A_DIV] = &a9_ao_pwm_a_div.hw,
+ [CLKID_AO_PWM_A] = &a9_ao_pwm_a.hw,
+ [CLKID_AO_PWM_B_SEL] = &a9_ao_pwm_b_sel.hw,
+ [CLKID_AO_PWM_B_DIV] = &a9_ao_pwm_b_div.hw,
+ [CLKID_AO_PWM_B] = &a9_ao_pwm_b.hw,
+ [CLKID_AO_PWM_C_SEL] = &a9_ao_pwm_c_sel.hw,
+ [CLKID_AO_PWM_C_DIV] = &a9_ao_pwm_c_div.hw,
+ [CLKID_AO_PWM_C] = &a9_ao_pwm_c.hw,
+ [CLKID_AO_PWM_D_SEL] = &a9_ao_pwm_d_sel.hw,
+ [CLKID_AO_PWM_D_DIV] = &a9_ao_pwm_d_div.hw,
+ [CLKID_AO_PWM_D] = &a9_ao_pwm_d.hw,
+ [CLKID_AO_PWM_E_SEL] = &a9_ao_pwm_e_sel.hw,
+ [CLKID_AO_PWM_E_DIV] = &a9_ao_pwm_e_div.hw,
+ [CLKID_AO_PWM_E] = &a9_ao_pwm_e.hw,
+ [CLKID_AO_PWM_F_SEL] = &a9_ao_pwm_f_sel.hw,
+ [CLKID_AO_PWM_F_DIV] = &a9_ao_pwm_f_div.hw,
+ [CLKID_AO_PWM_F] = &a9_ao_pwm_f.hw,
+ [CLKID_AO_PWM_G_SEL] = &a9_ao_pwm_g_sel.hw,
+ [CLKID_AO_PWM_G_DIV] = &a9_ao_pwm_g_div.hw,
+ [CLKID_AO_PWM_G] = &a9_ao_pwm_g.hw,
+ [CLKID_AO_RTC_DUALDIV_IN] = &a9_ao_rtc_dualdiv_in.hw,
+ [CLKID_AO_RTC_DUALDIV_DIV] = &a9_ao_rtc_dualdiv_div.hw,
+ [CLKID_AO_RTC_DUALDIV_SEL] = &a9_ao_rtc_dualdiv_sel.hw,
+ [CLKID_AO_RTC_DUALDIV] = &a9_ao_rtc_dualdiv.hw,
+ [CLKID_AO_RTC] = &a9_ao_rtc.hw,
+ [CLKID_AO_CEC_DUALDIV_IN] = &a9_ao_cec_dualdiv_in.hw,
+ [CLKID_AO_CEC_DUALDIV_DIV] = &a9_ao_cec_dualdiv_div.hw,
+ [CLKID_AO_CEC_DUALDIV_SEL] = &a9_ao_cec_dualdiv_sel.hw,
+ [CLKID_AO_CEC_DUALDIV] = &a9_ao_cec_dualdiv.hw,
+ [CLKID_AO_CEC] = &a9_ao_cec.hw,
+};
+
+static const struct meson_clkc_data a9_ao_clkc_data = {
+ .hw_clks = {
+ .hws = a9_ao_hw_clks,
+ .num = ARRAY_SIZE(a9_ao_hw_clks),
+ },
+};
+
+static const struct of_device_id a9_ao_clkc_match_table[] = {
+ {
+ .compatible = "amlogic,a9-aoclkc",
+ .data = &a9_ao_clkc_data,
+ },
+ { }
+};
+MODULE_DEVICE_TABLE(of, a9_ao_clkc_match_table);
+
+static struct platform_driver a9_ao_clkc_driver = {
+ .probe = meson_clkc_mmio_probe,
+ .driver = {
+ .name = "a9-aoclkc",
+ .of_match_table = a9_ao_clkc_match_table,
+ },
+};
+module_platform_driver(a9_ao_clkc_driver);
+
+MODULE_DESCRIPTION("Amlogic A9 Always-ON Clock Controller driver");
+MODULE_AUTHOR("Jian Hu <jian.hu@amlogic.com>");
+MODULE_LICENSE("GPL");
+MODULE_IMPORT_NS("CLK_MESON");
--
2.47.1
^ permalink raw reply related
* [PATCH v3 0/2] clk: amlogic: Add A9 AO clock controller
From: Jian Hu via B4 Relay @ 2026-06-10 8:23 UTC (permalink / raw)
To: Neil Armstrong, Jerome Brunet, Michael Turquette, Stephen Boyd,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Xianwei Zhao,
Kevin Hilman, Martin Blumenstingl
Cc: linux-amlogic, linux-clk, devicetree, linux-kernel,
linux-arm-kernel, Jian Hu, Conor Dooley
This series adds Amlogic A9 AO clock support, including dt-binding and AO clock driver.
Signed-off-by: Jian Hu <jian.hu@amlogic.com>
---
Changes in v3:
- Move COMPILE_TEST after 'depends on ARM64' reported by sashiko-bot.
- Rename i2c3 to i3c reported by sashiko-bot.
- Reword the comment describing ao_xtal_in's flags.
- Use struct clk_init_data to describe ao_xtal_in's hw.init.
- Link to v2: https://lore.kernel.org/r/20260603-a9_aoclk-v2-0-f47ea616ee78@amlogic.com
Changes in v2:
- Split the A9 clock driver and send the AO clock separately.
- Rename aobus to soc.
- Use CLK_HW_INIT_FW_NAME to describe clk_init_data.
- Use CLK_HW_INIT_PARENTS_DATA to describe clk_init_data.
- Use a9_ao prefix for MESON_COMP_SEL.
- Correct duandiv name.
- Fix pwm b reg.
- Link to v1: https://lore.kernel.org/all/20260511-b4-a9_clk-v1-0-41cb4071b7c9@amlogic.com/
---
Jian Hu (2):
dt-bindings: clock: Add Amlogic A9 AO clock controller
clk: amlogic: Add A9 AO clock controller driver
.../bindings/clock/amlogic,a9-aoclkc.yaml | 76 ++++
drivers/clk/meson/Kconfig | 13 +
drivers/clk/meson/Makefile | 1 +
drivers/clk/meson/a9-aoclk.c | 431 +++++++++++++++++++++
include/dt-bindings/clock/amlogic,a9-aoclkc.h | 76 ++++
5 files changed, 597 insertions(+)
---
base-commit: ca89c88bcf69daca829044c638a8163d5ce47af0
change-id: 20260603-a9_aoclk-bbf531badc63
Best regards,
--
Jian Hu <jian.hu@amlogic.com>
^ permalink raw reply
* [soc:soc/drivers] BUILD SUCCESS 3659b131999f71aa5a261e7684821ee355cc0234
From: kernel test robot @ 2026-06-10 8:19 UTC (permalink / raw)
To: Arnd Bergmann; +Cc: linux-arm-kernel, arm
tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git soc/drivers
branch HEAD: 3659b131999f71aa5a261e7684821ee355cc0234 Merge tag 'riscv-soc-drivers-for-v7.2' of https://git.kernel.org/pub/scm/linux/kernel/git/conor/linux into soc/drivers
elapsed time: 844m
configs tested: 228
configs skipped: 2
The following configs have been built successfully.
More configs may be tested in the coming days.
tested configs:
alpha allnoconfig gcc-16.1.0
alpha allyesconfig gcc-16.1.0
alpha defconfig gcc-16.1.0
arc allmodconfig clang-23
arc allmodconfig gcc-16.1.0
arc allnoconfig gcc-16.1.0
arc allyesconfig clang-23
arc allyesconfig gcc-16.1.0
arc defconfig gcc-16.1.0
arc randconfig-001-20260610 gcc-8.5.0
arc randconfig-002-20260610 gcc-8.5.0
arm allnoconfig clang-23
arm allnoconfig gcc-16.1.0
arm allyesconfig clang-23
arm allyesconfig gcc-16.1.0
arm defconfig gcc-16.1.0
arm randconfig-001-20260610 gcc-8.5.0
arm randconfig-002-20260610 gcc-8.5.0
arm randconfig-003-20260610 gcc-8.5.0
arm randconfig-004-20260610 gcc-8.5.0
arm64 allmodconfig clang-23
arm64 allnoconfig gcc-16.1.0
arm64 defconfig gcc-16.1.0
arm64 randconfig-001-20260610 gcc-11.5.0
arm64 randconfig-002-20260610 gcc-11.5.0
arm64 randconfig-003-20260610 gcc-11.5.0
arm64 randconfig-004-20260610 gcc-11.5.0
csky allmodconfig gcc-16.1.0
csky allnoconfig gcc-16.1.0
csky defconfig gcc-16.1.0
csky randconfig-001-20260610 gcc-11.5.0
csky randconfig-002-20260610 gcc-11.5.0
hexagon allmodconfig gcc-16.1.0
hexagon allnoconfig clang-23
hexagon allnoconfig gcc-16.1.0
hexagon defconfig gcc-16.1.0
hexagon randconfig-001 gcc-11.5.0
hexagon randconfig-001-20260610 clang-22
hexagon randconfig-001-20260610 gcc-11.5.0
hexagon randconfig-002 gcc-11.5.0
hexagon randconfig-002-20260610 clang-22
hexagon randconfig-002-20260610 gcc-11.5.0
i386 allmodconfig clang-22
i386 allnoconfig gcc-14
i386 allnoconfig gcc-16.1.0
i386 allyesconfig clang-22
i386 buildonly-randconfig-001-20260610 gcc-14
i386 buildonly-randconfig-002-20260610 gcc-14
i386 buildonly-randconfig-003-20260610 gcc-14
i386 buildonly-randconfig-004-20260610 gcc-14
i386 buildonly-randconfig-005-20260610 gcc-14
i386 buildonly-randconfig-006-20260610 gcc-14
i386 defconfig gcc-16.1.0
i386 randconfig-001-20260610 gcc-14
i386 randconfig-002-20260610 gcc-14
i386 randconfig-003-20260610 gcc-14
i386 randconfig-004-20260610 gcc-14
i386 randconfig-005-20260610 gcc-14
i386 randconfig-006-20260610 gcc-14
i386 randconfig-007-20260610 gcc-14
i386 randconfig-011 gcc-14
i386 randconfig-011-20260610 gcc-14
i386 randconfig-012 gcc-14
i386 randconfig-012-20260610 gcc-14
i386 randconfig-013 gcc-14
i386 randconfig-013-20260610 gcc-14
i386 randconfig-014 gcc-14
i386 randconfig-014-20260610 gcc-14
i386 randconfig-015 gcc-14
i386 randconfig-015-20260610 gcc-14
i386 randconfig-016 gcc-14
i386 randconfig-016-20260610 gcc-14
i386 randconfig-017 gcc-14
i386 randconfig-017-20260610 gcc-14
loongarch allmodconfig clang-19
loongarch allmodconfig clang-23
loongarch allnoconfig clang-20
loongarch allnoconfig gcc-16.1.0
loongarch defconfig clang-23
loongarch randconfig-001 gcc-11.5.0
loongarch randconfig-001-20260610 clang-22
loongarch randconfig-001-20260610 gcc-11.5.0
loongarch randconfig-002 gcc-11.5.0
loongarch randconfig-002-20260610 clang-22
loongarch randconfig-002-20260610 gcc-11.5.0
m68k allmodconfig gcc-16.1.0
m68k allnoconfig gcc-16.1.0
m68k allyesconfig clang-23
m68k allyesconfig gcc-16.1.0
m68k apollo_defconfig gcc-16.1.0
m68k defconfig clang-23
microblaze allnoconfig gcc-16.1.0
microblaze allyesconfig gcc-16.1.0
microblaze defconfig clang-23
mips allmodconfig gcc-16.1.0
mips allnoconfig gcc-16.1.0
mips allyesconfig gcc-16.1.0
mips lemote2f_defconfig gcc-16.1.0
nios2 allmodconfig clang-20
nios2 allmodconfig gcc-11.5.0
nios2 allnoconfig clang-23
nios2 allnoconfig gcc-11.5.0
nios2 defconfig clang-23
nios2 randconfig-001 gcc-11.5.0
nios2 randconfig-001-20260610 clang-22
nios2 randconfig-001-20260610 gcc-11.5.0
nios2 randconfig-002 gcc-11.5.0
nios2 randconfig-002-20260610 clang-22
nios2 randconfig-002-20260610 gcc-11.5.0
openrisc allmodconfig clang-20
openrisc allmodconfig gcc-16.1.0
openrisc allnoconfig clang-23
openrisc allnoconfig gcc-16.1.0
openrisc defconfig gcc-16.1.0
parisc allmodconfig gcc-16.1.0
parisc allnoconfig clang-23
parisc allnoconfig gcc-16.1.0
parisc allyesconfig clang-23
parisc allyesconfig gcc-16.1.0
parisc defconfig gcc-16.1.0
parisc randconfig-001 gcc-8.5.0
parisc randconfig-001-20260610 gcc-8.5.0
parisc randconfig-002 gcc-8.5.0
parisc randconfig-002-20260610 gcc-8.5.0
parisc64 defconfig clang-23
powerpc allmodconfig gcc-16.1.0
powerpc allnoconfig clang-23
powerpc allnoconfig gcc-16.1.0
powerpc microwatt_defconfig gcc-16.1.0
powerpc pasemi_defconfig clang-23
powerpc randconfig-001 gcc-8.5.0
powerpc randconfig-001-20260610 gcc-8.5.0
powerpc randconfig-002 gcc-8.5.0
powerpc randconfig-002-20260610 gcc-8.5.0
powerpc64 randconfig-001 gcc-8.5.0
powerpc64 randconfig-001-20260610 gcc-8.5.0
powerpc64 randconfig-002 gcc-8.5.0
powerpc64 randconfig-002-20260610 gcc-8.5.0
riscv allmodconfig clang-23
riscv allnoconfig clang-23
riscv allnoconfig gcc-16.1.0
riscv allyesconfig clang-23
riscv defconfig gcc-16.1.0
riscv randconfig-001 gcc-16.1.0
riscv randconfig-001-20260610 gcc-16.1.0
riscv randconfig-002 gcc-16.1.0
riscv randconfig-002-20260610 gcc-16.1.0
s390 allmodconfig clang-23
s390 allnoconfig clang-23
s390 allyesconfig gcc-16.1.0
s390 defconfig gcc-16.1.0
s390 randconfig-001 gcc-16.1.0
s390 randconfig-001-20260610 gcc-16.1.0
s390 randconfig-002 gcc-16.1.0
s390 randconfig-002-20260610 gcc-16.1.0
sh allmodconfig gcc-16.1.0
sh allnoconfig clang-23
sh allnoconfig gcc-16.1.0
sh allyesconfig clang-23
sh allyesconfig gcc-16.1.0
sh defconfig gcc-14
sh polaris_defconfig gcc-16.1.0
sh randconfig-001 gcc-16.1.0
sh randconfig-001-20260610 gcc-16.1.0
sh randconfig-002 gcc-16.1.0
sh randconfig-002-20260610 gcc-16.1.0
sh se7724_defconfig gcc-16.1.0
sparc allnoconfig clang-23
sparc allnoconfig gcc-16.1.0
sparc defconfig gcc-16.1.0
sparc randconfig-001-20260610 gcc-14.3.0
sparc randconfig-002-20260610 gcc-14.3.0
sparc64 allmodconfig clang-20
sparc64 defconfig gcc-14
sparc64 randconfig-001-20260610 gcc-14.3.0
sparc64 randconfig-002-20260610 gcc-14.3.0
um allmodconfig clang-23
um allnoconfig clang-16
um allnoconfig clang-23
um allyesconfig gcc-14
um allyesconfig gcc-16.1.0
um defconfig gcc-14
um i386_defconfig gcc-14
um randconfig-001-20260610 gcc-14.3.0
um randconfig-002-20260610 gcc-14.3.0
um x86_64_defconfig gcc-14
x86_64 allmodconfig clang-22
x86_64 allnoconfig clang-22
x86_64 allnoconfig clang-23
x86_64 allyesconfig clang-22
x86_64 buildonly-randconfig-001-20260610 gcc-14
x86_64 buildonly-randconfig-002-20260610 gcc-14
x86_64 buildonly-randconfig-003-20260610 gcc-14
x86_64 buildonly-randconfig-004-20260610 gcc-14
x86_64 buildonly-randconfig-005-20260610 gcc-14
x86_64 buildonly-randconfig-006-20260610 gcc-14
x86_64 defconfig gcc-14
x86_64 kexec clang-22
x86_64 randconfig-001-20260610 gcc-13
x86_64 randconfig-002-20260610 gcc-13
x86_64 randconfig-003-20260610 gcc-13
x86_64 randconfig-004-20260610 gcc-13
x86_64 randconfig-005-20260610 gcc-13
x86_64 randconfig-006-20260610 gcc-13
x86_64 randconfig-011-20260610 gcc-14
x86_64 randconfig-012-20260610 gcc-14
x86_64 randconfig-013-20260610 gcc-14
x86_64 randconfig-014-20260610 gcc-14
x86_64 randconfig-015-20260610 gcc-14
x86_64 randconfig-016-20260610 gcc-14
x86_64 randconfig-071-20260610 gcc-14
x86_64 randconfig-072-20260610 gcc-14
x86_64 randconfig-073-20260610 gcc-14
x86_64 randconfig-074-20260610 gcc-14
x86_64 randconfig-075-20260610 gcc-14
x86_64 randconfig-076-20260610 gcc-14
x86_64 rhel-9.4 clang-22
x86_64 rhel-9.4-bpf gcc-14
x86_64 rhel-9.4-func clang-22
x86_64 rhel-9.4-kselftests clang-22
x86_64 rhel-9.4-kunit gcc-14
x86_64 rhel-9.4-ltp gcc-14
x86_64 rhel-9.4-rust clang-22
xtensa allnoconfig clang-23
xtensa allnoconfig gcc-16.1.0
xtensa allyesconfig clang-20
xtensa randconfig-001-20260610 gcc-14.3.0
xtensa randconfig-002-20260610 gcc-14.3.0
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply
* [PATCH v3 2/2] clk: amlogic: Add A9 peripherals clock controller driver
From: Jian Hu via B4 Relay @ 2026-06-10 8:14 UTC (permalink / raw)
To: Neil Armstrong, Jerome Brunet, Michael Turquette, Stephen Boyd,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Xianwei Zhao,
Kevin Hilman, Martin Blumenstingl
Cc: linux-amlogic, linux-clk, devicetree, linux-kernel,
linux-arm-kernel, Jian Hu
In-Reply-To: <20260610-a9_peripherals-v3-0-d07a78085f71@amlogic.com>
From: Jian Hu <jian.hu@amlogic.com>
Add the peripherals clock controller driver for the Amlogic A9 SoC family.
Signed-off-by: Jian Hu <jian.hu@amlogic.com>
---
drivers/clk/meson/Kconfig | 15 +
drivers/clk/meson/Makefile | 1 +
drivers/clk/meson/a9-peripherals.c | 1925 ++++++++++++++++++++++++++++++++++++
3 files changed, 1941 insertions(+)
diff --git a/drivers/clk/meson/Kconfig b/drivers/clk/meson/Kconfig
index cf8cf3f9e4ee..86d2e270e1b8 100644
--- a/drivers/clk/meson/Kconfig
+++ b/drivers/clk/meson/Kconfig
@@ -132,6 +132,21 @@ config COMMON_CLK_A1_PERIPHERALS
device, A1 SoC Family. Say Y if you want A1 Peripherals clock
controller to work.
+config COMMON_CLK_A9_PERIPHERALS
+ tristate "Amlogic A9 SoC peripherals clock controller support"
+ depends on ARM64 || COMPILE_TEST
+ default ARCH_MESON
+ select COMMON_CLK_MESON_REGMAP
+ select COMMON_CLK_MESON_CLKC_UTILS
+ select COMMON_CLK_MESON_DUALDIV
+ select COMMON_CLK_MESON_VID_PLL_DIV
+ imply COMMON_CLK_SCMI
+ imply COMMON_CLK_A9_PLL
+ help
+ Support for the peripherals clock controller on Amlogic A311Y3 based
+ device, AKA A9. Peripherals are required by most peripheral to operate.
+ Say Y if you want A9 peripherals clock controller to work.
+
config COMMON_CLK_C3_PLL
tristate "Amlogic C3 PLL clock controller"
depends on ARM64
diff --git a/drivers/clk/meson/Makefile b/drivers/clk/meson/Makefile
index c6719694a242..bccd9ace9201 100644
--- a/drivers/clk/meson/Makefile
+++ b/drivers/clk/meson/Makefile
@@ -19,6 +19,7 @@ obj-$(CONFIG_COMMON_CLK_AXG) += axg.o axg-aoclk.o
obj-$(CONFIG_COMMON_CLK_AXG_AUDIO) += axg-audio.o
obj-$(CONFIG_COMMON_CLK_A1_PLL) += a1-pll.o
obj-$(CONFIG_COMMON_CLK_A1_PERIPHERALS) += a1-peripherals.o
+obj-$(CONFIG_COMMON_CLK_A9_PERIPHERALS) += a9-peripherals.o
obj-$(CONFIG_COMMON_CLK_C3_PLL) += c3-pll.o
obj-$(CONFIG_COMMON_CLK_C3_PERIPHERALS) += c3-peripherals.o
obj-$(CONFIG_COMMON_CLK_GXBB) += gxbb.o gxbb-aoclk.o
diff --git a/drivers/clk/meson/a9-peripherals.c b/drivers/clk/meson/a9-peripherals.c
new file mode 100644
index 000000000000..fef48613e186
--- /dev/null
+++ b/drivers/clk/meson/a9-peripherals.c
@@ -0,0 +1,1925 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR MIT)
+/*
+ * Copyright (C) 2026 Amlogic, Inc. All rights reserved
+ */
+
+#include <dt-bindings/clock/amlogic,a9-peripherals-clkc.h>
+#include <linux/clk-provider.h>
+#include <linux/platform_device.h>
+#include "clk-regmap.h"
+#include "clk-dualdiv.h"
+#include "meson-clkc-utils.h"
+#include "vid-pll-div.h"
+
+#define SYS_CLK_EN0_REG0 0x30
+#define SYS_CLK_EN0_REG1 0x34
+#define SYS_CLK_EN0_REG2 0x38
+#define SYS_CLK_EN0_REG3 0x3c
+#define SD_EMMC_CLK_CTRL0 0x90
+#define SD_EMMC_CLK_CTRL1 0x94
+#define PWM_CLK_H_CTRL 0xbc
+#define PWM_CLK_I_CTRL 0xc0
+#define PWM_CLK_J_CTRL 0xc4
+#define PWM_CLK_K_CTRL 0xc8
+#define PWM_CLK_L_CTRL 0xcc
+#define PWM_CLK_M_CTRL 0xd0
+#define PWM_CLK_N_CTRL 0xd4
+#define SPISG_CLK_CTRL 0x100
+#define SPISG_CLK_CTRL1 0x104
+#define SAR_CLK_CTRL 0x150
+#define AMFC_CLK_CTRL 0x154
+#define NNA_CLK_CTRL 0x15c
+#define USB_CLK_CTRL 0x160
+#define PCIE_TL_CLK_CTRL 0x164
+#define CMPR_CLK_CTRL 0x168
+#define DEWARP_CLK_CTRL 0x16c
+#define SC_CLK_CTRL 0x170
+#define DPTX_CLK_CTRL 0x178
+#define ISP_CLK_CTRL 0x17c
+#define CVE_CLK_CTRL 0x180
+#define PP_CLK_CTRL 0x184
+#define GLB_CLK_CTRL 0x188
+#define USB_CLK_CTRL0 0x18c
+#define USB_CLK_CTRL1 0x190
+#define CAN_CLK_CTRL 0x194
+#define CAN_CLK_CTRL1 0x198
+#define I3C_CLK_CTRL 0x19c
+#define TS_CLK_CTRL 0x1a0
+#define ETH_CLK_CTRL 0x1a4
+#define GEN_CLK_CTRL 0x1a8
+#define CLK12_24_CTRL 0x1ac
+#define MALI_CLK_CTRL 0x200
+#define MALI_STACK_CLK_CTRL 0x204
+#define DSPA_CLK_CTRL 0x220
+#define HEVCF_CLK_CTRL 0x240
+#define HCODEC_CLK_CTRL 0x244
+#define VPU_CLK_CTRL 0x260
+#define VAPB_CLK_CTRL 0x268
+#define VPU_CLKB_CTRL 0x280
+#define HDMI_CLK_CTRL 0x284
+#define HTX_CLK_CTRL 0x28c
+#define HTX_CLK_CTRL1 0x290
+#define HRX_CLK_CTRL 0x294
+#define HRX_CLK_CTRL1 0x298
+#define HRX_CLK_CTRL2 0x29c
+#define HRX_CLK_CTRL3 0x2a0
+#define VID_LOCK_CLK_CTRL 0x2a4
+#define VDIN_MEAS_CLK_CTRL 0x2a8
+#define VID_PLL_CLK_DIV 0x2b0
+#define VID_CLK_CTRL 0x2c0
+#define VID_CLK_CTRL2 0x2c4
+#define VID_CLK_DIV 0x2c8
+#define VIID_CLK_DIV 0x2cc
+#define VIID_CLK_CTRL 0x2d0
+#define MIPI_CSI_PHY_CLK_CTRL 0x2e0
+#define DSI_MEAS_CLK_CTRL 0x2f4
+
+#define A9_COMP_SEL(_name, _reg, _shift, _mask, _pdata, _table) \
+ MESON_COMP_SEL(a9_, _name, _reg, _shift, _mask, _pdata, _table, 0, 0)
+
+#define A9_COMP_DIV(_name, _reg, _shift, _width) \
+ MESON_COMP_DIV(a9_, _name, _reg, _shift, _width, 0, CLK_SET_RATE_PARENT)
+
+#define A9_COMP_GATE(_name, _reg, _bit, _iflags) \
+ MESON_COMP_GATE(a9_, _name, _reg, _bit, CLK_SET_RATE_PARENT | (_iflags))
+
+static const struct clk_parent_data a9_sys_pclk_parents = { .fw_name = "sys" };
+
+#define A9_SYS_PCLK(_name, _reg, _bit) \
+ MESON_PCLK(a9_##_name, _reg, _bit, &a9_sys_pclk_parents, 0)
+
+static A9_SYS_PCLK(sys_am_axi, SYS_CLK_EN0_REG0, 0);
+static A9_SYS_PCLK(sys_dos, SYS_CLK_EN0_REG0, 1);
+static A9_SYS_PCLK(sys_mipi_dsi, SYS_CLK_EN0_REG0, 3);
+static A9_SYS_PCLK(sys_eth_phy, SYS_CLK_EN0_REG0, 4);
+static A9_SYS_PCLK(sys_amfc, SYS_CLK_EN0_REG0, 5);
+static A9_SYS_PCLK(sys_mali, SYS_CLK_EN0_REG0, 6);
+static A9_SYS_PCLK(sys_nna, SYS_CLK_EN0_REG0, 7);
+static A9_SYS_PCLK(sys_eth_axi, SYS_CLK_EN0_REG0, 8);
+static A9_SYS_PCLK(sys_dp_apb, SYS_CLK_EN0_REG0, 9);
+static A9_SYS_PCLK(sys_edptx_apb, SYS_CLK_EN0_REG0, 10);
+static A9_SYS_PCLK(sys_u3hsg, SYS_CLK_EN0_REG0, 11);
+static A9_SYS_PCLK(sys_aucpu, SYS_CLK_EN0_REG0, 14);
+static A9_SYS_PCLK(sys_glb, SYS_CLK_EN0_REG0, 15);
+static A9_SYS_PCLK(sys_combo_dphy_apb, SYS_CLK_EN0_REG0, 17);
+static A9_SYS_PCLK(sys_hdmirx_apb, SYS_CLK_EN0_REG0, 18);
+static A9_SYS_PCLK(sys_hdmirx_pclk, SYS_CLK_EN0_REG0, 19);
+static A9_SYS_PCLK(sys_mipi_dsi_phy, SYS_CLK_EN0_REG0, 20);
+static A9_SYS_PCLK(sys_can0, SYS_CLK_EN0_REG0, 21);
+static A9_SYS_PCLK(sys_can1, SYS_CLK_EN0_REG0, 22);
+static A9_SYS_PCLK(sys_sd_emmc_a, SYS_CLK_EN0_REG0, 24);
+static A9_SYS_PCLK(sys_sd_emmc_b, SYS_CLK_EN0_REG0, 25);
+static A9_SYS_PCLK(sys_sd_emmc_c, SYS_CLK_EN0_REG0, 26);
+static A9_SYS_PCLK(sys_sc, SYS_CLK_EN0_REG0, 27);
+static A9_SYS_PCLK(sys_acodec, SYS_CLK_EN0_REG0, 28);
+static A9_SYS_PCLK(sys_mipi_isp, SYS_CLK_EN0_REG0, 29);
+static A9_SYS_PCLK(sys_msr, SYS_CLK_EN0_REG0, 30);
+static A9_SYS_PCLK(sys_audio, SYS_CLK_EN0_REG1, 0);
+static A9_SYS_PCLK(sys_mipi_dsi_b, SYS_CLK_EN0_REG1, 1);
+static A9_SYS_PCLK(sys_mipi_dsi1_phy, SYS_CLK_EN0_REG1, 2);
+static A9_SYS_PCLK(sys_eth, SYS_CLK_EN0_REG1, 3);
+static A9_SYS_PCLK(sys_eth_1g_mac, SYS_CLK_EN0_REG1, 4);
+static A9_SYS_PCLK(sys_uart_a, SYS_CLK_EN0_REG1, 5);
+static A9_SYS_PCLK(sys_uart_f, SYS_CLK_EN0_REG1, 10);
+static A9_SYS_PCLK(sys_ts_a55, SYS_CLK_EN0_REG1, 11);
+static A9_SYS_PCLK(sys_eth_1g_axi, SYS_CLK_EN0_REG1, 12);
+static A9_SYS_PCLK(sys_ts_dos, SYS_CLK_EN0_REG1, 13);
+static A9_SYS_PCLK(sys_u3drd_b, SYS_CLK_EN0_REG1, 14);
+static A9_SYS_PCLK(sys_ts_core, SYS_CLK_EN0_REG1, 15);
+static A9_SYS_PCLK(sys_ts_pll, SYS_CLK_EN0_REG1, 16);
+static A9_SYS_PCLK(sys_csi_dig_clkin, SYS_CLK_EN0_REG1, 18);
+static A9_SYS_PCLK(sys_cve, SYS_CLK_EN0_REG1, 19);
+static A9_SYS_PCLK(sys_ge2d, SYS_CLK_EN0_REG1, 20);
+static A9_SYS_PCLK(sys_spisg, SYS_CLK_EN0_REG1, 21);
+static A9_SYS_PCLK(sys_u3drd_1, SYS_CLK_EN0_REG1, 22);
+static A9_SYS_PCLK(sys_u2h, SYS_CLK_EN0_REG1, 23);
+static A9_SYS_PCLK(sys_pcie_mac_a, SYS_CLK_EN0_REG1, 24);
+static A9_SYS_PCLK(sys_u3drd_a, SYS_CLK_EN0_REG1, 25);
+static A9_SYS_PCLK(sys_u2drd, SYS_CLK_EN0_REG1, 26);
+static A9_SYS_PCLK(sys_pcie_phy, SYS_CLK_EN0_REG1, 27);
+static A9_SYS_PCLK(sys_pcie_mac_b, SYS_CLK_EN0_REG1, 28);
+static A9_SYS_PCLK(sys_periph, SYS_CLK_EN0_REG1, 29);
+static A9_SYS_PCLK(sys_pio, SYS_CLK_EN0_REG2, 0);
+static A9_SYS_PCLK(sys_i3c, SYS_CLK_EN0_REG2, 1);
+static A9_SYS_PCLK(sys_i2c_m_e, SYS_CLK_EN0_REG2, 2);
+static A9_SYS_PCLK(sys_i2c_m_f, SYS_CLK_EN0_REG2, 3);
+static A9_SYS_PCLK(sys_hdmitx_apb, SYS_CLK_EN0_REG2, 4);
+static A9_SYS_PCLK(sys_i2c_m_i, SYS_CLK_EN0_REG2, 5);
+static A9_SYS_PCLK(sys_i2c_m_g, SYS_CLK_EN0_REG2, 6);
+static A9_SYS_PCLK(sys_i2c_m_h, SYS_CLK_EN0_REG2, 7);
+static A9_SYS_PCLK(sys_hdmi20_aes, SYS_CLK_EN0_REG2, 9);
+static A9_SYS_PCLK(sys_csi2_host, SYS_CLK_EN0_REG2, 16);
+static A9_SYS_PCLK(sys_csi2_adapt, SYS_CLK_EN0_REG2, 17);
+static A9_SYS_PCLK(sys_dspa, SYS_CLK_EN0_REG2, 21);
+static A9_SYS_PCLK(sys_pp_dma, SYS_CLK_EN0_REG2, 22);
+static A9_SYS_PCLK(sys_pp_wrapper, SYS_CLK_EN0_REG2, 23);
+static A9_SYS_PCLK(sys_vpu_intr, SYS_CLK_EN0_REG2, 25);
+static A9_SYS_PCLK(sys_csi2_phy, SYS_CLK_EN0_REG2, 27);
+static A9_SYS_PCLK(sys_saradc, SYS_CLK_EN0_REG2, 28);
+static A9_SYS_PCLK(sys_pwm_j, SYS_CLK_EN0_REG2, 30);
+static A9_SYS_PCLK(sys_pwm_i, SYS_CLK_EN0_REG2, 31);
+static A9_SYS_PCLK(sys_pwm_h, SYS_CLK_EN0_REG3, 0);
+static A9_SYS_PCLK(sys_pwm_n, SYS_CLK_EN0_REG3, 8);
+static A9_SYS_PCLK(sys_pwm_m, SYS_CLK_EN0_REG3, 9);
+static A9_SYS_PCLK(sys_pwm_l, SYS_CLK_EN0_REG3, 10);
+static A9_SYS_PCLK(sys_pwm_k, SYS_CLK_EN0_REG3, 11);
+
+/* Channel 5 is unconnected. */
+static u32 a9_sd_emmc_parents_val_table[] = { 0, 1, 2, 3, 4, 6, 7 };
+static const struct clk_parent_data a9_sd_emmc_parents[] = {
+ { .fw_name = "xtal", },
+ { .fw_name = "fdiv2", },
+ { .fw_name = "fdiv3", },
+ { .fw_name = "hifi0", },
+ { .fw_name = "fdiv2p5", },
+ { .fw_name = "gp1", },
+ { .fw_name = "gp0", }
+};
+
+static A9_COMP_SEL(sd_emmc_a, SD_EMMC_CLK_CTRL0, 9, 0x7, a9_sd_emmc_parents,
+ a9_sd_emmc_parents_val_table);
+static A9_COMP_DIV(sd_emmc_a, SD_EMMC_CLK_CTRL0, 0, 7);
+static A9_COMP_GATE(sd_emmc_a, SD_EMMC_CLK_CTRL0, 8, 0);
+
+static A9_COMP_SEL(sd_emmc_b, SD_EMMC_CLK_CTRL0, 25, 0x7, a9_sd_emmc_parents,
+ a9_sd_emmc_parents_val_table);
+static A9_COMP_DIV(sd_emmc_b, SD_EMMC_CLK_CTRL0, 16, 7);
+static A9_COMP_GATE(sd_emmc_b, SD_EMMC_CLK_CTRL0, 24, 0);
+
+static A9_COMP_SEL(sd_emmc_c, SD_EMMC_CLK_CTRL1, 9, 0x7, a9_sd_emmc_parents,
+ a9_sd_emmc_parents_val_table);
+static A9_COMP_DIV(sd_emmc_c, SD_EMMC_CLK_CTRL1, 0, 7);
+static A9_COMP_GATE(sd_emmc_c, SD_EMMC_CLK_CTRL1, 8, 0);
+
+static const struct clk_parent_data a9_pwm_parents[] = {
+ { .fw_name = "xtal", },
+ { .fw_name = "fdiv5", },
+ { .fw_name = "fdiv4", },
+ { .fw_name = "fdiv3", }
+};
+
+static A9_COMP_SEL(pwm_h, PWM_CLK_H_CTRL, 9, 0x7, a9_pwm_parents, NULL);
+static A9_COMP_DIV(pwm_h, PWM_CLK_H_CTRL, 0, 8);
+static A9_COMP_GATE(pwm_h, PWM_CLK_H_CTRL, 8, 0);
+
+static A9_COMP_SEL(pwm_i, PWM_CLK_I_CTRL, 9, 0x7, a9_pwm_parents, NULL);
+static A9_COMP_DIV(pwm_i, PWM_CLK_I_CTRL, 0, 8);
+static A9_COMP_GATE(pwm_i, PWM_CLK_I_CTRL, 8, 0);
+
+static A9_COMP_SEL(pwm_j, PWM_CLK_J_CTRL, 9, 0x7, a9_pwm_parents, NULL);
+static A9_COMP_DIV(pwm_j, PWM_CLK_J_CTRL, 0, 8);
+static A9_COMP_GATE(pwm_j, PWM_CLK_J_CTRL, 8, 0);
+
+static A9_COMP_SEL(pwm_k, PWM_CLK_K_CTRL, 9, 0x7, a9_pwm_parents, NULL);
+static A9_COMP_DIV(pwm_k, PWM_CLK_K_CTRL, 0, 8);
+static A9_COMP_GATE(pwm_k, PWM_CLK_K_CTRL, 8, 0);
+
+static A9_COMP_SEL(pwm_l, PWM_CLK_L_CTRL, 9, 0x7, a9_pwm_parents, NULL);
+static A9_COMP_DIV(pwm_l, PWM_CLK_L_CTRL, 0, 8);
+static A9_COMP_GATE(pwm_l, PWM_CLK_L_CTRL, 8, 0);
+
+static A9_COMP_SEL(pwm_m, PWM_CLK_M_CTRL, 9, 0x7, a9_pwm_parents, NULL);
+static A9_COMP_DIV(pwm_m, PWM_CLK_M_CTRL, 0, 8);
+static A9_COMP_GATE(pwm_m, PWM_CLK_M_CTRL, 8, 0);
+
+static A9_COMP_SEL(pwm_n, PWM_CLK_N_CTRL, 9, 0x7, a9_pwm_parents, NULL);
+static A9_COMP_DIV(pwm_n, PWM_CLK_N_CTRL, 0, 8);
+static A9_COMP_GATE(pwm_n, PWM_CLK_N_CTRL, 8, 0);
+
+static const struct clk_parent_data a9_spisg_parents[] = {
+ { .fw_name = "xtal", },
+ { .fw_name = "sys", },
+ { .fw_name = "fdiv4", },
+ { .fw_name = "fdiv3", },
+ { .fw_name = "fdiv2", },
+ { .fw_name = "fdiv5", },
+ { .fw_name = "fdiv7", },
+ { .fw_name = "gp0", }
+};
+
+static A9_COMP_SEL(spisg, SPISG_CLK_CTRL, 9, 0x7, a9_spisg_parents, NULL);
+static A9_COMP_DIV(spisg, SPISG_CLK_CTRL, 0, 6);
+static A9_COMP_GATE(spisg, SPISG_CLK_CTRL, 8, 0);
+
+static A9_COMP_SEL(spisg1, SPISG_CLK_CTRL, 25, 0x7, a9_spisg_parents, NULL);
+static A9_COMP_DIV(spisg1, SPISG_CLK_CTRL, 16, 6);
+static A9_COMP_GATE(spisg1, SPISG_CLK_CTRL, 24, 0);
+
+static A9_COMP_SEL(spisg2, SPISG_CLK_CTRL1, 9, 0x7, a9_spisg_parents, NULL);
+static A9_COMP_DIV(spisg2, SPISG_CLK_CTRL1, 0, 6);
+static A9_COMP_GATE(spisg2, SPISG_CLK_CTRL1, 8, 0);
+
+static const struct clk_parent_data a9_saradc_parents[] = {
+ { .fw_name = "xtal", },
+ { .fw_name = "sys", }
+};
+
+static A9_COMP_SEL(saradc, SAR_CLK_CTRL, 9, 0x7, a9_saradc_parents, NULL);
+static A9_COMP_DIV(saradc, SAR_CLK_CTRL, 0, 8);
+static A9_COMP_GATE(saradc, SAR_CLK_CTRL, 8, 0);
+
+static const struct clk_parent_data a9_amfc_parents[] = {
+ { .fw_name = "xtal", },
+ { .fw_name = "sys", },
+ { .fw_name = "fdiv2", },
+ { .fw_name = "fdiv2p5", },
+ { .fw_name = "fdiv3", },
+ { .fw_name = "fdiv4", },
+ { .fw_name = "fdiv5", },
+ { .fw_name = "fdiv7", }
+};
+
+static A9_COMP_SEL(amfc, AMFC_CLK_CTRL, 9, 0x7, a9_amfc_parents, NULL);
+static A9_COMP_DIV(amfc, AMFC_CLK_CTRL, 0, 6);
+static A9_COMP_GATE(amfc, AMFC_CLK_CTRL, 8, 0);
+
+static const struct clk_parent_data a9_nna_parents[] = {
+ { .fw_name = "xtal", },
+ { .fw_name = "fdiv2p5", },
+ { .fw_name = "fdiv4", },
+ { .fw_name = "fdiv3", },
+ { .fw_name = "fdiv5", },
+ { .fw_name = "fdiv2", },
+ { .fw_name = "gp2", },
+ { .fw_name = "hifi0", }
+};
+
+static A9_COMP_SEL(nna, NNA_CLK_CTRL, 9, 0x7, a9_nna_parents, NULL);
+static A9_COMP_DIV(nna, NNA_CLK_CTRL, 0, 7);
+static A9_COMP_GATE(nna, NNA_CLK_CTRL, 8, 0);
+
+/* Channel 5 and 6 are unconnected. */
+static u32 a9_usb_250m_parents_val_table[] = { 0, 1, 2, 3, 4, 7 };
+static const struct clk_parent_data a9_usb_250m_parents[] = {
+ { .fw_name = "fdiv4", },
+ { .fw_name = "fdiv3", },
+ { .fw_name = "fdiv5", },
+ { .fw_name = "fdiv2", },
+ { .fw_name = "fdiv7", },
+ { .fw_name = "fdiv2p5", }
+};
+
+static A9_COMP_SEL(usb_250m, USB_CLK_CTRL, 9, 0x7, a9_usb_250m_parents,
+ a9_usb_250m_parents_val_table);
+static A9_COMP_DIV(usb_250m, USB_CLK_CTRL, 0, 7);
+static A9_COMP_GATE(usb_250m, USB_CLK_CTRL, 8, 0);
+
+static const struct clk_parent_data a9_usb_48m_pre_parents[] = {
+ { .fw_name = "gp0", },
+ { .fw_name = "gp1", },
+ { .fw_name = "gp2", },
+ { .fw_name = "fdiv2", },
+};
+
+static A9_COMP_SEL(usb_48m_pre, USB_CLK_CTRL, 25, 0x3, a9_usb_48m_pre_parents,
+ NULL);
+static A9_COMP_DIV(usb_48m_pre, USB_CLK_CTRL, 16, 7);
+static A9_COMP_GATE(usb_48m_pre, USB_CLK_CTRL, 24, 0);
+
+static const struct clk_parent_data a9_pcie_tl_parents[] = {
+ { .fw_name = "fdiv4", },
+ { .fw_name = "fdiv3", },
+ { .fw_name = "fdiv5", },
+ { .fw_name = "fdiv2", },
+ { .fw_name = "fdiv2p5", },
+ { .fw_name = "gp0", },
+ { .fw_name = "sys", },
+ { .fw_name = "xtal", }
+};
+
+static A9_COMP_SEL(pcie_tl, PCIE_TL_CLK_CTRL, 9, 0x7, a9_pcie_tl_parents,
+ NULL);
+static A9_COMP_DIV(pcie_tl, PCIE_TL_CLK_CTRL, 0, 7);
+static A9_COMP_GATE(pcie_tl, PCIE_TL_CLK_CTRL, 8, 0);
+
+static A9_COMP_SEL(pcie1_tl, PCIE_TL_CLK_CTRL, 25, 0x7, a9_pcie_tl_parents,
+ NULL);
+static A9_COMP_DIV(pcie1_tl, PCIE_TL_CLK_CTRL, 16, 7);
+static A9_COMP_GATE(pcie1_tl, PCIE_TL_CLK_CTRL, 24, 0);
+
+static const struct clk_parent_data a9_cmpr_parents[] = {
+ { .fw_name = "xtal", },
+ { .fw_name = "fdiv2p5", },
+ { .fw_name = "fdiv3", },
+ { .fw_name = "fdiv4", },
+ { .fw_name = "fdiv5", },
+ { .fw_name = "fdiv7", },
+ { .fw_name = "hifi0", },
+ { .fw_name = "gp1", }
+};
+
+static A9_COMP_SEL(cmpr, CMPR_CLK_CTRL, 25, 0x7, a9_cmpr_parents, NULL);
+static A9_COMP_DIV(cmpr, CMPR_CLK_CTRL, 16, 7);
+static A9_COMP_GATE(cmpr, CMPR_CLK_CTRL, 24, 0);
+
+static const struct clk_parent_data a9_dewarpa_parents[] = {
+ { .fw_name = "fdiv2p5", },
+ { .fw_name = "fdiv3", },
+ { .fw_name = "fdiv4", },
+ { .fw_name = "fdiv5", },
+ { .fw_name = "fdiv7", },
+ { .fw_name = "gp0", },
+ { .fw_name = "hifi0", },
+ { .fw_name = "gp1", }
+};
+
+static A9_COMP_SEL(dewarpa, DEWARP_CLK_CTRL, 9, 0x7, a9_dewarpa_parents, NULL);
+static A9_COMP_DIV(dewarpa, DEWARP_CLK_CTRL, 0, 7);
+static A9_COMP_GATE(dewarpa, DEWARP_CLK_CTRL, 8, 0);
+
+static const struct clk_parent_data a9_sc_parents[] = {
+ { .fw_name = "fdiv2", },
+ { .fw_name = "fdiv3", },
+ { .fw_name = "fdiv5", },
+ { .fw_name = "xtal", }
+};
+
+static A9_COMP_SEL(sc_pre, SC_CLK_CTRL, 9, 0x7, a9_sc_parents, NULL);
+static A9_COMP_DIV(sc_pre, SC_CLK_CTRL, 0, 8);
+static A9_COMP_GATE(sc_pre, SC_CLK_CTRL, 8, 0);
+
+static struct clk_regmap a9_sc = {
+ .data = &(struct clk_regmap_div_data) {
+ .offset = SC_CLK_CTRL,
+ .shift = 16,
+ .width = 4,
+ },
+ .hw.init = CLK_HW_INIT_HW("sc", &a9_sc_pre.hw,
+ &clk_regmap_divider_ops, CLK_SET_RATE_PARENT),
+};
+
+static const struct clk_parent_data a9_dptx_apb2_parents[] = {
+ { .fw_name = "xtal", },
+ { .fw_name = "sys", },
+ { .fw_name = "fdiv4", },
+ { .fw_name = "fdiv5", }
+};
+
+static A9_COMP_SEL(dptx_apb2, DPTX_CLK_CTRL, 9, 0x7, a9_dptx_apb2_parents, NULL);
+static A9_COMP_DIV(dptx_apb2, DPTX_CLK_CTRL, 0, 7);
+static A9_COMP_GATE(dptx_apb2, DPTX_CLK_CTRL, 8, 0);
+
+static const struct clk_parent_data a9_dptx_aud_parents[] = {
+ { .fw_name = "xtal", },
+ { .fw_name = "sys", },
+ { .fw_name = "fdiv3", },
+ { .fw_name = "fdiv4", }
+};
+
+static A9_COMP_SEL(dptx_aud, DPTX_CLK_CTRL, 25, 0x7, a9_dptx_aud_parents, NULL);
+static A9_COMP_DIV(dptx_aud, DPTX_CLK_CTRL, 16, 7);
+static A9_COMP_GATE(dptx_aud, DPTX_CLK_CTRL, 24, 0);
+
+static const struct clk_parent_data a9_isp_parents[] = {
+ { .fw_name = "fdiv2p5", },
+ { .fw_name = "fdiv3", },
+ { .fw_name = "fdiv4", },
+ { .fw_name = "fdiv5", },
+ { .fw_name = "gp0", },
+ { .fw_name = "hifi0", },
+ { .fw_name = "fdiv2", },
+ { .fw_name = "xtal", }
+};
+
+static A9_COMP_SEL(isp, ISP_CLK_CTRL, 9, 0x7, a9_isp_parents, NULL);
+static A9_COMP_DIV(isp, ISP_CLK_CTRL, 0, 7);
+static A9_COMP_GATE(isp, ISP_CLK_CTRL, 8, 0);
+
+static const struct clk_parent_data a9_cve_vge_parents[] = {
+ { .fw_name = "xtal", },
+ { .fw_name = "fdiv2p5", },
+ { .fw_name = "fdiv3", },
+ { .fw_name = "fdiv4", },
+ { .fw_name = "hifi0", },
+ { .fw_name = "fdiv5", },
+ { .fw_name = "gp0", },
+ { .fw_name = "rtc", }
+};
+
+static A9_COMP_SEL(cve, CVE_CLK_CTRL, 9, 0x7, a9_cve_vge_parents, NULL);
+static A9_COMP_DIV(cve, CVE_CLK_CTRL, 0, 7);
+static A9_COMP_GATE(cve, CVE_CLK_CTRL, 8, 0);
+
+static A9_COMP_SEL(vge, CVE_CLK_CTRL, 25, 0x7, a9_cve_vge_parents, NULL);
+static A9_COMP_DIV(vge, CVE_CLK_CTRL, 16, 7);
+static A9_COMP_GATE(vge, CVE_CLK_CTRL, 24, 0);
+
+static const struct clk_parent_data a9_pp_parents[] = {
+ { .fw_name = "fdiv4", },
+ { .fw_name = "fdiv3", },
+ { .fw_name = "fdiv5", },
+ { .fw_name = "fdiv2", },
+ { .fw_name = "fdiv2p5", },
+ { .fw_name = "gp0", },
+ { .fw_name = "sys", },
+ { .fw_name = "xtal", }
+};
+
+static A9_COMP_SEL(pp, PP_CLK_CTRL, 9, 0x7, a9_pp_parents, NULL);
+static A9_COMP_DIV(pp, PP_CLK_CTRL, 0, 6);
+static A9_COMP_GATE(pp, PP_CLK_CTRL, 8, 0);
+
+/* Channel 6 is unconnected. */
+static u32 a9_glb_parents_val_table[] = { 0, 1, 2, 3, 4, 5, 7 };
+static struct clk_regmap a9_dspa;
+
+static const struct clk_parent_data a9_glb_parents[] = {
+ { .fw_name = "xtal", },
+ { .hw = &a9_dspa.hw },
+ { .fw_name = "fdiv3", },
+ { .fw_name = "fdiv4", },
+ { .fw_name = "fdiv5", },
+ { .hw = &a9_isp.hw },
+ { .fw_name = "rtc", }
+};
+
+static A9_COMP_SEL(glb, GLB_CLK_CTRL, 9, 0x7, a9_glb_parents,
+ a9_glb_parents_val_table);
+static A9_COMP_DIV(glb, GLB_CLK_CTRL, 0, 7);
+static A9_COMP_GATE(glb, GLB_CLK_CTRL, 8, 0);
+
+static struct clk_regmap a9_usb_48m_dualdiv_in = {
+ .data = &(struct clk_regmap_gate_data) {
+ .offset = USB_CLK_CTRL,
+ .bit_idx = 31,
+ },
+ .hw.init = CLK_HW_INIT_HW("usb_48m_dualdiv_in", &a9_usb_48m_pre.hw,
+ &clk_regmap_gate_ops, 0),
+};
+
+static const struct meson_clk_dualdiv_param a9_usb_48m_dualdiv_div_table[] = {
+ { 733, 732, 8, 11, 1 },
+ { /* sentinel */ }
+};
+
+static struct clk_regmap a9_usb_48m_dualdiv_div = {
+ .data = &(struct meson_clk_dualdiv_data) {
+ .n1 = {
+ .reg_off = USB_CLK_CTRL0,
+ .shift = 0,
+ .width = 12,
+ },
+ .n2 = {
+ .reg_off = USB_CLK_CTRL0,
+ .shift = 12,
+ .width = 12,
+ },
+ .m1 = {
+ .reg_off = USB_CLK_CTRL1,
+ .shift = 0,
+ .width = 12,
+ },
+ .m2 = {
+ .reg_off = USB_CLK_CTRL1,
+ .shift = 12,
+ .width = 12,
+ },
+ .dual = {
+ .reg_off = USB_CLK_CTRL0,
+ .shift = 28,
+ .width = 1,
+ },
+ .table = a9_usb_48m_dualdiv_div_table,
+ },
+ .hw.init = CLK_HW_INIT_HW("usb_48m_dualdiv_div", &a9_usb_48m_dualdiv_in.hw,
+ &meson_clk_dualdiv_ops, 0),
+};
+
+static struct clk_regmap a9_usb_48m_dualdiv_sel = {
+ .data = &(struct clk_regmap_mux_data) {
+ .offset = USB_CLK_CTRL1,
+ .mask = 0x1,
+ .shift = 24,
+ },
+ .hw.init = CLK_HW_INIT_PARENTS_HW("usb_48m_dualdiv_sel",
+ ((const struct clk_hw *[]) {
+ &a9_usb_48m_dualdiv_in.hw,
+ &a9_usb_48m_dualdiv_div.hw,
+ }), &clk_regmap_mux_ops, CLK_SET_RATE_PARENT),
+};
+
+static struct clk_regmap a9_usb_48m_dualdiv = {
+ .data = &(struct clk_regmap_gate_data) {
+ .offset = USB_CLK_CTRL0,
+ .bit_idx = 30,
+ },
+ .hw.init = CLK_HW_INIT_HW("usb_48m_dualdiv", &a9_usb_48m_dualdiv_sel.hw,
+ &clk_regmap_gate_ops, CLK_SET_RATE_PARENT),
+};
+
+static struct clk_regmap a9_usb_48m = {
+ .data = &(struct clk_regmap_mux_data) {
+ .offset = USB_CLK_CTRL1,
+ .mask = 0x3,
+ .shift = 30,
+ },
+ .hw.init = CLK_HW_INIT_PARENTS_HW("usb_48m",
+ ((const struct clk_hw *[]) {
+ &a9_usb_48m_pre.hw,
+ &a9_usb_48m_dualdiv.hw,
+ }), &clk_regmap_mux_ops, CLK_SET_RATE_PARENT),
+};
+
+/* Channel 3 is unconnected. */
+static u32 a9_can_pe_parents_val_table[] = { 0, 1, 3 };
+static const struct clk_parent_data a9_can_pe_parents[] = {
+ { .fw_name = "sys", },
+ { .fw_name = "xtal", },
+ { .fw_name = "fdiv5", }
+};
+
+static A9_COMP_SEL(can_pe, CAN_CLK_CTRL, 9, 0x7, a9_can_pe_parents,
+ a9_can_pe_parents_val_table);
+static A9_COMP_DIV(can_pe, CAN_CLK_CTRL, 0, 7);
+static A9_COMP_GATE(can_pe, CAN_CLK_CTRL, 8, 0);
+
+static A9_COMP_SEL(can1_pe, CAN_CLK_CTRL, 25, 0x7, a9_can_pe_parents,
+ a9_can_pe_parents_val_table);
+static A9_COMP_DIV(can1_pe, CAN_CLK_CTRL, 16, 7);
+static A9_COMP_GATE(can1_pe, CAN_CLK_CTRL, 24, 0);
+
+static const struct clk_parent_data a9_can_filter_parents[] = {
+ { .fw_name = "sys", },
+ { .fw_name = "xtal", },
+ { .fw_name = "fdiv4", },
+ { .fw_name = "fdiv5", }
+};
+
+static A9_COMP_SEL(can_filter, CAN_CLK_CTRL1, 9, 0x7, a9_can_filter_parents,
+ NULL);
+static A9_COMP_DIV(can_filter, CAN_CLK_CTRL1, 0, 7);
+static A9_COMP_GATE(can_filter, CAN_CLK_CTRL1, 8, 0);
+
+static A9_COMP_SEL(can1_filter, CAN_CLK_CTRL1, 25, 0x7, a9_can_filter_parents,
+ NULL);
+static A9_COMP_DIV(can1_filter, CAN_CLK_CTRL1, 16, 7);
+static A9_COMP_GATE(can1_filter, CAN_CLK_CTRL1, 24, 0);
+
+static const struct clk_parent_data a9_i3c_parents[] = {
+ { .fw_name = "sys", },
+ { .fw_name = "xtal", },
+ { .fw_name = "fdiv5", }
+};
+
+static A9_COMP_SEL(i3c, I3C_CLK_CTRL, 9, 0x7, a9_i3c_parents, NULL);
+static A9_COMP_DIV(i3c, I3C_CLK_CTRL, 0, 8);
+static A9_COMP_GATE(i3c, I3C_CLK_CTRL, 8, 0);
+
+static struct clk_regmap a9_ts_div = {
+ .data = &(struct clk_regmap_div_data) {
+ .offset = TS_CLK_CTRL,
+ .shift = 0,
+ .width = 8,
+ },
+ .hw.init = CLK_HW_INIT_FW_NAME("ts_div", "xtal",
+ &clk_regmap_divider_ops, 0),
+};
+
+static struct clk_regmap a9_ts = {
+ .data = &(struct clk_regmap_gate_data) {
+ .offset = TS_CLK_CTRL,
+ .bit_idx = 8,
+ },
+ .hw.init = CLK_HW_INIT_HW("ts", &a9_ts_div.hw,
+ &clk_regmap_gate_ops, CLK_SET_RATE_PARENT),
+};
+
+static struct clk_fixed_factor a9_eth_125m_div = {
+ .mult = 1,
+ .div = 8,
+ .hw.init = CLK_HW_INIT_FW_NAME("eth_125m_div", "fdiv2",
+ &clk_fixed_factor_ops, 0),
+};
+
+static struct clk_regmap a9_eth_125m = {
+ .data = &(struct clk_regmap_gate_data) {
+ .offset = ETH_CLK_CTRL,
+ .bit_idx = 7,
+ },
+ .hw.init = CLK_HW_INIT_HW("eth_125m", &a9_eth_125m_div.hw,
+ &clk_regmap_gate_ops, CLK_SET_RATE_PARENT),
+};
+
+/*
+ * Channel 1, 2, 3, 4, 5 and 6 are unconnected,
+ * ext_rmii connects external PAD. Do not automatically reparent.
+ */
+static u32 a9_eth_rmii_parents_val_table[] = { 0, 7 };
+static const struct clk_parent_data a9_eth_rmii_parents[] = {
+ { .fw_name = "fdiv2", },
+ { .fw_name = "ext_rmii", }
+};
+
+static struct clk_regmap a9_eth_rmii_sel = {
+ .data = &(struct clk_regmap_mux_data) {
+ .offset = ETH_CLK_CTRL,
+ .mask = 0x7,
+ .shift = 9,
+ .table = a9_eth_rmii_parents_val_table,
+ },
+ .hw.init = CLK_HW_INIT_PARENTS_DATA("eth_rmii_sel",
+ a9_eth_rmii_parents,
+ &clk_regmap_mux_ops, CLK_SET_RATE_NO_REPARENT),
+};
+
+static struct clk_regmap a9_eth_rmii_div = {
+ .data = &(struct clk_regmap_div_data) {
+ .offset = ETH_CLK_CTRL,
+ .shift = 0,
+ .width = 7,
+ },
+ .hw.init = CLK_HW_INIT_HW("eth_rmii_div", &a9_eth_rmii_sel.hw,
+ &clk_regmap_divider_ops, CLK_SET_RATE_PARENT),
+};
+
+static struct clk_regmap a9_eth_rmii = {
+ .data = &(struct clk_regmap_gate_data) {
+ .offset = ETH_CLK_CTRL,
+ .bit_idx = 8,
+ },
+ .hw.init = CLK_HW_INIT_HW("eth_rmii", &a9_eth_rmii_div.hw,
+ &clk_regmap_gate_ops, CLK_SET_RATE_PARENT),
+};
+
+/*
+ * Channel 3(ddr_dpll_pt_clk) is manged by the DDR module;
+ * channel 12(msr_clk) is manged by clock measures module.
+ * channel 16(audio_dac1_clk) is manged by audio module.
+ * Channel 10, 11, 13, 14 are not connected.
+ */
+static u32 a9_gen_parents_val_table[] = { 0, 1, 2, 4, 5, 6, 7, 8, 9, 15, 17, 18,
+ 19, 20, 21, 22, 23, 24, 25, 26};
+static struct clk_regmap a9_vid_pll;
+
+static const struct clk_parent_data a9_gen_parents[] = {
+ { .fw_name = "xtal" },
+ { .fw_name = "rtc" },
+ { .fw_name = "sysplldiv16" },
+ { .hw = &a9_vid_pll.hw },
+ { .fw_name = "gp0" },
+ { .fw_name = "hifi1" },
+ { .fw_name = "hifi0" },
+ { .fw_name = "gp1" },
+ { .fw_name = "gp2" },
+ { .fw_name = "dsudiv16" },
+ { .fw_name = "cpudiv16" },
+ { .fw_name = "a78div16" },
+ { .fw_name = "fdiv2" },
+ { .fw_name = "fdiv2p5" },
+ { .fw_name = "fdiv3" },
+ { .fw_name = "fdiv4" },
+ { .fw_name = "fdiv5" },
+ { .fw_name = "fdiv7" },
+ { .fw_name = "mclk0" },
+ { .fw_name = "mclk1" }
+};
+
+static A9_COMP_SEL(gen, GEN_CLK_CTRL, 12, 0x1f, a9_gen_parents,
+ a9_gen_parents_val_table);
+static A9_COMP_DIV(gen, GEN_CLK_CTRL, 0, 11);
+static A9_COMP_GATE(gen, GEN_CLK_CTRL, 11, 0);
+
+static struct clk_regmap a9_24m_in = {
+ .data = &(struct clk_regmap_gate_data) {
+ .offset = CLK12_24_CTRL,
+ .bit_idx = 11,
+ },
+ .hw.init = CLK_HW_INIT_FW_NAME("24m_in", "xtal",
+ &clk_regmap_gate_ops, 0),
+};
+
+static struct clk_regmap a9_12_24m = {
+ .data = &(struct clk_regmap_div_data) {
+ .offset = CLK12_24_CTRL,
+ .shift = 10,
+ .width = 1,
+ },
+ .hw.init = CLK_HW_INIT_HW("12_24m", &a9_24m_in.hw,
+ &clk_regmap_divider_ops, 0),
+};
+
+static const struct clk_parent_data a9_mali_parents[] = {
+ { .fw_name = "xtal", },
+ { .fw_name = "gp1", },
+ { .fw_name = "fdiv2", },
+ { .fw_name = "fdiv2p5", },
+ { .fw_name = "fdiv3", },
+ { .fw_name = "fdiv4", },
+ { .fw_name = "fdiv5", },
+ { .fw_name = "fdiv7", }
+};
+
+static A9_COMP_SEL(mali_0, MALI_CLK_CTRL, 9, 0x7, a9_mali_parents, NULL);
+static A9_COMP_DIV(mali_0, MALI_CLK_CTRL, 0, 7);
+static A9_COMP_GATE(mali_0, MALI_CLK_CTRL, 8, CLK_SET_RATE_GATE);
+
+static A9_COMP_SEL(mali_1, MALI_CLK_CTRL, 25, 0x7, a9_mali_parents, NULL);
+static A9_COMP_DIV(mali_1, MALI_CLK_CTRL, 16, 7);
+static A9_COMP_GATE(mali_1, MALI_CLK_CTRL, 24, CLK_SET_RATE_GATE);
+
+static struct clk_regmap a9_mali = {
+ .data = &(struct clk_regmap_mux_data){
+ .offset = MALI_CLK_CTRL,
+ .mask = 0x1,
+ .shift = 31,
+ },
+ .hw.init = CLK_HW_INIT_PARENTS_HW("mali",
+ ((const struct clk_hw *[]) {
+ &a9_mali_0.hw,
+ &a9_mali_1.hw,
+ }), &clk_regmap_mux_ops, CLK_SET_RATE_PARENT),
+};
+
+static A9_COMP_SEL(mali_stack_0, MALI_STACK_CLK_CTRL, 9, 0x7, a9_mali_parents,
+ NULL);
+static A9_COMP_DIV(mali_stack_0, MALI_STACK_CLK_CTRL, 0, 7);
+static A9_COMP_GATE(mali_stack_0, MALI_STACK_CLK_CTRL, 8, CLK_SET_RATE_GATE);
+
+static A9_COMP_SEL(mali_stack_1, MALI_STACK_CLK_CTRL, 25, 0x7, a9_mali_parents,
+ NULL);
+static A9_COMP_DIV(mali_stack_1, MALI_STACK_CLK_CTRL, 16, 7);
+static A9_COMP_GATE(mali_stack_1, MALI_STACK_CLK_CTRL, 24, CLK_SET_RATE_GATE);
+
+static struct clk_regmap a9_mali_stack = {
+ .data = &(struct clk_regmap_mux_data){
+ .offset = MALI_STACK_CLK_CTRL,
+ .mask = 0x1,
+ .shift = 31,
+ },
+ .hw.init = CLK_HW_INIT_PARENTS_HW("mali_stack",
+ ((const struct clk_hw *[]) {
+ &a9_mali_stack_0.hw,
+ &a9_mali_stack_1.hw,
+ }), &clk_regmap_mux_ops, CLK_SET_RATE_PARENT),
+};
+
+static const struct clk_parent_data a9_dspa_parents[] = {
+ { .fw_name = "xtal", },
+ { .fw_name = "fdiv2p5", },
+ { .fw_name = "fdiv3", },
+ { .fw_name = "fdiv5", },
+ { .fw_name = "gp2", },
+ { .fw_name = "fdiv4", },
+ { .fw_name = "hifi0", },
+ { .fw_name = "rtc", }
+};
+
+static A9_COMP_SEL(dspa_0, DSPA_CLK_CTRL, 9, 0x7, a9_dspa_parents, NULL);
+static A9_COMP_DIV(dspa_0, DSPA_CLK_CTRL, 0, 7);
+static A9_COMP_GATE(dspa_0, DSPA_CLK_CTRL, 8, CLK_SET_RATE_GATE);
+
+static A9_COMP_SEL(dspa_1, DSPA_CLK_CTRL, 25, 0x7, a9_dspa_parents, NULL);
+static A9_COMP_DIV(dspa_1, DSPA_CLK_CTRL, 16, 7);
+static A9_COMP_GATE(dspa_1, DSPA_CLK_CTRL, 24, CLK_SET_RATE_GATE);
+
+static struct clk_regmap a9_dspa = {
+ .data = &(struct clk_regmap_mux_data){
+ .offset = DSPA_CLK_CTRL,
+ .mask = 0x1,
+ .shift = 31,
+ },
+ .hw.init = CLK_HW_INIT_PARENTS_HW("dspa",
+ ((const struct clk_hw *[]) {
+ &a9_dspa_0.hw,
+ &a9_dspa_1.hw,
+ }), &clk_regmap_mux_ops, CLK_SET_RATE_PARENT),
+};
+
+static const struct clk_parent_data a9_hevcf_parents[] = {
+ { .fw_name = "fdiv2p5", },
+ { .fw_name = "fdiv3", },
+ { .fw_name = "fdiv4", },
+ { .fw_name = "fdiv5", },
+ { .fw_name = "fdiv7", },
+ { .fw_name = "hifi0", },
+ { .fw_name = "gp1", },
+ { .fw_name = "xtal", }
+};
+
+static A9_COMP_SEL(hevcf_0, HEVCF_CLK_CTRL, 9, 0x7, a9_hevcf_parents, NULL);
+static A9_COMP_DIV(hevcf_0, HEVCF_CLK_CTRL, 0, 7);
+static A9_COMP_GATE(hevcf_0, HEVCF_CLK_CTRL, 8, CLK_SET_RATE_GATE);
+
+static A9_COMP_SEL(hevcf_1, HEVCF_CLK_CTRL, 25, 0x7, a9_hevcf_parents, NULL);
+static A9_COMP_DIV(hevcf_1, HEVCF_CLK_CTRL, 16, 7);
+static A9_COMP_GATE(hevcf_1, HEVCF_CLK_CTRL, 24, CLK_SET_RATE_GATE);
+
+static struct clk_regmap a9_hevcf = {
+ .data = &(struct clk_regmap_mux_data){
+ .offset = HEVCF_CLK_CTRL,
+ .mask = 0x1,
+ .shift = 31,
+ },
+ .hw.init = CLK_HW_INIT_PARENTS_HW("hevcf",
+ ((const struct clk_hw *[]) {
+ &a9_hevcf_0.hw,
+ &a9_hevcf_1.hw,
+ }), &clk_regmap_mux_ops, CLK_SET_RATE_PARENT),
+};
+
+static const struct clk_parent_data a9_hcodec_parents[] = {
+ { .fw_name = "fdiv2p5", },
+ { .fw_name = "fdiv3", },
+ { .fw_name = "fdiv4", },
+ { .fw_name = "fdiv5", },
+ { .fw_name = "fdiv7", },
+ { .fw_name = "hifi0", },
+ { .fw_name = "gp0", },
+ { .fw_name = "xtal", }
+};
+
+static A9_COMP_SEL(hcodec_0, HCODEC_CLK_CTRL, 9, 0x7, a9_hcodec_parents, NULL);
+static A9_COMP_DIV(hcodec_0, HCODEC_CLK_CTRL, 0, 7);
+static A9_COMP_GATE(hcodec_0, HCODEC_CLK_CTRL, 8, CLK_SET_RATE_GATE);
+
+static A9_COMP_SEL(hcodec_1, HCODEC_CLK_CTRL, 25, 0x7, a9_hcodec_parents, NULL);
+static A9_COMP_DIV(hcodec_1, HCODEC_CLK_CTRL, 16, 7);
+static A9_COMP_GATE(hcodec_1, HCODEC_CLK_CTRL, 24, CLK_SET_RATE_GATE);
+
+static struct clk_regmap a9_hcodec = {
+ .data = &(struct clk_regmap_mux_data){
+ .offset = HCODEC_CLK_CTRL,
+ .mask = 0x1,
+ .shift = 31,
+ },
+ .hw.init = CLK_HW_INIT_PARENTS_HW("hcodec",
+ ((const struct clk_hw *[]) {
+ &a9_hcodec_0.hw,
+ &a9_hcodec_1.hw,
+ }), &clk_regmap_mux_ops, CLK_SET_RATE_PARENT),
+};
+
+static const struct clk_parent_data a9_vpu_parents[] = {
+ { .fw_name = "fdiv3", },
+ { .fw_name = "fdiv4", },
+ { .fw_name = "fdiv5", },
+ { .fw_name = "vid1", },
+ { .fw_name = "fdiv2", },
+ { .hw = &a9_vid_pll.hw },
+ { .fw_name = "vid2", },
+ { .fw_name = "gp1", }
+};
+
+static A9_COMP_SEL(vpu_0, VPU_CLK_CTRL, 9, 0x7, a9_vpu_parents, NULL);
+static A9_COMP_DIV(vpu_0, VPU_CLK_CTRL, 0, 7);
+static A9_COMP_GATE(vpu_0, VPU_CLK_CTRL, 8, CLK_SET_RATE_GATE);
+
+static A9_COMP_SEL(vpu_1, VPU_CLK_CTRL, 25, 0x7, a9_vpu_parents, NULL);
+static A9_COMP_DIV(vpu_1, VPU_CLK_CTRL, 16, 7);
+static A9_COMP_GATE(vpu_1, VPU_CLK_CTRL, 24, CLK_SET_RATE_GATE);
+
+static struct clk_regmap a9_vpu = {
+ .data = &(struct clk_regmap_mux_data){
+ .offset = VPU_CLK_CTRL,
+ .mask = 0x1,
+ .shift = 31,
+ },
+ .hw.init = CLK_HW_INIT_PARENTS_HW("vpu",
+ ((const struct clk_hw *[]) {
+ &a9_vpu_0.hw,
+ &a9_vpu_1.hw,
+ }), &clk_regmap_mux_ops, CLK_SET_RATE_PARENT),
+};
+
+static const struct clk_parent_data a9_vapb_parents[] = {
+ { .fw_name = "fdiv4", },
+ { .fw_name = "fdiv3", },
+ { .fw_name = "fdiv5", },
+ { .fw_name = "fdiv7", },
+ { .fw_name = "fdiv2", },
+ { .hw = &a9_vid_pll.hw },
+ { .fw_name = "hifi0", },
+ { .fw_name = "fdiv2p5", }
+};
+
+static A9_COMP_SEL(vapb_0, VAPB_CLK_CTRL, 9, 0x7, a9_vapb_parents, NULL);
+static A9_COMP_DIV(vapb_0, VAPB_CLK_CTRL, 0, 7);
+static A9_COMP_GATE(vapb_0, VAPB_CLK_CTRL, 8, CLK_SET_RATE_GATE);
+
+static A9_COMP_SEL(vapb_1, VAPB_CLK_CTRL, 25, 0x7, a9_vapb_parents, NULL);
+static A9_COMP_DIV(vapb_1, VAPB_CLK_CTRL, 16, 7);
+static A9_COMP_GATE(vapb_1, VAPB_CLK_CTRL, 24, CLK_SET_RATE_GATE);
+
+static struct clk_regmap a9_vapb = {
+ .data = &(struct clk_regmap_mux_data){
+ .offset = VAPB_CLK_CTRL,
+ .mask = 0x1,
+ .shift = 31,
+ },
+ .hw.init = CLK_HW_INIT_PARENTS_HW("vapb",
+ ((const struct clk_hw *[]) {
+ &a9_vapb_0.hw,
+ &a9_vapb_1.hw,
+ }), &clk_regmap_mux_ops, CLK_SET_RATE_PARENT),
+};
+
+static struct clk_regmap a9_ge2d = {
+ .data = &(struct clk_regmap_gate_data) {
+ .offset = VAPB_CLK_CTRL,
+ .bit_idx = 30,
+ },
+ .hw.init = CLK_HW_INIT_HW("ge2d", &a9_vapb.hw,
+ &clk_regmap_gate_ops, 0),
+};
+
+static const struct clk_parent_data a9_vpu_clkb_tmp_parents[] = {
+ { .hw = &a9_vpu.hw },
+ { .fw_name = "fdiv4", },
+ { .fw_name = "fdiv5", },
+ { .fw_name = "fdiv7", }
+};
+
+static A9_COMP_SEL(vpu_clkb_tmp, VPU_CLKB_CTRL, 25, 0x7, a9_vpu_clkb_tmp_parents,
+ NULL);
+static A9_COMP_DIV(vpu_clkb_tmp, VPU_CLKB_CTRL, 16, 4);
+static A9_COMP_GATE(vpu_clkb_tmp, VPU_CLKB_CTRL, 24, 0);
+
+static struct clk_regmap a9_vpu_clkb_div = {
+ .data = &(struct clk_regmap_div_data) {
+ .offset = VPU_CLKB_CTRL,
+ .shift = 0,
+ .width = 8,
+ },
+ .hw.init = CLK_HW_INIT_HW("vpu_clkb_div", &a9_vpu_clkb_tmp.hw,
+ &clk_regmap_divider_ops, 0),
+};
+
+static struct clk_regmap a9_vpu_clkb = {
+ .data = &(struct clk_regmap_gate_data) {
+ .offset = VPU_CLKB_CTRL,
+ .bit_idx = 8,
+ },
+ .hw.init = CLK_HW_INIT_HW("vpu_clkb", &a9_vpu_clkb_div.hw,
+ &clk_regmap_gate_ops, CLK_SET_RATE_PARENT),
+};
+
+static const struct clk_parent_data a9_hdmi_parents[] = {
+ { .fw_name = "xtal", },
+ { .fw_name = "fdiv4", },
+ { .fw_name = "fdiv3", },
+ { .fw_name = "fdiv5", }
+};
+
+static A9_COMP_SEL(hdmitx_sys, HDMI_CLK_CTRL, 9, 0x7, a9_hdmi_parents, NULL);
+static A9_COMP_DIV(hdmitx_sys, HDMI_CLK_CTRL, 0, 7);
+static A9_COMP_GATE(hdmitx_sys, HDMI_CLK_CTRL, 8, 0);
+
+static A9_COMP_SEL(hdmitx_prif, HTX_CLK_CTRL, 9, 0x7, a9_hdmi_parents, NULL);
+static A9_COMP_DIV(hdmitx_prif, HTX_CLK_CTRL, 0, 7);
+static A9_COMP_GATE(hdmitx_prif, HTX_CLK_CTRL, 8, 0);
+
+static A9_COMP_SEL(hdmitx_200m, HTX_CLK_CTRL, 25, 0x7, a9_hdmi_parents, NULL);
+static A9_COMP_DIV(hdmitx_200m, HTX_CLK_CTRL, 16, 7);
+static A9_COMP_GATE(hdmitx_200m, HTX_CLK_CTRL, 24, 0);
+
+static A9_COMP_SEL(hdmitx_aud, HTX_CLK_CTRL1, 9, 0x7, a9_hdmi_parents, NULL);
+static A9_COMP_DIV(hdmitx_aud, HTX_CLK_CTRL1, 0, 7);
+static A9_COMP_GATE(hdmitx_aud, HTX_CLK_CTRL1, 8, 0);
+
+static A9_COMP_SEL(hdmirx_5m, HRX_CLK_CTRL, 9, 0x7, a9_hdmi_parents,
+ NULL);
+static A9_COMP_DIV(hdmirx_5m, HRX_CLK_CTRL, 0, 7);
+static A9_COMP_GATE(hdmirx_5m, HRX_CLK_CTRL, 8, 0);
+
+static A9_COMP_SEL(hdmirx_2m, HRX_CLK_CTRL, 25, 0x7, a9_hdmi_parents,
+ NULL);
+static A9_COMP_DIV(hdmirx_2m, HRX_CLK_CTRL, 16, 7);
+static A9_COMP_GATE(hdmirx_2m, HRX_CLK_CTRL, 24, 0);
+
+static A9_COMP_SEL(hdmirx_cfg, HRX_CLK_CTRL1, 9, 0x7, a9_hdmi_parents,
+ NULL);
+static A9_COMP_DIV(hdmirx_cfg, HRX_CLK_CTRL1, 0, 7);
+static A9_COMP_GATE(hdmirx_cfg, HRX_CLK_CTRL1, 8, 0);
+
+static A9_COMP_SEL(hdmirx_hdcp2x, HRX_CLK_CTRL1, 25, 0x7, a9_hdmi_parents,
+ NULL);
+static A9_COMP_DIV(hdmirx_hdcp2x, HRX_CLK_CTRL1, 16, 7);
+static A9_COMP_GATE(hdmirx_hdcp2x, HRX_CLK_CTRL1, 24, 0);
+
+static A9_COMP_SEL(hdmirx_acr_ref, HRX_CLK_CTRL2, 25, 0x7, a9_hdmi_parents,
+ NULL);
+static A9_COMP_DIV(hdmirx_acr_ref, HRX_CLK_CTRL2, 16, 7);
+static A9_COMP_GATE(hdmirx_acr_ref, HRX_CLK_CTRL2, 24, 0);
+
+static A9_COMP_SEL(hdmirx_meter, HRX_CLK_CTRL3, 9, 0x7, a9_hdmi_parents,
+ NULL);
+static A9_COMP_DIV(hdmirx_meter, HRX_CLK_CTRL3, 0, 7);
+static A9_COMP_GATE(hdmirx_meter, HRX_CLK_CTRL3, 8, 0);
+
+static struct clk_regmap a9_enc, a9_enc1;
+
+static const struct clk_parent_data a9_vid_lock_parents[] = {
+ { .fw_name = "xtal", },
+ { .hw = &a9_enc.hw },
+ { .hw = &a9_enc1.hw }
+};
+
+static A9_COMP_SEL(vid_lock, VID_LOCK_CLK_CTRL, 9, 0x7, a9_vid_lock_parents,
+ NULL);
+static A9_COMP_DIV(vid_lock, VID_LOCK_CLK_CTRL, 0, 7);
+static A9_COMP_GATE(vid_lock, VID_LOCK_CLK_CTRL, 8, 0);
+
+static const struct clk_parent_data a9_vdin_meas_parents[] = {
+ { .fw_name = "xtal", },
+ { .fw_name = "fdiv4", },
+ { .fw_name = "fdiv3", },
+ { .fw_name = "fdiv5", }
+};
+
+static A9_COMP_SEL(vdin_meas, VDIN_MEAS_CLK_CTRL, 9, 0x7, a9_vdin_meas_parents,
+ NULL);
+static A9_COMP_DIV(vdin_meas, VDIN_MEAS_CLK_CTRL, 0, 7);
+static A9_COMP_GATE(vdin_meas, VDIN_MEAS_CLK_CTRL, 8, 0);
+
+static struct clk_regmap a9_vid_pll_div = {
+ .data = &(struct meson_vid_pll_div_data){
+ .val = {
+ .reg_off = VID_PLL_CLK_DIV,
+ .shift = 0,
+ .width = 15,
+ },
+ .sel = {
+ .reg_off = VID_PLL_CLK_DIV,
+ .shift = 16,
+ .width = 2,
+ },
+ },
+ .hw.init = CLK_HW_INIT_FW_NAME("vid_pll_div", "hdmiout2",
+ &meson_vid_pll_div_ro_ops, 0),
+};
+
+static struct clk_regmap a9_vid_pll_sel = {
+ .data = &(struct clk_regmap_mux_data){
+ .offset = VID_PLL_CLK_DIV,
+ .mask = 0x1,
+ .shift = 18,
+ },
+ .hw.init = CLK_HW_INIT_PARENTS_DATA("vid_pll_sel",
+ ((const struct clk_parent_data []) {
+ { .hw = &a9_vid_pll_div.hw },
+ { .fw_name = "hdmiout2" }
+ }), &clk_regmap_mux_ops, CLK_SET_RATE_PARENT),
+};
+
+static struct clk_regmap a9_vid_pll = {
+ .data = &(struct clk_regmap_gate_data){
+ .offset = VID_PLL_CLK_DIV,
+ .bit_idx = 19,
+ },
+ .hw.init = CLK_HW_INIT_HW("vid_pll", &a9_vid_pll_sel.hw,
+ &clk_regmap_gate_ops, CLK_SET_RATE_PARENT),
+};
+
+static struct clk_regmap a9_vid_pll_vclk = {
+ .data = &(struct clk_regmap_mux_data){
+ .offset = HDMI_CLK_CTRL,
+ .mask = 0x1,
+ .shift = 15,
+ },
+ .hw.init = CLK_HW_INIT_PARENTS_DATA("vid_pll_vclk",
+ ((const struct clk_parent_data []) {
+ { .hw = &a9_vid_pll.hw },
+ { .fw_name = "hdmipix" }
+ }), &clk_regmap_mux_ops, 0),
+};
+
+static const struct clk_parent_data a9_vclk_parents[] = {
+ { .hw = &a9_vid_pll_vclk.hw },
+ { .fw_name = "pix0", },
+ { .fw_name = "vid1", },
+ { .fw_name = "pix1", },
+ { .fw_name = "fdiv3", },
+ { .fw_name = "fdiv4", },
+ { .fw_name = "fdiv5", },
+ { .fw_name = "vid2", }
+};
+
+static struct clk_regmap a9_vclk_sel = {
+ .data = &(struct clk_regmap_mux_data){
+ .offset = VID_CLK_CTRL,
+ .mask = 0x7,
+ .shift = 16,
+ },
+ .hw.init = CLK_HW_INIT_PARENTS_DATA("vclk_sel", a9_vclk_parents,
+ &clk_regmap_mux_ops, 0),
+};
+
+static struct clk_regmap a9_vclk_in = {
+ .data = &(struct clk_regmap_gate_data){
+ .offset = VID_CLK_DIV,
+ .bit_idx = 16,
+ },
+ .hw.init = CLK_HW_INIT_HW("vclk_in", &a9_vclk_sel.hw,
+ &clk_regmap_gate_ops, CLK_SET_RATE_PARENT),
+};
+
+static struct clk_regmap a9_vclk_div = {
+ .data = &(struct clk_regmap_div_data){
+ .offset = VID_CLK_DIV,
+ .shift = 0,
+ .width = 8,
+ },
+ .hw.init = CLK_HW_INIT_HW("vclk_div", &a9_vclk_in.hw,
+ &clk_regmap_divider_ops, CLK_SET_RATE_PARENT),
+};
+
+static struct clk_regmap a9_vclk = {
+ .data = &(struct clk_regmap_gate_data){
+ .offset = VID_CLK_CTRL,
+ .bit_idx = 19,
+ },
+ .hw.init = CLK_HW_INIT_HW("vclk", &a9_vclk_div.hw,
+ &clk_regmap_gate_ops, CLK_SET_RATE_PARENT),
+};
+
+static struct clk_regmap a9_vclk_div1_en = {
+ .data = &(struct clk_regmap_gate_data){
+ .offset = VID_CLK_CTRL,
+ .bit_idx = 0,
+ },
+ .hw.init = CLK_HW_INIT_HW("vclk_div1_en", &a9_vclk.hw,
+ &clk_regmap_gate_ops, CLK_SET_RATE_PARENT),
+};
+
+static struct clk_regmap a9_vclk_div2_en = {
+ .data = &(struct clk_regmap_gate_data){
+ .offset = VID_CLK_CTRL,
+ .bit_idx = 1,
+ },
+ .hw.init = CLK_HW_INIT_HW("vclk_div2_en", &a9_vclk.hw,
+ &clk_regmap_gate_ops, CLK_SET_RATE_PARENT),
+};
+
+static struct clk_fixed_factor a9_vclk_div2 = {
+ .mult = 1,
+ .div = 2,
+ .hw.init = CLK_HW_INIT_HW("vclk_div2", &a9_vclk_div2_en.hw,
+ &clk_fixed_factor_ops, CLK_SET_RATE_PARENT),
+};
+
+static struct clk_regmap a9_vclk_div4_en = {
+ .data = &(struct clk_regmap_gate_data){
+ .offset = VID_CLK_CTRL,
+ .bit_idx = 2,
+ },
+ .hw.init = CLK_HW_INIT_HW("vclk_div4_en", &a9_vclk.hw,
+ &clk_regmap_gate_ops, CLK_SET_RATE_PARENT),
+};
+
+static struct clk_fixed_factor a9_vclk_div4 = {
+ .mult = 1,
+ .div = 4,
+ .hw.init = CLK_HW_INIT_HW("vclk_div4", &a9_vclk_div4_en.hw,
+ &clk_fixed_factor_ops, CLK_SET_RATE_PARENT),
+};
+
+static struct clk_regmap a9_vclk_div6_en = {
+ .data = &(struct clk_regmap_gate_data){
+ .offset = VID_CLK_CTRL,
+ .bit_idx = 3,
+ },
+ .hw.init = CLK_HW_INIT_HW("vclk_div6_en", &a9_vclk.hw,
+ &clk_regmap_gate_ops, CLK_SET_RATE_PARENT),
+};
+
+static struct clk_fixed_factor a9_vclk_div6 = {
+ .mult = 1,
+ .div = 6,
+ .hw.init = CLK_HW_INIT_HW("vclk_div6", &a9_vclk_div6_en.hw,
+ &clk_fixed_factor_ops, CLK_SET_RATE_PARENT),
+};
+
+static struct clk_regmap a9_vclk_div12_en = {
+ .data = &(struct clk_regmap_gate_data){
+ .offset = VID_CLK_CTRL,
+ .bit_idx = 4,
+ },
+ .hw.init = CLK_HW_INIT_HW("vclk_div12_en", &a9_vclk.hw,
+ &clk_regmap_gate_ops, CLK_SET_RATE_PARENT),
+};
+
+static struct clk_fixed_factor a9_vclk_div12 = {
+ .mult = 1,
+ .div = 12,
+ .hw.init = CLK_HW_INIT_HW("vclk_div12", &a9_vclk_div12_en.hw,
+ &clk_fixed_factor_ops, CLK_SET_RATE_PARENT),
+};
+
+static struct clk_regmap a9_vclk2_sel = {
+ .data = &(struct clk_regmap_mux_data){
+ .offset = VIID_CLK_CTRL,
+ .mask = 0x7,
+ .shift = 16,
+ },
+ .hw.init = CLK_HW_INIT_PARENTS_DATA("vclk2_sel", a9_vclk_parents,
+ &clk_regmap_mux_ops, 0),
+};
+
+static struct clk_regmap a9_vclk2_in = {
+ .data = &(struct clk_regmap_gate_data){
+ .offset = VIID_CLK_DIV,
+ .bit_idx = 16,
+ },
+ .hw.init = CLK_HW_INIT_HW("vclk2_in", &a9_vclk2_sel.hw,
+ &clk_regmap_gate_ops, CLK_SET_RATE_PARENT),
+};
+
+static struct clk_regmap a9_vclk2_div = {
+ .data = &(struct clk_regmap_div_data){
+ .offset = VIID_CLK_DIV,
+ .shift = 0,
+ .width = 8,
+ },
+ .hw.init = CLK_HW_INIT_HW("vclk2_div", &a9_vclk2_in.hw,
+ &clk_regmap_divider_ops, CLK_SET_RATE_PARENT),
+};
+
+static struct clk_regmap a9_vclk2 = {
+ .data = &(struct clk_regmap_gate_data){
+ .offset = VIID_CLK_CTRL,
+ .bit_idx = 19,
+ },
+ .hw.init = CLK_HW_INIT_HW("vclk2", &a9_vclk2_div.hw,
+ &clk_regmap_gate_ops, CLK_SET_RATE_PARENT),
+};
+
+static struct clk_regmap a9_vclk2_div1_en = {
+ .data = &(struct clk_regmap_gate_data){
+ .offset = VIID_CLK_CTRL,
+ .bit_idx = 0,
+ },
+ .hw.init = CLK_HW_INIT_HW("vclk2_div1_en", &a9_vclk2.hw,
+ &clk_regmap_gate_ops, CLK_SET_RATE_PARENT),
+};
+
+static struct clk_regmap a9_vclk2_div2_en = {
+ .data = &(struct clk_regmap_gate_data){
+ .offset = VIID_CLK_CTRL,
+ .bit_idx = 1,
+ },
+ .hw.init = CLK_HW_INIT_HW("vclk2_div2_en", &a9_vclk2.hw,
+ &clk_regmap_gate_ops, CLK_SET_RATE_PARENT),
+};
+
+static struct clk_fixed_factor a9_vclk2_div2 = {
+ .mult = 1,
+ .div = 2,
+ .hw.init = CLK_HW_INIT_HW("vclk2_div2", &a9_vclk2_div2_en.hw,
+ &clk_fixed_factor_ops, CLK_SET_RATE_PARENT),
+};
+
+static struct clk_regmap a9_vclk2_div4_en = {
+ .data = &(struct clk_regmap_gate_data){
+ .offset = VIID_CLK_CTRL,
+ .bit_idx = 2,
+ },
+ .hw.init = CLK_HW_INIT_HW("vclk2_div4_en", &a9_vclk2.hw,
+ &clk_regmap_gate_ops, CLK_SET_RATE_PARENT),
+};
+
+static struct clk_fixed_factor a9_vclk2_div4 = {
+ .mult = 1,
+ .div = 4,
+ .hw.init = CLK_HW_INIT_HW("vclk2_div4", &a9_vclk2_div4_en.hw,
+ &clk_fixed_factor_ops, CLK_SET_RATE_PARENT),
+};
+
+static struct clk_regmap a9_vclk2_div6_en = {
+ .data = &(struct clk_regmap_gate_data){
+ .offset = VIID_CLK_CTRL,
+ .bit_idx = 3,
+ },
+ .hw.init = CLK_HW_INIT_HW("vclk2_div6_en", &a9_vclk2.hw,
+ &clk_regmap_gate_ops, CLK_SET_RATE_PARENT),
+};
+
+static struct clk_fixed_factor a9_vclk2_div6 = {
+ .mult = 1,
+ .div = 6,
+ .hw.init = CLK_HW_INIT_HW("vclk2_div6", &a9_vclk2_div6_en.hw,
+ &clk_fixed_factor_ops, CLK_SET_RATE_PARENT),
+};
+
+static struct clk_regmap a9_vclk2_div12_en = {
+ .data = &(struct clk_regmap_gate_data){
+ .offset = VIID_CLK_CTRL,
+ .bit_idx = 4,
+ },
+ .hw.init = CLK_HW_INIT_HW("vclk2_div12_en", &a9_vclk2.hw,
+ &clk_regmap_gate_ops, CLK_SET_RATE_PARENT),
+};
+
+static struct clk_fixed_factor a9_vclk2_div12 = {
+ .mult = 1,
+ .div = 12,
+ .hw.init = CLK_HW_INIT_HW("vclk2_div12", &a9_vclk2_div12_en.hw,
+ &clk_fixed_factor_ops, CLK_SET_RATE_PARENT),
+};
+
+/* Channel 5, 6 and 7 are unconnected */
+static u32 a9_vid_parents_val_table[] = { 0, 1, 2, 3, 4, 8, 9, 10, 11, 12 };
+static const struct clk_hw *a9_vid_parents[] = {
+ &a9_vclk_div1_en.hw,
+ &a9_vclk_div2.hw,
+ &a9_vclk_div4.hw,
+ &a9_vclk_div6.hw,
+ &a9_vclk_div12.hw,
+ &a9_vclk2_div1_en.hw,
+ &a9_vclk2_div2.hw,
+ &a9_vclk2_div4.hw,
+ &a9_vclk2_div6.hw,
+ &a9_vclk2_div12.hw
+};
+
+static struct clk_regmap a9_vdac_sel = {
+ .data = &(struct clk_regmap_mux_data){
+ .offset = VIID_CLK_DIV,
+ .mask = 0xf,
+ .shift = 28,
+ .table = a9_vid_parents_val_table,
+ },
+ .hw.init = CLK_HW_INIT_PARENTS_HW("vdac_sel", a9_vid_parents
+ , &clk_regmap_mux_ops, 0),
+};
+
+static struct clk_regmap a9_vdac = {
+ .data = &(struct clk_regmap_gate_data){
+ .offset = VID_CLK_CTRL2,
+ .bit_idx = 4,
+ },
+ .hw.init = CLK_HW_INIT_HW("vdac", &a9_vdac_sel.hw,
+ &clk_regmap_gate_ops, CLK_SET_RATE_PARENT),
+};
+
+static struct clk_regmap a9_enc_sel = {
+ .data = &(struct clk_regmap_mux_data){
+ .offset = VIID_CLK_DIV,
+ .mask = 0xf,
+ .shift = 12,
+ .table = a9_vid_parents_val_table,
+ },
+ .hw.init = CLK_HW_INIT_PARENTS_HW("enc_sel", a9_vid_parents
+ , &clk_regmap_mux_ops, 0),
+};
+
+static struct clk_regmap a9_enc = {
+ .data = &(struct clk_regmap_gate_data){
+ .offset = VID_CLK_CTRL2,
+ .bit_idx = 10,
+ },
+ .hw.init = CLK_HW_INIT_HW("enc", &a9_enc_sel.hw,
+ &clk_regmap_gate_ops, CLK_SET_RATE_PARENT),
+};
+
+static struct clk_regmap a9_enc1_sel = {
+ .data = &(struct clk_regmap_mux_data){
+ .offset = VIID_CLK_DIV,
+ .mask = 0xf,
+ .shift = 8,
+ .table = a9_vid_parents_val_table,
+ },
+ .hw.init = CLK_HW_INIT_PARENTS_HW("enc1_sel", a9_vid_parents
+ , &clk_regmap_mux_ops, 0),
+};
+
+static struct clk_regmap a9_enc1 = {
+ .data = &(struct clk_regmap_gate_data){
+ .offset = VID_CLK_CTRL2,
+ .bit_idx = 11,
+ },
+ .hw.init = CLK_HW_INIT_HW("enc1", &a9_enc1_sel.hw,
+ &clk_regmap_gate_ops, CLK_SET_RATE_PARENT),
+};
+
+static struct clk_regmap a9_hdmitx_pixel_sel = {
+ .data = &(struct clk_regmap_mux_data){
+ .offset = HDMI_CLK_CTRL,
+ .mask = 0xf,
+ .shift = 16,
+ .table = a9_vid_parents_val_table,
+ },
+ .hw.init = CLK_HW_INIT_PARENTS_HW("hdmitx_pixel_sel", a9_vid_parents
+ , &clk_regmap_mux_ops, 0),
+};
+
+static struct clk_regmap a9_hdmitx_pixel = {
+ .data = &(struct clk_regmap_gate_data){
+ .offset = VID_CLK_CTRL2,
+ .bit_idx = 5,
+ },
+ .hw.init = CLK_HW_INIT_HW("hdmitx_pixel", &a9_hdmitx_pixel_sel.hw,
+ &clk_regmap_gate_ops, CLK_SET_RATE_PARENT),
+};
+
+static struct clk_regmap a9_hdmitx_fe_sel = {
+ .data = &(struct clk_regmap_mux_data){
+ .offset = HDMI_CLK_CTRL,
+ .mask = 0xf,
+ .shift = 20,
+ .table = a9_vid_parents_val_table,
+ },
+ .hw.init = CLK_HW_INIT_PARENTS_HW("hdmitx_fe_sel", a9_vid_parents
+ , &clk_regmap_mux_ops, 0),
+};
+
+static struct clk_regmap a9_hdmitx_fe = {
+ .data = &(struct clk_regmap_gate_data){
+ .offset = VID_CLK_CTRL2,
+ .bit_idx = 9,
+ },
+ .hw.init = CLK_HW_INIT_HW("hdmitx_fe", &a9_hdmitx_fe_sel.hw,
+ &clk_regmap_gate_ops, CLK_SET_RATE_PARENT),
+};
+
+static struct clk_regmap a9_hdmitx1_pixel_sel = {
+ .data = &(struct clk_regmap_mux_data){
+ .offset = HDMI_CLK_CTRL,
+ .mask = 0xf,
+ .shift = 24,
+ .table = a9_vid_parents_val_table,
+ },
+ .hw.init = CLK_HW_INIT_PARENTS_HW("hdmitx1_pixel_sel", a9_vid_parents
+ , &clk_regmap_mux_ops, 0),
+};
+
+static struct clk_regmap a9_hdmitx1_pixel = {
+ .data = &(struct clk_regmap_gate_data){
+ .offset = VID_CLK_CTRL2,
+ .bit_idx = 12,
+ },
+ .hw.init = CLK_HW_INIT_HW("hdmitx1_pixel", &a9_hdmitx1_pixel_sel.hw,
+ &clk_regmap_gate_ops, CLK_SET_RATE_PARENT),
+};
+
+static struct clk_regmap a9_hdmitx1_fe_sel = {
+ .data = &(struct clk_regmap_mux_data){
+ .offset = HDMI_CLK_CTRL,
+ .mask = 0xf,
+ .shift = 28,
+ .table = a9_vid_parents_val_table,
+ },
+ .hw.init = CLK_HW_INIT_PARENTS_HW("hdmitx1_fe_sel", a9_vid_parents
+ , &clk_regmap_mux_ops, 0),
+};
+
+static struct clk_regmap a9_hdmitx1_fe = {
+ .data = &(struct clk_regmap_gate_data){
+ .offset = VID_CLK_CTRL2,
+ .bit_idx = 13,
+ },
+ .hw.init = CLK_HW_INIT_HW("hdmitx1_fe", &a9_hdmitx1_fe_sel.hw,
+ &clk_regmap_gate_ops, CLK_SET_RATE_PARENT),
+};
+
+static const struct clk_parent_data a9_csi_phy_parents[] = {
+ { .fw_name = "fdiv2p5", },
+ { .fw_name = "fdiv3", },
+ { .fw_name = "fdiv4", },
+ { .fw_name = "fdiv5", },
+ { .fw_name = "gp0", },
+ { .fw_name = "hifi0", },
+ { .fw_name = "fdiv2", },
+ { .fw_name = "xtal", }
+};
+
+static A9_COMP_SEL(csi_phy, MIPI_CSI_PHY_CLK_CTRL, 9, 0x7,
+ a9_csi_phy_parents, NULL);
+static A9_COMP_DIV(csi_phy, MIPI_CSI_PHY_CLK_CTRL, 0, 7);
+static A9_COMP_GATE(csi_phy, MIPI_CSI_PHY_CLK_CTRL, 8, 0);
+
+static const struct clk_parent_data a9_dsi_meas_parents[] = {
+ { .fw_name = "xtal", },
+ { .fw_name = "fdiv4", },
+ { .fw_name = "fdiv3", },
+ { .fw_name = "fdiv5", },
+ { .hw = &a9_vid_pll.hw },
+ { .fw_name = "gp0", },
+ { .fw_name = "vid1", },
+ { .fw_name = "vid2", }
+};
+
+static A9_COMP_SEL(dsi_meas, DSI_MEAS_CLK_CTRL, 9, 0x7,
+ a9_dsi_meas_parents, NULL);
+static A9_COMP_DIV(dsi_meas, DSI_MEAS_CLK_CTRL, 0, 7);
+static A9_COMP_GATE(dsi_meas, DSI_MEAS_CLK_CTRL, 8, 0);
+
+static A9_COMP_SEL(dsi_b_meas, DSI_MEAS_CLK_CTRL, 25, 0x7,
+ a9_dsi_meas_parents, NULL);
+static A9_COMP_DIV(dsi_b_meas, DSI_MEAS_CLK_CTRL, 16, 7);
+static A9_COMP_GATE(dsi_b_meas, DSI_MEAS_CLK_CTRL, 24, 0);
+
+static struct clk_hw *a9_peripherals_hw_clks[] = {
+ [CLKID_SYS_AM_AXI] = &a9_sys_am_axi.hw,
+ [CLKID_SYS_DOS] = &a9_sys_dos.hw,
+ [CLKID_SYS_MIPI_DSI] = &a9_sys_mipi_dsi.hw,
+ [CLKID_SYS_ETH_PHY] = &a9_sys_eth_phy.hw,
+ [CLKID_SYS_AMFC] = &a9_sys_amfc.hw,
+ [CLKID_SYS_MALI] = &a9_sys_mali.hw,
+ [CLKID_SYS_NNA] = &a9_sys_nna.hw,
+ [CLKID_SYS_ETH_AXI] = &a9_sys_eth_axi.hw,
+ [CLKID_SYS_DP_APB] = &a9_sys_dp_apb.hw,
+ [CLKID_SYS_EDPTX_APB] = &a9_sys_edptx_apb.hw,
+ [CLKID_SYS_U3HSG] = &a9_sys_u3hsg.hw,
+ [CLKID_SYS_AUCPU] = &a9_sys_aucpu.hw,
+ [CLKID_SYS_GLB] = &a9_sys_glb.hw,
+ [CLKID_SYS_COMBO_DPHY_APB] = &a9_sys_combo_dphy_apb.hw,
+ [CLKID_SYS_HDMIRX_APB] = &a9_sys_hdmirx_apb.hw,
+ [CLKID_SYS_HDMIRX_PCLK] = &a9_sys_hdmirx_pclk.hw,
+ [CLKID_SYS_MIPI_DSI_PHY] = &a9_sys_mipi_dsi_phy.hw,
+ [CLKID_SYS_CAN0] = &a9_sys_can0.hw,
+ [CLKID_SYS_CAN1] = &a9_sys_can1.hw,
+ [CLKID_SYS_SD_EMMC_A] = &a9_sys_sd_emmc_a.hw,
+ [CLKID_SYS_SD_EMMC_B] = &a9_sys_sd_emmc_b.hw,
+ [CLKID_SYS_SD_EMMC_C] = &a9_sys_sd_emmc_c.hw,
+ [CLKID_SYS_SC] = &a9_sys_sc.hw,
+ [CLKID_SYS_ACODEC] = &a9_sys_acodec.hw,
+ [CLKID_SYS_MIPI_ISP] = &a9_sys_mipi_isp.hw,
+ [CLKID_SYS_MSR] = &a9_sys_msr.hw,
+ [CLKID_SYS_AUDIO] = &a9_sys_audio.hw,
+ [CLKID_SYS_MIPI_DSI_B] = &a9_sys_mipi_dsi_b.hw,
+ [CLKID_SYS_MIPI_DSI1_PHY] = &a9_sys_mipi_dsi1_phy.hw,
+ [CLKID_SYS_ETH] = &a9_sys_eth.hw,
+ [CLKID_SYS_ETH_1G_MAC] = &a9_sys_eth_1g_mac.hw,
+ [CLKID_SYS_UART_A] = &a9_sys_uart_a.hw,
+ [CLKID_SYS_UART_F] = &a9_sys_uart_f.hw,
+ [CLKID_SYS_TS_A55] = &a9_sys_ts_a55.hw,
+ [CLKID_SYS_ETH_1G_AXI] = &a9_sys_eth_1g_axi.hw,
+ [CLKID_SYS_TS_DOS] = &a9_sys_ts_dos.hw,
+ [CLKID_SYS_U3DRD_B] = &a9_sys_u3drd_b.hw,
+ [CLKID_SYS_TS_CORE] = &a9_sys_ts_core.hw,
+ [CLKID_SYS_TS_PLL] = &a9_sys_ts_pll.hw,
+ [CLKID_SYS_CSI_DIG_CLKIN] = &a9_sys_csi_dig_clkin.hw,
+ [CLKID_SYS_CVE] = &a9_sys_cve.hw,
+ [CLKID_SYS_GE2D] = &a9_sys_ge2d.hw,
+ [CLKID_SYS_SPISG] = &a9_sys_spisg.hw,
+ [CLKID_SYS_U3DRD_1] = &a9_sys_u3drd_1.hw,
+ [CLKID_SYS_U2H] = &a9_sys_u2h.hw,
+ [CLKID_SYS_PCIE_MAC_A] = &a9_sys_pcie_mac_a.hw,
+ [CLKID_SYS_U3DRD_A] = &a9_sys_u3drd_a.hw,
+ [CLKID_SYS_U2DRD] = &a9_sys_u2drd.hw,
+ [CLKID_SYS_PCIE_PHY] = &a9_sys_pcie_phy.hw,
+ [CLKID_SYS_PCIE_MAC_B] = &a9_sys_pcie_mac_b.hw,
+ [CLKID_SYS_PERIPH] = &a9_sys_periph.hw,
+ [CLKID_SYS_PIO] = &a9_sys_pio.hw,
+ [CLKID_SYS_I3C] = &a9_sys_i3c.hw,
+ [CLKID_SYS_I2C_M_E] = &a9_sys_i2c_m_e.hw,
+ [CLKID_SYS_I2C_M_F] = &a9_sys_i2c_m_f.hw,
+ [CLKID_SYS_HDMITX_APB] = &a9_sys_hdmitx_apb.hw,
+ [CLKID_SYS_I2C_M_I] = &a9_sys_i2c_m_i.hw,
+ [CLKID_SYS_I2C_M_G] = &a9_sys_i2c_m_g.hw,
+ [CLKID_SYS_I2C_M_H] = &a9_sys_i2c_m_h.hw,
+ [CLKID_SYS_HDMI20_AES] = &a9_sys_hdmi20_aes.hw,
+ [CLKID_SYS_CSI2_HOST] = &a9_sys_csi2_host.hw,
+ [CLKID_SYS_CSI2_ADAPT] = &a9_sys_csi2_adapt.hw,
+ [CLKID_SYS_DSPA] = &a9_sys_dspa.hw,
+ [CLKID_SYS_PP_DMA] = &a9_sys_pp_dma.hw,
+ [CLKID_SYS_PP_WRAPPER] = &a9_sys_pp_wrapper.hw,
+ [CLKID_SYS_VPU_INTR] = &a9_sys_vpu_intr.hw,
+ [CLKID_SYS_CSI2_PHY] = &a9_sys_csi2_phy.hw,
+ [CLKID_SYS_SARADC] = &a9_sys_saradc.hw,
+ [CLKID_SYS_PWM_J] = &a9_sys_pwm_j.hw,
+ [CLKID_SYS_PWM_I] = &a9_sys_pwm_i.hw,
+ [CLKID_SYS_PWM_H] = &a9_sys_pwm_h.hw,
+ [CLKID_SYS_PWM_N] = &a9_sys_pwm_n.hw,
+ [CLKID_SYS_PWM_M] = &a9_sys_pwm_m.hw,
+ [CLKID_SYS_PWM_L] = &a9_sys_pwm_l.hw,
+ [CLKID_SYS_PWM_K] = &a9_sys_pwm_k.hw,
+ [CLKID_SD_EMMC_A_SEL] = &a9_sd_emmc_a_sel.hw,
+ [CLKID_SD_EMMC_A_DIV] = &a9_sd_emmc_a_div.hw,
+ [CLKID_SD_EMMC_A] = &a9_sd_emmc_a.hw,
+ [CLKID_SD_EMMC_B_SEL] = &a9_sd_emmc_b_sel.hw,
+ [CLKID_SD_EMMC_B_DIV] = &a9_sd_emmc_b_div.hw,
+ [CLKID_SD_EMMC_B] = &a9_sd_emmc_b.hw,
+ [CLKID_SD_EMMC_C_SEL] = &a9_sd_emmc_c_sel.hw,
+ [CLKID_SD_EMMC_C_DIV] = &a9_sd_emmc_c_div.hw,
+ [CLKID_SD_EMMC_C] = &a9_sd_emmc_c.hw,
+ [CLKID_PWM_H_SEL] = &a9_pwm_h_sel.hw,
+ [CLKID_PWM_H_DIV] = &a9_pwm_h_div.hw,
+ [CLKID_PWM_H] = &a9_pwm_h.hw,
+ [CLKID_PWM_I_SEL] = &a9_pwm_i_sel.hw,
+ [CLKID_PWM_I_DIV] = &a9_pwm_i_div.hw,
+ [CLKID_PWM_I] = &a9_pwm_i.hw,
+ [CLKID_PWM_J_SEL] = &a9_pwm_j_sel.hw,
+ [CLKID_PWM_J_DIV] = &a9_pwm_j_div.hw,
+ [CLKID_PWM_J] = &a9_pwm_j.hw,
+ [CLKID_PWM_K_SEL] = &a9_pwm_k_sel.hw,
+ [CLKID_PWM_K_DIV] = &a9_pwm_k_div.hw,
+ [CLKID_PWM_K] = &a9_pwm_k.hw,
+ [CLKID_PWM_L_SEL] = &a9_pwm_l_sel.hw,
+ [CLKID_PWM_L_DIV] = &a9_pwm_l_div.hw,
+ [CLKID_PWM_L] = &a9_pwm_l.hw,
+ [CLKID_PWM_M_SEL] = &a9_pwm_m_sel.hw,
+ [CLKID_PWM_M_DIV] = &a9_pwm_m_div.hw,
+ [CLKID_PWM_M] = &a9_pwm_m.hw,
+ [CLKID_PWM_N_SEL] = &a9_pwm_n_sel.hw,
+ [CLKID_PWM_N_DIV] = &a9_pwm_n_div.hw,
+ [CLKID_PWM_N] = &a9_pwm_n.hw,
+ [CLKID_SPISG_SEL] = &a9_spisg_sel.hw,
+ [CLKID_SPISG_DIV] = &a9_spisg_div.hw,
+ [CLKID_SPISG] = &a9_spisg.hw,
+ [CLKID_SPISG1_SEL] = &a9_spisg1_sel.hw,
+ [CLKID_SPISG1_DIV] = &a9_spisg1_div.hw,
+ [CLKID_SPISG1] = &a9_spisg1.hw,
+ [CLKID_SPISG2_SEL] = &a9_spisg2_sel.hw,
+ [CLKID_SPISG2_DIV] = &a9_spisg2_div.hw,
+ [CLKID_SPISG2] = &a9_spisg2.hw,
+ [CLKID_SARADC_SEL] = &a9_saradc_sel.hw,
+ [CLKID_SARADC_DIV] = &a9_saradc_div.hw,
+ [CLKID_SARADC] = &a9_saradc.hw,
+ [CLKID_AMFC_SEL] = &a9_amfc_sel.hw,
+ [CLKID_AMFC_DIV] = &a9_amfc_div.hw,
+ [CLKID_AMFC] = &a9_amfc.hw,
+ [CLKID_NNA_SEL] = &a9_nna_sel.hw,
+ [CLKID_NNA_DIV] = &a9_nna_div.hw,
+ [CLKID_NNA] = &a9_nna.hw,
+ [CLKID_USB_250M_SEL] = &a9_usb_250m_sel.hw,
+ [CLKID_USB_250M_DIV] = &a9_usb_250m_div.hw,
+ [CLKID_USB_250M] = &a9_usb_250m.hw,
+ [CLKID_USB_48M_PRE_SEL] = &a9_usb_48m_pre_sel.hw,
+ [CLKID_USB_48M_PRE_DIV] = &a9_usb_48m_pre_div.hw,
+ [CLKID_USB_48M_PRE] = &a9_usb_48m_pre.hw,
+ [CLKID_PCIE_TL_SEL] = &a9_pcie_tl_sel.hw,
+ [CLKID_PCIE_TL_DIV] = &a9_pcie_tl_div.hw,
+ [CLKID_PCIE_TL] = &a9_pcie_tl.hw,
+ [CLKID_PCIE1_TL_SEL] = &a9_pcie1_tl_sel.hw,
+ [CLKID_PCIE1_TL_DIV] = &a9_pcie1_tl_div.hw,
+ [CLKID_PCIE1_TL] = &a9_pcie1_tl.hw,
+ [CLKID_CMPR_SEL] = &a9_cmpr_sel.hw,
+ [CLKID_CMPR_DIV] = &a9_cmpr_div.hw,
+ [CLKID_CMPR] = &a9_cmpr.hw,
+ [CLKID_DEWARPA_SEL] = &a9_dewarpa_sel.hw,
+ [CLKID_DEWARPA_DIV] = &a9_dewarpa_div.hw,
+ [CLKID_DEWARPA] = &a9_dewarpa.hw,
+ [CLKID_SC_PRE_SEL] = &a9_sc_pre_sel.hw,
+ [CLKID_SC_PRE_DIV] = &a9_sc_pre_div.hw,
+ [CLKID_SC_PRE] = &a9_sc_pre.hw,
+ [CLKID_SC] = &a9_sc.hw,
+ [CLKID_DPTX_APB2_SEL] = &a9_dptx_apb2_sel.hw,
+ [CLKID_DPTX_APB2_DIV] = &a9_dptx_apb2_div.hw,
+ [CLKID_DPTX_APB2] = &a9_dptx_apb2.hw,
+ [CLKID_DPTX_AUD_SEL] = &a9_dptx_aud_sel.hw,
+ [CLKID_DPTX_AUD_DIV] = &a9_dptx_aud_div.hw,
+ [CLKID_DPTX_AUD] = &a9_dptx_aud.hw,
+ [CLKID_ISP_SEL] = &a9_isp_sel.hw,
+ [CLKID_ISP_DIV] = &a9_isp_div.hw,
+ [CLKID_ISP] = &a9_isp.hw,
+ [CLKID_CVE_SEL] = &a9_cve_sel.hw,
+ [CLKID_CVE_DIV] = &a9_cve_div.hw,
+ [CLKID_CVE] = &a9_cve.hw,
+ [CLKID_VGE_SEL] = &a9_vge_sel.hw,
+ [CLKID_VGE_DIV] = &a9_vge_div.hw,
+ [CLKID_VGE] = &a9_vge.hw,
+ [CLKID_PP_SEL] = &a9_pp_sel.hw,
+ [CLKID_PP_DIV] = &a9_pp_div.hw,
+ [CLKID_PP] = &a9_pp.hw,
+ [CLKID_GLB_SEL] = &a9_glb_sel.hw,
+ [CLKID_GLB_DIV] = &a9_glb_div.hw,
+ [CLKID_GLB] = &a9_glb.hw,
+ [CLKID_USB_48M_DUALDIV_IN] = &a9_usb_48m_dualdiv_in.hw,
+ [CLKID_USB_48M_DUALDIV_DIV] = &a9_usb_48m_dualdiv_div.hw,
+ [CLKID_USB_48M_DUALDIV_SEL] = &a9_usb_48m_dualdiv_sel.hw,
+ [CLKID_USB_48M_DUALDIV] = &a9_usb_48m_dualdiv.hw,
+ [CLKID_USB_48M] = &a9_usb_48m.hw,
+ [CLKID_CAN_PE_SEL] = &a9_can_pe_sel.hw,
+ [CLKID_CAN_PE_DIV] = &a9_can_pe_div.hw,
+ [CLKID_CAN_PE] = &a9_can_pe.hw,
+ [CLKID_CAN1_PE_SEL] = &a9_can1_pe_sel.hw,
+ [CLKID_CAN1_PE_DIV] = &a9_can1_pe_div.hw,
+ [CLKID_CAN1_PE] = &a9_can1_pe.hw,
+ [CLKID_CAN_FILTER_SEL] = &a9_can_filter_sel.hw,
+ [CLKID_CAN_FILTER_DIV] = &a9_can_filter_div.hw,
+ [CLKID_CAN_FILTER] = &a9_can_filter.hw,
+ [CLKID_CAN1_FILTER_SEL] = &a9_can1_filter_sel.hw,
+ [CLKID_CAN1_FILTER_DIV] = &a9_can1_filter_div.hw,
+ [CLKID_CAN1_FILTER] = &a9_can1_filter.hw,
+ [CLKID_I3C_SEL] = &a9_i3c_sel.hw,
+ [CLKID_I3C_DIV] = &a9_i3c_div.hw,
+ [CLKID_I3C] = &a9_i3c.hw,
+ [CLKID_TS_DIV] = &a9_ts_div.hw,
+ [CLKID_TS] = &a9_ts.hw,
+ [CLKID_ETH_125M_DIV] = &a9_eth_125m_div.hw,
+ [CLKID_ETH_125M] = &a9_eth_125m.hw,
+ [CLKID_ETH_RMII_SEL] = &a9_eth_rmii_sel.hw,
+ [CLKID_ETH_RMII_DIV] = &a9_eth_rmii_div.hw,
+ [CLKID_ETH_RMII] = &a9_eth_rmii.hw,
+ [CLKID_GEN_SEL] = &a9_gen_sel.hw,
+ [CLKID_GEN_DIV] = &a9_gen_div.hw,
+ [CLKID_GEN] = &a9_gen.hw,
+ [CLKID_CLK24M_IN] = &a9_24m_in.hw,
+ [CLKID_CLK12_24M] = &a9_12_24m.hw,
+ [CLKID_MALI_0_SEL] = &a9_mali_0_sel.hw,
+ [CLKID_MALI_0_DIV] = &a9_mali_0_div.hw,
+ [CLKID_MALI_0] = &a9_mali_0.hw,
+ [CLKID_MALI_1_SEL] = &a9_mali_1_sel.hw,
+ [CLKID_MALI_1_DIV] = &a9_mali_1_div.hw,
+ [CLKID_MALI_1] = &a9_mali_1.hw,
+ [CLKID_MALI] = &a9_mali.hw,
+ [CLKID_MALI_STACK_0_SEL] = &a9_mali_stack_0_sel.hw,
+ [CLKID_MALI_STACK_0_DIV] = &a9_mali_stack_0_div.hw,
+ [CLKID_MALI_STACK_0] = &a9_mali_stack_0.hw,
+ [CLKID_MALI_STACK_1_SEL] = &a9_mali_stack_1_sel.hw,
+ [CLKID_MALI_STACK_1_DIV] = &a9_mali_stack_1_div.hw,
+ [CLKID_MALI_STACK_1] = &a9_mali_stack_1.hw,
+ [CLKID_MALI_STACK] = &a9_mali_stack.hw,
+ [CLKID_DSPA_0_SEL] = &a9_dspa_0_sel.hw,
+ [CLKID_DSPA_0_DIV] = &a9_dspa_0_div.hw,
+ [CLKID_DSPA_0] = &a9_dspa_0.hw,
+ [CLKID_DSPA_1_SEL] = &a9_dspa_1_sel.hw,
+ [CLKID_DSPA_1_DIV] = &a9_dspa_1_div.hw,
+ [CLKID_DSPA_1] = &a9_dspa_1.hw,
+ [CLKID_DSPA] = &a9_dspa.hw,
+ [CLKID_HEVCF_0_SEL] = &a9_hevcf_0_sel.hw,
+ [CLKID_HEVCF_0_DIV] = &a9_hevcf_0_div.hw,
+ [CLKID_HEVCF_0] = &a9_hevcf_0.hw,
+ [CLKID_HEVCF_1_SEL] = &a9_hevcf_1_sel.hw,
+ [CLKID_HEVCF_1_DIV] = &a9_hevcf_1_div.hw,
+ [CLKID_HEVCF_1] = &a9_hevcf_1.hw,
+ [CLKID_HEVCF] = &a9_hevcf.hw,
+ [CLKID_HCODEC_0_SEL] = &a9_hcodec_0_sel.hw,
+ [CLKID_HCODEC_0_DIV] = &a9_hcodec_0_div.hw,
+ [CLKID_HCODEC_0] = &a9_hcodec_0.hw,
+ [CLKID_HCODEC_1_SEL] = &a9_hcodec_1_sel.hw,
+ [CLKID_HCODEC_1_DIV] = &a9_hcodec_1_div.hw,
+ [CLKID_HCODEC_1] = &a9_hcodec_1.hw,
+ [CLKID_HCODEC] = &a9_hcodec.hw,
+ [CLKID_VPU_0_SEL] = &a9_vpu_0_sel.hw,
+ [CLKID_VPU_0_DIV] = &a9_vpu_0_div.hw,
+ [CLKID_VPU_0] = &a9_vpu_0.hw,
+ [CLKID_VPU_1_SEL] = &a9_vpu_1_sel.hw,
+ [CLKID_VPU_1_DIV] = &a9_vpu_1_div.hw,
+ [CLKID_VPU_1] = &a9_vpu_1.hw,
+ [CLKID_VPU] = &a9_vpu.hw,
+ [CLKID_VAPB_0_SEL] = &a9_vapb_0_sel.hw,
+ [CLKID_VAPB_0_DIV] = &a9_vapb_0_div.hw,
+ [CLKID_VAPB_0] = &a9_vapb_0.hw,
+ [CLKID_VAPB_1_SEL] = &a9_vapb_1_sel.hw,
+ [CLKID_VAPB_1_DIV] = &a9_vapb_1_div.hw,
+ [CLKID_VAPB_1] = &a9_vapb_1.hw,
+ [CLKID_VAPB] = &a9_vapb.hw,
+ [CLKID_GE2D] = &a9_ge2d.hw,
+ [CLKID_VPU_CLKB_TMP_SEL] = &a9_vpu_clkb_tmp_sel.hw,
+ [CLKID_VPU_CLKB_TMP_DIV] = &a9_vpu_clkb_tmp_div.hw,
+ [CLKID_VPU_CLKB_TMP] = &a9_vpu_clkb_tmp.hw,
+ [CLKID_VPU_CLKB_DIV] = &a9_vpu_clkb_div.hw,
+ [CLKID_VPU_CLKB] = &a9_vpu_clkb.hw,
+ [CLKID_HDMITX_SYS_SEL] = &a9_hdmitx_sys_sel.hw,
+ [CLKID_HDMITX_SYS_DIV] = &a9_hdmitx_sys_div.hw,
+ [CLKID_HDMITX_SYS] = &a9_hdmitx_sys.hw,
+ [CLKID_HDMITX_PRIF_SEL] = &a9_hdmitx_prif_sel.hw,
+ [CLKID_HDMITX_PRIF_DIV] = &a9_hdmitx_prif_div.hw,
+ [CLKID_HDMITX_PRIF] = &a9_hdmitx_prif.hw,
+ [CLKID_HDMITX_200M_SEL] = &a9_hdmitx_200m_sel.hw,
+ [CLKID_HDMITX_200M_DIV] = &a9_hdmitx_200m_div.hw,
+ [CLKID_HDMITX_200M] = &a9_hdmitx_200m.hw,
+ [CLKID_HDMITX_AUD_SEL] = &a9_hdmitx_aud_sel.hw,
+ [CLKID_HDMITX_AUD_DIV] = &a9_hdmitx_aud_div.hw,
+ [CLKID_HDMITX_AUD] = &a9_hdmitx_aud.hw,
+ [CLKID_HDMIRX_5M_SEL] = &a9_hdmirx_5m_sel.hw,
+ [CLKID_HDMIRX_5M_DIV] = &a9_hdmirx_5m_div.hw,
+ [CLKID_HDMIRX_5M] = &a9_hdmirx_5m.hw,
+ [CLKID_HDMIRX_2M_SEL] = &a9_hdmirx_2m_sel.hw,
+ [CLKID_HDMIRX_2M_DIV] = &a9_hdmirx_2m_div.hw,
+ [CLKID_HDMIRX_2M] = &a9_hdmirx_2m.hw,
+ [CLKID_HDMIRX_CFG_SEL] = &a9_hdmirx_cfg_sel.hw,
+ [CLKID_HDMIRX_CFG_DIV] = &a9_hdmirx_cfg_div.hw,
+ [CLKID_HDMIRX_CFG] = &a9_hdmirx_cfg.hw,
+ [CLKID_HDMIRX_HDCP2X_SEL] = &a9_hdmirx_hdcp2x_sel.hw,
+ [CLKID_HDMIRX_HDCP2X_DIV] = &a9_hdmirx_hdcp2x_div.hw,
+ [CLKID_HDMIRX_HDCP2X] = &a9_hdmirx_hdcp2x.hw,
+ [CLKID_HDMIRX_ACR_REF_SEL] = &a9_hdmirx_acr_ref_sel.hw,
+ [CLKID_HDMIRX_ACR_REF_DIV] = &a9_hdmirx_acr_ref_div.hw,
+ [CLKID_HDMIRX_ACR_REF] = &a9_hdmirx_acr_ref.hw,
+ [CLKID_HDMIRX_METER_SEL] = &a9_hdmirx_meter_sel.hw,
+ [CLKID_HDMIRX_METER_DIV] = &a9_hdmirx_meter_div.hw,
+ [CLKID_HDMIRX_METER] = &a9_hdmirx_meter.hw,
+ [CLKID_VID_LOCK_SEL] = &a9_vid_lock_sel.hw,
+ [CLKID_VID_LOCK_DIV] = &a9_vid_lock_div.hw,
+ [CLKID_VID_LOCK] = &a9_vid_lock.hw,
+ [CLKID_VDIN_MEAS_SEL] = &a9_vdin_meas_sel.hw,
+ [CLKID_VDIN_MEAS_DIV] = &a9_vdin_meas_div.hw,
+ [CLKID_VDIN_MEAS] = &a9_vdin_meas.hw,
+ [CLKID_VID_PLL_DIV] = &a9_vid_pll_div.hw,
+ [CLKID_VID_PLL_SEL] = &a9_vid_pll_sel.hw,
+ [CLKID_VID_PLL] = &a9_vid_pll.hw,
+ [CLKID_VID_PLL_VCLK] = &a9_vid_pll_vclk.hw,
+ [CLKID_VCLK_SEL] = &a9_vclk_sel.hw,
+ [CLKID_VCLK_IN] = &a9_vclk_in.hw,
+ [CLKID_VCLK_DIV] = &a9_vclk_div.hw,
+ [CLKID_VCLK] = &a9_vclk.hw,
+ [CLKID_VCLK_DIV1_EN] = &a9_vclk_div1_en.hw,
+ [CLKID_VCLK_DIV2_EN] = &a9_vclk_div2_en.hw,
+ [CLKID_VCLK_DIV2] = &a9_vclk_div2.hw,
+ [CLKID_VCLK_DIV4_EN] = &a9_vclk_div4_en.hw,
+ [CLKID_VCLK_DIV4] = &a9_vclk_div4.hw,
+ [CLKID_VCLK_DIV6_EN] = &a9_vclk_div6_en.hw,
+ [CLKID_VCLK_DIV6] = &a9_vclk_div6.hw,
+ [CLKID_VCLK_DIV12_EN] = &a9_vclk_div12_en.hw,
+ [CLKID_VCLK_DIV12] = &a9_vclk_div12.hw,
+ [CLKID_VCLK2_SEL] = &a9_vclk2_sel.hw,
+ [CLKID_VCLK2_IN] = &a9_vclk2_in.hw,
+ [CLKID_VCLK2_DIV] = &a9_vclk2_div.hw,
+ [CLKID_VCLK2] = &a9_vclk2.hw,
+ [CLKID_VCLK2_DIV1_EN] = &a9_vclk2_div1_en.hw,
+ [CLKID_VCLK2_DIV2_EN] = &a9_vclk2_div2_en.hw,
+ [CLKID_VCLK2_DIV2] = &a9_vclk2_div2.hw,
+ [CLKID_VCLK2_DIV4_EN] = &a9_vclk2_div4_en.hw,
+ [CLKID_VCLK2_DIV4] = &a9_vclk2_div4.hw,
+ [CLKID_VCLK2_DIV6_EN] = &a9_vclk2_div6_en.hw,
+ [CLKID_VCLK2_DIV6] = &a9_vclk2_div6.hw,
+ [CLKID_VCLK2_DIV12_EN] = &a9_vclk2_div12_en.hw,
+ [CLKID_VCLK2_DIV12] = &a9_vclk2_div12.hw,
+ [CLKID_VDAC_SEL] = &a9_vdac_sel.hw,
+ [CLKID_VDAC] = &a9_vdac.hw,
+ [CLKID_ENC_SEL] = &a9_enc_sel.hw,
+ [CLKID_ENC] = &a9_enc.hw,
+ [CLKID_ENC1_SEL] = &a9_enc1_sel.hw,
+ [CLKID_ENC1] = &a9_enc1.hw,
+ [CLKID_HDMITX_PIXEL_SEL] = &a9_hdmitx_pixel_sel.hw,
+ [CLKID_HDMITX_PIXEL] = &a9_hdmitx_pixel.hw,
+ [CLKID_HDMITX_FE_SEL] = &a9_hdmitx_fe_sel.hw,
+ [CLKID_HDMITX_FE] = &a9_hdmitx_fe.hw,
+ [CLKID_HDMITX1_PIXEL_SEL] = &a9_hdmitx1_pixel_sel.hw,
+ [CLKID_HDMITX1_PIXEL] = &a9_hdmitx1_pixel.hw,
+ [CLKID_HDMITX1_FE_SEL] = &a9_hdmitx1_fe_sel.hw,
+ [CLKID_HDMITX1_FE] = &a9_hdmitx1_fe.hw,
+ [CLKID_CSI_PHY_SEL] = &a9_csi_phy_sel.hw,
+ [CLKID_CSI_PHY_DIV] = &a9_csi_phy_div.hw,
+ [CLKID_CSI_PHY] = &a9_csi_phy.hw,
+ [CLKID_DSI_MEAS_SEL] = &a9_dsi_meas_sel.hw,
+ [CLKID_DSI_MEAS_DIV] = &a9_dsi_meas_div.hw,
+ [CLKID_DSI_MEAS] = &a9_dsi_meas.hw,
+ [CLKID_DSI_B_MEAS_SEL] = &a9_dsi_b_meas_sel.hw,
+ [CLKID_DSI_B_MEAS_DIV] = &a9_dsi_b_meas_div.hw,
+ [CLKID_DSI_B_MEAS] = &a9_dsi_b_meas.hw,
+};
+
+static const struct meson_clkc_data a9_peripherals_clkc_data = {
+ .hw_clks = {
+ .hws = a9_peripherals_hw_clks,
+ .num = ARRAY_SIZE(a9_peripherals_hw_clks),
+ },
+};
+
+static const struct of_device_id a9_peripherals_clkc_match_table[] = {
+ {
+ .compatible = "amlogic,a9-peripherals-clkc",
+ .data = &a9_peripherals_clkc_data,
+ },
+ { /* sentinel */ }
+};
+
+MODULE_DEVICE_TABLE(of, a9_peripherals_clkc_match_table);
+
+static struct platform_driver a9_peripherals_clkc_driver = {
+ .probe = meson_clkc_mmio_probe,
+ .driver = {
+ .name = "a9-peripherals-clkc",
+ .of_match_table = a9_peripherals_clkc_match_table,
+ },
+};
+module_platform_driver(a9_peripherals_clkc_driver);
+
+MODULE_DESCRIPTION("Amlogic A9 Peripherals Clock Controller driver");
+MODULE_AUTHOR("Jian Hu <jian.hu@amlogic.com>");
+MODULE_LICENSE("GPL");
+MODULE_IMPORT_NS("CLK_MESON");
--
2.47.1
^ permalink raw reply related
* [PATCH v3 1/2] dt-bindings: clock: Add Amlogic A9 peripherals clock controller
From: Jian Hu via B4 Relay @ 2026-06-10 8:14 UTC (permalink / raw)
To: Neil Armstrong, Jerome Brunet, Michael Turquette, Stephen Boyd,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Xianwei Zhao,
Kevin Hilman, Martin Blumenstingl
Cc: linux-amlogic, linux-clk, devicetree, linux-kernel,
linux-arm-kernel, Jian Hu, Conor Dooley
In-Reply-To: <20260610-a9_peripherals-v3-0-d07a78085f71@amlogic.com>
From: Jian Hu <jian.hu@amlogic.com>
Add the peripherals clock controller dt-bindings for the Amlogic A9
SoC family.
Acked-by: Conor Dooley <conor.dooley@microchip.com>
Signed-off-by: Jian Hu <jian.hu@amlogic.com>
---
.../clock/amlogic,a9-peripherals-clkc.yaml | 160 ++++++++++
.../clock/amlogic,a9-peripherals-clkc.h | 352 +++++++++++++++++++++
2 files changed, 512 insertions(+)
diff --git a/Documentation/devicetree/bindings/clock/amlogic,a9-peripherals-clkc.yaml b/Documentation/devicetree/bindings/clock/amlogic,a9-peripherals-clkc.yaml
new file mode 100644
index 000000000000..1d0abbaa85b8
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/amlogic,a9-peripherals-clkc.yaml
@@ -0,0 +1,160 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+# Copyright (C) 2026 Amlogic, Inc. All rights reserved
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/amlogic,a9-peripherals-clkc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Amlogic A9 Series Peripherals Clock Controller
+
+maintainers:
+ - Neil Armstrong <neil.armstrong@linaro.org>
+ - Jerome Brunet <jbrunet@baylibre.com>
+ - Jian Hu <jian.hu@amlogic.com>
+ - Xianwei Zhao <xianwei.zhao@amlogic.com>
+
+properties:
+ compatible:
+ const: amlogic,a9-peripherals-clkc
+
+ reg:
+ maxItems: 1
+
+ '#clock-cells':
+ const: 1
+
+ clocks:
+ minItems: 26
+ items:
+ - description: input oscillator
+ - description: input fclk div 2
+ - description: input fclk div 3
+ - description: input fclk div 4
+ - description: input fclk div 5
+ - description: input fclk div 7
+ - description: input fclk div 2p5
+ - description: input sys clk
+ - description: input gp1 pll
+ - description: input gp2 pll
+ - description: input sys pll div 16
+ - description: input cpu clk div 16
+ - description: input a78 clk div 16
+ - description: input dsu clk div 16
+ - description: input rtc clk
+ - description: input gp0 pll
+ - description: input hifi0 pll
+ - description: input hifi1 pll
+ - description: input mclk0 pll
+ - description: input mclk1 pll
+ - description: input video1 pll
+ - description: input video2 pll
+ - description: input hdmi out2 clk
+ - description: input hdmi pixel clk
+ - description: input pixel0 pll
+ - description: input pixel1 pll
+ - description: external input rmii oscillator (optional)
+
+ clock-names:
+ minItems: 26
+ items:
+ - const: xtal
+ - const: fdiv2
+ - const: fdiv3
+ - const: fdiv4
+ - const: fdiv5
+ - const: fdiv7
+ - const: fdiv2p5
+ - const: sys
+ - const: gp1
+ - const: gp2
+ - const: sysplldiv16
+ - const: cpudiv16
+ - const: a78div16
+ - const: dsudiv16
+ - const: rtc
+ - const: gp0
+ - const: hifi0
+ - const: hifi1
+ - const: mclk0
+ - const: mclk1
+ - const: vid1
+ - const: vid2
+ - const: hdmiout2
+ - const: hdmipix
+ - const: pix0
+ - const: pix1
+ - const: ext_rmii
+
+required:
+ - compatible
+ - reg
+ - '#clock-cells'
+ - clocks
+ - clock-names
+
+additionalProperties: false
+
+examples:
+ - |
+ soc {
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ clock-controller@200 {
+ compatible = "amlogic,a9-peripherals-clkc";
+ reg = <0x0 0x200 0x0 0x2f8>;
+ #clock-cells = <1>;
+ clocks = <&xtal>,
+ <&scmi_clk 10>,
+ <&scmi_clk 12>,
+ <&scmi_clk 14>,
+ <&scmi_clk 16>,
+ <&scmi_clk 18>,
+ <&scmi_clk 20>,
+ <&scmi_clk 21>,
+ <&scmi_clk 33>,
+ <&scmi_clk 34>,
+ <&scmi_clk 35>,
+ <&scmi_clk 36>,
+ <&scmi_clk 37>,
+ <&scmi_clk 38>,
+ <&scmi_clk 40>,
+ <&gp0 3>,
+ <&hifi0 3>,
+ <&hifi1 3>,
+ <&mclk0 3>,
+ <&mclk1 3>,
+ <&vid1>,
+ <&vid2>,
+ <&hdmitx 10>,
+ <&hdmitx 11>,
+ <&pix0>,
+ <&pix1>;
+ clock-names = "xtal",
+ "fdiv2",
+ "fdiv3",
+ "fdiv4",
+ "fdiv5",
+ "fdiv7",
+ "fdiv2p5",
+ "sys",
+ "gp1",
+ "gp2",
+ "sysplldiv16",
+ "cpudiv16",
+ "a78div16",
+ "dsudiv16",
+ "rtc",
+ "gp0",
+ "hifi0",
+ "hifi1",
+ "mclk0",
+ "mclk1",
+ "vid1",
+ "vid2",
+ "hdmiout2",
+ "hdmipix",
+ "pix0",
+ "pix1";
+ };
+ };
diff --git a/include/dt-bindings/clock/amlogic,a9-peripherals-clkc.h b/include/dt-bindings/clock/amlogic,a9-peripherals-clkc.h
new file mode 100644
index 000000000000..bca69771d728
--- /dev/null
+++ b/include/dt-bindings/clock/amlogic,a9-peripherals-clkc.h
@@ -0,0 +1,352 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+/*
+ * Copyright (C) 2026 Amlogic, Inc. All rights reserved.
+ */
+
+#ifndef __AMLOGIC_A9_PERIPHERALS_CLKC_H
+#define __AMLOGIC_A9_PERIPHERALS_CLKC_H
+
+#define CLKID_SYS_AM_AXI 0
+#define CLKID_SYS_DOS 1
+#define CLKID_SYS_MIPI_DSI 2
+#define CLKID_SYS_ETH_PHY 3
+#define CLKID_SYS_AMFC 4
+#define CLKID_SYS_MALI 5
+#define CLKID_SYS_NNA 6
+#define CLKID_SYS_ETH_AXI 7
+#define CLKID_SYS_DP_APB 8
+#define CLKID_SYS_EDPTX_APB 9
+#define CLKID_SYS_U3HSG 10
+#define CLKID_SYS_AUCPU 11
+#define CLKID_SYS_GLB 12
+#define CLKID_SYS_COMBO_DPHY_APB 13
+#define CLKID_SYS_HDMIRX_APB 14
+#define CLKID_SYS_HDMIRX_PCLK 15
+#define CLKID_SYS_MIPI_DSI_PHY 16
+#define CLKID_SYS_CAN0 17
+#define CLKID_SYS_CAN1 18
+#define CLKID_SYS_SD_EMMC_A 19
+#define CLKID_SYS_SD_EMMC_B 20
+#define CLKID_SYS_SD_EMMC_C 21
+#define CLKID_SYS_SC 22
+#define CLKID_SYS_ACODEC 23
+#define CLKID_SYS_MIPI_ISP 24
+#define CLKID_SYS_MSR 25
+#define CLKID_SYS_AUDIO 26
+#define CLKID_SYS_MIPI_DSI_B 27
+#define CLKID_SYS_MIPI_DSI1_PHY 28
+#define CLKID_SYS_ETH 29
+#define CLKID_SYS_ETH_1G_MAC 30
+#define CLKID_SYS_UART_A 31
+#define CLKID_SYS_UART_F 32
+#define CLKID_SYS_TS_A55 33
+#define CLKID_SYS_ETH_1G_AXI 34
+#define CLKID_SYS_TS_DOS 35
+#define CLKID_SYS_U3DRD_B 36
+#define CLKID_SYS_TS_CORE 37
+#define CLKID_SYS_TS_PLL 38
+#define CLKID_SYS_CSI_DIG_CLKIN 39
+#define CLKID_SYS_CVE 40
+#define CLKID_SYS_GE2D 41
+#define CLKID_SYS_SPISG 42
+#define CLKID_SYS_U3DRD_1 43
+#define CLKID_SYS_U2H 44
+#define CLKID_SYS_PCIE_MAC_A 45
+#define CLKID_SYS_U3DRD_A 46
+#define CLKID_SYS_U2DRD 47
+#define CLKID_SYS_PCIE_PHY 48
+#define CLKID_SYS_PCIE_MAC_B 49
+#define CLKID_SYS_PERIPH 50
+#define CLKID_SYS_PIO 51
+#define CLKID_SYS_I3C 52
+#define CLKID_SYS_I2C_M_E 53
+#define CLKID_SYS_I2C_M_F 54
+#define CLKID_SYS_HDMITX_APB 55
+#define CLKID_SYS_I2C_M_I 56
+#define CLKID_SYS_I2C_M_G 57
+#define CLKID_SYS_I2C_M_H 58
+#define CLKID_SYS_HDMI20_AES 59
+#define CLKID_SYS_CSI2_HOST 60
+#define CLKID_SYS_CSI2_ADAPT 61
+#define CLKID_SYS_DSPA 62
+#define CLKID_SYS_PP_DMA 63
+#define CLKID_SYS_PP_WRAPPER 64
+#define CLKID_SYS_VPU_INTR 65
+#define CLKID_SYS_CSI2_PHY 66
+#define CLKID_SYS_SARADC 67
+#define CLKID_SYS_PWM_J 68
+#define CLKID_SYS_PWM_I 69
+#define CLKID_SYS_PWM_H 70
+#define CLKID_SYS_PWM_N 71
+#define CLKID_SYS_PWM_M 72
+#define CLKID_SYS_PWM_L 73
+#define CLKID_SYS_PWM_K 74
+#define CLKID_SD_EMMC_A_SEL 75
+#define CLKID_SD_EMMC_A_DIV 76
+#define CLKID_SD_EMMC_A 77
+#define CLKID_SD_EMMC_B_SEL 78
+#define CLKID_SD_EMMC_B_DIV 79
+#define CLKID_SD_EMMC_B 80
+#define CLKID_SD_EMMC_C_SEL 81
+#define CLKID_SD_EMMC_C_DIV 82
+#define CLKID_SD_EMMC_C 83
+#define CLKID_PWM_H_SEL 84
+#define CLKID_PWM_H_DIV 85
+#define CLKID_PWM_H 86
+#define CLKID_PWM_I_SEL 87
+#define CLKID_PWM_I_DIV 88
+#define CLKID_PWM_I 89
+#define CLKID_PWM_J_SEL 90
+#define CLKID_PWM_J_DIV 91
+#define CLKID_PWM_J 92
+#define CLKID_PWM_K_SEL 93
+#define CLKID_PWM_K_DIV 94
+#define CLKID_PWM_K 95
+#define CLKID_PWM_L_SEL 96
+#define CLKID_PWM_L_DIV 97
+#define CLKID_PWM_L 98
+#define CLKID_PWM_M_SEL 99
+#define CLKID_PWM_M_DIV 100
+#define CLKID_PWM_M 101
+#define CLKID_PWM_N_SEL 102
+#define CLKID_PWM_N_DIV 103
+#define CLKID_PWM_N 104
+#define CLKID_SPISG_SEL 105
+#define CLKID_SPISG_DIV 106
+#define CLKID_SPISG 107
+#define CLKID_SPISG1_SEL 108
+#define CLKID_SPISG1_DIV 109
+#define CLKID_SPISG1 110
+#define CLKID_SPISG2_SEL 111
+#define CLKID_SPISG2_DIV 112
+#define CLKID_SPISG2 113
+#define CLKID_SARADC_SEL 114
+#define CLKID_SARADC_DIV 115
+#define CLKID_SARADC 116
+#define CLKID_AMFC_SEL 117
+#define CLKID_AMFC_DIV 118
+#define CLKID_AMFC 119
+#define CLKID_NNA_SEL 120
+#define CLKID_NNA_DIV 121
+#define CLKID_NNA 122
+#define CLKID_USB_250M_SEL 123
+#define CLKID_USB_250M_DIV 124
+#define CLKID_USB_250M 125
+#define CLKID_USB_48M_PRE_SEL 126
+#define CLKID_USB_48M_PRE_DIV 127
+#define CLKID_USB_48M_PRE 128
+#define CLKID_PCIE_TL_SEL 129
+#define CLKID_PCIE_TL_DIV 130
+#define CLKID_PCIE_TL 131
+#define CLKID_PCIE1_TL_SEL 132
+#define CLKID_PCIE1_TL_DIV 133
+#define CLKID_PCIE1_TL 134
+#define CLKID_CMPR_SEL 135
+#define CLKID_CMPR_DIV 136
+#define CLKID_CMPR 137
+#define CLKID_DEWARPA_SEL 138
+#define CLKID_DEWARPA_DIV 139
+#define CLKID_DEWARPA 140
+#define CLKID_SC_PRE_SEL 141
+#define CLKID_SC_PRE_DIV 142
+#define CLKID_SC_PRE 143
+#define CLKID_SC 144
+#define CLKID_DPTX_APB2_SEL 145
+#define CLKID_DPTX_APB2_DIV 146
+#define CLKID_DPTX_APB2 147
+#define CLKID_DPTX_AUD_SEL 148
+#define CLKID_DPTX_AUD_DIV 149
+#define CLKID_DPTX_AUD 150
+#define CLKID_ISP_SEL 151
+#define CLKID_ISP_DIV 152
+#define CLKID_ISP 153
+#define CLKID_CVE_SEL 154
+#define CLKID_CVE_DIV 155
+#define CLKID_CVE 156
+#define CLKID_VGE_SEL 157
+#define CLKID_VGE_DIV 158
+#define CLKID_VGE 159
+#define CLKID_PP_SEL 160
+#define CLKID_PP_DIV 161
+#define CLKID_PP 162
+#define CLKID_GLB_SEL 163
+#define CLKID_GLB_DIV 164
+#define CLKID_GLB 165
+#define CLKID_USB_48M_DUALDIV_IN 166
+#define CLKID_USB_48M_DUALDIV_DIV 167
+#define CLKID_USB_48M_DUALDIV_SEL 168
+#define CLKID_USB_48M_DUALDIV 169
+#define CLKID_USB_48M 170
+#define CLKID_CAN_PE_SEL 171
+#define CLKID_CAN_PE_DIV 172
+#define CLKID_CAN_PE 173
+#define CLKID_CAN1_PE_SEL 174
+#define CLKID_CAN1_PE_DIV 175
+#define CLKID_CAN1_PE 176
+#define CLKID_CAN_FILTER_SEL 177
+#define CLKID_CAN_FILTER_DIV 178
+#define CLKID_CAN_FILTER 179
+#define CLKID_CAN1_FILTER_SEL 180
+#define CLKID_CAN1_FILTER_DIV 181
+#define CLKID_CAN1_FILTER 182
+#define CLKID_I3C_SEL 183
+#define CLKID_I3C_DIV 184
+#define CLKID_I3C 185
+#define CLKID_TS_DIV 186
+#define CLKID_TS 187
+#define CLKID_ETH_125M_DIV 188
+#define CLKID_ETH_125M 189
+#define CLKID_ETH_RMII_SEL 190
+#define CLKID_ETH_RMII_DIV 191
+#define CLKID_ETH_RMII 192
+#define CLKID_GEN_SEL 193
+#define CLKID_GEN_DIV 194
+#define CLKID_GEN 195
+#define CLKID_CLK24M_IN 196
+#define CLKID_CLK12_24M 197
+#define CLKID_MALI_0_SEL 198
+#define CLKID_MALI_0_DIV 199
+#define CLKID_MALI_0 200
+#define CLKID_MALI_1_SEL 201
+#define CLKID_MALI_1_DIV 202
+#define CLKID_MALI_1 203
+#define CLKID_MALI 204
+#define CLKID_MALI_STACK_0_SEL 205
+#define CLKID_MALI_STACK_0_DIV 206
+#define CLKID_MALI_STACK_0 207
+#define CLKID_MALI_STACK_1_SEL 208
+#define CLKID_MALI_STACK_1_DIV 209
+#define CLKID_MALI_STACK_1 210
+#define CLKID_MALI_STACK 211
+#define CLKID_DSPA_0_SEL 212
+#define CLKID_DSPA_0_DIV 213
+#define CLKID_DSPA_0 214
+#define CLKID_DSPA_1_SEL 215
+#define CLKID_DSPA_1_DIV 216
+#define CLKID_DSPA_1 217
+#define CLKID_DSPA 218
+#define CLKID_HEVCF_0_SEL 219
+#define CLKID_HEVCF_0_DIV 220
+#define CLKID_HEVCF_0 221
+#define CLKID_HEVCF_1_SEL 222
+#define CLKID_HEVCF_1_DIV 223
+#define CLKID_HEVCF_1 224
+#define CLKID_HEVCF 225
+#define CLKID_HCODEC_0_SEL 226
+#define CLKID_HCODEC_0_DIV 227
+#define CLKID_HCODEC_0 228
+#define CLKID_HCODEC_1_SEL 229
+#define CLKID_HCODEC_1_DIV 230
+#define CLKID_HCODEC_1 231
+#define CLKID_HCODEC 232
+#define CLKID_VPU_0_SEL 233
+#define CLKID_VPU_0_DIV 234
+#define CLKID_VPU_0 235
+#define CLKID_VPU_1_SEL 236
+#define CLKID_VPU_1_DIV 237
+#define CLKID_VPU_1 238
+#define CLKID_VPU 239
+#define CLKID_VAPB_0_SEL 240
+#define CLKID_VAPB_0_DIV 241
+#define CLKID_VAPB_0 242
+#define CLKID_VAPB_1_SEL 243
+#define CLKID_VAPB_1_DIV 244
+#define CLKID_VAPB_1 245
+#define CLKID_VAPB 246
+#define CLKID_GE2D 247
+#define CLKID_VPU_CLKB_TMP_SEL 248
+#define CLKID_VPU_CLKB_TMP_DIV 249
+#define CLKID_VPU_CLKB_TMP 250
+#define CLKID_VPU_CLKB_DIV 251
+#define CLKID_VPU_CLKB 252
+#define CLKID_HDMITX_SYS_SEL 253
+#define CLKID_HDMITX_SYS_DIV 254
+#define CLKID_HDMITX_SYS 255
+#define CLKID_HDMITX_PRIF_SEL 256
+#define CLKID_HDMITX_PRIF_DIV 257
+#define CLKID_HDMITX_PRIF 258
+#define CLKID_HDMITX_200M_SEL 259
+#define CLKID_HDMITX_200M_DIV 260
+#define CLKID_HDMITX_200M 261
+#define CLKID_HDMITX_AUD_SEL 262
+#define CLKID_HDMITX_AUD_DIV 263
+#define CLKID_HDMITX_AUD 264
+#define CLKID_HDMIRX_5M_SEL 265
+#define CLKID_HDMIRX_5M_DIV 266
+#define CLKID_HDMIRX_5M 267
+#define CLKID_HDMIRX_2M_SEL 268
+#define CLKID_HDMIRX_2M_DIV 269
+#define CLKID_HDMIRX_2M 270
+#define CLKID_HDMIRX_CFG_SEL 271
+#define CLKID_HDMIRX_CFG_DIV 272
+#define CLKID_HDMIRX_CFG 273
+#define CLKID_HDMIRX_HDCP2X_SEL 274
+#define CLKID_HDMIRX_HDCP2X_DIV 275
+#define CLKID_HDMIRX_HDCP2X 276
+#define CLKID_HDMIRX_ACR_REF_SEL 277
+#define CLKID_HDMIRX_ACR_REF_DIV 278
+#define CLKID_HDMIRX_ACR_REF 279
+#define CLKID_HDMIRX_METER_SEL 280
+#define CLKID_HDMIRX_METER_DIV 281
+#define CLKID_HDMIRX_METER 282
+#define CLKID_VID_LOCK_SEL 283
+#define CLKID_VID_LOCK_DIV 284
+#define CLKID_VID_LOCK 285
+#define CLKID_VDIN_MEAS_SEL 286
+#define CLKID_VDIN_MEAS_DIV 287
+#define CLKID_VDIN_MEAS 288
+#define CLKID_VID_PLL_DIV 289
+#define CLKID_VID_PLL_SEL 290
+#define CLKID_VID_PLL 291
+#define CLKID_VID_PLL_VCLK 292
+#define CLKID_VCLK_SEL 293
+#define CLKID_VCLK_IN 294
+#define CLKID_VCLK_DIV 295
+#define CLKID_VCLK 296
+#define CLKID_VCLK_DIV1_EN 297
+#define CLKID_VCLK_DIV2_EN 298
+#define CLKID_VCLK_DIV2 299
+#define CLKID_VCLK_DIV4_EN 300
+#define CLKID_VCLK_DIV4 301
+#define CLKID_VCLK_DIV6_EN 302
+#define CLKID_VCLK_DIV6 303
+#define CLKID_VCLK_DIV12_EN 304
+#define CLKID_VCLK_DIV12 305
+#define CLKID_VCLK2_SEL 306
+#define CLKID_VCLK2_IN 307
+#define CLKID_VCLK2_DIV 308
+#define CLKID_VCLK2 309
+#define CLKID_VCLK2_DIV1_EN 310
+#define CLKID_VCLK2_DIV2_EN 311
+#define CLKID_VCLK2_DIV2 312
+#define CLKID_VCLK2_DIV4_EN 313
+#define CLKID_VCLK2_DIV4 314
+#define CLKID_VCLK2_DIV6_EN 315
+#define CLKID_VCLK2_DIV6 316
+#define CLKID_VCLK2_DIV12_EN 317
+#define CLKID_VCLK2_DIV12 318
+#define CLKID_VDAC_SEL 319
+#define CLKID_VDAC 320
+#define CLKID_ENC_SEL 321
+#define CLKID_ENC 322
+#define CLKID_ENC1_SEL 323
+#define CLKID_ENC1 324
+#define CLKID_HDMITX_PIXEL_SEL 325
+#define CLKID_HDMITX_PIXEL 326
+#define CLKID_HDMITX_FE_SEL 327
+#define CLKID_HDMITX_FE 328
+#define CLKID_HDMITX1_PIXEL_SEL 329
+#define CLKID_HDMITX1_PIXEL 330
+#define CLKID_HDMITX1_FE_SEL 331
+#define CLKID_HDMITX1_FE 332
+#define CLKID_CSI_PHY_SEL 333
+#define CLKID_CSI_PHY_DIV 334
+#define CLKID_CSI_PHY 335
+#define CLKID_DSI_MEAS_SEL 336
+#define CLKID_DSI_MEAS_DIV 337
+#define CLKID_DSI_MEAS 338
+#define CLKID_DSI_B_MEAS_SEL 339
+#define CLKID_DSI_B_MEAS_DIV 340
+#define CLKID_DSI_B_MEAS 341
+
+#endif /* __AMLOGIC_A9_PERIPHERALS_CLKC_H */
--
2.47.1
^ permalink raw reply related
* [PATCH v3 0/2] clk: amlogic: Add A9 peripherals clock controller
From: Jian Hu via B4 Relay @ 2026-06-10 8:14 UTC (permalink / raw)
To: Neil Armstrong, Jerome Brunet, Michael Turquette, Stephen Boyd,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Xianwei Zhao,
Kevin Hilman, Martin Blumenstingl
Cc: linux-amlogic, linux-clk, devicetree, linux-kernel,
linux-arm-kernel, Jian Hu, Conor Dooley
This series adds Amlogic A9 peripherals clock support,
including dt-binding and peripherals clock driver.
Note that this driver depends on the A9 PLL driver, which is not yet
upstream. The Meson PLL framework is currently undergoing refactoring,
and the A9 PLL driver will be submitted as a follow-up series after
that work has been completed.
Signed-off-by: Jian Hu <jian.hu@amlogic.com>
---
Changes in v3:
- Add "depend on A9 pll" instructions in the cover-letter.
- Move COMPILE_TEST after 'depends on ARM64' reported by sashiko-bot.
- Fix usb_48m_pre_sel's parent reported by sashiko-bot.
- Fix gen_div width reported by sashiko-bot.
- Fix hdmitx1_pixel's parent reported by sashiko-bot.
- Link to v2: https://lore.kernel.org/r/20260603-a9_peripherals-v2-0-ee1b8c0a1e6c@amlogic.com
Changes in v2:
- Split the A9 clock driver and send the peripherals clock separately.
- Add COMPILE_TEST in Kconfig.
- Drop the 'optional'.
- Rename apb4 to soc.
- Sort the header file.
- Rename hifi to hifi0.
- Use CLK_HW_INIT_PARENTS_DATA to describe clk_init_data.
- Use CLK_HW_INIT_HW to describe clk_init_data.
- Use CLK_HW_INIT_PARENTS_HW to describe clk_init_data.
- Link to v1: https://lore.kernel.org/all/20260511-b4-a9_clk-v1-0-41cb4071b7c9@amlogic.com/
---
Jian Hu (2):
dt-bindings: clock: Add Amlogic A9 peripherals clock controller
clk: amlogic: Add A9 peripherals clock controller driver
.../clock/amlogic,a9-peripherals-clkc.yaml | 160 ++
drivers/clk/meson/Kconfig | 15 +
drivers/clk/meson/Makefile | 1 +
drivers/clk/meson/a9-peripherals.c | 1925 ++++++++++++++++++++
.../clock/amlogic,a9-peripherals-clkc.h | 352 ++++
5 files changed, 2453 insertions(+)
---
base-commit: ca89c88bcf69daca829044c638a8163d5ce47af0
change-id: 20260603-a9_peripherals-4214e79705dc
Best regards,
--
Jian Hu <jian.hu@amlogic.com>
^ permalink raw reply
* [PATCH 2/2] arm64: dts: rockchip: Fix USB hub phy-supply config for NanoPC-T6 LTS
From: Diederik de Haas @ 2026-06-10 8:04 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Heiko Stuebner
Cc: devicetree, linux-arm-kernel, linux-rockchip, linux-kernel,
Jonas Karlman, Marcin Juszkiewicz, Diederik de Haas, stable
In-Reply-To: <20260610081400.758687-1-diederik@cknow-tech.com>
The MTT USB 2.0 hub is connected to the SoC's USB20 HOST1, so the phy-supply
belongs to u2phy3_host, not u2phy2_host as that is for USB20 HOST0.
Fixes: db1dcbe5f752 ("arm64: dts: rockchip: add NanoPC-T6 LTS")
Cc: stable@vger.kernel.org
Signed-off-by: Diederik de Haas <diederik@cknow-tech.com>
---
arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6-lts.dts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6-lts.dts b/arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6-lts.dts
index 0ee67ee24f3c..0e15a2e1f2ff 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6-lts.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6-lts.dts
@@ -38,6 +38,6 @@ usb20_host_pwren: usb20-host-pwren {
};
};
-&u2phy2_host {
+&u2phy3_host {
phy-supply = <&vcc5v0_usb20_host>;
};
--
2.53.0
^ permalink raw reply related
* [PATCH 1/2] arm64: dts: rockchip: Drop duplicate USB nodes on NanoPC-T6 LTS
From: Diederik de Haas @ 2026-06-10 8:04 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Heiko Stuebner
Cc: devicetree, linux-arm-kernel, linux-rockchip, linux-kernel,
Jonas Karlman, Marcin Juszkiewicz, Diederik de Haas
In-Reply-To: <20260610081400.758687-1-diederik@cknow-tech.com>
Several USB nodes were enabled/configured on the NanoPC-T6 LTS first. Then
those same nodes were enabled/configured in the NanoPC-T6 dtsi file, but
the ones in the LTS dts file were not removed, so do so now.
Signed-off-by: Diederik de Haas <diederik@cknow-tech.com>
---
.../boot/dts/rockchip/rk3588-nanopc-t6-lts.dts | 17 -----------------
1 file changed, 17 deletions(-)
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6-lts.dts b/arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6-lts.dts
index ff855064be08..0ee67ee24f3c 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6-lts.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6-lts.dts
@@ -38,23 +38,6 @@ usb20_host_pwren: usb20-host-pwren {
};
};
-&u2phy1 {
- status = "okay";
-};
-
-&u2phy1_otg {
- status = "okay";
-};
-
&u2phy2_host {
phy-supply = <&vcc5v0_usb20_host>;
};
-
-&usbdp_phy1 {
- status = "okay";
-};
-
-&usb_host1_xhci {
- dr_mode = "host";
- status = "okay";
-};
--
2.53.0
^ permalink raw reply related
* [PATCH 0/2] Cleanup and fix for NanoPC-T6 Plus
From: Diederik de Haas @ 2026-06-10 8:04 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Heiko Stuebner
Cc: devicetree, linux-arm-kernel, linux-rockchip, linux-kernel,
Jonas Karlman, Marcin Juszkiewicz, Diederik de Haas
Several nodes were enabled/configured when support for the NanoPC-T6 Plus was
added, but later those same nodes got enabled/configured in the dtsi file,
making those in the dts file superfluous, so remove them.
The MTT USB 2.0 Hub is connected to USB20 HOST1, so the phy-supply belongs to
u2phy3_host, not u2phy2_host as that is for USB20 HOST0.
Diederik de Haas (2):
arm64: dts: rockchip: Drop duplicate USB nodes on NanoPC-T6 LTS
arm64: dts: rockchip: Fix USB hub phy-supply config for NanoPC-T6 LTS
.../dts/rockchip/rk3588-nanopc-t6-lts.dts | 19 +------------------
1 file changed, 1 insertion(+), 18 deletions(-)
--
2.53.0
^ permalink raw reply
* Re: [PATCH v2] gpiolib: handle gpio-hogs only once
From: Bartosz Golaszewski @ 2026-06-10 8:13 UTC (permalink / raw)
To: linusw, brgl, Daniel Drake
Cc: Bartosz Golaszewski, linux-gpio, linux-arm-kernel
In-Reply-To: <20260608210108.36248-1-dan@reactivated.net>
On Mon, 08 Jun 2026 22:01:08 +0100, Daniel Drake wrote:
> Commit d1d564ec49929 ("gpio: move hogs into GPIO core") introduced a
> behaviour change that breaks boot on Raspberry Pi 5 when using the
> firmware-supplied device tree:
>
> gpiochip_add_data_with_key: GPIOs 544..575
> (/soc@107c000000/gpio@7d517c00) failed to register, -22
> brcmstb-gpio 107d517c00.gpio: Could not add gpiochip for bank 1
> brcmstb-gpio 107d517c00.gpio: probe with driver brcmstb-gpio failed
> with error -22
>
> [...]
Applied, thanks!
[1/1] gpiolib: handle gpio-hogs only once
https://git.kernel.org/brgl/c/a23226b7c1f69eafd9ced4e037fb51c9758c0501
Best regards,
--
Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
^ permalink raw reply
* Re: [PATCH v2] gpiolib: handle gpio-hogs only once
From: Bartosz Golaszewski @ 2026-06-10 8:12 UTC (permalink / raw)
To: Daniel Drake; +Cc: linux-gpio, linux-arm-kernel, linusw, Bartosz Golaszewski
In-Reply-To: <b07f5bd8-26f8-4de4-becb-4f76f9d33361@reactivated.net>
On Tue, 9 Jun 2026 22:48:03 +0200, Daniel Drake <dan@reactivated.net> said:
> On 09/06/2026 13:39, Bartosz Golaszewski wrote:
>> On Mon, 8 Jun 2026 23:01:08 +0200, Daniel Drake <dan@reactivated.net> said:
>>> diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
>>> index 1e6dce430dca..b02d711289d0 100644
>>> --- a/drivers/gpio/gpiolib.c
>>> +++ b/drivers/gpio/gpiolib.c
>>> @@ -1031,9 +1031,17 @@ static int gpiochip_hog_lines(struct gpio_chip *gc)
>>> if (!fwnode_property_present(fwnode, "gpio-hog"))
>>> continue;
>>>
>>> + /* The hog may have been handled by another gpio_chip on the same fwnode */
>>> + if (is_of_node(fwnode) &&
>>> + of_node_check_flag(to_of_node(fwnode), OF_POPULATED))
>>> + continue;
>>> +
>>> ret = gpiochip_add_hog(gc, fwnode);
>>> if (ret)
>>> return ret;
>>> +
>>> + if (is_of_node(fwnode))
>>> + of_node_set_flag(to_of_node(fwnode), OF_POPULATED);
>>
>> Sashiko correctly points out that on errors, the state will be corrupted. We
>> could maybe move the clearing of the flag to gpiochip_free_hogs() and track its
>> state when processing fwnodes in order not to clear it incorrectly?
>
> I guess you are referring to:
>
>> Does setting OF_POPULATED here cause state corruption if a secondary chip on a
>> shared node fails to probe?
>> When multiple gpio_chip instances share a device node, the first chip processes
>> its hogs and sets OF_POPULATED. If a subsequent chip fails probe (for example,
>> returning -EPROBE_DEFER), its cleanup path calls of_gpiochip_remove() which
>> clears the flag for all hogs.
>> If the flag is unconditionally cleared, will the deferred chip attempt to
>> process the first chip's hogs on retry, fail due to a mismatch, and
>> permanently abort probe?
>
>
> I don't think this is actually an issue. If we have two gpio_chips
> sharing a device node, a first one with a hog that probes fine and a
> subsequent one that fails during probe, both of the gpio_chips will
> brought down and the flag is cleared. If it was a EPROBE_DEFER case
> which is then retried later, the first chip's hogs will be set up a 2nd
> time when the probe is retried.
>
> It is true that the teardown of the 2nd gpio_chip would erase the
> OF_POPULATED flag of a gpio-hog node that it does not "own", but the
> first gpio_chip would also be torn down at the same time (and
> OF_POPULATED unset a 2nd time). This is not ideal, but harmless as far
> as I can see.
>
> I don't quite follow the suggestion for doing the clearing better in
> gpiochip_free_hogs(). It would be neat if we could go from a hogged
> gpio_desc back to the fwnode, so that we could only unset OF_POPULATED
> on the fwnode at the point when we are really removing the hog, but I
> don't see a way to derive the gpio-hog fwnode from gpio_desc. Also, this
> would be complicated because one gpio-hog node can hog multiple gpios.
>
> Let me know if I'm missing anything or if you have any preference to
> handle this differently!
>
> Thanks
> Daniel
>
>
Ok, thanks for the clarification. Let's give this a chance then.
Bart
^ permalink raw reply
* [PATCH v8 09/10] clk: realtek: Add RTD1625-ISO clock controller driver
From: Yu-Chun Lin @ 2026-06-10 8:08 UTC (permalink / raw)
To: mturquette, sboyd, robh, krzk+dt, conor+dt, p.zabel, cylee12,
afaerber, jyanchou
Cc: bmasney, devicetree, linux-clk, linux-kernel, linux-arm-kernel,
linux-realtek-soc, james.tai, cy.huang, stanley_chang,
eleanor.lin
In-Reply-To: <20260610080824.255063-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 v8:
- Remove the trailing NULL element ([RTD1625_XX_CLK_MAX] = NULL) from the
clk_hw_onecell_data arrays.
- Add MODULE_DEVICE_TABLE(of, ...) for the tristate config.
- Add `.suppress_bind_attrs = true`, to avoid handling pointer problem, cause
clock should not allow to manually disable by users.
- Fix a typo.
---
drivers/clk/realtek/Makefile | 1 +
drivers/clk/realtek/clk-rtd1625-iso.c | 151 ++++++++++++++++++++++
drivers/reset/realtek/Makefile | 2 +-
drivers/reset/realtek/reset-rtd1625-iso.c | 99 ++++++++++++++
4 files changed, 252 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 f4a62be092d2..7627eb67ab66 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_CLK_RTD1625) += clk-rtd1625-crt.o
+obj-$(CONFIG_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..52c4a4304284
--- /dev/null
+++ b/drivers/clk/realtek/clk-rtd1625-iso.c
@@ -0,0 +1,151 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2024-2026 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 * const 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),
+ },
+};
+
+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 * const 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),
+ },
+};
+
+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;
+ const char *aux_name = NULL;
+
+ desc = of_device_get_match_data(&pdev->dev);
+ if (!desc)
+ return -EINVAL;
+
+ if (of_device_is_compatible(pdev->dev.of_node, "realtek,rtd1625-iso-clk"))
+ aux_name = "iso_rst";
+ else
+ aux_name = "iso_s_rst";
+
+ return rtk_clk_probe(pdev, desc, aux_name);
+}
+
+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 */ }
+};
+MODULE_DEVICE_TABLE(of, rtd1625_iso_match);
+
+static struct platform_driver rtd1625_iso_driver = {
+ .probe = rtd1625_iso_probe,
+ .driver = {
+ .name = "rtk-rtd1625-iso-clk",
+ .of_match_table = rtd1625_iso_match,
+ .suppress_bind_attrs = true,
+ },
+};
+
+static int __init rtd1625_iso_init(void)
+{
+ return platform_driver_register(&rtd1625_iso_driver);
+}
+subsys_initcall(rtd1625_iso_init);
+
+MODULE_DESCRIPTION("Realtek RTD1625 ISO Clock 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 65c29a12524d..e46a3831b582 100644
--- a/drivers/reset/realtek/Makefile
+++ b/drivers/reset/realtek/Makefile
@@ -1,3 +1,3 @@
# SPDX-License-Identifier: GPL-2.0-only
obj-$(CONFIG_RESET_RTK_COMMON) += common.o
-obj-$(CONFIG_RESET_RTD1625) += reset-rtd1625-crt.o
+obj-$(CONFIG_RESET_RTD1625) += 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..08a5d1e36fbc
--- /dev/null
+++ b/drivers/reset/realtek/reset-rtd1625-iso.c
@@ -0,0 +1,99 @@
+// 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 const 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 const 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;
+ }
+
+ data->rcdev.owner = THIS_MODULE;
+
+ return rtk_reset_controller_add(dev, data);
+}
+
+static const struct auxiliary_device_id rtd1625_iso_reset_ids[] = {
+ { .name = "clk_rtk.iso_rst" },
+ { .name = "clk_rtk.iso_s_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_DESCRIPTION("Realtek RTD1625 ISO Reset Controller Driver");
+MODULE_LICENSE("GPL");
+MODULE_IMPORT_NS("REALTEK_RESET");
--
2.43.0
^ permalink raw reply related
* [PATCH v8 01/10] dt-bindings: clock: Add Realtek RTD1625 Clock & Reset Controller
From: Yu-Chun Lin @ 2026-06-10 8:08 UTC (permalink / raw)
To: mturquette, sboyd, robh, krzk+dt, conor+dt, p.zabel, cylee12,
afaerber, jyanchou
Cc: bmasney, devicetree, linux-clk, linux-kernel, linux-arm-kernel,
linux-realtek-soc, james.tai, cy.huang, stanley_chang,
eleanor.lin, Krzysztof Kozlowski
In-Reply-To: <20260610080824.255063-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 v8:
- None
---
.../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 355e4ab2f9e5..613ca7e95e47 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -22477,6 +22477,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.43.0
^ permalink raw reply related
* [PATCH v8 07/10] clk: realtek: Add support for MMC-tuned PLL clocks
From: Yu-Chun Lin @ 2026-06-10 8:08 UTC (permalink / raw)
To: mturquette, sboyd, robh, krzk+dt, conor+dt, p.zabel, cylee12,
afaerber, jyanchou
Cc: bmasney, devicetree, linux-clk, linux-kernel, linux-arm-kernel,
linux-realtek-soc, james.tai, cy.huang, stanley_chang,
eleanor.lin
In-Reply-To: <20260610080824.255063-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 v8:
- Fix the mask shift in set_phrt0().
- For better safety and readability, modify pointer comparison for phase_id.
- In clk_pll_mmc_recalc_rate(), return 0 instead of an error code upon failure.
---
MAINTAINERS | 8 +
drivers/clk/realtek/Kconfig | 3 +
drivers/clk/realtek/Makefile | 2 +
drivers/clk/realtek/clk-pll-mmc.c | 459 ++++++++++++++++++++++++++++++
drivers/clk/realtek/clk-pll.h | 13 +
5 files changed, 485 insertions(+)
create mode 100644 drivers/clk/realtek/clk-pll-mmc.c
diff --git a/MAINTAINERS b/MAINTAINERS
index aec1ea6d35d6..52d8099d32a3 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -22489,6 +22489,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 ed97531e321d..5a832fc3228a 100644
--- a/drivers/clk/realtek/Kconfig
+++ b/drivers/clk/realtek/Kconfig
@@ -27,4 +27,7 @@ config RTK_CLK_COMMON
multiple Realtek clock implementations, and include integration
with reset controllers where required.
+config RTK_CLK_PLL_MMC
+ tristate
+
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..c11cb2bd577e
--- /dev/null
+++ b/drivers/clk/realtek/clk-pll-mmc.c
@@ -0,0 +1,459 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2021-2026 Realtek Semiconductor Corporation
+ * Author: Cheng-Yu Lee <cylee12@realtek.com>
+ */
+
+#include <linux/bits.h>
+#include <linux/export.h>
+#include <linux/math64.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(0)
+#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(8)
+
+#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, ®);
+ 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 << PLL_PHRT0_SHIFT, val << PLL_PHRT0_SHIFT);
+}
+
+static inline int get_phsel(struct clk_pll_mmc *clkm, int id, u32 *val)
+{
+ u32 sft = id ? 8 : 3;
+ u32 raw_val;
+ int ret;
+
+ 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) ? 0 : 1;
+ 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) ? 0 : 1;
+ 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;
+ u64 rate, base;
+ int ret;
+
+ ret = get_ssc_div_n(clkm, &val);
+ if (ret)
+ return 0;
+
+ ret = get_ssc_div_ext_f(clkm, &ext_f);
+ if (ret)
+ return 0;
+
+ base = parent_rate / 4;
+ rate = base * (val + 2);
+ rate += div_u64(base * ext_f, 8192);
+
+ return rate;
+}
+
+static int clk_pll_mmc_determine_rate(struct clk_hw *hw, struct clk_rate_request *req)
+{
+ u32 val;
+
+ if (!req->best_parent_rate)
+ return -EINVAL;
+
+ 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);
+ if (ret)
+ return ret;
+
+ ret = set_sscpll_rs(clkm, 3);
+ if (ret)
+ return ret;
+
+ ret = set_sscpll_icp(clkm, 2);
+ if (ret)
+ return ret;
+ break;
+
+ case 20 ... 30:
+ ret = set_pi_ibselh(clkm, 2);
+ if (ret)
+ return ret;
+
+ ret = set_sscpll_rs(clkm, 3);
+ if (ret)
+ return ret;
+
+ ret = set_sscpll_icp(clkm, 1);
+ if (ret)
+ return ret;
+ break;
+
+ case 10 ... 19:
+ ret = set_pi_ibselh(clkm, 1);
+ if (ret)
+ return ret;
+
+ ret = set_sscpll_rs(clkm, 2);
+ if (ret)
+ return ret;
+
+ ret = set_sscpll_icp(clkm, 1);
+ if (ret)
+ return ret;
+ break;
+
+ case 5 ... 9:
+ ret = set_pi_ibselh(clkm, 0);
+ if (ret)
+ return ret;
+
+ ret = set_sscpll_rs(clkm, 2);
+ if (ret)
+ return ret;
+
+ ret = set_sscpll_icp(clkm, 0);
+ if (ret)
+ return ret;
+ break;
+ }
+
+ 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 59abfa9a6122..192858013384 100644
--- a/drivers/clk/realtek/clk-pll.h
+++ b/drivers/clk/realtek/clk-pll.h
@@ -44,4 +44,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.43.0
^ permalink raw reply related
* [PATCH v8 04/10] clk: realtek: Add support for phase locked loops (PLLs)
From: Yu-Chun Lin @ 2026-06-10 8:08 UTC (permalink / raw)
To: mturquette, sboyd, robh, krzk+dt, conor+dt, p.zabel, cylee12,
afaerber, jyanchou
Cc: bmasney, devicetree, linux-clk, linux-kernel, linux-arm-kernel,
linux-realtek-soc, james.tai, cy.huang, stanley_chang,
eleanor.lin
In-Reply-To: <20260610080824.255063-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 v8:
- Reduce the timeout value in regmap_read_poll_timeout_atomic() from 2000ms to
500ms to avoid prolonged busy-waiting and prevent triggering the NMI Watchdog.
- Remove 'freq_ready_valid' and add comments to clarify that register offset 0
is never a valid address on Realtek SoCs, meaning it is not configured.
- Add the missing spin_unlock_irqrestore() when regmap_read() fails.
---
drivers/clk/realtek/Makefile | 2 +
drivers/clk/realtek/clk-pll.c | 209 +++++++++++++++++++++++++++++++
drivers/clk/realtek/clk-pll.h | 47 +++++++
drivers/clk/realtek/freq_table.c | 38 ++++++
drivers/clk/realtek/freq_table.h | 16 +++
5 files changed, 312 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..6c4343d71dbe
--- /dev/null
+++ b/drivers/clk/realtek/clk-pll.c
@@ -0,0 +1,209 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2024-2026 Realtek Semiconductor Corporation
+ * Author: Cheng-Yu Lee <cylee12@realtek.com>
+ */
+
+#include <linux/export.h>
+#include <linux/regmap.h>
+#include <linux/spinlock.h>
+#include "clk-pll.h"
+
+#define TIMEOUT 500
+
+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;
+
+ /* reg == 0 means not configured.
+ * Register offset 0 is never a valid address on Realtek SoCs.
+ */
+ if (!clkp->freq_ready_reg)
+ 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, 1, TIMEOUT);
+}
+
+static bool is_power_on(struct clk_pll *clkp)
+{
+ u32 val;
+
+ /* reg == 0 means not configured (assume always on).
+ * Register offset 0 is never a valid address on Realtek SoCs.
+ */
+ 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);
+ unsigned long flags;
+
+ if (!clkp->seq_power_off)
+ return;
+
+ spin_lock_irqsave(&clkp->lock, flags);
+
+ regmap_multi_reg_write(clkp->clkr.regmap, clkp->seq_power_off,
+ clkp->num_seq_power_off);
+
+ spin_unlock_irqrestore(&clkp->lock, flags);
+}
+
+static int clk_pll_is_enabled(struct clk_hw *hw)
+{
+ struct clk_pll *clkp = to_clk_pll(hw);
+ unsigned long flags;
+ int ret;
+
+ spin_lock_irqsave(&clkp->lock, flags);
+
+ ret = is_power_on(clkp);
+
+ spin_unlock_irqrestore(&clkp->lock, flags);
+
+ return ret;
+}
+
+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;
+ unsigned long flags;
+ u32 freq_val;
+
+ spin_lock_irqsave(&clkp->lock, flags);
+
+ if (regmap_read(clkp->clkr.regmap, clkp->freq_reg, &freq_val)) {
+ spin_unlock_irqrestore(&clkp->lock, flags);
+ return 0;
+ }
+
+ freq_val &= clkp->freq_mask;
+
+ fv = ftbl_find_by_val_with_mask(clkp->freq_tbl, clkp->freq_mask,
+ freq_val);
+
+ spin_unlock_irqrestore(&clkp->lock, flags);
+
+ 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;
+ unsigned long flags;
+ int ret;
+
+ fv = ftbl_find_by_rate(clkp->freq_tbl, rate);
+ if (!fv || fv->rate != rate)
+ return -EINVAL;
+
+ spin_lock_irqsave(&clkp->lock, flags);
+
+ 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)
+ goto unlock;
+ }
+
+ ret = regmap_update_bits(clkp->clkr.regmap, clkp->freq_reg,
+ clkp->freq_mask, fv->val);
+ if (ret)
+ goto unlock;
+
+ 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)
+ goto unlock;
+ }
+
+ if (is_power_on(clkp)) {
+ ret = wait_freq_ready(clkp);
+ if (ret)
+ goto unlock;
+ }
+
+unlock:
+ spin_unlock_irqrestore(&clkp->lock, flags);
+
+ return ret;
+}
+
+static int clk_pll_enable(struct clk_hw *hw)
+{
+ struct clk_pll *clkp = to_clk_pll(hw);
+ unsigned long flags;
+ int ret = 0;
+
+ if (!clkp->seq_power_on)
+ return ret;
+
+ spin_lock_irqsave(&clkp->lock, flags);
+
+ if (is_power_on(clkp))
+ goto unlock;
+
+ ret = regmap_multi_reg_write(clkp->clkr.regmap, clkp->seq_power_on,
+ clkp->num_seq_power_on);
+ if (ret)
+ goto unlock;
+
+ ret = wait_freq_ready(clkp);
+ if (ret)
+ goto unlock;
+
+unlock:
+ spin_unlock_irqrestore(&clkp->lock, flags);
+
+ return ret;
+}
+
+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..59abfa9a6122
--- /dev/null
+++ b/drivers/clk/realtek/clk-pll.h
@@ -0,0 +1,47 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2017-2026 Realtek Semiconductor Corporation
+ * Author: Cheng-Yu Lee <cylee12@realtek.com>
+ */
+
+#ifndef __CLK_REALTEK_CLK_PLL_H
+#define __CLK_REALTEK_CLK_PLL_H
+
+#include <linux/spinlock.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_mask;
+ u32 freq_ready_reg;
+ u32 freq_ready_val;
+ u32 power_reg;
+ u32 power_mask;
+ u32 power_val_on;
+
+ /* This lock prevents race conditions when multiple CPUs or contexts
+ * simultaneously access this PLL's registers during multi-step operations
+ */
+ spinlock_t lock;
+};
+
+#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..0ff1e5e79102
--- /dev/null
+++ b/drivers/clk/realtek/freq_table.c
@@ -0,0 +1,38 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include <linux/bitops.h>
+#include "freq_table.h"
+
+#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 *best = NULL;
+ unsigned long best_rate = 0;
+
+ 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..16bf7e3fd489
--- /dev/null
+++ b/drivers/clk/realtek/freq_table.h
@@ -0,0 +1,16 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+struct freq_table {
+ u32 val;
+ unsigned long rate;
+};
+
+#define FREQ_TABLE_END \
+ { \
+ .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.43.0
^ permalink raw reply related
* [PATCH v8 03/10] clk: realtek: Introduce a common probe()
From: Yu-Chun Lin @ 2026-06-10 8:08 UTC (permalink / raw)
To: mturquette, sboyd, robh, krzk+dt, conor+dt, p.zabel, cylee12,
afaerber, jyanchou
Cc: bmasney, devicetree, linux-clk, linux-kernel, linux-arm-kernel,
linux-realtek-soc, james.tai, cy.huang, stanley_chang,
eleanor.lin
In-Reply-To: <20260610080824.255063-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 v8:
- Add depends on RESET_CONTROLLER and select MFD_SYSCON for config
RTK_CLK_COMMON.
- Fix error handling for devm_auxiliary_device_create().
---
MAINTAINERS | 1 +
drivers/clk/Kconfig | 1 +
drivers/clk/Makefile | 1 +
drivers/clk/realtek/Kconfig | 30 ++++++++++++++++
drivers/clk/realtek/Makefile | 4 +++
drivers/clk/realtek/common.c | 66 ++++++++++++++++++++++++++++++++++++
drivers/clk/realtek/common.h | 37 ++++++++++++++++++++
7 files changed, 140 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 80e840a6691d..aec1ea6d35d6 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -22484,6 +22484,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 b2efbe9f6acb..8bf262dd23a9 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 a3e2862ebd7e..e226bee2d039 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..ed97531e321d
--- /dev/null
+++ b/drivers/clk/realtek/Kconfig
@@ -0,0 +1,30 @@
+# SPDX-License-Identifier: GPL-2.0-only
+config COMMON_CLK_REALTEK
+ tristate "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"
+ depends on RESET_CONTROLLER
+ select AUXILIARY_BUS
+ select MFD_SYSCON
+ 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..1b40fcc59a76
--- /dev/null
+++ b/drivers/clk/realtek/common.c
@@ -0,0 +1,66 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2019-2026 Realtek Semiconductor Corporation
+ * Author: Cheng-Yu Lee <cylee12@realtek.com>
+ */
+
+#include <linux/auxiliary_bus.h>
+#include <linux/device.h>
+#include <linux/export.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 regmap *map)
+{
+ struct auxiliary_device *adev;
+
+ if (!of_property_present(dev->of_node, "#reset-cells"))
+ return 0;
+
+ adev = devm_auxiliary_device_create(dev, aux_name, (void *)map);
+
+ if (!adev)
+ return -ENOMEM;
+
+ return 0;
+}
+
+int rtk_clk_probe(struct platform_device *pdev, const struct rtk_clk_desc *desc,
+ const char *aux_name)
+{
+ struct device *dev = &pdev->dev;
+ struct regmap *regmap;
+ int i, ret;
+
+ regmap = device_node_to_regmap(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)
+ return dev_err_probe(dev, ret, "failed to register hw of clk%d\n", i);
+ }
+
+ 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, regmap);
+}
+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..c52fcdbff5ee
--- /dev/null
+++ b/drivers/clk/realtek/common.h
@@ -0,0 +1,37 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2016-2026 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 * const *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.43.0
^ permalink raw reply related
* [PATCH v8 06/10] clk: realtek: Add support for mux clock
From: Yu-Chun Lin @ 2026-06-10 8:08 UTC (permalink / raw)
To: mturquette, sboyd, robh, krzk+dt, conor+dt, p.zabel, cylee12,
afaerber, jyanchou
Cc: bmasney, devicetree, linux-clk, linux-kernel, linux-arm-kernel,
linux-realtek-soc, james.tai, cy.huang, stanley_chang,
eleanor.lin
In-Reply-To: <20260610080824.255063-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 v8:
- In clk_regmap_mux_get_parent(), return 0xff instead of 0 to properly indicate
an error.
- In clk_regmap_mux_set_parent(), cast index to u32 to avoid signed integer
- overflow.
---
drivers/clk/realtek/Makefile | 1 +
drivers/clk/realtek/clk-regmap-mux.c | 41 ++++++++++++++++++++++++++
drivers/clk/realtek/clk-regmap-mux.h | 43 ++++++++++++++++++++++++++++
3 files changed, 85 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..8bb66a9e244a
--- /dev/null
+++ b/drivers/clk/realtek/clk-regmap-mux.c
@@ -0,0 +1,41 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2017-2026 Realtek Semiconductor Corporation
+ * Author: Cheng-Yu Lee <cylee12@realtek.com>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/export.h>
+#include <linux/regmap.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;
+
+ return val >= num_parents ? 0xff : 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, (u32)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");
diff --git a/drivers/clk/realtek/clk-regmap-mux.h b/drivers/clk/realtek/clk-regmap-mux.h
new file mode 100644
index 000000000000..fff413222d19
--- /dev/null
+++ b/drivers/clk/realtek/clk-regmap-mux.h
@@ -0,0 +1,43 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2017-2026 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.43.0
^ permalink raw reply related
* [PATCH v8 02/10] reset: Add Realtek basic reset support
From: Yu-Chun Lin @ 2026-06-10 8:08 UTC (permalink / raw)
To: mturquette, sboyd, robh, krzk+dt, conor+dt, p.zabel, cylee12,
afaerber, jyanchou
Cc: bmasney, devicetree, linux-clk, linux-kernel, linux-arm-kernel,
linux-realtek-soc, james.tai, cy.huang, stanley_chang,
eleanor.lin
In-Reply-To: <20260610080824.255063-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 v8:
- None
---
MAINTAINERS | 1 +
drivers/reset/Kconfig | 1 +
drivers/reset/Makefile | 1 +
drivers/reset/realtek/Kconfig | 8 +++
drivers/reset/realtek/Makefile | 2 +
drivers/reset/realtek/common.c | 90 ++++++++++++++++++++++++++++++++++
drivers/reset/realtek/common.h | 29 +++++++++++
7 files changed, 132 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 613ca7e95e47..80e840a6691d 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -22484,6 +22484,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 d009eb0849a3..45a4227b5f44 100644
--- a/drivers/reset/Kconfig
+++ b/drivers/reset/Kconfig
@@ -418,6 +418,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 3e52569bd276..7330fee91365 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..bb6dd856a64a
--- /dev/null
+++ b/drivers/reset/realtek/Kconfig
@@ -0,0 +1,8 @@
+# SPDX-License-Identifier: GPL-2.0-only
+config RESET_RTK_COMMON
+ tristate "Realtek common reset driver" if COMPILE_TEST
+ help
+ This option enables the common reset controller library for
+ Realtek SoCs. It provides shared reset control operations
+ (assert, deassert, status) and a registration helper function
+ that other Realtek-specific reset drivers can use.
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..2ce20c25377b
--- /dev/null
+++ b/drivers/reset/realtek/common.c
@@ -0,0 +1,90 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2019-2026 Realtek Semiconductor Corporation
+ */
+
+#include <linux/device.h>
+#include <linux/export.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 const 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);
+ const struct rtk_reset_desc *desc;
+ u32 mask, val;
+
+ desc = rtk_reset_get_desc(data, idx);
+ mask = desc->write_en ? (0x3U << desc->bit) : BIT(desc->bit);
+ val = desc->write_en ? (0x2U << 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);
+ const struct rtk_reset_desc *desc;
+ u32 mask, val;
+
+ desc = rtk_reset_get_desc(data, idx);
+ mask = desc->write_en ? (0x3U << desc->bit) : BIT(desc->bit);
+ 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);
+ const struct rtk_reset_desc *desc;
+ u32 val;
+ int ret;
+
+ desc = rtk_reset_get_desc(data, idx);
+ 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->descs, data->rcdev.nr_resets and
+ * data->rcdev.owner before calling rtk_reset_controller_add().
+ */
+int rtk_reset_controller_add(struct device *dev,
+ struct rtk_reset_data *data)
+{
+ data->regmap = dev_get_platdata(dev);
+ data->rcdev.ops = &rtk_reset_ops;
+ data->rcdev.dev = dev;
+ data->rcdev.of_node = dev->parent->of_node;
+
+ return devm_reset_controller_register(dev, &data->rcdev);
+}
+EXPORT_SYMBOL_NS_GPL(rtk_reset_controller_add, "REALTEK_RESET");
+
+MODULE_DESCRIPTION("realtek reset infrastructure");
+MODULE_LICENSE("GPL");
diff --git a/drivers/reset/realtek/common.h b/drivers/reset/realtek/common.h
new file mode 100644
index 000000000000..42eb41eae2ec
--- /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;
+ const 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.43.0
^ permalink raw reply related
* [PATCH v8 08/10] clk: realtek: Add RTD1625-CRT clock controller driver
From: Yu-Chun Lin @ 2026-06-10 8:08 UTC (permalink / raw)
To: mturquette, sboyd, robh, krzk+dt, conor+dt, p.zabel, cylee12,
afaerber, jyanchou
Cc: bmasney, devicetree, linux-clk, linux-kernel, linux-arm-kernel,
linux-realtek-soc, james.tai, cy.huang, stanley_chang,
eleanor.lin
In-Reply-To: <20260610080824.255063-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 v8:
- Remove the trailing NULL element ([RTD1625_CRT_CLK_MAX] = NULL) from the
clk_hw_onecell_data arrays.
- Add MODULE_DEVICE_TABLE(of, ...) for the tristate config.
- Add '.suppress_bind_attrs = true' to avoid handling pointer problem, cause
clock should not allow to manually disable by users.
- Fix a typo.
---
drivers/clk/realtek/Kconfig | 15 +
drivers/clk/realtek/Makefile | 1 +
drivers/clk/realtek/clk-rtd1625-crt.c | 792 ++++++++++++++++++++++
drivers/reset/realtek/Kconfig | 11 +
drivers/reset/realtek/Makefile | 1 +
drivers/reset/realtek/reset-rtd1625-crt.c | 187 +++++
6 files changed, 1007 insertions(+)
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 5a832fc3228a..acfbe95014f4 100644
--- a/drivers/clk/realtek/Kconfig
+++ b/drivers/clk/realtek/Kconfig
@@ -30,4 +30,19 @@ config RTK_CLK_COMMON
config RTK_CLK_PLL_MMC
tristate
+config CLK_RTD1625
+ tristate "RTD1625 Clock Controller"
+ depends on RESET_CONTROLLER
+ select RESET_RTD1625
+ 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..f4a62be092d2 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_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..6fa1c1f0d4f3
--- /dev/null
+++ b/drivers/clk/realtek/clk-rtd1625-crt.c
@@ -0,0 +1,792 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2022-2026 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 <linux/spinlock.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,
+ .lock = __SPIN_LOCK_UNLOCKED(pll_acpu.lock),
+};
+
+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,
+ .lock = __SPIN_LOCK_UNLOCKED(pll_ve1.lock),
+};
+
+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,
+ .lock = __SPIN_LOCK_UNLOCKED(pll_ddsa.lock),
+};
+
+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,
+ .lock = __SPIN_LOCK_UNLOCKED(pll_bus.lock),
+};
+
+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,
+ .lock = __SPIN_LOCK_UNLOCKED(pll_dcsb.lock),
+};
+
+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,
+ .lock = __SPIN_LOCK_UNLOCKED(pll_gpu.lock),
+};
+
+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,
+ .lock = __SPIN_LOCK_UNLOCKED(pll_npu.lock),
+};
+
+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,
+ .lock = __SPIN_LOCK_UNLOCKED(pll_ve2.lock),
+};
+
+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,
+ .lock = __SPIN_LOCK_UNLOCKED(pll_hifi.lock),
+};
+
+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 * const 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 - 1] = 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 */ }
+};
+MODULE_DEVICE_TABLE(of, rtd1625_crt_match);
+
+static struct platform_driver rtd1625_crt_driver = {
+ .probe = rtd1625_crt_probe,
+ .driver = {
+ .name = "rtk-rtd1625-crt-clk",
+ .of_match_table = rtd1625_crt_match,
+ .suppress_bind_attrs = true,
+ },
+};
+
+static int __init rtd1625_crt_init(void)
+{
+ return platform_driver_register(&rtd1625_crt_driver);
+}
+subsys_initcall(rtd1625_crt_init);
+
+MODULE_DESCRIPTION("Realtek RTD1625 CRT Clock 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 bb6dd856a64a..b122e6334508 100644
--- a/drivers/reset/realtek/Kconfig
+++ b/drivers/reset/realtek/Kconfig
@@ -6,3 +6,14 @@ config RESET_RTK_COMMON
Realtek SoCs. It provides shared reset control operations
(assert, deassert, status) and a registration helper function
that other Realtek-specific reset drivers can use.
+
+config RESET_RTD1625
+ tristate "RTD1625 Reset Controller"
+ depends on ARCH_REALTEK || COMPILE_TEST
+ select RESET_RTK_COMMON
+ select AUXILIARY_BUS
+ help
+ This enables the reset controller driver for Realtek RTD1625 SoC.
+ The driver controls reset lines for various peripherals including
+ PCIe, SATA, HDMI, display, video encoder/decoder, USB, SD, audio,
+ and other subsystems.
diff --git a/drivers/reset/realtek/Makefile b/drivers/reset/realtek/Makefile
index b59a3f7f2453..65c29a12524d 100644
--- a/drivers/reset/realtek/Makefile
+++ b/drivers/reset/realtek/Makefile
@@ -1,2 +1,3 @@
# SPDX-License-Identifier: GPL-2.0-only
obj-$(CONFIG_RESET_RTK_COMMON) += common.o
+obj-$(CONFIG_RESET_RTD1625) += 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..9de0e9808f7c
--- /dev/null
+++ b/drivers/reset/realtek/reset-rtd1625-crt.c
@@ -0,0 +1,187 @@
+// 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 const 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;
+ data->rcdev.owner = THIS_MODULE;
+
+ 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_DESCRIPTION("Realtek RTD1625 CRT Reset Controller Driver");
+MODULE_LICENSE("GPL");
+MODULE_IMPORT_NS("REALTEK_RESET");
--
2.43.0
^ permalink raw reply related
* [PATCH v8 00/10] clk: realtek: Add RTD1625 clock support
From: Yu-Chun Lin @ 2026-06-10 8:08 UTC (permalink / raw)
To: mturquette, sboyd, robh, krzk+dt, conor+dt, p.zabel, cylee12,
afaerber, jyanchou
Cc: bmasney, 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 v8:
Patch 3:
- Add depends on RESET_CONTROLLER and select MFD_SYSCON for config
RTK_CLK_COMMON
- Fix error handling for devm_auxiliary_device_create()
Patch 4:
- Reduce the timeout value in regmap_read_poll_timeout_atomic() from 2000ms to
500ms to avoid prolonged busy-waiting and prevent triggering the NMI Watchdog
- Remove 'freq_ready_valid' and add comments to clarify that register offset 0
is never a valid address on Realtek SoCs, meaning it is not configured
- Add the missing spin_unlock_irqrestore() when regmap_read() fails
Patch 6:
- In clk_regmap_mux_get_parent(), return 0xff instead of 0 to properly indicate
an error
- In clk_regmap_mux_set_parent(), cast index to u32 to avoid signed integer
- overflow
Patch 7:
- Fix the mask shift in set_phrt0()
- For better safety and readability, modify pointer comparison for phase_id
- In clk_pll_mmc_recalc_rate(), return 0 instead of an error code upon failure
Patch 8 & 9:
- Remove the trailing NULL element ([RTD1625_XX_CLK_MAX] = NULL) from the
clk_hw_onecell_data arrays
- Add MODULE_DEVICE_TABLE(of, ...) for the tristate config
- Add '.suppress_bind_attrs = true', to avoid handling pointer problem, cause
clock should not allow to manually disable by users
- Fix a typo
Patch 10:
- Sort device nodes by unit address
v7: https://lore.kernel.org/lkml/20260508111641.3192177-1-eleanor.lin@realtek.com/
Cheng-Yu Lee (8):
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
clk: realtek: Add RTD1625-CRT clock controller driver
clk: realtek: Add RTD1625-ISO clock controller driver
Yu-Chun Lin (2):
dt-bindings: clock: Add Realtek RTD1625 Clock & Reset Controller
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 | 48 ++
drivers/clk/realtek/Makefile | 13 +
drivers/clk/realtek/clk-pll-mmc.c | 459 ++++++++++
drivers/clk/realtek/clk-pll.c | 209 +++++
drivers/clk/realtek/clk-pll.h | 60 ++
drivers/clk/realtek/clk-regmap-gate.c | 70 ++
drivers/clk/realtek/clk-regmap-gate.h | 65 ++
drivers/clk/realtek/clk-regmap-mux.c | 41 +
drivers/clk/realtek/clk-regmap-mux.h | 43 +
drivers/clk/realtek/clk-rtd1625-crt.c | 792 ++++++++++++++++++
drivers/clk/realtek/clk-rtd1625-iso.c | 151 ++++
drivers/clk/realtek/common.c | 66 ++
drivers/clk/realtek/common.h | 37 +
drivers/clk/realtek/freq_table.c | 38 +
drivers/clk/realtek/freq_table.h | 16 +
drivers/reset/Kconfig | 1 +
drivers/reset/Makefile | 1 +
drivers/reset/realtek/Kconfig | 19 +
drivers/reset/realtek/Makefile | 3 +
drivers/reset/realtek/common.c | 90 ++
drivers/reset/realtek/common.h | 29 +
drivers/reset/realtek/reset-rtd1625-crt.c | 187 +++++
drivers/reset/realtek/reset-rtd1625-iso.c | 99 +++
.../dt-bindings/clock/realtek,rtd1625-clk.h | 164 ++++
include/dt-bindings/reset/realtek,rtd1625.h | 171 ++++
30 files changed, 2985 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.43.0
^ permalink raw reply
* [PATCH v8 10/10] arm64: dts: realtek: Add clock support for RTD1625
From: Yu-Chun Lin @ 2026-06-10 8:08 UTC (permalink / raw)
To: mturquette, sboyd, robh, krzk+dt, conor+dt, p.zabel, cylee12,
afaerber, jyanchou
Cc: bmasney, devicetree, linux-clk, linux-kernel, linux-arm-kernel,
linux-realtek-soc, james.tai, cy.huang, stanley_chang,
eleanor.lin
In-Reply-To: <20260610080824.255063-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>
---
Changes in v8:
- Sort device nodes by unit address.
---
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..69f28cb35585 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,22 @@ 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>;
+ };
+
+ ic: clock-controller@7088 {
+ compatible = "realtek,rtd1625-iso-clk";
+ reg = <0x7088 0x8>;
+ clocks = <&osc27m>;
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+ };
+
uart0: serial@7800 {
compatible = "snps,dw-apb-uart";
reg = <0x7800 0x100>;
@@ -150,6 +175,14 @@ uart0: serial@7800 {
reg-shift = <2>;
status = "disabled";
};
+
+ 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.43.0
^ permalink raw reply related
* Re: [PATCH v6 04/20] dma-pool: track decrypted atomic pools and select them via attrs
From: Aneesh Kumar K.V @ 2026-06-10 8:07 UTC (permalink / raw)
To: Jason Gunthorpe
Cc: iommu, linux-arm-kernel, linux-kernel, linux-coco, Robin Murphy,
Marek Szyprowski, Will Deacon, Marc Zyngier, Steven Price,
Suzuki K Poulose, Catalin Marinas, Jiri Pirko, Mostafa Saleh,
Petr Tesarik, Alexey Kardashevskiy, Dan Williams, Xu Yilun,
linuxppc-dev, linux-s390, Madhavan Srinivasan, Michael Ellerman,
Nicholas Piggin, Christophe Leroy (CS GROUP), Alexander Gordeev,
Gerald Schaefer, Heiko Carstens, Vasily Gorbik,
Christian Borntraeger, Sven Schnelle, x86, Jiri Pirko,
Michael Kelley
In-Reply-To: <20260609143242.GK2764304@ziepe.ca>
Jason Gunthorpe <jgg@ziepe.ca> writes:
> On Thu, Jun 04, 2026 at 02:09:43PM +0530, Aneesh Kumar K.V (Arm) wrote:
>> struct page *dma_alloc_from_pool(struct device *dev, size_t size,
>> - void **cpu_addr, gfp_t gfp,
>> + void **cpu_addr, gfp_t gfp, unsigned long attrs,
>> bool (*phys_addr_ok)(struct device *, phys_addr_t, size_t))
>> {
>> - struct gen_pool *pool = NULL;
>> + struct dma_gen_pool *dma_pool = NULL;
>> struct page *page;
>> bool pool_found = false;
>>
>> - while ((pool = dma_guess_pool(pool, gfp))) {
>> + while ((dma_pool = dma_guess_pool(dma_pool, gfp))) {
>> +
>> + if (dma_pool->unencrypted != !!(attrs & DMA_ATTR_CC_SHARED))
>> + continue;
>
> I don't think you should be overloading DMA_ATTR_CC_SHARED like this.
>
> /*
> * DMA_ATTR_CC_SHARED is not a caller-visible dma_alloc_*()
> * attribute. The direct allocator uses it internally after it has
> * decided that the backing pages must be shared/decrypted, so the
> * rest of the allocation path can consistently select DMA addresses,
> * choose compatible pools and restore encryption on free.
> */
> if (attrs & DMA_ATTR_CC_SHARED)
> return NULL;
>
> if (force_dma_unencrypted(dev)) {
> attrs |= DMA_ATTR_CC_SHARED;
> mark_mem_decrypt = true;
> }
>
> It is fine to have a bit inside the attrs that is only used by the
> internal logic, but it needs to have a clearer name
> __DMA_ATTR_REQUIRE_CC_SHARED perhaps.
>
Are you suggesting adding another attribute in addition to
DMA_ATTR_CC_SHARED?
Is the idea that __DMA_ATTR_REQUIRE_CC_SHARED would be used in the
allocation path to request a CC_SHARED allocation, while
DMA_ATTR_CC_SHARED would be used in the mapping path to describe the
attribute of the address?
>
> The sashiko note does look legit though:
>
> if (IS_ENABLED(CONFIG_DMA_DIRECT_REMAP) &&
> !gfpflags_allow_blocking(gfp) && !coherent) {
> page = dma_alloc_from_pool(dev, PAGE_ALIGN(size), &cpu_addr,
> gfp, attrs, NULL);
> if (!page)
> return NULL;
>
> I don't see anything doing the force_dma_unencrypted test along this
> callchain..
>
> I guess it should be done one step up in dma_alloc_attrs() instead of
> in dma_direct_alloc()?
>
Yes, I'll move it there.
-aneesh
^ permalink raw reply
* Re: [PATCH v2 1/4] dt-bindings: remoteproc: imx_rproc: document optional "memory-region-names"
From: Krzysztof Kozlowski @ 2026-06-10 7:37 UTC (permalink / raw)
To: Laurentiu Mihalcea
Cc: Bjorn Andersson, Mathieu Poirier, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Sascha Hauer, Peng Fan,
Fabio Estevam, Daniel Baluta, Francesco Dolcini, linux-remoteproc,
devicetree, imx, linux-arm-kernel, linux-kernel
In-Reply-To: <20260605113621.1479-2-laurentiumihalcea111@gmail.com>
On Fri, Jun 05, 2026 at 04:36:18AM -0700, Laurentiu Mihalcea wrote:
> From: Laurentiu Mihalcea <laurentiu.mihalcea@nxp.com>
>
> The names of the carveout regions are derived using the names of the
> reserved memory devicetree nodes, which are referenced using the
> "memory-region" property. This adds a restriction on the names of said
> devicetree nodes, often bearing specific names such as: "vdevbuffer",
> "vdev0vring0", "rsc-table", etc... This goes against the devicetree
> specification's recommendation, which states that the devicetree node
> names should be generic.
No, it does not. Names like rsc-table feels exactly like DT spec is
asking - for a name matching purpose. Are you sure you read the spec?
>
> Fix this by documenting an additional, optional property:
> "memory-region-names". This way, the carveout names can use the values
> passed via "memory-region-names", while keeping the devicetree node
> names of the reserved memory regions generic.
I don't see how anything here is fixed. memory-region-names has nothing
to do with node names.
Best regards,
Krzysztof
^ permalink raw reply
* [PATCH v3 5/5] arm64: dts: cix: sky1: add audss system control
From: joakim.zhang @ 2026-06-10 7:56 UTC (permalink / raw)
To: mturquette, sboyd, bmasney, robh, krzk+dt, conor+dt, p.zabel,
gary.yang
Cc: cix-kernel-upstream, linux-clk, devicetree, linux-kernel,
linux-arm-kernel, Joakim Zhang
In-Reply-To: <20260610075645.3581145-1-joakim.zhang@cixtech.com>
From: Joakim Zhang <joakim.zhang@cixtech.com>
Add audss system control device node, which would provides
clocks and resets for devices in audss domain.
Signed-off-by: Joakim Zhang <joakim.zhang@cixtech.com>
---
arch/arm64/boot/dts/cix/sky1.dtsi | 24 ++++++++++++++++++++++++
1 file changed, 24 insertions(+)
diff --git a/arch/arm64/boot/dts/cix/sky1.dtsi b/arch/arm64/boot/dts/cix/sky1.dtsi
index bb5cfb1f2113..368a1d85c93d 100644
--- a/arch/arm64/boot/dts/cix/sky1.dtsi
+++ b/arch/arm64/boot/dts/cix/sky1.dtsi
@@ -6,6 +6,10 @@
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/clock/cix,sky1.h>
+#include <dt-bindings/clock/cix,sky1-audss.h>
+#include <dt-bindings/reset/cix,sky1-system-control.h>
+#include <dt-bindings/reset/cix,sky1-s5-system-control.h>
+#include <dt-bindings/reset/cix,sky1-audss-system-control.h>
#include "sky1-power.h"
/ {
@@ -488,6 +492,26 @@ mbox_pm2ap: mailbox@65a0080 {
cix,mbox-dir = "rx";
};
+ audss_cru: system-controller@7110000 {
+ compatible = "cix,sky1-audss-system-control", "simple-mfd", "syscon";
+ reg = <0x0 0x07110000 0x0 0x10000>;
+ #reset-cells = <1>;
+ status = "okay";
+
+ audss_clk: clock-controller {
+ compatible = "cix,sky1-audss-clock";
+ power-domains = <&smc_devpd SKY1_PD_AUDIO>;
+ resets = <&s5_syscon SKY1_AUDIO_HIFI5_NOC_RESET_N>;
+ clocks = <&scmi_clk CLK_TREE_AUDIO_CLK0>,
+ <&scmi_clk CLK_TREE_AUDIO_CLK2>,
+ <&scmi_clk CLK_TREE_AUDIO_CLK4>,
+ <&scmi_clk CLK_TREE_AUDIO_CLK5>;
+ clock-names = "x8k", "x11k", "sys", "48m";
+ #clock-cells = <1>;
+ status = "okay";
+ };
+ };
+
mbox_sfh2ap: mailbox@8090000 {
compatible = "cix,sky1-mbox";
reg = <0x0 0x08090000 0x0 0x10000>;
--
2.50.1
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox