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