aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShilpasri G Bhat <shilpa.bhat@linux.vnet.ibm.com>2019-02-05 10:44:52 +0530
committerStewart Smith <stewart@linux.ibm.com>2019-02-25 21:59:03 -0600
commita96739c6c1cdf02521cab703733cef8cb54debbf (patch)
tree098109515c234dfedadde3a67ec47b98aafdaa7b
parent3b8b7e8c4e7880f992092856ae25d4bd3d53126b (diff)
downloadskiboot-a96739c6c1cdf02521cab703733cef8cb54debbf.zip
skiboot-a96739c6c1cdf02521cab703733cef8cb54debbf.tar.gz
skiboot-a96739c6c1cdf02521cab703733cef8cb54debbf.tar.bz2
powercap: occ: Fix the powercapping range allowed for user
OCC provides two limits for minimum powercap. One being hard powercap minimum which is guaranteed by OCC and the other one is a soft powercap minimum which is lesser than hard-min and may or may not be asserted due to various power-thermal reasons. So to allow the users to access the entire powercap range, this patch exports soft powercap minimum as the "powercap-min" DT property. And it also adds a new DT property called "powercap-hard-min" to export the hard-min powercap limit. Fixes: c6aabe3f2eb5("powercap: occ: Add a generic powercap framework") Signed-off-by: Shilpasri G Bhat <shilpa.bhat@linux.vnet.ibm.com> Reviewed-by: Vaidyanathan Srinivasan <svaidy@linux.vnet.ibm.com> Signed-off-by: Stewart Smith <stewart@linux.ibm.com>
-rw-r--r--doc/device-tree/ibm,opal/power-mgt/powercap.rst9
-rw-r--r--hw/occ.c30
2 files changed, 30 insertions, 9 deletions
diff --git a/doc/device-tree/ibm,opal/power-mgt/powercap.rst b/doc/device-tree/ibm,opal/power-mgt/powercap.rst
index 5a8d007..5d24ee1 100644
--- a/doc/device-tree/ibm,opal/power-mgt/powercap.rst
+++ b/doc/device-tree/ibm,opal/power-mgt/powercap.rst
@@ -20,11 +20,17 @@ Each child node has below properties:
Handle to indicate the current powercap
`powercap-min`
- Minimum possible powercap
+ Absolute minimum possible powercap. This points to the soft powercap minimum
+ limit as exported by OCC. The powercap set in the soft powercap range may or
+ may not be maintained.
`powercap-max`
Maximum possible powercap
+`powercap-hard-min`
+ This value points to the hard minimum powercap limit. The powercap set above
+ this limit is guaranteed unless there is a hardware failure
+
Powercap handle uses the following encoding: ::
| Class | Reserved | Attribute |
@@ -44,6 +50,7 @@ the future.
powercap-current = <0x00000002>;
powercap-min = <0x00000000>;
powercap-max = <0x00000001>;
+ powercap-hard-min = <0x000000003>;
};
};
};
diff --git a/hw/occ.c b/hw/occ.c
index 9580bb8..e290937 100644
--- a/hw/occ.c
+++ b/hw/occ.c
@@ -225,9 +225,12 @@ struct occ_response_buffer {
* power to maintain a power cap. Value of 100
* means take all power from CPU.
* @pwr_cap_type: Indicates type of power cap in effect
- * @min_pwr_cap: Minimum allowed system power cap in Watts
+ * @hard_min_pwr_cap: Hard minimum system power cap in Watts.
+ * Guaranteed unless hardware failure
* @max_pwr_cap: Maximum allowed system power cap in Watts
* @cur_pwr_cap: Current system power cap
+ * @soft_min_pwr_cap: Soft powercap minimum. OCC may or may not be
+ * able to maintain this
* @spare/reserved: Unused data
* @cmd: Opal Command Buffer
* @rsp: OCC Response Buffer
@@ -243,10 +246,11 @@ struct occ_dynamic_data {
u8 quick_pwr_drop;
u8 pwr_shifting_ratio;
u8 pwr_cap_type;
- u16 min_pwr_cap;
+ u16 hard_min_pwr_cap;
u16 max_pwr_cap;
u16 cur_pwr_cap;
- u8 pad[112];
+ u16 soft_min_pwr_cap;
+ u8 pad[110];
struct opal_command_buffer cmd;
struct occ_response_buffer rsp;
} __packed;
@@ -1324,9 +1328,10 @@ static void occ_cmd_interface_init(void)
/* Powercap interface */
enum sensor_powercap_occ_attr {
- POWERCAP_OCC_MIN,
+ POWERCAP_OCC_SOFT_MIN,
POWERCAP_OCC_MAX,
POWERCAP_OCC_CUR,
+ POWERCAP_OCC_HARD_MIN,
};
static void occ_add_powercap_sensors(struct dt_node *power_mgt)
@@ -1350,11 +1355,17 @@ static void occ_add_powercap_sensors(struct dt_node *power_mgt)
handle = powercap_make_handle(POWERCAP_CLASS_OCC, POWERCAP_OCC_CUR);
dt_add_property_cells(node, "powercap-current", handle);
- handle = powercap_make_handle(POWERCAP_CLASS_OCC, POWERCAP_OCC_MIN);
+ handle = powercap_make_handle(POWERCAP_CLASS_OCC,
+ POWERCAP_OCC_SOFT_MIN);
dt_add_property_cells(node, "powercap-min", handle);
handle = powercap_make_handle(POWERCAP_CLASS_OCC, POWERCAP_OCC_MAX);
dt_add_property_cells(node, "powercap-max", handle);
+
+ handle = powercap_make_handle(POWERCAP_CLASS_OCC,
+ POWERCAP_OCC_HARD_MIN);
+ dt_add_property_cells(node, "powercap-hard-min", handle);
+
}
int occ_get_powercap(u32 handle, u32 *pcap)
@@ -1371,8 +1382,8 @@ int occ_get_powercap(u32 handle, u32 *pcap)
return OPAL_HARDWARE;
switch (powercap_get_attr(handle)) {
- case POWERCAP_OCC_MIN:
- *pcap = ddata->min_pwr_cap;
+ case POWERCAP_OCC_SOFT_MIN:
+ *pcap = ddata->soft_min_pwr_cap;
break;
case POWERCAP_OCC_MAX:
*pcap = ddata->max_pwr_cap;
@@ -1380,6 +1391,9 @@ int occ_get_powercap(u32 handle, u32 *pcap)
case POWERCAP_OCC_CUR:
*pcap = ddata->cur_pwr_cap;
break;
+ case POWERCAP_OCC_HARD_MIN:
+ *pcap = ddata->hard_min_pwr_cap;
+ break;
default:
*pcap = 0;
return OPAL_UNSUPPORTED;
@@ -1420,7 +1434,7 @@ int occ_set_powercap(u32 handle, int token, u32 pcap)
return OPAL_SUCCESS;
if (pcap && (pcap > ddata->max_pwr_cap ||
- pcap < ddata->min_pwr_cap))
+ pcap < ddata->soft_min_pwr_cap))
return OPAL_PARAMETER;
pcap_cdata = pcap;