From f1bc982e7ceda6d0124ce65290727eaa49d0fd5a Mon Sep 17 00:00:00 2001 From: Michael Tretter Date: Thu, 21 Jan 2021 08:16:50 +0100 Subject: soc: xilinx: vcu: implement PLL disable The disabling of the PLL is not fully implemented, because according to the ZynqMP register reference the RESET, POR_IN and PWR_POR bits have to be set to bring the PLL into reset. Set the bits to disable the PLL. Signed-off-by: Michael Tretter Acked-by: Michal Simek Link: https://lore.kernel.org/r/20210121071659.1226489-7-m.tretter@pengutronix.de Signed-off-by: Stephen Boyd --- drivers/soc/xilinx/xlnx_vcu.c | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/drivers/soc/xilinx/xlnx_vcu.c b/drivers/soc/xilinx/xlnx_vcu.c index ff66551a5966..34f3299afc0d 100644 --- a/drivers/soc/xilinx/xlnx_vcu.c +++ b/drivers/soc/xilinx/xlnx_vcu.c @@ -329,6 +329,10 @@ static int xvcu_pll_enable(struct xvcu_device *xvcu) return ret; } + xvcu_write_field_reg(base, VCU_PLL_CTRL, + 1, VCU_PLL_CTRL_BYPASS_MASK, + VCU_PLL_CTRL_BYPASS_SHIFT); + vcu_pll_ctrl = xvcu_read(base, VCU_PLL_CTRL); vcu_pll_ctrl &= ~(VCU_PLL_CTRL_POR_IN_MASK << VCU_PLL_CTRL_POR_IN_SHIFT); @@ -340,15 +344,9 @@ static int xvcu_pll_enable(struct xvcu_device *xvcu) VCU_PLL_CTRL_PWR_POR_SHIFT; xvcu_write(base, VCU_PLL_CTRL, vcu_pll_ctrl); - xvcu_write_field_reg(base, VCU_PLL_CTRL, - 1, VCU_PLL_CTRL_BYPASS_MASK, - VCU_PLL_CTRL_BYPASS_SHIFT); - xvcu_write_field_reg(base, VCU_PLL_CTRL, - 1, VCU_PLL_CTRL_RESET_MASK, - VCU_PLL_CTRL_RESET_SHIFT); - xvcu_write_field_reg(base, VCU_PLL_CTRL, - 0, VCU_PLL_CTRL_RESET_MASK, - VCU_PLL_CTRL_RESET_SHIFT); + vcu_pll_ctrl &= ~(VCU_PLL_CTRL_RESET_MASK << VCU_PLL_CTRL_RESET_SHIFT); + vcu_pll_ctrl |= (0 & VCU_PLL_CTRL_RESET_MASK) << VCU_PLL_CTRL_RESET_SHIFT; + xvcu_write(base, VCU_PLL_CTRL, vcu_pll_ctrl); ret = xvcu_pll_wait_for_lock(xvcu); if (ret) { @@ -368,6 +366,18 @@ err: static void xvcu_pll_disable(struct xvcu_device *xvcu) { + void __iomem *base = xvcu->vcu_slcr_ba; + u32 vcu_pll_ctrl; + + vcu_pll_ctrl = xvcu_read(base, VCU_PLL_CTRL); + vcu_pll_ctrl &= ~(VCU_PLL_CTRL_POR_IN_MASK << VCU_PLL_CTRL_POR_IN_SHIFT); + vcu_pll_ctrl |= (1 & VCU_PLL_CTRL_POR_IN_MASK) << VCU_PLL_CTRL_POR_IN_SHIFT; + vcu_pll_ctrl &= ~(VCU_PLL_CTRL_PWR_POR_MASK << VCU_PLL_CTRL_PWR_POR_SHIFT); + vcu_pll_ctrl |= (1 & VCU_PLL_CTRL_PWR_POR_MASK) << VCU_PLL_CTRL_PWR_POR_SHIFT; + vcu_pll_ctrl &= ~(VCU_PLL_CTRL_RESET_MASK << VCU_PLL_CTRL_RESET_SHIFT); + vcu_pll_ctrl |= (1 & VCU_PLL_CTRL_RESET_MASK) << VCU_PLL_CTRL_RESET_SHIFT; + xvcu_write(base, VCU_PLL_CTRL, vcu_pll_ctrl); + clk_disable_unprepare(xvcu->pll_ref); } -- cgit v1.2.3-59-g8ed1b