[Skiboot] [PATCH v3] powercap: occ: Fix the powercapping range allowed for user

Shilpasri G Bhat shilpa.bhat at linux.vnet.ibm.com
Tue Feb 5 16:14:52 AEDT 2019


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 at linux.vnet.ibm.com>
---
Changes from V2:
- As per Vaidy's suggestion change powercap-min to point to
  soft-powercap min limit instead of hard-powercap as min and max
  should point to the absolute possible range.

 doc/device-tree/ibm,opal/power-mgt/powercap.rst |  9 +++++++-
 hw/occ.c                                        | 30 ++++++++++++++++++-------
 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;
-- 
1.8.3.1



More information about the Skiboot mailing list