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