/*1* Freescale General-purpose Timers Module2*3* Copyright (c) Freescale Semicondutor, Inc. 2006.4* Shlomi Gridish <[email protected]>5* Jerry Huang <[email protected]>6* Copyright (c) MontaVista Software, Inc. 2008.7* Anton Vorontsov <[email protected]>8*9* This program is free software; you can redistribute it and/or modify it10* under the terms of the GNU General Public License as published by the11* Free Software Foundation; either version 2 of the License, or (at your12* option) any later version.13*/1415#include <linux/kernel.h>16#include <linux/err.h>17#include <linux/errno.h>18#include <linux/list.h>19#include <linux/io.h>20#include <linux/of.h>21#include <linux/spinlock.h>22#include <linux/bitops.h>23#include <linux/slab.h>24#include <asm/fsl_gtm.h>2526#define GTCFR_STP(x) ((x) & 1 ? 1 << 5 : 1 << 1)27#define GTCFR_RST(x) ((x) & 1 ? 1 << 4 : 1 << 0)2829#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)3637struct gtm_timers_regs {38u8 gtcfr1; /* Timer 1, Timer 2 global config register */39u8 res0[0x3];40u8 gtcfr2; /* Timer 3, timer 4 global config register */41u8 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 */66u8 res2[0x40];67} __attribute__ ((packed));6869struct gtm {70unsigned int clock;71struct gtm_timers_regs __iomem *regs;72struct gtm_timer timers[4];73spinlock_t lock;74struct list_head list_node;75};7677static LIST_HEAD(gtms);7879/**80* gtm_get_timer - request GTM timer to use it with the rest of GTM API81* Context: non-IRQ82*83* This function reserves GTM timer for later use. It returns gtm_timer84* structure to use with the rest of GTM API, you should use timer->irq85* to manage timer interrupt.86*/87struct gtm_timer *gtm_get_timer16(void)88{89struct gtm *gtm = NULL;90int i;9192list_for_each_entry(gtm, >ms, list_node) {93spin_lock_irq(>m->lock);9495for (i = 0; i < ARRAY_SIZE(gtm->timers); i++) {96if (!gtm->timers[i].requested) {97gtm->timers[i].requested = true;98spin_unlock_irq(>m->lock);99return >m->timers[i];100}101}102103spin_unlock_irq(>m->lock);104}105106if (gtm)107return ERR_PTR(-EBUSY);108return ERR_PTR(-ENODEV);109}110EXPORT_SYMBOL(gtm_get_timer16);111112/**113* gtm_get_specific_timer - request specific GTM timer114* @gtm: specific GTM, pass here GTM's device_node->data115* @timer: specific timer number, Timer1 is 0.116* Context: non-IRQ117*118* This function reserves GTM timer for later use. It returns gtm_timer119* structure to use with the rest of GTM API, you should use timer->irq120* to manage timer interrupt.121*/122struct gtm_timer *gtm_get_specific_timer16(struct gtm *gtm,123unsigned int timer)124{125struct gtm_timer *ret = ERR_PTR(-EBUSY);126127if (timer > 3)128return ERR_PTR(-EINVAL);129130spin_lock_irq(>m->lock);131132if (gtm->timers[timer].requested)133goto out;134135ret = >m->timers[timer];136ret->requested = true;137138out:139spin_unlock_irq(>m->lock);140return ret;141}142EXPORT_SYMBOL(gtm_get_specific_timer16);143144/**145* gtm_put_timer16 - release 16 bits GTM timer146* @tmr: pointer to the gtm_timer structure obtained from gtm_get_timer147* Context: any148*149* This function releases GTM timer so others may request it.150*/151void gtm_put_timer16(struct gtm_timer *tmr)152{153gtm_stop_timer16(tmr);154155spin_lock_irq(&tmr->gtm->lock);156tmr->requested = false;157spin_unlock_irq(&tmr->gtm->lock);158}159EXPORT_SYMBOL(gtm_put_timer16);160161/*162* This is back-end for the exported functions, it's used to reset single163* timer in reference mode.164*/165static int gtm_set_ref_timer16(struct gtm_timer *tmr, int frequency,166int reference_value, bool free_run)167{168struct gtm *gtm = tmr->gtm;169int num = tmr - >m->timers[0];170unsigned int prescaler;171u8 iclk = GTMDR_ICLK_ICLK;172u8 psr;173u8 sps;174unsigned long flags;175int max_prescaler = 256 * 256 * 16;176177/* CPM2 doesn't have primary prescaler */178if (!tmr->gtpsr)179max_prescaler /= 256;180181prescaler = 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 is185* 16 * (psr + 1) * (sps + 1). Though, for CPM2 GTMs we losing psr.186*/187if (prescaler > max_prescaler)188return -EINVAL;189190if (prescaler > max_prescaler / 16) {191iclk = GTMDR_ICLK_SLGO;192prescaler /= 16;193}194195if (prescaler <= 256) {196psr = 0;197sps = prescaler - 1;198} else {199psr = 256 - 1;200sps = prescaler / 256 - 1;201}202203spin_lock_irqsave(>m->lock, flags);204205/*206* Properly reset timers: stop, reset, set up prescalers, reference207* value and clear event register.208*/209clrsetbits_8(tmr->gtcfr, ~(GTCFR_STP(num) | GTCFR_RST(num)),210GTCFR_STP(num) | GTCFR_RST(num));211212setbits8(tmr->gtcfr, GTCFR_STP(num));213214if (tmr->gtpsr)215out_be16(tmr->gtpsr, psr);216clrsetbits_be16(tmr->gtmdr, 0xFFFF, iclk | GTMDR_SPS(sps) |217GTMDR_ORI | (free_run ? GTMDR_FRR : 0));218out_be16(tmr->gtcnr, 0);219out_be16(tmr->gtrfr, reference_value);220out_be16(tmr->gtevr, 0xFFFF);221222/* Let it be. */223clrbits8(tmr->gtcfr, GTCFR_STP(num));224225spin_unlock_irqrestore(>m->lock, flags);226227return 0;228}229230/**231* gtm_set_timer16 - (re)set 16 bit timer with arbitrary precision232* @tmr: pointer to the gtm_timer structure obtained from gtm_get_timer233* @usec: timer interval in microseconds234* @reload: if set, the timer will reset upon expiry rather than235* continue running free.236* Context: any237*238* This function (re)sets the GTM timer so that it counts up to the requested239* interval value, and fires the interrupt when the value is reached. This240* function will reduce the precision of the timer as needed in order for the241* requested timeout to fit in a 16-bit register.242*/243int gtm_set_timer16(struct gtm_timer *tmr, unsigned long usec, bool reload)244{245/* quite obvious, frequency which is enough for µSec precision */246int freq = 1000000;247unsigned int bit;248249bit = fls_long(usec);250if (bit > 15) {251freq >>= bit - 15;252usec >>= bit - 15;253}254255if (!freq)256return -EINVAL;257258return gtm_set_ref_timer16(tmr, freq, usec, reload);259}260EXPORT_SYMBOL(gtm_set_timer16);261262/**263* gtm_set_exact_utimer16 - (re)set 16 bits timer264* @tmr: pointer to the gtm_timer structure obtained from gtm_get_timer265* @usec: timer interval in microseconds266* @reload: if set, the timer will reset upon expiry rather than267* continue running free.268* Context: any269*270* This function (re)sets GTM timer so that it counts up to the requested271* interval value, and fires the interrupt when the value is reached. If reload272* flag was set, timer will also reset itself upon reference value, otherwise273* it continues to increment.274*275* The _exact_ bit in the function name states that this function will not276* crop precision of the "usec" argument, thus usec is limited to 16 bits277* (single timer width).278*/279int gtm_set_exact_timer16(struct gtm_timer *tmr, u16 usec, bool reload)280{281/* quite obvious, frequency which is enough for µSec precision */282const int freq = 1000000;283284/*285* We can lower the frequency (and probably power consumption) by286* 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 just288* run the timer as is.289*/290291return gtm_set_ref_timer16(tmr, freq, usec, reload);292}293EXPORT_SYMBOL(gtm_set_exact_timer16);294295/**296* gtm_stop_timer16 - stop single timer297* @tmr: pointer to the gtm_timer structure obtained from gtm_get_timer298* Context: any299*300* This function simply stops the GTM timer.301*/302void gtm_stop_timer16(struct gtm_timer *tmr)303{304struct gtm *gtm = tmr->gtm;305int num = tmr - >m->timers[0];306unsigned long flags;307308spin_lock_irqsave(>m->lock, flags);309310setbits8(tmr->gtcfr, GTCFR_STP(num));311out_be16(tmr->gtevr, 0xFFFF);312313spin_unlock_irqrestore(>m->lock, flags);314}315EXPORT_SYMBOL(gtm_stop_timer16);316317/**318* gtm_ack_timer16 - acknowledge timer event (free-run timers only)319* @tmr: pointer to the gtm_timer structure obtained from gtm_get_timer320* @events: events mask to ack321* Context: any322*323* Thus function used to acknowledge timer interrupt event, use it inside the324* interrupt handler.325*/326void gtm_ack_timer16(struct gtm_timer *tmr, u16 events)327{328out_be16(tmr->gtevr, events);329}330EXPORT_SYMBOL(gtm_ack_timer16);331332static void __init gtm_set_shortcuts(struct device_node *np,333struct gtm_timer *timers,334struct 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 be340* even uglier and cryptic.341*/342timers[0].gtcfr = ®s->gtcfr1;343timers[0].gtmdr = ®s->gtmdr1;344timers[0].gtcnr = ®s->gtcnr1;345timers[0].gtrfr = ®s->gtrfr1;346timers[0].gtevr = ®s->gtevr1;347348timers[1].gtcfr = ®s->gtcfr1;349timers[1].gtmdr = ®s->gtmdr2;350timers[1].gtcnr = ®s->gtcnr2;351timers[1].gtrfr = ®s->gtrfr2;352timers[1].gtevr = ®s->gtevr2;353354timers[2].gtcfr = ®s->gtcfr2;355timers[2].gtmdr = ®s->gtmdr3;356timers[2].gtcnr = ®s->gtcnr3;357timers[2].gtrfr = ®s->gtrfr3;358timers[2].gtevr = ®s->gtevr3;359360timers[3].gtcfr = ®s->gtcfr2;361timers[3].gtmdr = ®s->gtmdr4;362timers[3].gtcnr = ®s->gtcnr4;363timers[3].gtrfr = ®s->gtrfr4;364timers[3].gtevr = ®s->gtevr4;365366/* CPM2 doesn't have primary prescaler */367if (!of_device_is_compatible(np, "fsl,cpm2-gtm")) {368timers[0].gtpsr = ®s->gtpsr1;369timers[1].gtpsr = ®s->gtpsr2;370timers[2].gtpsr = ®s->gtpsr3;371timers[3].gtpsr = ®s->gtpsr4;372}373}374375static int __init fsl_gtm_init(void)376{377struct device_node *np;378379for_each_compatible_node(np, NULL, "fsl,gtm") {380int i;381struct gtm *gtm;382const u32 *clock;383int size;384385gtm = kzalloc(sizeof(*gtm), GFP_KERNEL);386if (!gtm) {387pr_err("%s: unable to allocate memory\n",388np->full_name);389continue;390}391392spin_lock_init(>m->lock);393394clock = of_get_property(np, "clock-frequency", &size);395if (!clock || size != sizeof(*clock)) {396pr_err("%s: no clock-frequency\n", np->full_name);397goto err;398}399gtm->clock = *clock;400401for (i = 0; i < ARRAY_SIZE(gtm->timers); i++) {402int ret;403struct resource irq;404405ret = of_irq_to_resource(np, i, &irq);406if (ret == NO_IRQ) {407pr_err("%s: not enough interrupts specified\n",408np->full_name);409goto err;410}411gtm->timers[i].irq = irq.start;412gtm->timers[i].gtm = gtm;413}414415gtm->regs = of_iomap(np, 0);416if (!gtm->regs) {417pr_err("%s: unable to iomap registers\n",418np->full_name);419goto err;420}421422gtm_set_shortcuts(np, gtm->timers, gtm->regs);423list_add(>m->list_node, >ms);424425/* We don't want to lose the node and its ->data */426np->data = gtm;427of_node_get(np);428429continue;430err:431kfree(gtm);432}433return 0;434}435arch_initcall(fsl_gtm_init);436437438