Lines Matching +full:re +full:- +full:clocked
1 // SPDX-License-Identifier: GPL-2.0-only
5 * Copyright (C) 2011-2013 Xilinx
23 * This driver configures the 2 16/32-bit count-up timers as follows:
30 * common to all the timer channels (T1, T2, and T3). With a pre-scaler of 32,
31 * the timers are clocked at 78.125KHz (12.8 us resolution).
34 * obtained from device tree. The pre-scaler of 32 is used.
55 * Setup the timers to use pre-scaling, using a fixed value for now that will
60 #define CLK_CNTRL_PRESCALE ((PRESCALE_EXPONENT - 1) << 1)
67 * struct ttc_timer - This definition defines local timer structure
105 * ttc_set_interval - Set the timer interval value
115 /* Disable the counter, set the counter value and re-enable counter */ in ttc_set_interval()
116 ctrl_reg = readl_relaxed(timer->base_addr + TTC_CNT_CNTRL_OFFSET); in ttc_set_interval()
118 writel_relaxed(ctrl_reg, timer->base_addr + TTC_CNT_CNTRL_OFFSET); in ttc_set_interval()
120 writel_relaxed(cycles, timer->base_addr + TTC_INTR_VAL_OFFSET); in ttc_set_interval()
123 * Reset the counter (0x10) so that it starts from 0, one-shot in ttc_set_interval()
128 writel_relaxed(ctrl_reg, timer->base_addr + TTC_CNT_CNTRL_OFFSET); in ttc_set_interval()
132 * ttc_clock_event_interrupt - Clock event timer interrupt handler
137 * Returns: Always IRQ_HANDLED - success
142 struct ttc_timer *timer = &ttce->ttc; in ttc_clock_event_interrupt()
145 readl_relaxed(timer->base_addr + TTC_ISR_OFFSET); in ttc_clock_event_interrupt()
147 ttce->ce.event_handler(&ttce->ce); in ttc_clock_event_interrupt()
153 * __ttc_clocksource_read - Reads the timer counter register
160 struct ttc_timer *timer = &to_ttc_timer_clksrc(cs)->ttc; in __ttc_clocksource_read()
162 return (u64)readl_relaxed(timer->base_addr + in __ttc_clocksource_read()
172 * ttc_set_next_event - Sets the time interval for next event
177 * Returns: Always %0 - success
183 struct ttc_timer *timer = &ttce->ttc; in ttc_set_next_event()
190 * ttc_shutdown - Sets the state of timer
195 * Returns: Always %0 - success
200 struct ttc_timer *timer = &ttce->ttc; in ttc_shutdown()
203 ctrl_reg = readl_relaxed(timer->base_addr + TTC_CNT_CNTRL_OFFSET); in ttc_shutdown()
205 writel_relaxed(ctrl_reg, timer->base_addr + TTC_CNT_CNTRL_OFFSET); in ttc_shutdown()
210 * ttc_set_periodic - Sets the state of timer
213 * Returns: Always %0 - success
218 struct ttc_timer *timer = &ttce->ttc; in ttc_set_periodic()
221 DIV_ROUND_CLOSEST(ttce->ttc.freq, PRESCALE * HZ)); in ttc_set_periodic()
228 struct ttc_timer *timer = &ttce->ttc; in ttc_resume()
231 ctrl_reg = readl_relaxed(timer->base_addr + TTC_CNT_CNTRL_OFFSET); in ttc_resume()
233 writel_relaxed(ctrl_reg, timer->base_addr + TTC_CNT_CNTRL_OFFSET); in ttc_resume()
251 if (ndata->new_rate > ndata->old_rate) { in ttc_rate_change_clocksource_cb()
252 factor = DIV_ROUND_CLOSEST(ndata->new_rate, in ttc_rate_change_clocksource_cb()
253 ndata->old_rate); in ttc_rate_change_clocksource_cb()
254 rate_low = ndata->old_rate; in ttc_rate_change_clocksource_cb()
255 rate_high = ndata->new_rate; in ttc_rate_change_clocksource_cb()
257 factor = DIV_ROUND_CLOSEST(ndata->old_rate, in ttc_rate_change_clocksource_cb()
258 ndata->new_rate); in ttc_rate_change_clocksource_cb()
259 rate_low = ndata->new_rate; in ttc_rate_change_clocksource_cb()
260 rate_high = ndata->old_rate; in ttc_rate_change_clocksource_cb()
266 if (abs(rate_high - (factor * rate_low)) > MAX_F_ERR) in ttc_rate_change_clocksource_cb()
275 ttccs->scale_clk_ctrl_reg_old = in ttc_rate_change_clocksource_cb()
276 readl_relaxed(ttccs->ttc.base_addr + in ttc_rate_change_clocksource_cb()
279 psv = (ttccs->scale_clk_ctrl_reg_old & in ttc_rate_change_clocksource_cb()
282 if (ndata->new_rate < ndata->old_rate) in ttc_rate_change_clocksource_cb()
283 psv -= factor; in ttc_rate_change_clocksource_cb()
291 ttccs->scale_clk_ctrl_reg_new = ttccs->scale_clk_ctrl_reg_old & in ttc_rate_change_clocksource_cb()
293 ttccs->scale_clk_ctrl_reg_new |= psv << TTC_CLK_CNTRL_PSV_SHIFT; in ttc_rate_change_clocksource_cb()
296 /* scale down: adjust divider in post-change notification */ in ttc_rate_change_clocksource_cb()
297 if (ndata->new_rate < ndata->old_rate) in ttc_rate_change_clocksource_cb()
300 /* scale up: adjust divider now - before frequency change */ in ttc_rate_change_clocksource_cb()
301 writel_relaxed(ttccs->scale_clk_ctrl_reg_new, in ttc_rate_change_clocksource_cb()
302 ttccs->ttc.base_addr + TTC_CLK_CNTRL_OFFSET); in ttc_rate_change_clocksource_cb()
306 /* scale up: pre-change notification did the adjustment */ in ttc_rate_change_clocksource_cb()
307 if (ndata->new_rate > ndata->old_rate) in ttc_rate_change_clocksource_cb()
310 /* scale down: adjust divider now - after frequency change */ in ttc_rate_change_clocksource_cb()
311 writel_relaxed(ttccs->scale_clk_ctrl_reg_new, in ttc_rate_change_clocksource_cb()
312 ttccs->ttc.base_addr + TTC_CLK_CNTRL_OFFSET); in ttc_rate_change_clocksource_cb()
317 if (ndata->new_rate < ndata->old_rate) in ttc_rate_change_clocksource_cb()
321 writel_relaxed(ttccs->scale_clk_ctrl_reg_old, in ttc_rate_change_clocksource_cb()
322 ttccs->ttc.base_addr + TTC_CLK_CNTRL_OFFSET); in ttc_rate_change_clocksource_cb()
339 return -ENOMEM; in ttc_setup_clocksource()
341 ttccs->ttc.clk = clk; in ttc_setup_clocksource()
343 err = clk_prepare_enable(ttccs->ttc.clk); in ttc_setup_clocksource()
349 ttccs->ttc.freq = clk_get_rate(ttccs->ttc.clk); in ttc_setup_clocksource()
351 ttccs->ttc.clk_rate_change_nb.notifier_call = in ttc_setup_clocksource()
353 ttccs->ttc.clk_rate_change_nb.next = NULL; in ttc_setup_clocksource()
355 err = clk_notifier_register(ttccs->ttc.clk, in ttc_setup_clocksource()
356 &ttccs->ttc.clk_rate_change_nb); in ttc_setup_clocksource()
360 ttccs->ttc.base_addr = base; in ttc_setup_clocksource()
361 ttccs->cs.name = "ttc_clocksource"; in ttc_setup_clocksource()
362 ttccs->cs.rating = 200; in ttc_setup_clocksource()
363 ttccs->cs.read = __ttc_clocksource_read; in ttc_setup_clocksource()
364 ttccs->cs.mask = CLOCKSOURCE_MASK(timer_width); in ttc_setup_clocksource()
365 ttccs->cs.flags = CLOCK_SOURCE_IS_CONTINUOUS; in ttc_setup_clocksource()
369 * with no interrupt and it rolls over at 0xFFFF. Pre-scale in ttc_setup_clocksource()
372 writel_relaxed(0x0, ttccs->ttc.base_addr + TTC_IER_OFFSET); in ttc_setup_clocksource()
374 ttccs->ttc.base_addr + TTC_CLK_CNTRL_OFFSET); in ttc_setup_clocksource()
376 ttccs->ttc.base_addr + TTC_CNT_CNTRL_OFFSET); in ttc_setup_clocksource()
378 err = clocksource_register_hz(&ttccs->cs, ttccs->ttc.freq / PRESCALE); in ttc_setup_clocksource()
386 ttccs->ttc.freq / PRESCALE); in ttc_setup_clocksource()
402 ttc->freq = ndata->new_rate; in ttc_rate_change_clockevent_cb()
404 clockevents_update_freq(&ttcce->ce, ndata->new_rate / PRESCALE); in ttc_rate_change_clockevent_cb()
422 return -ENOMEM; in ttc_setup_clockevent()
424 ttcce->ttc.clk = clk; in ttc_setup_clockevent()
426 err = clk_prepare_enable(ttcce->ttc.clk); in ttc_setup_clockevent()
430 ttcce->ttc.clk_rate_change_nb.notifier_call = in ttc_setup_clockevent()
432 ttcce->ttc.clk_rate_change_nb.next = NULL; in ttc_setup_clockevent()
434 err = clk_notifier_register(ttcce->ttc.clk, in ttc_setup_clockevent()
435 &ttcce->ttc.clk_rate_change_nb); in ttc_setup_clockevent()
441 ttcce->ttc.freq = clk_get_rate(ttcce->ttc.clk); in ttc_setup_clockevent()
443 ttcce->ttc.base_addr = base; in ttc_setup_clockevent()
444 ttcce->ce.name = "ttc_clockevent"; in ttc_setup_clockevent()
445 ttcce->ce.features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT; in ttc_setup_clockevent()
446 ttcce->ce.set_next_event = ttc_set_next_event; in ttc_setup_clockevent()
447 ttcce->ce.set_state_shutdown = ttc_shutdown; in ttc_setup_clockevent()
448 ttcce->ce.set_state_periodic = ttc_set_periodic; in ttc_setup_clockevent()
449 ttcce->ce.set_state_oneshot = ttc_shutdown; in ttc_setup_clockevent()
450 ttcce->ce.tick_resume = ttc_resume; in ttc_setup_clockevent()
451 ttcce->ce.rating = 200; in ttc_setup_clockevent()
452 ttcce->ce.irq = irq; in ttc_setup_clockevent()
453 ttcce->ce.cpumask = cpu_possible_mask; in ttc_setup_clockevent()
460 writel_relaxed(0x23, ttcce->ttc.base_addr + TTC_CNT_CNTRL_OFFSET); in ttc_setup_clockevent()
462 ttcce->ttc.base_addr + TTC_CLK_CNTRL_OFFSET); in ttc_setup_clockevent()
463 writel_relaxed(0x1, ttcce->ttc.base_addr + TTC_IER_OFFSET); in ttc_setup_clockevent()
466 IRQF_TIMER, ttcce->ce.name, ttcce); in ttc_setup_clockevent()
470 clockevents_config_and_register(&ttcce->ce, in ttc_setup_clockevent()
471 ttcce->ttc.freq / PRESCALE, 1, 0xfffe); in ttc_setup_clockevent()
476 clk_disable_unprepare(ttcce->ttc.clk); in ttc_setup_clockevent()
490 struct device_node *timer = pdev->dev.of_node; in ttc_timer_probe()
502 timer_baseaddr = devm_of_iomap(&pdev->dev, timer, 0, NULL); in ttc_timer_probe()
511 return -EINVAL; in ttc_timer_probe()
514 of_property_read_u32(timer, "timer-width", &timer_width); in ttc_timer_probe()