]> xenbits.xensource.com Git - people/sstabellini/xen-unstable.git/.git/commitdiff
xen/arm: zynqmp: Add PLL set mode/parameter EEMI API
authorMirela Simonovic <mirela.simonovic@aggios.com>
Tue, 23 Oct 2018 14:51:21 +0000 (16:51 +0200)
committerStefano Stabellini <sstabellini@kernel.org>
Wed, 4 Dec 2019 23:58:10 +0000 (15:58 -0800)
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 <mirela.simonovic@aggios.com>
Reviewed-by: Saeed Nowshadi <saeedn@xilinx.com>
Reviewed-by: Stefano Stabellini <stefanos@xilinx.com>
xen/arch/arm/platforms/xilinx-zynqmp-eemi.c

index 20c4be353cf00fe109cde42eb8df7e1752a9cfe0..706514a8524b8015ef4d5f99a61b5be006f9ad47 100644 (file)
@@ -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;