[Skiboot] [PATCH V6 3/3] occ: Add support to change power-shifting-ratio

Shilpasri G Bhat shilpa.bhat at linux.vnet.ibm.com
Wed Jul 19 08:01:32 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           | 108 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 include/opal-api.h |   4 +-
 2 files changed, 111 insertions(+), 1 deletion(-)

diff --git a/hw/occ.c b/hw/occ.c
index 24ead8e..74094b6 100644
--- a/hw/occ.c
+++ b/hw/occ.c
@@ -1194,6 +1194,7 @@ exit:
 }
 
 static void occ_add_powercap_sensors(void);
+static void occ_add_psr_sensors(void);
 
 static void occ_cmd_interface_init(void)
 {
@@ -1229,6 +1230,7 @@ static void occ_cmd_interface_init(void)
 		i++;
 	}
 	occ_add_powercap_sensors();
+	occ_add_psr_sensors();
 }
 
 /* Powercap interface */
@@ -1340,6 +1342,112 @@ 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_pstate_table *pdata;
+	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;
+
+	chip = get_chip(chips[i].chip_id);
+	pdata = get_occ_pstate_table(chip);
+	if (!pdata->valid)
+		return OPAL_BUSY;
+
+	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_pstate_table *pdata;
+	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;
+
+	chip = next_chip(NULL);
+	pdata = get_occ_pstate_table(chip);
+	if (!pdata->valid)
+		return OPAL_BUSY;
+
+	if (!(PPC_BIT16(*chips[i].occ_state) &
+	    occ_cmds[psr_data.cmd].state_mask))
+		return OPAL_WRONG_STATE;
+
+	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(void)
+{
+	struct dt_node *node, *cnode, *power_mgt;
+	int i;
+
+	power_mgt = dt_find_by_path(dt_root, "/ibm,opal/power-mgt");
+	if (!power_mgt) {
+		prerror("OCC: dt node /ibm,opal/power-mgt not found\n");
+		return;
+	}
+
+	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