Skip to content

Commit

Permalink
powercap: occ: Fix the powercapping range allowed for user
Browse files Browse the repository at this point in the history
[ Upstream commit a96739c ]

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: c6aabe3("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>
Signed-off-by: Vasant Hegde <hegdevasant@linux.vnet.ibm.com>
  • Loading branch information
shilpasri authored and Vasant Hegde committed Mar 4, 2019
1 parent 6e7145a commit 0fe8ecd
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 9 deletions.
9 changes: 8 additions & 1 deletion doc/device-tree/ibm,opal/power-mgt/powercap.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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 |
Expand All @@ -44,6 +50,7 @@ the future.
powercap-current = <0x00000002>;
powercap-min = <0x00000000>;
powercap-max = <0x00000001>;
powercap-hard-min = <0x000000003>;
};
};
};
30 changes: 22 additions & 8 deletions hw/occ.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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;
Expand Down Expand Up @@ -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)
Expand All @@ -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)
Expand All @@ -1371,15 +1382,18 @@ 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;
break;
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;
Expand Down Expand Up @@ -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;
Expand Down

0 comments on commit 0fe8ecd

Please sign in to comment.