From 50cda5b03b12b238b947f886e31bab96bcd12215 Mon Sep 17 00:00:00 2001 From: Mirela Simonovic Date: Tue, 23 Oct 2018 16:51:21 +0200 Subject: [PATCH] xen/arm: zynqmp: Add PLL set mode/parameter EEMI API PLL set mode/parameter should be allowed only for VPLL and RPLL to a guest which uses the display port. This is the case because the display port driver requires some very specific frequencies for video and audio, so it relies on configuring VPLL and RPLL in fractional mode (for video and audio respectively). These two PLLs are reserved for exclusive usage to display port, or to be more specific - the clock framework of the guest that owns the display port will need to directly control the modes of these two PLLs and the power management framework should allow that. The check is implemented using the domain_has_node_access() function, which covers this use-case because access to NODE_VPLL and NODE_RPLL is granted to a guest which has access to the display port via the newly added entries in pm_node_access map. If a guest is allowed to control a PLL the request is passed through to the EL3. Otherwise, an error is returned. Signed-off-by: Mirela Simonovic Reviewed-by: Saeed Nowshadi Reviewed-by: Stefano Stabellini --- xen/arch/arm/platforms/xilinx-zynqmp-eemi.c | 22 +++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/xen/arch/arm/platforms/xilinx-zynqmp-eemi.c b/xen/arch/arm/platforms/xilinx-zynqmp-eemi.c index 20c4be353c..706514a852 100644 --- a/xen/arch/arm/platforms/xilinx-zynqmp-eemi.c +++ b/xen/arch/arm/platforms/xilinx-zynqmp-eemi.c @@ -142,6 +142,8 @@ static const struct pm_access pm_node_access[] = { [NODE_SD_0] = { MM_SD0 }, [NODE_SD_1] = { MM_SD1 }, [NODE_DP] = { MM_DP }, + [NODE_VPLL] = { MM_DP }, + [NODE_RPLL] = { MM_DP }, /* Guest with GDMA Channel 0 gets PM access. Other guests don't. */ [NODE_GDMA] = { MM_GDMA_CH0 }, @@ -157,9 +159,7 @@ static const struct pm_access pm_node_access[] = { /* Only for the hardware domain. */ [NODE_AFI] = { .hwdom_access = true }, [NODE_APLL] = { .hwdom_access = true }, - [NODE_VPLL] = { .hwdom_access = true }, [NODE_DPLL] = { .hwdom_access = true }, - [NODE_RPLL] = { .hwdom_access = true }, [NODE_IOPLL] = { .hwdom_access = true }, [NODE_DDR] = { .hwdom_access = true }, [NODE_IPI_APU] = { .hwdom_access = true }, @@ -933,6 +933,24 @@ bool zynqmp_eemi(struct cpu_user_regs *regs) else goto forward_to_fw; + case PM_PLL_SET_PARAMETER: + case PM_PLL_SET_MODE: + if ( nodeid < NODE_APLL || nodeid > NODE_IOPLL ) + { + gprintk(XENLOG_WARNING, "zynqmp-pm: fn=%u Invalid pll node %u\n", + pm_fn, nodeid); + ret = XST_PM_INVALID_PARAM; + goto done; + } + if ( !domain_has_node_access(current->domain, nodeid) ) + { + gprintk(XENLOG_WARNING, "zynqmp-pm: fn=%u No access to pll=%u\n", + pm_fn, nodeid); + ret = XST_PM_NO_ACCESS; + goto done; + } + goto forward_to_fw; + /* These calls are never allowed. */ case EEMI_FID(PM_SYSTEM_SHUTDOWN): ret = XST_PM_NO_ACCESS; -- 2.39.5