1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * linux/drivers/clocksource/timer-sp.c 4 * 5 * Copyright (C) 1999 - 2003 ARM Limited 6 * Copyright (C) 2000 Deep Blue Solutions Ltd 7 */ 8 #include <linux/clk.h> 9 #include <linux/clocksource.h> 10 #include <linux/clockchips.h> 11 #include <linux/err.h> 12 #include <linux/interrupt.h> 13 #include <linux/irq.h> 14 #include <linux/io.h> 15 #include <linux/of.h> 16 #include <linux/of_address.h> 17 #include <linux/of_clk.h> 18 #include <linux/of_irq.h> 19 #include <linux/sched_clock.h> 20 21 #include "timer-sp.h" 22 23 static long __init sp804_get_clock_rate(struct clk *clk, const char *name) 24 { 25 long rate; 26 int err; 27 28 if (!clk) 29 clk = clk_get_sys("sp804", name); 30 if (IS_ERR(clk)) { 31 pr_err("sp804: %s clock not found: %ld\n", name, PTR_ERR(clk)); 32 return PTR_ERR(clk); 33 } 34 35 err = clk_prepare(clk); 36 if (err) { 37 pr_err("sp804: clock failed to prepare: %d\n", err); 38 clk_put(clk); 39 return err; 40 } 41 42 err = clk_enable(clk); 43 if (err) { 44 pr_err("sp804: clock failed to enable: %d\n", err); 45 clk_unprepare(clk); 46 clk_put(clk); 47 return err; 48 } 49 50 rate = clk_get_rate(clk); 51 if (rate < 0) { 52 pr_err("sp804: clock failed to get rate: %ld\n", rate); 53 clk_disable(clk); 54 clk_unprepare(clk); 55 clk_put(clk); 56 } 57 58 return rate; 59 } 60 61 static void __iomem *sched_clock_base; 62 63 static u64 notrace sp804_read(void) 64 { 65 return ~readl_relaxed(sched_clock_base + TIMER_VALUE); 66 } 67 68 int __init sp804_clocksource_and_sched_clock_init(void __iomem *base, 69 const char *name, 70 struct clk *clk, 71 int use_sched_clock) 72 { 73 long rate; 74 75 rate = sp804_get_clock_rate(clk, name); 76 if (rate < 0) 77 return -EINVAL; 78 79 writel(0, base + TIMER_CTRL); 80 writel(0xffffffff, base + TIMER_LOAD); 81 writel(0xffffffff, base + TIMER_VALUE); 82 writel(TIMER_CTRL_32BIT | TIMER_CTRL_ENABLE | TIMER_CTRL_PERIODIC, 83 base + TIMER_CTRL); 84 85 clocksource_mmio_init(base + TIMER_VALUE, name, 86 rate, 200, 32, clocksource_mmio_readl_down); 87 88 if (use_sched_clock) { 89 sched_clock_base = base; 90 sched_clock_register(sp804_read, 32, rate); 91 } 92 93 return 0; 94 } 95 96 97 static void __iomem *clkevt_base; 98 static unsigned long clkevt_reload; 99 100 /* 101 * IRQ handler for the timer 102 */ 103 static irqreturn_t sp804_timer_interrupt(int irq, void *dev_id) 104 { 105 struct clock_event_device *evt = dev_id; 106 107 /* clear the interrupt */ 108 writel(1, clkevt_base + TIMER_INTCLR); 109 110 evt->event_handler(evt); 111 112 return IRQ_HANDLED; 113 } 114 115 static inline void timer_shutdown(struct clock_event_device *evt) 116 { 117 writel(0, clkevt_base + TIMER_CTRL); 118 } 119 120 static int sp804_shutdown(struct clock_event_device *evt) 121 { 122 timer_shutdown(evt); 123 return 0; 124 } 125 126 static int sp804_set_periodic(struct clock_event_device *evt) 127 { 128 unsigned long ctrl = TIMER_CTRL_32BIT | TIMER_CTRL_IE | 129 TIMER_CTRL_PERIODIC | TIMER_CTRL_ENABLE; 130 131 timer_shutdown(evt); 132 writel(clkevt_reload, clkevt_base + TIMER_LOAD); 133 writel(ctrl, clkevt_base + TIMER_CTRL); 134 return 0; 135 } 136 137 static int sp804_set_next_event(unsigned long next, 138 struct clock_event_device *evt) 139 { 140 unsigned long ctrl = TIMER_CTRL_32BIT | TIMER_CTRL_IE | 141 TIMER_CTRL_ONESHOT | TIMER_CTRL_ENABLE; 142 143 writel(next, clkevt_base + TIMER_LOAD); 144 writel(ctrl, clkevt_base + TIMER_CTRL); 145 146 return 0; 147 } 148 149 static struct clock_event_device sp804_clockevent = { 150 .features = CLOCK_EVT_FEAT_PERIODIC | 151 CLOCK_EVT_FEAT_ONESHOT | 152 CLOCK_EVT_FEAT_DYNIRQ, 153 .set_state_shutdown = sp804_shutdown, 154 .set_state_periodic = sp804_set_periodic, 155 .set_state_oneshot = sp804_shutdown, 156 .tick_resume = sp804_shutdown, 157 .set_next_event = sp804_set_next_event, 158 .rating = 300, 159 }; 160 161 int __init sp804_clockevents_init(void __iomem *base, unsigned int irq, 162 struct clk *clk, const char *name) 163 { 164 struct clock_event_device *evt = &sp804_clockevent; 165 long rate; 166 167 rate = sp804_get_clock_rate(clk, name); 168 if (rate < 0) 169 return -EINVAL; 170 171 clkevt_base = base; 172 clkevt_reload = DIV_ROUND_CLOSEST(rate, HZ); 173 evt->name = name; 174 evt->irq = irq; 175 evt->cpumask = cpu_possible_mask; 176 177 writel(0, base + TIMER_CTRL); 178 179 if (request_irq(irq, sp804_timer_interrupt, IRQF_TIMER | IRQF_IRQPOLL, 180 "timer", &sp804_clockevent)) 181 pr_err("%s: request_irq() failed\n", "timer"); 182 clockevents_config_and_register(evt, rate, 0xf, 0xffffffff); 183 184 return 0; 185 } 186 187 static int __init sp804_of_init(struct device_node *np) 188 { 189 static bool initialized = false; 190 void __iomem *base; 191 void __iomem *timer1_base; 192 void __iomem *timer2_base; 193 int irq, ret = -EINVAL; 194 u32 irq_num = 0; 195 struct clk *clk1, *clk2; 196 const char *name = of_get_property(np, "compatible", NULL); 197 198 base = of_iomap(np, 0); 199 if (!base) 200 return -ENXIO; 201 202 timer1_base = base; 203 timer2_base = base + TIMER_2_BASE; 204 205 /* Ensure timers are disabled */ 206 writel(0, timer1_base + TIMER_CTRL); 207 writel(0, timer2_base + TIMER_CTRL); 208 209 if (initialized || !of_device_is_available(np)) { 210 ret = -EINVAL; 211 goto err; 212 } 213 214 clk1 = of_clk_get(np, 0); 215 if (IS_ERR(clk1)) 216 clk1 = NULL; 217 218 /* Get the 2nd clock if the timer has 3 timer clocks */ 219 if (of_clk_get_parent_count(np) == 3) { 220 clk2 = of_clk_get(np, 1); 221 if (IS_ERR(clk2)) { 222 pr_err("sp804: %pOFn clock not found: %d\n", np, 223 (int)PTR_ERR(clk2)); 224 clk2 = NULL; 225 } 226 } else 227 clk2 = clk1; 228 229 irq = irq_of_parse_and_map(np, 0); 230 if (irq <= 0) 231 goto err; 232 233 of_property_read_u32(np, "arm,sp804-has-irq", &irq_num); 234 if (irq_num == 2) { 235 236 ret = sp804_clockevents_init(timer2_base, irq, clk2, name); 237 if (ret) 238 goto err; 239 240 ret = sp804_clocksource_and_sched_clock_init(timer1_base, 241 name, clk1, 1); 242 if (ret) 243 goto err; 244 } else { 245 246 ret = sp804_clockevents_init(timer1_base, irq, clk1, name); 247 if (ret) 248 goto err; 249 250 ret = sp804_clocksource_and_sched_clock_init(timer2_base, 251 name, clk2, 1); 252 if (ret) 253 goto err; 254 } 255 initialized = true; 256 257 return 0; 258 err: 259 iounmap(base); 260 return ret; 261 } 262 TIMER_OF_DECLARE(sp804, "arm,sp804", sp804_of_init); 263 264 static int __init integrator_cp_of_init(struct device_node *np) 265 { 266 static int init_count = 0; 267 void __iomem *base; 268 int irq, ret = -EINVAL; 269 const char *name = of_get_property(np, "compatible", NULL); 270 struct clk *clk; 271 272 base = of_iomap(np, 0); 273 if (!base) { 274 pr_err("Failed to iomap\n"); 275 return -ENXIO; 276 } 277 278 clk = of_clk_get(np, 0); 279 if (IS_ERR(clk)) { 280 pr_err("Failed to get clock\n"); 281 return PTR_ERR(clk); 282 } 283 284 /* Ensure timer is disabled */ 285 writel(0, base + TIMER_CTRL); 286 287 if (init_count == 2 || !of_device_is_available(np)) 288 goto err; 289 290 if (!init_count) { 291 ret = sp804_clocksource_and_sched_clock_init(base, 292 name, clk, 0); 293 if (ret) 294 goto err; 295 } else { 296 irq = irq_of_parse_and_map(np, 0); 297 if (irq <= 0) 298 goto err; 299 300 ret = sp804_clockevents_init(base, irq, clk, name); 301 if (ret) 302 goto err; 303 } 304 305 init_count++; 306 return 0; 307 err: 308 iounmap(base); 309 return ret; 310 } 311 TIMER_OF_DECLARE(intcp, "arm,integrator-cp-timer", integrator_cp_of_init); 312