Lines Matching +full:clock +full:- +full:error +full:- +full:detect
1 // SPDX-License-Identifier: GPL-2.0+
14 #include <linux/clk/clk-conf.h>
16 #include <clocksource/timer-ti-dm.h>
17 #include <dt-bindings/bus/ti-sysc.h>
19 /* For type1, set SYSC_OMAP2_CLOCKACTIVITY for fck off on idle, l4 clock on */
67 u32 tidr = readl_relaxed(t->base); in dmtimer_systimer_revision1()
81 writel_relaxed(val, t->base + t->sysc); in dmtimer_systimer_enable()
89 writel_relaxed(DMTIMER_TYPE1_DISABLE, t->base + t->sysc); in dmtimer_systimer_disable()
94 void __iomem *syss = t->base + OMAP_TIMER_V1_SYS_STAT_OFFSET; in dmtimer_systimer_type1_reset()
99 writel_relaxed(BIT(1) | BIT(2), t->base + t->ifctrl); in dmtimer_systimer_type1_reset()
109 void __iomem *sysc = t->base + t->sysc; in dmtimer_systimer_type2_reset()
139 { .compatible = "ti,omap-counter32k" },
145 * counter is handled by timer-ti-32k, but we need to detect it as it
159 counter_32k = -ENODEV; in dmtimer_systimer_check_counter32k()
167 counter_32k = -ENODEV; in dmtimer_systimer_check_counter32k()
173 { .compatible = "ti,omap2420-timer", },
174 { .compatible = "ti,omap3430-timer", },
175 { .compatible = "ti,omap4430-timer", },
176 { .compatible = "ti,omap5430-timer", },
177 { .compatible = "ti,am335x-timer", },
178 { .compatible = "ti,am335x-timer-1ms", },
179 { .compatible = "ti,dm814-timer", },
180 { .compatible = "ti,dm816-timer", },
186 * the generic timer-ti-dm device driver probe. And that the system timer
195 if (!of_property_read_bool(np->parent, in dmtimer_is_preferred()
196 "ti,no-reset-on-init")) in dmtimer_is_preferred()
199 if (!of_property_read_bool(np->parent, "ti,no-idle")) in dmtimer_is_preferred()
203 if (!of_property_read_bool(np, "ti,timer-secure")) { in dmtimer_is_preferred()
204 if (!of_property_read_bool(np, "assigned-clocks")) in dmtimer_is_preferred()
207 if (!of_property_read_bool(np, "assigned-clock-parents")) in dmtimer_is_preferred()
211 if (of_property_read_bool(np, "ti,timer-dsp")) in dmtimer_is_preferred()
214 if (of_property_read_bool(np, "ti,timer-pwm")) in dmtimer_is_preferred()
221 * Finds the first available usable always-on timer, and assigns it to either
228 * ti,always-on property, but let's not count on it. For these quirky cases,
229 * we prefer using the always-on secure dmtimer12 with the internal 32 KiHz
230 * clock as the clocksource, and any available dmtimer as clockevent.
243 if (of_machine_is_compatible("ti,omap3-beagle") || in dmtimer_systimer_assign_alwon()
244 of_machine_is_compatible("timll,omap3-devkit8000")) { in dmtimer_systimer_assign_alwon()
246 counter_32k = -ENODEV; in dmtimer_systimer_assign_alwon()
251 counter_32k = -ENODEV; in dmtimer_systimer_assign_alwon()
257 if (of_property_read_bool(np, "ti,timer-alwon")) { in dmtimer_systimer_assign_alwon()
330 struct clk *clock; in dmtimer_systimer_init_clock() local
333 int error; in dmtimer_systimer_init_clock() local
337 clock = of_clk_get_by_name(np, name); in dmtimer_systimer_init_clock()
338 if ((PTR_ERR(clock) == -EINVAL) && is_ick) in dmtimer_systimer_init_clock()
340 else if (IS_ERR(clock)) in dmtimer_systimer_init_clock()
341 return PTR_ERR(clock); in dmtimer_systimer_init_clock()
343 error = clk_prepare_enable(clock); in dmtimer_systimer_init_clock()
344 if (error) in dmtimer_systimer_init_clock()
345 return error; in dmtimer_systimer_init_clock()
347 r = clk_get_rate(clock); in dmtimer_systimer_init_clock()
349 return -ENODEV; in dmtimer_systimer_init_clock()
352 t->ick = clock; in dmtimer_systimer_init_clock()
354 t->fck = clock; in dmtimer_systimer_init_clock()
366 int error; in dmtimer_systimer_setup() local
368 if (!of_device_is_compatible(np->parent, "ti,sysc")) in dmtimer_systimer_setup()
369 return -EINVAL; in dmtimer_systimer_setup()
371 t->base = of_iomap(np, 0); in dmtimer_systimer_setup()
372 if (!t->base) in dmtimer_systimer_setup()
373 return -ENXIO; in dmtimer_systimer_setup()
376 * Enable optional assigned-clock-parents configured at the timer in dmtimer_systimer_setup()
380 error = of_clk_set_defaults(np, false); in dmtimer_systimer_setup()
381 if (error < 0) in dmtimer_systimer_setup()
382 pr_err("%s: clock source init failed: %i\n", __func__, error); in dmtimer_systimer_setup()
384 /* For ti-sysc, we have timer clocks at the parent module level */ in dmtimer_systimer_setup()
385 error = dmtimer_systimer_init_clock(t, np->parent, "fck", &rate); in dmtimer_systimer_setup()
386 if (error) in dmtimer_systimer_setup()
389 t->rate = rate; in dmtimer_systimer_setup()
391 error = dmtimer_systimer_init_clock(t, np->parent, "ick", &rate); in dmtimer_systimer_setup()
392 if (error) in dmtimer_systimer_setup()
396 t->irq_stat = OMAP_TIMER_V1_STAT_OFFSET; in dmtimer_systimer_setup()
397 t->irq_ena = OMAP_TIMER_V1_INT_EN_OFFSET; in dmtimer_systimer_setup()
398 t->pend = _OMAP_TIMER_WRITE_PEND_OFFSET; in dmtimer_systimer_setup()
401 t->irq_stat = OMAP_TIMER_V2_IRQSTATUS; in dmtimer_systimer_setup()
402 t->irq_ena = OMAP_TIMER_V2_IRQENABLE_SET; in dmtimer_systimer_setup()
404 t->pend = regbase + _OMAP_TIMER_WRITE_PEND_OFFSET; in dmtimer_systimer_setup()
407 t->sysc = OMAP_TIMER_OCP_CFG_OFFSET; in dmtimer_systimer_setup()
408 t->load = regbase + _OMAP_TIMER_LOAD_OFFSET; in dmtimer_systimer_setup()
409 t->counter = regbase + _OMAP_TIMER_COUNTER_OFFSET; in dmtimer_systimer_setup()
410 t->ctrl = regbase + _OMAP_TIMER_CTRL_OFFSET; in dmtimer_systimer_setup()
411 t->wakeup = regbase + _OMAP_TIMER_WAKEUP_EN_OFFSET; in dmtimer_systimer_setup()
412 t->ifctrl = regbase + _OMAP_TIMER_IF_CTRL_OFFSET; in dmtimer_systimer_setup()
416 pr_debug("dmtimer rev %08x sysc %08x\n", readl_relaxed(t->base), in dmtimer_systimer_setup()
417 readl_relaxed(t->base + t->sysc)); in dmtimer_systimer_setup()
422 iounmap(t->base); in dmtimer_systimer_setup()
424 return error; in dmtimer_systimer_setup()
437 struct dmtimer_systimer *t = &clkevt->t; in dmtimer_clockevent_interrupt()
439 writel_relaxed(OMAP_TIMER_INT_OVERFLOW, t->base + t->irq_stat); in dmtimer_clockevent_interrupt()
440 clkevt->dev.event_handler(&clkevt->dev); in dmtimer_clockevent_interrupt()
449 struct dmtimer_systimer *t = &clkevt->t; in dmtimer_set_next_event()
450 void __iomem *pend = t->base + t->pend; in dmtimer_set_next_event()
452 writel_relaxed(0xffffffff - cycles, t->base + t->counter); in dmtimer_set_next_event()
456 writel_relaxed(OMAP_TIMER_CTRL_ST, t->base + t->ctrl); in dmtimer_set_next_event()
466 struct dmtimer_systimer *t = &clkevt->t; in dmtimer_clockevent_shutdown()
467 void __iomem *ctrl = t->base + t->ctrl; in dmtimer_clockevent_shutdown()
476 /* Wait for functional clock period x 3.5 */ in dmtimer_clockevent_shutdown()
477 udelay(3500000 / t->rate + 1); in dmtimer_clockevent_shutdown()
479 writel_relaxed(OMAP_TIMER_INT_OVERFLOW, t->base + t->irq_stat); in dmtimer_clockevent_shutdown()
487 struct dmtimer_systimer *t = &clkevt->t; in dmtimer_set_periodic()
488 void __iomem *pend = t->base + t->pend; in dmtimer_set_periodic()
493 writel_relaxed(clkevt->period, t->base + t->load); in dmtimer_set_periodic()
497 writel_relaxed(clkevt->period, t->base + t->counter); in dmtimer_set_periodic()
502 t->base + t->ctrl); in dmtimer_set_periodic()
512 struct dmtimer_systimer *t = &clkevt->t; in omap_clockevent_idle()
515 clk_disable(t->fck); in omap_clockevent_idle()
521 struct dmtimer_systimer *t = &clkevt->t; in omap_clockevent_unidle()
522 int error; in omap_clockevent_unidle() local
524 error = clk_enable(t->fck); in omap_clockevent_unidle()
525 if (error) in omap_clockevent_unidle()
526 pr_err("could not enable timer fck on resume: %i\n", error); in omap_clockevent_unidle()
529 writel_relaxed(OMAP_TIMER_INT_OVERFLOW, t->base + t->irq_ena); in omap_clockevent_unidle()
530 writel_relaxed(OMAP_TIMER_INT_OVERFLOW, t->base + t->wakeup); in omap_clockevent_unidle()
538 int error; in dmtimer_clockevent_init() local
542 return -ENOMEM; in dmtimer_clockevent_init()
544 t = &clkevt->t; in dmtimer_clockevent_init()
545 dev = &clkevt->dev; in dmtimer_clockevent_init()
551 dev->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT; in dmtimer_clockevent_init()
552 dev->rating = 300; in dmtimer_clockevent_init()
553 dev->set_next_event = dmtimer_set_next_event; in dmtimer_clockevent_init()
554 dev->set_state_shutdown = dmtimer_clockevent_shutdown; in dmtimer_clockevent_init()
555 dev->set_state_periodic = dmtimer_set_periodic; in dmtimer_clockevent_init()
556 dev->set_state_oneshot = dmtimer_clockevent_shutdown; in dmtimer_clockevent_init()
557 dev->tick_resume = dmtimer_clockevent_shutdown; in dmtimer_clockevent_init()
558 dev->cpumask = cpu_possible_mask; in dmtimer_clockevent_init()
560 dev->irq = irq_of_parse_and_map(np, 0); in dmtimer_clockevent_init()
561 if (!dev->irq) { in dmtimer_clockevent_init()
562 error = -ENXIO; in dmtimer_clockevent_init()
566 error = dmtimer_systimer_setup(np, &clkevt->t); in dmtimer_clockevent_init()
567 if (error) in dmtimer_clockevent_init()
570 clkevt->period = 0xffffffff - DIV_ROUND_CLOSEST(t->rate, HZ); in dmtimer_clockevent_init()
573 * For clock-event timers we never read the timer counter and in dmtimer_clockevent_init()
575 * we can safely ignore this errata for clock-event timers. in dmtimer_clockevent_init()
577 writel_relaxed(OMAP_TIMER_CTRL_POSTED, t->base + t->ifctrl); in dmtimer_clockevent_init()
579 error = request_irq(dev->irq, dmtimer_clockevent_interrupt, in dmtimer_clockevent_init()
581 if (error) in dmtimer_clockevent_init()
584 writel_relaxed(OMAP_TIMER_INT_OVERFLOW, t->base + t->irq_ena); in dmtimer_clockevent_init()
585 writel_relaxed(OMAP_TIMER_INT_OVERFLOW, t->base + t->wakeup); in dmtimer_clockevent_init()
588 of_find_property(np, "ti,timer-alwon", NULL) ? in dmtimer_clockevent_init()
589 "always-on " : "", t->rate, np->parent); in dmtimer_clockevent_init()
591 clockevents_config_and_register(dev, t->rate, in dmtimer_clockevent_init()
597 dev->suspend = omap_clockevent_idle; in dmtimer_clockevent_init()
598 dev->resume = omap_clockevent_unidle; in dmtimer_clockevent_init()
604 iounmap(t->base); in dmtimer_clockevent_init()
609 return error; in dmtimer_clockevent_init()
622 struct dmtimer_systimer *t = &clksrc->t; in dmtimer_clocksource_read_cycles()
624 return (u64)readl_relaxed(t->base + t->counter); in dmtimer_clocksource_read_cycles()
637 struct dmtimer_systimer *t = &clksrc->t; in dmtimer_clocksource_suspend()
639 clksrc->loadval = readl_relaxed(t->base + t->counter); in dmtimer_clocksource_suspend()
641 clk_disable(t->fck); in dmtimer_clocksource_suspend()
647 struct dmtimer_systimer *t = &clksrc->t; in dmtimer_clocksource_resume()
648 int error; in dmtimer_clocksource_resume() local
650 error = clk_enable(t->fck); in dmtimer_clocksource_resume()
651 if (error) in dmtimer_clocksource_resume()
652 pr_err("could not enable timer fck on resume: %i\n", error); in dmtimer_clocksource_resume()
655 writel_relaxed(clksrc->loadval, t->base + t->counter); in dmtimer_clocksource_resume()
657 t->base + t->ctrl); in dmtimer_clocksource_resume()
665 int error; in dmtimer_clocksource_init() local
669 return -ENOMEM; in dmtimer_clocksource_init()
671 dev = &clksrc->dev; in dmtimer_clocksource_init()
672 t = &clksrc->t; in dmtimer_clocksource_init()
674 error = dmtimer_systimer_setup(np, t); in dmtimer_clocksource_init()
675 if (error) in dmtimer_clocksource_init()
678 dev->name = "dmtimer"; in dmtimer_clocksource_init()
679 dev->rating = 300; in dmtimer_clocksource_init()
680 dev->read = dmtimer_clocksource_read_cycles; in dmtimer_clocksource_init()
681 dev->mask = CLOCKSOURCE_MASK(32); in dmtimer_clocksource_init()
682 dev->flags = CLOCK_SOURCE_IS_CONTINUOUS; in dmtimer_clocksource_init()
686 dev->suspend = dmtimer_clocksource_suspend; in dmtimer_clocksource_init()
687 dev->resume = dmtimer_clocksource_resume; in dmtimer_clocksource_init()
690 writel_relaxed(0, t->base + t->counter); in dmtimer_clocksource_init()
692 t->base + t->ctrl); in dmtimer_clocksource_init()
695 of_find_property(np, "ti,timer-alwon", NULL) ? in dmtimer_clocksource_init()
696 "always-on " : "", np->parent); in dmtimer_clocksource_init()
699 dmtimer_sched_clock_counter = t->base + t->counter; in dmtimer_clocksource_init()
700 sched_clock_register(dmtimer_read_sched_clock, 32, t->rate); in dmtimer_clocksource_init()
703 if (clocksource_register_hz(dev, t->rate)) in dmtimer_clocksource_init()
711 return -ENODEV; in dmtimer_clocksource_init()
715 * To detect between a clocksource and clockevent, we assume the device tree
728 pr_err("%s: unable to detect system timers, update dtb?\n", in dmtimer_systimer_init()
731 return -EINVAL; in dmtimer_systimer_init()
737 return -EINVAL; in dmtimer_systimer_init()
748 TIMER_OF_DECLARE(systimer_omap2, "ti,omap2420-timer", dmtimer_systimer_init);
749 TIMER_OF_DECLARE(systimer_omap3, "ti,omap3430-timer", dmtimer_systimer_init);
750 TIMER_OF_DECLARE(systimer_omap4, "ti,omap4430-timer", dmtimer_systimer_init);
751 TIMER_OF_DECLARE(systimer_omap5, "ti,omap5430-timer", dmtimer_systimer_init);
752 TIMER_OF_DECLARE(systimer_am33x, "ti,am335x-timer", dmtimer_systimer_init);
753 TIMER_OF_DECLARE(systimer_am3ms, "ti,am335x-timer-1ms", dmtimer_systimer_init);
754 TIMER_OF_DECLARE(systimer_dm814, "ti,dm814-timer", dmtimer_systimer_init);
755 TIMER_OF_DECLARE(systimer_dm816, "ti,dm816-timer", dmtimer_systimer_init);