| Chris Metcalf | 867e359 | 2010-05-28 23:09:12 -0400 | [diff] [blame] | 1 | /* | 
|  | 2 | * Copyright 2010 Tilera Corporation. All Rights Reserved. | 
|  | 3 | * | 
|  | 4 | *   This program is free software; you can redistribute it and/or | 
|  | 5 | *   modify it under the terms of the GNU General Public License | 
|  | 6 | *   as published by the Free Software Foundation, version 2. | 
|  | 7 | * | 
|  | 8 | *   This program is distributed in the hope that it will be useful, but | 
|  | 9 | *   WITHOUT ANY WARRANTY; without even the implied warranty of | 
|  | 10 | *   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or | 
|  | 11 | *   NON INFRINGEMENT.  See the GNU General Public License for | 
|  | 12 | *   more details. | 
|  | 13 | * | 
|  | 14 | * Support the cycle counter clocksource and tile timer clock event device. | 
|  | 15 | */ | 
|  | 16 |  | 
|  | 17 | #include <linux/time.h> | 
|  | 18 | #include <linux/timex.h> | 
|  | 19 | #include <linux/clocksource.h> | 
|  | 20 | #include <linux/clockchips.h> | 
|  | 21 | #include <linux/hardirq.h> | 
|  | 22 | #include <linux/sched.h> | 
|  | 23 | #include <linux/smp.h> | 
|  | 24 | #include <linux/delay.h> | 
| Chris Metcalf | 28d7174 | 2011-05-02 16:06:42 -0400 | [diff] [blame] | 25 | #include <linux/module.h> | 
| Chris Metcalf | 867e359 | 2010-05-28 23:09:12 -0400 | [diff] [blame] | 26 | #include <asm/irq_regs.h> | 
| Chris Metcalf | 0707ad3 | 2010-06-25 17:04:17 -0400 | [diff] [blame] | 27 | #include <asm/traps.h> | 
| Chris Metcalf | 867e359 | 2010-05-28 23:09:12 -0400 | [diff] [blame] | 28 | #include <hv/hypervisor.h> | 
|  | 29 | #include <arch/interrupts.h> | 
|  | 30 | #include <arch/spr_def.h> | 
|  | 31 |  | 
|  | 32 |  | 
|  | 33 | /* | 
|  | 34 | * Define the cycle counter clock source. | 
|  | 35 | */ | 
|  | 36 |  | 
|  | 37 | /* How many cycles per second we are running at. */ | 
|  | 38 | static cycles_t cycles_per_sec __write_once; | 
|  | 39 |  | 
| Chris Metcalf | 0707ad3 | 2010-06-25 17:04:17 -0400 | [diff] [blame] | 40 | cycles_t get_clock_rate(void) | 
| Chris Metcalf | 867e359 | 2010-05-28 23:09:12 -0400 | [diff] [blame] | 41 | { | 
|  | 42 | return cycles_per_sec; | 
|  | 43 | } | 
|  | 44 |  | 
|  | 45 | #if CHIP_HAS_SPLIT_CYCLE() | 
| Chris Metcalf | 0707ad3 | 2010-06-25 17:04:17 -0400 | [diff] [blame] | 46 | cycles_t get_cycles(void) | 
| Chris Metcalf | 867e359 | 2010-05-28 23:09:12 -0400 | [diff] [blame] | 47 | { | 
|  | 48 | unsigned int high = __insn_mfspr(SPR_CYCLE_HIGH); | 
|  | 49 | unsigned int low = __insn_mfspr(SPR_CYCLE_LOW); | 
|  | 50 | unsigned int high2 = __insn_mfspr(SPR_CYCLE_HIGH); | 
|  | 51 |  | 
|  | 52 | while (unlikely(high != high2)) { | 
|  | 53 | low = __insn_mfspr(SPR_CYCLE_LOW); | 
|  | 54 | high = high2; | 
|  | 55 | high2 = __insn_mfspr(SPR_CYCLE_HIGH); | 
|  | 56 | } | 
|  | 57 |  | 
|  | 58 | return (((cycles_t)high) << 32) | low; | 
|  | 59 | } | 
| Chris Metcalf | 28d7174 | 2011-05-02 16:06:42 -0400 | [diff] [blame] | 60 | EXPORT_SYMBOL(get_cycles); | 
| Chris Metcalf | 867e359 | 2010-05-28 23:09:12 -0400 | [diff] [blame] | 61 | #endif | 
|  | 62 |  | 
| Chris Metcalf | 749dc6f | 2010-08-13 08:24:22 -0400 | [diff] [blame] | 63 | /* | 
|  | 64 | * We use a relatively small shift value so that sched_clock() | 
|  | 65 | * won't wrap around very often. | 
|  | 66 | */ | 
|  | 67 | #define SCHED_CLOCK_SHIFT 10 | 
|  | 68 |  | 
|  | 69 | static unsigned long sched_clock_mult __write_once; | 
|  | 70 |  | 
| Chris Metcalf | 0707ad3 | 2010-06-25 17:04:17 -0400 | [diff] [blame] | 71 | static cycles_t clocksource_get_cycles(struct clocksource *cs) | 
| Chris Metcalf | 867e359 | 2010-05-28 23:09:12 -0400 | [diff] [blame] | 72 | { | 
|  | 73 | return get_cycles(); | 
|  | 74 | } | 
|  | 75 |  | 
|  | 76 | static struct clocksource cycle_counter_cs = { | 
|  | 77 | .name = "cycle counter", | 
|  | 78 | .rating = 300, | 
|  | 79 | .read = clocksource_get_cycles, | 
|  | 80 | .mask = CLOCKSOURCE_MASK(64), | 
|  | 81 | .flags = CLOCK_SOURCE_IS_CONTINUOUS, | 
|  | 82 | }; | 
|  | 83 |  | 
|  | 84 | /* | 
|  | 85 | * Called very early from setup_arch() to set cycles_per_sec. | 
|  | 86 | * We initialize it early so we can use it to set up loops_per_jiffy. | 
|  | 87 | */ | 
|  | 88 | void __init setup_clock(void) | 
|  | 89 | { | 
|  | 90 | cycles_per_sec = hv_sysconf(HV_SYSCONF_CPU_SPEED); | 
| Chris Metcalf | 749dc6f | 2010-08-13 08:24:22 -0400 | [diff] [blame] | 91 | sched_clock_mult = | 
|  | 92 | clocksource_hz2mult(cycles_per_sec, SCHED_CLOCK_SHIFT); | 
| Chris Metcalf | 867e359 | 2010-05-28 23:09:12 -0400 | [diff] [blame] | 93 | } | 
|  | 94 |  | 
|  | 95 | void __init calibrate_delay(void) | 
|  | 96 | { | 
|  | 97 | loops_per_jiffy = get_clock_rate() / HZ; | 
|  | 98 | pr_info("Clock rate yields %lu.%02lu BogoMIPS (lpj=%lu)\n", | 
|  | 99 | loops_per_jiffy/(500000/HZ), | 
|  | 100 | (loops_per_jiffy/(5000/HZ)) % 100, loops_per_jiffy); | 
|  | 101 | } | 
|  | 102 |  | 
|  | 103 | /* Called fairly late in init/main.c, but before we go smp. */ | 
|  | 104 | void __init time_init(void) | 
|  | 105 | { | 
|  | 106 | /* Initialize and register the clock source. */ | 
| John Stultz | 9f14517 | 2011-06-01 00:32:50 -0700 | [diff] [blame] | 107 | clocksource_register_hz(&cycle_counter_cs, cycles_per_sec); | 
| Chris Metcalf | 867e359 | 2010-05-28 23:09:12 -0400 | [diff] [blame] | 108 |  | 
|  | 109 | /* Start up the tile-timer interrupt source on the boot cpu. */ | 
|  | 110 | setup_tile_timer(); | 
|  | 111 | } | 
|  | 112 |  | 
|  | 113 |  | 
|  | 114 | /* | 
|  | 115 | * Define the tile timer clock event device.  The timer is driven by | 
|  | 116 | * the TILE_TIMER_CONTROL register, which consists of a 31-bit down | 
|  | 117 | * counter, plus bit 31, which signifies that the counter has wrapped | 
|  | 118 | * from zero to (2**31) - 1.  The INT_TILE_TIMER interrupt will be | 
|  | 119 | * raised as long as bit 31 is set. | 
| Chris Metcalf | 749dc6f | 2010-08-13 08:24:22 -0400 | [diff] [blame] | 120 | * | 
|  | 121 | * The TILE_MINSEC value represents the largest range of real-time | 
|  | 122 | * we can possibly cover with the timer, based on MAX_TICK combined | 
|  | 123 | * with the slowest reasonable clock rate we might run at. | 
| Chris Metcalf | 867e359 | 2010-05-28 23:09:12 -0400 | [diff] [blame] | 124 | */ | 
|  | 125 |  | 
|  | 126 | #define MAX_TICK 0x7fffffff   /* we have 31 bits of countdown timer */ | 
| Chris Metcalf | 749dc6f | 2010-08-13 08:24:22 -0400 | [diff] [blame] | 127 | #define TILE_MINSEC 5         /* timer covers no more than 5 seconds */ | 
| Chris Metcalf | 867e359 | 2010-05-28 23:09:12 -0400 | [diff] [blame] | 128 |  | 
|  | 129 | static int tile_timer_set_next_event(unsigned long ticks, | 
|  | 130 | struct clock_event_device *evt) | 
|  | 131 | { | 
|  | 132 | BUG_ON(ticks > MAX_TICK); | 
|  | 133 | __insn_mtspr(SPR_TILE_TIMER_CONTROL, ticks); | 
| Chris Metcalf | 5d96611 | 2010-11-01 15:24:29 -0400 | [diff] [blame] | 134 | arch_local_irq_unmask_now(INT_TILE_TIMER); | 
| Chris Metcalf | 867e359 | 2010-05-28 23:09:12 -0400 | [diff] [blame] | 135 | return 0; | 
|  | 136 | } | 
|  | 137 |  | 
|  | 138 | /* | 
|  | 139 | * Whenever anyone tries to change modes, we just mask interrupts | 
|  | 140 | * and wait for the next event to get set. | 
|  | 141 | */ | 
|  | 142 | static void tile_timer_set_mode(enum clock_event_mode mode, | 
|  | 143 | struct clock_event_device *evt) | 
|  | 144 | { | 
| Chris Metcalf | 5d96611 | 2010-11-01 15:24:29 -0400 | [diff] [blame] | 145 | arch_local_irq_mask_now(INT_TILE_TIMER); | 
| Chris Metcalf | 867e359 | 2010-05-28 23:09:12 -0400 | [diff] [blame] | 146 | } | 
|  | 147 |  | 
|  | 148 | /* | 
|  | 149 | * Set min_delta_ns to 1 microsecond, since it takes about | 
|  | 150 | * that long to fire the interrupt. | 
|  | 151 | */ | 
|  | 152 | static DEFINE_PER_CPU(struct clock_event_device, tile_timer) = { | 
|  | 153 | .name = "tile timer", | 
|  | 154 | .features = CLOCK_EVT_FEAT_ONESHOT, | 
|  | 155 | .min_delta_ns = 1000, | 
|  | 156 | .rating = 100, | 
|  | 157 | .irq = -1, | 
|  | 158 | .set_next_event = tile_timer_set_next_event, | 
|  | 159 | .set_mode = tile_timer_set_mode, | 
|  | 160 | }; | 
|  | 161 |  | 
|  | 162 | void __cpuinit setup_tile_timer(void) | 
|  | 163 | { | 
|  | 164 | struct clock_event_device *evt = &__get_cpu_var(tile_timer); | 
|  | 165 |  | 
|  | 166 | /* Fill in fields that are speed-specific. */ | 
|  | 167 | clockevents_calc_mult_shift(evt, cycles_per_sec, TILE_MINSEC); | 
|  | 168 | evt->max_delta_ns = clockevent_delta2ns(MAX_TICK, evt); | 
|  | 169 |  | 
|  | 170 | /* Mark as being for this cpu only. */ | 
|  | 171 | evt->cpumask = cpumask_of(smp_processor_id()); | 
|  | 172 |  | 
|  | 173 | /* Start out with timer not firing. */ | 
| Chris Metcalf | 5d96611 | 2010-11-01 15:24:29 -0400 | [diff] [blame] | 174 | arch_local_irq_mask_now(INT_TILE_TIMER); | 
| Chris Metcalf | 867e359 | 2010-05-28 23:09:12 -0400 | [diff] [blame] | 175 |  | 
|  | 176 | /* Register tile timer. */ | 
|  | 177 | clockevents_register_device(evt); | 
|  | 178 | } | 
|  | 179 |  | 
|  | 180 | /* Called from the interrupt vector. */ | 
|  | 181 | void do_timer_interrupt(struct pt_regs *regs, int fault_num) | 
|  | 182 | { | 
|  | 183 | struct pt_regs *old_regs = set_irq_regs(regs); | 
|  | 184 | struct clock_event_device *evt = &__get_cpu_var(tile_timer); | 
|  | 185 |  | 
|  | 186 | /* | 
|  | 187 | * Mask the timer interrupt here, since we are a oneshot timer | 
|  | 188 | * and there are now by definition no events pending. | 
|  | 189 | */ | 
| Chris Metcalf | 5d96611 | 2010-11-01 15:24:29 -0400 | [diff] [blame] | 190 | arch_local_irq_mask(INT_TILE_TIMER); | 
| Chris Metcalf | 867e359 | 2010-05-28 23:09:12 -0400 | [diff] [blame] | 191 |  | 
|  | 192 | /* Track time spent here in an interrupt context */ | 
|  | 193 | irq_enter(); | 
|  | 194 |  | 
|  | 195 | /* Track interrupt count. */ | 
|  | 196 | __get_cpu_var(irq_stat).irq_timer_count++; | 
|  | 197 |  | 
|  | 198 | /* Call the generic timer handler */ | 
|  | 199 | evt->event_handler(evt); | 
|  | 200 |  | 
|  | 201 | /* | 
|  | 202 | * Track time spent against the current process again and | 
|  | 203 | * process any softirqs if they are waiting. | 
|  | 204 | */ | 
|  | 205 | irq_exit(); | 
|  | 206 |  | 
|  | 207 | set_irq_regs(old_regs); | 
|  | 208 | } | 
|  | 209 |  | 
|  | 210 | /* | 
|  | 211 | * Scheduler clock - returns current time in nanosec units. | 
|  | 212 | * Note that with LOCKDEP, this is called during lockdep_init(), and | 
|  | 213 | * we will claim that sched_clock() is zero for a little while, until | 
|  | 214 | * we run setup_clock(), above. | 
|  | 215 | */ | 
|  | 216 | unsigned long long sched_clock(void) | 
|  | 217 | { | 
|  | 218 | return clocksource_cyc2ns(get_cycles(), | 
| Chris Metcalf | 749dc6f | 2010-08-13 08:24:22 -0400 | [diff] [blame] | 219 | sched_clock_mult, SCHED_CLOCK_SHIFT); | 
| Chris Metcalf | 867e359 | 2010-05-28 23:09:12 -0400 | [diff] [blame] | 220 | } | 
|  | 221 |  | 
|  | 222 | int setup_profiling_timer(unsigned int multiplier) | 
|  | 223 | { | 
|  | 224 | return -EINVAL; | 
|  | 225 | } | 
| Chris Metcalf | 1337173 | 2011-02-28 13:21:52 -0500 | [diff] [blame] | 226 |  | 
|  | 227 | /* | 
|  | 228 | * Use the tile timer to convert nsecs to core clock cycles, relying | 
|  | 229 | * on it having the same frequency as SPR_CYCLE. | 
|  | 230 | */ | 
|  | 231 | cycles_t ns2cycles(unsigned long nsecs) | 
|  | 232 | { | 
|  | 233 | struct clock_event_device *dev = &__get_cpu_var(tile_timer); | 
|  | 234 | return ((u64)nsecs * dev->mult) >> dev->shift; | 
|  | 235 | } |