linux/drivers/clocksource/mxs_timer.c
<<
>>
Prefs
   1/*
   2 *  Copyright (C) 2000-2001 Deep Blue Solutions
   3 *  Copyright (C) 2002 Shane Nay (shane@minirl.com)
   4 *  Copyright (C) 2006-2007 Pavel Pisa (ppisa@pikron.com)
   5 *  Copyright (C) 2008 Juergen Beisert (kernel@pengutronix.de)
   6 *  Copyright (C) 2010 Freescale Semiconductor, Inc. All Rights Reserved.
   7 *
   8 * This program is free software; you can redistribute it and/or
   9 * modify it under the terms of the GNU General Public License
  10 * as published by the Free Software Foundation; either version 2
  11 * of the License, or (at your option) any later version.
  12 * This program is distributed in the hope that it will be useful,
  13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15 * GNU General Public License for more details.
  16 *
  17 * You should have received a copy of the GNU General Public License
  18 * along with this program; if not, write to the Free Software
  19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
  20 * MA 02110-1301, USA.
  21 */
  22
  23#include <linux/err.h>
  24#include <linux/interrupt.h>
  25#include <linux/irq.h>
  26#include <linux/clockchips.h>
  27#include <linux/clk.h>
  28#include <linux/of.h>
  29#include <linux/of_address.h>
  30#include <linux/of_irq.h>
  31#include <linux/stmp_device.h>
  32#include <linux/sched_clock.h>
  33
  34/*
  35 * There are 2 versions of the timrot on Freescale MXS-based SoCs.
  36 * The v1 on MX23 only gets 16 bits counter, while v2 on MX28
  37 * extends the counter to 32 bits.
  38 *
  39 * The implementation uses two timers, one for clock_event and
  40 * another for clocksource. MX28 uses timrot 0 and 1, while MX23
  41 * uses 0 and 2.
  42 */
  43
  44#define MX23_TIMROT_VERSION_OFFSET      0x0a0
  45#define MX28_TIMROT_VERSION_OFFSET      0x120
  46#define BP_TIMROT_MAJOR_VERSION         24
  47#define BV_TIMROT_VERSION_1             0x01
  48#define BV_TIMROT_VERSION_2             0x02
  49#define timrot_is_v1()  (timrot_major_version == BV_TIMROT_VERSION_1)
  50
  51/*
  52 * There are 4 registers for each timrotv2 instance, and 2 registers
  53 * for each timrotv1. So address step 0x40 in macros below strides
  54 * one instance of timrotv2 while two instances of timrotv1.
  55 *
  56 * As the result, HW_TIMROT_XXXn(1) defines the address of timrot1
  57 * on MX28 while timrot2 on MX23.
  58 */
  59/* common between v1 and v2 */
  60#define HW_TIMROT_ROTCTRL               0x00
  61#define HW_TIMROT_TIMCTRLn(n)           (0x20 + (n) * 0x40)
  62/* v1 only */
  63#define HW_TIMROT_TIMCOUNTn(n)          (0x30 + (n) * 0x40)
  64/* v2 only */
  65#define HW_TIMROT_RUNNING_COUNTn(n)     (0x30 + (n) * 0x40)
  66#define HW_TIMROT_FIXED_COUNTn(n)       (0x40 + (n) * 0x40)
  67
  68#define BM_TIMROT_TIMCTRLn_RELOAD       (1 << 6)
  69#define BM_TIMROT_TIMCTRLn_UPDATE       (1 << 7)
  70#define BM_TIMROT_TIMCTRLn_IRQ_EN       (1 << 14)
  71#define BM_TIMROT_TIMCTRLn_IRQ          (1 << 15)
  72#define BP_TIMROT_TIMCTRLn_SELECT       0
  73#define BV_TIMROTv1_TIMCTRLn_SELECT__32KHZ_XTAL         0x8
  74#define BV_TIMROTv2_TIMCTRLn_SELECT__32KHZ_XTAL         0xb
  75#define BV_TIMROTv2_TIMCTRLn_SELECT__TICK_ALWAYS        0xf
  76
  77static struct clock_event_device mxs_clockevent_device;
  78
  79static void __iomem *mxs_timrot_base;
  80static u32 timrot_major_version;
  81
  82static inline void timrot_irq_disable(void)
  83{
  84        __raw_writel(BM_TIMROT_TIMCTRLn_IRQ_EN, mxs_timrot_base +
  85                     HW_TIMROT_TIMCTRLn(0) + STMP_OFFSET_REG_CLR);
  86}
  87
  88static inline void timrot_irq_enable(void)
  89{
  90        __raw_writel(BM_TIMROT_TIMCTRLn_IRQ_EN, mxs_timrot_base +
  91                     HW_TIMROT_TIMCTRLn(0) + STMP_OFFSET_REG_SET);
  92}
  93
  94static void timrot_irq_acknowledge(void)
  95{
  96        __raw_writel(BM_TIMROT_TIMCTRLn_IRQ, mxs_timrot_base +
  97                     HW_TIMROT_TIMCTRLn(0) + STMP_OFFSET_REG_CLR);
  98}
  99
 100static cycle_t timrotv1_get_cycles(struct clocksource *cs)
 101{
 102        return ~((__raw_readl(mxs_timrot_base + HW_TIMROT_TIMCOUNTn(1))
 103                        & 0xffff0000) >> 16);
 104}
 105
 106static int timrotv1_set_next_event(unsigned long evt,
 107                                        struct clock_event_device *dev)
 108{
 109        /* timrot decrements the count */
 110        __raw_writel(evt, mxs_timrot_base + HW_TIMROT_TIMCOUNTn(0));
 111
 112        return 0;
 113}
 114
 115static int timrotv2_set_next_event(unsigned long evt,
 116                                        struct clock_event_device *dev)
 117{
 118        /* timrot decrements the count */
 119        __raw_writel(evt, mxs_timrot_base + HW_TIMROT_FIXED_COUNTn(0));
 120
 121        return 0;
 122}
 123
 124static irqreturn_t mxs_timer_interrupt(int irq, void *dev_id)
 125{
 126        struct clock_event_device *evt = dev_id;
 127
 128        timrot_irq_acknowledge();
 129        evt->event_handler(evt);
 130
 131        return IRQ_HANDLED;
 132}
 133
 134static struct irqaction mxs_timer_irq = {
 135        .name           = "MXS Timer Tick",
 136        .dev_id         = &mxs_clockevent_device,
 137        .flags          = IRQF_TIMER | IRQF_IRQPOLL,
 138        .handler        = mxs_timer_interrupt,
 139};
 140
 141static void mxs_irq_clear(char *state)
 142{
 143        /* Disable interrupt in timer module */
 144        timrot_irq_disable();
 145
 146        /* Set event time into the furthest future */
 147        if (timrot_is_v1())
 148                __raw_writel(0xffff, mxs_timrot_base + HW_TIMROT_TIMCOUNTn(1));
 149        else
 150                __raw_writel(0xffffffff,
 151                             mxs_timrot_base + HW_TIMROT_FIXED_COUNTn(1));
 152
 153        /* Clear pending interrupt */
 154        timrot_irq_acknowledge();
 155
 156#ifdef DEBUG
 157        pr_info("%s: changing mode to %s\n", __func__, state)
 158#endif /* DEBUG */
 159}
 160
 161static int mxs_shutdown(struct clock_event_device *evt)
 162{
 163        mxs_irq_clear("shutdown");
 164
 165        return 0;
 166}
 167
 168static int mxs_set_oneshot(struct clock_event_device *evt)
 169{
 170        if (clockevent_state_oneshot(evt))
 171                mxs_irq_clear("oneshot");
 172        timrot_irq_enable();
 173        return 0;
 174}
 175
 176static struct clock_event_device mxs_clockevent_device = {
 177        .name                   = "mxs_timrot",
 178        .features               = CLOCK_EVT_FEAT_ONESHOT,
 179        .set_state_shutdown     = mxs_shutdown,
 180        .set_state_oneshot      = mxs_set_oneshot,
 181        .tick_resume            = mxs_shutdown,
 182        .set_next_event         = timrotv2_set_next_event,
 183        .rating                 = 200,
 184};
 185
 186static int __init mxs_clockevent_init(struct clk *timer_clk)
 187{
 188        if (timrot_is_v1())
 189                mxs_clockevent_device.set_next_event = timrotv1_set_next_event;
 190        mxs_clockevent_device.cpumask = cpumask_of(0);
 191        clockevents_config_and_register(&mxs_clockevent_device,
 192                                        clk_get_rate(timer_clk),
 193                                        timrot_is_v1() ? 0xf : 0x2,
 194                                        timrot_is_v1() ? 0xfffe : 0xfffffffe);
 195
 196        return 0;
 197}
 198
 199static struct clocksource clocksource_mxs = {
 200        .name           = "mxs_timer",
 201        .rating         = 200,
 202        .read           = timrotv1_get_cycles,
 203        .mask           = CLOCKSOURCE_MASK(16),
 204        .flags          = CLOCK_SOURCE_IS_CONTINUOUS,
 205};
 206
 207static u64 notrace mxs_read_sched_clock_v2(void)
 208{
 209        return ~readl_relaxed(mxs_timrot_base + HW_TIMROT_RUNNING_COUNTn(1));
 210}
 211
 212static int __init mxs_clocksource_init(struct clk *timer_clk)
 213{
 214        unsigned int c = clk_get_rate(timer_clk);
 215
 216        if (timrot_is_v1())
 217                clocksource_register_hz(&clocksource_mxs, c);
 218        else {
 219                clocksource_mmio_init(mxs_timrot_base + HW_TIMROT_RUNNING_COUNTn(1),
 220                        "mxs_timer", c, 200, 32, clocksource_mmio_readl_down);
 221                sched_clock_register(mxs_read_sched_clock_v2, 32, c);
 222        }
 223
 224        return 0;
 225}
 226
 227static int __init mxs_timer_init(struct device_node *np)
 228{
 229        struct clk *timer_clk;
 230        int irq, ret;
 231
 232        mxs_timrot_base = of_iomap(np, 0);
 233        WARN_ON(!mxs_timrot_base);
 234
 235        timer_clk = of_clk_get(np, 0);
 236        if (IS_ERR(timer_clk)) {
 237                pr_err("%s: failed to get clk\n", __func__);
 238                return PTR_ERR(timer_clk);
 239        }
 240
 241        ret = clk_prepare_enable(timer_clk);
 242        if (ret)
 243                return ret;
 244
 245        /*
 246         * Initialize timers to a known state
 247         */
 248        stmp_reset_block(mxs_timrot_base + HW_TIMROT_ROTCTRL);
 249
 250        /* get timrot version */
 251        timrot_major_version = __raw_readl(mxs_timrot_base +
 252                        (of_device_is_compatible(np, "fsl,imx23-timrot") ?
 253                                                MX23_TIMROT_VERSION_OFFSET :
 254                                                MX28_TIMROT_VERSION_OFFSET));
 255        timrot_major_version >>= BP_TIMROT_MAJOR_VERSION;
 256
 257        /* one for clock_event */
 258        __raw_writel((timrot_is_v1() ?
 259                        BV_TIMROTv1_TIMCTRLn_SELECT__32KHZ_XTAL :
 260                        BV_TIMROTv2_TIMCTRLn_SELECT__TICK_ALWAYS) |
 261                        BM_TIMROT_TIMCTRLn_UPDATE |
 262                        BM_TIMROT_TIMCTRLn_IRQ_EN,
 263                        mxs_timrot_base + HW_TIMROT_TIMCTRLn(0));
 264
 265        /* another for clocksource */
 266        __raw_writel((timrot_is_v1() ?
 267                        BV_TIMROTv1_TIMCTRLn_SELECT__32KHZ_XTAL :
 268                        BV_TIMROTv2_TIMCTRLn_SELECT__TICK_ALWAYS) |
 269                        BM_TIMROT_TIMCTRLn_RELOAD,
 270                        mxs_timrot_base + HW_TIMROT_TIMCTRLn(1));
 271
 272        /* set clocksource timer fixed count to the maximum */
 273        if (timrot_is_v1())
 274                __raw_writel(0xffff,
 275                        mxs_timrot_base + HW_TIMROT_TIMCOUNTn(1));
 276        else
 277                __raw_writel(0xffffffff,
 278                        mxs_timrot_base + HW_TIMROT_FIXED_COUNTn(1));
 279
 280        /* init and register the timer to the framework */
 281        ret = mxs_clocksource_init(timer_clk);
 282        if (ret)
 283                return ret;
 284
 285        ret = mxs_clockevent_init(timer_clk);
 286        if (ret)
 287                return ret;
 288
 289        /* Make irqs happen */
 290        irq = irq_of_parse_and_map(np, 0);
 291        if (irq <= 0)
 292                return -EINVAL;
 293
 294        return setup_irq(irq, &mxs_timer_irq);
 295}
 296CLOCKSOURCE_OF_DECLARE(mxs, "fsl,timrot", mxs_timer_init);
 297