From e2151c96a3cd13ded9970f89c51498a642efda2f Mon Sep 17 00:00:00 2001 From: Mirela Simonovic Date: Tue, 23 Oct 2018 16:51:18 +0200 Subject: [PATCH] xen/arm: zynqmp: Clock get EEMI API functions are allowed to each guest 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 Reviewed-by: Saeed Nowshadi Signed-off-by: Stefano Stabellini --- xen/arch/arm/platforms/xilinx-zynqmp-eemi.c | 25 +++- .../asm-arm/platforms/xilinx-zynqmp-eemi.h | 116 ++++++++++++++++++ 2 files changed, 138 insertions(+), 3 deletions(-) diff --git a/xen/arch/arm/platforms/xilinx-zynqmp-eemi.c b/xen/arch/arm/platforms/xilinx-zynqmp-eemi.c index 63cf6dc9e5..c85de1da07 100644 --- a/xen/arch/arm/platforms/xilinx-zynqmp-eemi.c +++ b/xen/arch/arm/platforms/xilinx-zynqmp-eemi.c @@ -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; diff --git a/xen/include/asm-arm/platforms/xilinx-zynqmp-eemi.h b/xen/include/asm-arm/platforms/xilinx-zynqmp-eemi.h index 3483d12519..40762335ca 100644 --- a/xen/include/asm-arm/platforms/xilinx-zynqmp-eemi.h +++ b/xen/include/asm-arm/platforms/xilinx-zynqmp-eemi.h @@ -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 */ -- 2.39.5