]> git.baikalelectronics.ru Git - arm-tf.git/commitdiff
feat(tegra): implement 'pwr_domain_off_early' handler
authorVarun Wadekar <vwadekar@nvidia.com>
Tue, 25 Apr 2023 13:58:33 +0000 (14:58 +0100)
committerVarun Wadekar <vwadekar@nvidia.com>
Wed, 26 Apr 2023 18:52:50 +0000 (20:52 +0200)
This patch implements the pwr_domain_off_early handler for
Tegra platforms.

Powering off the boot core on some Tegra platforms is not
allowed and the SOC specific helper functions for Tegra194,
Tegra210 and Tegra186 implement this restriction.

Signed-off-by: Varun Wadekar <vwadekar@nvidia.com>
Change-Id: I9d06e0eee12314764adb0422e023a5bec6ed9c1e

plat/nvidia/tegra/common/aarch64/tegra_helpers.S
plat/nvidia/tegra/common/tegra_pm.c
plat/nvidia/tegra/include/platform_def.h
plat/nvidia/tegra/include/tegra_private.h
plat/nvidia/tegra/soc/t186/plat_psci_handlers.c
plat/nvidia/tegra/soc/t194/plat_psci_handlers.c
plat/nvidia/tegra/soc/t210/plat_psci_handlers.c

index 6c8c4f018defc1667a436830ee35cf7027dd85e3..72ecd54e9b462691bdd1273af9467f77c30e25cc 100644 (file)
 .endm
 
        /* -----------------------------------------------------
-        * unsigned int plat_is_my_cpu_primary(void);
+        * bool plat_is_my_cpu_primary(void);
         *
         * This function checks if this is the Primary CPU
+        *
+        * Registers clobbered: x0, x1
         * -----------------------------------------------------
         */
 func plat_is_my_cpu_primary
        mrs     x0, mpidr_el1
-       and     x0, x0, #(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK)
-       cmp     x0, #TEGRA_PRIMARY_CPU
+       adr     x1, tegra_primary_cpu_mpid
+       ldr     x1, [x1]
+       cmp     x0, x1
        cset    x0, eq
        ret
 endfunc plat_is_my_cpu_primary
@@ -251,6 +254,14 @@ _end:      mov     x0, x20
        adr     x18, bl31_entrypoint
        str     x18, [x17]
 
+       /* -----------------------------------
+        * save the boot CPU MPID value
+        * -----------------------------------
+        */
+       mrs     x0, mpidr_el1
+       adr     x1, tegra_primary_cpu_mpid
+       str     x0, [x1]
+
 1:     cpu_init_common
 
        ret
@@ -426,3 +437,10 @@ tegra_bl31_phys_base:
         */
 tegra_console_base:
        .quad   0
+
+       /* --------------------------------------------------
+        * MPID value for the boot CPU
+        * --------------------------------------------------
+        */
+tegra_primary_cpu_mpid:
+       .quad   0
index ec34a850d9e9e3bd603d9539924d86f0ae9dd98d..8edb0247e349323002a7dbe381ab058f19090962 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
- * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
+ * Copyright (c) 2020-2023, NVIDIA Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -89,6 +89,16 @@ static int32_t tegra_pwr_domain_on(u_register_t mpidr)
        return tegra_soc_pwr_domain_on(mpidr);
 }
 
+/*******************************************************************************
+ * Handler called when a power domain is about to be turned off. The
+ * target_state encodes the power state that each level should transition to.
+ * Return error if CPU off sequence is not allowed for the current core.
+ ******************************************************************************/
+static int tegra_pwr_domain_off_early(const psci_power_state_t *target_state)
+{
+       return tegra_soc_pwr_domain_off_early(target_state);
+}
+
 /*******************************************************************************
  * Handler called when a power domain is about to be turned off. The
  * target_state encodes the power state that each level should transition to.
@@ -268,6 +278,7 @@ static int32_t tegra_validate_ns_entrypoint(uintptr_t entrypoint)
 static plat_psci_ops_t tegra_plat_psci_ops = {
        .cpu_standby                    = tegra_cpu_standby,
        .pwr_domain_on                  = tegra_pwr_domain_on,
+       .pwr_domain_off_early           = tegra_pwr_domain_off_early,
        .pwr_domain_off                 = tegra_pwr_domain_off,
        .pwr_domain_suspend_pwrdown_early = tegra_pwr_domain_suspend_pwrdown_early,
        .pwr_domain_suspend             = tegra_pwr_domain_suspend,
index 84b3297e058e69f5ffb0a26864fbdf2a8b054ff9..958a3f9721e3469e0dd5fd952bb9378cdecb63b6 100644 (file)
@@ -41,8 +41,6 @@
 #define PLATFORM_STACK_SIZE            U(0x400)
 #endif
 
-#define TEGRA_PRIMARY_CPU              U(0x0)
-
 #define PLAT_MAX_PWR_LVL               MPIDR_AFFLVL2
 #define PLATFORM_CORE_COUNT            (PLATFORM_CLUSTER_COUNT * \
                                         PLATFORM_MAX_CPUS_PER_CLUSTER)
index cc2ad869c7f3c4b3472ce698b5b18e7c2a2eff93..71bea0845497e7c58fab57d4d1d1e08e3403e1d4 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
- * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
+ * Copyright (c) 2020-2023, NVIDIA Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -98,6 +98,9 @@ void tegra_fiq_handler_setup(void);
 int32_t tegra_fiq_get_intr_context(void);
 void tegra_fiq_set_ns_entrypoint(uint64_t entrypoint);
 
+/* Declarations for tegra_helpers.S */
+bool plat_is_my_cpu_primary(void);
+
 /* Declarations for tegra_security.c */
 void tegra_security_setup(void);
 void tegra_security_setup_videomem(uintptr_t base, uint64_t size);
@@ -109,6 +112,7 @@ int32_t tegra_system_suspended(void);
 int32_t tegra_soc_cpu_standby(plat_local_state_t cpu_state);
 int32_t tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state);
 int32_t tegra_soc_pwr_domain_on(u_register_t mpidr);
+int32_t tegra_soc_pwr_domain_off_early(const psci_power_state_t *target_state);
 int32_t tegra_soc_pwr_domain_off(const psci_power_state_t *target_state);
 int32_t tegra_soc_pwr_domain_on_finish(const psci_power_state_t *target_state);
 int32_t tegra_soc_pwr_domain_power_down_wfi(const psci_power_state_t *target_state);
index af4182e2474a0e236516569e95871c67a55fe941..8f88e2887b2cd3eaa714e621ecc6c8ae1c8b0bbb 100644 (file)
@@ -433,6 +433,16 @@ int32_t tegra_soc_pwr_domain_on_finish(const psci_power_state_t *target_state)
        return PSCI_E_SUCCESS;
 }
 
+int32_t tegra_soc_pwr_domain_off_early(const psci_power_state_t *target_state)
+{
+       /* Do not power off the boot CPU */
+       if (plat_is_my_cpu_primary()) {
+               return PSCI_E_DENIED;
+       }
+
+       return PSCI_E_SUCCESS;
+}
+
 int32_t tegra_soc_pwr_domain_off(const psci_power_state_t *target_state)
 {
        uint64_t impl = (read_midr() >> MIDR_IMPL_SHIFT) & (uint64_t)MIDR_IMPL_MASK;
index 41a85ee7c37cd42dff96a748c47e8c5038586652..83d815afc742b162260a80d0ee2a726dd16754f3 100644 (file)
@@ -463,6 +463,16 @@ int32_t tegra_soc_pwr_domain_on_finish(const psci_power_state_t *target_state)
        return PSCI_E_SUCCESS;
 }
 
+int32_t tegra_soc_pwr_domain_off_early(const psci_power_state_t *target_state)
+{
+       /* Do not power off the boot CPU */
+       if (plat_is_my_cpu_primary()) {
+               return PSCI_E_DENIED;
+       }
+
+       return PSCI_E_SUCCESS;
+}
+
 int32_t tegra_soc_pwr_domain_off(const psci_power_state_t *target_state)
 {
        uint64_t impl = (read_midr() >> MIDR_IMPL_SHIFT) & MIDR_IMPL_MASK;
index 7f73ea50683dd34d520bd41b3069cbdfa36ac64f..2ec044c407d4b66b64018de069ffb3015aa8c5f4 100644 (file)
@@ -575,6 +575,16 @@ int tegra_soc_pwr_domain_on(u_register_t mpidr)
        return PSCI_E_SUCCESS;
 }
 
+int32_t tegra_soc_pwr_domain_off_early(const psci_power_state_t *target_state)
+{
+       /* Do not power off the boot CPU */
+       if (plat_is_my_cpu_primary()) {
+               return PSCI_E_DENIED;
+       }
+
+       return PSCI_E_SUCCESS;
+}
+
 int tegra_soc_pwr_domain_off(const psci_power_state_t *target_state)
 {
        tegra_fc_cpu_off(read_mpidr() & MPIDR_CPU_MASK);