diff options
author | Huang, Tao <huangtao@rock-chips.com> | 2016-06-16 10:00:08 -0400 |
---|---|---|
committer | Daniel Lezcano <daniel.lezcano@linaro.org> | 2016-06-28 04:17:08 -0400 |
commit | be6af450bb1b74177f14afc6228458f16f92a6c5 (patch) | |
tree | c846d63c2fb9a3ada1dc23b785f7957fdff3b3ec /drivers/clocksource/rockchip_timer.c | |
parent | 716897d90f2bb1b732c45ddcc1f2f4651a06a9f6 (diff) |
clocksource/drivers/rockchip: Add support for the rk3399 SoC
The only difference between the rk3399 SoC and the other ones is the control
register offset which is different.
Add a new field to store the control register address depending on the SoC
and use it instead of the <base> + <control offset>.
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>
Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
Diffstat (limited to 'drivers/clocksource/rockchip_timer.c')
-rw-r--r-- | drivers/clocksource/rockchip_timer.c | 31 |
1 files changed, 26 insertions, 5 deletions
diff --git a/drivers/clocksource/rockchip_timer.c b/drivers/clocksource/rockchip_timer.c index b510863fd1e1..a3f22b03f94f 100644 --- a/drivers/clocksource/rockchip_timer.c +++ b/drivers/clocksource/rockchip_timer.c | |||
@@ -19,7 +19,8 @@ | |||
19 | 19 | ||
20 | #define TIMER_LOAD_COUNT0 0x00 | 20 | #define TIMER_LOAD_COUNT0 0x00 |
21 | #define TIMER_LOAD_COUNT1 0x04 | 21 | #define TIMER_LOAD_COUNT1 0x04 |
22 | #define TIMER_CONTROL_REG 0x10 | 22 | #define TIMER_CONTROL_REG3288 0x10 |
23 | #define TIMER_CONTROL_REG3399 0x1c | ||
23 | #define TIMER_INT_STATUS 0x18 | 24 | #define TIMER_INT_STATUS 0x18 |
24 | 25 | ||
25 | #define TIMER_DISABLE 0x0 | 26 | #define TIMER_DISABLE 0x0 |
@@ -31,6 +32,7 @@ | |||
31 | struct bc_timer { | 32 | struct bc_timer { |
32 | struct clock_event_device ce; | 33 | struct clock_event_device ce; |
33 | void __iomem *base; | 34 | void __iomem *base; |
35 | void __iomem *ctrl; | ||
34 | u32 freq; | 36 | u32 freq; |
35 | }; | 37 | }; |
36 | 38 | ||
@@ -46,15 +48,20 @@ static inline void __iomem *rk_base(struct clock_event_device *ce) | |||
46 | return rk_timer(ce)->base; | 48 | return rk_timer(ce)->base; |
47 | } | 49 | } |
48 | 50 | ||
51 | static inline void __iomem *rk_ctrl(struct clock_event_device *ce) | ||
52 | { | ||
53 | return rk_timer(ce)->ctrl; | ||
54 | } | ||
55 | |||
49 | static inline void rk_timer_disable(struct clock_event_device *ce) | 56 | static inline void rk_timer_disable(struct clock_event_device *ce) |
50 | { | 57 | { |
51 | writel_relaxed(TIMER_DISABLE, rk_base(ce) + TIMER_CONTROL_REG); | 58 | writel_relaxed(TIMER_DISABLE, rk_ctrl(ce)); |
52 | } | 59 | } |
53 | 60 | ||
54 | static inline void rk_timer_enable(struct clock_event_device *ce, u32 flags) | 61 | static inline void rk_timer_enable(struct clock_event_device *ce, u32 flags) |
55 | { | 62 | { |
56 | writel_relaxed(TIMER_ENABLE | TIMER_INT_UNMASK | flags, | 63 | writel_relaxed(TIMER_ENABLE | TIMER_INT_UNMASK | flags, |
57 | rk_base(ce) + TIMER_CONTROL_REG); | 64 | rk_ctrl(ce)); |
58 | } | 65 | } |
59 | 66 | ||
60 | static void rk_timer_update_counter(unsigned long cycles, | 67 | static void rk_timer_update_counter(unsigned long cycles, |
@@ -106,7 +113,7 @@ static irqreturn_t rk_timer_interrupt(int irq, void *dev_id) | |||
106 | return IRQ_HANDLED; | 113 | return IRQ_HANDLED; |
107 | } | 114 | } |
108 | 115 | ||
109 | static void __init rk_timer_init(struct device_node *np) | 116 | static void __init rk_timer_init(struct device_node *np, u32 ctrl_reg) |
110 | { | 117 | { |
111 | struct clock_event_device *ce = &bc_timer.ce; | 118 | struct clock_event_device *ce = &bc_timer.ce; |
112 | struct clk *timer_clk; | 119 | struct clk *timer_clk; |
@@ -118,6 +125,7 @@ static void __init rk_timer_init(struct device_node *np) | |||
118 | pr_err("Failed to get base address for '%s'\n", TIMER_NAME); | 125 | pr_err("Failed to get base address for '%s'\n", TIMER_NAME); |
119 | return; | 126 | return; |
120 | } | 127 | } |
128 | bc_timer.ctrl = bc_timer.base + ctrl_reg; | ||
121 | 129 | ||
122 | pclk = of_clk_get_by_name(np, "pclk"); | 130 | pclk = of_clk_get_by_name(np, "pclk"); |
123 | if (IS_ERR(pclk)) { | 131 | if (IS_ERR(pclk)) { |
@@ -180,4 +188,17 @@ out_unmap: | |||
180 | iounmap(bc_timer.base); | 188 | iounmap(bc_timer.base); |
181 | } | 189 | } |
182 | 190 | ||
183 | CLOCKSOURCE_OF_DECLARE(rk_timer, "rockchip,rk3288-timer", rk_timer_init); | 191 | static void __init rk3288_timer_init(struct device_node *np) |
192 | { | ||
193 | rk_timer_init(np, TIMER_CONTROL_REG3288); | ||
194 | } | ||
195 | |||
196 | static void __init rk3399_timer_init(struct device_node *np) | ||
197 | { | ||
198 | rk_timer_init(np, TIMER_CONTROL_REG3399); | ||
199 | } | ||
200 | |||
201 | CLOCKSOURCE_OF_DECLARE(rk3288_timer, "rockchip,rk3288-timer", | ||
202 | rk3288_timer_init); | ||
203 | CLOCKSOURCE_OF_DECLARE(rk3399_timer, "rockchip,rk3399-timer", | ||
204 | rk3399_timer_init); | ||