aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Kay <chris.kay@arm.com>2020-01-27 09:52:02 +0000
committerjimqui01 <54316584+jimqui01@users.noreply.github.com>2020-03-03 15:11:04 +0000
commit3cd1ca62dd56cd25977b743cb8dd12ea86b10ccb (patch)
tree2599814d2a9cec5d9d920794c4c39347a77f4261
parent7a7080fbc30a03b623a38ce9b74d3a2b40ba10fe (diff)
dvfs: Add support for SCMI power cost reporting
Linux's scheduler relies on the power cost information so we need to return accurate power cost for each cluster/core. Change-Id: I68762fa5a2aab4ade5f7f7d8d160eded37b3c040 Signed-off-by: Raphael Gault <raphael.gault@arm.com> Signed-off-by: Girish Pathak <girish.pathak@arm.com>
-rw-r--r--product/rdn1e1/scp_ramfw/config_dvfs.c49
-rw-r--r--product/rdn1e1/scp_ramfw/config_mock_psu.c4
-rw-r--r--product/sgm775/scp_ramfw/config_dvfs.c123
-rw-r--r--product/sgm775/scp_ramfw/config_mock_psu.c8
-rw-r--r--product/sgm776/scp_ramfw/config_dvfs.c111
-rw-r--r--product/sgm776/scp_ramfw/config_mock_psu.c8
6 files changed, 258 insertions, 45 deletions
diff --git a/product/rdn1e1/scp_ramfw/config_dvfs.c b/product/rdn1e1/scp_ramfw/config_dvfs.c
index 1c17dfa5..bba77d23 100644
--- a/product/rdn1e1/scp_ramfw/config_dvfs.c
+++ b/product/rdn1e1/scp_ramfw/config_dvfs.c
@@ -5,33 +5,35 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
+#include <fwk_assert.h>
#include <fwk_element.h>
#include <fwk_macros.h>
#include <fwk_module.h>
#include <fwk_module_idx.h>
#include <mod_dvfs.h>
+#include <mod_sid.h>
#include <config_clock.h>
static struct mod_dvfs_opp opps[] = {
{
.frequency = 1313 * FWK_MHZ,
- .voltage = 100,
+ .voltage = 800,
},
{
.frequency = 1531 * FWK_MHZ,
- .voltage = 200,
+ .voltage = 850,
},
{
.frequency = 1750 * FWK_MHZ,
- .voltage = 300,
+ .voltage = 900,
},
{
.frequency = 2100 * FWK_MHZ,
- .voltage = 400,
+ .voltage = 950,
},
{
.frequency = 2600 * FWK_MHZ,
- .voltage = 500,
+ .voltage = 1000,
},
{ 0 }
};
@@ -70,6 +72,43 @@ static const struct fwk_element element_table[] = {
static const struct fwk_element *dvfs_get_element_table(fwk_id_t module_id)
{
+ int status;
+ const struct mod_sid_info *system_info;
+ double cluster_core_coefficient;
+ unsigned int cluster_core_count;
+ struct mod_dvfs_opp *opp;
+
+ status = mod_sid_get_system_info(&system_info);
+ fwk_assert(status == FWK_SUCCESS);
+
+ switch (system_info->config_number) {
+ case 1:
+ cluster_core_count = 4;
+ cluster_core_coefficient = 0.338;
+ break;
+ case 2:
+ cluster_core_count = 8;
+ cluster_core_coefficient = 0.107;
+ break;
+ default:
+ fwk_unreachable();
+ }
+
+ /*
+ * The power cost figures below are built using the dynamic power
+ * consumption formula (P = CfV^2), where C represents the capacitance of
+ * one processing element in the domain (a core or shader core). This power
+ * figure is scaled linearly with the number of processing elements in the
+ * performance domain to give a rough representation of the overall power
+ * draw. The capacitance constants are given in mW/MHz/V^2.
+ */
+ for (opp = opps; opp->frequency != 0; opp++) {
+ opp->power = cluster_core_coefficient *
+ cluster_core_count *
+ (opp->frequency / FWK_MHZ) *
+ (opp->voltage * opp->voltage) / 1000000;
+ }
+
return element_table;
}
diff --git a/product/rdn1e1/scp_ramfw/config_mock_psu.c b/product/rdn1e1/scp_ramfw/config_mock_psu.c
index c9fd0495..d921ee3c 100644
--- a/product/rdn1e1/scp_ramfw/config_mock_psu.c
+++ b/product/rdn1e1/scp_ramfw/config_mock_psu.c
@@ -21,7 +21,7 @@ static const struct fwk_element element_table[] = {
.async_response_api_id = FWK_ID_NONE_INIT,
.default_enabled = true,
- .default_voltage = 100,
+ .default_voltage = 800,
},
},
{
@@ -35,7 +35,7 @@ static const struct fwk_element element_table[] = {
.async_response_api_id = FWK_ID_NONE_INIT,
.default_enabled = true,
- .default_voltage = 100,
+ .default_voltage = 800,
},
},
{ 0 }
diff --git a/product/sgm775/scp_ramfw/config_dvfs.c b/product/sgm775/scp_ramfw/config_dvfs.c
index e22ed07f..50f22bd9 100644
--- a/product/sgm775/scp_ramfw/config_dvfs.c
+++ b/product/sgm775/scp_ramfw/config_dvfs.c
@@ -5,6 +5,7 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
+#include <fwk_assert.h>
#include <fwk_element.h>
#include <fwk_macros.h>
#include <fwk_module.h>
@@ -12,6 +13,7 @@
#include <config_dvfs.h>
#include <config_timer.h>
#include <mod_dvfs.h>
+#include <mod_sid.h>
static const struct mod_dvfs_domain_config cpu_group_little = {
.psu_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_PSU, 0),
@@ -24,23 +26,23 @@ static const struct mod_dvfs_domain_config cpu_group_little = {
.opps = (struct mod_dvfs_opp[]) {
{
.frequency = 665 * FWK_MHZ,
- .voltage = 100,
+ .voltage = 800,
},
{
.frequency = 998 * FWK_MHZ,
- .voltage = 200,
+ .voltage = 850,
},
{
.frequency = 1330 * FWK_MHZ,
- .voltage = 300,
+ .voltage = 900,
},
{
.frequency = 1463 * FWK_MHZ,
- .voltage = 400,
+ .voltage = 950,
},
{
.frequency = 1596 * FWK_MHZ,
- .voltage = 500,
+ .voltage = 1000,
},
{ 0 }
}
@@ -57,23 +59,23 @@ static const struct mod_dvfs_domain_config cpu_group_big = {
.opps = (struct mod_dvfs_opp[]) {
{
.frequency = 1313 * FWK_MHZ,
- .voltage = 100,
+ .voltage = 800,
},
{
.frequency = 1531 * FWK_MHZ,
- .voltage = 200,
+ .voltage = 850,
},
{
.frequency = 1750 * FWK_MHZ,
- .voltage = 300,
+ .voltage = 900,
},
{
.frequency = 2100 * FWK_MHZ,
- .voltage = 400,
+ .voltage = 950,
},
{
.frequency = 2450 * FWK_MHZ,
- .voltage = 500,
+ .voltage = 1000,
},
{ 0 }
}
@@ -90,23 +92,23 @@ static const struct mod_dvfs_domain_config gpu = {
.opps = (struct mod_dvfs_opp[]) {
{
.frequency = 450 * FWK_MHZ,
- .voltage = 100,
+ .voltage = 800,
},
{
.frequency = 487500 * FWK_KHZ,
- .voltage = 200,
+ .voltage = 850,
},
{
.frequency = 525 * FWK_MHZ,
- .voltage = 300,
+ .voltage = 900,
},
{
.frequency = 562500 * FWK_KHZ,
- .voltage = 400,
+ .voltage = 950,
},
{
.frequency = 600 * FWK_MHZ,
- .voltage = 500,
+ .voltage = 1000,
},
{ 0 }
}
@@ -130,6 +132,97 @@ static const struct fwk_element element_table[] = {
static const struct fwk_element *dvfs_get_element_table(fwk_id_t module_id)
{
+ int status;
+ const struct mod_sid_info *system_info;
+ double big_cpu_core_coefficient;
+ unsigned int big_cpu_core_count;
+ double little_cpu_core_coefficient;
+ unsigned int little_cpu_core_count;
+ double gpu_core_coefficient;
+ unsigned int gpu_core_count;
+ struct mod_dvfs_opp *opp;
+
+ status = mod_sid_get_system_info(&system_info);
+ fwk_assert(status == FWK_SUCCESS);
+
+ big_cpu_core_coefficient = 0.453;
+ little_cpu_core_coefficient = 0.110;
+ gpu_core_coefficient = 0.640;
+
+ switch (system_info->config_number) {
+ case 0:
+ big_cpu_core_count = 4;
+ little_cpu_core_count = 4;
+ gpu_core_count = 16;
+ break;
+ case 2:
+ big_cpu_core_count = 4;
+ little_cpu_core_count = 4;
+ gpu_core_count = 12;
+ break;
+ case 4:
+ big_cpu_core_count = 2;
+ little_cpu_core_count = 6;
+ gpu_core_count = 16;
+ break;
+ case 6:
+ big_cpu_core_count = 2;
+ little_cpu_core_count = 6;
+ gpu_core_count = 12;
+ break;
+ case 8:
+ big_cpu_core_count = 4;
+ little_cpu_core_count = 4;
+ gpu_core_count = 16;
+ break;
+ case 10:
+ big_cpu_core_count = 4;
+ little_cpu_core_count = 4;
+ gpu_core_count = 12;
+ break;
+ case 12:
+ big_cpu_core_count = 2;
+ little_cpu_core_count = 4;
+ gpu_core_count = 16;
+ break;
+ case 14:
+ big_cpu_core_count = 2;
+ little_cpu_core_count = 4;
+ gpu_core_count = 12;
+ break;
+ default:
+ fwk_unreachable();
+ }
+
+ /*
+ * The power cost figures below are built using the dynamic power
+ * consumption formula (P = CfV^2), where C represents the capacitance of
+ * one processing element in the domain (a core or shader core). This power
+ * figure is scaled linearly with the number of processing elements in the
+ * performance domain to give a rough representation of the overall power
+ * draw. The capacitance constants are given in mW/MHz/V^2.
+ */
+ for (opp = cpu_group_little.opps; opp->frequency != 0; opp++) {
+ opp->power = little_cpu_core_coefficient *
+ little_cpu_core_count *
+ (opp->frequency / FWK_MHZ) *
+ (opp->voltage * opp->voltage) / 1000000;
+ }
+
+ for (opp = cpu_group_big.opps; opp->frequency != 0; opp++) {
+ opp->power = big_cpu_core_coefficient *
+ big_cpu_core_count *
+ (opp->frequency / FWK_MHZ) *
+ (opp->voltage * opp->voltage) / 1000000;
+ }
+
+ for (opp = gpu.opps; opp->frequency != 0; opp++) {
+ opp->power = gpu_core_coefficient *
+ gpu_core_count *
+ (opp->frequency / FWK_MHZ) *
+ (opp->voltage * opp->voltage) / 1000000;
+ }
+
return element_table;
}
diff --git a/product/sgm775/scp_ramfw/config_mock_psu.c b/product/sgm775/scp_ramfw/config_mock_psu.c
index 5bf1149b..13c44db4 100644
--- a/product/sgm775/scp_ramfw/config_mock_psu.c
+++ b/product/sgm775/scp_ramfw/config_mock_psu.c
@@ -21,7 +21,7 @@ static const struct fwk_element element_table[] = {
.async_response_api_id = FWK_ID_NONE_INIT,
.default_enabled = true,
- .default_voltage = 100,
+ .default_voltage = 800,
},
},
[CONFIG_MOCK_PSU_ELEMENT_IDX_CPU_GROUP_BIG] = {
@@ -34,7 +34,7 @@ static const struct fwk_element element_table[] = {
.async_response_api_id = FWK_ID_NONE_INIT,
.default_enabled = true,
- .default_voltage = 100,
+ .default_voltage = 800,
},
},
[CONFIG_MOCK_PSU_ELEMENT_IDX_GPU] = {
@@ -47,7 +47,7 @@ static const struct fwk_element element_table[] = {
.async_response_api_id = FWK_ID_NONE_INIT,
.default_enabled = true,
- .default_voltage = 100,
+ .default_voltage = 800,
},
},
[CONFIG_MOCK_PSU_ELEMENT_IDX_VPU] = {
@@ -60,7 +60,7 @@ static const struct fwk_element element_table[] = {
.async_response_api_id = FWK_ID_NONE_INIT,
.default_enabled = true,
- .default_voltage = 100,
+ .default_voltage = 800,
},
},
{ 0 }
diff --git a/product/sgm776/scp_ramfw/config_dvfs.c b/product/sgm776/scp_ramfw/config_dvfs.c
index e48d5aea..ca4a24a9 100644
--- a/product/sgm776/scp_ramfw/config_dvfs.c
+++ b/product/sgm776/scp_ramfw/config_dvfs.c
@@ -5,12 +5,14 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
+#include <fwk_assert.h>
#include <fwk_element.h>
#include <fwk_macros.h>
#include <fwk_module.h>
#include <fwk_module_idx.h>
#include <config_dvfs.h>
#include <mod_dvfs.h>
+#include <mod_sid.h>
static const struct mod_dvfs_domain_config cpu_group_little = {
.psu_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_PSU, 0),
@@ -20,23 +22,23 @@ static const struct mod_dvfs_domain_config cpu_group_little = {
.opps = (struct mod_dvfs_opp[]) {
{
.frequency = 665 * FWK_MHZ,
- .voltage = 100,
+ .voltage = 800,
},
{
.frequency = 998 * FWK_MHZ,
- .voltage = 200,
+ .voltage = 850,
},
{
.frequency = 1330 * FWK_MHZ,
- .voltage = 300,
+ .voltage = 900,
},
{
.frequency = 1463 * FWK_MHZ,
- .voltage = 400,
+ .voltage = 950,
},
{
.frequency = 2200 * FWK_MHZ,
- .voltage = 500,
+ .voltage = 1000,
},
{ 0 }
}
@@ -50,23 +52,23 @@ static const struct mod_dvfs_domain_config cpu_group_big = {
.opps = (struct mod_dvfs_opp[]) {
{
.frequency = 1313 * FWK_MHZ,
- .voltage = 100,
+ .voltage = 800,
},
{
.frequency = 1531 * FWK_MHZ,
- .voltage = 200,
+ .voltage = 850,
},
{
.frequency = 1750 * FWK_MHZ,
- .voltage = 300,
+ .voltage = 900,
},
{
.frequency = 2100 * FWK_MHZ,
- .voltage = 400,
+ .voltage = 950,
},
{
.frequency = 2700 * FWK_MHZ,
- .voltage = 500,
+ .voltage = 1000,
},
{ 0 }
}
@@ -80,23 +82,23 @@ static const struct mod_dvfs_domain_config gpu = {
.opps = (struct mod_dvfs_opp[]) {
{
.frequency = 450 * FWK_MHZ,
- .voltage = 100,
+ .voltage = 800,
},
{
.frequency = 487500 * FWK_KHZ,
- .voltage = 200,
+ .voltage = 850,
},
{
.frequency = 525 * FWK_MHZ,
- .voltage = 300,
+ .voltage = 900,
},
{
.frequency = 562500 * FWK_KHZ,
- .voltage = 400,
+ .voltage = 950,
},
{
.frequency = 800 * FWK_MHZ,
- .voltage = 500,
+ .voltage = 1000,
},
{ 0 }
}
@@ -120,6 +122,85 @@ static const struct fwk_element element_table[] = {
static const struct fwk_element *dvfs_get_element_table(fwk_id_t module_id)
{
+ int status;
+ const struct mod_sid_info *system_info;
+ double big_cpu_core_coefficient;
+ unsigned int big_cpu_core_count;
+ double little_cpu_core_coefficient;
+ unsigned int little_cpu_core_count;
+ double gpu_core_coefficient;
+ unsigned int gpu_core_count;
+ struct mod_dvfs_opp *opp;
+
+ status = mod_sid_get_system_info(&system_info);
+ fwk_assert(status == FWK_SUCCESS);
+
+ big_cpu_core_coefficient = 0.08;
+ little_cpu_core_coefficient = 0.338;
+ gpu_core_coefficient = 0.604;
+
+ switch (system_info->config_number) {
+ case 1:
+ case 5:
+ big_cpu_core_count = 2;
+ little_cpu_core_count = 6;
+ gpu_core_count = 12;
+ break;
+ case 2:
+ case 6:
+ big_cpu_core_count = 4;
+ little_cpu_core_count = 4;
+ gpu_core_count = 12;
+ break;
+ case 3:
+ case 4:
+ big_cpu_core_count = 4;
+ little_cpu_core_count = 4;
+ gpu_core_count = 16;
+ break;
+ case 7:
+ big_cpu_core_count = 2;
+ little_cpu_core_count = 4;
+ gpu_core_count = 16;
+ break;
+ case 8:
+ big_cpu_core_count = 2;
+ little_cpu_core_count = 4;
+ gpu_core_count = 12;
+ break;
+ default:
+ fwk_unreachable();
+ }
+
+ /*
+ * The power cost figures below are built using the dynamic power
+ * consumption formula (P = CfV^2), where C represents the capacitance of
+ * one processing element in the domain (a core or shader core). This power
+ * figure is scaled linearly with the number of processing elements in the
+ * performance domain to give a rough representation of the overall power
+ * draw. The capacitance constants are given in mW/MHz/V^2.
+ */
+ for (opp = cpu_group_little.opps; opp->frequency != 0; opp++) {
+ opp->power = little_cpu_core_coefficient *
+ little_cpu_core_count *
+ (opp->frequency / FWK_MHZ) *
+ (opp->voltage * opp->voltage) / 1000000;
+ }
+
+ for (opp = cpu_group_big.opps; opp->frequency != 0; opp++) {
+ opp->power = big_cpu_core_coefficient *
+ big_cpu_core_count *
+ (opp->frequency / FWK_MHZ) *
+ (opp->voltage * opp->voltage) / 1000000;
+ }
+
+ for (opp = gpu.opps; opp->frequency != 0; opp++) {
+ opp->power = gpu_core_coefficient *
+ gpu_core_count *
+ (opp->frequency / FWK_MHZ) *
+ (opp->voltage * opp->voltage) / 1000000;
+ }
+
return element_table;
}
diff --git a/product/sgm776/scp_ramfw/config_mock_psu.c b/product/sgm776/scp_ramfw/config_mock_psu.c
index 0bfc203e..b6b104da 100644
--- a/product/sgm776/scp_ramfw/config_mock_psu.c
+++ b/product/sgm776/scp_ramfw/config_mock_psu.c
@@ -20,7 +20,7 @@ static const struct fwk_element element_table[] = {
.async_response_api_id = FWK_ID_NONE_INIT,
.default_enabled = true,
- .default_voltage = 100,
+ .default_voltage = 800,
},
},
{
@@ -33,7 +33,7 @@ static const struct fwk_element element_table[] = {
.async_response_api_id = FWK_ID_NONE_INIT,
.default_enabled = true,
- .default_voltage = 100,
+ .default_voltage = 800,
},
},
{
@@ -46,7 +46,7 @@ static const struct fwk_element element_table[] = {
.async_response_api_id = FWK_ID_NONE_INIT,
.default_enabled = true,
- .default_voltage = 100,
+ .default_voltage = 800,
},
},
{
@@ -59,7 +59,7 @@ static const struct fwk_element element_table[] = {
.async_response_api_id = FWK_ID_NONE_INIT,
.default_enabled = true,
- .default_voltage = 100,
+ .default_voltage = 800,
},
},
{ 0 }