zynqmp: pm: Implemented 'get_op_characteristic' PM API call

Signed-off-by: Anes Hadziahmetagic <anes.hadziahmetagic@aggios.com>
Signed-off-by: Filip Drazic <filip.drazic@aggios.com>
Signed-off-by: Soren Brinkmann <soren.brinkmann@xilinx.com>
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_sys.c b/plat/xilinx/zynqmp/pm_service/pm_api_sys.c
index 053281e..5af0163 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_api_sys.c
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_sys.c
@@ -395,17 +395,25 @@
 }
 
 /**
- * pm_get_op_characteristic() - PM call to get a particular operating
- *				characteristic of a node
- * @nid	Node ID
- * @type	Operating characterstic type to be returned
+ * pm_get_op_characteristic() - PM call to request operating characteristics
+ *				of a node
+ * @nid		Node id of the slave
+ * @type	Type of the operating characteristic
+ *		(power, temperature and latency)
+ * @result	Returns the operating characteristic for the requested node,
+ *		specified by the type
  *
  * @return	Returns status, either success or error+reason
  */
 enum pm_ret_status pm_get_op_characteristic(enum pm_node_id nid,
-					    enum pm_opchar_type type)
+					    enum pm_opchar_type type,
+					    uint32_t *result)
 {
-	return PM_RET_ERROR_NOTSUPPORTED;
+	uint32_t payload[PAYLOAD_ARG_CNT];
+
+	/* Send request to the PMU */
+	PM_PACK_PAYLOAD3(payload, PM_GET_OP_CHARACTERISTIC, nid, type);
+	return pm_ipi_send_sync(primary_proc, payload, result);
 }
 
 /* Direct-Control API functions */
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_sys.h b/plat/xilinx/zynqmp/pm_service/pm_api_sys.h
index f0365cd..22bdb47 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_api_sys.h
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_sys.h
@@ -91,7 +91,8 @@
 					unsigned int wake,
 					unsigned int enable);
 enum pm_ret_status pm_get_op_characteristic(enum pm_node_id nid,
-					    enum pm_opchar_type type);
+					    enum pm_opchar_type type,
+					    uint32_t *result);
 enum pm_ret_status pm_acknowledge_cb(enum pm_node_id nid,
 				     enum pm_ret_status status,
 				     unsigned int oppoint);
diff --git a/plat/xilinx/zynqmp/pm_service/pm_defs.h b/plat/xilinx/zynqmp/pm_service/pm_defs.h
index 08f4aab..2fd05fe 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_defs.h
+++ b/plat/xilinx/zynqmp/pm_service/pm_defs.h
@@ -171,8 +171,8 @@
 
 enum pm_opchar_type {
 	PM_OPCHAR_TYPE_POWER = 1,
-	PM_OPCHAR_TYPE_ENERGY,
 	PM_OPCHAR_TYPE_TEMP,
+	PM_OPCHAR_TYPE_LATENCY,
 };
 
 /**
diff --git a/plat/xilinx/zynqmp/pm_service/pm_svc_main.c b/plat/xilinx/zynqmp/pm_service/pm_svc_main.c
index 6744065..e3c25c3 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_svc_main.c
+++ b/plat/xilinx/zynqmp/pm_service/pm_svc_main.c
@@ -191,8 +191,12 @@
 		SMC_RET1(handle, (uint64_t)ret);
 
 	case PM_GET_OP_CHARACTERISTIC:
-		ret = pm_get_op_characteristic(pm_arg[0], pm_arg[1]);
-		SMC_RET1(handle, (uint64_t)ret);
+	{
+		uint32_t result;
+
+		ret = pm_get_op_characteristic(pm_arg[0], pm_arg[1], &result);
+		SMC_RET1(handle, (uint64_t)ret | ((uint64_t)result << 32));
+	}
 
 	case PM_REGISTER_NOTIFIER:
 		ret = pm_register_notifier(pm_arg[0], pm_arg[1], pm_arg[2],