Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v3.11-rc2 449 lines 13 kB view raw
1/* 2 * This file contains driver for the Cadence Triple Timer Counter Rev 06 3 * 4 * Copyright (C) 2011-2013 Xilinx 5 * 6 * based on arch/mips/kernel/time.c timer driver 7 * 8 * This software is licensed under the terms of the GNU General Public 9 * License version 2, as published by the Free Software Foundation, and 10 * may be copied, distributed, and modified under those terms. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 */ 17 18#include <linux/clk.h> 19#include <linux/interrupt.h> 20#include <linux/clockchips.h> 21#include <linux/of_address.h> 22#include <linux/of_irq.h> 23#include <linux/slab.h> 24#include <linux/clk-provider.h> 25 26/* 27 * This driver configures the 2 16-bit count-up timers as follows: 28 * 29 * T1: Timer 1, clocksource for generic timekeeping 30 * T2: Timer 2, clockevent source for hrtimers 31 * T3: Timer 3, <unused> 32 * 33 * The input frequency to the timer module for emulation is 2.5MHz which is 34 * common to all the timer channels (T1, T2, and T3). With a pre-scaler of 32, 35 * the timers are clocked at 78.125KHz (12.8 us resolution). 36 37 * The input frequency to the timer module in silicon is configurable and 38 * obtained from device tree. The pre-scaler of 32 is used. 39 */ 40 41/* 42 * Timer Register Offset Definitions of Timer 1, Increment base address by 4 43 * and use same offsets for Timer 2 44 */ 45#define TTC_CLK_CNTRL_OFFSET 0x00 /* Clock Control Reg, RW */ 46#define TTC_CNT_CNTRL_OFFSET 0x0C /* Counter Control Reg, RW */ 47#define TTC_COUNT_VAL_OFFSET 0x18 /* Counter Value Reg, RO */ 48#define TTC_INTR_VAL_OFFSET 0x24 /* Interval Count Reg, RW */ 49#define TTC_ISR_OFFSET 0x54 /* Interrupt Status Reg, RO */ 50#define TTC_IER_OFFSET 0x60 /* Interrupt Enable Reg, RW */ 51 52#define TTC_CNT_CNTRL_DISABLE_MASK 0x1 53 54#define TTC_CLK_CNTRL_CSRC_MASK (1 << 5) /* clock source */ 55 56/* 57 * Setup the timers to use pre-scaling, using a fixed value for now that will 58 * work across most input frequency, but it may need to be more dynamic 59 */ 60#define PRESCALE_EXPONENT 11 /* 2 ^ PRESCALE_EXPONENT = PRESCALE */ 61#define PRESCALE 2048 /* The exponent must match this */ 62#define CLK_CNTRL_PRESCALE ((PRESCALE_EXPONENT - 1) << 1) 63#define CLK_CNTRL_PRESCALE_EN 1 64#define CNT_CNTRL_RESET (1 << 4) 65 66/** 67 * struct ttc_timer - This definition defines local timer structure 68 * 69 * @base_addr: Base address of timer 70 * @clk: Associated clock source 71 * @clk_rate_change_nb Notifier block for clock rate changes 72 */ 73struct ttc_timer { 74 void __iomem *base_addr; 75 struct clk *clk; 76 struct notifier_block clk_rate_change_nb; 77}; 78 79#define to_ttc_timer(x) \ 80 container_of(x, struct ttc_timer, clk_rate_change_nb) 81 82struct ttc_timer_clocksource { 83 struct ttc_timer ttc; 84 struct clocksource cs; 85}; 86 87#define to_ttc_timer_clksrc(x) \ 88 container_of(x, struct ttc_timer_clocksource, cs) 89 90struct ttc_timer_clockevent { 91 struct ttc_timer ttc; 92 struct clock_event_device ce; 93}; 94 95#define to_ttc_timer_clkevent(x) \ 96 container_of(x, struct ttc_timer_clockevent, ce) 97 98/** 99 * ttc_set_interval - Set the timer interval value 100 * 101 * @timer: Pointer to the timer instance 102 * @cycles: Timer interval ticks 103 **/ 104static void ttc_set_interval(struct ttc_timer *timer, 105 unsigned long cycles) 106{ 107 u32 ctrl_reg; 108 109 /* Disable the counter, set the counter value and re-enable counter */ 110 ctrl_reg = __raw_readl(timer->base_addr + TTC_CNT_CNTRL_OFFSET); 111 ctrl_reg |= TTC_CNT_CNTRL_DISABLE_MASK; 112 __raw_writel(ctrl_reg, timer->base_addr + TTC_CNT_CNTRL_OFFSET); 113 114 __raw_writel(cycles, timer->base_addr + TTC_INTR_VAL_OFFSET); 115 116 /* 117 * Reset the counter (0x10) so that it starts from 0, one-shot 118 * mode makes this needed for timing to be right. 119 */ 120 ctrl_reg |= CNT_CNTRL_RESET; 121 ctrl_reg &= ~TTC_CNT_CNTRL_DISABLE_MASK; 122 __raw_writel(ctrl_reg, timer->base_addr + TTC_CNT_CNTRL_OFFSET); 123} 124 125/** 126 * ttc_clock_event_interrupt - Clock event timer interrupt handler 127 * 128 * @irq: IRQ number of the Timer 129 * @dev_id: void pointer to the ttc_timer instance 130 * 131 * returns: Always IRQ_HANDLED - success 132 **/ 133static irqreturn_t ttc_clock_event_interrupt(int irq, void *dev_id) 134{ 135 struct ttc_timer_clockevent *ttce = dev_id; 136 struct ttc_timer *timer = &ttce->ttc; 137 138 /* Acknowledge the interrupt and call event handler */ 139 __raw_readl(timer->base_addr + TTC_ISR_OFFSET); 140 141 ttce->ce.event_handler(&ttce->ce); 142 143 return IRQ_HANDLED; 144} 145 146/** 147 * __ttc_clocksource_read - Reads the timer counter register 148 * 149 * returns: Current timer counter register value 150 **/ 151static cycle_t __ttc_clocksource_read(struct clocksource *cs) 152{ 153 struct ttc_timer *timer = &to_ttc_timer_clksrc(cs)->ttc; 154 155 return (cycle_t)__raw_readl(timer->base_addr + 156 TTC_COUNT_VAL_OFFSET); 157} 158 159/** 160 * ttc_set_next_event - Sets the time interval for next event 161 * 162 * @cycles: Timer interval ticks 163 * @evt: Address of clock event instance 164 * 165 * returns: Always 0 - success 166 **/ 167static int ttc_set_next_event(unsigned long cycles, 168 struct clock_event_device *evt) 169{ 170 struct ttc_timer_clockevent *ttce = to_ttc_timer_clkevent(evt); 171 struct ttc_timer *timer = &ttce->ttc; 172 173 ttc_set_interval(timer, cycles); 174 return 0; 175} 176 177/** 178 * ttc_set_mode - Sets the mode of timer 179 * 180 * @mode: Mode to be set 181 * @evt: Address of clock event instance 182 **/ 183static void ttc_set_mode(enum clock_event_mode mode, 184 struct clock_event_device *evt) 185{ 186 struct ttc_timer_clockevent *ttce = to_ttc_timer_clkevent(evt); 187 struct ttc_timer *timer = &ttce->ttc; 188 u32 ctrl_reg; 189 190 switch (mode) { 191 case CLOCK_EVT_MODE_PERIODIC: 192 ttc_set_interval(timer, 193 DIV_ROUND_CLOSEST(clk_get_rate(ttce->ttc.clk), 194 PRESCALE * HZ)); 195 break; 196 case CLOCK_EVT_MODE_ONESHOT: 197 case CLOCK_EVT_MODE_UNUSED: 198 case CLOCK_EVT_MODE_SHUTDOWN: 199 ctrl_reg = __raw_readl(timer->base_addr + 200 TTC_CNT_CNTRL_OFFSET); 201 ctrl_reg |= TTC_CNT_CNTRL_DISABLE_MASK; 202 __raw_writel(ctrl_reg, 203 timer->base_addr + TTC_CNT_CNTRL_OFFSET); 204 break; 205 case CLOCK_EVT_MODE_RESUME: 206 ctrl_reg = __raw_readl(timer->base_addr + 207 TTC_CNT_CNTRL_OFFSET); 208 ctrl_reg &= ~TTC_CNT_CNTRL_DISABLE_MASK; 209 __raw_writel(ctrl_reg, 210 timer->base_addr + TTC_CNT_CNTRL_OFFSET); 211 break; 212 } 213} 214 215static int ttc_rate_change_clocksource_cb(struct notifier_block *nb, 216 unsigned long event, void *data) 217{ 218 struct clk_notifier_data *ndata = data; 219 struct ttc_timer *ttc = to_ttc_timer(nb); 220 struct ttc_timer_clocksource *ttccs = container_of(ttc, 221 struct ttc_timer_clocksource, ttc); 222 223 switch (event) { 224 case POST_RATE_CHANGE: 225 /* 226 * Do whatever is necessary to maintain a proper time base 227 * 228 * I cannot find a way to adjust the currently used clocksource 229 * to the new frequency. __clocksource_updatefreq_hz() sounds 230 * good, but does not work. Not sure what's that missing. 231 * 232 * This approach works, but triggers two clocksource switches. 233 * The first after unregister to clocksource jiffies. And 234 * another one after the register to the newly registered timer. 235 * 236 * Alternatively we could 'waste' another HW timer to ping pong 237 * between clock sources. That would also use one register and 238 * one unregister call, but only trigger one clocksource switch 239 * for the cost of another HW timer used by the OS. 240 */ 241 clocksource_unregister(&ttccs->cs); 242 clocksource_register_hz(&ttccs->cs, 243 ndata->new_rate / PRESCALE); 244 /* fall through */ 245 case PRE_RATE_CHANGE: 246 case ABORT_RATE_CHANGE: 247 default: 248 return NOTIFY_DONE; 249 } 250} 251 252static void __init ttc_setup_clocksource(struct clk *clk, void __iomem *base) 253{ 254 struct ttc_timer_clocksource *ttccs; 255 int err; 256 257 ttccs = kzalloc(sizeof(*ttccs), GFP_KERNEL); 258 if (WARN_ON(!ttccs)) 259 return; 260 261 ttccs->ttc.clk = clk; 262 263 err = clk_prepare_enable(ttccs->ttc.clk); 264 if (WARN_ON(err)) { 265 kfree(ttccs); 266 return; 267 } 268 269 ttccs->ttc.clk_rate_change_nb.notifier_call = 270 ttc_rate_change_clocksource_cb; 271 ttccs->ttc.clk_rate_change_nb.next = NULL; 272 if (clk_notifier_register(ttccs->ttc.clk, 273 &ttccs->ttc.clk_rate_change_nb)) 274 pr_warn("Unable to register clock notifier.\n"); 275 276 ttccs->ttc.base_addr = base; 277 ttccs->cs.name = "ttc_clocksource"; 278 ttccs->cs.rating = 200; 279 ttccs->cs.read = __ttc_clocksource_read; 280 ttccs->cs.mask = CLOCKSOURCE_MASK(16); 281 ttccs->cs.flags = CLOCK_SOURCE_IS_CONTINUOUS; 282 283 /* 284 * Setup the clock source counter to be an incrementing counter 285 * with no interrupt and it rolls over at 0xFFFF. Pre-scale 286 * it by 32 also. Let it start running now. 287 */ 288 __raw_writel(0x0, ttccs->ttc.base_addr + TTC_IER_OFFSET); 289 __raw_writel(CLK_CNTRL_PRESCALE | CLK_CNTRL_PRESCALE_EN, 290 ttccs->ttc.base_addr + TTC_CLK_CNTRL_OFFSET); 291 __raw_writel(CNT_CNTRL_RESET, 292 ttccs->ttc.base_addr + TTC_CNT_CNTRL_OFFSET); 293 294 err = clocksource_register_hz(&ttccs->cs, 295 clk_get_rate(ttccs->ttc.clk) / PRESCALE); 296 if (WARN_ON(err)) { 297 kfree(ttccs); 298 return; 299 } 300} 301 302static int ttc_rate_change_clockevent_cb(struct notifier_block *nb, 303 unsigned long event, void *data) 304{ 305 struct clk_notifier_data *ndata = data; 306 struct ttc_timer *ttc = to_ttc_timer(nb); 307 struct ttc_timer_clockevent *ttcce = container_of(ttc, 308 struct ttc_timer_clockevent, ttc); 309 310 switch (event) { 311 case POST_RATE_CHANGE: 312 { 313 unsigned long flags; 314 315 /* 316 * clockevents_update_freq should be called with IRQ disabled on 317 * the CPU the timer provides events for. The timer we use is 318 * common to both CPUs, not sure if we need to run on both 319 * cores. 320 */ 321 local_irq_save(flags); 322 clockevents_update_freq(&ttcce->ce, 323 ndata->new_rate / PRESCALE); 324 local_irq_restore(flags); 325 326 /* fall through */ 327 } 328 case PRE_RATE_CHANGE: 329 case ABORT_RATE_CHANGE: 330 default: 331 return NOTIFY_DONE; 332 } 333} 334 335static void __init ttc_setup_clockevent(struct clk *clk, 336 void __iomem *base, u32 irq) 337{ 338 struct ttc_timer_clockevent *ttcce; 339 int err; 340 341 ttcce = kzalloc(sizeof(*ttcce), GFP_KERNEL); 342 if (WARN_ON(!ttcce)) 343 return; 344 345 ttcce->ttc.clk = clk; 346 347 err = clk_prepare_enable(ttcce->ttc.clk); 348 if (WARN_ON(err)) { 349 kfree(ttcce); 350 return; 351 } 352 353 ttcce->ttc.clk_rate_change_nb.notifier_call = 354 ttc_rate_change_clockevent_cb; 355 ttcce->ttc.clk_rate_change_nb.next = NULL; 356 if (clk_notifier_register(ttcce->ttc.clk, 357 &ttcce->ttc.clk_rate_change_nb)) 358 pr_warn("Unable to register clock notifier.\n"); 359 360 ttcce->ttc.base_addr = base; 361 ttcce->ce.name = "ttc_clockevent"; 362 ttcce->ce.features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT; 363 ttcce->ce.set_next_event = ttc_set_next_event; 364 ttcce->ce.set_mode = ttc_set_mode; 365 ttcce->ce.rating = 200; 366 ttcce->ce.irq = irq; 367 ttcce->ce.cpumask = cpu_possible_mask; 368 369 /* 370 * Setup the clock event timer to be an interval timer which 371 * is prescaled by 32 using the interval interrupt. Leave it 372 * disabled for now. 373 */ 374 __raw_writel(0x23, ttcce->ttc.base_addr + TTC_CNT_CNTRL_OFFSET); 375 __raw_writel(CLK_CNTRL_PRESCALE | CLK_CNTRL_PRESCALE_EN, 376 ttcce->ttc.base_addr + TTC_CLK_CNTRL_OFFSET); 377 __raw_writel(0x1, ttcce->ttc.base_addr + TTC_IER_OFFSET); 378 379 err = request_irq(irq, ttc_clock_event_interrupt, 380 IRQF_DISABLED | IRQF_TIMER, 381 ttcce->ce.name, ttcce); 382 if (WARN_ON(err)) { 383 kfree(ttcce); 384 return; 385 } 386 387 clockevents_config_and_register(&ttcce->ce, 388 clk_get_rate(ttcce->ttc.clk) / PRESCALE, 1, 0xfffe); 389} 390 391/** 392 * ttc_timer_init - Initialize the timer 393 * 394 * Initializes the timer hardware and register the clock source and clock event 395 * timers with Linux kernal timer framework 396 */ 397static void __init ttc_timer_init(struct device_node *timer) 398{ 399 unsigned int irq; 400 void __iomem *timer_baseaddr; 401 struct clk *clk_cs, *clk_ce; 402 static int initialized; 403 int clksel; 404 405 if (initialized) 406 return; 407 408 initialized = 1; 409 410 /* 411 * Get the 1st Triple Timer Counter (TTC) block from the device tree 412 * and use it. Note that the event timer uses the interrupt and it's the 413 * 2nd TTC hence the irq_of_parse_and_map(,1) 414 */ 415 timer_baseaddr = of_iomap(timer, 0); 416 if (!timer_baseaddr) { 417 pr_err("ERROR: invalid timer base address\n"); 418 BUG(); 419 } 420 421 irq = irq_of_parse_and_map(timer, 1); 422 if (irq <= 0) { 423 pr_err("ERROR: invalid interrupt number\n"); 424 BUG(); 425 } 426 427 clksel = __raw_readl(timer_baseaddr + TTC_CLK_CNTRL_OFFSET); 428 clksel = !!(clksel & TTC_CLK_CNTRL_CSRC_MASK); 429 clk_cs = of_clk_get(timer, clksel); 430 if (IS_ERR(clk_cs)) { 431 pr_err("ERROR: timer input clock not found\n"); 432 BUG(); 433 } 434 435 clksel = __raw_readl(timer_baseaddr + 4 + TTC_CLK_CNTRL_OFFSET); 436 clksel = !!(clksel & TTC_CLK_CNTRL_CSRC_MASK); 437 clk_ce = of_clk_get(timer, clksel); 438 if (IS_ERR(clk_ce)) { 439 pr_err("ERROR: timer input clock not found\n"); 440 BUG(); 441 } 442 443 ttc_setup_clocksource(clk_cs, timer_baseaddr); 444 ttc_setup_clockevent(clk_ce, timer_baseaddr + 4, irq); 445 446 pr_info("%s #0 at %p, irq=%d\n", timer->name, timer_baseaddr, irq); 447} 448 449CLOCKSOURCE_OF_DECLARE(ttc, "cdns,ttc", ttc_timer_init);