ice: add multiple TSPLL helpers

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>
This commit is contained in:
Karol Kolacinski
2025-06-23 17:30:00 -07:00
committed by Tony Nguyen
parent c6b4486a62
commit 5755b4c023

View 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);
}