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 static struct irqaction sp804_timer_irq = { 172 .name = "timer", 173 .flags = IRQF_TIMER | IRQF_IRQPOLL, 174 .handler = sp804_timer_interrupt, 175 .dev_id = &sp804_clockevent, 176 }; 177 178 int __init __sp804_clockevents_init(void __iomem *base, unsigned int irq, struct clk *clk, const char *name) 179 { 180 struct clock_event_device *evt = &sp804_clockevent; 181 long rate; 182 183 if (!clk) 184 clk = clk_get_sys("sp804", name); 185 if (IS_ERR(clk)) { 186 pr_err("sp804: %s clock not found: %d\n", name, 187 (int)PTR_ERR(clk)); 188 return PTR_ERR(clk); 189 } 190 191 rate = sp804_get_clock_rate(clk); 192 if (rate < 0) 193 return -EINVAL; 194 195 clkevt_base = base; 196 clkevt_reload = DIV_ROUND_CLOSEST(rate, HZ); 197 evt->name = name; 198 evt->irq = irq; 199 evt->cpumask = cpu_possible_mask; 200 201 writel(0, base + TIMER_CTRL); 202 203 setup_irq(irq, &sp804_timer_irq); 204 clockevents_config_and_register(evt, rate, 0xf, 0xffffffff); 205 206 return 0; 207 } 208 209 static int __init sp804_of_init(struct device_node *np) 210 { 211 static bool initialized = false; 212 void __iomem *base; 213 int irq, ret = -EINVAL; 214 u32 irq_num = 0; 215 struct clk *clk1, *clk2; 216 const char *name = of_get_property(np, "compatible", NULL); 217 218 base = of_iomap(np, 0); 219 if (!base) 220 return -ENXIO; 221 222 /* Ensure timers are disabled */ 223 writel(0, base + TIMER_CTRL); 224 writel(0, base + TIMER_2_BASE + TIMER_CTRL); 225 226 if (initialized || !of_device_is_available(np)) { 227 ret = -EINVAL; 228 goto err; 229 } 230 231 clk1 = of_clk_get(np, 0); 232 if (IS_ERR(clk1)) 233 clk1 = NULL; 234 235 /* Get the 2nd clock if the timer has 3 timer clocks */ 236 if (of_clk_get_parent_count(np) == 3) { 237 clk2 = of_clk_get(np, 1); 238 if (IS_ERR(clk2)) { 239 pr_err("sp804: %pOFn clock not found: %d\n", np, 240 (int)PTR_ERR(clk2)); 241 clk2 = NULL; 242 } 243 } else 244 clk2 = clk1; 245 246 irq = irq_of_parse_and_map(np, 0); 247 if (irq <= 0) 248 goto err; 249 250 of_property_read_u32(np, "arm,sp804-has-irq", &irq_num); 251 if (irq_num == 2) { 252 253 ret = __sp804_clockevents_init(base + TIMER_2_BASE, irq, clk2, name); 254 if (ret) 255 goto err; 256 257 ret = __sp804_clocksource_and_sched_clock_init(base, name, clk1, 1); 258 if (ret) 259 goto err; 260 } else { 261 262 ret = __sp804_clockevents_init(base, irq, clk1 , name); 263 if (ret) 264 goto err; 265 266 ret =__sp804_clocksource_and_sched_clock_init(base + TIMER_2_BASE, 267 name, clk2, 1); 268 if (ret) 269 goto err; 270 } 271 initialized = true; 272 273 return 0; 274 err: 275 iounmap(base); 276 return ret; 277 } 278 TIMER_OF_DECLARE(sp804, "arm,sp804", sp804_of_init); 279 280 static int __init integrator_cp_of_init(struct device_node *np) 281 { 282 static int init_count = 0; 283 void __iomem *base; 284 int irq, ret = -EINVAL; 285 const char *name = of_get_property(np, "compatible", NULL); 286 struct clk *clk; 287 288 base = of_iomap(np, 0); 289 if (!base) { 290 pr_err("Failed to iomap\n"); 291 return -ENXIO; 292 } 293 294 clk = of_clk_get(np, 0); 295 if (IS_ERR(clk)) { 296 pr_err("Failed to get clock\n"); 297 return PTR_ERR(clk); 298 } 299 300 /* Ensure timer is disabled */ 301 writel(0, base + TIMER_CTRL); 302 303 if (init_count == 2 || !of_device_is_available(np)) 304 goto err; 305 306 if (!init_count) { 307 ret = __sp804_clocksource_and_sched_clock_init(base, name, clk, 0); 308 if (ret) 309 goto err; 310 } else { 311 irq = irq_of_parse_and_map(np, 0); 312 if (irq <= 0) 313 goto err; 314 315 ret = __sp804_clockevents_init(base, irq, clk, name); 316 if (ret) 317 goto err; 318 } 319 320 init_count++; 321 return 0; 322 err: 323 iounmap(base); 324 return ret; 325 } 326 TIMER_OF_DECLARE(intcp, "arm,integrator-cp-timer", integrator_cp_of_init); 327