ARM: dts: Change dw-apb-timer-osc and dw-apb-timer-sp to just dw-apb-timer
PATCH v2 1/2 ARM: dts: Change dw-apb-timer-osc and dw-apb-timer-sp to just dw-apb-timer
From: Dinh Nguyen <[email protected]>
"dw-apb-timer-osc" and "dw-apb-timer-sp" are the same implementation of the DW APB timer, just fed by different clocks. Thus, deprecate both "dw-apb-timer-osc" and "dw-apb-timer-sp" in lieu of "dw-apb-timer",
Clean up the timer entries for socfpga by removing timer<n> and set the correct clocks for the timers.
v2:
- Deprecate the "dw-apb-timer-osc" and "dw-apb-timer-sp" but maintain backwards compatibility in the driver.
--- Documentation/devicetree/bindings/rtc/dw-apb.txt | 32 ++++++---------------- arch/arm/boot/dts/socfpga.dtsi | 24 ++++++++-------- arch/arm/boot/dts/socfpga_cyclone5.dts | 8 +++--- arch/arm/boot/dts/socfpga_vt.dts | 8 +++--- 4 files changed, 29 insertions(+), 43 deletions(-)
Documentation/devicetree/bindings/rtc/dw-apb.txt +9 -23
@@ -1,7 +1,8 @@ * Designware APB timer Required properties: -- compatible: "snps,dw-apb-timer-sp" or "snps,dw-apb-timer-osc" +- compatible: "snps,dw-apb-timer-sp" or "snps,dw-apb-timer-osc" <DEPRECATED> +- compatible: "snps,dw-apb-timer" - reg: physical base address of the controller and length of memory mapped region. - interrupts: IRQ line for the timer.
@@ -20,25 +21,10 @@ systems may use one. Example: - - timer1: timer at ffc09000 { - compatible = "snps,dw-apb-timer-sp"; - interrupts = <0 168 4>; - clock-frequency = <200000000>; - reg = <0xffc09000 0x1000>; - }; - - timer2: timer at ffd00000 { - compatible = "snps,dw-apb-timer-osc"; - interrupts = <0 169 4>; - clock-frequency = <200000000>; - reg = <0xffd00000 0x1000>; - }; - - timer3: timer at ffe00000 { - compatible = "snps,dw-apb-timer-osc"; - interrupts = <0 170 4>; - reg = <0xffe00000 0x1000>; - clocks = <&timer_clk>, <&timer_pclk>; - clock-names = "timer", "pclk"; - }; + timer at ffe00000 { + compatible = "snps,dw-apb-timer"; + interrupts = <0 170 4>; + reg = <0xffe00000 0x1000>; + clocks = <&timer_clk>, <&timer_pclk>; + clock-names = "timer", "pclk"; + };
arch/arm/boot/dts/socfpga.dtsi +12 -12
@@ -26,10 +26,6 @@ ethernet1 = &gmac1; serial0 = &uart0; serial1 = &uart1; - timer0 = &timer0; - timer1 = &timer1; - timer2 = &timer2; - timer3 = &timer3; }; cpus {
@@ -486,28 +482,32 @@ interrupts = <1 13 0xf04>; }; - timer0: timer0 at ffc08000 { - compatible = "snps,dw-apb-timer-sp"; + timer at ffc08000 { + compatible = "snps,dw-apb-timer"; interrupts = <0 167 4>; reg = <0xffc08000 0x1000>; + clocks = <&osc>; }; - timer1: timer1 at ffc09000 { - compatible = "snps,dw-apb-timer-sp"; + timer at ffc09000 { + compatible = "snps,dw-apb-timer"; interrupts = <0 168 4>; reg = <0xffc09000 0x1000>; + clocks = <&osc>; }; - timer2: timer2 at ffd00000 { - compatible = "snps,dw-apb-timer-osc"; + timer at ffd00000 { + compatible = "snps,dw-apb-timer"; interrupts = <0 169 4>; reg = <0xffd00000 0x1000>; + clocks = <&l4_sp_clk>; }; - timer3: timer3 at ffd01000 { - compatible = "snps,dw-apb-timer-osc"; + timer at ffd01000 { + compatible = "snps,dw-apb-timer"; interrupts = <0 170 4>; reg = <0xffd01000 0x1000>; + clocks = <&l4_sp_clk>; }; uart0: serial0 at ffc02000 {
arch/arm/boot/dts/socfpga_cyclone5.dts +4 -4
@@ -67,19 +67,19 @@ }; }; - timer0 at ffc08000 { + timer at ffc08000 { clock-frequency = <100000000>; }; - timer1 at ffc09000 { + timer at ffc09000 { clock-frequency = <100000000>; }; - timer2 at ffd00000 { + timer at ffd00000 { clock-frequency = <25000000>; }; - timer3 at ffd01000 { + timer at ffd01000 { clock-frequency = <25000000>; };
arch/arm/boot/dts/socfpga_vt.dts +4 -4
@@ -57,19 +57,19 @@ }; }; - timer0 at ffc08000 { + timer at ffc08000 { clock-frequency = <7000000>; }; - timer1 at ffc09000 { + timer at ffc09000 { clock-frequency = <7000000>; }; - timer2 at ffd00000 { + timer at ffd00000 { clock-frequency = <7000000>; }; - timer3 at ffd01000 { + timer at ffd01000 { clock-frequency = <7000000>; };
Signature · 1 line
1.7.9.5
PATCH v2 2/2 clocksource: dw_apb_timer_of: Fix read_sched_clock
From: Dinh Nguyen <[email protected]>
The read_sched_clock should return the ~value because the clock is a countdown implementation. read_sched_clock() should be the same as __apbt_read_clocksource().
If a separate timer for the sched_clock exist, then read_sched_clock() will return an incorrect value. The (sched_io_base + 0x4) needs to be in the function for both cases.
Maintain backwards compatibility for "dw-apb-timer-sp" and "dw-apb-timer-osc".
v2:
- Maintain backwards compatibility for "dw-apb-timer-sp" and "dw-apb-timer-osc".
--- drivers/clocksource/dw_apb_timer_of.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-)
drivers/clocksource/dw_apb_timer_of.c +5 -4
@@ -102,18 +102,17 @@ static void add_clocksource(struct device_node *source_timer)* timer is found. sched_io_base then points to the current_value * register of the clocksource timer. */ - sched_io_base = iobase +0x04 ; + sched_io_base = iobase; sched_rate = rate; }static u32 read_sched_clock (void ) { -return __raw_readl (sched_io_base); +return ~__raw_readl (sched_io_base +0x4 ); }static const struct of_device_id sptimer_ids[]__initconst = { { .compatible ="picochip,pc3x2-rtc" }, - { .compatible ="snps,dw-apb-timer-sp" }, {/* Sentinel */ }, };
@@ -153,4 +152,6 @@ static void __init dw_apb_timer_init(struct device_node *timer) num_called++; }CLOCKSOURCE_OF_DECLARE (pc3x2_timer,"picochip,pc3x2-timer" , dw_apb_timer_init); -CLOCKSOURCE_OF_DECLARE (apb_timer,"snps,dw-apb-timer-osc" , dw_apb_timer_init); +CLOCKSOURCE_OF_DECLARE (apb_timer_osc,"snps,dw-apb-timer-osc" , dw_apb_timer_init); +CLOCKSOURCE_OF_DECLARE (apb_timer_sp,"snps,dw-apb-timer-sp" , dw_apb_timer_init); +CLOCKSOURCE_OF_DECLARE (apb_timer,"snps,dw-apb-timer" , dw_apb_timer_init);
Signature · 1 line
1.7.9.5
PATCH v2 2/2 clocksource: dw_apb_timer_of: Fix read_sched_clock
drivers/clocksource/dw_apb_timer_of.c static void add_clocksource(struct device_node *source_timer) · line 111
Quoted 9 lines · On Thu, Aug 15, 2013 at 1:29 AM, <[email protected]> wrote:
drivers/clocksource/dw_apb_timer_of.c +2
-2- sched_io_base = iobase +0x04 ; + sched_io_base = iobase; sched_rate = rate; }static u32 read_sched_clock (void ) { -return __raw_readl (sched_io_base); +return ~__raw_readl (sched_io_base +0x4 );
So what about #define what 0x04 is?
#define MY_FOO_REGISTER_OFFSET 0x04
raw_readl(sched_io_base + MY_FOO_REGISTER_OFFSET);
You get the idea.
Yours,
Linus Walleij
PATCH v2 2/2 clocksource: dw_apb_timer_of: Fix read_sched_clock
Quoted 12 lines · Linus Walleij
drivers/clocksource/dw_apb_timer_of.c static void add_clocksource(struct device_node *source_timer) · line 111
Quoted 9 lines · On Thu, Aug 15, 2013 at 1:29 AM, <[email protected]> wrote:
drivers/clocksource/dw_apb_timer_of.c +2
-2- sched_io_base = iobase +0x04 ; + sched_io_base = iobase; sched_rate = rate; }static u32 read_sched_clock (void ) { -return __raw_readl (sched_io_base); +return ~__raw_readl (sched_io_base +0x4 );
Quoted 5 lines
So what about #define what
0x04is?#define
MY_FOO_REGISTER_OFFSET0x04
raw_readl(sched_io_base + MY_FOO_REGISTER_OFFSET);
That define is already there, #define APBTMR_N_CURRENT_VALUE 0x04, but it is in .c file, not in header.
Actually I believe I had patch that did that, and it was even applied, but it clashed with same other patches, and was dropped. (It is below, for reference).
Currently, the code _does not work_, and we have three platforms using it. It would be good to solve this now, and polish it later.
Pavel
PATCH v2 2/2 clocksource: dw_apb_timer_of: Fix read_sched_clock
Quoted 13 lines · ZY - pavel
Quoted 12 lines · Linus Walleij
Quoted 9 lines · On Thu, Aug 15, 2013 at 1:29 AM, <[email protected]> wrote:
drivers/clocksource/dw_apb_timer_of.c +2
-2- sched_io_base = iobase +0x04 ; + sched_io_base = iobase; sched_rate = rate; }static u32 read_sched_clock (void ) { -return __raw_readl (sched_io_base); +return ~__raw_readl (sched_io_base +0x4 );
Quoted 8 lines
Quoted 5 lines
So what about #define what
0x04is?#define
MY_FOO_REGISTER_OFFSET0x04
raw_readl(sched_io_base + MY_FOO_REGISTER_OFFSET);That define is already there, #define
APBTMR_N_CURRENT_VALUE0x04, but it is in .c file, not in header.
I'll send a V2 that will address this comment and Stephen Warren's.
Dinh
Quoted 206 lines
Actually I believe I had patch that did that, and it was even applied, but it clashed with same other patches, and was dropped. (It is below, for reference).
Currently, the code
_doesnotwork_, and we have three platforms using it. It would be good to solve this now, and polish it later.Pavel
From pavel at denx.de Tue May 7 22:11:26 2013
Date: Tue, 7 May 2013 22:11:26 +0200
From: Pavel Machek <[email protected]>
To: John Stultz <[email protected]>
Cc: Arnd Bergmann <[email protected]>, tglx at linutronix.de,
Jamie Iles <[email protected]>, dinguyen at altera.com, wd at denx.de, linux-arm-kernel at lists.infradead.org, olof at lixom.net, kernel list <[email protected]>
Subject: Re:dw_apb_timer_of.c: remove parts that were picoxcell-specific
Message-ID: <[email protected]>
References: <[email protected]>
<[email protected]> <[email protected]> <[email protected]> <[email protected]> <[email protected]>
MIME-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
In-Reply-To: <[email protected]>
User-Agent: Mutt/1.5.20 (2009-06-14)
Status: RO
Content-Length: 4987
Lines: 170Hi!
Quoted 7 lines
Quoted 5 lines
Quoted 3 lines
Quoted 1 line
So I guess it should go through the timekeeping tree...?
I would prefer that, but we can also take it through arm-soc, it doesn't really matter.
I see no response from timekeeping people... so if you could take it, that would be great.
I don't think the original patch ever made it to my inbox.
For some reason, I cced johnstul at us.ibm.com. (I guess get_maintainer.pl? But it seems to behave now.) Anyway, patch is below...
It would be great if you could apply it... Thanks,
Pavel----
It seems we made a mistake when creating
dw_apb_timer_of.c:
picoxcellsched_clockhad parts that were not related todw_apb_timer, yet we moved them todw_apb_timer_of, and tried to use them on socfpga.This results in system where user/system time is not measured properly, as demonstrated by
time dd if=/dev/urandom of=/dev/zero bs=100000 count=100So this patch switches
sched_clockto hardware that exists on both platforms, and adds missingof_node_put()indw_apb_timer_init().Signed-off-by Pavel Machek <[email protected]>Acked-by Jamie Iles <[email protected]>arch/arm/mach-picoxcell/common.h +0
-2@@ -12,6 +12,4 @@#include <asm/mach/time.h> -extern void dw_apb_timer_init (void ); -#endif /* __PICOXCELL_COMMON_H__ */ drivers/clocksource/dw_apb_timer.c +0
-6@@ -21,12 +21,6 @@#define APBT_MIN_PERIOD 4#define APBT_MIN_DELTA_USEC 200 -#define APBTMR_N_LOAD_COUNT 0x00 -#define APBTMR_N_CURRENT_VALUE 0x04 -#define APBTMR_N_CONTROL 0x08 -#define APBTMR_N_EOI 0x0c -#define APBTMR_N_INT_STATUS 0x10 -#define APBTMRS_INT_STATUS 0xa0#define APBTMRS_EOI 0xa4#define APBTMRS_RAW_INT_STATUS 0xa8drivers/clocksource/dw_apb_timer_of.c +23
-29@@ -57,6 +57,15 @@ static void add_clockevent(struct device_node *event_timer)dw_apb_clockevent_register (ced); } +static void __iomem *sched_io_base; + +/* This is actually same as __apbt_read_clocksource(), but with +different interface */ +static u32 read_sched_clock_sptimer (void ) +{ +return ~__raw_readl (sched_io_base +APBTMR_N_CURRENT_VALUE ); +} +static void add_clocksource (struct device_node *source_timer) {void __iomem *iobase;@@ -71,41 +80,27 @@ static void add_clocksource(struct device_node *source_timer)dw_apb_clocksource_start (cs);dw_apb_clocksource_register (cs); -} -static void __iomem *sched_io_base; - -static u32 read_sched_clock (void ) -{ -return __raw_readl (sched_io_base); + sched_io_base = iobase; +setup_sched_clock (read_sched_clock_sptimer,32 , rate); } -static const struct of_device_id sptimer_ids[]__initconst = { - { .compatible ="picochip,pc3x2-rtc" }, +static const struct of_device_id osctimer_ids[]__initconst = { + { .compatible ="picochip,pc3x2-timer" }, + { .compatible ="snps,dw-apb-timer-osc" }, { .compatible ="snps,dw-apb-timer-sp" }, - {/* Sentinel */ }, + {/* Sentinel */ }, }; -static void init_sched_clock (void ) -{ -struct device_node *sched_timer; -u32 rate; - - sched_timer =of_find_matching_node (NULL , sptimer_ids); -if (!sched_timer) -panic ("No RTC for sched clock to use" ); +/* +You don't have to use dw_apb_timer for scheduler clock, +this should also work fine on arm: -timer_get_base_and_rate (sched_timer, &sched_io_base, &rate); -of_node_put (sched_timer); +twd_local_timer_of_register(); +arch_timer_of_register(); +arch_timer_sched_clock_init(); +*/ -setup_sched_clock (read_sched_clock,32 , rate); -} - -static const struct of_device_id osctimer_ids[]__initconst = { - { .compatible ="picochip,pc3x2-timer" }, - { .compatible ="snps,dw-apb-timer-osc" }, - {}, -};void __init dw_apb_timer_init (void ) {@@ -121,7 +116,6 @@ void __init dw_apb_timer_init(void)panic ("No timer for clocksource" );add_clocksource (source_timer); +of_node_put (event_timer);of_node_put (source_timer); - -init_sched_clock (); }include/linux/dw_apb_timer.h +6
-0@@ -17,6 +17,12 @@#include <linux/clocksource.h> #include <linux/interrupt.h> +#define APBTMR_N_LOAD_COUNT 0x00 +#define APBTMR_N_CURRENT_VALUE 0x04 +#define APBTMR_N_CONTROL 0x08 +#define APBTMR_N_EOI 0x0c +#define APBTMR_N_INT_STATUS 0x10 +#define APBTMRS_REG_SIZE 0x14struct dw_apb_timer {Signature · 3 lines
-- (english) http://www.livejournal.com/~pavelmachek (cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
PATCH v2 2/2 clocksource: dw_apb_timer_of: Fix read_sched_clock
Quoted 13 lines · Dinh Nguyen
Quoted 12 lines · ZY - pavel
Quoted 11 lines · Linus Walleij
Quoted 9 lines · On Thu, Aug 15, 2013 at 1:29 AM, <[email protected]> wrote:
drivers/clocksource/dw_apb_timer_of.c +2
-2- sched_io_base = iobase +0x04 ; + sched_io_base = iobase; sched_rate = rate; }static u32 read_sched_clock (void ) { -return __raw_readl (sched_io_base); +return ~__raw_readl (sched_io_base +0x4 );
Quoted 8 lines
Quoted 7 lines
Quoted 5 lines
So what about #define what
0x04is?#define
MY_FOO_REGISTER_OFFSET0x04
raw_readl(sched_io_base + MY_FOO_REGISTER_OFFSET);That define is already there, #define
APBTMR_N_CURRENT_VALUE0x04, but it is in .c file, not in header.I'll send a V2 that will address this comment and Stephen Warren's.
Please be sure to CC Daniel Lezcano <[email protected]> on future versions as he's now maintaining the drivers/clocksource directory.
thanks
-john
PATCH v2 1/2 ARM: dts: Change dw-apb-timer-osc and dw-apb-timer-sp to just dw-apb-timer
In reply to dinguyen at altera.comQuoted 8 lines · dinguyen at altera.com
From: Dinh Nguyen <[email protected]>
"dw-apb-timer-osc" and "dw-apb-timer-sp" are the same implementation of the DW APB timer, just fed by different clocks. Thus, deprecate both "dw-apb-timer-osc" and "dw-apb-timer-sp" in lieu of "dw-apb-timer",
Clean up the timer entries for socfpga by removing timer<n> and set the correct clocks for the timers.
Hmm. That sounds like a separate patch. Cleanup isn't the same as adding new DT compatible values...
Documentation/devicetree/bindings/rtc/dw-apb.txt line 5
Quoted 6 lines
Documentation/devicetree/bindings/rtc/dw-apb.txt +2
-1Required properties: -- compatible: "snps,dw-apb-timer-sp" or "snps,dw-apb-timer-osc" +- compatible: "snps,dw-apb-timer-sp" or "snps,dw-apb-timer-osc" <DEPRECATED> +- compatible: "snps,dw-apb-timer"
It's slightly unclear whether "snps,dw-apb-timer-sp" is deprecated. Also, listing the non-deprecated values first would be a good hint to people which they should use. How about:
compatible: One of:
"snps,dw-apb-timer" "snps,dw-apb-timer-sp" <DEPRECATED> "snps,dw-apb-timer-osc" <DEPRECATED>