i.MX6UL hangs when starting LCD if IMX6UL_CLK_CAAM_ACLK clock are disabled

cancel
Showing results for 
Search instead for 
Did you mean: 

i.MX6UL hangs when starting LCD if IMX6UL_CLK_CAAM_ACLK clock are disabled

1,248 Views
jdepedro
Contributor IV

Hello,

I found out that a closed (HAB enabled) device (i.MX6UL-2) was not booting. After some debugging, the root cause seems to be enabling the LCD after the HAB has been used to authenticate images. This is what happens when reproducing the problem:

  1. U-Boot (signed) boots, starts to boot the device.
  2. During boot, U-Boot authenticates the kernel image before running it. In the process of doing so, it enables some clocks, then uses the HAB to authenticate, and the disables those clocks. (See code fragment in [1])

    Note: This creates a significant difference: In this case those clocks are disabled, but usually all clocks are enabled (See clock configuration [2])
  3. The kernel starts booting. Eventually the LCD driver loads, and then the target hangs.
    Further debugging shows that the line which makes the kernel hang is:

    writel(CTRL_RUN, host->base + LCDC_CTRL + REG_SET);

    documented as:

    pastedImage_4.png

    Note however that the device does not hang on that instruction, but some time after that has been executed.

The following workarounds have been tested and avoid the problem:

  • Remove the authentication from U-Boot.
    • Then the clocks are never disabled, and all works fine.
  • Remove the LCD driver.
    • Then the RUN register of the eLCDIF interface is never set, and the device does not hang
  • Just removing the problematic line and leaving the LCD driver probe.
    • That is, commenting
      //writel(CTRL_RUN, host->base + LCDC_CTRL + REG_SET);
    • Obviously, with this 'workaround' LCD stops working
  • Enable the clocks very soon in the kernel:
    • The following patch works:
      diff --git a/arch/arm/mach-imx/clk-imx6ul.c b/arch/arm/mach-imx/clk-imx6ul.c
      index 0957ab83de57..2949e4fa70b1 100644
      --- a/arch/arm/mach-imx/clk-imx6ul.c
      +++ b/arch/arm/mach-imx/clk-imx6ul.c
      @@ -399,6 +399,18 @@ static void __init imx6ul_clocks_init(struct device_node *ccm_node)
      clks[IMX6UL_CLK_PWM6] = imx_clk_gate2("pwm6", "perclk", base + 0x80, 28);
      clks[IMX6UL_CLK_PWM7] = imx_clk_gate2("Pwm7", "perclk", base + 0x80, 30);

      + clk_prepare_enable(clks[IMX6UL_CLK_CAAM_MEM]);
      + clk_prepare_enable(clks[IMX6UL_CLK_CAAM_ACLK]);
      + clk_prepare_enable(clks[IMX6UL_CLK_CAAM_IPG]);
      + clk_prepare_enable(clks[IMX6UL_CLK_EIM]);
    • Enabling the clocks a bit later (for example in machine code) does not work. Even introducing delays (up to 2 seconds)

It seems very strange that those clocks are used somehow by the eLCDIF controller. Could the documentation be wrong and those clocks are actually others (bad register offset)? Could those clocks actually be necessary for LCD?

I would like confirmation from NXP about this.

Also, seems like there is a similar problem when disabling the OCOTP clocks (see Linux kernel hangs on i.MX6UL after early read of OTP registers).

Code fragments:

[1] U-Boot code for authenticating images:

uint32_t authenticate_image(uint32_t ddr_start, uint32_t image_size)
{

        (...)

         hab_caam_clock_enable(1);

         (...)

          hab_caam_clock_enable(0);

}

void hab_caam_clock_enable(unsigned char enable)
{
u32 reg;

/* CG4 ~ CG6, CAAM clocks */
reg = __raw_readl(&imx_ccm->CCGR0);
if (enable)
reg |= (MXC_CCM_CCGR0_CAAM_WRAPPER_IPG_MASK |
MXC_CCM_CCGR0_CAAM_WRAPPER_ACLK_MASK |
MXC_CCM_CCGR0_CAAM_SECURE_MEM_MASK);
else
reg &= ~(MXC_CCM_CCGR0_CAAM_WRAPPER_IPG_MASK |
MXC_CCM_CCGR0_CAAM_WRAPPER_ACLK_MASK |
MXC_CCM_CCGR0_CAAM_SECURE_MEM_MASK);
__raw_writel(reg, &imx_ccm->CCGR0);

/* EMI slow clk */
reg = __raw_readl(&imx_ccm->CCGR6);
if (enable)
reg |= MXC_CCM_CCGR6_EMI_SLOW_MASK;
else
reg &= ~MXC_CCM_CCGR6_EMI_SLOW_MASK;
__raw_writel(reg, &imx_ccm->CCGR6);
}

[2] By default all clocks are enabled (fragment from DCD, in U-Boot)

/*
* Device Configuration Data (DCD)
*
* Each entry must have the format:
* Addr-type Address Value
*
* where:
* Addr-type register length (1,2 or 4 bytes)
* Address absolute address of the register
* value value to be stored in the register
*/

/* Enable all clocks */
DATA 4 0x020c4068 0xffffffff
DATA 4 0x020c406c 0xffffffff
DATA 4 0x020c4070 0xffffffff
DATA 4 0x020c4074 0xffffffff
DATA 4 0x020c4078 0xffffffff
DATA 4 0x020c407c 0xffffffff
DATA 4 0x020c4080 0xffffffff

Labels (1)
0 Kudos
10 Replies

142 Views
jdepedro
Contributor IV

I have been able to concrete more, the problem is caused when disabling ONLY the CAAM_WRAPPER_ACLK clock. In other words, this U-Boot patch makes it work:

diff --git a/arch/arm/cpu/armv7/mx6/clock.c b/arch/arm/cpu/armv7/mx6/clock.c
index e5fa6c20f9ab..3ad759590da5 100644
--- a/arch/arm/cpu/armv7/mx6/clock.c
+++ b/arch/arm/cpu/armv7/mx6/clock.c
@@ -1172,7 +1172,6 @@ void hab_caam_clock_enable(unsigned char enable)
MXC_CCM_CCGR0_CAAM_SECURE_MEM_MASK);
else
reg &= ~(MXC_CCM_CCGR0_CAAM_WRAPPER_IPG_MASK |
- MXC_CCM_CCGR0_CAAM_WRAPPER_ACLK_MASK |
MXC_CCM_CCGR0_CAAM_SECURE_MEM_MASK);
__raw_writel(reg, &imx_ccm->CCGR0);

0 Kudos

142 Views
allenivester
Contributor III

This is a year late, but thought I'd point something out I found with a similar problem.

For some reason, the hab_caam_clock_enable() function also touches the eim_slow clock.  When you enable CAAM, it enables EIM.  When you disable CAAM (which authenticate_image() does), it disables EIM.  So if you authenticate an app / OS image that uses some peripheral on EIM, unless that app / OS re-enables EIM clock itself, it's just going to hang.  Perhaps the LCD interface from the OP is on EIM.

My fix for this is different from Jose's.  Rather than prevent disable of CAAM_wrapper, I modified authenticate_image to save the current EIM clock status before enabling CAAM and then restore EIM clock after disabling CAAM.  This way, eim_slow_clock returns to its original value once the image auth has finished, and everything works fine.

NOTE:  I don't see any reason for HAB / CAAM to need to use EIM, so the only reason I can think why hab_caam_clock_enable() modifies the eim_slow_clock is that Freescale thought "well, it's possible someone may want to include EIM addresses in the CSF for HAB, so let's go ahead and enable EIM clocks in case they didn't do it themselves."  Regardless if that was the reason (and I hope it's not, since that's not appropriate), u-boot should at least restore the clocks when it is done with CAAM.  That at least seems obvious.

0 Kudos

142 Views
jdepedro
Contributor IV

Thanks for sharing this information.

0 Kudos

142 Views
igorpadykov
NXP TechSupport
NXP TechSupport

Hi Jose

used clocks can be found in Table 18-3. System Clocks, Gating, and Override i.MX6UL RM,

regarding "disabling CAAM_WRAPPER_ACLK clock" seems this may be

expected that in HAB enabled devices all CAAM clocks should be enabled,

otherwise it may cause probelms.

http://cache.freescale.com/files/32bit/doc/ref_manual/IMX6ULRM.pdf 

Best regards
igor

0 Kudos

142 Views
jdepedro
Contributor IV

Hi Igor,

From the table 18-3, it seems this clock is only used for the CAAM, so it does not make sense that the device hangs during LCD probing.

>> seems this may be expected that in HAB enabled devices all CAAM clocks should be enabled, otherwise it may cause probelms.

This problem is reproducible both in closed (HAB enabled) and in open (HAB disabled) devices: If you manually disable the clock on U-Boot and then the LCD driver probes, the device hangs even if it is not closed

Could you comment?

0 Kudos

142 Views
igorpadykov
NXP TechSupport
NXP TechSupport

Hi Jose

>This problem is reproducible both in closed (HAB enabled) and in open (HAB disabled) devices: If you manually

>disable the clock on U-Boot and then the LCD driver probes, the device hangs even if it is not closed

if image has CAAM driver, it will require all CAAM clocks enabled, otherwise problems may occur.

One can disable (remove) CAAM driver from image using sect.50.6 Driver Configuration attached Linux Manual

and test if problem persist.

Best regards
igor

0 Kudos

142 Views
jdepedro
Contributor IV

Hi Igor,

Any other information on this topic? Is NXP looking into it?

0 Kudos

142 Views
igorpadykov
NXP TechSupport
NXP TechSupport

Hi Jose

could you provide steps how this can be reproduced on i.MX6UL EVK

with Demo Image

http://www.nxp.com/webapp/Download?colCode=L4.1.15_2.0.1_iMX6UL7D&appType=license&location=null&Pare... 

Best regards
igor

0 Kudos

142 Views
jdepedro
Contributor IV

Sorry for the delay.

I don't think it can be reproduced with the precompiled binaries, as the U-Boot image does not include secure boot support, and there is no way to disable the CAAM clocks from U-Boot (using the precompiled binary) and then boot.

Would the test be okay if we used a sligthly modified U-Boot which just disables those clocks and then boots the kernel? Or modify the DCD table so that those clocks are not enabled and test?.

0 Kudos

142 Views
jdepedro
Contributor IV

Hi Igor,

thanks for your answer. Unfortunately, the problem persists even if the CAAM driver is not enabled.

Note that the device hangs BEFORE probing the CAAM driver anyways.

0 Kudos