--- /dev/null
+From 687d6bccb28238fcfa65f7c1badfdfeac498c428 Mon Sep 17 00:00:00 2001
+From: Sean Anderson <sean.anderson@linux.dev>
+Date: Fri, 28 Jun 2024 16:55:36 -0400
+Subject: phy: zynqmp: Enable reference clock correctly
+
+From: Sean Anderson <sean.anderson@linux.dev>
+
+commit 687d6bccb28238fcfa65f7c1badfdfeac498c428 upstream.
+
+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>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/phy/xilinx/phy-zynqmp.c | 14 ++++++++------
+ 1 file changed, 8 insertions(+), 6 deletions(-)
+
+--- a/drivers/phy/xilinx/phy-zynqmp.c
++++ b/drivers/phy/xilinx/phy-zynqmp.c
+@@ -81,7 +81,8 @@
+
+ /* Reference clock selection parameters */
+ #define L0_Ln_REF_CLK_SEL(n) (0x2860 + (n) * 4)
+-#define L0_REF_CLK_SEL_MASK 0x8f
++#define L0_REF_CLK_LCL_SEL BIT(7)
++#define L0_REF_CLK_SEL_MASK 0x9f
+
+ /* Calibration digital logic parameters */
+ #define L3_TM_CALIB_DIG19 0xec4c
+@@ -396,11 +397,12 @@ static void xpsgtr_configure_pll(struct
+ PLL_FREQ_MASK, ssc->pll_ref_clk);
+
+ /* Enable lane clock sharing, if required */
+- if (gtr_phy->refclk != gtr_phy->lane) {
+- /* Lane3 Ref Clock Selection Register */
++ if (gtr_phy->refclk == gtr_phy->lane)
++ xpsgtr_clr_set(gtr_phy->dev, L0_Ln_REF_CLK_SEL(gtr_phy->lane),
++ L0_REF_CLK_SEL_MASK, L0_REF_CLK_LCL_SEL);
++ else
+ xpsgtr_clr_set(gtr_phy->dev, L0_Ln_REF_CLK_SEL(gtr_phy->lane),
+ L0_REF_CLK_SEL_MASK, 1 << gtr_phy->refclk);
+- }
+
+ /* SSC step size [7:0] */
+ xpsgtr_clr_set_phy(gtr_phy, L0_PLL_SS_STEP_SIZE_0_LSB,
+@@ -620,7 +622,7 @@ static int xpsgtr_phy_init(struct phy *p
+ mutex_lock(>r_dev->gtr_mutex);
+
+ /* Configure and enable the clock when peripheral phy_init call */
+- if (clk_prepare_enable(gtr_dev->clk[gtr_phy->lane]))
++ if (clk_prepare_enable(gtr_dev->clk[gtr_phy->refclk]))
+ goto out;
+
+ /* Skip initialization if not required. */
+@@ -672,7 +674,7 @@ static int xpsgtr_phy_exit(struct phy *p
+ gtr_phy->skip_phy_init = false;
+
+ /* Ensure that disable clock only, which configure for lane */
+- clk_disable_unprepare(gtr_dev->clk[gtr_phy->lane]);
++ clk_disable_unprepare(gtr_dev->clk[gtr_phy->refclk]);
+
+ return 0;
+ }