305 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * Rockchip timer support4 *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 0x0020#define TIMER_LOAD_COUNT1 0x0421#define TIMER_CURRENT_VALUE0 0x0822#define TIMER_CURRENT_VALUE1 0x0C23#define TIMER_CONTROL_REG3288 0x1024#define TIMER_CONTROL_REG3399 0x1c25#define TIMER_INT_STATUS 0x1826 27#define TIMER_DISABLE 0x028#define TIMER_ENABLE 0x129#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 __init128rk_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);305