timer-rockchip.c (6947B)
1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * Rockchip timer support 4 * 5 * Copyright (C) Daniel Lezcano <daniel.lezcano@linaro.org> 6 */ 7#include <linux/clk.h> 8#include <linux/clockchips.h> 9#include <linux/init.h> 10#include <linux/interrupt.h> 11#include <linux/sched_clock.h> 12#include <linux/slab.h> 13#include <linux/of.h> 14#include <linux/of_address.h> 15#include <linux/of_irq.h> 16 17#define TIMER_NAME "rk_timer" 18 19#define TIMER_LOAD_COUNT0 0x00 20#define TIMER_LOAD_COUNT1 0x04 21#define TIMER_CURRENT_VALUE0 0x08 22#define TIMER_CURRENT_VALUE1 0x0C 23#define TIMER_CONTROL_REG3288 0x10 24#define TIMER_CONTROL_REG3399 0x1c 25#define TIMER_INT_STATUS 0x18 26 27#define TIMER_DISABLE 0x0 28#define TIMER_ENABLE 0x1 29#define TIMER_MODE_FREE_RUNNING (0 << 1) 30#define TIMER_MODE_USER_DEFINED_COUNT (1 << 1) 31#define TIMER_INT_UNMASK (1 << 2) 32 33struct rk_timer { 34 void __iomem *base; 35 void __iomem *ctrl; 36 struct clk *clk; 37 struct clk *pclk; 38 u32 freq; 39 int irq; 40}; 41 42struct rk_clkevt { 43 struct clock_event_device ce; 44 struct rk_timer timer; 45}; 46 47static struct rk_clkevt *rk_clkevt; 48static struct rk_timer *rk_clksrc; 49 50static inline struct rk_timer *rk_timer(struct clock_event_device *ce) 51{ 52 return &container_of(ce, struct rk_clkevt, ce)->timer; 53} 54 55static inline void rk_timer_disable(struct rk_timer *timer) 56{ 57 writel_relaxed(TIMER_DISABLE, timer->ctrl); 58} 59 60static inline void rk_timer_enable(struct rk_timer *timer, u32 flags) 61{ 62 writel_relaxed(TIMER_ENABLE | flags, timer->ctrl); 63} 64 65static void rk_timer_update_counter(unsigned long cycles, 66 struct rk_timer *timer) 67{ 68 writel_relaxed(cycles, timer->base + TIMER_LOAD_COUNT0); 69 writel_relaxed(0, timer->base + TIMER_LOAD_COUNT1); 70} 71 72static void rk_timer_interrupt_clear(struct rk_timer *timer) 73{ 74 writel_relaxed(1, timer->base + TIMER_INT_STATUS); 75} 76 77static inline int rk_timer_set_next_event(unsigned long cycles, 78 struct clock_event_device *ce) 79{ 80 struct rk_timer *timer = rk_timer(ce); 81 82 rk_timer_disable(timer); 83 rk_timer_update_counter(cycles, timer); 84 rk_timer_enable(timer, TIMER_MODE_USER_DEFINED_COUNT | 85 TIMER_INT_UNMASK); 86 return 0; 87} 88 89static int rk_timer_shutdown(struct clock_event_device *ce) 90{ 91 struct rk_timer *timer = rk_timer(ce); 92 93 rk_timer_disable(timer); 94 return 0; 95} 96 97static int rk_timer_set_periodic(struct clock_event_device *ce) 98{ 99 struct rk_timer *timer = rk_timer(ce); 100 101 rk_timer_disable(timer); 102 rk_timer_update_counter(timer->freq / HZ - 1, timer); 103 rk_timer_enable(timer, TIMER_MODE_FREE_RUNNING | TIMER_INT_UNMASK); 104 return 0; 105} 106 107static irqreturn_t rk_timer_interrupt(int irq, void *dev_id) 108{ 109 struct clock_event_device *ce = dev_id; 110 struct rk_timer *timer = rk_timer(ce); 111 112 rk_timer_interrupt_clear(timer); 113 114 if (clockevent_state_oneshot(ce)) 115 rk_timer_disable(timer); 116 117 ce->event_handler(ce); 118 119 return IRQ_HANDLED; 120} 121 122static u64 notrace rk_timer_sched_read(void) 123{ 124 return ~readl_relaxed(rk_clksrc->base + TIMER_CURRENT_VALUE0); 125} 126 127static int __init 128rk_timer_probe(struct rk_timer *timer, struct device_node *np) 129{ 130 struct clk *timer_clk; 131 struct clk *pclk; 132 int ret = -EINVAL, irq; 133 u32 ctrl_reg = TIMER_CONTROL_REG3288; 134 135 timer->base = of_iomap(np, 0); 136 if (!timer->base) { 137 pr_err("Failed to get base address for '%s'\n", TIMER_NAME); 138 return -ENXIO; 139 } 140 141 if (of_device_is_compatible(np, "rockchip,rk3399-timer")) 142 ctrl_reg = TIMER_CONTROL_REG3399; 143 144 timer->ctrl = timer->base + ctrl_reg; 145 146 pclk = of_clk_get_by_name(np, "pclk"); 147 if (IS_ERR(pclk)) { 148 ret = PTR_ERR(pclk); 149 pr_err("Failed to get pclk for '%s'\n", TIMER_NAME); 150 goto out_unmap; 151 } 152 153 ret = clk_prepare_enable(pclk); 154 if (ret) { 155 pr_err("Failed to enable pclk for '%s'\n", TIMER_NAME); 156 goto out_unmap; 157 } 158 timer->pclk = pclk; 159 160 timer_clk = of_clk_get_by_name(np, "timer"); 161 if (IS_ERR(timer_clk)) { 162 ret = PTR_ERR(timer_clk); 163 pr_err("Failed to get timer clock for '%s'\n", TIMER_NAME); 164 goto out_timer_clk; 165 } 166 167 ret = clk_prepare_enable(timer_clk); 168 if (ret) { 169 pr_err("Failed to enable timer clock\n"); 170 goto out_timer_clk; 171 } 172 timer->clk = timer_clk; 173 174 timer->freq = clk_get_rate(timer_clk); 175 176 irq = irq_of_parse_and_map(np, 0); 177 if (!irq) { 178 ret = -EINVAL; 179 pr_err("Failed to map interrupts for '%s'\n", TIMER_NAME); 180 goto out_irq; 181 } 182 timer->irq = irq; 183 184 rk_timer_interrupt_clear(timer); 185 rk_timer_disable(timer); 186 return 0; 187 188out_irq: 189 clk_disable_unprepare(timer_clk); 190out_timer_clk: 191 clk_disable_unprepare(pclk); 192out_unmap: 193 iounmap(timer->base); 194 195 return ret; 196} 197 198static void __init rk_timer_cleanup(struct rk_timer *timer) 199{ 200 clk_disable_unprepare(timer->clk); 201 clk_disable_unprepare(timer->pclk); 202 iounmap(timer->base); 203} 204 205static int __init rk_clkevt_init(struct device_node *np) 206{ 207 struct clock_event_device *ce; 208 int ret = -EINVAL; 209 210 rk_clkevt = kzalloc(sizeof(struct rk_clkevt), GFP_KERNEL); 211 if (!rk_clkevt) { 212 ret = -ENOMEM; 213 goto out; 214 } 215 216 ret = rk_timer_probe(&rk_clkevt->timer, np); 217 if (ret) 218 goto out_probe; 219 220 ce = &rk_clkevt->ce; 221 ce->name = TIMER_NAME; 222 ce->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT | 223 CLOCK_EVT_FEAT_DYNIRQ; 224 ce->set_next_event = rk_timer_set_next_event; 225 ce->set_state_shutdown = rk_timer_shutdown; 226 ce->set_state_periodic = rk_timer_set_periodic; 227 ce->irq = rk_clkevt->timer.irq; 228 ce->cpumask = cpu_possible_mask; 229 ce->rating = 250; 230 231 ret = request_irq(rk_clkevt->timer.irq, rk_timer_interrupt, IRQF_TIMER, 232 TIMER_NAME, ce); 233 if (ret) { 234 pr_err("Failed to initialize '%s': %d\n", 235 TIMER_NAME, ret); 236 goto out_irq; 237 } 238 239 clockevents_config_and_register(&rk_clkevt->ce, 240 rk_clkevt->timer.freq, 1, UINT_MAX); 241 return 0; 242 243out_irq: 244 rk_timer_cleanup(&rk_clkevt->timer); 245out_probe: 246 kfree(rk_clkevt); 247out: 248 /* Leave rk_clkevt not NULL to prevent future init */ 249 rk_clkevt = ERR_PTR(ret); 250 return ret; 251} 252 253static int __init rk_clksrc_init(struct device_node *np) 254{ 255 int ret = -EINVAL; 256 257 rk_clksrc = kzalloc(sizeof(struct rk_timer), GFP_KERNEL); 258 if (!rk_clksrc) { 259 ret = -ENOMEM; 260 goto out; 261 } 262 263 ret = rk_timer_probe(rk_clksrc, np); 264 if (ret) 265 goto out_probe; 266 267 rk_timer_update_counter(UINT_MAX, rk_clksrc); 268 rk_timer_enable(rk_clksrc, 0); 269 270 ret = clocksource_mmio_init(rk_clksrc->base + TIMER_CURRENT_VALUE0, 271 TIMER_NAME, rk_clksrc->freq, 250, 32, 272 clocksource_mmio_readl_down); 273 if (ret) { 274 pr_err("Failed to register clocksource\n"); 275 goto out_clocksource; 276 } 277 278 sched_clock_register(rk_timer_sched_read, 32, rk_clksrc->freq); 279 return 0; 280 281out_clocksource: 282 rk_timer_cleanup(rk_clksrc); 283out_probe: 284 kfree(rk_clksrc); 285out: 286 /* Leave rk_clksrc not NULL to prevent future init */ 287 rk_clksrc = ERR_PTR(ret); 288 return ret; 289} 290 291static int __init rk_timer_init(struct device_node *np) 292{ 293 if (!rk_clkevt) 294 return rk_clkevt_init(np); 295 296 if (!rk_clksrc) 297 return rk_clksrc_init(np); 298 299 pr_err("Too many timer definitions for '%s'\n", TIMER_NAME); 300 return -EINVAL; 301} 302 303TIMER_OF_DECLARE(rk3288_timer, "rockchip,rk3288-timer", rk_timer_init); 304TIMER_OF_DECLARE(rk3399_timer, "rockchip,rk3399-timer", rk_timer_init);