2021-03-15 04:34:32

by Samuel Holland

[permalink] [raw]
Subject: [PATCH 0/5] arm64: sunxi: Enable the sun4i timer

In preparation for adding CPU idle states, hook up the sun4i timer.
Having a non-c3stop clockevent source available is necessary for all
CPUs to simultaneously enter a local-timer-stop idle state.

Samuel Holland (5):
dt-bindings: timer: Simplify conditional expressions
dt-bindings: timer: Add compatibles for sun50i timers
arm64: dts: allwinner: a64: Sort watchdog node
arm64: dts: allwinner: Add sun4i MMIO timer nodes
arm64: sunxi: Build the sun4i timer driver

.../timer/allwinner,sun4i-a10-timer.yaml | 42 +++++++++----------
arch/arm64/Kconfig.platforms | 1 +
arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi | 25 +++++++----
arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi | 9 ++++
.../arm64/boot/dts/allwinner/sun50i-h616.dtsi | 9 ++++
5 files changed, 55 insertions(+), 31 deletions(-)

--
2.26.2


2021-03-15 04:34:34

by Samuel Holland

[permalink] [raw]
Subject: [PATCH 4/5] arm64: dts: allwinner: Add sun4i MMIO timer nodes

For a CPU to enter an idle state, there must be some timer which can
trigger an IRQ to wake it back up. The local ARM architectural timer is
not sufficient, because that timer stops when the CPU is powered down.
Some other CPU's ARM architectural timer can be used, but this prevents
that other CPU from entering an idle state. So to allow all CPUs to
enter an idle state at the same time, some MMIO timer must be available
that is not tied to any CPU.

The basic "sun4i" timer seems most appropriate for this purpose due to
its moderate rate, balancing precision and power consumption.

Signed-off-by: Samuel Holland <[email protected]>
---
arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi | 9 +++++++++
arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi | 9 +++++++++
arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi | 9 +++++++++
3 files changed, 27 insertions(+)

diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
index 33df866f6ea9..64e8b4a372cc 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
@@ -905,6 +905,15 @@ uart4_rts_cts_pins: uart4-rts-cts-pins {
};
};

+ timer@1c20c00 {
+ compatible = "allwinner,sun50i-a64-timer",
+ "allwinner,sun8i-a23-timer";
+ reg = <0x01c20c00 0xa0>;
+ interrupts = <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&osc24M>;
+ };
+
wdt0: watchdog@1c20ca0 {
compatible = "allwinner,sun50i-a64-wdt",
"allwinner,sun6i-a31-wdt";
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
index 62334054c710..9ba3b30e11fa 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
@@ -332,6 +332,15 @@ cpu_speed_grade: cpu-speed-grade@1c {
};
};

+ timer@3009000 {
+ compatible = "allwinner,sun50i-h6-timer",
+ "allwinner,sun8i-a23-timer";
+ reg = <0x03009000 0xa0>;
+ interrupts = <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&osc24M>;
+ };
+
watchdog: watchdog@30090a0 {
compatible = "allwinner,sun50i-h6-wdt",
"allwinner,sun6i-a31-wdt";
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi
index c277b53f94ea..ff55712ce96e 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi
@@ -128,6 +128,15 @@ ccu: clock@3001000 {
#reset-cells = <1>;
};

+ timer@3009000 {
+ compatible = "allwinner,sun50i-h616-timer",
+ "allwinner,sun8i-a23-timer";
+ reg = <0x03009000 0xa0>;
+ interrupts = <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&osc24M>;
+ };
+
watchdog: watchdog@30090a0 {
compatible = "allwinner,sun50i-h616-wdt",
"allwinner,sun6i-a31-wdt";
--
2.26.2

2021-03-15 04:36:37

by Samuel Holland

[permalink] [raw]
Subject: [PATCH 5/5] arm64: sunxi: Build the sun4i timer driver

While the ARM architectural timer is generatlly the best timer to use,
a non-c3stop timer is needed for cpuidle. Use the sun4i timer for this
purpose, which is present on all 64-bit sunxi SoCs.

Signed-off-by: Samuel Holland <[email protected]>
---
arch/arm64/Kconfig.platforms | 1 +
1 file changed, 1 insertion(+)

diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms
index cdfd5fed457f..7f6a66431fa7 100644
--- a/arch/arm64/Kconfig.platforms
+++ b/arch/arm64/Kconfig.platforms
@@ -26,6 +26,7 @@ config ARCH_SUNXI
select IRQ_FASTEOI_HIERARCHY_HANDLERS
select PINCTRL
select RESET_CONTROLLER
+ select SUN4I_TIMER
help
This enables support for Allwinner sunxi based SoCs like the A64.

--
2.26.2

2021-03-15 23:43:09

by Jernej Skrabec

[permalink] [raw]
Subject: Re: [PATCH 4/5] arm64: dts: allwinner: Add sun4i MMIO timer nodes

Hi!

Dne ponedeljek, 15. marec 2021 ob 05:32:49 CET je Samuel Holland napisal(a):
> For a CPU to enter an idle state, there must be some timer which can
> trigger an IRQ to wake it back up. The local ARM architectural timer is
> not sufficient, because that timer stops when the CPU is powered down.
> Some other CPU's ARM architectural timer can be used, but this prevents
> that other CPU from entering an idle state. So to allow all CPUs to
> enter an idle state at the same time, some MMIO timer must be available
> that is not tied to any CPU.
>
> The basic "sun4i" timer seems most appropriate for this purpose due to
> its moderate rate, balancing precision and power consumption.
>
> Signed-off-by: Samuel Holland <[email protected]>
> ---
> arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi | 9 +++++++++
> arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi | 9 +++++++++
> arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi | 9 +++++++++
> 3 files changed, 27 insertions(+)
>
> diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
> b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi index
> 33df866f6ea9..64e8b4a372cc 100644
> --- a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
> +++ b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
> @@ -905,6 +905,15 @@ uart4_rts_cts_pins: uart4-rts-cts-pins {
> };
> };
>
> + timer@1c20c00 {
> + compatible = "allwinner,sun50i-a64-timer",
> + "allwinner,sun8i-a23-timer";
> + reg = <0x01c20c00 0xa0>;
> + interrupts = <GIC_SPI 18
IRQ_TYPE_LEVEL_HIGH>,
> + <GIC_SPI 19
IRQ_TYPE_LEVEL_HIGH>;
> + clocks = <&osc24M>;
> + };
> +
> wdt0: watchdog@1c20ca0 {
> compatible = "allwinner,sun50i-a64-wdt",
> "allwinner,sun6i-a31-wdt";
> diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
> b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi index
> 62334054c710..9ba3b30e11fa 100644
> --- a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
> +++ b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
> @@ -332,6 +332,15 @@ cpu_speed_grade: cpu-speed-grade@1c {
> };
> };
>
> + timer@3009000 {
> + compatible = "allwinner,sun50i-h6-timer",
> + "allwinner,sun8i-a23-timer";
> + reg = <0x03009000 0xa0>;
> + interrupts = <GIC_SPI 48
IRQ_TYPE_LEVEL_HIGH>,
> + <GIC_SPI 49
IRQ_TYPE_LEVEL_HIGH>;
> + clocks = <&osc24M>;
> + };
> +
> watchdog: watchdog@30090a0 {
> compatible = "allwinner,sun50i-h6-wdt",
> "allwinner,sun6i-a31-wdt";
> diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi
> b/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi index
> c277b53f94ea..ff55712ce96e 100644
> --- a/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi
> +++ b/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi

This file does not exist yet upstream.

Best regards,
Jernej

> @@ -128,6 +128,15 @@ ccu: clock@3001000 {
> #reset-cells = <1>;
> };
>
> + timer@3009000 {
> + compatible = "allwinner,sun50i-h616-timer",
> + "allwinner,sun8i-a23-timer";
> + reg = <0x03009000 0xa0>;
> + interrupts = <GIC_SPI 48
IRQ_TYPE_LEVEL_HIGH>,
> + <GIC_SPI 49
IRQ_TYPE_LEVEL_HIGH>;
> + clocks = <&osc24M>;
> + };
> +
> watchdog: watchdog@30090a0 {
> compatible = "allwinner,sun50i-h616-wdt",
> "allwinner,sun6i-a31-wdt";




2021-03-16 08:04:43

by Samuel Holland

[permalink] [raw]
Subject: Re: [PATCH 4/5] arm64: dts: allwinner: Add sun4i MMIO timer nodes

On 3/15/21 1:32 PM, Jernej Škrabec wrote:
> Hi!
>
> Dne ponedeljek, 15. marec 2021 ob 05:32:49 CET je Samuel Holland napisal(a):
>> For a CPU to enter an idle state, there must be some timer which can
>> trigger an IRQ to wake it back up. The local ARM architectural timer is
>> not sufficient, because that timer stops when the CPU is powered down.
>> Some other CPU's ARM architectural timer can be used, but this prevents
>> that other CPU from entering an idle state. So to allow all CPUs to
>> enter an idle state at the same time, some MMIO timer must be available
>> that is not tied to any CPU.
>>
>> The basic "sun4i" timer seems most appropriate for this purpose due to
>> its moderate rate, balancing precision and power consumption.
>>
>> Signed-off-by: Samuel Holland <[email protected]>
>> ---
>> arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi | 9 +++++++++
>> arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi | 9 +++++++++
>> arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi | 9 +++++++++
>> 3 files changed, 27 insertions(+)
>>
>> diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
>> b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi index
>> 33df866f6ea9..64e8b4a372cc 100644
>> --- a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
>> +++ b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
>> @@ -905,6 +905,15 @@ uart4_rts_cts_pins: uart4-rts-cts-pins {
>> };
>> };
>>
>> + timer@1c20c00 {
>> + compatible = "allwinner,sun50i-a64-timer",
>> + "allwinner,sun8i-a23-timer";
>> + reg = <0x01c20c00 0xa0>;
>> + interrupts = <GIC_SPI 18
> IRQ_TYPE_LEVEL_HIGH>,
>> + <GIC_SPI 19
> IRQ_TYPE_LEVEL_HIGH>;
>> + clocks = <&osc24M>;
>> + };
>> +
>> wdt0: watchdog@1c20ca0 {
>> compatible = "allwinner,sun50i-a64-wdt",
>> "allwinner,sun6i-a31-wdt";
>> diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
>> b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi index
>> 62334054c710..9ba3b30e11fa 100644
>> --- a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
>> +++ b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
>> @@ -332,6 +332,15 @@ cpu_speed_grade: cpu-speed-grade@1c {
>> };
>> };
>>
>> + timer@3009000 {
>> + compatible = "allwinner,sun50i-h6-timer",
>> + "allwinner,sun8i-a23-timer";
>> + reg = <0x03009000 0xa0>;
>> + interrupts = <GIC_SPI 48
> IRQ_TYPE_LEVEL_HIGH>,
>> + <GIC_SPI 49
> IRQ_TYPE_LEVEL_HIGH>;
>> + clocks = <&osc24M>;
>> + };
>> +
>> watchdog: watchdog@30090a0 {
>> compatible = "allwinner,sun50i-h6-wdt",
>> "allwinner,sun6i-a31-wdt";
>> diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi
>> b/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi index
>> c277b53f94ea..ff55712ce96e 100644
>> --- a/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi
>> +++ b/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi
>
> This file does not exist yet upstream.

Right. I will remove this section for v2.

Cheers,
Samuel

> Best regards,
> Jernej
>
>> @@ -128,6 +128,15 @@ ccu: clock@3001000 {
>> #reset-cells = <1>;
>> };
>>
>> + timer@3009000 {
>> + compatible = "allwinner,sun50i-h616-timer",
>> + "allwinner,sun8i-a23-timer";
>> + reg = <0x03009000 0xa0>;
>> + interrupts = <GIC_SPI 48
> IRQ_TYPE_LEVEL_HIGH>,
>> + <GIC_SPI 49
> IRQ_TYPE_LEVEL_HIGH>;
>> + clocks = <&osc24M>;
>> + };
>> +
>> watchdog: watchdog@30090a0 {
>> compatible = "allwinner,sun50i-h616-wdt",
>> "allwinner,sun6i-a31-wdt";
>
>
>
>