Commit ad1df4f2 authored by Arkadiusz Kubalewski's avatar Arkadiusz Kubalewski Committed by Paolo Abeni
Browse files

ice: dpll: Support E825-C SyncE and dynamic pin discovery



Implement SyncE support for the E825-C Ethernet controller using the
DPLL subsystem. Unlike E810, the E825-C architecture relies on platform
firmware (ACPI) to describe connections between the NIC's recovered clock
outputs and external DPLL inputs.

Implement the following mechanisms to support this architecture:

1. Discovery Mechanism: The driver parses the 'dpll-pins' and 'dpll-pin names'
   firmware properties to identify the external DPLL pins (parents)
   corresponding to its RCLK outputs ("rclk0", "rclk1"). It uses
   fwnode_dpll_pin_find() to locate these parent pins in the DPLL core.

2. Asynchronous Registration: Since the platform DPLL driver (e.g.
   zl3073x) may probe independently of the network driver, utilize
   the DPLL notifier chain The driver listens for DPLL_PIN_CREATED
   events to detect when the parent MUX pins become available, then
   registers its own Recovered Clock (RCLK) pins as children of those
   parents.

3. Hardware Configuration: Implement the specific register access logic
   for E825-C CGU (Clock Generation Unit) registers (R10, R11). This
   includes configuring the bypass MUXes and clock dividers required to
   drive SyncE signals.

4. Split Initialization: Refactor `ice_dpll_init()` to separate the
   static initialization path of E810 from the dynamic, firmware-driven
   path required for E825-C.

Reviewed-by: default avatarAleksandr Loktionov <aleksandr.loktionov@intel.com>
Co-developed-by: default avatarIvan Vecera <ivecera@redhat.com>
Signed-off-by: default avatarIvan Vecera <ivecera@redhat.com>
Co-developed-by: default avatarGrzegorz Nitka <grzegorz.nitka@intel.com>
Signed-off-by: default avatarGrzegorz Nitka <grzegorz.nitka@intel.com>
Signed-off-by: default avatarArkadiusz Kubalewski <arkadiusz.kubalewski@intel.com>
Link: https://patch.msgid.link/20260203174002.705176-10-ivecera@redhat.com


Signed-off-by: default avatarPaolo Abeni <pabeni@redhat.com>
parent 085ca5d2
Loading
Loading
Loading
Loading
+655 −90

File changed.

Preview size limit exceeded, changes collapsed.

+26 −0
Original line number Diff line number Diff line
@@ -20,6 +20,12 @@ enum ice_dpll_pin_sw {
	ICE_DPLL_PIN_SW_NUM
};

struct ice_dpll_pin_work {
	struct work_struct work;
	unsigned long action;
	struct ice_dpll_pin *pin;
};

/** ice_dpll_pin - store info about pins
 * @pin: dpll pin structure
 * @pf: pointer to pf, which has registered the dpll_pin
@@ -39,6 +45,8 @@ struct ice_dpll_pin {
	struct dpll_pin *pin;
	struct ice_pf *pf;
	dpll_tracker tracker;
	struct fwnode_handle *fwnode;
	struct notifier_block nb;
	u8 idx;
	u8 num_parents;
	u8 parent_idx[ICE_DPLL_RCLK_NUM_MAX];
@@ -118,7 +126,9 @@ struct ice_dpll {
struct ice_dplls {
	struct kthread_worker *kworker;
	struct kthread_delayed_work work;
	struct workqueue_struct *wq;
	struct mutex lock;
	struct completion dpll_init;
	struct ice_dpll eec;
	struct ice_dpll pps;
	struct ice_dpll_pin *inputs;
@@ -147,3 +157,19 @@ static inline void ice_dpll_deinit(struct ice_pf *pf) { }
#endif

#endif

#define ICE_CGU_R10				0x28
#define ICE_CGU_R10_SYNCE_CLKO_SEL		GENMASK(8, 5)
#define ICE_CGU_R10_SYNCE_CLKODIV_M1		GENMASK(13, 9)
#define ICE_CGU_R10_SYNCE_CLKODIV_LOAD		BIT(14)
#define ICE_CGU_R10_SYNCE_DCK_RST		BIT(15)
#define ICE_CGU_R10_SYNCE_ETHCLKO_SEL		GENMASK(18, 16)
#define ICE_CGU_R10_SYNCE_ETHDIV_M1		GENMASK(23, 19)
#define ICE_CGU_R10_SYNCE_ETHDIV_LOAD		BIT(24)
#define ICE_CGU_R10_SYNCE_DCK2_RST		BIT(25)
#define ICE_CGU_R10_SYNCE_S_REF_CLK		GENMASK(31, 27)

#define ICE_CGU_R11				0x2C
#define ICE_CGU_R11_SYNCE_S_BYP_CLK		GENMASK(6, 1)

#define ICE_CGU_BYPASS_MUX_OFFSET_E825C		3
+3 −0
Original line number Diff line number Diff line
@@ -3989,6 +3989,9 @@ void ice_init_feature_support(struct ice_pf *pf)
		break;
	}

	if (pf->hw.mac_type == ICE_MAC_GENERIC_3K_E825)
		ice_set_feature_support(pf, ICE_F_PHY_RCLK);

	if (pf->hw.mac_type == ICE_MAC_E830) {
		ice_set_feature_support(pf, ICE_F_MBX_LIMIT);
		ice_set_feature_support(pf, ICE_F_GCS);
+32 −0
Original line number Diff line number Diff line
@@ -1341,6 +1341,38 @@ void ice_ptp_link_change(struct ice_pf *pf, bool linkup)
	if (pf->hw.reset_ongoing)
		return;

	if (hw->mac_type == ICE_MAC_GENERIC_3K_E825) {
		int pin, err;

		if (!test_bit(ICE_FLAG_DPLL, pf->flags))
			return;

		mutex_lock(&pf->dplls.lock);
		for (pin = 0; pin < ICE_SYNCE_CLK_NUM; pin++) {
			enum ice_synce_clk clk_pin;
			bool active;
			u8 port_num;

			port_num = ptp_port->port_num;
			clk_pin = (enum ice_synce_clk)pin;
			err = ice_tspll_bypass_mux_active_e825c(hw,
								port_num,
								&active,
								clk_pin);
			if (WARN_ON_ONCE(err)) {
				mutex_unlock(&pf->dplls.lock);
				return;
			}

			err = ice_tspll_cfg_synce_ethdiv_e825c(hw, clk_pin);
			if (active && WARN_ON_ONCE(err)) {
				mutex_unlock(&pf->dplls.lock);
				return;
			}
		}
		mutex_unlock(&pf->dplls.lock);
	}

	switch (hw->mac_type) {
	case ICE_MAC_E810:
	case ICE_MAC_E830:
+8 −1
Original line number Diff line number Diff line
@@ -5903,7 +5903,14 @@ int ice_get_cgu_rclk_pin_info(struct ice_hw *hw, u8 *base_idx, u8 *pin_num)
			*base_idx = SI_REF1P;
		else
			ret = -ENODEV;

		break;
	case ICE_DEV_ID_E825C_BACKPLANE:
	case ICE_DEV_ID_E825C_QSFP:
	case ICE_DEV_ID_E825C_SFP:
	case ICE_DEV_ID_E825C_SGMII:
		*pin_num = ICE_SYNCE_CLK_NUM;
		*base_idx = 0;
		ret = 0;
		break;
	default:
		ret = -ENODEV;
Loading