root/drivers/clocksource/mxs_timer.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. timrot_irq_disable
  2. timrot_irq_enable
  3. timrot_irq_acknowledge
  4. timrotv1_get_cycles
  5. timrotv1_set_next_event
  6. timrotv2_set_next_event
  7. mxs_timer_interrupt
  8. mxs_irq_clear
  9. mxs_shutdown
  10. mxs_set_oneshot
  11. mxs_clockevent_init
  12. mxs_read_sched_clock_v2
  13. mxs_clocksource_init
  14. mxs_timer_init

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

/* [<][>][^][v][top][bottom][index][help] */