[Letux-kernel] jz4730-i2c - clocksource

H. Nikolaus Schaller hns at goldelico.com
Tue Mar 2 17:59:45 CET 2021


> Am 02.03.2021 um 17:08 schrieb H. Nikolaus Schaller <hns at goldelico.com>:
> 
> Hi Paul,
> I may have found something new... I did simply loop
> and collect the timer values and the sched_clock()
> in an array with later printk(). So that data collection
> is not slowed down by printk().
> 
> The interesting thing is that the timer register overflows
> and restarts - and at the same moment the sched_clock()
> jumps back. Which means that there was no cevt triggered
> snapshot in between.
> 
> My idea now was: what happens if the cevt interrupts
> are not processed correctly?
> 
> Now, ingenic-timer does:
> 
> static int ingenic_tcu_setup_cevt(unsigned int cpu)
> {
> 	struct ingenic_tcu *tcu = ingenic_tcu;
> 	struct ingenic_tcu_timer *timer = &tcu->timers[cpu];
> 	unsigned int timer_virq;
> 	struct irq_domain *domain;
> 	unsigned long rate;
> 	int err;
> 
> ...
> 	domain = irq_find_host(tcu->np);
> 	if (!domain) {
> 		err = -ENODEV;
> 		goto err_clk_disable;
> 	}
> 
> 	timer_virq = irq_create_mapping(domain, timer->channel);
> 	if (!timer_virq) {
> 		err = -EINVAL;
> 		goto err_clk_disable;
> 	}
> 
> ...
> 
> 	err = request_irq(timer_virq, ingenic_tcu_cevt_cb, IRQF_TIMER,
> 			  timer->name, timer);
> 
> 
> while ingenic-sysost.c does:
> 
> static int __init ingenic_ost_percpu_timer_init(struct device_node *np,
> 					 struct ingenic_ost *ost)
> {
> 	unsigned int timer_virq, channel = OST_CLK_PERCPU_TIMER;
> 	unsigned long rate;
> 	int err;
> 
> ...
> 
> 	timer_virq = of_irq_get(np, 0);
> 	if (!timer_virq) {
> 		err = -EINVAL;
> 		goto err_clk_disable;
> 	}
> 
> 	snprintf(ost->name, sizeof(ost->name), "OST percpu timer");
> 
> 	err = request_irq(timer_virq, ingenic_ost_cevt_cb, IRQF_TIMER,
> 			  ost->name, &ost->cevt);
> 
> So the cevt interrupt is setup differently!
> 
> Interesting is that irq_create_mapping expects some irq_hw_number_t hwirq
> but I wonder why passing the timer->channel number should be the
> right value. Well, the magic "domain" could do some translation.
> 
> The sysost uses a direct device tree based approach. Maybe nobody did care
> about OF conversion since this feature wasn't used in the jz4740 setup...
> 
> If my finding is correct this would mean that the ingenic_tcu_cevt_cb()
> is not called by the timer expiry interrupt but some other interrupt
> which happens to be fairly regular.
> 
> This would mean again that all cevt based timings are wrong and may
> come too early or too late.
> 
> I'll give it a try...

unexpected result:

[    0.000000] random: get_random_bytes called from start_kernel+0x720/0x960 with crng_init=0
[    0.000000] clocksource: ingenic-timer: mask: 0xffff max_cycles: 0xffff, max_idle_ns: 7910990 ns
[    0.000000] ingenic_tcu_init: Unable to start CPU timers: -22
[    0.000000] Failed to initialize '/timer at 10002000': -22
[    0.000000] timer_probe: no matching timers found

Maybe the code is now trying the wrong irq definition from device tree.

		interrupt-parent = <&intc>;
		interrupts = <24 23 22>;

of_irq_get(np, 0) takes line #24 which is OST0.
Ok, we should take the channel into account.

	timer_virq = of_irq_get(np, timer->channel);

Basically it turns out that of_irq_get() is a shortcut for irq_find_host+irq_create_mapping

But it only works if we remove

//		interrupt-controller;
//		#interrupt-cells = <1>;

from the TCU node...

But there is no difference..

So my theory with bad IRQ setup was again a cul-de-sac.

But it gave me another idea: I can try to log the relationship between

ingenic_tcu_cevt_set_next() and ingenic_tcu_cevt_cb()

and the OST0/1 values.

BR,
Nikolaus


> BTW: I have replaced all regmap code by direct readl/writel and IMHO
> there is a very strong argument to bypass regmap: it takes an unknown
> amount of processor cycles to read through a regmap and that it is
> used for a timer with sub-microsecond precision... Here we should
> save every unnecessary instruction to get it as fast as possible.
> 
> iMHO the same would be wise to be done for the jz4740...
> 
> BR,
> Nikolaus
> 



More information about the Letux-kernel mailing list