clocksource: Add NVIDIA Tegra186 timers support
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
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
@@ -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
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.
Signed-off-by Thierry Reding <[email protected]>---
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
PATCH v3 2/7 clocksource: Add Tegra186 timers support
In reply to Thierry RedingFrom: 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
@@ -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
@@ -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
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 :)
Re: [PATCH v3 2/7] clocksource: Add Tegra186 timers support
In reply to Thierry Reding03.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; +}
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_NONEif 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?
Re: [PATCH v3 2/7] clocksource: Add Tegra186 timers support
In reply to Thierry Reding03.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 ; +}
PATCH v3 3/7 arm64: tegra: Order nodes by unit-address on Tegra194
In reply to Thierry RedingFrom: 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
@@ -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
PATCH v3 4/7 arm64: tegra: Add native timer support on Tegra186
In reply to Thierry RedingFrom: 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
@@ -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
PATCH v3 5/7 arm64: tegra: Enable native timers on Jetson TX2
In reply to Thierry RedingFrom: 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
@@ -58,6 +58,10 @@ memory-controller@2c00000 { status = "okay"; }; + timer@3010000 { + status = "okay"; + }; + serial@3100000 { status = "okay"; };
Signature · 1 line
2.24.1
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.
Signed-off-by Thierry Reding <[email protected]>--- arch/arm64/boot/dts/nvidia/tegra186-p3310.dtsi | 4 ++++ 1 file changed, 4 insertions(+)arch/arm64/boot/dts/nvidia/tegra186-p3310.dtsi +0
-0
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?
PATCH v3 6/7 arm64: tegra: Add native timer support on Tegra194
In reply to Thierry RedingFrom: 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
@@ -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
PATCH v3 7/7 arm64: tegra: Enable native timers on Jetson AGX Xavier
In reply to Thierry RedingFrom: 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
@@ -52,6 +52,10 @@ memory-controller@2c00000 { status = "okay"; }; + timer@3010000 { + status = "okay"; + }; + serial@3110000 { status = "okay"; };
Signature · 1 line
2.24.1