xilinx: versal: Add support for PM_GET_OPERATING_CHARACTERISTIC EEMI call

This patch adds EEMI support for PM_GET_OPERATING_CHARACTERISTIC api id.  This
interface obtains operating characteristic of a device from PMC firmware.  The
'power', 'temperature', and 'latency' characteristic are the options that are
supported.

Signed-off-by: Saeed Nowshadi <saeed.nowshadi@xilinx.com>
Signed-off-by: Jolly Shah <jolly.shah@xilinx.com>
Change-Id: If30959ba6a3a778a17df2a4281c2c09832cf7e92
diff --git a/plat/xilinx/versal/pm_service/pm_api_sys.c b/plat/xilinx/versal/pm_service/pm_api_sys.c
index a4c0b28..dbe94e6 100644
--- a/plat/xilinx/versal/pm_service/pm_api_sys.c
+++ b/plat/xilinx/versal/pm_service/pm_api_sys.c
@@ -785,6 +785,7 @@
 		return PM_RET_SUCCESS;
 	case PM_GET_API_VERSION:
 	case PM_GET_DEVICE_STATUS:
+	case PM_GET_OP_CHARACTERISTIC:
 	case PM_REQ_SUSPEND:
 	case PM_SELF_SUSPEND:
 	case PM_FORCE_POWERDOWN:
@@ -859,3 +860,26 @@
 			 address_high, address_low);
 	return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
 }
+
+/**
+ * pm_get_op_characteristic() - PM call to request operating characteristics
+ *                              of a device
+ * @device_id   Device id
+ * @type        Type of the operating characteristic
+ *              (power, temperature and latency)
+ * @result      Returns the operating characteristic for the requested device,
+ *              specified by the type
+ *
+ * @return      Returns status, either success or error+reason
+ */
+enum pm_ret_status pm_get_op_characteristic(uint32_t device_id,
+					    enum pm_opchar_type type,
+					    uint32_t *result)
+{
+	uint32_t payload[PAYLOAD_ARG_CNT];
+
+	/* Send request to the PMC */
+	PM_PACK_PAYLOAD3(payload, LIBPM_MODULE_ID, PM_GET_OP_CHARACTERISTIC,
+			 device_id, type);
+	return pm_ipi_send_sync(primary_proc, payload, result, 1);
+}
diff --git a/plat/xilinx/versal/pm_service/pm_api_sys.h b/plat/xilinx/versal/pm_service/pm_api_sys.h
index 995c49e..4de592a 100644
--- a/plat/xilinx/versal/pm_service/pm_api_sys.h
+++ b/plat/xilinx/versal/pm_service/pm_api_sys.h
@@ -69,4 +69,7 @@
 enum pm_ret_status pm_feature_check(uint32_t api_id, unsigned int *version);
 enum pm_ret_status pm_load_pdi(uint32_t src, uint32_t address_low,
 			       uint32_t address_high);
+enum pm_ret_status pm_get_op_characteristic(uint32_t device_id,
+					    enum pm_opchar_type type,
+					    uint32_t *result);
 #endif /* PM_API_SYS_H */
diff --git a/plat/xilinx/versal/pm_service/pm_defs.h b/plat/xilinx/versal/pm_service/pm_defs.h
index 7d4066b..966b00b 100644
--- a/plat/xilinx/versal/pm_service/pm_defs.h
+++ b/plat/xilinx/versal/pm_service/pm_defs.h
@@ -42,6 +42,7 @@
 /* PM API ids */
 #define PM_GET_API_VERSION		1U
 #define PM_GET_DEVICE_STATUS		3U
+#define PM_GET_OP_CHARACTERISTIC	4U
 #define PM_REQ_SUSPEND			6U
 #define PM_SELF_SUSPEND			7U
 #define PM_FORCE_POWERDOWN		8U
@@ -112,6 +113,12 @@
 	ABORT_REASON_UNKNOWN,
 };
 
+enum pm_opchar_type {
+	PM_OPCHAR_TYPE_POWER = 1,
+	PM_OPCHAR_TYPE_TEMP,
+	PM_OPCHAR_TYPE_LATENCY,
+};
+
 /**
  * Subsystem IDs
  */
diff --git a/plat/xilinx/versal/pm_service/pm_svc_main.c b/plat/xilinx/versal/pm_service/pm_svc_main.c
index d246013..a3a9f43 100644
--- a/plat/xilinx/versal/pm_service/pm_svc_main.c
+++ b/plat/xilinx/versal/pm_service/pm_svc_main.c
@@ -313,6 +313,14 @@
 		SMC_RET1(handle, (uint64_t)ret);
 	}
 
+	case PM_GET_OP_CHARACTERISTIC:
+	{
+		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));
+	}
+
 	default:
 		WARN("Unimplemented PM Service Call: 0x%x\n", smc_fid);
 		SMC_RET1(handle, SMC_UNK);