]> xenbits.xensource.com Git - people/sstabellini/xen-unstable.git/.git/commitdiff
xen/arm: zynqmp: Clock get EEMI API functions are allowed to each guest
authorMirela Simonovic <mirela.simonovic@aggios.com>
Tue, 23 Oct 2018 14:51:18 +0000 (16:51 +0200)
committerStefano Stabellini <sstabellini@kernel.org>
Wed, 4 Dec 2019 23:58:10 +0000 (15:58 -0800)
Each guest is allowed to query clock related information (get divisor
value, current clock parent or clock status). Guests may need to use
these APIs to construct the information about the partial clock tree
that they control or depend on - e.g. although a guest may not control
a clock it may need to calculate its frequency and these APIs are
necessary to enable the calculation.
If the provided clock ID is valid, the call is passed through to the
EL3. Otherwise, an error is returned.

The clock id definitions are added in this patch. Although this patch
requires only clock id min and max values to check if clock id is valid,
the clock id definitions are in general needed in Xen. This is because
Xilinx clock driver implementation in Linux queries the clock tree topology
at runtime from firmware (ATF). Device tree does contain some information
about the clocks - but only leaf clock ID numbers and their binding to device
interfaces. The underlying software layers need to know everything else about
the clock tree. Since the clock topology resides in ATF and querying calls
are passed through by Xen, the Xen at least needs to know about clock IDs to
be able to map them to nodes in order to determine clock-control permissions.
This clock-control permission checking will be added in a following patch.

Signed-off-by: Mirela Simonovic <mirela.simonovic@aggios.com>
Reviewed-by: Saeed Nowshadi <saeedn@xilinx.com>
Signed-off-by: Stefano Stabellini <stefano.stabellini@xilinx.com>
xen/arch/arm/platforms/xilinx-zynqmp-eemi.c
xen/include/asm-arm/platforms/xilinx-zynqmp-eemi.h

index 63cf6dc9e5e5f09e9277f5a099cd73dfeeaf03db..c85de1da07c2a8c827df7739dd72a0ccdefdc7c1 100644 (file)
@@ -591,6 +591,15 @@ static bool domain_has_reset_access(struct domain *d, enum pm_reset rst)
     return pm_check_access(pm_reset_access, d, rst_idx);
 }
 
+/* Check if a clock id is valid */
+static bool clock_id_is_valid(enum pm_clock clk_id)
+{
+    if ( clk_id < 0 || clk_id >= PM_CLOCK_END )
+        return false;
+
+    return true;
+}
+
 /*
  * Check if a given domain has access to perform an indirect
  * MMIO access.
@@ -769,11 +778,8 @@ bool zynqmp_eemi(struct cpu_user_regs *regs)
     case EEMI_FID(PM_QUERY_DATA):
     case EEMI_FID(PM_CLOCK_ENABLE):
     case EEMI_FID(PM_CLOCK_DISABLE):
-    case EEMI_FID(PM_CLOCK_GETSTATE):
-    case EEMI_FID(PM_CLOCK_GETDIVIDER):
     case EEMI_FID(PM_CLOCK_SETDIVIDER):
     case EEMI_FID(PM_CLOCK_SETPARENT):
-    case EEMI_FID(PM_CLOCK_GETPARENT):
         if ( !is_hardware_domain(current->domain) )
         {
             gprintk(XENLOG_WARNING, "eemi: fn=%u No access", pm_fn);
@@ -787,6 +793,19 @@ bool zynqmp_eemi(struct cpu_user_regs *regs)
         ret = XST_PM_NOTSUPPORTED;
         goto done;
 
+    case EEMI_FID(PM_CLOCK_GETSTATE):
+    case EEMI_FID(PM_CLOCK_GETDIVIDER):
+    case EEMI_FID(PM_CLOCK_GETPARENT):
+        if ( !clock_id_is_valid(nodeid) )
+        {
+            gprintk(XENLOG_WARNING, "zynqmp-pm: fn=%u Invalid clock=%u\n",
+                    pm_fn, nodeid);
+            ret = XST_PM_INVALID_PARAM;
+            goto done;
+        }
+        else
+            goto forward_to_fw;
+
     /* These calls are never allowed.  */
     case EEMI_FID(PM_SYSTEM_SHUTDOWN):
         ret = XST_PM_NO_ACCESS;
index 3483d12519c1afc39db9b259fdeea5c65452f2a5..40762335ca43a08d016c740819638e4ab499ce0b 100644 (file)
@@ -323,6 +323,122 @@ enum pm_reset {
        PM_RESET_END
 };
 
+enum pm_clock {
+    PM_CLOCK_IOPLL,
+    PM_CLOCK_RPLL,
+    PM_CLOCK_APLL,
+    PM_CLOCK_DPLL,
+    PM_CLOCK_VPLL,
+    PM_CLOCK_IOPLL_TO_FPD,
+    PM_CLOCK_RPLL_TO_FPD,
+    PM_CLOCK_APLL_TO_LPD,
+    PM_CLOCK_DPLL_TO_LPD,
+    PM_CLOCK_VPLL_TO_LPD,
+    PM_CLOCK_ACPU,
+    PM_CLOCK_ACPU_HALF,
+    PM_CLOCK_DBG_FPD,
+    PM_CLOCK_DBG_LPD,
+    PM_CLOCK_DBG_TRACE,
+    PM_CLOCK_DBG_TSTMP,
+    PM_CLOCK_DP_VIDEO_REF,
+    PM_CLOCK_DP_AUDIO_REF,
+    PM_CLOCK_DP_STC_REF,
+    PM_CLOCK_GDMA_REF,
+    PM_CLOCK_DPDMA_REF,
+    PM_CLOCK_DDR_REF,
+    PM_CLOCK_SATA_REF,
+    PM_CLOCK_PCIE_REF,
+    PM_CLOCK_GPU_REF,
+    PM_CLOCK_GPU_PP0_REF,
+    PM_CLOCK_GPU_PP1_REF,
+    PM_CLOCK_TOPSW_MAIN,
+    PM_CLOCK_TOPSW_LSBUS,
+    PM_CLOCK_GTGREF0_REF,
+    PM_CLOCK_LPD_SWITCH,
+    PM_CLOCK_LPD_LSBUS,
+    PM_CLOCK_USB0_BUS_REF,
+    PM_CLOCK_USB1_BUS_REF,
+    PM_CLOCK_USB3_DUAL_REF,
+    PM_CLOCK_USB0,
+    PM_CLOCK_USB1,
+    PM_CLOCK_CPU_R5,
+    PM_CLOCK_CPU_R5_CORE,
+    PM_CLOCK_CSU_SPB,
+    PM_CLOCK_CSU_PLL,
+    PM_CLOCK_PCAP,
+    PM_CLOCK_IOU_SWITCH,
+    PM_CLOCK_GEM_TSU_REF,
+    PM_CLOCK_GEM_TSU,
+    PM_CLOCK_GEM0_TX,
+    PM_CLOCK_GEM1_TX,
+    PM_CLOCK_GEM2_TX,
+    PM_CLOCK_GEM3_TX,
+    PM_CLOCK_GEM0_RX,
+    PM_CLOCK_GEM1_RX,
+    PM_CLOCK_GEM2_RX,
+    PM_CLOCK_GEM3_RX,
+    PM_CLOCK_QSPI_REF,
+    PM_CLOCK_SDIO0_REF,
+    PM_CLOCK_SDIO1_REF,
+    PM_CLOCK_UART0_REF,
+    PM_CLOCK_UART1_REF,
+    PM_CLOCK_SPI0_REF,
+    PM_CLOCK_SPI1_REF,
+    PM_CLOCK_NAND_REF,
+    PM_CLOCK_I2C0_REF,
+    PM_CLOCK_I2C1_REF,
+    PM_CLOCK_CAN0_REF,
+    PM_CLOCK_CAN1_REF,
+    PM_CLOCK_CAN0,
+    PM_CLOCK_CAN1,
+    PM_CLOCK_DLL_REF,
+    PM_CLOCK_ADMA_REF,
+    PM_CLOCK_TIMESTAMP_REF,
+    PM_CLOCK_AMS_REF,
+    PM_CLOCK_PL0_REF,
+    PM_CLOCK_PL1_REF,
+    PM_CLOCK_PL2_REF,
+    PM_CLOCK_PL3_REF,
+    PM_CLOCK_WDT,
+    PM_CLOCK_IOPLL_INT,
+    PM_CLOCK_IOPLL_PRE_SRC,
+    PM_CLOCK_IOPLL_HALF,
+    PM_CLOCK_IOPLL_INT_MUX,
+    PM_CLOCK_IOPLL_POST_SRC,
+    PM_CLOCK_RPLL_INT,
+    PM_CLOCK_RPLL_PRE_SRC,
+    PM_CLOCK_RPLL_HALF,
+    PM_CLOCK_RPLL_INT_MUX,
+    PM_CLOCK_RPLL_POST_SRC,
+    PM_CLOCK_APLL_INT,
+    PM_CLOCK_APLL_PRE_SRC,
+    PM_CLOCK_APLL_HALF,
+    PM_CLOCK_APLL_INT_MUX,
+    PM_CLOCK_APLL_POST_SRC,
+    PM_CLOCK_DPLL_INT,
+    PM_CLOCK_DPLL_PRE_SRC,
+    PM_CLOCK_DPLL_HALF,
+    PM_CLOCK_DPLL_INT_MUX,
+    PM_CLOCK_DPLL_POST_SRC,
+    PM_CLOCK_VPLL_INT,
+    PM_CLOCK_VPLL_PRE_SRC,
+    PM_CLOCK_VPLL_HALF,
+    PM_CLOCK_VPLL_INT_MUX,
+    PM_CLOCK_VPLL_POST_SRC,
+    PM_CLOCK_CAN0_MIO,
+    PM_CLOCK_CAN1_MIO,
+    PM_CLOCK_ACPU_FULL,
+    PM_CLOCK_GEM0_REF,
+    PM_CLOCK_GEM1_REF,
+    PM_CLOCK_GEM2_REF,
+    PM_CLOCK_GEM3_REF,
+    PM_CLOCK_GEM0_REF_UNGATED,
+    PM_CLOCK_GEM1_REF_UNGATED,
+    PM_CLOCK_GEM2_REF_UNGATED,
+    PM_CLOCK_GEM3_REF_UNGATED,
+    PM_CLOCK_END,
+};
+
 extern bool zynqmp_eemi(struct cpu_user_regs *regs);
 
 #endif /* __ASM_ARM_PLATFORMS_ZYNQMP_H */