Merge branch '100GbE' of git://git.kernel.org/pub/scm/linux/kernel/git/tnguy/next-queue

Tony Nguyen says:

====================
100GbE Intel Wired LAN Driver Updates 2021-12-21

This series contains updates to ice driver only.

Karol modifies the reset flow to correct issues with PTP reset.

Jake extends PTP support for E822 based devices. This includes a few
cleanup patches, that fix some minor issues. In addition, there are some
slight refactors to ease the addition of E822 support, followed by adding
the new hardware implementation ice_ptp_hw.c.

There are a few major differences with E822 support compared to E810
support:

*) The E822 device has a Clock Generation Unit which must be initialized in
order to generate proper clock frequencies on the output that drives the PTP
hardware clock registers

*) The E822 PHY is a bit different and requires a more complex
initialization procedure which must be rerun any time the link configuration
changes.

*) The E822 devices support enhanced timestamp calibration by making use of
a process called Vernier offset measurement. This allows the hardware to
measure phase offset related to the PHY clocks for Serdes and FEC, reducing
the inaccuracy of the timestamp relative to the actual packet transmission
and receipt. Making use of this requires data gathered from the first
transmitted and received packets, and waiting for the PHY to complete the
calibration measurements. This is done as part of a new kthread, ov_work.
Note that to avoid delay in enabling timestamps, we start the PHY in
'bypass' mode which allows timestamps to be captured without the Vernier
calibration measurement. Once the first packets have been sent and received,
we then complete the calibration setup and exit bypass mode and begin using
the more precise timestamps. According to the datasheet, timestamps without
calibration data can be incorrect relative to actual receipt or transmission
by up to 1 clock cycle (~1.25 nanoseconds), while calibrated timestamps
should be correct to within 1/8th of a clock cycle (~0.15 nanoseconds).

*) E822 devices support crosstimestamping via PCIe PTM, which we enable when
available on the platform.

There is a fair amount of logic required to perform PHY and CGU
initialization, which is the vast majority of the new code, but it is fairly
self contained within ice_ptp_hw.c, with the exception of monitoring for
offset validity being handled by a kthread.

* '100GbE' of git://git.kernel.org/pub/scm/linux/kernel/git/tnguy/next-queue:
  ice: support crosstimestamping on E822 devices if supported
  ice: exit bypass mode once hardware finishes timestamp calibration
  ice: ensure the hardware Clock Generation Unit is configured
  ice: implement basic E822 PTP support
  ice: convert clk_freq capability into time_ref
  ice: introduce ice_ptp_init_phc function
  ice: use 'int err' instead of 'int status' in ice_ptp_hw.c
  ice: PTP: move setting of tstamp_config
  ice: introduce ice_base_incval function
  ice: Fix E810 PTP reset flow
====================

Link: https://lore.kernel.org/r/20211221174845.3063640-1-anthony.l.nguyen@intel.com
Acked-by: Richard Cochran <richardcochran@gmail.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
Jakub Kicinski 2021-12-22 14:25:41 -08:00
commit 2030eddced
11 changed files with 4360 additions and 236 deletions

View file

@ -327,6 +327,16 @@ config ICE_SWITCHDEV
If unsure, say N.
config ICE_HWTS
bool "Support HW cross-timestamp on platforms with PTM support"
default y
depends on ICE && X86
help
Say Y to enable hardware supported cross-timestamping on platforms
with PCIe PTM support. The cross-timestamp is available through
the PTP clock driver precise cross-timestamp ioctl
(PTP_SYS_OFFSET_PRECISE).
config FM10K
tristate "Intel(R) FM10000 Ethernet Switch Host Interface Support"
default n

View file

@ -0,0 +1,116 @@
/* SPDX-License-Identifier: GPL-2.0 */
/* Copyright (C) 2018-2021, Intel Corporation. */
#ifndef _ICE_CGU_REGS_H_
#define _ICE_CGU_REGS_H_
#define NAC_CGU_DWORD9 0x24
union nac_cgu_dword9 {
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;
} field;
u32 val;
};
#define NAC_CGU_DWORD19 0x4c
union nac_cgu_dword19 {
struct {
u32 tspll_fbdiv_intgr : 8;
u32 fdpll_ulck_thr : 5;
u32 misc15 : 3;
u32 tspll_ndivratio : 4;
u32 tspll_iref_ndivratio : 3;
u32 misc19 : 1;
u32 japll_ndivratio : 4;
u32 japll_iref_ndivratio : 3;
u32 misc27 : 1;
} field;
u32 val;
};
#define NAC_CGU_DWORD22 0x58
union nac_cgu_dword22 {
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;
} field;
u32 val;
};
#define NAC_CGU_DWORD24 0x60
union nac_cgu_dword24 {
struct {
u32 tspll_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;
} field;
u32 val;
};
#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;
} field;
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;
} field;
u32 val;
};
#endif /* _ICE_CGU_REGS_H_ */

View file

@ -2189,6 +2189,18 @@ ice_parse_1588_func_caps(struct ice_hw *hw, struct ice_hw_func_caps *func_p,
info->clk_freq = (number & ICE_TS_CLK_FREQ_M) >> ICE_TS_CLK_FREQ_S;
info->clk_src = ((number & ICE_TS_CLK_SRC_M) != 0);
if (info->clk_freq < NUM_ICE_TIME_REF_FREQ) {
info->time_ref = (enum ice_time_ref_freq)info->clk_freq;
} else {
/* Unknown clock frequency, so assume a (probably incorrect)
* default to avoid out-of-bounds look ups of frequency
* related information.
*/
ice_debug(hw, ICE_DBG_INIT, "1588 func caps: unknown clock frequency %u\n",
info->clk_freq);
info->time_ref = ICE_TIME_REF_FREQ_25_000;
}
ice_debug(hw, ICE_DBG_INIT, "func caps: ieee_1588 = %u\n",
func_p->common_cap.ieee_1588);
ice_debug(hw, ICE_DBG_INIT, "func caps: src_tmr_owned = %u\n",

View file

@ -100,6 +100,7 @@
#define PF_SB_ATQT 0x0022FE00
#define PF_SB_ATQT_ATQT_S 0
#define PF_SB_ATQT_ATQT_M ICE_M(0x3FF, 0)
#define PF_SB_REM_DEV_CTL 0x002300F0
#define PRTDCB_GENC 0x00083000
#define PRTDCB_GENC_PFCLDA_S 16
#define PRTDCB_GENC_PFCLDA_M ICE_M(0xFFFF, 16)
@ -440,6 +441,10 @@
#define GLV_UPRCL(_i) (0x003B2000 + ((_i) * 8))
#define GLV_UPTCL(_i) (0x0030A000 + ((_i) * 8))
#define PRTRPB_RDPC 0x000AC260
#define GLHH_ART_CTL 0x000A41D4
#define GLHH_ART_CTL_ACTIVE_M BIT(0)
#define GLHH_ART_TIME_H 0x000A41D8
#define GLHH_ART_TIME_L 0x000A41DC
#define GLTSYN_AUX_IN_0(_i) (0x000889D8 + ((_i) * 4))
#define GLTSYN_AUX_IN_0_INT_ENA_M BIT(4)
#define GLTSYN_AUX_OUT_0(_i) (0x00088998 + ((_i) * 4))
@ -452,6 +457,8 @@
#define GLTSYN_ENA_TSYN_ENA_M BIT(0)
#define GLTSYN_EVNT_H_0(_i) (0x00088970 + ((_i) * 4))
#define GLTSYN_EVNT_L_0(_i) (0x00088968 + ((_i) * 4))
#define GLTSYN_HHTIME_H(_i) (0x00088900 + ((_i) * 4))
#define GLTSYN_HHTIME_L(_i) (0x000888F8 + ((_i) * 4))
#define GLTSYN_INCVAL_H(_i) (0x00088920 + ((_i) * 4))
#define GLTSYN_INCVAL_L(_i) (0x00088918 + ((_i) * 4))
#define GLTSYN_SHADJ_H(_i) (0x00088910 + ((_i) * 4))
@ -468,6 +475,8 @@
#define GLTSYN_TGT_L_0(_i) (0x00088928 + ((_i) * 4))
#define GLTSYN_TIME_H(_i) (0x000888D8 + ((_i) * 4))
#define GLTSYN_TIME_L(_i) (0x000888D0 + ((_i) * 4))
#define PFHH_SEM 0x000A4200 /* Reset Source: PFR */
#define PFHH_SEM_BUSY_M BIT(0)
#define PFTSYN_SEM 0x00088880
#define PFTSYN_SEM_BUSY_M BIT(0)
#define VSIQF_FD_CNT(_VSI) (0x00464000 + ((_VSI) * 4))

View file

@ -539,7 +539,7 @@ ice_prepare_for_reset(struct ice_pf *pf, enum ice_reset_req reset_type)
ice_pf_dis_all_vsi(pf, false);
if (test_bit(ICE_FLAG_PTP_SUPPORTED, pf->flags))
ice_ptp_release(pf);
ice_ptp_prepare_for_reset(pf);
if (hw->port_info)
ice_sched_clear_port(hw->port_info);
@ -1063,6 +1063,9 @@ ice_link_event(struct ice_pf *pf, struct ice_port_info *pi, bool link_up,
if (link_up == old_link && link_speed == old_link_speed)
return 0;
if (!ice_is_e810(&pf->hw))
ice_ptp_link_change(pf, pf->hw.pf_id, link_up);
if (ice_is_dcb_active(pf)) {
if (test_bit(ICE_FLAG_DCB_ENA, pf->flags))
ice_dcb_rebuild(pf);
@ -5839,6 +5842,8 @@ static int ice_up_complete(struct ice_vsi *vsi)
ice_print_link_msg(vsi, true);
netif_tx_start_all_queues(vsi->netdev);
netif_carrier_on(vsi->netdev);
if (!ice_is_e810(&pf->hw))
ice_ptp_link_change(pf, pf->hw.pf_id, true);
}
/* clear this now, and the first stats read will be used as baseline */
@ -6239,6 +6244,8 @@ int ice_down(struct ice_vsi *vsi)
WARN_ON(!test_bit(ICE_VSI_DOWN, vsi->state));
if (vsi->netdev && vsi->type == ICE_VSI_PF) {
if (!ice_is_e810(&vsi->back->hw))
ice_ptp_link_change(vsi->back, vsi->back->hw.pf_id, false);
netif_carrier_off(vsi->netdev);
netif_tx_disable(vsi->netdev);
} else if (vsi->type == ICE_VSI_SWITCHDEV_CTRL) {
@ -6685,7 +6692,7 @@ static void ice_rebuild(struct ice_pf *pf, enum ice_reset_req reset_type)
* fail.
*/
if (test_bit(ICE_FLAG_PTP_SUPPORTED, pf->flags))
ice_ptp_init(pf);
ice_ptp_reset(pf);
/* rebuild PF VSI */
err = ice_vsi_rebuild_by_type(pf, ICE_VSI_PF);
@ -6694,6 +6701,10 @@ static void ice_rebuild(struct ice_pf *pf, enum ice_reset_req reset_type)
goto err_vsi_rebuild;
}
/* configure PTP timestamping after VSI rebuild */
if (test_bit(ICE_FLAG_PTP_SUPPORTED, pf->flags))
ice_ptp_cfg_timestamp(pf, false);
err = ice_vsi_rebuild_by_type(pf, ICE_VSI_SWITCHDEV_CTRL);
if (err) {
dev_err(dev, "Switchdev CTRL VSI rebuild failed: %d\n", err);

File diff suppressed because it is too large Load diff

View file

@ -82,6 +82,8 @@ struct ice_tx_tstamp {
* @quad_offset: offset into timestamp block of the quad to get the real index
* @len: length of the tstamps and in_use fields.
* @init: if true, the tracker is initialized;
* @calibrating: if true, the PHY is calibrating the Tx offset. During this
* window, timestamps are temporarily disabled.
*/
struct ice_ptp_tx {
struct kthread_work work;
@ -92,6 +94,7 @@ struct ice_ptp_tx {
u8 quad_offset;
u8 len;
u8 init;
u8 calibrating;
};
/* Quad and port information for initializing timestamp blocks */
@ -101,15 +104,24 @@ struct ice_ptp_tx {
/**
* struct ice_ptp_port - data used to initialize an external port for PTP
*
* This structure contains PTP data related to the external ports. Currently
* it is used for tracking the Tx timestamps of a port. In the future this
* structure will also hold information for the E822 port initialization
* logic.
* This structure contains data indicating whether a single external port is
* ready for PTP functionality. It is used to track the port initialization
* and determine when the port's PHY offset is valid.
*
* @tx: Tx timestamp tracking for this port
* @ov_work: delayed work task for tracking when PHY offset is valid
* @ps_lock: mutex used to protect the overall PTP PHY start procedure
* @link_up: indicates whether the link is up
* @tx_fifo_busy_cnt: number of times the Tx FIFO was busy
* @port_num: the port number this structure represents
*/
struct ice_ptp_port {
struct ice_ptp_tx tx;
struct kthread_delayed_work ov_work;
struct mutex ps_lock; /* protects overall PTP PHY start procedure */
bool link_up;
u8 tx_fifo_busy_cnt;
u8 port_num;
};
#define GLTSYN_TGT_H_IDX_MAX 4
@ -127,6 +139,7 @@ struct ice_ptp_port {
* @info: structure defining PTP hardware capabilities
* @clock: pointer to registered PTP clock device
* @tstamp_config: hardware timestamping configuration
* @reset_time: kernel time after clock stop on reset
*/
struct ice_ptp {
struct ice_ptp_port port;
@ -140,6 +153,7 @@ struct ice_ptp {
struct ptp_clock_info info;
struct ptp_clock *clock;
struct hwtstamp_config tstamp_config;
u64 reset_time;
};
#define __ptp_port_to_ptp(p) \
@ -152,9 +166,15 @@ struct ice_ptp {
#define ptp_info_to_pf(i) \
container_of(__ptp_info_to_ptp((i)), struct ice_pf, ptp)
#define PFTSYN_SEM_BYTES 4
#define PTP_SHARED_CLK_IDX_VALID BIT(31)
#define TS_CMD_MASK 0xF
#define SYNC_EXEC_CMD 0x3
#define ICE_PTP_TS_VALID BIT(0)
#define FIFO_EMPTY BIT(2)
#define FIFO_OK 0xFF
#define ICE_PTP_FIFO_NUM_CHECKS 5
/* Per-channel register definitions */
#define GLTSYN_AUX_OUT(_chan, _idx) (GLTSYN_AUX_OUT_0(_idx) + ((_chan) * 8))
#define GLTSYN_AUX_IN(_chan, _idx) (GLTSYN_AUX_IN_0(_idx) + ((_chan) * 8))
@ -175,11 +195,13 @@ struct ice_ptp {
#define N_PER_OUT_E810T 3
#define N_PER_OUT_E810T_NO_SMA 2
#define N_EXT_TS_E810_NO_SMA 2
#define ETH_GLTSYN_ENA(_i) (0x03000348 + ((_i) * 4))
#if IS_ENABLED(CONFIG_PTP_1588_CLOCK)
struct ice_pf;
int ice_ptp_set_ts_config(struct ice_pf *pf, struct ifreq *ifr);
int ice_ptp_get_ts_config(struct ice_pf *pf, struct ifreq *ifr);
void ice_ptp_cfg_timestamp(struct ice_pf *pf, bool ena);
int ice_get_ptp_clock_index(struct ice_pf *pf);
s8 ice_ptp_request_ts(struct ice_ptp_tx *tx, struct sk_buff *skb);
@ -188,8 +210,11 @@ void ice_ptp_process_ts(struct ice_pf *pf);
void
ice_ptp_rx_hwtstamp(struct ice_rx_ring *rx_ring,
union ice_32b_rx_flex_desc *rx_desc, struct sk_buff *skb);
void ice_ptp_reset(struct ice_pf *pf);
void ice_ptp_prepare_for_reset(struct ice_pf *pf);
void ice_ptp_init(struct ice_pf *pf);
void ice_ptp_release(struct ice_pf *pf);
int ice_ptp_link_change(struct ice_pf *pf, u8 port, bool linkup);
#else /* IS_ENABLED(CONFIG_PTP_1588_CLOCK) */
static inline int ice_ptp_set_ts_config(struct ice_pf *pf, struct ifreq *ifr)
{
@ -201,6 +226,7 @@ static inline int ice_ptp_get_ts_config(struct ice_pf *pf, struct ifreq *ifr)
return -EOPNOTSUPP;
}
static inline void ice_ptp_cfg_timestamp(struct ice_pf *pf, bool ena) { }
static inline int ice_get_ptp_clock_index(struct ice_pf *pf)
{
return -1;
@ -216,7 +242,11 @@ static inline void ice_ptp_process_ts(struct ice_pf *pf) { }
static inline void
ice_ptp_rx_hwtstamp(struct ice_rx_ring *rx_ring,
union ice_32b_rx_flex_desc *rx_desc, struct sk_buff *skb) { }
static inline void ice_ptp_reset(struct ice_pf *pf) { }
static inline void ice_ptp_prepare_for_reset(struct ice_pf *pf) { }
static inline void ice_ptp_init(struct ice_pf *pf) { }
static inline void ice_ptp_release(struct ice_pf *pf) { }
static inline int ice_ptp_link_change(struct ice_pf *pf, u8 port, bool linkup)
{ return 0; }
#endif /* IS_ENABLED(CONFIG_PTP_1588_CLOCK) */
#endif /* _ICE_PTP_H_ */

View file

@ -0,0 +1,374 @@
/* SPDX-License-Identifier: GPL-2.0 */
/* Copyright (C) 2018-2021, Intel Corporation. */
#ifndef _ICE_PTP_CONSTS_H_
#define _ICE_PTP_CONSTS_H_
/* Constant definitions related to the hardware clock used for PTP 1588
* features and functionality.
*/
/* Constants defined for the PTP 1588 clock hardware. */
/* struct ice_time_ref_info_e822
*
* E822 hardware can use different sources as the reference for the PTP
* hardware clock. Each clock has different characteristics such as a slightly
* different frequency, etc.
*
* This lookup table defines several constants that depend on the current time
* reference. See the struct ice_time_ref_info_e822 for information about the
* meaning of each constant.
*/
const struct ice_time_ref_info_e822 e822_time_ref[NUM_ICE_TIME_REF_FREQ] = {
/* ICE_TIME_REF_FREQ_25_000 -> 25 MHz */
{
/* pll_freq */
823437500, /* 823.4375 MHz PLL */
/* nominal_incval */
0x136e44fabULL,
/* pps_delay */
11,
},
/* ICE_TIME_REF_FREQ_122_880 -> 122.88 MHz */
{
/* pll_freq */
783360000, /* 783.36 MHz */
/* nominal_incval */
0x146cc2177ULL,
/* pps_delay */
12,
},
/* ICE_TIME_REF_FREQ_125_000 -> 125 MHz */
{
/* pll_freq */
796875000, /* 796.875 MHz */
/* nominal_incval */
0x141414141ULL,
/* pps_delay */
12,
},
/* ICE_TIME_REF_FREQ_153_600 -> 153.6 MHz */
{
/* pll_freq */
816000000, /* 816 MHz */
/* nominal_incval */
0x139b9b9baULL,
/* pps_delay */
12,
},
/* ICE_TIME_REF_FREQ_156_250 -> 156.25 MHz */
{
/* pll_freq */
830078125, /* 830.78125 MHz */
/* nominal_incval */
0x134679aceULL,
/* pps_delay */
11,
},
/* ICE_TIME_REF_FREQ_245_760 -> 245.76 MHz */
{
/* pll_freq */
783360000, /* 783.36 MHz */
/* nominal_incval */
0x146cc2177ULL,
/* pps_delay */
12,
},
};
const struct ice_cgu_pll_params_e822 e822_cgu_params[NUM_ICE_TIME_REF_FREQ] = {
/* ICE_TIME_REF_FREQ_25_000 -> 25 MHz */
{
/* refclk_pre_div */
1,
/* feedback_div */
197,
/* frac_n_div */
2621440,
/* post_pll_div */
6,
},
/* ICE_TIME_REF_FREQ_122_880 -> 122.88 MHz */
{
/* refclk_pre_div */
5,
/* feedback_div */
223,
/* frac_n_div */
524288,
/* post_pll_div */
7,
},
/* ICE_TIME_REF_FREQ_125_000 -> 125 MHz */
{
/* refclk_pre_div */
5,
/* feedback_div */
223,
/* frac_n_div */
524288,
/* post_pll_div */
7,
},
/* ICE_TIME_REF_FREQ_153_600 -> 153.6 MHz */
{
/* refclk_pre_div */
5,
/* feedback_div */
159,
/* frac_n_div */
1572864,
/* post_pll_div */
6,
},
/* ICE_TIME_REF_FREQ_156_250 -> 156.25 MHz */
{
/* refclk_pre_div */
5,
/* feedback_div */
159,
/* frac_n_div */
1572864,
/* post_pll_div */
6,
},
/* ICE_TIME_REF_FREQ_245_760 -> 245.76 MHz */
{
/* refclk_pre_div */
10,
/* feedback_div */
223,
/* frac_n_div */
524288,
/* post_pll_div */
7,
},
};
/* struct ice_vernier_info_e822
*
* E822 hardware calibrates the delay of the timestamp indication from the
* actual packet transmission or reception during the initialization of the
* PHY. To do this, the hardware mechanism uses some conversions between the
* various clocks within the PHY block. This table defines constants used to
* calculate the correct conversion ratios in the PHY registers.
*
* Many of the values relate to the PAR/PCS clock conversion registers. For
* these registers, a value of 0 means that the associated register is not
* used by this link speed, and that the register should be cleared by writing
* 0. Other values specify the clock frequency in Hz.
*/
const struct ice_vernier_info_e822 e822_vernier[NUM_ICE_PTP_LNK_SPD] = {
/* ICE_PTP_LNK_SPD_1G */
{
/* tx_par_clk */
31250000, /* 31.25 MHz */
/* rx_par_clk */
31250000, /* 31.25 MHz */
/* tx_pcs_clk */
125000000, /* 125 MHz */
/* rx_pcs_clk */
125000000, /* 125 MHz */
/* tx_desk_rsgb_par */
0, /* unused */
/* rx_desk_rsgb_par */
0, /* unused */
/* tx_desk_rsgb_pcs */
0, /* unused */
/* rx_desk_rsgb_pcs */
0, /* unused */
/* tx_fixed_delay */
25140,
/* pmd_adj_divisor */
10000000,
/* rx_fixed_delay */
17372,
},
/* ICE_PTP_LNK_SPD_10G */
{
/* tx_par_clk */
257812500, /* 257.8125 MHz */
/* rx_par_clk */
257812500, /* 257.8125 MHz */
/* tx_pcs_clk */
156250000, /* 156.25 MHz */
/* rx_pcs_clk */
156250000, /* 156.25 MHz */
/* tx_desk_rsgb_par */
0, /* unused */
/* rx_desk_rsgb_par */
0, /* unused */
/* tx_desk_rsgb_pcs */
0, /* unused */
/* rx_desk_rsgb_pcs */
0, /* unused */
/* tx_fixed_delay */
6938,
/* pmd_adj_divisor */
82500000,
/* rx_fixed_delay */
6212,
},
/* ICE_PTP_LNK_SPD_25G */
{
/* tx_par_clk */
644531250, /* 644.53125 MHZ */
/* rx_par_clk */
644531250, /* 644.53125 MHz */
/* tx_pcs_clk */
390625000, /* 390.625 MHz */
/* rx_pcs_clk */
390625000, /* 390.625 MHz */
/* tx_desk_rsgb_par */
0, /* unused */
/* rx_desk_rsgb_par */
0, /* unused */
/* tx_desk_rsgb_pcs */
0, /* unused */
/* rx_desk_rsgb_pcs */
0, /* unused */
/* tx_fixed_delay */
2778,
/* pmd_adj_divisor */
206250000,
/* rx_fixed_delay */
2491,
},
/* ICE_PTP_LNK_SPD_25G_RS */
{
/* tx_par_clk */
0, /* unused */
/* rx_par_clk */
0, /* unused */
/* tx_pcs_clk */
0, /* unused */
/* rx_pcs_clk */
0, /* unused */
/* tx_desk_rsgb_par */
161132812, /* 162.1328125 MHz Reed Solomon gearbox */
/* rx_desk_rsgb_par */
161132812, /* 162.1328125 MHz Reed Solomon gearbox */
/* tx_desk_rsgb_pcs */
97656250, /* 97.62625 MHz Reed Solomon gearbox */
/* rx_desk_rsgb_pcs */
97656250, /* 97.62625 MHz Reed Solomon gearbox */
/* tx_fixed_delay */
3928,
/* pmd_adj_divisor */
206250000,
/* rx_fixed_delay */
29535,
},
/* ICE_PTP_LNK_SPD_40G */
{
/* tx_par_clk */
257812500,
/* rx_par_clk */
257812500,
/* tx_pcs_clk */
156250000, /* 156.25 MHz */
/* rx_pcs_clk */
156250000, /* 156.25 MHz */
/* tx_desk_rsgb_par */
0, /* unused */
/* rx_desk_rsgb_par */
156250000, /* 156.25 MHz deskew clock */
/* tx_desk_rsgb_pcs */
0, /* unused */
/* rx_desk_rsgb_pcs */
156250000, /* 156.25 MHz deskew clock */
/* tx_fixed_delay */
5666,
/* pmd_adj_divisor */
82500000,
/* rx_fixed_delay */
4244,
},
/* ICE_PTP_LNK_SPD_50G */
{
/* tx_par_clk */
644531250, /* 644.53125 MHZ */
/* rx_par_clk */
644531250, /* 644.53125 MHZ */
/* tx_pcs_clk */
390625000, /* 390.625 MHz */
/* rx_pcs_clk */
390625000, /* 390.625 MHz */
/* tx_desk_rsgb_par */
0, /* unused */
/* rx_desk_rsgb_par */
195312500, /* 193.3125 MHz deskew clock */
/* tx_desk_rsgb_pcs */
0, /* unused */
/* rx_desk_rsgb_pcs */
195312500, /* 193.3125 MHz deskew clock */
/* tx_fixed_delay */
2778,
/* pmd_adj_divisor */
206250000,
/* rx_fixed_delay */
2868,
},
/* ICE_PTP_LNK_SPD_50G_RS */
{
/* tx_par_clk */
0, /* unused */
/* rx_par_clk */
644531250, /* 644.53125 MHz */
/* tx_pcs_clk */
0, /* unused */
/* rx_pcs_clk */
644531250, /* 644.53125 MHz */
/* tx_desk_rsgb_par */
322265625, /* 322.265625 MHz Reed Solomon gearbox */
/* rx_desk_rsgb_par */
322265625, /* 322.265625 MHz Reed Solomon gearbox */
/* tx_desk_rsgb_pcs */
644531250, /* 644.53125 MHz Reed Solomon gearbox */
/* rx_desk_rsgb_pcs */
644531250, /* 644.53125 MHz Reed Solomon gearbox */
/* tx_fixed_delay */
2095,
/* pmd_adj_divisor */
206250000,
/* rx_fixed_delay */
14524,
},
/* ICE_PTP_LNK_SPD_100G_RS */
{
/* tx_par_clk */
0, /* unused */
/* rx_par_clk */
644531250, /* 644.53125 MHz */
/* tx_pcs_clk */
0, /* unused */
/* rx_pcs_clk */
644531250, /* 644.53125 MHz */
/* tx_desk_rsgb_par */
644531250, /* 644.53125 MHz Reed Solomon gearbox */
/* rx_desk_rsgb_par */
644531250, /* 644.53125 MHz Reed Solomon gearbox */
/* tx_desk_rsgb_pcs */
644531250, /* 644.53125 MHz Reed Solomon gearbox */
/* rx_desk_rsgb_pcs */
644531250, /* 644.53125 MHz Reed Solomon gearbox */
/* tx_fixed_delay */
1620,
/* pmd_adj_divisor */
206250000,
/* rx_fixed_delay */
7775,
},
};
#endif /* _ICE_PTP_CONSTS_H_ */

File diff suppressed because it is too large Load diff

View file

@ -12,6 +12,112 @@ enum ice_ptp_tmr_cmd {
READ_TIME
};
enum ice_ptp_serdes {
ICE_PTP_SERDES_1G,
ICE_PTP_SERDES_10G,
ICE_PTP_SERDES_25G,
ICE_PTP_SERDES_40G,
ICE_PTP_SERDES_50G,
ICE_PTP_SERDES_100G
};
enum ice_ptp_link_spd {
ICE_PTP_LNK_SPD_1G,
ICE_PTP_LNK_SPD_10G,
ICE_PTP_LNK_SPD_25G,
ICE_PTP_LNK_SPD_25G_RS,
ICE_PTP_LNK_SPD_40G,
ICE_PTP_LNK_SPD_50G,
ICE_PTP_LNK_SPD_50G_RS,
ICE_PTP_LNK_SPD_100G_RS,
NUM_ICE_PTP_LNK_SPD /* Must be last */
};
enum ice_ptp_fec_mode {
ICE_PTP_FEC_MODE_NONE,
ICE_PTP_FEC_MODE_CLAUSE74,
ICE_PTP_FEC_MODE_RS_FEC
};
/**
* struct ice_time_ref_info_e822
* @pll_freq: Frequency of PLL that drives timer ticks in Hz
* @nominal_incval: increment to generate nanoseconds in GLTSYN_TIME_L
* @pps_delay: propagation delay of the PPS output signal
*
* Characteristic information for the various TIME_REF sources possible in the
* E822 devices
*/
struct ice_time_ref_info_e822 {
u64 pll_freq;
u64 nominal_incval;
u8 pps_delay;
};
/**
* struct ice_vernier_info_e822
* @tx_par_clk: Frequency used to calculate P_REG_PAR_TX_TUS
* @rx_par_clk: Frequency used to calculate P_REG_PAR_RX_TUS
* @tx_pcs_clk: Frequency used to calculate P_REG_PCS_TX_TUS
* @rx_pcs_clk: Frequency used to calculate P_REG_PCS_RX_TUS
* @tx_desk_rsgb_par: Frequency used to calculate P_REG_DESK_PAR_TX_TUS
* @rx_desk_rsgb_par: Frequency used to calculate P_REG_DESK_PAR_RX_TUS
* @tx_desk_rsgb_pcs: Frequency used to calculate P_REG_DESK_PCS_TX_TUS
* @rx_desk_rsgb_pcs: Frequency used to calculate P_REG_DESK_PCS_RX_TUS
* @tx_fixed_delay: Fixed Tx latency measured in 1/100th nanoseconds
* @pmd_adj_divisor: Divisor used to calculate PDM alignment adjustment
* @rx_fixed_delay: Fixed Rx latency measured in 1/100th nanoseconds
*
* Table of constants used during as part of the Vernier calibration of the Tx
* and Rx timestamps. This includes frequency values used to compute TUs per
* PAR/PCS clock cycle, and static delay values measured during hardware
* design.
*
* Note that some values are not used for all link speeds, and the
* P_REG_DESK_PAR* registers may represent different clock markers at
* different link speeds, either the deskew marker for multi-lane link speeds
* or the Reed Solomon gearbox marker for RS-FEC.
*/
struct ice_vernier_info_e822 {
u32 tx_par_clk;
u32 rx_par_clk;
u32 tx_pcs_clk;
u32 rx_pcs_clk;
u32 tx_desk_rsgb_par;
u32 rx_desk_rsgb_par;
u32 tx_desk_rsgb_pcs;
u32 rx_desk_rsgb_pcs;
u32 tx_fixed_delay;
u32 pmd_adj_divisor;
u32 rx_fixed_delay;
};
/**
* struct ice_cgu_pll_params_e822
* @refclk_pre_div: Reference clock pre-divisor
* @feedback_div: Feedback divisor
* @frac_n_div: Fractional divisor
* @post_pll_div: Post PLL divisor
*
* Clock Generation Unit parameters used to program the PLL based on the
* selected TIME_REF frequency.
*/
struct ice_cgu_pll_params_e822 {
u32 refclk_pre_div;
u32 feedback_div;
u32 frac_n_div;
u32 post_pll_div;
};
extern const struct
ice_cgu_pll_params_e822 e822_cgu_params[NUM_ICE_TIME_REF_FREQ];
/* Table of constants related to possible TIME_REF sources */
extern const struct ice_time_ref_info_e822 e822_time_ref[NUM_ICE_TIME_REF_FREQ];
/* Table of constants for Vernier calibration on E822 */
extern const struct ice_vernier_info_e822 e822_vernier[NUM_ICE_PTP_LNK_SPD];
/* Increment value to generate nanoseconds in the GLTSYN_TIME_L register for
* the E810 devices. Based off of a PLL with an 812.5 MHz frequency.
*/
@ -27,6 +133,59 @@ int ice_ptp_write_incval_locked(struct ice_hw *hw, u64 incval);
int ice_ptp_adj_clock(struct ice_hw *hw, s32 adj);
int ice_read_phy_tstamp(struct ice_hw *hw, u8 block, u8 idx, u64 *tstamp);
int ice_clear_phy_tstamp(struct ice_hw *hw, u8 block, u8 idx);
int ice_ptp_init_phc(struct ice_hw *hw);
/* E822 family functions */
int ice_read_phy_reg_e822(struct ice_hw *hw, u8 port, u16 offset, u32 *val);
int ice_write_phy_reg_e822(struct ice_hw *hw, u8 port, u16 offset, u32 val);
int ice_read_quad_reg_e822(struct ice_hw *hw, u8 quad, u16 offset, u32 *val);
int ice_write_quad_reg_e822(struct ice_hw *hw, u8 quad, u16 offset, u32 val);
int ice_ptp_prep_port_adj_e822(struct ice_hw *hw, u8 port, s64 time);
/**
* ice_e822_time_ref - Get the current TIME_REF from capabilities
* @hw: pointer to the HW structure
*
* Returns the current TIME_REF from the capabilities structure.
*/
static inline enum ice_time_ref_freq ice_e822_time_ref(struct ice_hw *hw)
{
return hw->func_caps.ts_func_info.time_ref;
}
/**
* ice_set_e822_time_ref - Set new TIME_REF
* @hw: pointer to the HW structure
* @time_ref: new TIME_REF to set
*
* Update the TIME_REF in the capabilities structure in response to some
* change, such as an update to the CGU registers.
*/
static inline void
ice_set_e822_time_ref(struct ice_hw *hw, enum ice_time_ref_freq time_ref)
{
hw->func_caps.ts_func_info.time_ref = time_ref;
}
static inline u64 ice_e822_pll_freq(enum ice_time_ref_freq time_ref)
{
return e822_time_ref[time_ref].pll_freq;
}
static inline u64 ice_e822_nominal_incval(enum ice_time_ref_freq time_ref)
{
return e822_time_ref[time_ref].nominal_incval;
}
static inline u64 ice_e822_pps_delay(enum ice_time_ref_freq time_ref)
{
return e822_time_ref[time_ref].pps_delay;
}
/* E822 Vernier calibration functions */
int ice_stop_phy_timer_e822(struct ice_hw *hw, u8 port, bool soft_reset);
int ice_start_phy_timer_e822(struct ice_hw *hw, u8 port, bool bypass);
int ice_phy_exit_bypass_e822(struct ice_hw *hw, u8 port);
/* E810 family functions */
int ice_ptp_init_phy_e810(struct ice_hw *hw);
@ -36,19 +195,194 @@ bool ice_is_pca9575_present(struct ice_hw *hw);
#define PFTSYN_SEM_BYTES 4
#define ICE_PTP_CLOCK_INDEX_0 0x00
#define ICE_PTP_CLOCK_INDEX_1 0x01
/* PHY timer commands */
#define SEL_CPK_SRC 8
#define SEL_PHY_SRC 3
/* Time Sync command Definitions */
#define GLTSYN_CMD_INIT_TIME BIT(0)
#define GLTSYN_CMD_INIT_INCVAL BIT(1)
#define GLTSYN_CMD_INIT_TIME_INCVAL (BIT(0) | BIT(1))
#define GLTSYN_CMD_ADJ_TIME BIT(2)
#define GLTSYN_CMD_ADJ_INIT_TIME (BIT(2) | BIT(3))
#define GLTSYN_CMD_READ_TIME BIT(7)
/* PHY port Time Sync command definitions */
#define PHY_CMD_INIT_TIME BIT(0)
#define PHY_CMD_INIT_INCVAL BIT(1)
#define PHY_CMD_ADJ_TIME (BIT(0) | BIT(1))
#define PHY_CMD_ADJ_TIME_AT_TIME (BIT(0) | BIT(2))
#define PHY_CMD_READ_TIME (BIT(0) | BIT(1) | BIT(2))
#define TS_CMD_MASK_E810 0xFF
#define TS_CMD_MASK 0xF
#define SYNC_EXEC_CMD 0x3
/* Macros to derive port low and high addresses on both quads */
#define P_Q0_L(a, p) ((((a) + (0x2000 * (p)))) & 0xFFFF)
#define P_Q0_H(a, p) ((((a) + (0x2000 * (p)))) >> 16)
#define P_Q1_L(a, p) ((((a) - (0x2000 * ((p) - ICE_PORTS_PER_QUAD)))) & 0xFFFF)
#define P_Q1_H(a, p) ((((a) - (0x2000 * ((p) - ICE_PORTS_PER_QUAD)))) >> 16)
/* PHY QUAD register base addresses */
#define Q_0_BASE 0x94000
#define Q_1_BASE 0x114000
/* Timestamp memory reset registers */
#define Q_REG_TS_CTRL 0x618
#define Q_REG_TS_CTRL_S 0
#define Q_REG_TS_CTRL_M BIT(0)
/* Timestamp availability status registers */
#define Q_REG_TX_MEMORY_STATUS_L 0xCF0
#define Q_REG_TX_MEMORY_STATUS_U 0xCF4
/* Tx FIFO status registers */
#define Q_REG_FIFO23_STATUS 0xCF8
#define Q_REG_FIFO01_STATUS 0xCFC
#define Q_REG_FIFO02_S 0
#define Q_REG_FIFO02_M ICE_M(0x3FF, 0)
#define Q_REG_FIFO13_S 10
#define Q_REG_FIFO13_M ICE_M(0x3FF, 10)
/* Interrupt control Config registers */
#define Q_REG_TX_MEM_GBL_CFG 0xC08
#define Q_REG_TX_MEM_GBL_CFG_LANE_TYPE_S 0
#define Q_REG_TX_MEM_GBL_CFG_LANE_TYPE_M BIT(0)
#define Q_REG_TX_MEM_GBL_CFG_TX_TYPE_S 1
#define Q_REG_TX_MEM_GBL_CFG_TX_TYPE_M ICE_M(0xFF, 1)
#define Q_REG_TX_MEM_GBL_CFG_INTR_THR_S 9
#define Q_REG_TX_MEM_GBL_CFG_INTR_THR_M ICE_M(0x3F, 9)
#define Q_REG_TX_MEM_GBL_CFG_INTR_ENA_S 15
#define Q_REG_TX_MEM_GBL_CFG_INTR_ENA_M BIT(15)
/* Tx Timestamp data registers */
#define Q_REG_TX_MEMORY_BANK_START 0xA00
/* PHY port register base addresses */
#define P_0_BASE 0x80000
#define P_4_BASE 0x106000
/* Timestamp init registers */
#define P_REG_RX_TIMER_INC_PRE_L 0x46C
#define P_REG_RX_TIMER_INC_PRE_U 0x470
#define P_REG_TX_TIMER_INC_PRE_L 0x44C
#define P_REG_TX_TIMER_INC_PRE_U 0x450
/* Timestamp match and adjust target registers */
#define P_REG_RX_TIMER_CNT_ADJ_L 0x474
#define P_REG_RX_TIMER_CNT_ADJ_U 0x478
#define P_REG_TX_TIMER_CNT_ADJ_L 0x454
#define P_REG_TX_TIMER_CNT_ADJ_U 0x458
/* Timestamp capture registers */
#define P_REG_RX_CAPTURE_L 0x4D8
#define P_REG_RX_CAPTURE_U 0x4DC
#define P_REG_TX_CAPTURE_L 0x4B4
#define P_REG_TX_CAPTURE_U 0x4B8
/* Timestamp PHY incval registers */
#define P_REG_TIMETUS_L 0x410
#define P_REG_TIMETUS_U 0x414
#define P_REG_40B_LOW_M 0xFF
#define P_REG_40B_HIGH_S 8
/* PHY window length registers */
#define P_REG_WL 0x40C
#define PTP_VERNIER_WL 0x111ed
/* PHY start registers */
#define P_REG_PS 0x408
#define P_REG_PS_START_S 0
#define P_REG_PS_START_M BIT(0)
#define P_REG_PS_BYPASS_MODE_S 1
#define P_REG_PS_BYPASS_MODE_M BIT(1)
#define P_REG_PS_ENA_CLK_S 2
#define P_REG_PS_ENA_CLK_M BIT(2)
#define P_REG_PS_LOAD_OFFSET_S 3
#define P_REG_PS_LOAD_OFFSET_M BIT(3)
#define P_REG_PS_SFT_RESET_S 11
#define P_REG_PS_SFT_RESET_M BIT(11)
/* PHY offset valid registers */
#define P_REG_TX_OV_STATUS 0x4D4
#define P_REG_TX_OV_STATUS_OV_S 0
#define P_REG_TX_OV_STATUS_OV_M BIT(0)
#define P_REG_RX_OV_STATUS 0x4F8
#define P_REG_RX_OV_STATUS_OV_S 0
#define P_REG_RX_OV_STATUS_OV_M BIT(0)
/* PHY offset ready registers */
#define P_REG_TX_OR 0x45C
#define P_REG_RX_OR 0x47C
/* PHY total offset registers */
#define P_REG_TOTAL_RX_OFFSET_L 0x460
#define P_REG_TOTAL_RX_OFFSET_U 0x464
#define P_REG_TOTAL_TX_OFFSET_L 0x440
#define P_REG_TOTAL_TX_OFFSET_U 0x444
/* Timestamp PAR/PCS registers */
#define P_REG_UIX66_10G_40G_L 0x480
#define P_REG_UIX66_10G_40G_U 0x484
#define P_REG_UIX66_25G_100G_L 0x488
#define P_REG_UIX66_25G_100G_U 0x48C
#define P_REG_DESK_PAR_RX_TUS_L 0x490
#define P_REG_DESK_PAR_RX_TUS_U 0x494
#define P_REG_DESK_PAR_TX_TUS_L 0x498
#define P_REG_DESK_PAR_TX_TUS_U 0x49C
#define P_REG_DESK_PCS_RX_TUS_L 0x4A0
#define P_REG_DESK_PCS_RX_TUS_U 0x4A4
#define P_REG_DESK_PCS_TX_TUS_L 0x4A8
#define P_REG_DESK_PCS_TX_TUS_U 0x4AC
#define P_REG_PAR_RX_TUS_L 0x420
#define P_REG_PAR_RX_TUS_U 0x424
#define P_REG_PAR_TX_TUS_L 0x428
#define P_REG_PAR_TX_TUS_U 0x42C
#define P_REG_PCS_RX_TUS_L 0x430
#define P_REG_PCS_RX_TUS_U 0x434
#define P_REG_PCS_TX_TUS_L 0x438
#define P_REG_PCS_TX_TUS_U 0x43C
#define P_REG_PAR_RX_TIME_L 0x4F0
#define P_REG_PAR_RX_TIME_U 0x4F4
#define P_REG_PAR_TX_TIME_L 0x4CC
#define P_REG_PAR_TX_TIME_U 0x4D0
#define P_REG_PAR_PCS_RX_OFFSET_L 0x4E8
#define P_REG_PAR_PCS_RX_OFFSET_U 0x4EC
#define P_REG_PAR_PCS_TX_OFFSET_L 0x4C4
#define P_REG_PAR_PCS_TX_OFFSET_U 0x4C8
#define P_REG_LINK_SPEED 0x4FC
#define P_REG_LINK_SPEED_SERDES_S 0
#define P_REG_LINK_SPEED_SERDES_M ICE_M(0x7, 0)
#define P_REG_LINK_SPEED_FEC_MODE_S 3
#define P_REG_LINK_SPEED_FEC_MODE_M ICE_M(0x3, 3)
#define P_REG_LINK_SPEED_FEC_MODE(reg) \
(((reg) & P_REG_LINK_SPEED_FEC_MODE_M) >> \
P_REG_LINK_SPEED_FEC_MODE_S)
/* PHY timestamp related registers */
#define P_REG_PMD_ALIGNMENT 0x0FC
#define P_REG_RX_80_TO_160_CNT 0x6FC
#define P_REG_RX_80_TO_160_CNT_RXCYC_S 0
#define P_REG_RX_80_TO_160_CNT_RXCYC_M BIT(0)
#define P_REG_RX_40_TO_160_CNT 0x8FC
#define P_REG_RX_40_TO_160_CNT_RXCYC_S 0
#define P_REG_RX_40_TO_160_CNT_RXCYC_M ICE_M(0x3, 0)
/* Rx FIFO status registers */
#define P_REG_RX_OV_FS 0x4F8
#define P_REG_RX_OV_FS_FIFO_STATUS_S 2
#define P_REG_RX_OV_FS_FIFO_STATUS_M ICE_M(0x3FF, 2)
/* Timestamp command registers */
#define P_REG_TX_TMR_CMD 0x448
#define P_REG_RX_TMR_CMD 0x468
/* E810 timesync enable register */
#define ETH_GLTSYN_ENA(_i) (0x03000348 + ((_i) * 4))
@ -68,9 +402,20 @@ bool ice_is_pca9575_present(struct ice_hw *hw);
/* Timestamp block macros */
#define TS_LOW_M 0xFFFFFFFF
#define TS_HIGH_M 0xFF
#define TS_HIGH_S 32
#define TS_PHY_LOW_M 0xFF
#define TS_PHY_HIGH_M 0xFFFFFFFF
#define TS_PHY_HIGH_S 8
#define BYTES_PER_IDX_ADDR_L_U 8
#define BYTES_PER_IDX_ADDR_L 4
/* Internal PHY timestamp address */
#define TS_L(a, idx) ((a) + ((idx) * BYTES_PER_IDX_ADDR_L_U))
#define TS_H(a, idx) ((a) + ((idx) * BYTES_PER_IDX_ADDR_L_U + \
BYTES_PER_IDX_ADDR_L))
/* External PHY timestamp address */
#define TS_EXT(a, port, idx) ((a) + (0x1000 * (port)) + \

View file

@ -298,9 +298,30 @@ struct ice_hw_common_caps {
#define ICE_TS_TMR_IDX_ASSOC_S 24
#define ICE_TS_TMR_IDX_ASSOC_M BIT(24)
/* TIME_REF clock rate specification */
enum ice_time_ref_freq {
ICE_TIME_REF_FREQ_25_000 = 0,
ICE_TIME_REF_FREQ_122_880 = 1,
ICE_TIME_REF_FREQ_125_000 = 2,
ICE_TIME_REF_FREQ_153_600 = 3,
ICE_TIME_REF_FREQ_156_250 = 4,
ICE_TIME_REF_FREQ_245_760 = 5,
NUM_ICE_TIME_REF_FREQ
};
/* Clock source specification */
enum ice_clk_src {
ICE_CLK_SRC_TCX0 = 0, /* Temperature compensated oscillator */
ICE_CLK_SRC_TIME_REF = 1, /* Use TIME_REF reference clock */
NUM_ICE_CLK_SRC
};
struct ice_ts_func_info {
/* Function specific info */
u32 clk_freq;
enum ice_time_ref_freq time_ref;
u8 clk_freq;
u8 clk_src;
u8 tmr_index_assoc;
u8 ena;