linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] arm64: dts: allwinner: Mark timer as stopped in suspend
@ 2020-08-09  2:18 Samuel Holland
  2020-08-18  9:10 ` Maxime Ripard
  0 siblings, 1 reply; 3+ messages in thread
From: Samuel Holland @ 2020-08-09  2:18 UTC (permalink / raw)
  To: Maxime Ripard, Chen-Yu Tsai
  Cc: devicetree, linux-arm-kernel, linux-kernel, Samuel Holland

When possible, system firmware on 64-bit Allwinner platforms disables
OSC24M during system suspend. Since this oscillator is the clock source
for the ARM architectural timer, this causes the timer to stop counting.
Therefore, the ARM architectural timer must not be marked as NONSTOP on
these platforms, or the time will be wrong after system resume.

Adding the arm,no-tick-in-suspend property forces the kernel to ignore
the ARM architectural timer when calculating sleeptime; it falls back to
reading the RTC. Note that this only affects deep suspend, not s2idle.

Signed-off-by: Samuel Holland <samuel@sholland.org>
---
 arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi | 1 +
 arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi  | 1 +
 arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi  | 1 +
 3 files changed, 3 insertions(+)

diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
index 8dfbcd144072..5d19cf6f6d4f 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
@@ -157,6 +157,7 @@ link_codec: simple-audio-card,codec {
 	timer {
 		compatible = "arm,armv8-timer";
 		allwinner,erratum-unknown1;
+		arm,no-tick-in-suspend;
 		interrupts = <GIC_PPI 13
 			(GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>,
 			     <GIC_PPI 14
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi
index 4462a68c0681..a6c8b43b99a3 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi
@@ -53,6 +53,7 @@ psci {
 
 	timer {
 		compatible = "arm,armv8-timer";
+		arm,no-tick-in-suspend;
 		interrupts = <GIC_PPI 13
 				(GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
 			     <GIC_PPI 14
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
index 9ce78a7b117d..28c77d6872f6 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
@@ -90,6 +90,7 @@ psci {
 
 	timer {
 		compatible = "arm,armv8-timer";
+		arm,no-tick-in-suspend;
 		interrupts = <GIC_PPI 13
 			(GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>,
 			     <GIC_PPI 14
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH] arm64: dts: allwinner: Mark timer as stopped in suspend
  2020-08-09  2:18 [PATCH] arm64: dts: allwinner: Mark timer as stopped in suspend Samuel Holland
@ 2020-08-18  9:10 ` Maxime Ripard
  2020-08-26  3:52   ` Samuel Holland
  0 siblings, 1 reply; 3+ messages in thread
From: Maxime Ripard @ 2020-08-18  9:10 UTC (permalink / raw)
  To: Samuel Holland; +Cc: Chen-Yu Tsai, devicetree, linux-arm-kernel, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 817 bytes --]

Hi!

On Sat, Aug 08, 2020 at 09:18:22PM -0500, Samuel Holland wrote:
> When possible, system firmware on 64-bit Allwinner platforms disables
> OSC24M during system suspend. Since this oscillator is the clock source
> for the ARM architectural timer, this causes the timer to stop counting.
> Therefore, the ARM architectural timer must not be marked as NONSTOP on
> these platforms, or the time will be wrong after system resume.
> 
> Adding the arm,no-tick-in-suspend property forces the kernel to ignore
> the ARM architectural timer when calculating sleeptime; it falls back to
> reading the RTC. Note that this only affects deep suspend, not s2idle.
> 
> Signed-off-by: Samuel Holland <samuel@sholland.org>

Applied, thanks!

I assume it affects all the SoCs with a Cortex-A7 as well?

Maxime

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] arm64: dts: allwinner: Mark timer as stopped in suspend
  2020-08-18  9:10 ` Maxime Ripard
@ 2020-08-26  3:52   ` Samuel Holland
  0 siblings, 0 replies; 3+ messages in thread
From: Samuel Holland @ 2020-08-26  3:52 UTC (permalink / raw)
  To: Maxime Ripard; +Cc: Chen-Yu Tsai, devicetree, linux-arm-kernel, linux-kernel

On 8/18/20 4:10 AM, Maxime Ripard wrote:
> Hi!
> 
> On Sat, Aug 08, 2020 at 09:18:22PM -0500, Samuel Holland wrote:
>> When possible, system firmware on 64-bit Allwinner platforms disables
>> OSC24M during system suspend. Since this oscillator is the clock source
>> for the ARM architectural timer, this causes the timer to stop counting.
>> Therefore, the ARM architectural timer must not be marked as NONSTOP on
>> these platforms, or the time will be wrong after system resume.
>>
>> Adding the arm,no-tick-in-suspend property forces the kernel to ignore
>> the ARM architectural timer when calculating sleeptime; it falls back to
>> reading the RTC. Note that this only affects deep suspend, not s2idle.
>>
>> Signed-off-by: Samuel Holland <samuel@sholland.org>
> 
> Applied, thanks!
> 
> I assume it affects all the SoCs with a Cortex-A7 as well?

Yes, they all have the same ability to turn off OSC24M. Though they don't yet
have support for deep sleep.

Supposedly they can also reparent OSC24M from the crystal to IOSC, but I have
not got that to work, and IOSC belongs nowhere near timekeeping anyway (20%+
frequency error).

Ideally, we would run some MMIO counter off of LOSC during suspend. This would
be several orders of magnitude more accurate than the RTC for accounting
sleeptime. However, none of the basic timer blocks appear to work when OSC24M is
disabled and AHB1 is running off of LOSC; they count for about 10 cycles and
then stop.

The HSTIMER is the only timer block that I got working. It runs at the same
frequency as AHB1, so it would only be useful for timekeeping if we reparented
AHB1 to LOSC during Linux's suspend process before switching clock sources. I
doubt that is workable.

So the RTC is the best solution I know of for now.

> Maxime

Samuel


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2020-08-26  3:52 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-08-09  2:18 [PATCH] arm64: dts: allwinner: Mark timer as stopped in suspend Samuel Holland
2020-08-18  9:10 ` Maxime Ripard
2020-08-26  3:52   ` Samuel Holland

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).