diff options
author | Chris Kay <chris.kay@arm.com> | 2019-10-10 23:33:07 +0530 |
---|---|---|
committer | Thomas Abraham <thomas.abraham@arm.com> | 2019-10-23 09:22:09 +0530 |
commit | 6249a11030e2779453eea011741de85830afacd4 (patch) | |
tree | aff9c334bdf9a8ccdaa8eaf4cafce8ce4862a26e | |
parent | 44a517fd738e4112dce756c5bd04f911b853c1a3 (diff) |
rde1edge: add support for rde1edge platform
RD-E1-Edge initial support for RD-E1-Edge platform. This platform
is similar to the RD-N1-Edge platform except for changes in the
number of CPUs, clock and power domains.
Change-Id: I88f1b63fcb57b4f85a11563c21926e8354755676
Signed-off-by: Chris Kay <chris.kay@arm.com>
-rw-r--r-- | product/rdn1e1/include/rdn1e1_core.h | 67 | ||||
-rw-r--r-- | product/rdn1e1/include/rdn1e1_power_domain.h | 7 | ||||
-rw-r--r-- | product/rdn1e1/scp_ramfw/config_clock.c | 3 | ||||
-rw-r--r-- | product/rdn1e1/scp_ramfw/config_power_domain.c | 209 | ||||
-rw-r--r-- | product/rdn1e1/scp_ramfw/config_ppu_v1.c | 8 | ||||
-rw-r--r-- | product/rdn1e1/scp_ramfw/config_smt.c | 6 |
6 files changed, 237 insertions, 63 deletions
diff --git a/product/rdn1e1/include/rdn1e1_core.h b/product/rdn1e1/include/rdn1e1_core.h index 38a6c501..d38de800 100644 --- a/product/rdn1e1/include/rdn1e1_core.h +++ b/product/rdn1e1/include/rdn1e1_core.h @@ -9,12 +9,20 @@ #define RDN1E1_CORE_H #include <fwk_assert.h> +#include <mod_sid.h> + +#define RDN1EDGE_CONFIG_NUM 1 +#define RDE1EDGE_CONFIG_NUM 2 #define RDN1E1_CORE_PER_CLUSTER_MAX 8 -/* RDN1E1 only has one configuration, hence the constant values */ -#define CORES_PER_CLUSTER 4 -#define NUMBER_OF_CLUSTERS 2 +#define THREADS_PER_CORE_RDN1 0 +#define THREADS_PER_CORE_RDE1 2 + +#define CORES_PER_CLUSTER_RDN1 4 +#define CORES_PER_CLUSTER_RDE1 8 + +#define NUMBER_OF_CLUSTERS 2 static inline unsigned int rdn1e1_core_get_cluster_count(void) { @@ -24,14 +32,63 @@ static inline unsigned int rdn1e1_core_get_cluster_count(void) static inline unsigned int rdn1e1_core_get_core_per_cluster_count( unsigned int cluster) { + int status; + const struct mod_sid_info *system_info; + + status = mod_sid_get_system_info(&system_info); + if (status != FWK_SUCCESS) + return status; + fwk_assert(cluster < rdn1e1_core_get_cluster_count()); - return CORES_PER_CLUSTER; + switch (system_info->config_number) { + case RDN1EDGE_CONFIG_NUM: + return CORES_PER_CLUSTER_RDN1; + case RDE1EDGE_CONFIG_NUM: + return CORES_PER_CLUSTER_RDE1; + default: + fwk_assert(false); + } + + return 1; +} + +static inline unsigned int rdn1e1_core_get_thread_per_core_count( + unsigned int cluster, unsigned int core) +{ + int status; + const struct mod_sid_info *system_info; + + status = mod_sid_get_system_info(&system_info); + if (status != FWK_SUCCESS) + return status; + + fwk_assert(cluster < rdn1e1_core_get_cluster_count()); + fwk_assert(core < rdn1e1_core_get_core_per_cluster_count(cluster)); + + switch (system_info->config_number) { + case RDN1EDGE_CONFIG_NUM: + return THREADS_PER_CORE_RDN1; + case RDE1EDGE_CONFIG_NUM: + return THREADS_PER_CORE_RDE1; + default: + fwk_assert(false); + } + + return 1; +} + +static inline unsigned int rdn1e1_core_get_thread_count(void) +{ + return NUMBER_OF_CLUSTERS * + rdn1e1_core_get_core_per_cluster_count(0) * + rdn1e1_core_get_thread_per_core_count(0, 0); } static inline unsigned int rdn1e1_core_get_core_count(void) { - return NUMBER_OF_CLUSTERS * CORES_PER_CLUSTER; + return NUMBER_OF_CLUSTERS * + rdn1e1_core_get_core_per_cluster_count(0); } #endif /* RDN1E1_CORE_H */ diff --git a/product/rdn1e1/include/rdn1e1_power_domain.h b/product/rdn1e1/include/rdn1e1_power_domain.h index f0d23327..55125d89 100644 --- a/product/rdn1e1/include/rdn1e1_power_domain.h +++ b/product/rdn1e1/include/rdn1e1_power_domain.h @@ -48,4 +48,11 @@ enum rdn1e1_power_domain_state_masks { RDN1E1_POWER_DOMAIN_STATE_FULL_RET_MASK \ ) +/*! Mask for the thread valid power states */ +#define RDN1E1_THREAD_VALID_STATE_MASK ( \ + MOD_PD_STATE_OFF_MASK | \ + MOD_PD_STATE_ON_MASK | \ + MOD_PD_STATE_SLEEP_MASK \ + ) + #endif /* RDN1E1_POWER_DOMAIN_H */ diff --git a/product/rdn1e1/scp_ramfw/config_clock.c b/product/rdn1e1/scp_ramfw/config_clock.c index e80cc4d7..50ff0a04 100644 --- a/product/rdn1e1/scp_ramfw/config_clock.c +++ b/product/rdn1e1/scp_ramfw/config_clock.c @@ -58,7 +58,8 @@ static const struct fwk_element *clock_get_dev_desc_table(fwk_id_t module_id) (struct mod_clock_dev_config *)clock_dev_desc_table[i].data; dev_config->pd_source_id = fwk_id_build_element_id( fwk_module_id_power_domain, - rdn1e1_core_get_core_count() + PD_STATIC_DEV_IDX_SYSTOP); + rdn1e1_core_get_core_count() + + rdn1e1_core_get_thread_count() + PD_STATIC_DEV_IDX_SYSTOP); } return clock_dev_desc_table; diff --git a/product/rdn1e1/scp_ramfw/config_power_domain.c b/product/rdn1e1/scp_ramfw/config_power_domain.c index d0d9f070..d73d173f 100644 --- a/product/rdn1e1/scp_ramfw/config_power_domain.c +++ b/product/rdn1e1/scp_ramfw/config_power_domain.c @@ -22,7 +22,7 @@ #include <config_power_domain.h> /* Maximum power domain name size including the null terminator */ -#define PD_NAME_SIZE 12 +#define PD_NAME_SIZE 16 /* Mask of the allowed states for the systop power domain */ static const uint32_t systop_allowed_state_mask_table[] = { @@ -73,17 +73,24 @@ static const uint32_t core_pd_allowed_state_mask_table[] = { [RDN1E1_POWER_DOMAIN_STATE_MEM_RET] = MOD_PD_STATE_OFF_MASK }; +/* Mask of the allowed states for a thread depending on the core states. */ +static const uint32_t thread_pd_allowed_state_mask_table[] = { + [MOD_PD_STATE_OFF] = MOD_PD_STATE_OFF_MASK | MOD_PD_STATE_SLEEP_MASK, + [MOD_PD_STATE_ON] = RDN1E1_THREAD_VALID_STATE_MASK, + [MOD_PD_STATE_SLEEP] = RDN1E1_THREAD_VALID_STATE_MASK, + [RDN1E1_POWER_DOMAIN_STATE_FULL_RET] = + MOD_PD_STATE_OFF_MASK | MOD_PD_STATE_SLEEP_MASK, +}; + /* Power module specific configuration data (none) */ static const struct mod_power_domain_config rdn1e1_power_domain_config = { 0 }; -static struct fwk_element rdn1e1_power_domain_static_element_table[] = { +static const struct fwk_element rdn1e1_power_domain_static_element_table[] = { [PD_STATIC_DEV_IDX_CLUSTER0] = { .name = "CLUS0", .data = &((struct mod_power_domain_element_config) { .attributes.pd_type = MOD_PD_TYPE_CLUSTER, - .tree_pos = MOD_PD_TREE_POS( - MOD_PD_LEVEL_1, 0, 0, PD_STATIC_DEV_IDX_CLUSTER0, 0), .api_id = FWK_ID_API_INIT( FWK_MODULE_IDX_PPU_V1, MOD_PPU_V1_API_IDX_POWER_DOMAIN_DRIVER), @@ -96,8 +103,6 @@ static struct fwk_element rdn1e1_power_domain_static_element_table[] = { .name = "CLUS1", .data = &((struct mod_power_domain_element_config) { .attributes.pd_type = MOD_PD_TYPE_CLUSTER, - .tree_pos = MOD_PD_TREE_POS( - MOD_PD_LEVEL_1, 0, 0, PD_STATIC_DEV_IDX_CLUSTER1, 0), .api_id = FWK_ID_API_INIT( FWK_MODULE_IDX_PPU_V1, MOD_PPU_V1_API_IDX_POWER_DOMAIN_DRIVER), @@ -110,8 +115,6 @@ static struct fwk_element rdn1e1_power_domain_static_element_table[] = { .name = "DBGTOP", .data = &((struct mod_power_domain_element_config) { .attributes.pd_type = MOD_PD_TYPE_DEVICE_DEBUG, - .tree_pos = MOD_PD_TREE_POS( - MOD_PD_LEVEL_1, 0, 0, PD_STATIC_DEV_IDX_DBGTOP, 0), .driver_id = FWK_ID_ELEMENT_INIT( FWK_MODULE_IDX_PPU_V0, PPU_V0_ELEMENT_IDX_DBGTOP), .api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_PPU_V0, 0), @@ -124,8 +127,6 @@ static struct fwk_element rdn1e1_power_domain_static_element_table[] = { .name = "SYSTOP", .data = &((struct mod_power_domain_element_config) { .attributes.pd_type = MOD_PD_TYPE_SYSTEM, - .tree_pos = MOD_PD_TREE_POS( - MOD_PD_LEVEL_2, 0, 0, 0, 0), .driver_id = FWK_ID_MODULE_INIT(FWK_MODULE_IDX_SYSTEM_POWER), .api_id = FWK_ID_API_INIT( FWK_MODULE_IDX_SYSTEM_POWER, @@ -140,78 +141,180 @@ static struct fwk_element rdn1e1_power_domain_static_element_table[] = { /* * Function definitions with internal linkage */ +static int build_thread_element_descriptor(struct fwk_element *element, + struct mod_power_domain_element_config *pd_config, + unsigned int cluster_idx, unsigned int core_idx, + unsigned int cluster_core_idx, unsigned int core_thread_idx) { + + element->name = fwk_mm_alloc(PD_NAME_SIZE, 1); + if (element->name == NULL) + return FWK_E_NOMEM; + + snprintf((char *)element->name, PD_NAME_SIZE, "CLUS%uCORE%uTHR%u", + cluster_idx, cluster_core_idx, core_thread_idx); + + element->data = pd_config; + + *pd_config = (struct mod_power_domain_element_config) { + .attributes.pd_type = MOD_PD_TYPE_THREAD, + + .tree_pos = MOD_PD_TREE_POS(MOD_PD_LEVEL_0, 0, + cluster_idx, cluster_core_idx, core_thread_idx), + + .driver_id = FWK_ID_SUB_ELEMENT( + FWK_MODULE_IDX_PPU_V1, core_idx, core_thread_idx), + .api_id = FWK_ID_API( + FWK_MODULE_IDX_PPU_V1, + MOD_PPU_V1_API_IDX_POWER_DOMAIN_DRIVER), + + .allowed_state_mask_table = thread_pd_allowed_state_mask_table, + .allowed_state_mask_table_size = + FWK_ARRAY_SIZE(thread_pd_allowed_state_mask_table) + }; + + return FWK_SUCCESS; +} + +static int build_core_element_descriptor(struct fwk_element *element, + struct mod_power_domain_element_config *pd_config, + unsigned int cluster_idx, unsigned int core_idx, + unsigned int cluster_core_idx) { + + element->name = fwk_mm_alloc(PD_NAME_SIZE, 1); + if (element->name == NULL) + return FWK_E_NOMEM; + + snprintf((char *)element->name, PD_NAME_SIZE, "CLUS%uCORE%u", + cluster_idx, cluster_core_idx); + + element->data = pd_config; + + *pd_config = (struct mod_power_domain_element_config) { + .attributes.pd_type = MOD_PD_TYPE_CORE, + + .driver_id = FWK_ID_ELEMENT(FWK_MODULE_IDX_PPU_V1, core_idx), + .api_id = FWK_ID_API( + FWK_MODULE_IDX_PPU_V1, + MOD_PPU_V1_API_IDX_POWER_DOMAIN_DRIVER), + + .allowed_state_mask_table = core_pd_allowed_state_mask_table, + .allowed_state_mask_table_size = + FWK_ARRAY_SIZE(core_pd_allowed_state_mask_table) + }; + + pd_config->tree_pos = + rdn1e1_core_get_thread_per_core_count(cluster_idx, + cluster_core_idx) > 0 ? + MOD_PD_TREE_POS(MOD_PD_LEVEL_1, 0, cluster_idx, cluster_core_idx, 0) : + MOD_PD_TREE_POS(MOD_PD_LEVEL_0, 0, 0, cluster_idx, cluster_core_idx); + + return FWK_SUCCESS; +} + static const struct fwk_element *rdn1e1_power_domain_get_element_table (fwk_id_t module_id) { - struct fwk_element *element_table, *element; + int status; + struct fwk_element *element_table; struct mod_power_domain_element_config *pd_config_table, *pd_config; - unsigned int core_idx; - unsigned int cluster_idx; - unsigned int core_count; - unsigned int cluster_count; - unsigned int core_element_count = 0; + unsigned int cluster_idx, core_idx, thread_idx, element_idx; + unsigned int cluster_core_idx, core_thread_idx; + unsigned int core_count, thread_count; core_count = rdn1e1_core_get_core_count(); - cluster_count = rdn1e1_core_get_cluster_count(); + thread_count = rdn1e1_core_get_thread_count(); element_table = fwk_mm_calloc( - core_count + thread_count + core_count + FWK_ARRAY_SIZE(rdn1e1_power_domain_static_element_table) + 1, /* Terminator */ sizeof(struct fwk_element)); if (element_table == NULL) return NULL; - pd_config_table = fwk_mm_calloc(core_count, + pd_config_table = fwk_mm_calloc(thread_count + core_count, sizeof(struct mod_power_domain_element_config)); if (pd_config_table == NULL) return NULL; - for (cluster_idx = 0; cluster_idx < cluster_count; cluster_idx++) { - for (core_idx = 0; - core_idx < rdn1e1_core_get_core_per_cluster_count(cluster_idx); - core_idx++) { + for (cluster_idx = 0, core_idx = 0, + cluster_core_idx = 0, core_thread_idx = 0, + thread_idx = 0; thread_idx < thread_count; thread_idx++) { - element = &element_table[core_element_count]; - pd_config = &pd_config_table[core_element_count]; + status = build_thread_element_descriptor( + &element_table[thread_idx], + &pd_config_table[thread_idx], + cluster_idx, core_idx, cluster_core_idx, core_thread_idx); + if (status != FWK_SUCCESS) + return NULL; - element->name = fwk_mm_alloc(PD_NAME_SIZE, 1); - if (element->name == NULL) - return NULL; + core_thread_idx++; + if (core_thread_idx >= + rdn1e1_core_get_thread_per_core_count(cluster_idx, + cluster_core_idx)) { + core_thread_idx = 0; + core_idx++; + cluster_core_idx++; + } - snprintf((char *)element->name, PD_NAME_SIZE, "CLUS%uCORE%u", - cluster_idx, core_idx); + if (cluster_core_idx >= + rdn1e1_core_get_core_per_cluster_count(cluster_idx)) { + cluster_core_idx = 0; + cluster_idx++; + } + } - element->data = pd_config; + for (cluster_idx = 0, cluster_core_idx = 0, + core_idx = 0; core_idx < core_count; core_idx++) { - pd_config->attributes.pd_type = MOD_PD_TYPE_CORE; - pd_config->tree_pos = MOD_PD_TREE_POS( - MOD_PD_LEVEL_0, 0, 0, cluster_idx, core_idx); - pd_config->driver_id = - FWK_ID_ELEMENT(FWK_MODULE_IDX_PPU_V1, - core_element_count); - pd_config->api_id = FWK_ID_API( - FWK_MODULE_IDX_PPU_V1, - MOD_PPU_V1_API_IDX_POWER_DOMAIN_DRIVER); - pd_config->allowed_state_mask_table = - core_pd_allowed_state_mask_table; - pd_config->allowed_state_mask_table_size = - FWK_ARRAY_SIZE(core_pd_allowed_state_mask_table); - core_element_count++; - } + status = build_core_element_descriptor( + &element_table[core_idx + thread_count], + &pd_config_table[core_idx + thread_count], + cluster_idx, core_idx, cluster_core_idx); + if (status != FWK_SUCCESS) + return NULL; - /* Define the driver id for the cluster */ - pd_config = (struct mod_power_domain_element_config *) - rdn1e1_power_domain_static_element_table[cluster_idx].data; - pd_config->driver_id = - FWK_ID_ELEMENT(FWK_MODULE_IDX_PPU_V1, - (core_count + cluster_idx)); + cluster_core_idx++; + if (cluster_core_idx >= + rdn1e1_core_get_core_per_cluster_count(cluster_idx)) { + cluster_core_idx = 0; + cluster_idx++; + } } - memcpy(element_table + core_count, + memcpy(element_table + thread_count + core_count, rdn1e1_power_domain_static_element_table, sizeof(rdn1e1_power_domain_static_element_table)); + for (element_idx = 0; + element_idx < + FWK_ARRAY_SIZE(rdn1e1_power_domain_static_element_table); + element_idx++) { + pd_config = (struct mod_power_domain_element_config *) + element_table[thread_count + core_count + element_idx].data; + + switch (pd_config->attributes.pd_type) { + case MOD_PD_TYPE_CLUSTER: + pd_config->driver_id = FWK_ID_ELEMENT( + FWK_MODULE_IDX_PPU_V1, (core_count + element_idx)); + pd_config->tree_pos = thread_count > 0 ? + MOD_PD_TREE_POS(MOD_PD_LEVEL_2, 0, element_idx, 0, 0) : + MOD_PD_TREE_POS(MOD_PD_LEVEL_1, 0, 0, element_idx, 0); + break; + + case MOD_PD_TYPE_SYSTEM: + pd_config->tree_pos = thread_count > 0 ? + MOD_PD_TREE_POS(MOD_PD_LEVEL_3, 0, 0, 0, 0) : + MOD_PD_TREE_POS(MOD_PD_LEVEL_2, 0, 0, 0, 0); + break; + + default: + pd_config->tree_pos = thread_count > 0 ? + MOD_PD_TREE_POS(MOD_PD_LEVEL_2, 0, element_idx, 0, 0) : + MOD_PD_TREE_POS(MOD_PD_LEVEL_1, 0, 0, element_idx, 0); + } + } + return element_table; } diff --git a/product/rdn1e1/scp_ramfw/config_ppu_v1.c b/product/rdn1e1/scp_ramfw/config_ppu_v1.c index 6a7a7120..fbbeff5e 100644 --- a/product/rdn1e1/scp_ramfw/config_ppu_v1.c +++ b/product/rdn1e1/scp_ramfw/config_ppu_v1.c @@ -104,6 +104,8 @@ static const struct fwk_element *ppu_v1_get_element_table(fwk_id_t module_id) snprintf((char *)element->name, PPU_CORE_NAME_SIZE, "CLUS%uCORE%u", cluster_idx, core_idx); + element->sub_element_count = + rdn1e1_core_get_thread_per_core_count(cluster_idx, core_idx); element->data = pd_config; pd_config->pd_type = MOD_PD_TYPE_CORE; @@ -144,11 +146,13 @@ static const struct fwk_element *ppu_v1_get_element_table(fwk_id_t module_id) /* * Configure pd_source_id with the SYSTOP identifier from the power domain - * module which is dynamically defined based on the number of cores. + * module which is dynamically defined based on the number of cores and + * threads. */ ppu_v1_config_data.pd_source_id = fwk_id_build_element_id( fwk_module_id_power_domain, - core_count + PD_STATIC_DEV_IDX_SYSTOP); + core_count + rdn1e1_core_get_thread_count() + + PD_STATIC_DEV_IDX_SYSTOP); return element_table; } diff --git a/product/rdn1e1/scp_ramfw/config_smt.c b/product/rdn1e1/scp_ramfw/config_smt.c index 6ccb43a0..539cdfb4 100644 --- a/product/rdn1e1/scp_ramfw/config_smt.c +++ b/product/rdn1e1/scp_ramfw/config_smt.c @@ -52,8 +52,10 @@ static const struct fwk_element *smt_get_element_table(fwk_id_t module_id) for (idx = 0; idx < SCP_RDN1E1_SCMI_SERVICE_IDX_COUNT; idx++) { config = (struct mod_smt_channel_config *)(smt_element_table[idx].data); - config->pd_source_id = FWK_ID_ELEMENT(FWK_MODULE_IDX_POWER_DOMAIN, - rdn1e1_core_get_core_count() + PD_STATIC_DEV_IDX_SYSTOP); + config->pd_source_id = FWK_ID_ELEMENT( + FWK_MODULE_IDX_POWER_DOMAIN, + rdn1e1_core_get_core_count() + + rdn1e1_core_get_thread_count() + PD_STATIC_DEV_IDX_SYSTOP); } return smt_element_table; |