2398221_en-US

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

2398221_en-US

2398221_en-US

NXP iMX8MP: WFI-based CPU idle in U-Boot never wakes

Dear NXP Support Team,

We are investigating a low-power waiting mechanism in U-Boot for a i.MX8M Plus based product and have reached a point where we would appreciate guidance from NXP.

Software versions

  • SoC: NXP i.MX8M Plus
  • BSP:
    • ATF: lf_v2.10_android-15.0.0_1.2.0
    • U-Boot: lf_v2024.04_android-15.0.0_1.2.0
    • Based on the public NXP BSP (Variscite fork contains no relevant modifications in the ATF/GIC code paths)

Goal

The application needs to remain in U-Boot for several minutes while a deeply discharged battery charges before Android is started.

A busy-loop based on mdelay() consumes unnecessary power and generates additional heat, so we are trying to periodically enter a low-power idle state and wake using the ARM Generic Timer (CNTP, PPI 30).

Initial implementation

  • configure CNTP timer
  • enable PPI 30
  • execute a raw wfi() from EL2

The processor never wakes from wfi(). UART output simply stops with no exception or crash.

PSCI implementation

  • PSCI_VERSION returns 1.1
  • PSCI_FEATURES(CPU_SUSPEND) returns 0 (supported)
  • invoke CPU_SUSPEND requesting the Standby power state

This reaches the ATF standby implementation imx_cpu_standby(), but the system hangs in exactly the same way: no exception, no UART output, and execution never resumes.

Therefore, both:

  • raw wfi() executed at EL2
  • wfi() executed through ATF via PSCI

produce identical behavior.

What have been already verified

CPU and timer

  • U-Boot executes at EL2.
  • CNTP timer is correctly programmed.
  • CNTP_TVAL_EL0 counts down correctly.
  • CNTP_CTL_EL0 shows:
    • ENABLE = 1
    • IMASK = 0
    • ISTATUS = 0 immediately after arming.

CPU interface

  • ICC_PMR_EL1 is configured correctly.
  • ICC_IGRPEN1_EL1 is enabled.

Virtualization

HCR_EL2 has:

  • IMO = 0
  • FMO = 0

so interrupt routing through EL2 virtualization is not involved.

Interrupt security classification

From the ATF sources we verified that:

  • all PPIs are initially configured as Group 1 Non-secure by the generic GICv3 helper code,
  • only SGI8 (and optionally SDEI SGIs) are reconfigured as Secure,
  • PPI 30 is **not** present in the secure interrupt property table.

Therefore the Generic Timer interrupt appears to remain Group 1 Non-secure as expected.

SCR_EL3.TWE

We originally suspected that non-secure wfi() might be trapped to EL3 via SCR_EL3.TWE, but this now seems unlikely because the same behavior occurs when wfi() is executed inside ATF itself through PSCI.

Additional investigation

While tracing the ATF GIC initialization we noticed that gicv3_distif_init() clears the Distributor EnableGrp bits and only re-enables those requested by the secure interrupt property table.

Since the helper only produces Group0 and Group1 Secure properties, it appears that EnableGrp1NS is never explicitly re-enabled.

To verify this we:

  • read GICD_CTLR
  • observed EnableGrp1NS = 0
  • attempted to set EnableGrp1NS ourselves from EL2.

Unexpectedly:

  • the write completes without fault,
  • RWP behaves normally,
  • but EnableGrp1NS remains 0 after readback.

We also verified:

  • GICD_CTLR.DS == 0
  • RDC protection for the GIC memory regions is disabled (ENA = 0)
  • RDC violation registers remain zero.

Therefore RDC does not appear to be preventing the write.

Remaining question

At this point we have eliminated:

  • timer programming,
  • CPU interface configuration,
  • interrupt priority masking,
  • interrupt group classification,
  • SCR_EL3.TWE trapping,
  • PSCI vs raw WFI execution,
  • RDC protection.

The remaining unexplained behavior is that an architecturally Non-secure writable Distributor control bit (EnableGrp1NS) does not appear to accept writes on this platform, and consequently neither raw wfi() nor PSCI CPU_SUSPEND ever wake using the Generic Timer interrupt.

  1. Is this behavior expected on the i.MX8M Plus Android 15 BSP?
  2. Is there any platform-specific initialization missing outside the public ATF sources that is required before the Generic Timer PPI can wake a CPU from wfi()?
  3. Is EnableGrp1NS intentionally prevented from being modified by non-secure software on this platform?
  4. Has anyone successfully implemented periodic wake-up from U-Boot using either:
    • raw wfi(), or
    • PSCI CPU_SUSPEND 
      driven by the ARM Generic Timer?

Any insight into the expected initialization sequence or platform-specific behavior would be greatly appreciated.

Thanks

Best Regards

Pier

Tags (1)
No ratings
Version history
Last update:
18 hours ago
Updated by: