@@ -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
9981194static 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
10061204static const struct dpll_device_ops ice_dpll_ops = {
@@ -1031,6 +1229,8 @@ static u64 ice_generate_clock_id(struct ice_pf *pf)
10311229 */
10321230static 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 ;
0 commit comments