* [QUESTION] rtc: zynqmp: CALIB_RD reset behavior differs between ZynqMP and Versal
@ 2026-03-05 9:24 Takumi Ando
2026-03-06 10:09 ` Tomas Melin
0 siblings, 1 reply; 6+ messages in thread
From: Takumi Ando @ 2026-03-05 9:24 UTC (permalink / raw)
To: linux-rtc; +Cc: alexandre.belloni, michal.simek, Yasushi SHOJI, kanta tamura
Hi,
I have a question about the initialization logic in the zynqmp RTC
driver(drivers/rtc/rtc-zynqmp.c).
Currently the driver programs CALIB_WRITE only when CALIB_READ returns 0:
ret = readl(... + RTC_CALIB_RD);
if (!ret)
writel(freq, ... + RTC_CALIB_WR);
My understanding is that this was designed to avoid overwriting an
existing calibration value. Since the RTC may continue running from the
battery domain even when Linux is not running, the calibration value may
have been configured previously and should be preserved.
However, according to the Versal Adaptive SoC Register Reference (AM012) [1],
the value returned by CALIB_RD after reset can be undefined.
In practice, on Versal hardware we observe non-zero values even before
any calibration has been programmed. Because of this, the current logic
may skip programming CALIB_WR and leave the Max_Tick field uninitialized.
On Zynq UltraScale+ Devices Register Reference (UG1087) [2],
CALIB_RD resets to 0, so the current logic works correctly there.
However, this assumption does not appear to hold for Versal.
If there is a register or mechanism that indicates whether the RTC has
already been calibrated, the driver could use that instead. However,
I could not find such an indicator in the documentation.
Am I missing something here? Is there a recommended way to detect whether
RTC calibration has already been configured?
Alternatively, would it be acceptable for the driver to always program
Max_Tick while preserving the fractional calibration bits already stored
in hardware?
Best regards,
[1] https://docs.amd.com/r/en-US/am012-versal-register-reference/CALIB_READ-PMC_RTC-Register
[2] https://docs.amd.com/r/en-US/ug1087-zynq-ultrascale-registers/CALIB_READ-RTC-Register
--
Takumi Ando
Space Cubics Inc.
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [QUESTION] rtc: zynqmp: CALIB_RD reset behavior differs between ZynqMP and Versal
2026-03-05 9:24 [QUESTION] rtc: zynqmp: CALIB_RD reset behavior differs between ZynqMP and Versal Takumi Ando
@ 2026-03-06 10:09 ` Tomas Melin
2026-03-06 11:13 ` Alexandre Belloni
0 siblings, 1 reply; 6+ messages in thread
From: Tomas Melin @ 2026-03-06 10:09 UTC (permalink / raw)
To: Takumi Ando, linux-rtc
Cc: alexandre.belloni, michal.simek, Yasushi SHOJI, kanta tamura
Hi,
On 05/03/2026 11:24, Takumi Ando wrote:
> [You don't often get email from takumi@spacecubics.com. Learn why this is important at https://aka.ms/LearnAboutSenderIdentification ]
>
> Hi,
>
> I have a question about the initialization logic in the zynqmp RTC
> driver(drivers/rtc/rtc-zynqmp.c).
>
> Currently the driver programs CALIB_WRITE only when CALIB_READ returns 0:
>
> ret = readl(... + RTC_CALIB_RD);
> if (!ret)
> writel(freq, ... + RTC_CALIB_WR);
>
> My understanding is that this was designed to avoid overwriting an
> existing calibration value. Since the RTC may continue running from the
> battery domain even when Linux is not running, the calibration value may
> have been configured previously and should be preserved.
>
> However, according to the Versal Adaptive SoC Register Reference (AM012) [1],
> the value returned by CALIB_RD after reset can be undefined.
> In practice, on Versal hardware we observe non-zero values even before
> any calibration has been programmed. Because of this, the current logic
> may skip programming CALIB_WR and leave the Max_Tick field uninitialized.
>
> On Zynq UltraScale+ Devices Register Reference (UG1087) [2],
> CALIB_RD resets to 0, so the current logic works correctly there.
> However, this assumption does not appear to hold for Versal.
For Ultrascale+ the calibration register also gives random values after
reset, perhaps you have noticed this:
https://adaptivesupport.amd.com/s/article/000036886?language=en_US.
Maybe the same can occur also on Versal.
AFAIK there is no way of knowing if the value is correct or not after
reset, so user space helpers might be needed to maintain the calibration
value at a desired value.
thanks,
Tomas
>
> If there is a register or mechanism that indicates whether the RTC has
> already been calibrated, the driver could use that instead. However,
> I could not find such an indicator in the documentation.
>
> Am I missing something here? Is there a recommended way to detect whether
> RTC calibration has already been configured?
>
> Alternatively, would it be acceptable for the driver to always program
> Max_Tick while preserving the fractional calibration bits already stored
> in hardware?
>
> Best regards,
>
> [1] https://docs.amd.com/r/en-US/am012-versal-register-reference/CALIB_READ-PMC_RTC-Register
> [2] https://docs.amd.com/r/en-US/ug1087-zynq-ultrascale-registers/CALIB_READ-RTC-Register
>
> --
> Takumi Ando
> Space Cubics Inc.
>
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [QUESTION] rtc: zynqmp: CALIB_RD reset behavior differs between ZynqMP and Versal
2026-03-06 10:09 ` Tomas Melin
@ 2026-03-06 11:13 ` Alexandre Belloni
2026-03-11 3:19 ` Takumi Ando
0 siblings, 1 reply; 6+ messages in thread
From: Alexandre Belloni @ 2026-03-06 11:13 UTC (permalink / raw)
To: Tomas Melin
Cc: Takumi Ando, linux-rtc, michal.simek, Yasushi SHOJI, kanta tamura
On 06/03/2026 12:09:40+0200, Tomas Melin wrote:
> > On Zynq UltraScale+ Devices Register Reference (UG1087) [2],
> > CALIB_RD resets to 0, so the current logic works correctly there.
> > However, this assumption does not appear to hold for Versal.
>
> For Ultrascale+ the calibration register also gives random values after
> reset, perhaps you have noticed this:
> https://adaptivesupport.amd.com/s/article/000036886?language=en_US. Maybe
> the same can occur also on Versal.
>
> AFAIK there is no way of knowing if the value is correct or not after reset,
> so user space helpers might be needed to maintain the calibration value at a
> desired value.
>
Userspace is always needed to put the proper calibration, there is no
way for the kernel to know what value to put there. In the support case
above, the crystal will never be exactly 32768Hz and this value will
change over time and also depends on the temperature. The value always
needs to be computed, if your device can do NTP, chrony will provide the
proper offsets. If you don't have a way to measure the deviation, then
userspace can always forcefully set /sys/class/rtc/rtcX/offset if it
doesn't hold the correct value.
There is no need for devmem here.
--
Alexandre Belloni, co-owner and COO, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [QUESTION] rtc: zynqmp: CALIB_RD reset behavior differs between ZynqMP and Versal
2026-03-06 11:13 ` Alexandre Belloni
@ 2026-03-11 3:19 ` Takumi Ando
2026-03-11 5:22 ` Tomas Melin
0 siblings, 1 reply; 6+ messages in thread
From: Takumi Ando @ 2026-03-11 3:19 UTC (permalink / raw)
To: Tomas Melin, Alexandre Belloni, linux-rtc
Cc: michal.simek, Yasushi SHOJI, kanta tamura
Hi Tomas, Alexandre,
Thank you for the explanations.
So if I understand correctly, both on Zynq UltraScale+ and Versal,
CALIB_RD may return a non-zero (or otherwise undefined) value after
reset, meaning that it cannot reliably be used to determine whether
the calibration register has already been initialized.
While the fractional calibration should indeed be handled from
userspace (e.g. via the RTC offset interface), it seems that the
Max_Tick field should still always be programmed according to the
value provided in Device Tree, since it depends only on the RTC
oscillator frequency.
Would it make sense for the driver to always program Max_Tick from the
Device Tree "calibration" property while preserving the fractional
calibration bits currently stored in hardware?
If this approach sounds reasonable, I would like to prepare a patch
for upstream.
Best regards,
2026年3月6日(金) 20:13 Alexandre Belloni <alexandre.belloni@bootlin.com>:
>
> On 06/03/2026 12:09:40+0200, Tomas Melin wrote:
> > > On Zynq UltraScale+ Devices Register Reference (UG1087) [2],
> > > CALIB_RD resets to 0, so the current logic works correctly there.
> > > However, this assumption does not appear to hold for Versal.
> >
> > For Ultrascale+ the calibration register also gives random values after
> > reset, perhaps you have noticed this:
> > https://adaptivesupport.amd.com/s/article/000036886?language=en_US. Maybe
> > the same can occur also on Versal.
> >
> > AFAIK there is no way of knowing if the value is correct or not after reset,
> > so user space helpers might be needed to maintain the calibration value at a
> > desired value.
> >
>
> Userspace is always needed to put the proper calibration, there is no
> way for the kernel to know what value to put there. In the support case
> above, the crystal will never be exactly 32768Hz and this value will
> change over time and also depends on the temperature. The value always
> needs to be computed, if your device can do NTP, chrony will provide the
> proper offsets. If you don't have a way to measure the deviation, then
> userspace can always forcefully set /sys/class/rtc/rtcX/offset if it
> doesn't hold the correct value.
> There is no need for devmem here.
>
> --
> Alexandre Belloni, co-owner and COO, Bootlin
> Embedded Linux and Kernel engineering
> https://bootlin.com
--
Takumi Ando
Space Cubics Inc.
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [QUESTION] rtc: zynqmp: CALIB_RD reset behavior differs between ZynqMP and Versal
2026-03-11 3:19 ` Takumi Ando
@ 2026-03-11 5:22 ` Tomas Melin
2026-03-11 6:52 ` Takumi Ando
0 siblings, 1 reply; 6+ messages in thread
From: Tomas Melin @ 2026-03-11 5:22 UTC (permalink / raw)
To: Takumi Ando, Alexandre Belloni, linux-rtc
Cc: michal.simek, Yasushi SHOJI, kanta tamura
Hi,
On 11/03/2026 05:19, Takumi Ando wrote:
> [You don't often get email from takumi@spacecubics.com. Learn why this is important at https://aka.ms/LearnAboutSenderIdentification ]
>
> Hi Tomas, Alexandre,
>
> Thank you for the explanations.
>
> So if I understand correctly, both on Zynq UltraScale+ and Versal,
> CALIB_RD may return a non-zero (or otherwise undefined) value after
> reset, meaning that it cannot reliably be used to determine whether
> the calibration register has already been initialized.
>
> While the fractional calibration should indeed be handled from
> userspace (e.g. via the RTC offset interface), it seems that the
> Max_Tick field should still always be programmed according to the
> value provided in Device Tree, since it depends only on the RTC
> oscillator frequency.
Both max_tick and fract_data might change, it depends on how big
the calibrator drift/offset is and if it is negative/positive.
>
> Would it make sense for the driver to always program Max_Tick from the
> Device Tree "calibration" property while preserving the fractional
> calibration bits currently stored in hardware?
As Alexandre mentioned, user space needs to ensure calibration is what
it should be.
thanks,
Tomas
>
> If this approach sounds reasonable, I would like to prepare a patch
> for upstream.
>
> Best regards,
>
> 2026年3月6日(金) 20:13 Alexandre Belloni <alexandre.belloni@bootlin.com>:
>> On 06/03/2026 12:09:40+0200, Tomas Melin wrote:
>>>> On Zynq UltraScale+ Devices Register Reference (UG1087) [2],
>>>> CALIB_RD resets to 0, so the current logic works correctly there.
>>>> However, this assumption does not appear to hold for Versal.
>>> For Ultrascale+ the calibration register also gives random values after
>>> reset, perhaps you have noticed this:
>>> https://adaptivesupport.amd.com/s/article/000036886?language=en_US. Maybe
>>> the same can occur also on Versal.
>>>
>>> AFAIK there is no way of knowing if the value is correct or not after reset,
>>> so user space helpers might be needed to maintain the calibration value at a
>>> desired value.
>>>
>> Userspace is always needed to put the proper calibration, there is no
>> way for the kernel to know what value to put there. In the support case
>> above, the crystal will never be exactly 32768Hz and this value will
>> change over time and also depends on the temperature. The value always
>> needs to be computed, if your device can do NTP, chrony will provide the
>> proper offsets. If you don't have a way to measure the deviation, then
>> userspace can always forcefully set /sys/class/rtc/rtcX/offset if it
>> doesn't hold the correct value.
>> There is no need for devmem here.
>>
>> --
>> Alexandre Belloni, co-owner and COO, Bootlin
>> Embedded Linux and Kernel engineering
>> https://bootlin.com/
>
>
> --
> Takumi Ando
> Space Cubics Inc.
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [QUESTION] rtc: zynqmp: CALIB_RD reset behavior differs between ZynqMP and Versal
2026-03-11 5:22 ` Tomas Melin
@ 2026-03-11 6:52 ` Takumi Ando
0 siblings, 0 replies; 6+ messages in thread
From: Takumi Ando @ 2026-03-11 6:52 UTC (permalink / raw)
To: Tomas Melin
Cc: Alexandre Belloni, linux-rtc, michal.simek, Yasushi SHOJI,
kanta tamura
Hi Tomas,
Thanks for the clarification.
My understanding is that the fractional correction (fract_data) should
indeed be managed from userspace since it represents oscillator drift
and may change over time.
However, the Max_Tick field seems to have a different role: it defines
the number of RTC oscillator cycles corresponding to one second.
For example, with a 32.768 kHz oscillator the value should be 32768-1.
This is how I interpreted the documentation as well.
In the AM012, the description of Max_Tick says that the
register value multiplied by the oscillator period should equal one
second, and it explicitly states that for a 32.768 kHz oscillator the
value will be 0x7FFF.
Because of this, it appears that Max_Tick depends only on the oscillator
frequency and should not change dynamically like the fractional
correction.
Did I misunderstand the purpose of the Max_Tick field?
Best regards,
2026年3月11日(水) 14:23 Tomas Melin <tomas.melin@vaisala.com>:
>
> Hi,
>
> On 11/03/2026 05:19, Takumi Ando wrote:
> > [You don't often get email from takumi@spacecubics.com. Learn why this is important at https://aka.ms/LearnAboutSenderIdentification ]
> >
> > Hi Tomas, Alexandre,
> >
> > Thank you for the explanations.
> >
> > So if I understand correctly, both on Zynq UltraScale+ and Versal,
> > CALIB_RD may return a non-zero (or otherwise undefined) value after
> > reset, meaning that it cannot reliably be used to determine whether
> > the calibration register has already been initialized.
> >
> > While the fractional calibration should indeed be handled from
> > userspace (e.g. via the RTC offset interface), it seems that the
> > Max_Tick field should still always be programmed according to the
> > value provided in Device Tree, since it depends only on the RTC
> > oscillator frequency.
>
> Both max_tick and fract_data might change, it depends on how big
>
> the calibrator drift/offset is and if it is negative/positive.
>
> >
> > Would it make sense for the driver to always program Max_Tick from the
> > Device Tree "calibration" property while preserving the fractional
> > calibration bits currently stored in hardware?
>
> As Alexandre mentioned, user space needs to ensure calibration is what
> it should be.
>
>
> thanks,
>
> Tomas
>
>
> >
> > If this approach sounds reasonable, I would like to prepare a patch
> > for upstream.
> >
> > Best regards,
> >
> > 2026年3月6日(金) 20:13 Alexandre Belloni <alexandre.belloni@bootlin.com>:
> >> On 06/03/2026 12:09:40+0200, Tomas Melin wrote:
> >>>> On Zynq UltraScale+ Devices Register Reference (UG1087) [2],
> >>>> CALIB_RD resets to 0, so the current logic works correctly there.
> >>>> However, this assumption does not appear to hold for Versal.
> >>> For Ultrascale+ the calibration register also gives random values after
> >>> reset, perhaps you have noticed this:
> >>> https://adaptivesupport.amd.com/s/article/000036886?language=en_US. Maybe
> >>> the same can occur also on Versal.
> >>>
> >>> AFAIK there is no way of knowing if the value is correct or not after reset,
> >>> so user space helpers might be needed to maintain the calibration value at a
> >>> desired value.
> >>>
> >> Userspace is always needed to put the proper calibration, there is no
> >> way for the kernel to know what value to put there. In the support case
> >> above, the crystal will never be exactly 32768Hz and this value will
> >> change over time and also depends on the temperature. The value always
> >> needs to be computed, if your device can do NTP, chrony will provide the
> >> proper offsets. If you don't have a way to measure the deviation, then
> >> userspace can always forcefully set /sys/class/rtc/rtcX/offset if it
> >> doesn't hold the correct value.
> >> There is no need for devmem here.
> >>
> >> --
> >> Alexandre Belloni, co-owner and COO, Bootlin
> >> Embedded Linux and Kernel engineering
> >> https://bootlin.com/
> >
> >
> > --
> > Takumi Ando
> > Space Cubics Inc.
--
Takumi Ando
Space Cubics Inc.
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2026-03-11 6:52 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-03-05 9:24 [QUESTION] rtc: zynqmp: CALIB_RD reset behavior differs between ZynqMP and Versal Takumi Ando
2026-03-06 10:09 ` Tomas Melin
2026-03-06 11:13 ` Alexandre Belloni
2026-03-11 3:19 ` Takumi Ando
2026-03-11 5:22 ` Tomas Melin
2026-03-11 6:52 ` Takumi Ando
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox