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