[v2] powercap: occ: Fix the powercapping range allowed for user

Message ID 1538460041-16473-1-git-send-email-shilpa.bhat@linux.vnet.ibm.com
State New
Headers show
Series
  • [v2] powercap: occ: Fix the powercapping range allowed for user
Related show

Checks

Context Check Description
snowpatch_ozlabs/make_check success Test make_check on branch master
snowpatch_ozlabs/apply_patch success master/apply_patch Successfully applied

Commit Message

Shilpasri G Bhat Oct. 2, 2018, 6 a.m.
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 may or may not be asserted due to various
power-thermal reasons. This patch exports the soft-min powercap via
device tree and "powercap-min" DT property will be continued to be
used as hard powercap minimum.

Fixes: c6aabe3f2eb5("powercap: occ: Add a generic powercap framework")
Signed-off-by: Shilpasri G Bhat <shilpa.bhat@linux.vnet.ibm.com>
---
 doc/device-tree/ibm,opal/power-mgt/powercap.rst |  6 +++++-
 hw/occ.c                                        | 23 ++++++++++++++++++-----
 2 files changed, 23 insertions(+), 6 deletions(-)

Patch

diff --git a/doc/device-tree/ibm,opal/power-mgt/powercap.rst b/doc/device-tree/ibm,opal/power-mgt/powercap.rst
index 5a8d007..89362ba 100644
--- a/doc/device-tree/ibm,opal/power-mgt/powercap.rst
+++ b/doc/device-tree/ibm,opal/power-mgt/powercap.rst
@@ -20,11 +20,14 @@  Each child node has below properties:
   Handle to indicate the current powercap
 
 `powercap-min`
-  Minimum possible powercap
+  Guaranteed hard min powercap unless there is a hardware failure
 
 `powercap-max`
   Maximum possible powercap
 
+`powercap-soft-min`
+  Minimum possible powercap which may or may not be maintained
+
 Powercap handle uses the following encoding: ::
 
         | Class |    Reserved   | Attribute |
@@ -44,6 +47,7 @@  the future.
                 powercap-current = <0x00000002>;
                 powercap-min = <0x00000000>;
                 powercap-max = <0x00000001>;
+                powercap-soft-min = <0x000000003>;
         };
      };
     };
diff --git a/hw/occ.c b/hw/occ.c
index 9580bb8..56b4428 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;
@@ -1327,6 +1331,7 @@  enum sensor_powercap_occ_attr {
 	POWERCAP_OCC_MIN,
 	POWERCAP_OCC_MAX,
 	POWERCAP_OCC_CUR,
+	POWERCAP_OCC_SOFT_MIN,
 };
 
 static void occ_add_powercap_sensors(struct dt_node *power_mgt)
@@ -1355,6 +1360,11 @@  static void occ_add_powercap_sensors(struct dt_node *power_mgt)
 
 	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_SOFT_MIN);
+	dt_add_property_cells(node, "powercap-soft-min", handle);
+
 }
 
 int occ_get_powercap(u32 handle, u32 *pcap)
@@ -1372,7 +1382,7 @@  int occ_get_powercap(u32 handle, u32 *pcap)
 
 	switch (powercap_get_attr(handle)) {
 	case POWERCAP_OCC_MIN:
-		*pcap = ddata->min_pwr_cap;
+		*pcap = ddata->hard_min_pwr_cap;
 		break;
 	case POWERCAP_OCC_MAX:
 		*pcap = ddata->max_pwr_cap;
@@ -1380,6 +1390,9 @@  int occ_get_powercap(u32 handle, u32 *pcap)
 	case POWERCAP_OCC_CUR:
 		*pcap = ddata->cur_pwr_cap;
 		break;
+	case POWERCAP_OCC_SOFT_MIN:
+		*pcap = ddata->soft_min_pwr_cap;
+		break;
 	default:
 		*pcap = 0;
 		return OPAL_UNSUPPORTED;
@@ -1420,7 +1433,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;