Lines Matching full:timer
50 #include <clocksource/timer-ti-dm.h>
64 * omap_dm_timer_read_reg - read timer registers in posted and non-posted mode
65 * @timer: timer pointer over which read operation to perform
72 static inline u32 omap_dm_timer_read_reg(struct omap_dm_timer *timer, u32 reg) in omap_dm_timer_read_reg() argument
75 return __omap_dm_timer_read(timer, reg, timer->posted); in omap_dm_timer_read_reg()
79 * omap_dm_timer_write_reg - write timer registers in posted and non-posted mode
80 * @timer: timer pointer over which write operation is to perform
88 static void omap_dm_timer_write_reg(struct omap_dm_timer *timer, u32 reg, in omap_dm_timer_write_reg() argument
92 __omap_dm_timer_write(timer, reg, value, timer->posted); in omap_dm_timer_write_reg()
95 static void omap_timer_restore_context(struct omap_dm_timer *timer) in omap_timer_restore_context() argument
97 omap_dm_timer_write_reg(timer, OMAP_TIMER_WAKEUP_EN_REG, in omap_timer_restore_context()
98 timer->context.twer); in omap_timer_restore_context()
99 omap_dm_timer_write_reg(timer, OMAP_TIMER_COUNTER_REG, in omap_timer_restore_context()
100 timer->context.tcrr); in omap_timer_restore_context()
101 omap_dm_timer_write_reg(timer, OMAP_TIMER_LOAD_REG, in omap_timer_restore_context()
102 timer->context.tldr); in omap_timer_restore_context()
103 omap_dm_timer_write_reg(timer, OMAP_TIMER_MATCH_REG, in omap_timer_restore_context()
104 timer->context.tmar); in omap_timer_restore_context()
105 omap_dm_timer_write_reg(timer, OMAP_TIMER_IF_CTRL_REG, in omap_timer_restore_context()
106 timer->context.tsicr); in omap_timer_restore_context()
107 writel_relaxed(timer->context.tier, timer->irq_ena); in omap_timer_restore_context()
108 omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, in omap_timer_restore_context()
109 timer->context.tclr); in omap_timer_restore_context()
112 static int omap_dm_timer_reset(struct omap_dm_timer *timer) in omap_dm_timer_reset() argument
116 if (timer->revision != 1) in omap_dm_timer_reset()
119 omap_dm_timer_write_reg(timer, OMAP_TIMER_IF_CTRL_REG, 0x06); in omap_dm_timer_reset()
122 l = __omap_dm_timer_read(timer, in omap_dm_timer_reset()
127 dev_err(&timer->pdev->dev, "Timer failed to reset\n"); in omap_dm_timer_reset()
131 /* Configure timer for smart-idle mode */ in omap_dm_timer_reset()
132 l = __omap_dm_timer_read(timer, OMAP_TIMER_OCP_CFG_OFFSET, 0); in omap_dm_timer_reset()
134 __omap_dm_timer_write(timer, OMAP_TIMER_OCP_CFG_OFFSET, l, 0); in omap_dm_timer_reset()
136 timer->posted = 0; in omap_dm_timer_reset()
141 static int omap_dm_timer_of_set_source(struct omap_dm_timer *timer) in omap_dm_timer_of_set_source() argument
150 if (!timer->fclk) in omap_dm_timer_of_set_source()
153 parent = clk_get(&timer->pdev->dev, NULL); in omap_dm_timer_of_set_source()
158 if (clk_is_match(parent, timer->fclk)) in omap_dm_timer_of_set_source()
161 ret = clk_set_parent(timer->fclk, parent); in omap_dm_timer_of_set_source()
170 static int omap_dm_timer_set_source(struct omap_dm_timer *timer, int source) in omap_dm_timer_set_source() argument
177 if (unlikely(!timer) || IS_ERR(timer->fclk)) in omap_dm_timer_set_source()
194 pdata = timer->pdev->dev.platform_data; in omap_dm_timer_set_source()
202 return pdata->set_timer_src(timer->pdev, source); in omap_dm_timer_set_source()
206 if (clk_hw_get_num_parents(__clk_get_hw(timer->fclk)) < 2) in omap_dm_timer_set_source()
210 parent = clk_get(&timer->pdev->dev, parent_name); in omap_dm_timer_set_source()
216 ret = clk_set_parent(timer->fclk, parent); in omap_dm_timer_set_source()
226 static void omap_dm_timer_enable(struct omap_dm_timer *timer) in omap_dm_timer_enable() argument
230 pm_runtime_get_sync(&timer->pdev->dev); in omap_dm_timer_enable()
232 if (!(timer->capability & OMAP_TIMER_ALWON)) { in omap_dm_timer_enable()
233 if (timer->get_context_loss_count) { in omap_dm_timer_enable()
234 c = timer->get_context_loss_count(&timer->pdev->dev); in omap_dm_timer_enable()
235 if (c != timer->ctx_loss_count) { in omap_dm_timer_enable()
236 omap_timer_restore_context(timer); in omap_dm_timer_enable()
237 timer->ctx_loss_count = c; in omap_dm_timer_enable()
240 omap_timer_restore_context(timer); in omap_dm_timer_enable()
245 static void omap_dm_timer_disable(struct omap_dm_timer *timer) in omap_dm_timer_disable() argument
247 pm_runtime_put_sync(&timer->pdev->dev); in omap_dm_timer_disable()
250 static int omap_dm_timer_prepare(struct omap_dm_timer *timer) in omap_dm_timer_prepare() argument
258 if (!(timer->capability & OMAP_TIMER_NEEDS_RESET)) { in omap_dm_timer_prepare()
259 timer->fclk = clk_get(&timer->pdev->dev, "fck"); in omap_dm_timer_prepare()
260 if (WARN_ON_ONCE(IS_ERR(timer->fclk))) { in omap_dm_timer_prepare()
261 dev_err(&timer->pdev->dev, ": No fclk handle.\n"); in omap_dm_timer_prepare()
266 omap_dm_timer_enable(timer); in omap_dm_timer_prepare()
268 if (timer->capability & OMAP_TIMER_NEEDS_RESET) { in omap_dm_timer_prepare()
269 rc = omap_dm_timer_reset(timer); in omap_dm_timer_prepare()
271 omap_dm_timer_disable(timer); in omap_dm_timer_prepare()
276 __omap_dm_timer_enable_posted(timer); in omap_dm_timer_prepare()
277 omap_dm_timer_disable(timer); in omap_dm_timer_prepare()
279 rc = omap_dm_timer_of_set_source(timer); in omap_dm_timer_prepare()
281 return omap_dm_timer_set_source(timer, OMAP_TIMER_SRC_32_KHZ); in omap_dm_timer_prepare()
303 struct omap_dm_timer *timer = NULL, *t; in _omap_dm_timer_request() local
332 timer = t; in _omap_dm_timer_request()
333 timer->reserved = 1; in _omap_dm_timer_request()
340 * If timer is not NULL, we have already found in _omap_dm_timer_request()
341 * one timer. But it was not an exact match in _omap_dm_timer_request()
344 * timer found and see if this one is a better in _omap_dm_timer_request()
347 if (timer) in _omap_dm_timer_request()
348 timer->reserved = 0; in _omap_dm_timer_request()
349 timer = t; in _omap_dm_timer_request()
350 timer->reserved = 1; in _omap_dm_timer_request()
359 timer = t; in _omap_dm_timer_request()
360 timer->reserved = 1; in _omap_dm_timer_request()
366 timer = t; in _omap_dm_timer_request()
367 timer->reserved = 1; in _omap_dm_timer_request()
374 if (timer && omap_dm_timer_prepare(timer)) { in _omap_dm_timer_request()
375 timer->reserved = 0; in _omap_dm_timer_request()
376 timer = NULL; in _omap_dm_timer_request()
379 if (!timer) in _omap_dm_timer_request()
380 pr_debug("%s: timer request failed!\n", __func__); in _omap_dm_timer_request()
382 return timer; in _omap_dm_timer_request()
392 /* Requesting timer by ID is not supported when device tree is used */ in omap_dm_timer_request_specific()
403 * omap_dm_timer_request_by_cap - Request a timer by capability
406 * Find a timer based upon capabilities bit mask. Callers of this function
408 * comment "timer capabilities used in hwmod database". Returns pointer to
409 * timer handle on success and a NULL pointer on failure.
417 * omap_dm_timer_request_by_node - Request a timer by device-tree node
418 * @np: Pointer to device-tree timer node
420 * Request a timer based upon a device node pointer. Returns pointer to
421 * timer handle on success and a NULL pointer on failure.
431 static int omap_dm_timer_free(struct omap_dm_timer *timer) in omap_dm_timer_free() argument
433 if (unlikely(!timer)) in omap_dm_timer_free()
436 clk_put(timer->fclk); in omap_dm_timer_free()
438 WARN_ON(!timer->reserved); in omap_dm_timer_free()
439 timer->reserved = 0; in omap_dm_timer_free()
443 int omap_dm_timer_get_irq(struct omap_dm_timer *timer) in omap_dm_timer_get_irq() argument
445 if (timer) in omap_dm_timer_get_irq()
446 return timer->irq; in omap_dm_timer_get_irq()
453 static struct clk *omap_dm_timer_get_fclk(struct omap_dm_timer *timer) in omap_dm_timer_get_fclk() argument
465 struct omap_dm_timer *timer = NULL; in omap_dm_timer_modify_idlect_mask() local
472 /* If any active timer is using ARMXOR return modified mask */ in omap_dm_timer_modify_idlect_mask()
474 list_for_each_entry(timer, &omap_timer_list, node) { in omap_dm_timer_modify_idlect_mask()
477 l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG); in omap_dm_timer_modify_idlect_mask()
493 static struct clk *omap_dm_timer_get_fclk(struct omap_dm_timer *timer) in omap_dm_timer_get_fclk() argument
495 if (timer && !IS_ERR(timer->fclk)) in omap_dm_timer_get_fclk()
496 return timer->fclk; in omap_dm_timer_get_fclk()
509 int omap_dm_timer_trigger(struct omap_dm_timer *timer) in omap_dm_timer_trigger() argument
511 if (unlikely(!timer || pm_runtime_suspended(&timer->pdev->dev))) { in omap_dm_timer_trigger()
512 pr_err("%s: timer not available or enabled.\n", __func__); in omap_dm_timer_trigger()
516 omap_dm_timer_write_reg(timer, OMAP_TIMER_TRIGGER_REG, 0); in omap_dm_timer_trigger()
520 static int omap_dm_timer_start(struct omap_dm_timer *timer) in omap_dm_timer_start() argument
524 if (unlikely(!timer)) in omap_dm_timer_start()
527 omap_dm_timer_enable(timer); in omap_dm_timer_start()
529 l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG); in omap_dm_timer_start()
532 omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l); in omap_dm_timer_start()
536 timer->context.tclr = l; in omap_dm_timer_start()
540 static int omap_dm_timer_stop(struct omap_dm_timer *timer) in omap_dm_timer_stop() argument
544 if (unlikely(!timer)) in omap_dm_timer_stop()
547 if (!(timer->capability & OMAP_TIMER_NEEDS_RESET)) in omap_dm_timer_stop()
548 rate = clk_get_rate(timer->fclk); in omap_dm_timer_stop()
550 __omap_dm_timer_stop(timer, timer->posted, rate); in omap_dm_timer_stop()
557 timer->context.tclr = in omap_dm_timer_stop()
558 omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG); in omap_dm_timer_stop()
559 omap_dm_timer_disable(timer); in omap_dm_timer_stop()
563 static int omap_dm_timer_set_load(struct omap_dm_timer *timer, int autoreload, in omap_dm_timer_set_load() argument
568 if (unlikely(!timer)) in omap_dm_timer_set_load()
571 omap_dm_timer_enable(timer); in omap_dm_timer_set_load()
572 l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG); in omap_dm_timer_set_load()
577 omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l); in omap_dm_timer_set_load()
578 omap_dm_timer_write_reg(timer, OMAP_TIMER_LOAD_REG, load); in omap_dm_timer_set_load()
580 omap_dm_timer_write_reg(timer, OMAP_TIMER_TRIGGER_REG, 0); in omap_dm_timer_set_load()
582 timer->context.tclr = l; in omap_dm_timer_set_load()
583 timer->context.tldr = load; in omap_dm_timer_set_load()
584 omap_dm_timer_disable(timer); in omap_dm_timer_set_load()
589 int omap_dm_timer_set_load_start(struct omap_dm_timer *timer, int autoreload, in omap_dm_timer_set_load_start() argument
594 if (unlikely(!timer)) in omap_dm_timer_set_load_start()
597 omap_dm_timer_enable(timer); in omap_dm_timer_set_load_start()
599 l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG); in omap_dm_timer_set_load_start()
602 omap_dm_timer_write_reg(timer, OMAP_TIMER_LOAD_REG, load); in omap_dm_timer_set_load_start()
608 __omap_dm_timer_load_start(timer, l, load, timer->posted); in omap_dm_timer_set_load_start()
611 timer->context.tclr = l; in omap_dm_timer_set_load_start()
612 timer->context.tldr = load; in omap_dm_timer_set_load_start()
613 timer->context.tcrr = load; in omap_dm_timer_set_load_start()
616 static int omap_dm_timer_set_match(struct omap_dm_timer *timer, int enable, in omap_dm_timer_set_match() argument
621 if (unlikely(!timer)) in omap_dm_timer_set_match()
624 omap_dm_timer_enable(timer); in omap_dm_timer_set_match()
625 l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG); in omap_dm_timer_set_match()
630 omap_dm_timer_write_reg(timer, OMAP_TIMER_MATCH_REG, match); in omap_dm_timer_set_match()
631 omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l); in omap_dm_timer_set_match()
634 timer->context.tclr = l; in omap_dm_timer_set_match()
635 timer->context.tmar = match; in omap_dm_timer_set_match()
636 omap_dm_timer_disable(timer); in omap_dm_timer_set_match()
640 static int omap_dm_timer_set_pwm(struct omap_dm_timer *timer, int def_on, in omap_dm_timer_set_pwm() argument
645 if (unlikely(!timer)) in omap_dm_timer_set_pwm()
648 omap_dm_timer_enable(timer); in omap_dm_timer_set_pwm()
649 l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG); in omap_dm_timer_set_pwm()
657 omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l); in omap_dm_timer_set_pwm()
660 timer->context.tclr = l; in omap_dm_timer_set_pwm()
661 omap_dm_timer_disable(timer); in omap_dm_timer_set_pwm()
665 static int omap_dm_timer_set_prescaler(struct omap_dm_timer *timer, in omap_dm_timer_set_prescaler() argument
670 if (unlikely(!timer) || prescaler < -1 || prescaler > 7) in omap_dm_timer_set_prescaler()
673 omap_dm_timer_enable(timer); in omap_dm_timer_set_prescaler()
674 l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG); in omap_dm_timer_set_prescaler()
680 omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l); in omap_dm_timer_set_prescaler()
683 timer->context.tclr = l; in omap_dm_timer_set_prescaler()
684 omap_dm_timer_disable(timer); in omap_dm_timer_set_prescaler()
688 static int omap_dm_timer_set_int_enable(struct omap_dm_timer *timer, in omap_dm_timer_set_int_enable() argument
691 if (unlikely(!timer)) in omap_dm_timer_set_int_enable()
694 omap_dm_timer_enable(timer); in omap_dm_timer_set_int_enable()
695 __omap_dm_timer_int_enable(timer, value); in omap_dm_timer_set_int_enable()
698 timer->context.tier = value; in omap_dm_timer_set_int_enable()
699 timer->context.twer = value; in omap_dm_timer_set_int_enable()
700 omap_dm_timer_disable(timer); in omap_dm_timer_set_int_enable()
705 * omap_dm_timer_set_int_disable - disable timer interrupts
706 * @timer: pointer to timer handle
709 * Disables the specified timer interrupts for a timer.
711 static int omap_dm_timer_set_int_disable(struct omap_dm_timer *timer, u32 mask) in omap_dm_timer_set_int_disable() argument
715 if (unlikely(!timer)) in omap_dm_timer_set_int_disable()
718 omap_dm_timer_enable(timer); in omap_dm_timer_set_int_disable()
720 if (timer->revision == 1) in omap_dm_timer_set_int_disable()
721 l = readl_relaxed(timer->irq_ena) & ~mask; in omap_dm_timer_set_int_disable()
723 writel_relaxed(l, timer->irq_dis); in omap_dm_timer_set_int_disable()
724 l = omap_dm_timer_read_reg(timer, OMAP_TIMER_WAKEUP_EN_REG) & ~mask; in omap_dm_timer_set_int_disable()
725 omap_dm_timer_write_reg(timer, OMAP_TIMER_WAKEUP_EN_REG, l); in omap_dm_timer_set_int_disable()
728 timer->context.tier &= ~mask; in omap_dm_timer_set_int_disable()
729 timer->context.twer &= ~mask; in omap_dm_timer_set_int_disable()
730 omap_dm_timer_disable(timer); in omap_dm_timer_set_int_disable()
734 static unsigned int omap_dm_timer_read_status(struct omap_dm_timer *timer) in omap_dm_timer_read_status() argument
738 if (unlikely(!timer || pm_runtime_suspended(&timer->pdev->dev))) { in omap_dm_timer_read_status()
739 pr_err("%s: timer not available or enabled.\n", __func__); in omap_dm_timer_read_status()
743 l = readl_relaxed(timer->irq_stat); in omap_dm_timer_read_status()
748 static int omap_dm_timer_write_status(struct omap_dm_timer *timer, unsigned int value) in omap_dm_timer_write_status() argument
750 if (unlikely(!timer || pm_runtime_suspended(&timer->pdev->dev))) in omap_dm_timer_write_status()
753 __omap_dm_timer_write_status(timer, value); in omap_dm_timer_write_status()
758 static unsigned int omap_dm_timer_read_counter(struct omap_dm_timer *timer) in omap_dm_timer_read_counter() argument
760 if (unlikely(!timer || pm_runtime_suspended(&timer->pdev->dev))) { in omap_dm_timer_read_counter()
761 pr_err("%s: timer not iavailable or enabled.\n", __func__); in omap_dm_timer_read_counter()
765 return __omap_dm_timer_read_counter(timer, timer->posted); in omap_dm_timer_read_counter()
768 static int omap_dm_timer_write_counter(struct omap_dm_timer *timer, unsigned int value) in omap_dm_timer_write_counter() argument
770 if (unlikely(!timer || pm_runtime_suspended(&timer->pdev->dev))) { in omap_dm_timer_write_counter()
771 pr_err("%s: timer not available or enabled.\n", __func__); in omap_dm_timer_write_counter()
775 omap_dm_timer_write_reg(timer, OMAP_TIMER_COUNTER_REG, value); in omap_dm_timer_write_counter()
778 timer->context.tcrr = value; in omap_dm_timer_write_counter()
784 struct omap_dm_timer *timer; in omap_dm_timers_active() local
786 list_for_each_entry(timer, &omap_timer_list, node) { in omap_dm_timers_active()
787 if (!timer->reserved) in omap_dm_timers_active()
790 if (omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG) & in omap_dm_timers_active()
802 * @pdev: pointer to current timer platform device
805 * timer devices.
810 struct omap_dm_timer *timer; in omap_dm_timer_probe() local
839 timer = devm_kzalloc(dev, sizeof(*timer), GFP_KERNEL); in omap_dm_timer_probe()
840 if (!timer) in omap_dm_timer_probe()
843 timer->fclk = ERR_PTR(-ENODEV); in omap_dm_timer_probe()
844 timer->io_base = devm_ioremap_resource(dev, mem); in omap_dm_timer_probe()
845 if (IS_ERR(timer->io_base)) in omap_dm_timer_probe()
846 return PTR_ERR(timer->io_base); in omap_dm_timer_probe()
849 if (of_find_property(dev->of_node, "ti,timer-alwon", NULL)) in omap_dm_timer_probe()
850 timer->capability |= OMAP_TIMER_ALWON; in omap_dm_timer_probe()
851 if (of_find_property(dev->of_node, "ti,timer-dsp", NULL)) in omap_dm_timer_probe()
852 timer->capability |= OMAP_TIMER_HAS_DSP_IRQ; in omap_dm_timer_probe()
853 if (of_find_property(dev->of_node, "ti,timer-pwm", NULL)) in omap_dm_timer_probe()
854 timer->capability |= OMAP_TIMER_HAS_PWM; in omap_dm_timer_probe()
855 if (of_find_property(dev->of_node, "ti,timer-secure", NULL)) in omap_dm_timer_probe()
856 timer->capability |= OMAP_TIMER_SECURE; in omap_dm_timer_probe()
858 timer->id = pdev->id; in omap_dm_timer_probe()
859 timer->capability = pdata->timer_capability; in omap_dm_timer_probe()
860 timer->reserved = omap_dm_timer_reserved_systimer(timer->id); in omap_dm_timer_probe()
861 timer->get_context_loss_count = pdata->get_context_loss_count; in omap_dm_timer_probe()
865 timer->errata = pdata->timer_errata; in omap_dm_timer_probe()
867 timer->irq = irq->start; in omap_dm_timer_probe()
868 timer->pdev = pdev; in omap_dm_timer_probe()
872 if (!timer->reserved) { in omap_dm_timer_probe()
879 __omap_dm_timer_init_regs(timer); in omap_dm_timer_probe()
883 /* add the timer element to the list */ in omap_dm_timer_probe()
885 list_add_tail(&timer->node, &omap_timer_list); in omap_dm_timer_probe()
899 * omap_dm_timer_remove - cleanup a registered timer device
900 * @pdev: pointer to current timer platform device
902 * Called by driver framework whenever a timer device is unregistered.
903 * In addition to freeing platform resources it also deletes the timer
908 struct omap_dm_timer *timer; in omap_dm_timer_remove() local
913 list_for_each_entry(timer, &omap_timer_list, node) in omap_dm_timer_remove()
914 if (!strcmp(dev_name(&timer->pdev->dev), in omap_dm_timer_remove()
916 list_del(&timer->node); in omap_dm_timer_remove()
958 .compatible = "ti,omap2420-timer",
961 .compatible = "ti,omap3430-timer",
965 .compatible = "ti,omap4430-timer",
969 .compatible = "ti,omap5430-timer",
973 .compatible = "ti,am335x-timer",
977 .compatible = "ti,am335x-timer-1ms",
981 .compatible = "ti,dm816-timer",
1000 MODULE_DESCRIPTION("OMAP Dual-Mode Timer Driver");