GPT as system timer, EPIT as user timer

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

GPT as system timer, EPIT as user timer

3,639 Views
nluca
Contributor III

Hi,

I'm working with a custom i.MX6S board and Linux OS.

I've switched on the EPIT2 timer by initializing it and I want it to generate a square wave on the epit2_event_out pin. I've correctly set up the OCIE bit in the control register, a value in the LR and a value in the CMPR. The problem is that no compare event seems to occur. The register is counting for the all 32 bits and I have the output pin toggling every 67 seconds, which means it's working but is not taking care about the compare register. Even /proc/interrupts is showing that the EPIT2 interrupt is set up, but has never occurred.

In the meanwhile the GPT timer is working as system tick timer and this is confirmed by the booting messages that it has been chosen as system timer.

Why the EPIT2 interrupt is not occurring even if correctly setup?

Thanks,

Luca

Labels (3)
7 Replies

1,716 Views
sunyu
Contributor II

Hi,Luca!

     I would like to ask this patch is based on which version of linux?

Best Regards,

Sunyu

0 Kudos

1,716 Views
sunyu
Contributor II

my linux version is linux-3.0.35, and I can not find arch/arm/mach-imx/clk-imx6q.c in my kernel.

0 Kudos

1,716 Views
alejandrolozan1
NXP Employee
NXP Employee

Hi,

Can you share the steps you followed and the modifications of your source code?

Best Regards,

Alejandro

0 Kudos

1,716 Views
nluca
Contributor III

Hi Alejandro,

I've made these modifications:

  • added a call at the EPIT initialization function in arch/arm/mach-imx/clk-imx6q.c
  • added a call at setup_sched_clock in arch/arm/mach-imx/epit.c
  • avoided the use of the EPIT timer during the check for override clocksource in /kernel/time/clocksource.c (kernel is now using GPT as system timer)

Before these modifications, I commented out the check for the clocksource in kernel/time/clocksource.c, so that the kernel wasn't using either GPT or EPIT. EPIT was used by me with success and interrupts were occurring correctly. However, the resolution of the Kernel time (which I need for a synchronization purpose) dropped to 10ms (not enough for me). After a further modification to clocksource.c (the one mentioned above), the Kernel is using GPT as system timer, and the Kernel time has a much better resolution. The problem is that now the EPIT is not taking care of the compare register (I've checked it's written correctly during the initialization) anymore. The EPIT2_EVENT_OUT pin is now toggling only every 65s, which is the time the EPIT timer takes to roll over from 0xFFFFFFFF to 0 at 66MHz (frequency of the ipg clock).

I don't think the problem is in the EPIT initialization code, because when the kernel time was given by something else than EPIT or GPT (I don't actually know by who) it was working correctly and interrupt were occurring as I wanted. I think the problem is in the interrupt handling/masking by the kernel.

Is it possible having both the timer running and generating interrupts?

Any suggestion is appreciated!

Thanks,

Luca

0 Kudos

1,716 Views
alejandrolozan1
NXP Employee
NXP Employee

Hi,

I have skimmed through your code. And I have a few comments:

You set the load register to FFF value.

__raw_writel(0xfff, timer_base + EPITLR);

With this I suppose you want to use the set and forget mode. If so, you need to set the RLD bit in the EPIT_CR register.

If it is not set, the timer will work in free-running mode as per my understanding and even if the compare is set, this will raise every overflow of the timer, which would end up like comparing FFFF_FFFF but in a different phase.

And one last thing:

__raw_writel(EPITCR_EN | EPITCR_OCIEN | EPITCR_CLKSRC_PERIPHERAL | EPITCR_WAITEN | EPITCR_OM_TOGGLE,

             timer_base + EPITCR)

I recommned you to configure the timer before and at the end just enable it. In other words split the above line in two.

__raw_writel( EPITCR_OCIEN | EPITCR_CLKSRC_PERIPHERAL | EPITCR_WAITEN | EPITCR_OM_TOGGLE,

             timer_base + EPITCR);

__raw_writel(EPITCR_EN , timer_base + EPITCR);

Best Regards,

Alejandro

0 Kudos

1,716 Views
alejandrolozan1
NXP Employee
NXP Employee

Hi,

Can you share the code you modified?

/Alejandro

0 Kudos

1,716 Views
nluca
Contributor III

Hi Alejandro,

Attached is the diff patch of the modified code. We still can't get out of this problem and the output pin in no more toggling at the desired frequency.

Please, share your thought and suggestions.

Thanks,

Luca

0 Kudos