diff options
author | Chris Kay <chris.kay@arm.com> | 2020-01-27 09:52:02 +0000 |
---|---|---|
committer | jimqui01 <54316584+jimqui01@users.noreply.github.com> | 2020-03-03 15:11:04 +0000 |
commit | 3cd1ca62dd56cd25977b743cb8dd12ea86b10ccb (patch) | |
tree | 2599814d2a9cec5d9d920794c4c39347a77f4261 | |
parent | 7a7080fbc30a03b623a38ce9b74d3a2b40ba10fe (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.c | 49 | ||||
-rw-r--r-- | product/rdn1e1/scp_ramfw/config_mock_psu.c | 4 | ||||
-rw-r--r-- | product/sgm775/scp_ramfw/config_dvfs.c | 123 | ||||
-rw-r--r-- | product/sgm775/scp_ramfw/config_mock_psu.c | 8 | ||||
-rw-r--r-- | product/sgm776/scp_ramfw/config_dvfs.c | 111 | ||||
-rw-r--r-- | product/sgm776/scp_ramfw/config_mock_psu.c | 8 |
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 } |