Lines Matching full:timer

34 #include <clocksource/timer-ti-dm.h>
48 * omap_dm_timer_read_reg - read timer registers in posted and non-posted mode
49 * @timer: timer pointer over which read operation to perform
56 static inline u32 omap_dm_timer_read_reg(struct omap_dm_timer *timer, u32 reg) in omap_dm_timer_read_reg() argument
59 return __omap_dm_timer_read(timer, reg, timer->posted); in omap_dm_timer_read_reg()
63 * omap_dm_timer_write_reg - write timer registers in posted and non-posted mode
64 * @timer: timer pointer over which write operation is to perform
72 static void omap_dm_timer_write_reg(struct omap_dm_timer *timer, u32 reg, in omap_dm_timer_write_reg() argument
76 __omap_dm_timer_write(timer, reg, value, timer->posted); in omap_dm_timer_write_reg()
79 static void omap_timer_restore_context(struct omap_dm_timer *timer) in omap_timer_restore_context() argument
81 __omap_dm_timer_write(timer, OMAP_TIMER_OCP_CFG_OFFSET, in omap_timer_restore_context()
82 timer->context.ocp_cfg, 0); in omap_timer_restore_context()
84 omap_dm_timer_write_reg(timer, OMAP_TIMER_WAKEUP_EN_REG, in omap_timer_restore_context()
85 timer->context.twer); in omap_timer_restore_context()
86 omap_dm_timer_write_reg(timer, OMAP_TIMER_COUNTER_REG, in omap_timer_restore_context()
87 timer->context.tcrr); in omap_timer_restore_context()
88 omap_dm_timer_write_reg(timer, OMAP_TIMER_LOAD_REG, in omap_timer_restore_context()
89 timer->context.tldr); in omap_timer_restore_context()
90 omap_dm_timer_write_reg(timer, OMAP_TIMER_MATCH_REG, in omap_timer_restore_context()
91 timer->context.tmar); in omap_timer_restore_context()
92 omap_dm_timer_write_reg(timer, OMAP_TIMER_IF_CTRL_REG, in omap_timer_restore_context()
93 timer->context.tsicr); in omap_timer_restore_context()
94 writel_relaxed(timer->context.tier, timer->irq_ena); in omap_timer_restore_context()
95 omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, in omap_timer_restore_context()
96 timer->context.tclr); in omap_timer_restore_context()
99 static void omap_timer_save_context(struct omap_dm_timer *timer) in omap_timer_save_context() argument
101 timer->context.ocp_cfg = in omap_timer_save_context()
102 __omap_dm_timer_read(timer, OMAP_TIMER_OCP_CFG_OFFSET, 0); in omap_timer_save_context()
104 timer->context.tclr = in omap_timer_save_context()
105 omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG); in omap_timer_save_context()
106 timer->context.twer = in omap_timer_save_context()
107 omap_dm_timer_read_reg(timer, OMAP_TIMER_WAKEUP_EN_REG); in omap_timer_save_context()
108 timer->context.tldr = in omap_timer_save_context()
109 omap_dm_timer_read_reg(timer, OMAP_TIMER_LOAD_REG); in omap_timer_save_context()
110 timer->context.tmar = in omap_timer_save_context()
111 omap_dm_timer_read_reg(timer, OMAP_TIMER_MATCH_REG); in omap_timer_save_context()
112 timer->context.tier = readl_relaxed(timer->irq_ena); in omap_timer_save_context()
113 timer->context.tsicr = in omap_timer_save_context()
114 omap_dm_timer_read_reg(timer, OMAP_TIMER_IF_CTRL_REG); in omap_timer_save_context()
120 struct omap_dm_timer *timer; in omap_timer_context_notifier() local
122 timer = container_of(nb, struct omap_dm_timer, nb); in omap_timer_context_notifier()
126 if ((timer->capability & OMAP_TIMER_ALWON) || in omap_timer_context_notifier()
127 !atomic_read(&timer->enabled)) in omap_timer_context_notifier()
129 omap_timer_save_context(timer); in omap_timer_context_notifier()
134 if ((timer->capability & OMAP_TIMER_ALWON) || in omap_timer_context_notifier()
135 !atomic_read(&timer->enabled)) in omap_timer_context_notifier()
137 omap_timer_restore_context(timer); in omap_timer_context_notifier()
144 static int omap_dm_timer_reset(struct omap_dm_timer *timer) in omap_dm_timer_reset() argument
148 if (timer->revision != 1) in omap_dm_timer_reset()
151 omap_dm_timer_write_reg(timer, OMAP_TIMER_IF_CTRL_REG, 0x06); in omap_dm_timer_reset()
154 l = __omap_dm_timer_read(timer, in omap_dm_timer_reset()
159 dev_err(&timer->pdev->dev, "Timer failed to reset\n"); in omap_dm_timer_reset()
163 /* Configure timer for smart-idle mode */ in omap_dm_timer_reset()
164 l = __omap_dm_timer_read(timer, OMAP_TIMER_OCP_CFG_OFFSET, 0); in omap_dm_timer_reset()
166 __omap_dm_timer_write(timer, OMAP_TIMER_OCP_CFG_OFFSET, l, 0); in omap_dm_timer_reset()
168 timer->posted = 0; in omap_dm_timer_reset()
173 static int omap_dm_timer_set_source(struct omap_dm_timer *timer, int source) in omap_dm_timer_set_source() argument
180 if (unlikely(!timer) || IS_ERR(timer->fclk)) in omap_dm_timer_set_source()
197 pdata = timer->pdev->dev.platform_data; in omap_dm_timer_set_source()
205 return pdata->set_timer_src(timer->pdev, source); in omap_dm_timer_set_source()
209 if (clk_hw_get_num_parents(__clk_get_hw(timer->fclk)) < 2) in omap_dm_timer_set_source()
213 parent = clk_get(&timer->pdev->dev, parent_name); in omap_dm_timer_set_source()
219 ret = clk_set_parent(timer->fclk, parent); in omap_dm_timer_set_source()
229 static void omap_dm_timer_enable(struct omap_dm_timer *timer) in omap_dm_timer_enable() argument
231 pm_runtime_get_sync(&timer->pdev->dev); in omap_dm_timer_enable()
234 static void omap_dm_timer_disable(struct omap_dm_timer *timer) in omap_dm_timer_disable() argument
236 pm_runtime_put_sync(&timer->pdev->dev); in omap_dm_timer_disable()
239 static int omap_dm_timer_prepare(struct omap_dm_timer *timer) in omap_dm_timer_prepare() argument
247 if (!(timer->capability & OMAP_TIMER_NEEDS_RESET)) { in omap_dm_timer_prepare()
248 timer->fclk = clk_get(&timer->pdev->dev, "fck"); in omap_dm_timer_prepare()
249 if (WARN_ON_ONCE(IS_ERR(timer->fclk))) { in omap_dm_timer_prepare()
250 dev_err(&timer->pdev->dev, ": No fclk handle.\n"); in omap_dm_timer_prepare()
255 omap_dm_timer_enable(timer); in omap_dm_timer_prepare()
257 if (timer->capability & OMAP_TIMER_NEEDS_RESET) { in omap_dm_timer_prepare()
258 rc = omap_dm_timer_reset(timer); in omap_dm_timer_prepare()
260 omap_dm_timer_disable(timer); in omap_dm_timer_prepare()
265 __omap_dm_timer_enable_posted(timer); in omap_dm_timer_prepare()
266 omap_dm_timer_disable(timer); in omap_dm_timer_prepare()
288 struct omap_dm_timer *timer = NULL, *t; in _omap_dm_timer_request() local
317 timer = t; in _omap_dm_timer_request()
318 timer->reserved = 1; in _omap_dm_timer_request()
325 * If timer is not NULL, we have already found in _omap_dm_timer_request()
326 * one timer. But it was not an exact match in _omap_dm_timer_request()
329 * timer found and see if this one is a better in _omap_dm_timer_request()
332 if (timer) in _omap_dm_timer_request()
333 timer->reserved = 0; in _omap_dm_timer_request()
334 timer = t; in _omap_dm_timer_request()
335 timer->reserved = 1; in _omap_dm_timer_request()
344 timer = t; in _omap_dm_timer_request()
345 timer->reserved = 1; in _omap_dm_timer_request()
351 timer = t; in _omap_dm_timer_request()
352 timer->reserved = 1; in _omap_dm_timer_request()
359 if (timer && omap_dm_timer_prepare(timer)) { in _omap_dm_timer_request()
360 timer->reserved = 0; in _omap_dm_timer_request()
361 timer = NULL; in _omap_dm_timer_request()
364 if (!timer) in _omap_dm_timer_request()
365 pr_debug("%s: timer request failed!\n", __func__); in _omap_dm_timer_request()
367 return timer; in _omap_dm_timer_request()
377 /* Requesting timer by ID is not supported when device tree is used */ in omap_dm_timer_request_specific()
388 * omap_dm_timer_request_by_cap - Request a timer by capability
391 * Find a timer based upon capabilities bit mask. Callers of this function
393 * comment "timer capabilities used in hwmod database". Returns pointer to
394 * timer handle on success and a NULL pointer on failure.
402 * omap_dm_timer_request_by_node - Request a timer by device-tree node
403 * @np: Pointer to device-tree timer node
405 * Request a timer based upon a device node pointer. Returns pointer to
406 * timer handle on success and a NULL pointer on failure.
416 static int omap_dm_timer_free(struct omap_dm_timer *timer) in omap_dm_timer_free() argument
418 if (unlikely(!timer)) in omap_dm_timer_free()
421 clk_put(timer->fclk); in omap_dm_timer_free()
423 WARN_ON(!timer->reserved); in omap_dm_timer_free()
424 timer->reserved = 0; in omap_dm_timer_free()
428 int omap_dm_timer_get_irq(struct omap_dm_timer *timer) in omap_dm_timer_get_irq() argument
430 if (timer) in omap_dm_timer_get_irq()
431 return timer->irq; in omap_dm_timer_get_irq()
438 static struct clk *omap_dm_timer_get_fclk(struct omap_dm_timer *timer) in omap_dm_timer_get_fclk() argument
450 struct omap_dm_timer *timer = NULL; in omap_dm_timer_modify_idlect_mask() local
457 /* If any active timer is using ARMXOR return modified mask */ in omap_dm_timer_modify_idlect_mask()
459 list_for_each_entry(timer, &omap_timer_list, node) { in omap_dm_timer_modify_idlect_mask()
462 l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG); in omap_dm_timer_modify_idlect_mask()
478 static struct clk *omap_dm_timer_get_fclk(struct omap_dm_timer *timer) in omap_dm_timer_get_fclk() argument
480 if (timer && !IS_ERR(timer->fclk)) in omap_dm_timer_get_fclk()
481 return timer->fclk; in omap_dm_timer_get_fclk()
494 int omap_dm_timer_trigger(struct omap_dm_timer *timer) in omap_dm_timer_trigger() argument
496 if (unlikely(!timer || !atomic_read(&timer->enabled))) { in omap_dm_timer_trigger()
497 pr_err("%s: timer not available or enabled.\n", __func__); in omap_dm_timer_trigger()
501 omap_dm_timer_write_reg(timer, OMAP_TIMER_TRIGGER_REG, 0); in omap_dm_timer_trigger()
505 static int omap_dm_timer_start(struct omap_dm_timer *timer) in omap_dm_timer_start() argument
509 if (unlikely(!timer)) in omap_dm_timer_start()
512 omap_dm_timer_enable(timer); in omap_dm_timer_start()
514 l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG); in omap_dm_timer_start()
517 omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l); in omap_dm_timer_start()
523 static int omap_dm_timer_stop(struct omap_dm_timer *timer) in omap_dm_timer_stop() argument
527 if (unlikely(!timer)) in omap_dm_timer_stop()
530 if (!(timer->capability & OMAP_TIMER_NEEDS_RESET)) in omap_dm_timer_stop()
531 rate = clk_get_rate(timer->fclk); in omap_dm_timer_stop()
533 __omap_dm_timer_stop(timer, timer->posted, rate); in omap_dm_timer_stop()
535 omap_dm_timer_disable(timer); in omap_dm_timer_stop()
539 static int omap_dm_timer_set_load(struct omap_dm_timer *timer, in omap_dm_timer_set_load() argument
542 if (unlikely(!timer)) in omap_dm_timer_set_load()
545 omap_dm_timer_enable(timer); in omap_dm_timer_set_load()
546 omap_dm_timer_write_reg(timer, OMAP_TIMER_LOAD_REG, load); in omap_dm_timer_set_load()
548 omap_dm_timer_disable(timer); in omap_dm_timer_set_load()
552 static int omap_dm_timer_set_match(struct omap_dm_timer *timer, int enable, in omap_dm_timer_set_match() argument
557 if (unlikely(!timer)) in omap_dm_timer_set_match()
560 omap_dm_timer_enable(timer); in omap_dm_timer_set_match()
561 l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG); in omap_dm_timer_set_match()
566 omap_dm_timer_write_reg(timer, OMAP_TIMER_MATCH_REG, match); in omap_dm_timer_set_match()
567 omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l); in omap_dm_timer_set_match()
569 omap_dm_timer_disable(timer); in omap_dm_timer_set_match()
573 static int omap_dm_timer_set_pwm(struct omap_dm_timer *timer, int def_on, in omap_dm_timer_set_pwm() argument
578 if (unlikely(!timer)) in omap_dm_timer_set_pwm()
581 omap_dm_timer_enable(timer); in omap_dm_timer_set_pwm()
582 l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG); in omap_dm_timer_set_pwm()
592 omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l); in omap_dm_timer_set_pwm()
594 omap_dm_timer_disable(timer); in omap_dm_timer_set_pwm()
598 static int omap_dm_timer_get_pwm_status(struct omap_dm_timer *timer) in omap_dm_timer_get_pwm_status() argument
602 if (unlikely(!timer)) in omap_dm_timer_get_pwm_status()
605 omap_dm_timer_enable(timer); in omap_dm_timer_get_pwm_status()
606 l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG); in omap_dm_timer_get_pwm_status()
607 omap_dm_timer_disable(timer); in omap_dm_timer_get_pwm_status()
612 static int omap_dm_timer_set_prescaler(struct omap_dm_timer *timer, in omap_dm_timer_set_prescaler() argument
617 if (unlikely(!timer) || prescaler < -1 || prescaler > 7) in omap_dm_timer_set_prescaler()
620 omap_dm_timer_enable(timer); in omap_dm_timer_set_prescaler()
621 l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG); in omap_dm_timer_set_prescaler()
627 omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l); in omap_dm_timer_set_prescaler()
629 omap_dm_timer_disable(timer); in omap_dm_timer_set_prescaler()
633 static int omap_dm_timer_set_int_enable(struct omap_dm_timer *timer, in omap_dm_timer_set_int_enable() argument
636 if (unlikely(!timer)) in omap_dm_timer_set_int_enable()
639 omap_dm_timer_enable(timer); in omap_dm_timer_set_int_enable()
640 __omap_dm_timer_int_enable(timer, value); in omap_dm_timer_set_int_enable()
642 omap_dm_timer_disable(timer); in omap_dm_timer_set_int_enable()
647 * omap_dm_timer_set_int_disable - disable timer interrupts
648 * @timer: pointer to timer handle
651 * Disables the specified timer interrupts for a timer.
653 static int omap_dm_timer_set_int_disable(struct omap_dm_timer *timer, u32 mask) in omap_dm_timer_set_int_disable() argument
657 if (unlikely(!timer)) in omap_dm_timer_set_int_disable()
660 omap_dm_timer_enable(timer); in omap_dm_timer_set_int_disable()
662 if (timer->revision == 1) in omap_dm_timer_set_int_disable()
663 l = readl_relaxed(timer->irq_ena) & ~mask; in omap_dm_timer_set_int_disable()
665 writel_relaxed(l, timer->irq_dis); in omap_dm_timer_set_int_disable()
666 l = omap_dm_timer_read_reg(timer, OMAP_TIMER_WAKEUP_EN_REG) & ~mask; in omap_dm_timer_set_int_disable()
667 omap_dm_timer_write_reg(timer, OMAP_TIMER_WAKEUP_EN_REG, l); in omap_dm_timer_set_int_disable()
669 omap_dm_timer_disable(timer); in omap_dm_timer_set_int_disable()
673 static unsigned int omap_dm_timer_read_status(struct omap_dm_timer *timer) in omap_dm_timer_read_status() argument
677 if (unlikely(!timer || !atomic_read(&timer->enabled))) { in omap_dm_timer_read_status()
678 pr_err("%s: timer not available or enabled.\n", __func__); in omap_dm_timer_read_status()
682 l = readl_relaxed(timer->irq_stat); in omap_dm_timer_read_status()
687 static int omap_dm_timer_write_status(struct omap_dm_timer *timer, unsigned int value) in omap_dm_timer_write_status() argument
689 if (unlikely(!timer || !atomic_read(&timer->enabled))) in omap_dm_timer_write_status()
692 __omap_dm_timer_write_status(timer, value); in omap_dm_timer_write_status()
697 static unsigned int omap_dm_timer_read_counter(struct omap_dm_timer *timer) in omap_dm_timer_read_counter() argument
699 if (unlikely(!timer || !atomic_read(&timer->enabled))) { in omap_dm_timer_read_counter()
700 pr_err("%s: timer not iavailable or enabled.\n", __func__); in omap_dm_timer_read_counter()
704 return __omap_dm_timer_read_counter(timer, timer->posted); in omap_dm_timer_read_counter()
707 static int omap_dm_timer_write_counter(struct omap_dm_timer *timer, unsigned int value) in omap_dm_timer_write_counter() argument
709 if (unlikely(!timer || !atomic_read(&timer->enabled))) { in omap_dm_timer_write_counter()
710 pr_err("%s: timer not available or enabled.\n", __func__); in omap_dm_timer_write_counter()
714 omap_dm_timer_write_reg(timer, OMAP_TIMER_COUNTER_REG, value); in omap_dm_timer_write_counter()
717 timer->context.tcrr = value; in omap_dm_timer_write_counter()
723 struct omap_dm_timer *timer; in omap_dm_timers_active() local
725 list_for_each_entry(timer, &omap_timer_list, node) { in omap_dm_timers_active()
726 if (!timer->reserved) in omap_dm_timers_active()
729 if (omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG) & in omap_dm_timers_active()
739 struct omap_dm_timer *timer = dev_get_drvdata(dev); in omap_dm_timer_runtime_suspend() local
741 atomic_set(&timer->enabled, 0); in omap_dm_timer_runtime_suspend()
743 if (timer->capability & OMAP_TIMER_ALWON || !timer->func_base) in omap_dm_timer_runtime_suspend()
746 omap_timer_save_context(timer); in omap_dm_timer_runtime_suspend()
753 struct omap_dm_timer *timer = dev_get_drvdata(dev); in omap_dm_timer_runtime_resume() local
755 if (!(timer->capability & OMAP_TIMER_ALWON) && timer->func_base) in omap_dm_timer_runtime_resume()
756 omap_timer_restore_context(timer); in omap_dm_timer_runtime_resume()
758 atomic_set(&timer->enabled, 1); in omap_dm_timer_runtime_resume()
772 * @pdev: pointer to current timer platform device
775 * timer devices.
780 struct omap_dm_timer *timer; in omap_dm_timer_probe() local
796 timer = devm_kzalloc(dev, sizeof(*timer), GFP_KERNEL); in omap_dm_timer_probe()
797 if (!timer) in omap_dm_timer_probe()
800 timer->irq = platform_get_irq(pdev, 0); in omap_dm_timer_probe()
801 if (timer->irq < 0) in omap_dm_timer_probe()
802 return timer->irq; in omap_dm_timer_probe()
804 timer->fclk = ERR_PTR(-ENODEV); in omap_dm_timer_probe()
805 timer->io_base = devm_platform_ioremap_resource(pdev, 0); in omap_dm_timer_probe()
806 if (IS_ERR(timer->io_base)) in omap_dm_timer_probe()
807 return PTR_ERR(timer->io_base); in omap_dm_timer_probe()
809 platform_set_drvdata(pdev, timer); in omap_dm_timer_probe()
812 if (of_find_property(dev->of_node, "ti,timer-alwon", NULL)) in omap_dm_timer_probe()
813 timer->capability |= OMAP_TIMER_ALWON; in omap_dm_timer_probe()
814 if (of_find_property(dev->of_node, "ti,timer-dsp", NULL)) in omap_dm_timer_probe()
815 timer->capability |= OMAP_TIMER_HAS_DSP_IRQ; in omap_dm_timer_probe()
816 if (of_find_property(dev->of_node, "ti,timer-pwm", NULL)) in omap_dm_timer_probe()
817 timer->capability |= OMAP_TIMER_HAS_PWM; in omap_dm_timer_probe()
818 if (of_find_property(dev->of_node, "ti,timer-secure", NULL)) in omap_dm_timer_probe()
819 timer->capability |= OMAP_TIMER_SECURE; in omap_dm_timer_probe()
821 timer->id = pdev->id; in omap_dm_timer_probe()
822 timer->capability = pdata->timer_capability; in omap_dm_timer_probe()
823 timer->reserved = omap_dm_timer_reserved_systimer(timer->id); in omap_dm_timer_probe()
826 if (!(timer->capability & OMAP_TIMER_ALWON)) { in omap_dm_timer_probe()
827 timer->nb.notifier_call = omap_timer_context_notifier; in omap_dm_timer_probe()
828 cpu_pm_register_notifier(&timer->nb); in omap_dm_timer_probe()
832 timer->errata = pdata->timer_errata; in omap_dm_timer_probe()
834 timer->pdev = pdev; in omap_dm_timer_probe()
838 if (!timer->reserved) { in omap_dm_timer_probe()
845 __omap_dm_timer_init_regs(timer); in omap_dm_timer_probe()
849 /* add the timer element to the list */ in omap_dm_timer_probe()
851 list_add_tail(&timer->node, &omap_timer_list); in omap_dm_timer_probe()
865 * omap_dm_timer_remove - cleanup a registered timer device
866 * @pdev: pointer to current timer platform device
868 * Called by driver framework whenever a timer device is unregistered.
869 * In addition to freeing platform resources it also deletes the timer
874 struct omap_dm_timer *timer; in omap_dm_timer_remove() local
879 list_for_each_entry(timer, &omap_timer_list, node) in omap_dm_timer_remove()
880 if (!strcmp(dev_name(&timer->pdev->dev), in omap_dm_timer_remove()
882 if (!(timer->capability & OMAP_TIMER_ALWON)) in omap_dm_timer_remove()
883 cpu_pm_unregister_notifier(&timer->nb); in omap_dm_timer_remove()
884 list_del(&timer->node); in omap_dm_timer_remove()
927 .compatible = "ti,omap2420-timer",
930 .compatible = "ti,omap3430-timer",
934 .compatible = "ti,omap4430-timer",
938 .compatible = "ti,omap5430-timer",
942 .compatible = "ti,am335x-timer",
946 .compatible = "ti,am335x-timer-1ms",
950 .compatible = "ti,dm816-timer",
969 MODULE_DESCRIPTION("OMAP Dual-Mode Timer Driver");