* RE: Re: [PATCH v2 1/2] dt-bindings: gpu: mali-valhall-csf: Document i.MX952 support
From: Guangliu Ding @ 2026-04-02 7:48 UTC (permalink / raw)
To: Krzysztof Kozlowski
Cc: Daniel Almeida, Alice Ryhl, Boris Brezillon, Steven Price,
Liviu Dudau, David Airlie, Simona Vetter, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Frank Li, Sascha Hauer,
Pengutronix Kernel Team, Fabio Estevam,
dri-devel@lists.freedesktop.org, devicetree@vger.kernel.org,
linux-kernel@vger.kernel.org, imx@lists.linux.dev,
linux-arm-kernel@lists.infradead.org
In-Reply-To: <20260402-axiomatic-ludicrous-panther-7a96d2@quoll>
> On Wed, Apr 01, 2026 at 06:19:12PM +0800, Guangliu Ding wrote:
> > The GPU instance used on NXP i.MX952 is the Mali‑G310, document
> > support for this variant.
> >
> > A hardware GPU auto clock‑gating mechanism has been introduced,
> > enabling GPUMIX to automatically manage the GPU clock. This improves
> > overall response time.
> >
> > Signed-off-by: Guangliu Ding <guangliu.ding@nxp.com>
> > ---
> > Documentation/devicetree/bindings/gpu/arm,mali-valhall-csf.yaml | 1 +
> > 1 file changed, 1 insertion(+)
>
> Why are you sending next version when the discussion is happening?
>
I will drop this thread and raise v3 version with final fix. Sorry for inconvenience.
> Best regards,
> Krzysztof
^ permalink raw reply
* [PATCH v4 1/2] dmaengine: xilinx_dma: Fix CPU stall in xilinx_dma_poll_timeout
From: Alex Bereza @ 2026-04-02 7:46 UTC (permalink / raw)
To: Vinod Koul, Frank Li, Michal Simek, Geert Uytterhoeven,
Ulf Hansson, Arnd Bergmann, Tony Lindgren, Kedareswara rao Appana
Cc: dmaengine, linux-arm-kernel, linux-kernel, Alex Bereza,
Suraj Gupta, Frank Li
In-Reply-To: <20260402-fix-atomic-poll-timeout-regression-v4-0-f30d6a6c13cb@bereza.email>
Currently when calling xilinx_dma_poll_timeout with delay_us=0 and a
condition that is never fulfilled, the CPU busy-waits for prolonged time
and the timeout triggers only with a massive delay causing a CPU stall.
This happens due to a huge underestimation of wall clock time in
poll_timeout_us_atomic. Commit 7349a69cf312 ("iopoll: Do not use
timekeeping in read_poll_timeout_atomic()") changed the behavior to no
longer use ktime_get at the expense of underestimation of wall clock
time which appears to be very large for delay_us=0. Instead of timing
out after approximately XILINX_DMA_LOOP_COUNT microseconds, the timeout
takes XILINX_DMA_LOOP_COUNT * 1000 * (time that the overhead of the for
loop in poll_timeout_us_atomic takes) which is in the range of several
minutes for XILINX_DMA_LOOP_COUNT=1000000. Fix this by using a non-zero
value for delay_us. Use delay_us=10 to keep the delay in the hot path of
starting DMA transfers minimal but still avoid CPU stalls in case of
unexpected hardware failures.
One-off measurement with delay_us=0 causes the cpu to busy wait around 7
minutes in the timeout case. After applying this patch with delay_us=10
the measured timeout was 1053428 microseconds which is roughly
equivalent to the expected 1000000 microseconds specified in
XILINX_DMA_LOOP_COUNT.
Add a constant XILINX_DMA_POLL_DELAY_US for delay_us value.
Fixes: 9495f2648287 ("dmaengine: xilinx_vdma: Use readl_poll_timeout instead of do while loop's")
Fixes: 7349a69cf312 ("iopoll: Do not use timekeeping in read_poll_timeout_atomic()")
Reviewed-by: Suraj Gupta <suraj.gupta2@amd.com>
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Signed-off-by: Alex Bereza <alex@bereza.email>
---
drivers/dma/xilinx/xilinx_dma.c | 14 ++++++++++----
1 file changed, 10 insertions(+), 4 deletions(-)
diff --git a/drivers/dma/xilinx/xilinx_dma.c b/drivers/dma/xilinx/xilinx_dma.c
index 02a05f215614..345a738bab2c 100644
--- a/drivers/dma/xilinx/xilinx_dma.c
+++ b/drivers/dma/xilinx/xilinx_dma.c
@@ -167,6 +167,8 @@
/* Delay loop counter to prevent hardware failure */
#define XILINX_DMA_LOOP_COUNT 1000000
+/* Delay between polls (avoid a delay of 0 to prevent CPU stalls) */
+#define XILINX_DMA_POLL_DELAY_US 10
/* AXI DMA Specific Registers/Offsets */
#define XILINX_DMA_REG_SRCDSTADDR 0x18
@@ -1332,7 +1334,8 @@ static int xilinx_dma_stop_transfer(struct xilinx_dma_chan *chan)
/* Wait for the hardware to halt */
return xilinx_dma_poll_timeout(chan, XILINX_DMA_REG_DMASR, val,
- val & XILINX_DMA_DMASR_HALTED, 0,
+ val & XILINX_DMA_DMASR_HALTED,
+ XILINX_DMA_POLL_DELAY_US,
XILINX_DMA_LOOP_COUNT);
}
@@ -1347,7 +1350,8 @@ static int xilinx_cdma_stop_transfer(struct xilinx_dma_chan *chan)
u32 val;
return xilinx_dma_poll_timeout(chan, XILINX_DMA_REG_DMASR, val,
- val & XILINX_DMA_DMASR_IDLE, 0,
+ val & XILINX_DMA_DMASR_IDLE,
+ XILINX_DMA_POLL_DELAY_US,
XILINX_DMA_LOOP_COUNT);
}
@@ -1364,7 +1368,8 @@ static void xilinx_dma_start(struct xilinx_dma_chan *chan)
/* Wait for the hardware to start */
err = xilinx_dma_poll_timeout(chan, XILINX_DMA_REG_DMASR, val,
- !(val & XILINX_DMA_DMASR_HALTED), 0,
+ !(val & XILINX_DMA_DMASR_HALTED),
+ XILINX_DMA_POLL_DELAY_US,
XILINX_DMA_LOOP_COUNT);
if (err) {
@@ -1780,7 +1785,8 @@ static int xilinx_dma_reset(struct xilinx_dma_chan *chan)
/* Wait for the hardware to finish reset */
err = xilinx_dma_poll_timeout(chan, XILINX_DMA_REG_DMACR, tmp,
- !(tmp & XILINX_DMA_DMACR_RESET), 0,
+ !(tmp & XILINX_DMA_DMACR_RESET),
+ XILINX_DMA_POLL_DELAY_US,
XILINX_DMA_LOOP_COUNT);
if (err) {
--
2.53.0
^ permalink raw reply related
* Re: [PATCH v2 1/2] dt-bindings: rng: mtk-rng: add SMC-based TRNG variants
From: Krzysztof Kozlowski @ 2026-04-02 7:57 UTC (permalink / raw)
To: Daniel Golle
Cc: Olivia Mackall, Herbert Xu, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Matthias Brugger, AngeloGioacchino Del Regno,
Sean Wang, linux-crypto, devicetree, linux-kernel,
linux-arm-kernel, linux-mediatek
In-Reply-To: <0a951e34b7030e514091d6c0922c5982ae349221.1775090165.git.daniel@makrotopia.org>
On Thu, Apr 02, 2026 at 01:37:02AM +0100, Daniel Golle wrote:
> Add compatible strings for MediaTek SoCs where the hardware random number
> generator is accessed via a vendor-defined Secure Monitor Call (SMC)
> rather than direct MMIO register access:
>
> - mediatek,mt7981-rng
> - mediatek,mt7987-rng
> - mediatek,mt7988-rng
>
> These variants require no reg, clocks, or clock-names properties since
> the RNG hardware is managed by ARM Trusted Firmware-A.
>
> Relax the $nodename pattern to also allow 'rng' in addition to the
> existing 'rng@...' pattern.
>
> Add a second example showing the minimal SMC variant binding.
>
> Signed-off-by: Daniel Golle <daniel@makrotopia.org>
> ---
> v2: express compatibilities with fallback
>
> .../devicetree/bindings/rng/mtk-rng.yaml | 28 ++++++++++++++++---
> 1 file changed, 24 insertions(+), 4 deletions(-)
>
> diff --git a/Documentation/devicetree/bindings/rng/mtk-rng.yaml b/Documentation/devicetree/bindings/rng/mtk-rng.yaml
> index 7e8dc62e5d3a6..34648b53d14c6 100644
> --- a/Documentation/devicetree/bindings/rng/mtk-rng.yaml
> +++ b/Documentation/devicetree/bindings/rng/mtk-rng.yaml
> @@ -11,12 +11,13 @@ maintainers:
>
> properties:
> $nodename:
> - pattern: "^rng@[0-9a-f]+$"
> + pattern: "^rng(@[0-9a-f]+)?$"
>
> compatible:
> oneOf:
> - enum:
> - mediatek,mt7623-rng
> + - mediatek,mt7981-rng
> - items:
> - enum:
> - mediatek,mt7622-rng
> @@ -25,6 +26,11 @@ properties:
> - mediatek,mt8365-rng
> - mediatek,mt8516-rng
> - const: mediatek,mt7623-rng
> + - items:
> + - enum:
> + - mediatek,mt7987-rng
> + - mediatek,mt7988-rng
> + - const: mediatek,mt7981-rng
>
> reg:
> maxItems: 1
> @@ -38,9 +44,19 @@ properties:
>
> required:
> - compatible
> - - reg
> - - clocks
> - - clock-names
> +
> +allOf:
> + - if:
> + properties:
> + compatible:
> + not:
As requested last time - drop
> + contains:
> + const: mediatek,mt7981-rng
> + then:
missing constraints for mediatek,mt7981-rng. So does it have IO space
and clocks or not?
> + required:
> + - reg
> + - clocks
> + - clock-names
>
> additionalProperties: false
>
> @@ -53,3 +69,7 @@ examples:
> clocks = <&infracfg CLK_INFRA_TRNG>;
> clock-names = "rng";
> };
> + - |
> + rng {
> + compatible = "mediatek,mt7981-rng";
No improvements.
Also, make the example complete since binding claims you have clocks and
reg.
I am not sure it should be even same file, but if you are making it same
file, then make it correct.
Best regards,
Krzysztof
^ permalink raw reply
* Re: [PATCH v2 3/3] arm64: dts: exynos850: Add ap2apm mailbox
From: Krzysztof Kozlowski @ 2026-04-02 8:01 UTC (permalink / raw)
To: Alexey Klimov
Cc: Sylwester Nawrocki, Chanwoo Choi, Alim Akhtar, Sam Protsenko,
Michael Turquette, Stephen Boyd, Rob Herring, Conor Dooley,
Tudor Ambarus, Jassi Brar, Krzysztof Kozlowski, Peter Griffin,
linux-samsung-soc, linux-arm-kernel, linux-clk, devicetree,
linux-kernel
In-Reply-To: <20260402-exynos850-ap2apm-mailbox-v2-3-ca5ffdff99d4@linaro.org>
On Thu, Apr 02, 2026 at 03:20:16AM +0100, Alexey Klimov wrote:
> Add mailbox node that describes AP-to-APM mailbox, that can be
> used for communicating with APM co-processor on Exynos850 SoCs.
>
> Signed-off-by: Alexey Klimov <alexey.klimov@linaro.org>
> ---
> arch/arm64/boot/dts/exynos/exynos850.dtsi | 9 +++++++++
What DTS is doing in the middle of the patchset? If there is going to be
resend, then fix the order. If the order is intended, then most likely
NAK but I need somewhere explanation (but I really do not see the need
for it).
Please read submitting patches (both documents).
Best regards,
Krzysztof
^ permalink raw reply
* [PATCH] arm64: dts: imx{91,93}-phyboard-segin: Add peb-av-18 overlay
From: Florijan Plohl @ 2026-04-02 7:08 UTC (permalink / raw)
To: Frank Li, Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam,
Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: imx, linux-arm-kernel, devicetree, linux-kernel, upstream
Add overlay for the PEB-AV-18 adapter on phyBOARD-Segin-i.MX91/93.
The supported LCD is Powertip PH800480T032-ZHC19 panel (AC220).
Signed-off-by: Florijan Plohl <florijan.plohl@norik.com>
---
arch/arm64/boot/dts/freescale/Makefile | 4 +
.../imx91-phyboard-segin-peb-av-18.dtso | 142 ++++++++++++++++++
.../imx93-phyboard-segin-peb-av-18.dtso | 142 ++++++++++++++++++
3 files changed, 288 insertions(+)
create mode 100644 arch/arm64/boot/dts/freescale/imx91-phyboard-segin-peb-av-18.dtso
create mode 100644 arch/arm64/boot/dts/freescale/imx93-phyboard-segin-peb-av-18.dtso
diff --git a/arch/arm64/boot/dts/freescale/Makefile b/arch/arm64/boot/dts/freescale/Makefile
index bae24b53bce6..8f5b3996b678 100644
--- a/arch/arm64/boot/dts/freescale/Makefile
+++ b/arch/arm64/boot/dts/freescale/Makefile
@@ -437,17 +437,21 @@ dtb-$(CONFIG_ARCH_MXC) += imx93-kontron-bl-osm-s.dtb
dtb-$(CONFIG_ARCH_MXC) += imx93-phyboard-nash.dtb
dtb-$(CONFIG_ARCH_MXC) += imx93-phyboard-segin.dtb
+imx91-phyboard-segin-peb-av-18-dtbs += imx91-phyboard-segin.dtb imx91-phyboard-segin-peb-av-18.dtbo
imx93-phyboard-nash-jtag-dtbs += imx93-phyboard-nash.dtb imx93-phyboard-nash-jtag.dtbo
imx93-phyboard-nash-peb-wlbt-07-dtbs += imx93-phyboard-nash.dtb imx93-phyboard-nash-peb-wlbt-07.dtbo
imx93-phyboard-nash-pwm-fan-dtbs += imx93-phyboard-nash.dtb imx93-phyboard-nash-pwm-fan.dtbo
imx93-phyboard-segin-peb-av-02-dtbs += imx93-phyboard-segin.dtb imx93-phyboard-segin-peb-av-02.dtbo
+imx93-phyboard-segin-peb-av-18-dtbs += imx93-phyboard-segin.dtb imx93-phyboard-segin-peb-av-18.dtbo
imx93-phyboard-segin-peb-eval-01-dtbs += imx93-phyboard-segin.dtb imx93-phyboard-segin-peb-eval-01.dtbo
imx93-phyboard-segin-peb-wlbt-05-dtbs += imx93-phyboard-segin.dtb imx93-phyboard-segin-peb-wlbt-05.dtbo
imx93-phycore-rpmsg-dtbs += imx93-phyboard-nash.dtb imx93-phyboard-segin.dtb imx93-phycore-rpmsg.dtbo
+dtb-$(CONFIG_ARCH_MXC) += imx91-phyboard-segin-peb-av-18.dtb
dtb-$(CONFIG_ARCH_MXC) += imx93-phyboard-nash-jtag.dtb
dtb-$(CONFIG_ARCH_MXC) += imx93-phyboard-nash-peb-wlbt-07.dtb
dtb-$(CONFIG_ARCH_MXC) += imx93-phyboard-nash-pwm-fan.dtb
dtb-$(CONFIG_ARCH_MXC) += imx93-phyboard-segin-peb-av-02.dtb
+dtb-$(CONFIG_ARCH_MXC) += imx93-phyboard-segin-peb-av-18.dtb
dtb-$(CONFIG_ARCH_MXC) += imx93-phyboard-segin-peb-eval-01.dtb
dtb-$(CONFIG_ARCH_MXC) += imx93-phyboard-segin-peb-wlbt-05.dtb
dtb-$(CONFIG_ARCH_MXC) += imx93-phycore-rpmsg.dtb
diff --git a/arch/arm64/boot/dts/freescale/imx91-phyboard-segin-peb-av-18.dtso b/arch/arm64/boot/dts/freescale/imx91-phyboard-segin-peb-av-18.dtso
new file mode 100644
index 000000000000..ec6ef2e5a11a
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx91-phyboard-segin-peb-av-18.dtso
@@ -0,0 +1,142 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (C) 2026 PHYTEC Messtechnik GmbH
+ *
+ * Author: Florijan Plohl <florijan.plohl@norik.com>
+ */
+
+#include <dt-bindings/clock/imx93-clock.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include "imx91-pinfunc.h"
+
+/dts-v1/;
+/plugin/;
+
+&{/} {
+ backlight: backlight {
+ compatible = "pwm-backlight";
+ brightness-levels = <0 4 8 16 32 64 128 255>;
+ default-brightness-level = <5>;
+ power-supply = <®_vcc_3v3_con>;
+ pwms = <&pwm7 0 5000000 0>;
+ };
+
+ panel {
+ compatible = "powertip,ph800480t032-zhc19";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_panel>;
+
+ backlight = <&backlight>;
+ enable-gpios = <&gpio4 29 GPIO_ACTIVE_HIGH>;
+ power-supply = <®_vcc_3v3_con>;
+
+ port {
+ panel_in: endpoint {
+ remote-endpoint = <&dpi_to_panel>;
+ };
+ };
+ };
+
+ pwm7: pwm-7 {
+ compatible = "pwm-gpio";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pwm7>;
+ gpios = <&gpio4 28 GPIO_ACTIVE_HIGH>;
+ #pwm-cells = <3>;
+ };
+
+ reg_vcc_3v3_con: regulator-vcc-3v3-con {
+ compatible = "regulator-fixed";
+ regulator-name = "VCC3V3_CON";
+ regulator-max-microvolt = <3300000>;
+ regulator-min-microvolt = <3300000>;
+ };
+};
+
+&dpi_bridge {
+ status = "okay";
+};
+
+&dpi_to_panel {
+ remote-endpoint = <&panel_in>;
+ bus-width = <18>;
+};
+
+&lcdif {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lcdif>;
+ assigned-clocks = <&clk IMX93_CLK_VIDEO_PLL>;
+ assigned-clock-rates = <27272728>;
+ status = "okay";
+};
+
+&lpi2c2 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ touchscreen@41 {
+ compatible = "ilitek,ili2130";
+ reg = <0x41>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_touchscreen>;
+ interrupt-parent = <&gpio4>;
+ interrupts = <12 IRQ_TYPE_EDGE_FALLING>;
+ reset-gpios = <&gpio4 1 GPIO_ACTIVE_LOW>;
+ touchscreen-size-x = <800>;
+ touchscreen-size-y = <480>;
+ wakeup-source;
+ };
+};
+
+&media_blk_ctrl {
+ status = "okay";
+};
+
+&iomuxc {
+ pinctrl_lcdif: lcdifgrp {
+ fsl,pins = <
+ MX91_PAD_GPIO_IO00__MEDIAMIX_DISP_CLK 0x50e
+ MX91_PAD_GPIO_IO01__MEDIAMIX_DISP_DE 0x50e
+ MX91_PAD_GPIO_IO02__MEDIAMIX_DISP_VSYNC 0x50e
+ MX91_PAD_GPIO_IO03__MEDIAMIX_DISP_HSYNC 0x50e
+ MX91_PAD_GPIO_IO04__MEDIAMIX_DISP_DATA0 0x50e
+ MX91_PAD_GPIO_IO05__MEDIAMIX_DISP_DATA1 0x50e
+ MX91_PAD_GPIO_IO06__MEDIAMIX_DISP_DATA2 0x50e
+ MX91_PAD_GPIO_IO07__MEDIAMIX_DISP_DATA3 0x50e
+ MX91_PAD_GPIO_IO08__MEDIAMIX_DISP_DATA4 0x50e
+ MX91_PAD_GPIO_IO09__MEDIAMIX_DISP_DATA5 0x51e
+ MX91_PAD_GPIO_IO10__MEDIAMIX_DISP_DATA6 0x50e
+ MX91_PAD_GPIO_IO11__MEDIAMIX_DISP_DATA7 0x50e
+ MX91_PAD_GPIO_IO12__MEDIAMIX_DISP_DATA8 0x50e
+ MX91_PAD_GPIO_IO13__MEDIAMIX_DISP_DATA9 0x50e
+ MX91_PAD_GPIO_IO14__MEDIAMIX_DISP_DATA10 0x50e
+ MX91_PAD_GPIO_IO15__MEDIAMIX_DISP_DATA11 0x50e
+ MX91_PAD_GPIO_IO16__MEDIAMIX_DISP_DATA12 0x506
+ MX91_PAD_GPIO_IO17__MEDIAMIX_DISP_DATA13 0x506
+ MX91_PAD_GPIO_IO18__MEDIAMIX_DISP_DATA14 0x506
+ MX91_PAD_GPIO_IO19__MEDIAMIX_DISP_DATA15 0x506
+ MX91_PAD_GPIO_IO20__MEDIAMIX_DISP_DATA16 0x506
+ MX91_PAD_GPIO_IO21__MEDIAMIX_DISP_DATA17 0x506
+ >;
+ };
+
+ pinctrl_panel: panelgrp {
+ fsl,pins = <
+ MX91_PAD_CCM_CLKO4__GPIO4_IO29 0x1133e
+ >;
+ };
+
+ pinctrl_pwm7: pwm7grp {
+ fsl,pins = <
+ MX91_PAD_CCM_CLKO3__GPIO4_IO28 0x1133e
+ >;
+ };
+
+ pinctrl_touchscreen: touchscreengrp {
+ fsl,pins = <
+ MX91_PAD_ENET1_MDIO__GPIO4_IO1 0x11e
+ MX91_PAD_ENET1_RD2__GPIO4_IO12 0x1133e
+ >;
+ };
+};
diff --git a/arch/arm64/boot/dts/freescale/imx93-phyboard-segin-peb-av-18.dtso b/arch/arm64/boot/dts/freescale/imx93-phyboard-segin-peb-av-18.dtso
new file mode 100644
index 000000000000..189b0f0472d2
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx93-phyboard-segin-peb-av-18.dtso
@@ -0,0 +1,142 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (C) 2026 PHYTEC Messtechnik GmbH
+ *
+ * Author: Florijan Plohl <florijan.plohl@norik.com>
+ */
+
+#include <dt-bindings/clock/imx93-clock.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include "imx93-pinfunc.h"
+
+/dts-v1/;
+/plugin/;
+
+&{/} {
+ backlight: backlight {
+ compatible = "pwm-backlight";
+ brightness-levels = <0 4 8 16 32 64 128 255>;
+ default-brightness-level = <5>;
+ power-supply = <®_vcc_3v3_con>;
+ pwms = <&pwm7 0 5000000 0>;
+ };
+
+ panel {
+ compatible = "powertip,ph800480t032-zhc19";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_panel>;
+
+ backlight = <&backlight>;
+ enable-gpios = <&gpio4 29 GPIO_ACTIVE_HIGH>;
+ power-supply = <®_vcc_3v3_con>;
+
+ port {
+ panel_in: endpoint {
+ remote-endpoint = <&dpi_to_panel>;
+ };
+ };
+ };
+
+ pwm7: pwm-7 {
+ compatible = "pwm-gpio";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pwm7>;
+ gpios = <&gpio4 28 GPIO_ACTIVE_HIGH>;
+ #pwm-cells = <3>;
+ };
+
+ reg_vcc_3v3_con: regulator-vcc-3v3-con {
+ compatible = "regulator-fixed";
+ regulator-name = "VCC3V3_CON";
+ regulator-max-microvolt = <3300000>;
+ regulator-min-microvolt = <3300000>;
+ };
+};
+
+&dpi_bridge {
+ status = "okay";
+};
+
+&dpi_to_panel {
+ remote-endpoint = <&panel_in>;
+ bus-width = <18>;
+};
+
+&lcdif {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lcdif>;
+ assigned-clocks = <&clk IMX93_CLK_VIDEO_PLL>;
+ assigned-clock-rates = <27272728>;
+ status = "okay";
+};
+
+&lpi2c2 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ touchscreen@41 {
+ compatible = "ilitek,ili2130";
+ reg = <0x41>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_touchscreen>;
+ interrupt-parent = <&gpio4>;
+ interrupts = <12 IRQ_TYPE_EDGE_FALLING>;
+ reset-gpios = <&gpio4 1 GPIO_ACTIVE_LOW>;
+ touchscreen-size-x = <800>;
+ touchscreen-size-y = <480>;
+ wakeup-source;
+ };
+};
+
+&media_blk_ctrl {
+ status = "okay";
+};
+
+&iomuxc {
+ pinctrl_lcdif: lcdifgrp {
+ fsl,pins = <
+ MX93_PAD_GPIO_IO00__MEDIAMIX_DISP_CLK 0x50e
+ MX93_PAD_GPIO_IO01__MEDIAMIX_DISP_DE 0x50e
+ MX93_PAD_GPIO_IO02__MEDIAMIX_DISP_VSYNC 0x50e
+ MX93_PAD_GPIO_IO03__MEDIAMIX_DISP_HSYNC 0x50e
+ MX93_PAD_GPIO_IO04__MEDIAMIX_DISP_DATA00 0x50e
+ MX93_PAD_GPIO_IO05__MEDIAMIX_DISP_DATA01 0x50e
+ MX93_PAD_GPIO_IO06__MEDIAMIX_DISP_DATA02 0x50e
+ MX93_PAD_GPIO_IO07__MEDIAMIX_DISP_DATA03 0x50e
+ MX93_PAD_GPIO_IO08__MEDIAMIX_DISP_DATA04 0x50e
+ MX93_PAD_GPIO_IO09__MEDIAMIX_DISP_DATA05 0x51e
+ MX93_PAD_GPIO_IO10__MEDIAMIX_DISP_DATA06 0x50e
+ MX93_PAD_GPIO_IO11__MEDIAMIX_DISP_DATA07 0x50e
+ MX93_PAD_GPIO_IO12__MEDIAMIX_DISP_DATA08 0x50e
+ MX93_PAD_GPIO_IO13__MEDIAMIX_DISP_DATA09 0x50e
+ MX93_PAD_GPIO_IO14__MEDIAMIX_DISP_DATA10 0x50e
+ MX93_PAD_GPIO_IO15__MEDIAMIX_DISP_DATA11 0x50e
+ MX93_PAD_GPIO_IO16__MEDIAMIX_DISP_DATA12 0x506
+ MX93_PAD_GPIO_IO17__MEDIAMIX_DISP_DATA13 0x506
+ MX93_PAD_GPIO_IO18__MEDIAMIX_DISP_DATA14 0x506
+ MX93_PAD_GPIO_IO19__MEDIAMIX_DISP_DATA15 0x506
+ MX93_PAD_GPIO_IO20__MEDIAMIX_DISP_DATA16 0x506
+ MX93_PAD_GPIO_IO21__MEDIAMIX_DISP_DATA17 0x506
+ >;
+ };
+
+ pinctrl_panel: panelgrp {
+ fsl,pins = <
+ MX93_PAD_CCM_CLKO4__GPIO4_IO29 0x1133e
+ >;
+ };
+
+ pinctrl_pwm7: pwm7grp {
+ fsl,pins = <
+ MX93_PAD_CCM_CLKO3__GPIO4_IO28 0x1133e
+ >;
+ };
+
+ pinctrl_touchscreen: touchscreengrp {
+ fsl,pins = <
+ MX93_PAD_ENET1_MDIO__GPIO4_IO01 0x11e
+ MX93_PAD_ENET1_RD2__GPIO4_IO12 0x1133e
+ >;
+ };
+};
--
2.43.0
^ permalink raw reply related
* Re: [PATCH v2 2/3] mailbox: exynos: Add support for Exynos850 mailbox
From: Krzysztof Kozlowski @ 2026-04-02 8:11 UTC (permalink / raw)
To: Alexey Klimov
Cc: Sylwester Nawrocki, Chanwoo Choi, Alim Akhtar, Sam Protsenko,
Michael Turquette, Stephen Boyd, Rob Herring, Conor Dooley,
Tudor Ambarus, Jassi Brar, Krzysztof Kozlowski, Peter Griffin,
linux-samsung-soc, linux-arm-kernel, linux-clk, devicetree,
linux-kernel
In-Reply-To: <20260402-exynos850-ap2apm-mailbox-v2-2-ca5ffdff99d4@linaro.org>
On Thu, Apr 02, 2026 at 03:20:15AM +0100, Alexey Klimov wrote:
> Exynos850-based platforms support ACPM and has similar workflow
> of communicating with ACPM via mailbox, however mailbox controller
> registers are located at different offsets and writes/reads could be
> different. To distinguish between such different behaviours,
> the registers offsets for Exynos850 and the platform-specific data
> structs are introduced and configuration is described in such structs
> for gs101 and exynos850 based SoCs. Probe routine now selects the
> corresponding platform-specific data via device_get_match_data().
>
> Signed-off-by: Alexey Klimov <alexey.klimov@linaro.org>
> ---
> drivers/mailbox/exynos-mailbox.c | 67 ++++++++++++++++++++++++++++++++++++++--
> 1 file changed, 64 insertions(+), 3 deletions(-)
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
Best regards,
Krzysztof
^ permalink raw reply
* [PATCH v6 10/10] arm64: dts: realtek: Add clock support for RTD1625
From: Yu-Chun Lin @ 2026-04-02 7:39 UTC (permalink / raw)
To: mturquette, sboyd, robh, krzk+dt, conor+dt, p.zabel, cylee12,
afaerber, jyanchou
Cc: devicetree, linux-clk, linux-kernel, linux-arm-kernel,
linux-realtek-soc, james.tai, cy.huang, stanley_chang,
eleanor.lin
In-Reply-To: <20260402073957.2742459-1-eleanor.lin@realtek.com>
Add the clock controller nodes and osc27m fixed clock for the
Realtek RTD1625 SoC.
Signed-off-by: Yu-Chun Lin <eleanor.lin@realtek.com>
---
arch/arm64/boot/dts/realtek/kent.dtsi | 33 +++++++++++++++++++++++++++
1 file changed, 33 insertions(+)
diff --git a/arch/arm64/boot/dts/realtek/kent.dtsi b/arch/arm64/boot/dts/realtek/kent.dtsi
index ae006ce24420..4722337a143d 100644
--- a/arch/arm64/boot/dts/realtek/kent.dtsi
+++ b/arch/arm64/boot/dts/realtek/kent.dtsi
@@ -26,6 +26,15 @@ timer {
<GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>;
};
+ clocks {
+ osc27m: osc {
+ compatible = "fixed-clock";
+ clock-frequency = <27000000>;
+ clock-output-names = "osc27m";
+ #clock-cells = <0>;
+ };
+ };
+
cpus {
#address-cells = <1>;
#size-cells = <0>;
@@ -141,6 +150,14 @@ rbus: bus@98000000 {
#address-cells = <1>;
#size-cells = <1>;
+ cc: clock-controller@0 {
+ compatible = "realtek,rtd1625-crt-clk";
+ reg = <0x0 0x900>;
+ clocks = <&osc27m>;
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+ };
+
uart0: serial@7800 {
compatible = "snps,dw-apb-uart";
reg = <0x7800 0x100>;
@@ -150,6 +167,22 @@ uart0: serial@7800 {
reg-shift = <2>;
status = "disabled";
};
+
+ ic: clock-controller@7088 {
+ compatible = "realtek,rtd1625-iso-clk";
+ reg = <0x7088 0x8>;
+ clocks = <&osc27m>;
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+ };
+
+ iso_s_cc: clock-controller@146310 {
+ compatible = "realtek,rtd1625-iso-s-clk";
+ reg = <0x146310 0x8>;
+ clocks = <&osc27m>;
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+ };
};
gic: interrupt-controller@ff100000 {
--
2.34.1
^ permalink raw reply related
* [PATCH v6 06/10] clk: realtek: Add support for mux clock
From: Yu-Chun Lin @ 2026-04-02 7:39 UTC (permalink / raw)
To: mturquette, sboyd, robh, krzk+dt, conor+dt, p.zabel, cylee12,
afaerber, jyanchou
Cc: devicetree, linux-clk, linux-kernel, linux-arm-kernel,
linux-realtek-soc, james.tai, cy.huang, stanley_chang,
eleanor.lin
In-Reply-To: <20260402073957.2742459-1-eleanor.lin@realtek.com>
From: Cheng-Yu Lee <cylee12@realtek.com>
Add a simple regmap-based clk_ops implementation for Realtek mux clocks.
The implementation supports parent selection and rate determination through
regmap-backed register access.
Signed-off-by: Cheng-Yu Lee <cylee12@realtek.com>
Co-developed-by: Yu-Chun Lin <eleanor.lin@realtek.com>
Signed-off-by: Yu-Chun Lin <eleanor.lin@realtek.com>
---
Changes in v6:
- Add the headers used in c file to follow the "Include What You Use" principle.
---
drivers/clk/realtek/Makefile | 1 +
drivers/clk/realtek/clk-regmap-mux.c | 48 ++++++++++++++++++++++++++++
drivers/clk/realtek/clk-regmap-mux.h | 43 +++++++++++++++++++++++++
3 files changed, 92 insertions(+)
create mode 100644 drivers/clk/realtek/clk-regmap-mux.c
create mode 100644 drivers/clk/realtek/clk-regmap-mux.h
diff --git a/drivers/clk/realtek/Makefile b/drivers/clk/realtek/Makefile
index 74375f8127ac..f90dc57fcfdb 100644
--- a/drivers/clk/realtek/Makefile
+++ b/drivers/clk/realtek/Makefile
@@ -5,4 +5,5 @@ clk-rtk-y += common.o
clk-rtk-y += clk-pll.o
clk-rtk-y += clk-regmap-gate.o
+clk-rtk-y += clk-regmap-mux.o
clk-rtk-y += freq_table.o
diff --git a/drivers/clk/realtek/clk-regmap-mux.c b/drivers/clk/realtek/clk-regmap-mux.c
new file mode 100644
index 000000000000..068b056d61f0
--- /dev/null
+++ b/drivers/clk/realtek/clk-regmap-mux.c
@@ -0,0 +1,48 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2017 Realtek Semiconductor Corporation
+ * Author: Cheng-Yu Lee <cylee12@realtek.com>
+ */
+
+#include <linux/regmap.h>
+#include <linux/clk-provider.h>
+#include "clk-regmap-mux.h"
+
+static u8 clk_regmap_mux_get_parent(struct clk_hw *hw)
+{
+ struct clk_regmap_mux *clkm = to_clk_regmap_mux(hw);
+ int num_parents = clk_hw_get_num_parents(hw);
+ u32 val;
+ int ret;
+
+ ret = regmap_read(clkm->clkr.regmap, clkm->mux_ofs, &val);
+ if (ret)
+ return 0;
+
+ val = val >> clkm->shift & clkm->mask;
+
+ if (val >= num_parents)
+ return 0;
+
+ return val;
+}
+
+static int clk_regmap_mux_set_parent(struct clk_hw *hw, u8 index)
+{
+ struct clk_regmap_mux *clkm = to_clk_regmap_mux(hw);
+
+ return regmap_update_bits(clkm->clkr.regmap, clkm->mux_ofs,
+ clkm->mask << clkm->shift, index << clkm->shift);
+}
+
+const struct clk_ops rtk_clk_regmap_mux_ops = {
+ .set_parent = clk_regmap_mux_set_parent,
+ .get_parent = clk_regmap_mux_get_parent,
+ .determine_rate = __clk_mux_determine_rate,
+};
+EXPORT_SYMBOL_NS_GPL(rtk_clk_regmap_mux_ops, "REALTEK_CLK");
+
+const struct clk_ops rtk_clk_regmap_mux_ro_ops = {
+ .get_parent = clk_regmap_mux_get_parent,
+};
+EXPORT_SYMBOL_NS_GPL(rtk_clk_regmap_mux_ro_ops, "REALTEK_CLK");
diff --git a/drivers/clk/realtek/clk-regmap-mux.h b/drivers/clk/realtek/clk-regmap-mux.h
new file mode 100644
index 000000000000..cf7ab6a0604c
--- /dev/null
+++ b/drivers/clk/realtek/clk-regmap-mux.h
@@ -0,0 +1,43 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2017 Realtek Semiconductor Corporation
+ * Author: Cheng-Yu Lee <cylee12@realtek.com>
+ */
+
+#ifndef __CLK_REALTEK_CLK_REGMAP_MUX_H
+#define __CLK_REALTEK_CLK_REGMAP_MUX_H
+
+#include "common.h"
+
+struct clk_regmap_mux {
+ struct clk_regmap clkr;
+ int mux_ofs;
+ unsigned int mask;
+ unsigned int shift;
+};
+
+#define __clk_regmap_mux_hw(_p) __clk_regmap_hw(&(_p)->clkr)
+
+#define __CLK_REGMAP_MUX(_name, _parents, _ops, _flags, _ofs, _sft, _mask) \
+ struct clk_regmap_mux _name = { \
+ .clkr.hw.init = \
+ CLK_HW_INIT_PARENTS(#_name, _parents, _ops, _flags), \
+ .mux_ofs = _ofs, \
+ .shift = _sft, \
+ .mask = _mask, \
+ }
+
+#define CLK_REGMAP_MUX(_name, _parents, _flags, _ofs, _sft, _mask) \
+ __CLK_REGMAP_MUX(_name, _parents, &rtk_clk_regmap_mux_ops, _flags, _ofs, \
+ _sft, _mask)
+
+static inline struct clk_regmap_mux *to_clk_regmap_mux(struct clk_hw *hw)
+{
+ struct clk_regmap *clkr = to_clk_regmap(hw);
+
+ return container_of(clkr, struct clk_regmap_mux, clkr);
+}
+
+extern const struct clk_ops rtk_clk_regmap_mux_ops;
+
+#endif /* __CLK_REALTEK_CLK_REGMAP_MUX_H */
--
2.34.1
^ permalink raw reply related
* [PATCH v6 01/10] dt-bindings: clock: Add Realtek RTD1625 Clock & Reset Controller
From: Yu-Chun Lin @ 2026-04-02 7:39 UTC (permalink / raw)
To: mturquette, sboyd, robh, krzk+dt, conor+dt, p.zabel, cylee12,
afaerber, jyanchou
Cc: devicetree, linux-clk, linux-kernel, linux-arm-kernel,
linux-realtek-soc, james.tai, cy.huang, stanley_chang,
eleanor.lin, Krzysztof Kozlowski
In-Reply-To: <20260402073957.2742459-1-eleanor.lin@realtek.com>
Add DT binding schema for Realtek RTD1625 clock and reset controller
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
Co-developed-by: Cheng-Yu Lee <cylee12@realtek.com>
Signed-off-by: Cheng-Yu Lee <cylee12@realtek.com>
Signed-off-by: Yu-Chun Lin <eleanor.lin@realtek.com>
---
Changes in v6:
- Add reviewed-by tag from Krzysztof.
- Add Cheng-Yu Lee as maintainer in the binding file.
- Add 'clocks' property.
- Add include/dt-bindings/reset/realtek,rtd1625.h to the MAINTAINERS file.
---
.../bindings/clock/realtek,rtd1625-clk.yaml | 58 ++++++
MAINTAINERS | 10 +
.../dt-bindings/clock/realtek,rtd1625-clk.h | 164 +++++++++++++++++
include/dt-bindings/reset/realtek,rtd1625.h | 171 ++++++++++++++++++
4 files changed, 403 insertions(+)
create mode 100644 Documentation/devicetree/bindings/clock/realtek,rtd1625-clk.yaml
create mode 100644 include/dt-bindings/clock/realtek,rtd1625-clk.h
create mode 100644 include/dt-bindings/reset/realtek,rtd1625.h
diff --git a/Documentation/devicetree/bindings/clock/realtek,rtd1625-clk.yaml b/Documentation/devicetree/bindings/clock/realtek,rtd1625-clk.yaml
new file mode 100644
index 000000000000..1aceef31e148
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/realtek,rtd1625-clk.yaml
@@ -0,0 +1,58 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/realtek,rtd1625-clk.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Realtek RTD1625 Clock & Reset Controller
+
+maintainers:
+ - Cheng-Yu Lee <cylee12@realtek.com>
+ - Yu-Chun Lin <eleanor.lin@realtek.com>
+
+description: |
+ The Realtek RTD1625 Clock Controller manages and distributes clock
+ signals to various controllers and implements a Reset Controller for the
+ SoC peripherals.
+
+ Clocks and resets are referenced by unique identifiers, which are defined as
+ preprocessor macros in include/dt-bindings/clock/realtek,rtd1625-clk.h and
+ include/dt-bindings/reset/realtek,rtd1625.h.
+
+properties:
+ compatible:
+ enum:
+ - realtek,rtd1625-crt-clk
+ - realtek,rtd1625-iso-clk
+ - realtek,rtd1625-iso-s-clk
+
+ reg:
+ maxItems: 1
+
+ clocks:
+ maxItems: 1
+
+ "#clock-cells":
+ const: 1
+
+ "#reset-cells":
+ const: 1
+
+required:
+ - compatible
+ - reg
+ - clocks
+ - "#clock-cells"
+ - "#reset-cells"
+
+additionalProperties: false
+
+examples:
+ - |
+ clock-controller@98000000 {
+ compatible = "realtek,rtd1625-crt-clk";
+ reg = <0x98000000 0x1000>;
+ clocks = <&osc27m>;
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+ };
diff --git a/MAINTAINERS b/MAINTAINERS
index c3fe46d7c4bc..07e73bf621b0 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -22233,6 +22233,16 @@ S: Maintained
F: Documentation/devicetree/bindings/net/dsa/realtek.yaml
F: drivers/net/dsa/realtek/*
+REALTEK SOC CLOCK AND RESET DRIVERS
+M: Cheng-Yu Lee <cylee12@realtek.com>
+M: Yu-Chun Lin <eleanor.lin@realtek.com>
+L: devicetree@vger.kernel.org
+L: linux-clk@vger.kernel.org
+S: Supported
+F: Documentation/devicetree/bindings/clock/realtek*
+F: include/dt-bindings/clock/realtek*
+F: include/dt-bindings/reset/realtek*
+
REALTEK SPI-NAND
M: Chris Packham <chris.packham@alliedtelesis.co.nz>
S: Maintained
diff --git a/include/dt-bindings/clock/realtek,rtd1625-clk.h b/include/dt-bindings/clock/realtek,rtd1625-clk.h
new file mode 100644
index 000000000000..61ca652d6880
--- /dev/null
+++ b/include/dt-bindings/clock/realtek,rtd1625-clk.h
@@ -0,0 +1,164 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+/*
+ * Copyright (C) 2025 Realtek Semiconductor Corp.
+ */
+#ifndef __DT_BINDINGS_RTK_CLOCK_RTD1625_H
+#define __DT_BINDINGS_RTK_CLOCK_RTD1625_H
+
+#define RTD1625_CRT_CLK_EN_MISC 0
+#define RTD1625_CRT_CLK_EN_PCIE0 1
+#define RTD1625_CRT_CLK_EN_DIP 2
+#define RTD1625_CRT_CLK_EN_GSPI 3
+#define RTD1625_CRT_CLK_EN_ISO_MISC 5
+#define RTD1625_CRT_CLK_EN_SDS 6
+#define RTD1625_CRT_CLK_EN_HDMI 7
+#define RTD1625_CRT_CLK_EN_GPU 9
+#define RTD1625_CRT_CLK_EN_VE1 10
+#define RTD1625_CRT_CLK_EN_VE2 11
+#define RTD1625_CRT_CLK_EN_MD 18
+#define RTD1625_CRT_CLK_EN_TP 19
+#define RTD1625_CRT_CLK_EN_RCIC 20
+#define RTD1625_CRT_CLK_EN_NF 21
+#define RTD1625_CRT_CLK_EN_EMMC 22
+#define RTD1625_CRT_CLK_EN_SD 23
+#define RTD1625_CRT_CLK_EN_SDIO_IP 24
+#define RTD1625_CRT_CLK_EN_MIPI_CSI 25
+#define RTD1625_CRT_CLK_EN_EMMC_IP 26
+#define RTD1625_CRT_CLK_EN_SDIO 27
+#define RTD1625_CRT_CLK_EN_SD_IP 28
+#define RTD1625_CRT_CLK_EN_TPB 30
+#define RTD1625_CRT_CLK_EN_MISC_SC1 31
+#define RTD1625_CRT_CLK_EN_MISC_I2C_3 32
+#define RTD1625_CRT_CLK_EN_ACPU 33
+#define RTD1625_CRT_CLK_EN_JPEG 34
+#define RTD1625_CRT_CLK_EN_MISC_SC0 37
+#define RTD1625_CRT_CLK_EN_HDMIRX 45
+#define RTD1625_CRT_CLK_EN_HSE 46
+#define RTD1625_CRT_CLK_EN_FAN 49
+#define RTD1625_CRT_CLK_EN_SATA_WRAP_SYS 52
+#define RTD1625_CRT_CLK_EN_SATA_WRAP_SYSH 53
+#define RTD1625_CRT_CLK_EN_SATA_MAC_SYSH 54
+#define RTD1625_CRT_CLK_EN_R2RDSC 55
+#define RTD1625_CRT_CLK_EN_TPC 56
+#define RTD1625_CRT_CLK_EN_PCIE1 57
+#define RTD1625_CRT_CLK_EN_MISC_I2C_4 58
+#define RTD1625_CRT_CLK_EN_MISC_I2C_5 59
+#define RTD1625_CRT_CLK_EN_TSIO 60
+#define RTD1625_CRT_CLK_EN_VE4 61
+#define RTD1625_CRT_CLK_EN_EDP 62
+#define RTD1625_CRT_CLK_EN_TSIO_TRX 63
+#define RTD1625_CRT_CLK_EN_PCIE2 64
+#define RTD1625_CRT_CLK_EN_EARC 66
+#define RTD1625_CRT_CLK_EN_LITE 67
+#define RTD1625_CRT_CLK_EN_MIPI_DSI 68
+#define RTD1625_CRT_CLK_EN_NPUPP 69
+#define RTD1625_CRT_CLK_EN_NPU 70
+#define RTD1625_CRT_CLK_EN_AUCPU0 71
+#define RTD1625_CRT_CLK_EN_AUCPU1 72
+#define RTD1625_CRT_CLK_EN_NSRAM 73
+#define RTD1625_CRT_CLK_EN_HDMITOP 74
+#define RTD1625_CRT_CLK_EN_AUCPU_ISO_NPU 76
+#define RTD1625_CRT_CLK_EN_KEYLADDER 77
+#define RTD1625_CRT_CLK_EN_IFCP_KLM 78
+#define RTD1625_CRT_CLK_EN_IFCP 79
+#define RTD1625_CRT_CLK_EN_MDL_GENPW 80
+#define RTD1625_CRT_CLK_EN_MDL_CHIP 81
+#define RTD1625_CRT_CLK_EN_MDL_IP 82
+#define RTD1625_CRT_CLK_EN_MDLM2M 83
+#define RTD1625_CRT_CLK_EN_MDL_XTAL 84
+#define RTD1625_CRT_CLK_EN_TEST_MUX 85
+#define RTD1625_CRT_CLK_EN_DLA 86
+#define RTD1625_CRT_CLK_EN_TPCW 88
+#define RTD1625_CRT_CLK_EN_GPU_TS_SRC 89
+#define RTD1625_CRT_CLK_EN_VI 91
+#define RTD1625_CRT_CLK_EN_LVDS1 92
+#define RTD1625_CRT_CLK_EN_LVDS2 93
+#define RTD1625_CRT_CLK_EN_AUCPU 94
+#define RTD1625_CRT_CLK_EN_UR1 96
+#define RTD1625_CRT_CLK_EN_UR2 97
+#define RTD1625_CRT_CLK_EN_UR3 98
+#define RTD1625_CRT_CLK_EN_UR4 99
+#define RTD1625_CRT_CLK_EN_UR5 100
+#define RTD1625_CRT_CLK_EN_UR6 101
+#define RTD1625_CRT_CLK_EN_UR7 102
+#define RTD1625_CRT_CLK_EN_UR8 103
+#define RTD1625_CRT_CLK_EN_UR9 104
+#define RTD1625_CRT_CLK_EN_UR_TOP 105
+#define RTD1625_CRT_CLK_EN_MISC_I2C_7 110
+#define RTD1625_CRT_CLK_EN_MISC_I2C_6 111
+#define RTD1625_CRT_CLK_EN_SPI0 112
+#define RTD1625_CRT_CLK_EN_SPI1 113
+#define RTD1625_CRT_CLK_EN_SPI2 114
+#define RTD1625_CRT_CLK_EN_LSADC0 120
+#define RTD1625_CRT_CLK_EN_LSADC1 121
+#define RTD1625_CRT_CLK_EN_ISOMIS_DMA 122
+#define RTD1625_CRT_CLK_EN_DPTX 124
+#define RTD1625_CRT_CLK_EN_NPU_MIPI_CSI 125
+#define RTD1625_CRT_CLK_EN_EDPTX 126
+#define RTD1625_CRT_CLK_HIFI 128
+#define RTD1625_CRT_CLK_NPU_MIPI_CSI 129
+#define RTD1625_CRT_CLK_NPU 130
+#define RTD1625_CRT_CLK_NPU_SYSH 132
+#define RTD1625_CRT_CLK_HIFI_SCPU 133
+#define RTD1625_CRT_CLK_GPU 134
+#define RTD1625_CRT_CLK_GPU2D 135
+#define RTD1625_CRT_CLK_MIPI_DSI_PCLK 136
+#define RTD1625_CRT_CLK_VE1 137
+#define RTD1625_CRT_CLK_VE2 138
+#define RTD1625_CRT_CLK_VE4 139
+#define RTD1625_CRT_CLK_SYS 141
+#define RTD1625_CRT_CLK_SYSH 142
+#define RTD1625_CRT_PLL_SDIO_REF 145
+#define RTD1625_CRT_PLL_CR_REF 146
+#define RTD1625_CRT_PLL_EMMC_REF 147
+#define RTD1625_CRT_CLK_MIS_SC0 148
+#define RTD1625_CRT_CLK_MIS_SC1 149
+#define RTD1625_CRT_PLL_SCPU 150
+#define RTD1625_CRT_PLL_VE1 151
+#define RTD1625_CRT_PLL_DDSA 152
+#define RTD1625_CRT_PLL_PSAUDA1 153
+#define RTD1625_CRT_PLL_PSAUDA2 154
+#define RTD1625_CRT_PLL_BUS 155
+#define RTD1625_CRT_PLL_SDIO 156
+#define RTD1625_CRT_PLL_SDIO_VP0 157
+#define RTD1625_CRT_PLL_SDIO_VP1 158
+#define RTD1625_CRT_PLL_DCSB 159
+#define RTD1625_CRT_PLL_GPU 160
+#define RTD1625_CRT_PLL_NPU 161
+#define RTD1625_CRT_PLL_VE2 162
+#define RTD1625_CRT_PLL_HIFI 163
+#define RTD1625_CRT_PLL_SD 164
+#define RTD1625_CRT_PLL_SD_VP0 165
+#define RTD1625_CRT_PLL_SD_VP1 166
+#define RTD1625_CRT_PLL_EMMC 167
+#define RTD1625_CRT_PLL_EMMC_VP0 168
+#define RTD1625_CRT_PLL_EMMC_VP1 169
+#define RTD1625_CRT_PLL_ACPU 170
+#define RTD1625_CRT_CLK_DET 171
+
+#define RTD1625_ISO_CLK_EN_USB_P4 0
+#define RTD1625_ISO_CLK_EN_USB_P3 1
+#define RTD1625_ISO_CLK_EN_MISC_CEC0 2
+#define RTD1625_ISO_CLK_EN_CBUSRX_SYS 3
+#define RTD1625_ISO_CLK_EN_CBUSTX_SYS 4
+#define RTD1625_ISO_CLK_EN_CBUS_SYS 5
+#define RTD1625_ISO_CLK_EN_CBUS_OSC 6
+#define RTD1625_ISO_CLK_EN_MISC_UR0 8
+#define RTD1625_ISO_CLK_EN_I2C0 9
+#define RTD1625_ISO_CLK_EN_I2C1 10
+#define RTD1625_ISO_CLK_EN_ETN_250M 11
+#define RTD1625_ISO_CLK_EN_ETN_SYS 12
+#define RTD1625_ISO_CLK_EN_USB_DRD 13
+#define RTD1625_ISO_CLK_EN_USB_HOST 14
+#define RTD1625_ISO_CLK_EN_USB_U3_HOST 15
+#define RTD1625_ISO_CLK_EN_USB 16
+#define RTD1625_ISO_CLK_EN_VTC 17
+#define RTD1625_ISO_CLK_EN_MISC_VFD 18
+
+#define RTD1625_ISO_S_CLK_EN_ISOM_MIS 0
+#define RTD1625_ISO_S_CLK_EN_ISOM_GPIOM 1
+#define RTD1625_ISO_S_CLK_EN_TIMER7 2
+#define RTD1625_ISO_S_CLK_EN_IRDA 3
+#define RTD1625_ISO_S_CLK_EN_UR10 4
+
+#endif /* __DT_BINDINGS_RTK_CLOCK_RTD1625_H */
diff --git a/include/dt-bindings/reset/realtek,rtd1625.h b/include/dt-bindings/reset/realtek,rtd1625.h
new file mode 100644
index 000000000000..31e7fa66ef31
--- /dev/null
+++ b/include/dt-bindings/reset/realtek,rtd1625.h
@@ -0,0 +1,171 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+/*
+ * Copyright (C) 2025 Realtek Semiconductor Corp.
+ */
+
+#ifndef __DT_BINDINGS_RTK_RESET_RTD1625_H
+#define __DT_BINDINGS_RTK_RESET_RTD1625_H
+
+#define RTD1625_CRT_RSTN_MISC 0
+#define RTD1625_CRT_RSTN_DIP 1
+#define RTD1625_CRT_RSTN_GSPI 2
+#define RTD1625_CRT_RSTN_SDS 3
+#define RTD1625_CRT_RSTN_SDS_REG 4
+#define RTD1625_CRT_RSTN_SDS_PHY 5
+#define RTD1625_CRT_RSTN_GPU2D 6
+#define RTD1625_CRT_RSTN_DC_PHY 7
+#define RTD1625_CRT_RSTN_DCPHY_CRT 8
+#define RTD1625_CRT_RSTN_LSADC 9
+#define RTD1625_CRT_RSTN_SE 10
+#define RTD1625_CRT_RSTN_DLA 11
+#define RTD1625_CRT_RSTN_JPEG 12
+#define RTD1625_CRT_RSTN_SD 13
+#define RTD1625_CRT_RSTN_SDIO 14
+#define RTD1625_CRT_RSTN_PCR_CNT 15
+#define RTD1625_CRT_RSTN_PCIE0_STITCH 16
+#define RTD1625_CRT_RSTN_PCIE0_PHY 17
+#define RTD1625_CRT_RSTN_PCIE0 18
+#define RTD1625_CRT_RSTN_PCIE0_CORE 19
+#define RTD1625_CRT_RSTN_PCIE0_POWER 20
+#define RTD1625_CRT_RSTN_PCIE0_NONSTICH 21
+#define RTD1625_CRT_RSTN_PCIE0_PHY_MDIO 22
+#define RTD1625_CRT_RSTN_PCIE0_SGMII_MDIO 23
+#define RTD1625_CRT_RSTN_VO2 24
+#define RTD1625_CRT_RSTN_MISC_SC0 25
+#define RTD1625_CRT_RSTN_MD 26
+#define RTD1625_CRT_RSTN_LVDS1 27
+#define RTD1625_CRT_RSTN_LVDS2 28
+#define RTD1625_CRT_RSTN_MISC_SC1 29
+#define RTD1625_CRT_RSTN_I2C_3 30
+#define RTD1625_CRT_RSTN_FAN 31
+#define RTD1625_CRT_RSTN_TVE 32
+#define RTD1625_CRT_RSTN_AIO 33
+#define RTD1625_CRT_RSTN_VO 34
+#define RTD1625_CRT_RSTN_MIPI_CSI 35
+#define RTD1625_CRT_RSTN_HDMIRX 36
+#define RTD1625_CRT_RSTN_HDMIRX_WRAP 37
+#define RTD1625_CRT_RSTN_HDMI 38
+#define RTD1625_CRT_RSTN_DISP 39
+#define RTD1625_CRT_RSTN_SATA_PHY_POW1 40
+#define RTD1625_CRT_RSTN_SATA_PHY_POW0 41
+#define RTD1625_CRT_RSTN_SATA_MDIO1 42
+#define RTD1625_CRT_RSTN_SATA_MDIO0 43
+#define RTD1625_CRT_RSTN_SATA_WRAP 44
+#define RTD1625_CRT_RSTN_SATA_MAC_P1 45
+#define RTD1625_CRT_RSTN_SATA_MAC_P0 46
+#define RTD1625_CRT_RSTN_SATA_MAC_COM 47
+#define RTD1625_CRT_RSTN_PCIE1_STITCH 48
+#define RTD1625_CRT_RSTN_PCIE1_PHY 49
+#define RTD1625_CRT_RSTN_PCIE1 50
+#define RTD1625_CRT_RSTN_PCIE1_CORE 51
+#define RTD1625_CRT_RSTN_PCIE1_POWER 52
+#define RTD1625_CRT_RSTN_PCIE1_NONSTICH 53
+#define RTD1625_CRT_RSTN_PCIE1_PHY_MDIO 54
+#define RTD1625_CRT_RSTN_HDMITOP 55
+#define RTD1625_CRT_RSTN_I2C_4 56
+#define RTD1625_CRT_RSTN_I2C_5 57
+#define RTD1625_CRT_RSTN_TSIO 58
+#define RTD1625_CRT_RSTN_VI 59
+#define RTD1625_CRT_RSTN_EDP 60
+#define RTD1625_CRT_RSTN_VE1_MMU 61
+#define RTD1625_CRT_RSTN_VE1_MMU_FUNC 62
+#define RTD1625_CRT_RSTN_HSE_MMU 63
+#define RTD1625_CRT_RSTN_HSE_MMU_FUNC 64
+#define RTD1625_CRT_RSTN_MDLM2M 65
+#define RTD1625_CRT_RSTN_ISO_GSPI 66
+#define RTD1625_CRT_RSTN_SOFT_NPU 67
+#define RTD1625_CRT_RSTN_SPI2EMMC 68
+#define RTD1625_CRT_RSTN_EARC 69
+#define RTD1625_CRT_RSTN_VE1 70
+#define RTD1625_CRT_RSTN_PCIE2_STITCH 71
+#define RTD1625_CRT_RSTN_PCIE2_PHY 72
+#define RTD1625_CRT_RSTN_PCIE2 73
+#define RTD1625_CRT_RSTN_PCIE2_CORE 74
+#define RTD1625_CRT_RSTN_PCIE2_POWER 75
+#define RTD1625_CRT_RSTN_PCIE2_NONSTICH 76
+#define RTD1625_CRT_RSTN_PCIE2_PHY_MDIO 77
+#define RTD1625_CRT_RSTN_DCPHY_UMCTL2 78
+#define RTD1625_CRT_RSTN_MIPI_DSI 79
+#define RTD1625_CRT_RSTN_HIFM 80
+#define RTD1625_CRT_RSTN_NSRAM 81
+#define RTD1625_CRT_RSTN_AUCPU0_REG 82
+#define RTD1625_CRT_RSTN_MDL_GENPW 83
+#define RTD1625_CRT_RSTN_MDL_CHIP 84
+#define RTD1625_CRT_RSTN_MDL_IP 85
+#define RTD1625_CRT_RSTN_TEST_MUX 86
+#define RTD1625_CRT_RSTN_ISO_BIST 87
+#define RTD1625_CRT_RSTN_MAIN_BIST 88
+#define RTD1625_CRT_RSTN_MAIN2_BIST 89
+#define RTD1625_CRT_RSTN_VE1_BIST 90
+#define RTD1625_CRT_RSTN_VE2_BIST 91
+#define RTD1625_CRT_RSTN_DCPHY_BIST 92
+#define RTD1625_CRT_RSTN_GPU_BIST 93
+#define RTD1625_CRT_RSTN_DISP_BIST 94
+#define RTD1625_CRT_RSTN_NPU_BIST 95
+#define RTD1625_CRT_RSTN_CAS_BIST 96
+#define RTD1625_CRT_RSTN_VE4_BIST 97
+#define RTD1625_CRT_RSTN_EMMC 98
+#define RTD1625_CRT_RSTN_GPU 99
+#define RTD1625_CRT_RSTN_VE2 100
+#define RTD1625_CRT_RSTN_UR1 101
+#define RTD1625_CRT_RSTN_UR2 102
+#define RTD1625_CRT_RSTN_UR3 103
+#define RTD1625_CRT_RSTN_UR4 104
+#define RTD1625_CRT_RSTN_UR5 105
+#define RTD1625_CRT_RSTN_UR6 106
+#define RTD1625_CRT_RSTN_UR7 107
+#define RTD1625_CRT_RSTN_UR8 108
+#define RTD1625_CRT_RSTN_UR9 109
+#define RTD1625_CRT_RSTN_UR_TOP 110
+#define RTD1625_CRT_RSTN_I2C_7 111
+#define RTD1625_CRT_RSTN_I2C_6 112
+#define RTD1625_CRT_RSTN_SPI0 113
+#define RTD1625_CRT_RSTN_SPI1 114
+#define RTD1625_CRT_RSTN_SPI2 115
+#define RTD1625_CRT_RSTN_LSADC0 116
+#define RTD1625_CRT_RSTN_LSADC1 117
+#define RTD1625_CRT_RSTN_ISOMIS_DMA 118
+#define RTD1625_CRT_RSTN_AUDIO_ADC 119
+#define RTD1625_CRT_RSTN_DPTX 120
+#define RTD1625_CRT_RSTN_AUCPU1_REG 121
+#define RTD1625_CRT_RSTN_EDPTX 122
+
+/* ISO reset */
+#define RTD1625_ISO_RSTN_VFD 0
+#define RTD1625_ISO_RSTN_CEC0 1
+#define RTD1625_ISO_RSTN_CEC1 2
+#define RTD1625_ISO_RSTN_CBUSTX 3
+#define RTD1625_ISO_RSTN_CBUSRX 4
+#define RTD1625_ISO_RSTN_USB3_PHY2_XTAL_POW 5
+#define RTD1625_ISO_RSTN_UR0 6
+#define RTD1625_ISO_RSTN_GMAC 7
+#define RTD1625_ISO_RSTN_GPHY 8
+#define RTD1625_ISO_RSTN_I2C_0 9
+#define RTD1625_ISO_RSTN_I2C_1 10
+#define RTD1625_ISO_RSTN_CBUS 11
+#define RTD1625_ISO_RSTN_USB_DRD 12
+#define RTD1625_ISO_RSTN_USB_HOST 13
+#define RTD1625_ISO_RSTN_USB_PHY_0 14
+#define RTD1625_ISO_RSTN_USB_PHY_1 15
+#define RTD1625_ISO_RSTN_USB_PHY_2 16
+#define RTD1625_ISO_RSTN_USB 17
+#define RTD1625_ISO_RSTN_TYPE_C 18
+#define RTD1625_ISO_RSTN_USB_U3_HOST 19
+#define RTD1625_ISO_RSTN_USB3_PHY0_POW 20
+#define RTD1625_ISO_RSTN_USB3_P0_MDIO 21
+#define RTD1625_ISO_RSTN_USB3_PHY1_POW 22
+#define RTD1625_ISO_RSTN_USB3_P1_MDIO 23
+#define RTD1625_ISO_RSTN_VTC 24
+#define RTD1625_ISO_RSTN_USB3_PHY2_POW 25
+#define RTD1625_ISO_RSTN_USB3_P2_MDIO 26
+#define RTD1625_ISO_RSTN_USB_PHY_3 27
+#define RTD1625_ISO_RSTN_USB_PHY_4 28
+
+/* ISO_S reset */
+#define RTD1625_ISO_S_RSTN_ISOM_MIS 0
+#define RTD1625_ISO_S_RSTN_GPIOM 1
+#define RTD1625_ISO_S_RSTN_TIMER7 2
+#define RTD1625_ISO_S_RSTN_IRDA 3
+#define RTD1625_ISO_S_RSTN_UR10 4
+
+#endif /* __DT_BINDINGS_RTK_RESET_RTD1625_H */
--
2.34.1
^ permalink raw reply related
* [PATCH v6 00/10] clk: realtek: Add RTD1625 clock support
From: Yu-Chun Lin @ 2026-04-02 7:39 UTC (permalink / raw)
To: mturquette, sboyd, robh, krzk+dt, conor+dt, p.zabel, cylee12,
afaerber, jyanchou
Cc: devicetree, linux-clk, linux-kernel, linux-arm-kernel,
linux-realtek-soc, james.tai, cy.huang, stanley_chang,
eleanor.lin
Hello,
This patch series adds clock support for Realtek's RTD1625 platform.
The series includes:
1. Device Tree: Add clock controller nodes.
2. Infrastructure: reset controller, basic clocks, PLLs, gate clocks, mux
clocks, and MMC-tuned PLLs.
3. Platform drivers: two clock controller drivers for RTD1625-CRT and
RTD1625-ISO.
Best regards,
Yu-Chun Lin
---
Changes in v6:
General:
- Add the headers used in c file to follow the "Include What You Use" principle.
- Move dts patch to patch 10.
Patch 1:
- Add 'clocks' property.
- Add reviewed-by tag from Krzysztof.
- Add Cheng-Yu Lee as maintainer in the binding file.
- Add 'clocks' property.
- Add include/dt-bindings/reset/realtek,rtd1625.h to the MAINTAINERS file.
Patch 2:
- Remove the global header include/linux/reset/realtek.h and use a local common.h
instead.
- Extract regmap and of_node directly from the parent device.
- Remove struct rtk_reset_initdata. Now, when the caller uses
rtk_reset_controller_add(), directly passes struct rtk_reset_data.
Patch 3:
- Replace direct reset controller initialization with auxiliary device creation.
- Add aux_name parameter to rtk_clk_probe() to register the reset auxiliary device.
- Simplify rtk_clk_desc because reset data is handled entirely by the auxiliary reset driver.
- In Kconfig, change "depends on RESET_CONTROLLER" to "select RESET_CONTROLLER"
- Remove unused includes headers and added <linux/auxiliary_bus.h>.
Patch 6 and 7:
- Move to_clk_pll() from clk-pll.h to clk-pll.c to limit its scope.
Patch 7:
- Change offset type from int to unsigned int.
Patch 8 and 9:
- Move struct rtk_reset_desc arrays from the clock driver to the dedicated reset driver.
- Implement and register a dedicated reset auxiliary driver.
Patch 10:
- Add 'clocks' property.
Cheng-Yu Lee (6):
reset: Add Realtek basic reset support
clk: realtek: Introduce a common probe()
clk: realtek: Add support for phase locked loops (PLLs)
clk: realtek: Add support for gate clock
clk: realtek: Add support for mux clock
clk: realtek: Add support for MMC-tuned PLL clocks
Yu-Chun Lin (4):
dt-bindings: clock: Add Realtek RTD1625 Clock & Reset Controller
clk: realtek: Add RTD1625-CRT clock controller driver
clk: realtek: Add RTD1625-ISO clock controller driver
arm64: dts: realtek: Add clock support for RTD1625
.../bindings/clock/realtek,rtd1625-clk.yaml | 58 ++
MAINTAINERS | 20 +
arch/arm64/boot/dts/realtek/kent.dtsi | 33 +
drivers/clk/Kconfig | 1 +
drivers/clk/Makefile | 1 +
drivers/clk/realtek/Kconfig | 44 +
drivers/clk/realtek/Makefile | 13 +
drivers/clk/realtek/clk-pll-mmc.c | 410 +++++++++
drivers/clk/realtek/clk-pll.c | 164 ++++
drivers/clk/realtek/clk-pll.h | 55 ++
drivers/clk/realtek/clk-regmap-gate.c | 69 ++
drivers/clk/realtek/clk-regmap-gate.h | 65 ++
drivers/clk/realtek/clk-regmap-mux.c | 48 ++
drivers/clk/realtek/clk-regmap-mux.h | 43 +
drivers/clk/realtek/clk-rtd1625-crt.c | 779 ++++++++++++++++++
drivers/clk/realtek/clk-rtd1625-iso.c | 144 ++++
drivers/clk/realtek/common.c | 67 ++
drivers/clk/realtek/common.h | 37 +
drivers/clk/realtek/freq_table.c | 36 +
drivers/clk/realtek/freq_table.h | 21 +
drivers/reset/Kconfig | 1 +
drivers/reset/Makefile | 1 +
drivers/reset/realtek/Kconfig | 5 +
drivers/reset/realtek/Makefile | 2 +
drivers/reset/realtek/common.c | 85 ++
drivers/reset/realtek/common.h | 29 +
drivers/reset/realtek/reset-rtd1625-crt.c | 186 +++++
drivers/reset/realtek/reset-rtd1625-iso.c | 96 +++
.../dt-bindings/clock/realtek,rtd1625-clk.h | 164 ++++
include/dt-bindings/reset/realtek,rtd1625.h | 171 ++++
30 files changed, 2848 insertions(+)
create mode 100644 Documentation/devicetree/bindings/clock/realtek,rtd1625-clk.yaml
create mode 100644 drivers/clk/realtek/Kconfig
create mode 100644 drivers/clk/realtek/Makefile
create mode 100644 drivers/clk/realtek/clk-pll-mmc.c
create mode 100644 drivers/clk/realtek/clk-pll.c
create mode 100644 drivers/clk/realtek/clk-pll.h
create mode 100644 drivers/clk/realtek/clk-regmap-gate.c
create mode 100644 drivers/clk/realtek/clk-regmap-gate.h
create mode 100644 drivers/clk/realtek/clk-regmap-mux.c
create mode 100644 drivers/clk/realtek/clk-regmap-mux.h
create mode 100644 drivers/clk/realtek/clk-rtd1625-crt.c
create mode 100644 drivers/clk/realtek/clk-rtd1625-iso.c
create mode 100644 drivers/clk/realtek/common.c
create mode 100644 drivers/clk/realtek/common.h
create mode 100644 drivers/clk/realtek/freq_table.c
create mode 100644 drivers/clk/realtek/freq_table.h
create mode 100644 drivers/reset/realtek/Kconfig
create mode 100644 drivers/reset/realtek/Makefile
create mode 100644 drivers/reset/realtek/common.c
create mode 100644 drivers/reset/realtek/common.h
create mode 100644 drivers/reset/realtek/reset-rtd1625-crt.c
create mode 100644 drivers/reset/realtek/reset-rtd1625-iso.c
create mode 100644 include/dt-bindings/clock/realtek,rtd1625-clk.h
create mode 100644 include/dt-bindings/reset/realtek,rtd1625.h
--
2.34.1
^ permalink raw reply
* [PATCH v6 05/10] clk: realtek: Add support for gate clock
From: Yu-Chun Lin @ 2026-04-02 7:39 UTC (permalink / raw)
To: mturquette, sboyd, robh, krzk+dt, conor+dt, p.zabel, cylee12,
afaerber, jyanchou
Cc: devicetree, linux-clk, linux-kernel, linux-arm-kernel,
linux-realtek-soc, james.tai, cy.huang, stanley_chang,
eleanor.lin
In-Reply-To: <20260402073957.2742459-1-eleanor.lin@realtek.com>
From: Cheng-Yu Lee <cylee12@realtek.com>
Introduce clk_regmap_gate_ops supporting enable, disable, is_enabled, and
disable_unused for standard regmap gate clocks.
Add clk_regmap_gate_ro_ops as a read-only variant exposing only is_enabled.
Signed-off-by: Cheng-Yu Lee <cylee12@realtek.com>
Co-developed-by: Yu-Chun Lin <eleanor.lin@realtek.com>
Signed-off-by: Yu-Chun Lin <eleanor.lin@realtek.com>
---
Changes in v6:
- Add the headers used in c file to follow the "Include What You Use" principle.
---
drivers/clk/realtek/Makefile | 2 +
drivers/clk/realtek/clk-regmap-gate.c | 69 +++++++++++++++++++++++++++
drivers/clk/realtek/clk-regmap-gate.h | 65 +++++++++++++++++++++++++
3 files changed, 136 insertions(+)
create mode 100644 drivers/clk/realtek/clk-regmap-gate.c
create mode 100644 drivers/clk/realtek/clk-regmap-gate.h
diff --git a/drivers/clk/realtek/Makefile b/drivers/clk/realtek/Makefile
index a89ad77993e9..74375f8127ac 100644
--- a/drivers/clk/realtek/Makefile
+++ b/drivers/clk/realtek/Makefile
@@ -2,5 +2,7 @@
obj-$(CONFIG_RTK_CLK_COMMON) += clk-rtk.o
clk-rtk-y += common.o
+
clk-rtk-y += clk-pll.o
+clk-rtk-y += clk-regmap-gate.o
clk-rtk-y += freq_table.o
diff --git a/drivers/clk/realtek/clk-regmap-gate.c b/drivers/clk/realtek/clk-regmap-gate.c
new file mode 100644
index 000000000000..8738d6c6f8dd
--- /dev/null
+++ b/drivers/clk/realtek/clk-regmap-gate.c
@@ -0,0 +1,69 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2017 Realtek Semiconductor Corporation
+ * Author: Cheng-Yu Lee <cylee12@realtek.com>
+ */
+
+#include <linux/regmap.h>
+#include <linux/bits.h>
+#include "clk-regmap-gate.h"
+#include <linux/clk-provider.h>
+
+static int clk_regmap_gate_enable(struct clk_hw *hw)
+{
+ struct clk_regmap_gate *clkg = to_clk_regmap_gate(hw);
+ unsigned int mask;
+ unsigned int val;
+
+ mask = BIT(clkg->bit_idx);
+ val = BIT(clkg->bit_idx);
+
+ if (clkg->write_en) {
+ mask |= BIT(clkg->bit_idx + 1);
+ val |= BIT(clkg->bit_idx + 1);
+ }
+
+ return regmap_update_bits(clkg->clkr.regmap, clkg->gate_ofs, mask, val);
+}
+
+static void clk_regmap_gate_disable(struct clk_hw *hw)
+{
+ struct clk_regmap_gate *clkg = to_clk_regmap_gate(hw);
+ unsigned int mask;
+ unsigned int val;
+
+ mask = BIT(clkg->bit_idx);
+ val = 0;
+
+ if (clkg->write_en) {
+ mask |= BIT(clkg->bit_idx + 1);
+ val |= BIT(clkg->bit_idx + 1);
+ }
+
+ regmap_update_bits(clkg->clkr.regmap, clkg->gate_ofs, mask, val);
+}
+
+static int clk_regmap_gate_is_enabled(struct clk_hw *hw)
+{
+ struct clk_regmap_gate *clkg = to_clk_regmap_gate(hw);
+ int ret;
+ u32 val;
+
+ ret = regmap_read(clkg->clkr.regmap, clkg->gate_ofs, &val);
+ if (ret < 0)
+ return ret;
+
+ return !!(val & BIT(clkg->bit_idx));
+}
+
+const struct clk_ops rtk_clk_regmap_gate_ops = {
+ .enable = clk_regmap_gate_enable,
+ .disable = clk_regmap_gate_disable,
+ .is_enabled = clk_regmap_gate_is_enabled,
+};
+EXPORT_SYMBOL_NS_GPL(rtk_clk_regmap_gate_ops, "REALTEK_CLK");
+
+const struct clk_ops rtk_clk_regmap_gate_ro_ops = {
+ .is_enabled = clk_regmap_gate_is_enabled,
+};
+EXPORT_SYMBOL_NS_GPL(rtk_clk_regmap_gate_ro_ops, "REALTEK_CLK");
diff --git a/drivers/clk/realtek/clk-regmap-gate.h b/drivers/clk/realtek/clk-regmap-gate.h
new file mode 100644
index 000000000000..b93357bd5a0d
--- /dev/null
+++ b/drivers/clk/realtek/clk-regmap-gate.h
@@ -0,0 +1,65 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2017 Realtek Semiconductor Corporation
+ * Author: Cheng-Yu Lee <cylee12@realtek.com>
+ */
+
+#ifndef __CLK_REALTEK_CLK_REGMAP_GATE_H
+#define __CLK_REALTEK_CLK_REGMAP_GATE_H
+
+#include "common.h"
+
+struct clk_regmap_gate {
+ struct clk_regmap clkr;
+ int gate_ofs;
+ u8 bit_idx;
+ u32 write_en : 1;
+};
+
+#define __clk_regmap_gate_hw(_p) __clk_regmap_hw(&(_p)->clkr)
+
+#define __CLK_REGMAP_GATE(_name, _parent, _ops, _flags, _ofs, _bit_idx, \
+ _write_en) \
+ struct clk_regmap_gate _name = { \
+ .clkr.hw.init = CLK_HW_INIT(#_name, _parent, _ops, _flags), \
+ .gate_ofs = _ofs, \
+ .bit_idx = _bit_idx, \
+ .write_en = _write_en, \
+ }
+
+#define CLK_REGMAP_GATE(_name, _parent, _flags, _ofs, _bit_idx, _write_en) \
+ __CLK_REGMAP_GATE(_name, _parent, &rtk_clk_regmap_gate_ops, _flags, _ofs, \
+ _bit_idx, _write_en)
+
+#define CLK_REGMAP_GATE_RO(_name, _parent, _flags, _ofs, _bit_idx, _write_en) \
+ __CLK_REGMAP_GATE(_name, _parent, &rtk_clk_regmap_gate_ro_ops, _flags, \
+ _ofs, _bit_idx, _write_en)
+
+#define __CLK_REGMAP_GATE_NO_PARENT(_name, _ops, _flags, _ofs, _bit_idx, \
+ _write_en) \
+ struct clk_regmap_gate _name = { \
+ .clkr.hw.init = CLK_HW_INIT_NO_PARENT(#_name, _ops, _flags), \
+ .gate_ofs = _ofs, \
+ .bit_idx = _bit_idx, \
+ .write_en = _write_en, \
+ }
+
+#define CLK_REGMAP_GATE_NO_PARENT(_name, _flags, _ofs, _bit_idx, _write_en) \
+ __CLK_REGMAP_GATE_NO_PARENT(_name, &rtk_clk_regmap_gate_ops, _flags, _ofs, \
+ _bit_idx, _write_en)
+
+#define CLK_REGMAP_GATE_NO_PARENT_RO(_name, _flags, _ofs, _bit_idx, _write_en) \
+ __CLK_REGMAP_GATE_NO_PARENT(_name, &rtk_clk_regmap_gate_ro_ops, _flags, \
+ _ofs, _bit_idx, _write_en)
+
+static inline struct clk_regmap_gate *to_clk_regmap_gate(struct clk_hw *hw)
+{
+ struct clk_regmap *clkr = to_clk_regmap(hw);
+
+ return container_of(clkr, struct clk_regmap_gate, clkr);
+}
+
+extern const struct clk_ops rtk_clk_regmap_gate_ops;
+extern const struct clk_ops rtk_clk_regmap_gate_ro_ops;
+
+#endif /* __CLK_REALTEK_CLK_REGMAP_GATE_H */
--
2.34.1
^ permalink raw reply related
* [PATCH v6 02/10] reset: Add Realtek basic reset support
From: Yu-Chun Lin @ 2026-04-02 7:39 UTC (permalink / raw)
To: mturquette, sboyd, robh, krzk+dt, conor+dt, p.zabel, cylee12,
afaerber, jyanchou
Cc: devicetree, linux-clk, linux-kernel, linux-arm-kernel,
linux-realtek-soc, james.tai, cy.huang, stanley_chang,
eleanor.lin
In-Reply-To: <20260402073957.2742459-1-eleanor.lin@realtek.com>
From: Cheng-Yu Lee <cylee12@realtek.com>
Define the reset operations backed by a regmap-based register interface
and prepare the reset controller to be registered through the reset
framework.
Since the reset controllers on Realtek SoCs often share the same register
space with the clock controllers, this common framework is designed to
extract the regmap and device tree node from the parent device
(e.g., an auxiliary device parent).
Signed-off-by: Cheng-Yu Lee <cylee12@realtek.com>
Co-developed-by: Yu-Chun Lin <eleanor.lin@realtek.com>
Signed-off-by: Yu-Chun Lin <eleanor.lin@realtek.com>
---
Changes in v6:
- Remove the global header include/linux/reset/realtek.h and use a local common.h
instead.
- Extract regmap and of_node directly from the parent device.
- Remove struct rtk_reset_initdata. Now, pass struct rtk_reset_data directly when
calling rtk_reset_controller_add().
---
MAINTAINERS | 1 +
drivers/reset/Kconfig | 1 +
drivers/reset/Makefile | 1 +
drivers/reset/realtek/Kconfig | 3 ++
drivers/reset/realtek/Makefile | 2 +
drivers/reset/realtek/common.c | 85 ++++++++++++++++++++++++++++++++++
drivers/reset/realtek/common.h | 29 ++++++++++++
7 files changed, 122 insertions(+)
create mode 100644 drivers/reset/realtek/Kconfig
create mode 100644 drivers/reset/realtek/Makefile
create mode 100644 drivers/reset/realtek/common.c
create mode 100644 drivers/reset/realtek/common.h
diff --git a/MAINTAINERS b/MAINTAINERS
index 07e73bf621b0..8f355896583b 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -22240,6 +22240,7 @@ L: devicetree@vger.kernel.org
L: linux-clk@vger.kernel.org
S: Supported
F: Documentation/devicetree/bindings/clock/realtek*
+F: drivers/reset/realtek/*
F: include/dt-bindings/clock/realtek*
F: include/dt-bindings/reset/realtek*
diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig
index 7ce151f6a7e4..03be1931f264 100644
--- a/drivers/reset/Kconfig
+++ b/drivers/reset/Kconfig
@@ -398,6 +398,7 @@ config RESET_ZYNQMP
source "drivers/reset/amlogic/Kconfig"
source "drivers/reset/hisilicon/Kconfig"
+source "drivers/reset/realtek/Kconfig"
source "drivers/reset/spacemit/Kconfig"
source "drivers/reset/starfive/Kconfig"
source "drivers/reset/sti/Kconfig"
diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile
index fc0cc99f8514..4407d1630070 100644
--- a/drivers/reset/Makefile
+++ b/drivers/reset/Makefile
@@ -2,6 +2,7 @@
obj-y += core.o
obj-y += amlogic/
obj-y += hisilicon/
+obj-y += realtek/
obj-y += spacemit/
obj-y += starfive/
obj-y += sti/
diff --git a/drivers/reset/realtek/Kconfig b/drivers/reset/realtek/Kconfig
new file mode 100644
index 000000000000..99a14d355803
--- /dev/null
+++ b/drivers/reset/realtek/Kconfig
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0-only
+config RESET_RTK_COMMON
+ bool
diff --git a/drivers/reset/realtek/Makefile b/drivers/reset/realtek/Makefile
new file mode 100644
index 000000000000..b59a3f7f2453
--- /dev/null
+++ b/drivers/reset/realtek/Makefile
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0-only
+obj-$(CONFIG_RESET_RTK_COMMON) += common.o
diff --git a/drivers/reset/realtek/common.c b/drivers/reset/realtek/common.c
new file mode 100644
index 000000000000..ea7ff27117e7
--- /dev/null
+++ b/drivers/reset/realtek/common.c
@@ -0,0 +1,85 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2019 Realtek Semiconductor Corporation
+ */
+
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/regmap.h>
+#include "common.h"
+
+static inline struct rtk_reset_data *to_rtk_reset_controller(struct reset_controller_dev *r)
+{
+ return container_of(r, struct rtk_reset_data, rcdev);
+}
+
+static inline struct rtk_reset_desc *rtk_reset_get_desc(struct rtk_reset_data *data,
+ unsigned long idx)
+{
+ return &data->descs[idx];
+}
+
+static int rtk_reset_assert(struct reset_controller_dev *rcdev,
+ unsigned long idx)
+{
+ struct rtk_reset_data *data = to_rtk_reset_controller(rcdev);
+ struct rtk_reset_desc *desc = rtk_reset_get_desc(data, idx);
+ u32 mask = desc->write_en ? (0x3 << desc->bit) : BIT(desc->bit);
+ u32 val = desc->write_en ? (0x2 << desc->bit) : 0;
+
+ return regmap_update_bits(data->regmap, desc->ofs, mask, val);
+}
+
+static int rtk_reset_deassert(struct reset_controller_dev *rcdev,
+ unsigned long idx)
+{
+ struct rtk_reset_data *data = to_rtk_reset_controller(rcdev);
+ struct rtk_reset_desc *desc = rtk_reset_get_desc(data, idx);
+ u32 mask = desc->write_en ? (0x3 << desc->bit) : BIT(desc->bit);
+ u32 val = mask;
+
+ return regmap_update_bits(data->regmap, desc->ofs, mask, val);
+}
+
+static int rtk_reset_status(struct reset_controller_dev *rcdev,
+ unsigned long idx)
+{
+ struct rtk_reset_data *data = to_rtk_reset_controller(rcdev);
+ struct rtk_reset_desc *desc = rtk_reset_get_desc(data, idx);
+ u32 val;
+ int ret;
+
+ ret = regmap_read(data->regmap, desc->ofs, &val);
+ if (ret)
+ return ret;
+
+ return !((val >> desc->bit) & 1);
+}
+
+static const struct reset_control_ops rtk_reset_ops = {
+ .assert = rtk_reset_assert,
+ .deassert = rtk_reset_deassert,
+ .status = rtk_reset_status,
+};
+
+/* The caller must initialize data->rcdev.nr_resets and data->descs before
+ * calling rtk_reset_controller_add().
+ */
+int rtk_reset_controller_add(struct device *dev,
+ struct rtk_reset_data *data)
+{
+ struct device *parent = dev->parent;
+
+ data->regmap = dev_get_regmap(parent, NULL);
+ if (!data->regmap)
+ return -ENODEV;
+
+ data->rcdev.owner = THIS_MODULE;
+ data->rcdev.ops = &rtk_reset_ops;
+ data->rcdev.dev = dev;
+ data->rcdev.of_node = parent->of_node;
+
+ return devm_reset_controller_register(dev, &data->rcdev);
+}
+EXPORT_SYMBOL_NS_GPL(rtk_reset_controller_add, "REALTEK_RESET");
diff --git a/drivers/reset/realtek/common.h b/drivers/reset/realtek/common.h
new file mode 100644
index 000000000000..ed69bca458de
--- /dev/null
+++ b/drivers/reset/realtek/common.h
@@ -0,0 +1,29 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2026 Realtek Semiconductor Corporation
+ * Author: Yu-Chun Lin <eleanor.lin@realtek.com>
+ */
+
+#ifndef __RESET_REALTEK_COMMON_H
+#define __RESET_REALTEK_COMMON_H
+
+#include <linux/reset-controller.h>
+
+struct regmap;
+
+struct rtk_reset_desc {
+ u32 ofs;
+ u32 bit;
+ bool write_en;
+};
+
+struct rtk_reset_data {
+ struct reset_controller_dev rcdev;
+ struct rtk_reset_desc *descs;
+ struct regmap *regmap;
+};
+
+int rtk_reset_controller_add(struct device *dev,
+ struct rtk_reset_data *initdata);
+
+#endif /* __RESET_REALTEK_COMMON_H */
--
2.34.1
^ permalink raw reply related
* Re: [PATCH v2 1/3] dt-bindings: mailbox: google,gs101-mbox: Add samsung,exynos850-mbox
From: Krzysztof Kozlowski @ 2026-04-02 8:11 UTC (permalink / raw)
To: Alexey Klimov
Cc: Sylwester Nawrocki, Chanwoo Choi, Alim Akhtar, Sam Protsenko,
Michael Turquette, Stephen Boyd, Rob Herring, Conor Dooley,
Tudor Ambarus, Jassi Brar, Krzysztof Kozlowski, Peter Griffin,
linux-samsung-soc, linux-arm-kernel, linux-clk, devicetree,
linux-kernel
In-Reply-To: <20260402-exynos850-ap2apm-mailbox-v2-1-ca5ffdff99d4@linaro.org>
On Thu, Apr 02, 2026 at 03:20:14AM +0100, Alexey Klimov wrote:
> Document support for a mailbox present on Exynos850-based platforms.
> The registers offsets are different from gs101 mailbox, but the
> workflow is similar, hence new compatible.
>
> Signed-off-by: Alexey Klimov <alexey.klimov@linaro.org>
> ---
> Documentation/devicetree/bindings/mailbox/google,gs101-mbox.yaml | 4 +++-
> 1 file changed, 3 insertions(+), 1 deletion(-)
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
Best regards,
Krzysztof
^ permalink raw reply
* [PATCH] arm64/crash: Add crash hotplug support
From: Jinjie Ruan @ 2026-04-02 8:14 UTC (permalink / raw)
To: catalin.marinas, will, thuth, masahiroy, mark.rutland, nsc, maz,
bhe, rppt, ardb, kees, leitao, linux-arm-kernel, linux-kernel
Cc: ruanjinjie
Due to CPU/Memory hotplug or online/offline events, the elfcorehdr
(which describes the CPUs and memory of the crashed kernel) of kdump
image becomes outdated. Consequently, attempting dump collection with
an outdated elfcorehdr can lead to inaccurate dump collection.
The current solution to address the above issue involves monitoring
the CPU/Memory add/remove events in userspace using udev rules and
whenever there are changes in CPU and memory resources, the entire
kdump image is loaded again. The kdump image includes kernel, initrd,
elfcorehdr, FDT, purgatory. Given that only elfcorehdr gets outdated
due to CPU/Memory add/remove events, reloading the entire kdump image
is inefficient. More importantly, kdump remains inactive for a
substantial amount of time until the kdump reload completes.
To address the aforementioned issue, commit 247262756121 ("crash: add
generic infrastructure for crash hotplug support") added a generic
infrastructure that allows architectures to selectively update the
kdump image component during CPU or memory add/remove events within
the kernel itself.
In the event of a CPU or memory add/remove events, the generic crash
hotplug event handler, crash_handle_hotplug_event(), is triggered. It
then acquires the necessary locks to update the kdump image and invokes
the architecture-specific crash hotplug handler,
arch_crash_handle_hotplug_event(), to update the required kdump image
components.
[1] has supported virtual CPU hotplug in virtual machines for ARM64,
allowing vCPUs to be added or removed at runtime to meet Kubernetes
demands.
On ARM64, only memory add/remove events are handled. Here's why:
1. Physical CPU hotplug: Not supported on ARM64 hardware.
2. ACPI vCPU hotplug (KVM virtual machine):
- vCPU hotplug is implemented as a static firmware policy where all
possible vCPUs are pre-described in the MADT table at boot.
- The vCPU status will be automatically updated after vCPU hotplug.
- No FDT or elfcorehdr update needed.
3. Device tree booted Virtual Machine vCPU hotplug:
- The elfcorehdr is built using for_each_possible_cpu(), so it
already includes all possible CPUs and doesn't need updates.
For memory add/remove events, the elfcorehdr is updated to reflect
the current memory layout.
This patch adds the ARCH_SUPPORTS_CRASH_HOTPLUG config option and
implements:
- arch_crash_hotplug_support(): Check if hotplug update is supported
- arch_crash_get_elfcorehdr_size(): Return elfcorehdr buffer size
- arch_crash_handle_hotplug_event(): Handle memory hotplug events
This follows the same approach as x86 commit
ea53ad9cf73b ("x86/crash: add x86 crash hotplug support") and powerpc
commit b741092d5976 ("powerpc/crash: add crash CPU hotplug support")
and commit 849599b702ef ("powerpc/crash: add crash memory hotplug
support").
The test is based on the following QEMU version:
https://github.com/salil-mehta/qemu.git virt-cpuhp-armv8/rfc-v2
Replace your '-smp' argument with something like:
| -smp cpus=1,maxcpus=3,cores=3,threads=1,sockets=1
then feed the following to the Qemu montior to hotplug vCPU;
| (qemu) device_add driver=host-arm-cpu,core-id=1,id=cpu1
| (qemu) device_del cpu1
feed the following to the Qemu montior to hotplug memory;
| (qemu) object_add memory-backend-ram,id=mem1,size=256M
| (qemu) device_add pc-dimm,id=dimm1,memdev=mem1
| (qemu) device_del dimm1
The qemu startup configuration is as follows:
qemu-system-aarch64 \
-M virt,gic-version=3,acpi=on,highmem=on \
-enable-kvm \
-cpu host \
-kernel Image \
-smp cpus=1,maxcpus=3,cores=3,threads=1,sockets=1 \
-bios /usr/share/edk2/aarch64/QEMU_EFI.fd \
-m 2G,slots=64,maxmem=16G \
-nographic \
-no-reboot \
-device virtio-rng-pci \
-append "root=/dev/vda rw console=ttyAMA0 kgdboc=ttyAMA0,115200 \
earlycon acpi=on crashkernel=512M" \
-drive if=none,file=images/rootfs.ext4,format=raw,id=hd0 \
-device virtio-blk-device,drive=hd0 \
There are two system calls, `kexec_file_load` and `kexec_load`, used to
load the kdump image. Only kexec_file_load syscall way is tested now.
This patch is based on following rework:
https://lore.kernel.org/all/20260328074013.3589544-1-ruanjinjie@huawei.com/
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will@kernel.org>
Cc: Baoquan He <bhe@redhat.com>
Cc: "Mike Rapoport (Microsoft)" <rppt@kernel.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Breno Leitao <leitao@debian.org>
Cc: Kees Cook <kees@kernel.org>
[1]: https://lore.kernel.org/all/20240529133446.28446-1-Jonathan.Cameron@huawei.com/
Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com>
---
arch/arm64/Kconfig | 3 +
arch/arm64/include/asm/kexec.h | 11 +++
arch/arm64/kernel/Makefile | 1 +
arch/arm64/kernel/crash.c | 125 +++++++++++++++++++++++++
arch/arm64/kernel/machine_kexec_file.c | 24 ++++-
5 files changed, 162 insertions(+), 2 deletions(-)
create mode 100644 arch/arm64/kernel/crash.c
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 38dba5f7e4d2..518bb59e7c19 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -1630,6 +1630,9 @@ config ARCH_DEFAULT_CRASH_DUMP
config ARCH_HAS_GENERIC_CRASHKERNEL_RESERVATION
def_bool CRASH_RESERVE
+config ARCH_SUPPORTS_CRASH_HOTPLUG
+ def_bool y
+
config TRANS_TABLE
def_bool y
depends on HIBERNATION || KEXEC_CORE
diff --git a/arch/arm64/include/asm/kexec.h b/arch/arm64/include/asm/kexec.h
index 892e5bebda95..f165c094b32e 100644
--- a/arch/arm64/include/asm/kexec.h
+++ b/arch/arm64/include/asm/kexec.h
@@ -130,6 +130,17 @@ extern int load_other_segments(struct kimage *image,
char *cmdline);
#endif
+#ifdef CONFIG_CRASH_HOTPLUG
+void arch_crash_handle_hotplug_event(struct kimage *image, void *arg);
+#define arch_crash_handle_hotplug_event arch_crash_handle_hotplug_event
+
+int arch_crash_hotplug_support(struct kimage *image, unsigned long kexec_flags);
+#define arch_crash_hotplug_support arch_crash_hotplug_support
+
+unsigned int arch_crash_get_elfcorehdr_size(void);
+#define crash_get_elfcorehdr_size arch_crash_get_elfcorehdr_size
+#endif
+
#endif /* __ASSEMBLER__ */
#endif
diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
index 76f32e424065..f66737bed1cf 100644
--- a/arch/arm64/kernel/Makefile
+++ b/arch/arm64/kernel/Makefile
@@ -64,6 +64,7 @@ obj-$(CONFIG_KEXEC_FILE) += machine_kexec_file.o kexec_image.o
obj-$(CONFIG_ARM64_RELOC_TEST) += arm64-reloc-test.o
arm64-reloc-test-y := reloc_test_core.o reloc_test_syms.o
obj-$(CONFIG_CRASH_DUMP) += crash_dump.o
+obj-$(CONFIG_CRASH_HOTPLUG) += crash.o
obj-$(CONFIG_VMCORE_INFO) += vmcore_info.o
obj-$(CONFIG_ARM_SDE_INTERFACE) += sdei.o
obj-$(CONFIG_ARM64_PTR_AUTH) += pointer_auth.o
diff --git a/arch/arm64/kernel/crash.c b/arch/arm64/kernel/crash.c
new file mode 100644
index 000000000000..2114375820da
--- /dev/null
+++ b/arch/arm64/kernel/crash.c
@@ -0,0 +1,125 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Architecture specific functions for kexec based crash dumps.
+ */
+
+#define pr_fmt(fmt) "crash hp: " fmt
+
+#include <linux/kexec.h>
+#include <linux/elf.h>
+#include <linux/vmalloc.h>
+#include <linux/crash_core.h>
+
+#include <asm/kexec.h>
+
+#ifdef CONFIG_CRASH_HOTPLUG
+
+int arch_crash_hotplug_support(struct kimage *image, unsigned long kexec_flags)
+{
+#ifdef CONFIG_KEXEC_FILE
+ if (image->file_mode)
+ return 1;
+#endif
+ /*
+ * For kexec_load syscall, crash hotplug support requires
+ * KEXEC_CRASH_HOTPLUG_SUPPORT flag to be passed by userspace.
+ */
+ return kexec_flags & KEXEC_CRASH_HOTPLUG_SUPPORT;
+}
+
+unsigned int arch_crash_get_elfcorehdr_size(void)
+{
+ unsigned int phdr_cnt;
+
+ /* A program header for possible CPUs, vmcoreinfo and kernel_map */
+ phdr_cnt = 2 + num_possible_cpus();
+ if (IS_ENABLED(CONFIG_MEMORY_HOTPLUG))
+ phdr_cnt += CONFIG_CRASH_MAX_MEMORY_RANGES;
+
+ return sizeof(Elf64_Ehdr) + phdr_cnt * sizeof(Elf64_Phdr);
+}
+
+/**
+ * update_crash_elfcorehdr() - Recreate the elfcorehdr and replace it with old
+ * elfcorehdr in the kexec segment array.
+ * @image: the active struct kimage
+ */
+static void update_crash_elfcorehdr(struct kimage *image)
+{
+ void *elfbuf = NULL, *old_elfcorehdr;
+ unsigned long mem, memsz;
+ unsigned long elfsz = 0;
+
+ /*
+ * Create the new elfcorehdr reflecting the changes to CPU and/or
+ * memory resources.
+ */
+ if (crash_prepare_headers(true, &elfbuf, &elfsz, NULL)) {
+ pr_err("unable to create new elfcorehdr");
+ goto out;
+ }
+
+ /*
+ * Obtain address and size of the elfcorehdr segment, and
+ * check it against the new elfcorehdr buffer.
+ */
+ mem = image->segment[image->elfcorehdr_index].mem;
+ memsz = image->segment[image->elfcorehdr_index].memsz;
+ if (elfsz > memsz) {
+ pr_err("update elfcorehdr elfsz %lu > memsz %lu",
+ elfsz, memsz);
+ goto out;
+ }
+
+ /*
+ * Copy new elfcorehdr over the old elfcorehdr at destination.
+ */
+ old_elfcorehdr = (void *)__va(mem);
+ if (!old_elfcorehdr) {
+ pr_err("mapping elfcorehdr segment failed\n");
+ goto out;
+ }
+
+ /*
+ * Temporarily invalidate the crash image while the
+ * elfcorehdr is updated.
+ */
+ xchg(&kexec_crash_image, NULL);
+ memcpy_flushcache(old_elfcorehdr, elfbuf, elfsz);
+ xchg(&kexec_crash_image, image);
+ pr_debug("updated elfcorehdr\n");
+
+out:
+ vfree(elfbuf);
+}
+
+/**
+ * arch_crash_handle_hotplug_event() - Handle hotplug elfcorehdr changes
+ * @image: a pointer to kexec_crash_image
+ * @arg: struct memory_notify handler for memory hotplug case and
+ * NULL for CPU hotplug case.
+ *
+ * Update the kdump image based on the type of hotplug event:
+ * - CPU add and remove: No action is needed.
+ * - Memory add/remove: Update the elfcorehdr to reflect the current memory layout.
+ *
+ * Prepare the new elfcorehdr and replace the existing elfcorehdr.
+ */
+void arch_crash_handle_hotplug_event(struct kimage *image, void *arg)
+{
+ switch (image->hp_action) {
+ case KEXEC_CRASH_HP_ADD_CPU:
+ fallthrough;
+ case KEXEC_CRASH_HP_REMOVE_CPU:
+ if (image->file_mode || image->elfcorehdr_updated)
+ return;
+ fallthrough;
+ case KEXEC_CRASH_HP_ADD_MEMORY:
+ case KEXEC_CRASH_HP_REMOVE_MEMORY:
+ update_crash_elfcorehdr(image);
+ return;
+ default:
+ pr_warn_once("Unknown hotplug action\n");
+ }
+}
+#endif /* CONFIG_CRASH_HOTPLUG */
diff --git a/arch/arm64/kernel/machine_kexec_file.c b/arch/arm64/kernel/machine_kexec_file.c
index a8fe7e65ef75..a40ca37f3d55 100644
--- a/arch/arm64/kernel/machine_kexec_file.c
+++ b/arch/arm64/kernel/machine_kexec_file.c
@@ -85,6 +85,9 @@ int load_other_segments(struct kimage *image,
void *dtb = NULL;
unsigned long initrd_load_addr = 0, dtb_len,
orig_segments = image->nr_segments;
+#ifdef CONFIG_CRASH_HOTPLUG
+ unsigned long pnum = 0;
+#endif
int ret = 0;
kbuf.image = image;
@@ -96,7 +99,7 @@ int load_other_segments(struct kimage *image,
void *headers;
unsigned long headers_sz;
if (image->type == KEXEC_TYPE_CRASH) {
- ret = crash_prepare_headers(true, &headers, &headers_sz, NULL);
+ ret = crash_prepare_headers(true, &headers, &headers_sz, &pnum);
if (ret) {
pr_err("Preparing elf core header failed\n");
goto out_err;
@@ -106,6 +109,23 @@ int load_other_segments(struct kimage *image,
kbuf.bufsz = headers_sz;
kbuf.mem = KEXEC_BUF_MEM_UNKNOWN;
kbuf.memsz = headers_sz;
+
+#ifdef CONFIG_CRASH_HOTPLUG
+ /*
+ * The elfcorehdr segment size accounts for VMCOREINFO, kernel_map
+ * maximum CPUs and maximum memory ranges.
+ */
+ if (IS_ENABLED(CONFIG_MEMORY_HOTPLUG))
+ pnum = 2 + num_possible_cpus() + CONFIG_CRASH_MAX_MEMORY_RANGES;
+ else
+ pnum += 2 + num_possible_cpus();
+
+ if (pnum < (unsigned long)PN_XNUM)
+ kbuf.memsz = pnum * sizeof(Elf64_Phdr) + sizeof(Elf64_Ehdr);
+ else
+ pr_err("number of Phdrs %lu exceeds max\n", pnum);
+#endif
+
kbuf.buf_align = SZ_64K; /* largest supported page size */
kbuf.buf_max = ULONG_MAX;
kbuf.top_down = true;
@@ -117,7 +137,7 @@ int load_other_segments(struct kimage *image,
}
image->elf_headers = headers;
image->elf_load_addr = kbuf.mem;
- image->elf_headers_sz = headers_sz;
+ image->elf_headers_sz = kbuf.memsz;
kexec_dprintk("Loaded elf core header at 0x%lx bufsz=0x%lx memsz=0x%lx\n",
image->elf_load_addr, kbuf.bufsz, kbuf.memsz);
--
2.34.1
^ permalink raw reply related
* [PATCH v6 09/10] clk: realtek: Add RTD1625-ISO clock controller driver
From: Yu-Chun Lin @ 2026-04-02 7:39 UTC (permalink / raw)
To: mturquette, sboyd, robh, krzk+dt, conor+dt, p.zabel, cylee12,
afaerber, jyanchou
Cc: devicetree, linux-clk, linux-kernel, linux-arm-kernel,
linux-realtek-soc, james.tai, cy.huang, stanley_chang,
eleanor.lin
In-Reply-To: <20260402073957.2742459-1-eleanor.lin@realtek.com>
From: Cheng-Yu Lee <cylee12@realtek.com>
Add support for the ISO (Isolation) domain clock controller on the Realtek
RTD1625 SoC. This controller manages clocks in the always-on power domain,
ensuring essential services remain functional even when the main system
power is gated.
Since the reset controller shares the same register space with the ISO
clock controller, it is instantiated as an auxiliary device by the core
clock driver. This patch also includes the corresponding auxiliary reset
driver to handle the ISO domain resets.
Signed-off-by: Cheng-Yu Lee <cylee12@realtek.com>
Co-developed-by: Yu-Chun Lin <eleanor.lin@realtek.com>
Signed-off-by: Yu-Chun Lin <eleanor.lin@realtek.com>
---
Changes in v6:
- Add the headers used in c file to follow the "Include What You Use" principle.
- Move struct rtk_reset_desc arrays from the clock driver to the dedicated reset driver.
- Implement and register a dedicated reset auxiliary driver.
---
drivers/clk/realtek/Makefile | 1 +
drivers/clk/realtek/clk-rtd1625-iso.c | 144 ++++++++++++++++++++++
drivers/reset/realtek/Makefile | 2 +-
drivers/reset/realtek/reset-rtd1625-iso.c | 96 +++++++++++++++
4 files changed, 242 insertions(+), 1 deletion(-)
create mode 100644 drivers/clk/realtek/clk-rtd1625-iso.c
create mode 100644 drivers/reset/realtek/reset-rtd1625-iso.c
diff --git a/drivers/clk/realtek/Makefile b/drivers/clk/realtek/Makefile
index c992f97dfbc7..1680435e1e0f 100644
--- a/drivers/clk/realtek/Makefile
+++ b/drivers/clk/realtek/Makefile
@@ -10,3 +10,4 @@ clk-rtk-y += freq_table.o
clk-rtk-$(CONFIG_RTK_CLK_PLL_MMC) += clk-pll-mmc.o
obj-$(CONFIG_COMMON_CLK_RTD1625) += clk-rtd1625-crt.o
+obj-$(CONFIG_COMMON_CLK_RTD1625) += clk-rtd1625-iso.o
diff --git a/drivers/clk/realtek/clk-rtd1625-iso.c b/drivers/clk/realtek/clk-rtd1625-iso.c
new file mode 100644
index 000000000000..027a131363f9
--- /dev/null
+++ b/drivers/clk/realtek/clk-rtd1625-iso.c
@@ -0,0 +1,144 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2024 Realtek Semiconductor Corporation
+ * Author: Cheng-Yu Lee <cylee12@realtek.com>
+ */
+
+#include <dt-bindings/clock/realtek,rtd1625-clk.h>
+#include <linux/array_size.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include "clk-regmap-gate.h"
+
+#define RTD1625_ISO_CLK_MAX 19
+#define RTD1625_ISO_RSTN_MAX 29
+#define RTD1625_ISO_S_CLK_MAX 5
+#define RTD1625_ISO_S_RSTN_MAX 5
+
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_usb_p4, 0, 0x4, 0, 0);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_usb_p3, 0, 0x4, 1, 0);
+static CLK_REGMAP_GATE(clk_en_misc_cec0, "clk_en_misc", 0, 0x4, 2, 0);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_cbusrx_sys, 0, 0x4, 3, 0);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_cbustx_sys, 0, 0x4, 4, 0);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_cbus_sys, 0, 0x4, 5, 0);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_cbus_osc, 0, 0x4, 6, 0);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_i2c0, 0, 0x4, 9, 0);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_i2c1, 0, 0x4, 10, 0);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_etn_250m, 0, 0x4, 11, 0);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_etn_sys, 0, 0x4, 12, 0);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_usb_drd, 0, 0x4, 13, 0);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_usb_host, 0, 0x4, 14, 0);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_usb_u3_host, 0, 0x4, 15, 0);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_usb, 0, 0x4, 16, 0);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_vtc, 0, 0x4, 17, 0);
+static CLK_REGMAP_GATE(clk_en_misc_vfd, "clk_en_misc", 0, 0x4, 18, 0);
+
+static struct clk_regmap *rtd1625_clk_regmap_list[] = {
+ &clk_en_usb_p4.clkr,
+ &clk_en_usb_p3.clkr,
+ &clk_en_misc_cec0.clkr,
+ &clk_en_cbusrx_sys.clkr,
+ &clk_en_cbustx_sys.clkr,
+ &clk_en_cbus_sys.clkr,
+ &clk_en_cbus_osc.clkr,
+ &clk_en_i2c0.clkr,
+ &clk_en_i2c1.clkr,
+ &clk_en_etn_250m.clkr,
+ &clk_en_etn_sys.clkr,
+ &clk_en_usb_drd.clkr,
+ &clk_en_usb_host.clkr,
+ &clk_en_usb_u3_host.clkr,
+ &clk_en_usb.clkr,
+ &clk_en_vtc.clkr,
+ &clk_en_misc_vfd.clkr,
+};
+
+static struct clk_hw_onecell_data rtd1625_iso_clk_data = {
+ .num = RTD1625_ISO_CLK_MAX,
+ .hws = {
+ [RTD1625_ISO_CLK_EN_USB_P4] = &__clk_regmap_gate_hw(&clk_en_usb_p4),
+ [RTD1625_ISO_CLK_EN_USB_P3] = &__clk_regmap_gate_hw(&clk_en_usb_p3),
+ [RTD1625_ISO_CLK_EN_MISC_CEC0] = &__clk_regmap_gate_hw(&clk_en_misc_cec0),
+ [RTD1625_ISO_CLK_EN_CBUSRX_SYS] = &__clk_regmap_gate_hw(&clk_en_cbusrx_sys),
+ [RTD1625_ISO_CLK_EN_CBUSTX_SYS] = &__clk_regmap_gate_hw(&clk_en_cbustx_sys),
+ [RTD1625_ISO_CLK_EN_CBUS_SYS] = &__clk_regmap_gate_hw(&clk_en_cbus_sys),
+ [RTD1625_ISO_CLK_EN_CBUS_OSC] = &__clk_regmap_gate_hw(&clk_en_cbus_osc),
+ [RTD1625_ISO_CLK_EN_I2C0] = &__clk_regmap_gate_hw(&clk_en_i2c0),
+ [RTD1625_ISO_CLK_EN_I2C1] = &__clk_regmap_gate_hw(&clk_en_i2c1),
+ [RTD1625_ISO_CLK_EN_ETN_250M] = &__clk_regmap_gate_hw(&clk_en_etn_250m),
+ [RTD1625_ISO_CLK_EN_ETN_SYS] = &__clk_regmap_gate_hw(&clk_en_etn_sys),
+ [RTD1625_ISO_CLK_EN_USB_DRD] = &__clk_regmap_gate_hw(&clk_en_usb_drd),
+ [RTD1625_ISO_CLK_EN_USB_HOST] = &__clk_regmap_gate_hw(&clk_en_usb_host),
+ [RTD1625_ISO_CLK_EN_USB_U3_HOST] = &__clk_regmap_gate_hw(&clk_en_usb_u3_host),
+ [RTD1625_ISO_CLK_EN_USB] = &__clk_regmap_gate_hw(&clk_en_usb),
+ [RTD1625_ISO_CLK_EN_VTC] = &__clk_regmap_gate_hw(&clk_en_vtc),
+ [RTD1625_ISO_CLK_EN_MISC_VFD] = &__clk_regmap_gate_hw(&clk_en_misc_vfd),
+ [RTD1625_ISO_CLK_MAX] = NULL,
+ },
+};
+
+static const struct rtk_clk_desc rtd1625_iso_desc = {
+ .clk_data = &rtd1625_iso_clk_data,
+ .clks = rtd1625_clk_regmap_list,
+ .num_clks = ARRAY_SIZE(rtd1625_clk_regmap_list),
+};
+
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_irda, 0, 0x4, 6, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_ur10, 0, 0x4, 8, 1);
+
+static struct clk_regmap *rtd1625_iso_s_clk_regmap_list[] = {
+ &clk_en_irda.clkr,
+ &clk_en_ur10.clkr,
+};
+
+static struct clk_hw_onecell_data rtd1625_iso_s_clk_data = {
+ .num = RTD1625_ISO_S_CLK_MAX,
+ .hws = {
+ [RTD1625_ISO_S_CLK_EN_IRDA] = &__clk_regmap_gate_hw(&clk_en_irda),
+ [RTD1625_ISO_S_CLK_EN_UR10] = &__clk_regmap_gate_hw(&clk_en_ur10),
+ [RTD1625_ISO_S_CLK_MAX] = NULL,
+ },
+};
+
+static const struct rtk_clk_desc rtd1625_iso_s_desc = {
+ .clk_data = &rtd1625_iso_s_clk_data,
+ .clks = rtd1625_iso_s_clk_regmap_list,
+ .num_clks = ARRAY_SIZE(rtd1625_iso_s_clk_regmap_list),
+};
+
+static int rtd1625_iso_probe(struct platform_device *pdev)
+{
+ const struct rtk_clk_desc *desc;
+
+ desc = of_device_get_match_data(&pdev->dev);
+ if (!desc)
+ return -EINVAL;
+ return rtk_clk_probe(pdev, desc, "iso_rst");
+}
+
+static const struct of_device_id rtd1625_iso_match[] = {
+ {.compatible = "realtek,rtd1625-iso-clk", .data = &rtd1625_iso_desc},
+ {.compatible = "realtek,rtd1625-iso-s-clk", .data = &rtd1625_iso_s_desc},
+ { /* sentinel */ }
+};
+
+static struct platform_driver rtd1625_iso_driver = {
+ .probe = rtd1625_iso_probe,
+ .driver = {
+ .name = "rtk-rtd1625-iso-clk",
+ .of_match_table = rtd1625_iso_match,
+ },
+};
+
+static int __init rtd1625_iso_init(void)
+{
+ return platform_driver_register(&rtd1625_iso_driver);
+}
+subsys_initcall(rtd1625_iso_init);
+
+MODULE_DESCRIPTION("Realtek RTD1625 ISO Controller Driver");
+MODULE_AUTHOR("Cheng-Yu Lee <cylee12@realtek.com>");
+MODULE_LICENSE("GPL");
+MODULE_IMPORT_NS("REALTEK_CLK");
diff --git a/drivers/reset/realtek/Makefile b/drivers/reset/realtek/Makefile
index 8ca1fa939f10..26b3ddc75ada 100644
--- a/drivers/reset/realtek/Makefile
+++ b/drivers/reset/realtek/Makefile
@@ -1,2 +1,2 @@
# SPDX-License-Identifier: GPL-2.0-only
-obj-$(CONFIG_RESET_RTK_COMMON) += common.o reset-rtd1625-crt.o
+obj-$(CONFIG_RESET_RTK_COMMON) += common.o reset-rtd1625-crt.o reset-rtd1625-iso.o
diff --git a/drivers/reset/realtek/reset-rtd1625-iso.c b/drivers/reset/realtek/reset-rtd1625-iso.c
new file mode 100644
index 000000000000..f2a0478382ae
--- /dev/null
+++ b/drivers/reset/realtek/reset-rtd1625-iso.c
@@ -0,0 +1,96 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2026 Realtek Semiconductor Corporation
+ */
+
+#include <dt-bindings/reset/realtek,rtd1625.h>
+#include <linux/auxiliary_bus.h>
+#include <linux/device.h>
+#include <linux/errno.h>
+#include <linux/of.h>
+#include <linux/slab.h>
+#include "common.h"
+
+#define RTD1625_ISO_RSTN_MAX 29
+#define RTD1625_ISO_S_RSTN_MAX 5
+
+static struct rtk_reset_desc rtd1625_iso_reset_descs[] = {
+ [RTD1625_ISO_RSTN_VFD] = { .ofs = 0x88, .bit = 0 },
+ [RTD1625_ISO_RSTN_CEC0] = { .ofs = 0x88, .bit = 2 },
+ [RTD1625_ISO_RSTN_CEC1] = { .ofs = 0x88, .bit = 3 },
+ [RTD1625_ISO_RSTN_CBUSTX] = { .ofs = 0x88, .bit = 5 },
+ [RTD1625_ISO_RSTN_CBUSRX] = { .ofs = 0x88, .bit = 6 },
+ [RTD1625_ISO_RSTN_USB3_PHY2_XTAL_POW] = { .ofs = 0x88, .bit = 7 },
+ [RTD1625_ISO_RSTN_UR0] = { .ofs = 0x88, .bit = 8 },
+ [RTD1625_ISO_RSTN_GMAC] = { .ofs = 0x88, .bit = 9 },
+ [RTD1625_ISO_RSTN_GPHY] = { .ofs = 0x88, .bit = 10 },
+ [RTD1625_ISO_RSTN_I2C_0] = { .ofs = 0x88, .bit = 11 },
+ [RTD1625_ISO_RSTN_I2C_1] = { .ofs = 0x88, .bit = 12 },
+ [RTD1625_ISO_RSTN_CBUS] = { .ofs = 0x88, .bit = 13 },
+ [RTD1625_ISO_RSTN_USB_DRD] = { .ofs = 0x88, .bit = 14 },
+ [RTD1625_ISO_RSTN_USB_HOST] = { .ofs = 0x88, .bit = 15 },
+ [RTD1625_ISO_RSTN_USB_PHY_0] = { .ofs = 0x88, .bit = 16 },
+ [RTD1625_ISO_RSTN_USB_PHY_1] = { .ofs = 0x88, .bit = 17 },
+ [RTD1625_ISO_RSTN_USB_PHY_2] = { .ofs = 0x88, .bit = 18 },
+ [RTD1625_ISO_RSTN_USB] = { .ofs = 0x88, .bit = 19 },
+ [RTD1625_ISO_RSTN_TYPE_C] = { .ofs = 0x88, .bit = 20 },
+ [RTD1625_ISO_RSTN_USB_U3_HOST] = { .ofs = 0x88, .bit = 21 },
+ [RTD1625_ISO_RSTN_USB3_PHY0_POW] = { .ofs = 0x88, .bit = 22 },
+ [RTD1625_ISO_RSTN_USB3_P0_MDIO] = { .ofs = 0x88, .bit = 23 },
+ [RTD1625_ISO_RSTN_USB3_PHY1_POW] = { .ofs = 0x88, .bit = 24 },
+ [RTD1625_ISO_RSTN_USB3_P1_MDIO] = { .ofs = 0x88, .bit = 25 },
+ [RTD1625_ISO_RSTN_VTC] = { .ofs = 0x88, .bit = 26 },
+ [RTD1625_ISO_RSTN_USB3_PHY2_POW] = { .ofs = 0x88, .bit = 27 },
+ [RTD1625_ISO_RSTN_USB3_P2_MDIO] = { .ofs = 0x88, .bit = 28 },
+ [RTD1625_ISO_RSTN_USB_PHY_3] = { .ofs = 0x88, .bit = 29 },
+ [RTD1625_ISO_RSTN_USB_PHY_4] = { .ofs = 0x88, .bit = 30 },
+};
+
+static struct rtk_reset_desc rtd1625_iso_s_reset_descs[] = {
+ [RTD1625_ISO_S_RSTN_ISOM_MIS] = { .ofs = 0x310, .bit = 0, .write_en = 1 },
+ [RTD1625_ISO_S_RSTN_GPIOM] = { .ofs = 0x310, .bit = 2, .write_en = 1 },
+ [RTD1625_ISO_S_RSTN_TIMER7] = { .ofs = 0x310, .bit = 4, .write_en = 1 },
+ [RTD1625_ISO_S_RSTN_IRDA] = { .ofs = 0x310, .bit = 6, .write_en = 1 },
+ [RTD1625_ISO_S_RSTN_UR10] = { .ofs = 0x310, .bit = 8, .write_en = 1 },
+};
+
+static int rtd1625_iso_reset_probe(struct auxiliary_device *adev,
+ const struct auxiliary_device_id *id)
+{
+ struct device *dev = &adev->dev;
+ struct device *parent = dev->parent;
+ struct rtk_reset_data *data;
+
+ data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
+
+ if (of_device_is_compatible(parent->of_node, "realtek,rtd1625-iso-s-clk")) {
+ data->descs = rtd1625_iso_s_reset_descs;
+ data->rcdev.nr_resets = RTD1625_ISO_S_RSTN_MAX;
+ } else {
+ data->descs = rtd1625_iso_reset_descs;
+ data->rcdev.nr_resets = RTD1625_ISO_RSTN_MAX;
+ }
+ return rtk_reset_controller_add(dev, data);
+}
+
+static const struct auxiliary_device_id rtd1625_iso_reset_ids[] = {
+ {
+ .name = "clk_rtk.iso_rst",
+ },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(auxiliary, rtd1625_iso_reset_ids);
+
+static struct auxiliary_driver rtd1625_iso_driver = {
+ .probe = rtd1625_iso_reset_probe,
+ .id_table = rtd1625_iso_reset_ids,
+ .driver = {
+ .name = "rtd1625-iso-reset",
+ },
+};
+module_auxiliary_driver(rtd1625_iso_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_IMPORT_NS("REALTEK_RESET");
--
2.34.1
^ permalink raw reply related
* [PATCH v6 03/10] clk: realtek: Introduce a common probe()
From: Yu-Chun Lin @ 2026-04-02 7:39 UTC (permalink / raw)
To: mturquette, sboyd, robh, krzk+dt, conor+dt, p.zabel, cylee12,
afaerber, jyanchou
Cc: devicetree, linux-clk, linux-kernel, linux-arm-kernel,
linux-realtek-soc, james.tai, cy.huang, stanley_chang,
eleanor.lin
In-Reply-To: <20260402073957.2742459-1-eleanor.lin@realtek.com>
From: Cheng-Yu Lee <cylee12@realtek.com>
Add rtk_clk_probe() to set up the shared regmap, register clock hardware,
and add the clock provider.
Additionally, if the "#reset-cells" property is present in the device tree,
it creates and registers an auxiliary device using the provided aux_name.
This allows the dedicated reset driver to bind to this device, enabling
both clock and reset drivers to share the same regmap.
Signed-off-by: Cheng-Yu Lee <cylee12@realtek.com>
Co-developed-by: Yu-Chun Lin <eleanor.lin@realtek.com>
Signed-off-by: Yu-Chun Lin <eleanor.lin@realtek.com>
---
Changes in v6:
- Replace direct reset controller initialization with auxiliary device creation.
- Add aux_name parameter to rtk_clk_probe() to register the reset auxiliary device.
- Simplify rtk_clk_desc because reset data is handled entirely by the auxiliary reset driver.
- In Kconfig, change "depends on RESET_CONTROLLER" to "select RESET_CONTROLLER"
- Remove unused includes headers and added <linux/auxiliary_bus.h>.
---
MAINTAINERS | 1 +
drivers/clk/Kconfig | 1 +
drivers/clk/Makefile | 1 +
drivers/clk/realtek/Kconfig | 28 +++++++++++++++
drivers/clk/realtek/Makefile | 4 +++
drivers/clk/realtek/common.c | 67 ++++++++++++++++++++++++++++++++++++
drivers/clk/realtek/common.h | 37 ++++++++++++++++++++
7 files changed, 139 insertions(+)
create mode 100644 drivers/clk/realtek/Kconfig
create mode 100644 drivers/clk/realtek/Makefile
create mode 100644 drivers/clk/realtek/common.c
create mode 100644 drivers/clk/realtek/common.h
diff --git a/MAINTAINERS b/MAINTAINERS
index 8f355896583b..8318156a02b5 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -22240,6 +22240,7 @@ L: devicetree@vger.kernel.org
L: linux-clk@vger.kernel.org
S: Supported
F: Documentation/devicetree/bindings/clock/realtek*
+F: drivers/clk/realtek/*
F: drivers/reset/realtek/*
F: include/dt-bindings/clock/realtek*
F: include/dt-bindings/reset/realtek*
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index 3d803b4cf5c1..d60f6415b0a3 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -519,6 +519,7 @@ source "drivers/clk/nuvoton/Kconfig"
source "drivers/clk/pistachio/Kconfig"
source "drivers/clk/qcom/Kconfig"
source "drivers/clk/ralink/Kconfig"
+source "drivers/clk/realtek/Kconfig"
source "drivers/clk/renesas/Kconfig"
source "drivers/clk/rockchip/Kconfig"
source "drivers/clk/samsung/Kconfig"
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index f7bce3951a30..69b84d1e7bcc 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -140,6 +140,7 @@ obj-$(CONFIG_COMMON_CLK_PISTACHIO) += pistachio/
obj-$(CONFIG_COMMON_CLK_PXA) += pxa/
obj-$(CONFIG_COMMON_CLK_QCOM) += qcom/
obj-y += ralink/
+obj-$(CONFIG_COMMON_CLK_REALTEK) += realtek/
obj-y += renesas/
obj-$(CONFIG_ARCH_ROCKCHIP) += rockchip/
obj-$(CONFIG_COMMON_CLK_SAMSUNG) += samsung/
diff --git a/drivers/clk/realtek/Kconfig b/drivers/clk/realtek/Kconfig
new file mode 100644
index 000000000000..bc47d3f1c452
--- /dev/null
+++ b/drivers/clk/realtek/Kconfig
@@ -0,0 +1,28 @@
+# SPDX-License-Identifier: GPL-2.0-only
+config COMMON_CLK_REALTEK
+ bool "Clock driver for Realtek SoCs"
+ depends on ARCH_REALTEK || COMPILE_TEST
+ default ARCH_REALTEK
+ help
+ Enable the common clock framework infrastructure for Realtek
+ system-on-chip platforms.
+
+ This provides the base support required by individual Realtek
+ clock controller drivers to expose clocks to peripheral devices.
+
+ If you have a Realtek-based platform, say Y.
+
+if COMMON_CLK_REALTEK
+
+config RTK_CLK_COMMON
+ tristate "Realtek Clock Common"
+ select RESET_CONTROLLER
+ select RESET_RTK_COMMON
+ help
+ Common helper code shared by Realtek clock controller drivers.
+
+ This provides utility functions and data structures used by
+ multiple Realtek clock implementations, and include integration
+ with reset controllers where required.
+
+endif
diff --git a/drivers/clk/realtek/Makefile b/drivers/clk/realtek/Makefile
new file mode 100644
index 000000000000..377ec776ee47
--- /dev/null
+++ b/drivers/clk/realtek/Makefile
@@ -0,0 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0-only
+obj-$(CONFIG_RTK_CLK_COMMON) += clk-rtk.o
+
+clk-rtk-y += common.o
diff --git a/drivers/clk/realtek/common.c b/drivers/clk/realtek/common.c
new file mode 100644
index 000000000000..c5aea15a3714
--- /dev/null
+++ b/drivers/clk/realtek/common.c
@@ -0,0 +1,67 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2019 Realtek Semiconductor Corporation
+ * Author: Cheng-Yu Lee <cylee12@realtek.com>
+ */
+
+#include <linux/auxiliary_bus.h>
+#include <linux/device.h>
+#include <linux/mfd/syscon.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include "common.h"
+
+static int rtk_reset_controller_register(struct device *dev, const char *aux_name)
+{
+ struct auxiliary_device *adev;
+
+ if (!of_property_present(dev->of_node, "#reset-cells"))
+ return 0;
+
+ adev = devm_auxiliary_device_create(dev, aux_name, NULL);
+
+ if (IS_ERR(adev))
+ return PTR_ERR(adev);
+ return 0;
+}
+
+int rtk_clk_probe(struct platform_device *pdev, const struct rtk_clk_desc *desc,
+ const char *aux_name)
+{
+ int i, ret;
+ struct regmap *regmap;
+ struct device *dev = &pdev->dev;
+
+ regmap = device_node_to_regmap(pdev->dev.of_node);
+ if (IS_ERR(regmap))
+ return dev_err_probe(dev, PTR_ERR(regmap), "failed to get regmap\n");
+
+ for (i = 0; i < desc->num_clks; i++)
+ desc->clks[i]->regmap = regmap;
+
+ for (i = 0; i < desc->clk_data->num; i++) {
+ struct clk_hw *hw = desc->clk_data->hws[i];
+
+ if (!hw)
+ continue;
+
+ ret = devm_clk_hw_register(dev, hw);
+
+ if (ret) {
+ dev_warn(dev, "failed to register hw of clk%d: %d\n", i,
+ ret);
+ desc->clk_data->hws[i] = NULL;
+ }
+ }
+
+ ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get,
+ desc->clk_data);
+ if (ret)
+ return dev_err_probe(dev, ret, "failed to add clock provider\n");
+
+ return rtk_reset_controller_register(dev, aux_name);
+}
+EXPORT_SYMBOL_NS_GPL(rtk_clk_probe, "REALTEK_CLK");
+
+MODULE_DESCRIPTION("Realtek clock infrastructure");
+MODULE_LICENSE("GPL");
diff --git a/drivers/clk/realtek/common.h b/drivers/clk/realtek/common.h
new file mode 100644
index 000000000000..93a746d9bbf0
--- /dev/null
+++ b/drivers/clk/realtek/common.h
@@ -0,0 +1,37 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2016-2019 Realtek Semiconductor Corporation
+ * Author: Cheng-Yu Lee <cylee12@realtek.com>
+ */
+
+#ifndef __CLK_REALTEK_COMMON_H
+#define __CLK_REALTEK_COMMON_H
+
+#include <linux/clk-provider.h>
+
+#define __clk_regmap_hw(_p) ((_p)->hw)
+
+struct device;
+struct platform_device;
+struct regmap;
+
+struct clk_regmap {
+ struct clk_hw hw;
+ struct regmap *regmap;
+};
+
+struct rtk_clk_desc {
+ struct clk_hw_onecell_data *clk_data;
+ struct clk_regmap **clks;
+ size_t num_clks;
+};
+
+static inline struct clk_regmap *to_clk_regmap(struct clk_hw *hw)
+{
+ return container_of(hw, struct clk_regmap, hw);
+}
+
+int rtk_clk_probe(struct platform_device *pdev, const struct rtk_clk_desc *desc,
+ const char *aux_name);
+
+#endif /* __CLK_REALTEK_COMMON_H */
--
2.34.1
^ permalink raw reply related
* [PATCH v6 04/10] clk: realtek: Add support for phase locked loops (PLLs)
From: Yu-Chun Lin @ 2026-04-02 7:39 UTC (permalink / raw)
To: mturquette, sboyd, robh, krzk+dt, conor+dt, p.zabel, cylee12,
afaerber, jyanchou
Cc: devicetree, linux-clk, linux-kernel, linux-arm-kernel,
linux-realtek-soc, james.tai, cy.huang, stanley_chang,
eleanor.lin
In-Reply-To: <20260402073957.2742459-1-eleanor.lin@realtek.com>
From: Cheng-Yu Lee <cylee12@realtek.com>
Provide a full set of PLL operations for programmable PLLs and a read-only
variant for fixed or hardware-managed PLLs.
Signed-off-by: Cheng-Yu Lee <cylee12@realtek.com>
Co-developed-by: Yu-Chun Lin <eleanor.lin@realtek.com>
Signed-off-by: Yu-Chun Lin <eleanor.lin@realtek.com>
---
Changes in v6:
- Add the headers used in c file to follow the "Include What You Use" principle.
- Move to_clk_pll() from clk-pll.h to clk-pll.c to limit its scope.
---
drivers/clk/realtek/Makefile | 2 +
drivers/clk/realtek/clk-pll.c | 164 +++++++++++++++++++++++++++++++
drivers/clk/realtek/clk-pll.h | 42 ++++++++
drivers/clk/realtek/freq_table.c | 36 +++++++
drivers/clk/realtek/freq_table.h | 21 ++++
5 files changed, 265 insertions(+)
create mode 100644 drivers/clk/realtek/clk-pll.c
create mode 100644 drivers/clk/realtek/clk-pll.h
create mode 100644 drivers/clk/realtek/freq_table.c
create mode 100644 drivers/clk/realtek/freq_table.h
diff --git a/drivers/clk/realtek/Makefile b/drivers/clk/realtek/Makefile
index 377ec776ee47..a89ad77993e9 100644
--- a/drivers/clk/realtek/Makefile
+++ b/drivers/clk/realtek/Makefile
@@ -2,3 +2,5 @@
obj-$(CONFIG_RTK_CLK_COMMON) += clk-rtk.o
clk-rtk-y += common.o
+clk-rtk-y += clk-pll.o
+clk-rtk-y += freq_table.o
diff --git a/drivers/clk/realtek/clk-pll.c b/drivers/clk/realtek/clk-pll.c
new file mode 100644
index 000000000000..44730b22a94c
--- /dev/null
+++ b/drivers/clk/realtek/clk-pll.c
@@ -0,0 +1,164 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2024 Realtek Semiconductor Corporation
+ * Author: Cheng-Yu Lee <cylee12@realtek.com>
+ */
+
+#include <linux/regmap.h>
+#include "clk-pll.h"
+
+#define TIMEOUT 2000
+
+static inline struct clk_pll *to_clk_pll(struct clk_hw *hw)
+{
+ struct clk_regmap *clkr = to_clk_regmap(hw);
+
+ return container_of(clkr, struct clk_pll, clkr);
+}
+
+static int wait_freq_ready(struct clk_pll *clkp)
+{
+ u32 pollval;
+
+ if (!clkp->freq_ready_valid)
+ return 0;
+
+ return regmap_read_poll_timeout_atomic(clkp->clkr.regmap, clkp->freq_ready_reg, pollval,
+ (pollval & clkp->freq_ready_mask)
+ == clkp->freq_ready_val, 0, TIMEOUT);
+}
+
+static bool is_power_on(struct clk_pll *clkp)
+{
+ u32 val;
+
+ if (!clkp->power_reg)
+ return true;
+
+ if (regmap_read(clkp->clkr.regmap, clkp->power_reg, &val))
+ return true;
+
+ return (val & clkp->power_mask) == clkp->power_val_on;
+}
+
+static void clk_pll_disable(struct clk_hw *hw)
+{
+ struct clk_pll *clkp = to_clk_pll(hw);
+
+ if (!clkp->seq_power_off)
+ return;
+
+ regmap_multi_reg_write(clkp->clkr.regmap, clkp->seq_power_off,
+ clkp->num_seq_power_off);
+}
+
+static int clk_pll_is_enabled(struct clk_hw *hw)
+{
+ struct clk_pll *clkp = to_clk_pll(hw);
+
+ return is_power_on(clkp);
+}
+
+static int clk_pll_determine_rate(struct clk_hw *hw,
+ struct clk_rate_request *req)
+{
+ struct clk_pll *clkp = to_clk_pll(hw);
+ const struct freq_table *ftblv = NULL;
+
+ ftblv = ftbl_find_by_rate(clkp->freq_tbl, req->rate);
+ if (!ftblv)
+ return -EINVAL;
+
+ req->rate = ftblv->rate;
+ return 0;
+}
+
+static unsigned long clk_pll_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ struct clk_pll *clkp = to_clk_pll(hw);
+ const struct freq_table *fv;
+ u32 freq_val;
+
+ if (regmap_read(clkp->clkr.regmap, clkp->freq_reg, &freq_val))
+ return 0;
+
+ freq_val &= clkp->freq_mask;
+
+ fv = ftbl_find_by_val_with_mask(clkp->freq_tbl, clkp->freq_mask,
+ freq_val);
+ return fv ? fv->rate : 0;
+}
+
+static int clk_pll_set_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long parent_rate)
+{
+ struct clk_pll *clkp = to_clk_pll(hw);
+ const struct freq_table *fv;
+ int ret;
+
+ fv = ftbl_find_by_rate(clkp->freq_tbl, rate);
+ if (!fv || fv->rate != rate)
+ return -EINVAL;
+
+ if (clkp->seq_pre_set_freq) {
+ ret = regmap_multi_reg_write(clkp->clkr.regmap, clkp->seq_pre_set_freq,
+ clkp->num_seq_pre_set_freq);
+ if (ret)
+ return ret;
+ }
+
+ ret = regmap_update_bits(clkp->clkr.regmap, clkp->freq_reg,
+ clkp->freq_mask, fv->val);
+ if (ret)
+ return ret;
+
+ if (clkp->seq_post_set_freq) {
+ ret = regmap_multi_reg_write(clkp->clkr.regmap, clkp->seq_post_set_freq,
+ clkp->num_seq_post_set_freq);
+ if (ret)
+ return ret;
+ }
+
+ if (is_power_on(clkp)) {
+ ret = wait_freq_ready(clkp);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
+static int clk_pll_enable(struct clk_hw *hw)
+{
+ struct clk_pll *clkp = to_clk_pll(hw);
+ int ret;
+
+ if (!clkp->seq_power_on)
+ return 0;
+
+ if (is_power_on(clkp))
+ return 0;
+
+ ret = regmap_multi_reg_write(clkp->clkr.regmap, clkp->seq_power_on,
+ clkp->num_seq_power_on);
+ if (ret)
+ return ret;
+
+ return wait_freq_ready(clkp);
+}
+
+const struct clk_ops rtk_clk_pll_ops = {
+ .enable = clk_pll_enable,
+ .disable = clk_pll_disable,
+ .is_enabled = clk_pll_is_enabled,
+ .recalc_rate = clk_pll_recalc_rate,
+ .determine_rate = clk_pll_determine_rate,
+ .set_rate = clk_pll_set_rate,
+};
+EXPORT_SYMBOL_NS_GPL(rtk_clk_pll_ops, "REALTEK_CLK");
+
+const struct clk_ops rtk_clk_pll_ro_ops = {
+ .recalc_rate = clk_pll_recalc_rate,
+};
+EXPORT_SYMBOL_NS_GPL(rtk_clk_pll_ro_ops, "REALTEK_CLK");
diff --git a/drivers/clk/realtek/clk-pll.h b/drivers/clk/realtek/clk-pll.h
new file mode 100644
index 000000000000..00884585a242
--- /dev/null
+++ b/drivers/clk/realtek/clk-pll.h
@@ -0,0 +1,42 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2017-2019 Realtek Semiconductor Corporation
+ * Author: Cheng-Yu Lee <cylee12@realtek.com>
+ */
+
+#ifndef __CLK_REALTEK_CLK_PLL_H
+#define __CLK_REALTEK_CLK_PLL_H
+
+#include "common.h"
+#include "freq_table.h"
+
+struct reg_sequence;
+
+struct clk_pll {
+ struct clk_regmap clkr;
+ const struct reg_sequence *seq_power_on;
+ u32 num_seq_power_on;
+ const struct reg_sequence *seq_power_off;
+ u32 num_seq_power_off;
+ const struct reg_sequence *seq_pre_set_freq;
+ u32 num_seq_pre_set_freq;
+ const struct reg_sequence *seq_post_set_freq;
+ u32 num_seq_post_set_freq;
+ const struct freq_table *freq_tbl;
+ u32 freq_reg;
+ u32 freq_mask;
+ u32 freq_ready_valid;
+ u32 freq_ready_mask;
+ u32 freq_ready_reg;
+ u32 freq_ready_val;
+ u32 power_reg;
+ u32 power_mask;
+ u32 power_val_on;
+};
+
+#define __clk_pll_hw(_ptr) __clk_regmap_hw(&(_ptr)->clkr)
+
+extern const struct clk_ops rtk_clk_pll_ops;
+extern const struct clk_ops rtk_clk_pll_ro_ops;
+
+#endif /* __CLK_REALTEK_CLK_PLL_H */
diff --git a/drivers/clk/realtek/freq_table.c b/drivers/clk/realtek/freq_table.c
new file mode 100644
index 000000000000..272a10e75a54
--- /dev/null
+++ b/drivers/clk/realtek/freq_table.c
@@ -0,0 +1,36 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include <linux/bitops.h>
+#include "freq_table.h"
+
+const struct freq_table *ftbl_find_by_rate(const struct freq_table *ftbl,
+ unsigned long rate)
+{
+ unsigned long best_rate = 0;
+ const struct freq_table *best = NULL;
+
+ for (; !IS_FREQ_TABLE_END(ftbl); ftbl++) {
+ if (ftbl->rate == rate)
+ return ftbl;
+
+ if (ftbl->rate > rate)
+ continue;
+
+ if (ftbl->rate > best_rate) {
+ best_rate = ftbl->rate;
+ best = ftbl;
+ }
+ }
+
+ return best;
+}
+
+const struct freq_table *
+ftbl_find_by_val_with_mask(const struct freq_table *ftbl, u32 mask, u32 value)
+{
+ for (; !IS_FREQ_TABLE_END(ftbl); ftbl++) {
+ if ((ftbl->val & mask) == (value & mask))
+ return ftbl;
+ }
+ return NULL;
+};
diff --git a/drivers/clk/realtek/freq_table.h b/drivers/clk/realtek/freq_table.h
new file mode 100644
index 000000000000..6d9116651105
--- /dev/null
+++ b/drivers/clk/realtek/freq_table.h
@@ -0,0 +1,21 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+struct freq_table {
+ u32 val;
+ unsigned long rate;
+};
+
+/* ofs check */
+#define CLK_OFS_INVALID -1
+#define CLK_OFS_IS_VALID(_ofs) ((_ofs) != CLK_OFS_INVALID)
+
+#define FREQ_TABLE_END \
+ { \
+ .rate = 0 \
+ }
+#define IS_FREQ_TABLE_END(_f) ((_f)->rate == 0)
+
+const struct freq_table *ftbl_find_by_rate(const struct freq_table *ftbl,
+ unsigned long rate);
+const struct freq_table *
+ftbl_find_by_val_with_mask(const struct freq_table *ftbl, u32 mask, u32 value);
--
2.34.1
^ permalink raw reply related
* [PATCH v6 07/10] clk: realtek: Add support for MMC-tuned PLL clocks
From: Yu-Chun Lin @ 2026-04-02 7:39 UTC (permalink / raw)
To: mturquette, sboyd, robh, krzk+dt, conor+dt, p.zabel, cylee12,
afaerber, jyanchou
Cc: devicetree, linux-clk, linux-kernel, linux-arm-kernel,
linux-realtek-soc, james.tai, cy.huang, stanley_chang,
eleanor.lin
In-Reply-To: <20260402073957.2742459-1-eleanor.lin@realtek.com>
From: Cheng-Yu Lee <cylee12@realtek.com>
Add clk_pll_mmc_ops for enable/disable, prepare, rate control, and status
operations on MMC PLL clocks.
Also add clk_pll_mmc_phase_ops to support phase get/set operations.
Signed-off-by: Cheng-Yu Lee <cylee12@realtek.com>
Co-developed-by: Jyan Chou <jyanchou@realtek.com>
Signed-off-by: Jyan Chou <jyanchou@realtek.com>
Co-developed-by: Yu-Chun Lin <eleanor.lin@realtek.com>
Signed-off-by: Yu-Chun Lin <eleanor.lin@realtek.com>
---
Changes in v6:
- Add the headers used in c file to follow the "Include What You Use" principle.
- Move to_clk_pll_mmc() from clk-pll.h to clk-pll-mmc.c to limit its scope.
- Change offset type from int to unsigned int.
---
MAINTAINERS | 8 +
drivers/clk/realtek/Kconfig | 3 +
drivers/clk/realtek/Makefile | 2 +
drivers/clk/realtek/clk-pll-mmc.c | 410 ++++++++++++++++++++++++++++++
drivers/clk/realtek/clk-pll.h | 13 +
5 files changed, 436 insertions(+)
create mode 100644 drivers/clk/realtek/clk-pll-mmc.c
diff --git a/MAINTAINERS b/MAINTAINERS
index 8318156a02b5..4b28af4b26b5 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -22245,6 +22245,14 @@ F: drivers/reset/realtek/*
F: include/dt-bindings/clock/realtek*
F: include/dt-bindings/reset/realtek*
+REALTEK SOC PLL CLOCK FOR MMC SUPPORT
+M: Cheng-Yu Lee <cylee12@realtek.com>
+M: Jyan Chou <jyanchou@realtek.com>
+M: Yu-Chun Lin <eleanor.lin@realtek.com>
+L: linux-clk@vger.kernel.org
+S: Supported
+F: drivers/clk/realtek/clk-pll-mmc.c
+
REALTEK SPI-NAND
M: Chris Packham <chris.packham@alliedtelesis.co.nz>
S: Maintained
diff --git a/drivers/clk/realtek/Kconfig b/drivers/clk/realtek/Kconfig
index bc47d3f1c452..b31a31e57b3a 100644
--- a/drivers/clk/realtek/Kconfig
+++ b/drivers/clk/realtek/Kconfig
@@ -25,4 +25,7 @@ config RTK_CLK_COMMON
multiple Realtek clock implementations, and include integration
with reset controllers where required.
+config RTK_CLK_PLL_MMC
+ bool
+
endif
diff --git a/drivers/clk/realtek/Makefile b/drivers/clk/realtek/Makefile
index f90dc57fcfdb..fd7d777902c8 100644
--- a/drivers/clk/realtek/Makefile
+++ b/drivers/clk/realtek/Makefile
@@ -7,3 +7,5 @@ clk-rtk-y += clk-pll.o
clk-rtk-y += clk-regmap-gate.o
clk-rtk-y += clk-regmap-mux.o
clk-rtk-y += freq_table.o
+
+clk-rtk-$(CONFIG_RTK_CLK_PLL_MMC) += clk-pll-mmc.o
diff --git a/drivers/clk/realtek/clk-pll-mmc.c b/drivers/clk/realtek/clk-pll-mmc.c
new file mode 100644
index 000000000000..d28c7027d3f0
--- /dev/null
+++ b/drivers/clk/realtek/clk-pll-mmc.c
@@ -0,0 +1,410 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2021 Realtek Semiconductor Corporation
+ * Author: Cheng-Yu Lee <cylee12@realtek.com>
+ */
+
+#include <linux/bits.h>
+#include <linux/module.h>
+#include <linux/regmap.h>
+#include "clk-pll.h"
+
+#define PLL_EMMC1_OFFSET 0x0
+#define PLL_EMMC2_OFFSET 0x4
+#define PLL_EMMC3_OFFSET 0x8
+#define PLL_EMMC4_OFFSET 0xc
+#define PLL_SSC_DIG_EMMC1_OFFSET 0x0
+#define PLL_SSC_DIG_EMMC3_OFFSET 0xc
+#define PLL_SSC_DIG_EMMC4_OFFSET 0x10
+
+#define PLL_MMC_SSC_DIV_N_VAL 0x1b
+
+#define PLL_PHRT0_MASK BIT(1)
+#define PLL_PHSEL_MASK GENMASK(4, 0)
+#define PLL_SSCPLL_RS_MASK GENMASK(12, 10)
+#define PLL_SSCPLL_ICP_MASK GENMASK(9, 5)
+#define PLL_SSC_DIV_EXT_F_MASK GENMASK(25, 13)
+#define PLL_PI_IBSELH_MASK GENMASK(28, 27)
+#define PLL_SSC_DIV_N_MASK GENMASK(23, 16)
+#define PLL_NCODE_SSC_EMMC_MASK GENMASK(20, 13)
+#define PLL_FCODE_SSC_EMMC_MASK GENMASK(12, 0)
+#define PLL_GRAN_EST_EM_MC_MASK GENMASK(20, 0)
+#define PLL_EN_SSC_EMMC_MASK BIT(0)
+#define PLL_FLAG_INITAL_EMMC_MASK BIT(1)
+
+#define PLL_PHRT0_SHIFT 1
+#define PLL_SSCPLL_RS_SHIFT 10
+#define PLL_SSCPLL_ICP_SHIFT 5
+#define PLL_SSC_DIV_EXT_F_SHIFT 13
+#define PLL_PI_IBSELH_SHIFT 27
+#define PLL_SSC_DIV_N_SHIFT 16
+#define PLL_NCODE_SSC_EMMC_SHIFT 13
+#define PLL_FLAG_INITAL_EMMC_SHIFT 8
+
+#define CYCLE_DEGREES 360
+#define PHASE_STEPS 32
+#define PHASE_SCALE_FACTOR 1125
+
+static inline struct clk_pll_mmc *to_clk_pll_mmc(struct clk_hw *hw)
+{
+ struct clk_regmap *clkr = to_clk_regmap(hw);
+
+ return container_of(clkr, struct clk_pll_mmc, clkr);
+}
+
+static inline int get_phrt0(struct clk_pll_mmc *clkm, u32 *val)
+{
+ u32 reg;
+ int ret;
+
+ ret = regmap_read(clkm->clkr.regmap, clkm->pll_ofs + PLL_EMMC1_OFFSET, ®);
+ if (ret)
+ return ret;
+
+ *val = (reg >> PLL_PHRT0_SHIFT) & PLL_PHRT0_MASK;
+ return 0;
+}
+
+static inline int set_phrt0(struct clk_pll_mmc *clkm, u32 val)
+{
+ return regmap_update_bits(clkm->clkr.regmap, clkm->pll_ofs + PLL_EMMC1_OFFSET,
+ PLL_PHRT0_MASK, val << PLL_PHRT0_SHIFT);
+}
+
+static inline int get_phsel(struct clk_pll_mmc *clkm, int id, u32 *val)
+{
+ int ret;
+ u32 raw_val;
+ u32 sft = id ? 8 : 3;
+
+ ret = regmap_read(clkm->clkr.regmap, clkm->pll_ofs + PLL_EMMC1_OFFSET, &raw_val);
+ if (ret)
+ return ret;
+
+ *val = (raw_val >> sft) & PLL_PHSEL_MASK;
+ return 0;
+}
+
+static inline int set_phsel(struct clk_pll_mmc *clkm, int id, u32 val)
+{
+ u32 sft = id ? 8 : 3;
+
+ return regmap_update_bits(clkm->clkr.regmap, clkm->pll_ofs + PLL_EMMC1_OFFSET,
+ PLL_PHSEL_MASK << sft, val << sft);
+}
+
+static inline int set_sscpll_rs(struct clk_pll_mmc *clkm, u32 val)
+{
+ return regmap_update_bits(clkm->clkr.regmap, clkm->pll_ofs + PLL_EMMC2_OFFSET,
+ PLL_SSCPLL_RS_MASK, val << PLL_SSCPLL_RS_SHIFT);
+}
+
+static inline int set_sscpll_icp(struct clk_pll_mmc *clkm, u32 val)
+{
+ return regmap_update_bits(clkm->clkr.regmap, clkm->pll_ofs + PLL_EMMC2_OFFSET,
+ PLL_SSCPLL_ICP_MASK, val << PLL_SSCPLL_ICP_SHIFT);
+}
+
+static inline int get_ssc_div_ext_f(struct clk_pll_mmc *clkm, u32 *val)
+{
+ u32 raw_val;
+ int ret;
+
+ ret = regmap_read(clkm->clkr.regmap, clkm->pll_ofs + PLL_EMMC2_OFFSET, &raw_val);
+ if (ret)
+ return ret;
+
+ *val = (raw_val & PLL_SSC_DIV_EXT_F_MASK) >> PLL_SSC_DIV_EXT_F_SHIFT;
+ return 0;
+}
+
+static inline int set_ssc_div_ext_f(struct clk_pll_mmc *clkm, u32 val)
+{
+ return regmap_update_bits(clkm->clkr.regmap, clkm->pll_ofs + PLL_EMMC2_OFFSET,
+ PLL_SSC_DIV_EXT_F_MASK,
+ val << PLL_SSC_DIV_EXT_F_SHIFT);
+}
+
+static inline int set_pi_ibselh(struct clk_pll_mmc *clkm, u32 val)
+{
+ return regmap_update_bits(clkm->clkr.regmap, clkm->pll_ofs + PLL_EMMC2_OFFSET,
+ PLL_PI_IBSELH_MASK, val << PLL_PI_IBSELH_SHIFT);
+}
+
+static inline int set_ssc_div_n(struct clk_pll_mmc *clkm, u32 val)
+{
+ return regmap_update_bits(clkm->clkr.regmap, clkm->pll_ofs + PLL_EMMC3_OFFSET,
+ PLL_SSC_DIV_N_MASK, val << PLL_SSC_DIV_N_SHIFT);
+}
+
+static inline int get_ssc_div_n(struct clk_pll_mmc *clkm, u32 *val)
+{
+ int ret;
+ u32 raw_val;
+
+ ret = regmap_read(clkm->clkr.regmap, clkm->pll_ofs + PLL_EMMC3_OFFSET, &raw_val);
+ if (ret)
+ return ret;
+
+ *val = (raw_val & PLL_SSC_DIV_N_MASK) >> PLL_SSC_DIV_N_SHIFT;
+ return 0;
+}
+
+static inline int set_pow_ctl(struct clk_pll_mmc *clkm, u32 val)
+{
+ return regmap_write(clkm->clkr.regmap, clkm->pll_ofs + PLL_EMMC4_OFFSET, val);
+}
+
+static inline int get_pow_ctl(struct clk_pll_mmc *clkm, u32 *val)
+{
+ int ret;
+ u32 raw_val;
+
+ ret = regmap_read(clkm->clkr.regmap, clkm->pll_ofs + PLL_EMMC4_OFFSET, &raw_val);
+ if (ret)
+ return ret;
+
+ *val = raw_val;
+
+ return 0;
+}
+
+static int clk_pll_mmc_phase_set_phase(struct clk_hw *hw, int degrees)
+{
+ struct clk_hw *hwp = clk_hw_get_parent(hw);
+ struct clk_pll_mmc *clkm;
+ int phase_id;
+ int ret;
+ u32 val;
+
+ if (!hwp)
+ return -ENOENT;
+
+ clkm = to_clk_pll_mmc(hwp);
+ phase_id = (hw - &clkm->phase0_hw) ? 1 : 0;
+ val = DIV_ROUND_CLOSEST(degrees * 100, PHASE_SCALE_FACTOR);
+ ret = set_phsel(clkm, phase_id, val);
+ if (ret)
+ return ret;
+
+ usleep_range(10, 20);
+ return 0;
+}
+
+static int clk_pll_mmc_phase_get_phase(struct clk_hw *hw)
+{
+ struct clk_hw *hwp;
+ struct clk_pll_mmc *clkm;
+ int phase_id;
+ int ret;
+ u32 val;
+
+ hwp = clk_hw_get_parent(hw);
+ if (!hwp)
+ return -ENOENT;
+
+ clkm = to_clk_pll_mmc(hwp);
+ phase_id = (hw - &clkm->phase0_hw) ? 1 : 0;
+ ret = get_phsel(clkm, phase_id, &val);
+ if (ret)
+ return ret;
+
+ val = DIV_ROUND_CLOSEST(val * CYCLE_DEGREES, PHASE_STEPS);
+
+ return val;
+}
+
+const struct clk_ops rtk_clk_pll_mmc_phase_ops = {
+ .set_phase = clk_pll_mmc_phase_set_phase,
+ .get_phase = clk_pll_mmc_phase_get_phase,
+};
+EXPORT_SYMBOL_NS_GPL(rtk_clk_pll_mmc_phase_ops, "REALTEK_CLK");
+
+static int clk_pll_mmc_prepare(struct clk_hw *hw)
+{
+ struct clk_pll_mmc *clkm = to_clk_pll_mmc(hw);
+
+ return set_pow_ctl(clkm, 7);
+}
+
+static void clk_pll_mmc_unprepare(struct clk_hw *hw)
+{
+ struct clk_pll_mmc *clkm = to_clk_pll_mmc(hw);
+
+ set_pow_ctl(clkm, 0);
+}
+
+static int clk_pll_mmc_is_prepared(struct clk_hw *hw)
+{
+ struct clk_pll_mmc *clkm = to_clk_pll_mmc(hw);
+ u32 val;
+ int ret;
+
+ ret = get_pow_ctl(clkm, &val);
+ if (ret)
+ return 1;
+
+ return val != 0x0;
+}
+
+static int clk_pll_mmc_enable(struct clk_hw *hw)
+{
+ struct clk_pll_mmc *clkm = to_clk_pll_mmc(hw);
+ int ret;
+
+ ret = set_phrt0(clkm, 1);
+ if (ret)
+ return ret;
+
+ udelay(10);
+ return 0;
+}
+
+static void clk_pll_mmc_disable(struct clk_hw *hw)
+{
+ struct clk_pll_mmc *clkm = to_clk_pll_mmc(hw);
+
+ set_phrt0(clkm, 0);
+ udelay(10);
+}
+
+static int clk_pll_mmc_is_enabled(struct clk_hw *hw)
+{
+ struct clk_pll_mmc *clkm = to_clk_pll_mmc(hw);
+ u32 val;
+ int ret;
+
+ ret = get_phrt0(clkm, &val);
+ if (ret)
+ return 1;
+
+ return val == 0x1;
+}
+
+static unsigned long clk_pll_mmc_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
+{
+ struct clk_pll_mmc *clkm = to_clk_pll_mmc(hw);
+ u32 val, ext_f;
+ int ret;
+
+ ret = get_ssc_div_n(clkm, &val);
+ if (ret)
+ return ret;
+
+ ret = get_ssc_div_ext_f(clkm, &ext_f);
+ if (ret)
+ return ret;
+
+ return parent_rate / 4 * (val + 2) + (parent_rate / 4 * ext_f) / 8192;
+}
+
+static int clk_pll_mmc_determine_rate(struct clk_hw *hw, struct clk_rate_request *req)
+{
+ u32 val = DIV_ROUND_CLOSEST(req->rate * 4, req->best_parent_rate);
+
+ req->rate = req->best_parent_rate * val / 4;
+ return 0;
+}
+
+static int clk_pll_mmc_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long parent_rate)
+{
+ struct clk_pll_mmc *clkm = to_clk_pll_mmc(hw);
+ u32 val = PLL_MMC_SSC_DIV_N_VAL;
+ int ret;
+
+ ret = regmap_update_bits(clkm->clkr.regmap,
+ clkm->ssc_dig_ofs + PLL_SSC_DIG_EMMC1_OFFSET,
+ PLL_FLAG_INITAL_EMMC_MASK, 0x0 << PLL_FLAG_INITAL_EMMC_SHIFT);
+ if (ret)
+ return ret;
+
+ ret = set_ssc_div_n(clkm, val);
+ if (ret)
+ return ret;
+
+ ret = set_ssc_div_ext_f(clkm, 1517);
+ if (ret)
+ return ret;
+
+ switch (val) {
+ case 31 ... 46:
+ ret |= set_pi_ibselh(clkm, 3);
+ ret |= set_sscpll_rs(clkm, 3);
+ ret |= set_sscpll_icp(clkm, 2);
+ break;
+
+ case 20 ... 30:
+ ret |= set_pi_ibselh(clkm, 2);
+ ret |= set_sscpll_rs(clkm, 3);
+ ret |= set_sscpll_icp(clkm, 1);
+ break;
+
+ case 10 ... 19:
+ ret |= set_pi_ibselh(clkm, 1);
+ ret |= set_sscpll_rs(clkm, 2);
+ ret |= set_sscpll_icp(clkm, 1);
+ break;
+
+ case 5 ... 9:
+ ret |= set_pi_ibselh(clkm, 0);
+ ret |= set_sscpll_rs(clkm, 2);
+ ret |= set_sscpll_icp(clkm, 0);
+ break;
+ }
+ if (ret)
+ return ret;
+
+ ret = regmap_update_bits(clkm->clkr.regmap,
+ clkm->ssc_dig_ofs + PLL_SSC_DIG_EMMC3_OFFSET,
+ PLL_NCODE_SSC_EMMC_MASK,
+ 27 << PLL_NCODE_SSC_EMMC_SHIFT);
+ if (ret)
+ return ret;
+
+ ret = regmap_update_bits(clkm->clkr.regmap,
+ clkm->ssc_dig_ofs + PLL_SSC_DIG_EMMC3_OFFSET,
+ PLL_FCODE_SSC_EMMC_MASK, 321);
+ if (ret)
+ return ret;
+
+ ret = regmap_update_bits(clkm->clkr.regmap,
+ clkm->ssc_dig_ofs + PLL_SSC_DIG_EMMC4_OFFSET,
+ PLL_GRAN_EST_EM_MC_MASK, 5985);
+ if (ret)
+ return ret;
+
+ ret = regmap_update_bits(clkm->clkr.regmap,
+ clkm->ssc_dig_ofs + PLL_SSC_DIG_EMMC1_OFFSET,
+ PLL_EN_SSC_EMMC_MASK, 0x1);
+ if (ret)
+ return ret;
+
+ ret = regmap_update_bits(clkm->clkr.regmap,
+ clkm->ssc_dig_ofs + PLL_SSC_DIG_EMMC1_OFFSET,
+ PLL_EN_SSC_EMMC_MASK, 0x0);
+ if (ret)
+ return ret;
+
+ ret = regmap_update_bits(clkm->clkr.regmap,
+ clkm->ssc_dig_ofs + PLL_SSC_DIG_EMMC1_OFFSET,
+ PLL_FLAG_INITAL_EMMC_MASK,
+ 0x1 << PLL_FLAG_INITAL_EMMC_SHIFT);
+ if (ret)
+ return ret;
+
+ usleep_range(10, 20);
+ return 0;
+}
+
+const struct clk_ops rtk_clk_pll_mmc_ops = {
+ .prepare = clk_pll_mmc_prepare,
+ .unprepare = clk_pll_mmc_unprepare,
+ .is_prepared = clk_pll_mmc_is_prepared,
+ .enable = clk_pll_mmc_enable,
+ .disable = clk_pll_mmc_disable,
+ .is_enabled = clk_pll_mmc_is_enabled,
+ .recalc_rate = clk_pll_mmc_recalc_rate,
+ .determine_rate = clk_pll_mmc_determine_rate,
+ .set_rate = clk_pll_mmc_set_rate,
+};
+EXPORT_SYMBOL_NS_GPL(rtk_clk_pll_mmc_ops, "REALTEK_CLK");
diff --git a/drivers/clk/realtek/clk-pll.h b/drivers/clk/realtek/clk-pll.h
index 00884585a242..033c982e1eb1 100644
--- a/drivers/clk/realtek/clk-pll.h
+++ b/drivers/clk/realtek/clk-pll.h
@@ -39,4 +39,17 @@ struct clk_pll {
extern const struct clk_ops rtk_clk_pll_ops;
extern const struct clk_ops rtk_clk_pll_ro_ops;
+struct clk_pll_mmc {
+ struct clk_regmap clkr;
+ unsigned int pll_ofs;
+ unsigned int ssc_dig_ofs;
+ struct clk_hw phase0_hw;
+ struct clk_hw phase1_hw;
+};
+
+#define __clk_pll_mmc_hw(_ptr) __clk_regmap_hw(&(_ptr)->clkr)
+
+extern const struct clk_ops rtk_clk_pll_mmc_ops;
+extern const struct clk_ops rtk_clk_pll_mmc_phase_ops;
+
#endif /* __CLK_REALTEK_CLK_PLL_H */
--
2.34.1
^ permalink raw reply related
* [PATCH v6 08/10] clk: realtek: Add RTD1625-CRT clock controller driver
From: Yu-Chun Lin @ 2026-04-02 7:39 UTC (permalink / raw)
To: mturquette, sboyd, robh, krzk+dt, conor+dt, p.zabel, cylee12,
afaerber, jyanchou
Cc: devicetree, linux-clk, linux-kernel, linux-arm-kernel,
linux-realtek-soc, james.tai, cy.huang, stanley_chang,
eleanor.lin
In-Reply-To: <20260402073957.2742459-1-eleanor.lin@realtek.com>
From: Cheng-Yu Lee <cylee12@realtek.com>
Add support for the CRT (Clock, Reset, and Test) domain clock controller
on the Realtek RTD1625 SoC. This driver provides essential clock sources
(including PLLs), gating, and multiplexing functionalities for the
platform's peripherals.
Since the reset controller shares the same register space with the CRT
clock controller, it is instantiated as an auxiliary device by the core
clock driver. This patch also includes the corresponding auxiliary reset
driver to handle the CRT domain resets.
Signed-off-by: Cheng-Yu Lee <cylee12@realtek.com>
Co-developed-by: Yu-Chun Lin <eleanor.lin@realtek.com>
Signed-off-by: Yu-Chun Lin <eleanor.lin@realtek.com>
---
Changes in v6:
- Add the headers used in c file to follow the "Include What You Use" principle.
- Move struct rtk_reset_desc array from the clock driver to the dedicated reset driver.
- Implement and register a dedicated reset auxiliary driver.
---
drivers/clk/realtek/Kconfig | 13 +
drivers/clk/realtek/Makefile | 1 +
drivers/clk/realtek/clk-rtd1625-crt.c | 779 ++++++++++++++++++++++
drivers/reset/realtek/Kconfig | 2 +
drivers/reset/realtek/Makefile | 2 +-
drivers/reset/realtek/reset-rtd1625-crt.c | 186 ++++++
6 files changed, 982 insertions(+), 1 deletion(-)
create mode 100644 drivers/clk/realtek/clk-rtd1625-crt.c
create mode 100644 drivers/reset/realtek/reset-rtd1625-crt.c
diff --git a/drivers/clk/realtek/Kconfig b/drivers/clk/realtek/Kconfig
index b31a31e57b3a..6a213cfd66bc 100644
--- a/drivers/clk/realtek/Kconfig
+++ b/drivers/clk/realtek/Kconfig
@@ -28,4 +28,17 @@ config RTK_CLK_COMMON
config RTK_CLK_PLL_MMC
bool
+config COMMON_CLK_RTD1625
+ tristate "RTD1625 Clock Controller"
+ select RTK_CLK_COMMON
+ select RTK_CLK_PLL_MMC
+ help
+ Support for the clock controller on Realtek RTD1625 SoCs.
+
+ This driver provides clock sources, gating, multiplexing, and
+ reset control for peripherals on the RTD1625 platform.
+
+ Say Y here if your system is based on the RTD1625 and you need
+ its peripheral devices to function.
+
endif
diff --git a/drivers/clk/realtek/Makefile b/drivers/clk/realtek/Makefile
index fd7d777902c8..c992f97dfbc7 100644
--- a/drivers/clk/realtek/Makefile
+++ b/drivers/clk/realtek/Makefile
@@ -9,3 +9,4 @@ clk-rtk-y += clk-regmap-mux.o
clk-rtk-y += freq_table.o
clk-rtk-$(CONFIG_RTK_CLK_PLL_MMC) += clk-pll-mmc.o
+obj-$(CONFIG_COMMON_CLK_RTD1625) += clk-rtd1625-crt.o
diff --git a/drivers/clk/realtek/clk-rtd1625-crt.c b/drivers/clk/realtek/clk-rtd1625-crt.c
new file mode 100644
index 000000000000..fcb8b08722c8
--- /dev/null
+++ b/drivers/clk/realtek/clk-rtd1625-crt.c
@@ -0,0 +1,779 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2022 Realtek Semiconductor Corporation
+ * Author: Cheng-Yu Lee <cylee12@realtek.com>
+ */
+
+#include <dt-bindings/clock/realtek,rtd1625-clk.h>
+#include <linux/array_size.h>
+#include <linux/bits.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include "clk-pll.h"
+#include "clk-regmap-gate.h"
+#include "clk-regmap-mux.h"
+
+#define RTD1625_CRT_CLK_MAX 172
+#define RTD1625_CRT_RSTN_MAX 123
+
+#define RTD1625_REG_PLL_ACPU1 0x10c
+#define RTD1625_REG_PLL_ACPU2 0x110
+#define RTD1625_REG_PLL_SSC_DIG_ACPU0 0x5c0
+#define RTD1625_REG_PLL_SSC_DIG_ACPU1 0x5c4
+#define RTD1625_REG_PLL_SSC_DIG_ACPU2 0x5c8
+#define RTD1625_REG_PLL_SSC_DIG_ACPU_DBG2 0x5dc
+
+#define RTD1625_REG_PLL_VE1_1 0x114
+#define RTD1625_REG_PLL_VE1_2 0x118
+#define RTD1625_REG_PLL_SSC_DIG_VE1_0 0x580
+#define RTD1625_REG_PLL_SSC_DIG_VE1_1 0x584
+#define RTD1625_REG_PLL_SSC_DIG_VE1_2 0x588
+#define RTD1625_REG_PLL_SSC_DIG_VE1_DBG2 0x59c
+
+#define RTD1625_REG_PLL_GPU1 0x1c0
+#define RTD1625_REG_PLL_GPU2 0x1c4
+#define RTD1625_REG_PLL_SSC_DIG_GPU0 0x5a0
+#define RTD1625_REG_PLL_SSC_DIG_GPU1 0x5a4
+#define RTD1625_REG_PLL_SSC_DIG_GPU2 0x5a8
+#define RTD1625_REG_PLL_SSC_DIG_GPU_DBG2 0x5bc
+
+#define RTD1625_REG_PLL_NPU1 0x1c8
+#define RTD1625_REG_PLL_NPU2 0x1cc
+#define RTD1625_REG_PLL_SSC_DIG_NPU0 0x800
+#define RTD1625_REG_PLL_SSC_DIG_NPU1 0x804
+#define RTD1625_REG_PLL_SSC_DIG_NPU2 0x808
+#define RTD1625_REG_PLL_SSC_DIG_NPU_DBG2 0x81c
+
+#define RTD1625_REG_PLL_VE2_1 0x1d0
+#define RTD1625_REG_PLL_VE2_2 0x1d4
+#define RTD1625_REG_PLL_SSC_DIG_VE2_0 0x5e0
+#define RTD1625_REG_PLL_SSC_DIG_VE2_1 0x5e4
+#define RTD1625_REG_PLL_SSC_DIG_VE2_2 0x5e8
+#define RTD1625_REG_PLL_SSC_DIG_VE2_DBG2 0x5fc
+
+#define RTD1625_REG_PLL_HIFI1 0x1d8
+#define RTD1625_REG_PLL_HIFI2 0x1dc
+#define RTD1625_REG_PLL_SSC_DIG_HIFI0 0x6e0
+#define RTD1625_REG_PLL_SSC_DIG_HIFI1 0x6e4
+#define RTD1625_REG_PLL_SSC_DIG_HIFI2 0x6e8
+#define RTD1625_REG_PLL_SSC_DIG_HIFI_DBG2 0x6fc
+
+#define RTD1625_REG_PLL_BUS1 0x524
+
+#define RTD1625_REG_PLL_SSC_DIG_DDSA1 0x564
+
+#define RTD1625_REG_PLL_SSC_DIG_DCSB1 0x544
+
+static const char * const clk_gpu_parents[] = {"pll_gpu", "clk_sys"};
+static CLK_REGMAP_MUX(clk_gpu, clk_gpu_parents, CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
+ 0x28, 12, 0x1);
+static const char * const clk_ve_parents[] = {"pll_vo", "clk_sysh", "pll_ve1", "pll_ve2"};
+static CLK_REGMAP_MUX(clk_ve1, clk_ve_parents, CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
+ 0x4c, 0, 0x3);
+static CLK_REGMAP_MUX(clk_ve2, clk_ve_parents, CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
+ 0x4c, 3, 0x3);
+static CLK_REGMAP_MUX(clk_ve4, clk_ve_parents, CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
+ 0x4c, 6, 0x3);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_misc, CLK_IS_CRITICAL, 0x50, 0, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_pcie0, 0, 0x50, 2, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_gspi, 0, 0x50, 6, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_iso_misc, 0, 0x50, 10, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_sds, 0, 0x50, 12, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_hdmi, 0, 0x50, 14, 1);
+static CLK_REGMAP_GATE(clk_en_gpu, "clk_gpu", CLK_SET_RATE_PARENT, 0x50, 18, 1);
+static CLK_REGMAP_GATE(clk_en_ve1, "clk_ve1", CLK_SET_RATE_PARENT, 0x50, 20, 1);
+static CLK_REGMAP_GATE(clk_en_ve2, "clk_ve2", CLK_SET_RATE_PARENT, 0x50, 22, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_se, 0, 0x50, 30, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_md, 0, 0x54, 4, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_tp, CLK_IS_CRITICAL, 0x54, 6, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_rcic, 0, 0x54, 8, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_nf, 0, 0x54, 10, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_emmc, 0, 0x54, 12, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_sd, 0, 0x54, 14, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_sdio_ip, 0, 0x54, 16, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_mipi_csi, 0, 0x54, 18, 1);
+static CLK_REGMAP_GATE(clk_en_emmc_ip, "pll_emmc", CLK_SET_RATE_PARENT, 0x54, 20, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_sdio, 0, 0x54, 22, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_sd_ip, 0, 0x54, 24, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_tpb, 0, 0x54, 28, 1);
+static CLK_REGMAP_GATE(clk_en_misc_sc1, "clk_en_misc", 0, 0x54, 30, 1);
+static CLK_REGMAP_GATE(clk_en_misc_i2c_3, "clk_en_misc", 0, 0x58, 0, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_jpeg, 0, 0x58, 4, 1);
+static CLK_REGMAP_GATE(clk_en_acpu, "pll_acpu", CLK_SET_RATE_PARENT,
+ 0x58, 6, 1);
+static CLK_REGMAP_GATE(clk_en_misc_sc0, "clk_en_misc", 0, 0x58, 10, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_hdmirx, 0, 0x58, 26, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_hse, CLK_IS_CRITICAL, 0x58, 28, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_fan, 0, 0x5c, 2, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_sata_wrap_sys, 0, 0x5c, 8, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_sata_wrap_sysh, 0, 0x5c, 10, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_sata_mac_sysh, 0, 0x5c, 12, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_r2rdsc, 0, 0x5c, 14, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_pcie1, 0, 0x5c, 18, 1);
+static CLK_REGMAP_GATE(clk_en_misc_i2c_4, "clk_en_misc", 0, 0x5c, 20, 1);
+static CLK_REGMAP_GATE(clk_en_misc_i2c_5, "clk_en_misc", 0, 0x5c, 22, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_tsio, 0, 0x5c, 24, 1);
+static CLK_REGMAP_GATE(clk_en_ve4, "clk_ve4", CLK_SET_RATE_PARENT,
+ 0x5c, 26, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_edp, 0, 0x5c, 28, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_tsio_trx, 0, 0x5c, 30, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_pcie2, 0, 0x8c, 0, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_earc, 0, 0x8c, 4, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_lite, 0, 0x8c, 6, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_mipi_dsi, 0, 0x8c, 8, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_npupp, 0, 0x8c, 10, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_npu, 0, 0x8c, 12, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_aucpu0, 0, 0x8c, 14, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_aucpu1, 0, 0x8c, 16, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_nsram, 0, 0x8c, 18, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_hdmitop, 0, 0x8c, 20, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_aucpu_iso_npu, 0, 0x8c, 24, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_keyladder, 0, 0x8c, 26, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_ifcp_klm, 0, 0x8c, 28, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_ifcp, 0, 0x8c, 30, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_mdl_genpw, 0, 0xb0, 0, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_mdl_chip, 0, 0xb0, 2, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_mdl_ip, 0, 0xb0, 4, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_mdlm2m, 0, 0xb0, 6, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_mdl_xtal, 0, 0xb0, 8, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_test_mux, 0, 0xb0, 10, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_dla, 0, 0xb0, 12, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_tpcw, 0, 0xb0, 16, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_gpu_ts_src, 0, 0xb0, 18, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_vi, 0, 0xb0, 22, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_lvds1, 0, 0xb0, 24, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_lvds2, 0, 0xb0, 26, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_aucpu, 0, 0xb0, 28, 1);
+static CLK_REGMAP_GATE(clk_en_ur1, "clk_en_ur_top", 0, 0x884, 0, 1);
+static CLK_REGMAP_GATE(clk_en_ur2, "clk_en_ur_top", 0, 0x884, 2, 1);
+static CLK_REGMAP_GATE(clk_en_ur3, "clk_en_ur_top", 0, 0x884, 4, 1);
+static CLK_REGMAP_GATE(clk_en_ur4, "clk_en_ur_top", 0, 0x884, 6, 1);
+static CLK_REGMAP_GATE(clk_en_ur5, "clk_en_ur_top", 0, 0x884, 8, 1);
+static CLK_REGMAP_GATE(clk_en_ur6, "clk_en_ur_top", 0, 0x884, 10, 1);
+static CLK_REGMAP_GATE(clk_en_ur7, "clk_en_ur_top", 0, 0x884, 12, 1);
+static CLK_REGMAP_GATE(clk_en_ur8, "clk_en_ur_top", 0, 0x884, 14, 1);
+static CLK_REGMAP_GATE(clk_en_ur9, "clk_en_ur_top", 0, 0x884, 16, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_ur_top, CLK_IS_CRITICAL, 0x884, 18, 1);
+static CLK_REGMAP_GATE(clk_en_misc_i2c_7, "clk_en_misc", 0, 0x884, 28, 1);
+static CLK_REGMAP_GATE(clk_en_misc_i2c_6, "clk_en_misc", 0, 0x884, 30, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_spi0, 0, 0x894, 0, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_spi1, 0, 0x894, 2, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_spi2, 0, 0x894, 4, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_lsadc0, 0, 0x894, 16, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_lsadc1, 0, 0x894, 18, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_isomis_dma, 0, 0x894, 20, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_dptx, 0, 0x894, 24, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_npu_mipi_csi, 0, 0x894, 26, 1);
+static CLK_REGMAP_GATE_NO_PARENT(clk_en_edptx, 0, 0x894, 28, 1);
+
+#define FREQ_NF_MASK 0x7ffff
+#define FREQ_NF(_r, _nf) {.rate = _r, .val = (_nf),}
+
+static const struct freq_table acpu_tbl[] = {
+ FREQ_NF(513000000, 0x11000),
+ FREQ_TABLE_END
+};
+
+static const struct freq_table ve_tbl[] = {
+ FREQ_NF(553500000, 0x12800),
+ FREQ_NF(661500000, 0x16800),
+ FREQ_NF(688500000, 0x17800),
+ FREQ_TABLE_END
+};
+
+static const struct freq_table bus_tbl[] = {
+ FREQ_NF(513000000, 0x11000),
+ FREQ_NF(540000000, 0x12000),
+ FREQ_NF(553500000, 0x12800),
+ FREQ_TABLE_END
+};
+
+static const struct freq_table ddsa_tbl[] = {
+ FREQ_NF(432000000, 0xe000),
+ FREQ_TABLE_END
+};
+
+static const struct freq_table gpu_tbl[] = {
+ FREQ_NF(405000000, 0xd000),
+ FREQ_NF(540000000, 0x12000),
+ FREQ_NF(661500000, 0x16800),
+ FREQ_NF(729000000, 0x19000),
+ FREQ_NF(810000000, 0x1c000),
+ FREQ_NF(850500000, 0x1d800),
+ FREQ_TABLE_END
+};
+
+static const struct freq_table hifi_tbl[] = {
+ FREQ_NF(756000000, 0x1a000),
+ FREQ_NF(810000000, 0x1c000),
+ FREQ_TABLE_END
+};
+
+static const struct freq_table npu_tbl[] = {
+ FREQ_NF(661500000, 0x16800),
+ FREQ_NF(729000000, 0x19000),
+ FREQ_NF(810000000, 0x1c000),
+ FREQ_TABLE_END
+};
+
+static const struct reg_sequence pll_acpu_seq_power_on[] = {
+ {RTD1625_REG_PLL_ACPU2, 0x5},
+ {RTD1625_REG_PLL_ACPU2, 0x7},
+ {RTD1625_REG_PLL_ACPU1, 0x54000},
+ {RTD1625_REG_PLL_SSC_DIG_ACPU2, 0x1e1f8e},
+ {RTD1625_REG_PLL_SSC_DIG_ACPU0, 0x4},
+ {RTD1625_REG_PLL_SSC_DIG_ACPU0, 0x5, 200},
+ {RTD1625_REG_PLL_ACPU2, 0x3},
+};
+
+static const struct reg_sequence pll_acpu_seq_power_off[] = {
+ {RTD1625_REG_PLL_ACPU2, 0x4},
+};
+
+static const struct reg_sequence pll_acpu_seq_pre_set_freq[] = {
+ {RTD1625_REG_PLL_SSC_DIG_ACPU0, 0x4},
+};
+
+static const struct reg_sequence pll_acpu_seq_post_set_freq[] = {
+ {RTD1625_REG_PLL_SSC_DIG_ACPU0, 0x5},
+};
+
+static struct clk_pll pll_acpu = {
+ .clkr.hw.init = CLK_HW_INIT("pll_acpu", "osc27m", &rtk_clk_pll_ops, CLK_GET_RATE_NOCACHE),
+ .seq_power_on = pll_acpu_seq_power_on,
+ .num_seq_power_on = ARRAY_SIZE(pll_acpu_seq_power_on),
+ .seq_power_off = pll_acpu_seq_power_off,
+ .num_seq_power_off = ARRAY_SIZE(pll_acpu_seq_power_off),
+ .seq_pre_set_freq = pll_acpu_seq_pre_set_freq,
+ .num_seq_pre_set_freq = ARRAY_SIZE(pll_acpu_seq_pre_set_freq),
+ .seq_post_set_freq = pll_acpu_seq_post_set_freq,
+ .num_seq_post_set_freq = ARRAY_SIZE(pll_acpu_seq_post_set_freq),
+ .freq_reg = RTD1625_REG_PLL_SSC_DIG_ACPU1,
+ .freq_tbl = acpu_tbl,
+ .freq_mask = FREQ_NF_MASK,
+ .freq_ready_reg = RTD1625_REG_PLL_SSC_DIG_ACPU_DBG2,
+ .freq_ready_mask = BIT(20),
+ .freq_ready_val = BIT(20),
+ .power_reg = RTD1625_REG_PLL_ACPU2,
+ .power_mask = 0x7,
+ .power_val_on = 0x3,
+};
+
+static const struct reg_sequence pll_ve1_seq_power_on[] = {
+ {RTD1625_REG_PLL_VE1_2, 0x5},
+ {RTD1625_REG_PLL_VE1_2, 0x7},
+ {RTD1625_REG_PLL_VE1_1, 0x54000},
+ {RTD1625_REG_PLL_SSC_DIG_VE1_0, 0x4},
+ {RTD1625_REG_PLL_SSC_DIG_VE1_0, 0x5, 200},
+ {RTD1625_REG_PLL_VE1_2, 0x3},
+};
+
+static const struct reg_sequence pll_ve1_seq_power_off[] = {
+ {RTD1625_REG_PLL_VE1_2, 0x4},
+};
+
+static const struct reg_sequence pll_ve1_seq_pre_set_freq[] = {
+ {RTD1625_REG_PLL_SSC_DIG_VE1_0, 0x4},
+};
+
+static const struct reg_sequence pll_ve1_seq_post_set_freq[] = {
+ {RTD1625_REG_PLL_SSC_DIG_VE1_0, 0x5},
+};
+
+static struct clk_pll pll_ve1 = {
+ .clkr.hw.init = CLK_HW_INIT("pll_ve1", "osc27m", &rtk_clk_pll_ops, CLK_GET_RATE_NOCACHE),
+ .seq_power_on = pll_ve1_seq_power_on,
+ .num_seq_power_on = ARRAY_SIZE(pll_ve1_seq_power_on),
+ .seq_power_off = pll_ve1_seq_power_off,
+ .num_seq_power_off = ARRAY_SIZE(pll_ve1_seq_power_off),
+ .seq_pre_set_freq = pll_ve1_seq_pre_set_freq,
+ .num_seq_pre_set_freq = ARRAY_SIZE(pll_ve1_seq_pre_set_freq),
+ .seq_post_set_freq = pll_ve1_seq_post_set_freq,
+ .num_seq_post_set_freq = ARRAY_SIZE(pll_ve1_seq_post_set_freq),
+ .freq_reg = RTD1625_REG_PLL_SSC_DIG_VE1_1,
+ .freq_tbl = ve_tbl,
+ .freq_mask = FREQ_NF_MASK,
+ .freq_ready_reg = RTD1625_REG_PLL_SSC_DIG_VE1_DBG2,
+ .freq_ready_mask = BIT(20),
+ .freq_ready_val = BIT(20),
+ .power_reg = RTD1625_REG_PLL_VE1_2,
+ .power_mask = 0x7,
+ .power_val_on = 0x3,
+};
+
+static struct clk_pll pll_ddsa = {
+ .clkr.hw.init = CLK_HW_INIT("pll_ddsa", "osc27m", &rtk_clk_pll_ro_ops,
+ CLK_GET_RATE_NOCACHE),
+ .freq_reg = RTD1625_REG_PLL_SSC_DIG_DDSA1,
+ .freq_tbl = ddsa_tbl,
+ .freq_mask = FREQ_NF_MASK,
+};
+
+static struct clk_pll pll_bus = {
+ .clkr.hw.init = CLK_HW_INIT("pll_bus", "osc27m", &rtk_clk_pll_ro_ops, CLK_GET_RATE_NOCACHE),
+ .freq_reg = RTD1625_REG_PLL_BUS1,
+ .freq_tbl = bus_tbl,
+ .freq_mask = FREQ_NF_MASK,
+};
+
+static CLK_FIXED_FACTOR(clk_sys, "clk_sys", "pll_bus", 2, 1, 0);
+
+static struct clk_pll pll_dcsb = {
+ .clkr.hw.init = CLK_HW_INIT("pll_dcsb", "osc27m", &rtk_clk_pll_ro_ops,
+ CLK_GET_RATE_NOCACHE),
+ .freq_reg = RTD1625_REG_PLL_SSC_DIG_DCSB1,
+ .freq_tbl = bus_tbl,
+ .freq_mask = FREQ_NF_MASK,
+};
+
+static CLK_FIXED_FACTOR(clk_sysh, "clk_sysh", "pll_dcsb", 1, 1, 0);
+
+static const struct reg_sequence pll_gpu_seq_power_on[] = {
+ {RTD1625_REG_PLL_GPU2, 0x5},
+ {RTD1625_REG_PLL_GPU2, 0x7},
+ {RTD1625_REG_PLL_GPU1, 0x54000},
+ {RTD1625_REG_PLL_SSC_DIG_GPU0, 0x4},
+ {RTD1625_REG_PLL_SSC_DIG_GPU0, 0x5, 200},
+ {RTD1625_REG_PLL_GPU2, 0x3},
+};
+
+static const struct reg_sequence pll_gpu_seq_power_off[] = {
+ {RTD1625_REG_PLL_GPU2, 0x4},
+};
+
+static const struct reg_sequence pll_gpu_seq_pre_set_freq[] = {
+ {RTD1625_REG_PLL_SSC_DIG_GPU0, 0x4},
+};
+
+static const struct reg_sequence pll_gpu_seq_post_set_freq[] = {
+ {RTD1625_REG_PLL_SSC_DIG_GPU0, 0x5},
+};
+
+static struct clk_pll pll_gpu = {
+ .clkr.hw.init = CLK_HW_INIT("pll_gpu", "osc27m", &rtk_clk_pll_ops, CLK_GET_RATE_NOCACHE),
+ .seq_power_on = pll_gpu_seq_power_on,
+ .num_seq_power_on = ARRAY_SIZE(pll_gpu_seq_power_on),
+ .seq_power_off = pll_gpu_seq_power_off,
+ .num_seq_power_off = ARRAY_SIZE(pll_gpu_seq_power_off),
+ .seq_pre_set_freq = pll_gpu_seq_pre_set_freq,
+ .num_seq_pre_set_freq = ARRAY_SIZE(pll_gpu_seq_pre_set_freq),
+ .seq_post_set_freq = pll_gpu_seq_post_set_freq,
+ .num_seq_post_set_freq = ARRAY_SIZE(pll_gpu_seq_post_set_freq),
+ .freq_reg = RTD1625_REG_PLL_SSC_DIG_GPU1,
+ .freq_tbl = gpu_tbl,
+ .freq_mask = FREQ_NF_MASK,
+ .freq_ready_reg = RTD1625_REG_PLL_SSC_DIG_GPU_DBG2,
+ .freq_ready_mask = BIT(20),
+ .freq_ready_val = BIT(20),
+ .power_reg = RTD1625_REG_PLL_GPU2,
+ .power_mask = 0x7,
+ .power_val_on = 0x3,
+};
+
+static const struct reg_sequence pll_npu_seq_power_on[] = {
+ {RTD1625_REG_PLL_NPU2, 0x5},
+ {RTD1625_REG_PLL_NPU2, 0x7},
+ {RTD1625_REG_PLL_NPU1, 0x54000},
+ {RTD1625_REG_PLL_SSC_DIG_NPU0, 0x4},
+ {RTD1625_REG_PLL_SSC_DIG_NPU0, 0x5, 200},
+ {RTD1625_REG_PLL_NPU2, 0x3},
+};
+
+static const struct reg_sequence pll_npu_seq_power_off[] = {
+ {RTD1625_REG_PLL_NPU2, 0x4},
+ {RTD1625_REG_PLL_NPU1, 0x54010},
+};
+
+static const struct reg_sequence pll_npu_seq_pre_set_freq[] = {
+ {RTD1625_REG_PLL_SSC_DIG_NPU0, 0x4},
+};
+
+static const struct reg_sequence pll_npu_seq_post_set_freq[] = {
+ {RTD1625_REG_PLL_SSC_DIG_NPU0, 0x5},
+};
+
+static struct clk_pll pll_npu = {
+ .clkr.hw.init = CLK_HW_INIT("pll_npu", "osc27m", &rtk_clk_pll_ops, CLK_GET_RATE_NOCACHE),
+ .seq_power_on = pll_npu_seq_power_on,
+ .num_seq_power_on = ARRAY_SIZE(pll_npu_seq_power_on),
+ .seq_power_off = pll_npu_seq_power_off,
+ .num_seq_power_off = ARRAY_SIZE(pll_npu_seq_power_off),
+ .seq_pre_set_freq = pll_npu_seq_pre_set_freq,
+ .num_seq_pre_set_freq = ARRAY_SIZE(pll_npu_seq_pre_set_freq),
+ .seq_post_set_freq = pll_npu_seq_post_set_freq,
+ .num_seq_post_set_freq = ARRAY_SIZE(pll_npu_seq_post_set_freq),
+ .freq_reg = RTD1625_REG_PLL_SSC_DIG_NPU1,
+ .freq_tbl = npu_tbl,
+ .freq_mask = FREQ_NF_MASK,
+ .freq_ready_reg = RTD1625_REG_PLL_SSC_DIG_NPU_DBG2,
+ .freq_ready_mask = BIT(20),
+ .freq_ready_val = BIT(20),
+ .power_reg = RTD1625_REG_PLL_NPU2,
+ .power_mask = 0x7,
+ .power_val_on = 0x3,
+};
+
+static CLK_FIXED_FACTOR(clk_npu, "clk_npu", "pll_npu", 1, 1, CLK_SET_RATE_PARENT);
+static CLK_FIXED_FACTOR(clk_npu_mipi_csi, "clk_npu_mipi_csi", "pll_npu", 1, 1,
+ CLK_SET_RATE_PARENT);
+
+static const struct reg_sequence pll_ve2_seq_power_on[] = {
+ {RTD1625_REG_PLL_VE2_2, 0x5},
+ {RTD1625_REG_PLL_VE2_2, 0x7},
+ {RTD1625_REG_PLL_VE2_1, 0x54000},
+ {RTD1625_REG_PLL_SSC_DIG_VE2_0, 0x4},
+ {RTD1625_REG_PLL_SSC_DIG_VE2_0, 0x5, 200},
+ {RTD1625_REG_PLL_VE2_2, 0x3},
+};
+
+static const struct reg_sequence pll_ve2_seq_power_off[] = {
+ {RTD1625_REG_PLL_VE2_2, 0x4},
+};
+
+static const struct reg_sequence pll_ve2_seq_pre_set_freq[] = {
+ {RTD1625_REG_PLL_SSC_DIG_VE2_0, 0x4},
+};
+
+static const struct reg_sequence pll_ve2_seq_post_set_freq[] = {
+ {RTD1625_REG_PLL_SSC_DIG_VE2_0, 0x5},
+};
+
+static struct clk_pll pll_ve2 = {
+ .clkr.hw.init = CLK_HW_INIT("pll_ve2", "osc27m", &rtk_clk_pll_ops, CLK_GET_RATE_NOCACHE),
+ .seq_power_on = pll_ve2_seq_power_on,
+ .num_seq_power_on = ARRAY_SIZE(pll_ve2_seq_power_on),
+ .seq_power_off = pll_ve2_seq_power_off,
+ .num_seq_power_off = ARRAY_SIZE(pll_ve2_seq_power_off),
+ .seq_pre_set_freq = pll_ve2_seq_pre_set_freq,
+ .num_seq_pre_set_freq = ARRAY_SIZE(pll_ve2_seq_pre_set_freq),
+ .seq_post_set_freq = pll_ve2_seq_post_set_freq,
+ .num_seq_post_set_freq = ARRAY_SIZE(pll_ve2_seq_post_set_freq),
+ .freq_reg = RTD1625_REG_PLL_SSC_DIG_VE2_1,
+ .freq_tbl = ve_tbl,
+ .freq_mask = FREQ_NF_MASK,
+ .freq_ready_reg = RTD1625_REG_PLL_SSC_DIG_VE2_DBG2,
+ .freq_ready_mask = BIT(20),
+ .freq_ready_val = BIT(20),
+ .power_reg = RTD1625_REG_PLL_VE2_2,
+ .power_mask = 0x7,
+ .power_val_on = 0x3,
+};
+
+static const struct reg_sequence pll_hifi_seq_power_on[] = {
+ {RTD1625_REG_PLL_HIFI2, 0x5},
+ {RTD1625_REG_PLL_HIFI2, 0x7},
+ {RTD1625_REG_PLL_HIFI1, 0x54000},
+ {RTD1625_REG_PLL_SSC_DIG_HIFI0, 0x4},
+ {RTD1625_REG_PLL_SSC_DIG_HIFI0, 0x5, 200},
+ {RTD1625_REG_PLL_HIFI2, 0x3},
+};
+
+static const struct reg_sequence pll_hifi_seq_power_off[] = {
+ {RTD1625_REG_PLL_HIFI2, 0x4},
+};
+
+static const struct reg_sequence pll_hifi_seq_pre_set_freq[] = {
+ {RTD1625_REG_PLL_SSC_DIG_HIFI0, 0x4},
+};
+
+static const struct reg_sequence pll_hifi_seq_post_set_freq[] = {
+ {RTD1625_REG_PLL_SSC_DIG_HIFI0, 0x5},
+};
+
+static struct clk_pll pll_hifi = {
+ .clkr.hw.init = CLK_HW_INIT("pll_hifi", "osc27m", &rtk_clk_pll_ops, CLK_GET_RATE_NOCACHE),
+ .seq_power_on = pll_hifi_seq_power_on,
+ .num_seq_power_on = ARRAY_SIZE(pll_hifi_seq_power_on),
+ .seq_power_off = pll_hifi_seq_power_off,
+ .num_seq_power_off = ARRAY_SIZE(pll_hifi_seq_power_off),
+ .seq_pre_set_freq = pll_hifi_seq_pre_set_freq,
+ .num_seq_pre_set_freq = ARRAY_SIZE(pll_hifi_seq_pre_set_freq),
+ .seq_post_set_freq = pll_hifi_seq_post_set_freq,
+ .num_seq_post_set_freq = ARRAY_SIZE(pll_hifi_seq_post_set_freq),
+ .freq_reg = RTD1625_REG_PLL_SSC_DIG_HIFI1,
+ .freq_tbl = hifi_tbl,
+ .freq_mask = FREQ_NF_MASK,
+ .freq_ready_reg = RTD1625_REG_PLL_SSC_DIG_HIFI_DBG2,
+ .freq_ready_mask = BIT(20),
+ .freq_ready_val = BIT(20),
+ .power_reg = RTD1625_REG_PLL_HIFI2,
+ .power_mask = 0x7,
+ .power_val_on = 0x3,
+};
+
+static CLK_FIXED_FACTOR(pll_emmc_ref, "pll_emmc_ref", "osc27m", 1, 1, 0);
+
+static struct clk_pll_mmc pll_emmc = {
+ .pll_ofs = 0x1f0,
+ .ssc_dig_ofs = 0x6b0,
+ .clkr.hw.init = CLK_HW_INIT("pll_emmc", "pll_emmc_ref", &rtk_clk_pll_mmc_ops, 0),
+ .phase0_hw.init = CLK_HW_INIT("pll_emmc_vp0", "pll_emmc", &rtk_clk_pll_mmc_phase_ops, 0),
+ .phase1_hw.init = CLK_HW_INIT("pll_emmc_vp1", "pll_emmc", &rtk_clk_pll_mmc_phase_ops, 0),
+};
+
+static struct clk_regmap *rtd1625_crt_regmap_clks[] = {
+ &clk_en_misc.clkr,
+ &clk_en_pcie0.clkr,
+ &clk_en_gspi.clkr,
+ &clk_en_iso_misc.clkr,
+ &clk_en_sds.clkr,
+ &clk_en_hdmi.clkr,
+ &clk_en_gpu.clkr,
+ &clk_en_ve1.clkr,
+ &clk_en_ve2.clkr,
+ &clk_en_se.clkr,
+ &clk_en_md.clkr,
+ &clk_en_tp.clkr,
+ &clk_en_rcic.clkr,
+ &clk_en_nf.clkr,
+ &clk_en_emmc.clkr,
+ &clk_en_sd.clkr,
+ &clk_en_sdio_ip.clkr,
+ &clk_en_mipi_csi.clkr,
+ &clk_en_emmc_ip.clkr,
+ &clk_en_sdio.clkr,
+ &clk_en_sd_ip.clkr,
+ &clk_en_tpb.clkr,
+ &clk_en_misc_sc1.clkr,
+ &clk_en_misc_i2c_3.clkr,
+ &clk_en_jpeg.clkr,
+ &clk_en_acpu.clkr,
+ &clk_en_misc_sc0.clkr,
+ &clk_en_hdmirx.clkr,
+ &clk_en_hse.clkr,
+ &clk_en_fan.clkr,
+ &clk_en_sata_wrap_sys.clkr,
+ &clk_en_sata_wrap_sysh.clkr,
+ &clk_en_sata_mac_sysh.clkr,
+ &clk_en_r2rdsc.clkr,
+ &clk_en_pcie1.clkr,
+ &clk_en_misc_i2c_4.clkr,
+ &clk_en_misc_i2c_5.clkr,
+ &clk_en_tsio.clkr,
+ &clk_en_ve4.clkr,
+ &clk_en_edp.clkr,
+ &clk_en_tsio_trx.clkr,
+ &clk_en_pcie2.clkr,
+ &clk_en_earc.clkr,
+ &clk_en_lite.clkr,
+ &clk_en_mipi_dsi.clkr,
+ &clk_en_npupp.clkr,
+ &clk_en_npu.clkr,
+ &clk_en_aucpu0.clkr,
+ &clk_en_aucpu1.clkr,
+ &clk_en_nsram.clkr,
+ &clk_en_hdmitop.clkr,
+ &clk_en_aucpu_iso_npu.clkr,
+ &clk_en_keyladder.clkr,
+ &clk_en_ifcp_klm.clkr,
+ &clk_en_ifcp.clkr,
+ &clk_en_mdl_genpw.clkr,
+ &clk_en_mdl_chip.clkr,
+ &clk_en_mdl_ip.clkr,
+ &clk_en_mdlm2m.clkr,
+ &clk_en_mdl_xtal.clkr,
+ &clk_en_test_mux.clkr,
+ &clk_en_dla.clkr,
+ &clk_en_tpcw.clkr,
+ &clk_en_gpu_ts_src.clkr,
+ &clk_en_vi.clkr,
+ &clk_en_lvds1.clkr,
+ &clk_en_lvds2.clkr,
+ &clk_en_aucpu.clkr,
+ &clk_en_ur1.clkr,
+ &clk_en_ur2.clkr,
+ &clk_en_ur3.clkr,
+ &clk_en_ur4.clkr,
+ &clk_en_ur5.clkr,
+ &clk_en_ur6.clkr,
+ &clk_en_ur7.clkr,
+ &clk_en_ur8.clkr,
+ &clk_en_ur9.clkr,
+ &clk_en_ur_top.clkr,
+ &clk_en_misc_i2c_7.clkr,
+ &clk_en_misc_i2c_6.clkr,
+ &clk_en_spi0.clkr,
+ &clk_en_spi1.clkr,
+ &clk_en_spi2.clkr,
+ &clk_en_lsadc0.clkr,
+ &clk_en_lsadc1.clkr,
+ &clk_en_isomis_dma.clkr,
+ &clk_en_dptx.clkr,
+ &clk_en_npu_mipi_csi.clkr,
+ &clk_en_edptx.clkr,
+ &clk_gpu.clkr,
+ &clk_ve1.clkr,
+ &clk_ve2.clkr,
+ &clk_ve4.clkr,
+ &pll_ve1.clkr,
+ &pll_ddsa.clkr,
+ &pll_bus.clkr,
+ &pll_dcsb.clkr,
+ &pll_gpu.clkr,
+ &pll_npu.clkr,
+ &pll_ve2.clkr,
+ &pll_hifi.clkr,
+ &pll_emmc.clkr,
+ &pll_acpu.clkr,
+};
+
+static struct clk_hw_onecell_data rtd1625_crt_hw_data = {
+ .num = RTD1625_CRT_CLK_MAX,
+ .hws = {
+ [RTD1625_CRT_CLK_EN_MISC] = &__clk_regmap_gate_hw(&clk_en_misc),
+ [RTD1625_CRT_CLK_EN_PCIE0] = &__clk_regmap_gate_hw(&clk_en_pcie0),
+ [RTD1625_CRT_CLK_EN_GSPI] = &__clk_regmap_gate_hw(&clk_en_gspi),
+ [RTD1625_CRT_CLK_EN_ISO_MISC] = &__clk_regmap_gate_hw(&clk_en_iso_misc),
+ [RTD1625_CRT_CLK_EN_SDS] = &__clk_regmap_gate_hw(&clk_en_sds),
+ [RTD1625_CRT_CLK_EN_HDMI] = &__clk_regmap_gate_hw(&clk_en_hdmi),
+ [RTD1625_CRT_CLK_EN_GPU] = &__clk_regmap_gate_hw(&clk_en_gpu),
+ [RTD1625_CRT_CLK_EN_VE1] = &__clk_regmap_gate_hw(&clk_en_ve1),
+ [RTD1625_CRT_CLK_EN_VE2] = &__clk_regmap_gate_hw(&clk_en_ve2),
+ [RTD1625_CRT_CLK_EN_MD] = &__clk_regmap_gate_hw(&clk_en_md),
+ [RTD1625_CRT_CLK_EN_TP] = &__clk_regmap_gate_hw(&clk_en_tp),
+ [RTD1625_CRT_CLK_EN_RCIC] = &__clk_regmap_gate_hw(&clk_en_rcic),
+ [RTD1625_CRT_CLK_EN_NF] = &__clk_regmap_gate_hw(&clk_en_nf),
+ [RTD1625_CRT_CLK_EN_EMMC] = &__clk_regmap_gate_hw(&clk_en_emmc),
+ [RTD1625_CRT_CLK_EN_SD] = &__clk_regmap_gate_hw(&clk_en_sd),
+ [RTD1625_CRT_CLK_EN_SDIO_IP] = &__clk_regmap_gate_hw(&clk_en_sdio_ip),
+ [RTD1625_CRT_CLK_EN_MIPI_CSI] = &__clk_regmap_gate_hw(&clk_en_mipi_csi),
+ [RTD1625_CRT_CLK_EN_EMMC_IP] = &__clk_regmap_gate_hw(&clk_en_emmc_ip),
+ [RTD1625_CRT_CLK_EN_SDIO] = &__clk_regmap_gate_hw(&clk_en_sdio),
+ [RTD1625_CRT_CLK_EN_SD_IP] = &__clk_regmap_gate_hw(&clk_en_sd_ip),
+ [RTD1625_CRT_CLK_EN_TPB] = &__clk_regmap_gate_hw(&clk_en_tpb),
+ [RTD1625_CRT_CLK_EN_MISC_SC1] = &__clk_regmap_gate_hw(&clk_en_misc_sc1),
+ [RTD1625_CRT_CLK_EN_MISC_I2C_3] = &__clk_regmap_gate_hw(&clk_en_misc_i2c_3),
+ [RTD1625_CRT_CLK_EN_ACPU] = &__clk_regmap_gate_hw(&clk_en_acpu),
+ [RTD1625_CRT_CLK_EN_JPEG] = &__clk_regmap_gate_hw(&clk_en_jpeg),
+ [RTD1625_CRT_CLK_EN_MISC_SC0] = &__clk_regmap_gate_hw(&clk_en_misc_sc0),
+ [RTD1625_CRT_CLK_EN_HDMIRX] = &__clk_regmap_gate_hw(&clk_en_hdmirx),
+ [RTD1625_CRT_CLK_EN_HSE] = &__clk_regmap_gate_hw(&clk_en_hse),
+ [RTD1625_CRT_CLK_EN_FAN] = &__clk_regmap_gate_hw(&clk_en_fan),
+ [RTD1625_CRT_CLK_EN_SATA_WRAP_SYS] = &__clk_regmap_gate_hw(&clk_en_sata_wrap_sys),
+ [RTD1625_CRT_CLK_EN_SATA_WRAP_SYSH] = &__clk_regmap_gate_hw(&clk_en_sata_wrap_sysh),
+ [RTD1625_CRT_CLK_EN_SATA_MAC_SYSH] = &__clk_regmap_gate_hw(&clk_en_sata_mac_sysh),
+ [RTD1625_CRT_CLK_EN_R2RDSC] = &__clk_regmap_gate_hw(&clk_en_r2rdsc),
+ [RTD1625_CRT_CLK_EN_PCIE1] = &__clk_regmap_gate_hw(&clk_en_pcie1),
+ [RTD1625_CRT_CLK_EN_MISC_I2C_4] = &__clk_regmap_gate_hw(&clk_en_misc_i2c_4),
+ [RTD1625_CRT_CLK_EN_MISC_I2C_5] = &__clk_regmap_gate_hw(&clk_en_misc_i2c_5),
+ [RTD1625_CRT_CLK_EN_TSIO] = &__clk_regmap_gate_hw(&clk_en_tsio),
+ [RTD1625_CRT_CLK_EN_VE4] = &__clk_regmap_gate_hw(&clk_en_ve4),
+ [RTD1625_CRT_CLK_EN_EDP] = &__clk_regmap_gate_hw(&clk_en_edp),
+ [RTD1625_CRT_CLK_EN_TSIO_TRX] = &__clk_regmap_gate_hw(&clk_en_tsio_trx),
+ [RTD1625_CRT_CLK_EN_PCIE2] = &__clk_regmap_gate_hw(&clk_en_pcie2),
+ [RTD1625_CRT_CLK_EN_EARC] = &__clk_regmap_gate_hw(&clk_en_earc),
+ [RTD1625_CRT_CLK_EN_LITE] = &__clk_regmap_gate_hw(&clk_en_lite),
+ [RTD1625_CRT_CLK_EN_MIPI_DSI] = &__clk_regmap_gate_hw(&clk_en_mipi_dsi),
+ [RTD1625_CRT_CLK_EN_NPUPP] = &__clk_regmap_gate_hw(&clk_en_npupp),
+ [RTD1625_CRT_CLK_EN_NPU] = &__clk_regmap_gate_hw(&clk_en_npu),
+ [RTD1625_CRT_CLK_EN_AUCPU0] = &__clk_regmap_gate_hw(&clk_en_aucpu0),
+ [RTD1625_CRT_CLK_EN_AUCPU1] = &__clk_regmap_gate_hw(&clk_en_aucpu1),
+ [RTD1625_CRT_CLK_EN_NSRAM] = &__clk_regmap_gate_hw(&clk_en_nsram),
+ [RTD1625_CRT_CLK_EN_HDMITOP] = &__clk_regmap_gate_hw(&clk_en_hdmitop),
+ [RTD1625_CRT_CLK_EN_AUCPU_ISO_NPU] = &__clk_regmap_gate_hw(&clk_en_aucpu_iso_npu),
+ [RTD1625_CRT_CLK_EN_KEYLADDER] = &__clk_regmap_gate_hw(&clk_en_keyladder),
+ [RTD1625_CRT_CLK_EN_IFCP_KLM] = &__clk_regmap_gate_hw(&clk_en_ifcp_klm),
+ [RTD1625_CRT_CLK_EN_IFCP] = &__clk_regmap_gate_hw(&clk_en_ifcp),
+ [RTD1625_CRT_CLK_EN_MDL_GENPW] = &__clk_regmap_gate_hw(&clk_en_mdl_genpw),
+ [RTD1625_CRT_CLK_EN_MDL_CHIP] = &__clk_regmap_gate_hw(&clk_en_mdl_chip),
+ [RTD1625_CRT_CLK_EN_MDL_IP] = &__clk_regmap_gate_hw(&clk_en_mdl_ip),
+ [RTD1625_CRT_CLK_EN_MDLM2M] = &__clk_regmap_gate_hw(&clk_en_mdlm2m),
+ [RTD1625_CRT_CLK_EN_MDL_XTAL] = &__clk_regmap_gate_hw(&clk_en_mdl_xtal),
+ [RTD1625_CRT_CLK_EN_TEST_MUX] = &__clk_regmap_gate_hw(&clk_en_test_mux),
+ [RTD1625_CRT_CLK_EN_DLA] = &__clk_regmap_gate_hw(&clk_en_dla),
+ [RTD1625_CRT_CLK_EN_TPCW] = &__clk_regmap_gate_hw(&clk_en_tpcw),
+ [RTD1625_CRT_CLK_EN_GPU_TS_SRC] = &__clk_regmap_gate_hw(&clk_en_gpu_ts_src),
+ [RTD1625_CRT_CLK_EN_VI] = &__clk_regmap_gate_hw(&clk_en_vi),
+ [RTD1625_CRT_CLK_EN_LVDS1] = &__clk_regmap_gate_hw(&clk_en_lvds1),
+ [RTD1625_CRT_CLK_EN_LVDS2] = &__clk_regmap_gate_hw(&clk_en_lvds2),
+ [RTD1625_CRT_CLK_EN_AUCPU] = &__clk_regmap_gate_hw(&clk_en_aucpu),
+ [RTD1625_CRT_CLK_EN_UR1] = &__clk_regmap_gate_hw(&clk_en_ur1),
+ [RTD1625_CRT_CLK_EN_UR2] = &__clk_regmap_gate_hw(&clk_en_ur2),
+ [RTD1625_CRT_CLK_EN_UR3] = &__clk_regmap_gate_hw(&clk_en_ur3),
+ [RTD1625_CRT_CLK_EN_UR4] = &__clk_regmap_gate_hw(&clk_en_ur4),
+ [RTD1625_CRT_CLK_EN_UR5] = &__clk_regmap_gate_hw(&clk_en_ur5),
+ [RTD1625_CRT_CLK_EN_UR6] = &__clk_regmap_gate_hw(&clk_en_ur6),
+ [RTD1625_CRT_CLK_EN_UR7] = &__clk_regmap_gate_hw(&clk_en_ur7),
+ [RTD1625_CRT_CLK_EN_UR8] = &__clk_regmap_gate_hw(&clk_en_ur8),
+ [RTD1625_CRT_CLK_EN_UR9] = &__clk_regmap_gate_hw(&clk_en_ur9),
+ [RTD1625_CRT_CLK_EN_UR_TOP] = &__clk_regmap_gate_hw(&clk_en_ur_top),
+ [RTD1625_CRT_CLK_EN_MISC_I2C_7] = &__clk_regmap_gate_hw(&clk_en_misc_i2c_7),
+ [RTD1625_CRT_CLK_EN_MISC_I2C_6] = &__clk_regmap_gate_hw(&clk_en_misc_i2c_6),
+ [RTD1625_CRT_CLK_EN_SPI0] = &__clk_regmap_gate_hw(&clk_en_spi0),
+ [RTD1625_CRT_CLK_EN_SPI1] = &__clk_regmap_gate_hw(&clk_en_spi1),
+ [RTD1625_CRT_CLK_EN_SPI2] = &__clk_regmap_gate_hw(&clk_en_spi2),
+ [RTD1625_CRT_CLK_EN_LSADC0] = &__clk_regmap_gate_hw(&clk_en_lsadc0),
+ [RTD1625_CRT_CLK_EN_LSADC1] = &__clk_regmap_gate_hw(&clk_en_lsadc1),
+ [RTD1625_CRT_CLK_EN_ISOMIS_DMA] = &__clk_regmap_gate_hw(&clk_en_isomis_dma),
+ [RTD1625_CRT_CLK_EN_DPTX] = &__clk_regmap_gate_hw(&clk_en_dptx),
+ [RTD1625_CRT_CLK_EN_NPU_MIPI_CSI] = &__clk_regmap_gate_hw(&clk_en_npu_mipi_csi),
+ [RTD1625_CRT_CLK_EN_EDPTX] = &__clk_regmap_gate_hw(&clk_en_edptx),
+ [RTD1625_CRT_CLK_GPU] = &__clk_regmap_mux_hw(&clk_gpu),
+ [RTD1625_CRT_CLK_VE1] = &__clk_regmap_mux_hw(&clk_ve1),
+ [RTD1625_CRT_CLK_VE2] = &__clk_regmap_mux_hw(&clk_ve2),
+ [RTD1625_CRT_CLK_VE4] = &__clk_regmap_mux_hw(&clk_ve4),
+ [RTD1625_CRT_PLL_VE1] = &__clk_pll_hw(&pll_ve1),
+ [RTD1625_CRT_PLL_DDSA] = &__clk_pll_hw(&pll_ddsa),
+ [RTD1625_CRT_PLL_BUS] = &__clk_pll_hw(&pll_bus),
+ [RTD1625_CRT_CLK_SYS] = &clk_sys.hw,
+ [RTD1625_CRT_PLL_DCSB] = &__clk_pll_hw(&pll_dcsb),
+ [RTD1625_CRT_CLK_SYSH] = &clk_sysh.hw,
+ [RTD1625_CRT_PLL_GPU] = &__clk_pll_hw(&pll_gpu),
+ [RTD1625_CRT_PLL_NPU] = &__clk_pll_hw(&pll_npu),
+ [RTD1625_CRT_PLL_VE2] = &__clk_pll_hw(&pll_ve2),
+ [RTD1625_CRT_PLL_HIFI] = &__clk_pll_hw(&pll_hifi),
+ [RTD1625_CRT_PLL_EMMC_REF] = &pll_emmc_ref.hw,
+ [RTD1625_CRT_PLL_EMMC] = &__clk_pll_mmc_hw(&pll_emmc),
+ [RTD1625_CRT_PLL_EMMC_VP0] = &pll_emmc.phase0_hw,
+ [RTD1625_CRT_PLL_EMMC_VP1] = &pll_emmc.phase1_hw,
+ [RTD1625_CRT_PLL_ACPU] = &__clk_pll_hw(&pll_acpu),
+ [RTD1625_CRT_CLK_NPU] = &clk_npu.hw,
+ [RTD1625_CRT_CLK_NPU_MIPI_CSI] = &clk_npu_mipi_csi.hw,
+
+ [RTD1625_CRT_CLK_MAX] = NULL,
+ },
+};
+
+static const struct rtk_clk_desc rtd1625_crt_desc = {
+ .clk_data = &rtd1625_crt_hw_data,
+ .clks = rtd1625_crt_regmap_clks,
+ .num_clks = ARRAY_SIZE(rtd1625_crt_regmap_clks),
+};
+
+static int rtd1625_crt_probe(struct platform_device *pdev)
+{
+ const struct rtk_clk_desc *desc;
+
+ desc = of_device_get_match_data(&pdev->dev);
+ if (!desc)
+ return -EINVAL;
+
+ return rtk_clk_probe(pdev, desc, "crt_rst");
+}
+
+static const struct of_device_id rtd1625_crt_match[] = {
+ {.compatible = "realtek,rtd1625-crt-clk", .data = &rtd1625_crt_desc,},
+ {/* sentinel */}
+};
+
+static struct platform_driver rtd1625_crt_driver = {
+ .probe = rtd1625_crt_probe,
+ .driver = {
+ .name = "rtk-rtd1625-crt-clk",
+ .of_match_table = rtd1625_crt_match,
+ },
+};
+
+static int __init rtd1625_crt_init(void)
+{
+ return platform_driver_register(&rtd1625_crt_driver);
+}
+subsys_initcall(rtd1625_crt_init);
+
+MODULE_DESCRIPTION("Reatek RTD1625 CRT Controller Driver");
+MODULE_AUTHOR("Cheng-Yu Lee <cylee12@realtek.com>");
+MODULE_LICENSE("GPL");
+MODULE_IMPORT_NS("REALTEK_CLK");
diff --git a/drivers/reset/realtek/Kconfig b/drivers/reset/realtek/Kconfig
index 99a14d355803..a44c7834191c 100644
--- a/drivers/reset/realtek/Kconfig
+++ b/drivers/reset/realtek/Kconfig
@@ -1,3 +1,5 @@
# SPDX-License-Identifier: GPL-2.0-only
config RESET_RTK_COMMON
bool
+ select AUXILIARY_BUS
+ default COMMON_CLK_RTD1625
diff --git a/drivers/reset/realtek/Makefile b/drivers/reset/realtek/Makefile
index b59a3f7f2453..8ca1fa939f10 100644
--- a/drivers/reset/realtek/Makefile
+++ b/drivers/reset/realtek/Makefile
@@ -1,2 +1,2 @@
# SPDX-License-Identifier: GPL-2.0-only
-obj-$(CONFIG_RESET_RTK_COMMON) += common.o
+obj-$(CONFIG_RESET_RTK_COMMON) += common.o reset-rtd1625-crt.o
diff --git a/drivers/reset/realtek/reset-rtd1625-crt.c b/drivers/reset/realtek/reset-rtd1625-crt.c
new file mode 100644
index 000000000000..ebb15bb68885
--- /dev/null
+++ b/drivers/reset/realtek/reset-rtd1625-crt.c
@@ -0,0 +1,186 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2026 Realtek Semiconductor Corporation
+ */
+
+#include <dt-bindings/reset/realtek,rtd1625.h>
+#include <linux/auxiliary_bus.h>
+#include <linux/device.h>
+#include <linux/errno.h>
+#include <linux/slab.h>
+#include "common.h"
+
+#define RTD1625_CRT_RSTN_MAX 123
+
+static struct rtk_reset_desc rtd1625_crt_reset_descs[] = {
+ /* Bank 0: offset 0x0 */
+ [RTD1625_CRT_RSTN_MISC] = { .ofs = 0x0, .bit = 0, .write_en = 1 },
+ [RTD1625_CRT_RSTN_DIP] = { .ofs = 0x0, .bit = 2, .write_en = 1 },
+ [RTD1625_CRT_RSTN_GSPI] = { .ofs = 0x0, .bit = 4, .write_en = 1 },
+ [RTD1625_CRT_RSTN_SDS] = { .ofs = 0x0, .bit = 6, .write_en = 1 },
+ [RTD1625_CRT_RSTN_SDS_REG] = { .ofs = 0x0, .bit = 8, .write_en = 1 },
+ [RTD1625_CRT_RSTN_SDS_PHY] = { .ofs = 0x0, .bit = 10, .write_en = 1 },
+ [RTD1625_CRT_RSTN_GPU2D] = { .ofs = 0x0, .bit = 12, .write_en = 1 },
+ [RTD1625_CRT_RSTN_DC_PHY] = { .ofs = 0x0, .bit = 22, .write_en = 1 },
+ [RTD1625_CRT_RSTN_DCPHY_CRT] = { .ofs = 0x0, .bit = 24, .write_en = 1 },
+ [RTD1625_CRT_RSTN_LSADC] = { .ofs = 0x0, .bit = 26, .write_en = 1 },
+ [RTD1625_CRT_RSTN_SE] = { .ofs = 0x0, .bit = 28, .write_en = 1 },
+ [RTD1625_CRT_RSTN_DLA] = { .ofs = 0x0, .bit = 30, .write_en = 1 },
+ /* Bank 1: offset 0x4 */
+ [RTD1625_CRT_RSTN_JPEG] = { .ofs = 0x4, .bit = 0, .write_en = 1 },
+ [RTD1625_CRT_RSTN_SD] = { .ofs = 0x4, .bit = 2, .write_en = 1 },
+ [RTD1625_CRT_RSTN_SDIO] = { .ofs = 0x4, .bit = 6, .write_en = 1 },
+ [RTD1625_CRT_RSTN_PCR_CNT] = { .ofs = 0x4, .bit = 8, .write_en = 1 },
+ [RTD1625_CRT_RSTN_PCIE0_STITCH] = { .ofs = 0x4, .bit = 10, .write_en = 1 },
+ [RTD1625_CRT_RSTN_PCIE0_PHY] = { .ofs = 0x4, .bit = 12, .write_en = 1 },
+ [RTD1625_CRT_RSTN_PCIE0] = { .ofs = 0x4, .bit = 14, .write_en = 1 },
+ [RTD1625_CRT_RSTN_PCIE0_CORE] = { .ofs = 0x4, .bit = 16, .write_en = 1 },
+ [RTD1625_CRT_RSTN_PCIE0_POWER] = { .ofs = 0x4, .bit = 18, .write_en = 1 },
+ [RTD1625_CRT_RSTN_PCIE0_NONSTICH] = { .ofs = 0x4, .bit = 20, .write_en = 1 },
+ [RTD1625_CRT_RSTN_PCIE0_PHY_MDIO] = { .ofs = 0x4, .bit = 22, .write_en = 1 },
+ [RTD1625_CRT_RSTN_PCIE0_SGMII_MDIO] = { .ofs = 0x4, .bit = 24, .write_en = 1 },
+ [RTD1625_CRT_RSTN_VO2] = { .ofs = 0x4, .bit = 28, .write_en = 1 },
+ [RTD1625_CRT_RSTN_MISC_SC0] = { .ofs = 0x4, .bit = 30, .write_en = 1 },
+ /* Bank 2: offset 0x8 */
+ [RTD1625_CRT_RSTN_MD] = { .ofs = 0x8, .bit = 4, .write_en = 1 },
+ [RTD1625_CRT_RSTN_LVDS1] = { .ofs = 0x8, .bit = 6, .write_en = 1 },
+ [RTD1625_CRT_RSTN_LVDS2] = { .ofs = 0x8, .bit = 8, .write_en = 1 },
+ [RTD1625_CRT_RSTN_MISC_SC1] = { .ofs = 0x8, .bit = 10, .write_en = 1 },
+ [RTD1625_CRT_RSTN_I2C_3] = { .ofs = 0x8, .bit = 12, .write_en = 1 },
+ [RTD1625_CRT_RSTN_FAN] = { .ofs = 0x8, .bit = 14, .write_en = 1 },
+ [RTD1625_CRT_RSTN_TVE] = { .ofs = 0x8, .bit = 16, .write_en = 1 },
+ [RTD1625_CRT_RSTN_AIO] = { .ofs = 0x8, .bit = 18, .write_en = 1 },
+ [RTD1625_CRT_RSTN_VO] = { .ofs = 0x8, .bit = 20, .write_en = 1 },
+ [RTD1625_CRT_RSTN_MIPI_CSI] = { .ofs = 0x8, .bit = 22, .write_en = 1 },
+ [RTD1625_CRT_RSTN_HDMIRX] = { .ofs = 0x8, .bit = 24, .write_en = 1 },
+ [RTD1625_CRT_RSTN_HDMIRX_WRAP] = { .ofs = 0x8, .bit = 26, .write_en = 1 },
+ [RTD1625_CRT_RSTN_HDMI] = { .ofs = 0x8, .bit = 28, .write_en = 1 },
+ [RTD1625_CRT_RSTN_DISP] = { .ofs = 0x8, .bit = 30, .write_en = 1 },
+ /* Bank 3: offset 0xc */
+ [RTD1625_CRT_RSTN_SATA_PHY_POW1] = { .ofs = 0xc, .bit = 0, .write_en = 1 },
+ [RTD1625_CRT_RSTN_SATA_PHY_POW0] = { .ofs = 0xc, .bit = 2, .write_en = 1 },
+ [RTD1625_CRT_RSTN_SATA_MDIO1] = { .ofs = 0xc, .bit = 4, .write_en = 1 },
+ [RTD1625_CRT_RSTN_SATA_MDIO0] = { .ofs = 0xc, .bit = 6, .write_en = 1 },
+ [RTD1625_CRT_RSTN_SATA_WRAP] = { .ofs = 0xc, .bit = 8, .write_en = 1 },
+ [RTD1625_CRT_RSTN_SATA_MAC_P1] = { .ofs = 0xc, .bit = 10, .write_en = 1 },
+ [RTD1625_CRT_RSTN_SATA_MAC_P0] = { .ofs = 0xc, .bit = 12, .write_en = 1 },
+ [RTD1625_CRT_RSTN_SATA_MAC_COM] = { .ofs = 0xc, .bit = 14, .write_en = 1 },
+ [RTD1625_CRT_RSTN_PCIE1_STITCH] = { .ofs = 0xc, .bit = 16, .write_en = 1 },
+ [RTD1625_CRT_RSTN_PCIE1_PHY] = { .ofs = 0xc, .bit = 18, .write_en = 1 },
+ [RTD1625_CRT_RSTN_PCIE1] = { .ofs = 0xc, .bit = 20, .write_en = 1 },
+ [RTD1625_CRT_RSTN_PCIE1_CORE] = { .ofs = 0xc, .bit = 22, .write_en = 1 },
+ [RTD1625_CRT_RSTN_PCIE1_POWER] = { .ofs = 0xc, .bit = 24, .write_en = 1 },
+ [RTD1625_CRT_RSTN_PCIE1_NONSTICH] = { .ofs = 0xc, .bit = 26, .write_en = 1 },
+ [RTD1625_CRT_RSTN_PCIE1_PHY_MDIO] = { .ofs = 0xc, .bit = 28, .write_en = 1 },
+ [RTD1625_CRT_RSTN_HDMITOP] = { .ofs = 0xc, .bit = 30, .write_en = 1 },
+ /* Bank 4: offset 0x68 */
+ [RTD1625_CRT_RSTN_I2C_4] = { .ofs = 0x68, .bit = 2, .write_en = 1 },
+ [RTD1625_CRT_RSTN_I2C_5] = { .ofs = 0x68, .bit = 4, .write_en = 1 },
+ [RTD1625_CRT_RSTN_TSIO] = { .ofs = 0x68, .bit = 6, .write_en = 1 },
+ [RTD1625_CRT_RSTN_VI] = { .ofs = 0x68, .bit = 8, .write_en = 1 },
+ [RTD1625_CRT_RSTN_EDP] = { .ofs = 0x68, .bit = 10, .write_en = 1 },
+ [RTD1625_CRT_RSTN_VE1_MMU] = { .ofs = 0x68, .bit = 12, .write_en = 1 },
+ [RTD1625_CRT_RSTN_VE1_MMU_FUNC] = { .ofs = 0x68, .bit = 14, .write_en = 1 },
+ [RTD1625_CRT_RSTN_HSE_MMU] = { .ofs = 0x68, .bit = 16, .write_en = 1 },
+ [RTD1625_CRT_RSTN_HSE_MMU_FUNC] = { .ofs = 0x68, .bit = 18, .write_en = 1 },
+ [RTD1625_CRT_RSTN_MDLM2M] = { .ofs = 0x68, .bit = 20, .write_en = 1 },
+ [RTD1625_CRT_RSTN_ISO_GSPI] = { .ofs = 0x68, .bit = 22, .write_en = 1 },
+ [RTD1625_CRT_RSTN_SOFT_NPU] = { .ofs = 0x68, .bit = 24, .write_en = 1 },
+ [RTD1625_CRT_RSTN_SPI2EMMC] = { .ofs = 0x68, .bit = 26, .write_en = 1 },
+ [RTD1625_CRT_RSTN_EARC] = { .ofs = 0x68, .bit = 28, .write_en = 1 },
+ [RTD1625_CRT_RSTN_VE1] = { .ofs = 0x68, .bit = 30, .write_en = 1 },
+ /* Bank 5: offset 0x90 */
+ [RTD1625_CRT_RSTN_PCIE2_STITCH] = { .ofs = 0x90, .bit = 0, .write_en = 1 },
+ [RTD1625_CRT_RSTN_PCIE2_PHY] = { .ofs = 0x90, .bit = 2, .write_en = 1 },
+ [RTD1625_CRT_RSTN_PCIE2] = { .ofs = 0x90, .bit = 4, .write_en = 1 },
+ [RTD1625_CRT_RSTN_PCIE2_CORE] = { .ofs = 0x90, .bit = 6, .write_en = 1 },
+ [RTD1625_CRT_RSTN_PCIE2_POWER] = { .ofs = 0x90, .bit = 8, .write_en = 1 },
+ [RTD1625_CRT_RSTN_PCIE2_NONSTICH] = { .ofs = 0x90, .bit = 10, .write_en = 1 },
+ [RTD1625_CRT_RSTN_PCIE2_PHY_MDIO] = { .ofs = 0x90, .bit = 12, .write_en = 1 },
+ [RTD1625_CRT_RSTN_DCPHY_UMCTL2] = { .ofs = 0x90, .bit = 14, .write_en = 1 },
+ [RTD1625_CRT_RSTN_MIPI_DSI] = { .ofs = 0x90, .bit = 16, .write_en = 1 },
+ [RTD1625_CRT_RSTN_HIFM] = { .ofs = 0x90, .bit = 18, .write_en = 1 },
+ [RTD1625_CRT_RSTN_NSRAM] = { .ofs = 0x90, .bit = 20, .write_en = 1 },
+ [RTD1625_CRT_RSTN_AUCPU0_REG] = { .ofs = 0x90, .bit = 22, .write_en = 1 },
+ [RTD1625_CRT_RSTN_MDL_GENPW] = { .ofs = 0x90, .bit = 24, .write_en = 1 },
+ [RTD1625_CRT_RSTN_MDL_CHIP] = { .ofs = 0x90, .bit = 26, .write_en = 1 },
+ [RTD1625_CRT_RSTN_MDL_IP] = { .ofs = 0x90, .bit = 28, .write_en = 1 },
+ [RTD1625_CRT_RSTN_TEST_MUX] = { .ofs = 0x90, .bit = 30, .write_en = 1 },
+ /* Bank 6: offset 0xb8 */
+ [RTD1625_CRT_RSTN_ISO_BIST] = { .ofs = 0xb8, .bit = 0, .write_en = 1 },
+ [RTD1625_CRT_RSTN_MAIN_BIST] = { .ofs = 0xb8, .bit = 2, .write_en = 1 },
+ [RTD1625_CRT_RSTN_MAIN2_BIST] = { .ofs = 0xb8, .bit = 4, .write_en = 1 },
+ [RTD1625_CRT_RSTN_VE1_BIST] = { .ofs = 0xb8, .bit = 6, .write_en = 1 },
+ [RTD1625_CRT_RSTN_VE2_BIST] = { .ofs = 0xb8, .bit = 8, .write_en = 1 },
+ [RTD1625_CRT_RSTN_DCPHY_BIST] = { .ofs = 0xb8, .bit = 10, .write_en = 1 },
+ [RTD1625_CRT_RSTN_GPU_BIST] = { .ofs = 0xb8, .bit = 12, .write_en = 1 },
+ [RTD1625_CRT_RSTN_DISP_BIST] = { .ofs = 0xb8, .bit = 14, .write_en = 1 },
+ [RTD1625_CRT_RSTN_NPU_BIST] = { .ofs = 0xb8, .bit = 16, .write_en = 1 },
+ [RTD1625_CRT_RSTN_CAS_BIST] = { .ofs = 0xb8, .bit = 18, .write_en = 1 },
+ [RTD1625_CRT_RSTN_VE4_BIST] = { .ofs = 0xb8, .bit = 20, .write_en = 1 },
+ /* Bank 7: offset 0x454 (DUMMY0, no write_en) */
+ [RTD1625_CRT_RSTN_EMMC] = { .ofs = 0x454, .bit = 0 },
+ /* Bank 8: offset 0x458 (DUMMY1, no write_en) */
+ [RTD1625_CRT_RSTN_GPU] = { .ofs = 0x458, .bit = 0 },
+ /* Bank 9: offset 0x464 (DUMMY4, no write_en) */
+ [RTD1625_CRT_RSTN_VE2] = { .ofs = 0x464, .bit = 0 },
+ /* Bank 10: offset 0x880 */
+ [RTD1625_CRT_RSTN_UR1] = { .ofs = 0x880, .bit = 0, .write_en = 1 },
+ [RTD1625_CRT_RSTN_UR2] = { .ofs = 0x880, .bit = 2, .write_en = 1 },
+ [RTD1625_CRT_RSTN_UR3] = { .ofs = 0x880, .bit = 4, .write_en = 1 },
+ [RTD1625_CRT_RSTN_UR4] = { .ofs = 0x880, .bit = 6, .write_en = 1 },
+ [RTD1625_CRT_RSTN_UR5] = { .ofs = 0x880, .bit = 8, .write_en = 1 },
+ [RTD1625_CRT_RSTN_UR6] = { .ofs = 0x880, .bit = 10, .write_en = 1 },
+ [RTD1625_CRT_RSTN_UR7] = { .ofs = 0x880, .bit = 12, .write_en = 1 },
+ [RTD1625_CRT_RSTN_UR8] = { .ofs = 0x880, .bit = 14, .write_en = 1 },
+ [RTD1625_CRT_RSTN_UR9] = { .ofs = 0x880, .bit = 16, .write_en = 1 },
+ [RTD1625_CRT_RSTN_UR_TOP] = { .ofs = 0x880, .bit = 18, .write_en = 1 },
+ [RTD1625_CRT_RSTN_I2C_7] = { .ofs = 0x880, .bit = 28, .write_en = 1 },
+ [RTD1625_CRT_RSTN_I2C_6] = { .ofs = 0x880, .bit = 30, .write_en = 1 },
+ /* Bank 11: offset 0x890 */
+ [RTD1625_CRT_RSTN_SPI0] = { .ofs = 0x890, .bit = 0, .write_en = 1 },
+ [RTD1625_CRT_RSTN_SPI1] = { .ofs = 0x890, .bit = 2, .write_en = 1 },
+ [RTD1625_CRT_RSTN_SPI2] = { .ofs = 0x890, .bit = 4, .write_en = 1 },
+ [RTD1625_CRT_RSTN_LSADC0] = { .ofs = 0x890, .bit = 16, .write_en = 1 },
+ [RTD1625_CRT_RSTN_LSADC1] = { .ofs = 0x890, .bit = 18, .write_en = 1 },
+ [RTD1625_CRT_RSTN_ISOMIS_DMA] = { .ofs = 0x890, .bit = 20, .write_en = 1 },
+ [RTD1625_CRT_RSTN_AUDIO_ADC] = { .ofs = 0x890, .bit = 22, .write_en = 1 },
+ [RTD1625_CRT_RSTN_DPTX] = { .ofs = 0x890, .bit = 24, .write_en = 1 },
+ [RTD1625_CRT_RSTN_AUCPU1_REG] = { .ofs = 0x890, .bit = 26, .write_en = 1 },
+ [RTD1625_CRT_RSTN_EDPTX] = { .ofs = 0x890, .bit = 28, .write_en = 1 },
+};
+
+static int rtd1625_crt_reset_probe(struct auxiliary_device *adev,
+ const struct auxiliary_device_id *id)
+{
+ struct device *dev = &adev->dev;
+ struct rtk_reset_data *data;
+
+ data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
+
+ data->descs = rtd1625_crt_reset_descs;
+ data->rcdev.nr_resets = RTD1625_CRT_RSTN_MAX;
+ return rtk_reset_controller_add(dev, data);
+}
+
+static const struct auxiliary_device_id rtd1625_crt_reset_ids[] = {
+ {
+ .name = "clk_rtk.crt_rst",
+ },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(auxiliary, rtd1625_crt_reset_ids);
+
+static struct auxiliary_driver rtd1625_crt_driver = {
+ .probe = rtd1625_crt_reset_probe,
+ .id_table = rtd1625_crt_reset_ids,
+ .driver = {
+ .name = "rtd1625-crt-reset",
+ },
+};
+module_auxiliary_driver(rtd1625_crt_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_IMPORT_NS("REALTEK_RESET");
--
2.34.1
^ permalink raw reply related
* ✅ PASS (MISSED 2 of 56): Test report for for-kernelci (7.0.0-rc6, upstream-arm-next, 851b1b57)
From: cki-project @ 2026-04-02 8:23 UTC (permalink / raw)
To: will, linux-arm-kernel, catalin.marinas
Hi, we tested your kernel and here are the results:
Overall result: PASSED
Merge: OK
Compile: OK
Test: OK
Tested-by: CKI Project <cki-project@redhat.com>
Kernel information:
Commit message: Merge remote-tracking branch 'origin/nocache-cleanup' into for-kernelci
You can find all the details about the test run at
https://datawarehouse.cki-project.org/kcidb/checkouts/redhat:2424789119
Tests that were not ran because of internal issues:
/distribution/command [aarch64]
Reboot test [aarch64]
If you find a failure unrelated to your changes, please ask the test maintainer to review it.
This will prevent the failures from being incorrectly reported in the future.
Please reply to this email if you have any questions about the tests that we
ran or if you have any suggestions on how to make future tests more effective.
,-. ,-.
( C ) ( K ) Continuous
`-',-.`-' Kernel
( I ) Integration
`-'
______________________________________________________________________________
^ permalink raw reply
* Re: [PATCH v2 2/3] mailbox: exynos: Add support for Exynos850 mailbox
From: Tudor Ambarus @ 2026-04-02 8:42 UTC (permalink / raw)
To: Alexey Klimov, Krzysztof Kozlowski, Sylwester Nawrocki,
Chanwoo Choi, Alim Akhtar, Sam Protsenko, Michael Turquette,
Stephen Boyd, Rob Herring, Conor Dooley, Jassi Brar
Cc: Krzysztof Kozlowski, Peter Griffin, linux-samsung-soc,
linux-arm-kernel, linux-clk, devicetree, linux-kernel
In-Reply-To: <20260402-exynos850-ap2apm-mailbox-v2-2-ca5ffdff99d4@linaro.org>
Hi, Alexey,
On 4/2/26 5:20 AM, Alexey Klimov wrote:
> Exynos850-based platforms support ACPM and has similar workflow
> of communicating with ACPM via mailbox, however mailbox controller
> registers are located at different offsets and writes/reads could be
> different. To distinguish between such different behaviours,
> the registers offsets for Exynos850 and the platform-specific data
> structs are introduced and configuration is described in such structs
> for gs101 and exynos850 based SoCs. Probe routine now selects the
> corresponding platform-specific data via device_get_match_data().
>
> Signed-off-by: Alexey Klimov <alexey.klimov@linaro.org>
> ---
> drivers/mailbox/exynos-mailbox.c | 67 ++++++++++++++++++++++++++++++++++++++--
> 1 file changed, 64 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/mailbox/exynos-mailbox.c b/drivers/mailbox/exynos-mailbox.c
> index d2355b128ba4..f9c59c07558a 100644
> --- a/drivers/mailbox/exynos-mailbox.c
> +++ b/drivers/mailbox/exynos-mailbox.c
> @@ -31,14 +31,61 @@
>
> #define EXYNOS_MBOX_CHAN_COUNT HWEIGHT32(EXYNOS_MBOX_INTGR1_MASK)
>
> +#define EXYNOS850_MBOX_MCUCTRL 0x0 /* Mailbox Control Register */
> +#define EXYNOS850_MBOX_INTGR0 0x8 /* Interrupt Generation Register 0 */
> +#define EXYNOS850_MBOX_INTCR0 0x0C /* Interrupt Clear Register 0 */
> +#define EXYNOS850_MBOX_INTMR0 0x10 /* Interrupt Mask Register 0 */
> +#define EXYNOS850_MBOX_INTSR0 0x14 /* Interrupt Status Register 0 */
> +#define EXYNOS850_MBOX_INTMSR0 0x18 /* Interrupt Mask Status Register 0 */
> +#define EXYNOS850_MBOX_INTGR1 0x1C /* Interrupt Generation Register 1 */
> +#define EXYNOS850_MBOX_INTMR1 0x24 /* Interrupt Mask Register 1 */
> +#define EXYNOS850_MBOX_INTSR1 0x28 /* Interrupt Status Register 1 */
> +#define EXYNOS850_MBOX_INTMSR1 0x2C /* Interrupt Mask Status Register 1 */
> +#define EXYNOS850_MBOX_VERSION 0x70
Please consider defining just the registers that are used, to not
pollute the driver. You may drop the unused gs101 definitions too.
> +
> +#define EXYNOS850_MBOX_INTMR1_MASK GENMASK(15, 0)
> +
> +/**
> + * struct exynos_mbox_driver_data - platform-specific mailbox configuration.
> + * @irq_doorbell_offset: offset to the IRQ generation register, doorbell
> + * to APM co-processor.
> + * @irq_doorbell_shift: shift to apply to the value written to IRQ
> + * generation register.
> + * @irq_mask_offset: offset to the IRQ mask register.
> + * @irq_mask_value: value to right to the mask register to mask out
> + * all interrupts.
> + */
> +struct exynos_mbox_driver_data {
> + u16 irq_doorbell_offset;
> + u16 irq_doorbell_shift;
> + u16 irq_mask_offset;
> + u16 irq_mask_value;
> +};
> +
> /**
> * struct exynos_mbox - driver's private data.
> * @regs: mailbox registers base address.
> * @mbox: pointer to the mailbox controller.
> + * @data: pointer to driver platform-specific data.
> */
> struct exynos_mbox {
> void __iomem *regs;
> struct mbox_controller *mbox;
> + const struct exynos_mbox_driver_data *data;
> +};
> +
> +static const struct exynos_mbox_driver_data exynos850_mbox_data = {
> + .irq_doorbell_offset = EXYNOS850_MBOX_INTGR0,
> + .irq_doorbell_shift = 16,
> + .irq_mask_offset = EXYNOS850_MBOX_INTMR1,
> + .irq_mask_value = EXYNOS850_MBOX_INTMR1_MASK,
> +};
> +
> +static const struct exynos_mbox_driver_data exynos_gs101_mbox_data = {
> + .irq_doorbell_offset = EXYNOS_MBOX_INTGR1,
> + .irq_doorbell_shift = 0,
> + .irq_mask_offset = EXYNOS_MBOX_INTMR0,
> + .irq_mask_value = EXYNOS_MBOX_INTMR0_MASK,
> };
I find it strange that the SoCs use different registers. Are you sure you're
using the right direction? i.e. ring the doorbell to APM and not to AP?
>
> static int exynos_mbox_send_data(struct mbox_chan *chan, void *data)
> @@ -57,7 +104,8 @@ static int exynos_mbox_send_data(struct mbox_chan *chan, void *data)
> return -EINVAL;
> }
>
> - writel(BIT(msg->chan_id), exynos_mbox->regs + EXYNOS_MBOX_INTGR1);
> + writel(BIT(msg->chan_id) << exynos_mbox->data->irq_doorbell_shift,
> + exynos_mbox->regs + exynos_mbox->data->irq_doorbell_offset);
Use FIELD_PREP from <linux/bitfield.h> please. You will use a mask instead of
a shift.
I would rename irq_doorbell_offset to intgr. It aligns with the register name
from the datasheet. You won't need to prepend _offset to the name, we already
see it's an offset when doing the writel().
>
> return 0;
> }
> @@ -87,13 +135,21 @@ static struct mbox_chan *exynos_mbox_of_xlate(struct mbox_controller *mbox,
> }
>
> static const struct of_device_id exynos_mbox_match[] = {
> - { .compatible = "google,gs101-mbox" },
> + {
> + .compatible = "google,gs101-mbox",
> + .data = &exynos_gs101_mbox_data
> + },
> + {
> + .compatible = "samsung,exynos850-mbox",
> + .data = &exynos850_mbox_data
> + },
> {},
> };
> MODULE_DEVICE_TABLE(of, exynos_mbox_match);
>
> static int exynos_mbox_probe(struct platform_device *pdev)
> {
> + const struct exynos_mbox_driver_data *data;
> struct device *dev = &pdev->dev;
> struct exynos_mbox *exynos_mbox;
> struct mbox_controller *mbox;
> @@ -122,6 +178,11 @@ static int exynos_mbox_probe(struct platform_device *pdev)
> return dev_err_probe(dev, PTR_ERR(pclk),
> "Failed to enable clock.\n");
>
> + data = device_get_match_data(&pdev->dev);
> + if (!data)
> + return -ENODEV;
> +
> + exynos_mbox->data = data;
> mbox->num_chans = EXYNOS_MBOX_CHAN_COUNT;
> mbox->chans = chans;
> mbox->dev = dev;
> @@ -133,7 +194,7 @@ static int exynos_mbox_probe(struct platform_device *pdev)
> platform_set_drvdata(pdev, exynos_mbox);
>
> /* Mask out all interrupts. We support just polling channels for now. */
> - writel(EXYNOS_MBOX_INTMR0_MASK, exynos_mbox->regs + EXYNOS_MBOX_INTMR0);
> + writel(data->irq_mask_value, exynos_mbox->regs + data->irq_mask_offset);
>
and here I would s/irq_mask_value/intmr_mask and irq_mask_offset/intmr.
Cheers,
ta
> return devm_mbox_controller_register(dev, mbox);
> }
>
^ permalink raw reply
* Re: [PATCH v2 0/3] Exynos850 APM-to-AP mailbox support
From: Tudor Ambarus @ 2026-04-02 8:45 UTC (permalink / raw)
To: Alexey Klimov, Krzysztof Kozlowski, Sylwester Nawrocki,
Chanwoo Choi, Alim Akhtar, Sam Protsenko, Michael Turquette,
Stephen Boyd, Rob Herring, Conor Dooley, Jassi Brar
Cc: Krzysztof Kozlowski, Peter Griffin, linux-samsung-soc,
linux-arm-kernel, linux-clk, devicetree, linux-kernel
In-Reply-To: <20260402-exynos850-ap2apm-mailbox-v2-0-ca5ffdff99d4@linaro.org>
Hi!
On 4/2/26 5:20 AM, Alexey Klimov wrote:
> This patch series introduces support for the APM-to-AP mailbox on the
If AP initiates the communication and APM responds, shouldn't this be called
AP-to-APM mailbox?
Cheers,
ta
^ permalink raw reply
* Re: [PATCH v2 1/3] dt-bindings: mailbox: google,gs101-mbox: Add samsung,exynos850-mbox
From: Tudor Ambarus @ 2026-04-02 8:46 UTC (permalink / raw)
To: Alexey Klimov, Krzysztof Kozlowski, Sylwester Nawrocki,
Chanwoo Choi, Alim Akhtar, Sam Protsenko, Michael Turquette,
Stephen Boyd, Rob Herring, Conor Dooley, Jassi Brar
Cc: Krzysztof Kozlowski, Peter Griffin, linux-samsung-soc,
linux-arm-kernel, linux-clk, devicetree, linux-kernel
In-Reply-To: <20260402-exynos850-ap2apm-mailbox-v2-1-ca5ffdff99d4@linaro.org>
Reviewed-by: Tudor Ambarus <tudor.ambarus@linaro.org>
^ permalink raw reply
* Re: [PATCH v2 3/3] arm64: dts: exynos850: Add ap2apm mailbox
From: Tudor Ambarus @ 2026-04-02 8:48 UTC (permalink / raw)
To: Alexey Klimov, Krzysztof Kozlowski, Sylwester Nawrocki,
Chanwoo Choi, Alim Akhtar, Sam Protsenko, Michael Turquette,
Stephen Boyd, Rob Herring, Conor Dooley, Jassi Brar
Cc: Krzysztof Kozlowski, Peter Griffin, linux-samsung-soc,
linux-arm-kernel, linux-clk, devicetree, linux-kernel
In-Reply-To: <20260402-exynos850-ap2apm-mailbox-v2-3-ca5ffdff99d4@linaro.org>
On 4/2/26 5:20 AM, Alexey Klimov wrote:
> Add mailbox node that describes AP-to-APM mailbox, that can be
okay so here it's AP-to-APM mailbox.
> used for communicating with APM co-processor on Exynos850 SoCs.
>
> Signed-off-by: Alexey Klimov <alexey.klimov@linaro.org>
> ---
> arch/arm64/boot/dts/exynos/exynos850.dtsi | 9 +++++++++
> 1 file changed, 9 insertions(+)
>
> diff --git a/arch/arm64/boot/dts/exynos/exynos850.dtsi b/arch/arm64/boot/dts/exynos/exynos850.dtsi
> index cb55015c8dce..fcb665ccc7ae 100644
> --- a/arch/arm64/boot/dts/exynos/exynos850.dtsi
> +++ b/arch/arm64/boot/dts/exynos/exynos850.dtsi
> @@ -298,6 +298,15 @@ cmu_apm: clock-controller@11800000 {
> clock-names = "oscclk", "dout_clkcmu_apm_bus";
> };
>
> + ap2apm_mailbox: mailbox@11900000 {
> + compatible = "samsung,exynos850-mbox";
> + reg = <0x11900000 0x1000>;
> + clocks = <&cmu_apm CLK_GOUT_MAILBOX_APM_AP_PCLK>;
> + clock-names = "pclk";
> + interrupts = <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>;
> + #mbox-cells = <0>;
> + };
> +
lgtm:
Reviewed-by: Tudor Ambarus <tudor.ambarus@linaro.org>
> cmu_cmgp: clock-controller@11c00000 {
> compatible = "samsung,exynos850-cmu-cmgp";
> reg = <0x11c00000 0x8000>;
>
^ permalink raw reply
* Re: [PATCH 0/5] crc64: Tweak intrinsics code and enable it for ARM
From: Ard Biesheuvel @ 2026-04-02 8:52 UTC (permalink / raw)
To: Eric Biggers; +Cc: linux-crypto, linux-arm-kernel, Demian Shulhan
In-Reply-To: <20260401195943.GA2466@quark>
On Wed, 1 Apr 2026, at 21:59, Eric Biggers wrote:
> On Mon, Mar 30, 2026 at 04:46:31PM +0200, Ard Biesheuvel wrote:
>> Apply some tweaks to the new arm64 crc64 NEON intrinsics code, and wire
>> it up for the 32-bit ARM build. Note that true 32-bit ARM CPUs usually
>> don't implement the prerequisite 64x64 PMULL instructions, but 32-bit
>> kernels are commonly used on 64-bit capable hardware too, which do
>> implement the 32-bit versions of the crypto instructions if they are
>> implemented for the 64-bit ISA (as per the architecture).
>>
>> Cc: Demian Shulhan <demyansh@gmail.com>
>> Cc: Eric Biggers <ebiggers@kernel.org>
>>
>> Ard Biesheuvel (5):
>> lib/crc: arm64: Drop unnecessary chunking logic from crc64
>> lib/crc: arm64: Use existing macros for kernel-mode FPU cflags
>> ARM: Add a neon-intrinsics.h header like on arm64
>> lib/crc: arm64: Simplify intrinsics implementation
>> lib/crc: arm: Enable arm64's NEON intrinsics implementation of crc64
>
> I think patches 3 and 4 should be swapped, so it's cleanups first (which
> make sense regardless of the 32-bit ARM support) and then the 32-bit ARM
> support.
>
Ok.
> I do think we should be aware that even with the code mostly shared
> using the NEON intrinsics, the 32-bit ARM support (which works only on
> CPUs that support PMULL, i.e. are also 64-bit capable) doesn't come for
> free. We should expect to deal with occasional issues related to the
> intrinsics with certain compiler versions, compiler flags, etc.
>
> I assume that "32-bit kernels on ARMv8 CPUs" is currently still a big
> enough niche to bother with this, despite that niche getting smaller
> over time.
Running a 32-bit kernel on 64-bit capable hardware is usually done to reduce the RAM footprint, and that problem hasn't gotten any smaller lately. And 20x speedup is rather significant.
> But as I mentioned I do think we should try to simplify it
> as much as possible, e.g. by supporting little-endian only and avoiding
> #ifdefs based on things like the compiler whenever possible.
>
Sure. The only reason I think this is worth the effort is because the same code can be used on ARM and arm64, so once this is no longer the case, I don't think we should bother.
So it makes sense to apply this reasoning to little endian as well - arm64 supports it so we can support in on ARM too.
^ permalink raw reply
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