i.MX8m nano: Power consumption optimization in suspend mode

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

i.MX8m nano: Power consumption optimization in suspend mode

12,474 Views
anton_glukhov
Contributor III

Hello,

I'm trying to achieve the total power consumption <150mW in suspend mode on imx8m-nano SoC with DDR3L and PMIC BD71837, while keeping M7 core running. Here is the information regarding the Software and Hardware that we use.

Software:
Linux kernel, 5.4.70 from the repo: https://source.codeaurora.org/external/imx/linux-imx.git
branch: imx_5.4.70_2.3.0.
The current clock tree - please see in the attachment

Hardware:
SOM - AzureWave AW-PU551
imx8m-nano (with active M7 core)
RAM: DDR3L
PMIC: bd71837
eMMC:
Power tree: in attachment
Unfortunately, I cannot measure the current for each power rail and can only measure the total consumption for the SOM.

Our goals:
Achieve total power consumption in suspend mode (< 150mW), while keeping M7 core running with support following peripherals: GPT1, PWM(for one LED), control few GPIO lines, UART4 for debugging output. And being able to wake up the main core via MU or RPMSG, or any other internal mechanism.

Here are some ideas and knowledge that I've collected during the initial investigation.
1. ATF and PLL clocks. In order to reduce power consumption, we need to fine-tuning all PLLs, by disabling those that we don't need in suspend mode. Sys_pll1, sys_pll2, sys_pll3 which we can focus on.
2. DRAM PLL.
I've put this as a separate point, as it made a significant contribution during my tests. Since we put RAM into retention(refresh only) mode, we can disable DRAM PLL in the ATF code. In order to do so, please see the patch 0001-Disable-DRAM-PLL.patch.
4. PMIC.
As far as I understand, it's possible to disable some power rails in the suspend mode. Unfortunately, the PMIC that we have on the SOM, can disable only BUCK1 in suspend mode. And this BUCK1 provides the power for VDD_SOC rail. I need to investigate if we can disable others if it's possible.
5. M7 core
If we want to put DRAM in retention mode then M7 core has to use the only OCRAM. This part has to be adjusted in the linker script.

M7 core uses only clock sources that are enabled in suspend mode. In my case, I use 24MHz clock.

Clock configuration:

 

/* switch AHB NOC root to 24M first in order to configure the SYSTEM PLL1. */
CLOCK_SetRootMux(kCLOCK_RootAhb, kCLOCK_AhbRootmuxOsc24M);

/* switch AXI M7 root to 24M first in order to configure the SYSTEM PLL3. */
CLOCK_SetRootMux(kCLOCK_RootM7, kCLOCK_M7RootmuxOsc24M);

CLOCK_SetRootDivider(kCLOCK_RootUart4, 1U, 1U);
CLOCK_SetRootMux(kCLOCK_RootUart4, kCLOCK_UartRootmuxOsc24M);

CLOCK_EnableClock(kCLOCK_Rdc); /* Enable RDC clock */
CLOCK_EnableClock(kCLOCK_Ocram); /* Enable Ocram clock */

 

Additional RDC configuration:

 

void Peripheral_RdcSetting(void)
{
    rdc_periph_access_config_t periphConfig;

    RDC_GetDefaultPeriphAccessConfig(&periphConfig);
    /* Do not allow the A53 domain(domain0) to access the following peripherals. */
    periphConfig.policy = RDC_DISABLE_A53_ACCESS;
    periphConfig.periph = kRDC_Periph_UART4;
    RDC_SetPeriphAccessConfig(RDC, &periphConfig);
}

 

Additional CCM configuration (but I'm not sure that it's the correct one):

 

CCM->PLL_CTRL[6].PLL_CTRL = kCLOCK_ClockNeededRun;
CCM->PLL_CTRL[25].PLL_CTRL = kCLOCK_ClockNeededRun;
CCM->PLL_CTRL[27].PLL_CTRL = kCLOCK_ClockNeededRun;

 

 

Next step:
I would like to focus on SYS_PLL1 now. I believe that it's possible to switch it off. Could you please confirm it, based on the clock tree that I added in the attachment? From the clock tree I see that SYS_PLL1 provides the clock to the following:
audio_ahb (not used)
arm_a53_src (can we safely switch it off?)
dram_apb (can we safely switch it off?)
dram_alt (can we safely switch it off?)
disp_apb (not used)
usdhc3 (we can switch it off in suspend mode)
usdhc2 (we can switch it off in suspend mode)
usdhc1 (we can switch it off in suspend mode)
qspi (not used)
dsi_core (not used)
nand_usdhc_bus (not used)
enet_axi (we can switch it off in suspend mode)
ahb (not sure about it, since we need to use GPIO lines, and MU to wake up the main CPU)
usb_phy_ref (we can switch it off in suspend mode)
uart3 (not used)
uart1 (not used)
wrclk (not used)

Additional question:
1. Can we disable the voltage for VDD_SOC?
2. Can we disable the voltage for VDD_ARM, VDD_GPU, VDD_VPU? (it is not clear if it's possible with our PMIC)
3. Can we keep VDD_GPU and VDD_VPU disabled even in active/idle modes? (Because we don't need them)
4. What are the best optimal voltages in suspend mode? VDD_ARM, VDD_DRAM, NVCC_DRAM?
5. If I want to assign a certain clk_root to another clock source(for example to SYS_PLL2), what is the place in the source code where I can do it? Do you have any examples? Is it device tree files, or ATF, or u-boot?

Thank you!

Best regards,
Anton

Labels (2)
0 Kudos
30 Replies

2,123 Views
anton_glukhov
Contributor III

Hi @terry_lv 

Thank you very much for the documentation!

I absolutely believe that it's possible, I just cannot find any working example. I think that the one that you attached I've already seen and considered during my experiments.

Did you have a chance to run the example on your board? Maybe I have just an incorrect module, or did some mistakes in setup.

Thank you!

BR,
Anton

0 Kudos

2,095 Views
terry_lv
NXP Employee
NXP Employee

Hi Anton,

  Are you still on this issue?

  I've done some tests on iMX8MN board recently.

  Could you have a description of your M7 application from below points?

  1. Will the application enter low power mode and wakeup sometimes?
  2. Will the application need some PLLs to be ON all the time?
  3. What modules modules will your application use?

  Thanks!

Regards

Terry

0 Kudos

2,084 Views
anton_glukhov
Contributor III

Hi @terry_lv 

I still have the issue with too high power consumption and there is no news from my side.

The case that we need to support is very simple. The system goes to the suspend mode, while M7 core keeps running. M7 core needs only few peripherals: GPT, GPIO lines control, I2C3(or I2C4) bus. M7 core has to be able to wake up the main core, but not periodically. From my point of view we can assign those peripherals to a certain SYS_PLL and keep this running. For example, we can keep running SYS_PLL1, and switch off SYS_PLL2, and SYS_PLL3 (or any other combination with the best performance).

The latest news from my side, I was be able to switch off SYS_PLL1, but it did change power consumption. I don't know why, but it didn't show any errors.

Thank you for your support!

BR,
Anton

0 Kudos

2,069 Views
terry_lv
NXP Employee
NXP Employee

Hi Anton,

  So your application in M core will keep running and won't enter STOP or WAIT mode, right?

  And what core frequency do you want?

  Thanks!

Regards

Terry

0 Kudos

2,060 Views
anton_glukhov
Contributor III

Hi @terry_lv ,

Correct! It just running and doesn't need to go into SPOT or WAIT mode.

The frequency of M7 can be slow enough. For example we can use 24 OSC completely in suspend mode. But when the system in running mode then it would be great to have higher frequency(or normal frequency). But I'm not sure that switching from SYS PLL to 24OSC and back is a good idea for M7 core. Maybe we can just use one of those SYS PLLs but slow it down?

BR,
Anton

0 Kudos

2,164 Views
terry_lv
NXP Employee
NXP Employee

Hi,

  Could you give some description on your product?

  Thanks!

Regards

Terry

0 Kudos

2,127 Views
terry_lv
NXP Employee
NXP Employee

Hi,

  As the optimiziation in ATF are mainly on VDD_SOC, could you measure power consumption of VDD_SOC?

  It's weird that disabling POW_OPT_SUSP_DISABLE_SYSPLL1, POW_OPT_SUSP_DISABLE_CCGR, and POW_OPT_SUSP_DISABLE_SYSPLL2 don't have any improvement on power.

  In our low power enet demo on i.MX8MP, VDD_SOC can reach 43mW in low power state (A53 suspend/M7 run at 24MHz).

  Thanks!

Regards

Terry

0 Kudos

2,451 Views
terry_lv
NXP Employee
NXP Employee

Hi,

  On 8mp board, root clock of dram_apb is sys_pll1_800m.

  Thanks!

Regards

Terry

0 Kudos

2,556 Views
terry_lv
NXP Employee
NXP Employee

Hi Anton,

  I recommend to refer to the file attached for optimizations on SYSPLL1.

  Some root clock on SYSPLL1 should be bypassed, and some can be disabled. It needs a lot of tests.

  About your questions:

1. Can we disable the voltage for VDD_SOC?

[Ty] I'm afraid not. VDD_SOC supplys power of M core. If VDD_SOC is disabled, M core won't be able to run.
2. Can we disable the voltage for VDD_ARM, VDD_GPU, VDD_VPU? (it is not clear if it's possible with our PMIC)

[Ty] Yes. Those power rails can be disabled. But VDD_ARM need to be disabled carefully, as it might lead to hang or wakeup issue.
3. Can we keep VDD_GPU and VDD_VPU disabled even in active/idle modes? (Because we don't need them)

[Ty] Yes. I think this can be done in device tree blob.
4. What are the best optimal voltages in suspend mode? VDD_ARM, VDD_DRAM, NVCC_DRAM?

[Ty] I've attached a patch that will adjust VDD_SOC to 0.85V. This is the norminal voltage for VDD_SOC (By default, on 8MP, overdrive voltage 0.95V is used). I'm not sure about best optimal voltages of VDD_ARM, VDD_DRAM, NVCC_DRAM. Those power supply will be disabled in my case.
5. If I want to assign a certain clk_root to another clock source(for example to SYS_PLL2), what is the place in the source code where I can do it? Do you have any examples? Is it device tree files, or ATF, or u-boot?

[Ty] I think you can modify device tree blob files for this purpose.

Thanks!

Regards

Terry

0 Kudos

2,536 Views
anton_glukhov
Contributor III

Hi @terry_lv ,

Thank you for your help!

Could you please clarify if those consumers of SYS_PLL1 can be disabled in suspend mode?

arm_a53_src, dram_apb, dram_alt, ahb? (These are from the clock tree). Do I need to reassign some of those clocks to another SYS_PLL?

UPDATE:
I did a few more experiments and can say that at least those two clocks are important. If I try to disable them then the system cannot be resumed: dram_apb and nand_usdhc_bus. Can I somehow "save" and "restore" those clocks? Or maybe it's possible to assign them to another SYS_PLL?

Best regards,
Anton

0 Kudos