root/arch/powerpc/sysdev/fsl_gtm.c

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

DEFINITIONS

This source file includes following definitions.
  1. gtm_get_timer16
  2. gtm_get_specific_timer16
  3. gtm_put_timer16
  4. gtm_set_ref_timer16
  5. gtm_set_timer16
  6. gtm_set_exact_timer16
  7. gtm_stop_timer16
  8. gtm_ack_timer16
  9. gtm_set_shortcuts
  10. fsl_gtm_init

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

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