@@ -878,6 +878,196 @@ 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+ *
922+ * Helper for dpll subsystem callback. Handler for setting phase adjust value
923+ * of a pin.
924+ *
925+ * Context: Acquires pf->dplls.lock
926+ * Return:
927+ * * 0 - success
928+ * * negative - error
929+ */
930+ static int
931+ ice_dpll_pin_phase_adjust_set (const struct dpll_pin * pin , void * pin_priv ,
932+ const struct dpll_device * dpll , void * dpll_priv ,
933+ s32 phase_adjust ,
934+ struct netlink_ext_ack * extack ,
935+ enum ice_dpll_pin_type type )
936+ {
937+ struct ice_dpll_pin * p = pin_priv ;
938+ struct ice_dpll * d = dpll_priv ;
939+ struct ice_pf * pf = d -> pf ;
940+ u8 flag , flags_en = 0 ;
941+ int ret ;
942+
943+ mutex_lock (& pf -> dplls .lock );
944+ switch (type ) {
945+ case ICE_DPLL_PIN_TYPE_INPUT :
946+ flag = ICE_AQC_SET_CGU_IN_CFG_FLG1_UPDATE_DELAY ;
947+ if (p -> flags [0 ] & ICE_AQC_GET_CGU_IN_CFG_FLG2_ESYNC_EN )
948+ flags_en |= ICE_AQC_SET_CGU_IN_CFG_FLG2_ESYNC_EN ;
949+ if (p -> flags [0 ] & ICE_AQC_GET_CGU_IN_CFG_FLG2_INPUT_EN )
950+ flags_en |= ICE_AQC_SET_CGU_IN_CFG_FLG2_INPUT_EN ;
951+ ret = ice_aq_set_input_pin_cfg (& pf -> hw , p -> idx , flag , flags_en ,
952+ 0 , phase_adjust );
953+ break ;
954+ case ICE_DPLL_PIN_TYPE_OUTPUT :
955+ flag = ICE_AQC_SET_CGU_OUT_CFG_UPDATE_PHASE ;
956+ if (p -> flags [0 ] & ICE_AQC_GET_CGU_OUT_CFG_OUT_EN )
957+ flag |= ICE_AQC_SET_CGU_OUT_CFG_OUT_EN ;
958+ if (p -> flags [0 ] & ICE_AQC_GET_CGU_OUT_CFG_ESYNC_EN )
959+ flag |= ICE_AQC_SET_CGU_OUT_CFG_ESYNC_EN ;
960+ ret = ice_aq_set_output_pin_cfg (& pf -> hw , p -> idx , flag , 0 , 0 ,
961+ phase_adjust );
962+ break ;
963+ default :
964+ ret = - EINVAL ;
965+ }
966+ if (!ret )
967+ p -> phase_adjust = phase_adjust ;
968+ mutex_unlock (& pf -> dplls .lock );
969+ if (ret )
970+ NL_SET_ERR_MSG_FMT (extack ,
971+ "err:%d %s failed to set pin phase_adjust:%d for pin:%u on dpll:%u\n" ,
972+ ret ,
973+ ice_aq_str (pf -> hw .adminq .sq_last_status ),
974+ phase_adjust , p -> idx , d -> dpll_idx );
975+
976+ return ret ;
977+ }
978+
979+ /**
980+ * ice_dpll_input_phase_adjust_set - callback for set input pin phase adjust
981+ * @pin: pointer to a pin
982+ * @pin_priv: private data pointer passed on pin registration
983+ * @dpll: registered dpll pointer
984+ * @dpll_priv: private data pointer passed on dpll registration
985+ * @phase_adjust: phase_adjust to be set
986+ * @extack: error reporting
987+ *
988+ * Dpll subsystem callback. Wraps a handler for setting phase adjust on input
989+ * pin.
990+ *
991+ * Return:
992+ * * 0 - success
993+ * * negative - error
994+ */
995+ static int
996+ ice_dpll_input_phase_adjust_set (const struct dpll_pin * pin , void * pin_priv ,
997+ const struct dpll_device * dpll , void * dpll_priv ,
998+ s32 phase_adjust ,
999+ struct netlink_ext_ack * extack )
1000+ {
1001+ return ice_dpll_pin_phase_adjust_set (pin , pin_priv , dpll , dpll_priv ,
1002+ phase_adjust , extack ,
1003+ ICE_DPLL_PIN_TYPE_INPUT );
1004+ }
1005+
1006+ /**
1007+ * ice_dpll_output_phase_adjust_set - callback for set output pin phase adjust
1008+ * @pin: pointer to a pin
1009+ * @pin_priv: private data pointer passed on pin registration
1010+ * @dpll: registered dpll pointer
1011+ * @dpll_priv: private data pointer passed on dpll registration
1012+ * @phase_adjust: phase_adjust to be set
1013+ * @extack: error reporting
1014+ *
1015+ * Dpll subsystem callback. Wraps a handler for setting phase adjust on output
1016+ * pin.
1017+ *
1018+ * Return:
1019+ * * 0 - success
1020+ * * negative - error
1021+ */
1022+ static int
1023+ ice_dpll_output_phase_adjust_set (const struct dpll_pin * pin , void * pin_priv ,
1024+ const struct dpll_device * dpll , void * dpll_priv ,
1025+ s32 phase_adjust ,
1026+ struct netlink_ext_ack * extack )
1027+ {
1028+ return ice_dpll_pin_phase_adjust_set (pin , pin_priv , dpll , dpll_priv ,
1029+ phase_adjust , extack ,
1030+ ICE_DPLL_PIN_TYPE_OUTPUT );
1031+ }
1032+
1033+ #define ICE_DPLL_PHASE_OFFSET_DIVIDER 100
1034+ #define ICE_DPLL_PHASE_OFFSET_FACTOR \
1035+ (DPLL_PHASE_OFFSET_DIVIDER / ICE_DPLL_PHASE_OFFSET_DIVIDER)
1036+ /**
1037+ * ice_dpll_phase_offset_get - callback for get dpll phase shift value
1038+ * @pin: pointer to a pin
1039+ * @pin_priv: private data pointer passed on pin registration
1040+ * @dpll: registered dpll pointer
1041+ * @dpll_priv: private data pointer passed on dpll registration
1042+ * @phase_adjust: on success holds pin phase_adjust value
1043+ * @extack: error reporting
1044+ *
1045+ * Dpll subsystem callback. Handler for getting phase shift value between
1046+ * dpll's input and output.
1047+ *
1048+ * Context: Acquires pf->dplls.lock
1049+ * Return:
1050+ * * 0 - success
1051+ * * negative - error
1052+ */
1053+ static int
1054+ ice_dpll_phase_offset_get (const struct dpll_pin * pin , void * pin_priv ,
1055+ const struct dpll_device * dpll , void * dpll_priv ,
1056+ s64 * phase_offset , struct netlink_ext_ack * extack )
1057+ {
1058+ struct ice_dpll * d = dpll_priv ;
1059+ struct ice_pf * pf = d -> pf ;
1060+
1061+ mutex_lock (& pf -> dplls .lock );
1062+ if (d -> active_input == pin )
1063+ * phase_offset = d -> phase_offset * ICE_DPLL_PHASE_OFFSET_FACTOR ;
1064+ else
1065+ * phase_offset = 0 ;
1066+ mutex_unlock (& pf -> dplls .lock );
1067+
1068+ return 0 ;
1069+ }
1070+
8811071/**
8821072 * ice_dpll_rclk_state_on_pin_set - set a state on rclk pin
8831073 * @pin: pointer to a pin
@@ -993,6 +1183,9 @@ static const struct dpll_pin_ops ice_dpll_input_ops = {
9931183 .prio_get = ice_dpll_input_prio_get ,
9941184 .prio_set = ice_dpll_input_prio_set ,
9951185 .direction_get = ice_dpll_input_direction ,
1186+ .phase_adjust_get = ice_dpll_pin_phase_adjust_get ,
1187+ .phase_adjust_set = ice_dpll_input_phase_adjust_set ,
1188+ .phase_offset_get = ice_dpll_phase_offset_get ,
9961189};
9971190
9981191static const struct dpll_pin_ops ice_dpll_output_ops = {
@@ -1001,6 +1194,8 @@ static const struct dpll_pin_ops ice_dpll_output_ops = {
10011194 .state_on_dpll_get = ice_dpll_output_state_get ,
10021195 .state_on_dpll_set = ice_dpll_output_state_set ,
10031196 .direction_get = ice_dpll_output_direction ,
1197+ .phase_adjust_get = ice_dpll_pin_phase_adjust_get ,
1198+ .phase_adjust_set = ice_dpll_output_phase_adjust_set ,
10041199};
10051200
10061201static const struct dpll_device_ops ice_dpll_ops = {
@@ -1031,6 +1226,8 @@ static u64 ice_generate_clock_id(struct ice_pf *pf)
10311226 */
10321227static void ice_dpll_notify_changes (struct ice_dpll * d )
10331228{
1229+ bool pin_notified = false;
1230+
10341231 if (d -> prev_dpll_state != d -> dpll_state ) {
10351232 d -> prev_dpll_state = d -> dpll_state ;
10361233 dpll_device_change_ntf (d -> dpll );
@@ -1039,7 +1236,14 @@ static void ice_dpll_notify_changes(struct ice_dpll *d)
10391236 if (d -> prev_input )
10401237 dpll_pin_change_ntf (d -> prev_input );
10411238 d -> prev_input = d -> active_input ;
1042- if (d -> active_input )
1239+ if (d -> active_input ) {
1240+ dpll_pin_change_ntf (d -> active_input );
1241+ pin_notified = true;
1242+ }
1243+ }
1244+ if (d -> prev_phase_offset != d -> phase_offset ) {
1245+ d -> prev_phase_offset = d -> phase_offset ;
1246+ if (!pin_notified && d -> active_input )
10431247 dpll_pin_change_ntf (d -> active_input );
10441248 }
10451249}
@@ -1065,7 +1269,7 @@ ice_dpll_update_state(struct ice_pf *pf, struct ice_dpll *d, bool init)
10651269
10661270 ret = ice_get_cgu_state (& pf -> hw , d -> dpll_idx , d -> prev_dpll_state ,
10671271 & d -> input_idx , & d -> ref_state , & d -> eec_mode ,
1068- & d -> phase_shift , & d -> dpll_state );
1272+ & d -> phase_offset , & d -> dpll_state );
10691273
10701274 dev_dbg (ice_pf_to_dev (pf ),
10711275 "update dpll=%d, prev_src_idx:%u, src_idx:%u, state:%d, prev:%d mode:%d\n" ,
@@ -1656,6 +1860,15 @@ ice_dpll_init_info_direct_pins(struct ice_pf *pf,
16561860 return ret ;
16571861 pins [i ].prop .capabilities |=
16581862 DPLL_PIN_CAPABILITIES_PRIORITY_CAN_CHANGE ;
1863+ pins [i ].prop .phase_range .min =
1864+ pf -> dplls .input_phase_adj_max ;
1865+ pins [i ].prop .phase_range .max =
1866+ - pf -> dplls .input_phase_adj_max ;
1867+ } else {
1868+ pins [i ].prop .phase_range .min =
1869+ pf -> dplls .output_phase_adj_max ,
1870+ pins [i ].prop .phase_range .max =
1871+ - pf -> dplls .output_phase_adj_max ;
16591872 }
16601873 pins [i ].prop .capabilities |=
16611874 DPLL_PIN_CAPABILITIES_STATE_CAN_CHANGE ;
0 commit comments