root/arch/microblaze/kernel/timer.c

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

DEFINITIONS

This source file includes following definitions.
  1. timer_write32
  2. timer_read32
  3. timer_write32_be
  4. timer_read32_be
  5. xilinx_timer0_stop
  6. xilinx_timer0_start_periodic
  7. xilinx_timer0_start_oneshot
  8. xilinx_timer_set_next_event
  9. xilinx_timer_shutdown
  10. xilinx_timer_set_periodic
  11. timer_ack
  12. timer_interrupt
  13. xilinx_clockevent_init
  14. xilinx_clock_read
  15. xilinx_read
  16. xilinx_cc_read
  17. init_xilinx_timecounter
  18. xilinx_clocksource_init
  19. xilinx_timer_init

   1 /*
   2  * Copyright (C) 2007-2013 Michal Simek <monstr@monstr.eu>
   3  * Copyright (C) 2012-2013 Xilinx, Inc.
   4  * Copyright (C) 2007-2009 PetaLogix
   5  * Copyright (C) 2006 Atmark Techno, Inc.
   6  *
   7  * This file is subject to the terms and conditions of the GNU General Public
   8  * License. See the file "COPYING" in the main directory of this archive
   9  * for more details.
  10  */
  11 
  12 #include <linux/interrupt.h>
  13 #include <linux/delay.h>
  14 #include <linux/sched.h>
  15 #include <linux/sched/clock.h>
  16 #include <linux/sched_clock.h>
  17 #include <linux/clk.h>
  18 #include <linux/clockchips.h>
  19 #include <linux/of_address.h>
  20 #include <linux/of_irq.h>
  21 #include <linux/timecounter.h>
  22 #include <asm/cpuinfo.h>
  23 
  24 static void __iomem *timer_baseaddr;
  25 
  26 static unsigned int freq_div_hz;
  27 static unsigned int timer_clock_freq;
  28 
  29 #define TCSR0   (0x00)
  30 #define TLR0    (0x04)
  31 #define TCR0    (0x08)
  32 #define TCSR1   (0x10)
  33 #define TLR1    (0x14)
  34 #define TCR1    (0x18)
  35 
  36 #define TCSR_MDT        (1<<0)
  37 #define TCSR_UDT        (1<<1)
  38 #define TCSR_GENT       (1<<2)
  39 #define TCSR_CAPT       (1<<3)
  40 #define TCSR_ARHT       (1<<4)
  41 #define TCSR_LOAD       (1<<5)
  42 #define TCSR_ENIT       (1<<6)
  43 #define TCSR_ENT        (1<<7)
  44 #define TCSR_TINT       (1<<8)
  45 #define TCSR_PWMA       (1<<9)
  46 #define TCSR_ENALL      (1<<10)
  47 
  48 static unsigned int (*read_fn)(void __iomem *);
  49 static void (*write_fn)(u32, void __iomem *);
  50 
  51 static void timer_write32(u32 val, void __iomem *addr)
  52 {
  53         iowrite32(val, addr);
  54 }
  55 
  56 static unsigned int timer_read32(void __iomem *addr)
  57 {
  58         return ioread32(addr);
  59 }
  60 
  61 static void timer_write32_be(u32 val, void __iomem *addr)
  62 {
  63         iowrite32be(val, addr);
  64 }
  65 
  66 static unsigned int timer_read32_be(void __iomem *addr)
  67 {
  68         return ioread32be(addr);
  69 }
  70 
  71 static inline void xilinx_timer0_stop(void)
  72 {
  73         write_fn(read_fn(timer_baseaddr + TCSR0) & ~TCSR_ENT,
  74                  timer_baseaddr + TCSR0);
  75 }
  76 
  77 static inline void xilinx_timer0_start_periodic(unsigned long load_val)
  78 {
  79         if (!load_val)
  80                 load_val = 1;
  81         /* loading value to timer reg */
  82         write_fn(load_val, timer_baseaddr + TLR0);
  83 
  84         /* load the initial value */
  85         write_fn(TCSR_LOAD, timer_baseaddr + TCSR0);
  86 
  87         /* see timer data sheet for detail
  88          * !ENALL - don't enable 'em all
  89          * !PWMA - disable pwm
  90          * TINT - clear interrupt status
  91          * ENT- enable timer itself
  92          * ENIT - enable interrupt
  93          * !LOAD - clear the bit to let go
  94          * ARHT - auto reload
  95          * !CAPT - no external trigger
  96          * !GENT - no external signal
  97          * UDT - set the timer as down counter
  98          * !MDT0 - generate mode
  99          */
 100         write_fn(TCSR_TINT|TCSR_ENIT|TCSR_ENT|TCSR_ARHT|TCSR_UDT,
 101                  timer_baseaddr + TCSR0);
 102 }
 103 
 104 static inline void xilinx_timer0_start_oneshot(unsigned long load_val)
 105 {
 106         if (!load_val)
 107                 load_val = 1;
 108         /* loading value to timer reg */
 109         write_fn(load_val, timer_baseaddr + TLR0);
 110 
 111         /* load the initial value */
 112         write_fn(TCSR_LOAD, timer_baseaddr + TCSR0);
 113 
 114         write_fn(TCSR_TINT|TCSR_ENIT|TCSR_ENT|TCSR_ARHT|TCSR_UDT,
 115                  timer_baseaddr + TCSR0);
 116 }
 117 
 118 static int xilinx_timer_set_next_event(unsigned long delta,
 119                                         struct clock_event_device *dev)
 120 {
 121         pr_debug("%s: next event, delta %x\n", __func__, (u32)delta);
 122         xilinx_timer0_start_oneshot(delta);
 123         return 0;
 124 }
 125 
 126 static int xilinx_timer_shutdown(struct clock_event_device *evt)
 127 {
 128         pr_info("%s\n", __func__);
 129         xilinx_timer0_stop();
 130         return 0;
 131 }
 132 
 133 static int xilinx_timer_set_periodic(struct clock_event_device *evt)
 134 {
 135         pr_info("%s\n", __func__);
 136         xilinx_timer0_start_periodic(freq_div_hz);
 137         return 0;
 138 }
 139 
 140 static struct clock_event_device clockevent_xilinx_timer = {
 141         .name                   = "xilinx_clockevent",
 142         .features               = CLOCK_EVT_FEAT_ONESHOT |
 143                                   CLOCK_EVT_FEAT_PERIODIC,
 144         .shift                  = 8,
 145         .rating                 = 300,
 146         .set_next_event         = xilinx_timer_set_next_event,
 147         .set_state_shutdown     = xilinx_timer_shutdown,
 148         .set_state_periodic     = xilinx_timer_set_periodic,
 149 };
 150 
 151 static inline void timer_ack(void)
 152 {
 153         write_fn(read_fn(timer_baseaddr + TCSR0), timer_baseaddr + TCSR0);
 154 }
 155 
 156 static irqreturn_t timer_interrupt(int irq, void *dev_id)
 157 {
 158         struct clock_event_device *evt = &clockevent_xilinx_timer;
 159         timer_ack();
 160         evt->event_handler(evt);
 161         return IRQ_HANDLED;
 162 }
 163 
 164 static struct irqaction timer_irqaction = {
 165         .handler = timer_interrupt,
 166         .flags = IRQF_TIMER,
 167         .name = "timer",
 168         .dev_id = &clockevent_xilinx_timer,
 169 };
 170 
 171 static __init int xilinx_clockevent_init(void)
 172 {
 173         clockevent_xilinx_timer.mult =
 174                 div_sc(timer_clock_freq, NSEC_PER_SEC,
 175                                 clockevent_xilinx_timer.shift);
 176         clockevent_xilinx_timer.max_delta_ns =
 177                 clockevent_delta2ns((u32)~0, &clockevent_xilinx_timer);
 178         clockevent_xilinx_timer.max_delta_ticks = (u32)~0;
 179         clockevent_xilinx_timer.min_delta_ns =
 180                 clockevent_delta2ns(1, &clockevent_xilinx_timer);
 181         clockevent_xilinx_timer.min_delta_ticks = 1;
 182         clockevent_xilinx_timer.cpumask = cpumask_of(0);
 183         clockevents_register_device(&clockevent_xilinx_timer);
 184 
 185         return 0;
 186 }
 187 
 188 static u64 xilinx_clock_read(void)
 189 {
 190         return read_fn(timer_baseaddr + TCR1);
 191 }
 192 
 193 static u64 xilinx_read(struct clocksource *cs)
 194 {
 195         /* reading actual value of timer 1 */
 196         return (u64)xilinx_clock_read();
 197 }
 198 
 199 static struct timecounter xilinx_tc = {
 200         .cc = NULL,
 201 };
 202 
 203 static u64 xilinx_cc_read(const struct cyclecounter *cc)
 204 {
 205         return xilinx_read(NULL);
 206 }
 207 
 208 static struct cyclecounter xilinx_cc = {
 209         .read = xilinx_cc_read,
 210         .mask = CLOCKSOURCE_MASK(32),
 211         .shift = 8,
 212 };
 213 
 214 static int __init init_xilinx_timecounter(void)
 215 {
 216         xilinx_cc.mult = div_sc(timer_clock_freq, NSEC_PER_SEC,
 217                                 xilinx_cc.shift);
 218 
 219         timecounter_init(&xilinx_tc, &xilinx_cc, sched_clock());
 220 
 221         return 0;
 222 }
 223 
 224 static struct clocksource clocksource_microblaze = {
 225         .name           = "xilinx_clocksource",
 226         .rating         = 300,
 227         .read           = xilinx_read,
 228         .mask           = CLOCKSOURCE_MASK(32),
 229         .flags          = CLOCK_SOURCE_IS_CONTINUOUS,
 230 };
 231 
 232 static int __init xilinx_clocksource_init(void)
 233 {
 234         int ret;
 235 
 236         ret = clocksource_register_hz(&clocksource_microblaze,
 237                                       timer_clock_freq);
 238         if (ret) {
 239                 pr_err("failed to register clocksource");
 240                 return ret;
 241         }
 242 
 243         /* stop timer1 */
 244         write_fn(read_fn(timer_baseaddr + TCSR1) & ~TCSR_ENT,
 245                  timer_baseaddr + TCSR1);
 246         /* start timer1 - up counting without interrupt */
 247         write_fn(TCSR_TINT|TCSR_ENT|TCSR_ARHT, timer_baseaddr + TCSR1);
 248 
 249         /* register timecounter - for ftrace support */
 250         return init_xilinx_timecounter();
 251 }
 252 
 253 static int __init xilinx_timer_init(struct device_node *timer)
 254 {
 255         struct clk *clk;
 256         static int initialized;
 257         u32 irq;
 258         u32 timer_num = 1;
 259         int ret;
 260 
 261         if (initialized)
 262                 return -EINVAL;
 263 
 264         initialized = 1;
 265 
 266         timer_baseaddr = of_iomap(timer, 0);
 267         if (!timer_baseaddr) {
 268                 pr_err("ERROR: invalid timer base address\n");
 269                 return -ENXIO;
 270         }
 271 
 272         write_fn = timer_write32;
 273         read_fn = timer_read32;
 274 
 275         write_fn(TCSR_MDT, timer_baseaddr + TCSR0);
 276         if (!(read_fn(timer_baseaddr + TCSR0) & TCSR_MDT)) {
 277                 write_fn = timer_write32_be;
 278                 read_fn = timer_read32_be;
 279         }
 280 
 281         irq = irq_of_parse_and_map(timer, 0);
 282         if (irq <= 0) {
 283                 pr_err("Failed to parse and map irq");
 284                 return -EINVAL;
 285         }
 286 
 287         of_property_read_u32(timer, "xlnx,one-timer-only", &timer_num);
 288         if (timer_num) {
 289                 pr_err("Please enable two timers in HW\n");
 290                 return -EINVAL;
 291         }
 292 
 293         pr_info("%pOF: irq=%d\n", timer, irq);
 294 
 295         clk = of_clk_get(timer, 0);
 296         if (IS_ERR(clk)) {
 297                 pr_err("ERROR: timer CCF input clock not found\n");
 298                 /* If there is clock-frequency property than use it */
 299                 of_property_read_u32(timer, "clock-frequency",
 300                                     &timer_clock_freq);
 301         } else {
 302                 timer_clock_freq = clk_get_rate(clk);
 303         }
 304 
 305         if (!timer_clock_freq) {
 306                 pr_err("ERROR: Using CPU clock frequency\n");
 307                 timer_clock_freq = cpuinfo.cpu_clock_freq;
 308         }
 309 
 310         freq_div_hz = timer_clock_freq / HZ;
 311 
 312         ret = setup_irq(irq, &timer_irqaction);
 313         if (ret) {
 314                 pr_err("Failed to setup IRQ");
 315                 return ret;
 316         }
 317 
 318         ret = xilinx_clocksource_init();
 319         if (ret)
 320                 return ret;
 321 
 322         ret = xilinx_clockevent_init();
 323         if (ret)
 324                 return ret;
 325 
 326         sched_clock_register(xilinx_clock_read, 32, timer_clock_freq);
 327 
 328         return 0;
 329 }
 330 
 331 TIMER_OF_DECLARE(xilinx_timer, "xlnx,xps-timer-1.00.a",
 332                        xilinx_timer_init);

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