• Home
  • Raw
  • Download

Lines Matching +full:clk +full:- +full:source

4  *  Copyright (C) 2011-2013 Xilinx
18 #include <linux/clk.h>
28 * This driver configures the 2 16/32-bit count-up timers as follows:
31 * T2: Timer 2, clockevent source for hrtimers
35 * common to all the timer channels (T1, T2, and T3). With a pre-scaler of 32,
39 * obtained from device tree. The pre-scaler of 32 is used.
55 #define TTC_CLK_CNTRL_CSRC_MASK (1 << 5) /* clock source */
60 * Setup the timers to use pre-scaling, using a fixed value for now that will
65 #define CLK_CNTRL_PRESCALE ((PRESCALE_EXPONENT - 1) << 1)
72 * struct ttc_timer - This definition defines local timer structure
76 * @clk: Associated clock source
82 struct clk *clk; member
110 * ttc_set_interval - Set the timer interval value
120 /* Disable the counter, set the counter value and re-enable counter */ in ttc_set_interval()
121 ctrl_reg = readl_relaxed(timer->base_addr + TTC_CNT_CNTRL_OFFSET); in ttc_set_interval()
123 writel_relaxed(ctrl_reg, timer->base_addr + TTC_CNT_CNTRL_OFFSET); in ttc_set_interval()
125 writel_relaxed(cycles, timer->base_addr + TTC_INTR_VAL_OFFSET); in ttc_set_interval()
128 * Reset the counter (0x10) so that it starts from 0, one-shot in ttc_set_interval()
133 writel_relaxed(ctrl_reg, timer->base_addr + TTC_CNT_CNTRL_OFFSET); in ttc_set_interval()
137 * ttc_clock_event_interrupt - Clock event timer interrupt handler
142 * returns: Always IRQ_HANDLED - success
147 struct ttc_timer *timer = &ttce->ttc; in ttc_clock_event_interrupt()
150 readl_relaxed(timer->base_addr + TTC_ISR_OFFSET); in ttc_clock_event_interrupt()
152 ttce->ce.event_handler(&ttce->ce); in ttc_clock_event_interrupt()
158 * __ttc_clocksource_read - Reads the timer counter register
164 struct ttc_timer *timer = &to_ttc_timer_clksrc(cs)->ttc; in __ttc_clocksource_read()
166 return (u64)readl_relaxed(timer->base_addr + in __ttc_clocksource_read()
176 * ttc_set_next_event - Sets the time interval for next event
181 * returns: Always 0 - success
187 struct ttc_timer *timer = &ttce->ttc; in ttc_set_next_event()
194 * ttc_set_{shutdown|oneshot|periodic} - Sets the state of timer
201 struct ttc_timer *timer = &ttce->ttc; in ttc_shutdown()
204 ctrl_reg = readl_relaxed(timer->base_addr + TTC_CNT_CNTRL_OFFSET); in ttc_shutdown()
206 writel_relaxed(ctrl_reg, timer->base_addr + TTC_CNT_CNTRL_OFFSET); in ttc_shutdown()
213 struct ttc_timer *timer = &ttce->ttc; in ttc_set_periodic()
216 DIV_ROUND_CLOSEST(ttce->ttc.freq, PRESCALE * HZ)); in ttc_set_periodic()
223 struct ttc_timer *timer = &ttce->ttc; in ttc_resume()
226 ctrl_reg = readl_relaxed(timer->base_addr + TTC_CNT_CNTRL_OFFSET); in ttc_resume()
228 writel_relaxed(ctrl_reg, timer->base_addr + TTC_CNT_CNTRL_OFFSET); in ttc_resume()
246 if (ndata->new_rate > ndata->old_rate) { in ttc_rate_change_clocksource_cb()
247 factor = DIV_ROUND_CLOSEST(ndata->new_rate, in ttc_rate_change_clocksource_cb()
248 ndata->old_rate); in ttc_rate_change_clocksource_cb()
249 rate_low = ndata->old_rate; in ttc_rate_change_clocksource_cb()
250 rate_high = ndata->new_rate; in ttc_rate_change_clocksource_cb()
252 factor = DIV_ROUND_CLOSEST(ndata->old_rate, in ttc_rate_change_clocksource_cb()
253 ndata->new_rate); in ttc_rate_change_clocksource_cb()
254 rate_low = ndata->new_rate; in ttc_rate_change_clocksource_cb()
255 rate_high = ndata->old_rate; in ttc_rate_change_clocksource_cb()
261 if (abs(rate_high - (factor * rate_low)) > MAX_F_ERR) in ttc_rate_change_clocksource_cb()
270 ttccs->scale_clk_ctrl_reg_old = in ttc_rate_change_clocksource_cb()
271 readl_relaxed(ttccs->ttc.base_addr + in ttc_rate_change_clocksource_cb()
274 psv = (ttccs->scale_clk_ctrl_reg_old & in ttc_rate_change_clocksource_cb()
277 if (ndata->new_rate < ndata->old_rate) in ttc_rate_change_clocksource_cb()
278 psv -= factor; in ttc_rate_change_clocksource_cb()
286 ttccs->scale_clk_ctrl_reg_new = ttccs->scale_clk_ctrl_reg_old & in ttc_rate_change_clocksource_cb()
288 ttccs->scale_clk_ctrl_reg_new |= psv << TTC_CLK_CNTRL_PSV_SHIFT; in ttc_rate_change_clocksource_cb()
291 /* scale down: adjust divider in post-change notification */ in ttc_rate_change_clocksource_cb()
292 if (ndata->new_rate < ndata->old_rate) in ttc_rate_change_clocksource_cb()
295 /* scale up: adjust divider now - before frequency change */ in ttc_rate_change_clocksource_cb()
296 writel_relaxed(ttccs->scale_clk_ctrl_reg_new, in ttc_rate_change_clocksource_cb()
297 ttccs->ttc.base_addr + TTC_CLK_CNTRL_OFFSET); in ttc_rate_change_clocksource_cb()
301 /* scale up: pre-change notification did the adjustment */ in ttc_rate_change_clocksource_cb()
302 if (ndata->new_rate > ndata->old_rate) in ttc_rate_change_clocksource_cb()
305 /* scale down: adjust divider now - after frequency change */ in ttc_rate_change_clocksource_cb()
306 writel_relaxed(ttccs->scale_clk_ctrl_reg_new, in ttc_rate_change_clocksource_cb()
307 ttccs->ttc.base_addr + TTC_CLK_CNTRL_OFFSET); in ttc_rate_change_clocksource_cb()
312 if (ndata->new_rate < ndata->old_rate) in ttc_rate_change_clocksource_cb()
316 writel_relaxed(ttccs->scale_clk_ctrl_reg_old, in ttc_rate_change_clocksource_cb()
317 ttccs->ttc.base_addr + TTC_CLK_CNTRL_OFFSET); in ttc_rate_change_clocksource_cb()
326 static int __init ttc_setup_clocksource(struct clk *clk, void __iomem *base, in ttc_setup_clocksource() argument
334 return -ENOMEM; in ttc_setup_clocksource()
336 ttccs->ttc.clk = clk; in ttc_setup_clocksource()
338 err = clk_prepare_enable(ttccs->ttc.clk); in ttc_setup_clocksource()
344 ttccs->ttc.freq = clk_get_rate(ttccs->ttc.clk); in ttc_setup_clocksource()
346 ttccs->ttc.clk_rate_change_nb.notifier_call = in ttc_setup_clocksource()
348 ttccs->ttc.clk_rate_change_nb.next = NULL; in ttc_setup_clocksource()
350 err = clk_notifier_register(ttccs->ttc.clk, in ttc_setup_clocksource()
351 &ttccs->ttc.clk_rate_change_nb); in ttc_setup_clocksource()
355 ttccs->ttc.base_addr = base; in ttc_setup_clocksource()
356 ttccs->cs.name = "ttc_clocksource"; in ttc_setup_clocksource()
357 ttccs->cs.rating = 200; in ttc_setup_clocksource()
358 ttccs->cs.read = __ttc_clocksource_read; in ttc_setup_clocksource()
359 ttccs->cs.mask = CLOCKSOURCE_MASK(timer_width); in ttc_setup_clocksource()
360 ttccs->cs.flags = CLOCK_SOURCE_IS_CONTINUOUS; in ttc_setup_clocksource()
363 * Setup the clock source counter to be an incrementing counter in ttc_setup_clocksource()
364 * with no interrupt and it rolls over at 0xFFFF. Pre-scale in ttc_setup_clocksource()
367 writel_relaxed(0x0, ttccs->ttc.base_addr + TTC_IER_OFFSET); in ttc_setup_clocksource()
369 ttccs->ttc.base_addr + TTC_CLK_CNTRL_OFFSET); in ttc_setup_clocksource()
371 ttccs->ttc.base_addr + TTC_CNT_CNTRL_OFFSET); in ttc_setup_clocksource()
373 err = clocksource_register_hz(&ttccs->cs, ttccs->ttc.freq / PRESCALE); in ttc_setup_clocksource()
381 ttccs->ttc.freq / PRESCALE); in ttc_setup_clocksource()
397 ttc->freq = ndata->new_rate; in ttc_rate_change_clockevent_cb()
399 clockevents_update_freq(&ttcce->ce, ndata->new_rate / PRESCALE); in ttc_rate_change_clockevent_cb()
409 static int __init ttc_setup_clockevent(struct clk *clk, in ttc_setup_clockevent() argument
417 return -ENOMEM; in ttc_setup_clockevent()
419 ttcce->ttc.clk = clk; in ttc_setup_clockevent()
421 err = clk_prepare_enable(ttcce->ttc.clk); in ttc_setup_clockevent()
427 ttcce->ttc.clk_rate_change_nb.notifier_call = in ttc_setup_clockevent()
429 ttcce->ttc.clk_rate_change_nb.next = NULL; in ttc_setup_clockevent()
431 err = clk_notifier_register(ttcce->ttc.clk, in ttc_setup_clockevent()
432 &ttcce->ttc.clk_rate_change_nb); in ttc_setup_clockevent()
438 ttcce->ttc.freq = clk_get_rate(ttcce->ttc.clk); in ttc_setup_clockevent()
440 ttcce->ttc.base_addr = base; in ttc_setup_clockevent()
441 ttcce->ce.name = "ttc_clockevent"; in ttc_setup_clockevent()
442 ttcce->ce.features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT; in ttc_setup_clockevent()
443 ttcce->ce.set_next_event = ttc_set_next_event; in ttc_setup_clockevent()
444 ttcce->ce.set_state_shutdown = ttc_shutdown; in ttc_setup_clockevent()
445 ttcce->ce.set_state_periodic = ttc_set_periodic; in ttc_setup_clockevent()
446 ttcce->ce.set_state_oneshot = ttc_shutdown; in ttc_setup_clockevent()
447 ttcce->ce.tick_resume = ttc_resume; in ttc_setup_clockevent()
448 ttcce->ce.rating = 200; in ttc_setup_clockevent()
449 ttcce->ce.irq = irq; in ttc_setup_clockevent()
450 ttcce->ce.cpumask = cpu_possible_mask; in ttc_setup_clockevent()
457 writel_relaxed(0x23, ttcce->ttc.base_addr + TTC_CNT_CNTRL_OFFSET); in ttc_setup_clockevent()
459 ttcce->ttc.base_addr + TTC_CLK_CNTRL_OFFSET); in ttc_setup_clockevent()
460 writel_relaxed(0x1, ttcce->ttc.base_addr + TTC_IER_OFFSET); in ttc_setup_clockevent()
463 IRQF_TIMER, ttcce->ce.name, ttcce); in ttc_setup_clockevent()
469 clockevents_config_and_register(&ttcce->ce, in ttc_setup_clockevent()
470 ttcce->ttc.freq / PRESCALE, 1, 0xfffe); in ttc_setup_clockevent()
476 * ttc_timer_init - Initialize the timer
478 * Initializes the timer hardware and register the clock source and clock event
485 struct clk *clk_cs, *clk_ce; in ttc_timer_init()
503 return -ENXIO; in ttc_timer_init()
509 return -EINVAL; in ttc_timer_init()
512 of_property_read_u32(timer, "timer-width", &timer_width); in ttc_timer_init()
538 pr_info("%s #0 at %p, irq=%d\n", timer->name, timer_baseaddr, irq); in ttc_timer_init()