This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

am335x resume

Other Parts Discussed in Thread: AM3352

Hi.

I have a custom board with an am3352 and am having troubles with resume. 

The A8 executes the wfi instruction and that causes the expected interrupt in the M3 (extint34_handle runs).  Also, following a wakeup event (UART0 or GPIO), the M3 gets an interrupt and attempts to resume the A8.  The A8 wakeup isn't happening though.

From other posts, I see that the failure to disable a power or clock domain during suspend can cause resume to fail.  Since the M3 has no console, I am not able to dump the PM and CM registers.  However, I have added checks to extint34_handler() to verify that expected idle states are entered and clocks disabled.  I did find and fix a couple that needed to be disabled (GPIO and Timer1).

Currently, all but the following are disabled/inactive:

  • CLKACTIVITY_L4_WKUP_GCLK active in CM_WKUP_CLKSTCTRL register
  • L4WKUP not disabled (CM_WKUP_L4WKUP_CLKCTRL)
  • DEBUGSS not disabled (CM_WKUP_DEBUGSS_CLKCTRL)
  • L3_AON not disabled (CM_L3_AON_CLKSTCTRL)
  • The digitally controlled oscillator (CM_CLKDCOLDO_DPLL_PER) CLKOUT1 (CM_DIV_M4_DPLL_CORE) CLKOUT2 (CM_DIV_M5_DPLL_CORE)

Disabling these does not seem possible (hangs).  Certainly it is reasonable that the L3 and L4 clocks, for example, are needed.

I have also verified that the first IPC register contains the expected address for the ROM code to jump to the post-DS0 code in sleep33xx.S (40300740).  Dumping the data at that address matches a disassembly of am33xx_resume_from_deep_sleep.

What else should I be looking for that would case the A8 to not start when the M3 turns on the MPU domain via CM_MPU_CLKSTCTR?

Thanks,
    Steve

  • Hi Steve,
     
    What software are you using?
  • Hi Biser.

    I'm using Linux -- SDK05.07.00.00

    Regards,

        Steve

  • Hi Steve,

    Please try using the latest SDK version 06.00.00.00, I think there were some MPU domain related fixes in the latest version of the SDK.

    Best regards,
    Miroslav

  • Hi Miroslav, Biser.


    I do not see anything in the SDK 06.00.00.00 differences related to the MPU domain.  Can you tell me what you were referring to?

    The changes seem to be related to SmartReflex, adding ES2.1 support (I'm on ES 1.0), SGX initialization (my chip has no SGX), Beaglebone Black and MUSB Gadget DMA.  The only change I found related to suspend regards VT switch.

    Nonetheless, I have updated to SDK 06.00.00.00.  I see no difference.  At resume, the M3 code runs and attempts to start up the A8, but there is no response from the A8.

    So I am back to my original question: what can prevent the A8 from starting up when enabled by the M3?

    Or put another way, what exactly causes the ROM code to start running on the A8?  Initially, applying power to the chip causes the ROM code to start.  But for suspend the voltage rails are still on (just at a lower voltage) so that does not apply to resume.  I gathered that it was the turning on of the MPU clock and power domains that caused the ROM code to start, but...

    Using the M3 code, I have verified that when deep sleep 0 is entered, the MPU clock is disabled (CM_MPU_MPU_CLKCTRL).  Also, that the MPU power domain is off (PM_MPU_PWRSTST).  Likewise, I have verified at resume time that the MPU clock is enabled and the MPU power domain is on.  So it seems that the MPU domains turning on is not sufficient to ensure that the ROM code starts.  What else is required?

    Also, the TRM (26.1.11.2) indicates that the ROM code checks for a valid address in the first IPC register.  In my case, that is set to 40300750 which is in internal RAM and therefore valid.  What other tests are performed by the ROM code that may prevent it jumping to the address indicated by the IPC register?

    Thanks,

        Steve

  • Hi Steve,

    Can you check that the master oscillator (OSC0) goes off and DDR CKE signal goes low on suspend ? 

    Do you have a JTAG debugger to connect to M3 for debugging ? The PRCM register space is on L4_WKUP peripheral memory map and can be accessible from M3 when it's active. How did you check M3 received an interrupt by a wakeup event.

    Suspend/Resume works with the SDK on the GP EVM. Do you have a TI GP EVM you could use it as reference ? 

  • Hi Kazunobu.

    > Can you check that the master oscillator (OSC0) goes off

    The PM firmware running on the M3 writes to the deepsleep_ctrl register to set dsenable and gate the master oscillator.

    Beyond that, it does not seem possible to verify that the master oscillator actually goes off.  If, before suspend, the M3 reads back the deepsleep_ctrl register, the oscillator is not yet gated.  Likewise, if the M3 reads it after a wakeup event and before starting the A8, it is not gated.  This seems consistent with the TRM.  Section 8.1.4.4 indicates that the master oscillator will become disabled when the M3 enters standby and will be re-enabled when a wakeup event occurs.  So other than confirming the setting of the bit in the registers, it does not seem possible to confirm the clock gating.

    > and DDR CKE signal goes low on suspend ? 

    Yes.  This is a result of a pull-down resistor on the line.  There is a note in the Linux driver that the VTP must be disabled in order to get to a low power state due to a bug in the silicon (though I don't see a mention of this in the Errata).  So the low CKE I see is due to the resistor and not the EMIF PHY.

    Are you asking this to verify that the contents of the DRAM are still good?  Note that ROM code should be jumping to code in the internal RAM, so it is not as far as using the DRAM yet.

    > Do you have a JTAG debugger to connect to M3 for debugging ?

    Unfortunately, I don't.

    > The PRCM register space is on L4_WKUP peripheral memory map and can be accessible from M3 when
    > it's active.

    That is what I used to verify that the various clocks and power domains are off (see the exceptions in my first post).  See the attached code.  This is done at the end of the M3 handler code that runs when the A8 executes WFI.

    After using the M3's register reads to verify that the clocks and power domains are off, I re-enable GPIO0 and set a pin high and I see it on my 'scope.  If any of the tests fail, the code goes into a while(1);  So the pin going high tells me that all tests passed.  I then "#if 0" out the checks to run normally (so that, for example, I don't leave the handler with GPIO enabled).

    > How did you check M3 received an interrupt by a wakeup event.

    I use a similar arrangement to that described above.  In the M3 wakeup code, I added temporary code which sets the GPIO high.  I see this line go high when I enter characters on the console following suspend or press a GPIO-connected user button.

    Likewise I have temporarily added to the A8 resume code instructions which set the GPIO high.  The GPIO does not change though.  If I temporarily add the same code to the A8 suspend routine, I see the GPIO change.  With all of the GPIO test code removed, I also see no console output from the A8 during resume.

    > Suspend/Resume works with the SDK on the GP EVM. Do you have a TI GP EVM you could use it as reference ? 

    I have an EVM and, using the same BSP, that resumes properly.  However, there are necessarily code differences due to the hardware differences.  For example, the custom board uses mDDR RAM.  The Linux code running on the A8 handles DDR2 and DDR3 suspend differently and, until I added it, had no code for mDDR.  There are other differences in the peripherals surrounding the chip as well.  There is also one AM335x difference.  While both are ES1.0, the EVM's has an SGX while the custom board's AM335x does not.

    As much as possible with the hardware differences, I have made the EVM kernel configurations and initializations to match the custom board.  Having looked at the remaining differences many times, I do not see anything that could explain the failure to suspend.  This is why I am trying to better understand what causes the A8 to start running the ROM code other than removing and reapplying the power.

    In case the A8 is indeed starting up but the ROM code is failing to execute the code in internal RAM, do you have any comment on the checks performed by the ROM code (similar to a valid address in the first IPC register as mentioned in the TRM)?

    Thanks,

        Steve

  • Steve Schefter said:

    > Can you check that the master oscillator (OSC0) goes off

    The PM firmware running on the M3 writes to the deepsleep_ctrl register to set dsenable and gate the master oscillator.

    Beyond that, it does not seem possible to verify that the master oscillator actually goes off.  If, before suspend, the M3 reads back the deepsleep_ctrl register, the oscillator is not yet gated.  Likewise, if the M3 reads it after a wakeup event and before starting the A8, it is not gated.  This seems consistent with the TRM.  Section 8.1.4.4 indicates that the master oscillator will become disabled when the M3 enters standby and will be re-enabled when a wakeup event occurs.  So other than confirming the setting of the bit in the registers, it does not seem possible to confirm the clock gating.

    If some clocks are not gated, the OSC0 doesn't go off in suspend even if the dsenable bit in deepsleep_ctrl register is set. To confirm everything was ok in suspend path and processor was in DeepSleep0 state where MPU power domain is turned off, it would be better to check OSC0 output on your board by oscilloscope and see if it's actually turned off in suspend. If processor doesn't go to DeepSleep0 and MPU power domain remains active in suspend, the ROM code won't be executed on resume. 

    Steve Schefter said:

    > and DDR CKE signal goes low on suspend ? 

    Yes.  This is a result of a pull-down resistor on the line.  There is a note in the Linux driver that the VTP must be disabled in order to get to a low power state due to a bug in the silicon (though I don't see a mention of this in the Errata).  So the low CKE I see is due to the resistor and not the EMIF PHY.

    Are you asking this to verify that the contents of the DRAM are still good?  Note that ROM code should be jumping to code in the internal RAM, so it is not as far as using the DRAM yet.

    In DeepSleep (Linux suspend), EMIF/DDRPHY should drive the CKE signal low to put DDR in self refresh. This is also a check point to see suspend path was correctly executed and DDR was put in self refresh. Do you have an external pull-down on the CKE signal or are you referring to an internal pull  down on chip ?

    Steve Schefter said:
    In case the A8 is indeed starting up but the ROM code is failing to execute the code in internal RAM, do you have any comment on the checks performed by the ROM code (similar to a valid address in the first IPC register as mentioned in the TRM)?

    Is it possible to check MPU power domain state in M3 code before it's enabled in resume path ? If MPU power domain was not turned off in suspend, the ROM code cannot be executed on resume.  

  • Hi Kazunobu.

    Kazunobu Shin said:
    If some clocks are not gated, the OSC0 doesn't go off in suspend even if the dsenable bit in deepsleep_ctrl register is set. To confirm everything was ok in suspend path and processor was in DeepSleep0 state where MPU power domain is turned off, it would be better to check OSC0 output on your board by oscilloscope and see if it's actually turned off in suspend. If processor doesn't go to DeepSleep0 and MPU power domain remains active in suspend, the ROM code won't be executed on resume. 

    Ah, I didn't realize that the oscillator circuit would be turned off as opposed to just disabling the the clock internal to the AM335x.  I have checked and indeed both xtalin and xtalout go inactive when I enter suspend.  The 24MHz signal returns when there is a wakeup event.

    Kazunobu Shin said:
    In DeepSleep (Linux suspend), EMIF/DDRPHY should drive the CKE signal low to put DDR in self refresh. This is also a check point to see suspend path was correctly executed and DDR was put in self refresh. Do you have an external pull-down on the CKE signal or are you referring to an internal pull  down on chip ?

    There is an external pull down on the CKE line.  This was added to the design as a result of the comments in the Linux code that say the VTP needs to be disabled and, as a result, the AM335x won't be driving the CKE signal.

    As for using CKE as a checkpoint to see the suspend path, I don't think that is possible to see external to the chip given that the VTP is disabled by the Linux suspend code.  Or am I not following you on this point?

    Kazunobu Shin said:
    Is it possible to check MPU power domain state in M3 code before it's enabled in resume path ? If MPU power domain was not turned off in suspend, the ROM code cannot be executed on resume.  

    That is one of the tests in the checks.txt that I attached to my last post:
        //PM_MPU
        val = __raw_readl( 0x44E00E04);
        if (val & 0x002003f7)
        while(1)

    That is the PM_MPU_PWRSTST register.  The test verifies that the MPU PowerStateSt is OFF, the logic state is OFF, the L1, L2 and RAM memory states are OFF and the domain is not in transition.

    Regards,
        Steve

  • Steve Schefter said:
    Ah, I didn't realize that the oscillator circuit would be turned off as opposed to just disabling the the clock internal to the AM335x.  I have checked and indeed both xtalin and xtalout go inactive when I enter suspend.  The 24MHz signal returns when there is a wakeup event.

    OK, it looks all clocks are properly gated in the suspend path and initial resume path looks ok as you mentioned in your posts earlier. Thanks for checking.

    Steve Schefter said:

    There is an external pull down on the CKE line.  This was added to the design as a result of the comments in the Linux code that say the VTP needs to be disabled and, as a result, the AM335x won't be driving the CKE signal.

    As for using CKE as a checkpoint to see the suspend path, I don't think that is possible to see external to the chip given that the VTP is disabled by the Linux suspend code.  Or am I not following you on this point?

    Is it possible to monitor the CKE signal at the external pull down on oscilloscope or by multimeter ? It should go low in suspend path and come back to high in resume path. If it comes back to high in resume path on your setup, the failure point should be somewhere after the CKE signal is enabled in the resume path. 

    Steve Schefter said:
    That is the PM_MPU_PWRSTST register.  The test verifies that the MPU PowerStateSt is OFF, the logic state is OFF, the L1, L2 and RAM memory states are OFF and the domain is not in transition.

    OK, thanks for checking it. The ROM code should  boot when MPU power domain is enabled and MPU clock is gated by M3.

  • Steve Schefter said:
    I have an EVM and, using the same BSP, that resumes properly.  However, there are necessarily code differences due to the hardware differences.  For example, the custom board uses mDDR RAM.  The Linux code running on the A8 handles DDR2 and DDR3 suspend differently and, until I added it, had no code for mDDR.

    I'm attaching Linux patches for AM335x + LPDDR system. Can you please replace your modifications for LPDDR with these patches and see if it helps to resolve the issue ? The patches were tested for suspend/resume on an AM335x board with LPDDR.

    AM335x_LPDDR_patch.zip
  • Hi Kazunobu.

    Kazunobu Shin said:
    Is it possible to monitor the CKE signal at the external pull down on oscilloscope or by multimeter ? It should go low in suspend path and come back to high in resume path. If it comes back to high in resume path on your setup, the failure point should be somewhere after the CKE signal is enabled in the resume path. 

    I see CKE go low during suspend, but I don't see it go high at resume.  But since the VTP is disabled by the A8 during suspend and only re-enabled by the A8 after resume, isn't that expected?  With the VTP disabled, CKE won't be driven by the AM335x, will it?

    Regards,

        Steve

  • Hi Kazunobu.

    Kazunobu Shin said:
    I'm attaching Linux patches for AM335x + LPDDR system. Can you please replace your modifications for LPDDR with these patches and see if it helps to resolve the issue ? The patches were tested for suspend/resume on an AM335x board with LPDDR.

    Thanks!  I'll give them a try.

    Regards,
        Steve

  • A belated thank you to Kazunobu and confirmation that the provided patches enable the AM335x MPU to resume successfully.

        Steve