mirror of
https://github.com/torvalds/linux.git
synced 2026-06-04 20:46:48 +02:00
Merge branch '100GbE' of git://git.kernel.org/pub/scm/linux/kernel/git/tnguy/next-queue
Tony Nguyen says: ==================== ice: remaining TSPLL cleanups These are the remaining patches from the "ice: Separate TSPLL from PTP and cleanup" series [1] with control flow macros removed. What remains are cleanups and some minor improvements. [1] https://lore.kernel.org/netdev/20250618174231.3100231-1-anthony.l.nguyen@intel.com/ * '100GbE' of git://git.kernel.org/pub/scm/linux/kernel/git/tnguy/next-queue: ice: default to TIME_REF instead of TXCO on E825-C ice: move TSPLL init calls to ice_ptp.c ice: fall back to TCXO on TSPLL lock fail ice: wait before enabling TSPLL ice: add multiple TSPLL helpers ice: use bitfields instead of unions for CGU regs ice: read TSPLL registers again before reporting status ice: clear time_sync_en field for E825-C during reprogramming ==================== Link: https://patch.msgid.link/20250626162921.1173068-1-anthony.l.nguyen@intel.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
commit
8c72b2a2ed
|
|
@ -2302,7 +2302,7 @@ ice_parse_1588_func_caps(struct ice_hw *hw, struct ice_hw_func_caps *func_p,
|
|||
info->clk_src = ((number & ICE_TS_CLK_SRC_M) != 0);
|
||||
} else {
|
||||
info->clk_freq = ICE_TSPLL_FREQ_156_250;
|
||||
info->clk_src = ICE_CLK_SRC_TCXO;
|
||||
info->clk_src = ICE_CLK_SRC_TIME_REF;
|
||||
}
|
||||
|
||||
if (info->clk_freq < NUM_ICE_TSPLL_FREQ) {
|
||||
|
|
|
|||
|
|
@ -39,194 +39,46 @@
|
|||
#define FEC_RECEIVER_ID_PCS0 (0x33 << FEC_RECV_ID_SHIFT)
|
||||
#define FEC_RECEIVER_ID_PCS1 (0x34 << FEC_RECV_ID_SHIFT)
|
||||
|
||||
#define ICE_CGU_R9 0x24
|
||||
union ice_cgu_r9 {
|
||||
struct {
|
||||
u32 time_ref_freq_sel : 3;
|
||||
u32 clk_eref1_en : 1;
|
||||
u32 clk_eref0_en : 1;
|
||||
u32 time_ref_en : 1;
|
||||
u32 time_sync_en : 1;
|
||||
u32 one_pps_out_en : 1;
|
||||
u32 clk_ref_synce_en : 1;
|
||||
u32 clk_synce1_en : 1;
|
||||
u32 clk_synce0_en : 1;
|
||||
u32 net_clk_ref1_en : 1;
|
||||
u32 net_clk_ref0_en : 1;
|
||||
u32 clk_synce1_amp : 2;
|
||||
u32 misc6 : 1;
|
||||
u32 clk_synce0_amp : 2;
|
||||
u32 one_pps_out_amp : 2;
|
||||
u32 misc24 : 12;
|
||||
};
|
||||
u32 val;
|
||||
};
|
||||
#define ICE_CGU_R9 0x24
|
||||
#define ICE_CGU_R9_TIME_REF_FREQ_SEL GENMASK(2, 0)
|
||||
#define ICE_CGU_R9_CLK_EREF0_EN BIT(4)
|
||||
#define ICE_CGU_R9_TIME_REF_EN BIT(5)
|
||||
#define ICE_CGU_R9_TIME_SYNC_EN BIT(6)
|
||||
#define ICE_CGU_R9_ONE_PPS_OUT_EN BIT(7)
|
||||
#define ICE_CGU_R9_ONE_PPS_OUT_AMP GENMASK(19, 18)
|
||||
|
||||
#define ICE_CGU_R16 0x40
|
||||
union ice_cgu_r16 {
|
||||
struct {
|
||||
u32 synce_remndr : 6;
|
||||
u32 synce_phlmt_en : 1;
|
||||
u32 misc13 : 17;
|
||||
u32 ck_refclkfreq : 8;
|
||||
};
|
||||
u32 val;
|
||||
};
|
||||
#define ICE_CGU_R16 0x40
|
||||
#define ICE_CGU_R16_TSPLL_CK_REFCLKFREQ GENMASK(31, 24)
|
||||
|
||||
#define ICE_CGU_R19 0x4c
|
||||
union ice_cgu_r19_e82x {
|
||||
struct {
|
||||
u32 fbdiv_intgr : 8;
|
||||
u32 fdpll_ulck_thr : 5;
|
||||
u32 misc15 : 3;
|
||||
u32 ndivratio : 4;
|
||||
u32 tspll_iref_ndivratio : 3;
|
||||
u32 misc19 : 1;
|
||||
u32 japll_ndivratio : 4;
|
||||
u32 japll_iref_ndivratio : 3;
|
||||
u32 misc27 : 1;
|
||||
};
|
||||
u32 val;
|
||||
};
|
||||
#define ICE_CGU_R19 0x4C
|
||||
#define ICE_CGU_R19_TSPLL_FBDIV_INTGR_E82X GENMASK(7, 0)
|
||||
#define ICE_CGU_R19_TSPLL_FBDIV_INTGR_E825 GENMASK(9, 0)
|
||||
#define ICE_CGU_R19_TSPLL_NDIVRATIO GENMASK(19, 16)
|
||||
|
||||
union ice_cgu_r19_e825 {
|
||||
struct {
|
||||
u32 tspll_fbdiv_intgr : 10;
|
||||
u32 fdpll_ulck_thr : 5;
|
||||
u32 misc15 : 1;
|
||||
u32 tspll_ndivratio : 4;
|
||||
u32 tspll_iref_ndivratio : 3;
|
||||
u32 misc19 : 1;
|
||||
u32 japll_ndivratio : 4;
|
||||
u32 japll_postdiv_pdivratio : 3;
|
||||
u32 misc27 : 1;
|
||||
};
|
||||
u32 val;
|
||||
};
|
||||
#define ICE_CGU_R22 0x58
|
||||
#define ICE_CGU_R22_TIME1588CLK_DIV GENMASK(23, 20)
|
||||
#define ICE_CGU_R22_TIME1588CLK_DIV2 BIT(30)
|
||||
|
||||
#define ICE_CGU_R22 0x58
|
||||
union ice_cgu_r22 {
|
||||
struct {
|
||||
u32 fdpll_frac_div_out_nc : 2;
|
||||
u32 fdpll_lock_int_for : 1;
|
||||
u32 synce_hdov_int_for : 1;
|
||||
u32 synce_lock_int_for : 1;
|
||||
u32 fdpll_phlead_slip_nc : 1;
|
||||
u32 fdpll_acc1_ovfl_nc : 1;
|
||||
u32 fdpll_acc2_ovfl_nc : 1;
|
||||
u32 synce_status_nc : 6;
|
||||
u32 fdpll_acc1f_ovfl : 1;
|
||||
u32 misc18 : 1;
|
||||
u32 fdpllclk_div : 4;
|
||||
u32 time1588clk_div : 4;
|
||||
u32 synceclk_div : 4;
|
||||
u32 synceclk_sel_div2 : 1;
|
||||
u32 fdpllclk_sel_div2 : 1;
|
||||
u32 time1588clk_sel_div2 : 1;
|
||||
u32 misc3 : 1;
|
||||
};
|
||||
u32 val;
|
||||
};
|
||||
#define ICE_CGU_R23 0x5C
|
||||
#define ICE_CGU_R24 0x60
|
||||
#define ICE_CGU_R24_FBDIV_FRAC GENMASK(21, 0)
|
||||
#define ICE_CGU_R23_R24_TSPLL_ENABLE BIT(24)
|
||||
#define ICE_CGU_R23_R24_REF1588_CK_DIV GENMASK(30, 27)
|
||||
#define ICE_CGU_R23_R24_TIME_REF_SEL BIT(31)
|
||||
|
||||
#define ICE_CGU_R23 0x5C
|
||||
union ice_cgu_r23 {
|
||||
struct {
|
||||
u32 cgupll_fbdiv_intgr : 10;
|
||||
u32 ux56pll_fbdiv_intgr : 10;
|
||||
u32 misc20 : 4;
|
||||
u32 ts_pll_enable : 1;
|
||||
u32 time_sync_tspll_align_sel : 1;
|
||||
u32 ext_synce_sel : 1;
|
||||
u32 ref1588_ck_div : 4;
|
||||
u32 time_ref_sel : 1;
|
||||
#define ICE_CGU_BW_TDC 0x31C
|
||||
#define ICE_CGU_BW_TDC_PLLLOCK_SEL GENMASK(30, 29)
|
||||
|
||||
};
|
||||
u32 val;
|
||||
};
|
||||
#define ICE_CGU_RO_LOCK 0x3F0
|
||||
#define ICE_CGU_RO_LOCK_TRUE_LOCK BIT(12)
|
||||
#define ICE_CGU_RO_LOCK_UNLOCK BIT(13)
|
||||
|
||||
#define ICE_CGU_R24 0x60
|
||||
union ice_cgu_r24 {
|
||||
struct {
|
||||
u32 fbdiv_frac : 22;
|
||||
u32 misc20 : 2;
|
||||
u32 ts_pll_enable : 1;
|
||||
u32 time_sync_tspll_align_sel : 1;
|
||||
u32 ext_synce_sel : 1;
|
||||
u32 ref1588_ck_div : 4;
|
||||
u32 time_ref_sel : 1;
|
||||
};
|
||||
u32 val;
|
||||
};
|
||||
#define ICE_CGU_CNTR_BIST 0x344
|
||||
#define ICE_CGU_CNTR_BIST_PLLLOCK_SEL_0 BIT(15)
|
||||
#define ICE_CGU_CNTR_BIST_PLLLOCK_SEL_1 BIT(16)
|
||||
|
||||
#define TSPLL_CNTR_BIST_SETTINGS 0x344
|
||||
union tspll_cntr_bist_settings {
|
||||
struct {
|
||||
u32 i_irefgen_settling_time_cntr_7_0 : 8;
|
||||
u32 i_irefgen_settling_time_ro_standby_1_0 : 2;
|
||||
u32 reserved195 : 5;
|
||||
u32 i_plllock_sel_0 : 1;
|
||||
u32 i_plllock_sel_1 : 1;
|
||||
u32 i_plllock_cnt_6_0 : 7;
|
||||
u32 i_plllock_cnt_10_7 : 4;
|
||||
u32 reserved200 : 4;
|
||||
};
|
||||
u32 val;
|
||||
};
|
||||
|
||||
#define TSPLL_RO_BWM_LF 0x370
|
||||
union tspll_ro_bwm_lf {
|
||||
struct {
|
||||
u32 bw_freqov_high_cri_7_0 : 8;
|
||||
u32 bw_freqov_high_cri_9_8 : 2;
|
||||
u32 biascaldone_cri : 1;
|
||||
u32 plllock_gain_tran_cri : 1;
|
||||
u32 plllock_true_lock_cri : 1;
|
||||
u32 pllunlock_flag_cri : 1;
|
||||
u32 afcerr_cri : 1;
|
||||
u32 afcdone_cri : 1;
|
||||
u32 feedfwrdgain_cal_cri_7_0 : 8;
|
||||
u32 m2fbdivmod_cri_7_0 : 8;
|
||||
};
|
||||
u32 val;
|
||||
};
|
||||
|
||||
#define TSPLL_RO_LOCK_E825C 0x3f0
|
||||
union tspll_ro_lock_e825c {
|
||||
struct {
|
||||
u32 bw_freqov_high_cri_7_0 : 8;
|
||||
u32 bw_freqov_high_cri_9_8 : 2;
|
||||
u32 reserved455 : 1;
|
||||
u32 plllock_gain_tran_cri : 1;
|
||||
u32 plllock_true_lock_cri : 1;
|
||||
u32 pllunlock_flag_cri : 1;
|
||||
u32 afcerr_cri : 1;
|
||||
u32 afcdone_cri : 1;
|
||||
u32 feedfwrdgain_cal_cri_7_0 : 8;
|
||||
u32 reserved462 : 8;
|
||||
};
|
||||
u32 val;
|
||||
};
|
||||
|
||||
#define TSPLL_BW_TDC_E825C 0x31c
|
||||
union tspll_bw_tdc_e825c {
|
||||
struct {
|
||||
u32 i_tdc_offset_lock_1_0 : 2;
|
||||
u32 i_bbthresh1_2_0 : 3;
|
||||
u32 i_bbthresh2_2_0 : 3;
|
||||
u32 i_tdcsel_1_0 : 2;
|
||||
u32 i_tdcovccorr_en_h : 1;
|
||||
u32 i_divretimeren : 1;
|
||||
u32 i_bw_ampmeas_window : 1;
|
||||
u32 i_bw_lowerbound_2_0 : 3;
|
||||
u32 i_bw_upperbound_2_0 : 3;
|
||||
u32 i_bw_mode_1_0 : 2;
|
||||
u32 i_ft_mode_sel_2_0 : 3;
|
||||
u32 i_bwphase_4_0 : 5;
|
||||
u32 i_plllock_sel_1_0 : 2;
|
||||
u32 i_afc_divratio : 1;
|
||||
};
|
||||
u32 val;
|
||||
};
|
||||
#define ICE_CGU_RO_BWM_LF 0x370
|
||||
#define ICE_CGU_RO_BWM_LF_TRUE_LOCK BIT(12)
|
||||
|
||||
int ice_init_hw(struct ice_hw *hw);
|
||||
void ice_deinit_hw(struct ice_hw *hw);
|
||||
|
|
|
|||
|
|
@ -2892,6 +2892,10 @@ static int ice_ptp_rebuild_owner(struct ice_pf *pf)
|
|||
if (err)
|
||||
return err;
|
||||
|
||||
err = ice_tspll_init(hw);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
/* Acquire the global hardware lock */
|
||||
if (!ice_ptp_lock(hw)) {
|
||||
err = -EBUSY;
|
||||
|
|
@ -3059,6 +3063,13 @@ static int ice_ptp_init_owner(struct ice_pf *pf)
|
|||
return err;
|
||||
}
|
||||
|
||||
err = ice_tspll_init(hw);
|
||||
if (err) {
|
||||
dev_err(ice_pf_to_dev(pf), "Failed to initialize CGU, status %d\n",
|
||||
err);
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Acquire the global hardware lock */
|
||||
if (!ice_ptp_lock(hw)) {
|
||||
err = -EBUSY;
|
||||
|
|
|
|||
|
|
@ -2115,20 +2115,6 @@ int ice_start_phy_timer_eth56g(struct ice_hw *hw, u8 port)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* ice_ptp_init_phc_e825 - Perform E825 specific PHC initialization
|
||||
* @hw: pointer to HW struct
|
||||
*
|
||||
* Perform E825-specific PTP hardware clock initialization steps.
|
||||
*
|
||||
* Return: 0 on success, negative error code otherwise.
|
||||
*/
|
||||
static int ice_ptp_init_phc_e825(struct ice_hw *hw)
|
||||
{
|
||||
/* Initialize the Clock Generation Unit */
|
||||
return ice_tspll_init(hw);
|
||||
}
|
||||
|
||||
/**
|
||||
* ice_ptp_read_tx_hwtstamp_status_eth56g - Get TX timestamp status
|
||||
* @hw: pointer to the HW struct
|
||||
|
|
@ -2788,7 +2774,6 @@ static int ice_ptp_set_vernier_wl(struct ice_hw *hw)
|
|||
*/
|
||||
static int ice_ptp_init_phc_e82x(struct ice_hw *hw)
|
||||
{
|
||||
int err;
|
||||
u32 val;
|
||||
|
||||
/* Enable reading switch and PHY registers over the sideband queue */
|
||||
|
|
@ -2798,11 +2783,6 @@ static int ice_ptp_init_phc_e82x(struct ice_hw *hw)
|
|||
val |= (PF_SB_REM_DEV_CTL_SWITCH_READ | PF_SB_REM_DEV_CTL_PHY0);
|
||||
wr32(hw, PF_SB_REM_DEV_CTL, val);
|
||||
|
||||
/* Initialize the Clock Generation Unit */
|
||||
err = ice_tspll_init(hw);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
/* Set window length for all the ports */
|
||||
return ice_ptp_set_vernier_wl(hw);
|
||||
}
|
||||
|
|
@ -5584,7 +5564,7 @@ int ice_ptp_init_phc(struct ice_hw *hw)
|
|||
case ICE_MAC_GENERIC:
|
||||
return ice_ptp_init_phc_e82x(hw);
|
||||
case ICE_MAC_GENERIC_3K_E825:
|
||||
return ice_ptp_init_phc_e825(hw);
|
||||
return 0;
|
||||
default:
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -127,120 +179,121 @@ static void ice_tspll_log_cfg(struct ice_hw *hw, bool enable, u8 clk_src,
|
|||
static int ice_tspll_cfg_e82x(struct ice_hw *hw, enum ice_tspll_freq clk_freq,
|
||||
enum ice_clk_src clk_src)
|
||||
{
|
||||
union tspll_ro_bwm_lf bwm_lf;
|
||||
union ice_cgu_r19_e82x dw19;
|
||||
union ice_cgu_r22 dw22;
|
||||
union ice_cgu_r24 dw24;
|
||||
union ice_cgu_r9 dw9;
|
||||
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, &dw9.val);
|
||||
err = ice_read_cgu_reg(hw, ICE_CGU_R9, &r9);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = ice_read_cgu_reg(hw, ICE_CGU_R24, &dw24.val);
|
||||
err = ice_read_cgu_reg(hw, ICE_CGU_R24, &r24);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = ice_read_cgu_reg(hw, TSPLL_RO_BWM_LF, &bwm_lf.val);
|
||||
err = ice_read_cgu_reg(hw, ICE_CGU_RO_BWM_LF, &val);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
ice_tspll_log_cfg(hw, dw24.ts_pll_enable, dw24.time_ref_sel,
|
||||
dw9.time_ref_freq_sel, bwm_lf.plllock_true_lock_cri,
|
||||
ice_tspll_log_cfg(hw, !!FIELD_GET(ICE_CGU_R23_R24_TSPLL_ENABLE, r24),
|
||||
FIELD_GET(ICE_CGU_R23_R24_TIME_REF_SEL, r24),
|
||||
FIELD_GET(ICE_CGU_R9_TIME_REF_FREQ_SEL, r9),
|
||||
!!FIELD_GET(ICE_CGU_RO_BWM_LF_TRUE_LOCK, val),
|
||||
false);
|
||||
|
||||
/* Disable the PLL before changing the clock source or frequency */
|
||||
if (dw24.ts_pll_enable) {
|
||||
dw24.ts_pll_enable = 0;
|
||||
if (FIELD_GET(ICE_CGU_R23_R24_TSPLL_ENABLE, r24)) {
|
||||
r24 &= ~ICE_CGU_R23_R24_TSPLL_ENABLE;
|
||||
|
||||
err = ice_write_cgu_reg(hw, ICE_CGU_R24, dw24.val);
|
||||
err = ice_write_cgu_reg(hw, ICE_CGU_R24, r24);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Set the frequency */
|
||||
dw9.time_ref_freq_sel = clk_freq;
|
||||
err = ice_write_cgu_reg(hw, ICE_CGU_R9, dw9.val);
|
||||
r9 &= ~ICE_CGU_R9_TIME_REF_FREQ_SEL;
|
||||
r9 |= FIELD_PREP(ICE_CGU_R9_TIME_REF_FREQ_SEL, clk_freq);
|
||||
err = ice_write_cgu_reg(hw, ICE_CGU_R9, r9);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
/* Configure the TSPLL feedback divisor */
|
||||
err = ice_read_cgu_reg(hw, ICE_CGU_R19, &dw19.val);
|
||||
err = ice_read_cgu_reg(hw, ICE_CGU_R19, &val);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
dw19.fbdiv_intgr = e82x_tspll_params[clk_freq].feedback_div;
|
||||
dw19.ndivratio = 1;
|
||||
val &= ~(ICE_CGU_R19_TSPLL_FBDIV_INTGR_E82X | ICE_CGU_R19_TSPLL_NDIVRATIO);
|
||||
val |= FIELD_PREP(ICE_CGU_R19_TSPLL_FBDIV_INTGR_E82X,
|
||||
e82x_tspll_params[clk_freq].feedback_div);
|
||||
val |= FIELD_PREP(ICE_CGU_R19_TSPLL_NDIVRATIO, 1);
|
||||
|
||||
err = ice_write_cgu_reg(hw, ICE_CGU_R19, dw19.val);
|
||||
err = ice_write_cgu_reg(hw, ICE_CGU_R19, val);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
/* Configure the TSPLL post divisor */
|
||||
err = ice_read_cgu_reg(hw, ICE_CGU_R22, &dw22.val);
|
||||
err = ice_read_cgu_reg(hw, ICE_CGU_R22, &val);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
dw22.time1588clk_div = e82x_tspll_params[clk_freq].post_pll_div;
|
||||
dw22.time1588clk_sel_div2 = 0;
|
||||
val &= ~(ICE_CGU_R22_TIME1588CLK_DIV |
|
||||
ICE_CGU_R22_TIME1588CLK_DIV2);
|
||||
val |= FIELD_PREP(ICE_CGU_R22_TIME1588CLK_DIV,
|
||||
e82x_tspll_params[clk_freq].post_pll_div);
|
||||
|
||||
err = ice_write_cgu_reg(hw, ICE_CGU_R22, dw22.val);
|
||||
err = ice_write_cgu_reg(hw, ICE_CGU_R22, val);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
/* Configure the TSPLL pre divisor and clock source */
|
||||
err = ice_read_cgu_reg(hw, ICE_CGU_R24, &dw24.val);
|
||||
err = ice_read_cgu_reg(hw, ICE_CGU_R24, &r24);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
dw24.ref1588_ck_div = e82x_tspll_params[clk_freq].refclk_pre_div;
|
||||
dw24.fbdiv_frac = e82x_tspll_params[clk_freq].frac_n_div;
|
||||
dw24.time_ref_sel = clk_src;
|
||||
r24 &= ~(ICE_CGU_R23_R24_REF1588_CK_DIV | ICE_CGU_R24_FBDIV_FRAC |
|
||||
ICE_CGU_R23_R24_TIME_REF_SEL);
|
||||
r24 |= FIELD_PREP(ICE_CGU_R23_R24_REF1588_CK_DIV,
|
||||
e82x_tspll_params[clk_freq].refclk_pre_div);
|
||||
r24 |= FIELD_PREP(ICE_CGU_R24_FBDIV_FRAC,
|
||||
e82x_tspll_params[clk_freq].frac_n_div);
|
||||
r24 |= FIELD_PREP(ICE_CGU_R23_R24_TIME_REF_SEL, clk_src);
|
||||
|
||||
err = ice_write_cgu_reg(hw, ICE_CGU_R24, dw24.val);
|
||||
err = ice_write_cgu_reg(hw, ICE_CGU_R24, r24);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
/* Wait to ensure everything is stable */
|
||||
usleep_range(10, 20);
|
||||
|
||||
/* Finally, enable the PLL */
|
||||
dw24.ts_pll_enable = 1;
|
||||
r24 |= ICE_CGU_R23_R24_TSPLL_ENABLE;
|
||||
|
||||
err = ice_write_cgu_reg(hw, ICE_CGU_R24, dw24.val);
|
||||
err = ice_write_cgu_reg(hw, ICE_CGU_R24, r24);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
/* Wait to verify if the PLL locks */
|
||||
usleep_range(1000, 5000);
|
||||
/* Wait at least 1 ms to verify if the PLL locks */
|
||||
usleep_range(USEC_PER_MSEC, 2 * USEC_PER_MSEC);
|
||||
|
||||
err = ice_read_cgu_reg(hw, TSPLL_RO_BWM_LF, &bwm_lf.val);
|
||||
err = ice_read_cgu_reg(hw, ICE_CGU_RO_BWM_LF, &val);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (!bwm_lf.plllock_true_lock_cri) {
|
||||
dev_warn(ice_hw_to_dev(hw), "TSPLL failed to lock\n");
|
||||
if (!(val & ICE_CGU_RO_BWM_LF_TRUE_LOCK)) {
|
||||
dev_warn(ice_hw_to_dev(hw), "CGU PLL failed to lock\n");
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
ice_tspll_log_cfg(hw, dw24.ts_pll_enable, clk_src, clk_freq, true,
|
||||
true);
|
||||
err = ice_read_cgu_reg(hw, ICE_CGU_R9, &r9);
|
||||
if (err)
|
||||
return err;
|
||||
err = ice_read_cgu_reg(hw, ICE_CGU_R24, &r24);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
ice_tspll_log_cfg(hw, !!FIELD_GET(ICE_CGU_R23_R24_TSPLL_ENABLE, r24),
|
||||
FIELD_GET(ICE_CGU_R23_R24_TIME_REF_SEL, r24),
|
||||
FIELD_GET(ICE_CGU_R9_TIME_REF_FREQ_SEL, r9),
|
||||
true, true);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -256,18 +309,17 @@ static int ice_tspll_cfg_e82x(struct ice_hw *hw, enum ice_tspll_freq clk_freq,
|
|||
*/
|
||||
static int ice_tspll_dis_sticky_bits_e82x(struct ice_hw *hw)
|
||||
{
|
||||
union tspll_cntr_bist_settings cntr_bist;
|
||||
u32 val;
|
||||
int err;
|
||||
|
||||
err = ice_read_cgu_reg(hw, TSPLL_CNTR_BIST_SETTINGS, &cntr_bist.val);
|
||||
err = ice_read_cgu_reg(hw, ICE_CGU_CNTR_BIST, &val);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
/* Disable sticky lock detection so lock err reported is accurate */
|
||||
cntr_bist.i_plllock_sel_0 = 0;
|
||||
cntr_bist.i_plllock_sel_1 = 0;
|
||||
val &= ~(ICE_CGU_CNTR_BIST_PLLLOCK_SEL_0 |
|
||||
ICE_CGU_CNTR_BIST_PLLLOCK_SEL_1);
|
||||
|
||||
return ice_write_cgu_reg(hw, TSPLL_CNTR_BIST_SETTINGS, cntr_bist.val);
|
||||
return ice_write_cgu_reg(hw, ICE_CGU_CNTR_BIST, val);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -288,115 +340,106 @@ static int ice_tspll_dis_sticky_bits_e82x(struct ice_hw *hw)
|
|||
static int ice_tspll_cfg_e825c(struct ice_hw *hw, enum ice_tspll_freq clk_freq,
|
||||
enum ice_clk_src clk_src)
|
||||
{
|
||||
union tspll_ro_lock_e825c ro_lock;
|
||||
union ice_cgu_r19_e825 dw19;
|
||||
union ice_cgu_r16 dw16;
|
||||
union ice_cgu_r23 dw23;
|
||||
union ice_cgu_r22 dw22;
|
||||
union ice_cgu_r9 dw9;
|
||||
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, &dw9.val);
|
||||
err = ice_read_cgu_reg(hw, ICE_CGU_R9, &r9);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = ice_read_cgu_reg(hw, ICE_CGU_R16, &dw16.val);
|
||||
err = ice_read_cgu_reg(hw, ICE_CGU_R23, &r23);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = ice_read_cgu_reg(hw, ICE_CGU_R23, &dw23.val);
|
||||
err = ice_read_cgu_reg(hw, ICE_CGU_RO_LOCK, &val);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = ice_read_cgu_reg(hw, TSPLL_RO_LOCK_E825C, &ro_lock.val);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
ice_tspll_log_cfg(hw, dw23.ts_pll_enable, dw23.time_ref_sel,
|
||||
dw9.time_ref_freq_sel,
|
||||
ro_lock.plllock_true_lock_cri, false);
|
||||
ice_tspll_log_cfg(hw, !!FIELD_GET(ICE_CGU_R23_R24_TSPLL_ENABLE, r23),
|
||||
FIELD_GET(ICE_CGU_R23_R24_TIME_REF_SEL, r23),
|
||||
FIELD_GET(ICE_CGU_R9_TIME_REF_FREQ_SEL, r9),
|
||||
!!FIELD_GET(ICE_CGU_RO_LOCK_TRUE_LOCK, val),
|
||||
false);
|
||||
|
||||
/* Disable the PLL before changing the clock source or frequency */
|
||||
if (dw23.ts_pll_enable) {
|
||||
dw23.ts_pll_enable = 0;
|
||||
if (FIELD_GET(ICE_CGU_R23_R24_TSPLL_ENABLE, r23)) {
|
||||
r23 &= ~ICE_CGU_R23_R24_TSPLL_ENABLE;
|
||||
|
||||
err = ice_write_cgu_reg(hw, ICE_CGU_R23, dw23.val);
|
||||
err = ice_write_cgu_reg(hw, ICE_CGU_R23, r23);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Set the frequency */
|
||||
dw9.time_ref_freq_sel = clk_freq;
|
||||
if (FIELD_GET(ICE_CGU_R9_TIME_SYNC_EN, r9)) {
|
||||
r9 &= ~ICE_CGU_R9_TIME_SYNC_EN;
|
||||
|
||||
/* Enable the correct receiver */
|
||||
if (clk_src == ICE_CLK_SRC_TCXO) {
|
||||
dw9.time_ref_en = 0;
|
||||
dw9.clk_eref0_en = 1;
|
||||
} else {
|
||||
dw9.time_ref_en = 1;
|
||||
dw9.clk_eref0_en = 0;
|
||||
err = ice_write_cgu_reg(hw, ICE_CGU_R9, r9);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
err = ice_write_cgu_reg(hw, ICE_CGU_R9, dw9.val);
|
||||
|
||||
/* Set the frequency and enable the correct receiver */
|
||||
r9 &= ~(ICE_CGU_R9_TIME_REF_FREQ_SEL | ICE_CGU_R9_CLK_EREF0_EN |
|
||||
ICE_CGU_R9_TIME_REF_EN);
|
||||
r9 |= FIELD_PREP(ICE_CGU_R9_TIME_REF_FREQ_SEL, clk_freq);
|
||||
if (clk_src == ICE_CLK_SRC_TCXO)
|
||||
r9 |= ICE_CGU_R9_CLK_EREF0_EN;
|
||||
else
|
||||
r9 |= ICE_CGU_R9_TIME_REF_EN;
|
||||
r9 |= ICE_CGU_R9_TIME_SYNC_EN;
|
||||
err = ice_write_cgu_reg(hw, ICE_CGU_R9, r9);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
/* Choose the referenced frequency */
|
||||
dw16.ck_refclkfreq = ICE_TSPLL_CK_REFCLKFREQ_E825;
|
||||
err = ice_write_cgu_reg(hw, ICE_CGU_R16, dw16.val);
|
||||
err = ice_read_cgu_reg(hw, ICE_CGU_R16, &val);
|
||||
if (err)
|
||||
return err;
|
||||
val &= ~ICE_CGU_R16_TSPLL_CK_REFCLKFREQ;
|
||||
val |= FIELD_PREP(ICE_CGU_R16_TSPLL_CK_REFCLKFREQ,
|
||||
ICE_TSPLL_CK_REFCLKFREQ_E825);
|
||||
err = ice_write_cgu_reg(hw, ICE_CGU_R16, val);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
/* Configure the TSPLL feedback divisor */
|
||||
err = ice_read_cgu_reg(hw, ICE_CGU_R19, &dw19.val);
|
||||
err = ice_read_cgu_reg(hw, ICE_CGU_R19, &val);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
dw19.tspll_fbdiv_intgr = ICE_TSPLL_FBDIV_INTGR_E825;
|
||||
dw19.tspll_ndivratio = ICE_TSPLL_NDIVRATIO_E825;
|
||||
val &= ~(ICE_CGU_R19_TSPLL_FBDIV_INTGR_E825 |
|
||||
ICE_CGU_R19_TSPLL_NDIVRATIO);
|
||||
val |= FIELD_PREP(ICE_CGU_R19_TSPLL_FBDIV_INTGR_E825,
|
||||
ICE_TSPLL_FBDIV_INTGR_E825);
|
||||
val |= FIELD_PREP(ICE_CGU_R19_TSPLL_NDIVRATIO,
|
||||
ICE_TSPLL_NDIVRATIO_E825);
|
||||
|
||||
err = ice_write_cgu_reg(hw, ICE_CGU_R19, dw19.val);
|
||||
err = ice_write_cgu_reg(hw, ICE_CGU_R19, val);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
/* Configure the TSPLL post divisor */
|
||||
err = ice_read_cgu_reg(hw, ICE_CGU_R22, &dw22.val);
|
||||
/* Configure the TSPLL post divisor, these two are constant */
|
||||
err = ice_read_cgu_reg(hw, ICE_CGU_R22, &val);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
/* These two are constant for E825C */
|
||||
dw22.time1588clk_div = 5;
|
||||
dw22.time1588clk_sel_div2 = 0;
|
||||
val &= ~(ICE_CGU_R22_TIME1588CLK_DIV |
|
||||
ICE_CGU_R22_TIME1588CLK_DIV2);
|
||||
val |= FIELD_PREP(ICE_CGU_R22_TIME1588CLK_DIV, 5);
|
||||
|
||||
err = ice_write_cgu_reg(hw, ICE_CGU_R22, dw22.val);
|
||||
err = ice_write_cgu_reg(hw, ICE_CGU_R22, val);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
/* Configure the TSPLL pre divisor and clock source */
|
||||
err = ice_read_cgu_reg(hw, ICE_CGU_R23, &dw23.val);
|
||||
/* Configure the TSPLL pre divisor (constant) and clock source */
|
||||
err = ice_read_cgu_reg(hw, ICE_CGU_R23, &r23);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
dw23.ref1588_ck_div = 0;
|
||||
dw23.time_ref_sel = clk_src;
|
||||
r23 &= ~(ICE_CGU_R23_R24_REF1588_CK_DIV | ICE_CGU_R23_R24_TIME_REF_SEL);
|
||||
r23 |= FIELD_PREP(ICE_CGU_R23_R24_TIME_REF_SEL, clk_src);
|
||||
|
||||
err = ice_write_cgu_reg(hw, ICE_CGU_R23, dw23.val);
|
||||
err = ice_write_cgu_reg(hw, ICE_CGU_R23, r23);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
|
|
@ -405,27 +448,39 @@ static int ice_tspll_cfg_e825c(struct ice_hw *hw, enum ice_tspll_freq clk_freq,
|
|||
if (err)
|
||||
return err;
|
||||
|
||||
/* Wait to ensure everything is stable */
|
||||
usleep_range(10, 20);
|
||||
|
||||
/* Finally, enable the PLL */
|
||||
dw23.ts_pll_enable = 1;
|
||||
r23 |= ICE_CGU_R23_R24_TSPLL_ENABLE;
|
||||
|
||||
err = ice_write_cgu_reg(hw, ICE_CGU_R23, dw23.val);
|
||||
err = ice_write_cgu_reg(hw, ICE_CGU_R23, r23);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
/* Wait to verify if the PLL locks */
|
||||
usleep_range(1000, 5000);
|
||||
/* Wait at least 1 ms to verify if the PLL locks */
|
||||
usleep_range(USEC_PER_MSEC, 2 * USEC_PER_MSEC);
|
||||
|
||||
err = ice_read_cgu_reg(hw, TSPLL_RO_LOCK_E825C, &ro_lock.val);
|
||||
err = ice_read_cgu_reg(hw, ICE_CGU_RO_LOCK, &val);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (!ro_lock.plllock_true_lock_cri) {
|
||||
dev_warn(ice_hw_to_dev(hw), "TSPLL failed to lock\n");
|
||||
if (!(val & ICE_CGU_RO_LOCK_TRUE_LOCK)) {
|
||||
dev_warn(ice_hw_to_dev(hw), "CGU PLL failed to lock\n");
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
ice_tspll_log_cfg(hw, dw23.ts_pll_enable, clk_src, clk_freq, true,
|
||||
true);
|
||||
err = ice_read_cgu_reg(hw, ICE_CGU_R9, &r9);
|
||||
if (err)
|
||||
return err;
|
||||
err = ice_read_cgu_reg(hw, ICE_CGU_R23, &r23);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
ice_tspll_log_cfg(hw, !!FIELD_GET(ICE_CGU_R23_R24_TSPLL_ENABLE, r23),
|
||||
FIELD_GET(ICE_CGU_R23_R24_TIME_REF_SEL, r23),
|
||||
FIELD_GET(ICE_CGU_R9_TIME_REF_FREQ_SEL, r9),
|
||||
true, true);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -441,20 +496,18 @@ static int ice_tspll_cfg_e825c(struct ice_hw *hw, enum ice_tspll_freq clk_freq,
|
|||
*/
|
||||
static int ice_tspll_dis_sticky_bits_e825c(struct ice_hw *hw)
|
||||
{
|
||||
union tspll_bw_tdc_e825c bw_tdc;
|
||||
u32 val;
|
||||
int err;
|
||||
|
||||
err = ice_read_cgu_reg(hw, TSPLL_BW_TDC_E825C, &bw_tdc.val);
|
||||
err = ice_read_cgu_reg(hw, ICE_CGU_BW_TDC, &val);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
bw_tdc.i_plllock_sel_1_0 = 0;
|
||||
val &= ~ICE_CGU_BW_TDC_PLLLOCK_SEL;
|
||||
|
||||
return ice_write_cgu_reg(hw, TSPLL_BW_TDC_E825C, bw_tdc.val);
|
||||
return ice_write_cgu_reg(hw, ICE_CGU_BW_TDC, val);
|
||||
}
|
||||
|
||||
#define ICE_ONE_PPS_OUT_AMP_MAX 3
|
||||
|
||||
/**
|
||||
* ice_tspll_cfg_pps_out_e825c - Enable/disable 1PPS output and set amplitude
|
||||
* @hw: pointer to the HW struct
|
||||
|
|
@ -464,16 +517,64 @@ static int ice_tspll_dis_sticky_bits_e825c(struct ice_hw *hw)
|
|||
*/
|
||||
int ice_tspll_cfg_pps_out_e825c(struct ice_hw *hw, bool enable)
|
||||
{
|
||||
union ice_cgu_r9 r9;
|
||||
u32 val;
|
||||
int err;
|
||||
|
||||
err = ice_read_cgu_reg(hw, ICE_CGU_R9, &r9.val);
|
||||
err = ice_read_cgu_reg(hw, ICE_CGU_R9, &val);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
r9.one_pps_out_en = enable;
|
||||
r9.one_pps_out_amp = enable * ICE_ONE_PPS_OUT_AMP_MAX;
|
||||
return ice_write_cgu_reg(hw, ICE_CGU_R9, r9.val);
|
||||
val &= ~(ICE_CGU_R9_ONE_PPS_OUT_EN | ICE_CGU_R9_ONE_PPS_OUT_AMP);
|
||||
val |= FIELD_PREP(ICE_CGU_R9_ONE_PPS_OUT_EN, enable) |
|
||||
ICE_CGU_R9_ONE_PPS_OUT_AMP;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -487,25 +588,39 @@ 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);
|
||||
/* Only E822, E823 and E825 products support TSPLL */
|
||||
if (hw->mac_type != ICE_MAC_GENERIC &&
|
||||
hw->mac_type != ICE_MAC_GENERIC_3K_E825)
|
||||
return 0;
|
||||
|
||||
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);
|
||||
err = ice_tspll_cfg(hw, tspll_freq, clk_src);
|
||||
if (err) {
|
||||
dev_warn(ice_hw_to_dev(hw), "Failed to lock TSPLL to predefined frequency. Retrying with fallback frequency.\n");
|
||||
|
||||
/* Try to lock to internal TCXO as a fallback. */
|
||||
tspll_freq = ice_tspll_default_freq(hw->mac_type);
|
||||
clk_src = ICE_CLK_SRC_TCXO;
|
||||
err = ice_tspll_cfg(hw, tspll_freq, clk_src);
|
||||
if (err)
|
||||
dev_warn(ice_hw_to_dev(hw), "Failed to lock TSPLL to fallback frequency.\n");
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user