diff options
25 files changed, 224 insertions, 18 deletions
diff --git a/drivers/arm/ccn/ccn.c b/drivers/arm/ccn/ccn.c index 910cd7cd..59a7576c 100644 --- a/drivers/arm/ccn/ccn.c +++ b/drivers/arm/ccn/ccn.c @@ -11,6 +11,7 @@ #include <debug.h> #include <errno.h> #include <mmio.h> +#include <stdbool.h> #include "ccn_private.h" static const ccn_desc_t *ccn_plat_desc; @@ -490,3 +491,123 @@ int ccn_get_part0_id(uintptr_t periphbase) return (int)(mmio_read_64(periphbase + MN_PERIPH_ID_0_1_OFFSET) & 0xFF); } + +/******************************************************************************* + * This function returns the region id corresponding to a node_id of node_type. + ******************************************************************************/ +static unsigned int get_region_id_for_node(node_types_t node_type, + unsigned int node_id) +{ + unsigned int mn_reg_off, region_id; + unsigned long long node_bitmap; + unsigned int loc_node_id, node_pos_in_map = 0; + + assert(node_type < NUM_NODE_TYPES); + assert(node_id < MAX_RN_NODES); + + switch (node_type) { + case NODE_TYPE_RNI: + region_id = RNI_REGION_ID_START; + break; + case NODE_TYPE_HNF: + region_id = HNF_REGION_ID_START; + break; + case NODE_TYPE_HNI: + region_id = HNI_REGION_ID_START; + break; + case NODE_TYPE_SN: + region_id = SBSX_REGION_ID_START; + break; + default: + ERROR("Un-supported Node Type = %d.\n", node_type); + assert(false); + return REGION_ID_LIMIT; + } + /* + * RN-I, HN-F, HN-I, SN node registers in the MN region + * occupy contiguous 16 byte apart offsets. + * + * RN-F and RN-D node are not supported as + * none of them exposes any memory map to + * configure any of their offset registers. + */ + + mn_reg_off = MN_RNF_NODEID_OFFSET + (node_type << 4); + node_bitmap = ccn_reg_read(ccn_plat_desc->periphbase, + MN_REGION_ID, mn_reg_off); + + assert((node_bitmap & (1ULL << (node_id))) != 0U); + + + FOR_EACH_PRESENT_NODE_ID(loc_node_id, node_bitmap) { + INFO("Index = %u with loc_nod=%u and input nod=%u\n", + node_pos_in_map, loc_node_id, node_id); + if (loc_node_id == node_id) + break; + node_pos_in_map++; + } + + if (node_pos_in_map == CCN_MAX_RN_MASTERS) { + ERROR("Node Id = %d, is not found.\n", node_id); + assert(false); + return REGION_ID_LIMIT; + } + + region_id += node_pos_in_map; + + return region_id; +} + +/******************************************************************************* + * This function sets the value 'val' to the register at register_offset from + * the base address pointed to by the region_id. + * where, region id is mapped to a node_id of node_type. + ******************************************************************************/ +void ccn_write_node_reg(node_types_t node_type, unsigned int node_id, + unsigned int reg_offset, unsigned long long val) +{ + unsigned int region_id = get_region_id_for_node(node_type, node_id); + + if (reg_offset > REGION_ID_OFFSET) { + ERROR("Invalid Register offset 0x%x is provided.\n", + reg_offset); + assert(false); + return; + } + + /* Setting the value of Auxilary Control Register of the Node */ + ccn_reg_write(ccn_plat_desc->periphbase, region_id, reg_offset, val); + VERBOSE("Value is successfully written at address 0x%lx.\n", + (ccn_plat_desc->periphbase + + region_id_to_base(region_id)) + + reg_offset); +} + +/******************************************************************************* + * This function read the value 'val' stored in the register at register_offset + * from the base address pointed to by the region_id. + * where, region id is mapped to a node_id of node_type. + ******************************************************************************/ +unsigned long long ccn_read_node_reg(node_types_t node_type, + unsigned int node_id, + unsigned int reg_offset) +{ + unsigned long long val; + unsigned int region_id = get_region_id_for_node(node_type, node_id); + + if (reg_offset > REGION_ID_OFFSET) { + ERROR("Invalid Register offset 0x%x is provided.\n", + reg_offset); + assert(false); + return ULL(0); + } + + /* Setting the value of Auxilary Control Register of the Node */ + val = ccn_reg_read(ccn_plat_desc->periphbase, region_id, reg_offset); + VERBOSE("Value is successfully read from address 0x%lx.\n", + (ccn_plat_desc->periphbase + + region_id_to_base(region_id)) + + reg_offset); + + return val; +} diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index 418ab112..02bf770e 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -246,6 +246,13 @@ static int mmc_fill_device_info(void) return ret; } + do { + ret = mmc_device_state(); + if (ret < 0) { + return ret; + } + } while (ret != MMC_STATE_TRAN); + nb_blocks = (mmc_ext_csd[CMD_EXTCSD_SEC_CNT] << 0) | (mmc_ext_csd[CMD_EXTCSD_SEC_CNT + 1] << 8) | (mmc_ext_csd[CMD_EXTCSD_SEC_CNT + 2] << 16) | diff --git a/include/drivers/arm/ccn.h b/include/drivers/arm/ccn.h index eba974d2..9c3abac6 100644 --- a/include/drivers/arm/ccn.h +++ b/include/drivers/arm/ccn.h @@ -76,6 +76,16 @@ typedef struct ccn_desc { uintptr_t periphbase; } ccn_desc_t; +/* Enum used to loop through all types of nodes in CCN*/ +typedef enum node_types { + NODE_TYPE_RNF = 0, + NODE_TYPE_RNI, + NODE_TYPE_RND, + NODE_TYPE_HNF, + NODE_TYPE_HNI, + NODE_TYPE_SN, + NUM_NODE_TYPES +} node_types_t; void ccn_init(const ccn_desc_t *plat_ccn_desc); void ccn_enter_snoop_dvm_domain(unsigned long long master_iface_map); @@ -92,5 +102,12 @@ void ccn_program_sys_addrmap(unsigned int sn0_id, unsigned int ccn_get_l3_run_mode(void); int ccn_get_part0_id(uintptr_t periphbase); +void ccn_write_node_reg(node_types_t node_type, unsigned int node_id, + unsigned int reg_offset, + unsigned long long val); +unsigned long long ccn_read_node_reg(node_types_t node_type, + unsigned int node_id, + unsigned int reg_offset); + #endif /* __ASSEMBLY__ */ #endif /* CCN_H */ diff --git a/include/lib/utils_def.h b/include/lib/utils_def.h index 02963ac5..2b489675 100644 --- a/include/lib/utils_def.h +++ b/include/lib/utils_def.h @@ -162,4 +162,11 @@ #define COMPILER_BARRIER() __asm__ volatile ("" ::: "memory") +/* Compiler builtin of GCC >= 9 and planned in llvm */ +#ifdef __HAVE_SPECULATION_SAFE_VALUE +# define SPECULATION_SAFE_VALUE(var) __builtin_speculation_safe_value(var) +#else +# define SPECULATION_SAFE_VALUE(var) var +#endif + #endif /* UTILS_DEF_H */ diff --git a/include/plat/arm/common/arm_def.h b/include/plat/arm/common/arm_def.h index d02a4059..cbac247f 100644 --- a/include/plat/arm/common/arm_def.h +++ b/include/plat/arm/common/arm_def.h @@ -34,6 +34,7 @@ #define ARM_PWR_LVL0 MPIDR_AFFLVL0 #define ARM_PWR_LVL1 MPIDR_AFFLVL1 #define ARM_PWR_LVL2 MPIDR_AFFLVL2 +#define ARM_PWR_LVL3 MPIDR_AFFLVL3 /* * Macros for local power states in ARM platforms encoded by State-ID field diff --git a/include/plat/arm/css/common/css_pm.h b/include/plat/arm/css/common/css_pm.h index eeb72de5..ff75c691 100644 --- a/include/plat/arm/css/common/css_pm.h +++ b/include/plat/arm/css/common/css_pm.h @@ -11,9 +11,6 @@ #include <psci.h> #include <stdint.h> -/* System power domain at level 2, as currently implemented by CSS platforms */ -#define CSS_SYSTEM_PWR_DMN_LVL ARM_PWR_LVL2 - /* Macros to read the CSS power domain state */ #define CSS_CORE_PWR_STATE(state) (state)->pwr_domain_state[ARM_PWR_LVL0] #define CSS_CLUSTER_PWR_STATE(state) (state)->pwr_domain_state[ARM_PWR_LVL1] diff --git a/lib/psci/psci_stat.c b/lib/psci/psci_stat.c index 421db443..6f6a7d4f 100644 --- a/lib/psci/psci_stat.c +++ b/lib/psci/psci_stat.c @@ -206,9 +206,9 @@ static int psci_get_stat(u_register_t target_cpu, unsigned int power_state, if (pwrlvl > PSCI_CPU_PWR_LVL) { /* Get the power domain index */ - parent_idx = psci_cpu_pd_nodes[target_idx].parent_node; + parent_idx = SPECULATION_SAFE_VALUE(psci_cpu_pd_nodes[target_idx].parent_node); for (lvl = PSCI_CPU_PWR_LVL + 1U; lvl < pwrlvl; lvl++) - parent_idx = psci_non_cpu_pd_nodes[parent_idx].parent_node; + parent_idx = SPECULATION_SAFE_VALUE(psci_non_cpu_pd_nodes[parent_idx].parent_node); /* Get the non cpu power domain stats */ *psci_stat = psci_non_cpu_stat[parent_idx][stat_idx]; diff --git a/plat/arm/board/fvp/fvp_pm.c b/plat/arm/board/fvp/fvp_pm.c index 7b85043b..78d30255 100644 --- a/plat/arm/board/fvp/fvp_pm.c +++ b/plat/arm/board/fvp/fvp_pm.c @@ -416,3 +416,8 @@ plat_psci_ops_t plat_arm_psci_pm_ops = { .read_mem_protect = arm_psci_read_mem_protect, .write_mem_protect = arm_nor_psci_write_mem_protect, }; + +const plat_psci_ops_t *plat_arm_psci_override_pm_ops(plat_psci_ops_t *ops) +{ + return ops; +} diff --git a/plat/arm/board/juno/include/platform_def.h b/plat/arm/board/juno/include/platform_def.h index 0bbe3e19..8098bc3f 100644 --- a/plat/arm/board/juno/include/platform_def.h +++ b/plat/arm/board/juno/include/platform_def.h @@ -295,4 +295,7 @@ #define PLAT_ARM_PRIVATE_SDEI_EVENTS ARM_SDEI_PRIVATE_EVENTS #define PLAT_ARM_SHARED_SDEI_EVENTS ARM_SDEI_SHARED_EVENTS +/* System power domain level */ +#define CSS_SYSTEM_PWR_DMN_LVL ARM_PWR_LVL2 + #endif /* PLATFORM_DEF_H */ diff --git a/plat/arm/board/juno/juno_pm.c b/plat/arm/board/juno/juno_pm.c new file mode 100644 index 00000000..da2e92ba --- /dev/null +++ b/plat/arm/board/juno/juno_pm.c @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <plat_arm.h> +#include <scmi.h> + +const plat_psci_ops_t *plat_arm_psci_override_pm_ops(plat_psci_ops_t *ops) +{ + return css_scmi_override_pm_ops(ops); +} diff --git a/plat/arm/board/juno/platform.mk b/plat/arm/board/juno/platform.mk index ba1acd42..ad955f67 100644 --- a/plat/arm/board/juno/platform.mk +++ b/plat/arm/board/juno/platform.mk @@ -27,6 +27,7 @@ endif CSS_USE_SCMI_SDS_DRIVER := 1 PLAT_INCLUDES := -Iplat/arm/board/juno/include \ + -Iplat/arm/css/drivers/scmi \ -Iplat/arm/css/drivers/sds PLAT_BL_COMMON_SOURCES := plat/arm/board/juno/${ARCH}/juno_helpers.S \ @@ -79,6 +80,7 @@ BL31_SOURCES += drivers/cfi/v2m/v2m_flash.c \ lib/cpus/aarch64/cortex_a57.S \ lib/cpus/aarch64/cortex_a72.S \ lib/utils/mem_region.c \ + plat/arm/board/juno/juno_pm.c \ plat/arm/board/juno/juno_topology.c \ plat/arm/common/arm_nor_psci_mem_protect.c \ ${JUNO_GIC_SOURCES} \ diff --git a/plat/arm/board/juno/sp_min/sp_min-juno.mk b/plat/arm/board/juno/sp_min/sp_min-juno.mk index 52781093..b3471c1f 100644 --- a/plat/arm/board/juno/sp_min/sp_min-juno.mk +++ b/plat/arm/board/juno/sp_min/sp_min-juno.mk @@ -10,6 +10,7 @@ BL32_SOURCES += drivers/cfi/v2m/v2m_flash.c \ lib/cpus/aarch32/cortex_a57.S \ lib/cpus/aarch32/cortex_a72.S \ lib/utils/mem_region.c \ + plat/arm/board/juno/juno_pm.c \ plat/arm/board/juno/juno_topology.c \ plat/arm/common/arm_nor_psci_mem_protect.c \ plat/arm/soc/common/soc_css_security.c \ diff --git a/plat/arm/board/n1sdp/include/platform_def.h b/plat/arm/board/n1sdp/include/platform_def.h index 3e483978..fa639ca9 100644 --- a/plat/arm/board/n1sdp/include/platform_def.h +++ b/plat/arm/board/n1sdp/include/platform_def.h @@ -32,6 +32,8 @@ N1SDP_MAX_CPUS_PER_CLUSTER * \ N1SDP_MAX_PE_PER_CPU) +/* System power domain level */ +#define CSS_SYSTEM_PWR_DMN_LVL ARM_PWR_LVL2 /* * PLAT_ARM_MMAP_ENTRIES depends on the number of entries in the diff --git a/plat/arm/board/n1sdp/n1sdp_bl31_setup.c b/plat/arm/board/n1sdp/n1sdp_bl31_setup.c index 65aad9cf..cdd0b63d 100644 --- a/plat/arm/board/n1sdp/n1sdp_bl31_setup.c +++ b/plat/arm/board/n1sdp/n1sdp_bl31_setup.c @@ -6,6 +6,7 @@ #include "../../css/drivers/scmi/scmi.h" #include "../../css/drivers/mhu/css_mhu_doorbell.h" +#include <plat_arm.h> #include <platform_def.h> static scmi_channel_plat_info_t n1sdp_scmi_plat_info = { @@ -20,3 +21,8 @@ scmi_channel_plat_info_t *plat_css_get_scmi_info() { return &n1sdp_scmi_plat_info; } + +const plat_psci_ops_t *plat_arm_psci_override_pm_ops(plat_psci_ops_t *ops) +{ + return css_scmi_override_pm_ops(ops); +} diff --git a/plat/arm/board/sgi575/include/platform_def.h b/plat/arm/board/sgi575/include/platform_def.h index c06a0a1f..16e2898d 100644 --- a/plat/arm/board/sgi575/include/platform_def.h +++ b/plat/arm/board/sgi575/include/platform_def.h @@ -20,4 +20,9 @@ #define SGI575_DMC620_BASE0 UL(0x4e000000) #define SGI575_DMC620_BASE1 UL(0x4e100000) +/* System power domain level */ +#define CSS_SYSTEM_PWR_DMN_LVL ARM_PWR_LVL2 + +#define PLAT_MAX_PWR_LVL ARM_PWR_LVL1 + #endif /* PLATFORM_DEF_H */ diff --git a/plat/arm/board/sgiclarka/include/platform_def.h b/plat/arm/board/sgiclarka/include/platform_def.h index ba6d0434..39907e8b 100644 --- a/plat/arm/board/sgiclarka/include/platform_def.h +++ b/plat/arm/board/sgiclarka/include/platform_def.h @@ -20,4 +20,9 @@ #define SGICLARKA_DMC620_BASE0 UL(0x4e000000) #define SGICLARKA_DMC620_BASE1 UL(0x4e100000) +/* System power domain level */ +#define CSS_SYSTEM_PWR_DMN_LVL ARM_PWR_LVL2 + +#define PLAT_MAX_PWR_LVL ARM_PWR_LVL1 + #endif /* PLATFORM_DEF_H */ diff --git a/plat/arm/common/arm_pm.c b/plat/arm/common/arm_pm.c index 6394bfb5..3be1b5d3 100644 --- a/plat/arm/common/arm_pm.c +++ b/plat/arm/common/arm_pm.c @@ -14,7 +14,6 @@ #include <psci.h> /* Allow ARM Standard platforms to override these functions */ -#pragma weak plat_arm_psci_override_pm_ops #pragma weak plat_arm_program_trusted_mailbox #if !ARM_RECOM_STATE_ID_ENC @@ -133,14 +132,6 @@ int arm_validate_psci_entrypoint(uintptr_t entrypoint) } /****************************************************************************** - * Default definition on ARM standard platforms to override the plat_psci_ops. - *****************************************************************************/ -const plat_psci_ops_t *plat_arm_psci_override_pm_ops(plat_psci_ops_t *ops) -{ - return ops; -} - -/****************************************************************************** * Helper function to save the platform state before a system suspend. Save the * state of the system components which are not in the Always ON power domain. *****************************************************************************/ diff --git a/plat/arm/css/drivers/scmi/scmi.h b/plat/arm/css/drivers/scmi/scmi.h index e1358bfa..28dfc9ac 100644 --- a/plat/arm/css/drivers/scmi/scmi.h +++ b/plat/arm/css/drivers/scmi/scmi.h @@ -8,6 +8,7 @@ #define SCMI_H #include <bakery_lock.h> +#include <psci.h> #include <stddef.h> #include <stdint.h> #include <spinlock.h> @@ -162,4 +163,7 @@ int scmi_ap_core_get_reset_addr(void *p, uint64_t *reset_addr, uint32_t *attr); /* API to get the platform specific SCMI channel information. */ scmi_channel_plat_info_t *plat_css_get_scmi_info(); +/* API to override default PSCI callbacks for platforms that support SCMI. */ +const plat_psci_ops_t *css_scmi_override_pm_ops(plat_psci_ops_t *ops); + #endif /* SCMI_H */ diff --git a/plat/arm/css/drivers/scp/css_pm_scmi.c b/plat/arm/css/drivers/scp/css_pm_scmi.c index 956f583c..1397fd80 100644 --- a/plat/arm/css/drivers/scp/css_pm_scmi.c +++ b/plat/arm/css/drivers/scp/css_pm_scmi.c @@ -339,7 +339,7 @@ void __init plat_arm_pwrc_setup(void) * the SCMI driver, query capability via SCMI and modify the PSCI capability * based on that. *****************************************************************************/ -const plat_psci_ops_t *plat_arm_psci_override_pm_ops(plat_psci_ops_t *ops) +const plat_psci_ops_t *css_scmi_override_pm_ops(plat_psci_ops_t *ops) { uint32_t msg_attr; int ret; diff --git a/plat/arm/css/sgi/include/sgi_base_platform_def.h b/plat/arm/css/sgi/include/sgi_base_platform_def.h index 1395373c..8705d63b 100644 --- a/plat/arm/css/sgi/include/sgi_base_platform_def.h +++ b/plat/arm/css/sgi/include/sgi_base_platform_def.h @@ -119,8 +119,6 @@ #define PLAT_ARM_NSRAM_BASE 0x06000000 #define PLAT_ARM_NSRAM_SIZE 0x00080000 /* 512KB */ -#define PLAT_MAX_PWR_LVL U(1) - #define PLAT_ARM_G1S_IRQ_PROPS(grp) CSS_G1S_IRQ_PROPS(grp) #define PLAT_ARM_G0_IRQ_PROPS(grp) ARM_G0_IRQ_PROPS(grp) diff --git a/plat/arm/css/sgi/sgi_bl31_setup.c b/plat/arm/css/sgi/sgi_bl31_setup.c index ce850269..d44f89c7 100644 --- a/plat/arm/css/sgi/sgi_bl31_setup.c +++ b/plat/arm/css/sgi/sgi_bl31_setup.c @@ -101,3 +101,8 @@ void bl31_platform_setup(void) sgi_ras_intr_handler_setup(); #endif } + +const plat_psci_ops_t *plat_arm_psci_override_pm_ops(plat_psci_ops_t *ops) +{ + return css_scmi_override_pm_ops(ops); +} diff --git a/plat/arm/css/sgi/sgi_topology.c b/plat/arm/css/sgi/sgi_topology.c index 3b7a57ad..e524f11f 100644 --- a/plat/arm/css/sgi/sgi_topology.c +++ b/plat/arm/css/sgi/sgi_topology.c @@ -44,3 +44,11 @@ const uint32_t plat_css_core_pos_to_scmi_dmn_id_map[32] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, \ 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 }; + +/****************************************************************************** + * Return the number of PE's supported by the CPU. + *****************************************************************************/ +unsigned int plat_arm_get_cpu_pe_count(u_register_t mpidr) +{ + return CSS_SGI_MAX_PE_PER_CPU; +} diff --git a/plat/arm/css/sgm/include/sgm_base_platform_def.h b/plat/arm/css/sgm/include/sgm_base_platform_def.h index a9795a48..2178f069 100644 --- a/plat/arm/css/sgm/include/sgm_base_platform_def.h +++ b/plat/arm/css/sgm/include/sgm_base_platform_def.h @@ -239,4 +239,8 @@ */ #define PLAT_ARM_MEM_PROT_ADDR (V2M_FLASH0_BASE + \ V2M_FLASH0_SIZE - V2M_FLASH_BLOCK_SIZE) + +/* System power domain level */ +#define CSS_SYSTEM_PWR_DMN_LVL ARM_PWR_LVL2 + #endif /* SGM_BASE_PLATFORM_DEF_H */ diff --git a/plat/arm/css/sgm/sgm_bl31_setup.c b/plat/arm/css/sgm/sgm_bl31_setup.c index 29c32e7c..952572e3 100644 --- a/plat/arm/css/sgm/sgm_bl31_setup.c +++ b/plat/arm/css/sgm/sgm_bl31_setup.c @@ -47,3 +47,8 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, arm_bl31_early_platform_setup((void *)arg0, arg1, arg2, (void *)arg3); } + +const plat_psci_ops_t *plat_arm_psci_override_pm_ops(plat_psci_ops_t *ops) +{ + return css_scmi_override_pm_ops(ops); +} diff --git a/plat/hisilicon/hikey/hikey_bl2_setup.c b/plat/hisilicon/hikey/hikey_bl2_setup.c index d42afe0d..125d6654 100644 --- a/plat/hisilicon/hikey/hikey_bl2_setup.c +++ b/plat/hisilicon/hikey/hikey_bl2_setup.c @@ -336,7 +336,6 @@ void bl2_platform_setup(void) params.flags = MMC_FLAG_CMD23; info.mmc_dev_type = MMC_IS_EMMC; dw_mmc_init(¶ms, &info); - mdelay(20); hikey_io_setup(); } |