[PATCH 08/12] rtc: rzn1: Dynamically calculate synchronization delay based on clock rate
From: Prabhakar
Date: Mon Jun 15 2026 - 11:54:18 EST
From: Lad Prabhakar <prabhakar.mahadev-lad.rj@xxxxxxxxxxxxxx>
Replace the hardcoded hardware synchronization delays with a calculated
time window derived from the operating sub-clock frequency.
The driver currently hardcodes microsecond ranges assuming a fixed
sub-clock frequency of 32.768 kHz. Newer SoC variants, such as the
RZ/T2H, drive this hardware block using a much faster clock rate
(~195.3 kHz). Hardcoding these wait windows forces faster blocks to
over-sleep, introducing unnecessary delays during clock initialization
and register configuration.
Calculate the duration of the required clock cycles in microseconds based
on the runtime clock rate, and store this value in the driver private
structure to adjust the usleep_range() and readl_poll_timeout() boundaries
dynamically.
Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@xxxxxxxxxxxxxx>
---
drivers/rtc/rtc-rzn1.c | 19 ++++++++++++++-----
1 file changed, 14 insertions(+), 5 deletions(-)
diff --git a/drivers/rtc/rtc-rzn1.c b/drivers/rtc/rtc-rzn1.c
index 06339adae71f..bc6af59744e4 100644
--- a/drivers/rtc/rtc-rzn1.c
+++ b/drivers/rtc/rtc-rzn1.c
@@ -71,6 +71,7 @@ struct rzn1_rtc {
*/
spinlock_t ctl1_access_lock;
struct rtc_time tm_alarm;
+ unsigned long sync_time;
int alarm_irq;
int sec_irq;
bool alarm_enabled;
@@ -124,8 +125,8 @@ static int rzn1_rtc_set_time(struct device *dev, struct rtc_time *tm)
/* Hold the counter if it was counting up */
writel(RZN1_RTC_CTL2_WAIT, rtc->base + RZN1_RTC_CTL2);
- /* Wait for the counter to stop: two 32k clock cycles */
- usleep_range(61, 100);
+ /* Wait for the counter to stop: two RTC_PCLK clock cycles */
+ usleep_range(rtc->sync_time, rtc->sync_time + 100);
ret = readl_poll_timeout(rtc->base + RZN1_RTC_CTL2, val,
val & RZN1_RTC_CTL2_WST, 0, 100);
if (ret)
@@ -433,17 +434,25 @@ static int rzn1_rtc_probe(struct platform_device *pdev)
ret = -EOPNOTSUPP;
goto dis_runtime_pm;
}
-
if (rate != 32768)
scmp_val = RZN1_RTC_CTL0_SLSB_SCMP;
+
+ /*
+ * The internal clock counter operates in synchronization with the
+ * RTC_PCLK clock. Calculate the duration of two RTC_PCLK clock
+ * cycles in microseconds required for operations to complete.
+ */
+ rtc->sync_time = DIV_ROUND_UP(2 * NSEC_PER_MSEC, rate);
+
}
/* Disable controller during SUBU/SCMP setup */
val = readl(rtc->base + RZN1_RTC_CTL0) & ~RZN1_RTC_CTL0_CE;
writel(val, rtc->base + RZN1_RTC_CTL0);
- /* Wait 2-4 32k clock cycles for the disabled controller */
+ /* Wait 2-4 RTC_PCLK clock cycles for the disabled controller to stop */
ret = readl_poll_timeout(rtc->base + RZN1_RTC_CTL0, val,
- !(val & RZN1_RTC_CTL0_CEST), 62, 123);
+ !(val & RZN1_RTC_CTL0_CEST), rtc->sync_time,
+ rtc->sync_time * 2);
if (ret)
goto dis_runtime_pm;
--
2.54.0