time.c (8569B)
1/* 2 * Copyright (C) 2013-2014 Altera Corporation 3 * Copyright (C) 2010 Tobias Klauser <tklauser@distanz.ch> 4 * Copyright (C) 2004 Microtronix Datacom Ltd. 5 * 6 * This file is subject to the terms and conditions of the GNU General Public 7 * License. See the file "COPYING" in the main directory of this archive 8 * for more details. 9 */ 10 11#include <linux/export.h> 12#include <linux/interrupt.h> 13#include <linux/clockchips.h> 14#include <linux/clocksource.h> 15#include <linux/delay.h> 16#include <linux/of.h> 17#include <linux/of_address.h> 18#include <linux/of_irq.h> 19#include <linux/io.h> 20#include <linux/slab.h> 21 22#define ALTR_TIMER_COMPATIBLE "altr,timer-1.0" 23 24#define ALTERA_TIMER_STATUS_REG 0 25#define ALTERA_TIMER_CONTROL_REG 4 26#define ALTERA_TIMER_PERIODL_REG 8 27#define ALTERA_TIMER_PERIODH_REG 12 28#define ALTERA_TIMER_SNAPL_REG 16 29#define ALTERA_TIMER_SNAPH_REG 20 30 31#define ALTERA_TIMER_CONTROL_ITO_MSK (0x1) 32#define ALTERA_TIMER_CONTROL_CONT_MSK (0x2) 33#define ALTERA_TIMER_CONTROL_START_MSK (0x4) 34#define ALTERA_TIMER_CONTROL_STOP_MSK (0x8) 35 36struct nios2_timer { 37 void __iomem *base; 38 unsigned long freq; 39}; 40 41struct nios2_clockevent_dev { 42 struct nios2_timer timer; 43 struct clock_event_device ced; 44}; 45 46struct nios2_clocksource { 47 struct nios2_timer timer; 48 struct clocksource cs; 49}; 50 51static inline struct nios2_clockevent_dev * 52 to_nios2_clkevent(struct clock_event_device *evt) 53{ 54 return container_of(evt, struct nios2_clockevent_dev, ced); 55} 56 57static inline struct nios2_clocksource * 58 to_nios2_clksource(struct clocksource *cs) 59{ 60 return container_of(cs, struct nios2_clocksource, cs); 61} 62 63static u16 timer_readw(struct nios2_timer *timer, u32 offs) 64{ 65 return readw(timer->base + offs); 66} 67 68static void timer_writew(struct nios2_timer *timer, u16 val, u32 offs) 69{ 70 writew(val, timer->base + offs); 71} 72 73static inline unsigned long read_timersnapshot(struct nios2_timer *timer) 74{ 75 unsigned long count; 76 77 timer_writew(timer, 0, ALTERA_TIMER_SNAPL_REG); 78 count = timer_readw(timer, ALTERA_TIMER_SNAPH_REG) << 16 | 79 timer_readw(timer, ALTERA_TIMER_SNAPL_REG); 80 81 return count; 82} 83 84static u64 nios2_timer_read(struct clocksource *cs) 85{ 86 struct nios2_clocksource *nios2_cs = to_nios2_clksource(cs); 87 unsigned long flags; 88 u32 count; 89 90 local_irq_save(flags); 91 count = read_timersnapshot(&nios2_cs->timer); 92 local_irq_restore(flags); 93 94 /* Counter is counting down */ 95 return ~count; 96} 97 98static struct nios2_clocksource nios2_cs = { 99 .cs = { 100 .name = "nios2-clksrc", 101 .rating = 250, 102 .read = nios2_timer_read, 103 .mask = CLOCKSOURCE_MASK(32), 104 .flags = CLOCK_SOURCE_IS_CONTINUOUS, 105 }, 106}; 107 108cycles_t get_cycles(void) 109{ 110 /* Only read timer if it has been initialized */ 111 if (nios2_cs.timer.base) 112 return nios2_timer_read(&nios2_cs.cs); 113 return 0; 114} 115EXPORT_SYMBOL(get_cycles); 116 117static void nios2_timer_start(struct nios2_timer *timer) 118{ 119 u16 ctrl; 120 121 ctrl = timer_readw(timer, ALTERA_TIMER_CONTROL_REG); 122 ctrl |= ALTERA_TIMER_CONTROL_START_MSK; 123 timer_writew(timer, ctrl, ALTERA_TIMER_CONTROL_REG); 124} 125 126static void nios2_timer_stop(struct nios2_timer *timer) 127{ 128 u16 ctrl; 129 130 ctrl = timer_readw(timer, ALTERA_TIMER_CONTROL_REG); 131 ctrl |= ALTERA_TIMER_CONTROL_STOP_MSK; 132 timer_writew(timer, ctrl, ALTERA_TIMER_CONTROL_REG); 133} 134 135static void nios2_timer_config(struct nios2_timer *timer, unsigned long period, 136 bool periodic) 137{ 138 u16 ctrl; 139 140 /* The timer's actual period is one cycle greater than the value 141 * stored in the period register. */ 142 period--; 143 144 ctrl = timer_readw(timer, ALTERA_TIMER_CONTROL_REG); 145 /* stop counter */ 146 timer_writew(timer, ctrl | ALTERA_TIMER_CONTROL_STOP_MSK, 147 ALTERA_TIMER_CONTROL_REG); 148 149 /* write new count */ 150 timer_writew(timer, period, ALTERA_TIMER_PERIODL_REG); 151 timer_writew(timer, period >> 16, ALTERA_TIMER_PERIODH_REG); 152 153 ctrl |= ALTERA_TIMER_CONTROL_START_MSK | ALTERA_TIMER_CONTROL_ITO_MSK; 154 if (periodic) 155 ctrl |= ALTERA_TIMER_CONTROL_CONT_MSK; 156 else 157 ctrl &= ~ALTERA_TIMER_CONTROL_CONT_MSK; 158 timer_writew(timer, ctrl, ALTERA_TIMER_CONTROL_REG); 159} 160 161static int nios2_timer_set_next_event(unsigned long delta, 162 struct clock_event_device *evt) 163{ 164 struct nios2_clockevent_dev *nios2_ced = to_nios2_clkevent(evt); 165 166 nios2_timer_config(&nios2_ced->timer, delta, false); 167 168 return 0; 169} 170 171static int nios2_timer_shutdown(struct clock_event_device *evt) 172{ 173 struct nios2_clockevent_dev *nios2_ced = to_nios2_clkevent(evt); 174 struct nios2_timer *timer = &nios2_ced->timer; 175 176 nios2_timer_stop(timer); 177 return 0; 178} 179 180static int nios2_timer_set_periodic(struct clock_event_device *evt) 181{ 182 unsigned long period; 183 struct nios2_clockevent_dev *nios2_ced = to_nios2_clkevent(evt); 184 struct nios2_timer *timer = &nios2_ced->timer; 185 186 period = DIV_ROUND_UP(timer->freq, HZ); 187 nios2_timer_config(timer, period, true); 188 return 0; 189} 190 191static int nios2_timer_resume(struct clock_event_device *evt) 192{ 193 struct nios2_clockevent_dev *nios2_ced = to_nios2_clkevent(evt); 194 struct nios2_timer *timer = &nios2_ced->timer; 195 196 nios2_timer_start(timer); 197 return 0; 198} 199 200irqreturn_t timer_interrupt(int irq, void *dev_id) 201{ 202 struct clock_event_device *evt = (struct clock_event_device *) dev_id; 203 struct nios2_clockevent_dev *nios2_ced = to_nios2_clkevent(evt); 204 205 /* Clear the interrupt condition */ 206 timer_writew(&nios2_ced->timer, 0, ALTERA_TIMER_STATUS_REG); 207 evt->event_handler(evt); 208 209 return IRQ_HANDLED; 210} 211 212static int __init nios2_timer_get_base_and_freq(struct device_node *np, 213 void __iomem **base, u32 *freq) 214{ 215 *base = of_iomap(np, 0); 216 if (!*base) { 217 pr_crit("Unable to map reg for %pOFn\n", np); 218 return -ENXIO; 219 } 220 221 if (of_property_read_u32(np, "clock-frequency", freq)) { 222 pr_crit("Unable to get %pOFn clock frequency\n", np); 223 return -EINVAL; 224 } 225 226 return 0; 227} 228 229static struct nios2_clockevent_dev nios2_ce = { 230 .ced = { 231 .name = "nios2-clkevent", 232 .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, 233 .rating = 250, 234 .shift = 32, 235 .set_next_event = nios2_timer_set_next_event, 236 .set_state_shutdown = nios2_timer_shutdown, 237 .set_state_periodic = nios2_timer_set_periodic, 238 .set_state_oneshot = nios2_timer_shutdown, 239 .tick_resume = nios2_timer_resume, 240 }, 241}; 242 243static __init int nios2_clockevent_init(struct device_node *timer) 244{ 245 void __iomem *iobase; 246 u32 freq; 247 int irq, ret; 248 249 ret = nios2_timer_get_base_and_freq(timer, &iobase, &freq); 250 if (ret) 251 return ret; 252 253 irq = irq_of_parse_and_map(timer, 0); 254 if (!irq) { 255 pr_crit("Unable to parse timer irq\n"); 256 return -EINVAL; 257 } 258 259 nios2_ce.timer.base = iobase; 260 nios2_ce.timer.freq = freq; 261 262 nios2_ce.ced.cpumask = cpumask_of(0); 263 nios2_ce.ced.irq = irq; 264 265 nios2_timer_stop(&nios2_ce.timer); 266 /* clear pending interrupt */ 267 timer_writew(&nios2_ce.timer, 0, ALTERA_TIMER_STATUS_REG); 268 269 ret = request_irq(irq, timer_interrupt, IRQF_TIMER, timer->name, 270 &nios2_ce.ced); 271 if (ret) { 272 pr_crit("Unable to setup timer irq\n"); 273 return ret; 274 } 275 276 clockevents_config_and_register(&nios2_ce.ced, freq, 1, ULONG_MAX); 277 278 return 0; 279} 280 281static __init int nios2_clocksource_init(struct device_node *timer) 282{ 283 unsigned int ctrl; 284 void __iomem *iobase; 285 u32 freq; 286 int ret; 287 288 ret = nios2_timer_get_base_and_freq(timer, &iobase, &freq); 289 if (ret) 290 return ret; 291 292 nios2_cs.timer.base = iobase; 293 nios2_cs.timer.freq = freq; 294 295 ret = clocksource_register_hz(&nios2_cs.cs, freq); 296 if (ret) 297 return ret; 298 299 timer_writew(&nios2_cs.timer, USHRT_MAX, ALTERA_TIMER_PERIODL_REG); 300 timer_writew(&nios2_cs.timer, USHRT_MAX, ALTERA_TIMER_PERIODH_REG); 301 302 /* interrupt disable + continuous + start */ 303 ctrl = ALTERA_TIMER_CONTROL_CONT_MSK | ALTERA_TIMER_CONTROL_START_MSK; 304 timer_writew(&nios2_cs.timer, ctrl, ALTERA_TIMER_CONTROL_REG); 305 306 /* Calibrate the delay loop directly */ 307 lpj_fine = freq / HZ; 308 309 return 0; 310} 311 312/* 313 * The first timer instance will use as a clockevent. If there are two or 314 * more instances, the second one gets used as clocksource and all 315 * others are unused. 316*/ 317static int __init nios2_time_init(struct device_node *timer) 318{ 319 static int num_called; 320 int ret; 321 322 switch (num_called) { 323 case 0: 324 ret = nios2_clockevent_init(timer); 325 break; 326 case 1: 327 ret = nios2_clocksource_init(timer); 328 break; 329 default: 330 ret = 0; 331 break; 332 } 333 334 num_called++; 335 336 return ret; 337} 338 339void read_persistent_clock64(struct timespec64 *ts) 340{ 341 ts->tv_sec = mktime64(2007, 1, 1, 0, 0, 0); 342 ts->tv_nsec = 0; 343} 344 345void __init time_init(void) 346{ 347 struct device_node *np; 348 int count = 0; 349 350 for_each_compatible_node(np, NULL, ALTR_TIMER_COMPATIBLE) 351 count++; 352 353 if (count < 2) 354 panic("%d timer is found, it needs 2 timers in system\n", count); 355 356 timer_probe(); 357} 358 359TIMER_OF_DECLARE(nios2_timer, ALTR_TIMER_COMPATIBLE, nios2_time_init);