[Skiboot] [PATCH V7 3/8] occ: Add support to change power-shifting-ratio
Shilpasri G Bhat
shilpa.bhat at linux.vnet.ibm.com
Thu Jul 20 04:22:36 AEST 2017
Add support to set the CPU-GPU power shifting ratio which is used by
the OCC power capping algorithm. PSR value of 100 takes all power away
from CPU first and a PSR value of 0 caps GPU first.
Signed-off-by: Shilpasri G Bhat <shilpa.bhat at linux.vnet.ibm.com>
---
hw/occ.c | 96 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
include/opal-api.h | 4 ++-
2 files changed, 99 insertions(+), 1 deletion(-)
diff --git a/hw/occ.c b/hw/occ.c
index d166fe5..907cf6e 100644
--- a/hw/occ.c
+++ b/hw/occ.c
@@ -1217,6 +1217,7 @@ exit:
}
static void occ_add_powercap_sensors(struct dt_node *power_mgt);
+static void occ_add_psr_sensors(struct dt_node *power_mgt);
static void occ_cmd_interface_init(void)
{
@@ -1262,6 +1263,9 @@ static void occ_cmd_interface_init(void)
/* Add powercap sensors to DT */
occ_add_powercap_sensors(power_mgt);
+
+ /* Add power-shifting-ratio CPU-GPU sensors to DT */
+ occ_add_psr_sensors(power_mgt);
}
/* Powercap interface */
@@ -1362,6 +1366,98 @@ int occ_set_powercap(int token, u32 pcap)
return opal_occ_command(&chips[i], token, &pcap_data);
};
+/* Power-Shifting Ratio */
+enum psr_type {
+ PSR_TYPE_CPU_TO_GPU, /* 0% Cap GPU first, 100% Cap CPU first */
+};
+
+static int opal_get_power_shifting_ratio(u32 handle, int token __unused,
+ int *ratio)
+{
+ struct occ_dynamic_data *ddata;
+ struct proc_chip *chip;
+ int type = (handle >> 24) & 0xF;
+ int i = handle & 0xF;
+
+ if (type != PSR_TYPE_CPU_TO_GPU)
+ return OPAL_UNSUPPORTED;
+
+ if (i > nr_occs || i < 0)
+ return OPAL_PARAMETER;
+
+ if (!(*chips[i].valid))
+ return OPAL_WRONG_STATE;
+
+ chip = get_chip(chips[i].chip_id);
+ ddata = get_occ_dynamic_data(chip);
+ *ratio = ddata->pwr_shifting_ratio;
+ return OPAL_SUCCESS;
+}
+
+static u8 psr_cdata;
+static struct opal_occ_cmd_data psr_data = {
+ .data = &psr_cdata,
+ .cmd = OCC_CMD_SET_POWER_SHIFTING_RATIO,
+};
+
+static int opal_set_power_shifting_ratio(u32 handle, int token, int ratio)
+{
+ struct occ_dynamic_data *ddata;
+ struct proc_chip *chip;
+ int type = (handle >> 24) & 0xF;
+ int i = handle & 0xF;
+
+ if (type != PSR_TYPE_CPU_TO_GPU)
+ return OPAL_UNSUPPORTED;
+
+ if (ratio < 0 || ratio > 100)
+ return OPAL_PARAMETER;
+
+ if (i > nr_occs || i < 0)
+ return OPAL_PARAMETER;
+
+ if (!(*chips[i].valid))
+ return OPAL_WRONG_STATE;
+
+ chip = get_chip(chips[i].chip_id);
+ ddata = get_occ_dynamic_data(chip);
+ if (ratio == ddata->pwr_shifting_ratio)
+ return OPAL_SUCCESS;
+
+ psr_cdata = ratio;
+ return opal_occ_command(&chips[i], token, &psr_data);
+}
+
+static void occ_add_psr_sensors(struct dt_node *power_mgt)
+{
+ struct dt_node *node, *cnode;
+ int i;
+
+ node = dt_new(power_mgt, "psr");
+ if (!node) {
+ prerror("OCC: Failed to create power-shifting-ratio node\n");
+ return;
+ }
+
+ for (i = 0; i < nr_occs; i++) {
+ char name[20];
+ u32 handle = (PSR_TYPE_CPU_TO_GPU << 24) | i;
+
+ cnode = dt_new_addr(node, "cpu-to-gpu", handle);
+ if (!cnode) {
+ prerror("OCC: Failed to create power-shifting-ratio node\n");
+ return;
+ }
+
+ snprintf(name, 20, "cpu_to_gpu_%d", chips[i].chip_id);
+ dt_add_property_string(cnode, "label", name);
+ dt_add_property_cells(cnode, "handle", handle);
+ }
+
+ opal_register(OPAL_GET_PSR, opal_get_power_shifting_ratio, 3);
+ opal_register(OPAL_SET_PSR, opal_set_power_shifting_ratio, 3);
+}
+
/* CPU-OCC PState init */
/* Called after OCC init on P8 and P9 */
void occ_pstates_init(void)
diff --git a/include/opal-api.h b/include/opal-api.h
index 3ad4898..2717a0d 100644
--- a/include/opal-api.h
+++ b/include/opal-api.h
@@ -210,7 +210,9 @@
#define OPAL_IMC_COUNTERS_STOP 151
#define OPAL_GET_POWERCAP 152
#define OPAL_SET_POWERCAP 153
-#define OPAL_LAST 153
+#define OPAL_GET_PSR 154
+#define OPAL_SET_PSR 155
+#define OPAL_LAST 155
/* Device tree flags */
--
1.8.3.1
More information about the Skiboot
mailing list