timer-keystone.c (5429B)
1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * Keystone broadcast clock-event 4 * 5 * Copyright 2013 Texas Instruments, Inc. 6 * 7 * Author: Ivan Khoronzhuk <ivan.khoronzhuk@ti.com> 8 */ 9 10#include <linux/clk.h> 11#include <linux/clockchips.h> 12#include <linux/clocksource.h> 13#include <linux/interrupt.h> 14#include <linux/of_address.h> 15#include <linux/of_irq.h> 16 17#define TIMER_NAME "timer-keystone" 18 19/* Timer register offsets */ 20#define TIM12 0x10 21#define TIM34 0x14 22#define PRD12 0x18 23#define PRD34 0x1c 24#define TCR 0x20 25#define TGCR 0x24 26#define INTCTLSTAT 0x44 27 28/* Timer register bitfields */ 29#define TCR_ENAMODE_MASK 0xC0 30#define TCR_ENAMODE_ONESHOT_MASK 0x40 31#define TCR_ENAMODE_PERIODIC_MASK 0x80 32 33#define TGCR_TIM_UNRESET_MASK 0x03 34#define INTCTLSTAT_ENINT_MASK 0x01 35 36/** 37 * struct keystone_timer: holds timer's data 38 * @base: timer memory base address 39 * @hz_period: cycles per HZ period 40 * @event_dev: event device based on timer 41 */ 42static struct keystone_timer { 43 void __iomem *base; 44 unsigned long hz_period; 45 struct clock_event_device event_dev; 46} timer; 47 48static inline u32 keystone_timer_readl(unsigned long rg) 49{ 50 return readl_relaxed(timer.base + rg); 51} 52 53static inline void keystone_timer_writel(u32 val, unsigned long rg) 54{ 55 writel_relaxed(val, timer.base + rg); 56} 57 58/** 59 * keystone_timer_barrier: write memory barrier 60 * use explicit barrier to avoid using readl/writel non relaxed function 61 * variants, because in our case non relaxed variants hide the true places 62 * where barrier is needed. 63 */ 64static inline void keystone_timer_barrier(void) 65{ 66 __iowmb(); 67} 68 69/** 70 * keystone_timer_config: configures timer to work in oneshot/periodic modes. 71 * @ mask: mask of the mode to configure 72 * @ period: cycles number to configure for 73 */ 74static int keystone_timer_config(u64 period, int mask) 75{ 76 u32 tcr; 77 u32 off; 78 79 tcr = keystone_timer_readl(TCR); 80 off = tcr & ~(TCR_ENAMODE_MASK); 81 82 /* set enable mode */ 83 tcr |= mask; 84 85 /* disable timer */ 86 keystone_timer_writel(off, TCR); 87 /* here we have to be sure the timer has been disabled */ 88 keystone_timer_barrier(); 89 90 /* reset counter to zero, set new period */ 91 keystone_timer_writel(0, TIM12); 92 keystone_timer_writel(0, TIM34); 93 keystone_timer_writel(period & 0xffffffff, PRD12); 94 keystone_timer_writel(period >> 32, PRD34); 95 96 /* 97 * enable timer 98 * here we have to be sure that CNTLO, CNTHI, PRDLO, PRDHI registers 99 * have been written. 100 */ 101 keystone_timer_barrier(); 102 keystone_timer_writel(tcr, TCR); 103 return 0; 104} 105 106static void keystone_timer_disable(void) 107{ 108 u32 tcr; 109 110 tcr = keystone_timer_readl(TCR); 111 112 /* disable timer */ 113 tcr &= ~(TCR_ENAMODE_MASK); 114 keystone_timer_writel(tcr, TCR); 115} 116 117static irqreturn_t keystone_timer_interrupt(int irq, void *dev_id) 118{ 119 struct clock_event_device *evt = dev_id; 120 121 evt->event_handler(evt); 122 return IRQ_HANDLED; 123} 124 125static int keystone_set_next_event(unsigned long cycles, 126 struct clock_event_device *evt) 127{ 128 return keystone_timer_config(cycles, TCR_ENAMODE_ONESHOT_MASK); 129} 130 131static int keystone_shutdown(struct clock_event_device *evt) 132{ 133 keystone_timer_disable(); 134 return 0; 135} 136 137static int keystone_set_periodic(struct clock_event_device *evt) 138{ 139 keystone_timer_config(timer.hz_period, TCR_ENAMODE_PERIODIC_MASK); 140 return 0; 141} 142 143static int __init keystone_timer_init(struct device_node *np) 144{ 145 struct clock_event_device *event_dev = &timer.event_dev; 146 unsigned long rate; 147 struct clk *clk; 148 int irq, error; 149 150 irq = irq_of_parse_and_map(np, 0); 151 if (!irq) { 152 pr_err("%s: failed to map interrupts\n", __func__); 153 return -EINVAL; 154 } 155 156 timer.base = of_iomap(np, 0); 157 if (!timer.base) { 158 pr_err("%s: failed to map registers\n", __func__); 159 return -ENXIO; 160 } 161 162 clk = of_clk_get(np, 0); 163 if (IS_ERR(clk)) { 164 pr_err("%s: failed to get clock\n", __func__); 165 iounmap(timer.base); 166 return PTR_ERR(clk); 167 } 168 169 error = clk_prepare_enable(clk); 170 if (error) { 171 pr_err("%s: failed to enable clock\n", __func__); 172 goto err; 173 } 174 175 rate = clk_get_rate(clk); 176 177 /* disable, use internal clock source */ 178 keystone_timer_writel(0, TCR); 179 /* here we have to be sure the timer has been disabled */ 180 keystone_timer_barrier(); 181 182 /* reset timer as 64-bit, no pre-scaler, plus features are disabled */ 183 keystone_timer_writel(0, TGCR); 184 185 /* unreset timer */ 186 keystone_timer_writel(TGCR_TIM_UNRESET_MASK, TGCR); 187 188 /* init counter to zero */ 189 keystone_timer_writel(0, TIM12); 190 keystone_timer_writel(0, TIM34); 191 192 timer.hz_period = DIV_ROUND_UP(rate, HZ); 193 194 /* enable timer interrupts */ 195 keystone_timer_writel(INTCTLSTAT_ENINT_MASK, INTCTLSTAT); 196 197 error = request_irq(irq, keystone_timer_interrupt, IRQF_TIMER, 198 TIMER_NAME, event_dev); 199 if (error) { 200 pr_err("%s: failed to setup irq\n", __func__); 201 goto err; 202 } 203 204 /* setup clockevent */ 205 event_dev->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT; 206 event_dev->set_next_event = keystone_set_next_event; 207 event_dev->set_state_shutdown = keystone_shutdown; 208 event_dev->set_state_periodic = keystone_set_periodic; 209 event_dev->set_state_oneshot = keystone_shutdown; 210 event_dev->cpumask = cpu_possible_mask; 211 event_dev->owner = THIS_MODULE; 212 event_dev->name = TIMER_NAME; 213 event_dev->irq = irq; 214 215 clockevents_config_and_register(event_dev, rate, 1, ULONG_MAX); 216 217 pr_info("keystone timer clock @%lu Hz\n", rate); 218 return 0; 219err: 220 clk_put(clk); 221 iounmap(timer.base); 222 return error; 223} 224 225TIMER_OF_DECLARE(keystone_timer, "ti,keystone-timer", 226 keystone_timer_init);