feat(plat/xilinx/zynqmp): add support for runtime feature config

Add support for runtime feature configuration which are running on the
 firmware. Add new IOCTL IDs like IOCTL_SET_FEATURE_CONFIG and
 IOCTL_GET_FEATURE_CONFIG for configuring the features.

Signed-off-by: Ronak Jain <ronak.jain@xilinx.com>
Change-Id: I976aef15932783a25396b2adeb4c8f140cc87e79
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c b/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c
index f165fb0..9c5af88 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c
@@ -677,6 +677,10 @@
 	case IOCTL_AFI:
 		ret = pm_ioctl_afi(arg1, arg2);
 		break;
+	case IOCTL_SET_FEATURE_CONFIG:
+	case IOCTL_GET_FEATURE_CONFIG:
+		ret = pm_feature_config(ioctl_id, arg1, arg2, value);
+		break;
 	default:
 		ret = PM_RET_ERROR_NOTSUPPORTED;
 		break;
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.h b/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.h
index 7f96861..f18dc00 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.h
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.h
@@ -49,6 +49,9 @@
 	IOCTL_AIE_ISR_CLEAR = 24,
 	/* Register SGI to ATF */
 	IOCTL_REGISTER_SGI = 25,
+	/* Runtime feature configuration */
+	IOCTL_SET_FEATURE_CONFIG = 26,
+	IOCTL_GET_FEATURE_CONFIG = 27,
 };
 
 //RPU operation mode
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_sys.c b/plat/xilinx/zynqmp/pm_service/pm_api_sys.c
index 62260bc..5d9408c 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_api_sys.c
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_sys.c
@@ -1648,3 +1648,36 @@
 	EM_PACK_PAYLOAD1(payload, EM_SEND_ERRORS);
 	return pm_ipi_send_sync(primary_proc, payload, value, 1);
 }
+
+/**
+ * pm_feature_config() - feature configuration at runtime
+ *
+ * This function is used to send IPI request to PMUFW to configure feature
+ * at runtime. The feature can be enable or disable as well as the feature
+ * can be configure at runtime using an IOCTL call.
+ *
+ * @ioctl_id	The ioctl id for the feature configuration
+ * @config_id	The config id of the feature to be configured
+ * @value	The value to be configured
+ * @response	Return to reference pointer
+ *
+ * @return      Returns 0 on success or error value on failure
+ */
+enum pm_ret_status pm_feature_config(unsigned int ioctl_id,
+				     unsigned int config_id,
+				     unsigned int value,
+				     unsigned int *response)
+{
+	uint32_t payload[PAYLOAD_ARG_CNT];
+
+	/* Send request to the PMU */
+	PM_PACK_PAYLOAD5(payload, PM_IOCTL, 0, ioctl_id, config_id, value);
+
+	if (ioctl_id == IOCTL_GET_FEATURE_CONFIG) {
+		return pm_ipi_send_sync(primary_proc, payload, response, 1);
+	} else if (ioctl_id == IOCTL_SET_FEATURE_CONFIG) {
+		return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
+	} else {
+		return PM_RET_ERROR_ARGS;
+	}
+}
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_sys.h b/plat/xilinx/zynqmp/pm_service/pm_api_sys.h
index b0c2652..ca07cef 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_api_sys.h
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_sys.h
@@ -202,4 +202,9 @@
 enum pm_ret_status em_remove_action(unsigned int *value);
 enum pm_ret_status em_send_errors(unsigned int *value);
 
+enum pm_ret_status pm_feature_config(unsigned int ioctl_id,
+				     unsigned int config_id,
+				     unsigned int value,
+				     unsigned int *response);
+
 #endif /* PM_API_SYS_H */