1 /* 2 * This file is subject to the terms and conditions of the GNU General Public 3 * License. See the file "COPYING" in the main directory of this archive 4 * for more details. 5 * 6 * Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved. 7 */ 8 9 #define pr_fmt(fmt) "mips-gic-timer: " fmt 10 11 #include <linux/clk.h> 12 #include <linux/clockchips.h> 13 #include <linux/cpu.h> 14 #include <linux/init.h> 15 #include <linux/interrupt.h> 16 #include <linux/notifier.h> 17 #include <linux/of_irq.h> 18 #include <linux/percpu.h> 19 #include <linux/smp.h> 20 #include <linux/time.h> 21 #include <asm/mips-cps.h> 22 23 static DEFINE_PER_CPU(struct clock_event_device, gic_clockevent_device); 24 static int gic_timer_irq; 25 static unsigned int gic_frequency; 26 27 static u64 notrace gic_read_count(void) 28 { 29 unsigned int hi, hi2, lo; 30 31 if (mips_cm_is64) 32 return read_gic_counter(); 33 34 do { 35 hi = read_gic_counter_32h(); 36 lo = read_gic_counter_32l(); 37 hi2 = read_gic_counter_32h(); 38 } while (hi2 != hi); 39 40 return (((u64) hi) << 32) + lo; 41 } 42 43 static int gic_next_event(unsigned long delta, struct clock_event_device *evt) 44 { 45 int cpu = cpumask_first(evt->cpumask); 46 u64 cnt; 47 int res; 48 49 cnt = gic_read_count(); 50 cnt += (u64)delta; 51 if (cpu == raw_smp_processor_id()) { 52 write_gic_vl_compare(cnt); 53 } else { 54 write_gic_vl_other(mips_cm_vp_id(cpu)); 55 write_gic_vo_compare(cnt); 56 } 57 res = ((int)(gic_read_count() - cnt) >= 0) ? -ETIME : 0; 58 return res; 59 } 60 61 static irqreturn_t gic_compare_interrupt(int irq, void *dev_id) 62 { 63 struct clock_event_device *cd = dev_id; 64 65 write_gic_vl_compare(read_gic_vl_compare()); 66 cd->event_handler(cd); 67 return IRQ_HANDLED; 68 } 69 70 struct irqaction gic_compare_irqaction = { 71 .handler = gic_compare_interrupt, 72 .percpu_dev_id = &gic_clockevent_device, 73 .flags = IRQF_PERCPU | IRQF_TIMER, 74 .name = "timer", 75 }; 76 77 static void gic_clockevent_cpu_init(unsigned int cpu, 78 struct clock_event_device *cd) 79 { 80 cd->name = "MIPS GIC"; 81 cd->features = CLOCK_EVT_FEAT_ONESHOT | 82 CLOCK_EVT_FEAT_C3STOP; 83 84 cd->rating = 350; 85 cd->irq = gic_timer_irq; 86 cd->cpumask = cpumask_of(cpu); 87 cd->set_next_event = gic_next_event; 88 89 clockevents_config_and_register(cd, gic_frequency, 0x300, 0x7fffffff); 90 91 enable_percpu_irq(gic_timer_irq, IRQ_TYPE_NONE); 92 } 93 94 static void gic_clockevent_cpu_exit(struct clock_event_device *cd) 95 { 96 disable_percpu_irq(gic_timer_irq); 97 } 98 99 static void gic_update_frequency(void *data) 100 { 101 unsigned long rate = (unsigned long)data; 102 103 clockevents_update_freq(this_cpu_ptr(&gic_clockevent_device), rate); 104 } 105 106 static int gic_starting_cpu(unsigned int cpu) 107 { 108 gic_clockevent_cpu_init(cpu, this_cpu_ptr(&gic_clockevent_device)); 109 return 0; 110 } 111 112 static int gic_clk_notifier(struct notifier_block *nb, unsigned long action, 113 void *data) 114 { 115 struct clk_notifier_data *cnd = data; 116 117 if (action == POST_RATE_CHANGE) 118 on_each_cpu(gic_update_frequency, (void *)cnd->new_rate, 1); 119 120 return NOTIFY_OK; 121 } 122 123 static int gic_dying_cpu(unsigned int cpu) 124 { 125 gic_clockevent_cpu_exit(this_cpu_ptr(&gic_clockevent_device)); 126 return 0; 127 } 128 129 static struct notifier_block gic_clk_nb = { 130 .notifier_call = gic_clk_notifier, 131 }; 132 133 static int gic_clockevent_init(void) 134 { 135 int ret; 136 137 if (!gic_frequency) 138 return -ENXIO; 139 140 ret = setup_percpu_irq(gic_timer_irq, &gic_compare_irqaction); 141 if (ret < 0) { 142 pr_err("IRQ %d setup failed (%d)\n", gic_timer_irq, ret); 143 return ret; 144 } 145 146 cpuhp_setup_state(CPUHP_AP_MIPS_GIC_TIMER_STARTING, 147 "clockevents/mips/gic/timer:starting", 148 gic_starting_cpu, gic_dying_cpu); 149 return 0; 150 } 151 152 static u64 gic_hpt_read(struct clocksource *cs) 153 { 154 return gic_read_count(); 155 } 156 157 static struct clocksource gic_clocksource = { 158 .name = "GIC", 159 .read = gic_hpt_read, 160 .flags = CLOCK_SOURCE_IS_CONTINUOUS, 161 .archdata = { .vdso_clock_mode = VDSO_CLOCK_GIC }, 162 }; 163 164 static int __init __gic_clocksource_init(void) 165 { 166 unsigned int count_width; 167 int ret; 168 169 /* Set clocksource mask. */ 170 count_width = read_gic_config() & GIC_CONFIG_COUNTBITS; 171 count_width >>= __ffs(GIC_CONFIG_COUNTBITS); 172 count_width *= 4; 173 count_width += 32; 174 gic_clocksource.mask = CLOCKSOURCE_MASK(count_width); 175 176 /* Calculate a somewhat reasonable rating value. */ 177 gic_clocksource.rating = 200 + gic_frequency / 10000000; 178 179 ret = clocksource_register_hz(&gic_clocksource, gic_frequency); 180 if (ret < 0) 181 pr_warn("Unable to register clocksource\n"); 182 183 return ret; 184 } 185 186 static int __init gic_clocksource_of_init(struct device_node *node) 187 { 188 struct clk *clk; 189 int ret; 190 191 if (!mips_gic_present() || !node->parent || 192 !of_device_is_compatible(node->parent, "mti,gic")) { 193 pr_warn("No DT definition\n"); 194 return -ENXIO; 195 } 196 197 clk = of_clk_get(node, 0); 198 if (!IS_ERR(clk)) { 199 ret = clk_prepare_enable(clk); 200 if (ret < 0) { 201 pr_err("Failed to enable clock\n"); 202 clk_put(clk); 203 return ret; 204 } 205 206 gic_frequency = clk_get_rate(clk); 207 } else if (of_property_read_u32(node, "clock-frequency", 208 &gic_frequency)) { 209 pr_err("Frequency not specified\n"); 210 return -EINVAL; 211 } 212 gic_timer_irq = irq_of_parse_and_map(node, 0); 213 if (!gic_timer_irq) { 214 pr_err("IRQ not specified\n"); 215 return -EINVAL; 216 } 217 218 ret = __gic_clocksource_init(); 219 if (ret) 220 return ret; 221 222 ret = gic_clockevent_init(); 223 if (!ret && !IS_ERR(clk)) { 224 if (clk_notifier_register(clk, &gic_clk_nb) < 0) 225 pr_warn("Unable to register clock notifier\n"); 226 } 227 228 /* And finally start the counter */ 229 clear_gic_config(GIC_CONFIG_COUNTSTOP); 230 231 return 0; 232 } 233 TIMER_OF_DECLARE(mips_gic_timer, "mti,gic-timer", 234 gic_clocksource_of_init); 235