GPT capture sample on M4 seems to hang on Linux boot

cancel
Showing results for 
Search instead for 
Did you mean: 

GPT capture sample on M4 seems to hang on Linux boot

2,393 Views
gowricp
Contributor II

Platform: iMX8MQ EVK

Linux kernel: 4.14.78

Yocto: imx-linux-sumo  4.14.98-1.0.0 GA

I tried running the GPT capture sample in SDK 2.5.1 on the M4. I have an external signal connected to GPT1_CAPTURE1 via TP 803. This works just fine till Linux starts to boot. At some point during bootup, the GPT sample stops working. I have disabled sound card support entirely and notice that GPT1 is disabled in the device tree (<yocto_build_dir>/tmp/work-shared/imx8mqevk/kernel-source/arch/arm64/boot/dts/freescale/fsl-imx8mq.dtsi). Table 2-3 in the Linux reference manual states that iMX8M uses the System Counter Timer instead of GPT. Given what I know, I do not understand if there is a resource conflict between Linux and M4, or in general, why this sample would stop working when Linux starts to come up.

Also, it looks like for this platform, GPT1 is the only timer with a pin out for capture channels so I can't use any other timers on the M4. Any help would be greatly appreciated!

Labels (2)
4 Replies

1,020 Views
jack-cap
Contributor III

Have you solved the problem? How can you solve it? I have encountered similar problems. Can you help me solve this problem? Thank you.

The question is in the link below.

https://community.nxp.com/thread/515260 

0 Kudos

1,020 Views
ryandeville2
NXP Employee
NXP Employee

Hi Gowri,

For these types of problems, often the easiest approach to debug the issue is to look at the actual relevant SoC registers to attempt to determine what happened.  So why would the GPT IP module stop working during Linux boot?

While not an exhaustive list, a couple of possibilities immediately jump off the page:

      1.  The iomux was reconfigured for a different purpose

      2.  The clocks going to the GPT IP changed (or the clock gate was disabled)

      3.  The GPT itself was reconfigured.

 

The first step is to head to the SoC reference manual to determine what other IP is multiplexed to the I/O in question:

pastedImage_2.png

Taking a look at the i.MX8MQ device tree found in /arch/arm64/boot/dts/freescale/fsl-imx8mq-evk.dts, we see an sai5 entry, and it is enabled.  This indicates that when Linux configures the device tree, our GPT1_CAPTURE1 will be reconfigured to the SAI5 IP.  Thus we need to disable this device tree node.  Note that there is already a pre-made device tree for the RPMSG demo, targetted for M4 operation.  So let's modify that instead, and configure U-boot to alway load that:

/arch/arm64/boot/dts/freescale/fsl-imx8mq-evk-m4.dts

At the bottom, let's add an entry:

&sai5 {

   status = "disabled";

};

After recompiling, and copying the file to our non-volatile storage, we now have the updated M-4 DTB in our FAT partition.  We can then set it to be loaded by Linux by changing the fdt_file u-boot environment variable.

u-boot> editenv fdt_file

edit: fsl-imx8mq-evk-m4.dtb

u-boot> saveenv

u-boot> fatload mmc 1:1 0x7e0000 gpt_capture.bin

u-boot> bootaux 0x7e0000

u-boot> boot

Huh, still exhibits the same behavior.  NOTE: this does NOT mean we were wrong, it just means there is another issue in addition to this one.

So, on to step 2: let's find out if there is something going wrong with the clocks/GPT configuration.  U-boot and the validation images for linux have tools to peek/poke physical addresses.  Let's do a before and after comparison to determine what is going wrong.

So what registers are we interested in?  Well, taking a look back in the SoC Reference Manual, we can look at the clock tree to determine where the problem could be:

pastedImage_3.png

So there is a mux that could have changed, pre and post dividers, as well as a clock gate (CCRG16):

pastedImage_4.png

Now, we need to find what manages the GPT1_CLK_ROOT:

pastedImage_5.png

So clock slice 107 controls the clock root, need to find that register:

pastedImage_6.png

pastedImage_7.png

pastedImage_8.png

pastedImage_9.png

pastedImage_10.png

and et cetera.

We would also like to look at the GPT configuration, just in case that changed:

pastedImage_11.png

Going back into u-boot, let's peek and poke those registers!:

u-boot=> fatload mmc 1:1 0x7e0000 gpt_timer.bin

17316 bytes read in 25 ms (675.8 KiB/s)

u-boot=> bootaux 0x7e0000

## Starting auxiliary core at 0x007E0000 ...

u-boot=> md 0x30384100 1                         # Clock gate CCGR 16

30384100: 00000032                               2...

u-boot=> md 0x30360030 1                         # CCM_ANALOG_SYS_PLL1_CFG0

30360030: 82aaaa08                               ....

u-boot=> md 3038b580 1                           # Clock source 107

3038b580: 12000003                               ....

u-boot=> md 302d0000 1                           # GPT1 configuration

302d0000: 0000006b                               k...

u-boot=> md 302d0004 1

302d0004: 00000002                               ....

u-boot=> md 302d0008 1

302d0008: 00000000                               ....

u-boot=> md 302d000c 1

302d000c: 00000001                               ....

u-boot=> md 302d0010 1

302d0010: 01fca055                               U...

u-boot=> md 302d0014 1

302d0014: ffffffff                               ....

u-boot=> md 302d0018 1

302d0018: ffffffff                               ....

u-boot=> md 302d0024 1

302d0024: 010096c3  

Ok, that's great.  We see the configuration of both the basic clocks and the GPT1.  Next, let's boot Linux and see what changes (note that you will need to build the validation image OR add unit_tests to your build):

root@imx8mqevk:~# cd /unit_tests/

root@imx8mqevk:/unit_tests# ./memtool 0x30384100 1

E

Reading 0x1 count starting at address 0x30384100

 

0x30384100:  00000032

 

root@imx8mqevk:/unit_tests# ./memtool 0x30360030 1

E

Reading 0x1 count starting at address 0x30360030

 

0x30360030:  82AAAA08

 

root@imx8mqevk:/unit_tests# ./memtool 0x3038b580 1

E

Reading 0x1 count starting at address 0x3038B580

 

0x3038B580:  02000003

OK, whoa!  Something changed, what is this bit?  Back to the Reference Manual:

pastedImage_15.png

pastedImage_14.png

Ouch, Linux turned off our clock!!  What the heck, man?!

So, then the question becomes, where is Linux going squirrelly?

NXP adds a separate folder for i.MX in the Linux clocks driver - /drivers/clk/imx/clk-imx8mq.c holds the init function for the clocks.  A quick perusal shows that line 563 seems suspect:

https://source.codeaurora.org/external/imx/linux-imx/tree/drivers/clk/imx/clk-imx8mq.c?h=imx_4.14.78...

There is also a clk.h and clk.c that holds many of the definitions, and can be investigated.  Chasing this down a bit, we see that when clk_register_gate2() is called by imx_clk_gate4(), this bit field is disabled. 

So the easiest approach is just to comment out that line, as we want the M-4 to control that clock.

Recompile, not only the Linux, but also the full image.  Recopy gpt_capture.bin back to the non-volatile storage after flashing the new image.  Proceed to test (note that I do not have a breakout board handy right now, so I'm testing with gpt_timer.bin) -- YES!  VICTORY!

So, is this a bug in the NXP SDK?  No, as NXP we want to provide GPT functionality to Linux, it just happens in your application that is not the desired behavior.

I realize that I've been a little long-winded, but the purpose of this is to demonstrate HOW these types of issues are troubleshoot.  Hopefully, this will be helpful in future efforts.

Further note, we could have done this and produced some really nasty bugs.  Note that there is a gpt1 node in our device tree -- that's one reason to use the M-4 DTB, as it is already disabled in that device tree.  It's usually best to start with the device tree, then when that is exhausted, start peeking/poking registers.  For the vast majority of these types of issues, JTAG debugging is not required. When using JTAG, make sure you HALT the processors before you start to read/write the registers.

Regards,

Ryan

1,020 Views
igorpadykov
NXP TechSupport
NXP TechSupport

Hi Gowri

one can use linux/arch/arm64/boot/dts/freescale/fsl-imx8mq-evk-m4.dts

fsl-imx8mq-evk-m4.dts\freescale\dts\boot\arm64\arch - linux-imx - i.MX Linux kernel 

and procedure for running rpmsg m4 examples described in sect.2.8.5 Running i.MX RPMsg Test Programs

attached Linux Manual.

rpmsg\test - imx-test - i.MX Driver Test Application Software 

Using Cortex-M4 from Linux 

There are other approaches for running m4 appilcations from linux:

GitHub - NXPmicro/imx-m4fwloader: Tool for loading firmware to M4 core on i.MX6SX and 7D 

m4ctrl - M4 Control Tool for i.MX platforms 

AN5317 Loading Code on Cortex-M4 from Linux for the i.MX 6SoloX and i.MX7Dual/7Solo Application Processors

https://www.nxp.com/docs/en/application-note/AN5317.pdf 

Yes, GPT1 is the only timer with a external pin out for capture.

Best regards
igor
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos

1,020 Views
gowricp
Contributor II

Thanks so much for your response Igor. I will look into the documents you pointed me to but wanted to give a quick update, I did set status to enabled for GPT1 in the fsl-imx8mq-evk-m4.dts file but that didn't help either. Also, I ran the GPT sample while I was in the uboot environment and it ran just fine. It was when I continued on to boot the Linux kernel when the sample seemed to stop working. Thought I should make that clear.

I have run both RPMSG demo apps and those work fine. It seemed to me that GPT1 was not being used by Linux in any way but since the M4 sample seems to freeze, perhaps it actually is being used in some way? Can't seem to figure this out.

I also tried to set a hardware watchpoint in kgdb for the GPT1 control register to try to narrow down what kernel component might be using it but that didn't work. It looks like some eFuses need changing? Is there updated documentation for iMX8? I see some for some flavors of 6 and 7.

0 Kudos