1 /* 2 * Copyright (C) 2015 ARM Limited 3 * 4 * Author: Vladimir Murzin <vladimir.murzin@arm.com> 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License version 2 as 8 * published by the Free Software Foundation. 9 * 10 */ 11 12 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 13 14 #include <linux/clk.h> 15 #include <linux/clockchips.h> 16 #include <linux/clocksource.h> 17 #include <linux/err.h> 18 #include <linux/interrupt.h> 19 #include <linux/io.h> 20 #include <linux/irq.h> 21 #include <linux/of_address.h> 22 #include <linux/of.h> 23 #include <linux/of_irq.h> 24 #include <linux/sched_clock.h> 25 #include <linux/slab.h> 26 27 #define TIMER_CTRL 0x0 28 #define TIMER_CTRL_ENABLE BIT(0) 29 #define TIMER_CTRL_IE BIT(3) 30 31 #define TIMER_VALUE 0x4 32 #define TIMER_RELOAD 0x8 33 #define TIMER_INT 0xc 34 35 struct clockevent_mps2 { 36 void __iomem *reg; 37 u32 clock_count_per_tick; 38 struct clock_event_device clkevt; 39 }; 40 41 static void __iomem *sched_clock_base; 42 43 static u64 notrace mps2_sched_read(void) 44 { 45 return ~readl_relaxed(sched_clock_base + TIMER_VALUE); 46 } 47 48 static inline struct clockevent_mps2 *to_mps2_clkevt(struct clock_event_device *c) 49 { 50 return container_of(c, struct clockevent_mps2, clkevt); 51 } 52 53 static void clockevent_mps2_writel(u32 val, struct clock_event_device *c, u32 offset) 54 { 55 writel_relaxed(val, to_mps2_clkevt(c)->reg + offset); 56 } 57 58 static int mps2_timer_shutdown(struct clock_event_device *ce) 59 { 60 clockevent_mps2_writel(0, ce, TIMER_RELOAD); 61 clockevent_mps2_writel(0, ce, TIMER_CTRL); 62 63 return 0; 64 } 65 66 static int mps2_timer_set_next_event(unsigned long next, struct clock_event_device *ce) 67 { 68 clockevent_mps2_writel(next, ce, TIMER_VALUE); 69 clockevent_mps2_writel(TIMER_CTRL_IE | TIMER_CTRL_ENABLE, ce, TIMER_CTRL); 70 71 return 0; 72 } 73 74 static int mps2_timer_set_periodic(struct clock_event_device *ce) 75 { 76 u32 clock_count_per_tick = to_mps2_clkevt(ce)->clock_count_per_tick; 77 78 clockevent_mps2_writel(clock_count_per_tick, ce, TIMER_RELOAD); 79 clockevent_mps2_writel(clock_count_per_tick, ce, TIMER_VALUE); 80 clockevent_mps2_writel(TIMER_CTRL_IE | TIMER_CTRL_ENABLE, ce, TIMER_CTRL); 81 82 return 0; 83 } 84 85 static irqreturn_t mps2_timer_interrupt(int irq, void *dev_id) 86 { 87 struct clockevent_mps2 *ce = dev_id; 88 u32 status = readl_relaxed(ce->reg + TIMER_INT); 89 90 if (!status) { 91 pr_warn("spurious interrupt\n"); 92 return IRQ_NONE; 93 } 94 95 writel_relaxed(1, ce->reg + TIMER_INT); 96 97 ce->clkevt.event_handler(&ce->clkevt); 98 99 return IRQ_HANDLED; 100 } 101 102 static int __init mps2_clockevent_init(struct device_node *np) 103 { 104 void __iomem *base; 105 struct clk *clk = NULL; 106 struct clockevent_mps2 *ce; 107 u32 rate; 108 int irq, ret; 109 const char *name = "mps2-clkevt"; 110 111 ret = of_property_read_u32(np, "clock-frequency", &rate); 112 if (ret) { 113 clk = of_clk_get(np, 0); 114 if (IS_ERR(clk)) { 115 ret = PTR_ERR(clk); 116 pr_err("failed to get clock for clockevent: %d\n", ret); 117 goto out; 118 } 119 120 ret = clk_prepare_enable(clk); 121 if (ret) { 122 pr_err("failed to enable clock for clockevent: %d\n", ret); 123 goto out_clk_put; 124 } 125 126 rate = clk_get_rate(clk); 127 } 128 129 base = of_iomap(np, 0); 130 if (!base) { 131 ret = -EADDRNOTAVAIL; 132 pr_err("failed to map register for clockevent: %d\n", ret); 133 goto out_clk_disable; 134 } 135 136 irq = irq_of_parse_and_map(np, 0); 137 if (!irq) { 138 ret = -ENOENT; 139 pr_err("failed to get irq for clockevent: %d\n", ret); 140 goto out_iounmap; 141 } 142 143 ce = kzalloc(sizeof(*ce), GFP_KERNEL); 144 if (!ce) { 145 ret = -ENOMEM; 146 goto out_iounmap; 147 } 148 149 ce->reg = base; 150 ce->clock_count_per_tick = DIV_ROUND_CLOSEST(rate, HZ); 151 ce->clkevt.irq = irq; 152 ce->clkevt.name = name; 153 ce->clkevt.rating = 200; 154 ce->clkevt.features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT; 155 ce->clkevt.cpumask = cpu_possible_mask; 156 ce->clkevt.set_state_shutdown = mps2_timer_shutdown, 157 ce->clkevt.set_state_periodic = mps2_timer_set_periodic, 158 ce->clkevt.set_state_oneshot = mps2_timer_shutdown, 159 ce->clkevt.set_next_event = mps2_timer_set_next_event; 160 161 /* Ensure timer is disabled */ 162 writel_relaxed(0, base + TIMER_CTRL); 163 164 ret = request_irq(irq, mps2_timer_interrupt, IRQF_TIMER, name, ce); 165 if (ret) { 166 pr_err("failed to request irq for clockevent: %d\n", ret); 167 goto out_kfree; 168 } 169 170 clockevents_config_and_register(&ce->clkevt, rate, 0xf, 0xffffffff); 171 172 return 0; 173 174 out_kfree: 175 kfree(ce); 176 out_iounmap: 177 iounmap(base); 178 out_clk_disable: 179 /* clk_{disable, unprepare, put}() can handle NULL as a parameter */ 180 clk_disable_unprepare(clk); 181 out_clk_put: 182 clk_put(clk); 183 out: 184 return ret; 185 } 186 187 static int __init mps2_clocksource_init(struct device_node *np) 188 { 189 void __iomem *base; 190 struct clk *clk = NULL; 191 u32 rate; 192 int ret; 193 const char *name = "mps2-clksrc"; 194 195 ret = of_property_read_u32(np, "clock-frequency", &rate); 196 if (ret) { 197 clk = of_clk_get(np, 0); 198 if (IS_ERR(clk)) { 199 ret = PTR_ERR(clk); 200 pr_err("failed to get clock for clocksource: %d\n", ret); 201 goto out; 202 } 203 204 ret = clk_prepare_enable(clk); 205 if (ret) { 206 pr_err("failed to enable clock for clocksource: %d\n", ret); 207 goto out_clk_put; 208 } 209 210 rate = clk_get_rate(clk); 211 } 212 213 base = of_iomap(np, 0); 214 if (!base) { 215 ret = -EADDRNOTAVAIL; 216 pr_err("failed to map register for clocksource: %d\n", ret); 217 goto out_clk_disable; 218 } 219 220 /* Ensure timer is disabled */ 221 writel_relaxed(0, base + TIMER_CTRL); 222 223 /* ... and set it up as free-running clocksource */ 224 writel_relaxed(0xffffffff, base + TIMER_VALUE); 225 writel_relaxed(0xffffffff, base + TIMER_RELOAD); 226 227 writel_relaxed(TIMER_CTRL_ENABLE, base + TIMER_CTRL); 228 229 ret = clocksource_mmio_init(base + TIMER_VALUE, name, 230 rate, 200, 32, 231 clocksource_mmio_readl_down); 232 if (ret) { 233 pr_err("failed to init clocksource: %d\n", ret); 234 goto out_iounmap; 235 } 236 237 sched_clock_base = base; 238 sched_clock_register(mps2_sched_read, 32, rate); 239 240 return 0; 241 242 out_iounmap: 243 iounmap(base); 244 out_clk_disable: 245 /* clk_{disable, unprepare, put}() can handle NULL as a parameter */ 246 clk_disable_unprepare(clk); 247 out_clk_put: 248 clk_put(clk); 249 out: 250 return ret; 251 } 252 253 static void __init mps2_timer_init(struct device_node *np) 254 { 255 static int has_clocksource, has_clockevent; 256 int ret; 257 258 if (!has_clocksource) { 259 ret = mps2_clocksource_init(np); 260 if (!ret) { 261 has_clocksource = 1; 262 return; 263 } 264 } 265 266 if (!has_clockevent) { 267 ret = mps2_clockevent_init(np); 268 if (!ret) { 269 has_clockevent = 1; 270 return; 271 } 272 } 273 } 274 275 CLOCKSOURCE_OF_DECLARE(mps2_timer, "arm,mps2-timer", mps2_timer_init); 276