[PATCH v2] sh: sh7305: add TMU0 clock support

From: Artem Novak

Date: Fri Oct 30 2026 - 19:07:15 EST


Register the SH7305 master, peripheral, bus and CPU clocks using
the SuperH clock framework. Add the TMU0 module clock gate using
MSTPCR0 bit 15.

Keeping SH7305 clock initialization independent of the legacy CPG
initialization framework, which relies on arch_init_clk_ops().
Disable SH_CLK_CPG_LEGACY for SH7305.

update: SH7305 TMU device tree node will use the
renesas,tmu-sh7305 compatible.

Signed-off-by: Artem Novak <artem122novak@xxxxxxxxx>
---
arch/sh/Kconfig | 2 +-
arch/sh/boot/dts/sh7305.dtsi | 2 +-
arch/sh/kernel/cpu/sh4a/clock-sh7305.c | 78 +++++++++++++++++++-------
3 files changed, 60 insertions(+), 22 deletions(-)

diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig
index 5ce7df11c3ec..315a1d6ee452 100644
--- a/arch/sh/Kconfig
+++ b/arch/sh/Kconfig
@@ -532,7 +532,7 @@ config SH_CLK_CPG
def_bool y

config SH_CLK_CPG_LEGACY
- depends on SH_CLK_CPG
+ depends on SH_CLK_CPG && !CPU_SUBTYPE_SH7305
def_bool y if !CPU_SUBTYPE_SH7785 && !ARCH_SHMOBILE && \
!CPU_SHX3 && !CPU_SUBTYPE_SH7757 && \
!CPU_SUBTYPE_SH7734 && !CPU_SUBTYPE_SH7264 && \
diff --git a/arch/sh/boot/dts/sh7305.dtsi b/arch/sh/boot/dts/sh7305.dtsi
index e7dd8b15445d..501b166554b0 100644
--- a/arch/sh/boot/dts/sh7305.dtsi
+++ b/arch/sh/boot/dts/sh7305.dtsi
@@ -30,7 +30,7 @@ intc: interrupt-controller {
* hardware. Clock provider integration is still required.
*/
tmu0: timer@a4490000 {
- compatible = "renesas,sh7305-tmu", "renesas,tmu";
+ compatible = "renesas,tmu-sh7305", "renesas,tmu";
reg = <0xa4490000 0x2c>;
interrupts = <0x400>, <0x420>, <0x440>;
interrupt-names = "tuni0", "tuni1", "tuni2";
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7305.c b/arch/sh/kernel/cpu/sh4a/clock-sh7305.c
index 0e683dd6de11..03d4b5f987dd 100644
--- a/arch/sh/kernel/cpu/sh4a/clock-sh7305.c
+++ b/arch/sh/kernel/cpu/sh4a/clock-sh7305.c
@@ -7,6 +7,8 @@
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/io.h>
+#include <linux/clk.h>
+#include <linux/clkdev.h>
#include <linux/sh_clk.h>

#include <asm/clock.h>
@@ -84,13 +86,13 @@ static unsigned int sh7305_divisor(unsigned int shift)
/*
* master_clk is the clock before the B/I/P divider stages.
*/
-static void master_clk_init(struct clk *clk)
+static unsigned long master_clk_recalc(struct clk *clk)
{
- clk->rate = sh7305_base_rate();
+ return sh7305_base_rate();
}

static struct sh_clk_ops sh7305_master_clk_ops = {
- .init = master_clk_init,
+ .recalc = master_clk_recalc,
};


@@ -140,27 +142,63 @@ static struct sh_clk_ops sh7305_cpu_clk_ops = {


/*
- * Ordering must match arch/sh/kernel/cpu/clock-cpg.c:
- *
- * 0 master
- * 1 peripheral
- * 2 bus
- * 3 cpu
+ * SH7305 main clocks.
*/
-static struct sh_clk_ops *sh7305_clk_ops[] = {
- &sh7305_master_clk_ops,
- &sh7305_peripheral_clk_ops,
- &sh7305_bus_clk_ops,
- &sh7305_cpu_clk_ops,
+static struct clk master_clk = {
+ .ops = &sh7305_master_clk_ops,
+ .flags = CLK_ENABLE_ON_INIT,
};

-void __init arch_init_clk_ops(struct sh_clk_ops **ops, int idx)
-{
- if (idx < ARRAY_SIZE(sh7305_clk_ops))
- *ops = sh7305_clk_ops[idx];
-}
+static struct clk peripheral_clk = {
+ .ops = &sh7305_peripheral_clk_ops,
+ .parent = &master_clk,
+ .flags = CLK_ENABLE_ON_INIT,
+};
+
+static struct clk bus_clk = {
+ .ops = &sh7305_bus_clk_ops,
+ .parent = &master_clk,
+ .flags = CLK_ENABLE_ON_INIT,
+};
+
+static struct clk cpu_clk = {
+ .ops = &sh7305_cpu_clk_ops,
+ .parent = &master_clk,
+ .flags = CLK_ENABLE_ON_INIT,
+};
+
+static struct clk *main_clks[] = {
+ &master_clk,
+ &peripheral_clk,
+ &bus_clk,
+ &cpu_clk,
+};
+
+#define MSTPCR0 0xa4150030
+
+static struct clk mstp_clks[] = {
+ SH_CLK_MSTP32(&peripheral_clk, MSTPCR0, 15, 0),
+};
+
+static struct clk_lookup lookups[] = {
+ CLKDEV_CON_ID("master_clk", &master_clk),
+ CLKDEV_CON_ID("peripheral_clk", &peripheral_clk),
+ CLKDEV_CON_ID("bus_clk", &bus_clk),
+ CLKDEV_CON_ID("cpu_clk", &cpu_clk),
+ CLKDEV_ICK_ID("fck", "sh-tmu.0", &mstp_clks[0]),
+};

int __init arch_clk_init(void)
{
- return cpg_clk_init();
+ int i, ret = 0;
+
+ for (i = 0; !ret && i < ARRAY_SIZE(main_clks); i++)
+ ret = clk_register(main_clks[i]);
+
+ if (ret)
+ return ret;
+
+ clkdev_add_table(lookups, ARRAY_SIZE(lookups));
+
+ return sh_clk_mstp_register(mstp_clks, ARRAY_SIZE(mstp_clks));
}
--
2.56.0