1 /* 2 * (C) Copyright 2009 Intel Corporation 3 * Author: Jacob Pan (jacob.jun.pan@intel.com) 4 * 5 * Shared with ARM platforms, Jamie Iles, Picochip 2011 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License version 2 as 9 * published by the Free Software Foundation. 10 * 11 * Support for the Synopsys DesignWare APB Timers. 12 */ 13 #include <linux/dw_apb_timer.h> 14 #include <linux/delay.h> 15 #include <linux/kernel.h> 16 #include <linux/interrupt.h> 17 #include <linux/irq.h> 18 #include <linux/io.h> 19 #include <linux/slab.h> 20 21 #define APBT_MIN_PERIOD 4 22 #define APBT_MIN_DELTA_USEC 200 23 24 #define APBTMR_N_LOAD_COUNT 0x00 25 #define APBTMR_N_CURRENT_VALUE 0x04 26 #define APBTMR_N_CONTROL 0x08 27 #define APBTMR_N_EOI 0x0c 28 #define APBTMR_N_INT_STATUS 0x10 29 30 #define APBTMRS_INT_STATUS 0xa0 31 #define APBTMRS_EOI 0xa4 32 #define APBTMRS_RAW_INT_STATUS 0xa8 33 #define APBTMRS_COMP_VERSION 0xac 34 35 #define APBTMR_CONTROL_ENABLE (1 << 0) 36 /* 1: periodic, 0:free running. */ 37 #define APBTMR_CONTROL_MODE_PERIODIC (1 << 1) 38 #define APBTMR_CONTROL_INT (1 << 2) 39 40 static inline struct dw_apb_clock_event_device * 41 ced_to_dw_apb_ced(struct clock_event_device *evt) 42 { 43 return container_of(evt, struct dw_apb_clock_event_device, ced); 44 } 45 46 static inline struct dw_apb_clocksource * 47 clocksource_to_dw_apb_clocksource(struct clocksource *cs) 48 { 49 return container_of(cs, struct dw_apb_clocksource, cs); 50 } 51 52 static inline u32 apbt_readl(struct dw_apb_timer *timer, unsigned long offs) 53 { 54 return readl(timer->base + offs); 55 } 56 57 static inline void apbt_writel(struct dw_apb_timer *timer, u32 val, 58 unsigned long offs) 59 { 60 writel(val, timer->base + offs); 61 } 62 63 static inline u32 apbt_readl_relaxed(struct dw_apb_timer *timer, unsigned long offs) 64 { 65 return readl_relaxed(timer->base + offs); 66 } 67 68 static inline void apbt_writel_relaxed(struct dw_apb_timer *timer, u32 val, 69 unsigned long offs) 70 { 71 writel_relaxed(val, timer->base + offs); 72 } 73 74 static void apbt_disable_int(struct dw_apb_timer *timer) 75 { 76 u32 ctrl = apbt_readl(timer, APBTMR_N_CONTROL); 77 78 ctrl |= APBTMR_CONTROL_INT; 79 apbt_writel(timer, ctrl, APBTMR_N_CONTROL); 80 } 81 82 /** 83 * dw_apb_clockevent_pause() - stop the clock_event_device from running 84 * 85 * @dw_ced: The APB clock to stop generating events. 86 */ 87 void dw_apb_clockevent_pause(struct dw_apb_clock_event_device *dw_ced) 88 { 89 disable_irq(dw_ced->timer.irq); 90 apbt_disable_int(&dw_ced->timer); 91 } 92 93 static void apbt_eoi(struct dw_apb_timer *timer) 94 { 95 apbt_readl_relaxed(timer, APBTMR_N_EOI); 96 } 97 98 static irqreturn_t dw_apb_clockevent_irq(int irq, void *data) 99 { 100 struct clock_event_device *evt = data; 101 struct dw_apb_clock_event_device *dw_ced = ced_to_dw_apb_ced(evt); 102 103 if (!evt->event_handler) { 104 pr_info("Spurious APBT timer interrupt %d", irq); 105 return IRQ_NONE; 106 } 107 108 if (dw_ced->eoi) 109 dw_ced->eoi(&dw_ced->timer); 110 111 evt->event_handler(evt); 112 return IRQ_HANDLED; 113 } 114 115 static void apbt_enable_int(struct dw_apb_timer *timer) 116 { 117 u32 ctrl = apbt_readl(timer, APBTMR_N_CONTROL); 118 /* clear pending intr */ 119 apbt_readl(timer, APBTMR_N_EOI); 120 ctrl &= ~APBTMR_CONTROL_INT; 121 apbt_writel(timer, ctrl, APBTMR_N_CONTROL); 122 } 123 124 static int apbt_shutdown(struct clock_event_device *evt) 125 { 126 struct dw_apb_clock_event_device *dw_ced = ced_to_dw_apb_ced(evt); 127 u32 ctrl; 128 129 pr_debug("%s CPU %d state=shutdown\n", __func__, 130 cpumask_first(evt->cpumask)); 131 132 ctrl = apbt_readl(&dw_ced->timer, APBTMR_N_CONTROL); 133 ctrl &= ~APBTMR_CONTROL_ENABLE; 134 apbt_writel(&dw_ced->timer, ctrl, APBTMR_N_CONTROL); 135 return 0; 136 } 137 138 static int apbt_set_oneshot(struct clock_event_device *evt) 139 { 140 struct dw_apb_clock_event_device *dw_ced = ced_to_dw_apb_ced(evt); 141 u32 ctrl; 142 143 pr_debug("%s CPU %d state=oneshot\n", __func__, 144 cpumask_first(evt->cpumask)); 145 146 ctrl = apbt_readl(&dw_ced->timer, APBTMR_N_CONTROL); 147 /* 148 * set free running mode, this mode will let timer reload max 149 * timeout which will give time (3min on 25MHz clock) to rearm 150 * the next event, therefore emulate the one-shot mode. 151 */ 152 ctrl &= ~APBTMR_CONTROL_ENABLE; 153 ctrl &= ~APBTMR_CONTROL_MODE_PERIODIC; 154 155 apbt_writel(&dw_ced->timer, ctrl, APBTMR_N_CONTROL); 156 /* write again to set free running mode */ 157 apbt_writel(&dw_ced->timer, ctrl, APBTMR_N_CONTROL); 158 159 /* 160 * DW APB p. 46, load counter with all 1s before starting free 161 * running mode. 162 */ 163 apbt_writel(&dw_ced->timer, ~0, APBTMR_N_LOAD_COUNT); 164 ctrl &= ~APBTMR_CONTROL_INT; 165 ctrl |= APBTMR_CONTROL_ENABLE; 166 apbt_writel(&dw_ced->timer, ctrl, APBTMR_N_CONTROL); 167 return 0; 168 } 169 170 static int apbt_set_periodic(struct clock_event_device *evt) 171 { 172 struct dw_apb_clock_event_device *dw_ced = ced_to_dw_apb_ced(evt); 173 unsigned long period = DIV_ROUND_UP(dw_ced->timer.freq, HZ); 174 u32 ctrl; 175 176 pr_debug("%s CPU %d state=periodic\n", __func__, 177 cpumask_first(evt->cpumask)); 178 179 ctrl = apbt_readl(&dw_ced->timer, APBTMR_N_CONTROL); 180 ctrl |= APBTMR_CONTROL_MODE_PERIODIC; 181 apbt_writel(&dw_ced->timer, ctrl, APBTMR_N_CONTROL); 182 /* 183 * DW APB p. 46, have to disable timer before load counter, 184 * may cause sync problem. 185 */ 186 ctrl &= ~APBTMR_CONTROL_ENABLE; 187 apbt_writel(&dw_ced->timer, ctrl, APBTMR_N_CONTROL); 188 udelay(1); 189 pr_debug("Setting clock period %lu for HZ %d\n", period, HZ); 190 apbt_writel(&dw_ced->timer, period, APBTMR_N_LOAD_COUNT); 191 ctrl |= APBTMR_CONTROL_ENABLE; 192 apbt_writel(&dw_ced->timer, ctrl, APBTMR_N_CONTROL); 193 return 0; 194 } 195 196 static int apbt_resume(struct clock_event_device *evt) 197 { 198 struct dw_apb_clock_event_device *dw_ced = ced_to_dw_apb_ced(evt); 199 200 pr_debug("%s CPU %d state=resume\n", __func__, 201 cpumask_first(evt->cpumask)); 202 203 apbt_enable_int(&dw_ced->timer); 204 return 0; 205 } 206 207 static int apbt_next_event(unsigned long delta, 208 struct clock_event_device *evt) 209 { 210 u32 ctrl; 211 struct dw_apb_clock_event_device *dw_ced = ced_to_dw_apb_ced(evt); 212 213 /* Disable timer */ 214 ctrl = apbt_readl_relaxed(&dw_ced->timer, APBTMR_N_CONTROL); 215 ctrl &= ~APBTMR_CONTROL_ENABLE; 216 apbt_writel_relaxed(&dw_ced->timer, ctrl, APBTMR_N_CONTROL); 217 /* write new count */ 218 apbt_writel_relaxed(&dw_ced->timer, delta, APBTMR_N_LOAD_COUNT); 219 ctrl |= APBTMR_CONTROL_ENABLE; 220 apbt_writel_relaxed(&dw_ced->timer, ctrl, APBTMR_N_CONTROL); 221 222 return 0; 223 } 224 225 /** 226 * dw_apb_clockevent_init() - use an APB timer as a clock_event_device 227 * 228 * @cpu: The CPU the events will be targeted at. 229 * @name: The name used for the timer and the IRQ for it. 230 * @rating: The rating to give the timer. 231 * @base: I/O base for the timer registers. 232 * @irq: The interrupt number to use for the timer. 233 * @freq: The frequency that the timer counts at. 234 * 235 * This creates a clock_event_device for using with the generic clock layer 236 * but does not start and register it. This should be done with 237 * dw_apb_clockevent_register() as the next step. If this is the first time 238 * it has been called for a timer then the IRQ will be requested, if not it 239 * just be enabled to allow CPU hotplug to avoid repeatedly requesting and 240 * releasing the IRQ. 241 */ 242 struct dw_apb_clock_event_device * 243 dw_apb_clockevent_init(int cpu, const char *name, unsigned rating, 244 void __iomem *base, int irq, unsigned long freq) 245 { 246 struct dw_apb_clock_event_device *dw_ced = 247 kzalloc(sizeof(*dw_ced), GFP_KERNEL); 248 int err; 249 250 if (!dw_ced) 251 return NULL; 252 253 dw_ced->timer.base = base; 254 dw_ced->timer.irq = irq; 255 dw_ced->timer.freq = freq; 256 257 clockevents_calc_mult_shift(&dw_ced->ced, freq, APBT_MIN_PERIOD); 258 dw_ced->ced.max_delta_ns = clockevent_delta2ns(0x7fffffff, 259 &dw_ced->ced); 260 dw_ced->ced.min_delta_ns = clockevent_delta2ns(5000, &dw_ced->ced); 261 dw_ced->ced.cpumask = cpumask_of(cpu); 262 dw_ced->ced.features = CLOCK_EVT_FEAT_PERIODIC | 263 CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_DYNIRQ; 264 dw_ced->ced.set_state_shutdown = apbt_shutdown; 265 dw_ced->ced.set_state_periodic = apbt_set_periodic; 266 dw_ced->ced.set_state_oneshot = apbt_set_oneshot; 267 dw_ced->ced.set_state_oneshot_stopped = apbt_shutdown; 268 dw_ced->ced.tick_resume = apbt_resume; 269 dw_ced->ced.set_next_event = apbt_next_event; 270 dw_ced->ced.irq = dw_ced->timer.irq; 271 dw_ced->ced.rating = rating; 272 dw_ced->ced.name = name; 273 274 dw_ced->irqaction.name = dw_ced->ced.name; 275 dw_ced->irqaction.handler = dw_apb_clockevent_irq; 276 dw_ced->irqaction.dev_id = &dw_ced->ced; 277 dw_ced->irqaction.irq = irq; 278 dw_ced->irqaction.flags = IRQF_TIMER | IRQF_IRQPOLL | 279 IRQF_NOBALANCING; 280 281 dw_ced->eoi = apbt_eoi; 282 err = setup_irq(irq, &dw_ced->irqaction); 283 if (err) { 284 pr_err("failed to request timer irq\n"); 285 kfree(dw_ced); 286 dw_ced = NULL; 287 } 288 289 return dw_ced; 290 } 291 292 /** 293 * dw_apb_clockevent_resume() - resume a clock that has been paused. 294 * 295 * @dw_ced: The APB clock to resume. 296 */ 297 void dw_apb_clockevent_resume(struct dw_apb_clock_event_device *dw_ced) 298 { 299 enable_irq(dw_ced->timer.irq); 300 } 301 302 /** 303 * dw_apb_clockevent_stop() - stop the clock_event_device and release the IRQ. 304 * 305 * @dw_ced: The APB clock to stop generating the events. 306 */ 307 void dw_apb_clockevent_stop(struct dw_apb_clock_event_device *dw_ced) 308 { 309 free_irq(dw_ced->timer.irq, &dw_ced->ced); 310 } 311 312 /** 313 * dw_apb_clockevent_register() - register the clock with the generic layer 314 * 315 * @dw_ced: The APB clock to register as a clock_event_device. 316 */ 317 void dw_apb_clockevent_register(struct dw_apb_clock_event_device *dw_ced) 318 { 319 apbt_writel(&dw_ced->timer, 0, APBTMR_N_CONTROL); 320 clockevents_register_device(&dw_ced->ced); 321 apbt_enable_int(&dw_ced->timer); 322 } 323 324 /** 325 * dw_apb_clocksource_start() - start the clocksource counting. 326 * 327 * @dw_cs: The clocksource to start. 328 * 329 * This is used to start the clocksource before registration and can be used 330 * to enable calibration of timers. 331 */ 332 void dw_apb_clocksource_start(struct dw_apb_clocksource *dw_cs) 333 { 334 /* 335 * start count down from 0xffff_ffff. this is done by toggling the 336 * enable bit then load initial load count to ~0. 337 */ 338 u32 ctrl = apbt_readl(&dw_cs->timer, APBTMR_N_CONTROL); 339 340 ctrl &= ~APBTMR_CONTROL_ENABLE; 341 apbt_writel(&dw_cs->timer, ctrl, APBTMR_N_CONTROL); 342 apbt_writel(&dw_cs->timer, ~0, APBTMR_N_LOAD_COUNT); 343 /* enable, mask interrupt */ 344 ctrl &= ~APBTMR_CONTROL_MODE_PERIODIC; 345 ctrl |= (APBTMR_CONTROL_ENABLE | APBTMR_CONTROL_INT); 346 apbt_writel(&dw_cs->timer, ctrl, APBTMR_N_CONTROL); 347 /* read it once to get cached counter value initialized */ 348 dw_apb_clocksource_read(dw_cs); 349 } 350 351 static u64 __apbt_read_clocksource(struct clocksource *cs) 352 { 353 u32 current_count; 354 struct dw_apb_clocksource *dw_cs = 355 clocksource_to_dw_apb_clocksource(cs); 356 357 current_count = apbt_readl_relaxed(&dw_cs->timer, 358 APBTMR_N_CURRENT_VALUE); 359 360 return (u64)~current_count; 361 } 362 363 static void apbt_restart_clocksource(struct clocksource *cs) 364 { 365 struct dw_apb_clocksource *dw_cs = 366 clocksource_to_dw_apb_clocksource(cs); 367 368 dw_apb_clocksource_start(dw_cs); 369 } 370 371 /** 372 * dw_apb_clocksource_init() - use an APB timer as a clocksource. 373 * 374 * @rating: The rating to give the clocksource. 375 * @name: The name for the clocksource. 376 * @base: The I/O base for the timer registers. 377 * @freq: The frequency that the timer counts at. 378 * 379 * This creates a clocksource using an APB timer but does not yet register it 380 * with the clocksource system. This should be done with 381 * dw_apb_clocksource_register() as the next step. 382 */ 383 struct dw_apb_clocksource * 384 dw_apb_clocksource_init(unsigned rating, const char *name, void __iomem *base, 385 unsigned long freq) 386 { 387 struct dw_apb_clocksource *dw_cs = kzalloc(sizeof(*dw_cs), GFP_KERNEL); 388 389 if (!dw_cs) 390 return NULL; 391 392 dw_cs->timer.base = base; 393 dw_cs->timer.freq = freq; 394 dw_cs->cs.name = name; 395 dw_cs->cs.rating = rating; 396 dw_cs->cs.read = __apbt_read_clocksource; 397 dw_cs->cs.mask = CLOCKSOURCE_MASK(32); 398 dw_cs->cs.flags = CLOCK_SOURCE_IS_CONTINUOUS; 399 dw_cs->cs.resume = apbt_restart_clocksource; 400 401 return dw_cs; 402 } 403 404 /** 405 * dw_apb_clocksource_register() - register the APB clocksource. 406 * 407 * @dw_cs: The clocksource to register. 408 */ 409 void dw_apb_clocksource_register(struct dw_apb_clocksource *dw_cs) 410 { 411 clocksource_register_hz(&dw_cs->cs, dw_cs->timer.freq); 412 } 413 414 /** 415 * dw_apb_clocksource_read() - read the current value of a clocksource. 416 * 417 * @dw_cs: The clocksource to read. 418 */ 419 u64 dw_apb_clocksource_read(struct dw_apb_clocksource *dw_cs) 420 { 421 return (u64)~apbt_readl(&dw_cs->timer, APBTMR_N_CURRENT_VALUE); 422 } 423