static void up_pm_notify()

in arch/arm/src/s32k1xx/s32k1xx_clockconfig.c [1742:2304]


static void up_pm_notify(struct pm_callback_s *cb, int domain,
                         enum pm_state_e pmstate)
{
  int return_value;

  /* check if the transition is from the IDLE domain to the NORMAL domain */

  if (pm_querystate(PM_IDLE_DOMAIN) == PM_IDLE &&
    pmstate == PM_NORMAL)
    {
      /* return */

      return;
    }

  /* check what the new power state is */

  switch (pmstate)
    {
      /* if it needs to be set to RUN mode */

      case(PM_NORMAL):
        {
          /* Logic for PM_NORMAL goes here */

          /* change the microcontroller to RUN mode  */

          /* and wait until in RUN mode */

          return_value = (int)s32k1xx_set_runmode(SCG_SYSTEM_CLOCK_MODE_RUN);

          /* check for debug assertion */

          DEBUGASSERT(return_value != (int)SCG_SYSTEM_CLOCK_MODE_NONE);

          /* enable all clock sources again if needed  */

          /* these could be the FIRC, PPL, and SOSC */

          /* check if the FIRC was enabled and
           * it is not the system clock source
           */

          if (g_initial_clkconfig.scg.firc.initialize &&
            (s32k1xx_get_scgclk_source() != SCG_SYSTEM_CLOCK_SRC_SIRC))
          {
            /* enable FIRC */

            return_value = s32k1xx_firc_config(true,
              &g_initial_clkconfig.scg.firc);
            DEBUGASSERT(!return_value);
          }

          /* check if the FIRC needs to be disabled and if it is enabled */

          else if ((!(g_initial_clkconfig.scg.firc.initialize)) &&
            (s32k1xx_get_srcfreq(SCG_SYSTEM_CLOCK_SRC_FIRC)))
          {
            /* disable FIRC */

            return_value = s32k1xx_firc_config(false,
              &g_initial_clkconfig.scg.firc);
            DEBUGASSERT(!return_value);
          }

          /* check if the SOSC was enabled and
           * it is not the system clock source
           */

          if (g_initial_clkconfig.scg.sosc.initialize &&
            (s32k1xx_get_scgclk_source() != SCG_SYSTEM_CLOCK_SRC_SYS_OSC) &&
            (s32k1xx_get_scgclk_source() != SCG_SYSTEM_CLOCK_SRC_SYS_PLL))
          {
            /* enable SOSC */

            return_value =
              s32k1xx_sosc_config(true, &g_initial_clkconfig.scg.sosc);
            DEBUGASSERT(!return_value);
          }

          /* check if the SOSC needs to be disabled and if it is enabled */

          else if ((!(g_initial_clkconfig.scg.sosc.initialize)) &&
            (s32k1xx_get_srcfreq(SCG_SYSTEM_CLOCK_SRC_SYS_OSC)))
          {
            /* disable SOSC */

            return_value =
              s32k1xx_sosc_config(false, &g_initial_clkconfig.scg.sosc);
            DEBUGASSERT(!return_value);
          }

          /* check if the SPLL was enabled and
           * it is not the system clock source
           */

          if (g_initial_clkconfig.scg.spll.initialize &&
            (s32k1xx_get_scgclk_source() != SCG_SYSTEM_CLOCK_SRC_SYS_OSC) &&
            (s32k1xx_get_scgclk_source() != SCG_SYSTEM_CLOCK_SRC_SYS_PLL))
          {
            /* enable SPLL */

            return_value = s32k1xx_spll_config(true,
              &g_initial_clkconfig.scg.spll);
            DEBUGASSERT(!return_value);
          }

          /* check if the SPLL needs to be disabled and if it is enabled */

          else if ((!(g_initial_clkconfig.scg.spll.initialize)) &&
            (s32k1xx_get_srcfreq(SCG_SYSTEM_CLOCK_SRC_SYS_PLL)))
          {
            /* disable SPLL */

            return_value = s32k1xx_spll_config(false,
              &g_initial_clkconfig.scg.spll);
            DEBUGASSERT(!return_value);
          }

          /* check if the RCCR clock source is enabled */

          if (s32k1xx_get_srcfreq(g_initial_clkconfig.scg.clockmode.rccr.src)
            != 0)
          {
            /* change the system clock back to the configured clock */

            /* and wait until clock changed */

            if (s32k1xx_transition_systemclock(
              &g_initial_clkconfig.scg.clockmode.rccr))
            {
              /* error */

              DEBUGPANIC();
            }
          }

          /* if it is 0 */

          else
          {
            /* error */

            DEBUGPANIC();
          }

          /* calculate the new clock ticks */

          up_timer_initialize();
        }
        break;

      case(PM_IDLE):
        {
          /* Logic for PM_IDLE goes here */
        }
        break;

      /* if it needs to be set to VLPR mode */

      case(PM_STANDBY):
        {
          /* Logic for PM_STANDBY goes here */

#ifdef CONFIG_RUN_STANDBY

          /* change the microcontroller to RUN mode */

          /* and wait until in RUN mode */

          return_value =
            (int)s32k1xx_set_runmode(SCG_SYSTEM_CLOCK_MODE_RUN);
          DEBUGASSERT(return_value != (int)SCG_SYSTEM_CLOCK_MODE_NONE);

          /* enable all clock sources again if needed  */

          /* these could be the FIRC, PPL, and SOSC */

          /* check if the FIRC was enabled and
           * it is not the system clock source
           */

          if (g_initial_clkconfig.scg.firc.initialize &&
            (s32k1xx_get_scgclk_source() != SCG_SYSTEM_CLOCK_SRC_SIRC))
          {
            /* enable FIRC */

            return_value = s32k1xx_firc_config(true,
              &g_initial_clkconfig.scg.firc);
            DEBUGASSERT(!return_value);
          }

          /* check if the FIRC needs to be disabled and if it is enabled */

          else if ((!(g_initial_clkconfig.scg.firc.initialize)) &&
            (s32k1xx_get_srcfreq(SCG_SYSTEM_CLOCK_SRC_FIRC)))
          {
            /* disable FIRC */

            return_value = s32k1xx_firc_config(false,
              &g_initial_clkconfig.scg.firc);
            DEBUGASSERT(!return_value);
          }

          /* check if the SOSC was enabled and
           * it is not the system clock source
           */

          if (g_initial_clkconfig.scg.sosc.initialize &&
            (s32k1xx_get_scgclk_source() != SCG_SYSTEM_CLOCK_SRC_SYS_OSC) &&
            (s32k1xx_get_scgclk_source() != SCG_SYSTEM_CLOCK_SRC_SYS_PLL))
          {
            /* enable SOSC */

            return_value =
              s32k1xx_sosc_config(true, &g_initial_clkconfig.scg.sosc);
            DEBUGASSERT(!return_value);
          }

          /* check if the SOSC needs to be disabled and if it is enabled */

          else if ((!(g_initial_clkconfig.scg.sosc.initialize)) &&
            (s32k1xx_get_srcfreq(SCG_SYSTEM_CLOCK_SRC_SYS_OSC)))
          {
            /* disable SOSC */

            return_value =
              s32k1xx_sosc_config(false, &g_initial_clkconfig.scg.sosc);
            DEBUGASSERT(!return_value);
          }

          /* check if the SPLL was enabled and
           * it is not the system clock source
           */

          if (g_initial_clkconfig.scg.spll.initialize &&
            (s32k1xx_get_scgclk_source() != SCG_SYSTEM_CLOCK_SRC_SYS_OSC) &&
            (s32k1xx_get_scgclk_source() != SCG_SYSTEM_CLOCK_SRC_SYS_PLL))
          {
            /* enable SPLL */

            return_value = s32k1xx_spll_config(true,
              &g_initial_clkconfig.scg.spll);
            DEBUGASSERT(!return_value);
          }

          /* check if the SPLL needs to be disabled and if it is enabled */

          else if ((!(g_initial_clkconfig.scg.spll.initialize)) &&
            (s32k1xx_get_srcfreq(SCG_SYSTEM_CLOCK_SRC_SYS_PLL)))
          {
            /* disable SPLL */

            return_value = s32k1xx_spll_config(false,
              &g_initial_clkconfig.scg.spll);
            DEBUGASSERT(!return_value);
          }

          /* check if the RCCR clock source is enabled */

          if (s32k1xx_get_srcfreq(g_initial_clkconfig.scg.clockmode.rccr.src)
            != 0)
          {
            /* change the system clock back to the configured clock */

            /* and wait until clock changed */

            if (s32k1xx_transition_systemclock(
              &g_initial_clkconfig.scg.clockmode.rccr))
            {
              /* error */

              DEBUGPANIC();
            }
          }

          /* if it is 0 */

          else
          {
            /* error */

            DEBUGPANIC();
          }

#endif /* CONFIG_RUN_STANDBY */

#ifdef CONFIG_VLPR_STANDBY

          /* set the system clock to the SIRC 8MHz freq */

          /* this freq will change to the predefined vccr settings
           * when the mode change occures
           */

          /* and wait until system clock changed */

          return_value = s32k1xx_sirc_clocksource();
          DEBUGASSERT(!return_value);

          /* disable the other clock sources if not already disabled */

          /* these are the FIRC, PPL, and SOSC */

          /* check if the SPLL is enabled */

          if (s32k1xx_get_spllfreq() != 0)
          {
            /* disable SPLL */

            return_value = s32k1xx_spll_config(false,
              &g_initial_clkconfig.scg.spll);
            DEBUGASSERT(!return_value);
          }

          /* check if the SOSC is enabled */

          if (s32k1xx_get_soscfreq() != 0)
          {
            /* disable SOSC */

            return_value =
              s32k1xx_sosc_config(false, &g_initial_clkconfig.scg.sosc);
            DEBUGASSERT(!return_value);
          }

          /* check if the FIRC is enabled */

          if (s32k1xx_get_fircfreq() != 0)
          {
            /* disable FIRC */

            return_value = s32k1xx_firc_config(false,
              &g_initial_clkconfig.scg.firc);
            DEBUGASSERT(!return_value);
          }

  #ifdef CONFIG_ARCH_CHIP_S32K11X
            /* TODO make sure CMU is gated? (only for S32k11x) */

            #error Make sure CMU is gated
  #endif

          /* change the microcontroller to VLPR mode */

          /* and wait until it is in that runmode */

          return_value =
            (int)s32k1xx_set_runmode(SCG_SYSTEM_CLOCK_MODE_VLPR);
          DEBUGASSERT(return_value != (int)SCG_SYSTEM_CLOCK_MODE_NONE);

#endif /* CONFIG_VLPR_STANDBY */

          /* calculate the new clock ticks */

          up_timer_initialize();
        }
        break;

      case(PM_SLEEP):
        {
          /* Logic for PM_SLEEP goes here */

#ifdef CONFIG_RUN_SLEEP

          /* change the microcontroller to RUN mode */

          /* and wait until in RUN mode */

          return_value = (int)s32k1xx_set_runmode(SCG_SYSTEM_CLOCK_MODE_RUN);
          DEBUGASSERT(return_value != (int)SCG_SYSTEM_CLOCK_MODE_NONE);

          /* enable all clock sources again if needed */

          /* these could be the FIRC, PPL, and SOSC */

          /* check if the FIRC was enabled
           * and it is not the system clock source
           */

          if (g_initial_clkconfig.scg.firc.initialize &&
            (s32k1xx_get_scgclk_source() != SCG_SYSTEM_CLOCK_SRC_SIRC))
          {
            /* enable FIRC */

            return_value = s32k1xx_firc_config(true,
              &g_initial_clkconfig.scg.firc);
            DEBUGASSERT(!return_value);
          }

          /* check if the FIRC needs to be disabled and if it is enabled */

          else if ((!(g_initial_clkconfig.scg.firc.initialize)) &&
            (s32k1xx_get_srcfreq(SCG_SYSTEM_CLOCK_SRC_FIRC)))
          {
            /* disable FIRC */

            return_value = s32k1xx_firc_config(false,
              &g_initial_clkconfig.scg.firc);
            DEBUGASSERT(!return_value);
          }

          /* check if the SOSC was enabled
           * and it is not the system clock source
           */

          if (g_initial_clkconfig.scg.sosc.initialize &&
            (s32k1xx_get_scgclk_source() != SCG_SYSTEM_CLOCK_SRC_SYS_OSC) &&
            (s32k1xx_get_scgclk_source() != SCG_SYSTEM_CLOCK_SRC_SYS_PLL))
          {
            /* enable SOSC */

            return_value =
              s32k1xx_sosc_config(true, &g_initial_clkconfig.scg.sosc);
            DEBUGASSERT(!return_value);
          }

          /* check if the SOSC needs to be disabled and if it is enabled */

          else if ((!(g_initial_clkconfig.scg.sosc.initialize)) &&
            (s32k1xx_get_srcfreq(SCG_SYSTEM_CLOCK_SRC_SYS_OSC)))
          {
            /* disable SOSC */

            return_value =
              s32k1xx_sosc_config(false, &g_initial_clkconfig.scg.sosc);
            DEBUGASSERT(!return_value);
          }

          /* check if the SPLL was enabled
           * and it is not the system clock source
           */

          if (g_initial_clkconfig.scg.spll.initialize &&
            (s32k1xx_get_scgclk_source() != SCG_SYSTEM_CLOCK_SRC_SYS_OSC) &&
            (s32k1xx_get_scgclk_source() != SCG_SYSTEM_CLOCK_SRC_SYS_PLL))
          {
            /* enable SPLL */

            return_value = s32k1xx_spll_config(true,
              &g_initial_clkconfig.scg.spll);
            DEBUGASSERT(!return_value);
          }

          /* check if the SPLL needs to be disabled and if it is enabled */

          else if ((!(g_initial_clkconfig.scg.spll.initialize)) &&
            (s32k1xx_get_srcfreq(SCG_SYSTEM_CLOCK_SRC_SYS_PLL)))
          {
            /* disable SPLL */

            return_value = s32k1xx_spll_config(false,
              &g_initial_clkconfig.scg.spll);
            DEBUGASSERT(!return_value);
          }

          /* check if the RCCR clock source is enabled */

          if (s32k1xx_get_srcfreq(g_initial_clkconfig.scg.clockmode.rccr.src)
            != 0)
          {
            /* change the system clock back to the configured clock */

            /* and wait until clock changed */

            if (s32k1xx_transition_systemclock(
              &g_initial_clkconfig.scg.clockmode.rccr))
            {
              /* error */

              DEBUGPANIC();
            }
          }

          /* if it is 0 */

          else
          {
            /* error */

            DEBUGPANIC();
          }

#endif /* CONFIG_RUN_SLEEP */

#ifdef CONFIG_VLPR_SLEEP

          /* set the system clock to the SIRC 8MHz freq */

          /* this freq will change to the predefined vccr settings
           * when the mode change occures
           */

          /* and wait until system clock changed */

          return_value = s32k1xx_sirc_clocksource();
          DEBUGASSERT(!return_value);

          /* disable the other clock sources if not already disabled */

          /* these are the FIRC, PPL, and SOSC */

          /* check if the SPLL is enabled */

          if (s32k1xx_get_spllfreq() != 0)
          {
            /* disable SPLL */

            return_value =
            s32k1xx_spll_config(false, &g_initial_clkconfig.scg.spll);
            DEBUGASSERT(!return_value);
          }

          /* check if the SOSC is enabled */

          if (s32k1xx_get_soscfreq() != 0)
          {
            /* disable SOSC */

            return_value =
              s32k1xx_sosc_config(false, &g_initial_clkconfig.scg.sosc);
            DEBUGASSERT(!return_value);
          }

          /* check if the FIRC is enabled */

          if (s32k1xx_get_fircfreq() != 0)
          {
            /* disable FIRC */

            return_value =
            s32k1xx_firc_config(false, &g_initial_clkconfig.scg.firc);
            DEBUGASSERT(!return_value);
          }

  #ifdef CONFIG_ARCH_CHIP_S32K11X
            /* TODO make sure CMU is gated? (only for S32k11x) */

            #error Make sure CMU is gated
  #endif
          /* change the microcontroller to VLPR mode */

          /* and wait until it is in that runmode */

          return_value =
          (int)s32k1xx_set_runmode(SCG_SYSTEM_CLOCK_MODE_VLPR);
          DEBUGASSERT(return_value != (int)SCG_SYSTEM_CLOCK_MODE_NONE);

#endif /* CONFIG_VLPR_SLEEP */

          /* calculate the new clock ticks */

          up_timer_initialize();
        }
        break;

      default:

        /* Should not get here */

        break;
    }
}