plat: xilinx: versal: Add load Pdi API support

This patch adds support for load pdi api to enable loading
pdi from linux.

Signed-off-by: Jolly Shah <jolly.shah@xilinx.com>
Change-Id: I48549e276e1f7b9be45a0bebf559f73bd09d5f69
diff --git a/plat/xilinx/versal/pm_service/pm_api_sys.c b/plat/xilinx/versal/pm_service/pm_api_sys.c
index 54fd6e1..e48fbf5 100644
--- a/plat/xilinx/versal/pm_service/pm_api_sys.c
+++ b/plat/xilinx/versal/pm_service/pm_api_sys.c
@@ -802,6 +802,9 @@
 	case PM_FEATURE_CHECK:
 		*version = (PM_API_BASE_VERSION << 16);
 		break;
+	case PM_LOAD_PDI:
+		*version = (PM_API_BASE_VERSION << 16);
+		return PM_RET_SUCCESS;
 	default:
 		*version = 0U;
 		return PM_RET_ERROR_NOFEATURE;
@@ -817,3 +820,25 @@
 
 	return PM_RET_SUCCESS;
 }
+
+/**
+ * pm_load_pdi() - Load the PDI
+ *
+ * This function provides support to load PDI from linux
+ *
+ * src:        Source device of pdi(DDR, OCM, SD etc)
+ * address_low: lower 32-bit Linear memory space address
+ * address_high: higher 32-bit Linear memory space address
+ *
+ * @return      Returns status, either success or error+reason
+ */
+enum pm_ret_status pm_load_pdi(uint32_t src,
+			       uint32_t address_low, uint32_t address_high)
+{
+	uint32_t payload[PAYLOAD_ARG_CNT];
+
+	/* Send request to the PMU */
+	PM_PACK_PAYLOAD4(payload, LOADER_MODULE_ID, PM_LOAD_PDI, src,
+			 address_high, address_low);
+	return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
+}
diff --git a/plat/xilinx/versal/pm_service/pm_api_sys.h b/plat/xilinx/versal/pm_service/pm_api_sys.h
index 4e884e0..5effbb6 100644
--- a/plat/xilinx/versal/pm_service/pm_api_sys.h
+++ b/plat/xilinx/versal/pm_service/pm_api_sys.h
@@ -66,4 +66,6 @@
 				 uint32_t arg3, uint32_t *data);
 unsigned int pm_get_shutdown_scope(void);
 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);
 #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 a7b0a02..892804d 100644
--- a/plat/xilinx/versal/pm_service/pm_defs.h
+++ b/plat/xilinx/versal/pm_service/pm_defs.h
@@ -78,6 +78,9 @@
 #define PM_PLL_GET_MODE			51U
 #define PM_FEATURE_CHECK		63U
 
+/* Loader API ids */
+#define PM_LOAD_PDI			0x701U
+
 /* IOCTL IDs for clock driver */
 #define IOCTL_SET_PLL_FRAC_MODE		8
 #define	IOCTL_GET_PLL_FRAC_MODE		9
diff --git a/plat/xilinx/versal/pm_service/pm_svc_main.c b/plat/xilinx/versal/pm_service/pm_svc_main.c
index b5a6783..bbe8097 100644
--- a/plat/xilinx/versal/pm_service/pm_svc_main.c
+++ b/plat/xilinx/versal/pm_service/pm_svc_main.c
@@ -298,6 +298,12 @@
 		SMC_RET1(handle, (uint64_t)ret | ((uint64_t)version << 32));
 	}
 
+	case PM_LOAD_PDI:
+	{
+		ret = pm_load_pdi(pm_arg[0], pm_arg[1], pm_arg[2]);
+		SMC_RET1(handle, (uint64_t)ret);
+	}
+
 	default:
 		WARN("Unimplemented PM Service Call: 0x%x\n", smc_fid);
 		SMC_RET1(handle, SMC_UNK);