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 <padmarao.begari@amd.com>
Link: https://lore.kernel.org/r/20250618094329.296731-1-padmarao.begari@amd.com
Signed-off-by: Michal Simek <michal.simek@amd.com>
This commit is contained in:
Padmarao Begari
2025-06-18 15:13:29 +05:30
committed by Michal Simek
parent 4216a86343
commit a5f2aa4b38

View File

@@ -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;
}