summaryrefslogtreecommitdiff
path: root/plat/xilinx
diff options
context:
space:
mode:
authorJolly Shah <jollys@xilinx.com>2019-01-04 11:32:31 -0800
committerJolly Shah <jollys@xilinx.com>2019-01-04 11:33:56 -0800
commit5f1a5fee52b9bfb93f588325819cf706cf103d24 (patch)
treeca8cc40e17ad85aac6e3afcd101943e35999f714 /plat/xilinx
parentd833f64c90615b00e4fa1fd401bf521edb8b9909 (diff)
zynqmp: pm: Implement PLL set mode EEMI API
This API will be used to set the PLL mode: reset (unlocked), integer or fractional (locked). If reset mode is set the PM controller will bypass the target PLL prior to asserting the reset. If integer or fractional mode is set the PM controller will program and trigger locking of the PLL. If success status is returned the PLL is locked and its bypass is deasserted. If fractional mode is set the fractional divider (data parameter) has to have a non-zero value prior to issuing pll set fractional mode. The caller need to ensure that the data parameter is properly set using pll get/set parameter EEMI API. Signed-off-by: Mirela Simonovic <mirela.simonovic@aggios.com> Acked-by: Will Wong <WILLW@xilinx.com> Signed-off-by: Jolly Shah <jollys@xilinx.com>
Diffstat (limited to 'plat/xilinx')
-rw-r--r--plat/xilinx/zynqmp/pm_service/pm_api_sys.c30
-rw-r--r--plat/xilinx/zynqmp/pm_service/pm_api_sys.h2
-rw-r--r--plat/xilinx/zynqmp/pm_service/pm_defs.h12
-rw-r--r--plat/xilinx/zynqmp/pm_service/pm_svc_main.c4
4 files changed, 48 insertions, 0 deletions
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_sys.c b/plat/xilinx/zynqmp/pm_service/pm_api_sys.c
index da166911..b37512a2 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_api_sys.c
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_sys.c
@@ -1296,3 +1296,33 @@ enum pm_ret_status pm_pll_get_parameter(enum pm_node_id nid,
PM_PACK_PAYLOAD3(payload, PM_PLL_GET_PARAMETER, nid, param_id);
return pm_ipi_send_sync(primary_proc, payload, value, 1);
}
+
+/**
+ * pm_pll_set_mode() - Set the PLL mode
+ * @nid Node id of the target PLL
+ * @mode PLL mode to be set
+ *
+ * If reset mode is set the PM controller will first bypass the PLL and then
+ * assert the reset. If integer or fractional mode is set the PM controller will
+ * ensure that the complete PLL programming sequence is satisfied. After this
+ * function returns success the PLL is locked and its bypass is deasserted.
+ *
+ * @return Error if an argument is not valid or status as returned by the
+ * PM controller (PMU)
+ */
+enum pm_ret_status pm_pll_set_mode(enum pm_node_id nid, enum pm_pll_mode mode)
+{
+ uint32_t payload[PAYLOAD_ARG_CNT];
+
+ /* Check if given node ID is a PLL node */
+ if (nid < NODE_APLL || nid > NODE_IOPLL)
+ return PM_RET_ERROR_ARGS;
+
+ /* Check if PLL mode is valid */
+ if (mode >= PM_PLL_MODE_MAX)
+ return PM_RET_ERROR_ARGS;
+
+ /* Send request to the PMU */
+ PM_PACK_PAYLOAD3(payload, PM_PLL_SET_MODE, nid, mode);
+ return pm_ipi_send_sync(primary_proc, payload, NULL, 0);
+}
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_sys.h b/plat/xilinx/zynqmp/pm_service/pm_api_sys.h
index 8ef210ac..9b211f5f 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_api_sys.h
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_sys.h
@@ -184,4 +184,6 @@ enum pm_ret_status pm_pll_get_parameter(enum pm_node_id nid,
enum pm_pll_param param_id,
unsigned int *value);
+enum pm_ret_status pm_pll_set_mode(enum pm_node_id nid, enum pm_pll_mode mode);
+
#endif /* PM_API_SYS_H */
diff --git a/plat/xilinx/zynqmp/pm_service/pm_defs.h b/plat/xilinx/zynqmp/pm_service/pm_defs.h
index 167a7333..5927cafb 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_defs.h
+++ b/plat/xilinx/zynqmp/pm_service/pm_defs.h
@@ -95,6 +95,7 @@ enum pm_api_id {
/* PLL control API functions */
PM_PLL_SET_PARAMETER,
PM_PLL_GET_PARAMETER,
+ PM_PLL_SET_MODE,
PM_API_MAX
};
@@ -294,5 +295,16 @@ enum pm_pll_param {
PM_PLL_PARAM_MAX,
};
+/**
+ * @PM_PLL_MODE_RESET: PLL is in reset (not locked)
+ * @PM_PLL_MODE_INTEGER: PLL is locked in integer mode
+ * @PM_PLL_MODE_FRACTIONAL: PLL is locked in fractional mode
+ */
+enum pm_pll_mode {
+ PM_PLL_MODE_RESET,
+ PM_PLL_MODE_INTEGER,
+ PM_PLL_MODE_FRACTIONAL,
+ PM_PLL_MODE_MAX,
+};
#endif /* PM_DEFS_H */
diff --git a/plat/xilinx/zynqmp/pm_service/pm_svc_main.c b/plat/xilinx/zynqmp/pm_service/pm_svc_main.c
index 4e4a3ef6..881a5933 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_svc_main.c
+++ b/plat/xilinx/zynqmp/pm_service/pm_svc_main.c
@@ -575,6 +575,10 @@ uint64_t pm_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3,
SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value << 32));
}
+ case PM_PLL_SET_MODE:
+ ret = pm_pll_set_mode(pm_arg[0], pm_arg[1]);
+ SMC_RET1(handle, (uint64_t)ret);
+
default:
WARN("Unimplemented PM Service Call: 0x%x\n", smc_fid);
SMC_RET1(handle, SMC_UNK);