Migrate ARM platforms to use the new GICv3 API
[project/bcm63xx/atf.git] / plat / arm / css / common / css_pm.c
index 93d51fe66239091d8ee98afe911e0b6679aae016..01c674f82e1483e65c004757c7d4342b2bf4e249 100644 (file)
@@ -1,19 +1,21 @@
 /*
- * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#include <arch_helpers.h>
 #include <assert.h>
-#include <cassert.h>
-#include <css_pm.h>
-#include <debug.h>
 #include <errno.h>
-#include <plat_arm.h>
-#include <platform.h>
+
 #include <platform_def.h>
-#include "../drivers/scp/css_scp.h"
+
+#include <arch_helpers.h>
+#include <common/debug.h>
+#include <drivers/arm/css/css_scp.h>
+#include <lib/cassert.h>
+#include <plat/arm/common/plat_arm.h>
+#include <plat/arm/css/common/css_pm.h>
+#include <plat/common/platform.h>
 
 /* Allow CSS platforms to override `plat_arm_psci_pm_ops` */
 #pragma weak plat_arm_psci_pm_ops
@@ -93,10 +95,18 @@ static void css_pwr_domain_on_finisher_common(
 void css_pwr_domain_on_finish(const psci_power_state_t *target_state)
 {
        /* Assert that the system power domain need not be initialized */
-       assert(CSS_SYSTEM_PWR_STATE(target_state) == ARM_LOCAL_STATE_RUN);
+       assert(css_system_pwr_state(target_state) == ARM_LOCAL_STATE_RUN);
 
        css_pwr_domain_on_finisher_common(target_state);
+}
 
+/*******************************************************************************
+ * Handler called when a power domain has just been powered on and the cpu
+ * and its cluster are fully participating in coherent transaction on the
+ * interconnect. Data cache must be enabled for CPU at this point.
+ ******************************************************************************/
+void css_pwr_domain_on_finish_late(const psci_power_state_t *target_state)
+{
        /* Program the gic per-cpu distributor or re-distributor interface */
        plat_arm_gic_pcpu_init();
 
@@ -144,8 +154,18 @@ void css_pwr_domain_suspend(const psci_power_state_t *target_state)
        if (CSS_CORE_PWR_STATE(target_state) == ARM_LOCAL_STATE_RET)
                return;
 
+
        assert(CSS_CORE_PWR_STATE(target_state) == ARM_LOCAL_STATE_OFF);
        css_power_down_common(target_state);
+
+       /* Perform system domain state saving if issuing system suspend */
+       if (css_system_pwr_state(target_state) == ARM_LOCAL_STATE_OFF) {
+               arm_system_pwr_domain_save();
+
+               /* Power off the Redistributor after having saved its context */
+               plat_arm_gic_redistif_off();
+       }
+
        css_scp_suspend(target_state);
 }
 
@@ -164,13 +184,18 @@ void css_pwr_domain_suspend_finish(
                return;
 
        /* Perform system domain restore if woken up from system suspend */
-       if (CSS_SYSTEM_PWR_STATE(target_state) == ARM_LOCAL_STATE_OFF)
+       if (css_system_pwr_state(target_state) == ARM_LOCAL_STATE_OFF)
+               /*
+                * At this point, the Distributor must be powered on to be ready
+                * to have its state restored. The Redistributor will be powered
+                * on as part of gicv3_rdistif_init_restore.
+                */
                arm_system_pwr_domain_resume();
-       else
-               /* Enable the gic cpu interface */
-               plat_arm_gic_cpuif_enable();
 
        css_pwr_domain_on_finisher_common(target_state);
+
+       /* Enable the gic cpu interface */
+       plat_arm_gic_cpuif_enable();
 }
 
 /*******************************************************************************
@@ -251,12 +276,24 @@ static int css_validate_power_state(unsigned int power_state,
        int rc;
        rc = arm_validate_power_state(power_state, req_state);
 
+       /*
+        * Ensure that we don't overrun the pwr_domain_state array in the case
+        * where the platform supported max power level is less than the system
+        * power level
+        */
+
+#if (PLAT_MAX_PWR_LVL == CSS_SYSTEM_PWR_DMN_LVL)
+
        /*
         * Ensure that the system power domain level is never suspended
         * via PSCI CPU SUSPEND API. Currently system suspend is only
         * supported via PSCI SYSTEM SUSPEND API.
         */
-       req_state->pwr_domain_state[CSS_SYSTEM_PWR_DMN_LVL] = ARM_LOCAL_STATE_RUN;
+
+       req_state->pwr_domain_state[CSS_SYSTEM_PWR_DMN_LVL] =
+                                                       ARM_LOCAL_STATE_RUN;
+#endif
+
        return rc;
 }
 
@@ -280,6 +317,7 @@ static int css_translate_power_state_by_mpidr(u_register_t mpidr,
 plat_psci_ops_t plat_arm_psci_pm_ops = {
        .pwr_domain_on          = css_pwr_domain_on,
        .pwr_domain_on_finish   = css_pwr_domain_on_finish,
+       .pwr_domain_on_finish_late = css_pwr_domain_on_finish_late,
        .pwr_domain_off         = css_pwr_domain_off,
        .cpu_standby            = css_cpu_standby,
        .pwr_domain_suspend     = css_pwr_domain_suspend,
@@ -287,17 +325,17 @@ plat_psci_ops_t plat_arm_psci_pm_ops = {
        .system_off             = css_system_off,
        .system_reset           = css_system_reset,
        .validate_power_state   = css_validate_power_state,
-       .validate_ns_entrypoint = arm_validate_ns_entrypoint,
+       .validate_ns_entrypoint = arm_validate_psci_entrypoint,
        .translate_power_state_by_mpidr = css_translate_power_state_by_mpidr,
        .get_node_hw_state      = css_node_hw_state,
        .get_sys_suspend_power_state = css_get_sys_suspend_power_state,
-/*
- * mem_protect is not supported in RESET_TO_BL31 and RESET_TO_SP_MIN,
- * as that would require mapping in all of NS DRAM into BL31 or BL32.
- */
-#if defined(PLAT_ARM_MEM_PROT_ADDR) && !RESET_TO_BL31 && !RESET_TO_SP_MIN
+
+#if defined(PLAT_ARM_MEM_PROT_ADDR)
        .mem_protect_chk        = arm_psci_mem_protect_chk,
        .read_mem_protect       = arm_psci_read_mem_protect,
        .write_mem_protect      = arm_nor_psci_write_mem_protect,
 #endif
+#if CSS_USE_SCMI_SDS_DRIVER
+       .system_reset2          = css_system_reset2,
+#endif
 };