xref: /linux/drivers/net/ethernet/intel/ice/ice_dpll.c (revision bf4afc53b77aeaa48b5409da5c8da6bb4eff7f43)
1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright (C) 2022, Intel Corporation. */
3 
4 #include "ice.h"
5 #include "ice_lib.h"
6 #include "ice_trace.h"
7 #include <linux/dpll.h>
8 #include <linux/property.h>
9 
10 #define ICE_CGU_STATE_ACQ_ERR_THRESHOLD		50
11 #define ICE_DPLL_PIN_IDX_INVALID		0xff
12 #define ICE_DPLL_RCLK_NUM_PER_PF		1
13 #define ICE_DPLL_PIN_ESYNC_PULSE_HIGH_PERCENT	25
14 #define ICE_DPLL_PIN_GEN_RCLK_FREQ		1953125
15 #define ICE_DPLL_PIN_PRIO_OUTPUT		0xff
16 #define ICE_DPLL_INPUT_REF_NUM			10
17 #define ICE_DPLL_PHASE_OFFSET_PERIOD		2
18 #define ICE_DPLL_SW_PIN_INPUT_BASE_SFP		4
19 #define ICE_DPLL_SW_PIN_INPUT_BASE_QSFP		6
20 #define ICE_DPLL_SW_PIN_OUTPUT_BASE		0
21 
22 #define ICE_DPLL_PIN_SW_INPUT_ABS(in_idx) \
23 	(ICE_DPLL_SW_PIN_INPUT_BASE_SFP + (in_idx))
24 
25 #define ICE_DPLL_PIN_SW_1_INPUT_ABS_IDX \
26 	(ICE_DPLL_PIN_SW_INPUT_ABS(ICE_DPLL_PIN_SW_1_IDX))
27 
28 #define ICE_DPLL_PIN_SW_2_INPUT_ABS_IDX \
29 	(ICE_DPLL_PIN_SW_INPUT_ABS(ICE_DPLL_PIN_SW_2_IDX))
30 
31 #define ICE_DPLL_PIN_SW_OUTPUT_ABS(out_idx) \
32 	(ICE_DPLL_SW_PIN_OUTPUT_BASE + (out_idx))
33 
34 #define ICE_DPLL_PIN_SW_1_OUTPUT_ABS_IDX \
35 	(ICE_DPLL_PIN_SW_OUTPUT_ABS(ICE_DPLL_PIN_SW_1_IDX))
36 
37 #define ICE_DPLL_PIN_SW_2_OUTPUT_ABS_IDX \
38 	(ICE_DPLL_PIN_SW_OUTPUT_ABS(ICE_DPLL_PIN_SW_2_IDX))
39 
40 #define ICE_SR_PFA_DPLL_DEFAULTS		0x152
41 #define ICE_DPLL_PFA_REF_SYNC_TYPE		0x2420
42 #define ICE_DPLL_PFA_REF_SYNC_TYPE2		0x2424
43 #define ICE_DPLL_PFA_END			0xFFFF
44 #define ICE_DPLL_PFA_HEADER_LEN			4
45 #define ICE_DPLL_PFA_ENTRY_LEN			3
46 #define ICE_DPLL_PFA_MAILBOX_REF_SYNC_PIN_S	4
47 #define ICE_DPLL_PFA_MASK_OFFSET		1
48 #define ICE_DPLL_PFA_VALUE_OFFSET		2
49 
50 #define ICE_DPLL_E810C_SFP_NC_PINS		2
51 #define ICE_DPLL_E810C_SFP_NC_START		4
52 
53 /**
54  * enum ice_dpll_pin_type - enumerate ice pin types:
55  * @ICE_DPLL_PIN_INVALID: invalid pin type
56  * @ICE_DPLL_PIN_TYPE_INPUT: input pin
57  * @ICE_DPLL_PIN_TYPE_OUTPUT: output pin
58  * @ICE_DPLL_PIN_TYPE_RCLK_INPUT: recovery clock input pin
59  * @ICE_DPLL_PIN_TYPE_SOFTWARE: software controlled SMA/U.FL pins
60  */
61 enum ice_dpll_pin_type {
62 	ICE_DPLL_PIN_INVALID,
63 	ICE_DPLL_PIN_TYPE_INPUT,
64 	ICE_DPLL_PIN_TYPE_OUTPUT,
65 	ICE_DPLL_PIN_TYPE_RCLK_INPUT,
66 	ICE_DPLL_PIN_TYPE_SOFTWARE,
67 };
68 
69 static const char * const pin_type_name[] = {
70 	[ICE_DPLL_PIN_TYPE_INPUT] = "input",
71 	[ICE_DPLL_PIN_TYPE_OUTPUT] = "output",
72 	[ICE_DPLL_PIN_TYPE_RCLK_INPUT] = "rclk-input",
73 	[ICE_DPLL_PIN_TYPE_SOFTWARE] = "software",
74 };
75 
76 static const char * const ice_dpll_sw_pin_sma[] = { "SMA1", "SMA2" };
77 static const char * const ice_dpll_sw_pin_ufl[] = { "U.FL1", "U.FL2" };
78 
79 static const struct dpll_pin_frequency ice_esync_range[] = {
80 	DPLL_PIN_FREQUENCY_RANGE(0, DPLL_PIN_FREQUENCY_1_HZ),
81 };
82 
83 /**
84  * ice_dpll_is_sw_pin - check if given pin shall be controlled by SW
85  * @pf: private board structure
86  * @index: index of a pin as understood by FW
87  * @input: true for input, false for output
88  *
89  * Check if the pin shall be controlled by SW - instead of providing raw access
90  * for pin control. For E810 NIC with dpll there is additional MUX-related logic
91  * between SMA/U.FL pins/connectors and dpll device, best to give user access
92  * with series of wrapper functions as from user perspective they convey single
93  * functionality rather then separated pins.
94  *
95  * Return:
96  * * true - pin controlled by SW
97  * * false - pin not controlled by SW
98  */
ice_dpll_is_sw_pin(struct ice_pf * pf,u8 index,bool input)99 static bool ice_dpll_is_sw_pin(struct ice_pf *pf, u8 index, bool input)
100 {
101 	if (input && pf->hw.device_id == ICE_DEV_ID_E810C_QSFP)
102 		index -= ICE_DPLL_SW_PIN_INPUT_BASE_QSFP -
103 			 ICE_DPLL_SW_PIN_INPUT_BASE_SFP;
104 
105 	if ((input && (index == ICE_DPLL_PIN_SW_1_INPUT_ABS_IDX ||
106 		       index == ICE_DPLL_PIN_SW_2_INPUT_ABS_IDX)) ||
107 	    (!input && (index == ICE_DPLL_PIN_SW_1_OUTPUT_ABS_IDX ||
108 			index == ICE_DPLL_PIN_SW_2_OUTPUT_ABS_IDX)))
109 		return true;
110 	return false;
111 }
112 
113 /**
114  * ice_dpll_is_reset - check if reset is in progress
115  * @pf: private board structure
116  * @extack: error reporting
117  *
118  * If reset is in progress, fill extack with error.
119  *
120  * Return:
121  * * false - no reset in progress
122  * * true - reset in progress
123  */
ice_dpll_is_reset(struct ice_pf * pf,struct netlink_ext_ack * extack)124 static bool ice_dpll_is_reset(struct ice_pf *pf, struct netlink_ext_ack *extack)
125 {
126 	if (ice_is_reset_in_progress(pf->state)) {
127 		NL_SET_ERR_MSG(extack, "PF reset in progress");
128 		return true;
129 	}
130 	return false;
131 }
132 
133 /**
134  * ice_dpll_pin_freq_set - set pin's frequency
135  * @pf: private board structure
136  * @pin: pointer to a pin
137  * @pin_type: type of pin being configured
138  * @freq: frequency to be set
139  * @extack: error reporting
140  *
141  * Set requested frequency on a pin.
142  *
143  * Context: Called under pf->dplls.lock
144  * Return:
145  * * 0 - success
146  * * negative - error on AQ or wrong pin type given
147  */
148 static int
ice_dpll_pin_freq_set(struct ice_pf * pf,struct ice_dpll_pin * pin,enum ice_dpll_pin_type pin_type,const u32 freq,struct netlink_ext_ack * extack)149 ice_dpll_pin_freq_set(struct ice_pf *pf, struct ice_dpll_pin *pin,
150 		      enum ice_dpll_pin_type pin_type, const u32 freq,
151 		      struct netlink_ext_ack *extack)
152 {
153 	u8 flags;
154 	int ret;
155 
156 	switch (pin_type) {
157 	case ICE_DPLL_PIN_TYPE_INPUT:
158 		flags = ICE_AQC_SET_CGU_IN_CFG_FLG1_UPDATE_FREQ;
159 		ret = ice_aq_set_input_pin_cfg(&pf->hw, pin->idx, flags,
160 					       pin->flags[0], freq, 0);
161 		break;
162 	case ICE_DPLL_PIN_TYPE_OUTPUT:
163 		flags = ICE_AQC_SET_CGU_OUT_CFG_UPDATE_FREQ;
164 		ret = ice_aq_set_output_pin_cfg(&pf->hw, pin->idx, flags,
165 						0, freq, 0);
166 		break;
167 	default:
168 		return -EINVAL;
169 	}
170 	if (ret) {
171 		NL_SET_ERR_MSG_FMT(extack,
172 				   "err:%d %s failed to set pin freq:%u on pin:%u",
173 				   ret,
174 				   libie_aq_str(pf->hw.adminq.sq_last_status),
175 				   freq, pin->idx);
176 		return ret;
177 	}
178 	pin->freq = freq;
179 
180 	return 0;
181 }
182 
183 /**
184  * ice_dpll_frequency_set - wrapper for pin callback for set frequency
185  * @pin: pointer to a pin
186  * @pin_priv: private data pointer passed on pin registration
187  * @dpll: pointer to dpll
188  * @dpll_priv: private data pointer passed on dpll registration
189  * @frequency: frequency to be set
190  * @extack: error reporting
191  * @pin_type: type of pin being configured
192  *
193  * Wraps internal set frequency command on a pin.
194  *
195  * Context: Acquires pf->dplls.lock
196  * Return:
197  * * 0 - success
198  * * negative - error pin not found or couldn't set in hw
199  */
200 static int
ice_dpll_frequency_set(const struct dpll_pin * pin,void * pin_priv,const struct dpll_device * dpll,void * dpll_priv,const u32 frequency,struct netlink_ext_ack * extack,enum ice_dpll_pin_type pin_type)201 ice_dpll_frequency_set(const struct dpll_pin *pin, void *pin_priv,
202 		       const struct dpll_device *dpll, void *dpll_priv,
203 		       const u32 frequency,
204 		       struct netlink_ext_ack *extack,
205 		       enum ice_dpll_pin_type pin_type)
206 {
207 	struct ice_dpll_pin *p = pin_priv;
208 	struct ice_dpll *d = dpll_priv;
209 	struct ice_pf *pf = d->pf;
210 	int ret;
211 
212 	if (ice_dpll_is_reset(pf, extack))
213 		return -EBUSY;
214 
215 	mutex_lock(&pf->dplls.lock);
216 	ret = ice_dpll_pin_freq_set(pf, p, pin_type, frequency, extack);
217 	mutex_unlock(&pf->dplls.lock);
218 
219 	return ret;
220 }
221 
222 /**
223  * ice_dpll_input_frequency_set - input pin callback for set frequency
224  * @pin: pointer to a pin
225  * @pin_priv: private data pointer passed on pin registration
226  * @dpll: pointer to dpll
227  * @dpll_priv: private data pointer passed on dpll registration
228  * @frequency: frequency to be set
229  * @extack: error reporting
230  *
231  * Wraps internal set frequency command on a pin.
232  *
233  * Context: Calls a function which acquires pf->dplls.lock
234  * Return:
235  * * 0 - success
236  * * negative - error pin not found or couldn't set in hw
237  */
238 static int
ice_dpll_input_frequency_set(const struct dpll_pin * pin,void * pin_priv,const struct dpll_device * dpll,void * dpll_priv,u64 frequency,struct netlink_ext_ack * extack)239 ice_dpll_input_frequency_set(const struct dpll_pin *pin, void *pin_priv,
240 			     const struct dpll_device *dpll, void *dpll_priv,
241 			     u64 frequency, struct netlink_ext_ack *extack)
242 {
243 	return ice_dpll_frequency_set(pin, pin_priv, dpll, dpll_priv, frequency,
244 				      extack, ICE_DPLL_PIN_TYPE_INPUT);
245 }
246 
247 /**
248  * ice_dpll_output_frequency_set - output pin callback for set frequency
249  * @pin: pointer to a pin
250  * @pin_priv: private data pointer passed on pin registration
251  * @dpll: pointer to dpll
252  * @dpll_priv: private data pointer passed on dpll registration
253  * @frequency: frequency to be set
254  * @extack: error reporting
255  *
256  * Wraps internal set frequency command on a pin.
257  *
258  * Context: Calls a function which acquires pf->dplls.lock
259  * Return:
260  * * 0 - success
261  * * negative - error pin not found or couldn't set in hw
262  */
263 static int
ice_dpll_output_frequency_set(const struct dpll_pin * pin,void * pin_priv,const struct dpll_device * dpll,void * dpll_priv,u64 frequency,struct netlink_ext_ack * extack)264 ice_dpll_output_frequency_set(const struct dpll_pin *pin, void *pin_priv,
265 			      const struct dpll_device *dpll, void *dpll_priv,
266 			      u64 frequency, struct netlink_ext_ack *extack)
267 {
268 	return ice_dpll_frequency_set(pin, pin_priv, dpll, dpll_priv, frequency,
269 				      extack, ICE_DPLL_PIN_TYPE_OUTPUT);
270 }
271 
272 /**
273  * ice_dpll_frequency_get - wrapper for pin callback for get frequency
274  * @pin: pointer to a pin
275  * @pin_priv: private data pointer passed on pin registration
276  * @dpll: pointer to dpll
277  * @dpll_priv: private data pointer passed on dpll registration
278  * @frequency: on success holds pin's frequency
279  * @extack: error reporting
280  * @pin_type: type of pin being configured
281  *
282  * Wraps internal get frequency command of a pin.
283  *
284  * Context: Acquires pf->dplls.lock
285  * Return:
286  * * 0 - success
287  * * negative - error pin not found or couldn't get from hw
288  */
289 static int
ice_dpll_frequency_get(const struct dpll_pin * pin,void * pin_priv,const struct dpll_device * dpll,void * dpll_priv,u64 * frequency,struct netlink_ext_ack * extack,enum ice_dpll_pin_type pin_type)290 ice_dpll_frequency_get(const struct dpll_pin *pin, void *pin_priv,
291 		       const struct dpll_device *dpll, void *dpll_priv,
292 		       u64 *frequency, struct netlink_ext_ack *extack,
293 		       enum ice_dpll_pin_type pin_type)
294 {
295 	struct ice_dpll_pin *p = pin_priv;
296 	struct ice_dpll *d = dpll_priv;
297 	struct ice_pf *pf = d->pf;
298 
299 	mutex_lock(&pf->dplls.lock);
300 	*frequency = p->freq;
301 	mutex_unlock(&pf->dplls.lock);
302 
303 	return 0;
304 }
305 
306 /**
307  * ice_dpll_input_frequency_get - input pin callback for get frequency
308  * @pin: pointer to a pin
309  * @pin_priv: private data pointer passed on pin registration
310  * @dpll: pointer to dpll
311  * @dpll_priv: private data pointer passed on dpll registration
312  * @frequency: on success holds pin's frequency
313  * @extack: error reporting
314  *
315  * Wraps internal get frequency command of a input pin.
316  *
317  * Context: Calls a function which acquires pf->dplls.lock
318  * Return:
319  * * 0 - success
320  * * negative - error pin not found or couldn't get from hw
321  */
322 static int
ice_dpll_input_frequency_get(const struct dpll_pin * pin,void * pin_priv,const struct dpll_device * dpll,void * dpll_priv,u64 * frequency,struct netlink_ext_ack * extack)323 ice_dpll_input_frequency_get(const struct dpll_pin *pin, void *pin_priv,
324 			     const struct dpll_device *dpll, void *dpll_priv,
325 			     u64 *frequency, struct netlink_ext_ack *extack)
326 {
327 	return ice_dpll_frequency_get(pin, pin_priv, dpll, dpll_priv, frequency,
328 				      extack, ICE_DPLL_PIN_TYPE_INPUT);
329 }
330 
331 /**
332  * ice_dpll_output_frequency_get - output pin callback for get frequency
333  * @pin: pointer to a pin
334  * @pin_priv: private data pointer passed on pin registration
335  * @dpll: pointer to dpll
336  * @dpll_priv: private data pointer passed on dpll registration
337  * @frequency: on success holds pin's frequency
338  * @extack: error reporting
339  *
340  * Wraps internal get frequency command of a pin.
341  *
342  * Context: Calls a function which acquires pf->dplls.lock
343  * Return:
344  * * 0 - success
345  * * negative - error pin not found or couldn't get from hw
346  */
347 static int
ice_dpll_output_frequency_get(const struct dpll_pin * pin,void * pin_priv,const struct dpll_device * dpll,void * dpll_priv,u64 * frequency,struct netlink_ext_ack * extack)348 ice_dpll_output_frequency_get(const struct dpll_pin *pin, void *pin_priv,
349 			      const struct dpll_device *dpll, void *dpll_priv,
350 			      u64 *frequency, struct netlink_ext_ack *extack)
351 {
352 	return ice_dpll_frequency_get(pin, pin_priv, dpll, dpll_priv, frequency,
353 				      extack, ICE_DPLL_PIN_TYPE_OUTPUT);
354 }
355 
356 /**
357  * ice_dpll_sw_pin_frequency_set - callback to set frequency of SW pin
358  * @pin: pointer to a pin
359  * @pin_priv: private data pointer passed on pin registration
360  * @dpll: pointer to dpll
361  * @dpll_priv: private data pointer passed on dpll registration
362  * @frequency: on success holds pin's frequency
363  * @extack: error reporting
364  *
365  * Calls set frequency command for corresponding and active input/output pin.
366  *
367  * Context: Calls a function which acquires and releases pf->dplls.lock
368  * Return:
369  * * 0 - success
370  * * negative - error pin not active or couldn't get from hw
371  */
372 static int
ice_dpll_sw_pin_frequency_set(const struct dpll_pin * pin,void * pin_priv,const struct dpll_device * dpll,void * dpll_priv,u64 frequency,struct netlink_ext_ack * extack)373 ice_dpll_sw_pin_frequency_set(const struct dpll_pin *pin, void *pin_priv,
374 			      const struct dpll_device *dpll, void *dpll_priv,
375 			      u64 frequency, struct netlink_ext_ack *extack)
376 {
377 	struct ice_dpll_pin *sma = pin_priv;
378 	int ret;
379 
380 	if (!sma->active) {
381 		NL_SET_ERR_MSG(extack, "pin is not active");
382 		return -EINVAL;
383 	}
384 	if (sma->direction == DPLL_PIN_DIRECTION_INPUT)
385 		ret = ice_dpll_input_frequency_set(NULL, sma->input, dpll,
386 						   dpll_priv, frequency,
387 						   extack);
388 	else
389 		ret = ice_dpll_output_frequency_set(NULL, sma->output, dpll,
390 						    dpll_priv, frequency,
391 						    extack);
392 
393 	return ret;
394 }
395 
396 /**
397  * ice_dpll_sw_pin_frequency_get - callback for get frequency of SW pin
398  * @pin: pointer to a pin
399  * @pin_priv: private data pointer passed on pin registration
400  * @dpll: pointer to dpll
401  * @dpll_priv: private data pointer passed on dpll registration
402  * @frequency: on success holds pin's frequency
403  * @extack: error reporting
404  *
405  * Calls get frequency command for corresponding active input/output.
406  *
407  * Context: Calls a function which acquires and releases pf->dplls.lock
408  * Return:
409  * * 0 - success
410  * * negative - error pin not active or couldn't get from hw
411  */
412 static int
ice_dpll_sw_pin_frequency_get(const struct dpll_pin * pin,void * pin_priv,const struct dpll_device * dpll,void * dpll_priv,u64 * frequency,struct netlink_ext_ack * extack)413 ice_dpll_sw_pin_frequency_get(const struct dpll_pin *pin, void *pin_priv,
414 			      const struct dpll_device *dpll, void *dpll_priv,
415 			      u64 *frequency, struct netlink_ext_ack *extack)
416 {
417 	struct ice_dpll_pin *sma = pin_priv;
418 	int ret;
419 
420 	if (!sma->active) {
421 		*frequency = 0;
422 		return 0;
423 	}
424 	if (sma->direction == DPLL_PIN_DIRECTION_INPUT) {
425 		ret = ice_dpll_input_frequency_get(NULL, sma->input, dpll,
426 						   dpll_priv, frequency,
427 						   extack);
428 	} else {
429 		ret = ice_dpll_output_frequency_get(NULL, sma->output, dpll,
430 						    dpll_priv, frequency,
431 						    extack);
432 	}
433 
434 	return ret;
435 }
436 
437 /**
438  * ice_dpll_pin_enable - enable a pin on dplls
439  * @hw: board private hw structure
440  * @pin: pointer to a pin
441  * @dpll_idx: dpll index to connect to output pin
442  * @pin_type: type of pin being enabled
443  * @extack: error reporting
444  *
445  * Enable a pin on both dplls. Store current state in pin->flags.
446  *
447  * Context: Called under pf->dplls.lock
448  * Return:
449  * * 0 - OK
450  * * negative - error
451  */
452 static int
ice_dpll_pin_enable(struct ice_hw * hw,struct ice_dpll_pin * pin,u8 dpll_idx,enum ice_dpll_pin_type pin_type,struct netlink_ext_ack * extack)453 ice_dpll_pin_enable(struct ice_hw *hw, struct ice_dpll_pin *pin,
454 		    u8 dpll_idx, enum ice_dpll_pin_type pin_type,
455 		    struct netlink_ext_ack *extack)
456 {
457 	u8 flags = 0;
458 	int ret;
459 
460 	switch (pin_type) {
461 	case ICE_DPLL_PIN_TYPE_INPUT:
462 		if (pin->flags[0] & ICE_AQC_GET_CGU_IN_CFG_FLG2_ESYNC_EN)
463 			flags |= ICE_AQC_SET_CGU_IN_CFG_FLG2_ESYNC_EN;
464 		flags |= ICE_AQC_SET_CGU_IN_CFG_FLG2_INPUT_EN;
465 		ret = ice_aq_set_input_pin_cfg(hw, pin->idx, 0, flags, 0, 0);
466 		break;
467 	case ICE_DPLL_PIN_TYPE_OUTPUT:
468 		flags = ICE_AQC_SET_CGU_OUT_CFG_UPDATE_SRC_SEL;
469 		if (pin->flags[0] & ICE_AQC_GET_CGU_OUT_CFG_ESYNC_EN)
470 			flags |= ICE_AQC_SET_CGU_OUT_CFG_ESYNC_EN;
471 		flags |= ICE_AQC_SET_CGU_OUT_CFG_OUT_EN;
472 		ret = ice_aq_set_output_pin_cfg(hw, pin->idx, flags, dpll_idx,
473 						0, 0);
474 		break;
475 	default:
476 		return -EINVAL;
477 	}
478 	if (ret)
479 		NL_SET_ERR_MSG_FMT(extack,
480 				   "err:%d %s failed to enable %s pin:%u",
481 				   ret, libie_aq_str(hw->adminq.sq_last_status),
482 				   pin_type_name[pin_type], pin->idx);
483 
484 	return ret;
485 }
486 
487 /**
488  * ice_dpll_pin_disable - disable a pin on dplls
489  * @hw: board private hw structure
490  * @pin: pointer to a pin
491  * @pin_type: type of pin being disabled
492  * @extack: error reporting
493  *
494  * Disable a pin on both dplls. Store current state in pin->flags.
495  *
496  * Context: Called under pf->dplls.lock
497  * Return:
498  * * 0 - OK
499  * * negative - error
500  */
501 static int
ice_dpll_pin_disable(struct ice_hw * hw,struct ice_dpll_pin * pin,enum ice_dpll_pin_type pin_type,struct netlink_ext_ack * extack)502 ice_dpll_pin_disable(struct ice_hw *hw, struct ice_dpll_pin *pin,
503 		     enum ice_dpll_pin_type pin_type,
504 		     struct netlink_ext_ack *extack)
505 {
506 	u8 flags = 0;
507 	int ret;
508 
509 	switch (pin_type) {
510 	case ICE_DPLL_PIN_TYPE_INPUT:
511 		if (pin->flags[0] & ICE_AQC_GET_CGU_IN_CFG_FLG2_ESYNC_EN)
512 			flags |= ICE_AQC_SET_CGU_IN_CFG_FLG2_ESYNC_EN;
513 		ret = ice_aq_set_input_pin_cfg(hw, pin->idx, 0, flags, 0, 0);
514 		break;
515 	case ICE_DPLL_PIN_TYPE_OUTPUT:
516 		if (pin->flags[0] & ICE_AQC_GET_CGU_OUT_CFG_ESYNC_EN)
517 			flags |= ICE_AQC_SET_CGU_OUT_CFG_ESYNC_EN;
518 		ret = ice_aq_set_output_pin_cfg(hw, pin->idx, flags, 0, 0, 0);
519 		break;
520 	default:
521 		return -EINVAL;
522 	}
523 	if (ret)
524 		NL_SET_ERR_MSG_FMT(extack,
525 				   "err:%d %s failed to disable %s pin:%u",
526 				   ret, libie_aq_str(hw->adminq.sq_last_status),
527 				   pin_type_name[pin_type], pin->idx);
528 
529 	return ret;
530 }
531 
532 /**
533  * ice_dpll_pin_store_state - updates the state of pin in SW bookkeeping
534  * @pin: pointer to a pin
535  * @parent: parent pin index
536  * @state: pin state (connected or disconnected)
537  */
538 static void
ice_dpll_pin_store_state(struct ice_dpll_pin * pin,int parent,bool state)539 ice_dpll_pin_store_state(struct ice_dpll_pin *pin, int parent, bool state)
540 {
541 	pin->state[parent] = state ? DPLL_PIN_STATE_CONNECTED :
542 					DPLL_PIN_STATE_DISCONNECTED;
543 }
544 
545 /**
546  * ice_dpll_rclk_update_e825c - updates the state of rclk pin on e825c device
547  * @pf: private board struct
548  * @pin: pointer to a pin
549  *
550  * Update struct holding pin states info, states are separate for each parent
551  *
552  * Context: Called under pf->dplls.lock
553  * Return:
554  * * 0 - OK
555  * * negative - error
556  */
ice_dpll_rclk_update_e825c(struct ice_pf * pf,struct ice_dpll_pin * pin)557 static int ice_dpll_rclk_update_e825c(struct ice_pf *pf,
558 				      struct ice_dpll_pin *pin)
559 {
560 	u8 rclk_bits;
561 	int err;
562 	u32 reg;
563 
564 	if (pf->dplls.rclk.num_parents > ICE_SYNCE_CLK_NUM)
565 		return -EINVAL;
566 
567 	err = ice_read_cgu_reg(&pf->hw, ICE_CGU_R10, &reg);
568 	if (err)
569 		return err;
570 
571 	rclk_bits = FIELD_GET(ICE_CGU_R10_SYNCE_S_REF_CLK, reg);
572 	ice_dpll_pin_store_state(pin, ICE_SYNCE_CLK0, rclk_bits ==
573 		(pf->ptp.port.port_num + ICE_CGU_BYPASS_MUX_OFFSET_E825C));
574 
575 	err = ice_read_cgu_reg(&pf->hw, ICE_CGU_R11, &reg);
576 	if (err)
577 		return err;
578 
579 	rclk_bits = FIELD_GET(ICE_CGU_R11_SYNCE_S_BYP_CLK, reg);
580 	ice_dpll_pin_store_state(pin, ICE_SYNCE_CLK1, rclk_bits ==
581 		(pf->ptp.port.port_num + ICE_CGU_BYPASS_MUX_OFFSET_E825C));
582 
583 	return 0;
584 }
585 
586 /**
587  * ice_dpll_rclk_update - updates the state of rclk pin on a device
588  * @pf: private board struct
589  * @pin: pointer to a pin
590  * @port_num: port number
591  *
592  * Update struct holding pin states info, states are separate for each parent
593  *
594  * Context: Called under pf->dplls.lock
595  * Return:
596  * * 0 - OK
597  * * negative - error
598  */
ice_dpll_rclk_update(struct ice_pf * pf,struct ice_dpll_pin * pin,u8 port_num)599 static int ice_dpll_rclk_update(struct ice_pf *pf, struct ice_dpll_pin *pin,
600 				u8 port_num)
601 {
602 	int ret;
603 
604 	for (u8 parent = 0; parent < pf->dplls.rclk.num_parents; parent++) {
605 		u8 p = parent;
606 
607 		ret = ice_aq_get_phy_rec_clk_out(&pf->hw, &p, &port_num,
608 						 &pin->flags[parent], NULL);
609 		if (ret)
610 			return ret;
611 
612 		ice_dpll_pin_store_state(pin, parent,
613 					 ICE_AQC_GET_PHY_REC_CLK_OUT_OUT_EN &
614 					 pin->flags[parent]);
615 	}
616 
617 	return 0;
618 }
619 
620 /**
621  * ice_dpll_sw_pins_update - update status of all SW pins
622  * @pf: private board struct
623  *
624  * Determine and update pin struct fields (direction/active) of their current
625  * values for all the SW controlled pins.
626  *
627  * Context: Call with pf->dplls.lock held
628  * Return:
629  * * 0 - OK
630  * * negative - error
631  */
632 static int
ice_dpll_sw_pins_update(struct ice_pf * pf)633 ice_dpll_sw_pins_update(struct ice_pf *pf)
634 {
635 	struct ice_dplls *d = &pf->dplls;
636 	struct ice_dpll_pin *p;
637 	u8 data = 0;
638 	int ret;
639 
640 	ret = ice_read_sma_ctrl(&pf->hw, &data);
641 	if (ret)
642 		return ret;
643 	/* no change since last check */
644 	if (d->sma_data == data)
645 		return 0;
646 
647 	/*
648 	 * SMA1/U.FL1 vs SMA2/U.FL2 are using different bit scheme to decide
649 	 * on their direction and if are active
650 	 */
651 	p = &d->sma[ICE_DPLL_PIN_SW_1_IDX];
652 	p->active = true;
653 	p->direction = DPLL_PIN_DIRECTION_INPUT;
654 	if (data & ICE_SMA1_DIR_EN) {
655 		p->direction = DPLL_PIN_DIRECTION_OUTPUT;
656 		if (data & ICE_SMA1_TX_EN)
657 			p->active = false;
658 	}
659 
660 	p = &d->sma[ICE_DPLL_PIN_SW_2_IDX];
661 	p->active = true;
662 	p->direction = DPLL_PIN_DIRECTION_INPUT;
663 	if ((data & ICE_SMA2_INACTIVE_MASK) == ICE_SMA2_INACTIVE_MASK)
664 		p->active = false;
665 	else if (data & ICE_SMA2_DIR_EN)
666 		p->direction = DPLL_PIN_DIRECTION_OUTPUT;
667 
668 	p = &d->ufl[ICE_DPLL_PIN_SW_1_IDX];
669 	if (!(data & (ICE_SMA1_DIR_EN | ICE_SMA1_TX_EN)))
670 		p->active = true;
671 	else
672 		p->active = false;
673 
674 	p = &d->ufl[ICE_DPLL_PIN_SW_2_IDX];
675 	p->active = (data & ICE_SMA2_DIR_EN) && !(data & ICE_SMA2_UFL2_RX_DIS);
676 	d->sma_data = data;
677 
678 	return 0;
679 }
680 
681 /**
682  * ice_dpll_pin_state_update - update pin's state
683  * @pf: private board struct
684  * @pin: structure with pin attributes to be updated
685  * @pin_type: type of pin being updated
686  * @extack: error reporting
687  *
688  * Determine pin current state and frequency, then update struct
689  * holding the pin info. For input pin states are separated for each
690  * dpll, for rclk pins states are separated for each parent.
691  *
692  * Context: Called under pf->dplls.lock
693  * Return:
694  * * 0 - OK
695  * * negative - error
696  */
697 static int
ice_dpll_pin_state_update(struct ice_pf * pf,struct ice_dpll_pin * pin,enum ice_dpll_pin_type pin_type,struct netlink_ext_ack * extack)698 ice_dpll_pin_state_update(struct ice_pf *pf, struct ice_dpll_pin *pin,
699 			  enum ice_dpll_pin_type pin_type,
700 			  struct netlink_ext_ack *extack)
701 {
702 	u8 parent, port_num = ICE_AQC_SET_PHY_REC_CLK_OUT_CURR_PORT;
703 	int ret;
704 
705 	switch (pin_type) {
706 	case ICE_DPLL_PIN_TYPE_INPUT:
707 		ret = ice_aq_get_input_pin_cfg(&pf->hw, pin->idx, &pin->status,
708 					       NULL, NULL, &pin->flags[0],
709 					       &pin->freq, &pin->phase_adjust);
710 		if (ret)
711 			goto err;
712 		if (ICE_AQC_GET_CGU_IN_CFG_FLG2_INPUT_EN & pin->flags[0]) {
713 			if (pin->pin) {
714 				pin->state[pf->dplls.eec.dpll_idx] =
715 					pin->pin == pf->dplls.eec.active_input ?
716 					DPLL_PIN_STATE_CONNECTED :
717 					DPLL_PIN_STATE_SELECTABLE;
718 				pin->state[pf->dplls.pps.dpll_idx] =
719 					pin->pin == pf->dplls.pps.active_input ?
720 					DPLL_PIN_STATE_CONNECTED :
721 					DPLL_PIN_STATE_SELECTABLE;
722 			} else {
723 				pin->state[pf->dplls.eec.dpll_idx] =
724 					DPLL_PIN_STATE_SELECTABLE;
725 				pin->state[pf->dplls.pps.dpll_idx] =
726 					DPLL_PIN_STATE_SELECTABLE;
727 			}
728 		} else {
729 			pin->state[pf->dplls.eec.dpll_idx] =
730 				DPLL_PIN_STATE_DISCONNECTED;
731 			pin->state[pf->dplls.pps.dpll_idx] =
732 				DPLL_PIN_STATE_DISCONNECTED;
733 		}
734 		break;
735 	case ICE_DPLL_PIN_TYPE_OUTPUT:
736 		ret = ice_aq_get_output_pin_cfg(&pf->hw, pin->idx,
737 						&pin->flags[0], &parent,
738 						&pin->freq, NULL);
739 		if (ret)
740 			goto err;
741 
742 		parent &= ICE_AQC_GET_CGU_OUT_CFG_DPLL_SRC_SEL;
743 		if (ICE_AQC_GET_CGU_OUT_CFG_OUT_EN & pin->flags[0]) {
744 			pin->state[pf->dplls.eec.dpll_idx] =
745 				parent == pf->dplls.eec.dpll_idx ?
746 				DPLL_PIN_STATE_CONNECTED :
747 				DPLL_PIN_STATE_DISCONNECTED;
748 			pin->state[pf->dplls.pps.dpll_idx] =
749 				parent == pf->dplls.pps.dpll_idx ?
750 				DPLL_PIN_STATE_CONNECTED :
751 				DPLL_PIN_STATE_DISCONNECTED;
752 		} else {
753 			pin->state[pf->dplls.eec.dpll_idx] =
754 				DPLL_PIN_STATE_DISCONNECTED;
755 			pin->state[pf->dplls.pps.dpll_idx] =
756 				DPLL_PIN_STATE_DISCONNECTED;
757 		}
758 		break;
759 	case ICE_DPLL_PIN_TYPE_RCLK_INPUT:
760 		if (pf->hw.mac_type == ICE_MAC_GENERIC_3K_E825) {
761 			ret = ice_dpll_rclk_update_e825c(pf, pin);
762 			if (ret)
763 				goto err;
764 		} else {
765 			ret = ice_dpll_rclk_update(pf, pin, port_num);
766 			if (ret)
767 				goto err;
768 		}
769 		break;
770 	case ICE_DPLL_PIN_TYPE_SOFTWARE:
771 		ret = ice_dpll_sw_pins_update(pf);
772 		if (ret)
773 			goto err;
774 		break;
775 	default:
776 		return -EINVAL;
777 	}
778 
779 	return 0;
780 err:
781 	if (extack)
782 		NL_SET_ERR_MSG_FMT(extack,
783 				   "err:%d %s failed to update %s pin:%u",
784 				   ret,
785 				   libie_aq_str(pf->hw.adminq.sq_last_status),
786 				   pin_type_name[pin_type], pin->idx);
787 	else
788 		dev_err_ratelimited(ice_pf_to_dev(pf),
789 				    "err:%d %s failed to update %s pin:%u\n",
790 				    ret,
791 				    libie_aq_str(pf->hw.adminq.sq_last_status),
792 				    pin_type_name[pin_type], pin->idx);
793 	return ret;
794 }
795 
796 /**
797  * ice_dpll_hw_input_prio_set - set input priority value in hardware
798  * @pf: board private structure
799  * @dpll: ice dpll pointer
800  * @pin: ice pin pointer
801  * @prio: priority value being set on a dpll
802  * @extack: error reporting
803  *
804  * Internal wrapper for setting the priority in the hardware.
805  *
806  * Context: Called under pf->dplls.lock
807  * Return:
808  * * 0 - success
809  * * negative - failure
810  */
811 static int
ice_dpll_hw_input_prio_set(struct ice_pf * pf,struct ice_dpll * dpll,struct ice_dpll_pin * pin,const u32 prio,struct netlink_ext_ack * extack)812 ice_dpll_hw_input_prio_set(struct ice_pf *pf, struct ice_dpll *dpll,
813 			   struct ice_dpll_pin *pin, const u32 prio,
814 			   struct netlink_ext_ack *extack)
815 {
816 	int ret;
817 
818 	ret = ice_aq_set_cgu_ref_prio(&pf->hw, dpll->dpll_idx, pin->idx,
819 				      (u8)prio);
820 	if (ret)
821 		NL_SET_ERR_MSG_FMT(extack,
822 				   "err:%d %s failed to set pin prio:%u on pin:%u",
823 				   ret,
824 				   libie_aq_str(pf->hw.adminq.sq_last_status),
825 				   prio, pin->idx);
826 	else
827 		dpll->input_prio[pin->idx] = prio;
828 
829 	return ret;
830 }
831 
832 /**
833  * ice_dpll_lock_status_get - get dpll lock status callback
834  * @dpll: registered dpll pointer
835  * @dpll_priv: private data pointer passed on dpll registration
836  * @status: on success holds dpll's lock status
837  * @status_error: status error value
838  * @extack: error reporting
839  *
840  * Dpll subsystem callback, provides dpll's lock status.
841  *
842  * Context: Acquires pf->dplls.lock
843  * Return:
844  * * 0 - success
845  * * negative - failure
846  */
847 static int
ice_dpll_lock_status_get(const struct dpll_device * dpll,void * dpll_priv,enum dpll_lock_status * status,enum dpll_lock_status_error * status_error,struct netlink_ext_ack * extack)848 ice_dpll_lock_status_get(const struct dpll_device *dpll, void *dpll_priv,
849 			 enum dpll_lock_status *status,
850 			 enum dpll_lock_status_error *status_error,
851 			 struct netlink_ext_ack *extack)
852 {
853 	struct ice_dpll *d = dpll_priv;
854 	struct ice_pf *pf = d->pf;
855 
856 	mutex_lock(&pf->dplls.lock);
857 	*status = d->dpll_state;
858 	mutex_unlock(&pf->dplls.lock);
859 
860 	return 0;
861 }
862 
863 /**
864  * ice_dpll_mode_get - get dpll's working mode
865  * @dpll: registered dpll pointer
866  * @dpll_priv: private data pointer passed on dpll registration
867  * @mode: on success holds current working mode of dpll
868  * @extack: error reporting
869  *
870  * Dpll subsystem callback. Provides working mode of dpll.
871  *
872  * Context: Acquires pf->dplls.lock
873  * Return:
874  * * 0 - success
875  * * negative - failure
876  */
ice_dpll_mode_get(const struct dpll_device * dpll,void * dpll_priv,enum dpll_mode * mode,struct netlink_ext_ack * extack)877 static int ice_dpll_mode_get(const struct dpll_device *dpll, void *dpll_priv,
878 			     enum dpll_mode *mode,
879 			     struct netlink_ext_ack *extack)
880 {
881 	struct ice_dpll *d = dpll_priv;
882 	struct ice_pf *pf = d->pf;
883 
884 	mutex_lock(&pf->dplls.lock);
885 	*mode = d->mode;
886 	mutex_unlock(&pf->dplls.lock);
887 
888 	return 0;
889 }
890 
891 /**
892  * ice_dpll_phase_offset_monitor_set - set phase offset monitor state
893  * @dpll: registered dpll pointer
894  * @dpll_priv: private data pointer passed on dpll registration
895  * @state: feature state to be set
896  * @extack: error reporting
897  *
898  * Dpll subsystem callback. Enable/disable phase offset monitor feature of dpll.
899  *
900  * Context: Acquires and releases pf->dplls.lock
901  * Return: 0 - success
902  */
ice_dpll_phase_offset_monitor_set(const struct dpll_device * dpll,void * dpll_priv,enum dpll_feature_state state,struct netlink_ext_ack * extack)903 static int ice_dpll_phase_offset_monitor_set(const struct dpll_device *dpll,
904 					     void *dpll_priv,
905 					     enum dpll_feature_state state,
906 					     struct netlink_ext_ack *extack)
907 {
908 	struct ice_dpll *d = dpll_priv;
909 	struct ice_pf *pf = d->pf;
910 
911 	mutex_lock(&pf->dplls.lock);
912 	if (state == DPLL_FEATURE_STATE_ENABLE)
913 		d->phase_offset_monitor_period = ICE_DPLL_PHASE_OFFSET_PERIOD;
914 	else
915 		d->phase_offset_monitor_period = 0;
916 	mutex_unlock(&pf->dplls.lock);
917 
918 	return 0;
919 }
920 
921 /**
922  * ice_dpll_phase_offset_monitor_get - get phase offset monitor state
923  * @dpll: registered dpll pointer
924  * @dpll_priv: private data pointer passed on dpll registration
925  * @state: on success holds current state of phase offset monitor
926  * @extack: error reporting
927  *
928  * Dpll subsystem callback. Provides current state of phase offset monitor
929  * features on dpll device.
930  *
931  * Context: Acquires and releases pf->dplls.lock
932  * Return: 0 - success
933  */
ice_dpll_phase_offset_monitor_get(const struct dpll_device * dpll,void * dpll_priv,enum dpll_feature_state * state,struct netlink_ext_ack * extack)934 static int ice_dpll_phase_offset_monitor_get(const struct dpll_device *dpll,
935 					     void *dpll_priv,
936 					     enum dpll_feature_state *state,
937 					     struct netlink_ext_ack *extack)
938 {
939 	struct ice_dpll *d = dpll_priv;
940 	struct ice_pf *pf = d->pf;
941 
942 	mutex_lock(&pf->dplls.lock);
943 	if (d->phase_offset_monitor_period)
944 		*state = DPLL_FEATURE_STATE_ENABLE;
945 	else
946 		*state = DPLL_FEATURE_STATE_DISABLE;
947 	mutex_unlock(&pf->dplls.lock);
948 
949 	return 0;
950 }
951 
952 /**
953  * ice_dpll_pin_state_set - set pin's state on dpll
954  * @pin: pointer to a pin
955  * @pin_priv: private data pointer passed on pin registration
956  * @dpll: registered dpll pointer
957  * @dpll_priv: private data pointer passed on dpll registration
958  * @enable: if pin shalll be enabled
959  * @extack: error reporting
960  * @pin_type: type of a pin
961  *
962  * Set pin state on a pin.
963  *
964  * Context: Acquires pf->dplls.lock
965  * Return:
966  * * 0 - OK or no change required
967  * * negative - error
968  */
969 static int
ice_dpll_pin_state_set(const struct dpll_pin * pin,void * pin_priv,const struct dpll_device * dpll,void * dpll_priv,bool enable,struct netlink_ext_ack * extack,enum ice_dpll_pin_type pin_type)970 ice_dpll_pin_state_set(const struct dpll_pin *pin, void *pin_priv,
971 		       const struct dpll_device *dpll, void *dpll_priv,
972 		       bool enable, struct netlink_ext_ack *extack,
973 		       enum ice_dpll_pin_type pin_type)
974 {
975 	struct ice_dpll_pin *p = pin_priv;
976 	struct ice_dpll *d = dpll_priv;
977 	struct ice_pf *pf = d->pf;
978 	int ret;
979 
980 	if (ice_dpll_is_reset(pf, extack))
981 		return -EBUSY;
982 
983 	mutex_lock(&pf->dplls.lock);
984 	if (enable)
985 		ret = ice_dpll_pin_enable(&pf->hw, p, d->dpll_idx, pin_type,
986 					  extack);
987 	else
988 		ret = ice_dpll_pin_disable(&pf->hw, p, pin_type, extack);
989 	if (!ret)
990 		ret = ice_dpll_pin_state_update(pf, p, pin_type, extack);
991 	mutex_unlock(&pf->dplls.lock);
992 
993 	return ret;
994 }
995 
996 /**
997  * ice_dpll_output_state_set - enable/disable output pin on dpll device
998  * @pin: pointer to a pin
999  * @pin_priv: private data pointer passed on pin registration
1000  * @dpll: dpll being configured
1001  * @dpll_priv: private data pointer passed on dpll registration
1002  * @state: state of pin to be set
1003  * @extack: error reporting
1004  *
1005  * Dpll subsystem callback. Set given state on output type pin.
1006  *
1007  * Context: Calls a function which acquires pf->dplls.lock
1008  * Return:
1009  * * 0 - successfully enabled mode
1010  * * negative - failed to enable mode
1011  */
1012 static int
ice_dpll_output_state_set(const struct dpll_pin * pin,void * pin_priv,const struct dpll_device * dpll,void * dpll_priv,enum dpll_pin_state state,struct netlink_ext_ack * extack)1013 ice_dpll_output_state_set(const struct dpll_pin *pin, void *pin_priv,
1014 			  const struct dpll_device *dpll, void *dpll_priv,
1015 			  enum dpll_pin_state state,
1016 			  struct netlink_ext_ack *extack)
1017 {
1018 	bool enable = state == DPLL_PIN_STATE_CONNECTED;
1019 	struct ice_dpll_pin *p = pin_priv;
1020 	struct ice_dpll *d = dpll_priv;
1021 
1022 	if (state == DPLL_PIN_STATE_SELECTABLE)
1023 		return -EINVAL;
1024 	if (!enable && p->state[d->dpll_idx] == DPLL_PIN_STATE_DISCONNECTED)
1025 		return 0;
1026 
1027 	return ice_dpll_pin_state_set(pin, pin_priv, dpll, dpll_priv, enable,
1028 				      extack, ICE_DPLL_PIN_TYPE_OUTPUT);
1029 }
1030 
1031 /**
1032  * ice_dpll_input_state_set - enable/disable input pin on dpll levice
1033  * @pin: pointer to a pin
1034  * @pin_priv: private data pointer passed on pin registration
1035  * @dpll: dpll being configured
1036  * @dpll_priv: private data pointer passed on dpll registration
1037  * @state: state of pin to be set
1038  * @extack: error reporting
1039  *
1040  * Dpll subsystem callback. Enables given mode on input type pin.
1041  *
1042  * Context: Calls a function which acquires pf->dplls.lock
1043  * Return:
1044  * * 0 - successfully enabled mode
1045  * * negative - failed to enable mode
1046  */
1047 static int
ice_dpll_input_state_set(const struct dpll_pin * pin,void * pin_priv,const struct dpll_device * dpll,void * dpll_priv,enum dpll_pin_state state,struct netlink_ext_ack * extack)1048 ice_dpll_input_state_set(const struct dpll_pin *pin, void *pin_priv,
1049 			 const struct dpll_device *dpll, void *dpll_priv,
1050 			 enum dpll_pin_state state,
1051 			 struct netlink_ext_ack *extack)
1052 {
1053 	bool enable = state == DPLL_PIN_STATE_SELECTABLE;
1054 
1055 	return ice_dpll_pin_state_set(pin, pin_priv, dpll, dpll_priv, enable,
1056 				      extack, ICE_DPLL_PIN_TYPE_INPUT);
1057 }
1058 
1059 /**
1060  * ice_dpll_pin_state_get - set pin's state on dpll
1061  * @pin: pointer to a pin
1062  * @pin_priv: private data pointer passed on pin registration
1063  * @dpll: registered dpll pointer
1064  * @dpll_priv: private data pointer passed on dpll registration
1065  * @state: on success holds state of the pin
1066  * @extack: error reporting
1067  * @pin_type: type of questioned pin
1068  *
1069  * Determine pin state set it on a pin.
1070  *
1071  * Context: Acquires pf->dplls.lock
1072  * Return:
1073  * * 0 - success
1074  * * negative - failed to get state
1075  */
1076 static int
ice_dpll_pin_state_get(const struct dpll_pin * pin,void * pin_priv,const struct dpll_device * dpll,void * dpll_priv,enum dpll_pin_state * state,struct netlink_ext_ack * extack,enum ice_dpll_pin_type pin_type)1077 ice_dpll_pin_state_get(const struct dpll_pin *pin, void *pin_priv,
1078 		       const struct dpll_device *dpll, void *dpll_priv,
1079 		       enum dpll_pin_state *state,
1080 		       struct netlink_ext_ack *extack,
1081 		       enum ice_dpll_pin_type pin_type)
1082 {
1083 	struct ice_dpll_pin *p = pin_priv;
1084 	struct ice_dpll *d = dpll_priv;
1085 	struct ice_pf *pf = d->pf;
1086 	int ret;
1087 
1088 	if (ice_dpll_is_reset(pf, extack))
1089 		return -EBUSY;
1090 
1091 	mutex_lock(&pf->dplls.lock);
1092 	ret = ice_dpll_pin_state_update(pf, p, pin_type, extack);
1093 	if (ret)
1094 		goto unlock;
1095 	if (pin_type == ICE_DPLL_PIN_TYPE_INPUT ||
1096 	    pin_type == ICE_DPLL_PIN_TYPE_OUTPUT)
1097 		*state = p->state[d->dpll_idx];
1098 	ret = 0;
1099 unlock:
1100 	mutex_unlock(&pf->dplls.lock);
1101 
1102 	return ret;
1103 }
1104 
1105 /**
1106  * ice_dpll_output_state_get - get output pin state on dpll device
1107  * @pin: pointer to a pin
1108  * @pin_priv: private data pointer passed on pin registration
1109  * @dpll: registered dpll pointer
1110  * @dpll_priv: private data pointer passed on dpll registration
1111  * @state: on success holds state of the pin
1112  * @extack: error reporting
1113  *
1114  * Dpll subsystem callback. Check state of a pin.
1115  *
1116  * Context: Calls a function which acquires pf->dplls.lock
1117  * Return:
1118  * * 0 - success
1119  * * negative - failed to get state
1120  */
1121 static int
ice_dpll_output_state_get(const struct dpll_pin * pin,void * pin_priv,const struct dpll_device * dpll,void * dpll_priv,enum dpll_pin_state * state,struct netlink_ext_ack * extack)1122 ice_dpll_output_state_get(const struct dpll_pin *pin, void *pin_priv,
1123 			  const struct dpll_device *dpll, void *dpll_priv,
1124 			  enum dpll_pin_state *state,
1125 			  struct netlink_ext_ack *extack)
1126 {
1127 	return ice_dpll_pin_state_get(pin, pin_priv, dpll, dpll_priv, state,
1128 				      extack, ICE_DPLL_PIN_TYPE_OUTPUT);
1129 }
1130 
1131 /**
1132  * ice_dpll_input_state_get - get input pin state on dpll device
1133  * @pin: pointer to a pin
1134  * @pin_priv: private data pointer passed on pin registration
1135  * @dpll: registered dpll pointer
1136  * @dpll_priv: private data pointer passed on dpll registration
1137  * @state: on success holds state of the pin
1138  * @extack: error reporting
1139  *
1140  * Dpll subsystem callback. Check state of a input pin.
1141  *
1142  * Context: Calls a function which acquires pf->dplls.lock
1143  * Return:
1144  * * 0 - success
1145  * * negative - failed to get state
1146  */
1147 static int
ice_dpll_input_state_get(const struct dpll_pin * pin,void * pin_priv,const struct dpll_device * dpll,void * dpll_priv,enum dpll_pin_state * state,struct netlink_ext_ack * extack)1148 ice_dpll_input_state_get(const struct dpll_pin *pin, void *pin_priv,
1149 			 const struct dpll_device *dpll, void *dpll_priv,
1150 			 enum dpll_pin_state *state,
1151 			 struct netlink_ext_ack *extack)
1152 {
1153 	return ice_dpll_pin_state_get(pin, pin_priv, dpll, dpll_priv, state,
1154 				      extack, ICE_DPLL_PIN_TYPE_INPUT);
1155 }
1156 
1157 /**
1158  * ice_dpll_sma_direction_set - set direction of SMA pin
1159  * @p: pointer to a pin
1160  * @direction: requested direction of the pin
1161  * @extack: error reporting
1162  *
1163  * Wrapper for dpll subsystem callback. Set direction of a SMA pin.
1164  *
1165  * Context: Call with pf->dplls.lock held
1166  * Return:
1167  * * 0 - success
1168  * * negative - failed to get state
1169  */
ice_dpll_sma_direction_set(struct ice_dpll_pin * p,enum dpll_pin_direction direction,struct netlink_ext_ack * extack)1170 static int ice_dpll_sma_direction_set(struct ice_dpll_pin *p,
1171 				      enum dpll_pin_direction direction,
1172 				      struct netlink_ext_ack *extack)
1173 {
1174 	u8 data;
1175 	int ret;
1176 
1177 	if (p->direction == direction && p->active)
1178 		return 0;
1179 	ret = ice_read_sma_ctrl(&p->pf->hw, &data);
1180 	if (ret)
1181 		return ret;
1182 
1183 	switch (p->idx) {
1184 	case ICE_DPLL_PIN_SW_1_IDX:
1185 		data &= ~ICE_SMA1_MASK;
1186 		if (direction == DPLL_PIN_DIRECTION_OUTPUT)
1187 			data |= ICE_SMA1_DIR_EN;
1188 		break;
1189 	case ICE_DPLL_PIN_SW_2_IDX:
1190 		if (direction == DPLL_PIN_DIRECTION_INPUT) {
1191 			data &= ~ICE_SMA2_DIR_EN;
1192 		} else {
1193 			data &= ~ICE_SMA2_TX_EN;
1194 			data |= ICE_SMA2_DIR_EN;
1195 		}
1196 		break;
1197 	default:
1198 		return -EINVAL;
1199 	}
1200 	ret = ice_write_sma_ctrl(&p->pf->hw, data);
1201 	if (!ret)
1202 		ret = ice_dpll_pin_state_update(p->pf, p,
1203 						ICE_DPLL_PIN_TYPE_SOFTWARE,
1204 						extack);
1205 
1206 	return ret;
1207 }
1208 
1209 /**
1210  * ice_dpll_ufl_pin_state_set - set U.FL pin state on dpll device
1211  * @pin: pointer to a pin
1212  * @pin_priv: private data pointer passed on pin registration
1213  * @dpll: registered dpll pointer
1214  * @dpll_priv: private data pointer passed on dpll registration
1215  * @state: requested state of the pin
1216  * @extack: error reporting
1217  *
1218  * Dpll subsystem callback. Set the state of a pin.
1219  *
1220  * Context: Acquires and releases pf->dplls.lock
1221  * Return:
1222  * * 0 - success
1223  * * negative - error
1224  */
1225 static int
ice_dpll_ufl_pin_state_set(const struct dpll_pin * pin,void * pin_priv,const struct dpll_device * dpll,void * dpll_priv,enum dpll_pin_state state,struct netlink_ext_ack * extack)1226 ice_dpll_ufl_pin_state_set(const struct dpll_pin *pin, void *pin_priv,
1227 			   const struct dpll_device *dpll, void *dpll_priv,
1228 			   enum dpll_pin_state state,
1229 			   struct netlink_ext_ack *extack)
1230 {
1231 	struct ice_dpll_pin *p = pin_priv, *target;
1232 	struct ice_dpll *d = dpll_priv;
1233 	enum ice_dpll_pin_type type;
1234 	struct ice_pf *pf = p->pf;
1235 	struct ice_hw *hw;
1236 	bool enable;
1237 	u8 data;
1238 	int ret;
1239 
1240 	if (ice_dpll_is_reset(pf, extack))
1241 		return -EBUSY;
1242 
1243 	mutex_lock(&pf->dplls.lock);
1244 	hw = &pf->hw;
1245 	ret = ice_read_sma_ctrl(hw, &data);
1246 	if (ret)
1247 		goto unlock;
1248 
1249 	ret = -EINVAL;
1250 	switch (p->idx) {
1251 	case ICE_DPLL_PIN_SW_1_IDX:
1252 		if (state == DPLL_PIN_STATE_CONNECTED) {
1253 			data &= ~ICE_SMA1_MASK;
1254 			enable = true;
1255 		} else if (state == DPLL_PIN_STATE_DISCONNECTED) {
1256 			data |= ICE_SMA1_TX_EN;
1257 			enable = false;
1258 		} else {
1259 			goto unlock;
1260 		}
1261 		target = p->output;
1262 		type = ICE_DPLL_PIN_TYPE_OUTPUT;
1263 		break;
1264 	case ICE_DPLL_PIN_SW_2_IDX:
1265 		if (state == DPLL_PIN_STATE_SELECTABLE) {
1266 			data |= ICE_SMA2_DIR_EN;
1267 			data &= ~ICE_SMA2_UFL2_RX_DIS;
1268 			enable = true;
1269 		} else if (state == DPLL_PIN_STATE_DISCONNECTED) {
1270 			data |= ICE_SMA2_UFL2_RX_DIS;
1271 			enable = false;
1272 		} else {
1273 			goto unlock;
1274 		}
1275 		target = p->input;
1276 		type = ICE_DPLL_PIN_TYPE_INPUT;
1277 		break;
1278 	default:
1279 		goto unlock;
1280 	}
1281 
1282 	ret = ice_write_sma_ctrl(hw, data);
1283 	if (ret)
1284 		goto unlock;
1285 	ret = ice_dpll_pin_state_update(pf, p, ICE_DPLL_PIN_TYPE_SOFTWARE,
1286 					extack);
1287 	if (ret)
1288 		goto unlock;
1289 
1290 	if (enable)
1291 		ret = ice_dpll_pin_enable(hw, target, d->dpll_idx, type, extack);
1292 	else
1293 		ret = ice_dpll_pin_disable(hw, target, type, extack);
1294 	if (!ret)
1295 		ret = ice_dpll_pin_state_update(pf, target, type, extack);
1296 
1297 unlock:
1298 	mutex_unlock(&pf->dplls.lock);
1299 
1300 	return ret;
1301 }
1302 
1303 /**
1304  * ice_dpll_sw_pin_state_get - get SW pin state
1305  * @pin: pointer to a pin
1306  * @pin_priv: private data pointer passed on pin registration
1307  * @dpll: registered dpll pointer
1308  * @dpll_priv: private data pointer passed on dpll registration
1309  * @state: on success holds state of the pin
1310  * @extack: error reporting
1311  *
1312  * Dpll subsystem callback. Check state of a SW pin.
1313  *
1314  * Context: Acquires and releases pf->dplls.lock
1315  * Return:
1316  * * 0 - success
1317  * * negative - error
1318  */
1319 static int
ice_dpll_sw_pin_state_get(const struct dpll_pin * pin,void * pin_priv,const struct dpll_device * dpll,void * dpll_priv,enum dpll_pin_state * state,struct netlink_ext_ack * extack)1320 ice_dpll_sw_pin_state_get(const struct dpll_pin *pin, void *pin_priv,
1321 			  const struct dpll_device *dpll, void *dpll_priv,
1322 			  enum dpll_pin_state *state,
1323 			  struct netlink_ext_ack *extack)
1324 {
1325 	struct ice_dpll_pin *p = pin_priv;
1326 	struct ice_dpll *d = dpll_priv;
1327 	struct ice_pf *pf = p->pf;
1328 	int ret = 0;
1329 
1330 	if (ice_dpll_is_reset(pf, extack))
1331 		return -EBUSY;
1332 	mutex_lock(&pf->dplls.lock);
1333 	if (!p->active) {
1334 		*state = DPLL_PIN_STATE_DISCONNECTED;
1335 		goto unlock;
1336 	}
1337 
1338 	if (p->direction == DPLL_PIN_DIRECTION_INPUT) {
1339 		ret = ice_dpll_pin_state_update(pf, p->input,
1340 						ICE_DPLL_PIN_TYPE_INPUT,
1341 						extack);
1342 		if (ret)
1343 			goto unlock;
1344 		*state = p->input->state[d->dpll_idx];
1345 	} else {
1346 		ret = ice_dpll_pin_state_update(pf, p->output,
1347 						ICE_DPLL_PIN_TYPE_OUTPUT,
1348 						extack);
1349 		if (ret)
1350 			goto unlock;
1351 		*state = p->output->state[d->dpll_idx];
1352 	}
1353 unlock:
1354 	mutex_unlock(&pf->dplls.lock);
1355 
1356 	return ret;
1357 }
1358 
1359 /**
1360  * ice_dpll_sma_pin_state_set - set SMA pin state on dpll device
1361  * @pin: pointer to a pin
1362  * @pin_priv: private data pointer passed on pin registration
1363  * @dpll: registered dpll pointer
1364  * @dpll_priv: private data pointer passed on dpll registration
1365  * @state: requested state of the pin
1366  * @extack: error reporting
1367  *
1368  * Dpll subsystem callback. Set state of a pin.
1369  *
1370  * Context: Acquires and releases pf->dplls.lock
1371  * Return:
1372  * * 0 - success
1373  * * negative - failed to get state
1374  */
1375 static int
ice_dpll_sma_pin_state_set(const struct dpll_pin * pin,void * pin_priv,const struct dpll_device * dpll,void * dpll_priv,enum dpll_pin_state state,struct netlink_ext_ack * extack)1376 ice_dpll_sma_pin_state_set(const struct dpll_pin *pin, void *pin_priv,
1377 			   const struct dpll_device *dpll, void *dpll_priv,
1378 			   enum dpll_pin_state state,
1379 			   struct netlink_ext_ack *extack)
1380 {
1381 	struct ice_dpll_pin *sma = pin_priv, *target;
1382 	struct ice_dpll *d = dpll_priv;
1383 	struct ice_pf *pf = sma->pf;
1384 	enum ice_dpll_pin_type type;
1385 	bool enable;
1386 	int ret;
1387 
1388 	if (ice_dpll_is_reset(pf, extack))
1389 		return -EBUSY;
1390 
1391 	mutex_lock(&pf->dplls.lock);
1392 	if (!sma->active) {
1393 		ret = ice_dpll_sma_direction_set(sma, sma->direction, extack);
1394 		if (ret)
1395 			goto unlock;
1396 	}
1397 	if (sma->direction == DPLL_PIN_DIRECTION_INPUT) {
1398 		enable = state == DPLL_PIN_STATE_SELECTABLE;
1399 		target = sma->input;
1400 		type = ICE_DPLL_PIN_TYPE_INPUT;
1401 	} else {
1402 		enable = state == DPLL_PIN_STATE_CONNECTED;
1403 		target = sma->output;
1404 		type = ICE_DPLL_PIN_TYPE_OUTPUT;
1405 	}
1406 
1407 	if (enable)
1408 		ret = ice_dpll_pin_enable(&pf->hw, target, d->dpll_idx, type,
1409 					  extack);
1410 	else
1411 		ret = ice_dpll_pin_disable(&pf->hw, target, type, extack);
1412 	if (!ret)
1413 		ret = ice_dpll_pin_state_update(pf, target, type, extack);
1414 
1415 unlock:
1416 	mutex_unlock(&pf->dplls.lock);
1417 
1418 	return ret;
1419 }
1420 
1421 /**
1422  * ice_dpll_input_prio_get - get dpll's input prio
1423  * @pin: pointer to a pin
1424  * @pin_priv: private data pointer passed on pin registration
1425  * @dpll: registered dpll pointer
1426  * @dpll_priv: private data pointer passed on dpll registration
1427  * @prio: on success - returns input priority on dpll
1428  * @extack: error reporting
1429  *
1430  * Dpll subsystem callback. Handler for getting priority of a input pin.
1431  *
1432  * Context: Acquires pf->dplls.lock
1433  * Return:
1434  * * 0 - success
1435  * * negative - failure
1436  */
1437 static int
ice_dpll_input_prio_get(const struct dpll_pin * pin,void * pin_priv,const struct dpll_device * dpll,void * dpll_priv,u32 * prio,struct netlink_ext_ack * extack)1438 ice_dpll_input_prio_get(const struct dpll_pin *pin, void *pin_priv,
1439 			const struct dpll_device *dpll, void *dpll_priv,
1440 			u32 *prio, struct netlink_ext_ack *extack)
1441 {
1442 	struct ice_dpll_pin *p = pin_priv;
1443 	struct ice_dpll *d = dpll_priv;
1444 	struct ice_pf *pf = d->pf;
1445 
1446 	mutex_lock(&pf->dplls.lock);
1447 	*prio = d->input_prio[p->idx];
1448 	mutex_unlock(&pf->dplls.lock);
1449 
1450 	return 0;
1451 }
1452 
1453 /**
1454  * ice_dpll_input_prio_set - set dpll input prio
1455  * @pin: pointer to a pin
1456  * @pin_priv: private data pointer passed on pin registration
1457  * @dpll: registered dpll pointer
1458  * @dpll_priv: private data pointer passed on dpll registration
1459  * @prio: input priority to be set on dpll
1460  * @extack: error reporting
1461  *
1462  * Dpll subsystem callback. Handler for setting priority of a input pin.
1463  *
1464  * Context: Acquires pf->dplls.lock
1465  * Return:
1466  * * 0 - success
1467  * * negative - failure
1468  */
1469 static int
ice_dpll_input_prio_set(const struct dpll_pin * pin,void * pin_priv,const struct dpll_device * dpll,void * dpll_priv,u32 prio,struct netlink_ext_ack * extack)1470 ice_dpll_input_prio_set(const struct dpll_pin *pin, void *pin_priv,
1471 			const struct dpll_device *dpll, void *dpll_priv,
1472 			u32 prio, struct netlink_ext_ack *extack)
1473 {
1474 	struct ice_dpll_pin *p = pin_priv;
1475 	struct ice_dpll *d = dpll_priv;
1476 	struct ice_pf *pf = d->pf;
1477 	int ret;
1478 
1479 	if (ice_dpll_is_reset(pf, extack))
1480 		return -EBUSY;
1481 
1482 	mutex_lock(&pf->dplls.lock);
1483 	ret = ice_dpll_hw_input_prio_set(pf, d, p, prio, extack);
1484 	mutex_unlock(&pf->dplls.lock);
1485 
1486 	return ret;
1487 }
1488 
1489 static int
ice_dpll_sw_input_prio_get(const struct dpll_pin * pin,void * pin_priv,const struct dpll_device * dpll,void * dpll_priv,u32 * prio,struct netlink_ext_ack * extack)1490 ice_dpll_sw_input_prio_get(const struct dpll_pin *pin, void *pin_priv,
1491 			   const struct dpll_device *dpll, void *dpll_priv,
1492 			   u32 *prio, struct netlink_ext_ack *extack)
1493 {
1494 	struct ice_dpll_pin *p = pin_priv;
1495 	struct ice_dpll *d = dpll_priv;
1496 	struct ice_pf *pf = d->pf;
1497 
1498 	mutex_lock(&pf->dplls.lock);
1499 	if (p->input && p->direction == DPLL_PIN_DIRECTION_INPUT)
1500 		*prio = d->input_prio[p->input->idx];
1501 	else
1502 		*prio = ICE_DPLL_PIN_PRIO_OUTPUT;
1503 	mutex_unlock(&pf->dplls.lock);
1504 
1505 	return 0;
1506 }
1507 
1508 static int
ice_dpll_sw_input_prio_set(const struct dpll_pin * pin,void * pin_priv,const struct dpll_device * dpll,void * dpll_priv,u32 prio,struct netlink_ext_ack * extack)1509 ice_dpll_sw_input_prio_set(const struct dpll_pin *pin, void *pin_priv,
1510 			   const struct dpll_device *dpll, void *dpll_priv,
1511 			   u32 prio, struct netlink_ext_ack *extack)
1512 {
1513 	struct ice_dpll_pin *p = pin_priv;
1514 	struct ice_dpll *d = dpll_priv;
1515 	struct ice_pf *pf = d->pf;
1516 	int ret;
1517 
1518 	if (!p->input || p->direction != DPLL_PIN_DIRECTION_INPUT)
1519 		return -EINVAL;
1520 	if (ice_dpll_is_reset(pf, extack))
1521 		return -EBUSY;
1522 
1523 	mutex_lock(&pf->dplls.lock);
1524 	ret = ice_dpll_hw_input_prio_set(pf, d, p->input, prio, extack);
1525 	mutex_unlock(&pf->dplls.lock);
1526 
1527 	return ret;
1528 }
1529 
1530 /**
1531  * ice_dpll_input_direction - callback for get input pin direction
1532  * @pin: pointer to a pin
1533  * @pin_priv: private data pointer passed on pin registration
1534  * @dpll: registered dpll pointer
1535  * @dpll_priv: private data pointer passed on dpll registration
1536  * @direction: holds input pin direction
1537  * @extack: error reporting
1538  *
1539  * Dpll subsystem callback. Handler for getting direction of a input pin.
1540  *
1541  * Return:
1542  * * 0 - success
1543  */
1544 static int
ice_dpll_input_direction(const struct dpll_pin * pin,void * pin_priv,const struct dpll_device * dpll,void * dpll_priv,enum dpll_pin_direction * direction,struct netlink_ext_ack * extack)1545 ice_dpll_input_direction(const struct dpll_pin *pin, void *pin_priv,
1546 			 const struct dpll_device *dpll, void *dpll_priv,
1547 			 enum dpll_pin_direction *direction,
1548 			 struct netlink_ext_ack *extack)
1549 {
1550 	*direction = DPLL_PIN_DIRECTION_INPUT;
1551 
1552 	return 0;
1553 }
1554 
1555 /**
1556  * ice_dpll_output_direction - callback for get output pin direction
1557  * @pin: pointer to a pin
1558  * @pin_priv: private data pointer passed on pin registration
1559  * @dpll: registered dpll pointer
1560  * @dpll_priv: private data pointer passed on dpll registration
1561  * @direction: holds output pin direction
1562  * @extack: error reporting
1563  *
1564  * Dpll subsystem callback. Handler for getting direction of an output pin.
1565  *
1566  * Return:
1567  * * 0 - success
1568  */
1569 static int
ice_dpll_output_direction(const struct dpll_pin * pin,void * pin_priv,const struct dpll_device * dpll,void * dpll_priv,enum dpll_pin_direction * direction,struct netlink_ext_ack * extack)1570 ice_dpll_output_direction(const struct dpll_pin *pin, void *pin_priv,
1571 			  const struct dpll_device *dpll, void *dpll_priv,
1572 			  enum dpll_pin_direction *direction,
1573 			  struct netlink_ext_ack *extack)
1574 {
1575 	*direction = DPLL_PIN_DIRECTION_OUTPUT;
1576 
1577 	return 0;
1578 }
1579 
1580 /**
1581  * ice_dpll_pin_sma_direction_set - callback for set SMA pin direction
1582  * @pin: pointer to a pin
1583  * @pin_priv: private data pointer passed on pin registration
1584  * @dpll: registered dpll pointer
1585  * @dpll_priv: private data pointer passed on dpll registration
1586  * @direction: requested pin direction
1587  * @extack: error reporting
1588  *
1589  * Dpll subsystem callback. Handler for setting direction of a SMA pin.
1590  *
1591  * Context: Acquires and releases pf->dplls.lock
1592  * Return:
1593  * * 0 - success
1594  * * negative - error
1595  */
1596 static int
ice_dpll_pin_sma_direction_set(const struct dpll_pin * pin,void * pin_priv,const struct dpll_device * dpll,void * dpll_priv,enum dpll_pin_direction direction,struct netlink_ext_ack * extack)1597 ice_dpll_pin_sma_direction_set(const struct dpll_pin *pin, void *pin_priv,
1598 			       const struct dpll_device *dpll, void *dpll_priv,
1599 			       enum dpll_pin_direction direction,
1600 			       struct netlink_ext_ack *extack)
1601 {
1602 	struct ice_dpll_pin *p = pin_priv;
1603 	struct ice_pf *pf = p->pf;
1604 	int ret;
1605 
1606 	if (ice_dpll_is_reset(pf, extack))
1607 		return -EBUSY;
1608 
1609 	mutex_lock(&pf->dplls.lock);
1610 	ret = ice_dpll_sma_direction_set(p, direction, extack);
1611 	mutex_unlock(&pf->dplls.lock);
1612 
1613 	return ret;
1614 }
1615 
1616 /**
1617  * ice_dpll_pin_sw_direction_get - callback for get SW pin direction
1618  * @pin: pointer to a pin
1619  * @pin_priv: private data pointer passed on pin registration
1620  * @dpll: registered dpll pointer
1621  * @dpll_priv: private data pointer passed on dpll registration
1622  * @direction: on success holds pin direction
1623  * @extack: error reporting
1624  *
1625  * Dpll subsystem callback. Handler for getting direction of a SMA pin.
1626  *
1627  * Context: Acquires and releases pf->dplls.lock
1628  * Return:
1629  * * 0 - success
1630  * * negative - error
1631  */
1632 static int
ice_dpll_pin_sw_direction_get(const struct dpll_pin * pin,void * pin_priv,const struct dpll_device * dpll,void * dpll_priv,enum dpll_pin_direction * direction,struct netlink_ext_ack * extack)1633 ice_dpll_pin_sw_direction_get(const struct dpll_pin *pin, void *pin_priv,
1634 			      const struct dpll_device *dpll, void *dpll_priv,
1635 			      enum dpll_pin_direction *direction,
1636 			      struct netlink_ext_ack *extack)
1637 {
1638 	struct ice_dpll_pin *p = pin_priv;
1639 	struct ice_pf *pf = p->pf;
1640 
1641 	if (ice_dpll_is_reset(pf, extack))
1642 		return -EBUSY;
1643 	mutex_lock(&pf->dplls.lock);
1644 	*direction = p->direction;
1645 	mutex_unlock(&pf->dplls.lock);
1646 
1647 	return 0;
1648 }
1649 
1650 /**
1651  * ice_dpll_pin_phase_adjust_get - callback for get pin phase adjust value
1652  * @pin: pointer to a pin
1653  * @pin_priv: private data pointer passed on pin registration
1654  * @dpll: registered dpll pointer
1655  * @dpll_priv: private data pointer passed on dpll registration
1656  * @phase_adjust: on success holds pin phase_adjust value
1657  * @extack: error reporting
1658  *
1659  * Dpll subsystem callback. Handler for getting phase adjust value of a pin.
1660  *
1661  * Context: Acquires pf->dplls.lock
1662  * Return:
1663  * * 0 - success
1664  * * negative - error
1665  */
1666 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)1667 ice_dpll_pin_phase_adjust_get(const struct dpll_pin *pin, void *pin_priv,
1668 			      const struct dpll_device *dpll, void *dpll_priv,
1669 			      s32 *phase_adjust,
1670 			      struct netlink_ext_ack *extack)
1671 {
1672 	struct ice_dpll_pin *p = pin_priv;
1673 	struct ice_pf *pf = p->pf;
1674 
1675 	mutex_lock(&pf->dplls.lock);
1676 	*phase_adjust = p->phase_adjust;
1677 	mutex_unlock(&pf->dplls.lock);
1678 
1679 	return 0;
1680 }
1681 
1682 /**
1683  * ice_dpll_pin_phase_adjust_set - helper for setting a pin phase adjust value
1684  * @pin: pointer to a pin
1685  * @pin_priv: private data pointer passed on pin registration
1686  * @dpll: registered dpll pointer
1687  * @dpll_priv: private data pointer passed on dpll registration
1688  * @phase_adjust: phase_adjust to be set
1689  * @extack: error reporting
1690  * @type: type of a pin
1691  *
1692  * Helper for dpll subsystem callback. Handler for setting phase adjust value
1693  * of a pin.
1694  *
1695  * Context: Acquires pf->dplls.lock
1696  * Return:
1697  * * 0 - success
1698  * * negative - error
1699  */
1700 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)1701 ice_dpll_pin_phase_adjust_set(const struct dpll_pin *pin, void *pin_priv,
1702 			      const struct dpll_device *dpll, void *dpll_priv,
1703 			      s32 phase_adjust,
1704 			      struct netlink_ext_ack *extack,
1705 			      enum ice_dpll_pin_type type)
1706 {
1707 	struct ice_dpll_pin *p = pin_priv;
1708 	struct ice_dpll *d = dpll_priv;
1709 	struct ice_pf *pf = d->pf;
1710 	u8 flag, flags_en = 0;
1711 	int ret;
1712 
1713 	if (ice_dpll_is_reset(pf, extack))
1714 		return -EBUSY;
1715 
1716 	mutex_lock(&pf->dplls.lock);
1717 	switch (type) {
1718 	case ICE_DPLL_PIN_TYPE_INPUT:
1719 		flag = ICE_AQC_SET_CGU_IN_CFG_FLG1_UPDATE_DELAY;
1720 		if (p->flags[0] & ICE_AQC_GET_CGU_IN_CFG_FLG2_ESYNC_EN)
1721 			flags_en |= ICE_AQC_SET_CGU_IN_CFG_FLG2_ESYNC_EN;
1722 		if (p->flags[0] & ICE_AQC_GET_CGU_IN_CFG_FLG2_INPUT_EN)
1723 			flags_en |= ICE_AQC_SET_CGU_IN_CFG_FLG2_INPUT_EN;
1724 		ret = ice_aq_set_input_pin_cfg(&pf->hw, p->idx, flag, flags_en,
1725 					       0, phase_adjust);
1726 		break;
1727 	case ICE_DPLL_PIN_TYPE_OUTPUT:
1728 		flag = ICE_AQC_SET_CGU_OUT_CFG_UPDATE_PHASE;
1729 		if (p->flags[0] & ICE_AQC_GET_CGU_OUT_CFG_OUT_EN)
1730 			flag |= ICE_AQC_SET_CGU_OUT_CFG_OUT_EN;
1731 		if (p->flags[0] & ICE_AQC_GET_CGU_OUT_CFG_ESYNC_EN)
1732 			flag |= ICE_AQC_SET_CGU_OUT_CFG_ESYNC_EN;
1733 		ret = ice_aq_set_output_pin_cfg(&pf->hw, p->idx, flag, 0, 0,
1734 						phase_adjust);
1735 		break;
1736 	default:
1737 		ret = -EINVAL;
1738 	}
1739 	if (!ret)
1740 		p->phase_adjust = phase_adjust;
1741 	mutex_unlock(&pf->dplls.lock);
1742 	if (ret)
1743 		NL_SET_ERR_MSG_FMT(extack,
1744 				   "err:%d %s failed to set pin phase_adjust:%d for pin:%u on dpll:%u",
1745 				   ret,
1746 				   libie_aq_str(pf->hw.adminq.sq_last_status),
1747 				   phase_adjust, p->idx, d->dpll_idx);
1748 
1749 	return ret;
1750 }
1751 
1752 /**
1753  * ice_dpll_input_phase_adjust_set - callback for set input pin phase adjust
1754  * @pin: pointer to a pin
1755  * @pin_priv: private data pointer passed on pin registration
1756  * @dpll: registered dpll pointer
1757  * @dpll_priv: private data pointer passed on dpll registration
1758  * @phase_adjust: phase_adjust to be set
1759  * @extack: error reporting
1760  *
1761  * Dpll subsystem callback. Wraps a handler for setting phase adjust on input
1762  * pin.
1763  *
1764  * Context: Calls a function which acquires and releases pf->dplls.lock
1765  * Return:
1766  * * 0 - success
1767  * * negative - error
1768  */
1769 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)1770 ice_dpll_input_phase_adjust_set(const struct dpll_pin *pin, void *pin_priv,
1771 				const struct dpll_device *dpll, void *dpll_priv,
1772 				s32 phase_adjust,
1773 				struct netlink_ext_ack *extack)
1774 {
1775 	return ice_dpll_pin_phase_adjust_set(pin, pin_priv, dpll, dpll_priv,
1776 					     phase_adjust, extack,
1777 					     ICE_DPLL_PIN_TYPE_INPUT);
1778 }
1779 
1780 /**
1781  * ice_dpll_output_phase_adjust_set - callback for set output pin phase adjust
1782  * @pin: pointer to a pin
1783  * @pin_priv: private data pointer passed on pin registration
1784  * @dpll: registered dpll pointer
1785  * @dpll_priv: private data pointer passed on dpll registration
1786  * @phase_adjust: phase_adjust to be set
1787  * @extack: error reporting
1788  *
1789  * Dpll subsystem callback. Wraps a handler for setting phase adjust on output
1790  * pin.
1791  *
1792  * Context: Calls a function which acquires pf->dplls.lock
1793  * Return:
1794  * * 0 - success
1795  * * negative - error
1796  */
1797 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)1798 ice_dpll_output_phase_adjust_set(const struct dpll_pin *pin, void *pin_priv,
1799 				 const struct dpll_device *dpll, void *dpll_priv,
1800 				 s32 phase_adjust,
1801 				 struct netlink_ext_ack *extack)
1802 {
1803 	return ice_dpll_pin_phase_adjust_set(pin, pin_priv, dpll, dpll_priv,
1804 					     phase_adjust, extack,
1805 					     ICE_DPLL_PIN_TYPE_OUTPUT);
1806 }
1807 
1808 /**
1809  * ice_dpll_sw_phase_adjust_get - callback for get SW pin phase adjust
1810  * @pin: pointer to a pin
1811  * @pin_priv: private data pointer passed on pin registration
1812  * @dpll: registered dpll pointer
1813  * @dpll_priv: private data pointer passed on dpll registration
1814  * @phase_adjust: on success holds phase adjust value
1815  * @extack: error reporting
1816  *
1817  * Dpll subsystem callback. Wraps a handler for getting phase adjust on sw
1818  * pin.
1819  *
1820  * Context: Calls a function which acquires and releases pf->dplls.lock
1821  * Return:
1822  * * 0 - success
1823  * * negative - error
1824  */
1825 static int
ice_dpll_sw_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)1826 ice_dpll_sw_phase_adjust_get(const struct dpll_pin *pin, void *pin_priv,
1827 			     const struct dpll_device *dpll, void *dpll_priv,
1828 			     s32 *phase_adjust,
1829 			     struct netlink_ext_ack *extack)
1830 {
1831 	struct ice_dpll_pin *p = pin_priv;
1832 
1833 	if (p->direction == DPLL_PIN_DIRECTION_INPUT)
1834 		return ice_dpll_pin_phase_adjust_get(p->input->pin, p->input,
1835 						     dpll, dpll_priv,
1836 						     phase_adjust, extack);
1837 	else
1838 		return ice_dpll_pin_phase_adjust_get(p->output->pin, p->output,
1839 						     dpll, dpll_priv,
1840 						     phase_adjust, extack);
1841 }
1842 
1843 /**
1844  * ice_dpll_sw_phase_adjust_set - callback for set SW pin phase adjust value
1845  * @pin: pointer to a pin
1846  * @pin_priv: private data pointer passed on pin registration
1847  * @dpll: registered dpll pointer
1848  * @dpll_priv: private data pointer passed on dpll registration
1849  * @phase_adjust: phase_adjust to be set
1850  * @extack: error reporting
1851  *
1852  * Dpll subsystem callback. Wraps a handler for setting phase adjust on output
1853  * pin.
1854  *
1855  * Context: Calls a function which acquires and releases pf->dplls.lock
1856  * Return:
1857  * * 0 - success
1858  * * negative - error
1859  */
1860 static int
ice_dpll_sw_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)1861 ice_dpll_sw_phase_adjust_set(const struct dpll_pin *pin, void *pin_priv,
1862 			     const struct dpll_device *dpll, void *dpll_priv,
1863 			     s32 phase_adjust,
1864 			     struct netlink_ext_ack *extack)
1865 {
1866 	struct ice_dpll_pin *p = pin_priv;
1867 
1868 	if (!p->active) {
1869 		NL_SET_ERR_MSG(extack, "pin is not active");
1870 		return -EINVAL;
1871 	}
1872 	if (p->direction == DPLL_PIN_DIRECTION_INPUT)
1873 		return ice_dpll_pin_phase_adjust_set(p->input->pin, p->input,
1874 						     dpll, dpll_priv,
1875 						     phase_adjust, extack,
1876 						     ICE_DPLL_PIN_TYPE_INPUT);
1877 	else
1878 		return ice_dpll_pin_phase_adjust_set(p->output->pin, p->output,
1879 						     dpll, dpll_priv,
1880 						     phase_adjust, extack,
1881 						     ICE_DPLL_PIN_TYPE_OUTPUT);
1882 }
1883 
1884 #define ICE_DPLL_PHASE_OFFSET_DIVIDER	100
1885 #define ICE_DPLL_PHASE_OFFSET_FACTOR		\
1886 	(DPLL_PHASE_OFFSET_DIVIDER / ICE_DPLL_PHASE_OFFSET_DIVIDER)
1887 /**
1888  * ice_dpll_phase_offset_get - callback for get dpll phase shift value
1889  * @pin: pointer to a pin
1890  * @pin_priv: private data pointer passed on pin registration
1891  * @dpll: registered dpll pointer
1892  * @dpll_priv: private data pointer passed on dpll registration
1893  * @phase_offset: on success holds pin phase_offset value
1894  * @extack: error reporting
1895  *
1896  * Dpll subsystem callback. Handler for getting phase shift value between
1897  * dpll's input and output.
1898  *
1899  * Context: Acquires pf->dplls.lock
1900  * Return:
1901  * * 0 - success
1902  * * negative - error
1903  */
1904 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)1905 ice_dpll_phase_offset_get(const struct dpll_pin *pin, void *pin_priv,
1906 			  const struct dpll_device *dpll, void *dpll_priv,
1907 			  s64 *phase_offset, struct netlink_ext_ack *extack)
1908 {
1909 	struct ice_dpll_pin *p = pin_priv;
1910 	struct ice_dpll *d = dpll_priv;
1911 	struct ice_pf *pf = d->pf;
1912 
1913 	mutex_lock(&pf->dplls.lock);
1914 	if (d->active_input == pin || (p->input &&
1915 				       d->active_input == p->input->pin))
1916 		*phase_offset = d->phase_offset * ICE_DPLL_PHASE_OFFSET_FACTOR;
1917 	else if (d->phase_offset_monitor_period)
1918 		*phase_offset = p->phase_offset * ICE_DPLL_PHASE_OFFSET_FACTOR;
1919 	else
1920 		*phase_offset = 0;
1921 	mutex_unlock(&pf->dplls.lock);
1922 
1923 	return 0;
1924 }
1925 
1926 /**
1927  * ice_dpll_synce_update_e825c - setting PHY recovered clock pins on e825c
1928  * @hw: Pointer to the HW struct
1929  * @ena: true if enable, false in disable
1930  * @port_num: port number
1931  * @output: output pin, we have two in E825C
1932  *
1933  * DPLL subsystem callback. Set proper signals to recover clock from port.
1934  *
1935  * Context: Called under pf->dplls.lock
1936  * Return:
1937  * * 0 - success
1938  * * negative - error
1939  */
ice_dpll_synce_update_e825c(struct ice_hw * hw,bool ena,u32 port_num,enum ice_synce_clk output)1940 static int ice_dpll_synce_update_e825c(struct ice_hw *hw, bool ena,
1941 				       u32 port_num, enum ice_synce_clk output)
1942 {
1943 	int err;
1944 
1945 	/* configure the mux to deliver proper signal to DPLL from the MUX */
1946 	err = ice_tspll_cfg_bypass_mux_e825c(hw, ena, port_num, output);
1947 	if (err)
1948 		return err;
1949 
1950 	err = ice_tspll_cfg_synce_ethdiv_e825c(hw, output);
1951 	if (err)
1952 		return err;
1953 
1954 	dev_dbg(ice_hw_to_dev(hw), "CLK_SYNCE%u recovered clock: pin %s\n",
1955 		output, str_enabled_disabled(ena));
1956 
1957 	return 0;
1958 }
1959 
1960 /**
1961  * ice_dpll_output_esync_set - callback for setting embedded sync
1962  * @pin: pointer to a pin
1963  * @pin_priv: private data pointer passed on pin registration
1964  * @dpll: registered dpll pointer
1965  * @dpll_priv: private data pointer passed on dpll registration
1966  * @freq: requested embedded sync frequency
1967  * @extack: error reporting
1968  *
1969  * Dpll subsystem callback. Handler for setting embedded sync frequency value
1970  * on output pin.
1971  *
1972  * Context: Acquires pf->dplls.lock
1973  * Return:
1974  * * 0 - success
1975  * * negative - error
1976  */
1977 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)1978 ice_dpll_output_esync_set(const struct dpll_pin *pin, void *pin_priv,
1979 			  const struct dpll_device *dpll, void *dpll_priv,
1980 			  u64 freq, struct netlink_ext_ack *extack)
1981 {
1982 	struct ice_dpll_pin *p = pin_priv;
1983 	struct ice_dpll *d = dpll_priv;
1984 	struct ice_pf *pf = d->pf;
1985 	u8 flags = 0;
1986 	int ret;
1987 
1988 	if (ice_dpll_is_reset(pf, extack))
1989 		return -EBUSY;
1990 	mutex_lock(&pf->dplls.lock);
1991 	if (p->flags[0] & ICE_AQC_GET_CGU_OUT_CFG_OUT_EN)
1992 		flags = ICE_AQC_SET_CGU_OUT_CFG_OUT_EN;
1993 	if (freq == DPLL_PIN_FREQUENCY_1_HZ) {
1994 		if (p->flags[0] & ICE_AQC_GET_CGU_OUT_CFG_ESYNC_EN) {
1995 			ret = 0;
1996 		} else {
1997 			flags |= ICE_AQC_SET_CGU_OUT_CFG_ESYNC_EN;
1998 			ret = ice_aq_set_output_pin_cfg(&pf->hw, p->idx, flags,
1999 							0, 0, 0);
2000 		}
2001 	} else {
2002 		if (!(p->flags[0] & ICE_AQC_GET_CGU_OUT_CFG_ESYNC_EN)) {
2003 			ret = 0;
2004 		} else {
2005 			flags &= ~ICE_AQC_SET_CGU_OUT_CFG_ESYNC_EN;
2006 			ret = ice_aq_set_output_pin_cfg(&pf->hw, p->idx, flags,
2007 							0, 0, 0);
2008 		}
2009 	}
2010 	mutex_unlock(&pf->dplls.lock);
2011 
2012 	return ret;
2013 }
2014 
2015 /**
2016  * ice_dpll_output_esync_get - callback for getting embedded sync config
2017  * @pin: pointer to a pin
2018  * @pin_priv: private data pointer passed on pin registration
2019  * @dpll: registered dpll pointer
2020  * @dpll_priv: private data pointer passed on dpll registration
2021  * @esync: on success holds embedded sync pin properties
2022  * @extack: error reporting
2023  *
2024  * Dpll subsystem callback. Handler for getting embedded sync frequency value
2025  * and capabilities on output pin.
2026  *
2027  * Context: Acquires pf->dplls.lock
2028  * Return:
2029  * * 0 - success
2030  * * negative - error
2031  */
2032 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)2033 ice_dpll_output_esync_get(const struct dpll_pin *pin, void *pin_priv,
2034 			  const struct dpll_device *dpll, void *dpll_priv,
2035 			  struct dpll_pin_esync *esync,
2036 			  struct netlink_ext_ack *extack)
2037 {
2038 	struct ice_dpll_pin *p = pin_priv;
2039 	struct ice_dpll *d = dpll_priv;
2040 	struct ice_pf *pf = d->pf;
2041 
2042 	if (ice_dpll_is_reset(pf, extack))
2043 		return -EBUSY;
2044 	mutex_lock(&pf->dplls.lock);
2045 	if (!(p->flags[0] & ICE_AQC_GET_CGU_OUT_CFG_ESYNC_ABILITY) ||
2046 	    p->freq != DPLL_PIN_FREQUENCY_10_MHZ) {
2047 		mutex_unlock(&pf->dplls.lock);
2048 		return -EOPNOTSUPP;
2049 	}
2050 	esync->range = ice_esync_range;
2051 	esync->range_num = ARRAY_SIZE(ice_esync_range);
2052 	if (p->flags[0] & ICE_AQC_GET_CGU_OUT_CFG_ESYNC_EN) {
2053 		esync->freq = DPLL_PIN_FREQUENCY_1_HZ;
2054 		esync->pulse = ICE_DPLL_PIN_ESYNC_PULSE_HIGH_PERCENT;
2055 	} else {
2056 		esync->freq = 0;
2057 		esync->pulse = 0;
2058 	}
2059 	mutex_unlock(&pf->dplls.lock);
2060 
2061 	return 0;
2062 }
2063 
2064 /**
2065  * ice_dpll_input_esync_set - callback for setting embedded sync
2066  * @pin: pointer to a pin
2067  * @pin_priv: private data pointer passed on pin registration
2068  * @dpll: registered dpll pointer
2069  * @dpll_priv: private data pointer passed on dpll registration
2070  * @freq: requested embedded sync frequency
2071  * @extack: error reporting
2072  *
2073  * Dpll subsystem callback. Handler for setting embedded sync frequency value
2074  * on input pin.
2075  *
2076  * Context: Acquires pf->dplls.lock
2077  * Return:
2078  * * 0 - success
2079  * * negative - error
2080  */
2081 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)2082 ice_dpll_input_esync_set(const struct dpll_pin *pin, void *pin_priv,
2083 			 const struct dpll_device *dpll, void *dpll_priv,
2084 			 u64 freq, struct netlink_ext_ack *extack)
2085 {
2086 	struct ice_dpll_pin *p = pin_priv;
2087 	struct ice_dpll *d = dpll_priv;
2088 	struct ice_pf *pf = d->pf;
2089 	u8 flags_en = 0;
2090 	int ret;
2091 
2092 	if (ice_dpll_is_reset(pf, extack))
2093 		return -EBUSY;
2094 	mutex_lock(&pf->dplls.lock);
2095 	if (p->flags[0] & ICE_AQC_GET_CGU_IN_CFG_FLG2_INPUT_EN)
2096 		flags_en = ICE_AQC_SET_CGU_IN_CFG_FLG2_INPUT_EN;
2097 	if (freq == DPLL_PIN_FREQUENCY_1_HZ) {
2098 		if (p->flags[0] & ICE_AQC_GET_CGU_IN_CFG_FLG2_ESYNC_EN) {
2099 			ret = 0;
2100 		} else {
2101 			flags_en |= ICE_AQC_SET_CGU_IN_CFG_FLG2_ESYNC_EN;
2102 			ret = ice_aq_set_input_pin_cfg(&pf->hw, p->idx, 0,
2103 						       flags_en, 0, 0);
2104 		}
2105 	} else {
2106 		if (!(p->flags[0] & ICE_AQC_GET_CGU_IN_CFG_FLG2_ESYNC_EN)) {
2107 			ret = 0;
2108 		} else {
2109 			flags_en &= ~ICE_AQC_SET_CGU_IN_CFG_FLG2_ESYNC_EN;
2110 			ret = ice_aq_set_input_pin_cfg(&pf->hw, p->idx, 0,
2111 						       flags_en, 0, 0);
2112 		}
2113 	}
2114 	mutex_unlock(&pf->dplls.lock);
2115 
2116 	return ret;
2117 }
2118 
2119 /**
2120  * ice_dpll_input_esync_get - callback for getting embedded sync config
2121  * @pin: pointer to a pin
2122  * @pin_priv: private data pointer passed on pin registration
2123  * @dpll: registered dpll pointer
2124  * @dpll_priv: private data pointer passed on dpll registration
2125  * @esync: on success holds embedded sync pin properties
2126  * @extack: error reporting
2127  *
2128  * Dpll subsystem callback. Handler for getting embedded sync frequency value
2129  * and capabilities on input pin.
2130  *
2131  * Context: Acquires pf->dplls.lock
2132  * Return:
2133  * * 0 - success
2134  * * negative - error
2135  */
2136 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)2137 ice_dpll_input_esync_get(const struct dpll_pin *pin, void *pin_priv,
2138 			 const struct dpll_device *dpll, void *dpll_priv,
2139 			 struct dpll_pin_esync *esync,
2140 			 struct netlink_ext_ack *extack)
2141 {
2142 	struct ice_dpll_pin *p = pin_priv;
2143 	struct ice_dpll *d = dpll_priv;
2144 	struct ice_pf *pf = d->pf;
2145 
2146 	if (ice_dpll_is_reset(pf, extack))
2147 		return -EBUSY;
2148 	mutex_lock(&pf->dplls.lock);
2149 	if (!(p->status & ICE_AQC_GET_CGU_IN_CFG_STATUS_ESYNC_CAP) ||
2150 	    p->freq != DPLL_PIN_FREQUENCY_10_MHZ) {
2151 		mutex_unlock(&pf->dplls.lock);
2152 		return -EOPNOTSUPP;
2153 	}
2154 	esync->range = ice_esync_range;
2155 	esync->range_num = ARRAY_SIZE(ice_esync_range);
2156 	if (p->flags[0] & ICE_AQC_GET_CGU_IN_CFG_FLG2_ESYNC_EN) {
2157 		esync->freq = DPLL_PIN_FREQUENCY_1_HZ;
2158 		esync->pulse = ICE_DPLL_PIN_ESYNC_PULSE_HIGH_PERCENT;
2159 	} else {
2160 		esync->freq = 0;
2161 		esync->pulse = 0;
2162 	}
2163 	mutex_unlock(&pf->dplls.lock);
2164 
2165 	return 0;
2166 }
2167 
2168 /**
2169  * ice_dpll_sw_esync_set - callback for setting embedded sync on SW pin
2170  * @pin: pointer to a pin
2171  * @pin_priv: private data pointer passed on pin registration
2172  * @dpll: registered dpll pointer
2173  * @dpll_priv: private data pointer passed on dpll registration
2174  * @freq: requested embedded sync frequency
2175  * @extack: error reporting
2176  *
2177  * Dpll subsystem callback. Handler for setting embedded sync frequency value
2178  * on SW pin.
2179  *
2180  * Context: Calls a function which acquires and releases pf->dplls.lock
2181  * Return:
2182  * * 0 - success
2183  * * negative - error
2184  */
2185 static int
ice_dpll_sw_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)2186 ice_dpll_sw_esync_set(const struct dpll_pin *pin, void *pin_priv,
2187 		      const struct dpll_device *dpll, void *dpll_priv,
2188 		      u64 freq, struct netlink_ext_ack *extack)
2189 {
2190 	struct ice_dpll_pin *p = pin_priv;
2191 
2192 	if (!p->active) {
2193 		NL_SET_ERR_MSG(extack, "pin is not active");
2194 		return -EINVAL;
2195 	}
2196 	if (p->direction == DPLL_PIN_DIRECTION_INPUT)
2197 		return ice_dpll_input_esync_set(p->input->pin, p->input, dpll,
2198 						dpll_priv, freq, extack);
2199 	else
2200 		return ice_dpll_output_esync_set(p->output->pin, p->output,
2201 						 dpll, dpll_priv, freq, extack);
2202 }
2203 
2204 /**
2205  * ice_dpll_sw_esync_get - callback for getting embedded sync on SW pin
2206  * @pin: pointer to a pin
2207  * @pin_priv: private data pointer passed on pin registration
2208  * @dpll: registered dpll pointer
2209  * @dpll_priv: private data pointer passed on dpll registration
2210  * @esync: on success holds embedded sync frequency and properties
2211  * @extack: error reporting
2212  *
2213  * Dpll subsystem callback. Handler for getting embedded sync frequency value
2214  * of SW pin.
2215  *
2216  * Context: Calls a function which acquires and releases pf->dplls.lock
2217  * Return:
2218  * * 0 - success
2219  * * negative - error
2220  */
2221 static int
ice_dpll_sw_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)2222 ice_dpll_sw_esync_get(const struct dpll_pin *pin, void *pin_priv,
2223 		      const struct dpll_device *dpll, void *dpll_priv,
2224 		      struct dpll_pin_esync *esync,
2225 		      struct netlink_ext_ack *extack)
2226 {
2227 	struct ice_dpll_pin *p = pin_priv;
2228 
2229 	if (p->direction == DPLL_PIN_DIRECTION_INPUT)
2230 		return ice_dpll_input_esync_get(p->input->pin, p->input, dpll,
2231 						dpll_priv, esync, extack);
2232 	else
2233 		return ice_dpll_output_esync_get(p->output->pin, p->output,
2234 						 dpll, dpll_priv, esync,
2235 						 extack);
2236 }
2237 
2238 /*
2239  * ice_dpll_input_ref_sync_set - callback for setting reference sync feature
2240  * @pin: pointer to a pin
2241  * @pin_priv: private data pointer passed on pin registration
2242  * @ref_pin: pin pointer for reference sync pair
2243  * @ref_pin_priv: private data pointer of ref_pin
2244  * @state: requested state for reference sync for pin pair
2245  * @extack: error reporting
2246  *
2247  * Dpll subsystem callback. Handler for setting reference sync frequency
2248  * feature for input pin.
2249  *
2250  * Context: Acquires and releases pf->dplls.lock
2251  * Return:
2252  * * 0 - success
2253  * * negative - error
2254  */
2255 static int
ice_dpll_input_ref_sync_set(const struct dpll_pin * pin,void * pin_priv,const struct dpll_pin * ref_pin,void * ref_pin_priv,const enum dpll_pin_state state,struct netlink_ext_ack * extack)2256 ice_dpll_input_ref_sync_set(const struct dpll_pin *pin, void *pin_priv,
2257 			    const struct dpll_pin *ref_pin, void *ref_pin_priv,
2258 			    const enum dpll_pin_state state,
2259 			    struct netlink_ext_ack *extack)
2260 {
2261 	struct ice_dpll_pin *p = pin_priv;
2262 	struct ice_pf *pf = p->pf;
2263 	u8 flags_en = 0;
2264 	int ret;
2265 
2266 	if (ice_dpll_is_reset(pf, extack))
2267 		return -EBUSY;
2268 	mutex_lock(&pf->dplls.lock);
2269 
2270 	if (p->flags[0] & ICE_AQC_GET_CGU_IN_CFG_FLG2_INPUT_EN)
2271 		flags_en = ICE_AQC_SET_CGU_IN_CFG_FLG2_INPUT_EN;
2272 	if (state == DPLL_PIN_STATE_CONNECTED)
2273 		flags_en |= ICE_AQC_CGU_IN_CFG_FLG2_REFSYNC_EN;
2274 	ret = ice_aq_set_input_pin_cfg(&pf->hw, p->idx, 0, flags_en, 0, 0);
2275 	if (!ret)
2276 		ret = ice_dpll_pin_state_update(pf, p, ICE_DPLL_PIN_TYPE_INPUT,
2277 						extack);
2278 	mutex_unlock(&pf->dplls.lock);
2279 
2280 	return ret;
2281 }
2282 
2283 /**
2284  * ice_dpll_input_ref_sync_get - callback for getting reference sync config
2285  * @pin: pointer to a pin
2286  * @pin_priv: private data pointer passed on pin registration
2287  * @ref_pin: pin pointer for reference sync pair
2288  * @ref_pin_priv: private data pointer of ref_pin
2289  * @state: on success holds reference sync state for pin pair
2290  * @extack: error reporting
2291  *
2292  * Dpll subsystem callback. Handler for setting reference sync frequency
2293  * feature for input pin.
2294  *
2295  * Context: Acquires and releases pf->dplls.lock
2296  * Return:
2297  * * 0 - success
2298  * * negative - error
2299  */
2300 static int
ice_dpll_input_ref_sync_get(const struct dpll_pin * pin,void * pin_priv,const struct dpll_pin * ref_pin,void * ref_pin_priv,enum dpll_pin_state * state,struct netlink_ext_ack * extack)2301 ice_dpll_input_ref_sync_get(const struct dpll_pin *pin, void *pin_priv,
2302 			    const struct dpll_pin *ref_pin, void *ref_pin_priv,
2303 			    enum dpll_pin_state *state,
2304 			    struct netlink_ext_ack *extack)
2305 {
2306 	struct ice_dpll_pin *p = pin_priv;
2307 	struct ice_pf *pf = p->pf;
2308 
2309 	if (ice_dpll_is_reset(pf, extack))
2310 		return -EBUSY;
2311 	mutex_lock(&pf->dplls.lock);
2312 	if (p->flags[0] & ICE_AQC_CGU_IN_CFG_FLG2_REFSYNC_EN)
2313 		*state = DPLL_PIN_STATE_CONNECTED;
2314 	else
2315 		*state = DPLL_PIN_STATE_DISCONNECTED;
2316 	mutex_unlock(&pf->dplls.lock);
2317 
2318 	return 0;
2319 }
2320 
2321 /*
2322  * ice_dpll_sw_input_ref_sync_set - callback for setting reference sync feature
2323  * @pin: pointer to a pin
2324  * @pin_priv: private data pointer passed on pin registration
2325  * @ref_pin: pin pointer for reference sync pair
2326  * @ref_pin_priv: private data pointer of ref_pin
2327  * @state: requested state for reference sync for pin pair
2328  * @extack: error reporting
2329  *
2330  * Dpll subsystem callback. Handler for setting reference sync
2331  * feature for input pins.
2332  *
2333  * Context: Calls a function which acquires and releases pf->dplls.lock
2334  * Return:
2335  * * 0 - success
2336  * * negative - error
2337  */
2338 static int
ice_dpll_sw_input_ref_sync_set(const struct dpll_pin * pin,void * pin_priv,const struct dpll_pin * ref_pin,void * ref_pin_priv,const enum dpll_pin_state state,struct netlink_ext_ack * extack)2339 ice_dpll_sw_input_ref_sync_set(const struct dpll_pin *pin, void *pin_priv,
2340 			       const struct dpll_pin *ref_pin,
2341 			       void *ref_pin_priv,
2342 			       const enum dpll_pin_state state,
2343 			       struct netlink_ext_ack *extack)
2344 {
2345 	struct ice_dpll_pin *p = pin_priv;
2346 
2347 	return ice_dpll_input_ref_sync_set(pin, p->input, ref_pin, ref_pin_priv,
2348 					   state, extack);
2349 }
2350 
2351 /**
2352  * ice_dpll_sw_input_ref_sync_get - callback for getting reference sync config
2353  * @pin: pointer to a pin
2354  * @pin_priv: private data pointer passed on pin registration
2355  * @ref_pin: pin pointer for reference sync pair
2356  * @ref_pin_priv: private data pointer of ref_pin
2357  * @state: on success holds reference sync state for pin pair
2358  * @extack: error reporting
2359  *
2360  * Dpll subsystem callback. Handler for setting reference sync feature for
2361  * input pins.
2362  *
2363  * Context: Calls a function which acquires and releases pf->dplls.lock
2364  * Return:
2365  * * 0 - success
2366  * * negative - error
2367  */
2368 static int
ice_dpll_sw_input_ref_sync_get(const struct dpll_pin * pin,void * pin_priv,const struct dpll_pin * ref_pin,void * ref_pin_priv,enum dpll_pin_state * state,struct netlink_ext_ack * extack)2369 ice_dpll_sw_input_ref_sync_get(const struct dpll_pin *pin, void *pin_priv,
2370 			       const struct dpll_pin *ref_pin,
2371 			       void *ref_pin_priv,
2372 			       enum dpll_pin_state *state,
2373 			       struct netlink_ext_ack *extack)
2374 {
2375 	struct ice_dpll_pin *p = pin_priv;
2376 
2377 	return ice_dpll_input_ref_sync_get(pin, p->input, ref_pin, ref_pin_priv,
2378 					   state, extack);
2379 }
2380 
2381 static int
ice_dpll_pin_get_parent_num(struct ice_dpll_pin * pin,const struct dpll_pin * parent)2382 ice_dpll_pin_get_parent_num(struct ice_dpll_pin *pin,
2383 			    const struct dpll_pin *parent)
2384 {
2385 	int i;
2386 
2387 	for (i = 0; i < pin->num_parents; i++)
2388 		if (pin->pf->dplls.inputs[pin->parent_idx[i]].pin == parent)
2389 			return i;
2390 
2391 	return -ENOENT;
2392 }
2393 
2394 static int
ice_dpll_pin_get_parent_idx(struct ice_dpll_pin * pin,const struct dpll_pin * parent)2395 ice_dpll_pin_get_parent_idx(struct ice_dpll_pin *pin,
2396 			    const struct dpll_pin *parent)
2397 {
2398 	int num = ice_dpll_pin_get_parent_num(pin, parent);
2399 
2400 	return num < 0 ? num : pin->parent_idx[num];
2401 }
2402 
2403 /**
2404  * ice_dpll_rclk_state_on_pin_set - set a state on rclk pin
2405  * @pin: pointer to a pin
2406  * @pin_priv: private data pointer passed on pin registration
2407  * @parent_pin: pin parent pointer
2408  * @parent_pin_priv: parent private data pointer passed on pin registration
2409  * @state: state to be set on pin
2410  * @extack: error reporting
2411  *
2412  * Dpll subsystem callback, set a state of a rclk pin on a parent pin
2413  *
2414  * Context: Acquires pf->dplls.lock
2415  * Return:
2416  * * 0 - success
2417  * * negative - failure
2418  */
2419 static int
ice_dpll_rclk_state_on_pin_set(const struct dpll_pin * pin,void * pin_priv,const struct dpll_pin * parent_pin,void * parent_pin_priv,enum dpll_pin_state state,struct netlink_ext_ack * extack)2420 ice_dpll_rclk_state_on_pin_set(const struct dpll_pin *pin, void *pin_priv,
2421 			       const struct dpll_pin *parent_pin,
2422 			       void *parent_pin_priv,
2423 			       enum dpll_pin_state state,
2424 			       struct netlink_ext_ack *extack)
2425 {
2426 	bool enable = state == DPLL_PIN_STATE_CONNECTED;
2427 	struct ice_dpll_pin *p = pin_priv;
2428 	struct ice_pf *pf = p->pf;
2429 	struct ice_hw *hw;
2430 	int ret = -EINVAL;
2431 	int hw_idx;
2432 
2433 	hw = &pf->hw;
2434 
2435 	if (ice_dpll_is_reset(pf, extack))
2436 		return -EBUSY;
2437 
2438 	mutex_lock(&pf->dplls.lock);
2439 	hw_idx = ice_dpll_pin_get_parent_idx(p, parent_pin);
2440 	if (hw_idx < 0)
2441 		goto unlock;
2442 	hw_idx -= pf->dplls.base_rclk_idx;
2443 
2444 	if ((enable && p->state[hw_idx] == DPLL_PIN_STATE_CONNECTED) ||
2445 	    (!enable && p->state[hw_idx] == DPLL_PIN_STATE_DISCONNECTED)) {
2446 		NL_SET_ERR_MSG_FMT(extack,
2447 				   "pin:%u state:%u on parent:%u already set",
2448 				   p->idx, state,
2449 				   ice_dpll_pin_get_parent_num(p, parent_pin));
2450 		goto unlock;
2451 	}
2452 
2453 	ret = hw->mac_type == ICE_MAC_GENERIC_3K_E825 ?
2454 		ice_dpll_synce_update_e825c(hw, enable,
2455 					    pf->ptp.port.port_num,
2456 					    (enum ice_synce_clk)hw_idx) :
2457 		ice_aq_set_phy_rec_clk_out(hw, hw_idx, enable, &p->freq);
2458 	if (ret)
2459 		NL_SET_ERR_MSG_FMT(extack,
2460 				   "err:%d %s failed to set pin state:%u for pin:%u on parent:%u",
2461 				   ret,
2462 				   libie_aq_str(hw->adminq.sq_last_status),
2463 				   state, p->idx,
2464 				   ice_dpll_pin_get_parent_num(p, parent_pin));
2465 unlock:
2466 	mutex_unlock(&pf->dplls.lock);
2467 
2468 	return ret;
2469 }
2470 
2471 /**
2472  * ice_dpll_rclk_state_on_pin_get - get a state of rclk pin
2473  * @pin: pointer to a pin
2474  * @pin_priv: private data pointer passed on pin registration
2475  * @parent_pin: pin parent pointer
2476  * @parent_pin_priv: pin parent priv data pointer passed on pin registration
2477  * @state: on success holds pin state on parent pin
2478  * @extack: error reporting
2479  *
2480  * dpll subsystem callback, get a state of a recovered clock pin.
2481  *
2482  * Context: Acquires pf->dplls.lock
2483  * Return:
2484  * * 0 - success
2485  * * negative - failure
2486  */
2487 static int
ice_dpll_rclk_state_on_pin_get(const struct dpll_pin * pin,void * pin_priv,const struct dpll_pin * parent_pin,void * parent_pin_priv,enum dpll_pin_state * state,struct netlink_ext_ack * extack)2488 ice_dpll_rclk_state_on_pin_get(const struct dpll_pin *pin, void *pin_priv,
2489 			       const struct dpll_pin *parent_pin,
2490 			       void *parent_pin_priv,
2491 			       enum dpll_pin_state *state,
2492 			       struct netlink_ext_ack *extack)
2493 {
2494 	struct ice_dpll_pin *p = pin_priv;
2495 	struct ice_pf *pf = p->pf;
2496 	int ret = -EINVAL;
2497 	int hw_idx;
2498 
2499 	if (ice_dpll_is_reset(pf, extack))
2500 		return -EBUSY;
2501 
2502 	mutex_lock(&pf->dplls.lock);
2503 	hw_idx = ice_dpll_pin_get_parent_idx(p, parent_pin);
2504 	if (hw_idx < 0)
2505 		goto unlock;
2506 
2507 	ret = ice_dpll_pin_state_update(pf, p, ICE_DPLL_PIN_TYPE_RCLK_INPUT,
2508 					extack);
2509 	if (ret)
2510 		goto unlock;
2511 
2512 	*state = p->state[hw_idx];
2513 	ret = 0;
2514 unlock:
2515 	mutex_unlock(&pf->dplls.lock);
2516 
2517 	return ret;
2518 }
2519 
2520 static const struct dpll_pin_ops ice_dpll_rclk_ops = {
2521 	.state_on_pin_set = ice_dpll_rclk_state_on_pin_set,
2522 	.state_on_pin_get = ice_dpll_rclk_state_on_pin_get,
2523 	.direction_get = ice_dpll_input_direction,
2524 };
2525 
2526 static const struct dpll_pin_ops ice_dpll_pin_sma_ops = {
2527 	.state_on_dpll_set = ice_dpll_sma_pin_state_set,
2528 	.state_on_dpll_get = ice_dpll_sw_pin_state_get,
2529 	.direction_get = ice_dpll_pin_sw_direction_get,
2530 	.direction_set = ice_dpll_pin_sma_direction_set,
2531 	.prio_get = ice_dpll_sw_input_prio_get,
2532 	.prio_set = ice_dpll_sw_input_prio_set,
2533 	.frequency_get = ice_dpll_sw_pin_frequency_get,
2534 	.frequency_set = ice_dpll_sw_pin_frequency_set,
2535 	.phase_adjust_get = ice_dpll_sw_phase_adjust_get,
2536 	.phase_adjust_set = ice_dpll_sw_phase_adjust_set,
2537 	.phase_offset_get = ice_dpll_phase_offset_get,
2538 	.esync_set = ice_dpll_sw_esync_set,
2539 	.esync_get = ice_dpll_sw_esync_get,
2540 	.ref_sync_set = ice_dpll_sw_input_ref_sync_set,
2541 	.ref_sync_get = ice_dpll_sw_input_ref_sync_get,
2542 };
2543 
2544 static const struct dpll_pin_ops ice_dpll_pin_ufl_ops = {
2545 	.state_on_dpll_set = ice_dpll_ufl_pin_state_set,
2546 	.state_on_dpll_get = ice_dpll_sw_pin_state_get,
2547 	.direction_get = ice_dpll_pin_sw_direction_get,
2548 	.frequency_get = ice_dpll_sw_pin_frequency_get,
2549 	.frequency_set = ice_dpll_sw_pin_frequency_set,
2550 	.esync_set = ice_dpll_sw_esync_set,
2551 	.esync_get = ice_dpll_sw_esync_get,
2552 	.phase_adjust_get = ice_dpll_sw_phase_adjust_get,
2553 	.phase_adjust_set = ice_dpll_sw_phase_adjust_set,
2554 	.phase_offset_get = ice_dpll_phase_offset_get,
2555 };
2556 
2557 static const struct dpll_pin_ops ice_dpll_input_ops = {
2558 	.frequency_get = ice_dpll_input_frequency_get,
2559 	.frequency_set = ice_dpll_input_frequency_set,
2560 	.state_on_dpll_get = ice_dpll_input_state_get,
2561 	.state_on_dpll_set = ice_dpll_input_state_set,
2562 	.prio_get = ice_dpll_input_prio_get,
2563 	.prio_set = ice_dpll_input_prio_set,
2564 	.direction_get = ice_dpll_input_direction,
2565 	.phase_adjust_get = ice_dpll_pin_phase_adjust_get,
2566 	.phase_adjust_set = ice_dpll_input_phase_adjust_set,
2567 	.phase_offset_get = ice_dpll_phase_offset_get,
2568 	.esync_set = ice_dpll_input_esync_set,
2569 	.esync_get = ice_dpll_input_esync_get,
2570 	.ref_sync_set = ice_dpll_input_ref_sync_set,
2571 	.ref_sync_get = ice_dpll_input_ref_sync_get,
2572 };
2573 
2574 static const struct dpll_pin_ops ice_dpll_output_ops = {
2575 	.frequency_get = ice_dpll_output_frequency_get,
2576 	.frequency_set = ice_dpll_output_frequency_set,
2577 	.state_on_dpll_get = ice_dpll_output_state_get,
2578 	.state_on_dpll_set = ice_dpll_output_state_set,
2579 	.direction_get = ice_dpll_output_direction,
2580 	.phase_adjust_get = ice_dpll_pin_phase_adjust_get,
2581 	.phase_adjust_set = ice_dpll_output_phase_adjust_set,
2582 	.esync_set = ice_dpll_output_esync_set,
2583 	.esync_get = ice_dpll_output_esync_get,
2584 };
2585 
2586 static const struct dpll_device_ops ice_dpll_ops = {
2587 	.lock_status_get = ice_dpll_lock_status_get,
2588 	.mode_get = ice_dpll_mode_get,
2589 };
2590 
2591 static const struct dpll_device_ops ice_dpll_pom_ops = {
2592 	.lock_status_get = ice_dpll_lock_status_get,
2593 	.mode_get = ice_dpll_mode_get,
2594 	.phase_offset_monitor_set = ice_dpll_phase_offset_monitor_set,
2595 	.phase_offset_monitor_get = ice_dpll_phase_offset_monitor_get,
2596 };
2597 
2598 /**
2599  * ice_generate_clock_id - generates unique clock_id for registering dpll.
2600  * @pf: board private structure
2601  *
2602  * Generates unique (per board) clock_id for allocation and search of dpll
2603  * devices in Linux dpll subsystem.
2604  *
2605  * Return: generated clock id for the board
2606  */
ice_generate_clock_id(struct ice_pf * pf)2607 static u64 ice_generate_clock_id(struct ice_pf *pf)
2608 {
2609 	return pci_get_dsn(pf->pdev);
2610 }
2611 
2612 /**
2613  * ice_dpll_notify_changes - notify dpll subsystem about changes
2614  * @d: pointer do dpll
2615  *
2616  * Once change detected appropriate event is submitted to the dpll subsystem.
2617  */
ice_dpll_notify_changes(struct ice_dpll * d)2618 static void ice_dpll_notify_changes(struct ice_dpll *d)
2619 {
2620 	bool pin_notified = false;
2621 
2622 	if (d->prev_dpll_state != d->dpll_state) {
2623 		d->prev_dpll_state = d->dpll_state;
2624 		dpll_device_change_ntf(d->dpll);
2625 	}
2626 	if (d->prev_input != d->active_input) {
2627 		if (d->prev_input)
2628 			dpll_pin_change_ntf(d->prev_input);
2629 		d->prev_input = d->active_input;
2630 		if (d->active_input) {
2631 			dpll_pin_change_ntf(d->active_input);
2632 			pin_notified = true;
2633 		}
2634 	}
2635 	if (d->prev_phase_offset != d->phase_offset) {
2636 		d->prev_phase_offset = d->phase_offset;
2637 		if (!pin_notified && d->active_input)
2638 			dpll_pin_change_ntf(d->active_input);
2639 	}
2640 }
2641 
2642 /**
2643  * ice_dpll_is_pps_phase_monitor - check if dpll capable of phase offset monitor
2644  * @pf: pf private structure
2645  *
2646  * Check if firmware is capable of supporting admin command to provide
2647  * phase offset monitoring on all the input pins on PPS dpll.
2648  *
2649  * Returns:
2650  * * true - PPS dpll phase offset monitoring is supported
2651  * * false - PPS dpll phase offset monitoring is not supported
2652  */
ice_dpll_is_pps_phase_monitor(struct ice_pf * pf)2653 static bool ice_dpll_is_pps_phase_monitor(struct ice_pf *pf)
2654 {
2655 	struct ice_cgu_input_measure meas[ICE_DPLL_INPUT_REF_NUM];
2656 	int ret = ice_aq_get_cgu_input_pin_measure(&pf->hw, DPLL_TYPE_PPS, meas,
2657 						   ARRAY_SIZE(meas));
2658 
2659 	if (ret && pf->hw.adminq.sq_last_status == LIBIE_AQ_RC_ESRCH)
2660 		return false;
2661 
2662 	return true;
2663 }
2664 
2665 /**
2666  * ice_dpll_pins_notify_mask - notify dpll subsystem about bulk pin changes
2667  * @pins: array of ice_dpll_pin pointers registered within dpll subsystem
2668  * @pin_num: number of pins
2669  * @phase_offset_ntf_mask: bitmask of pin indexes to notify
2670  *
2671  * Iterate over array of pins and call dpll subsystem pin notify if
2672  * corresponding pin index within bitmask is set.
2673  *
2674  * Context: Must be called while pf->dplls.lock is released.
2675  */
ice_dpll_pins_notify_mask(struct ice_dpll_pin * pins,u8 pin_num,u32 phase_offset_ntf_mask)2676 static void ice_dpll_pins_notify_mask(struct ice_dpll_pin *pins,
2677 				      u8 pin_num,
2678 				      u32 phase_offset_ntf_mask)
2679 {
2680 	int i = 0;
2681 
2682 	for (i = 0; i < pin_num; i++)
2683 		if (phase_offset_ntf_mask & (1 << i))
2684 			dpll_pin_change_ntf(pins[i].pin);
2685 }
2686 
2687 /**
2688  * ice_dpll_pps_update_phase_offsets - update phase offset measurements
2689  * @pf: pf private structure
2690  * @phase_offset_pins_updated: returns mask of updated input pin indexes
2691  *
2692  * Read phase offset measurements for PPS dpll device and store values in
2693  * input pins array. On success phase_offset_pins_updated - fills bitmask of
2694  * updated input pin indexes, pins shall be notified.
2695  *
2696  * Context: Shall be called with pf->dplls.lock being locked.
2697  * Returns:
2698  * * 0 - success or no data available
2699  * * negative - AQ failure
2700  */
ice_dpll_pps_update_phase_offsets(struct ice_pf * pf,u32 * phase_offset_pins_updated)2701 static int ice_dpll_pps_update_phase_offsets(struct ice_pf *pf,
2702 					     u32 *phase_offset_pins_updated)
2703 {
2704 	struct ice_cgu_input_measure meas[ICE_DPLL_INPUT_REF_NUM];
2705 	struct ice_dpll_pin *p;
2706 	s64 phase_offset, tmp;
2707 	int i, j, ret;
2708 
2709 	*phase_offset_pins_updated = 0;
2710 	ret = ice_aq_get_cgu_input_pin_measure(&pf->hw, DPLL_TYPE_PPS, meas,
2711 					       ARRAY_SIZE(meas));
2712 	if (ret && pf->hw.adminq.sq_last_status == LIBIE_AQ_RC_EAGAIN) {
2713 		return 0;
2714 	} else if (ret) {
2715 		dev_err(ice_pf_to_dev(pf),
2716 			"failed to get input pin measurements dpll=%d, ret=%d %s\n",
2717 			DPLL_TYPE_PPS, ret,
2718 			libie_aq_str(pf->hw.adminq.sq_last_status));
2719 		return ret;
2720 	}
2721 	for (i = 0; i < pf->dplls.num_inputs; i++) {
2722 		p = &pf->dplls.inputs[i];
2723 		phase_offset = 0;
2724 		for (j = 0; j < ICE_CGU_INPUT_PHASE_OFFSET_BYTES; j++) {
2725 			tmp = meas[i].phase_offset[j];
2726 #ifdef __LITTLE_ENDIAN
2727 			phase_offset += tmp << 8 * j;
2728 #else
2729 			phase_offset += tmp << 8 *
2730 				(ICE_CGU_INPUT_PHASE_OFFSET_BYTES - 1 - j);
2731 #endif
2732 		}
2733 		phase_offset = sign_extend64(phase_offset, 47);
2734 		if (p->phase_offset != phase_offset) {
2735 			dev_dbg(ice_pf_to_dev(pf),
2736 				"phase offset changed for pin:%d old:%llx, new:%llx\n",
2737 				p->idx, p->phase_offset, phase_offset);
2738 			p->phase_offset = phase_offset;
2739 			*phase_offset_pins_updated |= (1 << i);
2740 		}
2741 	}
2742 
2743 	return 0;
2744 }
2745 
2746 /**
2747  * ice_dpll_update_state - update dpll state
2748  * @pf: pf private structure
2749  * @d: pointer to queried dpll device
2750  * @init: if function called on initialization of ice dpll
2751  *
2752  * Poll current state of dpll from hw and update ice_dpll struct.
2753  *
2754  * Context: Called by kworker under pf->dplls.lock
2755  * Return:
2756  * * 0 - success
2757  * * negative - AQ failure
2758  */
2759 static int
ice_dpll_update_state(struct ice_pf * pf,struct ice_dpll * d,bool init)2760 ice_dpll_update_state(struct ice_pf *pf, struct ice_dpll *d, bool init)
2761 {
2762 	struct ice_dpll_pin *p = NULL;
2763 	int ret;
2764 
2765 	ret = ice_get_cgu_state(&pf->hw, d->dpll_idx, d->prev_dpll_state,
2766 				&d->input_idx, &d->ref_state, &d->eec_mode,
2767 				&d->phase_offset, &d->dpll_state);
2768 
2769 	dev_dbg(ice_pf_to_dev(pf),
2770 		"update dpll=%d, prev_src_idx:%u, src_idx:%u, state:%d, prev:%d mode:%d\n",
2771 		d->dpll_idx, d->prev_input_idx, d->input_idx,
2772 		d->dpll_state, d->prev_dpll_state, d->mode);
2773 	if (ret) {
2774 		dev_err(ice_pf_to_dev(pf),
2775 			"update dpll=%d state failed, ret=%d %s\n",
2776 			d->dpll_idx, ret,
2777 			libie_aq_str(pf->hw.adminq.sq_last_status));
2778 		return ret;
2779 	}
2780 	if (init) {
2781 		if (d->dpll_state == DPLL_LOCK_STATUS_LOCKED ||
2782 		    d->dpll_state == DPLL_LOCK_STATUS_LOCKED_HO_ACQ)
2783 			d->active_input = pf->dplls.inputs[d->input_idx].pin;
2784 		p = &pf->dplls.inputs[d->input_idx];
2785 		return ice_dpll_pin_state_update(pf, p,
2786 						 ICE_DPLL_PIN_TYPE_INPUT, NULL);
2787 	}
2788 	if (d->dpll_state == DPLL_LOCK_STATUS_HOLDOVER ||
2789 	    d->dpll_state == DPLL_LOCK_STATUS_UNLOCKED) {
2790 		d->active_input = NULL;
2791 		if (d->input_idx != ICE_DPLL_PIN_IDX_INVALID)
2792 			p = &pf->dplls.inputs[d->input_idx];
2793 		d->prev_input_idx = ICE_DPLL_PIN_IDX_INVALID;
2794 		d->input_idx = ICE_DPLL_PIN_IDX_INVALID;
2795 		if (!p)
2796 			return 0;
2797 		ret = ice_dpll_pin_state_update(pf, p,
2798 						ICE_DPLL_PIN_TYPE_INPUT, NULL);
2799 	} else if (d->input_idx != d->prev_input_idx) {
2800 		if (d->prev_input_idx != ICE_DPLL_PIN_IDX_INVALID) {
2801 			p = &pf->dplls.inputs[d->prev_input_idx];
2802 			ice_dpll_pin_state_update(pf, p,
2803 						  ICE_DPLL_PIN_TYPE_INPUT,
2804 						  NULL);
2805 		}
2806 		if (d->input_idx != ICE_DPLL_PIN_IDX_INVALID) {
2807 			p = &pf->dplls.inputs[d->input_idx];
2808 			d->active_input = p->pin;
2809 			ice_dpll_pin_state_update(pf, p,
2810 						  ICE_DPLL_PIN_TYPE_INPUT,
2811 						  NULL);
2812 		}
2813 		d->prev_input_idx = d->input_idx;
2814 	}
2815 
2816 	return ret;
2817 }
2818 
2819 /**
2820  * ice_dpll_periodic_work - DPLLs periodic worker
2821  * @work: pointer to kthread_work structure
2822  *
2823  * DPLLs periodic worker is responsible for polling state of dpll.
2824  * Context: Holds pf->dplls.lock
2825  */
ice_dpll_periodic_work(struct kthread_work * work)2826 static void ice_dpll_periodic_work(struct kthread_work *work)
2827 {
2828 	struct ice_dplls *d = container_of(work, struct ice_dplls, work.work);
2829 	struct ice_pf *pf = container_of(d, struct ice_pf, dplls);
2830 	struct ice_dpll *de = &pf->dplls.eec;
2831 	struct ice_dpll *dp = &pf->dplls.pps;
2832 	u32 phase_offset_ntf = 0;
2833 	int ret = 0;
2834 
2835 	if (ice_is_reset_in_progress(pf->state))
2836 		goto resched;
2837 	mutex_lock(&pf->dplls.lock);
2838 	d->periodic_counter++;
2839 	ret = ice_dpll_update_state(pf, de, false);
2840 	if (!ret)
2841 		ret = ice_dpll_update_state(pf, dp, false);
2842 	if (!ret && dp->phase_offset_monitor_period &&
2843 	    d->periodic_counter % dp->phase_offset_monitor_period == 0)
2844 		ret = ice_dpll_pps_update_phase_offsets(pf, &phase_offset_ntf);
2845 	if (ret) {
2846 		d->cgu_state_acq_err_num++;
2847 		/* stop rescheduling this worker */
2848 		if (d->cgu_state_acq_err_num >
2849 		    ICE_CGU_STATE_ACQ_ERR_THRESHOLD) {
2850 			dev_err(ice_pf_to_dev(pf),
2851 				"EEC/PPS DPLLs periodic work disabled\n");
2852 			mutex_unlock(&pf->dplls.lock);
2853 			return;
2854 		}
2855 	}
2856 	mutex_unlock(&pf->dplls.lock);
2857 	ice_dpll_notify_changes(de);
2858 	ice_dpll_notify_changes(dp);
2859 	if (phase_offset_ntf)
2860 		ice_dpll_pins_notify_mask(d->inputs, d->num_inputs,
2861 					  phase_offset_ntf);
2862 
2863 resched:
2864 	/* Run twice a second or reschedule if update failed */
2865 	kthread_queue_delayed_work(d->kworker, &d->work,
2866 				   ret ? msecs_to_jiffies(10) :
2867 				   msecs_to_jiffies(500));
2868 }
2869 
2870 /**
2871  * ice_dpll_init_ref_sync_inputs - initialize reference sync pin pairs
2872  * @pf: pf private structure
2873  *
2874  * Read DPLL TLV capabilities and initialize reference sync pin pairs in
2875  * dpll subsystem.
2876  *
2877  * Return:
2878  * * 0 - success or nothing to do (no ref-sync tlv are present)
2879  * * negative - AQ failure
2880  */
ice_dpll_init_ref_sync_inputs(struct ice_pf * pf)2881 static int ice_dpll_init_ref_sync_inputs(struct ice_pf *pf)
2882 {
2883 	struct ice_dpll_pin *inputs = pf->dplls.inputs;
2884 	struct ice_hw *hw = &pf->hw;
2885 	u16 addr, len, end, hdr;
2886 	int ret;
2887 
2888 	ret = ice_get_pfa_module_tlv(hw, &hdr, &len, ICE_SR_PFA_DPLL_DEFAULTS);
2889 	if (ret) {
2890 		dev_err(ice_pf_to_dev(pf),
2891 			"Failed to read PFA dpll defaults TLV ret=%d\n", ret);
2892 		return ret;
2893 	}
2894 	end = hdr + len;
2895 
2896 	for (addr = hdr + ICE_DPLL_PFA_HEADER_LEN; addr < end;
2897 	     addr += ICE_DPLL_PFA_ENTRY_LEN) {
2898 		unsigned long bit, ul_mask, offset;
2899 		u16 pin, mask, buf;
2900 		bool valid = false;
2901 
2902 		ret = ice_read_sr_word(hw, addr, &buf);
2903 		if (ret)
2904 			return ret;
2905 
2906 		switch (buf) {
2907 		case ICE_DPLL_PFA_REF_SYNC_TYPE:
2908 		case ICE_DPLL_PFA_REF_SYNC_TYPE2:
2909 		{
2910 			u16 mask_addr = addr + ICE_DPLL_PFA_MASK_OFFSET;
2911 			u16 val_addr = addr + ICE_DPLL_PFA_VALUE_OFFSET;
2912 
2913 			ret = ice_read_sr_word(hw, mask_addr, &mask);
2914 			if (ret)
2915 				return ret;
2916 			ret = ice_read_sr_word(hw, val_addr, &pin);
2917 			if (ret)
2918 				return ret;
2919 			if (buf == ICE_DPLL_PFA_REF_SYNC_TYPE)
2920 				pin >>= ICE_DPLL_PFA_MAILBOX_REF_SYNC_PIN_S;
2921 			valid = true;
2922 			break;
2923 		}
2924 		case ICE_DPLL_PFA_END:
2925 			addr = end;
2926 			break;
2927 		default:
2928 			continue;
2929 		}
2930 		if (!valid)
2931 			continue;
2932 
2933 		ul_mask = mask;
2934 		offset = 0;
2935 		for_each_set_bit(bit, &ul_mask, BITS_PER_TYPE(u16)) {
2936 			int i, j;
2937 
2938 			if (hw->device_id == ICE_DEV_ID_E810C_SFP &&
2939 			    pin > ICE_DPLL_E810C_SFP_NC_START)
2940 				offset = -ICE_DPLL_E810C_SFP_NC_PINS;
2941 			i = pin + offset;
2942 			j = bit + offset;
2943 			if (i < 0 || j < 0)
2944 				return -ERANGE;
2945 			inputs[i].ref_sync = j;
2946 		}
2947 	}
2948 
2949 	return 0;
2950 }
2951 
2952 /**
2953  * ice_dpll_release_pins - release pins resources from dpll subsystem
2954  * @pins: pointer to pins array
2955  * @count: number of pins
2956  *
2957  * Release resources of given pins array in the dpll subsystem.
2958  */
ice_dpll_release_pins(struct ice_dpll_pin * pins,int count)2959 static void ice_dpll_release_pins(struct ice_dpll_pin *pins, int count)
2960 {
2961 	int i;
2962 
2963 	for (i = 0; i < count; i++)
2964 		if (!IS_ERR_OR_NULL(pins[i].pin))
2965 			dpll_pin_put(pins[i].pin, &pins[i].tracker);
2966 }
2967 
2968 /**
2969  * ice_dpll_get_pins - get pins from dpll subsystem
2970  * @pf: board private structure
2971  * @pins: pointer to pins array
2972  * @start_idx: get starts from this pin idx value
2973  * @count: number of pins
2974  * @clock_id: clock_id of dpll device
2975  *
2976  * Get pins - allocate - in dpll subsystem, store them in pin field of given
2977  * pins array.
2978  *
2979  * Return:
2980  * * 0 - success
2981  * * negative - allocation failure reason
2982  */
2983 static int
ice_dpll_get_pins(struct ice_pf * pf,struct ice_dpll_pin * pins,int start_idx,int count,u64 clock_id)2984 ice_dpll_get_pins(struct ice_pf *pf, struct ice_dpll_pin *pins,
2985 		  int start_idx, int count, u64 clock_id)
2986 {
2987 	u32 pin_index;
2988 	int i, ret;
2989 
2990 	for (i = 0; i < count; i++) {
2991 		pin_index = start_idx;
2992 		if (start_idx != DPLL_PIN_IDX_UNSPEC)
2993 			pin_index += i;
2994 		pins[i].pin = dpll_pin_get(clock_id, pin_index, THIS_MODULE,
2995 					   &pins[i].prop, &pins[i].tracker);
2996 		if (IS_ERR(pins[i].pin)) {
2997 			ret = PTR_ERR(pins[i].pin);
2998 			goto release_pins;
2999 		}
3000 	}
3001 
3002 	return 0;
3003 
3004 release_pins:
3005 	while (--i >= 0)
3006 		dpll_pin_put(pins[i].pin, &pins[i].tracker);
3007 	return ret;
3008 }
3009 
3010 /**
3011  * ice_dpll_unregister_pins - unregister pins from a dpll
3012  * @dpll: dpll device pointer
3013  * @pins: pointer to pins array
3014  * @ops: callback ops registered with the pins
3015  * @count: number of pins
3016  *
3017  * Unregister pins of a given array of pins from given dpll device registered in
3018  * dpll subsystem.
3019  */
3020 static void
ice_dpll_unregister_pins(struct dpll_device * dpll,struct ice_dpll_pin * pins,const struct dpll_pin_ops * ops,int count)3021 ice_dpll_unregister_pins(struct dpll_device *dpll, struct ice_dpll_pin *pins,
3022 			 const struct dpll_pin_ops *ops, int count)
3023 {
3024 	int i;
3025 
3026 	for (i = 0; i < count; i++)
3027 		if (!pins[i].hidden)
3028 			dpll_pin_unregister(dpll, pins[i].pin, ops, &pins[i]);
3029 }
3030 
3031 /**
3032  * ice_dpll_pin_ref_sync_register - register reference sync pins
3033  * @pins: pointer to pins array
3034  * @count: number of pins
3035  *
3036  * Register reference sync pins in dpll subsystem.
3037  *
3038  * Return:
3039  * * 0 - success
3040  * * negative - registration failure reason
3041  */
3042 static int
ice_dpll_pin_ref_sync_register(struct ice_dpll_pin * pins,int count)3043 ice_dpll_pin_ref_sync_register(struct ice_dpll_pin *pins, int count)
3044 {
3045 	int ret, i;
3046 
3047 	for (i = 0; i < count; i++) {
3048 		if (!pins[i].hidden && pins[i].ref_sync) {
3049 			int j = pins[i].ref_sync;
3050 
3051 			ret = dpll_pin_ref_sync_pair_add(pins[i].pin,
3052 							 pins[j].pin);
3053 			if (ret)
3054 				return ret;
3055 		}
3056 	}
3057 
3058 	return 0;
3059 }
3060 
3061 /**
3062  * ice_dpll_register_pins - register pins with a dpll
3063  * @dpll: dpll pointer to register pins with
3064  * @pins: pointer to pins array
3065  * @ops: callback ops registered with the pins
3066  * @count: number of pins
3067  *
3068  * Register pins of a given array with given dpll in dpll subsystem.
3069  *
3070  * Return:
3071  * * 0 - success
3072  * * negative - registration failure reason
3073  */
3074 static int
ice_dpll_register_pins(struct dpll_device * dpll,struct ice_dpll_pin * pins,const struct dpll_pin_ops * ops,int count)3075 ice_dpll_register_pins(struct dpll_device *dpll, struct ice_dpll_pin *pins,
3076 		       const struct dpll_pin_ops *ops, int count)
3077 {
3078 	int ret, i;
3079 
3080 	for (i = 0; i < count; i++) {
3081 		if (!pins[i].hidden) {
3082 			ret = dpll_pin_register(dpll, pins[i].pin, ops, &pins[i]);
3083 			if (ret)
3084 				goto unregister_pins;
3085 		}
3086 	}
3087 
3088 	return 0;
3089 
3090 unregister_pins:
3091 	while (--i >= 0)
3092 		if (!pins[i].hidden)
3093 			dpll_pin_unregister(dpll, pins[i].pin, ops, &pins[i]);
3094 	return ret;
3095 }
3096 
3097 /**
3098  * ice_dpll_deinit_direct_pins - deinitialize direct pins
3099  * @pf: board private structure
3100  * @cgu: if cgu is present and controlled by this NIC
3101  * @pins: pointer to pins array
3102  * @count: number of pins
3103  * @ops: callback ops registered with the pins
3104  * @first: dpll device pointer
3105  * @second: dpll device pointer
3106  *
3107  * If cgu is owned unregister pins from given dplls.
3108  * Release pins resources to the dpll subsystem.
3109  */
3110 static void
ice_dpll_deinit_direct_pins(struct ice_pf * pf,bool cgu,struct ice_dpll_pin * pins,int count,const struct dpll_pin_ops * ops,struct dpll_device * first,struct dpll_device * second)3111 ice_dpll_deinit_direct_pins(struct ice_pf *pf, bool cgu,
3112 			    struct ice_dpll_pin *pins, int count,
3113 			    const struct dpll_pin_ops *ops,
3114 			    struct dpll_device *first,
3115 			    struct dpll_device *second)
3116 {
3117 	if (cgu) {
3118 		ice_dpll_unregister_pins(first, pins, ops, count);
3119 		ice_dpll_unregister_pins(second, pins, ops, count);
3120 	}
3121 	ice_dpll_release_pins(pins, count);
3122 }
3123 
3124 /**
3125  * ice_dpll_init_direct_pins - initialize direct pins
3126  * @pf: board private structure
3127  * @cgu: if cgu is present and controlled by this NIC
3128  * @pins: pointer to pins array
3129  * @start_idx: on which index shall allocation start in dpll subsystem
3130  * @count: number of pins
3131  * @ops: callback ops registered with the pins
3132  * @first: dpll device pointer
3133  * @second: dpll device pointer
3134  *
3135  * Allocate directly connected pins of a given array in dpll subsystem.
3136  * If cgu is owned register allocated pins with given dplls.
3137  *
3138  * Return:
3139  * * 0 - success
3140  * * negative - registration failure reason
3141  */
3142 static int
ice_dpll_init_direct_pins(struct ice_pf * pf,bool cgu,struct ice_dpll_pin * pins,int start_idx,int count,const struct dpll_pin_ops * ops,struct dpll_device * first,struct dpll_device * second)3143 ice_dpll_init_direct_pins(struct ice_pf *pf, bool cgu,
3144 			  struct ice_dpll_pin *pins, int start_idx, int count,
3145 			  const struct dpll_pin_ops *ops,
3146 			  struct dpll_device *first, struct dpll_device *second)
3147 {
3148 	int ret;
3149 
3150 	ret = ice_dpll_get_pins(pf, pins, start_idx, count, pf->dplls.clock_id);
3151 	if (ret)
3152 		return ret;
3153 	if (cgu) {
3154 		ret = ice_dpll_register_pins(first, pins, ops, count);
3155 		if (ret)
3156 			goto release_pins;
3157 		ret = ice_dpll_register_pins(second, pins, ops, count);
3158 		if (ret)
3159 			goto unregister_first;
3160 	}
3161 
3162 	return 0;
3163 
3164 unregister_first:
3165 	ice_dpll_unregister_pins(first, pins, ops, count);
3166 release_pins:
3167 	ice_dpll_release_pins(pins, count);
3168 	return ret;
3169 }
3170 
3171 /**
3172  * ice_dpll_deinit_rclk_pin - release rclk pin resources
3173  * @pf: board private structure
3174  *
3175  * Deregister rclk pin from parent pins and release resources in dpll subsystem.
3176  */
ice_dpll_deinit_rclk_pin(struct ice_pf * pf)3177 static void ice_dpll_deinit_rclk_pin(struct ice_pf *pf)
3178 {
3179 	struct ice_dpll_pin *rclk = &pf->dplls.rclk;
3180 	struct ice_vsi *vsi = ice_get_main_vsi(pf);
3181 	struct ice_dpll_pin *parent;
3182 	int i;
3183 
3184 	for (i = 0; i < rclk->num_parents; i++) {
3185 		parent = &pf->dplls.inputs[rclk->parent_idx[i]];
3186 		if (IS_ERR_OR_NULL(parent->pin))
3187 			continue;
3188 		dpll_pin_on_pin_unregister(parent->pin, rclk->pin,
3189 					   &ice_dpll_rclk_ops, rclk);
3190 	}
3191 	if (WARN_ON_ONCE(!vsi || !vsi->netdev))
3192 		return;
3193 	dpll_netdev_pin_clear(vsi->netdev);
3194 	dpll_pin_put(rclk->pin, &rclk->tracker);
3195 }
3196 
ice_dpll_is_fwnode_pin(struct ice_dpll_pin * pin)3197 static bool ice_dpll_is_fwnode_pin(struct ice_dpll_pin *pin)
3198 {
3199 	return !IS_ERR_OR_NULL(pin->fwnode);
3200 }
3201 
ice_dpll_pin_notify_work(struct work_struct * work)3202 static void ice_dpll_pin_notify_work(struct work_struct *work)
3203 {
3204 	struct ice_dpll_pin_work *w = container_of(work,
3205 						   struct ice_dpll_pin_work,
3206 						   work);
3207 	struct ice_dpll_pin *pin, *parent = w->pin;
3208 	struct ice_pf *pf = parent->pf;
3209 	int ret;
3210 
3211 	wait_for_completion(&pf->dplls.dpll_init);
3212 	if (!test_bit(ICE_FLAG_DPLL, pf->flags))
3213 		goto out; /* DPLL initialization failed */
3214 
3215 	switch (w->action) {
3216 	case DPLL_PIN_CREATED:
3217 		if (!IS_ERR_OR_NULL(parent->pin)) {
3218 			/* We have already our pin registered */
3219 			goto out;
3220 		}
3221 
3222 		/* Grab reference on fwnode pin */
3223 		parent->pin = fwnode_dpll_pin_find(parent->fwnode,
3224 						   &parent->tracker);
3225 		if (IS_ERR_OR_NULL(parent->pin)) {
3226 			dev_err(ice_pf_to_dev(pf),
3227 				"Cannot get fwnode pin reference\n");
3228 			goto out;
3229 		}
3230 
3231 		/* Register rclk pin */
3232 		pin = &pf->dplls.rclk;
3233 		ret = dpll_pin_on_pin_register(parent->pin, pin->pin,
3234 					       &ice_dpll_rclk_ops, pin);
3235 		if (ret) {
3236 			dev_err(ice_pf_to_dev(pf),
3237 				"Failed to register pin: %pe\n", ERR_PTR(ret));
3238 			dpll_pin_put(parent->pin, &parent->tracker);
3239 			parent->pin = NULL;
3240 			goto out;
3241 		}
3242 		break;
3243 	case DPLL_PIN_DELETED:
3244 		if (IS_ERR_OR_NULL(parent->pin)) {
3245 			/* We have already our pin unregistered */
3246 			goto out;
3247 		}
3248 
3249 		/* Unregister rclk pin */
3250 		pin = &pf->dplls.rclk;
3251 		dpll_pin_on_pin_unregister(parent->pin, pin->pin,
3252 					   &ice_dpll_rclk_ops, pin);
3253 
3254 		/* Drop fwnode pin reference */
3255 		dpll_pin_put(parent->pin, &parent->tracker);
3256 		parent->pin = NULL;
3257 		break;
3258 	default:
3259 		break;
3260 	}
3261 out:
3262 	kfree(w);
3263 }
3264 
ice_dpll_pin_notify(struct notifier_block * nb,unsigned long action,void * data)3265 static int ice_dpll_pin_notify(struct notifier_block *nb, unsigned long action,
3266 			       void *data)
3267 {
3268 	struct ice_dpll_pin *pin = container_of(nb, struct ice_dpll_pin, nb);
3269 	struct dpll_pin_notifier_info *info = data;
3270 	struct ice_dpll_pin_work *work;
3271 
3272 	if (action != DPLL_PIN_CREATED && action != DPLL_PIN_DELETED)
3273 		return NOTIFY_DONE;
3274 
3275 	/* Check if the reported pin is this one */
3276 	if (pin->fwnode != info->fwnode)
3277 		return NOTIFY_DONE; /* Not this pin */
3278 
3279 	work = kzalloc_obj(*work);
3280 	if (!work)
3281 		return NOTIFY_DONE;
3282 
3283 	INIT_WORK(&work->work, ice_dpll_pin_notify_work);
3284 	work->action = action;
3285 	work->pin = pin;
3286 
3287 	queue_work(pin->pf->dplls.wq, &work->work);
3288 
3289 	return NOTIFY_OK;
3290 }
3291 
3292 /**
3293  * ice_dpll_init_pin_common - initialize pin
3294  * @pf: board private structure
3295  * @pin: pin to register
3296  * @start_idx: on which index shall allocation start in dpll subsystem
3297  * @ops: callback ops registered with the pins
3298  *
3299  * Allocate resource for given pin in dpll subsystem. Register the pin with
3300  * the parents it has in the info.
3301  *
3302  * Return:
3303  * * 0 - success
3304  * * negative - registration failure reason
3305  */
3306 static int
ice_dpll_init_pin_common(struct ice_pf * pf,struct ice_dpll_pin * pin,int start_idx,const struct dpll_pin_ops * ops)3307 ice_dpll_init_pin_common(struct ice_pf *pf, struct ice_dpll_pin *pin,
3308 			 int start_idx, const struct dpll_pin_ops *ops)
3309 {
3310 	struct ice_dpll_pin *parent;
3311 	int ret, i;
3312 
3313 	ret = ice_dpll_get_pins(pf, pin, start_idx, 1, pf->dplls.clock_id);
3314 	if (ret)
3315 		return ret;
3316 
3317 	for (i = 0; i < pin->num_parents; i++) {
3318 		parent = &pf->dplls.inputs[pin->parent_idx[i]];
3319 		if (IS_ERR_OR_NULL(parent->pin)) {
3320 			if (!ice_dpll_is_fwnode_pin(parent)) {
3321 				ret = -ENODEV;
3322 				goto unregister_pins;
3323 			}
3324 			parent->pin = fwnode_dpll_pin_find(parent->fwnode,
3325 							   &parent->tracker);
3326 			if (IS_ERR_OR_NULL(parent->pin)) {
3327 				dev_info(ice_pf_to_dev(pf),
3328 					 "Mux pin not registered yet\n");
3329 				continue;
3330 			}
3331 		}
3332 		ret = dpll_pin_on_pin_register(parent->pin, pin->pin, ops, pin);
3333 		if (ret)
3334 			goto unregister_pins;
3335 	}
3336 
3337 	return 0;
3338 
3339 unregister_pins:
3340 	while (i) {
3341 		parent = &pf->dplls.inputs[pin->parent_idx[--i]];
3342 		if (IS_ERR_OR_NULL(parent->pin))
3343 			continue;
3344 		dpll_pin_on_pin_unregister(parent->pin, pin->pin, ops, pin);
3345 	}
3346 	ice_dpll_release_pins(pin, 1);
3347 
3348 	return ret;
3349 }
3350 
3351 /**
3352  * ice_dpll_init_rclk_pin - initialize recovered clock pin
3353  * @pf: board private structure
3354  * @start_idx: on which index shall allocation start in dpll subsystem
3355  * @ops: callback ops registered with the pins
3356  *
3357  * Allocate resource for recovered clock pin in dpll subsystem. Register the
3358  * pin with the parents it has in the info.
3359  *
3360  * Return:
3361  * * 0 - success
3362  * * negative - registration failure reason
3363  */
3364 static int
ice_dpll_init_rclk_pin(struct ice_pf * pf,int start_idx,const struct dpll_pin_ops * ops)3365 ice_dpll_init_rclk_pin(struct ice_pf *pf, int start_idx,
3366 		       const struct dpll_pin_ops *ops)
3367 {
3368 	struct ice_vsi *vsi = ice_get_main_vsi(pf);
3369 	int ret;
3370 
3371 	ret = ice_dpll_init_pin_common(pf, &pf->dplls.rclk, start_idx, ops);
3372 	if (ret)
3373 		return ret;
3374 
3375 	dpll_netdev_pin_set(vsi->netdev, pf->dplls.rclk.pin);
3376 
3377 	return 0;
3378 }
3379 
3380 static void
ice_dpll_deinit_fwnode_pin(struct ice_dpll_pin * pin)3381 ice_dpll_deinit_fwnode_pin(struct ice_dpll_pin *pin)
3382 {
3383 	unregister_dpll_notifier(&pin->nb);
3384 	flush_workqueue(pin->pf->dplls.wq);
3385 	if (!IS_ERR_OR_NULL(pin->pin)) {
3386 		dpll_pin_put(pin->pin, &pin->tracker);
3387 		pin->pin = NULL;
3388 	}
3389 	fwnode_handle_put(pin->fwnode);
3390 	pin->fwnode = NULL;
3391 }
3392 
3393 static void
ice_dpll_deinit_fwnode_pins(struct ice_pf * pf,struct ice_dpll_pin * pins,int start_idx)3394 ice_dpll_deinit_fwnode_pins(struct ice_pf *pf, struct ice_dpll_pin *pins,
3395 			    int start_idx)
3396 {
3397 	int i;
3398 
3399 	for (i = 0; i < pf->dplls.rclk.num_parents; i++)
3400 		ice_dpll_deinit_fwnode_pin(&pins[start_idx + i]);
3401 	destroy_workqueue(pf->dplls.wq);
3402 }
3403 
3404 /**
3405  * ice_dpll_deinit_pins - deinitialize direct pins
3406  * @pf: board private structure
3407  * @cgu: if cgu is controlled by this pf
3408  *
3409  * If cgu is owned unregister directly connected pins from the dplls.
3410  * Release resources of directly connected pins from the dpll subsystem.
3411  */
ice_dpll_deinit_pins(struct ice_pf * pf,bool cgu)3412 static void ice_dpll_deinit_pins(struct ice_pf *pf, bool cgu)
3413 {
3414 	struct ice_dpll_pin *outputs = pf->dplls.outputs;
3415 	struct ice_dpll_pin *inputs = pf->dplls.inputs;
3416 	int num_outputs = pf->dplls.num_outputs;
3417 	int num_inputs = pf->dplls.num_inputs;
3418 	struct ice_dplls *d = &pf->dplls;
3419 	struct ice_dpll *de = &d->eec;
3420 	struct ice_dpll *dp = &d->pps;
3421 
3422 	ice_dpll_deinit_rclk_pin(pf);
3423 	if (pf->hw.mac_type == ICE_MAC_GENERIC_3K_E825)
3424 		ice_dpll_deinit_fwnode_pins(pf, pf->dplls.inputs, 0);
3425 	if (cgu) {
3426 		ice_dpll_unregister_pins(dp->dpll, inputs, &ice_dpll_input_ops,
3427 					 num_inputs);
3428 		ice_dpll_unregister_pins(de->dpll, inputs, &ice_dpll_input_ops,
3429 					 num_inputs);
3430 	}
3431 	ice_dpll_release_pins(inputs, num_inputs);
3432 	if (cgu) {
3433 		ice_dpll_unregister_pins(dp->dpll, outputs,
3434 					 &ice_dpll_output_ops, num_outputs);
3435 		ice_dpll_unregister_pins(de->dpll, outputs,
3436 					 &ice_dpll_output_ops, num_outputs);
3437 		ice_dpll_release_pins(outputs, num_outputs);
3438 		if (!pf->dplls.generic) {
3439 			ice_dpll_deinit_direct_pins(pf, cgu, pf->dplls.ufl,
3440 						    ICE_DPLL_PIN_SW_NUM,
3441 						    &ice_dpll_pin_ufl_ops,
3442 						    pf->dplls.pps.dpll,
3443 						    pf->dplls.eec.dpll);
3444 			ice_dpll_deinit_direct_pins(pf, cgu, pf->dplls.sma,
3445 						    ICE_DPLL_PIN_SW_NUM,
3446 						    &ice_dpll_pin_sma_ops,
3447 						    pf->dplls.pps.dpll,
3448 						    pf->dplls.eec.dpll);
3449 		}
3450 	}
3451 }
3452 
3453 static struct fwnode_handle *
ice_dpll_pin_node_get(struct ice_pf * pf,const char * name)3454 ice_dpll_pin_node_get(struct ice_pf *pf, const char *name)
3455 {
3456 	struct fwnode_handle *fwnode = dev_fwnode(ice_pf_to_dev(pf));
3457 	int index;
3458 
3459 	index = fwnode_property_match_string(fwnode, "dpll-pin-names", name);
3460 	if (index < 0)
3461 		return ERR_PTR(-ENOENT);
3462 
3463 	return fwnode_find_reference(fwnode, "dpll-pins", index);
3464 }
3465 
3466 static int
ice_dpll_init_fwnode_pin(struct ice_dpll_pin * pin,const char * name)3467 ice_dpll_init_fwnode_pin(struct ice_dpll_pin *pin, const char *name)
3468 {
3469 	struct ice_pf *pf = pin->pf;
3470 	int ret;
3471 
3472 	pin->fwnode = ice_dpll_pin_node_get(pf, name);
3473 	if (IS_ERR(pin->fwnode)) {
3474 		dev_err(ice_pf_to_dev(pf),
3475 			"Failed to find %s firmware node: %pe\n", name,
3476 			pin->fwnode);
3477 		pin->fwnode = NULL;
3478 		return -ENODEV;
3479 	}
3480 
3481 	dev_dbg(ice_pf_to_dev(pf), "Found fwnode node for %s\n", name);
3482 
3483 	pin->pin = fwnode_dpll_pin_find(pin->fwnode, &pin->tracker);
3484 	if (IS_ERR_OR_NULL(pin->pin)) {
3485 		dev_info(ice_pf_to_dev(pf),
3486 			 "DPLL pin for %pfwp not registered yet\n",
3487 			 pin->fwnode);
3488 		pin->pin = NULL;
3489 	}
3490 
3491 	pin->nb.notifier_call = ice_dpll_pin_notify;
3492 	ret = register_dpll_notifier(&pin->nb);
3493 	if (ret) {
3494 		dev_err(ice_pf_to_dev(pf),
3495 			"Failed to subscribe for DPLL notifications\n");
3496 
3497 		if (!IS_ERR_OR_NULL(pin->pin)) {
3498 			dpll_pin_put(pin->pin, &pin->tracker);
3499 			pin->pin = NULL;
3500 		}
3501 		fwnode_handle_put(pin->fwnode);
3502 		pin->fwnode = NULL;
3503 
3504 		return ret;
3505 	}
3506 
3507 	return ret;
3508 }
3509 
3510 /**
3511  * ice_dpll_init_fwnode_pins - initialize pins from device tree
3512  * @pf: board private structure
3513  * @pins: pointer to pins array
3514  * @start_idx: starting index for pins
3515  * @count: number of pins to initialize
3516  *
3517  * Initialize input pins for E825 RCLK support. The parent pins (rclk0, rclk1)
3518  * are expected to be defined by the system firmware (ACPI). This function
3519  * allocates them in the dpll subsystem and stores their indices for later
3520  * registration with the rclk pin.
3521  *
3522  * Return:
3523  * * 0 - success
3524  * * negative - initialization failure reason
3525  */
3526 static int
ice_dpll_init_fwnode_pins(struct ice_pf * pf,struct ice_dpll_pin * pins,int start_idx)3527 ice_dpll_init_fwnode_pins(struct ice_pf *pf, struct ice_dpll_pin *pins,
3528 			  int start_idx)
3529 {
3530 	char pin_name[8];
3531 	int i, ret;
3532 
3533 	pf->dplls.wq = create_singlethread_workqueue("ice_dpll_wq");
3534 	if (!pf->dplls.wq)
3535 		return -ENOMEM;
3536 
3537 	for (i = 0; i < pf->dplls.rclk.num_parents; i++) {
3538 		pins[start_idx + i].pf = pf;
3539 		snprintf(pin_name, sizeof(pin_name), "rclk%u", i);
3540 		ret = ice_dpll_init_fwnode_pin(&pins[start_idx + i], pin_name);
3541 		if (ret)
3542 			goto error;
3543 	}
3544 
3545 	return 0;
3546 error:
3547 	while (i--)
3548 		ice_dpll_deinit_fwnode_pin(&pins[start_idx + i]);
3549 
3550 	destroy_workqueue(pf->dplls.wq);
3551 
3552 	return ret;
3553 }
3554 
3555 /**
3556  * ice_dpll_init_pins_e825 - init pins and register pins with a dplls
3557  * @pf: board private structure
3558  * @cgu: if cgu is present and controlled by this NIC
3559  *
3560  * Initialize directly connected pf's pins within pf's dplls in a Linux dpll
3561  * subsystem.
3562  *
3563  * Return:
3564  * * 0 - success
3565  * * negative - initialization failure reason
3566  */
ice_dpll_init_pins_e825(struct ice_pf * pf)3567 static int ice_dpll_init_pins_e825(struct ice_pf *pf)
3568 {
3569 	int ret;
3570 
3571 	ret = ice_dpll_init_fwnode_pins(pf, pf->dplls.inputs, 0);
3572 	if (ret)
3573 		return ret;
3574 
3575 	ret = ice_dpll_init_rclk_pin(pf, DPLL_PIN_IDX_UNSPEC,
3576 				     &ice_dpll_rclk_ops);
3577 	if (ret) {
3578 		/* Inform DPLL notifier works that DPLL init was finished
3579 		 * unsuccessfully (ICE_DPLL_FLAG not set).
3580 		 */
3581 		complete_all(&pf->dplls.dpll_init);
3582 		ice_dpll_deinit_fwnode_pins(pf, pf->dplls.inputs, 0);
3583 	}
3584 
3585 	return ret;
3586 }
3587 
3588 /**
3589  * ice_dpll_init_pins - init pins and register pins with a dplls
3590  * @pf: board private structure
3591  * @cgu: if cgu is present and controlled by this NIC
3592  *
3593  * Initialize directly connected pf's pins within pf's dplls in a Linux dpll
3594  * subsystem.
3595  *
3596  * Return:
3597  * * 0 - success
3598  * * negative - initialization failure reason
3599  */
ice_dpll_init_pins(struct ice_pf * pf,bool cgu)3600 static int ice_dpll_init_pins(struct ice_pf *pf, bool cgu)
3601 {
3602 	const struct dpll_pin_ops *output_ops;
3603 	const struct dpll_pin_ops *input_ops;
3604 	int ret, count;
3605 
3606 	input_ops = &ice_dpll_input_ops;
3607 	output_ops = &ice_dpll_output_ops;
3608 
3609 	ret = ice_dpll_init_direct_pins(pf, cgu, pf->dplls.inputs, 0,
3610 					pf->dplls.num_inputs, input_ops,
3611 					pf->dplls.eec.dpll,
3612 					pf->dplls.pps.dpll);
3613 	if (ret)
3614 		return ret;
3615 	count = pf->dplls.num_inputs;
3616 	if (cgu) {
3617 		ret = ice_dpll_init_direct_pins(pf, cgu, pf->dplls.outputs,
3618 						count, pf->dplls.num_outputs,
3619 						output_ops, pf->dplls.eec.dpll,
3620 						pf->dplls.pps.dpll);
3621 		if (ret)
3622 			goto deinit_inputs;
3623 		count += pf->dplls.num_outputs;
3624 		if (!pf->dplls.generic) {
3625 			ret = ice_dpll_init_direct_pins(pf, cgu, pf->dplls.sma,
3626 							count,
3627 							ICE_DPLL_PIN_SW_NUM,
3628 							&ice_dpll_pin_sma_ops,
3629 							pf->dplls.eec.dpll,
3630 							pf->dplls.pps.dpll);
3631 			if (ret)
3632 				goto deinit_outputs;
3633 			count += ICE_DPLL_PIN_SW_NUM;
3634 			ret = ice_dpll_init_direct_pins(pf, cgu, pf->dplls.ufl,
3635 							count,
3636 							ICE_DPLL_PIN_SW_NUM,
3637 							&ice_dpll_pin_ufl_ops,
3638 							pf->dplls.eec.dpll,
3639 							pf->dplls.pps.dpll);
3640 			if (ret)
3641 				goto deinit_sma;
3642 			count += ICE_DPLL_PIN_SW_NUM;
3643 		}
3644 		ret = ice_dpll_pin_ref_sync_register(pf->dplls.inputs,
3645 						     pf->dplls.num_inputs);
3646 		if (ret)
3647 			goto deinit_ufl;
3648 		ret = ice_dpll_pin_ref_sync_register(pf->dplls.sma,
3649 						     ICE_DPLL_PIN_SW_NUM);
3650 		if (ret)
3651 			goto deinit_ufl;
3652 	} else {
3653 		count += pf->dplls.num_outputs + 2 * ICE_DPLL_PIN_SW_NUM;
3654 	}
3655 
3656 	ret = ice_dpll_init_rclk_pin(pf, count + pf->ptp.port.port_num,
3657 				     &ice_dpll_rclk_ops);
3658 	if (ret)
3659 		goto deinit_ufl;
3660 
3661 	return 0;
3662 deinit_ufl:
3663 	ice_dpll_deinit_direct_pins(pf, cgu, pf->dplls.ufl, ICE_DPLL_PIN_SW_NUM,
3664 				    &ice_dpll_pin_ufl_ops, pf->dplls.pps.dpll,
3665 				    pf->dplls.eec.dpll);
3666 deinit_sma:
3667 	ice_dpll_deinit_direct_pins(pf, cgu, pf->dplls.sma, ICE_DPLL_PIN_SW_NUM,
3668 				    &ice_dpll_pin_sma_ops, pf->dplls.pps.dpll,
3669 				    pf->dplls.eec.dpll);
3670 deinit_outputs:
3671 	ice_dpll_deinit_direct_pins(pf, cgu, pf->dplls.outputs,
3672 				    pf->dplls.num_outputs,
3673 				    output_ops, pf->dplls.pps.dpll,
3674 				    pf->dplls.eec.dpll);
3675 deinit_inputs:
3676 	ice_dpll_deinit_direct_pins(pf, cgu, pf->dplls.inputs,
3677 				    pf->dplls.num_inputs,
3678 				    input_ops, pf->dplls.pps.dpll,
3679 				    pf->dplls.eec.dpll);
3680 	return ret;
3681 }
3682 
3683 /**
3684  * ice_dpll_deinit_dpll - deinitialize dpll device
3685  * @pf: board private structure
3686  * @d: pointer to ice_dpll
3687  * @cgu: if cgu is present and controlled by this NIC
3688  *
3689  * If cgu is owned, unregister the DPLL from DPLL subsystem.
3690  * Release resources of DPLL device from DPLL subsystem.
3691  */
3692 static void
ice_dpll_deinit_dpll(struct ice_pf * pf,struct ice_dpll * d,bool cgu)3693 ice_dpll_deinit_dpll(struct ice_pf *pf, struct ice_dpll *d, bool cgu)
3694 {
3695 	if (cgu)
3696 		dpll_device_unregister(d->dpll, d->ops, d);
3697 	dpll_device_put(d->dpll, &d->tracker);
3698 }
3699 
3700 /**
3701  * ice_dpll_init_dpll - initialize dpll device in dpll subsystem
3702  * @pf: board private structure
3703  * @d: dpll to be initialized
3704  * @cgu: if cgu is present and controlled by this NIC
3705  * @type: type of dpll being initialized
3706  *
3707  * Allocate DPLL instance for this board in dpll subsystem, if cgu is controlled
3708  * by this NIC, register DPLL with the callback ops.
3709  *
3710  * Return:
3711  * * 0 - success
3712  * * negative - initialization failure reason
3713  */
3714 static int
ice_dpll_init_dpll(struct ice_pf * pf,struct ice_dpll * d,bool cgu,enum dpll_type type)3715 ice_dpll_init_dpll(struct ice_pf *pf, struct ice_dpll *d, bool cgu,
3716 		   enum dpll_type type)
3717 {
3718 	u64 clock_id = pf->dplls.clock_id;
3719 	int ret;
3720 
3721 	d->dpll = dpll_device_get(clock_id, d->dpll_idx, THIS_MODULE,
3722 				  &d->tracker);
3723 	if (IS_ERR(d->dpll)) {
3724 		ret = PTR_ERR(d->dpll);
3725 		dev_err(ice_pf_to_dev(pf),
3726 			"dpll_device_get failed (%p) err=%d\n", d, ret);
3727 		return ret;
3728 	}
3729 	d->pf = pf;
3730 	if (cgu) {
3731 		const struct dpll_device_ops *ops = &ice_dpll_ops;
3732 
3733 		if (type == DPLL_TYPE_PPS && ice_dpll_is_pps_phase_monitor(pf))
3734 			ops =  &ice_dpll_pom_ops;
3735 		ice_dpll_update_state(pf, d, true);
3736 		ret = dpll_device_register(d->dpll, type, ops, d);
3737 		if (ret) {
3738 			dpll_device_put(d->dpll, &d->tracker);
3739 			d->dpll = NULL;
3740 			return ret;
3741 		}
3742 		d->ops = ops;
3743 	}
3744 
3745 	return 0;
3746 }
3747 
3748 /**
3749  * ice_dpll_deinit_worker - deinitialize dpll kworker
3750  * @pf: board private structure
3751  *
3752  * Stop dpll's kworker, release it's resources.
3753  */
ice_dpll_deinit_worker(struct ice_pf * pf)3754 static void ice_dpll_deinit_worker(struct ice_pf *pf)
3755 {
3756 	struct ice_dplls *d = &pf->dplls;
3757 
3758 	kthread_cancel_delayed_work_sync(&d->work);
3759 	kthread_destroy_worker(d->kworker);
3760 }
3761 
3762 /**
3763  * ice_dpll_init_worker - Initialize DPLLs periodic worker
3764  * @pf: board private structure
3765  *
3766  * Create and start DPLLs periodic worker.
3767  *
3768  * Context: Shall be called after pf->dplls.lock is initialized.
3769  * Return:
3770  * * 0 - success
3771  * * negative - create worker failure
3772  */
ice_dpll_init_worker(struct ice_pf * pf)3773 static int ice_dpll_init_worker(struct ice_pf *pf)
3774 {
3775 	struct ice_dplls *d = &pf->dplls;
3776 	struct kthread_worker *kworker;
3777 
3778 	kthread_init_delayed_work(&d->work, ice_dpll_periodic_work);
3779 	kworker = kthread_run_worker(0, "ice-dplls-%s",
3780 					dev_name(ice_pf_to_dev(pf)));
3781 	if (IS_ERR(kworker))
3782 		return PTR_ERR(kworker);
3783 	d->kworker = kworker;
3784 	d->cgu_state_acq_err_num = 0;
3785 	kthread_queue_delayed_work(d->kworker, &d->work, 0);
3786 
3787 	return 0;
3788 }
3789 
3790 /**
3791  * ice_dpll_phase_range_set - initialize phase adjust range helper
3792  * @range: pointer to phase adjust range struct to be initialized
3793  * @phase_adj: a value to be used as min(-)/max(+) boundary
3794  */
ice_dpll_phase_range_set(struct dpll_pin_phase_adjust_range * range,u32 phase_adj)3795 static void ice_dpll_phase_range_set(struct dpll_pin_phase_adjust_range *range,
3796 				     u32 phase_adj)
3797 {
3798 	range->min = -phase_adj;
3799 	range->max = phase_adj;
3800 }
3801 
3802 /**
3803  * ice_dpll_init_info_pins_generic - initializes generic pins info
3804  * @pf: board private structure
3805  * @input: if input pins initialized
3806  *
3807  * Init information for generic pins, cache them in PF's pins structures.
3808  *
3809  * Return:
3810  * * 0 - success
3811  * * negative - init failure reason
3812  */
ice_dpll_init_info_pins_generic(struct ice_pf * pf,bool input)3813 static int ice_dpll_init_info_pins_generic(struct ice_pf *pf, bool input)
3814 {
3815 	struct ice_dpll *de = &pf->dplls.eec, *dp = &pf->dplls.pps;
3816 	static const char labels[][sizeof("99")] = {
3817 		"0", "1", "2", "3", "4", "5", "6", "7", "8",
3818 		"9", "10", "11", "12", "13", "14", "15" };
3819 	u32 cap = DPLL_PIN_CAPABILITIES_STATE_CAN_CHANGE;
3820 	enum ice_dpll_pin_type pin_type;
3821 	int i, pin_num, ret = -EINVAL;
3822 	struct ice_dpll_pin *pins;
3823 	u32 phase_adj_max;
3824 
3825 	if (input) {
3826 		pin_num = pf->dplls.num_inputs;
3827 		pins = pf->dplls.inputs;
3828 		phase_adj_max = pf->dplls.input_phase_adj_max;
3829 		pin_type = ICE_DPLL_PIN_TYPE_INPUT;
3830 		cap |= DPLL_PIN_CAPABILITIES_PRIORITY_CAN_CHANGE;
3831 	} else {
3832 		pin_num = pf->dplls.num_outputs;
3833 		pins = pf->dplls.outputs;
3834 		phase_adj_max = pf->dplls.output_phase_adj_max;
3835 		pin_type = ICE_DPLL_PIN_TYPE_OUTPUT;
3836 	}
3837 	if (pin_num > ARRAY_SIZE(labels))
3838 		return ret;
3839 
3840 	for (i = 0; i < pin_num; i++) {
3841 		pins[i].idx = i;
3842 		pins[i].prop.board_label = labels[i];
3843 		ice_dpll_phase_range_set(&pins[i].prop.phase_range,
3844 					 phase_adj_max);
3845 		pins[i].prop.capabilities = cap;
3846 		pins[i].pf = pf;
3847 		ret = ice_dpll_pin_state_update(pf, &pins[i], pin_type, NULL);
3848 		if (ret)
3849 			break;
3850 		if (input && pins[i].freq == ICE_DPLL_PIN_GEN_RCLK_FREQ)
3851 			pins[i].prop.type = DPLL_PIN_TYPE_MUX;
3852 		else
3853 			pins[i].prop.type = DPLL_PIN_TYPE_EXT;
3854 		if (!input)
3855 			continue;
3856 		ret = ice_aq_get_cgu_ref_prio(&pf->hw, de->dpll_idx, i,
3857 					      &de->input_prio[i]);
3858 		if (ret)
3859 			break;
3860 		ret = ice_aq_get_cgu_ref_prio(&pf->hw, dp->dpll_idx, i,
3861 					      &dp->input_prio[i]);
3862 		if (ret)
3863 			break;
3864 	}
3865 
3866 	return ret;
3867 }
3868 
3869 /**
3870  * ice_dpll_init_info_direct_pins - initializes direct pins info
3871  * @pf: board private structure
3872  * @pin_type: type of pins being initialized
3873  *
3874  * Init information for directly connected pins, cache them in pf's pins
3875  * structures.
3876  *
3877  * Return:
3878  * * 0 - success
3879  * * negative - init failure reason
3880  */
3881 static int
ice_dpll_init_info_direct_pins(struct ice_pf * pf,enum ice_dpll_pin_type pin_type)3882 ice_dpll_init_info_direct_pins(struct ice_pf *pf,
3883 			       enum ice_dpll_pin_type pin_type)
3884 {
3885 	struct ice_dpll *de = &pf->dplls.eec, *dp = &pf->dplls.pps;
3886 	int num_pins, i, ret = -EINVAL;
3887 	struct ice_hw *hw = &pf->hw;
3888 	struct ice_dpll_pin *pins;
3889 	unsigned long caps;
3890 	u32 phase_adj_max;
3891 	u8 freq_supp_num;
3892 	bool input;
3893 
3894 	switch (pin_type) {
3895 	case ICE_DPLL_PIN_TYPE_INPUT:
3896 		pins = pf->dplls.inputs;
3897 		num_pins = pf->dplls.num_inputs;
3898 		phase_adj_max = pf->dplls.input_phase_adj_max;
3899 		input = true;
3900 		break;
3901 	case ICE_DPLL_PIN_TYPE_OUTPUT:
3902 		pins = pf->dplls.outputs;
3903 		num_pins = pf->dplls.num_outputs;
3904 		phase_adj_max = pf->dplls.output_phase_adj_max;
3905 		input = false;
3906 		break;
3907 	default:
3908 		return -EINVAL;
3909 	}
3910 	if (num_pins != ice_cgu_get_num_pins(hw, input)) {
3911 		pf->dplls.generic = true;
3912 		return ice_dpll_init_info_pins_generic(pf, input);
3913 	}
3914 
3915 	for (i = 0; i < num_pins; i++) {
3916 		caps = 0;
3917 		pins[i].idx = i;
3918 		pins[i].prop.board_label = ice_cgu_get_pin_name(hw, i, input);
3919 		pins[i].prop.type = ice_cgu_get_pin_type(hw, i, input);
3920 		if (input) {
3921 			ret = ice_aq_get_cgu_ref_prio(hw, de->dpll_idx, i,
3922 						      &de->input_prio[i]);
3923 			if (ret)
3924 				return ret;
3925 			ret = ice_aq_get_cgu_ref_prio(hw, dp->dpll_idx, i,
3926 						      &dp->input_prio[i]);
3927 			if (ret)
3928 				return ret;
3929 			caps |= (DPLL_PIN_CAPABILITIES_PRIORITY_CAN_CHANGE |
3930 				 DPLL_PIN_CAPABILITIES_STATE_CAN_CHANGE);
3931 			if (ice_dpll_is_sw_pin(pf, i, true))
3932 				pins[i].hidden = true;
3933 		} else {
3934 			ret = ice_cgu_get_output_pin_state_caps(hw, i, &caps);
3935 			if (ret)
3936 				return ret;
3937 			if (ice_dpll_is_sw_pin(pf, i, false))
3938 				pins[i].hidden = true;
3939 		}
3940 		ice_dpll_phase_range_set(&pins[i].prop.phase_range,
3941 					 phase_adj_max);
3942 		pins[i].prop.capabilities = caps;
3943 		ret = ice_dpll_pin_state_update(pf, &pins[i], pin_type, NULL);
3944 		if (ret)
3945 			return ret;
3946 		pins[i].prop.freq_supported =
3947 			ice_cgu_get_pin_freq_supp(hw, i, input, &freq_supp_num);
3948 		pins[i].prop.freq_supported_num = freq_supp_num;
3949 		pins[i].pf = pf;
3950 	}
3951 	if (input)
3952 		ret = ice_dpll_init_ref_sync_inputs(pf);
3953 
3954 	return ret;
3955 }
3956 
3957 /**
3958  * ice_dpll_init_info_pin_on_pin_e825c - initializes rclk pin information
3959  * @pf: board private structure
3960  *
3961  * Init information for rclk pin, cache them in pf->dplls.rclk.
3962  *
3963  * Return:
3964  * * 0 - success
3965  */
ice_dpll_init_info_pin_on_pin_e825c(struct ice_pf * pf)3966 static int ice_dpll_init_info_pin_on_pin_e825c(struct ice_pf *pf)
3967 {
3968 	struct ice_dpll_pin *rclk_pin = &pf->dplls.rclk;
3969 
3970 	rclk_pin->prop.type = DPLL_PIN_TYPE_SYNCE_ETH_PORT;
3971 	rclk_pin->prop.capabilities |= DPLL_PIN_CAPABILITIES_STATE_CAN_CHANGE;
3972 	rclk_pin->pf = pf;
3973 
3974 	return 0;
3975 }
3976 
3977 /**
3978  * ice_dpll_init_info_rclk_pin - initializes rclk pin information
3979  * @pf: board private structure
3980  *
3981  * Init information for rclk pin, cache them in pf->dplls.rclk.
3982  *
3983  * Return:
3984  * * 0 - success
3985  * * negative - init failure reason
3986  */
ice_dpll_init_info_rclk_pin(struct ice_pf * pf)3987 static int ice_dpll_init_info_rclk_pin(struct ice_pf *pf)
3988 {
3989 	struct ice_dpll_pin *pin = &pf->dplls.rclk;
3990 
3991 	pin->prop.type = DPLL_PIN_TYPE_SYNCE_ETH_PORT;
3992 	pin->prop.capabilities |= DPLL_PIN_CAPABILITIES_STATE_CAN_CHANGE;
3993 	pin->pf = pf;
3994 
3995 	return ice_dpll_pin_state_update(pf, pin,
3996 					 ICE_DPLL_PIN_TYPE_RCLK_INPUT, NULL);
3997 }
3998 
3999 /**
4000  * ice_dpll_init_info_sw_pins - initializes software controlled pin information
4001  * @pf: board private structure
4002  *
4003  * Init information for software controlled pins, cache them in
4004  * pf->dplls.sma and pf->dplls.ufl.
4005  *
4006  * Return:
4007  * * 0 - success
4008  * * negative - init failure reason
4009  */
ice_dpll_init_info_sw_pins(struct ice_pf * pf)4010 static int ice_dpll_init_info_sw_pins(struct ice_pf *pf)
4011 {
4012 	u8 freq_supp_num, pin_abs_idx, input_idx_offset = 0;
4013 	struct ice_dplls *d = &pf->dplls;
4014 	struct ice_dpll_pin *pin;
4015 	u32 phase_adj_max, caps;
4016 	int i, ret;
4017 
4018 	if (pf->hw.device_id == ICE_DEV_ID_E810C_QSFP)
4019 		input_idx_offset = ICE_E810_RCLK_PINS_NUM;
4020 	phase_adj_max = max(d->input_phase_adj_max, d->output_phase_adj_max);
4021 	caps = DPLL_PIN_CAPABILITIES_STATE_CAN_CHANGE;
4022 	for (i = 0; i < ICE_DPLL_PIN_SW_NUM; i++) {
4023 		pin = &d->sma[i];
4024 		pin->idx = i;
4025 		pin->prop.type = DPLL_PIN_TYPE_EXT;
4026 		pin_abs_idx = ICE_DPLL_PIN_SW_INPUT_ABS(i) + input_idx_offset;
4027 		pin->prop.freq_supported =
4028 			ice_cgu_get_pin_freq_supp(&pf->hw, pin_abs_idx,
4029 						  true, &freq_supp_num);
4030 		pin->prop.freq_supported_num = freq_supp_num;
4031 		pin->prop.capabilities =
4032 			(DPLL_PIN_CAPABILITIES_DIRECTION_CAN_CHANGE |
4033 			 DPLL_PIN_CAPABILITIES_PRIORITY_CAN_CHANGE |
4034 			 caps);
4035 		pin->pf = pf;
4036 		pin->prop.board_label = ice_dpll_sw_pin_sma[i];
4037 		pin->input = &d->inputs[pin_abs_idx];
4038 		if (pin->input->ref_sync)
4039 			pin->ref_sync = pin->input->ref_sync - pin_abs_idx;
4040 		pin->output = &d->outputs[ICE_DPLL_PIN_SW_OUTPUT_ABS(i)];
4041 		ice_dpll_phase_range_set(&pin->prop.phase_range, phase_adj_max);
4042 	}
4043 	for (i = 0; i < ICE_DPLL_PIN_SW_NUM; i++) {
4044 		pin = &d->ufl[i];
4045 		pin->idx = i;
4046 		pin->prop.type = DPLL_PIN_TYPE_EXT;
4047 		pin->prop.capabilities = caps;
4048 		pin->pf = pf;
4049 		pin->prop.board_label = ice_dpll_sw_pin_ufl[i];
4050 		if (i == ICE_DPLL_PIN_SW_1_IDX) {
4051 			pin->direction = DPLL_PIN_DIRECTION_OUTPUT;
4052 			pin_abs_idx = ICE_DPLL_PIN_SW_OUTPUT_ABS(i);
4053 			pin->prop.freq_supported =
4054 				ice_cgu_get_pin_freq_supp(&pf->hw, pin_abs_idx,
4055 							  false,
4056 							  &freq_supp_num);
4057 			pin->prop.freq_supported_num = freq_supp_num;
4058 			pin->input = NULL;
4059 			pin->output = &d->outputs[pin_abs_idx];
4060 		} else if (i == ICE_DPLL_PIN_SW_2_IDX) {
4061 			pin->direction = DPLL_PIN_DIRECTION_INPUT;
4062 			pin_abs_idx = ICE_DPLL_PIN_SW_INPUT_ABS(i) +
4063 				      input_idx_offset;
4064 			pin->output = NULL;
4065 			pin->input = &d->inputs[pin_abs_idx];
4066 			pin->prop.freq_supported =
4067 				ice_cgu_get_pin_freq_supp(&pf->hw, pin_abs_idx,
4068 							  true, &freq_supp_num);
4069 			pin->prop.freq_supported_num = freq_supp_num;
4070 			pin->prop.capabilities =
4071 				(DPLL_PIN_CAPABILITIES_PRIORITY_CAN_CHANGE |
4072 				 caps);
4073 		}
4074 		ice_dpll_phase_range_set(&pin->prop.phase_range, phase_adj_max);
4075 	}
4076 	ret = ice_dpll_pin_state_update(pf, pin, ICE_DPLL_PIN_TYPE_SOFTWARE,
4077 					NULL);
4078 	if (ret)
4079 		return ret;
4080 
4081 	return 0;
4082 }
4083 
4084 /**
4085  * ice_dpll_init_pins_info - init pins info wrapper
4086  * @pf: board private structure
4087  * @pin_type: type of pins being initialized
4088  *
4089  * Wraps functions for pin initialization.
4090  *
4091  * Return:
4092  * * 0 - success
4093  * * negative - init failure reason
4094  */
4095 static int
ice_dpll_init_pins_info(struct ice_pf * pf,enum ice_dpll_pin_type pin_type)4096 ice_dpll_init_pins_info(struct ice_pf *pf, enum ice_dpll_pin_type pin_type)
4097 {
4098 	switch (pin_type) {
4099 	case ICE_DPLL_PIN_TYPE_INPUT:
4100 	case ICE_DPLL_PIN_TYPE_OUTPUT:
4101 		return ice_dpll_init_info_direct_pins(pf, pin_type);
4102 	case ICE_DPLL_PIN_TYPE_RCLK_INPUT:
4103 		if (pf->hw.mac_type == ICE_MAC_GENERIC_3K_E825)
4104 			return ice_dpll_init_info_pin_on_pin_e825c(pf);
4105 		else
4106 			return ice_dpll_init_info_rclk_pin(pf);
4107 	case ICE_DPLL_PIN_TYPE_SOFTWARE:
4108 		return ice_dpll_init_info_sw_pins(pf);
4109 	default:
4110 		return -EINVAL;
4111 	}
4112 }
4113 
4114 /**
4115  * ice_dpll_deinit_info - release memory allocated for pins info
4116  * @pf: board private structure
4117  *
4118  * Release memory allocated for pins by ice_dpll_init_info function.
4119  */
ice_dpll_deinit_info(struct ice_pf * pf)4120 static void ice_dpll_deinit_info(struct ice_pf *pf)
4121 {
4122 	kfree(pf->dplls.inputs);
4123 	kfree(pf->dplls.outputs);
4124 	kfree(pf->dplls.eec.input_prio);
4125 	kfree(pf->dplls.pps.input_prio);
4126 }
4127 
4128 /**
4129  * ice_dpll_init_info_e825c - prepare pf's dpll information structure for e825c
4130  * device
4131  * @pf: board private structure
4132  *
4133  * Acquire (from HW) and set basic DPLL information (on pf->dplls struct).
4134  *
4135  * Return:
4136  * * 0 - success
4137  * * negative - init failure reason
4138  */
ice_dpll_init_info_e825c(struct ice_pf * pf)4139 static int ice_dpll_init_info_e825c(struct ice_pf *pf)
4140 {
4141 	struct ice_dplls *d = &pf->dplls;
4142 	int ret = 0;
4143 	int i;
4144 
4145 	d->clock_id = ice_generate_clock_id(pf);
4146 	d->num_inputs = ICE_SYNCE_CLK_NUM;
4147 
4148 	d->inputs = kzalloc_objs(*d->inputs, d->num_inputs);
4149 	if (!d->inputs)
4150 		return -ENOMEM;
4151 
4152 	ret = ice_get_cgu_rclk_pin_info(&pf->hw, &d->base_rclk_idx,
4153 					&pf->dplls.rclk.num_parents);
4154 	if (ret)
4155 		goto deinit_info;
4156 
4157 	for (i = 0; i < pf->dplls.rclk.num_parents; i++)
4158 		pf->dplls.rclk.parent_idx[i] = d->base_rclk_idx + i;
4159 
4160 	ret = ice_dpll_init_pins_info(pf, ICE_DPLL_PIN_TYPE_RCLK_INPUT);
4161 	if (ret)
4162 		goto deinit_info;
4163 	dev_dbg(ice_pf_to_dev(pf),
4164 		"%s - success, inputs: %u, outputs: %u, rclk-parents: %u\n",
4165 		 __func__, d->num_inputs, d->num_outputs, d->rclk.num_parents);
4166 	return 0;
4167 deinit_info:
4168 	ice_dpll_deinit_info(pf);
4169 	return ret;
4170 }
4171 
4172 /**
4173  * ice_dpll_init_info - prepare pf's dpll information structure
4174  * @pf: board private structure
4175  * @cgu: if cgu is present and controlled by this NIC
4176  *
4177  * Acquire (from HW) and set basic dpll information (on pf->dplls struct).
4178  *
4179  * Return:
4180  * * 0 - success
4181  * * negative - init failure reason
4182  */
ice_dpll_init_info(struct ice_pf * pf,bool cgu)4183 static int ice_dpll_init_info(struct ice_pf *pf, bool cgu)
4184 {
4185 	struct ice_aqc_get_cgu_abilities abilities;
4186 	struct ice_dpll *de = &pf->dplls.eec;
4187 	struct ice_dpll *dp = &pf->dplls.pps;
4188 	struct ice_dplls *d = &pf->dplls;
4189 	struct ice_hw *hw = &pf->hw;
4190 	int ret, alloc_size, i;
4191 
4192 	d->clock_id = ice_generate_clock_id(pf);
4193 	ret = ice_aq_get_cgu_abilities(hw, &abilities);
4194 	if (ret) {
4195 		dev_err(ice_pf_to_dev(pf),
4196 			"err:%d %s failed to read cgu abilities\n",
4197 			ret, libie_aq_str(hw->adminq.sq_last_status));
4198 		return ret;
4199 	}
4200 
4201 	de->dpll_idx = abilities.eec_dpll_idx;
4202 	dp->dpll_idx = abilities.pps_dpll_idx;
4203 	d->num_inputs = abilities.num_inputs;
4204 	d->num_outputs = abilities.num_outputs;
4205 	d->input_phase_adj_max = le32_to_cpu(abilities.max_in_phase_adj) &
4206 		ICE_AQC_GET_CGU_MAX_PHASE_ADJ;
4207 	d->output_phase_adj_max = le32_to_cpu(abilities.max_out_phase_adj) &
4208 		ICE_AQC_GET_CGU_MAX_PHASE_ADJ;
4209 
4210 	alloc_size = sizeof(*d->inputs) * d->num_inputs;
4211 	d->inputs = kzalloc(alloc_size, GFP_KERNEL);
4212 	if (!d->inputs)
4213 		return -ENOMEM;
4214 
4215 	alloc_size = sizeof(*de->input_prio) * d->num_inputs;
4216 	de->input_prio = kzalloc(alloc_size, GFP_KERNEL);
4217 	if (!de->input_prio)
4218 		return -ENOMEM;
4219 
4220 	dp->input_prio = kzalloc(alloc_size, GFP_KERNEL);
4221 	if (!dp->input_prio)
4222 		return -ENOMEM;
4223 
4224 	ret = ice_dpll_init_pins_info(pf, ICE_DPLL_PIN_TYPE_INPUT);
4225 	if (ret)
4226 		goto deinit_info;
4227 
4228 	if (cgu) {
4229 		alloc_size = sizeof(*d->outputs) * d->num_outputs;
4230 		d->outputs = kzalloc(alloc_size, GFP_KERNEL);
4231 		if (!d->outputs) {
4232 			ret = -ENOMEM;
4233 			goto deinit_info;
4234 		}
4235 
4236 		ret = ice_dpll_init_pins_info(pf, ICE_DPLL_PIN_TYPE_OUTPUT);
4237 		if (ret)
4238 			goto deinit_info;
4239 		ret = ice_dpll_init_pins_info(pf, ICE_DPLL_PIN_TYPE_SOFTWARE);
4240 		if (ret)
4241 			goto deinit_info;
4242 	}
4243 
4244 	ret = ice_get_cgu_rclk_pin_info(&pf->hw, &d->base_rclk_idx,
4245 					&pf->dplls.rclk.num_parents);
4246 	if (ret)
4247 		return ret;
4248 	for (i = 0; i < pf->dplls.rclk.num_parents; i++)
4249 		pf->dplls.rclk.parent_idx[i] = d->base_rclk_idx + i;
4250 	ret = ice_dpll_init_pins_info(pf, ICE_DPLL_PIN_TYPE_RCLK_INPUT);
4251 	if (ret)
4252 		return ret;
4253 	de->mode = DPLL_MODE_AUTOMATIC;
4254 	dp->mode = DPLL_MODE_AUTOMATIC;
4255 
4256 	dev_dbg(ice_pf_to_dev(pf),
4257 		"%s - success, inputs:%u, outputs:%u rclk-parents:%u\n",
4258 		__func__, d->num_inputs, d->num_outputs, d->rclk.num_parents);
4259 
4260 	return 0;
4261 
4262 deinit_info:
4263 	dev_err(ice_pf_to_dev(pf),
4264 		"%s - fail: d->inputs:%p, de->input_prio:%p, dp->input_prio:%p, d->outputs:%p\n",
4265 		__func__, d->inputs, de->input_prio,
4266 		dp->input_prio, d->outputs);
4267 	ice_dpll_deinit_info(pf);
4268 	return ret;
4269 }
4270 
4271 /**
4272  * ice_dpll_deinit - Disable the driver/HW support for dpll subsystem
4273  * the dpll device.
4274  * @pf: board private structure
4275  *
4276  * Handles the cleanup work required after dpll initialization, freeing
4277  * resources and unregistering the dpll, pin and all resources used for
4278  * handling them.
4279  *
4280  * Context: Destroys pf->dplls.lock mutex. Call only if ICE_FLAG_DPLL was set.
4281  */
ice_dpll_deinit(struct ice_pf * pf)4282 void ice_dpll_deinit(struct ice_pf *pf)
4283 {
4284 	bool cgu = ice_is_feature_supported(pf, ICE_F_CGU);
4285 
4286 	clear_bit(ICE_FLAG_DPLL, pf->flags);
4287 	if (cgu)
4288 		ice_dpll_deinit_worker(pf);
4289 
4290 	ice_dpll_deinit_pins(pf, cgu);
4291 	if (!IS_ERR_OR_NULL(pf->dplls.pps.dpll))
4292 		ice_dpll_deinit_dpll(pf, &pf->dplls.pps, cgu);
4293 	if (!IS_ERR_OR_NULL(pf->dplls.eec.dpll))
4294 		ice_dpll_deinit_dpll(pf, &pf->dplls.eec, cgu);
4295 	ice_dpll_deinit_info(pf);
4296 	mutex_destroy(&pf->dplls.lock);
4297 }
4298 
4299 /**
4300  * ice_dpll_init_e825 - initialize support for dpll subsystem
4301  * @pf: board private structure
4302  *
4303  * Set up the device dplls, register them and pins connected within Linux dpll
4304  * subsystem. Allow userspace to obtain state of DPLL and handling of DPLL
4305  * configuration requests.
4306  *
4307  * Context: Initializes pf->dplls.lock mutex.
4308  */
ice_dpll_init_e825(struct ice_pf * pf)4309 static void ice_dpll_init_e825(struct ice_pf *pf)
4310 {
4311 	struct ice_dplls *d = &pf->dplls;
4312 	int err;
4313 
4314 	mutex_init(&d->lock);
4315 	init_completion(&d->dpll_init);
4316 
4317 	err = ice_dpll_init_info_e825c(pf);
4318 	if (err)
4319 		goto err_exit;
4320 	err = ice_dpll_init_pins_e825(pf);
4321 	if (err)
4322 		goto deinit_info;
4323 	set_bit(ICE_FLAG_DPLL, pf->flags);
4324 	complete_all(&d->dpll_init);
4325 
4326 	return;
4327 
4328 deinit_info:
4329 	ice_dpll_deinit_info(pf);
4330 err_exit:
4331 	mutex_destroy(&d->lock);
4332 	dev_warn(ice_pf_to_dev(pf), "DPLLs init failure err:%d\n", err);
4333 }
4334 
4335 /**
4336  * ice_dpll_init_e810 - initialize support for dpll subsystem
4337  * @pf: board private structure
4338  *
4339  * Set up the device dplls, register them and pins connected within Linux dpll
4340  * subsystem. Allow userspace to obtain state of DPLL and handling of DPLL
4341  * configuration requests.
4342  *
4343  * Context: Initializes pf->dplls.lock mutex.
4344  */
ice_dpll_init_e810(struct ice_pf * pf)4345 static void ice_dpll_init_e810(struct ice_pf *pf)
4346 {
4347 	bool cgu = ice_is_feature_supported(pf, ICE_F_CGU);
4348 	struct ice_dplls *d = &pf->dplls;
4349 	int err = 0;
4350 
4351 	mutex_init(&d->lock);
4352 	err = ice_dpll_init_info(pf, cgu);
4353 	if (err)
4354 		goto err_exit;
4355 	err = ice_dpll_init_dpll(pf, &pf->dplls.eec, cgu, DPLL_TYPE_EEC);
4356 	if (err)
4357 		goto deinit_info;
4358 	err = ice_dpll_init_dpll(pf, &pf->dplls.pps, cgu, DPLL_TYPE_PPS);
4359 	if (err)
4360 		goto deinit_eec;
4361 	err = ice_dpll_init_pins(pf, cgu);
4362 	if (err)
4363 		goto deinit_pps;
4364 	if (cgu) {
4365 		err = ice_dpll_init_worker(pf);
4366 		if (err)
4367 			goto deinit_pins;
4368 	}
4369 	set_bit(ICE_FLAG_DPLL, pf->flags);
4370 
4371 	return;
4372 
4373 deinit_pins:
4374 	ice_dpll_deinit_pins(pf, cgu);
4375 deinit_pps:
4376 	ice_dpll_deinit_dpll(pf, &pf->dplls.pps, cgu);
4377 deinit_eec:
4378 	ice_dpll_deinit_dpll(pf, &pf->dplls.eec, cgu);
4379 deinit_info:
4380 	ice_dpll_deinit_info(pf);
4381 err_exit:
4382 	mutex_destroy(&d->lock);
4383 	dev_warn(ice_pf_to_dev(pf), "DPLLs init failure err:%d\n", err);
4384 }
4385 
ice_dpll_init(struct ice_pf * pf)4386 void ice_dpll_init(struct ice_pf *pf)
4387 {
4388 	switch (pf->hw.mac_type) {
4389 	case ICE_MAC_GENERIC_3K_E825:
4390 		ice_dpll_init_e825(pf);
4391 		break;
4392 	default:
4393 		ice_dpll_init_e810(pf);
4394 		break;
4395 	}
4396 }
4397