summaryrefslogtreecommitdiffstats
path: root/src/import/chips/p9
diff options
context:
space:
mode:
authorJacob Harvey <jlharvey@us.ibm.com>2016-10-13 09:29:46 -0500
committerDaniel M. Crowell <dcrowell@us.ibm.com>2016-10-27 11:06:51 -0400
commitee413cb5a6ae5b743582c61427ab3d9f8ec1afc7 (patch)
tree4669e9e0dbf2f2ef14faa1d8b6b621376a1182b8 /src/import/chips/p9
parent097b78713b5afd3a0e5ec4fbe6233237f5b2319b (diff)
downloadtalos-hostboot-ee413cb5a6ae5b743582c61427ab3d9f8ec1afc7.tar.gz
talos-hostboot-ee413cb5a6ae5b743582c61427ab3d9f8ec1afc7.zip
Started implementation of bulk_pwr_throttles
Added calc_power and calc_databus functions for throttling Added testing for those calc functions Added a set_power_attrs which decodes power curve attributes Change-Id: I2f08f846f6b19b0200b1c1df4a095cabfa9ee840 Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/31163 Reviewed-by: Brian R. Silver <bsilver@us.ibm.com> Reviewed-by: Louis Stermole <stermole@us.ibm.com> Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com> Tested-by: Hostboot CI <hostboot-ci+hostboot@us.ibm.com> Reviewed-by: Jennifer A. Stofer <stofer@us.ibm.com> Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/31259 Reviewed-by: Matt Derksen <v2cibmd@us.ibm.com> Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com> Reviewed-by: JACOB L. HARVEY <jlharvey@us.ibm.com> Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
Diffstat (limited to 'src/import/chips/p9')
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/mss_attribute_accessors.H464
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/power_thermal/decoder.C46
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/power_thermal/decoder.H31
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/power_thermal/throttle.C286
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/power_thermal/throttle.H179
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/p9_mss_bulk_pwr_throttles.C30
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/p9_mss_eff_config_thermal.C112
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/p9_mss_eff_config_thermal.H5
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/p9_mss_utils_to_throttle.C4
-rw-r--r--src/import/chips/p9/procedures/xml/attribute_info/memory_mcs_attributes.xml60
-rwxr-xr-xsrc/import/chips/p9/procedures/xml/attribute_info/memory_mrw_attributes.xml6
-rw-r--r--src/import/chips/p9/procedures/xml/error_info/p9_memory_mss_eff_config.xml32
12 files changed, 669 insertions, 586 deletions
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/mss_attribute_accessors.H b/src/import/chips/p9/procedures/hwp/memory/lib/mss_attribute_accessors.H
index 0fc3992bc..5d99d8caf 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/mss_attribute_accessors.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/mss_attribute_accessors.H
@@ -5292,83 +5292,6 @@ fapi_try_exit:
}
///
-/// @brief ATTR_EFF_NUM_DROPS_PER_PORT getter
-/// @param[in] const ref to the fapi2::Target<fapi2::TARGET_TYPE_MCA>
-/// @param[out] ref to the value uint8_t
-/// @note Generated by gen_accessors.pl generateParameters (D)
-/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
-/// @note Specifies the number of DIMM dimensions that are valid per
-/// port.
-///
-inline fapi2::ReturnCode eff_num_drops_per_port(const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target, uint8_t& o_value)
-{
- uint8_t l_value[2];
-
- FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_EFF_NUM_DROPS_PER_PORT, i_target.getParent<fapi2::TARGET_TYPE_MCS>(), l_value) );
- o_value = l_value[mss::index(i_target)];
- return fapi2::current_err;
-
-fapi_try_exit:
- FAPI_ERR("failed accessing ATTR_EFF_NUM_DROPS_PER_PORT: 0x%lx (target: %s)",
- uint64_t(fapi2::current_err), mss::c_str(i_target));
- return fapi2::current_err;
-}
-
-///
-/// @brief ATTR_EFF_NUM_DROPS_PER_PORT getter
-/// @param[in] const ref to the fapi2::Target<fapi2::TARGET_TYPE_DIMM>
-/// @param[out] ref to the value uint8_t
-/// @note Generated by gen_accessors.pl generateParameters (D.1)
-/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
-/// @note Specifies the number of DIMM dimensions that are valid per
-/// port.
-///
-inline fapi2::ReturnCode eff_num_drops_per_port(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
- uint8_t& o_value)
-{
- uint8_t l_value[2];
- auto l_mca = i_target.getParent<fapi2::TARGET_TYPE_MCA>();
-
- FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_EFF_NUM_DROPS_PER_PORT, l_mca.getParent<fapi2::TARGET_TYPE_MCS>(), l_value) );
- o_value = l_value[mss::index(l_mca)];
- return fapi2::current_err;
-
-fapi_try_exit:
- FAPI_ERR("failed accessing ATTR_EFF_NUM_DROPS_PER_PORT: 0x%lx (target: %s)",
- uint64_t(fapi2::current_err), mss::c_str(i_target));
- return fapi2::current_err;
-}
-
-///
-/// @brief ATTR_EFF_NUM_DROPS_PER_PORT getter
-/// @param[in] const ref to the fapi2::Target<fapi2::TARGET_TYPE_MCS>
-/// @param[out] uint8_t* memory to store the value
-/// @note Generated by gen_accessors.pl generateParameters (E)
-/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
-/// @note Specifies the number of DIMM dimensions that are valid per
-/// port.
-///
-inline fapi2::ReturnCode eff_num_drops_per_port(const fapi2::Target<fapi2::TARGET_TYPE_MCS>& i_target, uint8_t* o_array)
-{
- if (o_array == nullptr)
- {
- FAPI_ERR("nullptr passed to attribute accessor %s", __func__);
- return fapi2::FAPI2_RC_INVALID_PARAMETER;
- }
-
- uint8_t l_value[2];
-
- FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_EFF_NUM_DROPS_PER_PORT, i_target, l_value) );
- memcpy(o_array, &l_value, 2);
- return fapi2::current_err;
-
-fapi_try_exit:
- FAPI_ERR("failed accessing ATTR_EFF_NUM_DROPS_PER_PORT: 0x%lx (target: %s)",
- uint64_t(fapi2::current_err), mss::c_str(i_target));
- return fapi2::current_err;
-}
-
-///
/// @brief ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM getter
/// @param[in] const ref to the fapi2::Target<fapi2::TARGET_TYPE_DIMM>
/// @param[out] ref to the value uint8_t
@@ -6050,15 +5973,15 @@ fapi_try_exit:
///
/// @brief ATTR_MSS_TOTAL_PWR_SLOPE getter
/// @param[in] const ref to the fapi2::Target<fapi2::TARGET_TYPE_DIMM>
-/// @param[out] ref to the value uint32_t
+/// @param[out] ref to the value uint16_t
/// @note Generated by gen_accessors.pl generateParameters (F)
/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
/// @note VDDR+VPP Power slope value for dimm creator: mss_eff_config consumer:
/// mss_bulk_pwr_throttles
///
-inline fapi2::ReturnCode total_pwr_slope(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, uint32_t& o_value)
+inline fapi2::ReturnCode total_pwr_slope(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, uint16_t& o_value)
{
- uint32_t l_value[2][2];
+ uint16_t l_value[2][2];
auto l_mca = i_target.getParent<fapi2::TARGET_TYPE_MCA>();
auto l_mcs = l_mca.getParent<fapi2::TARGET_TYPE_MCS>();
@@ -6075,13 +5998,13 @@ fapi_try_exit:
///
/// @brief ATTR_MSS_TOTAL_PWR_SLOPE getter
/// @param[in] const ref to the fapi2::Target<fapi2::TARGET_TYPE_MCA>
-/// @param[out] uint32_t* memory to store the value
+/// @param[out] uint16_t* memory to store the value
/// @note Generated by gen_accessors.pl generateParameters (G)
/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
/// @note VDDR+VPP Power slope value for dimm creator: mss_eff_config consumer:
/// mss_bulk_pwr_throttles
///
-inline fapi2::ReturnCode total_pwr_slope(const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target, uint32_t* o_array)
+inline fapi2::ReturnCode total_pwr_slope(const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target, uint16_t* o_array)
{
if (o_array == nullptr)
{
@@ -6089,11 +6012,11 @@ inline fapi2::ReturnCode total_pwr_slope(const fapi2::Target<fapi2::TARGET_TYPE_
return fapi2::FAPI2_RC_INVALID_PARAMETER;
}
- uint32_t l_value[2][2];
+ uint16_t l_value[2][2];
auto l_mcs = i_target.getParent<fapi2::TARGET_TYPE_MCS>();
FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MSS_TOTAL_PWR_SLOPE, l_mcs, l_value) );
- memcpy(o_array, &(l_value[mss::index(i_target)][0]), 8);
+ memcpy(o_array, &(l_value[mss::index(i_target)][0]), 4);
return fapi2::current_err;
fapi_try_exit:
@@ -6105,13 +6028,13 @@ fapi_try_exit:
///
/// @brief ATTR_MSS_TOTAL_PWR_SLOPE getter
/// @param[in] const ref to the fapi2::Target<fapi2::TARGET_TYPE_MCS>
-/// @param[out] uint32_t* memory to store the value
+/// @param[out] uint16_t* memory to store the value
/// @note Generated by gen_accessors.pl generateParameters (H)
/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
/// @note VDDR+VPP Power slope value for dimm creator: mss_eff_config consumer:
/// mss_bulk_pwr_throttles
///
-inline fapi2::ReturnCode total_pwr_slope(const fapi2::Target<fapi2::TARGET_TYPE_MCS>& i_target, uint32_t* o_array)
+inline fapi2::ReturnCode total_pwr_slope(const fapi2::Target<fapi2::TARGET_TYPE_MCS>& i_target, uint16_t* o_array)
{
if (o_array == nullptr)
{
@@ -6119,10 +6042,10 @@ inline fapi2::ReturnCode total_pwr_slope(const fapi2::Target<fapi2::TARGET_TYPE_
return fapi2::FAPI2_RC_INVALID_PARAMETER;
}
- uint32_t l_value[2][2];
+ uint16_t l_value[2][2];
FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MSS_TOTAL_PWR_SLOPE, i_target, l_value) );
- memcpy(o_array, &l_value, 16);
+ memcpy(o_array, &l_value, 8);
return fapi2::current_err;
fapi_try_exit:
@@ -6134,15 +6057,15 @@ fapi_try_exit:
///
/// @brief ATTR_MSS_TOTAL_PWR_INTERCEPT getter
/// @param[in] const ref to the fapi2::Target<fapi2::TARGET_TYPE_DIMM>
-/// @param[out] ref to the value uint32_t
+/// @param[out] ref to the value uint16_t
/// @note Generated by gen_accessors.pl generateParameters (F)
/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
/// @note VDDR+VPP Power intercept value for dimm creator: mss_eff_config consumer:
/// mss_bulk_pwr_throttles
///
-inline fapi2::ReturnCode total_pwr_intercept(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, uint32_t& o_value)
+inline fapi2::ReturnCode total_pwr_intercept(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, uint16_t& o_value)
{
- uint32_t l_value[2][2];
+ uint16_t l_value[2][2];
auto l_mca = i_target.getParent<fapi2::TARGET_TYPE_MCA>();
auto l_mcs = l_mca.getParent<fapi2::TARGET_TYPE_MCS>();
@@ -6159,13 +6082,13 @@ fapi_try_exit:
///
/// @brief ATTR_MSS_TOTAL_PWR_INTERCEPT getter
/// @param[in] const ref to the fapi2::Target<fapi2::TARGET_TYPE_MCA>
-/// @param[out] uint32_t* memory to store the value
+/// @param[out] uint16_t* memory to store the value
/// @note Generated by gen_accessors.pl generateParameters (G)
/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
/// @note VDDR+VPP Power intercept value for dimm creator: mss_eff_config consumer:
/// mss_bulk_pwr_throttles
///
-inline fapi2::ReturnCode total_pwr_intercept(const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target, uint32_t* o_array)
+inline fapi2::ReturnCode total_pwr_intercept(const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target, uint16_t* o_array)
{
if (o_array == nullptr)
{
@@ -6173,11 +6096,11 @@ inline fapi2::ReturnCode total_pwr_intercept(const fapi2::Target<fapi2::TARGET_T
return fapi2::FAPI2_RC_INVALID_PARAMETER;
}
- uint32_t l_value[2][2];
+ uint16_t l_value[2][2];
auto l_mcs = i_target.getParent<fapi2::TARGET_TYPE_MCS>();
FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MSS_TOTAL_PWR_INTERCEPT, l_mcs, l_value) );
- memcpy(o_array, &(l_value[mss::index(i_target)][0]), 8);
+ memcpy(o_array, &(l_value[mss::index(i_target)][0]), 4);
return fapi2::current_err;
fapi_try_exit:
@@ -6189,13 +6112,13 @@ fapi_try_exit:
///
/// @brief ATTR_MSS_TOTAL_PWR_INTERCEPT getter
/// @param[in] const ref to the fapi2::Target<fapi2::TARGET_TYPE_MCS>
-/// @param[out] uint32_t* memory to store the value
+/// @param[out] uint16_t* memory to store the value
/// @note Generated by gen_accessors.pl generateParameters (H)
/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
/// @note VDDR+VPP Power intercept value for dimm creator: mss_eff_config consumer:
/// mss_bulk_pwr_throttles
///
-inline fapi2::ReturnCode total_pwr_intercept(const fapi2::Target<fapi2::TARGET_TYPE_MCS>& i_target, uint32_t* o_array)
+inline fapi2::ReturnCode total_pwr_intercept(const fapi2::Target<fapi2::TARGET_TYPE_MCS>& i_target, uint16_t* o_array)
{
if (o_array == nullptr)
{
@@ -6203,10 +6126,10 @@ inline fapi2::ReturnCode total_pwr_intercept(const fapi2::Target<fapi2::TARGET_T
return fapi2::FAPI2_RC_INVALID_PARAMETER;
}
- uint32_t l_value[2][2];
+ uint16_t l_value[2][2];
FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MSS_TOTAL_PWR_INTERCEPT, i_target, l_value) );
- memcpy(o_array, &l_value, 16);
+ memcpy(o_array, &l_value, 8);
return fapi2::current_err;
fapi_try_exit:
@@ -6216,345 +6139,6 @@ fapi_try_exit:
}
///
-/// @brief ATTR_MSS_MASTER_PWR_SLOPE getter
-/// @param[in] const ref to the fapi2::Target<fapi2::TARGET_TYPE_DIMM>
-/// @param[out] ref to the value uint32_t
-/// @note Generated by gen_accessors.pl generateParameters (F)
-/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
-/// @note Master Power slope value for
-/// dimm
-///
-inline fapi2::ReturnCode master_pwr_slope(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, uint32_t& o_value)
-{
- uint32_t l_value[2][2];
- auto l_mca = i_target.getParent<fapi2::TARGET_TYPE_MCA>();
- auto l_mcs = l_mca.getParent<fapi2::TARGET_TYPE_MCS>();
-
- FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MSS_MASTER_PWR_SLOPE, l_mcs, l_value) );
- o_value = l_value[mss::index(l_mca)][mss::index(i_target)];
- return fapi2::current_err;
-
-fapi_try_exit:
- FAPI_ERR("failed accessing ATTR_MSS_MASTER_PWR_SLOPE: 0x%lx (target: %s)",
- uint64_t(fapi2::current_err), mss::c_str(i_target));
- return fapi2::current_err;
-}
-
-///
-/// @brief ATTR_MSS_MASTER_PWR_SLOPE getter
-/// @param[in] const ref to the fapi2::Target<fapi2::TARGET_TYPE_MCA>
-/// @param[out] uint32_t* memory to store the value
-/// @note Generated by gen_accessors.pl generateParameters (G)
-/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
-/// @note Master Power slope value for
-/// dimm
-///
-inline fapi2::ReturnCode master_pwr_slope(const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target, uint32_t* o_array)
-{
- if (o_array == nullptr)
- {
- FAPI_ERR("nullptr passed to attribute accessor %s", __func__);
- return fapi2::FAPI2_RC_INVALID_PARAMETER;
- }
-
- uint32_t l_value[2][2];
- auto l_mcs = i_target.getParent<fapi2::TARGET_TYPE_MCS>();
-
- FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MSS_MASTER_PWR_SLOPE, l_mcs, l_value) );
- memcpy(o_array, &(l_value[mss::index(i_target)][0]), 8);
- return fapi2::current_err;
-
-fapi_try_exit:
- FAPI_ERR("failed accessing ATTR_MSS_MASTER_PWR_SLOPE: 0x%lx (target: %s)",
- uint64_t(fapi2::current_err), mss::c_str(i_target));
- return fapi2::current_err;
-}
-
-///
-/// @brief ATTR_MSS_MASTER_PWR_SLOPE getter
-/// @param[in] const ref to the fapi2::Target<fapi2::TARGET_TYPE_MCS>
-/// @param[out] uint32_t* memory to store the value
-/// @note Generated by gen_accessors.pl generateParameters (H)
-/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
-/// @note Master Power slope value for
-/// dimm
-///
-inline fapi2::ReturnCode master_pwr_slope(const fapi2::Target<fapi2::TARGET_TYPE_MCS>& i_target, uint32_t* o_array)
-{
- if (o_array == nullptr)
- {
- FAPI_ERR("nullptr passed to attribute accessor %s", __func__);
- return fapi2::FAPI2_RC_INVALID_PARAMETER;
- }
-
- uint32_t l_value[2][2];
-
- FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MSS_MASTER_PWR_SLOPE, i_target, l_value) );
- memcpy(o_array, &l_value, 16);
- return fapi2::current_err;
-
-fapi_try_exit:
- FAPI_ERR("failed accessing ATTR_MSS_MASTER_PWR_SLOPE: 0x%lx (target: %s)",
- uint64_t(fapi2::current_err), mss::c_str(i_target));
- return fapi2::current_err;
-}
-
-///
-/// @brief ATTR_MSS_SUPPLIER_PWR_SLOPE getter
-/// @param[in] const ref to the fapi2::Target<fapi2::TARGET_TYPE_DIMM>
-/// @param[out] ref to the value uint32_t
-/// @note Generated by gen_accessors.pl generateParameters (F)
-/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
-/// @note Supplier Power slope value for
-/// dimm
-///
-inline fapi2::ReturnCode supplier_pwr_slope(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, uint32_t& o_value)
-{
- uint32_t l_value[2][2];
- auto l_mca = i_target.getParent<fapi2::TARGET_TYPE_MCA>();
- auto l_mcs = l_mca.getParent<fapi2::TARGET_TYPE_MCS>();
-
- FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MSS_SUPPLIER_PWR_SLOPE, l_mcs, l_value) );
- o_value = l_value[mss::index(l_mca)][mss::index(i_target)];
- return fapi2::current_err;
-
-fapi_try_exit:
- FAPI_ERR("failed accessing ATTR_MSS_SUPPLIER_PWR_SLOPE: 0x%lx (target: %s)",
- uint64_t(fapi2::current_err), mss::c_str(i_target));
- return fapi2::current_err;
-}
-
-///
-/// @brief ATTR_MSS_SUPPLIER_PWR_SLOPE getter
-/// @param[in] const ref to the fapi2::Target<fapi2::TARGET_TYPE_MCA>
-/// @param[out] uint32_t* memory to store the value
-/// @note Generated by gen_accessors.pl generateParameters (G)
-/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
-/// @note Supplier Power slope value for
-/// dimm
-///
-inline fapi2::ReturnCode supplier_pwr_slope(const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target, uint32_t* o_array)
-{
- if (o_array == nullptr)
- {
- FAPI_ERR("nullptr passed to attribute accessor %s", __func__);
- return fapi2::FAPI2_RC_INVALID_PARAMETER;
- }
-
- uint32_t l_value[2][2];
- auto l_mcs = i_target.getParent<fapi2::TARGET_TYPE_MCS>();
-
- FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MSS_SUPPLIER_PWR_SLOPE, l_mcs, l_value) );
- memcpy(o_array, &(l_value[mss::index(i_target)][0]), 8);
- return fapi2::current_err;
-
-fapi_try_exit:
- FAPI_ERR("failed accessing ATTR_MSS_SUPPLIER_PWR_SLOPE: 0x%lx (target: %s)",
- uint64_t(fapi2::current_err), mss::c_str(i_target));
- return fapi2::current_err;
-}
-
-///
-/// @brief ATTR_MSS_SUPPLIER_PWR_SLOPE getter
-/// @param[in] const ref to the fapi2::Target<fapi2::TARGET_TYPE_MCS>
-/// @param[out] uint32_t* memory to store the value
-/// @note Generated by gen_accessors.pl generateParameters (H)
-/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
-/// @note Supplier Power slope value for
-/// dimm
-///
-inline fapi2::ReturnCode supplier_pwr_slope(const fapi2::Target<fapi2::TARGET_TYPE_MCS>& i_target, uint32_t* o_array)
-{
- if (o_array == nullptr)
- {
- FAPI_ERR("nullptr passed to attribute accessor %s", __func__);
- return fapi2::FAPI2_RC_INVALID_PARAMETER;
- }
-
- uint32_t l_value[2][2];
-
- FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MSS_SUPPLIER_PWR_SLOPE, i_target, l_value) );
- memcpy(o_array, &l_value, 16);
- return fapi2::current_err;
-
-fapi_try_exit:
- FAPI_ERR("failed accessing ATTR_MSS_SUPPLIER_PWR_SLOPE: 0x%lx (target: %s)",
- uint64_t(fapi2::current_err), mss::c_str(i_target));
- return fapi2::current_err;
-}
-
-///
-/// @brief ATTR_MSS_MASTER_PWR_INTERCEPT getter
-/// @param[in] const ref to the fapi2::Target<fapi2::TARGET_TYPE_DIMM>
-/// @param[out] ref to the value uint32_t
-/// @note Generated by gen_accessors.pl generateParameters (F)
-/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
-/// @note Master Power intercept value for
-/// dimm
-///
-inline fapi2::ReturnCode master_pwr_intercept(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, uint32_t& o_value)
-{
- uint32_t l_value[2][2];
- auto l_mca = i_target.getParent<fapi2::TARGET_TYPE_MCA>();
- auto l_mcs = l_mca.getParent<fapi2::TARGET_TYPE_MCS>();
-
- FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MSS_MASTER_PWR_INTERCEPT, l_mcs, l_value) );
- o_value = l_value[mss::index(l_mca)][mss::index(i_target)];
- return fapi2::current_err;
-
-fapi_try_exit:
- FAPI_ERR("failed accessing ATTR_MSS_MASTER_PWR_INTERCEPT: 0x%lx (target: %s)",
- uint64_t(fapi2::current_err), mss::c_str(i_target));
- return fapi2::current_err;
-}
-
-///
-/// @brief ATTR_MSS_MASTER_PWR_INTERCEPT getter
-/// @param[in] const ref to the fapi2::Target<fapi2::TARGET_TYPE_MCA>
-/// @param[out] uint32_t* memory to store the value
-/// @note Generated by gen_accessors.pl generateParameters (G)
-/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
-/// @note Master Power intercept value for
-/// dimm
-///
-inline fapi2::ReturnCode master_pwr_intercept(const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target, uint32_t* o_array)
-{
- if (o_array == nullptr)
- {
- FAPI_ERR("nullptr passed to attribute accessor %s", __func__);
- return fapi2::FAPI2_RC_INVALID_PARAMETER;
- }
-
- uint32_t l_value[2][2];
- auto l_mcs = i_target.getParent<fapi2::TARGET_TYPE_MCS>();
-
- FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MSS_MASTER_PWR_INTERCEPT, l_mcs, l_value) );
- memcpy(o_array, &(l_value[mss::index(i_target)][0]), 8);
- return fapi2::current_err;
-
-fapi_try_exit:
- FAPI_ERR("failed accessing ATTR_MSS_MASTER_PWR_INTERCEPT: 0x%lx (target: %s)",
- uint64_t(fapi2::current_err), mss::c_str(i_target));
- return fapi2::current_err;
-}
-
-///
-/// @brief ATTR_MSS_MASTER_PWR_INTERCEPT getter
-/// @param[in] const ref to the fapi2::Target<fapi2::TARGET_TYPE_MCS>
-/// @param[out] uint32_t* memory to store the value
-/// @note Generated by gen_accessors.pl generateParameters (H)
-/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
-/// @note Master Power intercept value for
-/// dimm
-///
-inline fapi2::ReturnCode master_pwr_intercept(const fapi2::Target<fapi2::TARGET_TYPE_MCS>& i_target, uint32_t* o_array)
-{
- if (o_array == nullptr)
- {
- FAPI_ERR("nullptr passed to attribute accessor %s", __func__);
- return fapi2::FAPI2_RC_INVALID_PARAMETER;
- }
-
- uint32_t l_value[2][2];
-
- FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MSS_MASTER_PWR_INTERCEPT, i_target, l_value) );
- memcpy(o_array, &l_value, 16);
- return fapi2::current_err;
-
-fapi_try_exit:
- FAPI_ERR("failed accessing ATTR_MSS_MASTER_PWR_INTERCEPT: 0x%lx (target: %s)",
- uint64_t(fapi2::current_err), mss::c_str(i_target));
- return fapi2::current_err;
-}
-
-///
-/// @brief ATTR_MSS_SUPPLIER_PWR_INTERCEPT getter
-/// @param[in] const ref to the fapi2::Target<fapi2::TARGET_TYPE_DIMM>
-/// @param[out] ref to the value uint32_t
-/// @note Generated by gen_accessors.pl generateParameters (F)
-/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
-/// @note Supplier Power intercept value for
-/// dimm
-///
-inline fapi2::ReturnCode supplier_pwr_intercept(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
- uint32_t& o_value)
-{
- uint32_t l_value[2][2];
- auto l_mca = i_target.getParent<fapi2::TARGET_TYPE_MCA>();
- auto l_mcs = l_mca.getParent<fapi2::TARGET_TYPE_MCS>();
-
- FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MSS_SUPPLIER_PWR_INTERCEPT, l_mcs, l_value) );
- o_value = l_value[mss::index(l_mca)][mss::index(i_target)];
- return fapi2::current_err;
-
-fapi_try_exit:
- FAPI_ERR("failed accessing ATTR_MSS_SUPPLIER_PWR_INTERCEPT: 0x%lx (target: %s)",
- uint64_t(fapi2::current_err), mss::c_str(i_target));
- return fapi2::current_err;
-}
-
-///
-/// @brief ATTR_MSS_SUPPLIER_PWR_INTERCEPT getter
-/// @param[in] const ref to the fapi2::Target<fapi2::TARGET_TYPE_MCA>
-/// @param[out] uint32_t* memory to store the value
-/// @note Generated by gen_accessors.pl generateParameters (G)
-/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
-/// @note Supplier Power intercept value for
-/// dimm
-///
-inline fapi2::ReturnCode supplier_pwr_intercept(const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
- uint32_t* o_array)
-{
- if (o_array == nullptr)
- {
- FAPI_ERR("nullptr passed to attribute accessor %s", __func__);
- return fapi2::FAPI2_RC_INVALID_PARAMETER;
- }
-
- uint32_t l_value[2][2];
- auto l_mcs = i_target.getParent<fapi2::TARGET_TYPE_MCS>();
-
- FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MSS_SUPPLIER_PWR_INTERCEPT, l_mcs, l_value) );
- memcpy(o_array, &(l_value[mss::index(i_target)][0]), 8);
- return fapi2::current_err;
-
-fapi_try_exit:
- FAPI_ERR("failed accessing ATTR_MSS_SUPPLIER_PWR_INTERCEPT: 0x%lx (target: %s)",
- uint64_t(fapi2::current_err), mss::c_str(i_target));
- return fapi2::current_err;
-}
-
-///
-/// @brief ATTR_MSS_SUPPLIER_PWR_INTERCEPT getter
-/// @param[in] const ref to the fapi2::Target<fapi2::TARGET_TYPE_MCS>
-/// @param[out] uint32_t* memory to store the value
-/// @note Generated by gen_accessors.pl generateParameters (H)
-/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
-/// @note Supplier Power intercept value for
-/// dimm
-///
-inline fapi2::ReturnCode supplier_pwr_intercept(const fapi2::Target<fapi2::TARGET_TYPE_MCS>& i_target,
- uint32_t* o_array)
-{
- if (o_array == nullptr)
- {
- FAPI_ERR("nullptr passed to attribute accessor %s", __func__);
- return fapi2::FAPI2_RC_INVALID_PARAMETER;
- }
-
- uint32_t l_value[2][2];
-
- FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MSS_SUPPLIER_PWR_INTERCEPT, i_target, l_value) );
- memcpy(o_array, &l_value, 16);
- return fapi2::current_err;
-
-fapi_try_exit:
- FAPI_ERR("failed accessing ATTR_MSS_SUPPLIER_PWR_INTERCEPT: 0x%lx (target: %s)",
- uint64_t(fapi2::current_err), mss::c_str(i_target));
- return fapi2::current_err;
-}
-
-///
/// @brief ATTR_MSS_DIMM_MAXBANDWIDTH_GBS getter
/// @param[in] const ref to the fapi2::Target<fapi2::TARGET_TYPE_DIMM>
/// @param[out] ref to the value uint32_t
@@ -19490,7 +19074,7 @@ fapi_try_exit:
/// @note Generated by gen_accessors.pl generateParameters (SYSTEM)
/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
/// @note Memory power control settings programmed during IPL Used by OCC when exiting
-/// idle powersave
+/// idle power-save
/// mode
///
inline fapi2::ReturnCode mrw_power_control_requested(uint8_t& o_value)
@@ -19512,7 +19096,7 @@ fapi_try_exit:
/// @note Generated by gen_accessors.pl generateParameters (SYSTEM)
/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
/// @note Memory power control settings for IDLE powersave mode Used by OCC when entering
-/// idle powersave
+/// idle power-save
/// mode
///
inline fapi2::ReturnCode mrw_idle_power_control_requested(uint8_t& o_value)
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/power_thermal/decoder.C b/src/import/chips/p9/procedures/hwp/memory/lib/power_thermal/decoder.C
index 1013cbbfe..a6129774a 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/power_thermal/decoder.C
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/power_thermal/decoder.C
@@ -262,6 +262,52 @@ fapi2::ReturnCode decoder::find_thermal_power_limit (const std::vector<fapi2::bu
fapi_try_exit:
return fapi2::current_err;
}
+///
+/// @brief find the power curve attributes for each dimm on an MCS target
+/// @param[in] i_targets vector of MCS targets on which dimm attrs will be set
+/// @param[in] i_slope vector of generated hashes for encoding and values for MSS_MRW_POWER_SLOPE
+/// @param[in] i_intercept vector of generated hashes for encoding and values for MSS_MRW_POWER_INTERCEPT
+/// @param[in] i_thermal_power_limit vector of generated hashes for encoding and values for MSS_MRW_THERMAL_MEMORY_POWER_LIMIT
+/// @param[out] o_vddr_slope the VDDR power curve slope for each dimm
+/// @param[out] o_vddr_int the VDDR power curve intercept for each dimm
+/// @param[out] o_total_slope the VDDR+VPP power curve slope for each dimm
+/// @param[out] o_total_int the VDDR+VPP power curve intercept for each dimm
+/// @param[out] o_thermal_power the thermal power limit for the dimm
+/// @return FAPI2_RC_SUCCESS iff ok
+/// @note used to set power curve attributes in calling function
+/// @note decodes the attribute "encoding" to get the vddr and vddr/vpp power curves for a dimm
+///
+fapi2::ReturnCode get_power_attrs (const fapi2::Target<fapi2::TARGET_TYPE_MCS>& i_mcs,
+ const std::vector< fapi2::buffer< uint64_t > >& i_slope,
+ const std::vector< fapi2::buffer< uint64_t > >& i_intercept,
+ const std::vector< fapi2::buffer< uint64_t > >& i_thermal_power_limit,
+ uint16_t o_vddr_slope [PORTS_PER_MCS][MAX_DIMM_PER_PORT],
+ uint16_t o_vddr_int [PORTS_PER_MCS][MAX_DIMM_PER_PORT],
+ uint16_t o_total_slope[PORTS_PER_MCS][MAX_DIMM_PER_PORT],
+ uint16_t o_total_int [PORTS_PER_MCS][MAX_DIMM_PER_PORT],
+ uint32_t o_thermal_power [PORTS_PER_MCS][MAX_DIMM_PER_PORT])
+{
+ for (const auto& l_dimm : find_targets <fapi2::TARGET_TYPE_DIMM> (i_mcs))
+ {
+ const auto l_mca_pos = mss::index (find_target<TARGET_TYPE_MCA>(l_dimm));
+ const auto l_dimm_pos = mss::index (l_dimm);
+ mss::dimm::kind l_kind (l_dimm);
+ mss::power_thermal::decoder l_decoder(l_kind);
+ FAPI_TRY( l_decoder.generate_encoding() );
+ FAPI_TRY( l_decoder.find_slope(i_slope) );
+ FAPI_TRY( l_decoder.find_intercept(i_intercept) );
+ FAPI_TRY( l_decoder.find_thermal_power_limit(i_thermal_power_limit) );
+
+ o_vddr_slope [l_mca_pos][l_dimm_pos] = l_decoder.iv_vddr_slope;
+ o_vddr_int [l_mca_pos][l_dimm_pos] = l_decoder.iv_vddr_intercept;
+ o_total_slope [l_mca_pos][l_dimm_pos] = l_decoder.iv_total_slope;
+ o_total_int [l_mca_pos][l_dimm_pos] = l_decoder.iv_total_intercept;
+ o_thermal_power [l_mca_pos][l_dimm_pos] = l_decoder.iv_thermal_power_limit;
+ }
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
} //ns power_thermal
} // ns mss
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/power_thermal/decoder.H b/src/import/chips/p9/procedures/hwp/memory/lib/power_thermal/decoder.H
index 91e24d344..d7ca5bf71 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/power_thermal/decoder.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/power_thermal/decoder.H
@@ -41,6 +41,12 @@
#include <lib/utils/count_dimm.H>
namespace mss
{
+enum size_of_attrs : size_t
+{
+ SIZE_OF_POWER_CURVES_ATTRS = 100,
+ SIZE_OF_THERMAL_ATTR = 10,
+};
+
namespace power_thermal
{
@@ -223,6 +229,31 @@ class decoder
};
///
+/// @brief find the power curve attributes for each dimm on an MCS target
+/// @param[in] i_targets vector of MCS targets on which dimm attrs will be set
+/// @param[in] i_slope vector of generated hashes for encoding and values for MSS_MRW_POWER_SLOPE
+/// @param[in] i_intercept vector of generated hashes for encoding and values for MSS_MRW_POWER_INTERCEPT
+/// @param[in] i_thermal_power_limit vector of generated hashes for encoding and values for MSS_MRW_THERMAL_MEMORY_POWER_LIMIT
+/// @param[out] o_vddr_slope the VDDR power curve slope for each dimm
+/// @param[out] o_vddr_int the VDDR power curve intercept for each dimm
+/// @param[out] o_total_slope the VDDR+VPP power curve slope for each dimm
+/// @param[out] o_total_int the VDDR+VPP power curve intercept for each dimm
+/// @param[out] o_thermal_power the thermal power limit for the dimm
+/// @return FAPI2_RC_SUCCESS iff ok
+/// @note used to get power curve attributes in calling function
+/// @note decodes the attribute "encoding" to get the vddr and vddr/vpp power curves for a dimm
+///
+fapi2::ReturnCode get_power_attrs (const fapi2::Target<fapi2::TARGET_TYPE_MCS>& i_targets,
+ const std::vector< fapi2::buffer< uint64_t > >& i_slope,
+ const std::vector< fapi2::buffer< uint64_t > >& i_intercept,
+ const std::vector< fapi2::buffer< uint64_t > >& i_thermal_power_limit,
+ uint16_t o_vddr_slope [PORTS_PER_MCS][MAX_DIMM_PER_PORT],
+ uint16_t o_vddr_int [PORTS_PER_MCS][MAX_DIMM_PER_PORT],
+ uint16_t o_total_slope [PORTS_PER_MCS][MAX_DIMM_PER_PORT],
+ uint16_t o_total_int [PORTS_PER_MCS][MAX_DIMM_PER_PORT],
+ uint32_t o_thermal_power [PORTS_PER_MCS][MAX_DIMM_PER_PORT]);
+
+///
/// @brief Encode the attribute into a bit encoding
/// @tparam[in] S *ATTR*_SIZE enum used for fapi2::buffer position
/// @tparam[in] L *ATTR*_LEN enum used for fapi2::buffer position
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/power_thermal/throttle.C b/src/import/chips/p9/procedures/hwp/memory/lib/power_thermal/throttle.C
index c3f2c7686..f468ec708 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/power_thermal/throttle.C
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/power_thermal/throttle.C
@@ -37,6 +37,7 @@
// mss lib
#include <lib/power_thermal/throttle.H>
+#include <lib/utils/count_dimm.H>
#include <mss.H>
using fapi2::TARGET_TYPE_MCA;
using fapi2::TARGET_TYPE_MCS;
@@ -45,68 +46,273 @@ using fapi2::TARGET_TYPE_MCBIST;
namespace mss
{
+namespace power_thermal
+{
+
+
+///
+/// @brief Constructor
+/// @param[in] i_target MCS target to call power thermal stuff on
+/// @param[out] o_rc, a return code which determines the success of the constructor
+///
+throttle::throttle( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_mca, fapi2::ReturnCode o_rc) :
+ iv_target(i_mca),
+ iv_databus_port_max(0),
+ iv_runtime_n_slot(0),
+ iv_runtime_n_port(0),
+ iv_n_slot(0),
+ iv_n_port(0),
+ iv_port_power_limit(0),
+ iv_port_maxpower(0),
+ iv_calc_port_maxpower(0)
+{
+ uint32_t l_dimm_power_limits [MAX_DIMM_PER_PORT] = {};
+
+ FAPI_TRY( mem_throttled_n_commands_per_slot( iv_target, iv_n_slot) );
+ FAPI_TRY( mem_throttled_n_commands_per_port( iv_target, iv_n_port) );
+ FAPI_TRY( port_maxpower ( iv_target, iv_port_maxpower) );
+ FAPI_TRY( mrw_max_dram_databus_util(iv_databus_port_max) );
+
+ FAPI_TRY( mrw_dimm_power_curve_percent_uplift( iv_power_uplift) );
+ FAPI_TRY( mrw_dimm_power_curve_percent_uplift_idle( iv_power_uplift_idle) );
+ //FAPI_TRY( mrw_thermal_memory_power_limit( iv_dimm_thermal_limit) );
+
+ FAPI_TRY( runtime_mem_throttled_n_commands_per_slot(iv_target, iv_runtime_n_slot ) );
+ FAPI_TRY( runtime_mem_throttled_n_commands_per_port(iv_target, iv_runtime_n_port ) );
+ FAPI_TRY( mem_watt_target( iv_target, &(l_dimm_power_limits[0])) );
+ FAPI_TRY( mrw_mem_m_dram_clocks(iv_m_clocks) );
+
+ //Port power limit = sum of dimm power limits
+ for ( const auto& l_dimm : mss::find_targets<TARGET_TYPE_DIMM>(iv_target) )
+ {
+ iv_port_power_limit += l_dimm_power_limits[mss::index(l_dimm)];
+ }
+
+ FAPI_ASSERT ( (iv_databus_port_max != 0),
+ fapi2::MSS_NO_DATABUS_UTILIZATION()
+ .set_PORT_DATABUS_UTIL(iv_databus_port_max)
+ .set_MCA_TARGET(iv_target),
+ "Failed to get max databus utilization for target %s",
+ mss::c_str(iv_target));
+ o_rc = fapi2::FAPI2_RC_SUCCESS;
+ return;
+
+fapi_try_exit:
+ o_rc = fapi2::current_err;
+ FAPI_ERR("Error getting attributes for mss::power_thermal::throttle ctor");
+ return;
+}
///
/// @brief Set ATTR_MSS_CHANNEL_PAIR_MAXPOWER, ATTR_MSS_MEM_THROTTLED_N_COMMANDS_PER_SLOT and _PER_PORT
-/// @param[in] Vector of MCS's on the same VDDR domain
/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
/// @note Called in p9_mss_bulk_pwr_throttles
/// @note determines the throttle levels based off of the port's power curve,
/// @note the _per_slot throttles are set to the _per_port values
/// @note throttles are all equalized and set to the worst case value
///
-fapi2::ReturnCode bulk_power_regulator_throttles (const std::vector<fapi2::Target<TARGET_TYPE_MCS>>& i_targets)
+fapi2::ReturnCode throttle::power_regulator_throttles ()
{
-
- for (const auto& l_mcs : i_targets)
- {
- uint32_t l_databus_util_max = 0;
- uint8_t l_power_uplift = 0;
- uint8_t l_power_uplift_idle = 0;
- uint32_t l_dimm_power_limit [2][2] = {};
- uint32_t l_runtime_n_slot [2] = {};
- uint32_t l_m_clocks = 0;
- uint32_t l_final_n_slot_array[2] = {};
- uint32_t l_port_maxpower[2] = {};
-
- FAPI_TRY( mem_throttled_n_commands_per_slot( l_mcs, &(l_final_n_slot_array[0])) );
- FAPI_TRY( port_maxpower ( l_mcs, l_port_maxpower) );
- FAPI_TRY( mrw_max_dram_databus_util(l_databus_util_max) );
- FAPI_TRY( mrw_dimm_power_curve_percent_uplift( l_power_uplift) );
- FAPI_TRY( mrw_dimm_power_curve_percent_uplift_idle( l_power_uplift_idle) );
- FAPI_TRY( runtime_mem_throttled_n_commands_per_slot(l_mcs, &(l_runtime_n_slot[0]) ) );
- FAPI_TRY( mem_watt_target( l_mcs, &(l_dimm_power_limit[0][0])) );
- FAPI_TRY( mrw_mem_m_dram_clocks(l_m_clocks) );
- //Temp values until totally implemented
- l_port_maxpower[0] = 2088;
- l_port_maxpower[1] = 2088;
- //same for per port and per slot
- //Throttle per slot is set to per port value
- l_final_n_slot_array[0] = 115;
- l_final_n_slot_array[1] = 115;
- FAPI_TRY( FAPI_ATTR_SET( fapi2::ATTR_MSS_PORT_MAXPOWER, l_mcs, l_port_maxpower) );
- //Set the throttle for the MCS target
- FAPI_TRY( FAPI_ATTR_SET( fapi2::ATTR_MSS_MEM_THROTTLED_N_COMMANDS_PER_SLOT, l_mcs, l_final_n_slot_array ) );
- FAPI_TRY( FAPI_ATTR_SET( fapi2::ATTR_MSS_MEM_THROTTLED_N_COMMANDS_PER_PORT, l_mcs, l_final_n_slot_array ) );
- } // MCS
-
-fapi_try_exit:
- FAPI_INF("End power regulator bulk throttles");
return fapi2::current_err;
}
///
/// @brief Set ATTR_MSS_MEM_THROTTLED_N_COMMANDS_PER_SLOT and PER_PORT
-/// @param[in] Vector of MCS's on the same VDDR domain
/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
/// @note Called in p9_mss_bulk_pwr_throttles
/// @note Sets the throttle levels based off of the dimm's thermal limits
/// @note both DIMM's on a port are set to the same throttle level
///
-fapi2::ReturnCode bulk_thermal_throttles (const std::vector<fapi2::Target<TARGET_TYPE_MCS>>& i_targets)
+fapi2::ReturnCode throttle::thermal_throttles ()
{
- FAPI_INF("End thermal bulk throttles");
+
return fapi2::FAPI2_RC_SUCCESS;
}
+///
+/// @brief Calculates the min and max power usage for a port based off of power curves and utilizati
+/// @param[in] i_idle_util the utilization of the databus in idle mode
+/// @param[in] i_max_util the utilization of the port at maximum possible (mrw or calculated)
+/// @param[out] o_port_power_idle max value of port power in cW
+/// @param[out] o_port_power_max max value of port power in cW
+/// @note Called twice in p9_mss_bulk_pwr_throttles
+/// @note uses dimm power curves from class variables
+///
+void throttle::calc_port_power( const double i_idle_util [MAX_DIMM_PER_PORT],
+ const double i_max_util [MAX_DIMM_PER_PORT],
+ double& o_port_power_idle,
+ double& o_port_power_max)
+{
+ //Playing it safe
+ o_port_power_idle = 0;
+ o_port_power_max = 0;
+
+ //Calculate the port power curve info by summing the dimms on the port
+ for ( const auto& l_dimm : mss::find_targets<TARGET_TYPE_DIMM>(iv_target) )
+ {
+ uint32_t l_pos = mss::index(l_dimm);
+ //Sum up the dim's power to calculate the port power curve
+ o_port_power_idle +=
+ ( i_idle_util[l_pos] / UTIL_CONVERSION * iv_pwr_slope[l_pos]) + iv_pwr_int[l_pos];
+
+ o_port_power_max +=
+ ( i_max_util[l_pos] / UTIL_CONVERSION * iv_pwr_slope[l_pos]) + iv_pwr_int[l_pos];
+ }
+
+ //Raise the powers by the uplift percent
+ o_port_power_idle *= (1 + (double(iv_power_uplift_idle) / PERCENT_CONVERSION));
+ o_port_power_max *= (1 + (double(iv_power_uplift) / PERCENT_CONVERSION));
+}
+
+///
+/// @brief Calculate the port power curve in order to calculate the port utilization
+/// @paramp[in] i_port_power_calc_idle double of the port's power consumption at idle
+/// @paramp[in] i_port_power_calc_max double of the port's power consumption at max utilization
+/// @paramp[out] o_port_power_slope
+/// @paramp[out] o_port_power_int
+/// @note Called in p9_mss_bulk_pwr_throttles
+/// @note Port power curve needed to calculate the port utilization
+///
+fapi2::ReturnCode throttle::calc_port_power_curve (const double& i_port_power_calc_idle,
+ const double& i_port_power_calc_max,
+ uint32_t& o_port_power_slope,
+ uint32_t& o_port_power_int)
+{
+ double l_denominator = ((double(iv_databus_port_max) / UTIL_CONVERSION) - IDLE_UTIL);
+
+ FAPI_ASSERT(l_denominator != 0,
+ fapi2::MSS_CALC_PORT_POWER_CURVE_DIVIDE_BY_ZERO().
+ set_PORT_DATABUS_UTIL(iv_databus_port_max).
+ set_UTIL_CONVERSION(UTIL_CONVERSION).
+ set_IDLE_UTIL(IDLE_UTIL),
+ "Denominator = (databus(%d) / UTIL_CONVERSION (%d)) - IDLE_UTIL(%d)",
+ iv_databus_port_max,
+ UTIL_CONVERSION,
+ IDLE_UTIL);
+
+ o_port_power_slope = (i_port_power_calc_max - i_port_power_calc_idle) / l_denominator;
+ o_port_power_int = i_port_power_calc_idle - (o_port_power_slope * IDLE_UTIL);
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Calculate the port's databus utilization given the port's power curve
+/// @paramp[in] i_port_power_slope
+/// @paramp[in] i_port_power_int
+/// @paramp[out] o_port_util the port's databus utilization
+/// @note Called in p9_mss_bulk_pwr_throttles
+/// @note Chooses worst case between the maximum allowed databus utilization and the calculated value
+/// @notes makes sure that the utilization isn't 0
+///
+void throttle::calc_port_util_usage (const uint32_t& i_port_power_slope,
+ const uint32_t& i_port_power_int,
+ double& o_port_util)
+{
+ o_port_util = (double(iv_port_power_limit) - i_port_power_int) / i_port_power_slope * UTIL_CONVERSION;
+ o_port_util = (uint32_t(o_port_util) < iv_databus_port_max) ? o_port_util : iv_databus_port_max;
+ o_port_util = (o_port_util == 0) ? 1 : o_port_util;
+}
+
+///
+/// @brief Calculates the power max and idle for each dimm using power curves and databus utilization
+/// @param[out] o_dimm_power_idle double type for precision, the DIMM power limit in idle state (0 utilization)
+/// @param[out] o_dimm_power_max double type for precision, the DIMM power limit at max utilization
+/// @note Called in p9_mss_bulk_pwr_throttle for thermal_throttles, eff_config_thermal
+/// @note power values are as if dimm is alone on port, using port_databus_util_max
+///
+void throttle::calc_dimm_power( double o_dimm_power_idle [MAX_DIMM_PER_PORT],
+ double o_dimm_power_max [MAX_DIMM_PER_PORT])
+{
+ for ( const auto& l_dimm : mss::find_targets<TARGET_TYPE_DIMM>(iv_target) )
+ {
+ const auto l_pos = mss::index(l_dimm);
+
+ o_dimm_power_idle[l_pos] = iv_pwr_int[l_pos];
+ o_dimm_power_max[l_pos] = (double(iv_databus_port_max) / UTIL_CONVERSION) * iv_pwr_slope[l_pos] +
+ iv_pwr_int[l_pos];
+
+
+ //Raise the powers by the uplift percent
+ o_dimm_power_idle[l_pos] *= (1 + (iv_power_uplift_idle / PERCENT_CONVERSION));
+ o_dimm_power_max[l_pos] *= (1 + (iv_power_uplift / PERCENT_CONVERSION));
+ }
+}
+
+///
+/// @brief Converts the port maximum databus to a dimm level based on powerslopes and dimms installed
+/// @param[in] i_databus_port_max max databus utilization for the port (either calculated or mrw)
+/// @param[out] o_databus_dimm_max array of dimm utilization values
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff the split is OK
+/// @note Called in p9_mss_bulk_pwr_throttles
+/// @used to calculate the port power based off of DIMM power curves
+///
+fapi2::ReturnCode throttle::calc_databus( const double& i_databus_port_max,
+ double o_databus_dimm_max [MAX_DIMM_PER_PORT])
+{
+ uint8_t l_count_dimms = count_dimm (iv_target);
+
+ //No work for no dimms
+ if (l_count_dimms == 0)
+ {
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ for (const auto& l_dimm : mss::find_targets<fapi2::TARGET_TYPE_DIMM>(iv_target))
+ {
+ //Left early if count_dimms == 0
+ o_databus_dimm_max[mss::index(l_dimm)] = i_databus_port_max / l_count_dimms;
+ }
+
+ //If not equal power slopes, set the dimm with the highest power slope
+ //Should be correct even if only one DIMM installed
+ if (iv_pwr_slope[0] != iv_pwr_slope[1])
+ {
+ o_databus_dimm_max[0] = (iv_pwr_slope[0] > iv_pwr_slope[1]) ? i_databus_port_max : 0;
+ o_databus_dimm_max[1] = (iv_pwr_slope[1] > iv_pwr_slope[0]) ? i_databus_port_max : 0;
+ }
+
+ //make sure both aren't equal to 0
+ FAPI_ASSERT ( (o_databus_dimm_max[0] != 0) || (o_databus_dimm_max[1] != 0),
+ fapi2::MSS_NO_DATABUS_UTILIZATION()
+ .set_PORT_DATABUS_UTIL(iv_databus_port_max)
+ .set_MCA_TARGET(iv_target),
+ "Failed to calculated databus utilization for target %s",
+ mss::c_str(iv_target));
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Perform thermal calculations as part of the effective configuration
+/// @param[in] i_target the MCS target in which the runtime throttles will be reset
+/// @return FAPI2_RC_SUCCESS iff ok
+/// TK implement/ will be overun?
+///
+fapi2::ReturnCode restore_runtime_throttles( const fapi2::Target<fapi2::TARGET_TYPE_MCS>& i_target )
+{
+ uint32_t l_run_throttles [PORTS_PER_MCS] = {};
+ uint32_t l_max_databus = 0;
+ uint32_t l_throttle_m_clocks [PORTS_PER_MCS] = {};
+
+ FAPI_TRY( runtime_mem_m_dram_clocks(i_target, l_throttle_m_clocks) );
+ FAPI_TRY( mrw_max_dram_databus_util(l_max_databus) );
+
+ for (const auto& l_mca : find_targets<TARGET_TYPE_MCA> (i_target))
+ {
+ const uint8_t l_pos = mss::index(l_mca);
+ l_run_throttles[l_pos] = mss::power_thermal::throttled_cmds(l_max_databus, l_throttle_m_clocks[0]);
+ }
+
+ FAPI_TRY( FAPI_ATTR_SET( fapi2::ATTR_MSS_RUNTIME_MEM_THROTTLED_N_COMMANDS_PER_PORT, i_target, l_run_throttles) );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+}//namespace power_thermal
+
}//namespace mss
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/power_thermal/throttle.H b/src/import/chips/p9/procedures/hwp/memory/lib/power_thermal/throttle.H
index e22950a39..3259608ce 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/power_thermal/throttle.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/power_thermal/throttle.H
@@ -27,7 +27,7 @@
/// @brief throttle API
///
-// *HWP HWP Owner: Andre Marin <aamarin@us.ibm.com>
+// *HWP HWP Owner: Jacob Harvey <jlharvey@us.ibm.com>
// *HWP HWP Backup: Brian Silver <bsilver@us.ibm.com>
// *HWP Team: Memory
// *HWP Level: 2
@@ -36,15 +36,141 @@
#ifndef _MSS_POWER_THROTTLE_
#define _MSS_POWER_THROTTLE_
-
+#include <fapi2.H>
+#include <mss.H>
namespace mss
{
-
+namespace power_thermal
+{
enum throttle_const : size_t
{
- // Dram data bus utilization is 4X the address bus utilization
+ // Dram data bus utilization is bus utilization / 4
DRAM_BUS_UTILS = 4,
+ UTIL_CONVERSION = 10000,
PERCENT_CONVERSION = 100,
+ MIN_UTIL = 1,
+ IDLE_UTIL = 0,
+};
+///
+/// @class throttle
+/// @brief Determine power_thermal throttles for memory
+///
+class throttle
+{
+ private:
+
+ public:
+ const fapi2::Target<fapi2::TARGET_TYPE_MCA>& iv_target;
+ //dimm level
+ uint32_t iv_databus_port_max;
+
+ uint8_t iv_power_uplift_idle;
+ uint8_t iv_power_uplift;
+
+ uint32_t iv_runtime_n_slot;
+ uint32_t iv_runtime_n_port;
+ uint32_t iv_m_clocks;
+ uint32_t iv_dimm_thermal_limit[MAX_DIMM_PER_PORT] = {};
+ uint16_t iv_pwr_slope[MAX_DIMM_PER_PORT] = {};
+ uint16_t iv_pwr_int[MAX_DIMM_PER_PORT] = {};
+ uint32_t iv_n_slot;
+ uint32_t iv_n_port;
+ uint32_t iv_port_power_limit;
+ uint32_t iv_port_maxpower;
+ uint32_t iv_calc_port_maxpower;
+
+ //default ctor deleted
+ throttle() = delete;
+
+ ///
+ /// @brief Constructor
+ /// @param[in] i_target MCA target to call power thermal stuff on
+ /// @param[out] o_rc fapi2::ReturnCode fapi2::FAPI2_RC_SUCCESS iff ctor was successful
+ ///
+ throttle( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_mca, fapi2::ReturnCode o_rc);
+
+ //
+ // @brief Destructor
+ //
+ ~throttle() = default;
+
+ ///
+ /// @brief Calculates the min and max power usage for a port based off of power curves and utilizati
+ /// @param[in] i_idle_util the utilization of the databus in idle mode
+ /// @param[in] i_max_util the utilization of the port at maximum possible (mrw or calculated)
+ /// @param[out] o_port_power_idle max value of port power in cW
+ /// @param[out] o_port_power_max max value of port power in cW
+ /// @note Called twice in p9_mss_bulk_pwr_throttles
+ /// @note uses dimm power curves from class variables
+ ///
+ void calc_port_power(const double i_idle_util [MAX_DIMM_PER_PORT],
+ const double i_max_util [MAX_DIMM_PER_PORT],
+ double& o_port_power_idle,
+ double& o_port_power_max);
+ ///
+ /// @brief Calculate the port power curve in order to calculate the port utilization
+ /// @paramp[in] i_port_power_calc_idle double of the port's power consumption at idle
+ /// @paramp[in] i_port_power_calc_max double of the port's power consumption at max utilization
+ /// @paramp[out] o_port_power_slope
+ /// @paramp[out] o_port_power_int
+ /// @return FAPI2_RC_SUCCESS iff success
+ /// @note Called in p9_mss_bulk_pwr_throttles
+ /// @note Port power curve needed to calculate the port utilization
+ ///
+ fapi2::ReturnCode calc_port_power_curve(const double& i_port_power_calc_idle,
+ const double& i_port_power_calc_max,
+ uint32_t& o_port_power_slope,
+ uint32_t& o_port_power_int);
+ ///
+ /// @brief Calculate the port's databus utilization given the port's power curve
+ /// @paramp[in] i_port_power_slope
+ /// @paramp[in] i_port_power_int
+ /// @paramp[out] o_port_util the port's databus utilization
+ /// @note Called in p9_mss_bulk_pwr_throttles
+ /// @note Chooses worst case between the maximum allowed databus utilization and the calculated value
+ /// @notes makes sure that the utilization isn't 0
+ ///
+ void calc_port_util_usage(const uint32_t& i_port_power_slope,
+ const uint32_t& i_port_power_int,
+ double& o_port_util);
+
+ ///
+ /// @brief Calculates the power max and idle for each dimm using power curves and databus utilization
+ /// @param[out] o_dimm_power_idle double type for precision, the DIMM power limit in idle state (0 utilization)
+ /// @param[out] o_dimm_power_max double type for precision, the DIMM power limit at max utilization
+ /// @note Called in p9_mss_bulk_pwr_throttle for thermal_throttles, eff_config_thermal
+ /// @note power values are as if dimm is alone on port, using port_databus_util_max
+ ///
+ void calc_dimm_power(double o_dimm_power_idle [MAX_DIMM_PER_PORT],
+ double o_dimm_power_max [MAX_DIMM_PER_PORT]);
+ ///
+ /// @brief Converts the port maximum databus to a dimm level based on powerslopes and dimms installed
+ /// @param[in] i_databus_port_max max databus utilization for the port (either calculated or mrw)
+ /// @param[out] o_databus_dimm_max array of dimm utilization values
+ /// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff the split is OK
+ /// @note Called in p9_mss_bulk_pwr_throttles
+ /// @used to calculate the port power based off of DIMM power curves
+ ///
+ fapi2::ReturnCode calc_databus(const double& i_databus_port_max,
+ double o_databus_dimm_max [MAX_DIMM_PER_PORT]);
+
+ ///
+ /// @brief Set ATTR_MSS_CHANNEL_PAIR_MAXPOWER and ATTR_MSS_MEM_THROTTLED_N_COMMANDS_PER_SLOT,
+ /// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+ /// @note Called in p9_mss_bulk_pwr_throttles
+ /// @note determines the throttle levels based off of the port's power curve,
+ /// sets the slot throttles to the same
+ ///
+ fapi2::ReturnCode power_regulator_throttles ();
+
+ ///
+ /// @brief Set ATTR_MSS_MEM_THROTTLED_N_COMMANDS_PER_SLOT,
+ /// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+ /// @note Called in p9_mss_bulk_pwr_throttles
+ /// @note Sets the throttle levels based off of the dimm's thermal limits
+ /// @note both DIMM's on a port are set to the same throttle level
+ ///
+ fapi2::ReturnCode thermal_throttles ();
};
///
@@ -53,42 +179,41 @@ enum throttle_const : size_t
/// @param[in] i_num_dram_clocks window of M DRAM clocks
/// @return number of throttled commands allowed
/// @note Uses N/M Throttling.
-/// Equation: (DRAM data bus utilization Percent / 100 ) = ((N * 4) / M )
-/// Dram data bus utilization is 4X the address bus utilization
-///
+/// Equation: (DRAM data bus utilization Percent / 10000 ) = ((N * M) / 4 )
+/// Equation: N = (DRAM data bus utilization Percent * M) / (4 * 10000)
inline uint32_t throttled_cmds(const uint32_t i_databus_util, const uint32_t i_num_dram_clocks)
{
- constexpr uint64_t l_divisor = DRAM_BUS_UTILS * PERCENT_CONVERSION;
+ constexpr uint64_t l_divisor = DRAM_BUS_UTILS * UTIL_CONVERSION;
const uint64_t l_dividend = i_databus_util * i_num_dram_clocks;
- const uint64_t l_quotient = l_dividend / l_divisor;
- const uint64_t l_remainder = l_dividend % l_divisor;
+ const uint64_t l_result = l_dividend / l_divisor;
- return l_quotient + (l_remainder == 0 ? 0 : 1);
+ return l_result;
}
///
-/// @brief Set ATTR_MSS_CHANNEL_PAIR_MAXPOWER and ATTR_MSS_MEM_THROTTLED_N_COMMANDS_PER_SLOT,
-/// @param[in] Vector of MCS 's on the same VDDR domain
-/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
-/// @note Called in p9_mss_bulk_pwr_throttles
-/// @note determines the throttle levels based off of the port's power curve,
-/// sets the slot throttles to the same
+/// @brief Calculate the port databus utilization based off of N throttles and M dram clocks
+/// @param[in] i_n_throttles N (address operations) allowed within a window of M DRAM clocks
+/// @param[in] i_num_dram_clocks window of M DRAM clocks
+/// @return number of throttled commands allowed
+/// @note Uses N/M Throttling.
+/// Equation: databus utilization = (N * 4 * 100000) / M
///
-fapi2::ReturnCode bulk_power_regulator_throttles (const std::vector<fapi2::Target<fapi2::TARGET_TYPE_MCS>>&
- i_targets);
+inline double calc_util_from_throttles(const uint16_t i_n_throttles, const uint32_t i_num_dram_clocks)
+{
+ constexpr uint32_t l_multiplier = DRAM_BUS_UTILS * UTIL_CONVERSION;
+ return ( (double(i_n_throttles) * l_multiplier) / i_num_dram_clocks);
+
+}
///
-/// @brief Set ATTR_MSS_MEM_THROTTLED_N_COMMANDS_PER_SLOT,
-/// @param[in] Vector of MCS 's on the same VDDR domain
-/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
-/// @note Called in p9_mss_bulk_pwr_throttles
-/// @note Sets the throttle levels based off of the dimm's thermal limits
-/// @note both DIMM's on a port are set to the same throttle level
+/// @brief Perform thermal calculations as part of the effective configuration
+/// @param[in] i_target the MCS target in which the runtime throttles will be reset
+/// @return FAPI2_RC_SUCCESS iff ok
///
-fapi2::ReturnCode bulk_thermal_throttles (const std::vector<fapi2::Target<fapi2::TARGET_TYPE_MCS>>& i_targets);
-
+fapi2::ReturnCode restore_runtime_throttles( const fapi2::Target<fapi2::TARGET_TYPE_MCS>& i_target );
+}//power_thermal
}// mss
#endif
diff --git a/src/import/chips/p9/procedures/hwp/memory/p9_mss_bulk_pwr_throttles.C b/src/import/chips/p9/procedures/hwp/memory/p9_mss_bulk_pwr_throttles.C
index 65d3bd083..77cbacf5d 100644
--- a/src/import/chips/p9/procedures/hwp/memory/p9_mss_bulk_pwr_throttles.C
+++ b/src/import/chips/p9/procedures/hwp/memory/p9_mss_bulk_pwr_throttles.C
@@ -32,7 +32,7 @@
// *HWP Team: Memory
// *HWP Level: 1
// *HWP Consumed by: FSP:HB
-#include <algorithm>
+#include <vector>
#include <mss.H>
#include <fapi2.H>
@@ -62,22 +62,42 @@ extern "C"
throttle_type t)
{
FAPI_INF("Start bulk_pwr_throttles");
-
- FAPI_TRY ( mss::bulk_thermal_throttles (i_targets) );
+//To be implemented in next commit
+#if 0
//Check for THERMAL
if (t == THERMAL)
{
- FAPI_TRY ( mss::bulk_thermal_throttles (i_targets) );
+ for ( const auto& l_mcs : i_targets)
+ {
+ for (const auto& l_mca : mss::find_targets<TARGET_TYPE_MCA>(l_mcs))
+ {
+ //mss::power_thermal::throttle l_pwr_struct(l_mca);
+ //FAPI_TRY (l_pwr_struct.thermal_throttles() );
+ }
+ }
+
+ //Equalize throttles
}
//else do POWER
else
{
- FAPI_TRY ( mss::bulk_power_regulator_throttles (i_targets) );
+ for ( const auto& l_mcs : i_targets)
+ {
+ for (const auto& l_mca : mss::find_targets<TARGET_TYPE_MCA>(l_mcs))
+ {
+ //mss::power_thermal::throttle l_pwr_struct(l_mca);
+ //FAPI_TRY (l_pwr_struct.power_regulator_throttles() );
+ }
+ }
+
+ //Equalize throttles
}
+
FAPI_INF("End bulk_pwr_throttles");
fapi_try_exit:
+#endif
return fapi2::current_err;
}
} //extern C
diff --git a/src/import/chips/p9/procedures/hwp/memory/p9_mss_eff_config_thermal.C b/src/import/chips/p9/procedures/hwp/memory/p9_mss_eff_config_thermal.C
index ec918049c..361c3dbe6 100644
--- a/src/import/chips/p9/procedures/hwp/memory/p9_mss_eff_config_thermal.C
+++ b/src/import/chips/p9/procedures/hwp/memory/p9_mss_eff_config_thermal.C
@@ -27,23 +27,117 @@
/// @file p9_mss_eff_config_thermal.C
/// @brief Perform thermal calculations as part of the effective configuration
///
-// *HWP HWP Owner: Andre Marin <aamarin@us.ibm.com>
+// *HWP HWP Owner: Jacob Harvey <jlharvey@us.ibm.com>
// *HWP HWP Backup: Brian Silver <bsilver@us.ibm.com>
// *HWP Team: Memory
// *HWP Level: 1
// *HWP Consumed by: FSP:HB
#include <fapi2.H>
+#include <vector>
#include <p9_mss_eff_config_thermal.H>
-
+#include <p9_mss_bulk_pwr_throttles.H>
+#include <lib/power_thermal/throttle.H>
+#include <lib/power_thermal/decoder.H>
+#include <lib/dimm/kind.H>
+#include <mss.H>
+extern "C"
+{
///
/// @brief Perform thermal calculations as part of the effective configuration
-/// @param[in] i_target the controller (e.g., MCS)
+/// @param[in] i_targets an array of MCS targets all on the same VDDR domain
/// @return FAPI2_RC_SUCCESS iff ok
///
-fapi2::ReturnCode p9_mss_eff_config_thermal( const fapi2::Target<fapi2::TARGET_TYPE_MCS>& i_target )
-{
- FAPI_INF("Start effective config thermal");
- FAPI_INF("End effective config thermal");
- return fapi2::FAPI2_RC_SUCCESS;
-}
+ fapi2::ReturnCode p9_mss_eff_config_thermal( const std::vector< fapi2::Target<fapi2::TARGET_TYPE_MCS> >& i_targets )
+ {
+
+ FAPI_INF("Start effective config thermal");
+
+ uint16_t l_vddr_slope [mss::PORTS_PER_MCS][mss::MAX_DIMM_PER_PORT] = {};
+ uint16_t l_vddr_int [mss::PORTS_PER_MCS][mss::MAX_DIMM_PER_PORT] = {};
+ uint16_t l_total_slope [mss::PORTS_PER_MCS][mss::MAX_DIMM_PER_PORT] = {};
+ uint16_t l_total_int [mss::PORTS_PER_MCS][mss::MAX_DIMM_PER_PORT] = {};
+ uint32_t l_thermal_power [mss::PORTS_PER_MCS][mss::MAX_DIMM_PER_PORT] = {};
+
+ //Gotta convert into fapi2::buffers. Not very elegant
+ //Do it here or in the encode and decode functions
+ std::vector< uint64_t > l_tslope (mss::SIZE_OF_POWER_CURVES_ATTRS, 0);
+ std::vector< uint64_t > l_tintercept (mss::SIZE_OF_POWER_CURVES_ATTRS, 0);
+ std::vector< uint64_t > l_tthermal_power_limit (mss::SIZE_OF_THERMAL_ATTR, 0);
+
+ std::vector< fapi2::buffer< uint64_t > > l_slope (mss::SIZE_OF_POWER_CURVES_ATTRS);
+ std::vector< fapi2::buffer< uint64_t > > l_intercept (mss::SIZE_OF_POWER_CURVES_ATTRS);
+ std::vector< fapi2::buffer< uint64_t > > l_thermal_power_limit (mss::SIZE_OF_THERMAL_ATTR);
+
+ FAPI_TRY ( mss::mrw_pwr_slope (l_tslope.data() ));
+ FAPI_TRY ( mss::mrw_pwr_intercept (l_tintercept.data()) );
+ FAPI_TRY ( mss::mrw_thermal_memory_power_limit (l_tthermal_power_limit.data()) );
+
+ for (size_t i = 0; i < l_slope.size(); ++i)
+ {
+ l_slope[i] = fapi2::buffer<uint64_t> (l_tslope[i]);
+ l_intercept[i] = fapi2::buffer<uint64_t>(l_tintercept[i]);
+ }
+
+ for ( const auto& l_mcs : i_targets )
+ {
+ FAPI_TRY (mss::power_thermal::get_power_attrs(l_mcs,
+ l_slope,
+ l_intercept,
+ l_thermal_power_limit,
+ l_vddr_slope,
+ l_vddr_int,
+ l_total_slope,
+ l_total_int,
+ l_thermal_power));
+
+ FAPI_TRY( mss::power_thermal::restore_runtime_throttles(l_mcs));
+
+ //Set the power attribute (TOTAL_PWR) to just VDDR for IPL, restoreto vddr+vpp later for OCC
+ //Set here because bulk_pwr_throttles takes input as attributes, and I can't change which attribute it takes
+ //So we have to use TOTAL_PWR_SLOPE
+ //Setting here and not in set_power_attrs because get_power_attrs decodes the attributes and stores them
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_MSS_TOTAL_PWR_SLOPE,
+ l_mcs,
+ l_vddr_slope));
+
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_MSS_TOTAL_PWR_INTERCEPT,
+ l_mcs,
+ l_vddr_int));
+ }
+
+ //get the thermal limits, done per dimm and set to worst case for the slot and port throttles
+ FAPI_TRY (p9_mss_bulk_pwr_throttles(i_targets, THERMAL));
+
+ //Set VDDR+VPP
+ for ( const auto& l_mcs : i_targets )
+ {
+ FAPI_TRY (mss::power_thermal::get_power_attrs(l_mcs,
+ l_slope,
+ l_intercept,
+ l_thermal_power_limit,
+ l_vddr_slope,
+ l_vddr_int,
+ l_total_slope,
+ l_total_int,
+ l_thermal_power));
+
+ FAPI_TRY( mss::power_thermal::restore_runtime_throttles(l_mcs));
+
+ //Set the power attribute (TOTAL_PWR) to just VDDR for IPL, restoreto vddr+vpp later for OCC
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_MSS_TOTAL_PWR_SLOPE,
+ l_mcs,
+ l_total_slope));
+
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_MSS_TOTAL_PWR_INTERCEPT,
+ l_mcs,
+ l_total_int));
+ }
+
+
+ FAPI_INF("End effective config thermal");
+
+ fapi_try_exit:
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+} //extern C
diff --git a/src/import/chips/p9/procedures/hwp/memory/p9_mss_eff_config_thermal.H b/src/import/chips/p9/procedures/hwp/memory/p9_mss_eff_config_thermal.H
index 003454acb..9071f5a1c 100644
--- a/src/import/chips/p9/procedures/hwp/memory/p9_mss_eff_config_thermal.H
+++ b/src/import/chips/p9/procedures/hwp/memory/p9_mss_eff_config_thermal.H
@@ -37,8 +37,9 @@
#define __P9_MSS_EFF_CONFIG_THERMAL__
#include <fapi2.H>
+#include <vector>
-typedef fapi2::ReturnCode (*p9_mss_eff_config_thermal_FP_t) (const fapi2::Target<fapi2::TARGET_TYPE_MCS>&);
+typedef fapi2::ReturnCode (*p9_mss_eff_config_thermal_FP_t) (const std::vector<fapi2::Target<fapi2::TARGET_TYPE_MCS>>&);
extern "C"
{
@@ -48,7 +49,7 @@ extern "C"
/// @param[in] i_target the controller (e.g., MCS)
/// @return FAPI2_RC_SUCCESS iff ok
///
- fapi2::ReturnCode p9_mss_eff_config_thermal( const fapi2::Target<fapi2::TARGET_TYPE_MCS>& i_target );
+ fapi2::ReturnCode p9_mss_eff_config_thermal( const std::vector< fapi2::Target<fapi2::TARGET_TYPE_MCS> >& i_targets );
}
diff --git a/src/import/chips/p9/procedures/hwp/memory/p9_mss_utils_to_throttle.C b/src/import/chips/p9/procedures/hwp/memory/p9_mss_utils_to_throttle.C
index ee980cd92..8809ad0f4 100644
--- a/src/import/chips/p9/procedures/hwp/memory/p9_mss_utils_to_throttle.C
+++ b/src/import/chips/p9/procedures/hwp/memory/p9_mss_utils_to_throttle.C
@@ -85,8 +85,8 @@ extern "C"
l_databus_util );
// Calculate programmable N address operations within M dram clock window
- l_throttled_cmds_port[l_port_num] = mss::throttled_cmds( l_databus_util[l_port_num], l_dram_clocks );
- l_throttled_cmds_slot[l_port_num] = mss::throttled_cmds( l_databus_util[l_port_num], l_dram_clocks );
+ l_throttled_cmds_port[l_port_num] = mss::power_thermal::throttled_cmds( l_databus_util[l_port_num], l_dram_clocks );
+ l_throttled_cmds_slot[l_port_num] = mss::power_thermal::throttled_cmds( l_databus_util[l_port_num], l_dram_clocks );
//TK - actually implement function - JLH
//Quick hard code for API purposes
l_max_power[l_port_num] = 2088;
diff --git a/src/import/chips/p9/procedures/xml/attribute_info/memory_mcs_attributes.xml b/src/import/chips/p9/procedures/xml/attribute_info/memory_mcs_attributes.xml
index 155a02270..8d5776543 100644
--- a/src/import/chips/p9/procedures/xml/attribute_info/memory_mcs_attributes.xml
+++ b/src/import/chips/p9/procedures/xml/attribute_info/memory_mcs_attributes.xml
@@ -1128,18 +1128,6 @@
</attribute>
<attribute>
- <id>ATTR_EFF_NUM_DROPS_PER_PORT</id>
- <targetType>TARGET_TYPE_MCS</targetType>
- <description>Specifies the number of DIMM dimensions that are valid per port. </description>
- <initToZero></initToZero>
- <valueType>uint8</valueType>
- <enum>EMPTY = 0, SINGLE = 1, DUAL = 2</enum>
- <writeable/>
- <array>2</array>
- <mssAccessorName>eff_num_drops_per_port</mssAccessorName>
- </attribute>
-
- <attribute>
<id>ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM</id>
<targetType>TARGET_TYPE_MCS</targetType>
<description>Specifies the number of master ranks per DIMM.</description>
@@ -1255,7 +1243,7 @@
consumer: mss_bulk_pwr_throttles
</description>
<initToZero></initToZero>
- <valueType>uint32</valueType>
+ <valueType>uint16</valueType>
<writeable/>
<array> 2 2</array>
<mssAccessorName>total_pwr_slope</mssAccessorName>
@@ -1270,57 +1258,13 @@
consumer: mss_bulk_pwr_throttles
</description>
<initToZero></initToZero>
- <valueType>uint32</valueType>
+ <valueType>uint16</valueType>
<writeable/>
<array> 2 2</array>
<mssAccessorName>total_pwr_intercept</mssAccessorName>
</attribute>
<attribute>
- <id>ATTR_MSS_MASTER_PWR_SLOPE</id>
- <targetType>TARGET_TYPE_MCS</targetType>
- <description>Master Power slope value for dimm</description>
- <initToZero></initToZero>
- <valueType>uint32</valueType>
- <writeable/>
- <array> 2 2</array>
- <mssAccessorName>master_pwr_slope</mssAccessorName>
- </attribute>
-
- <attribute>
- <id>ATTR_MSS_SUPPLIER_PWR_SLOPE</id>
- <targetType>TARGET_TYPE_MCS</targetType>
- <description>Supplier Power slope value for dimm</description>
- <initToZero></initToZero>
- <valueType>uint32</valueType>
- <writeable/>
- <array> 2 2</array>
- <mssAccessorName>supplier_pwr_slope</mssAccessorName>
- </attribute>
-
- <attribute>
- <id>ATTR_MSS_MASTER_PWR_INTERCEPT</id>
- <targetType>TARGET_TYPE_MCS</targetType>
- <description>Master Power intercept value for dimm</description>
- <initToZero></initToZero>
- <valueType>uint32</valueType>
- <writeable/>
- <array> 2 2</array>
- <mssAccessorName>master_pwr_intercept</mssAccessorName>
- </attribute>
-
- <attribute>
- <id>ATTR_MSS_SUPPLIER_PWR_INTERCEPT</id>
- <targetType>TARGET_TYPE_MCS</targetType>
- <description>Supplier Power intercept value for dimm</description>
- <initToZero></initToZero>
- <valueType>uint32</valueType>
- <writeable/>
- <array> 2 2</array>
- <mssAccessorName>supplier_pwr_intercept</mssAccessorName>
- </attribute>
-
- <attribute>
<id>ATTR_MSS_DIMM_MAXBANDWIDTH_GBS</id>
<targetType>TARGET_TYPE_MCS</targetType>
<description>DIMM Max Bandwidth in GBs output from thermal procedures</description>
diff --git a/src/import/chips/p9/procedures/xml/attribute_info/memory_mrw_attributes.xml b/src/import/chips/p9/procedures/xml/attribute_info/memory_mrw_attributes.xml
index 6c35ef2ac..f4737af85 100755
--- a/src/import/chips/p9/procedures/xml/attribute_info/memory_mrw_attributes.xml
+++ b/src/import/chips/p9/procedures/xml/attribute_info/memory_mrw_attributes.xml
@@ -67,7 +67,7 @@
</description>
<valueType>uint64</valueType>
<mssUnits>cW</mssUnits>
- <default>ffffe0001700</default>
+ <default>ffffe000000006A4</default>
<array>10</array>
<platInit/>
<initToZero/>
@@ -247,7 +247,7 @@
<targetType>TARGET_TYPE_SYSTEM</targetType>
<description>
Memory power control settings programmed during IPL
- Used by OCC when exiting idle powersave mode
+ Used by OCC when exiting idle power-save mode
</description>
<valueType>uint8</valueType>
<enum>OFF = 0x00, POWER_DOWN = 0x01, STR = 0x02, PD_AND_STR = 0x03</enum>
@@ -263,7 +263,7 @@
<targetType>TARGET_TYPE_SYSTEM</targetType>
<description>
Memory power control settings for IDLE powersave mode
- Used by OCC when entering idle powersave mode
+ Used by OCC when entering idle power-save mode
</description>
<valueType>uint8</valueType>
<enum>OFF = 0x00, POWER_DOWN = 0x01, STR = 0x02, PD_AND_STR = 0x03</enum>
diff --git a/src/import/chips/p9/procedures/xml/error_info/p9_memory_mss_eff_config.xml b/src/import/chips/p9/procedures/xml/error_info/p9_memory_mss_eff_config.xml
index 95adb0067..12336a55b 100644
--- a/src/import/chips/p9/procedures/xml/error_info/p9_memory_mss_eff_config.xml
+++ b/src/import/chips/p9/procedures/xml/error_info/p9_memory_mss_eff_config.xml
@@ -145,4 +145,36 @@
</deconfigure>
</hwpError>
+ <hwpError>
+ <rc>RC_MSS_NO_DATABUS_UTILIZATION</rc>
+ <description>
+ There are 2 DIMMS on the port but both have 0 databus utilization
+ </description>
+ <ffdc>PORT_DATABUS_UTIL</ffdc>
+ <callout>
+ <target>MCA_TARGET</target>
+ <priority>HIGH</priority>
+ </callout>
+ <deconfigure>
+ <target>MCA_TARGET</target>
+ </deconfigure>
+ </hwpError>
+
+ <hwpError>
+ <rc>RC_MSS_CALC_PORT_POWER_CURVE_DIVIDE_BY_ZERO</rc>
+ <description>
+ Denominator equals 0
+ </description>
+ <ffdc>PORT_DATABUS_UTIL</ffdc>
+ <ffdc>UTIL_CONVERSION</ffdc>
+ <ffdc>IDLE_UTIL</ffdc>
+ <callout>
+ <target>MCA_TARGET</target>
+ <priority>HIGH</priority>
+ </callout>
+ <deconfigure>
+ <target>MCA_TARGET</target>
+ </deconfigure>
+ </hwpError>
+
</hwpErrors>
OpenPOWER on IntegriCloud