ZU+ Example - Deep Sleep with PS SysMon(SysOsc) in Sleep Mode

This page describes how to put PS SysMon in sleep mode during deep sleep. With default pmu-fw during deep sleep mode, PS SysMon is in normal operation mode. One can put PS SysMon in sleep mode during deep sleep to get lower power consumption by LPD, which may affect system performance.

(This is for 2017.1 or earlier release only. Starting from 2017.3 release, the PS SysMon is always in sleep mode during Deep Sleep.)

Change in PMU-FW to put PS SysMon in sleep mode during system deep sleep

  1. Create PMU-FW project in SDK.
  2. Add following two functions in src/pm_power.c
    /**
     * PmPowerPowerDownSysOsc() - Wrapper to put SysOsc in sleep mode.
     */
    static void PmPowerDownSysOsc(void)
    {
            u32 val = 0;
            /* Sysosc in sleep */
            val = Xil_In32(0xFFA50908);
            val |= 0x30;
            Xil_Out32(0xFFA50908, val);
    }
    /**
     * PmPowerPowerUpSysOsc() - Wrapper to put SysOsc in normal operation mode.
     */
    static void PmPowerUpSysOsc(void)
    {
            u32 val = 0;
            /* Wake up SysOsc */
            val = Xil_In32(0xFFA50908);
            val &= 0xFF0F;
            Xil_Out32(0xFFA50908, val);
    }
  3. Call PmPowerDownSysOsc() and PmPowerUpSysOsc() from PmPowerDown() and PmPowerUp() in src/pm_power.c respectively as shown below:
    @@ -455,7 +485,12 @@ static int PmPowerDown(PmPower* const power)
            }
            PmDbg("%s\r\n", PmStrNode(power->node.nodeId));
    +
    +       /* Put SysOsc in sleep mode if RPU and FPD are powered down. */
    +       if ((pmPowerIslandRpu_g.power.node.currState == PM_PWR_STATE_OFF) &&
    +                       (pmPowerDomainFpd_g.power.node.currState == PM_PWR_STATE_OFF)) {
    +               PmPowerDownSysOsc();
    +       }
    +
     done:
            return status;
     }
    @@ -470,6 +506,11 @@ static int PmPowerUp(PmPower* const power)
     {
            int status = XST_SUCCESS;
    +
    +       /* Enable SysOsc for Normal operation if it is in sleep mode. */
    +       if ((Xil_In32(0xFFA50908) & 0xF0) == 0x30) {
    +               PmPowerUpSysOsc();
    +       }
    +
            PmDbg("%s\r\n", PmStrNode(power->node.nodeId));
            if (PM_PWR_STATE_ON == power->node.currState) {
  4. After above changes are done, build pmu-fw.
  5. When this pmu-fw is used to put system into deep sleep, PS SysMon goes in sleep mode.
  6. Refer Deep Sleep example and Deep Sleep with Periodic Wake-up for more information on deep sleep steps.



Configuration Object

Configuration Object file Generated by PetaLinux tool chain and Vivado is attached below.



Subsystems -
1) Linux Subsystem
Master -
  1. APU
Slaves -
  1. DDR
  2. L2 Cache
  3. OCM Bank 0, 1, 2 and 3
  4. I2C0
  5. I2C1
  6. SD1
  7. QSPI
  8. PL

2) R5-0 Subsystem
Master -
  1. RPU0
Slaves -
  1. TCM Bank 0 - A
  2. TCM Bank 0 - B

3) R5-1 Subsystem
Master -
  1. RPU1
Slaves -
  1. TCM Bank 1 - A
  2. TCM Bank 1 - B


Performance Impact

  • Keeping SYSOSC in low power mode reduces the frequency and brings in more variation in the output frequency.
  • Since PMU is clocked by SYSOSC, it will run on a lower clock. So PITs(Timers) or timing calculations may not be accurate (if any).

Related Links