* [PATCH net-next 0/8][pull request] ice: remaining TSPLL cleanups
@ 2025-06-26 16:29 Tony Nguyen
2025-06-26 16:29 ` [PATCH net-next 1/8] ice: clear time_sync_en field for E825-C during reprogramming Tony Nguyen
` (8 more replies)
0 siblings, 9 replies; 10+ messages in thread
From: Tony Nguyen @ 2025-06-26 16:29 UTC (permalink / raw)
To: davem, kuba, pabeni, edumazet, andrew+netdev, netdev
Cc: Tony Nguyen, karol.kolacinski, jacob.e.keller, przemyslaw.kitszel,
richardcochran
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/
---
IWL: https://lore.kernel.org/intel-wired-lan/20250623-kk-tspll-improvements-alignment-v1-0-fe9a50620700@intel.com/
The following are changes since commit 5cfb2ac2806c7a255df5184d86ffca056cd5cb5c:
docs: net: sysctl documentation cleanup
and are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/tnguy/next-queue 100GbE
Jacob Keller (3):
ice: clear time_sync_en field for E825-C during reprogramming
ice: read TSPLL registers again before reporting status
ice: default to TIME_REF instead of TXCO on E825-C
Karol Kolacinski (5):
ice: use bitfields instead of unions for CGU regs
ice: add multiple TSPLL helpers
ice: wait before enabling TSPLL
ice: fall back to TCXO on TSPLL lock fail
ice: move TSPLL init calls to ice_ptp.c
drivers/net/ethernet/intel/ice/ice_common.c | 2 +-
drivers/net/ethernet/intel/ice/ice_common.h | 212 ++--------
drivers/net/ethernet/intel/ice/ice_ptp.c | 11 +
drivers/net/ethernet/intel/ice/ice_ptp_hw.c | 22 +-
drivers/net/ethernet/intel/ice/ice_tspll.c | 427 +++++++++++++-------
5 files changed, 316 insertions(+), 358 deletions(-)
--
2.47.1
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH net-next 1/8] ice: clear time_sync_en field for E825-C during reprogramming
2025-06-26 16:29 [PATCH net-next 0/8][pull request] ice: remaining TSPLL cleanups Tony Nguyen
@ 2025-06-26 16:29 ` Tony Nguyen
2025-06-26 16:29 ` [PATCH net-next 2/8] ice: read TSPLL registers again before reporting status Tony Nguyen
` (7 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Tony Nguyen @ 2025-06-26 16:29 UTC (permalink / raw)
To: davem, kuba, pabeni, edumazet, andrew+netdev, netdev
Cc: Jacob Keller, anthony.l.nguyen, karol.kolacinski,
przemyslaw.kitszel, richardcochran
From: Jacob Keller <jacob.e.keller@intel.com>
When programming the Clock Generation Unit for E285-C hardware, we need
to clear the time_sync_en bit of the DWORD 9 before we set the
frequency.
Co-developed-by: Karol Kolacinski <karol.kolacinski@intel.com>
Signed-off-by: Karol Kolacinski <karol.kolacinski@intel.com>
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
---
drivers/net/ethernet/intel/ice/ice_tspll.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/drivers/net/ethernet/intel/ice/ice_tspll.c b/drivers/net/ethernet/intel/ice/ice_tspll.c
index 08af4ced50eb..e2f07d60fcdc 100644
--- a/drivers/net/ethernet/intel/ice/ice_tspll.c
+++ b/drivers/net/ethernet/intel/ice/ice_tspll.c
@@ -342,6 +342,14 @@ static int ice_tspll_cfg_e825c(struct ice_hw *hw, enum ice_tspll_freq clk_freq,
return err;
}
+ if (dw9.time_sync_en) {
+ dw9.time_sync_en = 0;
+
+ err = ice_write_cgu_reg(hw, ICE_CGU_R9, dw9.val);
+ if (err)
+ return err;
+ }
+
/* Set the frequency */
dw9.time_ref_freq_sel = clk_freq;
@@ -353,6 +361,7 @@ static int ice_tspll_cfg_e825c(struct ice_hw *hw, enum ice_tspll_freq clk_freq,
dw9.time_ref_en = 1;
dw9.clk_eref0_en = 0;
}
+ dw9.time_sync_en = 1;
err = ice_write_cgu_reg(hw, ICE_CGU_R9, dw9.val);
if (err)
return err;
--
2.47.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH net-next 2/8] ice: read TSPLL registers again before reporting status
2025-06-26 16:29 [PATCH net-next 0/8][pull request] ice: remaining TSPLL cleanups Tony Nguyen
2025-06-26 16:29 ` [PATCH net-next 1/8] ice: clear time_sync_en field for E825-C during reprogramming Tony Nguyen
@ 2025-06-26 16:29 ` Tony Nguyen
2025-06-26 16:29 ` [PATCH net-next 3/8] ice: use bitfields instead of unions for CGU regs Tony Nguyen
` (6 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Tony Nguyen @ 2025-06-26 16:29 UTC (permalink / raw)
To: davem, kuba, pabeni, edumazet, andrew+netdev, netdev
Cc: Jacob Keller, anthony.l.nguyen, karol.kolacinski,
przemyslaw.kitszel, richardcochran
From: Jacob Keller <jacob.e.keller@intel.com>
After programming the TSPLL, re-read the registers before reporting status.
This ensures the debug log message will show what was actually programmed,
rather than relying on a cached value.
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
---
drivers/net/ethernet/intel/ice/ice_tspll.c | 22 ++++++++++++++++++----
1 file changed, 18 insertions(+), 4 deletions(-)
diff --git a/drivers/net/ethernet/intel/ice/ice_tspll.c b/drivers/net/ethernet/intel/ice/ice_tspll.c
index e2f07d60fcdc..440aba817b9c 100644
--- a/drivers/net/ethernet/intel/ice/ice_tspll.c
+++ b/drivers/net/ethernet/intel/ice/ice_tspll.c
@@ -239,8 +239,15 @@ static int ice_tspll_cfg_e82x(struct ice_hw *hw, enum ice_tspll_freq clk_freq,
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, &dw9.val);
+ if (err)
+ return err;
+ err = ice_read_cgu_reg(hw, ICE_CGU_R24, &dw24.val);
+ if (err)
+ return err;
+
+ ice_tspll_log_cfg(hw, dw24.ts_pll_enable, dw24.time_ref_sel,
+ dw9.time_ref_freq_sel, true, false);
return 0;
}
@@ -433,8 +440,15 @@ static int ice_tspll_cfg_e825c(struct ice_hw *hw, enum ice_tspll_freq clk_freq,
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, &dw9.val);
+ if (err)
+ return err;
+ err = ice_read_cgu_reg(hw, ICE_CGU_R23, &dw23.val);
+ if (err)
+ return err;
+
+ ice_tspll_log_cfg(hw, dw23.ts_pll_enable, dw23.time_ref_sel,
+ dw9.time_ref_freq_sel, true, true);
return 0;
}
--
2.47.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH net-next 3/8] ice: use bitfields instead of unions for CGU regs
2025-06-26 16:29 [PATCH net-next 0/8][pull request] ice: remaining TSPLL cleanups Tony Nguyen
2025-06-26 16:29 ` [PATCH net-next 1/8] ice: clear time_sync_en field for E825-C during reprogramming Tony Nguyen
2025-06-26 16:29 ` [PATCH net-next 2/8] ice: read TSPLL registers again before reporting status Tony Nguyen
@ 2025-06-26 16:29 ` Tony Nguyen
2025-06-26 16:29 ` [PATCH net-next 4/8] ice: add multiple TSPLL helpers Tony Nguyen
` (5 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Tony Nguyen @ 2025-06-26 16:29 UTC (permalink / raw)
To: davem, kuba, pabeni, edumazet, andrew+netdev, netdev
Cc: Karol Kolacinski, anthony.l.nguyen, jacob.e.keller,
przemyslaw.kitszel, richardcochran, Milena Olech
From: Karol Kolacinski <karol.kolacinski@intel.com>
Switch from unions with bitfield structs to definitions with bitfield
masks. This is necessary, because some registers have different
field definitions or even use a different register for the same fields
based on HW type.
Remove unused register fields.
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_common.h | 212 +++--------------
drivers/net/ethernet/intel/ice/ice_tspll.c | 239 ++++++++++----------
2 files changed, 156 insertions(+), 295 deletions(-)
diff --git a/drivers/net/ethernet/intel/ice/ice_common.h b/drivers/net/ethernet/intel/ice/ice_common.h
index ed375babcde3..e8979b80c2f0 100644
--- a/drivers/net/ethernet/intel/ice/ice_common.h
+++ b/drivers/net/ethernet/intel/ice/ice_common.h
@@ -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);
diff --git a/drivers/net/ethernet/intel/ice/ice_tspll.c b/drivers/net/ethernet/intel/ice/ice_tspll.c
index 440aba817b9c..8e1f522c579b 100644
--- a/drivers/net/ethernet/intel/ice/ice_tspll.c
+++ b/drivers/net/ethernet/intel/ice/ice_tspll.c
@@ -127,11 +127,7 @@ 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) {
@@ -152,102 +148,115 @@ static int ice_tspll_cfg_e82x(struct ice_hw *hw, enum ice_tspll_freq clk_freq,
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;
/* 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);
- 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;
}
- 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;
- ice_tspll_log_cfg(hw, dw24.ts_pll_enable, dw24.time_ref_sel,
- dw9.time_ref_freq_sel, true, false);
+ 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;
}
@@ -263,18 +272,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);
}
/**
@@ -295,12 +303,7 @@ 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) {
@@ -320,99 +323,103 @@ static int ice_tspll_cfg_e825c(struct ice_hw *hw, enum ice_tspll_freq clk_freq,
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;
}
- if (dw9.time_sync_en) {
- dw9.time_sync_en = 0;
+ if (FIELD_GET(ICE_CGU_R9_TIME_SYNC_EN, r9)) {
+ r9 &= ~ICE_CGU_R9_TIME_SYNC_EN;
- err = ice_write_cgu_reg(hw, ICE_CGU_R9, dw9.val);
+ err = ice_write_cgu_reg(hw, ICE_CGU_R9, r9);
if (err)
return err;
}
- /* Set the frequency */
- dw9.time_ref_freq_sel = clk_freq;
-
- /* 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;
- }
- dw9.time_sync_en = 1;
- 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;
@@ -422,33 +429,35 @@ static int ice_tspll_cfg_e825c(struct ice_hw *hw, enum ice_tspll_freq clk_freq,
return err;
/* 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);
- 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;
}
- 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_R23, &dw23.val);
+ err = ice_read_cgu_reg(hw, ICE_CGU_R23, &r23);
if (err)
return err;
- ice_tspll_log_cfg(hw, dw23.ts_pll_enable, dw23.time_ref_sel,
- dw9.time_ref_freq_sel, true, true);
+ 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;
}
@@ -464,20 +473,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
@@ -487,16 +494,18 @@ 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);
}
/**
--
2.47.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH net-next 4/8] ice: add multiple TSPLL helpers
2025-06-26 16:29 [PATCH net-next 0/8][pull request] ice: remaining TSPLL cleanups Tony Nguyen
` (2 preceding siblings ...)
2025-06-26 16:29 ` [PATCH net-next 3/8] ice: use bitfields instead of unions for CGU regs Tony Nguyen
@ 2025-06-26 16:29 ` Tony Nguyen
2025-06-26 16:29 ` [PATCH net-next 5/8] ice: wait before enabling TSPLL Tony Nguyen
` (4 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Tony Nguyen @ 2025-06-26 16:29 UTC (permalink / raw)
To: davem, kuba, pabeni, edumazet, andrew+netdev, netdev
Cc: Karol Kolacinski, anthony.l.nguyen, jacob.e.keller,
przemyslaw.kitszel, richardcochran, Milena Olech
From: Karol Kolacinski <karol.kolacinski@intel.com>
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 | 156 ++++++++++++++-------
1 file changed, 108 insertions(+), 48 deletions(-)
diff --git a/drivers/net/ethernet/intel/ice/ice_tspll.c b/drivers/net/ethernet/intel/ice/ice_tspll.c
index 8e1f522c579b..e7b44e703d7c 100644
--- a/drivers/net/ethernet/intel/ice/ice_tspll.c
+++ b/drivers/net/ethernet/intel/ice/ice_tspll.c
@@ -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);
}
--
2.47.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH net-next 5/8] ice: wait before enabling TSPLL
2025-06-26 16:29 [PATCH net-next 0/8][pull request] ice: remaining TSPLL cleanups Tony Nguyen
` (3 preceding siblings ...)
2025-06-26 16:29 ` [PATCH net-next 4/8] ice: add multiple TSPLL helpers Tony Nguyen
@ 2025-06-26 16:29 ` Tony Nguyen
2025-06-26 16:29 ` [PATCH net-next 6/8] ice: fall back to TCXO on TSPLL lock fail Tony Nguyen
` (3 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Tony Nguyen @ 2025-06-26 16:29 UTC (permalink / raw)
To: davem, kuba, pabeni, edumazet, andrew+netdev, netdev
Cc: Karol Kolacinski, anthony.l.nguyen, jacob.e.keller,
przemyslaw.kitszel, richardcochran, Milena Olech
From: Karol Kolacinski <karol.kolacinski@intel.com>
To ensure proper operation, wait for 10 to 20 microseconds before
enabling TSPLL.
Adjust wait time after enabling TSPLL from 1-5 ms to 1-2 ms.
Those values are empirical and tested on multiple HW configurations.
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 | 14 ++++++++++----
1 file changed, 10 insertions(+), 4 deletions(-)
diff --git a/drivers/net/ethernet/intel/ice/ice_tspll.c b/drivers/net/ethernet/intel/ice/ice_tspll.c
index e7b44e703d7c..abd9f4ff2f55 100644
--- a/drivers/net/ethernet/intel/ice/ice_tspll.c
+++ b/drivers/net/ethernet/intel/ice/ice_tspll.c
@@ -261,6 +261,9 @@ static int ice_tspll_cfg_e82x(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 */
r24 |= ICE_CGU_R23_R24_TSPLL_ENABLE;
@@ -268,8 +271,8 @@ static int ice_tspll_cfg_e82x(struct ice_hw *hw, enum ice_tspll_freq clk_freq,
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, ICE_CGU_RO_BWM_LF, &val);
if (err)
@@ -445,6 +448,9 @@ 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 */
r23 |= ICE_CGU_R23_R24_TSPLL_ENABLE;
@@ -452,8 +458,8 @@ static int ice_tspll_cfg_e825c(struct ice_hw *hw, enum ice_tspll_freq clk_freq,
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, ICE_CGU_RO_LOCK, &val);
if (err)
--
2.47.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH net-next 6/8] ice: fall back to TCXO on TSPLL lock fail
2025-06-26 16:29 [PATCH net-next 0/8][pull request] ice: remaining TSPLL cleanups Tony Nguyen
` (4 preceding siblings ...)
2025-06-26 16:29 ` [PATCH net-next 5/8] ice: wait before enabling TSPLL Tony Nguyen
@ 2025-06-26 16:29 ` Tony Nguyen
2025-06-26 16:29 ` [PATCH net-next 7/8] ice: move TSPLL init calls to ice_ptp.c Tony Nguyen
` (2 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Tony Nguyen @ 2025-06-26 16:29 UTC (permalink / raw)
To: davem, kuba, pabeni, edumazet, andrew+netdev, netdev
Cc: Karol Kolacinski, anthony.l.nguyen, jacob.e.keller,
przemyslaw.kitszel, richardcochran, Milena Olech, Rinitha S
From: Karol Kolacinski <karol.kolacinski@intel.com>
TSPLL can fail when trying to lock to TIME_REF as a clock source, e.g.
when the external clock source is not stable or connected to the board.
To continue operation after failure, try to lock again to internal TCXO
and inform user about this.
Reviewed-by: Milena Olech <milena.olech@intel.com>
Signed-off-by: Karol Kolacinski <karol.kolacinski@intel.com>
Tested-by: Rinitha S <sx.rinitha@intel.com>
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
---
drivers/net/ethernet/intel/ice/ice_tspll.c | 14 +++++++++++++-
1 file changed, 13 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/intel/ice/ice_tspll.c b/drivers/net/ethernet/intel/ice/ice_tspll.c
index abd9f4ff2f55..886a18b2e65f 100644
--- a/drivers/net/ethernet/intel/ice/ice_tspll.c
+++ b/drivers/net/ethernet/intel/ice/ice_tspll.c
@@ -605,5 +605,17 @@ int ice_tspll_init(struct ice_hw *hw)
/* Configure the TSPLL using the parameters from the function
* capabilities.
*/
- return ice_tspll_cfg(hw, tspll_freq, 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;
}
--
2.47.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH net-next 7/8] ice: move TSPLL init calls to ice_ptp.c
2025-06-26 16:29 [PATCH net-next 0/8][pull request] ice: remaining TSPLL cleanups Tony Nguyen
` (5 preceding siblings ...)
2025-06-26 16:29 ` [PATCH net-next 6/8] ice: fall back to TCXO on TSPLL lock fail Tony Nguyen
@ 2025-06-26 16:29 ` Tony Nguyen
2025-06-26 16:29 ` [PATCH net-next 8/8] ice: default to TIME_REF instead of TXCO on E825-C Tony Nguyen
2025-06-27 23:40 ` [PATCH net-next 0/8][pull request] ice: remaining TSPLL cleanups patchwork-bot+netdevbpf
8 siblings, 0 replies; 10+ messages in thread
From: Tony Nguyen @ 2025-06-26 16:29 UTC (permalink / raw)
To: davem, kuba, pabeni, edumazet, andrew+netdev, netdev
Cc: Karol Kolacinski, anthony.l.nguyen, jacob.e.keller,
przemyslaw.kitszel, richardcochran, Michal Kubiak, Milena Olech,
Rinitha S
From: Karol Kolacinski <karol.kolacinski@intel.com>
Initialize TSPLL after initializing PHC in ice_ptp.c instead of calling
for each product in PHC init in ice_ptp_hw.c.
Reviewed-by: Michal Kubiak <michal.kubiak@intel.com>
Reviewed-by: Milena Olech <milena.olech@intel.com>
Signed-off-by: Karol Kolacinski <karol.kolacinski@intel.com>
Tested-by: Rinitha S <sx.rinitha@intel.com>
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
---
drivers/net/ethernet/intel/ice/ice_ptp.c | 11 +++++++++++
drivers/net/ethernet/intel/ice/ice_ptp_hw.c | 22 +--------------------
drivers/net/ethernet/intel/ice/ice_tspll.c | 5 +++++
3 files changed, 17 insertions(+), 21 deletions(-)
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.c b/drivers/net/ethernet/intel/ice/ice_ptp.c
index b8cf8d64aaaa..e7005d757477 100644
--- a/drivers/net/ethernet/intel/ice/ice_ptp.c
+++ b/drivers/net/ethernet/intel/ice/ice_ptp.c
@@ -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;
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp_hw.c b/drivers/net/ethernet/intel/ice/ice_ptp_hw.c
index 278231443546..e8e439fd64a4 100644
--- a/drivers/net/ethernet/intel/ice/ice_ptp_hw.c
+++ b/drivers/net/ethernet/intel/ice/ice_ptp_hw.c
@@ -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;
}
diff --git a/drivers/net/ethernet/intel/ice/ice_tspll.c b/drivers/net/ethernet/intel/ice/ice_tspll.c
index 886a18b2e65f..66320a4ab86f 100644
--- a/drivers/net/ethernet/intel/ice/ice_tspll.c
+++ b/drivers/net/ethernet/intel/ice/ice_tspll.c
@@ -592,6 +592,11 @@ int ice_tspll_init(struct ice_hw *hw)
enum ice_clk_src clk_src;
int err;
+ /* 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))
--
2.47.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH net-next 8/8] ice: default to TIME_REF instead of TXCO on E825-C
2025-06-26 16:29 [PATCH net-next 0/8][pull request] ice: remaining TSPLL cleanups Tony Nguyen
` (6 preceding siblings ...)
2025-06-26 16:29 ` [PATCH net-next 7/8] ice: move TSPLL init calls to ice_ptp.c Tony Nguyen
@ 2025-06-26 16:29 ` Tony Nguyen
2025-06-27 23:40 ` [PATCH net-next 0/8][pull request] ice: remaining TSPLL cleanups patchwork-bot+netdevbpf
8 siblings, 0 replies; 10+ messages in thread
From: Tony Nguyen @ 2025-06-26 16:29 UTC (permalink / raw)
To: davem, kuba, pabeni, edumazet, andrew+netdev, netdev
Cc: Jacob Keller, anthony.l.nguyen, karol.kolacinski,
przemyslaw.kitszel, richardcochran, Rinitha S
From: Jacob Keller <jacob.e.keller@intel.com>
The driver currently defaults to the internal oscillator as the clock
source for E825-C hardware. While this clock source is labeled TCXO,
indicating a temperature compensated oscillator, this is only true for some
board designs. Many board designs have a less capable oscillator. The
E825-C hardware may also have its clock source set to the TIME_REF pin.
This pin is connected to the DPLL and is often a more stable clock source.
The choice of the internal oscillator is not suitable for all systems,
especially those which want to enable SyncE support.
There is currently no interface available for users to configure the clock
source. Other variants of the E82x board have the clock source configured
in the NVM, but E825-C lacks this capability, so different board designs
cannot select a different default clock via firmware.
In most setups, the TIME_REF is a suitable default clock source.
Additionally, we now fall back to the internal oscillator automatically if
the TIME_REF clock source cannot be locked.
Change the default clock source for E825-C to TIME_REF. Note that the
driver logs a dev_dbg message upon configuring the TSPLL which includes the
clock source and frequency. This can be enabled to confirm which clock
source is in use.
Longterm a proper interface to dynamically introspect and change the clock
source will be designed (perhaps some extension of the DPLL subsystem?)
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
Tested-by: Rinitha S <sx.rinitha@intel.com>
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
---
drivers/net/ethernet/intel/ice/ice_common.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/intel/ice/ice_common.c b/drivers/net/ethernet/intel/ice/ice_common.c
index bc292d61892c..84cd8c6dcf39 100644
--- a/drivers/net/ethernet/intel/ice/ice_common.c
+++ b/drivers/net/ethernet/intel/ice/ice_common.c
@@ -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) {
--
2.47.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH net-next 0/8][pull request] ice: remaining TSPLL cleanups
2025-06-26 16:29 [PATCH net-next 0/8][pull request] ice: remaining TSPLL cleanups Tony Nguyen
` (7 preceding siblings ...)
2025-06-26 16:29 ` [PATCH net-next 8/8] ice: default to TIME_REF instead of TXCO on E825-C Tony Nguyen
@ 2025-06-27 23:40 ` patchwork-bot+netdevbpf
8 siblings, 0 replies; 10+ messages in thread
From: patchwork-bot+netdevbpf @ 2025-06-27 23:40 UTC (permalink / raw)
To: Tony Nguyen
Cc: davem, kuba, pabeni, edumazet, andrew+netdev, netdev,
karol.kolacinski, jacob.e.keller, przemyslaw.kitszel,
richardcochran
Hello:
This series was applied to netdev/net-next.git (main)
by Tony Nguyen <anthony.l.nguyen@intel.com>:
On Thu, 26 Jun 2025 09:29:11 -0700 you wrote:
> 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/
> ---
> IWL: https://lore.kernel.org/intel-wired-lan/20250623-kk-tspll-improvements-alignment-v1-0-fe9a50620700@intel.com/
>
> [...]
Here is the summary with links:
- [net-next,1/8] ice: clear time_sync_en field for E825-C during reprogramming
https://git.kernel.org/netdev/net-next/c/d261d755300e
- [net-next,2/8] ice: read TSPLL registers again before reporting status
https://git.kernel.org/netdev/net-next/c/38f742df9fcf
- [net-next,3/8] ice: use bitfields instead of unions for CGU regs
https://git.kernel.org/netdev/net-next/c/c6b4486a6201
- [net-next,4/8] ice: add multiple TSPLL helpers
https://git.kernel.org/netdev/net-next/c/5755b4c023db
- [net-next,5/8] ice: wait before enabling TSPLL
https://git.kernel.org/netdev/net-next/c/df3f3c5645be
- [net-next,6/8] ice: fall back to TCXO on TSPLL lock fail
https://git.kernel.org/netdev/net-next/c/84b8694433c8
- [net-next,7/8] ice: move TSPLL init calls to ice_ptp.c
https://git.kernel.org/netdev/net-next/c/e980aa685209
- [net-next,8/8] ice: default to TIME_REF instead of TXCO on E825-C
https://git.kernel.org/netdev/net-next/c/8b4987543453
You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2025-06-27 23:39 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-06-26 16:29 [PATCH net-next 0/8][pull request] ice: remaining TSPLL cleanups Tony Nguyen
2025-06-26 16:29 ` [PATCH net-next 1/8] ice: clear time_sync_en field for E825-C during reprogramming Tony Nguyen
2025-06-26 16:29 ` [PATCH net-next 2/8] ice: read TSPLL registers again before reporting status Tony Nguyen
2025-06-26 16:29 ` [PATCH net-next 3/8] ice: use bitfields instead of unions for CGU regs Tony Nguyen
2025-06-26 16:29 ` [PATCH net-next 4/8] ice: add multiple TSPLL helpers Tony Nguyen
2025-06-26 16:29 ` [PATCH net-next 5/8] ice: wait before enabling TSPLL Tony Nguyen
2025-06-26 16:29 ` [PATCH net-next 6/8] ice: fall back to TCXO on TSPLL lock fail Tony Nguyen
2025-06-26 16:29 ` [PATCH net-next 7/8] ice: move TSPLL init calls to ice_ptp.c Tony Nguyen
2025-06-26 16:29 ` [PATCH net-next 8/8] ice: default to TIME_REF instead of TXCO on E825-C Tony Nguyen
2025-06-27 23:40 ` [PATCH net-next 0/8][pull request] ice: remaining TSPLL cleanups patchwork-bot+netdevbpf
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).