mirror of
https://github.com/torvalds/linux
synced 2024-09-30 00:10:51 +00:00
ice: add callbacks for Embedded SYNC enablement on dpll pins
Allow the user to get and set configuration of Embedded SYNC feature on the ice driver dpll pins. Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com> Signed-off-by: Arkadiusz Kubalewski <arkadiusz.kubalewski@intel.com> Reviewed-by: Jiri Pirko <jiri@nvidia.com> Link: https://patch.msgid.link/20240822222513.255179-3-arkadiusz.kubalewski@intel.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
cda1fba15c
commit
87abc5666a
|
@ -9,6 +9,7 @@
|
||||||
#define ICE_CGU_STATE_ACQ_ERR_THRESHOLD 50
|
#define ICE_CGU_STATE_ACQ_ERR_THRESHOLD 50
|
||||||
#define ICE_DPLL_PIN_IDX_INVALID 0xff
|
#define ICE_DPLL_PIN_IDX_INVALID 0xff
|
||||||
#define ICE_DPLL_RCLK_NUM_PER_PF 1
|
#define ICE_DPLL_RCLK_NUM_PER_PF 1
|
||||||
|
#define ICE_DPLL_PIN_ESYNC_PULSE_HIGH_PERCENT 25
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* enum ice_dpll_pin_type - enumerate ice pin types:
|
* enum ice_dpll_pin_type - enumerate ice pin types:
|
||||||
|
@ -30,6 +31,10 @@ static const char * const pin_type_name[] = {
|
||||||
[ICE_DPLL_PIN_TYPE_RCLK_INPUT] = "rclk-input",
|
[ICE_DPLL_PIN_TYPE_RCLK_INPUT] = "rclk-input",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const struct dpll_pin_frequency ice_esync_range[] = {
|
||||||
|
DPLL_PIN_FREQUENCY_RANGE(0, DPLL_PIN_FREQUENCY_1_HZ),
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ice_dpll_is_reset - check if reset is in progress
|
* ice_dpll_is_reset - check if reset is in progress
|
||||||
* @pf: private board structure
|
* @pf: private board structure
|
||||||
|
@ -394,8 +399,8 @@ ice_dpll_pin_state_update(struct ice_pf *pf, struct ice_dpll_pin *pin,
|
||||||
|
|
||||||
switch (pin_type) {
|
switch (pin_type) {
|
||||||
case ICE_DPLL_PIN_TYPE_INPUT:
|
case ICE_DPLL_PIN_TYPE_INPUT:
|
||||||
ret = ice_aq_get_input_pin_cfg(&pf->hw, pin->idx, NULL, NULL,
|
ret = ice_aq_get_input_pin_cfg(&pf->hw, pin->idx, &pin->status,
|
||||||
NULL, &pin->flags[0],
|
NULL, NULL, &pin->flags[0],
|
||||||
&pin->freq, &pin->phase_adjust);
|
&pin->freq, &pin->phase_adjust);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto err;
|
goto err;
|
||||||
|
@ -430,7 +435,7 @@ ice_dpll_pin_state_update(struct ice_pf *pf, struct ice_dpll_pin *pin,
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
parent &= ICE_AQC_GET_CGU_OUT_CFG_DPLL_SRC_SEL;
|
parent &= ICE_AQC_GET_CGU_OUT_CFG_DPLL_SRC_SEL;
|
||||||
if (ICE_AQC_SET_CGU_OUT_CFG_OUT_EN & pin->flags[0]) {
|
if (ICE_AQC_GET_CGU_OUT_CFG_OUT_EN & pin->flags[0]) {
|
||||||
pin->state[pf->dplls.eec.dpll_idx] =
|
pin->state[pf->dplls.eec.dpll_idx] =
|
||||||
parent == pf->dplls.eec.dpll_idx ?
|
parent == pf->dplls.eec.dpll_idx ?
|
||||||
DPLL_PIN_STATE_CONNECTED :
|
DPLL_PIN_STATE_CONNECTED :
|
||||||
|
@ -1098,6 +1103,214 @@ ice_dpll_phase_offset_get(const struct dpll_pin *pin, void *pin_priv,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ice_dpll_output_esync_set - callback for setting embedded sync
|
||||||
|
* @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
|
||||||
|
* @freq: requested embedded sync frequency
|
||||||
|
* @extack: error reporting
|
||||||
|
*
|
||||||
|
* Dpll subsystem callback. Handler for setting embedded sync frequency value
|
||||||
|
* on output pin.
|
||||||
|
*
|
||||||
|
* Context: Acquires pf->dplls.lock
|
||||||
|
* Return:
|
||||||
|
* * 0 - success
|
||||||
|
* * negative - error
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
ice_dpll_output_esync_set(const struct dpll_pin *pin, void *pin_priv,
|
||||||
|
const struct dpll_device *dpll, void *dpll_priv,
|
||||||
|
u64 freq, struct netlink_ext_ack *extack)
|
||||||
|
{
|
||||||
|
struct ice_dpll_pin *p = pin_priv;
|
||||||
|
struct ice_dpll *d = dpll_priv;
|
||||||
|
struct ice_pf *pf = d->pf;
|
||||||
|
u8 flags = 0;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (ice_dpll_is_reset(pf, extack))
|
||||||
|
return -EBUSY;
|
||||||
|
mutex_lock(&pf->dplls.lock);
|
||||||
|
if (p->flags[0] & ICE_AQC_GET_CGU_OUT_CFG_OUT_EN)
|
||||||
|
flags = ICE_AQC_SET_CGU_OUT_CFG_OUT_EN;
|
||||||
|
if (freq == DPLL_PIN_FREQUENCY_1_HZ) {
|
||||||
|
if (p->flags[0] & ICE_AQC_GET_CGU_OUT_CFG_ESYNC_EN) {
|
||||||
|
ret = 0;
|
||||||
|
} else {
|
||||||
|
flags |= ICE_AQC_SET_CGU_OUT_CFG_ESYNC_EN;
|
||||||
|
ret = ice_aq_set_output_pin_cfg(&pf->hw, p->idx, flags,
|
||||||
|
0, 0, 0);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!(p->flags[0] & ICE_AQC_GET_CGU_OUT_CFG_ESYNC_EN)) {
|
||||||
|
ret = 0;
|
||||||
|
} else {
|
||||||
|
flags &= ~ICE_AQC_SET_CGU_OUT_CFG_ESYNC_EN;
|
||||||
|
ret = ice_aq_set_output_pin_cfg(&pf->hw, p->idx, flags,
|
||||||
|
0, 0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mutex_unlock(&pf->dplls.lock);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ice_dpll_output_esync_get - callback for getting embedded sync config
|
||||||
|
* @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
|
||||||
|
* @esync: on success holds embedded sync pin properties
|
||||||
|
* @extack: error reporting
|
||||||
|
*
|
||||||
|
* Dpll subsystem callback. Handler for getting embedded sync frequency value
|
||||||
|
* and capabilities on output pin.
|
||||||
|
*
|
||||||
|
* Context: Acquires pf->dplls.lock
|
||||||
|
* Return:
|
||||||
|
* * 0 - success
|
||||||
|
* * negative - error
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
ice_dpll_output_esync_get(const struct dpll_pin *pin, void *pin_priv,
|
||||||
|
const struct dpll_device *dpll, void *dpll_priv,
|
||||||
|
struct dpll_pin_esync *esync,
|
||||||
|
struct netlink_ext_ack *extack)
|
||||||
|
{
|
||||||
|
struct ice_dpll_pin *p = pin_priv;
|
||||||
|
struct ice_dpll *d = dpll_priv;
|
||||||
|
struct ice_pf *pf = d->pf;
|
||||||
|
|
||||||
|
if (ice_dpll_is_reset(pf, extack))
|
||||||
|
return -EBUSY;
|
||||||
|
mutex_lock(&pf->dplls.lock);
|
||||||
|
if (!(p->flags[0] & ICE_AQC_GET_CGU_OUT_CFG_ESYNC_ABILITY) ||
|
||||||
|
p->freq != DPLL_PIN_FREQUENCY_10_MHZ) {
|
||||||
|
mutex_unlock(&pf->dplls.lock);
|
||||||
|
return -EOPNOTSUPP;
|
||||||
|
}
|
||||||
|
esync->range = ice_esync_range;
|
||||||
|
esync->range_num = ARRAY_SIZE(ice_esync_range);
|
||||||
|
if (p->flags[0] & ICE_AQC_GET_CGU_OUT_CFG_ESYNC_EN) {
|
||||||
|
esync->freq = DPLL_PIN_FREQUENCY_1_HZ;
|
||||||
|
esync->pulse = ICE_DPLL_PIN_ESYNC_PULSE_HIGH_PERCENT;
|
||||||
|
} else {
|
||||||
|
esync->freq = 0;
|
||||||
|
esync->pulse = 0;
|
||||||
|
}
|
||||||
|
mutex_unlock(&pf->dplls.lock);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ice_dpll_input_esync_set - callback for setting embedded sync
|
||||||
|
* @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
|
||||||
|
* @freq: requested embedded sync frequency
|
||||||
|
* @extack: error reporting
|
||||||
|
*
|
||||||
|
* Dpll subsystem callback. Handler for setting embedded sync frequency value
|
||||||
|
* on input pin.
|
||||||
|
*
|
||||||
|
* Context: Acquires pf->dplls.lock
|
||||||
|
* Return:
|
||||||
|
* * 0 - success
|
||||||
|
* * negative - error
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
ice_dpll_input_esync_set(const struct dpll_pin *pin, void *pin_priv,
|
||||||
|
const struct dpll_device *dpll, void *dpll_priv,
|
||||||
|
u64 freq, struct netlink_ext_ack *extack)
|
||||||
|
{
|
||||||
|
struct ice_dpll_pin *p = pin_priv;
|
||||||
|
struct ice_dpll *d = dpll_priv;
|
||||||
|
struct ice_pf *pf = d->pf;
|
||||||
|
u8 flags_en = 0;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (ice_dpll_is_reset(pf, extack))
|
||||||
|
return -EBUSY;
|
||||||
|
mutex_lock(&pf->dplls.lock);
|
||||||
|
if (p->flags[0] & ICE_AQC_GET_CGU_IN_CFG_FLG2_INPUT_EN)
|
||||||
|
flags_en = ICE_AQC_SET_CGU_IN_CFG_FLG2_INPUT_EN;
|
||||||
|
if (freq == DPLL_PIN_FREQUENCY_1_HZ) {
|
||||||
|
if (p->flags[0] & ICE_AQC_GET_CGU_IN_CFG_FLG2_ESYNC_EN) {
|
||||||
|
ret = 0;
|
||||||
|
} else {
|
||||||
|
flags_en |= ICE_AQC_SET_CGU_IN_CFG_FLG2_ESYNC_EN;
|
||||||
|
ret = ice_aq_set_input_pin_cfg(&pf->hw, p->idx, 0,
|
||||||
|
flags_en, 0, 0);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!(p->flags[0] & ICE_AQC_GET_CGU_IN_CFG_FLG2_ESYNC_EN)) {
|
||||||
|
ret = 0;
|
||||||
|
} else {
|
||||||
|
flags_en &= ~ICE_AQC_SET_CGU_IN_CFG_FLG2_ESYNC_EN;
|
||||||
|
ret = ice_aq_set_input_pin_cfg(&pf->hw, p->idx, 0,
|
||||||
|
flags_en, 0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mutex_unlock(&pf->dplls.lock);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ice_dpll_input_esync_get - callback for getting embedded sync config
|
||||||
|
* @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
|
||||||
|
* @esync: on success holds embedded sync pin properties
|
||||||
|
* @extack: error reporting
|
||||||
|
*
|
||||||
|
* Dpll subsystem callback. Handler for getting embedded sync frequency value
|
||||||
|
* and capabilities on input pin.
|
||||||
|
*
|
||||||
|
* Context: Acquires pf->dplls.lock
|
||||||
|
* Return:
|
||||||
|
* * 0 - success
|
||||||
|
* * negative - error
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
ice_dpll_input_esync_get(const struct dpll_pin *pin, void *pin_priv,
|
||||||
|
const struct dpll_device *dpll, void *dpll_priv,
|
||||||
|
struct dpll_pin_esync *esync,
|
||||||
|
struct netlink_ext_ack *extack)
|
||||||
|
{
|
||||||
|
struct ice_dpll_pin *p = pin_priv;
|
||||||
|
struct ice_dpll *d = dpll_priv;
|
||||||
|
struct ice_pf *pf = d->pf;
|
||||||
|
|
||||||
|
if (ice_dpll_is_reset(pf, extack))
|
||||||
|
return -EBUSY;
|
||||||
|
mutex_lock(&pf->dplls.lock);
|
||||||
|
if (!(p->status & ICE_AQC_GET_CGU_IN_CFG_STATUS_ESYNC_CAP) ||
|
||||||
|
p->freq != DPLL_PIN_FREQUENCY_10_MHZ) {
|
||||||
|
mutex_unlock(&pf->dplls.lock);
|
||||||
|
return -EOPNOTSUPP;
|
||||||
|
}
|
||||||
|
esync->range = ice_esync_range;
|
||||||
|
esync->range_num = ARRAY_SIZE(ice_esync_range);
|
||||||
|
if (p->flags[0] & ICE_AQC_GET_CGU_IN_CFG_FLG2_ESYNC_EN) {
|
||||||
|
esync->freq = DPLL_PIN_FREQUENCY_1_HZ;
|
||||||
|
esync->pulse = ICE_DPLL_PIN_ESYNC_PULSE_HIGH_PERCENT;
|
||||||
|
} else {
|
||||||
|
esync->freq = 0;
|
||||||
|
esync->pulse = 0;
|
||||||
|
}
|
||||||
|
mutex_unlock(&pf->dplls.lock);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ice_dpll_rclk_state_on_pin_set - set a state on rclk pin
|
* ice_dpll_rclk_state_on_pin_set - set a state on rclk pin
|
||||||
* @pin: pointer to a pin
|
* @pin: pointer to a pin
|
||||||
|
@ -1222,6 +1435,8 @@ static const struct dpll_pin_ops ice_dpll_input_ops = {
|
||||||
.phase_adjust_get = ice_dpll_pin_phase_adjust_get,
|
.phase_adjust_get = ice_dpll_pin_phase_adjust_get,
|
||||||
.phase_adjust_set = ice_dpll_input_phase_adjust_set,
|
.phase_adjust_set = ice_dpll_input_phase_adjust_set,
|
||||||
.phase_offset_get = ice_dpll_phase_offset_get,
|
.phase_offset_get = ice_dpll_phase_offset_get,
|
||||||
|
.esync_set = ice_dpll_input_esync_set,
|
||||||
|
.esync_get = ice_dpll_input_esync_get,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct dpll_pin_ops ice_dpll_output_ops = {
|
static const struct dpll_pin_ops ice_dpll_output_ops = {
|
||||||
|
@ -1232,6 +1447,8 @@ static const struct dpll_pin_ops ice_dpll_output_ops = {
|
||||||
.direction_get = ice_dpll_output_direction,
|
.direction_get = ice_dpll_output_direction,
|
||||||
.phase_adjust_get = ice_dpll_pin_phase_adjust_get,
|
.phase_adjust_get = ice_dpll_pin_phase_adjust_get,
|
||||||
.phase_adjust_set = ice_dpll_output_phase_adjust_set,
|
.phase_adjust_set = ice_dpll_output_phase_adjust_set,
|
||||||
|
.esync_set = ice_dpll_output_esync_set,
|
||||||
|
.esync_get = ice_dpll_output_esync_get,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct dpll_device_ops ice_dpll_ops = {
|
static const struct dpll_device_ops ice_dpll_ops = {
|
||||||
|
|
|
@ -31,6 +31,7 @@ struct ice_dpll_pin {
|
||||||
struct dpll_pin_properties prop;
|
struct dpll_pin_properties prop;
|
||||||
u32 freq;
|
u32 freq;
|
||||||
s32 phase_adjust;
|
s32 phase_adjust;
|
||||||
|
u8 status;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** ice_dpll - store info required for DPLL control
|
/** ice_dpll - store info required for DPLL control
|
||||||
|
|
Loading…
Reference in a new issue