linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/8] clocksource/drivers/timer-atmel-tcb: add sama5d2 support
@ 2019-10-09 22:39 Alexandre Belloni
  2019-10-09 22:39 ` [PATCH 1/8] dt-bindings: mfd: atmel-tcb: convert bindings to json-schema Alexandre Belloni
                   ` (8 more replies)
  0 siblings, 9 replies; 11+ messages in thread
From: Alexandre Belloni @ 2019-10-09 22:39 UTC (permalink / raw)
  To: Daniel Lezcano
  Cc: Thomas Gleixner, Nicolas Ferre, Sebastian Andrzej Siewior,
	linux-arm-kernel, linux-kernel, devicetree, Alexandre Belloni

This series mainly adds sama5d2 support where we need to avoid using
clock index 0 because that clock is never enabled by the driver.

There is also a rework of the 32khz clock handling so it is not used for
clockevents on 32 bit counter because the increased rate improves the
resolution and doesn't have any drawback with that counter width. This
replaces a patch that has been carried in the linux-rt tree for a while.

Alexandre Belloni (8):
  dt-bindings: mfd: atmel-tcb: convert bindings to json-schema
  dt-bindings: mfd: atmel,at91rm9200-tcb: add sama5d2 compatible
  ARM: dts: at91: sama5d2: add TCB GCLK
  clocksource/drivers/timer-atmel-tcb: rework 32khz clock selection
  clocksource/drivers/timer-atmel-tcb: fill tcb_config
  clocksource/drivers/timer-atmel-tcb: stop using the 32kHz for
    clockevents
  clocksource/drivers/timer-atmel-tcb: allow selecting first divider
  clocksource/drivers/timer-atmel-tcb: add sama5d2 support

 .../bindings/mfd/atmel,at91rm9200-tcb.yaml    | 113 ++++++++++++++++++
 .../devicetree/bindings/mfd/atmel-tcb.txt     |  56 ---------
 arch/arm/boot/dts/sama5d2.dtsi                |  12 +-
 drivers/clocksource/timer-atmel-tcb.c         | 101 +++++++++-------
 include/soc/at91/atmel_tcb.h                  |   1 +
 5 files changed, 178 insertions(+), 105 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/mfd/atmel,at91rm9200-tcb.yaml
 delete mode 100644 Documentation/devicetree/bindings/mfd/atmel-tcb.txt

-- 
2.21.0


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

* [PATCH 1/8] dt-bindings: mfd: atmel-tcb: convert bindings to json-schema
  2019-10-09 22:39 [PATCH 0/8] clocksource/drivers/timer-atmel-tcb: add sama5d2 support Alexandre Belloni
@ 2019-10-09 22:39 ` Alexandre Belloni
  2019-10-15 22:39   ` Rob Herring
  2019-10-09 22:40 ` [PATCH 2/8] dt-bindings: mfd: atmel,at91rm9200-tcb: add sama5d2 compatible Alexandre Belloni
                   ` (7 subsequent siblings)
  8 siblings, 1 reply; 11+ messages in thread
From: Alexandre Belloni @ 2019-10-09 22:39 UTC (permalink / raw)
  To: Daniel Lezcano
  Cc: Thomas Gleixner, Nicolas Ferre, Sebastian Andrzej Siewior,
	linux-arm-kernel, linux-kernel, devicetree, Alexandre Belloni,
	Rob Herring

Convert Atmel Timer Counter Blocks bindings to DT schema format using
json-schema.

Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
---
Cc: Rob Herring <robh+dt@kernel.org>

 .../bindings/mfd/atmel,at91rm9200-tcb.yaml    | 89 +++++++++++++++++++
 .../devicetree/bindings/mfd/atmel-tcb.txt     | 56 ------------
 2 files changed, 89 insertions(+), 56 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/mfd/atmel,at91rm9200-tcb.yaml
 delete mode 100644 Documentation/devicetree/bindings/mfd/atmel-tcb.txt

diff --git a/Documentation/devicetree/bindings/mfd/atmel,at91rm9200-tcb.yaml b/Documentation/devicetree/bindings/mfd/atmel,at91rm9200-tcb.yaml
new file mode 100644
index 000000000000..4d9247fc0593
--- /dev/null
+++ b/Documentation/devicetree/bindings/mfd/atmel,at91rm9200-tcb.yaml
@@ -0,0 +1,89 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: "http://devicetree.org/schemas/mfd/atmel,at91rm9200-tcb.yaml#"
+$schema: "http://devicetree.org/meta-schemas/core.yaml#"
+
+title: Atmel Timer Counter Block
+
+maintainers:
+  - Alexandre Belloni <alexandre.belloni@bootlin.com>
+
+description: |
+  The Atmel (now Microchip) SoCs have timers named Timer Counter Block. Each
+  timer has three channels with two counters each.
+
+properties:
+  compatible:
+    items:
+      - enum:
+          - atmel,at91rm9200-tcb
+          - atmel,at91sam9x5-tcb
+      - const: simple-mfd
+      - const: syscon
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    description:
+      List of interrupts. One interrupt per TCB channel if available or one
+      interrupt for the TC block
+    minItems: 1
+    maxItems: 3
+
+  clock-names:
+    description:
+      List of clock names. Always includes t0_clk and slow clk. Also includes
+      t1_clk and t2_clk if a clock per channel is available.
+    minItems: 2
+    maxItems: 4
+    items:
+      enum:
+        - t0_clk
+        - t1_clk
+        - t2_clk
+        - slow_clk
+
+  clocks:
+    minItems: 2
+    maxItems: 4
+
+  '#address-cells':
+    const: 1
+
+  '#size-cells':
+    const: 0
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+  - clock-names
+  - '#address-cells'
+  - '#size-cells'
+
+examples:
+  - |
+    /* One interrupt per TC block: */
+        tcb0: timer@fff7c000 {
+                compatible = "atmel,at91rm9200-tcb", "simple-mfd", "syscon";
+                #address-cells = <1>;
+                #size-cells = <0>;
+                reg = <0xfff7c000 0x100>;
+                interrupts = <18 4>;
+                clocks = <&tcb0_clk>, <&clk32k>;
+                clock-names = "t0_clk", "slow_clk";
+        };
+
+    /* One interrupt per TC channel in a TC block: */
+        tcb1: timer@fffdc000 {
+                compatible = "atmel,at91rm9200-tcb", "simple-mfd", "syscon";
+                #address-cells = <1>;
+                #size-cells = <0>;
+                reg = <0xfffdc000 0x100>;
+                interrupts = <26 4>, <27 4>, <28 4>;
+                clocks = <&tcb1_clk>, <&clk32k>;
+                clock-names = "t0_clk", "slow_clk";
+        };
diff --git a/Documentation/devicetree/bindings/mfd/atmel-tcb.txt b/Documentation/devicetree/bindings/mfd/atmel-tcb.txt
deleted file mode 100644
index c4a83e364cb6..000000000000
--- a/Documentation/devicetree/bindings/mfd/atmel-tcb.txt
+++ /dev/null
@@ -1,56 +0,0 @@
-* Device tree bindings for Atmel Timer Counter Blocks
-- compatible: Should be "atmel,<chip>-tcb", "simple-mfd", "syscon".
-  <chip> can be "at91rm9200" or "at91sam9x5"
-- reg: Should contain registers location and length
-- #address-cells: has to be 1
-- #size-cells: has to be 0
-- interrupts: Should contain all interrupts for the TC block
-  Note that you can specify several interrupt cells if the TC
-  block has one interrupt per channel.
-- clock-names: tuple listing input clock names.
-	Required elements: "t0_clk", "slow_clk"
-	Optional elements: "t1_clk", "t2_clk"
-- clocks: phandles to input clocks.
-
-The TCB can expose multiple subdevices:
- * a timer
-   - compatible: Should be "atmel,tcb-timer"
-   - reg: Should contain the TCB channels to be used. If the
-     counter width is 16 bits (at91rm9200-tcb), two consecutive
-     channels are needed. Else, only one channel will be used.
-
-Examples:
-
-One interrupt per TC block:
-	tcb0: timer@fff7c000 {
-		compatible = "atmel,at91rm9200-tcb", "simple-mfd", "syscon";
-		#address-cells = <1>;
-		#size-cells = <0>;
-		reg = <0xfff7c000 0x100>;
-		interrupts = <18 4>;
-		clocks = <&tcb0_clk>, <&clk32k>;
-		clock-names = "t0_clk", "slow_clk";
-
-		timer@0 {
-			compatible = "atmel,tcb-timer";
-			reg = <0>, <1>;
-		};
-
-		timer@2 {
-			compatible = "atmel,tcb-timer";
-			reg = <2>;
-		};
-	};
-
-One interrupt per TC channel in a TC block:
-	tcb1: timer@fffdc000 {
-		compatible = "atmel,at91rm9200-tcb", "simple-mfd", "syscon";
-		#address-cells = <1>;
-		#size-cells = <0>;
-		reg = <0xfffdc000 0x100>;
-		interrupts = <26 4>, <27 4>, <28 4>;
-		clocks = <&tcb1_clk>, <&clk32k>;
-		clock-names = "t0_clk", "slow_clk";
-	};
-
-
-- 
2.21.0


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

* [PATCH 2/8] dt-bindings: mfd: atmel,at91rm9200-tcb: add sama5d2 compatible
  2019-10-09 22:39 [PATCH 0/8] clocksource/drivers/timer-atmel-tcb: add sama5d2 support Alexandre Belloni
  2019-10-09 22:39 ` [PATCH 1/8] dt-bindings: mfd: atmel-tcb: convert bindings to json-schema Alexandre Belloni
@ 2019-10-09 22:40 ` Alexandre Belloni
  2019-10-09 22:40 ` [PATCH 3/8] ARM: dts: at91: sama5d2: add TCB GCLK Alexandre Belloni
                   ` (6 subsequent siblings)
  8 siblings, 0 replies; 11+ messages in thread
From: Alexandre Belloni @ 2019-10-09 22:40 UTC (permalink / raw)
  To: Daniel Lezcano
  Cc: Thomas Gleixner, Nicolas Ferre, Sebastian Andrzej Siewior,
	linux-arm-kernel, linux-kernel, devicetree, Alexandre Belloni,
	Rob Herring

The sama5d2 TC block TIMER_CLOCK1 is different from the at91sam9x5 one.
Instead of being MCK / 2, it is the TCB GCLK.

Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
---
Cc: Rob Herring <robh+dt@kernel.org>

 .../bindings/mfd/atmel,at91rm9200-tcb.yaml    | 36 +++++++++++++++----
 1 file changed, 30 insertions(+), 6 deletions(-)

diff --git a/Documentation/devicetree/bindings/mfd/atmel,at91rm9200-tcb.yaml b/Documentation/devicetree/bindings/mfd/atmel,at91rm9200-tcb.yaml
index 4d9247fc0593..4fc5bd34d38b 100644
--- a/Documentation/devicetree/bindings/mfd/atmel,at91rm9200-tcb.yaml
+++ b/Documentation/devicetree/bindings/mfd/atmel,at91rm9200-tcb.yaml
@@ -19,6 +19,7 @@ properties:
       - enum:
           - atmel,at91rm9200-tcb
           - atmel,at91sam9x5-tcb
+          - atmel,sama5d2-tcb
       - const: simple-mfd
       - const: syscon
 
@@ -38,12 +39,6 @@ properties:
       t1_clk and t2_clk if a clock per channel is available.
     minItems: 2
     maxItems: 4
-    items:
-      enum:
-        - t0_clk
-        - t1_clk
-        - t2_clk
-        - slow_clk
 
   clocks:
     minItems: 2
@@ -55,6 +50,35 @@ properties:
   '#size-cells':
     const: 0
 
+allOf:
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: atmel,sama5d2-tcb
+    then:
+      properties:
+        clocks:
+          minItems: 3
+          maxItems: 3
+        clock-names:
+          items:
+            - const: t0_clk
+            - const: gclk
+            - const: slow_clk
+    else:
+      properties:
+        clocks:
+          minItems: 2
+          maxItems: 4
+        clock-names:
+          items:
+            enum:
+              - t0_clk
+              - t1_clk
+              - t2_clk
+              - slow_clk
+
 required:
   - compatible
   - reg
-- 
2.21.0


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

* [PATCH 3/8] ARM: dts: at91: sama5d2: add TCB GCLK
  2019-10-09 22:39 [PATCH 0/8] clocksource/drivers/timer-atmel-tcb: add sama5d2 support Alexandre Belloni
  2019-10-09 22:39 ` [PATCH 1/8] dt-bindings: mfd: atmel-tcb: convert bindings to json-schema Alexandre Belloni
  2019-10-09 22:40 ` [PATCH 2/8] dt-bindings: mfd: atmel,at91rm9200-tcb: add sama5d2 compatible Alexandre Belloni
@ 2019-10-09 22:40 ` Alexandre Belloni
  2019-10-09 22:40 ` [PATCH 4/8] clocksource/drivers/timer-atmel-tcb: rework 32khz clock selection Alexandre Belloni
                   ` (5 subsequent siblings)
  8 siblings, 0 replies; 11+ messages in thread
From: Alexandre Belloni @ 2019-10-09 22:40 UTC (permalink / raw)
  To: Daniel Lezcano
  Cc: Thomas Gleixner, Nicolas Ferre, Sebastian Andrzej Siewior,
	linux-arm-kernel, linux-kernel, devicetree, Alexandre Belloni

The sama5d2 tcbs take an extra input clock, their gclk.

Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
---
 arch/arm/boot/dts/sama5d2.dtsi | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/arch/arm/boot/dts/sama5d2.dtsi b/arch/arm/boot/dts/sama5d2.dtsi
index 2e2c1a7b1d1d..f878d7866970 100644
--- a/arch/arm/boot/dts/sama5d2.dtsi
+++ b/arch/arm/boot/dts/sama5d2.dtsi
@@ -495,23 +495,23 @@
 			};
 
 			tcb0: timer@f800c000 {
-				compatible = "atmel,at91sam9x5-tcb", "simple-mfd", "syscon";
+				compatible = "atmel,sama5d2-tcb", "simple-mfd", "syscon";
 				#address-cells = <1>;
 				#size-cells = <0>;
 				reg = <0xf800c000 0x100>;
 				interrupts = <35 IRQ_TYPE_LEVEL_HIGH 0>;
-				clocks = <&pmc PMC_TYPE_PERIPHERAL 35>, <&clk32k>;
-				clock-names = "t0_clk", "slow_clk";
+				clocks = <&pmc PMC_TYPE_PERIPHERAL 35>, <&pmc PMC_TYPE_GCK 35>, <&clk32k>;
+				clock-names = "t0_clk", "gclk", "slow_clk";
 			};
 
 			tcb1: timer@f8010000 {
-				compatible = "atmel,at91sam9x5-tcb", "simple-mfd", "syscon";
+				compatible = "atmel,sama5d2-tcb", "simple-mfd", "syscon";
 				#address-cells = <1>;
 				#size-cells = <0>;
 				reg = <0xf8010000 0x100>;
 				interrupts = <36 IRQ_TYPE_LEVEL_HIGH 0>;
-				clocks = <&pmc PMC_TYPE_PERIPHERAL 36>, <&clk32k>;
-				clock-names = "t0_clk", "slow_clk";
+				clocks = <&pmc PMC_TYPE_PERIPHERAL 36>, <&pmc PMC_TYPE_GCK 36>, <&clk32k>;
+				clock-names = "t0_clk", "gclk", "slow_clk";
 			};
 
 			hsmc: hsmc@f8014000 {
-- 
2.21.0


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

* [PATCH 4/8] clocksource/drivers/timer-atmel-tcb: rework 32khz clock selection
  2019-10-09 22:39 [PATCH 0/8] clocksource/drivers/timer-atmel-tcb: add sama5d2 support Alexandre Belloni
                   ` (2 preceding siblings ...)
  2019-10-09 22:40 ` [PATCH 3/8] ARM: dts: at91: sama5d2: add TCB GCLK Alexandre Belloni
@ 2019-10-09 22:40 ` Alexandre Belloni
  2019-10-09 22:40 ` [PATCH 5/8] clocksource/drivers/timer-atmel-tcb: fill tcb_config Alexandre Belloni
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 11+ messages in thread
From: Alexandre Belloni @ 2019-10-09 22:40 UTC (permalink / raw)
  To: Daniel Lezcano
  Cc: Thomas Gleixner, Nicolas Ferre, Sebastian Andrzej Siewior,
	linux-arm-kernel, linux-kernel, devicetree, Alexandre Belloni

On all the supported SoCs, the slow clock is always ATMEL_TC_TIMER_CLOCK5,
avoid looking it up and pass it directly to setup_clkevents.

Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
---
 drivers/clocksource/timer-atmel-tcb.c | 11 ++---------
 1 file changed, 2 insertions(+), 9 deletions(-)

diff --git a/drivers/clocksource/timer-atmel-tcb.c b/drivers/clocksource/timer-atmel-tcb.c
index 7427b07495a8..b255a4a1a36b 100644
--- a/drivers/clocksource/timer-atmel-tcb.c
+++ b/drivers/clocksource/timer-atmel-tcb.c
@@ -346,7 +346,7 @@ static void __init tcb_setup_single_chan(struct atmel_tc *tc, int mck_divisor_id
 	writel(ATMEL_TC_SYNC, tcaddr + ATMEL_TC_BCR);
 }
 
-static const u8 atmel_tcb_divisors[5] = { 2, 8, 32, 128, 0, };
+static const u8 atmel_tcb_divisors[] = { 2, 8, 32, 128 };
 
 static const struct of_device_id atmel_tcb_of_match[] = {
 	{ .compatible = "atmel,at91rm9200-tcb", .data = (void *)16, },
@@ -362,7 +362,6 @@ static int __init tcb_clksrc_init(struct device_node *node)
 	u64 (*tc_sched_clock)(void);
 	u32 rate, divided_rate = 0;
 	int best_divisor_idx = -1;
-	int clk32k_divisor_idx = -1;
 	int bits;
 	int i;
 	int ret;
@@ -416,12 +415,6 @@ static int __init tcb_clksrc_init(struct device_node *node)
 		unsigned divisor = atmel_tcb_divisors[i];
 		unsigned tmp;
 
-		/* remember 32 KiHz clock for later */
-		if (!divisor) {
-			clk32k_divisor_idx = i;
-			continue;
-		}
-
 		tmp = rate / divisor;
 		pr_debug("TC: %u / %-3u [%d] --> %u\n", rate, divisor, i, tmp);
 		if (best_divisor_idx > 0) {
@@ -467,7 +460,7 @@ static int __init tcb_clksrc_init(struct device_node *node)
 		goto err_disable_t1;
 
 	/* channel 2:  periodic and oneshot timer support */
-	ret = setup_clkevents(&tc, clk32k_divisor_idx);
+	ret = setup_clkevents(&tc, ATMEL_TC_TIMER_CLOCK5);
 	if (ret)
 		goto err_unregister_clksrc;
 
-- 
2.21.0


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

* [PATCH 5/8] clocksource/drivers/timer-atmel-tcb: fill tcb_config
  2019-10-09 22:39 [PATCH 0/8] clocksource/drivers/timer-atmel-tcb: add sama5d2 support Alexandre Belloni
                   ` (3 preceding siblings ...)
  2019-10-09 22:40 ` [PATCH 4/8] clocksource/drivers/timer-atmel-tcb: rework 32khz clock selection Alexandre Belloni
@ 2019-10-09 22:40 ` Alexandre Belloni
  2019-10-09 22:40 ` [PATCH 6/8] clocksource/drivers/timer-atmel-tcb: stop using the 32kHz for clockevents Alexandre Belloni
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 11+ messages in thread
From: Alexandre Belloni @ 2019-10-09 22:40 UTC (permalink / raw)
  To: Daniel Lezcano
  Cc: Thomas Gleixner, Nicolas Ferre, Sebastian Andrzej Siewior,
	linux-arm-kernel, linux-kernel, devicetree, Alexandre Belloni

Use the tcb_config and struct atmel_tcb_config to get the timer counter
width. This is necessary because atmel_tcb_config will be extended later
on.

Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
---
 drivers/clocksource/timer-atmel-tcb.c | 18 +++++++++++++++---
 1 file changed, 15 insertions(+), 3 deletions(-)

diff --git a/drivers/clocksource/timer-atmel-tcb.c b/drivers/clocksource/timer-atmel-tcb.c
index b255a4a1a36b..423af2f9835f 100644
--- a/drivers/clocksource/timer-atmel-tcb.c
+++ b/drivers/clocksource/timer-atmel-tcb.c
@@ -348,9 +348,17 @@ static void __init tcb_setup_single_chan(struct atmel_tc *tc, int mck_divisor_id
 
 static const u8 atmel_tcb_divisors[] = { 2, 8, 32, 128 };
 
+static struct atmel_tcb_config tcb_rm9200_config = {
+	.counter_width = 16,
+};
+
+static struct atmel_tcb_config tcb_sam9x5_config = {
+	.counter_width = 32,
+};
+
 static const struct of_device_id atmel_tcb_of_match[] = {
-	{ .compatible = "atmel,at91rm9200-tcb", .data = (void *)16, },
-	{ .compatible = "atmel,at91sam9x5-tcb", .data = (void *)32, },
+	{ .compatible = "atmel,at91rm9200-tcb", .data = &tcb_rm9200_config, },
+	{ .compatible = "atmel,at91sam9x5-tcb", .data = &tcb_sam9x5_config, },
 	{ /* sentinel */ }
 };
 
@@ -398,7 +406,11 @@ static int __init tcb_clksrc_init(struct device_node *node)
 	}
 
 	match = of_match_node(atmel_tcb_of_match, node->parent);
-	bits = (uintptr_t)match->data;
+	if (!match)
+		return -ENODEV;
+
+	tc.tcb_config = match->data;
+	bits = tc.tcb_config->counter_width;
 
 	for (i = 0; i < ARRAY_SIZE(tc.irq); i++)
 		writel(ATMEL_TC_ALL_IRQ, tc.regs + ATMEL_TC_REG(i, IDR));
-- 
2.21.0


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

* [PATCH 6/8] clocksource/drivers/timer-atmel-tcb: stop using the 32kHz for clockevents
  2019-10-09 22:39 [PATCH 0/8] clocksource/drivers/timer-atmel-tcb: add sama5d2 support Alexandre Belloni
                   ` (4 preceding siblings ...)
  2019-10-09 22:40 ` [PATCH 5/8] clocksource/drivers/timer-atmel-tcb: fill tcb_config Alexandre Belloni
@ 2019-10-09 22:40 ` Alexandre Belloni
  2019-10-09 22:40 ` [PATCH 7/8] clocksource/drivers/timer-atmel-tcb: allow selecting first divider Alexandre Belloni
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 11+ messages in thread
From: Alexandre Belloni @ 2019-10-09 22:40 UTC (permalink / raw)
  To: Daniel Lezcano
  Cc: Thomas Gleixner, Nicolas Ferre, Sebastian Andrzej Siewior,
	linux-arm-kernel, linux-kernel, devicetree, Alexandre Belloni

Stop using the slow clock as the clock source for 32 bit counters because
even at 10MHz, they are able to handle delays up to two minutes. This
provides a way better resolution.

Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
---
 drivers/clocksource/timer-atmel-tcb.c | 61 ++++++++++++++-------------
 1 file changed, 32 insertions(+), 29 deletions(-)

diff --git a/drivers/clocksource/timer-atmel-tcb.c b/drivers/clocksource/timer-atmel-tcb.c
index 423af2f9835f..8fcd4d74c54b 100644
--- a/drivers/clocksource/timer-atmel-tcb.c
+++ b/drivers/clocksource/timer-atmel-tcb.c
@@ -27,9 +27,10 @@
  *   - Some chips support 32 bit counter. A single channel is used for
  *     this 32 bit free-running counter. the second channel is not used.
  *
- *   - The third channel may be used to provide a 16-bit clockevent
- *     source, used in either periodic or oneshot mode.  This runs
- *     at 32 KiHZ, and can handle delays of up to two seconds.
+ *   - The third channel may be used to provide a clockevent source, used in
+ *   either periodic or oneshot mode. For 16-bit counter its runs at 32 KiHZ,
+ *   and can handle delays of up to two seconds. For 32-bit counters, it runs at
+ *   the same rate as the clocksource
  *
  * REVISIT behavior during system suspend states... we should disable
  * all clocks and save the power.  Easily done for clockevent devices,
@@ -47,6 +48,8 @@ static struct
 } tcb_cache[3];
 static u32 bmr_cache;
 
+static const u8 atmel_tcb_divisors[] = { 2, 8, 32, 128 };
+
 static u64 tc_get_cycles(struct clocksource *cs)
 {
 	unsigned long	flags;
@@ -151,13 +154,6 @@ static struct tc_clkevt_device *to_tc_clkevt(struct clock_event_device *clkevt)
 	return container_of(clkevt, struct tc_clkevt_device, clkevt);
 }
 
-/* For now, we always use the 32K clock ... this optimizes for NO_HZ,
- * because using one of the divided clocks would usually mean the
- * tick rate can never be less than several dozen Hz (vs 0.5 Hz).
- *
- * A divided clock could be good for high resolution timers, since
- * 30.5 usec resolution can seem "low".
- */
 static u32 timer_clock;
 
 static int tc_shutdown(struct clock_event_device *d)
@@ -183,7 +179,7 @@ static int tc_set_oneshot(struct clock_event_device *d)
 
 	clk_enable(tcd->clk);
 
-	/* slow clock, count up to RC, then irq and stop */
+	/* count up to RC, then irq and stop */
 	writel(timer_clock | ATMEL_TC_CPCSTOP | ATMEL_TC_WAVE |
 		     ATMEL_TC_WAVESEL_UP_AUTO, regs + ATMEL_TC_REG(2, CMR));
 	writel(ATMEL_TC_CPCS, regs + ATMEL_TC_REG(2, IER));
@@ -205,7 +201,7 @@ static int tc_set_periodic(struct clock_event_device *d)
 	 */
 	clk_enable(tcd->clk);
 
-	/* slow clock, count up to RC, then irq and restart */
+	/* count up to RC, then irq and restart */
 	writel(timer_clock | ATMEL_TC_WAVE | ATMEL_TC_WAVESEL_UP_AUTO,
 		     regs + ATMEL_TC_REG(2, CMR));
 	writel((32768 + HZ / 2) / HZ, tcaddr + ATMEL_TC_REG(2, RC));
@@ -256,47 +252,56 @@ static irqreturn_t ch2_irq(int irq, void *handle)
 	return IRQ_NONE;
 }
 
-static int __init setup_clkevents(struct atmel_tc *tc, int clk32k_divisor_idx)
+static int __init setup_clkevents(struct atmel_tc *tc, int divisor_idx)
 {
+	u32 rate;
 	int ret;
 	struct clk *t2_clk = tc->clk[2];
 	int irq = tc->irq[2];
-
-	ret = clk_prepare_enable(tc->slow_clk);
-	if (ret)
-		return ret;
+	int bits = tc->tcb_config->counter_width;
 
 	/* try to enable t2 clk to avoid future errors in mode change */
 	ret = clk_prepare_enable(t2_clk);
-	if (ret) {
-		clk_disable_unprepare(tc->slow_clk);
+	if (ret)
 		return ret;
-	}
-
-	clk_disable(t2_clk);
 
 	clkevt.regs = tc->regs;
 	clkevt.clk = t2_clk;
 
-	timer_clock = clk32k_divisor_idx;
+	if (bits == 32) {
+		timer_clock = divisor_idx;
+		rate = clk_get_rate(t2_clk) / atmel_tcb_divisors[divisor_idx];
+	} else {
+		ret = clk_prepare_enable(tc->slow_clk);
+		if (ret) {
+			clk_disable_unprepare(t2_clk);
+			return ret;
+		}
+
+		rate = clk_get_rate(tc->slow_clk);
+		timer_clock = ATMEL_TC_TIMER_CLOCK5;
+	}
+
+	clk_disable(t2_clk);
 
 	clkevt.clkevt.cpumask = cpumask_of(0);
 
 	ret = request_irq(irq, ch2_irq, IRQF_TIMER, "tc_clkevt", &clkevt);
 	if (ret) {
 		clk_unprepare(t2_clk);
-		clk_disable_unprepare(tc->slow_clk);
+		if (bits != 32)
+			clk_disable_unprepare(tc->slow_clk);
 		return ret;
 	}
 
-	clockevents_config_and_register(&clkevt.clkevt, 32768, 1, 0xffff);
+	clockevents_config_and_register(&clkevt.clkevt, rate, 1, BIT(bits) - 1);
 
 	return ret;
 }
 
 #else /* !CONFIG_GENERIC_CLOCKEVENTS */
 
-static int __init setup_clkevents(struct atmel_tc *tc, int clk32k_divisor_idx)
+static int __init setup_clkevents(struct atmel_tc *tc, int divisor_idx)
 {
 	/* NOTHING */
 	return 0;
@@ -346,8 +351,6 @@ static void __init tcb_setup_single_chan(struct atmel_tc *tc, int mck_divisor_id
 	writel(ATMEL_TC_SYNC, tcaddr + ATMEL_TC_BCR);
 }
 
-static const u8 atmel_tcb_divisors[] = { 2, 8, 32, 128 };
-
 static struct atmel_tcb_config tcb_rm9200_config = {
 	.counter_width = 16,
 };
@@ -472,7 +475,7 @@ static int __init tcb_clksrc_init(struct device_node *node)
 		goto err_disable_t1;
 
 	/* channel 2:  periodic and oneshot timer support */
-	ret = setup_clkevents(&tc, ATMEL_TC_TIMER_CLOCK5);
+	ret = setup_clkevents(&tc, best_divisor_idx);
 	if (ret)
 		goto err_unregister_clksrc;
 
-- 
2.21.0


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

* [PATCH 7/8] clocksource/drivers/timer-atmel-tcb: allow selecting first divider
  2019-10-09 22:39 [PATCH 0/8] clocksource/drivers/timer-atmel-tcb: add sama5d2 support Alexandre Belloni
                   ` (5 preceding siblings ...)
  2019-10-09 22:40 ` [PATCH 6/8] clocksource/drivers/timer-atmel-tcb: stop using the 32kHz for clockevents Alexandre Belloni
@ 2019-10-09 22:40 ` Alexandre Belloni
  2019-10-09 22:40 ` [PATCH 8/8] clocksource/drivers/timer-atmel-tcb: add sama5d2 support Alexandre Belloni
  2019-10-10  8:26 ` [PATCH 0/8] " Sebastian Andrzej Siewior
  8 siblings, 0 replies; 11+ messages in thread
From: Alexandre Belloni @ 2019-10-09 22:40 UTC (permalink / raw)
  To: Daniel Lezcano
  Cc: Thomas Gleixner, Nicolas Ferre, Sebastian Andrzej Siewior,
	linux-arm-kernel, linux-kernel, devicetree, Alexandre Belloni

The divider selection algorithm never allowed to get index 0. It was also
continuing to look for dividers, trying to find the slow clock selection.
This is not necessary anymore.

Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
---
 drivers/clocksource/timer-atmel-tcb.c | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/clocksource/timer-atmel-tcb.c b/drivers/clocksource/timer-atmel-tcb.c
index 8fcd4d74c54b..ccb77b9cb489 100644
--- a/drivers/clocksource/timer-atmel-tcb.c
+++ b/drivers/clocksource/timer-atmel-tcb.c
@@ -432,10 +432,8 @@ static int __init tcb_clksrc_init(struct device_node *node)
 
 		tmp = rate / divisor;
 		pr_debug("TC: %u / %-3u [%d] --> %u\n", rate, divisor, i, tmp);
-		if (best_divisor_idx > 0) {
-			if (tmp < 5 * 1000 * 1000)
-				continue;
-		}
+		if ((best_divisor_idx >= 0) && (tmp < 5 * 1000 * 1000))
+			break;
 		divided_rate = tmp;
 		best_divisor_idx = i;
 	}
-- 
2.21.0


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

* [PATCH 8/8] clocksource/drivers/timer-atmel-tcb: add sama5d2 support
  2019-10-09 22:39 [PATCH 0/8] clocksource/drivers/timer-atmel-tcb: add sama5d2 support Alexandre Belloni
                   ` (6 preceding siblings ...)
  2019-10-09 22:40 ` [PATCH 7/8] clocksource/drivers/timer-atmel-tcb: allow selecting first divider Alexandre Belloni
@ 2019-10-09 22:40 ` Alexandre Belloni
  2019-10-10  8:26 ` [PATCH 0/8] " Sebastian Andrzej Siewior
  8 siblings, 0 replies; 11+ messages in thread
From: Alexandre Belloni @ 2019-10-09 22:40 UTC (permalink / raw)
  To: Daniel Lezcano
  Cc: Thomas Gleixner, Nicolas Ferre, Sebastian Andrzej Siewior,
	linux-arm-kernel, linux-kernel, devicetree, Alexandre Belloni

The first divisor for the sama5d2 is actually the gclk selector. Because
the currently remaining divisors are fitting the use case, currently ensure
it is skipped.

Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
---
 drivers/clocksource/timer-atmel-tcb.c | 11 ++++++++++-
 include/soc/at91/atmel_tcb.h          |  1 +
 2 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/drivers/clocksource/timer-atmel-tcb.c b/drivers/clocksource/timer-atmel-tcb.c
index ccb77b9cb489..e373b02d509a 100644
--- a/drivers/clocksource/timer-atmel-tcb.c
+++ b/drivers/clocksource/timer-atmel-tcb.c
@@ -359,9 +359,15 @@ static struct atmel_tcb_config tcb_sam9x5_config = {
 	.counter_width = 32,
 };
 
+static struct atmel_tcb_config tcb_sama5d2_config = {
+	.counter_width = 32,
+	.has_gclk = 1,
+};
+
 static const struct of_device_id atmel_tcb_of_match[] = {
 	{ .compatible = "atmel,at91rm9200-tcb", .data = &tcb_rm9200_config, },
 	{ .compatible = "atmel,at91sam9x5-tcb", .data = &tcb_sam9x5_config, },
+	{ .compatible = "atmel,sama5d2-tcb", .data = &tcb_sama5d2_config, },
 	{ /* sentinel */ }
 };
 
@@ -426,7 +432,10 @@ static int __init tcb_clksrc_init(struct device_node *node)
 
 	/* How fast will we be counting?  Pick something over 5 MHz.  */
 	rate = (u32) clk_get_rate(t0_clk);
-	for (i = 0; i < ARRAY_SIZE(atmel_tcb_divisors); i++) {
+	i = 0;
+	if (tc.tcb_config->has_gclk)
+		i = 1;
+	for (; i < ARRAY_SIZE(atmel_tcb_divisors); i++) {
 		unsigned divisor = atmel_tcb_divisors[i];
 		unsigned tmp;
 
diff --git a/include/soc/at91/atmel_tcb.h b/include/soc/at91/atmel_tcb.h
index c3c7200ce151..fbf5474f4484 100644
--- a/include/soc/at91/atmel_tcb.h
+++ b/include/soc/at91/atmel_tcb.h
@@ -39,6 +39,7 @@ struct clk;
  */
 struct atmel_tcb_config {
 	size_t	counter_width;
+	unsigned int has_gclk:1;
 };
 
 /**
-- 
2.21.0


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

* Re: [PATCH 0/8] clocksource/drivers/timer-atmel-tcb: add sama5d2 support
  2019-10-09 22:39 [PATCH 0/8] clocksource/drivers/timer-atmel-tcb: add sama5d2 support Alexandre Belloni
                   ` (7 preceding siblings ...)
  2019-10-09 22:40 ` [PATCH 8/8] clocksource/drivers/timer-atmel-tcb: add sama5d2 support Alexandre Belloni
@ 2019-10-10  8:26 ` Sebastian Andrzej Siewior
  8 siblings, 0 replies; 11+ messages in thread
From: Sebastian Andrzej Siewior @ 2019-10-10  8:26 UTC (permalink / raw)
  To: Alexandre Belloni
  Cc: Daniel Lezcano, Thomas Gleixner, Nicolas Ferre, linux-arm-kernel,
	linux-kernel, devicetree

On 2019-10-10 00:39:58 [+0200], Alexandre Belloni wrote:
> This series mainly adds sama5d2 support where we need to avoid using
> clock index 0 because that clock is never enabled by the driver.
> 
> There is also a rework of the 32khz clock handling so it is not used for
> clockevents on 32 bit counter because the increased rate improves the
> resolution and doesn't have any drawback with that counter width. This
> replaces a patch that has been carried in the linux-rt tree for a while.

Thank you for doing this!

Sebastian

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

* Re: [PATCH 1/8] dt-bindings: mfd: atmel-tcb: convert bindings to json-schema
  2019-10-09 22:39 ` [PATCH 1/8] dt-bindings: mfd: atmel-tcb: convert bindings to json-schema Alexandre Belloni
@ 2019-10-15 22:39   ` Rob Herring
  0 siblings, 0 replies; 11+ messages in thread
From: Rob Herring @ 2019-10-15 22:39 UTC (permalink / raw)
  To: Alexandre Belloni
  Cc: Daniel Lezcano, Thomas Gleixner, Nicolas Ferre,
	Sebastian Andrzej Siewior, linux-arm-kernel, linux-kernel,
	devicetree

On Thu, Oct 10, 2019 at 12:39:59AM +0200, Alexandre Belloni wrote:
> Convert Atmel Timer Counter Blocks bindings to DT schema format using
> json-schema.
> 
> Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
> ---
> Cc: Rob Herring <robh+dt@kernel.org>
> 
>  .../bindings/mfd/atmel,at91rm9200-tcb.yaml    | 89 +++++++++++++++++++
>  .../devicetree/bindings/mfd/atmel-tcb.txt     | 56 ------------
>  2 files changed, 89 insertions(+), 56 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/mfd/atmel,at91rm9200-tcb.yaml
>  delete mode 100644 Documentation/devicetree/bindings/mfd/atmel-tcb.txt
> 
> diff --git a/Documentation/devicetree/bindings/mfd/atmel,at91rm9200-tcb.yaml b/Documentation/devicetree/bindings/mfd/atmel,at91rm9200-tcb.yaml
> new file mode 100644
> index 000000000000..4d9247fc0593
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/mfd/atmel,at91rm9200-tcb.yaml
> @@ -0,0 +1,89 @@
> +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: "http://devicetree.org/schemas/mfd/atmel,at91rm9200-tcb.yaml#"
> +$schema: "http://devicetree.org/meta-schemas/core.yaml#"
> +
> +title: Atmel Timer Counter Block
> +
> +maintainers:
> +  - Alexandre Belloni <alexandre.belloni@bootlin.com>
> +
> +description: |
> +  The Atmel (now Microchip) SoCs have timers named Timer Counter Block. Each
> +  timer has three channels with two counters each.
> +
> +properties:
> +  compatible:
> +    items:
> +      - enum:
> +          - atmel,at91rm9200-tcb
> +          - atmel,at91sam9x5-tcb
> +      - const: simple-mfd
> +      - const: syscon
> +
> +  reg:
> +    maxItems: 1
> +
> +  interrupts:
> +    description:
> +      List of interrupts. One interrupt per TCB channel if available or one
> +      interrupt for the TC block
> +    minItems: 1
> +    maxItems: 3
> +
> +  clock-names:
> +    description:
> +      List of clock names. Always includes t0_clk and slow clk. Also includes
> +      t1_clk and t2_clk if a clock per channel is available.
> +    minItems: 2
> +    maxItems: 4
> +    items:
> +      enum:
> +        - t0_clk
> +        - t1_clk
> +        - t2_clk
> +        - slow_clk
> +
> +  clocks:
> +    minItems: 2
> +    maxItems: 4
> +
> +  '#address-cells':
> +    const: 1
> +
> +  '#size-cells':
> +    const: 0

What happened to the child nodes?

> +
> +required:
> +  - compatible
> +  - reg
> +  - interrupts
> +  - clocks
> +  - clock-names
> +  - '#address-cells'
> +  - '#size-cells'
> +
> +examples:
> +  - |
> +    /* One interrupt per TC block: */
> +        tcb0: timer@fff7c000 {
> +                compatible = "atmel,at91rm9200-tcb", "simple-mfd", "syscon";
> +                #address-cells = <1>;
> +                #size-cells = <0>;
> +                reg = <0xfff7c000 0x100>;
> +                interrupts = <18 4>;
> +                clocks = <&tcb0_clk>, <&clk32k>;
> +                clock-names = "t0_clk", "slow_clk";
> +        };
> +
> +    /* One interrupt per TC channel in a TC block: */
> +        tcb1: timer@fffdc000 {
> +                compatible = "atmel,at91rm9200-tcb", "simple-mfd", "syscon";
> +                #address-cells = <1>;
> +                #size-cells = <0>;
> +                reg = <0xfffdc000 0x100>;
> +                interrupts = <26 4>, <27 4>, <28 4>;
> +                clocks = <&tcb1_clk>, <&clk32k>;
> +                clock-names = "t0_clk", "slow_clk";
> +        };
> diff --git a/Documentation/devicetree/bindings/mfd/atmel-tcb.txt b/Documentation/devicetree/bindings/mfd/atmel-tcb.txt
> deleted file mode 100644
> index c4a83e364cb6..000000000000
> --- a/Documentation/devicetree/bindings/mfd/atmel-tcb.txt
> +++ /dev/null
> @@ -1,56 +0,0 @@
> -* Device tree bindings for Atmel Timer Counter Blocks
> -- compatible: Should be "atmel,<chip>-tcb", "simple-mfd", "syscon".
> -  <chip> can be "at91rm9200" or "at91sam9x5"
> -- reg: Should contain registers location and length
> -- #address-cells: has to be 1
> -- #size-cells: has to be 0
> -- interrupts: Should contain all interrupts for the TC block
> -  Note that you can specify several interrupt cells if the TC
> -  block has one interrupt per channel.
> -- clock-names: tuple listing input clock names.
> -	Required elements: "t0_clk", "slow_clk"
> -	Optional elements: "t1_clk", "t2_clk"
> -- clocks: phandles to input clocks.
> -
> -The TCB can expose multiple subdevices:
> - * a timer
> -   - compatible: Should be "atmel,tcb-timer"
> -   - reg: Should contain the TCB channels to be used. If the
> -     counter width is 16 bits (at91rm9200-tcb), two consecutive
> -     channels are needed. Else, only one channel will be used.
> -
> -Examples:
> -
> -One interrupt per TC block:
> -	tcb0: timer@fff7c000 {
> -		compatible = "atmel,at91rm9200-tcb", "simple-mfd", "syscon";
> -		#address-cells = <1>;
> -		#size-cells = <0>;
> -		reg = <0xfff7c000 0x100>;
> -		interrupts = <18 4>;
> -		clocks = <&tcb0_clk>, <&clk32k>;
> -		clock-names = "t0_clk", "slow_clk";
> -
> -		timer@0 {
> -			compatible = "atmel,tcb-timer";
> -			reg = <0>, <1>;
> -		};
> -
> -		timer@2 {
> -			compatible = "atmel,tcb-timer";
> -			reg = <2>;
> -		};
> -	};
> -
> -One interrupt per TC channel in a TC block:
> -	tcb1: timer@fffdc000 {
> -		compatible = "atmel,at91rm9200-tcb", "simple-mfd", "syscon";
> -		#address-cells = <1>;
> -		#size-cells = <0>;
> -		reg = <0xfffdc000 0x100>;
> -		interrupts = <26 4>, <27 4>, <28 4>;
> -		clocks = <&tcb1_clk>, <&clk32k>;
> -		clock-names = "t0_clk", "slow_clk";
> -	};
> -
> -
> -- 
> 2.21.0
> 

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

end of thread, other threads:[~2019-10-15 22:39 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-10-09 22:39 [PATCH 0/8] clocksource/drivers/timer-atmel-tcb: add sama5d2 support Alexandre Belloni
2019-10-09 22:39 ` [PATCH 1/8] dt-bindings: mfd: atmel-tcb: convert bindings to json-schema Alexandre Belloni
2019-10-15 22:39   ` Rob Herring
2019-10-09 22:40 ` [PATCH 2/8] dt-bindings: mfd: atmel,at91rm9200-tcb: add sama5d2 compatible Alexandre Belloni
2019-10-09 22:40 ` [PATCH 3/8] ARM: dts: at91: sama5d2: add TCB GCLK Alexandre Belloni
2019-10-09 22:40 ` [PATCH 4/8] clocksource/drivers/timer-atmel-tcb: rework 32khz clock selection Alexandre Belloni
2019-10-09 22:40 ` [PATCH 5/8] clocksource/drivers/timer-atmel-tcb: fill tcb_config Alexandre Belloni
2019-10-09 22:40 ` [PATCH 6/8] clocksource/drivers/timer-atmel-tcb: stop using the 32kHz for clockevents Alexandre Belloni
2019-10-09 22:40 ` [PATCH 7/8] clocksource/drivers/timer-atmel-tcb: allow selecting first divider Alexandre Belloni
2019-10-09 22:40 ` [PATCH 8/8] clocksource/drivers/timer-atmel-tcb: add sama5d2 support Alexandre Belloni
2019-10-10  8:26 ` [PATCH 0/8] " Sebastian Andrzej Siewior

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).