From: Karol Kolacinski <karol.kolacin...@intel.com>

If TS PLL fails to lock to the values from the capabilities, retry with safe
internal 25 MHz TCXO in nanosecond mode. This prevents PTP init fail and does
not disturb nominal initialization of the device.

Signed-off-by: Karol Kolacinski <karol.kolacin...@intel.com>
Signed-off-by: Ian Stokes <ian.sto...@intel.com>
---
 drivers/net/ice/base/ice_ptp_hw.c | 55 ++++++++++++++++++++-----------
 drivers/net/ice/base/ice_ptp_hw.h |  4 +--
 2 files changed, 38 insertions(+), 21 deletions(-)

diff --git a/drivers/net/ice/base/ice_ptp_hw.c 
b/drivers/net/ice/base/ice_ptp_hw.c
index 50fd90c7e2..22f7b86284 100644
--- a/drivers/net/ice/base/ice_ptp_hw.c
+++ b/drivers/net/ice/base/ice_ptp_hw.c
@@ -219,8 +219,8 @@ static const char *ice_clk_src_str(u8 clk_src)
  * time reference, enabling the PLL which drives the PTP hardware clock.
  */
 int
-ice_cfg_cgu_pll_e822(struct ice_hw *hw, enum ice_time_ref_freq clk_freq,
-                    enum ice_clk_src clk_src)
+ice_cfg_cgu_pll_e822(struct ice_hw *hw, enum ice_time_ref_freq *clk_freq,
+                    enum ice_clk_src *clk_src)
 {
        union tspll_ro_bwm_lf bwm_lf;
        union nac_cgu_dword19 dw19;
@@ -229,18 +229,18 @@ ice_cfg_cgu_pll_e822(struct ice_hw *hw, enum 
ice_time_ref_freq clk_freq,
        union nac_cgu_dword9 dw9;
        int err;
 
-       if (clk_freq >= NUM_ICE_TIME_REF_FREQ) {
-               ice_warn(hw, "Invalid TIME_REF frequency %u\n", clk_freq);
+       if (*clk_freq >= NUM_ICE_TIME_REF_FREQ) {
+               ice_warn(hw, "Invalid TIME_REF frequency %u\n", *clk_freq);
                return ICE_ERR_PARAM;
        }
 
-       if (clk_src >= NUM_ICE_CLK_SRC) {
-               ice_warn(hw, "Invalid clock source %u\n", clk_src);
+       if (*clk_src >= NUM_ICE_CLK_SRC) {
+               ice_warn(hw, "Invalid clock source %u\n", *clk_src);
                return ICE_ERR_PARAM;
        }
 
-       if (clk_src == ICE_CLK_SRC_TCX0 &&
-           clk_freq != ICE_TIME_REF_FREQ_25_000) {
+       if (*clk_src == ICE_CLK_SRC_TCX0 &&
+           *clk_freq != ICE_TIME_REF_FREQ_25_000) {
                ice_warn(hw, "TCX0 only supports 25 MHz frequency\n");
                return ICE_ERR_PARAM;
        }
@@ -258,7 +258,7 @@ ice_cfg_cgu_pll_e822(struct ice_hw *hw, enum 
ice_time_ref_freq clk_freq,
                return err;
 
        /* Log the current clock configuration */
-       ice_debug(hw, ICE_DBG_PTP, "Current CGU configuration -- %s, clk_src 
%s, clk_freq %s, PLL %s\n",
+       ice_debug(hw, ICE_DBG_PTP, "Current CGU configuration -- %s, clk_src 
%s, *clk_freq %s, PLL %s\n",
                  dw24.field.ts_pll_enable ? "enabled" : "disabled",
                  ice_clk_src_str(dw24.field.time_ref_sel),
                  ice_clk_freq_str(dw9.field.time_ref_freq_sel),
@@ -274,7 +274,7 @@ ice_cfg_cgu_pll_e822(struct ice_hw *hw, enum 
ice_time_ref_freq clk_freq,
        }
 
        /* Set the frequency */
-       dw9.field.time_ref_freq_sel = clk_freq;
+       dw9.field.time_ref_freq_sel = *clk_freq;
        err = ice_write_cgu_reg_e82x(hw, NAC_CGU_DWORD9, dw9.val);
        if (err)
                return err;
@@ -284,7 +284,7 @@ ice_cfg_cgu_pll_e822(struct ice_hw *hw, enum 
ice_time_ref_freq clk_freq,
        if (err)
                return err;
 
-       dw19.field.tspll_fbdiv_intgr = e822_cgu_params[clk_freq].feedback_div;
+       dw19.field.tspll_fbdiv_intgr = e822_cgu_params[*clk_freq].feedback_div;
        dw19.field.tspll_ndivratio = 1;
 
        err = ice_write_cgu_reg_e82x(hw, NAC_CGU_DWORD19, dw19.val);
@@ -296,7 +296,7 @@ ice_cfg_cgu_pll_e822(struct ice_hw *hw, enum 
ice_time_ref_freq clk_freq,
        if (err)
                return err;
 
-       dw22.field.time1588clk_div = e822_cgu_params[clk_freq].post_pll_div;
+       dw22.field.time1588clk_div = e822_cgu_params[*clk_freq].post_pll_div;
        dw22.field.time1588clk_sel_div2 = 0;
 
        err = ice_write_cgu_reg_e82x(hw, NAC_CGU_DWORD22, dw22.val);
@@ -308,9 +308,9 @@ ice_cfg_cgu_pll_e822(struct ice_hw *hw, enum 
ice_time_ref_freq clk_freq,
        if (err)
                return err;
 
-       dw24.field.ref1588_ck_div = e822_cgu_params[clk_freq].refclk_pre_div;
-       dw24.field.tspll_fbdiv_frac = e822_cgu_params[clk_freq].frac_n_div;
-       dw24.field.time_ref_sel = clk_src;
+       dw24.field.ref1588_ck_div = e822_cgu_params[*clk_freq].refclk_pre_div;
+       dw24.field.tspll_fbdiv_frac = e822_cgu_params[*clk_freq].frac_n_div;
+       dw24.field.time_ref_sel = *clk_src;
 
        err = ice_write_cgu_reg_e82x(hw, NAC_CGU_DWORD24, dw24.val);
        if (err)
@@ -342,6 +342,9 @@ ice_cfg_cgu_pll_e822(struct ice_hw *hw, enum 
ice_time_ref_freq clk_freq,
                  ice_clk_freq_str(dw9.field.time_ref_freq_sel),
                  bwm_lf.field.plllock_true_lock_cri ? "locked" : "unlocked");
 
+       *clk_freq = (enum ice_time_ref_freq)dw9.field.time_ref_freq_sel;
+       *clk_src = (enum ice_clk_src)dw24.field.time_ref_sel;
+
        return 0;
 }
 
@@ -762,11 +765,25 @@ static int ice_init_cgu_e82x(struct ice_hw *hw)
        if (ice_is_e825c(hw))
                err = ice_cfg_cgu_pll_e825c(hw, &time_ref_freq, &clk_src);
        else
-               err = ice_cfg_cgu_pll_e822(hw, time_ref_freq, clk_src);
-       if (err)
-               return err;
+               err = ice_cfg_cgu_pll_e822(hw, &time_ref_freq, &clk_src);
+       if (err) {
+               ice_warn(hw, "Failed to lock TS PLL to predefined frequency. 
Retrying with fallback frequency.\n");
 
-       return 0;
+               /* Try to lock to internal 25 MHz TCXO as a fallback */
+               time_ref_freq = ICE_TIME_REF_FREQ_25_000;
+               clk_src = ICE_CLK_SRC_TCX0;
+               if (ice_is_e825c(hw))
+                       err = ice_cfg_cgu_pll_e825c(hw, &time_ref_freq,
+                                                   &clk_src);
+               else
+                       err = ice_cfg_cgu_pll_e822(hw, &time_ref_freq,
+                                                  &clk_src);
+
+               if (err)
+                       ice_warn(hw, "Failed to lock TS PLL to fallback 
frequency.\n");
+       }
+
+       return err;
 }
 
 /**
diff --git a/drivers/net/ice/base/ice_ptp_hw.h 
b/drivers/net/ice/base/ice_ptp_hw.h
index f4110108e2..73d01a047e 100644
--- a/drivers/net/ice/base/ice_ptp_hw.h
+++ b/drivers/net/ice/base/ice_ptp_hw.h
@@ -165,8 +165,8 @@ int
 ice_ptp_read_port_capture_e822(struct ice_hw *hw, u8 port,
                               u64 *tx_ts, u64 *rx_ts);
 int
-ice_cfg_cgu_pll_e822(struct ice_hw *hw, enum ice_time_ref_freq clk_freq,
-                    enum ice_clk_src clk_src);
+ice_cfg_cgu_pll_e822(struct ice_hw *hw, enum ice_time_ref_freq *clk_freq,
+                    enum ice_clk_src *clk_src);
 int
 ice_ptp_write_port_cmd_e822(struct ice_hw *hw, u8 port,
                            enum ice_ptp_tmr_cmd cmd, bool lock_sbq);
-- 
2.43.0

Reply via email to