From 5857bc66e492bc745b68e36b5723e9fd7dbc5c5c Mon Sep 17 00:00:00 2001
From: recursivetree <recursivetreemail@gmail.com>
Date: Wed, 22 Apr 2026 21:39:05 +0200
Subject: [PATCH 1/3] arm/fdt: introduce a generic setstatclockrate function

These changes lay the groundwork for cleaning up setstatclockrate implementations across arm timers
---
 sys/arch/aarch64/conf/files.aarch64 |  1 +
 sys/arch/arm/conf/files.arm         |  1 +
 sys/arch/arm/fdt/arm_fdt.c          | 24 ++++++++++++++++++++++++
 sys/arch/arm/fdt/arm_fdtvar.h       |  1 +
 4 files changed, 27 insertions(+)

diff --git a/sys/arch/aarch64/conf/files.aarch64 b/sys/arch/aarch64/conf/files.aarch64
index e5cdc4ed3ea0..f796a65db4d4 100644
--- a/sys/arch/aarch64/conf/files.aarch64
+++ b/sys/arch/aarch64/conf/files.aarch64
@@ -21,6 +21,7 @@ defparam opt_arm_debug.h	EARLYCONS
 
 # Timer options
 defflag opt_arm_timer.h		__HAVE_GENERIC_CPU_INITCLOCKS
+defflag opt_arm_timer.h		__HAVE_GENERIC_SETSTATCLOCKRATE
 
 # Board-specific bus_space(9)/bus_dma(9) definitions
 defflag  opt_arm_bus_space.h	__BUS_SPACE_HAS_STREAM_METHODS
diff --git a/sys/arch/arm/conf/files.arm b/sys/arch/arm/conf/files.arm
index 53f5965f8811..a5109d822766 100644
--- a/sys/arch/arm/conf/files.arm
+++ b/sys/arch/arm/conf/files.arm
@@ -82,6 +82,7 @@ defflag  opt_arm_bus_space.h	__BUS_SPACE_HAS_STREAM_METHODS
 
 # Timer options
 defflag opt_arm_timer.h		__HAVE_GENERIC_CPU_INITCLOCKS
+defflag opt_arm_timer.h		__HAVE_GENERIC_SETSTATCLOCKRATE
 
 # Start code option
 defflag opt_arm_start.h		__HAVE_GENERIC_START
diff --git a/sys/arch/arm/fdt/arm_fdt.c b/sys/arch/arm/fdt/arm_fdt.c
index 947fc369a9f0..13ed206b2813 100644
--- a/sys/arch/arm/fdt/arm_fdt.c
+++ b/sys/arch/arm/fdt/arm_fdt.c
@@ -91,6 +91,7 @@ static TAILQ_HEAD(, arm_fdt_cpu_hatch_cb) arm_fdt_cpu_hatch_cbs =
 static void (*_arm_fdt_irq_handler)(void *) = arm_fdt_irq_default_handler;
 static void (*_arm_fdt_fiq_handler)(void *) = arm_fdt_fiq_default_handler;
 static void (*_arm_fdt_timer_init)(void) = NULL;
+static void (*_arm_fdt_timer_setstatclockrate)(int) = NULL;
 
 int
 arm_fdt_match(device_t parent, cfdata_t cf, void *aux)
@@ -200,6 +201,29 @@ cpu_initclocks(void)
 }
 #endif
 
+void
+arm_fdt_timer_register_setstatclockrate(void (*ratefn)(int))
+{
+	if (_arm_fdt_timer_setstatclockrate != NULL) {
+#ifdef DIAGNOSTIC
+		aprint_verbose("%s: setstatclockrate already registered\n",
+		    __func__);
+#endif
+		return;
+	}
+	_arm_fdt_timer_setstatclockrate = ratefn;
+}
+
+#ifdef __HAVE_GENERIC_SETSTATCLOCKRATE
+void
+setstatclockrate(int newhz)
+{
+	if (_arm_fdt_timer_setstatclockrate != NULL) {
+		_arm_fdt_timer_setstatclockrate(newhz);
+	}
+}
+#endif
+
 void
 arm_fdt_module_init(void)
 {
diff --git a/sys/arch/arm/fdt/arm_fdtvar.h b/sys/arch/arm/fdt/arm_fdtvar.h
index f17c1e61f141..b43c89eb77e1 100644
--- a/sys/arch/arm/fdt/arm_fdtvar.h
+++ b/sys/arch/arm/fdt/arm_fdtvar.h
@@ -54,6 +54,7 @@ void    arm_fdt_cpu_hatch_register(void *, void (*)(void *, struct cpu_info *));
 void    arm_fdt_cpu_hatch(struct cpu_info *);
 
 void	arm_fdt_timer_register(void (*)(void));
+void	arm_fdt_timer_register_setstatclockrate(void (*)(int));
 
 void	arm_fdt_irq_set_handler(void (*)(void *));
 void	arm_fdt_irq_handler(void *);
-- 
2.50.1 (Apple Git-155)


From a1c8d7570d67df5f51964496ad706897566a902e Mon Sep 17 00:00:00 2001
From: recursivetree <recursivetreemail@gmail.com>
Date: Wed, 22 Apr 2026 21:39:26 +0200
Subject: [PATCH 2/3] arm/generic_v5: use generic setstatclockrate

---
 sys/arch/arm/imx/imx23_timrot.c     | 18 +++++++-----------
 sys/arch/evbarm/conf/std.generic_v5 |  1 +
 2 files changed, 8 insertions(+), 11 deletions(-)

diff --git a/sys/arch/arm/imx/imx23_timrot.c b/sys/arch/arm/imx/imx23_timrot.c
index 0e13e00cc517..5e41e655926c 100644
--- a/sys/arch/arm/imx/imx23_timrot.c
+++ b/sys/arch/arm/imx/imx23_timrot.c
@@ -62,10 +62,7 @@ static void	imx23_timrot_attach(device_t, device_t, void *);
 static void	imx23_timrot_reset(struct imx23_timrot_softc *);
 int 		imx23_timrot_systimer_irq(void *frame);
 int 		imx23_timrot_stattimer_irq(void *);
-
-
-void	cpu_initclocks(void);
-void 	setstatclockrate(int);
+static void	imx23_timrot_setstatclockrate(int);
 
 CFATTACH_DECL_NEW(imx23timrot, sizeof(struct imx23_timrot_softc),
 		  imx23_timrot_match, imx23_timrot_attach, NULL, NULL);
@@ -162,6 +159,7 @@ imx23_timrot_attach(device_t parent, device_t self, void *aux)
 	aprint_normal(": stattimer on %s\n", intrstr);
 
 	arm_fdt_timer_register(imx23_timrot_cpu_initclocks);
+	arm_fdt_timer_register_setstatclockrate(imx23_timrot_setstatclockrate);
 }
 
 /*
@@ -190,16 +188,14 @@ imx23_timrot_cpu_initclocks(void)
 /*
  * Change statclock rate when profiling takes place.
  */
-void
-setstatclockrate(int newhz)
+static void
+imx23_timrot_setstatclockrate(int newhz)
 {
 	struct imx23_timrot_softc *sc = timer_sc;
 
-	if(sc != NULL) {
-		TIMER_WRITE_2(sc, HW_TIMROT_TIMCOUNT1,
-			      __SHIFTIN(SOURCE_32KHZ_HZ / newhz - 1,
-					HW_TIMROT_TIMCOUNT1_FIXED_COUNT));
-	}
+	TIMER_WRITE_2(sc, HW_TIMROT_TIMCOUNT1,
+		      __SHIFTIN(SOURCE_32KHZ_HZ / newhz - 1,
+				HW_TIMROT_TIMCOUNT1_FIXED_COUNT));
 }
 
 /*
diff --git a/sys/arch/evbarm/conf/std.generic_v5 b/sys/arch/evbarm/conf/std.generic_v5
index cd54c9cd2e9b..35efdd2a7ae5 100644
--- a/sys/arch/evbarm/conf/std.generic_v5
+++ b/sys/arch/evbarm/conf/std.generic_v5
@@ -26,6 +26,7 @@ options 	__HAVE_CPU_UAREA_ALLOC_IDLELWP
 options 	__HAVE_FAST_SOFTINTS		# should be in types.h
 options 	__HAVE_GENERIC_START
 options 	__HAVE_GENERIC_CPU_INITCLOCKS
+options 	__HAVE_GENERIC_SETSTATCLOCKRATE
 options 	__HAVE_PCI_CONF_HOOK
 options 	__HAVE_PCI_MSI_MSIX
 
-- 
2.50.1 (Apple Git-155)


From a7927e9ef7566f1eeab8af3dc0b071c1fa4f27ca Mon Sep 17 00:00:00 2001
From: recursivetree <recursivetreemail@gmail.com>
Date: Wed, 22 Apr 2026 22:59:57 +0200
Subject: [PATCH 3/3] arm/generic: use generic setstatclockrate

This allows us to get rid of the weak symbol hack in a9tmr since GENERIC is the only configuration with both a9tmr and gtmr active in one configuration. Configurations without __HAVE_GENERIC_SETSTATCLOCKRATE still get a setstatclockrate from the ifdef.
---
 sys/arch/arm/cortex/a9tmr.c      | 8 +++-----
 sys/arch/arm/cortex/gtmr.c       | 3 +++
 sys/arch/evbarm/conf/std.generic | 1 +
 3 files changed, 7 insertions(+), 5 deletions(-)

diff --git a/sys/arch/arm/cortex/a9tmr.c b/sys/arch/arm/cortex/a9tmr.c
index 1dbabbbd949e..fe023a9acdab 100644
--- a/sys/arch/arm/cortex/a9tmr.c
+++ b/sys/arch/arm/cortex/a9tmr.c
@@ -362,14 +362,12 @@ a9tmr_intr(void *arg)
 	return 1;
 }
 
-/* XXX This conflicts with gtmr, hence the temporary weak alias kludge */
-#if 1
-void a9tmr_setstatclockrate(int);
+#ifndef __HAVE_GENERIC_SETSTATCLOCKRATE
 void
-a9tmr_setstatclockrate(int newhz)
+setstatclockrate(int newhz)
 {
+	/* use hardclock */
 }
-__weak_alias(setstatclockrate, a9tmr_setstatclockrate);
 #endif
 
 static u_int
diff --git a/sys/arch/arm/cortex/gtmr.c b/sys/arch/arm/cortex/gtmr.c
index 057125c52331..b87ee9be633f 100644
--- a/sys/arch/arm/cortex/gtmr.c
+++ b/sys/arch/arm/cortex/gtmr.c
@@ -411,10 +411,13 @@ gtmr_intr(void *arg)
 	return 1;
 }
 
+#ifndef __HAVE_GENERIC_SETSTATCLOCKRATE
 void
 setstatclockrate(int newhz)
 {
+	/* use hardclock */
 }
+#endif
 
 static u_int
 gtmr_get_timecount(struct timecounter *tc)
diff --git a/sys/arch/evbarm/conf/std.generic b/sys/arch/evbarm/conf/std.generic
index 821d4d308573..1f9a028febbf 100644
--- a/sys/arch/evbarm/conf/std.generic
+++ b/sys/arch/evbarm/conf/std.generic
@@ -27,6 +27,7 @@ options 	__BUS_SPACE_HAS_STREAM_METHODS
 options 	__HAVE_CPU_COUNTER
 options 	__HAVE_CPU_UAREA_ALLOC_IDLELWP
 options 	__HAVE_FAST_SOFTINTS		# should be in types.h
+options 	__HAVE_GENERIC_SETSTATCLOCKRATE
 options 	__HAVE_GENERIC_START
 options 	__HAVE_GENERIC_CPU_INITCLOCKS
 options 	__HAVE_PCI_CONF_HOOK
-- 
2.50.1 (Apple Git-155)

