Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

phy: zynqmp: Enable reference clock correctly

Lanes can use other lanes' reference clocks, as determined by refclk.
Use refclk to determine the clock to enable/disable instead of always
using the lane's own reference clock. This ensures the clock selected in
xpsgtr_configure_pll is the one enabled.

For the other half of the equation, always program REF_CLK_SEL even when
we are selecting the lane's own clock. This ensures that Linux's idea of
the reference clock matches the hardware. We use the "local" clock mux
for this instead of going through the ref clock network.

Fixes: 25d700833513 ("phy: xilinx: phy-zynqmp: dynamic clock support for power-save")
Signed-off-by: Sean Anderson <sean.anderson@linux.dev>
Link: https://lore.kernel.org/r/20240628205540.3098010-2-sean.anderson@linux.dev
Signed-off-by: Vinod Koul <vkoul@kernel.org>

authored by

Sean Anderson and committed by
Vinod Koul
687d6bcc 967969cf

+8 -6
+8 -6
drivers/phy/xilinx/phy-zynqmp.c
··· 80 80 81 81 /* Reference clock selection parameters */ 82 82 #define L0_Ln_REF_CLK_SEL(n) (0x2860 + (n) * 4) 83 - #define L0_REF_CLK_SEL_MASK 0x8f 83 + #define L0_REF_CLK_LCL_SEL BIT(7) 84 + #define L0_REF_CLK_SEL_MASK 0x9f 84 85 85 86 /* Calibration digital logic parameters */ 86 87 #define L3_TM_CALIB_DIG19 0xec4c ··· 350 349 PLL_FREQ_MASK, ssc->pll_ref_clk); 351 350 352 351 /* Enable lane clock sharing, if required */ 353 - if (gtr_phy->refclk != gtr_phy->lane) { 354 - /* Lane3 Ref Clock Selection Register */ 352 + if (gtr_phy->refclk == gtr_phy->lane) 353 + xpsgtr_clr_set(gtr_phy->dev, L0_Ln_REF_CLK_SEL(gtr_phy->lane), 354 + L0_REF_CLK_SEL_MASK, L0_REF_CLK_LCL_SEL); 355 + else 355 356 xpsgtr_clr_set(gtr_phy->dev, L0_Ln_REF_CLK_SEL(gtr_phy->lane), 356 357 L0_REF_CLK_SEL_MASK, 1 << gtr_phy->refclk); 357 - } 358 358 359 359 /* SSC step size [7:0] */ 360 360 xpsgtr_clr_set_phy(gtr_phy, L0_PLL_SS_STEP_SIZE_0_LSB, ··· 575 573 mutex_lock(&gtr_dev->gtr_mutex); 576 574 577 575 /* Configure and enable the clock when peripheral phy_init call */ 578 - if (clk_prepare_enable(gtr_dev->clk[gtr_phy->lane])) 576 + if (clk_prepare_enable(gtr_dev->clk[gtr_phy->refclk])) 579 577 goto out; 580 578 581 579 /* Skip initialization if not required. */ ··· 627 625 gtr_phy->skip_phy_init = false; 628 626 629 627 /* Ensure that disable clock only, which configure for lane */ 630 - clk_disable_unprepare(gtr_dev->clk[gtr_phy->lane]); 628 + clk_disable_unprepare(gtr_dev->clk[gtr_phy->refclk]); 631 629 632 630 return 0; 633 631 }