diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_clock.c b/plat/xilinx/zynqmp/pm_service/pm_api_clock.c index b175b78b3ebd39fa6fe05a356a6542f19ebb6e43..723ad401dd8a65b1a96f6ac793c706f4bede00fc 100644 --- a/plat/xilinx/zynqmp/pm_service/pm_api_clock.c +++ b/plat/xilinx/zynqmp/pm_service/pm_api_clock.c @@ -2488,6 +2488,74 @@ enum pm_ret_status pm_api_clock_get_attributes(unsigned int clock_id, return PM_RET_SUCCESS; } +/** + * struct pm_pll - PLL related data required to map IOCTL-based PLL control + * implemented by linux to system-level EEMI APIs + * @nid: PLL node ID + * @cid: PLL clock ID + */ +struct pm_pll { + const enum pm_node_id nid; + const enum clock_id cid; +}; + +static struct pm_pll pm_plls[] = { + { + .nid = NODE_IOPLL, + .cid = CLK_IOPLL_INT, + }, { + .nid = NODE_RPLL, + .cid = CLK_RPLL_INT, + }, { + .nid = NODE_APLL, + .cid = CLK_APLL_INT, + }, { + .nid = NODE_VPLL, + .cid = CLK_VPLL_INT, + }, { + .nid = NODE_DPLL, + .cid = CLK_DPLL_INT, + }, +}; + +/** + * pm_clock_get_pll() - Get PLL structure by PLL clock ID + * @clock_id Clock ID of the target PLL + * + * @return Pointer to PLL structure if found, NULL otherwise + */ +static struct pm_pll *pm_clock_get_pll(enum clock_id clock_id) +{ + uint32_t i; + + for (i = 0; i < ARRAY_SIZE(pm_plls); i++) { + if (pm_plls[i].cid == clock_id) + return &pm_plls[i]; + } + + return NULL; +} + +/** + * pm_clock_get_pll_node_id() - Get PLL node ID by PLL clock ID + * @clock_id Clock ID of the target PLL + * @node_id Location to store node ID of the target PLL + * + * @return PM_RET_SUCCESS if node ID is found, PM_RET_ERROR_ARGS otherwise + */ +enum pm_ret_status pm_clock_get_pll_node_id(enum clock_id clock_id, + enum pm_node_id *node_id) +{ + struct pm_pll *pll = pm_clock_get_pll(clock_id); + + if (pll) { + *node_id = pll->nid; + return PM_RET_SUCCESS; + } + + return PM_RET_ERROR_ARGS; +} + /** * pll_get_lockbit() - Returns lockbit index for pll id * @pll_id: Id of the pll @@ -3170,35 +3238,3 @@ enum pm_ret_status pm_api_clk_set_pll_frac_data(unsigned int pll, return ret; } - -/** - * pm_api_clk_get_pll_frac_data() - Get PLL fraction data - * @pll PLL id - * @data fraction data - * - * This function returns fraction data value. - * - * @return Returns status, either success or error+reason - */ -enum pm_ret_status pm_api_clk_get_pll_frac_data(unsigned int pll, - unsigned int *data) -{ - enum pm_ret_status ret = PM_RET_SUCCESS; - unsigned int val, reg; - - if (!pm_clock_valid(pll)) - return PM_RET_ERROR_ARGS; - - if (pm_clock_type(pll) != CLK_TYPE_OUTPUT) - return PM_RET_ERROR_NOTSUPPORTED; - - if (!ISPLL(pll)) - return PM_RET_ERROR_NOTSUPPORTED; - - reg = clocks[pll].control_reg + PLL_FRAC_OFFSET; - - ret = pm_mmio_read(reg, &val); - *data = (val & PLL_FRAC_DATA_MASK); - - return ret; -} diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_clock.h b/plat/xilinx/zynqmp/pm_service/pm_api_clock.h index f7cbdbaf08114d80665e48694cedb73b37d91b30..ebada774baedd423d9533cb32ff050262835c4f4 100644 --- a/plat/xilinx/zynqmp/pm_service/pm_api_clock.h +++ b/plat/xilinx/zynqmp/pm_service/pm_api_clock.h @@ -55,7 +55,7 @@ #define END_OF_CLK "END_OF_CLK" //CLock Ids -enum { +enum clock_id { CLK_IOPLL, CLK_RPLL, CLK_APLL, @@ -288,6 +288,10 @@ enum pm_ret_status pm_api_clock_get_parents(unsigned int clock_id, uint32_t *parents); enum pm_ret_status pm_api_clock_get_attributes(unsigned int clock_id, uint32_t *attr); + +enum pm_ret_status pm_clock_get_pll_node_id(enum clock_id clock_id, + enum pm_node_id *node_id); + enum pm_ret_status pm_api_clock_enable(unsigned int clock_id); enum pm_ret_status pm_api_clock_disable(unsigned int clock_id); enum pm_ret_status pm_api_clock_getstate(unsigned int clock_id, @@ -310,7 +314,5 @@ enum pm_ret_status pm_api_clk_get_pll_mode(unsigned int pll, unsigned int *mode); enum pm_ret_status pm_api_clk_set_pll_frac_data(unsigned int pll, unsigned int data); -enum pm_ret_status pm_api_clk_get_pll_frac_data(unsigned int pll, - unsigned int *data); #endif /* PM_API_CLOCK_H */ diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c b/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c index 16c08ae6d2c2be9295e9bd043c5b14419cd6f72a..87c3f7de9cee7b758d78e419953d22f0441c7403 100644 --- a/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c +++ b/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c @@ -381,7 +381,7 @@ static enum pm_ret_status pm_ioctl_set_pll_frac_data /** * pm_ioctl_get_pll_frac_data() - Ioctl function for * getting pll fraction data - * @pll PLL id + * @pll PLL clock id * @data fraction data * * This function returns fraction data value. @@ -391,7 +391,15 @@ static enum pm_ret_status pm_ioctl_set_pll_frac_data static enum pm_ret_status pm_ioctl_get_pll_frac_data (unsigned int pll, unsigned int *data) { - return pm_api_clk_get_pll_frac_data(pll, data); + enum pm_node_id pll_nid; + enum pm_ret_status status; + + /* Get PLL node ID using PLL clock ID */ + status = pm_clock_get_pll_node_id(pll, &pll_nid); + if (status != PM_RET_SUCCESS) + return status; + + return pm_pll_get_parameter(pll_nid, PM_PLL_PARAM_DATA, data); } /**