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