Skip to contentSkip to conversation

clocksource: Add NVIDIA Tegra186 timers support

PATCH In review Thierry Reding 3 participants 14 messages Apr 3, 2020 – Apr 14, 2020

Subsystems (3)
lore
Share & tools
lore
#0 lore raw

v3 cover clocksource: Add NVIDIA Tegra186 timers support

From: Thierry Reding <[email protected]>

This set of patches adds the device tree bindings and a simplified driver for the timers found on Tegra186 and later SoCs. The driver itself currently only exposes a couple of clock sources and a watchdog, which in turn relies on the counter provided by one of the timers. The timers themselves are not used at the moment because the SoC also has an architected timer and there's currently no use for the additional timers provided by this hardware block.

I suggest that patches 1 & 2 go through the clocksource tree, while I can carry the DTS changes in the Tegra tree for v5.8.

Changes in v3:
- request IRQ at the end of ->probe() to avoid potential race condition
- only enable/disable watchdog when it's active
- use _relaxed variants of register accessors
- drop unneeded tegra186_timer.irq field

Changes in v2:
- address review comments on the bindings
- make the driver buildable as a module
- support various clock sources

Thierry

Thierry Reding (7):
dt-bindings: timer: Add bindings for NVIDIA Tegra186 timers
clocksource: Add Tegra186 timers support
arm64: tegra: Order nodes by unit-address on Tegra194
arm64: tegra: Add native timer support on Tegra186
arm64: tegra: Enable native timers on Jetson TX2
arm64: tegra: Add native timer support on Tegra194
arm64: tegra: Enable native timers on Jetson AGX Xavier

 .../bindings/timer/nvidia,tegra186-timer.yaml |  61 +++
 .../arm64/boot/dts/nvidia/tegra186-p3310.dtsi |   4 +
 arch/arm64/boot/dts/nvidia/tegra186.dtsi      |  16 +
 .../arm64/boot/dts/nvidia/tegra194-p2888.dtsi |   4 +
 arch/arm64/boot/dts/nvidia/tegra194.dtsi      |  81 +--
 drivers/clocksource/Kconfig                   |   8 +
 drivers/clocksource/Makefile                  |   1 +
 drivers/clocksource/timer-tegra186.c          | 508 ++++++++++++++++++
 8 files changed, 651 insertions(+), 32 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/timer/nvidia,tegra186-timer.yaml
 create mode 100644 drivers/clocksource/timer-tegra186.c
Signature · 1 line
2.24.1
#1 lore raw

PATCH v3 1/7 dt-bindings: timer: Add bindings for NVIDIA Tegra186 timers

From: Thierry Reding <[email protected]>

The NVIDIA Tegra186 SoC contains an IP block that provides a register interface for ten timers with a 29-bit counter that can generate one- shot, periodic or watchdog interrupts.

---
Changes in v2:
- add required properties section
- add additionalProperties: false
- do not show status in example

 .../bindings/timer/nvidia,tegra186-timer.yaml | 61 +++++++++++++++++++
 1 file changed, 61 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/timer/nvidia,tegra186-timer.yaml
Documentation/devicetree/bindings/timer/nvidia,tegra186-timer.yaml new file +61 -0
new file mode 100644
index 000000000000..d722cd267bf9
@@ -0,0 +1,61 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/timer/nvidia,tegra186-timer.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: NVIDIA Tegra186 timers
+
+maintainers:
+  - Thierry Reding <[email protected]>
+  - Jonathan Hunter <[email protected]>
+
+description: |
+  The Tegra186 timer provides ten 29-bit timer counters and one 32-bit TSC
+  (timestamp counter). The timers run at either a fixed 1 MHz clock rate
+  derived from the oscillator clock. Each timer can be programmed to raise
+  one-shot, periodic, or watchdog interrupts.
+
+properties:
+  compatible:
+    oneOf:
+      - description: NVIDIA Tegra186
+        items:
+          - const: nvidia,tegra186-timer
+
+      - description: NVIDIA Tegra194
+        items:
+          - const: nvidia,tegra194-timer
+          - const: nvidia,tegra186-timer
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 10
+
+required:
+  - compatible
+  - reg
+  - interrupts
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+
+    timer@3010000 {
+        compatible = "nvidia,tegra186-timer";
+        reg = <0x03010000 0x000e0000>;
+        interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>,
+                     <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>,
+                     <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>,
+                     <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>,
+                     <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>,
+                     <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>,
+                     <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>,
+                     <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>,
+                     <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>,
+                     <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>;
+    };
Signature · 1 line
2.24.1
maintainer Reviewed-by on v3 1/7
#2 lore raw

Re: [PATCH v3 1/7] dt-bindings: timer: Add bindings for NVIDIA Tegra186 timers

Quoted 13 lines · Thierry Reding

From: Thierry Reding <[email protected]>

The NVIDIA Tegra186 SoC contains an IP block that provides a register interface for ten timers with a 29-bit counter that can generate one- shot, periodic or watchdog interrupts.

---
Changes in v2:
- add required properties section
- add additionalProperties: false
- do not show status in example

Quoted 4 lines
 .../bindings/timer/nvidia,tegra186-timer.yaml | 61 +++++++++++++++++++
 1 file changed, 61 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/timer/nvidia,tegra186-timer.yaml
#3 lore raw

PATCH v3 2/7 clocksource: Add Tegra186 timers support

In reply to Thierry Reding

From: Thierry Reding <[email protected]>

Currently this only supports a single watchdog, which uses a timer in the background for countdown. Eventually the timers could be used for various time-keeping tasks, but by default the architected timer will already provide that functionality.

---
Changes in v3:
- request IRQ at the end of ->probe() to avoid race condition
- only enable/disable watchdog when it's active
- use _relaxed variants of register accessors
- drop tegra186_timer.irq field

Changes in v2:
- add dependency on WATCHDOG && WATCHDOG_CORE
- expose TSC, OSC and USEC clocksources
- implement suspend/resume support
- make driver tristate

 drivers/clocksource/Kconfig          |   8 +
 drivers/clocksource/Makefile         |   1 +
 drivers/clocksource/timer-tegra186.c | 508 +++++++++++++++++++++++++++
 3 files changed, 517 insertions(+)
 create mode 100644 drivers/clocksource/timer-tegra186.c
drivers/clocksource/Kconfig +8 -0
index f2142e6bbea3..385573c215d8 100644
@@ -149,6 +149,14 @@ config TEGRA_TIMER
 	help
 	  Enables support for the Tegra driver.
 
+config TEGRA186_TIMER
+	tristate "NVIDIA Tegra186 timer driver"
+	depends on ARCH_TEGRA || COMPILE_TEST
+	depends on WATCHDOG && WATCHDOG_CORE
+	help
+	  Enables support for the timers and watchdogs found on NVIDIA
+	  Tegra186 and later SoCs.
+
 config VT8500_TIMER
 	bool "VT8500 timer driver" if COMPILE_TEST
 	depends on HAS_IOMEM
drivers/clocksource/Makefile +1 -0
index 641ba5383ab5..ffa7950f4b7c 100644
@@ -38,6 +38,7 @@ obj-$(CONFIG_SUN4I_TIMER)	+= timer-sun4i.o
 obj-$(CONFIG_SUN5I_HSTIMER)	+= timer-sun5i.o
 obj-$(CONFIG_MESON6_TIMER)	+= timer-meson6.o
 obj-$(CONFIG_TEGRA_TIMER)	+= timer-tegra.o
+obj-$(CONFIG_TEGRA186_TIMER)	+= timer-tegra186.o
 obj-$(CONFIG_VT8500_TIMER)	+= timer-vt8500.o
 obj-$(CONFIG_NSPIRE_TIMER)	+= timer-zevio.o
 obj-$(CONFIG_BCM_KONA_TIMER)	+= bcm_kona_timer.o
drivers/clocksource/timer-tegra186.c new file +508 -0

508 lines not on this page · raw message

Signature · 1 line
2.24.1
#4 lore raw

Re: [PATCH v3 2/7] clocksource: Add Tegra186 timers support

03.04.2020 23:22, Thierry Reding пишет:
...

drivers/clocksource/Kconfig config TEGRA_TIMER · line 158

Quoted 7 lines
drivers/clocksource/Kconfig +7 -0
+config TEGRA186_TIMER
+	tristate "NVIDIA Tegra186 timer driver"
+	depends on ARCH_TEGRA || COMPILE_TEST
+	depends on WATCHDOG && WATCHDOG_CORE
+	help
+	  Enables support for the timers and watchdogs found on NVIDIA
+	  Tegra186 and later SoCs.

Personally, I'd like to see this in drivers/watchdog/ because I've seen cases where subsys maintainers are doing bulk-changes to drivers and missing those that reside outside of the subsys directory.

But, that's not to me to decide, so I don't really mind.

...

drivers/clocksource/timer-tegra186.c line 149

Quoted 8 lines
drivers/clocksource/timer-tegra186.c new file +8 -0
+static void tegra186_wdt_enable(struct tegra186_wdt *wdt)
+{
+	struct tegra186_timer *tegra = wdt->tmr->parent;
+	u32 value;
+
+	/* unmask hardware IRQ, this may have been lost across powergate */
+	value = TKEIE_WDT_MASK(wdt->index, 1);
+	writel(value, tegra->regs + TKEIE(wdt->tmr->hwirq));

Perhaps this one also could be relaxed, for consistency. Sorry for missing it in v2 :)

#5 lore raw

Re: [PATCH v3 2/7] clocksource: Add Tegra186 timers support

In reply to Thierry Reding

03.04.2020 23:22, Thierry Reding пишет:
...

drivers/clocksource/timer-tegra186.c line 376

Quoted 8 lines
drivers/clocksource/timer-tegra186.c new file +8 -0
+static irqreturn_t tegra186_timer_irq(int irq, void *data)
+{
+	struct tegra186_timer *tegra = data;
+
+	if (watchdog_active(&tegra->wdt->base)) {
+		tegra186_wdt_disable(tegra->wdt);
+		tegra186_wdt_enable(tegra->wdt);
+	}

Shouldn't this return IRQ_NONE if watchdog is inactive?

Quoted 2 lines
(quoted diff) +2 -0
+	return IRQ_HANDLED;
+}
#6 lore raw

Re: [PATCH v3 2/7] clocksource: Add Tegra186 timers support

03.04.2020 23:51, Dmitry Osipenko пишет:

Quoted 13 lines

03.04.2020 23:22, Thierry Reding пишет:
...

drivers/clocksource/timer-tegra186.c line 376

Quoted 8 lines
drivers/clocksource/timer-tegra186.c new file +8 -0
+static irqreturn_t tegra186_timer_irq(int irq, void *data)
+{
+	struct tegra186_timer *tegra = data;
+
+	if (watchdog_active(&tegra->wdt->base)) {
+		tegra186_wdt_disable(tegra->wdt);
+		tegra186_wdt_enable(tegra->wdt);
+	}

Shouldn't this return IRQ_NONE if watchdog is inactive?

Quoted 3 lines

Review

Quoted 2 lines
(quoted diff) +2 -0
+	return IRQ_HANDLED;
+}

Could you please explain why this interrupt handler is needed at all? Shouldn't the watchdog's core take care of the pinging?

#7 lore raw

Re: [PATCH v3 2/7] clocksource: Add Tegra186 timers support

In reply to Thierry Reding

03.04.2020 23:22, Thierry Reding пишет:
...

drivers/clocksource/timer-tegra186.c line 228

Quoted 7 lines
drivers/clocksource/timer-tegra186.c new file +7 -0
+static int tegra186_wdt_set_timeout(struct watchdog_device *wdd,
+				    unsigned int timeout)
+{
+	struct tegra186_wdt *wdt = to_tegra186_wdt(wdd);
+
+	if (watchdog_active(&wdt->base))
+		tegra186_wdt_disable(wdt);

Could this and other tegra186_wdt_enable/disable occurrences race with the interrupt handler?

Shouldn't IRQ be disabled/enable in a such cases to avoid the races?

Quoted 7 lines
drivers/clocksource/timer-tegra186.c new file +7 -0
+	wdt->base.timeout = timeout;
+
+	if (watchdog_active(&wdt->base))
+		tegra186_wdt_enable(wdt);
+
+	return 0;
+}
#8 lore raw

PATCH v3 3/7 arm64: tegra: Order nodes by unit-address on Tegra194

In reply to Thierry Reding

From: Thierry Reding <[email protected]>

The pin controller device tree node was accidentally added in the wrong place. Move it to the correct location to keep nodes ordered by unit- address.

---
 arch/arm64/boot/dts/nvidia/tegra194.dtsi | 64 ++++++++++++------------
 1 file changed, 32 insertions(+), 32 deletions(-)
arch/arm64/boot/dts/nvidia/tegra194.dtsi +32 -32
index f4ede86e32b4..019f66f03a97 100644
@@ -45,6 +45,38 @@ gpio: gpio@2200000 {
 			gpio-controller;
 		};
 
+		pinmux: pinmux@2430000 {
+			compatible = "nvidia,tegra194-pinmux";
+			reg = <0x2430000 0x17000
+			       0xc300000 0x4000>;
+
+			status = "okay";
+
+			pex_rst_c5_out_state: pex_rst_c5_out {
+				pex_rst {
+					nvidia,pins = "pex_l5_rst_n_pgg1";
+					nvidia,schmitt = <TEGRA_PIN_DISABLE>;
+					nvidia,lpdr = <TEGRA_PIN_ENABLE>;
+					nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+					nvidia,io-high-voltage = <TEGRA_PIN_ENABLE>;
+					nvidia,tristate = <TEGRA_PIN_DISABLE>;
+					nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+				};
+			};
+
+			clkreq_c5_bi_dir_state: clkreq_c5_bi_dir {
+				clkreq {
+					nvidia,pins = "pex_l5_clkreq_n_pgg0";
+					nvidia,schmitt = <TEGRA_PIN_DISABLE>;
+					nvidia,lpdr = <TEGRA_PIN_ENABLE>;
+					nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+					nvidia,io-high-voltage = <TEGRA_PIN_ENABLE>;
+					nvidia,tristate = <TEGRA_PIN_DISABLE>;
+					nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+				};
+			};
+		};
+
 		ethernet@2490000 {
 			compatible = "nvidia,tegra194-eqos",
 				     "nvidia,tegra186-eqos",
@@ -139,38 +171,6 @@ agic: interrupt-controller@2a40000 {
 			};
 		};
 
-		pinmux: pinmux@2430000 {
-			compatible = "nvidia,tegra194-pinmux";
-			reg = <0x2430000 0x17000
-			       0xc300000 0x4000>;
-
-			status = "okay";
-
-			pex_rst_c5_out_state: pex_rst_c5_out {
-				pex_rst {
-					nvidia,pins = "pex_l5_rst_n_pgg1";
-					nvidia,schmitt = <TEGRA_PIN_DISABLE>;
-					nvidia,lpdr = <TEGRA_PIN_ENABLE>;
-					nvidia,enable-input = <TEGRA_PIN_DISABLE>;
-					nvidia,io-high-voltage = <TEGRA_PIN_ENABLE>;
-					nvidia,tristate = <TEGRA_PIN_DISABLE>;
-					nvidia,pull = <TEGRA_PIN_PULL_NONE>;
-				};
-			};
-
-			clkreq_c5_bi_dir_state: clkreq_c5_bi_dir {
-				clkreq {
-					nvidia,pins = "pex_l5_clkreq_n_pgg0";
-					nvidia,schmitt = <TEGRA_PIN_DISABLE>;
-					nvidia,lpdr = <TEGRA_PIN_ENABLE>;
-					nvidia,enable-input = <TEGRA_PIN_ENABLE>;
-					nvidia,io-high-voltage = <TEGRA_PIN_ENABLE>;
-					nvidia,tristate = <TEGRA_PIN_DISABLE>;
-					nvidia,pull = <TEGRA_PIN_PULL_NONE>;
-				};
-			};
-		};
-
 		mc: memory-controller@2c00000 {
 			compatible = "nvidia,tegra194-mc";
 			reg = <0x02c00000 0x100000>,
Signature · 1 line
2.24.1
#9 lore raw

PATCH v3 4/7 arm64: tegra: Add native timer support on Tegra186

In reply to Thierry Reding

From: Thierry Reding <[email protected]>

The native timers IP block found on NVIDIA Tegra SoCs implements a watchdog timer that can be used to recover from system hangs. Add the device tree node on Tegra186.

---
 arch/arm64/boot/dts/nvidia/tegra186.dtsi | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)
arch/arm64/boot/dts/nvidia/tegra186.dtsi +16 -0
index 58100fb9cd8b..4dfa70e93693 100644
@@ -167,6 +167,22 @@ emc: external-memory-controller@2c60000 {
 		};
 	};
 
+	timer@3010000 {
+		compatible = "nvidia,tegra186-timer";
+		reg = <0x0 0x03010000 0x0 0x000e0000>;
+		interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>;
+		status = "disabled";
+	};
+
 	uarta: serial@3100000 {
 		compatible = "nvidia,tegra186-uart", "nvidia,tegra20-uart";
 		reg = <0x0 0x03100000 0x0 0x40>;
Signature · 1 line
2.24.1
#10 lore raw

PATCH v3 5/7 arm64: tegra: Enable native timers on Jetson TX2

In reply to Thierry Reding

From: Thierry Reding <[email protected]>

Enable the native timers on Jetson TX2 to allow using the watchdog functionality to recover from system hangs, for example.

---
 arch/arm64/boot/dts/nvidia/tegra186-p3310.dtsi | 4 ++++
 1 file changed, 4 insertions(+)
arch/arm64/boot/dts/nvidia/tegra186-p3310.dtsi +4 -0
index da96de04d003..9aa17744c4a0 100644
@@ -58,6 +58,10 @@ memory-controller@2c00000 {
 		status = "okay";
 	};
 
+	timer@3010000 {
+		status = "okay";
+	};
+
 	serial@3100000 {
 		status = "okay";
 	};
Signature · 1 line
2.24.1
#11 lore raw

Re: [PATCH v3 5/7] arm64: tegra: Enable native timers on Jetson TX2

03.04.2020 23:22, Thierry Reding пишет:

Quoted 15 lines

From: Thierry Reding <[email protected]>

Enable the native timers on Jetson TX2 to allow using the watchdog functionality to recover from system hangs, for example.

---
 arch/arm64/boot/dts/nvidia/tegra186-p3310.dtsi | 4 ++++
 1 file changed, 4 insertions(+)
arch/arm64/boot/dts/nvidia/tegra186-p3310.dtsi +0 -0
index da96de04d003..9aa17744c4a0 100644

arch/arm64/boot/dts/nvidia/tegra186-p3310.dtsi memory-controller@2c00000 { · line 63

Quoted 6 lines
arch/arm64/boot/dts/nvidia/tegra186-p3310.dtsi +3 -0
@@ -58,6 +58,10 @@ memory-controller@2c00000 {
 		status = "okay";
 	};
 
+	timer@3010000 {
+		status = "okay";
+	};

Why timer needs to be enabled per-board?

#12 lore raw

PATCH v3 6/7 arm64: tegra: Add native timer support on Tegra194

In reply to Thierry Reding

From: Thierry Reding <[email protected]>

The native timers IP block found on NVIDIA Tegra SoCs implements a watchdog timer that can be used to recover from system hangs. Add the device tree node on Tegra194.

---
 arch/arm64/boot/dts/nvidia/tegra194.dtsi | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)
arch/arm64/boot/dts/nvidia/tegra194.dtsi +17 -0
index 019f66f03a97..a0a5b44ff9bb 100644
@@ -213,6 +213,23 @@ emc: external-memory-controller@2c60000 {
 			};
 		};
 
+		timer@3010000 {
+			compatible = "nvidia,tegra194-timer",
+				     "nvidia,tegra186-timer";
+			reg = <0x03010000 0x000e0000>;
+			interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>;
+			status = "disabled";
+		};
+
 		uarta: serial@3100000 {
 			compatible = "nvidia,tegra194-uart", "nvidia,tegra20-uart";
 			reg = <0x03100000 0x40>;
Signature · 1 line
2.24.1
#13 lore raw

PATCH v3 7/7 arm64: tegra: Enable native timers on Jetson AGX Xavier

In reply to Thierry Reding

From: Thierry Reding <[email protected]>

Enable the native timers on Jetson AGX Xavier to allow using the watchdog functionality to recover from system hangs, for example.

---
 arch/arm64/boot/dts/nvidia/tegra194-p2888.dtsi | 4 ++++
 1 file changed, 4 insertions(+)
arch/arm64/boot/dts/nvidia/tegra194-p2888.dtsi +4 -0
index 623f7d7d216b..d68588f2709e 100644
@@ -52,6 +52,10 @@ memory-controller@2c00000 {
 			status = "okay";
 		};
 
+		timer@3010000 {
+			status = "okay";
+		};
+
 		serial@3110000 {
 			status = "okay";
 		};
Signature · 1 line
2.24.1