2 * drivers/clocksource/timer-oxnas-rps.c
4 * Copyright (C) 2009 Oxford Semiconductor Ltd
5 * Copyright (C) 2013 Ma Haijun <mahaijuns@gmail.com>
6 * Copyright (C) 2016 Neil Armstrong <narmstrong@baylibre.com>
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms and conditions of the GNU General Public License,
10 * version 2, as published by the Free Software Foundation.
12 * This program is distributed in the hope it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
21 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
23 #include <linux/init.h>
24 #include <linux/irq.h>
26 #include <linux/clk.h>
27 #include <linux/slab.h>
28 #include <linux/interrupt.h>
29 #include <linux/of_irq.h>
30 #include <linux/of_address.h>
31 #include <linux/clockchips.h>
32 #include <linux/sched_clock.h>
34 /* TIMER1 used as tick
35 * TIMER2 used as clocksource
38 /* Registers definitions */
40 #define TIMER_LOAD_REG 0x0
41 #define TIMER_CURR_REG 0x4
42 #define TIMER_CTRL_REG 0x8
43 #define TIMER_CLRINT_REG 0xC
47 #define TIMER_MAX_VAL (BIT(TIMER_BITS) - 1)
49 #define TIMER_PERIODIC BIT(6)
50 #define TIMER_ENABLE BIT(7)
52 #define TIMER_DIV1 (0)
53 #define TIMER_DIV16 (1 << 2)
54 #define TIMER_DIV256 (2 << 2)
56 #define TIMER1_REG_OFFSET 0
57 #define TIMER2_REG_OFFSET 0x20
59 /* Clockevent & Clocksource data */
61 struct oxnas_rps_timer
{
62 struct clock_event_device clkevent
;
63 void __iomem
*clksrc_base
;
64 void __iomem
*clkevt_base
;
65 unsigned long timer_period
;
66 unsigned int timer_prescaler
;
71 static irqreturn_t
oxnas_rps_timer_irq(int irq
, void *dev_id
)
73 struct oxnas_rps_timer
*rps
= dev_id
;
75 writel_relaxed(0, rps
->clkevt_base
+ TIMER_CLRINT_REG
);
77 rps
->clkevent
.event_handler(&rps
->clkevent
);
82 static void oxnas_rps_timer_config(struct oxnas_rps_timer
*rps
,
84 unsigned int periodic
)
86 uint32_t cfg
= rps
->timer_prescaler
;
92 cfg
|= TIMER_PERIODIC
;
94 writel_relaxed(period
, rps
->clkevt_base
+ TIMER_LOAD_REG
);
95 writel_relaxed(cfg
, rps
->clkevt_base
+ TIMER_CTRL_REG
);
98 static int oxnas_rps_timer_shutdown(struct clock_event_device
*evt
)
100 struct oxnas_rps_timer
*rps
=
101 container_of(evt
, struct oxnas_rps_timer
, clkevent
);
103 oxnas_rps_timer_config(rps
, 0, 0);
108 static int oxnas_rps_timer_set_periodic(struct clock_event_device
*evt
)
110 struct oxnas_rps_timer
*rps
=
111 container_of(evt
, struct oxnas_rps_timer
, clkevent
);
113 oxnas_rps_timer_config(rps
, rps
->timer_period
, 1);
118 static int oxnas_rps_timer_set_oneshot(struct clock_event_device
*evt
)
120 struct oxnas_rps_timer
*rps
=
121 container_of(evt
, struct oxnas_rps_timer
, clkevent
);
123 oxnas_rps_timer_config(rps
, rps
->timer_period
, 0);
128 static int oxnas_rps_timer_next_event(unsigned long delta
,
129 struct clock_event_device
*evt
)
131 struct oxnas_rps_timer
*rps
=
132 container_of(evt
, struct oxnas_rps_timer
, clkevent
);
134 oxnas_rps_timer_config(rps
, delta
, 0);
139 static int __init
oxnas_rps_clockevent_init(struct oxnas_rps_timer
*rps
)
141 ulong clk_rate
= clk_get_rate(rps
->clk
);
144 /* Start with prescaler 1 */
145 rps
->timer_prescaler
= TIMER_DIV1
;
146 rps
->timer_period
= DIV_ROUND_UP(clk_rate
, HZ
);
147 timer_rate
= clk_rate
;
149 if (rps
->timer_period
> TIMER_MAX_VAL
) {
150 rps
->timer_prescaler
= TIMER_DIV16
;
151 timer_rate
= clk_rate
/ 16;
152 rps
->timer_period
= DIV_ROUND_UP(timer_rate
, HZ
);
154 if (rps
->timer_period
> TIMER_MAX_VAL
) {
155 rps
->timer_prescaler
= TIMER_DIV256
;
156 timer_rate
= clk_rate
/ 256;
157 rps
->timer_period
= DIV_ROUND_UP(timer_rate
, HZ
);
160 rps
->clkevent
.name
= "oxnas-rps";
161 rps
->clkevent
.features
= CLOCK_EVT_FEAT_PERIODIC
|
162 CLOCK_EVT_FEAT_ONESHOT
|
163 CLOCK_EVT_FEAT_DYNIRQ
;
164 rps
->clkevent
.tick_resume
= oxnas_rps_timer_shutdown
;
165 rps
->clkevent
.set_state_shutdown
= oxnas_rps_timer_shutdown
;
166 rps
->clkevent
.set_state_periodic
= oxnas_rps_timer_set_periodic
;
167 rps
->clkevent
.set_state_oneshot
= oxnas_rps_timer_set_oneshot
;
168 rps
->clkevent
.set_next_event
= oxnas_rps_timer_next_event
;
169 rps
->clkevent
.rating
= 200;
170 rps
->clkevent
.cpumask
= cpu_possible_mask
;
171 rps
->clkevent
.irq
= rps
->irq
;
172 clockevents_config_and_register(&rps
->clkevent
,
177 pr_info("Registered clock event rate %luHz prescaler %x period %lu\n",
179 rps
->timer_prescaler
,
187 static void __iomem
*timer_sched_base
;
189 static u64 notrace
oxnas_rps_read_sched_clock(void)
191 return ~readl_relaxed(timer_sched_base
);
194 static int __init
oxnas_rps_clocksource_init(struct oxnas_rps_timer
*rps
)
196 ulong clk_rate
= clk_get_rate(rps
->clk
);
199 /* use prescale 16 */
200 clk_rate
= clk_rate
/ 16;
202 writel_relaxed(TIMER_MAX_VAL
, rps
->clksrc_base
+ TIMER_LOAD_REG
);
203 writel_relaxed(TIMER_PERIODIC
| TIMER_ENABLE
| TIMER_DIV16
,
204 rps
->clksrc_base
+ TIMER_CTRL_REG
);
206 timer_sched_base
= rps
->clksrc_base
+ TIMER_CURR_REG
;
207 sched_clock_register(oxnas_rps_read_sched_clock
,
208 TIMER_BITS
, clk_rate
);
209 ret
= clocksource_mmio_init(timer_sched_base
,
210 "oxnas_rps_clocksource_timer",
211 clk_rate
, 250, TIMER_BITS
,
212 clocksource_mmio_readl_down
);
214 pr_err("can't register clocksource\n");
218 pr_info("Registered clocksource rate %luHz\n", clk_rate
);
223 static int __init
oxnas_rps_timer_init(struct device_node
*np
)
225 struct oxnas_rps_timer
*rps
;
229 rps
= kzalloc(sizeof(*rps
), GFP_KERNEL
);
233 rps
->clk
= of_clk_get(np
, 0);
234 if (IS_ERR(rps
->clk
)) {
235 ret
= PTR_ERR(rps
->clk
);
239 ret
= clk_prepare_enable(rps
->clk
);
243 base
= of_iomap(np
, 0);
246 goto err_clk_prepare
;
249 rps
->irq
= irq_of_parse_and_map(np
, 0);
255 rps
->clkevt_base
= base
+ TIMER1_REG_OFFSET
;
256 rps
->clksrc_base
= base
+ TIMER2_REG_OFFSET
;
259 writel_relaxed(0, rps
->clkevt_base
+ TIMER_CTRL_REG
);
260 writel_relaxed(0, rps
->clksrc_base
+ TIMER_CTRL_REG
);
261 writel_relaxed(0, rps
->clkevt_base
+ TIMER_LOAD_REG
);
262 writel_relaxed(0, rps
->clksrc_base
+ TIMER_LOAD_REG
);
263 writel_relaxed(0, rps
->clkevt_base
+ TIMER_CLRINT_REG
);
264 writel_relaxed(0, rps
->clksrc_base
+ TIMER_CLRINT_REG
);
266 ret
= request_irq(rps
->irq
, oxnas_rps_timer_irq
,
267 IRQF_TIMER
| IRQF_IRQPOLL
,
272 ret
= oxnas_rps_clocksource_init(rps
);
276 ret
= oxnas_rps_clockevent_init(rps
);
283 free_irq(rps
->irq
, rps
);
287 clk_disable_unprepare(rps
->clk
);
296 CLOCKSOURCE_OF_DECLARE(ox810se_rps
,
297 "oxsemi,ox810se-rps-timer", oxnas_rps_timer_init
);
298 CLOCKSOURCE_OF_DECLARE(ox820_rps
,
299 "oxsemi,ox820se-rps-timer", oxnas_rps_timer_init
);