aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Kay <chris.kay@arm.com>2019-10-10 23:33:07 +0530
committerThomas Abraham <thomas.abraham@arm.com>2019-10-23 09:22:09 +0530
commit6249a11030e2779453eea011741de85830afacd4 (patch)
treeaff9c334bdf9a8ccdaa8eaf4cafce8ce4862a26e
parent44a517fd738e4112dce756c5bd04f911b853c1a3 (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.h67
-rw-r--r--product/rdn1e1/include/rdn1e1_power_domain.h7
-rw-r--r--product/rdn1e1/scp_ramfw/config_clock.c3
-rw-r--r--product/rdn1e1/scp_ramfw/config_power_domain.c209
-rw-r--r--product/rdn1e1/scp_ramfw/config_ppu_v1.c8
-rw-r--r--product/rdn1e1/scp_ramfw/config_smt.c6
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;