All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/8] clocksource: Generalize Faraday timer
@ 2017-05-17 14:05 ` Linus Walleij
  0 siblings, 0 replies; 40+ messages in thread
From: Linus Walleij @ 2017-05-17 14:05 UTC (permalink / raw)
  To: Daniel Lezcano, Thomas Gleixner, Joel Stanley, Jonas Jensen
  Cc: Janos Laube, Paulius Zaleckas, linux-arm-kernel, Hans Ulli Kroll,
	Florian Fainelli, linux-kernel, Linus Walleij

It turns out that the Moxa is using a Faraday IP timer named
FTTMR010. This is also what Aspeed's derivative is based on.

This series attempts to merge these two drivers into one to
get lesser code to maintain. Also it incidentally adds a
sched_clock() implementation to the Moxa and Aspeed, which
is nice.

The patches can also be grabbed from here:
https://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-nomadik.git/commit/?h=fttmr010

Future ideas include supporting the optional EXTCLK
(32kHz clock) and delay timers. This will then get available
on all three supported platforms = big win.

The patches can be applied as soon as Jonas Jensen and Joel
Stanley says they work for them.

I have chosen to work on this body of code (rather than the
Moxart code) as it is derived from code originally posted
by Faraday themselves here:
https://lwn.net/Articles/447919/

I hope we can get this to work!

Linus Walleij (8):
  clocksource/drivers/fttmr010: Fix the clock handling
  clocksource/drivers/fttmr010: Merge FTTMR010 DT bindings
  clocksource/drivers/fttmr010: Drop Gemini specifics
  clocksource/drivers/fttmr010: Use state container
  clocksource/drivers/fttmr010: Switch to use bitops
  clocksource/drivers/fttmr010: Switch to use TIMER2 src
  clocksource/drivers/fttmr010: Merge Moxa into FTTMR010
  ARM: dts: augment Moxa and Aspeed DTS for FTTMR010

 .../devicetree/bindings/timer/faraday,fttmr010.txt |   4 +-
 .../bindings/timer/moxa,moxart-timer.txt           |  19 --
 arch/arm/boot/dts/aspeed-g4.dtsi                   |   7 +-
 arch/arm/boot/dts/aspeed-g5.dtsi                   |   6 +-
 arch/arm/boot/dts/moxart.dtsi                      |   3 +-
 arch/arm/mach-aspeed/Kconfig                       |   2 +-
 arch/arm/mach-moxart/Kconfig                       |   2 +-
 drivers/clocksource/Kconfig                        |   7 -
 drivers/clocksource/Makefile                       |   1 -
 drivers/clocksource/moxart_timer.c                 | 256 --------------
 drivers/clocksource/timer-fttmr010.c               | 377 +++++++++++----------
 11 files changed, 214 insertions(+), 470 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/timer/moxa,moxart-timer.txt
 delete mode 100644 drivers/clocksource/moxart_timer.c

-- 
2.9.3

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

* [PATCH 0/8] clocksource: Generalize Faraday timer
@ 2017-05-17 14:05 ` Linus Walleij
  0 siblings, 0 replies; 40+ messages in thread
From: Linus Walleij @ 2017-05-17 14:05 UTC (permalink / raw)
  To: linux-arm-kernel

It turns out that the Moxa is using a Faraday IP timer named
FTTMR010. This is also what Aspeed's derivative is based on.

This series attempts to merge these two drivers into one to
get lesser code to maintain. Also it incidentally adds a
sched_clock() implementation to the Moxa and Aspeed, which
is nice.

The patches can also be grabbed from here:
https://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-nomadik.git/commit/?h=fttmr010

Future ideas include supporting the optional EXTCLK
(32kHz clock) and delay timers. This will then get available
on all three supported platforms = big win.

The patches can be applied as soon as Jonas Jensen and Joel
Stanley says they work for them.

I have chosen to work on this body of code (rather than the
Moxart code) as it is derived from code originally posted
by Faraday themselves here:
https://lwn.net/Articles/447919/

I hope we can get this to work!

Linus Walleij (8):
  clocksource/drivers/fttmr010: Fix the clock handling
  clocksource/drivers/fttmr010: Merge FTTMR010 DT bindings
  clocksource/drivers/fttmr010: Drop Gemini specifics
  clocksource/drivers/fttmr010: Use state container
  clocksource/drivers/fttmr010: Switch to use bitops
  clocksource/drivers/fttmr010: Switch to use TIMER2 src
  clocksource/drivers/fttmr010: Merge Moxa into FTTMR010
  ARM: dts: augment Moxa and Aspeed DTS for FTTMR010

 .../devicetree/bindings/timer/faraday,fttmr010.txt |   4 +-
 .../bindings/timer/moxa,moxart-timer.txt           |  19 --
 arch/arm/boot/dts/aspeed-g4.dtsi                   |   7 +-
 arch/arm/boot/dts/aspeed-g5.dtsi                   |   6 +-
 arch/arm/boot/dts/moxart.dtsi                      |   3 +-
 arch/arm/mach-aspeed/Kconfig                       |   2 +-
 arch/arm/mach-moxart/Kconfig                       |   2 +-
 drivers/clocksource/Kconfig                        |   7 -
 drivers/clocksource/Makefile                       |   1 -
 drivers/clocksource/moxart_timer.c                 | 256 --------------
 drivers/clocksource/timer-fttmr010.c               | 377 +++++++++++----------
 11 files changed, 214 insertions(+), 470 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/timer/moxa,moxart-timer.txt
 delete mode 100644 drivers/clocksource/moxart_timer.c

-- 
2.9.3

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

* [PATCH 1/8] clocksource/drivers/fttmr010: Fix the clock handling
  2017-05-17 14:05 ` Linus Walleij
@ 2017-05-17 14:05   ` Linus Walleij
  -1 siblings, 0 replies; 40+ messages in thread
From: Linus Walleij @ 2017-05-17 14:05 UTC (permalink / raw)
  To: Daniel Lezcano, Thomas Gleixner, Joel Stanley, Jonas Jensen
  Cc: Janos Laube, Paulius Zaleckas, linux-arm-kernel, Hans Ulli Kroll,
	Florian Fainelli, linux-kernel, Linus Walleij

We need to also prepare and enable the clock we are using to get
the right reference count and avoid it being shut off.

Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
 drivers/clocksource/timer-fttmr010.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/clocksource/timer-fttmr010.c b/drivers/clocksource/timer-fttmr010.c
index b4a6f1e4bc54..58ce017e4a65 100644
--- a/drivers/clocksource/timer-fttmr010.c
+++ b/drivers/clocksource/timer-fttmr010.c
@@ -238,12 +238,18 @@ static int __init fttmr010_timer_of_init(struct device_node *np)
 	 * and using EXTCLK is not supported in the driver.
 	 */
 	struct clk *clk;
+	int ret;
 
 	clk = of_clk_get_by_name(np, "PCLK");
 	if (IS_ERR(clk)) {
-		pr_err("could not get PCLK");
+		pr_err("could not get PCLK\n");
 		return PTR_ERR(clk);
 	}
+	ret = clk_prepare_enable(clk);
+	if (ret) {
+		pr_err("failed to enable PCLK\n");
+		return ret;
+	}
 	tick_rate = clk_get_rate(clk);
 
 	return fttmr010_timer_common_init(np);
-- 
2.9.3

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

* [PATCH 1/8] clocksource/drivers/fttmr010: Fix the clock handling
@ 2017-05-17 14:05   ` Linus Walleij
  0 siblings, 0 replies; 40+ messages in thread
From: Linus Walleij @ 2017-05-17 14:05 UTC (permalink / raw)
  To: linux-arm-kernel

We need to also prepare and enable the clock we are using to get
the right reference count and avoid it being shut off.

Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
 drivers/clocksource/timer-fttmr010.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/clocksource/timer-fttmr010.c b/drivers/clocksource/timer-fttmr010.c
index b4a6f1e4bc54..58ce017e4a65 100644
--- a/drivers/clocksource/timer-fttmr010.c
+++ b/drivers/clocksource/timer-fttmr010.c
@@ -238,12 +238,18 @@ static int __init fttmr010_timer_of_init(struct device_node *np)
 	 * and using EXTCLK is not supported in the driver.
 	 */
 	struct clk *clk;
+	int ret;
 
 	clk = of_clk_get_by_name(np, "PCLK");
 	if (IS_ERR(clk)) {
-		pr_err("could not get PCLK");
+		pr_err("could not get PCLK\n");
 		return PTR_ERR(clk);
 	}
+	ret = clk_prepare_enable(clk);
+	if (ret) {
+		pr_err("failed to enable PCLK\n");
+		return ret;
+	}
 	tick_rate = clk_get_rate(clk);
 
 	return fttmr010_timer_common_init(np);
-- 
2.9.3

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

* [PATCH 2/8] clocksource/drivers/fttmr010: Merge FTTMR010 DT bindings
@ 2017-05-17 14:05   ` Linus Walleij
  0 siblings, 0 replies; 40+ messages in thread
From: Linus Walleij @ 2017-05-17 14:05 UTC (permalink / raw)
  To: Daniel Lezcano, Thomas Gleixner, Joel Stanley, Jonas Jensen
  Cc: Janos Laube, Paulius Zaleckas, linux-arm-kernel, Hans Ulli Kroll,
	Florian Fainelli, linux-kernel, Linus Walleij, devicetree,
	Rob Herring

This merges the Moxa and FTTMR010 device tree bindings into the
Faraday binding document to avoid confusion.

The FTTMR010 is the IP block used by these SoCs, in vanilla
or modified variant.

The Aspeed variant is modified such that it is no longer fully
register-compatible with FTTMR010 so for this reason it is not
listed with two compatible strings, instead just one.

Cc: devicetree@vger.kernel.org
Cc: Rob Herring <robh+dt@kernel.org>
Cc: Joel Stanley <joel@jms.id.au>
Cc: Jonas Jensen <jonas.jensen@gmail.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
 .../devicetree/bindings/timer/faraday,fttmr010.txt    |  4 +++-
 .../devicetree/bindings/timer/moxa,moxart-timer.txt   | 19 -------------------
 2 files changed, 3 insertions(+), 20 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/timer/moxa,moxart-timer.txt

diff --git a/Documentation/devicetree/bindings/timer/faraday,fttmr010.txt b/Documentation/devicetree/bindings/timer/faraday,fttmr010.txt
index b73ca6cd07f8..6e18bd662ccb 100644
--- a/Documentation/devicetree/bindings/timer/faraday,fttmr010.txt
+++ b/Documentation/devicetree/bindings/timer/faraday,fttmr010.txt
@@ -7,7 +7,9 @@ Required properties:
 
 - compatible : Must be one of
   "faraday,fttmr010"
-  "cortina,gemini-timer"
+  "cortina,gemini-timer", "faraday,fttmr010"
+  "moxa,moxart-timer", "faraday,fttmr010"
+  "aspeed,ast2400-timer"
 - reg : Should contain registers location and length
 - interrupts : Should contain the three timer interrupts usually with
   flags for falling edge
diff --git a/Documentation/devicetree/bindings/timer/moxa,moxart-timer.txt b/Documentation/devicetree/bindings/timer/moxa,moxart-timer.txt
deleted file mode 100644
index e207c11630af..000000000000
--- a/Documentation/devicetree/bindings/timer/moxa,moxart-timer.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-MOXA ART timer
-
-Required properties:
-
-- compatible : Must be one of:
- 	- "moxa,moxart-timer"
- 	- "aspeed,ast2400-timer"
-- reg : Should contain registers location and length
-- interrupts : Should contain the timer interrupt number
-- clocks : Should contain phandle for the clock that drives the counter
-
-Example:
-
-	timer: timer@98400000 {
-		compatible = "moxa,moxart-timer";
-		reg = <0x98400000 0x42>;
-		interrupts = <19 1>;
-		clocks = <&coreclk>;
-	};
-- 
2.9.3

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

* [PATCH 2/8] clocksource/drivers/fttmr010: Merge FTTMR010 DT bindings
@ 2017-05-17 14:05   ` Linus Walleij
  0 siblings, 0 replies; 40+ messages in thread
From: Linus Walleij @ 2017-05-17 14:05 UTC (permalink / raw)
  To: Daniel Lezcano, Thomas Gleixner, Joel Stanley, Jonas Jensen
  Cc: Janos Laube, Paulius Zaleckas,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	Hans Ulli Kroll, Florian Fainelli,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, Linus Walleij,
	devicetree-u79uwXL29TY76Z2rM5mHXA, Rob Herring

This merges the Moxa and FTTMR010 device tree bindings into the
Faraday binding document to avoid confusion.

The FTTMR010 is the IP block used by these SoCs, in vanilla
or modified variant.

The Aspeed variant is modified such that it is no longer fully
register-compatible with FTTMR010 so for this reason it is not
listed with two compatible strings, instead just one.

Cc: devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Cc: Rob Herring <robh+dt-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
Cc: Joel Stanley <joel-U3u1mxZcP9KHXe+LvDLADg@public.gmane.org>
Cc: Jonas Jensen <jonas.jensen-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Signed-off-by: Linus Walleij <linus.walleij-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
---
 .../devicetree/bindings/timer/faraday,fttmr010.txt    |  4 +++-
 .../devicetree/bindings/timer/moxa,moxart-timer.txt   | 19 -------------------
 2 files changed, 3 insertions(+), 20 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/timer/moxa,moxart-timer.txt

diff --git a/Documentation/devicetree/bindings/timer/faraday,fttmr010.txt b/Documentation/devicetree/bindings/timer/faraday,fttmr010.txt
index b73ca6cd07f8..6e18bd662ccb 100644
--- a/Documentation/devicetree/bindings/timer/faraday,fttmr010.txt
+++ b/Documentation/devicetree/bindings/timer/faraday,fttmr010.txt
@@ -7,7 +7,9 @@ Required properties:
 
 - compatible : Must be one of
   "faraday,fttmr010"
-  "cortina,gemini-timer"
+  "cortina,gemini-timer", "faraday,fttmr010"
+  "moxa,moxart-timer", "faraday,fttmr010"
+  "aspeed,ast2400-timer"
 - reg : Should contain registers location and length
 - interrupts : Should contain the three timer interrupts usually with
   flags for falling edge
diff --git a/Documentation/devicetree/bindings/timer/moxa,moxart-timer.txt b/Documentation/devicetree/bindings/timer/moxa,moxart-timer.txt
deleted file mode 100644
index e207c11630af..000000000000
--- a/Documentation/devicetree/bindings/timer/moxa,moxart-timer.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-MOXA ART timer
-
-Required properties:
-
-- compatible : Must be one of:
- 	- "moxa,moxart-timer"
- 	- "aspeed,ast2400-timer"
-- reg : Should contain registers location and length
-- interrupts : Should contain the timer interrupt number
-- clocks : Should contain phandle for the clock that drives the counter
-
-Example:
-
-	timer: timer@98400000 {
-		compatible = "moxa,moxart-timer";
-		reg = <0x98400000 0x42>;
-		interrupts = <19 1>;
-		clocks = <&coreclk>;
-	};
-- 
2.9.3

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [PATCH 2/8] clocksource/drivers/fttmr010: Merge FTTMR010 DT bindings
@ 2017-05-17 14:05   ` Linus Walleij
  0 siblings, 0 replies; 40+ messages in thread
From: Linus Walleij @ 2017-05-17 14:05 UTC (permalink / raw)
  To: linux-arm-kernel

This merges the Moxa and FTTMR010 device tree bindings into the
Faraday binding document to avoid confusion.

The FTTMR010 is the IP block used by these SoCs, in vanilla
or modified variant.

The Aspeed variant is modified such that it is no longer fully
register-compatible with FTTMR010 so for this reason it is not
listed with two compatible strings, instead just one.

Cc: devicetree at vger.kernel.org
Cc: Rob Herring <robh+dt@kernel.org>
Cc: Joel Stanley <joel@jms.id.au>
Cc: Jonas Jensen <jonas.jensen@gmail.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
 .../devicetree/bindings/timer/faraday,fttmr010.txt    |  4 +++-
 .../devicetree/bindings/timer/moxa,moxart-timer.txt   | 19 -------------------
 2 files changed, 3 insertions(+), 20 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/timer/moxa,moxart-timer.txt

diff --git a/Documentation/devicetree/bindings/timer/faraday,fttmr010.txt b/Documentation/devicetree/bindings/timer/faraday,fttmr010.txt
index b73ca6cd07f8..6e18bd662ccb 100644
--- a/Documentation/devicetree/bindings/timer/faraday,fttmr010.txt
+++ b/Documentation/devicetree/bindings/timer/faraday,fttmr010.txt
@@ -7,7 +7,9 @@ Required properties:
 
 - compatible : Must be one of
   "faraday,fttmr010"
-  "cortina,gemini-timer"
+  "cortina,gemini-timer", "faraday,fttmr010"
+  "moxa,moxart-timer", "faraday,fttmr010"
+  "aspeed,ast2400-timer"
 - reg : Should contain registers location and length
 - interrupts : Should contain the three timer interrupts usually with
   flags for falling edge
diff --git a/Documentation/devicetree/bindings/timer/moxa,moxart-timer.txt b/Documentation/devicetree/bindings/timer/moxa,moxart-timer.txt
deleted file mode 100644
index e207c11630af..000000000000
--- a/Documentation/devicetree/bindings/timer/moxa,moxart-timer.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-MOXA ART timer
-
-Required properties:
-
-- compatible : Must be one of:
- 	- "moxa,moxart-timer"
- 	- "aspeed,ast2400-timer"
-- reg : Should contain registers location and length
-- interrupts : Should contain the timer interrupt number
-- clocks : Should contain phandle for the clock that drives the counter
-
-Example:
-
-	timer: timer at 98400000 {
-		compatible = "moxa,moxart-timer";
-		reg = <0x98400000 0x42>;
-		interrupts = <19 1>;
-		clocks = <&coreclk>;
-	};
-- 
2.9.3

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

* [PATCH 3/8] clocksource/drivers/fttmr010: Drop Gemini specifics
  2017-05-17 14:05 ` Linus Walleij
@ 2017-05-17 14:05   ` Linus Walleij
  -1 siblings, 0 replies; 40+ messages in thread
From: Linus Walleij @ 2017-05-17 14:05 UTC (permalink / raw)
  To: Daniel Lezcano, Thomas Gleixner, Joel Stanley, Jonas Jensen
  Cc: Janos Laube, Paulius Zaleckas, linux-arm-kernel, Hans Ulli Kroll,
	Florian Fainelli, linux-kernel, Linus Walleij

The Gemini now has a proper clock driver and a proper PCLK
assigned in its device tree. Drop the Gemini-specific hacks
to look up the system speed and rely on the clock framework
like everyone else.

Cc: Joel Stanley <joel@jms.id.au>
Cc: Jonas Jensen <jonas.jensen@gmail.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
 drivers/clocksource/timer-fttmr010.c | 103 ++++++++---------------------------
 1 file changed, 22 insertions(+), 81 deletions(-)

diff --git a/drivers/clocksource/timer-fttmr010.c b/drivers/clocksource/timer-fttmr010.c
index 58ce017e4a65..db097db346e3 100644
--- a/drivers/clocksource/timer-fttmr010.c
+++ b/drivers/clocksource/timer-fttmr010.c
@@ -11,8 +11,6 @@
 #include <linux/of.h>
 #include <linux/of_address.h>
 #include <linux/of_irq.h>
-#include <linux/mfd/syscon.h>
-#include <linux/regmap.h>
 #include <linux/clockchips.h>
 #include <linux/clocksource.h>
 #include <linux/sched_clock.h>
@@ -179,9 +177,28 @@ static struct irqaction fttmr010_timer_irq = {
 	.handler	= fttmr010_timer_interrupt,
 };
 
-static int __init fttmr010_timer_common_init(struct device_node *np)
+static int __init fttmr010_timer_init(struct device_node *np)
 {
 	int irq;
+	struct clk *clk;
+	int ret;
+
+	/*
+	 * These implementations require a clock reference.
+	 * FIXME: we currently only support clocking using PCLK
+	 * and using EXTCLK is not supported in the driver.
+	 */
+	clk = of_clk_get_by_name(np, "PCLK");
+	if (IS_ERR(clk)) {
+		pr_err("could not get PCLK\n");
+		return PTR_ERR(clk);
+	}
+	ret = clk_prepare_enable(clk);
+	if (ret) {
+		pr_err("failed to enable PCLK\n");
+		return ret;
+	}
+	tick_rate = clk_get_rate(clk);
 
 	base = of_iomap(np, 0);
 	if (!base) {
@@ -229,81 +246,5 @@ static int __init fttmr010_timer_common_init(struct device_node *np)
 
 	return 0;
 }
-
-static int __init fttmr010_timer_of_init(struct device_node *np)
-{
-	/*
-	 * These implementations require a clock reference.
-	 * FIXME: we currently only support clocking using PCLK
-	 * and using EXTCLK is not supported in the driver.
-	 */
-	struct clk *clk;
-	int ret;
-
-	clk = of_clk_get_by_name(np, "PCLK");
-	if (IS_ERR(clk)) {
-		pr_err("could not get PCLK\n");
-		return PTR_ERR(clk);
-	}
-	ret = clk_prepare_enable(clk);
-	if (ret) {
-		pr_err("failed to enable PCLK\n");
-		return ret;
-	}
-	tick_rate = clk_get_rate(clk);
-
-	return fttmr010_timer_common_init(np);
-}
-CLOCKSOURCE_OF_DECLARE(fttmr010, "faraday,fttmr010", fttmr010_timer_of_init);
-
-/*
- * Gemini-specific: relevant registers in the global syscon
- */
-#define GLOBAL_STATUS		0x04
-#define CPU_AHB_RATIO_MASK	(0x3 << 18)
-#define CPU_AHB_1_1		(0x0 << 18)
-#define CPU_AHB_3_2		(0x1 << 18)
-#define CPU_AHB_24_13		(0x2 << 18)
-#define CPU_AHB_2_1		(0x3 << 18)
-#define REG_TO_AHB_SPEED(reg)	((((reg) >> 15) & 0x7) * 10 + 130)
-
-static int __init gemini_timer_of_init(struct device_node *np)
-{
-	static struct regmap *map;
-	int ret;
-	u32 val;
-
-	map = syscon_regmap_lookup_by_phandle(np, "syscon");
-	if (IS_ERR(map)) {
-		pr_err("Can't get regmap for syscon handle\n");
-		return -ENODEV;
-	}
-	ret = regmap_read(map, GLOBAL_STATUS, &val);
-	if (ret) {
-		pr_err("Can't read syscon status register\n");
-		return -ENXIO;
-	}
-
-	tick_rate = REG_TO_AHB_SPEED(val) * 1000000;
-	pr_info("Bus: %dMHz ", tick_rate / 1000000);
-
-	tick_rate /= 6;		/* APB bus run AHB*(1/6) */
-
-	switch (val & CPU_AHB_RATIO_MASK) {
-	case CPU_AHB_1_1:
-		pr_cont("(1/1)\n");
-		break;
-	case CPU_AHB_3_2:
-		pr_cont("(3/2)\n");
-		break;
-	case CPU_AHB_24_13:
-		pr_cont("(24/13)\n");
-		break;
-	case CPU_AHB_2_1:
-		pr_cont("(2/1)\n");
-		break;
-	}
-
-	return fttmr010_timer_common_init(np);
-}
-CLOCKSOURCE_OF_DECLARE(gemini, "cortina,gemini-timer", gemini_timer_of_init);
+CLOCKSOURCE_OF_DECLARE(fttmr010, "faraday,fttmr010", fttmr010_timer_init);
+CLOCKSOURCE_OF_DECLARE(gemini, "cortina,gemini-timer", fttmr010_timer_init);
-- 
2.9.3

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

* [PATCH 3/8] clocksource/drivers/fttmr010: Drop Gemini specifics
@ 2017-05-17 14:05   ` Linus Walleij
  0 siblings, 0 replies; 40+ messages in thread
From: Linus Walleij @ 2017-05-17 14:05 UTC (permalink / raw)
  To: linux-arm-kernel

The Gemini now has a proper clock driver and a proper PCLK
assigned in its device tree. Drop the Gemini-specific hacks
to look up the system speed and rely on the clock framework
like everyone else.

Cc: Joel Stanley <joel@jms.id.au>
Cc: Jonas Jensen <jonas.jensen@gmail.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
 drivers/clocksource/timer-fttmr010.c | 103 ++++++++---------------------------
 1 file changed, 22 insertions(+), 81 deletions(-)

diff --git a/drivers/clocksource/timer-fttmr010.c b/drivers/clocksource/timer-fttmr010.c
index 58ce017e4a65..db097db346e3 100644
--- a/drivers/clocksource/timer-fttmr010.c
+++ b/drivers/clocksource/timer-fttmr010.c
@@ -11,8 +11,6 @@
 #include <linux/of.h>
 #include <linux/of_address.h>
 #include <linux/of_irq.h>
-#include <linux/mfd/syscon.h>
-#include <linux/regmap.h>
 #include <linux/clockchips.h>
 #include <linux/clocksource.h>
 #include <linux/sched_clock.h>
@@ -179,9 +177,28 @@ static struct irqaction fttmr010_timer_irq = {
 	.handler	= fttmr010_timer_interrupt,
 };
 
-static int __init fttmr010_timer_common_init(struct device_node *np)
+static int __init fttmr010_timer_init(struct device_node *np)
 {
 	int irq;
+	struct clk *clk;
+	int ret;
+
+	/*
+	 * These implementations require a clock reference.
+	 * FIXME: we currently only support clocking using PCLK
+	 * and using EXTCLK is not supported in the driver.
+	 */
+	clk = of_clk_get_by_name(np, "PCLK");
+	if (IS_ERR(clk)) {
+		pr_err("could not get PCLK\n");
+		return PTR_ERR(clk);
+	}
+	ret = clk_prepare_enable(clk);
+	if (ret) {
+		pr_err("failed to enable PCLK\n");
+		return ret;
+	}
+	tick_rate = clk_get_rate(clk);
 
 	base = of_iomap(np, 0);
 	if (!base) {
@@ -229,81 +246,5 @@ static int __init fttmr010_timer_common_init(struct device_node *np)
 
 	return 0;
 }
-
-static int __init fttmr010_timer_of_init(struct device_node *np)
-{
-	/*
-	 * These implementations require a clock reference.
-	 * FIXME: we currently only support clocking using PCLK
-	 * and using EXTCLK is not supported in the driver.
-	 */
-	struct clk *clk;
-	int ret;
-
-	clk = of_clk_get_by_name(np, "PCLK");
-	if (IS_ERR(clk)) {
-		pr_err("could not get PCLK\n");
-		return PTR_ERR(clk);
-	}
-	ret = clk_prepare_enable(clk);
-	if (ret) {
-		pr_err("failed to enable PCLK\n");
-		return ret;
-	}
-	tick_rate = clk_get_rate(clk);
-
-	return fttmr010_timer_common_init(np);
-}
-CLOCKSOURCE_OF_DECLARE(fttmr010, "faraday,fttmr010", fttmr010_timer_of_init);
-
-/*
- * Gemini-specific: relevant registers in the global syscon
- */
-#define GLOBAL_STATUS		0x04
-#define CPU_AHB_RATIO_MASK	(0x3 << 18)
-#define CPU_AHB_1_1		(0x0 << 18)
-#define CPU_AHB_3_2		(0x1 << 18)
-#define CPU_AHB_24_13		(0x2 << 18)
-#define CPU_AHB_2_1		(0x3 << 18)
-#define REG_TO_AHB_SPEED(reg)	((((reg) >> 15) & 0x7) * 10 + 130)
-
-static int __init gemini_timer_of_init(struct device_node *np)
-{
-	static struct regmap *map;
-	int ret;
-	u32 val;
-
-	map = syscon_regmap_lookup_by_phandle(np, "syscon");
-	if (IS_ERR(map)) {
-		pr_err("Can't get regmap for syscon handle\n");
-		return -ENODEV;
-	}
-	ret = regmap_read(map, GLOBAL_STATUS, &val);
-	if (ret) {
-		pr_err("Can't read syscon status register\n");
-		return -ENXIO;
-	}
-
-	tick_rate = REG_TO_AHB_SPEED(val) * 1000000;
-	pr_info("Bus: %dMHz ", tick_rate / 1000000);
-
-	tick_rate /= 6;		/* APB bus run AHB*(1/6) */
-
-	switch (val & CPU_AHB_RATIO_MASK) {
-	case CPU_AHB_1_1:
-		pr_cont("(1/1)\n");
-		break;
-	case CPU_AHB_3_2:
-		pr_cont("(3/2)\n");
-		break;
-	case CPU_AHB_24_13:
-		pr_cont("(24/13)\n");
-		break;
-	case CPU_AHB_2_1:
-		pr_cont("(2/1)\n");
-		break;
-	}
-
-	return fttmr010_timer_common_init(np);
-}
-CLOCKSOURCE_OF_DECLARE(gemini, "cortina,gemini-timer", gemini_timer_of_init);
+CLOCKSOURCE_OF_DECLARE(fttmr010, "faraday,fttmr010", fttmr010_timer_init);
+CLOCKSOURCE_OF_DECLARE(gemini, "cortina,gemini-timer", fttmr010_timer_init);
-- 
2.9.3

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

* [PATCH 4/8] clocksource/drivers/fttmr010: Use state container
  2017-05-17 14:05 ` Linus Walleij
@ 2017-05-17 14:05   ` Linus Walleij
  -1 siblings, 0 replies; 40+ messages in thread
From: Linus Walleij @ 2017-05-17 14:05 UTC (permalink / raw)
  To: Daniel Lezcano, Thomas Gleixner, Joel Stanley, Jonas Jensen
  Cc: Janos Laube, Paulius Zaleckas, linux-arm-kernel, Hans Ulli Kroll,
	Florian Fainelli, linux-kernel, Linus Walleij

This converts the Faraday FTTMR010 to use the state container
design pattern. Take some care to handle the state container
and free:ing of resources as has been done in the Moxa driver.

Cc: Joel Stanley <joel@jms.id.au>
Cc: Jonas Jensen <jonas.jensen@gmail.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
 drivers/clocksource/timer-fttmr010.c | 190 +++++++++++++++++++++--------------
 1 file changed, 116 insertions(+), 74 deletions(-)

diff --git a/drivers/clocksource/timer-fttmr010.c b/drivers/clocksource/timer-fttmr010.c
index db097db346e3..9ad31489bbef 100644
--- a/drivers/clocksource/timer-fttmr010.c
+++ b/drivers/clocksource/timer-fttmr010.c
@@ -15,6 +15,7 @@
 #include <linux/clocksource.h>
 #include <linux/sched_clock.h>
 #include <linux/clk.h>
+#include <linux/slab.h>
 
 /*
  * Register definitions for the timers
@@ -62,23 +63,35 @@
 #define TIMER_3_INT_OVERFLOW	(1 << 8)
 #define TIMER_INT_ALL_MASK	0x1ff
 
-static unsigned int tick_rate;
-static void __iomem *base;
+struct fttmr010 {
+	void __iomem *base;
+	unsigned int tick_rate;
+	struct clock_event_device clkevt;
+};
+
+/* A local singleton used by sched_clock, which is stateless */
+static struct fttmr010 *local_fttmr;
+
+static inline struct fttmr010 *to_fttmr010(struct clock_event_device *evt)
+{
+	return container_of(evt, struct fttmr010, clkevt);
+}
 
 static u64 notrace fttmr010_read_sched_clock(void)
 {
-	return readl(base + TIMER3_COUNT);
+	return readl(local_fttmr->base + TIMER3_COUNT);
 }
 
 static int fttmr010_timer_set_next_event(unsigned long cycles,
 				       struct clock_event_device *evt)
 {
+	struct fttmr010 *fttmr010 = to_fttmr010(evt);
 	u32 cr;
 
 	/* Setup the match register */
-	cr = readl(base + TIMER1_COUNT);
-	writel(cr + cycles, base + TIMER1_MATCH1);
-	if (readl(base + TIMER1_COUNT) - cr > cycles)
+	cr = readl(fttmr010->base + TIMER1_COUNT);
+	writel(cr + cycles, fttmr010->base + TIMER1_MATCH1);
+	if (readl(fttmr010->base + TIMER1_COUNT) - cr > cycles)
 		return -ETIME;
 
 	return 0;
@@ -86,99 +99,90 @@ static int fttmr010_timer_set_next_event(unsigned long cycles,
 
 static int fttmr010_timer_shutdown(struct clock_event_device *evt)
 {
+	struct fttmr010 *fttmr010 = to_fttmr010(evt);
+	u32 cr;
+
+	/* Stop timer and interrupt. */
+	cr = readl(fttmr010->base + TIMER_CR);
+	cr &= ~(TIMER_1_CR_ENABLE | TIMER_1_CR_INT);
+	writel(cr, fttmr010->base + TIMER_CR);
+
+	return 0;
+}
+
+static int fttmr010_timer_set_oneshot(struct clock_event_device *evt)
+{
+	struct fttmr010 *fttmr010 = to_fttmr010(evt);
 	u32 cr;
 
-	/*
-	 * Disable also for oneshot: the set_next() call will arm the timer
-	 * instead.
-	 */
 	/* Stop timer and interrupt. */
-	cr = readl(base + TIMER_CR);
+	cr = readl(fttmr010->base + TIMER_CR);
 	cr &= ~(TIMER_1_CR_ENABLE | TIMER_1_CR_INT);
-	writel(cr, base + TIMER_CR);
+	writel(cr, fttmr010->base + TIMER_CR);
 
 	/* Setup counter start from 0 */
-	writel(0, base + TIMER1_COUNT);
-	writel(0, base + TIMER1_LOAD);
+	writel(0, fttmr010->base + TIMER1_COUNT);
+	writel(0, fttmr010->base + TIMER1_LOAD);
 
-	/* enable interrupt */
-	cr = readl(base + TIMER_INTR_MASK);
+	/* Enable interrupt */
+	cr = readl(fttmr010->base + TIMER_INTR_MASK);
 	cr &= ~(TIMER_1_INT_OVERFLOW | TIMER_1_INT_MATCH2);
 	cr |= TIMER_1_INT_MATCH1;
-	writel(cr, base + TIMER_INTR_MASK);
+	writel(cr, fttmr010->base + TIMER_INTR_MASK);
 
-	/* start the timer */
-	cr = readl(base + TIMER_CR);
+	/* Start the timer */
+	cr = readl(fttmr010->base + TIMER_CR);
 	cr |= TIMER_1_CR_ENABLE;
-	writel(cr, base + TIMER_CR);
+	writel(cr, fttmr010->base + TIMER_CR);
 
 	return 0;
 }
 
 static int fttmr010_timer_set_periodic(struct clock_event_device *evt)
 {
-	u32 period = DIV_ROUND_CLOSEST(tick_rate, HZ);
+	struct fttmr010 *fttmr010 = to_fttmr010(evt);
+	u32 period = DIV_ROUND_CLOSEST(fttmr010->tick_rate, HZ);
 	u32 cr;
 
 	/* Stop timer and interrupt */
-	cr = readl(base + TIMER_CR);
+	cr = readl(fttmr010->base + TIMER_CR);
 	cr &= ~(TIMER_1_CR_ENABLE | TIMER_1_CR_INT);
-	writel(cr, base + TIMER_CR);
+	writel(cr, fttmr010->base + TIMER_CR);
 
 	/* Setup timer to fire at 1/HT intervals. */
 	cr = 0xffffffff - (period - 1);
-	writel(cr, base + TIMER1_COUNT);
-	writel(cr, base + TIMER1_LOAD);
+	writel(cr, fttmr010->base + TIMER1_COUNT);
+	writel(cr, fttmr010->base + TIMER1_LOAD);
 
 	/* enable interrupt on overflow */
-	cr = readl(base + TIMER_INTR_MASK);
+	cr = readl(fttmr010->base + TIMER_INTR_MASK);
 	cr &= ~(TIMER_1_INT_MATCH1 | TIMER_1_INT_MATCH2);
 	cr |= TIMER_1_INT_OVERFLOW;
-	writel(cr, base + TIMER_INTR_MASK);
+	writel(cr, fttmr010->base + TIMER_INTR_MASK);
 
 	/* Start the timer */
-	cr = readl(base + TIMER_CR);
+	cr = readl(fttmr010->base + TIMER_CR);
 	cr |= TIMER_1_CR_ENABLE;
 	cr |= TIMER_1_CR_INT;
-	writel(cr, base + TIMER_CR);
+	writel(cr, fttmr010->base + TIMER_CR);
 
 	return 0;
 }
 
-/* Use TIMER1 as clock event */
-static struct clock_event_device fttmr010_clockevent = {
-	.name			= "TIMER1",
-	/* Reasonably fast and accurate clock event */
-	.rating			= 300,
-	.shift                  = 32,
-	.features		= CLOCK_EVT_FEAT_PERIODIC |
-				  CLOCK_EVT_FEAT_ONESHOT,
-	.set_next_event		= fttmr010_timer_set_next_event,
-	.set_state_shutdown	= fttmr010_timer_shutdown,
-	.set_state_periodic	= fttmr010_timer_set_periodic,
-	.set_state_oneshot	= fttmr010_timer_shutdown,
-	.tick_resume		= fttmr010_timer_shutdown,
-};
-
 /*
  * IRQ handler for the timer
  */
 static irqreturn_t fttmr010_timer_interrupt(int irq, void *dev_id)
 {
-	struct clock_event_device *evt = &fttmr010_clockevent;
+	struct clock_event_device *evt = dev_id;
 
 	evt->event_handler(evt);
 	return IRQ_HANDLED;
 }
 
-static struct irqaction fttmr010_timer_irq = {
-	.name		= "Faraday FTTMR010 Timer Tick",
-	.flags		= IRQF_TIMER,
-	.handler	= fttmr010_timer_interrupt,
-};
-
 static int __init fttmr010_timer_init(struct device_node *np)
 {
+	struct fttmr010 *fttmr010;
 	int irq;
 	struct clk *clk;
 	int ret;
@@ -198,53 +202,91 @@ static int __init fttmr010_timer_init(struct device_node *np)
 		pr_err("failed to enable PCLK\n");
 		return ret;
 	}
-	tick_rate = clk_get_rate(clk);
 
-	base = of_iomap(np, 0);
-	if (!base) {
+	fttmr010 = kzalloc(sizeof(*fttmr010), GFP_KERNEL);
+	if (!fttmr010) {
+		ret = -ENOMEM;
+		goto out_disable_clock;
+	}
+	fttmr010->tick_rate = clk_get_rate(clk);
+
+	fttmr010->base = of_iomap(np, 0);
+	if (!fttmr010->base) {
 		pr_err("Can't remap registers");
-		return -ENXIO;
+		ret = -ENXIO;
+		goto out_free;
 	}
 	/* IRQ for timer 1 */
 	irq = irq_of_parse_and_map(np, 0);
 	if (irq <= 0) {
 		pr_err("Can't parse IRQ");
-		return -EINVAL;
+		ret = -EINVAL;
+		goto out_unmap;
 	}
 
 	/*
 	 * Reset the interrupt mask and status
 	 */
-	writel(TIMER_INT_ALL_MASK, base + TIMER_INTR_MASK);
-	writel(0, base + TIMER_INTR_STATE);
-	writel(TIMER_DEFAULT_FLAGS, base + TIMER_CR);
+	writel(TIMER_INT_ALL_MASK, fttmr010->base + TIMER_INTR_MASK);
+	writel(0, fttmr010->base + TIMER_INTR_STATE);
+	writel(TIMER_DEFAULT_FLAGS, fttmr010->base + TIMER_CR);
 
 	/*
 	 * Setup free-running clocksource timer (interrupts
 	 * disabled.)
 	 */
-	writel(0, base + TIMER3_COUNT);
-	writel(0, base + TIMER3_LOAD);
-	writel(0, base + TIMER3_MATCH1);
-	writel(0, base + TIMER3_MATCH2);
-	clocksource_mmio_init(base + TIMER3_COUNT,
-			      "fttmr010_clocksource", tick_rate,
+	local_fttmr = fttmr010;
+	writel(0, fttmr010->base + TIMER3_COUNT);
+	writel(0, fttmr010->base + TIMER3_LOAD);
+	writel(0, fttmr010->base + TIMER3_MATCH1);
+	writel(0, fttmr010->base + TIMER3_MATCH2);
+	clocksource_mmio_init(fttmr010->base + TIMER3_COUNT,
+			      "FTTMR010-TIMER3",
+			      fttmr010->tick_rate,
 			      300, 32, clocksource_mmio_readl_up);
-	sched_clock_register(fttmr010_read_sched_clock, 32, tick_rate);
+	sched_clock_register(fttmr010_read_sched_clock, 32,
+			     fttmr010->tick_rate);
 
 	/*
-	 * Setup clockevent timer (interrupt-driven.)
+	 * Setup clockevent timer (interrupt-driven) on timer 1.
 	 */
-	writel(0, base + TIMER1_COUNT);
-	writel(0, base + TIMER1_LOAD);
-	writel(0, base + TIMER1_MATCH1);
-	writel(0, base + TIMER1_MATCH2);
-	setup_irq(irq, &fttmr010_timer_irq);
-	fttmr010_clockevent.cpumask = cpumask_of(0);
-	clockevents_config_and_register(&fttmr010_clockevent, tick_rate,
+	writel(0, fttmr010->base + TIMER1_COUNT);
+	writel(0, fttmr010->base + TIMER1_LOAD);
+	writel(0, fttmr010->base + TIMER1_MATCH1);
+	writel(0, fttmr010->base + TIMER1_MATCH2);
+	ret = request_irq(irq, fttmr010_timer_interrupt, IRQF_TIMER,
+			  "FTTMR010-TIMER1", &fttmr010->clkevt);
+	if (ret) {
+		pr_err("FTTMR010-TIMER1 no IRQ\n");
+		goto out_unmap;
+	}
+
+	fttmr010->clkevt.name = "FTTMR010-TIMER1";
+	/* Reasonably fast and accurate clock event */
+	fttmr010->clkevt.rating = 300;
+	fttmr010->clkevt.features = CLOCK_EVT_FEAT_PERIODIC |
+		CLOCK_EVT_FEAT_ONESHOT;
+	fttmr010->clkevt.set_next_event = fttmr010_timer_set_next_event;
+	fttmr010->clkevt.set_state_shutdown = fttmr010_timer_shutdown;
+	fttmr010->clkevt.set_state_periodic = fttmr010_timer_set_periodic;
+	fttmr010->clkevt.set_state_oneshot = fttmr010_timer_set_oneshot;
+	fttmr010->clkevt.tick_resume = fttmr010_timer_shutdown;
+	fttmr010->clkevt.cpumask = cpumask_of(0);
+	fttmr010->clkevt.irq = irq;
+	clockevents_config_and_register(&fttmr010->clkevt,
+					fttmr010->tick_rate,
 					1, 0xffffffff);
 
 	return 0;
+
+out_unmap:
+	iounmap(fttmr010->base);
+out_free:
+	kfree(fttmr010);
+out_disable_clock:
+	clk_disable_unprepare(clk);
+
+	return ret;
 }
 CLOCKSOURCE_OF_DECLARE(fttmr010, "faraday,fttmr010", fttmr010_timer_init);
 CLOCKSOURCE_OF_DECLARE(gemini, "cortina,gemini-timer", fttmr010_timer_init);
-- 
2.9.3

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

* [PATCH 4/8] clocksource/drivers/fttmr010: Use state container
@ 2017-05-17 14:05   ` Linus Walleij
  0 siblings, 0 replies; 40+ messages in thread
From: Linus Walleij @ 2017-05-17 14:05 UTC (permalink / raw)
  To: linux-arm-kernel

This converts the Faraday FTTMR010 to use the state container
design pattern. Take some care to handle the state container
and free:ing of resources as has been done in the Moxa driver.

Cc: Joel Stanley <joel@jms.id.au>
Cc: Jonas Jensen <jonas.jensen@gmail.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
 drivers/clocksource/timer-fttmr010.c | 190 +++++++++++++++++++++--------------
 1 file changed, 116 insertions(+), 74 deletions(-)

diff --git a/drivers/clocksource/timer-fttmr010.c b/drivers/clocksource/timer-fttmr010.c
index db097db346e3..9ad31489bbef 100644
--- a/drivers/clocksource/timer-fttmr010.c
+++ b/drivers/clocksource/timer-fttmr010.c
@@ -15,6 +15,7 @@
 #include <linux/clocksource.h>
 #include <linux/sched_clock.h>
 #include <linux/clk.h>
+#include <linux/slab.h>
 
 /*
  * Register definitions for the timers
@@ -62,23 +63,35 @@
 #define TIMER_3_INT_OVERFLOW	(1 << 8)
 #define TIMER_INT_ALL_MASK	0x1ff
 
-static unsigned int tick_rate;
-static void __iomem *base;
+struct fttmr010 {
+	void __iomem *base;
+	unsigned int tick_rate;
+	struct clock_event_device clkevt;
+};
+
+/* A local singleton used by sched_clock, which is stateless */
+static struct fttmr010 *local_fttmr;
+
+static inline struct fttmr010 *to_fttmr010(struct clock_event_device *evt)
+{
+	return container_of(evt, struct fttmr010, clkevt);
+}
 
 static u64 notrace fttmr010_read_sched_clock(void)
 {
-	return readl(base + TIMER3_COUNT);
+	return readl(local_fttmr->base + TIMER3_COUNT);
 }
 
 static int fttmr010_timer_set_next_event(unsigned long cycles,
 				       struct clock_event_device *evt)
 {
+	struct fttmr010 *fttmr010 = to_fttmr010(evt);
 	u32 cr;
 
 	/* Setup the match register */
-	cr = readl(base + TIMER1_COUNT);
-	writel(cr + cycles, base + TIMER1_MATCH1);
-	if (readl(base + TIMER1_COUNT) - cr > cycles)
+	cr = readl(fttmr010->base + TIMER1_COUNT);
+	writel(cr + cycles, fttmr010->base + TIMER1_MATCH1);
+	if (readl(fttmr010->base + TIMER1_COUNT) - cr > cycles)
 		return -ETIME;
 
 	return 0;
@@ -86,99 +99,90 @@ static int fttmr010_timer_set_next_event(unsigned long cycles,
 
 static int fttmr010_timer_shutdown(struct clock_event_device *evt)
 {
+	struct fttmr010 *fttmr010 = to_fttmr010(evt);
+	u32 cr;
+
+	/* Stop timer and interrupt. */
+	cr = readl(fttmr010->base + TIMER_CR);
+	cr &= ~(TIMER_1_CR_ENABLE | TIMER_1_CR_INT);
+	writel(cr, fttmr010->base + TIMER_CR);
+
+	return 0;
+}
+
+static int fttmr010_timer_set_oneshot(struct clock_event_device *evt)
+{
+	struct fttmr010 *fttmr010 = to_fttmr010(evt);
 	u32 cr;
 
-	/*
-	 * Disable also for oneshot: the set_next() call will arm the timer
-	 * instead.
-	 */
 	/* Stop timer and interrupt. */
-	cr = readl(base + TIMER_CR);
+	cr = readl(fttmr010->base + TIMER_CR);
 	cr &= ~(TIMER_1_CR_ENABLE | TIMER_1_CR_INT);
-	writel(cr, base + TIMER_CR);
+	writel(cr, fttmr010->base + TIMER_CR);
 
 	/* Setup counter start from 0 */
-	writel(0, base + TIMER1_COUNT);
-	writel(0, base + TIMER1_LOAD);
+	writel(0, fttmr010->base + TIMER1_COUNT);
+	writel(0, fttmr010->base + TIMER1_LOAD);
 
-	/* enable interrupt */
-	cr = readl(base + TIMER_INTR_MASK);
+	/* Enable interrupt */
+	cr = readl(fttmr010->base + TIMER_INTR_MASK);
 	cr &= ~(TIMER_1_INT_OVERFLOW | TIMER_1_INT_MATCH2);
 	cr |= TIMER_1_INT_MATCH1;
-	writel(cr, base + TIMER_INTR_MASK);
+	writel(cr, fttmr010->base + TIMER_INTR_MASK);
 
-	/* start the timer */
-	cr = readl(base + TIMER_CR);
+	/* Start the timer */
+	cr = readl(fttmr010->base + TIMER_CR);
 	cr |= TIMER_1_CR_ENABLE;
-	writel(cr, base + TIMER_CR);
+	writel(cr, fttmr010->base + TIMER_CR);
 
 	return 0;
 }
 
 static int fttmr010_timer_set_periodic(struct clock_event_device *evt)
 {
-	u32 period = DIV_ROUND_CLOSEST(tick_rate, HZ);
+	struct fttmr010 *fttmr010 = to_fttmr010(evt);
+	u32 period = DIV_ROUND_CLOSEST(fttmr010->tick_rate, HZ);
 	u32 cr;
 
 	/* Stop timer and interrupt */
-	cr = readl(base + TIMER_CR);
+	cr = readl(fttmr010->base + TIMER_CR);
 	cr &= ~(TIMER_1_CR_ENABLE | TIMER_1_CR_INT);
-	writel(cr, base + TIMER_CR);
+	writel(cr, fttmr010->base + TIMER_CR);
 
 	/* Setup timer to fire at 1/HT intervals. */
 	cr = 0xffffffff - (period - 1);
-	writel(cr, base + TIMER1_COUNT);
-	writel(cr, base + TIMER1_LOAD);
+	writel(cr, fttmr010->base + TIMER1_COUNT);
+	writel(cr, fttmr010->base + TIMER1_LOAD);
 
 	/* enable interrupt on overflow */
-	cr = readl(base + TIMER_INTR_MASK);
+	cr = readl(fttmr010->base + TIMER_INTR_MASK);
 	cr &= ~(TIMER_1_INT_MATCH1 | TIMER_1_INT_MATCH2);
 	cr |= TIMER_1_INT_OVERFLOW;
-	writel(cr, base + TIMER_INTR_MASK);
+	writel(cr, fttmr010->base + TIMER_INTR_MASK);
 
 	/* Start the timer */
-	cr = readl(base + TIMER_CR);
+	cr = readl(fttmr010->base + TIMER_CR);
 	cr |= TIMER_1_CR_ENABLE;
 	cr |= TIMER_1_CR_INT;
-	writel(cr, base + TIMER_CR);
+	writel(cr, fttmr010->base + TIMER_CR);
 
 	return 0;
 }
 
-/* Use TIMER1 as clock event */
-static struct clock_event_device fttmr010_clockevent = {
-	.name			= "TIMER1",
-	/* Reasonably fast and accurate clock event */
-	.rating			= 300,
-	.shift                  = 32,
-	.features		= CLOCK_EVT_FEAT_PERIODIC |
-				  CLOCK_EVT_FEAT_ONESHOT,
-	.set_next_event		= fttmr010_timer_set_next_event,
-	.set_state_shutdown	= fttmr010_timer_shutdown,
-	.set_state_periodic	= fttmr010_timer_set_periodic,
-	.set_state_oneshot	= fttmr010_timer_shutdown,
-	.tick_resume		= fttmr010_timer_shutdown,
-};
-
 /*
  * IRQ handler for the timer
  */
 static irqreturn_t fttmr010_timer_interrupt(int irq, void *dev_id)
 {
-	struct clock_event_device *evt = &fttmr010_clockevent;
+	struct clock_event_device *evt = dev_id;
 
 	evt->event_handler(evt);
 	return IRQ_HANDLED;
 }
 
-static struct irqaction fttmr010_timer_irq = {
-	.name		= "Faraday FTTMR010 Timer Tick",
-	.flags		= IRQF_TIMER,
-	.handler	= fttmr010_timer_interrupt,
-};
-
 static int __init fttmr010_timer_init(struct device_node *np)
 {
+	struct fttmr010 *fttmr010;
 	int irq;
 	struct clk *clk;
 	int ret;
@@ -198,53 +202,91 @@ static int __init fttmr010_timer_init(struct device_node *np)
 		pr_err("failed to enable PCLK\n");
 		return ret;
 	}
-	tick_rate = clk_get_rate(clk);
 
-	base = of_iomap(np, 0);
-	if (!base) {
+	fttmr010 = kzalloc(sizeof(*fttmr010), GFP_KERNEL);
+	if (!fttmr010) {
+		ret = -ENOMEM;
+		goto out_disable_clock;
+	}
+	fttmr010->tick_rate = clk_get_rate(clk);
+
+	fttmr010->base = of_iomap(np, 0);
+	if (!fttmr010->base) {
 		pr_err("Can't remap registers");
-		return -ENXIO;
+		ret = -ENXIO;
+		goto out_free;
 	}
 	/* IRQ for timer 1 */
 	irq = irq_of_parse_and_map(np, 0);
 	if (irq <= 0) {
 		pr_err("Can't parse IRQ");
-		return -EINVAL;
+		ret = -EINVAL;
+		goto out_unmap;
 	}
 
 	/*
 	 * Reset the interrupt mask and status
 	 */
-	writel(TIMER_INT_ALL_MASK, base + TIMER_INTR_MASK);
-	writel(0, base + TIMER_INTR_STATE);
-	writel(TIMER_DEFAULT_FLAGS, base + TIMER_CR);
+	writel(TIMER_INT_ALL_MASK, fttmr010->base + TIMER_INTR_MASK);
+	writel(0, fttmr010->base + TIMER_INTR_STATE);
+	writel(TIMER_DEFAULT_FLAGS, fttmr010->base + TIMER_CR);
 
 	/*
 	 * Setup free-running clocksource timer (interrupts
 	 * disabled.)
 	 */
-	writel(0, base + TIMER3_COUNT);
-	writel(0, base + TIMER3_LOAD);
-	writel(0, base + TIMER3_MATCH1);
-	writel(0, base + TIMER3_MATCH2);
-	clocksource_mmio_init(base + TIMER3_COUNT,
-			      "fttmr010_clocksource", tick_rate,
+	local_fttmr = fttmr010;
+	writel(0, fttmr010->base + TIMER3_COUNT);
+	writel(0, fttmr010->base + TIMER3_LOAD);
+	writel(0, fttmr010->base + TIMER3_MATCH1);
+	writel(0, fttmr010->base + TIMER3_MATCH2);
+	clocksource_mmio_init(fttmr010->base + TIMER3_COUNT,
+			      "FTTMR010-TIMER3",
+			      fttmr010->tick_rate,
 			      300, 32, clocksource_mmio_readl_up);
-	sched_clock_register(fttmr010_read_sched_clock, 32, tick_rate);
+	sched_clock_register(fttmr010_read_sched_clock, 32,
+			     fttmr010->tick_rate);
 
 	/*
-	 * Setup clockevent timer (interrupt-driven.)
+	 * Setup clockevent timer (interrupt-driven) on timer 1.
 	 */
-	writel(0, base + TIMER1_COUNT);
-	writel(0, base + TIMER1_LOAD);
-	writel(0, base + TIMER1_MATCH1);
-	writel(0, base + TIMER1_MATCH2);
-	setup_irq(irq, &fttmr010_timer_irq);
-	fttmr010_clockevent.cpumask = cpumask_of(0);
-	clockevents_config_and_register(&fttmr010_clockevent, tick_rate,
+	writel(0, fttmr010->base + TIMER1_COUNT);
+	writel(0, fttmr010->base + TIMER1_LOAD);
+	writel(0, fttmr010->base + TIMER1_MATCH1);
+	writel(0, fttmr010->base + TIMER1_MATCH2);
+	ret = request_irq(irq, fttmr010_timer_interrupt, IRQF_TIMER,
+			  "FTTMR010-TIMER1", &fttmr010->clkevt);
+	if (ret) {
+		pr_err("FTTMR010-TIMER1 no IRQ\n");
+		goto out_unmap;
+	}
+
+	fttmr010->clkevt.name = "FTTMR010-TIMER1";
+	/* Reasonably fast and accurate clock event */
+	fttmr010->clkevt.rating = 300;
+	fttmr010->clkevt.features = CLOCK_EVT_FEAT_PERIODIC |
+		CLOCK_EVT_FEAT_ONESHOT;
+	fttmr010->clkevt.set_next_event = fttmr010_timer_set_next_event;
+	fttmr010->clkevt.set_state_shutdown = fttmr010_timer_shutdown;
+	fttmr010->clkevt.set_state_periodic = fttmr010_timer_set_periodic;
+	fttmr010->clkevt.set_state_oneshot = fttmr010_timer_set_oneshot;
+	fttmr010->clkevt.tick_resume = fttmr010_timer_shutdown;
+	fttmr010->clkevt.cpumask = cpumask_of(0);
+	fttmr010->clkevt.irq = irq;
+	clockevents_config_and_register(&fttmr010->clkevt,
+					fttmr010->tick_rate,
 					1, 0xffffffff);
 
 	return 0;
+
+out_unmap:
+	iounmap(fttmr010->base);
+out_free:
+	kfree(fttmr010);
+out_disable_clock:
+	clk_disable_unprepare(clk);
+
+	return ret;
 }
 CLOCKSOURCE_OF_DECLARE(fttmr010, "faraday,fttmr010", fttmr010_timer_init);
 CLOCKSOURCE_OF_DECLARE(gemini, "cortina,gemini-timer", fttmr010_timer_init);
-- 
2.9.3

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

* [PATCH 5/8] clocksource/drivers/fttmr010: Switch to use bitops
  2017-05-17 14:05 ` Linus Walleij
@ 2017-05-17 14:05   ` Linus Walleij
  -1 siblings, 0 replies; 40+ messages in thread
From: Linus Walleij @ 2017-05-17 14:05 UTC (permalink / raw)
  To: Daniel Lezcano, Thomas Gleixner, Joel Stanley, Jonas Jensen
  Cc: Janos Laube, Paulius Zaleckas, linux-arm-kernel, Hans Ulli Kroll,
	Florian Fainelli, linux-kernel, Linus Walleij

This switches the drivers to use the bitops BIT() macro
to define bits.

Cc: Joel Stanley <joel@jms.id.au>
Cc: Jonas Jensen <jonas.jensen@gmail.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
 drivers/clocksource/timer-fttmr010.c | 43 ++++++++++++++++++------------------
 1 file changed, 22 insertions(+), 21 deletions(-)

diff --git a/drivers/clocksource/timer-fttmr010.c b/drivers/clocksource/timer-fttmr010.c
index 9ad31489bbef..9df14cf13808 100644
--- a/drivers/clocksource/timer-fttmr010.c
+++ b/drivers/clocksource/timer-fttmr010.c
@@ -16,6 +16,7 @@
 #include <linux/sched_clock.h>
 #include <linux/clk.h>
 #include <linux/slab.h>
+#include <linux/bitops.h>
 
 /*
  * Register definitions for the timers
@@ -36,31 +37,31 @@
 #define TIMER_INTR_STATE	(0x34)
 #define TIMER_INTR_MASK		(0x38)
 
-#define TIMER_1_CR_ENABLE	(1 << 0)
-#define TIMER_1_CR_CLOCK	(1 << 1)
-#define TIMER_1_CR_INT		(1 << 2)
-#define TIMER_2_CR_ENABLE	(1 << 3)
-#define TIMER_2_CR_CLOCK	(1 << 4)
-#define TIMER_2_CR_INT		(1 << 5)
-#define TIMER_3_CR_ENABLE	(1 << 6)
-#define TIMER_3_CR_CLOCK	(1 << 7)
-#define TIMER_3_CR_INT		(1 << 8)
-#define TIMER_1_CR_UPDOWN	(1 << 9)
-#define TIMER_2_CR_UPDOWN	(1 << 10)
-#define TIMER_3_CR_UPDOWN	(1 << 11)
+#define TIMER_1_CR_ENABLE	BIT(0)
+#define TIMER_1_CR_CLOCK	BIT(1)
+#define TIMER_1_CR_INT		BIT(2)
+#define TIMER_2_CR_ENABLE	BIT(3)
+#define TIMER_2_CR_CLOCK	BIT(4)
+#define TIMER_2_CR_INT		BIT(5)
+#define TIMER_3_CR_ENABLE	BIT(6)
+#define TIMER_3_CR_CLOCK	BIT(7)
+#define TIMER_3_CR_INT		BIT(8)
+#define TIMER_1_CR_UPDOWN	BIT(9)
+#define TIMER_2_CR_UPDOWN	BIT(10)
+#define TIMER_3_CR_UPDOWN	BIT(11)
 #define TIMER_DEFAULT_FLAGS	(TIMER_1_CR_UPDOWN | \
 				 TIMER_3_CR_ENABLE | \
 				 TIMER_3_CR_UPDOWN)
 
-#define TIMER_1_INT_MATCH1	(1 << 0)
-#define TIMER_1_INT_MATCH2	(1 << 1)
-#define TIMER_1_INT_OVERFLOW	(1 << 2)
-#define TIMER_2_INT_MATCH1	(1 << 3)
-#define TIMER_2_INT_MATCH2	(1 << 4)
-#define TIMER_2_INT_OVERFLOW	(1 << 5)
-#define TIMER_3_INT_MATCH1	(1 << 6)
-#define TIMER_3_INT_MATCH2	(1 << 7)
-#define TIMER_3_INT_OVERFLOW	(1 << 8)
+#define TIMER_1_INT_MATCH1	BIT(0)
+#define TIMER_1_INT_MATCH2	BIT(1)
+#define TIMER_1_INT_OVERFLOW	BIT(2)
+#define TIMER_2_INT_MATCH1	BIT(3)
+#define TIMER_2_INT_MATCH2	BIT(4)
+#define TIMER_2_INT_OVERFLOW	BIT(5)
+#define TIMER_3_INT_MATCH1	BIT(6)
+#define TIMER_3_INT_MATCH2	BIT(7)
+#define TIMER_3_INT_OVERFLOW	BIT(8)
 #define TIMER_INT_ALL_MASK	0x1ff
 
 struct fttmr010 {
-- 
2.9.3

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

* [PATCH 5/8] clocksource/drivers/fttmr010: Switch to use bitops
@ 2017-05-17 14:05   ` Linus Walleij
  0 siblings, 0 replies; 40+ messages in thread
From: Linus Walleij @ 2017-05-17 14:05 UTC (permalink / raw)
  To: linux-arm-kernel

This switches the drivers to use the bitops BIT() macro
to define bits.

Cc: Joel Stanley <joel@jms.id.au>
Cc: Jonas Jensen <jonas.jensen@gmail.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
 drivers/clocksource/timer-fttmr010.c | 43 ++++++++++++++++++------------------
 1 file changed, 22 insertions(+), 21 deletions(-)

diff --git a/drivers/clocksource/timer-fttmr010.c b/drivers/clocksource/timer-fttmr010.c
index 9ad31489bbef..9df14cf13808 100644
--- a/drivers/clocksource/timer-fttmr010.c
+++ b/drivers/clocksource/timer-fttmr010.c
@@ -16,6 +16,7 @@
 #include <linux/sched_clock.h>
 #include <linux/clk.h>
 #include <linux/slab.h>
+#include <linux/bitops.h>
 
 /*
  * Register definitions for the timers
@@ -36,31 +37,31 @@
 #define TIMER_INTR_STATE	(0x34)
 #define TIMER_INTR_MASK		(0x38)
 
-#define TIMER_1_CR_ENABLE	(1 << 0)
-#define TIMER_1_CR_CLOCK	(1 << 1)
-#define TIMER_1_CR_INT		(1 << 2)
-#define TIMER_2_CR_ENABLE	(1 << 3)
-#define TIMER_2_CR_CLOCK	(1 << 4)
-#define TIMER_2_CR_INT		(1 << 5)
-#define TIMER_3_CR_ENABLE	(1 << 6)
-#define TIMER_3_CR_CLOCK	(1 << 7)
-#define TIMER_3_CR_INT		(1 << 8)
-#define TIMER_1_CR_UPDOWN	(1 << 9)
-#define TIMER_2_CR_UPDOWN	(1 << 10)
-#define TIMER_3_CR_UPDOWN	(1 << 11)
+#define TIMER_1_CR_ENABLE	BIT(0)
+#define TIMER_1_CR_CLOCK	BIT(1)
+#define TIMER_1_CR_INT		BIT(2)
+#define TIMER_2_CR_ENABLE	BIT(3)
+#define TIMER_2_CR_CLOCK	BIT(4)
+#define TIMER_2_CR_INT		BIT(5)
+#define TIMER_3_CR_ENABLE	BIT(6)
+#define TIMER_3_CR_CLOCK	BIT(7)
+#define TIMER_3_CR_INT		BIT(8)
+#define TIMER_1_CR_UPDOWN	BIT(9)
+#define TIMER_2_CR_UPDOWN	BIT(10)
+#define TIMER_3_CR_UPDOWN	BIT(11)
 #define TIMER_DEFAULT_FLAGS	(TIMER_1_CR_UPDOWN | \
 				 TIMER_3_CR_ENABLE | \
 				 TIMER_3_CR_UPDOWN)
 
-#define TIMER_1_INT_MATCH1	(1 << 0)
-#define TIMER_1_INT_MATCH2	(1 << 1)
-#define TIMER_1_INT_OVERFLOW	(1 << 2)
-#define TIMER_2_INT_MATCH1	(1 << 3)
-#define TIMER_2_INT_MATCH2	(1 << 4)
-#define TIMER_2_INT_OVERFLOW	(1 << 5)
-#define TIMER_3_INT_MATCH1	(1 << 6)
-#define TIMER_3_INT_MATCH2	(1 << 7)
-#define TIMER_3_INT_OVERFLOW	(1 << 8)
+#define TIMER_1_INT_MATCH1	BIT(0)
+#define TIMER_1_INT_MATCH2	BIT(1)
+#define TIMER_1_INT_OVERFLOW	BIT(2)
+#define TIMER_2_INT_MATCH1	BIT(3)
+#define TIMER_2_INT_MATCH2	BIT(4)
+#define TIMER_2_INT_OVERFLOW	BIT(5)
+#define TIMER_3_INT_MATCH1	BIT(6)
+#define TIMER_3_INT_MATCH2	BIT(7)
+#define TIMER_3_INT_OVERFLOW	BIT(8)
 #define TIMER_INT_ALL_MASK	0x1ff
 
 struct fttmr010 {
-- 
2.9.3

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

* [PATCH 6/8] clocksource/drivers/fttmr010: Switch to use TIMER2 src
  2017-05-17 14:05 ` Linus Walleij
@ 2017-05-17 14:05   ` Linus Walleij
  -1 siblings, 0 replies; 40+ messages in thread
From: Linus Walleij @ 2017-05-17 14:05 UTC (permalink / raw)
  To: Daniel Lezcano, Thomas Gleixner, Joel Stanley, Jonas Jensen
  Cc: Janos Laube, Paulius Zaleckas, linux-arm-kernel, Hans Ulli Kroll,
	Florian Fainelli, linux-kernel, Linus Walleij

This switches the clocksource to TIMER2 like the Moxart driver
does. Mainly to make it more similar to the Moxart/Aspeed driver
but also because it seems more neat to use the timers in order:
use timer 1, then timer 2.

Cc: Joel Stanley <joel@jms.id.au>
Cc: Jonas Jensen <jonas.jensen@gmail.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
 drivers/clocksource/timer-fttmr010.c | 21 ++++++++++-----------
 1 file changed, 10 insertions(+), 11 deletions(-)

diff --git a/drivers/clocksource/timer-fttmr010.c b/drivers/clocksource/timer-fttmr010.c
index 9df14cf13808..2d915d1455ab 100644
--- a/drivers/clocksource/timer-fttmr010.c
+++ b/drivers/clocksource/timer-fttmr010.c
@@ -49,9 +49,6 @@
 #define TIMER_1_CR_UPDOWN	BIT(9)
 #define TIMER_2_CR_UPDOWN	BIT(10)
 #define TIMER_3_CR_UPDOWN	BIT(11)
-#define TIMER_DEFAULT_FLAGS	(TIMER_1_CR_UPDOWN | \
-				 TIMER_3_CR_ENABLE | \
-				 TIMER_3_CR_UPDOWN)
 
 #define TIMER_1_INT_MATCH1	BIT(0)
 #define TIMER_1_INT_MATCH2	BIT(1)
@@ -80,7 +77,7 @@ static inline struct fttmr010 *to_fttmr010(struct clock_event_device *evt)
 
 static u64 notrace fttmr010_read_sched_clock(void)
 {
-	return readl(local_fttmr->base + TIMER3_COUNT);
+	return readl(local_fttmr->base + TIMER2_COUNT);
 }
 
 static int fttmr010_timer_set_next_event(unsigned long cycles,
@@ -230,19 +227,21 @@ static int __init fttmr010_timer_init(struct device_node *np)
 	 */
 	writel(TIMER_INT_ALL_MASK, fttmr010->base + TIMER_INTR_MASK);
 	writel(0, fttmr010->base + TIMER_INTR_STATE);
-	writel(TIMER_DEFAULT_FLAGS, fttmr010->base + TIMER_CR);
+	/* Enable timer 1 count up, timer 2 count up */
+	writel((TIMER_1_CR_UPDOWN | TIMER_2_CR_ENABLE | TIMER_2_CR_UPDOWN),
+	       fttmr010->base + TIMER_CR);
 
 	/*
 	 * Setup free-running clocksource timer (interrupts
 	 * disabled.)
 	 */
 	local_fttmr = fttmr010;
-	writel(0, fttmr010->base + TIMER3_COUNT);
-	writel(0, fttmr010->base + TIMER3_LOAD);
-	writel(0, fttmr010->base + TIMER3_MATCH1);
-	writel(0, fttmr010->base + TIMER3_MATCH2);
-	clocksource_mmio_init(fttmr010->base + TIMER3_COUNT,
-			      "FTTMR010-TIMER3",
+	writel(0, fttmr010->base + TIMER2_COUNT);
+	writel(0, fttmr010->base + TIMER2_LOAD);
+	writel(0, fttmr010->base + TIMER2_MATCH1);
+	writel(0, fttmr010->base + TIMER2_MATCH2);
+	clocksource_mmio_init(fttmr010->base + TIMER2_COUNT,
+			      "FTTMR010-TIMER2",
 			      fttmr010->tick_rate,
 			      300, 32, clocksource_mmio_readl_up);
 	sched_clock_register(fttmr010_read_sched_clock, 32,
-- 
2.9.3

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

* [PATCH 6/8] clocksource/drivers/fttmr010: Switch to use TIMER2 src
@ 2017-05-17 14:05   ` Linus Walleij
  0 siblings, 0 replies; 40+ messages in thread
From: Linus Walleij @ 2017-05-17 14:05 UTC (permalink / raw)
  To: linux-arm-kernel

This switches the clocksource to TIMER2 like the Moxart driver
does. Mainly to make it more similar to the Moxart/Aspeed driver
but also because it seems more neat to use the timers in order:
use timer 1, then timer 2.

Cc: Joel Stanley <joel@jms.id.au>
Cc: Jonas Jensen <jonas.jensen@gmail.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
 drivers/clocksource/timer-fttmr010.c | 21 ++++++++++-----------
 1 file changed, 10 insertions(+), 11 deletions(-)

diff --git a/drivers/clocksource/timer-fttmr010.c b/drivers/clocksource/timer-fttmr010.c
index 9df14cf13808..2d915d1455ab 100644
--- a/drivers/clocksource/timer-fttmr010.c
+++ b/drivers/clocksource/timer-fttmr010.c
@@ -49,9 +49,6 @@
 #define TIMER_1_CR_UPDOWN	BIT(9)
 #define TIMER_2_CR_UPDOWN	BIT(10)
 #define TIMER_3_CR_UPDOWN	BIT(11)
-#define TIMER_DEFAULT_FLAGS	(TIMER_1_CR_UPDOWN | \
-				 TIMER_3_CR_ENABLE | \
-				 TIMER_3_CR_UPDOWN)
 
 #define TIMER_1_INT_MATCH1	BIT(0)
 #define TIMER_1_INT_MATCH2	BIT(1)
@@ -80,7 +77,7 @@ static inline struct fttmr010 *to_fttmr010(struct clock_event_device *evt)
 
 static u64 notrace fttmr010_read_sched_clock(void)
 {
-	return readl(local_fttmr->base + TIMER3_COUNT);
+	return readl(local_fttmr->base + TIMER2_COUNT);
 }
 
 static int fttmr010_timer_set_next_event(unsigned long cycles,
@@ -230,19 +227,21 @@ static int __init fttmr010_timer_init(struct device_node *np)
 	 */
 	writel(TIMER_INT_ALL_MASK, fttmr010->base + TIMER_INTR_MASK);
 	writel(0, fttmr010->base + TIMER_INTR_STATE);
-	writel(TIMER_DEFAULT_FLAGS, fttmr010->base + TIMER_CR);
+	/* Enable timer 1 count up, timer 2 count up */
+	writel((TIMER_1_CR_UPDOWN | TIMER_2_CR_ENABLE | TIMER_2_CR_UPDOWN),
+	       fttmr010->base + TIMER_CR);
 
 	/*
 	 * Setup free-running clocksource timer (interrupts
 	 * disabled.)
 	 */
 	local_fttmr = fttmr010;
-	writel(0, fttmr010->base + TIMER3_COUNT);
-	writel(0, fttmr010->base + TIMER3_LOAD);
-	writel(0, fttmr010->base + TIMER3_MATCH1);
-	writel(0, fttmr010->base + TIMER3_MATCH2);
-	clocksource_mmio_init(fttmr010->base + TIMER3_COUNT,
-			      "FTTMR010-TIMER3",
+	writel(0, fttmr010->base + TIMER2_COUNT);
+	writel(0, fttmr010->base + TIMER2_LOAD);
+	writel(0, fttmr010->base + TIMER2_MATCH1);
+	writel(0, fttmr010->base + TIMER2_MATCH2);
+	clocksource_mmio_init(fttmr010->base + TIMER2_COUNT,
+			      "FTTMR010-TIMER2",
 			      fttmr010->tick_rate,
 			      300, 32, clocksource_mmio_readl_up);
 	sched_clock_register(fttmr010_read_sched_clock, 32,
-- 
2.9.3

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

* [PATCH 7/8] clocksource/drivers/fttmr010: Merge Moxa into FTTMR010
  2017-05-17 14:05 ` Linus Walleij
@ 2017-05-17 14:05   ` Linus Walleij
  -1 siblings, 0 replies; 40+ messages in thread
From: Linus Walleij @ 2017-05-17 14:05 UTC (permalink / raw)
  To: Daniel Lezcano, Thomas Gleixner, Joel Stanley, Jonas Jensen
  Cc: Janos Laube, Paulius Zaleckas, linux-arm-kernel, Hans Ulli Kroll,
	Florian Fainelli, linux-kernel, Linus Walleij

This merges the Moxa Art timer driver into the Faraday FTTMR010
driver and replaces all Kconfig symbols to use the Faraday
driver instead. We are now so similar that the drivers can
be merged by just adding a few lines to the Faraday timer.

Differences:

- The Faraday driver explicitly sets the counter to count
  upwards for the clocksource, removing the need for the
  clocksource core to invert the value.

- The Faraday driver also handles sched_clock()

I am just guessing at the way the Aspeed has moved the count
up/down bits to bits 3, 8 and 11 (keeping the bits pertaining
to a certain timer together), so this really needs testing on
the Aspeed. I'm guessing like this because it is what I would
have done, if I was rewriting some VHDL/Verilog to extend
these three timers to 8 (as the Aspeed apparently does).

After this we have one driver for all three SoCs and a generic
Faraday FTTMR010 timer driver, which is nice.

Cc: Joel Stanley <joel@jms.id.au>
Cc: Jonas Jensen <jonas.jensen@gmail.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
ARM SoC folks: please ACK this so it can be merged with in the
clocksource subsystem once it works.

Joel: it would be super if you can test this. If you have some
vendor tree or similar that actually indicates where the
up/down counter bits are it's even better, but I'm hoping that
this half-assed guesswork will JustWork(TM) (yeah, famous
last words, sorry...)
---
 arch/arm/mach-aspeed/Kconfig         |   2 +-
 arch/arm/mach-moxart/Kconfig         |   2 +-
 drivers/clocksource/Kconfig          |   7 -
 drivers/clocksource/Makefile         |   1 -
 drivers/clocksource/moxart_timer.c   | 256 -----------------------------------
 drivers/clocksource/timer-fttmr010.c |  52 +++++--
 6 files changed, 46 insertions(+), 274 deletions(-)
 delete mode 100644 drivers/clocksource/moxart_timer.c

diff --git a/arch/arm/mach-aspeed/Kconfig b/arch/arm/mach-aspeed/Kconfig
index f3f8c5c658db..2d5570e6e186 100644
--- a/arch/arm/mach-aspeed/Kconfig
+++ b/arch/arm/mach-aspeed/Kconfig
@@ -4,7 +4,7 @@ menuconfig ARCH_ASPEED
 	select SRAM
 	select WATCHDOG
 	select ASPEED_WATCHDOG
-	select MOXART_TIMER
+	select FTTMR010_TIMER
 	select MFD_SYSCON
 	select PINCTRL
 	help
diff --git a/arch/arm/mach-moxart/Kconfig b/arch/arm/mach-moxart/Kconfig
index 70db2abf6163..a4a91f9a3301 100644
--- a/arch/arm/mach-moxart/Kconfig
+++ b/arch/arm/mach-moxart/Kconfig
@@ -4,7 +4,7 @@ menuconfig ARCH_MOXART
 	select CPU_FA526
 	select ARM_DMA_MEM_BUFFERABLE
 	select FARADAY_FTINTC010
-	select MOXART_TIMER
+	select FTTMR010_TIMER
 	select GPIOLIB
 	select PHYLIB if NETDEVICES
 	help
diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index 545d541ae20e..1b22ade4c8f1 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -188,13 +188,6 @@ config ATLAS7_TIMER
 	help
 	  Enables support for the Atlas7 timer.
 
-config MOXART_TIMER
-	bool "Moxart timer driver" if COMPILE_TEST
-	depends on GENERIC_CLOCKEVENTS
-	select CLKSRC_MMIO
-	help
-	  Enables support for the Moxart timer.
-
 config MXS_TIMER
 	bool "Mxs timer driver" if COMPILE_TEST
 	depends on GENERIC_CLOCKEVENTS
diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
index 2b5b56a6f00f..cf0c30b6ec1f 100644
--- a/drivers/clocksource/Makefile
+++ b/drivers/clocksource/Makefile
@@ -26,7 +26,6 @@ obj-$(CONFIG_ORION_TIMER)	+= time-orion.o
 obj-$(CONFIG_BCM2835_TIMER)	+= bcm2835_timer.o
 obj-$(CONFIG_CLPS711X_TIMER)	+= clps711x-timer.o
 obj-$(CONFIG_ATLAS7_TIMER)	+= timer-atlas7.o
-obj-$(CONFIG_MOXART_TIMER)	+= moxart_timer.o
 obj-$(CONFIG_MXS_TIMER)		+= mxs_timer.o
 obj-$(CONFIG_CLKSRC_PXA)	+= pxa_timer.o
 obj-$(CONFIG_PRIMA2_TIMER)	+= timer-prima2.o
diff --git a/drivers/clocksource/moxart_timer.c b/drivers/clocksource/moxart_timer.c
deleted file mode 100644
index 7f3430654fbd..000000000000
--- a/drivers/clocksource/moxart_timer.c
+++ /dev/null
@@ -1,256 +0,0 @@
-/*
- * MOXA ART SoCs timer handling.
- *
- * Copyright (C) 2013 Jonas Jensen
- *
- * Jonas Jensen <jonas.jensen@gmail.com>
- *
- * This file is licensed under the terms of the GNU General Public
- * License version 2.  This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
- */
-
-#include <linux/clk.h>
-#include <linux/clockchips.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/irqreturn.h>
-#include <linux/of.h>
-#include <linux/of_address.h>
-#include <linux/of_irq.h>
-#include <linux/io.h>
-#include <linux/clocksource.h>
-#include <linux/bitops.h>
-#include <linux/slab.h>
-
-#define TIMER1_BASE		0x00
-#define TIMER2_BASE		0x10
-#define TIMER3_BASE		0x20
-
-#define REG_COUNT		0x0 /* writable */
-#define REG_LOAD		0x4
-#define REG_MATCH1		0x8
-#define REG_MATCH2		0xC
-
-#define TIMER_CR		0x30
-#define TIMER_INTR_STATE	0x34
-#define TIMER_INTR_MASK		0x38
-
-/*
- * Moxart TIMER_CR flags:
- *
- * MOXART_CR_*_CLOCK	0: PCLK, 1: EXT1CLK
- * MOXART_CR_*_INT	overflow interrupt enable bit
- */
-#define MOXART_CR_1_ENABLE	BIT(0)
-#define MOXART_CR_1_CLOCK	BIT(1)
-#define MOXART_CR_1_INT	BIT(2)
-#define MOXART_CR_2_ENABLE	BIT(3)
-#define MOXART_CR_2_CLOCK	BIT(4)
-#define MOXART_CR_2_INT	BIT(5)
-#define MOXART_CR_3_ENABLE	BIT(6)
-#define MOXART_CR_3_CLOCK	BIT(7)
-#define MOXART_CR_3_INT	BIT(8)
-#define MOXART_CR_COUNT_UP	BIT(9)
-
-#define MOXART_TIMER1_ENABLE	(MOXART_CR_2_ENABLE | MOXART_CR_1_ENABLE)
-#define MOXART_TIMER1_DISABLE	(MOXART_CR_2_ENABLE)
-
-/*
- * The ASpeed variant of the IP block has a different layout
- * for the control register
- */
-#define ASPEED_CR_1_ENABLE	BIT(0)
-#define ASPEED_CR_1_CLOCK	BIT(1)
-#define ASPEED_CR_1_INT		BIT(2)
-#define ASPEED_CR_2_ENABLE	BIT(4)
-#define ASPEED_CR_2_CLOCK	BIT(5)
-#define ASPEED_CR_2_INT		BIT(6)
-#define ASPEED_CR_3_ENABLE	BIT(8)
-#define ASPEED_CR_3_CLOCK	BIT(9)
-#define ASPEED_CR_3_INT		BIT(10)
-
-#define ASPEED_TIMER1_ENABLE   (ASPEED_CR_2_ENABLE | ASPEED_CR_1_ENABLE)
-#define ASPEED_TIMER1_DISABLE  (ASPEED_CR_2_ENABLE)
-
-struct moxart_timer {
-	void __iomem *base;
-	unsigned int t1_disable_val;
-	unsigned int t1_enable_val;
-	unsigned int count_per_tick;
-	struct clock_event_device clkevt;
-};
-
-static inline struct moxart_timer *to_moxart(struct clock_event_device *evt)
-{
-	return container_of(evt, struct moxart_timer, clkevt);
-}
-
-static inline void moxart_disable(struct clock_event_device *evt)
-{
-	struct moxart_timer *timer = to_moxart(evt);
-
-	writel(timer->t1_disable_val, timer->base + TIMER_CR);
-}
-
-static inline void moxart_enable(struct clock_event_device *evt)
-{
-	struct moxart_timer *timer = to_moxart(evt);
-
-	writel(timer->t1_enable_val, timer->base + TIMER_CR);
-}
-
-static int moxart_shutdown(struct clock_event_device *evt)
-{
-	moxart_disable(evt);
-	return 0;
-}
-
-static int moxart_set_oneshot(struct clock_event_device *evt)
-{
-	moxart_disable(evt);
-	writel(~0, to_moxart(evt)->base + TIMER1_BASE + REG_LOAD);
-	return 0;
-}
-
-static int moxart_set_periodic(struct clock_event_device *evt)
-{
-	struct moxart_timer *timer = to_moxart(evt);
-
-	moxart_disable(evt);
-	writel(timer->count_per_tick, timer->base + TIMER1_BASE + REG_LOAD);
-	writel(0, timer->base + TIMER1_BASE + REG_MATCH1);
-	moxart_enable(evt);
-	return 0;
-}
-
-static int moxart_clkevt_next_event(unsigned long cycles,
-				    struct clock_event_device *evt)
-{
-	struct moxart_timer *timer = to_moxart(evt);
-	u32 u;
-
-	moxart_disable(evt);
-
-	u = readl(timer->base + TIMER1_BASE + REG_COUNT) - cycles;
-	writel(u, timer->base + TIMER1_BASE + REG_MATCH1);
-
-	moxart_enable(evt);
-
-	return 0;
-}
-
-static irqreturn_t moxart_timer_interrupt(int irq, void *dev_id)
-{
-	struct clock_event_device *evt = dev_id;
-	evt->event_handler(evt);
-	return IRQ_HANDLED;
-}
-
-static int __init moxart_timer_init(struct device_node *node)
-{
-	int ret, irq;
-	unsigned long pclk;
-	struct clk *clk;
-	struct moxart_timer *timer;
-
-	timer = kzalloc(sizeof(*timer), GFP_KERNEL);
-	if (!timer)
-		return -ENOMEM;
-
-	timer->base = of_iomap(node, 0);
-	if (!timer->base) {
-		pr_err("%s: of_iomap failed\n", node->full_name);
-		ret = -ENXIO;
-		goto out_free;
-	}
-
-	irq = irq_of_parse_and_map(node, 0);
-	if (irq <= 0) {
-		pr_err("%s: irq_of_parse_and_map failed\n", node->full_name);
-		ret = -EINVAL;
-		goto out_unmap;
-	}
-
-	clk = of_clk_get(node, 0);
-	if (IS_ERR(clk))  {
-		pr_err("%s: of_clk_get failed\n", node->full_name);
-		ret = PTR_ERR(clk);
-		goto out_unmap;
-	}
-
-	pclk = clk_get_rate(clk);
-
-	if (of_device_is_compatible(node, "moxa,moxart-timer")) {
-		timer->t1_enable_val = MOXART_TIMER1_ENABLE;
-		timer->t1_disable_val = MOXART_TIMER1_DISABLE;
-	} else if (of_device_is_compatible(node, "aspeed,ast2400-timer")) {
-		timer->t1_enable_val = ASPEED_TIMER1_ENABLE;
-		timer->t1_disable_val = ASPEED_TIMER1_DISABLE;
-	} else {
-		pr_err("%s: unknown platform\n", node->full_name);
-		ret = -EINVAL;
-		goto out_unmap;
-	}
-
-	timer->count_per_tick = DIV_ROUND_CLOSEST(pclk, HZ);
-
-	timer->clkevt.name = node->name;
-	timer->clkevt.rating = 200;
-	timer->clkevt.features = CLOCK_EVT_FEAT_PERIODIC |
-					CLOCK_EVT_FEAT_ONESHOT;
-	timer->clkevt.set_state_shutdown = moxart_shutdown;
-	timer->clkevt.set_state_periodic = moxart_set_periodic;
-	timer->clkevt.set_state_oneshot = moxart_set_oneshot;
-	timer->clkevt.tick_resume = moxart_set_oneshot;
-	timer->clkevt.set_next_event = moxart_clkevt_next_event;
-	timer->clkevt.cpumask = cpumask_of(0);
-	timer->clkevt.irq = irq;
-
-	ret = clocksource_mmio_init(timer->base + TIMER2_BASE + REG_COUNT,
-				    "moxart_timer", pclk, 200, 32,
-				    clocksource_mmio_readl_down);
-	if (ret) {
-		pr_err("%s: clocksource_mmio_init failed\n", node->full_name);
-		goto out_unmap;
-	}
-
-	ret = request_irq(irq, moxart_timer_interrupt, IRQF_TIMER,
-			  node->name, &timer->clkevt);
-	if (ret) {
-		pr_err("%s: setup_irq failed\n", node->full_name);
-		goto out_unmap;
-	}
-
-	/* Clear match registers */
-	writel(0, timer->base + TIMER1_BASE + REG_MATCH1);
-	writel(0, timer->base + TIMER1_BASE + REG_MATCH2);
-	writel(0, timer->base + TIMER2_BASE + REG_MATCH1);
-	writel(0, timer->base + TIMER2_BASE + REG_MATCH2);
-
-	/*
-	 * Start timer 2 rolling as our main wall clock source, keep timer 1
-	 * disabled
-	 */
-	writel(0, timer->base + TIMER_CR);
-	writel(~0, timer->base + TIMER2_BASE + REG_LOAD);
-	writel(timer->t1_disable_val, timer->base + TIMER_CR);
-
-	/*
-	 * documentation is not publicly available:
-	 * min_delta / max_delta obtained by trial-and-error,
-	 * max_delta 0xfffffffe should be ok because count
-	 * register size is u32
-	 */
-	clockevents_config_and_register(&timer->clkevt, pclk, 0x4, 0xfffffffe);
-
-	return 0;
-
-out_unmap:
-	iounmap(timer->base);
-out_free:
-	kfree(timer);
-	return ret;
-}
-CLOCKSOURCE_OF_DECLARE(moxart, "moxa,moxart-timer", moxart_timer_init);
-CLOCKSOURCE_OF_DECLARE(aspeed, "aspeed,ast2400-timer", moxart_timer_init);
diff --git a/drivers/clocksource/timer-fttmr010.c b/drivers/clocksource/timer-fttmr010.c
index 2d915d1455ab..86d5159d3457 100644
--- a/drivers/clocksource/timer-fttmr010.c
+++ b/drivers/clocksource/timer-fttmr010.c
@@ -50,6 +50,20 @@
 #define TIMER_2_CR_UPDOWN	BIT(10)
 #define TIMER_3_CR_UPDOWN	BIT(11)
 
+/* The Aspeed AST2400 moves bits around in the control register */
+#define TIMER_1_CR_ASPEED_ENABLE	BIT(0)
+#define TIMER_1_CR_ASPEED_CLOCK		BIT(1)
+#define TIMER_1_CR_ASPEED_INT		BIT(2)
+#define TIMER_1_CR_ASPEED_UPDOWN	BIT(3)
+#define TIMER_2_CR_ASPEED_ENABLE	BIT(4)
+#define TIMER_2_CR_ASPEED_CLOCK		BIT(5)
+#define TIMER_2_CR_ASPEED_INT		BIT(6)
+#define TIMER_2_CR_ASPEED_UPDOWN	BIT(7)
+#define TIMER_3_CR_ASPEED_ENABLE	BIT(8)
+#define TIMER_3_CR_ASPEED_CLOCK		BIT(9)
+#define TIMER_3_CR_ASPEED_INT		BIT(10)
+#define TIMER_3_CR_ASPEED_UPDOWN	BIT(11)
+
 #define TIMER_1_INT_MATCH1	BIT(0)
 #define TIMER_1_INT_MATCH2	BIT(1)
 #define TIMER_1_INT_OVERFLOW	BIT(2)
@@ -64,6 +78,8 @@
 struct fttmr010 {
 	void __iomem *base;
 	unsigned int tick_rate;
+	bool is_ast2400;
+	u32 t1_enable_val;
 	struct clock_event_device clkevt;
 };
 
@@ -102,7 +118,7 @@ static int fttmr010_timer_shutdown(struct clock_event_device *evt)
 
 	/* Stop timer and interrupt. */
 	cr = readl(fttmr010->base + TIMER_CR);
-	cr &= ~(TIMER_1_CR_ENABLE | TIMER_1_CR_INT);
+	cr &= ~fttmr010->t1_enable_val;
 	writel(cr, fttmr010->base + TIMER_CR);
 
 	return 0;
@@ -115,7 +131,7 @@ static int fttmr010_timer_set_oneshot(struct clock_event_device *evt)
 
 	/* Stop timer and interrupt. */
 	cr = readl(fttmr010->base + TIMER_CR);
-	cr &= ~(TIMER_1_CR_ENABLE | TIMER_1_CR_INT);
+	cr &= ~fttmr010->t1_enable_val;
 	writel(cr, fttmr010->base + TIMER_CR);
 
 	/* Setup counter start from 0 */
@@ -130,7 +146,7 @@ static int fttmr010_timer_set_oneshot(struct clock_event_device *evt)
 
 	/* Start the timer */
 	cr = readl(fttmr010->base + TIMER_CR);
-	cr |= TIMER_1_CR_ENABLE;
+	cr |= fttmr010->t1_enable_val;
 	writel(cr, fttmr010->base + TIMER_CR);
 
 	return 0;
@@ -144,7 +160,7 @@ static int fttmr010_timer_set_periodic(struct clock_event_device *evt)
 
 	/* Stop timer and interrupt */
 	cr = readl(fttmr010->base + TIMER_CR);
-	cr &= ~(TIMER_1_CR_ENABLE | TIMER_1_CR_INT);
+	cr &= ~fttmr010->t1_enable_val;
 	writel(cr, fttmr010->base + TIMER_CR);
 
 	/* Setup timer to fire at 1/HT intervals. */
@@ -160,8 +176,7 @@ static int fttmr010_timer_set_periodic(struct clock_event_device *evt)
 
 	/* Start the timer */
 	cr = readl(fttmr010->base + TIMER_CR);
-	cr |= TIMER_1_CR_ENABLE;
-	cr |= TIMER_1_CR_INT;
+	cr |= fttmr010->t1_enable_val;
 	writel(cr, fttmr010->base + TIMER_CR);
 
 	return 0;
@@ -184,6 +199,7 @@ static int __init fttmr010_timer_init(struct device_node *np)
 	int irq;
 	struct clk *clk;
 	int ret;
+	u32 val;
 
 	/*
 	 * These implementations require a clock reference.
@@ -223,13 +239,31 @@ static int __init fttmr010_timer_init(struct device_node *np)
 	}
 
 	/*
+	 * The Aspeed AST2400 moves bits around in the control register,
+	 * otherwise it works the same.
+	 */
+	fttmr010->is_ast2400 =
+		of_device_is_compatible(np, "aspeed,ast2400-timer");
+	if (fttmr010->is_ast2400)
+		fttmr010->t1_enable_val = TIMER_1_CR_ASPEED_ENABLE |
+			TIMER_1_CR_ASPEED_INT;
+	else
+		fttmr010->t1_enable_val = TIMER_1_CR_ENABLE | TIMER_1_CR_INT;
+
+	/*
 	 * Reset the interrupt mask and status
 	 */
 	writel(TIMER_INT_ALL_MASK, fttmr010->base + TIMER_INTR_MASK);
 	writel(0, fttmr010->base + TIMER_INTR_STATE);
+
 	/* Enable timer 1 count up, timer 2 count up */
-	writel((TIMER_1_CR_UPDOWN | TIMER_2_CR_ENABLE | TIMER_2_CR_UPDOWN),
-	       fttmr010->base + TIMER_CR);
+	if (fttmr010->is_ast2400)
+		val = TIMER_1_CR_ASPEED_UPDOWN | TIMER_2_CR_ASPEED_ENABLE |
+			TIMER_2_CR_ASPEED_UPDOWN;
+	else
+		val = TIMER_1_CR_UPDOWN | TIMER_2_CR_ENABLE |
+			TIMER_2_CR_UPDOWN;
+	writel(val, fttmr010->base + TIMER_CR);
 
 	/*
 	 * Setup free-running clocksource timer (interrupts
@@ -290,3 +324,5 @@ static int __init fttmr010_timer_init(struct device_node *np)
 }
 CLOCKSOURCE_OF_DECLARE(fttmr010, "faraday,fttmr010", fttmr010_timer_init);
 CLOCKSOURCE_OF_DECLARE(gemini, "cortina,gemini-timer", fttmr010_timer_init);
+CLOCKSOURCE_OF_DECLARE(moxart, "moxa,moxart-timer", fttmr010_timer_init);
+CLOCKSOURCE_OF_DECLARE(aspeed, "aspeed,ast2400-timer", fttmr010_timer_init);
-- 
2.9.3

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

* [PATCH 7/8] clocksource/drivers/fttmr010: Merge Moxa into FTTMR010
@ 2017-05-17 14:05   ` Linus Walleij
  0 siblings, 0 replies; 40+ messages in thread
From: Linus Walleij @ 2017-05-17 14:05 UTC (permalink / raw)
  To: linux-arm-kernel

This merges the Moxa Art timer driver into the Faraday FTTMR010
driver and replaces all Kconfig symbols to use the Faraday
driver instead. We are now so similar that the drivers can
be merged by just adding a few lines to the Faraday timer.

Differences:

- The Faraday driver explicitly sets the counter to count
  upwards for the clocksource, removing the need for the
  clocksource core to invert the value.

- The Faraday driver also handles sched_clock()

I am just guessing at the way the Aspeed has moved the count
up/down bits to bits 3, 8 and 11 (keeping the bits pertaining
to a certain timer together), so this really needs testing on
the Aspeed. I'm guessing like this because it is what I would
have done, if I was rewriting some VHDL/Verilog to extend
these three timers to 8 (as the Aspeed apparently does).

After this we have one driver for all three SoCs and a generic
Faraday FTTMR010 timer driver, which is nice.

Cc: Joel Stanley <joel@jms.id.au>
Cc: Jonas Jensen <jonas.jensen@gmail.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
ARM SoC folks: please ACK this so it can be merged with in the
clocksource subsystem once it works.

Joel: it would be super if you can test this. If you have some
vendor tree or similar that actually indicates where the
up/down counter bits are it's even better, but I'm hoping that
this half-assed guesswork will JustWork(TM) (yeah, famous
last words, sorry...)
---
 arch/arm/mach-aspeed/Kconfig         |   2 +-
 arch/arm/mach-moxart/Kconfig         |   2 +-
 drivers/clocksource/Kconfig          |   7 -
 drivers/clocksource/Makefile         |   1 -
 drivers/clocksource/moxart_timer.c   | 256 -----------------------------------
 drivers/clocksource/timer-fttmr010.c |  52 +++++--
 6 files changed, 46 insertions(+), 274 deletions(-)
 delete mode 100644 drivers/clocksource/moxart_timer.c

diff --git a/arch/arm/mach-aspeed/Kconfig b/arch/arm/mach-aspeed/Kconfig
index f3f8c5c658db..2d5570e6e186 100644
--- a/arch/arm/mach-aspeed/Kconfig
+++ b/arch/arm/mach-aspeed/Kconfig
@@ -4,7 +4,7 @@ menuconfig ARCH_ASPEED
 	select SRAM
 	select WATCHDOG
 	select ASPEED_WATCHDOG
-	select MOXART_TIMER
+	select FTTMR010_TIMER
 	select MFD_SYSCON
 	select PINCTRL
 	help
diff --git a/arch/arm/mach-moxart/Kconfig b/arch/arm/mach-moxart/Kconfig
index 70db2abf6163..a4a91f9a3301 100644
--- a/arch/arm/mach-moxart/Kconfig
+++ b/arch/arm/mach-moxart/Kconfig
@@ -4,7 +4,7 @@ menuconfig ARCH_MOXART
 	select CPU_FA526
 	select ARM_DMA_MEM_BUFFERABLE
 	select FARADAY_FTINTC010
-	select MOXART_TIMER
+	select FTTMR010_TIMER
 	select GPIOLIB
 	select PHYLIB if NETDEVICES
 	help
diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index 545d541ae20e..1b22ade4c8f1 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -188,13 +188,6 @@ config ATLAS7_TIMER
 	help
 	  Enables support for the Atlas7 timer.
 
-config MOXART_TIMER
-	bool "Moxart timer driver" if COMPILE_TEST
-	depends on GENERIC_CLOCKEVENTS
-	select CLKSRC_MMIO
-	help
-	  Enables support for the Moxart timer.
-
 config MXS_TIMER
 	bool "Mxs timer driver" if COMPILE_TEST
 	depends on GENERIC_CLOCKEVENTS
diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
index 2b5b56a6f00f..cf0c30b6ec1f 100644
--- a/drivers/clocksource/Makefile
+++ b/drivers/clocksource/Makefile
@@ -26,7 +26,6 @@ obj-$(CONFIG_ORION_TIMER)	+= time-orion.o
 obj-$(CONFIG_BCM2835_TIMER)	+= bcm2835_timer.o
 obj-$(CONFIG_CLPS711X_TIMER)	+= clps711x-timer.o
 obj-$(CONFIG_ATLAS7_TIMER)	+= timer-atlas7.o
-obj-$(CONFIG_MOXART_TIMER)	+= moxart_timer.o
 obj-$(CONFIG_MXS_TIMER)		+= mxs_timer.o
 obj-$(CONFIG_CLKSRC_PXA)	+= pxa_timer.o
 obj-$(CONFIG_PRIMA2_TIMER)	+= timer-prima2.o
diff --git a/drivers/clocksource/moxart_timer.c b/drivers/clocksource/moxart_timer.c
deleted file mode 100644
index 7f3430654fbd..000000000000
--- a/drivers/clocksource/moxart_timer.c
+++ /dev/null
@@ -1,256 +0,0 @@
-/*
- * MOXA ART SoCs timer handling.
- *
- * Copyright (C) 2013 Jonas Jensen
- *
- * Jonas Jensen <jonas.jensen@gmail.com>
- *
- * This file is licensed under the terms of the GNU General Public
- * License version 2.  This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
- */
-
-#include <linux/clk.h>
-#include <linux/clockchips.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/irqreturn.h>
-#include <linux/of.h>
-#include <linux/of_address.h>
-#include <linux/of_irq.h>
-#include <linux/io.h>
-#include <linux/clocksource.h>
-#include <linux/bitops.h>
-#include <linux/slab.h>
-
-#define TIMER1_BASE		0x00
-#define TIMER2_BASE		0x10
-#define TIMER3_BASE		0x20
-
-#define REG_COUNT		0x0 /* writable */
-#define REG_LOAD		0x4
-#define REG_MATCH1		0x8
-#define REG_MATCH2		0xC
-
-#define TIMER_CR		0x30
-#define TIMER_INTR_STATE	0x34
-#define TIMER_INTR_MASK		0x38
-
-/*
- * Moxart TIMER_CR flags:
- *
- * MOXART_CR_*_CLOCK	0: PCLK, 1: EXT1CLK
- * MOXART_CR_*_INT	overflow interrupt enable bit
- */
-#define MOXART_CR_1_ENABLE	BIT(0)
-#define MOXART_CR_1_CLOCK	BIT(1)
-#define MOXART_CR_1_INT	BIT(2)
-#define MOXART_CR_2_ENABLE	BIT(3)
-#define MOXART_CR_2_CLOCK	BIT(4)
-#define MOXART_CR_2_INT	BIT(5)
-#define MOXART_CR_3_ENABLE	BIT(6)
-#define MOXART_CR_3_CLOCK	BIT(7)
-#define MOXART_CR_3_INT	BIT(8)
-#define MOXART_CR_COUNT_UP	BIT(9)
-
-#define MOXART_TIMER1_ENABLE	(MOXART_CR_2_ENABLE | MOXART_CR_1_ENABLE)
-#define MOXART_TIMER1_DISABLE	(MOXART_CR_2_ENABLE)
-
-/*
- * The ASpeed variant of the IP block has a different layout
- * for the control register
- */
-#define ASPEED_CR_1_ENABLE	BIT(0)
-#define ASPEED_CR_1_CLOCK	BIT(1)
-#define ASPEED_CR_1_INT		BIT(2)
-#define ASPEED_CR_2_ENABLE	BIT(4)
-#define ASPEED_CR_2_CLOCK	BIT(5)
-#define ASPEED_CR_2_INT		BIT(6)
-#define ASPEED_CR_3_ENABLE	BIT(8)
-#define ASPEED_CR_3_CLOCK	BIT(9)
-#define ASPEED_CR_3_INT		BIT(10)
-
-#define ASPEED_TIMER1_ENABLE   (ASPEED_CR_2_ENABLE | ASPEED_CR_1_ENABLE)
-#define ASPEED_TIMER1_DISABLE  (ASPEED_CR_2_ENABLE)
-
-struct moxart_timer {
-	void __iomem *base;
-	unsigned int t1_disable_val;
-	unsigned int t1_enable_val;
-	unsigned int count_per_tick;
-	struct clock_event_device clkevt;
-};
-
-static inline struct moxart_timer *to_moxart(struct clock_event_device *evt)
-{
-	return container_of(evt, struct moxart_timer, clkevt);
-}
-
-static inline void moxart_disable(struct clock_event_device *evt)
-{
-	struct moxart_timer *timer = to_moxart(evt);
-
-	writel(timer->t1_disable_val, timer->base + TIMER_CR);
-}
-
-static inline void moxart_enable(struct clock_event_device *evt)
-{
-	struct moxart_timer *timer = to_moxart(evt);
-
-	writel(timer->t1_enable_val, timer->base + TIMER_CR);
-}
-
-static int moxart_shutdown(struct clock_event_device *evt)
-{
-	moxart_disable(evt);
-	return 0;
-}
-
-static int moxart_set_oneshot(struct clock_event_device *evt)
-{
-	moxart_disable(evt);
-	writel(~0, to_moxart(evt)->base + TIMER1_BASE + REG_LOAD);
-	return 0;
-}
-
-static int moxart_set_periodic(struct clock_event_device *evt)
-{
-	struct moxart_timer *timer = to_moxart(evt);
-
-	moxart_disable(evt);
-	writel(timer->count_per_tick, timer->base + TIMER1_BASE + REG_LOAD);
-	writel(0, timer->base + TIMER1_BASE + REG_MATCH1);
-	moxart_enable(evt);
-	return 0;
-}
-
-static int moxart_clkevt_next_event(unsigned long cycles,
-				    struct clock_event_device *evt)
-{
-	struct moxart_timer *timer = to_moxart(evt);
-	u32 u;
-
-	moxart_disable(evt);
-
-	u = readl(timer->base + TIMER1_BASE + REG_COUNT) - cycles;
-	writel(u, timer->base + TIMER1_BASE + REG_MATCH1);
-
-	moxart_enable(evt);
-
-	return 0;
-}
-
-static irqreturn_t moxart_timer_interrupt(int irq, void *dev_id)
-{
-	struct clock_event_device *evt = dev_id;
-	evt->event_handler(evt);
-	return IRQ_HANDLED;
-}
-
-static int __init moxart_timer_init(struct device_node *node)
-{
-	int ret, irq;
-	unsigned long pclk;
-	struct clk *clk;
-	struct moxart_timer *timer;
-
-	timer = kzalloc(sizeof(*timer), GFP_KERNEL);
-	if (!timer)
-		return -ENOMEM;
-
-	timer->base = of_iomap(node, 0);
-	if (!timer->base) {
-		pr_err("%s: of_iomap failed\n", node->full_name);
-		ret = -ENXIO;
-		goto out_free;
-	}
-
-	irq = irq_of_parse_and_map(node, 0);
-	if (irq <= 0) {
-		pr_err("%s: irq_of_parse_and_map failed\n", node->full_name);
-		ret = -EINVAL;
-		goto out_unmap;
-	}
-
-	clk = of_clk_get(node, 0);
-	if (IS_ERR(clk))  {
-		pr_err("%s: of_clk_get failed\n", node->full_name);
-		ret = PTR_ERR(clk);
-		goto out_unmap;
-	}
-
-	pclk = clk_get_rate(clk);
-
-	if (of_device_is_compatible(node, "moxa,moxart-timer")) {
-		timer->t1_enable_val = MOXART_TIMER1_ENABLE;
-		timer->t1_disable_val = MOXART_TIMER1_DISABLE;
-	} else if (of_device_is_compatible(node, "aspeed,ast2400-timer")) {
-		timer->t1_enable_val = ASPEED_TIMER1_ENABLE;
-		timer->t1_disable_val = ASPEED_TIMER1_DISABLE;
-	} else {
-		pr_err("%s: unknown platform\n", node->full_name);
-		ret = -EINVAL;
-		goto out_unmap;
-	}
-
-	timer->count_per_tick = DIV_ROUND_CLOSEST(pclk, HZ);
-
-	timer->clkevt.name = node->name;
-	timer->clkevt.rating = 200;
-	timer->clkevt.features = CLOCK_EVT_FEAT_PERIODIC |
-					CLOCK_EVT_FEAT_ONESHOT;
-	timer->clkevt.set_state_shutdown = moxart_shutdown;
-	timer->clkevt.set_state_periodic = moxart_set_periodic;
-	timer->clkevt.set_state_oneshot = moxart_set_oneshot;
-	timer->clkevt.tick_resume = moxart_set_oneshot;
-	timer->clkevt.set_next_event = moxart_clkevt_next_event;
-	timer->clkevt.cpumask = cpumask_of(0);
-	timer->clkevt.irq = irq;
-
-	ret = clocksource_mmio_init(timer->base + TIMER2_BASE + REG_COUNT,
-				    "moxart_timer", pclk, 200, 32,
-				    clocksource_mmio_readl_down);
-	if (ret) {
-		pr_err("%s: clocksource_mmio_init failed\n", node->full_name);
-		goto out_unmap;
-	}
-
-	ret = request_irq(irq, moxart_timer_interrupt, IRQF_TIMER,
-			  node->name, &timer->clkevt);
-	if (ret) {
-		pr_err("%s: setup_irq failed\n", node->full_name);
-		goto out_unmap;
-	}
-
-	/* Clear match registers */
-	writel(0, timer->base + TIMER1_BASE + REG_MATCH1);
-	writel(0, timer->base + TIMER1_BASE + REG_MATCH2);
-	writel(0, timer->base + TIMER2_BASE + REG_MATCH1);
-	writel(0, timer->base + TIMER2_BASE + REG_MATCH2);
-
-	/*
-	 * Start timer 2 rolling as our main wall clock source, keep timer 1
-	 * disabled
-	 */
-	writel(0, timer->base + TIMER_CR);
-	writel(~0, timer->base + TIMER2_BASE + REG_LOAD);
-	writel(timer->t1_disable_val, timer->base + TIMER_CR);
-
-	/*
-	 * documentation is not publicly available:
-	 * min_delta / max_delta obtained by trial-and-error,
-	 * max_delta 0xfffffffe should be ok because count
-	 * register size is u32
-	 */
-	clockevents_config_and_register(&timer->clkevt, pclk, 0x4, 0xfffffffe);
-
-	return 0;
-
-out_unmap:
-	iounmap(timer->base);
-out_free:
-	kfree(timer);
-	return ret;
-}
-CLOCKSOURCE_OF_DECLARE(moxart, "moxa,moxart-timer", moxart_timer_init);
-CLOCKSOURCE_OF_DECLARE(aspeed, "aspeed,ast2400-timer", moxart_timer_init);
diff --git a/drivers/clocksource/timer-fttmr010.c b/drivers/clocksource/timer-fttmr010.c
index 2d915d1455ab..86d5159d3457 100644
--- a/drivers/clocksource/timer-fttmr010.c
+++ b/drivers/clocksource/timer-fttmr010.c
@@ -50,6 +50,20 @@
 #define TIMER_2_CR_UPDOWN	BIT(10)
 #define TIMER_3_CR_UPDOWN	BIT(11)
 
+/* The Aspeed AST2400 moves bits around in the control register */
+#define TIMER_1_CR_ASPEED_ENABLE	BIT(0)
+#define TIMER_1_CR_ASPEED_CLOCK		BIT(1)
+#define TIMER_1_CR_ASPEED_INT		BIT(2)
+#define TIMER_1_CR_ASPEED_UPDOWN	BIT(3)
+#define TIMER_2_CR_ASPEED_ENABLE	BIT(4)
+#define TIMER_2_CR_ASPEED_CLOCK		BIT(5)
+#define TIMER_2_CR_ASPEED_INT		BIT(6)
+#define TIMER_2_CR_ASPEED_UPDOWN	BIT(7)
+#define TIMER_3_CR_ASPEED_ENABLE	BIT(8)
+#define TIMER_3_CR_ASPEED_CLOCK		BIT(9)
+#define TIMER_3_CR_ASPEED_INT		BIT(10)
+#define TIMER_3_CR_ASPEED_UPDOWN	BIT(11)
+
 #define TIMER_1_INT_MATCH1	BIT(0)
 #define TIMER_1_INT_MATCH2	BIT(1)
 #define TIMER_1_INT_OVERFLOW	BIT(2)
@@ -64,6 +78,8 @@
 struct fttmr010 {
 	void __iomem *base;
 	unsigned int tick_rate;
+	bool is_ast2400;
+	u32 t1_enable_val;
 	struct clock_event_device clkevt;
 };
 
@@ -102,7 +118,7 @@ static int fttmr010_timer_shutdown(struct clock_event_device *evt)
 
 	/* Stop timer and interrupt. */
 	cr = readl(fttmr010->base + TIMER_CR);
-	cr &= ~(TIMER_1_CR_ENABLE | TIMER_1_CR_INT);
+	cr &= ~fttmr010->t1_enable_val;
 	writel(cr, fttmr010->base + TIMER_CR);
 
 	return 0;
@@ -115,7 +131,7 @@ static int fttmr010_timer_set_oneshot(struct clock_event_device *evt)
 
 	/* Stop timer and interrupt. */
 	cr = readl(fttmr010->base + TIMER_CR);
-	cr &= ~(TIMER_1_CR_ENABLE | TIMER_1_CR_INT);
+	cr &= ~fttmr010->t1_enable_val;
 	writel(cr, fttmr010->base + TIMER_CR);
 
 	/* Setup counter start from 0 */
@@ -130,7 +146,7 @@ static int fttmr010_timer_set_oneshot(struct clock_event_device *evt)
 
 	/* Start the timer */
 	cr = readl(fttmr010->base + TIMER_CR);
-	cr |= TIMER_1_CR_ENABLE;
+	cr |= fttmr010->t1_enable_val;
 	writel(cr, fttmr010->base + TIMER_CR);
 
 	return 0;
@@ -144,7 +160,7 @@ static int fttmr010_timer_set_periodic(struct clock_event_device *evt)
 
 	/* Stop timer and interrupt */
 	cr = readl(fttmr010->base + TIMER_CR);
-	cr &= ~(TIMER_1_CR_ENABLE | TIMER_1_CR_INT);
+	cr &= ~fttmr010->t1_enable_val;
 	writel(cr, fttmr010->base + TIMER_CR);
 
 	/* Setup timer to fire at 1/HT intervals. */
@@ -160,8 +176,7 @@ static int fttmr010_timer_set_periodic(struct clock_event_device *evt)
 
 	/* Start the timer */
 	cr = readl(fttmr010->base + TIMER_CR);
-	cr |= TIMER_1_CR_ENABLE;
-	cr |= TIMER_1_CR_INT;
+	cr |= fttmr010->t1_enable_val;
 	writel(cr, fttmr010->base + TIMER_CR);
 
 	return 0;
@@ -184,6 +199,7 @@ static int __init fttmr010_timer_init(struct device_node *np)
 	int irq;
 	struct clk *clk;
 	int ret;
+	u32 val;
 
 	/*
 	 * These implementations require a clock reference.
@@ -223,13 +239,31 @@ static int __init fttmr010_timer_init(struct device_node *np)
 	}
 
 	/*
+	 * The Aspeed AST2400 moves bits around in the control register,
+	 * otherwise it works the same.
+	 */
+	fttmr010->is_ast2400 =
+		of_device_is_compatible(np, "aspeed,ast2400-timer");
+	if (fttmr010->is_ast2400)
+		fttmr010->t1_enable_val = TIMER_1_CR_ASPEED_ENABLE |
+			TIMER_1_CR_ASPEED_INT;
+	else
+		fttmr010->t1_enable_val = TIMER_1_CR_ENABLE | TIMER_1_CR_INT;
+
+	/*
 	 * Reset the interrupt mask and status
 	 */
 	writel(TIMER_INT_ALL_MASK, fttmr010->base + TIMER_INTR_MASK);
 	writel(0, fttmr010->base + TIMER_INTR_STATE);
+
 	/* Enable timer 1 count up, timer 2 count up */
-	writel((TIMER_1_CR_UPDOWN | TIMER_2_CR_ENABLE | TIMER_2_CR_UPDOWN),
-	       fttmr010->base + TIMER_CR);
+	if (fttmr010->is_ast2400)
+		val = TIMER_1_CR_ASPEED_UPDOWN | TIMER_2_CR_ASPEED_ENABLE |
+			TIMER_2_CR_ASPEED_UPDOWN;
+	else
+		val = TIMER_1_CR_UPDOWN | TIMER_2_CR_ENABLE |
+			TIMER_2_CR_UPDOWN;
+	writel(val, fttmr010->base + TIMER_CR);
 
 	/*
 	 * Setup free-running clocksource timer (interrupts
@@ -290,3 +324,5 @@ static int __init fttmr010_timer_init(struct device_node *np)
 }
 CLOCKSOURCE_OF_DECLARE(fttmr010, "faraday,fttmr010", fttmr010_timer_init);
 CLOCKSOURCE_OF_DECLARE(gemini, "cortina,gemini-timer", fttmr010_timer_init);
+CLOCKSOURCE_OF_DECLARE(moxart, "moxa,moxart-timer", fttmr010_timer_init);
+CLOCKSOURCE_OF_DECLARE(aspeed, "aspeed,ast2400-timer", fttmr010_timer_init);
-- 
2.9.3

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

* [PATCH 8/8] ARM: dts: augment Moxa and Aspeed DTS for FTTMR010
  2017-05-17 14:05 ` Linus Walleij
@ 2017-05-17 14:05   ` Linus Walleij
  -1 siblings, 0 replies; 40+ messages in thread
From: Linus Walleij @ 2017-05-17 14:05 UTC (permalink / raw)
  To: Daniel Lezcano, Thomas Gleixner, Joel Stanley, Jonas Jensen
  Cc: Janos Laube, Paulius Zaleckas, linux-arm-kernel, Hans Ulli Kroll,
	Florian Fainelli, linux-kernel, Linus Walleij

This augments the Moxa Art and Aspeed device trees to:

- Explicitly name the clock "PCLK" as the Faraday FTTMR010
  names it.
- List the Moxa timer as compatible with the Faradat FTTMR010
  vanilla version.
- Add a comment that the Aspeed driver is a Faraday
  FTTMR010 derivative.
- Pass all IRQs to the timer from Aspeed: they are all there
  so they should be in the device tree, we only use the
  first one anyways.

Cc: Joel Stanley <joel@jms.id.au>
Cc: Jonas Jensen <jonas.jensen@gmail.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
Clocksource maintainers: I will ask the ARM SoC people to merge
this patch orthogonally, it is only included in this series
for reference and for testing.
---
 arch/arm/boot/dts/aspeed-g4.dtsi | 7 +++----
 arch/arm/boot/dts/aspeed-g5.dtsi | 6 +++---
 arch/arm/boot/dts/moxart.dtsi    | 3 ++-
 3 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/arch/arm/boot/dts/aspeed-g4.dtsi b/arch/arm/boot/dts/aspeed-g4.dtsi
index 8c6bc29eb7f6..8a04c7e2d818 100644
--- a/arch/arm/boot/dts/aspeed-g4.dtsi
+++ b/arch/arm/boot/dts/aspeed-g4.dtsi
@@ -886,13 +886,12 @@
 			};
 
 			timer: timer@1e782000 {
+				/* This timer is a Faraday FTTMR010 derivative */
 				compatible = "aspeed,ast2400-timer";
 				reg = <0x1e782000 0x90>;
-				// The moxart_timer driver registers only one
-				// interrupt and assumes it's for timer 1
-				//interrupts = <16 17 18 35 36 37 38 39>;
-				interrupts = <16>;
+				interrupts = <16 17 18 35 36 37 38 39>;
 				clocks = <&clk_apb>;
+				clock-names = "PCLK";
 			};
 
 			wdt1: wdt@1e785000 {
diff --git a/arch/arm/boot/dts/aspeed-g5.dtsi b/arch/arm/boot/dts/aspeed-g5.dtsi
index a0bea4a6ec77..2b613fb61804 100644
--- a/arch/arm/boot/dts/aspeed-g5.dtsi
+++ b/arch/arm/boot/dts/aspeed-g5.dtsi
@@ -993,13 +993,13 @@
 			};
 
 			timer: timer@1e782000 {
+				/* This timer is a Faraday FTTMR010 derivative */
 				compatible = "aspeed,ast2400-timer";
 				reg = <0x1e782000 0x90>;
-				// The moxart_timer driver registers only one
-				// interrupt and assumes it's for timer 1
-				//interrupts = <16 17 18 35 36 37 38 39>;
+				interrupts = <16 17 18 35 36 37 38 39>;
 				interrupts = <16>;
 				clocks = <&clk_apb>;
+				clock-names = "PCLK";
 			};
 
 
diff --git a/arch/arm/boot/dts/moxart.dtsi b/arch/arm/boot/dts/moxart.dtsi
index e86f8c905ac5..1f4c795d3f72 100644
--- a/arch/arm/boot/dts/moxart.dtsi
+++ b/arch/arm/boot/dts/moxart.dtsi
@@ -58,10 +58,11 @@
 		};
 
 		timer: timer@98400000 {
-			compatible = "moxa,moxart-timer";
+			compatible = "moxa,moxart-timer", "faraday,fttmr010";
 			reg = <0x98400000 0x42>;
 			interrupts = <19 IRQ_TYPE_EDGE_FALLING>;
 			clocks = <&clk_apb>;
+			clock-names = "PCLK";
 		};
 
 		gpio: gpio@98700000 {
-- 
2.9.3

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

* [PATCH 8/8] ARM: dts: augment Moxa and Aspeed DTS for FTTMR010
@ 2017-05-17 14:05   ` Linus Walleij
  0 siblings, 0 replies; 40+ messages in thread
From: Linus Walleij @ 2017-05-17 14:05 UTC (permalink / raw)
  To: linux-arm-kernel

This augments the Moxa Art and Aspeed device trees to:

- Explicitly name the clock "PCLK" as the Faraday FTTMR010
  names it.
- List the Moxa timer as compatible with the Faradat FTTMR010
  vanilla version.
- Add a comment that the Aspeed driver is a Faraday
  FTTMR010 derivative.
- Pass all IRQs to the timer from Aspeed: they are all there
  so they should be in the device tree, we only use the
  first one anyways.

Cc: Joel Stanley <joel@jms.id.au>
Cc: Jonas Jensen <jonas.jensen@gmail.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
Clocksource maintainers: I will ask the ARM SoC people to merge
this patch orthogonally, it is only included in this series
for reference and for testing.
---
 arch/arm/boot/dts/aspeed-g4.dtsi | 7 +++----
 arch/arm/boot/dts/aspeed-g5.dtsi | 6 +++---
 arch/arm/boot/dts/moxart.dtsi    | 3 ++-
 3 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/arch/arm/boot/dts/aspeed-g4.dtsi b/arch/arm/boot/dts/aspeed-g4.dtsi
index 8c6bc29eb7f6..8a04c7e2d818 100644
--- a/arch/arm/boot/dts/aspeed-g4.dtsi
+++ b/arch/arm/boot/dts/aspeed-g4.dtsi
@@ -886,13 +886,12 @@
 			};
 
 			timer: timer at 1e782000 {
+				/* This timer is a Faraday FTTMR010 derivative */
 				compatible = "aspeed,ast2400-timer";
 				reg = <0x1e782000 0x90>;
-				// The moxart_timer driver registers only one
-				// interrupt and assumes it's for timer 1
-				//interrupts = <16 17 18 35 36 37 38 39>;
-				interrupts = <16>;
+				interrupts = <16 17 18 35 36 37 38 39>;
 				clocks = <&clk_apb>;
+				clock-names = "PCLK";
 			};
 
 			wdt1: wdt at 1e785000 {
diff --git a/arch/arm/boot/dts/aspeed-g5.dtsi b/arch/arm/boot/dts/aspeed-g5.dtsi
index a0bea4a6ec77..2b613fb61804 100644
--- a/arch/arm/boot/dts/aspeed-g5.dtsi
+++ b/arch/arm/boot/dts/aspeed-g5.dtsi
@@ -993,13 +993,13 @@
 			};
 
 			timer: timer at 1e782000 {
+				/* This timer is a Faraday FTTMR010 derivative */
 				compatible = "aspeed,ast2400-timer";
 				reg = <0x1e782000 0x90>;
-				// The moxart_timer driver registers only one
-				// interrupt and assumes it's for timer 1
-				//interrupts = <16 17 18 35 36 37 38 39>;
+				interrupts = <16 17 18 35 36 37 38 39>;
 				interrupts = <16>;
 				clocks = <&clk_apb>;
+				clock-names = "PCLK";
 			};
 
 
diff --git a/arch/arm/boot/dts/moxart.dtsi b/arch/arm/boot/dts/moxart.dtsi
index e86f8c905ac5..1f4c795d3f72 100644
--- a/arch/arm/boot/dts/moxart.dtsi
+++ b/arch/arm/boot/dts/moxart.dtsi
@@ -58,10 +58,11 @@
 		};
 
 		timer: timer at 98400000 {
-			compatible = "moxa,moxart-timer";
+			compatible = "moxa,moxart-timer", "faraday,fttmr010";
 			reg = <0x98400000 0x42>;
 			interrupts = <19 IRQ_TYPE_EDGE_FALLING>;
 			clocks = <&clk_apb>;
+			clock-names = "PCLK";
 		};
 
 		gpio: gpio at 98700000 {
-- 
2.9.3

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

* Re: [PATCH 7/8] clocksource/drivers/fttmr010: Merge Moxa into FTTMR010
  2017-05-17 14:05   ` Linus Walleij
@ 2017-05-18  7:22     ` Joel Stanley
  -1 siblings, 0 replies; 40+ messages in thread
From: Joel Stanley @ 2017-05-18  7:22 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Daniel Lezcano, Thomas Gleixner, Jonas Jensen, Janos Laube,
	Paulius Zaleckas, linux-arm-kernel, Hans Ulli Kroll,
	Florian Fainelli, Linux Kernel Mailing List,
	Benjamin Herrenschmidt, Ryan Chen, Cédric Le Goater

Hey Linus,

On Wed, May 17, 2017 at 10:05 PM, Linus Walleij
<linus.walleij@linaro.org> wrote:
> This merges the Moxa Art timer driver into the Faraday FTTMR010
> driver and replaces all Kconfig symbols to use the Faraday
> driver instead. We are now so similar that the drivers can
> be merged by just adding a few lines to the Faraday timer.

Nice work!

I gave this a spin on hardware and it didn't work :(

>
> Differences:
>
> - The Faraday driver explicitly sets the counter to count
>   upwards for the clocksource, removing the need for the
>   clocksource core to invert the value.
>
> - The Faraday driver also handles sched_clock()
>
> I am just guessing at the way the Aspeed has moved the count
> up/down bits to bits 3, 8 and 11 (keeping the bits pertaining
> to a certain timer together), so this really needs testing on
> the Aspeed. I'm guessing like this because it is what I would
> have done, if I was rewriting some VHDL/Verilog to extend
> these three timers to 8 (as the Aspeed apparently does).
>
> After this we have one driver for all three SoCs and a generic
> Faraday FTTMR010 timer driver, which is nice.
>
> Cc: Joel Stanley <joel@jms.id.au>
> Cc: Jonas Jensen <jonas.jensen@gmail.com>
> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
> ---
> ARM SoC folks: please ACK this so it can be merged with in the
> clocksource subsystem once it works.
>
> Joel: it would be super if you can test this. If you have some
> vendor tree or similar that actually indicates where the
> up/down counter bits are it's even better, but I'm hoping that
> this half-assed guesswork will JustWork(TM) (yeah, famous
> last words, sorry...)

Thanks for the rework! Unfortunately the Aspeed IP does not have bits
to control the direction of counting, and the timers only count down.
Bits 3, 7 and 11 are marked reserved in the data sheet. Can you rework
the patch to count down?

As an aside, we have a pretty decent model for the Aspeed SoCs in
Qemu. If you want to use it to smoketest your rework:

 $ qemu-system-arm -m 512 -M ast2500-evb -nodefaults -nographic
-serial stdio -kernel arch/arm/boot/zImage -dtb
arch/arm/boot/dts/aspeed-ast2500-evb.dtb

I tested with Ubuntu's qemu v2.8. It looks like we have a bug when the
kernel tries to use the clock the way your driver works, so we will
look at that. It does function properly for the current upstream code.

Cheers,

Joel

> ---
>  arch/arm/mach-aspeed/Kconfig         |   2 +-
>  arch/arm/mach-moxart/Kconfig         |   2 +-
>  drivers/clocksource/Kconfig          |   7 -
>  drivers/clocksource/Makefile         |   1 -
>  drivers/clocksource/moxart_timer.c   | 256 -----------------------------------
>  drivers/clocksource/timer-fttmr010.c |  52 +++++--
>  6 files changed, 46 insertions(+), 274 deletions(-)
>  delete mode 100644 drivers/clocksource/moxart_timer.c
>
> diff --git a/arch/arm/mach-aspeed/Kconfig b/arch/arm/mach-aspeed/Kconfig
> index f3f8c5c658db..2d5570e6e186 100644
> --- a/arch/arm/mach-aspeed/Kconfig
> +++ b/arch/arm/mach-aspeed/Kconfig
> @@ -4,7 +4,7 @@ menuconfig ARCH_ASPEED
>         select SRAM
>         select WATCHDOG
>         select ASPEED_WATCHDOG
> -       select MOXART_TIMER
> +       select FTTMR010_TIMER
>         select MFD_SYSCON
>         select PINCTRL
>         help
> diff --git a/arch/arm/mach-moxart/Kconfig b/arch/arm/mach-moxart/Kconfig
> index 70db2abf6163..a4a91f9a3301 100644
> --- a/arch/arm/mach-moxart/Kconfig
> +++ b/arch/arm/mach-moxart/Kconfig
> @@ -4,7 +4,7 @@ menuconfig ARCH_MOXART
>         select CPU_FA526
>         select ARM_DMA_MEM_BUFFERABLE
>         select FARADAY_FTINTC010
> -       select MOXART_TIMER
> +       select FTTMR010_TIMER
>         select GPIOLIB
>         select PHYLIB if NETDEVICES
>         help
> diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
> index 545d541ae20e..1b22ade4c8f1 100644
> --- a/drivers/clocksource/Kconfig
> +++ b/drivers/clocksource/Kconfig
> @@ -188,13 +188,6 @@ config ATLAS7_TIMER
>         help
>           Enables support for the Atlas7 timer.
>
> -config MOXART_TIMER
> -       bool "Moxart timer driver" if COMPILE_TEST
> -       depends on GENERIC_CLOCKEVENTS
> -       select CLKSRC_MMIO
> -       help
> -         Enables support for the Moxart timer.
> -
>  config MXS_TIMER
>         bool "Mxs timer driver" if COMPILE_TEST
>         depends on GENERIC_CLOCKEVENTS
> diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
> index 2b5b56a6f00f..cf0c30b6ec1f 100644
> --- a/drivers/clocksource/Makefile
> +++ b/drivers/clocksource/Makefile
> @@ -26,7 +26,6 @@ obj-$(CONFIG_ORION_TIMER)     += time-orion.o
>  obj-$(CONFIG_BCM2835_TIMER)    += bcm2835_timer.o
>  obj-$(CONFIG_CLPS711X_TIMER)   += clps711x-timer.o
>  obj-$(CONFIG_ATLAS7_TIMER)     += timer-atlas7.o
> -obj-$(CONFIG_MOXART_TIMER)     += moxart_timer.o
>  obj-$(CONFIG_MXS_TIMER)                += mxs_timer.o
>  obj-$(CONFIG_CLKSRC_PXA)       += pxa_timer.o
>  obj-$(CONFIG_PRIMA2_TIMER)     += timer-prima2.o
> diff --git a/drivers/clocksource/moxart_timer.c b/drivers/clocksource/moxart_timer.c
> deleted file mode 100644
> index 7f3430654fbd..000000000000
> --- a/drivers/clocksource/moxart_timer.c
> +++ /dev/null
> @@ -1,256 +0,0 @@
> -/*
> - * MOXA ART SoCs timer handling.
> - *
> - * Copyright (C) 2013 Jonas Jensen
> - *
> - * Jonas Jensen <jonas.jensen@gmail.com>
> - *
> - * This file is licensed under the terms of the GNU General Public
> - * License version 2.  This program is licensed "as is" without any
> - * warranty of any kind, whether express or implied.
> - */
> -
> -#include <linux/clk.h>
> -#include <linux/clockchips.h>
> -#include <linux/interrupt.h>
> -#include <linux/irq.h>
> -#include <linux/irqreturn.h>
> -#include <linux/of.h>
> -#include <linux/of_address.h>
> -#include <linux/of_irq.h>
> -#include <linux/io.h>
> -#include <linux/clocksource.h>
> -#include <linux/bitops.h>
> -#include <linux/slab.h>
> -
> -#define TIMER1_BASE            0x00
> -#define TIMER2_BASE            0x10
> -#define TIMER3_BASE            0x20
> -
> -#define REG_COUNT              0x0 /* writable */
> -#define REG_LOAD               0x4
> -#define REG_MATCH1             0x8
> -#define REG_MATCH2             0xC
> -
> -#define TIMER_CR               0x30
> -#define TIMER_INTR_STATE       0x34
> -#define TIMER_INTR_MASK                0x38
> -
> -/*
> - * Moxart TIMER_CR flags:
> - *
> - * MOXART_CR_*_CLOCK   0: PCLK, 1: EXT1CLK
> - * MOXART_CR_*_INT     overflow interrupt enable bit
> - */
> -#define MOXART_CR_1_ENABLE     BIT(0)
> -#define MOXART_CR_1_CLOCK      BIT(1)
> -#define MOXART_CR_1_INT        BIT(2)
> -#define MOXART_CR_2_ENABLE     BIT(3)
> -#define MOXART_CR_2_CLOCK      BIT(4)
> -#define MOXART_CR_2_INT        BIT(5)
> -#define MOXART_CR_3_ENABLE     BIT(6)
> -#define MOXART_CR_3_CLOCK      BIT(7)
> -#define MOXART_CR_3_INT        BIT(8)
> -#define MOXART_CR_COUNT_UP     BIT(9)
> -
> -#define MOXART_TIMER1_ENABLE   (MOXART_CR_2_ENABLE | MOXART_CR_1_ENABLE)
> -#define MOXART_TIMER1_DISABLE  (MOXART_CR_2_ENABLE)
> -
> -/*
> - * The ASpeed variant of the IP block has a different layout
> - * for the control register
> - */
> -#define ASPEED_CR_1_ENABLE     BIT(0)
> -#define ASPEED_CR_1_CLOCK      BIT(1)
> -#define ASPEED_CR_1_INT                BIT(2)
> -#define ASPEED_CR_2_ENABLE     BIT(4)
> -#define ASPEED_CR_2_CLOCK      BIT(5)
> -#define ASPEED_CR_2_INT                BIT(6)
> -#define ASPEED_CR_3_ENABLE     BIT(8)
> -#define ASPEED_CR_3_CLOCK      BIT(9)
> -#define ASPEED_CR_3_INT                BIT(10)
> -
> -#define ASPEED_TIMER1_ENABLE   (ASPEED_CR_2_ENABLE | ASPEED_CR_1_ENABLE)
> -#define ASPEED_TIMER1_DISABLE  (ASPEED_CR_2_ENABLE)
> -
> -struct moxart_timer {
> -       void __iomem *base;
> -       unsigned int t1_disable_val;
> -       unsigned int t1_enable_val;
> -       unsigned int count_per_tick;
> -       struct clock_event_device clkevt;
> -};
> -
> -static inline struct moxart_timer *to_moxart(struct clock_event_device *evt)
> -{
> -       return container_of(evt, struct moxart_timer, clkevt);
> -}
> -
> -static inline void moxart_disable(struct clock_event_device *evt)
> -{
> -       struct moxart_timer *timer = to_moxart(evt);
> -
> -       writel(timer->t1_disable_val, timer->base + TIMER_CR);
> -}
> -
> -static inline void moxart_enable(struct clock_event_device *evt)
> -{
> -       struct moxart_timer *timer = to_moxart(evt);
> -
> -       writel(timer->t1_enable_val, timer->base + TIMER_CR);
> -}
> -
> -static int moxart_shutdown(struct clock_event_device *evt)
> -{
> -       moxart_disable(evt);
> -       return 0;
> -}
> -
> -static int moxart_set_oneshot(struct clock_event_device *evt)
> -{
> -       moxart_disable(evt);
> -       writel(~0, to_moxart(evt)->base + TIMER1_BASE + REG_LOAD);
> -       return 0;
> -}
> -
> -static int moxart_set_periodic(struct clock_event_device *evt)
> -{
> -       struct moxart_timer *timer = to_moxart(evt);
> -
> -       moxart_disable(evt);
> -       writel(timer->count_per_tick, timer->base + TIMER1_BASE + REG_LOAD);
> -       writel(0, timer->base + TIMER1_BASE + REG_MATCH1);
> -       moxart_enable(evt);
> -       return 0;
> -}
> -
> -static int moxart_clkevt_next_event(unsigned long cycles,
> -                                   struct clock_event_device *evt)
> -{
> -       struct moxart_timer *timer = to_moxart(evt);
> -       u32 u;
> -
> -       moxart_disable(evt);
> -
> -       u = readl(timer->base + TIMER1_BASE + REG_COUNT) - cycles;
> -       writel(u, timer->base + TIMER1_BASE + REG_MATCH1);
> -
> -       moxart_enable(evt);
> -
> -       return 0;
> -}
> -
> -static irqreturn_t moxart_timer_interrupt(int irq, void *dev_id)
> -{
> -       struct clock_event_device *evt = dev_id;
> -       evt->event_handler(evt);
> -       return IRQ_HANDLED;
> -}
> -
> -static int __init moxart_timer_init(struct device_node *node)
> -{
> -       int ret, irq;
> -       unsigned long pclk;
> -       struct clk *clk;
> -       struct moxart_timer *timer;
> -
> -       timer = kzalloc(sizeof(*timer), GFP_KERNEL);
> -       if (!timer)
> -               return -ENOMEM;
> -
> -       timer->base = of_iomap(node, 0);
> -       if (!timer->base) {
> -               pr_err("%s: of_iomap failed\n", node->full_name);
> -               ret = -ENXIO;
> -               goto out_free;
> -       }
> -
> -       irq = irq_of_parse_and_map(node, 0);
> -       if (irq <= 0) {
> -               pr_err("%s: irq_of_parse_and_map failed\n", node->full_name);
> -               ret = -EINVAL;
> -               goto out_unmap;
> -       }
> -
> -       clk = of_clk_get(node, 0);
> -       if (IS_ERR(clk))  {
> -               pr_err("%s: of_clk_get failed\n", node->full_name);
> -               ret = PTR_ERR(clk);
> -               goto out_unmap;
> -       }
> -
> -       pclk = clk_get_rate(clk);
> -
> -       if (of_device_is_compatible(node, "moxa,moxart-timer")) {
> -               timer->t1_enable_val = MOXART_TIMER1_ENABLE;
> -               timer->t1_disable_val = MOXART_TIMER1_DISABLE;
> -       } else if (of_device_is_compatible(node, "aspeed,ast2400-timer")) {
> -               timer->t1_enable_val = ASPEED_TIMER1_ENABLE;
> -               timer->t1_disable_val = ASPEED_TIMER1_DISABLE;
> -       } else {
> -               pr_err("%s: unknown platform\n", node->full_name);
> -               ret = -EINVAL;
> -               goto out_unmap;
> -       }
> -
> -       timer->count_per_tick = DIV_ROUND_CLOSEST(pclk, HZ);
> -
> -       timer->clkevt.name = node->name;
> -       timer->clkevt.rating = 200;
> -       timer->clkevt.features = CLOCK_EVT_FEAT_PERIODIC |
> -                                       CLOCK_EVT_FEAT_ONESHOT;
> -       timer->clkevt.set_state_shutdown = moxart_shutdown;
> -       timer->clkevt.set_state_periodic = moxart_set_periodic;
> -       timer->clkevt.set_state_oneshot = moxart_set_oneshot;
> -       timer->clkevt.tick_resume = moxart_set_oneshot;
> -       timer->clkevt.set_next_event = moxart_clkevt_next_event;
> -       timer->clkevt.cpumask = cpumask_of(0);
> -       timer->clkevt.irq = irq;
> -
> -       ret = clocksource_mmio_init(timer->base + TIMER2_BASE + REG_COUNT,
> -                                   "moxart_timer", pclk, 200, 32,
> -                                   clocksource_mmio_readl_down);
> -       if (ret) {
> -               pr_err("%s: clocksource_mmio_init failed\n", node->full_name);
> -               goto out_unmap;
> -       }
> -
> -       ret = request_irq(irq, moxart_timer_interrupt, IRQF_TIMER,
> -                         node->name, &timer->clkevt);
> -       if (ret) {
> -               pr_err("%s: setup_irq failed\n", node->full_name);
> -               goto out_unmap;
> -       }
> -
> -       /* Clear match registers */
> -       writel(0, timer->base + TIMER1_BASE + REG_MATCH1);
> -       writel(0, timer->base + TIMER1_BASE + REG_MATCH2);
> -       writel(0, timer->base + TIMER2_BASE + REG_MATCH1);
> -       writel(0, timer->base + TIMER2_BASE + REG_MATCH2);
> -
> -       /*
> -        * Start timer 2 rolling as our main wall clock source, keep timer 1
> -        * disabled
> -        */
> -       writel(0, timer->base + TIMER_CR);
> -       writel(~0, timer->base + TIMER2_BASE + REG_LOAD);
> -       writel(timer->t1_disable_val, timer->base + TIMER_CR);
> -
> -       /*
> -        * documentation is not publicly available:
> -        * min_delta / max_delta obtained by trial-and-error,
> -        * max_delta 0xfffffffe should be ok because count
> -        * register size is u32
> -        */
> -       clockevents_config_and_register(&timer->clkevt, pclk, 0x4, 0xfffffffe);
> -
> -       return 0;
> -
> -out_unmap:
> -       iounmap(timer->base);
> -out_free:
> -       kfree(timer);
> -       return ret;
> -}
> -CLOCKSOURCE_OF_DECLARE(moxart, "moxa,moxart-timer", moxart_timer_init);
> -CLOCKSOURCE_OF_DECLARE(aspeed, "aspeed,ast2400-timer", moxart_timer_init);
> diff --git a/drivers/clocksource/timer-fttmr010.c b/drivers/clocksource/timer-fttmr010.c
> index 2d915d1455ab..86d5159d3457 100644
> --- a/drivers/clocksource/timer-fttmr010.c
> +++ b/drivers/clocksource/timer-fttmr010.c
> @@ -50,6 +50,20 @@
>  #define TIMER_2_CR_UPDOWN      BIT(10)
>  #define TIMER_3_CR_UPDOWN      BIT(11)
>
> +/* The Aspeed AST2400 moves bits around in the control register */
> +#define TIMER_1_CR_ASPEED_ENABLE       BIT(0)
> +#define TIMER_1_CR_ASPEED_CLOCK                BIT(1)
> +#define TIMER_1_CR_ASPEED_INT          BIT(2)
> +#define TIMER_1_CR_ASPEED_UPDOWN       BIT(3)
> +#define TIMER_2_CR_ASPEED_ENABLE       BIT(4)
> +#define TIMER_2_CR_ASPEED_CLOCK                BIT(5)
> +#define TIMER_2_CR_ASPEED_INT          BIT(6)
> +#define TIMER_2_CR_ASPEED_UPDOWN       BIT(7)
> +#define TIMER_3_CR_ASPEED_ENABLE       BIT(8)
> +#define TIMER_3_CR_ASPEED_CLOCK                BIT(9)
> +#define TIMER_3_CR_ASPEED_INT          BIT(10)
> +#define TIMER_3_CR_ASPEED_UPDOWN       BIT(11)
> +
>  #define TIMER_1_INT_MATCH1     BIT(0)
>  #define TIMER_1_INT_MATCH2     BIT(1)
>  #define TIMER_1_INT_OVERFLOW   BIT(2)
> @@ -64,6 +78,8 @@
>  struct fttmr010 {
>         void __iomem *base;
>         unsigned int tick_rate;
> +       bool is_ast2400;
> +       u32 t1_enable_val;
>         struct clock_event_device clkevt;
>  };
>
> @@ -102,7 +118,7 @@ static int fttmr010_timer_shutdown(struct clock_event_device *evt)
>
>         /* Stop timer and interrupt. */
>         cr = readl(fttmr010->base + TIMER_CR);
> -       cr &= ~(TIMER_1_CR_ENABLE | TIMER_1_CR_INT);
> +       cr &= ~fttmr010->t1_enable_val;
>         writel(cr, fttmr010->base + TIMER_CR);
>
>         return 0;
> @@ -115,7 +131,7 @@ static int fttmr010_timer_set_oneshot(struct clock_event_device *evt)
>
>         /* Stop timer and interrupt. */
>         cr = readl(fttmr010->base + TIMER_CR);
> -       cr &= ~(TIMER_1_CR_ENABLE | TIMER_1_CR_INT);
> +       cr &= ~fttmr010->t1_enable_val;
>         writel(cr, fttmr010->base + TIMER_CR);
>
>         /* Setup counter start from 0 */
> @@ -130,7 +146,7 @@ static int fttmr010_timer_set_oneshot(struct clock_event_device *evt)
>
>         /* Start the timer */
>         cr = readl(fttmr010->base + TIMER_CR);
> -       cr |= TIMER_1_CR_ENABLE;
> +       cr |= fttmr010->t1_enable_val;
>         writel(cr, fttmr010->base + TIMER_CR);
>
>         return 0;
> @@ -144,7 +160,7 @@ static int fttmr010_timer_set_periodic(struct clock_event_device *evt)
>
>         /* Stop timer and interrupt */
>         cr = readl(fttmr010->base + TIMER_CR);
> -       cr &= ~(TIMER_1_CR_ENABLE | TIMER_1_CR_INT);
> +       cr &= ~fttmr010->t1_enable_val;
>         writel(cr, fttmr010->base + TIMER_CR);
>
>         /* Setup timer to fire at 1/HT intervals. */
> @@ -160,8 +176,7 @@ static int fttmr010_timer_set_periodic(struct clock_event_device *evt)
>
>         /* Start the timer */
>         cr = readl(fttmr010->base + TIMER_CR);
> -       cr |= TIMER_1_CR_ENABLE;
> -       cr |= TIMER_1_CR_INT;
> +       cr |= fttmr010->t1_enable_val;
>         writel(cr, fttmr010->base + TIMER_CR);
>
>         return 0;
> @@ -184,6 +199,7 @@ static int __init fttmr010_timer_init(struct device_node *np)
>         int irq;
>         struct clk *clk;
>         int ret;
> +       u32 val;
>
>         /*
>          * These implementations require a clock reference.
> @@ -223,13 +239,31 @@ static int __init fttmr010_timer_init(struct device_node *np)
>         }
>
>         /*
> +        * The Aspeed AST2400 moves bits around in the control register,
> +        * otherwise it works the same.
> +        */
> +       fttmr010->is_ast2400 =
> +               of_device_is_compatible(np, "aspeed,ast2400-timer");
> +       if (fttmr010->is_ast2400)
> +               fttmr010->t1_enable_val = TIMER_1_CR_ASPEED_ENABLE |
> +                       TIMER_1_CR_ASPEED_INT;
> +       else
> +               fttmr010->t1_enable_val = TIMER_1_CR_ENABLE | TIMER_1_CR_INT;
> +
> +       /*
>          * Reset the interrupt mask and status
>          */
>         writel(TIMER_INT_ALL_MASK, fttmr010->base + TIMER_INTR_MASK);
>         writel(0, fttmr010->base + TIMER_INTR_STATE);
> +
>         /* Enable timer 1 count up, timer 2 count up */
> -       writel((TIMER_1_CR_UPDOWN | TIMER_2_CR_ENABLE | TIMER_2_CR_UPDOWN),
> -              fttmr010->base + TIMER_CR);
> +       if (fttmr010->is_ast2400)
> +               val = TIMER_1_CR_ASPEED_UPDOWN | TIMER_2_CR_ASPEED_ENABLE |
> +                       TIMER_2_CR_ASPEED_UPDOWN;
> +       else
> +               val = TIMER_1_CR_UPDOWN | TIMER_2_CR_ENABLE |
> +                       TIMER_2_CR_UPDOWN;
> +       writel(val, fttmr010->base + TIMER_CR);
>
>         /*
>          * Setup free-running clocksource timer (interrupts
> @@ -290,3 +324,5 @@ static int __init fttmr010_timer_init(struct device_node *np)
>  }
>  CLOCKSOURCE_OF_DECLARE(fttmr010, "faraday,fttmr010", fttmr010_timer_init);
>  CLOCKSOURCE_OF_DECLARE(gemini, "cortina,gemini-timer", fttmr010_timer_init);
> +CLOCKSOURCE_OF_DECLARE(moxart, "moxa,moxart-timer", fttmr010_timer_init);
> +CLOCKSOURCE_OF_DECLARE(aspeed, "aspeed,ast2400-timer", fttmr010_timer_init);
> --
> 2.9.3
>

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

* [PATCH 7/8] clocksource/drivers/fttmr010: Merge Moxa into FTTMR010
@ 2017-05-18  7:22     ` Joel Stanley
  0 siblings, 0 replies; 40+ messages in thread
From: Joel Stanley @ 2017-05-18  7:22 UTC (permalink / raw)
  To: linux-arm-kernel

Hey Linus,

On Wed, May 17, 2017 at 10:05 PM, Linus Walleij
<linus.walleij@linaro.org> wrote:
> This merges the Moxa Art timer driver into the Faraday FTTMR010
> driver and replaces all Kconfig symbols to use the Faraday
> driver instead. We are now so similar that the drivers can
> be merged by just adding a few lines to the Faraday timer.

Nice work!

I gave this a spin on hardware and it didn't work :(

>
> Differences:
>
> - The Faraday driver explicitly sets the counter to count
>   upwards for the clocksource, removing the need for the
>   clocksource core to invert the value.
>
> - The Faraday driver also handles sched_clock()
>
> I am just guessing at the way the Aspeed has moved the count
> up/down bits to bits 3, 8 and 11 (keeping the bits pertaining
> to a certain timer together), so this really needs testing on
> the Aspeed. I'm guessing like this because it is what I would
> have done, if I was rewriting some VHDL/Verilog to extend
> these three timers to 8 (as the Aspeed apparently does).
>
> After this we have one driver for all three SoCs and a generic
> Faraday FTTMR010 timer driver, which is nice.
>
> Cc: Joel Stanley <joel@jms.id.au>
> Cc: Jonas Jensen <jonas.jensen@gmail.com>
> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
> ---
> ARM SoC folks: please ACK this so it can be merged with in the
> clocksource subsystem once it works.
>
> Joel: it would be super if you can test this. If you have some
> vendor tree or similar that actually indicates where the
> up/down counter bits are it's even better, but I'm hoping that
> this half-assed guesswork will JustWork(TM) (yeah, famous
> last words, sorry...)

Thanks for the rework! Unfortunately the Aspeed IP does not have bits
to control the direction of counting, and the timers only count down.
Bits 3, 7 and 11 are marked reserved in the data sheet. Can you rework
the patch to count down?

As an aside, we have a pretty decent model for the Aspeed SoCs in
Qemu. If you want to use it to smoketest your rework:

 $ qemu-system-arm -m 512 -M ast2500-evb -nodefaults -nographic
-serial stdio -kernel arch/arm/boot/zImage -dtb
arch/arm/boot/dts/aspeed-ast2500-evb.dtb

I tested with Ubuntu's qemu v2.8. It looks like we have a bug when the
kernel tries to use the clock the way your driver works, so we will
look at that. It does function properly for the current upstream code.

Cheers,

Joel

> ---
>  arch/arm/mach-aspeed/Kconfig         |   2 +-
>  arch/arm/mach-moxart/Kconfig         |   2 +-
>  drivers/clocksource/Kconfig          |   7 -
>  drivers/clocksource/Makefile         |   1 -
>  drivers/clocksource/moxart_timer.c   | 256 -----------------------------------
>  drivers/clocksource/timer-fttmr010.c |  52 +++++--
>  6 files changed, 46 insertions(+), 274 deletions(-)
>  delete mode 100644 drivers/clocksource/moxart_timer.c
>
> diff --git a/arch/arm/mach-aspeed/Kconfig b/arch/arm/mach-aspeed/Kconfig
> index f3f8c5c658db..2d5570e6e186 100644
> --- a/arch/arm/mach-aspeed/Kconfig
> +++ b/arch/arm/mach-aspeed/Kconfig
> @@ -4,7 +4,7 @@ menuconfig ARCH_ASPEED
>         select SRAM
>         select WATCHDOG
>         select ASPEED_WATCHDOG
> -       select MOXART_TIMER
> +       select FTTMR010_TIMER
>         select MFD_SYSCON
>         select PINCTRL
>         help
> diff --git a/arch/arm/mach-moxart/Kconfig b/arch/arm/mach-moxart/Kconfig
> index 70db2abf6163..a4a91f9a3301 100644
> --- a/arch/arm/mach-moxart/Kconfig
> +++ b/arch/arm/mach-moxart/Kconfig
> @@ -4,7 +4,7 @@ menuconfig ARCH_MOXART
>         select CPU_FA526
>         select ARM_DMA_MEM_BUFFERABLE
>         select FARADAY_FTINTC010
> -       select MOXART_TIMER
> +       select FTTMR010_TIMER
>         select GPIOLIB
>         select PHYLIB if NETDEVICES
>         help
> diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
> index 545d541ae20e..1b22ade4c8f1 100644
> --- a/drivers/clocksource/Kconfig
> +++ b/drivers/clocksource/Kconfig
> @@ -188,13 +188,6 @@ config ATLAS7_TIMER
>         help
>           Enables support for the Atlas7 timer.
>
> -config MOXART_TIMER
> -       bool "Moxart timer driver" if COMPILE_TEST
> -       depends on GENERIC_CLOCKEVENTS
> -       select CLKSRC_MMIO
> -       help
> -         Enables support for the Moxart timer.
> -
>  config MXS_TIMER
>         bool "Mxs timer driver" if COMPILE_TEST
>         depends on GENERIC_CLOCKEVENTS
> diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
> index 2b5b56a6f00f..cf0c30b6ec1f 100644
> --- a/drivers/clocksource/Makefile
> +++ b/drivers/clocksource/Makefile
> @@ -26,7 +26,6 @@ obj-$(CONFIG_ORION_TIMER)     += time-orion.o
>  obj-$(CONFIG_BCM2835_TIMER)    += bcm2835_timer.o
>  obj-$(CONFIG_CLPS711X_TIMER)   += clps711x-timer.o
>  obj-$(CONFIG_ATLAS7_TIMER)     += timer-atlas7.o
> -obj-$(CONFIG_MOXART_TIMER)     += moxart_timer.o
>  obj-$(CONFIG_MXS_TIMER)                += mxs_timer.o
>  obj-$(CONFIG_CLKSRC_PXA)       += pxa_timer.o
>  obj-$(CONFIG_PRIMA2_TIMER)     += timer-prima2.o
> diff --git a/drivers/clocksource/moxart_timer.c b/drivers/clocksource/moxart_timer.c
> deleted file mode 100644
> index 7f3430654fbd..000000000000
> --- a/drivers/clocksource/moxart_timer.c
> +++ /dev/null
> @@ -1,256 +0,0 @@
> -/*
> - * MOXA ART SoCs timer handling.
> - *
> - * Copyright (C) 2013 Jonas Jensen
> - *
> - * Jonas Jensen <jonas.jensen@gmail.com>
> - *
> - * This file is licensed under the terms of the GNU General Public
> - * License version 2.  This program is licensed "as is" without any
> - * warranty of any kind, whether express or implied.
> - */
> -
> -#include <linux/clk.h>
> -#include <linux/clockchips.h>
> -#include <linux/interrupt.h>
> -#include <linux/irq.h>
> -#include <linux/irqreturn.h>
> -#include <linux/of.h>
> -#include <linux/of_address.h>
> -#include <linux/of_irq.h>
> -#include <linux/io.h>
> -#include <linux/clocksource.h>
> -#include <linux/bitops.h>
> -#include <linux/slab.h>
> -
> -#define TIMER1_BASE            0x00
> -#define TIMER2_BASE            0x10
> -#define TIMER3_BASE            0x20
> -
> -#define REG_COUNT              0x0 /* writable */
> -#define REG_LOAD               0x4
> -#define REG_MATCH1             0x8
> -#define REG_MATCH2             0xC
> -
> -#define TIMER_CR               0x30
> -#define TIMER_INTR_STATE       0x34
> -#define TIMER_INTR_MASK                0x38
> -
> -/*
> - * Moxart TIMER_CR flags:
> - *
> - * MOXART_CR_*_CLOCK   0: PCLK, 1: EXT1CLK
> - * MOXART_CR_*_INT     overflow interrupt enable bit
> - */
> -#define MOXART_CR_1_ENABLE     BIT(0)
> -#define MOXART_CR_1_CLOCK      BIT(1)
> -#define MOXART_CR_1_INT        BIT(2)
> -#define MOXART_CR_2_ENABLE     BIT(3)
> -#define MOXART_CR_2_CLOCK      BIT(4)
> -#define MOXART_CR_2_INT        BIT(5)
> -#define MOXART_CR_3_ENABLE     BIT(6)
> -#define MOXART_CR_3_CLOCK      BIT(7)
> -#define MOXART_CR_3_INT        BIT(8)
> -#define MOXART_CR_COUNT_UP     BIT(9)
> -
> -#define MOXART_TIMER1_ENABLE   (MOXART_CR_2_ENABLE | MOXART_CR_1_ENABLE)
> -#define MOXART_TIMER1_DISABLE  (MOXART_CR_2_ENABLE)
> -
> -/*
> - * The ASpeed variant of the IP block has a different layout
> - * for the control register
> - */
> -#define ASPEED_CR_1_ENABLE     BIT(0)
> -#define ASPEED_CR_1_CLOCK      BIT(1)
> -#define ASPEED_CR_1_INT                BIT(2)
> -#define ASPEED_CR_2_ENABLE     BIT(4)
> -#define ASPEED_CR_2_CLOCK      BIT(5)
> -#define ASPEED_CR_2_INT                BIT(6)
> -#define ASPEED_CR_3_ENABLE     BIT(8)
> -#define ASPEED_CR_3_CLOCK      BIT(9)
> -#define ASPEED_CR_3_INT                BIT(10)
> -
> -#define ASPEED_TIMER1_ENABLE   (ASPEED_CR_2_ENABLE | ASPEED_CR_1_ENABLE)
> -#define ASPEED_TIMER1_DISABLE  (ASPEED_CR_2_ENABLE)
> -
> -struct moxart_timer {
> -       void __iomem *base;
> -       unsigned int t1_disable_val;
> -       unsigned int t1_enable_val;
> -       unsigned int count_per_tick;
> -       struct clock_event_device clkevt;
> -};
> -
> -static inline struct moxart_timer *to_moxart(struct clock_event_device *evt)
> -{
> -       return container_of(evt, struct moxart_timer, clkevt);
> -}
> -
> -static inline void moxart_disable(struct clock_event_device *evt)
> -{
> -       struct moxart_timer *timer = to_moxart(evt);
> -
> -       writel(timer->t1_disable_val, timer->base + TIMER_CR);
> -}
> -
> -static inline void moxart_enable(struct clock_event_device *evt)
> -{
> -       struct moxart_timer *timer = to_moxart(evt);
> -
> -       writel(timer->t1_enable_val, timer->base + TIMER_CR);
> -}
> -
> -static int moxart_shutdown(struct clock_event_device *evt)
> -{
> -       moxart_disable(evt);
> -       return 0;
> -}
> -
> -static int moxart_set_oneshot(struct clock_event_device *evt)
> -{
> -       moxart_disable(evt);
> -       writel(~0, to_moxart(evt)->base + TIMER1_BASE + REG_LOAD);
> -       return 0;
> -}
> -
> -static int moxart_set_periodic(struct clock_event_device *evt)
> -{
> -       struct moxart_timer *timer = to_moxart(evt);
> -
> -       moxart_disable(evt);
> -       writel(timer->count_per_tick, timer->base + TIMER1_BASE + REG_LOAD);
> -       writel(0, timer->base + TIMER1_BASE + REG_MATCH1);
> -       moxart_enable(evt);
> -       return 0;
> -}
> -
> -static int moxart_clkevt_next_event(unsigned long cycles,
> -                                   struct clock_event_device *evt)
> -{
> -       struct moxart_timer *timer = to_moxart(evt);
> -       u32 u;
> -
> -       moxart_disable(evt);
> -
> -       u = readl(timer->base + TIMER1_BASE + REG_COUNT) - cycles;
> -       writel(u, timer->base + TIMER1_BASE + REG_MATCH1);
> -
> -       moxart_enable(evt);
> -
> -       return 0;
> -}
> -
> -static irqreturn_t moxart_timer_interrupt(int irq, void *dev_id)
> -{
> -       struct clock_event_device *evt = dev_id;
> -       evt->event_handler(evt);
> -       return IRQ_HANDLED;
> -}
> -
> -static int __init moxart_timer_init(struct device_node *node)
> -{
> -       int ret, irq;
> -       unsigned long pclk;
> -       struct clk *clk;
> -       struct moxart_timer *timer;
> -
> -       timer = kzalloc(sizeof(*timer), GFP_KERNEL);
> -       if (!timer)
> -               return -ENOMEM;
> -
> -       timer->base = of_iomap(node, 0);
> -       if (!timer->base) {
> -               pr_err("%s: of_iomap failed\n", node->full_name);
> -               ret = -ENXIO;
> -               goto out_free;
> -       }
> -
> -       irq = irq_of_parse_and_map(node, 0);
> -       if (irq <= 0) {
> -               pr_err("%s: irq_of_parse_and_map failed\n", node->full_name);
> -               ret = -EINVAL;
> -               goto out_unmap;
> -       }
> -
> -       clk = of_clk_get(node, 0);
> -       if (IS_ERR(clk))  {
> -               pr_err("%s: of_clk_get failed\n", node->full_name);
> -               ret = PTR_ERR(clk);
> -               goto out_unmap;
> -       }
> -
> -       pclk = clk_get_rate(clk);
> -
> -       if (of_device_is_compatible(node, "moxa,moxart-timer")) {
> -               timer->t1_enable_val = MOXART_TIMER1_ENABLE;
> -               timer->t1_disable_val = MOXART_TIMER1_DISABLE;
> -       } else if (of_device_is_compatible(node, "aspeed,ast2400-timer")) {
> -               timer->t1_enable_val = ASPEED_TIMER1_ENABLE;
> -               timer->t1_disable_val = ASPEED_TIMER1_DISABLE;
> -       } else {
> -               pr_err("%s: unknown platform\n", node->full_name);
> -               ret = -EINVAL;
> -               goto out_unmap;
> -       }
> -
> -       timer->count_per_tick = DIV_ROUND_CLOSEST(pclk, HZ);
> -
> -       timer->clkevt.name = node->name;
> -       timer->clkevt.rating = 200;
> -       timer->clkevt.features = CLOCK_EVT_FEAT_PERIODIC |
> -                                       CLOCK_EVT_FEAT_ONESHOT;
> -       timer->clkevt.set_state_shutdown = moxart_shutdown;
> -       timer->clkevt.set_state_periodic = moxart_set_periodic;
> -       timer->clkevt.set_state_oneshot = moxart_set_oneshot;
> -       timer->clkevt.tick_resume = moxart_set_oneshot;
> -       timer->clkevt.set_next_event = moxart_clkevt_next_event;
> -       timer->clkevt.cpumask = cpumask_of(0);
> -       timer->clkevt.irq = irq;
> -
> -       ret = clocksource_mmio_init(timer->base + TIMER2_BASE + REG_COUNT,
> -                                   "moxart_timer", pclk, 200, 32,
> -                                   clocksource_mmio_readl_down);
> -       if (ret) {
> -               pr_err("%s: clocksource_mmio_init failed\n", node->full_name);
> -               goto out_unmap;
> -       }
> -
> -       ret = request_irq(irq, moxart_timer_interrupt, IRQF_TIMER,
> -                         node->name, &timer->clkevt);
> -       if (ret) {
> -               pr_err("%s: setup_irq failed\n", node->full_name);
> -               goto out_unmap;
> -       }
> -
> -       /* Clear match registers */
> -       writel(0, timer->base + TIMER1_BASE + REG_MATCH1);
> -       writel(0, timer->base + TIMER1_BASE + REG_MATCH2);
> -       writel(0, timer->base + TIMER2_BASE + REG_MATCH1);
> -       writel(0, timer->base + TIMER2_BASE + REG_MATCH2);
> -
> -       /*
> -        * Start timer 2 rolling as our main wall clock source, keep timer 1
> -        * disabled
> -        */
> -       writel(0, timer->base + TIMER_CR);
> -       writel(~0, timer->base + TIMER2_BASE + REG_LOAD);
> -       writel(timer->t1_disable_val, timer->base + TIMER_CR);
> -
> -       /*
> -        * documentation is not publicly available:
> -        * min_delta / max_delta obtained by trial-and-error,
> -        * max_delta 0xfffffffe should be ok because count
> -        * register size is u32
> -        */
> -       clockevents_config_and_register(&timer->clkevt, pclk, 0x4, 0xfffffffe);
> -
> -       return 0;
> -
> -out_unmap:
> -       iounmap(timer->base);
> -out_free:
> -       kfree(timer);
> -       return ret;
> -}
> -CLOCKSOURCE_OF_DECLARE(moxart, "moxa,moxart-timer", moxart_timer_init);
> -CLOCKSOURCE_OF_DECLARE(aspeed, "aspeed,ast2400-timer", moxart_timer_init);
> diff --git a/drivers/clocksource/timer-fttmr010.c b/drivers/clocksource/timer-fttmr010.c
> index 2d915d1455ab..86d5159d3457 100644
> --- a/drivers/clocksource/timer-fttmr010.c
> +++ b/drivers/clocksource/timer-fttmr010.c
> @@ -50,6 +50,20 @@
>  #define TIMER_2_CR_UPDOWN      BIT(10)
>  #define TIMER_3_CR_UPDOWN      BIT(11)
>
> +/* The Aspeed AST2400 moves bits around in the control register */
> +#define TIMER_1_CR_ASPEED_ENABLE       BIT(0)
> +#define TIMER_1_CR_ASPEED_CLOCK                BIT(1)
> +#define TIMER_1_CR_ASPEED_INT          BIT(2)
> +#define TIMER_1_CR_ASPEED_UPDOWN       BIT(3)
> +#define TIMER_2_CR_ASPEED_ENABLE       BIT(4)
> +#define TIMER_2_CR_ASPEED_CLOCK                BIT(5)
> +#define TIMER_2_CR_ASPEED_INT          BIT(6)
> +#define TIMER_2_CR_ASPEED_UPDOWN       BIT(7)
> +#define TIMER_3_CR_ASPEED_ENABLE       BIT(8)
> +#define TIMER_3_CR_ASPEED_CLOCK                BIT(9)
> +#define TIMER_3_CR_ASPEED_INT          BIT(10)
> +#define TIMER_3_CR_ASPEED_UPDOWN       BIT(11)
> +
>  #define TIMER_1_INT_MATCH1     BIT(0)
>  #define TIMER_1_INT_MATCH2     BIT(1)
>  #define TIMER_1_INT_OVERFLOW   BIT(2)
> @@ -64,6 +78,8 @@
>  struct fttmr010 {
>         void __iomem *base;
>         unsigned int tick_rate;
> +       bool is_ast2400;
> +       u32 t1_enable_val;
>         struct clock_event_device clkevt;
>  };
>
> @@ -102,7 +118,7 @@ static int fttmr010_timer_shutdown(struct clock_event_device *evt)
>
>         /* Stop timer and interrupt. */
>         cr = readl(fttmr010->base + TIMER_CR);
> -       cr &= ~(TIMER_1_CR_ENABLE | TIMER_1_CR_INT);
> +       cr &= ~fttmr010->t1_enable_val;
>         writel(cr, fttmr010->base + TIMER_CR);
>
>         return 0;
> @@ -115,7 +131,7 @@ static int fttmr010_timer_set_oneshot(struct clock_event_device *evt)
>
>         /* Stop timer and interrupt. */
>         cr = readl(fttmr010->base + TIMER_CR);
> -       cr &= ~(TIMER_1_CR_ENABLE | TIMER_1_CR_INT);
> +       cr &= ~fttmr010->t1_enable_val;
>         writel(cr, fttmr010->base + TIMER_CR);
>
>         /* Setup counter start from 0 */
> @@ -130,7 +146,7 @@ static int fttmr010_timer_set_oneshot(struct clock_event_device *evt)
>
>         /* Start the timer */
>         cr = readl(fttmr010->base + TIMER_CR);
> -       cr |= TIMER_1_CR_ENABLE;
> +       cr |= fttmr010->t1_enable_val;
>         writel(cr, fttmr010->base + TIMER_CR);
>
>         return 0;
> @@ -144,7 +160,7 @@ static int fttmr010_timer_set_periodic(struct clock_event_device *evt)
>
>         /* Stop timer and interrupt */
>         cr = readl(fttmr010->base + TIMER_CR);
> -       cr &= ~(TIMER_1_CR_ENABLE | TIMER_1_CR_INT);
> +       cr &= ~fttmr010->t1_enable_val;
>         writel(cr, fttmr010->base + TIMER_CR);
>
>         /* Setup timer to fire at 1/HT intervals. */
> @@ -160,8 +176,7 @@ static int fttmr010_timer_set_periodic(struct clock_event_device *evt)
>
>         /* Start the timer */
>         cr = readl(fttmr010->base + TIMER_CR);
> -       cr |= TIMER_1_CR_ENABLE;
> -       cr |= TIMER_1_CR_INT;
> +       cr |= fttmr010->t1_enable_val;
>         writel(cr, fttmr010->base + TIMER_CR);
>
>         return 0;
> @@ -184,6 +199,7 @@ static int __init fttmr010_timer_init(struct device_node *np)
>         int irq;
>         struct clk *clk;
>         int ret;
> +       u32 val;
>
>         /*
>          * These implementations require a clock reference.
> @@ -223,13 +239,31 @@ static int __init fttmr010_timer_init(struct device_node *np)
>         }
>
>         /*
> +        * The Aspeed AST2400 moves bits around in the control register,
> +        * otherwise it works the same.
> +        */
> +       fttmr010->is_ast2400 =
> +               of_device_is_compatible(np, "aspeed,ast2400-timer");
> +       if (fttmr010->is_ast2400)
> +               fttmr010->t1_enable_val = TIMER_1_CR_ASPEED_ENABLE |
> +                       TIMER_1_CR_ASPEED_INT;
> +       else
> +               fttmr010->t1_enable_val = TIMER_1_CR_ENABLE | TIMER_1_CR_INT;
> +
> +       /*
>          * Reset the interrupt mask and status
>          */
>         writel(TIMER_INT_ALL_MASK, fttmr010->base + TIMER_INTR_MASK);
>         writel(0, fttmr010->base + TIMER_INTR_STATE);
> +
>         /* Enable timer 1 count up, timer 2 count up */
> -       writel((TIMER_1_CR_UPDOWN | TIMER_2_CR_ENABLE | TIMER_2_CR_UPDOWN),
> -              fttmr010->base + TIMER_CR);
> +       if (fttmr010->is_ast2400)
> +               val = TIMER_1_CR_ASPEED_UPDOWN | TIMER_2_CR_ASPEED_ENABLE |
> +                       TIMER_2_CR_ASPEED_UPDOWN;
> +       else
> +               val = TIMER_1_CR_UPDOWN | TIMER_2_CR_ENABLE |
> +                       TIMER_2_CR_UPDOWN;
> +       writel(val, fttmr010->base + TIMER_CR);
>
>         /*
>          * Setup free-running clocksource timer (interrupts
> @@ -290,3 +324,5 @@ static int __init fttmr010_timer_init(struct device_node *np)
>  }
>  CLOCKSOURCE_OF_DECLARE(fttmr010, "faraday,fttmr010", fttmr010_timer_init);
>  CLOCKSOURCE_OF_DECLARE(gemini, "cortina,gemini-timer", fttmr010_timer_init);
> +CLOCKSOURCE_OF_DECLARE(moxart, "moxa,moxart-timer", fttmr010_timer_init);
> +CLOCKSOURCE_OF_DECLARE(aspeed, "aspeed,ast2400-timer", fttmr010_timer_init);
> --
> 2.9.3
>

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

* Re: [PATCH 0/8] clocksource: Generalize Faraday timer
  2017-05-17 14:05 ` Linus Walleij
@ 2017-05-18 10:32   ` Jonas Jensen
  -1 siblings, 0 replies; 40+ messages in thread
From: Jonas Jensen @ 2017-05-18 10:32 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Daniel Lezcano, Thomas Gleixner, Joel Stanley, Janos Laube,
	Paulius Zaleckas, linux-arm-kernel, Hans Ulli Kroll,
	Florian Fainelli, linux-kernel

On 17 May 2017 at 16:05, Linus Walleij <linus.walleij@linaro.org> wrote:
> The patches can be applied as soon as Jonas Jensen and Joel
> Stanley says they work for them.

Thanks! fttmr010 seem to work OK!

I did the usual test on UC-7112-LX [1] after merging
linux-nomadik/fttmr010 into next-20170518.

[1] https://bitbucket.org/Kasreyn/linux-next/commits/2904b508ad46bd98b09c11e312c396d672fc7e9a
Uncompressing Linux... done, booting the kernel.
[    0.000000] Booting Linux on physical CPU 0x0
[    0.000000] Linux version 4.12.0-rc1-next-20170518-00010-g2904b50
(i@ildjarn) (gcc version 4.9.1 (crosstool-NG 1.20.0) ) #4483 PREEMPT
Thu May 18 11:38:28 CEST 2017
[    0.000000] CPU: FA526 [66015261] revision 1 (ARMv4), cr=0000397f
[    0.000000] CPU: VIVT data cache, VIVT instruction cache
[    0.000000] OF: fdt: Machine model: MOXA UC-7112-LX
[    0.000000] bootconsole [earlycon0] enabled
[    0.000000] Memory policy: Data cache writeback
[    0.000000] Built 1 zonelists in Zone order, mobility grouping on.
Total pages: 8128
[    0.000000] Kernel command line: console=ttyS0,115200n8 earlyprintk
root=/dev/mmcblk0p1 rw rootwait
[    0.000000] PID hash table entries: 128 (order: -3, 512 bytes)
[    0.000000] Dentry cache hash table entries: 4096 (order: 2, 16384 bytes)
[    0.000000] Inode-cache hash table entries: 2048 (order: 1, 8192 bytes)
[    0.000000] Memory: 19172K/32768K available (3421K kernel code,
156K rwdata, 724K rodata, 192K init, 8587K bss, 13596K reserved, 0K
cma-reserved)
[    0.000000] Virtual kernel memory layout:
[    0.000000]     vector  : 0xffff0000 - 0xffff1000   (   4 kB)
[    0.000000]     fixmap  : 0xffc00000 - 0xfff00000   (3072 kB)
[    0.000000]     vmalloc : 0xc2800000 - 0xff800000   ( 976 MB)
[    0.000000]     lowmem  : 0xc0000000 - 0xc2000000   (  32 MB)
[    0.000000]       .text : 0xc0008000 - 0xc035f700   (3422 kB)
[    0.000000]       .init : 0xc0430000 - 0xc0460000   ( 192 kB)
[    0.000000]       .data : 0xc0460000 - 0xc0487360   ( 157 kB)
[    0.000000]        .bss : 0xc048ba40 - 0xc0cee7ec   (8588 kB)
[    0.000000] SLUB: HWalign=32, Order=0-3, MinObjects=0, CPUs=1, Nodes=1
[    0.000000] Running RCU self tests
[    0.000000] Preemptible hierarchical RCU implementation.
[    0.000000] RCU lockdep checking is enabled.
[    0.000000] NR_IRQS:16 nr_irqs:16 16
[    0.000000] clocksource: FTTMR010-TIMER2: mask: 0xffffffff
max_cycles: 0xffffffff, max_idle_ns: 39817925974 ns
[    0.000087] sched_clock: 32 bits at 48MHz, resolution 20ns, wraps
every 44739242997ns
[    0.009487] Lock dependency validator: Copyright (c) 2006 Red Hat,
Inc., Ingo Molnar
[    0.017848] ... MAX_LOCKDEP_SUBCLASSES:  8
[    0.024640] ... MAX_LOCK_DEPTH:          48
[    0.029566] ... MAX_LOCKDEP_KEYS:        8191
[    0.034261] ... CLASSHASH_SIZE:          4096
[    0.039299] ... MAX_LOCKDEP_ENTRIES:     32768
[    0.044069] ... MAX_LOCKDEP_CHAINS:      65536
[    0.049183] ... CHAINHASH_SIZE:          32768
[    0.053969]  memory used by lock dependency info: 5167 kB
[    0.060064]  per task-struct memory footprint: 1536 bytes
[    0.072855] kmemleak: Kernel memory leak detector disabled
[    0.091073] kmemleak: Early log buffer exceeded (1229), please
increase DEBUG_KMEMLEAK_EARLY_LOG_SIZE
[    0.101346] Calibrating delay loop... 143.76 BogoMIPS (lpj=718848)
[    0.175662] pid_max: default: 4096 minimum: 301
[    0.183736] Mount-cache hash table entries: 1024 (order: 0, 4096 bytes)
[    0.191487] Mountpoint-cache hash table entries: 1024 (order: 0, 4096 bytes)
[    0.217924] CPU: Testing write buffer coherency: ok
[    0.250678] Setting up static identity map for 0x8200 - 0x8248
[    0.262190] Hierarchical SRCU implementation.
[    0.327717] devtmpfs: initialized
[    0.407364] DMA-API: preallocated 4096 debug entries
[    0.413210] DMA-API: debugging enabled by kernel config
[    0.445120] clocksource: jiffies: mask: 0xffffffff max_cycles:
0xffffffff, max_idle_ns: 19112604462750000 ns
[    0.458278] kworker/u2:0 (14) used greatest stack depth: 6224 bytes left
[    0.467584] futex hash table entries: 16 (order: -3, 704 bytes)
[    0.498128] NET: Registered protocol family 16
[    0.518378] DMA: preallocated 256 KiB pool for atomic coherent allocations
[    0.558707] kworker/u2:1 (17) used greatest stack depth: 5856 bytes left
[    1.322437] clocksource: Switched to clocksource FTTMR010-TIMER2
[    1.426799] NET: Registered protocol family 2
[    1.448712] TCP established hash table entries: 1024 (order: 0, 4096 bytes)
[    1.457909] TCP bind hash table entries: 1024 (order: 3, 36864 bytes)
[    1.468402] TCP: Hash tables configured (established 1024 bind 1024)
[    1.479267] UDP hash table entries: 128 (order: 1, 10240 bytes)
[    1.487244] UDP-Lite hash table entries: 128 (order: 1, 10240 bytes)
[    1.501083] NET: Registered protocol family 1
[    1.555364] workingset: timestamp_bits=30 max_order=13 bucket_order=0
[    2.067555] jffs2: version 2.2. (NAND) © 2001-2006 Red Hat, Inc.
[    2.209611] io scheduler noop registered
[    2.221533] io scheduler cfq registered (default)
[    2.229911] io scheduler mq-deadline registered
[    2.236161] io scheduler kyber registered
[    2.298243] ftgpio010-gpio 98700000.gpio: FTGPIO010 @c289e000 registered
[    2.338079] Serial: 8250/16550 driver, 1 ports, IRQ sharing enabled
[    2.419644] console [ttyS0] disabled
[    2.429418] 98200000.uart: ttyS0 at MMIO 0x98200000 (irq = 21,
base_baud = 921600) is a 16550A
[    2.444308] console [ttyS0] enabled
[    2.444308] console [ttyS0] enabled
[    2.452080] bootconsole [earlycon0] disabled
[    2.452080] bootconsole [earlycon0] disabled
[    2.534670] 80000000.flash: Found 1 x16 devices at 0x0 in 16-bit
bank. Manufacturer ID 0x000089 Chip ID 0x000018
[    2.546948] Intel/Sharp Extended Query Table at 0x0031
[    2.554074] random: fast init done
[    2.559148] Intel/Sharp Extended Query Table at 0x0031
[    2.565687] Using buffer write method
[    2.569613] cfi_cmdset_0001: Erase suspend on write enabled
[    2.577158] 4 ofpart partitions found on MTD device 80000000.flash
[    2.584094] Creating 4 MTD partitions on "80000000.flash":
[    2.590023] 0x000000000000-0x000000040000 : "bootloader"
[    2.666600] 0x000000040000-0x000000200000 : "linux kernel"
[    2.725067] 0x000000200000-0x000000a00000 : "root filesystem"
[    2.781665] 0x000000a00000-0x000001000000 : "user filesystem"
[    3.499737] libphy: MOXA ART Ethernet MII: probed
[    4.186428] libphy: MOXA ART Ethernet MII: probed
[    4.234239] libphy: Fixed MDIO Bus: probed
[    4.359522] moxart-rtc 90000000.soc:rtc: rtc core: registered
90000000.soc:rtc as rtc0
[    4.439789] sdhci: Secure Digital Host Controller Interface driver
[    4.451775] sdhci: Copyright(c) Pierre Ossman
[    4.546512] sdhci-pltfm: SDHCI platform and OF driver helper
[    4.609536] NET: Registered protocol family 17
[    4.621712] mmc0: new SD card at address e624
[    4.704356] mmcblk0: mmc0:e624 SD02G 1.84 GiB
[    4.768791]  mmcblk0: p1
[    4.779134] console [netcon0] enabled
[    4.794176] netconsole: network logging started
[    4.834073] moxart-rtc 90000000.soc:rtc: setting system clock to
2017-05-18 10:10:23 UTC (1495102223)
[    4.889168] EXT4-fs (mmcblk0p1): mounting ext3 file system using
the ext4 subsystem
[    5.309434] EXT4-fs (mmcblk0p1): warning: mounting fs with errors,
running e2fsck is recommended
[    5.351091] EXT4-fs (mmcblk0p1): recovery complete
[    5.370392] EXT4-fs (mmcblk0p1): mounted filesystem with ordered
data mode. Opts: (null)
[    5.381420] VFS: Mounted root (ext3 filesystem) on device 179:1.
[    5.475945] devtmpfs: mounted
[    5.514759] Freeing unused kernel memory: 192K
[    5.521611] This architecture does not have kernel memory protection.
INIT: version 2.88 booting

   Jonas

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

* [PATCH 0/8] clocksource: Generalize Faraday timer
@ 2017-05-18 10:32   ` Jonas Jensen
  0 siblings, 0 replies; 40+ messages in thread
From: Jonas Jensen @ 2017-05-18 10:32 UTC (permalink / raw)
  To: linux-arm-kernel

On 17 May 2017 at 16:05, Linus Walleij <linus.walleij@linaro.org> wrote:
> The patches can be applied as soon as Jonas Jensen and Joel
> Stanley says they work for them.

Thanks! fttmr010 seem to work OK!

I did the usual test on UC-7112-LX [1] after merging
linux-nomadik/fttmr010 into next-20170518.

[1] https://bitbucket.org/Kasreyn/linux-next/commits/2904b508ad46bd98b09c11e312c396d672fc7e9a
Uncompressing Linux... done, booting the kernel.
[    0.000000] Booting Linux on physical CPU 0x0
[    0.000000] Linux version 4.12.0-rc1-next-20170518-00010-g2904b50
(i at ildjarn) (gcc version 4.9.1 (crosstool-NG 1.20.0) ) #4483 PREEMPT
Thu May 18 11:38:28 CEST 2017
[    0.000000] CPU: FA526 [66015261] revision 1 (ARMv4), cr=0000397f
[    0.000000] CPU: VIVT data cache, VIVT instruction cache
[    0.000000] OF: fdt: Machine model: MOXA UC-7112-LX
[    0.000000] bootconsole [earlycon0] enabled
[    0.000000] Memory policy: Data cache writeback
[    0.000000] Built 1 zonelists in Zone order, mobility grouping on.
Total pages: 8128
[    0.000000] Kernel command line: console=ttyS0,115200n8 earlyprintk
root=/dev/mmcblk0p1 rw rootwait
[    0.000000] PID hash table entries: 128 (order: -3, 512 bytes)
[    0.000000] Dentry cache hash table entries: 4096 (order: 2, 16384 bytes)
[    0.000000] Inode-cache hash table entries: 2048 (order: 1, 8192 bytes)
[    0.000000] Memory: 19172K/32768K available (3421K kernel code,
156K rwdata, 724K rodata, 192K init, 8587K bss, 13596K reserved, 0K
cma-reserved)
[    0.000000] Virtual kernel memory layout:
[    0.000000]     vector  : 0xffff0000 - 0xffff1000   (   4 kB)
[    0.000000]     fixmap  : 0xffc00000 - 0xfff00000   (3072 kB)
[    0.000000]     vmalloc : 0xc2800000 - 0xff800000   ( 976 MB)
[    0.000000]     lowmem  : 0xc0000000 - 0xc2000000   (  32 MB)
[    0.000000]       .text : 0xc0008000 - 0xc035f700   (3422 kB)
[    0.000000]       .init : 0xc0430000 - 0xc0460000   ( 192 kB)
[    0.000000]       .data : 0xc0460000 - 0xc0487360   ( 157 kB)
[    0.000000]        .bss : 0xc048ba40 - 0xc0cee7ec   (8588 kB)
[    0.000000] SLUB: HWalign=32, Order=0-3, MinObjects=0, CPUs=1, Nodes=1
[    0.000000] Running RCU self tests
[    0.000000] Preemptible hierarchical RCU implementation.
[    0.000000] RCU lockdep checking is enabled.
[    0.000000] NR_IRQS:16 nr_irqs:16 16
[    0.000000] clocksource: FTTMR010-TIMER2: mask: 0xffffffff
max_cycles: 0xffffffff, max_idle_ns: 39817925974 ns
[    0.000087] sched_clock: 32 bits at 48MHz, resolution 20ns, wraps
every 44739242997ns
[    0.009487] Lock dependency validator: Copyright (c) 2006 Red Hat,
Inc., Ingo Molnar
[    0.017848] ... MAX_LOCKDEP_SUBCLASSES:  8
[    0.024640] ... MAX_LOCK_DEPTH:          48
[    0.029566] ... MAX_LOCKDEP_KEYS:        8191
[    0.034261] ... CLASSHASH_SIZE:          4096
[    0.039299] ... MAX_LOCKDEP_ENTRIES:     32768
[    0.044069] ... MAX_LOCKDEP_CHAINS:      65536
[    0.049183] ... CHAINHASH_SIZE:          32768
[    0.053969]  memory used by lock dependency info: 5167 kB
[    0.060064]  per task-struct memory footprint: 1536 bytes
[    0.072855] kmemleak: Kernel memory leak detector disabled
[    0.091073] kmemleak: Early log buffer exceeded (1229), please
increase DEBUG_KMEMLEAK_EARLY_LOG_SIZE
[    0.101346] Calibrating delay loop... 143.76 BogoMIPS (lpj=718848)
[    0.175662] pid_max: default: 4096 minimum: 301
[    0.183736] Mount-cache hash table entries: 1024 (order: 0, 4096 bytes)
[    0.191487] Mountpoint-cache hash table entries: 1024 (order: 0, 4096 bytes)
[    0.217924] CPU: Testing write buffer coherency: ok
[    0.250678] Setting up static identity map for 0x8200 - 0x8248
[    0.262190] Hierarchical SRCU implementation.
[    0.327717] devtmpfs: initialized
[    0.407364] DMA-API: preallocated 4096 debug entries
[    0.413210] DMA-API: debugging enabled by kernel config
[    0.445120] clocksource: jiffies: mask: 0xffffffff max_cycles:
0xffffffff, max_idle_ns: 19112604462750000 ns
[    0.458278] kworker/u2:0 (14) used greatest stack depth: 6224 bytes left
[    0.467584] futex hash table entries: 16 (order: -3, 704 bytes)
[    0.498128] NET: Registered protocol family 16
[    0.518378] DMA: preallocated 256 KiB pool for atomic coherent allocations
[    0.558707] kworker/u2:1 (17) used greatest stack depth: 5856 bytes left
[    1.322437] clocksource: Switched to clocksource FTTMR010-TIMER2
[    1.426799] NET: Registered protocol family 2
[    1.448712] TCP established hash table entries: 1024 (order: 0, 4096 bytes)
[    1.457909] TCP bind hash table entries: 1024 (order: 3, 36864 bytes)
[    1.468402] TCP: Hash tables configured (established 1024 bind 1024)
[    1.479267] UDP hash table entries: 128 (order: 1, 10240 bytes)
[    1.487244] UDP-Lite hash table entries: 128 (order: 1, 10240 bytes)
[    1.501083] NET: Registered protocol family 1
[    1.555364] workingset: timestamp_bits=30 max_order=13 bucket_order=0
[    2.067555] jffs2: version 2.2. (NAND) ? 2001-2006 Red Hat, Inc.
[    2.209611] io scheduler noop registered
[    2.221533] io scheduler cfq registered (default)
[    2.229911] io scheduler mq-deadline registered
[    2.236161] io scheduler kyber registered
[    2.298243] ftgpio010-gpio 98700000.gpio: FTGPIO010 @c289e000 registered
[    2.338079] Serial: 8250/16550 driver, 1 ports, IRQ sharing enabled
[    2.419644] console [ttyS0] disabled
[    2.429418] 98200000.uart: ttyS0 at MMIO 0x98200000 (irq = 21,
base_baud = 921600) is a 16550A
[    2.444308] console [ttyS0] enabled
[    2.444308] console [ttyS0] enabled
[    2.452080] bootconsole [earlycon0] disabled
[    2.452080] bootconsole [earlycon0] disabled
[    2.534670] 80000000.flash: Found 1 x16 devices at 0x0 in 16-bit
bank. Manufacturer ID 0x000089 Chip ID 0x000018
[    2.546948] Intel/Sharp Extended Query Table at 0x0031
[    2.554074] random: fast init done
[    2.559148] Intel/Sharp Extended Query Table at 0x0031
[    2.565687] Using buffer write method
[    2.569613] cfi_cmdset_0001: Erase suspend on write enabled
[    2.577158] 4 ofpart partitions found on MTD device 80000000.flash
[    2.584094] Creating 4 MTD partitions on "80000000.flash":
[    2.590023] 0x000000000000-0x000000040000 : "bootloader"
[    2.666600] 0x000000040000-0x000000200000 : "linux kernel"
[    2.725067] 0x000000200000-0x000000a00000 : "root filesystem"
[    2.781665] 0x000000a00000-0x000001000000 : "user filesystem"
[    3.499737] libphy: MOXA ART Ethernet MII: probed
[    4.186428] libphy: MOXA ART Ethernet MII: probed
[    4.234239] libphy: Fixed MDIO Bus: probed
[    4.359522] moxart-rtc 90000000.soc:rtc: rtc core: registered
90000000.soc:rtc as rtc0
[    4.439789] sdhci: Secure Digital Host Controller Interface driver
[    4.451775] sdhci: Copyright(c) Pierre Ossman
[    4.546512] sdhci-pltfm: SDHCI platform and OF driver helper
[    4.609536] NET: Registered protocol family 17
[    4.621712] mmc0: new SD card at address e624
[    4.704356] mmcblk0: mmc0:e624 SD02G 1.84 GiB
[    4.768791]  mmcblk0: p1
[    4.779134] console [netcon0] enabled
[    4.794176] netconsole: network logging started
[    4.834073] moxart-rtc 90000000.soc:rtc: setting system clock to
2017-05-18 10:10:23 UTC (1495102223)
[    4.889168] EXT4-fs (mmcblk0p1): mounting ext3 file system using
the ext4 subsystem
[    5.309434] EXT4-fs (mmcblk0p1): warning: mounting fs with errors,
running e2fsck is recommended
[    5.351091] EXT4-fs (mmcblk0p1): recovery complete
[    5.370392] EXT4-fs (mmcblk0p1): mounted filesystem with ordered
data mode. Opts: (null)
[    5.381420] VFS: Mounted root (ext3 filesystem) on device 179:1.
[    5.475945] devtmpfs: mounted
[    5.514759] Freeing unused kernel memory: 192K
[    5.521611] This architecture does not have kernel memory protection.
INIT: version 2.88 booting

   Jonas

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

* Re: [PATCH 0/8] clocksource: Generalize Faraday timer
  2017-05-18 10:32   ` Jonas Jensen
@ 2017-05-18 12:11     ` Linus Walleij
  -1 siblings, 0 replies; 40+ messages in thread
From: Linus Walleij @ 2017-05-18 12:11 UTC (permalink / raw)
  To: Jonas Jensen
  Cc: Daniel Lezcano, Thomas Gleixner, Joel Stanley, Janos Laube,
	Paulius Zaleckas, linux-arm-kernel, Hans Ulli Kroll,
	Florian Fainelli, linux-kernel

On Thu, May 18, 2017 at 12:32 PM, Jonas Jensen <jonas.jensen@gmail.com> wrote:
> On 17 May 2017 at 16:05, Linus Walleij <linus.walleij@linaro.org> wrote:
>> The patches can be applied as soon as Jonas Jensen and Joel
>> Stanley says they work for them.
>
> Thanks! fttmr010 seem to work OK!
>
> I did the usual test on UC-7112-LX [1] after merging
> linux-nomadik/fttmr010 into next-20170518.

Thanks a lot! I'll add your Tested-by tags (if I need to repost, else
I guess Daniel can add it when applying).

I'm really curious to see if it also works on Aspeed.

Yours,
Linus Walleij

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

* [PATCH 0/8] clocksource: Generalize Faraday timer
@ 2017-05-18 12:11     ` Linus Walleij
  0 siblings, 0 replies; 40+ messages in thread
From: Linus Walleij @ 2017-05-18 12:11 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, May 18, 2017 at 12:32 PM, Jonas Jensen <jonas.jensen@gmail.com> wrote:
> On 17 May 2017 at 16:05, Linus Walleij <linus.walleij@linaro.org> wrote:
>> The patches can be applied as soon as Jonas Jensen and Joel
>> Stanley says they work for them.
>
> Thanks! fttmr010 seem to work OK!
>
> I did the usual test on UC-7112-LX [1] after merging
> linux-nomadik/fttmr010 into next-20170518.

Thanks a lot! I'll add your Tested-by tags (if I need to repost, else
I guess Daniel can add it when applying).

I'm really curious to see if it also works on Aspeed.

Yours,
Linus Walleij

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

* Re: [PATCH 7/8] clocksource/drivers/fttmr010: Merge Moxa into FTTMR010
  2017-05-18  7:22     ` Joel Stanley
@ 2017-05-18 12:43       ` Linus Walleij
  -1 siblings, 0 replies; 40+ messages in thread
From: Linus Walleij @ 2017-05-18 12:43 UTC (permalink / raw)
  To: Joel Stanley
  Cc: Daniel Lezcano, Thomas Gleixner, Jonas Jensen, Janos Laube,
	Paulius Zaleckas, linux-arm-kernel, Hans Ulli Kroll,
	Florian Fainelli, Linux Kernel Mailing List,
	Benjamin Herrenschmidt, Ryan Chen, Cédric Le Goater

On Thu, May 18, 2017 at 9:22 AM, Joel Stanley <joel@jms.id.au> wrote:
> On Wed, May 17, 2017 at 10:05 PM, Linus Walleij
> <linus.walleij@linaro.org> wrote:
>> This merges the Moxa Art timer driver into the Faraday FTTMR010
>> driver and replaces all Kconfig symbols to use the Faraday
>> driver instead. We are now so similar that the drivers can
>> be merged by just adding a few lines to the Faraday timer.
>
> Nice work!
>
> I gave this a spin on hardware and it didn't work :(

How typical.

> Thanks for the rework! Unfortunately the Aspeed IP does not have bits
> to control the direction of counting, and the timers only count down.
> Bits 3, 7 and 11 are marked reserved in the data sheet. Can you rework
> the patch to count down?

How unintuitive.

I guess I will just make it handle the Aspeed separately, so we
count up on Gemini and Moxa and down on Aspeed if that is all
it can do.

> As an aside, we have a pretty decent model for the Aspeed SoCs in
> Qemu. If you want to use it to smoketest your rework:
>
>  $ qemu-system-arm -m 512 -M ast2500-evb -nodefaults -nographic
> -serial stdio -kernel arch/arm/boot/zImage -dtb
> arch/arm/boot/dts/aspeed-ast2500-evb.dtb
>
> I tested with Ubuntu's qemu v2.8. It looks like we have a bug when the
> kernel tries to use the clock the way your driver works, so we will
> look at that. It does function properly for the current upstream code.

Oh that's sweet! I'll test it if I can get it working like this.

Yours,
Linus Walleij

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

* [PATCH 7/8] clocksource/drivers/fttmr010: Merge Moxa into FTTMR010
@ 2017-05-18 12:43       ` Linus Walleij
  0 siblings, 0 replies; 40+ messages in thread
From: Linus Walleij @ 2017-05-18 12:43 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, May 18, 2017 at 9:22 AM, Joel Stanley <joel@jms.id.au> wrote:
> On Wed, May 17, 2017 at 10:05 PM, Linus Walleij
> <linus.walleij@linaro.org> wrote:
>> This merges the Moxa Art timer driver into the Faraday FTTMR010
>> driver and replaces all Kconfig symbols to use the Faraday
>> driver instead. We are now so similar that the drivers can
>> be merged by just adding a few lines to the Faraday timer.
>
> Nice work!
>
> I gave this a spin on hardware and it didn't work :(

How typical.

> Thanks for the rework! Unfortunately the Aspeed IP does not have bits
> to control the direction of counting, and the timers only count down.
> Bits 3, 7 and 11 are marked reserved in the data sheet. Can you rework
> the patch to count down?

How unintuitive.

I guess I will just make it handle the Aspeed separately, so we
count up on Gemini and Moxa and down on Aspeed if that is all
it can do.

> As an aside, we have a pretty decent model for the Aspeed SoCs in
> Qemu. If you want to use it to smoketest your rework:
>
>  $ qemu-system-arm -m 512 -M ast2500-evb -nodefaults -nographic
> -serial stdio -kernel arch/arm/boot/zImage -dtb
> arch/arm/boot/dts/aspeed-ast2500-evb.dtb
>
> I tested with Ubuntu's qemu v2.8. It looks like we have a bug when the
> kernel tries to use the clock the way your driver works, so we will
> look at that. It does function properly for the current upstream code.

Oh that's sweet! I'll test it if I can get it working like this.

Yours,
Linus Walleij

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

* Re: [PATCH 7/8] clocksource/drivers/fttmr010: Merge Moxa into FTTMR010
  2017-05-18 12:43       ` Linus Walleij
@ 2017-05-18 13:12         ` Cédric Le Goater
  -1 siblings, 0 replies; 40+ messages in thread
From: Cédric Le Goater @ 2017-05-18 13:12 UTC (permalink / raw)
  To: Linus Walleij, Joel Stanley
  Cc: Daniel Lezcano, Thomas Gleixner, Jonas Jensen, Janos Laube,
	Paulius Zaleckas, linux-arm-kernel, Hans Ulli Kroll,
	Florian Fainelli, Linux Kernel Mailing List,
	Benjamin Herrenschmidt, Ryan Chen

>> As an aside, we have a pretty decent model for the Aspeed SoCs in
>> Qemu. If you want to use it to smoketest your rework:
>>
>>  $ qemu-system-arm -m 512 -M ast2500-evb -nodefaults -nographic
>> -serial stdio -kernel arch/arm/boot/zImage -dtb
>> arch/arm/boot/dts/aspeed-ast2500-evb.dtb
>>
>> I tested with Ubuntu's qemu v2.8. It looks like we have a bug when the
>> kernel tries to use the clock the way your driver works, so we will
>> look at that. It does function properly for the current upstream code.
> 
> Oh that's sweet! I'll test it if I can get it working like this.

In case you need a small ramfs, here is one :

	https://openpower.xyz/job/openbmc-build/distro=ubuntu,target=evb-ast2500/lastSuccessfulBuild/artifact/images/evb-ast2500/obmc-phosphor-initramfs-evb-ast2500.cpio.lzma

Cheers,

C. 

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

* [PATCH 7/8] clocksource/drivers/fttmr010: Merge Moxa into FTTMR010
@ 2017-05-18 13:12         ` Cédric Le Goater
  0 siblings, 0 replies; 40+ messages in thread
From: Cédric Le Goater @ 2017-05-18 13:12 UTC (permalink / raw)
  To: linux-arm-kernel

>> As an aside, we have a pretty decent model for the Aspeed SoCs in
>> Qemu. If you want to use it to smoketest your rework:
>>
>>  $ qemu-system-arm -m 512 -M ast2500-evb -nodefaults -nographic
>> -serial stdio -kernel arch/arm/boot/zImage -dtb
>> arch/arm/boot/dts/aspeed-ast2500-evb.dtb
>>
>> I tested with Ubuntu's qemu v2.8. It looks like we have a bug when the
>> kernel tries to use the clock the way your driver works, so we will
>> look at that. It does function properly for the current upstream code.
> 
> Oh that's sweet! I'll test it if I can get it working like this.

In case you need a small ramfs, here is one :

	https://openpower.xyz/job/openbmc-build/distro=ubuntu,target=evb-ast2500/lastSuccessfulBuild/artifact/images/evb-ast2500/obmc-phosphor-initramfs-evb-ast2500.cpio.lzma

Cheers,

C. 

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

* Re: [PATCH 0/8] clocksource: Generalize Faraday timer
  2017-05-18 12:11     ` Linus Walleij
@ 2017-05-18 13:31       ` Daniel Lezcano
  -1 siblings, 0 replies; 40+ messages in thread
From: Daniel Lezcano @ 2017-05-18 13:31 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Jonas Jensen, Thomas Gleixner, Joel Stanley, Janos Laube,
	Paulius Zaleckas, linux-arm-kernel, Hans Ulli Kroll,
	Florian Fainelli, linux-kernel

On Thu, May 18, 2017 at 02:11:48PM +0200, Linus Walleij wrote:
> On Thu, May 18, 2017 at 12:32 PM, Jonas Jensen <jonas.jensen@gmail.com> wrote:
> > On 17 May 2017 at 16:05, Linus Walleij <linus.walleij@linaro.org> wrote:
> >> The patches can be applied as soon as Jonas Jensen and Joel
> >> Stanley says they work for them.
> >
> > Thanks! fttmr010 seem to work OK!
> >
> > I did the usual test on UC-7112-LX [1] after merging
> > linux-nomadik/fttmr010 into next-20170518.
> 
> Thanks a lot! I'll add your Tested-by tags (if I need to repost, else
> I guess Daniel can add it when applying).

Yes, sure. No problem.

> I'm really curious to see if it also works on Aspeed.
> 
> Yours,
> Linus Walleij

-- 

 <http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog

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

* [PATCH 0/8] clocksource: Generalize Faraday timer
@ 2017-05-18 13:31       ` Daniel Lezcano
  0 siblings, 0 replies; 40+ messages in thread
From: Daniel Lezcano @ 2017-05-18 13:31 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, May 18, 2017 at 02:11:48PM +0200, Linus Walleij wrote:
> On Thu, May 18, 2017 at 12:32 PM, Jonas Jensen <jonas.jensen@gmail.com> wrote:
> > On 17 May 2017 at 16:05, Linus Walleij <linus.walleij@linaro.org> wrote:
> >> The patches can be applied as soon as Jonas Jensen and Joel
> >> Stanley says they work for them.
> >
> > Thanks! fttmr010 seem to work OK!
> >
> > I did the usual test on UC-7112-LX [1] after merging
> > linux-nomadik/fttmr010 into next-20170518.
> 
> Thanks a lot! I'll add your Tested-by tags (if I need to repost, else
> I guess Daniel can add it when applying).

Yes, sure. No problem.

> I'm really curious to see if it also works on Aspeed.
> 
> Yours,
> Linus Walleij

-- 

 <http://www.linaro.org/> Linaro.org ? Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog

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

* Re: [PATCH 7/8] clocksource/drivers/fttmr010: Merge Moxa into FTTMR010
  2017-05-18 12:43       ` Linus Walleij
@ 2017-05-18 20:20         ` Linus Walleij
  -1 siblings, 0 replies; 40+ messages in thread
From: Linus Walleij @ 2017-05-18 20:20 UTC (permalink / raw)
  To: Joel Stanley
  Cc: Daniel Lezcano, Thomas Gleixner, Jonas Jensen, Janos Laube,
	Paulius Zaleckas, linux-arm-kernel, Hans Ulli Kroll,
	Florian Fainelli, Linux Kernel Mailing List,
	Benjamin Herrenschmidt, Ryan Chen, Cédric Le Goater

On Thu, May 18, 2017 at 2:43 PM, Linus Walleij <linus.walleij@linaro.org> wrote:
> On Thu, May 18, 2017 at 9:22 AM, Joel Stanley <joel@jms.id.au> wrote:
>> On Wed, May 17, 2017 at 10:05 PM, Linus Walleij
>> <linus.walleij@linaro.org> wrote:
>>> This merges the Moxa Art timer driver into the Faraday FTTMR010
>>> driver and replaces all Kconfig symbols to use the Faraday
>>> driver instead. We are now so similar that the drivers can
>>> be merged by just adding a few lines to the Faraday timer.
>>
>> Nice work!
>>
>> I gave this a spin on hardware and it didn't work :(
>
> How typical.

I sent a v2 patch set.

I couldn't get qemu to work because Fedora's QEMU is not
up-to-date and I didn't want to venture into compiling from source...

I did the second best and tested Gemini with downward counting
timers, after just adding that as general code path in the driver
in the commit merging the two drivers.

Please test it, and I hope I'm not wasting too much of your time :/

If it still doesn't work I guess I have to try to get qemu going.

The fttmr010 branch in my git is updated:
https://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-nomadik.git/

Yours,
Linus Walleij

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

* [PATCH 7/8] clocksource/drivers/fttmr010: Merge Moxa into FTTMR010
@ 2017-05-18 20:20         ` Linus Walleij
  0 siblings, 0 replies; 40+ messages in thread
From: Linus Walleij @ 2017-05-18 20:20 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, May 18, 2017 at 2:43 PM, Linus Walleij <linus.walleij@linaro.org> wrote:
> On Thu, May 18, 2017 at 9:22 AM, Joel Stanley <joel@jms.id.au> wrote:
>> On Wed, May 17, 2017 at 10:05 PM, Linus Walleij
>> <linus.walleij@linaro.org> wrote:
>>> This merges the Moxa Art timer driver into the Faraday FTTMR010
>>> driver and replaces all Kconfig symbols to use the Faraday
>>> driver instead. We are now so similar that the drivers can
>>> be merged by just adding a few lines to the Faraday timer.
>>
>> Nice work!
>>
>> I gave this a spin on hardware and it didn't work :(
>
> How typical.

I sent a v2 patch set.

I couldn't get qemu to work because Fedora's QEMU is not
up-to-date and I didn't want to venture into compiling from source...

I did the second best and tested Gemini with downward counting
timers, after just adding that as general code path in the driver
in the commit merging the two drivers.

Please test it, and I hope I'm not wasting too much of your time :/

If it still doesn't work I guess I have to try to get qemu going.

The fttmr010 branch in my git is updated:
https://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-nomadik.git/

Yours,
Linus Walleij

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

* Re: [PATCH 7/8] clocksource/drivers/fttmr010: Merge Moxa into FTTMR010
  2017-05-18 20:20         ` Linus Walleij
@ 2017-05-18 21:09           ` Cédric Le Goater
  -1 siblings, 0 replies; 40+ messages in thread
From: Cédric Le Goater @ 2017-05-18 21:09 UTC (permalink / raw)
  To: Linus Walleij, Joel Stanley
  Cc: Daniel Lezcano, Thomas Gleixner, Jonas Jensen, Janos Laube,
	Paulius Zaleckas, linux-arm-kernel, Hans Ulli Kroll,
	Florian Fainelli, Linux Kernel Mailing List,
	Benjamin Herrenschmidt, Ryan Chen

On 05/18/2017 10:20 PM, Linus Walleij wrote:
> On Thu, May 18, 2017 at 2:43 PM, Linus Walleij <linus.walleij@linaro.org> wrote:
>> On Thu, May 18, 2017 at 9:22 AM, Joel Stanley <joel@jms.id.au> wrote:
>>> On Wed, May 17, 2017 at 10:05 PM, Linus Walleij
>>> <linus.walleij@linaro.org> wrote:
>>>> This merges the Moxa Art timer driver into the Faraday FTTMR010
>>>> driver and replaces all Kconfig symbols to use the Faraday
>>>> driver instead. We are now so similar that the drivers can
>>>> be merged by just adding a few lines to the Faraday timer.
>>>
>>> Nice work!
>>>
>>> I gave this a spin on hardware and it didn't work :(
>>
>> How typical.
> 
> I sent a v2 patch set.
> 
> I couldn't get qemu to work because Fedora's QEMU is not
> up-to-date and I didn't want to venture into compiling from source...
> 
> I did the second best and tested Gemini with downward counting
> timers, after just adding that as general code path in the driver
> in the commit merging the two drivers.
> 
> Please test it, and I hope I'm not wasting too much of your time :/
> 
> If it still doesn't work I guess I have to try to get qemu going.
> 
> The fttmr010 branch in my git is updated:
> https://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-nomadik.git/

So a real AST2500 evb board boot fines with this branch but the timer 
model in QEMU crashes miserably :

	[    0.000000] NR_IRQS:16 nr_irqs:16 16
	Floating point exception (core dumped)

that is just before :

	[    0.000000] clocksource: FTTMR010-TIMER2: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 77222644334 ns
	[    0.000025] sched_clock: 32 bits at 24MHz, resolution 40ns, wraps every 86767015915ns

Something to look at in QEMU.

Joel, do you confirm ? 

Thanks,

C.  

	

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

* [PATCH 7/8] clocksource/drivers/fttmr010: Merge Moxa into FTTMR010
@ 2017-05-18 21:09           ` Cédric Le Goater
  0 siblings, 0 replies; 40+ messages in thread
From: Cédric Le Goater @ 2017-05-18 21:09 UTC (permalink / raw)
  To: linux-arm-kernel

On 05/18/2017 10:20 PM, Linus Walleij wrote:
> On Thu, May 18, 2017 at 2:43 PM, Linus Walleij <linus.walleij@linaro.org> wrote:
>> On Thu, May 18, 2017 at 9:22 AM, Joel Stanley <joel@jms.id.au> wrote:
>>> On Wed, May 17, 2017 at 10:05 PM, Linus Walleij
>>> <linus.walleij@linaro.org> wrote:
>>>> This merges the Moxa Art timer driver into the Faraday FTTMR010
>>>> driver and replaces all Kconfig symbols to use the Faraday
>>>> driver instead. We are now so similar that the drivers can
>>>> be merged by just adding a few lines to the Faraday timer.
>>>
>>> Nice work!
>>>
>>> I gave this a spin on hardware and it didn't work :(
>>
>> How typical.
> 
> I sent a v2 patch set.
> 
> I couldn't get qemu to work because Fedora's QEMU is not
> up-to-date and I didn't want to venture into compiling from source...
> 
> I did the second best and tested Gemini with downward counting
> timers, after just adding that as general code path in the driver
> in the commit merging the two drivers.
> 
> Please test it, and I hope I'm not wasting too much of your time :/
> 
> If it still doesn't work I guess I have to try to get qemu going.
> 
> The fttmr010 branch in my git is updated:
> https://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-nomadik.git/

So a real AST2500 evb board boot fines with this branch but the timer 
model in QEMU crashes miserably :

	[    0.000000] NR_IRQS:16 nr_irqs:16 16
	Floating point exception (core dumped)

that is just before :

	[    0.000000] clocksource: FTTMR010-TIMER2: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 77222644334 ns
	[    0.000025] sched_clock: 32 bits at 24MHz, resolution 40ns, wraps every 86767015915ns

Something to look at in QEMU.

Joel, do you confirm ? 

Thanks,

C.  

	

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

* Re: [PATCH 7/8] clocksource/drivers/fttmr010: Merge Moxa into FTTMR010
  2017-05-18 21:09           ` Cédric Le Goater
@ 2017-05-19  7:59             ` Cédric Le Goater
  -1 siblings, 0 replies; 40+ messages in thread
From: Cédric Le Goater @ 2017-05-19  7:59 UTC (permalink / raw)
  To: Linus Walleij, Joel Stanley
  Cc: Daniel Lezcano, Thomas Gleixner, Jonas Jensen, Janos Laube,
	Paulius Zaleckas, linux-arm-kernel, Hans Ulli Kroll,
	Florian Fainelli, Linux Kernel Mailing List,
	Benjamin Herrenschmidt, Ryan Chen

On 05/18/2017 11:09 PM, Cédric Le Goater wrote:
> On 05/18/2017 10:20 PM, Linus Walleij wrote:
>> On Thu, May 18, 2017 at 2:43 PM, Linus Walleij <linus.walleij@linaro.org> wrote:
>>> On Thu, May 18, 2017 at 9:22 AM, Joel Stanley <joel@jms.id.au> wrote:
>>>> On Wed, May 17, 2017 at 10:05 PM, Linus Walleij
>>>> <linus.walleij@linaro.org> wrote:
>>>>> This merges the Moxa Art timer driver into the Faraday FTTMR010
>>>>> driver and replaces all Kconfig symbols to use the Faraday
>>>>> driver instead. We are now so similar that the drivers can
>>>>> be merged by just adding a few lines to the Faraday timer.
>>>>
>>>> Nice work!
>>>>
>>>> I gave this a spin on hardware and it didn't work :(
>>>
>>> How typical.
>>
>> I sent a v2 patch set.
>>
>> I couldn't get qemu to work because Fedora's QEMU is not
>> up-to-date and I didn't want to venture into compiling from source...
>>
>> I did the second best and tested Gemini with downward counting
>> timers, after just adding that as general code path in the driver
>> in the commit merging the two drivers.
>>
>> Please test it, and I hope I'm not wasting too much of your time :/
>>
>> If it still doesn't work I guess I have to try to get qemu going.
>>
>> The fttmr010 branch in my git is updated:
>> https://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-nomadik.git/
> 
> So a real AST2500 evb board boot fines with this branch but the timer 
> model in QEMU crashes miserably :
> 
> 	[    0.000000] NR_IRQS:16 nr_irqs:16 16
> 	Floating point exception (core dumped)

This is because the FTTMR010 driver enables a timer before setting
its reload value. This is 'against' the specs but the HW works fine
as it only starts decrementing when a reload is set.   

So, I changed the QEMU model.

Cheers,

C.   

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

* [PATCH 7/8] clocksource/drivers/fttmr010: Merge Moxa into FTTMR010
@ 2017-05-19  7:59             ` Cédric Le Goater
  0 siblings, 0 replies; 40+ messages in thread
From: Cédric Le Goater @ 2017-05-19  7:59 UTC (permalink / raw)
  To: linux-arm-kernel

On 05/18/2017 11:09 PM, C?dric Le Goater wrote:
> On 05/18/2017 10:20 PM, Linus Walleij wrote:
>> On Thu, May 18, 2017 at 2:43 PM, Linus Walleij <linus.walleij@linaro.org> wrote:
>>> On Thu, May 18, 2017 at 9:22 AM, Joel Stanley <joel@jms.id.au> wrote:
>>>> On Wed, May 17, 2017 at 10:05 PM, Linus Walleij
>>>> <linus.walleij@linaro.org> wrote:
>>>>> This merges the Moxa Art timer driver into the Faraday FTTMR010
>>>>> driver and replaces all Kconfig symbols to use the Faraday
>>>>> driver instead. We are now so similar that the drivers can
>>>>> be merged by just adding a few lines to the Faraday timer.
>>>>
>>>> Nice work!
>>>>
>>>> I gave this a spin on hardware and it didn't work :(
>>>
>>> How typical.
>>
>> I sent a v2 patch set.
>>
>> I couldn't get qemu to work because Fedora's QEMU is not
>> up-to-date and I didn't want to venture into compiling from source...
>>
>> I did the second best and tested Gemini with downward counting
>> timers, after just adding that as general code path in the driver
>> in the commit merging the two drivers.
>>
>> Please test it, and I hope I'm not wasting too much of your time :/
>>
>> If it still doesn't work I guess I have to try to get qemu going.
>>
>> The fttmr010 branch in my git is updated:
>> https://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-nomadik.git/
> 
> So a real AST2500 evb board boot fines with this branch but the timer 
> model in QEMU crashes miserably :
> 
> 	[    0.000000] NR_IRQS:16 nr_irqs:16 16
> 	Floating point exception (core dumped)

This is because the FTTMR010 driver enables a timer before setting
its reload value. This is 'against' the specs but the HW works fine
as it only starts decrementing when a reload is set.   

So, I changed the QEMU model.

Cheers,

C.   

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

* Re: [PATCH 2/8] clocksource/drivers/fttmr010: Merge FTTMR010 DT bindings
@ 2017-05-23  0:51     ` Rob Herring
  0 siblings, 0 replies; 40+ messages in thread
From: Rob Herring @ 2017-05-23  0:51 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Daniel Lezcano, Thomas Gleixner, Joel Stanley, Jonas Jensen,
	Janos Laube, Paulius Zaleckas, linux-arm-kernel, Hans Ulli Kroll,
	Florian Fainelli, linux-kernel, devicetree

On Wed, May 17, 2017 at 04:05:36PM +0200, Linus Walleij wrote:
> This merges the Moxa and FTTMR010 device tree bindings into the
> Faraday binding document to avoid confusion.
> 
> The FTTMR010 is the IP block used by these SoCs, in vanilla
> or modified variant.
> 
> The Aspeed variant is modified such that it is no longer fully
> register-compatible with FTTMR010 so for this reason it is not
> listed with two compatible strings, instead just one.
> 
> Cc: devicetree@vger.kernel.org
> Cc: Rob Herring <robh+dt@kernel.org>
> Cc: Joel Stanley <joel@jms.id.au>
> Cc: Jonas Jensen <jonas.jensen@gmail.com>
> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
> ---
>  .../devicetree/bindings/timer/faraday,fttmr010.txt    |  4 +++-
>  .../devicetree/bindings/timer/moxa,moxart-timer.txt   | 19 -------------------
>  2 files changed, 3 insertions(+), 20 deletions(-)
>  delete mode 100644 Documentation/devicetree/bindings/timer/moxa,moxart-timer.txt

Acked-by: Rob Herring <robh@kernel.org> 

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

* Re: [PATCH 2/8] clocksource/drivers/fttmr010: Merge FTTMR010 DT bindings
@ 2017-05-23  0:51     ` Rob Herring
  0 siblings, 0 replies; 40+ messages in thread
From: Rob Herring @ 2017-05-23  0:51 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Daniel Lezcano, Thomas Gleixner, Joel Stanley, Jonas Jensen,
	Janos Laube, Paulius Zaleckas,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	Hans Ulli Kroll, Florian Fainelli,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA

On Wed, May 17, 2017 at 04:05:36PM +0200, Linus Walleij wrote:
> This merges the Moxa and FTTMR010 device tree bindings into the
> Faraday binding document to avoid confusion.
> 
> The FTTMR010 is the IP block used by these SoCs, in vanilla
> or modified variant.
> 
> The Aspeed variant is modified such that it is no longer fully
> register-compatible with FTTMR010 so for this reason it is not
> listed with two compatible strings, instead just one.
> 
> Cc: devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> Cc: Rob Herring <robh+dt-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
> Cc: Joel Stanley <joel-U3u1mxZcP9KHXe+LvDLADg@public.gmane.org>
> Cc: Jonas Jensen <jonas.jensen-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
> Signed-off-by: Linus Walleij <linus.walleij-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
> ---
>  .../devicetree/bindings/timer/faraday,fttmr010.txt    |  4 +++-
>  .../devicetree/bindings/timer/moxa,moxart-timer.txt   | 19 -------------------
>  2 files changed, 3 insertions(+), 20 deletions(-)
>  delete mode 100644 Documentation/devicetree/bindings/timer/moxa,moxart-timer.txt

Acked-by: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org> 

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [PATCH 2/8] clocksource/drivers/fttmr010: Merge FTTMR010 DT bindings
@ 2017-05-23  0:51     ` Rob Herring
  0 siblings, 0 replies; 40+ messages in thread
From: Rob Herring @ 2017-05-23  0:51 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, May 17, 2017 at 04:05:36PM +0200, Linus Walleij wrote:
> This merges the Moxa and FTTMR010 device tree bindings into the
> Faraday binding document to avoid confusion.
> 
> The FTTMR010 is the IP block used by these SoCs, in vanilla
> or modified variant.
> 
> The Aspeed variant is modified such that it is no longer fully
> register-compatible with FTTMR010 so for this reason it is not
> listed with two compatible strings, instead just one.
> 
> Cc: devicetree at vger.kernel.org
> Cc: Rob Herring <robh+dt@kernel.org>
> Cc: Joel Stanley <joel@jms.id.au>
> Cc: Jonas Jensen <jonas.jensen@gmail.com>
> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
> ---
>  .../devicetree/bindings/timer/faraday,fttmr010.txt    |  4 +++-
>  .../devicetree/bindings/timer/moxa,moxart-timer.txt   | 19 -------------------
>  2 files changed, 3 insertions(+), 20 deletions(-)
>  delete mode 100644 Documentation/devicetree/bindings/timer/moxa,moxart-timer.txt

Acked-by: Rob Herring <robh@kernel.org> 

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

end of thread, other threads:[~2017-05-23  0:51 UTC | newest]

Thread overview: 40+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-05-17 14:05 [PATCH 0/8] clocksource: Generalize Faraday timer Linus Walleij
2017-05-17 14:05 ` Linus Walleij
2017-05-17 14:05 ` [PATCH 1/8] clocksource/drivers/fttmr010: Fix the clock handling Linus Walleij
2017-05-17 14:05   ` Linus Walleij
2017-05-17 14:05 ` [PATCH 2/8] clocksource/drivers/fttmr010: Merge FTTMR010 DT bindings Linus Walleij
2017-05-17 14:05   ` Linus Walleij
2017-05-17 14:05   ` Linus Walleij
2017-05-23  0:51   ` Rob Herring
2017-05-23  0:51     ` Rob Herring
2017-05-23  0:51     ` Rob Herring
2017-05-17 14:05 ` [PATCH 3/8] clocksource/drivers/fttmr010: Drop Gemini specifics Linus Walleij
2017-05-17 14:05   ` Linus Walleij
2017-05-17 14:05 ` [PATCH 4/8] clocksource/drivers/fttmr010: Use state container Linus Walleij
2017-05-17 14:05   ` Linus Walleij
2017-05-17 14:05 ` [PATCH 5/8] clocksource/drivers/fttmr010: Switch to use bitops Linus Walleij
2017-05-17 14:05   ` Linus Walleij
2017-05-17 14:05 ` [PATCH 6/8] clocksource/drivers/fttmr010: Switch to use TIMER2 src Linus Walleij
2017-05-17 14:05   ` Linus Walleij
2017-05-17 14:05 ` [PATCH 7/8] clocksource/drivers/fttmr010: Merge Moxa into FTTMR010 Linus Walleij
2017-05-17 14:05   ` Linus Walleij
2017-05-18  7:22   ` Joel Stanley
2017-05-18  7:22     ` Joel Stanley
2017-05-18 12:43     ` Linus Walleij
2017-05-18 12:43       ` Linus Walleij
2017-05-18 13:12       ` Cédric Le Goater
2017-05-18 13:12         ` Cédric Le Goater
2017-05-18 20:20       ` Linus Walleij
2017-05-18 20:20         ` Linus Walleij
2017-05-18 21:09         ` Cédric Le Goater
2017-05-18 21:09           ` Cédric Le Goater
2017-05-19  7:59           ` Cédric Le Goater
2017-05-19  7:59             ` Cédric Le Goater
2017-05-17 14:05 ` [PATCH 8/8] ARM: dts: augment Moxa and Aspeed DTS for FTTMR010 Linus Walleij
2017-05-17 14:05   ` Linus Walleij
2017-05-18 10:32 ` [PATCH 0/8] clocksource: Generalize Faraday timer Jonas Jensen
2017-05-18 10:32   ` Jonas Jensen
2017-05-18 12:11   ` Linus Walleij
2017-05-18 12:11     ` Linus Walleij
2017-05-18 13:31     ` Daniel Lezcano
2017-05-18 13:31       ` Daniel Lezcano

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.