From: Caesar Wang <wxt@rock-chips.com> To: daniel.lezcano@linaro.org, Heiko Stuebner <heiko@sntech.de> Cc: dianders@chromium.org, briannorris@google.com, smbarber@google.com, linux-rockchip@lists.infradead.org, Thomas Gleixner <tglx@linutronix.de>, cf@rock-chips.com, huangtao@rock-chips.com, Caesar Wang <wxt@rock-chips.com>, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org Subject: [PATCH 4/5] clocksource: rockchip: add support for rk3399 SoC Date: Wed, 25 May 2016 17:50:01 +0800 [thread overview] Message-ID: <1464169802-6033-5-git-send-email-wxt@rock-chips.com> (raw) In-Reply-To: <1464169802-6033-1-git-send-email-wxt@rock-chips.com> From: Huang Tao <huangtao@rock-chips.com> The CONTROL register offset is different from old SoCs. For Linux driver, there are not functional changes at all. Let's call it v2. Signed-off-by: Huang Tao <huangtao@rock-chips.com> Cc: Daniel Lezcano <daniel.lezcano@linaro.org> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: Heiko Stuebner <heiko@sntech.de> Tested-by: Jianqun Xu <jay.xu@rock-chips.com> Signed-off-by: Caesar Wang <wxt@rock-chips.com> --- drivers/clocksource/rockchip_timer.c | 112 ++++++++++++++++++++++++++++------- 1 file changed, 91 insertions(+), 21 deletions(-) diff --git a/drivers/clocksource/rockchip_timer.c b/drivers/clocksource/rockchip_timer.c index f3dfb1a..7ce1d08 100644 --- a/drivers/clocksource/rockchip_timer.c +++ b/drivers/clocksource/rockchip_timer.c @@ -19,8 +19,9 @@ #define TIMER_LOAD_COUNT0 0x00 #define TIMER_LOAD_COUNT1 0x04 -#define TIMER_CONTROL_REG 0x10 +#define TIMER_V1_CONTROL_REG 0x10 #define TIMER_INT_STATUS 0x18 +#define TIMER_V2_CONTROL_REG 0x1c #define TIMER_DISABLE 0x0 #define TIMER_ENABLE 0x1 @@ -46,15 +47,26 @@ static inline void __iomem *rk_base(struct clock_event_device *ce) return rk_timer(ce)->base; } -static inline void rk_timer_disable(struct clock_event_device *ce) +static inline void rk_timer_v1_disable(struct clock_event_device *ce) { - writel_relaxed(TIMER_DISABLE, rk_base(ce) + TIMER_CONTROL_REG); + writel_relaxed(TIMER_DISABLE, rk_base(ce) + TIMER_V1_CONTROL_REG); } -static inline void rk_timer_enable(struct clock_event_device *ce, u32 flags) +static inline void rk_timer_v1_enable(struct clock_event_device *ce, u32 flags) { writel_relaxed(TIMER_ENABLE | TIMER_INT_UNMASK | flags, - rk_base(ce) + TIMER_CONTROL_REG); + rk_base(ce) + TIMER_V1_CONTROL_REG); +} + +static inline void rk_timer_v2_disable(struct clock_event_device *ce) +{ + writel_relaxed(TIMER_DISABLE, rk_base(ce) + TIMER_V2_CONTROL_REG); +} + +static inline void rk_timer_v2_enable(struct clock_event_device *ce, u32 flags) +{ + writel_relaxed(TIMER_ENABLE | TIMER_INT_UNMASK | flags, + rk_base(ce) + TIMER_V2_CONTROL_REG); } static void rk_timer_update_counter(unsigned long cycles, @@ -69,44 +81,82 @@ static void rk_timer_interrupt_clear(struct clock_event_device *ce) writel_relaxed(1, rk_base(ce) + TIMER_INT_STATUS); } -static inline int rk_timer_set_next_event(unsigned long cycles, - struct clock_event_device *ce) +static int rk_timer_v1_set_next_event(unsigned long cycles, + struct clock_event_device *ce) { - rk_timer_disable(ce); + rk_timer_v1_disable(ce); rk_timer_update_counter(cycles, ce); - rk_timer_enable(ce, TIMER_MODE_USER_DEFINED_COUNT); + rk_timer_v1_enable(ce, TIMER_MODE_USER_DEFINED_COUNT); return 0; } -static int rk_timer_shutdown(struct clock_event_device *ce) +static int rk_timer_v1_shutdown(struct clock_event_device *ce) { - rk_timer_disable(ce); + rk_timer_v1_disable(ce); return 0; } -static int rk_timer_set_periodic(struct clock_event_device *ce) +static int rk_timer_v1_set_periodic(struct clock_event_device *ce) { - rk_timer_disable(ce); + rk_timer_v1_disable(ce); rk_timer_update_counter(rk_timer(ce)->freq / HZ - 1, ce); - rk_timer_enable(ce, TIMER_MODE_FREE_RUNNING); + rk_timer_v1_enable(ce, TIMER_MODE_FREE_RUNNING); return 0; } -static irqreturn_t rk_timer_interrupt(int irq, void *dev_id) +static irqreturn_t rk_timer_v1_interrupt(int irq, void *dev_id) { struct clock_event_device *ce = dev_id; rk_timer_interrupt_clear(ce); if (clockevent_state_oneshot(ce)) - rk_timer_disable(ce); + rk_timer_v1_disable(ce); ce->event_handler(ce); return IRQ_HANDLED; } -static void __init rk_timer_init(struct device_node *np) +static int rk_timer_v2_set_next_event(unsigned long cycles, + struct clock_event_device *ce) +{ + rk_timer_v2_disable(ce); + rk_timer_update_counter(cycles, ce); + rk_timer_v2_enable(ce, TIMER_MODE_USER_DEFINED_COUNT); + return 0; +} + +static int rk_timer_v2_shutdown(struct clock_event_device *ce) +{ + rk_timer_v2_disable(ce); + return 0; +} + +static int rk_timer_v2_set_periodic(struct clock_event_device *ce) +{ + rk_timer_v2_disable(ce); + rk_timer_update_counter(rk_timer(ce)->freq / HZ - 1, ce); + rk_timer_v2_enable(ce, TIMER_MODE_FREE_RUNNING); + return 0; +} + +static irqreturn_t rk_timer_v2_interrupt(int irq, void *dev_id) +{ + struct clock_event_device *ce = dev_id; + + rk_timer_interrupt_clear(ce); + + if (clockevent_state_oneshot(ce)) + rk_timer_v2_disable(ce); + + ce->event_handler(ce); + + return IRQ_HANDLED; +} + +static void __init rk_timer_init(struct device_node *np, + irq_handler_t rk_timer_interrupt) { struct clock_event_device *ce = &bc_timer.ce; struct clk *timer_clk; @@ -152,9 +202,6 @@ static void __init rk_timer_init(struct device_node *np) ce->name = TIMER_NAME; ce->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_DYNIRQ; - ce->set_next_event = rk_timer_set_next_event; - ce->set_state_shutdown = rk_timer_shutdown; - ce->set_state_periodic = rk_timer_set_periodic; ce->irq = irq; ce->cpumask = cpu_all_mask; ce->rating = 250; @@ -177,4 +224,27 @@ out_unmap: iounmap(bc_timer.base); } -CLOCKSOURCE_OF_DECLARE(rk_timer, "rockchip,rk3288-timer", rk_timer_init); +static void __init rk_timer_v1_init(struct device_node *np) +{ + struct clock_event_device *ce = &bc_timer.ce; + + ce->set_next_event = rk_timer_v1_set_next_event; + ce->set_state_shutdown = rk_timer_v1_shutdown; + ce->set_state_periodic = rk_timer_v1_set_periodic; + + rk_timer_init(np, rk_timer_v1_interrupt); +} + +static void __init rk_timer_v2_init(struct device_node *np) +{ + struct clock_event_device *ce = &bc_timer.ce; + + ce->set_next_event = rk_timer_v2_set_next_event; + ce->set_state_shutdown = rk_timer_v2_shutdown; + ce->set_state_periodic = rk_timer_v2_set_periodic; + + rk_timer_init(np, rk_timer_v2_interrupt); +} + +CLOCKSOURCE_OF_DECLARE(rk3288_timer, "rockchip,rk3288-timer", rk_timer_v1_init); +CLOCKSOURCE_OF_DECLARE(rk3399_timer, "rockchip,rk3399-timer", rk_timer_v2_init); -- 1.9.1
WARNING: multiple messages have this Message-ID (diff)
From: wxt@rock-chips.com (Caesar Wang) To: linux-arm-kernel@lists.infradead.org Subject: [PATCH 4/5] clocksource: rockchip: add support for rk3399 SoC Date: Wed, 25 May 2016 17:50:01 +0800 [thread overview] Message-ID: <1464169802-6033-5-git-send-email-wxt@rock-chips.com> (raw) In-Reply-To: <1464169802-6033-1-git-send-email-wxt@rock-chips.com> From: Huang Tao <huangtao@rock-chips.com> The CONTROL register offset is different from old SoCs. For Linux driver, there are not functional changes at all. Let's call it v2. Signed-off-by: Huang Tao <huangtao@rock-chips.com> Cc: Daniel Lezcano <daniel.lezcano@linaro.org> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: Heiko Stuebner <heiko@sntech.de> Tested-by: Jianqun Xu <jay.xu@rock-chips.com> Signed-off-by: Caesar Wang <wxt@rock-chips.com> --- drivers/clocksource/rockchip_timer.c | 112 ++++++++++++++++++++++++++++------- 1 file changed, 91 insertions(+), 21 deletions(-) diff --git a/drivers/clocksource/rockchip_timer.c b/drivers/clocksource/rockchip_timer.c index f3dfb1a..7ce1d08 100644 --- a/drivers/clocksource/rockchip_timer.c +++ b/drivers/clocksource/rockchip_timer.c @@ -19,8 +19,9 @@ #define TIMER_LOAD_COUNT0 0x00 #define TIMER_LOAD_COUNT1 0x04 -#define TIMER_CONTROL_REG 0x10 +#define TIMER_V1_CONTROL_REG 0x10 #define TIMER_INT_STATUS 0x18 +#define TIMER_V2_CONTROL_REG 0x1c #define TIMER_DISABLE 0x0 #define TIMER_ENABLE 0x1 @@ -46,15 +47,26 @@ static inline void __iomem *rk_base(struct clock_event_device *ce) return rk_timer(ce)->base; } -static inline void rk_timer_disable(struct clock_event_device *ce) +static inline void rk_timer_v1_disable(struct clock_event_device *ce) { - writel_relaxed(TIMER_DISABLE, rk_base(ce) + TIMER_CONTROL_REG); + writel_relaxed(TIMER_DISABLE, rk_base(ce) + TIMER_V1_CONTROL_REG); } -static inline void rk_timer_enable(struct clock_event_device *ce, u32 flags) +static inline void rk_timer_v1_enable(struct clock_event_device *ce, u32 flags) { writel_relaxed(TIMER_ENABLE | TIMER_INT_UNMASK | flags, - rk_base(ce) + TIMER_CONTROL_REG); + rk_base(ce) + TIMER_V1_CONTROL_REG); +} + +static inline void rk_timer_v2_disable(struct clock_event_device *ce) +{ + writel_relaxed(TIMER_DISABLE, rk_base(ce) + TIMER_V2_CONTROL_REG); +} + +static inline void rk_timer_v2_enable(struct clock_event_device *ce, u32 flags) +{ + writel_relaxed(TIMER_ENABLE | TIMER_INT_UNMASK | flags, + rk_base(ce) + TIMER_V2_CONTROL_REG); } static void rk_timer_update_counter(unsigned long cycles, @@ -69,44 +81,82 @@ static void rk_timer_interrupt_clear(struct clock_event_device *ce) writel_relaxed(1, rk_base(ce) + TIMER_INT_STATUS); } -static inline int rk_timer_set_next_event(unsigned long cycles, - struct clock_event_device *ce) +static int rk_timer_v1_set_next_event(unsigned long cycles, + struct clock_event_device *ce) { - rk_timer_disable(ce); + rk_timer_v1_disable(ce); rk_timer_update_counter(cycles, ce); - rk_timer_enable(ce, TIMER_MODE_USER_DEFINED_COUNT); + rk_timer_v1_enable(ce, TIMER_MODE_USER_DEFINED_COUNT); return 0; } -static int rk_timer_shutdown(struct clock_event_device *ce) +static int rk_timer_v1_shutdown(struct clock_event_device *ce) { - rk_timer_disable(ce); + rk_timer_v1_disable(ce); return 0; } -static int rk_timer_set_periodic(struct clock_event_device *ce) +static int rk_timer_v1_set_periodic(struct clock_event_device *ce) { - rk_timer_disable(ce); + rk_timer_v1_disable(ce); rk_timer_update_counter(rk_timer(ce)->freq / HZ - 1, ce); - rk_timer_enable(ce, TIMER_MODE_FREE_RUNNING); + rk_timer_v1_enable(ce, TIMER_MODE_FREE_RUNNING); return 0; } -static irqreturn_t rk_timer_interrupt(int irq, void *dev_id) +static irqreturn_t rk_timer_v1_interrupt(int irq, void *dev_id) { struct clock_event_device *ce = dev_id; rk_timer_interrupt_clear(ce); if (clockevent_state_oneshot(ce)) - rk_timer_disable(ce); + rk_timer_v1_disable(ce); ce->event_handler(ce); return IRQ_HANDLED; } -static void __init rk_timer_init(struct device_node *np) +static int rk_timer_v2_set_next_event(unsigned long cycles, + struct clock_event_device *ce) +{ + rk_timer_v2_disable(ce); + rk_timer_update_counter(cycles, ce); + rk_timer_v2_enable(ce, TIMER_MODE_USER_DEFINED_COUNT); + return 0; +} + +static int rk_timer_v2_shutdown(struct clock_event_device *ce) +{ + rk_timer_v2_disable(ce); + return 0; +} + +static int rk_timer_v2_set_periodic(struct clock_event_device *ce) +{ + rk_timer_v2_disable(ce); + rk_timer_update_counter(rk_timer(ce)->freq / HZ - 1, ce); + rk_timer_v2_enable(ce, TIMER_MODE_FREE_RUNNING); + return 0; +} + +static irqreturn_t rk_timer_v2_interrupt(int irq, void *dev_id) +{ + struct clock_event_device *ce = dev_id; + + rk_timer_interrupt_clear(ce); + + if (clockevent_state_oneshot(ce)) + rk_timer_v2_disable(ce); + + ce->event_handler(ce); + + return IRQ_HANDLED; +} + +static void __init rk_timer_init(struct device_node *np, + irq_handler_t rk_timer_interrupt) { struct clock_event_device *ce = &bc_timer.ce; struct clk *timer_clk; @@ -152,9 +202,6 @@ static void __init rk_timer_init(struct device_node *np) ce->name = TIMER_NAME; ce->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_DYNIRQ; - ce->set_next_event = rk_timer_set_next_event; - ce->set_state_shutdown = rk_timer_shutdown; - ce->set_state_periodic = rk_timer_set_periodic; ce->irq = irq; ce->cpumask = cpu_all_mask; ce->rating = 250; @@ -177,4 +224,27 @@ out_unmap: iounmap(bc_timer.base); } -CLOCKSOURCE_OF_DECLARE(rk_timer, "rockchip,rk3288-timer", rk_timer_init); +static void __init rk_timer_v1_init(struct device_node *np) +{ + struct clock_event_device *ce = &bc_timer.ce; + + ce->set_next_event = rk_timer_v1_set_next_event; + ce->set_state_shutdown = rk_timer_v1_shutdown; + ce->set_state_periodic = rk_timer_v1_set_periodic; + + rk_timer_init(np, rk_timer_v1_interrupt); +} + +static void __init rk_timer_v2_init(struct device_node *np) +{ + struct clock_event_device *ce = &bc_timer.ce; + + ce->set_next_event = rk_timer_v2_set_next_event; + ce->set_state_shutdown = rk_timer_v2_shutdown; + ce->set_state_periodic = rk_timer_v2_set_periodic; + + rk_timer_init(np, rk_timer_v2_interrupt); +} + +CLOCKSOURCE_OF_DECLARE(rk3288_timer, "rockchip,rk3288-timer", rk_timer_v1_init); +CLOCKSOURCE_OF_DECLARE(rk3399_timer, "rockchip,rk3399-timer", rk_timer_v2_init); -- 1.9.1
next prev parent reply other threads:[~2016-05-25 9:50 UTC|newest] Thread overview: 42+ messages / expand[flat|nested] mbox.gz Atom feed top 2016-05-25 9:49 [PATCH 0/5] clocksource: rockchip/timer: Support rktimer for rk3399 Caesar Wang 2016-05-25 9:49 ` Caesar Wang 2016-05-25 9:49 ` [PATCH 1/5] dt-bindings: document rk3399 rk-timer bindings Caesar Wang 2016-05-25 9:49 ` Caesar Wang 2016-05-25 19:11 ` Rob Herring 2016-05-25 19:11 ` Rob Herring 2016-05-25 19:11 ` Rob Herring 2016-05-25 9:49 ` [PATCH 2/5] clocksource: rockchip: remove unnecessary clear irq before request_irq Caesar Wang 2016-05-25 9:49 ` Caesar Wang 2016-05-30 23:09 ` Daniel Lezcano 2016-05-30 23:09 ` Daniel Lezcano 2016-05-31 17:03 ` Doug Anderson 2016-05-31 17:03 ` Doug Anderson 2016-05-31 17:03 ` Doug Anderson 2016-06-01 2:30 ` Huang, Tao 2016-06-01 2:30 ` Huang, Tao 2016-06-01 2:30 ` Huang, Tao 2016-06-01 2:36 ` Doug Anderson 2016-06-01 2:36 ` Doug Anderson 2016-06-01 2:36 ` Doug Anderson 2016-05-25 9:50 ` [PATCH 3/5] clocksource: rockchip: add dynamic irq flag to the timer Caesar Wang 2016-05-25 9:50 ` Caesar Wang 2016-05-30 23:16 ` Daniel Lezcano 2016-05-30 23:16 ` Daniel Lezcano 2016-05-31 13:45 ` Huang, Tao 2016-05-31 13:45 ` Huang, Tao 2016-05-31 13:45 ` Huang, Tao 2016-05-25 9:50 ` Caesar Wang [this message] 2016-05-25 9:50 ` [PATCH 4/5] clocksource: rockchip: add support for rk3399 SoC Caesar Wang 2016-05-30 23:28 ` Daniel Lezcano 2016-05-30 23:28 ` Daniel Lezcano 2016-05-31 13:46 ` Huang, Tao 2016-05-31 13:46 ` Huang, Tao 2016-05-31 13:46 ` Huang, Tao 2016-05-31 14:06 ` Daniel Lezcano 2016-05-31 14:06 ` Daniel Lezcano 2016-06-01 1:58 ` Huang, Tao 2016-06-01 1:58 ` Huang, Tao 2016-06-01 6:16 ` Daniel Lezcano 2016-06-01 6:16 ` Daniel Lezcano 2016-05-25 9:50 ` [PATCH 5/5] ARM64: dts: rockchip: add rktimer device node for rk3399 Caesar Wang 2016-05-25 9:50 ` Caesar Wang
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=1464169802-6033-5-git-send-email-wxt@rock-chips.com \ --to=wxt@rock-chips.com \ --cc=briannorris@google.com \ --cc=cf@rock-chips.com \ --cc=daniel.lezcano@linaro.org \ --cc=dianders@chromium.org \ --cc=heiko@sntech.de \ --cc=huangtao@rock-chips.com \ --cc=linux-arm-kernel@lists.infradead.org \ --cc=linux-kernel@vger.kernel.org \ --cc=linux-rockchip@lists.infradead.org \ --cc=smbarber@google.com \ --cc=tglx@linutronix.de \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
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.