zynqmp: pm: Add IOCTLs for global storage access

Add IOCTLs to read/write global general storage and
persistent global general storage registers access.

Signed-off-by: Rajan Vaja <rajanv@xilinx.com>
Signed-off-by: Jolly Shah <jollys@xilinx.com>
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c b/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c
index 7634b8c..3ef0272 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c
@@ -396,6 +396,82 @@
 }
 
 /**
+ * pm_ioctl_write_ggs() - Ioctl function for writing
+ *			  global general storage (ggs)
+ * @index	GGS register index
+ * @value	Register value to be written
+ *
+ * This function writes value to GGS register.
+ *
+ * @return      Returns status, either success or error+reason
+ */
+static enum pm_ret_status pm_ioctl_write_ggs(unsigned int index,
+					     unsigned int value)
+{
+	if (index >= GGS_NUM_REGS)
+		return PM_RET_ERROR_ARGS;
+
+	return pm_mmio_write(GGS_BASEADDR + (index << 2), 0xFFFFFFFF, value);
+}
+
+/**
+ * pm_ioctl_read_ggs() - Ioctl function for reading
+ *			 global general storage (ggs)
+ * @index	GGS register index
+ * @value	Register value
+ *
+ * This function returns GGS register value.
+ *
+ * @return      Returns status, either success or error+reason
+ */
+static enum pm_ret_status pm_ioctl_read_ggs(unsigned int index,
+					    unsigned int *value)
+{
+	if (index >= GGS_NUM_REGS)
+		return PM_RET_ERROR_ARGS;
+
+	return pm_mmio_read(GGS_BASEADDR + (index << 2), value);
+}
+
+/**
+ * pm_ioctl_write_pggs() - Ioctl function for writing persistent
+ *			   global general storage (pggs)
+ * @index	PGGS register index
+ * @value	Register value to be written
+ *
+ * This function writes value to PGGS register.
+ *
+ * @return      Returns status, either success or error+reason
+ */
+static enum pm_ret_status pm_ioctl_write_pggs(unsigned int index,
+					      unsigned int value)
+{
+	if (index >= PGGS_NUM_REGS)
+		return PM_RET_ERROR_ARGS;
+
+	return pm_mmio_write(PGGS_BASEADDR + (index << 2), 0xFFFFFFFF, value);
+}
+
+/**
+ * pm_ioctl_read_pggs() - Ioctl function for reading persistent
+ *			  global general storage (pggs)
+ * @index	PGGS register index
+ * @value	Register value
+ *
+ * This function returns PGGS register value.
+ *
+ * @return      Returns status, either success or error+reason
+ */
+static enum pm_ret_status pm_ioctl_read_pggs(unsigned int index,
+					     unsigned int *value)
+{
+	if (index >= PGGS_NUM_REGS)
+		return PM_RET_ERROR_ARGS;
+
+	return pm_mmio_read(PGGS_BASEADDR + (index << 2), value);
+}
+
+/**
  * pm_api_ioctl() -  PM IOCTL API for device control and configs
  * @node_id	Node ID of the device
  * @ioctl_id	ID of the requested IOCTL
@@ -452,6 +528,18 @@
 	case IOCTL_GET_PLL_FRAC_DATA:
 		ret = pm_ioctl_get_pll_frac_data(arg1, value);
 		break;
+	case IOCTL_WRITE_GGS:
+		ret = pm_ioctl_write_ggs(arg1, arg2);
+		break;
+	case IOCTL_READ_GGS:
+		ret = pm_ioctl_read_ggs(arg1, value);
+		break;
+	case IOCTL_WRITE_PGGS:
+		ret = pm_ioctl_write_pggs(arg1, arg2);
+		break;
+	case IOCTL_READ_PGGS:
+		ret = pm_ioctl_read_pggs(arg1, value);
+		break;
 	default:
 		ret = PM_RET_ERROR_NOTSUPPORTED;
 	}
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.h b/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.h
index b290574..548ac9e 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.h
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.h
@@ -27,6 +27,10 @@
 	IOCTL_GET_PLL_FRAC_MODE,
 	IOCTL_SET_PLL_FRAC_DATA,
 	IOCTL_GET_PLL_FRAC_DATA,
+	IOCTL_WRITE_GGS,
+	IOCTL_READ_GGS,
+	IOCTL_WRITE_PGGS,
+	IOCTL_READ_PGGS,
 };
 
 enum rpu_oper_mode {
diff --git a/plat/xilinx/zynqmp/zynqmp_def.h b/plat/xilinx/zynqmp/zynqmp_def.h
index 3feae9d..e7fceda 100644
--- a/plat/xilinx/zynqmp/zynqmp_def.h
+++ b/plat/xilinx/zynqmp/zynqmp_def.h
@@ -303,4 +303,12 @@
 #define IOU_SLCR_CAN_MIO_CTRL		(IOU_SLCR_BASEADDR + 0x304)
 #define IOU_SLCR_WDT_CLK_SEL		(IOU_SLCR_BASEADDR + 0x300)
 
+/* Global general storage register base address */
+#define GGS_BASEADDR		(0xFFD80030U)
+#define GGS_NUM_REGS		(4)
+
+/* Persistent global general storage register base address */
+#define PGGS_BASEADDR		(0xFFD80050U)
+#define PGGS_NUM_REGS		(4)
+
 #endif /* __ZYNQMP_DEF_H__ */