
This commit back ports the DPLL related commits from the upstream kernel that are identified by Intel to provide the expected SyncE/GNSS functionality. There are totally 46 back ported commits included the four commits I added are used to resolve the conflicts during back porting. The 0046 patch is cherry picked from kernel-6.9. The 0031-0045 patches are cherry picked from kernel-6.8. The 0001-0030 patches are cherry picked from kernel-6.7. We also change the in-tree ice driver version to 6.6.40-stx.2 from 6.6.40-stx.1. * To fix the conflict of 91e43ca0090b ("ice: fix linking when CONFIG_PTP_1588_CLOCK=n"), we cherry pick 12a5a28b565b ("ice: remove ICE_F_PTP_EXTTS feature flag") and 89776a6a702e ("ice: check netlist before enabling ICE_F_GNSS"). Adjust 12a5a28b565b because 0d1b22367ec2 ("ice: fix pin assignment for E810-T without SMA control") already included the part code of 12a5a28b565b. https://git.yoctoproject.org/linux-yocto/commit/?id=0d1b22367ec2 * Cherry pick 7049fd5df7 ("netlink: specs: remove redundant type keys from attributes in subsets") to fix the the conflict of c3c6ab95c397 ("dpll: spec: add support for pin-dpll signal phase offset/adjust.") * Cherry pick be16574609f1 ("ice: introduce hw->phy_model for handling PTP PHY differences") to fix the confilict of 6db5f2cd9ebb ("ice: dpll:fix output pin capabilities"). Verification: - Build kernel and out of tree modules success for rt and std. - Install success onto a All-in-One lab with rt kernel. - Boot up successfully in the lab. - interfaces are up and pass packets for rt and std. - Check dmesg to see DDP package is loaded successfully and the version is 1.3.36.0 for rt and std, that is same with the OOT ice-1.14.9 driver. - The SyncE/GNSS functionality tests were done by the network team. Story: 2011056 Task: 50797 Change-Id: I715480681c7c43d53b0a0126b34135562e9d02a0 Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
343 lines
11 KiB
Diff
343 lines
11 KiB
Diff
From 2cad1ea959a38a58726855eeda1d618d99226774 Mon Sep 17 00:00:00 2001
|
|
From: Arkadiusz Kubalewski <arkadiusz.kubalewski@intel.com>
|
|
Date: Wed, 11 Oct 2023 12:12:35 +0200
|
|
Subject: [PATCH 24/46] ice: dpll: implement phase related callbacks
|
|
|
|
Implement new callback ops related to measurement and adjustment of
|
|
signal phase for pin-dpll in ice driver.
|
|
|
|
Signed-off-by: Arkadiusz Kubalewski <arkadiusz.kubalewski@intel.com>
|
|
Signed-off-by: David S. Miller <davem@davemloft.net>
|
|
(cherry picked from commit 90e1c90750d773fc991833f317b439236e13fc25)
|
|
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
|
---
|
|
drivers/net/ethernet/intel/ice/ice_dpll.c | 220 +++++++++++++++++++++-
|
|
drivers/net/ethernet/intel/ice/ice_dpll.h | 10 +-
|
|
2 files changed, 226 insertions(+), 4 deletions(-)
|
|
|
|
diff --git a/drivers/net/ethernet/intel/ice/ice_dpll.c b/drivers/net/ethernet/intel/ice/ice_dpll.c
|
|
index 1faee9cb944d..835c419ccc74 100644
|
|
--- a/drivers/net/ethernet/intel/ice/ice_dpll.c
|
|
+++ b/drivers/net/ethernet/intel/ice/ice_dpll.c
|
|
@@ -878,6 +878,199 @@ ice_dpll_output_direction(const struct dpll_pin *pin, void *pin_priv,
|
|
return 0;
|
|
}
|
|
|
|
+/**
|
|
+ * ice_dpll_pin_phase_adjust_get - callback for get pin phase adjust value
|
|
+ * @pin: pointer to a pin
|
|
+ * @pin_priv: private data pointer passed on pin registration
|
|
+ * @dpll: registered dpll pointer
|
|
+ * @dpll_priv: private data pointer passed on dpll registration
|
|
+ * @phase_adjust: on success holds pin phase_adjust value
|
|
+ * @extack: error reporting
|
|
+ *
|
|
+ * Dpll subsystem callback. Handler for getting phase adjust value of a pin.
|
|
+ *
|
|
+ * Context: Acquires pf->dplls.lock
|
|
+ * Return:
|
|
+ * * 0 - success
|
|
+ * * negative - error
|
|
+ */
|
|
+static int
|
|
+ice_dpll_pin_phase_adjust_get(const struct dpll_pin *pin, void *pin_priv,
|
|
+ const struct dpll_device *dpll, void *dpll_priv,
|
|
+ s32 *phase_adjust,
|
|
+ struct netlink_ext_ack *extack)
|
|
+{
|
|
+ struct ice_dpll_pin *p = pin_priv;
|
|
+ struct ice_pf *pf = p->pf;
|
|
+
|
|
+ mutex_lock(&pf->dplls.lock);
|
|
+ *phase_adjust = p->phase_adjust;
|
|
+ mutex_unlock(&pf->dplls.lock);
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+/**
|
|
+ * ice_dpll_pin_phase_adjust_set - helper for setting a pin phase adjust value
|
|
+ * @pin: pointer to a pin
|
|
+ * @pin_priv: private data pointer passed on pin registration
|
|
+ * @dpll: registered dpll pointer
|
|
+ * @dpll_priv: private data pointer passed on dpll registration
|
|
+ * @phase_adjust: phase_adjust to be set
|
|
+ * @extack: error reporting
|
|
+ * @type: type of a pin
|
|
+ *
|
|
+ * Helper for dpll subsystem callback. Handler for setting phase adjust value
|
|
+ * of a pin.
|
|
+ *
|
|
+ * Context: Acquires pf->dplls.lock
|
|
+ * Return:
|
|
+ * * 0 - success
|
|
+ * * negative - error
|
|
+ */
|
|
+static int
|
|
+ice_dpll_pin_phase_adjust_set(const struct dpll_pin *pin, void *pin_priv,
|
|
+ const struct dpll_device *dpll, void *dpll_priv,
|
|
+ s32 phase_adjust,
|
|
+ struct netlink_ext_ack *extack,
|
|
+ enum ice_dpll_pin_type type)
|
|
+{
|
|
+ struct ice_dpll_pin *p = pin_priv;
|
|
+ struct ice_dpll *d = dpll_priv;
|
|
+ struct ice_pf *pf = d->pf;
|
|
+ u8 flag, flags_en = 0;
|
|
+ int ret;
|
|
+
|
|
+ mutex_lock(&pf->dplls.lock);
|
|
+ switch (type) {
|
|
+ case ICE_DPLL_PIN_TYPE_INPUT:
|
|
+ flag = ICE_AQC_SET_CGU_IN_CFG_FLG1_UPDATE_DELAY;
|
|
+ if (p->flags[0] & ICE_AQC_GET_CGU_IN_CFG_FLG2_ESYNC_EN)
|
|
+ flags_en |= ICE_AQC_SET_CGU_IN_CFG_FLG2_ESYNC_EN;
|
|
+ if (p->flags[0] & ICE_AQC_GET_CGU_IN_CFG_FLG2_INPUT_EN)
|
|
+ flags_en |= ICE_AQC_SET_CGU_IN_CFG_FLG2_INPUT_EN;
|
|
+ ret = ice_aq_set_input_pin_cfg(&pf->hw, p->idx, flag, flags_en,
|
|
+ 0, phase_adjust);
|
|
+ break;
|
|
+ case ICE_DPLL_PIN_TYPE_OUTPUT:
|
|
+ flag = ICE_AQC_SET_CGU_OUT_CFG_UPDATE_PHASE;
|
|
+ if (p->flags[0] & ICE_AQC_GET_CGU_OUT_CFG_OUT_EN)
|
|
+ flag |= ICE_AQC_SET_CGU_OUT_CFG_OUT_EN;
|
|
+ if (p->flags[0] & ICE_AQC_GET_CGU_OUT_CFG_ESYNC_EN)
|
|
+ flag |= ICE_AQC_SET_CGU_OUT_CFG_ESYNC_EN;
|
|
+ ret = ice_aq_set_output_pin_cfg(&pf->hw, p->idx, flag, 0, 0,
|
|
+ phase_adjust);
|
|
+ break;
|
|
+ default:
|
|
+ ret = -EINVAL;
|
|
+ }
|
|
+ if (!ret)
|
|
+ p->phase_adjust = phase_adjust;
|
|
+ mutex_unlock(&pf->dplls.lock);
|
|
+ if (ret)
|
|
+ NL_SET_ERR_MSG_FMT(extack,
|
|
+ "err:%d %s failed to set pin phase_adjust:%d for pin:%u on dpll:%u\n",
|
|
+ ret,
|
|
+ ice_aq_str(pf->hw.adminq.sq_last_status),
|
|
+ phase_adjust, p->idx, d->dpll_idx);
|
|
+
|
|
+ return ret;
|
|
+}
|
|
+
|
|
+/**
|
|
+ * ice_dpll_input_phase_adjust_set - callback for set input pin phase adjust
|
|
+ * @pin: pointer to a pin
|
|
+ * @pin_priv: private data pointer passed on pin registration
|
|
+ * @dpll: registered dpll pointer
|
|
+ * @dpll_priv: private data pointer passed on dpll registration
|
|
+ * @phase_adjust: phase_adjust to be set
|
|
+ * @extack: error reporting
|
|
+ *
|
|
+ * Dpll subsystem callback. Wraps a handler for setting phase adjust on input
|
|
+ * pin.
|
|
+ *
|
|
+ * Context: Calls a function which acquires pf->dplls.lock
|
|
+ * Return:
|
|
+ * * 0 - success
|
|
+ * * negative - error
|
|
+ */
|
|
+static int
|
|
+ice_dpll_input_phase_adjust_set(const struct dpll_pin *pin, void *pin_priv,
|
|
+ const struct dpll_device *dpll, void *dpll_priv,
|
|
+ s32 phase_adjust,
|
|
+ struct netlink_ext_ack *extack)
|
|
+{
|
|
+ return ice_dpll_pin_phase_adjust_set(pin, pin_priv, dpll, dpll_priv,
|
|
+ phase_adjust, extack,
|
|
+ ICE_DPLL_PIN_TYPE_INPUT);
|
|
+}
|
|
+
|
|
+/**
|
|
+ * ice_dpll_output_phase_adjust_set - callback for set output pin phase adjust
|
|
+ * @pin: pointer to a pin
|
|
+ * @pin_priv: private data pointer passed on pin registration
|
|
+ * @dpll: registered dpll pointer
|
|
+ * @dpll_priv: private data pointer passed on dpll registration
|
|
+ * @phase_adjust: phase_adjust to be set
|
|
+ * @extack: error reporting
|
|
+ *
|
|
+ * Dpll subsystem callback. Wraps a handler for setting phase adjust on output
|
|
+ * pin.
|
|
+ *
|
|
+ * Context: Calls a function which acquires pf->dplls.lock
|
|
+ * Return:
|
|
+ * * 0 - success
|
|
+ * * negative - error
|
|
+ */
|
|
+static int
|
|
+ice_dpll_output_phase_adjust_set(const struct dpll_pin *pin, void *pin_priv,
|
|
+ const struct dpll_device *dpll, void *dpll_priv,
|
|
+ s32 phase_adjust,
|
|
+ struct netlink_ext_ack *extack)
|
|
+{
|
|
+ return ice_dpll_pin_phase_adjust_set(pin, pin_priv, dpll, dpll_priv,
|
|
+ phase_adjust, extack,
|
|
+ ICE_DPLL_PIN_TYPE_OUTPUT);
|
|
+}
|
|
+
|
|
+#define ICE_DPLL_PHASE_OFFSET_DIVIDER 100
|
|
+#define ICE_DPLL_PHASE_OFFSET_FACTOR \
|
|
+ (DPLL_PHASE_OFFSET_DIVIDER / ICE_DPLL_PHASE_OFFSET_DIVIDER)
|
|
+/**
|
|
+ * ice_dpll_phase_offset_get - callback for get dpll phase shift value
|
|
+ * @pin: pointer to a pin
|
|
+ * @pin_priv: private data pointer passed on pin registration
|
|
+ * @dpll: registered dpll pointer
|
|
+ * @dpll_priv: private data pointer passed on dpll registration
|
|
+ * @phase_offset: on success holds pin phase_offset value
|
|
+ * @extack: error reporting
|
|
+ *
|
|
+ * Dpll subsystem callback. Handler for getting phase shift value between
|
|
+ * dpll's input and output.
|
|
+ *
|
|
+ * Context: Acquires pf->dplls.lock
|
|
+ * Return:
|
|
+ * * 0 - success
|
|
+ * * negative - error
|
|
+ */
|
|
+static int
|
|
+ice_dpll_phase_offset_get(const struct dpll_pin *pin, void *pin_priv,
|
|
+ const struct dpll_device *dpll, void *dpll_priv,
|
|
+ s64 *phase_offset, struct netlink_ext_ack *extack)
|
|
+{
|
|
+ struct ice_dpll *d = dpll_priv;
|
|
+ struct ice_pf *pf = d->pf;
|
|
+
|
|
+ mutex_lock(&pf->dplls.lock);
|
|
+ if (d->active_input == pin)
|
|
+ *phase_offset = d->phase_offset * ICE_DPLL_PHASE_OFFSET_FACTOR;
|
|
+ else
|
|
+ *phase_offset = 0;
|
|
+ mutex_unlock(&pf->dplls.lock);
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
/**
|
|
* ice_dpll_rclk_state_on_pin_set - set a state on rclk pin
|
|
* @pin: pointer to a pin
|
|
@@ -993,6 +1186,9 @@ static const struct dpll_pin_ops ice_dpll_input_ops = {
|
|
.prio_get = ice_dpll_input_prio_get,
|
|
.prio_set = ice_dpll_input_prio_set,
|
|
.direction_get = ice_dpll_input_direction,
|
|
+ .phase_adjust_get = ice_dpll_pin_phase_adjust_get,
|
|
+ .phase_adjust_set = ice_dpll_input_phase_adjust_set,
|
|
+ .phase_offset_get = ice_dpll_phase_offset_get,
|
|
};
|
|
|
|
static const struct dpll_pin_ops ice_dpll_output_ops = {
|
|
@@ -1001,6 +1197,8 @@ static const struct dpll_pin_ops ice_dpll_output_ops = {
|
|
.state_on_dpll_get = ice_dpll_output_state_get,
|
|
.state_on_dpll_set = ice_dpll_output_state_set,
|
|
.direction_get = ice_dpll_output_direction,
|
|
+ .phase_adjust_get = ice_dpll_pin_phase_adjust_get,
|
|
+ .phase_adjust_set = ice_dpll_output_phase_adjust_set,
|
|
};
|
|
|
|
static const struct dpll_device_ops ice_dpll_ops = {
|
|
@@ -1031,6 +1229,8 @@ static u64 ice_generate_clock_id(struct ice_pf *pf)
|
|
*/
|
|
static void ice_dpll_notify_changes(struct ice_dpll *d)
|
|
{
|
|
+ bool pin_notified = false;
|
|
+
|
|
if (d->prev_dpll_state != d->dpll_state) {
|
|
d->prev_dpll_state = d->dpll_state;
|
|
dpll_device_change_ntf(d->dpll);
|
|
@@ -1039,7 +1239,14 @@ static void ice_dpll_notify_changes(struct ice_dpll *d)
|
|
if (d->prev_input)
|
|
dpll_pin_change_ntf(d->prev_input);
|
|
d->prev_input = d->active_input;
|
|
- if (d->active_input)
|
|
+ if (d->active_input) {
|
|
+ dpll_pin_change_ntf(d->active_input);
|
|
+ pin_notified = true;
|
|
+ }
|
|
+ }
|
|
+ if (d->prev_phase_offset != d->phase_offset) {
|
|
+ d->prev_phase_offset = d->phase_offset;
|
|
+ if (!pin_notified && d->active_input)
|
|
dpll_pin_change_ntf(d->active_input);
|
|
}
|
|
}
|
|
@@ -1065,7 +1272,7 @@ ice_dpll_update_state(struct ice_pf *pf, struct ice_dpll *d, bool init)
|
|
|
|
ret = ice_get_cgu_state(&pf->hw, d->dpll_idx, d->prev_dpll_state,
|
|
&d->input_idx, &d->ref_state, &d->eec_mode,
|
|
- &d->phase_shift, &d->dpll_state);
|
|
+ &d->phase_offset, &d->dpll_state);
|
|
|
|
dev_dbg(ice_pf_to_dev(pf),
|
|
"update dpll=%d, prev_src_idx:%u, src_idx:%u, state:%d, prev:%d mode:%d\n",
|
|
@@ -1656,6 +1863,15 @@ ice_dpll_init_info_direct_pins(struct ice_pf *pf,
|
|
return ret;
|
|
pins[i].prop.capabilities |=
|
|
DPLL_PIN_CAPABILITIES_PRIORITY_CAN_CHANGE;
|
|
+ pins[i].prop.phase_range.min =
|
|
+ pf->dplls.input_phase_adj_max;
|
|
+ pins[i].prop.phase_range.max =
|
|
+ -pf->dplls.input_phase_adj_max;
|
|
+ } else {
|
|
+ pins[i].prop.phase_range.min =
|
|
+ pf->dplls.output_phase_adj_max;
|
|
+ pins[i].prop.phase_range.max =
|
|
+ -pf->dplls.output_phase_adj_max;
|
|
}
|
|
pins[i].prop.capabilities |=
|
|
DPLL_PIN_CAPABILITIES_STATE_CAN_CHANGE;
|
|
diff --git a/drivers/net/ethernet/intel/ice/ice_dpll.h b/drivers/net/ethernet/intel/ice/ice_dpll.h
|
|
index 2dfe764b81e1..bb32b6d88373 100644
|
|
--- a/drivers/net/ethernet/intel/ice/ice_dpll.h
|
|
+++ b/drivers/net/ethernet/intel/ice/ice_dpll.h
|
|
@@ -19,6 +19,7 @@
|
|
* @state: state of a pin
|
|
* @prop: pin properties
|
|
* @freq: current frequency of a pin
|
|
+ * @phase_adjust: current phase adjust value
|
|
*/
|
|
struct ice_dpll_pin {
|
|
struct dpll_pin *pin;
|
|
@@ -30,6 +31,7 @@ struct ice_dpll_pin {
|
|
u8 state[ICE_DPLL_RCLK_NUM_MAX];
|
|
struct dpll_pin_properties prop;
|
|
u32 freq;
|
|
+ s32 phase_adjust;
|
|
};
|
|
|
|
/** ice_dpll - store info required for DPLL control
|
|
@@ -40,7 +42,8 @@ struct ice_dpll_pin {
|
|
* @prev_input_idx: previously selected input index
|
|
* @ref_state: state of dpll reference signals
|
|
* @eec_mode: eec_mode dpll is configured for
|
|
- * @phase_shift: phase shift delay of a dpll
|
|
+ * @phase_offset: phase offset of active pin vs dpll signal
|
|
+ * @prev_phase_offset: previous phase offset of active pin vs dpll signal
|
|
* @input_prio: priorities of each input
|
|
* @dpll_state: current dpll sync state
|
|
* @prev_dpll_state: last dpll sync state
|
|
@@ -55,7 +58,8 @@ struct ice_dpll {
|
|
u8 prev_input_idx;
|
|
u8 ref_state;
|
|
u8 eec_mode;
|
|
- s64 phase_shift;
|
|
+ s64 phase_offset;
|
|
+ s64 prev_phase_offset;
|
|
u8 *input_prio;
|
|
enum dpll_lock_status dpll_state;
|
|
enum dpll_lock_status prev_dpll_state;
|
|
@@ -78,6 +82,8 @@ struct ice_dpll {
|
|
* @cgu_state_acq_err_num: number of errors returned during periodic work
|
|
* @base_rclk_idx: idx of first pin used for clock revocery pins
|
|
* @clock_id: clock_id of dplls
|
|
+ * @input_phase_adj_max: max phase adjust value for an input pins
|
|
+ * @output_phase_adj_max: max phase adjust value for an output pins
|
|
*/
|
|
struct ice_dplls {
|
|
struct kthread_worker *kworker;
|
|
--
|
|
2.43.0
|
|
|