Lines Matching refs: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)
59 return __omap_dm_timer_read(timer, reg, timer->posted);
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,
76 __omap_dm_timer_write(timer, reg, value, timer->posted);
79 static void omap_timer_restore_context(struct omap_dm_timer *timer)
81 __omap_dm_timer_write(timer, OMAP_TIMER_OCP_CFG_OFFSET,
82 timer->context.ocp_cfg, 0);
84 omap_dm_timer_write_reg(timer, OMAP_TIMER_WAKEUP_EN_REG,
85 timer->context.twer);
86 omap_dm_timer_write_reg(timer, OMAP_TIMER_COUNTER_REG,
87 timer->context.tcrr);
88 omap_dm_timer_write_reg(timer, OMAP_TIMER_LOAD_REG,
89 timer->context.tldr);
90 omap_dm_timer_write_reg(timer, OMAP_TIMER_MATCH_REG,
91 timer->context.tmar);
92 omap_dm_timer_write_reg(timer, OMAP_TIMER_IF_CTRL_REG,
93 timer->context.tsicr);
94 writel_relaxed(timer->context.tier, timer->irq_ena);
95 omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG,
96 timer->context.tclr);
99 static void omap_timer_save_context(struct omap_dm_timer *timer)
101 timer->context.ocp_cfg =
102 __omap_dm_timer_read(timer, OMAP_TIMER_OCP_CFG_OFFSET, 0);
104 timer->context.tclr =
105 omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
106 timer->context.twer =
107 omap_dm_timer_read_reg(timer, OMAP_TIMER_WAKEUP_EN_REG);
108 timer->context.tldr =
109 omap_dm_timer_read_reg(timer, OMAP_TIMER_LOAD_REG);
110 timer->context.tmar =
111 omap_dm_timer_read_reg(timer, OMAP_TIMER_MATCH_REG);
112 timer->context.tier = readl_relaxed(timer->irq_ena);
113 timer->context.tsicr =
114 omap_dm_timer_read_reg(timer, OMAP_TIMER_IF_CTRL_REG);
120 struct omap_dm_timer *timer;
122 timer = container_of(nb, struct omap_dm_timer, nb);
126 if ((timer->capability & OMAP_TIMER_ALWON) ||
127 !atomic_read(&timer->enabled))
129 omap_timer_save_context(timer);
133 if ((timer->capability & OMAP_TIMER_ALWON) ||
134 !atomic_read(&timer->enabled))
136 omap_timer_restore_context(timer);
143 static int omap_dm_timer_reset(struct omap_dm_timer *timer)
147 if (timer->revision != 1)
150 omap_dm_timer_write_reg(timer, OMAP_TIMER_IF_CTRL_REG, 0x06);
153 l = __omap_dm_timer_read(timer,
158 dev_err(&timer->pdev->dev, "Timer failed to reset\n");
162 /* Configure timer for smart-idle mode */
163 l = __omap_dm_timer_read(timer, OMAP_TIMER_OCP_CFG_OFFSET, 0);
165 __omap_dm_timer_write(timer, OMAP_TIMER_OCP_CFG_OFFSET, l, 0);
167 timer->posted = 0;
172 static int omap_dm_timer_set_source(struct omap_dm_timer *timer, int source)
179 if (unlikely(!timer) || IS_ERR(timer->fclk))
196 pdata = timer->pdev->dev.platform_data;
204 return pdata->set_timer_src(timer->pdev, source);
208 if (clk_hw_get_num_parents(__clk_get_hw(timer->fclk)) < 2)
212 parent = clk_get(&timer->pdev->dev, parent_name);
218 ret = clk_set_parent(timer->fclk, parent);
228 static void omap_dm_timer_enable(struct omap_dm_timer *timer)
230 pm_runtime_get_sync(&timer->pdev->dev);
233 static void omap_dm_timer_disable(struct omap_dm_timer *timer)
235 pm_runtime_put_sync(&timer->pdev->dev);
238 static int omap_dm_timer_prepare(struct omap_dm_timer *timer)
246 if (!(timer->capability & OMAP_TIMER_NEEDS_RESET)) {
247 timer->fclk = clk_get(&timer->pdev->dev, "fck");
248 if (WARN_ON_ONCE(IS_ERR(timer->fclk))) {
249 dev_err(&timer->pdev->dev, ": No fclk handle.\n");
254 omap_dm_timer_enable(timer);
256 if (timer->capability & OMAP_TIMER_NEEDS_RESET) {
257 rc = omap_dm_timer_reset(timer);
259 omap_dm_timer_disable(timer);
264 __omap_dm_timer_enable_posted(timer);
265 omap_dm_timer_disable(timer);
287 struct omap_dm_timer *timer = NULL, *t;
316 timer = t;
317 timer->reserved = 1;
324 * If timer is not NULL, we have already found
325 * one timer. But it was not an exact match
328 * timer found and see if this one is a better
331 if (timer)
332 timer->reserved = 0;
333 timer = t;
334 timer->reserved = 1;
343 timer = t;
344 timer->reserved = 1;
350 timer = t;
351 timer->reserved = 1;
358 if (timer && omap_dm_timer_prepare(timer)) {
359 timer->reserved = 0;
360 timer = NULL;
363 if (!timer)
364 pr_debug("%s: timer request failed!\n", __func__);
366 return timer;
376 /* Requesting timer by ID is not supported when device tree is used */
387 * omap_dm_timer_request_by_cap - Request a timer by capability
390 * Find a timer based upon capabilities bit mask. Callers of this function
392 * comment "timer capabilities used in hwmod database". Returns pointer to
393 * timer handle on success and a NULL pointer on failure.
401 * omap_dm_timer_request_by_node - Request a timer by device-tree node
402 * @np: Pointer to device-tree timer node
404 * Request a timer based upon a device node pointer. Returns pointer to
405 * timer handle on success and a NULL pointer on failure.
415 static int omap_dm_timer_free(struct omap_dm_timer *timer)
417 if (unlikely(!timer))
420 clk_put(timer->fclk);
422 WARN_ON(!timer->reserved);
423 timer->reserved = 0;
427 int omap_dm_timer_get_irq(struct omap_dm_timer *timer)
429 if (timer)
430 return timer->irq;
437 static struct clk *omap_dm_timer_get_fclk(struct omap_dm_timer *timer)
449 struct omap_dm_timer *timer = NULL;
456 /* If any active timer is using ARMXOR return modified mask */
458 list_for_each_entry(timer, &omap_timer_list, node) {
461 l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
477 static struct clk *omap_dm_timer_get_fclk(struct omap_dm_timer *timer)
479 if (timer && !IS_ERR(timer->fclk))
480 return timer->fclk;
493 int omap_dm_timer_trigger(struct omap_dm_timer *timer)
495 if (unlikely(!timer || !atomic_read(&timer->enabled))) {
496 pr_err("%s: timer not available or enabled.\n", __func__);
500 omap_dm_timer_write_reg(timer, OMAP_TIMER_TRIGGER_REG, 0);
504 static int omap_dm_timer_start(struct omap_dm_timer *timer)
508 if (unlikely(!timer))
511 omap_dm_timer_enable(timer);
513 l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
516 omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);
522 static int omap_dm_timer_stop(struct omap_dm_timer *timer)
526 if (unlikely(!timer))
529 if (!(timer->capability & OMAP_TIMER_NEEDS_RESET))
530 rate = clk_get_rate(timer->fclk);
532 __omap_dm_timer_stop(timer, timer->posted, rate);
534 omap_dm_timer_disable(timer);
538 static int omap_dm_timer_set_load(struct omap_dm_timer *timer,
541 if (unlikely(!timer))
544 omap_dm_timer_enable(timer);
545 omap_dm_timer_write_reg(timer, OMAP_TIMER_LOAD_REG, load);
547 omap_dm_timer_disable(timer);
551 static int omap_dm_timer_set_match(struct omap_dm_timer *timer, int enable,
556 if (unlikely(!timer))
559 omap_dm_timer_enable(timer);
560 l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
565 omap_dm_timer_write_reg(timer, OMAP_TIMER_MATCH_REG, match);
566 omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);
568 omap_dm_timer_disable(timer);
572 static int omap_dm_timer_set_pwm(struct omap_dm_timer *timer, int def_on,
577 if (unlikely(!timer))
580 omap_dm_timer_enable(timer);
581 l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
591 omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);
593 omap_dm_timer_disable(timer);
597 static int omap_dm_timer_get_pwm_status(struct omap_dm_timer *timer)
601 if (unlikely(!timer))
604 omap_dm_timer_enable(timer);
605 l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
606 omap_dm_timer_disable(timer);
611 static int omap_dm_timer_set_prescaler(struct omap_dm_timer *timer,
616 if (unlikely(!timer) || prescaler < -1 || prescaler > 7)
619 omap_dm_timer_enable(timer);
620 l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
626 omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);
628 omap_dm_timer_disable(timer);
632 static int omap_dm_timer_set_int_enable(struct omap_dm_timer *timer,
635 if (unlikely(!timer))
638 omap_dm_timer_enable(timer);
639 __omap_dm_timer_int_enable(timer, value);
641 omap_dm_timer_disable(timer);
646 * omap_dm_timer_set_int_disable - disable timer interrupts
647 * @timer: pointer to timer handle
650 * Disables the specified timer interrupts for a timer.
652 static int omap_dm_timer_set_int_disable(struct omap_dm_timer *timer, u32 mask)
656 if (unlikely(!timer))
659 omap_dm_timer_enable(timer);
661 if (timer->revision == 1)
662 l = readl_relaxed(timer->irq_ena) & ~mask;
664 writel_relaxed(l, timer->irq_dis);
665 l = omap_dm_timer_read_reg(timer, OMAP_TIMER_WAKEUP_EN_REG) & ~mask;
666 omap_dm_timer_write_reg(timer, OMAP_TIMER_WAKEUP_EN_REG, l);
668 omap_dm_timer_disable(timer);
672 static unsigned int omap_dm_timer_read_status(struct omap_dm_timer *timer)
676 if (unlikely(!timer || !atomic_read(&timer->enabled))) {
677 pr_err("%s: timer not available or enabled.\n", __func__);
681 l = readl_relaxed(timer->irq_stat);
686 static int omap_dm_timer_write_status(struct omap_dm_timer *timer, unsigned int value)
688 if (unlikely(!timer || !atomic_read(&timer->enabled)))
691 __omap_dm_timer_write_status(timer, value);
696 static unsigned int omap_dm_timer_read_counter(struct omap_dm_timer *timer)
698 if (unlikely(!timer || !atomic_read(&timer->enabled))) {
699 pr_err("%s: timer not iavailable or enabled.\n", __func__);
703 return __omap_dm_timer_read_counter(timer, timer->posted);
706 static int omap_dm_timer_write_counter(struct omap_dm_timer *timer, unsigned int value)
708 if (unlikely(!timer || !atomic_read(&timer->enabled))) {
709 pr_err("%s: timer not available or enabled.\n", __func__);
713 omap_dm_timer_write_reg(timer, OMAP_TIMER_COUNTER_REG, value);
716 timer->context.tcrr = value;
722 struct omap_dm_timer *timer;
724 list_for_each_entry(timer, &omap_timer_list, node) {
725 if (!timer->reserved)
728 if (omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG) &
738 struct omap_dm_timer *timer = dev_get_drvdata(dev);
740 atomic_set(&timer->enabled, 0);
742 if (timer->capability & OMAP_TIMER_ALWON || !timer->func_base)
745 omap_timer_save_context(timer);
752 struct omap_dm_timer *timer = dev_get_drvdata(dev);
754 if (!(timer->capability & OMAP_TIMER_ALWON) && timer->func_base)
755 omap_timer_restore_context(timer);
757 atomic_set(&timer->enabled, 1);
771 * @pdev: pointer to current timer platform device
774 * timer devices.
779 struct omap_dm_timer *timer;
795 timer = devm_kzalloc(dev, sizeof(*timer), GFP_KERNEL);
796 if (!timer)
799 timer->irq = platform_get_irq(pdev, 0);
800 if (timer->irq < 0)
801 return timer->irq;
803 timer->fclk = ERR_PTR(-ENODEV);
804 timer->io_base = devm_platform_ioremap_resource(pdev, 0);
805 if (IS_ERR(timer->io_base))
806 return PTR_ERR(timer->io_base);
808 platform_set_drvdata(pdev, timer);
811 if (of_find_property(dev->of_node, "ti,timer-alwon", NULL))
812 timer->capability |= OMAP_TIMER_ALWON;
813 if (of_find_property(dev->of_node, "ti,timer-dsp", NULL))
814 timer->capability |= OMAP_TIMER_HAS_DSP_IRQ;
815 if (of_find_property(dev->of_node, "ti,timer-pwm", NULL))
816 timer->capability |= OMAP_TIMER_HAS_PWM;
817 if (of_find_property(dev->of_node, "ti,timer-secure", NULL))
818 timer->capability |= OMAP_TIMER_SECURE;
820 timer->id = pdev->id;
821 timer->capability = pdata->timer_capability;
822 timer->reserved = omap_dm_timer_reserved_systimer(timer->id);
825 if (!(timer->capability & OMAP_TIMER_ALWON)) {
826 timer->nb.notifier_call = omap_timer_context_notifier;
827 cpu_pm_register_notifier(&timer->nb);
831 timer->errata = pdata->timer_errata;
833 timer->pdev = pdev;
837 if (!timer->reserved) {
844 __omap_dm_timer_init_regs(timer);
848 /* add the timer element to the list */
850 list_add_tail(&timer->node, &omap_timer_list);
864 * omap_dm_timer_remove - cleanup a registered timer device
865 * @pdev: pointer to current timer platform device
867 * Called by driver framework whenever a timer device is unregistered.
868 * In addition to freeing platform resources it also deletes the timer
873 struct omap_dm_timer *timer;
878 list_for_each_entry(timer, &omap_timer_list, node)
879 if (!strcmp(dev_name(&timer->pdev->dev),
881 if (!(timer->capability & OMAP_TIMER_ALWON))
882 cpu_pm_unregister_notifier(&timer->nb);
883 list_del(&timer->node);
926 .compatible = "ti,omap2420-timer",
929 .compatible = "ti,omap3430-timer",
933 .compatible = "ti,omap4430-timer",
937 .compatible = "ti,omap5430-timer",
941 .compatible = "ti,am335x-timer",
945 .compatible = "ti,am335x-timer-1ms",
949 .compatible = "ti,dm816-timer",