From: Padmarao Begari Date: Wed, 18 Jun 2025 09:43:29 +0000 (+0530) Subject: clk: zynqmp: Add support for dpll clock source X-Git-Tag: v2025.10-rc1~131^2~18 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a5f2aa4b3898d3fb7ba37c17b446aa62c7c83cc4;p=thirdparty%2Fu-boot.git clk: zynqmp: Add support for dpll clock source The clock driver fails to correctly calculate the PLL clock rate for peripherals when using the DPLL as the clock source. The DPLL operates within the full power domain, while peripheral clocks reside in the low power domain. To ensure accurate PLL clock rate computation when the peripheral clock source is set to DPLL, the DPLL-to-LPD cross divisor is used. Signed-off-by: Padmarao Begari Link: https://lore.kernel.org/r/20250618094329.296731-1-padmarao.begari@amd.com Signed-off-by: Michal Simek --- diff --git a/drivers/clk/clk_zynqmp.c b/drivers/clk/clk_zynqmp.c index a8239e228cf..4f67c958d0f 100644 --- a/drivers/clk/clk_zynqmp.c +++ b/drivers/clk/clk_zynqmp.c @@ -108,6 +108,8 @@ static const resource_size_t zynqmp_crl_apb_clkc_base = 0xff5e0020; #define PLLCTRL_POST_SRC_MASK (0x7 << PLLCTRL_POST_SRC_SHFT) #define PLLCTRL_PRE_SRC_SHFT 20 #define PLLCTRL_PRE_SRC_MASK (0x7 << PLLCTRL_PRE_SRC_SHFT) +#define PLL_TO_LPD_DIV_SHIFT 8 +#define PLL_TO_LPD_DIV_MASK (0x3f << PLL_TO_LPD_DIV_SHIFT) #define NUM_MIO_PINS 77 @@ -334,6 +336,8 @@ static u32 zynqmp_clk_get_register(enum zynqmp_clk id) return CRF_APB_TOPSW_LSBUS_CTRL; case iopll_to_fpd: return CRL_APB_IOPLL_TO_FPD_CTRL; + case dpll_to_lpd: + return CRF_APB_DPLL_TO_LPD_CTRL; default: debug("Invalid clk id%d\n", id); } @@ -397,6 +401,22 @@ static ulong zynqmp_clk_get_pll_rate(struct zynqmp_clk_priv *priv, if (clk_ctrl & (1 << 16)) freq /= 2; + if (id == dpll) { + u32 dpll_lpd_reg, cross_div; + + dpll_lpd_reg = zynqmp_clk_get_register(dpll_to_lpd); + + ret = zynqmp_mmio_read(dpll_lpd_reg, &cross_div); + if (ret) { + printf("%s mio read fail\n", __func__); + return -EIO; + } + + cross_div = (cross_div & PLL_TO_LPD_DIV_MASK) >> + PLL_TO_LPD_DIV_SHIFT; + freq /= cross_div; + } + return freq; }