GPT register access from M4 blocks Linux

Hi all,

I stumbled onto a new challenge…
On the M4 of my Colibri i.MX4D, I am using timer GPT4 to toggle an I/O pin (GPT4.COMPARE3) with a frequency that is derived from an external 4MHz clock (on the GPT4.CLK pin). There are no GPT or I/O interrupts associated with this setup. After initialization, GPT4 is “kept alone”.

When running the M4 without Linux (halted in U-Boot), everything works fine and the GPT4.COMPARE3 output toggles at the frequency I want (e.g. 100kHz).
Now, when I start Linux (boot command on U-Boot prompt), things get weird:

  • There are periods in which the output signal stops. This can be several seconds. Linux boots and the console works fine.
    In this scenario, the M4 does not access any of the GPT4 registers after the initialization that was done before booting Linux
  • If, during the boot, the M4 accesses the CR register of GPT4, the Linux boot never finishes and generally ends with a system reset. (The M4 accesses GPT4->CR when I type a character on the M4 console)

To me, this looks like a conflict between Linux and the M4 concerning GPT4. The question is how exactly.
On the Linux side:

  • I have modified the device tree, such that I explicitly disable gpt4 on the highest level .dts file (I’m using Torizon 5.6 and Torizon Builder to incorporate the DT changes).
    Note that this is not really necessary since it is already disabled in imx7s.dtsi.

On the M4 side

  • I have configured the gpio mux for the two GPT4 pins
  • obtained exclusive access to GPT4 (“GPTB” in the board.h defines):
 RDC_SetPdapAccess( RDC, BOARD_GPTB_RDC_PDAP, 3 << (BOARD_DOMAIN_ID * 2), false, false);
  • I also configure the clocks for the GPT4 peripheral (not to confuse with the external clock source on the GPT4.CLK input)
//--- Enable Sys PLL PFD0 for GPTB peripheral clock (this is NOT the counter source !)
CCM_ControlGate( CCM, ccmPllGatePfd0, ccmClockNeededRunWait);

//--- Select GPTB peripheral root clock source: derived from PLL PFD0
CCM_UpdateRoot ( CCM, BOARD_GPTB_CCM_ROOT, ccmRootmuxGptSysPllPfd0, 0, 0);
CCM_EnableRoot ( CCM, BOARD_GPTB_CCM_ROOT);
CCM_ControlGate( CCM, BOARD_GPTB_CCM_CCGR, ccmClockNeededRun);

To summarize:

  • Linux does something that occasionally stops output on the GPT compare output, without changing anything (it keeps the same frequency)
    => Perhaps something with the peripheral clock tree ??
  • When the M4 tries to access a GPT4 register while Linux is booting or after it, then both Linux and the M4 are stuck and after a while, the module reboots

Does anyone have an idea of what may be going on ?

Thanks for your precious help, as always.

Jeroen

Hi all,

Problem solved !
It appeared to be the same problem as this post.
In short, as I mentioned, I assigned the System PLL PFD0 clock to the GPT peripheral and this clock seems be be modified by the Linux SHDC driver.

Assigning ccmRootmuxGptOsc24m did the trick and my output pulse is now working all the time, even when accessing the GPT4 registers.

Jeroen

1 Like