Skip to content

Commit 90e1c90

Browse files
kubalewskidavem330
authored andcommitted
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>
1 parent d7fbc0b commit 90e1c90

File tree

2 files changed

+226
-4
lines changed

2 files changed

+226
-4
lines changed

drivers/net/ethernet/intel/ice/ice_dpll.c

Lines changed: 218 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -878,6 +878,199 @@ ice_dpll_output_direction(const struct dpll_pin *pin, void *pin_priv,
878878
return 0;
879879
}
880880

881+
/**
882+
* ice_dpll_pin_phase_adjust_get - callback for get pin phase adjust value
883+
* @pin: pointer to a pin
884+
* @pin_priv: private data pointer passed on pin registration
885+
* @dpll: registered dpll pointer
886+
* @dpll_priv: private data pointer passed on dpll registration
887+
* @phase_adjust: on success holds pin phase_adjust value
888+
* @extack: error reporting
889+
*
890+
* Dpll subsystem callback. Handler for getting phase adjust value of a pin.
891+
*
892+
* Context: Acquires pf->dplls.lock
893+
* Return:
894+
* * 0 - success
895+
* * negative - error
896+
*/
897+
static int
898+
ice_dpll_pin_phase_adjust_get(const struct dpll_pin *pin, void *pin_priv,
899+
const struct dpll_device *dpll, void *dpll_priv,
900+
s32 *phase_adjust,
901+
struct netlink_ext_ack *extack)
902+
{
903+
struct ice_dpll_pin *p = pin_priv;
904+
struct ice_pf *pf = p->pf;
905+
906+
mutex_lock(&pf->dplls.lock);
907+
*phase_adjust = p->phase_adjust;
908+
mutex_unlock(&pf->dplls.lock);
909+
910+
return 0;
911+
}
912+
913+
/**
914+
* ice_dpll_pin_phase_adjust_set - helper for setting a pin phase adjust value
915+
* @pin: pointer to a pin
916+
* @pin_priv: private data pointer passed on pin registration
917+
* @dpll: registered dpll pointer
918+
* @dpll_priv: private data pointer passed on dpll registration
919+
* @phase_adjust: phase_adjust to be set
920+
* @extack: error reporting
921+
* @type: type of a pin
922+
*
923+
* Helper for dpll subsystem callback. Handler for setting phase adjust value
924+
* of a pin.
925+
*
926+
* Context: Acquires pf->dplls.lock
927+
* Return:
928+
* * 0 - success
929+
* * negative - error
930+
*/
931+
static int
932+
ice_dpll_pin_phase_adjust_set(const struct dpll_pin *pin, void *pin_priv,
933+
const struct dpll_device *dpll, void *dpll_priv,
934+
s32 phase_adjust,
935+
struct netlink_ext_ack *extack,
936+
enum ice_dpll_pin_type type)
937+
{
938+
struct ice_dpll_pin *p = pin_priv;
939+
struct ice_dpll *d = dpll_priv;
940+
struct ice_pf *pf = d->pf;
941+
u8 flag, flags_en = 0;
942+
int ret;
943+
944+
mutex_lock(&pf->dplls.lock);
945+
switch (type) {
946+
case ICE_DPLL_PIN_TYPE_INPUT:
947+
flag = ICE_AQC_SET_CGU_IN_CFG_FLG1_UPDATE_DELAY;
948+
if (p->flags[0] & ICE_AQC_GET_CGU_IN_CFG_FLG2_ESYNC_EN)
949+
flags_en |= ICE_AQC_SET_CGU_IN_CFG_FLG2_ESYNC_EN;
950+
if (p->flags[0] & ICE_AQC_GET_CGU_IN_CFG_FLG2_INPUT_EN)
951+
flags_en |= ICE_AQC_SET_CGU_IN_CFG_FLG2_INPUT_EN;
952+
ret = ice_aq_set_input_pin_cfg(&pf->hw, p->idx, flag, flags_en,
953+
0, phase_adjust);
954+
break;
955+
case ICE_DPLL_PIN_TYPE_OUTPUT:
956+
flag = ICE_AQC_SET_CGU_OUT_CFG_UPDATE_PHASE;
957+
if (p->flags[0] & ICE_AQC_GET_CGU_OUT_CFG_OUT_EN)
958+
flag |= ICE_AQC_SET_CGU_OUT_CFG_OUT_EN;
959+
if (p->flags[0] & ICE_AQC_GET_CGU_OUT_CFG_ESYNC_EN)
960+
flag |= ICE_AQC_SET_CGU_OUT_CFG_ESYNC_EN;
961+
ret = ice_aq_set_output_pin_cfg(&pf->hw, p->idx, flag, 0, 0,
962+
phase_adjust);
963+
break;
964+
default:
965+
ret = -EINVAL;
966+
}
967+
if (!ret)
968+
p->phase_adjust = phase_adjust;
969+
mutex_unlock(&pf->dplls.lock);
970+
if (ret)
971+
NL_SET_ERR_MSG_FMT(extack,
972+
"err:%d %s failed to set pin phase_adjust:%d for pin:%u on dpll:%u\n",
973+
ret,
974+
ice_aq_str(pf->hw.adminq.sq_last_status),
975+
phase_adjust, p->idx, d->dpll_idx);
976+
977+
return ret;
978+
}
979+
980+
/**
981+
* ice_dpll_input_phase_adjust_set - callback for set input pin phase adjust
982+
* @pin: pointer to a pin
983+
* @pin_priv: private data pointer passed on pin registration
984+
* @dpll: registered dpll pointer
985+
* @dpll_priv: private data pointer passed on dpll registration
986+
* @phase_adjust: phase_adjust to be set
987+
* @extack: error reporting
988+
*
989+
* Dpll subsystem callback. Wraps a handler for setting phase adjust on input
990+
* pin.
991+
*
992+
* Context: Calls a function which acquires pf->dplls.lock
993+
* Return:
994+
* * 0 - success
995+
* * negative - error
996+
*/
997+
static int
998+
ice_dpll_input_phase_adjust_set(const struct dpll_pin *pin, void *pin_priv,
999+
const struct dpll_device *dpll, void *dpll_priv,
1000+
s32 phase_adjust,
1001+
struct netlink_ext_ack *extack)
1002+
{
1003+
return ice_dpll_pin_phase_adjust_set(pin, pin_priv, dpll, dpll_priv,
1004+
phase_adjust, extack,
1005+
ICE_DPLL_PIN_TYPE_INPUT);
1006+
}
1007+
1008+
/**
1009+
* ice_dpll_output_phase_adjust_set - callback for set output pin phase adjust
1010+
* @pin: pointer to a pin
1011+
* @pin_priv: private data pointer passed on pin registration
1012+
* @dpll: registered dpll pointer
1013+
* @dpll_priv: private data pointer passed on dpll registration
1014+
* @phase_adjust: phase_adjust to be set
1015+
* @extack: error reporting
1016+
*
1017+
* Dpll subsystem callback. Wraps a handler for setting phase adjust on output
1018+
* pin.
1019+
*
1020+
* Context: Calls a function which acquires pf->dplls.lock
1021+
* Return:
1022+
* * 0 - success
1023+
* * negative - error
1024+
*/
1025+
static int
1026+
ice_dpll_output_phase_adjust_set(const struct dpll_pin *pin, void *pin_priv,
1027+
const struct dpll_device *dpll, void *dpll_priv,
1028+
s32 phase_adjust,
1029+
struct netlink_ext_ack *extack)
1030+
{
1031+
return ice_dpll_pin_phase_adjust_set(pin, pin_priv, dpll, dpll_priv,
1032+
phase_adjust, extack,
1033+
ICE_DPLL_PIN_TYPE_OUTPUT);
1034+
}
1035+
1036+
#define ICE_DPLL_PHASE_OFFSET_DIVIDER 100
1037+
#define ICE_DPLL_PHASE_OFFSET_FACTOR \
1038+
(DPLL_PHASE_OFFSET_DIVIDER / ICE_DPLL_PHASE_OFFSET_DIVIDER)
1039+
/**
1040+
* ice_dpll_phase_offset_get - callback for get dpll phase shift value
1041+
* @pin: pointer to a pin
1042+
* @pin_priv: private data pointer passed on pin registration
1043+
* @dpll: registered dpll pointer
1044+
* @dpll_priv: private data pointer passed on dpll registration
1045+
* @phase_offset: on success holds pin phase_offset value
1046+
* @extack: error reporting
1047+
*
1048+
* Dpll subsystem callback. Handler for getting phase shift value between
1049+
* dpll's input and output.
1050+
*
1051+
* Context: Acquires pf->dplls.lock
1052+
* Return:
1053+
* * 0 - success
1054+
* * negative - error
1055+
*/
1056+
static int
1057+
ice_dpll_phase_offset_get(const struct dpll_pin *pin, void *pin_priv,
1058+
const struct dpll_device *dpll, void *dpll_priv,
1059+
s64 *phase_offset, struct netlink_ext_ack *extack)
1060+
{
1061+
struct ice_dpll *d = dpll_priv;
1062+
struct ice_pf *pf = d->pf;
1063+
1064+
mutex_lock(&pf->dplls.lock);
1065+
if (d->active_input == pin)
1066+
*phase_offset = d->phase_offset * ICE_DPLL_PHASE_OFFSET_FACTOR;
1067+
else
1068+
*phase_offset = 0;
1069+
mutex_unlock(&pf->dplls.lock);
1070+
1071+
return 0;
1072+
}
1073+
8811074
/**
8821075
* ice_dpll_rclk_state_on_pin_set - set a state on rclk pin
8831076
* @pin: pointer to a pin
@@ -993,6 +1186,9 @@ static const struct dpll_pin_ops ice_dpll_input_ops = {
9931186
.prio_get = ice_dpll_input_prio_get,
9941187
.prio_set = ice_dpll_input_prio_set,
9951188
.direction_get = ice_dpll_input_direction,
1189+
.phase_adjust_get = ice_dpll_pin_phase_adjust_get,
1190+
.phase_adjust_set = ice_dpll_input_phase_adjust_set,
1191+
.phase_offset_get = ice_dpll_phase_offset_get,
9961192
};
9971193

9981194
static const struct dpll_pin_ops ice_dpll_output_ops = {
@@ -1001,6 +1197,8 @@ static const struct dpll_pin_ops ice_dpll_output_ops = {
10011197
.state_on_dpll_get = ice_dpll_output_state_get,
10021198
.state_on_dpll_set = ice_dpll_output_state_set,
10031199
.direction_get = ice_dpll_output_direction,
1200+
.phase_adjust_get = ice_dpll_pin_phase_adjust_get,
1201+
.phase_adjust_set = ice_dpll_output_phase_adjust_set,
10041202
};
10051203

10061204
static const struct dpll_device_ops ice_dpll_ops = {
@@ -1031,6 +1229,8 @@ static u64 ice_generate_clock_id(struct ice_pf *pf)
10311229
*/
10321230
static void ice_dpll_notify_changes(struct ice_dpll *d)
10331231
{
1232+
bool pin_notified = false;
1233+
10341234
if (d->prev_dpll_state != d->dpll_state) {
10351235
d->prev_dpll_state = d->dpll_state;
10361236
dpll_device_change_ntf(d->dpll);
@@ -1039,7 +1239,14 @@ static void ice_dpll_notify_changes(struct ice_dpll *d)
10391239
if (d->prev_input)
10401240
dpll_pin_change_ntf(d->prev_input);
10411241
d->prev_input = d->active_input;
1042-
if (d->active_input)
1242+
if (d->active_input) {
1243+
dpll_pin_change_ntf(d->active_input);
1244+
pin_notified = true;
1245+
}
1246+
}
1247+
if (d->prev_phase_offset != d->phase_offset) {
1248+
d->prev_phase_offset = d->phase_offset;
1249+
if (!pin_notified && d->active_input)
10431250
dpll_pin_change_ntf(d->active_input);
10441251
}
10451252
}
@@ -1065,7 +1272,7 @@ ice_dpll_update_state(struct ice_pf *pf, struct ice_dpll *d, bool init)
10651272

10661273
ret = ice_get_cgu_state(&pf->hw, d->dpll_idx, d->prev_dpll_state,
10671274
&d->input_idx, &d->ref_state, &d->eec_mode,
1068-
&d->phase_shift, &d->dpll_state);
1275+
&d->phase_offset, &d->dpll_state);
10691276

10701277
dev_dbg(ice_pf_to_dev(pf),
10711278
"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,
16561863
return ret;
16571864
pins[i].prop.capabilities |=
16581865
DPLL_PIN_CAPABILITIES_PRIORITY_CAN_CHANGE;
1866+
pins[i].prop.phase_range.min =
1867+
pf->dplls.input_phase_adj_max;
1868+
pins[i].prop.phase_range.max =
1869+
-pf->dplls.input_phase_adj_max;
1870+
} else {
1871+
pins[i].prop.phase_range.min =
1872+
pf->dplls.output_phase_adj_max;
1873+
pins[i].prop.phase_range.max =
1874+
-pf->dplls.output_phase_adj_max;
16591875
}
16601876
pins[i].prop.capabilities |=
16611877
DPLL_PIN_CAPABILITIES_STATE_CAN_CHANGE;

drivers/net/ethernet/intel/ice/ice_dpll.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
* @state: state of a pin
2020
* @prop: pin properties
2121
* @freq: current frequency of a pin
22+
* @phase_adjust: current phase adjust value
2223
*/
2324
struct ice_dpll_pin {
2425
struct dpll_pin *pin;
@@ -30,6 +31,7 @@ struct ice_dpll_pin {
3031
u8 state[ICE_DPLL_RCLK_NUM_MAX];
3132
struct dpll_pin_properties prop;
3233
u32 freq;
34+
s32 phase_adjust;
3335
};
3436

3537
/** ice_dpll - store info required for DPLL control
@@ -40,7 +42,8 @@ struct ice_dpll_pin {
4042
* @prev_input_idx: previously selected input index
4143
* @ref_state: state of dpll reference signals
4244
* @eec_mode: eec_mode dpll is configured for
43-
* @phase_shift: phase shift delay of a dpll
45+
* @phase_offset: phase offset of active pin vs dpll signal
46+
* @prev_phase_offset: previous phase offset of active pin vs dpll signal
4447
* @input_prio: priorities of each input
4548
* @dpll_state: current dpll sync state
4649
* @prev_dpll_state: last dpll sync state
@@ -55,7 +58,8 @@ struct ice_dpll {
5558
u8 prev_input_idx;
5659
u8 ref_state;
5760
u8 eec_mode;
58-
s64 phase_shift;
61+
s64 phase_offset;
62+
s64 prev_phase_offset;
5963
u8 *input_prio;
6064
enum dpll_lock_status dpll_state;
6165
enum dpll_lock_status prev_dpll_state;
@@ -78,6 +82,8 @@ struct ice_dpll {
7882
* @cgu_state_acq_err_num: number of errors returned during periodic work
7983
* @base_rclk_idx: idx of first pin used for clock revocery pins
8084
* @clock_id: clock_id of dplls
85+
* @input_phase_adj_max: max phase adjust value for an input pins
86+
* @output_phase_adj_max: max phase adjust value for an output pins
8187
*/
8288
struct ice_dplls {
8389
struct kthread_worker *kworker;

0 commit comments

Comments
 (0)