]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
ice: add multiple TSPLL helpers
authorKarol Kolacinski <karol.kolacinski@intel.com>
Tue, 24 Jun 2025 00:30:00 +0000 (17:30 -0700)
committerTony Nguyen <anthony.l.nguyen@intel.com>
Thu, 26 Jun 2025 15:37:00 +0000 (08:37 -0700)
Add helpers for checking TSPLL params, disabling sticky bits,
configuring TSPLL and getting default clock frequency to simplify
the code flows.

Reviewed-by: Milena Olech <milena.olech@intel.com>
Signed-off-by: Karol Kolacinski <karol.kolacinski@intel.com>
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
drivers/net/ethernet/intel/ice/ice_tspll.c

index 8e1f522c579b7e4d440424fd8af4c7b7e198d067..e7b44e703d7c0966414e119f861ee1ab165d9293 100644 (file)
@@ -71,6 +71,58 @@ static const char *ice_tspll_clk_freq_str(enum ice_tspll_freq clk_freq)
        }
 }
 
+/**
+ * ice_tspll_default_freq - Return default frequency for a MAC type
+ * @mac_type: MAC type
+ *
+ * Return: default TSPLL frequency for a correct MAC type, -ERANGE otherwise.
+ */
+static enum ice_tspll_freq ice_tspll_default_freq(enum ice_mac_type mac_type)
+{
+       switch (mac_type) {
+       case ICE_MAC_GENERIC:
+               return ICE_TSPLL_FREQ_25_000;
+       case ICE_MAC_GENERIC_3K_E825:
+               return ICE_TSPLL_FREQ_156_250;
+       default:
+               return -ERANGE;
+       }
+}
+
+/**
+ * ice_tspll_check_params - Check if TSPLL params are correct
+ * @hw: Pointer to the HW struct
+ * @clk_freq: Clock frequency to program
+ * @clk_src: Clock source to select (TIME_REF or TCXO)
+ *
+ * Return: true if TSPLL params are correct, false otherwise.
+ */
+static bool ice_tspll_check_params(struct ice_hw *hw,
+                                  enum ice_tspll_freq clk_freq,
+                                  enum ice_clk_src clk_src)
+{
+       if (clk_freq >= NUM_ICE_TSPLL_FREQ) {
+               dev_warn(ice_hw_to_dev(hw), "Invalid TSPLL frequency %u\n",
+                        clk_freq);
+               return false;
+       }
+
+       if (clk_src >= NUM_ICE_CLK_SRC) {
+               dev_warn(ice_hw_to_dev(hw), "Invalid clock source %u\n",
+                        clk_src);
+               return false;
+       }
+
+       if ((hw->mac_type == ICE_MAC_GENERIC_3K_E825 ||
+            clk_src == ICE_CLK_SRC_TCXO) &&
+           clk_freq != ice_tspll_default_freq(hw->mac_type)) {
+               dev_warn(ice_hw_to_dev(hw), "Unsupported frequency for this clock source\n");
+               return false;
+       }
+
+       return true;
+}
+
 /**
  * ice_tspll_clk_src_str - Convert time_ref_src to string
  * @clk_src: Clock source
@@ -130,24 +182,6 @@ static int ice_tspll_cfg_e82x(struct ice_hw *hw, enum ice_tspll_freq clk_freq,
        u32 val, r9, r24;
        int err;
 
-       if (clk_freq >= NUM_ICE_TSPLL_FREQ) {
-               dev_warn(ice_hw_to_dev(hw), "Invalid TIME_REF frequency %u\n",
-                        clk_freq);
-               return -EINVAL;
-       }
-
-       if (clk_src >= NUM_ICE_CLK_SRC) {
-               dev_warn(ice_hw_to_dev(hw), "Invalid clock source %u\n",
-                        clk_src);
-               return -EINVAL;
-       }
-
-       if (clk_src == ICE_CLK_SRC_TCXO && clk_freq != ICE_TSPLL_FREQ_25_000) {
-               dev_warn(ice_hw_to_dev(hw),
-                        "TCXO only supports 25 MHz frequency\n");
-               return -EINVAL;
-       }
-
        err = ice_read_cgu_reg(hw, ICE_CGU_R9, &r9);
        if (err)
                return err;
@@ -306,23 +340,6 @@ static int ice_tspll_cfg_e825c(struct ice_hw *hw, enum ice_tspll_freq clk_freq,
        u32 val, r9, r23;
        int err;
 
-       if (clk_freq >= NUM_ICE_TSPLL_FREQ) {
-               dev_warn(ice_hw_to_dev(hw), "Invalid TIME_REF frequency %u\n",
-                        clk_freq);
-               return -EINVAL;
-       }
-
-       if (clk_src >= NUM_ICE_CLK_SRC) {
-               dev_warn(ice_hw_to_dev(hw), "Invalid clock source %u\n",
-                        clk_src);
-               return -EINVAL;
-       }
-
-       if (clk_freq != ICE_TSPLL_FREQ_156_250) {
-               dev_warn(ice_hw_to_dev(hw), "Adapter only supports 156.25 MHz frequency\n");
-               return -EINVAL;
-       }
-
        err = ice_read_cgu_reg(hw, ICE_CGU_R9, &r9);
        if (err)
                return err;
@@ -508,6 +525,52 @@ int ice_tspll_cfg_pps_out_e825c(struct ice_hw *hw, bool enable)
        return ice_write_cgu_reg(hw, ICE_CGU_R9, val);
 }
 
+/**
+ * ice_tspll_cfg - Configure the Clock Generation Unit TSPLL
+ * @hw: Pointer to the HW struct
+ * @clk_freq: Clock frequency to program
+ * @clk_src: Clock source to select (TIME_REF, or TCXO)
+ *
+ * Configure the Clock Generation Unit with the desired clock frequency and
+ * time reference, enabling the TSPLL which drives the PTP hardware clock.
+ *
+ * Return: 0 on success, -ERANGE on unsupported MAC type, other negative error
+ *         codes when failed to configure CGU.
+ */
+static int ice_tspll_cfg(struct ice_hw *hw, enum ice_tspll_freq clk_freq,
+                        enum ice_clk_src clk_src)
+{
+       switch (hw->mac_type) {
+       case ICE_MAC_GENERIC:
+               return ice_tspll_cfg_e82x(hw, clk_freq, clk_src);
+       case ICE_MAC_GENERIC_3K_E825:
+               return ice_tspll_cfg_e825c(hw, clk_freq, clk_src);
+       default:
+               return -ERANGE;
+       }
+}
+
+/**
+ * ice_tspll_dis_sticky_bits - disable TSPLL sticky bits
+ * @hw: Pointer to the HW struct
+ *
+ * Configure the Clock Generation Unit TSPLL sticky bits so they don't latch on
+ * losing TSPLL lock, but always show current state.
+ *
+ * Return: 0 on success, -ERANGE on unsupported MAC type.
+ */
+static int ice_tspll_dis_sticky_bits(struct ice_hw *hw)
+{
+       switch (hw->mac_type) {
+       case ICE_MAC_GENERIC:
+               return ice_tspll_dis_sticky_bits_e82x(hw);
+       case ICE_MAC_GENERIC_3K_E825:
+               return ice_tspll_dis_sticky_bits_e825c(hw);
+       default:
+               return -ERANGE;
+       }
+}
+
 /**
  * ice_tspll_init - Initialize TSPLL with settings from firmware
  * @hw: Pointer to the HW structure
@@ -519,25 +582,22 @@ int ice_tspll_cfg_pps_out_e825c(struct ice_hw *hw, bool enable)
 int ice_tspll_init(struct ice_hw *hw)
 {
        struct ice_ts_func_info *ts_info = &hw->func_caps.ts_func_info;
+       enum ice_tspll_freq tspll_freq;
+       enum ice_clk_src clk_src;
        int err;
 
-       /* Disable sticky lock detection so lock err reported is accurate. */
-       if (hw->mac_type == ICE_MAC_GENERIC_3K_E825)
-               err = ice_tspll_dis_sticky_bits_e825c(hw);
-       else
-               err = ice_tspll_dis_sticky_bits_e82x(hw);
+       tspll_freq = (enum ice_tspll_freq)ts_info->time_ref;
+       clk_src = (enum ice_clk_src)ts_info->clk_src;
+       if (!ice_tspll_check_params(hw, tspll_freq, clk_src))
+               return -EINVAL;
+
+       /* Disable sticky lock detection so lock status reported is accurate */
+       err = ice_tspll_dis_sticky_bits(hw);
        if (err)
                return err;
 
        /* Configure the TSPLL using the parameters from the function
         * capabilities.
         */
-       if (hw->mac_type == ICE_MAC_GENERIC_3K_E825)
-               err = ice_tspll_cfg_e825c(hw, ts_info->time_ref,
-                                         (enum ice_clk_src)ts_info->clk_src);
-       else
-               err = ice_tspll_cfg_e82x(hw, ts_info->time_ref,
-                                        (enum ice_clk_src)ts_info->clk_src);
-
-       return err;
+       return ice_tspll_cfg(hw, tspll_freq, clk_src);
 }