/* Trusted mailbox base address common to all CSS */
#define PLAT_ARM_TRUSTED_MAILBOX_BASE ARM_TRUSTED_SRAM_BASE
+/*
+ * Parsing of CPU and Cluster states, as returned by 'Get CSS Power State' SCP
+ * command
+ */
+#define CSS_CLUSTER_PWR_STATE_ON 0
+#define CSS_CLUSTER_PWR_STATE_OFF 3
+
+#define CSS_CPU_PWR_STATE_ON 1
+#define CSS_CPU_PWR_STATE_OFF 0
+#define CSS_CPU_PWR_STATE(state, n) (((state) >> (n)) & 1)
#endif /* __CSS_DEF_H__ */
/*
- * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
.validate_power_state = juno_validate_power_state,
.validate_ns_entrypoint = arm_validate_ns_entrypoint,
.get_sys_suspend_power_state = css_get_sys_suspend_power_state,
- .translate_power_state_by_mpidr = juno_translate_power_state_by_mpidr
+ .translate_power_state_by_mpidr = juno_translate_power_state_by_mpidr,
+ .get_node_hw_state = css_node_hw_state
};
req_state->pwr_domain_state[i] = ARM_LOCAL_STATE_OFF;
}
+/*******************************************************************************
+ * Handler to query CPU/cluster power states from SCP
+ ******************************************************************************/
+int css_node_hw_state(u_register_t mpidr, unsigned int power_level)
+{
+ int rc, element;
+ unsigned int cpu_state, cluster_state;
+
+ /*
+ * The format of 'power_level' is implementation-defined, but 0 must
+ * mean a CPU. We also allow 1 to denote the cluster
+ */
+ if (power_level != ARM_PWR_LVL0 && power_level != ARM_PWR_LVL1)
+ return PSCI_E_INVALID_PARAMS;
+
+ /* Query SCP */
+ rc = scpi_get_css_power_state(mpidr, &cpu_state, &cluster_state);
+ if (rc != 0)
+ return PSCI_E_INVALID_PARAMS;
+
+ /* Map power states of CPU and cluster to expected PSCI return codes */
+ if (power_level == ARM_PWR_LVL0) {
+ /*
+ * The CPU state returned by SCP is an 8-bit bit mask
+ * corresponding to each CPU in the cluster
+ */
+ element = mpidr & MPIDR_AFFLVL_MASK;
+ return CSS_CPU_PWR_STATE(cpu_state, element) ==
+ CSS_CPU_PWR_STATE_ON ? HW_ON : HW_OFF;
+ } else {
+ assert(cluster_state == CSS_CLUSTER_PWR_STATE_ON ||
+ cluster_state == CSS_CLUSTER_PWR_STATE_OFF);
+ return cluster_state == CSS_CLUSTER_PWR_STATE_ON ? HW_ON :
+ HW_OFF;
+ }
+}
+
/*******************************************************************************
* Export the platform handlers via plat_arm_psci_pm_ops. The ARM Standard
* platform will take care of registering the handlers with PSCI.
.system_off = css_system_off,
.system_reset = css_system_reset,
.validate_power_state = arm_validate_power_state,
- .validate_ns_entrypoint = arm_validate_ns_entrypoint
+ .validate_ns_entrypoint = arm_validate_ns_entrypoint,
+ .get_node_hw_state = css_node_hw_state
};