VF61 suspend A5 linux while M4 is running

Hello all,

Is it possible with current 2.6.1Beta1 to get to this high level scenario on a VF61?

  1. M4 always running (low MHz ok), with one UART on, control over GPIO, one FEC+PHY on and both USB controllers on in host mode. A5 suspended as deeply as possible with DDR contents preserved

  2. M4 able to wake up A5 to run a job in Linux, A5 suspends itself when job is done after passing results to M4

Currently remoteproc seems to require initcall_blacklist=sram_init boot option, which disables the “mem” suspend mode, but it seems that even “standby” turns off the M4 (at least FreeRTOS hellow-world.elf does no longer echo keystrokes on UART_B). “freeze” still has the M4 and UART running.

If not possible, any tips on how to modify the suspend code to leave the M4 running with some of the OCRAM region reserved for the M4?



I think this can be generalized a bit.

The part about M4 can be ignored as it is beside the real point. However I did find a way to have both M4 code running outside of the 0x4000 bytes used for LPSTOP2 by limiting the ranges of &ocram0 in dts, removing &ocram1 node completely, updating the ranges in the &cortexm4 node, modifying M4 linker script for the FreeRTOS example accordingly, and adding -z --max-page-size=0x4000 to the linker options to change from the default 0x8000 page size.

Sticking to A5 only, what seems to be the real problem in keeping Ethernet and USB up, is that LPSTOP2 turns off the two cores and power-gates the peripherals. What I’m looking for is an LPRUN mode which suspends to SRAM, turning DDR into power save mode and turning off as much as possible, but leaves Ethernet and USB peripherals untouched, and then wakes up from wfi instruction through Ethernet or USB interrupt.

This seems to need a substantial code change to the suspend code. Any tips or no-you’re-wrongs?

In the current BSP V2.6.1Beta1 there is no suspend mode supported when M4 is running. We also don’t have plans to support suspend with M4 involved.

The main reason for that is lack of (good) hardware support. On Vybrid, the A5 CPU clock is used to derive the M4 clock and the bus clock. Hence you cannot turn off the A5 clock while using the M4 core… The power gating situation looks similar: There is one big power domain in which both cores live in (PD0). There is a second power domain (PD1) which only covers some wake-up capable peripherals.

It might be possible to put the DDR3 memory in suspend and the A5 in a idle state, but the whole SoC will still consume quite some power since all clocks and power domains need to be still on. Hence the usefulness of such a combination is questionable…

That said, we are fully aware of such use cases. The newer Colibri iMX7 modules also have the HMP architecture, and its SoC has a much more advanced architecture: The Cortex-A7 cores are in a separate power domain, the clocks can be configured individually and there are mechanisms to help software supporting “cross operating system” sleep modes. We plan to build a demo around the Colibri iMX7, but this is still some months out. But already now I really recommend you to consider using Colibri iMX7 for your project.

LPRUN should be a doable low power mode. You probably would start with looking at the “standby” code (which implements STOP) and just disable the STOP part of it. DDR in self-refresh is currently written in assembler since Linux kernel code is not position independent… C core relocates the assembler written lowest level code to SRAM, jumps to that function in SRAM and then puts DDR in self-refresh (have a look at arch/arm/mach-imx/pm-vf610.c and arch/arm/mach-imx/suspend-vf610.S). Currently all the code disables almost all clocks, so you would have to change that. But that said, it is certainly not an easy task, and also here it is questionable how much power savings you get from that: You need to keep quite some PLLs on to have USB and Ethernet working…

Given that you use something power hungry as Ethernet (which requires almost more power than the whole reset of the module by itself), it seems questionable to me whether the savings you would gain from putting DDR3 in to self-refresh are even worthwhile…