linux/arch/powerpc/sysdev/fsl_gtm.c
<<
>>
Prefs
   1/*
   2 * Freescale General-purpose Timers Module
   3 *
   4 * Copyright (c) Freescale Semiconductor, Inc. 2006.
   5 *               Shlomi Gridish <gridish@freescale.com>
   6 *               Jerry Huang <Chang-Ming.Huang@freescale.com>
   7 * Copyright (c) MontaVista Software, Inc. 2008.
   8 *               Anton Vorontsov <avorontsov@ru.mvista.com>
   9 *
  10 * This program is free software; you can redistribute  it and/or modify it
  11 * under  the terms of  the GNU General  Public License as published by the
  12 * Free Software Foundation;  either version 2 of the  License, or (at your
  13 * option) any later version.
  14 */
  15
  16#include <linux/kernel.h>
  17#include <linux/err.h>
  18#include <linux/errno.h>
  19#include <linux/list.h>
  20#include <linux/io.h>
  21#include <linux/of.h>
  22#include <linux/of_address.h>
  23#include <linux/of_irq.h>
  24#include <linux/spinlock.h>
  25#include <linux/bitops.h>
  26#include <linux/slab.h>
  27#include <linux/export.h>
  28#include <asm/fsl_gtm.h>
  29
  30#define GTCFR_STP(x)            ((x) & 1 ? 1 << 5 : 1 << 1)
  31#define GTCFR_RST(x)            ((x) & 1 ? 1 << 4 : 1 << 0)
  32
  33#define GTMDR_ICLK_MASK         (3 << 1)
  34#define GTMDR_ICLK_ICAS         (0 << 1)
  35#define GTMDR_ICLK_ICLK         (1 << 1)
  36#define GTMDR_ICLK_SLGO         (2 << 1)
  37#define GTMDR_FRR               (1 << 3)
  38#define GTMDR_ORI               (1 << 4)
  39#define GTMDR_SPS(x)            ((x) << 8)
  40
  41struct gtm_timers_regs {
  42        u8      gtcfr1;         /* Timer 1, Timer 2 global config register */
  43        u8      res0[0x3];
  44        u8      gtcfr2;         /* Timer 3, timer 4 global config register */
  45        u8      res1[0xB];
  46        __be16  gtmdr1;         /* Timer 1 mode register */
  47        __be16  gtmdr2;         /* Timer 2 mode register */
  48        __be16  gtrfr1;         /* Timer 1 reference register */
  49        __be16  gtrfr2;         /* Timer 2 reference register */
  50        __be16  gtcpr1;         /* Timer 1 capture register */
  51        __be16  gtcpr2;         /* Timer 2 capture register */
  52        __be16  gtcnr1;         /* Timer 1 counter */
  53        __be16  gtcnr2;         /* Timer 2 counter */
  54        __be16  gtmdr3;         /* Timer 3 mode register */
  55        __be16  gtmdr4;         /* Timer 4 mode register */
  56        __be16  gtrfr3;         /* Timer 3 reference register */
  57        __be16  gtrfr4;         /* Timer 4 reference register */
  58        __be16  gtcpr3;         /* Timer 3 capture register */
  59        __be16  gtcpr4;         /* Timer 4 capture register */
  60        __be16  gtcnr3;         /* Timer 3 counter */
  61        __be16  gtcnr4;         /* Timer 4 counter */
  62        __be16  gtevr1;         /* Timer 1 event register */
  63        __be16  gtevr2;         /* Timer 2 event register */
  64        __be16  gtevr3;         /* Timer 3 event register */
  65        __be16  gtevr4;         /* Timer 4 event register */
  66        __be16  gtpsr1;         /* Timer 1 prescale register */
  67        __be16  gtpsr2;         /* Timer 2 prescale register */
  68        __be16  gtpsr3;         /* Timer 3 prescale register */
  69        __be16  gtpsr4;         /* Timer 4 prescale register */
  70        u8 res2[0x40];
  71} __attribute__ ((packed));
  72
  73struct gtm {
  74        unsigned int clock;
  75        struct gtm_timers_regs __iomem *regs;
  76        struct gtm_timer timers[4];
  77        spinlock_t lock;
  78        struct list_head list_node;
  79};
  80
  81static LIST_HEAD(gtms);
  82
  83/**
  84 * gtm_get_timer - request GTM timer to use it with the rest of GTM API
  85 * Context:     non-IRQ
  86 *
  87 * This function reserves GTM timer for later use. It returns gtm_timer
  88 * structure to use with the rest of GTM API, you should use timer->irq
  89 * to manage timer interrupt.
  90 */
  91struct gtm_timer *gtm_get_timer16(void)
  92{
  93        struct gtm *gtm = NULL;
  94        int i;
  95
  96        list_for_each_entry(gtm, &gtms, list_node) {
  97                spin_lock_irq(&gtm->lock);
  98
  99                for (i = 0; i < ARRAY_SIZE(gtm->timers); i++) {
 100                        if (!gtm->timers[i].requested) {
 101                                gtm->timers[i].requested = true;
 102                                spin_unlock_irq(&gtm->lock);
 103                                return &gtm->timers[i];
 104                        }
 105                }
 106
 107                spin_unlock_irq(&gtm->lock);
 108        }
 109
 110        if (gtm)
 111                return ERR_PTR(-EBUSY);
 112        return ERR_PTR(-ENODEV);
 113}
 114EXPORT_SYMBOL(gtm_get_timer16);
 115
 116/**
 117 * gtm_get_specific_timer - request specific GTM timer
 118 * @gtm:        specific GTM, pass here GTM's device_node->data
 119 * @timer:      specific timer number, Timer1 is 0.
 120 * Context:     non-IRQ
 121 *
 122 * This function reserves GTM timer for later use. It returns gtm_timer
 123 * structure to use with the rest of GTM API, you should use timer->irq
 124 * to manage timer interrupt.
 125 */
 126struct gtm_timer *gtm_get_specific_timer16(struct gtm *gtm,
 127                                           unsigned int timer)
 128{
 129        struct gtm_timer *ret = ERR_PTR(-EBUSY);
 130
 131        if (timer > 3)
 132                return ERR_PTR(-EINVAL);
 133
 134        spin_lock_irq(&gtm->lock);
 135
 136        if (gtm->timers[timer].requested)
 137                goto out;
 138
 139        ret = &gtm->timers[timer];
 140        ret->requested = true;
 141
 142out:
 143        spin_unlock_irq(&gtm->lock);
 144        return ret;
 145}
 146EXPORT_SYMBOL(gtm_get_specific_timer16);
 147
 148/**
 149 * gtm_put_timer16 - release 16 bits GTM timer
 150 * @tmr:        pointer to the gtm_timer structure obtained from gtm_get_timer
 151 * Context:     any
 152 *
 153 * This function releases GTM timer so others may request it.
 154 */
 155void gtm_put_timer16(struct gtm_timer *tmr)
 156{
 157        gtm_stop_timer16(tmr);
 158
 159        spin_lock_irq(&tmr->gtm->lock);
 160        tmr->requested = false;
 161        spin_unlock_irq(&tmr->gtm->lock);
 162}
 163EXPORT_SYMBOL(gtm_put_timer16);
 164
 165/*
 166 * This is back-end for the exported functions, it's used to reset single
 167 * timer in reference mode.
 168 */
 169static int gtm_set_ref_timer16(struct gtm_timer *tmr, int frequency,
 170                               int reference_value, bool free_run)
 171{
 172        struct gtm *gtm = tmr->gtm;
 173        int num = tmr - &gtm->timers[0];
 174        unsigned int prescaler;
 175        u8 iclk = GTMDR_ICLK_ICLK;
 176        u8 psr;
 177        u8 sps;
 178        unsigned long flags;
 179        int max_prescaler = 256 * 256 * 16;
 180
 181        /* CPM2 doesn't have primary prescaler */
 182        if (!tmr->gtpsr)
 183                max_prescaler /= 256;
 184
 185        prescaler = gtm->clock / frequency;
 186        /*
 187         * We have two 8 bit prescalers -- primary and secondary (psr, sps),
 188         * plus "slow go" mode (clk / 16). So, total prescale value is
 189         * 16 * (psr + 1) * (sps + 1). Though, for CPM2 GTMs we losing psr.
 190         */
 191        if (prescaler > max_prescaler)
 192                return -EINVAL;
 193
 194        if (prescaler > max_prescaler / 16) {
 195                iclk = GTMDR_ICLK_SLGO;
 196                prescaler /= 16;
 197        }
 198
 199        if (prescaler <= 256) {
 200                psr = 0;
 201                sps = prescaler - 1;
 202        } else {
 203                psr = 256 - 1;
 204                sps = prescaler / 256 - 1;
 205        }
 206
 207        spin_lock_irqsave(&gtm->lock, flags);
 208
 209        /*
 210         * Properly reset timers: stop, reset, set up prescalers, reference
 211         * value and clear event register.
 212         */
 213        clrsetbits_8(tmr->gtcfr, ~(GTCFR_STP(num) | GTCFR_RST(num)),
 214                                 GTCFR_STP(num) | GTCFR_RST(num));
 215
 216        setbits8(tmr->gtcfr, GTCFR_STP(num));
 217
 218        if (tmr->gtpsr)
 219                out_be16(tmr->gtpsr, psr);
 220        clrsetbits_be16(tmr->gtmdr, 0xFFFF, iclk | GTMDR_SPS(sps) |
 221                        GTMDR_ORI | (free_run ? GTMDR_FRR : 0));
 222        out_be16(tmr->gtcnr, 0);
 223        out_be16(tmr->gtrfr, reference_value);
 224        out_be16(tmr->gtevr, 0xFFFF);
 225
 226        /* Let it be. */
 227        clrbits8(tmr->gtcfr, GTCFR_STP(num));
 228
 229        spin_unlock_irqrestore(&gtm->lock, flags);
 230
 231        return 0;
 232}
 233
 234/**
 235 * gtm_set_timer16 - (re)set 16 bit timer with arbitrary precision
 236 * @tmr:        pointer to the gtm_timer structure obtained from gtm_get_timer
 237 * @usec:       timer interval in microseconds
 238 * @reload:     if set, the timer will reset upon expiry rather than
 239 *              continue running free.
 240 * Context:     any
 241 *
 242 * This function (re)sets the GTM timer so that it counts up to the requested
 243 * interval value, and fires the interrupt when the value is reached. This
 244 * function will reduce the precision of the timer as needed in order for the
 245 * requested timeout to fit in a 16-bit register.
 246 */
 247int gtm_set_timer16(struct gtm_timer *tmr, unsigned long usec, bool reload)
 248{
 249        /* quite obvious, frequency which is enough for µSec precision */
 250        int freq = 1000000;
 251        unsigned int bit;
 252
 253        bit = fls_long(usec);
 254        if (bit > 15) {
 255                freq >>= bit - 15;
 256                usec >>= bit - 15;
 257        }
 258
 259        if (!freq)
 260                return -EINVAL;
 261
 262        return gtm_set_ref_timer16(tmr, freq, usec, reload);
 263}
 264EXPORT_SYMBOL(gtm_set_timer16);
 265
 266/**
 267 * gtm_set_exact_utimer16 - (re)set 16 bits timer
 268 * @tmr:        pointer to the gtm_timer structure obtained from gtm_get_timer
 269 * @usec:       timer interval in microseconds
 270 * @reload:     if set, the timer will reset upon expiry rather than
 271 *              continue running free.
 272 * Context:     any
 273 *
 274 * This function (re)sets GTM timer so that it counts up to the requested
 275 * interval value, and fires the interrupt when the value is reached. If reload
 276 * flag was set, timer will also reset itself upon reference value, otherwise
 277 * it continues to increment.
 278 *
 279 * The _exact_ bit in the function name states that this function will not
 280 * crop precision of the "usec" argument, thus usec is limited to 16 bits
 281 * (single timer width).
 282 */
 283int gtm_set_exact_timer16(struct gtm_timer *tmr, u16 usec, bool reload)
 284{
 285        /* quite obvious, frequency which is enough for µSec precision */
 286        const int freq = 1000000;
 287
 288        /*
 289         * We can lower the frequency (and probably power consumption) by
 290         * dividing both frequency and usec by 2 until there is no remainder.
 291         * But we won't bother with this unless savings are measured, so just
 292         * run the timer as is.
 293         */
 294
 295        return gtm_set_ref_timer16(tmr, freq, usec, reload);
 296}
 297EXPORT_SYMBOL(gtm_set_exact_timer16);
 298
 299/**
 300 * gtm_stop_timer16 - stop single timer
 301 * @tmr:        pointer to the gtm_timer structure obtained from gtm_get_timer
 302 * Context:     any
 303 *
 304 * This function simply stops the GTM timer.
 305 */
 306void gtm_stop_timer16(struct gtm_timer *tmr)
 307{
 308        struct gtm *gtm = tmr->gtm;
 309        int num = tmr - &gtm->timers[0];
 310        unsigned long flags;
 311
 312        spin_lock_irqsave(&gtm->lock, flags);
 313
 314        setbits8(tmr->gtcfr, GTCFR_STP(num));
 315        out_be16(tmr->gtevr, 0xFFFF);
 316
 317        spin_unlock_irqrestore(&gtm->lock, flags);
 318}
 319EXPORT_SYMBOL(gtm_stop_timer16);
 320
 321/**
 322 * gtm_ack_timer16 - acknowledge timer event (free-run timers only)
 323 * @tmr:        pointer to the gtm_timer structure obtained from gtm_get_timer
 324 * @events:     events mask to ack
 325 * Context:     any
 326 *
 327 * Thus function used to acknowledge timer interrupt event, use it inside the
 328 * interrupt handler.
 329 */
 330void gtm_ack_timer16(struct gtm_timer *tmr, u16 events)
 331{
 332        out_be16(tmr->gtevr, events);
 333}
 334EXPORT_SYMBOL(gtm_ack_timer16);
 335
 336static void __init gtm_set_shortcuts(struct device_node *np,
 337                                     struct gtm_timer *timers,
 338                                     struct gtm_timers_regs __iomem *regs)
 339{
 340        /*
 341         * Yeah, I don't like this either, but timers' registers a bit messed,
 342         * so we have to provide shortcuts to write timer independent code.
 343         * Alternative option is to create gt*() accessors, but that will be
 344         * even uglier and cryptic.
 345         */
 346        timers[0].gtcfr = &regs->gtcfr1;
 347        timers[0].gtmdr = &regs->gtmdr1;
 348        timers[0].gtcnr = &regs->gtcnr1;
 349        timers[0].gtrfr = &regs->gtrfr1;
 350        timers[0].gtevr = &regs->gtevr1;
 351
 352        timers[1].gtcfr = &regs->gtcfr1;
 353        timers[1].gtmdr = &regs->gtmdr2;
 354        timers[1].gtcnr = &regs->gtcnr2;
 355        timers[1].gtrfr = &regs->gtrfr2;
 356        timers[1].gtevr = &regs->gtevr2;
 357
 358        timers[2].gtcfr = &regs->gtcfr2;
 359        timers[2].gtmdr = &regs->gtmdr3;
 360        timers[2].gtcnr = &regs->gtcnr3;
 361        timers[2].gtrfr = &regs->gtrfr3;
 362        timers[2].gtevr = &regs->gtevr3;
 363
 364        timers[3].gtcfr = &regs->gtcfr2;
 365        timers[3].gtmdr = &regs->gtmdr4;
 366        timers[3].gtcnr = &regs->gtcnr4;
 367        timers[3].gtrfr = &regs->gtrfr4;
 368        timers[3].gtevr = &regs->gtevr4;
 369
 370        /* CPM2 doesn't have primary prescaler */
 371        if (!of_device_is_compatible(np, "fsl,cpm2-gtm")) {
 372                timers[0].gtpsr = &regs->gtpsr1;
 373                timers[1].gtpsr = &regs->gtpsr2;
 374                timers[2].gtpsr = &regs->gtpsr3;
 375                timers[3].gtpsr = &regs->gtpsr4;
 376        }
 377}
 378
 379static int __init fsl_gtm_init(void)
 380{
 381        struct device_node *np;
 382
 383        for_each_compatible_node(np, NULL, "fsl,gtm") {
 384                int i;
 385                struct gtm *gtm;
 386                const u32 *clock;
 387                int size;
 388
 389                gtm = kzalloc(sizeof(*gtm), GFP_KERNEL);
 390                if (!gtm) {
 391                        pr_err("%pOF: unable to allocate memory\n",
 392                                np);
 393                        continue;
 394                }
 395
 396                spin_lock_init(&gtm->lock);
 397
 398                clock = of_get_property(np, "clock-frequency", &size);
 399                if (!clock || size != sizeof(*clock)) {
 400                        pr_err("%pOF: no clock-frequency\n", np);
 401                        goto err;
 402                }
 403                gtm->clock = *clock;
 404
 405                for (i = 0; i < ARRAY_SIZE(gtm->timers); i++) {
 406                        unsigned int irq;
 407
 408                        irq = irq_of_parse_and_map(np, i);
 409                        if (!irq) {
 410                                pr_err("%pOF: not enough interrupts specified\n",
 411                                       np);
 412                                goto err;
 413                        }
 414                        gtm->timers[i].irq = irq;
 415                        gtm->timers[i].gtm = gtm;
 416                }
 417
 418                gtm->regs = of_iomap(np, 0);
 419                if (!gtm->regs) {
 420                        pr_err("%pOF: unable to iomap registers\n",
 421                               np);
 422                        goto err;
 423                }
 424
 425                gtm_set_shortcuts(np, gtm->timers, gtm->regs);
 426                list_add(&gtm->list_node, &gtms);
 427
 428                /* We don't want to lose the node and its ->data */
 429                np->data = gtm;
 430                of_node_get(np);
 431
 432                continue;
 433err:
 434                kfree(gtm);
 435        }
 436        return 0;
 437}
 438arch_initcall(fsl_gtm_init);
 439